mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	- h3 hero classes and artifacts can be modified via json
- commander artifacts are now merged into main artifacts.json, todo - split 2.5k file into something manageable
This commit is contained in:
		| @@ -262,6 +262,26 @@ int main(int argc, char** argv) | ||||
|  | ||||
| 	preinitDLL(::console, logfile); | ||||
|  | ||||
| 	// Some basic data validation to produce better error messages in cases of incorrect install | ||||
| 	auto testFile = [](std::string filename, std::string message) -> bool | ||||
| 	{ | ||||
| 		if (CResourceHandler::get()->existsResource(ResourceID(filename))) | ||||
| 			return true; | ||||
|  | ||||
| 		tlog1 << "Error: " << message << " was not found!\n"; | ||||
| 		return false; | ||||
| 	}; | ||||
|  | ||||
| 	if (!testFile("DATA/HELP.TXT", "Heroes III data") && | ||||
| 	    !testFile("DATA/ZELP.TXT", "In the Wake of Gods data") && | ||||
| 	    !testFile("MODS/VCMI/MOD.JSON", "VCMI mod") && | ||||
| 	    !testFile("DATA/StackQueueBgBig.PCX", "VCMI data")) | ||||
| 		exit(1); // These are unrecoverable errors | ||||
|  | ||||
| 	// these two are optional + some installs have them on CD and not in data directory | ||||
| 	testFile("VIDEO/GOOD1A.SMK", "campaign movies"); | ||||
| 	testFile("SOUNDS/G1A.WAV", "campaign music"); //technically not a music but voiced intro sounds | ||||
|  | ||||
| 	settings.init(); | ||||
| 	conf.init(); | ||||
| 	tlog0 <<"Loading settings: "<<pomtime.getDiff() << std::endl; | ||||
|   | ||||
| @@ -2356,7 +2356,17 @@ | ||||
| 				} | ||||
| 			], | ||||
| 			"id" : 146, | ||||
| 			"type" : ["COMMANDER"] | ||||
| 			"type" : ["COMMANDER"], | ||||
| 			"growing": | ||||
| 			{ | ||||
| 				"bonusesPerLevel": | ||||
| 				[ | ||||
| 					{ | ||||
| 						"level": 6, | ||||
| 						"bonus": ["PRIMARY_SKILL", 1, "primSkill.attack", 0] | ||||
| 					} | ||||
| 				] | ||||
| 			} | ||||
| 		}, | ||||
| 		"mithrilMail": | ||||
| 		{ | ||||
| @@ -2368,7 +2378,17 @@ | ||||
| 				} | ||||
| 			], | ||||
| 			"id" : 147, | ||||
| 			"type" : ["COMMANDER"] | ||||
| 			"type" : ["COMMANDER"], | ||||
| 			"growing": | ||||
| 			{ | ||||
| 				"bonusesPerLevel": | ||||
| 				[ | ||||
| 					{ | ||||
| 						"level": 1, | ||||
| 						"bonus": ["STACK_HEALTH", 1, 0, 0] | ||||
| 					} | ||||
| 				] | ||||
| 			} | ||||
| 		}, | ||||
| 		"swordOfSharpness": | ||||
| 		{ | ||||
| @@ -2381,7 +2401,17 @@ | ||||
| 				} | ||||
| 			], | ||||
| 			"id" : 148, | ||||
| 			"type" : ["COMMANDER"] | ||||
| 			"type" : ["COMMANDER"], | ||||
| 			"growing": | ||||
| 			{ | ||||
| 				"bonusesPerLevel": | ||||
| 				[ | ||||
| 					{ | ||||
| 						"level": 1, | ||||
| 						"bonus": ["CREATURE_DAMAGE", 1, 0, 0] | ||||
| 					} | ||||
| 				] | ||||
| 			} | ||||
| 		}, | ||||
| 		"helmOfImmortality": //TODO: implement | ||||
| 		{ | ||||
| @@ -2398,7 +2428,17 @@ | ||||
| 				} | ||||
| 			], | ||||
| 			"id" : 150, | ||||
| 			"type" : ["COMMANDER"] | ||||
| 			"type" : ["COMMANDER"], | ||||
| 			"growing": | ||||
| 			{ | ||||
| 				"bonusesPerLevel": | ||||
| 				[ | ||||
| 					{ | ||||
| 						"level": 10, | ||||
| 						"bonus": ["CREATURE_ENCHANT_POWER", 1, 0, 0] | ||||
| 					} | ||||
| 				] | ||||
| 			} | ||||
| 		}, | ||||
| 		"bootsOfHaste": | ||||
| 		{ | ||||
| @@ -2410,17 +2450,46 @@ | ||||
| 				} | ||||
| 			], | ||||
| 			"id" : 151, | ||||
| 			"type" : ["COMMANDER"] | ||||
| 			"type" : ["COMMANDER"], | ||||
| 			"growing": | ||||
| 			{ | ||||
| 				"bonusesPerLevel": | ||||
| 				[ | ||||
| 					{ | ||||
| 						"level": 10, | ||||
| 						"bonus": ["STACKS_SPEED", 1, 0, 0] | ||||
| 					} | ||||
| 				] | ||||
| 			} | ||||
| 		}, | ||||
| 		"bowOfSeeking": | ||||
| 		{ | ||||
| 			"id" : 152, | ||||
| 			"type" : ["COMMANDER"] | ||||
| 			"type" : ["COMMANDER"], | ||||
| 			"growing": | ||||
| 			{ | ||||
| 				"id": 152, //bow of seeking | ||||
| 				"thresholdBonuses": | ||||
| 				[ | ||||
| 					{ | ||||
| 						"level": 5, | ||||
| 						"bonus": ["SHOOTER", 0, 0, 0] | ||||
| 					}, | ||||
| 					{ | ||||
| 						"level": 25, | ||||
| 						"bonus": ["NO_WALL_PENALTY", 0, 0, 0] | ||||
| 					}, | ||||
| 					{ | ||||
| 						"level": 50, | ||||
| 						"bonus": ["NO_DISTANCE_PENALTY", 0, 0, 0] | ||||
| 					} | ||||
| 				] | ||||
| 			} | ||||
| 		}, | ||||
| 		"dragonEyeRing": //TODO: implement | ||||
| 		{ | ||||
| 			"id" : 153, | ||||
| 			"type" : ["COMMANDER"] | ||||
| 			"type" : ["COMMANDER"], | ||||
| 		}, | ||||
| 		"hardenedShield": | ||||
| 		{ | ||||
| @@ -2433,7 +2502,18 @@ | ||||
| 				} | ||||
| 			], | ||||
| 			"id" : 154, | ||||
| 			"type" : ["COMMANDER"] | ||||
| 			"type" : ["COMMANDER"], | ||||
| 			"growing": | ||||
| 			{ | ||||
| 				"id": 153, //hardened shield | ||||
| 				"bonusesPerLevel": | ||||
| 				[ | ||||
| 					{ | ||||
| 						"level": 6, | ||||
| 						"bonus": ["PRIMARY_SKILL", 1, "primSkill.defence", 0] | ||||
| 					} | ||||
| 				] | ||||
| 			} | ||||
| 		}, | ||||
| 		"slavasRingOfPower": //TODO: implement if possible | ||||
| 		{ | ||||
| @@ -2530,4 +2610,4 @@ | ||||
| 			"type" : ["HERO"] | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -37,86 +37,5 @@ | ||||
| 		{"ability": ["JOUSTING", 0, 0, 0 ], "skills": [3, 4]}, | ||||
| 		{"ability": ["DEATH_STARE", 1, 1, 0 ], "skills": [3,5]}, | ||||
| 		{"ability": ["FLYING", 0, 0, 0 ], "skills": [4,5]} | ||||
| 	], | ||||
| 	"artifacts": | ||||
| 	[ | ||||
| 		{ | ||||
| 			"id": 146, //axe of smashing | ||||
| 			"bonusesPerLevel": | ||||
| 			[ | ||||
| 				{ | ||||
| 					"level": 6, | ||||
| 					"bonus": ["PRIMARY_SKILL", 1, "primSkill.attack", 0] | ||||
| 				} | ||||
| 			] | ||||
| 		}, | ||||
| 		{ | ||||
| 			"id": 147, //mithril mail | ||||
| 			"bonusesPerLevel": | ||||
| 			[ | ||||
| 				{ | ||||
| 					"level": 1, | ||||
| 					"bonus": ["STACK_HEALTH", 1, 0, 0] | ||||
| 				} | ||||
| 			] | ||||
| 		}, | ||||
| 		{ | ||||
| 			"id": 148, //sword of sharpness | ||||
| 			"bonusesPerLevel": | ||||
| 			[ | ||||
| 				{ | ||||
| 					"level": 1, | ||||
| 					"bonus": ["CREATURE_DAMAGE", 1, 0, 0] | ||||
| 				} | ||||
| 			] | ||||
| 		}, | ||||
| 		{ | ||||
| 			"id": 150, //pendant of sorcery | ||||
| 			"bonusesPerLevel": | ||||
| 			[ | ||||
| 				{ | ||||
| 					"level": 10, | ||||
| 					"bonus": ["CREATURE_ENCHANT_POWER", 1, 0, 0] | ||||
| 				} | ||||
| 			] | ||||
| 		}, | ||||
| 		{ | ||||
| 			"id": 151, //boots of haste | ||||
| 			"bonusesPerLevel": | ||||
| 			[ | ||||
| 				{ | ||||
| 					"level": 10, | ||||
| 					"bonus": ["STACKS_SPEED", 1, 0, 0] | ||||
| 				} | ||||
| 			] | ||||
| 		}, | ||||
| 		{ | ||||
| 			"id": 152, //bow of seeking | ||||
| 			"thresholdBonuses": | ||||
| 			[ | ||||
| 				{ | ||||
| 					"level": 5, | ||||
| 					"bonus": ["SHOOTER", 0, 0, 0] | ||||
| 				}, | ||||
| 				{ | ||||
| 					"level": 25, | ||||
| 					"bonus": ["NO_WALL_PENALTY", 0, 0, 0] | ||||
| 				}, | ||||
| 				{ | ||||
| 					"level": 50, | ||||
| 					"bonus": ["NO_DISTANCE_PENALTY", 0, 0, 0] | ||||
| 				} | ||||
| 			] | ||||
| 		}, | ||||
| 		{ | ||||
| 			"id": 153, //hardened shield | ||||
| 			"bonusesPerLevel": | ||||
| 			[ | ||||
| 				{ | ||||
| 					"level": 6, | ||||
| 					"bonus": ["PRIMARY_SKILL", 1, "primSkill.defence", 0] | ||||
| 				} | ||||
| 			] | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
|   | ||||
| @@ -168,12 +168,12 @@ | ||||
| 				{ "id" : 15, "requires" : [ 14 ] }, | ||||
| 				{ "id" : 16 }, | ||||
| 				{ "id" : 18, "upgrades" : 30 }, | ||||
| 				{ "id" : 19, "upgrades" : 37, "requires" : [ 18, 19 ], "mode" : "auto" }, | ||||
| 				{ "id" : 19, "upgrades" : 37, "requires" : [ 18 ], "mode" : "auto" }, | ||||
| 				{ "id" : 21, "requires" : [ 7 ] }, | ||||
| 				{ "id" : 22, "requires" : [ 8 ] }, | ||||
| 				{ "id" : 23, "requires" : [ 0 ] }, | ||||
| 				{ "id" : 24, "upgrades" : 32 }, | ||||
| 				{ "id" : 25, "upgrades" : 39, "requires" : [ 24, 25 ], "mode" : "auto" }, | ||||
| 				{ "id" : 25, "upgrades" : 39, "requires" : [ 24 ], "mode" : "auto" }, | ||||
| 				{ "id" : 26, "mode" : "grail"}, | ||||
| 				{ "id" : 27, "requires" : [ 11 ], "mode" : "auto" }, | ||||
| 				{ "id" : 28, "requires" : [ 12 ], "mode" : "auto" }, | ||||
|   | ||||
| @@ -1,38 +1,182 @@ | ||||
| { | ||||
| 	// battle animations for heroes, ordered by faction | ||||
| 	"heroBattleAnim" : | ||||
| 	[ | ||||
| 		{ "male" : "CH00.DEF",  "female" : "CH01.DEF" }, | ||||
| 		{ "male" : "CH02.DEF",  "female" : "CH03.DEF" }, | ||||
| 		{ "male" : "CH05.DEF",  "female" : "CH04.DEF" }, | ||||
| 		{ "male" : "CH06.DEF",  "female" : "CH07.DEF" }, | ||||
| 		{ "male" : "CH08.DEF",  "female" : "CH09.DEF" }, | ||||
| 		{ "male" : "CH010.DEF", "female" : "CH11.DEF" }, | ||||
| 		{ "male" : "CH013.DEF", "female" : "CH012.DEF" }, | ||||
| 		{ "male" : "CH014.DEF", "female" : "CH015.DEF" }, | ||||
| 		{ "male" : "CH16.DEF",  "female" : "CH17.DEF" } | ||||
| 	], | ||||
|  | ||||
| 	// map animations for heroes, ordered by hero class | ||||
| 	"heroMapAnim" : | ||||
| 	[ | ||||
| 		"AH00_.def", | ||||
| 		"AH01_.def", | ||||
| 		"AH02_.def", | ||||
| 		"AH03_.def", | ||||
| 		"AH04_.def", | ||||
| 		"AH05_.def", | ||||
| 		"AH06_.def", | ||||
| 		"AH07_.def", | ||||
| 		"AH08_.def", | ||||
| 		"AH09_.def", | ||||
| 		"AH10_.def", | ||||
| 		"AH11_.def", | ||||
| 		"AH12_.def", | ||||
| 		"AH13_.def", | ||||
| 		"AH14_.def", | ||||
| 		"AH15_.def", | ||||
| 		"AH16_.def", | ||||
| 		"AH17_.def" | ||||
| 	] | ||||
| 	"knight": | ||||
| 	{ | ||||
| 		"id": 0, | ||||
| 		"faction" : "castle", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH00.DEF",  "female" : "CH01.DEF" }, | ||||
| 			"map":     { "male" : "AH00_.def", "female" : "AH00_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"cleric" : | ||||
| 	{ | ||||
| 		"id": 1, | ||||
| 		"faction" : "castle", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH00.DEF",  "female" : "CH01.DEF" }, | ||||
| 			"map":     { "male" : "AH01_.def", "female" : "AH01_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"ranger" : | ||||
| 	{ | ||||
| 		"id": 2, | ||||
| 		"faction" : "rampart", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH02.DEF",  "female" : "CH03.DEF" }, | ||||
| 			"map":     { "male" : "AH02_.def", "female" : "AH02_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"druid" : | ||||
| 	{ | ||||
| 		"id": 3, | ||||
| 		"faction" : "rampart", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH02.DEF",  "female" : "CH03.DEF" }, | ||||
| 			"map":     { "male" : "AH03_.def", "female" : "AH03_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"alchemist" : | ||||
| 	{ | ||||
| 		"id": 4, | ||||
| 		"faction" : "tower", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH05.DEF",  "female" : "CH04.DEF" }, | ||||
| 			"map":     { "male" : "AH04_.def", "female" : "AH04_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"wizard" : | ||||
| 	{ | ||||
| 		"id": 5, | ||||
| 		"faction" : "tower", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH05.DEF",  "female" : "CH04.DEF" }, | ||||
| 			"map":     { "male" : "AH05_.def", "female" : "AH05_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"demoniac" : | ||||
| 	{ | ||||
| 		"id": 6, | ||||
| 		"faction" : "inferno", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH06.DEF",  "female" : "CH07.DEF" }, | ||||
| 			"map":     { "male" : "AH06_.def", "female" : "AH06_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"heretic" : | ||||
| 	{ | ||||
| 		"id": 7, | ||||
| 		"faction" : "inferno", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH06.DEF",  "female" : "CH07.DEF" }, | ||||
| 			"map":     { "male" : "AH07_.def", "female" : "AH07_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"deathknight" : | ||||
| 	{ | ||||
| 		"id": 8, | ||||
| 		"faction" : "necropolis", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH08.DEF",  "female" : "CH09.DEF" }, | ||||
| 			"map":     { "male" : "AH08_.def", "female" : "AH08_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"necromancer" : | ||||
| 	{ | ||||
| 		"id": 9, | ||||
| 		"faction" : "necropolis", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH08.DEF",  "female" : "CH09.DEF" }, | ||||
| 			"map":     { "male" : "AH09_.def", "female" : "AH09_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"warlock" : | ||||
| 	{ | ||||
| 		"id": 10, | ||||
| 		"faction" : "dungeon", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH010.DEF", "female" : "CH11.DEF" }, | ||||
| 			"map":     { "male" : "AH10_.def", "female" : "AH10_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"overlord" : | ||||
| 	{ | ||||
| 		"id": 11, | ||||
| 		"faction" : "dungeon", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH010.DEF", "female" : "CH11.DEF" }, | ||||
| 			"map":     { "male" : "AH11_.def", "female" : "AH11_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"barbarian" : | ||||
| 	{ | ||||
| 		"id": 12, | ||||
| 		"faction" : "stronghold", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH013.DEF", "female" : "CH012.DEF" }, | ||||
| 			"map":     { "male" : "AH12_.def", "female" : "AH12_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"battlemage" : | ||||
| 	{ | ||||
| 		"id": 13, | ||||
| 		"faction" : "stronghold", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH013.DEF", "female" : "CH012.DEF" }, | ||||
| 			"map":     { "male" : "AH13_.def", "female" : "AH13_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"beastmaster" : | ||||
| 	{ | ||||
| 		"id": 14, | ||||
| 		"faction" : "fortress", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH014.DEF", "female" : "CH015.DEF" }, | ||||
| 			"map":     { "male" : "AH14_.def", "female" : "AH14_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"witch" : | ||||
| 	{ | ||||
| 		"id": 15, | ||||
| 		"faction" : "fortress", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH014.DEF", "female" : "CH015.DEF" }, | ||||
| 			"map":     { "male" : "AH15_.def", "female" : "AH15_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"planeswalker" : | ||||
| 	{ | ||||
| 		"id": 16, | ||||
| 		"faction" : "conflux", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH16.DEF",  "female" : "CH17.DEF" }, | ||||
| 			"map":     { "male" : "AH16_.def", "female" : "AH16_.def" } | ||||
| 		} | ||||
| 	}, | ||||
| 	"elementalist" : | ||||
| 	{ | ||||
| 		"id": 17, | ||||
| 		"faction" : "conflux", | ||||
| 		"animation": | ||||
| 		{ | ||||
| 			"battle" : { "male" : "CH16.DEF",  "female" : "CH17.DEF" }, | ||||
| 			"map":     { "male" : "AH17_.def", "female" : "AH17_.def" } | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -24,40 +24,27 @@ using namespace boost::assign; | ||||
|  */ | ||||
|  | ||||
| extern boost::rand48 ran; | ||||
|  | ||||
| const std::map<std::string, CArtifact::EartClass> artifactClassMap = boost::assign::map_list_of | ||||
| 	("TREASURE", CArtifact::ART_TREASURE) | ||||
| 	("MINOR", CArtifact::ART_MINOR) | ||||
| 	("MAJOR", CArtifact::ART_MAJOR) | ||||
| 	("RELIC", CArtifact::ART_RELIC) | ||||
| 	("SPECIAL", CArtifact::ART_SPECIAL); | ||||
|  | ||||
| #define ART_BEARER(x) ( #x, ArtBearer::x ) | ||||
| 	const std::map<std::string, int> artifactBearerMap = boost::assign::map_list_of ART_BEARER_LIST; | ||||
| #undef ART_BEARER | ||||
|  | ||||
| #define ART_POS(x) ( #x, ArtifactPosition::x ) | ||||
|  | ||||
| const std::map<std::string, ArtifactPosition> artifactPositionMap = boost::assign::map_list_of | ||||
| 	ART_POS(HEAD) | ||||
| 	ART_POS(SHOULDERS) | ||||
| 	ART_POS(NECK) | ||||
| 	ART_POS(RIGHT_HAND) | ||||
| 	ART_POS(LEFT_HAND) | ||||
| 	ART_POS(TORSO) | ||||
| 	ART_POS(RIGHT_RING) | ||||
| 	ART_POS(LEFT_RING) | ||||
| 	ART_POS(FEET) | ||||
| 	ART_POS(MISC1) | ||||
| 	ART_POS(MISC2) | ||||
| 	ART_POS(MISC3) | ||||
| 	ART_POS(MISC4) | ||||
| 	ART_POS(MISC5) | ||||
| 	ART_POS(MACH1) | ||||
| 	ART_POS(MACH2) | ||||
| 	ART_POS(MACH3) | ||||
| 	ART_POS(MACH4) | ||||
| 	ART_POS(SPELLBOOK); //no need to specify commander / stack position? | ||||
| // Note: list must match entries in ArtTraits.txt | ||||
| #define ART_POS_LIST    \ | ||||
| 	ART_POS(SPELLBOOK)  \ | ||||
| 	ART_POS(MACH4)      \ | ||||
| 	ART_POS(MACH3)      \ | ||||
| 	ART_POS(MACH2)      \ | ||||
| 	ART_POS(MACH1)      \ | ||||
| 	ART_POS(MISC5)      \ | ||||
| 	ART_POS(MISC4)      \ | ||||
| 	ART_POS(MISC3)      \ | ||||
| 	ART_POS(MISC2)      \ | ||||
| 	ART_POS(MISC1)      \ | ||||
| 	ART_POS(FEET)       \ | ||||
| 	ART_POS(LEFT_RING)  \ | ||||
| 	ART_POS(RIGHT_RING) \ | ||||
| 	ART_POS(TORSO)      \ | ||||
| 	ART_POS(LEFT_HAND)  \ | ||||
| 	ART_POS(RIGHT_HAND) \ | ||||
| 	ART_POS(NECK)       \ | ||||
| 	ART_POS(SHOULDERS)  \ | ||||
| 	ART_POS(HEAD); | ||||
|  | ||||
| const std::string & CArtifact::Name() const | ||||
| { | ||||
| @@ -166,15 +153,12 @@ void CArtHandler::load(bool onlyTxt) | ||||
| 	if (onlyTxt) | ||||
| 		return; // looks to be broken anyway... | ||||
|  | ||||
| 	std::vector<ui16> artSlots; | ||||
| 	artSlots += 17, 16, 15, 14, 13, 18, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0; | ||||
| 	#define ART_POS(x) (  #x) | ||||
| 	const std::vector<std::string> artSlots = boost::assign::list_of ART_POS_LIST; | ||||
| 	#undef ART_POS | ||||
|  | ||||
| 	growingArtifacts += ArtifactID::AXE_OF_SMASHING, ArtifactID::MITHRIL_MAIL, | ||||
| 		ArtifactID::SWORD_OF_SHARPNESS, ArtifactID::PENDANT_OF_SORCERY, ArtifactID::BOOTS_OF_HASTE, | ||||
| 		ArtifactID::BOW_OF_SEEKING, ArtifactID::DRAGON_EYE_RING; | ||||
|  | ||||
| 	static std::map<char, CArtifact::EartClass> classes = | ||||
| 	  map_list_of('S',CArtifact::ART_SPECIAL)('T',CArtifact::ART_TREASURE)('N',CArtifact::ART_MINOR)('J',CArtifact::ART_MAJOR)('R',CArtifact::ART_RELIC); | ||||
| 	static std::map<char, std::string> classes = | ||||
| 	  map_list_of('S',"SPECIAL")('T',"TREASURE")('N',"MINOR")('J',"MAJOR")('R',"RELIC"); | ||||
|  | ||||
| 	CLegacyConfigParser parser("DATA/ARTRAITS.TXT"); | ||||
| 	CLegacyConfigParser events("DATA/ARTEVENT.TXT"); | ||||
| @@ -184,74 +168,54 @@ void CArtHandler::load(bool onlyTxt) | ||||
|  | ||||
| 	std::map<ui32,ui8>::iterator itr; | ||||
|  | ||||
| 	for (ArtifactID i=ArtifactID(0); i<GameConstants::ARTIFACTS_QUANTITY; i.advance(1)) | ||||
| 	{ | ||||
| 		CArtifact *art; | ||||
| 		if (vstd::contains (growingArtifacts, i)) | ||||
| 		{ | ||||
| 			art = new CGrowingArtifact(); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			art = new CArtifact(); | ||||
| 		} | ||||
| 		art->id=i; | ||||
| 		art->iconIndex=i; | ||||
| 		art->name = parser.readString(); | ||||
| 		art->eventText = events.readString(); | ||||
| 		events.endLine(); | ||||
| 	std::vector<JsonNode> h3Data; | ||||
|  | ||||
| 		art->price= parser.readNumber(); | ||||
| 	for (size_t i = 0; i < GameConstants::ARTIFACTS_QUANTITY; i++) | ||||
| 	{ | ||||
| 		JsonNode artData; | ||||
|  | ||||
| 		artData["graphics"]["iconIndex"].Float() = i; | ||||
| 		artData["text"]["name"].String() = parser.readString(); | ||||
| 		artData["text"]["event"].String() = events.readString(); | ||||
| 		artData["value"].Float() = parser.readNumber(); | ||||
|  | ||||
| 		for(int j=0; j<artSlots.size(); j++) | ||||
| 		{ | ||||
| 			if(parser.readString() == "x") | ||||
| 				art->possibleSlots[ArtBearer::HERO].push_back(ArtifactPosition(artSlots[j])); | ||||
| 			{ | ||||
| 				artData["slot"].Vector().push_back(JsonNode()); | ||||
| 				artData["slot"].Vector().back().String() = artSlots.at(j); | ||||
| 			} | ||||
| 		} | ||||
| 		art->aClass = classes[parser.readString()[0]]; | ||||
|  | ||||
| 		//load description and remove quotation marks | ||||
| 		art->description = parser.readString(); | ||||
| 		artData["class"].String() = classes[parser.readString()[0]]; | ||||
| 		artData["text"]["description"].String() = parser.readString(); | ||||
|  | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		if(onlyTxt) // FIXME: pointer to art will be lost. Bug? | ||||
| 			continue; | ||||
|  | ||||
| 		artifacts.push_back(art); | ||||
| 		events.endLine(); | ||||
| 		h3Data.push_back(artData); | ||||
| 	} | ||||
|  | ||||
| 	if (VLC->modh->modules.COMMANDERS) | ||||
| 	{ //TODO: move all artifacts config to separate json file | ||||
| 		const JsonNode config(ResourceID("config/commanders.json")); | ||||
| 		BOOST_FOREACH(const JsonNode &artifact, config["artifacts"].Vector()) | ||||
| 		{ | ||||
| 			auto ga = dynamic_cast <CGrowingArtifact *>(artifacts[artifact["id"].Float()].get()); | ||||
| 			BOOST_FOREACH (auto b, artifact["bonusesPerLevel"].Vector()) | ||||
| 			{ | ||||
| 				ga->bonusesPerLevel.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *JsonUtils::parseBonus (b["bonus"].Vector()))); | ||||
| 			} | ||||
| 			BOOST_FOREACH (auto b, artifact["thresholdBonuses"].Vector()) | ||||
| 			{ | ||||
| 				ga->thresholdBonuses.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *JsonUtils::parseBonus (b["bonus"].Vector()))); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if(onlyTxt) | ||||
| 		return; | ||||
| 	artifacts.resize(GameConstants::ARTIFACTS_QUANTITY); | ||||
|  | ||||
| 	JsonNode config(ResourceID("config/artifacts.json")); | ||||
|  | ||||
| 	BOOST_FOREACH(auto & node, config["artifacts"].Struct()) | ||||
| 	{ | ||||
| 		int numeric = node.second["id"].Float(); | ||||
| 		CArtifact * art = artifacts[numeric]; | ||||
| 		JsonNode & artData = h3Data[numeric]; | ||||
| 		JsonUtils::merge(artData, node.second); | ||||
|  | ||||
| 		loadArtifactJson(art, node.second); | ||||
| 		artifacts[numeric] = loadArtifact(artData); | ||||
| 		artifacts[numeric]->id = ArtifactID(numeric); | ||||
|  | ||||
| 		VLC->modh->identifiers.registerObject ("artifact." + node.first, numeric); | ||||
| 	} | ||||
|  | ||||
| 	for (size_t i=0; i < artifacts.size(); i++) | ||||
| 	{ | ||||
| 		if (artifacts[i] == nullptr) | ||||
| 			tlog0 << "Warning: artifact with id " << i << " is missing!\n"; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CArtHandler::load(std::string objectID, const JsonNode & node) | ||||
| @@ -266,7 +230,16 @@ void CArtHandler::load(std::string objectID, const JsonNode & node) | ||||
|  | ||||
| CArtifact * CArtHandler::loadArtifact(const JsonNode & node) | ||||
| { | ||||
| 	CArtifact * art = new CArtifact; | ||||
| 	CArtifact * art; | ||||
|  | ||||
| 	if (!VLC->modh->modules.COMMANDERS || node["growing"].isNull()) | ||||
| 		art = new CArtifact(); | ||||
| 	else | ||||
| 	{ | ||||
| 		CGrowingArtifact * growing = new CGrowingArtifact(); | ||||
| 		loadGrowingArt(growing, node); | ||||
| 		art = growing; | ||||
| 	} | ||||
|  | ||||
| 	const JsonNode & text = node["text"]; | ||||
| 	art->name        = text["name"].String(); | ||||
| @@ -283,59 +256,90 @@ CArtifact * CArtHandler::loadArtifact(const JsonNode & node) | ||||
| 	art->advMapDef = graphics["map"].String(); | ||||
|  | ||||
| 	art->price = node["value"].Float(); | ||||
| 	{ | ||||
| 		auto it = artifactClassMap.find (node["class"].String()); | ||||
| 		if (it != artifactClassMap.end()) | ||||
| 		{ | ||||
| 			art->aClass = it->second; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			tlog2 << "Warning! Artifact rarity " << node["class"].String() << " not recognized!"; | ||||
| 			art->aClass = CArtifact::ART_SPECIAL; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (!node["slot"].isNull()) //we assume non-hero slots are irrelevant? | ||||
| 	{ | ||||
| 		std::string slotName = node["slot"].String(); | ||||
| 		if (slotName == "MISC") | ||||
| 		{ | ||||
| 			//unfortunatelly slot ids aare not continuous | ||||
| 			art->possibleSlots[ArtBearer::HERO] += ArtifactPosition::MISC1, ArtifactPosition::MISC2, ArtifactPosition::MISC3, ArtifactPosition::MISC4, ArtifactPosition::MISC5; | ||||
| 		} | ||||
| 		else if (slotName == "RING") | ||||
| 		{ | ||||
| 			art->possibleSlots[ArtBearer::HERO] += ArtifactPosition::LEFT_RING, ArtifactPosition::RIGHT_RING; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 	loadSlots(art, node); | ||||
| 	loadClass(art, node); | ||||
| 	loadType(art, node); | ||||
| 	loadComponents(art, node); | ||||
|  | ||||
| 			auto it = artifactPositionMap.find (slotName); | ||||
| 			if (it != artifactPositionMap.end()) | ||||
| 			{ | ||||
| 				auto slot = it->second; | ||||
| 				art->possibleSlots[ArtBearer::HERO].push_back (slot); | ||||
| 			} | ||||
| 			else | ||||
| 				tlog2 << "Warning! Artifact slot " << node["slot"].String() << " not recognized!"; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	loadArtifactJson(art, node); | ||||
|  | ||||
| 	return art; | ||||
| } | ||||
|  | ||||
| void CArtHandler::loadArtifactJson(CArtifact * art, const JsonNode & artifact) | ||||
| { | ||||
| 	BOOST_FOREACH (auto b, artifact["bonuses"].Vector()) | ||||
| 	BOOST_FOREACH (auto b, node["bonuses"].Vector()) | ||||
| 	{ | ||||
| 		auto bonus = JsonUtils::parseBonus (b); | ||||
| 		bonus->sid = art->id; | ||||
| 		art->addNewBonus (bonus); | ||||
| 	} | ||||
| 	BOOST_FOREACH (const JsonNode & b, artifact["type"].Vector()) | ||||
| 	return art; | ||||
| } | ||||
|  | ||||
| void CArtHandler::addSlot(CArtifact * art, const std::string & slotID) | ||||
| { | ||||
| #define ART_POS(x) ( #x, ArtifactPosition::x ) | ||||
| 	static const std::map<std::string, ArtifactPosition> artifactPositionMap = boost::assign::map_list_of ART_POS_LIST; | ||||
| #undef ART_POS | ||||
|  | ||||
| 	if (slotID == "MISC") | ||||
| 	{ | ||||
| 		art->possibleSlots[ArtBearer::HERO] += ArtifactPosition::MISC1, ArtifactPosition::MISC2, ArtifactPosition::MISC3, ArtifactPosition::MISC4, ArtifactPosition::MISC5; | ||||
| 	} | ||||
| 	else if (slotID == "RING") | ||||
| 	{ | ||||
| 		art->possibleSlots[ArtBearer::HERO] += ArtifactPosition::LEFT_RING, ArtifactPosition::RIGHT_RING; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		auto it = artifactPositionMap.find (slotID); | ||||
| 		if (it != artifactPositionMap.end()) | ||||
| 		{ | ||||
| 			auto slot = it->second; | ||||
| 			art->possibleSlots[ArtBearer::HERO].push_back (slot); | ||||
| 		} | ||||
| 		else | ||||
| 			tlog2 << "Warning! Artifact slot " << slotID << " not recognized!"; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CArtHandler::loadSlots(CArtifact * art, const JsonNode & node) | ||||
| { | ||||
| 	if (!node["slot"].isNull()) //we assume non-hero slots are irrelevant? | ||||
| 	{ | ||||
| 		if (node["slot"].getType() == JsonNode::DATA_STRING) | ||||
| 			addSlot(art, node["slot"].String()); | ||||
| 		else | ||||
| 		{ | ||||
| 			BOOST_FOREACH (const JsonNode & slot, node["slot"].Vector()) | ||||
| 				addSlot(art, slot.String()); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CArtHandler::loadClass(CArtifact * art, const JsonNode & node) | ||||
| { | ||||
| 	static const std::map<std::string, CArtifact::EartClass> artifactClassMap = boost::assign::map_list_of | ||||
| 		("TREASURE", CArtifact::ART_TREASURE) | ||||
| 		("MINOR", CArtifact::ART_MINOR) | ||||
| 		("MAJOR", CArtifact::ART_MAJOR) | ||||
| 		("RELIC", CArtifact::ART_RELIC) | ||||
| 		("SPECIAL", CArtifact::ART_SPECIAL); | ||||
|  | ||||
| 	auto it = artifactClassMap.find (node["class"].String()); | ||||
| 	if (it != artifactClassMap.end()) | ||||
| 	{ | ||||
| 		art->aClass = it->second; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		tlog2 << "Warning! Artifact rarity " << node["class"].String() << " not recognized!"; | ||||
| 		art->aClass = CArtifact::ART_SPECIAL; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CArtHandler::loadType(CArtifact * art, const JsonNode & node) | ||||
| { | ||||
| #define ART_BEARER(x) ( #x, ArtBearer::x ) | ||||
| 	static const std::map<std::string, int> artifactBearerMap = boost::assign::map_list_of ART_BEARER_LIST; | ||||
| #undef ART_BEARER | ||||
|  | ||||
| 	BOOST_FOREACH (const JsonNode & b, node["type"].Vector()) | ||||
| 	{ | ||||
| 		auto it = artifactBearerMap.find (b.String()); | ||||
| 		if (it != artifactBearerMap.end()) | ||||
| @@ -356,11 +360,14 @@ void CArtHandler::loadArtifactJson(CArtifact * art, const JsonNode & artifact) | ||||
| 		else | ||||
| 			tlog2 << "Warning! Artifact type " << b.String() << " not recognized!"; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| 	if (!artifact["components"].isNull()) | ||||
| void CArtHandler::loadComponents(CArtifact * art, const JsonNode & node) | ||||
| { | ||||
| 	if (!node["components"].isNull()) | ||||
| 	{ | ||||
| 		art->constituents.reset(new std::vector<CArtifact *>()); | ||||
| 		BOOST_FOREACH (auto component, artifact["components"].Vector()) | ||||
| 		BOOST_FOREACH (auto component, node["components"].Vector()) | ||||
| 		{ | ||||
| 			VLC->modh->identifiers.requestIdentifier("artifact." + component.String(), [=](si32 id) | ||||
| 			{ | ||||
| @@ -373,6 +380,18 @@ void CArtHandler::loadArtifactJson(CArtifact * art, const JsonNode & artifact) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CArtHandler::loadGrowingArt(CGrowingArtifact * art, const JsonNode & node) | ||||
| { | ||||
| 	BOOST_FOREACH (auto b, node["growing"]["bonusesPerLevel"].Vector()) | ||||
| 	{ | ||||
| 		art->bonusesPerLevel.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *JsonUtils::parseBonus (b["bonus"].Vector()))); | ||||
| 	} | ||||
| 	BOOST_FOREACH (auto b, node["growing"]["thresholdBonuses"].Vector()) | ||||
| 	{ | ||||
| 		art->thresholdBonuses.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *JsonUtils::parseBonus (b["bonus"].Vector()))); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| ArtifactID CArtHandler::creatureToMachineID(CreatureID id) | ||||
| { | ||||
| 	int dif = 142; | ||||
|   | ||||
| @@ -59,8 +59,8 @@ public: | ||||
| 	bool isBig () const; | ||||
|  | ||||
| 	int getArtClassSerial() const; //0 - treasure, 1 - minor, 2 - major, 3 - relic, 4 - spell scroll, 5 - other | ||||
| 	std::string nodeName() const OVERRIDE; | ||||
| 	void addNewBonus(Bonus *b) OVERRIDE; | ||||
| 	std::string nodeName() const override; | ||||
| 	void addNewBonus(Bonus *b) override; | ||||
|  | ||||
| 	virtual void levelUpArtifact (CArtifactInstance * art){}; | ||||
|  | ||||
| @@ -112,7 +112,7 @@ public: | ||||
|  | ||||
| 	//CArtifactInstance(int aid); | ||||
|  | ||||
| 	std::string nodeName() const OVERRIDE; | ||||
| 	std::string nodeName() const override; | ||||
| 	void deserializationFix(); | ||||
| 	void setType(CArtifact *Art); | ||||
|  | ||||
| @@ -161,11 +161,11 @@ public: | ||||
|  | ||||
| 	std::vector<ConstituentInfo> constituentsInfo; | ||||
|  | ||||
| 	bool canBePutAt(const CArtifactSet *artSet, ArtifactPosition slot, bool assumeDestRemoved = false) const OVERRIDE; | ||||
| 	bool canBeDisassembled() const OVERRIDE; | ||||
| 	void putAt(ArtifactLocation al) OVERRIDE; | ||||
| 	void removeFrom(ArtifactLocation al) OVERRIDE; | ||||
| 	bool isPart(const CArtifactInstance *supposedPart) const OVERRIDE; | ||||
| 	bool canBePutAt(const CArtifactSet *artSet, ArtifactPosition slot, bool assumeDestRemoved = false) const override; | ||||
| 	bool canBeDisassembled() const override; | ||||
| 	void putAt(ArtifactLocation al) override; | ||||
| 	void removeFrom(ArtifactLocation al) override; | ||||
| 	bool isPart(const CArtifactInstance *supposedPart) const override; | ||||
|  | ||||
| 	void createConstituents(); | ||||
| 	void addAsConstituent(CArtifactInstance *art, ArtifactPosition slot); | ||||
| @@ -187,6 +187,13 @@ public: | ||||
|  | ||||
| class DLL_LINKAGE CArtHandler //handles artifacts | ||||
| { | ||||
| 	void addSlot(CArtifact * art, const std::string & slotID); | ||||
| 	void loadSlots(CArtifact * art, const JsonNode & node); | ||||
| 	void loadClass(CArtifact * art, const JsonNode & node); | ||||
| 	void loadType(CArtifact * art, const JsonNode & node); | ||||
| 	void loadComponents(CArtifact * art, const JsonNode & node); | ||||
| 	void loadGrowingArt(CGrowingArtifact * art, const JsonNode & node); | ||||
|  | ||||
| 	void giveArtBonus(ArtifactID aid, Bonus::BonusType type, int val, int subtype = -1, Bonus::ValueType valType = Bonus::BASE_NUMBER, shared_ptr<ILimiter> limiter = shared_ptr<ILimiter>(), int additionalinfo = 0); | ||||
| 	void giveArtBonus(ArtifactID aid, Bonus::BonusType type, int val, int subtype, shared_ptr<IPropagator> propagator, int additionalinfo = 0); | ||||
| 	void giveArtBonus(ArtifactID aid, Bonus *bonus); | ||||
| @@ -204,8 +211,6 @@ public: | ||||
| 	/// load one artifact from json config | ||||
| 	CArtifact * loadArtifact(const JsonNode & node); | ||||
|  | ||||
| 	void loadArtifactJson(CArtifact * art, const JsonNode & node); | ||||
|  | ||||
| 	void addBonuses(CArtifact *art, const JsonNode &bonusList); | ||||
|  | ||||
| 	void fillList(std::vector<CArtifact*> &listToBeFilled, CArtifact::EartClass artifactClass); //fills given empty list with allowed artifacts of gibven class. No side effects | ||||
|   | ||||
| @@ -85,49 +85,54 @@ void CHeroClassHandler::load() | ||||
| 	parser.endLine(); // header | ||||
| 	parser.endLine(); | ||||
|  | ||||
| 	std::vector<JsonNode> h3Data; | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		CHeroClass * hc = new CHeroClass; | ||||
| 		JsonNode entry; | ||||
|  | ||||
| 		hc->name             = parser.readString(); | ||||
| 		hc->aggression       = parser.readNumber(); | ||||
| 		hc->id = heroClasses.size(); | ||||
| 		entry["name"].String() = parser.readString(); | ||||
|  | ||||
| 		hc->primarySkillInitial   = parser.readNumArray<int>(GameConstants::PRIMARY_SKILLS); | ||||
| 		hc->primarySkillLowLevel  = parser.readNumArray<int>(GameConstants::PRIMARY_SKILLS); | ||||
| 		hc->primarySkillHighLevel = parser.readNumArray<int>(GameConstants::PRIMARY_SKILLS); | ||||
| 		parser.readNumber(); // unused aggression | ||||
|  | ||||
| 		hc->secSkillProbability   = parser.readNumArray<int>(GameConstants::SKILL_QUANTITY); | ||||
| 		for (size_t i=0; i < GameConstants::PRIMARY_SKILLS; i++) | ||||
| 			entry["primarySkills"][PrimarySkill::names[i]].Float() = parser.readNumber(); | ||||
|  | ||||
| 		for(int dd=0; dd<GameConstants::F_NUMBER; ++dd) | ||||
| 		{ | ||||
| 			hc->selectionProbability[dd] = parser.readNumber(); | ||||
| 		} | ||||
| 		for (size_t i=0; i < GameConstants::PRIMARY_SKILLS; i++) | ||||
| 			entry["lowLevelChance"][PrimarySkill::names[i]].Float() = parser.readNumber(); | ||||
|  | ||||
| 		VLC->modh->identifiers.requestIdentifier("faction." + ETownType::names[heroClasses.size()/2], | ||||
| 		[=](si32 faction) | ||||
| 		{ | ||||
| 			hc->faction = faction; | ||||
| 		}); | ||||
| 		for (size_t i=0; i < GameConstants::PRIMARY_SKILLS; i++) | ||||
| 			entry["highLevelChance"][PrimarySkill::names[i]].Float() = parser.readNumber(); | ||||
|  | ||||
| 		heroClasses.push_back(hc); | ||||
| 		VLC->modh->identifiers.registerObject("heroClass." + GameConstants::HERO_CLASSES_NAMES[hc->id], hc->id); | ||||
| 		for (size_t i=0; i < GameConstants::SKILL_QUANTITY; i++) | ||||
| 			entry["secondarySkills"][NSecondarySkill::names[i]].Float() = parser.readNumber(); | ||||
|  | ||||
| 		for(size_t i = 0; i < GameConstants::F_NUMBER; i++) | ||||
| 			entry["tavern"][ETownType::names[i]].Float() = parser.readNumber(); | ||||
|  | ||||
| 		h3Data.push_back(entry); | ||||
| 	} | ||||
| 	while (parser.endLine() && !parser.isNextEntryEmpty()); | ||||
|  | ||||
| 	const JsonNode & heroGraphics = JsonNode(ResourceID("config/heroClasses.json")); | ||||
| 	JsonNode classConf = JsonNode(ResourceID("config/heroClasses.json")); | ||||
| 	heroClasses.resize(GameConstants::F_NUMBER * 2); | ||||
|  | ||||
| 	for (size_t i=0; i<heroClasses.size(); i++) | ||||
| 	BOOST_FOREACH(auto & node, classConf.Struct()) | ||||
| 	{ | ||||
| 		const JsonNode & battle = heroGraphics["heroBattleAnim"].Vector()[i/2]; | ||||
| 		int numeric = node.second["id"].Float(); | ||||
| 		JsonNode & classData = h3Data[numeric]; | ||||
| 		JsonUtils::merge(classData, node.second); | ||||
|  | ||||
| 		heroClasses[i]->imageBattleFemale = battle["female"].String(); | ||||
| 		heroClasses[i]->imageBattleMale = battle["male"].String(); | ||||
| 		heroClasses[numeric] = loadClass(classData); | ||||
| 		heroClasses[numeric]->id = numeric; | ||||
|  | ||||
| 		const JsonNode & map = heroGraphics["heroMapAnim"].Vector()[i]; | ||||
| 		VLC->modh->identifiers.registerObject ("heroClass." + node.first, numeric); | ||||
| 	} | ||||
|  | ||||
| 		heroClasses[i]->imageMapMale = map.String(); | ||||
| 		heroClasses[i]->imageMapFemale = map.String(); | ||||
| 	for (size_t i=0; i < heroClasses.size(); i++) | ||||
| 	{ | ||||
| 		if (heroClasses[i] == nullptr) | ||||
| 			tlog0 << "Warning: class with id " << i << " is missing!\n"; | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -98,7 +98,7 @@ class DLL_LINKAGE CHeroClass | ||||
| public: | ||||
| 	std::string identifier; | ||||
| 	std::string name; // translatable | ||||
| 	double aggression; | ||||
| 	//double aggression; // not used in vcmi. | ||||
| 	TFaction faction; | ||||
| 	ui8 id; | ||||
|  | ||||
| @@ -119,7 +119,7 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & identifier & name & faction & aggression; | ||||
| 		h & identifier & name & faction;// & aggression; | ||||
| 		h & primarySkillInitial   & primarySkillLowLevel; | ||||
| 		h & primarySkillHighLevel & secSkillProbability; | ||||
| 		h & selectionProbability; | ||||
|   | ||||
| @@ -26,11 +26,6 @@ namespace GameConstants | ||||
| 	    "wood", "mercury", "ore", "sulfur", "crystal", "gems", "gold", "mithril" | ||||
| 	}; | ||||
|  | ||||
| 	const std::string HERO_CLASSES_NAMES [F_NUMBER * 2] = { | ||||
| 	    "knight",    "cleric",     "ranger",      "druid",       "alchemist",    "wizard", | ||||
| 	    "demoniac",  "heretic",    "deathknight", "necromancer", "warlock",      "overlord", | ||||
| 	    "barbarian", "battlemage", "beastmaster", "witch",       "planeswalker", "elementalist" | ||||
| 	}; | ||||
| 	const std::string PLAYER_COLOR_NAMES [PlayerColor::PLAYER_LIMIT_I] = { | ||||
| 		"red", "blue", "tan", "green", "orange", "purple", "teal", "pink" | ||||
| 	}; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user