mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
artifacts swap optimization
This commit is contained in:
parent
8aea2be0db
commit
ce3d407396
@ -301,7 +301,7 @@ void ApplyClientNetPackVisitor::visitBulkMoveArtifacts(BulkMoveArtifacts & pack)
|
||||
{
|
||||
auto srcLoc = ArtifactLocation(pack.srcArtHolder, slotToMove.srcPos);
|
||||
auto dstLoc = ArtifactLocation(pack.dstArtHolder, slotToMove.dstPos);
|
||||
MoveArtifact ma(&srcLoc, &dstLoc, false);
|
||||
MoveArtifact ma(&srcLoc, &dstLoc, pack.askAssemble);
|
||||
visitMoveArtifact(ma);
|
||||
}
|
||||
};
|
||||
|
@ -31,6 +31,12 @@ struct ArtifactLocation
|
||||
, creature(std::nullopt)
|
||||
{
|
||||
}
|
||||
ArtifactLocation(const ObjectInstanceID id, const std::optional<SlotID> creatureSlot)
|
||||
: artHolder(id)
|
||||
, slot(ArtifactPosition::PRE_FIRST)
|
||||
, creature(creatureSlot)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
|
@ -1837,13 +1837,13 @@ void BulkMoveArtifacts::applyGs(CGameState * gs)
|
||||
switch(operation)
|
||||
{
|
||||
case EBulkArtsOp::BULK_MOVE:
|
||||
art->move(artSet, srcPos, *gs->getHero(dstArtHolder), slot.dstPos);
|
||||
art->move(artSet, srcPos, *gs->getArtSet(ArtifactLocation(dstArtHolder, dstCreature)), slot.dstPos);
|
||||
break;
|
||||
case EBulkArtsOp::BULK_REMOVE:
|
||||
art->removeFrom(artSet, srcPos);
|
||||
break;
|
||||
case EBulkArtsOp::BULK_PUT:
|
||||
art->putAt(*gs->getHero(srcArtHolder), slot.dstPos);
|
||||
art->putAt(*gs->getArtSet(ArtifactLocation(srcArtHolder, srcCreature)), slot.dstPos);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1856,11 +1856,11 @@ void BulkMoveArtifacts::applyGs(CGameState * gs)
|
||||
}
|
||||
};
|
||||
|
||||
auto * leftSet = gs->getArtSet(ArtifactLocation(srcArtHolder));
|
||||
auto * leftSet = gs->getArtSet(ArtifactLocation(srcArtHolder, srcCreature));
|
||||
if(swap)
|
||||
{
|
||||
// Swap
|
||||
auto * rightSet = gs->getArtSet(ArtifactLocation(dstArtHolder));
|
||||
auto * rightSet = gs->getArtSet(ArtifactLocation(dstArtHolder, dstCreature));
|
||||
CArtifactFittingSet artFittingSet(leftSet->bearerType());
|
||||
|
||||
artFittingSet.artifactsWorn = rightSet->artifactsWorn;
|
||||
|
@ -1064,17 +1064,25 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
|
||||
|
||||
ObjectInstanceID srcArtHolder;
|
||||
ObjectInstanceID dstArtHolder;
|
||||
std::optional<SlotID> srcCreature;
|
||||
std::optional<SlotID> dstCreature;
|
||||
|
||||
BulkMoveArtifacts()
|
||||
: srcArtHolder(ObjectInstanceID::NONE)
|
||||
, dstArtHolder(ObjectInstanceID::NONE)
|
||||
, swap(false)
|
||||
, askAssemble(false)
|
||||
, srcCreature(std::nullopt)
|
||||
, dstCreature(std::nullopt)
|
||||
{
|
||||
}
|
||||
BulkMoveArtifacts(const ObjectInstanceID srcArtHolder, const ObjectInstanceID dstArtHolder, bool swap)
|
||||
: srcArtHolder(std::move(srcArtHolder))
|
||||
, dstArtHolder(std::move(dstArtHolder))
|
||||
, swap(swap)
|
||||
, askAssemble(false)
|
||||
, srcCreature(std::nullopt)
|
||||
, dstCreature(std::nullopt)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1083,6 +1091,7 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
|
||||
std::vector<LinkedSlots> artsPack0;
|
||||
std::vector<LinkedSlots> artsPack1;
|
||||
bool swap;
|
||||
bool askAssemble;
|
||||
|
||||
void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
@ -1092,7 +1101,10 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
|
||||
h & artsPack1;
|
||||
h & srcArtHolder;
|
||||
h & dstArtHolder;
|
||||
h & srcCreature;
|
||||
h & dstCreature;
|
||||
h & swap;
|
||||
h & askAssemble;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2667,19 +2667,18 @@ bool CGameHandler::garrisonSwap(ObjectInstanceID tid)
|
||||
// Function moves artifact from src to dst. If dst is not a backpack and is already occupied, old dst art goes to backpack and is replaced.
|
||||
bool CGameHandler::moveArtifact(const ArtifactLocation & src, const ArtifactLocation & dst)
|
||||
{
|
||||
ArtifactLocation srcLoc = src, dstLoc = dst;
|
||||
const auto srcArtSet = getArtSet(srcLoc);
|
||||
const auto dstArtSet = getArtSet(dstLoc);
|
||||
const auto srcArtSet = getArtSet(src);
|
||||
const auto dstArtSet = getArtSet(dst);
|
||||
assert(srcArtSet);
|
||||
assert(dstArtSet);
|
||||
|
||||
// Make sure exchange is even possible between the two heroes.
|
||||
if(!isAllowedExchange(srcLoc.artHolder, dstLoc.artHolder))
|
||||
if(!isAllowedExchange(src.artHolder, dst.artHolder))
|
||||
COMPLAIN_RET("That heroes cannot make any exchange!");
|
||||
|
||||
const auto srcArtifact = srcArtSet->getArt(srcLoc.slot);
|
||||
const auto dstArtifact = dstArtSet->getArt(dstLoc.slot);
|
||||
const bool isDstSlotBackpack = dstArtSet->bearerType() == ArtBearer::HERO ? ArtifactUtils::isSlotBackpack(dstLoc.slot) : false;
|
||||
const auto srcArtifact = srcArtSet->getArt(src.slot);
|
||||
const auto dstArtifact = dstArtSet->getArt(dst.slot);
|
||||
const bool isDstSlotBackpack = dstArtSet->bearerType() == ArtBearer::HERO ? ArtifactUtils::isSlotBackpack(dst.slot) : false;
|
||||
|
||||
if(srcArtifact == nullptr)
|
||||
COMPLAIN_RET("No artifact to move!");
|
||||
@ -2688,55 +2687,54 @@ bool CGameHandler::moveArtifact(const ArtifactLocation & src, const ArtifactLoca
|
||||
|
||||
// Check if src/dest slots are appropriate for the artifacts exchanged.
|
||||
// Moving to the backpack is always allowed.
|
||||
if((!srcArtifact || !isDstSlotBackpack) && srcArtifact && !srcArtifact->canBePutAt(dstArtSet, dstLoc.slot, true))
|
||||
if((!srcArtifact || !isDstSlotBackpack) && srcArtifact && !srcArtifact->canBePutAt(dstArtSet, dst.slot, true))
|
||||
COMPLAIN_RET("Cannot move artifact!");
|
||||
|
||||
auto srcSlotInfo = srcArtSet->getSlot(srcLoc.slot);
|
||||
auto dstSlotInfo = dstArtSet->getSlot(dstLoc.slot);
|
||||
auto srcSlotInfo = srcArtSet->getSlot(src.slot);
|
||||
auto dstSlotInfo = dstArtSet->getSlot(dst.slot);
|
||||
|
||||
if((srcSlotInfo && srcSlotInfo->locked) || (dstSlotInfo && dstSlotInfo->locked))
|
||||
COMPLAIN_RET("Cannot move artifact locks.");
|
||||
|
||||
if(isDstSlotBackpack && srcArtifact->artType->isBig())
|
||||
COMPLAIN_RET("Cannot put big artifacts in backpack!");
|
||||
if(srcLoc.slot == ArtifactPosition::MACH4 || dstLoc.slot == ArtifactPosition::MACH4)
|
||||
if(src.slot == ArtifactPosition::MACH4 || dst.slot == ArtifactPosition::MACH4)
|
||||
COMPLAIN_RET("Cannot move catapult!");
|
||||
if(isDstSlotBackpack && !ArtifactUtils::isBackpackFreeSlots(dstArtSet))
|
||||
COMPLAIN_RET("Backpack is full!");
|
||||
|
||||
if(isDstSlotBackpack)
|
||||
auto dstSlot = std::min(dst.slot, ArtifactPosition(ArtifactPosition::BACKPACK_START + dstArtSet->artifactsInBackpack.size()));
|
||||
|
||||
if(src.slot == dstSlot && src.artHolder == dst.artHolder)
|
||||
COMPLAIN_RET("Won't move artifact: Dest same as source!");
|
||||
|
||||
BulkMoveArtifacts ma(src.artHolder, dst.artHolder, false);
|
||||
ma.srcCreature = src.creature;
|
||||
ma.dstCreature = dst.creature;
|
||||
|
||||
// Check if dst slot is occupied
|
||||
if(!isDstSlotBackpack && dstArtifact)
|
||||
{
|
||||
if(!ArtifactUtils::isBackpackFreeSlots(dstArtSet))
|
||||
COMPLAIN_RET("Backpack is full!");
|
||||
vstd::amin(dstLoc.slot, ArtifactPosition::BACKPACK_START + dstArtSet->artifactsInBackpack.size());
|
||||
// Previous artifact must be removed
|
||||
ma.artsPack1.push_back(BulkMoveArtifacts::LinkedSlots(dstSlot, src.slot));
|
||||
ma.swap = true;
|
||||
}
|
||||
|
||||
if(!(srcLoc.slot == ArtifactPosition::TRANSITION_POS && dstLoc.slot == ArtifactPosition::TRANSITION_POS))
|
||||
try
|
||||
{
|
||||
if(srcLoc.slot == dstLoc.slot && srcLoc.artHolder == dstLoc.artHolder)
|
||||
COMPLAIN_RET("Won't move artifact: Dest same as source!");
|
||||
|
||||
// Check if dst slot is occupied
|
||||
if(!isDstSlotBackpack && dstArtifact)
|
||||
{
|
||||
// Previous artifact must be removed first
|
||||
moveArtifact(dstLoc, ArtifactLocation(dstLoc.artHolder, ArtifactPosition::TRANSITION_POS));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
auto hero = getHero(dst.artHolder);
|
||||
if(ArtifactUtils::checkSpellbookIsNeeded(hero, srcArtifact->artType->getId(), dstLoc.slot))
|
||||
giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
|
||||
}
|
||||
catch(const std::bad_variant_access &)
|
||||
{
|
||||
// object other than hero received an art - ignore
|
||||
}
|
||||
|
||||
MoveArtifact ma(&srcLoc, &dstLoc);
|
||||
if(srcLoc.artHolder == dstLoc.artHolder)
|
||||
ma.askAssemble = false;
|
||||
sendAndApply(&ma);
|
||||
auto hero = getHero(dst.artHolder);
|
||||
if(ArtifactUtils::checkSpellbookIsNeeded(hero, srcArtifact->artType->getId(), dstSlot))
|
||||
giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
|
||||
}
|
||||
catch(const std::bad_variant_access &)
|
||||
{
|
||||
// object other than hero received an art - ignore
|
||||
}
|
||||
|
||||
ma.artsPack0.push_back(BulkMoveArtifacts::LinkedSlots(src.slot, dstSlot));
|
||||
if(src.artHolder != dst.artHolder)
|
||||
ma.askAssemble = true;
|
||||
sendAndApply(&ma);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user