1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Merge pull request #4534 from SoundSSGood/BulkEraseArtifacts

BulkEraseArtifacts network pack
This commit is contained in:
Ivan Savenko 2024-08-31 13:52:26 +03:00 committed by GitHub
commit 0a72a0a48e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 68 additions and 44 deletions

View File

@ -47,7 +47,7 @@ public:
void visitBulkRebalanceStacks(BulkRebalanceStacks & pack) override;
void visitBulkSmartRebalanceStacks(BulkSmartRebalanceStacks & pack) override;
void visitPutArtifact(PutArtifact & pack) override;
void visitEraseArtifact(EraseArtifact & pack) override;
void visitEraseArtifact(BulkEraseArtifacts & pack) override;
void visitBulkMoveArtifacts(BulkMoveArtifacts & pack) override;
void visitAssembledArtifact(AssembledArtifact & pack) override;
void visitDisassembledArtifact(DisassembledArtifact & pack) override;

View File

@ -290,9 +290,10 @@ void ApplyClientNetPackVisitor::visitPutArtifact(PutArtifact & pack)
callInterfaceIfPresent(cl, cl.getOwner(pack.al.artHolder), &IGameEventsReceiver::askToAssembleArtifact, pack.al);
}
void ApplyClientNetPackVisitor::visitEraseArtifact(EraseArtifact & pack)
void ApplyClientNetPackVisitor::visitEraseArtifact(BulkEraseArtifacts & pack)
{
callInterfaceIfPresent(cl, cl.getOwner(pack.al.artHolder), &IGameEventsReceiver::artifactRemoved, pack.al);
for(const auto & slotErase : pack.posPack)
callInterfaceIfPresent(cl, cl.getOwner(pack.artHolder), &IGameEventsReceiver::artifactRemoved, ArtifactLocation(pack.artHolder, slotErase));
}
void ApplyClientNetPackVisitor::visitBulkMoveArtifacts(BulkMoveArtifacts & pack)

View File

@ -120,7 +120,7 @@ public:
virtual bool giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact * artType, ArtifactPosition pos) = 0;
virtual bool putArtifact(const ArtifactLocation & al, const CArtifactInstance * art, std::optional<bool> askAssemble = std::nullopt) = 0;
virtual void removeArtifact(const ArtifactLocation &al) = 0;
virtual void removeArtifact(const ArtifactLocation& al) = 0;
virtual bool moveArtifact(const PlayerColor & player, const ArtifactLocation & al1, const ArtifactLocation & al2) = 0;
virtual void heroVisitCastle(const CGTownInstance * obj, const CGHeroInstance * hero)=0;

View File

@ -78,7 +78,7 @@ public:
virtual void visitBulkRebalanceStacks(BulkRebalanceStacks & pack) {}
virtual void visitBulkSmartRebalanceStacks(BulkSmartRebalanceStacks & pack) {}
virtual void visitPutArtifact(PutArtifact & pack) {}
virtual void visitEraseArtifact(EraseArtifact & pack) {}
virtual void visitEraseArtifact(BulkEraseArtifacts & pack) {}
virtual void visitBulkMoveArtifacts(BulkMoveArtifacts & pack) {}
virtual void visitAssembledArtifact(AssembledArtifact & pack) {}
virtual void visitDisassembledArtifact(DisassembledArtifact & pack) {}

View File

@ -336,7 +336,7 @@ void PutArtifact::visitTyped(ICPackVisitor & visitor)
visitor.visitPutArtifact(*this);
}
void EraseArtifact::visitTyped(ICPackVisitor & visitor)
void BulkEraseArtifacts::visitTyped(ICPackVisitor & visitor)
{
visitor.visitEraseArtifact(*this);
}
@ -1611,9 +1611,10 @@ void RebalanceStacks::applyGs(CGameState *gs)
//else - artifact can be lost :/
else
{
EraseArtifact ea;
ea.al = ArtifactLocation(dstHero->id, ArtifactPosition::CREATURE_SLOT);
ea.al.creature = dst.slot;
BulkEraseArtifacts ea;
ea.artHolder = dstHero->id;
ea.posPack.emplace_back(ArtifactPosition::CREATURE_SLOT);
ea.creature = dst.slot;
ea.applyGs(gs);
logNetwork->warn("Cannot move artifact! No free slots");
}
@ -1701,37 +1702,46 @@ void PutArtifact::applyGs(CGameState *gs)
art->putAt(*hero, al.slot);
}
void EraseArtifact::applyGs(CGameState *gs)
void BulkEraseArtifacts::applyGs(CGameState *gs)
{
const auto artSet = gs->getArtSet(al.artHolder);
const auto artSet = gs->getArtSet(artHolder);
assert(artSet);
const auto slot = artSet->getSlot(al.slot);
if(slot->locked)
{
logGlobal->debug("Erasing locked artifact: %s", slot->artifact->artType->getNameTranslated());
DisassembledArtifact dis;
dis.al.artHolder = al.artHolder;
for(auto & slotInfo : artSet->artifactsWorn)
std::sort(posPack.begin(), posPack.end(), [](const ArtifactPosition & slot0, const ArtifactPosition & slot1) -> bool
{
auto art = slotInfo.second.artifact;
if(art->isCombined() && art->isPart(slot->artifact))
{
dis.al.slot = artSet->getArtPos(art);
break;
}
}
assert((dis.al.slot != ArtifactPosition::PRE_FIRST) && "Failed to determine the assembly this locked artifact belongs to");
logGlobal->debug("Found the corresponding assembly: %s", artSet->getArt(dis.al.slot)->artType->getNameTranslated());
dis.applyGs(gs);
}
else
return slot0.num > slot1.num;
});
for(const auto & slot : posPack)
{
logGlobal->debug("Erasing artifact %s", slot->artifact->artType->getNameTranslated());
const auto slotInfo = artSet->getSlot(slot);
if(slotInfo->locked)
{
logGlobal->debug("Erasing locked artifact: %s", slotInfo->artifact->artType->getNameTranslated());
DisassembledArtifact dis;
dis.al.artHolder = artHolder;
for(auto & slotInfoWorn : artSet->artifactsWorn)
{
auto art = slotInfoWorn.second.artifact;
if(art->isCombined() && art->isPart(slotInfo->getArt()))
{
dis.al.slot = artSet->getArtPos(art);
break;
}
}
assert((dis.al.slot != ArtifactPosition::PRE_FIRST) && "Failed to determine the assembly this locked artifact belongs to");
logGlobal->debug("Found the corresponding assembly: %s", artSet->getArt(dis.al.slot)->artType->getNameTranslated());
dis.applyGs(gs);
}
else
{
logGlobal->debug("Erasing artifact %s", slotInfo->artifact->artType->getNameTranslated());
}
auto art = artSet->getArt(slot);
assert(art);
art->removeFrom(*artSet, slot);
}
auto art = artSet->getArt(al.slot);
assert(art);
art->removeFrom(*artSet, al.slot);
}
void BulkMoveArtifacts::applyGs(CGameState *gs)

View File

@ -998,16 +998,20 @@ struct DLL_LINKAGE NewArtifact : public CArtifactOperationPack
}
};
struct DLL_LINKAGE EraseArtifact : CArtifactOperationPack
struct DLL_LINKAGE BulkEraseArtifacts : CArtifactOperationPack
{
ArtifactLocation al;
ObjectInstanceID artHolder;
std::vector<ArtifactPosition> posPack;
std::optional<SlotID> creature;
void applyGs(CGameState * gs) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h)
{
h & al;
h & artHolder;
h & posPack;
h & creature;
}
};

View File

@ -223,7 +223,7 @@ void registerTypes(Serializer &s)
s.template registerType<InsertNewStack>(166);
s.template registerType<RebalanceStacks>(167);
s.template registerType<PutArtifact>(169);
s.template registerType<EraseArtifact>(170);
s.template registerType<BulkEraseArtifacts>(170);
s.template registerType<AssembledArtifact>(171);
s.template registerType<DisassembledArtifact>(172);
s.template registerType<BulkMoveArtifacts>(173);

View File

@ -1192,10 +1192,16 @@ void CGameHandler::stopHeroVisitCastle(const CGTownInstance * obj, const CGHeroI
sendAndApply(&vc);
}
void CGameHandler::removeArtifact(const ArtifactLocation &al)
void CGameHandler::removeArtifact(const ArtifactLocation & al)
{
EraseArtifact ea;
ea.al = al;
removeArtifact(al.artHolder, {al.slot});
}
void CGameHandler::removeArtifact(const ObjectInstanceID & srcId, const std::vector<ArtifactPosition> & slotsPack)
{
BulkEraseArtifacts ea;
ea.artHolder = srcId;
ea.posPack.insert(ea.posPack.end(), slotsPack.begin(), slotsPack.end());
sendAndApply(&ea);
}
@ -3494,8 +3500,10 @@ bool CGameHandler::sacrificeArtifact(const IMarket * market, const CGHeroInstanc
const auto artSet = market->getArtifactsStorage();
int expSum = 0;
auto finish = [this, &hero, &expSum]()
std::vector<ArtifactPosition> artPack;
auto finish = [this, &hero, &expSum, &artPack, market]()
{
removeArtifact(market->getObjInstanceID(), artPack);
giveExperience(hero, hero->calculateXp(expSum));
};
@ -3509,7 +3517,7 @@ bool CGameHandler::sacrificeArtifact(const IMarket * market, const CGHeroInstanc
int expToGive;
market->getOffer(art->getTypeId(), 0, dmp, expToGive, EMarketMode::ARTIFACT_EXP);
expSum += expToGive;
removeArtifact(ArtifactLocation(market->getObjInstanceID(), artSet->getArtPos(art)));
artPack.push_back(artSet->getArtPos(art));
}
else
{

View File

@ -136,6 +136,7 @@ public:
bool giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact * artType, ArtifactPosition pos = ArtifactPosition::FIRST_AVAILABLE) override;
bool putArtifact(const ArtifactLocation & al, const CArtifactInstance * art, std::optional<bool> askAssemble) override;
void removeArtifact(const ArtifactLocation &al) override;
void removeArtifact(const ObjectInstanceID & srcId, const std::vector<ArtifactPosition> & slotsPack);
bool moveArtifact(const PlayerColor & player, const ArtifactLocation & src, const ArtifactLocation & dst) override;
bool bulkMoveArtifacts(const PlayerColor & player, ObjectInstanceID srcId, ObjectInstanceID dstId, bool swap, bool equipped, bool backpack);
bool scrollBackpackArtifacts(const PlayerColor & player, const ObjectInstanceID heroID, bool left);