فهرست منبع

Merge pull request #1175 from SoundSSGood/refactoring-art

Refactoring of artifacts code
Andrii Danylchenko 2 سال پیش
والد
کامیت
ab365fdaef

+ 1 - 1
AI/Nullkiller/AIGateway.cpp

@@ -1140,7 +1140,7 @@ HeroPtr AIGateway::getHeroWithGrail() const
 {
 	for(const CGHeroInstance * h : cb->getHeroesInfo())
 	{
-		if(h->hasArt(2)) //grail
+		if(h->hasArt(ArtifactID::GRAIL))
 			return h;
 	}
 	return nullptr;

+ 1 - 1
AI/VCAI/VCAI.cpp

@@ -1755,7 +1755,7 @@ HeroPtr VCAI::getHeroWithGrail() const
 {
 	for(const CGHeroInstance * h : cb->getHeroesInfo())
 	{
-		if(h->hasArt(2)) //grail
+		if(h->hasArt(ArtifactID::GRAIL))
 			return h;
 	}
 	return nullptr;

+ 1 - 1
client/battle/CBattleInterface.cpp

@@ -914,7 +914,7 @@ void CBattleInterface::bSpellf()
 
 		if (blockingBonus->source == Bonus::ARTIFACT)
 		{
-			const int32_t artID = blockingBonus->sid;
+			const auto artID = ArtifactID(blockingBonus->sid);
 			//If we have artifact, put name of our hero. Otherwise assume it's the enemy.
 			//TODO check who *really* is source of bonus
 			std::string heroName = myHero->hasArt(artID) ? myHero->name : enemyHero().name;

+ 3 - 2
client/widgets/CComponent.cpp

@@ -155,10 +155,11 @@ std::string CComponent::getDescription()
 	case creature:   return "";
 	case artifact:
 	{
+		auto artID = ArtifactID(subtype);
 		std::unique_ptr<CArtifactInstance> art;
-		if (subtype != ArtifactID::SPELL_SCROLL)
+		if (artID != ArtifactID::SPELL_SCROLL)
 		{
-			art.reset(CArtifactInstance::createNewArtifactInstance(subtype));
+			art.reset(CArtifactInstance::createNewArtifactInstance(artID));
 		}
 		else
 		{

+ 1 - 1
client/windows/CCastleInterface.cpp

@@ -935,7 +935,7 @@ void CCastleBuildings::enterMagesGuild()
 
 void CCastleBuildings::enterTownHall()
 {
-	if(town->visitingHero && town->visitingHero->hasArt(2) &&
+	if(town->visitingHero && town->visitingHero->hasArt(ArtifactID::GRAIL) &&
 		!vstd::contains(town->builtBuildings, BuildingID::GRAIL)) //hero has grail, but town does not have it
 	{
 		if(!vstd::contains(town->forbiddenBuildings, BuildingID::GRAIL))

+ 55 - 28
lib/CArtHandler.cpp

@@ -851,7 +851,7 @@ void CArtifactInstance::putAt(ArtifactLocation al)
 	assert(canBePutAt(al));
 
 	al.getHolderArtSet()->setNewArtSlot(al.slot, this, false);
-	if(al.slot < GameConstants::BACKPACK_START)
+	if(!ArtifactUtils::isSlotBackpack(al.slot))
 		al.getHolderNode()->attachTo(*this);
 }
 
@@ -859,7 +859,7 @@ void CArtifactInstance::removeFrom(ArtifactLocation al)
 {
 	assert(al.getHolderArtSet()->getArt(al.slot) == this);
 	al.getHolderArtSet()->eraseArtSlot(al.slot);
-	if(al.slot < GameConstants::BACKPACK_START)
+	if(!ArtifactUtils::isSlotBackpack(al.slot))
 		al.getHolderNode()->detachFrom(*this);
 
 	//TODO delete me?
@@ -938,12 +938,12 @@ CArtifactInstance * CArtifactInstance::createNewArtifactInstance(CArtifact *Art)
 	}
 }
 
-CArtifactInstance * CArtifactInstance::createNewArtifactInstance(int aid)
+CArtifactInstance * CArtifactInstance::createNewArtifactInstance(ArtifactID aid)
 {
 	return createNewArtifactInstance(VLC->arth->objects[aid]);
 }
 
-CArtifactInstance * CArtifactInstance::createArtifact(CMap * map, int aid, int spellID)
+CArtifactInstance * CArtifactInstance::createArtifact(CMap * map, ArtifactID aid, int spellID)
 {
 	CArtifactInstance * a = nullptr;
 	if(aid >= 0)
@@ -1003,7 +1003,7 @@ bool CCombinedArtifactInstance::canBePutAt(const CArtifactSet *artSet, ArtifactP
 	bool canMainArtifactBePlaced = CArtifactInstance::canBePutAt(artSet, slot, assumeDestRemoved);
 	if(!canMainArtifactBePlaced)
 		return false; //no is no...
-	if(slot >= GameConstants::BACKPACK_START)
+	if(ArtifactUtils::isSlotBackpack(slot))
 		return true; //we can always remove combined art to the backapck
 
 
@@ -1019,11 +1019,12 @@ bool CCombinedArtifactInstance::canBePutAt(const CArtifactSet *artSet, ArtifactP
 	}
 
 	//we iterate over all active slots and check if constituents fits them
-	for (int i = 0; i < GameConstants::BACKPACK_START; i++)
+	for(const auto pos : ArtifactUtils::constituentWornSlots())
 	{
 		for(auto art = constituentsToBePlaced.begin(); art != constituentsToBePlaced.end(); art++)
 		{
-			if(art->art->canBePutAt(artSet, ArtifactPosition(i), i == slot)) // i == al.slot because we can remove already worn artifact only from that slot  that is our main destination
+			// pos == slot because we can remove already worn artifact only from that slot. That is our main destination
+			if(art->art->canBePutAt(artSet, pos, pos == slot))
 			{
 				constituentsToBePlaced.erase(art);
 				break;
@@ -1069,7 +1070,7 @@ void CCombinedArtifactInstance::addAsConstituent(CArtifactInstance *art, Artifac
 
 void CCombinedArtifactInstance::putAt(ArtifactLocation al)
 {
-	if(al.slot >= GameConstants::BACKPACK_START)
+	if(ArtifactUtils::isSlotBackpack(al.slot))
 	{
 		CArtifactInstance::putAt(al);
 		for(ConstituentInfo &ci : constituentsInfo)
@@ -1094,7 +1095,7 @@ void CCombinedArtifactInstance::putAt(ArtifactLocation al)
 				else
 					ci.slot = pos = ci.art->firstAvailableSlot(al.getHolderArtSet());
 
-				assert(pos < GameConstants::BACKPACK_START);
+				assert(!ArtifactUtils::isSlotBackpack(pos));
 				al.getHolderArtSet()->setNewArtSlot(pos, ci.art, true); //sets as lock
 			}
 			else
@@ -1107,7 +1108,7 @@ void CCombinedArtifactInstance::putAt(ArtifactLocation al)
 
 void CCombinedArtifactInstance::removeFrom(ArtifactLocation al)
 {
-	if(al.slot >= GameConstants::BACKPACK_START)
+	if(ArtifactUtils::isSlotBackpack(al.slot))
 	{
 		CArtifactInstance::removeFrom(al);
 	}
@@ -1199,19 +1200,19 @@ CArtifactInstance* CArtifactSet::getArt(ArtifactPosition pos, bool excludeLocked
 	return const_cast<CArtifactInstance*>((const_cast<const CArtifactSet*>(this))->getArt(pos, excludeLocked));
 }
 
-ArtifactPosition CArtifactSet::getArtPos(int aid, bool onlyWorn, bool allowLocked) const
+ArtifactPosition CArtifactSet::getArtPos(ArtifactID aid, bool onlyWorn, bool allowLocked) const
 {
 	const auto result = getAllArtPositions(aid, onlyWorn, allowLocked, false);
 	return result.empty() ? ArtifactPosition{ArtifactPosition::PRE_FIRST} : result[0];
 }
 
-ArtifactPosition CArtifactSet::getArtBackpackPos(int aid) const
+ArtifactPosition CArtifactSet::getArtBackpackPos(ArtifactID aid) const
 {
 	const auto result = getBackpackArtPositions(aid);
 	return result.empty() ? ArtifactPosition{ArtifactPosition::PRE_FIRST} : result[0];
 }
 
-std::vector<ArtifactPosition> CArtifactSet::getAllArtPositions(int aid, bool onlyWorn, bool allowLocked, bool getAll) const
+std::vector<ArtifactPosition> CArtifactSet::getAllArtPositions(ArtifactID aid, bool onlyWorn, bool allowLocked, bool getAll) const
 {
 	std::vector<ArtifactPosition> result;
 	for(auto & slotInfo : artifactsWorn)
@@ -1228,7 +1229,7 @@ std::vector<ArtifactPosition> CArtifactSet::getAllArtPositions(int aid, bool onl
 	return result;
 }
 
-std::vector<ArtifactPosition> CArtifactSet::getBackpackArtPositions(int aid) const
+std::vector<ArtifactPosition> CArtifactSet::getBackpackArtPositions(ArtifactID aid) const
 {
 	std::vector<ArtifactPosition> result;
 
@@ -1270,7 +1271,7 @@ const CArtifactInstance * CArtifactSet::getArtByInstanceId( ArtifactInstanceID a
 }
 
 bool CArtifactSet::hasArt(
-	ui32 aid,
+	ArtifactID aid,
 	bool onlyWorn,
     bool searchBackpackAssemblies,
 	bool allowLocked) const
@@ -1278,12 +1279,12 @@ bool CArtifactSet::hasArt(
 	return getArtPosCount(aid, onlyWorn, searchBackpackAssemblies, allowLocked) > 0;
 }
 
-bool CArtifactSet::hasArtBackpack(ui32 aid) const
+bool CArtifactSet::hasArtBackpack(ArtifactID aid) const
 {
 	return getBackpackArtPositions(aid).size() > 0;
 }
 
-unsigned CArtifactSet::getArtPosCount(int aid, bool onlyWorn, bool searchBackpackAssemblies, bool allowLocked) const
+unsigned CArtifactSet::getArtPosCount(ArtifactID aid, bool onlyWorn, bool searchBackpackAssemblies, bool allowLocked) const
 {
 	const auto allPositions = getAllArtPositions(aid, onlyWorn, allowLocked, true);
 	if(!allPositions.empty())
@@ -1296,7 +1297,7 @@ unsigned CArtifactSet::getArtPosCount(int aid, bool onlyWorn, bool searchBackpac
 }
 
 std::pair<const CCombinedArtifactInstance *, const CArtifactInstance *>
-CArtifactSet::searchForConstituent(int aid) const
+CArtifactSet::searchForConstituent(ArtifactID aid) const
 {
 	for(auto & slot : artifactsInBackpack)
 	{
@@ -1316,12 +1317,12 @@ CArtifactSet::searchForConstituent(int aid) const
 	return {nullptr, nullptr};
 }
 
-const CArtifactInstance *CArtifactSet::getHiddenArt(int aid) const
+const CArtifactInstance *CArtifactSet::getHiddenArt(ArtifactID aid) const
 {
 	return searchForConstituent(aid).second;
 }
 
-const CCombinedArtifactInstance *CArtifactSet::getAssemblyByConstituent(int aid) const
+const CCombinedArtifactInstance *CArtifactSet::getAssemblyByConstituent(ArtifactID aid) const
 {
 	return searchForConstituent(aid).first;
 }
@@ -1353,7 +1354,7 @@ bool CArtifactSet::isPositionFree(ArtifactPosition pos, bool onlyLockCheck) cons
 ArtSlotInfo & CArtifactSet::retrieveNewArtSlot(ArtifactPosition slot)
 {
 	assert(!vstd::contains(artifactsWorn, slot));
-	ArtSlotInfo &ret = slot < GameConstants::BACKPACK_START
+	ArtSlotInfo &ret = !ArtifactUtils::isSlotBackpack(slot)
 		? artifactsWorn[slot]
 		: *artifactsInBackpack.insert(artifactsInBackpack.begin() + (slot - GameConstants::BACKPACK_START), ArtSlotInfo());
 
@@ -1369,14 +1370,15 @@ void CArtifactSet::setNewArtSlot(ArtifactPosition slot, CArtifactInstance *art,
 
 void CArtifactSet::eraseArtSlot(ArtifactPosition slot)
 {
-	if(slot < GameConstants::BACKPACK_START)
+	if(ArtifactUtils::isSlotBackpack(slot))
 	{
-		artifactsWorn.erase(slot);
+		assert(artifactsInBackpack.begin() + slot < artifactsInBackpack.end());
+		slot = ArtifactPosition(slot - GameConstants::BACKPACK_START);
+		artifactsInBackpack.erase(artifactsInBackpack.begin() + slot);
 	}
 	else
 	{
-		slot = ArtifactPosition(slot - GameConstants::BACKPACK_START);
-		artifactsInBackpack.erase(artifactsInBackpack.begin() + slot);
+		artifactsWorn.erase(slot);
 	}
 }
 
@@ -1543,16 +1545,41 @@ DLL_LINKAGE ArtifactPosition ArtifactUtils::getArtifactDstPosition(	const CArtif
 	return ArtifactPosition(GameConstants::BACKPACK_START);
 }
 
-DLL_LINKAGE std::vector<ArtifactPosition> ArtifactUtils::unmovablePositions()
+DLL_LINKAGE const std::vector<ArtifactPosition::EArtifactPosition> & ArtifactUtils::unmovableSlots()
 {
-	return { ArtifactPosition::SPELLBOOK, ArtifactPosition::MACH4 };
+	return
+	{
+		ArtifactPosition::SPELLBOOK,
+		ArtifactPosition::MACH4
+	};
+}
+
+DLL_LINKAGE const std::vector<ArtifactPosition::EArtifactPosition> & ArtifactUtils::constituentWornSlots()
+{
+	return
+	{
+		ArtifactPosition::HEAD,
+		ArtifactPosition::SHOULDERS,
+		ArtifactPosition::NECK,
+		ArtifactPosition::RIGHT_HAND,
+		ArtifactPosition::LEFT_HAND,
+		ArtifactPosition::TORSO,
+		ArtifactPosition::RIGHT_RING,
+		ArtifactPosition::LEFT_RING,
+		ArtifactPosition::FEET,
+		ArtifactPosition::MISC1,
+		ArtifactPosition::MISC2,
+		ArtifactPosition::MISC3,
+		ArtifactPosition::MISC4,
+		ArtifactPosition::MISC5,
+	};
 }
 
 DLL_LINKAGE bool ArtifactUtils::isArtRemovable(const std::pair<ArtifactPosition, ArtSlotInfo> & slot)
 {
 	return slot.second.artifact
 		&& !slot.second.locked
-		&& !vstd::contains(unmovablePositions(), slot.first);
+		&& !vstd::contains(unmovableSlots(), slot.first);
 }
 
 DLL_LINKAGE bool ArtifactUtils::checkSpellbookIsNeeded(const CGHeroInstance * heroPtr, ArtifactID artID, ArtifactPosition slot)

+ 15 - 13
lib/CArtHandler.h

@@ -176,7 +176,7 @@ public:
 
 	static CArtifactInstance *createScroll(SpellID sid);
 	static CArtifactInstance *createNewArtifactInstance(CArtifact *Art);
-	static CArtifactInstance *createNewArtifactInstance(int aid);
+	static CArtifactInstance *createNewArtifactInstance(ArtifactID aid);
 
 	/**
 	 * Creates an artifact instance.
@@ -185,7 +185,7 @@ public:
 	 * @param spellID optional. the id of a spell if a spell scroll object should be created
 	 * @return the created artifact instance
 	 */
-	static CArtifactInstance * createArtifact(CMap * map, int aid, int spellID = -1);
+	static CArtifactInstance * createArtifact(CMap * map, ArtifactID aid, int spellID = -1);
 };
 
 class DLL_LINKAGE CCombinedArtifactInstance : public CArtifactInstance
@@ -327,20 +327,20 @@ public:
 	CArtifactInstance* getArt(ArtifactPosition pos, bool excludeLocked = true); //nullptr - no artifact
 	/// Looks for equipped artifact with given ID and returns its slot ID or -1 if none
 	/// (if more than one such artifact lower ID is returned)
-	ArtifactPosition getArtPos(int aid, bool onlyWorn = true, bool allowLocked = true) const;
+	ArtifactPosition getArtPos(ArtifactID aid, bool onlyWorn = true, bool allowLocked = true) const;
 	ArtifactPosition getArtPos(const CArtifactInstance *art) const;
-	ArtifactPosition getArtBackpackPos(int aid) const;
-	std::vector<ArtifactPosition> getAllArtPositions(int aid, bool onlyWorn, bool allowLocked, bool getAll) const;
-	std::vector<ArtifactPosition> getBackpackArtPositions(int aid) const;
+	ArtifactPosition getArtBackpackPos(ArtifactID aid) const;
+	std::vector<ArtifactPosition> getAllArtPositions(ArtifactID aid, bool onlyWorn, bool allowLocked, bool getAll) const;
+	std::vector<ArtifactPosition> getBackpackArtPositions(ArtifactID aid) const;
 	const CArtifactInstance *getArtByInstanceId(ArtifactInstanceID artInstId) const;
 	/// Search for constituents of assemblies in backpack which do not have an ArtifactPosition
-	const CArtifactInstance *getHiddenArt(int aid) const;
-	const CCombinedArtifactInstance *getAssemblyByConstituent(int aid) const;
+	const CArtifactInstance *getHiddenArt(ArtifactID aid) const;
+	const CCombinedArtifactInstance *getAssemblyByConstituent(ArtifactID aid) const;
 	/// Checks if hero possess artifact of given id (either in backack or worn)
-	bool hasArt(ui32 aid, bool onlyWorn = false, bool searchBackpackAssemblies = false, bool allowLocked = true) const;
-	bool hasArtBackpack(ui32 aid) const;
+	bool hasArt(ArtifactID aid, bool onlyWorn = false, bool searchBackpackAssemblies = false, bool allowLocked = true) const;
+	bool hasArtBackpack(ArtifactID aid) const;
 	bool isPositionFree(ArtifactPosition pos, bool onlyLockCheck = false) const;
-	unsigned getArtPosCount(int aid, bool onlyWorn = true, bool searchBackpackAssemblies = true, bool allowLocked = true) const;
+	unsigned getArtPosCount(ArtifactID aid, bool onlyWorn = true, bool searchBackpackAssemblies = true, bool allowLocked = true) const;
 
 	virtual ArtBearer::ArtBearer bearerType() const = 0;
 	virtual void putArtifact(ArtifactPosition pos, CArtifactInstance * art) = 0;
@@ -358,7 +358,7 @@ public:
 protected:
 
 
-	std::pair<const CCombinedArtifactInstance *, const CArtifactInstance *> searchForConstituent(int aid) const;
+	std::pair<const CCombinedArtifactInstance *, const CArtifactInstance *> searchForConstituent(ArtifactID aid) const;
 private:
 	void serializeJsonHero(JsonSerializeFormat & handler, CMap * map);
 	void serializeJsonCreature(JsonSerializeFormat & handler, CMap * map);
@@ -386,7 +386,9 @@ namespace ArtifactUtils
 	DLL_LINKAGE ArtifactPosition getArtifactDstPosition(	const CArtifactInstance * artifact, 
 								const CArtifactSet * target,
 								ArtBearer::ArtBearer bearer);
-	DLL_LINKAGE std::vector<ArtifactPosition> unmovablePositions(); // TODO: Make this constexpr when the toolset is upgraded
+	// 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 bool isArtRemovable(const std::pair<ArtifactPosition, ArtSlotInfo> & slot);
 	DLL_LINKAGE bool checkSpellbookIsNeeded(const CGHeroInstance * heroPtr, ArtifactID artID, ArtifactPosition slot);
 	DLL_LINKAGE bool isSlotBackpack(ArtifactPosition slot);

+ 3 - 3
lib/CGameState.cpp

@@ -2256,7 +2256,7 @@ bool CGameState::checkForVictory(PlayerColor player, const EventCondition & cond
 		case EventCondition::HAVE_ARTIFACT: //check if any hero has winning artifact
 		{
 			for(auto & elem : p->heroes)
-				if(elem->hasArt(condition.objectType))
+				if(elem->hasArt(ArtifactID(condition.objectType)))
 					return true;
 			return false;
 		}
@@ -2342,8 +2342,8 @@ bool CGameState::checkForVictory(PlayerColor player, const EventCondition & cond
 		case EventCondition::TRANSPORT:
 		{
 			const CGTownInstance *t = static_cast<const CGTownInstance *>(condition.object);
-			if((t->visitingHero && t->visitingHero->hasArt(condition.objectType))
-				|| (t->garrisonHero && t->garrisonHero->hasArt(condition.objectType)))
+			if((t->visitingHero && t->visitingHero->hasArt(ArtifactID(condition.objectType)))
+				|| (t->garrisonHero && t->garrisonHero->hasArt(ArtifactID(condition.objectType))))
 			{
 				return true;
 			}

+ 8 - 0
lib/GameConstants.h

@@ -1054,6 +1054,14 @@ public:
 	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)

+ 2 - 2
lib/mapObjects/CQuest.cpp

@@ -422,7 +422,7 @@ void CQuest::getCompletionText(MetaString &iwText, std::vector<Component> &compo
 	}
 }
 
-void CQuest::addArtifactID(ui16 id)
+void CQuest::addArtifactID(ArtifactID id)
 {
 	m5arts.push_back(id);
 	++artifactsRequirements[id];
@@ -474,7 +474,7 @@ void CQuest::serializeJson(JsonSerializeFormat & handler, const std::string & fi
 		break;
 	case MISSION_ART:
 		//todo: ban artifacts
-		handler.serializeIdArray<ui16, ArtifactID>("artifacts", m5arts);
+		handler.serializeIdArray<ArtifactID>("artifacts", m5arts);
 		break;
 	case MISSION_ARMY:
         {

+ 3 - 3
lib/mapObjects/CQuest.h

@@ -21,7 +21,7 @@ class CGCreature;
 
 class DLL_LINKAGE CQuest final
 {
-	mutable std::unordered_map<ui16, unsigned> artifactsRequirements; // artifact ID -> required count
+	mutable std::unordered_map<ArtifactID, unsigned, ArtifactID::hash> artifactsRequirements; // artifact ID -> required count
 
 public:
 	enum Emission {MISSION_NONE = 0, MISSION_LEVEL = 1, MISSION_PRIMARY_STAT = 2, MISSION_KILL_HERO = 3, MISSION_KILL_CREATURE = 4,
@@ -36,7 +36,7 @@ public:
 
 	ui32 m13489val;
 	std::vector<ui32> m2stats;
-	std::vector<ui16> m5arts; // artifact IDs. Add IDs through addArtifactID(), not directly to the field.
+	std::vector<ArtifactID> m5arts; // artifact IDs. Add IDs through addArtifactID(), not directly to the field.
 	std::vector<CStackBasicDescriptor> m6creatures; //pair[cre id, cre count], CreatureSet info irrelevant
 	std::vector<ui32> m7resources; //TODO: use resourceset?
 
@@ -62,7 +62,7 @@ public:
 	virtual void getRolloverText (MetaString &text, bool onHover) const; //hover or quest log entry
 	virtual void completeQuest (const CGHeroInstance * h) const {};
 	virtual void addReplacements(MetaString &out, const std::string &base) const;
-	void addArtifactID(ui16 id);
+	void addArtifactID(ArtifactID id);
 
 	bool operator== (const CQuest & quest) const
 	{

+ 7 - 7
lib/mapping/MapFormatH3M.cpp

@@ -870,15 +870,15 @@ void CMapLoaderH3M::loadArtifactsOfHero(CGHeroInstance * hero)
 bool CMapLoaderH3M::loadArtifactToSlot(CGHeroInstance * hero, int slot)
 {
 	const int artmask = map->version == EMapFormat::ROE ? 0xff : 0xffff;
-	int aid;
+	ArtifactID aid;
 
 	if(map->version == EMapFormat::ROE)
 	{
-		aid = reader.readUInt8();
+		aid = ArtifactID(reader.readUInt8());
 	}
 	else
 	{
-		aid = reader.readUInt16();
+		aid = ArtifactID(reader.readUInt16());
 	}
 
 	bool isArt  =  aid != artmask;
@@ -1207,7 +1207,7 @@ void CMapLoaderH3M::readObjects()
 		case Obj::RANDOM_RELIC_ART:
 		case Obj::SPELL_SCROLL:
 			{
-				int artID = ArtifactID::NONE; //random, set later
+				auto artID = ArtifactID::NONE; //random, set later
 				int spellID = -1;
 				auto  art = new CGArtifact();
 				nobj = art;
@@ -1222,7 +1222,7 @@ void CMapLoaderH3M::readObjects()
 				else if(objTempl->id == Obj::ARTIFACT)
 				{
 					//specific artifact
-					artID = objTempl->subid;
+					artID = ArtifactID(objTempl->subid);
 				}
 
 				art->storedArtifact = CArtifactInstance::createArtifact(map, artID, spellID);
@@ -1754,7 +1754,7 @@ CGSeerHut * CMapLoaderH3M::readSeerHut()
 	else
 	{
 		//RoE
-		int artID = reader.readUInt8();
+		auto artID = ArtifactID(reader.readUInt8());
 		if (artID != 255)
 		{
 			//not none quest
@@ -1886,7 +1886,7 @@ void CMapLoaderH3M::readQuest(IQuestObject * guard)
 			int artNumber = reader.readUInt8();
 			for(int yy = 0; yy < artNumber; ++yy)
 			{
-				int artid = reader.readUInt16();
+				auto artid = ArtifactID(reader.readUInt16());
 				guard->quest->addArtifactID(artid);
 				map->allowedArtifact[artid] = false; //these are unavailable for random generation
 			}

+ 2 - 2
lib/mapping/MapFormatJson.cpp

@@ -1152,7 +1152,7 @@ void CMapLoaderJson::MapObjectLoader::configure()
 
 	if(auto art = dynamic_cast<CGArtifact *>(instance))
 	{
-		int artID = ArtifactID::NONE;
+		auto artID = ArtifactID::NONE;
 		int spellID = -1;
 
 		if(art->ID == Obj::SPELL_SCROLL)
@@ -1168,7 +1168,7 @@ void CMapLoaderJson::MapObjectLoader::configure()
 		else if(art->ID  == Obj::ARTIFACT)
 		{
 			//specific artifact
-			artID = art->subID;
+			artID = ArtifactID(art->subID);
 		}
 
 		art->storedArtifact = CArtifactInstance::createArtifact(owner->map, artID, spellID);

+ 1 - 1
mapeditor/inspector/questwidget.cpp

@@ -134,7 +134,7 @@ QString QuestWidget::commitChanges()
 			return QString("N/A");
 		case CQuest::Emission::MISSION_ART:
 			seerhut.quest->m5arts.clear();
-			seerhut.quest->m5arts.push_back(ui->targetId->currentIndex());
+			seerhut.quest->m5arts.push_back(ArtifactID(ui->targetId->currentIndex()));
 			//TODO: support multiple artifacts
 			return ui->targetId->currentText();
 		case CQuest::Emission::MISSION_ARMY: