diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index 92be1822a..f587ae03a 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/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; diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index 7f42b8d70..6bbb91658 100644 --- a/AI/VCAI/VCAI.cpp +++ b/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; diff --git a/client/battle/CBattleInterface.cpp b/client/battle/CBattleInterface.cpp index 478bd4eba..a0aa4a219 100644 --- a/client/battle/CBattleInterface.cpp +++ b/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; diff --git a/client/widgets/CComponent.cpp b/client/widgets/CComponent.cpp index 48b7af3b4..15026dde4 100644 --- a/client/widgets/CComponent.cpp +++ b/client/widgets/CComponent.cpp @@ -155,10 +155,11 @@ std::string CComponent::getDescription() case creature: return ""; case artifact: { + auto artID = ArtifactID(subtype); std::unique_ptr art; - if (subtype != ArtifactID::SPELL_SCROLL) + if (artID != ArtifactID::SPELL_SCROLL) { - art.reset(CArtifactInstance::createNewArtifactInstance(subtype)); + art.reset(CArtifactInstance::createNewArtifactInstance(artID)); } else { diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index a656dad68..97a9487db 100644 --- a/client/windows/CCastleInterface.cpp +++ b/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)) diff --git a/lib/CArtHandler.cpp b/lib/CArtHandler.cpp index f8b3a8584..a01264a2b 100644 --- a/lib/CArtHandler.cpp +++ b/lib/CArtHandler.cpp @@ -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) @@ -1199,19 +1199,19 @@ CArtifactInstance* CArtifactSet::getArt(ArtifactPosition pos, bool excludeLocked return const_cast((const_cast(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 CArtifactSet::getAllArtPositions(int aid, bool onlyWorn, bool allowLocked, bool getAll) const +std::vector CArtifactSet::getAllArtPositions(ArtifactID aid, bool onlyWorn, bool allowLocked, bool getAll) const { std::vector result; for(auto & slotInfo : artifactsWorn) @@ -1228,7 +1228,7 @@ std::vector CArtifactSet::getAllArtPositions(int aid, bool onl return result; } -std::vector CArtifactSet::getBackpackArtPositions(int aid) const +std::vector CArtifactSet::getBackpackArtPositions(ArtifactID aid) const { std::vector result; @@ -1270,7 +1270,7 @@ const CArtifactInstance * CArtifactSet::getArtByInstanceId( ArtifactInstanceID a } bool CArtifactSet::hasArt( - ui32 aid, + ArtifactID aid, bool onlyWorn, bool searchBackpackAssemblies, bool allowLocked) const @@ -1278,12 +1278,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 +1296,7 @@ unsigned CArtifactSet::getArtPosCount(int aid, bool onlyWorn, bool searchBackpac } std::pair -CArtifactSet::searchForConstituent(int aid) const +CArtifactSet::searchForConstituent(ArtifactID aid) const { for(auto & slot : artifactsInBackpack) { @@ -1316,12 +1316,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; } diff --git a/lib/CArtHandler.h b/lib/CArtHandler.h index 978a00bbc..347477265 100644 --- a/lib/CArtHandler.h +++ b/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 getAllArtPositions(int aid, bool onlyWorn, bool allowLocked, bool getAll) const; - std::vector getBackpackArtPositions(int aid) const; + ArtifactPosition getArtBackpackPos(ArtifactID aid) const; + std::vector getAllArtPositions(ArtifactID aid, bool onlyWorn, bool allowLocked, bool getAll) const; + std::vector 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 searchForConstituent(int aid) const; + std::pair searchForConstituent(ArtifactID aid) const; private: void serializeJsonHero(JsonSerializeFormat & handler, CMap * map); void serializeJsonCreature(JsonSerializeFormat & handler, CMap * map); diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index a07bbd43e..6d318de54 100644 --- a/lib/CGameState.cpp +++ b/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(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; } diff --git a/lib/mapObjects/CQuest.cpp b/lib/mapObjects/CQuest.cpp index a63ff4eca..05c07379b 100644 --- a/lib/mapObjects/CQuest.cpp +++ b/lib/mapObjects/CQuest.cpp @@ -422,7 +422,7 @@ void CQuest::getCompletionText(MetaString &iwText, std::vector &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("artifacts", m5arts); + handler.serializeIdArray("artifacts", m5arts); break; case MISSION_ARMY: { diff --git a/lib/mapObjects/CQuest.h b/lib/mapObjects/CQuest.h index a8fe68b32..bc98c7dad 100644 --- a/lib/mapObjects/CQuest.h +++ b/lib/mapObjects/CQuest.h @@ -19,9 +19,18 @@ VCMI_LIB_NAMESPACE_BEGIN class CGCreature; +// Used in std::unordered_map +template<> struct std::hash +{ + std::size_t operator()(const ArtifactID & aid) const + { + return std::hash{}(aid.num); + } +}; + class DLL_LINKAGE CQuest final { - mutable std::unordered_map artifactsRequirements; // artifact ID -> required count + mutable std::unordered_map 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 +45,7 @@ public: ui32 m13489val; std::vector m2stats; - std::vector m5arts; // artifact IDs. Add IDs through addArtifactID(), not directly to the field. + std::vector m5arts; // artifact IDs. Add IDs through addArtifactID(), not directly to the field. std::vector m6creatures; //pair[cre id, cre count], CreatureSet info irrelevant std::vector m7resources; //TODO: use resourceset? @@ -62,7 +71,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 { diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp index 5ca1087d6..f8a0c6c7d 100644 --- a/lib/mapping/MapFormatH3M.cpp +++ b/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 } diff --git a/lib/mapping/MapFormatJson.cpp b/lib/mapping/MapFormatJson.cpp index 4e26cdfe9..ff6f3c507 100644 --- a/lib/mapping/MapFormatJson.cpp +++ b/lib/mapping/MapFormatJson.cpp @@ -1152,7 +1152,7 @@ void CMapLoaderJson::MapObjectLoader::configure() if(auto art = dynamic_cast(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);