2
0
Эх сурвалжийг харах

* next part of thieves' guild window

mateuszb 15 жил өмнө
parent
commit
f5a719c2da

+ 17 - 0
CCallback.cpp

@@ -135,6 +135,23 @@ int CCallback::estimateSpellDamage(const CSpell * sp) const
 	return gs->curB->calculateSpellDmg(sp, ourHero, NULL);
 }
 
+void CCallback::getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj)
+{
+	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
+
+	if(obj == NULL)
+		return;
+
+	if(obj->ID == TOWNI_TYPE) //it is a town
+	{
+		gs->obtainPlayersStats(thi, gs->players[player].towns.size());
+	}
+	else if(obj->ID == 97) //Den of Thieves
+	{
+		gs->obtainPlayersStats(thi, 20);
+	}
+}
+
 int CCallback::howManyTowns() const
 {
 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);

+ 2 - 0
CCallback.h

@@ -132,6 +132,7 @@ public:
 	virtual const CMapHeader * getMapHeader()const =0;
 	virtual int getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const =0; //when called during battle, takes into account creatures' spell cost reduction
 	virtual int estimateSpellDamage(const CSpell * sp) const =0; //estimates damage of given spell; returns 0 if spell causes no dmg
+	virtual void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj)=0; //get thieves' guild info obtainable while visiting given object
 
 	//hero
 	virtual int howManyHeroes(bool includeGarrisoned = true)const =0;
@@ -264,6 +265,7 @@ public:
 	const CMapHeader * getMapHeader()const ;
 	int getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const; //when called during battle, takes into account creatures' spell cost reduction
 	int estimateSpellDamage(const CSpell * sp) const; //estimates damage of given spell; returns 0 if spell causes no dmg
+	void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object
 
 	std::vector < const CGObjectInstance * > getBlockingObjs(int3 pos) const;
 	std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos) const;

+ 24 - 6
client/GUIClasses.cpp

@@ -3098,7 +3098,7 @@ void CTavernWindow::recruitb()
 
 void CTavernWindow::thievesguildb()
 {
-	GH.pushInt(new CThievesGuildWindow());
+	GH.pushInt( new CThievesGuildWindow(LOCPLINT->castleInt->town) );
 }
 
 CTavernWindow::~CTavernWindow()
@@ -4774,8 +4774,12 @@ void CThievesGuildWindow::bexitf()
 	GH.popIntTotally(this);
 }
 
-CThievesGuildWindow::CThievesGuildWindow()
+CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner)
+	:owner(_owner)
 {
+	SThievesGuildInfo tgi; //info to be displayed
+	LOCPLINT->cb->getThievesGuildInfo(tgi, owner);
+
 	pos = Rect( (conf.cc.resx - 800) / 2, (conf.cc.resy - 600) / 2, 800, 600 );
 
 	//loading backround and converting to more bpp form
@@ -4794,15 +4798,15 @@ CThievesGuildWindow::CThievesGuildWindow()
 	for(int g=0; g<12; ++g)
 	{
 		int y;
-		if(g == 9)
+		if(g == 9) //best hero
 		{
 			y = 400;
 		}
-		else if(g == 10)
+		else if(g == 10) //personality
 		{
 			y = 460;
 		}
-		else if(g == 11)
+		else if(g == 11) //best monster
 		{
 			y = 510;
 		}
@@ -4813,10 +4817,24 @@ CThievesGuildWindow::CThievesGuildWindow()
 		printAtMiddle(CGI->generaltexth->jktexts[24+g], 135, y, FONT_MEDIUM, tytulowy, background);
 	}
 
-	for(int g=0; g<8; ++g)
+	CDefHandler * strips = CDefHandler::giveDef("PRSTRIPS.DEF");
+
+	static const std::string colorToBox[] = {"PRRED.BMP", "PRBLUE.BMP", "PRTAN.BMP", "PRGREEN.BMP", "PRORANGE.BMP", "PRPURPLE.BMP", "PRTEAL.BMP", "PRPINK.BMP"};
+
+	for(int g=0; g<tgi.playerColors.size(); ++g)
 	{
+		if(g > 0)
+		{
+			blitAt(strips->ourImages[g-1].bitmap, 250 + 66*g, 7, background);
+		}
 		printAtMiddle(CGI->generaltexth->jktexts[16+g], 283 + 66*g, 20, FONT_MEDIUM, tytulowy, background);
+		SDL_Surface * box = BitmapHandler::loadBitmap(colorToBox[tgi.playerColors[g]]);
+		blitAt(box, 253 + 66*g, 334, background);
+		SDL_FreeSurface(box);
 	}
+
+	delete strips;
+
 }
 
 CThievesGuildWindow::~CThievesGuildWindow()

+ 3 - 1
client/GUIClasses.h

@@ -829,6 +829,8 @@ class CHillFortWindow : public CIntObject //garrison dialog? shop?
 
 class CThievesGuildWindow : public CIntObject
 {
+	const CGObjectInstance * owner;
+
 	CStatusBar * statusBar;
 	AdventureMapButton * exitb;
 	SDL_Surface * background;
@@ -841,7 +843,7 @@ public:
 
 	void bexitf();
 
-	CThievesGuildWindow();
+	CThievesGuildWindow(const CGObjectInstance * _owner);
 	~CThievesGuildWindow();
 };
 

+ 101 - 0
lib/CGameState.cpp

@@ -3089,6 +3089,107 @@ bool CGameState::checkForStandardLoss( ui8 player ) const
 	return !p.heroes.size() && !p.towns.size();
 }
 
+void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
+{
+	struct HLP
+	{
+		typedef std::pair< ui8, si64 > TStat;
+		//converts [<player's color, value>] to vec[place] -> platers
+		static std::vector< std::list< ui8 > > getRank( std::vector<TStat> stats )
+		{
+			std::sort(stats.begin(), stats.end(), HLP());
+
+			//put first element
+			std::vector< std::list<ui8> > ret;
+			std::list<ui8> tmp;
+			tmp.push_back( stats[0].first );
+			ret.push_back( tmp );
+
+			//the rest of elements
+			for(int g=1; g<stats.size(); ++g)
+			{
+				if(stats[g].second == stats[g-1].second)
+				{
+					(ret.end()-1)->push_back( stats[g].first );
+				}
+				else
+				{
+					//create next occupied rank
+					std::list<ui8> tmp;
+					tmp.push_back(stats[g].first);
+					ret.push_back(tmp);
+				}
+			}
+
+			return ret;
+		}
+
+		bool operator()(const TStat & a, const TStat & b) const
+		{
+			return a.second > b.second;
+		}
+	};
+
+#define FILL_FIELD(FIELD, VAL_GETTER) \
+	{ \
+		std::vector< std::pair< ui8, si64 > > stats; \
+		for(std::map<ui8, PlayerState>::const_iterator g = players.begin(); g != players.end(); ++g) \
+		{ \
+			if(g->second.color == 255) \
+				continue; \
+			std::pair< ui8, si64 > stat; \
+			stat.first = g->second.color; \
+			stat.second = VAL_GETTER; \
+			stats.push_back(stat); \
+		} \
+		tgi.FIELD = HLP::getRank(stats); \
+	}
+
+	for(std::map<ui8, PlayerState>::const_iterator g = players.begin(); g != players.end(); ++g)
+	{
+		if(g->second.color != 255)
+			tgi.playerColors.push_back(g->second.color);
+	}
+	
+	if(level >= 1) //num of towns & num of heroes
+	{
+		//num of towns
+		FILL_FIELD(numOfTowns, g->second.towns.size())
+		//num of heroes
+		FILL_FIELD(numOfHeroes, g->second.heroes.size())
+	}
+	if(level >= 2) //gold
+	{
+		FILL_FIELD(gold, g->second.resources[6])
+	}
+	if(level >= 2) //wood & ore
+	{
+		FILL_FIELD(woodOre, g->second.resources[0] + g->second.resources[1])
+	}
+	if(level >= 3) //mercury, sulfur, crystal, gems
+	{
+		FILL_FIELD(woodOre, g->second.resources[2] + g->second.resources[3] + g->second.resources[4] + g->second.resources[5])
+	}
+	if(level >= 4) //obelisks found
+	{
+		//TODO
+	}
+	if(level >= 5) //artifacts
+	{
+		//TODO
+	}
+	if(level >= 6) //army strength
+	{
+		//TODO
+	}
+	if(level >= 7) //income
+	{
+		//TODO
+	}
+
+#undef FILL_FIELD
+}
+
 int CGameState::lossCheck( ui8 player ) const
 {
 	const PlayerState *p = getPlayer(player);

+ 17 - 0
lib/CGameState.h

@@ -9,6 +9,7 @@
 #endif
 #include <set>
 #include <vector>
+#include <list>
 #include "StackFeature.h"
 #ifdef _WIN32
 #include <tchar.h>
@@ -57,6 +58,21 @@ namespace boost
 	class shared_mutex;
 }
 
+struct DLL_EXPORT SThievesGuildInfo
+{
+	std::vector<ui8> playerColors; //colors of players that are in-game
+
+	std::vector< std::list< ui8 > > numOfTowns, numOfHeroes, gold, woodOre, mercSulfCrystGems, obelisks, artifacts, army, income; // [place] -> [colours of players]
+
+	//TODO: best hero, personality, best monster
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & playerColors & numOfTowns & numOfHeroes & gold & woodOre & mercSulfCrystGems & obelisks & artifacts & army & income;
+	}
+
+};
+
 struct DLL_EXPORT PlayerState
 {
 public:
@@ -391,6 +407,7 @@ public:
 	int lossCheck(ui8 player) const; //checks if given player is loser;  -1 if std loss, 1 if special, 0 else
 	ui8 checkForStandardWin() const; //returns color of player that accomplished standard victory conditions or 255 if no winner
 	bool checkForStandardLoss(ui8 player) const; //checks if given player lost the game
+	void obtainPlayersStats(SThievesGuildInfo & tgi, int level); //fills tgi with info about other players that is available at given level of thieves' guild
 
 	bool isVisible(int3 pos, int player);
 	bool isVisible(const CGObjectInstance *obj, int player);