浏览代码

Remove explicit convesion to int in operators

Ivan Savenko 1 年之前
父节点
当前提交
abad4b01ce

+ 2 - 1
include/vcmi/spells/Caster.h

@@ -17,6 +17,7 @@ class MetaString;
 class ServerCallback;
 class CGHeroInstance;
 class Spell;
+class SpellSchool;
 
 namespace battle
 {
@@ -38,7 +39,7 @@ public:
 	/// returns level on which given spell would be cast by this(0 - none, 1 - basic etc);
 	/// caster may not know this spell at all
 	/// optionally returns number of selected school by arg - 0 - air magic, 1 - fire magic, 2 - water magic, 3 - earth magic
-	virtual int32_t getSpellSchoolLevel(const Spell * spell, int32_t * outSelectedSchool = nullptr) const = 0;
+	virtual int32_t getSpellSchoolLevel(const Spell * spell, SpellSchool * outSelectedSchool = nullptr) const = 0;
 
 	///default spell school level for effect calculation
 	virtual int32_t getEffectLevel(const Spell * spell) const = 0;

+ 1 - 1
lib/ArtifactUtils.cpp

@@ -216,7 +216,7 @@ DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(CArtifa
 
 DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(const ArtifactID & aid)
 {
-	return ArtifactUtils::createNewArtifactInstance(VLC->arth->objects[aid]);
+	return ArtifactUtils::createNewArtifactInstance((*VLC->arth)[aid]);
 }
 
 DLL_LINKAGE CArtifactInstance * ArtifactUtils::createArtifact(CMap * map, const ArtifactID & aid, SpellID spellID)

+ 7 - 8
lib/CArtHandler.cpp

@@ -371,7 +371,7 @@ void CArtHandler::loadObject(std::string scope, std::string name, const JsonNode
 
 	objects.emplace_back(object);
 
-	registerObject(scope, "artifact", name, object->id);
+	registerObject(scope, "artifact", name, object->id.getNum());
 }
 
 void CArtHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index)
@@ -383,7 +383,7 @@ void CArtHandler::loadObject(std::string scope, std::string name, const JsonNode
 	assert(objects[index] == nullptr); // ensure that this id was not loaded before
 	objects[index] = object;
 
-	registerObject(scope, "artifact", name, object->id);
+	registerObject(scope, "artifact", name, object->id.getNum());
 }
 
 const std::vector<std::string> & CArtHandler::getTypeNames() const
@@ -630,7 +630,7 @@ void CArtHandler::makeItCommanderArt(CArtifact * a, bool onlyCommander)
 
 bool CArtHandler::legalArtifact(const ArtifactID & id)
 {
-	auto art = objects[id];
+	auto art = id.toArtifact();
 	//assert ( (!art->constituents) || art->constituents->size() ); //artifacts is not combined or has some components
 
 	if(art->isCombined())
@@ -639,13 +639,13 @@ bool CArtHandler::legalArtifact(const ArtifactID & id)
 	if(art->aClass < CArtifact::ART_TREASURE || art->aClass > CArtifact::ART_RELIC)
 		return false; // invalid class
 
-	if(!art->possibleSlots[ArtBearer::HERO].empty())
+	if(art->possibleSlots.count(ArtBearer::HERO) && !art->possibleSlots.at(ArtBearer::HERO).empty())
 		return true;
 
-	if(!art->possibleSlots[ArtBearer::CREATURE].empty() && VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_ARTIFACT))
+	if(art->possibleSlots.count(ArtBearer::CREATURE) && !art->possibleSlots.at(ArtBearer::CREATURE).empty() && VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_ARTIFACT))
 		return true;
 
-	if(!art->possibleSlots[ArtBearer::COMMANDER].empty() && VLC->settings()->getBoolean(EGameSettings::MODULE_COMMANDERS))
+	if(art->possibleSlots.count(ArtBearer::COMMANDER) && !art->possibleSlots.at(ArtBearer::COMMANDER).empty() && VLC->settings()->getBoolean(EGameSettings::MODULE_COMMANDERS))
 		return true;
 
 	return false;
@@ -658,7 +658,7 @@ void CArtHandler::initAllowedArtifactsList(const std::set<ArtifactID> & allowed)
 	for (ArtifactID i : allowed)
 	{
 		if (legalArtifact(ArtifactID(i)))
-			allowedArtifacts.push_back(objects[i]);
+			allowedArtifacts.push_back(i.toArtifact());
 			//keep im mind that artifact can be worn by more than one type of bearer
 	}
 }
@@ -682,7 +682,6 @@ void CArtHandler::afterLoadFinalization()
 	{
 		for(auto &bonus : art->getExportedBonusList())
 		{
-			assert(art == objects[art->id]);
 			assert(bonus->source == BonusSource::ARTIFACT);
 			bonus->sid = BonusSourceID(art->id);
 		}

+ 1 - 1
lib/CArtHandler.h

@@ -142,7 +142,7 @@ class DLL_LINKAGE CArtHandler : public CHandlerBase<ArtifactID, Artifact, CArtif
 {
 public:
 	/// List of artifacts allowed on the map
-	std::vector<CArtifact *> allowedArtifacts;
+	std::vector<const CArtifact *> allowedArtifacts;
 
 	void addBonuses(CArtifact *art, const JsonNode &bonusList);
 

+ 3 - 5
lib/CCreatureHandler.cpp

@@ -324,7 +324,7 @@ bool CCreature::isMyUpgrade(const CCreature *anotherCre) const
 
 bool CCreature::valid() const
 {
-	return this == VLC->creh->objects[idNumber];
+	return this == (*VLC->creh)[idNumber];
 }
 
 std::string CCreature::nodeName() const
@@ -778,15 +778,13 @@ void CCreatureHandler::loadCrExpBon(CBonusSystemNode & globalEffects)
 		}
 		do //parse everything that's left
 		{
-			CreatureID sid = static_cast<ui32>(parser.readNumber()); //id = this particular creature ID
+			CreatureID sid = parser.readNumber(); //id = this particular creature ID
 
 			b.sid = BonusSourceID(sid);
 			bl.clear();
 			loadStackExp(b, bl, parser);
 			for(const auto & b : bl)
-			{
-				objects[sid]->addNewBonus(b); //add directly to CCreature Node
-			}
+				(*this)[sid]->addNewBonus(b); //add directly to CCreature Node
 		}
 		while (parser.endLine());
 

+ 7 - 7
lib/CCreatureSet.cpp

@@ -79,7 +79,7 @@ bool CCreatureSet::setCreature(SlotID slot, CreatureID type, TQuantity quantity)
 
 SlotID CCreatureSet::getSlotFor(const CreatureID & creature, ui32 slotsAmount) const /*returns -1 if no slot available */
 {
-	return getSlotFor(VLC->creh->objects[creature], slotsAmount);
+	return getSlotFor(creature.toCreature(), slotsAmount);
 }
 
 SlotID CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount) const
@@ -304,7 +304,7 @@ void CCreatureSet::sweep()
 
 void CCreatureSet::addToSlot(const SlotID & slot, const CreatureID & cre, TQuantity count, bool allowMerging)
 {
-	const CCreature *c = VLC->creh->objects[cre];
+	const CCreature *c = cre.toCreature();
 
 	if(!hasStackAtSlot(slot))
 	{
@@ -749,10 +749,10 @@ void CStackInstance::giveStackExp(TExpType exp)
 
 void CStackInstance::setType(const CreatureID & creID)
 {
-	if(creID.getNum() >= 0 && creID.getNum() < VLC->creh->objects.size())
-		setType(VLC->creh->objects[creID]);
+	if (creID == CreatureID::NONE)
+		setType(nullptr);//FIXME: unused branch?
 	else
-		setType((const CCreature*)nullptr);
+		setType(creID.toCreature());
 }
 
 void CStackInstance::setType(const CCreature *c)
@@ -809,7 +809,7 @@ bool CStackInstance::valid(bool allowUnrandomized) const
 {
 	if(!randomStack)
 	{
-		return (type  &&  type == VLC->creh->objects[type->getId()]);
+		return (type && type == type->getId().toEntity(VLC));
 	}
 	else
 		return allowUnrandomized;
@@ -999,7 +999,7 @@ bool CCommanderInstance::gainsLevel() const
 CStackBasicDescriptor::CStackBasicDescriptor() = default;
 
 CStackBasicDescriptor::CStackBasicDescriptor(const CreatureID & id, TQuantity Count):
-	type(VLC->creh->objects[id]), 
+	type(id.toCreature()),
 	count(Count)
 {
 }

+ 2 - 2
lib/CHeroHandler.cpp

@@ -518,7 +518,7 @@ static std::vector<std::shared_ptr<Bonus>> createCreatureSpecialty(CreatureID ba
 
 		for (auto const & upgradeSourceID : oldTargets)
 		{
-			const CCreature * upgradeSource = VLC->creh->objects[upgradeSourceID];
+			const CCreature * upgradeSource = upgradeSourceID.toCreature();
 			targets.insert(upgradeSource->upgrades.begin(), upgradeSource->upgrades.end());
 		}
 
@@ -528,7 +528,7 @@ static std::vector<std::shared_ptr<Bonus>> createCreatureSpecialty(CreatureID ba
 
 	for(CreatureID cid : targets)
 	{
-		const CCreature &specCreature = *VLC->creh->objects[cid];
+		auto const & specCreature = *cid.toCreature();
 		int stepSize = specCreature.getLevel() ? specCreature.getLevel() : 5;
 
 		{

+ 4 - 4
lib/JsonRandom.cpp

@@ -156,7 +156,7 @@ namespace JsonRandom
 
 		for (auto const & artID : valuesSet)
 		{
-			CArtifact * art = VLC->arth->objects[artID];
+			const CArtifact * art = artID.toArtifact();
 
 			if(!vstd::iswithin(art->getPrice(), minValue, maxValue))
 				continue;
@@ -482,13 +482,13 @@ namespace JsonRandom
 		else
 			logMod->warn("Failed to select suitable random creature!");
 
-		stack.type = VLC->creh->objects[pickedCreature];
+		stack.type = pickedCreature.toCreature();
 		stack.count = loadValue(value, rng, variables);
 		if (!value["upgradeChance"].isNull() && !stack.type->upgrades.empty())
 		{
 			if (int(value["upgradeChance"].Float()) > rng.nextInt(99)) // select random upgrade
 			{
-				stack.type = VLC->creh->objects[*RandomGeneratorUtil::nextItem(stack.type->upgrades, rng)];
+				stack.type = RandomGeneratorUtil::nextItem(stack.type->upgrades, rng)->toCreature();
 			}
 		}
 		return stack;
@@ -523,7 +523,7 @@ namespace JsonRandom
 			if (node["upgradeChance"].Float() > 0)
 			{
 				for(const auto & creaID : crea->upgrades)
-					info.allowedCreatures.push_back(VLC->creh->objects[creaID]);
+					info.allowedCreatures.push_back(creaID.toCreature());
 			}
 			ret.push_back(info);
 		}

+ 1 - 1
lib/battle/CUnitState.cpp

@@ -428,7 +428,7 @@ const CGHeroInstance * CUnitState::getHeroCaster() const
 	return nullptr;
 }
 
-int32_t CUnitState::getSpellSchoolLevel(const spells::Spell * spell, int32_t * outSelectedSchool) const
+int32_t CUnitState::getSpellSchoolLevel(const spells::Spell * spell, SpellSchool * outSelectedSchool) const
 {
 	int32_t skill = valOfBonuses(Selector::typeSubtype(BonusType::SPELLCASTER, BonusSubtypeID(spell->getId())));
 	vstd::abetween(skill, 0, 3);

+ 1 - 1
lib/battle/CUnitState.h

@@ -182,7 +182,7 @@ public:
 
 	int32_t getCasterUnitId() const override;
 
-	int32_t getSpellSchoolLevel(const spells::Spell * spell, int32_t * outSelectedSchool = nullptr) const override;
+	int32_t getSpellSchoolLevel(const spells::Spell * spell, SpellSchool * outSelectedSchool = nullptr) const override;
 	int32_t getEffectLevel(const spells::Spell * spell) const override;
 
 	int64_t getSpellBonus(const spells::Spell * spell, int64_t base, const Unit * affectedStack) const override;

+ 3 - 3
lib/constants/EntityIdentifiers.cpp

@@ -160,12 +160,12 @@ std::string CampaignScenarioID::encode(const si32 index)
 	return std::to_string(index);
 }
 
-std::string Obj::encode(int32_t index)
+std::string MapObjectID::encode(int32_t index)
 {
-	return VLC->objtypeh->getObjectHandlerName(index);
+	return VLC->objtypeh->getObjectHandlerName(MapObjectID(index));
 }
 
-si32 Obj::decode(const std::string & identifier)
+si32 MapObjectID::decode(const std::string & identifier)
 {
 	auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "objects", identifier);
 	if(rawId)

+ 7 - 0
lib/constants/EntityIdentifiers.h

@@ -672,6 +672,12 @@ class ArtifactPosition : public IdentifierWithEnum<ArtifactPosition, ArtifactPos
 {
 public:
 	using IdentifierWithEnum<ArtifactPosition, ArtifactPositionBase>::IdentifierWithEnum;
+
+	// TODO: Remove
+	constexpr operator int32_t () const
+	{
+		return num;
+	}
 };
 
 class ArtifactIDBase : public IdentifierBase
@@ -728,6 +734,7 @@ public:
 		FIRE_ELEMENTAL = 114, // for tests
 		PSYCHIC_ELEMENTAL = 120, // for hardcoded ability
 		MAGIC_ELEMENTAL = 121, // for hardcoded ability
+		AZURE_DRAGON = 132,
 		CATAPULT = 145,
 		BALLISTA = 146,
 		FIRST_AID_TENT = 147,

+ 1 - 2
lib/gameState/CGameState.cpp

@@ -1860,8 +1860,7 @@ void CGameState::attachArmedObjects()
 
 bool CGameState::giveHeroArtifact(CGHeroInstance * h, const ArtifactID & aid)
 {
-	 CArtifact * const artifact = VLC->arth->objects[aid]; //pointer to constant object
-	 CArtifactInstance * ai = ArtifactUtils::createNewArtifactInstance(artifact);
+	 CArtifactInstance * ai = ArtifactUtils::createNewArtifactInstance(aid);
 	 map->addNewArtifactInstance(ai);
 	 auto slot = ArtifactUtils::getArtAnyPosition(h, aid);
 	 if(ArtifactUtils::isSlotEquipment(slot) || ArtifactUtils::isSlotBackpack(slot))

+ 15 - 17
lib/mapObjectConstructors/CObjectClassesHandler.cpp

@@ -288,27 +288,26 @@ void CObjectClassesHandler::loadObject(std::string scope, std::string name, cons
 void CObjectClassesHandler::loadSubObject(const std::string & identifier, JsonNode config, MapObjectID ID, MapObjectSubID subID)
 {
 	config.setType(JsonNode::JsonType::DATA_STRUCT); // ensure that input is not NULL
-	assert(objects[ID]);
+	assert(objects[ID.getNum()]);
 
-	if ( subID >= objects[ID]->objects.size())
-		objects[ID]->objects.resize(subID+1);
+	if ( subID.getNum() >= objects[ID.getNum()]->objects.size())
+		objects[ID.getNum()]->objects.resize(subID.getNum()+1);
 
-	JsonUtils::inherit(config, objects.at(ID)->base);
-	loadSubObject(config.meta, identifier, config, objects[ID], subID);
+	JsonUtils::inherit(config, objects.at(ID.getNum())->base);
+	loadSubObject(config.meta, identifier, config, objects[ID.getNum()], subID.getNum());
 }
 
 void CObjectClassesHandler::removeSubObject(MapObjectID ID, MapObjectSubID subID)
 {
-	assert(objects[ID]);
-	assert(subID < objects[ID]->objects.size());
-	objects[ID]->objects[subID] = nullptr;
+	assert(objects[ID.getNum()]);
+	objects[ID.getNum()]->objects[subID.getNum()] = nullptr;
 }
 
 TObjectTypeHandler CObjectClassesHandler::getHandlerFor(MapObjectID type, MapObjectSubID subtype) const
 {
 	try
 	{
-		auto result = objects.at(type)->objects.at(subtype);
+		auto result = objects.at(type.getNum())->objects.at(subtype.getNum());
 
 		if (result != nullptr)
 			return result;
@@ -318,7 +317,7 @@ TObjectTypeHandler CObjectClassesHandler::getHandlerFor(MapObjectID type, MapObj
 		// Leave catch block silently
 	}
 
-	std::string errorString = "Failed to find object of type " + std::to_string(type) + "::" + std::to_string(subtype);
+	std::string errorString = "Failed to find object of type " + std::to_string(type.getNum()) + "::" + std::to_string(subtype.getNum());
 	logGlobal->error(errorString);
 	throw std::runtime_error(errorString);
 }
@@ -360,13 +359,13 @@ std::set<MapObjectSubID> CObjectClassesHandler::knownSubObjects(MapObjectID prim
 {
 	std::set<MapObjectSubID> ret;
 
-	if (!objects.at(primaryID))
+	if (!objects.at(primaryID.getNum()))
 	{
 		logGlobal->error("Failed to find object %d", primaryID);
 		return ret;
 	}
 
-	for(const auto & entry : objects.at(primaryID)->objects)
+	for(const auto & entry : objects.at(primaryID.getNum())->objects)
 		if (entry)
 			ret.insert(entry->subtype);
 
@@ -460,7 +459,7 @@ std::string CObjectClassesHandler::getObjectName(MapObjectID type, MapObjectSubI
 	if (handler && handler->hasNameTextID())
 		return handler->getNameTranslated();
 	else
-		return objects[type]->getNameTranslated();
+		return objects[type.getNum()]->getNameTranslated();
 }
 
 SObjectSounds CObjectClassesHandler::getObjectSounds(MapObjectID type, MapObjectSubID subtype) const
@@ -472,20 +471,19 @@ SObjectSounds CObjectClassesHandler::getObjectSounds(MapObjectID type, MapObject
 	if(type == Obj::PRISON || type == Obj::HERO || type == Obj::SPELL_SCROLL)
 		subtype = 0;
 
-	assert(objects[type]);
-	assert(subtype < objects[type]->objects.size());
+	assert(objects[type.getNum()]);
 
 	return getHandlerFor(type, subtype)->getSounds();
 }
 
 std::string CObjectClassesHandler::getObjectHandlerName(MapObjectID type) const
 {
-	return objects.at(type)->handlerName;
+	return objects.at(type.getNum())->handlerName;
 }
 
 std::string CObjectClassesHandler::getJsonKey(MapObjectID type) const
 {
-	return objects.at(type)->getJsonKey();
+	return objects.at(type.getNum())->getJsonKey();
 }
 
 VCMI_LIB_NAMESPACE_END

+ 1 - 1
lib/mapObjects/CArmedInstance.cpp

@@ -19,7 +19,7 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-void CArmedInstance::randomizeArmy(int type)
+void CArmedInstance::randomizeArmy(FactionID type)
 {
 	for (auto & elem : stacks)
 	{

+ 1 - 1
lib/mapObjects/CArmedInstance.h

@@ -29,7 +29,7 @@ private:
 public:
 	BattleInfo *battle; //set to the current battle, if engaged
 
-	void randomizeArmy(int type);
+	void randomizeArmy(FactionID type);
 	virtual void updateMoraleBonusFromArmy();
 
 	void armyChanged() override;

+ 11 - 15
lib/mapObjects/CGHeroInstance.cpp

@@ -578,11 +578,11 @@ void CGHeroInstance::pickRandomObject(CRandomGenerator & rand)
 	{
 		ID = Obj::HERO;
 		subID = cb->gameState()->pickNextHeroType(getOwner());
-		type = VLC->heroh->objects[subID];
+		type = VLC->heroh->objects[getHeroType().getNum()];
 		randomizeArmy(type->heroClass->faction);
 	}
 	else
-		type = VLC->heroh->objects[subID];
+		type = VLC->heroh->objects[getHeroType().getNum()];
 
 	auto oldSubID = subID;
 
@@ -657,7 +657,7 @@ int32_t CGHeroInstance::getCasterUnitId() const
 	return id.getNum();
 }
 
-int32_t CGHeroInstance::getSpellSchoolLevel(const spells::Spell * spell, int32_t * outSelectedSchool) const
+int32_t CGHeroInstance::getSpellSchoolLevel(const spells::Spell * spell, SpellSchool * outSelectedSchool) const
 {
 	int32_t skill = -1; //skill level
 
@@ -909,7 +909,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
 		// raise upgraded creature (at 2/3 rate) if no space available otherwise
 		if(getSlotFor(creatureTypeRaised) == SlotID())
 		{
-			for(const CreatureID & upgraded : VLC->creh->objects[creatureTypeRaised]->upgrades)
+			for(const CreatureID & upgraded : creatureTypeRaised.toCreature()->upgrades)
 			{
 				if(getSlotFor(upgraded) != SlotID())
 				{
@@ -920,7 +920,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
 			}
 		}
 		// calculate number of creatures raised - low level units contribute at 50% rate
-		const double raisedUnitHealth = VLC->creh->objects[creatureTypeRaised]->getMaxHealth();
+		const double raisedUnitHealth = creatureTypeRaised.toCreature()->getMaxHealth();
 		double raisedUnits = 0;
 		for(const auto & casualty : casualties)
 		{
@@ -1523,7 +1523,7 @@ std::string CGHeroInstance::getHeroTypeName() const
 		}
 		else
 		{
-			return VLC->heroh->objects[getHeroType()]->getJsonKey();
+			return getHeroType().toEntity(VLC)->getJsonKey();
 		}
 	}
 	return "";
@@ -1657,15 +1657,11 @@ void CGHeroInstance::serializeCommonOptions(JsonSerializeFormat & handler)
 			for(size_t skillIndex = 0; skillIndex < secondarySkills.size(); ++skillIndex)
 			{
 				JsonArraySerializer inner = secondarySkills.enterArray(skillIndex);
-				const si32 rawId = secSkills.at(skillIndex).first;
-
-				if(rawId < 0 || rawId >= VLC->skillh->size())
-					logGlobal->error("Invalid secondary skill %d", rawId);
+				SecondarySkill skillId = secSkills.at(skillIndex).first;
 
-				auto value = (*VLC->skillh)[SecondarySkill(rawId)]->getJsonKey();
-				handler.serializeString("skill", value);
-				value = NSecondarySkill::levels.at(secSkills.at(skillIndex).second);
-				handler.serializeString("level", value);
+				handler.serializeId("skill", skillId);
+				std::string skillLevel = NSecondarySkill::levels.at(secSkills.at(skillIndex).second);
+				handler.serializeString("level", skillLevel);
 			}
 		}
 	}
@@ -1757,7 +1753,7 @@ void CGHeroInstance::serializeJsonOptions(JsonSerializeFormat & handler)
 			if(!appearance)
 			{
 				// crossoverDeserialize
-				type = VLC->heroh->objects[getHeroType()];
+				type = VLC->heroh->objects[getHeroType().getNum()];
 				appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
 			}
 

+ 1 - 1
lib/mapObjects/CGHeroInstance.h

@@ -274,7 +274,7 @@ public:
 
 	///spells::Caster
 	int32_t getCasterUnitId() const override;
-	int32_t getSpellSchoolLevel(const spells::Spell * spell, int32_t * outSelectedSchool = nullptr) const override;
+	int32_t getSpellSchoolLevel(const spells::Spell * spell, SpellSchool * outSelectedSchool = nullptr) const override;
 	int64_t getSpellBonus(const spells::Spell * spell, int64_t base, const battle::Unit * affectedStack) const override;
 	int64_t getSpecificSpellBonus(const spells::Spell * spell, int64_t base) const override;
 

+ 5 - 5
lib/mapObjects/CGTownInstance.cpp

@@ -136,7 +136,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
 	if (creatures[level].second.empty())
 		return ret; //no dwelling
 
-	const CCreature *creature = VLC->creh->objects[creatures[level].second.back()];
+	const Creature *creature = creatures[level].second.back().toEntity(VLC);
 	const int base = creature->getGrowth();
 	int castleBonus = 0;
 
@@ -489,8 +489,8 @@ void CGTownInstance::pickRandomObject(CRandomGenerator & rand)
 
 	assert(ID == Obj::TOWN); // just in case
 	setType(ID, subID);
-	town = (*VLC->townh)[subID]->town;
-	randomizeArmy(subID);
+	town = (*VLC->townh)[getFaction()]->town;
+	randomizeArmy(getFaction());
 	updateAppearance();
 }
 
@@ -571,7 +571,7 @@ void CGTownInstance::newTurn(CRandomGenerator & rand) const
 				}
 				else //upgrade
 				{
-					cb->changeStackType(sl, VLC->creh->objects[*c->upgrades.begin()]);
+					cb->changeStackType(sl, c->upgrades.begin()->toCreature());
 				}
 			}
 			if ((stacksCount() < GameConstants::ARMY_SIZE && rand.nextInt(99) < 25) || Slots().empty()) //add new stack
@@ -592,7 +592,7 @@ void CGTownInstance::newTurn(CRandomGenerator & rand) const
 						{
 							StackLocation sl(this, n);
 							if (slotEmpty(n))
-								cb->insertNewStack(sl, VLC->creh->objects[c], count);
+								cb->insertNewStack(sl, c.toCreature(), count);
 							else //add to existing
 								cb->changeStackCount(sl, count);
 						}

+ 2 - 2
lib/mapObjects/MiscObjects.cpp

@@ -33,7 +33,7 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-std::map <si32, std::vector<ObjectInstanceID> > CGMagi::eyelist;
+std::map <MapObjectSubID, std::vector<ObjectInstanceID> > CGMagi::eyelist;
 ui8 CGObelisk::obeliskCount = 0; //how many obelisks are on map
 std::map<TeamID, ui8> CGObelisk::visited; //map: team_id => how many obelisks has been visited
 
@@ -219,7 +219,7 @@ void CGMine::serializeJsonOptions(JsonSerializeFormat & handler)
 			for(const auto & resID : abandonedMineResources)
 			{
 				JsonNode one(JsonNode::JsonType::DATA_STRING);
-				one.String() = GameConstants::RESOURCE_NAMES[resID];
+				one.String() = GameConstants::RESOURCE_NAMES[resID.getNum()];
 				node.Vector().push_back(one);
 			}
 			handler.serializeRaw("possibleResources", node, std::nullopt);

+ 1 - 1
lib/mapObjects/MiscObjects.h

@@ -338,7 +338,7 @@ protected:
 class DLL_LINKAGE CGMagi : public CGObjectInstance
 {
 public:
-	static std::map <si32, std::vector<ObjectInstanceID> > eyelist; //[subID][id], supports multiple sets as in H5
+	static std::map <MapObjectSubID, std::vector<ObjectInstanceID> > eyelist; //[subID][id], supports multiple sets as in H5
 
 	static void reset();
 

+ 1 - 1
lib/mapping/MapFormatH3M.cpp

@@ -2095,7 +2095,7 @@ int CMapLoaderH3M::readQuest(IQuestObject * guard, const int3 & position)
 			guard->quest->mission.creatures.resize(typeNumber);
 			for(int hh = 0; hh < typeNumber; ++hh)
 			{
-				guard->quest->mission.creatures[hh].type = VLC->creh->objects[reader->readCreature()];
+				guard->quest->mission.creatures[hh].type = reader->readCreature().toCreature();
 				guard->quest->mission.creatures[hh].count = reader->readUInt16();
 			}
 			break;

+ 3 - 6
lib/mapping/MapFormatJson.cpp

@@ -528,13 +528,10 @@ void CMapFormatJson::serializePlayerInfo(JsonSerializeFormat & handler)
 						{
 							std::string temp;
 							if(hero->type)
-							{
 								temp = hero->type->getJsonKey();
-							}
 							else
-							{
-								temp = VLC->heroh->objects[hero->subID]->getJsonKey();
-							}
+								temp = hero->getHeroType().toEntity(VLC)->getJsonKey();
+
 							handler.serializeString("type", temp);
 						}
 					}
@@ -753,7 +750,7 @@ void CMapFormatJson::writeDisposedHeroes(JsonSerializeFormat & handler)
 
 	for(DisposedHero & hero : map->disposedHeroes)
 	{
-		std::string type = HeroTypeID::encode(hero.heroId);
+		std::string type = HeroTypeID::encode(hero.heroId.getNum());
 
 		auto definition = definitions->enterStruct(type);
 

+ 1 - 1
lib/rewardable/Interface.cpp

@@ -157,7 +157,7 @@ void Rewardable::Interface::grantRewardAfterLevelup(IGameCallback * cb, const Re
 	}
 
 	for(const ArtifactID & art : info.reward.artifacts)
-		cb->giveHeroNewArtifact(hero, VLC->arth->objects[art],ArtifactPosition::FIRST_AVAILABLE);
+		cb->giveHeroNewArtifact(hero, art.toArtifact(), ArtifactPosition::FIRST_AVAILABLE);
 
 	if(!info.reward.spells.empty())
 	{

+ 1 - 6
lib/rmg/CMapGenerator.cpp

@@ -98,12 +98,7 @@ const CMapGenOptions& CMapGenerator::getMapGenOptions() const
 
 void CMapGenerator::initPrisonsRemaining()
 {
-	allowedPrisons = 0;
-	for (auto isAllowed : map->getMap(this).allowedHeroes)
-	{
-		if (isAllowed)
-			allowedPrisons++;
-	}
+	allowedPrisons = map->getMap(this).allowedHeroes.size();
 	allowedPrisons = std::max<int> (0, allowedPrisons - 16 * mapGenOptions.getHumanOrCpuPlayerCount()); //so at least 16 heroes will be available for every player
 }
 

+ 3 - 3
lib/rmg/modificators/ObjectManager.cpp

@@ -638,14 +638,14 @@ CGCreature * ObjectManager::chooseGuard(si32 strength, bool zoneGuard)
 	if(!possibleCreatures.empty())
 	{
 		creId = *RandomGeneratorUtil::nextItem(possibleCreatures, zone.getRand());
-		amount = strength / VLC->creh->objects[creId]->getAIValue();
+		amount = strength / creId.toEntity(VLC)->getAIValue();
 		if (amount >= 4)
 			amount = static_cast<int>(amount * zone.getRand().nextDouble(0.75, 1.25));
 	}
 	else //just pick any available creature
 	{
-		creId = CreatureID(132); //Azure Dragon
-		amount = strength / VLC->creh->objects[creId]->getAIValue();
+		creId = CreatureID::AZURE_DRAGON; //Azure Dragon
+		amount = strength / creId.toEntity(VLC)->getAIValue();
 	}
 	
 	auto guardFactory = VLC->objtypeh->getHandlerFor(Obj::MONSTER, creId);

+ 1 - 1
lib/spells/AbilityCaster.cpp

@@ -28,7 +28,7 @@ AbilityCaster::AbilityCaster(const battle::Unit * actualCaster_, int32_t baseSpe
 
 AbilityCaster::~AbilityCaster() = default;
 
-int32_t AbilityCaster::getSpellSchoolLevel(const Spell * spell, int32_t * outSelectedSchool) const
+int32_t AbilityCaster::getSpellSchoolLevel(const Spell * spell, SpellSchool * outSelectedSchool) const
 {
 	auto skill = baseSpellLevel;
 	const auto * unit = dynamic_cast<const battle::Unit*>(actualCaster);

+ 1 - 1
lib/spells/AbilityCaster.h

@@ -23,7 +23,7 @@ public:
 	AbilityCaster(const battle::Unit * actualCaster_, int32_t baseSpellLevel_);
 	virtual ~AbilityCaster();
 
-	int32_t getSpellSchoolLevel(const Spell * spell, int32_t * outSelectedSchool = nullptr) const override;
+	int32_t getSpellSchoolLevel(const Spell * spell, SpellSchool * outSelectedSchool = nullptr) const override;
 	int32_t getEffectLevel(const Spell * spell) const override;
 	void getCastDescription(const Spell * spell, const std::vector<const battle::Unit *> & attacked, MetaString & text) const override;
 	void spendMana(ServerCallback * server, const int32_t spellCost) const override;

+ 1 - 1
lib/spells/CSpellHandler.cpp

@@ -154,7 +154,7 @@ void CSpell::forEachSchool(const std::function<void(const SpellSchool &, bool &)
 	bool stop = false;
 	for(auto iter : SpellConfig::SCHOOL_ORDER)
 	{
-		const spells::SchoolInfo & cnf = SpellConfig::SCHOOL[iter];
+		const spells::SchoolInfo & cnf = SpellConfig::SCHOOL[iter.getNum()];
 		if(school.at(cnf.id))
 		{
 			cb(cnf.id, stop);

+ 1 - 1
lib/spells/ExternalCaster.cpp

@@ -42,7 +42,7 @@ void ExternalCaster::spendMana(ServerCallback * server, const int32_t spellCost)
 	//do nothing
 }
 
-int32_t ExternalCaster::getSpellSchoolLevel(const Spell * spell, int32_t * outSelectedSchool) const
+int32_t ExternalCaster::getSpellSchoolLevel(const Spell * spell, SpellSchool * outSelectedSchool) const
 {
 	return schoolLevel;
 }

+ 3 - 1
lib/spells/ExternalCaster.h

@@ -14,6 +14,8 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+class SpellSchool;
+
 namespace spells
 {
 
@@ -27,7 +29,7 @@ public:
 	void setActualCaster(const Caster * actualCaster);
 	void setSpellSchoolLevel(int level);
 
-	int32_t getSpellSchoolLevel(const Spell * spell, int32_t * outSelectedSchool = nullptr) const override;
+	int32_t getSpellSchoolLevel(const Spell * spell, SpellSchool * outSelectedSchool = nullptr) const override;
 	void spendMana(ServerCallback * server, const int32_t spellCost) const override;
 };
 

+ 1 - 1
lib/spells/ObstacleCasterProxy.cpp

@@ -22,7 +22,7 @@ ObstacleCasterProxy::ObstacleCasterProxy(PlayerColor owner_, const Caster * hero
 {
 }
 
-int32_t ObstacleCasterProxy::getSpellSchoolLevel(const Spell * spell, int32_t * outSelectedSchool) const
+int32_t ObstacleCasterProxy::getSpellSchoolLevel(const Spell * spell, SpellSchool * outSelectedSchool) const
 {
 	return obs.spellLevel;
 }

+ 1 - 1
lib/spells/ObstacleCasterProxy.h

@@ -35,7 +35,7 @@ class DLL_LINKAGE ObstacleCasterProxy : public SilentCaster
 public:
 	ObstacleCasterProxy(PlayerColor owner_, const Caster * hero_, const SpellCreatedObstacle & obs_);
 
-	int32_t getSpellSchoolLevel(const Spell * spell, int32_t * outSelectedSchool = nullptr) const override;
+	int32_t getSpellSchoolLevel(const Spell * spell, SpellSchool * outSelectedSchool = nullptr) const override;
 	int32_t getEffectLevel(const Spell * spell) const override;
 	int64_t getSpellBonus(const Spell * spell, int64_t base, const battle::Unit * affectedStack) const override;
 	int32_t getEffectPower(const Spell * spell) const override;

+ 1 - 1
lib/spells/ProxyCaster.cpp

@@ -36,7 +36,7 @@ int32_t ProxyCaster::getCasterUnitId() const
 	return -1;
 }
 
-int32_t ProxyCaster::getSpellSchoolLevel(const Spell * spell, int32_t * outSelectedSchool) const
+int32_t ProxyCaster::getSpellSchoolLevel(const Spell * spell, SpellSchool * outSelectedSchool) const
 {
 	if(actualCaster)
 		return actualCaster->getSpellSchoolLevel(spell, outSelectedSchool);

+ 1 - 1
lib/spells/ProxyCaster.h

@@ -24,7 +24,7 @@ public:
 	virtual ~ProxyCaster();
 
 	int32_t getCasterUnitId() const override;
-	int32_t getSpellSchoolLevel(const Spell * spell, int32_t * outSelectedSchool = nullptr) const override;
+	int32_t getSpellSchoolLevel(const Spell * spell, SpellSchool * outSelectedSchool = nullptr) const override;
 	int32_t getEffectLevel(const Spell * spell) const override;
 	int64_t getSpellBonus(const Spell * spell, int64_t base, const battle::Unit * affectedStack) const override;
 	int64_t getSpecificSpellBonus(const Spell * spell, int64_t base) const override;