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
CCombinedArtifactInstance::PartInfo::PartInfo(IGameCallback * cb)
:GameCallbackHolder(cb)
{}
CCombinedArtifactInstance::PartInfo::PartInfo(const CArtifactInstance * artifact, ArtifactPosition slot)
: GameCallbackHolder(artifact->cb)
, artifactID(artifact->getId())
: artifactID(artifact->getId())
, artifactPtr(artifact)
, slot(slot)
{
}
const CArtifactInstance * CCombinedArtifactInstance::PartInfo::getArtifact() const
{
if (artifactID.hasValue())
return cb->getArtInstance(artifactID);
return nullptr;
assert(artifactPtr != nullptr || !artifactID.hasValue());
return artifactPtr;
}
ArtifactInstanceID CCombinedArtifactInstance::PartInfo::getArtifactID() const
{
return artifactID;
}
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)
{
if(constituent.artifactID == supposedPart->getId())
if(constituent.getArtifactID() == supposedPart->getId())
return true;
}
@@ -186,7 +186,10 @@ bool CArtifactInstance::isScroll() const
void CArtifactInstance::attachToBonusSystem(CGameState & gs)
{
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)

View File

@@ -22,18 +22,24 @@ class DLL_LINKAGE CCombinedArtifactInstance : public GameCallbackHolder
{
protected:
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);
ArtifactInstanceID artifactID;
ArtifactPosition slot;
const CArtifactInstance * getArtifact() const;
ArtifactInstanceID getArtifactID() const;
template <typename Handler>
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;
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
}

View File

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

View File

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