mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Merge pull request #3656 from SoundSSGood/backpack-management
Backpack management init
This commit is contained in:
commit
6a5696604e
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -191,7 +191,7 @@ public:
|
||||
bool giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact * artType, ArtifactPosition pos) override {return false;}
|
||||
bool putArtifact(const ArtifactLocation & al, const CArtifactInstance * art, std::optional<bool> askAssemble) override {return false;};
|
||||
void removeArtifact(const ArtifactLocation & al) override {};
|
||||
bool moveArtifact(const ArtifactLocation & al1, const ArtifactLocation & al2) override {return false;};
|
||||
bool moveArtifact(const PlayerColor & player, const ArtifactLocation & al1, const ArtifactLocation & al2) override {return false;};
|
||||
|
||||
void heroVisitCastle(const CGTownInstance * obj, const CGHeroInstance * hero) override {};
|
||||
void visitCastleObjects(const CGTownInstance * obj, const CGHeroInstance * hero) override {};
|
||||
|
@ -290,8 +290,8 @@ void ApplyClientNetPackVisitor::visitMoveArtifact(MoveArtifact & pack)
|
||||
callInterfaceIfPresent(cl, player, &IGameEventsReceiver::askToAssembleArtifact, pack.dst);
|
||||
};
|
||||
|
||||
moveArtifact(cl.getOwner(pack.src.artHolder));
|
||||
if(cl.getOwner(pack.src.artHolder) != cl.getOwner(pack.dst.artHolder))
|
||||
moveArtifact(pack.interfaceOwner);
|
||||
if(pack.interfaceOwner != cl.getOwner(pack.dst.artHolder))
|
||||
moveArtifact(cl.getOwner(pack.dst.artHolder));
|
||||
|
||||
cl.invalidatePaths(); // hero might have equipped/unequipped Angel Wings
|
||||
@ -305,7 +305,7 @@ void ApplyClientNetPackVisitor::visitBulkMoveArtifacts(BulkMoveArtifacts & pack)
|
||||
{
|
||||
auto srcLoc = ArtifactLocation(pack.srcArtHolder, slotToMove.srcPos);
|
||||
auto dstLoc = ArtifactLocation(pack.dstArtHolder, slotToMove.dstPos);
|
||||
MoveArtifact ma(&srcLoc, &dstLoc, pack.askAssemble);
|
||||
MoveArtifact ma(pack.interfaceOwner, srcLoc, dstLoc, pack.askAssemble);
|
||||
visitMoveArtifact(ma);
|
||||
}
|
||||
};
|
||||
|
@ -25,7 +25,7 @@ CArtifactsOfHeroAltar::CArtifactsOfHeroAltar(const Point & position)
|
||||
std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2),
|
||||
std::bind(&CArtifactsOfHeroBase::showPopupArtPlace, this, _1, _2),
|
||||
position,
|
||||
std::bind(&CArtifactsOfHeroAltar::scrollBackpack, this, _1));
|
||||
std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, _1));
|
||||
|
||||
// The backpack is in the altar window above and to the right
|
||||
for(auto & slot : backpack)
|
||||
|
@ -26,6 +26,7 @@
|
||||
CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack(size_t slotsColumnsMax, size_t slotsRowsMax)
|
||||
: slotsColumnsMax(slotsColumnsMax)
|
||||
, slotsRowsMax(slotsRowsMax)
|
||||
, backpackPos(0)
|
||||
{
|
||||
setRedrawParent(true);
|
||||
}
|
||||
@ -41,11 +42,11 @@ CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack()
|
||||
initAOHbackpack(visibleCapacityMax, backpackCap < 0 || visibleCapacityMax < backpackCap);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBackpack::scrollBackpack(int offset)
|
||||
void CArtifactsOfHeroBackpack::onSliderMoved(int newVal)
|
||||
{
|
||||
if(backpackListBox)
|
||||
backpackListBox->resize(getActiveSlotRowsNum());
|
||||
backpackPos += offset;
|
||||
backpackPos += newVal;
|
||||
auto slot = ArtifactPosition::BACKPACK_START + backpackPos;
|
||||
for(auto artPlace : backpack)
|
||||
{
|
||||
@ -98,7 +99,7 @@ void CArtifactsOfHeroBackpack::initAOHbackpack(size_t slots, bool slider)
|
||||
};
|
||||
CListBoxWithCallback::MovedPosCallback posMoved = [this](size_t pos) -> void
|
||||
{
|
||||
scrollBackpack(static_cast<int>(pos) * slotsColumnsMax - backpackPos);
|
||||
onSliderMoved(static_cast<int>(pos) * slotsColumnsMax - backpackPos);
|
||||
};
|
||||
backpackListBox = std::make_shared<CListBoxWithCallback>(
|
||||
posMoved, onCreate, Point(0, 0), Point(0, 0), slotsRowsMax, 0, 0, 1,
|
||||
|
@ -24,7 +24,7 @@ class CArtifactsOfHeroBackpack : public CArtifactsOfHeroBase
|
||||
public:
|
||||
CArtifactsOfHeroBackpack(size_t slotsColumnsMax, size_t slotsRowsMax);
|
||||
CArtifactsOfHeroBackpack();
|
||||
void scrollBackpack(int offset) override;
|
||||
void onSliderMoved(int newVal);
|
||||
void updateBackpackSlots() override;
|
||||
size_t getActiveSlotRowsNum();
|
||||
size_t getSlotsNum();
|
||||
@ -36,6 +36,7 @@ protected:
|
||||
size_t slotsRowsMax;
|
||||
const int slotSizeWithMargin = 46;
|
||||
const int sliderPosOffsetX = 5;
|
||||
int backpackPos; // Position to display artifacts in heroes backpack
|
||||
|
||||
void initAOHbackpack(size_t slots, bool slider);
|
||||
size_t calcRows(size_t slots);
|
||||
|
@ -25,8 +25,7 @@
|
||||
#include "../../lib/networkPacks/ArtifactLocation.h"
|
||||
|
||||
CArtifactsOfHeroBase::CArtifactsOfHeroBase()
|
||||
: backpackPos(0),
|
||||
curHero(nullptr),
|
||||
: curHero(nullptr),
|
||||
putBackPickedArtCallback(nullptr)
|
||||
{
|
||||
}
|
||||
@ -56,10 +55,10 @@ void CArtifactsOfHeroBase::setPutBackPickedArtifactCallback(PutBackPickedArtCall
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::init(
|
||||
CArtPlace::ClickFunctor lClickCallback,
|
||||
CArtPlace::ClickFunctor showPopupCallback,
|
||||
const CArtPlace::ClickFunctor & onClickPressedCallback,
|
||||
const CArtPlace::ClickFunctor & onShowPopupCallback,
|
||||
const Point & position,
|
||||
BpackScrollFunctor scrollCallback)
|
||||
const BpackScrollFunctor & scrollCallback)
|
||||
{
|
||||
// CArtifactsOfHeroBase::init may be transform to CArtifactsOfHeroBase::CArtifactsOfHeroBase if OBJECT_CONSTRUCTION_CAPTURING is removed
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
@ -78,17 +77,19 @@ void CArtifactsOfHeroBase::init(
|
||||
{
|
||||
artPlace.second->slot = artPlace.first;
|
||||
artPlace.second->setArtifact(nullptr);
|
||||
artPlace.second->setClickPressedCallback(lClickCallback);
|
||||
artPlace.second->setShowPopupCallback(showPopupCallback);
|
||||
artPlace.second->setClickPressedCallback(onClickPressedCallback);
|
||||
artPlace.second->setShowPopupCallback(onShowPopupCallback);
|
||||
}
|
||||
for(auto artPlace : backpack)
|
||||
{
|
||||
artPlace->setArtifact(nullptr);
|
||||
artPlace->setClickPressedCallback(lClickCallback);
|
||||
artPlace->setShowPopupCallback(showPopupCallback);
|
||||
artPlace->setClickPressedCallback(onClickPressedCallback);
|
||||
artPlace->setShowPopupCallback(onShowPopupCallback);
|
||||
}
|
||||
leftBackpackRoll = std::make_shared<CButton>(Point(379, 364), AnimationPath::builtin("hsbtns3.def"), CButton::tooltip(), [scrollCallback]() {scrollCallback(-1);}, EShortcut::MOVE_LEFT);
|
||||
rightBackpackRoll = std::make_shared<CButton>(Point(632, 364), AnimationPath::builtin("hsbtns5.def"), CButton::tooltip(), [scrollCallback]() {scrollCallback(+1);}, EShortcut::MOVE_RIGHT);
|
||||
leftBackpackRoll = std::make_shared<CButton>(Point(379, 364), AnimationPath::builtin("hsbtns3.def"), CButton::tooltip(),
|
||||
[scrollCallback](){scrollCallback(true);}, EShortcut::MOVE_LEFT);
|
||||
rightBackpackRoll = std::make_shared<CButton>(Point(632, 364), AnimationPath::builtin("hsbtns5.def"), CButton::tooltip(),
|
||||
[scrollCallback](){scrollCallback(false);}, EShortcut::MOVE_RIGHT);
|
||||
leftBackpackRoll->block(true);
|
||||
rightBackpackRoll->block(true);
|
||||
|
||||
@ -116,16 +117,12 @@ void CArtifactsOfHeroBase::gestureArtPlace(CArtPlace & artPlace, const Point & c
|
||||
void CArtifactsOfHeroBase::setHero(const CGHeroInstance * hero)
|
||||
{
|
||||
curHero = hero;
|
||||
if(curHero->artifactsInBackpack.size() > 0)
|
||||
backpackPos %= curHero->artifactsInBackpack.size();
|
||||
else
|
||||
backpackPos = 0;
|
||||
|
||||
for(auto slot : artWorn)
|
||||
{
|
||||
setSlotData(slot.second, slot.first);
|
||||
}
|
||||
scrollBackpack(0);
|
||||
updateBackpackSlots();
|
||||
}
|
||||
|
||||
const CGHeroInstance * CArtifactsOfHeroBase::getHero() const
|
||||
@ -133,48 +130,9 @@ const CGHeroInstance * CArtifactsOfHeroBase::getHero() const
|
||||
return curHero;
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::scrollBackpack(int offset)
|
||||
void CArtifactsOfHeroBase::scrollBackpack(bool left)
|
||||
{
|
||||
// offset==-1 => to left; offset==1 => to right
|
||||
using slotInc = std::function<ArtifactPosition(ArtifactPosition&)>;
|
||||
auto artsInBackpack = static_cast<int>(curHero->artifactsInBackpack.size());
|
||||
auto scrollingPossible = artsInBackpack > backpack.size();
|
||||
|
||||
slotInc inc_straight = [](ArtifactPosition & slot) -> ArtifactPosition
|
||||
{
|
||||
return slot + 1;
|
||||
};
|
||||
slotInc inc_ring = [artsInBackpack](ArtifactPosition & slot) -> ArtifactPosition
|
||||
{
|
||||
return ArtifactPosition::BACKPACK_START + (slot - ArtifactPosition::BACKPACK_START + 1) % artsInBackpack;
|
||||
};
|
||||
slotInc inc;
|
||||
if(scrollingPossible)
|
||||
inc = inc_ring;
|
||||
else
|
||||
inc = inc_straight;
|
||||
|
||||
backpackPos += offset;
|
||||
if(backpackPos < 0)
|
||||
backpackPos += artsInBackpack;
|
||||
|
||||
if(artsInBackpack)
|
||||
backpackPos %= artsInBackpack;
|
||||
|
||||
auto slot = ArtifactPosition(ArtifactPosition::BACKPACK_START + backpackPos);
|
||||
for(auto artPlace : backpack)
|
||||
{
|
||||
setSlotData(artPlace, slot);
|
||||
slot = inc(slot);
|
||||
}
|
||||
|
||||
// Blocking scrolling if there is not enough artifacts to scroll
|
||||
if(leftBackpackRoll)
|
||||
leftBackpackRoll->block(!scrollingPossible);
|
||||
if(rightBackpackRoll)
|
||||
rightBackpackRoll->block(!scrollingPossible);
|
||||
|
||||
redraw();
|
||||
LOCPLINT->cb->scrollBackpackArtifacts(curHero->id, left);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::markPossibleSlots(const CArtifactInstance * art, bool assumeDestRemoved)
|
||||
@ -224,9 +182,18 @@ void CArtifactsOfHeroBase::updateWornSlots()
|
||||
|
||||
void CArtifactsOfHeroBase::updateBackpackSlots()
|
||||
{
|
||||
if(curHero->artifactsInBackpack.size() <= backpack.size() && backpackPos != 0)
|
||||
backpackPos = 0;
|
||||
scrollBackpack(0);
|
||||
ArtifactPosition slot = ArtifactPosition::BACKPACK_START;
|
||||
for(const 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)
|
||||
leftBackpackRoll->block(!scrollingPossible);
|
||||
if(rightBackpackRoll)
|
||||
rightBackpackRoll->block(!scrollingPossible);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::updateSlot(const ArtifactPosition & slot)
|
||||
|
@ -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);
|
||||
@ -52,7 +52,6 @@ protected:
|
||||
std::vector<ArtPlacePtr> backpack;
|
||||
std::shared_ptr<CButton> leftBackpackRoll;
|
||||
std::shared_ptr<CButton> rightBackpackRoll;
|
||||
int backpackPos; // Position to display artifacts in heroes backpack
|
||||
PutBackPickedArtCallback putBackPickedArtCallback;
|
||||
|
||||
const std::vector<Point> slotPos =
|
||||
@ -66,8 +65,8 @@ protected:
|
||||
Point(381,295) //18
|
||||
};
|
||||
|
||||
virtual void init(CHeroArtPlace::ClickFunctor lClickCallback, CHeroArtPlace::ClickFunctor showPopupCallback,
|
||||
const Point & position, BpackScrollFunctor scrollCallback);
|
||||
virtual void init(const CHeroArtPlace::ClickFunctor & lClickCallback, const CHeroArtPlace::ClickFunctor & showPopupCallback,
|
||||
const Point & position, const BpackScrollFunctor & scrollCallback);
|
||||
// Assigns an artifacts to an artifact place depending on it's new slot ID
|
||||
virtual void setSlotData(ArtPlacePtr artPlace, const ArtifactPosition & slot);
|
||||
};
|
||||
|
@ -18,7 +18,7 @@ CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position)
|
||||
std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2),
|
||||
std::bind(&CArtifactsOfHeroBase::showPopupArtPlace, this, _1, _2),
|
||||
position,
|
||||
std::bind(&CArtifactsOfHeroMarket::scrollBackpack, this, _1));
|
||||
std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, _1));
|
||||
|
||||
for(const auto & [slot, artPlace] : artWorn)
|
||||
artPlace->setSelectionWidth(2);
|
||||
@ -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)
|
||||
|
@ -17,5 +17,5 @@ public:
|
||||
std::function<void(CArtPlace*)> selectArtCallback;
|
||||
|
||||
CArtifactsOfHeroMarket(const Point & position);
|
||||
void scrollBackpack(int offset) override;
|
||||
void scrollBackpack(bool left) override;
|
||||
};
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -192,7 +192,7 @@ class DLL_LINKAGE CArtifactSet
|
||||
public:
|
||||
using ArtPlacementMap = std::map<CArtifactInstance*, ArtifactPosition>;
|
||||
|
||||
std::vector<ArtSlotInfo> artifactsInBackpack; //hero's artifacts from bag
|
||||
std::deque<ArtSlotInfo> artifactsInBackpack; //hero's artifacts from bag
|
||||
std::map<ArtifactPosition, ArtSlotInfo> artifactsWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
|
||||
std::vector<ArtSlotInfo> artifactsTransitionPos; // Used as transition position for dragAndDrop artifact exchange
|
||||
|
||||
|
@ -110,7 +110,7 @@ public:
|
||||
virtual bool giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact * artType, ArtifactPosition pos) = 0;
|
||||
virtual bool putArtifact(const ArtifactLocation & al, const CArtifactInstance * art, std::optional<bool> askAssemble = std::nullopt) = 0;
|
||||
virtual void removeArtifact(const ArtifactLocation &al) = 0;
|
||||
virtual bool moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) = 0;
|
||||
virtual bool moveArtifact(const PlayerColor & player, const ArtifactLocation & al1, const ArtifactLocation & al2) = 0;
|
||||
|
||||
virtual void heroVisitCastle(const CGTownInstance * obj, const CGHeroInstance * hero)=0;
|
||||
virtual void visitCastleObjects(const CGTownInstance * obj, const CGHeroInstance * hero)=0;
|
||||
|
@ -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) {}
|
||||
|
@ -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);
|
||||
|
@ -1030,10 +1030,11 @@ struct DLL_LINKAGE EraseArtifact : CArtifactOperationPack
|
||||
struct DLL_LINKAGE MoveArtifact : CArtifactOperationPack
|
||||
{
|
||||
MoveArtifact() = default;
|
||||
MoveArtifact(ArtifactLocation * src, ArtifactLocation * dst, bool askAssemble = true)
|
||||
: src(*src), dst(*dst), askAssemble(askAssemble)
|
||||
MoveArtifact(const PlayerColor & interfaceOwner, const ArtifactLocation & src, const ArtifactLocation & dst, bool askAssemble = true)
|
||||
: interfaceOwner(interfaceOwner), src(src), dst(dst), askAssemble(askAssemble)
|
||||
{
|
||||
}
|
||||
PlayerColor interfaceOwner;
|
||||
ArtifactLocation src;
|
||||
ArtifactLocation dst;
|
||||
bool askAssemble = true;
|
||||
@ -1043,6 +1044,7 @@ struct DLL_LINKAGE MoveArtifact : CArtifactOperationPack
|
||||
|
||||
template <typename Handler> void serialize(Handler & h)
|
||||
{
|
||||
h & interfaceOwner;
|
||||
h & src;
|
||||
h & dst;
|
||||
h & askAssemble;
|
||||
@ -1069,13 +1071,15 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
|
||||
}
|
||||
};
|
||||
|
||||
PlayerColor interfaceOwner;
|
||||
ObjectInstanceID srcArtHolder;
|
||||
ObjectInstanceID dstArtHolder;
|
||||
std::optional<SlotID> srcCreature;
|
||||
std::optional<SlotID> dstCreature;
|
||||
|
||||
BulkMoveArtifacts()
|
||||
: srcArtHolder(ObjectInstanceID::NONE)
|
||||
: interfaceOwner(PlayerColor::NEUTRAL)
|
||||
, srcArtHolder(ObjectInstanceID::NONE)
|
||||
, dstArtHolder(ObjectInstanceID::NONE)
|
||||
, swap(false)
|
||||
, askAssemble(false)
|
||||
@ -1083,9 +1087,10 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
|
||||
, dstCreature(std::nullopt)
|
||||
{
|
||||
}
|
||||
BulkMoveArtifacts(const ObjectInstanceID srcArtHolder, const ObjectInstanceID dstArtHolder, bool swap)
|
||||
: srcArtHolder(std::move(srcArtHolder))
|
||||
, dstArtHolder(std::move(dstArtHolder))
|
||||
BulkMoveArtifacts(const PlayerColor & interfaceOwner, const ObjectInstanceID srcArtHolder, const ObjectInstanceID dstArtHolder, bool swap)
|
||||
: interfaceOwner(interfaceOwner)
|
||||
, srcArtHolder(srcArtHolder)
|
||||
, dstArtHolder(dstArtHolder)
|
||||
, swap(swap)
|
||||
, askAssemble(false)
|
||||
, srcCreature(std::nullopt)
|
||||
@ -1104,6 +1109,7 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
|
||||
|
||||
template <typename Handler> void serialize(Handler & h)
|
||||
{
|
||||
h & interfaceOwner;
|
||||
h & artsPack0;
|
||||
h & artsPack1;
|
||||
h & srcArtHolder;
|
||||
|
@ -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;
|
||||
|
@ -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>();
|
||||
}
|
||||
|
@ -218,6 +218,15 @@ public:
|
||||
load( data[i]);
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if_t < !std::is_same_v<T, bool >, int > = 0>
|
||||
void load(std::deque<T> & data)
|
||||
{
|
||||
ui32 length = readAndCheckLength();
|
||||
data.resize(length);
|
||||
for(ui32 i = 0; i < length; i++)
|
||||
load(data[i]);
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if_t < std::is_pointer_v<T>, int > = 0 >
|
||||
void load(T &data)
|
||||
{
|
||||
|
@ -276,6 +276,14 @@ public:
|
||||
for(ui32 i=0;i<length;i++)
|
||||
save(data[i]);
|
||||
}
|
||||
template <typename T, typename std::enable_if_t < !std::is_same_v<T, bool >, int > = 0>
|
||||
void save(const std::deque<T> & data)
|
||||
{
|
||||
ui32 length = (ui32)data.size();
|
||||
*this & length;
|
||||
for(ui32 i = 0; i < length; i++)
|
||||
save(data[i]);
|
||||
}
|
||||
template <typename T, size_t N>
|
||||
void save(const std::array<T, N> &data)
|
||||
{
|
||||
|
@ -2690,7 +2690,7 @@ bool CGameHandler::garrisonSwap(ObjectInstanceID tid)
|
||||
|
||||
// With the amount of changes done to the function, it's more like transferArtifacts.
|
||||
// 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)
|
||||
bool CGameHandler::moveArtifact(const PlayerColor & player, const ArtifactLocation & src, const ArtifactLocation & dst)
|
||||
{
|
||||
const auto srcArtSet = getArtSet(src);
|
||||
const auto dstArtSet = getArtSet(dst);
|
||||
@ -2733,7 +2733,7 @@ bool CGameHandler::moveArtifact(const ArtifactLocation & src, const ArtifactLoca
|
||||
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);
|
||||
BulkMoveArtifacts ma(player, src.artHolder, dst.artHolder, false);
|
||||
ma.srcCreature = src.creature;
|
||||
ma.dstCreature = dst.creature;
|
||||
|
||||
@ -2756,7 +2756,7 @@ bool CGameHandler::moveArtifact(const ArtifactLocation & src, const ArtifactLoca
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcId, ObjectInstanceID dstId, bool swap, bool equipped, bool backpack)
|
||||
bool CGameHandler::bulkMoveArtifacts(const PlayerColor & player, ObjectInstanceID srcId, ObjectInstanceID dstId, bool swap, bool equipped, bool backpack)
|
||||
{
|
||||
// Make sure exchange is even possible between the two heroes.
|
||||
if(!isAllowedExchange(srcId, dstId))
|
||||
@ -2767,7 +2767,7 @@ bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcId, ObjectInstanceID ds
|
||||
if((!psrcSet) || (!pdstSet))
|
||||
COMPLAIN_RET("bulkMoveArtifacts: wrong hero's ID");
|
||||
|
||||
BulkMoveArtifacts ma(srcId, dstId, swap);
|
||||
BulkMoveArtifacts ma(player, srcId, dstId, swap);
|
||||
auto & slotsSrcDst = ma.artsPack0;
|
||||
auto & slotsDstSrc = ma.artsPack1;
|
||||
|
||||
@ -2857,6 +2857,25 @@ bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcId, ObjectInstanceID ds
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameHandler::scrollBackpackArtifacts(const PlayerColor & player, const ObjectInstanceID heroID, bool left)
|
||||
{
|
||||
auto artSet = getArtSet(heroID);
|
||||
COMPLAIN_RET_FALSE_IF(artSet == nullptr, "scrollBackpackArtifacts: wrong hero's ID");
|
||||
|
||||
BulkMoveArtifacts bma(player, 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).
|
||||
|
@ -128,8 +128,9 @@ public:
|
||||
bool giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact * artType, ArtifactPosition pos = ArtifactPosition::FIRST_AVAILABLE) override;
|
||||
bool putArtifact(const ArtifactLocation & al, const CArtifactInstance * art, std::optional<bool> askAssemble) override;
|
||||
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 moveArtifact(const PlayerColor & player, const ArtifactLocation & src, const ArtifactLocation & dst) override;
|
||||
bool bulkMoveArtifacts(const PlayerColor & player, ObjectInstanceID srcId, ObjectInstanceID dstId, bool swap, bool equipped, bool backpack);
|
||||
bool scrollBackpackArtifacts(const PlayerColor & player, const ObjectInstanceID heroID, bool left);
|
||||
bool eraseArtifactByClient(const ArtifactLocation & al);
|
||||
void synchronizeArtifactHandlerLists();
|
||||
|
||||
|
@ -136,7 +136,7 @@ void ApplyGhNetPackVisitor::visitExchangeArtifacts(ExchangeArtifacts & pack)
|
||||
{
|
||||
if(gh.getHero(pack.src.artHolder))
|
||||
gh.throwIfWrongPlayer(&pack, gh.getOwner(pack.src.artHolder)); //second hero can be ally
|
||||
result = gh.moveArtifact(pack.src, pack.dst);
|
||||
result = gh.moveArtifact(pack.player, pack.src, pack.dst);
|
||||
}
|
||||
|
||||
void ApplyGhNetPackVisitor::visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack)
|
||||
@ -145,7 +145,28 @@ void ApplyGhNetPackVisitor::visitBulkExchangeArtifacts(BulkExchangeArtifacts & p
|
||||
gh.throwIfWrongOwner(&pack, pack.srcHero);
|
||||
if(pack.swap)
|
||||
gh.throwIfWrongOwner(&pack, pack.dstHero);
|
||||
result = gh.bulkMoveArtifacts(pack.srcHero, pack.dstHero, pack.swap, pack.equipped, pack.backpack);
|
||||
result = gh.bulkMoveArtifacts(pack.player, 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.player, pack.artHolder, true);
|
||||
else if(pack.cmd == ManageBackpackArtifacts::ManageCmd::SCROLL_RIGHT)
|
||||
result = gh.scrollBackpackArtifacts(pack.player, 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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
@ -203,6 +206,9 @@ bool OpenWindowQuery::blocksPack(const CPack *pack) const
|
||||
if(dynamic_ptr_cast<BulkExchangeArtifacts>(pack) != nullptr)
|
||||
return false;
|
||||
|
||||
if(dynamic_ptr_cast<ManageBackpackArtifacts>(pack) != nullptr)
|
||||
return false;
|
||||
|
||||
if(dynamic_ptr_cast<AssembleArtifacts>(pack))
|
||||
return false;
|
||||
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
bool giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact * artType, ArtifactPosition pos) override {return false;}
|
||||
bool putArtifact(const ArtifactLocation & al, const CArtifactInstance * art, std::optional<bool> askAssemble) override {return false;}
|
||||
void removeArtifact(const ArtifactLocation &al) override {}
|
||||
bool moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) override {return false;}
|
||||
bool moveArtifact(const PlayerColor & player, const ArtifactLocation & al1, const ArtifactLocation & al2) override {return false;}
|
||||
|
||||
void heroVisitCastle(const CGTownInstance * obj, const CGHeroInstance * hero) override {}
|
||||
void stopHeroVisitCastle(const CGTownInstance * obj, const CGHeroInstance * hero) override {}
|
||||
|
Loading…
Reference in New Issue
Block a user