瀏覽代碼

Implement missing functions, fixes linking errors

Ivan Savenko 2 年之前
父節點
當前提交
77facf9387

+ 1 - 0
AI/Nullkiller/Engine/PriorityEvaluator.cpp

@@ -11,6 +11,7 @@
 #include <limits>
 
 #include "Nullkiller.h"
+#include "../../../lib/bonuses/BonusSubtypes.h"
 #include "../../../lib/mapObjectConstructors/AObjectTypeHandler.h"
 #include "../../../lib/mapObjectConstructors/CObjectClassesHandler.h"
 #include "../../../lib/mapObjectConstructors/CBankInstanceConstructor.h"

+ 1 - 1
client/battle/BattleActionsController.cpp

@@ -898,7 +898,7 @@ void BattleActionsController::tryActivateStackSpellcasting(const CStack *casterS
 	for(const auto & bonus : *bl)
 	{
 		if (bonus->additionalInfo[0] <= 0)
-			creatureSpells.push_back(SpellID(bonus->subtype).toSpell());
+			creatureSpells.push_back(bonus->subtype.as<SpellID>().toSpell());
 	}
 }
 

+ 2 - 1
client/battle/BattleStacksController.cpp

@@ -34,6 +34,7 @@
 #include "../../lib/spells/ISpellMechanics.h"
 #include "../../lib/battle/BattleAction.h"
 #include "../../lib/battle/BattleHex.h"
+#include "../../lib/bonuses/BonusSubtypes.h"
 #include "../../lib/CStack.h"
 #include "../../lib/CondSh.h"
 #include "../../lib/TextOperations.h"
@@ -534,7 +535,7 @@ void BattleStacksController::stackMoved(const CStack *stack, std::vector<BattleH
 		addNewAnim(new MovementStartAnimation(owner, stack));
 	});
 
-	if (!stack->hasBonus(Selector::typeSubtype(BonusType::FLYING, 1)))
+	if (!stack->hasBonus(Selector::typeSubtype(BonusType::FLYING, BonusSubtypes::movementFlying)))
 	{
 		owner.addToAnimationStage(EAnimationEvents::MOVEMENT, [&]()
 		{

+ 1 - 1
client/windows/CKingdomInterface.cpp

@@ -579,7 +579,7 @@ void CKingdomInterface::generateMinesList(const std::vector<const CGObjectInstan
 	std::vector<const CGHeroInstance*> heroes = LOCPLINT->cb->getHeroesInfo(true);
 	for(auto & heroe : heroes)
 	{
-		totalIncome += heroe->valOfBonuses(Selector::typeSubtype(BonusType::GENERATE_RESOURCE, GameResID(EGameResID::GOLD)));
+		totalIncome += heroe->valOfBonuses(Selector::typeSubtype(BonusType::GENERATE_RESOURCE, TBonusSubtype(GameResID(EGameResID::GOLD))));
 	}
 
 	//Add town income of all towns

+ 5 - 0
cmake_modules/VCMI_lib.cmake

@@ -31,6 +31,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
 		${MAIN_LIB_DIR}/bonuses/BonusList.cpp
 		${MAIN_LIB_DIR}/bonuses/BonusParams.cpp
 		${MAIN_LIB_DIR}/bonuses/BonusSelector.cpp
+		${MAIN_LIB_DIR}/bonuses/BonusSubtypes.cpp
 		${MAIN_LIB_DIR}/bonuses/CBonusProxy.cpp
 		${MAIN_LIB_DIR}/bonuses/CBonusSystemNode.cpp
 		${MAIN_LIB_DIR}/bonuses/IBonusBearer.cpp
@@ -42,6 +43,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
 		${MAIN_LIB_DIR}/campaign/CampaignState.cpp
 
 		${MAIN_LIB_DIR}/constants/EntityIdentifiers.cpp
+		${MAIN_LIB_DIR}/constants/MetaIdentifier.cpp
 
 		${MAIN_LIB_DIR}/events/ApplyDamage.cpp
 		${MAIN_LIB_DIR}/events/GameResumed.cpp
@@ -357,6 +359,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
 		${MAIN_LIB_DIR}/bonuses/BonusList.h
 		${MAIN_LIB_DIR}/bonuses/BonusParams.h
 		${MAIN_LIB_DIR}/bonuses/BonusSelector.h
+		${MAIN_LIB_DIR}/bonuses/BonusSubtypes.h
 		${MAIN_LIB_DIR}/bonuses/CBonusProxy.h
 		${MAIN_LIB_DIR}/bonuses/CBonusSystemNode.h
 		${MAIN_LIB_DIR}/bonuses/IBonusBearer.h
@@ -371,6 +374,8 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
 
 		${MAIN_LIB_DIR}/constants/EntityIdentifiers.h
 		${MAIN_LIB_DIR}/constants/Enumerations.h
+		${MAIN_LIB_DIR}/constants/IdentifierBase.h
+		${MAIN_LIB_DIR}/constants/MetaIdentifier.h
 		${MAIN_LIB_DIR}/constants/NumericConstants.h
 		${MAIN_LIB_DIR}/constants/StringConstants.h
 

+ 1 - 0
lib/BasicTypes.cpp

@@ -17,6 +17,7 @@
 #include "bonuses/BonusList.h"
 #include "bonuses/Bonus.h"
 #include "bonuses/IBonusBearer.h"
+#include "bonuses/BonusSubtypes.h"
 
 #include <vcmi/Creature.h>
 #include <vcmi/Faction.h>

+ 1 - 0
lib/CBonusTypeHandler.cpp

@@ -20,6 +20,7 @@
 #include "CCreatureHandler.h"
 #include "CGeneralTextHandler.h"
 #include "spells/CSpellHandler.h"
+#include "bonuses/BonusSubtypes.h"
 
 template class std::vector<VCMI_LIB_WRAP_NAMESPACE(CBonusType)>;
 

+ 6 - 0
lib/CCreatureHandler.cpp

@@ -19,6 +19,7 @@
 #include "constants/StringConstants.h"
 #include "bonuses/Limiters.h"
 #include "bonuses/Updaters.h"
+#include "bonuses/BonusSubtypes.h"
 #include "serializer/JsonDeserializer.h"
 #include "serializer/JsonUpdater.h"
 #include "mapObjectConstructors/AObjectTypeHandler.h"
@@ -291,6 +292,11 @@ CCreature::CCreature()
 	fightValue = AIValue = growth = hordeGrowth = ammMin = ammMax = 0;
 }
 
+void CCreature::addBonus(int val, BonusType type)
+{
+	addBonus(val, type, TBonusSubtype::NONE);
+}
+
 void CCreature::addBonus(int val, BonusType type, TBonusSubtype subtype)
 {
 	auto selector = Selector::typeSubtype(type, subtype).And(Selector::source(BonusSource::CREATURE_ABILITY, getIndex()));

+ 1 - 0
lib/CGameInfoCallback.cpp

@@ -17,6 +17,7 @@
 #include "CGeneralTextHandler.h"
 #include "StartInfo.h" // for StartInfo
 #include "battle/BattleInfo.h" // for BattleInfo
+#include "bonuses/BonusSubtypes.h"
 #include "NetPacks.h" // for InfoWindow
 #include "GameSettings.h"
 #include "TerrainHandler.h"

+ 1 - 0
lib/CStack.cpp

@@ -17,6 +17,7 @@
 
 #include "CGeneralTextHandler.h"
 #include "battle/BattleInfo.h"
+#include "bonuses/BonusSubtypes.h"
 #include "spells/CSpellHandler.h"
 #include "NetPacks.h"
 

+ 6 - 0
lib/CTownHandler.cpp

@@ -23,6 +23,7 @@
 #include "filesystem/Filesystem.h"
 #include "bonuses/Bonus.h"
 #include "bonuses/Propagators.h"
+#include "bonuses/BonusSubtypes.h"
 #include "ResourceSet.h"
 #include "mapObjectConstructors/AObjectTypeHandler.h"
 #include "mapObjectConstructors/CObjectClassesHandler.h"
@@ -544,6 +545,11 @@ void CTownHandler::addBonusesForVanilaBuilding(CBuilding * building) const
 		building->addNewBonus(b, building->buildingBonuses);
 }
 
+std::shared_ptr<Bonus> CTownHandler::createBonus(CBuilding * build, BonusType type, int val) const
+{
+	return createBonus(build, type, val, TBonusSubtype::NONE, emptyPropagator());
+}
+
 std::shared_ptr<Bonus> CTownHandler::createBonus(CBuilding * build, BonusType type, int val, TBonusSubtype subtype) const
 {
 	return createBonus(build, type, val, subtype, emptyPropagator());

+ 2 - 0
lib/battle/CUnitState.cpp

@@ -16,6 +16,8 @@
 #include "../NetPacks.h"
 #include "../CCreatureHandler.h"
 
+#include "../bonuses/BonusSubtypes.h"
+
 #include "../serializer/JsonDeserializer.h"
 #include "../serializer/JsonSerializer.h"
 

+ 1 - 0
lib/battle/DamageCalculator.cpp

@@ -14,6 +14,7 @@
 #include "Unit.h"
 
 #include "../bonuses/Bonus.h"
+#include "../bonuses/BonusSubtypes.h"
 #include "../mapObjects/CGTownInstance.h"
 #include "../spells/CSpellHandler.h"
 #include "../GameSettings.h"

+ 12 - 0
lib/bonuses/Bonus.cpp

@@ -183,6 +183,18 @@ JsonNode Bonus::toJsonNode() const
 	return root;
 }
 
+Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 ID)
+	: Bonus(Duration, Type, Src, Val, ID, TBonusSubtype::NONE, std::string())
+{}
+
+Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 ID, std::string Desc)
+	: Bonus(Duration, Type, Src, Val, ID, TBonusSubtype::NONE, Desc)
+{}
+
+Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 ID, TBonusSubtype Subtype)
+	: Bonus(Duration, Type, Src, Val, ID, Subtype, std::string())
+{}
+
 Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 ID, TBonusSubtype Subtype, std::string Desc):
 	duration(Duration),
 	type(Type),

+ 1 - 45
lib/bonuses/Bonus.h

@@ -10,7 +10,7 @@
 #pragma once
 
 #include "BonusEnum.h"
-#include "../constants/EntityIdentifiers.h"
+#include "../constants/MetaIdentifier.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -30,50 +30,6 @@ using TLimiterPtr = std::shared_ptr<ILimiter>;
 using TPropagatorPtr = std::shared_ptr<IPropagator>;
 using TUpdaterPtr = std::shared_ptr<IUpdater>;
 
-namespace BonusSubtypes
-{
-
-static const TBonusSubtype creatureDamageBoth; // 0
-static const TBonusSubtype creatureDamageMin;  // 1
-static const TBonusSubtype creatureDamageMax;  // 2
-
-static const TBonusSubtype damageTypeAll;    // -1
-static const TBonusSubtype damageTypeMelee;  // 0
-static const TBonusSubtype damageTypeRanged; // 1
-
-static const TBonusSubtype heroMovementLand; // 1
-static const TBonusSubtype heroMovementSea; // 0
-
-static const TBonusSubtype heroMovementPenalty; // 2
-static const TBonusSubtype heroMovementFull; // 1
-
-static const TBonusSubtype deathStareGorgon; // 0
-static const TBonusSubtype deathStareCommander;
-
-static const TBonusSubtype rebirthRegular; // 0
-static const TBonusSubtype rebirthSpecial; // 1
-
-static const TBonusSubtype visionsMonsters; // 0
-static const TBonusSubtype visionsHeroes;  // 1
-static const TBonusSubtype visionsTowns;  // 2
-
-static const TBonusSubtype immunityBattleWide; // 0
-static const TBonusSubtype immunityEnemyHero; // 1
-
-static const TBonusSubtype transmutationPerHealth; // 0
-static const TBonusSubtype transmutationPerUnit; // 1
-
-static const TBonusSubtype destructionKillPercentage; // 0
-static const TBonusSubtype destructionKillAmount; // 1
-
-static const TBonusSubtype soulStealPermanent; // 0
-static const TBonusSubtype soulStealBattle; // 1
-
-TBonusSubtype spellLevel(int level);
-TBonusSubtype creatureLevel(int level);
-
-}
-
 class DLL_LINKAGE CAddInfo : public std::vector<si32>
 {
 public:

+ 1 - 0
lib/bonuses/BonusParams.cpp

@@ -13,6 +13,7 @@
 #include "BonusEnum.h"
 #include "BonusParams.h"
 #include "BonusSelector.h"
+#include "BonusSubtypes.h"
 
 #include "../ResourceSet.h"
 

+ 56 - 0
lib/bonuses/BonusSubtypes.cpp

@@ -0,0 +1,56 @@
+/*
+ * Bonus.cpp, 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
+ *
+ */
+
+#include "StdInc.h"
+#include "BonusSubtypes.h"
+
+VCMI_LIB_NAMESPACE_BEGIN
+
+const TBonusSubtype BonusSubtypes::creatureDamageBoth("", "", 0);
+const TBonusSubtype BonusSubtypes::creatureDamageMin("", "", 1);
+const TBonusSubtype BonusSubtypes::creatureDamageMax("", "", 2);
+const TBonusSubtype BonusSubtypes::damageTypeAll("", "", -1);
+const TBonusSubtype BonusSubtypes::damageTypeMelee("", "", 0);
+const TBonusSubtype BonusSubtypes::damageTypeRanged("", "", 1);
+const TBonusSubtype BonusSubtypes::heroMovementLand("", "", 1);
+const TBonusSubtype BonusSubtypes::heroMovementSea("", "", 0);
+const TBonusSubtype BonusSubtypes::heroMovementPenalty("", "", 2);
+const TBonusSubtype BonusSubtypes::heroMovementFull("", "", 1);
+const TBonusSubtype BonusSubtypes::deathStareGorgon("", "", 0);
+const TBonusSubtype BonusSubtypes::deathStareCommander("", "", 1);
+const TBonusSubtype BonusSubtypes::rebirthRegular("", "", 0);
+const TBonusSubtype BonusSubtypes::rebirthSpecial("", "", 1);
+const TBonusSubtype BonusSubtypes::visionsMonsters("", "", 0);
+const TBonusSubtype BonusSubtypes::visionsHeroes("", "", 1);
+const TBonusSubtype BonusSubtypes::visionsTowns("", "", 2);
+const TBonusSubtype BonusSubtypes::immunityBattleWide("", "", 0);
+const TBonusSubtype BonusSubtypes::immunityEnemyHero("", "", 1);
+const TBonusSubtype BonusSubtypes::transmutationPerHealth("", "", 0);
+const TBonusSubtype BonusSubtypes::transmutationPerUnit("", "", 1);
+const TBonusSubtype BonusSubtypes::destructionKillPercentage("", "", 0);
+const TBonusSubtype BonusSubtypes::destructionKillAmount("", "", 1);
+const TBonusSubtype BonusSubtypes::soulStealPermanent("", "", 0);
+const TBonusSubtype BonusSubtypes::soulStealBattle("", "", 1);
+const TBonusSubtype BonusSubtypes::movementFlying("", "", 0);
+const TBonusSubtype BonusSubtypes::movementTeleporting("", "", 1);
+
+TBonusSubtype BonusSubtypes::spellLevel(int level)
+{
+	assert(0); //todo
+	return TBonusSubtype();
+}
+
+TBonusSubtype BonusSubtypes::creatureLevel(int level)
+{
+	assert(0); //todo
+	return TBonusSubtype();
+}
+
+VCMI_LIB_NAMESPACE_END

+ 64 - 0
lib/bonuses/BonusSubtypes.h

@@ -0,0 +1,64 @@
+/*
+ * BonusSubtypes.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 "../constants/MetaIdentifier.h"
+
+VCMI_LIB_NAMESPACE_BEGIN
+
+using TBonusSubtype = MetaIdentifier;
+
+class DLL_LINKAGE BonusSubtypes
+{
+public:
+	static const TBonusSubtype creatureDamageBoth; // 0
+	static const TBonusSubtype creatureDamageMin; // 1
+	static const TBonusSubtype creatureDamageMax; // 2
+
+	static const TBonusSubtype damageTypeAll; // -1
+	static const TBonusSubtype damageTypeMelee; // 0
+	static const TBonusSubtype damageTypeRanged; // 1
+
+	static const TBonusSubtype heroMovementLand; // 1
+	static const TBonusSubtype heroMovementSea; // 0
+
+	static const TBonusSubtype heroMovementPenalty; // 2
+	static const TBonusSubtype heroMovementFull; // 1
+
+	static const TBonusSubtype deathStareGorgon; // 0
+	static const TBonusSubtype deathStareCommander;
+
+	static const TBonusSubtype rebirthRegular; // 0
+	static const TBonusSubtype rebirthSpecial; // 1
+
+	static const TBonusSubtype visionsMonsters; // 0
+	static const TBonusSubtype visionsHeroes; // 1
+	static const TBonusSubtype visionsTowns; // 2
+
+	static const TBonusSubtype immunityBattleWide; // 0
+	static const TBonusSubtype immunityEnemyHero; // 1
+
+	static const TBonusSubtype transmutationPerHealth; // 0
+	static const TBonusSubtype transmutationPerUnit; // 1
+
+	static const TBonusSubtype destructionKillPercentage; // 0
+	static const TBonusSubtype destructionKillAmount; // 1
+
+	static const TBonusSubtype soulStealPermanent; // 0
+	static const TBonusSubtype soulStealBattle; // 1
+
+	static const TBonusSubtype movementFlying; // 0
+	static const TBonusSubtype movementTeleporting; // 1
+
+	static TBonusSubtype spellLevel(int level);
+	static TBonusSubtype creatureLevel(int level);
+};
+
+VCMI_LIB_NAMESPACE_END

+ 54 - 0
lib/constants/EntityIdentifiers.cpp

@@ -80,6 +80,15 @@ const FactionID FactionID::FORTRESS(7);
 const FactionID FactionID::CONFLUX(8);
 const FactionID FactionID::NEUTRAL(9);
 
+const PrimarySkill PrimarySkill::NONE(-1);
+const PrimarySkill PrimarySkill::ATTACK(0);
+const PrimarySkill PrimarySkill::DEFENSE(1);
+const PrimarySkill PrimarySkill::SPELL_POWER(2);
+const PrimarySkill PrimarySkill::KNOWLEDGE(3);
+const PrimarySkill PrimarySkill::BEGIN(0);
+const PrimarySkill PrimarySkill::END(4);
+const PrimarySkill PrimarySkill::EXPERIENCE(4);
+
 const BoatId BoatId::NONE(-1);
 const BoatId BoatId::NECROPOLIS(0);
 const BoatId BoatId::CASTLE(1);
@@ -273,6 +282,21 @@ std::string PlayerColor::entityType()
 	return "playerColor";
 }
 
+si32 PrimarySkill::decode(const std::string& identifier)
+{
+	return *VLC->identifiers()->getIdentifier(ModScope::scopeGame(), entityType(), identifier);
+}
+
+std::string PrimarySkill::encode(const si32 index)
+{
+	return NPrimarySkill::names[index];
+}
+
+std::string PrimarySkill::entityType()
+{
+	return "primarySkill";
+}
+
 si32 FactionID::decode(const std::string & identifier)
 {
 	auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), entityType(), identifier);
@@ -323,6 +347,36 @@ const ObstacleInfo * Obstacle::getInfo() const
 	return VLC->obstacles()->getById(*this);
 }
 
+si32 SpellSchool::decode(const std::string & identifier)
+{
+	return *VLC->identifiers()->getIdentifier(ModScope::scopeGame(), entityType(), identifier);
+}
+
+std::string SpellSchool::encode(const si32 index)
+{
+	return SpellConfig::SCHOOL[index].jsonName;
+}
+
+std::string SpellSchool::entityType()
+{
+	return "spellSchool";
+}
+
+si32 GameResID::decode(const std::string & identifier)
+{
+	return *VLC->identifiers()->getIdentifier(ModScope::scopeGame(), entityType(), identifier);
+}
+
+std::string GameResID::encode(const si32 index)
+{
+	return GameConstants::RESOURCE_NAMES[index];
+}
+
+std::string GameResID::entityType()
+{
+	return "resource";
+}
+
 std::string GameResID::entityType()
 {
 	return "resource";

+ 15 - 151
lib/constants/EntityIdentifiers.h

@@ -10,6 +10,7 @@
 #pragma once
 
 #include "NumericConstants.h"
+#include "IdentifierBase.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -35,62 +36,6 @@ class CNonConstInfoCallback;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-class IdentifierBase
-{
-protected:
-	constexpr IdentifierBase():
-		num(-1)
-	{}
-
-	explicit constexpr IdentifierBase(int32_t value):
-		num(value)
-	{}
-
-	~IdentifierBase() = default;
-public:
-	int32_t num;
-
-	constexpr int32_t getNum() const
-	{
-		return num;
-	}
-
-	constexpr void setNum(int32_t value)
-	{
-		num = value;
-	}
-
-	struct hash
-	{
-		size_t operator()(const IdentifierBase & id) const
-		{
-			return std::hash<int>()(id.num);
-		}
-	};
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & num;
-	}
-
-	constexpr void advance(int change)
-	{
-		num += change;
-	}
-
-	constexpr operator int32_t () const
-	{
-		return 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
@@ -739,18 +684,18 @@ public:
 	DLL_LINKAGE const Creature * toCreature(const CreatureService * creatures) const;
 };
 
-class CreatureID : public IdentifierWithEnum<CreatureID, CreatureIDBase>
+class DLL_LINKAGE CreatureID : public IdentifierWithEnum<CreatureID, CreatureIDBase>
 {
 public:
 	using IdentifierWithEnum<CreatureID, CreatureIDBase>::IdentifierWithEnum;
 
 	///json serialization helpers
-	DLL_LINKAGE static si32 decode(const std::string & identifier);
-	DLL_LINKAGE static std::string encode(const si32 index);
+	static si32 decode(const std::string & identifier);
+	static std::string encode(const si32 index);
 	static std::string entityType();
 };
 
-class SpellIDBase : public IdentifierBase
+class DLL_LINKAGE SpellIDBase : public IdentifierBase
 {
 public:
 	enum Type
@@ -853,18 +798,18 @@ public:
 		AFTER_LAST = 82
 	};
 
-	DLL_LINKAGE const CSpell * toSpell() const; //deprecated
-	DLL_LINKAGE const spells::Spell * toSpell(const spells::Service * service) const;
+	const CSpell * toSpell() const; //deprecated
+	const spells::Spell * toSpell(const spells::Service * service) const;
 };
 
-class SpellID : public IdentifierWithEnum<SpellID, SpellIDBase>
+class DLL_LINKAGE SpellID : public IdentifierWithEnum<SpellID, SpellIDBase>
 {
 public:
 	using IdentifierWithEnum<SpellID, SpellIDBase>::IdentifierWithEnum;
 
 	///json serialization helpers
-	DLL_LINKAGE static si32 decode(const std::string & identifier);
-	DLL_LINKAGE static std::string encode(const si32 index);
+	static si32 decode(const std::string & identifier);
+	static std::string encode(const si32 index);
 	static std::string entityType();
 };
 
@@ -941,8 +886,8 @@ public:
 	static const SpellSchool WATER;
 	static const SpellSchool EARTH;
 
-	DLL_LINKAGE static si32 decode(const std::string & identifier);
-	DLL_LINKAGE static std::string encode(const si32 index);
+	static si32 decode(const std::string & identifier);
+	static std::string encode(const si32 index);
 	static std::string entityType();
 };
 
@@ -966,13 +911,13 @@ public:
 	};
 };
 
-class GameResID : public IdentifierWithEnum<GameResID, GameResIDBase>
+class DLL_LINKAGE GameResID : public IdentifierWithEnum<GameResID, GameResIDBase>
 {
 public:
 	using IdentifierWithEnum<GameResID, GameResIDBase>::IdentifierWithEnum;
 
-	DLL_LINKAGE static si32 decode(const std::string & identifier);
-	DLL_LINKAGE static std::string encode(const si32 index);
+	static si32 decode(const std::string & identifier);
+	static std::string encode(const si32 index);
 	static std::string entityType();
 };
 
@@ -984,85 +929,4 @@ using River = RiverId;
 using Road = RoadId;
 using ETerrainId = TerrainId;
 
-/// This class represents field that may contain value of multiple different identifer types
-class MetaIdentifier
-{
-	std::string entityType;
-	std::string stringForm;
-	int32_t integerForm;
-
-	void onDeserialized();
-public:
-
-	static const MetaIdentifier NONE;
-
-	MetaIdentifier():
-		integerForm(-1)
-	{}
-
-	explicit MetaIdentifier(const std::string & entityType, const std::string & identifier)
-		: entityType(entityType)
-		, stringForm(identifier)
-		, integerForm(-1)
-	{
-		onDeserialized();
-	}
-
-	explicit MetaIdentifier(const std::string & entityType, const std::string & identifier, int32_t value)
-		: entityType(entityType)
-		, stringForm(identifier)
-		, integerForm(value)
-	{
-	}
-
-	template<typename IdentifierType>
-	explicit MetaIdentifier(const IdentifierType & identifier )
-		: entityType(IdentifierType::entityType())
-		, integerForm(identifier.getNum())
-		, stringForm(IdentifierType::encode(identifier.getNum()))
-	{
-		static_assert(std::is_base_of<IdentifierBase, IdentifierType>::value, "MetaIdentifier can only be constructed from Identifer class");
-	}
-
-	int32_t getNum() const
-	{
-		return integerForm;
-	}
-
-	std::string toString() const
-	{
-		return stringForm;
-	}
-
-	template<typename IdentifierType>
-	IdentifierType as() const
-	{
-		IdentifierType result(integerForm);
-		return result;
-	}
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & stringForm;
-
-		if (!h.saving)
-			onDeserialized();
-	}
-
-	bool operator == (const MetaIdentifier & other) const
-	{
-		assert( (stringForm == other.stringForm) ? (integerForm == other.integerForm) : true );
-
-		return stringForm == other.stringForm;
-	}
-
-	bool operator != (const MetaIdentifier & other) const
-	{
-		return !(*this == other);
-	}
-
-	bool operator < (const MetaIdentifier & other) const;
-};
-
-
 VCMI_LIB_NAMESPACE_END

+ 64 - 0
lib/constants/IdentifierBase.h

@@ -0,0 +1,64 @@
+/*
+ * IdentifierBase.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
+
+class IdentifierBase
+{
+protected:
+	constexpr IdentifierBase():
+		num(-1)
+	{}
+
+	explicit constexpr IdentifierBase(int32_t value):
+		num(value)
+	{}
+
+	~IdentifierBase() = default;
+public:
+	int32_t num;
+
+	constexpr int32_t getNum() const
+	{
+		return num;
+	}
+
+	constexpr void setNum(int32_t value)
+	{
+		num = value;
+	}
+
+	struct hash
+	{
+		size_t operator()(const IdentifierBase & id) const
+		{
+			return std::hash<int>()(id.num);
+		}
+	};
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & num;
+	}
+
+	constexpr void advance(int change)
+	{
+		num += change;
+	}
+
+	constexpr operator int32_t () const
+	{
+		return num;
+	}
+
+	friend std::ostream& operator<<(std::ostream& os, const IdentifierBase& dt)
+	{
+		return os << dt.num;
+	}
+};

+ 69 - 0
lib/constants/MetaIdentifier.cpp

@@ -0,0 +1,69 @@
+/*
+ * EntityIdentifiers.cpp, 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
+ *
+ */
+
+#include "StdInc.h"
+#include "MetaIdentifier.h"
+
+VCMI_LIB_NAMESPACE_BEGIN
+
+const MetaIdentifier MetaIdentifier::NONE("", "", -1);
+
+MetaIdentifier::MetaIdentifier():
+	integerForm(-1)
+{}
+
+MetaIdentifier::MetaIdentifier(const std::string & entityType, const std::string & identifier)
+	: entityType(entityType)
+	, stringForm(identifier)
+	, integerForm(-1)
+{
+	onDeserialized();
+}
+
+MetaIdentifier::MetaIdentifier(const std::string & entityType, const std::string & identifier, int32_t value)
+	: entityType(entityType)
+	, stringForm(identifier)
+	, integerForm(value)
+{
+}
+
+bool MetaIdentifier::operator == (const MetaIdentifier & other) const
+{
+	assert( (stringForm == other.stringForm) ? (integerForm == other.integerForm) : true );
+
+	return stringForm == other.stringForm;
+}
+
+bool MetaIdentifier::operator != (const MetaIdentifier & other) const
+{
+	return !(*this == other);
+}
+
+bool MetaIdentifier::operator < (const MetaIdentifier & other) const
+{
+	assert(0);
+}
+
+int32_t MetaIdentifier::getNum() const
+{
+	return integerForm;
+}
+
+std::string MetaIdentifier::toString() const
+{
+	return stringForm;
+}
+
+void MetaIdentifier::onDeserialized()
+{
+	assert(0); //TODO
+}
+
+VCMI_LIB_NAMESPACE_END

+ 65 - 0
lib/constants/MetaIdentifier.h

@@ -0,0 +1,65 @@
+/*
+ * MetaIdentifier.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 "IdentifierBase.h"
+
+VCMI_LIB_NAMESPACE_BEGIN
+
+/// This class represents field that may contain value of multiple different identifer types
+class DLL_LINKAGE MetaIdentifier
+{
+	std::string entityType;
+	std::string stringForm;
+	int32_t integerForm;
+
+	void onDeserialized();
+public:
+
+	static const MetaIdentifier NONE;
+
+	MetaIdentifier();
+	MetaIdentifier(const std::string & entityType, const std::string & identifier);
+	MetaIdentifier(const std::string & entityType, const std::string & identifier, int32_t value);
+
+	template<typename IdentifierType>
+	explicit MetaIdentifier(const IdentifierType & identifier )
+		: entityType(IdentifierType::entityType())
+		, integerForm(identifier.getNum())
+		, stringForm(IdentifierType::encode(identifier.getNum()))
+	{
+		static_assert(std::is_base_of<IdentifierBase, IdentifierType>::value, "MetaIdentifier can only be constructed from Identifer class");
+	}
+
+	int32_t getNum() const;
+	std::string toString() const;
+
+	template<typename IdentifierType>
+	IdentifierType as() const
+	{
+		static_assert(std::is_base_of<IdentifierBase, IdentifierType>::value, "MetaIdentifier can only be converted to Identifer class");
+		IdentifierType result(integerForm);
+		return result;
+	}
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & stringForm;
+
+		if (!h.saving)
+			onDeserialized();
+	}
+
+	bool operator == (const MetaIdentifier & other) const;
+	bool operator != (const MetaIdentifier & other) const;
+	bool operator < (const MetaIdentifier & other) const;
+};
+
+VCMI_LIB_NAMESPACE_END

+ 1 - 0
lib/mapObjects/CGCreature.cpp

@@ -16,6 +16,7 @@
 #include "../CConfigHandler.h"
 #include "../GameSettings.h"
 #include "../IGameCallback.h"
+#include "../bonuses/BonusSubtypes.h"
 #include "../serializer/JsonSerializeFormat.h"
 
 VCMI_LIB_NAMESPACE_BEGIN

+ 1 - 0
lib/mapObjects/CGHeroInstance.cpp

@@ -37,6 +37,7 @@
 #include "../modding/ModScope.h"
 #include "../constants/StringConstants.h"
 #include "../battle/Unit.h"
+#include "../bonuses/BonusSubtypes.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 

+ 1 - 0
lib/mapObjects/CGTownBuilding.cpp

@@ -15,6 +15,7 @@
 #include "../NetPacks.h"
 #include "../IGameCallback.h"
 #include "../gameState/CGameState.h"
+#include "../bonuses/BonusSubtypes.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 

+ 1 - 0
lib/mapObjects/CGTownInstance.cpp

@@ -13,6 +13,7 @@
 #include "CGTownBuilding.h"
 #include "../spells/CSpellHandler.h"
 #include "../bonuses/Bonus.h"
+#include "../bonuses/BonusSubtypes.h"
 #include "../battle/IBattleInfoCallback.h"
 #include "../NetPacks.h"
 #include "../CConfigHandler.h"

+ 1 - 0
lib/mapObjects/MiscObjects.cpp

@@ -25,6 +25,7 @@
 #include "../mapObjectConstructors/AObjectTypeHandler.h"
 #include "../mapObjectConstructors/CObjectClassesHandler.h"
 #include "../modding/ModScope.h"
+#include "../bonuses/BonusSubtypes.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 

+ 10 - 0
lib/pathfinder/TurnInfo.cpp

@@ -71,6 +71,11 @@ bool TurnInfo::isLayerAvailable(const EPathfindingLayer & layer) const
 	return true;
 }
 
+bool TurnInfo::hasBonusOfType(BonusType type) const
+{
+	return hasBonusOfType(type, TBonusSubtype::NONE);
+}
+
 bool TurnInfo::hasBonusOfType(BonusType type, TBonusSubtype subtype) const
 {
 	switch(type)
@@ -89,6 +94,11 @@ bool TurnInfo::hasBonusOfType(BonusType type, TBonusSubtype subtype) const
 			bonuses->getFirst(Selector::type()(type).And(Selector::subtype()(subtype))));
 }
 
+int TurnInfo::valOfBonuses(BonusType type) const
+{
+	return valOfBonuses(type, TBonusSubtype::NONE);
+}
+
 int TurnInfo::valOfBonuses(BonusType type, TBonusSubtype subtype) const
 {
 	switch(type)

+ 1 - 0
lib/spells/TargetCondition.cpp

@@ -17,6 +17,7 @@
 #include "../battle/Unit.h"
 #include "../bonuses/BonusParams.h"
 #include "../bonuses/BonusList.h"
+#include "../bonuses/BonusSubtypes.h"
 
 #include "../modding/IdentifierStorage.h"
 #include "../modding/ModUtility.h"

+ 1 - 0
server/battles/BattleActionProcessor.cpp

@@ -20,6 +20,7 @@
 #include "../../lib/battle/CBattleInfoCallback.h"
 #include "../../lib/battle/IBattleState.h"
 #include "../../lib/battle/BattleAction.h"
+#include "../../lib/bonuses/BonusSubtypes.h"
 #include "../../lib/gameState/CGameState.h"
 #include "../../lib/NetPacks.h"
 #include "../../lib/spells/AbilityCaster.h"

+ 3 - 2
server/processors/PlayerMessageProcessor.cpp

@@ -16,6 +16,7 @@
 #include "../../lib/serializer/Connection.h"
 #include "../../lib/CGeneralTextHandler.h"
 #include "../../lib/CHeroHandler.h"
+#include "../../lib/bonuses/BonusSubtypes.h"
 #include "../../lib/modding/IdentifierStorage.h"
 #include "../../lib/CPlayerState.h"
 #include "../../lib/GameConstants.h"
@@ -23,8 +24,8 @@
 #include "../../lib/StartInfo.h"
 #include "../../lib/gameState/CGameState.h"
 #include "../../lib/mapObjects/CGTownInstance.h"
-#include "../lib/modding/IdentifierStorage.h"
-#include "../lib/modding/ModScope.h"
+#include "../../lib/modding/IdentifierStorage.h"
+#include "../../lib/modding/ModScope.h"
 
 PlayerMessageProcessor::PlayerMessageProcessor()
 	:gameHandler(nullptr)

+ 1 - 0
test/battle/CUnitStateTest.cpp

@@ -12,6 +12,7 @@
 #include "mock/mock_BonusBearer.h"
 #include "mock/mock_UnitInfo.h"
 #include "mock/mock_UnitEnvironment.h"
+#include "../../lib/bonuses/BonusSubtypes.h"
 #include "../../lib/battle/CUnitState.h"
 #include "../../lib/CCreatureHandler.h"
 

+ 1 - 0
test/spells/targetConditions/ImmunityNegationConditionTest.cpp

@@ -10,6 +10,7 @@
 #include "StdInc.h"
 
 #include "TargetConditionItemFixture.h"
+#include "../../../lib/bonuses/BonusSubtypes.h"
 
 //FIXME: Orb of vulnerability mechanics is not such trivial (mantis issue 1791)
 //TODO: NEGATE_ALL_NATURAL_IMMUNITIES special cases: dispel, chain lightning