Bläddra i källkod

* creature ID refactoring
* double week creatures are configurable now

mateuszb 13 år sedan
förälder
incheckning
f1c78e3260
52 ändrade filer med 420 tillägg och 345 borttagningar
  1. 1 1
      AI/BattleAI/BattleAI.cpp
  2. 1 1
      AI/StupidAI/StupidAI.cpp
  3. 2 2
      AI/VCAI/VCAI.cpp
  4. 3 3
      CCallback.cpp
  5. 6 6
      CCallback.h
  6. 1 1
      Scripting/ERM/ERMInterpreter.cpp
  7. 7 7
      client/CCastleInterface.cpp
  8. 2 2
      client/CCastleInterface.h
  9. 2 2
      client/CCreatureWindow.cpp
  10. 2 2
      client/CCreatureWindow.h
  11. 5 5
      client/GUIClasses.cpp
  12. 3 3
      client/GUIClasses.h
  13. 1 0
      config/creatures/castle.json
  14. 2 0
      config/creatures/dungeon.json
  15. 2 0
      config/creatures/fortress.json
  16. 1 0
      config/creatures/inferno.json
  17. 1 0
      config/creatures/necropolis.json
  18. 2 0
      config/creatures/rampart.json
  19. 2 0
      config/creatures/stronghold.json
  20. 1 0
      config/creatures/tower.json
  21. 12 12
      lib/BattleState.cpp
  22. 1 1
      lib/BattleState.h
  23. 40 34
      lib/CArtHandler.cpp
  24. 15 32
      lib/CArtHandler.h
  25. 4 4
      lib/CBattleCallback.cpp
  26. 11 10
      lib/CCreatureHandler.cpp
  27. 5 5
      lib/CCreatureHandler.h
  28. 12 12
      lib/CCreatureSet.cpp
  29. 12 12
      lib/CCreatureSet.h
  30. 1 1
      lib/CDefObjInfoHandler.cpp
  31. 2 1
      lib/CDefObjInfoHandler.h
  32. 35 35
      lib/CGameState.cpp
  33. 7 7
      lib/CGameState.h
  34. 2 2
      lib/CHeroHandler.cpp
  35. 1 1
      lib/CHeroHandler.h
  36. 45 44
      lib/CObjectHandler.cpp
  37. 8 7
      lib/CObjectHandler.h
  38. 4 4
      lib/CTownHandler.cpp
  39. 5 4
      lib/CTownHandler.h
  40. 34 21
      lib/Connection.h
  41. 55 2
      lib/GameConstants.h
  42. 1 1
      lib/HeroBonus.cpp
  43. 1 1
      lib/HeroBonus.h
  44. 2 2
      lib/IGameCallback.cpp
  45. 1 1
      lib/IGameCallback.h
  46. 1 1
      lib/JsonNode.cpp
  47. 9 9
      lib/Mapping/MapFormatH3M.cpp
  48. 15 12
      lib/NetPacks.h
  49. 3 3
      lib/NetPacksLib.cpp
  50. 20 20
      server/CGameHandler.cpp
  51. 7 7
      server/CGameHandler.h
  52. 2 2
      server/NetPacksServer.cpp

+ 1 - 1
AI/BattleAI/BattleAI.cpp

@@ -350,7 +350,7 @@ BattleAction CBattleAI::activeStack( const CStack * stack )
 	try
 	{
 		print("activeStack called for " + stack->nodeName());
-		if(stack->type->idNumber == 145) //catapult
+		if(stack->type->idNumber == CreatureID::CATAPULT)
 			return useCatapult(stack);
 
 		if(cb->battleCanCastSpell())

+ 1 - 1
AI/StupidAI/StupidAI.cpp

@@ -101,7 +101,7 @@ BattleAction CStupidAI::activeStack( const CStack * stack )
 	auto dists = cb->battleGetDistances(stack);
 	std::vector<EnemyInfo> enemiesShootable, enemiesReachable, enemiesUnreachable;
 
-	if(stack->type->idNumber == 145) //catapult
+	if(stack->type->idNumber == CreatureID::CATAPULT)
 	{
 		BattleAction attack;
 		static const int wallHexes[] = {50, 183, 182, 130, 62, 29, 12, 95};

+ 2 - 2
AI/VCAI/VCAI.cpp

@@ -1127,7 +1127,7 @@ void VCAI::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h)
 				townVisitsThisWeek[h].push_back(h->visitedTown);
 				if (!h->hasSpellbook() && cb->getResourceAmount(Res::GOLD) >= GameConstants::SPELLBOOK_GOLD_COST + saving[Res::GOLD] &&
 					h->visitedTown->hasBuilt (EBuilding::MAGES_GUILD_1))
-					cb->buyArtifact(h.get(), 0); //buy spellbook
+					cb->buyArtifact(h.get(), ArtifactID::SPELLBOOK);
 			}
 			break;
 	}
@@ -1243,7 +1243,7 @@ void VCAI::recruitCreatures(const CGDwelling * d)
 			continue;
 
 		int count = d->creatures[i].first;
-		int creID = d->creatures[i].second.back();
+		CreatureID::CreatureID creID = d->creatures[i].second.back();
 //		const CCreature *c = VLC->creh->creatures[creID];
 // 		if(containsSavedRes(c->cost))
 // 			continue;

+ 3 - 3
CCallback.cpp

@@ -69,7 +69,7 @@ int CCallback::selectionMade(int selection, int queryID)
 	return sendRequest(&pack);
 }
 
-void CCallback::recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount, si32 level/*=-1*/)
+void CCallback::recruitCreatures(const CGObjectInstance *obj, CreatureID::CreatureID ID, ui32 amount, si32 level/*=-1*/)
 {
 	if(player!=obj->tempOwner  &&  obj->ID != Obj::WAR_MACHINE_FACTORY)
 		return;
@@ -88,7 +88,7 @@ bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos)
 	return true;
 }
 
-bool CCallback::upgradeCreature(const CArmedInstance *obj, int stackPos, int newID)
+bool CCallback::upgradeCreature(const CArmedInstance *obj, int stackPos, CreatureID::CreatureID newID)
 {
 	UpgradeCreature pack(stackPos,obj->id,newID);
 	sendRequest(&pack);
@@ -205,7 +205,7 @@ void CCallback::swapGarrisonHero( const CGTownInstance *town )
 	sendRequest(&pack);
 }
 
-void CCallback::buyArtifact(const CGHeroInstance *hero, int aid)
+void CCallback::buyArtifact(const CGHeroInstance *hero, ArtifactID::ArtifactID aid)
 {
 	if(hero->tempOwner != player) return;
 

+ 6 - 6
CCallback.h

@@ -50,8 +50,8 @@ public:
 	//town
 	virtual void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero)=0;
 	virtual bool buildBuilding(const CGTownInstance *town, si32 buildingID)=0;
-	virtual void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount, si32 level=-1)=0;
-	virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1)=0; //if newID==-1 then best possible upgrade will be made
+	virtual void recruitCreatures(const CGObjectInstance *obj, CreatureID::CreatureID ID, ui32 amount, si32 level=-1)=0;
+	virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, CreatureID::CreatureID newID=CreatureID::NONE)=0; //if newID==-1 then best possible upgrade will be made
 	virtual void swapGarrisonHero(const CGTownInstance *town)=0;
 
 	virtual void trade(const CGObjectInstance *market, EMarketMode::EMarketMode mode, int id1, int id2, int val1, const CGHeroInstance *hero = NULL)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce
@@ -66,7 +66,7 @@ public:
 	virtual bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition::ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo)=0;
 	virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0;
 	virtual void endTurn()=0;
-	virtual void buyArtifact(const CGHeroInstance *hero, int aid)=0; //used to buy artifacts in towns (including spell book in the guild and war machines in blacksmith)
+	virtual void buyArtifact(const CGHeroInstance *hero, ArtifactID::ArtifactID aid)=0; //used to buy artifacts in towns (including spell book in the guild and war machines in blacksmith)
 	virtual void setFormation(const CGHeroInstance * hero, bool tight)=0;
 	virtual void setSelection(const CArmedInstance * obj)=0;
 
@@ -128,12 +128,12 @@ public:
 	//bool moveArtifact(const CStackInstance * stack, ui16 src , const CGHeroInstance * hero, ui16 dest); // TODO: unify classes
 	bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition::ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo);
 	bool buildBuilding(const CGTownInstance *town, si32 buildingID);
-	void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount, si32 level=-1);
+	void recruitCreatures(const CGObjectInstance *obj, CreatureID::CreatureID ID, ui32 amount, si32 level=-1);
 	bool dismissCreature(const CArmedInstance *obj, int stackPos);
-	bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1);
+	bool upgradeCreature(const CArmedInstance *obj, int stackPos, CreatureID::CreatureID newID=CreatureID::NONE) OVERRIDE;
 	void endTurn();
 	void swapGarrisonHero(const CGTownInstance *town);
-	void buyArtifact(const CGHeroInstance *hero, int aid);
+	void buyArtifact(const CGHeroInstance *hero, ArtifactID::ArtifactID aid) OVERRIDE;
 	void trade(const CGObjectInstance *market, EMarketMode::EMarketMode mode, int id1, int id2, int val1, const CGHeroInstance *hero = NULL);
 	void setFormation(const CGHeroInstance * hero, bool tight);
 	void setSelection(const CArmedInstance * obj);

+ 1 - 1
Scripting/ERM/ERMInterpreter.cpp

@@ -2398,7 +2398,7 @@ void ERMInterpreter::heroVisit(const CGHeroInstance *visitor, const CGObjectInst
 	tip[3] = {visitedObj->pos.x, visitedObj->pos.y, visitedObj->pos.z};
 #else
 	tip[1] = list_of(visitedObj->ID);
-	tip[2] = list_of(visitedObj->ID)(visitedObj->subID);
+	tip[2] = list_of((int)visitedObj->ID)(visitedObj->subID);
 	tip[3] = list_of(visitedObj->pos.x)(visitedObj->pos.y)(visitedObj->pos.z);
 #endif
 	executeTriggerType(VERMInterpreter::TriggerType("OB"), start, tip);

+ 7 - 7
client/CCastleInterface.cpp

@@ -694,7 +694,7 @@ void CCastleBuildings::buildingClicked(int building)
 						break;
 
 				case ETownType::STRONGHOLD: //Ballista Yard
-						enterBlacksmith(4);
+						enterBlacksmith(ArtifactID::BALLISTA);
 						break;
 
 				default:
@@ -710,7 +710,7 @@ void CCastleBuildings::buildingClicked(int building)
 	}
 }
 
-void CCastleBuildings::enterBlacksmith(int ArtifactID)
+void CCastleBuildings::enterBlacksmith(ArtifactID::ArtifactID artifactID)
 {
 	const CGHeroInstance *hero = town->visitingHero;
 	if(!hero)
@@ -718,9 +718,9 @@ void CCastleBuildings::enterBlacksmith(int ArtifactID)
 		LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % town->town->buildings.find(16)->second->Name()));
 		return;
 	}
-	int price = CGI->arth->artifacts[ArtifactID]->price;
-	bool possible = LOCPLINT->cb->getResourceAmount(Res::GOLD) >= price && !hero->hasArt(ArtifactID);
-	GH.pushInt(new CBlacksmithDialog(possible,CArtHandler::convertMachineID(ArtifactID,false),ArtifactID,hero->id));
+	int price = CGI->arth->artifacts[artifactID]->price;
+	bool possible = LOCPLINT->cb->getResourceAmount(Res::GOLD) >= price && !hero->hasArt(artifactID);
+	GH.pushInt(new CBlacksmithDialog(possible, CArtHandler::machineIDToCreature(artifactID), artifactID, hero->id));
 }
 
 void CCastleBuildings::enterBuilding(int building)
@@ -795,7 +795,7 @@ void CCastleBuildings::enterMagesGuild()
 		{
 			CFunctionList<void()> onYes = boost::bind(&CCastleBuildings::openMagesGuild,this);
 			CFunctionList<void()> onNo = onYes;
-			onYes += boost::bind(&CCallback::buyArtifact,LOCPLINT->cb, hero,0);
+			onYes += boost::bind(&CCallback::buyArtifact,LOCPLINT->cb, hero,ArtifactID::SPELLBOOK);
 			std::vector<CComponent*> components(1, new CComponent(CComponent::artifact,0,0));
 
 			LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[214], onYes, onNo, true, components);
@@ -1653,7 +1653,7 @@ void CMageGuildScreen::Scroll::hover(bool on)
 
 }
 
-CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid):
+CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, ArtifactID::ArtifactID aid, int hid):
     CWindowObject(PLAYER_COLORED, "TPSMITH")
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;

+ 2 - 2
client/CCastleInterface.h

@@ -123,7 +123,7 @@ class CCastleBuildings : public CIntObject
 
 	const CGHeroInstance* getHero();//Select hero for buildings usage
 
-	void enterBlacksmith(int ArtifactID);//support for blacksmith + ballista yard
+	void enterBlacksmith(ArtifactID::ArtifactID artifactID);//support for blacksmith + ballista yard
 	void enterBuilding(int building);//for buildings with simple description + pic left-click messages
 	void enterCastleGate();
 	void enterFountain(int building);//Rampart's fountains
@@ -369,5 +369,5 @@ class CBlacksmithDialog : public CWindowObject
 	CGStatusBar *statusBar;
 
 public:
-	CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid);
+	CBlacksmithDialog(bool possible, int creMachineID, ArtifactID::ArtifactID aid, int hid);
 };

+ 2 - 2
client/CCreatureWindow.cpp

@@ -66,7 +66,7 @@ CCreatureWindow::CCreatureWindow (const CStackInstance &stack, CreWinType Type):
 	init(&stack, &stack, dynamic_cast<const CGHeroInstance*>(stack.armyObj));
 }
 
-CCreatureWindow::CCreatureWindow(int Cid, CreWinType Type, int creatureCount):
+CCreatureWindow::CCreatureWindow(CreatureID::CreatureID Cid, CreWinType Type, int creatureCount):
    CWindowObject(PLAYER_COLORED | (Type == OTHER ? RCLICK_POPUP : 0 ) ),
     type(Type)
 {
@@ -903,7 +903,7 @@ CIntObject * createCreWindow(
 	}
 }
 
-CIntObject * createCreWindow(int Cid, CCreatureWindow::CreWinType Type, int creatureCount)
+CIntObject * createCreWindow(CreatureID::CreatureID Cid, CCreatureWindow::CreWinType Type, int creatureCount)
 {
 	if(settings["general"]["classicCreatureWindow"].Bool())
 		return new CCreInfoWindow(Cid, Type, creatureCount);

+ 2 - 2
client/CCreatureWindow.h

@@ -91,7 +91,7 @@ public:
 	CCreatureWindow(const CStackInstance &st, CreWinType Type, boost::function<void()> Upg, boost::function<void()> Dsm, UpgradeInfo *ui); //full garrison window
 	CCreatureWindow(const CCommanderInstance * commander, const CStack * stack = NULL); //commander window
 	CCreatureWindow(std::vector<ui32> &skills, const CCommanderInstance * commander, boost::function<void(ui32)> callback); 
-	CCreatureWindow(int Cid, CreWinType Type, int creatureCount); //c-tor
+	CCreatureWindow(CreatureID::CreatureID Cid, CreWinType Type, int creatureCount); //c-tor
 
 	void init(const CStackInstance *stack, const CBonusSystemNode *stackNode, const CGHeroInstance *heroOwner);
 	void showAll(SDL_Surface * to);
@@ -159,5 +159,5 @@ public:
 };
 
 CIntObject *createCreWindow(const CStack *s, bool lclick = false);
-CIntObject *createCreWindow(int Cid, CCreatureWindow::CreWinType Type, int creatureCount);
+CIntObject *createCreWindow(CreatureID::CreatureID Cid, CCreatureWindow::CreWinType Type, int creatureCount);
 CIntObject *createCreWindow(const CStackInstance *s, CCreatureWindow::CreWinType type, boost::function<void()> Upg = 0, boost::function<void()> Dsm = 0, UpgradeInfo *ui = NULL);

+ 5 - 5
client/GUIClasses.cpp

@@ -1467,10 +1467,10 @@ void CRecruitmentWindow::select(CCreatureCard *card)
 
 void CRecruitmentWindow::buy()
 {
-	int crid =  selected->creature->idNumber,
-		dstslot = dst-> getSlotFor(crid);
+	CreatureID::CreatureID crid =  selected->creature->idNumber;
+	TSlot dstslot = dst-> getSlotFor(crid);
 
-	if(dstslot < 0 && !vstd::contains(CGI->arth->bigArtifacts,CGI->arth->convertMachineID(crid, true))) //no available slot
+	if(dstslot < 0 && !vstd::contains(CGI->arth->bigArtifacts,CGI->arth->creatureToMachineID(crid))) //no available slot
 	{
 		std::string txt;
 		if(dst->ID == Obj::HERO)
@@ -1510,7 +1510,7 @@ void CRecruitmentWindow::showAll(SDL_Surface * to)
 	drawBorder(to, pos.x + 289, pos.y + 312, 66, 34, int3(173,142,66));
 }
 
-CRecruitmentWindow::CRecruitmentWindow(const CGDwelling *Dwelling, int Level, const CArmedInstance *Dst, const boost::function<void(int,int)> &Recruit, int y_offset):
+CRecruitmentWindow::CRecruitmentWindow(const CGDwelling *Dwelling, int Level, const CArmedInstance *Dst, const boost::function<void(CreatureID::CreatureID,int)> &Recruit, int y_offset):
     CWindowObject(PLAYER_COLORED, "TPRCRT"),
 	onRecruit(Recruit),
     level(Level),
@@ -4365,7 +4365,7 @@ bool CArtPlace::fitsHere(const CArtifactInstance * art) const
 
 	// Anything can but War Machines can be placed in backpack.
 	if (slotID >= GameConstants::BACKPACK_START)
-		return !CGI->arth->isBigArtifact(art->id);
+		return !CGI->arth->isBigArtifact(art->artType->id);
 
 	return art->canBePutAt(ArtifactLocation(ourOwner->curHero, slotID), true);
 }

+ 3 - 3
client/GUIClasses.h

@@ -430,7 +430,7 @@ class CRecruitmentWindow : public CWindowObject
 		void createItems(TResources res);
 	};
 
-	boost::function<void(int,int)> onRecruit; //void (int ID, int amount) <-- call to recruit creatures
+	boost::function<void(CreatureID::CreatureID,int)> onRecruit; //void (int ID, int amount) <-- call to recruit creatures
 
 	int level;
 	const CArmedInstance *dst;
@@ -454,11 +454,11 @@ class CRecruitmentWindow : public CWindowObject
 	void showAll(SDL_Surface *to);
 public:
 	const CGDwelling * const dwelling;
-	CRecruitmentWindow(const CGDwelling *Dwelling, int Level, const CArmedInstance *Dst, const boost::function<void(int,int)> & Recruit, int y_offset = 0); //creatures - pairs<creature_ID,amount> //c-tor
+	CRecruitmentWindow(const CGDwelling *Dwelling, int Level, const CArmedInstance *Dst, const boost::function<void(CreatureID::CreatureID,int)> & Recruit, int y_offset = 0); //creatures - pairs<creature_ID,amount> //c-tor
 	void availableCreaturesChanged();
 };
 
-/// Split window where creatures can be splitted up into two single unit stacks
+/// Split window where creatures can be split up into two single unit stacks
 class CSplitWindow : public CWindowObject
 {
 	boost::function<void(int, int)> callback;

+ 1 - 0
config/creatures/castle.json

@@ -95,6 +95,7 @@
 		"faction": "castle",
 		"abilities": [ [ "ADDITIONAL_RETALIATION", 1, 0, 0 ] ], 	//griffins retaliate twice
 		"upgrades": ["royalGriffin"],
+		"hasDoubleWeek": true,
 		"graphics" :
 		{
 			"animation": "CGRIFF.DEF"

+ 2 - 0
config/creatures/dungeon.json

@@ -6,6 +6,7 @@
 		"faction": "dungeon",
 		"abilities": [ [ "SPELL_IMMUNITY", 0, 62, 0 ] ],	  	   	//troglodytes are immune to blind
 		"upgrades": ["infernalTroglodyte"],
+		"hasDoubleWeek": true,
 		"graphics" :
 		{
 			"animation": "CTROGL.DEF"
@@ -45,6 +46,7 @@
 		"faction": "dungeon",
 		"abilities": [ [ "RETURN_AFTER_STRIKE", 0, 0, 0 ] ],	   	//Harpies return after attack
 		"upgrades": ["harpyHag"],
+		"hasDoubleWeek": true,
 		"graphics" :
 		{
 			"animation": "CHARPY.DEF"

+ 2 - 0
config/creatures/fortress.json

@@ -43,6 +43,7 @@
 		"extraNames": [ "primitiveLizardman", ],
 		"faction": "fortress",
 		"upgrades": ["lizardWarrior"],
+		"hasDoubleWeek": true,
 		"graphics" :
 		{
 			"animation": "CPLIZA.DEF",
@@ -132,6 +133,7 @@
 		"faction": "fortress",
 		"abilities": [ [ "SPELL_AFTER_ATTACK", 100, 78, 0 ] ],  	//serpent fly
 		"upgrades": ["fireDragonFly"],
+		"hasDoubleWeek": true,
 		"graphics" :
 		{
 			"animation": "CDRFLY.DEF"

+ 1 - 0
config/creatures/inferno.json

@@ -43,6 +43,7 @@
 		"level": 2,
 		"faction": "inferno",
 		"upgrades": ["magog"],
+		"hasDoubleWeek": true,
 		"graphics" :
 		{
 			"animation": "CGOG.DEF",

+ 1 - 0
config/creatures/necropolis.json

@@ -81,6 +81,7 @@
 		"faction": "necropolis",
 		"abilities": [ [ "FULL_HP_REGENERATION", 0, 1, 0 ] ],			//wight
 		"upgrades": ["wraith"],
+		"hasDoubleWeek": true,
 		"graphics" :
 		{
 			"animation": "CWIGHT.DEF"

+ 2 - 0
config/creatures/rampart.json

@@ -5,6 +5,7 @@
 		"level": 1,
 		"faction": "rampart",
 		"upgrades": ["centaurCaptain"],
+		"hasDoubleWeek": true,
 		"graphics" :
 		{
 			"animation": "CCENTR.DEF"
@@ -132,6 +133,7 @@
 		"faction": "rampart",
 		"abilities": [ [ "CHANGES_SPELL_COST_FOR_ENEMY", 2, 0, 0 ] ],	//pegasus makes spell cost higher for enemy mage
 		"upgrades": ["silverPegasus"],
+		"hasDoubleWeek": true,
 		"graphics" :
 		{
 			"animation": "CPEGAS.DEF"

+ 2 - 0
config/creatures/stronghold.json

@@ -24,6 +24,7 @@
 		"id": 85,
 		"level": 1,
 		"faction": "stronghold",
+		"hasDoubleWeek": true,
 		"graphics" :
 		{
 			"animation": "CHGOBL.DEF"
@@ -43,6 +44,7 @@
 		"level": 2,
 		"faction": "stronghold",
 		"upgrades": ["hobgoblinWolfRider"],
+		"hasDoubleWeek": true,
 		"graphics" :
 		{
 			"animation": "CBWLFR.DEF"

+ 1 - 0
config/creatures/tower.json

@@ -6,6 +6,7 @@
 		"extraNames": [ "apprenticeGremlin" ],
 		"faction": "tower",
 		"upgrades": ["masterGremlin"],
+		"hasDoubleWeek": true,
 		"graphics" :
 		{
 			"animation": "CGREMA.DEF"

+ 12 - 12
lib/BattleState.cpp

@@ -36,7 +36,7 @@ const CStack * BattleInfo::getNextStack() const
 		return NULL;
 }
 
-int BattleInfo::getAvaliableHex(TCreature creID, bool attackerOwned, int initialPos) const
+int BattleInfo::getAvaliableHex(CreatureID::CreatureID creID, bool attackerOwned, int initialPos) const
 {
 	bool twoHex = VLC->creh->creatures[creID]->isDoubleWide();
 	//bool flying = VLC->creh->creatures[creID]->isFlying();
@@ -512,22 +512,22 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType::ETerrainType terr
 	if(!creatureBank)
 	{
 		//Checks if hero has artifact and create appropriate stack
-		auto handleWarMachine= [&](int side, ArtifactPosition::ArtifactPosition artslot, int cretype, int hex)
+		auto handleWarMachine= [&](int side, ArtifactPosition::ArtifactPosition artslot, CreatureID::CreatureID cretype, BattleHex hex)
 		{
 			if(heroes[side] && heroes[side]->getArt(artslot))
 				stacks.push_back(curB->generateNewStack(CStackBasicDescriptor(cretype, 1), !side, 255, hex));
 		};
 
-		handleWarMachine(0, ArtifactPosition::MACH1, 146, 52); //ballista
-		handleWarMachine(0, ArtifactPosition::MACH2, 148, 18); //ammo cart
-		handleWarMachine(0, ArtifactPosition::MACH3, 147, 154);//first aid tent
+		handleWarMachine(0, ArtifactPosition::MACH1, CreatureID::BALLISTA, 52);
+		handleWarMachine(0, ArtifactPosition::MACH2, CreatureID::AMMO_CART, 18);
+		handleWarMachine(0, ArtifactPosition::MACH3, CreatureID::FIRST_AID_TENT, 154);
 		if(town && town->hasFort())
-			handleWarMachine(0, ArtifactPosition::MACH4, 145, 120);//catapult
+			handleWarMachine(0, ArtifactPosition::MACH4, CreatureID::CATAPULT, 120);
 
 		if(!town) //defending hero shouldn't receive ballista (bug #551)
-			handleWarMachine(1, ArtifactPosition::MACH1, 146, 66); //ballista
-		handleWarMachine(1, ArtifactPosition::MACH2, 148, 32); //ammo cart
-		handleWarMachine(1, ArtifactPosition::MACH3, 147, 168); //first aid tent
+			handleWarMachine(1, ArtifactPosition::MACH1, CreatureID::BALLISTA, 66);
+		handleWarMachine(1, ArtifactPosition::MACH2, CreatureID::AMMO_CART, 32);
+		handleWarMachine(1, ArtifactPosition::MACH3, CreatureID::FIRST_AID_TENT, 168);
 	}
 	//war machines added
 
@@ -572,15 +572,15 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType::ETerrainType terr
 	if (curB->siege == CGTownInstance::CITADEL || curB->siege == CGTownInstance::CASTLE)
 	{
 		// keep tower
-		CStack * stack = curB->generateNewStack(CStackBasicDescriptor(149, 1), false, 255, -2);
+		CStack * stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, 255, -2);
 		stacks.push_back(stack);
 
 		if (curB->siege == CGTownInstance::CASTLE)
 		{
 			// lower tower + upper tower
-			CStack * stack = curB->generateNewStack(CStackBasicDescriptor(149, 1), false, 255, -4);
+			CStack * stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, 255, -4);
 			stacks.push_back(stack);
-			stack = curB->generateNewStack(CStackBasicDescriptor(149, 1), false, 255, -3);
+			stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, 255, -3);
 			stacks.push_back(stack);
 		}
 

+ 1 - 1
lib/BattleState.h

@@ -90,7 +90,7 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
 
 	//void getAccessibilityMap(bool *accessibility, bool twoHex, bool attackerOwned, bool addOccupiable, std::set<BattleHex> & occupyable, bool flying, const CStack* stackToOmmit = NULL) const; //send pointer to at least 187 allocated bytes
 	//static bool isAccessible(BattleHex hex, bool * accessibility, bool twoHex, bool attackerOwned, bool flying, bool lastPos); //helper for makeBFS
-	int getAvaliableHex(TCreature creID, bool attackerOwned, int initialPos = -1) const; //find place for summon / clone effects
+	int getAvaliableHex(CreatureID::CreatureID creID, bool attackerOwned, int initialPos = -1) const; //find place for summon / clone effects
 	//void makeBFS(BattleHex start, bool*accessibility, BattleHex *predecessor, int *dists, bool twoHex, bool attackerOwned, bool flying, bool fillPredecessors) const; //*accessibility must be prepared bool[187] array; last two pointers must point to the at least 187-elements int arrays - there is written result
 	std::pair< std::vector<BattleHex>, int > getPath(BattleHex start, BattleHex dest, const CStack *stack); //returned value: pair<path, length>; length may be different than number of elements in path since flying vreatures jump between distant hexes
 	//std::vector<BattleHex> getAccessibility(const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable = NULL, bool forPassingBy = false) const; //returns vector of accessible tiles (taking into account the creature range)

+ 40 - 34
lib/CArtHandler.cpp

@@ -271,7 +271,7 @@ CArtHandler::CArtHandler()
 	//VLC->arth = this;
 
 	// War machines are the default big artifacts.
-	for (ui32 i = 3; i <= 6; i++)
+	for (ArtifactID::ArtifactID i = ArtifactID::CATAPULT; i <= ArtifactID::FIRST_AID_TENT; vstd::advance(i, 1))
 		bigArtifacts.insert(i);
 }
 
@@ -288,7 +288,9 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
 {
 	std::vector<ui16> slots;
 	slots += 17, 16, 15, 14, 13, 18, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0;
-	growingArtifacts += 146, 147, 148, 150, 151, 152, 153;
+	growingArtifacts += ArtifactID::AXE_OF_SMASHING, ArtifactID::MITHRIL_MAIL,
+		ArtifactID::SWORD_OF_SHARPNESS, ArtifactID::PENDANT_OF_SORCERY, ArtifactID::BOOTS_OF_HASTE,
+		ArtifactID::BOW_OF_SEEKING, ArtifactID::DRAGON_EYE_RING;
 	static std::map<char, CArtifact::EartClass> classes =
 	  map_list_of('S',CArtifact::ART_SPECIAL)('T',CArtifact::ART_TREASURE)('N',CArtifact::ART_MINOR)('J',CArtifact::ART_MAJOR)('R',CArtifact::ART_RELIC);
 
@@ -300,7 +302,7 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
 
 	std::map<ui32,ui8>::iterator itr;
 
-	for (int i=0; i<GameConstants::ARTIFACTS_QUANTITY; i++)
+	for (ArtifactID::ArtifactID i=static_cast<ArtifactID::ArtifactID>(0); i<GameConstants::ARTIFACTS_QUANTITY; vstd::advance(i, 1))
 	{
 		CArtifact *art;
 		if (vstd::contains (growingArtifacts, i))
@@ -369,7 +371,7 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
 			BOOST_FOREACH(ui32 constituentID, *artifact->constituents)
 			{
 				if (artifacts[constituentID]->constituentOf == NULL)
-					artifacts[constituentID]->constituentOf = new std::vector<TArtifactID>();
+					artifacts[constituentID]->constituentOf = new std::vector<ArtifactID::ArtifactID>();
 				artifacts[constituentID]->constituentOf->push_back(artifact->id);
 			}
 		}
@@ -383,7 +385,7 @@ void CArtHandler::load(const JsonNode & node)
 		if (!entry.second.isNull()) // may happens if mod removed creature by setting json entry to null
 		{
 			CArtifact * art = loadArtifact(entry.second);
-			art->id = artifacts.size();
+			art->id = static_cast<ArtifactID::ArtifactID>(artifacts.size());
 
 			artifacts.push_back(art);
 			tlog5 << "Added artifact: " << entry.first << "\n";
@@ -493,41 +495,42 @@ CArtifact * CArtHandler::loadArtifact(const JsonNode & node)
 	return art;
 }
 
-void CArtifact::addConstituent (ui32 component)
+void CArtifact::addConstituent (ArtifactID::ArtifactID component)
 {
 	assert (constituents);
 	constituents->push_back (component);
 }
 
-int CArtHandler::convertMachineID(int id, bool creToArt )
+ArtifactID::ArtifactID CArtHandler::creatureToMachineID(CreatureID::CreatureID id)
 {
 	int dif = 142;
-	if(creToArt)
+	switch (id)
 	{
-		switch (id)
-		{
-		case 147:
-			dif--;
-			break;
-		case 148:
-			dif++;
-			break;
-		}
-		dif = -dif;
+	case 147:
+		dif--;
+		break;
+	case 148:
+		dif++;
+		break;
 	}
-	else
+	dif = -dif;
+	return static_cast<ArtifactID::ArtifactID>(id+dif);
+}
+
+CreatureID::CreatureID CArtHandler::machineIDToCreature(ArtifactID::ArtifactID id)
+{
+	int dif = 142;
+
+	switch (id)
 	{
-		switch (id)
-		{
-		case 6:
-			dif--;
-			break;
-		case 5:
-			dif++;
-			break;
-		}
+	case 6:
+		dif--;
+		break;
+	case 5:
+		dif++;
+		break;
 	}
-	return id + dif;
+	return static_cast<CreatureID::CreatureID>(id + dif);
 }
 
 void CArtHandler::sortArts()
@@ -648,17 +651,17 @@ Bonus *createBonus(Bonus::BonusType type, int val, int subtype, shared_ptr<IProp
 	return added;
 }
 
-void CArtHandler::giveArtBonus( TArtifactID aid, Bonus::BonusType type, int val, int subtype, Bonus::ValueType valType, shared_ptr<ILimiter> limiter, int additionalInfo)
+void CArtHandler::giveArtBonus( ArtifactID::ArtifactID aid, Bonus::BonusType type, int val, int subtype, Bonus::ValueType valType, shared_ptr<ILimiter> limiter, int additionalInfo)
 {
 	giveArtBonus(aid, createBonus(type, val, subtype, valType, limiter, additionalInfo));
 }
 
-void CArtHandler::giveArtBonus(TArtifactID aid, Bonus::BonusType type, int val, int subtype, shared_ptr<IPropagator> propagator /*= NULL*/, int additionalInfo)
+void CArtHandler::giveArtBonus(ArtifactID::ArtifactID aid, Bonus::BonusType type, int val, int subtype, shared_ptr<IPropagator> propagator /*= NULL*/, int additionalInfo)
 {
 	giveArtBonus(aid, createBonus(type, val, subtype, propagator, additionalInfo));
 }
 
-void CArtHandler::giveArtBonus(TArtifactID aid, Bonus *bonus)
+void CArtHandler::giveArtBonus(ArtifactID::ArtifactID aid, Bonus *bonus)
 {
 	bonus->sid = aid;
 	if(bonus->subtype == Bonus::MORALE || bonus->type == Bonus::LUCK)
@@ -747,11 +750,14 @@ void CArtHandler::readComponents (const JsonNode & node, CArtifact * art)
 	value = &node["components"];
 	if (!value->isNull())
 	{
-		art->constituents = new std::vector<TArtifactID>();
+		art->constituents = new std::vector<ArtifactID::ArtifactID>();
 		BOOST_FOREACH (auto component, value->Vector())
 		{
 			VLC->modh->identifiers.requestIdentifier(std::string("artifact.") + component.String(),
-				boost::bind (&CArtifact::addConstituent, art, _1)
+				[art](si32 id)
+				{
+					art->addConstituent(static_cast<ArtifactID::ArtifactID>(id));
+				}
 			);
 		}
 	}

+ 15 - 32
lib/CArtHandler.h

@@ -22,24 +22,6 @@ struct ArtifactLocation;
 class CArtifactSet;
 class CArtifactInstance;
 
-namespace ArtifactID
-{
-	enum ArtifactID
-	{
-		SPELLBOOK = 0,
-		SPELL_SCROLL = 1,
-		GRAIL = 2,
-		CATAPULT = 3,
-		BALLISTA = 4,
-		AMMO_CART = 5,
-		FIRST_AID_TENT = 6,
-		CENTAUR_AXE = 7,
-		BLACKSHARD_OF_THE_DEAD_KNIGHT = 8,
-		CORNUCOPIA = 140,
-		ART_LOCK = 145
-	};
-}
-
 #define ART_BEARER_LIST \
 	ART_BEARER(HERO)\
 	ART_BEARER(CREATURE)\
@@ -47,7 +29,7 @@ namespace ArtifactID
 
 namespace ArtBearer
 {
-	enum
+	enum ArtBearer
 	{
 #define ART_BEARER(x) x,
 		ART_BEARER_LIST
@@ -75,7 +57,7 @@ public:
 	void setName (std::string desc);
 	void setDescription (std::string desc);
 	void setEventText (std::string desc);
-	void addConstituent (ui32 component);
+	void addConstituent (ArtifactID::ArtifactID component);
 
 	int getArtClassSerial() const; //0 - treasure, 1 - minor, 2 - major, 3 - relic, 4 - spell scroll, 5 - other
 	std::string nodeName() const OVERRIDE;
@@ -84,11 +66,11 @@ public:
 	virtual void levelUpArtifact (CArtifactInstance * art){};
 
 	ui32 price;
-	bmap<ui8, std::vector<ArtifactPosition::ArtifactPosition> > possibleSlots; //Bearer Type => ids of slots where artifact can be placed
-	std::vector<TArtifactID> * constituents; // Artifacts IDs a combined artifact consists of, or NULL.
-	std::vector<TArtifactID> * constituentOf; // Reverse map of constituents.
+	bmap<ArtBearer::ArtBearer, std::vector<ArtifactPosition::ArtifactPosition> > possibleSlots; //Bearer Type => ids of slots where artifact can be placed
+	std::vector<ArtifactID::ArtifactID> * constituents; // Artifacts IDs a combined artifact consists of, or NULL.
+	std::vector<ArtifactID::ArtifactID> * constituentOf; // Reverse map of constituents.
 	EartClass aClass;
-	TArtifactID id;
+	ArtifactID::ArtifactID id;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -207,15 +189,15 @@ public:
 
 class DLL_LINKAGE CArtHandler //handles artifacts
 {
-	void giveArtBonus(TArtifactID aid, Bonus::BonusType type, int val, int subtype = -1, Bonus::ValueType valType = Bonus::BASE_NUMBER, shared_ptr<ILimiter> limiter = shared_ptr<ILimiter>(), int additionalinfo = 0);
-	void giveArtBonus(TArtifactID aid, Bonus::BonusType type, int val, int subtype, shared_ptr<IPropagator> propagator, int additionalinfo = 0);
-	void giveArtBonus(TArtifactID aid, Bonus *bonus);
+	void giveArtBonus(ArtifactID::ArtifactID aid, Bonus::BonusType type, int val, int subtype = -1, Bonus::ValueType valType = Bonus::BASE_NUMBER, shared_ptr<ILimiter> limiter = shared_ptr<ILimiter>(), int additionalinfo = 0);
+	void giveArtBonus(ArtifactID::ArtifactID aid, Bonus::BonusType type, int val, int subtype, shared_ptr<IPropagator> propagator, int additionalinfo = 0);
+	void giveArtBonus(ArtifactID::ArtifactID aid, Bonus *bonus);
 public:
 	std::vector<CArtifact*> treasures, minors, majors, relics;
 	std::vector< ConstTransitivePtr<CArtifact> > artifacts;
 	std::vector<CArtifact *> allowedArtifacts;
-	std::set<ui32> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines.
-	std::set<ui32> growingArtifacts;
+	std::set<ArtifactID::ArtifactID> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines.
+	std::set<ArtifactID::ArtifactID> growingArtifacts;
 
 	void loadArtifacts(bool onlyTxt);
 	/// load all artifacts from json structure
@@ -235,9 +217,10 @@ public:
 	void getAllowedArts(std::vector<ConstTransitivePtr<CArtifact> > &out, std::vector<CArtifact*> *arts, int flag);
 	void getAllowed(std::vector<ConstTransitivePtr<CArtifact> > &out, int flags);
 	void erasePickedArt (TArtifactInstanceID id);
-	bool isBigArtifact (TArtifactID artID) const {return bigArtifacts.find(artID) != bigArtifacts.end();}
+	bool isBigArtifact (ArtifactID::ArtifactID artID) const {return bigArtifacts.find(artID) != bigArtifacts.end();}
 	void initAllowedArtifactsList(const std::vector<bool> &allowed); //allowed[art_id] -> 0 if not allowed, 1 if allowed
-	static int convertMachineID(int id, bool creToArt);
+	static ArtifactID::ArtifactID creatureToMachineID(CreatureID::CreatureID id);
+	static CreatureID::CreatureID machineIDToCreature(ArtifactID::ArtifactID id);
 	void makeItCreatureArt (CArtifact * a, bool onlyCreature = true);
 	void makeItCreatureArt (TArtifactInstanceID aid, bool onlyCreature = true);
 	void makeItCommanderArt (CArtifact * a, bool onlyCommander = true);
@@ -295,7 +278,7 @@ public:
 	bool isPositionFree(ArtifactPosition::ArtifactPosition pos, bool onlyLockCheck = false) const;
 	si32 getArtTypeId(ArtifactPosition::ArtifactPosition pos) const;
 
-	virtual ui8 bearerType() const = 0;
+	virtual ArtBearer::ArtBearer bearerType() const = 0;
 	virtual ~CArtifactSet();
 
 	template <typename Handler> void serialize(Handler &h, const int version)

+ 4 - 4
lib/CBattleCallback.cpp

@@ -605,7 +605,7 @@ void CBattleInfoCallback::battleGetStackQueue(std::vector<const CStack *> &out,
 			else
 				p = 3;
 		}
-		else if(s->getCreature()->idNumber == 145  ||  s->getCreature()->idNumber == 149) //catapult and turrets are first
+		else if(s->getCreature()->idNumber == CreatureID::CATAPULT  ||  s->getCreature()->idNumber == CreatureID::ARROW_TOWERS) //catapult and turrets are first
 		{
 			p = 0;
 		}
@@ -765,7 +765,7 @@ bool CBattleInfoCallback::battleCanShoot(const CStack * stack, BattleHex dest) c
 	if(stack->hasBonusOfType(Bonus::FORGETFULL)) //forgetfulness
 		return false;
 
-	if(stack->getCreature()->idNumber == 145 && dst) //catapult cannot attack creatures
+	if(stack->getCreature()->idNumber == CreatureID::CATAPULT && dst) //catapult cannot attack creatures
 		return false;
 
 	//const CGHeroInstance * stackHero = battleGetOwner(stack);
@@ -800,12 +800,12 @@ TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo &info) c
 	const CCreature *attackerType = info.attacker->getCreature(),
 		*defenderType = info.defender->getCreature();
 
-	if(attackerType->idNumber == 149) //arrow turret
+	if(attackerType->idNumber == CreatureID::ARROW_TOWERS)
 	{
 		SiegeStuffThatShouldBeMovedToHandlers::retreiveTurretDamageRange(info.attacker, minDmg, maxDmg);
 	}
 
-	if(info.attackerBonuses->hasBonusOfType(Bonus::SIEGE_WEAPON) && attackerType->idNumber != 149) //any siege weapon, but only ballista can attack (second condition - not arrow turret)
+	if(info.attackerBonuses->hasBonusOfType(Bonus::SIEGE_WEAPON) && attackerType->idNumber != CreatureID::ARROW_TOWERS) //any siege weapon, but only ballista can attack (second condition - not arrow turret)
 	{ //minDmg and maxDmg are multiplied by hero attack + 1
 		auto retreiveHeroPrimSkill = [&](int skill) -> int
 		{

+ 11 - 10
lib/CCreatureHandler.cpp

@@ -24,8 +24,6 @@ CCreatureHandler::CCreatureHandler()
 {
 	VLC->creh = this;
 
-	doubledCreatures +=  4, 14, 20, 28, 44, 60, 70, 72, 85, 86, 100, 104; //FIXME: move to creature config //according to Strategija
-
 	allCreatures.setDescription("All creatures");
 	creaturesOfLevel[0].setDescription("Creatures of unnormalized tier");
 	for(int i = 1; i < ARRAY_COUNT(creaturesOfLevel); i++)
@@ -223,7 +221,7 @@ void CCreatureHandler::loadCreatures()
 			parser.endLine();
 
 		CCreature &ncre = *new CCreature;
-		ncre.idNumber = creatures.size();
+		ncre.idNumber = static_cast<CreatureID::CreatureID>(creatures.size());
 		ncre.cost.resize(GameConstants::RESOURCE_QUANTITY);
 		ncre.level=0;
 		ncre.iconIndex = ncre.idNumber + 2; // +2 for empty\selection images
@@ -545,7 +543,7 @@ void CCreatureHandler::load(const JsonNode & node)
 		{
 			CCreature * creature = loadCreature(entry.second);
 			creature->nameRef = entry.first;
-			creature->idNumber = creatures.size();
+			creature->idNumber = static_cast<CreatureID::CreatureID>(creatures.size());
 
 			creatures.push_back(creature);
 			tlog5 << "Added creature: " << entry.first << "\n";
@@ -679,10 +677,13 @@ void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & c
 	{
 		VLC->modh->identifiers.requestIdentifier(std::string("creature.") + value.String(), [=](si32 identifier)
 		{
-			creature->upgrades.insert(identifier);
+			creature->upgrades.insert(static_cast<CreatureID::CreatureID>(identifier));
 		});
 	}
 
+	if(config["hasDoubleWeek"].Bool())
+		doubledCreatures.insert(creature->idNumber);
+
 	creature->projectile = config["graphics"]["missile"]["projectile"].String();
 	creature->projectileSpin = config["graphics"]["missile"]["spinning"].Bool();
 
@@ -1011,7 +1012,7 @@ CCreatureHandler::~CCreatureHandler()
 {
 }
 
-int CCreatureHandler::pickRandomMonster(const boost::function<int()> &randGen, int tier) const
+CreatureID::CreatureID CCreatureHandler::pickRandomMonster(const boost::function<int()> &randGen, int tier) const
 {
 	int r = 0;
 	if(tier == -1) //pick any allowed creature
@@ -1024,11 +1025,11 @@ int CCreatureHandler::pickRandomMonster(const boost::function<int()> &randGen, i
 	else
 	{
 		assert(vstd::iswithin(tier, 1, 7));
-		std::vector<int> allowed;
+		std::vector<CreatureID::CreatureID> allowed;
 		BOOST_FOREACH(const CBonusSystemNode *b, creaturesOfLevel[tier].getChildrenNodes())
 		{
 			assert(b->getNodeType() == CBonusSystemNode::CREATURE);
-			int creid = static_cast<const CCreature*>(b)->idNumber;
+			CreatureID::CreatureID creid = static_cast<const CCreature*>(b)->idNumber;
 			if(!vstd::contains(notUsedMonsters, creid))
 				allowed.push_back(creid);
 		}
@@ -1036,12 +1037,12 @@ int CCreatureHandler::pickRandomMonster(const boost::function<int()> &randGen, i
 		if(!allowed.size())
 		{
 			tlog2 << "Cannot pick a random creature of tier " << tier << "!\n";
-			return 0;
+			return CreatureID::NONE;
 		}
 
 		return vstd::pickRandomElementOf(allowed, randGen);
 	}
-	return r;
+	return static_cast<CreatureID::CreatureID>(r);
 }
 
 void CCreatureHandler::addBonusForTier(int tier, Bonus *b)

+ 5 - 5
lib/CCreatureHandler.h

@@ -28,7 +28,7 @@ public:
 	std::string namePl, nameSing, nameRef; //name in singular and plural form; and reference name
 	TResources cost; //cost[res_id] - amount of that resource
 	std::set<std::string> upgradeNames; //for reference, they are later transformed info ui32 upgrades
-	std::set<ui32> upgrades; // IDs of creatures to which this creature can be upgraded
+	std::set<CreatureID::CreatureID> upgrades; // IDs of creatures to which this creature can be upgraded
 	//damage, hp. etc are handled by Bonuses
 	ui32 fightValue, AIValue, growth, hordeGrowth;
 	ui32 ammMin, ammMax;
@@ -36,11 +36,11 @@ public:
 	std::string abilityRefs; //references to abilities, in text format
 	std::string animDefName;
 	std::string advMapDef; //for new creatures only
-	si32 idNumber;
+	CreatureID::CreatureID idNumber;
 	si32 iconIndex; // index of icon in files like twcrport
 	TFaction faction; //-1 = neutral
 	ui8 level; // 0 - unknown
-	ui8 doubleWide;
+	bool doubleWide;
 	ui8 special; // Creature is not available normally (war machines, commanders, etc
 
 	///animation info
@@ -132,7 +132,7 @@ private:
 	void loadCreatureJson(CCreature * creature, const JsonNode & config);
 public:
 	std::set<int> notUsedMonsters;
-	std::set<TCreature> doubledCreatures; //they get double week
+	std::set<CreatureID::CreatureID> doubledCreatures; //they get double week
 	std::vector<ConstTransitivePtr<CCreature> > creatures; //creature ID -> creature info
 
 	//stack exp
@@ -169,7 +169,7 @@ public:
 	~CCreatureHandler();
 
 	void deserializationFix();
-	int pickRandomMonster(const boost::function<int()> &randGen = 0, int tier = -1) const; //tier <1 - CREATURES_PER_TOWN> or -1 for any
+	CreatureID::CreatureID pickRandomMonster(const boost::function<int()> &randGen = 0, int tier = -1) const; //tier <1 - CREATURES_PER_TOWN> or -1 for any
 	void addBonusForTier(int tier, Bonus *b); //tier must be <1-7>
 	void addBonusForAllCreatures(Bonus *b);
 

+ 12 - 12
lib/CCreatureSet.cpp

@@ -39,7 +39,7 @@ const CCreature* CCreatureSet::getCreature(TSlot slot) const
 		return NULL;
 }
 
-bool CCreatureSet::setCreature(TSlot slot, TCreature type, TQuantity quantity) /*slots 0 to 6 */
+bool CCreatureSet::setCreature(TSlot slot, CreatureID::CreatureID type, TQuantity quantity) /*slots 0 to 6 */
 {
 	if(slot > 6 || slot < 0)
 	{
@@ -60,7 +60,7 @@ bool CCreatureSet::setCreature(TSlot slot, TCreature type, TQuantity quantity) /
 	return true;
 }
 
-TSlot CCreatureSet::getSlotFor(TCreature creature, ui32 slotsAmount/*=7*/) const /*returns -1 if no slot available */
+TSlot CCreatureSet::getSlotFor(CreatureID::CreatureID creature, ui32 slotsAmount/*=7*/) const /*returns -1 if no slot available */
 {
 	return getSlotFor(VLC->creh->creatures[creature], slotsAmount);
 }
@@ -162,7 +162,7 @@ void CCreatureSet::sweep()
 	}
 }
 
-void CCreatureSet::addToSlot(TSlot slot, TCreature cre, TQuantity count, bool allowMerging/* = true*/)
+void CCreatureSet::addToSlot(TSlot slot, CreatureID::CreatureID cre, TQuantity count, bool allowMerging/* = true*/)
 {
 	const CCreature *c = VLC->creh->creatures[cre];
 
@@ -463,7 +463,7 @@ CStackInstance::CStackInstance()
 	init();
 }
 
-CStackInstance::CStackInstance(TCreature id, TQuantity Count)
+CStackInstance::CStackInstance(CreatureID::CreatureID id, TQuantity Count)
 	: armyObj(_armyObj)
 {
 	init();
@@ -545,7 +545,7 @@ void CStackInstance::giveStackExp(TExpType exp)
 	vstd::amin(experience += exp, maxExp); //can't get more exp than this limit
 }
 
-void CStackInstance::setType(int creID)
+void CStackInstance::setType(CreatureID::CreatureID creID)
 {
 	if(creID >= 0 && creID < VLC->creh->creatures.size())
 		setType(VLC->creh->creatures[creID]);
@@ -974,12 +974,12 @@ void CStackInstance::deserializationFix()
 	artDeserializationFix(this);
 }
 
-int CStackInstance::getCreatureID() const
+CreatureID::CreatureID CStackInstance::getCreatureID() const
 {
 	if(type)
 		return type->idNumber;
 	else 
-		return -1;
+		return CreatureID::NONE;
 }
 
 std::string CStackInstance::getName() const
@@ -993,7 +993,7 @@ ui64 CStackInstance::getPower() const
 	return type->AIValue * count;
 }
 
-ui8 CStackInstance::bearerType() const
+ArtBearer::ArtBearer CStackInstance::bearerType() const
 {
 	return ArtBearer::CREATURE;
 }
@@ -1004,7 +1004,7 @@ CCommanderInstance::CCommanderInstance()
 	name = "Unnamed";
 }
 
-CCommanderInstance::CCommanderInstance (TCreature id)
+CCommanderInstance::CCommanderInstance (CreatureID::CreatureID id)
 {
 	init();
 	setType(id);
@@ -1059,7 +1059,7 @@ void CCommanderInstance::levelUp ()
 	}
 }
 
-ui8 CCommanderInstance::bearerType() const
+ArtBearer::ArtBearer CCommanderInstance::bearerType() const
 {
 	return ArtBearer::COMMANDER;
 }
@@ -1070,7 +1070,7 @@ CStackBasicDescriptor::CStackBasicDescriptor()
 	count = -1;
 }
 
-CStackBasicDescriptor::CStackBasicDescriptor(TCreature id, TQuantity Count)
+CStackBasicDescriptor::CStackBasicDescriptor(CreatureID::CreatureID id, TQuantity Count)
 	: type (VLC->creh->creatures[id]), count(Count)
 {
 }
@@ -1104,7 +1104,7 @@ CSimpleArmy::operator bool() const
 	return army.size();
 }
 
-bool CSimpleArmy::setCreature(TSlot slot, TCreature cre, TQuantity count)
+bool CSimpleArmy::setCreature(TSlot slot, CreatureID::CreatureID cre, TQuantity count)
 {
 	assert(!vstd::contains(army, slot));
 	army[slot] = CStackBasicDescriptor(cre, count);

+ 12 - 12
lib/CCreatureSet.h

@@ -27,7 +27,7 @@ public:
 	TQuantity count;
 
 	CStackBasicDescriptor();
-	CStackBasicDescriptor(TCreature id, TQuantity Count);
+	CStackBasicDescriptor(CreatureID::CreatureID id, TQuantity Count);
 	CStackBasicDescriptor(const CCreature *c, TQuantity Count);
 
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -65,20 +65,20 @@ public:
 	std::string getQuantityTXT(bool capitalized = true) const;
 	virtual int getExpRank() const;
 	si32 magicResistance() const;
-	int getCreatureID() const; //-1 if not available
+	CreatureID::CreatureID getCreatureID() const; //-1 if not available
 	std::string getName() const; //plural or singular
 	virtual void init();
 	CStackInstance();
-	CStackInstance(TCreature id, TQuantity count);
+	CStackInstance(CreatureID::CreatureID id, TQuantity count);
 	CStackInstance(const CCreature *cre, TQuantity count);
 	~CStackInstance();
 
-	void setType(int creID);
+	void setType(CreatureID::CreatureID creID);
 	void setType(const CCreature *c);
 	void setArmyObj(const CArmedInstance *ArmyObj);
 	virtual void giveStackExp(TExpType exp);
 	bool valid(bool allowUnrandomized) const;
-	ui8 bearerType() const OVERRIDE; //from CArtifactSet
+	ArtBearer::ArtBearer bearerType() const OVERRIDE; //from CArtifactSet
 	virtual std::string nodeName() const OVERRIDE; //from CBonusSystemnode
 	void deserializationFix();
 };
@@ -97,7 +97,7 @@ public:
 	//std::vector <CArtifactInstance *> arts;
 	void init() OVERRIDE;
 	CCommanderInstance();
-	CCommanderInstance (TCreature id);
+	CCommanderInstance (CreatureID::CreatureID id);
 	~CCommanderInstance();
 	void setAlive (bool alive);
 	void giveStackExp (TExpType exp);
@@ -105,7 +105,7 @@ public:
 
 	ui64 getPower() const {return 0;};
 	int getExpRank() const;
-	ui8 bearerType() const OVERRIDE; //from CArtifactSet
+	ArtBearer::ArtBearer bearerType() const OVERRIDE; //from CArtifactSet
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -123,7 +123,7 @@ class IArmyDescriptor
 {
 public:
 	virtual void clear() = 0;
-	virtual bool setCreature(TSlot slot, TCreature cre, TQuantity count) = 0;
+	virtual bool setCreature(TSlot slot, CreatureID::CreatureID cre, TQuantity count) = 0;
 };
 
 //simplified version of CCreatureSet
@@ -132,7 +132,7 @@ class DLL_LINKAGE CSimpleArmy : public IArmyDescriptor
 public:
 	TSimpleSlots army;
 	void clear() OVERRIDE;
-	bool setCreature(TSlot slot, TCreature cre, TQuantity count) OVERRIDE;
+	bool setCreature(TSlot slot, CreatureID::CreatureID cre, TQuantity count) OVERRIDE;
 	operator bool() const;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -157,7 +157,7 @@ public:
 
 	const TSlots &Slots() const {return stacks;}
 
-	void addToSlot(TSlot slot, TCreature cre, TQuantity count, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature
+	void addToSlot(TSlot slot, CreatureID::CreatureID cre, TQuantity count, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature
 	void addToSlot(TSlot slot, CStackInstance *stack, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature
 	void clear() OVERRIDE;
 	void setFormation(bool tight);
@@ -175,7 +175,7 @@ public:
 	void eraseStack(TSlot slot); //slot must be occupied
 	void joinStack(TSlot slot, CStackInstance * stack); //adds new stack to the existing stack of the same type
 	void changeStackCount(TSlot slot, TQuantity toAdd); //stack must exist!
-	bool setCreature (TSlot slot, TCreature type, TQuantity quantity) OVERRIDE; //replaces creature in stack; slots 0 to 6, if quantity=0 erases stack
+	bool setCreature (TSlot slot, CreatureID::CreatureID type, TQuantity quantity) OVERRIDE; //replaces creature in stack; slots 0 to 6, if quantity=0 erases stack
 	void setToArmy(CSimpleArmy &src); //erases all our army and moves stacks from src to us; src MUST NOT be an armed object! WARNING: use it wisely. Or better do not use at all.
 
 	const CStackInstance& getStack(TSlot slot) const; //stack must exist
@@ -184,7 +184,7 @@ public:
 	int getStackCount (TSlot slot) const;
 	TExpType getStackExperience(TSlot slot) const;
 	TSlot findStack(const CStackInstance *stack) const; //-1 if none
-	TSlot getSlotFor(TCreature creature, ui32 slotsAmount = GameConstants::ARMY_SIZE) const; //returns -1 if no slot available
+	TSlot getSlotFor(CreatureID::CreatureID creature, ui32 slotsAmount = GameConstants::ARMY_SIZE) const; //returns -1 if no slot available
 	TSlot getSlotFor(const CCreature *c, ui32 slotsAmount = GameConstants::ARMY_SIZE) const; //returns -1 if no slot available
 	TSlot getFreeSlot(ui32 slotsAmount = GameConstants::ARMY_SIZE) const;
 	bool mergableStacks(std::pair<TSlot, TSlot> &out, TSlot preferable = -1) const; //looks for two same stacks, returns slot positions;

+ 1 - 1
lib/CDefObjInfoHandler.cpp

@@ -90,7 +90,7 @@ void CDefObjInfoHandler::load()
 
 		for(int yy=0; yy<2; ++yy) //first - on which types of terrain object can be placed;
 			inp>>dump; //second -in which terrains' menus object in the editor will be available (?)
-		inp>>nobj->id;
+		si32 id; inp >> id; nobj->id = static_cast<Obj::Obj>(id);
 		inp>>nobj->subid;
 		inp>>nobj->type;
 

+ 2 - 1
lib/CDefObjInfoHandler.h

@@ -23,7 +23,8 @@ public:
 	ui8 blockMap[6];
 	ui8 coverageMap[6], shadowCoverage[6]; //to determine which tiles are covered by picture of this object
 	ui8 visitDir; //directions from which object can be entered, format same as for moveDir in CGHeroInstance(but 0 - 7)
-	si32 id, subid; //of object described by this defInfo
+	Obj::Obj id;
+	si32 subid; //of object described by this defInfo
 	si32 terrainAllowed, //on which terrain it is possible to place object
 		 terrainMenu; //in which menus in map editor object will be showed
 	si32 width, height; //tiles

+ 35 - 35
lib/CGameState.cpp

@@ -332,7 +332,7 @@ DLL_LINKAGE std::string MetaString::buildList () const
 }
 
 
-void  MetaString::addCreReplacement(TCreature id, TQuantity count) //adds sing or plural name;
+void  MetaString::addCreReplacement(CreatureID::CreatureID id, TQuantity count) //adds sing or plural name;
 {
 	if (!count)
 		addReplacement (CRE_PL_NAMES, id); //no creatures - just empty name (eg. defeat Angels)
@@ -348,7 +348,7 @@ void MetaString::addReplacement(const CStackBasicDescriptor &stack)
 	addCreReplacement(stack.type->idNumber, stack.count);
 }
 
-static CGObjectInstance * createObject(int id, int subid, int3 pos, int owner)
+static CGObjectInstance * createObject(Obj::Obj id, int subid, int3 pos, int owner)
 {
 	CGObjectInstance * nobj;
 	switch(id)
@@ -516,34 +516,34 @@ int CGameState::pickHero(int owner)
 }
 
 
-std::pair<int,int> CGameState::pickObject (CGObjectInstance *obj)
+std::pair<Obj::Obj,int> CGameState::pickObject (CGObjectInstance *obj)
 {
 	switch(obj->ID)
 	{
 	case Obj::RANDOM_ART:
-		return std::pair<int,int>(Obj::ARTIFACT, VLC->arth->getRandomArt (CArtifact::ART_TREASURE | CArtifact::ART_MINOR | CArtifact::ART_MAJOR | CArtifact::ART_RELIC));
+		return std::make_pair(Obj::ARTIFACT, VLC->arth->getRandomArt (CArtifact::ART_TREASURE | CArtifact::ART_MINOR | CArtifact::ART_MAJOR | CArtifact::ART_RELIC));
 	case Obj::RANDOM_TREASURE_ART:
-		return std::pair<int,int>(Obj::ARTIFACT, VLC->arth->getRandomArt (CArtifact::ART_TREASURE));
+		return std::make_pair(Obj::ARTIFACT, VLC->arth->getRandomArt (CArtifact::ART_TREASURE));
 	case Obj::RANDOM_MINOR_ART:
-		return std::pair<int,int>(Obj::ARTIFACT, VLC->arth->getRandomArt (CArtifact::ART_MINOR));
+		return std::make_pair(Obj::ARTIFACT, VLC->arth->getRandomArt (CArtifact::ART_MINOR));
 	case Obj::RANDOM_MAJOR_ART:
-		return std::pair<int,int>(Obj::ARTIFACT, VLC->arth->getRandomArt (CArtifact::ART_MAJOR));
+		return std::make_pair(Obj::ARTIFACT, VLC->arth->getRandomArt (CArtifact::ART_MAJOR));
 	case Obj::RANDOM_RELIC_ART:
-		return std::pair<int,int>(Obj::ARTIFACT, VLC->arth->getRandomArt (CArtifact::ART_RELIC));
+		return std::make_pair(Obj::ARTIFACT, VLC->arth->getRandomArt (CArtifact::ART_RELIC));
 	case Obj::RANDOM_HERO:
-		return std::pair<int,int>(Obj::HERO, pickHero(obj->tempOwner));
+		return std::make_pair(Obj::HERO, pickHero(obj->tempOwner));
 	case Obj::RANDOM_MONSTER:
-		return std::pair<int,int>(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran)));
+		return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran)));
 	case Obj::RANDOM_MONSTER_L1:
-		return std::pair<int,int>(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 1));
+		return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 1));
 	case Obj::RANDOM_MONSTER_L2:
-		return std::pair<int,int>(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 2));
+		return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 2));
 	case Obj::RANDOM_MONSTER_L3:
-		return std::pair<int,int>(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 3));
+		return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 3));
 	case Obj::RANDOM_MONSTER_L4:
-		return std::pair<int,int>(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 4));
+		return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 4));
 	case Obj::RANDOM_RESOURCE:
-		return std::pair<int,int>(Obj::RESOURCE,ran()%7); //now it's OH3 style, use %8 for mithril
+		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,
@@ -565,14 +565,14 @@ std::pair<int,int> CGameState::pickObject (CGObjectInstance *obj)
 				std::advance(iter, ran()%VLC->townh->towns.size());
 				f = iter->first;
 			}
-			return std::pair<int,int>(Obj::TOWN,f);
+			return std::make_pair(Obj::TOWN,f);
 		}
 	case Obj::RANDOM_MONSTER_L5:
-		return std::pair<int,int>(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 5));
+		return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 5));
 	case Obj::RANDOM_MONSTER_L6:
-		return std::pair<int,int>(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 6));
+		return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 6));
 	case Obj::RANDOM_MONSTER_L7:
-		return std::pair<int,int>(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 7));
+		return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(boost::ref(ran), 7));
 	case Obj::RANDOM_DWELLING:
 	case Obj::RANDOM_DWELLING_LVL:
 	case Obj::RANDOM_DWELLING_FACTION:
@@ -630,38 +630,38 @@ std::pair<int,int> CGameState::pickObject (CGObjectInstance *obj)
 			delete dwl->info;
 			dwl->info = nullptr;
 
-			std::pair<int,int> result(-1, -1);
+			std::pair<Obj::Obj,int> result(Obj::NO_OBJ, -1);
 			int cid = VLC->townh->towns[faction].creatures[level][0];
 
 			//golem factory is not in list of cregens but can be placed as random object
 			static const int factoryCreatures[] = {32, 33, 116, 117};
 			std::vector<int> factory(factoryCreatures, factoryCreatures + ARRAY_COUNT(factoryCreatures));
 			if (vstd::contains(factory, cid))
-				result = std::pair<int,int>(20, 1);
+				result = std::make_pair(Obj::CREATURE_GENERATOR4, 1);
 
 			//NOTE: this will pick last dwelling with this creature (Mantis #900)
 			//check for block map equality is better but more complex solution
 			BOOST_FOREACH(auto &iter, VLC->objh->cregens)
 				if (iter.second == cid)
-					result = std::pair<int,int>(17, iter.first);
+					result = std::make_pair(Obj::CREATURE_GENERATOR1, iter.first);
 
-			if (result.first == -1)
+			if (result.first == Obj::NO_OBJ)
 			{
 				tlog0 << "Error: failed to find creature for dwelling of "<< int(faction) << " of level " << int(level) << "\n";
 				auto iter = VLC->objh->cregens.begin();
 				std::advance(iter, ran() % VLC->objh->cregens.size() );
-				result = std::pair<int, int>(17, iter->first);
+				result = std::make_pair(Obj::CREATURE_GENERATOR1, iter->first);
 			}
 
 			return result;
 		}
 	}
-	return std::pair<int,int>(-1,-1);
+	return std::make_pair(Obj::NO_OBJ,-1);
 }
 
 void CGameState::randomizeObject(CGObjectInstance *cur)
 {
-	std::pair<int,int> ran = pickObject(cur);
+	std::pair<Obj::Obj,int> ran = pickObject(cur);
 	if(ran.first<0 || ran.second<0) //this is not a random object, or we couldn't find anything
 	{
 		if(cur->ID==Obj::TOWN) //town - set def
@@ -806,7 +806,7 @@ void CGameState::init(StartInfo * si)
 					{
 						if(hero->slotEmpty(i))
 						{
-							hero->addToSlot(i, curBonus->info2, curBonus->info3);
+							hero->addToSlot(i, static_cast<CreatureID::CreatureID>(curBonus->info2), curBonus->info3);
 							break;
 						}
 					}
@@ -1737,7 +1737,7 @@ void CGameState::initDuel()
 
 		for(int j = 0; j < ARRAY_COUNT(dp.sides[i].stacks); j++)
 		{
-			TCreature cre = dp.sides[i].stacks[j].type;
+			CreatureID::CreatureID cre = dp.sides[i].stacks[j].type;
 			TQuantity count = dp.sides[i].stacks[j].count;
 			if(count || obj->hasStackAtSlot(j))
 				obj->setCreature(j, cre, count);
@@ -1859,7 +1859,7 @@ UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
 		TBonusListPtr lista = h->getBonuses(Selector::typeSubtype(Bonus::SPECIAL_UPGRADE, base->idNumber));
 		BOOST_FOREACH(const Bonus *it, *lista)
 		{
-			ui16 nid = it->additionalInfo;
+			auto nid = static_cast<CreatureID::CreatureID>(it->additionalInfo);
 			if (nid != base->idNumber) //in very specific case the upgrade is available by default (?)
 			{
 				ret.newID.push_back(nid);
@@ -1874,7 +1874,7 @@ UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
 		{
 			if (vstd::contains(dwelling.second, base->idNumber)) //Dwelling with our creature
 			{
-				BOOST_FOREACH(ui32 upgrID, dwelling.second)
+				BOOST_FOREACH(auto upgrID, dwelling.second)
 				{
 					if(vstd::contains(base->upgrades, upgrID)) //possible upgrade
 					{
@@ -1887,12 +1887,12 @@ UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
 	}
 
 	//hero is visiting Hill Fort
-	if(h && map->getTile(h->visitablePos()).visitableObjects.front()->ID == 35)
+	if(h && map->getTile(h->visitablePos()).visitableObjects.front()->ID == Obj::HILL_FORT)
 	{
 		static const int costModifiers[] = {0, 25, 50, 75, 100}; //we get cheaper upgrades depending on level
 		const int costModifier = costModifiers[std::min<int>(std::max((int)base->level - 1, 0), ARRAY_COUNT(costModifiers) - 1)];
 
-		BOOST_FOREACH(si32 nid, base->upgrades)
+		BOOST_FOREACH(auto nid, base->upgrades)
 		{
 			ret.newID.push_back(nid);
 			ret.cost.push_back((VLC->creh->creatures[nid]->cost - base->cost) * costModifier / 100);
@@ -2941,11 +2941,11 @@ int ArmyDescriptor::getStrength() const
 }
 
 DuelParameters::SideSettings::StackSettings::StackSettings()
-	: type(-1), count(0)
+	: type(CreatureID::NONE), count(0)
 {
 }
 
-DuelParameters::SideSettings::StackSettings::StackSettings(si32 Type, si32 Count)
+DuelParameters::SideSettings::StackSettings::StackSettings(CreatureID::CreatureID Type, si32 Count)
 	: type(Type), count(Count)
 {
 }
@@ -2974,7 +2974,7 @@ DuelParameters DuelParameters::fromJSON(const std::string &fname)
 		int i = 0;
 		BOOST_FOREACH(const JsonNode &stackNode, n["army"].Vector())
 		{
-			ss.stacks[i].type = stackNode.Vector()[0].Float();
+			ss.stacks[i].type = static_cast<CreatureID::CreatureID>((si32)stackNode.Vector()[0].Float());
 			ss.stacks[i].count = stackNode.Vector()[1].Float();
 			i++;
 		}

+ 7 - 7
lib/CGameState.h

@@ -216,10 +216,10 @@ public:
 
 struct UpgradeInfo
 {
-	int oldID; //creature to be upgraded
-	std::vector<int> newID; //possible upgrades
+	CreatureID::CreatureID oldID; //creature to be upgraded
+	std::vector<CreatureID::CreatureID> newID; //possible upgrades
 	std::vector<TResources> cost; // cost[upgrade_serial] -> set of pairs<resource_ID,resource_amount>; cost is for single unit (not entire stack)
-	UpgradeInfo(){oldID = -1;};
+	UpgradeInfo(){oldID = CreatureID::NONE;};
 };
 
 struct DLL_LINKAGE CGPathNode
@@ -274,7 +274,7 @@ struct DLL_EXPORT DuelParameters
 	{
 		struct DLL_EXPORT StackSettings
 		{
-			si32 type;
+			CreatureID::CreatureID type;
 			si32 count;
 			template <typename Handler> void serialize(Handler &h, const int version)
 			{
@@ -282,7 +282,7 @@ struct DLL_EXPORT DuelParameters
 			}
 
 			StackSettings();
-			StackSettings(si32 Type, si32 Count);
+			StackSettings(CreatureID::CreatureID Type, si32 Count);
 		} stacks[GameConstants::ARMY_SIZE];
 
 		si32 heroId; //-1 if none
@@ -365,7 +365,7 @@ class DLL_LINKAGE CGameState : public CNonConstInfoCallback
 {
 public:
 	ConstTransitivePtr<StartInfo> scenarioOps, initialOpts; //second one is a copy of settings received from pregame (not randomized)
-	ui8 currentPlayer; //ID of player currently having turn
+	TPlayerColor currentPlayer; //ID of player currently having turn
 	ConstTransitivePtr<BattleInfo> curB; //current battle
 	ui32 day; //total number of days in game
 	ConstTransitivePtr<CMap> map;
@@ -393,7 +393,7 @@ public:
 
 	void initDuel();
 	void randomizeObject(CGObjectInstance *cur);
-	std::pair<int,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
+	std::pair<Obj::Obj,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
 	int pickHero(int owner);
 	void giveHeroArtifact(CGHeroInstance *h, int aid);
 

+ 2 - 2
lib/CHeroHandler.cpp

@@ -255,7 +255,7 @@ CHero * CHeroHandler::loadHero(const JsonNode & node)
 
 		VLC->modh->identifiers.requestIdentifier(std::string("creature.") + source["creature"].String(), [=](si32 creature)
 		{
-			hero->initialArmy[i].creature = creature;
+			hero->initialArmy[i].creature = static_cast<CreatureID::CreatureID>(creature);
 		});
 	}
 
@@ -404,7 +404,7 @@ void CHeroHandler::loadHeroes()
 			refName[0] = std::tolower(refName[0]); // to camelCase
 			VLC->modh->identifiers.requestIdentifier(std::string("creature.") + refName, [=](si32 creature)
 			{
-				hero->initialArmy[x].creature = creature;
+				hero->initialArmy[x].creature = static_cast<CreatureID::CreatureID>(creature);
 			});
 		}
 		parser.endLine();

+ 1 - 1
lib/CHeroHandler.h

@@ -50,7 +50,7 @@ public:
 	{
 		ui32 minAmount;
 		ui32 maxAmount;
-		TCreature creature;
+		CreatureID::CreatureID creature;
 
 		template <typename Handler> void serialize(Handler &h, const int version)
 		{

+ 45 - 44
lib/CObjectHandler.cpp

@@ -138,12 +138,12 @@ bool CPlayersVisited::wasVisited( TPlayerColor player ) const
 
 // 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 <ui16, ui32> > &storage)
+static void readCreatures(const JsonNode &creature, std::vector< std::pair <CreatureID::CreatureID, ui32> > &storage)
 {
-	std::pair<si16, si32> creInfo = std::make_pair(-1, 0);
+	std::pair<CreatureID::CreatureID, si32> creInfo = std::make_pair(CreatureID::NONE, 0);
 
 	creInfo.second = creature["number"].Float();
-	creInfo.first = creature["id"].Float();
+	creInfo.first = static_cast<CreatureID::CreatureID>((si32)creature["id"].Float());
 	storage.push_back(creInfo);
 }
 
@@ -195,7 +195,7 @@ void CObjectHandler::loadObjects()
 	const JsonNode config(ResourceID("config/dwellings.json"));
 	BOOST_FOREACH(const JsonNode &dwelling, config["dwellings"].Vector())
 	{
-		cregens[dwelling["dwelling"].Float()] = dwelling["creature"].Float();
+		cregens[dwelling["dwelling"].Float()] = static_cast<CreatureID::CreatureID>((si32)dwelling["creature"].Float());
 	}
 	tlog5 << "\t\tDone loading cregens!\n";
 
@@ -262,7 +262,8 @@ CGObjectInstance::CGObjectInstance(): animPhaseShift(rand()%0xff)
 	pos = int3(-1,-1,-1);
 	//std::cout << "Tworze obiekt "<<this<<std::endl;
 	//state = new CLuaObjectScript();
-	ID = subID = id = -1;
+	ID = Obj::NO_OBJ;
+	subID = id = -1;
 	defInfo = NULL;
 	tempOwner = 254;
 	blockVisit = false;
@@ -404,7 +405,7 @@ void CGObjectInstance::setProperty( ui8 what, ui32 val )
 		blockVisit = val;
 		break;
 	case ObjProperty::ID:
-		ID = val;
+		ID = static_cast<Obj::Obj>(val);
 		break;
 	case ObjProperty::SUBID:
 		subID = val;
@@ -822,22 +823,23 @@ void CGHeroInstance::initArmy(IArmyDescriptor *dst /*= NULL*/)
 		int range = stack.maxAmount - stack.minAmount;
 		int count = ran()%(range+1) + stack.minAmount;
 
-		if(stack.creature >= 145 &&
-		   stack.creature <= 149) //war machine
+		if(stack.creature >= CreatureID::CATAPULT &&
+		   stack.creature <= CreatureID::ARROW_TOWERS) //war machine
 		{
 			warMachinesGiven++;
 			if(dst != this)
 				continue;
 
-			int slot = -1, aid = -1;
+			int slot = -1;
+			ArtifactID::ArtifactID aid = ArtifactID::NONE;
 			switch (stack.creature)
 			{
-			case 145: //catapult
+			case CreatureID::CATAPULT:
 				slot = ArtifactPosition::MACH4;
-				aid = 3;
+				aid = ArtifactID::CATAPULT;
 				break;
 			default:
-				aid = CArtHandler::convertMachineID(stack.creature, true);
+				aid = CArtHandler::creatureToMachineID(stack.creature);
 				slot = 9 + aid;
 				break;
 			}
@@ -1575,7 +1577,7 @@ CGHeroInstance::ECanDig CGHeroInstance::diggingStatus() const
 	}
 }
 
-ui8 CGHeroInstance::bearerType() const
+ArtBearer::ArtBearer CGHeroInstance::bearerType() const
 {
 	return ArtBearer::HERO;
 }
@@ -1586,14 +1588,14 @@ void CGDwelling::initObj()
 	{
 	case Obj::CREATURE_GENERATOR1:
 		{
-			int crid = VLC->objh->cregens[subID];
+			CreatureID::CreatureID crid = VLC->objh->cregens[subID];
 			const CCreature *crs = VLC->creh->creatures[crid];
 
 			creatures.resize(1);
 			creatures[0].second.push_back(crid);
 			if (subID >= VLC->generaltexth->creGens.size()) //very messy workaround
 			{
-				int faction = VLC->creh->creatures[subID]->faction;
+				TFaction faction = VLC->creh->creatures[subID]->faction;
 				assert (VLC->townh->towns[faction].dwellingNames.size());
 				hoverName = VLC->townh->towns[faction].dwellingNames[VLC->creh->creatures[subID]->level - 1];
 			}
@@ -1610,22 +1612,22 @@ void CGDwelling::initObj()
 		creatures.resize(4);
 		if(subID == 1) //Golem Factory
 		{
-			creatures[0].second.push_back(32);  //Stone Golem
-			creatures[1].second.push_back(33);  //Iron Golem
-			creatures[2].second.push_back(116); //Gold Golem
-			creatures[3].second.push_back(117); //Diamond Golem
+			creatures[0].second.push_back(CreatureID::STONE_GOLEM);
+			creatures[1].second.push_back(CreatureID::IRON_GOLEM);
+			creatures[2].second.push_back(CreatureID::GOLD_GOLEM);
+			creatures[3].second.push_back(CreatureID::DIAMOND_GOLEM);
 			//guards
-			putStack(0, new CStackInstance(116, 9));
-			putStack(1, new CStackInstance(117, 6));
+			putStack(0, new CStackInstance(CreatureID::GOLD_GOLEM, 9));
+			putStack(1, new CStackInstance(CreatureID::DIAMOND_GOLEM, 6));
 		}
 		else if(subID == 0) // Elemental Conflux
 		{
-			creatures[0].second.push_back(112); //Air Elemental
-			creatures[1].second.push_back(114); //Fire Elemental
-			creatures[2].second.push_back(113); //Earth Elemental
-			creatures[3].second.push_back(115); //Water Elemental
+			creatures[0].second.push_back(CreatureID::AIR_ELEMENTAL);
+			creatures[1].second.push_back(CreatureID::FIRE_ELEMENTAL);
+			creatures[2].second.push_back(CreatureID::EARTH_ELEMENTAL);
+			creatures[3].second.push_back(CreatureID::WATER_ELEMENTAL);
 			//guards
-			putStack(0, new CStackInstance(113, 12));
+			putStack(0, new CStackInstance(CreatureID::EARTH_ELEMENTAL, 12));
 		}
 		else
 		{
@@ -1640,9 +1642,9 @@ void CGDwelling::initObj()
 
 	case Obj::WAR_MACHINE_FACTORY:
 		creatures.resize(3);
-		creatures[0].second.push_back(146); //Ballista
-		creatures[1].second.push_back(147); //First Aid Tent
-		creatures[2].second.push_back(148); //Ammo Cart
+		creatures[0].second.push_back(CreatureID::BALLISTA);
+		creatures[1].second.push_back(CreatureID::FIRST_AID_TENT);
+		creatures[2].second.push_back(CreatureID::AMMO_CART);
 		break;
 
 	default:
@@ -1670,7 +1672,7 @@ void CGDwelling::setProperty(ui8 what, ui32 val)
 		case ObjProperty::AVAILABLE_CREATURE:
 			creatures.resize(1);
 			creatures[0].second.resize(1);
-			creatures[0].second[0] = val;
+			creatures[0].second[0] = static_cast<CreatureID::CreatureID>(val);
 			break;
 	}
 	CGObjectInstance::setProperty(what,val);
@@ -1775,7 +1777,7 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h, ui32 answer ) co
 	if(!answer)
 		return;
 
-	int crid = creatures[0].second[0];
+	CreatureID::CreatureID crid = creatures[0].second[0];
 	CCreature *crs = VLC->creh->creatures[crid];
 	TQuantity count = creatures[0].first;
 
@@ -2197,7 +2199,7 @@ void CGTownInstance::newTurn() const
 				if ((stacksCount() < GameConstants::ARMY_SIZE && rand()%100 < 25) || Slots().empty()) //add new stack
 				{
 					int i = rand() % std::min (GameConstants::ARMY_SIZE, cb->getDate(Date::MONTH)<<1);
-					TCreature c = town->creatures[i][0];
+					CreatureID::CreatureID c = town->creatures[i][0];
 					TSlot n = -1;
 
 					TQuantity count = creatureGrowth(i);
@@ -3118,7 +3120,7 @@ void CGCreature::initObj()
 		break;
 	}
 
-	stacks[0]->setType(subID);
+	stacks[0]->setType(static_cast<CreatureID::CreatureID>(subID));
 	TQuantity &amount = stacks[0]->count;
 	CCreature &c = *VLC->creh->creatures[subID];
 	if(!amount)
@@ -3336,7 +3338,7 @@ void CGCreature::fight( const CGHeroInstance *h ) const
 			TSlot slotId = (stacks.size() / 2);
 			if(ui32 upgradesSize = getStack(slotId).type->upgrades.size())
 			{
-				std::set<TCreature>::const_iterator it = getStack(slotId).type->upgrades.begin(); //pick random in case there are more
+				auto it = getStack(slotId).type->upgrades.cbegin(); //pick random in case there are more
 				std::advance (it, rand() % upgradesSize);
 				cb->changeStackType(StackLocation(this, slotId), VLC->creh->creatures[*it]);
 			}
@@ -3398,12 +3400,12 @@ void CGMine::initObj()
 	{
 		//set guardians
 		int howManyTroglodytes = 100 + ran()%100;
-		CStackInstance *troglodytes = new CStackInstance(70, howManyTroglodytes);
+		CStackInstance *troglodytes = new CStackInstance(CreatureID::TROGLODYTES, howManyTroglodytes);
 		putStack(0, troglodytes);
 
 		//after map reading tempOwner placeholds bitmask for allowed resources
 		std::vector<Res::ERes> possibleResources;
-		for (int i = 0; i < 8; i++)
+		for (int i = 0; i < GameConstants::PLAYER_LIMIT; i++)
 			if(tempOwner & 1<<i)
 				possibleResources.push_back(static_cast<Res::ERes>(i));
 
@@ -4742,7 +4744,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
 		case CREATURE:
 			{
 				CCreatureSet creatures;
-				creatures.setCreature(0, rID, rVal);
+				creatures.setCreature(0, static_cast<CreatureID::CreatureID>(rID), rVal);
 				cb->giveCreatures(this, h, creatures, false);
 			}
 			break;
@@ -4973,9 +4975,9 @@ void CGBonusingObject::onHeroVisit( const CGHeroInstance * h ) const
 
 		for (TSlots::const_iterator i = h->Slots().begin(); i != h->Slots().end(); ++i)
 		{
-			if(i->second->type->idNumber == 10)
+			if(i->second->type->idNumber == CreatureID::CAVALIER)
 			{
-				cb->changeStackType(StackLocation(h, i->first), VLC->creh->creatures[11]);
+				cb->changeStackType(StackLocation(h, i->first), VLC->creh->creatures[CreatureID::CHAMPION]);
 				someUpgradeDone = true;
 			}
 		}
@@ -5925,14 +5927,13 @@ void CBank::setPropertyDer (ui8 what, ui32 val)
 					case 1:
 						for	(int i = 0; i < 4; ++i)
 							setCreature (i, bc->guards[0].first, bc->guards[0].second  / 5 );
-						setCreature (4, bc->guards[0].first + upgraded, bc->guards[0].second  / 5 );
+						setCreature (4, static_cast<CreatureID::CreatureID>(bc->guards[0].first + upgraded), bc->guards[0].second  / 5 );
 						break;
 					case 4:
 					{
-						std::vector< std::pair <ui16, ui32> >::const_iterator it;
 						if (bc->guards.back().second) //all stacks are present
 						{
-							for (it = bc->guards.begin(); it != bc->guards.end(); it++)
+							for (auto it = bc->guards.begin(); it != bc->guards.end(); it++)
 							{
 								setCreature (stacksCount(), it->first, it->second);
 							}
@@ -5941,7 +5942,7 @@ void CBank::setPropertyDer (ui8 what, ui32 val)
 						{
 							setCreature (0, bc->guards[0].first, bc->guards[0].second  / 2 );
 							setCreature (1, bc->guards[1].first, bc->guards[1].second / 2);
-							setCreature (2, bc->guards[2].first + upgraded, bc->guards[2].second);
+							setCreature (2, static_cast<CreatureID::CreatureID>(bc->guards[2].first + upgraded), bc->guards[2].second);
 							setCreature (3, bc->guards[1].first, bc->guards[1].second / 2 );
 							setCreature (4, bc->guards[0].first, bc->guards[0].second - (bc->guards[0].second  / 2) );
 
@@ -6181,7 +6182,7 @@ void CBank::endBattle (const CGHeroInstance *h, const BattleResult *result) cons
 
 		//grant creatures
 		CCreatureSet ourArmy;
-		for (std::vector< std::pair <ui16, ui32> >::const_iterator it = bc->creatures.begin(); it != bc->creatures.end(); it++)
+		for (auto it = bc->creatures.cbegin(); it != bc->creatures.cend(); it++)
 		{
 			int slot = ourArmy.getSlotFor(it->first);
 			ourArmy.addToSlot(slot, it->first, it->second);

+ 8 - 7
lib/CObjectHandler.h

@@ -168,7 +168,8 @@ class DLL_LINKAGE CGObjectInstance : public IObjectInterface
 public:
 	mutable std::string hoverName;
 	int3 pos; //h3m pos
-	si32 ID, subID; //normal ID (this one from OH3 maps ;]) - eg. town=98; hero=34
+	Obj::Obj ID;
+	si32 subID; //normal subID (this one from OH3 maps ;])
 	si32 id;//number of object in map's vector
 	CGDefInfo * defInfo;
 	ui8 animPhaseShift;
@@ -418,7 +419,7 @@ public:
 	virtual ~CGHeroInstance();
 	//////////////////////////////////////////////////////////////////////////
 	//
-	ui8 bearerType() const override;
+	ArtBearer::ArtBearer bearerType() const override;
 	//////////////////////////////////////////////////////////////////////////
 
 	CBonusSystemNode *whereShouldBeAttached(CGameState *gs) override;
@@ -459,7 +460,7 @@ class DLL_LINKAGE CCreGenLeveledCastleInfo : public CCreGenAsCastleInfo, public
 class DLL_LINKAGE CGDwelling : public CArmedInstance
 {
 public:
-	typedef std::vector<std::pair<ui32, std::vector<ui32> > > TCreaturesSet;
+	typedef std::vector<std::pair<ui32, std::vector<CreatureID::CreatureID> > > TCreaturesSet;
 
 	CSpecObjInfo * info; //h3m info about dewlling
 	TCreaturesSet creatures; //creatures[level] -> <vector of alternative ids (base creature and upgrades, creatures amount>
@@ -731,7 +732,7 @@ public:
 	si8 character; //character of this set of creatures (0 - the most friendly, 4 - the most hostile) => on init changed to -4 (compliant) ... 10 value (savage)
 	std::string message; //message printed for attacking hero
 	TResources resources; // resources given to hero that has won with monsters
-	TArtifactID gainedArtifact; //ID of artifact gained to hero, -1 if none
+	ArtifactID::ArtifactID gainedArtifact; //ID of artifact gained to hero, -1 if none
 	bool neverFlees; //if true, the troops will never flee
 	bool notGrowingTeam; //if true, number of units won't grow
 	ui64 temppower; //used to handle fractional stack growth for tiny stacks
@@ -1372,10 +1373,10 @@ struct BankConfig
 	ui8 level; //1 - 4, how hard the battle will be
 	ui8 chance; //chance for this level being chosen
 	ui8 upgradeChance; //chance for creatures to be in upgraded versions
-	std::vector< std::pair <ui16, ui32> > guards; //creature ID, amount
+	std::vector< std::pair <CreatureID::CreatureID, ui32> > guards; //creature ID, amount
 	ui32 combatValue; //how hard are guards of this level
 	std::vector<si32> resources; //resources given in case of victory
-	std::vector< std::pair <ui16, ui32> > creatures; //creatures granted in case of victory (creature ID, amount)
+	std::vector< std::pair <CreatureID::CreatureID, ui32> > creatures; //creatures granted in case of victory (creature ID, amount)
 	std::vector<ui16> artifacts; //number of artifacts given in case of victory [0] -> treasure, [1] -> minor [2] -> major [3] -> relic
 	ui32 value; //overall value of given things
 	ui32 rewardDifficulty; //proportion of reward value to difficulty of guards; how profitable is this creature Bank config
@@ -1390,7 +1391,7 @@ struct BankConfig
 class DLL_LINKAGE CObjectHandler
 {
 public:
-	std::map<si32, si32> cregens; //type 17. dwelling subid -> creature ID
+	std::map<si32, CreatureID::CreatureID> cregens; //type 17. dwelling subid -> creature ID
 	std::map <ui32, std::vector < ConstTransitivePtr<BankConfig> > > banksInfo; //[index][preset]
 	std::map <ui32, std::string> creBanksNames; //[crebank index] -> name of this creature bank
 	std::vector<ui32> resVals; //default values of resources in gold

+ 4 - 4
lib/CTownHandler.cpp

@@ -339,7 +339,7 @@ void CTownHandler::loadSiegeScreen(CTown &town, const JsonNode & source)
 	town.clientInfo.siegePrefix = source["imagePrefix"].String();
 	VLC->modh->identifiers.requestIdentifier(std::string("creature.") + source["shooter"].String(), [&town](si32 creature)
 	{
-		town.clientInfo.siegeShooter = creature;
+		town.clientInfo.siegeShooter = static_cast<CreatureID::CreatureID>(creature);
 	});
 
 	town.clientInfo.siegeShooterCropHeight = source["shooterHeight"].Float();
@@ -418,7 +418,7 @@ void CTownHandler::loadTown(CTown &town, const JsonNode & source)
 	VLC->modh->identifiers.requestIdentifier(std::string("creature." + source["warMachine"].String()),
 	[&town](si32 creature)
 	{
-		town.warMachine = CArtHandler::convertMachineID(creature, true);
+		town.warMachine = CArtHandler::creatureToMachineID(static_cast<CreatureID::CreatureID>(creature));
 	});
 
 	town.mageLevel = source["mageGuild"].Float();
@@ -444,7 +444,7 @@ void CTownHandler::loadTown(CTown &town, const JsonNode & source)
 		{
 			VLC->modh->identifiers.requestIdentifier(std::string("creature.") + level[j].String(), [=, &town](si32 creature)
 			{
-				town.creatures[i][j] = creature;
+				town.creatures[i][j] = static_cast<CreatureID::CreatureID>(creature);
 			});
 		}
 	}
@@ -519,7 +519,7 @@ void CTownHandler::load(const JsonNode &source)
 		VLC->modh->identifiers.requestIdentifier ("creature." + node.second["commander"].String(),
 			[=](si32 commanderID)
 			{
-				factions[id].commander = commanderID;
+				factions[id].commander = static_cast<CreatureID::CreatureID>(commanderID);
 			});
 
 		faction.creatureBg120 = node.second["creatureBackground"]["120px"].String();

+ 5 - 4
lib/CTownHandler.h

@@ -90,7 +90,7 @@ public:
 
 	/// level -> list of creatures on this tier
 	// TODO: replace with pointers to CCreature
-	std::vector<std::vector<TCreature> > creatures;
+	std::vector<std::vector<CreatureID::CreatureID> > creatures;
 
 	bmap<int, ConstTransitivePtr<CBuilding> > buildings;
 
@@ -100,7 +100,8 @@ public:
 	// should be removed at least from configs in favour of auto-detection
 	std::map<int,int> hordeLvl; //[0] - first horde building creature level; [1] - second horde building (-1 if not present)
 	ui32 mageLevel; //max available mage guild level
-	ui16 primaryRes, warMachine;
+	ui16 primaryRes;
+	ArtifactID::ArtifactID warMachine;
 
 	// Client-only data. Should be moved away from lib
 	struct ClientInfo
@@ -135,7 +136,7 @@ public:
 
 		std::string siegePrefix;
 		std::vector<Point> siegePositions;
-		TCreature siegeShooter; // shooter creature ID
+		CreatureID::CreatureID siegeShooter; // shooter creature ID
 		si32 siegeShooterCropHeight; //trim height for shooters in turrets
 
 		template <typename Handler> void serialize(Handler &h, const int version)
@@ -176,7 +177,7 @@ public:
 	ETerrainType::ETerrainType nativeTerrain;
 	EAlignment::EAlignment alignment;
 
-	TCreature commander;
+	CreatureID::CreatureID commander;
 
 	std::string creatureBg120;
 	std::string creatureBg130;

+ 34 - 21
lib/Connection.h

@@ -303,13 +303,13 @@ struct SerializationLevel
 	static const int value = SerializationLevel::type::value;
 };
 
-template <typename T>
+template <typename T, typename U>
 struct VectorisedObjectInfo
 {
 	const std::vector<ConstTransitivePtr<T> > *vector;	//pointer to the appropriate vector
-	const si32 T::*idPtr;			//pointer to the field representing the position in the vector
+	const U T::*idPtr;			//pointer to the field representing the position in the vector
 
-	VectorisedObjectInfo(const std::vector< ConstTransitivePtr<T> > *Vector, const si32 T::*IdPtr)
+	VectorisedObjectInfo(const std::vector< ConstTransitivePtr<T> > *Vector, const U T::*IdPtr)
 		:vector(Vector), idPtr(IdPtr)
 	{
 	}
@@ -330,19 +330,19 @@ public:
 
 	virtual void reportState(CLogger &out){};
 
-	template <typename T>
-	void registerVectoredType(const std::vector<T*> *Vector, const si32 T::*IdPtr)
+	template <typename T, typename U>
+	void registerVectoredType(const std::vector<T*> *Vector, const U T::*IdPtr)
 	{
-		vectors[&typeid(T)] = VectorisedObjectInfo<T>(Vector, IdPtr);
+		vectors[&typeid(T)] = VectorisedObjectInfo<T, U>(Vector, IdPtr);
 	}
-	template <typename T>
-	void registerVectoredType(const std::vector<ConstTransitivePtr<T> > *Vector, const si32 T::*IdPtr)
+	template <typename T, typename U>
+	void registerVectoredType(const std::vector<ConstTransitivePtr<T> > *Vector, const U T::*IdPtr)
 	{
-		vectors[&typeid(T)] = VectorisedObjectInfo<T>(Vector, IdPtr);
+		vectors[&typeid(T)] = VectorisedObjectInfo<T, U>(Vector, IdPtr);
 	}
 
-	template <typename T>
-	const VectorisedObjectInfo<T> *getVectorisedTypeInfo()
+	template <typename T, typename U>
+	const VectorisedObjectInfo<T, U> *getVectorisedTypeInfo()
 	{
 		const std::type_info *myType = NULL;
 //
@@ -357,14 +357,14 @@ public:
 		else
 		{
 			assert(!i->second.empty());
-			assert(i->second.type() == typeid(VectorisedObjectInfo<T>));
-			VectorisedObjectInfo<T> *ret = &(boost::any_cast<VectorisedObjectInfo<T>&>(i->second));
+			assert(i->second.type() == typeid(VectorisedObjectInfo<T, U>));
+			VectorisedObjectInfo<T, U> *ret = &(boost::any_cast<VectorisedObjectInfo<T, U>&>(i->second));
 			return ret;
 		}
 	}
 
-	template <typename T>
-	T* getVectorItemFromId(const VectorisedObjectInfo<T> &oInfo, ui32 id) const
+	template <typename T, typename U>
+	T* getVectorItemFromId(const VectorisedObjectInfo<T, U> &oInfo, U id) const
 	{
 	/*	if(id < 0)
 			return NULL;*/
@@ -374,11 +374,11 @@ public:
 		return const_cast<T*>((*oInfo.vector)[id].get());
 	}
 
-	template <typename T>
-	si32 getIdFromVectorItem(const VectorisedObjectInfo<T> &oInfo, const T* obj) const
+	template <typename T, typename U>
+	U getIdFromVectorItem(const VectorisedObjectInfo<T, U> &oInfo, const T* obj) const
 	{
 		if(!obj)
-			return -1;
+			return static_cast<U>(-1);
 
 		return obj->*oInfo.idPtr;
 	}
@@ -421,6 +421,17 @@ struct VectorisedTypeFor
 		mpl::identity<T>
 		>::type type;
 };
+template <typename U>
+struct VectorizedIDType
+{
+	typedef typename
+		//if
+		mpl::eval_if<boost::is_same<CArtifact,U>,
+		mpl::identity<ArtifactID::ArtifactID>,
+		//else
+		mpl::identity<si32>
+		>::type type;
+};
 
 template <typename Handler>
 struct VariantVisitorSaver : boost::static_visitor<>
@@ -568,7 +579,8 @@ public:
 		{
 			typedef typename boost::remove_const<typename boost::remove_pointer<T>::type>::type TObjectType;
 			typedef typename VectorisedTypeFor<TObjectType>::type VType;
- 			if(const VectorisedObjectInfo<VType> *info = getVectorisedTypeInfo<VType>())
+			typedef typename VectorizedIDType<TObjectType>::type IDType;
+ 			if(const auto *info = getVectorisedTypeInfo<VType, IDType>())
  			{
 				si32 id = getIdFromVectorItem<VType>(*info, data);
 				*this << id;
@@ -942,13 +954,14 @@ public:
 		{
 			typedef typename boost::remove_const<typename boost::remove_pointer<T>::type>::type TObjectType; //eg: const CGHeroInstance * => CGHeroInstance
 			typedef typename VectorisedTypeFor<TObjectType>::type VType;									 //eg: CGHeroInstance -> CGobjectInstance
-			if(const VectorisedObjectInfo<VType> *info = getVectorisedTypeInfo<VType>())
+			typedef typename VectorizedIDType<TObjectType>::type IDType;
+			if(const auto *info = getVectorisedTypeInfo<VType, IDType>())
 			{
 				si32 id;
 				*this >> id;
 				if(id != -1)
 				{
-					data = static_cast<T>(getVectorItemFromId(*info, id));
+					data = static_cast<T>(getVectorItemFromId<VType, IDType>(*info, static_cast<IDType>(id)));
 					return;
 				}
 			}

+ 55 - 2
lib/GameConstants.h

@@ -265,6 +265,7 @@ namespace Obj
 {
 	enum Obj
 	{
+		NO_OBJ = -1,
 		ALTAR_OF_SACRIFICE = 2,
 		ANCHOR_POINT = 3,
 		ARENA = 4,
@@ -498,6 +499,60 @@ namespace ArtifactPosition
 	};
 }
 
+namespace ArtifactID
+{
+	enum ArtifactID
+	{
+		NONE = -1,
+		SPELLBOOK = 0,
+		SPELL_SCROLL = 1,
+		GRAIL = 2,
+		CATAPULT = 3,
+		BALLISTA = 4,
+		AMMO_CART = 5,
+		FIRST_AID_TENT = 6,
+		CENTAUR_AXE = 7,
+		BLACKSHARD_OF_THE_DEAD_KNIGHT = 8,
+		CORNUCOPIA = 140,
+		ART_LOCK = 145,
+		AXE_OF_SMASHING = 146,
+		MITHRIL_MAIL = 147,
+		SWORD_OF_SHARPNESS = 148,
+		HELM_OF_IMMORTALITY = 149,
+		PENDANT_OF_SORCERY = 150,
+		BOOTS_OF_HASTE = 151,
+		BOW_OF_SEEKING = 152,
+		DRAGON_EYE_RING = 153,
+		HARDENED_SHIELD = 154,
+		SLAVAS_RING_OF_POWER = 155
+	};
+}
+
+namespace CreatureID
+{
+	enum CreatureID
+	{
+		NONE = -1,
+		CAVALIER = 10,
+		CHAMPION = 11,
+		STONE_GOLEM = 32,
+		IRON_GOLEM = 33,
+		IMP = 42,
+		TROGLODYTES = 70,
+		AIR_ELEMENTAL = 112,
+		EARTH_ELEMENTAL = 113,
+		FIRE_ELEMENTAL = 114,
+		WATER_ELEMENTAL = 115,
+		GOLD_GOLEM = 116,
+		DIAMOND_GOLEM = 117,
+		CATAPULT = 145,
+		BALLISTA = 146,
+		FIRST_AID_TENT = 147,
+		AMMO_CART = 148,
+		ARROW_TOWERS = 149
+	};
+}
+
 // Typedef declarations
 typedef si8 TFaction;
 typedef si64 TExpType;
@@ -507,7 +562,5 @@ typedef ui8 TBonusType;
 typedef si32 TBonusSubtype;
 typedef si32 TSlot;
 typedef si32 TQuantity;
-typedef si32 TArtifactID;
 typedef si32 TArtifactInstanceID;
-typedef ui32 TCreature; //creature id
 typedef ui8 TPlayerColor;

+ 1 - 1
lib/HeroBonus.cpp

@@ -1356,7 +1356,7 @@ CCreatureTypeLimiter::CCreatureTypeLimiter()
 	includeUpgrades = false;
 }
 
-void CCreatureTypeLimiter::setCreature (TCreature id)
+void CCreatureTypeLimiter::setCreature (CreatureID::CreatureID id)
 {
 	creature = VLC->creh->creatures[id];
 }

+ 1 - 1
lib/HeroBonus.h

@@ -766,7 +766,7 @@ public:
 
 	CCreatureTypeLimiter();
 	CCreatureTypeLimiter(const CCreature &Creature, bool IncludeUpgrades = true);
-	void setCreature (TCreature id);
+	void setCreature (CreatureID::CreatureID id);
 
 	int limit(const BonusLimitationContext &context) const OVERRIDE;
 

+ 2 - 2
lib/IGameCallback.cpp

@@ -933,7 +933,7 @@ void IGameEventRealizer::setObjProperty(int objid, int prop, si64 val)
 	commitPackage(&sob);
 }
 
-const CGObjectInstance * IGameCallback::putNewObject(int ID, int subID, int3 pos)
+const CGObjectInstance * IGameCallback::putNewObject(Obj::Obj ID, int subID, int3 pos)
 {
 	NewObject no;
 	no.ID = ID; //creature
@@ -945,7 +945,7 @@ const CGObjectInstance * IGameCallback::putNewObject(int ID, int subID, int3 pos
 
 const CGCreature * IGameCallback::putNewMonster(int creID, int count, int3 pos)
 {
-	const CGObjectInstance *m = putNewObject(54, creID, pos);
+	const CGObjectInstance *m = putNewObject(Obj::MONSTER, creID, pos);
 	setObjProperty(m->id, ObjProperty::MONSTER_COUNT, count);
 	setObjProperty(m->id, ObjProperty::MONSTER_POWER, (si64)1000*count);
 	return dynamic_cast<const CGCreature*>(m);

+ 1 - 1
lib/IGameCallback.h

@@ -258,7 +258,7 @@ public:
 	virtual ~IGameCallback(){};
 
 	//do sth
-	const CGObjectInstance *putNewObject(int ID, int subID, int3 pos);
+	const CGObjectInstance *putNewObject(Obj::Obj ID, int subID, int3 pos);
 	const CGCreature *putNewMonster(int creID, int count, int3 pos);
 
 	friend struct CPack;

+ 1 - 1
lib/JsonNode.cpp

@@ -1055,7 +1055,7 @@ Bonus * JsonUtils::parseBonus (const JsonNode &ability)
 							const JsonVector vec = limiter["parameters"].Vector();
 							VLC->modh->identifiers.requestIdentifier(std::string("creature.") + vec[0].String(), [=](si32 creature)
 							{
-								l2->setCreature (creature);
+								l2->setCreature (static_cast<CreatureID::CreatureID>(creature));
 							});
 							if (vec.size() > 1)
 							{

+ 9 - 9
lib/Mapping/MapFormatH3M.cpp

@@ -747,7 +747,7 @@ void CMapLoaderH3M::readDefInfo()
 
 		defInfo->terrainAllowed = reader.readUInt16();
 		defInfo->terrainMenu = reader.readUInt16();
-		defInfo->id = reader.readUInt32();
+		defInfo->id = static_cast<Obj::Obj>(reader.readUInt32());
 		defInfo->subid = reader.readUInt32();
 		defInfo->type = reader.readUInt8();
 		defInfo->printPriority = reader.readUInt8();
@@ -984,22 +984,22 @@ void CMapLoaderH3M::readObjects()
 					{
 						if(artID != 0xff)
 						{
-							cre->gainedArtifact = artID;
+							cre->gainedArtifact = static_cast<ArtifactID::ArtifactID>(artID);
 						}
 						else
 						{
-							cre->gainedArtifact = -1;
+							cre->gainedArtifact = ArtifactID::NONE;
 						}
 					}
 					else
 					{
 						if(artID != 0xffff)
 						{
-							cre->gainedArtifact = artID;
+							cre->gainedArtifact = static_cast<ArtifactID::ArtifactID>(artID);
 						}
 						else
 						{
-							cre->gainedArtifact = -1;
+							cre->gainedArtifact = ArtifactID::NONE;
 						}
 					}
 				}
@@ -1476,16 +1476,16 @@ void CMapLoaderH3M::readCreatureSet(CCreatureSet * out, int number)
 
 	for(int ir = 0; ir < number; ++ir)
 	{
-		int creID;
+		CreatureID::CreatureID creID;
 		int count;
 
 		if (version)
 		{
-			creID = reader.readUInt16();
+			creID = static_cast<CreatureID::CreatureID>(reader.readUInt16());
 		}
 		else
 		{
-			creID = reader.readUInt8();
+			creID = static_cast<CreatureID::CreatureID>(reader.readUInt8());
 		}
 		count = reader.readUInt16();
 
@@ -1498,7 +1498,7 @@ void CMapLoaderH3M::readCreatureSet(CCreatureSet * out, int number)
 		if(creID > maxID - 0xf)
 		{
 			//this will happen when random object has random army
-			creID = maxID + 1 - creID + VLC->creh->creatures.size();
+			creID = static_cast<CreatureID::CreatureID>(maxID + 1 - creID + VLC->creh->creatures.size());
 			hlp->idRand = creID;
 		}
 		else

+ 15 - 12
lib/NetPacks.h

@@ -151,7 +151,7 @@ public:
 		message.push_back(TREPLACE_PLUSNUMBER);
 		numbers.push_back(txt);
 	}
-	DLL_LINKAGE void addCreReplacement(TCreature id, TQuantity count); //adds sing or plural name;
+	DLL_LINKAGE void addCreReplacement(CreatureID::CreatureID id, TQuantity count); //adds sing or plural name;
 	DLL_LINKAGE void addReplacement(const CStackBasicDescriptor &stack); //adds sing or plural name;
 	DLL_LINKAGE std::string buildList () const;
 	void clear()
@@ -664,7 +664,7 @@ struct SetAvailableCreatures : public CPackForClient //506
 	DLL_LINKAGE void applyGs(CGameState *gs);
 
 	si32 tid;
-	std::vector<std::pair<ui32, std::vector<ui32> > > creatures;
+	std::vector<std::pair<ui32, std::vector<CreatureID::CreatureID> > > creatures;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -763,7 +763,8 @@ struct NewObject  : public CPackForClient //518
 	void applyCl(CClient *cl);
 	DLL_LINKAGE void applyGs(CGameState *gs);
 
-	ui32 ID, subID;
+	Obj::Obj ID;
+	ui32 subID;
 	int3 pos;
 
 	int id; //used locally, filled during applyGs
@@ -1065,7 +1066,7 @@ struct NewTurn : public CPackForClient //101
 	ui32 day;
 	bool resetBuilded;
 	ui8 specialWeek; //weekType
-	TCreature creatureid; //for creature weeks
+	CreatureID::CreatureID creatureid; //for creature weeks
 
 	NewTurn(){type = 101;};
 
@@ -1512,7 +1513,7 @@ struct BattleSpellCast : public CPackForClient//3009
 	BattleHex tile; //destination tile (may not be set in some global/mass spells
 	std::vector<ui32> resisted; //ids of creatures that resisted this spell
 	std::set<ui32> affectedCres; //ids of creatures affected by this spell, generally used if spell does not set any effect (like dispel or cure)
-	TCreature attackerType;//id of caster to generate console message; -1 if not set (eg. spell casted by artifact)
+	CreatureID::CreatureID attackerType;//id of caster to generate console message; -1 if not set (eg. spell casted by artifact)
 	bool castedByHero; //if true - spell has been casted by hero, otherwise by a creature
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -1618,7 +1619,7 @@ struct BattleStackAdded : public CPackForClient //3017
 	void applyCl(CClient *cl);
 
 	int attacker; // if true, stack belongs to attacker
-	int creID;
+	CreatureID::CreatureID creID;
 	int amount;
 	int pos;
 	int summoned; //if true, remove it afterwards
@@ -1846,9 +1847,10 @@ struct RazeStructure : public BuildStructure
 struct RecruitCreatures : public CPackForServer
 {
 	RecruitCreatures(){};
-	RecruitCreatures(si32 TID, si32 CRID, si32 Amount, si32 Level):tid(TID),crid(CRID),amount(Amount),level(Level){};
+	RecruitCreatures(si32 TID, CreatureID::CreatureID CRID, si32 Amount, si32 Level):tid(TID),crid(CRID),amount(Amount),level(Level){};
 	si32 tid; //town id
-	ui32 crid, amount;//creature ID and amount
+	CreatureID::CreatureID crid;
+	ui32 amount;//creature amount
 	si32 level;//dwelling level to buy from, -1 if any
 	bool applyGh(CGameHandler *gh);
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -1860,10 +1862,10 @@ struct RecruitCreatures : public CPackForServer
 struct UpgradeCreature : public CPackForServer
 {
 	UpgradeCreature(){};
-	UpgradeCreature(ui8 Pos, si32 ID, si32 CRID):pos(Pos),id(ID), cid(CRID){};
+	UpgradeCreature(ui8 Pos, si32 ID, CreatureID::CreatureID CRID):pos(Pos),id(ID), cid(CRID){};
 	ui8 pos; //stack pos
 	si32 id; //object id
-	si32 cid; //id of type to which we want make upgrade
+	CreatureID::CreatureID cid; //id of type to which we want make upgrade
 
 	bool applyGh(CGameHandler *gh);
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -1918,8 +1920,9 @@ struct AssembleArtifacts : public CPackForServer
 struct BuyArtifact : public CPackForServer
 {
 	BuyArtifact(){};
-	BuyArtifact(si32 HID, si32 AID):hid(HID),aid(AID){};
-	si32 hid, aid; //hero and artifact id
+	BuyArtifact(si32 HID, ArtifactID::ArtifactID AID):hid(HID),aid(AID){};
+	si32 hid;
+	ArtifactID::ArtifactID aid;
 
 	bool applyGh(CGameHandler *gh);
 	template <typename Handler> void serialize(Handler &h, const int version)

+ 3 - 3
lib/NetPacksLib.cpp

@@ -535,9 +535,9 @@ DLL_LINKAGE void NewObject::applyGs( CGameState *gs )
 			//cre->slots[0] = hlp;
 			cre->notGrowingTeam = cre->neverFlees = 0;
 			cre->character = 2;
-			cre->gainedArtifact = -1;
+			cre->gainedArtifact = ArtifactID::NONE;
 			cre->identifier = -1;
-			cre->addToSlot(0, new CStackInstance(subID, -1)); //add placeholder stack
+			cre->addToSlot(0, new CStackInstance(static_cast<CreatureID::CreatureID>(subID), -1)); //add placeholder stack
 		}
 		break;
 	default:
@@ -1151,7 +1151,7 @@ DLL_LINKAGE void BattleAttack::applyGs( CGameState *gs )
 		bool hasAmmoCart = false;
 		BOOST_FOREACH(const CStack * st, gs->curB->stacks)
 		{
-			if(st->owner == attacker->owner && st->getCreature()->idNumber == 148 && st->alive())
+			if(st->owner == attacker->owner && st->getCreature()->idNumber == CreatureID::AMMO_CART && st->alive())
 			{
 				hasAmmoCart = true;
 				break;

+ 20 - 20
server/CGameHandler.cpp

@@ -1144,7 +1144,7 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa
 
 			ui32 dwellpos = rand()%dwellings.size();//take random dwelling
 			ui32 creapos = rand()%dwellings[dwellpos]->creatures.size();//for multi-creature dwellings like Golem Factory
-			ui32 creature = dwellings[dwellpos]->creatures[creapos].second[0];
+			CreatureID::CreatureID creature = dwellings[dwellpos]->creatures[creapos].second[0];
 
 			if (clear)
 				ssi.creatures[GameConstants::CREATURES_PER_TOWN].first = std::max((ui32)1, (VLC->creh->creatures[creature]->growth)/2);
@@ -1160,7 +1160,7 @@ void CGameHandler::newTurn()
 	tlog5 << "Turn " << gs->day+1 << std::endl;
 	NewTurn n;
 	n.specialWeek = NewTurn::NO_ACTION;
-	n.creatureid = -1;
+	n.creatureid = CreatureID::NONE;
 	n.day = gs->day + 1;
 
 	bool firstTurn = !getDate(Date::DAY);
@@ -1197,7 +1197,7 @@ void CGameHandler::newTurn()
 		if(deityOfFireBuilt)
 		{
 			n.specialWeek = NewTurn::DEITYOFFIRE;
-			n.creatureid = 42;
+			n.creatureid = CreatureID::IMP;
 		}
 		else
 		{
@@ -1209,12 +1209,12 @@ void CGameHandler::newTurn()
 					n.specialWeek = NewTurn::DOUBLE_GROWTH;
 					if (VLC->modh->settings.ALL_CREATURES_GET_DOUBLE_MONTHS)
 					{
-						std::pair<int,int> newMonster(54, VLC->creh->pickRandomMonster(boost::ref(rand)));
+						std::pair<int,CreatureID::CreatureID> newMonster(54, VLC->creh->pickRandomMonster(boost::ref(rand)));
 						n.creatureid = newMonster.second;
 					}
 					else
 					{
-						std::set<TCreature>::const_iterator it = VLC->creh->doubledCreatures.begin();
+						auto it = VLC->creh->doubledCreatures.cbegin();
 						std::advance (it, rand() % VLC->creh->doubledCreatures.size()); //picking random element of set is tiring
 						n.creatureid = *it;
 					}
@@ -1227,7 +1227,7 @@ void CGameHandler::newTurn()
 				if (monthType < 25)
 				{
 					n.specialWeek = NewTurn::BONUS_GROWTH; //+5
-					std::pair<int,int> newMonster (54, VLC->creh->pickRandomMonster(boost::ref(rand)));
+					std::pair<int, CreatureID::CreatureID> newMonster (54, VLC->creh->pickRandomMonster(boost::ref(rand)));
 					//TODO do not pick neutrals
 					n.creatureid = newMonster.second;
 				}
@@ -2609,7 +2609,7 @@ void CGameHandler::sendMessageToAll( const std::string &message )
 	sendToAllClients(&sm);
 }
 
-bool CGameHandler::recruitCreatures( si32 objid, ui32 crid, ui32 cram, si32 fromLvl )
+bool CGameHandler::recruitCreatures( si32 objid, CreatureID::CreatureID crid, ui32 cram, si32 fromLvl )
 {
 	const CGDwelling *dw = static_cast<CGDwelling*>(gs->map->objects[objid].get());
 	const CArmedInstance *dst = NULL;
@@ -2637,7 +2637,7 @@ bool CGameHandler::recruitCreatures( si32 objid, ui32 crid, ui32 cram, si32 from
 	{
 		if ( (fromLvl != -1) && ( level !=fromLvl ) )
 			continue;
-		const std::pair<ui32, std::vector<ui32> > &cur = dw->creatures[level]; //current level info <amount, list of cr. ids>
+		const auto &cur = dw->creatures[level]; //current level info <amount, list of cr. ids>
 		int i = 0;
 		for(; i < cur.second.size(); i++) //look for crid among available creatures list on current level
 			if(cur.second[i] == crid)
@@ -2928,7 +2928,7 @@ bool CGameHandler::assembleArtifacts (si32 heroID, ArtifactPosition::ArtifactPos
 	return false;
 }
 
-bool CGameHandler::buyArtifact( ui32 hid, TArtifactID aid )
+bool CGameHandler::buyArtifact( ui32 hid, ArtifactID::ArtifactID aid )
 {
 	CGHeroInstance *hero = gs->getHero(hid);
 	CGTownInstance *town = hero->visitedTown;
@@ -2968,7 +2968,7 @@ bool CGameHandler::buyArtifact( ui32 hid, TArtifactID aid )
 	return false;
 }
 
-bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, Res::ERes rid, TArtifactID aid)
+bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, Res::ERes rid, ArtifactID::ArtifactID aid)
 {
 	if(!vstd::contains(m->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT), aid))
 		COMPLAIN_RET("That artifact is unavailable!");
@@ -3703,7 +3703,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 			BattleStackAdded bsa;
 			bsa.attacker = summoner->attackerOwned;
 
-			bsa.creID = summoner->getBonusLocalFirst(Selector::type(Bonus::DAEMON_SUMMONING))->subtype; //in case summoner can summon more than one type of monsters... scream!
+			bsa.creID = static_cast<CreatureID::CreatureID>(summoner->getBonusLocalFirst(Selector::type(Bonus::DAEMON_SUMMONING))->subtype); //in case summoner can summon more than one type of monsters... scream!
 			ui64 risedHp = summoner->count * summoner->valOfBonuses(Bonus::DAEMON_SUMMONING, bsa.creID);
 			bsa.amount = std::min ((ui32)(risedHp / VLC->creh->creatures[bsa.creID]->MaxHealth()), destStack->baseAmount);
 
@@ -3975,7 +3975,7 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex dest
 	sc.tile = destination;
 	sc.dmgToDisplay = 0;
 	sc.castedByHero = (bool)caster;
-	sc.attackerType = (stack ? stack->type->idNumber : -1);
+	sc.attackerType = (stack ? stack->type->idNumber : CreatureID::NONE);
 	sc.manaGained = 0;
 	sc.spellCost = 0;
 
@@ -4268,20 +4268,20 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex dest
 	case Spells::SUMMON_WATER_ELEMENTAL:
 	case Spells::SUMMON_AIR_ELEMENTAL:
 		{ //elemental summoning
-			int creID;
+			CreatureID::CreatureID creID;
 			switch(spellID)
 			{
 				case Spells::SUMMON_FIRE_ELEMENTAL:
-					creID = 114;
+					creID = CreatureID::FIRE_ELEMENTAL;
 					break;
 				case Spells::SUMMON_EARTH_ELEMENTAL:
-					creID = 113;
+					creID = CreatureID::EARTH_ELEMENTAL;
 					break;
 				case Spells::SUMMON_WATER_ELEMENTAL:
-					creID = 115;
+					creID = CreatureID::WATER_ELEMENTAL;
 					break;
 				case Spells::SUMMON_AIR_ELEMENTAL:
-					creID = 112;
+					creID = CreatureID::AIR_ELEMENTAL;
 					break;
 			}
 
@@ -5093,7 +5093,7 @@ void CGameHandler::checkLossVictory( TPlayerColor player )
 	}
 }
 
-void CGameHandler::getLossVicMessage( ui8 player, si8 standard, bool victory, InfoWindow &out ) const
+void CGameHandler::getLossVicMessage( TPlayerColor player, si8 standard, bool victory, InfoWindow &out ) const
 {
 //	const PlayerState *p = gs->getPlayer(player);
 // 	if(!p->human)
@@ -5442,7 +5442,7 @@ bool CGameHandler::castSpell(const CGHeroInstance *h, int spellID, const int3 &p
 			else //create boat
 			{
 				NewObject no;
-				no.ID = 8;
+				no.ID = Obj::BOAT;
 				no.subID = h->getBoatType();
 				no.pos = summonPos + int3(1,0,0);;
 				sendAndApply(&no);
@@ -6136,7 +6136,7 @@ void CGameHandler::commitPackage( CPackForClient *pack )
 	sendAndApply(pack);
 }
 
-void CGameHandler::spawnWanderingMonsters(int creatureID)
+void CGameHandler::spawnWanderingMonsters(CreatureID::CreatureID creatureID)
 {
 	std::vector<int3>::iterator tile;
 	std::vector<int3> tiles;

+ 7 - 7
server/CGameHandler.h

@@ -109,7 +109,7 @@ public:
 	void runBattle();
 	void checkLossVictory(TPlayerColor player);
 	void winLoseHandle(ui8 players=255); //players: bit field - colours of players to be checked; default: all
-	void getLossVicMessage(ui8 player, si8 standard, bool victory, InfoWindow &out) const;
+	void getLossVicMessage(TPlayerColor player, si8 standard, bool victory, InfoWindow &out) const;
 
 	////used only in endBattle - don't touch elsewhere
 	boost::function<void(BattleResult*)> * battleEndCallback;
@@ -214,14 +214,14 @@ public:
 	bool sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, ui32 slot, Res::ERes resourceID);
 	bool transformInUndead(const IMarket *market, const CGHeroInstance * hero, ui32 slot);
 	bool assembleArtifacts (si32 heroID, ArtifactPosition::ArtifactPosition artifactSlot, bool assemble, ui32 assembleTo);
-	bool buyArtifact( ui32 hid, TArtifactID aid ); //for blacksmith and mage guild only -> buying for gold in common buildings
-	bool buyArtifact( const IMarket *m, const CGHeroInstance *h, Res::ERes rid, TArtifactID aid); //for artifact merchant and black market -> buying for any resource in special building / advobject
+	bool buyArtifact( ui32 hid, ArtifactID::ArtifactID aid ); //for blacksmith and mage guild only -> buying for gold in common buildings
+	bool buyArtifact( const IMarket *m, const CGHeroInstance *h, Res::ERes rid, ArtifactID::ArtifactID aid); //for artifact merchant and black market -> buying for any resource in special building / advobject
 	bool sellArtifact( const IMarket *m, const CGHeroInstance *h, TArtifactInstanceID aid, Res::ERes rid); //for artifact merchant selling
 	//void lootArtifacts (TArtHolder source, TArtHolder dest, std::vector<ui32> &arts); //after battle - move al arts to winer
 	bool buySecSkill( const IMarket *m, const CGHeroInstance *h, SecondarySkill::SecondarySkill skill);
 	bool garrisonSwap(si32 tid);
 	bool upgradeCreature( ui32 objid, ui8 pos, ui32 upgID );
-	bool recruitCreatures(si32 objid, ui32 crid, ui32 cram, si32 level);
+	bool recruitCreatures(si32 objid, CreatureID::CreatureID crid, ui32 cram, si32 level);
 	bool buildStructure(si32 tid, si32 bid, bool force=false);//force - for events: no cost, no checkings
 	bool razeStructure(si32 tid, si32 bid);
 	bool disbandCreature( si32 id, ui8 pos );
@@ -232,7 +232,7 @@ public:
 	void handleTownEvents(CGTownInstance *town, NewTurn &n, std::map<si32, 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( ui8 player );
+	void engageIntoBattle( TPlayerColor player );
 	bool dig(const CGHeroInstance *h);
 	bool castSpell(const CGHeroInstance *h, int spellID, const int3 &pos);
 	void moveArmy(const CArmedInstance *src, const CArmedInstance *dst, bool allowMerging);
@@ -242,7 +242,7 @@ public:
 		h & QID & states;
 	}
 
-	ui32 getQueryResult(ui8 player, int queryID);
+	ui32 getQueryResult(TPlayerColor player, int queryID);
 	void sendMessageToAll(const std::string &message);
 	void sendMessageTo(CConnection &c, const std::string &message);
 	void applyAndAsk(Query * sel, ui8 player, boost::function<void(ui32)> &callback);
@@ -262,7 +262,7 @@ public:
 	void handleAfterAttackCasting (const BattleAttack & bat);
 	void attackCasting(const BattleAttack & bat, Bonus::BonusType attackMode, const CStack * attacker);
 	bool sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, ArtifactPosition::ArtifactPosition slot);
-	void spawnWanderingMonsters(int creatureID);
+	void spawnWanderingMonsters(CreatureID::CreatureID creatureID);
 	friend class CVCMIServer;
 	friend class CScriptCallback;
 };

+ 2 - 2
server/NetPacksServer.cpp

@@ -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<Res::ERes>(r2));
+		return gh->sendResources(val, player, static_cast<Res::ERes>(r1), static_cast<TPlayerColor>(r2));
 	case EMarketMode::CREATURE_RESOURCE:
 		if(!hero)
 			COMPLAIN_AND_RETURN("Only hero can sell creatures!");
@@ -184,7 +184,7 @@ bool TradeOnMarketplace::applyGh( CGameHandler *gh )
 	case EMarketMode::RESOURCE_ARTIFACT:
 		if(!hero)
 			COMPLAIN_AND_RETURN("Only hero can buy artifacts!");
-		return gh->buyArtifact(m, hero, static_cast<Res::ERes>(r1), static_cast<Res::ERes>(r2));
+		return gh->buyArtifact(m, hero, static_cast<Res::ERes>(r1), static_cast<ArtifactID::ArtifactID>(r2));
 	case EMarketMode::ARTIFACT_RESOURCE:
 		if(!hero)
 			COMPLAIN_AND_RETURN("Only hero can sell artifacts!");