1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-23 22:37:55 +02:00

Fix crash on loading map with heroes that have combined art equipped

This commit is contained in:
Ivan Savenko
2025-05-07 18:05:30 +03:00
parent 92c4bcbf68
commit 69de14a42f
5 changed files with 27 additions and 21 deletions

View File

@@ -19,22 +19,22 @@
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
CCombinedArtifactInstance::PartInfo::PartInfo(IGameCallback * cb)
:GameCallbackHolder(cb)
{}
CCombinedArtifactInstance::PartInfo::PartInfo(const CArtifactInstance * artifact, ArtifactPosition slot) CCombinedArtifactInstance::PartInfo::PartInfo(const CArtifactInstance * artifact, ArtifactPosition slot)
: GameCallbackHolder(artifact->cb) : artifactID(artifact->getId())
, artifactID(artifact->getId()) , artifactPtr(artifact)
, slot(slot) , slot(slot)
{ {
} }
const CArtifactInstance * CCombinedArtifactInstance::PartInfo::getArtifact() const const CArtifactInstance * CCombinedArtifactInstance::PartInfo::getArtifact() const
{ {
if (artifactID.hasValue()) assert(artifactPtr != nullptr || !artifactID.hasValue());
return cb->getArtInstance(artifactID); return artifactPtr;
return nullptr; }
ArtifactInstanceID CCombinedArtifactInstance::PartInfo::getArtifactID() const
{
return artifactID;
} }
void CCombinedArtifactInstance::addPart(const CArtifactInstance * art, const ArtifactPosition & slot) void CCombinedArtifactInstance::addPart(const CArtifactInstance * art, const ArtifactPosition & slot)
@@ -57,7 +57,7 @@ bool CCombinedArtifactInstance::isPart(const CArtifactInstance * supposedPart) c
for(const PartInfo & constituent : partsInfo) for(const PartInfo & constituent : partsInfo)
{ {
if(constituent.artifactID == supposedPart->getId()) if(constituent.getArtifactID() == supposedPart->getId())
return true; return true;
} }
@@ -186,7 +186,10 @@ bool CArtifactInstance::isScroll() const
void CArtifactInstance::attachToBonusSystem(CGameState & gs) void CArtifactInstance::attachToBonusSystem(CGameState & gs)
{ {
for(PartInfo & part : partsInfo) for(PartInfo & part : partsInfo)
attachToSource(*gs.getArtInstance(part.artifactID)); {
part = PartInfo(gs.getArtInstance(part.getArtifactID()), part.slot);
attachToSource(*gs.getArtInstance(part.getArtifactID()));
}
} }
void CArtifactInstance::saveCompatibilityFixArtifactID(std::shared_ptr<CArtifactInstance> self) void CArtifactInstance::saveCompatibilityFixArtifactID(std::shared_ptr<CArtifactInstance> self)

View File

@@ -22,18 +22,24 @@ class DLL_LINKAGE CCombinedArtifactInstance : public GameCallbackHolder
{ {
protected: protected:
using GameCallbackHolder::GameCallbackHolder; using GameCallbackHolder::GameCallbackHolder;
public:
using ArtPlacementMap = std::map<const CArtifactInstance*, ArtifactPosition>;
struct PartInfo : public GameCallbackHolder public:
using ArtPlacementMap = std::map<const CArtifactInstance *, ArtifactPosition>;
struct PartInfo
{ {
explicit PartInfo(IGameCallback * cb); private:
const CArtifactInstance * artifactPtr = nullptr;
ArtifactInstanceID artifactID;
public:
PartInfo() = default;
PartInfo(const CArtifactInstance * artifact, ArtifactPosition slot); PartInfo(const CArtifactInstance * artifact, ArtifactPosition slot);
ArtifactInstanceID artifactID;
ArtifactPosition slot; ArtifactPosition slot;
const CArtifactInstance * getArtifact() const; const CArtifactInstance * getArtifact() const;
ArtifactInstanceID getArtifactID() const;
template <typename Handler> template <typename Handler>
void serialize(Handler & h); void serialize(Handler & h);

View File

@@ -281,7 +281,7 @@ bool CArtifactSet::isPositionFree(const ArtifactPosition & pos, bool onlyLockChe
return artifactsInBackpack.size() < GameConstants::ALTAR_ARTIFACTS_SLOTS; return artifactsInBackpack.size() < GameConstants::ALTAR_ARTIFACTS_SLOTS;
if(const ArtSlotInfo *s = getSlot(pos)) if(const ArtSlotInfo *s = getSlot(pos))
return (onlyLockCheck || !s->getArt()) && !s->locked; return (onlyLockCheck || !s->getID().hasValue()) && !s->locked;
return true; //no slot means not used return true; //no slot means not used
} }

View File

@@ -1569,9 +1569,6 @@ void CGameState::buildBonusSystemTree()
buildGlobalTeamPlayerTree(); buildGlobalTeamPlayerTree();
for(auto & armed : map->getObjects<CArmedInstance>()) for(auto & armed : map->getObjects<CArmedInstance>())
armed->attachToBonusSystem(*this); armed->attachToBonusSystem(*this);
for(auto & art : map->getArtifacts())
art->attachToBonusSystem(*this);
} }
void CGameState::restoreBonusSystemTree() void CGameState::restoreBonusSystemTree()

View File

@@ -873,7 +873,7 @@ const std::vector<ObjectInstanceID> & CMap::getHeroesOnMap()
void CMap::addToHeroPool(std::shared_ptr<CGHeroInstance> hero) void CMap::addToHeroPool(std::shared_ptr<CGHeroInstance> hero)
{ {
assert(hero->getHeroTypeID().isValid()); assert(hero->getHeroTypeID().isValid());
assert(!vstd::contains(heroesOnMap, hero->getHeroTypeID())); assert(!vstd::contains(heroesOnMap, hero->id));
assert(heroesPool.at(hero->getHeroTypeID().getNum()) == nullptr); assert(heroesPool.at(hero->getHeroTypeID().getNum()) == nullptr);
heroesPool.at(hero->getHeroTypeID().getNum()) = hero; heroesPool.at(hero->getHeroTypeID().getNum()) = hero;