mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	- Implementation of overrides for towns
- Converted dwellings.json into new format - Implemented "mapObject" entry in town format - Removed capital/fort/village fields from town in favor of overrides
This commit is contained in:
		| @@ -500,7 +500,7 @@ void CKingdomInterface::generateObjectsList(const std::vector<const CGObjectInst | ||||
| 			OwnedObjectInfo &info = visibleObjects[object->subID]; | ||||
| 			if (info.count++ == 0) | ||||
| 			{ | ||||
| 				info.hoverText = CGI->creh->creatures[CGI->objh->cregens.find(object->subID)->second]->namePl; | ||||
| 				info.hoverText = object->getHoverText(); | ||||
| 				info.imageID = object->subID; | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
| @@ -1,108 +0,0 @@ | ||||
| { | ||||
| 	// Indicate which dwelling produces which creature | ||||
| 	// Note that it is 1<->n connection since | ||||
| 	// a creature can be produced by more than one dwelling. | ||||
| 	"dwellings": [ | ||||
| 		{ "dwelling": 0, "creature": 106 }, | ||||
| 		{ "dwelling": 1, "creature": 96 }, | ||||
| 		{ "dwelling": 2, "creature": 74 }, | ||||
| 		{ "dwelling": 3, "creature": 66 }, | ||||
| 		{ "dwelling": 4, "creature": 68 }, | ||||
| 		{ "dwelling": 5, "creature": 10 }, | ||||
| 		{ "dwelling": 6, "creature": 14 }, | ||||
| 		{ "dwelling": 7, "creature": 112 }, | ||||
| 		{ "dwelling": 8, "creature": 12 }, | ||||
| 		{ "dwelling": 9, "creature": 94 }, | ||||
| 		{ "dwelling": 10, "creature": 54 }, | ||||
| 		{ "dwelling": 11, "creature": 104 }, | ||||
| 		{ "dwelling": 12, "creature": 16 }, | ||||
| 		{ "dwelling": 13, "creature": 113 }, | ||||
| 		{ "dwelling": 14, "creature": 52 }, | ||||
| 		{ "dwelling": 15, "creature": 18 }, | ||||
| 		{ "dwelling": 16, "creature": 114 }, | ||||
| 		{ "dwelling": 17, "creature": 30 }, | ||||
| 		{ "dwelling": 18, "creature": 36 }, | ||||
| 		{ "dwelling": 19, "creature": 86 }, | ||||
| 		{ "dwelling": 20, "creature": 98 }, | ||||
| 		{ "dwelling": 21, "creature": 84 }, | ||||
| 		{ "dwelling": 22, "creature": 44 }, | ||||
| 		{ "dwelling": 23, "creature": 102 }, | ||||
| 		{ "dwelling": 24, "creature": 26 }, | ||||
| 		{ "dwelling": 25, "creature": 4 }, | ||||
| 		{ "dwelling": 26, "creature": 72 }, | ||||
| 		{ "dwelling": 27, "creature": 46 }, | ||||
| 		{ "dwelling": 28, "creature": 110 }, | ||||
| 		{ "dwelling": 29, "creature": 42 }, | ||||
| 		{ "dwelling": 30, "creature": 100 }, | ||||
| 		{ "dwelling": 31, "creature": 34 }, | ||||
| 		{ "dwelling": 32, "creature": 80 }, | ||||
| 		{ "dwelling": 33, "creature": 76 }, | ||||
| 		{ "dwelling": 34, "creature": 78 }, | ||||
| 		{ "dwelling": 35, "creature": 8 }, | ||||
| 		{ "dwelling": 36, "creature": 38 }, | ||||
| 		{ "dwelling": 37, "creature": 48 }, | ||||
| 		{ "dwelling": 38, "creature": 90 }, | ||||
| 		{ "dwelling": 39, "creature": 88 }, | ||||
| 		{ "dwelling": 40, "creature": 50 }, | ||||
| 		{ "dwelling": 41, "creature": 82 }, | ||||
| 		{ "dwelling": 42, "creature": 92 }, | ||||
| 		{ "dwelling": 43, "creature": 28 }, | ||||
| 		{ "dwelling": 44, "creature": 40 }, | ||||
| 		{ "dwelling": 45, "creature": 22 }, | ||||
| 		{ "dwelling": 46, "creature": 70 }, | ||||
| 		{ "dwelling": 47, "creature": 115 }, | ||||
| 		{ "dwelling": 48, "creature": 60 }, | ||||
| 		{ "dwelling": 49, "creature": 108 }, | ||||
| 		{ "dwelling": 50, "creature": 20 }, | ||||
| 		{ "dwelling": 51, "creature": 24 }, | ||||
| 		{ "dwelling": 52, "creature": 64 }, | ||||
| 		{ "dwelling": 53, "creature": 62 }, | ||||
| 		{ "dwelling": 54, "creature": 56 }, | ||||
| 		{ "dwelling": 55, "creature": 58 }, | ||||
| 		{ "dwelling": 56, "creature": 0 }, | ||||
| 		{ "dwelling": 57, "creature": 2 }, | ||||
| 		{ "dwelling": 58, "creature": 6 }, | ||||
| 		{ "dwelling": 59, "creature": 118 }, | ||||
| 		{ "dwelling": 60, "creature": 120 }, | ||||
| 		{ "dwelling": 61, "creature": 130 }, | ||||
| 		{ "dwelling": 62, "creature": 132 }, | ||||
| 		{ "dwelling": 63, "creature": 133 }, | ||||
| 		{ "dwelling": 64, "creature": 134 }, | ||||
| 		{ "dwelling": 65, "creature": 135 }, | ||||
| 		{ "dwelling": 66, "creature": 136 }, | ||||
| 		{ "dwelling": 67, "creature": 137 }, | ||||
| 		{ "dwelling": 68, "creature": 24 }, | ||||
| 		{ "dwelling": 69, "creature": 112 }, | ||||
| 		{ "dwelling": 70, "creature": 113 }, | ||||
| 		{ "dwelling": 71, "creature": 114 }, | ||||
| 		{ "dwelling": 72, "creature": 115 }, | ||||
| 		{ "dwelling": 73, "creature": 138 }, | ||||
| 		{ "dwelling": 74, "creature": 139 }, | ||||
| 		{ "dwelling": 75, "creature": 140 }, | ||||
| 		{ "dwelling": 76, "creature": 141 }, | ||||
| 		{ "dwelling": 77, "creature": 142 }, | ||||
| 		{ "dwelling": 78, "creature": 143 }, | ||||
| 		{ "dwelling": 79, "creature": 144 }, | ||||
| 		{ "dwelling": 80, "creature": 150 }, | ||||
| 		{ "dwelling": 81, "creature": 151 }, | ||||
| 		{ "dwelling": 82, "creature": 152 }, | ||||
| 		{ "dwelling": 83, "creature": 153 }, | ||||
| 		{ "dwelling": 84, "creature": 154 }, | ||||
| 		{ "dwelling": 85, "creature": 155 }, | ||||
| 		{ "dwelling": 86, "creature": 156 }, | ||||
| 		{ "dwelling": 87, "creature": 157 }, | ||||
| 		{ "dwelling": 88, "creature": 158 }, | ||||
| 		{ "dwelling": 89, "creature": 171 }, | ||||
| 		{ "dwelling": 90, "creature": 170 }, | ||||
| 		{ "dwelling": 91, "creature": 168 }, | ||||
| 		{ "dwelling": 92, "creature": 172 }, | ||||
| 		{ "dwelling": 93, "creature": 164 }, | ||||
| 		{ "dwelling": 94, "creature": 169 }, | ||||
| 		{ "dwelling": 95, "creature": 173 }, | ||||
| 		{ "dwelling": 96, "creature": 192 }, | ||||
| 		{ "dwelling": 97, "creature": 193 }, | ||||
| 		{ "dwelling": 98, "creature": 194 }, | ||||
| 		{ "dwelling": 99, "creature": 195 }, | ||||
| 		{ "dwelling": 100, "creature": 196 } | ||||
| 	] | ||||
| } | ||||
| @@ -66,11 +66,13 @@ | ||||
| 		}, | ||||
| 		"town" : | ||||
| 		{ | ||||
| 			"adventureMap" : | ||||
| 			"mapObject" : | ||||
| 			{ | ||||
| 				"castle" : "AVCcasx0.def", | ||||
| 				"village" : "AVCCAST0.DEF", | ||||
| 				"capitol" : "AVCCASZ0.DEF" | ||||
| 				"templates" : { | ||||
| 					"castle" :  { "animation" : "AVCcasx0.def" }, | ||||
| 					"village" : { "animation" : "AVCCAST0.DEF" }, | ||||
| 					"capitol" : { "animation" : "AVCCASZ0.DEF" } | ||||
| 				} | ||||
| 			}, | ||||
| 			"structures" : | ||||
| 			{ | ||||
|   | ||||
| @@ -66,11 +66,13 @@ | ||||
| 		}, | ||||
| 		"town" : | ||||
| 		{ | ||||
| 			"adventureMap" : | ||||
| 			"mapObject" : | ||||
| 			{ | ||||
| 				"castle" : "avchforx.def", | ||||
| 				"village" : "AVCHFOR0.DEF", | ||||
| 				"capitol" : "AVCHFORZ.DEF" | ||||
| 				"templates" : { | ||||
| 					"castle" :  { "animation" : "avchforx.def" }, | ||||
| 					"village" : { "animation" : "AVCHFOR0.DEF" }, | ||||
| 					"capitol" : { "animation" : "AVCHFORZ.DEF" } | ||||
| 				} | ||||
| 			}, | ||||
| 			"structures" : | ||||
| 			{ | ||||
|   | ||||
| @@ -66,11 +66,13 @@ | ||||
| 		}, | ||||
| 		"town" : | ||||
| 		{ | ||||
| 			"adventureMap" : | ||||
| 			"mapObject" : | ||||
| 			{ | ||||
| 				"castle" : "AVCdunx0.def", | ||||
| 				"village" : "AVCDUNG0.DEF", | ||||
| 				"capitol" : "AVCDUNZ0.DEF" | ||||
| 				"templates" : { | ||||
| 					"castle" :  { "animation" : "AVCdunx0.def" }, | ||||
| 					"village" : { "animation" : "AVCDUNG0.DEF" }, | ||||
| 					"capitol" : { "animation" : "AVCDUNZ0.DEF" } | ||||
| 				} | ||||
| 			}, | ||||
| 			"structures" : | ||||
| 			{ | ||||
|   | ||||
| @@ -66,11 +66,13 @@ | ||||
| 		}, | ||||
| 		"town" : | ||||
| 		{ | ||||
| 			"adventureMap" : | ||||
| 			"mapObject" : | ||||
| 			{ | ||||
| 				"castle" : "AVCftrx0.def", | ||||
| 				"village" : "AVCFTRT0.DEF", | ||||
| 				"capitol" : "AVCFORZ0.DEF" | ||||
| 				"templates" : { | ||||
| 					"castle" :  { "animation" : "AVCftrx0.def" }, | ||||
| 					"village" : { "animation" : "AVCFTRT0.DEF" }, | ||||
| 					"capitol" : { "animation" : "AVCFORZ0.DEF" } | ||||
| 				} | ||||
| 			}, | ||||
| 			"structures" : | ||||
| 			{ | ||||
|   | ||||
| @@ -66,11 +66,13 @@ | ||||
| 		}, | ||||
| 		"town" : | ||||
| 		{ | ||||
| 			"adventureMap" : | ||||
| 			"mapObject" : | ||||
| 			{ | ||||
| 				"castle" : "AVCinfx0.def", | ||||
| 				"village" : "AVCINFT0.DEF", | ||||
| 				"capitol" : "AVCINFZ0.DEF" | ||||
| 				"templates" : { | ||||
| 					"castle" :  { "animation" : "AVCinfx0.def" }, | ||||
| 					"village" : { "animation" : "AVCINFT0.DEF" }, | ||||
| 					"capitol" : { "animation" : "AVCINFZ0.DEF" } | ||||
| 				} | ||||
| 			}, | ||||
| 			"structures" : | ||||
| 			{ | ||||
|   | ||||
| @@ -66,11 +66,13 @@ | ||||
| 		}, | ||||
| 		"town" : | ||||
| 		{ | ||||
| 			"adventureMap" : | ||||
| 			"mapObject" : | ||||
| 			{ | ||||
| 				"castle" : "AVCnecx0.def", | ||||
| 				"village" : "AVCNECR0.DEF", | ||||
| 				"capitol" : "AVCNECZ0.DEF" | ||||
| 				"templates" : { | ||||
| 					"castle" :  { "animation" : "AVCnecx0.def" }, | ||||
| 					"village" : { "animation" : "AVCNECR0.DEF" }, | ||||
| 					"capitol" : { "animation" : "AVCNECZ0.DEF" } | ||||
| 				} | ||||
| 			}, | ||||
| 			"structures" : | ||||
| 			{ | ||||
|   | ||||
| @@ -66,11 +66,13 @@ | ||||
| 		}, | ||||
| 		"town" : | ||||
| 		{ | ||||
| 			"adventureMap" : | ||||
| 			"mapObject" : | ||||
| 			{ | ||||
| 				"castle" : "AVCramx0.def", | ||||
| 				"village" : "AVCRAMP0.DEF", | ||||
| 				"capitol" : "AVCRAMZ0.DEF" | ||||
| 				"templates" : { | ||||
| 					"castle" :  { "animation" : "AVCramx0.def" }, | ||||
| 					"village" : { "animation" : "AVCRAMP0.DEF" }, | ||||
| 					"capitol" : { "animation" : "AVCRAMZ0.DEF" } | ||||
| 				} | ||||
| 			}, | ||||
| 			"structures" : | ||||
| 			{ | ||||
|   | ||||
| @@ -66,11 +66,13 @@ | ||||
| 		}, | ||||
| 		"town" : | ||||
| 		{ | ||||
| 			"adventureMap" : | ||||
| 			"mapObject" : | ||||
| 			{ | ||||
| 				"castle" : "AVCstrx0.def", | ||||
| 				"village" : "AVCSTRO0.DEF", | ||||
| 				"capitol" : "AVCSTRZ0.DEF" | ||||
| 				"templates" : { | ||||
| 					"castle" :  { "animation" : "AVCstrx0.def" }, | ||||
| 					"village" : { "animation" : "AVCSTRO0.DEF" }, | ||||
| 					"capitol" : { "animation" : "AVCSTRZ0.DEF" } | ||||
| 				} | ||||
| 			}, | ||||
| 			"structures" : | ||||
| 			{ | ||||
|   | ||||
| @@ -66,11 +66,13 @@ | ||||
| 		}, | ||||
| 		"town" : | ||||
| 		{ | ||||
| 			"adventureMap" : | ||||
| 			"mapObject" : | ||||
| 			{ | ||||
| 				"castle" : "AVCtowx0.def", | ||||
| 				"village" : "AVCTOWR0.DEF", | ||||
| 				"capitol" : "AVCTOWZ0.DEF" | ||||
| 				"templates" : { | ||||
| 					"castle" :  { "animation" : "AVCtowx0.def" }, | ||||
| 					"village" : { "animation" : "AVCTOWR0.DEF" }, | ||||
| 					"capitol" : { "animation" : "AVCTOWZ0.DEF" } | ||||
| 				} | ||||
| 			}, | ||||
| 			"structures" : | ||||
| 			{ | ||||
|   | ||||
| @@ -49,6 +49,7 @@ | ||||
| 	[ | ||||
| 		"config/objects/generic.json", | ||||
| 		"config/objects/moddables.json", | ||||
| 		"config/objects/dwellings.json", | ||||
| 		"config/objects/rewardable.json" | ||||
| 	], | ||||
|  | ||||
|   | ||||
							
								
								
									
										126
									
								
								config/objects/dwellings.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								config/objects/dwellings.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| { | ||||
| 	"creatureGeneratorCommon" : { | ||||
| 		"index" :17, | ||||
| 		"handler": "dwelling", | ||||
| 		"base" : { | ||||
| 			"base" : { | ||||
| 				"visitableFrom" : [ "---", "+++", "+++" ], | ||||
| 				"mask" : [ "VVV", "VBB", "VAA" ] | ||||
| 			} | ||||
| 		}, | ||||
| 		"types" : { | ||||
| 			"basiliskPit" :      { "index" : 0,  "creatures" :  [ [ "basilisk" ] ] }, | ||||
| 			"behemothCrag" :     { "index" : 1,  "creatures" :  [ [ "behemoth" ] ], "guards" : true }, | ||||
| 			"pillarOfEyes" :     { "index" : 2,  "creatures" :  [ [ "beholder" ] ] }, | ||||
| 			"hallOfDarkness" :   { "index" : 3,  "creatures" :  [ [ "blackKnight" ] ], "guards" : true }, | ||||
| 			"dragonVault" :      { "index" : 4,  "creatures" :  [ [ "boneDragon" ] ], "guards" : true }, | ||||
| 			"trainingGrounds" :  { "index" : 5,  "creatures" :  [ [ "cavalier" ] ], "guards" : true }, | ||||
| 			"centaurStables" :   { "index" : 6,  "creatures" :  [ [ "centaur" ] ] }, | ||||
| 			"airConflux" :       { "index" : 7,  "creatures" :  [ [ "airElemental" ] ] }, | ||||
| 			"portalOfGlory" :    { "index" : 8,  "creatures" :  [ [ "angel" ] ], "guards" : true }, | ||||
| 			"cyclopsCave" :      { "index" : 9,  "creatures" :  [ [ "cyclop" ] ], "guards" : true }, | ||||
| 			"forsakenPalace" :   { "index" : 10, "creatures" : [ [ "devil" ] ], "guards" : true }, | ||||
| 			"serpentFlyHive" :   { "index" : 11, "creatures" : [ [ "serpentFly" ] ] }, | ||||
| 			"dwarfCottage" :     { "index" : 12, "creatures" : [ [ "dwarf" ] ] }, | ||||
| 			"earthConflux" :     { "index" : 13, "creatures" : [ [ "earthElemental" ] ], "guards" : true }, | ||||
| 			"fireLake" :         { "index" : 14, "creatures" : [ [ "efreet" ] ], "guards" : true }, | ||||
| 			"homestead" :        { "index" : 15, "creatures" : [ [ "woodElf" ] ] }, | ||||
| 			"fireConflux" :      { "index" : 16, "creatures" : [ [ "fireElemental" ] ] }, | ||||
| 			"parapet" :          { "index" : 17, "creatures" : [ [ "stoneGargoyle" ] ] }, | ||||
| 			"altarOfWishes" :    { "index" : 18, "creatures" : [ [ "genie" ] ], "guards" : true }, | ||||
| 			"wolfPen" :          { "index" : 19, "creatures" : [ [ "goblinWolfRider" ] ] }, | ||||
| 			"gnollHut" :         { "index" : 20, "creatures" : [ [ "gnoll" ] ] }, | ||||
| 			"goblinBarracks" :   { "index" : 21, "creatures" : [ [ "goblin" ] ] }, | ||||
| 			"hallOfSins" :       { "index" : 22, "creatures" : [ [ "gog" ] ] }, | ||||
| 			"gorgonLair" :       { "index" : 23, "creatures" : [ [ "gorgon" ] ], "guards" : true }, | ||||
| 			"dragonCliffs" :     { "index" : 24, "creatures" : [ [ "greenDragon" ] ], "guards" : true }, | ||||
| 			"griffinTower" :     { "index" : 25, "creatures" : [ [ "griffin" ] ] }, | ||||
| 			"harpyLoft" :        { "index" : 26, "creatures" : [ [ "harpy" ] ] }, | ||||
| 			"kennels" :          { "index" : 27, "creatures" : [ [ "hellHound" ] ] }, | ||||
| 			"hydraPond" :        { "index" : 28, "creatures" : [ [ "hydra" ] ], "guards" : true }, | ||||
| 			"impCrucible" :      { "index" : 29, "creatures" : [ [ "imp" ] ] }, | ||||
| 			"lizardDen" :        { "index" : 30, "creatures" : [ [ "lizardman" ] ] }, | ||||
| 			"mageTower" :        { "index" : 31, "creatures" : [ [ "mage" ] ] }, | ||||
| 			"manticoreLair" :    { "index" : 32, "creatures" : [ [ "manticore" ] ], "guards" : true }, | ||||
| 			"medusaChapel" :     { "index" : 33, "creatures" : [ [ "medusa" ] ] }, | ||||
| 			"labyrinth" :        { "index" : 34, "creatures" : [ [ "minotaur" ] ], "guards" : true }, | ||||
| 			"monastery" :        { "index" : 35, "creatures" : [ [ "monk" ] ], "guards" : true }, | ||||
| 			"goldenPavilion" :   { "index" : 36, "creatures" : [ [ "naga" ] ], "guards" : true }, | ||||
| 			"demonGate" :        { "index" : 37, "creatures" : [ [ "demon" ] ] }, | ||||
| 			"ogreFort" :         { "index" : 38, "creatures" : [ [ "ogre" ] ] }, | ||||
| 			"orcTower" :         { "index" : 39, "creatures" : [ [ "orc" ] ] }, | ||||
| 			"hellHole" :         { "index" : 40, "creatures" : [ [ "pitFiend" ] ], "guards" : true }, | ||||
| 			"dragonCave" :       { "index" : 41, "creatures" : [ [ "redDragon" ] ], "guards" : true }, | ||||
| 			"cliffNest" :        { "index" : 42, "creatures" : [ [ "roc" ] ], "guards" : true }, | ||||
| 			"workshop" :         { "index" : 43, "creatures" : [ [ "gremlin" ] ] }, | ||||
| 			"cloudTemple" :      { "index" : 44, "creatures" : [ [ "giant" ] ], "guards" : true }, | ||||
| 			"dendroidArches" :   { "index" : 45, "creatures" : [ [ "dendroidGuard" ] ], "guards" : true }, | ||||
| 			"warren" :           { "index" : 46, "creatures" : [ [ "troglodyte" ] ] }, | ||||
| 			"waterConflux" :     { "index" : 47, "creatures" : [ [ "waterElemental" ] ] }, | ||||
| 			"tombOfSouls" :      { "index" : 48, "creatures" : [ [ "wight" ] ] }, | ||||
| 			"wyvernNest" :       { "index" : 49, "creatures" : [ [ "wyvern" ] ], "guards" : true }, | ||||
| 			"enchantedSpring" :  { "index" : 50, "creatures" : [ [ "pegasus" ] ] }, | ||||
| 			"unicornGladeBig" :  { "index" : 51, "creatures" : [ [ "unicorn" ] ], "guards" : true }, | ||||
| 			"mausoleum" :        { "index" : 52, "creatures" : [ [ "lich" ] ], "guards" : true }, | ||||
| 			"estate" :           { "index" : 53, "creatures" : [ [ "vampire" ] ] }, | ||||
| 			"cursedTemple" :     { "index" : 54, "creatures" : [ [ "skeleton" ] ] }, | ||||
| 			"graveyard" :        { "index" : 55, "creatures" : [ [ "walkingDead" ] ] }, | ||||
| 			"guardhouse" :       { "index" : 56, "creatures" : [ [ "pikeman" ] ] }, | ||||
| 			"archersTower" :     { "index" : 57, "creatures" : [ [ "archer" ] ] }, | ||||
| 			"barracks" :         { "index" : 58, "creatures" : [ [ "swordsman" ] ] }, | ||||
| 			"magicLantern" :     { "index" : 59, "creatures" : [ [ "pixie" ] ] }, | ||||
| 			"altarOfThought" :   { "index" : 60, "creatures" : [ [ "psychicElemental" ] ], "guards" : true }, | ||||
| 			"pyre" :             { "index" : 61, "creatures" : [ [ "firebird" ] ], "guards" : true }, | ||||
| 			"frozenCliffs" :     { "index" : 62, "creatures" : [ [ "azureDragon" ] ], "guards" : true }, | ||||
| 			"crystalCavern" :    { "index" : 63, "creatures" : [ [ "crystalDragon" ] ], "guards" : true }, | ||||
| 			"magicForest" :      { "index" : 64, "creatures" : [ [ "fairieDragon" ] ], "guards" : true }, | ||||
| 			"sulfurousLair" :    { "index" : 65, "creatures" : [ [ "rustDragon" ] ], "guards" : true }, | ||||
| 			"enchantersHollow" : { "index" : 66, "creatures" : [ [ "enchanter" ] ], "guards" : true }, | ||||
| 			"treetopTower" :     { "index" : 67, "creatures" : [ [ "sharpshooter" ] ], "guards" : true }, | ||||
| 			"unicornGlade" :     { "index" : 68, "creatures" : [ [ "unicorn" ] ], "guards" : true }, | ||||
| 			"altarOfAir" :       { "index" : 69, "creatures" : [ [ "airElemental" ] ] }, | ||||
| 			"altarOfEarth" :     { "index" : 70, "creatures" : [ [ "earthElemental" ] ], "guards" : true }, | ||||
| 			"altarOfFire" :      { "index" : 71, "creatures" : [ [ "fireElemental" ] ] }, | ||||
| 			"altarOfWater" :     { "index" : 72, "creatures" : [ [ "waterElemental" ] ] }, | ||||
| 			"thatchedHut" :      { "index" : 73, "creatures" : [ [ "halfling" ] ] }, | ||||
| 			"hovel" :            { "index" : 74, "creatures" : [ [ "peasant" ] ] }, | ||||
| 			"boarGlen" :         { "index" : 75, "creatures" : [ [ "boar" ] ] }, | ||||
| 			"tombOfCurses" :     { "index" : 76, "creatures" : [ [ "mummy" ] ] }, | ||||
| 			"nomadTent" :        { "index" : 77, "creatures" : [ [ "nomad" ] ] }, | ||||
| 			"rogueCavern" :      { "index" : 78, "creatures" : [ [ "rogue" ] ] }, | ||||
| 			"trollBridge" :      { "index" : 79, "creatures" : [ [ "troll" ] ], "guards" : true } | ||||
| 		} | ||||
| 	}, | ||||
| 	// subtype: unique special dwellings - golem factory and elemental conflux | ||||
| 	"creatureGeneratorSpecial" : { | ||||
| 		"index" :20, | ||||
| 		"handler": "dwelling", | ||||
| 		"types" : { | ||||
| 			"elementalConflux" : { | ||||
| 				"index" : 0, | ||||
| 				"creatures" : [ // 4 separate "levels" to give them separate growth | ||||
| 					[ "airElemental" ], | ||||
| 					[ "waterElemental" ], | ||||
| 					[ "fireElemental" ], | ||||
| 					[ "earthElemental" ] | ||||
| 				], | ||||
| 				"guards" : { | ||||
| 					"earthElemental" : 12 | ||||
| 				} | ||||
| 			}, | ||||
| 			"golemFactory" : { | ||||
| 				"index" : 1, | ||||
| 				"creatures" : [ // 4 separate "levels" to give them separate growth | ||||
| 					[ "ironGolem" ], | ||||
| 					[ "stoneGolem" ], | ||||
| 					[ "goldGolem" ], | ||||
| 					[ "diamondGolem" ] | ||||
| 				], | ||||
| 				"guards" : { | ||||
| 					"goldGolem" : 9, | ||||
| 					"diamondGolem" : 6 | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	}, | ||||
| } | ||||
| @@ -48,6 +48,16 @@ | ||||
| 				"visitableFrom" : [ "+++", "+-+", "+++" ], | ||||
| 				"mask" : [ "VA" ] | ||||
| 			} | ||||
| 		}, | ||||
| 		"types" : { | ||||
| 			"wood" :    { "index" : 0 }, | ||||
| 			"mercury" : { "index" : 1 }, | ||||
| 			"ore" :     { "index" : 2 }, | ||||
| 			"sulfur" :  { "index" : 3 }, | ||||
| 			"crystal" : { "index" : 4 }, | ||||
| 			"gems" :    { "index" : 5 }, | ||||
| 			"gold" :    { "index" : 6 }, | ||||
| 			"mithril" : { "index" : 7 } // TODO: move to WoG? | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| @@ -56,7 +66,7 @@ | ||||
| 		"index" :98, | ||||
| 		"handler": "town", | ||||
| 		"base" : { | ||||
| 			"filter" : { | ||||
| 			"filters" : { | ||||
| 				// village image - fort not present | ||||
| 				"village" : [ "noneOf", [ "fort" ] ], | ||||
| 				// fort image - fort is here but not capitol | ||||
| @@ -125,21 +135,6 @@ | ||||
| 	// subtype: faction ID | ||||
| 	"randomDwellingFaction"			: { "index" :218, "handler": "dwelling" }, | ||||
|  | ||||
| 	// subtype: not well defined, describes various dwellings that can be placed as random | ||||
| 	"creatureGeneratorCommon" : { | ||||
| 		"index" :17, | ||||
| 		"handler": "dwelling", | ||||
| 		"base" : { | ||||
| 			"base" : { | ||||
| 				"visitableFrom" : [ "---", "+++", "+++" ], | ||||
| 				"mask" : [ "VVV", "VBB", "VAA" ] | ||||
| 			} | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	// subtype: unique special dwellings - golem factory, elemental conflux | ||||
| 	"creatureGeneratorSpecial"		: { "index" :20, "handler": "dwelling" }, | ||||
| 	 | ||||
| 	// don't have subtypes (at least now), but closely connected to this objects | ||||
| 	"spellScroll"					: { "index" :93, "handler": "artifact" }, | ||||
| 	"heroPlaceholder"				: { "index" :214, "handler": "heroPlaceholder" } | ||||
|   | ||||
| @@ -622,23 +622,28 @@ std::pair<Obj,int> CGameState::pickObject (CGObjectInstance *obj) | ||||
| 			std::pair<Obj, int> result(Obj::NO_OBJ, -1); | ||||
| 			CreatureID cid = VLC->townh->factions[faction]->town->creatures[level][0]; | ||||
|  | ||||
| 			//golem factory is not in list of cregens but can be placed as random object | ||||
| 			static const CreatureID factoryCreatures[] = {CreatureID::STONE_GOLEM, CreatureID::IRON_GOLEM, | ||||
| 				CreatureID::GOLD_GOLEM, CreatureID::DIAMOND_GOLEM}; | ||||
| 			std::vector<CreatureID> factory(factoryCreatures, factoryCreatures + ARRAY_COUNT(factoryCreatures)); | ||||
| 			if (vstd::contains(factory, cid)) | ||||
| 				result = std::make_pair(Obj::CREATURE_GENERATOR4, 1); | ||||
|  | ||||
| 			//NOTE: this will pick last dwelling with this creature (Mantis #900) | ||||
| 			//check for block map equality is better but more complex solution | ||||
| 			for(auto &iter : VLC->objh->cregens) | ||||
| 				if (iter.second == cid) | ||||
| 					result = std::make_pair(Obj::CREATURE_GENERATOR1, iter.first); | ||||
| 			auto testID = [&](Obj primaryID) -> void | ||||
| 			{ | ||||
| 				auto dwellingIDs = VLC->objtypeh->knownSubObjects(primaryID); | ||||
| 				for (si32 entry : dwellingIDs) | ||||
| 				{ | ||||
| 					auto handler = dynamic_cast<const CDwellingInstanceConstructor*>(VLC->objtypeh->getHandlerFor(primaryID, entry).get()); | ||||
|  | ||||
| 					if (handler->producesCreature(VLC->creh->creatures[cid])) | ||||
| 						result = std::make_pair(primaryID, entry); | ||||
| 				} | ||||
| 			}; | ||||
|  | ||||
| 			testID(Obj::CREATURE_GENERATOR1); | ||||
| 			if (result.first == Obj::NO_OBJ) | ||||
| 				testID(Obj::CREATURE_GENERATOR4); | ||||
|  | ||||
| 			if (result.first == Obj::NO_OBJ) | ||||
| 			{ | ||||
|                 logGlobal->errorStream() << "Error: failed to find creature for dwelling of "<< int(faction) << " of level " << int(level); | ||||
| 				result = std::make_pair(Obj::CREATURE_GENERATOR1, RandomGeneratorUtil::nextItem(VLC->objh->cregens, rand)->first); | ||||
| 				logGlobal->errorStream() << "Error: failed to find dwelling for "<< VLC->townh->factions[faction]->name << " of level " << int(level); | ||||
| 				result = std::make_pair(Obj::CREATURE_GENERATOR1, *RandomGeneratorUtil::nextItem(VLC->objtypeh->knownSubObjects(Obj::CREATURE_GENERATOR1), rand)); | ||||
| 			} | ||||
|  | ||||
| 			return result; | ||||
|   | ||||
| @@ -128,7 +128,7 @@ boost::optional<si32> CIdentifierStorage::getIdentifier(std::string scope, std:: | ||||
| 	if (idList.size() == 1) | ||||
| 		return idList.front().id; | ||||
| 	if (!silent) | ||||
| 		logGlobal->errorStream() << "Failed to resolve identifier " << name << " from mod " << scope; | ||||
| 		logGlobal->errorStream() << "Failed to resolve identifier " << name << " of type " << type << " from mod " << scope; | ||||
|  | ||||
| 	return boost::optional<si32>(); | ||||
| } | ||||
| @@ -141,7 +141,7 @@ boost::optional<si32> CIdentifierStorage::getIdentifier(std::string type, const | ||||
| 	if (idList.size() == 1) | ||||
| 		return idList.front().id; | ||||
| 	if (!silent) | ||||
| 		logGlobal->errorStream() << "Failed to resolve identifier " << name.String() << " from mod " << type; | ||||
| 		logGlobal->errorStream() << "Failed to resolve identifier " << name.String() << " of type " << type << " from mod " << name.meta; | ||||
|  | ||||
| 	return boost::optional<si32>(); | ||||
| } | ||||
| @@ -155,7 +155,7 @@ boost::optional<si32> CIdentifierStorage::getIdentifier(const JsonNode & name, b | ||||
| 	if (idList.size() == 1) | ||||
| 		return idList.front().id; | ||||
| 	if (!silent) | ||||
| 		logGlobal->errorStream() << "Failed to resolve identifier " << name.String() << " from mod " << name.meta; | ||||
| 		logGlobal->errorStream() << "Failed to resolve identifier " << name.String() << " of type " << pair2.first << " from mod " << name.meta; | ||||
|  | ||||
| 	return boost::optional<si32>(); | ||||
| } | ||||
| @@ -223,7 +223,9 @@ bool CIdentifierStorage::resolveIdentifier(const ObjectCallback & request) | ||||
| 	} | ||||
|  | ||||
| 	if (request.optional && identifiers.empty()) // failed to resolve optinal ID | ||||
| 	{ | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	// error found. Try to generate some debug info | ||||
| 	if (identifiers.size() == 0) | ||||
| @@ -244,16 +246,17 @@ void CIdentifierStorage::finalize() | ||||
| { | ||||
| 	bool errorsFound = false; | ||||
|  | ||||
| 	for(const ObjectCallback & request : scheduledRequests) | ||||
| 	//Note: we may receive new requests during resolution phase -> end may change -> range for can't be used | ||||
| 	for(auto it = scheduledRequests.begin(); it != scheduledRequests.end(); it++) | ||||
| 	{ | ||||
| 		errorsFound |= !resolveIdentifier(request); | ||||
| 		errorsFound |= !resolveIdentifier(*it); | ||||
| 	} | ||||
|  | ||||
| 	if (errorsFound) | ||||
| 	{ | ||||
| 		for(auto object : registeredObjects) | ||||
| 		{ | ||||
| 			logGlobal->traceStream() << object.first << " -> " << object.second.id; | ||||
| 			logGlobal->traceStream() << object.second.scope << " : " << object.first << " -> " << object.second.id; | ||||
| 		} | ||||
| 		logGlobal->errorStream() << "All known identifiers were dumped into log file"; | ||||
| 	} | ||||
|   | ||||
| @@ -554,10 +554,6 @@ void CTownHandler::loadClientData(CTown &town, const JsonNode & source) | ||||
| 		info.tavernVideo = "TAVERN.BIK"; | ||||
| 	//end of legacy assignment  | ||||
|  | ||||
| 	info.advMapVillage = source["adventureMap"]["village"].String(); | ||||
| 	info.advMapCastle  = source["adventureMap"]["castle"].String(); | ||||
| 	info.advMapCapitol = source["adventureMap"]["capitol"].String(); | ||||
|  | ||||
| 	loadTownHall(town,   source["hallSlots"]); | ||||
| 	loadStructures(town, source["structures"]); | ||||
| 	loadSiegeScreen(town, source["siege"]); | ||||
| @@ -723,6 +719,8 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod | ||||
| 	auto object = loadFromJson(data, name); | ||||
|  | ||||
| 	object->index = factions.size(); | ||||
| 	factions.push_back(object); | ||||
|  | ||||
| 	if (object->town) | ||||
| 	{ | ||||
| 		auto & info = object->town->clientInfo; | ||||
| @@ -730,9 +728,16 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod | ||||
| 		info.icons[0][1] = 8 + object->index * 4 + 1; | ||||
| 		info.icons[1][0] = 8 + object->index * 4 + 2; | ||||
| 		info.icons[1][1] = 8 + object->index * 4 + 3; | ||||
| 	} | ||||
|  | ||||
| 	factions.push_back(object); | ||||
| 		VLC->modh->identifiers.requestIdentifier(scope, "object", "town", [=](si32 index) | ||||
| 		{ | ||||
| 			// register town once objects are loaded | ||||
| 			JsonNode config = data["town"]["mapObject"]; | ||||
| 			config["faction"].String() = object->identifier; | ||||
| 			config["faction"].meta = scope; | ||||
| 			VLC->objtypeh->loadSubObject(object->identifier, config, index, object->index); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	VLC->modh->identifiers.registerObject(scope, "faction", name, object->index); | ||||
| } | ||||
| @@ -741,6 +746,9 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod | ||||
| { | ||||
| 	auto object = loadFromJson(data, name); | ||||
| 	object->index = index; | ||||
| 	assert(factions[index] == nullptr); // ensure that this id was not loaded before | ||||
| 	factions[index] = object; | ||||
|  | ||||
| 	if (object->town) | ||||
| 	{ | ||||
| 		auto & info = object->town->clientInfo; | ||||
| @@ -748,10 +756,16 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod | ||||
| 		info.icons[0][1] = (GameConstants::F_NUMBER + object->index) * 2 + 1; | ||||
| 		info.icons[1][0] = object->index * 2 + 0; | ||||
| 		info.icons[1][1] = object->index * 2 + 1; | ||||
| 	} | ||||
|  | ||||
| 	assert(factions[index] == nullptr); // ensure that this id was not loaded before | ||||
| 	factions[index] = object; | ||||
| 		VLC->modh->identifiers.requestIdentifier(scope, "object", "town", [=](si32 index) | ||||
| 		{ | ||||
| 			// register town once objects are loaded | ||||
| 			JsonNode config = data["town"]["mapObject"]; | ||||
| 			config["faction"].String() = object->identifier; | ||||
| 			config["faction"].meta = scope; | ||||
| 			VLC->objtypeh->loadSubObject(object->identifier, config, index, object->index); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	VLC->modh->identifiers.registerObject(scope, "faction", name, object->index); | ||||
| } | ||||
| @@ -761,31 +775,20 @@ void CTownHandler::afterLoadFinalization() | ||||
| 	initializeRequirements(); | ||||
| 	for (CFaction * fact : factions) | ||||
| 	{ | ||||
| 		// MODS COMPATIBILITY FOR 0.96 | ||||
| 		if (fact->town) | ||||
| 		{ | ||||
| 			VLC->objtypeh->loadSubObject(fact->identifier, JsonNode(), Obj::TOWN, fact->index); | ||||
| 			if (!fact->town->clientInfo.advMapCastle.empty()) | ||||
| 			{ | ||||
| 				JsonNode templ; | ||||
| 				templ["animation"].String() = fact->town->clientInfo.advMapCastle; | ||||
| 				VLC->objtypeh->getHandlerFor(Obj::TOWN, fact->index)->addTemplate(templ); | ||||
| 			} | ||||
|  | ||||
| 			assert(fact->town->dwellings.size() == fact->town->dwellingNames.size()); | ||||
| 			for (size_t i=0; i<fact->town->dwellings.size(); i++) | ||||
| 			{ | ||||
| 				//both unupgraded and upgraded get same dwelling | ||||
| 				for (auto cre : fact->town->creatures[i]) | ||||
| 				{ | ||||
| 					if (VLC->objh->cregens.count(cre) == 0) | ||||
| 					{ | ||||
| 						JsonNode templ; | ||||
| 						templ["animation"].String() = fact->town->dwellings[i]; | ||||
| 					JsonNode templ; | ||||
| 					templ["animation"].String() = fact->town->dwellings[i]; | ||||
|  | ||||
| 						VLC->objtypeh->loadSubObject("", JsonNode(), Obj::CREATURE_GENERATOR1, 80 + cre); | ||||
| 						VLC->objtypeh->getHandlerFor(Obj::CREATURE_GENERATOR1, 80 + cre)->addTemplate(templ); | ||||
| 						VLC->objh->cregens[80 + cre] = cre; //map of dwelling -> creature id | ||||
| 					} | ||||
| 					VLC->objtypeh->loadSubObject("", JsonNode(), Obj::CREATURE_GENERATOR1, 100 + cre); | ||||
| 					VLC->objtypeh->getHandlerFor(Obj::CREATURE_GENERATOR1, 100 + cre)->addTemplate(templ); | ||||
| 				 } | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
| @@ -190,10 +190,6 @@ public: | ||||
| 		/// NOTE: index in vector is meaningless. Vector used instead of list for a bit faster access | ||||
| 		std::vector<ConstTransitivePtr<CStructure> > structures; | ||||
|  | ||||
| 		std::string advMapVillage; | ||||
| 		std::string advMapCastle; | ||||
| 		std::string advMapCapitol; | ||||
|  | ||||
| 		std::string siegePrefix; | ||||
| 		std::vector<Point> siegePositions; | ||||
| 		CreatureID siegeShooter; // shooter creature ID | ||||
| @@ -201,7 +197,7 @@ public: | ||||
| 		template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 		{ | ||||
| 			h & icons & iconSmall & iconLarge & tavernVideo & musicTheme & townBackground & guildBackground & guildWindow & buildingsIcons & hallBackground; | ||||
| 			h & advMapVillage & advMapCastle & advMapCapitol & hallSlots & structures; | ||||
| 			h & hallSlots & structures; | ||||
| 			h & siegePrefix & siegePositions & siegeShooter; | ||||
| 		} | ||||
| 	} clientInfo; | ||||
|   | ||||
| @@ -737,7 +737,7 @@ void JsonUtils::mergeCopy(JsonNode & dest, JsonNode source) | ||||
|  | ||||
| void JsonUtils::inherit(JsonNode & descendant, const JsonNode & base) | ||||
| { | ||||
| 	JsonNode inheritedNode(base);		 | ||||
| 	JsonNode inheritedNode(base); | ||||
| 	merge(inheritedNode,descendant); | ||||
| 	descendant.swap(inheritedNode); | ||||
| } | ||||
|   | ||||
| @@ -45,11 +45,11 @@ DLL_LINKAGE void preinitDLL(CConsoleHandler *Console) | ||||
|  | ||||
| DLL_LINKAGE void loadDLLClasses() | ||||
| { | ||||
| 	try | ||||
| //	try | ||||
| 	{ | ||||
| 		VLC->init(); | ||||
| 	} | ||||
| 	HANDLE_EXCEPTION; | ||||
| //	HANDLE_EXCEPTION; | ||||
| } | ||||
|  | ||||
| const IBonusTypeHandler * LibClasses::getBth() const | ||||
|   | ||||
| @@ -13,6 +13,7 @@ | ||||
|  | ||||
| #include "../NetPacks.h" | ||||
| #include "../CGeneralTextHandler.h" | ||||
| #include "../mapObjects/CObjectClassesHandler.h" | ||||
|  | ||||
| using namespace boost::assign; | ||||
|  | ||||
| @@ -24,54 +25,18 @@ void CGDwelling::initObj() | ||||
| 	switch(ID) | ||||
| 	{ | ||||
| 	case Obj::CREATURE_GENERATOR1: | ||||
| 	case Obj::CREATURE_GENERATOR4: | ||||
| 		{ | ||||
| 			CreatureID crid = VLC->objh->cregens[subID]; | ||||
| 			const CCreature *crs = VLC->creh->creatures[crid]; | ||||
| 			VLC->objtypeh->getHandlerFor(ID, subID)->configureObject(this, cb->gameState()->getRandomGenerator()); | ||||
|  | ||||
| 			creatures.resize(1); | ||||
| 			creatures[0].second.push_back(crid); | ||||
| 			if (subID >= VLC->generaltexth->creGens.size()) //very messy workaround | ||||
| 			{ | ||||
| 				auto & dwellingNames = VLC->townh->factions[crs->faction]->town->dwellingNames; | ||||
| 				assert (dwellingNames.size() > crs->level - 1); | ||||
| 				hoverName = dwellingNames[crs->level - 1]; | ||||
| 			} | ||||
| 			else | ||||
| 				hoverName = VLC->generaltexth->creGens[subID]; | ||||
| 			if(crs->level > 4) | ||||
| 				putStack(SlotID(0), new CStackInstance(crs, (crs->growth) * 3)); | ||||
| 			if (getOwner() != PlayerColor::NEUTRAL) | ||||
| 				cb->gameState()->players[getOwner()].dwellings.push_back (this); | ||||
| 		} | ||||
| 		break; | ||||
| 			//putStack(SlotID(0), new CStackInstance(CreatureID::GOLD_GOLEM, 9)); | ||||
| 			//putStack(SlotID(1), new CStackInstance(CreatureID::DIAMOND_GOLEM, 6)); | ||||
|  | ||||
| 	case Obj::CREATURE_GENERATOR4: | ||||
| 		creatures.resize(4); | ||||
| 		if(subID == 1) //Golem Factory | ||||
| 		{ | ||||
| 			creatures[0].second.push_back(CreatureID::STONE_GOLEM); | ||||
| 			creatures[1].second.push_back(CreatureID::IRON_GOLEM); | ||||
| 			creatures[2].second.push_back(CreatureID::GOLD_GOLEM); | ||||
| 			creatures[3].second.push_back(CreatureID::DIAMOND_GOLEM); | ||||
| 			//guards | ||||
| 			putStack(SlotID(0), new CStackInstance(CreatureID::GOLD_GOLEM, 9)); | ||||
| 			putStack(SlotID(1), new CStackInstance(CreatureID::DIAMOND_GOLEM, 6)); | ||||
| 		} | ||||
| 		else if(subID == 0) // Elemental Conflux | ||||
| 		{ | ||||
| 			creatures[0].second.push_back(CreatureID::AIR_ELEMENTAL); | ||||
| 			creatures[1].second.push_back(CreatureID::FIRE_ELEMENTAL); | ||||
| 			creatures[2].second.push_back(CreatureID::EARTH_ELEMENTAL); | ||||
| 			creatures[3].second.push_back(CreatureID::WATER_ELEMENTAL); | ||||
| 			//guards | ||||
| 			putStack(SlotID(0), new CStackInstance(CreatureID::EARTH_ELEMENTAL, 12)); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			assert(0); | ||||
| 		} | ||||
| 		hoverName = VLC->generaltexth->creGens4[subID]; | ||||
| 		break; | ||||
| 			//putStack(SlotID(0), new CStackInstance(CreatureID::EARTH_ELEMENTAL, 12)); | ||||
| 			break; | ||||
|  | ||||
| 	case Obj::REFUGEE_CAMP: | ||||
| 		//is handled within newturn func | ||||
| @@ -811,12 +776,10 @@ void CGTownInstance::setType(si32 ID, si32 subID) | ||||
|  | ||||
| void CGTownInstance::updateAppearance() | ||||
| { | ||||
| 	if (!hasFort()) | ||||
| 		appearance.animationFile = town->clientInfo.advMapVillage; | ||||
| 	else if(hasCapitol()) | ||||
| 		appearance.animationFile = town->clientInfo.advMapCapitol; | ||||
| 	else | ||||
| 		appearance.animationFile = town->clientInfo.advMapCastle; | ||||
| 	//FIXME: not the best way to do this | ||||
| 	auto app = VLC->objtypeh->getHandlerFor(ID, subID)->getOverride(cb->gameState()->getTile(visitablePos())->terType, this); | ||||
| 	if (app) | ||||
| 		appearance = app.get(); | ||||
| } | ||||
|  | ||||
| std::string CGTownInstance::nodeName() const | ||||
|   | ||||
| @@ -153,6 +153,7 @@ void CObjectClassesHandler::loadObjectEntry(const JsonNode & entry, ObjectContai | ||||
| 	} | ||||
| 	 | ||||
| 	obj->objects[id] = handler; | ||||
| 	logGlobal->debugStream() << "Loaded object " << obj->id << ":" << id; | ||||
| } | ||||
|  | ||||
| CObjectClassesHandler::ObjectContainter * CObjectClassesHandler::loadFromJson(const JsonNode & json) | ||||
| @@ -198,8 +199,9 @@ void CObjectClassesHandler::loadSubObject(std::string name, JsonNode config, si3 | ||||
| 		config["index"].Float() = subID.get(); | ||||
| 	} | ||||
|  | ||||
| 	std::string oldMeta = config.meta; // FIXME: move into inheritNode? | ||||
| 	JsonUtils::inherit(config, objects.at(ID)->base); | ||||
| 	logGlobal->errorStream() << "JSON: " << config; | ||||
| 	config.setMeta(oldMeta); | ||||
| 	loadObjectEntry(config, objects[ID]); | ||||
| } | ||||
|  | ||||
| @@ -339,9 +341,6 @@ void AObjectTypeHandler::addTemplate(ObjectTemplate templ) | ||||
|  | ||||
| void AObjectTypeHandler::addTemplate(JsonNode config) | ||||
| { | ||||
| 	logGlobal->errorStream() << "INPUT  FOR: " << type << ":" << subtype << " " << config; | ||||
| 	logGlobal->errorStream() << "BASE   FOR: " << type << ":" << subtype << " " << base; | ||||
|  | ||||
| 	config.setType(JsonNode::DATA_STRUCT); // ensure that input is not null | ||||
| 	JsonUtils::inherit(config, base); | ||||
| 	ObjectTemplate tmpl; | ||||
| @@ -349,7 +348,6 @@ void AObjectTypeHandler::addTemplate(JsonNode config) | ||||
| 	tmpl.subid = subtype; | ||||
| 	tmpl.stringID = ""; // TODO? | ||||
| 	tmpl.readJson(config); | ||||
| 	logGlobal->errorStream() << "DATA  FOR: " << type << ":" << subtype << " " << config; | ||||
| 	addTemplate(tmpl); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -68,7 +68,7 @@ public: | ||||
|  | ||||
| class CGObjectInstance; | ||||
|  | ||||
| class AObjectTypeHandler | ||||
| class AObjectTypeHandler : public boost::noncopyable | ||||
| { | ||||
| 	RandomMapInfo rmgInfo; | ||||
|  | ||||
|   | ||||
| @@ -157,15 +157,6 @@ static void readBankLevel(const JsonNode &level, BankConfig &bc) | ||||
|  | ||||
| CObjectHandler::CObjectHandler() | ||||
| { | ||||
|     logGlobal->traceStream() << "\t\tReading cregens "; | ||||
|  | ||||
| 	const JsonNode config(ResourceID("config/dwellings.json")); | ||||
| 	for(const JsonNode &dwelling : config["dwellings"].Vector()) | ||||
| 	{ | ||||
| 		cregens[dwelling["dwelling"].Float()] = CreatureID((si32)dwelling["creature"].Float()); | ||||
| 	} | ||||
|     logGlobal->traceStream() << "\t\tDone loading cregens!"; | ||||
|  | ||||
|     logGlobal->traceStream() << "\t\tReading resources prices "; | ||||
| 	const JsonNode config2(ResourceID("config/resources.json")); | ||||
| 	for(const JsonNode &price : config2["resources_prices"].Vector()) | ||||
| @@ -342,10 +333,10 @@ void CGObjectInstance::setType(si32 ID, si32 subID) | ||||
|  | ||||
| 	this->ID = Obj(ID); | ||||
| 	this->subID = subID; | ||||
| 	this->appearance = VLC->objtypeh->getHandlerFor(ID, subID)->getTemplates(tile.terType).front(); | ||||
|  | ||||
| 	//recalculate blockvis tiles - new appearance might have different blockmap than before | ||||
| 	cb->gameState()->map->removeBlockVisTiles(this, true); | ||||
| 	this->appearance = VLC->objtypeh->getHandlerFor(ID, subID)->getTemplates(tile.terType).at(0); | ||||
| 	cb->gameState()->map->addBlockVisTiles(this); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -187,7 +187,6 @@ struct BankConfig | ||||
| class DLL_LINKAGE CObjectHandler | ||||
| { | ||||
| public: | ||||
| 	std::map<si32, CreatureID> cregens; //type 17. dwelling subid -> creature ID | ||||
| 	std::map <ui32, std::vector < ConstTransitivePtr<BankConfig> > > banksInfo; //[index][preset] | ||||
| 	std::map <ui32, std::string> creBanksNames; //[crebank index] -> name of this creature bank | ||||
| 	std::vector<ui32> resVals; //default values of resources in gold | ||||
| @@ -199,6 +198,6 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & cregens & banksInfo & creBanksNames & resVals; | ||||
| 		h & banksInfo & creBanksNames & resVals; | ||||
| 	} | ||||
| }; | ||||
|   | ||||
| @@ -26,23 +26,27 @@ bool CObstacleConstructor::isStaticObject() | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| CTownInstanceConstructor::CTownInstanceConstructor() | ||||
| CTownInstanceConstructor::CTownInstanceConstructor(): | ||||
| 	faction(nullptr) | ||||
| { | ||||
| } | ||||
|  | ||||
| void CTownInstanceConstructor::initTypeData(const JsonNode & input) | ||||
| { | ||||
| 	VLC->modh->identifiers.requestIdentifier("faction", input["faction"], | ||||
| 			[&](si32 index) { faction = VLC->townh->factions[index]; }); | ||||
| 	VLC->modh->identifiers.requestIdentifier("faction", input["faction"], [&](si32 index) | ||||
| 	{ | ||||
| 		faction = VLC->townh->factions[index]; | ||||
| 	}); | ||||
|  | ||||
| 	filtersJson = input["filters"]; | ||||
| } | ||||
|  | ||||
| void CTownInstanceConstructor::afterLoadFinalization() | ||||
| { | ||||
| 	assert(faction); | ||||
| 	for (auto entry : filtersJson.Struct()) | ||||
| 	{ | ||||
| 		filters[entry.first] = LogicalExpression<BuildingID>(entry.second, [&](const JsonNode & node) | ||||
| 		filters[entry.first] = LogicalExpression<BuildingID>(entry.second, [this](const JsonNode & node) | ||||
| 		{ | ||||
| 			return BuildingID(VLC->modh->identifiers.getIdentifier("building." + faction->identifier, node.Vector()[0]).get()); | ||||
| 		}); | ||||
| @@ -121,12 +125,13 @@ void CDwellingInstanceConstructor::initTypeData(const JsonNode & input) | ||||
| 		availableCreatures[i].resize(creatures.size()); | ||||
| 		for (size_t j=0; j<creatures.size(); j++) | ||||
| 		{ | ||||
| 			VLC->modh->identifiers.requestIdentifier("creature", creatures[j], [&] (si32 index) | ||||
| 			VLC->modh->identifiers.requestIdentifier("creature", creatures[j], [=] (si32 index) | ||||
| 			{ | ||||
| 				availableCreatures[i][j] = VLC->creh->creatures[index]; | ||||
| 			}); | ||||
| 		} | ||||
| 	} | ||||
| 	guards = input["guards"]; | ||||
| } | ||||
|  | ||||
| bool CDwellingInstanceConstructor::objectFilter(const CGObjectInstance *, const ObjectTemplate &) const | ||||
| @@ -137,17 +142,69 @@ bool CDwellingInstanceConstructor::objectFilter(const CGObjectInstance *, const | ||||
| CGObjectInstance * CDwellingInstanceConstructor::create(ObjectTemplate tmpl) const | ||||
| { | ||||
| 	CGDwelling * obj = createTyped(tmpl); | ||||
| 	for (auto entry : availableCreatures) | ||||
| 	{ | ||||
| 		obj->creatures.resize(obj->creatures.size()+1); | ||||
|  | ||||
| 	obj->creatures.resize(availableCreatures.size()); | ||||
| 	for (auto & entry : availableCreatures) | ||||
| 	{ | ||||
| 		for (const CCreature * cre : entry) | ||||
| 			obj->creatures.back().second.push_back(cre->idNumber); | ||||
| 	} | ||||
| 	return obj; | ||||
| } | ||||
|  | ||||
| void CDwellingInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator & rng) const | ||||
| namespace | ||||
| { | ||||
| 	si32 loadValue(const JsonNode & value, CRandomGenerator & rng, si32 defaultValue = 0) | ||||
| 	{ | ||||
| 		if (value.isNull()) | ||||
| 			return defaultValue; | ||||
| 		if (value.getType() == JsonNode::DATA_FLOAT) | ||||
| 			return value.Float(); | ||||
| 		si32 min = value["min"].Float(); | ||||
| 		si32 max = value["max"].Float(); | ||||
| 		return rng.getIntRange(min, max)(); | ||||
| 	} | ||||
|  | ||||
| 	std::vector<CStackBasicDescriptor> loadCreatures(const JsonNode & value, CRandomGenerator & rng) | ||||
| 	{ | ||||
| 		std::vector<CStackBasicDescriptor> ret; | ||||
| 		for (auto & pair : value.Struct()) | ||||
| 		{ | ||||
| 			CStackBasicDescriptor stack; | ||||
| 			stack.type = VLC->creh->creatures[VLC->modh->identifiers.getIdentifier(pair.second.meta, "creature", pair.first).get()]; | ||||
| 			stack.count = loadValue(pair.second, rng); | ||||
| 			ret.push_back(stack); | ||||
| 		} | ||||
| 		return ret; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CDwellingInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator &rng) const | ||||
| { | ||||
| 	CGDwelling * dwelling = dynamic_cast<CGDwelling*>(object); | ||||
|  | ||||
| 	dwelling->creatures.clear(); | ||||
| 	dwelling->creatures.resize(availableCreatures.size()); | ||||
|  | ||||
| 	for (auto & entry : availableCreatures) | ||||
| 	{ | ||||
| 		for (const CCreature * cre : entry) | ||||
| 			dwelling->creatures.back().second.push_back(cre->idNumber); | ||||
| 	} | ||||
|  | ||||
| 	for (auto & stack : loadCreatures(guards, rng)) | ||||
| 	{ | ||||
| 		dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.type->idNumber, stack.count)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool CDwellingInstanceConstructor::producesCreature(const CCreature * crea) const | ||||
| { | ||||
| 	for (auto & entry : availableCreatures) | ||||
| 	{ | ||||
| 		for (const CCreature * cre : entry) | ||||
| 			if (crea == cre) | ||||
| 				return true; | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
|   | ||||
| @@ -91,14 +91,19 @@ public: | ||||
|  | ||||
| class CDwellingInstanceConstructor : public CDefaultObjectTypeHandler<CGDwelling> | ||||
| { | ||||
| 	std::vector<std::vector<const CCreature *>> availableCreatures; | ||||
|  | ||||
| 	JsonNode guards; | ||||
|  | ||||
| protected: | ||||
| 	bool objectFilter(const CGObjectInstance *, const ObjectTemplate &) const; | ||||
|  | ||||
| public: | ||||
| 	std::vector<std::vector<CCreature *>> availableCreatures; | ||||
|  | ||||
| 	CDwellingInstanceConstructor(); | ||||
| 	CGObjectInstance * create(ObjectTemplate tmpl) const; | ||||
| 	void initTypeData(const JsonNode & input); | ||||
| 	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const; | ||||
|  | ||||
| 	bool producesCreature(const CCreature * crea) const; | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user