Browse Source

* PlayerColor and TeamID refactoring

mateuszb 12 years ago
parent
commit
dbec99ffc7
70 changed files with 889 additions and 843 deletions
  1. 7 7
      AI/VCAI/VCAI.cpp
  2. 1 1
      AI/VCAI/VCAI.h
  3. 3 3
      CCallback.cpp
  4. 2 2
      CCallback.h
  5. 1 1
      Editor/Editor.cpp
  6. 4 3
      Scripting/ERM/ERMInterpreter.cpp
  7. 18 18
      client/AdventureMapClasses.cpp
  8. 2 2
      client/AdventureMapClasses.h
  9. 1 1
      client/BattleInterface/CBattleInterfaceClasses.cpp
  10. 1 1
      client/BattleInterface/CBattleInterfaceClasses.h
  11. 3 3
      client/CAdvmapInterface.cpp
  12. 3 3
      client/CAdvmapInterface.h
  13. 6 6
      client/CAnimation.cpp
  14. 5 5
      client/CAnimation.h
  15. 1 1
      client/CCastleInterface.cpp
  16. 1 1
      client/CHeroWindow.cpp
  17. 2 2
      client/CMT.cpp
  18. 8 8
      client/CMessage.cpp
  19. 3 3
      client/CMessage.h
  20. 6 6
      client/CPlayerInterface.cpp
  21. 3 3
      client/CPlayerInterface.h
  22. 59 59
      client/CPreGame.cpp
  23. 15 14
      client/CPreGame.h
  24. 32 32
      client/Client.cpp
  25. 12 12
      client/Client.h
  26. 13 13
      client/GUIClasses.cpp
  27. 4 4
      client/GUIClasses.h
  28. 11 11
      client/Graphics.cpp
  29. 1 1
      client/Graphics.h
  30. 21 21
      client/NetPacksClient.cpp
  31. 4 4
      client/UIFramework/CIntObjectClasses.cpp
  32. 3 3
      client/UIFramework/CIntObjectClasses.h
  33. 4 4
      client/UIFramework/SDL_Extensions.cpp
  34. 1 1
      client/UIFramework/SDL_Extensions.h
  35. 5 5
      client/mapHandler.cpp
  36. 12 12
      lib/BattleState.cpp
  37. 8 8
      lib/BattleState.h
  38. 11 11
      lib/CBattleCallback.cpp
  39. 12 12
      lib/CBattleCallback.h
  40. 1 1
      lib/CGameInterface.h
  41. 63 62
      lib/CGameState.cpp
  42. 22 22
      lib/CGameState.h
  43. 80 70
      lib/CObjectHandler.cpp
  44. 21 20
      lib/CObjectHandler.h
  45. 1 1
      lib/Connection.cpp
  46. 3 3
      lib/Connection.h
  47. 5 0
      lib/GameConstants.cpp
  48. 65 40
      lib/GameConstants.h
  49. 1 1
      lib/HeroBonus.cpp
  50. 2 2
      lib/HeroBonus.h
  51. 33 33
      lib/IGameCallback.cpp
  52. 32 32
      lib/IGameCallback.h
  53. 2 2
      lib/IGameEventsReceiver.h
  54. 1 1
      lib/Mapping/CCampaignHandler.cpp
  55. 1 1
      lib/Mapping/CCampaignHandler.h
  56. 1 1
      lib/Mapping/CMap.cpp
  57. 2 2
      lib/Mapping/CMap.h
  58. 1 1
      lib/Mapping/CMapInfo.cpp
  59. 13 13
      lib/Mapping/MapFormatH3M.cpp
  60. 31 30
      lib/NetPacks.h
  61. 12 12
      lib/NetPacksLib.cpp
  62. 4 4
      lib/RMG/CMapGenOptions.cpp
  63. 4 4
      lib/RMG/CMapGenOptions.h
  64. 18 18
      lib/RMG/CMapGenerator.cpp
  65. 9 9
      lib/RMG/CMapGenerator.h
  66. 4 4
      lib/StartInfo.h
  67. 1 1
      lib/StringConstants.h
  68. 109 108
      server/CGameHandler.cpp
  69. 32 32
      server/CGameHandler.h
  70. 6 6
      server/NetPacksServer.cpp

+ 7 - 7
AI/VCAI/VCAI.cpp

@@ -393,7 +393,7 @@ ui64 evaluateDanger(crint3 tile, const CGHeroInstance *visitor)
 
 ui64 evaluateDanger(const CGObjectInstance *obj)
 {
-	if(obj->tempOwner < GameConstants::PLAYER_LIMIT && cb->getPlayerRelations(obj->tempOwner, ai->playerID) != PlayerRelations::ENEMIES) //owned or allied objects don't pose any threat
+	if(obj->tempOwner < PlayerColor::PLAYER_LIMIT && cb->getPlayerRelations(obj->tempOwner, ai->playerID) != PlayerRelations::ENEMIES) //owned or allied objects don't pose any threat
 		return 0;
 
 	switch(obj->ID)
@@ -553,11 +553,11 @@ void VCAI::showShipyardDialog(const IShipyard *obj)
 	LOG_ENTRY;
 }
 
-void VCAI::gameOver(ui8 player, bool victory)
+void VCAI::gameOver(PlayerColor player, bool victory)
 {
 	NET_EVENT_HANDLER;
 	LOG_ENTRY;
-	BNLOG("Player %d: I heard that player %d %s.", playerID % (int)player % (victory ? "won" : "lost"));
+	BNLOG("Player %d: I heard that player %d %s.", playerID % player.getNum() % (victory ? "won" : "lost"));
 	if(player == playerID)
 	{
 		if(victory)
@@ -567,7 +567,7 @@ void VCAI::gameOver(ui8 player, bool victory)
 		}
 		else
 		{
-			tlog0 << "VCAI: Player " << (int)player << " lost. It's me. What a disappointment! :(\n";
+			tlog0 << "VCAI: Player " << player << " lost. It's me. What a disappointment! :(\n";
 		}
 
 // 		//let's make Impossible difficulty finally standing to its name :>
@@ -838,7 +838,7 @@ void VCAI::objectPropertyChanged(const SetObjectProperty * sop)
 	LOG_ENTRY;
 	if(sop->what == ObjProperty::OWNER)
 	{
-		if(sop->val == playerID)
+		if(sop->val == playerID.getNum())
 			remove_if_present(visitableObjs, myCb->getObj(sop->id));
 		//TODO restore lost obj
 	}
@@ -1593,7 +1593,7 @@ void VCAI::completeGoal (const CGoal goal)
 void VCAI::battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side)
 {
 	NET_EVENT_HANDLER;
-	assert(playerID > GameConstants::PLAYER_LIMIT || status.getBattle() == UPCOMING_BATTLE);
+	assert(playerID > PlayerColor::PLAYER_LIMIT || status.getBattle() == UPCOMING_BATTLE);
 	status.setBattle(ONGOING_BATTLE);
 	const CGObjectInstance *presumedEnemy = backOrNull(cb->getVisitableObjs(tile)); //may be NULL in some very are cases -> eg. visited monolith and fighting with an enemy at the FoW covered exit
 	battlename = boost::str(boost::format("Starting battle of %s attacking %s at %s") % (hero1 ? hero1->name : "a army") % (presumedEnemy ? presumedEnemy->hoverName : "unknown enemy") % tile);
@@ -2344,7 +2344,7 @@ void VCAI::striveToQuest (const QuestInfo &q)
 			}
 			case CQuest::MISSION_PLAYER:
 			{
-				if (playerID != q.quest->m13489val)
+				if (playerID.getNum() != q.quest->m13489val)
 					BNLOG ("Can't be player of color %d\n", q.quest->m13489val);
 				break;
 			}

+ 1 - 1
AI/VCAI/VCAI.h

@@ -305,7 +305,7 @@ public:
 	virtual void playerBlocked(int reason) OVERRIDE;
 	virtual void showPuzzleMap() OVERRIDE;
 	virtual void showShipyardDialog(const IShipyard *obj) OVERRIDE;
-	virtual void gameOver(ui8 player, bool victory) OVERRIDE;
+	virtual void gameOver(PlayerColor player, bool victory) OVERRIDE;
 	virtual void artifactPut(const ArtifactLocation &al) OVERRIDE;
 	virtual void artifactRemoved(const ArtifactLocation &al) OVERRIDE;
 	virtual void stacksErased(const StackLocation &location) OVERRIDE;

+ 3 - 3
CCallback.cpp

@@ -98,7 +98,7 @@ bool CCallback::upgradeCreature(const CArmedInstance *obj, SlotID stackPos, Crea
 
 void CCallback::endTurn()
 {
-	tlog5 << "Player " << (unsigned)*player << " ended his turn." << std::endl;
+	tlog5 << "Player " << *player << " ended his turn." << std::endl;
 	EndTurn pack;
 	sendRequest(&pack); //report that we ended turn
 }
@@ -289,7 +289,7 @@ void CCallback::buildBoat( const IShipyard *obj )
 	sendRequest(&bb);
 }
 
-CCallback::CCallback( CGameState * GS, boost::optional<TPlayerColor> Player, CClient *C )
+CCallback::CCallback( CGameState * GS, boost::optional<PlayerColor> Player, CClient *C )
 	:CBattleCallback(GS, Player, C)
 {
 	waitTillRealize = false;
@@ -376,7 +376,7 @@ int CCallback::mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance
 		return swapCreatures(s1, s2, p1, p2);
 }
 
-CBattleCallback::CBattleCallback(CGameState *GS, boost::optional<TPlayerColor> Player, CClient *C )
+CBattleCallback::CBattleCallback(CGameState *GS, boost::optional<PlayerColor> Player, CClient *C )
 {
 	gs = GS;
 	player = Player;

+ 2 - 2
CCallback.h

@@ -86,7 +86,7 @@ protected:
 	//virtual bool hasAccess(int playerId) const;
 
 public:
-	CBattleCallback(CGameState *GS, boost::optional<TPlayerColor> Player, CClient *C);
+	CBattleCallback(CGameState *GS, boost::optional<PlayerColor> Player, CClient *C);
 	int battleMakeAction(BattleAction* action) OVERRIDE;//for casting spells by hero - DO NOT use it for moving active stack
 	bool battleMakeTacticAction(BattleAction * action) OVERRIDE; // performs tactic phase actions
 
@@ -101,7 +101,7 @@ private:
 	void validatePaths(); //recalcualte paths if necessary
 
 public:
-	CCallback(CGameState * GS, boost::optional<TPlayerColor> Player, CClient *C);
+	CCallback(CGameState * GS, boost::optional<PlayerColor> Player, CClient *C);
 	virtual ~CCallback();
 
 	//client-specific functionalities (pathfinding)

+ 1 - 1
Editor/Editor.cpp

@@ -10,7 +10,7 @@
 Editor::Editor(QWidget *parent)
 	: QMainWindow(parent)
 {
-	logfile = new std::ofstream((GVCMIDirs.UserPath + "/VCMI_Editor_log.txt").c_str());
+	logfile = new std::ofstream((VCMIDirs::get().localPath() + "/VCMI_Editor_log.txt").c_str());
 	console = new CConsoleHandler;
 
 	preinitDLL(console,logfile);

+ 4 - 3
Scripting/ERM/ERMInterpreter.cpp

@@ -5,6 +5,7 @@
 #include "../../lib/CObjectHandler.h"
 #include "../../lib/CHeroHandler.h"
 #include "../../lib/CCreatureHandler.h"
+#include "../../lib/VCMIDirs.h"
 
 /*
  * ERMInterpreter.cpp, part of VCMI engine
@@ -366,13 +367,13 @@ void ERMInterpreter::scanForScripts()
 {
 	using namespace boost::filesystem;
 	//parser checking
-	if(!exists(GameConstants::DATA_DIR + "/Data/s/"))
+	if(!exists(VCMIDirs::get().dataPath() + "/Data/s/"))
 	{
-		tlog3 << "Warning: Folder " << GameConstants::DATA_DIR << "/Data/s/ doesn't exist!\n";
+		tlog3 << "Warning: Folder " << VCMIDirs::get().dataPath() << "/Data/s/ doesn't exist!\n";
 		return;
 	}
 	directory_iterator enddir;
-	for (directory_iterator dir(GameConstants::DATA_DIR + "/Data/s"); dir!=enddir; dir++)
+	for (directory_iterator dir(VCMIDirs::get().dataPath() + "/Data/s"); dir!=enddir; dir++)
 	{
 		if(is_regular(dir->status()))
 		{

+ 18 - 18
client/AdventureMapClasses.cpp

@@ -361,12 +361,12 @@ const SDL_Color & CMinimapInstance::getTileColor(const int3 & pos)
 		if (obj->ID == Obj::HERO)
 			continue;
 
-		int player = obj->getOwner();
-		if(player == GameConstants::NEUTRAL_PLAYER)
+		PlayerColor player = obj->getOwner();
+		if(player == PlayerColor::NEUTRAL)
 			return *graphics->neutralColor;
 		else
-		if (player < GameConstants::PLAYER_LIMIT)
-			return graphics->playerColors[player];
+		if (player < PlayerColor::PLAYER_LIMIT)
+			return graphics->playerColors[player.getNum()];
 	}
 
 	// else - use terrain color (blocked version or normal)
@@ -468,7 +468,7 @@ void CMinimapInstance::showAll(SDL_Surface *to)
 		int3 position = hero->getPosition(false);
 		if (position.z == level)
 		{
-			const SDL_Color & color = graphics->playerColors[hero->getOwner()];
+			const SDL_Color & color = graphics->playerColors[hero->getOwner().getNum()];
 			blitTileWithColor(color, position, to, pos.x, pos.y);
 		}
 	}
@@ -723,13 +723,13 @@ void CInfoBar::CVisibleInfo::loadDay()
 	forceRefresh.push_back(new CLabel(95, 31, FONT_MEDIUM, CENTER, Colors::WHITE, labelText));
 }
 
-void CInfoBar::CVisibleInfo::loadEnemyTurn(int player)
+void CInfoBar::CVisibleInfo::loadEnemyTurn(PlayerColor player)
 {
 	assert(children.empty()); // visible info should be re-created to change type
 
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	new CPicture("ADSTATNX");
-	new CAnimImage("CREST58", player, 0, 20, 51);
+	new CAnimImage("CREST58", player.getNum(), 0, 20, 51);
 	new CShowableAnim(99, 51, "HOURSAND");
 
 	// FIXME: currently there is no way to get progress from VCAI
@@ -753,17 +753,17 @@ void CInfoBar::CVisibleInfo::loadGameStatus()
 	BOOST_FOREACH(auto town, LOCPLINT->towns)
 		halls[town->hallLevel()]++;
 
-	std::vector<int> allies, enemies;
+	std::vector<PlayerColor> allies, enemies;
 
 	//generate list of allies and enemies
-	for(int i = 0; i < GameConstants::PLAYER_LIMIT; i++)
+	for(int i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++)
 	{
-		if(LOCPLINT->cb->getPlayerStatus(i) == EPlayerStatus::INGAME)
+		if(LOCPLINT->cb->getPlayerStatus(PlayerColor(i)) == EPlayerStatus::INGAME)
 		{
-			if (LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, i) != PlayerRelations::ENEMIES)
-				allies.push_back(i);
+			if (LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, PlayerColor(i)) != PlayerRelations::ENEMIES)
+				allies.push_back(PlayerColor(i));
 			else
-				enemies.push_back(i);
+				enemies.push_back(PlayerColor(i));
 		}
 	}
 
@@ -774,16 +774,16 @@ void CInfoBar::CVisibleInfo::loadGameStatus()
 	auto enemyLabel = new CLabel(10, 136, FONT_SMALL, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[391] + ":");
 
 	int posx = allyLabel->pos.w + allyLabel->pos.x - pos.x + 4;
-	BOOST_FOREACH(int & player, allies)
+	BOOST_FOREACH(PlayerColor & player, allies)
 	{
-		auto image = new CAnimImage("ITGFLAGS", player, 0, posx, 102);
+		auto image = new CAnimImage("ITGFLAGS", player.getNum(), 0, posx, 102);
 		posx += image->pos.w;
 	}
 
 	posx = enemyLabel->pos.w + enemyLabel->pos.x - pos.x + 4;
-	BOOST_FOREACH(int & player, enemies)
+	BOOST_FOREACH(PlayerColor & player, enemies)
 	{
-		auto image = new CAnimImage("ITGFLAGS", player, 0, posx, 132);
+		auto image = new CAnimImage("ITGFLAGS", player.getNum(), 0, posx, 132);
 		posx += image->pos.w;
 	}
 
@@ -904,7 +904,7 @@ void CInfoBar::showComponent(const Component & comp, std::string message)
 	redraw();
 }
 
-void CInfoBar::startEnemyTurn(ui8 color)
+void CInfoBar::startEnemyTurn(PlayerColor color)
 {
 	reset(AITURN);
 	visibleInfo->loadEnemyTurn(color);

+ 2 - 2
client/AdventureMapClasses.h

@@ -261,7 +261,7 @@ class CInfoBar : public CIntObject
 		void loadHero(const CGHeroInstance * hero);
 		void loadTown(const CGTownInstance * town);
 		void loadDay();
-		void loadEnemyTurn(int player);
+		void loadEnemyTurn(PlayerColor player);
 		void loadGameStatus();
 		void loadComponent(const Component &comp, std::string message);
 
@@ -298,7 +298,7 @@ public:
 	void showComponent(const Component & comp, std::string message);
 
 	/// print enemy turn progress
-	void startEnemyTurn(ui8 color);
+	void startEnemyTurn(PlayerColor color);
 	/// updates enemy turn.
 	/// NOTE: currently DISABLED. Check comments in CInfoBar::CVisibleInfo::loadEnemyTurn()
 	void updateEnemyTurn(double progress);

+ 1 - 1
client/BattleInterface/CBattleInterfaceClasses.cpp

@@ -198,7 +198,7 @@ void CBattleHero::switchToNextPhase()
 	currentFrame = firstFrame;
 }
 
-CBattleHero::CBattleHero(const std::string & defName, bool flipG, ui8 player, const CGHeroInstance * hero, const CBattleInterface * owner):
+CBattleHero::CBattleHero(const std::string & defName, bool flipG, PlayerColor player, const CGHeroInstance * hero, const CBattleInterface * owner):
     flip(flipG),
     myHero(hero),
     myOwner(owner),

+ 1 - 1
client/BattleInterface/CBattleInterfaceClasses.h

@@ -61,7 +61,7 @@ public:
 	void show(SDL_Surface * to); //prints next frame of animation to to
 	void setPhase(int newPhase); //sets phase of hero animation
 	void clickLeft(tribool down, bool previousState); //call-in
-	CBattleHero(const std::string &defName, bool filpG, ui8 player, const CGHeroInstance *hero, const CBattleInterface *owner); //c-tor
+	CBattleHero(const std::string &defName, bool filpG, PlayerColor player, const CGHeroInstance *hero, const CBattleInterface *owner); //c-tor
 	~CBattleHero(); //d-tor
 };
 

+ 3 - 3
client/CAdvmapInterface.cpp

@@ -748,7 +748,7 @@ void CAdvMapInt::show(SDL_Surface * to)
 	{
 		terrain.show(to);
 		for(int i=0;i<4;i++)
-			blitAt(gems[i]->ourImages[LOCPLINT->playerID].bitmap,ADVOPT.gemX[i],ADVOPT.gemY[i],to);
+			blitAt(gems[i]->ourImages[LOCPLINT->playerID.getNum()].bitmap,ADVOPT.gemX[i],ADVOPT.gemY[i],to);
 		updateScreen=false;
 		LOCPLINT->cingconsole->showAll(to);
 	}
@@ -1066,12 +1066,12 @@ bool CAdvMapInt::isActive()
 	return active & ~CIntObject::KEYBOARD;
 }
 
-void CAdvMapInt::startHotSeatWait(int Player)
+void CAdvMapInt::startHotSeatWait(PlayerColor Player)
 {
 	state = WAITING;
 }
 
-void CAdvMapInt::setPlayer(int Player)
+void CAdvMapInt::setPlayer(PlayerColor Player)
 {
 	player = Player;
 	graphics->blueToPlayersAdv(bg,player);

+ 3 - 3
client/CAdvmapInterface.h

@@ -93,7 +93,7 @@ public:
 	~CAdvMapInt();
 
 	int3 position; //top left corner of visible map part
-	int player;
+	PlayerColor player;
 
 	bool duringAITurn;
 
@@ -164,8 +164,8 @@ public:
 	void setHeroSleeping(const CGHeroInstance *hero, bool sleep);
 	int getNextHeroIndex(int startIndex); //for Next Hero button - cycles awake heroes with movement only
 
-	void setPlayer(int Player);
-	void startHotSeatWait(int Player);
+	void setPlayer(PlayerColor Player);
+	void startHotSeatWait(PlayerColor Player);
 	void startTurn();
 	void endingTurn();
 	void aiTurnStarted();

+ 6 - 6
client/CAnimation.cpp

@@ -651,7 +651,7 @@ void SDLImage::draw(SDL_Surface *where, int posX, int posY, Rect *src, ui8 rotat
 	CSDL_Ext::blitSurface(surf, &sourceRect, where, &destRect);
 }
 
-void SDLImage::playerColored(int player)
+void SDLImage::playerColored(PlayerColor player)
 {
 	graphics->blueToPlayersAdv(surf, player);
 }
@@ -852,14 +852,14 @@ void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha)
 	}
 }
 
-void CompImage::playerColored(int player)
+void CompImage::playerColored(PlayerColor player)
 {
 	SDL_Color *pal = NULL;
-	if(player < GameConstants::PLAYER_LIMIT && player >= 0)
+	if(player < PlayerColor::PLAYER_LIMIT)
 	{
-		pal = graphics->playerColorPalette + 32*player;
+		pal = graphics->playerColorPalette + 32*player.getNum();
 	}
-	else if(player == 255 || player == -1)
+	else if(player == PlayerColor::NEUTRAL)
 	{
 		pal = graphics->neutralColorPalette;
 	}
@@ -1253,7 +1253,7 @@ void CAnimImage::setFrame(size_t Frame, size_t Group)
 		tlog1 << "Error: accessing unavailable frame " << Group << ":" << Frame << " in CAnimation!\n";
 }
 
-void CAnimImage::playerColored(int currPlayer)
+void CAnimImage::playerColored(PlayerColor currPlayer)
 {
 	player = currPlayer;
 	flags |= CShowableAnim::PLAYER_COLORED;

+ 5 - 5
client/CAnimation.h

@@ -68,7 +68,7 @@ public:
 	void increaseRef();
 
 	//Change palette to specific player
-	virtual void playerColored(int player)=0;
+	virtual void playerColored(PlayerColor player)=0;
 	virtual int width() const=0;
 	virtual int height() const=0;
 	IImage();
@@ -98,7 +98,7 @@ public:
 	~SDLImage();
 
 	void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL,  ui8 alpha=255) const;
-	void playerColored(int player);
+	void playerColored(PlayerColor player);
 	int width() const;
 	int height() const;
 
@@ -144,7 +144,7 @@ public:
 	~CompImage();
 
 	void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL, ui8 alpha=255) const;
-	void playerColored(int player);
+	void playerColored(PlayerColor player);
 	int width() const;
 	int height() const;
 
@@ -228,7 +228,7 @@ private:
 	//displayed frame/group
 	size_t frame;
 	size_t group;
-	int player;
+	PlayerColor player;
 	ui8 flags;
 
 	void init();
@@ -245,7 +245,7 @@ public:
 	void setFrame(size_t Frame, size_t Group=0);
 
 	//makes image player-colored
-	void playerColored(int player);
+	void playerColored(PlayerColor player);
 
 	void showAll(SDL_Surface * to);
 };

+ 1 - 1
client/CCastleInterface.cpp

@@ -424,7 +424,7 @@ void CHeroGSlot::set(const CGHeroInstance *newHero)
 	if (newHero)
 		image = new CAnimImage("PortraitsLarge", newHero->portrait, 0, 0, 0);
 	else if(!upg && owner->showEmpty) //up garrison
-		image = new CAnimImage("CREST58", LOCPLINT->castleInt->town->getOwner(), 0, 0, 0);
+		image = new CAnimImage("CREST58", LOCPLINT->castleInt->town->getOwner().getNum(), 0, 0, 0);
 	else 
 		image = NULL;
 }

+ 1 - 1
client/CHeroWindow.cpp

@@ -98,7 +98,7 @@ CHeroWindow::CHeroWindow(const CGHeroInstance *hero):
 	curHero = hero;
 	listSelection = nullptr;
 
-	new CAnimImage("CREST58", LOCPLINT->playerID, 0, 606, 8);
+	new CAnimImage("CREST58", LOCPLINT->playerID.getNum(), 0, 606, 8);
 
 	//artifs = new CArtifactsOfHero(pos.topLeft(), true);
 	ourBar = new CGStatusBar(7, 559, "ADROLLVR.bmp", 660); // new CStatusBar(pos.x+72, pos.y+567, "ADROLLVR.bmp", 660);

+ 2 - 2
client/CMT.cpp

@@ -348,8 +348,8 @@ int main(int argc, char** argv)
 		StartInfo *si = new StartInfo();
 		si->mode = StartInfo::DUEL;
 		si->mapname = vm["battle"].as<std::string>();
-		si->playerInfos[0].color = 0;
-		si->playerInfos[1].color = 1;
+		si->playerInfos[PlayerColor(0)].color = PlayerColor(0);
+		si->playerInfos[PlayerColor(1)].color = PlayerColor(1);
 		startGame(si);
 	}
 	mainGUIThread = new boost::thread(&CGuiHandler::run, boost::ref(GH));

+ 8 - 8
client/CMessage.cpp

@@ -73,8 +73,8 @@ namespace
 void CMessage::init()
 {
 	{
-		piecesOfBox.resize(GameConstants::PLAYER_LIMIT);
-		for (int i=0;i<GameConstants::PLAYER_LIMIT;i++)
+		piecesOfBox.resize(PlayerColor::PLAYER_LIMIT_I);
+		for (int i=0; i<PlayerColor::PLAYER_LIMIT_I; i++)
 		{
 			CDefHandler * bluePieces = CDefHandler::giveDef("DIALGBOX.DEF");
 			if (i==1)
@@ -87,7 +87,7 @@ void CMessage::init()
 			}
 			for (size_t j=0;j<bluePieces->ourImages.size();++j)
 			{
-				graphics->blueToPlayersAdv(bluePieces->ourImages[j].bitmap,i);
+				graphics->blueToPlayersAdv(bluePieces->ourImages[j].bitmap, PlayerColor(i));
 				piecesOfBox[i].push_back(bluePieces->ourImages[j].bitmap);
 				bluePieces->ourImages[j].bitmap->refcount++;
 			}
@@ -102,7 +102,7 @@ void CMessage::init()
 
 void CMessage::dispose()
 {
-	for (int i=0;i<GameConstants::PLAYER_LIMIT;i++)
+	for (int i=0; i<PlayerColor::PLAYER_LIMIT_I; i++)
 	{
 		for (size_t j=0; j<piecesOfBox[i].size(); ++j)
 		{
@@ -114,7 +114,7 @@ void CMessage::dispose()
 	delete cancel;
 }
 
-SDL_Surface * CMessage::drawDialogBox(int w, int h, TPlayerColor playerColor)
+SDL_Surface * CMessage::drawDialogBox(int w, int h, PlayerColor playerColor)
 {
 	//prepare surface
 	SDL_Surface * ret = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
@@ -219,7 +219,7 @@ std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineSi
 	return ret;
 }
 
-void CMessage::drawIWindow(CInfoWindow * ret, std::string text, TPlayerColor player)
+void CMessage::drawIWindow(CInfoWindow * ret, std::string text, PlayerColor player)
 {
 	bool blitOr = false;
 	if(dynamic_cast<CSelWindow*>(ret)) //it's selection window, so we'll blit "or" between components
@@ -304,9 +304,9 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, TPlayerColor pla
 		ret->components[i]->moveBy(Point(ret->pos.x, ret->pos.y));
 }
 
-void CMessage::drawBorder(TPlayerColor playerColor, SDL_Surface * ret, int w, int h, int x, int y)
+void CMessage::drawBorder(PlayerColor playerColor, SDL_Surface * ret, int w, int h, int x, int y)
 {	
-	std::vector<SDL_Surface *> &box = piecesOfBox[playerColor];
+	std::vector<SDL_Surface *> &box = piecesOfBox[playerColor.getNum()];
 
 	// Note: this code assumes that the corner dimensions are all the same.
 

+ 3 - 3
client/CMessage.h

@@ -31,12 +31,12 @@ public:
 	static SDL_Surface * blitTextOnSur(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight, int & curh, SDL_Surface * ret, int xCenterPos=-1); //xPos==-1 works as if ret->w/2
 
 	/// Draw border on exiting surface
-	static void drawBorder(TPlayerColor playerColor, SDL_Surface * ret, int w, int h, int x=0, int y=0);
+	static void drawBorder(PlayerColor playerColor, SDL_Surface * ret, int w, int h, int x=0, int y=0);
 
 	/// Draw simple dialog box (borders and background only)
-	static SDL_Surface * drawDialogBox(int w, int h, TPlayerColor playerColor=1);
+	static SDL_Surface * drawDialogBox(int w, int h, PlayerColor playerColor = PlayerColor(1));
 
-	static void drawIWindow(CInfoWindow * ret, std::string text, TPlayerColor player);
+	static void drawIWindow(CInfoWindow * ret, std::string text, PlayerColor player);
 
 	/// split text in lines
 	static std::vector<std::string> breakText(std::string text, size_t maxLineWidth, EFonts font);

+ 6 - 6
client/CPlayerInterface.cpp

@@ -96,7 +96,7 @@ struct OCM_HLP_CGIN
 
 
 
-CPlayerInterface::CPlayerInterface(int Player)
+CPlayerInterface::CPlayerInterface(PlayerColor Player)
 {
 	tlog5 << "\tHuman player interface for player " << Player << " being constructed\n";
 	observerInDuelMode = false;
@@ -189,7 +189,7 @@ void CPlayerInterface::yourTurn()
 			std::string msg = CGI->generaltexth->allTexts[13];
 			boost::replace_first(msg, "%s", cb->getStartInfo()->playerInfos.find(playerID)->second.name);
 			std::vector<CComponent*> cmp;
-			cmp.push_back(new CComponent(CComponent::flag, playerID, 0));
+			cmp.push_back(new CComponent(CComponent::flag, playerID.getNum(), 0));
 			showInfoDialog(msg, cmp);
 		}
 		else
@@ -2045,7 +2045,7 @@ void CPlayerInterface::finishMovement( const TryMoveHero &details, const int3 &h
 	std::stable_sort(CGI->mh->ttiles[details.end.x][details.end.y][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x][details.end.y][details.end.z].objects.end(), ocmptwo_cgin);
 }
 
-void CPlayerInterface::gameOver(ui8 player, bool victory )
+void CPlayerInterface::gameOver(PlayerColor player, bool victory )
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	if(LOCPLINT != this)
@@ -2076,8 +2076,8 @@ void CPlayerInterface::gameOver(ui8 player, bool victory )
 		if(!victory && cb->getPlayerStatus(playerID) == EPlayerStatus::INGAME) //enemy has lost
 		{
 			std::string txt = CGI->generaltexth->allTexts[5]; //%s has been vanquished!
-			boost::algorithm::replace_first(txt, "%s", CGI->generaltexth->capColors[player]);
-			showInfoDialog(txt,std::vector<CComponent*>(1, new CComponent(CComponent::flag, player, 0)));
+			boost::algorithm::replace_first(txt, "%s", CGI->generaltexth->capColors[player.getNum()]);
+			showInfoDialog(txt,std::vector<CComponent*>(1, new CComponent(CComponent::flag, player.getNum(), 0)));
 		}
 	}
 }
@@ -2432,7 +2432,7 @@ void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
 	}
 }
 
-void CPlayerInterface::playerStartsTurn(ui8 player)
+void CPlayerInterface::playerStartsTurn(PlayerColor player)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 

+ 3 - 3
client/CPlayerInterface.h

@@ -179,8 +179,8 @@ public:
 	void centerView (int3 pos, int focusTime) OVERRIDE;
 	void objectPropertyChanged(const SetObjectProperty * sop) OVERRIDE;
 	void objectRemoved(const CGObjectInstance *obj) OVERRIDE;
-	void gameOver(ui8 player, bool victory) OVERRIDE;
-	void playerStartsTurn(ui8 player) OVERRIDE; //called before yourTurn on active itnerface
+	void gameOver(PlayerColor player, bool victory) OVERRIDE;
+	void playerStartsTurn(PlayerColor player) OVERRIDE; //called before yourTurn on active itnerface
 	void showComp(const Component &comp, std::string message) OVERRIDE; //display component in the advmapint infobox
 	void serialize(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
 	void serialize(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading
@@ -242,7 +242,7 @@ public:
 	void sendCustomEvent(int code);
 	void proposeLoadingGame();
 
-	CPlayerInterface(int Player);//c-tor
+	CPlayerInterface(PlayerColor Player);//c-tor
 	~CPlayerInterface();//d-tor
 
 	static CondSh<bool> terminate_cond; // confirm termination

+ 59 - 59
client/CPreGame.cpp

@@ -66,7 +66,7 @@ void startGame(StartInfo * options, CConnection *serv = NULL);
 CGPreGame * CGP = nullptr;
 ISelectionScreenInfo *SEL;
 
-static int playerColor; //if more than one player - applies to the first
+static PlayerColor playerColor; //if more than one player - applies to the first
 
 /**
  * Stores the current name of the savegame.
@@ -129,7 +129,7 @@ static void swapPlayers(PlayerSettings &a, PlayerSettings &b)
 		playerColor = b.color;
 }
 
-void setPlayer(PlayerSettings &pset, TPlayerColor player, const std::map<TPlayerColor, std::string> &playerNames)
+void setPlayer(PlayerSettings &pset, ui8 player, const std::map<ui8, std::string> &playerNames)
 {
 	if(vstd::contains(playerNames, player))
 		pset.name = playerNames.find(player)->second;
@@ -141,7 +141,7 @@ void setPlayer(PlayerSettings &pset, TPlayerColor player, const std::map<TPlayer
 		playerColor = pset.color;
 }
 
-void updateStartInfo(std::string filename, StartInfo & sInfo, const CMapHeader * mapHeader, const std::map<TPlayerColor, std::string> &playerNames)
+void updateStartInfo(std::string filename, StartInfo & sInfo, const CMapHeader * mapHeader, const std::map<ui8, std::string> &playerNames)
 {
 	sInfo.playerInfos.clear();
 	if(!mapHeader)
@@ -150,7 +150,7 @@ void updateStartInfo(std::string filename, StartInfo & sInfo, const CMapHeader *
 	}
 
 	sInfo.mapname = filename;
-	playerColor = -1;
+	playerColor = PlayerColor::NEUTRAL;
 
 	auto namesIt = playerNames.cbegin();
 
@@ -162,8 +162,8 @@ void updateStartInfo(std::string filename, StartInfo & sInfo, const CMapHeader *
 		if (!(pinfo.canHumanPlay || pinfo.canComputerPlay))
 			continue;
 
-		PlayerSettings &pset = sInfo.playerInfos[i];
-		pset.color = i;
+		PlayerSettings &pset = sInfo.playerInfos[PlayerColor(i)];
+		pset.color = PlayerColor(i);
 		if(pinfo.canHumanPlay && namesIt != playerNames.cend())
 		{
 			setPlayer(pset, namesIt++->first, playerNames);
@@ -270,7 +270,7 @@ void CMenuScreen::showAll(SDL_Surface * to)
 	CIntObject::showAll(to);
 
 	if (pos.h != to->h || pos.w != to->w)
-		CMessage::drawBorder(1, to, pos.w+28, pos.h+30, pos.x-14, pos.y-15);
+		CMessage::drawBorder(PlayerColor(1), to, pos.w+28, pos.h+30, pos.x-14, pos.y-15);
 
 }
 
@@ -354,7 +354,7 @@ static boost::function<void()> genCommand(CMenuScreen* menu, std::vector<std::st
 				}
 				break; case 4://exit
 				{
-					return boost::bind(CInfoWindow::showYesNoDialog, boost::ref(CGI->generaltexth->allTexts[69]), (const std::vector<CComponent*>*)0, do_quit, 0, false, 1);
+					return boost::bind(CInfoWindow::showYesNoDialog, boost::ref(CGI->generaltexth->allTexts[69]), (const std::vector<CComponent*>*)0, do_quit, 0, false, PlayerColor(1));
 				}
 				break; case 5://highscores
 				{
@@ -562,7 +562,7 @@ void CGPreGame::removeFromGui()
 	GH.popInt(GH.topInt()); //remove background
 }
 
-CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMultiMode MultiPlayer /*= CMenuScreen::SINGLE_PLAYER*/, const std::map<TPlayerColor, std::string> *Names /*= NULL*/)
+CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMultiMode MultiPlayer /*= CMenuScreen::SINGLE_PLAYER*/, const std::map<ui8, std::string> *Names /*= NULL*/)
 	: ISelectionScreenInfo(Names), serverHandlingThread(NULL), mx(new boost::recursive_mutex),
 	  serv(NULL), ongoingClosing(false), myNameID(255)
 {
@@ -756,7 +756,7 @@ CSelectionScreen::~CSelectionScreen()
 		serverHandlingThread->join();
 		delete serverHandlingThread;
 	}
-	playerColor = -1;
+	playerColor = PlayerColor::CANNOT_DETERMINE;
 	playerNames.clear();
 
 	assert(!serv);
@@ -858,7 +858,7 @@ void CSelectionScreen::startScenario()
 	if(screenType == CMenuScreen::newGame)
 	{
 		//there must be at least one human player before game can be started
-		std::map<TPlayerColor, PlayerSettings>::const_iterator i;
+		std::map<PlayerColor, PlayerSettings>::const_iterator i;
 		for(i = SEL->sInfo.playerInfos.cbegin(); i != SEL->sInfo.playerInfos.cend(); i++)
 			if(i->second.playerID != PlayerSettings::PLAYER_AI)
 				break;
@@ -960,7 +960,7 @@ void CSelectionScreen::handleConnection()
 
 void CSelectionScreen::setSInfo(const StartInfo &si)
 {
-	std::map<TPlayerColor, PlayerSettings>::const_iterator i;
+	std::map<PlayerColor, PlayerSettings>::const_iterator i;
 	for(i = si.playerInfos.cbegin(); i != si.playerInfos.cend(); i++)
 	{
 		if(i->second.playerID == myNameID)
@@ -971,7 +971,7 @@ void CSelectionScreen::setSInfo(const StartInfo &si)
 	}
 
 	if(i == si.playerInfos.cend()) //not found
-		playerColor = -1;
+		playerColor = PlayerColor::CANNOT_DETERMINE;
 
 	sInfo = si;
 	if(current)
@@ -1039,7 +1039,7 @@ void CSelectionScreen::showAll(SDL_Surface *to)
 {
 	CIntObject::showAll(to);
 	if (bordered && (pos.h != to->h || pos.w != to->w))
-		CMessage::drawBorder(1, to, pos.w+28, pos.h+30, pos.x-14, pos.y-15);
+		CMessage::drawBorder(PlayerColor(1), to, pos.w+28, pos.h+30, pos.x-14, pos.y-15);
 }
 
 // A new size filter (Small, Medium, ...) has been selected. Populate
@@ -1853,7 +1853,7 @@ void RandomMapTab::updateMapInfo()
 		{
 			player.canHumanPlay = true;
 		}
-		player.team = i;
+		player.team = TeamID(i);
 		player.hasMainTown = true;
 		player.generateHeroAtMainTown = true;
 		mapInfo.mapHeader->players.push_back(player);
@@ -1995,7 +1995,7 @@ void InfoCard::showAll(SDL_Surface * to)
 		}
 		else //players list
 		{
-			std::map<TPlayerColor, std::string> playerNames = SEL->playerNames;
+			std::map<ui8, std::string> playerNames = SEL->playerNames;
 			int playerSoFar = 0;
 			for (auto i = SEL->sInfo.playerInfos.cbegin(); i != SEL->sInfo.playerInfos.cend(); i++)
 			{
@@ -2079,18 +2079,18 @@ void InfoCard::showAll(SDL_Surface * to)
 			int fx = 34  + graphics->fonts[FONT_SMALL]->getStringWidth(CGI->generaltexth->allTexts[390]);
 			int ex = 200 + graphics->fonts[FONT_SMALL]->getStringWidth(CGI->generaltexth->allTexts[391]);
 
-			int myT;
+			TeamID myT;
 
-			if(playerColor >= 0)
-				myT = SEL->current->mapHeader->players[playerColor].team;
+			if(playerColor < PlayerColor::PLAYER_LIMIT)
+				myT = SEL->current->mapHeader->players[playerColor.getNum()].team;
 			else
-				myT = -1;
+				myT = TeamID::NO_TEAM;
 
 			for (auto i = SEL->sInfo.playerInfos.cbegin(); i != SEL->sInfo.playerInfos.cend(); i++)
 			{
-				int *myx = ((i->first == playerColor  ||  SEL->current->mapHeader->players[i->first].team == myT) ? &fx : &ex);
-				blitAtLoc(sFlags->ourImages[i->first].bitmap, *myx, 399, to);
-				*myx += sFlags->ourImages[i->first].bitmap->w;
+				int *myx = ((i->first == playerColor  ||  SEL->current->mapHeader->players[i->first.getNum()].team == myT) ? &fx : &ex);
+				blitAtLoc(sFlags->ourImages[i->first.getNum()].bitmap, *myx, 399, to);
+				*myx += sFlags->ourImages[i->first.getNum()].bitmap->w;
 			}
 
 			std::string tob;
@@ -2173,9 +2173,9 @@ void InfoCard::showTeamsPopup()
 
 		graphics->fonts[FONT_SMALL]->renderTextCenter(bmp, hlp, Colors::WHITE, Point(128, 65 + 50 * i));
 
-		for(int j = 0; j < GameConstants::PLAYER_LIMIT; j++)
+		for(int j = 0; j < PlayerColor::PLAYER_LIMIT_I; j++)
 			if((SEL->current->mapHeader->players[j].canHumanPlay || SEL->current->mapHeader->players[j].canComputerPlay)
-				&& SEL->current->mapHeader->players[j].team == i)
+				&& SEL->current->mapHeader->players[j].team == TeamID(i))
 				flags.push_back(j);
 
 		int curx = 128 - 9*flags.size();
@@ -2248,7 +2248,7 @@ void OptionsTab::showAll(SDL_Surface * to)
 		printAtMiddleLoc(CGI->generaltexth->turnDurations[turnDuration->value], 319,559, FONT_SMALL, Colors::WHITE, to);//Turn duration value
 }
 
-void OptionsTab::nextCastle( int player, int dir )
+void OptionsTab::nextCastle( PlayerColor player, int dir )
 {
 	if(SEL->isGuest())
 	{
@@ -2258,7 +2258,7 @@ void OptionsTab::nextCastle( int player, int dir )
 
 	PlayerSettings &s = SEL->sInfo.playerInfos[player];
 	si16 &cur = s.castle;
-	auto & allowed = SEL->current->mapHeader->players[s.color].allowedFactions;
+	auto & allowed = SEL->current->mapHeader->players[s.color.getNum()].allowedFactions;
 
 	if (cur == PlayerSettings::NONE) //no change
 		return;
@@ -2285,7 +2285,7 @@ void OptionsTab::nextCastle( int player, int dir )
 		}
 	}
 
-	if(s.hero >= 0 && SEL->current->mapHeader->players[s.color].customHeroID < 0) // remove hero unless it set to fixed one in map editor
+	if(s.hero >= 0 && SEL->current->mapHeader->players[s.color.getNum()].customHeroID < 0) // remove hero unless it set to fixed one in map editor
 		s.hero =  PlayerSettings::RANDOM;
 	if(cur < 0  &&  s.bonus == PlayerSettings::RESOURCE)
 		s.bonus = PlayerSettings::RANDOM;
@@ -2297,7 +2297,7 @@ void OptionsTab::nextCastle( int player, int dir )
 	redraw();
 }
 
-void OptionsTab::nextHero( int player, int dir )
+void OptionsTab::nextHero( PlayerColor player, int dir )
 {
 	if(SEL->isGuest())
 	{
@@ -2334,7 +2334,7 @@ void OptionsTab::nextHero( int player, int dir )
 	SEL->propagateOptions();
 }
 
-int OptionsTab::nextAllowedHero( int player, int min, int max, int incl, int dir )
+int OptionsTab::nextAllowedHero( PlayerColor player, int min, int max, int incl, int dir )
 {
 	if(dir>0)
 	{
@@ -2351,7 +2351,7 @@ int OptionsTab::nextAllowedHero( int player, int min, int max, int incl, int dir
 	return -1;
 }
 
-bool OptionsTab::canUseThisHero( int player, int ID )
+bool OptionsTab::canUseThisHero( PlayerColor player, int ID )
 {
 	return CGI->heroh->heroes.size() > ID
 	        && SEL->sInfo.playerInfos[player].castle == CGI->heroh->heroes[ID]->heroClass->faction
@@ -2359,7 +2359,7 @@ bool OptionsTab::canUseThisHero( int player, int ID )
 	        && SEL->current->mapHeader->allowedHeroes[ID];
 }
 
-void OptionsTab::nextBonus( int player, int dir )
+void OptionsTab::nextBonus( PlayerColor player, int dir )
 {
 	if(SEL->isGuest())
 	{
@@ -2371,7 +2371,7 @@ void OptionsTab::nextBonus( int player, int dir )
 	PlayerSettings::Ebonus &ret = s.bonus = static_cast<PlayerSettings::Ebonus>(static_cast<int>(s.bonus) + dir);
 
 	if (s.hero==PlayerSettings::NONE &&
-		!SEL->current->mapHeader->players[s.color].heroesNames.size() &&
+		!SEL->current->mapHeader->players[s.color.getNum()].heroesNames.size() &&
 		ret==PlayerSettings::ARTIFACT) //no hero - can't be artifact
 	{
 		if (dir<0)
@@ -2398,7 +2398,7 @@ void OptionsTab::nextBonus( int player, int dir )
 
 void OptionsTab::recreate()
 {
-	for(std::map<int, PlayerOptionsEntry*>::iterator it = entries.begin(); it != entries.end(); ++it)
+	for(auto it = entries.begin(); it != entries.end(); ++it)
 	{
 		delete it->second;
 	}
@@ -2409,7 +2409,7 @@ void OptionsTab::recreate()
 	for(auto it = SEL->sInfo.playerInfos.begin(); it != SEL->sInfo.playerInfos.end(); ++it)
 	{
 		entries.insert(std::make_pair(it->first, new PlayerOptionsEntry(this, it->second)));
-		const std::vector<SHeroName> &heroes = SEL->current->mapHeader->players[it->first].heroesNames;
+		const std::vector<SHeroName> &heroes = SEL->current->mapHeader->players[it->first.getNum()].heroesNames;
 		for(size_t hi=0; hi<heroes.size(); hi++)
 			usedHeroes.insert(heroes[hi].heroId);
 	}
@@ -2425,7 +2425,7 @@ void OptionsTab::setTurnLength( int npos )
 	redraw();
 }
 
-void OptionsTab::flagPressed( int color )
+void OptionsTab::flagPressed( PlayerColor color )
 {
 	PlayerSettings &clicked =  SEL->sInfo.playerInfos[color];
 	PlayerSettings *old = NULL;
@@ -2506,13 +2506,13 @@ void OptionsTab::flagPressed( int color )
 }
 
 OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry( OptionsTab *owner, PlayerSettings &S)
- : pi(SEL->current->mapHeader->players[S.color]), s(S)
+ : pi(SEL->current->mapHeader->players[S.color.getNum()]), s(S)
 {
 	OBJ_CONSTRUCTION;
 	defActions |= SHARE_POS;
 
 	int serial = 0;
-	for(int g=0; g < s.color; ++g)
+	for(int g=0; g < s.color.getNum(); ++g)
 	{
 		PlayerInfo &itred = SEL->current->mapHeader->players[g];
 		if( itred.canComputerPlay || itred.canHumanPlay)
@@ -2527,7 +2527,7 @@ OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry( OptionsTab *owner, PlayerSet
 	static const char *bgs[] = {"ADOPRPNL.bmp", "ADOPBPNL.bmp", "ADOPYPNL.bmp", "ADOPGPNL.bmp",
 		"ADOPOPNL.bmp", "ADOPPPNL.bmp", "ADOPTPNL.bmp", "ADOPSPNL.bmp"};
 
-	bg = new CPicture(BitmapHandler::loadBitmap(bgs[s.color]), 0, 0, true);
+	bg = new CPicture(BitmapHandler::loadBitmap(bgs[s.color.getNum()]), 0, 0, true);
 	if(SEL->screenType == CMenuScreen::newGame)
 	{
 		btns[0] = new CAdventureMapButton(CGI->generaltexth->zelp[132], bind(&OptionsTab::nextCastle, owner, s.color, -1), 107, 5, "ADOPLFA.DEF");
@@ -2544,7 +2544,7 @@ OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry( OptionsTab *owner, PlayerSet
 	selectButtons();
 
 	assert(SEL->current && SEL->current->mapHeader);
-	const PlayerInfo &p = SEL->current->mapHeader->players[s.color];
+	const PlayerInfo &p = SEL->current->mapHeader->players[s.color.getNum()];
 	assert(p.canComputerPlay || p.canHumanPlay); //someone must be able to control this player
 	if(p.canHumanPlay && p.canComputerPlay)
 		whoCanPlay = HUMAN_OR_CPU;
@@ -2554,10 +2554,10 @@ OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry( OptionsTab *owner, PlayerSet
 		whoCanPlay = HUMAN;
 
 	if(SEL->screenType != CMenuScreen::scenarioInfo
-		&&  SEL->current->mapHeader->players[s.color].canHumanPlay
+		&&  SEL->current->mapHeader->players[s.color.getNum()].canHumanPlay
 		&&  SEL->multiPlayer != CMenuScreen::MULTI_NETWORK_GUEST)
 	{
-		flag = new CAdventureMapButton(CGI->generaltexth->zelp[180], bind(&OptionsTab::flagPressed, owner, s.color), -43, 2, flags[s.color]);
+		flag = new CAdventureMapButton(CGI->generaltexth->zelp[180], bind(&OptionsTab::flagPressed, owner, s.color), -43, 2, flags[s.color.getNum()]);
 		flag->hoverable = true;
 	}
 	else
@@ -2924,7 +2924,7 @@ void OptionsTab::SelectedBox::clickRight( tribool down, bool previousState )
 		// cases when we do not need to display a message
 		if (settings.castle == -2 && CPlayerSettingsHelper::type == TOWN )
 			return;
-		if (settings.hero == -2 && SEL->current->mapHeader->players[settings.color].customHeroID == -1 && CPlayerSettingsHelper::type == HERO)
+		if (settings.hero == -2 && SEL->current->mapHeader->players[settings.color.getNum()].customHeroID == -1 && CPlayerSettingsHelper::type == HERO)
 			return;
 
 		GH.pushInt(new CPregameTooltipBox(*this));
@@ -3103,7 +3103,7 @@ void CHotSeatPlayers::onChange(std::string newText)
 
 void CHotSeatPlayers::enterSelectionScreen()
 {
-	std::map<TPlayerColor, std::string> names;
+	std::map<ui8, std::string> names;
 	for(int i = 0, j = 1; i < ARRAY_COUNT(txt); i++)
 		if(txt[i]->text.length())
 			names[j++] = txt[i]->text;
@@ -3265,7 +3265,7 @@ void CBonusSelection::showAll(SDL_Surface * to)
 
 	show(to);
 	if (pos.h != to->h || pos.w != to->w)
-		CMessage::drawBorder(1, to, pos.w+28, pos.h+30, pos.x-14, pos.y-15);
+		CMessage::drawBorder(PlayerColor(1), to, pos.w+28, pos.h+30, pos.x-14, pos.y-15);
 }
 
 void CBonusSelection::loadPositionsOfGraphics()
@@ -3314,7 +3314,7 @@ void CBonusSelection::selectMap( int whichOne, bool initialSelect )
 		auto buffer = reinterpret_cast<const ui8 *>(headerStr.data());
 		ourHeader = CMapService::loadMapHeader(buffer, headerStr.size()).release();
 
-		std::map<TPlayerColor, std::string> names;
+		std::map<ui8, std::string> names;
 		names[1] = settings["general"]["playerName"].String();
 		updateStartInfo(ourCampaign->camp->header.filename, sInfo, ourHeader, names);
 		sInfo.turnTime = 0;
@@ -3368,13 +3368,13 @@ void CBonusSelection::show(SDL_Surface * to)
 	//flags
 	int fx = 496  + graphics->fonts[FONT_SMALL]->getStringWidth(CGI->generaltexth->allTexts[390]);
 	int ex = 629 + graphics->fonts[FONT_SMALL]->getStringWidth(CGI->generaltexth->allTexts[391]);
-	int myT;
-	myT = ourHeader->players[playerColor].team;
+	TeamID myT;
+	myT = ourHeader->players[playerColor.getNum()].team;
 	for (auto i = sInfo.playerInfos.cbegin(); i != sInfo.playerInfos.cend(); i++)
 	{
-		int *myx = ((i->first == playerColor  ||  ourHeader->players[i->first].team == myT) ? &fx : &ex);
-		blitAtLoc(sFlags->ourImages[i->first].bitmap, pos.x + *myx, pos.y + 405, to);
-		*myx += sFlags->ourImages[i->first].bitmap->w;
+		int *myx = ((i->first == playerColor  ||  ourHeader->players[i->first.getNum()].team == myT) ? &fx : &ex);
+		blitAtLoc(sFlags->ourImages[i->first.getNum()].bitmap, pos.x + *myx, pos.y + 405, to);
+		*myx += sFlags->ourImages[i->first.getNum()].bitmap->w;
 	}
 
 	//difficulty
@@ -3534,7 +3534,7 @@ void CBonusSelection::updateBonusSelection()
 				break;
 			case CScenarioTravel::STravelBonus::PLAYER_PREV_SCENARIO:
 				{
-					auto superhero = ourCampaign->camp->scenarios[bonDescs[i].info2].strongestHero(bonDescs[i].info1);
+					auto superhero = ourCampaign->camp->scenarios[bonDescs[i].info2].strongestHero(PlayerColor(bonDescs[i].info1));
 					if (!superhero) tlog5 << "No superhero! How could it be transfered?\n";
 					picNumber = superhero ? superhero->portrait : 0;
 					desc = CGI->generaltexth->allTexts[719];
@@ -3623,11 +3623,11 @@ void CBonusSelection::selectBonus( int id )
 	const std::vector<CScenarioTravel::STravelBonus> & bonDescs = scenario.travelOptions.bonusesToChoose;
 	if (bonDescs[id].type == CScenarioTravel::STravelBonus::HERO)
 	{
-		std::map<TPlayerColor, std::string> names;
+		std::map<ui8, std::string> names;
 		names[1] = settings["general"]["playerName"].String();
 		for(auto it = sInfo.playerInfos.begin(); it != sInfo.playerInfos.end(); ++it)
 		{
-			if(it->first == bonDescs[id].info1)
+			if(it->first == PlayerColor(bonDescs[id].info1))
 				::setPlayer(it->second, 1, names);
 			else
 				::setPlayer(it->second, 0, names);
@@ -3751,7 +3751,7 @@ CSavingScreen::~CSavingScreen()
 
 }
 
-ISelectionScreenInfo::ISelectionScreenInfo(const std::map<TPlayerColor, std::string> *Names /*= NULL*/)
+ISelectionScreenInfo::ISelectionScreenInfo(const std::map<ui8, std::string> *Names /*= NULL*/)
 {
 	multiPlayer = CMenuScreen::SINGLE_PLAYER;
 	assert(!SEL);
@@ -3775,12 +3775,12 @@ void ISelectionScreenInfo::updateStartInfo(std::string filename, StartInfo & sIn
 	::updateStartInfo(filename, sInfo, mapHeader, playerNames);
 }
 
-void ISelectionScreenInfo::setPlayer(PlayerSettings &pset, TPlayerColor player)
+void ISelectionScreenInfo::setPlayer(PlayerSettings &pset, ui8 player)
 {
 	::setPlayer(pset, player, playerNames);
 }
 
-int ISelectionScreenInfo::getIdOfFirstUnallocatedPlayer()
+ui8 ISelectionScreenInfo::getIdOfFirstUnallocatedPlayer()
 {
 	for(auto i = playerNames.cbegin(); i != playerNames.cend(); i++)
 		if(!sInfo.getPlayersSettings(i->first))  //
@@ -3882,7 +3882,7 @@ void RequestOptionsChange::apply(CSelectionScreen *selScreen)
 	if(!selScreen->isHost())
 		return;
 
-	ui8 color = selScreen->sInfo.getPlayersSettings(playerID)->color;
+	PlayerColor color = selScreen->sInfo.getPlayersSettings(playerID)->color;
 
 	switch(what)
 	{
@@ -4051,7 +4051,7 @@ void CCampaignScreen::showAll(SDL_Surface *to)
 {
 	CIntObject::showAll(to);
 	if (pos.h != to->h || pos.w != to->w)
-		CMessage::drawBorder(1, to, pos.w+28, pos.h+30, pos.x-14, pos.y-15);
+		CMessage::drawBorder(PlayerColor(1), to, pos.w+28, pos.h+30, pos.x-14, pos.y-15);
 }
 
 void CGPreGame::showLoadingScreen(boost::function<void()> loader)

+ 15 - 14
client/CPreGame.h

@@ -257,28 +257,29 @@ public:
 
 	struct PlayerToRestore
 	{
-		int color, id;
-		void reset() { color = id = -1; }
+		PlayerColor color;
+		int id;
+		void reset() { id = -1; color = PlayerColor::CANNOT_DETERMINE; }
 		PlayerToRestore(){ reset(); }
 	} playerToRestore;
 
 
-	std::map<int, PlayerOptionsEntry *> entries; //indexed by color
+	std::map<PlayerColor, 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
-	void nextBonus(int player, int dir); //dir == -1 or +1
+	void nextCastle(PlayerColor player, int dir); //dir == -1 or +1
+	void nextHero(PlayerColor player, int dir); //dir == -1 or +1
+	void nextBonus(PlayerColor player, int dir); //dir == -1 or +1
 	void setTurnLength(int npos);
-	void flagPressed(int player);
+	void flagPressed(PlayerColor player);
 
 	void recreate();
 	OptionsTab();
 	~OptionsTab();
 	void showAll(SDL_Surface * to);
 
-	int nextAllowedHero(int player, int min, int max, int incl, int dir );
+	int nextAllowedHero(PlayerColor player, int min, int max, int incl, int dir );
 
-	bool canUseThisHero(int player, int ID );
+	bool canUseThisHero(PlayerColor player, int ID );
 };
 
 /**
@@ -425,19 +426,19 @@ public:
 	CMenuScreen::EState screenType; //new/save/load#Game
 	const CMapInfo *current;
 	StartInfo sInfo;
-	std::map<TPlayerColor, std::string> playerNames; // id of player <-> player name; 0 is reserved as ID of AI "players"
+	std::map<ui8, std::string> playerNames; // id of player <-> player name; 0 is reserved as ID of AI "players"
 
-	ISelectionScreenInfo(const std::map<TPlayerColor, std::string> *Names = NULL);
+	ISelectionScreenInfo(const std::map<ui8, std::string> *Names = NULL);
 	virtual ~ISelectionScreenInfo();
 	virtual void update(){};
 	virtual void propagateOptions() {};
 	virtual void postRequest(ui8 what, ui8 dir) {};
 	virtual void postChatMessage(const std::string &txt){};
 
-	void setPlayer(PlayerSettings &pset, TPlayerColor player);
+	void setPlayer(PlayerSettings &pset, ui8 player);
 	void updateStartInfo( std::string filename, StartInfo & sInfo, const CMapHeader * mapHeader );
 
-	int getIdOfFirstUnallocatedPlayer(); //returns 0 if none
+	ui8 getIdOfFirstUnallocatedPlayer(); //returns 0 if none
 	bool isGuest() const;
 	bool isHost() const;
 
@@ -465,7 +466,7 @@ public:
 	bool ongoingClosing;
 	ui8 myNameID; //used when networking - otherwise all player are "mine"
 
-	CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMultiMode MultiPlayer = CMenuScreen::SINGLE_PLAYER, const std::map<TPlayerColor, std::string> *Names = NULL);
+	CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMultiMode MultiPlayer = CMenuScreen::SINGLE_PLAYER, const std::map<ui8, std::string> *Names = NULL);
 	~CSelectionScreen();
 	void toggleTab(CIntObject *tab);
 	void changeSelection(const CMapInfo *to);

+ 32 - 32
client/Client.cpp

@@ -112,7 +112,7 @@ CClient::~CClient(void)
 	delete applier;
 }
 
-void CClient::waitForMoveAndSend(TPlayerColor color)
+void CClient::waitForMoveAndSend(PlayerColor color)
 {
 	try
 	{
@@ -175,7 +175,7 @@ void CClient::save(const std::string & fname)
 	}
 
 	SaveGame save_game(fname);
-	sendRequest((CPackForClient*)&save_game, 255);
+	sendRequest((CPackForClient*)&save_game, PlayerColor::NEUTRAL);
 }
 
 void CClient::endGame( bool closeConnection /*= true*/ )
@@ -270,9 +270,9 @@ void CClient::loadGame( const std::string & fname )
 	for(auto it = gs->scenarioOps->playerInfos.begin(); 
 		it != gs->scenarioOps->playerInfos.end(); ++it)
 	{
-		*serv << ui8(it->first); //players
+		*serv << ui8(it->first.getNum()); //players
 	}
-	*serv << ui8(GameConstants::NEUTRAL_PLAYER);
+	*serv << ui8(PlayerColor::NEUTRAL.getNum());
 	tlog0 <<"Sent info to server: "<<tmh.getDiff()<<std::endl;
 
 	serv->enableStackSendingByID();
@@ -326,7 +326,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 
 	// Now after possible random map gen, we know exact player count.
 	// Inform server about how many players client handles
-	std::set<TPlayerColor> myPlayers;
+	std::set<PlayerColor> myPlayers;
 	for(auto it = gs->scenarioOps->playerInfos.begin(); it != gs->scenarioOps->playerInfos.end(); ++it)
 	{
 		if((networkMode == SINGLE)                                                      //single - one client has all player
@@ -337,7 +337,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 		}
 	}
 	if(networkMode != GUEST)
-		myPlayers.insert(GameConstants::NEUTRAL_PLAYER);
+		myPlayers.insert(PlayerColor::NEUTRAL);
 	c << myPlayers;
 
 	// Init map handler
@@ -352,16 +352,16 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 	}
 
 	int humanPlayers = 0;
-	int sensibleAILimit = settings["session"]["oneGoodAI"].Bool() ? 1 : GameConstants::PLAYER_LIMIT;
+	int sensibleAILimit = settings["session"]["oneGoodAI"].Bool() ? 1 : PlayerColor::PLAYER_LIMIT_I;
 	for(auto it = gs->scenarioOps->playerInfos.begin(); 
 		it != gs->scenarioOps->playerInfos.end(); ++it)//initializing interfaces for players
 	{
-		TPlayerColor color = it->first;
+		PlayerColor color = it->first;
 		gs->currentPlayer = color;
 		if(!vstd::contains(myPlayers, color))
 			continue;
 
-		tlog5 << "Preparing interface for player " << (int)color << std::endl;
+		tlog5 << "Preparing interface for player " << color << std::endl;
 		if(si->mode != StartInfo::DUEL)
 		{
 			auto cb = make_shared<CCallback>(gs,color,this);
@@ -373,7 +373,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 				else
 					sensibleAILimit--;
 				playerint[color] = static_cast<CGameInterface*>(CDynLibHandler::getNewAI(AItoGive));
-				tlog1 << "Player " << (int)color << " will be lead by " << AItoGive << std::endl;
+				tlog1 << "Player " << color << " will be lead by " << AItoGive << std::endl;
 			}
 			else 
 			{
@@ -390,7 +390,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 		{
 			auto cbc = make_shared<CBattleCallback>(gs, color, this);
 			battleCallbacks[color] = cbc;
-			if(!color)
+			if(color == PlayerColor(0))
 				battleints[color] = CDynLibHandler::getNewBattleAI(settings["server"]["neutralAI"].String());
 			else
 				battleints[color] = CDynLibHandler::getNewBattleAI("StupidAI");
@@ -401,13 +401,13 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 	if(si->mode == StartInfo::DUEL)
 	{
 		boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
-		CPlayerInterface *p = new CPlayerInterface(-1);
+		CPlayerInterface *p = new CPlayerInterface(PlayerColor::NEUTRAL); //TODO: check if neutral really works -- was -1, but CPlayerInterface seems to cooperate with this value not too well
 		p->observerInDuelMode = true;
-		battleints[254] = playerint[254] = p;
+		battleints[PlayerColor::UNFLAGGABLE] = playerint[PlayerColor::UNFLAGGABLE] = p;
 		privilagedBattleEventReceivers.push_back(p);
 		GH.curInt = p;
-		auto cb = make_shared<CCallback>(gs, -1, this);
-		battleCallbacks[-1] = callbacks[-1] = cb;
+		auto cb = make_shared<CCallback>(gs, boost::optional<PlayerColor>(), this);
+		battleCallbacks[PlayerColor::NEUTRAL] = callbacks[PlayerColor::NEUTRAL] = cb;
 		p->init(cb.get());
 		battleStarted(gs->curB);
 	}
@@ -443,7 +443,7 @@ void CClient::serialize( Handler &h, const int version )
 		ui8 players = playerint.size();
 		h & players;
 
-		for(std::map<ui8,CGameInterface *>::iterator i = playerint.begin(); i != playerint.end(); i++)
+		for(auto i = playerint.begin(); i != playerint.end(); i++)
 		{
 			h & i->first & i->second->dllName;
 			i->second->serialize(h,version);
@@ -457,14 +457,14 @@ void CClient::serialize( Handler &h, const int version )
 		for(int i=0; i < players; i++)
 		{
 			std::string dllname;
-			ui8 pid = 0; //fix for uninitialized warning
+			PlayerColor pid = PlayerColor(0); //fix for uninitialized warning
 			h & pid & dllname;
 
 
 			CGameInterface *nInt = NULL;
 			if(dllname.length())
 			{
-				if(pid == GameConstants::NEUTRAL_PLAYER)
+				if(pid == PlayerColor::NEUTRAL)
 				{
 					//CBattleCallback * cbc = new CBattleCallback(gs, pid, this);//FIXME: unused?
 					CBattleGameInterface *cbgi = CDynLibHandler::getNewBattleAI(dllname);
@@ -485,7 +485,7 @@ void CClient::serialize( Handler &h, const int version )
 			nInt->serialize(h, version);
 		}
 
-		if(!vstd::contains(battleints, GameConstants::NEUTRAL_PLAYER))
+		if(!vstd::contains(battleints, PlayerColor::NEUTRAL))
 			loadNeutralBattleAI();
 	}
 }
@@ -536,7 +536,7 @@ void CClient::stopConnection()
 		tlog0 << "Connection has been requested to be closed.\n";
 		boost::unique_lock<boost::mutex>(*serv->wmx);
 		CloseServer close_server;
-		sendRequest(&close_server, 255);
+		sendRequest(&close_server, PlayerColor::NEUTRAL);
 		tlog0 << "Sent closing signal to the server\n";
 	}
 
@@ -564,7 +564,7 @@ void CClient::battleStarted(const BattleInfo * info)
 {
 	BOOST_FOREACH(auto &battleCb, battleCallbacks)
 	{
-		if(vstd::contains(info->sides, battleCb.first)  ||  battleCb.first >= GameConstants::PLAYER_LIMIT)
+		if(vstd::contains(info->sides, battleCb.first)  ||  battleCb.first >= PlayerColor::PLAYER_LIMIT)
 			battleCb.second->setBattle(info);
 	}
 // 	BOOST_FOREACH(ui8 side, info->sides)
@@ -594,8 +594,8 @@ void CClient::battleStarted(const BattleInfo * info)
 		battleints[info->sides[0]]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 0);
 	if(vstd::contains(battleints,info->sides[1]))
 		battleints[info->sides[1]]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 1);
-	if(vstd::contains(battleints,254))
-		battleints[254]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 1);
+	if(vstd::contains(battleints,PlayerColor::UNFLAGGABLE))
+		battleints[PlayerColor::UNFLAGGABLE]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 1);
 
 	if(info->tacticDistance && vstd::contains(battleints,info->sides[info->tacticsSide]))
 	{
@@ -605,17 +605,17 @@ void CClient::battleStarted(const BattleInfo * info)
 
 void CClient::battleFinished()
 {
-	BOOST_FOREACH(ui8 side, gs->curB->sides)
+	BOOST_FOREACH(PlayerColor side, gs->curB->sides)
 		if(battleCallbacks.count(side))
 			battleCallbacks[side]->setBattle(nullptr);
 }
 
 void CClient::loadNeutralBattleAI()
 {
-	battleints[GameConstants::NEUTRAL_PLAYER] = CDynLibHandler::getNewBattleAI(settings["server"]["neutralAI"].String());
-	auto cbc = make_shared<CBattleCallback>(gs, GameConstants::NEUTRAL_PLAYER, this);
-	battleCallbacks[GameConstants::NEUTRAL_PLAYER] = cbc;
-	battleints[GameConstants::NEUTRAL_PLAYER]->init(cbc.get());
+	battleints[PlayerColor::NEUTRAL] = CDynLibHandler::getNewBattleAI(settings["server"]["neutralAI"].String());
+	auto cbc = make_shared<CBattleCallback>(gs, PlayerColor::NEUTRAL, this);
+	battleCallbacks[PlayerColor::NEUTRAL] = cbc;
+	battleints[PlayerColor::NEUTRAL]->init(cbc.get());
 }
 
 void CClient::commitPackage( CPackForClient *pack )
@@ -623,10 +623,10 @@ void CClient::commitPackage( CPackForClient *pack )
 	CommitPackage cp;
 	cp.freePack = false;
 	cp.packToCommit = pack;
-	sendRequest(&cp, 255);
+	sendRequest(&cp, PlayerColor::NEUTRAL);
 }
 
-int CClient::getLocalPlayer() const
+PlayerColor CClient::getLocalPlayer() const
 {
 	if(LOCPLINT)
 		return LOCPLINT->playerID;
@@ -648,7 +648,7 @@ void CClient::commenceTacticPhaseForInt(CBattleGameInterface *battleInt)
 		battleInt->yourTacticPhase(gs->curB->tacticDistance);
 		if(gs && !!gs->curB && gs->curB->tacticDistance) //while awaiting for end of tactics phase, many things can happen (end of battle... or game)
 		{
-			MakeAction ma(BattleAction::makeEndOFTacticPhase(battleInt->playerID));
+			MakeAction ma(BattleAction::makeEndOFTacticPhase(gs->curB->playerToSide(battleInt->playerID)));
 			sendRequest(&ma, battleInt->playerID);
 		}
 	} HANDLE_EXCEPTION
@@ -660,7 +660,7 @@ void CClient::invalidatePaths(const CGHeroInstance *h /*= NULL*/)
 		pathInfo->isValid = false;
 }
 
-int CClient::sendRequest(const CPack *request, TPlayerColor player)
+int CClient::sendRequest(const CPack *request, PlayerColor player)
 {
 	static ui32 requestCounter = 0;
 

+ 12 - 12
client/Client.h

@@ -113,12 +113,12 @@ class CClient : public IGameCallback
 {
 public:
 	CCallback *cb;
-	std::map<TPlayerColor,shared_ptr<CCallback> > callbacks; //callbacks given to player interfaces
-	std::map<TPlayerColor,shared_ptr<CBattleCallback> > battleCallbacks; //callbacks given to player interfaces
+	std::map<PlayerColor,shared_ptr<CCallback> > callbacks; //callbacks given to player interfaces
+	std::map<PlayerColor,shared_ptr<CBattleCallback> > battleCallbacks; //callbacks given to player interfaces
 	std::vector<IGameEventsReceiver*> privilagedGameEventReceivers; //scripting modules, spectator interfaces
 	std::vector<IBattleEventsReceiver*> privilagedBattleEventReceivers; //scripting modules, spectator interfaces
-	std::map<TPlayerColor,CGameInterface *> playerint;
-	std::map<TPlayerColor,CBattleGameInterface *> battleints;
+	std::map<PlayerColor,CGameInterface *> playerint;
+	std::map<PlayerColor,CBattleGameInterface *> battleints;
 	bool hotSeat;
 	CConnection *serv;
 	BattleAction *curbaction;
@@ -133,7 +133,7 @@ public:
 	std::queue<CPack *> packs;
 	boost::mutex packsM;
 
-	void waitForMoveAndSend(TPlayerColor color);
+	void waitForMoveAndSend(PlayerColor color);
 	//void sendRequest(const CPackForServer *request, bool waitForRealization);
 	CClient(void);
 	CClient(CConnection *con, StartInfo *si);
@@ -159,22 +159,22 @@ public:
 	boost::thread *connectionHandler; //thread running run() method
 
 	//////////////////////////////////////////////////////////////////////////
-	virtual int getLocalPlayer() const OVERRIDE;
+	virtual PlayerColor getLocalPlayer() const OVERRIDE;
 
 	//////////////////////////////////////////////////////////////////////////
 	//not working yet, will be implement somewhen later with support for local-sim-based gameplay
 	void changeSpells(const CGHeroInstance * hero, bool give, const std::set<SpellID> &spells) OVERRIDE {};
 	bool removeObject(const CGObjectInstance * obj) OVERRIDE {return false;};
 	void setBlockVis(ObjectInstanceID objid, bool bv) OVERRIDE {};
-	void setOwner(const CGObjectInstance * obj, TPlayerColor owner) OVERRIDE {};
+	void setOwner(const CGObjectInstance * obj, PlayerColor owner) OVERRIDE {};
 	void setHoverName(const CGObjectInstance * obj, MetaString * name) OVERRIDE {};
 	void changePrimSkill(const CGHeroInstance * hero, PrimarySkill::PrimarySkill which, si64 val, bool abs=false) OVERRIDE {};
 	void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false) OVERRIDE {}; 
 	void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback) OVERRIDE {};
 	ui32 showBlockingDialog(BlockingDialog *iw) OVERRIDE {return 0;}; //synchronous version of above
 	void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits, const boost::function<void()> &cb) OVERRIDE {};
-	void showThievesGuildWindow(TPlayerColor player, ObjectInstanceID requestingObjId) OVERRIDE {};
-	void giveResource(TPlayerColor player, Res::ERes which, int val) OVERRIDE {};
+	void showThievesGuildWindow(PlayerColor player, ObjectInstanceID requestingObjId) OVERRIDE {};
+	void giveResource(PlayerColor player, Res::ERes which, int val) OVERRIDE {};
 
 	void giveCreatures(const CArmedInstance * objid, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove) OVERRIDE {};
 	void takeCreatures(ObjectInstanceID objid, const std::vector<CStackBasicDescriptor> &creatures) OVERRIDE {};
@@ -203,11 +203,11 @@ public:
 	void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false) OVERRIDE {}; //if any of armies is hero, hero will be used
 	void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false) OVERRIDE {}; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle
 	void setAmount(ObjectInstanceID objid, ui32 val) OVERRIDE {};
-	bool moveHero(ObjectInstanceID hid, int3 dst, ui8 instant, TPlayerColor asker = GameConstants::NEUTRAL_PLAYER) OVERRIDE {return false;};
+	bool moveHero(ObjectInstanceID hid, int3 dst, ui8 instant, PlayerColor asker = PlayerColor::NEUTRAL) OVERRIDE {return false;};
 	void giveHeroBonus(GiveBonus * bonus) OVERRIDE {};
 	void setMovePoints(SetMovePoints * smp) OVERRIDE {};
 	void setManaPoints(ObjectInstanceID hid, int val) OVERRIDE {};
-	void giveHero(ObjectInstanceID id, TPlayerColor player) OVERRIDE {};
+	void giveHero(ObjectInstanceID id, PlayerColor player) OVERRIDE {};
 	void changeObjPos(ObjectInstanceID objid, int3 newPos, ui8 flags) OVERRIDE {};
 	void sendAndApply(CPackForClient * info) OVERRIDE {};
 	void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2) OVERRIDE {};
@@ -217,7 +217,7 @@ public:
 	friend class CBattleCallback; //handling players actions
 	friend void processCommand(const std::string &message, CClient *&client); //handling console
 	
-	int sendRequest(const CPack *request, TPlayerColor player); //returns ID given to that request
+	int sendRequest(const CPack *request, PlayerColor player); //returns ID given to that request
 
 	void handlePack( CPack * pack ); //applies the given pack and deletes it
 	void battleStarted(const BattleInfo * info);

+ 13 - 13
client/GUIClasses.cpp

@@ -644,11 +644,11 @@ bool CGarrisonInt::getSplittingMode()
 
 void CGarrisonInt::setArmy(const CArmedInstance *army, bool bottomGarrison)
 {
-	owned[bottomGarrison] =  army ? (army->tempOwner == LOCPLINT->playerID || army->tempOwner == GameConstants::UNFLAGGABLE_PLAYER) : false;
+	owned[bottomGarrison] =  army ? (army->tempOwner == LOCPLINT->playerID || army->tempOwner == PlayerColor::UNFLAGGABLE) : false;
 	armedObjs[bottomGarrison] = army;
 }
 
-CInfoWindow::CInfoWindow(std::string Text, int player, const TCompsInfo &comps, const TButtonsInfo &Buttons, bool delComps)
+CInfoWindow::CInfoWindow(std::string Text, PlayerColor player, const TCompsInfo &comps, const TButtonsInfo &Buttons, bool delComps)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 
@@ -721,7 +721,7 @@ void CInfoWindow::showAll(SDL_Surface * to)
 	CIntObject::showAll(to);
 }
 
-void CInfoWindow::showYesNoDialog(const std::string & text, const std::vector<CComponent*> *components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, bool DelComps, int player)
+void CInfoWindow::showYesNoDialog(const std::string & text, const std::vector<CComponent*> *components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, bool DelComps, PlayerColor player)
 {
 	assert(!LOCPLINT || LOCPLINT->showingDialog->get());
 	std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
@@ -736,7 +736,7 @@ void CInfoWindow::showYesNoDialog(const std::string & text, const std::vector<CC
 	GH.pushInt(temp);
 }
 
-CInfoWindow * CInfoWindow::create(const std::string &text, int playerID /*= 1*/, const std::vector<CComponent*> *components /*= NULL*/, bool DelComps)
+CInfoWindow * CInfoWindow::create(const std::string &text, PlayerColor playerID /*= 1*/, const std::vector<CComponent*> *components /*= NULL*/, bool DelComps)
 {
 	std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
 	pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0));
@@ -1262,7 +1262,7 @@ void CSelWindow::selectionChange(unsigned to)
 	redraw();
 }
 
-CSelWindow::CSelWindow(const std::string &Text, int player, int charperline, const std::vector<CSelectableComponent*> &comps, const std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, int askID)
+CSelWindow::CSelWindow(const std::string &Text, PlayerColor player, int charperline, const std::vector<CSelectableComponent*> &comps, const std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, int askID)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	ID = askID;
@@ -2360,8 +2360,8 @@ std::vector<int> *CTradeWindow::getItemsIds(bool Left)
 		{
 		case PLAYER:
 			ids = new std::vector<int>;
-			for(int i = 0; i < GameConstants::PLAYER_LIMIT; i++)
-				if(i != LOCPLINT->playerID && LOCPLINT->cb->getPlayerStatus(i) == EPlayerStatus::INGAME)
+			for(int i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++)
+				if(PlayerColor(i) != LOCPLINT->playerID && LOCPLINT->cb->getPlayerStatus(PlayerColor(i)) == EPlayerStatus::INGAME)
 					ids->push_back(i);
 			break;
 
@@ -4028,7 +4028,7 @@ CGarrisonWindow::CGarrisonWindow( const CArmedInstance *up, const CGHeroInstance
 	}
 	new CLabel(275, 30, FONT_BIG, CENTER, Colors::YELLOW, titleText);
 
-	new CAnimImage("CREST58", garr->armedObjs[0]->getOwner(), 0, 28, 124);
+	new CAnimImage("CREST58", garr->armedObjs[0]->getOwner().getNum(), 0, 28, 124);
 	new CAnimImage("PortraitsLarge", dynamic_cast<const CGHeroInstance*>(garr->armedObjs[1])->portrait, 0, 29, 222);
 }
 
@@ -5737,7 +5737,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner):
 
 	//data for information table:
 	// fields[row][column] = list of id's of players for this box
-	static std::vector< std::vector< TPlayerColor > > SThievesGuildInfo::* fields[] =
+	static std::vector< std::vector< PlayerColor > > SThievesGuildInfo::* fields[] =
 		{ &SThievesGuildInfo::numOfTowns, &SThievesGuildInfo::numOfHeroes,       &SThievesGuildInfo::gold,
 		  &SThievesGuildInfo::woodOre,    &SThievesGuildInfo::mercSulfCrystGems, &SThievesGuildInfo::obelisks,
 		  &SThievesGuildInfo::artifacts,  &SThievesGuildInfo::army,              &SThievesGuildInfo::income };
@@ -5769,7 +5769,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner):
 	{
 		for(int b=0; b<(tgi .* fields[g]).size(); ++b) //by places (1st, 2nd, ...)
 		{
-			std::vector<TPlayerColor> &players = (tgi .* fields[g])[b]; //get players with this place in this line
+			std::vector<PlayerColor> &players = (tgi .* fields[g])[b]; //get players with this place in this line
 
 			//position of box
 			int xpos = 259 + 66 * b;
@@ -5788,7 +5788,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner):
 
 				for (size_t i=0; i< rowLength[j]; i++)
 				{
-					new CAnimImage("itgflags", players[i + j*4], 0, rowStartX + i*12, rowStartY);
+					new CAnimImage("itgflags", players[i + j*4].getNum(), 0, rowStartX + i*12, rowStartY);
 				}
 			}
 		}
@@ -5802,7 +5802,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner):
 	{
 		if(iter.second.portrait >= 0)
 		{
-			new CPicture(colorToBox[iter.first], 253 + 66 * counter, 334);
+			new CPicture(colorToBox[iter.first.getNum()], 253 + 66 * counter, 334);
 			new CAnimImage("PortraitsSmall", iter.second.portrait, 0, 260 + 66 * counter, 360);
 			//TODO: r-click info:
 			// - r-click on hero
@@ -6005,7 +6005,7 @@ void CRClickPopup::close()
 
 void CRClickPopup::createAndPush(const std::string &txt, const CInfoWindow::TCompsInfo &comps)
 {
-	int player = LOCPLINT ? LOCPLINT->playerID : 1; //if no player, then use blue
+	PlayerColor player = LOCPLINT ? LOCPLINT->playerID : PlayerColor(1); //if no player, then use blue
 
 	CSimpleWindow * temp = new CInfoWindow(txt, player, comps);
 	temp->center(Point(GH.current->motion)); //center on mouse

+ 4 - 4
client/GUIClasses.h

@@ -100,12 +100,12 @@ public:
 	void showAll(SDL_Surface * to);
 	void sliderMoved(int to);
 
-	CInfoWindow(std::string Text, int player, const TCompsInfo &comps = TCompsInfo(), const TButtonsInfo &Buttons = TButtonsInfo(), bool delComps = true); //c-tor
+	CInfoWindow(std::string Text, PlayerColor player, const TCompsInfo &comps = TCompsInfo(), const TButtonsInfo &Buttons = TButtonsInfo(), bool delComps = true); //c-tor
 	CInfoWindow(); //c-tor
 	~CInfoWindow(); //d-tor
 
-	static void showYesNoDialog( const std::string & text, const std::vector<CComponent*> *components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, bool DelComps = true, int player = 1); //use only before the game starts! (showYesNoDialog in LOCPLINT must be used then)
-	static CInfoWindow *create(const std::string &text, int playerID = 1, const std::vector<CComponent*> *components = NULL, bool DelComps = false);
+	static void showYesNoDialog( const std::string & text, const std::vector<CComponent*> *components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, bool DelComps = true, PlayerColor player = PlayerColor(1)); //use only before the game starts! (showYesNoDialog in LOCPLINT must be used then)
+	static CInfoWindow *create(const std::string &text, PlayerColor playerID = PlayerColor(1), const std::vector<CComponent*> *components = NULL, bool DelComps = false);
 
 	/// create text from title and description: {title}\n\n description
 	static std::string genText(std::string title, std::string description);
@@ -117,7 +117,7 @@ class CSelWindow : public CInfoWindow
 public:
 	void selectionChange(unsigned to);
 	void madeChoice(); //looks for selected component and calls callback
-	CSelWindow(const std::string& text, int player, int charperline ,const std::vector<CSelectableComponent*> &comps, const std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, int askID); //c-tor
+	CSelWindow(const std::string& text, PlayerColor player, int charperline ,const std::vector<CSelectableComponent*> &comps, const std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, int askID); //c-tor
 	CSelWindow(){}; //c-tor
 	//notification - this class inherits important destructor from CInfoWindow
 };

+ 11 - 11
client/Graphics.cpp

@@ -51,7 +51,7 @@ void Graphics::loadPaletteAndColors()
 
 	playerColorPalette = new SDL_Color[256];
 	neutralColor = new SDL_Color;
-	playerColors = new SDL_Color[GameConstants::PLAYER_LIMIT];
+	playerColors = new SDL_Color[PlayerColor::PLAYER_LIMIT_I];
 	int startPoint = 24; //beginning byte; used to read
 	for(int i=0; i<256; ++i)
 	{
@@ -278,18 +278,18 @@ void Graphics::loadHeroFlags()
 	tlog0 << "Loading and transforming heroes' flags: "<<th.getDiff()<<std::endl;
 }
 
-void Graphics::blueToPlayersAdv(SDL_Surface * sur, int player)
+void Graphics::blueToPlayersAdv(SDL_Surface * sur, PlayerColor player)
 {
 // 	if(player==1) //it is actually blue...
 // 		return;
 	if(sur->format->BitsPerPixel == 8)
 	{
 		SDL_Color *palette = NULL;
-		if(player < GameConstants::PLAYER_LIMIT && player >= 0)
+		if(player < PlayerColor::PLAYER_LIMIT)
 		{
-			palette = playerColorPalette + 32*player;
+			palette = playerColorPalette + 32*player.getNum();
 		}
-		else if(player == 255 || player == -1)
+		else if(player == PlayerColor::NEUTRAL)
 		{
 			palette = neutralColorPalette;
 		}
@@ -321,9 +321,9 @@ void Graphics::blueToPlayersAdv(SDL_Surface * sur, int player)
 						sort1.push_back(cp[1]);
 						sort1.push_back(cp[2]);
 						std::vector< std::pair<long long int, Uint8*> > sort2;
-						sort2.push_back(std::make_pair(graphics->playerColors[player].r, &(cp[0])));
-						sort2.push_back(std::make_pair(graphics->playerColors[player].g, &(cp[1])));
-						sort2.push_back(std::make_pair(graphics->playerColors[player].b, &(cp[2])));
+						sort2.push_back(std::make_pair(graphics->playerColors[player.getNum()].r, &(cp[0])));
+						sort2.push_back(std::make_pair(graphics->playerColors[player.getNum()].g, &(cp[1])));
+						sort2.push_back(std::make_pair(graphics->playerColors[player.getNum()].b, &(cp[2])));
 						std::sort(sort1.begin(), sort1.end());
 						if(sort2[0].first>sort2[1].first)
 							std::swap(sort2[0], sort2[1]);
@@ -349,9 +349,9 @@ void Graphics::blueToPlayersAdv(SDL_Surface * sur, int player)
 						sort1.push_back(cp[1]);
 						sort1.push_back(cp[0]);
 						std::vector< std::pair<long long int, Uint8*> > sort2;
-						sort2.push_back(std::make_pair(graphics->playerColors[player].r, &(cp[2])));
-						sort2.push_back(std::make_pair(graphics->playerColors[player].g, &(cp[1])));
-						sort2.push_back(std::make_pair(graphics->playerColors[player].b, &(cp[0])));
+						sort2.push_back(std::make_pair(graphics->playerColors[player.getNum()].r, &(cp[2])));
+						sort2.push_back(std::make_pair(graphics->playerColors[player.getNum()].g, &(cp[1])));
+						sort2.push_back(std::make_pair(graphics->playerColors[player.getNum()].b, &(cp[0])));
 						std::sort(sort1.begin(), sort1.end());
 						if(sort2[0].first>sort2[1].first)
 							std::swap(sort2[0], sort2[1]);

+ 1 - 1
client/Graphics.h

@@ -74,7 +74,7 @@ public:
 	void loadHeroAnims();
 	CDefEssential *  loadHeroAnim(const std::string &name, const std::vector<std::pair<int,int> > &rotations);
 	void loadErmuToPicture();
-	void blueToPlayersAdv(SDL_Surface * sur, int player); //replaces blue interface colour with a color of player
+	void blueToPlayersAdv(SDL_Surface * sur, PlayerColor player); //replaces blue interface colour with a color of player
 	void loadFonts();
 };
 

+ 21 - 21
client/NetPacksClient.cpp

@@ -76,8 +76,8 @@
 #define CALL_IN_ALL_INTERFACES(function, ...)							\
 	do																	\
 	{																	\
-		std::map<ui8, CGameInterface*> ints = cl->playerint;			\
-		for(std::map<ui8, CGameInterface*>::iterator i = ints.begin(); i != ints.end(); i++)\
+		std::map<PlayerColor, CGameInterface*> ints = cl->playerint;			\
+		for(auto i = ints.begin(); i != ints.end(); i++)\
 			CALL_ONLY_THAT_INTERFACE(i->first, function, __VA_ARGS__);	\
 	} while(0)
 
@@ -261,8 +261,8 @@ void GiveBonus::applyCl( CClient *cl )
 		break;
 	case PLAYER:
 		{
-			const PlayerState *p = GS(cl)->getPlayer(id);
-			INTERFACE_CALL_IF_PRESENT(id, playerBonusChanged, *p->getBonusList().back(), true);
+			const PlayerState *p = GS(cl)->getPlayer(PlayerColor(id));
+			INTERFACE_CALL_IF_PRESENT(PlayerColor(id), playerBonusChanged, *p->getBonusList().back(), true);
 		}
 		break;
 	}
@@ -302,7 +302,7 @@ void RemoveBonus::applyCl( CClient *cl )
 	case PLAYER:
 		{
 			//const PlayerState *p = GS(cl)->getPlayer(id);
-			INTERFACE_CALL_IF_PRESENT(id, playerBonusChanged, bonus, false);
+			INTERFACE_CALL_IF_PRESENT(PlayerColor(id), playerBonusChanged, bonus, false);
 		}
 		break;
 	}
@@ -327,7 +327,7 @@ void RemoveObject::applyFirstCl( CClient *cl )
 
 	int3 pos = o->visitablePos();
 	//notify interfaces about removal
-	for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
+	for(auto i=cl->playerint.begin(); i!=cl->playerint.end(); i++)
 	{
 		if(GS(cl)->isVisible(o, i->first))
 			i->second->objectRemoved(o);
@@ -344,9 +344,9 @@ void TryMoveHero::applyFirstCl( CClient *cl )
 	CGHeroInstance *h = GS(cl)->getHero(id);
 
 	//check if playerint will have the knowledge about movement - if not, directly update maphandler
-	for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
+	for(auto i=cl->playerint.begin(); i!=cl->playerint.end(); i++)
 	{
-		if(i->first >= GameConstants::PLAYER_LIMIT)
+		if(i->first >= PlayerColor::PLAYER_LIMIT)
 			continue;
 		TeamState *t = GS(cl)->getPlayerTeam(i->first);
 		if((t->fogOfWarMap[start.x-1][start.y][start.z] || t->fogOfWarMap[end.x-1][end.y][end.z])
@@ -375,16 +375,16 @@ void TryMoveHero::applyCl( CClient *cl )
 	if(result == EMBARK)
 		CGI->mh->hideObject(h->boat);
 
-	int player = h->tempOwner;
+	PlayerColor player = h->tempOwner;
 
 	BOOST_FOREACH(auto &i, cl->playerint)
 		if(cl->getPlayerRelations(i.first, player) != PlayerRelations::ENEMIES)
 			i.second->tileRevealed(fowRevealed);
 
 	//notify interfaces about move
-	for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
+	for(auto i=cl->playerint.begin(); i!=cl->playerint.end(); i++)
 	{
-		if(i->first >= GameConstants::PLAYER_LIMIT) continue;
+		if(i->first >= PlayerColor::PLAYER_LIMIT) continue;
 		TeamState *t = GS(cl)->getPlayerTeam(i->first);
 		if(t->fogOfWarMap[start.x-1][start.y][start.z] || t->fogOfWarMap[end.x-1][end.y][end.z])
 		{
@@ -435,7 +435,7 @@ void SetAvailableCreatures::applyCl( CClient *cl )
 
 	//inform order about the change
 
-	int p = -1;
+	PlayerColor p;
 	if(dw->ID == Obj::WAR_MACHINE_FACTORY) //War Machines Factory is not flaggable, it's "owned" by visitor
 		p = cl->getTile(dw->visitablePos())->visitableObjects.back()->tempOwner;
 	else
@@ -450,7 +450,7 @@ void SetHeroesInTown::applyCl( CClient *cl )
 	CGHeroInstance *hGarr  = GS(cl)->getHero(this->garrison);
 	CGHeroInstance *hVisit = GS(cl)->getHero(this->visiting);
 
-	std::set<TPlayerColor> playersToNotify;
+	std::set<PlayerColor> playersToNotify;
 
 	if(vstd::contains(cl->playerint,t->tempOwner)) // our town
 		playersToNotify.insert(t->tempOwner);
@@ -561,7 +561,7 @@ void CommanderLevelUp::applyCl( CClient *cl )
 {
 	CCommanderInstance * commander = GS(cl)->getHero(heroid)->commander;
 	assert (commander);
-	ui8 player = commander->armyObj->tempOwner;
+	PlayerColor player = commander->armyObj->tempOwner;
 	if (commander->armyObj && vstd::contains(cl->playerint, player)) //is it possible for Commander to exist beyond armed instance?
 	{
 		cl->playerint[player]->commanderGotLevel(commander, skills, queryID);
@@ -611,7 +611,7 @@ void BattleSetActiveStack::applyCl( CClient *cl )
 		return;
 
 	const CStack * activated = GS(cl)->curB->battleGetStackByID(stack);
-	int playerToCall = -1; //player that will move activated stack
+	PlayerColor playerToCall; //player that will move activated stack
 	if( activated->hasBonusOfType(Bonus::HYPNOTIZED) )
 	{
 		playerToCall = ( GS(cl)->curB->sides[0] == activated->owner ? GS(cl)->curB->sides[1] : GS(cl)->curB->sides[0] );
@@ -698,7 +698,7 @@ void BattleResultsApplied::applyCl( CClient *cl )
 {
 	INTERFACE_CALL_IF_PRESENT(player1, battleResultsApplied);
 	INTERFACE_CALL_IF_PRESENT(player2, battleResultsApplied);
-	INTERFACE_CALL_IF_PRESENT(254, battleResultsApplied);
+	INTERFACE_CALL_IF_PRESENT(PlayerColor::UNFLAGGABLE, battleResultsApplied);
 	if(GS(cl)->initialOpts->mode == StartInfo::DUEL)
 	{
 		cl->terminate = true;
@@ -823,7 +823,7 @@ void SaveGame::applyCl(CClient *cl)
 void PlayerMessage::applyCl(CClient *cl)
 {
 	std::ostringstream str;
-	str << "Player "<<(int)player<<" sends a message: " << text;
+	str << "Player "<< player <<" sends a message: " << text;
 
 	tlog4 << str.str() << std::endl;
 	if(LOCPLINT)
@@ -881,7 +881,7 @@ void OpenWindow::applyCl(CClient *cl)
 		{
 			//displays Thieves' Guild window (when hero enters Den of Thieves)
 			const CGObjectInstance *obj = cl->getObj(ObjectInstanceID(id2));
-			INTERFACE_CALL_IF_PRESENT(id1, showThievesGuildWindow, obj);
+			INTERFACE_CALL_IF_PRESENT(PlayerColor(id1), showThievesGuildWindow, obj);
 		}
 		break;
 	case UNIVERSITY_WINDOW:
@@ -911,7 +911,7 @@ void OpenWindow::applyCl(CClient *cl)
 		break;
 	case PUZZLE_MAP:
 		{
-			INTERFACE_CALL_IF_PRESENT(id1, showPuzzleMap);
+			INTERFACE_CALL_IF_PRESENT(PlayerColor(id1), showPuzzleMap);
 		}
 		break;
 	case TAVERN_WINDOW:
@@ -935,7 +935,7 @@ void NewObject::applyCl(CClient *cl)
 	const CGObjectInstance *obj = cl->getObj(id);
 	CGI->mh->printObject(obj);
 
-	for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
+	for(auto i=cl->playerint.begin(); i!=cl->playerint.end(); i++)
 	{
 		if(GS(cl)->isVisible(obj, i->first))
 			i->second->newObject(obj);
@@ -946,7 +946,7 @@ void SetAvailableArtifacts::applyCl(CClient *cl)
 {
 	if(id < 0) //artifact merchants globally
 	{
-		for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
+		for(auto i=cl->playerint.begin(); i!=cl->playerint.end(); i++)
 			i->second->availableArtifactsChanged(NULL);
 	}
 	else

+ 4 - 4
client/UIFramework/CIntObjectClasses.cpp

@@ -162,14 +162,14 @@ void CPicture::createSimpleRect(const Rect &r, bool screenFormat, ui32 color)
 	freeSurf = true;
 }
 
-void CPicture::colorizeAndConvert(int player)
+void CPicture::colorizeAndConvert(PlayerColor player)
 {
 	assert(bg);
 	colorize(player);
 	convertToScreenBPP();
 }
 
-void CPicture::colorize(int player)
+void CPicture::colorize(PlayerColor player)
 {
 	assert(bg);
 	assert(bg->format->BitsPerPixel == 8);
@@ -428,7 +428,7 @@ void CAdventureMapButton::setImage(CAnimation* anim, bool playerColoredButton, i
 	pos.h = image->pos.h;
 }
 
-void CAdventureMapButton::setPlayerColor(int player)
+void CAdventureMapButton::setPlayerColor(PlayerColor player)
 {
 	if (image)
 		image->playerColored(player);
@@ -1866,7 +1866,7 @@ void CWindowObject::showAll(SDL_Surface *to)
 {
 	CIntObject::showAll(to);
 	if ((options & BORDERED) && (pos.h != to->h || pos.w != to->w))
-		CMessage::drawBorder(LOCPLINT ? LOCPLINT->playerID : 1, to, pos.w+28, pos.h+29, pos.x-14, pos.y-15);
+		CMessage::drawBorder(LOCPLINT ? LOCPLINT->playerID : PlayerColor(1), to, pos.w+28, pos.h+29, pos.x-14, pos.y-15);
 }
 
 void CWindowObject::close()

+ 3 - 3
client/UIFramework/CIntObjectClasses.h

@@ -63,8 +63,8 @@ public:
 	void show(SDL_Surface * to);
 	void showAll(SDL_Surface * to);
 	void convertToScreenBPP();
-	void colorizeAndConvert(int player);
-	void colorize(int player);
+	void colorizeAndConvert(PlayerColor player);
+	void colorize(PlayerColor player);
 };
 
 /// area filled with specific texture
@@ -147,7 +147,7 @@ public:
 
 	void setIndex(size_t index, bool playerColoredButton=false);
 	void setImage(CAnimation* anim, bool playerColoredButton=false, int animFlags=0);
-	void setPlayerColor(int player);
+	void setPlayerColor(PlayerColor player);
 	void showAll(SDL_Surface * to);
 };
 

+ 4 - 4
client/UIFramework/SDL_Extensions.cpp

@@ -580,15 +580,15 @@ void CSDL_Ext::drawDashedBorder(SDL_Surface * sur, const Rect &r, const int3 &co
 	}
 }
 
-void CSDL_Ext::setPlayerColor(SDL_Surface * sur, ui8 player)
+void CSDL_Ext::setPlayerColor(SDL_Surface * sur, PlayerColor player)
 {
-	if(player==254)
+	if(player==PlayerColor::UNFLAGGABLE)
 		return;
 	if(sur->format->BitsPerPixel==8)
 	{
-		SDL_Color *color = (player == 255
+		SDL_Color *color = (player == PlayerColor::NEUTRAL
 							? graphics->neutralColor
-							: &graphics->playerColors[player]);
+							: &graphics->playerColors[player.getNum()]);
 		SDL_SetColors(sur, color, 5, 1);
 	}
 	else

+ 1 - 1
client/UIFramework/SDL_Extensions.h

@@ -176,7 +176,7 @@ namespace CSDL_Ext
 	void drawBorder(SDL_Surface * sur, int x, int y, int w, int h, const int3 &color);
 	void drawBorder(SDL_Surface * sur, const SDL_Rect &r, const int3 &color);
 	void drawDashedBorder(SDL_Surface * sur, const Rect &r, const int3 &color);
-	void setPlayerColor(SDL_Surface * sur, ui8 player); //sets correct color of flags; -1 for neutral
+	void setPlayerColor(SDL_Surface * sur, PlayerColor player); //sets correct color of flags; -1 for neutral
 	std::string processStr(std::string str, std::vector<std::string> & tor); //replaces %s in string
 	SDL_Surface * newSurface(int w, int h, SDL_Surface * mod=screen); //creates new surface, with flags/format same as in surface given
 	SDL_Surface * copySurface(SDL_Surface * mod); //returns copy of given surface

+ 5 - 5
client/mapHandler.cpp

@@ -524,7 +524,7 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
 				if (!graphics->getDef(obj))
 					processDef(obj->defInfo);
 
-				ui8 color = obj->tempOwner;
+				PlayerColor color = obj->tempOwner;
 
 				//checking if object has non-empty graphic on this tile
 				if(obj->ID != Obj::HERO && !obj->coveringAt(top_tile.x + bx - obj->pos.x, top_tile.y + by - obj->pos.y))
@@ -557,7 +557,7 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
 
 					if(themp) //hero
 					{
-						if(themp->tempOwner >= GameConstants::PLAYER_LIMIT) //Neutral hero?
+						if(themp->tempOwner >= PlayerColor::PLAYER_LIMIT) //Neutral hero?
 						{
 							tlog1 << "A neutral hero (" << themp->name << ") at " << themp->pos << ". Should not happen!\n";
 							continue;
@@ -613,7 +613,7 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
 						//printing flag
 						pp.y+=IMGVAL*2-32;
 						sr2.y-=16;
-						CSDL_Ext::blitSurface((graphics->*flg)[color]->ourImages[gg+heroAnim%IMGVAL+35].bitmap, &pp, extSurf, &sr2);
+						CSDL_Ext::blitSurface((graphics->*flg)[color.getNum()]->ourImages[gg+heroAnim%IMGVAL+35].bitmap, &pp, extSurf, &sr2);
 					}
 					else //hero / boat stands still
 					{
@@ -639,7 +639,7 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
 							bufr.h = 64;
 							bufr.w = 96;
 							if(bufr.x-extRect->x>-64)
-								CSDL_Ext::blitSurface((graphics->*flg)[color]->ourImages[getHeroFrameNum(dir, false) *8+(heroAnim/4)%IMGVAL].bitmap, NULL, extSurf, &bufr);
+								CSDL_Ext::blitSurface((graphics->*flg)[color.getNum()]->ourImages[getHeroFrameNum(dir, false) *8+(heroAnim/4)%IMGVAL].bitmap, NULL, extSurf, &bufr);
 						}
 					}
 				}
@@ -649,7 +649,7 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
 					SDL_Surface *bitmap = ourImages[(anim+getPhaseShift(obj))%ourImages.size()].bitmap;
 
 					//setting appropriate flag color
-					if(color < 8 || color==255)
+					if(color < PlayerColor::PLAYER_LIMIT || color==PlayerColor::NEUTRAL)
 						CSDL_Ext::setPlayerColor(bitmap, color);
 
 					if( obj->hasShadowAt(top_tile.x + bx - obj->pos.x, top_tile.y + by - obj->pos.y) )

+ 12 - 12
lib/BattleState.cpp

@@ -141,8 +141,8 @@ int BattleInfo::calculateSpellDuration( const CSpell * spell, const CGHeroInstan
 CStack * BattleInfo::generateNewStack(const CStackInstance &base, bool attackerOwned, SlotID slot, BattleHex position) const
 {
 	int stackID = getIdForNewStack();
-	int owner = attackerOwned ? sides[0] : sides[1];
-	assert((owner >= GameConstants::PLAYER_LIMIT)  ||
+	PlayerColor owner = attackerOwned ? sides[0] : sides[1];
+	assert((owner >= PlayerColor::PLAYER_LIMIT)  ||
 		   (base.armyObj && base.armyObj->tempOwner == owner));
 
 	CStack * ret = new CStack(&base, owner, stackID, attackerOwned, slot);
@@ -154,7 +154,7 @@ CStack * BattleInfo::generateNewStack(const CStackInstance &base, bool attackerO
 CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, bool attackerOwned, SlotID slot, BattleHex position) const
 {
 	int stackID = getIdForNewStack();
-	int owner = attackerOwned ? sides[0] : sides[1];
+	PlayerColor owner = attackerOwned ? sides[0] : sides[1];
 	CStack * ret = new CStack(&base, owner, stackID, attackerOwned, slot);
 	ret->position = position;
 	ret->state.insert(EBattleStackState::ALIVE);  //alive state indication
@@ -353,8 +353,8 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp
 	curB->castSpells[0] = curB->castSpells[1] = 0;
 	curB->sides[0] = armies[0]->tempOwner;
 	curB->sides[1] = armies[1]->tempOwner;
-	if(curB->sides[1] == GameConstants::UNFLAGGABLE_PLAYER)
-		curB->sides[1] = GameConstants::NEUTRAL_PLAYER;
+	if(curB->sides[1] == PlayerColor::UNFLAGGABLE)
+		curB->sides[1] = PlayerColor::NEUTRAL;
 
 	std::vector<CStack*> & stacks = (curB->stacks);
 
@@ -708,7 +708,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp
 	return curB;
 }
 
-const CGHeroInstance * BattleInfo::getHero( TPlayerColor player ) const
+const CGHeroInstance * BattleInfo::getHero( PlayerColor player ) const
 {
 	assert(sides[0] == player || sides[1] == player);
 	if(heroes[0] && heroes[0]->getOwner() == player)
@@ -717,7 +717,7 @@ const CGHeroInstance * BattleInfo::getHero( TPlayerColor player ) const
 	return heroes[1];
 }
 
-std::vector<ui32> BattleInfo::calculateResistedStacks(const CSpell * sp, const CGHeroInstance * caster, const CGHeroInstance * hero2, const std::set<const CStack*> affectedCreatures, int casterSideOwner, ECastingMode::ECastingMode mode, int usedSpellPower, int spellLevel) const
+std::vector<ui32> BattleInfo::calculateResistedStacks(const CSpell * sp, const CGHeroInstance * caster, const CGHeroInstance * hero2, const std::set<const CStack*> affectedCreatures, PlayerColor casterSideOwner, ECastingMode::ECastingMode mode, int usedSpellPower, int spellLevel) const
 {
 	std::vector<ui32> ret;
 	for(auto it = affectedCreatures.begin(); it != affectedCreatures.end(); ++it)
@@ -766,12 +766,12 @@ std::vector<ui32> BattleInfo::calculateResistedStacks(const CSpell * sp, const C
 	return ret;
 }
 
-TPlayerColor BattleInfo::theOtherPlayer(TPlayerColor player) const
+PlayerColor BattleInfo::theOtherPlayer(PlayerColor player) const
 {
 	return sides[!whatSide(player)];
 }
 
-ui8 BattleInfo::whatSide(TPlayerColor player) const
+ui8 BattleInfo::whatSide(PlayerColor player) const
 {
 	for(int i = 0; i < ARRAY_COUNT(sides); i++)
 		if(sides[i] == player)
@@ -842,7 +842,7 @@ BattleInfo::BattleInfo()
 	setNodeType(BATTLE);
 }
 
-CStack::CStack(const CStackInstance *Base, int O, int I, bool AO, SlotID S)
+CStack::CStack(const CStackInstance *Base, PlayerColor O, int I, bool AO, SlotID S)
 	: base(Base), ID(I), owner(O), slot(S), attackerOwned(AO),
 	counterAttacks(1)
 {
@@ -856,7 +856,7 @@ CStack::CStack()
 	init();
 	setNodeType(STACK_BATTLE);
 }
-CStack::CStack(const CStackBasicDescriptor *stack, int O, int I, bool AO, SlotID S)
+CStack::CStack(const CStackBasicDescriptor *stack, PlayerColor O, int I, bool AO, SlotID S)
 	: base(NULL), ID(I), owner(O), slot(S), attackerOwned(AO), counterAttacks(1)
 {
 	type = stack->type;
@@ -871,7 +871,7 @@ void CStack::init()
 	ID = -1;
 	count = baseAmount = -1;
 	firstHPleft = -1;
-	owner = GameConstants::NEUTRAL_PLAYER;
+	owner = PlayerColor::NEUTRAL;
 	slot = SlotID(255);
 	attackerOwned = false;
 	position = BattleHex();

+ 8 - 8
lib/BattleState.h

@@ -45,7 +45,7 @@ struct DLL_LINKAGE SiegeInfo
 
 struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallback
 {
-	TPlayerColor sides[2]; //sides[0] - attacker, sides[1] - defender
+	PlayerColor sides[2]; //sides[0] - attacker, sides[1] - defender
 	si32 round, activeStack, selectedStack;
 	CGTownInstance::EFortLevel siege;
 	const CGTownInstance * town; //used during town siege - id of attacked town; -1 if not town defence
@@ -115,10 +115,10 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
 	ui32 calculateHealedHP(const CSpell * spell, int usedSpellPower, int spellSchoolLevel, const CStack * stack) const; //healing spells casted by stacks
 	bool resurrects(SpellID spellid) const; //TODO: move it to spellHandler?
 
-	const CGHeroInstance * getHero(TPlayerColor player) const; //returns fighting hero that belongs to given player
+	const CGHeroInstance * getHero(PlayerColor player) const; //returns fighting hero that belongs to given player
 
 
-	std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHeroInstance * caster, const CGHeroInstance * hero2, const std::set<const CStack*> affectedCreatures, int casterSideOwner, ECastingMode::ECastingMode mode, int usedSpellPower, int spellLevel) const;
+	std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHeroInstance * caster, const CGHeroInstance * hero2, const std::set<const CStack*> affectedCreatures, PlayerColor casterSideOwner, ECastingMode::ECastingMode mode, int usedSpellPower, int spellLevel) const;
 
 	const CStack * battleGetStack(BattleHex pos, bool onlyAlive); //returns stack at given tile
 	const CGHeroInstance * battleGetOwner(const CStack * stack) const; //returns hero that owns given stack; NULL if none
@@ -128,8 +128,8 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
 	static BattleInfo * setupBattle( int3 tile, ETerrainType terrain, BFieldType battlefieldType, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town );
 	//bool hasNativeStack(ui8 side) const;
 
-	TPlayerColor theOtherPlayer(TPlayerColor player) const;
-	ui8 whatSide(TPlayerColor player) const;
+	PlayerColor theOtherPlayer(PlayerColor player) const;
+	ui8 whatSide(PlayerColor player) const;
 
 	static BattlefieldBI::BattlefieldBI battlefieldTypeToBI(BFieldType bfieldType); //converts above to ERM BI format
 	static int battlefieldTypeToTerrain(int bfieldType); //converts above to ERM BI format
@@ -143,7 +143,7 @@ public:
 	ui32 ID; //unique ID of stack
 	ui32 baseAmount;
 	ui32 firstHPleft; //HP of first creature in stack
-	TPlayerColor owner; //owner - player colour (255 for neutrals)
+	PlayerColor owner; //owner - player colour (255 for neutrals)
 	SlotID slot;  //slot - position in garrison (may be 255 for neutrals/called creatures)
 	bool attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle)
 	BattleHex position; //position on battlefield; -2 - keep, -3 - lower tower, -4 - upper tower
@@ -155,8 +155,8 @@ public:
 	//overrides
 	const CCreature* getCreature() const {return type;}
 
-	CStack(const CStackInstance *base, int O, int I, bool AO, SlotID S); //c-tor
-	CStack(const CStackBasicDescriptor *stack, int O, int I, bool AO, SlotID S = SlotID(255)); //c-tor
+	CStack(const CStackInstance *base, PlayerColor O, int I, bool AO, SlotID S); //c-tor
+	CStack(const CStackBasicDescriptor *stack, PlayerColor O, int I, bool AO, SlotID S = SlotID(255)); //c-tor
 	CStack(); //c-tor
 	~CStack();
 	std::string nodeName() const OVERRIDE;

+ 11 - 11
lib/CBattleCallback.cpp

@@ -107,7 +107,7 @@ void CCallbackBase::setBattle(const BattleInfo *B)
 	battle = B;
 }
 
-boost::optional<TPlayerColor> CCallbackBase::getPlayerID() const
+boost::optional<PlayerColor> CCallbackBase::getPlayerID() const
 {
 	return player;
 }
@@ -299,7 +299,7 @@ int CBattleInfoEssentials::battleCastSpells(ui8 side) const
 	return getBattle()->castSpells[side];
 }
 
-ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastSpell(TPlayerColor player, ECastingMode::ECastingMode mode) const
+ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastSpell(PlayerColor player, ECastingMode::ECastingMode mode) const
 {
 	RETURN_IF_NOT_BATTLE(ESpellCastProblem::INVALID);
 	const ui8 side = playerToSide(player);
@@ -335,7 +335,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastSpell(TPl
 	return ESpellCastProblem::OK;
 }
 
-bool CBattleInfoEssentials::battleCanFlee(TPlayerColor player) const
+bool CBattleInfoEssentials::battleCanFlee(PlayerColor player) const
 {
 	RETURN_IF_NOT_BATTLE(false);
 	ui8 mySide = playerToSide(player);
@@ -360,7 +360,7 @@ bool CBattleInfoEssentials::battleCanFlee(TPlayerColor player) const
 	return true;
 }
 
-ui8 CBattleInfoEssentials::playerToSide(TPlayerColor player) const
+ui8 CBattleInfoEssentials::playerToSide(PlayerColor player) const
 {
 	RETURN_IF_NOT_BATTLE(-1);
 	int ret = vstd::find_pos(getBattle()->sides, player);
@@ -376,7 +376,7 @@ ui8 CBattleInfoEssentials::battleGetSiegeLevel() const
 	return getBattle()->siege;
 }
 
-bool CBattleInfoEssentials::battleCanSurrender(TPlayerColor player) const
+bool CBattleInfoEssentials::battleCanSurrender(PlayerColor player) const
 {
 	RETURN_IF_NOT_BATTLE(false);
 	//conditions like for fleeing + enemy must have a hero
@@ -1535,7 +1535,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleIsImmune(const C
 	return ESpellCastProblem::OK;
 }
 
-ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell( TPlayerColor player, const CSpell * spell, ECastingMode::ECastingMode mode ) const
+ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell( PlayerColor player, const CSpell * spell, ECastingMode::ECastingMode mode ) const
 {
 	RETURN_IF_NOT_BATTLE(ESpellCastProblem::INVALID);
 	const ui8 side = playerToSide(player);
@@ -1662,7 +1662,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
 	return ESpellCastProblem::OK;
 }
 
-std::vector<BattleHex> CBattleInfoCallback::battleGetPossibleTargets(int player, const CSpell *spell) const
+std::vector<BattleHex> CBattleInfoCallback::battleGetPossibleTargets(PlayerColor player, const CSpell *spell) const
 {
 	std::vector<BattleHex> ret;
 	RETURN_IF_NOT_BATTLE(ret);
@@ -1735,7 +1735,7 @@ ui32 CBattleInfoCallback::battleGetSpellCost(const CSpell * sp, const CGHeroInst
 	return ret - manaReduction + manaIncrease;
 }
 
-ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpellHere( TPlayerColor player, const CSpell * spell, ECastingMode::ECastingMode mode, BattleHex dest ) const
+ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpellHere( PlayerColor player, const CSpell * spell, ECastingMode::ECastingMode mode, BattleHex dest ) const
 {
 	RETURN_IF_NOT_BATTLE(ESpellCastProblem::INVALID);
 	ESpellCastProblem::ESpellCastProblem moreGeneralProblem = battleCanCastThisSpell(player, spell, mode);
@@ -1862,7 +1862,7 @@ ui32 CBattleInfoCallback::calculateSpellDmg( const CSpell * sp, const CGHeroInst
 	return ret;
 }
 
-std::set<const CStack*> CBattleInfoCallback::getAffectedCreatures(const CSpell * spell, int skillLevel, ui8 attackerOwner, BattleHex destinationTile)
+std::set<const CStack*> CBattleInfoCallback::getAffectedCreatures(const CSpell * spell, int skillLevel, PlayerColor attackerOwner, BattleHex destinationTile)
 {
 	std::set<const CStack*> attackedCres; /*std::set to exclude multiple occurrences of two hex creatures*/
 
@@ -1910,7 +1910,7 @@ std::set<const CStack*> CBattleInfoCallback::getAffectedCreatures(const CSpell *
 			}
 			if (!possibleHexes.size()) //not enough targets
 				break;
-			lightningHex = BattleHex::getClosestTile (attackerOwner, destinationTile, possibleHexes);
+			lightningHex = BattleHex::getClosestTile (stack->attackerOwned, destinationTile, possibleHexes);
 		}
 	}
 	else if (spell->range[skillLevel].size() > 1) //custom many-hex range
@@ -2121,7 +2121,7 @@ SpellID CBattleInfoCallback::getRandomCastedSpell(const CStack * caster) const
 	return SpellID::NONE;
 }
 
-int CBattleInfoCallback::battleGetSurrenderCost(TPlayerColor Player) const
+int CBattleInfoCallback::battleGetSurrenderCost(PlayerColor Player) const
 {
 	RETURN_IF_NOT_BATTLE(-3);
 	if(!battleCanSurrender(Player))

+ 12 - 12
lib/CBattleCallback.h

@@ -45,9 +45,9 @@ class DLL_LINKAGE CCallbackBase
 
 protected:
 	CGameState *gs;
-	boost::optional<TPlayerColor> player; // not set gives access to all information, otherwise callback provides only information "visible" for player
+	boost::optional<PlayerColor> player; // not set gives access to all information, otherwise callback provides only information "visible" for player
 
-	CCallbackBase(CGameState *GS, boost::optional<TPlayerColor> Player)
+	CCallbackBase(CGameState *GS, boost::optional<PlayerColor> Player)
 		: battle(nullptr), gs(GS), player(Player)
 	{}
 	CCallbackBase()
@@ -59,7 +59,7 @@ protected:
 
 public:
 	boost::shared_mutex &getGsMutex(); //just return a reference to mutex, does not lock nor anything
-	boost::optional<TPlayerColor> getPlayerID() const;
+	boost::optional<PlayerColor> getPlayerID() const;
 
 	friend class CBattleInfoEssentials;
 };
@@ -175,9 +175,9 @@ public:
 	const CStack *battleActiveStack() const;
 	si8 battleTacticDist() const; //returns tactic distance in current tactics phase; 0 if not in tactics phase
 	si8 battleGetTacticsSide() const; //returns which side is in tactics phase, undefined if none (?)
-	bool battleCanFlee(TPlayerColor player) const;
-	bool battleCanSurrender(TPlayerColor player) const;
-	ui8 playerToSide(TPlayerColor player) const;
+	bool battleCanFlee(PlayerColor player) const;
+	bool battleCanSurrender(PlayerColor player) const;
+	ui8 playerToSide(PlayerColor player) const;
 	ui8 battleGetSiegeLevel() const; //returns 0 when there is no siege, 1 if fort, 2 is citadel, 3 is castle
 	bool battleHasHero(ui8 side) const;
 	int battleCastSpells(ui8 side) const; //how many spells has given side casted
@@ -227,7 +227,7 @@ public:
 
 	std::vector<BattleHex> battleGetAvailableHexes(const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable = NULL) const; //returns hexes reachable by creature with id ID (valid movement destinations), DOES contain stack current position
 
-	int battleGetSurrenderCost(TPlayerColor Player) const; //returns cost of surrendering battle, -1 if surrendering is not possible
+	int battleGetSurrenderCost(PlayerColor Player) const; //returns cost of surrendering battle, -1 if surrendering is not possible
 	ReachabilityInfo::TDistances battleGetDistances(const CStack * stack, BattleHex hex = BattleHex::INVALID, BattleHex * predecessors = NULL) const; //returns vector of distances to [dest hex number]
 	std::set<BattleHex> battleGetAttackedHexes(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos = BattleHex::INVALID) const;
 	bool battleCanShoot(const CStack * stack, BattleHex dest) const; //determines if stack with given ID shoot at the selected destination
@@ -250,14 +250,14 @@ public:
 	//*** MAGIC 
 	si8 battleMaxSpellLevel() const; //calculates minimum spell level possible to be cast on battlefield - takes into account artifacts of both heroes; if no effects are set, 0 is returned
 	ui32 battleGetSpellCost(const CSpell * sp, const CGHeroInstance * caster) const; //returns cost of given spell
-	ESpellCastProblem::ESpellCastProblem battleCanCastSpell(TPlayerColor player, ECastingMode::ECastingMode mode) const; //returns true if there are no general issues preventing from casting a spell
-	ESpellCastProblem::ESpellCastProblem battleCanCastThisSpell(TPlayerColor player, const CSpell * spell, ECastingMode::ECastingMode mode) const; //checks if given player can cast given spell
-	ESpellCastProblem::ESpellCastProblem battleCanCastThisSpellHere(TPlayerColor player, const CSpell * spell, ECastingMode::ECastingMode mode, BattleHex dest) const; //checks if given player can cast given spell at given tile in given mode
+	ESpellCastProblem::ESpellCastProblem battleCanCastSpell(PlayerColor player, ECastingMode::ECastingMode mode) const; //returns true if there are no general issues preventing from casting a spell
+	ESpellCastProblem::ESpellCastProblem battleCanCastThisSpell(PlayerColor player, const CSpell * spell, ECastingMode::ECastingMode mode) const; //checks if given player can cast given spell
+	ESpellCastProblem::ESpellCastProblem battleCanCastThisSpellHere(PlayerColor player, const CSpell * spell, ECastingMode::ECastingMode mode, BattleHex dest) const; //checks if given player can cast given spell at given tile in given mode
 	ESpellCastProblem::ESpellCastProblem battleCanCreatureCastThisSpell(const CSpell * spell, BattleHex destination) const; //determines if creature can cast a spell here
-	std::vector<BattleHex> battleGetPossibleTargets(int player, const CSpell *spell) const;
+	std::vector<BattleHex> battleGetPossibleTargets(PlayerColor player, const CSpell *spell) const;
 	ui32 calculateSpellBonus(ui32 baseDamage, const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature) const;
 	ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature, int spellSchoolLevel, int usedSpellPower) const; //calculates damage inflicted by spell
-	std::set<const CStack*> getAffectedCreatures(const CSpell * s, int skillLevel, ui8 attackerOwner, BattleHex destinationTile); //calculates stack affected by given spell
+	std::set<const CStack*> getAffectedCreatures(const CSpell * s, int skillLevel, PlayerColor attackerOwner, BattleHex destinationTile); //calculates stack affected by given spell
 
 	SpellID battleGetRandomStackSpell(const CStack * stack, ERandomSpell mode) const;
 	SpellID getRandomBeneficialSpell(const CStack * subject) const;

+ 1 - 1
lib/CGameInterface.h

@@ -57,7 +57,7 @@ class CBattleGameInterface : public IBattleEventsReceiver
 {
 public:
 	bool human;
-	int playerID;
+	PlayerColor playerID;
 	std::string dllName;
 
 	virtual ~CBattleGameInterface() {};

+ 63 - 62
lib/CGameState.cpp

@@ -337,7 +337,7 @@ void MetaString::addReplacement(const CStackBasicDescriptor &stack)
 	addCreReplacement(stack.type->idNumber, stack.count);
 }
 
-static CGObjectInstance * createObject(Obj id, int subid, int3 pos, int owner)
+static CGObjectInstance * createObject(Obj id, int subid, int3 pos, PlayerColor owner)
 {
 	CGObjectInstance * nobj;
 	switch(id)
@@ -376,11 +376,11 @@ static CGObjectInstance * createObject(Obj id, int subid, int3 pos, int owner)
 	return nobj;
 }
 
-CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, TPlayerColor player, const CTown *town, bmap<ui32, ConstTransitivePtr<CGHeroInstance> > &available, const CHeroClass *bannedClass /*= NULL*/) const
+CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor player, const CTown *town, bmap<ui32, ConstTransitivePtr<CGHeroInstance> > &available, const CHeroClass *bannedClass /*= NULL*/) const
 {
 	CGHeroInstance *ret = NULL;
 
-	if(player>=GameConstants::PLAYER_LIMIT)
+	if(player>=PlayerColor::PLAYER_LIMIT)
 	{
 		tlog1 << "Cannot pick hero for " << town->typeID << ". Wrong owner!\n";
 		return NULL;
@@ -392,7 +392,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, TPlayerColor p
 	{
 		for(auto i=available.begin(); i!=available.end(); i++)
 		{
-			if(pavailable.find(i->first)->second & 1<<player
+			if(pavailable.find(i->first)->second & 1<<player.getNum()
 				&& i->second->type->heroClass->faction == town->typeID)
 			{
 				pool.push_back(i->second); //get all available heroes
@@ -400,7 +400,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, TPlayerColor p
 		}
 		if(!pool.size())
 		{
-			tlog1 << "Cannot pick native hero for " << int(player) << ". Picking any...\n";
+			tlog1 << "Cannot pick native hero for " << player << ". Picking any...\n";
 			return pickHeroFor(false, player, town, available);
 		}
 		else
@@ -414,7 +414,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, TPlayerColor p
 
 		for(auto i=available.begin(); i!=available.end(); i++)
 		{
-			if ((!bannedClass && (pavailable.find(i->first)->second & (1<<player))) ||
+			if ((!bannedClass && (pavailable.find(i->first)->second & (1<<player.getNum()))) ||
 				i->second->type->heroClass != bannedClass)
 			{
 				pool.push_back(i->second);
@@ -454,7 +454,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, TPlayerColor p
 //	//applyNL(pack);
 //	mx->unlock();
 //}
-int CGameState::pickHero(int owner)
+int CGameState::pickHero(PlayerColor owner)
 {
 	int h=-1;
 	const PlayerSettings &ps = scenarioOps->getIthPlayersSettings(owner);
@@ -464,7 +464,7 @@ int CGameState::pickHero(int owner)
 	if(scenarioOps->mode == StartInfo::CAMPAIGN)
 	{
 		auto bonus = scenarioOps->campState->getBonusForCurrentMap();
-		if(bonus.is_initialized() && bonus->type == CScenarioTravel::STravelBonus::HERO && owner == bonus->info1)
+		if(bonus.is_initialized() && bonus->type == CScenarioTravel::STravelBonus::HERO && owner == PlayerColor(bonus->info1))
 		{
 			if(bonus->info2 != 0xffff && !map->getHero(bonus->info2)) //not random and not taken
 			{
@@ -535,11 +535,11 @@ std::pair<Obj,int> CGameState::pickObject (CGObjectInstance *obj)
 		return std::make_pair(Obj::RESOURCE,ran()%7); //now it's OH3 style, use %8 for mithril
 	case Obj::RANDOM_TOWN:
 		{
-			int align = (static_cast<CGTownInstance*>(obj))->alignment,
-				f;
-			if(align>GameConstants::PLAYER_LIMIT-1)//same as owner / random
+			PlayerColor align = PlayerColor((static_cast<CGTownInstance*>(obj))->alignment);
+			ui32 f;
+			if(align >= PlayerColor::PLAYER_LIMIT)//same as owner / random
 			{
-				if(obj->tempOwner > GameConstants::PLAYER_LIMIT-1)
+				if(obj->tempOwner >= PlayerColor::PLAYER_LIMIT)
 					f = -1; //random
 				else
 					f = scenarioOps->getIthPlayersSettings(obj->tempOwner).castle;
@@ -862,7 +862,7 @@ void CGameState::init(StartInfo * si)
 				tlog0 << "Create random map." << std::endl;
 
 				// Create player settings for RMG
-				std::map<TPlayerColor, CMapGenerator::CPlayerSettings> players;
+				std::map<PlayerColor, CMapGenerator::CPlayerSettings> players;
 				BOOST_FOREACH(auto pInfo, scenarioOps->playerInfos)
 				{
 					const PlayerSettings & startSettings = pInfo.second;
@@ -890,7 +890,7 @@ void CGameState::init(StartInfo * si)
 					const PlayerInfo & pInfo = map->players[i];
 					if(pInfo.canComputerPlay || pInfo.canHumanPlay)
 					{
-						PlayerSettings & pSettings = scenarioOps->playerInfos[i];
+						PlayerSettings & pSettings = scenarioOps->playerInfos[PlayerColor(i)];
 						pSettings.compOnly = !pInfo.canHumanPlay;
 						pSettings.team = pInfo.team;
 						pSettings.castle = pInfo.defaultCastle();
@@ -898,11 +898,11 @@ void CGameState::init(StartInfo * si)
 						{
 							pSettings.name = VLC->generaltexth->allTexts[468];
 						}
-						pSettings.color = i;
+						pSettings.color = PlayerColor(i);
 					}
 					else
 					{
-						scenarioOps->playerInfos.erase(i);
+						scenarioOps->playerInfos.erase(PlayerColor(i));
 					}
 				}
 
@@ -998,8 +998,8 @@ void CGameState::init(StartInfo * si)
 	{
 		if(it->second.castle==-1)
 		{
-			int randomID = ran() % map->players[it->first].allowedFactions.size();
-			auto iter = map->players[it->first].allowedFactions.begin();
+			int randomID = ran() % map->players[it->first.getNum()].allowedFactions.size();
+			auto iter = map->players[it->first.getNum()].allowedFactions.begin();
 			std::advance(iter, randomID);
 
 			it->second.castle = *iter;
@@ -1033,10 +1033,10 @@ void CGameState::init(StartInfo * si)
 	for(auto it = scenarioOps->playerInfos.begin();
 		it != scenarioOps->playerInfos.end(); ++it)
 	{
-		std::pair<TPlayerColor,PlayerState> ins(it->first,PlayerState());
+		std::pair<PlayerColor, PlayerState> ins(it->first,PlayerState());
 		ins.second.color=ins.first;
 		ins.second.human = it->second.playerID;
-		ins.second.team = map->players[ins.first].team;
+		ins.second.team = map->players[ins.first.getNum()].team;
 		teams[ins.second.team].id = ins.second.team;//init team
 		teams[ins.second.team].players.insert(ins.first);//add player to team
 		players.insert(ins);
@@ -1059,7 +1059,7 @@ void CGameState::init(StartInfo * si)
 
 		for(auto it = scenarioOps->playerInfos.begin(); it != scenarioOps->playerInfos.end(); ++it)
 		{
-			const PlayerInfo &p = map->players[it->first];
+			const PlayerInfo &p = map->players[it->first.getNum()];
 			bool generateHero = (p.generateHeroAtMainTown ||
 			                     (it->second.playerID != PlayerSettings::PLAYER_AI && campaignGiveHero)) && p.hasMainTown;
 			if(generateHero && vstd::contains(scenarioOps->playerInfos, it->first))
@@ -1272,7 +1272,7 @@ void CGameState::init(StartInfo * si)
 
 	for (ui32 i=0; i<map->heroes.size();i++) //heroes instances initialization
 	{
-		if (map->heroes[i]->getOwner()<0)
+		if (map->heroes[i]->getOwner() == PlayerColor::UNFLAGGABLE)
 		{
 			tlog2 << "Warning - hero with uninitialized owner!\n";
 			continue;
@@ -1320,7 +1320,7 @@ void CGameState::init(StartInfo * si)
 		if (chosenBonus.is_initialized() && chosenBonus->isBonusForHero() && chosenBonus->info1 != 0xFFFE) //exclude generated heroes
 		{
 			//find human player
-			int humanPlayer=GameConstants::NEUTRAL_PLAYER;
+			PlayerColor humanPlayer=PlayerColor::NEUTRAL;
 			for (auto it=players.begin(); it != players.end(); ++it)
 			{
 				if(it->second.human)
@@ -1329,7 +1329,7 @@ void CGameState::init(StartInfo * si)
 					break;
 				}
 			}
-			assert(humanPlayer != GameConstants::NEUTRAL_PLAYER);
+			assert(humanPlayer != PlayerColor::NEUTRAL);
 
 			std::vector<ConstTransitivePtr<CGHeroInstance> > & heroes = players[humanPlayer].heroes;
 
@@ -1448,7 +1448,7 @@ void CGameState::init(StartInfo * si)
 				PlayerState * owner = getPlayer(map->towns[g]->getOwner());
 				if (owner)
 				{
-					PlayerInfo & pi = map->players[owner->color];
+					PlayerInfo & pi = map->players[owner->color.getNum()];
 
 					if (owner->human && //human-owned
 						map->towns[g]->pos == pi.posOfMainTown + int3(2, 0, 0))
@@ -1558,7 +1558,7 @@ void CGameState::init(StartInfo * si)
 			vti->possibleSpells -= s->id;
 		}
 		vti->possibleSpells.clear();
-		if(vti->getOwner() != GameConstants::NEUTRAL_PLAYER)
+		if(vti->getOwner() != PlayerColor::NEUTRAL)
 			getPlayer(vti->getOwner())->towns.push_back(vti);
 	}
 
@@ -1591,7 +1591,7 @@ void CGameState::init(StartInfo * si)
 
 	for(auto k=players.begin(); k!=players.end(); ++k)
 	{
-		if(k->first==GameConstants::NEUTRAL_PLAYER)
+		if(k->first==PlayerColor::NEUTRAL)
 			continue;
 
 		//init visiting and garrisoned heroes
@@ -1697,7 +1697,7 @@ void CGameState::initDuel()
 			//c->subID = 34;
 		}
 
-		obj->setOwner(i);
+		obj->setOwner(PlayerColor(i));
 
 		for(int j = 0; j < ARRAY_COUNT(dp.sides[i].stacks); j++)
 		{
@@ -1869,11 +1869,11 @@ UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
 	return ret;
 }
 
-PlayerRelations::PlayerRelations CGameState::getPlayerRelations( TPlayerColor color1, TPlayerColor color2 )
+PlayerRelations::PlayerRelations CGameState::getPlayerRelations( PlayerColor color1, PlayerColor color2 )
 {
 	if ( color1 == color2 )
 		return PlayerRelations::SAME_PLAYER;
-	if(color1 == GameConstants::NEUTRAL_PLAYER || color2 == GameConstants::NEUTRAL_PLAYER) //neutral player has no friends
+	if(color1 == PlayerColor::NEUTRAL || color2 == PlayerColor::NEUTRAL) //neutral player has no friends
 		return PlayerRelations::ENEMIES;
 
 	const TeamState * ts = getPlayerTeam(color1);
@@ -2096,19 +2096,19 @@ int3 CGameState::guardingCreaturePosition (int3 pos) const
 	return int3(-1, -1, -1);
 }
 
-bool CGameState::isVisible(int3 pos, TPlayerColor player)
+bool CGameState::isVisible(int3 pos, PlayerColor player)
 {
-	if(player == GameConstants::NEUTRAL_PLAYER)
+	if(player == PlayerColor::NEUTRAL)
 		return false;
 	return getPlayerTeam(player)->fogOfWarMap[pos.x][pos.y][pos.z];
 }
 
-bool CGameState::isVisible( const CGObjectInstance *obj, boost::optional<TPlayerColor> player )
+bool CGameState::isVisible( const CGObjectInstance *obj, boost::optional<PlayerColor> player )
 {
 	if(!player)
 		return true;
 
-	if(*player == GameConstants::NEUTRAL_PLAYER) //-> TODO ??? needed?
+	if(*player == PlayerColor::NEUTRAL) //-> TODO ??? needed?
 		return false;
 	//object is visible when at least one blocked tile is visible
 	for(int fx=0; fx<8; ++fx)
@@ -2176,7 +2176,7 @@ bool CGameState::checkForVisitableDir( const int3 & src, const TerrainTile *pom,
 }
 
 
-int CGameState::victoryCheck( ui8 player ) const
+int CGameState::victoryCheck( PlayerColor player ) const
 {
 	const PlayerState *p = CGameInfoCallback::getPlayer(player);
 	if(map->victoryCondition.condition == EVictoryConditionType::WINSTANDARD  ||  map->victoryCondition.allowNormalVictory
@@ -2251,7 +2251,7 @@ int CGameState::victoryCheck( ui8 player ) const
 			break;
 
 		case EVictoryConditionType::BEATHERO:
-			if(map->victoryCondition.obj->tempOwner >= GameConstants::PLAYER_LIMIT) //target hero not present on map
+			if(map->victoryCondition.obj->tempOwner >= PlayerColor::PLAYER_LIMIT) //target hero not present on map
 				return 1;
 			break;
 		case EVictoryConditionType::CAPTURECITY:
@@ -2310,16 +2310,17 @@ int CGameState::victoryCheck( ui8 player ) const
 	return 0;
 }
 
-ui8 CGameState::checkForStandardWin() const
+PlayerColor CGameState::checkForStandardWin() const
 {
 	//std victory condition is:
 	//all enemies lost
-	TPlayerColor supposedWinner = 255, winnerTeam = 255;
+	PlayerColor supposedWinner = PlayerColor::NEUTRAL;
+	TeamID winnerTeam = TeamID::NO_TEAM;
 	for(auto i = players.begin(); i != players.end(); i++)
 	{
-		if(i->second.status == EPlayerStatus::INGAME && i->first < GameConstants::PLAYER_LIMIT)
+		if(i->second.status == EPlayerStatus::INGAME && i->first < PlayerColor::PLAYER_LIMIT)
 		{
-			if(supposedWinner == 255)
+			if(supposedWinner == PlayerColor::NEUTRAL)
 			{
 				//first player remaining ingame - candidate for victory
 				supposedWinner = i->second.color;
@@ -2328,7 +2329,7 @@ ui8 CGameState::checkForStandardWin() const
 			else if(winnerTeam != i->second.team)
 			{
 				//current candidate has enemy remaining in game -> no vicotry
-				return 255;
+				return PlayerColor::NEUTRAL;
 			}
 		}
 	}
@@ -2336,7 +2337,7 @@ ui8 CGameState::checkForStandardWin() const
 	return supposedWinner;
 }
 
-bool CGameState::checkForStandardLoss( TPlayerColor player ) const
+bool CGameState::checkForStandardLoss( PlayerColor player ) const
 {
 	//std loss condition is: player lost all towns and heroes
 	const PlayerState &p = *CGameInfoCallback::getPlayer(player);
@@ -2345,15 +2346,15 @@ bool CGameState::checkForStandardLoss( TPlayerColor player ) const
 
 struct statsHLP
 {
-	typedef std::pair< TPlayerColor, si64 > TStat;
+	typedef std::pair< PlayerColor, si64 > TStat;
 	//converts [<player's color, value>] to vec[place] -> platers
-	static std::vector< std::vector< TPlayerColor > > getRank( std::vector<TStat> stats )
+	static std::vector< std::vector< PlayerColor > > getRank( std::vector<TStat> stats )
 	{
 		std::sort(stats.begin(), stats.end(), statsHLP());
 
 		//put first element
-		std::vector< std::vector<TPlayerColor> > ret;
-		std::vector<TPlayerColor> tmp;
+		std::vector< std::vector<PlayerColor> > ret;
+		std::vector<PlayerColor> tmp;
 		tmp.push_back( stats[0].first );
 		ret.push_back( tmp );
 
@@ -2367,7 +2368,7 @@ struct statsHLP
 			else
 			{
 				//create next occupied rank
-				std::vector<TPlayerColor> tmp;
+				std::vector<PlayerColor> tmp;
 				tmp.push_back(stats[g].first);
 				ret.push_back(tmp);
 			}
@@ -2381,7 +2382,7 @@ struct statsHLP
 		return a.second > b.second;
 	}
 
-	static const CGHeroInstance * findBestHero(CGameState * gs, int color)
+	static const CGHeroInstance * findBestHero(CGameState * gs, PlayerColor color)
 	{
 		std::vector<ConstTransitivePtr<CGHeroInstance> > &h = gs->players[color].heroes;
 		if(!h.size())
@@ -2427,12 +2428,12 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 {
 #define FILL_FIELD(FIELD, VAL_GETTER) \
 	{ \
-		std::vector< std::pair< TPlayerColor, si64 > > stats; \
+		std::vector< std::pair< PlayerColor, si64 > > stats; \
 		for(auto g = players.begin(); g != players.end(); ++g) \
 		{ \
-			if(g->second.color == GameConstants::NEUTRAL_PLAYER) \
+			if(g->second.color == PlayerColor::NEUTRAL) \
 				continue; \
-			std::pair< ui8, si64 > stat; \
+			std::pair< PlayerColor, si64 > stat; \
 			stat.first = g->second.color; \
 			stat.second = VAL_GETTER; \
 			stats.push_back(stat); \
@@ -2442,7 +2443,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 
 	for(auto g = players.begin(); g != players.end(); ++g)
 	{
-		if(g->second.color != GameConstants::NEUTRAL_PLAYER)
+		if(g->second.color != PlayerColor::NEUTRAL)
 			tgi.playerColors.push_back(g->second.color);
 	}
 
@@ -2455,7 +2456,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 		//best hero's portrait
 		for(auto g = players.cbegin(); g != players.cend(); ++g)
 		{
-			if(g->second.color == GameConstants::NEUTRAL_PLAYER)
+			if(g->second.color == PlayerColor::NEUTRAL)
 				continue;
 			const CGHeroInstance * best = statsHLP::findBestHero(this, g->second.color);
 			InfoAboutHero iah;
@@ -2500,7 +2501,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 	{
 		for(auto g = players.cbegin(); g != players.cend(); ++g)
 		{
-			if(g->second.color == GameConstants::NEUTRAL_PLAYER) //do nothing for neutral player
+			if(g->second.color == PlayerColor::NEUTRAL) //do nothing for neutral player
 				continue;
 			if(g->second.human)
 			{
@@ -2508,7 +2509,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 			}
 			else //AI
 			{
-                tgi.personality[g->second.color] = map->players[g->second.color].aiTactic;
+                tgi.personality[g->second.color] = map->players[g->second.color.getNum()].aiTactic;
 			}
 
 		}
@@ -2518,7 +2519,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 		//best creatures belonging to player (highest AI value)
 		for(auto g = players.cbegin(); g != players.cend(); ++g)
 		{
-			if(g->second.color == GameConstants::NEUTRAL_PLAYER) //do nothing for neutral player
+			if(g->second.color == PlayerColor::NEUTRAL) //do nothing for neutral player
 				continue;
 			int bestCre = -1; //best creature's ID
 			for(int b=0; b<g->second.heroes.size(); ++b)
@@ -2539,7 +2540,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 #undef FILL_FIELD
 }
 
-int CGameState::lossCheck( TPlayerColor player ) const
+int CGameState::lossCheck( PlayerColor player ) const
 {
 	const PlayerState *p = CGameInfoCallback::getPlayer(player);
 	//if(map->lossCondition.typeOfLossCon == lossStandard)
@@ -2614,7 +2615,7 @@ void CGameState::buildGlobalTeamPlayerTree()
 		TeamState *t = &k->second;
 		t->attachTo(&globalEffects);
 
-		BOOST_FOREACH(ui8 teamMember, k->second.players)
+		BOOST_FOREACH(PlayerColor teamMember, k->second.players)
 		{
 			PlayerState *p = getPlayer(teamMember);
 			assert(p);
@@ -2732,7 +2733,7 @@ PlayerState::PlayerState()
 
 std::string PlayerState::nodeName() const
 {
-	return "Player " + (color < VLC->generaltexth->capColors.size() ? VLC->generaltexth->capColors[color] : boost::lexical_cast<std::string>(color));
+	return "Player " + (color.getNum() < VLC->generaltexth->capColors.size() ? VLC->generaltexth->capColors[color.getNum()] : boost::lexical_cast<std::string>(color));
 }
 
 // void PlayerState::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
@@ -2750,7 +2751,7 @@ std::string PlayerState::nodeName() const
 // }
 
 InfoAboutArmy::InfoAboutArmy():
-    owner(GameConstants::NEUTRAL_PLAYER)
+    owner(PlayerColor::NEUTRAL)
 {}
 
 InfoAboutArmy::InfoAboutArmy(const CArmedInstance *Army, bool detailed)
@@ -3220,7 +3221,7 @@ CGPathNode::EAccessibility CPathfinder::evaluateAccessibility(const TerrainTile
 		{
 			BOOST_FOREACH(const CGObjectInstance *obj, tinfo->visitableObjects)
 			{
-				if(obj->getPassableness() & 1<<hero->tempOwner) //special object instance specific passableness flag - overwrites other accessibility flags
+				if(obj->getPassableness() & 1<<hero->tempOwner.getNum()) //special object instance specific passableness flag - overwrites other accessibility flags
 				{
 					ret = CGPathNode::ACCESSIBLE;
 				}
@@ -3276,7 +3277,7 @@ bool CPathfinder::goodForLandSeaTransition()
 	return true;
 }
 
-CPathfinder::CPathfinder(CPathsInfo &_out, CGameState *_gs, const CGHeroInstance *_hero) : CGameInfoCallback(_gs, boost::optional<TPlayerColor>()), out(_out), hero(_hero), FoW(getPlayerTeam(hero->tempOwner)->fogOfWarMap)
+CPathfinder::CPathfinder(CPathsInfo &_out, CGameState *_gs, const CGHeroInstance *_hero) : CGameInfoCallback(_gs, boost::optional<PlayerColor>()), out(_out), hero(_hero), FoW(getPlayerTeam(hero->tempOwner)->fogOfWarMap)
 {
 	useSubterraneanGates = true;
 	allowEmbarkAndDisembark = true;

+ 22 - 22
lib/CGameState.h

@@ -80,7 +80,7 @@ struct ArmyDescriptor : public std::map<SlotID, CStackBasicDescriptor>
 
 struct DLL_LINKAGE InfoAboutArmy
 {
-	ui8 owner;
+	PlayerColor owner;
 	std::string name;
 
 	ArmyDescriptor army;
@@ -143,14 +143,14 @@ struct DLL_LINKAGE InfoAboutTown : public InfoAboutArmy
 
 struct DLL_LINKAGE SThievesGuildInfo
 {
-	std::vector<TPlayerColor> playerColors; //colors of players that are in-game
+	std::vector<PlayerColor> playerColors; //colors of players that are in-game
 
-	std::vector< std::vector< TPlayerColor > > numOfTowns, numOfHeroes, gold, woodOre, mercSulfCrystGems, obelisks, artifacts, army, income; // [place] -> [colours of players]
+	std::vector< std::vector< PlayerColor > > numOfTowns, numOfHeroes, gold, woodOre, mercSulfCrystGems, obelisks, artifacts, army, income; // [place] -> [colours of players]
 
-	std::map<TPlayerColor, InfoAboutHero> colorToBestHero; //maps player's color to his best heros'
+	std::map<PlayerColor, InfoAboutHero> colorToBestHero; //maps player's color to his best heros'
 
-    std::map<TPlayerColor, EAiTactic::EAiTactic> personality; // color to personality // ai tactic
-	std::map<TPlayerColor, si32> bestCreature; // color to ID // id or -1 if not known
+    std::map<PlayerColor, EAiTactic::EAiTactic> personality; // color to personality // ai tactic
+	std::map<PlayerColor, si32> bestCreature; // color to ID // id or -1 if not known
 
 // 	template <typename Handler> void serialize(Handler &h, const int version)
 // 	{
@@ -163,10 +163,10 @@ struct DLL_LINKAGE SThievesGuildInfo
 struct DLL_LINKAGE PlayerState : public CBonusSystemNode
 {
 public:
-	TPlayerColor color;
+	PlayerColor color;
 	bool human; //true if human controlled player, false for AI
 	ObjectInstanceID currentSelection; //id of hero/town, 0xffffffff if none
-	ui8 team;
+	TeamID team;
 	TResources resources;
 	std::vector<ConstTransitivePtr<CGHeroInstance> > heroes;
 	std::vector<ConstTransitivePtr<CGTownInstance> > towns;
@@ -199,8 +199,8 @@ public:
 struct DLL_LINKAGE TeamState : public CBonusSystemNode
 {
 public:
-	ui8 id; //position in gameState::teams
-	std::set<TPlayerColor> players; // members of this team
+	TeamID id; //position in gameState::teams
+	std::set<PlayerColor> players; // members of this team
 	std::vector<std::vector<std::vector<ui8> > >  fogOfWarMap; //true - visible, false - hidden
 
 	TeamState();
@@ -364,12 +364,12 @@ class DLL_LINKAGE CGameState : public CNonConstInfoCallback
 {
 public:
 	ConstTransitivePtr<StartInfo> scenarioOps, initialOpts; //second one is a copy of settings received from pregame (not randomized)
-	TPlayerColor currentPlayer; //ID of player currently having turn
+	PlayerColor currentPlayer; //ID of player currently having turn
 	ConstTransitivePtr<BattleInfo> curB; //current battle
 	ui32 day; //total number of days in game
 	ConstTransitivePtr<CMap> map;
-	bmap<TPlayerColor, PlayerState> players;
-	bmap<TPlayerColor, TeamState> teams;
+	bmap<PlayerColor, PlayerState> players;
+	bmap<TeamID, TeamState> teams;
 	CBonusSystemNode globalEffects;
 	bmap<const CGHeroInstance*, const CGObjectInstance*> ongoingVisits;
 
@@ -378,7 +378,7 @@ public:
 		bmap<ui32, ConstTransitivePtr<CGHeroInstance> > heroesPool; //[subID] - heroes available to buy; NULL if not available
 		bmap<ui32,ui8> pavailable; // [subid] -> which players can recruit hero (binary flags)
 
-		CGHeroInstance * pickHeroFor(bool native, TPlayerColor player, const CTown *town, bmap<ui32, ConstTransitivePtr<CGHeroInstance> > &available, const CHeroClass *bannedClass = NULL) const;
+		CGHeroInstance * pickHeroFor(bool native, PlayerColor player, const CTown *town, bmap<ui32, ConstTransitivePtr<CGHeroInstance> > &available, const CHeroClass *bannedClass = NULL) const;
 
 		template <typename Handler> void serialize(Handler &h, const int version)
 		{
@@ -393,22 +393,22 @@ public:
 	void initDuel();
 	void randomizeObject(CGObjectInstance *cur);
 	std::pair<Obj,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
-	int pickHero(int owner);
+	int pickHero(PlayerColor owner);
 	void giveHeroArtifact(CGHeroInstance *h, ArtifactID aid);
 
 	void apply(CPack *pack);
 	BFieldType battleGetBattlefieldType(int3 tile) const;
 	UpgradeInfo getUpgradeInfo(const CStackInstance &stack);
-	PlayerRelations::PlayerRelations getPlayerRelations(TPlayerColor color1, TPlayerColor color2);
+	PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2);
 	bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if src tile is visitable from dst tile
 	bool checkForVisitableDir(const int3 & src, const TerrainTile *pom, const int3 & dst) const; //check if src tile is visitable from dst tile
 	void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src = int3(-1,-1,-1), int movement = -1); //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or NULL if path does not exists
 	int3 guardingCreaturePosition (int3 pos) const;
 	std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const;
-	int victoryCheck(TPlayerColor player) const; //checks if given player is winner; -1 if std victory, 1 if special victory, 0 else
-	int lossCheck(TPlayerColor 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(TPlayerColor player) const; //checks if given player lost the game
+	int victoryCheck(PlayerColor player) const; //checks if given player is winner; -1 if std victory, 1 if special victory, 0 else
+	int lossCheck(PlayerColor player) const; //checks if given player is loser;  -1 if std loss, 1 if special, 0 else
+	PlayerColor checkForStandardWin() const; //returns color of player that accomplished standard victory conditions or 255 (NEUTRAL) if no winner
+	bool checkForStandardLoss(PlayerColor 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
 	bmap<ui32, ConstTransitivePtr<CGHeroInstance> > unusedHeroesFromPool(); //heroes pool without heroes that are available in taverns
 	BattleInfo * setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town);
@@ -418,8 +418,8 @@ public:
 	void buildGlobalTeamPlayerTree();
 	void deserializationFix();
 
-	bool isVisible(int3 pos, TPlayerColor player);
-	bool isVisible(const CGObjectInstance *obj, boost::optional<TPlayerColor> player);
+	bool isVisible(int3 pos, PlayerColor player);
+	bool isVisible(const CGObjectInstance *obj, boost::optional<PlayerColor> player);
 
 	CGameState(); //c-tor
 	virtual ~CGameState(); //d-tor

+ 80 - 70
lib/CObjectHandler.cpp

@@ -43,10 +43,10 @@ std::map<Obj, std::map<int, std::vector<ObjectInstanceID> > > CGTeleport::objs;
 std::vector<std::pair<ObjectInstanceID, ObjectInstanceID> > CGTeleport::gates;
 IGameCallback * IObjectInterface::cb = NULL;
 extern boost::rand48 ran;
-std::map <TPlayerColor, std::set <ui8> > CGKeys::playerKeyMap;
+std::map <PlayerColor, std::set <ui8> > CGKeys::playerKeyMap;
 std::map <si32, std::vector<ObjectInstanceID> > CGMagi::eyelist;
 ui8 CGObelisk::obeliskCount; //how many obelisks are on map
-std::map<TTeamID, ui8> CGObelisk::visited; //map: team_id => how many obelisks has been visited
+std::map<TeamID, ui8> CGObelisk::visited; //map: team_id => how many obelisks has been visited
 
 std::vector<const CArtifact *> CGTownInstance::merchantArtifacts;
 std::vector<int> CGTownInstance::universitySkills;
@@ -61,7 +61,7 @@ static void openWindow(const OpenWindow::EWindow type, const int id1, const int
 	IObjectInterface::cb->sendAndApply(&ow);
 }
 
-static void showInfoDialog(const TPlayerColor playerID, const ui32 txtID, const ui16 soundID)
+static void showInfoDialog(const PlayerColor playerID, const ui32 txtID, const ui16 soundID)
 {
 	InfoWindow iw;
 	iw.soundID = soundID;
@@ -72,13 +72,13 @@ static void showInfoDialog(const TPlayerColor playerID, const ui32 txtID, const
 
 static void showInfoDialog(const ObjectInstanceID heroID, const ui32 txtID, const ui16 soundID)
 {
-	const TPlayerColor playerID = IObjectInterface::cb->getOwner(heroID);
+	const PlayerColor playerID = IObjectInterface::cb->getOwner(heroID);
 	showInfoDialog(playerID,txtID,soundID);
 }
 
 static void showInfoDialog(const CGHeroInstance* h, const ui32 txtID, const ui16 soundID)
 {
-	const TPlayerColor playerID = h->getOwner();
+	const PlayerColor playerID = h->getOwner();
 	showInfoDialog(playerID,txtID,soundID);
 }
 
@@ -110,7 +110,7 @@ void IObjectInterface::initObj()
 void IObjectInterface::setProperty( ui8 what, ui32 val )
 {}
 
-bool IObjectInterface::wasVisited (ui8 player) const
+bool IObjectInterface::wasVisited (PlayerColor player) const
 {
 	return false;
 }
@@ -128,14 +128,24 @@ void IObjectInterface::preInit()
 void CPlayersVisited::setPropertyDer( ui8 what, ui32 val )
 {
 	if(what == 10)
-		players.insert((ui8)val);
+		players.insert(PlayerColor(val));
 }
 
-bool CPlayersVisited::wasVisited( TPlayerColor player ) const
+bool CPlayersVisited::wasVisited( PlayerColor player ) const
 {
 	return vstd::contains(players,player);
 }
 
+bool CPlayersVisited::wasVisited( TeamID team ) const
+{
+	BOOST_FOREACH(auto i, players)
+	{
+		if(cb->getPlayer(i)->team == team)
+			return true;
+	}
+	return false;
+}
+
 // Bank helper. Find the creature ID and their number, and store the
 // result in storage (either guards or reward creatures).
 static void readCreatures(const JsonNode &creature, std::vector< std::pair <CreatureID, ui32> > &storage)
@@ -249,7 +259,7 @@ int CObjectHandler::bankObjToIndex (const CGObjectInstance * obj)
 		return 0;
 	}
 }
-int CGObjectInstance::getOwner() const
+PlayerColor CGObjectInstance::getOwner() const
 {
 	//if (state)
 	//	return state->owner;
@@ -265,7 +275,7 @@ CGObjectInstance::CGObjectInstance()
 	ID = Obj::NO_OBJ;
 	subID = -1;
 	defInfo = NULL;
-	tempOwner = 254;
+	tempOwner = PlayerColor::UNFLAGGABLE;
 	blockVisit = false;
 }
 CGObjectInstance::~CGObjectInstance()
@@ -280,7 +290,7 @@ const std::string & CGObjectInstance::getHoverText() const
 {
 	return hoverName;
 }
-void CGObjectInstance::setOwner(int ow)
+void CGObjectInstance::setOwner(PlayerColor ow)
 {
 	//if (state)
 	//	state->owner = ow;
@@ -399,7 +409,7 @@ void CGObjectInstance::setProperty( ui8 what, ui32 val )
 	switch(what)
 	{
 	case ObjProperty::OWNER:
-		tempOwner = val;
+		tempOwner = PlayerColor(val);
 		break;
 	case ObjProperty::BLOCKVIS:
 		blockVisit = val;
@@ -435,7 +445,7 @@ void CGObjectInstance::getSightTiles(boost::unordered_set<int3, ShashInt3> &tile
 {
 	cb->getTilesInRange(tiles, getSightCenter(), getSightRadious(), tempOwner, 1);
 }
-void CGObjectInstance::hideTiles(TPlayerColor ourplayer, int radius) const
+void CGObjectInstance::hideTiles(PlayerColor ourplayer, int radius) const
 {
 	for (auto i = cb->gameState()->teams.begin(); i != cb->gameState()->teams.end(); i++)
 	{
@@ -1603,7 +1613,7 @@ void CGDwelling::initObj()
 				hoverName = VLC->generaltexth->creGens[subID];
 			if(crs->level > 4)
 				putStack(SlotID(0), new CStackInstance(crs, (crs->growth) * 3));
-			if (getOwner() != GameConstants::NEUTRAL_PLAYER)
+			if (getOwner() != PlayerColor::NEUTRAL)
 				cb->gameState()->players[getOwner()].dwellings.push_back (this);
 		}
 		break;
@@ -1660,13 +1670,13 @@ void CGDwelling::setProperty(ui8 what, ui32 val)
 		case ObjProperty::OWNER: //change owner
 			if (ID == Obj::CREATURE_GENERATOR1) //single generators
 			{
-				if (tempOwner != GameConstants::NEUTRAL_PLAYER)
+				if (tempOwner != PlayerColor::NEUTRAL)
 				{
 					std::vector<ConstTransitivePtr<CGDwelling> >* dwellings = &cb->gameState()->players[tempOwner].dwellings;
 					dwellings->erase (std::find(dwellings->begin(), dwellings->end(), this));
 				}
-				if (val != GameConstants::NEUTRAL_PLAYER) //can new owner be neutral?
-					cb->gameState()->players[val].dwellings.push_back (this);
+				if (PlayerColor(val) != PlayerColor::NEUTRAL) //can new owner be neutral?
+					cb->gameState()->players[PlayerColor(val)].dwellings.push_back (this);
 			}
 			break;
 		case ObjProperty::AVAILABLE_CREATURE:
@@ -2154,7 +2164,7 @@ void CGTownInstance::newTurn() const
 	{
 		//give resources for Rampart, Mystic Pond
 		if (hasBuilt(BuildingID::MYSTIC_POND, ETownType::RAMPART)
-			&& cb->getDate(Date::DAY) != 1 && (tempOwner < GameConstants::PLAYER_LIMIT))
+			&& cb->getDate(Date::DAY) != 1 && (tempOwner < PlayerColor::PLAYER_LIMIT))
 		{
 			int resID = rand()%4+2;//bonus to random rare resource
 			resID = (resID==2)?1:resID;
@@ -2171,7 +2181,7 @@ void CGTownInstance::newTurn() const
 				cb->setObjProperty (id, ObjProperty::STRUCTURE_CLEAR_VISITORS, (*i)->id); //reset visitors for Mana Vortex
 		}
 
-		if (tempOwner == GameConstants::NEUTRAL_PLAYER) //garrison growth for neutral towns
+		if (tempOwner == PlayerColor::NEUTRAL) //garrison growth for neutral towns
 			{
 				std::vector<SlotID> nativeCrits; //slots
 				for (TSlots::const_iterator it = Slots().begin(); it != Slots().end(); it++)
@@ -2231,13 +2241,13 @@ ui8 CGTownInstance::getPassableness() const
 {
 	if (!armedGarrison())//empty castle - anyone can visit
 		return GameConstants::ALL_PLAYERS;
-	if ( tempOwner == GameConstants::NEUTRAL_PLAYER )//neutral guarded - no one can visit
+	if ( tempOwner == PlayerColor::NEUTRAL )//neutral guarded - no one can visit
 		return 0;
 
 	ui8 mask = 0;
 	TeamState * ts = cb->gameState()->getPlayerTeam(tempOwner);
-	BOOST_FOREACH(ui8 it, ts->players)
-		mask |= 1<<it;//allies - add to possible visitors
+	BOOST_FOREACH(PlayerColor it, ts->players)
+		mask |= 1<<it.getNum();//allies - add to possible visitors
 
 	return mask;
 }
@@ -2261,12 +2271,12 @@ void CGTownInstance::fightOver( const CGHeroInstance *h, BattleResult *result )
 	}
 }
 
-void CGTownInstance::removeCapitols (ui8 owner) const
+void CGTownInstance::removeCapitols (PlayerColor owner) const
 {
 	if (hasCapitol()) // search if there's an older capitol
 	{
 		PlayerState* state = cb->gameState()->getPlayer (owner); //get all towns owned by player
-		for (std::vector<ConstTransitivePtr<CGTownInstance> >::const_iterator i = state->towns.begin(); i < state->towns.end(); ++i)
+		for (auto i = state->towns.cbegin(); i < state->towns.cend(); ++i)
 		{
 			if (*i != this && (*i)->hasCapitol())
 			{
@@ -3407,7 +3417,7 @@ void CGMine::newTurn() const
 	if(cb->getDate() == 1)
 		return;
 
-	if (tempOwner == GameConstants::NEUTRAL_PLAYER)
+	if (tempOwner == PlayerColor::NEUTRAL)
 		return;
 
 	cb->giveResource(tempOwner, producedResource, producedQuantity);
@@ -3424,13 +3434,13 @@ void CGMine::initObj()
 
 		//after map reading tempOwner placeholds bitmask for allowed resources
 		std::vector<Res::ERes> possibleResources;
-		for (int i = 0; i < GameConstants::PLAYER_LIMIT; i++)
-			if(tempOwner & 1<<i)
+		for (int i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++)
+			if(tempOwner.getNum() & 1<<i) //NOTE: reuse of tempOwner
 				possibleResources.push_back(static_cast<Res::ERes>(i));
 
 		assert(possibleResources.size());
 		producedResource = possibleResources[ran()%possibleResources.size()];
-		tempOwner = GameConstants::NEUTRAL_PLAYER;
+		tempOwner = PlayerColor::NEUTRAL;
 		hoverName = VLC->generaltexth->mines[7].first + "\n" + VLC->generaltexth->allTexts[202] + " " + troglodytes->getQuantityTXT(false) + " " + troglodytes->type->namePl;
 	}
 	else
@@ -3439,10 +3449,10 @@ void CGMine::initObj()
 
 		MetaString ms;
 		ms << std::pair<ui8,ui32>(9,producedResource);
-		if(tempOwner >= GameConstants::PLAYER_LIMIT)
-			tempOwner = GameConstants::NEUTRAL_PLAYER;
+		if(tempOwner >= PlayerColor::PLAYER_LIMIT)
+			tempOwner = PlayerColor::NEUTRAL;
 		else
-			ms << " (" << std::pair<ui8,ui32>(6,23+tempOwner) << ")";
+			ms << " (" << std::pair<ui8,ui32>(6,23+tempOwner.getNum()) << ")";
 		ms.toString(hoverName);
 	}
 
@@ -3454,7 +3464,7 @@ void CGMine::fight(ui32 agreed, const CGHeroInstance *h) const
 	cb->startBattleI(h, this, boost::bind(&CGMine::endBattle, this, _1, h->tempOwner));
 }
 
-void CGMine::endBattle(BattleResult *result, TPlayerColor attackingPlayer) const
+void CGMine::endBattle(BattleResult *result, PlayerColor attackingPlayer) const
 {
 	if(result->winner == 0) //attacker won
 	{
@@ -3466,13 +3476,13 @@ void CGMine::endBattle(BattleResult *result, TPlayerColor attackingPlayer) const
 	}
 }
 
-void CGMine::flagMine(TPlayerColor player) const
+void CGMine::flagMine(PlayerColor player) const
 {
 	assert(tempOwner != player);
 	cb->setOwner(this, player); //not ours? flag it!
 
 	MetaString ms;
-	ms << std::pair<ui8,ui32>(9,subID) << "\n(" << std::pair<ui8,ui32>(6,23+player) << ")";
+	ms << std::pair<ui8,ui32>(9,subID) << "\n(" << std::pair<ui8,ui32>(6,23+player.getNum()) << ")";
 	if(subID == 7)
 	{
 		ms << "(%s)";
@@ -3553,7 +3563,7 @@ void CGResource::onHeroVisit( const CGHeroInstance * h ) const
 	}
 }
 
-void CGResource::collectRes( int player ) const
+void CGResource::collectRes( PlayerColor player ) const
 {
 	cb->giveResource(player, static_cast<Res::ERes>(subID), amount);
 	ShowInInfobox sii;
@@ -3587,7 +3597,7 @@ void CGVisitableOPW::newTurn() const
 		cb->setHoverName(this,&ms);
 	}
 }
-bool CGVisitableOPW::wasVisited(TPlayerColor player) const
+bool CGVisitableOPW::wasVisited(PlayerColor player) const
 {
 	return visited; //TODO: other players should see object as unvisited
 }
@@ -4184,7 +4194,7 @@ bool CQuest::checkQuest (const CGHeroInstance * h) const
 				return true;
 			return false;
 		case MISSION_PLAYER:
-			if (m13489val == h->getOwner())
+			if (m13489val == h->getOwner().getNum())
 				return true;
 			return false;
 		default:
@@ -4822,9 +4832,9 @@ void CGWitchHut::onHeroVisit( const CGHeroInstance * h ) const
 	iw.soundID = soundBase::gazebo;
 	iw.player = h->getOwner();
 	if(!wasVisited(h->tempOwner))
-		cb->setObjProperty(id,10,h->tempOwner);
+		cb->setObjProperty(id, 10, h->tempOwner.getNum());
 	ui32 txt_id;
-	if(h->getSecSkillLevel(SecondarySkill(ability))) //you alredy know this skill
+	if(h->getSecSkillLevel(SecondarySkill(ability))) //you already know this skill
 	{
 		txt_id =172;
 	}
@@ -5403,7 +5413,7 @@ void CGPandoraBox::getText( InfoWindow &iw, bool &afterBattle, int val, int nega
 
 void CGEvent::onHeroVisit( const CGHeroInstance * h ) const
 {
-	if(!(availableFor & (1 << h->tempOwner)))
+	if(!(availableFor & (1 << h->tempOwner.getNum())))
 		return;
 	if(cb->getPlayerSettings(h->tempOwner)->playerID)
 	{
@@ -5471,7 +5481,7 @@ void CGShrine::onHeroVisit( const CGHeroInstance * h ) const
 	}
 
 	if(!wasVisited(h->tempOwner))
-		cb->setObjProperty(id,10,h->tempOwner);
+		cb->setObjProperty(id, 10, h->tempOwner.getNum());
 
 	InfoWindow iw;
 	iw.soundID = soundBase::temple;
@@ -5666,13 +5676,13 @@ ui8 CGGarrison::getPassableness() const
 {
 	if ( !stacksCount() )//empty - anyone can visit
 		return GameConstants::ALL_PLAYERS;
-	if ( tempOwner == GameConstants::NEUTRAL_PLAYER )//neutral guarded - no one can visit
+	if ( tempOwner == PlayerColor::NEUTRAL )//neutral guarded - no one can visit
 		return 0;
 
 	ui8 mask = 0;
 	TeamState * ts = cb->gameState()->getPlayerTeam(tempOwner);
-	BOOST_FOREACH(ui8 it, ts->players)
-		mask |= 1<<it;//allies - add to possible visitors
+	BOOST_FOREACH(PlayerColor it, ts->players)
+		mask |= 1<<it.getNum(); //allies - add to possible visitors
 
 	return mask;
 }
@@ -5758,7 +5768,7 @@ void CGOnceVisitable::onHeroVisit( const CGHeroInstance * h ) const
 	}
 
 	cb->showInfoDialog(&iw);
-	cb->setObjProperty(id,10,h->getOwner());
+	cb->setObjProperty(id, 10, h->getOwner().getNum());
 }
 
 const std::string & CGOnceVisitable::getHoverText() const
@@ -5867,7 +5877,7 @@ void CGOnceVisitable::searchTomb(const CGHeroInstance *h, ui32 accept) const
 			cb->giveHeroBonus(&gb);
 		}
 		cb->showInfoDialog(&iw);
-		cb->setObjProperty(id,10,h->getOwner());
+		cb->setObjProperty(id, 10, h->getOwner().getNum());
 	}
 }
 
@@ -6022,7 +6032,7 @@ void CBank::newTurn() const
 			cb->setObjProperty (id, ObjProperty::BANK_DAYCOUNTER, 1); //daycounter++
 	}
 }
-bool CBank::wasVisited (TPlayerColor player) const
+bool CBank::wasVisited (PlayerColor player) const
 {
 	return !bc;
 }
@@ -6289,11 +6299,11 @@ void CGPyramid::endBattle (const CGHeroInstance *h, const BattleResult *result)
 }
 void CGKeys::setPropertyDer (ui8 what, ui32 val) //101-108 - enable key for player 1-8
 {
-	if (what >= 101 && what <= (100 + GameConstants::PLAYER_LIMIT))
-		playerKeyMap.find(what-101)->second.insert((ui8)val);
+	if (what >= 101 && what <= (100 + PlayerColor::PLAYER_LIMIT_I))
+		playerKeyMap.find(PlayerColor(what-101))->second.insert((ui8)val);
 }
 
-bool CGKeys::wasMyColorVisited (TPlayerColor player) const
+bool CGKeys::wasMyColorVisited (PlayerColor player) const
 {
 	if (vstd::contains(playerKeyMap[player], subID)) //creates set if it's not there
 		return true;
@@ -6316,7 +6326,7 @@ const std::string CGKeys::getName() const
 	return name;
 }
 
-bool CGKeymasterTent::wasVisited (TPlayerColor player) const
+bool CGKeymasterTent::wasVisited (PlayerColor player) const
 {
 	return wasMyColorVisited (player);
 }
@@ -6326,7 +6336,7 @@ void CGKeymasterTent::onHeroVisit( const CGHeroInstance * h ) const
 	int txt_id;
 	if (!wasMyColorVisited (h->getOwner()) )
 	{
-		cb->setObjProperty(id, h->tempOwner+101, subID);
+		cb->setObjProperty(id, h->tempOwner.getNum()+101, subID);
 		txt_id=19;
 	}
 	else
@@ -6400,8 +6410,8 @@ void CGBorderGate::onHeroVisit( const CGHeroInstance * h ) const //TODO: passabi
 ui8 CGBorderGate::getPassableness() const
 {
 	ui8 ret = 0;
-	for (int i = 0; i < GameConstants::PLAYER_LIMIT; i++)
-		ret |= wasMyColorVisited(i)<<i;
+	for (int i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++)
+		ret |= wasMyColorVisited(PlayerColor(i))<<i;
 	return ret;
 }
 
@@ -6699,7 +6709,7 @@ void CCartographer::buyMap (const CGHeroInstance *h, ui32 accept) const
 		//water = 0; land = 1; underground = 2;
 		cb->getAllTiles (fw.tiles, h->tempOwner, subID - 1, !subID + 1); //reveal appropriate tiles
 		cb->sendAndApply (&fw);
-		cb->setObjProperty (id, 10, h->tempOwner);
+		cb->setObjProperty (id, 10, h->tempOwner.getNum());
 	}
 }
 
@@ -6714,18 +6724,18 @@ void CGObelisk::onHeroVisit( const CGHeroInstance * h ) const
 	iw.player = h->tempOwner;
 	TeamState *ts = cb->gameState()->getPlayerTeam(h->tempOwner);
 	assert(ts);
-	int team = ts->id;
+	TeamID team = ts->id;
 
 	if(!wasVisited(team))
 	{
 		iw.text.addTxt(MetaString::ADVOB_TXT, 96);
 		cb->sendAndApply(&iw);
 
-		cb->setObjProperty(id,20,team); //increment general visited obelisks counter
+		cb->setObjProperty(id, 20, h->tempOwner.getNum()); //increment general visited obelisks counter
 
-		openWindow(OpenWindow::PUZZLE_MAP,h->tempOwner);
+		openWindow(OpenWindow::PUZZLE_MAP, h->tempOwner.getNum());
 
-		cb->setObjProperty(id,10,team); //mark that particular obelisk as visited
+		cb->setObjProperty(id, 10, h->tempOwner.getNum()); //mark that particular obelisk as visited
 	}
 	else
 	{
@@ -6753,12 +6763,12 @@ void CGObelisk::setPropertyDer( ui8 what, ui32 val )
 	switch(what)
 	{
 	case 20:
-		assert(val < GameConstants::PLAYER_LIMIT);
-		visited[val]++;
+		assert(val < PlayerColor::PLAYER_LIMIT_I);
+		visited[TeamID(val)]++;
 
-		if(visited[val] > obeliskCount)
+		if(visited[TeamID(val)] > obeliskCount)
 		{
-			tlog0 << "Error: Visited " << visited[val] << "\t\t" << obeliskCount << std::endl;
+			tlog0 << "Error: Visited " << visited[TeamID(val)] << "\t\t" << obeliskCount << std::endl;
 			assert(0);
 		}
 
@@ -6770,15 +6780,15 @@ void CGLighthouse::onHeroVisit( const CGHeroInstance * h ) const
 {
 	if(h->tempOwner != tempOwner)
 	{
-		ui8 oldOwner = tempOwner;
+		PlayerColor oldOwner = tempOwner;
 		cb->setOwner(this,h->tempOwner); //not ours? flag it!
 		showInfoDialog(h,69,soundBase::LIGHTHOUSE);
 		giveBonusTo(h->tempOwner);
 
-		if(oldOwner < GameConstants::PLAYER_LIMIT) //remove bonus from old owner
+		if(oldOwner < PlayerColor::PLAYER_LIMIT) //remove bonus from old owner
 		{
 			RemoveBonus rb(RemoveBonus::PLAYER);
-			rb.whoID = oldOwner;
+			rb.whoID = oldOwner.getNum();
 			rb.source = Bonus::OBJECT;
 			rb.id = id.getNum();
 			cb->sendAndApply(&rb);
@@ -6788,7 +6798,7 @@ void CGLighthouse::onHeroVisit( const CGHeroInstance * h ) const
 
 void CGLighthouse::initObj()
 {
-	if(tempOwner < GameConstants::PLAYER_LIMIT)
+	if(tempOwner < PlayerColor::PLAYER_LIMIT)
 	{
 		giveBonusTo(tempOwner);
 	}
@@ -6801,12 +6811,12 @@ const std::string & CGLighthouse::getHoverText() const
 	return hoverName;
 }
 
-void CGLighthouse::giveBonusTo( ui8 player ) const
+void CGLighthouse::giveBonusTo( PlayerColor player ) const
 {
 	GiveBonus gb(GiveBonus::PLAYER);
 	gb.bonus.type = Bonus::SEA_MOVEMENT;
 	gb.bonus.val = 500;
-	gb.id = player;
+	gb.id = player.getNum();
 	gb.bonus.duration = Bonus::PERMANENT;
 	gb.bonus.source = Bonus::OBJECT;
 	gb.bonus.sid = id.getNum();
@@ -6917,7 +6927,7 @@ void CArmedInstance::armyChanged()
 
 CBonusSystemNode * CArmedInstance::whereShouldBeAttached(CGameState *gs)
 {
-	if(tempOwner < GameConstants::PLAYER_LIMIT)
+	if(tempOwner < PlayerColor::PLAYER_LIMIT)
 		return gs->getPlayer(tempOwner);
 	else
 		return &gs->globalEffects;

+ 21 - 20
lib/CObjectHandler.h

@@ -114,11 +114,11 @@ public:
 	virtual void initObj(); //synchr
 	virtual void setProperty(ui8 what, ui32 val);//synchr
 //unified interface, AI helpers
-	virtual bool wasVisited (ui8 player) const;
+	virtual bool wasVisited (PlayerColor player) const;
 	virtual bool wasVisited (const CGHeroInstance * h) const;
 
 	static void preInit(); //called before objs receive their initObj
-	static void postInit();//caleed after objs receive their initObj
+	static void postInit();//called after objs receive their initObj
 };
 
 class DLL_LINKAGE IBoatGenerator
@@ -173,15 +173,15 @@ public:
 	ObjectInstanceID id;//number of object in map's vector
 	CGDefInfo * defInfo;
 
-	TPlayerColor tempOwner;
+	PlayerColor tempOwner;
 	bool blockVisit; //if non-zero then blocks the tile but is visitable from neighbouring tile
 
 	virtual ui8 getPassableness() const; //bitmap - if the bit is set the corresponding player can pass through the visitable tiles of object, even if it's blockvis; if not set - default properties from definfo are used
 	virtual int3 getSightCenter() const; //"center" tile from which the sight distance is calculated
 	virtual int getSightRadious() const; //sight distance (should be used if player-owned structure)
 	void getSightTiles(boost::unordered_set<int3, ShashInt3> &tiles) const; //returns reference to the set
-	int getOwner() const;
-	void setOwner(int ow);
+	PlayerColor getOwner() const;
+	void setOwner(PlayerColor ow);
 	int getWidth() const; //returns width of object graphic in tiles
 	int getHeight() const; //returns height of object graphic in tiles
 	bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) form left top tile of image (x, y in tiles)
@@ -193,7 +193,7 @@ public:
 	std::set<int3> getBlockedPos() const; //returns set of positions blocked by this object
 	bool isVisitable() const; //returns true if object is visitable
 	bool operator<(const CGObjectInstance & cmp) const;  //screen printing priority comparing
-	void hideTiles(TPlayerColor ourplayer, int radius) const;
+	void hideTiles(PlayerColor ourplayer, int radius) const;
 	CGObjectInstance();
 	virtual ~CGObjectInstance();
 	//CGObjectInstance(const CGObjectInstance & right);
@@ -235,9 +235,10 @@ public:
 class DLL_LINKAGE CPlayersVisited: public CGObjectInstance
 {
 public:
-	std::set<TPlayerColor> players; //players that visited this object
+	std::set<PlayerColor> players; //players that visited this object
 
-	bool wasVisited(TPlayerColor player) const;
+	bool wasVisited(PlayerColor player) const;
+	bool wasVisited(TeamID team) const;
 	void setPropertyDer(ui8 what, ui32 val) override;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -435,7 +436,7 @@ class DLL_LINKAGE CSpecObjInfo
 {
 public:
 	virtual ~CSpecObjInfo(){};
-	ui8 player; //owner
+	PlayerColor player; //owner
 };
 
 class DLL_LINKAGE CCreGenAsCastleInfo : public virtual CSpecObjInfo
@@ -654,7 +655,7 @@ public:
 	int spellsAtLevel(int level, bool checkGuild) const; //levels are counted from 1 (1 - 5)
 	bool armedGarrison() const; //true if town has creatures in garrison or garrisoned hero
 
-	void removeCapitols (ui8 owner) const;
+	void removeCapitols (PlayerColor owner) const;
 	void addHeroToStructureVisitors(const CGHeroInstance *h, si32 structureInstanceID) const; //hero must be visiting or garrisoned in town
 
 	CGTownInstance();
@@ -928,7 +929,7 @@ public:
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void initObj() override;
 
-	void collectRes(int player) const;
+	void collectRes(PlayerColor player) const;
 	void fightForRes(ui32 agreed, const CGHeroInstance *h) const;
 	void endBattle(BattleResult *result, const CGHeroInstance *h) const;
 
@@ -977,12 +978,12 @@ public:
 	ui32 producedQuantity;
 
 	void offerLeavingGuards(const CGHeroInstance *h) const;
-	void endBattle(BattleResult *result, TPlayerColor attackingPlayer) const;
+	void endBattle(BattleResult *result, PlayerColor attackingPlayer) const;
 	void fight(ui32 agreed, const CGHeroInstance *h) const;
 
 	void onHeroVisit(const CGHeroInstance * h) const override;
 
-	void flagMine(TPlayerColor player) const;
+	void flagMine(PlayerColor player) const;
 	void newTurn() const override;
 	void initObj() override;
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -998,7 +999,7 @@ class DLL_LINKAGE CGVisitableOPW : public CGObjectInstance //objects visitable O
 public:
 	ui8 visited; //true if object has been visited this week
 
-	bool wasVisited(TPlayerColor player) const;
+	bool wasVisited(PlayerColor player) const;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void newTurn() const override;
 
@@ -1094,11 +1095,11 @@ public:
 class DLL_LINKAGE CGKeys : public CGObjectInstance //Base class for Keymaster and guards
 {
 public:
-	static std::map <TPlayerColor, std::set <ui8> > playerKeyMap; //[players][keysowned]
+	static std::map <PlayerColor, std::set <ui8> > playerKeyMap; //[players][keysowned]
 	//SubID 0 - lightblue, 1 - green, 2 - red, 3 - darkblue, 4 - brown, 5 - purple, 6 - white, 7 - black
 
 	const std::string getName() const; //depending on color
-	bool wasMyColorVisited (TPlayerColor player) const;
+	bool wasMyColorVisited (PlayerColor player) const;
 
 	const std::string & getHoverText() const override;
 
@@ -1113,7 +1114,7 @@ protected:
 class DLL_LINKAGE CGKeymasterTent : public CGKeys
 {
 public:
-	bool wasVisited (TPlayerColor player) const;
+	bool wasVisited (PlayerColor player) const;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -1211,7 +1212,7 @@ class DLL_LINKAGE CBank : public CArmedInstance
 	void initialize() const;
 	void reset(ui16 var1);
 	void newTurn() const override;
-	bool wasVisited (TPlayerColor player) const override;
+	bool wasVisited (PlayerColor player) const override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 
 	virtual void fightGuards (const CGHeroInstance *h, ui32 accept) const;
@@ -1290,7 +1291,7 @@ class DLL_LINKAGE CGObelisk : public CPlayersVisited
 {
 public:
 	static ui8 obeliskCount; //how many obelisks are on map
-	static std::map<TTeamID, ui8> visited; //map: team_id => how many obelisks has been visited
+	static std::map<TeamID, ui8> visited; //map: team_id => how many obelisks has been visited
 
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void initObj() override;
@@ -1315,7 +1316,7 @@ public:
 	{
 		h & static_cast<CGObjectInstance&>(*this);
 	}
-	void giveBonusTo( ui8 player ) const;
+	void giveBonusTo( PlayerColor player ) const;
 };
 
 class DLL_LINKAGE CGMarket : public CGObjectInstance, public IMarket

+ 1 - 1
lib/Connection.cpp

@@ -228,7 +228,7 @@ CPack * CConnection::retreivePack()
 	return ret;
 }
 
-void CConnection::sendPackToServer(const CPack &pack, TPlayerColor player, ui32 requestID)
+void CConnection::sendPackToServer(const CPack &pack, PlayerColor player, ui32 requestID)
 {
 	boost::unique_lock<boost::mutex> lock(*wmx);
 	tlog5 << "Sending to server a pack of type " << typeid(pack).name() << std::endl;

+ 3 - 3
lib/Connection.h

@@ -314,8 +314,8 @@ si32 idToNumber(const T &t, typename boost::enable_if<boost::is_convertible<T,si
 	return t;
 }
 
-template<typename T>
-si32 idToNumber(const BaseForID<T> &t)
+template<typename T, typename NT>
+NT idToNumber(const BaseForID<T, NT> &t)
 {
 	return t.getNum();
 }
@@ -1291,7 +1291,7 @@ public:
 	virtual ~CConnection(void);
 
 	CPack *retreivePack(); //gets from server next pack (allocates it with new)
-	void sendPackToServer(const CPack &pack, TPlayerColor player, ui32 requestID);
+	void sendPackToServer(const CPack &pack, PlayerColor player, ui32 requestID);
 
 	void disableStackSendingByID();
 	void enableStackSendingByID();

+ 5 - 0
lib/GameConstants.cpp

@@ -19,6 +19,11 @@
 #include "CSpellHandler.h"
 
 const SlotID SlotID::COMMANDER_SLOT_PLACEHOLDER = SlotID(-2);
+const PlayerColor PlayerColor::CANNOT_DETERMINE = PlayerColor(253);
+const PlayerColor PlayerColor::UNFLAGGABLE = PlayerColor(254);
+const PlayerColor PlayerColor::NEUTRAL = PlayerColor(255);
+const PlayerColor PlayerColor::PLAYER_LIMIT = PlayerColor(PLAYER_LIMIT_I);
+const TeamID TeamID::NO_TEAM = TeamID(255);
 
 #define ID_LIKE_OPERATORS_INTERNAL(A, B, AN, BN)	\
 bool operator==(const A & a, const B & b)			\

+ 65 - 40
lib/GameConstants.h

@@ -22,12 +22,9 @@ namespace GameConstants
 
 	const int PUZZLE_MAP_PIECES = 48;
 
-	const int PLAYER_LIMIT = 8; //player limit per map
 	const int MAX_HEROES_PER_PLAYER = 8;
 	const int AVAILABLE_HEROES_PER_PLAYER = 2;
 
-	const int UNFLAGGABLE_PLAYER = 254; //254 - neutral objects (pandora, banks)
-	const int NEUTRAL_PLAYER=255;
 	const int ALL_PLAYERS = 255; //bitfield
 
 	const ui16 BACKPACK_START = 19;
@@ -115,29 +112,29 @@ bool operator OP (const CLASS_NAME & b) const		\
 	return num OP b.num;							\
 }
 
-#define INSTID_LIKE_CLASS_COMMON(CLASS_NAME)		\
-public:												\
-CLASS_NAME() : BaseForID<CLASS_NAME>(-1) {}			\
-CLASS_NAME(const CLASS_NAME & other):				\
-	BaseForID<CLASS_NAME>(other)					\
-{													\
-}													\
-CLASS_NAME & operator=(const CLASS_NAME & other)	\
-{													\
-	num = other.num;								\
-	return *this;									\
-}													\
-explicit CLASS_NAME(si32 id)						\
-	: BaseForID<CLASS_NAME>(id)						\
+#define INSTID_LIKE_CLASS_COMMON(CLASS_NAME, NUMERIC_NAME)	\
+public:														\
+CLASS_NAME() : BaseForID<CLASS_NAME, NUMERIC_NAME>(-1) {}	\
+CLASS_NAME(const CLASS_NAME & other):						\
+	BaseForID<CLASS_NAME, NUMERIC_NAME>(other)				\
+{															\
+}															\
+CLASS_NAME & operator=(const CLASS_NAME & other)			\
+{															\
+	num = other.num;										\
+	return *this;											\
+}															\
+explicit CLASS_NAME(si32 id)								\
+	: BaseForID<CLASS_NAME, NUMERIC_NAME>(id)				\
 {}
 
-template < typename Derived>
+template < typename Derived, typename NumericType>
 class BaseForID
 {
 protected:
-	si32 num;
+	NumericType num;
 public:
-	si32 getNum() const
+	NumericType getNum() const
 	{
 		return num;
 	}
@@ -146,50 +143,56 @@ public:
 		h & num;
 	}
 
-	explicit BaseForID(si32 _num = -1)
+	explicit BaseForID(NumericType _num = -1)
 	{
 		num = _num;
 	}
 
-	OP_DECL_INT(BaseForID<Derived>, ==)
-	OP_DECL_INT(BaseForID<Derived>, !=)
-	OP_DECL_INT(BaseForID<Derived>, <)
-	OP_DECL_INT(BaseForID<Derived>, >)
-	OP_DECL_INT(BaseForID<Derived>, <=)
-	OP_DECL_INT(BaseForID<Derived>, >=)
+	void advance(int change)
+	{
+		num += change;
+	}
+
+	typedef BaseForID<Derived, NumericType> __SelfType;
+	OP_DECL_INT(__SelfType, ==)
+	OP_DECL_INT(__SelfType, !=)
+	OP_DECL_INT(__SelfType, <)
+	OP_DECL_INT(__SelfType, >)
+	OP_DECL_INT(__SelfType, <=)
+	OP_DECL_INT(__SelfType, >=)
 };
 
-template<typename Der>
-std::ostream & operator << (std::ostream & os, BaseForID<Der> id);
+template<typename Der, typename Num>
+std::ostream & operator << (std::ostream & os, BaseForID<Der, Num> id);
 
-template<typename Der>
-std::ostream & operator << (std::ostream & os, BaseForID<Der> id)
+template<typename Der, typename Num>
+std::ostream & operator << (std::ostream & os, BaseForID<Der, Num> id)
 {
 	return os << id.getNum();
 }
 
-class ArtifactInstanceID : public BaseForID<ArtifactInstanceID>
+class ArtifactInstanceID : public BaseForID<ArtifactInstanceID, si32>
 {
-	INSTID_LIKE_CLASS_COMMON(ArtifactInstanceID)
+	INSTID_LIKE_CLASS_COMMON(ArtifactInstanceID, si32)
 
 	friend class CGameInfoCallback;
 	friend class CNonConstInfoCallback;
 };
 
 
-class ObjectInstanceID : public BaseForID<ObjectInstanceID>
+class ObjectInstanceID : public BaseForID<ObjectInstanceID, si32>
 {
-	INSTID_LIKE_CLASS_COMMON(ObjectInstanceID)
+	INSTID_LIKE_CLASS_COMMON(ObjectInstanceID, si32)
 
 	friend class CGameInfoCallback;
 	friend class CNonConstInfoCallback;
 };
 
-class SlotID : public BaseForID<SlotID>
+class SlotID : public BaseForID<SlotID, si32>
 {
-	INSTID_LIKE_CLASS_COMMON(SlotID)
+	INSTID_LIKE_CLASS_COMMON(SlotID, si32)
 
-		friend class CGameInfoCallback;
+	friend class CGameInfoCallback;
 	friend class CNonConstInfoCallback;
 
 	DLL_LINKAGE static const SlotID COMMANDER_SLOT_PLACEHOLDER;
@@ -200,6 +203,30 @@ class SlotID : public BaseForID<SlotID>
 	}
 };
 
+class PlayerColor : public BaseForID<PlayerColor, ui8>
+{
+	INSTID_LIKE_CLASS_COMMON(PlayerColor, ui8)
+
+	DLL_LINKAGE static const PlayerColor CANNOT_DETERMINE; //253
+	DLL_LINKAGE static const PlayerColor UNFLAGGABLE; //254 - neutral objects (pandora, banks)
+	DLL_LINKAGE static const PlayerColor NEUTRAL; //255
+	DLL_LINKAGE static const int PLAYER_LIMIT_I = 8; //player limit per map
+	DLL_LINKAGE static const PlayerColor PLAYER_LIMIT; //player limit per map
+
+	friend class CGameInfoCallback;
+	friend class CNonConstInfoCallback;
+};
+
+class TeamID : public BaseForID<TeamID, ui8>
+{
+	INSTID_LIKE_CLASS_COMMON(TeamID, ui8)
+
+	DLL_LINKAGE static const TeamID NO_TEAM;
+
+	friend class CGameInfoCallback;
+	friend class CNonConstInfoCallback;
+};
+
 // #ifndef INSTANTIATE_BASE_FOR_ID_HERE
 // extern template std::ostream & operator << <ArtifactInstanceID>(std::ostream & os, BaseForID<ArtifactInstanceID> id);
 // extern template std::ostream & operator << <ObjectInstanceID>(std::ostream & os, BaseForID<ObjectInstanceID> id);
@@ -820,8 +847,6 @@ typedef si64 TExpType;
 typedef std::pair<ui32, ui32> TDmgRange;
 typedef si32 TBonusSubtype;
 typedef si32 TQuantity;
-typedef ui8 TPlayerColor;
-typedef ui8 TTeamID;
 
 
 #undef ID_LIKE_CLASS_COMMON

+ 1 - 1
lib/HeroBonus.cpp

@@ -1522,7 +1522,7 @@ StackOwnerLimiter::StackOwnerLimiter()
 {
 }
 
-StackOwnerLimiter::StackOwnerLimiter(ui8 Owner)
+StackOwnerLimiter::StackOwnerLimiter(PlayerColor Owner)
 	: owner(Owner)
 {
 }

+ 2 - 2
lib/HeroBonus.h

@@ -889,9 +889,9 @@ public:
 class DLL_LINKAGE StackOwnerLimiter : public ILimiter //applies only to creatures of given alignment
 {
 public:
-	ui8 owner;
+	PlayerColor owner;
 	StackOwnerLimiter();
-	StackOwnerLimiter(ui8 Owner);
+	StackOwnerLimiter(PlayerColor Owner);
 
 	int limit(const BonusLimitationContext &context) const OVERRIDE;
 

+ 33 - 33
lib/IGameCallback.cpp

@@ -44,14 +44,14 @@ CGameState * CPrivilagedInfoCallback::gameState ()
 	return gs;
 }
 
-TPlayerColor CGameInfoCallback::getOwner(ObjectInstanceID heroID) const
+PlayerColor CGameInfoCallback::getOwner(ObjectInstanceID heroID) const
 {
 	const CGObjectInstance *obj = getObj(heroID);
-	ERROR_RET_VAL_IF(!obj, "No such object!", -1);
+	ERROR_RET_VAL_IF(!obj, "No such object!", PlayerColor::CANNOT_DETERMINE);
 	return obj->tempOwner;
 }
 
-int CGameInfoCallback::getResource(TPlayerColor Player, Res::ERes which) const
+int CGameInfoCallback::getResource(PlayerColor Player, Res::ERes which) const
 {
 	const PlayerState *p = getPlayer(Player);
 	ERROR_RET_VAL_IF(!p, "No player info!", -1);
@@ -59,7 +59,7 @@ int CGameInfoCallback::getResource(TPlayerColor Player, Res::ERes which) const
 	return p->resources[which];
 }
 
-const CGHeroInstance* CGameInfoCallback::getSelectedHero( TPlayerColor Player ) const
+const CGHeroInstance* CGameInfoCallback::getSelectedHero( PlayerColor Player ) const
 {
 	const PlayerState *p = getPlayer(Player);
 	ERROR_RET_VAL_IF(!p, "No player info!", NULL);
@@ -71,14 +71,14 @@ const CGHeroInstance* CGameInfoCallback::getSelectedHero() const
 	return getSelectedHero(gs->currentPlayer);
 }
 
-const PlayerSettings * CGameInfoCallback::getPlayerSettings(TPlayerColor color) const
+const PlayerSettings * CGameInfoCallback::getPlayerSettings(PlayerColor color) const
 {
 	return &gs->scenarioOps->getIthPlayersSettings(color);
 }
 
-void CPrivilagedInfoCallback::getTilesInRange( boost::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, int player/*=-1*/, int mode/*=0*/ ) const
+void CPrivilagedInfoCallback::getTilesInRange( boost::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, boost::optional<PlayerColor> player/*=uninit*/, int mode/*=0*/ ) const
 {
-	if(player >= GameConstants::PLAYER_LIMIT)
+	if(!!player && *player >= PlayerColor::PLAYER_LIMIT)
 	{
 		tlog1 << "Illegal call to getTilesInRange!\n";
 		return;
@@ -87,7 +87,7 @@ void CPrivilagedInfoCallback::getTilesInRange( boost::unordered_set<int3, ShashI
 		getAllTiles (tiles, player, -1, 0);
 	else
 	{
-		const TeamState * team = gs->getPlayerTeam(player);
+		const TeamState * team = !player ? NULL : gs->getPlayerTeam(*player);
 		for (int xd = std::max<int>(pos.x - radious , 0); xd <= std::min<int>(pos.x + radious, gs->map->width - 1); xd++)
 		{
 			for (int yd = std::max<int>(pos.y - radious, 0); yd <= std::min<int>(pos.y + radious, gs->map->height - 1); yd++)
@@ -95,7 +95,7 @@ void CPrivilagedInfoCallback::getTilesInRange( boost::unordered_set<int3, ShashI
 				double distance = pos.dist2d(int3(xd,yd,pos.z)) - 0.5;
 				if(distance <= radious)
 				{
-					if(player < 0
+					if(!player
 						|| (mode == 1  && team->fogOfWarMap[xd][yd][pos.z]==0)
 						|| (mode == -1 && team->fogOfWarMap[xd][yd][pos.z]==1)
 					)
@@ -106,9 +106,9 @@ void CPrivilagedInfoCallback::getTilesInRange( boost::unordered_set<int3, ShashI
 	}
 }
 
-void CPrivilagedInfoCallback::getAllTiles (boost::unordered_set<int3, ShashInt3> &tiles, int Player/*=-1*/, int level, int surface ) const
+void CPrivilagedInfoCallback::getAllTiles (boost::unordered_set<int3, ShashInt3> &tiles, boost::optional<PlayerColor> Player/*=uninit*/, int level, int surface ) const
 {
-	if(Player >= GameConstants::PLAYER_LIMIT)
+	if(!!Player && *Player >= PlayerColor::PLAYER_LIMIT)
 	{
 		tlog1 << "Illegal call to getAllTiles !\n";
 		return;
@@ -262,14 +262,14 @@ inline TerrainTile * CNonConstInfoCallback::getTile( int3 pos )
 	return &gs->map->getTile(pos);
 }
 
-const PlayerState * CGameInfoCallback::getPlayer(TPlayerColor color, bool verbose) const
+const PlayerState * CGameInfoCallback::getPlayer(PlayerColor color, bool verbose) const
 {
 	ERROR_VERBOSE_OR_NOT_RET_VAL_IF(!hasAccess(color), verbose, "Cannot access player " << color << "info!", NULL);
 	ERROR_VERBOSE_OR_NOT_RET_VAL_IF(!vstd::contains(gs->players,color), verbose, "Cannot find player " << color << "info!", NULL);
 	return &gs->players[color];
 }
 
-const CTown * CGameInfoCallback::getNativeTown(TPlayerColor color) const
+const CTown * CGameInfoCallback::getNativeTown(PlayerColor color) const
 {
 	const PlayerSettings *ps = getPlayerSettings(color);
 	ERROR_RET_VAL_IF(!ps, "There is no such player!", NULL);
@@ -398,7 +398,7 @@ void CGameInfoCallback::getThievesGuildInfo(SThievesGuildInfo & thi, const CGObj
 	}
 }
 
-int CGameInfoCallback::howManyTowns(TPlayerColor Player) const
+int CGameInfoCallback::howManyTowns(PlayerColor Player) const
 {
 	ERROR_RET_VAL_IF(!hasAccess(Player), "Access forbidden!", -1);
 	return gs->players[Player].towns.size();
@@ -466,7 +466,7 @@ std::vector < std::string > CGameInfoCallback::getObjDescriptions(int3 pos) cons
 	return ret;
 }
 
-bool CGameInfoCallback::isVisible(int3 pos, boost::optional<TPlayerColor> Player) const
+bool CGameInfoCallback::isVisible(int3 pos, boost::optional<PlayerColor> Player) const
 {
 	//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
 	return gs->map->isInTheMap(pos) && (!Player || gs->isVisible(pos, *Player));
@@ -477,7 +477,7 @@ bool CGameInfoCallback::isVisible(int3 pos) const
 	return isVisible(pos, player);
 }
 
-bool CGameInfoCallback::isVisible( const CGObjectInstance *obj, boost::optional<TPlayerColor> Player ) const
+bool CGameInfoCallback::isVisible( const CGObjectInstance *obj, boost::optional<PlayerColor> Player ) const
 {
 	return gs->isVisible(obj, Player);
 }
@@ -529,7 +529,7 @@ std::vector < const CGObjectInstance * > CGameInfoCallback::getFlaggableObjects(
 	const TerrainTile *t = getTile(pos);
 	ERROR_RET_VAL_IF(!t, "Not a valid tile requested!", ret);
 	BOOST_FOREACH(const CGObjectInstance *obj, t->blockingObjects)
-		if(obj->tempOwner != 254)
+		if(obj->tempOwner != PlayerColor::UNFLAGGABLE)
 			ret.push_back(obj);
 // 	const std::vector < std::pair<const CGObjectInstance*,SDL_Rect> > & objs = CGI->mh->ttiles[pos.x][pos.y][pos.z].objects;
 // 	for(size_t b=0; b<objs.size(); ++b)
@@ -665,12 +665,12 @@ const CMapHeader * CGameInfoCallback::getMapHeader() const
 	return gs->map;
 }
 
-bool CGameInfoCallback::hasAccess(boost::optional<TPlayerColor> playerId) const
+bool CGameInfoCallback::hasAccess(boost::optional<PlayerColor> playerId) const
 {
 	return !player || gs->getPlayerRelations( *playerId, *player ) != PlayerRelations::ENEMIES;
 }
 
-EPlayerStatus::EStatus CGameInfoCallback::getPlayerStatus(TPlayerColor player) const
+EPlayerStatus::EStatus CGameInfoCallback::getPlayerStatus(PlayerColor player) const
 {
 	const PlayerState *ps = gs->getPlayer(player, false);
 	ERROR_RET_VAL_IF(!ps, "No such player!", EPlayerStatus::WRONG);
@@ -683,7 +683,7 @@ std::string CGameInfoCallback::getTavernGossip(const CGObjectInstance * townOrTa
 	return "GOSSIP TEST";
 }
 
-PlayerRelations::PlayerRelations CGameInfoCallback::getPlayerRelations( TPlayerColor color1, TPlayerColor color2 ) const
+PlayerRelations::PlayerRelations CGameInfoCallback::getPlayerRelations( PlayerColor color1, PlayerColor color2 ) const
 {
 	return gs->getPlayerRelations(color1, color2);
 }
@@ -693,7 +693,7 @@ bool CGameInfoCallback::canGetFullInfo(const CGObjectInstance *obj) const
 	return !obj || hasAccess(obj->tempOwner);
 }
 
-int CGameInfoCallback::getHeroCount( TPlayerColor player, bool includeGarrisoned ) const
+int CGameInfoCallback::getHeroCount( PlayerColor player, bool includeGarrisoned ) const
 {
 	int ret = 0;
 	const PlayerState *p = gs->getPlayer(player);
@@ -718,7 +718,7 @@ bool CGameInfoCallback::isOwnedOrVisited(const CGObjectInstance *obj) const
 	return visitor->ID == Obj::HERO && canGetFullInfo(visitor); //owned or allied hero is a visitor
 }
 
-int CGameInfoCallback::getCurrentPlayer() const
+PlayerColor CGameInfoCallback::getCurrentPlayer() const
 {
 	return gs->currentPlayer;
 }
@@ -727,7 +727,7 @@ CGameInfoCallback::CGameInfoCallback()
 {
 }
 
-CGameInfoCallback::CGameInfoCallback(CGameState *GS, boost::optional<TPlayerColor> Player)
+CGameInfoCallback::CGameInfoCallback(CGameState *GS, boost::optional<PlayerColor> Player)
 {
 	gs = GS;
 	player = Player;
@@ -777,7 +777,7 @@ std::vector < const CGHeroInstance *> CPlayerSpecificInfoCallback::getHeroesInfo
 	return ret;
 }
 
-boost::optional<TPlayerColor> CPlayerSpecificInfoCallback::getMyColor() const
+boost::optional<PlayerColor> CPlayerSpecificInfoCallback::getMyColor() const
 {
 	return player;
 }
@@ -903,17 +903,17 @@ CGTownInstance *CNonConstInfoCallback::getTown(ObjectInstanceID objid)
 	return const_cast<CGTownInstance*>(CGameInfoCallback::getTown(objid));
 }
 
-TeamState *CNonConstInfoCallback::getTeam(ui8 teamID)
+TeamState *CNonConstInfoCallback::getTeam(TeamID teamID)
 {
 	return const_cast<TeamState*>(CGameInfoCallback::getTeam(teamID));
 }
 
-TeamState *CNonConstInfoCallback::getPlayerTeam(TPlayerColor color)
+TeamState *CNonConstInfoCallback::getPlayerTeam(PlayerColor color)
 {
 	return const_cast<TeamState*>(CGameInfoCallback::getPlayerTeam(color));
 }
 
-PlayerState * CNonConstInfoCallback::getPlayer( TPlayerColor color, bool verbose )
+PlayerState * CNonConstInfoCallback::getPlayer( PlayerColor color, bool verbose )
 {
 	return const_cast<PlayerState*>(CGameInfoCallback::getPlayer(color, verbose));
 }
@@ -928,15 +928,15 @@ CGObjectInstance * CNonConstInfoCallback::getObjInstance( ObjectInstanceID oid )
 	return gs->map->objects[oid.num];
 }
 
-const TeamState * CGameInfoCallback::getTeam( ui8 teamID ) const
+const TeamState * CGameInfoCallback::getTeam( TeamID teamID ) const
 {
-	ERROR_RET_VAL_IF(!vstd::contains(gs->teams, teamID), "Cannot find info for team " << int(teamID), NULL);
+	ERROR_RET_VAL_IF(!vstd::contains(gs->teams, teamID), "Cannot find info for team " << teamID, NULL);
 	const TeamState *ret = &gs->teams[teamID];
 	ERROR_RET_VAL_IF(!!player && !vstd::contains(ret->players, *player), "Illegal attempt to access team data!", NULL);
 	return ret;
 }
 
-const TeamState * CGameInfoCallback::getPlayerTeam( TPlayerColor color ) const
+const TeamState * CGameInfoCallback::getPlayerTeam( PlayerColor color ) const
 {
 	const PlayerState * ps = getPlayer(color);
 	if (ps)
@@ -953,7 +953,7 @@ const CGHeroInstance* CGameInfoCallback::getHeroWithSubid( int subid ) const
 	return NULL;
 }
 
-int CGameInfoCallback::getLocalPlayer() const
+PlayerColor CGameInfoCallback::getLocalPlayer() const
 {
 	return getCurrentPlayer();
 }
@@ -978,7 +978,7 @@ void IGameEventRealizer::showInfoDialog( InfoWindow *iw )
 	commitPackage(iw);
 }
 
-void IGameEventRealizer::showInfoDialog(const std::string &msg, TPlayerColor player)
+void IGameEventRealizer::showInfoDialog(const std::string &msg, PlayerColor player)
 {
 	InfoWindow iw;
 	iw.player = player;
@@ -1005,7 +1005,7 @@ const CGObjectInstance * IGameCallback::putNewObject(Obj ID, int subID, int3 pos
 	return getObj(no.id); //id field will be filled during applying on gs
 }
 
-const CGCreature * IGameCallback::putNewMonster(int creID, int count, int3 pos)
+const CGCreature * IGameCallback::putNewMonster(CreatureID creID, int count, int3 pos)
 {
 	const CGObjectInstance *m = putNewObject(Obj::MONSTER, creID, pos);
 	setObjProperty(m->id, ObjProperty::MONSTER_COUNT, count);

+ 32 - 32
lib/IGameCallback.h

@@ -65,10 +65,10 @@ class DLL_LINKAGE CGameInfoCallback : public virtual CCallbackBase
 {
 protected:
 	CGameInfoCallback();
-	CGameInfoCallback(CGameState *GS, boost::optional<TPlayerColor> Player);
-	bool hasAccess(boost::optional<TPlayerColor> playerId) const;
-	bool isVisible(int3 pos, boost::optional<TPlayerColor> Player) const;
-	bool isVisible(const CGObjectInstance *obj, boost::optional<TPlayerColor> Player) const;
+	CGameInfoCallback(CGameState *GS, boost::optional<PlayerColor> Player);
+	bool hasAccess(boost::optional<PlayerColor> playerId) const;
+	bool isVisible(int3 pos, boost::optional<PlayerColor> Player) const;
+	bool isVisible(const CGObjectInstance *obj, boost::optional<PlayerColor> Player) const;
 	bool isVisible(const CGObjectInstance *obj) const;
 
 	bool canGetFullInfo(const CGObjectInstance *obj) const; //true we player owns obj or ally owns obj or privileged mode
@@ -81,15 +81,15 @@ public:
 	bool isAllowed(int type, int id); //type: 0 - spell; 1- artifact; 2 - secondary skill
 
 	//player
-	const PlayerState * getPlayer(TPlayerColor color, bool verbose = true) const;
-	int getResource(TPlayerColor Player, Res::ERes which) const;
+	const PlayerState * getPlayer(PlayerColor color, bool verbose = true) const;
+	int getResource(PlayerColor Player, Res::ERes which) const;
 	bool isVisible(int3 pos) const;
-	PlayerRelations::PlayerRelations getPlayerRelations(TPlayerColor color1, TPlayerColor color2) const;
+	PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const;
 	void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object
-	EPlayerStatus::EStatus getPlayerStatus(TPlayerColor player) const; //-1 if no such player
-	int getCurrentPlayer() const; //player that currently makes move // TODO synchronous turns
-	virtual int getLocalPlayer() const; //player that is currently owning given client (if not a client, then returns current player)
-	const PlayerSettings * getPlayerSettings(TPlayerColor color) const;
+	EPlayerStatus::EStatus getPlayerStatus(PlayerColor player) const; //-1 if no such player
+	PlayerColor getCurrentPlayer() const; //player that currently makes move // TODO synchronous turns
+	virtual PlayerColor getLocalPlayer() const; //player that is currently owning given client (if not a client, then returns current player)
+	const PlayerSettings * getPlayerSettings(PlayerColor color) const;
 
 
 	//armed object
@@ -98,11 +98,11 @@ public:
 	//hero
 	const CGHeroInstance* getHero(ObjectInstanceID objid) const;
 	const CGHeroInstance* getHeroWithSubid(int subid) const;
-	int getHeroCount(TPlayerColor player, bool includeGarrisoned) const;
+	int getHeroCount(PlayerColor player, bool includeGarrisoned) const;
 	bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) 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 CGHeroInstance * hero) const; //estimates damage of given spell; returns 0 if spell causes no dmg
-	const CGHeroInstance* getSelectedHero(TPlayerColor player) const; //NULL if no hero is selected
+	const CGHeroInstance* getSelectedHero(PlayerColor player) const; //NULL if no hero is selected
 	const CGHeroInstance* getSelectedHero() const; //of current (active) player
 	const CArtifactInstance * getArtInstance(ArtifactInstanceID aid) const;
 	const CGObjectInstance * getObjInstance(ObjectInstanceID oid) const;
@@ -113,7 +113,7 @@ public:
 	std::vector <const CGObjectInstance * > getVisitableObjs(int3 pos, bool verbose = true)const;
 	std::vector <const CGObjectInstance * > getFlaggableObjects(int3 pos) const;
 	std::vector <std::string > getObjDescriptions(int3 pos)const; //returns descriptions of objects at pos in order from the lowest to the highest
-	TPlayerColor getOwner(ObjectInstanceID heroID) const;
+	PlayerColor getOwner(ObjectInstanceID heroID) const;
 	const CGObjectInstance *getObjByQuestIdentifier(int identifier) const; //NULL if object has been removed (eg. killed)
 
 	//map
@@ -126,18 +126,18 @@ public:
 
 	//town
 	const CGTownInstance* getTown(ObjectInstanceID objid) const;
-	int howManyTowns(TPlayerColor Player) const;
+	int howManyTowns(PlayerColor Player) const;
 	const CGTownInstance * getTownInfo(int val, bool mode)const; //mode = 0 -> val = player town serial; mode = 1 -> val = object id (serial)
 	std::vector<const CGHeroInstance *> getAvailableHeroes(const CGObjectInstance * townOrTavern) const; //heroes that can be recruited
 	std::string getTavernGossip(const CGObjectInstance * townOrTavern) const; 
 	EBuildingState::EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID 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
 	std::set<BuildingID> getBuildingRequiments(const CGTownInstance *t, BuildingID ID);
 	virtual bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const;
-	const CTown *getNativeTown(TPlayerColor color) const;
+	const CTown *getNativeTown(PlayerColor color) const;
 
 	//from gs
-	const TeamState *getTeam(ui8 teamID) const;
-	const TeamState *getPlayerTeam(TPlayerColor color) const;
+	const TeamState *getTeam(TeamID teamID) const;
+	const TeamState *getPlayerTeam(PlayerColor color) const;
 	std::set<BuildingID> getBuildingRequiments(const CGTownInstance *t, BuildingID ID) const;
 	EBuildingState::EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID) const;// 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
 };
@@ -149,7 +149,7 @@ public:
 	int howManyTowns() const;
 	int howManyHeroes(bool includeGarrisoned = true) const;
 	int3 getGrailPos(double &outKnownRatio);
-	boost::optional<TPlayerColor> getMyColor() const;
+	boost::optional<PlayerColor> getMyColor() const;
 
 	std::vector <const CGTownInstance *> getTownsInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible
 	int getHeroSerial(const CGHeroInstance * hero, bool includeGarrisoned=true) const;
@@ -163,7 +163,7 @@ public:
 	int getResourceAmount(Res::ERes type) const;
 	TResources getResourceAmount() const;
 	const std::vector< std::vector< std::vector<ui8> > > & getVisibilityMap()const; //returns visibility map 
-	const PlayerSettings * getPlayerSettings(TPlayerColor color) const;
+	const PlayerSettings * getPlayerSettings(PlayerColor color) const;
 };
 
 class DLL_LINKAGE CPrivilagedInfoCallback : public CGameInfoCallback
@@ -171,8 +171,8 @@ class DLL_LINKAGE CPrivilagedInfoCallback : public CGameInfoCallback
 public:
 	CGameState * gameState ();
 	void getFreeTiles (std::vector<int3> &tiles) const; //used for random spawns
-	void getTilesInRange(boost::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, int player=-1, int mode=0) const;  //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 -  only unrevealed
-	void getAllTiles (boost::unordered_set<int3, ShashInt3> &tiles, int player=-1, int level=-1, int surface=0) const; //returns all tiles on given level (-1 - both levels, otherwise number of level); surface: 0 - land and water, 1 - only land, 2 - only water
+	void getTilesInRange(boost::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, boost::optional<PlayerColor> player = boost::optional<PlayerColor>(), int mode=0) const;  //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 -  only unrevealed
+	void getAllTiles (boost::unordered_set<int3, ShashInt3> &tiles, boost::optional<PlayerColor> player = boost::optional<PlayerColor>(), int level=-1, int surface=0) const; //returns all tiles on given level (-1 - both levels, otherwise number of level); surface: 0 - land and water, 1 - only land, 2 - only water
 	ArtifactID getRandomArt (int flags);
 	ArtifactID getArtSync (ui32 rand, int flags, bool erasePicked); //synchronous
 	void pickAllowedArtsSet(std::vector<const CArtifact*> &out); //gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
@@ -188,9 +188,9 @@ public:
 class DLL_LINKAGE CNonConstInfoCallback : public CPrivilagedInfoCallback
 {
 public:
-	PlayerState *getPlayer(TPlayerColor color, bool verbose = true);
-	TeamState *getTeam(ui8 teamID);//get team by team ID
-	TeamState *getPlayerTeam(TPlayerColor color);// get team by player color
+	PlayerState *getPlayer(PlayerColor color, bool verbose = true);
+	TeamState *getTeam(TeamID teamID);//get team by team ID
+	TeamState *getPlayerTeam(PlayerColor color);// get team by player color
 	CGHeroInstance *getHero(ObjectInstanceID objid);
 	CGTownInstance *getTown(ObjectInstanceID objid);
 	TerrainTile * getTile(int3 pos);
@@ -207,7 +207,7 @@ public:
 	virtual void setObjProperty(ObjectInstanceID objid, int prop, si64 val);
 
 
-	virtual void showInfoDialog(const std::string &msg, TPlayerColor player);
+	virtual void showInfoDialog(const std::string &msg, PlayerColor player);
 };
 
 class DLL_LINKAGE IGameEventCallback : public IGameEventRealizer
@@ -216,15 +216,15 @@ public:
 	virtual void changeSpells(const CGHeroInstance * hero, bool give, const std::set<SpellID> &spells)=0;
 	virtual bool removeObject(const CGObjectInstance * obj)=0;
 	virtual void setBlockVis(ObjectInstanceID objid, bool bv)=0;
-	virtual void setOwner(const CGObjectInstance * objid, TPlayerColor owner)=0;
+	virtual void setOwner(const CGObjectInstance * objid, PlayerColor owner)=0;
 	virtual void setHoverName(const CGObjectInstance * obj, MetaString * name)=0;
 	virtual void changePrimSkill(const CGHeroInstance * hero, PrimarySkill::PrimarySkill which, si64 val, bool abs=false)=0;
 	virtual void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false)=0; 
 	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(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits, const boost::function<void()> &cb) =0; //cb will be called when player closes garrison window
-	virtual void showThievesGuildWindow(TPlayerColor player, ObjectInstanceID requestingObjId) =0;
-	virtual void giveResource(TPlayerColor player, Res::ERes which, int val)=0;
+	virtual void showThievesGuildWindow(PlayerColor player, ObjectInstanceID requestingObjId) =0;
+	virtual void giveResource(PlayerColor player, Res::ERes which, int val)=0;
 
 	virtual void giveCreatures(const CArmedInstance *objid, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove) =0;
 	virtual void takeCreatures(ObjectInstanceID objid, const std::vector<CStackBasicDescriptor> &creatures) =0;
@@ -251,11 +251,11 @@ public:
 	virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false)=0; //if any of armies is hero, hero will be used
 	virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false)=0; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle
 	virtual void setAmount(ObjectInstanceID objid, ui32 val)=0;
-	virtual bool moveHero(ObjectInstanceID hid, int3 dst, ui8 instant, TPlayerColor asker = GameConstants::NEUTRAL_PLAYER)=0;
+	virtual bool moveHero(ObjectInstanceID hid, int3 dst, ui8 instant, PlayerColor asker = PlayerColor::NEUTRAL)=0;
 	virtual void giveHeroBonus(GiveBonus * bonus)=0;
 	virtual void setMovePoints(SetMovePoints * smp)=0;
 	virtual void setManaPoints(ObjectInstanceID hid, int val)=0;
-	virtual void giveHero(ObjectInstanceID id, TPlayerColor player)=0;
+	virtual void giveHero(ObjectInstanceID id, PlayerColor player)=0;
 	virtual void changeObjPos(ObjectInstanceID objid, int3 newPos, ui8 flags)=0;
 	virtual void sendAndApply(CPackForClient * info)=0;
 	virtual void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2)=0; //when two heroes meet on adventure map
@@ -270,7 +270,7 @@ public:
 
 	//do sth
 	const CGObjectInstance *putNewObject(Obj ID, int subID, int3 pos);
-	const CGCreature *putNewMonster(int creID, int count, int3 pos);
+	const CGCreature *putNewMonster(CreatureID creID, int count, int3 pos);
 
 	friend struct CPack;
 	friend struct CPackForClient;

+ 2 - 2
lib/IGameEventsReceiver.h

@@ -128,7 +128,7 @@ public:
 	virtual void objectPropertyChanged(const SetObjectProperty * sop){}; //eg. mine has been flagged
 	virtual void objectRemoved(const CGObjectInstance *obj){}; //eg. collected resource, picked artifact, beaten hero
 	virtual void playerBlocked(int reason){}; //reason: 0 - upcoming battle
-	virtual void gameOver(TPlayerColor player, bool victory){}; //player lost or won the game
-	virtual void playerStartsTurn(TPlayerColor player){};
+	virtual void gameOver(PlayerColor player, bool victory){}; //player lost or won the game
+	virtual void playerStartsTurn(PlayerColor player){};
 	virtual void showComp(const Component &comp, std::string message) {}; //display component in the advmapint infobox
 };

+ 1 - 1
lib/Mapping/CCampaignHandler.cpp

@@ -401,7 +401,7 @@ void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> he
 	}
 }
 
-const CGHeroInstance * CCampaignScenario::strongestHero( TPlayerColor owner ) const
+const CGHeroInstance * CCampaignScenario::strongestHero( PlayerColor owner ) const
 {
 	using boost::adaptors::filtered;
 	std::function<bool(CGHeroInstance*)> isOwned =  [=](const CGHeroInstance *h){ return h->tempOwner == owner; };

+ 1 - 1
lib/Mapping/CCampaignHandler.h

@@ -112,7 +112,7 @@ public:
 
 	std::vector<CGHeroInstance *> crossoverHeroes;
 
-	const CGHeroInstance * strongestHero(TPlayerColor owner) const;
+	const CGHeroInstance * strongestHero(PlayerColor owner) const;
 
 	void loadPreconditionRegions(ui32 regions);
 	void prepareCrossoverHeroes(std::vector<CGHeroInstance *> heroes);

+ 1 - 1
lib/Mapping/CMap.cpp

@@ -131,7 +131,7 @@ CMapHeader::CMapHeader() : version(EMapFormat::SOD), height(72), width(72),
 	twoLevel(true), difficulty(1), levelLimit(0), howManyTeams(0), areAnyPlayers(false)
 {
 	allowedHeroes = VLC->heroh->getDefaultAllowedHeroes();
-	players.resize(GameConstants::PLAYER_LIMIT);
+	players.resize(PlayerColor::PLAYER_LIMIT_I);
 }
 
 CMapHeader::~CMapHeader()

+ 2 - 2
lib/Mapping/CMap.h

@@ -126,7 +126,7 @@ struct DLL_LINKAGE PlayerInfo
 	int3 posOfMainTown;
 
 	/** The team id to which the player belongs to. The default value is 255 representing that the player belongs to no team. */
-	ui8 team;
+	TeamID team;
 
 	/** Unused. True if a hero should be generated. */
 	bool generateHero;
@@ -573,7 +573,7 @@ public:
 	/** Specifies the victory condition. The default value is defeat all enemies. */
 	VictoryCondition victoryCondition;
 
-	/** A list containing information about players. The default size of the vector is GameConstants::PLAYER_LIMIT. */
+	/** A list containing information about players. The default size of the vector is PlayerColor::PLAYER_LIMIT. */
 	std::vector<PlayerInfo> players;
 
 	/** The number of teams. */

+ 1 - 1
lib/Mapping/CMapInfo.cpp

@@ -10,7 +10,7 @@
 void CMapInfo::countPlayers()
 {
 	actualHumanPlayers = playerAmnt = humanPlayers = 0;
-	for(int i=0;i<GameConstants::PLAYER_LIMIT;i++)
+	for(int i=0; i<PlayerColor::PLAYER_LIMIT_I; i++)
 	{
 		if(mapHeader->players[i].canHumanPlay)
 		{

+ 13 - 13
lib/Mapping/MapFormatH3M.cpp

@@ -379,19 +379,19 @@ void CMapLoaderH3M::readTeamInfo()
 	if(mapHeader->howManyTeams > 0)
 	{
 		// Teams
-		for(int i = 0; i < GameConstants::PLAYER_LIMIT; ++i)
+		for(int i = 0; i < PlayerColor::PLAYER_LIMIT_I; ++i)
 		{
-			mapHeader->players[i].team = reader.readUInt8();
+			mapHeader->players[i].team = TeamID(reader.readUInt8());
 		}
 	}
 	else
 	{
 		// No alliances
-		for(int i = 0; i < GameConstants::PLAYER_LIMIT; i++)
+		for(int i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++)
 		{
 			if(mapHeader->players[i].canComputerPlay || mapHeader->players[i].canHumanPlay)
 			{
-				mapHeader->players[i].team = mapHeader->howManyTeams++;
+				mapHeader->players[i].team = TeamID(mapHeader->howManyTeams++);
 			}
 		}
 	}
@@ -1070,7 +1070,7 @@ void CMapLoaderH3M::readObjects()
 			{
 				CGGarrison * gar = new CGGarrison();
 				nobj = gar;
-				nobj->setOwner(reader.readUInt8());
+				nobj->setOwner(PlayerColor(reader.readUInt8()));
 				reader.skip(3);
 				readCreatureSet(gar, 7);
 				if(map->version > EMapFormat::ROE)
@@ -1140,7 +1140,7 @@ void CMapLoaderH3M::readObjects()
 		case Obj::ABANDONED_MINE:
 			{
 				nobj = new CGMine();
-				nobj->setOwner(reader.readUInt8());
+				nobj->setOwner(PlayerColor(reader.readUInt8()));
 				reader.skip(3);
 				break;
 			}
@@ -1150,7 +1150,7 @@ void CMapLoaderH3M::readObjects()
 		case Obj::CREATURE_GENERATOR4:
 			{
 				nobj = new CGDwelling();
-				nobj->setOwner(reader.readUInt8());
+				nobj->setOwner(PlayerColor(reader.readUInt8()));
 				reader.skip(3);
 				break;
 			}
@@ -1246,7 +1246,7 @@ void CMapLoaderH3M::readObjects()
 					break; case Obj::RANDOM_DWELLING_FACTION: spec = new CCreGenLeveledInfo();
 				}
 
-				spec->player = reader.readUInt32();
+				spec->player = PlayerColor(reader.readUInt32());
 
 				//216 and 217
 				if (auto castleSpec = dynamic_cast<CCreGenAsCastleInfo *>(spec))
@@ -1331,7 +1331,7 @@ void CMapLoaderH3M::readObjects()
 		case Obj::SHIPYARD:
 			{
 				nobj = new CGShipyard();
-				nobj->setOwner(reader.readUInt32());
+				nobj->setOwner(PlayerColor(reader.readUInt32()));
 				break;
 			}
 		case Obj::HERO_PLACEHOLDER: //hero placeholder
@@ -1339,7 +1339,7 @@ void CMapLoaderH3M::readObjects()
 				CGHeroPlaceholder * hp = new CGHeroPlaceholder();
 				nobj = hp;
 
-				hp->setOwner(reader.readUInt8());
+				hp->setOwner(PlayerColor(reader.readUInt8()));
 
 				int htid = reader.readUInt8();; //hero type id
 				nobj->subID = htid;
@@ -1424,7 +1424,7 @@ void CMapLoaderH3M::readObjects()
 		case Obj::LIGHTHOUSE: //Lighthouse
 			{
 				nobj = new CGLighthouse();
-				nobj->tempOwner = reader.readUInt32();
+				nobj->tempOwner = PlayerColor(reader.readUInt32());
 				break;
 			}
 		case Obj::ALTAR_OF_SACRIFICE:
@@ -1532,7 +1532,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven)
 		map->questIdentifierToId[identifier] = idToBeGiven;
 	}
 
-	ui8 owner = reader.readUInt8();
+	PlayerColor owner = PlayerColor(reader.readUInt8());
 	nhi->subID = reader.readUInt8();
 
 	for(int j = 0; j < map->predefinedHeroes.size(); ++j)
@@ -1884,7 +1884,7 @@ CGTownInstance * CMapLoaderH3M::readTown(int castleID)
 	{
 		nt->identifier = reader.readUInt32();
 	}
-	nt->tempOwner = reader.readUInt8();
+	nt->tempOwner = PlayerColor(reader.readUInt8());
 	bool hasName = reader.readBool();
 	if(hasName)
 	{

+ 31 - 30
lib/NetPacks.h

@@ -65,14 +65,14 @@ struct CPackForClient : public CPack
 
 struct CPackForServer : public CPack
 {
-	TPlayerColor player;
+	PlayerColor player;
 	CConnection *c;
 	CGameState* GS(CGameHandler *gh);
 	CPackForServer()
 	{
 		type = 2;
 		c = NULL;
-		player = 255;
+		player = PlayerColor::NEUTRAL;
 	};
 
 	bool applyGh(CGameHandler *gh);//called after applying to gs
@@ -203,7 +203,7 @@ struct PackageApplied : public CPackForClient //94
 	ui8 result; //0 - something went wrong, request hasn't been realized; 1 - OK
 	ui32 packType; //type id of applied package
 	ui32 requestID; //an ID given by client to the request that was applied
-	TPlayerColor player;
+	PlayerColor player;
 
 
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -234,7 +234,7 @@ struct PlayerBlocked : public CPackForClient //96
 	enum EReason { UPCOMING_BATTLE };
 
 	EReason reason;
-	TPlayerColor player;
+	PlayerColor player;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -248,7 +248,7 @@ struct YourTurn : public CPackForClient //100
 	void applyCl(CClient *cl);
 	DLL_LINKAGE void applyGs(CGameState *gs);
 
-	TPlayerColor player;
+	PlayerColor player;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -262,7 +262,7 @@ struct SetResource : public CPackForClient //102
 	void applyCl(CClient *cl);
 	DLL_LINKAGE void applyGs(CGameState *gs);
 
-	TPlayerColor player;
+	PlayerColor player;
 	Res::ERes resid;
 	TResourceCap val;
 
@@ -277,7 +277,7 @@ struct SetResource : public CPackForClient //102
  	void applyCl(CClient *cl);
  	DLL_LINKAGE void applyGs(CGameState *gs);
 
- 	TPlayerColor player;
+ 	PlayerColor player;
  	TResources res; //res[resid] => res amount
 
  	template <typename Handler> void serialize(Handler &h, const int version)
@@ -394,7 +394,8 @@ struct FoWChange : public CPackForClient //112
 	DLL_LINKAGE void applyGs(CGameState *gs);
 
 	boost::unordered_set<int3, struct ShashInt3 > tiles;
-	ui8 player, mode; //mode==0 - hide, mode==1 - reveal
+	PlayerColor player;
+	ui8 mode; //mode==0 - hide, mode==1 - reveal
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & tiles & player & mode;
@@ -415,7 +416,7 @@ struct SetAvailableHeroes : public CPackForClient //113
 	void applyCl(CClient *cl);
 	DLL_LINKAGE void applyGs(CGameState *gs);
 
-	TPlayerColor player;
+	PlayerColor player;
 	si32 hid[GameConstants::AVAILABLE_HEROES_PER_PLAYER]; //-1 if no hero
 	CSimpleArmy army[GameConstants::AVAILABLE_HEROES_PER_PLAYER];
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -478,7 +479,7 @@ struct PlayerEndsGame : public CPackForClient //117
 	void applyCl(CClient *cl);
 	DLL_LINKAGE void applyGs(CGameState *gs);
 
-	TPlayerColor player;
+	PlayerColor player;
 	ui8 victory;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -558,7 +559,7 @@ struct AddQuest : public CPackForClient //121
 	void applyCl(CClient *cl){};
 	DLL_LINKAGE void applyGs(CGameState *gs);
 
-	TPlayerColor player;
+	PlayerColor player;
 	QuestInfo quest;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -758,7 +759,7 @@ struct HeroRecruited : public CPackForClient //515
 	si32 hid;//subID of hero
 	ObjectInstanceID tid;
 	int3 tile;
-	TPlayerColor player;
+	PlayerColor player;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -774,7 +775,7 @@ struct GiveHero : public CPackForClient //516
 	DLL_LINKAGE void applyGs(CGameState *gs);
 
 	ObjectInstanceID id; //object id
-	TPlayerColor player;
+	PlayerColor player;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -987,7 +988,7 @@ struct ArtifactLocation
 	}
 
 	DLL_LINKAGE const CArmedInstance *relatedObj() const; //hero or the stack owner
-	DLL_LINKAGE int owningPlayer() const;
+	DLL_LINKAGE PlayerColor owningPlayer() const;
 	DLL_LINKAGE CArtifactSet *getHolderArtSet();
 	DLL_LINKAGE CBonusSystemNode *getHolderNode();
 	DLL_LINKAGE const CArtifactSet *getHolderArtSet() const;
@@ -1106,7 +1107,7 @@ struct NewTurn : public CPackForClient //101
 
 	std::set<Hero> heroes; //updates movement and mana points
 	//std::vector<SetResources> res;//resource list
-	std::map<TPlayerColor, TResources> res; //player ID => resource value[res_id]
+	std::map<PlayerColor, TResources> res; //player ID => resource value[res_id]
 	std::vector<SetAvailableCreatures> cres;//creatures to be placed in towns
 	ui32 day;
 	bool resetBuilded;
@@ -1150,7 +1151,7 @@ struct InfoWindow : public CPackForClient //103  - displays simple info window
 
 	MetaString text;
 	std::vector<Component> components;
-	TPlayerColor player;
+	PlayerColor player;
 	ui16 soundID;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -1273,7 +1274,7 @@ struct BlockingDialog : public Query//2003
 
 	MetaString text;
 	std::vector<Component> components;
-	TPlayerColor player;
+	PlayerColor player;
 	ui8 flags;
 	ui16 soundID;
 
@@ -1606,7 +1607,7 @@ struct BattleResultsApplied : public CPackForClient //3012
 {
 	BattleResultsApplied(){type = 3012;}
 
-	ui8 player1, player2;
+	PlayerColor player1, player2;
 
 	void applyCl(CClient *cl);
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -1742,7 +1743,7 @@ struct BattleObstaclePlaced : public CPackForClient //3020
 struct ShowInInfobox : public CPackForClient //107
 {
 	ShowInInfobox(){type = 107;};
-	ui8 player;
+	PlayerColor player;
 	Component c;
 	MetaString text;
 
@@ -1757,7 +1758,7 @@ struct AdvmapSpellCast : public CPackForClient //108
 {
 	AdvmapSpellCast(){type = 108;}
 	const CGHeroInstance * caster;
-	si32 spellID;
+	SpellID spellID;
 
 	void applyCl(CClient *cl);
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -2022,7 +2023,7 @@ struct HireHero : public CPackForServer
 	HireHero(si32 HID, ObjectInstanceID TID):hid(HID),tid(TID){};
 	si32 hid; //available hero serial
 	ObjectInstanceID tid; //town (tavern) id
-	TPlayerColor player;
+	PlayerColor player;
 
 	bool applyGh(CGameHandler *gh);
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -2049,7 +2050,7 @@ struct QueryReply : public CPackForServer
 	QueryReply(){type = 6000;};
 	QueryReply(ui32 QID, ui32 Answer):qid(QID),answer(Answer){type = 6000;};
 	ui32 qid, answer; //hero and artifact id
-	TPlayerColor player;
+	PlayerColor player;
 
 	bool applyGh(CGameHandler *gh);
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -2130,14 +2131,14 @@ struct SaveGame : public CPackForClient, public CPackForServer
 struct PlayerMessage : public CPackForClient, public CPackForServer //513
 {
 	PlayerMessage(){CPackForClient::type = 513;};
-	PlayerMessage(ui8 Player, const std::string &Text)
+	PlayerMessage(PlayerColor Player, const std::string &Text)
 		:player(Player),text(Text)
 	{CPackForClient::type = 513;};
 	void applyCl(CClient *cl);
 	void applyGs(CGameState *gs){};
 	bool applyGh(CGameHandler *gh);
 
-	TPlayerColor player;
+	PlayerColor player;
 	std::string text;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -2154,7 +2155,7 @@ struct SetSelection : public CPackForClient, public CPackForServer //514
 	bool applyGh(CGameHandler *gh);
 	void applyCl(CClient *cl);
 
-	TPlayerColor player;
+	PlayerColor player;
 	ObjectInstanceID id;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -2168,7 +2169,7 @@ struct CenterView : public CPackForClient//515
 	CenterView(){CPackForClient::type = 515;};
 	void applyCl(CClient *cl);
 
-	TPlayerColor player;
+	PlayerColor player;
 	int3 pos;
 	ui32 focusTime; //ms
 
@@ -2301,9 +2302,9 @@ struct RequestOptionsChange : public CPregamePackToHost
 	enum EWhat {TOWN, HERO, BONUS};
 	ui8 what;
 	si8 direction; //-1 or +1
-	TPlayerColor playerID;
+	ui8 playerID;
 
-	RequestOptionsChange(ui8 What, si8 Dir, TPlayerColor Player)
+	RequestOptionsChange(ui8 What, si8 Dir, ui8 Player)
 		:what(What), direction(Dir), playerID(Player)
 	{}
 	RequestOptionsChange(){}
@@ -2318,7 +2319,7 @@ struct RequestOptionsChange : public CPregamePackToHost
 
 struct PlayerLeft : public CPregamePackToPropagate
 {
-	TPlayerColor playerID;
+	ui8 playerID;
 
 	void apply(CSelectionScreen *selScreen); //that functions are implemented in CPreGame.cpp
 
@@ -2331,7 +2332,7 @@ struct PlayerLeft : public CPregamePackToPropagate
 struct PlayersNames : public CPregamePackToPropagate
 {
 public:
-	std::map<TPlayerColor, std::string> playerNames;
+	std::map<ui8, std::string> playerNames;
 
 	void apply(CSelectionScreen *selScreen); //that functions are implemented in CPreGame.cpp
 

+ 12 - 12
lib/NetPacksLib.cpp

@@ -36,14 +36,14 @@
 
 DLL_LINKAGE void SetResource::applyGs( CGameState *gs )
 {
-	assert(player < GameConstants::PLAYER_LIMIT);
+	assert(player < PlayerColor::PLAYER_LIMIT);
 	vstd::amax(val, 0); //new value must be >= 0
 	gs->getPlayer(player)->resources[resid] = val;
 }
 
 DLL_LINKAGE void SetResources::applyGs( CGameState *gs )
 {
-	assert(player < GameConstants::PLAYER_LIMIT);
+	assert(player < PlayerColor::PLAYER_LIMIT);
 	gs->getPlayer(player)->resources = res;
 }
 
@@ -224,7 +224,7 @@ DLL_LINKAGE void GiveBonus::applyGs( CGameState *gs )
 		cbsn = gs->getHero(ObjectInstanceID(id));
 		break;
 	case PLAYER:
-		cbsn = gs->getPlayer(id);
+		cbsn = gs->getPlayer(PlayerColor(id));
 		break;
 	case TOWN:
 		cbsn = gs->getTown(ObjectInstanceID(id));
@@ -277,7 +277,7 @@ DLL_LINKAGE void RemoveBonus::applyGs( CGameState *gs )
 	if (who == HERO)
 		node = gs->getHero(ObjectInstanceID(whoID));
 	else
-		node = gs->getPlayer(whoID);
+		node = gs->getPlayer(PlayerColor(whoID));
 
 	BonusList &bonuses = node->getBonusList();
 
@@ -309,7 +309,7 @@ DLL_LINKAGE void RemoveObject::applyGs( CGameState *gs )
 		gs->map->heroes -= h;
 		p->heroes -= h;
 		h->detachFrom(h->whereShouldBeAttached(gs));
-		h->tempOwner = 255; //no one owns beaten hero
+		h->tempOwner = PlayerColor::NEUTRAL; //no one owns beaten hero
 
 		if(h->visitedTown)
 		{
@@ -636,10 +636,10 @@ DLL_LINKAGE const CArmedInstance * ArtifactLocation::relatedObj() const
 	return boost::apply_visitor(ObjectRetriever(), artHolder);
 }
 
-DLL_LINKAGE int ArtifactLocation::owningPlayer() const
+DLL_LINKAGE PlayerColor ArtifactLocation::owningPlayer() const
 {
 	auto obj = relatedObj();
-	return obj ? obj->tempOwner : GameConstants::NEUTRAL_PLAYER;
+	return obj ? obj->tempOwner : PlayerColor::NEUTRAL;
 }
 
 DLL_LINKAGE CArtifactSet *ArtifactLocation::getHolderArtSet()
@@ -901,9 +901,9 @@ DLL_LINKAGE void NewTurn::applyGs( CGameState *gs )
 		hero->mana = h.mana;
 	}
 
-	for(std::map<ui8, TResources>::iterator i = res.begin(); i != res.end(); i++)
+	for(auto i = res.cbegin(); i != res.cend(); i++)
 	{
-		assert(i->first < GameConstants::PLAYER_LIMIT);
+		assert(i->first < PlayerColor::PLAYER_LIMIT);
 		gs->getPlayer(i->first)->resources = i->second;
 	}
 
@@ -944,10 +944,10 @@ DLL_LINKAGE void SetObjectProperty::applyGs( CGameState *gs )
 		if(obj->ID == Obj::TOWN)
 		{
 			CGTownInstance *t = static_cast<CGTownInstance*>(obj);
-			if(t->tempOwner < GameConstants::PLAYER_LIMIT)
+			if(t->tempOwner < PlayerColor::PLAYER_LIMIT)
 				gs->getPlayer(t->tempOwner)->towns -= t;
-			if(val < GameConstants::PLAYER_LIMIT)
-				gs->getPlayer(val)->towns.push_back(t);
+			if(val < PlayerColor::PLAYER_LIMIT_I)
+				gs->getPlayer(PlayerColor(val))->towns.push_back(t);
 		}
 
 		CBonusSystemNode *nodeToMove = cai->whatShouldBeAttached();

+ 4 - 4
lib/RMG/CMapGenOptions.cpp

@@ -61,14 +61,14 @@ si8 CMapGenOptions::getPlayersCnt() const
 
 void CMapGenOptions::setPlayersCnt(si8 value)
 {
-	if((value >= 1 && value <= GameConstants::PLAYER_LIMIT) || value == RANDOM_SIZE)
+	if((value >= 1 && value <= PlayerColor::PLAYER_LIMIT_I) || value == RANDOM_SIZE)
 	{
 		playersCnt = value;
 	}
 	else
 	{
 		throw std::runtime_error("Players count of RMG options should be between 1 and " +
-			boost::lexical_cast<std::string>(GameConstants::PLAYER_LIMIT) + " or CMapGenOptions::RANDOM_SIZE for random.");
+			boost::lexical_cast<std::string>(PlayerColor::PLAYER_LIMIT) + " or CMapGenOptions::RANDOM_SIZE for random.");
 	}
 }
 
@@ -97,14 +97,14 @@ si8 CMapGenOptions::getCompOnlyPlayersCnt() const
 
 void CMapGenOptions::setCompOnlyPlayersCnt(si8 value)
 {
-	if(value == RANDOM_SIZE || (value >= 0 && value <= GameConstants::PLAYER_LIMIT - playersCnt))
+	if(value == RANDOM_SIZE || (value >= 0 && value <= PlayerColor::PLAYER_LIMIT_I - playersCnt))
 	{
 		compOnlyPlayersCnt = value;
 	}
 	else
 	{
 		throw std::runtime_error(std::string("Computer only players count of RMG options should be ") +
-			"between 0 and <GameConstants::PLAYER_LIMIT - " + boost::lexical_cast<std::string>(playersCnt) +
+			"between 0 and <PlayerColor::PLAYER_LIMIT - " + boost::lexical_cast<std::string>(playersCnt) +
 			"(playersCount)> or CMapGenOptions::RANDOM_SIZE for random.");
 	}
 }

+ 4 - 4
lib/RMG/CMapGenOptions.h

@@ -92,14 +92,14 @@ public:
 	 * Gets the count of the players. The default value is RANDOM_SIZE representing a random
 	 * player count.
 	 *
-	 * @return the count of the players ranging from 1 to GameConstants::PLAYER_LIMIT or RANDOM_SIZE for random
+	 * @return the count of the players ranging from 1 to PlayerColor::PLAYER_LIMIT or RANDOM_SIZE for random
 	 */
 	si8 getPlayersCnt() const;
 
 	/**
 	 * Sets the count of the players.
 	 *
-	 * @param value the count of the players ranging from 1 to GameConstants::PLAYER_LIMIT, RANDOM_SIZE for random
+	 * @param value the count of the players ranging from 1 to PlayerColor::PLAYER_LIMIT, RANDOM_SIZE for random
 	 */
 	void setPlayersCnt(si8 value);
 
@@ -121,14 +121,14 @@ public:
 	/**
 	 * Gets the count of the computer only players. The default value is 0.
 	 *
-	 * @return the count of the computer only players ranging from 0 to <GameConstants::PLAYER_LIMIT - players count> or RANDOM_SIZE for random
+	 * @return the count of the computer only players ranging from 0 to <PlayerColor::PLAYER_LIMIT - players count> or RANDOM_SIZE for random
 	 */
 	si8 getCompOnlyPlayersCnt() const;
 
 	/**
 	 * Sets the count of the computer only players.
 	 *
-	 * @param value the count of the computer only players ranging from 0 to <GameConstants::PLAYER_LIMIT - players count>, RANDOM_SIZE for random
+	 * @param value the count of the computer only players ranging from 0 to <PlayerColor::PLAYER_LIMIT - players count>, RANDOM_SIZE for random
 	 */
 	void setCompOnlyPlayersCnt(si8 value);
 

+ 18 - 18
lib/RMG/CMapGenerator.cpp

@@ -11,7 +11,7 @@
 #include "../CTownHandler.h"
 #include "../StringConstants.h"
 
-CMapGenerator::CMapGenerator(const CMapGenOptions & mapGenOptions, const std::map<TPlayerColor, CPlayerSettings> & players, int randomSeed) :
+CMapGenerator::CMapGenerator(const CMapGenOptions & mapGenOptions, const std::map<PlayerColor, CPlayerSettings> & players, int randomSeed) :
 	mapGenOptions(mapGenOptions), randomSeed(randomSeed), players(players)
 {
 	gen.seed(randomSeed);
@@ -57,10 +57,10 @@ void CMapGenerator::validateOptions() const
 	}
 	if(mapGenOptions.getPlayersCnt() == CMapGenOptions::RANDOM_SIZE)
 	{
-		if(playersCnt != GameConstants::PLAYER_LIMIT)
+		if(playersCnt != PlayerColor::PLAYER_LIMIT_I)
 		{
 			throw std::runtime_error(std::string("If the count of players is random size, ")
-				+ "the count of the items in the players map should equal GameConstants::PLAYER_LIMIT.");
+				+ "the count of the items in the players map should equal PlayerColor::PLAYER_LIMIT.");
 		}
 		if(playersCnt == mapGenOptions.getPlayersCnt())
 		{
@@ -81,10 +81,10 @@ void CMapGenerator::validateOptions() const
 		else
 		{
 			if(playersCnt != mapGenOptions.getPlayersCnt() || (playersCnt == mapGenOptions.getPlayersCnt()
-				&& compOnlyPlayersCnt != GameConstants::PLAYER_LIMIT - playersCnt))
+				&& compOnlyPlayersCnt != PlayerColor::PLAYER_LIMIT_I - playersCnt))
 			{
 				throw std::runtime_error(std::string("If the count of players is fixed and the count of comp only players random, ")
-					+ "the items in the players map should equal GameConstants::PLAYER_LIMIT.");
+					+ "the items in the players map should equal PlayerColor::PLAYER_LIMIT.");
 			}
 		}
 	}
@@ -107,7 +107,7 @@ void CMapGenerator::finalizeMapGenOptions()
 {
 	if(mapGenOptions.getPlayersCnt() == CMapGenOptions::RANDOM_SIZE)
 	{
-		mapGenOptions.setPlayersCnt(gen.getInteger(countHumanPlayers(), GameConstants::PLAYER_LIMIT));
+		mapGenOptions.setPlayersCnt(gen.getInteger(countHumanPlayers(), PlayerColor::PLAYER_LIMIT_I));
 
 		// Remove AI players only from the end of the players map if necessary
 		for(auto itrev = players.end(); itrev != players.begin();)
@@ -217,11 +217,11 @@ std::string CMapGenerator::getMapDescription() const
 		const CPlayerSettings & pSettings = pair.second;
 		if(pSettings.getPlayerType() == CPlayerSettings::HUMAN)
 		{
-			ss << ", " << GameConstants::PLAYER_COLOR_NAMES[pSettings.getColor()] << " is human";
+			ss << ", " << GameConstants::PLAYER_COLOR_NAMES[pSettings.getColor().getNum()] << " is human";
 		}
 		if(pSettings.getStartingTown() != CPlayerSettings::RANDOM_TOWN)
 		{
-			ss << ", " << GameConstants::PLAYER_COLOR_NAMES[pSettings.getColor()]
+			ss << ", " << GameConstants::PLAYER_COLOR_NAMES[pSettings.getColor().getNum()]
 				<< " town choice is " << ETownType::names[pSettings.getStartingTown()];
 		}
 	}
@@ -276,9 +276,9 @@ void CMapGenerator::addPlayerInfo()
 			player.canHumanPlay = true;
 		}
 		auto itTeam = std::next(teamNumbers[j].begin(), gen.getInteger(0, teamNumbers[j].size() - 1));
-		player.team = *itTeam;
+		player.team = TeamID(*itTeam);
 		teamNumbers[j].erase(itTeam);
-		map->players[pSettings.getColor()] = player;
+		map->players[pSettings.getColor().getNum()] = player;
 	}
 
 	map->howManyTeams = (mapGenOptions.getTeamsCnt() == 0 ? mapGenOptions.getPlayersCnt() : mapGenOptions.getTeamsCnt())
@@ -287,7 +287,7 @@ void CMapGenerator::addPlayerInfo()
 
 int CMapGenerator::countHumanPlayers() const
 {
-	return static_cast<int>(boost::count_if(players, [](const std::pair<TPlayerColor, CPlayerSettings> & pair)
+	return static_cast<int>(boost::count_if(players, [](const std::pair<PlayerColor, CPlayerSettings> & pair)
 	{
 		return pair.second.getPlayerType() == CMapGenerator::CPlayerSettings::HUMAN;
 	}));
@@ -308,7 +308,7 @@ void CMapGenerator::genTowns()
 
 	for(auto it = players.begin(); it != players.end(); ++it)
 	{
-		TPlayerColor owner = it->first;
+		PlayerColor owner = it->first;
 		int pos = std::distance(players.begin(), it);
 		int side = pos % 2;
 		CGTownInstance * town = new CGTownInstance();
@@ -321,7 +321,7 @@ void CMapGenerator::genTowns()
 		mapMgr->insertObject(town, townPos[side].x, townPos[side].y + (pos / 2) * 5, false);
 
 		// Update player info
-		PlayerInfo & pInfo = map->players[owner];
+		PlayerInfo & pInfo = map->players[owner.getNum()];
 		pInfo.allowedFactions.clear();
 		pInfo.allowedFactions.insert(townTypes[side]);
 		pInfo.hasMainTown = true;
@@ -342,9 +342,9 @@ void CMapGenerator::addHeaderInfo()
 	addPlayerInfo();
 }
 
-TPlayerColor CMapGenerator::getNextPlayerColor() const
+PlayerColor CMapGenerator::getNextPlayerColor() const
 {
-	for(TPlayerColor i = 0; i < GameConstants::PLAYER_LIMIT; ++i)
+	for(PlayerColor i = PlayerColor(0); i < PlayerColor::PLAYER_LIMIT; i.advance(1))
 	{
 		if(!players.count(i))
 		{
@@ -359,15 +359,15 @@ CMapGenerator::CPlayerSettings::CPlayerSettings() : color(0), startingTown(RANDO
 
 }
 
-int CMapGenerator::CPlayerSettings::getColor() const
+PlayerColor CMapGenerator::CPlayerSettings::getColor() const
 {
 	return color;
 }
 
 
-void CMapGenerator::CPlayerSettings::setColor(int value)
+void CMapGenerator::CPlayerSettings::setColor(PlayerColor value)
 {
-	if(value >= 0 && value < GameConstants::PLAYER_LIMIT)
+	if(value >= PlayerColor(0) && value < PlayerColor::PLAYER_LIMIT)
 	{
 		color = value;
 	}

+ 9 - 9
lib/RMG/CMapGenerator.h

@@ -46,16 +46,16 @@ public:
 		/**
 		 * Gets the color of the player. The default value is 0.
 		 *
-		 * @return the color of the player ranging from 0 to GameConstants::PLAYER_LIMIT - 1
+		 * @return the color of the player ranging from 0 to PlayerColor::PLAYER_LIMIT - 1
 		 */
-		int getColor() const;
+		PlayerColor getColor() const;
 
 		/**
 		 * Sets the color of the player.
 		 *
-		 * @param value the color of the player ranging from 0 to GameConstants::PLAYER_LIMIT - 1
+		 * @param value the color of the player ranging from 0 to PlayerColor::PLAYER_LIMIT - 1
 		 */
-		void setColor(int value);
+		void setColor(PlayerColor value);
 
 		/**
 		 * Gets the starting town of the player. The default value is RANDOM_TOWN.
@@ -90,7 +90,7 @@ public:
 
 	private:
 		/** The color of the player. */
-		int color;
+		PlayerColor color;
 
 		/** The starting town of the player. */
 		int startingTown;
@@ -106,7 +106,7 @@ public:
 	 * @param players the random gen player settings
 	 * @param randomSeed a random seed is required to get random numbers.
 	 */
-	CMapGenerator(const CMapGenOptions & mapGenOptions, const std::map<TPlayerColor, CPlayerSettings> & players, int randomSeed);
+	CMapGenerator(const CMapGenOptions & mapGenOptions, const std::map<PlayerColor, CPlayerSettings> & players, int randomSeed);
 
 	/**
 	 * Destructor.
@@ -147,7 +147,7 @@ private:
 	/**
 	 * Counts the amount of human players.
 	 *
-	 * @return the amount of human players ranging from 0 to GameConstants::PLAYER_LIMIT
+	 * @return the amount of human players ranging from 0 to PlayerColor::PLAYER_LIMIT
 	 */
 	int countHumanPlayers() const;
 
@@ -171,7 +171,7 @@ private:
 	 *
 	 * @return the next free player color
 	 */
-	TPlayerColor getNextPlayerColor() const;
+	PlayerColor getNextPlayerColor() const;
 
 	/** The map options which describes the size of the map and contain player info. */
 	CMapGenOptions mapGenOptions;
@@ -192,5 +192,5 @@ private:
 	std::unique_ptr<CMapEditManager> mapMgr;
 
 	/** The random gen player settings. */
-	std::map<TPlayerColor, CPlayerSettings> players;
+	std::map<PlayerColor, CPlayerSettings> players;
 };

+ 4 - 4
lib/StartInfo.h

@@ -35,10 +35,10 @@ struct PlayerSettings
 	     heroPortrait; //-1 if default, else ID
 
 	std::string heroName;
-	TPlayerColor color; //from 0 - 
+	PlayerColor color; //from 0 - 
 	enum EHandicap {NO_HANDICAP, MILD, SEVERE};
 	EHandicap handicap;//0-no, 1-mild, 2-severe
-	ui8 team;
+	TeamID team;
 
 	std::string name;
 	ui8 playerID; //0 - AI, non-0 serves as player id
@@ -74,7 +74,7 @@ struct StartInfo
 	EMode mode;
 	ui8 difficulty; //0=easy; 4=impossible
 
-	typedef bmap<TPlayerColor, PlayerSettings> TPlayerInfos;
+	typedef bmap<PlayerColor, PlayerSettings> TPlayerInfos;
 	TPlayerInfos playerInfos; //color indexed
 
 	ui32 seedToBeUsed; //0 if not sure (client requests server to decide, will be send in reply pack)
@@ -87,7 +87,7 @@ struct StartInfo
 
 	shared_ptr<CCampaignState> campState;
 
-	PlayerSettings & getIthPlayersSettings(TPlayerColor no)
+	PlayerSettings & getIthPlayersSettings(PlayerColor no)
 	{
 		if(playerInfos.find(no) != playerInfos.end())
 			return playerInfos[no];

+ 1 - 1
lib/StringConstants.h

@@ -31,7 +31,7 @@ namespace GameConstants
 	    "demoniac",  "heretic",    "deathknight", "necromancer", "warlock",      "overlord",
 	    "barbarian", "battlemage", "beastmaster", "witch",       "planeswalker", "elementalist"
 	};
-	const std::string PLAYER_COLOR_NAMES [PLAYER_LIMIT] = {
+	const std::string PLAYER_COLOR_NAMES [PlayerColor::PLAYER_LIMIT_I] = {
 		"red", "blue", "tan", "green", "orange", "purple", "teal", "pink"
 	};
 }

+ 109 - 108
server/CGameHandler.cpp

@@ -67,7 +67,7 @@ template <typename T> class CApplyOnGH;
 class CBaseForGHApply
 {
 public:
-	virtual bool applyOnGH(CGameHandler *gh, CConnection *c, void *pack, ui8 player) const =0;
+	virtual bool applyOnGH(CGameHandler *gh, CConnection *c, void *pack, PlayerColor player) const =0;
 	virtual ~CBaseForGHApply(){}
 	template<typename U> static CBaseForGHApply *getApplier(const U * t=NULL)
 	{
@@ -78,7 +78,7 @@ public:
 template <typename T> class CApplyOnGH : public CBaseForGHApply
 {
 public:
-	bool applyOnGH(CGameHandler *gh, CConnection *c, void *pack, ui8 player) const
+	bool applyOnGH(CGameHandler *gh, CConnection *c, void *pack, PlayerColor player) const
 	{
 		T *ptr = static_cast<T*>(pack);
 		ptr->c = c;
@@ -105,7 +105,7 @@ static void giveExp(BattleResult &r)
 	}
 }
 
-PlayerStatus PlayerStatuses::operator[](TPlayerColor player)
+PlayerStatus PlayerStatuses::operator[](PlayerColor player)
 {
 	boost::unique_lock<boost::mutex> l(mx);
 	if(players.find(player) != players.end())
@@ -117,13 +117,13 @@ PlayerStatus PlayerStatuses::operator[](TPlayerColor player)
 		throw std::runtime_error("No such player!");
 	}
 }
-void PlayerStatuses::addPlayer(TPlayerColor player)
+void PlayerStatuses::addPlayer(PlayerColor player)
 {
 	boost::unique_lock<boost::mutex> l(mx);
 	players[player];
 }
 
-int PlayerStatuses::getQueriesCount(TPlayerColor player)
+int PlayerStatuses::getQueriesCount(PlayerColor player)
 {
 	boost::unique_lock<boost::mutex> l(mx);
 	if(players.find(player) != players.end())
@@ -136,7 +136,7 @@ int PlayerStatuses::getQueriesCount(TPlayerColor player)
 	}
 }
 
-bool PlayerStatuses::checkFlag(TPlayerColor player, bool PlayerStatus::*flag)
+bool PlayerStatuses::checkFlag(PlayerColor player, bool PlayerStatus::*flag)
 {
 	boost::unique_lock<boost::mutex> l(mx);
 	if(players.find(player) != players.end())
@@ -148,7 +148,7 @@ bool PlayerStatuses::checkFlag(TPlayerColor player, bool PlayerStatus::*flag)
 		throw std::runtime_error("No such player!");
 	}
 }
-void PlayerStatuses::setFlag(TPlayerColor player, bool PlayerStatus::*flag, bool val)
+void PlayerStatuses::setFlag(PlayerColor player, bool PlayerStatus::*flag, bool val)
 {
 	boost::unique_lock<boost::mutex> l(mx);
 	if(players.find(player) != players.end())
@@ -161,7 +161,7 @@ void PlayerStatuses::setFlag(TPlayerColor player, bool PlayerStatus::*flag, bool
 	}
 	cv.notify_all();
 }
-void PlayerStatuses::addQuery(TPlayerColor player, ui32 id)
+void PlayerStatuses::addQuery(PlayerColor player, ui32 id)
 {
 	boost::unique_lock<boost::mutex> l(mx);
 	if(players.find(player) != players.end())
@@ -174,7 +174,7 @@ void PlayerStatuses::addQuery(TPlayerColor player, ui32 id)
 	}
 	cv.notify_all();
 }
-void PlayerStatuses::removeQuery(TPlayerColor player, ui32 id)
+void PlayerStatuses::removeQuery(PlayerColor player, ui32 id)
 {
 	boost::unique_lock<boost::mutex> l(mx);
 	if(players.find(player) != players.end())
@@ -273,7 +273,7 @@ void CGameHandler::levelUpHero(const CGHeroInstance * hero)
 		hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(basicAndAdv)); //upgrade existing
 	}
 
-	if (hero->tempOwner == GameConstants::NEUTRAL_PLAYER) //choose skill automatically
+	if (hero->tempOwner == PlayerColor::NEUTRAL) //choose skill automatically
 	{
 		sendAndApply (&hlu);
 		if (hlu.skills.size())
@@ -426,7 +426,7 @@ void CGameHandler::levelUpCommander(const CCommanderInstance * c)
 	}
 	int skillAmount = clu.skills.size();
 
-	if (hero->tempOwner == GameConstants::NEUTRAL_PLAYER) //choose skill automatically
+	if (hero->tempOwner == PlayerColor::NEUTRAL) //choose skill automatically
 	{
 		sendAndApply(&clu);
 		if (clu.skills.size())
@@ -526,9 +526,9 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 	if(!duel)
 	{
 		//unblock engaged players
-		if(bEndArmy1->tempOwner<GameConstants::PLAYER_LIMIT)
+		if(bEndArmy1->tempOwner<PlayerColor::PLAYER_LIMIT)
 			states.setFlag(bEndArmy1->tempOwner, &PlayerStatus::engagedIntoBattle, false);
-		if(bEndArmy2 && bEndArmy2->tempOwner<GameConstants::PLAYER_LIMIT)
+		if(bEndArmy2 && bEndArmy2->tempOwner<PlayerColor::PLAYER_LIMIT)
 			states.setFlag(bEndArmy2->tempOwner, &PlayerStatus::engagedIntoBattle, false);
 	}
 
@@ -539,12 +539,12 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 	if (hero2)
 		battleResult.data->exp[1] = hero2->calculateXp(battleResult.data->exp[1]);
 
-	ui8 sides[2];
+	PlayerColor sides[2];
 	for(int i=0; i<2; ++i)
 	{
 		sides[i] = gs->curB->sides[i];
 	}
-	ui8 loser = sides[!battleResult.data->winner];
+	PlayerColor loser = sides[!battleResult.data->winner];
 
 	CasualtiesAfterBattle cab1(bEndArmy1, gs->curB), cab2(bEndArmy2, gs->curB); //calculate casualties before deleting battle
 	ChangeSpells cs; //for Eagle Eye
@@ -741,7 +741,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 	}
 	visitObjectAfterVictory = false;
 
-	winLoseHandle(1<<sides[0] | 1<<sides[1]); //handle victory/loss of engaged players
+	winLoseHandle(1<<sides[0].getNum() | 1<<sides[1].getNum()); //handle victory/loss of engaged players
 
 	if(result == BattleResult::SURRENDER || result == BattleResult::ESCAPE) //loser has escaped or surrendered
 	{
@@ -885,7 +885,7 @@ void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, cons
 		bat.bsa.push_back(bsa);
 	}
 }
-void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
+void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &c)
 {
 	setThreadName("CGameHandler::handleConnection");
 	srand(time(NULL));
@@ -895,7 +895,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 		while(1)//server should never shut connection first //was: while(!end2)
 		{
 			CPack *pack = NULL;
-			ui8 player = 255;
+			PlayerColor player = PlayerColor::NEUTRAL;
 			si32 requestID = -999;
 			int packType = 0;
 
@@ -905,7 +905,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 				packType = typeList.getTypeID(pack); //get the id of type
 
 				tlog5 << boost::format("Received client message (request %d by player %d) of type with ID=%d (%s).\n")
-					% requestID % (int)player % packType % typeid(*pack).name();
+					% requestID % player.getNum() % packType % typeid(*pack).name();
 			}
 
 			//prepare struct informing that action was applied
@@ -918,7 +918,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 			CBaseForGHApply *apply = applier->apps[packType]; //and appropriae applier object
 			if(isBlockedByQueries(pack, packType, player))
 			{
-				complain(boost::str(boost::format("Player %d has to answer queries  before attempting any further actions (count=%d)!") % (int)player % states.getQueriesCount(player)));
+				complain(boost::str(boost::format("Player %d has to answer queries  before attempting any further actions (count=%d)!") % player.getNum() % states.getQueriesCount(player)));
 				{
 					boost::unique_lock<boost::mutex> lock(*c.wmx);
 					c << &applied;
@@ -1164,7 +1164,7 @@ void CGameHandler::newTurn()
 	bool newWeek = getDate(Date::DAY_OF_WEEK) == 7; //day numbers are confusing, as day was not yet switched
 	bool newMonth = getDate(Date::DAY_OF_MONTH) == 28;
 
-	std::map<ui8, si32> hadGold;//starting gold - for buildings like dwarven treasury
+	std::map<PlayerColor, si32> hadGold;//starting gold - for buildings like dwarven treasury
 	srand(time(NULL));
 
 	if (firstTurn)
@@ -1241,12 +1241,12 @@ void CGameHandler::newTurn()
 
 	for ( auto i=gs->players.begin() ; i!=gs->players.end();i++)
 	{
-		if(i->first == 255)
+		if(i->first == PlayerColor::NEUTRAL)
 			continue;
-		else if(i->first >= GameConstants::PLAYER_LIMIT)
+		else if(i->first >= PlayerColor::PLAYER_LIMIT)
 			assert(0); //illegal player number!
 
-		std::pair<TPlayerColor,si32> playerGold(i->first,i->second.resources[Res::GOLD]);
+		std::pair<PlayerColor, si32> playerGold(i->first, i->second.resources[Res::GOLD]);
 		hadGold.insert(playerGold);
 
 		if(newWeek) //new heroes in tavern
@@ -1305,7 +1305,7 @@ void CGameHandler::newTurn()
 
 	BOOST_FOREACH(CGTownInstance *t, gs->map->towns)
 	{
-		ui8 player = t->tempOwner;
+		PlayerColor player = t->tempOwner;
 		handleTownEvents(t, n, newCreas);
 		if(newWeek) //first day of week
 		{
@@ -1313,7 +1313,7 @@ void CGameHandler::newTurn()
 				setPortalDwelling(t, true, (n.specialWeek == NewTurn::PLAGUE ? true : false)); //set creatures for Portal of Summoning
 
 			if(!firstTurn)
-				if (t->hasBuilt(BuildingID::TREASURY, ETownType::RAMPART) && player < GameConstants::PLAYER_LIMIT)
+				if (t->hasBuilt(BuildingID::TREASURY, ETownType::RAMPART) && player < PlayerColor::PLAYER_LIMIT)
 						n.res[player][Res::GOLD] += hadGold[player]/10; //give 10% of starting gold
 
 			SetAvailableCreatures sac;
@@ -1356,7 +1356,7 @@ void CGameHandler::newTurn()
 
 			n.cres.push_back(sac);
 		}
-		if(!firstTurn  &&  player < GameConstants::PLAYER_LIMIT)//not the first day and town not neutral
+		if(!firstTurn  &&  player < PlayerColor::PLAYER_LIMIT)//not the first day and town not neutral
 		{
 			if(t->hasBuilt(BuildingID::RESOURCE_SILO)) //there is resource silo
 			{
@@ -1377,7 +1377,7 @@ void CGameHandler::newTurn()
 		{
 			// Skyship, probably easier to handle same as Veil of darkness
 			//do it every new day after veils apply
-			if (player != GameConstants::NEUTRAL_PLAYER) //do not reveal fow for neutral player
+			if (player != PlayerColor::NEUTRAL) //do not reveal fow for neutral player
 			{
 				FoWChange fw;
 				fw.mode = 1;
@@ -1480,27 +1480,27 @@ void CGameHandler::newTurn()
 	{
 		for (auto i=gs->players.cbegin() ; i!=gs->players.cend();i++)
 		{
-			if(i->second.status || i->second.towns.size() || i->second.color >= GameConstants::PLAYER_LIMIT)
+			if(i->second.status || i->second.towns.size() || i->second.color >= PlayerColor::PLAYER_LIMIT)
 				continue;
 
 			InfoWindow iw;
 			iw.player = i->first;
-			iw.components.push_back(Component(Component::FLAG,i->first,0,0));
+			iw.components.push_back(Component(Component::FLAG, i->first.getNum(), 0, 0));
 
 			if(!i->second.daysWithoutCastle)
 			{
 				iw.text.addTxt(MetaString::GENERAL_TXT,6); //%s, you have lost your last town.  If you do not conquer another town in the next week, you will be eliminated.
-				iw.text.addReplacement(MetaString::COLOR, i->first);
+				iw.text.addReplacement(MetaString::COLOR, i->first.getNum());
 			}
 			else if(i->second.daysWithoutCastle == 6)
 			{
 				iw.text.addTxt(MetaString::ARRAY_TXT,129); //%s, this is your last day to capture a town or you will be banished from this land.
-				iw.text.addReplacement(MetaString::COLOR, i->first);
+				iw.text.addReplacement(MetaString::COLOR, i->first.getNum());
 			}
 			else
 			{
 				iw.text.addTxt(MetaString::ARRAY_TXT,128); //%s, you only have %d days left to capture a town or you will be banished from this land.
-				iw.text.addReplacement(MetaString::COLOR, i->first);
+				iw.text.addReplacement(MetaString::COLOR, i->first.getNum());
 				iw.text.addReplacement(7 - i->second.daysWithoutCastle);
 			}
 			sendAndApply(&iw);
@@ -1519,13 +1519,13 @@ void CGameHandler::run(bool resume)
 			(*cc) << gs->initialOpts; // gs->scenarioOps
 		}
 
-		std::set<TPlayerColor> players;
+		std::set<PlayerColor> players;
 		(*cc) >> players; //how many players will be handled at that client
 
 		tlog0 << "Connection " << cc->connectionID << " will handle " << players.size() << " player: ";
-		BOOST_FOREACH(TPlayerColor color, players)
+		BOOST_FOREACH(PlayerColor color, players)
 		{
-			tlog0 << static_cast<int>(color) << " ";
+			tlog0 << color << " ";
 			{
 				boost::unique_lock<boost::recursive_mutex> lock(gsm);
 				connections[color] = cc;
@@ -1540,8 +1540,8 @@ void CGameHandler::run(bool resume)
 
 	for(std::set<CConnection*>::iterator i = conns.begin(); i!=conns.end();i++)
 	{
-		std::set<int> pom;
-		for(std::map<int,CConnection*>::iterator j = connections.begin(); j!=connections.end();j++)
+		std::set<PlayerColor> pom;
+		for(auto j = connections.cbegin(); j!=connections.cend();j++)
 			if(j->second == *i)
 				pom.insert(j->first);
 
@@ -1559,7 +1559,7 @@ void CGameHandler::run(bool resume)
 		if(!resume)
 			newTurn();
 
-		std::map<TPlayerColor,PlayerState>::iterator i;
+		std::map<PlayerColor,PlayerState>::iterator i;
 		if(!resume)
 			i = gs->players.begin();
 		else
@@ -1569,7 +1569,7 @@ void CGameHandler::run(bool resume)
 		for(; i != gs->players.end(); i++)
 		{
 			if((i->second.towns.size()==0 && i->second.heroes.size()==0)
-				|| i->first>=GameConstants::PLAYER_LIMIT
+				|| i->first>=PlayerColor::PLAYER_LIMIT
 				|| i->second.status)
 			{
 				continue;
@@ -1683,18 +1683,18 @@ void CGameHandler::setAmount(ObjectInstanceID objid, ui32 val)
 	sendAndApply(&sop);
 }
 
-bool CGameHandler::moveHero( ObjectInstanceID hid, int3 dst, ui8 instant, TPlayerColor asker /*= 255*/ )
+bool CGameHandler::moveHero( ObjectInstanceID hid, int3 dst, ui8 instant, PlayerColor asker /*= 255*/ )
 {
 	const CGHeroInstance *h = getHero(hid);
 
-	if(!h  || (asker != GameConstants::NEUTRAL_PLAYER && (instant  ||   h->getOwner() != gs->currentPlayer)) //not turn of that hero or player can't simply teleport hero (at least not with this function)
+	if(!h  || (asker != PlayerColor::NEUTRAL && (instant  ||   h->getOwner() != gs->currentPlayer)) //not turn of that hero or player can't simply teleport hero (at least not with this function)
 	  )
 	{
 		tlog1 << "Illegal call to move hero!\n";
 		return false;
 	}
 
-	tlog5 << "Player " <<int(asker) << " wants to move hero "<< hid.getNum() << " from "<< h->pos << " to " << dst << std::endl;
+	tlog5 << "Player " << asker << " wants to move hero "<< hid.getNum() << " from "<< h->pos << " to " << dst << std::endl;
 	int3 hmpos = dst + int3(-1,0,0);
 
 	if(!gs->map->isInTheMap(hmpos))
@@ -1763,7 +1763,7 @@ bool CGameHandler::moveHero( ObjectInstanceID hid, int3 dst, ui8 instant, TPlaye
 	{
 		BOOST_FOREACH(CGObjectInstance *obj, t.visitableObjects)
 		{
-			if(obj != h  &&  obj->blockVisit  &&  !(obj->getPassableness() & 1<<h->tempOwner))
+			if(obj != h  &&  obj->blockVisit  &&  !(obj->getPassableness() & 1<<h->tempOwner.getNum()))
 			{
 
 				applyWithResult(TryMoveHero::BLOCKING_VISIT);
@@ -1844,7 +1844,7 @@ bool CGameHandler::moveHero( ObjectInstanceID hid, int3 dst, ui8 instant, TPlaye
 	}
 }
 
-bool CGameHandler::teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui8 source, TPlayerColor asker/* = 255*/)
+bool CGameHandler::teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui8 source, PlayerColor asker/* = 255*/)
 {
 	const CGHeroInstance *h = getHero(hid);
 	const CGTownInstance *t = getTown(dstid);
@@ -1866,14 +1866,14 @@ bool CGameHandler::teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui
 	return true;
 }
 
-void CGameHandler::setOwner(const CGObjectInstance * obj, TPlayerColor owner)
+void CGameHandler::setOwner(const CGObjectInstance * obj, PlayerColor owner)
 {
-	ui8 oldOwner = getOwner(obj->id);
-	SetObjectProperty sop(obj->id,1,owner);
+	PlayerColor oldOwner = getOwner(obj->id);
+	SetObjectProperty sop(obj->id, 1, owner.getNum());
 	sendAndApply(&sop);
 
-	winLoseHandle(1<<owner | 1<<oldOwner);
-	if(owner < GameConstants::PLAYER_LIMIT && dynamic_cast<const CGTownInstance *>(obj)) //town captured
+	winLoseHandle(1<<owner.getNum() | 1<<oldOwner.getNum());
+	if(owner < PlayerColor::PLAYER_LIMIT && dynamic_cast<const CGTownInstance *>(obj)) //town captured
 	{
 		const CGTownInstance * town = dynamic_cast<const CGTownInstance *>(obj);
 		if (town->hasBuilt(BuildingID::PORTAL_OF_SUMMON, ETownType::DUNGEON))
@@ -1927,7 +1927,7 @@ ui32 CGameHandler::showBlockingDialog( BlockingDialog *iw )
 	return 0;
 }
 
-void CGameHandler::giveResource(TPlayerColor player, Res::ERes which, int val) //TODO: cap according to Bersy's suggestion
+void CGameHandler::giveResource(PlayerColor player, Res::ERes which, int val) //TODO: cap according to Bersy's suggestion
 {
 	if(!val) return; //don't waste time on empty call
 	SetResource sr;
@@ -2035,7 +2035,7 @@ void CGameHandler::startBattleI(const CArmedInstance *army1, const CArmedInstanc
 	engageIntoBattle(army1->tempOwner);
 	engageIntoBattle(army2->tempOwner);
 	//block engaged players
-	if(army2->tempOwner < GameConstants::PLAYER_LIMIT)
+	if(army2->tempOwner < PlayerColor::PLAYER_LIMIT)
 		states.setFlag(army2->tempOwner,&PlayerStatus::engagedIntoBattle,true);
 
 	static const CArmedInstance *armies[2];
@@ -2096,7 +2096,7 @@ void CGameHandler::setManaPoints( ObjectInstanceID hid, int val )
 	sendAndApply(&sm);
 }
 
-void CGameHandler::giveHero( ObjectInstanceID id, TPlayerColor player )
+void CGameHandler::giveHero( ObjectInstanceID id, PlayerColor player )
 {
 	GiveHero gh;
 	gh.id = id;
@@ -2204,8 +2204,8 @@ void CGameHandler::useScholarSkill(ObjectInstanceID fromHero, ObjectInstanceID t
 
 void CGameHandler::heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2)
 {
-	TPlayerColor player1 = getHero(hero1)->tempOwner;
-	TPlayerColor player2 = getHero(hero2)->tempOwner;
+	PlayerColor player1 = getHero(hero1)->tempOwner;
+	PlayerColor player2 = getHero(hero2)->tempOwner;
 
 	if( gameState()->getPlayerRelations( player1, player2))
 	{
@@ -2218,24 +2218,24 @@ void CGameHandler::heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2)
 	}
 }
 
-void CGameHandler::prepareNewQuery(Query * queryPack, TPlayerColor player, const boost::function<void(ui32)> &callback)
+void CGameHandler::prepareNewQuery(Query * queryPack, PlayerColor player, const boost::function<void(ui32)> &callback)
 {
 	boost::unique_lock<boost::recursive_mutex> lock(gsm);
-	tlog4 << "Creating a query for player " << (int)player << " with ID=" << QID << std::endl;
+	tlog4 << "Creating a query for player " << player << " with ID=" << QID << std::endl;
 	callbacks[QID] = callback;
 	states.addQuery(player, QID);
 	queryPack->queryID = QID;
 	QID++;
 }
 
-void CGameHandler::applyAndAsk( Query * sel, TPlayerColor player, boost::function<void(ui32)> &callback )
+void CGameHandler::applyAndAsk( Query * sel, PlayerColor player, boost::function<void(ui32)> &callback )
 {
 	boost::unique_lock<boost::recursive_mutex> lock(gsm);
 	prepareNewQuery(sel, player, callback);
 	sendAndApply(sel);
 }
 
-void CGameHandler::ask( Query * sel, TPlayerColor player, const CFunctionList<void(ui32)> &callback )
+void CGameHandler::ask( Query * sel, PlayerColor player, const CFunctionList<void(ui32)> &callback )
 {
 	boost::unique_lock<boost::recursive_mutex> lock(gsm);
 	prepareNewQuery(sel, player, callback);
@@ -2352,7 +2352,7 @@ void CGameHandler::close()
 	//exit(0);
 }
 
-bool CGameHandler::arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, SlotID p1, SlotID p2, si32 val, TPlayerColor player )
+bool CGameHandler::arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, SlotID p1, SlotID p2, si32 val, PlayerColor player )
 {
 	const CArmedInstance *s1 = static_cast<CArmedInstance*>(gs->getObjInstance(id1)),
 		*s2 = static_cast<CArmedInstance*>(gs->getObjInstance(id2));
@@ -2372,8 +2372,8 @@ bool CGameHandler::arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui
 
 	if(what==1) //swap
 	{
-		if ( ((s1->tempOwner != player && s1->tempOwner != GameConstants::UNFLAGGABLE_PLAYER) && s1->getStackCount(p1)) //why 254??
-		  || ((s2->tempOwner != player && s2->tempOwner != GameConstants::UNFLAGGABLE_PLAYER) && s2->getStackCount(p2)))
+		if ( ((s1->tempOwner != player && s1->tempOwner != PlayerColor::UNFLAGGABLE) && s1->getStackCount(p1)) //why 254??
+		  || ((s2->tempOwner != player && s2->tempOwner != PlayerColor::UNFLAGGABLE) && s2->getStackCount(p2)))
 		{
 			complain("Can't take troops from another player!");
 			return false;
@@ -2384,7 +2384,7 @@ bool CGameHandler::arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui
 	else if(what==2)//merge
 	{
 		if (( s1->getCreature(p1) != s2->getCreature(p2) && complain("Cannot merge different creatures stacks!"))
-		|| (((s1->tempOwner != player && s1->tempOwner != GameConstants::UNFLAGGABLE_PLAYER) && s2->getStackCount(p2)) && complain("Can't take troops from another player!")))
+		|| (((s1->tempOwner != player && s1->tempOwner != PlayerColor::UNFLAGGABLE) && s2->getStackCount(p2)) && complain("Can't take troops from another player!")))
 			return false;
 
 		moveStack(sl1, sl2);
@@ -2436,26 +2436,26 @@ bool CGameHandler::arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui
 	return true;
 }
 
-TPlayerColor CGameHandler::getPlayerAt( CConnection *c ) const
+PlayerColor CGameHandler::getPlayerAt( CConnection *c ) const
 {
-	std::set<int> all;
-	for(std::map<int,CConnection*>::const_iterator i=connections.begin(); i!=connections.end(); i++)
+	std::set<PlayerColor> all;
+	for(auto i=connections.cbegin(); i!=connections.cend(); i++)
 		if(i->second == c)
 			all.insert(i->first);
 
 	switch(all.size())
 	{
 	case 0:
-		return 255;
+		return PlayerColor::NEUTRAL;
 	case 1:
 		return *all.begin();
 	default:
 		{
 			//if we have more than one player at this connection, try to pick active one
-			if(vstd::contains(all,int(gs->currentPlayer)))
+			if(vstd::contains(all, gs->currentPlayer))
 				return gs->currentPlayer;
 			else
-				return 253; //cannot say which player is it
+				return PlayerColor::CANNOT_DETERMINE; //cannot say which player is it
 		}
 	}
 }
@@ -2713,7 +2713,7 @@ bool CGameHandler::upgradeCreature( ObjectInstanceID objid, SlotID pos, Creature
 	CArmedInstance *obj = static_cast<CArmedInstance*>(gs->getObjInstance(objid));
 	assert(obj->hasStackAtSlot(pos));
 	UpgradeInfo ui = gs->getUpgradeInfo(obj->getStack(pos));
-	int player = obj->tempOwner;
+	PlayerColor player = obj->tempOwner;
 	const PlayerState *p = getPlayer(player);
 	int crQuantity = obj->stacks[pos]->count;
 	int newIDpos= vstd::find_pos(ui.newID, upgID);//get position of new id in UpgradeInfo
@@ -2842,7 +2842,7 @@ bool CGameHandler::garrisonSwap( ObjectInstanceID tid )
 bool CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2)
 {
 	ArtifactLocation src = al1, dst = al2;
-	const int srcPlayer = src.owningPlayer(), dstPlayer = dst.owningPlayer();
+	const PlayerColor srcPlayer = src.owningPlayer(), dstPlayer = dst.owningPlayer();
 	const CArmedInstance *srcObj = src.relatedObj(), *dstObj = dst.relatedObj();
 
 	// Make sure exchange is even possible between the two heroes.
@@ -3080,7 +3080,7 @@ bool CGameHandler::buySecSkill( const IMarket *m, const CGHeroInstance *h, Secon
 	return true;
 }
 
-bool CGameHandler::tradeResources(const IMarket *market, ui32 val, TPlayerColor player, ui32 id1, ui32 id2)
+bool CGameHandler::tradeResources(const IMarket *market, ui32 val, PlayerColor player, ui32 id1, ui32 id2)
 {
 	int r1 = gs->getPlayer(player)->resources[id1],
 		r2 = gs->getPlayer(player)->resources[id2];
@@ -3170,7 +3170,7 @@ bool CGameHandler::transformInUndead(const IMarket *market, const CGHeroInstance
 	return true;
 }
 
-bool CGameHandler::sendResources(ui32 val, TPlayerColor player, Res::ERes r1, TPlayerColor r2)
+bool CGameHandler::sendResources(ui32 val, PlayerColor player, Res::ERes r1, PlayerColor r2)
 {
 	const PlayerState *p2 = gs->getPlayer(r2, false);
 	if(!p2  ||  p2->status != EPlayerStatus::INGAME)
@@ -3201,13 +3201,14 @@ bool CGameHandler::setFormation( ObjectInstanceID hid, ui8 formation )
 	return true;
 }
 
-bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, TPlayerColor player)
+bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, PlayerColor player)
 {
 	const PlayerState *p = gs->getPlayer(player);
 	const CGTownInstance *t = gs->getTown(obj->id);
+	static const int GOLD_NEEDED = 2500;
 
 	//common preconditions
-	if( (p->resources[Res::GOLD]<2500  && complain("Not enough gold for buying hero!"))
+	if( (p->resources[Res::GOLD]<GOLD_NEEDED  && complain("Not enough gold for buying hero!"))
 		|| (getHeroCount(player, false) >= GameConstants::MAX_HEROES_PER_PLAYER && complain("Cannot hire hero, only 8 wandering heroes are allowed!")))
 		return false;
 
@@ -3264,7 +3265,7 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, TPlayerColor p
 	SetResource sr;
 	sr.player = player;
 	sr.resid = Res::GOLD;
-	sr.val = p->resources[Res::GOLD] - 2500;
+	sr.val = p->resources[Res::GOLD] - GOLD_NEEDED;
 	sendAndApply(&sr);
 
 	if(t)
@@ -3275,7 +3276,7 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, TPlayerColor p
 	return true;
 }
 
-bool CGameHandler::queryReply(ui32 qid, ui32 answer, TPlayerColor player)
+bool CGameHandler::queryReply(ui32 qid, ui32 answer, PlayerColor player)
 {
 	boost::unique_lock<boost::recursive_mutex> lock(gsm);
 	states.removeQuery(player, qid);
@@ -3396,7 +3397,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 		}
 	case Battle::SURRENDER:
 		{
-			int player = gs->curB->sides[ba.side];
+			PlayerColor player = gs->curB->sides[ba.side];
 			int cost = gs->curB->battleGetSurrenderCost(player);
 			if(cost < 0)
 				complain("Cannot surrender!");
@@ -3780,10 +3781,10 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 	return ok;
 }
 
-void CGameHandler::playerMessage( TPlayerColor player, const std::string &message )
+void CGameHandler::playerMessage( PlayerColor player, const std::string &message )
 {
 	bool cheated=true;
-	PlayerMessage temp_message(player,message);
+	PlayerMessage temp_message(player, message);
 
 	sendAndApply(&temp_message);
 	if(message == "vcmiistari") //give all spells and 999 mana
@@ -3924,7 +3925,7 @@ void CGameHandler::playerMessage( TPlayerColor player, const std::string &messag
 	}
 }
 
-void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex destination, ui8 casterSide, TPlayerColor casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero,
+void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex destination, ui8 casterSide, PlayerColor casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero,
 	int usedSpellPower, ECastingMode::ECastingMode mode, const CStack * stack, si32 selectedStack)
 {
 	const CSpell *spell = SpellID(spellID).toSpell();
@@ -4415,7 +4416,7 @@ void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex
 				std::vector<CStack *> & battleStacks = gs->curB->stacks;
 				for (size_t j = 0; j < battleStacks.size(); ++j)
 				{
-					if(battleStacks[j]->owner == casterSide) //get enemy stacks which can be affected by this spell
+					if(battleStacks[j]->owner == gs->curB->sides[casterSide]) //get enemy stacks which can be affected by this spell
 					{
 						if (!gs->curB->battleIsImmune(NULL, spell, ECastingMode::MAGIC_MIRROR, battleStacks[j]->position))
 							mirrorTargets.push_back(battleStacks[j]);
@@ -4705,9 +4706,9 @@ void CGameHandler::handleTimeEvents()
 	while(gs->map->events.size() && gs->map->events.front().firstOccurence+1 == gs->day)
 	{
 		CMapEvent ev = gs->map->events.front();
-		for(int player = 0; player < GameConstants::PLAYER_LIMIT; player++)
+		for(int player = 0; player < PlayerColor::PLAYER_LIMIT_I; player++)
 		{
-			PlayerState *pinfo = gs->getPlayer(player);
+			PlayerState *pinfo = gs->getPlayer(PlayerColor(player));
 
 			if( pinfo  //player exists
 				&& (ev.players & 1<<player) //event is enabled to this player
@@ -4718,12 +4719,12 @@ void CGameHandler::handleTimeEvents()
 			{
 				//give resources
 				SetResources sr;
-				sr.player = player;
+				sr.player = PlayerColor(player);
 				sr.res = pinfo->resources + ev.resources;
 
 				//prepare dialog
 				InfoWindow iw;
-				iw.player = player;
+				iw.player = PlayerColor(player);
 				iw.text << ev.message;
 
 				for (int i=0; i<ev.resources.size(); i++)
@@ -4769,12 +4770,12 @@ void CGameHandler::handleTownEvents(CGTownInstance * town, NewTurn &n, std::map<
 	town->events.sort(evntCmp);
 	while(town->events.size() && town->events.front().firstOccurence == gs->day)
 	{
-		ui8 player = town->tempOwner;
+		PlayerColor player = town->tempOwner;
 		CCastleEvent ev = town->events.front();
 		PlayerState *pinfo = gs->getPlayer(player);
 
 		if( pinfo  //player exists
-			&& (ev.players & 1<<player) //event is enabled to this player
+			&& (ev.players & 1<<player.getNum()) //event is enabled to this player
 			&& ((ev.computerAffected && !pinfo->human)
 				|| (ev.humanAffected && pinfo->human) ) )
 		{
@@ -4848,7 +4849,7 @@ bool CGameHandler::complain( const std::string &problem )
 	return true;
 }
 
-ui32 CGameHandler::getQueryResult( TPlayerColor player, int queryID )
+ui32 CGameHandler::getQueryResult( PlayerColor player, int queryID )
 {
 	//TODO: write
 	return 0;
@@ -4856,7 +4857,7 @@ ui32 CGameHandler::getQueryResult( TPlayerColor player, int queryID )
 
 void CGameHandler::showGarrisonDialog( ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits, const boost::function<void()> &cb )
 {
-	ui8 player = getOwner(hid);
+	PlayerColor player = getOwner(hid);
 	GarrisonDialog gd;
 	gd.hid = hid;
 	gd.objid = upobj;
@@ -4881,11 +4882,11 @@ void CGameHandler::showGarrisonDialog( ObjectInstanceID upobj, ObjectInstanceID
 	}
 }
 
-void CGameHandler::showThievesGuildWindow(TPlayerColor player, ObjectInstanceID requestingObjId)
+void CGameHandler::showThievesGuildWindow(PlayerColor player, ObjectInstanceID requestingObjId)
 {
 	OpenWindow ow;
 	ow.window = OpenWindow::THIEVES_GUILD;
-	ow.id1 = player;
+	ow.id1 = player.getNum();
 	ow.id2 = requestingObjId.getNum();
 	sendAndApply(&ow);
 }
@@ -4974,7 +4975,7 @@ bool CGameHandler::buildBoat( ObjectInstanceID objid )
 		return false;
 	}
 
-	const TPlayerColor playerID = obj->o->tempOwner;
+	const PlayerColor playerID = obj->o->tempOwner;
 	TResources boatCost;
 	obj->getBoatCost(boatCost);
 	TResources aviable = gs->getPlayer(playerID)->resources;
@@ -5008,7 +5009,7 @@ bool CGameHandler::buildBoat( ObjectInstanceID objid )
 	return true;
 }
 
-void CGameHandler::engageIntoBattle( ui8 player )
+void CGameHandler::engageIntoBattle( PlayerColor player )
 {
 	if(vstd::contains(states.players, player))
 		states.setFlag(player,&PlayerStatus::engagedIntoBattle,true);
@@ -5023,16 +5024,16 @@ void CGameHandler::engageIntoBattle( ui8 player )
 void CGameHandler::winLoseHandle(ui8 players )
 {
 
-	for(size_t i = 0; i < GameConstants::PLAYER_LIMIT; i++)
+	for(size_t i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++)
 	{
-		if(players & 1<<i  &&  gs->getPlayer(i))
+		if(players & 1<<i  &&  gs->getPlayer(PlayerColor(i)))
 		{
-			checkLossVictory(i);
+			checkLossVictory(PlayerColor(i));
 		}
 	}
 }
 
-void CGameHandler::checkLossVictory( TPlayerColor player )
+void CGameHandler::checkLossVictory( PlayerColor player )
 {
 	const PlayerState *p = gs->getPlayer(player);
 	if(p->status) //player already won / lost
@@ -5060,7 +5061,7 @@ void CGameHandler::checkLossVictory( TPlayerColor player )
 
 		for (auto i = gs->players.cbegin(); i!=gs->players.cend(); i++)
 		{
-			if(i->first < GameConstants::PLAYER_LIMIT && i->first != player)//FIXME: skip already eliminated players?
+			if(i->first < PlayerColor::PLAYER_LIMIT && i->first != player)//FIXME: skip already eliminated players?
 			{
 				iw.player = i->first;
 				sendAndApply(&iw);
@@ -5080,11 +5081,11 @@ void CGameHandler::checkLossVictory( TPlayerColor player )
 		for (auto i = gs->map->objects.cbegin(); i != gs->map->objects.cend(); i++) //unflag objs
 		{
 			if(*i  &&  (*i)->tempOwner == player)
-				setOwner(*i,GameConstants::NEUTRAL_PLAYER);
+				setOwner(*i,PlayerColor::NEUTRAL);
 		}
 
 		//eliminating one player may cause victory of another:
-		winLoseHandle(GameConstants::ALL_PLAYERS & ~(1<<player));
+		winLoseHandle(GameConstants::ALL_PLAYERS & ~(1<<player.getNum()));
 	}
 
 	if(vic && p->human)
@@ -5121,7 +5122,7 @@ void CGameHandler::checkLossVictory( TPlayerColor player )
 	}
 }
 
-void CGameHandler::getLossVicMessage( TPlayerColor player, si8 standard, bool victory, InfoWindow &out ) const
+void CGameHandler::getLossVicMessage( PlayerColor player, si8 standard, bool victory, InfoWindow &out ) const
 {
 //	const PlayerState *p = gs->getPlayer(player);
 // 	if(!p->human)
@@ -5220,8 +5221,8 @@ void CGameHandler::getLossVicMessage( TPlayerColor player, si8 standard, bool vi
 		else if(standard == 2)
 		{
 			out.text.addTxt(MetaString::GENERAL_TXT, 7);//%s, your heroes abandon you, and you are banished from this land.
-			out.text.addReplacement(MetaString::COLOR, player);
-			out.components.push_back(Component(Component::FLAG,player,0,0));
+			out.text.addReplacement(MetaString::COLOR, player.getNum());
+			out.components.push_back(Component(Component::FLAG, player.getNum(), 0, 0));
 		}
 		else //lost all towns and heroes
 		{
@@ -6181,7 +6182,7 @@ void CGameHandler::spawnWanderingMonsters(CreatureID creatureID)
 	}
 }
 
-bool CGameHandler::isBlockedByQueries(const CPack *pack, int packType, TPlayerColor player)
+bool CGameHandler::isBlockedByQueries(const CPack *pack, int packType, PlayerColor player)
 {
 	//it's always legal to send query reply (we'll check later if it makes sense)
 	if(packType == typeList.getTypeID<QueryReply>())
@@ -6218,9 +6219,9 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleI
 {
 	heroWithDeadCommander = ObjectInstanceID();
 
-	int color = army->tempOwner;
-	if(color == GameConstants::UNFLAGGABLE_PLAYER)
-		color = GameConstants::NEUTRAL_PLAYER;
+	PlayerColor color = army->tempOwner;
+	if(color == PlayerColor::UNFLAGGABLE)
+		color = PlayerColor::NEUTRAL;
 
 	BOOST_FOREACH(CStack *st, bat->stacks)
 	{

+ 32 - 32
server/CGameHandler.h

@@ -53,17 +53,17 @@ struct PlayerStatus
 class PlayerStatuses
 {
 public:
-	std::map<TPlayerColor,PlayerStatus> players;
+	std::map<PlayerColor,PlayerStatus> players;
 	boost::mutex mx;
 	boost::condition_variable cv; //notifies when any changes are made
 
-	void addPlayer(TPlayerColor player);
-	PlayerStatus operator[](TPlayerColor player);
-	int getQueriesCount(TPlayerColor player); //returns 0 if there is no such player
-	bool checkFlag(TPlayerColor player, bool PlayerStatus::*flag);
-	void setFlag(TPlayerColor player, bool PlayerStatus::*flag, bool val);
-	void addQuery(TPlayerColor player, ui32 id);
-	void removeQuery(TPlayerColor player, ui32 id);
+	void addPlayer(PlayerColor player);
+	PlayerStatus operator[](PlayerColor player);
+	int getQueriesCount(PlayerColor player); //returns 0 if there is no such player
+	bool checkFlag(PlayerColor player, bool PlayerStatus::*flag);
+	void setFlag(PlayerColor player, bool PlayerStatus::*flag, bool val);
+	void addQuery(PlayerColor player, ui32 id);
+	void removeQuery(PlayerColor player, ui32 id);
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & players;
@@ -88,7 +88,7 @@ private:
 	bool isAllowedExchangeForQuery(ObjectInstanceID id1, ObjectInstanceID id2);
 public:
 	CVCMIServer *s;
-	std::map<int,CConnection*> connections; //player color -> connection to client with interface of that player
+	std::map<PlayerColor, CConnection*> connections; //player color -> connection to client with interface of that player
 	PlayerStatuses states; //player color -> player state
 	std::set<CConnection*> conns;
 
@@ -100,16 +100,16 @@ public:
 	std::map<ui32, CFunctionList<void(ui32)> > callbacks; //query id => callback function - for selection and yes/no dialogs
 	std::map<ui32, std::pair<ObjectInstanceID, ObjectInstanceID> > allowedExchanges;
 
-	bool isBlockedByQueries(const CPack *pack, int packType, TPlayerColor player); 
+	bool isBlockedByQueries(const CPack *pack, int packType, PlayerColor player); 
 	bool isAllowedExchange(ObjectInstanceID id1, ObjectInstanceID id2);
 	bool isAllowedArrangePack(const ArrangeStacks *pack);
 	void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
 	int moveStack(int stack, BattleHex dest); //returned value - travelled distance
 	void startBattle(const CArmedInstance *armies[2], int3 tile, const CGHeroInstance *heroes[2], bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero
 	void runBattle();
-	void checkLossVictory(TPlayerColor player);
+	void checkLossVictory(PlayerColor player);
 	void winLoseHandle(ui8 players=255); //players: bit field - colours of players to be checked; default: all
-	void getLossVicMessage(TPlayerColor player, si8 standard, bool victory, InfoWindow &out) const;
+	void getLossVicMessage(PlayerColor player, si8 standard, bool victory, InfoWindow &out) const;
 
 	////used only in endBattle - don't touch elsewhere
 	boost::function<void(BattleResult*)> * battleEndCallback;
@@ -132,7 +132,7 @@ public:
 	void changeSpells(const CGHeroInstance * hero, bool give, const std::set<SpellID> &spells) OVERRIDE;
 	bool removeObject(const CGObjectInstance * obj) OVERRIDE;
 	void setBlockVis(ObjectInstanceID objid, bool bv) OVERRIDE;
-	void setOwner(const CGObjectInstance * obj, TPlayerColor owner) OVERRIDE;
+	void setOwner(const CGObjectInstance * obj, PlayerColor owner) OVERRIDE;
 	void setHoverName(const CGObjectInstance * objid, MetaString * name) OVERRIDE;
 	void changePrimSkill(const CGHeroInstance * hero, PrimarySkill::PrimarySkill which, si64 val, bool abs=false) OVERRIDE;
 	void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false) OVERRIDE; 
@@ -140,8 +140,8 @@ public:
 	void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback) OVERRIDE;
 	ui32 showBlockingDialog(BlockingDialog *iw) OVERRIDE; //synchronous version of above
 	void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits, const boost::function<void()> &cb) OVERRIDE;
-	void showThievesGuildWindow(TPlayerColor player, ObjectInstanceID requestingObjId) OVERRIDE;
-	void giveResource(TPlayerColor player, Res::ERes which, int val) OVERRIDE;
+	void showThievesGuildWindow(PlayerColor player, ObjectInstanceID requestingObjId) OVERRIDE;
+	void giveResource(PlayerColor player, Res::ERes which, int val) OVERRIDE;
 
 	void giveCreatures(const CArmedInstance *objid, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove) OVERRIDE;
 	void takeCreatures(ObjectInstanceID objid, const std::vector<CStackBasicDescriptor> &creatures) OVERRIDE;
@@ -169,11 +169,11 @@ public:
 	void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false) OVERRIDE; //if any of armies is hero, hero will be used
 	void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false) OVERRIDE; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle//void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb) OVERRIDE; //for hero<=>neutral army
 	void setAmount(ObjectInstanceID objid, ui32 val) OVERRIDE;
-	bool moveHero(ObjectInstanceID hid, int3 dst, ui8 instant, TPlayerColor asker = GameConstants::NEUTRAL_PLAYER) OVERRIDE;
+	bool moveHero(ObjectInstanceID hid, int3 dst, ui8 instant, PlayerColor asker = PlayerColor::NEUTRAL) OVERRIDE;
 	void giveHeroBonus(GiveBonus * bonus) OVERRIDE;
 	void setMovePoints(SetMovePoints * smp) OVERRIDE;
 	void setManaPoints(ObjectInstanceID hid, int val) OVERRIDE;
-	void giveHero(ObjectInstanceID id, TPlayerColor player) OVERRIDE;
+	void giveHero(ObjectInstanceID id, PlayerColor player) OVERRIDE;
 	void changeObjPos(ObjectInstanceID objid, int3 newPos, ui8 flags) OVERRIDE;
 	void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2) OVERRIDE;
 	//////////////////////////////////////////////////////////////////////////
@@ -181,7 +181,7 @@ public:
 	void setPortalDwelling(const CGTownInstance * town, bool forced, bool clear);
 	bool tryAttackingGuard(const int3 &guardPos, const CGHeroInstance * h);
 	void visitObjectOnTile(const TerrainTile &t, const CGHeroInstance * h);
-	bool teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui8 source, TPlayerColor asker = GameConstants::NEUTRAL_PLAYER);
+	bool teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui8 source, PlayerColor asker = PlayerColor::NEUTRAL);
 	void vistiCastleObjects (const CGTownInstance *t, const CGHeroInstance *h);
 	void levelUpHero(const CGHeroInstance * hero, SecondarySkill skill);//handle client respond and send one more request if needed
 	void levelUpHero(const CGHeroInstance * hero);//initial call - check if hero have remaining levelups & handle them
@@ -193,25 +193,25 @@ public:
 	void commitPackage(CPackForClient *pack) OVERRIDE;
 
 	void init(StartInfo *si);
-	void handleConnection(std::set<int> players, CConnection &c);
-	TPlayerColor getPlayerAt(CConnection *c) const;
+	void handleConnection(std::set<PlayerColor> players, CConnection &c);
+	PlayerColor getPlayerAt(CConnection *c) const;
 
-	void playerMessage( TPlayerColor player, const std::string &message);
+	void playerMessage( PlayerColor player, const std::string &message);
 	bool makeBattleAction(BattleAction &ba);
 	bool makeAutomaticAction(const CStack *stack, BattleAction &ba); //used when action is taken by stack without volition of player (eg. unguided catapult attack)
-	void handleSpellCasting(SpellID spellID, int spellLvl, BattleHex destination, ui8 casterSide, TPlayerColor casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero,
+	void handleSpellCasting(SpellID spellID, int spellLvl, BattleHex destination, ui8 casterSide, PlayerColor casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero,
 		int usedSpellPower, ECastingMode::ECastingMode mode, const CStack * stack, si32 selectedStack = -1);
 	bool makeCustomAction(BattleAction &ba);
 	void stackTurnTrigger(const CStack * stack);
 	void handleDamageFromObstacle(const CObstacleInstance &obstacle, const CStack * curStack); //checks if obstacle is land mine and handles possible consequences
 	void removeObstacle(const CObstacleInstance &obstacle);
-	bool queryReply( ui32 qid, ui32 answer, TPlayerColor player );
-	bool hireHero( const CGObjectInstance *obj, ui8 hid, TPlayerColor player );
+	bool queryReply( ui32 qid, ui32 answer, PlayerColor player );
+	bool hireHero( const CGObjectInstance *obj, ui8 hid, PlayerColor player );
 	bool buildBoat( ObjectInstanceID objid );
 	bool setFormation( ObjectInstanceID hid, ui8 formation );
-	bool tradeResources(const IMarket *market, ui32 val, TPlayerColor player, ui32 id1, ui32 id2);
+	bool tradeResources(const IMarket *market, ui32 val, PlayerColor player, ui32 id1, ui32 id2);
 	bool sacrificeCreatures(const IMarket *market, const CGHeroInstance *hero, SlotID slot, ui32 count);
-	bool sendResources(ui32 val, TPlayerColor player, Res::ERes r1, TPlayerColor r2);
+	bool sendResources(ui32 val, PlayerColor player, Res::ERes r1, PlayerColor r2);
 	bool sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, SlotID slot, Res::ERes resourceID);
 	bool transformInUndead(const IMarket *market, const CGHeroInstance * hero, SlotID slot);
 	bool assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo);
@@ -226,14 +226,14 @@ public:
 	bool buildStructure(ObjectInstanceID tid, BuildingID bid, bool force=false);//force - for events: no cost, no checkings
 	bool razeStructure(ObjectInstanceID tid, BuildingID bid);
 	bool disbandCreature( ObjectInstanceID id, SlotID pos );
-	bool arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, SlotID p1, SlotID p2, si32 val, TPlayerColor player);
+	bool arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, SlotID p1, SlotID p2, si32 val, PlayerColor player);
 	void save(const std::string &fname);
 	void close();
 	void handleTimeEvents();
 	void handleTownEvents(CGTownInstance *town, NewTurn &n, std::map<ObjectInstanceID, std::map<si32, si32> > &newCreas);
 	bool complain(const std::string &problem); //sends message to all clients, prints on the logs and return true
 	void objectVisited( const CGObjectInstance * obj, const CGHeroInstance * h );
-	void engageIntoBattle( TPlayerColor player );
+	void engageIntoBattle( PlayerColor player );
 	bool dig(const CGHeroInstance *h);
 	bool castSpell(const CGHeroInstance *h, SpellID spellID, const int3 &pos);
 	void moveArmy(const CArmedInstance *src, const CArmedInstance *dst, bool allowMerging);
@@ -243,12 +243,12 @@ public:
 		h & QID & states;
 	}
 
-	ui32 getQueryResult(TPlayerColor player, int queryID);
+	ui32 getQueryResult(PlayerColor player, int queryID);
 	void sendMessageToAll(const std::string &message);
 	void sendMessageTo(CConnection &c, const std::string &message);
-	void applyAndAsk(Query * sel, TPlayerColor player, boost::function<void(ui32)> &callback);
-	void prepareNewQuery(Query * queryPack, TPlayerColor player, const boost::function<void(ui32)> &callback = 0); //generates unique query id and writes it to the pack; blocks the player till query is answered (then callback is called)
-	void ask(Query * sel, TPlayerColor player, const CFunctionList<void(ui32)> &callback);
+	void applyAndAsk(Query * sel, PlayerColor player, boost::function<void(ui32)> &callback);
+	void prepareNewQuery(Query * queryPack, PlayerColor player, const boost::function<void(ui32)> &callback = 0); //generates unique query id and writes it to the pack; blocks the player till query is answered (then callback is called)
+	void ask(Query * sel, PlayerColor player, const CFunctionList<void(ui32)> &callback);
 	void sendToAllClients(CPackForClient * info);
 	void sendAndApply(CPackForClient * info);
 	void applyAndSend(CPackForClient * info);

+ 6 - 6
server/NetPacksServer.cpp

@@ -21,7 +21,7 @@
 		return false;} while(0)
 
 #define WRONG_PLAYER_MSG(expectedplayer) do {std::ostringstream oss;\
-			oss << "You were identified as player " << (int)gh->getPlayerAt(c) << " while expecting " << (int)expectedplayer;\
+			oss << "You were identified as player " << gh->getPlayerAt(c) << " while expecting " << expectedplayer;\
 			tlog1 << oss.str() << std::endl; \
 			if(c) { SystemMessage temp_message(oss.str()); boost::unique_lock<boost::mutex> lock(*c->wmx); *c << &temp_message; } } while(0)
 
@@ -67,7 +67,7 @@ bool CloseServer::applyGh( CGameHandler *gh )
 
 bool EndTurn::applyGh( CGameHandler *gh )
 {
-	int player = GS(gh)->currentPlayer;
+	PlayerColor player = GS(gh)->currentPlayer;
 	ERROR_IF_NOT(player);
 	if(gh->states.checkFlag(player, &PlayerStatus::engagedIntoBattle))
 		COMPLAIN_AND_RETURN("Cannot end turn when in battle!");
@@ -158,12 +158,12 @@ bool TradeOnMarketplace::applyGh( CGameHandler *gh )
 	if(!m)
 		COMPLAIN_AND_RETURN("market is not-a-market! :/");
 
-	ui8 player = market->tempOwner;
+	PlayerColor player = market->tempOwner;
 
-	if(player >= GameConstants::PLAYER_LIMIT)
+	if(player >= PlayerColor::PLAYER_LIMIT)
 		player = gh->getTile(market->visitablePos())->visitableObjects.back()->tempOwner;
 
-	if(player >= GameConstants::PLAYER_LIMIT)
+	if(player >= PlayerColor::PLAYER_LIMIT)
 		COMPLAIN_AND_RETURN("No player can use this market!");
 
 	if(hero && (player != hero->tempOwner || hero->visitablePos() != market->visitablePos()))
@@ -176,7 +176,7 @@ bool TradeOnMarketplace::applyGh( CGameHandler *gh )
 	case EMarketMode::RESOURCE_RESOURCE:
 		return gh->tradeResources(m, val, player, r1, r2);
 	case EMarketMode::RESOURCE_PLAYER:
-		return gh->sendResources(val, player, static_cast<Res::ERes>(r1), static_cast<TPlayerColor>(r2));
+		return gh->sendResources(val, player, static_cast<Res::ERes>(r1), PlayerColor(r2));
 	case EMarketMode::CREATURE_RESOURCE:
 		if(!hero)
 			COMPLAIN_AND_RETURN("Only hero can sell creatures!");