Quellcode durchsuchen

Merge pull request #2624 from IvanSavenko/identifiers_cleanup

Identifiers system refactoring and cleanup
Ivan Savenko vor 2 Jahren
Ursprung
Commit
4500e59713
100 geänderte Dateien mit 352 neuen und 1872 gelöschten Zeilen
  1. 1 1
      AI/BattleAI/BattleExchangeVariant.cpp
  2. 1 1
      AI/EmptyAI/CEmptyAI.cpp
  3. 1 1
      AI/EmptyAI/CEmptyAI.h
  4. 6 6
      AI/Nullkiller/AIGateway.cpp
  5. 2 2
      AI/Nullkiller/AIGateway.h
  6. 2 2
      AI/Nullkiller/AIUtility.cpp
  7. 2 2
      AI/Nullkiller/AIUtility.h
  8. 2 2
      AI/Nullkiller/Analyzers/ArmyManager.cpp
  9. 2 2
      AI/Nullkiller/Analyzers/BuildAnalyzer.cpp
  10. 4 4
      AI/Nullkiller/Engine/PriorityEvaluator.cpp
  11. 1 1
      AI/Nullkiller/Goals/AbstractGoal.cpp
  12. 1 1
      AI/Nullkiller/Goals/BuildThis.cpp
  13. 1 1
      AI/Nullkiller/Goals/BuyArmy.cpp
  14. 1 1
      AI/Nullkiller/Goals/Composition.cpp
  15. 1 1
      AI/Nullkiller/Goals/RecruitHero.cpp
  16. 1 1
      AI/VCAI/AIUtility.cpp
  17. 1 1
      AI/VCAI/AIUtility.h
  18. 2 2
      AI/VCAI/ArmyManager.cpp
  19. 3 3
      AI/VCAI/BuildingManager.cpp
  20. 1 1
      AI/VCAI/Goals/AbstractGoal.cpp
  21. 1 1
      AI/VCAI/Goals/Build.cpp
  22. 1 1
      AI/VCAI/Goals/BuildThis.cpp
  23. 3 3
      AI/VCAI/Goals/CollectRes.cpp
  24. 1 1
      AI/VCAI/Goals/Conquer.cpp
  25. 1 1
      AI/VCAI/Goals/Explore.cpp
  26. 3 3
      AI/VCAI/Goals/FindObj.cpp
  27. 1 1
      AI/VCAI/Goals/GatherArmy.cpp
  28. 2 2
      AI/VCAI/Goals/GatherTroops.cpp
  29. 1 1
      AI/VCAI/Goals/RecruitHero.cpp
  30. 1 1
      AI/VCAI/Goals/VisitObj.cpp
  31. 1 1
      AI/VCAI/Goals/VisitTile.cpp
  32. 1 1
      AI/VCAI/Goals/Win.cpp
  33. 8 8
      AI/VCAI/VCAI.cpp
  34. 2 2
      AI/VCAI/VCAI.h
  35. 3 3
      CCallback.cpp
  36. 4 4
      CCallback.h
  37. 1 1
      client/CMusicHandler.cpp
  38. 5 5
      client/CPlayerInterface.cpp
  39. 2 2
      client/CPlayerInterface.h
  40. 1 1
      client/Client.h
  41. 1 1
      client/ClientCommandManager.cpp
  42. 1 1
      client/adventureMap/AdventureMapInterface.cpp
  43. 1 1
      client/adventureMap/AdventureMapWidget.cpp
  44. 0 5
      client/adventureMap/CResDataBar.h
  45. 4 8
      client/battle/BattleSiegeController.cpp
  46. 2 2
      client/battle/BattleWindow.cpp
  47. 27 27
      client/lobby/OptionsTab.cpp
  48. 1 1
      client/widgets/CArtifactsOfHeroBackpack.cpp
  49. 3 3
      client/widgets/CArtifactsOfHeroBase.cpp
  50. 1 1
      client/widgets/CGarrisonInt.cpp
  51. 14 12
      client/windows/CCastleInterface.cpp
  52. 5 5
      client/windows/CCastleInterface.h
  53. 1 1
      client/windows/CHeroWindow.cpp
  54. 1 1
      client/windows/CKingdomInterface.cpp
  55. 6 6
      client/windows/CTradeWindow.cpp
  56. 7 7
      client/windows/CTradeWindow.h
  57. 5 5
      client/windows/GUIClasses.cpp
  58. 1 1
      client/windows/GUIClasses.h
  59. 7 2
      cmake_modules/VCMI_lib.cmake
  60. 2 2
      include/vcmi/Creature.h
  61. 3 4
      include/vcmi/Entity.h
  62. 3 3
      include/vcmi/Faction.h
  63. 4 8
      include/vcmi/FactionMember.h
  64. 3 3
      include/vcmi/spells/Spell.h
  65. 12 12
      lib/ArtifactUtils.cpp
  66. 3 3
      lib/ArtifactUtils.h
  67. 5 5
      lib/BasicTypes.cpp
  68. 14 15
      lib/CArtHandler.cpp
  69. 1 0
      lib/CArtifactInstance.h
  70. 26 35
      lib/CBonusTypeHandler.cpp
  71. 6 2
      lib/CBuildingHandler.cpp
  72. 10 10
      lib/CCreatureHandler.cpp
  73. 1 1
      lib/CCreatureSet.cpp
  74. 1 1
      lib/CCreatureSet.h
  75. 5 5
      lib/CGameInfoCallback.cpp
  76. 10 10
      lib/CGameInfoCallback.h
  77. 1 1
      lib/CGameInterface.h
  78. 9 9
      lib/CHeroHandler.cpp
  79. 1 1
      lib/CHeroHandler.h
  80. 2 1
      lib/CPlayerState.h
  81. 1 1
      lib/CSkillHandler.cpp
  82. 10 10
      lib/CTownHandler.cpp
  83. 3 3
      lib/CTownHandler.h
  84. 3 1382
      lib/GameConstants.h
  85. 1 1
      lib/IGameCallback.h
  86. 1 1
      lib/IGameEventsReceiver.h
  87. 1 1
      lib/JsonNode.cpp
  88. 6 6
      lib/JsonRandom.cpp
  89. 3 3
      lib/NetPacks.h
  90. 4 4
      lib/NetPacksLib.cpp
  91. 4 4
      lib/ResourceSet.cpp
  92. 0 10
      lib/ResourceSet.h
  93. 0 125
      lib/StringConstants.h
  94. 1 4
      lib/battle/BattleAction.cpp
  95. 8 0
      lib/battle/BattleHex.h
  96. 2 2
      lib/battle/BattleInfo.cpp
  97. 10 10
      lib/battle/CBattleInfoCallback.cpp
  98. 1 1
      lib/battle/CBattleInfoCallback.h
  99. 2 2
      lib/battle/CUnitState.cpp
  100. 2 2
      lib/battle/DamageCalculator.cpp

+ 1 - 1
AI/BattleAI/BattleExchangeVariant.cpp

@@ -357,7 +357,7 @@ int64_t BattleExchangeEvaluator::calculateExchange(
 
 	if(cb->battleGetMySide() == BattlePerspective::LEFT_SIDE
 		&& cb->battleGetGateState() == EGateState::BLOCKED
-		&& ap.attack.defender->coversPos(ESiegeHex::GATE_BRIDGE))
+		&& ap.attack.defender->coversPos(BattleHex::GATE_BRIDGE))
 	{
 		return EvaluationResult::INEFFECTIVE_SCORE;
 	}

+ 1 - 1
AI/EmptyAI/CEmptyAI.cpp

@@ -45,7 +45,7 @@ void CEmptyAI::yourTacticPhase(int distance)
 	cb->battleMakeTacticAction(BattleAction::makeEndOFTacticPhase(cb->battleGetTacticsSide()));
 }
 
-void CEmptyAI::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID)
+void CEmptyAI::heroGotLevel(const CGHeroInstance *hero, PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID)
 {
 	cb->selectionMade(CRandomGenerator::getDefault().nextInt((int)skills.size() - 1), queryID);
 }

+ 1 - 1
AI/EmptyAI/CEmptyAI.h

@@ -26,7 +26,7 @@ public:
 	void yourTurn() override;
 	void yourTacticPhase(int distance) override;
 	void activeStack(const CStack * stack) override;
-	void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID) override;
+	void heroGotLevel(const CGHeroInstance *hero, PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID) override;
 	void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID) override;
 	void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel) override;
 	void showTeleportDialog(TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override;

+ 6 - 6
AI/Nullkiller/AIGateway.cpp

@@ -314,9 +314,9 @@ void AIGateway::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID her
 	});
 }
 
-void AIGateway::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val)
+void AIGateway::heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkill which, si64 val)
 {
-	LOG_TRACE_PARAMS(logAi, "which '%i', val '%i'", which % val);
+	LOG_TRACE_PARAMS(logAi, "which '%i', val '%i'", static_cast<int>(which) % val);
 	NET_EVENT_HANDLER;
 }
 
@@ -552,7 +552,7 @@ void AIGateway::yourTurn()
 	makingTurn = std::make_unique<boost::thread>(&AIGateway::makeTurn, this);
 }
 
-void AIGateway::heroGotLevel(const CGHeroInstance * hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> & skills, QueryID queryID)
+void AIGateway::heroGotLevel(const CGHeroInstance * hero, PrimarySkill pskill, std::vector<SecondarySkill> & skills, QueryID queryID)
 {
 	LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
 	NET_EVENT_HANDLER;
@@ -757,7 +757,7 @@ bool AIGateway::makePossibleUpgrades(const CArmedInstance * obj)
 		{
 			UpgradeInfo ui;
 			myCb->fillUpgradeInfo(obj, SlotID(i), ui);
-			if(ui.oldID >= 0 && nullkiller->getFreeResources().canAfford(ui.cost[0] * s->count))
+			if(ui.oldID != CreatureID::NONE && nullkiller->getFreeResources().canAfford(ui.cost[0] * s->count))
 			{
 				myCb->upgradeCreature(obj, SlotID(i), ui.newID[0]);
 				upgraded = true;
@@ -773,7 +773,7 @@ void AIGateway::makeTurn()
 {
 	MAKING_TURN;
 
-	auto day = cb->getDate(Date::EDateType::DAY);
+	auto day = cb->getDate(Date::DAY);
 	logAi->info("Player %d (%s) starting turn, day %d", playerID, playerID.getStr(), day);
 
 	boost::shared_lock<boost::shared_mutex> gsLock(CGameState::mutex);
@@ -1097,7 +1097,7 @@ void AIGateway::battleEnd(const BattleResult * br, QueryID queryID)
 	logAi->debug("Player %d (%s): I %s the %s!", playerID, playerID.getStr(), (won ? "won" : "lost"), battlename);
 	battlename.clear();
 
-	if (queryID != -1)
+	if (queryID != QueryID::NONE)
 	{
 		status.addQuery(queryID, "Combat result dialog");
 		const int confirmAction = 0;

+ 2 - 2
AI/Nullkiller/AIGateway.h

@@ -113,7 +113,7 @@ public:
 	void initGameInterface(std::shared_ptr<Environment> env, std::shared_ptr<CCallback> CB) override;
 	void yourTurn() override;
 
-	void heroGotLevel(const CGHeroInstance * hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> & skills, QueryID queryID) override; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
+	void heroGotLevel(const CGHeroInstance * hero, PrimarySkill pskill, std::vector<SecondarySkill> & skills, QueryID queryID) override; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
 	void commanderGotLevel(const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID) override; //TODO
 	void showBlockingDialog(const std::string & text, const std::vector<Component> & components, QueryID askID, const int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
 	void showGarrisonDialog(const CArmedInstance * up, const CGHeroInstance * down, bool removableUnits, QueryID queryID) override; //all stacks operations between these objects become allowed, interface has to call onEnd when done
@@ -144,7 +144,7 @@ public:
 	void heroVisitsTown(const CGHeroInstance * hero, const CGTownInstance * town) override;
 	void tileRevealed(const std::unordered_set<int3> & pos) override;
 	void heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query) override;
-	void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) override;
+	void heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkill which, si64 val) override;
 	void showRecruitmentDialog(const CGDwelling * dwelling, const CArmedInstance * dst, int level) override;
 	void heroMovePointsChanged(const CGHeroInstance * hero) override;
 	void garrisonsChanged(ObjectInstanceID id1, ObjectInstanceID id2) override;

+ 2 - 2
AI/Nullkiller/AIUtility.cpp

@@ -241,7 +241,7 @@ bool isObjectPassable(const CGObjectInstance * obj)
 }
 
 // Pathfinder internal helper
-bool isObjectPassable(const CGObjectInstance * obj, PlayerColor playerColor, PlayerRelations::PlayerRelations objectRelations)
+bool isObjectPassable(const CGObjectInstance * obj, PlayerColor playerColor, PlayerRelations objectRelations)
 {
 	if((obj->ID == Obj::GARRISON || obj->ID == Obj::GARRISON2)
 		&& objectRelations != PlayerRelations::ENEMIES)
@@ -274,7 +274,7 @@ creInfo infoFromDC(const dwellingContent & dc)
 	creInfo ci;
 	ci.count = dc.first;
 	ci.creID = dc.second.size() ? dc.second.back() : CreatureID(-1); //should never be accessed
-	if (ci.creID != -1)
+	if (ci.creID != CreatureID::NONE)
 	{
 		ci.cre = VLC->creatures()->getById(ci.creID);
 		ci.level = ci.cre->getLevel(); //this is creature tier, while tryRealize expects dwelling level. Ignore.

+ 2 - 2
AI/Nullkiller/AIUtility.h

@@ -151,7 +151,7 @@ struct ObjectIdRef
 	}
 };
 
-template<int id>
+template<Obj::Type id>
 bool objWithID(const CGObjectInstance * obj)
 {
 	return obj->ID == id;
@@ -226,7 +226,7 @@ void foreach_neighbour(CCallback * cbp, const int3 & pos, const Func & foo) // a
 bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater);
 bool isObjectPassable(const CGObjectInstance * obj);
 bool isObjectPassable(const Nullkiller * ai, const CGObjectInstance * obj);
-bool isObjectPassable(const CGObjectInstance * obj, PlayerColor playerColor, PlayerRelations::PlayerRelations objectRelations);
+bool isObjectPassable(const CGObjectInstance * obj, PlayerColor playerColor, PlayerRelations objectRelations);
 bool isBlockVisitObj(const int3 & pos);
 
 bool isWeeklyRevisitable(const CGObjectInstance * obj);

+ 2 - 2
AI/Nullkiller/Analyzers/ArmyManager.cpp

@@ -256,7 +256,7 @@ std::shared_ptr<CCreatureSet> ArmyManager::getArmyAvailableToBuyAsCCreatureSet(
 	{
 		auto ci = infoFromDC(dwelling->creatures[i]);
 
-		if(!ci.count || ci.creID == -1)
+		if(!ci.count || ci.creID == CreatureID::NONE)
 			continue;
 
 		vstd::amin(ci.count, availableRes / ci.cre->getFullRecruitCost()); //max count we can afford
@@ -316,7 +316,7 @@ std::vector<creInfo> ArmyManager::getArmyAvailableToBuy(
 	{
 		auto ci = infoFromDC(dwelling->creatures[i]);
 
-		if(ci.creID == -1) continue;
+		if(ci.creID == CreatureID::NONE) continue;
 
 		if(i < GameConstants::CREATURES_PER_TOWN && countGrowth)
 		{

+ 2 - 2
AI/Nullkiller/Analyzers/BuildAnalyzer.cpp

@@ -24,7 +24,7 @@ void BuildAnalyzer::updateTownDwellings(TownDevelopmentInfo & developmentInfo)
 
 	for(auto &pair : townInfo->buildings)
 	{
-		if(pair.second->upgrade != -1)
+		if(pair.second->upgrade != BuildingID::NONE)
 		{
 			parentMap[pair.second->upgrade] = pair.first;
 		}
@@ -160,7 +160,7 @@ void BuildAnalyzer::update()
 
 	updateDailyIncome();
 
-	if(ai->cb->getDate(Date::EDateType::DAY) == 1)
+	if(ai->cb->getDate(Date::DAY) == 1)
 	{
 		goldPreasure = 1;
 	}

+ 4 - 4
AI/Nullkiller/Engine/PriorityEvaluator.cpp

@@ -244,10 +244,10 @@ uint64_t evaluateArtifactArmyValue(CArtifactInstance * art)
 		10 * art->valOfBonuses(BonusType::MOVEMENT, 1)
 		+ 1200 * art->valOfBonuses(BonusType::STACKS_SPEED)
 		+ 700 * art->valOfBonuses(BonusType::MORALE)
-		+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, PrimarySkill::ATTACK)
-		+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, PrimarySkill::DEFENSE)
-		+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, PrimarySkill::KNOWLEDGE)
-		+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, PrimarySkill::SPELL_POWER)
+		+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::ATTACK))
+		+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::DEFENSE))
+		+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::KNOWLEDGE))
+		+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::SPELL_POWER))
 		+ 500 * art->valOfBonuses(BonusType::LUCK);
 
 	auto classValue = 0;

+ 1 - 1
AI/Nullkiller/Goals/AbstractGoal.cpp

@@ -10,7 +10,7 @@
 #include "StdInc.h"
 #include "AbstractGoal.h"
 #include "../AIGateway.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 namespace NKAI
 {

+ 1 - 1
AI/Nullkiller/Goals/BuildThis.cpp

@@ -11,7 +11,7 @@
 #include "BuildThis.h"
 #include "../AIGateway.h"
 #include "../AIUtility.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 
 namespace NKAI

+ 1 - 1
AI/Nullkiller/Goals/BuyArmy.cpp

@@ -51,7 +51,7 @@ void BuyArmy::accept(AIGateway * ai)
 		auto res = cb->getResourceAmount();
 		auto & ci = armyToBuy[i];
 
-		if(objid != -1 && ci.creID != objid)
+		if(objid != CreatureID::NONE && ci.creID.getNum() != objid)
 			continue;
 
 		vstd::amin(ci.count, res / ci.cre->getFullRecruitCost());

+ 1 - 1
AI/Nullkiller/Goals/Composition.cpp

@@ -11,7 +11,7 @@
 #include "Composition.h"
 #include "../AIGateway.h"
 #include "../AIUtility.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 
 namespace NKAI

+ 1 - 1
AI/Nullkiller/Goals/RecruitHero.cpp

@@ -11,7 +11,7 @@
 #include "Goals.h"
 #include "../AIGateway.h"
 #include "../AIUtility.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 
 namespace NKAI

+ 1 - 1
AI/VCAI/AIUtility.cpp

@@ -224,7 +224,7 @@ creInfo infoFromDC(const dwellingContent & dc)
 	creInfo ci;
 	ci.count = dc.first;
 	ci.creID = dc.second.size() ? dc.second.back() : CreatureID(-1); //should never be accessed
-	if (ci.creID != -1)
+	if (ci.creID != CreatureID::NONE)
 	{
 		ci.cre = VLC->creatures()->getById(ci.creID);
 		ci.level = ci.cre->getLevel(); //this is creature tier, while tryRealize expects dwelling level. Ignore.

+ 1 - 1
AI/VCAI/AIUtility.h

@@ -142,7 +142,7 @@ class ObjsVector : public std::vector<ObjectIdRef>
 {
 };
 
-template<int id>
+template<Obj::Type id>
 bool objWithID(const CGObjectInstance * obj)
 {
 	return obj->ID == id;

+ 2 - 2
AI/VCAI/ArmyManager.cpp

@@ -118,12 +118,12 @@ ui64 ArmyManager::howManyReinforcementsCanBuy(const CCreatureSet * h, const CGDw
 	{
 		creInfo ci = infoFromDC(dc);
 
-		if(!ci.count || ci.creID == -1)
+		if(!ci.count || ci.creID == CreatureID::NONE)
 			continue;
 
 		vstd::amin(ci.count, availableRes / ci.cre->getFullRecruitCost()); //max count we can afford
 
-		if(ci.count && ci.creID != -1) //valid creature at this level
+		if(ci.count && ci.creID != CreatureID::NONE) //valid creature at this level
 		{
 			//can be merged with another stack?
 			SlotID dst = h->getSlotFor(ci.creID);

+ 3 - 3
AI/VCAI/BuildingManager.cpp

@@ -38,7 +38,7 @@ bool BuildingManager::tryBuildThisStructure(const CGTownInstance * t, BuildingID
 
 	for (BuildingID buildID : toBuild)
 	{
-		EBuildingState::EBuildingState canBuild = cb->canBuildStructure(t, buildID);
+		EBuildingState canBuild = cb->canBuildStructure(t, buildID);
 		if (canBuild == EBuildingState::HAVE_CAPITAL || canBuild == EBuildingState::FORBIDDEN || canBuild == EBuildingState::NO_WATER)
 			return false; //we won't be able to build this
 	}
@@ -52,7 +52,7 @@ bool BuildingManager::tryBuildThisStructure(const CGTownInstance * t, BuildingID
 	{
 		const CBuilding * b = t->town->buildings.at(buildID);
 
-		EBuildingState::EBuildingState canBuild = cb->canBuildStructure(t, buildID);
+		EBuildingState canBuild = cb->canBuildStructure(t, buildID);
 		if (canBuild == EBuildingState::ALLOWED)
 		{
 			PotentialBuilding pb;
@@ -222,7 +222,7 @@ bool BuildingManager::getBuildingOptions(const CGTownInstance * t)
 	std::vector<BuildingID> extraBuildings;
 	for (auto buildingInfo : t->town->buildings)
 	{
-		if (buildingInfo.first > 43)
+		if (buildingInfo.first > BuildingID::DWELL_UP2_FIRST)
 			extraBuildings.push_back(buildingInfo.first);
 	}
 	return tryBuildAnyStructure(t, extraBuildings);

+ 1 - 1
AI/VCAI/Goals/AbstractGoal.cpp

@@ -14,7 +14,7 @@
 #include "../FuzzyHelper.h"
 #include "../ResourceManager.h"
 #include "../BuildingManager.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 using namespace Goals;
 

+ 1 - 1
AI/VCAI/Goals/Build.cpp

@@ -17,7 +17,7 @@
 #include "../ResourceManager.h"
 #include "../BuildingManager.h"
 #include "../../../lib/mapObjects/CGTownInstance.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 using namespace Goals;
 

+ 1 - 1
AI/VCAI/Goals/BuildThis.cpp

@@ -16,7 +16,7 @@
 #include "../ResourceManager.h"
 #include "../BuildingManager.h"
 #include "../../../lib/mapObjects/CGTownInstance.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 using namespace Goals;
 

+ 3 - 3
AI/VCAI/Goals/CollectRes.cpp

@@ -16,7 +16,7 @@
 #include "../ResourceManager.h"
 #include "../BuildingManager.h"
 #include "../../../lib/mapObjects/CGMarket.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 using namespace Goals;
 
@@ -170,10 +170,10 @@ TSubgoal CollectRes::whatToDoToTrade()
 		int howManyCanWeBuy = 0;
 		for (GameResID i = EGameResID::WOOD; i <= EGameResID::GOLD; ++i)
 		{
-			if (GameResID(i) == resID)
+			if (i.getNum() == resID)
 				continue;
 			int toGive = -1, toReceive = -1;
-			m->getOffer(GameResID(i), resID, toGive, toReceive, EMarketMode::RESOURCE_RESOURCE);
+			m->getOffer(i, resID, toGive, toReceive, EMarketMode::RESOURCE_RESOURCE);
 			assert(toGive > 0 && toReceive > 0);
 			howManyCanWeBuy += toReceive * (ai->ah->freeResources()[i] / toGive);
 		}

+ 1 - 1
AI/VCAI/Goals/Conquer.cpp

@@ -15,7 +15,7 @@
 #include "../FuzzyHelper.h"
 #include "../ResourceManager.h"
 #include "../BuildingManager.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 using namespace Goals;
 

+ 1 - 1
AI/VCAI/Goals/Explore.cpp

@@ -15,7 +15,7 @@
 #include "../FuzzyHelper.h"
 #include "../ResourceManager.h"
 #include "../BuildingManager.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 #include "../../../lib/CPlayerState.h"
 
 using namespace Goals;

+ 3 - 3
AI/VCAI/Goals/FindObj.cpp

@@ -28,7 +28,7 @@ TSubgoal FindObj::whatToDoToAchieve()
 	{
 		for(const CGObjectInstance * obj : ai->visitableObjs)
 		{
-			if(obj->ID == objid && obj->subID == resID)
+			if(obj->ID.getNum() == objid && obj->subID == resID)
 			{
 				o = obj;
 				break; //TODO: consider multiple objects and choose best
@@ -39,7 +39,7 @@ TSubgoal FindObj::whatToDoToAchieve()
 	{
 		for(const CGObjectInstance * obj : ai->visitableObjs)
 		{
-			if(obj->ID == objid)
+			if(obj->ID.getNum() == objid)
 			{
 				o = obj;
 				break; //TODO: consider multiple objects and choose best
@@ -59,7 +59,7 @@ bool FindObj::fulfillsMe(TSubgoal goal)
 		if (!hero || hero == goal->hero)
 			for (auto obj : cb->getVisitableObjs(goal->tile)) //check if any object on that tile matches criteria
 				if (obj->visitablePos() == goal->tile) //object could be removed
-					if (obj->ID == objid && obj->subID == resID) //same type and subtype
+					if (obj->ID.getNum() == objid && obj->subID == resID) //same type and subtype
 						return true;
 	}
 	return false;

+ 1 - 1
AI/VCAI/Goals/GatherArmy.cpp

@@ -16,7 +16,7 @@
 #include "../ResourceManager.h"
 #include "../BuildingManager.h"
 #include "../../../lib/mapObjects/CGTownInstance.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 using namespace Goals;
 

+ 2 - 2
AI/VCAI/Goals/GatherTroops.cpp

@@ -16,7 +16,7 @@
 #include "../ResourceManager.h"
 #include "../BuildingManager.h"
 #include "../../../lib/mapObjects/CGTownInstance.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 using namespace Goals;
 
@@ -134,7 +134,7 @@ TGoalVec GatherTroops::getAllPossibleSubgoals()
 			{
 				for(auto type : creature.second)
 				{
-					if(type == objid && ai->ah->freeResources().canAfford(VLC->creatures()->getById(type)->getFullRecruitCost()))
+					if(type.getNum() == objid && ai->ah->freeResources().canAfford(VLC->creatures()->getById(type)->getFullRecruitCost()))
 						vstd::concatenate(solutions, ai->ah->howToVisitObj(obj));
 				}
 			}

+ 1 - 1
AI/VCAI/Goals/RecruitHero.cpp

@@ -15,7 +15,7 @@
 #include "../FuzzyHelper.h"
 #include "../ResourceManager.h"
 #include "../BuildingManager.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 using namespace Goals;
 

+ 1 - 1
AI/VCAI/Goals/VisitObj.cpp

@@ -15,7 +15,7 @@
 #include "../FuzzyHelper.h"
 #include "../ResourceManager.h"
 #include "../BuildingManager.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 using namespace Goals;
 

+ 1 - 1
AI/VCAI/Goals/VisitTile.cpp

@@ -15,7 +15,7 @@
 #include "../FuzzyHelper.h"
 #include "../ResourceManager.h"
 #include "../BuildingManager.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 using namespace Goals;
 

+ 1 - 1
AI/VCAI/Goals/Win.cpp

@@ -17,7 +17,7 @@
 #include "../BuildingManager.h"
 #include "../../../lib/mapping/CMapHeader.h" //for victory conditions
 #include "../../../lib/mapObjects/CGTownInstance.h"
-#include "../../../lib/StringConstants.h"
+#include "../../../lib/constants/StringConstants.h"
 
 using namespace Goals;
 

+ 8 - 8
AI/VCAI/VCAI.cpp

@@ -351,9 +351,9 @@ void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, Q
 	});
 }
 
-void VCAI::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val)
+void VCAI::heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkill which, si64 val)
 {
-	LOG_TRACE_PARAMS(logAi, "which '%i', val '%i'", which % val);
+	LOG_TRACE_PARAMS(logAi, "which '%i', val '%i'", static_cast<int>(which) % val);
 	NET_EVENT_HANDLER;
 }
 
@@ -618,7 +618,7 @@ void VCAI::yourTurn()
 	makingTurn = std::make_unique<boost::thread>(&VCAI::makeTurn, this);
 }
 
-void VCAI::heroGotLevel(const CGHeroInstance * hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> & skills, QueryID queryID)
+void VCAI::heroGotLevel(const CGHeroInstance * hero, PrimarySkill pskill, std::vector<SecondarySkill> & skills, QueryID queryID)
 {
 	LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
 	NET_EVENT_HANDLER;
@@ -764,7 +764,7 @@ void makePossibleUpgrades(const CArmedInstance * obj)
 		{
 			UpgradeInfo ui;
 			cb->fillUpgradeInfo(obj, SlotID(i), ui);
-			if(ui.oldID >= 0 && cb->getResourceAmount().canAfford(ui.cost[0] * s->count))
+			if(ui.oldID != CreatureID::NONE && cb->getResourceAmount().canAfford(ui.cost[0] * s->count))
 			{
 				cb->upgradeCreature(obj, SlotID(i), ui.newID[0]);
 			}
@@ -776,7 +776,7 @@ void VCAI::makeTurn()
 {
 	MAKING_TURN;
 
-	auto day = cb->getDate(Date::EDateType::DAY);
+	auto day = cb->getDate(Date::DAY);
 	logAi->info("Player %d (%s) starting turn, day %d", playerID, playerID.getStr(), day);
 
 	boost::shared_lock<boost::shared_mutex> gsLock(CGameState::mutex);
@@ -1594,7 +1594,7 @@ void VCAI::battleEnd(const BattleResult * br, QueryID queryID)
 	logAi->debug("Player %d (%s): I %s the %s!", playerID, playerID.getStr(), (won ? "won" : "lost"), battlename);
 	battlename.clear();
 
-	if (queryID != -1)
+	if (queryID != QueryID::NONE)
 	{
 		status.addQuery(queryID, "Combat result dialog");
 		const int confirmAction = 0;
@@ -2184,8 +2184,8 @@ void VCAI::tryRealize(Goals::BuyArmy & g)
 			auto ci = infoFromDC(t->creatures[i]);
 
 			if(!ci.count
-				|| ci.creID == -1
-				|| (g.objid != -1 && ci.creID != g.objid)
+				|| ci.creID == CreatureID::NONE
+				|| (g.objid != -1 && ci.creID.getNum() != g.objid)
 				|| t->getUpperArmy()->getSlotFor(ci.creID) == SlotID())
 				continue;
 

+ 2 - 2
AI/VCAI/VCAI.h

@@ -146,7 +146,7 @@ public:
 	void initGameInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB) override;
 	void yourTurn() override;
 
-	void heroGotLevel(const CGHeroInstance * hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> & skills, QueryID queryID) override; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
+	void heroGotLevel(const CGHeroInstance * hero, PrimarySkill pskill, std::vector<SecondarySkill> & skills, QueryID queryID) override; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
 	void commanderGotLevel(const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID) override; //TODO
 	void showBlockingDialog(const std::string & text, const std::vector<Component> & components, QueryID askID, const int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
 	void showGarrisonDialog(const CArmedInstance * up, const CGHeroInstance * down, bool removableUnits, QueryID queryID) override; //all stacks operations between these objects become allowed, interface has to call onEnd when done
@@ -177,7 +177,7 @@ public:
 	void heroVisitsTown(const CGHeroInstance * hero, const CGTownInstance * town) override;
 	void tileRevealed(const std::unordered_set<int3> & pos) override;
 	void heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query) override;
-	void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) override;
+	void heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkill which, si64 val) override;
 	void showRecruitmentDialog(const CGDwelling * dwelling, const CArmedInstance * dst, int level) override;
 	void heroMovePointsChanged(const CGHeroInstance * hero) override;
 	void garrisonsChanged(ObjectInstanceID id1, ObjectInstanceID id2) override;

+ 3 - 3
CCallback.cpp

@@ -195,7 +195,7 @@ bool CCallback::buildBuilding(const CGTownInstance *town, BuildingID buildingID)
 	if(town->tempOwner!=player)
 		return false;
 
-	if(!canBuildStructure(town, buildingID))
+	if(canBuildStructure(town, buildingID) != EBuildingState::ALLOWED)
 		return false;
 
 	BuildStructure pack(town->id,buildingID);
@@ -242,12 +242,12 @@ void CCallback::buyArtifact(const CGHeroInstance *hero, ArtifactID aid)
 	sendRequest(&pack);
 }
 
-void CCallback::trade(const IMarket * market, EMarketMode::EMarketMode mode, ui32 id1, ui32 id2, ui32 val1, const CGHeroInstance * hero)
+void CCallback::trade(const IMarket * market, EMarketMode mode, ui32 id1, ui32 id2, ui32 val1, const CGHeroInstance * hero)
 {
 	trade(market, mode, std::vector<ui32>(1, id1), std::vector<ui32>(1, id2), std::vector<ui32>(1, val1), hero);
 }
 
-void CCallback::trade(const IMarket * market, EMarketMode::EMarketMode mode, const std::vector<ui32> & id1, const std::vector<ui32> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero)
+void CCallback::trade(const IMarket * market, EMarketMode mode, const std::vector<ui32> & id1, const std::vector<ui32> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero)
 {
 	TradeOnMarketplace pack;
 	pack.marketId = dynamic_cast<const CGObjectInstance *>(market)->id;

+ 4 - 4
CCallback.h

@@ -75,8 +75,8 @@ public:
 	virtual bool upgradeCreature(const CArmedInstance *obj, SlotID stackPos, 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 IMarket * market, EMarketMode::EMarketMode mode, ui32 id1, ui32 id2, ui32 val1, const CGHeroInstance * hero = nullptr)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce
-	virtual void trade(const IMarket * market, EMarketMode::EMarketMode mode, const std::vector<ui32> & id1, const std::vector<ui32> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero = nullptr)=0;
+	virtual void trade(const IMarket * market, EMarketMode mode, ui32 id1, ui32 id2, ui32 val1, const CGHeroInstance * hero = nullptr)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce
+	virtual void trade(const IMarket * market, EMarketMode mode, const std::vector<ui32> & id1, const std::vector<ui32> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero = nullptr)=0;
 
 	virtual int selectionMade(int selection, QueryID queryID) =0;
 	virtual int sendQueryReply(const JsonNode & reply, QueryID queryID) =0;
@@ -171,8 +171,8 @@ public:
 	void endTurn() override;
 	void swapGarrisonHero(const CGTownInstance *town) override;
 	void buyArtifact(const CGHeroInstance *hero, ArtifactID aid) override;
-	void trade(const IMarket * market, EMarketMode::EMarketMode mode, ui32 id1, ui32 id2, ui32 val1, const CGHeroInstance * hero = nullptr) override;
-	void trade(const IMarket * market, EMarketMode::EMarketMode mode, const std::vector<ui32> & id1, const std::vector<ui32> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero = nullptr) override;
+	void trade(const IMarket * market, EMarketMode mode, ui32 id1, ui32 id2, ui32 val1, const CGHeroInstance * hero = nullptr) override;
+	void trade(const IMarket * market, EMarketMode mode, const std::vector<ui32> & id1, const std::vector<ui32> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero = nullptr) override;
 	void setFormation(const CGHeroInstance * hero, bool tight) override;
 	void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero) override;
 	void save(const std::string &fname) override;

+ 1 - 1
client/CMusicHandler.cpp

@@ -19,7 +19,7 @@
 #include "../lib/JsonNode.h"
 #include "../lib/GameConstants.h"
 #include "../lib/filesystem/Filesystem.h"
-#include "../lib/StringConstants.h"
+#include "../lib/constants/StringConstants.h"
 #include "../lib/CRandomGenerator.h"
 #include "../lib/VCMIDirs.h"
 #include "../lib/TerrainHandler.h"

+ 5 - 5
client/CPlayerInterface.cpp

@@ -183,7 +183,7 @@ void CPlayerInterface::playerStartsTurn(PlayerColor player)
 
 	// close window from another player
 	if(auto w = GH.windows().topWindow<CInfoWindow>())
-		if(w->ID == -1 && player != playerID)
+		if(w->ID == QueryID::NONE && player != playerID)
 			w->close();
 	
 	// remove all dialogs that do not expect query answer
@@ -466,10 +466,10 @@ void CPlayerInterface::openTownWindow(const CGTownInstance * town)
 	GH.windows().pushWindow(newCastleInt);
 }
 
-void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val)
+void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkill which, si64 val)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	if (which == 4)
+	if (which == PrimarySkill::EXPERIENCE)
 	{
 		for (auto ctw : GH.windows().findWindows<CAltarWindow>())
 			ctw->setExpToLevel();
@@ -510,7 +510,7 @@ void CPlayerInterface::receivedResource()
 	GH.windows().totalRedraw();
 }
 
-void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill>& skills, QueryID queryID)
+void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, PrimarySkill pskill, std::vector<SecondarySkill>& skills, QueryID queryID)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	waitWhileDialog();
@@ -854,7 +854,7 @@ void CPlayerInterface::battleEnd(const BattleResult *br, QueryID queryID)
 
 		if(!battleInt)
 		{
-			bool allowManualReplay = queryID != -1;
+			bool allowManualReplay = queryID != QueryID::NONE;
 
 			auto wnd = std::make_shared<BattleResultWindow>(*br, *this, allowManualReplay);
 

+ 2 - 2
client/CPlayerInterface.h

@@ -109,11 +109,11 @@ protected: // Call-ins from server, should not be called directly, but only via
 
 	void heroVisit(const CGHeroInstance * visitor, const CGObjectInstance * visitedObj, bool start) override;
 	void heroCreated(const CGHeroInstance* hero) override;
-	void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID) override;
+	void heroGotLevel(const CGHeroInstance *hero, PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID) override;
 	void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID) override;
 	void heroInGarrisonChange(const CGTownInstance *town) override;
 	void heroMoved(const TryMoveHero & details, bool verbose = true) override;
-	void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) override;
+	void heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkill which, si64 val) override;
 	void heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val) override;
 	void heroManaPointsChanged(const CGHeroInstance * hero) override;
 	void heroMovePointsChanged(const CGHeroInstance * hero) override;

+ 1 - 1
client/Client.h

@@ -165,7 +165,7 @@ public:
 	bool removeObject(const CGObjectInstance * obj) override {return false;};
 	void createObject(const int3 & visitablePosition, Obj type, int32_t subtype ) override {};
 	void setOwner(const CGObjectInstance * obj, PlayerColor owner) override {};
-	void changePrimSkill(const CGHeroInstance * hero, PrimarySkill::PrimarySkill which, si64 val, bool abs = false) override {};
+	void changePrimSkill(const CGHeroInstance * hero, PrimarySkill which, si64 val, bool abs = false) override {};
 	void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs = false) override {};
 
 	void showBlockingDialog(BlockingDialog * iw) override {};

+ 1 - 1
client/ClientCommandManager.cpp

@@ -22,7 +22,7 @@
 #include "../lib/CConfigHandler.h"
 #include "../lib/gameState/CGameState.h"
 #include "../lib/CPlayerState.h"
-#include "../lib/StringConstants.h"
+#include "../lib/constants/StringConstants.h"
 #include "../lib/campaign/CampaignHandler.h"
 #include "../lib/mapping/CMapService.h"
 #include "../lib/mapping/CMap.h"

+ 1 - 1
client/adventureMap/AdventureMapInterface.cpp

@@ -483,7 +483,7 @@ void AdventureMapInterface::onTileLeftClicked(const int3 &mapPos)
 	}
 	//check if we can select this object
 	bool canSelect = topBlocking && topBlocking->ID == Obj::HERO && topBlocking->tempOwner == LOCPLINT->playerID;
-	canSelect |= topBlocking && topBlocking->ID == Obj::TOWN && LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, topBlocking->tempOwner);
+	canSelect |= topBlocking && topBlocking->ID == Obj::TOWN && LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, topBlocking->tempOwner) != PlayerRelations::ENEMIES;
 
 	bool isHero = false;
 	if(LOCPLINT->localState->getCurrentArmy()->ID != Obj::HERO) //hero is not selected (presumably town)

+ 1 - 1
client/adventureMap/AdventureMapWidget.cpp

@@ -29,7 +29,7 @@
 #include "../CPlayerInterface.h"
 #include "../PlayerLocalState.h"
 
-#include "../../lib/StringConstants.h"
+#include "../../lib/constants/StringConstants.h"
 #include "../../lib/filesystem/ResourceID.h"
 
 AdventureMapWidget::AdventureMapWidget( std::shared_ptr<AdventureMapShortcuts> shortcuts )

+ 0 - 5
client/adventureMap/CResDataBar.h

@@ -11,11 +11,6 @@
 
 #include "../gui/CIntObject.h"
 
-VCMI_LIB_NAMESPACE_BEGIN
-enum class EGameResID : int8_t;
-using GameResID = Identifier<EGameResID>;
-VCMI_LIB_NAMESPACE_END
-
 /// Resources bar which shows information about how many gold, crystals,... you have
 /// Current date is displayed too
 class CResDataBar : public CIntObject

+ 4 - 8
client/battle/BattleSiegeController.cpp

@@ -65,16 +65,12 @@ std::string BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisua
 	{
 	case EWallVisual::BACKGROUND_WALL:
 		{
-			switch(town->town->faction->getIndex())
-			{
-			case ETownType::RAMPART:
-			case ETownType::NECROPOLIS:
-			case ETownType::DUNGEON:
-			case ETownType::STRONGHOLD:
+			auto faction = town->town->faction->getIndex();
+
+			if (faction == ETownType::RAMPART || faction == ETownType::NECROPOLIS || faction == ETownType::DUNGEON || faction == ETownType::STRONGHOLD)
 				return prefix + "TPW1.BMP";
-			default:
+			else
 				return prefix + "TPWL.BMP";
-			}
 		}
 	case EWallVisual::KEEP:
 		return prefix + "MAN" + addit + ".BMP";

+ 2 - 2
client/battle/BattleWindow.cpp

@@ -523,7 +523,7 @@ void BattleWindow::bSpellf()
 
 	CCS->curh->set(Cursor::Map::POINTER);
 
-	ESpellCastProblem::ESpellCastProblem spellCastProblem = owner.curInt->cb->battleCanCastSpell(myHero, spells::Mode::HERO);
+	ESpellCastProblem spellCastProblem = owner.curInt->cb->battleCanCastSpell(myHero, spells::Mode::HERO);
 
 	if(spellCastProblem == ESpellCastProblem::OK)
 	{
@@ -629,7 +629,7 @@ void BattleWindow::blockUI(bool on)
 
 	if(hero)
 	{
-		ESpellCastProblem::ESpellCastProblem spellcastingProblem = owner.curInt->cb->battleCanCastSpell(hero, spells::Mode::HERO);
+		ESpellCastProblem spellcastingProblem = owner.curInt->cb->battleCanCastSpell(hero, spells::Mode::HERO);
 
 		//if magic is blocked, we leave button active, so the message can be displayed after button click
 		canCastSpells = spellcastingProblem == ESpellCastProblem::OK || spellcastingProblem == ESpellCastProblem::MAGIC_IS_BLOCKED;

+ 27 - 27
client/lobby/OptionsTab.cpp

@@ -94,7 +94,7 @@ size_t OptionsTab::CPlayerSettingsHelper::getImageIndex(bool big)
 		TOWN_RANDOM = 38,  TOWN_NONE = 39, // Special frames in ITPA
 		HERO_RANDOM = 163, HERO_NONE = 164 // Special frames in PortraitsSmall
 	};
-	auto factionIndex = settings.castle >= CGI->townh->size() ? 0 : settings.castle;
+	auto factionIndex = settings.castle.getNum() >= CGI->townh->size() ? 0 : settings.castle.getNum();
 
 	switch(type)
 	{
@@ -117,9 +117,9 @@ size_t OptionsTab::CPlayerSettingsHelper::getImageIndex(bool big)
 			return HERO_RANDOM;
 		default:
 		{
-			if(settings.heroPortrait >= 0)
+			if(settings.heroPortrait != HeroTypeID::NONE)
 				return settings.heroPortrait;
-			auto index = settings.hero >= CGI->heroh->size() ? 0 : settings.hero;
+			auto index = settings.hero.getNum() >= CGI->heroh->size() ? 0 : settings.hero.getNum();
 			return (*CGI->heroh)[index]->imageIndex;
 		}
 		}
@@ -191,7 +191,7 @@ std::string OptionsTab::CPlayerSettingsHelper::getName()
 			return CGI->generaltexth->allTexts[522];
 		default:
 		{
-			auto factionIndex = settings.castle >= CGI->townh->size() ? 0 : settings.castle;
+			auto factionIndex = settings.castle.getNum() >= CGI->townh->size() ? 0 : settings.castle.getNum();
 			return (*CGI->townh)[factionIndex]->getNameTranslated();
 		}
 	}
@@ -208,7 +208,7 @@ std::string OptionsTab::CPlayerSettingsHelper::getName()
 		{
 			if(!settings.heroName.empty())
 				return settings.heroName;
-			auto index = settings.hero >= CGI->heroh->size() ? 0 : settings.hero;
+			auto index = settings.hero.getNum() >= CGI->heroh->size() ? 0 : settings.hero.getNum();
 			return (*CGI->heroh)[index]->getNameTranslated();
 		}
 		}
@@ -233,9 +233,9 @@ std::string OptionsTab::CPlayerSettingsHelper::getTitle()
 	switch(type)
 	{
 	case OptionsTab::TOWN:
-		return (settings.castle < 0) ? CGI->generaltexth->allTexts[103] : CGI->generaltexth->allTexts[80];
+		return (settings.castle.getNum() < 0) ? CGI->generaltexth->allTexts[103] : CGI->generaltexth->allTexts[80];
 	case OptionsTab::HERO:
-		return (settings.hero < 0) ? CGI->generaltexth->allTexts[101] : CGI->generaltexth->allTexts[77];
+		return (settings.hero.getNum() < 0) ? CGI->generaltexth->allTexts[101] : CGI->generaltexth->allTexts[77];
 	case OptionsTab::BONUS:
 	{
 		switch(settings.bonus)
@@ -255,8 +255,8 @@ std::string OptionsTab::CPlayerSettingsHelper::getTitle()
 }
 std::string OptionsTab::CPlayerSettingsHelper::getSubtitle()
 {
-	auto factionIndex = settings.castle >= CGI->townh->size() ? 0 : settings.castle;
-	auto heroIndex = settings.hero >= CGI->heroh->size() ? 0 : settings.hero;
+	auto factionIndex = settings.castle.getNum() >= CGI->townh->size() ? 0 : settings.castle.getNum();
+	auto heroIndex = settings.hero.getNum() >= CGI->heroh->size() ? 0 : settings.hero.getNum();
 
 	switch(type)
 	{
@@ -264,7 +264,7 @@ std::string OptionsTab::CPlayerSettingsHelper::getSubtitle()
 		return getName();
 	case HERO:
 	{
-		if(settings.hero >= 0)
+		if(settings.hero.getNum() >= 0)
 			return getName() + " - " + (*CGI->heroh)[heroIndex]->heroClass->getNameTranslated();
 		return getName();
 	}
@@ -299,7 +299,7 @@ std::string OptionsTab::CPlayerSettingsHelper::getSubtitle()
 
 std::string OptionsTab::CPlayerSettingsHelper::getDescription()
 {
-	auto factionIndex = settings.castle >= CGI->townh->size() ? 0 : settings.castle;
+	auto factionIndex = settings.castle.getNum() >= CGI->townh->size() ? 0 : settings.castle.getNum();
 
 	switch(type)
 	{
@@ -386,7 +386,7 @@ void OptionsTab::CPlayerOptionTooltipBox::genTownWindow()
 	pos = Rect(0, 0, 228, 290);
 	genHeader();
 	labelAssociatedCreatures = std::make_shared<CLabel>(pos.w / 2 + 8, 122, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[79]);
-	auto factionIndex = settings.castle >= CGI->townh->size() ? 0 : settings.castle;
+	auto factionIndex = settings.castle.getNum() >= CGI->townh->size() ? 0 : settings.castle.getNum();
 	std::vector<std::shared_ptr<CComponent>> components;
 	const CTown * town = (*CGI->townh)[factionIndex]->town;
 
@@ -403,7 +403,7 @@ void OptionsTab::CPlayerOptionTooltipBox::genHeroWindow()
 	pos = Rect(0, 0, 292, 226);
 	genHeader();
 	labelHeroSpeciality = std::make_shared<CLabel>(pos.w / 2 + 4, 117, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[78]);
-	auto heroIndex = settings.hero >= CGI->heroh->size() ? 0 : settings.hero;
+	auto heroIndex = settings.hero.getNum() >= CGI->heroh->size() ? 0 : settings.hero.getNum();
 
 	imageSpeciality = std::make_shared<CAnimImage>("UN44", (*CGI->heroh)[heroIndex]->imageIndex, 0, pos.w / 2 - 22, 134);
 	labelSpecialityName = std::make_shared<CLabel>(pos.w / 2, 188, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, (*CGI->heroh)[heroIndex]->getSpecialtyNameTranslated());
@@ -438,10 +438,10 @@ OptionsTab::SelectionWindow::SelectionWindow(PlayerColor _color, SelType _type)
 			allowedHeroes.insert(HeroTypeID(i));
 
 	allowedBonus.push_back(-1); // random
-	if(initialHero >= -1)
+	if(initialHero.getNum() >= -1)
 		allowedBonus.push_back(0); // artifact
 	allowedBonus.push_back(1); // gold
-	if(initialFaction >= 0)
+	if(initialFaction.getNum() >= 0)
 		allowedBonus.push_back(2); // resource
 
 	recreate();
@@ -451,7 +451,7 @@ int OptionsTab::SelectionWindow::calcLines(FactionID faction)
 {
 	double additionalItems = 1; // random
 
-	if(faction < 0)
+	if(faction.getNum() < 0)
 		return std::ceil(((double)allowedFactions.size() + additionalItems) / elementsPerLine);
 
 	int count = 0;
@@ -568,8 +568,8 @@ void OptionsTab::SelectionWindow::genContentFactions()
 	set.castle = PlayerSettings::RANDOM;
 	CPlayerSettingsHelper helper = CPlayerSettingsHelper(set, SelType::TOWN);
 	components.push_back(std::make_shared<CAnimImage>(helper.getImageName(), helper.getImageIndex(), 0, 6, (ICON_SMALL_HEIGHT/2)));
-	drawOutlinedText(TEXT_POS_X, TEXT_POS_Y, (selectedFaction == PlayerSettings::RANDOM) ? Colors::YELLOW : Colors::WHITE, helper.getName());
-	if(selectedFaction == PlayerSettings::RANDOM)
+	drawOutlinedText(TEXT_POS_X, TEXT_POS_Y, (selectedFaction.getNum() == PlayerSettings::RANDOM) ? Colors::YELLOW : Colors::WHITE, helper.getName());
+	if(selectedFaction.getNum() == PlayerSettings::RANDOM)
 		components.push_back(std::make_shared<CPicture>("lobby/townBorderSmallActivated", 6, (ICON_SMALL_HEIGHT/2)));
 
 	for(auto & elem : allowedFactions)
@@ -600,8 +600,8 @@ void OptionsTab::SelectionWindow::genContentHeroes()
 	set.hero = PlayerSettings::RANDOM;
 	CPlayerSettingsHelper helper = CPlayerSettingsHelper(set, SelType::HERO);
 	components.push_back(std::make_shared<CAnimImage>(helper.getImageName(), helper.getImageIndex(), 0, 6, (ICON_SMALL_HEIGHT/2)));
-	drawOutlinedText(TEXT_POS_X, TEXT_POS_Y, (selectedHero == PlayerSettings::RANDOM) ? Colors::YELLOW : Colors::WHITE, helper.getName());
-	if(selectedHero == PlayerSettings::RANDOM)
+	drawOutlinedText(TEXT_POS_X, TEXT_POS_Y, (selectedHero.getNum() == PlayerSettings::RANDOM) ? Colors::YELLOW : Colors::WHITE, helper.getName());
+	if(selectedHero.getNum() == PlayerSettings::RANDOM)
 		components.push_back(std::make_shared<CPicture>("lobby/townBorderSmallActivated", 6, (ICON_SMALL_HEIGHT/2)));
 
 	for(auto & elem : allowedHeroes)
@@ -677,7 +677,7 @@ void OptionsTab::SelectionWindow::setElement(int elem, bool doApply)
 		{
 			set.castle = PlayerSettings::RANDOM;
 		}
-		if(set.castle != PlayerSettings::NONE)
+		if(set.castle.getNum() != PlayerSettings::NONE)
 		{
 			if(!doApply)
 			{
@@ -701,7 +701,7 @@ void OptionsTab::SelectionWindow::setElement(int elem, bool doApply)
 		{
 			set.hero = PlayerSettings::RANDOM;
 		}
-		if(set.hero != PlayerSettings::NONE)
+		if(set.hero.getNum() != PlayerSettings::NONE)
 		{
 			if(!doApply)
 			{
@@ -784,9 +784,9 @@ void OptionsTab::SelectedBox::update()
 void OptionsTab::SelectedBox::showPopupWindow(const Point & cursorPosition)
 {
 	// cases when we do not need to display a message
-	if(settings.castle == PlayerSettings::NONE && CPlayerSettingsHelper::type == TOWN)
+	if(settings.castle.getNum() == PlayerSettings::NONE && CPlayerSettingsHelper::type == TOWN)
 		return;
-	if(settings.hero == PlayerSettings::NONE && !SEL->getPlayerInfo(settings.color.getNum()).hasCustomMainHero() && CPlayerSettingsHelper::type == HERO)
+	if(settings.hero.getNum() == PlayerSettings::NONE && !SEL->getPlayerInfo(settings.color.getNum()).hasCustomMainHero() && CPlayerSettingsHelper::type == HERO)
 		return;
 
 	GH.windows().createAndPushWindow<CPlayerOptionTooltipBox>(*this);
@@ -800,7 +800,7 @@ void OptionsTab::SelectedBox::clickReleased(const Point & cursorPosition)
 	if(type == SelType::TOWN && ((pi.allowedFactions.size() < 2 && !pi.isFactionRandom) || foreignPlayer))
 		return;
 
-	if(type == SelType::HERO && ((pi.defaultHero() != -1 || settings.castle < 0) || foreignPlayer))
+	if(type == SelType::HERO && ((pi.defaultHero() != -1 || settings.castle.getNum() < 0) || foreignPlayer))
 		return;
 
 	if(type == SelType::BONUS && foreignPlayer)
@@ -932,7 +932,7 @@ void OptionsTab::PlayerOptionsEntry::hideUnavailableButtons()
 		buttonTownRight->enable();
 	}
 
-	if((pi->defaultHero() != -1 || s->castle < 0) //fixed hero
+	if((pi->defaultHero() != -1 || s->castle.getNum() < 0) //fixed hero
 		|| foreignPlayer) //or not our player
 	{
 		buttonHeroLeft->disable();
@@ -954,4 +954,4 @@ void OptionsTab::PlayerOptionsEntry::hideUnavailableButtons()
 		buttonBonusLeft->enable();
 		buttonBonusRight->enable();
 	}
-}
+}

+ 1 - 1
client/widgets/CArtifactsOfHeroBackpack.cpp

@@ -77,7 +77,7 @@ void CArtifactsOfHeroBackpack::scrollBackpack(int offset)
 	if(backpackListBox)
 		backpackListBox->resize(getActiveSlotLinesNum());
 	backpackPos += offset;
-	auto slot = ArtifactPosition(GameConstants::BACKPACK_START + backpackPos);
+	auto slot = ArtifactPosition::BACKPACK_START + backpackPos;
 	for(auto artPlace : backpack)
 	{
 		setSlotData(artPlace, slot, *curHero);

+ 3 - 3
client/widgets/CArtifactsOfHeroBase.cpp

@@ -63,7 +63,7 @@ void CArtifactsOfHeroBase::init(
 	// CArtifactsOfHeroBase::init may be transform to CArtifactsOfHeroBase::CArtifactsOfHeroBase if OBJECT_CONSTRUCTION_CAPTURING is removed
 	OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
 	pos += position;
-	for(int g = 0; g < GameConstants::BACKPACK_START; g++)
+	for(int g = 0; g < ArtifactPosition::BACKPACK_START; g++)
 	{
 		artWorn[ArtifactPosition(g)] = std::make_shared<CHeroArtPlace>(slotPos[g]);
 	}
@@ -143,7 +143,7 @@ void CArtifactsOfHeroBase::scrollBackpackForArtSet(int offset, const CArtifactSe
 	};
 	slotInc inc_ring = [artsInBackpack](ArtifactPosition & slot) -> ArtifactPosition
 	{
-		return ArtifactPosition(GameConstants::BACKPACK_START + (slot - GameConstants::BACKPACK_START + 1) % artsInBackpack);
+		return ArtifactPosition::BACKPACK_START + (slot - ArtifactPosition::BACKPACK_START + 1) % artsInBackpack;
 	};
 	slotInc inc;
 	if(scrollingPossible)
@@ -158,7 +158,7 @@ void CArtifactsOfHeroBase::scrollBackpackForArtSet(int offset, const CArtifactSe
 	if(artsInBackpack)
 		backpackPos %= artsInBackpack;
 
-	auto slot = ArtifactPosition(GameConstants::BACKPACK_START + backpackPos);
+	auto slot = ArtifactPosition(ArtifactPosition::BACKPACK_START + backpackPos);
 	for(auto artPlace : backpack)
 	{
 		setSlotData(artPlace, slot, artSet);

+ 1 - 1
client/widgets/CGarrisonInt.cpp

@@ -164,7 +164,7 @@ bool CGarrisonSlot::viewInfo()
 	UpgradeInfo pom;
 	LOCPLINT->cb->fillUpgradeInfo(getObj(), ID, pom);
 
-	bool canUpgrade = getObj()->tempOwner == LOCPLINT->playerID && pom.oldID>=0; //upgrade is possible
+	bool canUpgrade = getObj()->tempOwner == LOCPLINT->playerID && pom.oldID != CreatureID::NONE; //upgrade is possible
 	std::function<void(CreatureID)> upgr = nullptr;
 	auto dism = getDismiss();
 	if(canUpgrade) upgr = [=] (CreatureID newID) { LOCPLINT->cb->upgradeCreature(getObj(), ID, newID); };

+ 14 - 12
client/windows/CCastleInterface.cpp

@@ -651,7 +651,7 @@ const CGHeroInstance * CCastleBuildings::getHero()
 		return town->garrisonHero;
 }
 
-void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuildingSubID subID, BuildingID::EBuildingID upgrades)
+void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuildingSubID subID, BuildingID upgrades)
 {
 	logGlobal->trace("You've clicked on %d", (int)building.toEnum());
 	const CBuilding *b = town->town->buildings.find(building)->second;
@@ -876,7 +876,7 @@ void CCastleBuildings::enterToTheQuickRecruitmentWindow()
 		CInfoWindow::showInfoDialog(CGI->generaltexth->translate("vcmi.townHall.noCreaturesToRecruit"), {});
 }
 
-void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID::EBuildingID upgrades)
+void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID upgrades)
 {
 	std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(CComponent::building,town->subID,building));
 	std::string descr = town->town->buildings.find(building)->second->getDescriptionTranslated();
@@ -1351,9 +1351,9 @@ CHallInterface::CBuildingBox::CBuildingBox(int x, int y, const CGTownInstance *
 	};
 
 	icon = std::make_shared<CAnimImage>(town->town->clientInfo.buildingsIcons, building->bid, 0, 2, 2);
-	header = std::make_shared<CAnimImage>("TPTHBAR", panelIndex[state], 0, 1, 73);
-	if(iconIndex[state] >=0)
-		mark = std::make_shared<CAnimImage>("TPTHCHK", iconIndex[state], 0, 136, 56);
+	header = std::make_shared<CAnimImage>("TPTHBAR", panelIndex[static_cast<int>(state)], 0, 1, 73);
+	if(iconIndex[static_cast<int>(state)] >=0)
+		mark = std::make_shared<CAnimImage>("TPTHCHK", iconIndex[static_cast<int>(state)], 0, 136, 56);
 	name = std::make_shared<CLabel>(75, 81, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, building->getNameTranslated());
 
 	//todo: add support for all possible states
@@ -1371,7 +1371,7 @@ void CHallInterface::CBuildingBox::hover(bool on)
 		else if(state==EBuildingState::CANT_BUILD_TODAY)
 			toPrint = CGI->generaltexth->allTexts[223];
 		else
-			toPrint = CGI->generaltexth->hcommands[state];
+			toPrint = CGI->generaltexth->hcommands[static_cast<int>(state)];
 		boost::algorithm::replace_first(toPrint,"%s",building->getNameTranslated());
 		GH.statusbar()->write(toPrint);
 	}
@@ -1439,7 +1439,7 @@ CHallInterface::CHallInterface(const CGTownInstance * Town):
 	}
 }
 
-CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Building, int state, bool rightClick):
+CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Building, EBuildingState state, bool rightClick):
 	CStatusbarWindow(PLAYER_COLORED | (rightClick ? RCLICK_POPUP : 0), "TPUBUILD"),
 	town(Town),
 	building(Building)
@@ -1482,7 +1482,7 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
 
 		buy = std::make_shared<CButton>(Point(45, 446), "IBUY30", CButton::tooltip(tooltipYes.toString()), [&](){ buyFunc(); }, EShortcut::GLOBAL_ACCEPT);
 		buy->setBorderColor(Colors::METALLIC_GOLD);
-		buy->block(state!=7 || LOCPLINT->playerID != town->tempOwner);
+		buy->block(state!=EBuildingState::ALLOWED || LOCPLINT->playerID != town->tempOwner);
 
 		cancel = std::make_shared<CButton>(Point(290, 445), "ICANCEL", CButton::tooltip(tooltipNo.toString()), [&](){ close();}, EShortcut::GLOBAL_CANCEL);
 		cancel->setBorderColor(Colors::METALLIC_GOLD);
@@ -1495,11 +1495,11 @@ void CBuildWindow::buyFunc()
 	GH.windows().popWindows(2); //we - build window and hall screen
 }
 
-std::string CBuildWindow::getTextForState(int state)
+std::string CBuildWindow::getTextForState(EBuildingState state)
 {
 	std::string ret;
 	if(state < EBuildingState::ALLOWED)
-		ret =  CGI->generaltexth->hcommands[state];
+		ret =  CGI->generaltexth->hcommands[static_cast<int>(state)];
 	switch (state)
 	{
 	case EBuildingState::ALREADY_PRESENT:
@@ -1613,7 +1613,9 @@ CFortScreen::CFortScreen(const CGTownInstance * town):
 		BuildingID buildingID;
 		if(fortSize == GameConstants::CREATURES_PER_TOWN)
 		{
-			if(vstd::contains(town->builtBuildings, BuildingID::DWELL_UP_FIRST+i))
+			BuildingID dwelling = BuildingID::DWELL_UP_FIRST+i;
+
+			if(vstd::contains(town->builtBuildings, dwelling))
 				buildingID = BuildingID(BuildingID::DWELL_UP_FIRST+i);
 			else
 				buildingID = BuildingID(BuildingID::DWELL_FIRST+i);
@@ -1718,7 +1720,7 @@ const CCreature * CFortScreen::RecruitArea::getMyCreature()
 
 const CBuilding * CFortScreen::RecruitArea::getMyBuilding()
 {
-	BuildingID myID = BuildingID(BuildingID::DWELL_FIRST).advance(level);
+	BuildingID myID = BuildingID(BuildingID::DWELL_FIRST + level);
 
 	if (level == GameConstants::CREATURES_PER_TOWN)
 		return town->town->getSpecialBuilding(BuildingSubID::PORTAL_OF_SUMMONING);

+ 5 - 5
client/windows/CCastleInterface.h

@@ -152,7 +152,7 @@ class CCastleBuildings : public CIntObject
 	void enterBlacksmith(ArtifactID artifactID);//support for blacksmith + ballista yard
 	void enterBuilding(BuildingID building);//for buildings with simple description + pic left-click messages
 	void enterCastleGate();
-	void enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID::EBuildingID upgrades);//Rampart's fountains
+	void enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID upgrades);//Rampart's fountains
 	void enterMagesGuild();
 	void enterTownHall();
 
@@ -169,7 +169,7 @@ public:
 	void enterDwelling(int level);
 	void enterToTheQuickRecruitmentWindow();
 
-	void buildingClicked(BuildingID building, BuildingSubID::EBuildingSubID subID = BuildingSubID::NONE, BuildingID::EBuildingID upgrades = BuildingID::NONE);
+	void buildingClicked(BuildingID building, BuildingSubID::EBuildingSubID subID = BuildingSubID::NONE, BuildingID upgrades = BuildingID::NONE);
 	void addBuilding(BuildingID building);
 	void removeBuilding(BuildingID building);//FIXME: not tested!!!
 };
@@ -265,7 +265,7 @@ class CHallInterface : public CStatusbarWindow
 		const CGTownInstance * town;
 		const CBuilding * building;
 
-		ui32 state;//Buildings::EBuildStructure enum
+		EBuildingState state;
 
 		std::shared_ptr<CAnimImage> header;
 		std::shared_ptr<CAnimImage> icon;
@@ -303,10 +303,10 @@ class CBuildWindow: public CStatusbarWindow
 	std::shared_ptr<CButton> buy;
 	std::shared_ptr<CButton> cancel;
 
-	std::string getTextForState(int state);
+	std::string getTextForState(EBuildingState state);
 	void buyFunc();
 public:
-	CBuildWindow(const CGTownInstance *Town, const CBuilding * building, int State, bool rightClick);
+	CBuildWindow(const CGTownInstance *Town, const CBuilding * building, EBuildingState State, bool rightClick);
 };
 
 //Small class to display

+ 1 - 1
client/windows/CHeroWindow.cpp

@@ -222,7 +222,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
 	//primary skills support
 	for(size_t g=0; g<primSkillAreas.size(); ++g)
 	{
-		primSkillAreas[g]->bonusValue = curHero->getPrimSkillLevel(static_cast<PrimarySkill::PrimarySkill>(g));
+		primSkillAreas[g]->bonusValue = curHero->getPrimSkillLevel(static_cast<PrimarySkill>(g));
 		primSkillValues[g]->setText(std::to_string(primSkillAreas[g]->bonusValue));
 	}
 

+ 1 - 1
client/windows/CKingdomInterface.cpp

@@ -315,7 +315,7 @@ si64 InfoBoxHeroData::getValue()
 	switch(type)
 	{
 	case HERO_PRIMARY_SKILL:
-		return hero->getPrimSkillLevel(static_cast<PrimarySkill::PrimarySkill>(index));
+		return hero->getPrimSkillLevel(static_cast<PrimarySkill>(index));
 	case HERO_MANA:
 		return hero->mana;
 	case HERO_EXPERIENCE:

+ 6 - 6
client/windows/CTradeWindow.cpp

@@ -317,7 +317,7 @@ void CTradeWindow::CTradeableItem::setArtInstance(const CArtifactInstance *art)
 		setID(-1);
 }
 
-CTradeWindow::CTradeWindow(std::string bgName, const IMarket *Market, const CGHeroInstance *Hero, EMarketMode::EMarketMode Mode):
+CTradeWindow::CTradeWindow(std::string bgName, const IMarket *Market, const CGHeroInstance *Hero, EMarketMode Mode):
 	CWindowObject(PLAYER_COLORED, bgName),
 	market(Market),
 	hero(Hero),
@@ -585,7 +585,7 @@ void CTradeWindow::getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toR
 			toRemove.insert(item);
 }
 
-void CTradeWindow::setMode(EMarketMode::EMarketMode Mode)
+void CTradeWindow::setMode(EMarketMode Mode)
 {
 	const IMarket *m = market;
 	const CGHeroInstance *h = hero;
@@ -616,7 +616,7 @@ void CTradeWindow::artifactSelected(CHeroArtPlace *slot)
 	selectionChanged(true);
 }
 
-std::string CMarketplaceWindow::getBackgroundForMode(EMarketMode::EMarketMode mode)
+std::string CMarketplaceWindow::getBackgroundForMode(EMarketMode mode)
 {
 	switch(mode)
 	{
@@ -635,7 +635,7 @@ std::string CMarketplaceWindow::getBackgroundForMode(EMarketMode::EMarketMode mo
 	return "";
 }
 
-CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInstance * Hero, EMarketMode::EMarketMode Mode)
+CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInstance * Hero, EMarketMode Mode)
 	: CTradeWindow(getBackgroundForMode(Mode), Market, Hero, Mode)
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
@@ -870,7 +870,7 @@ void CMarketplaceWindow::selectionChanged(bool side)
 	redraw();
 }
 
-bool CMarketplaceWindow::printButtonFor(EMarketMode::EMarketMode M) const
+bool CMarketplaceWindow::printButtonFor(EMarketMode M) const
 {
 	return market->allowsTrade(M) && M != mode && (hero || ( M != EMarketMode::CREATURE_RESOURCE && M != EMarketMode::RESOURCE_ARTIFACT && M != EMarketMode::ARTIFACT_RESOURCE ));
 }
@@ -1075,7 +1075,7 @@ void CMarketplaceWindow::updateTraderText()
 	traderText->setText(CGI->generaltexth->allTexts[gnrtxtnr]);
 }
 
-CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, EMarketMode::EMarketMode Mode)
+CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, EMarketMode Mode)
 	: CTradeWindow((Mode == EMarketMode::CREATURE_EXP ? "ALTARMON.bmp" : "ALTRART2.bmp"), Market, Hero, Mode)
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);

+ 7 - 7
client/windows/CTradeWindow.h

@@ -75,7 +75,7 @@ public:
 	std::shared_ptr<CTradeableItem> hRight;
 	EType itemsType[2];
 
-	EMarketMode::EMarketMode mode;
+	EMarketMode mode;
 	std::shared_ptr<CButton> ok;
 	std::shared_ptr<CButton> max;
 	std::shared_ptr<CButton> deal;
@@ -83,7 +83,7 @@ public:
 	std::shared_ptr<CSlider> slider; //for choosing amount to be exchanged
 	bool readyToTrade;
 
-	CTradeWindow(std::string bgName, const IMarket * Market, const CGHeroInstance * Hero, EMarketMode::EMarketMode Mode); //c
+	CTradeWindow(std::string bgName, const IMarket * Market, const CGHeroInstance * Hero, EMarketMode Mode); //c
 
 	void showAll(Canvas & to) override;
 
@@ -95,7 +95,7 @@ public:
 	void removeItems(const std::set<std::shared_ptr<CTradeableItem>> & toRemove);
 	void removeItem(std::shared_ptr<CTradeableItem> item);
 	void getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove);
-	void setMode(EMarketMode::EMarketMode Mode); //mode setter
+	void setMode(EMarketMode Mode); //mode setter
 
 	void artifactSelected(CHeroArtPlace *slot); //used when selling artifacts -> called when user clicked on artifact slot
 
@@ -118,9 +118,9 @@ class CMarketplaceWindow : public CTradeWindow
 	std::shared_ptr<CLabel> titleLabel;
 	std::shared_ptr<CArtifactsOfHeroMarket> arts;
 
-	bool printButtonFor(EMarketMode::EMarketMode M) const;
+	bool printButtonFor(EMarketMode M) const;
 
-	std::string getBackgroundForMode(EMarketMode::EMarketMode mode);
+	std::string getBackgroundForMode(EMarketMode mode);
 public:
 	int r1, r2; //suggested amounts of traded resources
 	bool madeTransaction; //if player made at least one transaction
@@ -130,7 +130,7 @@ public:
 	void sliderMoved(int to);
 	void makeDeal();
 	void selectionChanged(bool side) override; //true == left
-	CMarketplaceWindow(const IMarket * Market, const CGHeroInstance * Hero = nullptr, EMarketMode::EMarketMode Mode = EMarketMode::RESOURCE_RESOURCE);
+	CMarketplaceWindow(const IMarket * Market, const CGHeroInstance * Hero = nullptr, EMarketMode Mode = EMarketMode::RESOURCE_RESOURCE);
 	~CMarketplaceWindow();
 
 	Point selectionOffset(bool Left) const override;
@@ -157,7 +157,7 @@ public:
 	std::shared_ptr<CLabel> expOnAltar;
 	std::shared_ptr<CArtifactsOfHeroAltar> arts;
 
-	CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, EMarketMode::EMarketMode Mode);
+	CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, EMarketMode Mode);
 	~CAltarWindow();
 
 	void getExpValues();

+ 5 - 5
client/windows/GUIClasses.cpp

@@ -400,7 +400,7 @@ void CSplitWindow::sliderMoved(int to)
 	setAmount(rightMin + to, false);
 }
 
-CLevelWindow::CLevelWindow(const CGHeroInstance * hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> & skills, std::function<void(ui32)> callback)
+CLevelWindow::CLevelWindow(const CGHeroInstance * hero, PrimarySkill pskill, std::vector<SecondarySkill> & skills, std::function<void(ui32)> callback)
 	: CWindowObject(PLAYER_COLORED, "LVLUPBKG"),
 	cb(callback)
 {
@@ -434,9 +434,9 @@ CLevelWindow::CLevelWindow(const CGHeroInstance * hero, PrimarySkill::PrimarySki
 
 	levelTitle = std::make_shared<CLabel>(192, 162, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, levelTitleText);
 
-	skillIcon = std::make_shared<CAnimImage>("PSKIL42", pskill, 0, 174, 190);
+	skillIcon = std::make_shared<CAnimImage>("PSKIL42", static_cast<int>(pskill), 0, 174, 190);
 
-	skillValue = std::make_shared<CLabel>(192, 253, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->primarySkillNames[pskill] + " +1");
+	skillValue = std::make_shared<CLabel>(192, 253, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->primarySkillNames[static_cast<int>(pskill)] + " +1");
 }
 
 
@@ -1029,7 +1029,7 @@ void CExchangeWindow::updateWidgets()
 
 		for(int m=0; m<GameConstants::PRIMARY_SKILLS; ++m)
 		{
-			auto value = heroInst[leftRight]->getPrimSkillLevel(static_cast<PrimarySkill::PrimarySkill>(m));
+			auto value = heroInst[leftRight]->getPrimSkillLevel(static_cast<PrimarySkill>(m));
 			primSkillValues[leftRight][m]->setText(std::to_string(value));
 		}
 
@@ -1711,7 +1711,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner):
 		}
 		else if(it.second != EAiTactic::RANDOM)
 		{
-			text = CGI->generaltexth->arraytxt[168 + it.second];
+			text = CGI->generaltexth->arraytxt[168 + static_cast<int>(it.second)];
 		}
 
 		personalities.push_back(std::make_shared<CLabel>(283 + 66*counter, 459, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, text));

+ 1 - 1
client/windows/GUIClasses.h

@@ -145,7 +145,7 @@ class CLevelWindow : public CWindowObject
 	void selectionChanged(unsigned to);
 
 public:
-	CLevelWindow(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, std::function<void(ui32)> callback);
+	CLevelWindow(const CGHeroInstance *hero, PrimarySkill pskill, std::vector<SecondarySkill> &skills, std::function<void(ui32)> callback);
 	~CLevelWindow();
 };
 

+ 7 - 2
cmake_modules/VCMI_lib.cmake

@@ -42,6 +42,8 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
 		${MAIN_LIB_DIR}/campaign/CampaignHandler.cpp
 		${MAIN_LIB_DIR}/campaign/CampaignState.cpp
 
+		${MAIN_LIB_DIR}/constants/EntityIdentifiers.cpp
+
 		${MAIN_LIB_DIR}/events/ApplyDamage.cpp
 		${MAIN_LIB_DIR}/events/GameResumed.cpp
 		${MAIN_LIB_DIR}/events/ObjectVisitEnded.cpp
@@ -246,7 +248,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
 		${MAIN_LIB_DIR}/CStack.cpp
 		${MAIN_LIB_DIR}/CThreadHelper.cpp
 		${MAIN_LIB_DIR}/CTownHandler.cpp
-		${MAIN_LIB_DIR}/GameConstants.cpp
 		${MAIN_LIB_DIR}/GameSettings.cpp
 		${MAIN_LIB_DIR}/IGameCallback.cpp
 		${MAIN_LIB_DIR}/IHandlerBase.cpp
@@ -369,6 +370,11 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
 		${MAIN_LIB_DIR}/campaign/CampaignScenarioPrologEpilog.h
 		${MAIN_LIB_DIR}/campaign/CampaignState.h
 
+		${MAIN_LIB_DIR}/constants/EntityIdentifiers.h
+		${MAIN_LIB_DIR}/constants/Enumerations.h
+		${MAIN_LIB_DIR}/constants/NumericConstants.h
+		${MAIN_LIB_DIR}/constants/StringConstants.h
+
 		${MAIN_LIB_DIR}/events/ApplyDamage.h
 		${MAIN_LIB_DIR}/events/GameResumed.h
 		${MAIN_LIB_DIR}/events/ObjectVisitEnded.h
@@ -621,7 +627,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
 		${MAIN_LIB_DIR}/ScriptHandler.h
 		${MAIN_LIB_DIR}/ScopeGuard.h
 		${MAIN_LIB_DIR}/StartInfo.h
-		${MAIN_LIB_DIR}/StringConstants.h
 		${MAIN_LIB_DIR}/TerrainHandler.h
 		${MAIN_LIB_DIR}/TextOperations.h
 		${MAIN_LIB_DIR}/TurnTimerInfo.h

+ 2 - 2
include/vcmi/Creature.h

@@ -16,7 +16,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 
 class CreatureID;
 class ResourceSet;
-enum class EGameResID : int8_t;
+class GameResID;
 
 /// Base class for creatures and battle stacks
 class DLL_LINKAGE ACreature: public AFactionMember
@@ -63,7 +63,7 @@ public:
 	virtual int32_t getBaseSpeed() const = 0;
 	virtual int32_t getBaseShots() const = 0;
 
-	virtual int32_t getRecruitCost(Identifier<EGameResID> resIndex) const = 0;
+	virtual int32_t getRecruitCost(GameResID resIndex) const = 0;
 	virtual ResourceSet getFullRecruitCost() const = 0;
 	
 	virtual bool hasUpgrades() const = 0;

+ 3 - 4
include/vcmi/Entity.h

@@ -14,8 +14,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 
 class IBonusBearer;
 class FactionID;
-enum class ETerrainId;
-template<typename T> class Identifier;
+class TerrainId;
 
 class DLL_LINKAGE IConstBonusProvider
 {
@@ -26,9 +25,9 @@ public:
 class DLL_LINKAGE INativeTerrainProvider
 {
 public:
-	virtual Identifier<ETerrainId> getNativeTerrain() const = 0;
+	virtual TerrainId getNativeTerrain() const = 0;
 	virtual FactionID getFaction() const = 0;
-	virtual bool isNativeTerrain(Identifier<ETerrainId> terrain) const;
+	virtual bool isNativeTerrain(TerrainId terrain) const;
 };
 
 class DLL_LINKAGE Entity

+ 3 - 3
include/vcmi/Faction.h

@@ -15,15 +15,15 @@
 VCMI_LIB_NAMESPACE_BEGIN
 
 class FactionID;
-enum class EAlignment : uint8_t;
-enum class EBoatId : int32_t;
+enum class EAlignment : int8_t;
+class BoatId;
 
 class DLL_LINKAGE Faction : public EntityT<FactionID>, public INativeTerrainProvider
 {
 public:
 	virtual bool hasTown() const = 0;
 	virtual EAlignment getAlignment() const = 0;
-	virtual EBoatId getBoatType() const = 0;
+	virtual BoatId getBoatType() const = 0;
 };
 
 VCMI_LIB_NAMESPACE_END

+ 4 - 8
include/vcmi/FactionMember.h

@@ -15,11 +15,7 @@
 VCMI_LIB_NAMESPACE_BEGIN
 
 class BonusList;
-
-namespace PrimarySkill
-{
-    enum PrimarySkill : int8_t;
-}
+enum class PrimarySkill : int8_t;
 
 class DLL_LINKAGE AFactionMember: public IConstBonusProvider, public INativeTerrainProvider
 {
@@ -27,7 +23,7 @@ public:
 	/**
 	 Returns native terrain considering some terrain bonuses.
 	*/
-	virtual Identifier<ETerrainId> getNativeTerrain() const;
+	virtual TerrainId getNativeTerrain() const;
 	/**
 	 Returns magic resistance considering some bonuses.
 	*/
@@ -51,7 +47,7 @@ public:
 	/**
 	 Returns primskill of creature or hero.
 	*/
-	int getPrimSkillLevel(PrimarySkill::PrimarySkill id) const;
+	int getPrimSkillLevel(PrimarySkill id) const;
 	/**
 	 Returns morale of creature or hero. Taking absolute bonuses into account.
 	 For now, uses range from EGameSettings
@@ -71,4 +67,4 @@ public:
 	int luckValAndBonusList(std::shared_ptr<const BonusList> & bonusList) const;
 };
 
-VCMI_LIB_NAMESPACE_END
+VCMI_LIB_NAMESPACE_END

+ 3 - 3
include/vcmi/spells/Spell.h

@@ -15,7 +15,7 @@
 VCMI_LIB_NAMESPACE_BEGIN
 
 class SpellID;
-enum class ESpellSchool: int8_t;
+class SpellSchool;
 
 namespace spells
 {
@@ -24,7 +24,7 @@ class Caster;
 class DLL_LINKAGE Spell: public EntityT<SpellID>
 {
 public:
-	using SchoolCallback = std::function<void(const Identifier<ESpellSchool> &, bool &)>;
+	using SchoolCallback = std::function<void(const SpellSchool &, bool &)>;
 
 	///calculate spell damage on stack taking caster`s secondary skills into account
 	virtual int64_t calculateDamage(const Caster * caster) const = 0;
@@ -43,7 +43,7 @@ public:
 	virtual bool isSpecial() const = 0;
 	virtual bool isMagical() const = 0; //Should this spell considered as magical effect or as ability (like dendroid's bind)
 
-	virtual bool hasSchool(Identifier<ESpellSchool> school) const = 0;
+	virtual bool hasSchool(SpellSchool school) const = 0;
 	virtual void forEachSchool(const SchoolCallback & cb) const = 0;
 	virtual const std::string & getCastSound() const = 0;
 	virtual int32_t getCost(const int32_t skillLevel) const = 0;

+ 12 - 12
lib/ArtifactUtils.cpp

@@ -33,16 +33,16 @@ DLL_LINKAGE ArtifactPosition ArtifactUtils::getArtAnyPosition(const CArtifactSet
 DLL_LINKAGE ArtifactPosition ArtifactUtils::getArtBackpackPosition(const CArtifactSet * target, const ArtifactID & aid)
 {
 	const auto * art = aid.toArtifact();
-	if(art->canBePutAt(target, GameConstants::BACKPACK_START))
+	if(art->canBePutAt(target, ArtifactPosition::BACKPACK_START))
 	{
-		return GameConstants::BACKPACK_START;
+		return ArtifactPosition::BACKPACK_START;
 	}
 	return ArtifactPosition::PRE_FIRST;
 }
 
-DLL_LINKAGE const std::vector<ArtifactPosition::EArtifactPosition> & ArtifactUtils::unmovableSlots()
+DLL_LINKAGE const std::vector<ArtifactPosition> & ArtifactUtils::unmovableSlots()
 {
-	static const std::vector<ArtifactPosition::EArtifactPosition> positions =
+	static const std::vector<ArtifactPosition> positions =
 	{
 		ArtifactPosition::SPELLBOOK,
 		ArtifactPosition::MACH4
@@ -51,9 +51,9 @@ DLL_LINKAGE const std::vector<ArtifactPosition::EArtifactPosition> & ArtifactUti
 	return positions;
 }
 
-DLL_LINKAGE const std::vector<ArtifactPosition::EArtifactPosition> & ArtifactUtils::constituentWornSlots()
+DLL_LINKAGE const std::vector<ArtifactPosition> & ArtifactUtils::constituentWornSlots()
 {
-	static const std::vector<ArtifactPosition::EArtifactPosition> positions =
+	static const std::vector<ArtifactPosition> positions =
 	{
 		ArtifactPosition::HEAD,
 		ArtifactPosition::SHOULDERS,
@@ -98,12 +98,12 @@ DLL_LINKAGE bool ArtifactUtils::checkSpellbookIsNeeded(const CGHeroInstance * he
 
 DLL_LINKAGE bool ArtifactUtils::isSlotBackpack(const ArtifactPosition & slot)
 {
-	return slot >= GameConstants::BACKPACK_START;
+	return slot >= ArtifactPosition::BACKPACK_START;
 }
 
 DLL_LINKAGE bool ArtifactUtils::isSlotEquipment(const ArtifactPosition & slot)
 {
-	return slot < GameConstants::BACKPACK_START && slot >= 0;
+	return slot < ArtifactPosition::BACKPACK_START && slot >= ArtifactPosition(0);
 }
 
 DLL_LINKAGE bool ArtifactUtils::isBackpackFreeSlots(const CArtifactSet * target, const size_t reqSlots)
@@ -190,18 +190,18 @@ DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(const A
 	return ArtifactUtils::createNewArtifactInstance(VLC->arth->objects[aid]);
 }
 
-DLL_LINKAGE CArtifactInstance * ArtifactUtils::createArtifact(CMap * map, const ArtifactID & aid, int spellID)
+DLL_LINKAGE CArtifactInstance * ArtifactUtils::createArtifact(CMap * map, const ArtifactID & aid, SpellID spellID)
 {
 	CArtifactInstance * art = nullptr;
-	if(aid >= 0)
+	if(aid.getNum() >= 0)
 	{
-		if(spellID < 0)
+		if(spellID == SpellID::NONE)
 		{
 			art = ArtifactUtils::createNewArtifactInstance(aid);
 		}
 		else
 		{
-			art = ArtifactUtils::createScroll(SpellID(spellID));
+			art = ArtifactUtils::createScroll(spellID);
 		}
 	}
 	else

+ 3 - 3
lib/ArtifactUtils.h

@@ -29,8 +29,8 @@ namespace ArtifactUtils
 	DLL_LINKAGE ArtifactPosition getArtAnyPosition(const CArtifactSet * target, const ArtifactID & aid);
 	DLL_LINKAGE ArtifactPosition getArtBackpackPosition(const CArtifactSet * target, const ArtifactID & aid);
 	// TODO: Make this constexpr when the toolset is upgraded
-	DLL_LINKAGE const std::vector<ArtifactPosition::EArtifactPosition> & unmovableSlots();
-	DLL_LINKAGE const std::vector<ArtifactPosition::EArtifactPosition> & constituentWornSlots();
+	DLL_LINKAGE const std::vector<ArtifactPosition> & unmovableSlots();
+	DLL_LINKAGE const std::vector<ArtifactPosition> & constituentWornSlots();
 	DLL_LINKAGE bool isArtRemovable(const std::pair<ArtifactPosition, ArtSlotInfo> & slot);
 	DLL_LINKAGE bool checkSpellbookIsNeeded(const CGHeroInstance * heroPtr, const ArtifactID & artID, const ArtifactPosition & slot);
 	DLL_LINKAGE bool isSlotBackpack(const ArtifactPosition & slot);
@@ -40,7 +40,7 @@ namespace ArtifactUtils
 	DLL_LINKAGE CArtifactInstance * createScroll(const SpellID & sid);
 	DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(CArtifact * art);
 	DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const ArtifactID & aid);
-	DLL_LINKAGE CArtifactInstance * createArtifact(CMap * map, const ArtifactID & aid, int spellID = -1);
+	DLL_LINKAGE CArtifactInstance * createArtifact(CMap * map, const ArtifactID & aid, SpellID spellID = SpellID::NONE);
 	DLL_LINKAGE void insertScrrollSpellName(std::string & description, const SpellID & sid);
 }
 

+ 5 - 5
lib/BasicTypes.cpp

@@ -54,7 +54,7 @@ int AFactionMember::getAttack(bool ranged) const
 {
 	const std::string cachingStr = "type_PRIMARY_SKILLs_ATTACK";
 
-	static const auto selector = Selector::typeSubtype(BonusType::PRIMARY_SKILL, PrimarySkill::ATTACK);
+	static const auto selector = Selector::typeSubtype(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::ATTACK));
 
 	return getBonusBearer()->valOfBonuses(selector, cachingStr);
 }
@@ -63,7 +63,7 @@ int AFactionMember::getDefense(bool ranged) const
 {
 	const std::string cachingStr = "type_PRIMARY_SKILLs_DEFENSE";
 
-	static const auto selector = Selector::typeSubtype(BonusType::PRIMARY_SKILL, PrimarySkill::DEFENSE);
+	static const auto selector = Selector::typeSubtype(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::DEFENSE));
 
 	return getBonusBearer()->valOfBonuses(selector, cachingStr);
 }
@@ -82,12 +82,12 @@ int AFactionMember::getMaxDamage(bool ranged) const
 	return getBonusBearer()->valOfBonuses(selector, cachingStr);
 }
 
-int AFactionMember::getPrimSkillLevel(PrimarySkill::PrimarySkill id) const
+int AFactionMember::getPrimSkillLevel(PrimarySkill id) const
 {
 	static const CSelector selectorAllSkills = Selector::type()(BonusType::PRIMARY_SKILL);
 	static const std::string keyAllSkills = "type_PRIMARY_SKILL";
 	auto allSkills = getBonusBearer()->getBonuses(selectorAllSkills, keyAllSkills);
-	auto ret = allSkills->valOfBonuses(Selector::subtype()(id));
+	auto ret = allSkills->valOfBonuses(Selector::subtype()(static_cast<int>(id)));
 	auto minSkillValue = (id == PrimarySkill::SPELL_POWER || id == PrimarySkill::KNOWLEDGE) ? 1 : 0;
 	return std::max(ret, minSkillValue); //otherwise, some artifacts may cause negative skill value effect, sp=0 works in old saves
 }
@@ -183,4 +183,4 @@ bool ACreature::isLiving() const //TODO: theoreticaly there exists "LIVING" bonu
 }
 
 
-VCMI_LIB_NAMESPACE_END
+VCMI_LIB_NAMESPACE_END

+ 14 - 15
lib/CArtHandler.cpp

@@ -15,7 +15,7 @@
 #include "CGeneralTextHandler.h"
 #include "GameSettings.h"
 #include "mapObjects/MapObjects.h"
-#include "StringConstants.h"
+#include "constants/StringConstants.h"
 
 #include "mapObjectConstructors/AObjectTypeHandler.h"
 #include "mapObjectConstructors/CObjectClassesHandler.h"
@@ -239,11 +239,11 @@ bool CArtifact::canBePutAt(const CArtifactSet * artSet, ArtifactPosition slot, b
 			if(artCanBePutAt(artSet, slot, assumeDestRemoved))
 				return true;
 		}
-		return artCanBePutAt(artSet, GameConstants::BACKPACK_START, assumeDestRemoved);
+		return artCanBePutAt(artSet, ArtifactPosition::BACKPACK_START, assumeDestRemoved);
 	}
 	else if(ArtifactUtils::isSlotBackpack(slot))
 	{
-		return artCanBePutAt(artSet, GameConstants::BACKPACK_START, assumeDestRemoved);
+		return artCanBePutAt(artSet, ArtifactPosition::BACKPACK_START, assumeDestRemoved);
 	}
 	else
 	{
@@ -483,17 +483,16 @@ CArtifact * CArtHandler::loadFromJson(const std::string & scope, const JsonNode
 	return art;
 }
 
-ArtifactPosition::ArtifactPosition(std::string slotName):
-	num(ArtifactPosition::PRE_FIRST)
+int32_t ArtifactPositionBase::decode(const std::string & slotName)
 {
 #define ART_POS(x) { #x, ArtifactPosition::x },
 	static const std::map<std::string, ArtifactPosition> artifactPositionMap = { ART_POS_LIST };
 #undef ART_POS
 	auto it = artifactPositionMap.find (slotName);
 	if (it != artifactPositionMap.end())
-		num = it->second;
+		return it->second;
 	else
-		logMod->warn("Warning! Artifact slot %s not recognized!", slotName);
+		return PRE_FIRST;
 }
 
 void CArtHandler::addSlot(CArtifact * art, const std::string & slotID) const
@@ -518,7 +517,7 @@ void CArtHandler::addSlot(CArtifact * art, const std::string & slotID) const
 	}
 	else
 	{
-		auto slot = ArtifactPosition(slotID);
+		auto slot = ArtifactPosition::decode(slotID);
 		if (slot != ArtifactPosition::PRE_FIRST)
 			art->possibleSlots[ArtBearer::HERO].push_back(slot);
 	}
@@ -848,7 +847,7 @@ std::vector<ArtifactPosition> CArtifactSet::getBackpackArtPositions(const Artifa
 {
 	std::vector<ArtifactPosition> result;
 
-	si32 backpackPosition = GameConstants::BACKPACK_START;
+	si32 backpackPosition = ArtifactPosition::BACKPACK_START;
 	for(const auto & artInfo : artifactsInBackpack)
 	{
 		const auto * art = artInfo.getArt();
@@ -867,7 +866,7 @@ ArtifactPosition CArtifactSet::getArtPos(const CArtifactInstance *art) const
 
 	for(int i = 0; i < artifactsInBackpack.size(); i++)
 		if(artifactsInBackpack[i].artifact == art)
-			return ArtifactPosition(GameConstants::BACKPACK_START + i);
+			return ArtifactPosition::BACKPACK_START + i;
 
 	return ArtifactPosition::PRE_FIRST;
 }
@@ -893,7 +892,7 @@ const ArtifactPosition CArtifactSet::getSlotByInstance(const CArtifactInstance *
 			if(getArt(slot) == artInst)
 				return slot;
 
-		auto backpackSlot = GameConstants::BACKPACK_START;
+		ArtifactPosition backpackSlot = ArtifactPosition::BACKPACK_START;
 		for(auto & slotInfo : artifactsInBackpack)
 		{
 			if(slotInfo.getArt() == artInst)
@@ -1014,7 +1013,7 @@ const ArtSlotInfo * CArtifactSet::getSlot(const ArtifactPosition & pos) const
 		return &artifactsWorn.at(pos);
 	if(pos >= ArtifactPosition::AFTER_LAST )
 	{
-		int backpackPos = (int)pos - GameConstants::BACKPACK_START;
+		int backpackPos = (int)pos - ArtifactPosition::BACKPACK_START;
 		if(backpackPos < 0 || backpackPos >= artifactsInBackpack.size())
 			return nullptr;
 		else
@@ -1049,7 +1048,7 @@ void CArtifactSet::setNewArtSlot(const ArtifactPosition & slot, CArtifactInstanc
 	}
 	else
 	{
-		auto position = artifactsInBackpack.begin() + slot - GameConstants::BACKPACK_START;
+		auto position = artifactsInBackpack.begin() + slot - ArtifactPosition::BACKPACK_START;
 		slotInfo = &(*artifactsInBackpack.emplace(position, ArtSlotInfo()));
 	}
 	slotInfo->artifact = art;
@@ -1065,7 +1064,7 @@ void CArtifactSet::eraseArtSlot(const ArtifactPosition & slot)
 	}
 	else if(ArtifactUtils::isSlotBackpack(slot))
 	{
-		auto backpackSlot = ArtifactPosition(slot - GameConstants::BACKPACK_START);
+		auto backpackSlot = ArtifactPosition(slot - ArtifactPosition::BACKPACK_START);
 
 		assert(artifactsInBackpack.begin() + backpackSlot < artifactsInBackpack.end());
 		artifactsInBackpack.erase(artifactsInBackpack.begin() + backpackSlot);
@@ -1136,7 +1135,7 @@ void CArtifactSet::serializeJsonHero(JsonSerializeFormat & handler, CMap * map)
 		for(const ArtifactID & artifactID : backpackTemp)
 		{
 			auto * artifact = ArtifactUtils::createArtifact(map, artifactID.toEnum());
-			auto slot = ArtifactPosition(GameConstants::BACKPACK_START + (si32)artifactsInBackpack.size());
+			auto slot = ArtifactPosition::BACKPACK_START + (si32)artifactsInBackpack.size();
 			if(artifact->artType->canBePutAt(this, slot))
 				putArtifact(slot, artifact);
 		}

+ 1 - 0
lib/CArtifactInstance.h

@@ -11,6 +11,7 @@
 
 #include "bonuses/CBonusSystemNode.h"
 #include "GameConstants.h"
+#include "ConstTransitivePtr.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 

+ 26 - 35
lib/CBonusTypeHandler.cpp

@@ -101,62 +101,53 @@ std::string CBonusTypeHandler::bonusToGraphics(const std::shared_ptr<Bonus> & bo
 	}
 	case BonusType::SPELL_DAMAGE_REDUCTION: //Spell damage reduction for all schools
 	{
-		switch(bonus->subtype)
-		{
-		case SpellSchool(ESpellSchool::ANY):
+		if (bonus->subtype == SpellSchool::ANY.getNum())
 			fileName = "E_GOLEM.bmp";
-			break;	
-		case SpellSchool(ESpellSchool::AIR):
+
+		if (bonus->subtype == SpellSchool::AIR.getNum())
 			fileName = "E_LIGHT.bmp";
-			break;
-		case SpellSchool(ESpellSchool::FIRE):
+
+		if (bonus->subtype == SpellSchool::FIRE.getNum())
 			fileName = "E_FIRE.bmp";
-			break;
-		case SpellSchool(ESpellSchool::WATER):
+
+		if (bonus->subtype == SpellSchool::WATER.getNum())
 			fileName = "E_COLD.bmp";
-			break;
-		case SpellSchool(ESpellSchool::EARTH):
+
+		if (bonus->subtype == SpellSchool::EARTH.getNum())
 			fileName = "E_SPEATH1.bmp"; //No separate icon for earth damage
-			break;
-		}
+
 		break;
 	}
 	case BonusType::SPELL_SCHOOL_IMMUNITY: //for all school
 	{
-		switch(bonus->subtype)
-		{
-		case SpellSchool(ESpellSchool::AIR):
+		if (bonus->subtype == SpellSchool::AIR.getNum())
 			fileName = "E_SPAIR.bmp";
-			break;
-		case SpellSchool(ESpellSchool::FIRE):
+
+		if (bonus->subtype == SpellSchool::FIRE.getNum())
 			fileName = "E_SPFIRE.bmp";
-			break;
-		case SpellSchool(ESpellSchool::WATER):
+
+		if (bonus->subtype == SpellSchool::WATER.getNum())
 			fileName = "E_SPWATER.bmp";
-			break;
-		case SpellSchool(ESpellSchool::EARTH):
+
+		if (bonus->subtype == SpellSchool::EARTH.getNum())
 			fileName = "E_SPEATH.bmp";
-			break;
-		}
+
 		break;
 	}
 	case BonusType::NEGATIVE_EFFECTS_IMMUNITY:
 	{
-		switch(bonus->subtype)
-		{
-		case SpellSchool(ESpellSchool::AIR):
+		if (bonus->subtype == SpellSchool::AIR.getNum())
 			fileName = "E_SPAIR1.bmp";
-			break;
-		case SpellSchool(ESpellSchool::FIRE):
+
+		if (bonus->subtype == SpellSchool::FIRE.getNum())
 			fileName = "E_SPFIRE1.bmp";
-			break;
-		case SpellSchool(ESpellSchool::WATER):
+
+		if (bonus->subtype == SpellSchool::WATER.getNum())
 			fileName = "E_SPWATER1.bmp";
-			break;
-		case SpellSchool(ESpellSchool::EARTH):
+
+		if (bonus->subtype == SpellSchool::EARTH.getNum())
 			fileName = "E_SPEATH1.bmp";
-			break;
-		}
+
 		break;
 	}
 	case BonusType::LEVEL_SPELL_IMMUNITY:

+ 6 - 2
lib/CBuildingHandler.cpp

@@ -53,7 +53,9 @@ BuildingID CBuildingHandler::campToERMU(int camp, int townType, const std::set<B
 				{
 					if (hordeLvlsPerTType[townType][0] == i)
 					{
-						if(vstd::contains(builtBuildings, 37 + hordeLvlsPerTType[townType][0])) //if upgraded dwelling is built
+						BuildingID dwellingID(BuildingID::DWELL_UP_FIRST + hordeLvlsPerTType[townType][0]);
+
+						if(vstd::contains(builtBuildings, dwellingID)) //if upgraded dwelling is built
 							return BuildingID::HORDE_1_UPGR;
 						else //upgraded dwelling not presents
 							return BuildingID::HORDE_1;
@@ -62,7 +64,9 @@ BuildingID CBuildingHandler::campToERMU(int camp, int townType, const std::set<B
 					{
 						if(hordeLvlsPerTType[townType].size() > 1)
 						{
-							if(vstd::contains(builtBuildings, 37 + hordeLvlsPerTType[townType][1])) //if upgraded dwelling is built
+							BuildingID dwellingID(BuildingID::DWELL_UP_FIRST + hordeLvlsPerTType[townType][1]);
+
+							if(vstd::contains(builtBuildings, dwellingID)) //if upgraded dwelling is built
 								return BuildingID::HORDE_2_UPGR;
 							else //upgraded dwelling not presents
 								return BuildingID::HORDE_2;

+ 10 - 10
lib/CCreatureHandler.cpp

@@ -16,7 +16,7 @@
 #include "VCMI_Lib.h"
 #include "CTownHandler.h"
 #include "GameSettings.h"
-#include "StringConstants.h"
+#include "constants/StringConstants.h"
 #include "bonuses/Limiters.h"
 #include "bonuses/Updaters.h"
 #include "serializer/JsonDeserializer.h"
@@ -113,13 +113,13 @@ FactionID CCreature::getFaction() const
 
 int32_t CCreature::getBaseAttack() const
 {
-	static const auto SELECTOR = Selector::typeSubtype(BonusType::PRIMARY_SKILL, PrimarySkill::ATTACK).And(Selector::sourceTypeSel(BonusSource::CREATURE_ABILITY));
+	static const auto SELECTOR = Selector::typeSubtype(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::ATTACK)).And(Selector::sourceTypeSel(BonusSource::CREATURE_ABILITY));
 	return getExportedBonusList().valOfBonuses(SELECTOR);
 }
 
 int32_t CCreature::getBaseDefense() const
 {
-	static const auto SELECTOR = Selector::typeSubtype(BonusType::PRIMARY_SKILL, PrimarySkill::DEFENSE).And(Selector::sourceTypeSel(BonusSource::CREATURE_ABILITY));
+	static const auto SELECTOR = Selector::typeSubtype(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::DEFENSE)).And(Selector::sourceTypeSel(BonusSource::CREATURE_ABILITY));
 	return getExportedBonusList().valOfBonuses(SELECTOR);
 }
 
@@ -161,7 +161,7 @@ int32_t CCreature::getBaseShots() const
 
 int32_t CCreature::getRecruitCost(GameResID resIndex) const
 {
-	if(resIndex >= 0 && resIndex < cost.size())
+	if(resIndex.getNum() >= 0 && resIndex.getNum() < cost.size())
 		return cost[resIndex];
 	else
 		return 0;
@@ -345,10 +345,10 @@ void CCreature::updateFrom(const JsonNode & data)
 			addBonus(configNode["speed"].Integer(), BonusType::STACKS_SPEED);
 
 		if(!configNode["attack"].isNull())
-			addBonus(configNode["attack"].Integer(), BonusType::PRIMARY_SKILL, PrimarySkill::ATTACK);
+			addBonus(configNode["attack"].Integer(), BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::ATTACK));
 
 		if(!configNode["defense"].isNull())
-			addBonus(configNode["defense"].Integer(), BonusType::PRIMARY_SKILL, PrimarySkill::DEFENSE);
+			addBonus(configNode["defense"].Integer(), BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::DEFENSE));
 
 		if(!configNode["damage"]["min"].isNull())
 			addBonus(configNode["damage"]["min"].Integer(), BonusType::CREATURE_DAMAGE, 1);
@@ -603,8 +603,8 @@ CCreature * CCreatureHandler::loadFromJson(const std::string & scope, const Json
 
 	cre->addBonus(node["hitPoints"].Integer(), BonusType::STACK_HEALTH);
 	cre->addBonus(node["speed"].Integer(), BonusType::STACKS_SPEED);
-	cre->addBonus(node["attack"].Integer(), BonusType::PRIMARY_SKILL, PrimarySkill::ATTACK);
-	cre->addBonus(node["defense"].Integer(), BonusType::PRIMARY_SKILL, PrimarySkill::DEFENSE);
+	cre->addBonus(node["attack"].Integer(), BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::ATTACK));
+	cre->addBonus(node["defense"].Integer(), BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::DEFENSE));
 
 	cre->addBonus(node["damage"]["min"].Integer(), BonusType::CREATURE_DAMAGE, 1);
 	cre->addBonus(node["damage"]["max"].Integer(), BonusType::CREATURE_DAMAGE, 2);
@@ -1030,11 +1030,11 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars
 		break;
 	case 'A':
 		b.type = BonusType::PRIMARY_SKILL;
-		b.subtype = PrimarySkill::ATTACK;
+		b.subtype = static_cast<int>(PrimarySkill::ATTACK);
 		break;
 	case 'D':
 		b.type = BonusType::PRIMARY_SKILL;
-		b.subtype = PrimarySkill::DEFENSE;
+		b.subtype = static_cast<int>(PrimarySkill::DEFENSE);
 		break;
 	case 'M': //Max damage
 		b.type = BonusType::CREATURE_DAMAGE;

+ 1 - 1
lib/CCreatureSet.cpp

@@ -752,7 +752,7 @@ void CStackInstance::giveStackExp(TExpType exp)
 
 void CStackInstance::setType(const CreatureID & creID)
 {
-	if(creID >= 0 && creID < VLC->creh->objects.size())
+	if(creID.getNum() >= 0 && creID.getNum() < VLC->creh->objects.size())
 		setType(VLC->creh->objects[creID]);
 	else
 		setType((const CCreature*)nullptr);

+ 1 - 1
lib/CCreatureSet.h

@@ -55,7 +55,7 @@ public:
 			CreatureID idNumber;
 			h & idNumber;
 			if(idNumber != CreatureID::NONE)
-				setType(dynamic_cast<const CCreature*>(VLC->creatures()->getByIndex(idNumber)));
+				setType(dynamic_cast<const CCreature*>(VLC->creatures()->getById(idNumber)));
 			else
 				type = nullptr;
 		}

+ 5 - 5
lib/CGameInfoCallback.cpp

@@ -42,7 +42,7 @@ int CGameInfoCallback::getResource(PlayerColor Player, GameResID which) const
 {
 	const PlayerState *p = getPlayerState(Player);
 	ERROR_RET_VAL_IF(!p, "No player info!", -1);
-	ERROR_RET_VAL_IF(p->resources.size() <= which || which < 0, "No such resource!", -1);
+	ERROR_RET_VAL_IF(p->resources.size() <= which.getNum() || which.getNum() < 0, "No such resource!", -1);
 	return p->resources[which];
 }
 
@@ -405,7 +405,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
 	return true;
 }
 
-int CGameInfoCallback::getDate(Date::EDateType mode) const
+int CGameInfoCallback::getDate(Date mode) const
 {
 	//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
 	return gs->getDate(mode);
@@ -551,7 +551,7 @@ std::shared_ptr<const boost::multi_array<TerrainTile*, 3>> CGameInfoCallback::ge
 	return std::shared_ptr<const boost::multi_array<TerrainTile*, 3>>(ptr);
 }
 
-EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTownInstance *t, BuildingID ID )
+EBuildingState CGameInfoCallback::canBuildStructure( const CGTownInstance *t, BuildingID ID )
 {
 	ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", EBuildingState::TOWN_NOT_OWNED);
 
@@ -631,7 +631,7 @@ bool CGameInfoCallback::hasAccess(std::optional<PlayerColor> playerId) const
 	return !player || player->isSpectator() || gs->getPlayerRelations(*playerId, *player) != PlayerRelations::ENEMIES;
 }
 
-EPlayerStatus::EStatus CGameInfoCallback::getPlayerStatus(PlayerColor player, bool verbose) const
+EPlayerStatus CGameInfoCallback::getPlayerStatus(PlayerColor player, bool verbose) const
 {
 	const PlayerState *ps = gs->getPlayerState(player, verbose);
 	ERROR_VERBOSE_OR_NOT_RET_VAL_IF(!ps, verbose, "No such player!", EPlayerStatus::WRONG);
@@ -670,7 +670,7 @@ std::string CGameInfoCallback::getTavernRumor(const CGObjectInstance * townOrTav
 	return text;
 }
 
-PlayerRelations::PlayerRelations CGameInfoCallback::getPlayerRelations( PlayerColor color1, PlayerColor color2 ) const
+PlayerRelations CGameInfoCallback::getPlayerRelations( PlayerColor color1, PlayerColor color2 ) const
 {
 	return gs->getPlayerRelations(color1, color2);
 }

+ 10 - 10
lib/CGameInfoCallback.h

@@ -52,7 +52,7 @@ public:
 	//TODO: all other public methods of CGameInfoCallback
 
 //	//various
-	virtual int getDate(Date::EDateType mode=Date::DAY) const = 0; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
+	virtual int getDate(Date mode=Date::DAY) const = 0; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
 //	const StartInfo * getStartInfo(bool beforeRandomization = false)const;
 	virtual bool isAllowed(int32_t type, int32_t id) const = 0; //type: 0 - spell; 1- artifact; 2 - secondary skill
 
@@ -60,9 +60,9 @@ public:
 	virtual const Player * getPlayer(PlayerColor color) const = 0;
 //	virtual int getResource(PlayerColor Player, EGameResID which) const = 0;
 //	bool isVisible(int3 pos) const;
-//	PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const;
+//	PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const;
 //	void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object
-//	EPlayerStatus::EStatus getPlayerStatus(PlayerColor player, bool verbose = true) const; //-1 if no such player
+//	EPlayerStatus getPlayerStatus(PlayerColor player, bool verbose = true) const; //-1 if no such player
 //	PlayerColor getCurrentPlayer() const; //player that currently makes move // TODO synchronous turns
 	virtual PlayerColor getLocalPlayer() const = 0; //player that is currently owning given client (if not a client, then returns current player)
 //	const PlayerSettings * getPlayerSettings(PlayerColor color) const;
@@ -107,13 +107,13 @@ public:
 //	const CGTownInstance * getTownInfo(int val, bool mode)const; //mode = 0 -> val = player town serial; mode = 1 -> val = object id (serial)
 //	std::vector<const CGHeroInstance *> getAvailableHeroes(const CGObjectInstance * townOrTavern) const; //heroes that can be recruited
 //	std::string getTavernRumor(const CGObjectInstance * townOrTavern) const;
-//	EBuildingState::EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
+//	EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
 //	virtual bool getTownInfo(const CGObjectInstance * town, InfoAboutTown & dest, const CGObjectInstance * selectedObject = nullptr) const;
 
 	//from gs
 //	const TeamState *getTeam(TeamID teamID) const;
 //	const TeamState *getPlayerTeam(PlayerColor color) const;
-//	EBuildingState::EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID) const;// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
+//	EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID) const;// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
 
 	//teleport
 //	std::vector<ObjectInstanceID> getVisibleTeleportObjects(std::vector<ObjectInstanceID> ids, PlayerColor player)  const;
@@ -140,7 +140,7 @@ protected:
 
 public:
 	//various
-	int getDate(Date::EDateType mode=Date::DAY)const override; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
+	int getDate(Date mode=Date::DAY)const override; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
 	virtual const StartInfo * getStartInfo(bool beforeRandomization = false)const;
 	bool isAllowed(int32_t type, int32_t id) const override; //type: 0 - spell; 1- artifact; 2 - secondary skill
 
@@ -148,9 +148,9 @@ public:
 	const Player * getPlayer(PlayerColor color) const override;
 	virtual const PlayerState * getPlayerState(PlayerColor color, bool verbose = true) const;
 	virtual int getResource(PlayerColor Player, GameResID which) const;
-	virtual PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const;
+	virtual PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const;
 	virtual void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object
-	virtual EPlayerStatus::EStatus getPlayerStatus(PlayerColor player, bool verbose = true) const; //-1 if no such player
+	virtual EPlayerStatus getPlayerStatus(PlayerColor player, bool verbose = true) const; //-1 if no such player
 	virtual PlayerColor getCurrentPlayer() const; //player that currently makes move // TODO synchronous turns
 	PlayerColor getLocalPlayer() const override; //player that is currently owning given client (if not a client, then returns current player)
 	virtual const PlayerSettings * getPlayerSettings(PlayerColor color) const;
@@ -205,13 +205,13 @@ public:
 	//virtual const CGTownInstance * getTownInfo(int val, bool mode)const; //mode = 0 -> val = player town serial; mode = 1 -> val = object id (serial)
 	virtual std::vector<const CGHeroInstance *> getAvailableHeroes(const CGObjectInstance * townOrTavern) const; //heroes that can be recruited
 	virtual std::string getTavernRumor(const CGObjectInstance * townOrTavern) const;
-	virtual EBuildingState::EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
+	virtual EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
 	virtual bool getTownInfo(const CGObjectInstance * town, InfoAboutTown & dest, const CGObjectInstance * selectedObject = nullptr) const;
 
 	//from gs
 	virtual const TeamState *getTeam(TeamID teamID) const;
 	virtual const TeamState *getPlayerTeam(PlayerColor color) const;
-	//virtual EBuildingState::EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID) const;// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
+	//virtual EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID) const;// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
 
 	//teleport
 	virtual std::vector<ObjectInstanceID> getVisibleTeleportObjects(std::vector<ObjectInstanceID> ids, PlayerColor player)  const;

+ 1 - 1
lib/CGameInterface.h

@@ -91,7 +91,7 @@ public:
 	virtual void yourTurn(){}; //called AFTER playerStartsTurn(player)
 
 	//pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
-	virtual void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID)=0;
+	virtual void heroGotLevel(const CGHeroInstance *hero, PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID)=0;
 	virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID)=0;
 
 	// Show a dialog, player must take decision. If selection then he has to choose between one of given components,

+ 9 - 9
lib/CHeroHandler.cpp

@@ -14,7 +14,7 @@
 #include "filesystem/Filesystem.h"
 #include "VCMI_Lib.h"
 #include "JsonNode.h"
-#include "StringConstants.h"
+#include "constants/StringConstants.h"
 #include "battle/BattleHex.h"
 #include "CCreatureHandler.h"
 #include "GameSettings.h"
@@ -207,9 +207,9 @@ CHeroClass::CHeroClass():
 {
 }
 
-void CHeroClassHandler::fillPrimarySkillData(const JsonNode & node, CHeroClass * heroClass, PrimarySkill::PrimarySkill pSkill) const
+void CHeroClassHandler::fillPrimarySkillData(const JsonNode & node, CHeroClass * heroClass, PrimarySkill pSkill) const
 {
-	const auto & skillName = PrimarySkill::names[pSkill];
+	const auto & skillName = NPrimarySkill::names[static_cast<int>(pSkill)];
 	auto currentPrimarySkillValue = static_cast<int>(node["primarySkills"][skillName].Integer());
 	//minimal value is 0 for attack and defense and 1 for spell power and knowledge
 	auto primarySkillLegalMinimum = (pSkill == PrimarySkill::ATTACK || pSkill == PrimarySkill::DEFENSE) ? 0 : 1;
@@ -333,19 +333,19 @@ std::vector<JsonNode> CHeroClassHandler::loadLegacyData()
 
 		parser.readNumber(); // unused aggression
 
-		for(const auto & name : PrimarySkill::names)
+		for(const auto & name : NPrimarySkill::names)
 			entry["primarySkills"][name].Float() = parser.readNumber();
 
-		for(const auto & name : PrimarySkill::names)
+		for(const auto & name : NPrimarySkill::names)
 			entry["lowLevelChance"][name].Float() = parser.readNumber();
 
-		for(const auto & name : PrimarySkill::names)
+		for(const auto & name : NPrimarySkill::names)
 			entry["highLevelChance"][name].Float() = parser.readNumber();
 
 		for(const auto & name : NSecondarySkill::names)
 			entry["secondarySkills"][name].Float() = parser.readNumber();
 
-		for(const auto & name : ETownType::names)
+		for(const auto & name : NFaction::names)
 			entry["tavern"][name].Float() = parser.readNumber();
 
 		parser.endLine();
@@ -547,7 +547,7 @@ static std::vector<std::shared_ptr<Bonus>> createCreatureSpecialty(CreatureID ba
 		{
 			std::shared_ptr<Bonus> bonus = std::make_shared<Bonus>();
 			bonus->type = BonusType::PRIMARY_SKILL;
-			bonus->subtype = PrimarySkill::ATTACK;
+			bonus->subtype = static_cast<int>(PrimarySkill::ATTACK);
 			bonus->val = 0;
 			bonus->limiter.reset(new CCreatureTypeLimiter(specCreature, false));
 			bonus->updater.reset(new GrowsWithLevelUpdater(specCreature.getAttack(false), stepSize));
@@ -557,7 +557,7 @@ static std::vector<std::shared_ptr<Bonus>> createCreatureSpecialty(CreatureID ba
 		{
 			std::shared_ptr<Bonus> bonus = std::make_shared<Bonus>();
 			bonus->type = BonusType::PRIMARY_SKILL;
-			bonus->subtype = PrimarySkill::DEFENSE;
+			bonus->subtype = static_cast<int>(PrimarySkill::DEFENSE);
 			bonus->val = 0;
 			bonus->limiter.reset(new CCreatureTypeLimiter(specCreature, false));
 			bonus->updater.reset(new GrowsWithLevelUpdater(specCreature.getDefense(false), stepSize));

+ 1 - 1
lib/CHeroHandler.h

@@ -212,7 +212,7 @@ public:
 
 class DLL_LINKAGE CHeroClassHandler : public CHandlerBase<HeroClassID, HeroClass, CHeroClass, HeroClassService>
 {
-	void fillPrimarySkillData(const JsonNode & node, CHeroClass * heroClass, PrimarySkill::PrimarySkill pSkill) const;
+	void fillPrimarySkillData(const JsonNode & node, CHeroClass * heroClass, PrimarySkill pSkill) const;
 
 public:
 	std::vector<JsonNode> loadLegacyData() override;

+ 2 - 1
lib/CPlayerState.h

@@ -16,6 +16,7 @@
 #include "bonuses/CBonusSystemNode.h"
 #include "ResourceSet.h"
 #include "TurnTimerInfo.h"
+#include "ConstTransitivePtr.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -38,7 +39,7 @@ public:
 	std::vector<QuestInfo> quests; //store info about all received quests
 
 	bool enteredWinningCheatCode, enteredLosingCheatCode; //if true, this player has entered cheat codes for loss / victory
-	EPlayerStatus::EStatus status;
+	EPlayerStatus status;
 	std::optional<ui8> daysWithoutCastle;
 	TurnTimerInfo turnTimer;
 

+ 1 - 1
lib/CSkillHandler.cpp

@@ -22,7 +22,7 @@
 
 #include "JsonNode.h"
 
-#include "StringConstants.h"
+#include "constants/StringConstants.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 

+ 10 - 10
lib/CTownHandler.cpp

@@ -13,7 +13,7 @@
 #include "VCMI_Lib.h"
 #include "CGeneralTextHandler.h"
 #include "JsonNode.h"
-#include "StringConstants.h"
+#include "constants/StringConstants.h"
 #include "CCreatureHandler.h"
 #include "CHeroHandler.h"
 #include "CArtHandler.h"
@@ -82,7 +82,7 @@ std::string CBuilding::getDescriptionTextID() const
 BuildingID CBuilding::getBase() const
 {
 	const CBuilding * build = this;
-	while (build->upgrade >= 0)
+	while (build->upgrade != BuildingID::NONE)
 	{
 		build = build->town->buildings.at(build->upgrade);
 	}
@@ -94,7 +94,7 @@ si32 CBuilding::getDistance(const BuildingID & buildID) const
 {
 	const CBuilding * build = town->buildings.at(buildID);
 	int distance = 0;
-	while (build->upgrade >= 0 && build != this)
+	while (build->upgrade != BuildingID::NONE && build != this)
 	{
 		build = build->town->buildings.at(build->upgrade);
 		distance++;
@@ -184,9 +184,9 @@ EAlignment CFaction::getAlignment() const
 	return alignment;
 }
 
-EBoatId CFaction::getBoatType() const
+BoatId CFaction::getBoatType() const
 {
-	return boatType.toEnum();
+	return boatType;
 }
 
 TerrainId CFaction::getNativeTerrain() const
@@ -265,7 +265,7 @@ const CBuilding * CTown::getSpecialBuilding(BuildingSubID::EBuildingSubID subID)
 	return nullptr;
 }
 
-BuildingID::EBuildingID CTown::getBuildingType(BuildingSubID::EBuildingSubID subID) const
+BuildingID CTown::getBuildingType(BuildingSubID::EBuildingSubID subID) const
 {
 	const auto * building = getSpecialBuilding(subID);
 	return building == nullptr ? BuildingID::NONE : building->bid.num;
@@ -527,13 +527,13 @@ void CTownHandler::addBonusesForVanilaBuilding(CBuilding * building) const
 		b = createBonus(building, BonusType::LUCK, +2);
 		break;
 	case BuildingSubID::SPELL_POWER_GARRISON_BONUS:
-		b = createBonus(building, BonusType::PRIMARY_SKILL, +2, PrimarySkill::SPELL_POWER);
+		b = createBonus(building, BonusType::PRIMARY_SKILL, +2, static_cast<int>(PrimarySkill::SPELL_POWER));
 		break;
 	case BuildingSubID::ATTACK_GARRISON_BONUS:
-		b = createBonus(building, BonusType::PRIMARY_SKILL, +2, PrimarySkill::ATTACK);
+		b = createBonus(building, BonusType::PRIMARY_SKILL, +2, static_cast<int>(PrimarySkill::ATTACK));
 		break;
 	case BuildingSubID::DEFENSE_GARRISON_BONUS:
-		b = createBonus(building, BonusType::PRIMARY_SKILL, +2, PrimarySkill::DEFENSE);
+		b = createBonus(building, BonusType::PRIMARY_SKILL, +2, static_cast<int>(PrimarySkill::DEFENSE));
 		break;
 	case BuildingSubID::LIGHTHOUSE:
 		b = createBonus(building, BonusType::MOVEMENT, +500, playerPropagator, 0);
@@ -1034,7 +1034,7 @@ CFaction * CTownHandler::loadFromJson(const std::string & scope, const JsonNode
 	faction->creatureBg120 = source["creatureBackground"]["120px"].String();
 	faction->creatureBg130 = source["creatureBackground"]["130px"].String();
 
-	faction->boatType = EBoatId::CASTLE; //Do not crash
+	faction->boatType = BoatId::CASTLE; //Do not crash
 	if (!source["boat"].isNull())
 	{
 		VLC->identifiers()->requestIdentifier("core:boat", source["boat"], [=](int32_t boatTypeID)

+ 3 - 3
lib/CTownHandler.h

@@ -207,7 +207,7 @@ public:
 
 	/// Boat that will be used by town shipyard (if any)
 	/// and for placing heroes directly on boat (in map editor, water prisons & taverns)
-	BoatId boatType = BoatId(EBoatId::CASTLE);
+	BoatId boatType = BoatId::CASTLE;
 
 
 	CTown * town = nullptr; //NOTE: can be null
@@ -232,7 +232,7 @@ public:
 	bool hasTown() const override;
 	TerrainId getNativeTerrain() const override;
 	EAlignment getAlignment() const override;
-	EBoatId getBoatType() const override;
+	BoatId getBoatType() const override;
 
 	void updateFrom(const JsonNode & data);
 	void serializeJson(JsonSerializeFormat & handler);
@@ -266,7 +266,7 @@ public:
 	const CBuilding * getSpecialBuilding(BuildingSubID::EBuildingSubID subID) const;
 	std::string getGreeting(BuildingSubID::EBuildingSubID subID) const;
 	void setGreeting(BuildingSubID::EBuildingSubID subID, const std::string & message) const; //may affect only mutable field
-	BuildingID::EBuildingID getBuildingType(BuildingSubID::EBuildingSubID subID) const;
+	BuildingID getBuildingType(BuildingSubID::EBuildingSubID subID) const;
 
 	std::string getRandomNameTranslated(size_t index) const;
 	std::string getRandomNameTextID(size_t index) const;

+ 3 - 1382
lib/GameConstants.h

@@ -9,1393 +9,14 @@
  */
 #pragma once
 
-#include "ConstTransitivePtr.h"
+#include "constants/NumericConstants.h"
+#include "constants/Enumerations.h"
+#include "constants/EntityIdentifiers.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-class Artifact;
-class ArtifactService;
-class Creature;
-class CreatureService;
-
-namespace spells
-{
-	class Spell;
-	class Service;
-}
-
-class CArtifact;
-class CArtifactInstance;
-class CCreature;
-class CHero;
-class CSpell;
-class CSkill;
-class CGameInfoCallback;
-class CNonConstInfoCallback;
-
-struct IdTag
-{};
-
-namespace GameConstants
-{
-	DLL_LINKAGE extern const std::string VCMI_VERSION;
-
-	constexpr int PUZZLE_MAP_PIECES = 48;
-
-	constexpr int MAX_HEROES_PER_PLAYER = 8;
-	constexpr int AVAILABLE_HEROES_PER_PLAYER = 2;
-
-	constexpr int ALL_PLAYERS = 255; //bitfield
-
-	constexpr int CREATURES_PER_TOWN = 7; //without upgrades
-	constexpr int SPELL_LEVELS = 5;
-	constexpr int SPELL_SCHOOL_LEVELS = 4;
-	constexpr int DEFAULT_SCHOOLS = 4;
-	constexpr int CRE_LEVELS = 10; // number of creature experience levels
-
-	constexpr int HERO_GOLD_COST = 2500;
-	constexpr int SPELLBOOK_GOLD_COST = 500;
-	constexpr int SKILL_GOLD_COST = 2000;
-	constexpr int BATTLE_SHOOTING_PENALTY_DISTANCE = 10; //if the distance is > than this, then shooting stack has distance penalty
-	constexpr int BATTLE_SHOOTING_RANGE_DISTANCE = std::numeric_limits<uint8_t>::max(); // used when shooting stack has no shooting range limit
-	constexpr int ARMY_SIZE = 7;
-	constexpr int SKILL_PER_HERO = 8;
-	constexpr ui32 HERO_HIGH_LEVEL = 10; // affects primary skill upgrade order
-
-	constexpr int SKILL_QUANTITY=28;
-	constexpr int PRIMARY_SKILLS=4;
-	constexpr int RESOURCE_QUANTITY=8;
-	constexpr int HEROES_PER_TYPE=8; //amount of heroes of each type
-
-	// amounts of OH3 objects. Can be changed by mods, should be used only during H3 loading phase
-	constexpr int F_NUMBER = 9;
-	constexpr int ARTIFACTS_QUANTITY=171;
-	constexpr int HEROES_QUANTITY=156;
-	constexpr int SPELLS_QUANTITY=70;
-	constexpr int CREATURES_COUNT = 197;
-
-	constexpr ui32 BASE_MOVEMENT_COST = 100; //default cost for non-diagonal movement
-
-	constexpr int HERO_PORTRAIT_SHIFT = 9;// 2 special frames + 7 extra portraits
-
-	constexpr std::array<int, 11> POSSIBLE_TURNTIME = {1, 2, 4, 6, 8, 10, 15, 20, 25, 30, 0};
-}
-
-#define ID_LIKE_CLASS_COMMON(CLASS_NAME, ENUM_NAME)	\
-constexpr CLASS_NAME(const CLASS_NAME & other) = default;	\
-constexpr CLASS_NAME & operator=(const CLASS_NAME & other) = default;	\
-explicit constexpr CLASS_NAME(si32 id)				\
-	: num(static_cast<ENUM_NAME>(id))				\
-{}													\
-constexpr operator ENUM_NAME() const				\
-{													\
-	return num;										\
-}													\
-constexpr si32 getNum() const						\
-{													\
-	return static_cast<si32>(num);					\
-}													\
-constexpr ENUM_NAME toEnum() const					\
-{													\
-	return num;										\
-}													\
-template <typename Handler> void serialize(Handler &h, const int version)	\
-{													\
-	h & num;										\
-}													\
-constexpr CLASS_NAME & advance(int i)				\
-{													\
-	num = static_cast<ENUM_NAME>(static_cast<int>(num) + i);		\
-	return *this;									\
-}
-
-
-// Operators are performance-critical and to be inlined they must be in header
-#define ID_LIKE_OPERATORS_INTERNAL(A, B, AN, BN)	\
-STRONG_INLINE constexpr bool operator==(const A & a, const B & b)	\
-{													\
-	return AN == BN ;								\
-}													\
-STRONG_INLINE constexpr bool operator!=(const A & a, const B & b)	\
-{													\
-	return AN != BN ;								\
-}													\
-STRONG_INLINE constexpr bool operator<(const A & a, const B & b)	\
-{													\
-	return AN < BN ;								\
-}													\
-STRONG_INLINE constexpr bool operator<=(const A & a, const B & b)	\
-{													\
-	return AN <= BN ;								\
-}													\
-STRONG_INLINE constexpr bool operator>(const A & a, const B & b)	\
-{													\
-	return AN > BN ;								\
-}													\
-STRONG_INLINE constexpr bool operator>=(const A & a, const B & b)	\
-{													\
-	return AN >= BN ;								\
-}
-
-#define ID_LIKE_OPERATORS(CLASS_NAME, ENUM_NAME)	\
-	ID_LIKE_OPERATORS_INTERNAL(CLASS_NAME, CLASS_NAME, a.num, b.num)	\
-	ID_LIKE_OPERATORS_INTERNAL(CLASS_NAME, ENUM_NAME, a.num, b)	\
-	ID_LIKE_OPERATORS_INTERNAL(ENUM_NAME, CLASS_NAME, a, b.num)
-
-
-#define INSTID_LIKE_CLASS_COMMON(CLASS_NAME, NUMERIC_NAME)	\
-public:														\
-constexpr CLASS_NAME(const CLASS_NAME & other):						\
-	BaseForID<CLASS_NAME, NUMERIC_NAME>(other)				\
-{															\
-}															\
-constexpr CLASS_NAME & operator=(const CLASS_NAME & other) = default;	\
-constexpr CLASS_NAME & operator=(NUMERIC_NAME other) { num = other; return *this; };	\
-explicit constexpr CLASS_NAME(si32 id = -1)								\
-	: BaseForID<CLASS_NAME, NUMERIC_NAME>(id)				\
-{}
-
-template < typename Derived, typename NumericType>
-class BaseForID : public IdTag
-{
-protected:
-	NumericType num;
-
-public:
-	constexpr NumericType getNum() const
-	{
-		return num;
-	}
-
-	//to make it more similar to IDLIKE
-	constexpr NumericType toEnum() const
-	{
-		return num;
-	}
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & num;
-	}
-
-	constexpr explicit BaseForID(NumericType _num = -1) :
-		num(_num)
-	{
-	}
-
-	constexpr void advance(int change)
-	{
-		num += change;
-	}
-
-	constexpr bool operator == (const BaseForID & b) const { return num == b.num; }
-	constexpr bool operator <= (const BaseForID & b) const { return num <= b.num; }
-	constexpr bool operator >= (const BaseForID & b) const { return num >= b.num; }
-	constexpr bool operator != (const BaseForID & b) const { return num != b.num; }
-	constexpr bool operator <  (const BaseForID & b) const { return num <  b.num; }
-	constexpr bool operator >  (const BaseForID & b) const { return num >  b.num; }
-
-	constexpr BaseForID & operator++() { ++num; return *this; }
-
-	constexpr operator NumericType() const
-	{
-		return num;
-	}
-};
-
-template < typename T>
-class Identifier : public IdTag
-{
-public:
-	using EnumType    = T;
-	using NumericType = typename std::underlying_type<EnumType>::type;
-
-private:
-	NumericType num;
-
-public:
-	constexpr NumericType getNum() const
-	{
-		return num;
-	}
-
-	constexpr EnumType toEnum() const
-	{
-		return static_cast<EnumType>(num);
-	}
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & num;
-	}
-
-	constexpr explicit Identifier(NumericType _num = -1)
-	{
-		num = _num;
-	}
-
-	/* implicit */constexpr Identifier(EnumType _num):
-		num(static_cast<NumericType>(_num))
-	{
-	}
-
-	constexpr void advance(int change)
-	{
-		num += change;
-	}
-
-	constexpr bool operator == (const Identifier & b) const { return num == b.num; }
-	constexpr bool operator <= (const Identifier & b) const { return num <= b.num; }
-	constexpr bool operator >= (const Identifier & b) const { return num >= b.num; }
-	constexpr bool operator != (const Identifier & b) const { return num != b.num; }
-	constexpr bool operator <  (const Identifier & b) const { return num <  b.num; }
-	constexpr bool operator >  (const Identifier & b) const { return num > b.num; }
-
-	constexpr Identifier & operator++()
-	{
-		++num;
-		return *this;
-	}
-
-	constexpr Identifier operator++(int)
-	{
-		Identifier ret(*this);
-		++num;
-		return ret;
-	}
-
-	constexpr operator NumericType() const
-	{
-		return num;
-	}
-};
-
-
-template<typename Der, typename Num>
-std::ostream & operator << (std::ostream & os, BaseForID<Der, Num> id);
-
-template<typename Der, typename Num>
-std::ostream & operator << (std::ostream & os, BaseForID<Der, Num> id)
-{
-	//We use common type with short to force char and unsigned char to be promoted and formatted as numbers.
-	typedef typename std::common_type<short, Num>::type Number;
-	return os << static_cast<Number>(id.getNum());
-}
-
-template<typename EnumType>
-std::ostream & operator << (std::ostream & os, Identifier<EnumType> id)
-{
-	//We use common type with short to force char and unsigned char to be promoted and formatted as numbers.
-	typedef typename std::common_type<short, typename Identifier<EnumType>::NumericType>::type Number;
-	return os << static_cast<Number>(id.getNum());
-}
-
-class ArtifactInstanceID : public BaseForID<ArtifactInstanceID, si32>
-{
-	INSTID_LIKE_CLASS_COMMON(ArtifactInstanceID, si32)
-
-	friend class CGameInfoCallback;
-	friend class CNonConstInfoCallback;
-};
-
-class QueryID : public BaseForID<QueryID, si32>
-{
-	INSTID_LIKE_CLASS_COMMON(QueryID, si32)
-
-	QueryID & operator++()
-	{
-		++num;
-		return *this;
-	}
-};
-
-class ObjectInstanceID : public BaseForID<ObjectInstanceID, si32>
-{
-	INSTID_LIKE_CLASS_COMMON(ObjectInstanceID, si32)
-
-	DLL_LINKAGE static const ObjectInstanceID NONE;
-
-	friend class CGameInfoCallback;
-	friend class CNonConstInfoCallback;
-};
-
-class HeroClassID : public BaseForID<HeroClassID, si32>
-{
-	INSTID_LIKE_CLASS_COMMON(HeroClassID, si32)
-};
-
-class HeroTypeID : public BaseForID<HeroTypeID, si32>
-{
-	INSTID_LIKE_CLASS_COMMON(HeroTypeID, si32)
-
-	///json serialization helpers
-	static si32 decode(const std::string & identifier);
-	static std::string encode(const si32 index);
-
-	DLL_LINKAGE static const HeroTypeID NONE;
-};
-
-class SlotID : public BaseForID<SlotID, si32>
-{
-	INSTID_LIKE_CLASS_COMMON(SlotID, si32)
-
-	friend class CGameInfoCallback;
-	friend class CNonConstInfoCallback;
-
-	DLL_LINKAGE static const SlotID COMMANDER_SLOT_PLACEHOLDER;
-	DLL_LINKAGE static const SlotID SUMMONED_SLOT_PLACEHOLDER; ///<for all summoned creatures, only during battle
-	DLL_LINKAGE static const SlotID WAR_MACHINES_SLOT; ///<for all war machines during battle
-	DLL_LINKAGE static const SlotID ARROW_TOWERS_SLOT; ///<for all arrow towers during battle
-
-	bool validSlot() const
-	{
-		return getNum() >= 0  &&  getNum() < GameConstants::ARMY_SIZE;
-	}
-};
-
-class PlayerColor : public BaseForID<PlayerColor, ui8>
-{
-	INSTID_LIKE_CLASS_COMMON(PlayerColor, ui8)
-
-	enum EPlayerColor
-	{
-		PLAYER_LIMIT_I = 8,
-	};
-
-	using Mask = uint8_t;
-
-	DLL_LINKAGE static const PlayerColor SPECTATOR; //252
-	DLL_LINKAGE static const PlayerColor CANNOT_DETERMINE; //253
-	DLL_LINKAGE static const PlayerColor UNFLAGGABLE; //254 - neutral objects (pandora, banks)
-	DLL_LINKAGE static const PlayerColor NEUTRAL; //255
-	DLL_LINKAGE static const PlayerColor PLAYER_LIMIT; //player limit per map
-
-	DLL_LINKAGE bool isValidPlayer() const; //valid means < PLAYER_LIMIT (especially non-neutral)
-	DLL_LINKAGE bool isSpectator() const;
-
-	DLL_LINKAGE std::string getStr(bool L10n = false) const;
-	DLL_LINKAGE std::string getStrCap(bool L10n = false) const;
-
-	friend class CGameInfoCallback;
-	friend class CNonConstInfoCallback;
-};
-
-class TeamID : public BaseForID<TeamID, ui8>
-{
-	INSTID_LIKE_CLASS_COMMON(TeamID, ui8)
-
-	DLL_LINKAGE static const TeamID NO_TEAM;
-
-	friend class CGameInfoCallback;
-	friend class CNonConstInfoCallback;
-};
-
-class TeleportChannelID : public BaseForID<TeleportChannelID, si32>
-{
-	INSTID_LIKE_CLASS_COMMON(TeleportChannelID, si32)
-
-	friend class CGameInfoCallback;
-	friend class CNonConstInfoCallback;
-};
-
-// #ifndef INSTANTIATE_BASE_FOR_ID_HERE
-// extern template std::ostream & operator << <ArtifactInstanceID>(std::ostream & os, BaseForID<ArtifactInstanceID> id);
-// extern template std::ostream & operator << <ObjectInstanceID>(std::ostream & os, BaseForID<ObjectInstanceID> id);
-// #endif
-
-// Enum declarations
-namespace PrimarySkill
-{
-	enum PrimarySkill : int8_t { NONE = -1, ATTACK, DEFENSE, SPELL_POWER, KNOWLEDGE,
-				EXPERIENCE = 4}; //for some reason changePrimSkill uses it
-}
-
-class SecondarySkill
-{
-public:
-	enum ESecondarySkill
-	{
-		WRONG = -2,
-		DEFAULT = -1,
-		PATHFINDING = 0, ARCHERY, LOGISTICS, SCOUTING, DIPLOMACY, NAVIGATION, LEADERSHIP, WISDOM, MYSTICISM,
-		LUCK, BALLISTICS, EAGLE_EYE, NECROMANCY, ESTATES, FIRE_MAGIC, AIR_MAGIC, WATER_MAGIC, EARTH_MAGIC,
-		SCHOLAR, TACTICS, ARTILLERY, LEARNING, OFFENCE, ARMORER, INTELLIGENCE, SORCERY, RESISTANCE,
-		FIRST_AID, SKILL_SIZE
-	};
-
-	static_assert(GameConstants::SKILL_QUANTITY == SKILL_SIZE, "Incorrect number of skills");
-
-	SecondarySkill(ESecondarySkill _num = WRONG) : num(_num)
-	{}
-
-	ID_LIKE_CLASS_COMMON(SecondarySkill, ESecondarySkill)
-
-	ESecondarySkill num;
-};
-
-ID_LIKE_OPERATORS(SecondarySkill, SecondarySkill::ESecondarySkill)
-
-enum class EAlignment : uint8_t { GOOD, EVIL, NEUTRAL };
-
-namespace ETownType//deprecated
-{
-	enum ETownType
-	{
-		ANY = -1,
-		CASTLE, RAMPART, TOWER, INFERNO, NECROPOLIS, DUNGEON, STRONGHOLD, FORTRESS, CONFLUX, NEUTRAL
-	};
-}
-
-class FactionID : public BaseForID<FactionID, int32_t>
-{
-	INSTID_LIKE_CLASS_COMMON(FactionID, si32)
-
-	DLL_LINKAGE static const FactionID NONE;
-	DLL_LINKAGE static const FactionID DEFAULT;
-	DLL_LINKAGE static const FactionID CASTLE;
-	DLL_LINKAGE static const FactionID RAMPART;
-	DLL_LINKAGE static const FactionID TOWER;
-	DLL_LINKAGE static const FactionID INFERNO;
-	DLL_LINKAGE static const FactionID NECROPOLIS;
-	DLL_LINKAGE static const FactionID DUNGEON;
-	DLL_LINKAGE static const FactionID STRONGHOLD;
-	DLL_LINKAGE static const FactionID FORTRESS;
-	DLL_LINKAGE static const FactionID CONFLUX;
-	DLL_LINKAGE static const FactionID NEUTRAL;
-
-	static si32 decode(const std::string& identifier);
-	static std::string encode(const si32 index);
-	static std::string entityType();
-};
-
-class TerrainID
-{
-	//Dummy class used only for serialization
-public:
-	static si32 decode(const std::string & identifier);
-	static std::string encode(const si32 index);
-	static std::string entityType();
-};
-
-class BuildingID
-{
-public:
-	//Quite useful as long as most of building mechanics hardcoded
-	// NOTE: all building with completely configurable mechanics will be removed from list
-	enum EBuildingID
-	{
-		DEFAULT = -50,
-		HORDE_PLACEHOLDER7 = -36,
-		HORDE_PLACEHOLDER6 = -35,
-		HORDE_PLACEHOLDER5 = -34,
-		HORDE_PLACEHOLDER4 = -33,
-		HORDE_PLACEHOLDER3 = -32,
-		HORDE_PLACEHOLDER2 = -31,
-		HORDE_PLACEHOLDER1 = -30,
-		NONE = -1,
-		FIRST_REGULAR_ID = 0,
-		MAGES_GUILD_1 = 0,  MAGES_GUILD_2, MAGES_GUILD_3,     MAGES_GUILD_4,   MAGES_GUILD_5,
-		TAVERN,         SHIPYARD,      FORT,              CITADEL,         CASTLE,
-		VILLAGE_HALL,   TOWN_HALL,     CITY_HALL,         CAPITOL,         MARKETPLACE,
-		RESOURCE_SILO,  BLACKSMITH,    SPECIAL_1,         HORDE_1,         HORDE_1_UPGR,
-		SHIP,           SPECIAL_2,     SPECIAL_3,         SPECIAL_4,       HORDE_2,
-		HORDE_2_UPGR,   GRAIL,         EXTRA_TOWN_HALL,   EXTRA_CITY_HALL, EXTRA_CAPITOL,
-		DWELL_FIRST=30, DWELL_LVL_2, DWELL_LVL_3, DWELL_LVL_4, DWELL_LVL_5, DWELL_LVL_6, DWELL_LAST=36,
-		DWELL_UP_FIRST=37,  DWELL_LVL_2_UP, DWELL_LVL_3_UP, DWELL_LVL_4_UP, DWELL_LVL_5_UP,
-		DWELL_LVL_6_UP, DWELL_UP_LAST=43,
-
-		DWELL_LVL_1 = DWELL_FIRST,
-		DWELL_LVL_7 = DWELL_LAST,
-		DWELL_LVL_1_UP = DWELL_UP_FIRST,
-		DWELL_LVL_7_UP = DWELL_UP_LAST,
-
-		//Special buildings for towns.
-		LIGHTHOUSE  = SPECIAL_1,
-		STABLES     = SPECIAL_2, //Castle
-		BROTHERHOOD = SPECIAL_3,
-
-		MYSTIC_POND         = SPECIAL_1,
-		FOUNTAIN_OF_FORTUNE = SPECIAL_2, //Rampart
-		TREASURY            = SPECIAL_3,
-
-		ARTIFACT_MERCHANT = SPECIAL_1,
-		LOOKOUT_TOWER     = SPECIAL_2, //Tower
-		LIBRARY           = SPECIAL_3,
-		WALL_OF_KNOWLEDGE = SPECIAL_4,
-
-		STORMCLOUDS   = SPECIAL_2,
-		CASTLE_GATE   = SPECIAL_3, //Inferno
-		ORDER_OF_FIRE = SPECIAL_4,
-
-		COVER_OF_DARKNESS    = SPECIAL_1,
-		NECROMANCY_AMPLIFIER = SPECIAL_2, //Necropolis
-		SKELETON_TRANSFORMER = SPECIAL_3,
-
-		//ARTIFACT_MERCHANT - same ID as in tower
-		MANA_VORTEX      = SPECIAL_2,
-		PORTAL_OF_SUMMON = SPECIAL_3, //Dungeon
-		BATTLE_ACADEMY   = SPECIAL_4,
-
-		ESCAPE_TUNNEL     = SPECIAL_1,
-		FREELANCERS_GUILD = SPECIAL_2, //Stronghold
-		BALLISTA_YARD     = SPECIAL_3,
-		HALL_OF_VALHALLA  = SPECIAL_4,
-
-		CAGE_OF_WARLORDS = SPECIAL_1,
-		GLYPHS_OF_FEAR   = SPECIAL_2, // Fortress
-		BLOOD_OBELISK    = SPECIAL_3,
-
-		//ARTIFACT_MERCHANT - same ID as in tower
-		MAGIC_UNIVERSITY = SPECIAL_2, // Conflux
-	};
-
-	BuildingID(EBuildingID _num = NONE) : num(_num)
-	{}
-
-	STRONG_INLINE
-	bool IsSpecialOrGrail() const
-	{
-		return num == SPECIAL_1 || num == SPECIAL_2 || num == SPECIAL_3 || num == SPECIAL_4 || num == GRAIL;
-	}
-
-	ID_LIKE_CLASS_COMMON(BuildingID, EBuildingID)
-
-	EBuildingID num;
-};
-
-ID_LIKE_OPERATORS(BuildingID, BuildingID::EBuildingID)
-
-namespace BuildingSubID
-{
-	enum EBuildingSubID
-	{
-		DEFAULT = -50,
-		NONE = -1,
-		STABLES,
-		BROTHERHOOD_OF_SWORD,
-		CASTLE_GATE,
-		CREATURE_TRANSFORMER,
-		MYSTIC_POND,
-		FOUNTAIN_OF_FORTUNE,
-		ARTIFACT_MERCHANT,
-		LOOKOUT_TOWER,
-		LIBRARY,
-		MANA_VORTEX,
-		PORTAL_OF_SUMMONING,
-		ESCAPE_TUNNEL,
-		FREELANCERS_GUILD,
-		BALLISTA_YARD,
-		ATTACK_VISITING_BONUS,
-		MAGIC_UNIVERSITY,
-		SPELL_POWER_GARRISON_BONUS,
-		ATTACK_GARRISON_BONUS,
-		DEFENSE_GARRISON_BONUS,
-		DEFENSE_VISITING_BONUS,
-		SPELL_POWER_VISITING_BONUS,
-		KNOWLEDGE_VISITING_BONUS,
-		EXPERIENCE_VISITING_BONUS,
-		LIGHTHOUSE,
-		TREASURY,
-		CUSTOM_VISITING_BONUS,
-		CUSTOM_VISITING_REWARD
-	};
-}
-
-namespace EMarketMode
-{
-	enum EMarketMode
-	{
-		RESOURCE_RESOURCE, RESOURCE_PLAYER, CREATURE_RESOURCE, RESOURCE_ARTIFACT,
-		ARTIFACT_RESOURCE, ARTIFACT_EXP, CREATURE_EXP, CREATURE_UNDEAD, RESOURCE_SKILL,
-		MARTKET_AFTER_LAST_PLACEHOLDER
-	};
-}
-
-namespace MappedKeys
-{
-
-	static const std::map<std::string, BuildingID> BUILDING_NAMES_TO_TYPES =
-	{
-		{ "special1", BuildingID::SPECIAL_1 },
-		{ "special2", BuildingID::SPECIAL_2 },
-		{ "special3", BuildingID::SPECIAL_3 },
-		{ "special4", BuildingID::SPECIAL_4 },
-		{ "grail", BuildingID::GRAIL },
-		{ "mageGuild1", BuildingID::MAGES_GUILD_1 },
-		{ "mageGuild2", BuildingID::MAGES_GUILD_2 },
-		{ "mageGuild3", BuildingID::MAGES_GUILD_3 },
-		{ "mageGuild4", BuildingID::MAGES_GUILD_4 },
-		{ "mageGuild5", BuildingID::MAGES_GUILD_5 },
-		{ "tavern", BuildingID::TAVERN },
-		{ "shipyard", BuildingID::SHIPYARD },
-		{ "fort", BuildingID::FORT },
-		{ "citadel", BuildingID::CITADEL },
-		{ "castle", BuildingID::CASTLE },
-		{ "villageHall", BuildingID::VILLAGE_HALL },
-		{ "townHall", BuildingID::TOWN_HALL },
-		{ "cityHall", BuildingID::CITY_HALL },
-		{ "capitol", BuildingID::CAPITOL },
-		{ "marketplace", BuildingID::MARKETPLACE },
-		{ "resourceSilo", BuildingID::RESOURCE_SILO },
-		{ "blacksmith", BuildingID::BLACKSMITH },
-		{ "horde1", BuildingID::HORDE_1 },
-		{ "horde1Upgr", BuildingID::HORDE_1_UPGR },
-		{ "horde2", BuildingID::HORDE_2 },
-		{ "horde2Upgr", BuildingID::HORDE_2_UPGR },
-		{ "ship", BuildingID::SHIP },
-		{ "dwellingLvl1", BuildingID::DWELL_LVL_1 },
-		{ "dwellingLvl2", BuildingID::DWELL_LVL_2 },
-		{ "dwellingLvl3", BuildingID::DWELL_LVL_3 },
-		{ "dwellingLvl4", BuildingID::DWELL_LVL_4 },
-		{ "dwellingLvl5", BuildingID::DWELL_LVL_5 },
-		{ "dwellingLvl6", BuildingID::DWELL_LVL_6 },
-		{ "dwellingLvl7", BuildingID::DWELL_LVL_7 },
-		{ "dwellingUpLvl1", BuildingID::DWELL_LVL_1_UP },
-		{ "dwellingUpLvl2", BuildingID::DWELL_LVL_2_UP },
-		{ "dwellingUpLvl3", BuildingID::DWELL_LVL_3_UP },
-		{ "dwellingUpLvl4", BuildingID::DWELL_LVL_4_UP },
-		{ "dwellingUpLvl5", BuildingID::DWELL_LVL_5_UP },
-		{ "dwellingUpLvl6", BuildingID::DWELL_LVL_6_UP },
-		{ "dwellingUpLvl7", BuildingID::DWELL_LVL_7_UP },
-	};
-
-	static const std::map<std::string, BuildingSubID::EBuildingSubID> SPECIAL_BUILDINGS =
-	{
-		{ "mysticPond", BuildingSubID::MYSTIC_POND },
-		{ "artifactMerchant", BuildingSubID::ARTIFACT_MERCHANT },
-		{ "freelancersGuild", BuildingSubID::FREELANCERS_GUILD },
-		{ "magicUniversity", BuildingSubID::MAGIC_UNIVERSITY },
-		{ "castleGate", BuildingSubID::CASTLE_GATE },
-		{ "creatureTransformer", BuildingSubID::CREATURE_TRANSFORMER },//only skeleton transformer yet
-		{ "portalOfSummoning", BuildingSubID::PORTAL_OF_SUMMONING },
-		{ "ballistaYard", BuildingSubID::BALLISTA_YARD },
-		{ "stables", BuildingSubID::STABLES },
-		{ "manaVortex", BuildingSubID::MANA_VORTEX },
-		{ "lookoutTower", BuildingSubID::LOOKOUT_TOWER },
-		{ "library", BuildingSubID::LIBRARY },
-		{ "brotherhoodOfSword", BuildingSubID::BROTHERHOOD_OF_SWORD },//morale garrison bonus
-		{ "fountainOfFortune", BuildingSubID::FOUNTAIN_OF_FORTUNE },//luck garrison bonus
-		{ "spellPowerGarrisonBonus", BuildingSubID::SPELL_POWER_GARRISON_BONUS },//such as 'stormclouds', but this name is not ok for good towns
-		{ "attackGarrisonBonus", BuildingSubID::ATTACK_GARRISON_BONUS },
-		{ "defenseGarrisonBonus", BuildingSubID::DEFENSE_GARRISON_BONUS },
-		{ "escapeTunnel", BuildingSubID::ESCAPE_TUNNEL },
-		{ "attackVisitingBonus", BuildingSubID::ATTACK_VISITING_BONUS },
-		{ "defenceVisitingBonus", BuildingSubID::DEFENSE_VISITING_BONUS },
-		{ "spellPowerVisitingBonus", BuildingSubID::SPELL_POWER_VISITING_BONUS },
-		{ "knowledgeVisitingBonus", BuildingSubID::KNOWLEDGE_VISITING_BONUS },
-		{ "experienceVisitingBonus", BuildingSubID::EXPERIENCE_VISITING_BONUS },
-		{ "lighthouse", BuildingSubID::LIGHTHOUSE },
-		{ "treasury", BuildingSubID::TREASURY }
-	};
-
-	static const std::map<std::string, EMarketMode::EMarketMode> MARKET_NAMES_TO_TYPES =
-	{
-		{ "resource-resource", EMarketMode::RESOURCE_RESOURCE },
-		{ "resource-player", EMarketMode::RESOURCE_PLAYER },
-		{ "creature-resource", EMarketMode::CREATURE_RESOURCE },
-		{ "resource-artifact", EMarketMode::RESOURCE_ARTIFACT },
-		{ "artifact-resource", EMarketMode::ARTIFACT_RESOURCE },
-		{ "artifact-experience", EMarketMode::ARTIFACT_EXP },
-		{ "creature-experience", EMarketMode::CREATURE_EXP },
-		{ "creature-undead", EMarketMode::CREATURE_UNDEAD },
-		{ "resource-skill", EMarketMode::RESOURCE_SKILL },
-	};
-}
-
-namespace EAiTactic
-{
-enum EAiTactic
-{
-	NONE = -1,
-	RANDOM,
-	WARRIOR,
-	BUILDER,
-	EXPLORER
-};
-}
-
-namespace EBuildingState
-{
-	enum EBuildingState
-	{
-		HAVE_CAPITAL, NO_WATER, FORBIDDEN, ADD_MAGES_GUILD, ALREADY_PRESENT, CANT_BUILD_TODAY,
-		NO_RESOURCES, ALLOWED, PREREQUIRES, MISSING_BASE, BUILDING_ERROR, TOWN_NOT_OWNED
-	};
-}
-
-namespace ESpellCastProblem
-{
-	enum ESpellCastProblem
-	{
-		OK, NO_HERO_TO_CAST_SPELL, CASTS_PER_TURN_LIMIT, NO_SPELLBOOK,
-		HERO_DOESNT_KNOW_SPELL, NOT_ENOUGH_MANA, ADVMAP_SPELL_INSTEAD_OF_BATTLE_SPELL,
-		SPELL_LEVEL_LIMIT_EXCEEDED, NO_SPELLS_TO_DISPEL,
-		NO_APPROPRIATE_TARGET, STACK_IMMUNE_TO_SPELL, WRONG_SPELL_TARGET, ONGOING_TACTIC_PHASE,
-		MAGIC_IS_BLOCKED, //For Orb of Inhibition and similar - no casting at all
-		INVALID
-	};
-}
-
-namespace ECommander
-{
-	enum SecondarySkills {ATTACK, DEFENSE, HEALTH, DAMAGE, SPEED, SPELL_POWER, CASTS, RESISTANCE};
-	const int MAX_SKILL_LEVEL = 5;
-}
-
-enum class EWallPart : int8_t
-{
-	INDESTRUCTIBLE_PART_OF_GATE = -3, INDESTRUCTIBLE_PART = -2, INVALID = -1,
-	KEEP = 0, BOTTOM_TOWER, BOTTOM_WALL, BELOW_GATE, OVER_GATE, UPPER_WALL, UPPER_TOWER, GATE,
-	PARTS_COUNT /* This constant SHOULD always stay as the last item in the enum. */
-};
-
-enum class EWallState : int8_t
-{
-	NONE = -1, //no wall
-	DESTROYED,
-	DAMAGED,
-	INTACT,
-	REINFORCED, // walls in towns with castle
-};
-
-enum class EGateState : uint8_t
-{
-	NONE,
-	CLOSED,
-	BLOCKED, // gate is blocked in closed state, e.g. by creature
-	OPENED,
-	DESTROYED
-};
-
-namespace ESiegeHex
-{
-	enum ESiegeHex : si16
-	{
-		DESTRUCTIBLE_WALL_1 = 29,
-		DESTRUCTIBLE_WALL_2 = 78,
-		DESTRUCTIBLE_WALL_3 = 130,
-		DESTRUCTIBLE_WALL_4 = 182,
-		GATE_BRIDGE = 94,
-		GATE_OUTER = 95,
-		GATE_INNER = 96
-	};
-}
-
-namespace ETileType
-{
-	enum ETileType
-	{
-		FREE,
-		POSSIBLE,
-		BLOCKED,
-		USED
-	};
-}
-
-enum class ETeleportChannelType
-{
-	IMPASSABLE,
-	BIDIRECTIONAL,
-	UNIDIRECTIONAL,
-	MIXED
-};
-
-class Obj
-{
-public:
-	enum EObj
-	{
-		NO_OBJ = -1,
-		ALTAR_OF_SACRIFICE [[deprecated]] = 2,
-		ANCHOR_POINT = 3,
-		ARENA = 4,
-		ARTIFACT = 5,
-		PANDORAS_BOX = 6,
-		BLACK_MARKET [[deprecated]] = 7,
-		BOAT = 8,
-		BORDERGUARD = 9,
-		KEYMASTER = 10,
-		BUOY = 11,
-		CAMPFIRE = 12,
-		CARTOGRAPHER = 13,
-		SWAN_POND = 14,
-		COVER_OF_DARKNESS = 15,
-		CREATURE_BANK = 16,
-		CREATURE_GENERATOR1 = 17,
-		CREATURE_GENERATOR2 = 18,
-		CREATURE_GENERATOR3 = 19,
-		CREATURE_GENERATOR4 = 20,
-		CURSED_GROUND1 = 21,
-		CORPSE = 22,
-		MARLETTO_TOWER = 23,
-		DERELICT_SHIP = 24,
-		DRAGON_UTOPIA = 25,
-		EVENT = 26,
-		EYE_OF_MAGI = 27,
-		FAERIE_RING = 28,
-		FLOTSAM = 29,
-		FOUNTAIN_OF_FORTUNE = 30,
-		FOUNTAIN_OF_YOUTH = 31,
-		GARDEN_OF_REVELATION = 32,
-		GARRISON = 33,
-		HERO = 34,
-		HILL_FORT = 35,
-		GRAIL = 36,
-		HUT_OF_MAGI = 37,
-		IDOL_OF_FORTUNE = 38,
-		LEAN_TO = 39,
-		LIBRARY_OF_ENLIGHTENMENT = 41,
-		LIGHTHOUSE = 42,
-		MONOLITH_ONE_WAY_ENTRANCE = 43,
-		MONOLITH_ONE_WAY_EXIT = 44,
-		MONOLITH_TWO_WAY = 45,
-		MAGIC_PLAINS1 = 46,
-		SCHOOL_OF_MAGIC = 47,
-		MAGIC_SPRING = 48,
-		MAGIC_WELL = 49,
-		MARKET_OF_TIME = 50,
-		MERCENARY_CAMP = 51,
-		MERMAID = 52,
-		MINE = 53,
-		MONSTER = 54,
-		MYSTICAL_GARDEN = 55,
-		OASIS = 56,
-		OBELISK = 57,
-		REDWOOD_OBSERVATORY = 58,
-		OCEAN_BOTTLE = 59,
-		PILLAR_OF_FIRE = 60,
-		STAR_AXIS = 61,
-		PRISON = 62,
-		PYRAMID = 63,//subtype 0
-		WOG_OBJECT = 63,//subtype > 0
-		RALLY_FLAG = 64,
-		RANDOM_ART = 65,
-		RANDOM_TREASURE_ART = 66,
-		RANDOM_MINOR_ART = 67,
-		RANDOM_MAJOR_ART = 68,
-		RANDOM_RELIC_ART = 69,
-		RANDOM_HERO = 70,
-		RANDOM_MONSTER = 71,
-		RANDOM_MONSTER_L1 = 72,
-		RANDOM_MONSTER_L2 = 73,
-		RANDOM_MONSTER_L3 = 74,
-		RANDOM_MONSTER_L4 = 75,
-		RANDOM_RESOURCE = 76,
-		RANDOM_TOWN = 77,
-		REFUGEE_CAMP = 78,
-		RESOURCE = 79,
-		SANCTUARY = 80,
-		SCHOLAR = 81,
-		SEA_CHEST = 82,
-		SEER_HUT = 83,
-		CRYPT = 84,
-		SHIPWRECK = 85,
-		SHIPWRECK_SURVIVOR = 86,
-		SHIPYARD = 87,
-		SHRINE_OF_MAGIC_INCANTATION = 88,
-		SHRINE_OF_MAGIC_GESTURE = 89,
-		SHRINE_OF_MAGIC_THOUGHT = 90,
-		SIGN = 91,
-		SIRENS = 92,
-		SPELL_SCROLL = 93,
-		STABLES = 94,
-		TAVERN = 95,
-		TEMPLE = 96,
-		DEN_OF_THIEVES = 97,
-		TOWN = 98,
-		TRADING_POST [[deprecated]] = 99,
-		LEARNING_STONE = 100,
-		TREASURE_CHEST = 101,
-		TREE_OF_KNOWLEDGE = 102,
-		SUBTERRANEAN_GATE = 103,
-		UNIVERSITY [[deprecated]] = 104,
-		WAGON = 105,
-		WAR_MACHINE_FACTORY = 106,
-		SCHOOL_OF_WAR = 107,
-		WARRIORS_TOMB = 108,
-		WATER_WHEEL = 109,
-		WATERING_HOLE = 110,
-		WHIRLPOOL = 111,
-		WINDMILL = 112,
-		WITCH_HUT = 113,
-		HOLE = 124,
-		RANDOM_MONSTER_L5 = 162,
-		RANDOM_MONSTER_L6 = 163,
-		RANDOM_MONSTER_L7 = 164,
-		BORDER_GATE = 212,
-		FREELANCERS_GUILD [[deprecated]] = 213,
-		HERO_PLACEHOLDER = 214,
-		QUEST_GUARD = 215,
-		RANDOM_DWELLING = 216,
-		RANDOM_DWELLING_LVL = 217, //subtype = creature level
-		RANDOM_DWELLING_FACTION = 218, //subtype = faction
-		GARRISON2 = 219,
-		ABANDONED_MINE = 220,
-		TRADING_POST_SNOW [[deprecated]] = 221,
-		CLOVER_FIELD = 222,
-		CURSED_GROUND2 = 223,
-		EVIL_FOG = 224,
-		FAVORABLE_WINDS = 225,
-		FIERY_FIELDS = 226,
-		HOLY_GROUNDS = 227,
-		LUCID_POOLS = 228,
-		MAGIC_CLOUDS = 229,
-		MAGIC_PLAINS2 = 230,
-		ROCKLANDS = 231,
-	};
-	Obj(EObj _num = NO_OBJ) : num(_num)
-	{}
-
-	ID_LIKE_CLASS_COMMON(Obj, EObj)
-
-	EObj num;
-};
-
-ID_LIKE_OPERATORS(Obj, Obj::EObj)
-
-enum class Road : int8_t
-{
-	NO_ROAD = 0,
-	FIRST_REGULAR_ROAD = 1,
-	DIRT_ROAD = 1,
-	GRAVEL_ROAD = 2,
-	COBBLESTONE_ROAD = 3,
-	ORIGINAL_ROAD_COUNT //+1
-};
-
-enum class River : int8_t
-{
-	NO_RIVER = 0,
-	FIRST_REGULAR_RIVER = 1,
-	WATER_RIVER = 1,
-	ICY_RIVER = 2,
-	MUD_RIVER = 3,
-	LAVA_RIVER = 4,
-	ORIGINAL_RIVER_COUNT //+1
-};
-
-namespace SecSkillLevel
-{
-	enum SecSkillLevel
-	{
-		NONE,
-		BASIC,
-		ADVANCED,
-		EXPERT,
-		LEVELS_SIZE
-	};
-}
-
-namespace Date
-{
-	enum EDateType
-	{
-		DAY = 0,
-		DAY_OF_WEEK = 1,
-		WEEK = 2,
-		MONTH = 3,
-		DAY_OF_MONTH
-	};
-}
-
-enum class EActionType : int8_t
-{
-	NO_ACTION,
-
-	END_TACTIC_PHASE,
-	RETREAT,
-	SURRENDER,
-
-	HERO_SPELL,
-
-	WALK,
-	WAIT,
-	DEFEND,
-	WALK_AND_ATTACK,
-	SHOOT,
-	CATAPULT,
-	MONSTER_SPELL,
-	BAD_MORALE,
-	STACK_HEAL,
-};
-
-DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const EActionType actionType);
-
-class DLL_LINKAGE EDiggingStatus
-{
-public:
-	enum EEDiggingStatus
-	{
-		UNKNOWN = -1,
-		CAN_DIG = 0,
-		LACK_OF_MOVEMENT,
-		WRONG_TERRAIN,
-		TILE_OCCUPIED,
-		BACKPACK_IS_FULL
-	};
-
-	EDiggingStatus(EEDiggingStatus _num = UNKNOWN) : num(_num)
-	{}
-
-	ID_LIKE_CLASS_COMMON(EDiggingStatus, EEDiggingStatus)
-
-	EEDiggingStatus num;
-};
-
-ID_LIKE_OPERATORS(EDiggingStatus, EDiggingStatus::EEDiggingStatus)
-
-class DLL_LINKAGE EPathfindingLayer
-{
-public:
-	enum EEPathfindingLayer : ui8
-	{
-		LAND = 0, SAIL = 1, WATER, AIR, NUM_LAYERS, WRONG, AUTO
-	};
-
-	EPathfindingLayer(EEPathfindingLayer _num = WRONG) : num(_num)
-	{}
-
-	ID_LIKE_CLASS_COMMON(EPathfindingLayer, EEPathfindingLayer)
-
-	EEPathfindingLayer num;
-};
-
-DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const EPathfindingLayer & pathfindingLayer);
-
-ID_LIKE_OPERATORS(EPathfindingLayer, EPathfindingLayer::EEPathfindingLayer)
-
-namespace EPlayerStatus
-{
-	enum EStatus {WRONG = -1, INGAME, LOSER, WINNER};
-}
-
-namespace PlayerRelations
-{
-	enum PlayerRelations {ENEMIES, ALLIES, SAME_PLAYER};
-}
-
-class ArtifactPosition
-{
-public:
-	enum EArtifactPosition
-	{
-		TRANSITION_POS = -3,
-		FIRST_AVAILABLE = -2,
-		PRE_FIRST = -1, //sometimes used as error, sometimes as first free in backpack
-		HEAD, SHOULDERS, NECK, RIGHT_HAND, LEFT_HAND, TORSO, //5
-		RIGHT_RING, LEFT_RING, FEET, //8
-		MISC1, MISC2, MISC3, MISC4, //12
-		MACH1, MACH2, MACH3, MACH4, //16
-		SPELLBOOK, MISC5, //18
-		AFTER_LAST,
-		//cres
-		CREATURE_SLOT = 0,
-		COMMANDER1 = 0, COMMANDER2, COMMANDER3, COMMANDER4, COMMANDER5, COMMANDER6, COMMANDER_AFTER_LAST
-	};
-
-	static_assert (AFTER_LAST == 19, "incorrect number of artifact slots");
-
-	ArtifactPosition(EArtifactPosition _num = PRE_FIRST) : num(_num)
-	{}
-
-	ArtifactPosition(std::string slotName);
-
-	ID_LIKE_CLASS_COMMON(ArtifactPosition, EArtifactPosition)
-
-	EArtifactPosition num;
-
-        STRONG_INLINE EArtifactPosition operator+(const int arg)
-	{
-		return EArtifactPosition(static_cast<int>(num) + arg);
-	}
-	STRONG_INLINE EArtifactPosition operator+(const EArtifactPosition & arg)
-	{
-		return EArtifactPosition(static_cast<int>(num) + static_cast<int>(arg));
-	}
-};
-
-ID_LIKE_OPERATORS(ArtifactPosition, ArtifactPosition::EArtifactPosition)
-
-namespace GameConstants
-{
-	const auto BACKPACK_START = ArtifactPosition::AFTER_LAST;
-}
-
-class ArtifactID
-{
-public:
-	enum EArtifactID
-	{
-		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,
-		VIAL_OF_DRAGON_BLOOD = 127,
-		ARMAGEDDONS_BLADE = 128,
-		TITANS_THUNDER = 135,
-		//CORNUCOPIA = 140,
-		//FIXME: the following is only true if WoG is enabled. Otherwise other mod artifacts will take these slots.
-		ART_SELECTION = 144,
-		ART_LOCK = 145, // FIXME: We must get rid of this one since it's conflict with artifact from mods. See issue 2455
-		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
-	};
-
-	ArtifactID(EArtifactID _num = NONE) : num(_num)
-	{}
-
-	DLL_LINKAGE const CArtifact * toArtifact() const;
-	DLL_LINKAGE const Artifact * toArtifact(const ArtifactService * service) const;
-
-	///json serialization helpers
-	static si32 decode(const std::string & identifier);
-	static std::string encode(const si32 index);
-
-	ID_LIKE_CLASS_COMMON(ArtifactID, EArtifactID)
-
-	EArtifactID num;
-
-	struct hash
-	{
-		size_t operator()(const ArtifactID & aid) const
-		{
-			return std::hash<int>()(aid.num);
-		}
-	};
-};
-
-ID_LIKE_OPERATORS(ArtifactID, ArtifactID::EArtifactID)
-
-class CreatureID
-{
-public:
-	enum ECreatureID
-	{
-		NONE = -1,
-		ARCHER = 2,
-		CAVALIER = 10,
-		CHAMPION = 11,
-		STONE_GOLEM = 32,
-		IRON_GOLEM = 33,
-		IMP = 42,
-		SKELETON = 56,
-		WALKING_DEAD = 58,
-		WIGHTS = 60,
-		LICHES = 64,
-		BONE_DRAGON = 68,
-		TROGLODYTES = 70,
-		MEDUSA = 76,
-		HYDRA = 110,
-		CHAOS_HYDRA = 111,
-		AIR_ELEMENTAL = 112,
-		EARTH_ELEMENTAL = 113,
-		FIRE_ELEMENTAL = 114,
-		WATER_ELEMENTAL = 115,
-		GOLD_GOLEM = 116,
-		DIAMOND_GOLEM = 117,
-		PSYCHIC_ELEMENTAL = 120,
-		MAGIC_ELEMENTAL = 121,
-		CATAPULT = 145,
-		BALLISTA = 146,
-		FIRST_AID_TENT = 147,
-		AMMO_CART = 148,
-		ARROW_TOWERS = 149
-	};
-
-	CreatureID(ECreatureID _num = NONE) : num(_num)
-	{}
-
-	DLL_LINKAGE const CCreature * toCreature() const;
-	DLL_LINKAGE const Creature * toCreature(const CreatureService * creatures) const;
-
-	ID_LIKE_CLASS_COMMON(CreatureID, ECreatureID)
-
-	ECreatureID num;
-
-	///json serialization helpers
-	static si32 decode(const std::string & identifier);
-	static std::string encode(const si32 index);
-};
-
-ID_LIKE_OPERATORS(CreatureID, CreatureID::ECreatureID)
-
-class SpellID
-{
-public:
-	enum ESpellID
-	{
-		SPELLBOOK_PRESET = -3,
-		PRESET = -2,
-		NONE = -1,
-		SUMMON_BOAT=0, SCUTTLE_BOAT=1, VISIONS=2, VIEW_EARTH=3, DISGUISE=4, VIEW_AIR=5,
-		FLY=6, WATER_WALK=7, DIMENSION_DOOR=8, TOWN_PORTAL=9,
-
-		QUICKSAND=10, LAND_MINE=11, FORCE_FIELD=12, FIRE_WALL=13, EARTHQUAKE=14,
-		MAGIC_ARROW=15, ICE_BOLT=16, LIGHTNING_BOLT=17, IMPLOSION=18,
-		CHAIN_LIGHTNING=19, FROST_RING=20, FIREBALL=21, INFERNO=22,
-		METEOR_SHOWER=23, DEATH_RIPPLE=24, DESTROY_UNDEAD=25, ARMAGEDDON=26,
-		SHIELD=27, AIR_SHIELD=28, FIRE_SHIELD=29, PROTECTION_FROM_AIR=30,
-		PROTECTION_FROM_FIRE=31, PROTECTION_FROM_WATER=32,
-		PROTECTION_FROM_EARTH=33, ANTI_MAGIC=34, DISPEL=35, MAGIC_MIRROR=36,
-		CURE=37, RESURRECTION=38, ANIMATE_DEAD=39, SACRIFICE=40, BLESS=41,
-		CURSE=42, BLOODLUST=43, PRECISION=44, WEAKNESS=45, STONE_SKIN=46,
-		DISRUPTING_RAY=47, PRAYER=48, MIRTH=49, SORROW=50, FORTUNE=51,
-		MISFORTUNE=52, HASTE=53, SLOW=54, SLAYER=55, FRENZY=56,
-		TITANS_LIGHTNING_BOLT=57, COUNTERSTRIKE=58, BERSERK=59, HYPNOTIZE=60,
-		FORGETFULNESS=61, BLIND=62, TELEPORT=63, REMOVE_OBSTACLE=64, CLONE=65,
-		SUMMON_FIRE_ELEMENTAL=66, SUMMON_EARTH_ELEMENTAL=67, SUMMON_WATER_ELEMENTAL=68, SUMMON_AIR_ELEMENTAL=69,
-
-		STONE_GAZE=70, POISON=71, BIND=72, DISEASE=73, PARALYZE=74, AGE=75, DEATH_CLOUD=76, THUNDERBOLT=77,
-		DISPEL_HELPFUL_SPELLS=78, DEATH_STARE=79, ACID_BREATH_DEFENSE=80, ACID_BREATH_DAMAGE=81,
-
-		FIRST_NON_SPELL = 70, AFTER_LAST = 82
-	};
-
-	SpellID(ESpellID _num = NONE) : num(_num)
-	{}
-
-	DLL_LINKAGE const CSpell * toSpell() const; //deprecated
-	DLL_LINKAGE const spells::Spell * toSpell(const spells::Service * service) const;
-
-	ID_LIKE_CLASS_COMMON(SpellID, ESpellID)
-
-	ESpellID num;
-
-	///json serialization helpers
-	static si32 decode(const std::string & identifier);
-	static std::string encode(const si32 index);
-};
-
-ID_LIKE_OPERATORS(SpellID, SpellID::ESpellID)
-
-class BattleFieldInfo;
-class BattleField : public BaseForID<BattleField, si32>
-{
-	INSTID_LIKE_CLASS_COMMON(BattleField, si32)
-
-	DLL_LINKAGE static const BattleField NONE;
-
-	DLL_LINKAGE friend bool operator==(const BattleField & l, const BattleField & r);
-	DLL_LINKAGE friend bool operator!=(const BattleField & l, const BattleField & r);
-	DLL_LINKAGE friend bool operator<(const BattleField & l, const BattleField & r);
-
-	DLL_LINKAGE const BattleFieldInfo * getInfo() const;
-};
-
-enum class EBoatId : int32_t
-{
-	NONE = -1,
-	NECROPOLIS = 0,
-	CASTLE,
-	FORTRESS
-};
-
-using BoatId = Identifier<EBoatId>;
-
-enum class ETerrainId {
-	NATIVE_TERRAIN = -4,
-	ANY_TERRAIN = -3,
-	NONE = -1,
-	FIRST_REGULAR_TERRAIN = 0,
-	DIRT = 0,
-	SAND,
-	GRASS,
-	SNOW,
-	SWAMP,
-	ROUGH,
-	SUBTERRANEAN,
-	LAVA,
-	WATER,
-	ROCK,
-	ORIGINAL_REGULAR_TERRAIN_COUNT = ROCK
-};
-
-using TerrainId = Identifier<ETerrainId>;
-using RoadId = Identifier<Road>;
-using RiverId = Identifier<River>;
-
-class ObstacleInfo;
-class Obstacle : public BaseForID<Obstacle, si32>
-{
-	INSTID_LIKE_CLASS_COMMON(Obstacle, si32)
-
-	DLL_LINKAGE const ObstacleInfo * getInfo() const;
-};
-
-enum class ESpellSchool: int8_t
-{
-	ANY 	= -1,
-	AIR 	= 0,
-	FIRE 	= 1,
-	WATER 	= 2,
-	EARTH 	= 3,
-};
-
-using SpellSchool = Identifier<ESpellSchool>;
-
-enum class EMetaclass: ui8
-{
-	INVALID = 0,
-	ARTIFACT,
-	CREATURE,
-	FACTION,
-	EXPERIENCE,
-	HERO,
-	HEROCLASS,
-	LUCK,
-	MANA,
-	MORALE,
-	MOVEMENT,
-	OBJECT,
-	PRIMARY_SKILL,
-	SECONDARY_SKILL,
-	SPELL,
-	RESOURCE
-};
-
-enum class EHealLevel: ui8
-{
-	HEAL,
-	RESURRECT,
-	OVERHEAL
-};
-
-enum class EHealPower : ui8
-{
-	ONE_BATTLE,
-	PERMANENT
-};
-
-enum class EBattleResult : int8_t
-{
-	NORMAL = 0,
-	ESCAPE = 1,
-	SURRENDER = 2
-};
-
-// Typedef declarations
 using TExpType = si64;
 using TQuantity = si32;
-
 using TRmgTemplateZoneId = int;
 
-#undef ID_LIKE_CLASS_COMMON
-#undef ID_LIKE_OPERATORS
-#undef ID_LIKE_OPERATORS_INTERNAL
-#undef INSTID_LIKE_CLASS_COMMON
-
 VCMI_LIB_NAMESPACE_END

+ 1 - 1
lib/IGameCallback.h

@@ -92,7 +92,7 @@ public:
 	virtual bool removeObject(const CGObjectInstance * obj)=0;
 	virtual void createObject(const int3 & visitablePosition, Obj type, int32_t subtype = 0) = 0;
 	virtual void setOwner(const CGObjectInstance * objid, PlayerColor owner)=0;
-	virtual void changePrimSkill(const CGHeroInstance * hero, PrimarySkill::PrimarySkill which, si64 val, bool abs=false)=0;
+	virtual void changePrimSkill(const CGHeroInstance * hero, PrimarySkill which, si64 val, bool abs=false)=0;
 	virtual void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false)=0;
 	virtual void showBlockingDialog(BlockingDialog *iw) =0;
 	virtual void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits) =0; //cb will be called when player closes garrison window

+ 1 - 1
lib/IGameEventsReceiver.h

@@ -98,7 +98,7 @@ public:
 	virtual void heroCreated(const CGHeroInstance*){};
 	virtual void heroInGarrisonChange(const CGTownInstance *town){};
 	virtual void heroMoved(const TryMoveHero & details, bool verbose = true){};
-	virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val){};
+	virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkill which, si64 val){};
 	virtual void heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val){};
 	virtual void heroManaPointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after spell casts
 	virtual void heroMovePointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after movement

+ 1 - 1
lib/JsonNode.cpp

@@ -23,7 +23,7 @@
 #include "VCMI_Lib.h" //for identifier resolution
 #include "CGeneralTextHandler.h"
 #include "JsonDetail.h"
-#include "StringConstants.h"
+#include "constants/StringConstants.h"
 #include "battle/BattleHex.h"
 
 namespace

+ 6 - 6
lib/JsonRandom.cpp

@@ -15,7 +15,7 @@
 
 #include "JsonNode.h"
 #include "CRandomGenerator.h"
-#include "StringConstants.h"
+#include "constants/StringConstants.h"
 #include "VCMI_Lib.h"
 #include "CArtHandler.h"
 #include "CCreatureHandler.h"
@@ -119,7 +119,7 @@ namespace JsonRandom
 		std::vector<si32> ret;
 		if(value.isStruct())
 		{
-			for(const auto & name : PrimarySkill::names)
+			for(const auto & name : NPrimarySkill::names)
 			{
 				ret.push_back(loadValue(value[name], rng));
 			}
@@ -127,12 +127,12 @@ namespace JsonRandom
 		if(value.isVector())
 		{
 			ret.resize(GameConstants::PRIMARY_SKILLS, 0);
-			std::set<std::string> defaultStats(std::begin(PrimarySkill::names), std::end(PrimarySkill::names));
+			std::set<std::string> defaultStats(std::begin(NPrimarySkill::names), std::end(NPrimarySkill::names));
 			for(const auto & element : value.Vector())
 			{
 				auto key = loadKey(element, rng, defaultStats);
 				defaultStats.erase(key);
-				int id = vstd::find_pos(PrimarySkill::names, key);
+				int id = vstd::find_pos(NPrimarySkill::names, key);
 				if(id != -1)
 					ret[id] += loadValue(element, rng);
 			}
@@ -195,10 +195,10 @@ namespace JsonRandom
 				allowedClasses.insert(CArtHandler::stringToClass(entry.String()));
 
 		if (value["slot"].getType() == JsonNode::JsonType::DATA_STRING)
-			allowedPositions.insert(ArtifactPosition(value["class"].String()));
+			allowedPositions.insert(ArtifactPosition::decode(value["class"].String()));
 		else
 			for(const auto & entry : value["slot"].Vector())
-				allowedPositions.insert(ArtifactPosition(entry.String()));
+				allowedPositions.insert(ArtifactPosition::decode(entry.String()));
 
 		if (!value["minValue"].isNull()) minValue = static_cast<ui32>(value["minValue"].Float());
 		if (!value["maxValue"].isNull()) maxValue = static_cast<ui32>(value["maxValue"].Float());

+ 3 - 3
lib/NetPacks.h

@@ -232,7 +232,7 @@ struct DLL_LINKAGE SetPrimSkill : public CPackForClient
 
 	ui8 abs = 0; //0 - changes by value; 1 - sets to value
 	ObjectInstanceID id;
-	PrimarySkill::PrimarySkill which = PrimarySkill::ATTACK;
+	PrimarySkill which = PrimarySkill::ATTACK;
 	si64 val = 0;
 
 	template <typename Handler> void serialize(Handler & h, const int version)
@@ -1318,7 +1318,7 @@ struct DLL_LINKAGE HeroLevelUp : public Query
 	PlayerColor player;
 	ObjectInstanceID heroId;
 
-	PrimarySkill::PrimarySkill primskill = PrimarySkill::ATTACK;
+	PrimarySkill primskill = PrimarySkill::ATTACK;
 	std::vector<SecondarySkill> skills;
 
 	void applyGs(CGameState * gs) const;
@@ -2425,7 +2425,7 @@ struct DLL_LINKAGE TradeOnMarketplace : public CPackForServer
 	ObjectInstanceID marketId;
 	ObjectInstanceID heroId;
 
-	EMarketMode::EMarketMode mode = EMarketMode::RESOURCE_RESOURCE;
+	EMarketMode mode = EMarketMode::RESOURCE_RESOURCE;
 	std::vector<ui32> r1, r2; //mode 0: r1 - sold resource, r2 - bought res (exception: when sacrificing art r1 is art id [todo: make r2 preferred slot?]
 	std::vector<ui32> val; //units of sold resource
 

+ 4 - 4
lib/NetPacksLib.cpp

@@ -1382,7 +1382,7 @@ void HeroRecruited::applyGs(CGameState * gs) const
 	CGTownInstance *t = gs->getTown(tid);
 	PlayerState *p = gs->getPlayerState(player);
 
-	if (boatId >= 0)
+	if (boatId != ObjectInstanceID::NONE)
 	{
 		CGObjectInstance *obj = gs->getObjInstance(boatId);
 		auto * boat = dynamic_cast<CGBoat *>(obj);
@@ -1418,7 +1418,7 @@ void GiveHero::applyGs(CGameState * gs) const
 {
 	CGHeroInstance *h = gs->getHero(id);
 
-	if (boatId >= 0)
+	if (boatId != ObjectInstanceID::NONE)
 	{
 		CGObjectInstance *obj = gs->getObjInstance(boatId);
 		auto * boat = dynamic_cast<CGBoat *>(obj);
@@ -1880,7 +1880,7 @@ void BulkMoveArtifacts::applyGs(CGameState * gs)
 				break;
 			}
 
-			if(srcPos >= GameConstants::BACKPACK_START)
+			if(srcPos >= ArtifactPosition::BACKPACK_START)
 			{
 				numBackpackArtifactsMoved++;
 			}
@@ -1925,7 +1925,7 @@ void AssembledArtifact::applyGs(CGameState *gs)
 	{
 		ArtifactPosition pos = combineEquipped ? artSet->getArtPos(constituent->getId(), true, false) :
 			artSet->getArtBackpackPos(constituent->getId());
-		assert(pos >= 0);
+		assert(pos != ArtifactPosition::PRE_FIRST);
 		CArtifactInstance * constituentInstance = artSet->getArt(pos);
 
 		//move constituent from hero to be part of new, combined artifact

+ 4 - 4
lib/ResourceSet.cpp

@@ -11,7 +11,7 @@
 #include "StdInc.h"
 #include "GameConstants.h"
 #include "ResourceSet.h"
-#include "StringConstants.h"
+#include "constants/StringConstants.h"
 #include "JsonNode.h"
 #include "serializer/JsonSerializeFormat.h"
 #include "mapObjects/CObjectHandler.h"
@@ -119,7 +119,7 @@ std::string ResourceSet::toString() const
 
 bool ResourceSet::nziterator::valid() const
 {
-	return cur.resType < GameConstants::RESOURCE_QUANTITY && cur.resVal;
+	return cur.resType < GameResID::COUNT && cur.resVal;
 }
 
 ResourceSet::nziterator ResourceSet::nziterator::operator++()
@@ -150,9 +150,9 @@ void ResourceSet::nziterator::advance()
 	do
 	{
 		++cur.resType;
-	} while(cur.resType < GameConstants::RESOURCE_QUANTITY && !(cur.resVal=rs[cur.resType]));
+	} while(cur.resType < GameResID::COUNT && !(cur.resVal=rs[cur.resType]));
 
-	if(cur.resType >= GameConstants::RESOURCE_QUANTITY)
+	if(cur.resType >= GameResID::COUNT)
 		cur.resVal = -1;
 }
 

+ 0 - 10
lib/ResourceSet.h

@@ -22,16 +22,6 @@ class JsonSerializeFormat;
 
 class ResourceSet;
 
-enum class EGameResID : int8_t
-{
-	WOOD = 0, MERCURY, ORE, SULFUR, CRYSTAL, GEMS, GOLD, MITHRIL,
-
-	WOOD_AND_ORE = 127,  // special case for town bonus resource
-	INVALID = -1
-};
-
-using GameResID = Identifier<EGameResID>;
-
 //class to be representing a vector of resource
 class ResourceSet
 {

+ 0 - 125
lib/StringConstants.h

@@ -1,125 +0,0 @@
-/*
- * StringConstants.h, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
-#pragma once
-
-#include "GameConstants.h"
-
-VCMI_LIB_NAMESPACE_BEGIN
-
-///
-/// String ID which are pointless to move to config file - these types are mostly hardcoded
-///
-namespace GameConstants
-{
-	const std::string RESOURCE_NAMES [RESOURCE_QUANTITY] = {
-	    "wood", "mercury", "ore", "sulfur", "crystal", "gems", "gold", "mithril"
-	};
-
-	const std::string PLAYER_COLOR_NAMES [PlayerColor::PLAYER_LIMIT_I] = {
-		"red", "blue", "tan", "green", "orange", "purple", "teal", "pink"
-	};
-
-	const std::string ALIGNMENT_NAMES [3] = {"good", "evil", "neutral"};
-}
-
-namespace PrimarySkill
-{
-	const std::string names [GameConstants::PRIMARY_SKILLS] = { "attack", "defence", "spellpower", "knowledge" };
-}
-
-namespace NSecondarySkill
-{
-	const std::string names [GameConstants::SKILL_QUANTITY] =
-	{
-		"pathfinding",  "archery",      "logistics",    "scouting",     "diplomacy",    //  5
-		"navigation",   "leadership",   "wisdom",       "mysticism",    "luck",         // 10
-		"ballistics",   "eagleEye",     "necromancy",   "estates",      "fireMagic",    // 15
-		"airMagic",     "waterMagic",   "earthMagic",   "scholar",      "tactics",      // 20
-		"artillery",    "learning",     "offence",      "armorer",      "intelligence", // 25
-		"sorcery",      "resistance",   "firstAid"
-	};
-
-	const std::vector<std::string> levels =
-	{
-	    "none", "basic", "advanced", "expert"
-	};
-}
-
-namespace EBuildingType
-{
-	const std::string names [44] =
-	{
-		"mageGuild1",       "mageGuild2",       "mageGuild3",       "mageGuild4",       "mageGuild5",       //  5
-		"tavern",           "shipyard",         "fort",             "citadel",          "castle",           // 10
-		"villageHall",      "townHall",         "cityHall",         "capitol",          "marketplace",      // 15
-		"resourceSilo",     "blacksmith",       "special1",         "horde1",           "horde1Upgr",       // 20
-		"ship",             "special2",         "special3",         "special4",         "horde2",           // 25
-		"horde2Upgr",       "grail",            "extraTownHall",    "extraCityHall",    "extraCapitol",     // 30
-		"dwellingLvl1",     "dwellingLvl2",     "dwellingLvl3",     "dwellingLvl4",     "dwellingLvl5",     // 35
-		"dwellingLvl6",     "dwellingLvl7",     "dwellingUpLvl1",   "dwellingUpLvl2",   "dwellingUpLvl3",   // 40
-		"dwellingUpLvl4",   "dwellingUpLvl5",   "dwellingUpLvl6",   "dwellingUpLvl7"
-	};
-}
-
-namespace ETownType
-{
-	const std::string names [GameConstants::F_NUMBER] =
-	{
-		"castle",       "rampart",      "tower",
-		"inferno",      "necropolis",   "dungeon",
-		"stronghold",   "fortress",     "conflux"
-	};
-}
-
-namespace NArtifactPosition
-{
-	const std::string namesHero [19] =
-	{
-		"head", "shoulders", "neck", "rightHand", "leftHand", "torso", //5
-		"rightRing", "leftRing", "feet", //8
-		"misc1", "misc2", "misc3", "misc4", //12
-		"mach1", "mach2", "mach3", "mach4", //16
-		"spellbook", "misc5" //18
-	};
-
-	const std::string namesCreature[1] =
-	{
-		"creature1"
-	};
-
-	const std::string namesCommander[6] =
-	{
-		"commander1", "commander2", "commander3", "commander4", "commander5", "commander6",
-	};
-
-
-	const std::string backpack = "backpack";
-}
-
-namespace NMetaclass
-{
-    const std::string names [16] =
-    {
-		"",
-		"artifact", "creature", "faction", "experience", "hero",
-		"heroClass", "luck", "mana", "morale", "movement",
-		"object", "primarySkill", "secondarySkill", "spell", "resource"
-    };
-}
-
-namespace NPathfindingLayer
-{
-	const std::string names[EPathfindingLayer::NUM_LAYERS] =
-	{
-		"land", "sail", "water", "air"
-	};
-}
-
-VCMI_LIB_NAMESPACE_END

+ 1 - 4
lib/battle/BattleAction.cpp

@@ -122,9 +122,6 @@ BattleAction BattleAction::makeRetreat(ui8 side)
 
 std::string BattleAction::toString() const
 {
-	std::stringstream actionTypeStream;
-	actionTypeStream << actionType;
-
 	std::stringstream targetStream;
 
 	for(const DestinationInfo & info : target)
@@ -143,7 +140,7 @@ std::string BattleAction::toString() const
 	}
 
 	boost::format fmt("{BattleAction: side '%d', stackNumber '%d', actionType '%s', actionSubtype '%d', target {%s}}");
-	fmt % static_cast<int>(side) % stackNumber % actionTypeStream.str() % spell.getNum() % targetStream.str();
+	fmt % static_cast<int>(side) % stackNumber % static_cast<int>(actionType) % spell.getNum() % targetStream.str();
 	return fmt.str();
 }
 

+ 8 - 0
lib/battle/BattleHex.h

@@ -47,6 +47,14 @@ struct DLL_LINKAGE BattleHex //TODO: decide if this should be changed to class f
 	static constexpr si16 HEX_BEFORE_ALL = std::numeric_limits<si16>::min();
 	static constexpr si16 HEX_AFTER_ALL = std::numeric_limits<si16>::max();
 
+	static constexpr si16 DESTRUCTIBLE_WALL_1 = 29;
+	static constexpr si16 DESTRUCTIBLE_WALL_2 = 78;
+	static constexpr si16 DESTRUCTIBLE_WALL_3 = 130;
+	static constexpr si16 DESTRUCTIBLE_WALL_4 = 182;
+	static constexpr si16 GATE_BRIDGE = 94;
+	static constexpr si16 GATE_OUTER = 95;
+	static constexpr si16 GATE_INNER = 96;
+
 	si16 hex;
 	static constexpr si16 INVALID = -1;
 	enum EDir

+ 2 - 2
lib/battle/BattleInfo.cpp

@@ -475,8 +475,8 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, TerrainId terrain, const
 	static auto nativeTerrain = std::make_shared<CreatureTerrainLimiter>();
 	
 	curB->addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::STACKS_SPEED, BonusSource::TERRAIN_NATIVE, 1, 0, 0)->addLimiter(nativeTerrain));
-	curB->addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::PRIMARY_SKILL, BonusSource::TERRAIN_NATIVE, 1, 0, PrimarySkill::ATTACK)->addLimiter(nativeTerrain));
-	curB->addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::PRIMARY_SKILL, BonusSource::TERRAIN_NATIVE, 1, 0, PrimarySkill::DEFENSE)->addLimiter(nativeTerrain));
+	curB->addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::PRIMARY_SKILL, BonusSource::TERRAIN_NATIVE, 1, 0, static_cast<int>(PrimarySkill::ATTACK))->addLimiter(nativeTerrain));
+	curB->addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::PRIMARY_SKILL, BonusSource::TERRAIN_NATIVE, 1, 0, static_cast<int>(PrimarySkill::DEFENSE))->addLimiter(nativeTerrain));
 	//////////////////////////////////////////////////////////////////////////
 
 	//tactics

+ 10 - 10
lib/battle/CBattleInfoCallback.cpp

@@ -93,7 +93,7 @@ static BattleHex WallPartToHex(EWallPart part)
 
 using namespace SiegeStuffThatShouldBeMovedToHandlers;
 
-ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastSpell(const spells::Caster * caster, spells::Mode mode) const
+ESpellCastProblem CBattleInfoCallback::battleCanCastSpell(const spells::Caster * caster, spells::Mode mode) const
 {
 	RETURN_IF_NOT_BATTLE(ESpellCastProblem::INVALID);
 	if(caster == nullptr)
@@ -187,7 +187,7 @@ bool CBattleInfoCallback::battleHasPenaltyOnLine(BattleHex from, BattleHex dest,
 
 		auto obstacles = battleGetAllObstaclesOnPos(hex, false);
 
-		if(hex != ESiegeHex::GATE_BRIDGE || (battleIsGatePassable()))
+		if(hex != BattleHex::GATE_BRIDGE || (battleIsGatePassable()))
 			for(const auto & obst : obstacles)
 				if(obst->obstacleType ==  CObstacleInstance::MOAT)
 					pathHasMoat |= true;
@@ -821,7 +821,7 @@ std::vector<std::shared_ptr<const CObstacleInstance>> CBattleInfoCallback::getAl
 						affectedObstacles.push_back(i);
 		}
 		for(auto hex : unit->getHexes())
-			if(hex == ESiegeHex::GATE_BRIDGE && battleIsGatePassable())
+			if(hex == BattleHex::GATE_BRIDGE && battleIsGatePassable())
 				for(int i=0; i<affectedObstacles.size(); i++)
 					if(affectedObstacles.at(i)->obstacleType == CObstacleInstance::MOAT)
 						affectedObstacles.erase(affectedObstacles.begin()+i);
@@ -926,7 +926,7 @@ AccessibilityInfo CBattleInfoCallback::getAccesibility() const
 			accessability = EAccessibility::UNAVAILABLE;
 			break;
 		}
-		ret[ESiegeHex::GATE_OUTER] = ret[ESiegeHex::GATE_INNER] = accessability;
+		ret[BattleHex::GATE_OUTER] = ret[BattleHex::GATE_INNER] = accessability;
 	}
 
 	//tiles occupied by standing stacks
@@ -955,10 +955,10 @@ AccessibilityInfo CBattleInfoCallback::getAccesibility() const
 		static const std::pair<EWallPart, BattleHex> lockedIfNotDestroyed[] =
 		{
 			//which part of wall, which hex is blocked if this part of wall is not destroyed
-			std::make_pair(EWallPart::BOTTOM_WALL, BattleHex(ESiegeHex::DESTRUCTIBLE_WALL_4)),
-			std::make_pair(EWallPart::BELOW_GATE, BattleHex(ESiegeHex::DESTRUCTIBLE_WALL_3)),
-			std::make_pair(EWallPart::OVER_GATE, BattleHex(ESiegeHex::DESTRUCTIBLE_WALL_2)),
-			std::make_pair(EWallPart::UPPER_WALL, BattleHex(ESiegeHex::DESTRUCTIBLE_WALL_1))
+			std::make_pair(EWallPart::BOTTOM_WALL, BattleHex(BattleHex::DESTRUCTIBLE_WALL_4)),
+			std::make_pair(EWallPart::BELOW_GATE, BattleHex(BattleHex::DESTRUCTIBLE_WALL_3)),
+			std::make_pair(EWallPart::OVER_GATE, BattleHex(BattleHex::DESTRUCTIBLE_WALL_2)),
+			std::make_pair(EWallPart::UPPER_WALL, BattleHex(BattleHex::DESTRUCTIBLE_WALL_1))
 		};
 
 		for(const auto & elem : lockedIfNotDestroyed)
@@ -1055,7 +1055,7 @@ bool CBattleInfoCallback::isInObstacle(
 
 		if(vstd::contains(obstacles, occupiedHex))
 		{
-			if(occupiedHex == ESiegeHex::GATE_BRIDGE)
+			if(occupiedHex == BattleHex::GATE_BRIDGE)
 			{
 				if(battleGetGateState() != EGateState::DESTROYED && params.side == BattleSide::ATTACKER)
 					return true;
@@ -1080,7 +1080,7 @@ std::set<BattleHex> CBattleInfoCallback::getStoppers(BattlePerspective::BattlePe
 
 		for(const auto & hex : oi->getStoppingTile())
 		{
-			if(hex == ESiegeHex::GATE_BRIDGE && oi->obstacleType == CObstacleInstance::MOAT)
+			if(hex == BattleHex::GATE_BRIDGE && oi->obstacleType == CObstacleInstance::MOAT)
 			{
 				if(battleGetGateState() == EGateState::OPENED || battleGetGateState() == EGateState::DESTROYED)
 					continue; // this tile is disabled by drawbridge on top of it

+ 1 - 1
lib/battle/CBattleInfoCallback.h

@@ -118,7 +118,7 @@ public:
 	si8 battleMinSpellLevel(ui8 side) const; //calculates maximum spell level possible to be cast on battlefield - takes into account artifacts of both heroes; if no effects are set, 0 is returned
 	si8 battleMaxSpellLevel(ui8 side) const; //calculates minimum spell level possible to be cast on battlefield - takes into account artifacts of both heroes; if no effects are set, 0 is returned
 	int32_t battleGetSpellCost(const spells::Spell * sp, const CGHeroInstance * caster) const; //returns cost of given spell
-	ESpellCastProblem::ESpellCastProblem battleCanCastSpell(const spells::Caster * caster, spells::Mode mode) const; //returns true if there are no general issues preventing from casting a spell
+	ESpellCastProblem battleCanCastSpell(const spells::Caster * caster, spells::Mode mode) const; //returns true if there are no general issues preventing from casting a spell
 
 	SpellID battleGetRandomStackSpell(CRandomGenerator & rand, const CStack * stack, ERandomSpell mode) const;
 	SpellID getRandomBeneficialSpell(CRandomGenerator & rand, const CStack * subject) const;

+ 2 - 2
lib/battle/CUnitState.cpp

@@ -342,8 +342,8 @@ CUnitState::CUnitState():
 	totalAttacks(this, Selector::type()(BonusType::ADDITIONAL_ATTACK), 1),
 	minDamage(this, Selector::typeSubtype(BonusType::CREATURE_DAMAGE, 0).Or(Selector::typeSubtype(BonusType::CREATURE_DAMAGE, 1)), 0),
 	maxDamage(this, Selector::typeSubtype(BonusType::CREATURE_DAMAGE, 0).Or(Selector::typeSubtype(BonusType::CREATURE_DAMAGE, 2)), 0),
-	attack(this, Selector::typeSubtype(BonusType::PRIMARY_SKILL, PrimarySkill::ATTACK), 0),
-	defence(this, Selector::typeSubtype(BonusType::PRIMARY_SKILL, PrimarySkill::DEFENSE), 0),
+	attack(this, Selector::typeSubtype(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::ATTACK)), 0),
+	defence(this, Selector::typeSubtype(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::DEFENSE)), 0),
 	inFrenzy(this, Selector::type()(BonusType::IN_FRENZY)),
 	cloneLifetimeMarker(this, Selector::type()(BonusType::NONE).And(Selector::source(BonusSource::SPELL_EFFECT, SpellID::CLONE))),
 	cloneID(-1)

+ 2 - 2
lib/battle/DamageCalculator.cpp

@@ -50,9 +50,9 @@ DamageRange DamageCalculator::getBaseDamageSingle() const
 
 	if(info.attacker->hasBonus(selectorSiedgeWeapon, cachingStrSiedgeWeapon) && info.attacker->creatureIndex() != CreatureID::ARROW_TOWERS)
 	{
-		auto retrieveHeroPrimSkill = [&](int skill) -> int
+		auto retrieveHeroPrimSkill = [&](PrimarySkill skill) -> int
 		{
-			std::shared_ptr<const Bonus> b = info.attacker->getBonus(Selector::sourceTypeSel(BonusSource::HERO_BASE_SKILL).And(Selector::typeSubtype(BonusType::PRIMARY_SKILL, skill)));
+			std::shared_ptr<const Bonus> b = info.attacker->getBonus(Selector::sourceTypeSel(BonusSource::HERO_BASE_SKILL).And(Selector::typeSubtype(BonusType::PRIMARY_SKILL, static_cast<int>(skill))));
 			return b ? b->val : 0;
 		};
 

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.