1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-10-31 00:07:39 +02:00

ManageBackpackArtifacts

This commit is contained in:
SoundSSGood
2024-03-06 15:16:35 +02:00
parent d143f53d7e
commit b1f52eec41
18 changed files with 110 additions and 33 deletions

View File

@@ -180,6 +180,14 @@ void CCallback::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dst
sendRequest(&bma);
}
void CCallback::scrollBackpackArtifacts(ObjectInstanceID hero, bool left)
{
ManageBackpackArtifacts mba(hero, ManageBackpackArtifacts::ManageCmd::SCROLL_RIGHT);
if(left)
mba.cmd = ManageBackpackArtifacts::ManageCmd::SCROLL_LEFT;
sendRequest(&mba);
}
void CCallback::eraseArtifactByClient(const ArtifactLocation & al)
{
EraseArtifactByClient ea(al);

View File

@@ -90,6 +90,7 @@ public:
virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2, int val)=0;//split creatures from the first stack
//virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes
virtual bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2)=0;
virtual void scrollBackpackArtifacts(ObjectInstanceID hero, bool left) = 0;
virtual void assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)=0;
virtual void eraseArtifactByClient(const ArtifactLocation & al)=0;
virtual bool dismissCreature(const CArmedInstance *obj, SlotID stackPos)=0;
@@ -174,6 +175,7 @@ public:
bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2) override;
void assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo) override;
void bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap, bool equipped = true, bool backpack = true) override;
void scrollBackpackArtifacts(ObjectInstanceID hero, bool left) override;
void eraseArtifactByClient(const ArtifactLocation & al) override;
bool buildBuilding(const CGTownInstance *town, BuildingID buildingID) override;
void recruitCreatures(const CGDwelling * obj, const CArmedInstance * dst, CreatureID ID, ui32 amount, si32 level=-1) override;

View File

@@ -290,7 +290,7 @@ void ApplyClientNetPackVisitor::visitMoveArtifact(MoveArtifact & pack)
callInterfaceIfPresent(cl, player, &IGameEventsReceiver::askToAssembleArtifact, pack.dst);
};
moveArtifact(cl.getOwner(pack.src.artHolder));
moveArtifact(LOCPLINT->playerID);
if(cl.getOwner(pack.src.artHolder) != cl.getOwner(pack.dst.artHolder))
moveArtifact(cl.getOwner(pack.dst.artHolder));

View File

@@ -24,7 +24,7 @@ class CArtifactsOfHeroBackpack : public CArtifactsOfHeroBase
public:
CArtifactsOfHeroBackpack(size_t slotsColumnsMax, size_t slotsRowsMax);
CArtifactsOfHeroBackpack();
void scrollBackpack(int offset) override;
void scrollBackpack(int offset);
void updateBackpackSlots() override;
size_t getActiveSlotRowsNum();
size_t getSlotsNum();

View File

@@ -87,9 +87,9 @@ void CArtifactsOfHeroBase::init(
artPlace->setShowPopupCallback(showPopupCallback);
}
leftBackpackRoll = std::make_shared<CButton>(Point(379, 364), AnimationPath::builtin("hsbtns3.def"), CButton::tooltip(),
[scrollCallback](){scrollCallback(-1);}, EShortcut::MOVE_LEFT);
[scrollCallback](){scrollCallback(true);}, EShortcut::MOVE_LEFT);
rightBackpackRoll = std::make_shared<CButton>(Point(632, 364), AnimationPath::builtin("hsbtns5.def"), CButton::tooltip(),
[scrollCallback](){scrollCallback(+1);}, EShortcut::MOVE_RIGHT);
[scrollCallback](){scrollCallback(false);}, EShortcut::MOVE_RIGHT);
leftBackpackRoll->block(true);
rightBackpackRoll->block(true);
@@ -130,30 +130,9 @@ const CGHeroInstance * CArtifactsOfHeroBase::getHero() const
return curHero;
}
void CArtifactsOfHeroBase::scrollBackpack(int offset)
void CArtifactsOfHeroBase::scrollBackpack(bool left)
{
const ArtifactLocation beginLoc = ArtifactLocation(curHero->id, ArtifactPosition::BACKPACK_START);
const ArtifactLocation endLoc = ArtifactLocation(curHero->id, ArtifactPosition(ArtifactPosition::BACKPACK_START + curHero->artifactsInBackpack.size() - 1));
// To right by default
ArtifactLocation const * srcLoc = &beginLoc;
ArtifactLocation const * dstLoc = &endLoc;
if(offset < 0)
{
// To left
srcLoc = &endLoc;
dstLoc = &beginLoc;
offset = -offset;
}
for(auto step = 0; step < offset; step++)
LOCPLINT->cb->swapArtifacts(*srcLoc, *dstLoc);
ArtifactPosition slot = ArtifactPosition::BACKPACK_START;
for(auto artPlace : backpack)
{
setSlotData(artPlace, slot);
slot = slot + 1;
}
LOCPLINT->cb->scrollBackpackArtifacts(curHero->id, left);
}
void CArtifactsOfHeroBase::markPossibleSlots(const CArtifactInstance * art, bool assumeDestRemoved)
@@ -203,7 +182,12 @@ void CArtifactsOfHeroBase::updateWornSlots()
void CArtifactsOfHeroBase::updateBackpackSlots()
{
scrollBackpack(0);
ArtifactPosition slot = ArtifactPosition::BACKPACK_START;
for(auto & artPlace : backpack)
{
setSlotData(artPlace, slot);
slot = slot + 1;
}
auto scrollingPossible = static_cast<int>(curHero->artifactsInBackpack.size()) > backpack.size();
// Blocking scrolling if there is not enough artifacts to scroll
if(leftBackpackRoll)

View File

@@ -36,7 +36,7 @@ public:
virtual void gestureArtPlace(CArtPlace & artPlace, const Point & cursorPosition);
virtual void setHero(const CGHeroInstance * hero);
virtual const CGHeroInstance * getHero() const;
virtual void scrollBackpack(int offset);
virtual void scrollBackpack(bool left);
virtual void markPossibleSlots(const CArtifactInstance * art, bool assumeDestRemoved = true);
virtual void unmarkSlots();
virtual ArtPlacePtr getArtPlace(const ArtifactPosition & slot);

View File

@@ -26,9 +26,9 @@ CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position)
artPlace->setSelectionWidth(2);
};
void CArtifactsOfHeroMarket::scrollBackpack(int offset)
void CArtifactsOfHeroMarket::scrollBackpack(bool left)
{
CArtifactsOfHeroBase::scrollBackpack(offset);
CArtifactsOfHeroBase::scrollBackpack(left);
// We may have highlight on one of backpack artifacts
if(selectArtCallback)

View File

@@ -17,5 +17,5 @@ public:
std::function<void(CArtPlace*)> selectArtCallback;
CArtifactsOfHeroMarket(const Point & position);
void scrollBackpack(int offset) override;
void scrollBackpack(bool left) override;
};

View File

@@ -145,7 +145,11 @@ void CWindowWithArtifacts::clickPressedArtPlaceHero(CArtifactsOfHeroBase & artsI
if(artSetPtr->getHero()->getOwner() == LOCPLINT->playerID)
{
if(checkSpecialArts(*art, hero, std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroAltar>> ? true : false))
LOCPLINT->cb->swapArtifacts(ArtifactLocation(artSetPtr->getHero()->id, artPlace.slot), ArtifactLocation(artSetPtr->getHero()->id, ArtifactPosition::TRANSITION_POS));
{
assert(artSetPtr->getHero()->getSlotByInstance(art));
LOCPLINT->cb->swapArtifacts(ArtifactLocation(artSetPtr->getHero()->id, artSetPtr->getHero()->getSlotByInstance(art)),
ArtifactLocation(artSetPtr->getHero()->id, ArtifactPosition::TRANSITION_POS));
}
}
else
{

View File

@@ -131,6 +131,7 @@ public:
virtual void visitGarrisonHeroSwap(GarrisonHeroSwap & pack) {}
virtual void visitExchangeArtifacts(ExchangeArtifacts & pack) {}
virtual void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) {}
virtual void visitManageBackpackArtifacts(ManageBackpackArtifacts & pack) {}
virtual void visitAssembleArtifacts(AssembleArtifacts & pack) {}
virtual void visitEraseArtifactByClient(EraseArtifactByClient & pack) {}
virtual void visitBuyArtifact(BuyArtifact & pack) {}

View File

@@ -608,6 +608,11 @@ void BulkExchangeArtifacts::visitTyped(ICPackVisitor & visitor)
visitor.visitBulkExchangeArtifacts(*this);
}
void ManageBackpackArtifacts::visitTyped(ICPackVisitor & visitor)
{
visitor.visitManageBackpackArtifacts(*this);
}
void AssembleArtifacts::visitTyped(ICPackVisitor & visitor)
{
visitor.visitAssembleArtifacts(*this);

View File

@@ -401,6 +401,33 @@ struct DLL_LINKAGE BulkExchangeArtifacts : public CPackForServer
}
};
struct DLL_LINKAGE ManageBackpackArtifacts : public CPackForServer
{
enum class ManageCmd
{
SCROLL_LEFT, SCROLL_RIGHT, SORT_BY_SLOT, SORT_BY_CLASS, SORT_BY_COST
};
ManageBackpackArtifacts() = default;
ManageBackpackArtifacts(const ObjectInstanceID & artHolder, const ManageCmd & cmd)
: artHolder(artHolder)
, cmd(cmd)
{
}
ObjectInstanceID artHolder;
ManageCmd cmd;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h)
{
h & static_cast<CPackForServer&>(*this);
h & artHolder;
h & cmd;
}
};
struct DLL_LINKAGE AssembleArtifacts : public CPackForServer
{
AssembleArtifacts() = default;

View File

@@ -49,6 +49,7 @@ void registerTypesServerPacks(Serializer &s)
s.template registerType<CPackForServer, BulkSmartSplitStack>();
s.template registerType<CPackForServer, BulkMoveArmy>();
s.template registerType<CPackForServer, BulkExchangeArtifacts>();
s.template registerType < CPackForServer, ManageBackpackArtifacts>();
s.template registerType<CPackForServer, EraseArtifactByClient>();
s.template registerType<CPackForServer, GamePause>();
}

View File

@@ -2857,6 +2857,25 @@ bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcId, ObjectInstanceID ds
return true;
}
bool CGameHandler::scrollBackpackArtifacts(const ObjectInstanceID heroID, bool left)
{
auto artSet = getArtSet(heroID);
COMPLAIN_RET_FALSE_IF(artSet == nullptr, "scrollBackpackArtifacts: wrong hero's ID");
BulkMoveArtifacts bma(heroID, heroID, false);
const auto backpackEnd = ArtifactPosition(ArtifactPosition::BACKPACK_START + artSet->artifactsInBackpack.size() - 1);
if(backpackEnd > ArtifactPosition::BACKPACK_START)
{
if(left)
bma.artsPack0.push_back(BulkMoveArtifacts::LinkedSlots(backpackEnd, ArtifactPosition::BACKPACK_START));
else
bma.artsPack0.push_back(BulkMoveArtifacts::LinkedSlots(ArtifactPosition::BACKPACK_START, backpackEnd));
sendAndApply(&bma);
}
return true;
}
/**
* Assembles or disassembles a combination artifact.
* @param heroID ID of hero holding the artifact(s).

View File

@@ -130,6 +130,7 @@ public:
void removeArtifact(const ArtifactLocation &al) override;
bool moveArtifact(const ArtifactLocation & src, const ArtifactLocation & dst) override;
bool bulkMoveArtifacts(ObjectInstanceID srcId, ObjectInstanceID dstId, bool swap, bool equipped, bool backpack);
bool scrollBackpackArtifacts(const ObjectInstanceID heroID, bool left);
bool eraseArtifactByClient(const ArtifactLocation & al);
void synchronizeArtifactHandlerLists();

View File

@@ -148,6 +148,27 @@ void ApplyGhNetPackVisitor::visitBulkExchangeArtifacts(BulkExchangeArtifacts & p
result = gh.bulkMoveArtifacts(pack.srcHero, pack.dstHero, pack.swap, pack.equipped, pack.backpack);
}
void ApplyGhNetPackVisitor::visitManageBackpackArtifacts(ManageBackpackArtifacts & pack)
{
if(gh.getPlayerRelations(pack.player, gh.getOwner(pack.artHolder)) != PlayerRelations::ENEMIES)
{
if(pack.cmd == ManageBackpackArtifacts::ManageCmd::SCROLL_LEFT)
result = gh.scrollBackpackArtifacts(pack.artHolder, true);
else if(pack.cmd == ManageBackpackArtifacts::ManageCmd::SCROLL_RIGHT)
result = gh.scrollBackpackArtifacts(pack.artHolder, false);
else
{
gh.throwIfWrongOwner(&pack, pack.artHolder);
if(pack.cmd == ManageBackpackArtifacts::ManageCmd::SORT_BY_CLASS)
result = true;
else if(pack.cmd == ManageBackpackArtifacts::ManageCmd::SORT_BY_COST)
result = true;
else if(pack.cmd == ManageBackpackArtifacts::ManageCmd::SORT_BY_SLOT)
result = true;
}
}
}
void ApplyGhNetPackVisitor::visitAssembleArtifacts(AssembleArtifacts & pack)
{
gh.throwIfWrongOwner(&pack, pack.heroID);

View File

@@ -46,6 +46,7 @@ public:
void visitGarrisonHeroSwap(GarrisonHeroSwap & pack) override;
void visitExchangeArtifacts(ExchangeArtifacts & pack) override;
void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) override;
void visitManageBackpackArtifacts(ManageBackpackArtifacts & pack) override;
void visitAssembleArtifacts(AssembleArtifacts & pack) override;
void visitEraseArtifactByClient(EraseArtifactByClient & pack) override;
void visitBuyArtifact(BuyArtifact & pack) override;

View File

@@ -128,6 +128,9 @@ bool CGarrisonDialogQuery::blocksPack(const CPack * pack) const
if(auto arts = dynamic_ptr_cast<BulkExchangeArtifacts>(pack))
return !vstd::contains(ourIds, arts->srcHero) || !vstd::contains(ourIds, arts->dstHero);
if(auto arts = dynamic_ptr_cast<ManageBackpackArtifacts>(pack))
return !vstd::contains(ourIds, arts->artHolder);
if(auto art = dynamic_ptr_cast<EraseArtifactByClient>(pack))
{
if(auto id = art->al.artHolder)