1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-02 00:10:22 +02:00

End of battle BulkMoveArtifacts

This commit is contained in:
SoundSSGood 2024-03-28 00:28:31 +02:00
parent 719f920914
commit 5dbe88d9a4
6 changed files with 55 additions and 68 deletions

View File

@ -306,8 +306,8 @@ void ApplyClientNetPackVisitor::visitMoveArtifact(MoveArtifact & pack)
}; };
moveArtifact(pack.interfaceOwner); moveArtifact(pack.interfaceOwner);
if(pack.interfaceOwner != cl.getOwner(pack.dst.artHolder)) //if(pack.interfaceOwner != cl.getOwner(pack.dst.artHolder))
moveArtifact(cl.getOwner(pack.dst.artHolder)); // moveArtifact(cl.getOwner(pack.dst.artHolder));
cl.invalidatePaths(); // hero might have equipped/unequipped Angel Wings cl.invalidatePaths(); // hero might have equipped/unequipped Angel Wings
} }

View File

@ -1079,8 +1079,8 @@ void CArtifactSet::serializeJsonSlot(JsonSerializeFormat & handler, const Artifa
} }
} }
CArtifactFittingSet::CArtifactFittingSet(ArtBearer::ArtBearer Bearer): CArtifactFittingSet::CArtifactFittingSet(ArtBearer::ArtBearer bearer)
Bearer(Bearer) : bearer(bearer)
{ {
} }
@ -1094,7 +1094,7 @@ CArtifactFittingSet::CArtifactFittingSet(const CArtifactSet & artSet)
ArtBearer::ArtBearer CArtifactFittingSet::bearerType() const ArtBearer::ArtBearer CArtifactFittingSet::bearerType() const
{ {
return this->Bearer; return this->bearer;
} }
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@ -255,7 +255,7 @@ public:
ArtBearer::ArtBearer bearerType() const override; ArtBearer::ArtBearer bearerType() const override;
protected: protected:
ArtBearer::ArtBearer Bearer; ArtBearer::ArtBearer bearer;
}; };
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@ -37,6 +37,12 @@ struct ArtifactLocation
, creature(creatureSlot) , creature(creatureSlot)
{ {
} }
ArtifactLocation(const ObjectInstanceID id, const std::optional<SlotID> creatureSlot, const ArtifactPosition & slot)
: artHolder(id)
, slot(slot)
, creature(creatureSlot)
{
}
template <typename Handler> void serialize(Handler & h) template <typename Handler> void serialize(Handler & h)
{ {

View File

@ -2891,7 +2891,7 @@ bool CGameHandler::bulkMoveArtifacts(const PlayerColor & player, ObjectInstanceI
bool CGameHandler::scrollBackpackArtifacts(const PlayerColor & player, const ObjectInstanceID heroID, bool left) bool CGameHandler::scrollBackpackArtifacts(const PlayerColor & player, const ObjectInstanceID heroID, bool left)
{ {
auto artSet = getArtSet(heroID); const auto artSet = getArtSet(heroID);
COMPLAIN_RET_FALSE_IF(artSet == nullptr, "scrollBackpackArtifacts: wrong hero's ID"); COMPLAIN_RET_FALSE_IF(artSet == nullptr, "scrollBackpackArtifacts: wrong hero's ID");
BulkMoveArtifacts bma(player, heroID, heroID, false); BulkMoveArtifacts bma(player, heroID, heroID, false);

View File

@ -342,80 +342,61 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
if(result == EBattleResult::NORMAL && !finishingBattle->isDraw() && finishingBattle->winnerHero) if(result == EBattleResult::NORMAL && !finishingBattle->isDraw() && finishingBattle->winnerHero)
{ {
auto sendMoveArtifact = [&](const CArtifactInstance *art, MoveArtifact *ma) BulkMoveArtifacts bma(finishingBattle->winnerHero->getOwner(), finishingBattle->loserHero->id, finishingBattle->winnerHero->id, false);
bma.askAssemble = true;
CArtifactFittingSet artFittingSet(*finishingBattle->winnerHero);
const auto addArtifactToTransfer = [&](const ArtifactPosition & srcSlot, const CArtifactInstance * art)
{ {
const auto slot = ArtifactUtils::getArtAnyPosition(finishingBattle->winnerHero, art->getTypeId()); const auto dstSlot = ArtifactUtils::getArtAnyPosition(&artFittingSet, art->getTypeId());
if(slot != ArtifactPosition::PRE_FIRST) if(dstSlot != ArtifactPosition::PRE_FIRST)
{ {
arts.push_back(art); bma.artsPack0.emplace_back(BulkMoveArtifacts::LinkedSlots(srcSlot, dstSlot));
ma->dst = ArtifactLocation(finishingBattle->winnerHero->id, slot); arts.emplace_back(art);
if(ArtifactUtils::isSlotBackpack(slot)) artFittingSet.putArtifact(dstSlot, const_cast<CArtifactInstance*>(art));
ma->askAssemble = false;
gameHandler->sendAndApply(ma);
} }
}; };
const auto sendArtifacts = [&bma, this]()
if (finishingBattle->loserHero)
{ {
//TODO: wrap it into a function, somehow (std::variant -_-) if(!bma.artsPack0.empty())
auto artifactsWorn = finishingBattle->loserHero->artifactsWorn; gameHandler->sendAndApply(&bma);
for (auto artSlot : artifactsWorn) };
if(finishingBattle->loserHero)
{
for(const auto & artSlot : finishingBattle->loserHero->artifactsWorn)
{ {
MoveArtifact ma; if(ArtifactUtils::isArtRemovable(artSlot))
ma.src = ArtifactLocation(finishingBattle->loserHero->id, artSlot.first); addArtifactToTransfer(artSlot.first, artSlot.second.getArt());
const CArtifactInstance * art = finishingBattle->loserHero->getArt(artSlot.first);
if (art && !art->artType->isBig() &&
art->artType->getId() != ArtifactID::SPELLBOOK)
// don't move war machines or locked arts (spellbook)
{
sendMoveArtifact(art, &ma);
}
} }
for(int slotNumber = finishingBattle->loserHero->artifactsInBackpack.size() - 1; slotNumber >= 0; slotNumber--) for(const auto & artSlot : finishingBattle->loserHero->artifactsInBackpack)
{ {
//we assume that no big artifacts can be found const auto art = artSlot.getArt();
MoveArtifact ma; if(art->getTypeId() != ArtifactID::GRAIL)
ma.src = ArtifactLocation(finishingBattle->loserHero->id, addArtifactToTransfer(finishingBattle->loserHero->getArtPos(art), art);
ArtifactPosition(ArtifactPosition::BACKPACK_START + slotNumber)); //backpack automatically shifts arts to beginning
const CArtifactInstance * art = finishingBattle->loserHero->getArt(ArtifactPosition::BACKPACK_START + slotNumber);
if (art->artType->getId() != ArtifactID::GRAIL) //grail may not be won
{
sendMoveArtifact(art, &ma);
}
} }
if (finishingBattle->loserHero->commander) //TODO: what if commanders belong to no hero? sendArtifacts();
bma.askAssemble = false;
bma.artsPack0.clear();
if(finishingBattle->loserHero->commander)
{ {
artifactsWorn = finishingBattle->loserHero->commander->artifactsWorn; bma.srcCreature = finishingBattle->loserHero->findStack(finishingBattle->loserHero->commander);
for (auto artSlot : artifactsWorn) for(const auto & artSlot : finishingBattle->loserHero->commander->artifactsWorn)
{ addArtifactToTransfer(artSlot.first, artSlot.second.getArt());
MoveArtifact ma; sendArtifacts();
ma.src = ArtifactLocation(finishingBattle->loserHero->id, artSlot.first);
ma.src.creature = finishingBattle->loserHero->findStack(finishingBattle->loserHero->commander);
const auto art = finishingBattle->loserHero->commander->getArt(artSlot.first);
if (art && !art->artType->isBig())
{
sendMoveArtifact(art, &ma);
}
}
} }
} }
auto armyObj = battle.battleGetArmyObject(battle.otherSide(battleResult->winner));
auto loser = battle.otherSide(battleResult->winner); bma.srcArtHolder = armyObj->id;
for(const auto & armySlot : armyObj->stacks)
for (auto armySlot : battle.battleGetArmyObject(loser)->stacks)
{ {
auto artifactsWorn = armySlot.second->artifactsWorn; bma.artsPack0.clear();
for(const auto & artSlot : artifactsWorn) bma.interfaceOwner = finishingBattle->winnerHero->getOwner();
{ bma.srcCreature = armySlot.first;
MoveArtifact ma; for(const auto & artSlot : armySlot.second->artifactsWorn)
ma.src = ArtifactLocation(finishingBattle->loserHero->id, artSlot.first); addArtifactToTransfer(artSlot.first, armySlot.second->getArt(artSlot.first));
ma.src.creature = finishingBattle->loserHero->findStack(finishingBattle->loserHero->commander); sendArtifacts();
const auto art = finishingBattle->loserHero->commander->getArt(artSlot.first);
if (art && !art->artType->isBig())
{
sendMoveArtifact(art, &ma);
}
}
} }
} }