Răsfoiți Sursa

Infowindows for enemy towns.

Michał W. Urbańczyk 16 ani în urmă
părinte
comite
fbd496b756
5 a modificat fișierele cu 143 adăugiri și 31 ștergeri
  1. 54 1
      CCallback.cpp
  2. 26 1
      CCallback.h
  3. 21 8
      client/CAdvmapInterface.cpp
  4. 40 21
      client/Graphics.cpp
  5. 2 0
      client/Graphics.h

+ 54 - 1
CCallback.cpp

@@ -135,6 +135,18 @@ const CGTownInstance * CCallback::getTownInfo(int val, bool mode) const //mode =
 	}
 	}
 	return NULL;
 	return NULL;
 }
 }
+
+bool CCallback::getTownInfo( const CGObjectInstance *town, InfoAboutTown &dest ) const
+{
+	const CGTownInstance *t = dynamic_cast<const CGTownInstance *>(town);
+	if(!t || !isVisible(t, player)) //it's not a town or it's not visible for layer
+		return false;
+
+	//TODO vision support, info about allies
+	dest.initFromTown(t, false);
+	return true;
+}
+
 int CCallback::howManyHeroes(bool includeGarrisoned) const
 int CCallback::howManyHeroes(bool includeGarrisoned) const
 {
 {
 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
@@ -292,7 +304,7 @@ bool CCallback::isVisible(int3 pos) const
 	return isVisible(pos,player);
 	return isVisible(pos,player);
 }
 }
 
 
-bool CCallback::isVisible( CGObjectInstance *obj, int Player ) const
+bool CCallback::isVisible( const CGObjectInstance *obj, int Player ) const
 {
 {
 	//object is visible when at least one blocked tile is visible
 	//object is visible when at least one blocked tile is visible
 	for(int fx=0; fx<8; ++fx)
 	for(int fx=0; fx<8; ++fx)
@@ -762,4 +774,45 @@ void InfoAboutHero::initFromHero( const CGHeroInstance *h, bool detailed )
 			i->second.second = CCreature::getQuantityID(i->second.second);
 			i->second.second = CCreature::getQuantityID(i->second.second);
 		}
 		}
 	}
 	}
+}
+
+InfoAboutTown::InfoAboutTown()
+{
+	tType = NULL;
+	details = NULL;
+	fortLevel = 0;
+	owner = -1;
+}
+
+InfoAboutTown::~InfoAboutTown()
+{
+	delete details;
+}
+
+void InfoAboutTown::initFromTown( const CGTownInstance *t, bool detailed )
+{
+	army = t->army;
+	built = t->builded;
+	fortLevel = t->fortLevel();
+	name = t->name;
+	tType = t->town;
+	owner = t->tempOwner;
+
+	if(detailed) 
+	{
+		//include details about hero
+		details = new Details;
+		details->goldIncome = t->dailyIncome();
+		details->customRes = vstd::contains(t->builtBuildings, 15);
+		details->hallLevel = t->hallLevel();
+		details->garrisonedHero = t->garrisonHero;
+	}
+	else
+	{
+		//hide info about hero stacks counts
+		for(std::map<si32,std::pair<ui32,si32> >::iterator i = army.slots.begin(); i != army.slots.end(); ++i)
+		{
+			i->second.second = 0;
+		}
+	}
 }
 }

+ 26 - 1
CCallback.h

@@ -57,6 +57,29 @@ struct InfoAboutHero
 	void initFromHero(const CGHeroInstance *h, bool detailed);
 	void initFromHero(const CGHeroInstance *h, bool detailed);
 };
 };
 
 
+struct InfoAboutTown
+{
+	struct Details
+	{
+		int hallLevel, goldIncome;
+		bool customRes;
+		bool garrisonedHero;
+
+	} *details;
+
+	char fortLevel; //0 - none
+	char owner;
+	std::string name;
+	CTown *tType;
+	bool built;
+
+	CCreatureSet army; //numbers of creatures are valid only if details
+
+	InfoAboutTown();
+	~InfoAboutTown();
+	void initFromTown(const CGTownInstance *t, bool detailed);
+};
+
 class ICallback
 class ICallback
 {
 {
 public:
 public:
@@ -108,6 +131,7 @@ public:
 	virtual int canBuildStructure(const CGTownInstance *t, int ID) =0;//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
 	virtual int canBuildStructure(const CGTownInstance *t, int ID) =0;//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
 	virtual bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret)=0;
 	virtual bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret)=0;
 	virtual bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const = 0;
 	virtual bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const = 0;
+	virtual bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const = 0;
 
 
 //battle
 //battle
 	virtual int battleGetBattlefieldType()=0; //   1. sand/shore   2. sand/mesas   3. dirt/birches   4. dirt/hills   5. dirt/pines   6. grass/hills   7. grass/pines   8. lava   9. magic plains   10. snow/mountains   11. snow/trees   12. subterranean   13. swamp/trees   14. fiery fields   15. rock lands   16. magic clouds   17. lucid pools   18. holy ground   19. clover field   20. evil fog   21. "favourable winds" text on magic plains background   22. cursed ground   23. rough   24. ship to ship   25. ship
 	virtual int battleGetBattlefieldType()=0; //   1. sand/shore   2. sand/mesas   3. dirt/birches   4. dirt/hills   5. dirt/pines   6. grass/hills   7. grass/pines   8. lava   9. magic plains   10. snow/mountains   11. snow/trees   12. subterranean   13. swamp/trees   14. fiery fields   15. rock lands   16. magic clouds   17. lucid pools   18. holy ground   19. clover field   20. evil fog   21. "favourable winds" text on magic plains background   22. cursed ground   23. rough   24. ship to ship   25. ship
@@ -145,7 +169,7 @@ private:
 	CGameState * gs;
 	CGameState * gs;
 	CClient *cl;
 	CClient *cl;
 	bool isVisible(int3 pos, int Player) const;
 	bool isVisible(int3 pos, int Player) const;
-	bool isVisible(CGObjectInstance *obj, int Player) const;
+	bool isVisible(const CGObjectInstance *obj, int Player) const;
 
 
 protected:
 protected:
 	int player;
 	int player;
@@ -203,6 +227,7 @@ public:
 	int canBuildStructure(const CGTownInstance *t, int ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
 	int canBuildStructure(const CGTownInstance *t, int ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
 	bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret);
 	bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret);
 	bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const;
 	bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const;
+	bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const;
 
 
 	//battle
 	//battle
 	int battleGetBattlefieldType(); //   1. sand/shore   2. sand/mesas   3. dirt/birches   4. dirt/hills   5. dirt/pines   6. grass/hills   7. grass/pines   8. lava   9. magic plains   10. snow/mountains   11. snow/trees   12. subterranean   13. swamp/trees   14. fiery fields   15. rock lands   16. magic clouds   17. lucid pools   18. holy ground   19. clover field   20. evil fog   21. "favourable winds" text on magic plains background   22. cursed ground   23. rough   24. ship to ship   25. ship
 	int battleGetBattlefieldType(); //   1. sand/shore   2. sand/mesas   3. dirt/birches   4. dirt/hills   5. dirt/pines   6. grass/hills   7. grass/pines   8. lava   9. magic plains   10. snow/mountains   11. snow/trees   12. subterranean   13. swamp/trees   14. fiery fields   15. rock lands   16. magic clouds   17. lucid pools   18. holy ground   19. clover field   20. evil fog   21. "favourable winds" text on magic plains background   22. cursed ground   23. rough   24. ship to ship   25. ship

+ 21 - 8
client/CAdvmapInterface.cpp

@@ -546,16 +546,29 @@ void CTerrainRect::clickRight(tribool down)
 		}
 		}
 	case TOWNI_TYPE:
 	case TOWNI_TYPE:
 		{
 		{
-			if(!vstd::contains(graphics->townWins,obj->id))
+			if(!vstd::contains(graphics->townWins,obj->id) || obj->tempOwner != LOCPLINT->playerID)
 			{
 			{
-				tlog3 << "Warning - no infowin for town " << obj->id << std::endl;
-				break;
+				InfoAboutTown iah;
+				if(LOCPLINT->cb->getTownInfo(obj, iah))
+				{
+					SDL_Surface *iwin = graphics->drawTownInfoWin(iah);
+					CInfoPopup * ip = new CInfoPopup(iwin, LOCPLINT->current->motion.x-iwin->w,
+						LOCPLINT->current->motion.y-iwin->h, true);
+					LOCPLINT->pushInt(ip);
+				}
+				else
+				{
+					tlog3 << "Warning - no infowin for town " << obj->id << std::endl;
+				}
+			}
+			else
+			{
+				CInfoPopup * ip = new CInfoPopup(graphics->townWins[obj->id],
+					LOCPLINT->current->motion.x-graphics->townWins[obj->id]->w,
+					LOCPLINT->current->motion.y-graphics->townWins[obj->id]->h,false
+					);
+				LOCPLINT->pushInt(ip);
 			}
 			}
-			CInfoPopup * ip = new CInfoPopup(graphics->townWins[obj->id],
-				LOCPLINT->current->motion.x-graphics->townWins[obj->id]->w,
-				LOCPLINT->current->motion.y-graphics->townWins[obj->id]->h,false
-				);
-			LOCPLINT->pushInt(ip);
 			break;
 			break;
 		}
 		}
 	default:
 	default:

+ 40 - 21
client/Graphics.cpp

@@ -15,6 +15,7 @@
 #include "../hch/CLodHandler.h"
 #include "../hch/CLodHandler.h"
 #include "../lib/VCMI_Lib.h"
 #include "../lib/VCMI_Lib.h"
 #include "../CCallback.h"
 #include "../CCallback.h"
+#include "../hch/CTownHandler.h"
 using namespace boost::assign;
 using namespace boost::assign;
 using namespace CSDL_Ext;
 using namespace CSDL_Ext;
 #ifdef min
 #ifdef min
@@ -87,37 +88,55 @@ SDL_Surface * Graphics::drawHeroInfoWin(const CGHeroInstance * curh)
 }
 }
 
 
 SDL_Surface * Graphics::drawTownInfoWin(const CGTownInstance * curh)
 SDL_Surface * Graphics::drawTownInfoWin(const CGTownInstance * curh)
+{
+	InfoAboutTown iah;
+	iah.initFromTown(curh, true);
+	return drawTownInfoWin(iah);
+}
+
+SDL_Surface * Graphics::drawTownInfoWin( const InfoAboutTown & curh )
 {
 {
 	char buf[10];
 	char buf[10];
-	blueToPlayersAdv(tInfo,curh->tempOwner);
+	blueToPlayersAdv(tInfo,curh.owner);
 	SDL_Surface * ret = SDL_DisplayFormat(tInfo);
 	SDL_Surface * ret = SDL_DisplayFormat(tInfo);
 	SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,0,255,255));
 	SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,0,255,255));
-	printAt(curh->name,75,15,GEOR13,zwykly,ret);
-
-	int pom = curh->fortLevel() - 1; if(pom<0) pom = 3;
-	blitAt(forts->ourImages[pom].bitmap,115,42,ret);
-	if((pom=curh->hallLevel())>=0)
-		blitAt(halls->ourImages[pom].bitmap,77,42,ret);
-	SDL_itoa(curh->dailyIncome(),buf,10);
-	printAtMiddle(buf,167,70,GEORM,zwykly,ret);
-	for (std::map<si32,std::pair<ui32,si32> >::const_iterator i=curh->army.slots.begin(); i!=curh->army.slots.end();i++)
+
+	printAt(curh.name,75,15,GEOR13,zwykly,ret); //name
+	int pom = curh.fortLevel - 1; if(pom<0) pom = 3; //fort pic id
+	blitAt(forts->ourImages[pom].bitmap,115,42,ret); //fort
+
+	for (std::map<si32,std::pair<ui32,si32> >::const_iterator i=curh.army.slots.begin(); i!=curh.army.slots.end();i++)
 	{
 	{
-		if(!i->second.second)
-			continue;
+		//if(!i->second.second)
+		//	continue;
 		blitAt(graphics->smallImgs[(*i).second.first],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret);
 		blitAt(graphics->smallImgs[(*i).second.first],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret);
-		SDL_itoa((*i).second.second,buf,10);
-		printAtMiddle(buf,slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+39,GEORM,zwykly,ret);
+		if(curh.details)
+		{
+			SDL_itoa((*i).second.second,buf,10);
+			printAtMiddle(buf,slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+39,GEORM,zwykly,ret);
+		}
 	}
 	}
 
 
 	//blit town icon
 	//blit town icon
-	pom = curh->subID*2;
-	if (!curh->hasFort())
+	pom = curh.tType->typeID*2;
+	if (!curh.fortLevel)
 		pom += F_NUMBER*2;
 		pom += F_NUMBER*2;
-	if(curh->builded >= MAX_BUILDING_PER_TURN)
+	if(curh.built)
 		pom++;
 		pom++;
-	if(curh->garrisonHero)
-		blitAt(graphics->heroInGarrison,158,87,ret);
 	blitAt(bigTownPic->ourImages[pom].bitmap,13,13,ret);
 	blitAt(bigTownPic->ourImages[pom].bitmap,13,13,ret);
+
+	if(curh.details)
+	{
+		//hall level icon
+		if((pom=curh.details->hallLevel) >= 0)
+			blitAt(halls->ourImages[pom].bitmap, 77, 42, ret);
+
+		SDL_itoa(curh.details->goldIncome, buf, 10); //gold income
+		printAtMiddle(buf, 167, 70, GEORM, zwykly, ret);
+		if(curh.details->garrisonedHero) //garrisoned hero icon
+			blitAt(graphics->heroInGarrison,158,87,ret);
+	}
+
 	return ret;
 	return ret;
 }
 }
 
 
@@ -516,11 +535,11 @@ void Graphics::blueToPlayersAdv(SDL_Surface * sur, int player)
 	if(sur->format->BitsPerPixel == 8)
 	if(sur->format->BitsPerPixel == 8)
 	{
 	{
 		SDL_Color *palette = NULL;
 		SDL_Color *palette = NULL;
-		if(player < PLAYER_LIMIT)
+		if(player < PLAYER_LIMIT && player >= 0)
 		{
 		{
 			palette = playerColorPalette + 32*player;
 			palette = playerColorPalette + 32*player;
 		}
 		}
-		else if(player == 255)
+		else if(player == 255 || player == -1)
 		{
 		{
 			palette = neutralColorPalette;
 			palette = neutralColorPalette;
 		}
 		}

+ 2 - 0
client/Graphics.h

@@ -22,6 +22,7 @@ class CDefHandler;
 class CHeroClass;
 class CHeroClass;
 struct SDL_Color;
 struct SDL_Color;
 struct InfoAboutHero;
 struct InfoAboutHero;
+struct InfoAboutTown;
 
 
 class Graphics
 class Graphics
 {
 {
@@ -77,6 +78,7 @@ public:
 	void loadHeroPortraits();
 	void loadHeroPortraits();
 	SDL_Surface * drawHeroInfoWin(const InfoAboutHero &curh);
 	SDL_Surface * drawHeroInfoWin(const InfoAboutHero &curh);
 	SDL_Surface * drawHeroInfoWin(const CGHeroInstance * curh);
 	SDL_Surface * drawHeroInfoWin(const CGHeroInstance * curh);
+	SDL_Surface * drawTownInfoWin(const InfoAboutTown & curh);
 	SDL_Surface * drawTownInfoWin(const CGTownInstance * curh);
 	SDL_Surface * drawTownInfoWin(const CGTownInstance * curh);
 	SDL_Surface * getPic(int ID, bool fort=true, bool builded=false); //returns small picture of town: ID=-1 - blank; -2 - border; -3 - random
 	SDL_Surface * getPic(int ID, bool fort=true, bool builded=false); //returns small picture of town: ID=-1 - blank; -2 - border; -3 - random
 	void blueToPlayersAdv(SDL_Surface * sur, int player); //replaces blue interface colour with a color of player
 	void blueToPlayersAdv(SDL_Surface * sur, int player); //replaces blue interface colour with a color of player