Parcourir la source

* player's serialID removed (save format broken, new game seems to work)
* building bonus (campaigns) supported

mateuszb il y a 15 ans
Parent
commit
54496ddee1

+ 2 - 3
AI/GeniusAI/CGeniusAI.cpp

@@ -451,7 +451,6 @@ void CGeniusAI::init(ICallback *CB)
 
 	human = false;
 	playerID = m_cb->getMyColor();
-	serialID = m_cb->getMySerial();
 	std::string info = std::string("GeniusAI initialized for player ") 
                    + boost::lexical_cast<std::string>(playerID);
 	m_battleLogic = NULL;
@@ -462,13 +461,13 @@ void CGeniusAI::init(ICallback *CB)
 void CGeniusAI::reportResources()
 {
 	cout << "Day " << m_cb->getDate() << ": ";
-	cout << "AI Player " <<m_cb->getMySerial()<< " with "
+	cout << "AI Player " <<m_cb->getMyColor()<< " with "
        <<  m_cb->howManyHeroes(true) << " heroes. " << endl;
 	cout << m_cb->getResourceAmount(0) << " wood. ";
 	cout << m_cb->getResourceAmount(1) << " mercury. ";
 	cout << m_cb->getResourceAmount(2) << " ore. ";
 	cout << m_cb->getResourceAmount(3) << " sulfur. ";
-	cout << m_cb->getResourceAmount(4) << " cristal. ";
+	cout << m_cb->getResourceAmount(4) << " crystal. ";
 	cout << m_cb->getResourceAmount(5) << " gems. ";
 	cout << m_cb->getResourceAmount(6) << " gold.";
 	cout << endl;

+ 5 - 5
CCallback.cpp

@@ -423,11 +423,11 @@ bool CCallback::dismissHero(const CGHeroInstance *hero)
 	return true;
 }
 
-int CCallback::getMySerial() const
-{	
-	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
-	return gs->players[player].serial;
-}
+// int CCallback::getMySerial() const
+// {	
+// 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
+// 	return gs->players[player].serial;
+// }
 
 bool CCallback::swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)
 {

+ 1 - 2
CCallback.h

@@ -110,7 +110,6 @@ public:
 	virtual int getResourceAmount(int type)const =0;
 	virtual bool isVisible(int3 pos)const =0;
 	virtual int getMyColor()const =0;
-	virtual int getMySerial()const =0;
 	virtual int getHeroSerial(const CGHeroInstance * hero)const =0;
 	virtual const StartInfo * getStartInfo()const =0;
 	virtual const CMapHeader * getMapHeader()const =0;
@@ -254,7 +253,7 @@ public:
 	bool isVisible(int3 pos) const;
 	int getMyColor() const;
 	int getHeroSerial(const CGHeroInstance * hero) const;
-	int getMySerial() const;
+	//int getMySerial() const;
 	const CCreatureSet* getGarrison(const CGObjectInstance *obj) const;
 	UpgradeInfo getUpgradeInfo(const CArmedInstance *obj, int stackPos) const;
 	const StartInfo * getStartInfo() const;

+ 1 - 1
CGameInterface.h

@@ -59,7 +59,7 @@ class CGameInterface
 {
 public:
 	bool human;
-	int playerID, serialID;
+	int playerID;
 	std::string dllName;
 
 	virtual ~CGameInterface() {};

+ 6 - 9
StartInfo.h

@@ -25,7 +25,6 @@ struct PlayerSettings
 	std::string heroName;
 	si8 bonus; //usees enum type Ebonus
 	ui8 color; //from 0 - 
-	ui8 serial;
 	ui8 handicap;//0-no, 1-mild, 2-severe
 	std::string name;
 	ui8 human;
@@ -37,7 +36,6 @@ struct PlayerSettings
 		h & heroName;
 		h & bonus;
 		h & color;
-		h & serial;
 		h & handicap;
 		h & name;
 		h & human;
@@ -55,25 +53,24 @@ struct StartInfo
 {
 	ui8 mode; //0 - new game; 1 - load game; 2 - campaign
 	ui8 difficulty; //0=easy; 4=impossible
-	std::vector<PlayerSettings> playerInfos; //serial indexed
+	std::map<int, PlayerSettings> playerInfos; //color indexed
 	ui8 turnTime; //in minutes, 0=unlimited
 	std::string mapname;
 	ui8 whichMapInCampaign; //used only for mode 2
 	ui8 choosenCampaignBonus; //used only for mode 2
 	PlayerSettings & getIthPlayersSettings(int no)
 	{
-		for(unsigned int i=0; i<playerInfos.size(); ++i)
-			if(playerInfos[i].color == no)
-				return playerInfos[i];
+		if(playerInfos.find(no) != playerInfos.end())
+			return playerInfos[no];
 		tlog1 << "Cannot find info about player " << no <<". Throwing...\n";
 		throw std::string("Cannot find info about player");
 	}
 
 	PlayerSettings *getPlayersSettings(const std::string &name)
 	{
-		for(unsigned int i=0; i<playerInfos.size(); ++i)
-			if(playerInfos[i].name == name)
-				return &playerInfos[i];
+		for(std::map<int, PlayerSettings>::iterator it=playerInfos.begin(); it != playerInfos.end(); ++it)
+			if(it->second.name == name)
+				return &it->second;
 
 		return NULL;
 	}

+ 3 - 2
client/CMT.cpp

@@ -614,9 +614,10 @@ void startGame(StartInfo * options)
 	GH.curInt =NULL;
 	if(gOnlyAI)
 	{
-		for (size_t i =0; i < options->playerInfos.size(); i++)
+		for(std::map<int, PlayerSettings>::iterator it = options->playerInfos.begin(); 
+			it != options->playerInfos.end(); ++it)
 		{
-			options->playerInfos[i].human = false;
+			it->second.human = false;
 		}
 	}
 

+ 3 - 4
client/CPlayerInterface.cpp

@@ -90,14 +90,13 @@ struct OCM_HLP_CGIN
 
 
 
-CPlayerInterface::CPlayerInterface(int Player, int serial)
+CPlayerInterface::CPlayerInterface(int Player)
 {
 	howManyPeople++;
 	GH.defActionsDef = 0;
 	LOCPLINT = this;
 	curAction = NULL;
 	playerID=Player;
-	serialID=serial;
 	human=true;
 	castleInt = NULL;
 	battleInt = NULL;
@@ -192,7 +191,7 @@ void CPlayerInterface::yourTurn()
 
 			makingTurn = true;
 			std::string msg = CGI->generaltexth->allTexts[13];
-			boost::replace_first(msg, "%s", cb->getStartInfo()->playerInfos[serialID].name);
+			boost::replace_first(msg, "%s", cb->getStartInfo()->playerInfos.find(playerID)->second.name);
 			std::vector<SComponent*> cmp;
 			cmp.push_back(new SComponent(SComponent::flag, playerID, 0));
 			showInfoDialog(msg, cmp);
@@ -1016,7 +1015,7 @@ void CPlayerInterface::heroBonusChanged( const CGHeroInstance *hero, const Bonus
 
 template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, const int version )
 {
-	h & playerID & serialID;
+	h & playerID;
 	h & sysOpts;
 	h & spellbookSettings;
 }

+ 1 - 1
client/CPlayerInterface.h

@@ -245,7 +245,7 @@ public:
 	void tryDiggging(const CGHeroInstance *h);
 	void showShipyardDialogOrProblemPopup(const IShipyard *obj); //obj may be town or shipyard; 
 
-	CPlayerInterface(int Player, int serial);//c-tor
+	CPlayerInterface(int Player);//c-tor
 	~CPlayerInterface();//d-tor
 
 	CondSh<bool> terminate_cond; // confirm termination

+ 66 - 61
client/CPreGame.cpp

@@ -62,7 +62,7 @@ void startGame(StartInfo * options);
 CGPreGame * CGP;
 static const CMapInfo *curMap;
 static StartInfo *curOpts;
-static int playerColor, playerSerial; //if more than one player - applies to the first
+static int playerColor; //if more than one player - applies to the first
 static std::vector<std::string> playerNames; // serial id of name <-> player name
 
 static std::string selectedName; //set when game is started/loaded
@@ -85,14 +85,13 @@ static CMapInfo *mapInfoFromGame()
 static void setPlayersFromGame()
 {
 	playerColor = LOCPLINT->playerID;
-	playerSerial = LOCPLINT->serialID;
 }
 
 static void clearInfo()
 {
 	delNull(curMap);
 	delNull(curOpts);
-	playerColor = playerSerial = -1;
+	playerColor = -1;
 	playerNames.clear();
 }
 
@@ -113,8 +112,8 @@ void CMapInfo::countPlayers()
 	}
 
 	if(scenarioOpts)
-		for (std::vector<PlayerSettings>::const_iterator i = scenarioOpts->playerInfos.begin(); i != scenarioOpts->playerInfos.end(); i++)
-			if(i->human)
+		for (std::map<int, PlayerSettings>::const_iterator i = scenarioOpts->playerInfos.begin(); i != scenarioOpts->playerInfos.end(); i++)
+			if(i->second.human)
 				actualHumanPlayers++;
 }
 
@@ -406,7 +405,7 @@ CSelectionScreen::~CSelectionScreen()
 {
 	curMap = NULL;
 	curOpts = NULL;
-	playerSerial = playerColor = -1;
+	playerColor = -1;
 	playerNames.clear();
 }
 
@@ -456,7 +455,7 @@ void setPlayer(PlayerSettings &pset, unsigned player)
 		if(playerColor < 0)
 		{
 			playerColor = pset.color;
-			playerSerial = pset.serial;
+			//playerSerial = pset.serial;
 		}
 	}
 	else
@@ -472,12 +471,11 @@ void CSelectionScreen::updateStartInfo( const CMapInfo * to, StartInfo & sInfo,
 	if(!to) 
 		return;
 
-	sInfo.playerInfos.resize(to->playerAmnt);
+	/*sInfo.playerInfos.resize(to->playerAmnt);*/
 	sInfo.mapname = to->filename;
-	playerSerial = playerColor = -1;
+	playerColor = -1;
 	ui8 placedPlayers = 0;
 
-	int serialC=0;
 	for (int i = 0; i < PLAYER_LIMIT; i++)
 	{
 		const PlayerInfo &pinfo = mapHeader->players[i];
@@ -486,9 +484,8 @@ void CSelectionScreen::updateStartInfo( const CMapInfo * to, StartInfo & sInfo,
 		if (!(pinfo.canComputerPlay || pinfo.canComputerPlay))
 			continue;
 
-		PlayerSettings &pset = sInfo.playerInfos[serialC];
+		PlayerSettings &pset = sInfo.playerInfos[i];
 		pset.color = i;
-		pset.serial = serialC++;
 		if(pinfo.canHumanPlay)
 			setPlayer(pset, placedPlayers++);
 		else
@@ -533,9 +530,9 @@ void CSelectionScreen::startGame()
 	if(type == CMenuScreen::newGame)
 	{
 		//there must be at least one human player before game can be started
-		std::vector<PlayerSettings>::const_iterator i;
+		std::map<int, PlayerSettings>::const_iterator i;
 		for(i = curOpts->playerInfos.begin(); i != curOpts->playerInfos.end(); i++)
-			if(i->human)
+			if(i->second.human)
 				break;
 
 		if(i == curOpts->playerInfos.end())
@@ -1303,11 +1300,11 @@ void InfoCard::showAll( SDL_Surface * to )
 			myT = curMap->mapHeader->players[playerColor].team;
 			//else 
 			//	myT = -1;
-			for (std::vector<PlayerSettings>::const_iterator i = curOpts->playerInfos.begin(); i != curOpts->playerInfos.end(); i++)
+			for (std::map<int, PlayerSettings>::const_iterator i = curOpts->playerInfos.begin(); i != curOpts->playerInfos.end(); i++)
 			{
-				int *myx = ((i->color == playerColor  ||  curMap->mapHeader->players[i->color].team == myT) ? &fx : &ex);
-				blitAtLoc(sFlags->ourImages[i->color].bitmap, *myx, 399, to);
-				*myx += sFlags->ourImages[i->color].bitmap->w;
+				int *myx = ((i->first == playerColor  ||  curMap->mapHeader->players[i->first].team == myT) ? &fx : &ex);
+				blitAtLoc(sFlags->ourImages[i->first].bitmap, *myx, 399, to);
+				*myx += sFlags->ourImages[i->first].bitmap->w;
 			}
 
 			std::string tob;
@@ -1578,19 +1575,20 @@ void OptionsTab::nextBonus( int player, int dir )
 
 void OptionsTab::changeSelection( const CMapHeader *to )
 {
-	for(int i = 0; i < entries.size(); i++)
+	for(std::map<int, PlayerOptionsEntry*>::iterator it = entries.begin(); it != entries.end(); ++it)
 	{
-		children -= entries[i];
-		delete entries[i];
+		children -= it->second;
+		delete it->second;
 	}
 	entries.clear();
 	usedHeroes.clear();
 
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
-	for(int i = 0; i < curOpts->playerInfos.size(); i++)
+	for(std::map<int, PlayerSettings>::iterator it = curOpts->playerInfos.begin(); 
+		it != curOpts->playerInfos.end(); ++it)
 	{
-		entries.push_back(new PlayerOptionsEntry(this, curOpts->playerInfos[i]));
-		const std::vector<SheroName> &heroes = curMap->mapHeader->players[curOpts->playerInfos[i].color].heroesNames;
+		entries.insert(std::make_pair(it->first, new PlayerOptionsEntry(this, it->second)));
+		const std::vector<SheroName> &heroes = curMap->mapHeader->players[it->first].heroesNames;
 		for(size_t hi=0; hi<heroes.size(); hi++)
 			usedHeroes.insert(heroes[hi].heroID);
 	}
@@ -1607,22 +1605,21 @@ void OptionsTab::setTurnLength( int npos )
 
 void OptionsTab::flagPressed( int player )
 {
-	static std::pair<int, int> playerToRestore(-1, -1); //<color serial, player name serial> 
+	static std::pair<int, int> playerToRestore(-1, -1); //<color, player name serial> 
 
 	PlayerSettings &clicked =  curOpts->playerInfos[player];
 	PlayerSettings *old = NULL;
 
 	if(playerNames.size() == 1) //single player -> swap
 	{
-		if(player == playerSerial) //that color is already selected, no action needed
+		if(player == playerColor) //that color is already selected, no action needed
 			return;
 
 
-		old = &curOpts->playerInfos[playerSerial];
+		old = &curOpts->playerInfos[playerColor];
 		std::swap(old->human, clicked.human);
 		std::swap(old->name, clicked.name);
 		playerColor = clicked.color;
-		playerSerial = player;
 	}
 	else
 	{
@@ -1656,26 +1653,26 @@ void OptionsTab::flagPressed( int player )
 		//if that player was somewhere else, we need to replace him with computer
 		if(curNameID < playerNames.size())
 		{
-			for(std::vector<PlayerSettings>::iterator i = curOpts->playerInfos.begin(); i != curOpts->playerInfos.end(); i++)
+			for(std::map<int, PlayerSettings>::iterator i = curOpts->playerInfos.begin(); i != curOpts->playerInfos.end(); i++)
 			{
-				if(i->serial != player  &&  i->name == playerNames[curNameID])
+				if(i->first != player  &&  i->second.name == playerNames[curNameID])
 				{
-					assert(i->human);
-					playerToRestore.first = i->serial;
-					playerToRestore.second = vstd::findPos(playerNames, i->name);
-					setPlayer(*i, -1); //set computer
-					old = &*i;
+					assert(i->second.human);
+					playerToRestore.first = i->first;
+					playerToRestore.second = vstd::findPos(playerNames, i->second.name);
+					setPlayer(i->second, -1); //set computer
+					old = &i->second;
 					break;
 				}
 			}
 		}
 	}
 
-	entries[clicked.serial]->selectButtons();
+	entries[clicked.color]->selectButtons();
 	if(old)
 	{
-		entries[old->serial]->selectButtons();
-		if(!entries[playerSerial]->fixedHero)
+		entries[old->color]->selectButtons();
+		if(!entries[playerColor]->fixedHero)
 			old->hero = -1;
 	}
 	GH.totalRedraw();
@@ -1686,7 +1683,14 @@ OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry( OptionsTab *owner, PlayerSet
 {
 	OBJ_CONSTRUCTION;
 	defActions |= SHARE_POS;
-	pos = parent->pos + Point(54, 122 + s.serial*50);
+	int serial = 0;
+	for(int g=0; g < s.color; ++g)
+	{
+		if( curMap->mapHeader->players[g].canComputerPlay || curMap->mapHeader->players[g].canHumanPlay)
+			serial++;
+	}
+
+	pos = parent->pos + Point(54, 122 + serial*50);
 
 	static const char *flags[] = {"AOFLGBR.DEF", "AOFLGBB.DEF", "AOFLGBY.DEF", "AOFLGBG.DEF", 
 		"AOFLGBO.DEF", "AOFLGBP.DEF", "AOFLGBT.DEF", "AOFLGBS.DEF"};
@@ -1696,12 +1700,12 @@ OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry( OptionsTab *owner, PlayerSet
 	bg = new CPicture(BitmapHandler::loadBitmap(bgs[s.color]), 0, 0, true);
 	if(owner->type == CMenuScreen::newGame)
 	{
-		btns[0] = new AdventureMapButton(CGI->generaltexth->zelp[132], bind(&OptionsTab::nextCastle, owner, s.serial, -1), 107, 5, "ADOPLFA.DEF");
-		btns[1] = new AdventureMapButton(CGI->generaltexth->zelp[133], bind(&OptionsTab::nextCastle, owner, s.serial, +1), 168, 5, "ADOPRTA.DEF");
-		btns[2] = new AdventureMapButton(CGI->generaltexth->zelp[148], bind(&OptionsTab::nextHero, owner, s.serial, -1), 183, 5, "ADOPLFA.DEF");
-		btns[3] = new AdventureMapButton(CGI->generaltexth->zelp[149], bind(&OptionsTab::nextHero, owner, s.serial, +1), 244, 5, "ADOPRTA.DEF");
-		btns[4] = new AdventureMapButton(CGI->generaltexth->zelp[164], bind(&OptionsTab::nextBonus, owner, s.serial, -1), 259, 5, "ADOPLFA.DEF");
-		btns[5] = new AdventureMapButton(CGI->generaltexth->zelp[165], bind(&OptionsTab::nextBonus, owner, s.serial, +1), 320, 5, "ADOPRTA.DEF");
+		btns[0] = new AdventureMapButton(CGI->generaltexth->zelp[132], bind(&OptionsTab::nextCastle, owner, s.color, -1), 107, 5, "ADOPLFA.DEF");
+		btns[1] = new AdventureMapButton(CGI->generaltexth->zelp[133], bind(&OptionsTab::nextCastle, owner, s.color, +1), 168, 5, "ADOPRTA.DEF");
+		btns[2] = new AdventureMapButton(CGI->generaltexth->zelp[148], bind(&OptionsTab::nextHero, owner, s.color, -1), 183, 5, "ADOPLFA.DEF");
+		btns[3] = new AdventureMapButton(CGI->generaltexth->zelp[149], bind(&OptionsTab::nextHero, owner, s.color, +1), 244, 5, "ADOPRTA.DEF");
+		btns[4] = new AdventureMapButton(CGI->generaltexth->zelp[164], bind(&OptionsTab::nextBonus, owner, s.color, -1), 259, 5, "ADOPLFA.DEF");
+		btns[5] = new AdventureMapButton(CGI->generaltexth->zelp[165], bind(&OptionsTab::nextBonus, owner, s.color, +1), 320, 5, "ADOPRTA.DEF");
 	}
 	else
 		for(int i = 0; i < 6; i++)
@@ -1722,18 +1726,18 @@ OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry( OptionsTab *owner, PlayerSet
 
 	if(owner->type != CMenuScreen::scenarioInfo  &&  curMap->mapHeader->players[s.color].canHumanPlay)
 	{
-		flag = new AdventureMapButton(CGI->generaltexth->zelp[180], bind(&OptionsTab::flagPressed, owner, s.serial), -43, 2, flags[s.color]);
+		flag = new AdventureMapButton(CGI->generaltexth->zelp[180], bind(&OptionsTab::flagPressed, owner, s.color), -43, 2, flags[s.color]);
 		flag->hoverable = true;
 	}
 	else
 		flag = NULL;
 
 	defActions &= ~SHARE_POS;
-	town = new SelectedBox(TOWN, s.serial);
+	town = new SelectedBox(TOWN, s.color);
 	town->pos += pos + Point(119, 2);
-	hero = new SelectedBox(HERO, s.serial);
+	hero = new SelectedBox(HERO, s.color);
 	hero->pos += pos + Point(195, 2);
-	bonus = new SelectedBox(BONUS, s.serial);
+	bonus = new SelectedBox(BONUS, s.color);
 	bonus->pos += pos + Point(271, 2);
 }
 
@@ -2050,12 +2054,12 @@ CScenarioInfo::CScenarioInfo(const CMapHeader *mapHeader, const StartInfo *start
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 
-	for(size_t i = 0; i < startInfo->playerInfos.size(); i++)
+	for(std::map<int, PlayerSettings>::const_iterator it = startInfo->playerInfos.begin(); 
+		it != startInfo->playerInfos.end(); ++it)
 	{
-		if(startInfo->playerInfos[i].human)
+		if(it->second.human)
 		{
-			playerColor = startInfo->playerInfos[i].color;
-			playerSerial = i;
+			playerColor = it->first;
 		}
 	}
 
@@ -2414,11 +2418,11 @@ void CBonusSelection::show( SDL_Surface * to )
 	//flags
 	int fx=530, ex=674, myT;
 	myT = ourHeader->players[playerColor].team;
-	for (std::vector<PlayerSettings>::const_iterator i = sInfo.playerInfos.begin(); i != sInfo.playerInfos.end(); i++)
+	for (std::map<int, PlayerSettings>::const_iterator i = sInfo.playerInfos.begin(); i != sInfo.playerInfos.end(); i++)
 	{
-		int *myx = ((i->color == playerColor  ||  ourHeader->players[i->color].team == myT) ? &fx : &ex);
-		blitAtLoc(sFlags->ourImages[i->color].bitmap, *myx, 405, to);
-		*myx += sFlags->ourImages[i->color].bitmap->w;
+		int *myx = ((i->first == playerColor  ||  ourHeader->players[i->first].team == myT) ? &fx : &ex);
+		blitAtLoc(sFlags->ourImages[i->first].bitmap, *myx, 405, to);
+		*myx += sFlags->ourImages[i->first].bitmap->w;
 	}
 
 	//difficulty
@@ -2476,18 +2480,19 @@ void CBonusSelection::updateBonusSelection()
 			case 2: //building
 				{
 					int faction = -1;
-					for (int g=0; g<sInfo.playerInfos.size(); ++g)
+					for(std::map<int, PlayerSettings>::iterator it = sInfo.playerInfos.begin(); 
+						it != sInfo.playerInfos.end(); ++it)
 					{
-						if (sInfo.playerInfos[g].human)
+						if (it->second.human)
 						{
-							faction = sInfo.playerInfos[g].castle;
+							faction = it->second.castle;
 							break;
 						}
 						
 					}
 					assert(faction != -1);
 
-					std::string bldgBitmapName = CGI->buildh->ERMUtoPicture[faction][CBuildingHandler::campToERMU(bonDescs[i].info1, faction)];
+					std::string bldgBitmapName = CGI->buildh->ERMUtoPicture[faction][CBuildingHandler::campToERMU(bonDescs[i].info1, faction, std::set<si32>())];
 					surfToDuplicate = BitmapHandler::loadBitmap(bldgBitmapName);
 
 					freeDuplicatedSurface = true;

+ 1 - 1
client/CPreGame.h

@@ -182,7 +182,7 @@ public:
 
 	std::set<int> usedHeroes;
 
-	std::vector<PlayerOptionsEntry *> entries;
+	std::map<int, PlayerOptionsEntry *> entries; //indexed by color
 
 	void nextCastle(int player, int dir); //dir == -1 or +1
 	void nextHero(int player, int dir); //dir == -1 or +1

+ 12 - 9
client/Client.cpp

@@ -294,9 +294,10 @@ void CClient::loadGame( const std::string & fname )
 		tlog0 << "Server opened savegame properly.\n";
 
 	*serv << ui8(gs->scenarioOps->playerInfos.size()+1); //number of players + neutral
-	for(size_t i=0;i<gs->scenarioOps->playerInfos.size();i++) 
+	for(std::map<int, PlayerSettings>::iterator it = gs->scenarioOps->playerInfos.begin(); 
+		it != gs->scenarioOps->playerInfos.end(); ++it)
 	{
-		*serv << ui8(gs->scenarioOps->playerInfos[i].color); //players
+		*serv << ui8(it->first); //players
 	}
 	*serv << ui8(255); // neutrals
 	tlog0 <<"Sent info to server: "<<tmh.getDif()<<std::endl;
@@ -367,9 +368,10 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 	else
 		tlog0 << "Server opened map properly.\n";
 	c << ui8(si->playerInfos.size()+1); //number of players + neutral
-	for(size_t i=0;i<si->playerInfos.size();i++) 
+	for(std::map<int, PlayerSettings>::iterator it =si->playerInfos.begin(); 
+		it != si->playerInfos.end(); ++it)
 	{
-		c << ui8(si->playerInfos[i].color); //players
+		c << ui8(it->first); //players
 	}
 	c << ui8(255); // neutrals
 
@@ -393,17 +395,18 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 	tlog0 <<"Initializing mapHandler (together): "<<tmh.getDif()<<std::endl;
 
 	int humanPlayers = 0;
-	for (size_t i=0; i<gs->scenarioOps->playerInfos.size();++i) //initializing interfaces for players
+	for(std::map<int, PlayerSettings>::iterator it = gs->scenarioOps->playerInfos.begin(); 
+		it != gs->scenarioOps->playerInfos.end(); ++it)//initializing interfaces for players
 	{ 
-		ui8 color = gs->scenarioOps->playerInfos[i].color;
+		ui8 color = it->first;
 		CCallback *cb = new CCallback(gs,color,this);
-		if(!gs->scenarioOps->playerInfos[i].human) 
+		if(!it->second.human) 
 		{
 			playerint[color] = static_cast<CGameInterface*>(CAIHandler::getNewAI(cb,conf.cc.defaultAI));
 		}
 		else 
 		{
-			playerint[color] = new CPlayerInterface(color,i);
+			playerint[color] = new CPlayerInterface(color);
 			humanPlayers++;
 		}
 		gs->currentPlayer = color;
@@ -466,7 +469,7 @@ void CClient::serialize( Handler &h, const int version )
 			if(dllname.length())
 				nInt = CAIHandler::getNewAI(callback,dllname);
 			else
-				nInt = new CPlayerInterface(pid,i);
+				nInt = new CPlayerInterface(pid);
 
 			playerint[pid] = nInt;
 			nInt->init(callback);

+ 1 - 1
client/GUIClasses.cpp

@@ -5757,7 +5757,7 @@ CPuzzleWindow::CPuzzleWindow(const int3 &grailPos, float discoveredRatio)
 
 	delete arrows;
 
-	int faction = LOCPLINT->cb->getStartInfo()->playerInfos[LOCPLINT->serialID].castle;
+	int faction = LOCPLINT->cb->getStartInfo()->playerInfos.find(LOCPLINT->playerID)->second.castle;
 
 	std::vector<SPuzzleInfo> puzzlesToPrint;
 

+ 12 - 3
hch/CBuildingHandler.cpp

@@ -199,7 +199,7 @@ CBuilding::CBuilding( int TID, int BID )
 	bid = BID;
 }
 
-int CBuildingHandler::campToERMU(int camp, int townType)
+int CBuildingHandler::campToERMU( int camp, int townType, std::set<si32> builtBuildings )
 {
 	using namespace boost::assign;
 	static const std::vector<int> campToERMU = list_of(11)(12)(13)(7)(8)(9)(5)(16)(14)(15)(-1)(0)(1)(2)(3)(4)
@@ -229,11 +229,20 @@ int CBuildingHandler::campToERMU(int camp, int townType)
 			{
 				if (hordeLvlsPerTType[townType][0] == i)
 				{
-					return 18; //or 19 - TODO
+					if(vstd::contains(builtBuildings, 37 + hordeLvlsPerTType[townType][0])) //if upgraded dwelling is built
+						return 19;
+					else //upgraded dwelling not presents
+						return 18;
 				}
 				else
 				{
-					return 24; //or 25 - TODO
+					if(hordeLvlsPerTType[townType].size() > 1)
+					{
+						if(vstd::contains(builtBuildings, 37 + hordeLvlsPerTType[townType][1])) //if upgraded dwelling is built
+							return 25;
+						else //upgraded dwelling not presents
+							return 24;
+					}
 				}
 			}
 			curPos++;

+ 2 - 1
hch/CBuildingHandler.h

@@ -3,6 +3,7 @@
 #include "../global.h"
 #include <map>
 #include <vector>
+#include <set>
 
 /*
  * CBuildingHandler.h, part of VCMI engine
@@ -42,7 +43,7 @@ public:
 
 	void loadBuildings(); //main loader
 	~CBuildingHandler(); //d-tor
-	static int campToERMU(int camp, int townType);
+	static int campToERMU(int camp, int townType, std::set<si32> builtBuildings);
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{

+ 25 - 26
lib/CGameState.cpp

@@ -1256,10 +1256,11 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
 		static std::vector<const PlayerSettings *> getHumanPlayerInfo(const StartInfo * si)
 		{
 			std::vector<const PlayerSettings *> ret;
-			for (int g=0; g<si->playerInfos.size(); ++g)
+			for(std::map<int, PlayerSettings>::const_iterator it = si->playerInfos.begin(); 
+				it != si->playerInfos.end(); ++it)
 			{
-				if(si->playerInfos[g].human)
-					ret.push_back(&si->playerInfos[g]);
+				if(it->second.human)
+					ret.push_back(&it->second);
 			}
 
 			return ret;
@@ -1350,16 +1351,17 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
  	}
 
 	//picking random factions for players
-	for(unsigned int i=0;i<scenarioOps->playerInfos.size();i++)
+	for(std::map<int, PlayerSettings>::iterator it = scenarioOps->playerInfos.begin(); 
+		it != scenarioOps->playerInfos.end(); ++it)
 	{
-		if(scenarioOps->playerInfos[i].castle==-1)
+		if(it->second.castle==-1)
 		{
 			int f;
 			do
 			{
 				f = ran()%F_NUMBER;
-			}while(!(map->players[scenarioOps->playerInfos[i].color].allowedFactions  &  1<<f));
-			scenarioOps->playerInfos[i].castle = f;
+			}while(!(map->players[it->first].allowedFactions  &  1<<f));
+			it->second.castle = f;
 		}
 	}
 
@@ -1386,12 +1388,12 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
 	//std::cout<<"\tRandomizing objects: "<<th.getDif()<<std::endl;
 
 	/*********creating players entries in gs****************************************/
-	for (unsigned int i=0; i<scenarioOps->playerInfos.size();i++)
+	for(std::map<int, PlayerSettings>::iterator it = scenarioOps->playerInfos.begin(); 
+		it != scenarioOps->playerInfos.end(); ++it)
 	{
-		std::pair<int,PlayerState> ins(scenarioOps->playerInfos[i].color,PlayerState());
+		std::pair<int,PlayerState> ins(it->first,PlayerState());
 		ins.second.color=ins.first;
-		ins.second.serial=i;
-		ins.second.human = scenarioOps->playerInfos[i].human;
+		ins.second.human = it->second.human;
 		players.insert(ins);
 	}
 
@@ -1402,16 +1404,14 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
 		{
 			int3 hpos = map->players[i].posOfMainTown;
 			hpos.x+=1;// hpos.y+=1;
-			int j;
-			for(j=0; j<scenarioOps->playerInfos.size(); j++) //don't add unsigned here - we are refering to the variable above
-				if(scenarioOps->playerInfos[j].color == i)
-					break;
-			if(j == scenarioOps->playerInfos.size())
+			if (scenarioOps->playerInfos.find(i) == scenarioOps->playerInfos.end())
+			{
 				continue;
+			}
 
 			int h=pickHero(i);
-			if(scenarioOps->playerInfos[j].hero == -1)
-				scenarioOps->playerInfos[j].hero = h;
+			if(scenarioOps->playerInfos[i].hero == -1)
+				scenarioOps->playerInfos[i].hero = h;
 
 			CGHeroInstance * nnn =  static_cast<CGHeroInstance*>(createObject(HEROI_TYPE,h,hpos,i));
 			nnn->id = map->objects.size();
@@ -1637,16 +1637,16 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
 		}
 
 		//starting bonus
-		if(si->playerInfos[k->second.serial].bonus==PlayerSettings::brandom)
-			si->playerInfos[k->second.serial].bonus = ran()%3;
-		switch(si->playerInfos[k->second.serial].bonus)
+		if(si->playerInfos[k->first].bonus==PlayerSettings::brandom)
+			si->playerInfos[k->first].bonus = ran()%3;
+		switch(si->playerInfos[k->first].bonus)
 		{
 		case PlayerSettings::bgold:
 			k->second.resources[6] += 500 + (ran()%6)*100;
 			break;
 		case PlayerSettings::bresource:
 			{
-				int res = VLC->townh->towns[si->playerInfos[k->second.serial].castle].primaryRes;
+				int res = VLC->townh->towns[si->playerInfos[k->first].castle].primaryRes;
 				if(res == 127)
 				{
 					k->second.resources[0] += 5 + ran()%6;
@@ -1769,12 +1769,11 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
 				PlayerState * owner = getPlayer(map->towns[g]->getOwner());
 				PlayerInfo & pi = map->players[owner->color];
 				
-
 				if (owner->human && //human-owned
-					map->towns[g]->pos == pi.posOfMainTown) 
+					map->towns[g]->pos == pi.posOfMainTown + int3(2, 0, 0)) 
 				{
 					map->towns[g]->builtBuildings.insert(
-						CBuildingHandler::campToERMU(chosenBonus.info1, map->towns[g]->alignment));
+						CBuildingHandler::campToERMU(chosenBonus.info1, map->towns[g]->town->typeID, map->towns[g]->builtBuildings));
 					break;
 				}
 			}
@@ -3607,7 +3606,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 			}
 			else //AI
 			{
-				tgi.personality[g->second.color] = map->players[g->second.serial].AITactic;
+				tgi.personality[g->second.color] = map->players[g->second.color].AITactic;
 			}
 			
 		}

+ 2 - 2
lib/CGameState.h

@@ -117,7 +117,7 @@ struct DLL_EXPORT PlayerState : public CBonusSystemNode
 {
 public:
 	enum EStatus {INGAME, LOSER, WINNER};
-	ui8 color, serial;
+	ui8 color;
 	ui8 human; //true if human controlled player, false for AI
 	ui32 currentSelection; //id of hero/town, 0xffffffff if none
 	std::vector<std::vector<std::vector<ui8> > >  fogOfWarMap; //true - visible, false - hidden
@@ -139,7 +139,7 @@ public:
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & color & serial & human & currentSelection & fogOfWarMap & resources & status;
+		h & color & human & currentSelection & fogOfWarMap & resources & status;
 		h & heroes & towns & availableHeroes & dwellings & bonuses & status & daysWithoutCastle;
 		h & enteredLosingCheatCode & enteredWinningCheatCode;
 		h & static_cast<CBonusSystemNode&>(*this);