mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Switching costume
This commit is contained in:
		| @@ -195,8 +195,6 @@ void CCallback::scrollBackpackArtifacts(ObjectInstanceID hero, bool left) | ||||
|  | ||||
| void CCallback::manageHeroCostume(ObjectInstanceID hero, size_t costumeIndex, bool saveCostume) | ||||
| { | ||||
| 	assert(costumeIndex < GameConstants::HERO_COSTUMES_ARTIFACTS); | ||||
|  | ||||
| 	ManageEquippedArtifacts mea(hero, costumeIndex, saveCostume); | ||||
| 	sendRequest(&mea); | ||||
| } | ||||
|   | ||||
| @@ -314,12 +314,20 @@ CKeyShortcut::CKeyShortcut(EShortcut key) | ||||
| { | ||||
| } | ||||
|  | ||||
| CKeyShortcut::CKeyShortcut(const EShortcut & key, const KeyPressedFunctor & keyPressedCallback) | ||||
| 	: CKeyShortcut(key) | ||||
| { | ||||
| 	this->keyPressedCallback = keyPressedCallback; | ||||
| } | ||||
|  | ||||
| void CKeyShortcut::keyPressed(EShortcut key) | ||||
| { | ||||
| 	if( assignedKey == key && assignedKey != EShortcut::NONE && !shortcutPressed) | ||||
| 	{ | ||||
| 		shortcutPressed = true; | ||||
| 		clickPressed(GH.getCursorPosition()); | ||||
| 		if(keyPressedCallback) | ||||
| 			keyPressedCallback(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -133,14 +133,19 @@ public: | ||||
| /// Classes wanting use it should have it as one of their base classes | ||||
| class CKeyShortcut : public virtual CIntObject | ||||
| { | ||||
| 	bool shortcutPressed; | ||||
| public: | ||||
| 	using KeyPressedFunctor = std::function<void()>; | ||||
|  | ||||
| 	EShortcut assignedKey; | ||||
| 	CKeyShortcut(); | ||||
| 	CKeyShortcut(EShortcut key); | ||||
| 	CKeyShortcut(const EShortcut & key, const KeyPressedFunctor & keyPressedCallback); | ||||
| 	void keyPressed(EShortcut key) override; | ||||
| 	void keyReleased(EShortcut key) override; | ||||
|  | ||||
| private: | ||||
| 	bool shortcutPressed; | ||||
| 	KeyPressedFunctor keyPressedCallback; | ||||
| }; | ||||
|  | ||||
| class WindowBase : public CIntObject | ||||
|   | ||||
| @@ -18,7 +18,7 @@ | ||||
| #include "../../CCallback.h" | ||||
| #include "../../lib/networkPacks/ArtifactLocation.h" | ||||
|  | ||||
| CArtifactsOfHeroMain::CArtifactsOfHeroMain(const Point & position, bool costumesEnabled) | ||||
| CArtifactsOfHeroMain::CArtifactsOfHeroMain(const Point & position) | ||||
| { | ||||
| 	init( | ||||
| 		std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2), | ||||
| @@ -26,21 +26,6 @@ CArtifactsOfHeroMain::CArtifactsOfHeroMain(const Point & position, bool costumes | ||||
| 		position, | ||||
| 		std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, _1)); | ||||
| 	addGestureCallback(std::bind(&CArtifactsOfHeroBase::gestureArtPlace, this, _1, _2)); | ||||
|  | ||||
| 	if(costumesEnabled) | ||||
| 	{ | ||||
| 		size_t costumeIndex = 0; | ||||
| 		for(const auto & hotkey : hotkeys) | ||||
| 		{ | ||||
| 			auto keyProc = costumesSwitchers.emplace_back(std::make_shared<CKeyShortcutWrapper>(hotkey, | ||||
| 				[this, hotkey, costumeIndex]() | ||||
| 				{ | ||||
| 					CArtifactsOfHeroMain::onCostumeSelect(costumeIndex); | ||||
| 				})); | ||||
| 			keyProc->addUsedEvents(AEventsReceiver::KEYBOARD); | ||||
| 			costumeIndex++; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| CArtifactsOfHeroMain::~CArtifactsOfHeroMain() | ||||
| @@ -48,19 +33,17 @@ CArtifactsOfHeroMain::~CArtifactsOfHeroMain() | ||||
| 	CArtifactsOfHeroBase::putBackPickedArtifact(); | ||||
| } | ||||
|  | ||||
| void CArtifactsOfHeroMain::onCostumeSelect(const size_t costumeIndex) | ||||
| void CArtifactsOfHeroMain::enableArtifactsCostumeSwitcher() | ||||
| { | ||||
| 	LOCPLINT->cb->manageHeroCostume(getHero()->id, costumeIndex, GH.isKeyboardCtrlDown()); | ||||
| } | ||||
|  | ||||
| CArtifactsOfHeroMain::CKeyShortcutWrapper::CKeyShortcutWrapper(const EShortcut & key, const KeyPressedFunctor & onCostumeSelect) | ||||
| 	: CKeyShortcut(key) | ||||
| 	, onCostumeSelect(onCostumeSelect) | ||||
| { | ||||
| } | ||||
|  | ||||
| void CArtifactsOfHeroMain::CKeyShortcutWrapper::clickPressed(const Point & cursorPosition) | ||||
| { | ||||
| 	if(onCostumeSelect) | ||||
| 		onCostumeSelect(); | ||||
| 	size_t costumeIdx = 0; | ||||
| 	for(const auto & hotkey : costumesSwitcherHotkeys) | ||||
| 	{ | ||||
| 		auto keyProc = costumesSwitcherProcessors.emplace_back(std::make_shared<CKeyShortcut>(hotkey, | ||||
| 			[this, costumeIdx]() | ||||
| 			{ | ||||
| 				LOCPLINT->cb->manageHeroCostume(getHero()->id, costumeIdx, GH.isKeyboardCtrlDown()); | ||||
| 			})); | ||||
| 		keyProc->addUsedEvents(AEventsReceiver::KEYBOARD); | ||||
| 		costumeIdx++; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -16,24 +16,12 @@ | ||||
| class CArtifactsOfHeroMain : public CArtifactsOfHeroBase | ||||
| { | ||||
| public: | ||||
| 	CArtifactsOfHeroMain(const Point & position, bool costumesEnabled = false); | ||||
| 	CArtifactsOfHeroMain(const Point & position); | ||||
| 	~CArtifactsOfHeroMain() override; | ||||
| 	void enableArtifactsCostumeSwitcher(); | ||||
|  | ||||
| private: | ||||
| 	// TODO may be removed if CKeyShortcut supports callbacks | ||||
| 	class CKeyShortcutWrapper : public CKeyShortcut | ||||
| 	{ | ||||
| 	public: | ||||
| 		using KeyPressedFunctor = std::function<void()>; | ||||
|  | ||||
| 		CKeyShortcutWrapper(const EShortcut & key, const KeyPressedFunctor & onCostumeSelect); | ||||
| 		void clickPressed(const Point & cursorPosition) override; | ||||
|  | ||||
| 	private: | ||||
| 		KeyPressedFunctor onCostumeSelect; | ||||
| 	}; | ||||
|  | ||||
| 	const std::array<EShortcut, GameConstants::HERO_COSTUMES_ARTIFACTS> hotkeys = | ||||
| 	const std::vector<EShortcut> costumesSwitcherHotkeys = | ||||
| 	{ | ||||
| 		EShortcut::HERO_COSTUME_0, | ||||
| 		EShortcut::HERO_COSTUME_1, | ||||
| @@ -46,7 +34,5 @@ private: | ||||
| 		EShortcut::HERO_COSTUME_8, | ||||
| 		EShortcut::HERO_COSTUME_9 | ||||
| 	}; | ||||
| 	std::vector<std::shared_ptr<CKeyShortcutWrapper>> costumesSwitchers; | ||||
|  | ||||
| 	void onCostumeSelect(const size_t costumeIndex); | ||||
| 	std::vector<std::shared_ptr<CKeyShortcut>> costumesSwitcherProcessors; | ||||
| }; | ||||
|   | ||||
| @@ -218,9 +218,10 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded) | ||||
| 		} | ||||
| 		if(!arts) | ||||
| 		{ | ||||
| 			arts = std::make_shared<CArtifactsOfHeroMain>(Point(-65, -8), true); | ||||
| 			arts = std::make_shared<CArtifactsOfHeroMain>(Point(-65, -8)); | ||||
| 			arts->setHero(curHero); | ||||
| 			addSetAndCallbacks(arts); | ||||
| 			enableArtifactsCostumeSwitcher(); | ||||
| 		} | ||||
|  | ||||
| 		int serial = LOCPLINT->cb->getHeroSerial(curHero, false); | ||||
|   | ||||
| @@ -343,6 +343,20 @@ void CWindowWithArtifacts::deactivate() | ||||
| 	CWindowObject::deactivate(); | ||||
| } | ||||
|  | ||||
| void CWindowWithArtifacts::enableArtifactsCostumeSwitcher() | ||||
| { | ||||
| 	for(auto artSet : artSets) | ||||
| 		std::visit( | ||||
| 			[](auto artSetWeak) | ||||
| 			{ | ||||
| 				if constexpr(std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroMain>>) | ||||
| 				{ | ||||
| 					const auto artSetPtr = artSetWeak.lock(); | ||||
| 					artSetPtr->enableArtifactsCostumeSwitcher(); | ||||
| 				} | ||||
| 			}, artSet); | ||||
| } | ||||
|  | ||||
| void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation & artLoc) | ||||
| { | ||||
| 	update(); | ||||
|   | ||||
| @@ -42,6 +42,7 @@ public: | ||||
| 	void gestureArtPlaceHero(const CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition); | ||||
| 	void activate() override; | ||||
| 	void deactivate() override; | ||||
| 	void enableArtifactsCostumeSwitcher(); | ||||
|  | ||||
| 	virtual void artifactRemoved(const ArtifactLocation & artLoc); | ||||
| 	virtual void artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw); | ||||
|   | ||||
| @@ -52,7 +52,7 @@ DLL_LINKAGE const std::vector<ArtifactPosition> & ArtifactUtils::unmovableSlots( | ||||
| 	return positions; | ||||
| } | ||||
|  | ||||
| DLL_LINKAGE const std::vector<ArtifactPosition> & ArtifactUtils::constituentWornSlots() | ||||
| DLL_LINKAGE const std::vector<ArtifactPosition> & ArtifactUtils::commonWornSlots() | ||||
| { | ||||
| 	static const std::vector<ArtifactPosition> positions = | ||||
| 	{ | ||||
|   | ||||
| @@ -30,7 +30,7 @@ namespace ArtifactUtils | ||||
| 	DLL_LINKAGE ArtifactPosition getArtBackpackPosition(const CArtifactSet * target, const ArtifactID & aid); | ||||
| 	// TODO: Make this constexpr when the toolset is upgraded | ||||
| 	DLL_LINKAGE const std::vector<ArtifactPosition> & unmovableSlots(); | ||||
| 	DLL_LINKAGE const std::vector<ArtifactPosition> & constituentWornSlots(); | ||||
| 	DLL_LINKAGE const std::vector<ArtifactPosition> & commonWornSlots(); | ||||
| 	DLL_LINKAGE const std::vector<ArtifactPosition> & allWornSlots(); | ||||
| 	DLL_LINKAGE const std::vector<ArtifactPosition> & commanderSlots(); | ||||
| 	DLL_LINKAGE bool isArtRemovable(const std::pair<ArtifactPosition, ArtSlotInfo> & slot); | ||||
|   | ||||
| @@ -1086,6 +1086,14 @@ CArtifactFittingSet::CArtifactFittingSet(ArtBearer::ArtBearer Bearer): | ||||
| { | ||||
| } | ||||
|  | ||||
| CArtifactFittingSet::CArtifactFittingSet(const CArtifactSet & artSet) | ||||
| 	: CArtifactFittingSet(artSet.bearerType()) | ||||
| { | ||||
| 	artifactsWorn = artSet.artifactsWorn; | ||||
| 	artifactsInBackpack = artSet.artifactsInBackpack; | ||||
| 	artifactsTransitionPos = artSet.artifactsTransitionPos; | ||||
| } | ||||
|  | ||||
| ArtBearer::ArtBearer CArtifactFittingSet::bearerType() const | ||||
| { | ||||
| 	return this->Bearer; | ||||
|   | ||||
| @@ -249,6 +249,7 @@ class DLL_LINKAGE CArtifactFittingSet : public CArtifactSet | ||||
| { | ||||
| public: | ||||
| 	CArtifactFittingSet(ArtBearer::ArtBearer Bearer); | ||||
| 	CArtifactFittingSet(const CArtifactSet & artSet); | ||||
| 	ArtBearer::ArtBearer bearerType() const override; | ||||
|  | ||||
| protected: | ||||
|   | ||||
| @@ -1075,7 +1075,7 @@ void ChangeObjectVisitors::applyGs(CGameState * gs) const | ||||
| void ChangeArtifactsCostume::applyGs(CGameState * gs) const | ||||
| { | ||||
| 	auto & allCostumes = gs->getPlayerState(player)->costumesArtifacts; | ||||
| 	if(auto & costume = allCostumes.find(costumeIdx); costume != allCostumes.end()) | ||||
| 	if(const auto & costume = allCostumes.find(costumeIdx); costume != allCostumes.end()) | ||||
| 		costume->second = costumeSet; | ||||
| 	else | ||||
| 		allCostumes.emplace(costumeIdx, costumeSet); | ||||
| @@ -1802,69 +1802,47 @@ void MoveArtifact::applyGs(CGameState * gs) | ||||
|  | ||||
| void BulkMoveArtifacts::applyGs(CGameState * gs) | ||||
| { | ||||
| 	enum class EBulkArtsOp | ||||
| 	const auto bulkArtsRemove = [](std::vector<LinkedSlots> & artsPack, CArtifactSet & artSet) | ||||
| 	{ | ||||
| 		BULK_MOVE, | ||||
| 		BULK_REMOVE, | ||||
| 		BULK_PUT | ||||
| 		std::vector<ArtifactPosition> packToRemove; | ||||
| 		for(const auto & slotsPair : artsPack) | ||||
| 			packToRemove.push_back(slotsPair.srcPos); | ||||
| 		std::sort(packToRemove.begin(), packToRemove.end(), [](const ArtifactPosition & slot0, const ArtifactPosition & slot1) -> bool | ||||
| 			{ | ||||
| 				return slot0.num > slot1.num; | ||||
| 			}); | ||||
|  | ||||
| 		for(const auto & slot : packToRemove) | ||||
| 		{ | ||||
| 			auto * art = artSet.getArt(slot); | ||||
| 			assert(art); | ||||
| 			art->removeFrom(artSet, slot); | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	auto bulkArtsOperation = [this, gs](std::vector<LinkedSlots> & artsPack,  | ||||
| 		CArtifactSet & artSet, EBulkArtsOp operation) -> void | ||||
| 	const auto bulkArtsPut = [](std::vector<LinkedSlots> & artsPack, CArtifactSet & initArtSet, CArtifactSet & dstArtSet) | ||||
| 	{ | ||||
| 		int numBackpackArtifactsMoved = 0; | ||||
| 		for(auto & slot : artsPack) | ||||
| 		for(const auto & slotsPair : artsPack) | ||||
| 		{ | ||||
| 			// When an object gets removed from the backpack, the backpack shrinks | ||||
| 			// so all the following indices will be affected. Thus, we need to update | ||||
| 			// the subsequent artifact slots to account for that | ||||
| 			auto srcPos = slot.srcPos; | ||||
| 			if(ArtifactUtils::isSlotBackpack(srcPos) && (operation != EBulkArtsOp::BULK_PUT)) | ||||
| 			{ | ||||
| 				srcPos = ArtifactPosition(srcPos.num - numBackpackArtifactsMoved); | ||||
| 			} | ||||
| 			auto * art = artSet.getArt(srcPos); | ||||
| 			auto * art = initArtSet.getArt(slotsPair.srcPos); | ||||
| 			assert(art); | ||||
| 			switch(operation) | ||||
| 			{ | ||||
| 			case EBulkArtsOp::BULK_MOVE: | ||||
| 				art->move(artSet, srcPos, *gs->getArtSet(ArtifactLocation(dstArtHolder, dstCreature)), slot.dstPos); | ||||
| 				break; | ||||
| 			case EBulkArtsOp::BULK_REMOVE: | ||||
| 				art->removeFrom(artSet, srcPos); | ||||
| 				break; | ||||
| 			case EBulkArtsOp::BULK_PUT: | ||||
| 				art->putAt(*gs->getArtSet(ArtifactLocation(srcArtHolder, srcCreature)), slot.dstPos); | ||||
| 				break; | ||||
| 			default: | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			if(srcPos >= ArtifactPosition::BACKPACK_START) | ||||
| 			{ | ||||
| 				numBackpackArtifactsMoved++; | ||||
| 			} | ||||
| 			art->putAt(dstArtSet, slotsPair.dstPos); | ||||
| 		} | ||||
| 	}; | ||||
| 	 | ||||
| 	auto * leftSet = gs->getArtSet(ArtifactLocation(srcArtHolder, srcCreature)); | ||||
| 	if(swap) | ||||
| 	assert(leftSet); | ||||
| 	auto * rightSet = gs->getArtSet(ArtifactLocation(dstArtHolder, dstCreature)); | ||||
| 	assert(rightSet); | ||||
| 	CArtifactFittingSet artInitialSetLeft(*leftSet); | ||||
| 	bulkArtsRemove(artsPack0, *leftSet); | ||||
| 	if(!artsPack1.empty()) | ||||
| 	{ | ||||
| 		// Swap | ||||
| 		auto * rightSet = gs->getArtSet(ArtifactLocation(dstArtHolder, dstCreature)); | ||||
| 		CArtifactFittingSet artFittingSet(leftSet->bearerType()); | ||||
|  | ||||
| 		artFittingSet.artifactsWorn = rightSet->artifactsWorn; | ||||
| 		artFittingSet.artifactsInBackpack = rightSet->artifactsInBackpack; | ||||
|  | ||||
| 		bulkArtsOperation(artsPack1, *rightSet, EBulkArtsOp::BULK_REMOVE); | ||||
| 		bulkArtsOperation(artsPack0, *leftSet, EBulkArtsOp::BULK_MOVE); | ||||
| 		bulkArtsOperation(artsPack1, artFittingSet, EBulkArtsOp::BULK_PUT); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		bulkArtsOperation(artsPack0, *leftSet, EBulkArtsOp::BULK_MOVE); | ||||
| 		CArtifactFittingSet artInitialSetRight(*rightSet); | ||||
| 		bulkArtsRemove(artsPack1, *rightSet); | ||||
| 		bulkArtsPut(artsPack1, artInitialSetRight, *leftSet); | ||||
| 	} | ||||
| 	bulkArtsPut(artsPack0, artInitialSetLeft, *rightSet); | ||||
| } | ||||
|  | ||||
| void AssembledArtifact::applyGs(CGameState *gs) | ||||
|   | ||||
| @@ -1291,8 +1291,8 @@ struct DLL_LINKAGE ChangeObjectVisitors : public CPackForClient | ||||
| struct DLL_LINKAGE ChangeArtifactsCostume : public CPackForClient | ||||
| { | ||||
| 	std::map<ArtifactPosition, ArtifactID> costumeSet; | ||||
| 	size_t costumeIdx; | ||||
| 	const PlayerColor player; | ||||
| 	size_t costumeIdx = 0; | ||||
| 	const PlayerColor player = PlayerColor::NEUTRAL; | ||||
|  | ||||
| 	void applyGs(CGameState * gs) const; | ||||
| 	void visitTyped(ICPackVisitor & visitor) override; | ||||
|   | ||||
| @@ -2896,20 +2896,74 @@ bool CGameHandler::saveArtifactsCostume(const PlayerColor & player, const Object | ||||
| { | ||||
| 	auto artSet = getArtSet(heroID); | ||||
| 	COMPLAIN_RET_FALSE_IF(artSet == nullptr, "saveArtifactsCostume: wrong hero's ID"); | ||||
| 	COMPLAIN_RET_FALSE_IF(costumeIdx >= GameConstants::HERO_COSTUMES_ARTIFACTS, "saveArtifactsCostume: wrong costume index"); | ||||
|  | ||||
| 	ChangeArtifactsCostume costume(player, costumeIdx); | ||||
| 	for(const auto & slot : ArtifactUtils::constituentWornSlots()) | ||||
| 	for(const auto & slot : ArtifactUtils::commonWornSlots()) | ||||
| 	{ | ||||
| 		if(const auto & slotInfo = artSet->getSlot(slot)) | ||||
| 			if(!slotInfo->locked) | ||||
| 				costume.costumeSet.emplace(slot, slotInfo->getArt()->getTypeId()); | ||||
| 		if(const auto slotInfo = artSet->getSlot(slot); slotInfo != nullptr && !slotInfo->locked) | ||||
| 			costume.costumeSet.emplace(slot, slotInfo->getArt()->getTypeId()); | ||||
| 	} | ||||
|  | ||||
| 	sendAndApply(&costume); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool CGameHandler::switchArtifactsCostume(const PlayerColor & player, const ObjectInstanceID heroID, size_t costumeIdx) | ||||
| { | ||||
| 	const auto artSet = getArtSet(heroID); | ||||
| 	COMPLAIN_RET_FALSE_IF(artSet == nullptr, "switchArtifactsCostume: wrong hero's ID"); | ||||
| 	const auto playerState = getPlayerState(player); | ||||
| 	COMPLAIN_RET_FALSE_IF(playerState == nullptr, "switchArtifactsCostume: wrong player"); | ||||
|  | ||||
| 	if(auto costume = playerState->costumesArtifacts.find(costumeIdx); costume != playerState->costumesArtifacts.end()) | ||||
| 	{ | ||||
| 		CArtifactFittingSet artFittingSet(*artSet); | ||||
| 		BulkMoveArtifacts bma(player, heroID, heroID, false); | ||||
| 		auto costumeArtMap = costume->second; | ||||
| 		auto estimateBackpackSize = artSet->artifactsInBackpack.size(); | ||||
|  | ||||
| 		// First, find those artifacts that are already in place | ||||
| 		for(const auto & slot : ArtifactUtils::commonWornSlots()) | ||||
| 		{ | ||||
| 			if(const auto * slotInfo = artFittingSet.getSlot(slot); slotInfo != nullptr && !slotInfo->locked) | ||||
| 				if(const auto artPos = costumeArtMap.find(slot); artPos != costumeArtMap.end() && artPos->second == slotInfo->getArt()->getTypeId()) | ||||
| 				{ | ||||
| 					costumeArtMap.erase(artPos); | ||||
| 					artFittingSet.removeArtifact(slot); | ||||
| 				} | ||||
| 		} | ||||
| 		 | ||||
| 		// Second, find the necessary artifacts for the costume | ||||
| 		for(const auto & artPos : costumeArtMap) | ||||
| 		{ | ||||
| 			if(const auto availableArts = artFittingSet.getAllArtPositions(artPos.second, false, false, false); !availableArts.empty()) | ||||
| 			{ | ||||
| 				bma.artsPack0.emplace_back(BulkMoveArtifacts::LinkedSlots | ||||
| 					{ | ||||
| 						artSet->getSlotByInstance(artFittingSet.getArt(availableArts.front())), | ||||
| 						artPos.first | ||||
| 					}); | ||||
| 				artFittingSet.removeArtifact(availableArts.front()); | ||||
| 				if(ArtifactUtils::isSlotBackpack(availableArts.front())) | ||||
| 					estimateBackpackSize--; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// Third, put unnecessary artifacts into backpack | ||||
| 		for(const auto & slot : ArtifactUtils::commonWornSlots()) | ||||
| 			if(artFittingSet.getArt(slot)) | ||||
| 			{ | ||||
| 				bma.artsPack0.emplace_back(BulkMoveArtifacts::LinkedSlots{slot, ArtifactPosition::BACKPACK_START}); | ||||
| 				estimateBackpackSize++; | ||||
| 			} | ||||
| 		 | ||||
| 		const auto backpackCap = VLC->settings()->getInteger(EGameSettings::HEROES_BACKPACK_CAP); | ||||
| 		if((backpackCap < 0 || estimateBackpackSize <= backpackCap) && !bma.artsPack0.empty()) | ||||
| 			sendAndApply(&bma); | ||||
| 	} | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Assembles or disassembles a combination artifact. | ||||
|  * @param heroID ID of hero holding the artifact(s). | ||||
|   | ||||
| @@ -131,6 +131,7 @@ public: | ||||
| 	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 saveArtifactsCostume(const PlayerColor & player, const ObjectInstanceID heroID, size_t costumeIdx); | ||||
| 	bool switchArtifactsCostume(const PlayerColor & player, const ObjectInstanceID heroID, size_t costumeIdx); | ||||
| 	bool eraseArtifactByClient(const ArtifactLocation & al); | ||||
| 	void synchronizeArtifactHandlerLists(); | ||||
|  | ||||
|   | ||||
| @@ -183,8 +183,9 @@ void ApplyGhNetPackVisitor::visitManageEquippedArtifacts(ManageEquippedArtifacts | ||||
| { | ||||
| 	gh.throwIfWrongOwner(&pack, pack.artHolder); | ||||
| 	if(pack.saveCostume) | ||||
| 		gh.saveArtifactsCostume(pack.player, pack.artHolder, pack.costumeIdx); | ||||
| 	result = true; | ||||
| 		result = gh.saveArtifactsCostume(pack.player, pack.artHolder, pack.costumeIdx); | ||||
| 	else | ||||
| 		result = gh.switchArtifactsCostume(pack.player, pack.artHolder, pack.costumeIdx); | ||||
| } | ||||
|  | ||||
| void ApplyGhNetPackVisitor::visitAssembleArtifacts(AssembleArtifacts & pack) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user