浏览代码

- fixed ancient #31
- fixed #603

Ivan Savenko 13 年之前
父节点
当前提交
90ff99d4eb
共有 5 个文件被更改,包括 129 次插入109 次删除
  1. 43 33
      client/CAdvmapInterface.cpp
  2. 6 3
      client/CAdvmapInterface.h
  3. 11 20
      client/CMT.cpp
  4. 0 1
      client/CMessage.cpp
  5. 69 52
      client/mapHandler.cpp

+ 43 - 33
client/CAdvmapInterface.cpp

@@ -1781,20 +1781,31 @@ void CAdvMapInt::endingTurn()
 	LOCPLINT->cb->endTurn();
 }
 
-void CAdvMapInt::tileLClicked(const int3 &mp)
+const CGObjectInstance* CAdvMapInt::getBlockingObject(const int3 &mapPos)
 {
-	if(!LOCPLINT->cb->isVisible(mp) || !LOCPLINT->makingTurn)
-		return;
+	std::vector < const CGObjectInstance * > bobjs = LOCPLINT->cb->getBlockingObjs(mapPos);  //blocking objects at tile
+
+	if (bobjs.empty())
+		return nullptr;
 
+	if (bobjs.back()->ID == GameConstants::HEROI_TYPE)
+		return bobjs.back();
+	else
+		return bobjs.front();
+}
+
+void CAdvMapInt::tileLClicked(const int3 &mapPos)
+{
+	if(!LOCPLINT->cb->isVisible(mapPos) || !LOCPLINT->makingTurn)
+		return;
 
-	std::vector < const CGObjectInstance * > bobjs = LOCPLINT->cb->getBlockingObjs(mp),  //blocking objects at tile
-		vobjs = LOCPLINT->cb->getVisitableObjs(mp); //visitable objects
-	const TerrainTile *tile = LOCPLINT->cb->getTile(mp);
-	const CGObjectInstance *topBlocking = bobjs.size() ? bobjs.back() : NULL;
+	std::vector < const CGObjectInstance * > bobjs = LOCPLINT->cb->getBlockingObjs(mapPos);//blocking objects at tile
+	const TerrainTile *tile = LOCPLINT->cb->getTile(mapPos);
 
+	const CGObjectInstance *topBlocking = getBlockingObject(mapPos);
 
 	int3 selPos = selection->getSightCenter();
-	if(spellBeingCasted && isInScreenRange(selPos, mp))
+	if(spellBeingCasted && isInScreenRange(selPos, mapPos))
 	{
 		const TerrainTile *heroTile = LOCPLINT->cb->getTile(selPos);
 
@@ -1802,11 +1813,11 @@ void CAdvMapInt::tileLClicked(const int3 &mp)
 		{
 		case Spells::SCUTTLE_BOAT: //Scuttle Boat
 			if(topBlocking && topBlocking->ID == 8)
-				leaveCastingMode(true, mp);
+				leaveCastingMode(true, mapPos);
 			break;
 		case Spells::DIMENSION_DOOR:
 			if(!tile || tile->isClear(heroTile))
-				leaveCastingMode(true, mp);
+				leaveCastingMode(true, mapPos);
 			break;
 		}
 		return;
@@ -1826,7 +1837,7 @@ void CAdvMapInt::tileLClicked(const int3 &mp)
 	}
 	else if(const CGHeroInstance * currentHero = curHero()) //hero is selected
 	{
-		const CGPathNode *pn = LOCPLINT->cb->getPathInfo(mp);
+		const CGPathNode *pn = LOCPLINT->cb->getPathInfo(mapPos);
 		if(currentHero == topBlocking) //clicked selected hero
 		{
 			LOCPLINT->openHeroWindow(currentHero);
@@ -1839,7 +1850,7 @@ void CAdvMapInt::tileLClicked(const int3 &mp)
 		}
 		else //still here? we need to move hero if we clicked end of already selected path or calculate a new path otherwise
 		{
-			if (terrain.currentPath  &&  terrain.currentPath->endPos() == mp)//we'll be moving
+			if (terrain.currentPath  &&  terrain.currentPath->endPos() == mapPos)//we'll be moving
 			{
 				LOCPLINT->moveHero(currentHero,*terrain.currentPath);
 				return;
@@ -1848,7 +1859,7 @@ void CAdvMapInt::tileLClicked(const int3 &mp)
 			{
 				CGPath &path = LOCPLINT->paths[currentHero];
 				terrain.currentPath = &path;
-				bool gotPath = LOCPLINT->cb->getPath2(mp, path); //try getting path, erase if failed
+				bool gotPath = LOCPLINT->cb->getPath2(mapPos, path); //try getting path, erase if failed
 				updateMoveHero(currentHero);
 				if (!gotPath)
 					LOCPLINT->eraseCurrentPathOf(currentHero);
@@ -1868,31 +1879,31 @@ void CAdvMapInt::tileLClicked(const int3 &mp)
 	}
 }
 
-void CAdvMapInt::tileHovered(const int3 &tile)
+void CAdvMapInt::tileHovered(const int3 &mapPos)
 {
-	if(!LOCPLINT->cb->isVisible(tile))
+	if(!LOCPLINT->cb->isVisible(mapPos))
 	{
 		CCS->curh->changeGraphic(0, 0);
 		statusbar.clear();
 		return;
 	}
+	const CGObjectInstance *objAtTile = getBlockingObject(mapPos);
 
-	std::vector<std::string> temp = LOCPLINT->cb->getObjDescriptions(tile);
-	if (temp.size())
+	//std::vector<std::string> temp = LOCPLINT->cb->getObjDescriptions(mapPos);
+	if (objAtTile)
 	{
-		boost::replace_all(temp.back(),"\n"," ");
-		statusbar.print(temp.back());
+		std::string text = objAtTile->getHoverText();
+		boost::replace_all(text,"\n"," ");
+		statusbar.print(text);
 	}
 	else
 	{
 		std::string hlp;
-		CGI->mh->getTerrainDescr(tile, hlp, false);
+		CGI->mh->getTerrainDescr(mapPos, hlp, false);
 		statusbar.print(hlp);
 	}
 
-	const CGPathNode *pnode = LOCPLINT->cb->getPathInfo(tile);
-	std::vector<const CGObjectInstance *> objs = LOCPLINT->cb->getBlockingObjs(tile);
-	const CGObjectInstance *objAtTile = objs.size() ? objs.back() : NULL;
+	const CGPathNode *pnode = LOCPLINT->cb->getPathInfo(mapPos);
 	bool accessible  =  pnode->turns < 255;
 
 	int turns = pnode->turns;
@@ -1913,9 +1924,9 @@ void CAdvMapInt::tileHovered(const int3 &tile)
 			return;
 		case Spells::DIMENSION_DOOR:
 			{
-				const TerrainTile *t = LOCPLINT->cb->getTile(tile, false);
+				const TerrainTile *t = LOCPLINT->cb->getTile(mapPos, false);
 				int3 hpos = selection->getSightCenter();
-				if((!t  ||  t->isClear(LOCPLINT->cb->getTile(hpos)))   &&   isInScreenRange(hpos, tile))
+				if((!t  ||  t->isClear(LOCPLINT->cb->getTile(hpos)))   &&   isInScreenRange(hpos, mapPos))
 					CCS->curh->changeGraphic(0, 41);
 				else
 					CCS->curh->changeGraphic(0, 0);
@@ -1924,7 +1935,7 @@ void CAdvMapInt::tileHovered(const int3 &tile)
 		}
 	}
 
-	const bool guardingCreature = CGI->mh->map->isInTheMap(LOCPLINT->cb->guardingCreaturePosition(tile));
+	const bool guardingCreature = CGI->mh->map->isInTheMap(LOCPLINT->cb->guardingCreaturePosition(mapPos));
 
 	if(selection->ID == GameConstants::TOWNI_TYPE)
 	{
@@ -2062,34 +2073,33 @@ void CAdvMapInt::tileHovered(const int3 &tile)
 	}
 }
 
-void CAdvMapInt::tileRClicked(const int3 &mp)
+void CAdvMapInt::tileRClicked(const int3 &mapPos)
 {
 	if(spellBeingCasted)
 	{
 		leaveCastingMode();
 		return;
 	}
-	if(!LOCPLINT->cb->isVisible(mp))
+	if(!LOCPLINT->cb->isVisible(mapPos))
 	{
 		CRClickPopup::createAndPush(VLC->generaltexth->allTexts[61]); //Uncharted Territory
 		return;
 	}
 
-	std::vector < const CGObjectInstance * > objs = LOCPLINT->cb->getBlockingObjs(mp);
-	if(!objs.size())
+	const CGObjectInstance * obj = getBlockingObject(mapPos);
+	if(!obj)
 	{
 		// Bare or undiscovered terrain
-		const TerrainTile * tile = LOCPLINT->cb->getTile(mp);
+		const TerrainTile * tile = LOCPLINT->cb->getTile(mapPos);
 		if (tile)
 		{
 			std::string hlp;
-			CGI->mh->getTerrainDescr(mp, hlp, true);
+			CGI->mh->getTerrainDescr(mapPos, hlp, true);
 			CRClickPopup::createAndPush(hlp);
 		}
 		return;
 	}
 
-	const CGObjectInstance * obj = objs.back();
 	CRClickPopup::createAndPush(obj, GH.current->motion, CENTER);
 }
 

+ 6 - 3
client/CAdvmapInterface.h

@@ -176,6 +176,9 @@ public:
 /// can get to the towns and heroes. 
 class CAdvMapInt : public CIntObject
 {
+	//get top selectable object at tile
+	const CGObjectInstance *getBlockingObject(const int3 &tile);
+
 public:
 	CAdvMapInt();
 	~CAdvMapInt();
@@ -259,9 +262,9 @@ public:
 	void aiTurnStarted();
 
 	void adjustActiveness(bool aiTurnStart); //should be called everytime at AI/human turn transition; blocks GUI during AI turn
-	void tileLClicked(const int3 &mp);
-	void tileHovered(const int3 &tile);
-	void tileRClicked(const int3 &mp);
+	void tileLClicked(const int3 &mapPos);
+	void tileHovered(const int3 &mapPos);
+	void tileRClicked(const int3 &mapPos);
 	void enterCastingMode(const CSpell * sp);
 	void leaveCastingMode(bool cast = false, int3 dest = int3(-1, -1, -1));
 	const CGHeroInstance * curHero() const;

+ 11 - 20
client/CMT.cpp

@@ -402,12 +402,6 @@ void processCommand(const std::string &message)
 		readed >> fname;
 		client->save(fname);
 	}
-	//else if(cn=="list")
-	//{
-	//	if(CPG)
-	//		for(int i = 0; i < CPG->ourScenSel->mapsel.ourGames.size(); i++)
-	//			tlog0 << i << ".\t" << CPG->ourScenSel->mapsel.ourGames[i]->filename << std::endl;
-	//}
 	else if(cn=="load")
 	{
 		// TODO: this code should end the running game and manage to call startGame instead
@@ -415,13 +409,6 @@ void processCommand(const std::string &message)
 		readed >> fname;
 		client->loadGame(fname);
 	}
-	//else if(cn=="ln")
-	//{
-	//	int num;
-	//	readed >> num;
-	//	std::string &name = CPG->ourScenSel->mapsel.ourGames[num]->filename;
-	//	client->load(name.substr(0, name.size()-6));
-	//}
 	else if(cn=="resolution" || cn == "r")
 	{
 		if(LOCPLINT)
@@ -531,15 +518,19 @@ void processCommand(const std::string &message)
 					if(const CArtifactInstance *a = h->getArt(id2))
 						tlog4 << a->nodeName();
 		}
-		else if (what == "anim" )
-		{
-			CAnimation::getAnimInfo();
-		}
 	}
-	else if (cn == "switchCreWin" )
+	else if (cn == "set")
 	{
-		Settings window = settings.write["general"]["classicCreatureWindow"];
-		window->Bool() = !window->Bool();
+		std::string what, value;
+		readed >> what;
+
+		Settings conf = settings.write["session"][what];
+
+		readed >> value;
+		if (value == "on")
+			conf->Bool() = true;
+		else if (value == "off")
+			conf->Bool() = false;
 	}
 	else if(cn == "sinfo")
 	{

+ 0 - 1
client/CMessage.cpp

@@ -566,7 +566,6 @@ ComponentResolved::~ComponentResolved()
 
 void ComponentResolved::showAll(SDL_Surface *to)
 {
-	tlog0 << "Blitting at "<< pos.x << " " << pos.y << "\n";
 	int fontHeight;
 	if (graphics->fontsTrueType[FONT_SMALL])
 		fontHeight = TTF_FontHeight(graphics->fontsTrueType[FONT_SMALL]);

+ 69 - 52
client/mapHandler.cpp

@@ -99,7 +99,7 @@ void CMapHandler::prepareFOWDefs()
 	graphics->FoWpartialHide = CDefHandler::giveDef("TSHRE.DEF");
 
 	//adding necessary rotations
-	static const int missRot [] = {22, 15, 2, 13, 12, 16, 18, 17, 20, 19, 7, 24, 26, 25, 30, 32, 27, 28};
+	static const int missRot [] = {22, 15, 2, 13, 12, 16, 28, 17, 20, 19, 7, 24, 26, 25, 30, 32, 27};
 
 	Cimage nw;
 	for(int g=0; g<ARRAY_COUNT(missRot); ++g)
@@ -753,43 +753,42 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
 	}
 	// borders printed
 
-#ifdef MARK_GRID_POSITIONS
 	// print grid
-	// TODO: This option should be activated by the console.
-	srx = srx_init;
-
-	for (int bx = 0; bx < dx; bx++, srx+=32)
+	if (settings["session"]["showGrid"].Bool())
 	{
-		sry = sry_init;
+		srx = srx_init;
 
-		for (int by = 0; by<dy; by++, sry+=32)
+		for (int bx = 0; bx < dx; bx++, srx+=32)
 		{
-			SDL_Rect sr;
+			sry = sry_init;
 
-			sr.x=srx;
-			sr.y=sry;
-			sr.h=sr.w=32;
-
-			const int3 color(0x555555, 0x555555, 0x555555);
-
-			if (sr.y >= extRect->y &&
-				sr.y < extRect->y+extRect->h)
-				for(int i=0;i<sr.w;i++)
-					if (sr.x+i >= extRect->x &&
-						sr.x+i < extRect->x+extRect->w)
-						CSDL_Ext::SDL_PutPixelWithoutRefresh(extSurf,sr.x+i,sr.y,color.x,color.y,color.z);
-
-			if (sr.x >= extRect->x &&
-				sr.x < extRect->x+extRect->w)
-				for(int i=0; i<sr.h;i++)
-					if (sr.y+i >= extRect->y &&
-						sr.y+i < extRect->y+extRect->h)
-						CSDL_Ext::SDL_PutPixelWithoutRefresh(extSurf,sr.x,sr.y+i,color.x,color.y,color.z);
+			for (int by = 0; by<dy; by++, sry+=32)
+			{
+				SDL_Rect sr;
+
+				sr.x=srx;
+				sr.y=sry;
+				sr.h=sr.w=32;
+
+				const int3 color(0x555555, 0x555555, 0x555555);
+
+				if (sr.y >= extRect->y &&
+					sr.y < extRect->y+extRect->h)
+					for(int i=0;i<sr.w;i++)
+						if (sr.x+i >= extRect->x &&
+							sr.x+i < extRect->x+extRect->w)
+							CSDL_Ext::SDL_PutPixelWithoutRefresh(extSurf,sr.x+i,sr.y,color.x,color.y,color.z);
+
+				if (sr.x >= extRect->x &&
+					sr.x < extRect->x+extRect->w)
+					for(int i=0; i<sr.h;i++)
+						if (sr.y+i >= extRect->y &&
+							sr.y+i < extRect->y+extRect->h)
+							CSDL_Ext::SDL_PutPixelWithoutRefresh(extSurf,sr.x,sr.y+i,color.x,color.y,color.z);
+			}
 		}
 	}
-
-	// grid	
-#endif
+	// grid
 
 	//applying sepia / gray effect
 	if(puzzleMode)
@@ -803,27 +802,45 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
 
 std::pair<SDL_Surface *, bool> CMapHandler::getVisBitmap( const int3 & pos, const std::vector< std::vector< std::vector<ui8> > > & visibilityMap ) const
 {
-	static const int visBitmaps[256] = {-1, 34, -1, 4, 22, 22, 4, 4, 36, 36, 38, 38, 47, 47, 38, 38, 3, 25, 12, 12, 3, 25, 12, 12,
-		9, 9, 6, 6, 9, 9, 6, 6, 35, 34, 4, 4, 22, 22, 4, 4, 36, 36, 38, 38, 47, 47, 38, 38, 26, 49, 28, 28, 26, 49, 28,
-		28, 9, 9, 6, 6, 9, 9, 6, 6, -3, 0, -3, 4, 0, 0, 4, 4, 37, 37, 7, 7, 50, 50, 7, 7, 13, 27, 44, 44, 13, 27, 44,
-		44, 8,8, 10, 10, 8, 8, 10, 10, 0, 0, 4, 4, 0, 0, 4, 4, 37, 37, 7, 7, 50, 50, 7, 7, 13, 27, 44, 44, 13, 27, 44,
-		44, 8, 8, 10, 10, 8, 8, 10, 10, 15, 15, 4, 4, 22, 22, 4, 4, 46, 46, 51, 51, 32, 32, 51, 51, 2, 25, 12, 12, 2,
-		25, 12, 12, 9, 9, 6, 6, 9, 9, 6, 6, 15, 15, 4, 4, 22, 22, 4, 4, 46, 46, 51, 51, 32, 32, 51, 51, 26, 49, 28, 28,
-		26, 49, 28, 28, 9, 9, 6, 6, 9, 9, 6, 6, 0, 0, 4, 4, 0, 0, 4, 4, 37, 37, 7, 7, 50, 50, 7, 7, 13, 27, 44, 44, 13,
-		27, 44, 44, 8, 8, 10, 10, 8, 8, 10, 10, 0, 0, 4, 4, 0, 0, 4, 4, 37, 37, 7, 7, 50, 50, 7, 7, 13, 27, 44, 44, 13,
-		27, 44, 44, 8, 8, 10, 10, 8, 8, 10, 10};
-
-
-							//is tile visible. arrangement: (like num keyboard)
-	bool d7 = (pos.x>0 && pos.y>0) ? visibilityMap[pos.x-1][pos.y-1][pos.z] : 0,		//789
-		d8 = (pos.y>0) ? visibilityMap[pos.x][pos.y-1][pos.z] : 0,					//456
-		d9 = (pos.y>0 && pos.x<sizes.x-1) ? visibilityMap[pos.x+1][pos.y-1][pos.z] : 0,	//123
-		d4 = (pos.x>0) ? visibilityMap[pos.x-1][pos.y][pos.z] : 0,
-		//d5 = visibilityMap[pos.x][y][pos.z], //TODO use me - OMFG
-		d6 = (pos.x<sizes.x-1) ? visibilityMap[pos.x+1][pos.y][pos.z] : 0,
-		d1 = (pos.x>0 && pos.y<sizes.y-1) ? visibilityMap[pos.x-1][pos.y+1][pos.z] : 0,
-		d2 = (pos.y<sizes.y-1) ? visibilityMap[pos.x][pos.y+1][pos.z] : 0,
-		d3 = (pos.x<sizes.x-1 && pos.y<sizes.y-1) ? visibilityMap[pos.x+1][pos.y+1][pos.z] : 0;
+	//NOTE: some images have unused in VCMI pair (same blockmap but a bit different look)
+	// 0-1, 2-3, 4-5, 11-13, 13-14
+	static const int visBitmaps[256] = {
+		-1,  34,   4,   4,  22,  23,   4,   4,  36,  36,  38,  38,  47,  47,  38,  38, //16
+		 3,  25,  12,  12,   3,  25,  12,  12,   9,   9,   6,   6,   9,   9,   6,   6, //32
+		35,  39,  48,  48,  41,  43,  48,  48,  36,  36,  38,  38,  47,  47,  38,  38, //48
+		26,  49,  28,  28,  26,  49,  28,  28,   9,   9,   6,   6,   9,   9,   6,   6, //64
+		 0,  45,  29,  29,  24,  33,  29,  29,  37,  37,   7,   7,  50,  50,   7,   7, //80
+		13,  27,  44,  44,  13,  27,  44,  44,   8,   8,  10,  10,   8,   8,  10,  10, //96
+		 0,  45,  29,  29,  24,  33,  29,  29,  37,  37,   7,   7,  50,  50,   7,   7, //112
+		13,  27,  44,  44,  13,  27,  44,  44,   8,   8,  10,  10,   8,   8,  10,  10, //128
+		15,  17,  30,  30,  16,  19,  30,  30,  46,  46,  40,  40,  32,  32,  40,  40, //144
+		 2,  25,  12,  12,   2,  25,  12,  12,   9,   9,   6,   6,   9,   9,   6,   6, //160
+		18,  42,  31,  31,  20,  21,  31,  31,  46,  46,  40,  40,  32,  32,  40,  40, //176
+		26,  49,  28,  28,  26,  49,  28,  28,   9,   9,   6,   6,   9,   9,   6,   6, //192
+		 0,  45,  29,  29,  24,  33,  29,  29,  37,  37,   7,   7,  50,  50,   7,   7, //208
+		13,  27,  44,  44,  13,  27,  44,  44,   8,   8,  10,  10,   8,   8,  10,  10, //224
+		 0,  45,  29,  29,  24,  33,  29,  29,  37,  37,   7,   7,  50,  50,   7,   7, //240
+		13,  27,  44,  44,  13,  27,  44,  44,   8,   8,  10,  10,   8,   8,  10,  10  //256
+	};
+
+	auto getTile = [&](int dx, int dy)
+	{
+		if ( dx + pos.x < 0 || dx + pos.x >= sizes.x
+		  || dy + pos.y < 0 || dy + pos.y >= sizes.y)
+			return false;
+		return bool(visibilityMap[dx+pos.x][dy+pos.y][pos.z]);
+	};
+
+	//is tile visible. arrangement: (like num keyboard)
+	bool d7 = getTile(-1, -1), //789
+		 d8 = getTile( 0, -1), //456
+		 d9 = getTile(+1, -1), //123
+		 d4 = getTile(-1, 0),
+
+		 d6 = getTile(+1, 0),
+		 d1 = getTile(-1, +1),
+		 d2 = getTile( 0, +1),
+		 d3 = getTile(+1, +1);
 
 	int retBitmapID = visBitmaps[d1 + d2 * 2 + d3 * 4 + d4 * 8 + d6 * 16 + d7 * 32 + d8 * 64 + d9 * 128]; // >=0 -> partial hide, <0 - full hide
 	if (retBitmapID < 0)