Pārlūkot izejas kodu

Converted creature ID and spell ID to new form

Ivan Savenko 2 gadi atpakaļ
vecāks
revīzija
17d3d663ee

+ 1 - 1
AI/Nullkiller/AIGateway.cpp

@@ -757,7 +757,7 @@ bool AIGateway::makePossibleUpgrades(const CArmedInstance * obj)
 		{
 			UpgradeInfo ui;
 			myCb->fillUpgradeInfo(obj, SlotID(i), ui);
-			if(ui.oldID >= 0 && nullkiller->getFreeResources().canAfford(ui.cost[0] * s->count))
+			if(ui.oldID != CreatureID::NONE && nullkiller->getFreeResources().canAfford(ui.cost[0] * s->count))
 			{
 				myCb->upgradeCreature(obj, SlotID(i), ui.newID[0]);
 				upgraded = true;

+ 1 - 1
AI/Nullkiller/AIUtility.cpp

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

+ 1 - 1
AI/Nullkiller/AIUtility.h

@@ -151,7 +151,7 @@ struct ObjectIdRef
 	}
 };
 
-template<int id>
+template<Obj::Type id>
 bool objWithID(const CGObjectInstance * obj)
 {
 	return obj->ID == id;

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

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

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

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

+ 1 - 1
AI/VCAI/AIUtility.cpp

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

+ 1 - 1
AI/VCAI/AIUtility.h

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

+ 2 - 2
AI/VCAI/ArmyManager.cpp

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

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

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

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

@@ -134,7 +134,7 @@ TGoalVec GatherTroops::getAllPossibleSubgoals()
 			{
 				for(auto type : creature.second)
 				{
-					if(type == objid && ai->ah->freeResources().canAfford(VLC->creatures()->getById(type)->getFullRecruitCost()))
+					if(type.getNum() == objid && ai->ah->freeResources().canAfford(VLC->creatures()->getById(type)->getFullRecruitCost()))
 						vstd::concatenate(solutions, ai->ah->howToVisitObj(obj));
 				}
 			}

+ 3 - 3
AI/VCAI/VCAI.cpp

@@ -764,7 +764,7 @@ void makePossibleUpgrades(const CArmedInstance * obj)
 		{
 			UpgradeInfo ui;
 			cb->fillUpgradeInfo(obj, SlotID(i), ui);
-			if(ui.oldID >= 0 && cb->getResourceAmount().canAfford(ui.cost[0] * s->count))
+			if(ui.oldID != CreatureID::NONE && cb->getResourceAmount().canAfford(ui.cost[0] * s->count))
 			{
 				cb->upgradeCreature(obj, SlotID(i), ui.newID[0]);
 			}
@@ -2184,8 +2184,8 @@ void VCAI::tryRealize(Goals::BuyArmy & g)
 			auto ci = infoFromDC(t->creatures[i]);
 
 			if(!ci.count
-				|| ci.creID == -1
-				|| (g.objid != -1 && ci.creID != g.objid)
+				|| ci.creID == CreatureID::NONE
+				|| (g.objid != -1 && ci.creID.getNum() != g.objid)
 				|| t->getUpperArmy()->getSlotFor(ci.creID) == SlotID())
 				continue;
 

+ 1 - 1
client/widgets/CGarrisonInt.cpp

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

+ 4 - 4
lib/ArtifactUtils.cpp

@@ -190,18 +190,18 @@ DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(const A
 	return ArtifactUtils::createNewArtifactInstance(VLC->arth->objects[aid]);
 }
 
-DLL_LINKAGE CArtifactInstance * ArtifactUtils::createArtifact(CMap * map, const ArtifactID & aid, int spellID)
+DLL_LINKAGE CArtifactInstance * ArtifactUtils::createArtifact(CMap * map, const ArtifactID & aid, SpellID spellID)
 {
 	CArtifactInstance * art = nullptr;
-	if(aid >= 0)
+	if(aid.getNum() >= 0)
 	{
-		if(spellID < 0)
+		if(spellID == SpellID::NONE)
 		{
 			art = ArtifactUtils::createNewArtifactInstance(aid);
 		}
 		else
 		{
-			art = ArtifactUtils::createScroll(SpellID(spellID));
+			art = ArtifactUtils::createScroll(spellID);
 		}
 	}
 	else

+ 1 - 1
lib/ArtifactUtils.h

@@ -40,7 +40,7 @@ namespace ArtifactUtils
 	DLL_LINKAGE CArtifactInstance * createScroll(const SpellID & sid);
 	DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(CArtifact * art);
 	DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const ArtifactID & aid);
-	DLL_LINKAGE CArtifactInstance * createArtifact(CMap * map, const ArtifactID & aid, int spellID = -1);
+	DLL_LINKAGE CArtifactInstance * createArtifact(CMap * map, const ArtifactID & aid, SpellID spellID = SpellID::NONE);
 	DLL_LINKAGE void insertScrrollSpellName(std::string & description, const SpellID & sid);
 }
 

+ 1 - 1
lib/CCreatureSet.cpp

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

+ 17 - 17
lib/GameConstants.cpp

@@ -78,17 +78,17 @@ std::string HeroTypeID::encode(const si32 index)
 	return VLC->heroTypes()->getByIndex(index)->getJsonKey();
 }
 
-const CArtifact * ArtifactID::toArtifact() const
+const CArtifact * ArtifactIDBase::toArtifact() const
 {
 	return dynamic_cast<const CArtifact*>(toArtifact(VLC->artifacts()));
 }
 
-const Artifact * ArtifactID::toArtifact(const ArtifactService * service) const
+const Artifact * ArtifactIDBase::toArtifact(const ArtifactService * service) const
 {
-	return service->getById(*this);
+	return service->getByIndex(num);
 }
 
-si32 ArtifactID::decode(const std::string & identifier)
+si32 ArtifactIDBase::decode(const std::string & identifier)
 {
 	auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "artifact", identifier);
 	if(rawId)
@@ -97,22 +97,22 @@ si32 ArtifactID::decode(const std::string & identifier)
 		return -1;
 }
 
-std::string ArtifactID::encode(const si32 index)
+std::string ArtifactIDBase::encode(const si32 index)
 {
 	return VLC->artifacts()->getByIndex(index)->getJsonKey();
 }
 
-const CCreature * CreatureID::toCreature() const
+const CCreature * CreatureIDBase::toCreature() const
 {
-	return VLC->creh->objects.at(*this);
+	return VLC->creh->objects.at(num);
 }
 
-const Creature * CreatureID::toCreature(const CreatureService * creatures) const
+const Creature * CreatureIDBase::toCreature(const CreatureService * creatures) const
 {
-	return creatures->getById(*this);
+	return creatures->getByIndex(num);
 }
 
-si32 CreatureID::decode(const std::string & identifier)
+si32 CreatureIDBase::decode(const std::string & identifier)
 {
 	auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "creature", identifier);
 	if(rawId)
@@ -121,27 +121,27 @@ si32 CreatureID::decode(const std::string & identifier)
 		return -1;
 }
 
-std::string CreatureID::encode(const si32 index)
+std::string CreatureIDBase::encode(const si32 index)
 {
 	return VLC->creatures()->getById(CreatureID(index))->getJsonKey();
 }
 
-const CSpell * SpellID::toSpell() const
+const CSpell * SpellIDBase::toSpell() const
 {
 	if(num < 0 || num >= VLC->spellh->objects.size())
 	{
 		logGlobal->error("Unable to get spell of invalid ID %d", static_cast<int>(num));
 		return nullptr;
 	}
-	return VLC->spellh->objects[*this];
+	return VLC->spellh->objects[num];
 }
 
-const spells::Spell * SpellID::toSpell(const spells::Service * service) const
+const spells::Spell * SpellIDBase::toSpell(const spells::Service * service) const
 {
-	return service->getById(*this);
+	return service->getByIndex(num);
 }
 
-si32 SpellID::decode(const std::string & identifier)
+si32 SpellIDBase::decode(const std::string & identifier)
 {
 	auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "spell", identifier);
 	if(rawId)
@@ -150,7 +150,7 @@ si32 SpellID::decode(const std::string & identifier)
 		return -1;
 }
 
-std::string SpellID::encode(const si32 index)
+std::string SpellIDBase::encode(const si32 index)
 {
 	return VLC->spells()->getByIndex(index)->getJsonKey();
 }

+ 51 - 87
lib/GameConstants.h

@@ -221,6 +221,14 @@ class EntityBase
 {
 public:
 	int32_t num;
+
+	struct hash
+	{
+		size_t operator()(const EntityBase & id) const
+		{
+			return std::hash<int>()(id.num);
+		}
+	};
 };
 
 template<typename T>
@@ -790,10 +798,10 @@ enum class ETeleportChannelType
 	MIXED
 };
 
-class Obj
+class ObjBase : public EntityBase
 {
 public:
-	enum EObj
+	enum Type
 	{
 		NO_OBJ = -1,
 		ALTAR_OF_SACRIFICE [[deprecated]] = 2,
@@ -933,17 +941,15 @@ public:
 		MAGIC_PLAINS2 = 230,
 		ROCKLANDS = 231,
 	};
-	Obj(EObj _num = NO_OBJ) : num(_num)
-	{}
-
-	ID_LIKE_CLASS_COMMON(Obj, EObj)
-
-	EObj num;
 };
 
-ID_LIKE_OPERATORS(Obj, Obj::EObj)
+class Obj : public EntityIdentifier<ObjBase>
+{
+public:
+	using EntityIdentifier<ObjBase>::EntityIdentifier;
+};
 
-class RoadIsBase : public EntityBase
+class RoadIdBase : public EntityBase
 {
 public:
 	enum Type : int32_t
@@ -957,10 +963,10 @@ public:
 	};
 };
 
-class RoadId : public EntityIdentifier<RoadIsBase>
+class RoadId : public EntityIdentifier<RoadIdBase>
 {
 public:
-	using EntityIdentifier<RoadIsBase>::EntityIdentifier;
+	using EntityIdentifier<RoadIdBase>::EntityIdentifier;
 };
 
 class RiverIdBase : public EntityBase
@@ -1134,10 +1140,10 @@ namespace GameConstants
 	const auto BACKPACK_START = ArtifactPosition::AFTER_LAST;
 }
 
-class ArtifactID
+class ArtifactIDBase : public EntityBase
 {
 public:
-	enum EArtifactID
+	enum Type
 	{
 		NONE = -1,
 		SPELLBOOK = 0,
@@ -1147,81 +1153,45 @@ public:
 		BALLISTA = 4,
 		AMMO_CART = 5,
 		FIRST_AID_TENT = 6,
-		//CENTAUR_AXE = 7,
-		//BLACKSHARD_OF_THE_DEAD_KNIGHT = 8,
 		VIAL_OF_DRAGON_BLOOD = 127,
 		ARMAGEDDONS_BLADE = 128,
 		TITANS_THUNDER = 135,
-		//CORNUCOPIA = 140,
-		//FIXME: the following is only true if WoG is enabled. Otherwise other mod artifacts will take these slots.
 		ART_SELECTION = 144,
 		ART_LOCK = 145, // FIXME: We must get rid of this one since it's conflict with artifact from mods. See issue 2455
-		AXE_OF_SMASHING = 146,
-		MITHRIL_MAIL = 147,
-		SWORD_OF_SHARPNESS = 148,
-		HELM_OF_IMMORTALITY = 149,
-		PENDANT_OF_SORCERY = 150,
-		BOOTS_OF_HASTE = 151,
-		BOW_OF_SEEKING = 152,
-		DRAGON_EYE_RING = 153
-		//HARDENED_SHIELD = 154,
-		//SLAVAS_RING_OF_POWER = 155
 	};
 
-	ArtifactID(EArtifactID _num = NONE) : num(_num)
-	{}
-
 	DLL_LINKAGE const CArtifact * toArtifact() const;
 	DLL_LINKAGE const Artifact * toArtifact(const ArtifactService * service) const;
 
 	///json serialization helpers
 	static si32 decode(const std::string & identifier);
 	static std::string encode(const si32 index);
-
-	ID_LIKE_CLASS_COMMON(ArtifactID, EArtifactID)
-
-	EArtifactID num;
-
-	struct hash
-	{
-		size_t operator()(const ArtifactID & aid) const
-		{
-			return std::hash<int>()(aid.num);
-		}
-	};
 };
 
-ID_LIKE_OPERATORS(ArtifactID, ArtifactID::EArtifactID)
+class ArtifactID : public EntityIdentifier<ArtifactIDBase>
+{
+public:
+	using EntityIdentifier<ArtifactIDBase>::EntityIdentifier;
+};
 
-class CreatureID
+class CreatureIDBase : public EntityBase
 {
 public:
-	enum ECreatureID
+	enum Type
 	{
 		NONE = -1,
-		ARCHER = 2,
-		CAVALIER = 10,
-		CHAMPION = 11,
-		STONE_GOLEM = 32,
-		IRON_GOLEM = 33,
-		IMP = 42,
-		SKELETON = 56,
-		WALKING_DEAD = 58,
-		WIGHTS = 60,
-		LICHES = 64,
-		BONE_DRAGON = 68,
-		TROGLODYTES = 70,
-		MEDUSA = 76,
-		HYDRA = 110,
-		CHAOS_HYDRA = 111,
-		AIR_ELEMENTAL = 112,
-		EARTH_ELEMENTAL = 113,
-		FIRE_ELEMENTAL = 114,
-		WATER_ELEMENTAL = 115,
-		GOLD_GOLEM = 116,
-		DIAMOND_GOLEM = 117,
-		PSYCHIC_ELEMENTAL = 120,
-		MAGIC_ELEMENTAL = 121,
+		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,
@@ -1229,27 +1199,24 @@ public:
 		ARROW_TOWERS = 149
 	};
 
-	CreatureID(ECreatureID _num = NONE) : num(_num)
-	{}
-
 	DLL_LINKAGE const CCreature * toCreature() const;
 	DLL_LINKAGE const Creature * toCreature(const CreatureService * creatures) const;
 
-	ID_LIKE_CLASS_COMMON(CreatureID, ECreatureID)
-
-	ECreatureID num;
-
 	///json serialization helpers
 	static si32 decode(const std::string & identifier);
 	static std::string encode(const si32 index);
 };
 
-ID_LIKE_OPERATORS(CreatureID, CreatureID::ECreatureID)
+class CreatureID : public EntityIdentifier<CreatureIDBase>
+{
+public:
+	using EntityIdentifier<CreatureIDBase>::EntityIdentifier;
+};
 
-class SpellID
+class SpellIDBase : public EntityBase
 {
 public:
-	enum ESpellID
+	enum Type
 	{
 		SPELLBOOK_PRESET = -3,
 		PRESET = -2,
@@ -1278,22 +1245,19 @@ public:
 		FIRST_NON_SPELL = 70, AFTER_LAST = 82
 	};
 
-	SpellID(ESpellID _num = NONE) : num(_num)
-	{}
-
 	DLL_LINKAGE const CSpell * toSpell() const; //deprecated
 	DLL_LINKAGE const spells::Spell * toSpell(const spells::Service * service) const;
 
-	ID_LIKE_CLASS_COMMON(SpellID, ESpellID)
-
-	ESpellID num;
-
 	///json serialization helpers
 	static si32 decode(const std::string & identifier);
 	static std::string encode(const si32 index);
 };
 
-ID_LIKE_OPERATORS(SpellID, SpellID::ESpellID)
+class SpellID : public EntityIdentifier<SpellIDBase>
+{
+public:
+	using EntityIdentifier<SpellIDBase>::EntityIdentifier;
+};
 
 class BattleFieldInfo;
 class BattleField : public BaseForID<BattleField, si32>

+ 3 - 3
lib/gameState/CGameState.cpp

@@ -1575,7 +1575,7 @@ bool CGameState::checkForVictory(const PlayerColor & player, const EventConditio
 					&& (ai = dynamic_cast<const CArmedInstance *>(object.get()))) //contains army
 				{
 					for(const auto & elem : ai->Slots()) //iterate through army
-						if(elem.second->type->getId() == condition.objectType) //it's searched creature
+						if(elem.second->type->getIndex() == condition.objectType) //it's searched creature
 							total += elem.second->count;
 				}
 			}
@@ -1615,7 +1615,7 @@ bool CGameState::checkForVictory(const PlayerColor & player, const EventConditio
 			{
 				for(const auto & elem : map->objects) // mode B - destroy all objects of this type
 				{
-					if(elem && elem->ID == condition.objectType)
+					if(elem && elem->ID.getNum() == condition.objectType)
 						return false;
 				}
 				return true;
@@ -1636,7 +1636,7 @@ bool CGameState::checkForVictory(const PlayerColor & player, const EventConditio
 				for(const auto & elem : map->objects) // mode B - flag all objects of this type
 				{
 					 //check not flagged objs
-					if ( elem && elem->ID == condition.objectType && team.count(elem->tempOwner) == 0 )
+					if ( elem && elem->ID.getNum() == condition.objectType && team.count(elem->tempOwner) == 0 )
 						return false;
 				}
 				return true;

+ 1 - 1
lib/gameState/CGameStateCampaign.cpp

@@ -155,7 +155,7 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(std::vector<CampaignHeroR
 	{
 		auto shouldSlotBeErased = [&](const std::pair<SlotID, CStackInstance *> & j) -> bool
 		{
-			CreatureID::ECreatureID crid = j.second->getCreatureID().toEnum();
+			CreatureID crid = j.second->getCreatureID();
 			return !travelOptions.monstersKeptByHero.count(crid);
 		};
 

+ 1 - 1
lib/mapObjects/CGHeroInstance.cpp

@@ -824,7 +824,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
 		vstd::amin(necromancySkill, 1.0); //it's impossible to raise more creatures than all...
 		const std::map<ui32,si32> &casualties = battleResult.casualties[!battleResult.winner];
 		// figure out what to raise - pick strongest creature meeting requirements
-		auto creatureTypeRaised = CreatureID::NONE; //now we always have IMPROVED_NECROMANCY, no need for hardcode
+		CreatureID creatureTypeRaised = CreatureID::NONE; //now we always have IMPROVED_NECROMANCY, no need for hardcode
 		int requiredCasualtyLevel = 1;
 		TConstBonusListPtr improvedNecromancy = getBonuses(Selector::type()(BonusType::IMPROVED_NECROMANCY));
 		if(!improvedNecromancy->empty())

+ 1 - 1
lib/mapObjects/ObjectTemplate.cpp

@@ -24,7 +24,7 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-static bool isOnVisitableFromTopList(int identifier, int type)
+static bool isOnVisitableFromTopList(Obj identifier, int type)
 {
 	if(type == 2 || type == 3 || type == 4 || type == 5) //creature, hero, artifact, resource
 		return true;

+ 3 - 3
lib/mapping/CMap.cpp

@@ -355,7 +355,7 @@ int3 CMap::guardingCreaturePosition (int3 pos) const
 	return int3(-1, -1, -1);
 }
 
-const CGObjectInstance * CMap::getObjectiveObjectFrom(const int3 & pos, Obj::EObj type)
+const CGObjectInstance * CMap::getObjectiveObjectFrom(const int3 & pos, Obj type)
 {
 	for (CGObjectInstance * object : getTile(pos).visitableObjects)
 	{
@@ -418,7 +418,7 @@ void CMap::checkForObjectives()
 
 				case EventCondition::CONTROL:
 					if (isInTheMap(cond.position))
-						cond.object = getObjectiveObjectFrom(cond.position, static_cast<Obj::EObj>(cond.objectType));
+						cond.object = getObjectiveObjectFrom(cond.position, static_cast<Obj>(cond.objectType));
 
 					if (cond.object)
 					{
@@ -433,7 +433,7 @@ void CMap::checkForObjectives()
 
 				case EventCondition::DESTROY:
 					if (isInTheMap(cond.position))
-						cond.object = getObjectiveObjectFrom(cond.position, static_cast<Obj::EObj>(cond.objectType));
+						cond.object = getObjectiveObjectFrom(cond.position, static_cast<Obj>(cond.objectType));
 
 					if (cond.object)
 					{

+ 1 - 1
lib/mapping/CMap.h

@@ -116,7 +116,7 @@ public:
 	void banWaterContent();
 
 	/// Gets object of specified type on requested position
-	const CGObjectInstance * getObjectiveObjectFrom(const int3 & pos, Obj::EObj type);
+	const CGObjectInstance * getObjectiveObjectFrom(const int3 & pos, Obj type);
 	CGHeroInstance * getHero(int heroId);
 
 	/// Sets the victory/loss condition objectives ??

+ 3 - 3
lib/mapping/MapFormatH3M.cpp

@@ -1159,8 +1159,8 @@ CGObjectInstance * CMapLoaderH3M::readGarrison(const int3 & mapPosition)
 
 CGObjectInstance * CMapLoaderH3M::readArtifact(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
 {
-	auto artID = ArtifactID::NONE; //random, set later
-	int spellID = -1;
+	ArtifactID artID = ArtifactID::NONE; //random, set later
+	SpellID spellID = SpellID::NONE;
 	auto * object = new CGArtifact();
 
 	readMessageAndGuards(object->message, object, mapPosition);
@@ -1176,7 +1176,7 @@ CGObjectInstance * CMapLoaderH3M::readArtifact(const int3 & mapPosition, std::sh
 		artID = ArtifactID(objectTemplate->subid);
 	}
 
-	object->storedArtifact = ArtifactUtils::createArtifact(map, artID, spellID);
+	object->storedArtifact = ArtifactUtils::createArtifact(map, artID, spellID.getNum());
 	return object;
 }
 

+ 3 - 3
lib/mapping/MapFormatJson.cpp

@@ -1189,8 +1189,8 @@ void CMapLoaderJson::MapObjectLoader::configure()
 
 	if(auto * art = dynamic_cast<CGArtifact *>(instance))
 	{
-		auto artID = ArtifactID::NONE;
-		int spellID = -1;
+		ArtifactID artID = ArtifactID::NONE;
+		SpellID spellID = SpellID::NONE;
 
 		if(art->ID == Obj::SPELL_SCROLL)
 		{
@@ -1208,7 +1208,7 @@ void CMapLoaderJson::MapObjectLoader::configure()
 			artID = ArtifactID(art->subID);
 		}
 
-		art->storedArtifact = ArtifactUtils::createArtifact(owner->map, artID, spellID);
+		art->storedArtifact = ArtifactUtils::createArtifact(owner->map, artID, spellID.getNum());
 	}
 
 	if(auto * hero = dynamic_cast<CGHeroInstance *>(instance))

+ 11 - 11
lib/mapping/MapReaderH3M.cpp

@@ -65,10 +65,10 @@ ArtifactID MapReaderH3M::readArtifact()
 	else
 		result = ArtifactID(reader->readUInt8());
 
-	if(result == features.artifactIdentifierInvalid)
+	if(result.getNum() == features.artifactIdentifierInvalid)
 		return ArtifactID::NONE;
 
-	if (result < features.artifactsCount)
+	if (result.getNum() < features.artifactsCount)
 		return remapIdentifier(result);
 
 	logGlobal->warn("Map contains invalid artifact %d. Will be removed!", result.getNum());
@@ -82,7 +82,7 @@ ArtifactID MapReaderH3M::readArtifact32()
 	if(result == ArtifactID::NONE)
 		return ArtifactID::NONE;
 
-	if (result < features.artifactsCount)
+	if (result.getNum() < features.artifactsCount)
 		return remapIdentifier(result);
 
 	logGlobal->warn("Map contains invalid artifact %d. Will be removed!", result.getNum());
@@ -120,17 +120,17 @@ CreatureID MapReaderH3M::readCreature()
 	else
 		result = CreatureID(reader->readUInt8());
 
-	if(result == features.creatureIdentifierInvalid)
+	if(result.getNum() == features.creatureIdentifierInvalid)
 		return CreatureID::NONE;
 
-	if(result < features.creaturesCount)
+	if(result.getNum() < features.creaturesCount)
 		return remapIdentifier(result);;
 
 	// this may be random creature in army/town, to be randomized later
 	CreatureID randomIndex(result.getNum() - features.creatureIdentifierInvalid - 1);
 	assert(randomIndex < CreatureID::NONE);
 
-	if (randomIndex > -16)
+	if (randomIndex.getNum() > -16)
 		return randomIndex;
 
 	logGlobal->warn("Map contains invalid creature %d. Will be removed!", result.getNum());
@@ -168,21 +168,21 @@ SecondarySkill MapReaderH3M::readSkill()
 SpellID MapReaderH3M::readSpell()
 {
 	SpellID result(readUInt8());
-	if(result == features.spellIdentifierInvalid)
+	if(result.getNum() == features.spellIdentifierInvalid)
 		return SpellID::NONE;
-	if(result == features.spellIdentifierInvalid - 1)
+	if(result.getNum() == features.spellIdentifierInvalid - 1)
 		return SpellID::PRESET;
 
-	assert(result < features.spellsCount);
+	assert(result.getNum() < features.spellsCount);
 	return remapIdentifier(result);;
 }
 
 SpellID MapReaderH3M::readSpell32()
 {
 	SpellID result(readInt32());
-	if(result == features.spellIdentifierInvalid)
+	if(result.getNum() == features.spellIdentifierInvalid)
 		return SpellID::NONE;
-	assert(result < features.spellsCount);
+	assert(result.getNum() < features.spellsCount);
 	return result;
 }
 

+ 2 - 2
lib/rmg/RmgMap.cpp

@@ -342,8 +342,8 @@ ui32 RmgMap::getTotalZoneCount() const
 
 bool RmgMap::isAllowedSpell(const SpellID & sid) const
 {
-	assert(sid >= 0);
-	if (sid < mapInstance->allowedSpells.size())
+	assert(sid.getNum() >= 0);
+	if (sid.getNum() < mapInstance->allowedSpells.size())
 	{
 		return mapInstance->allowedSpells[sid];
 	}

+ 1 - 1
mapeditor/inspector/armywidget.cpp

@@ -80,7 +80,7 @@ bool ArmyWidget::commitChanges()
 	for(int i = 0; i < TOTAL_SLOTS; ++i)
 	{
 		CreatureID creId(uiSlots[i]->itemData(uiSlots[i]->currentIndex()).toInt());
-		if(creId == -1)
+		if(creId == CreatureID::NONE)
 		{
 			if(army.hasStackAtSlot(SlotID(i)))
 				army.eraseStack(SlotID(i));

+ 1 - 1
mapeditor/inspector/inspector.cpp

@@ -284,7 +284,7 @@ void Inspector::updateProperties(CGArtifact * o)
 	if(instance)
 	{
 		SpellID spellId = instance->getScrollSpellID();
-		if(spellId != -1)
+		if(spellId != SpellID::NONE)
 		{
 			auto * delegate = new InspectorDelegate;
 			for(auto spell : VLC->spellh->objects)

+ 1 - 1
server/CGameHandler.cpp

@@ -2491,7 +2491,7 @@ bool CGameHandler::upgradeCreature(ObjectInstanceID objid, SlotID pos, CreatureI
 	int newIDpos= vstd::find_pos(ui.newID, upgID);//get position of new id in UpgradeInfo
 
 	//check if upgrade is possible
-	if ((ui.oldID<0 || newIDpos == -1) && complain("That upgrade is not possible!"))
+	if ((ui.oldID == CreatureID::NONE || newIDpos == -1) && complain("That upgrade is not possible!"))
 	{
 		return false;
 	}

+ 5 - 5
server/CVCMIServer.cpp

@@ -890,7 +890,7 @@ void CVCMIServer::optionSetCastle(PlayerColor player, int id)
 	FactionID & cur = s.castle;
 	auto & allowed = getPlayerInfo(player.getNum()).allowedFactions;
 
-	if(cur == PlayerSettings::NONE) //no change
+	if(cur.getNum() == PlayerSettings::NONE) //no change
 		return;
 
 	if(allowed.find(static_cast<FactionID>(id)) == allowed.end() && id != PlayerSettings::RANDOM) // valid id
@@ -898,11 +898,11 @@ void CVCMIServer::optionSetCastle(PlayerColor player, int id)
 
 	cur = static_cast<FactionID>(id);
 
-	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;
 	}
-	if(cur < 0 && s.bonus == PlayerSettings::RESOURCE)
+	if(cur.getNum() < 0 && s.bonus == PlayerSettings::RESOURCE)
 		s.bonus = PlayerSettings::RANDOM;
 }
 
@@ -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 < 0 || s.hero == PlayerSettings::NONE)
+	if(s.castle.getNum() < 0 || s.hero == PlayerSettings::NONE)
 		return;
 
 	if(id == PlayerSettings::RANDOM)
@@ -1027,7 +1027,7 @@ void CVCMIServer::optionSetBonus(PlayerColor player, int id)
 	if(id < PlayerSettings::RANDOM)
 		return;
 
-	if(s.castle == PlayerSettings::RANDOM && id == PlayerSettings::RESOURCE) //random castle - can't be resource
+	if(s.castle.getNum() == PlayerSettings::RANDOM && id == PlayerSettings::RESOURCE) //random castle - can't be resource
 		return;
 
 	s.bonus = static_cast<PlayerSettings::Ebonus>(static_cast<int>(id));

+ 3 - 3
server/battles/BattleActionProcessor.cpp

@@ -406,10 +406,10 @@ bool BattleActionProcessor::doUnitSpellAction(const BattleAction & ba)
 	std::shared_ptr<const Bonus> spellcaster = stack->getBonus(Selector::typeSubtype(BonusType::SPELLCASTER, spellID));
 
 	//TODO special bonus for genies ability
-	if (randSpellcaster && gameHandler->battleGetRandomStackSpell(gameHandler->getRandomGenerator(), stack, CBattleInfoCallback::RANDOM_AIMED) < 0)
+	if (randSpellcaster && gameHandler->battleGetRandomStackSpell(gameHandler->getRandomGenerator(), stack, CBattleInfoCallback::RANDOM_AIMED) == SpellID::NONE)
 		spellID = gameHandler->battleGetRandomStackSpell(gameHandler->getRandomGenerator(), stack, CBattleInfoCallback::RANDOM_GENIE);
 
-	if (spellID < 0)
+	if (spellID == SpellID::NONE)
 		gameHandler->complain("That stack can't cast spells!");
 	else
 	{
@@ -1216,7 +1216,7 @@ void BattleActionProcessor::handleAfterAttackCasting(bool ranged, const CStack *
 
 		int bonusAdditionalInfo = attacker->getBonus(Selector::type()(BonusType::TRANSMUTATION))->additionalInfo[0];
 
-		if(defender->unitType()->getId() == bonusAdditionalInfo ||
+		if(defender->unitType()->getIndex() == bonusAdditionalInfo ||
 			(bonusAdditionalInfo == CAddInfo::NONE && defender->unitType()->getId() == attacker->unitType()->getId()))
 			return;
 

+ 1 - 1
server/battles/BattleResultProcessor.cpp

@@ -383,7 +383,7 @@ void BattleResultProcessor::endBattleConfirm(const BattleInfo * battleInfo)
 		{
 			iw.components.emplace_back(
 				Component::EComponentType::ARTIFACT, art->artType->getId(),
-				art->artType->getId() == ArtifactID::SPELL_SCROLL? art->getScrollSpellID() : 0, 0);
+				art->artType->getId() == ArtifactID::SPELL_SCROLL? art->getScrollSpellID() : SpellID(0), 0);
 			if (iw.components.size() >= 14)
 			{
 				gameHandler->sendAndApply(&iw);