1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

putArtifact, removeArtifact

This commit is contained in:
SoundSSGood
2023-05-17 17:01:22 +03:00
parent 021f94a579
commit f0feeeac6e
3 changed files with 58 additions and 124 deletions

View File

@@ -858,7 +858,7 @@ void CArtifactInstance::putAt(ArtifactLocation al)
{ {
assert(canBePutAt(al)); assert(canBePutAt(al));
al.getHolderArtSet()->setNewArtSlot(al.slot, this, false); al.getHolderArtSet()->CArtifactSet::putArtifact(al.slot, this);
if(ArtifactUtils::isSlotEquipment(al.slot)) if(ArtifactUtils::isSlotEquipment(al.slot))
al.getHolderNode()->attachTo(*this); al.getHolderNode()->attachTo(*this);
} }
@@ -866,7 +866,8 @@ void CArtifactInstance::putAt(ArtifactLocation al)
void CArtifactInstance::removeFrom(ArtifactLocation al) void CArtifactInstance::removeFrom(ArtifactLocation al)
{ {
assert(al.getHolderArtSet()->getArt(al.slot) == this); assert(al.getHolderArtSet()->getArt(al.slot) == this);
al.getHolderArtSet()->eraseArtSlot(al.slot);
al.getHolderArtSet()->removeArtifact(al.slot);
if(ArtifactUtils::isSlotEquipment(al.slot)) if(ArtifactUtils::isSlotEquipment(al.slot))
al.getHolderNode()->detachFrom(*this); al.getHolderNode()->detachFrom(*this);
} }
@@ -929,88 +930,14 @@ void CCombinedArtifactInstance::addAsConstituent(CArtifactInstance * art, const
attachTo(*art); attachTo(*art);
} }
void CCombinedArtifactInstance::putAt(ArtifactLocation al)
{
if(al.slot == ArtifactPosition::TRANSITION_POS)
{
CArtifactInstance::putAt(al);
}
else if(ArtifactUtils::isSlotBackpack(al.slot))
{
CArtifactInstance::putAt(al);
for(ConstituentInfo &ci : constituentsInfo)
ci.slot = ArtifactPosition::PRE_FIRST;
}
else
{
CArtifactInstance *mainConstituent = figureMainConstituent(al); //it'll be replaced with combined artifact, not a lock
CArtifactInstance::putAt(al); //puts combined art (this)
for(ConstituentInfo & ci : constituentsInfo)
{
if(ci.art != mainConstituent)
{
const ArtifactLocation suggestedPos(al.artHolder, ci.slot);
const bool inActiveSlot = vstd::isbetween(ci.slot, 0, GameConstants::BACKPACK_START);
const bool suggestedPosValid = ci.art->canBePutAt(suggestedPos);
if(!(inActiveSlot && suggestedPosValid)) //there is a valid suggestion where to place lock
ci.slot = ArtifactUtils::getArtAnyPosition(al.getHolderArtSet(), ci.art->getTypeId());
assert(ArtifactUtils::isSlotEquipment(ci.slot));
al.getHolderArtSet()->setNewArtSlot(ci.slot, ci.art, true); //sets as lock
}
else
{
ci.slot = ArtifactPosition::PRE_FIRST;
}
}
}
}
void CCombinedArtifactInstance::removeFrom(ArtifactLocation al) void CCombinedArtifactInstance::removeFrom(ArtifactLocation al)
{ {
if(ArtifactUtils::isSlotBackpack(al.slot) || al.slot == ArtifactPosition::TRANSITION_POS)
{
CArtifactInstance::removeFrom(al); CArtifactInstance::removeFrom(al);
} for(auto & part : constituentsInfo)
else
{ {
for(ConstituentInfo &ci : constituentsInfo) if(part.slot != ArtifactPosition::PRE_FIRST)
{ part.slot = ArtifactPosition::PRE_FIRST;
if(ci.slot >= 0)
{
al.getHolderArtSet()->eraseArtSlot(ci.slot);
ci.slot = ArtifactPosition::PRE_FIRST;
} }
else
{
//main constituent
CArtifactInstance::removeFrom(al);
}
}
}
}
CArtifactInstance * CCombinedArtifactInstance::figureMainConstituent(const ArtifactLocation & al)
{
CArtifactInstance *mainConstituent = nullptr; //it'll be replaced with combined artifact, not a lock
for(ConstituentInfo &ci : constituentsInfo)
if(ci.slot == al.slot)
mainConstituent = ci.art;
if(!mainConstituent)
{
for(ConstituentInfo &ci : constituentsInfo)
{
if(vstd::contains(ci.art->artType->possibleSlots[al.getHolderArtSet()->bearerType()], al.slot))
{
mainConstituent = ci.art;
}
}
}
return mainConstituent;
} }
void CCombinedArtifactInstance::deserializationFix() void CCombinedArtifactInstance::deserializationFix()
@@ -1173,6 +1100,52 @@ unsigned CArtifactSet::getArtPosCount(const ArtifactID & aid, bool onlyWorn, boo
return 0; return 0;
} }
void CArtifactSet::putArtifact(ArtifactPosition slot, CArtifactInstance * art)
{
setNewArtSlot(slot, art, false);
if(art->artType->canBeDisassembled() && ArtifactUtils::isSlotEquipment(slot))
{
const CArtifactInstance * mainPart = nullptr;
auto & parts = dynamic_cast<CCombinedArtifactInstance*>(art)->constituentsInfo;
for(const auto & part : parts)
if(vstd::contains(part.art->artType->possibleSlots.at(bearerType()), slot))
{
mainPart = part.art;
break;
}
for(auto & part : parts)
{
if(part.art != mainPart)
{
if(!part.art->artType->canBePutAt(this, part.slot))
part.slot = ArtifactUtils::getArtAnyPosition(this, part.art->getTypeId());
assert(ArtifactUtils::isSlotEquipment(part.slot));
setNewArtSlot(part.slot, art, true);
}
}
}
}
void CArtifactSet::removeArtifact(ArtifactPosition slot)
{
auto art = getArt(slot, false);
if(art)
{
if(art->canBeDisassembled())
{
auto combinedArt = dynamic_cast<CCombinedArtifactInstance*>(art);
for(auto & part : combinedArt->constituentsInfo)
{
if(getArt(part.slot, false))
eraseArtSlot(part.slot);
}
}
eraseArtSlot(slot);
}
}
std::pair<const CCombinedArtifactInstance *, const CArtifactInstance *> CArtifactSet::searchForConstituent(const ArtifactID & aid) const std::pair<const CCombinedArtifactInstance *, const CArtifactInstance *> CArtifactSet::searchForConstituent(const ArtifactID & aid) const
{ {
for(const auto & slot : artifactsInBackpack) for(const auto & slot : artifactsInBackpack)
@@ -1399,44 +1372,6 @@ CArtifactFittingSet::CArtifactFittingSet(ArtBearer::ArtBearer Bearer):
{ {
} }
void CArtifactFittingSet::putArtifact(ArtifactPosition pos, CArtifactInstance * art)
{
if(art && art->canBeDisassembled() && ArtifactUtils::isSlotEquipment(pos))
{
for(auto & part : dynamic_cast<CCombinedArtifactInstance*>(art)->constituentsInfo)
{
const auto slot = ArtifactUtils::getArtAnyPosition(this, part.art->getTypeId());
assert(slot != ArtifactPosition::PRE_FIRST);
// For the ArtFittingSet is no needed to do figureMainConstituent, just lock slots
this->setNewArtSlot(slot, part.art, true);
}
}
else
{
this->setNewArtSlot(pos, art, false);
}
}
void CArtifactFittingSet::removeArtifact(ArtifactPosition pos)
{
// Removes the art from the CartifactSet, but does not remove it from art->constituentsInfo.
// removeArtifact is for CArtifactFittingSet only. Do not move it to the parent class.
auto art = getArt(pos);
if(art == nullptr)
return;
if(art->canBeDisassembled())
{
auto combinedArt = dynamic_cast<CCombinedArtifactInstance*>(art);
for(const auto & part : combinedArt->constituentsInfo)
{
if(ArtifactUtils::isSlotEquipment(part.slot))
eraseArtSlot(part.slot);
}
}
eraseArtSlot(pos);
}
ArtBearer::ArtBearer CArtifactFittingSet::bearerType() const ArtBearer::ArtBearer CArtifactFittingSet::bearerType() const
{ {
return this->Bearer; return this->Bearer;

View File

@@ -195,13 +195,11 @@ public:
std::vector<ConstituentInfo> constituentsInfo; std::vector<ConstituentInfo> constituentsInfo;
void putAt(ArtifactLocation al) override;
void removeFrom(ArtifactLocation al) override; void removeFrom(ArtifactLocation al) override;
bool isPart(const CArtifactInstance *supposedPart) const override; bool isPart(const CArtifactInstance *supposedPart) const override;
void createConstituents(); void createConstituents();
void addAsConstituent(CArtifactInstance * art, const ArtifactPosition & slot); void addAsConstituent(CArtifactInstance * art, const ArtifactPosition & slot);
CArtifactInstance * figureMainConstituent(const ArtifactLocation & al); //main constituent is replaced with us (combined art), not lock
CCombinedArtifactInstance() = default; CCombinedArtifactInstance() = default;
@@ -325,7 +323,8 @@ public:
unsigned getArtPosCount(const ArtifactID & aid, bool onlyWorn = true, bool searchBackpackAssemblies = true, bool allowLocked = true) const; unsigned getArtPosCount(const ArtifactID & aid, bool onlyWorn = true, bool searchBackpackAssemblies = true, bool allowLocked = true) const;
virtual ArtBearer::ArtBearer bearerType() const = 0; virtual ArtBearer::ArtBearer bearerType() const = 0;
virtual void putArtifact(ArtifactPosition pos, CArtifactInstance * art) = 0; virtual void putArtifact(ArtifactPosition slot, CArtifactInstance * art);
void removeArtifact(ArtifactPosition slot);
virtual ~CArtifactSet(); virtual ~CArtifactSet();
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
@@ -353,8 +352,6 @@ class DLL_LINKAGE CArtifactFittingSet : public CArtifactSet
{ {
public: public:
CArtifactFittingSet(ArtBearer::ArtBearer Bearer); CArtifactFittingSet(ArtBearer::ArtBearer Bearer);
void putArtifact(ArtifactPosition pos, CArtifactInstance * art) override;
void removeArtifact(ArtifactPosition pos);
ArtBearer::ArtBearer bearerType() const override; ArtBearer::ArtBearer bearerType() const override;
protected: protected:

View File

@@ -1936,7 +1936,6 @@ void AssembledArtifact::applyGs(CGameState *gs)
//move constituent from hero to be part of new, combined artifact //move constituent from hero to be part of new, combined artifact
constituentInstance->removeFrom(ArtifactLocation(al.artHolder, pos)); constituentInstance->removeFrom(ArtifactLocation(al.artHolder, pos));
combinedArt->addAsConstituent(constituentInstance, pos);
if(combineEquipped) if(combineEquipped)
{ {
if(!vstd::contains(combinedArt->artType->possibleSlots[artSet->bearerType()], al.slot) if(!vstd::contains(combinedArt->artType->possibleSlots[artSet->bearerType()], al.slot)
@@ -1947,6 +1946,9 @@ void AssembledArtifact::applyGs(CGameState *gs)
{ {
al.slot = std::min(al.slot, pos); al.slot = std::min(al.slot, pos);
} }
if(al.slot == pos)
pos = ArtifactPosition::PRE_FIRST;
combinedArt->addAsConstituent(constituentInstance, pos);
} }
//put new combined artifacts //put new combined artifacts