浏览代码

manageBackpackArtifacts

SoundSSGood 1 年之前
父节点
当前提交
e22d15b1d8

+ 18 - 0
CCallback.cpp

@@ -192,6 +192,24 @@ void CCallback::scrollBackpackArtifacts(ObjectInstanceID hero, bool left)
 	sendRequest(&mba);
 }
 
+void CCallback::sortBackpackArtifactsBySlot(const ObjectInstanceID hero)
+{
+	ManageBackpackArtifacts mba(hero, ManageBackpackArtifacts::ManageCmd::SORT_BY_SLOT);
+	sendRequest(&mba);
+}
+
+void CCallback::sortBackpackArtifactsByCost(const ObjectInstanceID hero)
+{
+	ManageBackpackArtifacts mba(hero, ManageBackpackArtifacts::ManageCmd::SORT_BY_COST);
+	sendRequest(&mba);
+}
+
+void CCallback::sortBackpackArtifactsByClass(const ObjectInstanceID hero)
+{
+	ManageBackpackArtifacts mba(hero, ManageBackpackArtifacts::ManageCmd::SORT_BY_CLASS);
+	sendRequest(&mba);
+}
+
 void CCallback::manageHeroCostume(ObjectInstanceID hero, size_t costumeIndex, bool saveCostume)
 {
 	ManageEquippedArtifacts mea(hero, costumeIndex, saveCostume);

+ 6 - 0
CCallback.h

@@ -92,6 +92,9 @@ public:
 	//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 sortBackpackArtifactsBySlot(const ObjectInstanceID hero) = 0;
+	virtual void sortBackpackArtifactsByCost(const ObjectInstanceID hero) = 0;
+	virtual void sortBackpackArtifactsByClass(const ObjectInstanceID hero) = 0;
 	virtual void manageHeroCostume(ObjectInstanceID hero, size_t costumeIndex, bool saveCostume) = 0;
 	virtual void assembleArtifacts(const ObjectInstanceID & heroID, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)=0;
 	virtual void eraseArtifactByClient(const ArtifactLocation & al)=0;
@@ -179,6 +182,9 @@ public:
 	void assembleArtifacts(const ObjectInstanceID & heroID, 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 sortBackpackArtifactsBySlot(const ObjectInstanceID hero) override;
+	void sortBackpackArtifactsByCost(const ObjectInstanceID hero) override;
+	void sortBackpackArtifactsByClass(const ObjectInstanceID hero) override;
 	void manageHeroCostume(ObjectInstanceID hero, size_t costumeIdx, bool saveCostume) override;
 	void eraseArtifactByClient(const ArtifactLocation & al) override;
 	bool buildBuilding(const CGTownInstance *town, BuildingID buildingID) override;

+ 7 - 0
client/windows/CHeroBackpackWindow.cpp

@@ -20,6 +20,8 @@
 #include "render/Canvas.h"
 #include "CPlayerInterface.h"
 
+#include "../../CCallback.h"
+
 #include "../../lib/mapObjects/CGHeroInstance.h"
 #include "../../lib/networkPacks/ArtifactLocation.h"
 
@@ -41,11 +43,16 @@ CHeroBackpackWindow::CHeroBackpackWindow(const CGHeroInstance * hero, const std:
 	};
 	addSet(arts);
 	arts->setHero(hero);
+	
 	quitButton = std::make_shared<CButton>(Point(), AnimationPath::builtin("IOKAY32.def"), CButton::tooltip(""),
 		[this]() { WindowBase::close(); }, EShortcut::GLOBAL_RETURN);
 	pos.w = stretchedBackground->pos.w = arts->pos.w + 2 * windowMargin;
 	pos.h = stretchedBackground->pos.h = arts->pos.h + quitButton->pos.h + 3 * windowMargin;
 	quitButton->moveTo(Point(pos.x + pos.w / 2 - quitButton->pos.w / 2, pos.y + arts->pos.h + 2 * windowMargin));
+	
+	sortBySlot = std::make_shared<CButton>(Point(), AnimationPath::builtin("IOKAY32.def"), CButton::tooltip(""),
+		[hero]() { LOCPLINT->cb->sortBackpackArtifactsBySlot(hero->id); }, EShortcut::GLOBAL_RETURN);
+	sortBySlot->moveTo(Point(pos.x + windowMargin, quitButton->pos.y));
 	statusbar = CGStatusBar::create(0, pos.h, ImagePath::builtin("ADROLLVR.bmp"), pos.w);
 	pos.h += statusbar->pos.h;
 

+ 1 - 0
client/windows/CHeroBackpackWindow.h

@@ -21,6 +21,7 @@ public:
 protected:
 	std::shared_ptr<CArtifactsOfHeroBackpack> arts;
 	std::shared_ptr<CButton> quitButton;
+	std::shared_ptr<CButton> sortBySlot;
 	std::shared_ptr<CFilledTexture> stretchedBackground;
 	const int windowMargin = 5;
 

+ 53 - 9
server/CGameHandler.cpp

@@ -2655,22 +2655,66 @@ bool CGameHandler::bulkMoveArtifacts(const PlayerColor & player, ObjectInstanceI
 	return true;
 }
 
-bool CGameHandler::scrollBackpackArtifacts(const PlayerColor & player, const ObjectInstanceID heroID, bool left)
+bool CGameHandler::manageBackpackArtifacts(const PlayerColor & player, const ObjectInstanceID heroID, const ManageBackpackArtifacts::ManageCmd & sortType)
 {
 	const auto artSet = getArtSet(heroID);
-	COMPLAIN_RET_FALSE_IF(artSet == nullptr, "scrollBackpackArtifacts: wrong hero's ID");
+	COMPLAIN_RET_FALSE_IF(artSet == nullptr, "manageBackpackArtifacts: wrong hero's ID");
 
 	BulkMoveArtifacts bma(player, heroID, heroID, false);
+	const auto makeSortBackpackRequest = [artSet, &bma](const std::function<int32_t(const ArtSlotInfo&)> & getSortId)
+	{
+		std::map<int32_t, std::vector<BulkMoveArtifacts::LinkedSlots>> packsSorted;
+		ArtifactPosition backpackSlot = ArtifactPosition::BACKPACK_START;
+		for(const auto & backpackSlotInfo : artSet->artifactsInBackpack)
+			packsSorted.try_emplace(getSortId(backpackSlotInfo)).first->second.emplace_back(backpackSlot++, ArtifactPosition::PRE_FIRST);
 
-	const auto backpackEnd = ArtifactPosition(ArtifactPosition::BACKPACK_START + artSet->artifactsInBackpack.size() - 1);
-	if(backpackEnd > ArtifactPosition::BACKPACK_START)
+		for(auto & [sortId, pack] : packsSorted)
+		{
+			// Each pack of artifacts is also sorted by ArtifactID
+			std::sort(pack.begin(), pack.end(), [artSet](const auto & slots0, const auto & slots1) -> bool
+				{
+					return artSet->getArt(slots0.srcPos)->getTypeId().num > artSet->getArt(slots1.srcPos)->getTypeId().num;
+				});
+			bma.artsPack0.insert(bma.artsPack0.end(), pack.begin(), pack.end());
+		}
+		backpackSlot = ArtifactPosition::BACKPACK_START;
+		for(auto & slots : bma.artsPack0)
+			slots.dstPos = backpackSlot++;
+	};
+	
+	if(sortType == ManageBackpackArtifacts::ManageCmd::SORT_BY_SLOT)
 	{
-		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);
+		makeSortBackpackRequest([](const ArtSlotInfo & inf) -> int32_t
+			{
+				return inf.getArt()->artType->getPossibleSlots().at(ArtBearer::HERO).front().num;
+			});
+	}
+	else if(sortType == ManageBackpackArtifacts::ManageCmd::SORT_BY_COST)
+	{
+		makeSortBackpackRequest([](const ArtSlotInfo & inf) -> int32_t
+			{
+				return inf.getArt()->artType->getPrice();
+			});
+	}
+	else if(sortType == ManageBackpackArtifacts::ManageCmd::SORT_BY_CLASS)
+	{
+		makeSortBackpackRequest([](const ArtSlotInfo & inf) -> int32_t
+			{
+				return inf.getArt()->artType->aClass;
+			});
+	}
+	else
+	{
+		const auto backpackEnd = ArtifactPosition(ArtifactPosition::BACKPACK_START + artSet->artifactsInBackpack.size() - 1);
+		if(backpackEnd > ArtifactPosition::BACKPACK_START)
+		{
+			if(sortType == ManageBackpackArtifacts::ManageCmd::SCROLL_LEFT)
+				bma.artsPack0.emplace_back(backpackEnd, ArtifactPosition::BACKPACK_START);
+			else
+				bma.artsPack0.emplace_back(ArtifactPosition::BACKPACK_START, backpackEnd);
+		}
 	}
+	sendAndApply(&bma);
 	return true;
 }
 

+ 2 - 1
server/CGameHandler.h

@@ -15,6 +15,7 @@
 #include "../lib/LoadProgress.h"
 #include "../lib/ScriptHandler.h"
 #include "../lib/gameState/GameStatistics.h"
+#include "../lib/networkPacks/PacksForServer.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -141,7 +142,7 @@ public:
 	void removeArtifact(const ObjectInstanceID & srcId, const std::vector<ArtifactPosition> & slotsPack);
 	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 manageBackpackArtifacts(const PlayerColor & player, const ObjectInstanceID heroID, const ManageBackpackArtifacts::ManageCmd & sortType);
 	bool saveArtifactsCostume(const PlayerColor & player, const ObjectInstanceID heroID, uint32_t costumeIdx);
 	bool switchArtifactsCostume(const PlayerColor & player, const ObjectInstanceID heroID, uint32_t costumeIdx);
 	bool eraseArtifactByClient(const ArtifactLocation & al);

+ 1 - 16
server/NetPacksServer.cpp

@@ -197,22 +197,7 @@ void ApplyGhNetPackVisitor::visitManageBackpackArtifacts(ManageBackpackArtifacts
 	gh.throwIfPlayerNotActive(&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;
-		}
-	}
+		result = gh.manageBackpackArtifacts(pack.player, pack.artHolder, pack.cmd);
 }
 
 void ApplyGhNetPackVisitor::visitManageEquippedArtifacts(ManageEquippedArtifacts & pack)