1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

BulkMoveArtifacts structure optimization

This commit is contained in:
SoundSSGood
2022-11-07 14:13:36 +02:00
parent 0032947735
commit 203c54e956
4 changed files with 46 additions and 63 deletions

View File

@@ -286,10 +286,10 @@ void MoveArtifact::applyCl(CClient *cl)
void BulkMoveArtifacts::applyCl(CClient * cl) void BulkMoveArtifacts::applyCl(CClient * cl)
{ {
auto & movingArts = artsPack0; auto & movingArts = artsPack0;
for (auto & slotToMove : movingArts.slots) for (auto & slotToMove : movingArts)
{ {
auto srcLoc = ArtifactLocation(movingArts.srcArtHolder, slotToMove.srcPos); auto srcLoc = ArtifactLocation(srcArtHolder, slotToMove.srcPos);
auto dstLoc = ArtifactLocation(movingArts.dstArtHolder, slotToMove.dstPos); auto dstLoc = ArtifactLocation(dstArtHolder, slotToMove.dstPos);
callInterfaceIfPresent(cl, srcLoc.owningPlayer(), &IGameEventsReceiver::artifactMoved, srcLoc, dstLoc); callInterfaceIfPresent(cl, srcLoc.owningPlayer(), &IGameEventsReceiver::artifactMoved, srcLoc, dstLoc);
if (srcLoc.owningPlayer() != dstLoc.owningPlayer()) if (srcLoc.owningPlayer() != dstLoc.owningPlayer())
callInterfaceIfPresent(cl, dstLoc.owningPlayer(), &IGameEventsReceiver::artifactMoved, srcLoc, dstLoc); callInterfaceIfPresent(cl, dstLoc.owningPlayer(), &IGameEventsReceiver::artifactMoved, srcLoc, dstLoc);
@@ -298,10 +298,10 @@ void BulkMoveArtifacts::applyCl(CClient * cl)
if (artsPack1.has_value()) if (artsPack1.has_value())
{ {
movingArts = artsPack1.value(); movingArts = artsPack1.value();
for (auto & slotToMove : movingArts.slots) for (auto & slotToMove : movingArts)
{ {
auto srcLoc = ArtifactLocation(movingArts.srcArtHolder, slotToMove.srcPos); auto srcLoc = ArtifactLocation(srcArtHolder, slotToMove.srcPos);
auto dstLoc = ArtifactLocation(movingArts.dstArtHolder, slotToMove.dstPos); auto dstLoc = ArtifactLocation(dstArtHolder, slotToMove.dstPos);
callInterfaceIfPresent(cl, srcLoc.owningPlayer(), &IGameEventsReceiver::artifactMoved, srcLoc, dstLoc); callInterfaceIfPresent(cl, srcLoc.owningPlayer(), &IGameEventsReceiver::artifactMoved, srcLoc, dstLoc);
if (srcLoc.owningPlayer() != dstLoc.owningPlayer()) if (srcLoc.owningPlayer() != dstLoc.owningPlayer())
callInterfaceIfPresent(cl, dstLoc.owningPlayer(), &IGameEventsReceiver::artifactMoved, srcLoc, dstLoc); callInterfaceIfPresent(cl, dstLoc.owningPlayer(), &IGameEventsReceiver::artifactMoved, srcLoc, dstLoc);

View File

@@ -1011,55 +1011,44 @@ struct MoveArtifact : CArtifactOperationPack
struct BulkMoveArtifacts : CArtifactOperationPack struct BulkMoveArtifacts : CArtifactOperationPack
{ {
struct HeroArtsToMove struct LinkedSlots
{ {
struct LinkedSlots ArtifactPosition srcPos;
{ ArtifactPosition dstPos;
ArtifactPosition srcPos;
ArtifactPosition dstPos;
LinkedSlots() {} LinkedSlots() {}
LinkedSlots(ArtifactPosition srcPos, ArtifactPosition dstPos) LinkedSlots(ArtifactPosition srcPos, ArtifactPosition dstPos)
: srcPos(srcPos), dstPos(dstPos) {} : srcPos(srcPos), dstPos(dstPos) {}
template <typename Handler> void serialize(Handler & h, const int version)
{
h & srcPos;
h & dstPos;
}
};
TArtHolder srcArtHolder;
TArtHolder dstArtHolder;
std::vector<LinkedSlots> slots;
CArtifactSet * getSrcHolderArtSet();
CArtifactSet * getDstHolderArtSet();
template <typename Handler> void serialize(Handler & h, const int version) template <typename Handler> void serialize(Handler & h, const int version)
{ {
h & srcArtHolder; h & srcPos;
h & dstArtHolder; h & dstPos;
h & slots;
} }
}; };
TArtHolder srcArtHolder;
TArtHolder dstArtHolder;
BulkMoveArtifacts() {} BulkMoveArtifacts() {}
BulkMoveArtifacts(TArtHolder srcArtHolder, TArtHolder dstArtHolder) BulkMoveArtifacts(TArtHolder srcArtHolder, TArtHolder dstArtHolder)
{ : srcArtHolder(srcArtHolder), dstArtHolder(dstArtHolder) {}
artsPack0.srcArtHolder = srcArtHolder;
artsPack0.dstArtHolder = dstArtHolder;
}
void applyCl(CClient * cl); void applyCl(CClient * cl);
DLL_LINKAGE void applyGs(CGameState * gs); DLL_LINKAGE void applyGs(CGameState * gs);
HeroArtsToMove artsPack0; std::vector<LinkedSlots> artsPack0;
// If the artsPack1 is present then make swap // If the artsPack1 is present then make swap
boost::optional<HeroArtsToMove> artsPack1; boost::optional<std::vector<LinkedSlots>> artsPack1;
CArtifactSet * getSrcHolderArtSet();
CArtifactSet * getDstHolderArtSet();
template <typename Handler> void serialize(Handler & h, const int version) template <typename Handler> void serialize(Handler & h, const int version)
{ {
h & artsPack0; h & artsPack0;
h & artsPack1; h & artsPack1;
h & srcArtHolder;
h & dstArtHolder;
} }
}; };

View File

@@ -1102,9 +1102,8 @@ DLL_LINKAGE void BulkMoveArtifacts::applyGs(CGameState * gs)
{ {
// Swap // Swap
auto & leftRightPack = artsPack0; auto & leftRightPack = artsPack0;
auto & rightLeftPack = artsPack1.value(); auto leftSet = getSrcHolderArtSet();
auto leftSet = leftRightPack.getSrcHolderArtSet(); auto rightSet = getDstHolderArtSet();
auto rightSet = leftRightPack.getDstHolderArtSet();
CArtifactFittingSet ArtFittingSet(leftSet->bearerType()); CArtifactFittingSet ArtFittingSet(leftSet->bearerType());
std::vector<std::pair<ArtifactPosition, ArtSlotInfo>> unmovableArtsLeftHero, unmovableArtsRightHero; std::vector<std::pair<ArtifactPosition, ArtSlotInfo>> unmovableArtsLeftHero, unmovableArtsRightHero;
@@ -1147,7 +1146,7 @@ DLL_LINKAGE void BulkMoveArtifacts::applyGs(CGameState * gs)
{ {
// Move // Move
auto & artsPack = artsPack0; auto & artsPack = artsPack0;
for (auto & slot : artsPack.slots) for (auto & slot : artsPack)
{ {
// When an object gets removed from the backpack, the backpack shrinks // When an object gets removed from the backpack, the backpack shrinks
// so all the following indices will be affected. Thus, we need to update // so all the following indices will be affected. Thus, we need to update
@@ -1156,16 +1155,12 @@ DLL_LINKAGE void BulkMoveArtifacts::applyGs(CGameState * gs)
{ {
slot.srcPos = ArtifactPosition(slot.srcPos.num - numBackpackArtifactsMoved); slot.srcPos = ArtifactPosition(slot.srcPos.num - numBackpackArtifactsMoved);
} }
auto srcSlotInfo = artsPack.getSrcHolderArtSet()->getSlot(slot.srcPos); auto srcSlotInfo = getSrcHolderArtSet()->getSlot(slot.srcPos);
auto dstSlotInfo = artsPack.getDstHolderArtSet()->getSlot(slot.dstPos);
if (slot.dstPos < GameConstants::BACKPACK_START)
assert(!dstSlotInfo->getArt());
assert(srcSlotInfo); assert(srcSlotInfo);
auto art = srcSlotInfo->getArt(); auto art = srcSlotInfo->getArt();
const_cast<CArtifactInstance*>(art)->move( const_cast<CArtifactInstance*>(art)->move(
ArtifactLocation(artsPack.srcArtHolder, slot.srcPos), ArtifactLocation(artsPack.dstArtHolder, slot.dstPos)); ArtifactLocation(srcArtHolder, slot.srcPos), ArtifactLocation(dstArtHolder, slot.dstPos));
if (slot.srcPos >= GameConstants::BACKPACK_START) if (slot.srcPos >= GameConstants::BACKPACK_START)
{ {
@@ -1788,12 +1783,12 @@ const CArtifactInstance * ArtSlotInfo::getArt() const
return nullptr; return nullptr;
} }
CArtifactSet * BulkMoveArtifacts::HeroArtsToMove::getSrcHolderArtSet() CArtifactSet * BulkMoveArtifacts::getSrcHolderArtSet()
{ {
return boost::apply_visitor(GetBase<CArtifactSet>(), srcArtHolder); return boost::apply_visitor(GetBase<CArtifactSet>(), srcArtHolder);
} }
CArtifactSet * BulkMoveArtifacts::HeroArtsToMove::getDstHolderArtSet() CArtifactSet * BulkMoveArtifacts::getDstHolderArtSet()
{ {
return boost::apply_visitor(GetBase<CArtifactSet>(), dstArtHolder); return boost::apply_visitor(GetBase<CArtifactSet>(), dstArtHolder);
} }

View File

@@ -3935,7 +3935,7 @@ bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID
auto pdstHero = getHero(dstHero); auto pdstHero = getHero(dstHero);
BulkMoveArtifacts ma(static_cast<ConstTransitivePtr<CGHeroInstance>>(psrcHero), BulkMoveArtifacts ma(static_cast<ConstTransitivePtr<CGHeroInstance>>(psrcHero),
static_cast<ConstTransitivePtr<CGHeroInstance>>(pdstHero)); static_cast<ConstTransitivePtr<CGHeroInstance>>(pdstHero));
auto slots = &ma.artsPack0.slots; auto slots = &ma.artsPack0;
// Temporary fitting set for artifacts. Used to select available slots before sending data. // Temporary fitting set for artifacts. Used to select available slots before sending data.
CArtifactFittingSet ArtFittingSet(pdstHero->bearerType()); CArtifactFittingSet ArtFittingSet(pdstHero->bearerType());
@@ -3951,8 +3951,7 @@ bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID
auto dstSlot = ArtifactUtils::getArtifactDstPosition(artifact, &ArtFittingSet, pdstHero->bearerType()); auto dstSlot = ArtifactUtils::getArtifactDstPosition(artifact, &ArtFittingSet, pdstHero->bearerType());
ArtFittingSet.putArtifact(dstSlot, ArtFittingSet.putArtifact(dstSlot,
static_cast<ConstTransitivePtr<CArtifactInstance>>(psrcHero->getArt(artInfo.first))); static_cast<ConstTransitivePtr<CArtifactInstance>>(psrcHero->getArt(artInfo.first)));
slots->push_back(BulkMoveArtifacts::HeroArtsToMove::LinkedSlots(artInfo.first, dstSlot)); slots->push_back(BulkMoveArtifacts::LinkedSlots(artInfo.first, dstSlot));
if (ArtifactUtils::checkSpellbookIsNeeded(pdstHero, artifact->artType->id, dstSlot)) if (ArtifactUtils::checkSpellbookIsNeeded(pdstHero, artifact->artType->id, dstSlot))
giveHeroNewArtifact(pdstHero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK); giveHeroNewArtifact(pdstHero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
@@ -3964,7 +3963,7 @@ bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID
auto artifact = psrcHero->getArt(psrcHero->getArtPos(slotInfo.artifact)); auto artifact = psrcHero->getArt(psrcHero->getArtPos(slotInfo.artifact));
auto dstSlot = ArtifactUtils::getArtifactDstPosition(artifact, &ArtFittingSet, pdstHero->bearerType()); auto dstSlot = ArtifactUtils::getArtifactDstPosition(artifact, &ArtFittingSet, pdstHero->bearerType());
ArtFittingSet.putArtifact(dstSlot, static_cast<ConstTransitivePtr<CArtifactInstance>>(slotInfo.artifact)); ArtFittingSet.putArtifact(dstSlot, static_cast<ConstTransitivePtr<CArtifactInstance>>(slotInfo.artifact));
slots->push_back(BulkMoveArtifacts::HeroArtsToMove::LinkedSlots(psrcHero->getArtPos(slotInfo.artifact), dstSlot)); slots->push_back(BulkMoveArtifacts::LinkedSlots(psrcHero->getArtPos(slotInfo.artifact), dstSlot));
if (ArtifactUtils::checkSpellbookIsNeeded(pdstHero, artifact->artType->id, dstSlot)) if (ArtifactUtils::checkSpellbookIsNeeded(pdstHero, artifact->artType->id, dstSlot))
giveHeroNewArtifact(pdstHero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK); giveHeroNewArtifact(pdstHero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
@@ -3983,14 +3982,14 @@ bool CGameHandler::bulkSwapArtifacts(ObjectInstanceID leftHero, ObjectInstanceID
auto prightHero = getHero(rightHero); auto prightHero = getHero(rightHero);
BulkMoveArtifacts ma(static_cast<ConstTransitivePtr<CGHeroInstance>>(pleftHero), BulkMoveArtifacts ma(static_cast<ConstTransitivePtr<CGHeroInstance>>(pleftHero),
static_cast<ConstTransitivePtr<CGHeroInstance>>(prightHero)); static_cast<ConstTransitivePtr<CGHeroInstance>>(prightHero));
ma.artsPack1 = BulkMoveArtifacts::HeroArtsToMove(); ma.artsPack1 = std::vector<BulkMoveArtifacts::LinkedSlots>();
ma.artsPack1.value().srcArtHolder = static_cast<ConstTransitivePtr<CGHeroInstance>>(prightHero); ma.srcArtHolder = static_cast<ConstTransitivePtr<CGHeroInstance>>(prightHero);
ma.artsPack1.value().dstArtHolder = static_cast<ConstTransitivePtr<CGHeroInstance>>(pleftHero); ma.dstArtHolder = static_cast<ConstTransitivePtr<CGHeroInstance>>(pleftHero);
auto slotsLeftRight = &ma.artsPack0.slots; auto slotsLeftRight = &ma.artsPack0;
auto slotsRightLeft = &ma.artsPack1.value().slots; auto slotsRightLeft = &ma.artsPack1.value();
auto moveArtsWorn = [this](const CGHeroInstance * srcHero, const CGHeroInstance * dstHero, auto moveArtsWorn = [this](const CGHeroInstance * srcHero, const CGHeroInstance * dstHero,
std::vector<BulkMoveArtifacts::HeroArtsToMove::LinkedSlots> * slots) -> void std::vector<BulkMoveArtifacts::LinkedSlots> * slots) -> void
{ {
for (auto & artifact : srcHero->artifactsWorn) for (auto & artifact : srcHero->artifactsWorn)
{ {
@@ -3998,7 +3997,7 @@ bool CGameHandler::bulkSwapArtifacts(ObjectInstanceID leftHero, ObjectInstanceID
continue; continue;
if (!ArtifactUtils::isArtRemovable(artifact)) if (!ArtifactUtils::isArtRemovable(artifact))
continue; continue;
slots->push_back(BulkMoveArtifacts::HeroArtsToMove::LinkedSlots(artifact.first, artifact.first)); slots->push_back(BulkMoveArtifacts::LinkedSlots(artifact.first, artifact.first));
if (ArtifactUtils::checkSpellbookIsNeeded(dstHero, artifact.second.getArt()->artType->id, artifact.first)) if (ArtifactUtils::checkSpellbookIsNeeded(dstHero, artifact.second.getArt()->artType->id, artifact.first))
giveHeroNewArtifact(dstHero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK); giveHeroNewArtifact(dstHero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
@@ -4012,13 +4011,13 @@ bool CGameHandler::bulkSwapArtifacts(ObjectInstanceID leftHero, ObjectInstanceID
for (auto & slotInfo : pleftHero->artifactsInBackpack) for (auto & slotInfo : pleftHero->artifactsInBackpack)
{ {
auto slot = pleftHero->getArtPos(slotInfo.artifact); auto slot = pleftHero->getArtPos(slotInfo.artifact);
slotsLeftRight->push_back(BulkMoveArtifacts::HeroArtsToMove::LinkedSlots(slot, slot)); slotsLeftRight->push_back(BulkMoveArtifacts::LinkedSlots(slot, slot));
} }
// Move over artifacts that are in backpack rightHero -> leftHero // Move over artifacts that are in backpack rightHero -> leftHero
for (auto & slotInfo : prightHero->artifactsInBackpack) for (auto & slotInfo : prightHero->artifactsInBackpack)
{ {
auto slot = prightHero->getArtPos(slotInfo.artifact); auto slot = prightHero->getArtPos(slotInfo.artifact);
slotsRightLeft->push_back(BulkMoveArtifacts::HeroArtsToMove::LinkedSlots(slot, slot)); slotsRightLeft->push_back(BulkMoveArtifacts::LinkedSlots(slot, slot));
} }
sendAndApply(&ma); sendAndApply(&ma);
return true; return true;