浏览代码

- filesystem.json files for wog and vcmi data
- merged puzzle map into town configuration (todo: sieges, adventure map, icons)

Ivan Savenko 13 年之前
父节点
当前提交
99dcb73a72

+ 35 - 0
Mods/WoG/filesystem.json

@@ -0,0 +1,35 @@
+{
+	"filesystem":
+	{
+		"DATA/" :
+		[
+			{"type" : "lod", "path" : "ALL/MODS/WOG/Data/hmm35wog.pac"},
+			{"type" : "dir", "path" : "ALL/MODS/WOG/Data"}
+		],
+		"SPRITES/":
+		[
+			{"type" : "lod", "path" : "ALL/MODS/WOG/Data/hmm35wog.pac"},
+			{"type" : "lod", "path" : "ALL/MODS/WOG/Data/wog - animated objects.pac"},
+			{"type" : "lod", "path" : "ALL/MODS/WOG/Data/wog - animated trees.pac"},
+			{"type" : "lod", "path" : "ALL/MODS/WOG/Data/wog - battle decorations.pac"}
+		],
+		"SOUNDS/":
+		[
+			{"type" : "snd", "path" : "ALL/MODS/WOG/Data/wog - sounds.snd"},
+			{"type" : "snd", "path" : "ALL/MODS/WOG/Data/wog.snd"}
+		],
+		"MUSIC/":
+		[
+			{"type" : "dir", "path" : "ALL/MODS/WOG/Mp3"}
+		],
+		"VIDEO/":
+		[
+			{"type" : "vid", "path" : "ALL/MODS/WOG/Data/wog - video.vid"},
+			{"type" : "vid", "path" : "ALL/MODS/WOG/Data/wog.vid"}
+		],
+		"MAPS/":
+		[
+			{"type" : "dir", "path" : "ALL/Maps"}
+		],
+	}
+}

+ 17 - 0
Mods/vcmi/filesystem.json

@@ -0,0 +1,17 @@
+{
+	"filesystem":
+	{
+		"DATA/" :
+		[
+			{"type" : "dir",  "path" : "ALL/MODS/VCMI/Data"}
+		],
+		"SPRITES/":
+		[
+			{"type" : "dir",  "path" : "ALL/MODS/VCMI/Sprites"}
+		],
+		"MAPS/":
+		[
+			{"type" : "dir",  "path" : "ALL/MODS/VCMI/Maps"}
+		]
+	}
+}

+ 5 - 3
client/GUIClasses.cpp

@@ -5018,14 +5018,16 @@ CPuzzleWindow::CPuzzleWindow(const int3 &GrailPos, double discoveredRatio):
 
 	int faction = LOCPLINT->cb->getStartInfo()->playerInfos.find(LOCPLINT->playerID)->second.castle;
 
-	for(int g=0; g<PUZZLES_PER_FACTION; ++g)
+	auto & puzzleMap = CGI->townh->factions[faction].puzzleMap;
+
+	for(int g=0; g<puzzleMap.size(); ++g)
 	{
-		const SPuzzleInfo & info = CGI->heroh->puzzleInfo[faction][g];
+		const SPuzzleInfo & info = puzzleMap[g];
 
 		auto piece = new CPicture(info.filename, info.x, info.y);
 
 		//piece that will slowly disappear
-		if(info.whenUncovered < PUZZLES_PER_FACTION * discoveredRatio)
+		if(info.whenUncovered < GameConstants::PUZZLE_MAP_PIECES * discoveredRatio)
 		{
 			piecesToRemove.push_back(piece);
 			piece->needRefresh = true;

+ 496 - 0
config/buildings.json

@@ -8,6 +8,61 @@
 			"120px" : "TPCASCAS",
 			"130px" : "CRBKGCAS"
 		},
+		"puzzleMap" :
+		{
+			"prefix" : "PUZCAS",
+			"pieces" :
+			[
+				{ "x": 7, "y": 8, "index": 39 },
+				{ "x": 7, "y": 30, "index": 41 },
+				{ "x": 7, "y": 102, "index": 1 },
+				{ "x": 7, "y": 156, "index": 23 },
+				{ "x": 7, "y": 202, "index": 6 },
+				{ "x": 7, "y": 320, "index": 13 },
+				{ "x": 16, "y": 8, "index": 39 },
+				{ "x": 22, "y": 406, "index": 2 },
+				{ "x": 70, "y": 301, "index": 22 },
+				{ "x": 72, "y": 194, "index": 11 },
+				{ "x": 101, "y": 332, "index": 8 },
+				{ "x": 106, "y": 8, "index": 9 },
+				{ "x": 106, "y": 31, "index": 29 },
+				{ "x": 114, "y": 60, "index": 7 },
+				{ "x": 126, "y": 329, "index": 17 },
+				{ "x": 128, "y": 191, "index": 21 },
+				{ "x": 152, "y": 347, "index": 27 },
+				{ "x": 154, "y": 239, "index": 31 },
+				{ "x": 157, "y": 429, "index": 34 },
+				{ "x": 166, "y": 470, "index": 4 },
+				{ "x": 185, "y": 127, "index": 30 },
+				{ "x": 212, "y": 335, "index": 36 },
+				{ "x": 214, "y": 191, "index": 48 },
+				{ "x": 217, "y": 226, "index": 43 },
+				{ "x": 235, "y": 147, "index": 35 },
+				{ "x": 245, "y": 77, "index": 16 },
+				{ "x": 266, "y": 384, "index": 42 },
+				{ "x": 288, "y": 288, "index": 45 },
+				{ "x": 298, "y": 8, "index": 26 },
+				{ "x": 321, "y": 177, "index": 46 },
+				{ "x": 346, "y": 67, "index": 38 },
+				{ "x": 354, "y": 459, "index": 20 },
+				{ "x": 355, "y": 397, "index": 25 },
+				{ "x": 375, "y": 162, "index": 28 },
+				{ "x": 382, "y": 255, "index": 32 },
+				{ "x": 408, "y": 32, "index": 37 },
+				{ "x": 408, "y": 111, "index": 14 },
+				{ "x": 421, "y": 147, "index": 19 },
+				{ "x": 422, "y": 466, "index": 12 },
+				{ "x": 426, "y": 8, "index": 15 },
+				{ "x": 436, "y": 238, "index": 24 },
+				{ "x": 458, "y": 336, "index": 44 },
+				{ "x": 486, "y": 8, "index": 40 },
+				{ "x": 487, "y": 144, "index": 33 },
+				{ "x": 517, "y": 145, "index": 18 },
+				{ "x": 520, "y": 68, "index": 5 },
+				{ "x": 524, "y": 234, "index": 10 },
+				{ "x": 525, "y": 327, "index": 3 }
+			]
+		},
 		"town" :
 		{
 			"structures" :
@@ -127,8 +182,64 @@
 			"120px" : "TPCASRAM",
 			"130px" : "CRBKGRAM"
 		},
+		"puzzleMap" :
+		{
+			"prefix" : "PUZRAM",
+			"pieces" :
+			[
+				{ "x": 7, "y": 8, "index": 2 },
+				{ "x": 7, "y": 101, "index": 13 },
+				{ "x": 7, "y": 195, "index": 20 },
+				{ "x": 7, "y": 310, "index": 6 },
+				{ "x": 7, "y": 378, "index": 22 },
+				{ "x": 7, "y": 449, "index": 21 },
+				{ "x": 61, "y": 8, "index": 19 },
+				{ "x": 97, "y": 42, "index": 8 },
+				{ "x": 98, "y": 201, "index": 24 },
+				{ "x": 108, "y": 308, "index": 36 },
+				{ "x": 115, "y": 461, "index": 1 },
+				{ "x": 129, "y": 366, "index": 7 },
+				{ "x": 134, "y": 8, "index": 4 },
+				{ "x": 157, "y": 188, "index": 25 },
+				{ "x": 160, "y": 309, "index": 39 },
+				{ "x": 162, "y": 441, "index": 11 },
+				{ "x": 164, "y": 126, "index": 28 },
+				{ "x": 174, "y": 390, "index": 33 },
+				{ "x": 178, "y": 188, "index": 46 },
+				{ "x": 187, "y": 258, "index": 41 },
+				{ "x": 190, "y": 24, "index": 38 },
+				{ "x": 215, "y": 272, "index": 45 },
+				{ "x": 255, "y": 443, "index": 9 },
+				{ "x": 265, "y": 323, "index": 40 },
+				{ "x": 277, "y": 45, "index": 47 },
+				{ "x": 278, "y": 383, "index": 27 },
+				{ "x": 292, "y": 196, "index": 43 },
+				{ "x": 294, "y": 266, "index": 48 },
+				{ "x": 310, "y": 8, "index": 17 },
+				{ "x": 330, "y": 493, "index": 16 },
+				{ "x": 339, "y": 8, "index": 12 },
+				{ "x": 339, "y": 167, "index": 29 },
+				{ "x": 344, "y": 108, "index": 35 },
+				{ "x": 361, "y": 239, "index": 31 },
+				{ "x": 363, "y": 385, "index": 44 },
+				{ "x": 398, "y": 310, "index": 42 },
+				{ "x": 400, "y": 130, "index": 23 },
+				{ "x": 404, "y": 436, "index": 32 },
+				{ "x": 421, "y": 127, "index": 26 },
+				{ "x": 429, "y": 8, "index": 37 },
+				{ "x": 430, "y": 106, "index": 30 },
+				{ "x": 462, "y": 393, "index": 14 },
+				{ "x": 469, "y": 270, "index": 10 },
+				{ "x": 486, "y": 8, "index": 3 },
+				{ "x": 499, "y": 481, "index": 15 },
+				{ "x": 511, "y": 255, "index": 34 },
+				{ "x": 516, "y": 48, "index": 18 },
+				{ "x": 525, "y": 169, "index": 5 }
+			]
+		},
 		"town" :
 		{
+
 			"structures" :
 			[
 				{ "animation" : "TBRMEXT2.def", "x" : 327, "y" : 236 },
@@ -250,6 +361,61 @@
 			"120px" : "TPCASTOW",
 			"130px" : "CRBKGTOW"
 		},
+		"puzzleMap" :
+		{
+			"prefix" : "PUZTOW",
+			"pieces" :
+			[
+				{ "x": 7, "y": 8, "index": 1 },
+				{ "x": 7, "y": 52, "index": 13 },
+				{ "x": 7, "y": 243, "index": 8 },
+				{ "x": 7, "y": 486, "index": 22 },
+				{ "x": 26, "y": 391, "index": 7 },
+				{ "x": 27, "y": 31, "index": 23 },
+				{ "x": 27, "y": 89, "index": 31 },
+				{ "x": 28, "y": 303, "index": 20 },
+				{ "x": 28, "y": 336, "index": 25 },
+				{ "x": 37, "y": 234, "index": 33 },
+				{ "x": 59, "y": 77, "index": 6 },
+				{ "x": 76, "y": 462, "index": 15 },
+				{ "x": 91, "y": 245, "index": 34 },
+				{ "x": 114, "y": 31, "index": 19 },
+				{ "x": 118, "y": 323, "index": 42 },
+				{ "x": 132, "y": 87, "index": 36 },
+				{ "x": 163, "y": 370, "index": 40 },
+				{ "x": 171, "y": 255, "index": 21 },
+				{ "x": 192, "y": 8, "index": 28 },
+				{ "x": 212, "y": 483, "index": 38 },
+				{ "x": 228, "y": 95, "index": 44 },
+				{ "x": 231, "y": 205, "index": 46 },
+				{ "x": 293, "y": 380, "index": 10 },
+				{ "x": 297, "y": 190, "index": 43 },
+				{ "x": 297, "y": 260, "index": 48 },
+				{ "x": 298, "y": 8, "index": 17 },
+				{ "x": 298, "y": 89, "index": 35 },
+				{ "x": 312, "y": 462, "index": 29 },
+				{ "x": 320, "y": 261, "index": 45 },
+				{ "x": 340, "y": 17, "index": 37 },
+				{ "x": 350, "y": 121, "index": 12 },
+				{ "x": 350, "y": 174, "index": 41 },
+				{ "x": 355, "y": 371, "index": 27 },
+				{ "x": 357, "y": 469, "index": 3 },
+				{ "x": 376, "y": 289, "index": 11 },
+				{ "x": 388, "y": 8, "index": 4 },
+				{ "x": 407, "y": 45, "index": 47 },
+				{ "x": 421, "y": 284, "index": 30 },
+				{ "x": 436, "y": 159, "index": 39 },
+				{ "x": 445, "y": 8, "index": 18 },
+				{ "x": 445, "y": 211, "index": 26 },
+				{ "x": 463, "y": 422, "index": 24 },
+				{ "x": 477, "y": 29, "index": 2 },
+				{ "x": 497, "y": 153, "index": 5 },
+				{ "x": 499, "y": 108, "index": 14 },
+				{ "x": 503, "y": 281, "index": 16 },
+				{ "x": 537, "y": 418, "index": 9 },
+				{ "x": 556, "y": 215, "index": 32 }
+			]
+		},
 		"town" :
 		{
 			"structures" :
@@ -366,6 +532,61 @@
 			"120px" : "TPCASINF",
 			"130px" : "CRBKGINF"
 		},
+		"puzzleMap" :
+		{
+			"prefix" : "PUZINF",
+			"pieces" :
+			[
+				{ "x": 7, "y": 8, "index": 30 },
+				{ "x": 7, "y": 16, "index": 2 },
+				{ "x": 7, "y": 95, "index": 12 },
+				{ "x": 7, "y": 271, "index": 27 },
+				{ "x": 7, "y": 308, "index": 8 },
+				{ "x": 7, "y": 464, "index": 1 },
+				{ "x": 16, "y": 164, "index": 26 },
+				{ "x": 41, "y": 378, "index": 39 },
+				{ "x": 50, "y": 471, "index": 13 },
+				{ "x": 51, "y": 101, "index": 17 },
+				{ "x": 80, "y": 260, "index": 35 },
+				{ "x": 81, "y": 48, "index": 4 },
+				{ "x": 91, "y": 143, "index": 47 },
+				{ "x": 115, "y": 8, "index": 25 },
+				{ "x": 141, "y": 360, "index": 28 },
+				{ "x": 153, "y": 269, "index": 41 },
+				{ "x": 164, "y": 55, "index": 44 },
+				{ "x": 173, "y": 101, "index": 36 },
+				{ "x": 173, "y": 492, "index": 6 },
+				{ "x": 187, "y": 160, "index": 48 },
+				{ "x": 194, "y": 388, "index": 19 },
+				{ "x": 200, "y": 373, "index": 20 },
+				{ "x": 204, "y": 282, "index": 45 },
+				{ "x": 239, "y": 469, "index": 11 },
+				{ "x": 240, "y": 8, "index": 32 },
+				{ "x": 271, "y": 163, "index": 43 },
+				{ "x": 276, "y": 255, "index": 46 },
+				{ "x": 296, "y": 428, "index": 3 },
+				{ "x": 297, "y": 281, "index": 16 },
+				{ "x": 306, "y": 8, "index": 10 },
+				{ "x": 317, "y": 17, "index": 15 },
+				{ "x": 327, "y": 84, "index": 29 },
+				{ "x": 348, "y": 142, "index": 40 },
+				{ "x": 348, "y": 342, "index": 21 },
+				{ "x": 370, "y": 405, "index": 22 },
+				{ "x": 401, "y": 103, "index": 18 },
+				{ "x": 407, "y": 40, "index": 31 },
+				{ "x": 421, "y": 508, "index": 7 },
+				{ "x": 453, "y": 215, "index": 33 },
+				{ "x": 455, "y": 377, "index": 34 },
+				{ "x": 460, "y": 170, "index": 38 },
+				{ "x": 475, "y": 319, "index": 42 },
+				{ "x": 488, "y": 412, "index": 37 },
+				{ "x": 504, "y": 8, "index": 24 },
+				{ "x": 515, "y": 67, "index": 5 },
+				{ "x": 517, "y": 211, "index": 14 },
+				{ "x": 532, "y": 305, "index": 23 },
+				{ "x": 556, "y": 335, "index": 9 }
+			]
+		},
 		"town" :
 		{
 			"structures" :
@@ -485,6 +706,61 @@
 			"120px" : "TPCASNEC",
 			"130px" : "CRBKGNEC"
 		},
+		"puzzleMap" :
+		{
+			"prefix" : "PUZNEC",
+			"pieces" :
+			[
+				{ "x": 7, "y": 8, "index": 22 },
+				{ "x": 7, "y": 188, "index": 1 },
+				{ "x": 7, "y": 329, "index": 20 },
+				{ "x": 7, "y": 403, "index": 24 },
+				{ "x": 8, "y": 8, "index": 47 },
+				{ "x": 14, "y": 138, "index": 30 },
+				{ "x": 15, "y": 8, "index": 9 },
+				{ "x": 34, "y": 374, "index": 31 },
+				{ "x": 55, "y": 82, "index": 25 },
+				{ "x": 55, "y": 150, "index": 38 },
+				{ "x": 57, "y": 281, "index": 8 },
+				{ "x": 94, "y": 188, "index": 36 },
+				{ "x": 108, "y": 344, "index": 6 },
+				{ "x": 119, "y": 424, "index": 13 },
+				{ "x": 124, "y": 256, "index": 37 },
+				{ "x": 131, "y": 8, "index": 7 },
+				{ "x": 139, "y": 92, "index": 11 },
+				{ "x": 145, "y": 371, "index": 29 },
+				{ "x": 148, "y": 42, "index": 21 },
+				{ "x": 175, "y": 200, "index": 44 },
+				{ "x": 200, "y": 291, "index": 45 },
+				{ "x": 201, "y": 66, "index": 42 },
+				{ "x": 210, "y": 482, "index": 18 },
+				{ "x": 247, "y": 98, "index": 28 },
+				{ "x": 250, "y": 227, "index": 48 },
+				{ "x": 262, "y": 8, "index": 15 },
+				{ "x": 293, "y": 373, "index": 32 },
+				{ "x": 303, "y": 286, "index": 46 },
+				{ "x": 318, "y": 173, "index": 43 },
+				{ "x": 345, "y": 444, "index": 2 },
+				{ "x": 356, "y": 8, "index": 5 },
+				{ "x": 357, "y": 386, "index": 17 },
+				{ "x": 362, "y": 38, "index": 40 },
+				{ "x": 382, "y": 8, "index": 19 },
+				{ "x": 382, "y": 119, "index": 35 },
+				{ "x": 421, "y": 164, "index": 27 },
+				{ "x": 422, "y": 249, "index": 4 },
+				{ "x": 428, "y": 52, "index": 14 },
+				{ "x": 429, "y": 101, "index": 10 },
+				{ "x": 443, "y": 132, "index": 41 },
+				{ "x": 452, "y": 239, "index": 34 },
+				{ "x": 465, "y": 441, "index": 23 },
+				{ "x": 469, "y": 300, "index": 39 },
+				{ "x": 476, "y": 20, "index": 3 },
+				{ "x": 537, "y": 249, "index": 33 },
+				{ "x": 547, "y": 430, "index": 12 },
+				{ "x": 559, "y": 140, "index": 26 },
+				{ "x": 558, "y": 8, "index": 16 }
+			]
+		},
 		"town" :
 		{
 			"structures" :
@@ -607,6 +883,61 @@
 			"120px" : "TPCASDUN",
 			"130px" : "CRBKGDUN"
 		},
+		"puzzleMap" :
+		{
+			"prefix" : "PUZDUN",
+			"pieces" :
+			[
+				{ "x": 7, "y": 8, "index": 31 },
+				{ "x": 7, "y": 125, "index": 1 },
+				{ "x": 7, "y": 353, "index": 33 },
+				{ "x": 7, "y": 394, "index": 6 },
+				{ "x": 30, "y": 101, "index": 36 },
+				{ "x": 33, "y": 219, "index": 16 },
+				{ "x": 57, "y": 171, "index": 13 },
+				{ "x": 62, "y": 8, "index": 47 },
+				{ "x": 63, "y": 90, "index": 41 },
+				{ "x": 83, "y": 471, "index": 10 },
+				{ "x": 94, "y": 117, "index": 21 },
+				{ "x": 99, "y": 8, "index": 5 },
+				{ "x": 113, "y": 258, "index": 32 },
+				{ "x": 156, "y": 146, "index": 28 },
+				{ "x": 165, "y": 288, "index": 42 },
+				{ "x": 172, "y": 388, "index": 44 },
+				{ "x": 177, "y": 36, "index": 39 },
+				{ "x": 194, "y": 235, "index": 46 },
+				{ "x": 204, "y": 502, "index": 3 },
+				{ "x": 236, "y": 320, "index": 23 },
+				{ "x": 238, "y": 8, "index": 20 },
+				{ "x": 245, "y": 75, "index": 25 },
+				{ "x": 247, "y": 396, "index": 29 },
+				{ "x": 247, "y": 459, "index": 14 },
+				{ "x": 253, "y": 152, "index": 48 },
+				{ "x": 301, "y": 233, "index": 43 },
+				{ "x": 323, "y": 8, "index": 12 },
+				{ "x": 323, "y": 178, "index": 45 },
+				{ "x": 328, "y": 342, "index": 30 },
+				{ "x": 329, "y": 428, "index": 19 },
+				{ "x": 339, "y": 8, "index": 26 },
+				{ "x": 357, "y": 141, "index": 27 },
+				{ "x": 374, "y": 8, "index": 15 },
+				{ "x": 374, "y": 236, "index": 34 },
+				{ "x": 392, "y": 439, "index": 35 },
+				{ "x": 400, "y": 291, "index": 40 },
+				{ "x": 401, "y": 103, "index": 18 },
+				{ "x": 422, "y": 381, "index": 37 },
+				{ "x": 436, "y": 8, "index": 17 },
+				{ "x": 438, "y": 336, "index": 24 },
+				{ "x": 449, "y": 131, "index": 9 },
+				{ "x": 453, "y": 161, "index": 11 },
+				{ "x": 471, "y": 267, "index": 38 },
+				{ "x": 477, "y": 64, "index": 22 },
+				{ "x": 480, "y": 456, "index": 8 },
+				{ "x": 485, "y": 8, "index": 2 },
+				{ "x": 536, "y": 197, "index": 4 },
+				{ "x": 541, "y": 22, "index": 7 }
+			]
+		},
 		"town" :
 		{
 			"structures" :
@@ -723,6 +1054,61 @@
 			"120px" : "TPCASSTR",
 			"130px" : "CRBKGSTR"
 		},
+		"puzzleMap" :
+		{
+			"prefix" : "PUZSTR",
+			"pieces" :
+			[
+				{ "x": 7, "y": 8, "index": 6 },
+				{ "x": 7, "y": 229, "index": 14 },
+				{ "x": 7, "y": 405, "index": 15 },
+				{ "x": 7, "y": 465, "index": 10 },
+				{ "x": 12, "y": 8, "index": 9 },
+				{ "x": 32, "y": 245, "index": 21 },
+				{ "x": 32, "y": 277, "index": 33 },
+				{ "x": 36, "y": 337, "index": 19 },
+				{ "x": 39, "y": 15, "index": 36 },
+				{ "x": 47, "y": 115, "index": 23 },
+				{ "x": 49, "y": 178, "index": 25 },
+				{ "x": 70, "y": 8, "index": 1 },
+				{ "x": 101, "y": 35, "index": 41 },
+				{ "x": 111, "y": 311, "index": 44 },
+				{ "x": 123, "y": 156, "index": 45 },
+				{ "x": 138, "y": 423, "index": 32 },
+				{ "x": 140, "y": 224, "index": 43 },
+				{ "x": 144, "y": 136, "index": 11 },
+				{ "x": 149, "y": 452, "index": 18 },
+				{ "x": 158, "y": 475, "index": 5 },
+				{ "x": 191, "y": 68, "index": 7 },
+				{ "x": 202, "y": 12, "index": 39 },
+				{ "x": 218, "y": 349, "index": 34 },
+				{ "x": 219, "y": 285, "index": 42 },
+				{ "x": 222, "y": 96, "index": 28 },
+				{ "x": 262, "y": 8, "index": 8 },
+				{ "x": 279, "y": 166, "index": 48 },
+				{ "x": 279, "y": 425, "index": 22 },
+				{ "x": 303, "y": 314, "index": 27 },
+				{ "x": 320, "y": 109, "index": 16 },
+				{ "x": 326, "y": 146, "index": 47 },
+				{ "x": 333, "y": 160, "index": 46 },
+				{ "x": 362, "y": 26, "index": 4 },
+				{ "x": 365, "y": 441, "index": 17 },
+				{ "x": 380, "y": 297, "index": 38 },
+				{ "x": 392, "y": 242, "index": 29 },
+				{ "x": 427, "y": 275, "index": 40 },
+				{ "x": 445, "y": 85, "index": 2 },
+				{ "x": 446, "y": 424, "index": 30 },
+				{ "x": 459, "y": 347, "index": 37 },
+				{ "x": 463, "y": 53, "index": 24 },
+				{ "x": 484, "y": 210, "index": 20 },
+				{ "x": 488, "y": 8, "index": 26 },
+				{ "x": 489, "y": 303, "index": 35 },
+				{ "x": 529, "y": 8, "index": 31 },
+				{ "x": 529, "y": 421, "index": 3 },
+				{ "x": 558, "y": 87, "index": 13 },
+				{ "x": 563, "y": 261, "index": 12 }
+			]
+		},
 		"town" :
 		{
 			"structures" :
@@ -838,6 +1224,61 @@
 			"120px" : "TPCASFOR",
 			"130px" : "CRBKGFOR"
 		},
+		"puzzleMap" :
+		{
+			"prefix" : "PUZFOR",
+			"pieces" :
+			[
+				{ "x": 7, "y": 8, "index": 36 },
+				{ "x": 7, "y": 152, "index": 25 },
+				{ "x": 7, "y": 306, "index": 34 },
+				{ "x": 7, "y": 388, "index": 23 },
+				{ "x": 7, "y": 434, "index": 15 },
+				{ "x": 23, "y": 417, "index": 37 },
+				{ "x": 32, "y": 232, "index": 38 },
+				{ "x": 42, "y": 137, "index": 39 },
+				{ "x": 47, "y": 440, "index": 8 },
+				{ "x": 56, "y": 19, "index": 47 },
+				{ "x": 71, "y": 8, "index": 1 },
+				{ "x": 87, "y": 219, "index": 30 },
+				{ "x": 90, "y": 26, "index": 41 },
+				{ "x": 104, "y": 397, "index": 33 },
+				{ "x": 116, "y": 345, "index": 40 },
+				{ "x": 134, "y": 215, "index": 11 },
+				{ "x": 175, "y": 168, "index": 19 },
+				{ "x": 191, "y": 428, "index": 13 },
+				{ "x": 200, "y": 326, "index": 24 },
+				{ "x": 216, "y": 98, "index": 18 },
+				{ "x": 221, "y": 398, "index": 20 },
+				{ "x": 225, "y": 235, "index": 46 },
+				{ "x": 239, "y": 8, "index": 9 },
+				{ "x": 245, "y": 40, "index": 7 },
+				{ "x": 248, "y": 208, "index": 48 },
+				{ "x": 261, "y": 439, "index": 5 },
+				{ "x": 262, "y": 134, "index": 26 },
+				{ "x": 297, "y": 352, "index": 22 },
+				{ "x": 309, "y": 99, "index": 16 },
+				{ "x": 320, "y": 262, "index": 43 },
+				{ "x": 323, "y": 404, "index": 10 },
+				{ "x": 326, "y": 200, "index": 45 },
+				{ "x": 331, "y": 20, "index": 17 },
+				{ "x": 345, "y": 178, "index": 21 },
+				{ "x": 353, "y": 8, "index": 3 },
+				{ "x": 358, "y": 290, "index": 42 },
+				{ "x": 381, "y": 399, "index": 14 },
+				{ "x": 400, "y": 65, "index": 12 },
+				{ "x": 428, "y": 160, "index": 35 },
+				{ "x": 448, "y": 293, "index": 29 },
+				{ "x": 451, "y": 94, "index": 27 },
+				{ "x": 453, "y": 424, "index": 2 },
+				{ "x": 462, "y": 397, "index": 32 },
+				{ "x": 465, "y": 8, "index": 4 },
+				{ "x": 486, "y": 163, "index": 44 },
+				{ "x": 492, "y": 184, "index": 31 },
+				{ "x": 517, "y": 304, "index": 6 },
+				{ "x": 549, "y": 8, "index": 28 }
+			]
+		},
 		"town" :
 		{
 			"structures" :
@@ -956,6 +1397,61 @@
 			"120px" : "TPCASELE",
 			"130px" : "CRBKGELE"
 		},
+		"puzzleMap" :
+		{
+			"prefix" : "PUZELE",
+			"pieces" :
+			[
+				{ "x": 7, "y": 8, "index": 1 },
+				{ "x": 7, "y": 54, "index": 6 },
+				{ "x": 7, "y": 227, "index": 16 },
+				{ "x": 7, "y": 426, "index": 9 },
+				{ "x": 15, "y": 48, "index": 22 },
+				{ "x": 45, "y": 375, "index": 32 },
+				{ "x": 48, "y": 249, "index": 28 },
+				{ "x": 86, "y": 500, "index": 15 },
+				{ "x": 93, "y": 55, "index": 37 },
+				{ "x": 99, "y": 245, "index": 7 },
+				{ "x": 101, "y": 354, "index": 27 },
+				{ "x": 104, "y": 175, "index": 35 },
+				{ "x": 107, "y": 14, "index": 21 },
+				{ "x": 124, "y": 296, "index": 38 },
+				{ "x": 134, "y": 8, "index": 4 },
+				{ "x": 181, "y": 466, "index": 26 },
+				{ "x": 182, "y": 200, "index": 40 },
+				{ "x": 189, "y": 381, "index": 33 },
+				{ "x": 192, "y": 40, "index": 8 },
+				{ "x": 192, "y": 364, "index": 11 },
+				{ "x": 201, "y": 124, "index": 48 },
+				{ "x": 203, "y": 330, "index": 42 },
+				{ "x": 228, "y": 293, "index": 45 },
+				{ "x": 235, "y": 39, "index": 25 },
+				{ "x": 242, "y": 335, "index": 44 },
+				{ "x": 275, "y": 488, "index": 5 },
+				{ "x": 278, "y": 202, "index": 46 },
+				{ "x": 290, "y": 80, "index": 13 },
+				{ "x": 291, "y": 115, "index": 20 },
+				{ "x": 308, "y": 225, "index": 43 },
+				{ "x": 310, "y": 158, "index": 39 },
+				{ "x": 312, "y": 24, "index": 12 },
+				{ "x": 317, "y": 8, "index": 2 },
+				{ "x": 323, "y": 443, "index": 10 },
+				{ "x": 327, "y": 253, "index": 41 },
+				{ "x": 330, "y": 36, "index": 36 },
+				{ "x": 349, "y": 330, "index": 34 },
+				{ "x": 349, "y": 426, "index": 17 },
+				{ "x": 407, "y": 191, "index": 47 },
+				{ "x": 421, "y": 430, "index": 31 },
+				{ "x": 428, "y": 246, "index": 23 },
+				{ "x": 467, "y": 90, "index": 29 },
+				{ "x": 481, "y": 13, "index": 30 },
+				{ "x": 489, "y": 346, "index": 18 },
+				{ "x": 504, "y": 113, "index": 19 },
+				{ "x": 504, "y": 190, "index": 24 },
+				{ "x": 507, "y": 8, "index": 14 },
+				{ "x": 542, "y": 436, "index": 3 }
+			]
+		},
 		"town" :
 		{
 			"structures" :

+ 9 - 9
config/filesystem.json

@@ -11,21 +11,21 @@
 	{
 		"DATA/" :
 		[
-			{"type" : "file", "path" : "ALL/Data/H3ab_bmp.lod"},
-			{"type" : "file", "path" : "ALL/Data/H3bitmap.lod"},
+			{"type" : "lod", "path" : "ALL/Data/H3ab_bmp.lod"},
+			{"type" : "lod", "path" : "ALL/Data/H3bitmap.lod"},
 			{"type" : "dir",  "path" : "ALL/Data"}
 		],
 		"SPRITES/":
 		[
-			{"type" : "file", "path" : "ALL/Data/H3ab_spr.lod"},
-			{"type" : "file", "path" : "ALL/Data/H3sprite.lod"},
+			{"type" : "lod", "path" : "ALL/Data/H3ab_spr.lod"},
+			{"type" : "lod", "path" : "ALL/Data/H3sprite.lod"},
 			{"type" : "dir",  "path" : "ALL/Sprites"}
 		],
 		"SOUNDS/":
 		[
-			{"type" : "file", "path" : "ALL/Data/H3ab_ahd.snd"},
-			{"type" : "file", "path" : "ALL/Data/Heroes3-cd2.snd"},
-			{"type" : "file", "path" : "ALL/Data/Heroes3.snd"},
+			{"type" : "snd", "path" : "ALL/Data/H3ab_ahd.snd"},
+			{"type" : "snd", "path" : "ALL/Data/Heroes3-cd2.snd"},
+			{"type" : "snd", "path" : "ALL/Data/Heroes3.snd"},
 			//WoG have overriden sounds with .82m extension in Data
 			{"type" : "dir",  "path" : "ALL/Data", "depth": 0}
 		],
@@ -35,8 +35,8 @@
 		],
 		"VIDEO/":
 		[
-			{"type" : "file", "path" : "ALL/Data/H3ab_ahd.vid"},
-			{"type" : "file", "path" : "ALL/Data/video.vid"},
+			{"type" : "vid", "path" : "ALL/Data/H3ab_ahd.vid"},
+			{"type" : "vid", "path" : "ALL/Data/video.vid"},
 			// Location of video files in linux release
 			{"type" : "dir",  "path" : "ALL/Data/Video"}
 		],

+ 0 - 472
config/puzzle_map.json

@@ -1,472 +0,0 @@
-{
-	// Description of puzzle's pieces positions and order of discovering.
-	"puzzles": [
-		[
-			//Castle
-			{ "x": 7, "y": 8, "order": 39 },
-			{ "x": 7, "y": 30, "order": 41 },
-			{ "x": 7, "y": 102, "order": 1 },
-			{ "x": 7, "y": 156, "order": 23 },
-			{ "x": 7, "y": 202, "order": 6 },
-			{ "x": 7, "y": 320, "order": 13 },
-			{ "x": 16, "y": 8, "order": 39 },
-			{ "x": 22, "y": 406, "order": 2 },
-			{ "x": 70, "y": 301, "order": 22 },
-			{ "x": 72, "y": 194, "order": 11 },
-			{ "x": 101, "y": 332, "order": 8 },
-			{ "x": 106, "y": 8, "order": 9 },
-			{ "x": 106, "y": 31, "order": 29 },
-			{ "x": 114, "y": 60, "order": 7 },
-			{ "x": 126, "y": 329, "order": 17 },
-			{ "x": 128, "y": 191, "order": 21 },
-			{ "x": 152, "y": 347, "order": 27 },
-			{ "x": 154, "y": 239, "order": 31 },
-			{ "x": 157, "y": 429, "order": 34 },
-			{ "x": 166, "y": 470, "order": 4 },
-			{ "x": 185, "y": 127, "order": 30 },
-			{ "x": 212, "y": 335, "order": 36 },
-			{ "x": 214, "y": 191, "order": 48 },
-			{ "x": 217, "y": 226, "order": 43 },
-			{ "x": 235, "y": 147, "order": 35 },
-			{ "x": 245, "y": 77, "order": 16 },
-			{ "x": 266, "y": 384, "order": 42 },
-			{ "x": 288, "y": 288, "order": 45 },
-			{ "x": 298, "y": 8, "order": 26 },
-			{ "x": 321, "y": 177, "order": 46 },
-			{ "x": 346, "y": 67, "order": 38 },
-			{ "x": 354, "y": 459, "order": 20 },
-			{ "x": 355, "y": 397, "order": 25 },
-			{ "x": 375, "y": 162, "order": 28 },
-			{ "x": 382, "y": 255, "order": 32 },
-			{ "x": 408, "y": 32, "order": 37 },
-			{ "x": 408, "y": 111, "order": 14 },
-			{ "x": 421, "y": 147, "order": 19 },
-			{ "x": 422, "y": 466, "order": 12 },
-			{ "x": 426, "y": 8, "order": 15 },
-			{ "x": 436, "y": 238, "order": 24 },
-			{ "x": 458, "y": 336, "order": 44 },
-			{ "x": 486, "y": 8, "order": 40 },
-			{ "x": 487, "y": 144, "order": 33 },
-			{ "x": 517, "y": 145, "order": 18 },
-			{ "x": 520, "y": 68, "order": 5 },
-			{ "x": 524, "y": 234, "order": 10 },
-			{ "x": 525, "y": 327, "order": 3 }
-		],
-
-		[
-			//Rampart
-			{ "x": 7, "y": 8, "order": 2 },
-			{ "x": 7, "y": 101, "order": 13 },
-			{ "x": 7, "y": 195, "order": 20 },
-			{ "x": 7, "y": 310, "order": 6 },
-			{ "x": 7, "y": 378, "order": 22 },
-			{ "x": 7, "y": 449, "order": 21 },
-			{ "x": 61, "y": 8, "order": 19 },
-			{ "x": 97, "y": 42, "order": 8 },
-			{ "x": 98, "y": 201, "order": 24 },
-			{ "x": 108, "y": 308, "order": 36 },
-			{ "x": 115, "y": 461, "order": 1 },
-			{ "x": 129, "y": 366, "order": 7 },
-			{ "x": 134, "y": 8, "order": 4 },
-			{ "x": 157, "y": 188, "order": 25 },
-			{ "x": 160, "y": 309, "order": 39 },
-			{ "x": 162, "y": 441, "order": 11 },
-			{ "x": 164, "y": 126, "order": 28 },
-			{ "x": 174, "y": 390, "order": 33 },
-			{ "x": 178, "y": 188, "order": 46 },
-			{ "x": 187, "y": 258, "order": 41 },
-			{ "x": 190, "y": 24, "order": 38 },
-			{ "x": 215, "y": 272, "order": 45 },
-			{ "x": 255, "y": 443, "order": 9 },
-			{ "x": 265, "y": 323, "order": 40 },
-			{ "x": 277, "y": 45, "order": 47 },
-			{ "x": 278, "y": 383, "order": 27 },
-			{ "x": 292, "y": 196, "order": 43 },
-			{ "x": 294, "y": 266, "order": 48 },
-			{ "x": 310, "y": 8, "order": 17 },
-			{ "x": 330, "y": 493, "order": 16 },
-			{ "x": 339, "y": 8, "order": 12 },
-			{ "x": 339, "y": 167, "order": 29 },
-			{ "x": 344, "y": 108, "order": 35 },
-			{ "x": 361, "y": 239, "order": 31 },
-			{ "x": 363, "y": 385, "order": 44 },
-			{ "x": 398, "y": 310, "order": 42 },
-			{ "x": 400, "y": 130, "order": 23 },
-			{ "x": 404, "y": 436, "order": 32 },
-			{ "x": 421, "y": 127, "order": 26 },
-			{ "x": 429, "y": 8, "order": 37 },
-			{ "x": 430, "y": 106, "order": 30 },
-			{ "x": 462, "y": 393, "order": 14 },
-			{ "x": 469, "y": 270, "order": 10 },
-			{ "x": 486, "y": 8, "order": 3 },
-			{ "x": 499, "y": 481, "order": 15 },
-			{ "x": 511, "y": 255, "order": 34 },
-			{ "x": 516, "y": 48, "order": 18 },
-			{ "x": 525, "y": 169, "order": 5 }
-		],
-
-		[
-			//Tower
-			{ "x": 7, "y": 8, "order": 1 },
-			{ "x": 7, "y": 52, "order": 13 },
-			{ "x": 7, "y": 243, "order": 8 },
-			{ "x": 7, "y": 486, "order": 22 },
-			{ "x": 26, "y": 391, "order": 7 },
-			{ "x": 27, "y": 31, "order": 23 },
-			{ "x": 27, "y": 89, "order": 31 },
-			{ "x": 28, "y": 303, "order": 20 },
-			{ "x": 28, "y": 336, "order": 25 },
-			{ "x": 37, "y": 234, "order": 33 },
-			{ "x": 59, "y": 77, "order": 6 },
-			{ "x": 76, "y": 462, "order": 15 },
-			{ "x": 91, "y": 245, "order": 34 },
-			{ "x": 114, "y": 31, "order": 19 },
-			{ "x": 118, "y": 323, "order": 42 },
-			{ "x": 132, "y": 87, "order": 36 },
-			{ "x": 163, "y": 370, "order": 40 },
-			{ "x": 171, "y": 255, "order": 21 },
-			{ "x": 192, "y": 8, "order": 28 },
-			{ "x": 212, "y": 483, "order": 38 },
-			{ "x": 228, "y": 95, "order": 44 },
-			{ "x": 231, "y": 205, "order": 46 },
-			{ "x": 293, "y": 380, "order": 10 },
-			{ "x": 297, "y": 190, "order": 43 },
-			{ "x": 297, "y": 260, "order": 48 },
-			{ "x": 298, "y": 8, "order": 17 },
-			{ "x": 298, "y": 89, "order": 35 },
-			{ "x": 312, "y": 462, "order": 29 },
-			{ "x": 320, "y": 261, "order": 45 },
-			{ "x": 340, "y": 17, "order": 37 },
-			{ "x": 350, "y": 121, "order": 12 },
-			{ "x": 350, "y": 174, "order": 41 },
-			{ "x": 355, "y": 371, "order": 27 },
-			{ "x": 357, "y": 469, "order": 3 },
-			{ "x": 376, "y": 289, "order": 11 },
-			{ "x": 388, "y": 8, "order": 4 },
-			{ "x": 407, "y": 45, "order": 47 },
-			{ "x": 421, "y": 284, "order": 30 },
-			{ "x": 436, "y": 159, "order": 39 },
-			{ "x": 445, "y": 8, "order": 18 },
-			{ "x": 445, "y": 211, "order": 26 },
-			{ "x": 463, "y": 422, "order": 24 },
-			{ "x": 477, "y": 29, "order": 2 },
-			{ "x": 497, "y": 153, "order": 5 },
-			{ "x": 499, "y": 108, "order": 14 },
-			{ "x": 503, "y": 281, "order": 16 },
-			{ "x": 537, "y": 418, "order": 9 },
-			{ "x": 556, "y": 215, "order": 32 }
-		],
-
-		[
-			//Inferno
-			{ "x": 7, "y": 8, "order": 30 },
-			{ "x": 7, "y": 16, "order": 2 },
-			{ "x": 7, "y": 95, "order": 12 },
-			{ "x": 7, "y": 271, "order": 27 },
-			{ "x": 7, "y": 308, "order": 8 },
-			{ "x": 7, "y": 464, "order": 1 },
-			{ "x": 16, "y": 164, "order": 26 },
-			{ "x": 41, "y": 378, "order": 39 },
-			{ "x": 50, "y": 471, "order": 13 },
-			{ "x": 51, "y": 101, "order": 17 },
-			{ "x": 80, "y": 260, "order": 35 },
-			{ "x": 81, "y": 48, "order": 4 },
-			{ "x": 91, "y": 143, "order": 47 },
-			{ "x": 115, "y": 8, "order": 25 },
-			{ "x": 141, "y": 360, "order": 28 },
-			{ "x": 153, "y": 269, "order": 41 },
-			{ "x": 164, "y": 55, "order": 44 },
-			{ "x": 173, "y": 101, "order": 36 },
-			{ "x": 173, "y": 492, "order": 6 },
-			{ "x": 187, "y": 160, "order": 48 },
-			{ "x": 194, "y": 388, "order": 19 },
-			{ "x": 200, "y": 373, "order": 20 },
-			{ "x": 204, "y": 282, "order": 45 },
-			{ "x": 239, "y": 469, "order": 11 },
-			{ "x": 240, "y": 8, "order": 32 },
-			{ "x": 271, "y": 163, "order": 43 },
-			{ "x": 276, "y": 255, "order": 46 },
-			{ "x": 296, "y": 428, "order": 3 },
-			{ "x": 297, "y": 281, "order": 16 },
-			{ "x": 306, "y": 8, "order": 10 },
-			{ "x": 317, "y": 17, "order": 15 },
-			{ "x": 327, "y": 84, "order": 29 },
-			{ "x": 348, "y": 142, "order": 40 },
-			{ "x": 348, "y": 342, "order": 21 },
-			{ "x": 370, "y": 405, "order": 22 },
-			{ "x": 401, "y": 103, "order": 18 },
-			{ "x": 407, "y": 40, "order": 31 },
-			{ "x": 421, "y": 508, "order": 7 },
-			{ "x": 453, "y": 215, "order": 33 },
-			{ "x": 455, "y": 377, "order": 34 },
-			{ "x": 460, "y": 170, "order": 38 },
-			{ "x": 475, "y": 319, "order": 42 },
-			{ "x": 488, "y": 412, "order": 37 },
-			{ "x": 504, "y": 8, "order": 24 },
-			{ "x": 515, "y": 67, "order": 5 },
-			{ "x": 517, "y": 211, "order": 14 },
-			{ "x": 532, "y": 305, "order": 23 },
-			{ "x": 556, "y": 335, "order": 9 }
-		],
-
-		[
-			//Necropolis
-			{ "x": 7, "y": 8, "order": 22 },
-			{ "x": 7, "y": 188, "order": 1 },
-			{ "x": 7, "y": 329, "order": 20 },
-			{ "x": 7, "y": 403, "order": 24 },
-			{ "x": 8, "y": 8, "order": 47 },
-			{ "x": 14, "y": 138, "order": 30 },
-			{ "x": 15, "y": 8, "order": 9 },
-			{ "x": 34, "y": 374, "order": 31 },
-			{ "x": 55, "y": 82, "order": 25 },
-			{ "x": 55, "y": 150, "order": 38 },
-			{ "x": 57, "y": 281, "order": 8 },
-			{ "x": 94, "y": 188, "order": 36 },
-			{ "x": 108, "y": 344, "order": 6 },
-			{ "x": 119, "y": 424, "order": 13 },
-			{ "x": 124, "y": 256, "order": 37 },
-			{ "x": 131, "y": 8, "order": 7 },
-			{ "x": 139, "y": 92, "order": 11 },
-			{ "x": 145, "y": 371, "order": 29 },
-			{ "x": 148, "y": 42, "order": 21 },
-			{ "x": 175, "y": 200, "order": 44 },
-			{ "x": 200, "y": 291, "order": 45 },
-			{ "x": 201, "y": 66, "order": 42 },
-			{ "x": 210, "y": 482, "order": 18 },
-			{ "x": 247, "y": 98, "order": 28 },
-			{ "x": 250, "y": 227, "order": 48 },
-			{ "x": 262, "y": 8, "order": 15 },
-			{ "x": 293, "y": 373, "order": 32 },
-			{ "x": 303, "y": 286, "order": 46 },
-			{ "x": 318, "y": 173, "order": 43 },
-			{ "x": 345, "y": 444, "order": 2 },
-			{ "x": 356, "y": 8, "order": 5 },
-			{ "x": 357, "y": 386, "order": 17 },
-			{ "x": 362, "y": 38, "order": 40 },
-			{ "x": 382, "y": 8, "order": 19 },
-			{ "x": 382, "y": 119, "order": 35 },
-			{ "x": 421, "y": 164, "order": 27 },
-			{ "x": 422, "y": 249, "order": 4 },
-			{ "x": 428, "y": 52, "order": 14 },
-			{ "x": 429, "y": 101, "order": 10 },
-			{ "x": 443, "y": 132, "order": 41 },
-			{ "x": 452, "y": 239, "order": 34 },
-			{ "x": 465, "y": 441, "order": 23 },
-			{ "x": 469, "y": 300, "order": 39 },
-			{ "x": 476, "y": 20, "order": 3 },
-			{ "x": 537, "y": 249, "order": 33 },
-			{ "x": 547, "y": 430, "order": 12 },
-			{ "x": 559, "y": 140, "order": 26 },
-			{ "x": 558, "y": 8, "order": 16 }
-		],
-
-		[
-			//Dungeon
-			{ "x": 7, "y": 8, "order": 31 },
-			{ "x": 7, "y": 125, "order": 1 },
-			{ "x": 7, "y": 353, "order": 33 },
-			{ "x": 7, "y": 394, "order": 6 },
-			{ "x": 30, "y": 101, "order": 36 },
-			{ "x": 33, "y": 219, "order": 16 },
-			{ "x": 57, "y": 171, "order": 13 },
-			{ "x": 62, "y": 8, "order": 47 },
-			{ "x": 63, "y": 90, "order": 41 },
-			{ "x": 83, "y": 471, "order": 10 },
-			{ "x": 94, "y": 117, "order": 21 },
-			{ "x": 99, "y": 8, "order": 5 },
-			{ "x": 113, "y": 258, "order": 32 },
-			{ "x": 156, "y": 146, "order": 28 },
-			{ "x": 165, "y": 288, "order": 42 },
-			{ "x": 172, "y": 388, "order": 44 },
-			{ "x": 177, "y": 36, "order": 39 },
-			{ "x": 194, "y": 235, "order": 46 },
-			{ "x": 204, "y": 502, "order": 3 },
-			{ "x": 236, "y": 320, "order": 23 },
-			{ "x": 238, "y": 8, "order": 20 },
-			{ "x": 245, "y": 75, "order": 25 },
-			{ "x": 247, "y": 396, "order": 29 },
-			{ "x": 247, "y": 459, "order": 14 },
-			{ "x": 253, "y": 152, "order": 48 },
-			{ "x": 301, "y": 233, "order": 43 },
-			{ "x": 323, "y": 8, "order": 12 },
-			{ "x": 323, "y": 178, "order": 45 },
-			{ "x": 328, "y": 342, "order": 30 },
-			{ "x": 329, "y": 428, "order": 19 },
-			{ "x": 339, "y": 8, "order": 26 },
-			{ "x": 357, "y": 141, "order": 27 },
-			{ "x": 374, "y": 8, "order": 15 },
-			{ "x": 374, "y": 236, "order": 34 },
-			{ "x": 392, "y": 439, "order": 35 },
-			{ "x": 400, "y": 291, "order": 40 },
-			{ "x": 401, "y": 103, "order": 18 },
-			{ "x": 422, "y": 381, "order": 37 },
-			{ "x": 436, "y": 8, "order": 17 },
-			{ "x": 438, "y": 336, "order": 24 },
-			{ "x": 449, "y": 131, "order": 9 },
-			{ "x": 453, "y": 161, "order": 11 },
-			{ "x": 471, "y": 267, "order": 38 },
-			{ "x": 477, "y": 64, "order": 22 },
-			{ "x": 480, "y": 456, "order": 8 },
-			{ "x": 485, "y": 8, "order": 2 },
-			{ "x": 536, "y": 197, "order": 4 },
-			{ "x": 541, "y": 22, "order": 7 }
-		],
-
-		[
-			//Stronghold
-			{ "x": 7, "y": 8, "order": 6 },
-			{ "x": 7, "y": 229, "order": 14 },
-			{ "x": 7, "y": 405, "order": 15 },
-			{ "x": 7, "y": 465, "order": 10 },
-			{ "x": 12, "y": 8, "order": 9 },
-			{ "x": 32, "y": 245, "order": 21 },
-			{ "x": 32, "y": 277, "order": 33 },
-			{ "x": 36, "y": 337, "order": 19 },
-			{ "x": 39, "y": 15, "order": 36 },
-			{ "x": 47, "y": 115, "order": 23 },
-			{ "x": 49, "y": 178, "order": 25 },
-			{ "x": 70, "y": 8, "order": 1 },
-			{ "x": 101, "y": 35, "order": 41 },
-			{ "x": 111, "y": 311, "order": 44 },
-			{ "x": 123, "y": 156, "order": 45 },
-			{ "x": 138, "y": 423, "order": 32 },
-			{ "x": 140, "y": 224, "order": 43 },
-			{ "x": 144, "y": 136, "order": 11 },
-			{ "x": 149, "y": 452, "order": 18 },
-			{ "x": 158, "y": 475, "order": 5 },
-			{ "x": 191, "y": 68, "order": 7 },
-			{ "x": 202, "y": 12, "order": 39 },
-			{ "x": 218, "y": 349, "order": 34 },
-			{ "x": 219, "y": 285, "order": 42 },
-			{ "x": 222, "y": 96, "order": 28 },
-			{ "x": 262, "y": 8, "order": 8 },
-			{ "x": 279, "y": 166, "order": 48 },
-			{ "x": 279, "y": 425, "order": 22 },
-			{ "x": 303, "y": 314, "order": 27 },
-			{ "x": 320, "y": 109, "order": 16 },
-			{ "x": 326, "y": 146, "order": 47 },
-			{ "x": 333, "y": 160, "order": 46 },
-			{ "x": 362, "y": 26, "order": 4 },
-			{ "x": 365, "y": 441, "order": 17 },
-			{ "x": 380, "y": 297, "order": 38 },
-			{ "x": 392, "y": 242, "order": 29 },
-			{ "x": 427, "y": 275, "order": 40 },
-			{ "x": 445, "y": 85, "order": 2 },
-			{ "x": 446, "y": 424, "order": 30 },
-			{ "x": 459, "y": 347, "order": 37 },
-			{ "x": 463, "y": 53, "order": 24 },
-			{ "x": 484, "y": 210, "order": 20 },
-			{ "x": 488, "y": 8, "order": 26 },
-			{ "x": 489, "y": 303, "order": 35 },
-			{ "x": 529, "y": 8, "order": 31 },
-			{ "x": 529, "y": 421, "order": 3 },
-			{ "x": 558, "y": 87, "order": 13 },
-			{ "x": 563, "y": 261, "order": 12 }
-		],
-
-		[
-			//Fortress
-			{ "x": 7, "y": 8, "order": 36 },
-			{ "x": 7, "y": 152, "order": 25 },
-			{ "x": 7, "y": 306, "order": 34 },
-			{ "x": 7, "y": 388, "order": 23 },
-			{ "x": 7, "y": 434, "order": 15 },
-			{ "x": 23, "y": 417, "order": 37 },
-			{ "x": 32, "y": 232, "order": 38 },
-			{ "x": 42, "y": 137, "order": 39 },
-			{ "x": 47, "y": 440, "order": 8 },
-			{ "x": 56, "y": 19, "order": 47 },
-			{ "x": 71, "y": 8, "order": 1 },
-			{ "x": 87, "y": 219, "order": 30 },
-			{ "x": 90, "y": 26, "order": 41 },
-			{ "x": 104, "y": 397, "order": 33 },
-			{ "x": 116, "y": 345, "order": 40 },
-			{ "x": 134, "y": 215, "order": 11 },
-			{ "x": 175, "y": 168, "order": 19 },
-			{ "x": 191, "y": 428, "order": 13 },
-			{ "x": 200, "y": 326, "order": 24 },
-			{ "x": 216, "y": 98, "order": 18 },
-			{ "x": 221, "y": 398, "order": 20 },
-			{ "x": 225, "y": 235, "order": 46 },
-			{ "x": 239, "y": 8, "order": 9 },
-			{ "x": 245, "y": 40, "order": 7 },
-			{ "x": 248, "y": 208, "order": 48 },
-			{ "x": 261, "y": 439, "order": 5 },
-			{ "x": 262, "y": 134, "order": 26 },
-			{ "x": 297, "y": 352, "order": 22 },
-			{ "x": 309, "y": 99, "order": 16 },
-			{ "x": 320, "y": 262, "order": 43 },
-			{ "x": 323, "y": 404, "order": 10 },
-			{ "x": 326, "y": 200, "order": 45 },
-			{ "x": 331, "y": 20, "order": 17 },
-			{ "x": 345, "y": 178, "order": 21 },
-			{ "x": 353, "y": 8, "order": 3 },
-			{ "x": 358, "y": 290, "order": 42 },
-			{ "x": 381, "y": 399, "order": 14 },
-			{ "x": 400, "y": 65, "order": 12 },
-			{ "x": 428, "y": 160, "order": 35 },
-			{ "x": 448, "y": 293, "order": 29 },
-			{ "x": 451, "y": 94, "order": 27 },
-			{ "x": 453, "y": 424, "order": 2 },
-			{ "x": 462, "y": 397, "order": 32 },
-			{ "x": 465, "y": 8, "order": 4 },
-			{ "x": 486, "y": 163, "order": 44 },
-			{ "x": 492, "y": 184, "order": 31 },
-			{ "x": 517, "y": 304, "order": 6 },
-			{ "x": 549, "y": 8, "order": 28 }
-		],
-
-		[
-			//Conflux
-			{ "x": 7, "y": 8, "order": 1 },
-			{ "x": 7, "y": 54, "order": 6 },
-			{ "x": 7, "y": 227, "order": 16 },
-			{ "x": 7, "y": 426, "order": 9 },
-			{ "x": 15, "y": 48, "order": 22 },
-			{ "x": 45, "y": 375, "order": 32 },
-			{ "x": 48, "y": 249, "order": 28 },
-			{ "x": 86, "y": 500, "order": 15 },
-			{ "x": 93, "y": 55, "order": 37 },
-			{ "x": 99, "y": 245, "order": 7 },
-			{ "x": 101, "y": 354, "order": 27 },
-			{ "x": 104, "y": 175, "order": 35 },
-			{ "x": 107, "y": 14, "order": 21 },
-			{ "x": 124, "y": 296, "order": 38 },
-			{ "x": 134, "y": 8, "order": 4 },
-			{ "x": 181, "y": 466, "order": 26 },
-			{ "x": 182, "y": 200, "order": 40 },
-			{ "x": 189, "y": 381, "order": 33 },
-			{ "x": 192, "y": 40, "order": 8 },
-			{ "x": 192, "y": 364, "order": 11 },
-			{ "x": 201, "y": 124, "order": 48 },
-			{ "x": 203, "y": 330, "order": 42 },
-			{ "x": 228, "y": 293, "order": 45 },
-			{ "x": 235, "y": 39, "order": 25 },
-			{ "x": 242, "y": 335, "order": 44 },
-			{ "x": 275, "y": 488, "order": 5 },
-			{ "x": 278, "y": 202, "order": 46 },
-			{ "x": 290, "y": 80, "order": 13 },
-			{ "x": 291, "y": 115, "order": 20 },
-			{ "x": 308, "y": 225, "order": 43 },
-			{ "x": 310, "y": 158, "order": 39 },
-			{ "x": 312, "y": 24, "order": 12 },
-			{ "x": 317, "y": 8, "order": 2 },
-			{ "x": 323, "y": 443, "order": 10 },
-			{ "x": 327, "y": 253, "order": 41 },
-			{ "x": 330, "y": 36, "order": 36 },
-			{ "x": 349, "y": 330, "order": 34 },
-			{ "x": 349, "y": 426, "order": 17 },
-			{ "x": 407, "y": 191, "order": 47 },
-			{ "x": 421, "y": 430, "order": 31 },
-			{ "x": 428, "y": 246, "order": 23 },
-			{ "x": 467, "y": 90, "order": 29 },
-			{ "x": 481, "y": 13, "order": 30 },
-			{ "x": 489, "y": 346, "order": 18 },
-			{ "x": 504, "y": 113, "order": 19 },
-			{ "x": 504, "y": 190, "order": 24 },
-			{ "x": 507, "y": 8, "order": 14 },
-			{ "x": 542, "y": 436, "order": 3 }
-		]
-	]
-}

+ 1 - 1
lib/CBattleCallback.cpp

@@ -996,7 +996,7 @@ std::pair<ui32, ui32> CBattleInfoCallback::battleEstimateDamage(const BattleAtta
 {
 	RETURN_IF_NOT_BATTLE(std::make_pair(0, 0));
 
-	const bool shooting = battleCanShoot(bai.attacker, bai.defenderPosition); //TODO handle bonus bearer
+	//const bool shooting = battleCanShoot(bai.attacker, bai.defenderPosition); //TODO handle bonus bearer
 	//const ui8 mySide = !attacker->attackerOwned;
 
 	TDmgRange ret = calculateDmgRange(bai);

+ 0 - 40
lib/CHeroHandler.cpp

@@ -119,46 +119,6 @@ void CHeroHandler::loadObstacles()
 	//loadObstacles(config["moats"], true, moats);
 }
 
-void CHeroHandler::loadPuzzleInfo()
-{
-	const JsonNode config(ResourceID("config/puzzle_map.json"));
-
-	int faction = 0;
-
-	BOOST_FOREACH(const JsonNode &puzzle, config["puzzles"].Vector()) 
-	{
-		int idx = 0;
-
-		BOOST_FOREACH(const JsonNode &piece, puzzle.Vector()) 
-		{
-			SPuzzleInfo spi;
-
-			spi.x = piece["x"].Float();
-			spi.y = piece["y"].Float();
-			spi.whenUncovered = piece["order"].Float();
-			spi.number = idx;
-				
-			// filename calculation
-			std::ostringstream suffix;
-			suffix << std::setfill('0') << std::setw(2);
-			suffix << idx << ".BMP";
-
-			static const std::string factionToInfix[GameConstants::F_NUMBER] = {"CAS", "RAM", "TOW", "INF", "NEC", "DUN", "STR", "FOR", "ELE"};
-			spi.filename = "PUZ" + factionToInfix[faction] + suffix.str();
-
-			puzzleInfo[faction].push_back(spi);
-
-			idx ++;
-		}
-
-		assert(idx == PUZZLES_PER_FACTION);
-
-		faction ++;
-	}
-
-	assert(faction == GameConstants::F_NUMBER);
-}
-
 void CHeroHandler::loadHeroes()
 {
 	VLC->heroh = this;

+ 1 - 19
lib/CHeroHandler.h

@@ -103,21 +103,6 @@ struct DLL_LINKAGE CObstacleInfo
 	}
 };
 
-struct DLL_LINKAGE SPuzzleInfo
-{
-	ui16 number; //type of puzzle
-	si16 x, y; //position
-	ui16 whenUncovered; //determines the sequnce of discovering (the lesser it is the sooner puzzle will be discovered)
-	std::string filename; //file with graphic of this puzzle
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & number & x & y & whenUncovered & filename;
-	}
-};
-
-const int PUZZLES_PER_FACTION = 48;
-
 class DLL_LINKAGE CHeroHandler
 {
 public:
@@ -146,9 +131,6 @@ public:
 
 	void loadObstacles(); //loads info about obstacles
 
-	std::vector<SPuzzleInfo> puzzleInfo[GameConstants::F_NUMBER]; //descriptions of puzzles
-	void loadPuzzleInfo();
-
 	ui32 level(ui64 experience) const; //calculates level corresponding to given experience amount
 	ui64 reqExp(ui32 level) const; //calculates experience required for given level
 
@@ -161,7 +143,7 @@ public:
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & heroClasses & heroes & expPerLevel & ballistics & terrCosts & puzzleInfo;
+		h & heroClasses & heroes & expPerLevel & ballistics & terrCosts;
 		h & obstacles & absoluteObstacles;
 		if(!h.saving)
 		{

+ 18 - 22
lib/CModHandler.cpp

@@ -51,7 +51,7 @@ void CModHandler::loadConfigFromFile (std::string name)
 {
 
 	const JsonNode config(ResourceID("config/" + name + ".json"));
-	auto hardcodedFeatures = config["hardcodedFeatures"];
+	const JsonNode & hardcodedFeatures = config["hardcodedFeatures"];
 
 	settings.CREEP_SIZE = hardcodedFeatures["CREEP_SIZE"].Float();
 	settings.WEEKLY_GROWTH = hardcodedFeatures["WEEKLY_GROWTH_PERCENT"].Float();
@@ -60,7 +60,7 @@ void CModHandler::loadConfigFromFile (std::string name)
 	settings.DWELLINGS_ACCUMULATE_CREATURES = hardcodedFeatures["DWELLINGS_ACCUMULATE_CREATURES"].Bool();
 	settings.ALL_CREATURES_GET_DOUBLE_MONTHS = hardcodedFeatures["ALL_CREATURES_GET_DOUBLE_MONTHS"].Bool();
 
-	auto gameModules = config["modules"];
+	const JsonNode & gameModules = config["modules"];
 	modules.STACK_EXP = gameModules["STACK_EXPERIENCE"].Bool();
 	modules.STACK_ARTIFACT = gameModules["STACK_ARTIFACTS"].Bool();
 	modules.COMMANDERS = gameModules["COMMANDERS"].Bool();
@@ -70,7 +70,7 @@ void CModHandler::loadConfigFromFile (std::string name)
 
 	//TODO: read mods from Mods/ folder
 
-	auto & configList = CResourceHandler::get()->getResourcesWithName (ResourceID("CONFIG/mod.json")); 
+	auto & configList = CResourceHandler::get()->getResourcesWithName (ResourceID("CONFIG/mod.json"));
 
 	BOOST_FOREACH(auto & entry, configList)
 	{
@@ -82,17 +82,13 @@ void CModHandler::loadConfigFromFile (std::string name)
 		const JsonNode config ((char*)textData.get(), stream->getSize());
 
 		const JsonNode *value = &config["creatures"];
-		if (!value->isNull())
+		BOOST_FOREACH (auto creature, value->Vector())
 		{
-			BOOST_FOREACH (auto creature, value->Vector())
-			{
-				auto cre = loadCreature (creature); //create and push back creature
-			}
+			auto cre = loadCreature (creature); //create and push back creature
 		}
 	}
-
-
 }
+
 void CModHandler::saveConfigToFile (std::string name)
 {
 	//JsonNode savedConf = config;
@@ -113,13 +109,13 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
 	const JsonNode *value; //optional value
 
 	//TODO: ref name?
-	auto name = node["name"];
+	const JsonNode & name = node["name"];
 	cre->nameSing = name["singular"].String();
 	cre->namePl = name["plural"].String();
 	cre->nameRef = cre->nameSing;
 
 	//TODO: export resource set to separate function?
-	auto cost = node["cost"];
+	const JsonNode &  cost = node["cost"];
 	if (cost.getType() == JsonNode::DATA_FLOAT) //gold
 	{
 		cre->cost[Res::GOLD] = cost.Float();
@@ -127,7 +123,7 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
 	else if (cost.getType() == JsonNode::DATA_VECTOR)
 	{
 		int i = 0;
-		BOOST_FOREACH (auto val, cost.Vector())
+		BOOST_FOREACH (auto & val, cost.Vector())
 		{
 			cre->cost[i++] = val.Float();
 		}
@@ -171,11 +167,11 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
 	cre->addBonus(node["speed"].Float(), Bonus::STACKS_SPEED);
 	cre->addBonus(node["attack"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK);
 	cre->addBonus(node["defense"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE);
-	auto vec = node["damage"];
+	const JsonNode &  vec = node["damage"];
 	cre->addBonus(vec["min"].Float(), Bonus::CREATURE_DAMAGE, 1);
 	cre->addBonus(vec["max"].Float(), Bonus::CREATURE_DAMAGE, 2);
 
-	auto amounts = node ["advMapAmount"];
+	auto & amounts = node ["advMapAmount"];
 	cre->ammMin = amounts["min"].Float();
 	cre->ammMax = amounts["max"].Float();
 
@@ -183,7 +179,7 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
 	value = &node["upgrades"];
 	if (!value->isNull())
 	{
-		BOOST_FOREACH (auto str, value->Vector())
+		BOOST_FOREACH (auto & str, value->Vector())
 		{
 			cre->upgradeNames.insert (str.String());
 		}
@@ -213,19 +209,19 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
 	}
 	//graphics
 
-	auto graphics = node["graphics"];
+	const JsonNode & graphics = node["graphics"];
 	cre->animDefName = graphics["animation"].String();
 	cre->timeBetweenFidgets = graphics["timeBetweenFidgets"].Float();
 	cre->troopCountLocationOffset = graphics["troopCountLocationOffset"].Float();
 	cre->attackClimaxFrame = graphics["attackClimaxFrame"].Float();
 
-	auto animationTime = graphics["animationTime"];
+	const JsonNode & animationTime = graphics["animationTime"];
 	cre->walkAnimationTime = animationTime["walk"].Float();
 	cre->attackAnimationTime = animationTime["attack"].Float();
 	cre->flightAnimationDistance = animationTime["flight"].Float(); //?
 	//TODO: background?
-	auto missle = graphics["missle"];
-	auto offsets = missle["offset"];
+	const JsonNode & missle = graphics["missle"];
+	const JsonNode & offsets = missle["offset"];
 	cre->upperRightMissleOffsetX = offsets["upperX"].Float();
 	cre->upperRightMissleOffsetY = offsets["upperY"].Float();
 	cre->rightMissleOffsetX = offsets["middleX"].Float();
@@ -233,7 +229,7 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
 	cre->lowerRightMissleOffsetX = offsets["lowerX"].Float();
 	cre->lowerRightMissleOffsetY = offsets["lowerY"].Float();
 	int i = 0;
-	BOOST_FOREACH (auto angle, missle["frameAngles"].Vector())
+	BOOST_FOREACH (auto & angle, missle["frameAngles"].Vector())
 	{
 		cre->missleFrameAngles[i++] = angle.Float();
 	}
@@ -243,7 +239,7 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
 	//VLC->creh->idToProjectile[cre->idNumber] = "PLCBOWX.DEF";
 	cre->projectile = "PLCBOWX.DEF";
 
-	auto sounds = node["sound"];
+	const JsonNode & sounds = node["sound"];
 
 #define GET_SOUND_VALUE(value_name) do { value = &node[#value_name]; if (!value->isNull()) cre->sounds.value_name = sounds[#value_name].String(); } while(0)
 	GET_SOUND_VALUE(attack);

+ 28 - 0
lib/CTownHandler.cpp

@@ -292,6 +292,32 @@ void CTownHandler::loadTown(CTown &town, const JsonNode & source)
 	loadClientData(town,source);
 }
 
+void CTownHandler::loadPuzzle(CFaction &faction, const JsonNode &source)
+{
+	faction.puzzleMap.reserve(GameConstants::PUZZLE_MAP_PIECES);
+
+	std::string prefix = source["prefix"].String();
+	BOOST_FOREACH(const JsonNode &piece, source["pieces"].Vector())
+	{
+		size_t index = faction.puzzleMap.size();
+		SPuzzleInfo spi;
+
+		spi.x = piece["x"].Float();
+		spi.y = piece["y"].Float();
+		spi.whenUncovered = piece["index"].Float();
+		spi.number = index;
+
+		// filename calculation
+		std::ostringstream suffix;
+		suffix << std::setfill('0') << std::setw(2) << index;
+
+		spi.filename = prefix + suffix.str();
+
+		faction.puzzleMap.push_back(spi);
+	}
+	assert(faction.puzzleMap.size() == GameConstants::PUZZLE_MAP_PIECES);
+}
+
 void CTownHandler::loadFactions(const JsonNode &source)
 {
 	BOOST_FOREACH(auto & node, source.Struct())
@@ -318,6 +344,8 @@ void CTownHandler::loadFactions(const JsonNode &source)
 			towns[id].typeID = id;
 			loadTown(towns[id], node.second["town"]);
 		}
+		if (!node.second["puzzleMap"].isNull())
+			loadPuzzle(faction, node.second["puzzleMap"]);
 	}
 }
 

+ 18 - 1
lib/CTownHandler.h

@@ -135,6 +135,19 @@ public:
 	friend class CTownHandler;
 };
 
+struct DLL_LINKAGE SPuzzleInfo
+{
+	ui16 number; //type of puzzle
+	si16 x, y; //position
+	ui16 whenUncovered; //determines the sequnce of discovering (the lesser it is the sooner puzzle will be discovered)
+	std::string filename; //file with graphic of this puzzle
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & number & x & y & whenUncovered & filename;
+	}
+};
+
 class CFaction
 {
 public:
@@ -146,9 +159,11 @@ public:
 	std::string creatureBg120;
 	std::string creatureBg130;
 
+	std::vector<SPuzzleInfo> puzzleMap;
+
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & name & factionID & nativeTerrain & creatureBg120 & creatureBg130;
+		h & name & factionID & nativeTerrain & creatureBg120 & creatureBg130 & puzzleMap;
 	}
 };
 
@@ -169,6 +184,8 @@ class DLL_LINKAGE CTownHandler
 
 	void loadTown(CTown &town, const JsonNode & source);
 
+	void loadPuzzle(CFaction & faction, const JsonNode & source);
+
 	/// main loading function, accepts merged JSON source and add all entries from it into game
 	/// all entries in JSON should be checked for validness before using this function
 	void loadFactions(const JsonNode & source);

+ 1 - 0
lib/GameConstants.h

@@ -79,6 +79,7 @@ namespace GameConstants
 	const int SPELL_LEVELS = 5;
 	const int AVAILABLE_HEROES_PER_PLAYER = 2;
 	const int SPELLBOOK_GOLD_COST = 500;
+	const int PUZZLE_MAP_PIECES = 48;
 
 	const int BATTLE_PENALTY_DISTANCE = 10; //if the distance is > than this, then shooting stack has distance penalty
 

+ 0 - 1
lib/VCMI_Lib.cpp

@@ -75,7 +75,6 @@ void LibClasses::init()
 	heroh = new CHeroHandler;
 	heroh->loadHeroes();
 	heroh->loadObstacles();
-	heroh->loadPuzzleInfo();
 	tlog0 <<"\tHero handler: "<<pomtime.getDiff()<<std::endl;
 
 	arth = new CArtHandler;