1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

Net Packs BulkMoveArtifacts structure and BulkMoveArtifacts::applyCl

This commit is contained in:
SoundSSGood 2022-11-06 23:54:50 +02:00
parent d0895e30ef
commit 95ab343116
6 changed files with 152 additions and 17 deletions

View File

@ -2591,6 +2591,7 @@ void CPlayerInterface::artifactMoved(const ArtifactLocation &src, const Artifact
if (artWin)
artWin->artifactMoved(src, dst);
}
GH.listInt.back()->redraw();
askToAssembleArtifact(dst);
}

View File

@ -279,6 +279,28 @@ void MoveArtifact::applyCl(CClient *cl)
callInterfaceIfPresent(cl, dst.owningPlayer(), &IGameEventsReceiver::artifactMoved, src, dst);
}
void BulkMoveArtifacts::applyCl(CClient * cl)
{
auto & movingArts = artsPack0;
for (auto & slotToMove : movingArts.slots)
{
auto srcLoc = ArtifactLocation(movingArts.srcArtHolder, slotToMove.srcPos);
auto dstLoc = ArtifactLocation(movingArts.dstArtHolder, slotToMove.dstPos);
MoveArtifact(&srcLoc, &dstLoc).applyCl(cl);
}
if (artsPack1.has_value())
{
movingArts = artsPack1.value();
for (auto & slotToMove : movingArts.slots)
{
auto srcLoc = ArtifactLocation(movingArts.srcArtHolder, slotToMove.srcPos);
auto dstLoc = ArtifactLocation(movingArts.dstArtHolder, slotToMove.dstPos);
MoveArtifact(&srcLoc, &dstLoc).applyCl(cl);
}
}
}
void AssembledArtifact::applyCl(CClient *cl)
{
callInterfaceIfPresent(cl, al.owningPlayer(), &IGameEventsReceiver::artifactAssembled, al);

View File

@ -303,8 +303,9 @@ struct DLL_LINKAGE ArtSlotInfo
ui8 locked; //if locked, then artifact points to the combined artifact
ArtSlotInfo() : locked(false) {}
const CArtifactInstance * getArt() const;
template <typename Handler> void serialize(Handler &h, const int version)
template <typename Handler> void serialize(Handler & h, const int version)
{
h & artifact;
h & locked;

View File

@ -994,12 +994,15 @@ struct EraseArtifact : CArtifactOperationPack
struct MoveArtifact : CArtifactOperationPack
{
MoveArtifact() {}
MoveArtifact(ArtifactLocation * src, ArtifactLocation * dst)
: src(*src), dst(*dst) {}
ArtifactLocation src, dst;
void applyCl(CClient *cl);
DLL_LINKAGE void applyGs(CGameState *gs);
template <typename Handler> void serialize(Handler &h, const int version)
template <typename Handler> void serialize(Handler & h, const int version)
{
h & src;
h & dst;

View File

@ -845,18 +845,11 @@ DLL_LINKAGE CBonusSystemNode *ArtifactLocation::getHolderNode()
DLL_LINKAGE const CArtifactInstance *ArtifactLocation::getArt() const
{
const ArtSlotInfo *s = getSlot();
if(s && s->artifact)
{
if(!s->locked)
return s->artifact;
else
{
logNetwork->warn("ArtifactLocation::getArt: This location is locked!");
return nullptr;
}
}
return nullptr;
auto s = getSlot();
if (s)
return s->getArt();
else
return nullptr;
}
DLL_LINKAGE const CArtifactSet * ArtifactLocation::getHolderArtSet() const
@ -1093,13 +1086,13 @@ DLL_LINKAGE void EraseArtifact::applyGs(CGameState *gs)
al.removeArtifact();
}
DLL_LINKAGE void MoveArtifact::applyGs(CGameState *gs)
DLL_LINKAGE void MoveArtifact::applyGs(CGameState * gs)
{
CArtifactInstance *a = src.getArt();
CArtifactInstance * art = src.getArt();
if(dst.slot < GameConstants::BACKPACK_START)
assert(!dst.getArt());
a->move(src, dst);
art->move(src, dst);
//TODO what'll happen if Titan's thunder is equipped by pickin git up or the start of game?
if (a->artType->id == ArtifactID::TITANS_THUNDER && dst.slot == ArtifactPosition::RIGHT_HAND) //Titan's Thunder creates new spellbook on equip
@ -1114,6 +1107,86 @@ DLL_LINKAGE void MoveArtifact::applyGs(CGameState *gs)
}
}
DLL_LINKAGE void BulkMoveArtifacts::applyGs(CGameState * gs)
{
int numBackpackArtifactsMoved = 0;
if (artsPack1.has_value())
{
// Swap
auto & leftRightPack = artsPack0;
auto & rightLeftPack = artsPack1.value();
auto leftSet = leftRightPack.getSrcHolderArtSet();
auto rightSet = leftRightPack.getDstHolderArtSet();
CArtifactFittingSet ArtFittingSet(leftSet->bearerType());
std::vector<std::pair<ArtifactPosition, ArtSlotInfo>> unmovableArtsLeftHero, unmovableArtsRightHero;
// Keep unmovable artifacts separately until the swap
for (auto artPos : ArtifactUtils::unmovablePositions())
{
auto slotInfo = leftSet->getSlot(artPos);
if (slotInfo)
{
unmovableArtsLeftHero.push_back(std::make_pair(artPos, *slotInfo));
leftSet->eraseArtSlot(artPos);
}
slotInfo = rightSet->getSlot(artPos);
if (slotInfo)
{
unmovableArtsRightHero.push_back(std::make_pair(artPos, *slotInfo));
rightSet->eraseArtSlot(artPos);
}
}
ArtFittingSet.artifactsWorn = rightSet->artifactsWorn;
ArtFittingSet.artifactsInBackpack = rightSet->artifactsInBackpack;
rightSet->artifactsWorn = leftSet->artifactsWorn;
rightSet->artifactsInBackpack = leftSet->artifactsInBackpack;
leftSet->artifactsWorn = ArtFittingSet.artifactsWorn;
leftSet->artifactsInBackpack = ArtFittingSet.artifactsInBackpack;
// Return non movable artifacts to their place after the swap
for (auto & art : unmovableArtsLeftHero)
{
leftSet->putArtifact(art.first, art.second.artifact);
}
for (auto & art : unmovableArtsRightHero)
{
rightSet->putArtifact(art.first, art.second.artifact);
}
}
else
{
// Move
auto & artsPack = artsPack0;
for (auto & slot : artsPack.slots)
{
// When an object gets removed from the backpack, the backpack shrinks
// so all the following indices will be affected. Thus, we need to update
// the subsequent artifact slots to account for that
if (slot.srcPos >= GameConstants::BACKPACK_START)
{
slot.srcPos = ArtifactPosition(slot.srcPos.num - numBackpackArtifactsMoved);
}
auto srcSlotInfo = artsPack.getSrcHolderArtSet()->getSlot(slot.srcPos);
auto dstSlotInfo = artsPack.getDstHolderArtSet()->getSlot(slot.dstPos);
if (slot.dstPos < GameConstants::BACKPACK_START)
assert(!dstSlotInfo->getArt());
assert(srcSlotInfo);
auto art = srcSlotInfo->getArt();
const_cast<CArtifactInstance*>(art)->move(
ArtifactLocation(artsPack.srcArtHolder, slot.srcPos), ArtifactLocation(artsPack.dstArtHolder, slot.dstPos));
if (slot.srcPos >= GameConstants::BACKPACK_START)
{
numBackpackArtifactsMoved++;
}
}
}
}
DLL_LINKAGE void AssembledArtifact::applyGs(CGameState *gs)
{
CArtifactSet *artSet = al.getHolderArtSet();
@ -1712,4 +1785,29 @@ DLL_LINKAGE void EntitiesChanged::applyGs(CGameState * gs)
gs->updateEntity(change.metatype, change.entityIndex, change.data);
}
const CArtifactInstance * ArtSlotInfo::getArt() const
{
if (artifact)
{
if (!locked)
return artifact;
else
{
logNetwork->warn("ArtifactLocation::getArt: This location is locked!");
return nullptr;
}
}
return nullptr;
}
CArtifactSet * BulkMoveArtifacts::HeroArtsToMove::getSrcHolderArtSet()
{
return boost::apply_visitor(GetBase<CArtifactSet>(), srcArtHolder);
}
CArtifactSet * BulkMoveArtifacts::HeroArtsToMove::getDstHolderArtSet()
{
return boost::apply_visitor(GetBase<CArtifactSet>(), dstArtHolder);
}
VCMI_LIB_NAMESPACE_END

View File

@ -180,6 +180,16 @@ bool ExchangeArtifacts::applyGh(CGameHandler * gh)
return gh->moveArtifact(src, dst);
}
bool BulkExchangeArtifacts::applyGh(CGameHandler * gh)
{
const CGHeroInstance * pSrcHero = gh->getHero(srcHero);
throwOnWrongPlayer(gh, pSrcHero->getOwner());
if (swap)
return gh->bulkSwapArtifacts(srcHero, dstHero);
else
return gh->bulkMoveArtifacts(srcHero, dstHero);
}
bool AssembleArtifacts::applyGh(CGameHandler * gh)
{
throwOnWrongOwner(gh, heroID);