Browse Source

using deque for hero's backpack storage

SoundSSGood 1 year ago
parent
commit
d143f53d7e

+ 1 - 1
client/widgets/CArtifactsOfHeroAltar.cpp

@@ -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)

+ 1 - 0
client/widgets/CArtifactsOfHeroBackpack.cpp

@@ -26,6 +26,7 @@
 CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack(size_t slotsColumnsMax, size_t slotsRowsMax)
 	: slotsColumnsMax(slotsColumnsMax)
 	, slotsRowsMax(slotsRowsMax)
+	, backpackPos(0)
 {
 	setRedrawParent(true);
 }

+ 1 - 0
client/widgets/CArtifactsOfHeroBackpack.h

@@ -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);

+ 30 - 47
client/widgets/CArtifactsOfHeroBase.cpp

@@ -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 & lClickCallback,
+	const CArtPlace::ClickFunctor & showPopupCallback,
 	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);
@@ -87,8 +86,10 @@ void CArtifactsOfHeroBase::init(
 		artPlace->setClickPressedCallback(lClickCallback);
 		artPlace->setShowPopupCallback(showPopupCallback);
 	}
-	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(-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->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
@@ -135,46 +132,28 @@ const CGHeroInstance * CArtifactsOfHeroBase::getHero() const
 
 void CArtifactsOfHeroBase::scrollBackpack(int offset)
 {
-	// 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
+	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)
 	{
-		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;
+		// To left
+		srcLoc = &endLoc;
+		dstLoc = &beginLoc;
+		offset = -offset;
+	}
 
-	if(artsInBackpack)
-		backpackPos %= artsInBackpack;
+	for(auto step = 0; step < offset; step++)
+		LOCPLINT->cb->swapArtifacts(*srcLoc, *dstLoc);
 
-	auto slot = ArtifactPosition(ArtifactPosition::BACKPACK_START + backpackPos);
+	ArtifactPosition slot = ArtifactPosition::BACKPACK_START;
 	for(auto artPlace : backpack)
 	{
 		setSlotData(artPlace, slot);
-		slot = inc(slot);
+		slot = slot + 1;
 	}
-
-	// Blocking scrolling if there is not enough artifacts to scroll
-	if(leftBackpackRoll)
-		leftBackpackRoll->block(!scrollingPossible);
-	if(rightBackpackRoll)
-		rightBackpackRoll->block(!scrollingPossible);
-
-	redraw();
 }
 
 void CArtifactsOfHeroBase::markPossibleSlots(const CArtifactInstance * art, bool assumeDestRemoved)
@@ -224,9 +203,13 @@ void CArtifactsOfHeroBase::updateWornSlots()
 
 void CArtifactsOfHeroBase::updateBackpackSlots()
 {
-	if(curHero->artifactsInBackpack.size() <= backpack.size() && backpackPos != 0)
-		backpackPos = 0;
 	scrollBackpack(0);
+	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)

+ 2 - 3
client/widgets/CArtifactsOfHeroBase.h

@@ -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);
 };

+ 1 - 1
client/widgets/CArtifactsOfHeroMarket.cpp

@@ -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);

+ 1 - 1
lib/CArtHandler.h

@@ -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
 

+ 9 - 0
lib/serializer/BinaryDeserializer.h

@@ -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)
 	{

+ 8 - 0
lib/serializer/BinarySerializer.h

@@ -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)
 	{