Переглянути джерело

* partially implemented puzzle map

mateuszb 16 роки тому
батько
коміт
399f58f1af

+ 11 - 3
client/CAdvmapInterface.cpp

@@ -1118,12 +1118,12 @@ void CTerrainRect::show(SDL_Surface * to)
 		CGI->mh->terrainRect
 			(LOCPLINT->adventureInt->position, LOCPLINT->adventureInt->anim,
 			 &LOCPLINT->cb->getVisibilityMap(), true, LOCPLINT->adventureInt->heroAnim,
-			 to, &pos, moveX, moveY);
+			 to, &pos, moveX, moveY, false);
 	else
 		CGI->mh->terrainRect
 			(LOCPLINT->adventureInt->position, LOCPLINT->adventureInt->anim,
 			 &LOCPLINT->cb->getVisibilityMap(), true, LOCPLINT->adventureInt->heroAnim,
-			 to, &pos, 0, 0);
+			 to, &pos, 0, 0, false);
 	
 	//SDL_BlitSurface(teren,&genRect(pos.h,pos.w,0,0),screen,&genRect(547,594,7,6));
 	//SDL_FreeSurface(teren);
@@ -1899,6 +1899,9 @@ CAdventureOptions::CAdventureOptions()
 	scenInfo = new AdventureMapButton("","", boost::bind(&CGuiHandler::popIntTotally, &GH, this), 24, 198, "ADVINFO.DEF",SDLK_i);
 	scenInfo->callback += CAdventureOptions::showScenarioInfo;
 	//viewWorld = new AdventureMapButton("","",boost::bind(&CGuiHandler::popIntTotally, &GH, this), 204, 313, "IOK6432.DEF",SDLK_RETURN);
+
+	puzzle = new AdventureMapButton("","", boost::bind(&CGuiHandler::popIntTotally, &GH, this), 24, 81, "ADVPUZ.DEF");;
+	puzzle->callback += CAdventureOptions::showPuzzleMap;
 }
 
 CAdventureOptions::~CAdventureOptions()
@@ -1908,4 +1911,9 @@ CAdventureOptions::~CAdventureOptions()
 void CAdventureOptions::showScenarioInfo()
 {
 	GH.pushInt(new CScenarioInfo(LOCPLINT->cb->getMapHeader(), LOCPLINT->cb->getStartInfo()));
-}
+}
+
+void CAdventureOptions::showPuzzleMap()
+{
+	GH.pushInt(new CPuzzleWindow());
+}

+ 1 - 0
client/CAdvmapInterface.h

@@ -34,6 +34,7 @@ public:
 	CAdventureOptions();
 	~CAdventureOptions();
 	static void showScenarioInfo();
+	static void showPuzzleMap();
 };
 	 
 

+ 1 - 1
client/CBattleInterface.cpp

@@ -2442,7 +2442,7 @@ void CBattleInterface::showPieceOfWall(SDL_Surface * to, int hex)
 	if(!siegeH)
 		return;
 
-	static const std::map<int, int> hexToPart = boost::assign::map_list_of(12, 8)(16, 1)(29, 7)(62, 12)(78, 6)(112, 10)(147, 5)(165, 11)(182, 4);
+	static const std::map<int, int> hexToPart = boost::assign::map_list_of(12, 8)(16, 1)(29, 7)(50, 2)(62, 12)(78, 6)(112, 10)(147, 5)(165, 11)(182, 4);
 
 	std::map<int, int>::const_iterator it = hexToPart.find(hex);
 	if(it != hexToPart.end())

+ 1 - 0
client/CConfigHandler.cpp

@@ -238,6 +238,7 @@ struct SettingsGrammar : public grammar<SettingsGrammar>
 							  | "width=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::advmapW)]
 							  | "height=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::advmapH)]
 							  | "smoothMove=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::smoothMove)]
+							  | "puzzleSepia=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::puzzleSepia)]
 							) 
 						 )
 				| str_p("background=") >> fname[SetAdventureStr(&AdventureMapConfig::mainGraphic)]

+ 1 - 0
client/CConfigHandler.h

@@ -44,6 +44,7 @@ namespace config
 		//advmap
 		int advmapX, advmapY, advmapW, advmapH;
 		bool smoothMove;
+		bool puzzleSepia;
 		//general properties
 		std::string mainGraphic;
 		//buttons

+ 97 - 0
client/GUIClasses.cpp

@@ -4157,3 +4157,100 @@ CShipyardWindow::CShipyardWindow(const std::vector<si32> &cost, int state, const
 	printAtMiddle(CGI->generaltexth->jktexts[13], 165, 28, GEORXX, tytulowy, bg);  //Build A New Ship
 	printAtMiddle(CGI->generaltexth->jktexts[14], 165, 218, GEOR16, zwykly, bg); //Resource cost:
 }
+
+CPuzzleWindow::CPuzzleWindow()
+:animCount(0)
+{
+	SDL_Surface * back = BitmapHandler::loadBitmap("PUZZLE.BMP", false);
+	//make transparency black
+	back->format->palette->colors[0].b = back->format->palette->colors[0].r = back->format->palette->colors[0].g = 0;
+	//the rest
+	background = SDL_ConvertSurface(back, screen->format, back->flags);
+	SDL_FreeSurface(back);
+	pos = genRect(background->h, background->w, (conf.cc.resx - background->w) / 2, (conf.cc.resy - background->h) / 2);
+	quitb = new AdventureMapButton(CGI->generaltexth->allTexts[599], "", boost::bind(&CGuiHandler::popIntTotally, &GH, this), pos.x+670, pos.y+538, "IOK6432.DEF", SDLK_RETURN);
+	resdatabar = new CResDataBar();
+	resdatabar->pos.x = pos.x+3; resdatabar->pos.y = pos.y+575;
+
+	//printing necessary thinks to background
+	
+	CGI->mh->terrainRect
+		(int3(14, 15, 0), LOCPLINT->adventureInt->anim,
+		 &LOCPLINT->cb->getVisibilityMap(), true, LOCPLINT->adventureInt->heroAnim,
+		 background, &genRect(544, 591, 8, 8), 0, 0, true);
+
+	
+	float discoveryRatio = 0.5f;
+	int faction = 3;
+
+	std::vector<SPuzzleInfo> puzzlesToPrint;
+
+	for(int g=0; g<PUZZLES_PER_FACTION; ++g)
+	{
+		if(CGI->heroh->puzzleInfo[faction][g].whenUncovered >= PUZZLES_PER_FACTION * discoveryRatio)
+		{
+			puzzlesToPrint.push_back(CGI->heroh->puzzleInfo[faction][g]);
+		}
+		else
+		{
+			SDL_Surface *buf = BitmapHandler::loadBitmap(CGI->heroh->puzzleInfo[faction][g].filename);
+			puzzlesToPullBack.push_back( std::make_pair(buf, &CGI->heroh->puzzleInfo[faction][g]) );
+		}
+	}
+
+	for(int b = 0; b < puzzlesToPrint.size(); ++b)
+	{
+		SDL_Surface * puzzle = BitmapHandler::loadBitmap(puzzlesToPrint[b].filename);
+
+		blitAt(puzzle, puzzlesToPrint[b].x, puzzlesToPrint[b].y, background);
+
+		SDL_FreeSurface(puzzle);
+	}
+
+}
+
+CPuzzleWindow::~CPuzzleWindow()
+{
+	delete quitb;
+	delete resdatabar;
+	SDL_FreeSurface(background);
+	for(int g = 0; g < puzzlesToPullBack.size(); ++g)
+		SDL_FreeSurface( puzzlesToPullBack[g].first );
+}
+
+void CPuzzleWindow::activate()
+{
+	quitb->activate();
+}
+
+void CPuzzleWindow::deactivate()
+{
+	quitb->deactivate();
+}
+
+void CPuzzleWindow::show(SDL_Surface * to)
+{
+	blitAt(background, pos.x, pos.y, to);
+	quitb->show(to);
+	resdatabar->draw(to);
+
+	//blitting disappearing puzzles
+	for(int g=0; g<2; ++g)
+		if(animCount != 255)
+			++animCount;
+
+	if(animCount != 255)
+	{
+		for(int b = 0; b < puzzlesToPullBack.size(); ++b)
+		{
+			int xPos = puzzlesToPullBack[b].second->x,
+				yPos = puzzlesToPullBack[b].second->y;
+			SDL_Surface *from = puzzlesToPullBack[b].first;
+
+			SDL_SetAlpha(from, SDL_SRCALPHA, 255 - animCount);
+			blitAt(from, xPos, yPos, to);
+		}
+	}
+	//disappearing puzzles blitted
+
+}

+ 21 - 0
client/GUIClasses.h

@@ -60,6 +60,8 @@ class CPlayerInterface;
 class CHeroWindow;
 class CArtifact;
 class CArtifactsOfHero;
+class CResDataBar;
+struct SPuzzleInfo;
 
 class CInfoWindow : public CSimpleWindow //text + comp. + ok button
 { //window able to delete its components when closed
@@ -735,4 +737,23 @@ public:
 	~CShipyardWindow();
 };
 
+class CPuzzleWindow : public CIntObject
+{
+private:
+	SDL_Surface * background;
+	AdventureMapButton * quitb;
+	CResDataBar * resdatabar;
+
+	std::vector<std::pair<SDL_Surface *, SPuzzleInfo *> > puzzlesToPullBack;
+	ui8 animCount;
+
+public:
+	void activate();
+	void deactivate();
+	void show(SDL_Surface * to);
+
+	CPuzzleWindow();
+	~CPuzzleWindow();
+};
+
 #endif //__GUICLASSES_H__

+ 442 - 0
config/puzzle_map.txt

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

+ 5 - 5
config/settings.txt

@@ -16,7 +16,7 @@ GUISettings
 	{
 		AdventureMap
 		{
-			AdvMap: x=7 y=6 width=593 height=547 smoothMove=1;
+			AdvMap: x=7 y=6 width=593 height=547 smoothMove=1 puzzleSepia=1;
 			InfoBox: x=605 y=389;
 			gem0: x=6 y=508 graphic=agemLL.def;
 			gem1: x=556 y=508 graphic=agemLR.def;
@@ -44,7 +44,7 @@ GUISettings
 	{
 		AdventureMap
 		{
-			AdvMap: x=7 y=6 width=817 height=547 smoothMove=1;
+			AdvMap: x=7 y=6 width=817 height=547 smoothMove=1 puzzleSepia=1;
 			InfoBox: x=829 y=389;
 		 	gem0: x=6 y=508 graphic=agemLL.def;
 			gem1: x=780 y=508 graphic=agemLR.def;
@@ -73,7 +73,7 @@ GUISettings
 	{
 		AdventureMap
 		{
-			AdvMap: x=7 y=6 width=817 height=715 smoothMove=1;
+			AdvMap: x=7 y=6 width=817 height=715 smoothMove=1 puzzleSepia=1;
 			InfoBox: x=829 y=557;
 			gem0: x=6 y=676 graphic=agemLL.def;
 			gem1: x=780 y=676 graphic=agemLR.def;
@@ -101,7 +101,7 @@ GUISettings
 	{
 		AdventureMap
 		{
-			AdvMap: x=7 y=6 width=1073 height=971 smoothMove=1;
+			AdvMap: x=7 y=6 width=1073 height=971 smoothMove=1 puzzleSepia=1;
 			InfoBox: x=1085 y=557;
 			gem0: x=6 y=932 graphic=agemLL.def;
 			gem1: x=1036 y=932 graphic=agemLR.def;
@@ -129,7 +129,7 @@ GUISettings
 	{
 		AdventureMap
 		{
-			AdvMap: x=7 y=6 width=1395 height=1147 smoothMove=1;
+			AdvMap: x=7 y=6 width=1395 height=1147 smoothMove=1 puzzleSepia=1;
 			InfoBox: x=1406 y=989;
 			gem0: x=6 y=1108 graphic=agemLL.def;
 			gem1: x=1356 y=1108 graphic=agemLR.def;

+ 45 - 0
hch/CHeroHandler.cpp

@@ -4,6 +4,8 @@
 #include <sstream>
 #include "CLodHandler.h"
 #include "../lib/VCMI_Lib.h"
+#include <iomanip>
+
 extern CLodHandler * bitmaph;
 void loadToIt(std::string &dest, std::string &src, int &iter, int mode);
 
@@ -186,6 +188,49 @@ void CHeroHandler::loadObstacles()
 	}
 }
 
+void CHeroHandler::loadPuzzleInfo()
+{
+	std::ifstream inp;
+	inp.open("config" PATHSEPARATOR "puzzle_map.txt", std::ios_base::in|std::ios_base::binary);
+	if(!inp.is_open())
+	{
+		tlog1<<"missing file: config/puzzle_map.txt"<<std::endl;
+	}
+	else
+	{
+		const int MAX_DUMP = 10000;
+		char dump[MAX_DUMP+1];
+
+		inp.getline(dump, MAX_DUMP);
+
+		for(int fct = 0; fct < F_NUMBER; ++fct)
+		{
+			std::string dmp;
+			inp >> dmp;
+
+			for(int g=0; g<PUZZLES_PER_FACTION; ++g)
+			{
+				SPuzzleInfo spi;
+				inp >> spi.x;
+				inp >> spi.y;
+				inp >> spi.whenUncovered;
+				spi.number = g;
+				
+				//filename calculation
+				std::ostringstream suffix;
+				suffix << std::setfill('0') << std::setw(2);
+				suffix << g << ".BMP";
+
+				static const std::string factionToInfix[F_NUMBER] = {"CAS", "TOW", "RAM", "INF", "NEC", "DUN", "STR", "FOR", "ELE"};
+				spi.filename = "PUZ" + factionToInfix[fct] + suffix.str();
+
+				puzzleInfo[fct].push_back(spi);
+			}
+		}
+		inp.close();
+	}
+}
+
 void CHeroHandler::loadHeroes()
 {
 	VLC->heroh = this;

+ 19 - 1
hch/CHeroHandler.h

@@ -89,6 +89,21 @@ struct DLL_EXPORT CObstacleInfo
 	}
 };
 
+struct DLL_EXPORT 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_EXPORT CHeroHandler
 {
 public:
@@ -117,6 +132,9 @@ public:
 
 	void loadObstacles(); //loads info about obstacles
 
+	std::vector<SPuzzleInfo> puzzleInfo[F_NUMBER]; //descriptions of puzzles
+	void loadPuzzleInfo();
+
 	unsigned int level(ui64 experience); //calculates level corresponding to given experience amount
 	ui64 reqExp(unsigned int level); //calculates experience resuired for given level
 
@@ -130,7 +148,7 @@ public:
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & heroClasses & heroes & expPerLevel & ballistics & wallPositions & obstacles & nativeTerrains;
+		h & heroClasses & heroes & expPerLevel & ballistics & wallPositions & obstacles & nativeTerrains & puzzleInfo;
 		if(!h.saving)
 		{
 			//restore class pointers

+ 1 - 0
lib/VCMI_Lib.cpp

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

+ 93 - 24
mapHandler.cpp

@@ -29,6 +29,7 @@
  */
 
 extern SDL_Surface * screen;
+#define ADVOPT (conf.go()->ac)
 
 std::string nameFromType (int typ)
 {
@@ -500,7 +501,7 @@ void CMapHandler::init()
 // top_tile top left tile to draw. Not necessarily visible.
 // extRect, extRect = map window on screen
 // moveX, moveY: when a hero is in movement indicates how to shift the map. Range is -31 to + 31.
-void CMapHandler::terrainRect(int3 top_tile, unsigned char anim, std::vector< std::vector< std::vector<unsigned char> > > * visibilityMap, bool otherHeroAnim, unsigned char heroAnim, SDL_Surface * extSurf, const SDL_Rect * extRect, int moveX, int moveY)
+void CMapHandler::terrainRect(int3 top_tile, unsigned char anim, const std::vector< std::vector< std::vector<unsigned char> > > * visibilityMap, bool otherHeroAnim, unsigned char heroAnim, SDL_Surface * extSurf, const SDL_Rect * extRect, int moveX, int moveY, bool puzzleMode)
 {
 	// Width and height of the portion of the map to process. Units in tiles.
 	unsigned int dx = tilesW;
@@ -712,6 +713,10 @@ void CMapHandler::terrainRect(int3 top_tile, unsigned char anim, std::vector< st
 				if(obj->ID != HEROI_TYPE && !obj->coveringAt(obj->pos.x - (top_tile.x + bx), top_tile.y + by - obj->pos.y + 5))
 					continue;
 
+				//don't print flaggable objects in puzzle mode
+				if(puzzleMode && obj->tempOwner != 254)
+					continue;
+
 				SDL_Rect sr;
 				sr.x = srx;
 				sr.y = sry;
@@ -830,36 +835,39 @@ void CMapHandler::terrainRect(int3 top_tile, unsigned char anim, std::vector< st
 	// objects printed
 
 	// printing shadow
-	srx = srx_init;
-
-	for (int bx = 0; bx<dx; bx++, srx+=32)
+	if(!puzzleMode)
 	{
-		// Skip column if not in map
-		if (top_tile.x+bx < 0 || top_tile.x+bx >= map->width)
-			continue;
-
-		sry = sry_init;
+		srx = srx_init;
 
-		for (int by = 0; by<dy; by++, sry+=32)
+		for (int bx = 0; bx<dx; bx++, srx+=32)
 		{
-			// Skip tile if not in map
-			if (top_tile.y+by < 0 || top_tile.y+by >= map->height)
+			// Skip column if not in map
+			if (top_tile.x+bx < 0 || top_tile.x+bx >= map->width)
 				continue;
 
-			SDL_Rect sr;
-
-			sr.x = srx;
-			sr.y = sry;
-			sr.h = sr.w = 32;
+			sry = sry_init;
 
-			if (top_tile.x+bx >= 0 &&
-				top_tile.y+by >= 0 &&
-				top_tile.x+bx < CGI->mh->map->width &&
-				top_tile.y+by < CGI->mh->map->height &&
-				!(*visibilityMap)[top_tile.x+bx][top_tile.y+by][top_tile.z])
+			for (int by = 0; by<dy; by++, sry+=32)
 			{
-				SDL_Surface * hide = getVisBitmap(top_tile.x+bx, top_tile.y+by, *visibilityMap, top_tile.z);
-				CSDL_Ext::blit8bppAlphaTo24bpp(hide, &rtile, extSurf, &sr);
+				// Skip tile if not in map
+				if (top_tile.y+by < 0 || top_tile.y+by >= map->height)
+					continue;
+
+				SDL_Rect sr;
+
+				sr.x = srx;
+				sr.y = sry;
+				sr.h = sr.w = 32;
+
+				if (top_tile.x+bx >= 0 &&
+					top_tile.y+by >= 0 &&
+					top_tile.x+bx < CGI->mh->map->width &&
+					top_tile.y+by < CGI->mh->map->height &&
+					!(*visibilityMap)[top_tile.x+bx][top_tile.y+by][top_tile.z])
+				{
+					SDL_Surface * hide = getVisBitmap(top_tile.x+bx, top_tile.y+by, *visibilityMap, top_tile.z);
+					CSDL_Ext::blit8bppAlphaTo24bpp(hide, &rtile, extSurf, &sr);
+				}
 			}
 		}
 	}
@@ -956,6 +964,67 @@ void CMapHandler::terrainRect(int3 top_tile, unsigned char anim, std::vector< st
 	// grid	
 #endif
 
+	//applying sepia / gray effect
+	if(puzzleMode)
+	{
+		if(ADVOPT.puzzleSepia)
+		{
+			const int sepiaDepth = 20;
+			const int sepiaIntensity = 30;
+
+			for(int xp = extRect->x; xp < extRect->x + extRect->w; ++xp)
+			{
+				for(int yp = extRect->y; yp < extRect->y + extRect->h; ++yp)
+				{
+					unsigned char * pixels = (unsigned char*)extSurf->pixels + yp * extSurf->pitch + xp * extSurf->format->BytesPerPixel;
+
+					int b = pixels[0]; 
+					int g = pixels[1]; 
+					int r = pixels[2]; 
+					int gry = (r + g + b) / 3;
+
+					r = g = b = gry; 
+					r = r + (sepiaDepth * 2); 
+					g = g + sepiaDepth; 
+
+					if (r>255) r=255; 
+					if (g>255) g=255; 
+					if (b>255) b=255; 
+
+					// Darken blue color to increase sepia effect 
+					b -= sepiaIntensity; 
+
+					// normalize if out of bounds 
+					if (b<0) b=0; 
+					if (b>255) b=255; 
+
+					pixels[0] = b; 
+					pixels[1] = g; 
+					pixels[2] = r; 
+
+				}
+			}
+		}
+		else
+		{
+			for(int xp = extRect->x; xp < extRect->x + extRect->w; ++xp)
+			{
+				for(int yp = extRect->y; yp < extRect->y + extRect->h; ++yp)
+				{
+					unsigned char * pixels = (unsigned char*)extSurf->pixels + yp * extSurf->pitch + xp * extSurf->format->BytesPerPixel;
+
+					int b = pixels[0]; 
+					int g = pixels[1]; 
+					int r = pixels[2]; 
+					int gry = (r + g + b) / 3;
+
+					pixels[0] = pixels[1] = pixels[2] = gry;
+				}
+			}
+		}
+	}
+	//sepia / gray effect applied
+
 	SDL_SetClipRect(extSurf, &prevClip); //restoring clip_rect
 
 	SDL_FreeSurface(rSurf);

+ 1 - 1
mapHandler.h

@@ -136,7 +136,7 @@ public:
 	void roadsRiverTerrainInit();
 	void prepareFOWDefs();
 
-	void terrainRect(int3 top_tile, unsigned char anim, std::vector< std::vector< std::vector<unsigned char> > > * visibilityMap, bool otherHeroAnim, unsigned char heroAnim, SDL_Surface * extSurf, const SDL_Rect * extRect, int moveX, int moveY);
+	void terrainRect(int3 top_tile, unsigned char anim, const std::vector< std::vector< std::vector<unsigned char> > > * visibilityMap, bool otherHeroAnim, unsigned char heroAnim, SDL_Surface * extSurf, const SDL_Rect * extRect, int moveX, int moveY, bool puzzleMode);
 	void updateWater();
 	unsigned char getHeroFrameNum(unsigned char dir, bool isMoving) const; //terrainRect helper function
 	void validateRectTerr(SDL_Rect * val, const SDL_Rect * ext); //terrainRect helper