mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	ManageBackpackArtifacts
This commit is contained in:
		| @@ -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; | ||||
|   | ||||
| @@ -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)); | ||||
|  | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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 | ||||
| 					{ | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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>(); | ||||
| } | ||||
|   | ||||
| @@ -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). | ||||
|   | ||||
| @@ -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(); | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user