浏览代码

* another part of thieves' guild
* den of thieves

mateuszb 15 年之前
父节点
当前提交
5fbde49bfb

+ 1 - 0
client/Client.h

@@ -81,6 +81,7 @@ public:
 	void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback){};
 	ui32 showBlockingDialog(BlockingDialog *iw){return 0;}; //synchronous version of above
 	void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function<void()> &cb){};
+	void showThievesGuildWindow(int requestingObjId){};
 	void giveResource(int player, int which, int val){};
 	void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures) {};
 	void takeCreatures (int objid, CCreatureSet creatures){};

+ 9 - 0
client/GUIClasses.cpp

@@ -4885,6 +4885,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner)
 	statusBar = new CStatusBar(pos.x + 3, pos.y + 555, "TStatBar.bmp", 742);
 
 	resdatabar = new CMinorResDataBar();
+	resdatabar->pos.x += pos.x - 3;
 	resdatabar->pos.y += pos.y;
 
 	static std::vector< std::list< ui8 > > SThievesGuildInfo::* fields[] = { &SThievesGuildInfo::numOfTowns, &SThievesGuildInfo::numOfHeroes, &SThievesGuildInfo::gold,
@@ -4965,6 +4966,14 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner)
 		counter++;
 	}
 
+	//printing best creature
+	counter = 0;
+	for(std::map<ui8, si32>::const_iterator it = tgi.bestCreature.begin(); it !=  tgi.bestCreature.end(); ++it)
+	{
+		blitAt(graphics->bigImgs[it->second], 255 + 66 * counter, 479, background);
+		counter++;
+	}
+
 }
 
 CThievesGuildWindow::~CThievesGuildWindow()

+ 7 - 0
client/NetPacksClient.cpp

@@ -668,3 +668,10 @@ void TradeComponents::applyCl(CClient *cl)
 			tlog2 << "Shop type not supported! \n";
 	}
 }
+
+void SShowThievesGuildWindow::applyCl(CClient *cl)
+{
+	//displays Thieves' Guild window (when hero enters Den of Thieves)
+	const CGObjectInstance *obj = cl->getObj(requestingObject);
+	GH.pushInt( new CThievesGuildWindow(obj) );
+}

+ 6 - 0
hch/CObjectHandler.cpp

@@ -5450,3 +5450,9 @@ void CGRefugeeCamp::reset(ui32 val)
 	available[0] = new Component (Component::CREATURE, creid, 0, 0);
 	*/
 }
+
+
+void CGDenOfthieves::onHeroVisit (const CGHeroInstance * h) const
+{
+	cb->showThievesGuildWindow(id);
+}

+ 9 - 1
hch/CObjectHandler.h

@@ -308,7 +308,7 @@ public:
 	std::vector<std::pair<int,std::string> > getCurrentLuckModifiers(int stack=-1, bool town=false) const; //args as above
 	int getCurrentMorale(int stack=-1, bool town=false) const; //if stack - position of creature, if -1 then morale for hero is calculated; town - if bonuses from town (tavern) should be considered
 	std::vector<std::pair<int,std::string> > getCurrentMoraleModifiers(int stack=-1, bool town=false) const; //args as above
-	int getPrimSkillLevel(int id) const;
+	int getPrimSkillLevel(int id) const; //0-attack, 1-defence, 2-spell power, 3-knowledge
 	ui8 getSecSkillLevel(const int & ID) const; //0 - no skill
 	int maxMovePoints(bool onLand) const;
 
@@ -1061,18 +1061,26 @@ public:
 		h & available & chosen & bought & price;
 	}
 };
+
 class DLL_EXPORT CGArtMerchant : public CShop
 {
 public:
 	void reset (ui32 val);
 	void onHeroVisit (const CGHeroInstance * h) const {};
 };
+
 class DLL_EXPORT CGRefugeeCamp : public CShop
 {
 public:
 	void reset (ui32 val);
 	void onHeroVisit (const CGHeroInstance * h) const {};
 };
+
+class DLL_EXPORT CGDenOfthieves : public CGObjectInstance
+{
+	void onHeroVisit (const CGHeroInstance * h) const;
+};
+
 struct BankConfig
 {
 	BankConfig() {level = chance = upgradeChance = combatValue = value = rewardDifficulty = easiest = 0; };

+ 83 - 12
lib/CGameState.cpp

@@ -3131,6 +3131,31 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 		{
 			return a.second > b.second;
 		}
+
+		static const CGHeroInstance * findBestHero(CGameState * gs, int color)
+		{
+			//best hero will be that with highest exp
+			int best = 0;
+			for(int b=1; b<gs->players[color].heroes.size(); ++b)
+			{
+				if(gs->players[color].heroes[b]->exp > gs->players[color].heroes[best]->exp)
+				{
+					best = b;
+				}
+			}
+			return gs->players[color].heroes[best];
+		}
+
+		//calculates total number of artifacts that belong to given player
+		static int getNumberOfArts(const PlayerState * ps)
+		{
+			int ret = 0;
+			for(int g=0; g<ps->heroes.size(); ++g)
+			{
+				ret += ps->heroes[g]->artifacts.size() + ps->heroes[g]->artifWorn.size();
+			}
+			return ret;
+		}
 	};
 
 #define FILL_FIELD(FIELD, VAL_GETTER) \
@@ -3165,17 +3190,9 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 		{
 			if(g->second.color == 255)
 				continue;
-			//best hero will be that with highest exp
-			int best = 0;
-			for(int b=1; b<g->second.heroes.size(); ++b)
-			{
-				if(g->second.heroes[b]->exp > g->second.heroes[best]->exp)
-				{
-					best = b;
-				}
-			}
+			const CGHeroInstance * best = HLP::findBestHero(this, g->second.color);
 			SThievesGuildInfo::InfoAboutHero iah;
-			iah.portrait = g->second.heroes[best]->portrait;
+			iah.portrait = best->portrait;
 			for(int c=0; c<PRIMARY_SKILLS; ++c)
 			{
 				iah.primSkills[c] = -1; //mark as unknown
@@ -3193,7 +3210,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 	}
 	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])
+		FILL_FIELD(mercSulfCrystGems, g->second.resources[2] + g->second.resources[3] + g->second.resources[4] + g->second.resources[5])
 	}
 	if(level >= 4) //obelisks found
 	{
@@ -3201,7 +3218,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 	}
 	if(level >= 5) //artifacts
 	{
-		//TODO
+		FILL_FIELD(artifacts, HLP::getNumberOfArts(&g->second))
 	}
 	if(level >= 6) //army strength
 	{
@@ -3211,6 +3228,60 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 	{
 		//TODO
 	}
+	if(level >= 8) //best hero's stats
+	{
+		for(std::map<ui8, PlayerState>::const_iterator g = players.begin(); g != players.end(); ++g)
+		{
+			if(g->second.color == 255) //do nothing for neutral player
+				continue;
+			const CGHeroInstance * best = HLP::findBestHero(this, g->second.color);
+
+			for(int k=0; k<ARRAY_COUNT(tgi.colorToBestHero[g->second.color].primSkills); ++k)
+			{
+				//getting prim skills with all bonuses
+				tgi.colorToBestHero[g->second.color].primSkills[k] = best->getPrimSkillLevel(k);
+			}
+		}
+	}
+	if(level >= 9) //personality
+	{
+		for(std::map<ui8, PlayerState>::const_iterator g = players.begin(); g != players.end(); ++g)
+		{
+			if(g->second.color == 255) //do nothing for neutral player
+				continue;
+			if(g->second.human)
+			{
+				tgi.personality[g->second.color] = -1;
+			}
+			else //AI
+			{
+				tgi.personality[g->second.color] = map->players[g->second.serial].AITactic;
+			}
+			
+		}
+	}
+	if(level >= 10) //best creature
+	{
+		//best creatures belonging to player (highest AI value)
+		for(std::map<ui8, PlayerState>::const_iterator g = players.begin(); g != players.end(); ++g)
+		{
+			if(g->second.color == 255) //do nothing for neutral player
+				continue;
+			int bestCre = -1; //best creature's ID
+			for(int b=0; b<g->second.heroes.size(); ++b)
+			{
+				for(TSlots::const_iterator it = g->second.heroes[b]->army.slots.begin(); it != g->second.heroes[b]->army.slots.end(); ++it)
+				{
+					int toCmp = it->second.first; //ID of creature we should compare with the best one
+					if(bestCre == -1 || VLC->creh->creatures[bestCre].AIValue < VLC->creh->creatures[toCmp].AIValue)
+					{
+						bestCre = toCmp;
+					}
+				}
+			}
+			tgi.bestCreature[g->second.color] = bestCre;
+		}
+	}
 
 #undef FILL_FIELD
 }

+ 4 - 3
lib/CGameState.h

@@ -64,8 +64,6 @@ struct DLL_EXPORT SThievesGuildInfo
 
 	std::vector< std::list< ui8 > > numOfTowns, numOfHeroes, gold, woodOre, mercSulfCrystGems, obelisks, artifacts, army, income; // [place] -> [colours of players]
 
-	//TODO: personality, best monster
-
 	struct InfoAboutHero
 	{
 		ui32 portrait;
@@ -79,10 +77,13 @@ struct DLL_EXPORT SThievesGuildInfo
 
 	std::map<ui8, InfoAboutHero> colorToBestHero; //maps player's color to his best heros' 
 
+	std::map<ui8, si8> personality; // color to personality // -1 - human, AI -> (00 - random, 01 -  warrior, 02 - builder, 03 - explorer)
+	std::map<ui8, si32> bestCreature; // color to ID // id or -1 if not known
+
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & playerColors & numOfTowns & numOfHeroes & gold & woodOre & mercSulfCrystGems & obelisks & artifacts & army & income;
-		h & colorToBestHero;
+		h & colorToBestHero & personality & bestCreature;
 	}
 
 };

+ 1 - 0
lib/IGameCallback.h

@@ -77,6 +77,7 @@ public:
 	virtual void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback)=0;
 	virtual ui32 showBlockingDialog(BlockingDialog *iw) =0; //synchronous version of above //TODO:
 	virtual void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function<void()> &cb) =0; //cb will be called when player closes garrison window
+	virtual void showThievesGuildWindow(int requestingObjId) =0;
 	virtual void giveResource(int player, int which, int val)=0;
 	virtual void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures) =0;
 	virtual void takeCreatures (int objid, CCreatureSet creatures) =0;

+ 13 - 0
lib/NetPacks.h

@@ -1427,5 +1427,18 @@ struct CenterView : public CPackForClient//515
 	}
 };  
 
+struct SShowThievesGuildWindow : public CPackForClient //516
+{
+	SShowThievesGuildWindow(){CPackForClient::type = 516;};
+	void applyCl(CClient *cl);
+
+	si32 requestingObject;
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & requestingObject;
+	}
+};
+
 
 #endif //__NETPACKS_H__

+ 1 - 0
lib/RegisterTypes.cpp

@@ -123,6 +123,7 @@ void registerTypes2(Serializer &s)
 	s.template registerType<SetSelection>();
 	s.template registerType<PlayerMessage>();
 	s.template registerType<CenterView>();
+	s.template registerType<SShowThievesGuildWindow>();
 }
 
 template<typename Serializer> DLL_EXPORT

+ 12 - 4
lib/map.cpp

@@ -1724,7 +1724,7 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
 				shr->spell = bufor[i]; i+=4;
 				break;
 			}
-		case 6:
+		case 6: //pandora's box
 			{
 				CGPandoraBox *box = new CGPandoraBox();
 				nobj = box;
@@ -1787,7 +1787,7 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
 				i+=8;
 				break;
 			}
-		case 36:
+		case 36: //grail
 			{
 				grailPos = pos;
 				grailRadious = readNormalNr(bufor,i); i+=4;
@@ -1967,8 +1967,16 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
 				nobj = new CGMagicSpring();
 				break;
 			}
-		default:
-			nobj = new CGObjectInstance();
+		case 97: //den of thieves
+			{
+				nobj = new CGDenOfthieves();
+				break;
+			}
+		default: //any other object
+			{
+				nobj = new CGObjectInstance();
+				break;
+			}
 		} //end of main switch
 
 		nobj->pos = pos;

+ 7 - 0
server/CGameHandler.cpp

@@ -3458,6 +3458,13 @@ void CGameHandler::showGarrisonDialog( int upobj, int hid, bool removableUnits,
 	}
 }
 
+void CGameHandler::showThievesGuildWindow(int requestingObjId)
+{
+	SShowThievesGuildWindow sthg;
+	sthg.requestingObject = requestingObjId;
+	sendAndApply(&sthg);
+}
+
 bool CGameHandler::isAllowedExchange( int id1, int id2 )
 {
 	if(id1 == id2)

+ 1 - 0
server/CGameHandler.h

@@ -126,6 +126,7 @@ public:
 	void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback);
 	ui32 showBlockingDialog(BlockingDialog *iw); //synchronous version of above
 	void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function<void()> &cb);
+	void showThievesGuildWindow(int requestingObjId); //TODO: make something more general?
 	void giveResource(int player, int which, int val);
 	void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures);
 	void takeCreatures (int objid, CCreatureSet creatures);