浏览代码

Converted remaining identifier to new system

Ivan Savenko 2 年之前
父节点
当前提交
e54287ea5d
共有 91 个文件被更改,包括 1590 次插入1654 次删除
  1. 1 1
      AI/Nullkiller/AIGateway.cpp
  2. 1 1
      AI/Nullkiller/Analyzers/BuildAnalyzer.cpp
  3. 1 1
      AI/Nullkiller/Goals/AbstractGoal.cpp
  4. 1 1
      AI/Nullkiller/Goals/BuildThis.cpp
  5. 1 1
      AI/Nullkiller/Goals/Composition.cpp
  6. 1 1
      AI/Nullkiller/Goals/RecruitHero.cpp
  7. 1 1
      AI/VCAI/BuildingManager.cpp
  8. 1 1
      AI/VCAI/Goals/AbstractGoal.cpp
  9. 1 1
      AI/VCAI/Goals/Build.cpp
  10. 1 1
      AI/VCAI/Goals/BuildThis.cpp
  11. 1 1
      AI/VCAI/Goals/CollectRes.cpp
  12. 1 1
      AI/VCAI/Goals/Conquer.cpp
  13. 1 1
      AI/VCAI/Goals/Explore.cpp
  14. 1 1
      AI/VCAI/Goals/GatherArmy.cpp
  15. 1 1
      AI/VCAI/Goals/GatherTroops.cpp
  16. 1 1
      AI/VCAI/Goals/RecruitHero.cpp
  17. 1 1
      AI/VCAI/Goals/VisitObj.cpp
  18. 1 1
      AI/VCAI/Goals/VisitTile.cpp
  19. 1 1
      AI/VCAI/Goals/Win.cpp
  20. 1 1
      AI/VCAI/VCAI.cpp
  21. 1 1
      client/CMusicHandler.cpp
  22. 1 1
      client/CPlayerInterface.cpp
  23. 1 1
      client/ClientCommandManager.cpp
  24. 1 1
      client/adventureMap/AdventureMapWidget.cpp
  25. 12 12
      client/lobby/OptionsTab.cpp
  26. 1 1
      client/widgets/CArtifactsOfHeroBackpack.cpp
  27. 3 3
      client/widgets/CArtifactsOfHeroBase.cpp
  28. 6 4
      client/windows/CCastleInterface.cpp
  29. 2 2
      client/windows/CCastleInterface.h
  30. 5 1
      cmake_modules/VCMI_lib.cmake
  31. 1 1
      include/vcmi/Faction.h
  32. 8 8
      lib/ArtifactUtils.cpp
  33. 2 2
      lib/ArtifactUtils.h
  34. 14 15
      lib/CArtHandler.cpp
  35. 1 0
      lib/CArtifactInstance.h
  36. 6 2
      lib/CBuildingHandler.cpp
  37. 1 1
      lib/CCreatureHandler.cpp
  38. 1 1
      lib/CHeroHandler.cpp
  39. 1 0
      lib/CPlayerState.h
  40. 1 1
      lib/CSkillHandler.cpp
  41. 4 4
      lib/CTownHandler.cpp
  42. 1 1
      lib/CTownHandler.h
  43. 3 2
      lib/GameConstants.cpp
  44. 3 1376
      lib/GameConstants.h
  45. 1 1
      lib/JsonNode.cpp
  46. 3 3
      lib/JsonRandom.cpp
  47. 4 4
      lib/NetPacksLib.cpp
  48. 1 1
      lib/ResourceSet.cpp
  49. 0 125
      lib/StringConstants.h
  50. 1 4
      lib/battle/BattleAction.cpp
  51. 1 1
      lib/bonuses/Bonus.cpp
  52. 1 1
      lib/bonuses/Limiters.cpp
  53. 1 1
      lib/campaign/CampaignHandler.cpp
  54. 896 0
      lib/constants/EntityIdentifiers.h
  55. 251 0
      lib/constants/Enumerations.h
  56. 59 0
      lib/constants/NumericConstants.h
  57. 217 0
      lib/constants/StringConstants.h
  58. 3 3
      lib/gameState/CGameState.cpp
  59. 1 0
      lib/gameState/CGameState.h
  60. 1 1
      lib/gameState/CGameStateCampaign.cpp
  61. 1 1
      lib/mapObjectConstructors/CObjectClassesHandler.cpp
  62. 1 1
      lib/mapObjectConstructors/CommonConstructors.cpp
  63. 1 1
      lib/mapObjects/CGHeroInstance.cpp
  64. 1 1
      lib/mapObjects/CGObjectInstance.cpp
  65. 1 1
      lib/mapObjects/CGPandoraBox.cpp
  66. 3 3
      lib/mapObjects/CGTownInstance.cpp
  67. 2 2
      lib/mapObjects/CGTownInstance.h
  68. 2 2
      lib/mapObjects/CQuest.cpp
  69. 2 2
      lib/mapObjects/MiscObjects.cpp
  70. 1 1
      lib/mapObjects/MiscObjects.h
  71. 1 1
      lib/mapObjects/ObjectTemplate.cpp
  72. 3 3
      lib/mapping/MapFormatH3M.cpp
  73. 1 1
      lib/mapping/MapFormatJson.cpp
  74. 1 1
      lib/modding/CModHandler.cpp
  75. 1 1
      lib/modding/ContentTypeHandler.cpp
  76. 1 1
      lib/pathfinder/PathfinderUtil.h
  77. 1 1
      lib/rmg/CMapGenerator.cpp
  78. 1 1
      lib/rmg/CRmgTemplate.cpp
  79. 1 1
      lib/serializer/CSerializer.h
  80. 1 1
      lib/spells/CSpellHandler.cpp
  81. 1 1
      mapeditor/inspector/questwidget.cpp
  82. 1 1
      mapeditor/inspector/rewardswidget.cpp
  83. 1 1
      mapeditor/inspector/townbulidingswidget.cpp
  84. 1 1
      mapeditor/mapsettings.cpp
  85. 1 1
      mapeditor/playerparams.cpp
  86. 1 1
      server/CGameHandler.cpp
  87. 11 11
      server/CVCMIServer.cpp
  88. 1 1
      server/CVCMIServer.h
  89. 2 2
      server/battles/BattleResultProcessor.cpp
  90. 1 0
      server/queries/CQuery.h
  91. 1 1
      test/game/CGameStateTest.cpp

+ 1 - 1
AI/Nullkiller/AIGateway.cpp

@@ -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;

+ 1 - 1
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;
 		}

+ 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/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/BuildingManager.cpp

@@ -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;
 

+ 1 - 1
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;
 

+ 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;

+ 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;
 

+ 1 - 1
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;
 

+ 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;
 

+ 1 - 1
AI/VCAI/VCAI.cpp

@@ -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;

+ 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"

+ 1 - 1
client/CPlayerInterface.cpp

@@ -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);
 

+ 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/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 )

+ 12 - 12
client/lobby/OptionsTab.cpp

@@ -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;
 		}
 		}
@@ -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();
 		}
 		}
@@ -235,7 +235,7 @@ std::string OptionsTab::CPlayerSettingsHelper::getTitle()
 	case OptionsTab::TOWN:
 		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)
@@ -256,7 +256,7 @@ std::string OptionsTab::CPlayerSettingsHelper::getTitle()
 std::string OptionsTab::CPlayerSettingsHelper::getSubtitle()
 {
 	auto factionIndex = settings.castle.getNum() >= CGI->townh->size() ? 0 : settings.castle.getNum();
-	auto heroIndex = settings.hero >= CGI->heroh->size() ? 0 : settings.hero;
+	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();
 	}
@@ -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,7 +438,7 @@ 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.getNum() >= 0)
@@ -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)
@@ -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)
 			{
@@ -786,7 +786,7 @@ void OptionsTab::SelectedBox::showPopupWindow(const Point & cursorPosition)
 	// cases when we do not need to display a message
 	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);

+ 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);

+ 6 - 4
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();
@@ -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);

+ 2 - 2
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!!!
 };

+ 5 - 1
cmake_modules/VCMI_lib.cmake

@@ -369,6 +369,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 +626,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

+ 1 - 1
include/vcmi/Faction.h

@@ -15,7 +15,7 @@
 VCMI_LIB_NAMESPACE_BEGIN
 
 class FactionID;
-enum class EAlignment : uint8_t;
+enum class EAlignment : int8_t;
 class BoatId;
 
 class DLL_LINKAGE Faction : public EntityT<FactionID>, public INativeTerrainProvider

+ 8 - 8
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)

+ 2 - 2
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);

+ 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
 

+ 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;

+ 1 - 1
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"

+ 1 - 1
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"

+ 1 - 0
lib/CPlayerState.h

@@ -16,6 +16,7 @@
 #include "bonuses/CBonusSystemNode.h"
 #include "ResourceSet.h"
 #include "TurnTimerInfo.h"
+#include "ConstTransitivePtr.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 

+ 1 - 1
lib/CSkillHandler.cpp

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

+ 4 - 4
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++;
@@ -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;

+ 1 - 1
lib/CTownHandler.h

@@ -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 - 2
lib/GameConstants.cpp

@@ -32,7 +32,7 @@
 #include "CCreatureHandler.h"//todo: remove
 #include "spells/CSpellHandler.h" //todo: remove
 #include "CSkillHandler.h"//todo: remove
-#include "StringConstants.h"
+#include "constants/StringConstants.h"
 #include "CGeneralTextHandler.h"
 #include "TerrainHandler.h" //TODO: remove
 #include "BattleFieldHandler.h"
@@ -40,6 +40,7 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+const QueryID QueryID::NONE = QueryID(-1);
 const HeroTypeID HeroTypeID::NONE = HeroTypeID(-1);
 const ObjectInstanceID ObjectInstanceID::NONE = ObjectInstanceID(-1);
 
@@ -257,7 +258,7 @@ std::ostream & operator<<(std::ostream & os, const EActionType actionType)
 
 std::ostream & operator<<(std::ostream & os, const EPathfindingLayer & pathfindingLayer)
 {
-	static const std::map<EPathfindingLayer::EEPathfindingLayer, std::string> pathfinderLayerToString
+	static const std::map<EPathfindingLayer, std::string> pathfinderLayerToString
 	{
 	#define DEFINE_ELEMENT(element) {EPathfindingLayer::element, #element}
 		DEFINE_ELEMENT(WRONG),

+ 3 - 1376
lib/GameConstants.h

@@ -9,1387 +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 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());
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-class EntityBase
-{
-public:
-	int32_t num;
-
-	struct hash
-	{
-		size_t operator()(const EntityBase & id) const
-		{
-			return std::hash<int>()(id.num);
-		}
-	};
-};
-
-template<typename T>
-class EntityIdentifier : public T
-{
-	using EnumType = typename T::Type;
-
-	static_assert(std::is_same_v<std::underlying_type_t<EnumType>, int32_t>, "Entity Identifier must use int32_t");
-public:
-	constexpr int32_t getNum() const
-	{
-		return T::num;
-	}
-
-	constexpr EnumType toEnum() const
-	{
-		return static_cast<EnumType>(T::num);
-	}
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & T::num;
-	}
-
-	constexpr EntityIdentifier(const EnumType & enumValue)
-	{
-		T::num = static_cast<int32_t>(enumValue);
-	}
-
-	constexpr EntityIdentifier(int32_t _num = -1)
-	{
-		T::num = _num;
-	}
-
-	constexpr void advance(int change)
-	{
-		T::num += change;
-	}
-
-	constexpr bool operator == (const EnumType & b) const { return T::num == static_cast<int32_t>(b); }
-	constexpr bool operator <= (const EnumType & b) const { return T::num <= static_cast<int32_t>(b); }
-	constexpr bool operator >= (const EnumType & b) const { return T::num >= static_cast<int32_t>(b); }
-	constexpr bool operator != (const EnumType & b) const { return T::num != static_cast<int32_t>(b); }
-	constexpr bool operator <  (const EnumType & b) const { return T::num <  static_cast<int32_t>(b); }
-	constexpr bool operator >  (const EnumType & b) const { return T::num >  static_cast<int32_t>(b); }
-
-	constexpr bool operator == (const EntityIdentifier & b) const { return T::num == b.num; }
-	constexpr bool operator <= (const EntityIdentifier & b) const { return T::num <= b.num; }
-	constexpr bool operator >= (const EntityIdentifier & b) const { return T::num >= b.num; }
-	constexpr bool operator != (const EntityIdentifier & b) const { return T::num != b.num; }
-	constexpr bool operator <  (const EntityIdentifier & b) const { return T::num <  b.num; }
-	constexpr bool operator >  (const EntityIdentifier & b) const { return T::num >  b.num; }
-
-	constexpr EntityIdentifier & operator++()
-	{
-		++T::num;
-		return *this;
-	}
-
-	constexpr EntityIdentifier operator++(int)
-	{
-		EntityIdentifier ret(*this);
-		++T::num;
-		return ret;
-	}
-
-	constexpr operator int32_t () const
-	{
-		return T::num;
-	}
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-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;
-};
-
-// Enum declarations
-enum class PrimarySkill : int8_t
-{
-	NONE = -1,
-	ATTACK,
-	DEFENSE,
-	SPELL_POWER,
-	KNOWLEDGE,
-	EXPERIENCE = 4 //for some reason changePrimSkill uses it
-};
-
-class SecondarySkillBase : public EntityBase
-{
-public:
-	enum Type : int32_t
-	{
-		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");
-};
-
-class SecondarySkill : public EntityIdentifier<SecondarySkillBase>
-{
-public:
-	using EntityIdentifier<SecondarySkillBase>::EntityIdentifier;
-};
-
-enum class EAlignment : uint8_t { GOOD, EVIL, NEUTRAL };
-
-class FactionIDBase : public EntityBase
-{
-public:
-	enum Type : int32_t
-	{
-		NONE = -2,
-		DEFAULT = -1,
-		RANDOM = -1,
-		ANY = -1,
-		CASTLE,
-		RAMPART,
-		TOWER,
-		INFERNO,
-		NECROPOLIS,
-		DUNGEON,
-		STRONGHOLD,
-		FORTRESS,
-		CONFLUX,
-		NEUTRAL
-	};
-
-	static si32 decode(const std::string& identifier);
-	static std::string encode(const si32 index);
-	static std::string entityType();
-};
-
-class FactionID : public EntityIdentifier<FactionIDBase>
-{
-public:
-	using EntityIdentifier<FactionIDBase>::EntityIdentifier;
-};
-
-using ETownType = FactionID;
-
-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
-	};
-}
-
-enum class EMarketMode : int8_t
-{
-	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> 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 },
-	};
-}
-
-enum class EAiTactic : int8_t
-{
-	NONE = -1,
-	RANDOM,
-	WARRIOR,
-	BUILDER,
-	EXPLORER
-};
-
-enum class EBuildingState : int8_t
-{
-	HAVE_CAPITAL, NO_WATER, FORBIDDEN, ADD_MAGES_GUILD, ALREADY_PRESENT, CANT_BUILD_TODAY,
-	NO_RESOURCES, ALLOWED, PREREQUIRES, MISSING_BASE, BUILDING_ERROR, TOWN_NOT_OWNED
-};
-
-enum class ESpellCastProblem : int8_t
-{
-	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 : int8_t
-{
-	NONE,
-	CLOSED,
-	BLOCKED, // gate is blocked in closed state, e.g. by creature
-	OPENED,
-	DESTROYED
-};
-
-
-enum class ETileType : int8_t
-{
-	FREE,
-	POSSIBLE,
-	BLOCKED,
-	USED
-};
-
-enum class ETeleportChannelType : int8_t
-{
-	IMPASSABLE,
-	BIDIRECTIONAL,
-	UNIDIRECTIONAL,
-	MIXED
-};
-
-class ObjBase : public EntityBase
-{
-public:
-	enum Type
-	{
-		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,
-	};
-};
-
-class Obj : public EntityIdentifier<ObjBase>
-{
-public:
-	using EntityIdentifier<ObjBase>::EntityIdentifier;
-};
-
-class RoadIdBase : public EntityBase
-{
-public:
-	enum Type : int32_t
-	{
-		NO_ROAD = 0,
-		FIRST_REGULAR_ROAD = 1,
-		DIRT_ROAD = 1,
-		GRAVEL_ROAD = 2,
-		COBBLESTONE_ROAD = 3,
-		ORIGINAL_ROAD_COUNT //+1
-	};
-};
-
-class RoadId : public EntityIdentifier<RoadIdBase>
-{
-public:
-	using EntityIdentifier<RoadIdBase>::EntityIdentifier;
-};
-
-class RiverIdBase : public EntityBase
-{
-public:
-	enum Type : int32_t
-	{
-		NO_RIVER = 0,
-		FIRST_REGULAR_RIVER = 1,
-		WATER_RIVER = 1,
-		ICY_RIVER = 2,
-		MUD_RIVER = 3,
-		LAVA_RIVER = 4,
-		ORIGINAL_RIVER_COUNT //+1
-	};
-};
-
-class RiverId : public EntityIdentifier<RiverIdBase>
-{
-public:
-	using EntityIdentifier<RiverIdBase>::EntityIdentifier;
-};
-
-using River = RiverId;
-using Road = RoadId;
-
-namespace SecSkillLevel
-{
-	enum SecSkillLevel
-	{
-		NONE,
-		BASIC,
-		ADVANCED,
-		EXPERT,
-		LEVELS_SIZE
-	};
-}
-
-enum class Date : int8_t
-{
-	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);
-
-enum class EDiggingStatus : int8_t
-{
-	UNKNOWN = -1,
-	CAN_DIG = 0,
-	LACK_OF_MOVEMENT,
-	WRONG_TERRAIN,
-	TILE_OCCUPIED,
-	BACKPACK_IS_FULL
-};
-
-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)
-
-enum class EPlayerStatus
-{
-	WRONG = -1,
-	INGAME,
-	LOSER,
-	WINNER
-};
-
-enum class 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 ArtifactIDBase : public EntityBase
-{
-public:
-	enum Type
-	{
-		NONE = -1,
-		SPELLBOOK = 0,
-		SPELL_SCROLL = 1,
-		GRAIL = 2,
-		CATAPULT = 3,
-		BALLISTA = 4,
-		AMMO_CART = 5,
-		FIRST_AID_TENT = 6,
-		VIAL_OF_DRAGON_BLOOD = 127,
-		ARMAGEDDONS_BLADE = 128,
-		TITANS_THUNDER = 135,
-		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
-	};
-
-	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);
-};
-
-class ArtifactID : public EntityIdentifier<ArtifactIDBase>
-{
-public:
-	using EntityIdentifier<ArtifactIDBase>::EntityIdentifier;
-};
-
-class CreatureIDBase : public EntityBase
-{
-public:
-	enum Type
-	{
-		NONE = -1,
-		ARCHER = 2, // for debug / fallback
-		IMP = 42, // for Deity of Fire
-		SKELETON = 56, // for Skeleton Transformer
-		BONE_DRAGON = 68, // for Skeleton Transformer
-		TROGLODYTES = 70, // for Abandoned Mine
-		MEDUSA = 76, // for Siege UI workaround
-		HYDRA = 110, // for Skeleton Transformer
-		CHAOS_HYDRA = 111, // for Skeleton Transformer
-		AIR_ELEMENTAL = 112, // for tests
-		FIRE_ELEMENTAL = 114, // for tests
-		PSYCHIC_ELEMENTAL = 120, // for hardcoded ability
-		MAGIC_ELEMENTAL = 121, // for hardcoded ability
-		CATAPULT = 145,
-		BALLISTA = 146,
-		FIRST_AID_TENT = 147,
-		AMMO_CART = 148,
-		ARROW_TOWERS = 149
-	};
-
-	DLL_LINKAGE const CCreature * toCreature() const;
-	DLL_LINKAGE const Creature * toCreature(const CreatureService * creatures) const;
-
-	///json serialization helpers
-	static si32 decode(const std::string & identifier);
-	static std::string encode(const si32 index);
-};
-
-class CreatureID : public EntityIdentifier<CreatureIDBase>
-{
-public:
-	using EntityIdentifier<CreatureIDBase>::EntityIdentifier;
-};
-
-class SpellIDBase : public EntityBase
-{
-public:
-	enum Type
-	{
-		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
-	};
-
-	DLL_LINKAGE const CSpell * toSpell() const; //deprecated
-	DLL_LINKAGE const spells::Spell * toSpell(const spells::Service * service) const;
-
-	///json serialization helpers
-	static si32 decode(const std::string & identifier);
-	static std::string encode(const si32 index);
-};
-
-class SpellID : public EntityIdentifier<SpellIDBase>
-{
-public:
-	using EntityIdentifier<SpellIDBase>::EntityIdentifier;
-};
-
-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;
-};
-
-class BoatIdBase : public EntityBase
-{
-public:
-	enum Type : int32_t
-	{
-		NONE = -1,
-		NECROPOLIS = 0,
-		CASTLE,
-		FORTRESS
-	};
-};
-
-class BoatId : public EntityIdentifier<BoatIdBase>
-{
-public:
-	using EntityIdentifier<BoatIdBase>::EntityIdentifier;
-};
-
-class TerrainIdBase : public EntityBase
-{
-public:
-	enum Type : int32_t
-	{
-		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
-	};
-
-	static si32 decode(const std::string & identifier);
-	static std::string encode(const si32 index);
-	static std::string entityType();
-};
-
-class TerrainId : public EntityIdentifier<TerrainIdBase>
-{
-public:
-	using EntityIdentifier<TerrainIdBase>::EntityIdentifier;
-};
-
-using ETerrainId = TerrainId;
-
-class ObstacleInfo;
-class Obstacle : public BaseForID<Obstacle, si32>
-{
-	INSTID_LIKE_CLASS_COMMON(Obstacle, si32)
-
-	DLL_LINKAGE const ObstacleInfo * getInfo() const;
-};
-
-class SpellSchoolBase : public EntityBase
-{
-public:
-	enum Type : int32_t
-	{
-		ANY 	= -1,
-		AIR 	= 0,
-		FIRE 	= 1,
-		WATER 	= 2,
-		EARTH 	= 3,
-	};
-};
-
-class SpellSchool : public EntityIdentifier<SpellSchoolBase>
-{
-public:
-	using EntityIdentifier<SpellSchoolBase>::EntityIdentifier;
-};
-
-using ESpellSchool = SpellSchool;
-
-enum class EMetaclass: int8_t
-{
-	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
-};
-
-class GameResIDBase : public EntityBase
-{
-public:
-	enum Type : int32_t
-	{
-		WOOD = 0, MERCURY, ORE, SULFUR, CRYSTAL, GEMS, GOLD, MITHRIL,
-		COUNT,
-
-		WOOD_AND_ORE = 127,  // special case for town bonus resource
-		INVALID = -1
-	};
-};
-
-class GameResID : public EntityIdentifier<GameResIDBase>
-{
-public:
-	using EntityIdentifier<GameResIDBase>::EntityIdentifier;
-};
-
-using EGameResID = GameResID;
-
-// 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/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

+ 3 - 3
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"
@@ -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());

+ 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

+ 1 - 1
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"

+ 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 NPrimarySkill
-{
-	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 NFaction
-{
-	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();
 }
 

+ 1 - 1
lib/bonuses/Bonus.cpp

@@ -25,7 +25,7 @@
 #include "../CSkillHandler.h"
 #include "../CArtHandler.h"
 #include "../TerrainHandler.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../battle/BattleInfo.h"
 #include "../modding/ModUtility.h"
 

+ 1 - 1
lib/bonuses/Limiters.cpp

@@ -22,7 +22,7 @@
 #include "../CStack.h"
 #include "../CArtHandler.h"
 #include "../TerrainHandler.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../battle/BattleInfo.h"
 
 VCMI_LIB_NAMESPACE_BEGIN

+ 1 - 1
lib/campaign/CampaignHandler.cpp

@@ -21,7 +21,7 @@
 #include "../CGeneralTextHandler.h"
 #include "../TextOperations.h"
 #include "../Languages.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../mapping/CMapHeader.h"
 #include "../mapping/CMapService.h"
 #include "../modding/CModHandler.h"

+ 896 - 0
lib/constants/EntityIdentifiers.h

@@ -0,0 +1,896 @@
+/*
+ * GameConstants.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 "NumericConstants.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;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class IdentifierBase
+{
+protected:
+	constexpr IdentifierBase(int32_t value = -1 ):
+		num(value)
+	{}
+public:
+	int32_t num;
+
+	constexpr int32_t getNum() const
+	{
+		return num;
+	}
+
+	struct hash
+	{
+		size_t operator()(const IdentifierBase & id) const
+		{
+			return std::hash<int>()(id.num);
+		}
+	};
+
+	friend std::ostream& operator<<(std::ostream& os, const IdentifierBase& dt)
+	{
+		return os << dt.num;
+	}
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Note: use template to force different type, blocking any Identifier<A> <=> Identifier<B> comparisons
+template<typename FinalClass>
+class Identifier : public IdentifierBase
+{
+	using T = IdentifierBase;
+public:
+	constexpr Identifier(int32_t _num = -1)
+		:IdentifierBase(_num)
+	{}
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & T::num;
+	}
+
+	constexpr bool operator == (const Identifier & b) const { return T::num == b.num; }
+	constexpr bool operator <= (const Identifier & b) const { return T::num <= b.num; }
+	constexpr bool operator >= (const Identifier & b) const { return T::num >= b.num; }
+	constexpr bool operator != (const Identifier & b) const { return T::num != b.num; }
+	constexpr bool operator <  (const Identifier & b) const { return T::num <  b.num; }
+	constexpr bool operator >  (const Identifier & b) const { return T::num >  b.num; }
+
+	constexpr FinalClass & operator++()
+	{
+		++T::num;
+		return static_cast<FinalClass&>(*this);
+	}
+
+	constexpr FinalClass operator++(int)
+	{
+		FinalClass ret(num);
+		++T::num;
+		return ret;
+	}
+
+	constexpr operator int32_t () const
+	{
+		return T::num;
+	}
+
+	constexpr void advance(int change)
+	{
+		T::num += change;
+	}
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+template<typename T>
+class IdentifierWithEnum : public T
+{
+	using EnumType = typename T::Type;
+
+	static_assert(std::is_same_v<std::underlying_type_t<EnumType>, int32_t>, "Entity Identifier must use int32_t");
+public:
+	constexpr int32_t getNum() const
+	{
+		return T::num;
+	}
+
+	constexpr EnumType toEnum() const
+	{
+		return static_cast<EnumType>(T::num);
+	}
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & T::num;
+	}
+
+	constexpr IdentifierWithEnum(const EnumType & enumValue)
+	{
+		T::num = static_cast<int32_t>(enumValue);
+	}
+
+	constexpr IdentifierWithEnum(int32_t _num = -1)
+	{
+		T::num = _num;
+	}
+
+	constexpr void advance(int change)
+	{
+		T::num += change;
+	}
+
+	constexpr bool operator == (const EnumType & b) const { return T::num == static_cast<int32_t>(b); }
+	constexpr bool operator <= (const EnumType & b) const { return T::num <= static_cast<int32_t>(b); }
+	constexpr bool operator >= (const EnumType & b) const { return T::num >= static_cast<int32_t>(b); }
+	constexpr bool operator != (const EnumType & b) const { return T::num != static_cast<int32_t>(b); }
+	constexpr bool operator <  (const EnumType & b) const { return T::num <  static_cast<int32_t>(b); }
+	constexpr bool operator >  (const EnumType & b) const { return T::num >  static_cast<int32_t>(b); }
+
+	constexpr bool operator == (const IdentifierWithEnum & b) const { return T::num == b.num; }
+	constexpr bool operator <= (const IdentifierWithEnum & b) const { return T::num <= b.num; }
+	constexpr bool operator >= (const IdentifierWithEnum & b) const { return T::num >= b.num; }
+	constexpr bool operator != (const IdentifierWithEnum & b) const { return T::num != b.num; }
+	constexpr bool operator <  (const IdentifierWithEnum & b) const { return T::num <  b.num; }
+	constexpr bool operator >  (const IdentifierWithEnum & b) const { return T::num >  b.num; }
+
+	constexpr IdentifierWithEnum & operator++()
+	{
+		++T::num;
+		return *this;
+	}
+
+	constexpr IdentifierWithEnum operator++(int)
+	{
+		IdentifierWithEnum ret(*this);
+		++T::num;
+		return ret;
+	}
+
+	constexpr operator int32_t () const
+	{
+		return T::num;
+	}
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ArtifactInstanceID : public Identifier<ArtifactInstanceID>
+{
+public:
+	using Identifier<ArtifactInstanceID>::Identifier;
+};
+
+class QueryID : public Identifier<QueryID>
+{
+public:
+	using Identifier<QueryID>::Identifier;
+	DLL_LINKAGE static const QueryID NONE;
+};
+
+class ObjectInstanceID : public Identifier<ObjectInstanceID>
+{
+public:
+	using Identifier<ObjectInstanceID>::Identifier;
+	DLL_LINKAGE static const ObjectInstanceID NONE;
+};
+
+class HeroClassID : public Identifier<HeroClassID>
+{
+public:
+	using Identifier<HeroClassID>::Identifier;
+};
+
+class HeroTypeID : public Identifier<HeroTypeID>
+{
+public:
+	using Identifier<HeroTypeID>::Identifier;
+	///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 Identifier<SlotID>
+{
+public:
+	using Identifier<SlotID>::Identifier;
+
+	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 Identifier<PlayerColor>
+{
+public:
+	using Identifier<PlayerColor>::Identifier;
+
+	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;
+};
+
+class TeamID : public Identifier<TeamID>
+{
+public:
+	using Identifier<TeamID>::Identifier;
+
+	DLL_LINKAGE static const TeamID NO_TEAM;
+};
+
+class TeleportChannelID : public Identifier<TeleportChannelID>
+{
+public:
+	using Identifier<TeleportChannelID>::Identifier;
+};
+
+class SecondarySkillBase : public IdentifierBase
+{
+public:
+	enum Type : int32_t
+	{
+		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");
+};
+
+class SecondarySkill : public IdentifierWithEnum<SecondarySkillBase>
+{
+public:
+	using IdentifierWithEnum<SecondarySkillBase>::IdentifierWithEnum;
+};
+
+class FactionIDBase : public IdentifierBase
+{
+public:
+	enum Type : int32_t
+	{
+		NONE = -2,
+		DEFAULT = -1,
+		RANDOM = -1,
+		ANY = -1,
+		CASTLE,
+		RAMPART,
+		TOWER,
+		INFERNO,
+		NECROPOLIS,
+		DUNGEON,
+		STRONGHOLD,
+		FORTRESS,
+		CONFLUX,
+		NEUTRAL
+	};
+
+	static si32 decode(const std::string& identifier);
+	static std::string encode(const si32 index);
+	static std::string entityType();
+};
+
+class FactionID : public IdentifierWithEnum<FactionIDBase>
+{
+public:
+	using IdentifierWithEnum<FactionIDBase>::IdentifierWithEnum;
+};
+
+using ETownType = FactionID;
+
+class BuildingIDBase : public IdentifierBase
+{
+public:
+	//Quite useful as long as most of building mechanics hardcoded
+	// NOTE: all building with completely configurable mechanics will be removed from list
+	enum Type
+	{
+		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,
+
+		DWELL_UP2_FIRST = DWELL_LVL_7_UP + 1,
+
+		//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
+	};
+
+	bool IsSpecialOrGrail() const
+	{
+		return num == SPECIAL_1 || num == SPECIAL_2 || num == SPECIAL_3 || num == SPECIAL_4 || num == GRAIL;
+	}
+};
+
+class BuildingID : public IdentifierWithEnum<BuildingIDBase>
+{
+public:
+	using IdentifierWithEnum<BuildingIDBase>::IdentifierWithEnum;
+};
+
+class ObjBase : public IdentifierBase
+{
+public:
+	enum Type
+	{
+		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,
+	};
+};
+
+class Obj : public IdentifierWithEnum<ObjBase>
+{
+public:
+	using IdentifierWithEnum<ObjBase>::IdentifierWithEnum;
+};
+
+class RoadIdBase : public IdentifierBase
+{
+public:
+	enum Type : int32_t
+	{
+		NO_ROAD = 0,
+		FIRST_REGULAR_ROAD = 1,
+		DIRT_ROAD = 1,
+		GRAVEL_ROAD = 2,
+		COBBLESTONE_ROAD = 3,
+		ORIGINAL_ROAD_COUNT //+1
+	};
+};
+
+class RoadId : public IdentifierWithEnum<RoadIdBase>
+{
+public:
+	using IdentifierWithEnum<RoadIdBase>::IdentifierWithEnum;
+};
+
+class RiverIdBase : public IdentifierBase
+{
+public:
+	enum Type : int32_t
+	{
+		NO_RIVER = 0,
+		FIRST_REGULAR_RIVER = 1,
+		WATER_RIVER = 1,
+		ICY_RIVER = 2,
+		MUD_RIVER = 3,
+		LAVA_RIVER = 4,
+		ORIGINAL_RIVER_COUNT //+1
+	};
+};
+
+class RiverId : public IdentifierWithEnum<RiverIdBase>
+{
+public:
+	using IdentifierWithEnum<RiverIdBase>::IdentifierWithEnum;
+};
+
+using River = RiverId;
+using Road = RoadId;
+
+class DLL_LINKAGE EPathfindingLayerBase : public IdentifierBase
+{
+public:
+	enum Type : int32_t
+	{
+		LAND = 0, SAIL = 1, WATER, AIR, NUM_LAYERS, WRONG, AUTO
+	};
+};
+
+class EPathfindingLayer : public IdentifierWithEnum<EPathfindingLayerBase>
+{
+public:
+	using IdentifierWithEnum<EPathfindingLayerBase>::IdentifierWithEnum;
+};
+
+class ArtifactPositionBase : public IdentifierBase
+{
+public:
+	enum Type
+	{
+		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,
+
+		BACKPACK_START = 19
+	};
+
+	static_assert (AFTER_LAST == BACKPACK_START, "incorrect number of artifact slots");
+
+	static si32 decode(const std::string & identifier);
+	static std::string encode(const si32 index);
+};
+
+class ArtifactPosition : public IdentifierWithEnum<ArtifactPositionBase>
+{
+public:
+	using IdentifierWithEnum<ArtifactPositionBase>::IdentifierWithEnum;
+};
+
+class ArtifactIDBase : public IdentifierBase
+{
+public:
+	enum Type
+	{
+		NONE = -1,
+		SPELLBOOK = 0,
+		SPELL_SCROLL = 1,
+		GRAIL = 2,
+		CATAPULT = 3,
+		BALLISTA = 4,
+		AMMO_CART = 5,
+		FIRST_AID_TENT = 6,
+		VIAL_OF_DRAGON_BLOOD = 127,
+		ARMAGEDDONS_BLADE = 128,
+		TITANS_THUNDER = 135,
+		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
+	};
+
+	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);
+};
+
+class ArtifactID : public IdentifierWithEnum<ArtifactIDBase>
+{
+public:
+	using IdentifierWithEnum<ArtifactIDBase>::IdentifierWithEnum;
+};
+
+class CreatureIDBase : public IdentifierBase
+{
+public:
+	enum Type
+	{
+		NONE = -1,
+		ARCHER = 2, // for debug / fallback
+		IMP = 42, // for Deity of Fire
+		SKELETON = 56, // for Skeleton Transformer
+		BONE_DRAGON = 68, // for Skeleton Transformer
+		TROGLODYTES = 70, // for Abandoned Mine
+		MEDUSA = 76, // for Siege UI workaround
+		HYDRA = 110, // for Skeleton Transformer
+		CHAOS_HYDRA = 111, // for Skeleton Transformer
+		AIR_ELEMENTAL = 112, // for tests
+		FIRE_ELEMENTAL = 114, // for tests
+		PSYCHIC_ELEMENTAL = 120, // for hardcoded ability
+		MAGIC_ELEMENTAL = 121, // for hardcoded ability
+		CATAPULT = 145,
+		BALLISTA = 146,
+		FIRST_AID_TENT = 147,
+		AMMO_CART = 148,
+		ARROW_TOWERS = 149
+	};
+
+	DLL_LINKAGE const CCreature * toCreature() const;
+	DLL_LINKAGE const Creature * toCreature(const CreatureService * creatures) const;
+
+	///json serialization helpers
+	static si32 decode(const std::string & identifier);
+	static std::string encode(const si32 index);
+};
+
+class CreatureID : public IdentifierWithEnum<CreatureIDBase>
+{
+public:
+	using IdentifierWithEnum<CreatureIDBase>::IdentifierWithEnum;
+};
+
+class SpellIDBase : public IdentifierBase
+{
+public:
+	enum Type
+	{
+		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
+	};
+
+	DLL_LINKAGE const CSpell * toSpell() const; //deprecated
+	DLL_LINKAGE const spells::Spell * toSpell(const spells::Service * service) const;
+
+	///json serialization helpers
+	static si32 decode(const std::string & identifier);
+	static std::string encode(const si32 index);
+};
+
+class SpellID : public IdentifierWithEnum<SpellIDBase>
+{
+public:
+	using IdentifierWithEnum<SpellIDBase>::IdentifierWithEnum;
+};
+
+class BattleFieldInfo;
+class BattleField : public Identifier<BattleField>
+{
+public:
+	using Identifier<BattleField>::Identifier;
+
+	DLL_LINKAGE static const BattleField NONE;
+	DLL_LINKAGE const BattleFieldInfo * getInfo() const;
+};
+
+class BoatIdBase : public IdentifierBase
+{
+public:
+	enum Type : int32_t
+	{
+		NONE = -1,
+		NECROPOLIS = 0,
+		CASTLE,
+		FORTRESS
+	};
+};
+
+class BoatId : public IdentifierWithEnum<BoatIdBase>
+{
+public:
+	using IdentifierWithEnum<BoatIdBase>::IdentifierWithEnum;
+};
+
+class TerrainIdBase : public IdentifierBase
+{
+public:
+	enum Type : int32_t
+	{
+		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
+	};
+
+	static si32 decode(const std::string & identifier);
+	static std::string encode(const si32 index);
+	static std::string entityType();
+};
+
+class TerrainId : public IdentifierWithEnum<TerrainIdBase>
+{
+public:
+	using IdentifierWithEnum<TerrainIdBase>::IdentifierWithEnum;
+};
+
+using ETerrainId = TerrainId;
+
+class ObstacleInfo;
+class Obstacle : public Identifier<Obstacle>
+{
+public:
+	using Identifier<Obstacle>::Identifier;
+	DLL_LINKAGE const ObstacleInfo * getInfo() const;
+};
+
+class SpellSchoolBase : public IdentifierBase
+{
+public:
+	enum Type : int32_t
+	{
+		ANY 	= -1,
+		AIR 	= 0,
+		FIRE 	= 1,
+		WATER 	= 2,
+		EARTH 	= 3,
+	};
+};
+
+class SpellSchool : public IdentifierWithEnum<SpellSchoolBase>
+{
+public:
+	using IdentifierWithEnum<SpellSchoolBase>::IdentifierWithEnum;
+};
+
+using ESpellSchool = SpellSchool;
+
+class GameResIDBase : public IdentifierBase
+{
+public:
+	enum Type : int32_t
+	{
+		WOOD = 0, MERCURY, ORE, SULFUR, CRYSTAL, GEMS, GOLD, MITHRIL,
+		COUNT,
+
+		WOOD_AND_ORE = 127,  // special case for town bonus resource
+		INVALID = -1
+	};
+};
+
+class GameResID : public IdentifierWithEnum<GameResIDBase>
+{
+public:
+	using IdentifierWithEnum<GameResIDBase>::IdentifierWithEnum;
+};
+
+using EGameResID = GameResID;
+
+VCMI_LIB_NAMESPACE_END

+ 251 - 0
lib/constants/Enumerations.h

@@ -0,0 +1,251 @@
+/*
+ * GameConstants.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
+
+enum class PrimarySkill : int8_t
+{
+	NONE = -1,
+	ATTACK,
+	DEFENSE,
+	SPELL_POWER,
+	KNOWLEDGE,
+	EXPERIENCE = 4 //for some reason changePrimSkill uses it
+};
+
+enum class EAlignment : int8_t
+{
+	GOOD,
+	EVIL,
+	NEUTRAL
+};
+
+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
+	};
+}
+
+enum class EMarketMode : int8_t
+{
+	RESOURCE_RESOURCE, RESOURCE_PLAYER, CREATURE_RESOURCE, RESOURCE_ARTIFACT,
+	ARTIFACT_RESOURCE, ARTIFACT_EXP, CREATURE_EXP, CREATURE_UNDEAD, RESOURCE_SKILL,
+	MARTKET_AFTER_LAST_PLACEHOLDER
+};
+
+enum class EAiTactic : int8_t
+{
+	NONE = -1,
+	RANDOM,
+	WARRIOR,
+	BUILDER,
+	EXPLORER
+};
+
+enum class EBuildingState : int8_t
+{
+	HAVE_CAPITAL, NO_WATER, FORBIDDEN, ADD_MAGES_GUILD, ALREADY_PRESENT, CANT_BUILD_TODAY,
+	NO_RESOURCES, ALLOWED, PREREQUIRES, MISSING_BASE, BUILDING_ERROR, TOWN_NOT_OWNED
+};
+
+enum class ESpellCastProblem : int8_t
+{
+	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 : int8_t
+{
+	NONE,
+	CLOSED,
+	BLOCKED, // gate is blocked in closed state, e.g. by creature
+	OPENED,
+	DESTROYED
+};
+
+enum class ETileType : int8_t
+{
+	FREE,
+	POSSIBLE,
+	BLOCKED,
+	USED
+};
+
+enum class ETeleportChannelType : int8_t
+{
+	IMPASSABLE,
+	BIDIRECTIONAL,
+	UNIDIRECTIONAL,
+	MIXED
+};
+
+namespace SecSkillLevel
+{
+	enum SecSkillLevel
+	{
+		NONE,
+		BASIC,
+		ADVANCED,
+		EXPERT,
+		LEVELS_SIZE
+	};
+}
+
+enum class Date : int8_t
+{
+	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,
+};
+
+enum class EDiggingStatus : int8_t
+{
+	UNKNOWN = -1,
+	CAN_DIG = 0,
+	LACK_OF_MOVEMENT,
+	WRONG_TERRAIN,
+	TILE_OCCUPIED,
+	BACKPACK_IS_FULL
+};
+
+enum class EPlayerStatus : int8_t
+{
+	WRONG = -1,
+	INGAME,
+	LOSER,
+	WINNER
+};
+
+enum class PlayerRelations : int8_t
+{
+	ENEMIES,
+	ALLIES,
+	SAME_PLAYER
+};
+
+enum class EMetaclass : int8_t
+{
+	INVALID = 0,
+	ARTIFACT,
+	CREATURE,
+	FACTION,
+	EXPERIENCE,
+	HERO,
+	HEROCLASS,
+	LUCK,
+	MANA,
+	MORALE,
+	MOVEMENT,
+	OBJECT,
+	PRIMARY_SKILL,
+	SECONDARY_SKILL,
+	SPELL,
+	RESOURCE
+};
+
+enum class EHealLevel: int8_t
+{
+	HEAL,
+	RESURRECT,
+	OVERHEAL
+};
+
+enum class EHealPower : int8_t
+{
+	ONE_BATTLE,
+	PERMANENT
+};
+
+enum class EBattleResult : int8_t
+{
+	NORMAL = 0,
+	ESCAPE = 1,
+	SURRENDER = 2,
+};
+
+VCMI_LIB_NAMESPACE_END

+ 59 - 0
lib/constants/NumericConstants.h

@@ -0,0 +1,59 @@
+/*
+ * GameConstants.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
+
+VCMI_LIB_NAMESPACE_BEGIN
+
+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};
+}
+
+VCMI_LIB_NAMESPACE_END

+ 217 - 0
lib/constants/StringConstants.h

@@ -0,0 +1,217 @@
+/*
+ * constants/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 NPrimarySkill
+{
+	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 NFaction
+{
+	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"
+	};
+}
+
+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> 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 },
+	};
+}
+
+
+VCMI_LIB_NAMESPACE_END

+ 3 - 3
lib/gameState/CGameState.cpp

@@ -107,7 +107,7 @@ static CGObjectInstance * createObject(const Obj & id, int subid, const int3 & p
 HeroTypeID CGameState::pickNextHeroType(const PlayerColor & owner)
 {
 	const PlayerSettings &ps = scenarioOps->getIthPlayersSettings(owner);
-	if(ps.hero >= 0 && !isUsedHero(HeroTypeID(ps.hero))) //we haven't used selected hero
+	if(ps.hero >= HeroTypeID(0) && !isUsedHero(HeroTypeID(ps.hero))) //we haven't used selected hero
 	{
 		return HeroTypeID(ps.hero);
 	}
@@ -777,7 +777,7 @@ void CGameState::placeStartingHeroes()
 				continue;
 
 			int heroTypeId = pickNextHeroType(playerColor);
-			if(playerSettingPair.second.hero == -1)
+			if(playerSettingPair.second.hero == HeroTypeID::NONE)
 				playerSettingPair.second.hero = heroTypeId;
 
 			placeStartingHero(playerColor, HeroTypeID(heroTypeId), playerInfo.posOfMainTown);
@@ -2063,7 +2063,7 @@ std::set<HeroTypeID> CGameState::getUnusedAllowedHeroes(bool alsoIncludeNotAllow
 
 	for(const auto & playerSettingPair : scenarioOps->playerInfos) //remove uninitialized yet heroes picked for start by other players
 	{
-		if(playerSettingPair.second.hero != PlayerSettings::RANDOM)
+		if(playerSettingPair.second.hero.getNum() != PlayerSettings::RANDOM)
 			ret -= HeroTypeID(playerSettingPair.second.hero);
 	}
 

+ 1 - 0
lib/gameState/CGameState.h

@@ -12,6 +12,7 @@
 #include "bonuses/CBonusSystemNode.h"
 #include "IGameCallback.h"
 #include "LoadProgress.h"
+#include "ConstTransitivePtr.h"
 
 namespace boost
 {

+ 1 - 1
lib/gameState/CGameStateCampaign.cpp

@@ -146,7 +146,7 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(std::vector<CampaignHeroR
 
 			// process in reverse - removal of artifact will shift all artifacts after this one
 			for(int slotNumber = hero->artifactsInBackpack.size() - 1; slotNumber >= 0; slotNumber--)
-				checkAndRemoveArtifact(ArtifactPosition(GameConstants::BACKPACK_START + slotNumber));
+				checkAndRemoveArtifact(ArtifactPosition::BACKPACK_START + slotNumber);
 		}
 	}
 

+ 1 - 1
lib/mapObjectConstructors/CObjectClassesHandler.cpp

@@ -14,7 +14,7 @@
 #include "../filesystem/CBinaryReader.h"
 #include "../VCMI_Lib.h"
 #include "../GameConstants.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../CGeneralTextHandler.h"
 #include "../GameSettings.h"
 #include "../JsonNode.h"

+ 1 - 1
lib/mapObjectConstructors/CommonConstructors.cpp

@@ -15,7 +15,7 @@
 #include "../CTownHandler.h"
 #include "../IGameCallback.h"
 #include "../JsonRandom.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../TerrainHandler.h"
 #include "../VCMI_Lib.h"
 

+ 1 - 1
lib/mapObjects/CGHeroInstance.cpp

@@ -35,7 +35,7 @@
 #include "../mapObjectConstructors/AObjectTypeHandler.h"
 #include "../mapObjectConstructors/CObjectClassesHandler.h"
 #include "../modding/ModScope.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../battle/Unit.h"
 
 VCMI_LIB_NAMESPACE_BEGIN

+ 1 - 1
lib/mapObjects/CGObjectInstance.cpp

@@ -18,7 +18,7 @@
 #include "../CGeneralTextHandler.h"
 #include "../IGameCallback.h"
 #include "../NetPacks.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../TerrainHandler.h"
 #include "../mapObjectConstructors/AObjectTypeHandler.h"
 #include "../mapObjectConstructors/CObjectClassesHandler.h"

+ 1 - 1
lib/mapObjects/CGPandoraBox.cpp

@@ -20,7 +20,7 @@
 #include "../CSkillHandler.h"
 #include "../StartInfo.h"
 #include "../IGameCallback.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../serializer/JsonSerializeFormat.h"
 
 VCMI_LIB_NAMESPACE_BEGIN

+ 3 - 3
lib/mapObjects/CGTownInstance.cpp

@@ -364,7 +364,7 @@ void CGTownInstance::initOverriddenBids()
 	}
 }
 
-bool CGTownInstance::isBonusingBuildingAdded(BuildingID::EBuildingID bid) const
+bool CGTownInstance::isBonusingBuildingAdded(BuildingID bid) const
 {
 	auto present = std::find_if(bonusingBuildings.begin(), bonusingBuildings.end(), [&](CGTownBuilding* building)
 		{
@@ -428,7 +428,7 @@ DamageRange CGTownInstance::getKeepDamageRange() const
 	};
 }
 
-void CGTownInstance::deleteTownBonus(BuildingID::EBuildingID bid)
+void CGTownInstance::deleteTownBonus(BuildingID bid)
 {
 	size_t i = 0;
 	CGTownBuilding * freeIt = nullptr;
@@ -467,7 +467,7 @@ void CGTownInstance::initObj(CRandomGenerator & rand) ///initialize town structu
 
 	for (int level = 0; level < GameConstants::CREATURES_PER_TOWN; level++)
 	{
-		BuildingID buildID = BuildingID(BuildingID::DWELL_FIRST).advance(level);
+		BuildingID buildID = BuildingID(BuildingID::DWELL_FIRST + level);
 		int upgradeNum = 0;
 
 		for (; town->buildings.count(buildID); upgradeNum++, buildID.advance(GameConstants::CREATURES_PER_TOWN))

+ 2 - 2
lib/mapObjects/CGTownInstance.h

@@ -175,7 +175,7 @@ public:
 	void removeCapitols(const PlayerColor & owner) const;
 	void clearArmy() const;
 	void addHeroToStructureVisitors(const CGHeroInstance *h, si64 structureInstanceID) const; //hero must be visiting or garrisoned in town
-	void deleteTownBonus(BuildingID::EBuildingID bid);
+	void deleteTownBonus(BuildingID bid);
 
 	/// Returns damage range for secondary towers of this town
 	DamageRange getTowerDamageRange() const;
@@ -220,7 +220,7 @@ private:
 	void onTownCaptured(const PlayerColor & winner) const;
 	int getDwellingBonus(const std::vector<CreatureID>& creatureIds, const std::vector<ConstTransitivePtr<CGDwelling> >& dwellings) const;
 	bool townEnvisagesBuilding(BuildingSubID::EBuildingSubID bid) const;
-	bool isBonusingBuildingAdded(BuildingID::EBuildingID bid) const;
+	bool isBonusingBuildingAdded(BuildingID bid) const;
 	void initOverriddenBids();
 	void addTownBonuses(CRandomGenerator & rand);
 };

+ 2 - 2
lib/mapObjects/CQuest.cpp

@@ -23,7 +23,7 @@
 #include "../mapObjectConstructors/CObjectClassesHandler.h"
 #include "../serializer/JsonSerializeFormat.h"
 #include "../GameConstants.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../CSkillHandler.h"
 #include "../mapping/CMap.h"
 #include "../modding/ModScope.h"
@@ -814,7 +814,7 @@ void CGSeerHut::finishQuest(const CGHeroInstance * h, ui32 accept) const
 						for(const auto & ci : parts)
 						{
 							if(ci.art->getTypeId() != elem)
-								cb->giveHeroNewArtifact(h, ci.art->artType, GameConstants::BACKPACK_START);
+								cb->giveHeroNewArtifact(h, ci.art->artType, ArtifactPosition::BACKPACK_START);
 						}
 					}
 				}

+ 2 - 2
lib/mapObjects/MiscObjects.cpp

@@ -11,7 +11,7 @@
 #include "StdInc.h"
 #include "MiscObjects.h"
 
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../NetPacks.h"
 #include "../CGeneralTextHandler.h"
 #include "../CSoundBase.h"
@@ -1291,7 +1291,7 @@ CGBoat::CGBoat()
 {
 	hero = nullptr;
 	direction = 4;
-	layer = EPathfindingLayer::EEPathfindingLayer::SAIL;
+	layer = EPathfindingLayer::SAIL;
 }
 
 bool CGBoat::isCoastVisitable() const

+ 1 - 1
lib/mapObjects/MiscObjects.h

@@ -351,7 +351,7 @@ public:
 	const CGHeroInstance *hero;  //hero on board
 	bool onboardAssaultAllowed; //if true, hero can attack units from transport
 	bool onboardVisitAllowed; //if true, hero can visit objects from transport
-	EPathfindingLayer::EEPathfindingLayer layer;
+	EPathfindingLayer layer;
 	
 	//animation filenames. If empty - animations won't be used
 	std::string actualAnimation; //for OH3 boats those have actual animations

+ 1 - 1
lib/mapObjects/ObjectTemplate.cpp

@@ -14,7 +14,7 @@
 #include "../filesystem/CBinaryReader.h"
 #include "../VCMI_Lib.h"
 #include "../GameConstants.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../CGeneralTextHandler.h"
 #include "../JsonNode.h"
 #include "../TerrainHandler.h"

+ 3 - 3
lib/mapping/MapFormatH3M.cpp

@@ -898,7 +898,7 @@ void CMapLoaderH3M::loadArtifactsOfHero(CGHeroInstance * hero)
 	int amount = reader->readUInt16();
 	for(int i = 0; i < amount; ++i)
 	{
-		loadArtifactToSlot(hero, GameConstants::BACKPACK_START + static_cast<int>(hero->artifactsInBackpack.size()));
+		loadArtifactToSlot(hero, ArtifactPosition::BACKPACK_START + static_cast<int>(hero->artifactsInBackpack.size()));
 	}
 }
 
@@ -917,7 +917,7 @@ bool CMapLoaderH3M::loadArtifactToSlot(CGHeroInstance * hero, int slot)
 		return false;
 	}
 
-	if(art->isBig() && slot >= GameConstants::BACKPACK_START)
+	if(art->isBig() && slot >= ArtifactPosition::BACKPACK_START)
 	{
 		logGlobal->warn("Map '%s': A big artifact (war machine) in hero's backpack, ignoring...", mapName);
 		return false;
@@ -1652,7 +1652,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
 
 	for(auto & elem : map->disposedHeroes)
 	{
-		if(elem.heroId == object->subID)
+		if(elem.heroId.getNum() == object->subID)
 		{
 			object->nameCustom = elem.name;
 			object->portrait = elem.portrait;

+ 1 - 1
lib/mapping/MapFormatJson.cpp

@@ -32,7 +32,7 @@
 #include "../modding/ModUtility.h"
 #include "../spells/CSpellHandler.h"
 #include "../CSkillHandler.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../serializer/JsonDeserializer.h"
 #include "../serializer/JsonSerializer.h"
 

+ 1 - 1
lib/modding/CModHandler.cpp

@@ -22,7 +22,7 @@
 #include "../GameSettings.h"
 #include "../Languages.h"
 #include "../ScriptHandler.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../filesystem/Filesystem.h"
 #include "../spells/CSpellHandler.h"
 

+ 1 - 1
lib/modding/ContentTypeHandler.cpp

@@ -29,7 +29,7 @@
 #include "../RiverHandler.h"
 #include "../RoadHandler.h"
 #include "../ScriptHandler.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../TerrainHandler.h"
 #include "../mapObjectConstructors/CObjectClassesHandler.h"
 #include "../rmg/CRmgTemplateStorage.h"

+ 1 - 1
lib/pathfinder/PathfinderUtil.h

@@ -22,7 +22,7 @@ namespace PathfinderUtil
 	using FoW = std::shared_ptr<const boost::multi_array<ui8, 3>>;
 	using ELayer = EPathfindingLayer;
 
-	template<EPathfindingLayer::EEPathfindingLayer layer>
+	template<EPathfindingLayer::Type layer>
 	EPathAccessibility evaluateAccessibility(const int3 & pos, const TerrainTile & tinfo, FoW fow, const PlayerColor player, const CGameState * gs)
 	{
 		if(!(*fow)[pos.z][pos.x][pos.y])

+ 1 - 1
lib/rmg/CMapGenerator.cpp

@@ -19,7 +19,7 @@
 #include "../mapping/CMapEditManager.h"
 #include "../CTownHandler.h"
 #include "../CHeroHandler.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 #include "../filesystem/Filesystem.h"
 #include "CZonePlacer.h"
 #include "TileInfo.h"

+ 1 - 1
lib/rmg/CRmgTemplate.cpp

@@ -19,7 +19,7 @@
 #include "../TerrainHandler.h"
 #include "../serializer/JsonSerializeFormat.h"
 #include "../modding/ModScope.h"
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 

+ 1 - 1
lib/serializer/CSerializer.h

@@ -60,7 +60,7 @@ class DLL_LINKAGE CSerializer
 	}
 
 	template<typename T, typename NT>
-	static NT idToNumber(const BaseForID<T, NT> &t)
+	static NT idToNumber(const IdentifierBase &t)
 	{
 		return t.getNum();
 	}

+ 1 - 1
lib/spells/CSpellHandler.cpp

@@ -20,7 +20,7 @@
 #include "../CGeneralTextHandler.h"
 #include "../filesystem/Filesystem.h"
 
-#include "../StringConstants.h"
+#include "../constants/StringConstants.h"
 
 #include "../battle/BattleInfo.h"
 #include "../battle/CBattleInfoCallback.h"

+ 1 - 1
mapeditor/inspector/questwidget.cpp

@@ -15,7 +15,7 @@
 #include "../lib/CArtHandler.h"
 #include "../lib/CCreatureHandler.h"
 #include "../lib/CHeroHandler.h"
-#include "../lib/StringConstants.h"
+#include "../lib/constants/StringConstants.h"
 #include "../lib/mapping/CMap.h"
 
 QuestWidget::QuestWidget(const CMap & _map, CGSeerHut & _sh, QWidget *parent) :

+ 1 - 1
mapeditor/inspector/rewardswidget.cpp

@@ -15,7 +15,7 @@
 #include "../lib/spells/CSpellHandler.h"
 #include "../lib/CArtHandler.h"
 #include "../lib/CCreatureHandler.h"
-#include "../lib/StringConstants.h"
+#include "../lib/constants/StringConstants.h"
 #include "../lib/mapping/CMap.h"
 
 RewardsWidget::RewardsWidget(const CMap & m, CGPandoraBox & p, QWidget *parent) :

+ 1 - 1
mapeditor/inspector/townbulidingswidget.cpp

@@ -130,7 +130,7 @@ QStandardItem * TownBulidingsWidget::addBuilding(const CTown & ctown, int bId, s
 			for(int i = 0; i < model.rowCount(pindex); ++i)
 			{
 				QModelIndex index = model.index(i, 0, pindex);
-				if(building->upgrade == model.itemFromIndex(index)->data(Qt::UserRole).toInt())
+				if(building->upgrade.getNum() == model.itemFromIndex(index)->data(Qt::UserRole).toInt())
 				{
 					parent = model.itemFromIndex(index);
 					break;

+ 1 - 1
mapeditor/mapsettings.cpp

@@ -22,7 +22,7 @@
 #include "../lib/mapping/CMapService.h"
 #include "../lib/modding/CModHandler.h"
 #include "../lib/modding/CModInfo.h"
-#include "../lib/StringConstants.h"
+#include "../lib/constants/StringConstants.h"
 #include "inspector/townbulidingswidget.h" //to convert BuildingID to string
 
 //parses date for lose condition (1m 1w 1d)

+ 1 - 1
mapeditor/playerparams.cpp

@@ -12,7 +12,7 @@
 #include "playerparams.h"
 #include "ui_playerparams.h"
 #include "../lib/CTownHandler.h"
-#include "../lib/StringConstants.h"
+#include "../lib/constants/StringConstants.h"
 
 #include "../lib/mapping/CMap.h"
 

+ 1 - 1
server/CGameHandler.cpp

@@ -2676,7 +2676,7 @@ bool CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocat
 	{
 		if(!ArtifactUtils::isBackpackFreeSlots(dst.getHolderArtSet()))
 			COMPLAIN_RET("Backpack is full!");
-		vstd::amin(dst.slot, GameConstants::BACKPACK_START + dst.getHolderArtSet()->artifactsInBackpack.size());
+		vstd::amin(dst.slot, ArtifactPosition::BACKPACK_START + dst.getHolderArtSet()->artifactsInBackpack.size());
 	}
 
 	if(!(src.slot == ArtifactPosition::TRANSITION_POS && dst.slot == ArtifactPosition::TRANSITION_POS))

+ 11 - 11
server/CVCMIServer.cpp

@@ -727,7 +727,7 @@ void CVCMIServer::updateStartInfoOnMapChange(std::shared_ptr<CMapInfo> mapInfo,
 			pset.castle = pinfo.defaultCastle();
 			pset.hero = pinfo.defaultHero();
 
-			if(pset.hero != PlayerSettings::RANDOM && pinfo.hasCustomMainHero())
+			if(pset.hero.getNum() != PlayerSettings::RANDOM && pinfo.hasCustomMainHero())
 			{
 				pset.hero = pinfo.mainCustomHeroId;
 				pset.heroName = pinfo.mainCustomHeroName;
@@ -876,7 +876,7 @@ void CVCMIServer::optionNextCastle(PlayerColor player, int dir)
 		}
 	}
 
-	if(s.hero >= 0 && !getPlayerInfo(player.getNum()).hasCustomMainHero()) // remove hero unless it set to fixed one in map editor
+	if(s.hero.getNum() >= 0 && !getPlayerInfo(player.getNum()).hasCustomMainHero()) // remove hero unless it set to fixed one in map editor
 	{
 		s.hero = PlayerSettings::RANDOM;
 	}
@@ -935,10 +935,10 @@ void CVCMIServer::setCampaignBonus(int bonusId)
 void CVCMIServer::optionNextHero(PlayerColor player, int dir)
 {
 	PlayerSettings & s = si->playerInfos[player];
-	if(s.castle.getNum() < 0 || s.hero == PlayerSettings::NONE)
+	if(s.castle.getNum() < 0 || s.hero.getNum() == PlayerSettings::NONE)
 		return;
 
-	if(s.hero == PlayerSettings::RANDOM) // first/last available
+	if(s.hero.getNum() == PlayerSettings::RANDOM) // first/last available
 	{
 		int max = static_cast<int>(VLC->heroh->size()),
 			min = 0;
@@ -956,7 +956,7 @@ void CVCMIServer::optionNextHero(PlayerColor player, int dir)
 void CVCMIServer::optionSetHero(PlayerColor player, int id)
 {
 	PlayerSettings & s = si->playerInfos[player];
-	if(s.castle.getNum() < 0 || s.hero == PlayerSettings::NONE)
+	if(s.castle.getNum() < 0 || s.hero.getNum() == PlayerSettings::NONE)
 		return;
 
 	if(id == PlayerSettings::RANDOM)
@@ -967,19 +967,19 @@ void CVCMIServer::optionSetHero(PlayerColor player, int id)
 		s.hero = static_cast<HeroTypeID>(id);
 }
 
-int CVCMIServer::nextAllowedHero(PlayerColor player, int min, int max, int incl, int dir)
+HeroTypeID CVCMIServer::nextAllowedHero(PlayerColor player, int min, int max, int incl, int dir)
 {
 	if(dir > 0)
 	{
 		for(int i = min + incl; i <= max - incl; i++)
 			if(canUseThisHero(player, i))
-				return i;
+				return HeroTypeID(i);
 	}
 	else
 	{
 		for(int i = max - incl; i >= min + incl; i--)
 			if(canUseThisHero(player, i))
-				return i;
+				return HeroTypeID(i);
 	}
 	return -1;
 }
@@ -989,7 +989,7 @@ void CVCMIServer::optionNextBonus(PlayerColor player, int dir)
 	PlayerSettings & s = si->playerInfos[player];
 	PlayerSettings::Ebonus & ret = s.bonus = static_cast<PlayerSettings::Ebonus>(static_cast<int>(s.bonus) + dir);
 
-	if(s.hero == PlayerSettings::NONE &&
+	if(s.hero.getNum() == PlayerSettings::NONE &&
 		!getPlayerInfo(player.getNum()).heroesNames.size() &&
 		ret == PlayerSettings::ARTIFACT) //no hero - can't be artifact
 	{
@@ -1017,7 +1017,7 @@ void CVCMIServer::optionSetBonus(PlayerColor player, int id)
 {
 	PlayerSettings & s = si->playerInfos[player];
 
-	if(s.hero == PlayerSettings::NONE &&
+	if(s.hero.getNum() == PlayerSettings::NONE &&
 		!getPlayerInfo(player.getNum()).heroesNames.size() &&
 		id == PlayerSettings::ARTIFACT) //no hero - can't be artifact
 			return;
@@ -1051,7 +1051,7 @@ std::vector<int> CVCMIServer::getUsedHeroes()
 			if(hero.heroId >= 0) //in VCMI map format heroId = -1 means random hero
 				heroIds.push_back(hero.heroId);
 
-		if(p.second.hero != PlayerSettings::RANDOM)
+		if(p.second.hero.getNum() != PlayerSettings::RANDOM)
 			heroIds.push_back(p.second.hero);
 	}
 	return heroIds;

+ 1 - 1
server/CVCMIServer.h

@@ -108,7 +108,7 @@ public:
 	void setPlayer(PlayerColor clickedColor);
 	void optionNextHero(PlayerColor player, int dir); //dir == -1 or +1
 	void optionSetHero(PlayerColor player, int id);
-	int nextAllowedHero(PlayerColor player, int min, int max, int incl, int dir);
+	HeroTypeID nextAllowedHero(PlayerColor player, int min, int max, int incl, int dir);
 	bool canUseThisHero(PlayerColor player, int ID);
 	std::vector<int> getUsedHeroes();
 	void optionNextBonus(PlayerColor player, int dir); //dir == -1 or +1

+ 2 - 2
server/battles/BattleResultProcessor.cpp

@@ -265,7 +265,7 @@ void BattleResultProcessor::endBattle(int3 tile, const CGHeroInstance * heroAtta
 
 	gameHandler->sendAndApply(battleResult.get()); //after this point casualties objects are destroyed
 
-	if (battleResult->queryID == -1)
+	if (battleResult->queryID == QueryID::NONE)
 		endBattleConfirm(gameHandler->gameState()->curB);
 }
 
@@ -334,7 +334,7 @@ void BattleResultProcessor::endBattleConfirm(const BattleInfo * battleInfo)
 				//we assume that no big artifacts can be found
 				MoveArtifact ma;
 				ma.src = ArtifactLocation(finishingBattle->loserHero,
-					ArtifactPosition(GameConstants::BACKPACK_START + slotNumber)); //backpack automatically shifts arts to beginning
+					ArtifactPosition(ArtifactPosition::BACKPACK_START + slotNumber)); //backpack automatically shifts arts to beginning
 				const CArtifactInstance * art =  ma.src.getArt();
 				if (art->artType->getId() != ArtifactID::GRAIL) //grail may not be won
 				{

+ 1 - 0
server/queries/CQuery.h

@@ -21,6 +21,7 @@ VCMI_LIB_NAMESPACE_END
 class CObjectVisitQuery;
 class QueriesProcessor;
 class CQuery;
+class CGameHandler;
 
 using QueryPtr = std::shared_ptr<CQuery>;
 

+ 1 - 1
test/game/CGameStateTest.cpp

@@ -167,7 +167,7 @@ public:
 			pset.castle = pinfo.defaultCastle();
 			pset.hero = pinfo.defaultHero();
 
-			if(pset.hero != PlayerSettings::RANDOM && pinfo.hasCustomMainHero())
+			if(pset.hero.getNum() != PlayerSettings::RANDOM && pinfo.hasCustomMainHero())
 			{
 				pset.hero = pinfo.mainCustomHeroId;
 				pset.heroName = pinfo.mainCustomHeroName;