mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	refactoring
This commit is contained in:
		| @@ -94,6 +94,7 @@ set(client_SRCS | ||||
| 	widgets/Buttons.cpp | ||||
| 	widgets/CArtifactHolder.cpp | ||||
| 	widgets/CComponent.cpp | ||||
| 	widgets/CExchangeController.cpp | ||||
| 	widgets/CGarrisonInt.cpp | ||||
| 	widgets/CreatureCostBox.cpp | ||||
| 	widgets/ComboBox.cpp | ||||
| @@ -255,6 +256,7 @@ set(client_HEADERS | ||||
| 	widgets/Buttons.h | ||||
| 	widgets/CArtifactHolder.h | ||||
| 	widgets/CComponent.h | ||||
| 	widgets/CExchangeController.h | ||||
| 	widgets/CGarrisonInt.h | ||||
| 	widgets/CreatureCostBox.h | ||||
| 	widgets/ComboBox.h | ||||
|   | ||||
| @@ -186,8 +186,8 @@ void CHeroArtPlace::clickPressed(const Point & cursorPosition) | ||||
|  | ||||
| void CHeroArtPlace::showPopupWindow(const Point & cursorPosition) | ||||
| { | ||||
| 	if(rightClickCallback) | ||||
| 		rightClickCallback(*this); | ||||
| 	if(showPopupCallback) | ||||
| 		showPopupCallback(*this); | ||||
| } | ||||
|  | ||||
| void CHeroArtPlace::showAll(Canvas & to) | ||||
|   | ||||
| @@ -65,11 +65,11 @@ public: | ||||
| class CHeroArtPlace: public CArtPlace | ||||
| { | ||||
| public: | ||||
| 	using ClickHandler = std::function<void(CHeroArtPlace&)>; | ||||
| 	using ClickFunctor = std::function<void(CHeroArtPlace&)>; | ||||
|  | ||||
| 	ArtifactPosition slot; | ||||
| 	ClickHandler leftClickCallback; | ||||
| 	ClickHandler rightClickCallback; | ||||
| 	ClickFunctor leftClickCallback; | ||||
| 	ClickFunctor showPopupCallback; | ||||
|  | ||||
| 	CHeroArtPlace(Point position, const CArtifactInstance * Art = nullptr); | ||||
| 	void lockSlot(bool on); | ||||
|   | ||||
| @@ -42,7 +42,7 @@ CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack(const Point & position) | ||||
| 		artPlace = std::make_shared<CHeroArtPlace>(pos); | ||||
| 		artPlace->setArtifact(nullptr); | ||||
| 		artPlace->leftClickCallback = std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1); | ||||
| 		artPlace->rightClickCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1); | ||||
| 		artPlace->showPopupCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1); | ||||
| 		artPlaceIdx++; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -55,10 +55,10 @@ void CArtifactsOfHeroBase::setPutBackPickedArtifactCallback(PutBackPickedArtCall | ||||
| } | ||||
|  | ||||
| void CArtifactsOfHeroBase::init( | ||||
| 	CHeroArtPlace::ClickHandler lClickCallback, | ||||
| 	CHeroArtPlace::ClickHandler rClickCallback, | ||||
| 	CHeroArtPlace::ClickFunctor lClickCallback, | ||||
| 	CHeroArtPlace::ClickFunctor showPopupCallback, | ||||
| 	const Point & position, | ||||
| 	BpackScrollHandler scrollHandler) | ||||
| 	BpackScrollFunctor scrollCallback) | ||||
| { | ||||
| 	// CArtifactsOfHeroBase::init may be transform to CArtifactsOfHeroBase::CArtifactsOfHeroBase if OBJECT_CONSTRUCTION_CAPTURING is removed | ||||
| 	OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); | ||||
| @@ -78,16 +78,16 @@ void CArtifactsOfHeroBase::init( | ||||
| 		artPlace.second->slot = artPlace.first; | ||||
| 		artPlace.second->setArtifact(nullptr); | ||||
| 		artPlace.second->leftClickCallback = lClickCallback; | ||||
| 		artPlace.second->rightClickCallback = rClickCallback; | ||||
| 		artPlace.second->showPopupCallback = showPopupCallback; | ||||
| 	} | ||||
| 	for(auto artPlace : backpack) | ||||
| 	{ | ||||
| 		artPlace->setArtifact(nullptr); | ||||
| 		artPlace->leftClickCallback = lClickCallback; | ||||
| 		artPlace->rightClickCallback = rClickCallback; | ||||
| 		artPlace->showPopupCallback = showPopupCallback; | ||||
| 	} | ||||
| 	leftBackpackRoll = std::make_shared<CButton>(Point(379, 364), AnimationPath::builtin("hsbtns3.def"), CButton::tooltip(), [scrollHandler]() { scrollHandler(-1); }, EShortcut::MOVE_LEFT); | ||||
| 	rightBackpackRoll = std::make_shared<CButton>(Point(632, 364), AnimationPath::builtin("hsbtns5.def"), CButton::tooltip(), [scrollHandler]() { scrollHandler(+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); | ||||
|  | ||||
| @@ -102,8 +102,8 @@ void CArtifactsOfHeroBase::leftClickArtPlace(CHeroArtPlace & artPlace) | ||||
|  | ||||
| void CArtifactsOfHeroBase::rightClickArtPlace(CHeroArtPlace & artPlace) | ||||
| { | ||||
| 	if(rightClickCallback) | ||||
| 		rightClickCallback(*this, artPlace); | ||||
| 	if(showPopupCallback) | ||||
| 		showPopupCallback(*this, artPlace); | ||||
| } | ||||
|  | ||||
| void CArtifactsOfHeroBase::setHero(const CGHeroInstance * hero) | ||||
|   | ||||
| @@ -15,15 +15,15 @@ class CArtifactsOfHeroBase : public CIntObject | ||||
| { | ||||
| protected: | ||||
| 	using ArtPlacePtr = std::shared_ptr<CHeroArtPlace>; | ||||
| 	using BpackScrollHandler = std::function<void(int)>; | ||||
| 	using BpackScrollFunctor = std::function<void(int)>; | ||||
|  | ||||
| public: | ||||
| 	using ArtPlaceMap = std::map<ArtifactPosition, ArtPlacePtr>; | ||||
| 	using ClickHandler = std::function<void(CArtifactsOfHeroBase&, CHeroArtPlace&)>; | ||||
| 	using ClickFunctor = std::function<void(CArtifactsOfHeroBase&, CHeroArtPlace&)>; | ||||
| 	using PutBackPickedArtCallback = std::function<void()>; | ||||
|  | ||||
| 	ClickHandler leftClickCallback; | ||||
| 	ClickHandler rightClickCallback; | ||||
| 	ClickFunctor leftClickCallback; | ||||
| 	ClickFunctor showPopupCallback; | ||||
| 	 | ||||
| 	CArtifactsOfHeroBase(); | ||||
| 	virtual void putBackPickedArtifact(); | ||||
| @@ -61,8 +61,8 @@ protected: | ||||
| 		Point(381,296) //18 | ||||
| 	}; | ||||
|  | ||||
| 	virtual void init(CHeroArtPlace::ClickHandler lClickCallback, CHeroArtPlace::ClickHandler rClickCallback, | ||||
| 		const Point & position, BpackScrollHandler scrollHandler); | ||||
| 	virtual void init(CHeroArtPlace::ClickFunctor lClickCallback, CHeroArtPlace::ClickFunctor showPopupCallback, | ||||
| 		const Point & position, BpackScrollFunctor scrollCallback); | ||||
| 	// Assigns an artifacts to an artifact place depending on it's new slot ID | ||||
| 	virtual void setSlotData(ArtPlacePtr artPlace, const ArtifactPosition & slot, const CArtifactSet & artSet); | ||||
| 	virtual void scrollBackpackForArtSet(int offset, const CArtifactSet & artSet); | ||||
|   | ||||
| @@ -29,13 +29,13 @@ CArtifactsOfHeroKingdom::CArtifactsOfHeroKingdom(ArtPlaceMap ArtWorn, std::vecto | ||||
| 		artPlace.second->slot = artPlace.first; | ||||
| 		artPlace.second->setArtifact(nullptr); | ||||
| 		artPlace.second->leftClickCallback = std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1); | ||||
| 		artPlace.second->rightClickCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1); | ||||
| 		artPlace.second->showPopupCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1); | ||||
| 	} | ||||
| 	for(auto artPlace : backpack) | ||||
| 	{ | ||||
| 		artPlace->setArtifact(nullptr); | ||||
| 		artPlace->leftClickCallback = std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1); | ||||
| 		artPlace->rightClickCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1); | ||||
| 		artPlace->showPopupCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1); | ||||
| 	} | ||||
| 	leftBackpackRoll->addCallback(std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, -1)); | ||||
| 	rightBackpackRoll->addCallback(std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, +1)); | ||||
|   | ||||
							
								
								
									
										119
									
								
								client/widgets/CExchangeController.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								client/widgets/CExchangeController.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| /* | ||||
|  * CExchangeController.cpp, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "CExchangeController.h" | ||||
|  | ||||
| #include "../CPlayerInterface.h" | ||||
|  | ||||
| #include "../widgets/CGarrisonInt.h" | ||||
|  | ||||
| #include "../../CCallback.h" | ||||
|  | ||||
| #include "../lib/mapObjects/CGHeroInstance.h" | ||||
|  | ||||
| CExchangeController::CExchangeController(ObjectInstanceID hero1, ObjectInstanceID hero2) | ||||
| 	: left(LOCPLINT->cb->getHero(hero1)) | ||||
| 	, right(LOCPLINT->cb->getHero(hero2)) | ||||
| { | ||||
| } | ||||
|  | ||||
| void CExchangeController::swapArmy() | ||||
| { | ||||
| 	auto getStacks = [](const CArmedInstance * source) -> std::vector<std::pair<SlotID, CStackInstance*>> | ||||
| 	{ | ||||
| 		auto slots = source->Slots(); | ||||
| 		return std::vector<std::pair<SlotID, CStackInstance*>>(slots.begin(), slots.end()); | ||||
| 	}; | ||||
|  | ||||
| 	auto leftSlots = getStacks(left); | ||||
| 	auto rightSlots = getStacks(right); | ||||
|  | ||||
| 	auto i = leftSlots.begin(), j = rightSlots.begin(); | ||||
|  | ||||
| 	for(; i != leftSlots.end() && j != rightSlots.end(); i++, j++) | ||||
| 	{ | ||||
| 		LOCPLINT->cb->swapCreatures(left, right, i->first, j->first); | ||||
| 	} | ||||
|  | ||||
| 	if(i != leftSlots.end()) | ||||
| 	{ | ||||
| 		auto freeSlots = right->getFreeSlots(); | ||||
| 		auto slot = freeSlots.begin(); | ||||
|  | ||||
| 		for(; i != leftSlots.end() && slot != freeSlots.end(); i++, slot++) | ||||
| 		{ | ||||
| 			LOCPLINT->cb->swapCreatures(left, right, i->first, *slot); | ||||
| 		} | ||||
| 	} | ||||
| 	else if(j != rightSlots.end()) | ||||
| 	{ | ||||
| 		auto freeSlots = left->getFreeSlots(); | ||||
| 		auto slot = freeSlots.begin(); | ||||
|  | ||||
| 		for(; j != rightSlots.end() && slot != freeSlots.end(); j++, slot++) | ||||
| 		{ | ||||
| 			LOCPLINT->cb->swapCreatures(left, right, *slot, j->first); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CExchangeController::moveArmy(bool leftToRight, std::optional<SlotID> heldSlot) | ||||
| { | ||||
| 	const auto source = leftToRight ? left : right; | ||||
| 	const auto target = leftToRight ? right : left; | ||||
|  | ||||
| 	if(!heldSlot.has_value()) | ||||
| 	{ | ||||
| 		auto weakestSlot = vstd::minElementByFun(source->Slots(), | ||||
| 			[](const std::pair<SlotID, CStackInstance*> & s) -> int | ||||
| 			{ | ||||
| 				return s.second->getCreatureID().toCreature()->getAIValue(); | ||||
| 			}); | ||||
| 		heldSlot = weakestSlot->first; | ||||
| 	} | ||||
| 	LOCPLINT->cb->bulkMoveArmy(source->id, target->id, heldSlot.value()); | ||||
| } | ||||
|  | ||||
| void CExchangeController::moveStack(bool leftToRight, SlotID sourceSlot) | ||||
| { | ||||
| 	const auto source = leftToRight ? left : right; | ||||
| 	const auto target = leftToRight ? right : left; | ||||
| 	auto creature = source->getCreature(sourceSlot); | ||||
|  | ||||
| 	if(creature == nullptr) | ||||
| 		return; | ||||
|  | ||||
| 	SlotID targetSlot = target->getSlotFor(creature); | ||||
| 	if(targetSlot.validSlot()) | ||||
| 	{ | ||||
| 		if(source->stacksCount() == 1 && source->needsLastStack()) | ||||
| 		{ | ||||
| 			LOCPLINT->cb->splitStack(source, target, sourceSlot, targetSlot, | ||||
| 				target->getStackCount(targetSlot) + source->getStackCount(sourceSlot) - 1); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			LOCPLINT->cb->mergeOrSwapStacks(source, target, sourceSlot, targetSlot); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CExchangeController::swapArtifacts(bool equipped, bool baclpack) | ||||
| { | ||||
| 	LOCPLINT->cb->bulkMoveArtifacts(left->id, right->id, true, equipped, baclpack); | ||||
| } | ||||
|  | ||||
| void CExchangeController::moveArtifacts(bool leftToRight, bool equipped, bool baclpack) | ||||
| { | ||||
| 	const auto source = leftToRight ? left : right; | ||||
| 	const auto target = leftToRight ? right : left; | ||||
|  | ||||
| 	LOCPLINT->cb->bulkMoveArtifacts(source->id, target->id, false, equipped, baclpack); | ||||
| } | ||||
							
								
								
									
										30
									
								
								client/widgets/CExchangeController.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								client/widgets/CExchangeController.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| /* | ||||
|  * CExchangeController.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  #pragma once | ||||
|   | ||||
|  #include "../windows/CWindowObject.h" | ||||
|  #include "CWindowWithArtifacts.h" | ||||
|   | ||||
| class CCallback; | ||||
|  | ||||
| class CExchangeController | ||||
| { | ||||
| public: | ||||
| 	CExchangeController(ObjectInstanceID hero1, ObjectInstanceID hero2); | ||||
| 	void swapArmy(); | ||||
| 	void moveArmy(bool leftToRight, std::optional<SlotID> heldSlot); | ||||
| 	void moveStack(bool leftToRight, SlotID sourceSlot); | ||||
| 	void swapArtifacts(bool equipped, bool baclpack); | ||||
| 	void moveArtifacts(bool leftToRight, bool equipped, bool baclpack); | ||||
|  | ||||
| private: | ||||
| 	const CGHeroInstance * left; | ||||
| 	const CGHeroInstance * right; | ||||
| }; | ||||
| @@ -38,7 +38,7 @@ void CWindowWithArtifacts::addSet(CArtifactsOfHeroPtr artSet) | ||||
| 		{ | ||||
| 			auto artSet = artSetWeak.lock(); | ||||
| 			artSet->leftClickCallback = std::bind(&CWindowWithArtifacts::leftClickArtPlaceHero, this, _1, _2); | ||||
| 			artSet->rightClickCallback = std::bind(&CWindowWithArtifacts::rightClickArtPlaceHero, this, _1, _2); | ||||
| 			artSet->showPopupCallback = std::bind(&CWindowWithArtifacts::rightClickArtPlaceHero, this, _1, _2); | ||||
| 			artSet->setPutBackPickedArtifactCallback(artPutBackHandler); | ||||
| 		}, artSet); | ||||
| } | ||||
|   | ||||
| @@ -19,62 +19,40 @@ | ||||
| #include "../CMusicHandler.h" | ||||
| #include "../CPlayerInterface.h" | ||||
| #include "../CVideoHandler.h" | ||||
| #include "../CServerHandler.h" | ||||
|  | ||||
| #include "../battle/BattleInterfaceClasses.h" | ||||
| #include "../battle/BattleInterface.h" | ||||
|  | ||||
| #include "../gui/CGuiHandler.h" | ||||
| #include "../gui/CursorHandler.h" | ||||
| #include "../gui/TextAlignment.h" | ||||
| #include "../gui/Shortcut.h" | ||||
| #include "../gui/WindowHandler.h" | ||||
|  | ||||
| #include "../widgets/CComponent.h" | ||||
| #include "../widgets/CGarrisonInt.h" | ||||
| #include "../widgets/MiscWidgets.h" | ||||
| #include "../widgets/CreatureCostBox.h" | ||||
| #include "../widgets/Buttons.h" | ||||
| #include "../widgets/Slider.h" | ||||
| #include "../widgets/TextControls.h" | ||||
| #include "../widgets/ObjectLists.h" | ||||
|  | ||||
| #include "../lobby/CSavingScreen.h" | ||||
| #include "../render/Canvas.h" | ||||
| #include "../render/CAnimation.h" | ||||
| #include "../render/IRenderHandler.h" | ||||
| #include "../CMT.h" | ||||
|  | ||||
| #include "../../CCallback.h" | ||||
|  | ||||
| #include "../lib/mapObjectConstructors/AObjectTypeHandler.h" | ||||
| #include "../lib/mapObjectConstructors/CObjectClassesHandler.h" | ||||
| #include "../lib/mapObjectConstructors/CommonConstructors.h" | ||||
| #include "../lib/mapObjects/CGHeroInstance.h" | ||||
| #include "../lib/mapObjects/CGMarket.h" | ||||
| #include "../lib/ArtifactUtils.h" | ||||
| #include "../lib/mapObjects/CGTownInstance.h" | ||||
| #include "../lib/mapObjects/ObjectTemplate.h" | ||||
| #include "../lib/gameState/CGameState.h" | ||||
| #include "../lib/gameState/InfoAboutArmy.h" | ||||
| #include "../lib/gameState/SThievesGuildInfo.h" | ||||
| #include "../lib/CArtHandler.h" | ||||
| #include "../lib/CBuildingHandler.h" | ||||
| #include "../lib/CConfigHandler.h" | ||||
| #include "../lib/CCreatureHandler.h" | ||||
| #include "../lib/CGeneralTextHandler.h" | ||||
| #include "../lib/CHeroHandler.h" | ||||
| #include "../lib/GameSettings.h" | ||||
| #include "../lib/CondSh.h" | ||||
| #include "../lib/CSkillHandler.h" | ||||
| #include "../lib/spells/CSpellHandler.h" | ||||
| #include "../lib/filesystem/Filesystem.h" | ||||
| #include "../lib/CStopWatch.h" | ||||
| #include "../lib/CTownHandler.h" | ||||
| #include "../lib/GameConstants.h" | ||||
| #include "../lib/bonuses/Bonus.h" | ||||
| #include "../lib/NetPacksBase.h" | ||||
| #include "../lib/StartInfo.h" | ||||
| #include "../lib/TextOperations.h" | ||||
|  | ||||
| CRecruitmentWindow::CCreatureCard::CCreatureCard(CRecruitmentWindow * window, const CCreature * crea, int totalAmount) | ||||
| @@ -623,223 +601,9 @@ static bool isQuickExchangeLayoutAvailable() | ||||
| 	return CResourceHandler::get()->existsResource(ImagePath::builtin("SPRITES/" + QUICK_EXCHANGE_BG)); | ||||
| } | ||||
|  | ||||
| CExchangeController::CExchangeController(CExchangeWindow * view, ObjectInstanceID hero1, ObjectInstanceID hero2) | ||||
| 	:left(LOCPLINT->cb->getHero(hero1)), right(LOCPLINT->cb->getHero(hero2)), cb(LOCPLINT->cb), view(view) | ||||
| { | ||||
| } | ||||
|  | ||||
| std::function<void()> CExchangeController::onMoveArmyToLeft() | ||||
| { | ||||
| 	return [&]() { moveArmy(false); }; | ||||
| } | ||||
|  | ||||
| std::function<void()> CExchangeController::onMoveArmyToRight() | ||||
| { | ||||
| 	return [&]() { moveArmy(true); }; | ||||
| } | ||||
|  | ||||
| std::vector<CArtifactInstance *> getBackpackArts(const CGHeroInstance * hero) | ||||
| { | ||||
| 	std::vector<CArtifactInstance *> result; | ||||
|  | ||||
| 	for(auto slot : hero->artifactsInBackpack) | ||||
| 	{ | ||||
| 		result.push_back(slot.artifact); | ||||
| 	} | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| std::function<void()> CExchangeController::onSwapArtifacts() | ||||
| { | ||||
| 	return [&]() | ||||
| 	{ | ||||
| 		if(GH.isKeyboardCtrlDown()) | ||||
| 			cb->bulkMoveArtifacts(left->id, right->id, true, true, false); | ||||
| 		else if(GH.isKeyboardShiftDown()) | ||||
| 			cb->bulkMoveArtifacts(left->id, right->id, true, false, true); | ||||
| 		else | ||||
| 			cb->bulkMoveArtifacts(left->id, right->id, true); | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| std::function<void()> CExchangeController::onMoveArtifactsToLeft() | ||||
| { | ||||
| 	return [&]() { moveArtifacts(false); }; | ||||
| } | ||||
|  | ||||
| std::function<void()> CExchangeController::onMoveArtifactsToRight() | ||||
| { | ||||
| 	return [&]() { moveArtifacts(true); }; | ||||
| } | ||||
|  | ||||
| std::vector<std::pair<SlotID, CStackInstance *>> getStacks(const CArmedInstance * source) | ||||
| { | ||||
| 	auto slots = source->Slots(); | ||||
|  | ||||
| 	return std::vector<std::pair<SlotID, CStackInstance *>>(slots.begin(), slots.end()); | ||||
| } | ||||
|  | ||||
| std::function<void()> CExchangeController::onSwapArmy() | ||||
| { | ||||
| 	return [&]() | ||||
| 	{ | ||||
| 		if(left->tempOwner != cb->getPlayerID() | ||||
| 		   || right->tempOwner != cb->getPlayerID()) | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		auto leftSlots = getStacks(left); | ||||
| 		auto rightSlots = getStacks(right); | ||||
|  | ||||
| 		auto i = leftSlots.begin(), j = rightSlots.begin(); | ||||
|  | ||||
| 		for(; i != leftSlots.end() && j != rightSlots.end(); i++, j++) | ||||
| 		{ | ||||
| 			cb->swapCreatures(left, right, i->first, j->first); | ||||
| 		} | ||||
|  | ||||
| 		if(i != leftSlots.end()) | ||||
| 		{ | ||||
| 			auto freeSlots = right->getFreeSlots(); | ||||
| 			auto slot = freeSlots.begin(); | ||||
|  | ||||
| 			for(; i != leftSlots.end() && slot != freeSlots.end(); i++, slot++) | ||||
| 			{ | ||||
| 				cb->swapCreatures(left, right, i->first, *slot); | ||||
| 			} | ||||
| 		} | ||||
| 		else if(j != rightSlots.end()) | ||||
| 		{ | ||||
| 			auto freeSlots = left->getFreeSlots(); | ||||
| 			auto slot = freeSlots.begin(); | ||||
|  | ||||
| 			for(; j != rightSlots.end() && slot != freeSlots.end(); j++, slot++) | ||||
| 			{ | ||||
| 				cb->swapCreatures(left, right, *slot, j->first); | ||||
| 			} | ||||
| 		} | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| std::function<void()> CExchangeController::onMoveStackToLeft(SlotID slotID) | ||||
| { | ||||
| 	return [=]() | ||||
| 	{ | ||||
| 		if(right->tempOwner != cb->getPlayerID()) | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		moveStack(right, left, slotID); | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| std::function<void()> CExchangeController::onMoveStackToRight(SlotID slotID) | ||||
| { | ||||
| 	return [=]() | ||||
| 	{ | ||||
| 		if(left->tempOwner != cb->getPlayerID()) | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		moveStack(left, right, slotID); | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| void CExchangeController::moveStack( | ||||
| 	const CGHeroInstance * source, | ||||
| 	const CGHeroInstance * target, | ||||
| 	SlotID sourceSlot) | ||||
| { | ||||
| 	auto creature = source->getCreature(sourceSlot); | ||||
| 	if(creature == nullptr) | ||||
| 		return; | ||||
|  | ||||
| 	SlotID targetSlot = target->getSlotFor(creature); | ||||
|  | ||||
| 	if(targetSlot.validSlot()) | ||||
| 	{ | ||||
| 		if(source->stacksCount() == 1 && source->needsLastStack()) | ||||
| 		{ | ||||
| 			cb->splitStack( | ||||
| 				source, | ||||
| 				target, | ||||
| 				sourceSlot, | ||||
| 				targetSlot, | ||||
| 				target->getStackCount(targetSlot) + source->getStackCount(sourceSlot) - 1); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			cb->mergeOrSwapStacks(source, target, sourceSlot, targetSlot); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CExchangeController::moveArmy(bool leftToRight) | ||||
| { | ||||
| 	const CGHeroInstance * source = leftToRight ? left : right; | ||||
| 	const CGHeroInstance * target = leftToRight ? right : left; | ||||
| 	const CGarrisonSlot * selection =  this->view->getSelectedSlotID(); | ||||
| 	SlotID slot; | ||||
|  | ||||
| 	if(source->tempOwner != cb->getPlayerID()) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if(selection && selection->our() && selection->getObj() == source) | ||||
| 	{ | ||||
| 		slot = selection->getSlot(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		auto weakestSlot = vstd::minElementByFun( | ||||
| 			source->Slots(),  | ||||
| 			[](const std::pair<SlotID, CStackInstance *> & s) -> int | ||||
| 			{ | ||||
| 				return s.second->getCreatureID().toCreature()->getAIValue(); | ||||
| 			}); | ||||
|  | ||||
| 		slot = weakestSlot->first; | ||||
| 	} | ||||
|  | ||||
| 	cb->bulkMoveArmy(source->id, target->id, slot); | ||||
| } | ||||
|  | ||||
| void CExchangeController::moveArtifacts(bool leftToRight) | ||||
| { | ||||
| 	const CGHeroInstance * source = leftToRight ? left : right; | ||||
| 	const CGHeroInstance * target = leftToRight ? right : left; | ||||
|  | ||||
| 	if(source->tempOwner != cb->getPlayerID()) | ||||
| 		return; | ||||
|  | ||||
| 	if(GH.isKeyboardCtrlDown()) | ||||
| 		cb->bulkMoveArtifacts(source->id, target->id, false, true, false); | ||||
| 	else if(GH.isKeyboardShiftDown()) | ||||
| 		cb->bulkMoveArtifacts(source->id, target->id, false, false, true); | ||||
| 	else | ||||
| 		cb->bulkMoveArtifacts(source->id, target->id, false); | ||||
| } | ||||
|  | ||||
| void CExchangeController::moveArtifact( | ||||
| 	const CGHeroInstance * source, | ||||
| 	const CGHeroInstance * target, | ||||
| 	ArtifactPosition srcPosition) | ||||
| { | ||||
| 	auto srcLocation = ArtifactLocation(source, srcPosition); | ||||
| 	auto dstLocation = ArtifactLocation(target, | ||||
| 		ArtifactUtils::getArtAnyPosition(target, source->getArt(srcPosition)->getTypeId())); | ||||
|  | ||||
| 	cb->swapArtifacts(srcLocation, dstLocation); | ||||
| } | ||||
|  | ||||
| CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID queryID) | ||||
| 	: CStatusbarWindow(PLAYER_COLORED | BORDERED, ImagePath::builtin(isQuickExchangeLayoutAvailable() ? QUICK_EXCHANGE_BG : "TRADE2")), | ||||
| 	controller(this, hero1, hero2), | ||||
| 	controller(hero1, hero2), | ||||
| 	moveStackLeftButtons(), | ||||
| 	moveStackRightButtons() | ||||
| { | ||||
| @@ -990,12 +754,38 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, | ||||
|  | ||||
| 	if(qeLayout) | ||||
| 	{ | ||||
| 		moveAllGarrButtonLeft    = std::make_shared<CButton>(Point(325, 118), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/armRight.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[1]), controller.onMoveArmyToRight()); | ||||
| 		echangeGarrButton        = std::make_shared<CButton>(Point(377, 118), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/swapAll.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[2]), controller.onSwapArmy()); | ||||
| 		moveAllGarrButtonRight   = std::make_shared<CButton>(Point(425, 118), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/armLeft.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[1]), controller.onMoveArmyToLeft()); | ||||
| 		moveArtifactsButtonLeft  = std::make_shared<CButton>(Point(325, 154), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/artRight.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[3]), controller.onMoveArtifactsToRight()); | ||||
| 		echangeArtifactsButton   = std::make_shared<CButton>(Point(377, 154), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/swapAll.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[4]), controller.onSwapArtifacts()); | ||||
| 		moveArtifactsButtonRight = std::make_shared<CButton>(Point(425, 154), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/artLeft.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[3]), controller.onMoveArtifactsToLeft()); | ||||
| 		auto moveArtifacts = [this](std::function<void(bool, bool)> moveRoutine) -> void | ||||
| 		{ | ||||
| 			bool moveEquipped = true; | ||||
| 			bool moveBackpack = true; | ||||
|  | ||||
| 			if(GH.isKeyboardCtrlDown()) | ||||
| 				moveBackpack = false; | ||||
| 			else if(GH.isKeyboardShiftDown()) | ||||
| 				moveEquipped = false; | ||||
| 			moveRoutine(moveEquipped, moveBackpack); | ||||
| 		}; | ||||
|  | ||||
| 		auto moveArmy = [this](bool leftToRight) -> void | ||||
| 		{ | ||||
| 			std::optional<SlotID> slotId = std::nullopt; | ||||
| 			if(auto slot = getSelectedSlotID()) | ||||
| 				slotId = slot->getSlot(); | ||||
| 			controller.moveArmy(leftToRight, slotId); | ||||
| 		}; | ||||
|  | ||||
| 		moveAllGarrButtonLeft    = std::make_shared<CButton>(Point(325, 118), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/armRight.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[1]), | ||||
| 			std::bind(moveArmy, true)); | ||||
| 		echangeGarrButton        = std::make_shared<CButton>(Point(377, 118), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/swapAll.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[2]), | ||||
| 			std::bind(&CExchangeController::swapArmy, &controller)); | ||||
| 		moveAllGarrButtonRight   = std::make_shared<CButton>(Point(425, 118), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/armLeft.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[1]), | ||||
| 			std::bind(moveArmy, false)); | ||||
| 		moveArtifactsButtonLeft  = std::make_shared<CButton>(Point(325, 154), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/artRight.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[3]), | ||||
| 			std::bind(moveArtifacts, [this](bool equipped, bool baclpack) -> void {controller.moveArtifacts(true, equipped, baclpack);})); | ||||
| 		echangeArtifactsButton   = std::make_shared<CButton>(Point(377, 154), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/swapAll.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[4]), | ||||
| 			std::bind(moveArtifacts, [this](bool equipped, bool baclpack) -> void {controller.swapArtifacts(equipped, baclpack);})); | ||||
| 		moveArtifactsButtonRight = std::make_shared<CButton>(Point(425, 154), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/artLeft.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[3]), | ||||
| 			std::bind(moveArtifacts, [this](bool equipped, bool baclpack) -> void {controller.moveArtifacts(false, equipped, baclpack);})); | ||||
|  | ||||
| 		for(int i = 0; i < GameConstants::ARMY_SIZE; i++) | ||||
| 		{ | ||||
| @@ -1004,14 +794,14 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, | ||||
| 					Point(484 + 35 * i, 154), | ||||
| 					AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/unitLeft.DEF"), | ||||
| 					CButton::tooltip(CGI->generaltexth->qeModCommands[1]), | ||||
| 					controller.onMoveStackToLeft(SlotID(i)))); | ||||
| 					std::bind(&CExchangeController::moveStack, &controller, false, SlotID(i)))); | ||||
|  | ||||
| 			moveStackRightButtons.push_back( | ||||
| 				std::make_shared<CButton>( | ||||
| 					Point(66 + 35 * i, 154), | ||||
| 					AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/unitRight.DEF"), | ||||
| 					CButton::tooltip(CGI->generaltexth->qeModCommands[1]), | ||||
| 					controller.onMoveStackToRight(SlotID(i)))); | ||||
| 					std::bind(&CExchangeController::moveStack, &controller, true, SlotID(i)))); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -9,10 +9,8 @@ | ||||
|  */ | ||||
| #pragma once | ||||
|  | ||||
| #include "CWindowObject.h" | ||||
| #include "../lib/GameConstants.h" | ||||
| #include "../lib/ResourceSet.h" | ||||
| #include "../lib/int3.h" | ||||
| #include "../widgets/CExchangeController.h" | ||||
| #include "../widgets/CWindowWithArtifacts.h" | ||||
| #include "../widgets/Images.h" | ||||
|  | ||||
| @@ -28,16 +26,13 @@ class CreatureCostBox; | ||||
| class CCreaturePic; | ||||
| class MoraleLuckBox; | ||||
| class CHeroArea; | ||||
| class CMinorResDataBar; | ||||
| class CSlider; | ||||
| class CComponentBox; | ||||
| class CTextInput; | ||||
| class CListBox; | ||||
| class CLabelGroup; | ||||
| class CToggleButton; | ||||
| class CGStatusBar; | ||||
| class CTextBox; | ||||
| class CResDataBar; | ||||
| class CGarrisonInt; | ||||
| class CGarrisonSlot; | ||||
|  | ||||
| @@ -246,35 +241,6 @@ public: | ||||
| 	void show(Canvas & to) override; | ||||
| }; | ||||
|  | ||||
| class CCallback; | ||||
| class CExchangeWindow; | ||||
|  | ||||
| class CExchangeController | ||||
| { | ||||
| private: | ||||
| 	const CGHeroInstance * left; | ||||
| 	const CGHeroInstance * right; | ||||
| 	std::shared_ptr<CCallback> cb; | ||||
| 	CExchangeWindow * view; | ||||
|  | ||||
| public: | ||||
| 	CExchangeController(CExchangeWindow * view, ObjectInstanceID hero1, ObjectInstanceID hero2); | ||||
| 	std::function<void()> onMoveArmyToRight(); | ||||
| 	std::function<void()> onSwapArmy(); | ||||
| 	std::function<void()> onMoveArmyToLeft(); | ||||
| 	std::function<void()> onSwapArtifacts(); | ||||
| 	std::function<void()> onMoveArtifactsToLeft(); | ||||
| 	std::function<void()> onMoveArtifactsToRight(); | ||||
| 	std::function<void()> onMoveStackToLeft(SlotID slotID); | ||||
| 	std::function<void()> onMoveStackToRight(SlotID slotID); | ||||
|  | ||||
| private: | ||||
| 	void moveArmy(bool leftToRight); | ||||
| 	void moveArtifacts(bool leftToRight); | ||||
| 	void moveArtifact(const CGHeroInstance * source, const CGHeroInstance * target, ArtifactPosition srcPosition); | ||||
| 	void moveStack(const CGHeroInstance * source, const CGHeroInstance * target, SlotID sourceSlot); | ||||
| }; | ||||
|  | ||||
| class CExchangeWindow : public CStatusbarWindow, public IGarrisonHolder, public CWindowWithArtifacts | ||||
| { | ||||
| 	std::array<std::shared_ptr<CLabel>, 2> titles; | ||||
|   | ||||
| @@ -171,7 +171,6 @@ DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(CArtifa | ||||
| 	auto * artInst = new CArtifactInstance(art); | ||||
| 	if(art->isCombined()) | ||||
| 	{ | ||||
| 		assert(art->isCombined()); | ||||
| 		for(const auto & part : art->getConstituents()) | ||||
| 			artInst->addPart(ArtifactUtils::createNewArtifactInstance(part), ArtifactPosition::PRE_FIRST); | ||||
| 	} | ||||
|   | ||||
| @@ -44,12 +44,6 @@ bool CCombinedArtifactInstance::isPart(const CArtifactInstance * supposedPart) c | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| std::vector<CCombinedArtifactInstance::PartInfo> & CCombinedArtifactInstance::getPartsInfo() | ||||
| { | ||||
| 	// TODO romove this func. encapsulation violation | ||||
| 	return partsInfo; | ||||
| } | ||||
|  | ||||
| const std::vector<CCombinedArtifactInstance::PartInfo> & CCombinedArtifactInstance::getPartsInfo() const | ||||
| { | ||||
| 	return partsInfo; | ||||
|   | ||||
| @@ -38,7 +38,6 @@ public: | ||||
| 	void addPart(CArtifactInstance * art, const ArtifactPosition & slot); | ||||
| 	// Checks if supposed part inst is part of this combined art inst | ||||
| 	bool isPart(const CArtifactInstance * supposedPart) const; | ||||
| 	std::vector<PartInfo> & getPartsInfo(); | ||||
| 	const std::vector<PartInfo> & getPartsInfo() const; | ||||
| 	void addPlacementMap(CArtifactSet::ArtPlacementMap & placementMap); | ||||
|  | ||||
|   | ||||
| @@ -492,7 +492,7 @@ void CMap::checkForObjectives() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CMap::addNewArtifactInstance(CArtifactInstance * art) | ||||
| void CMap::addNewArtifactInstance(ConstTransitivePtr<CArtifactInstance> art) | ||||
| { | ||||
| 	art->setId(static_cast<ArtifactInstanceID>(artInstances.size())); | ||||
| 	artInstances.emplace_back(art); | ||||
|   | ||||
| @@ -94,7 +94,7 @@ public: | ||||
| 	void removeBlockVisTiles(CGObjectInstance * obj, bool total = false); | ||||
| 	void calculateGuardingGreaturePositions(); | ||||
|  | ||||
| 	void addNewArtifactInstance(CArtifactInstance * art); | ||||
| 	void addNewArtifactInstance(ConstTransitivePtr<CArtifactInstance> art); | ||||
| 	void eraseArtifactInstance(CArtifactInstance * art); | ||||
|  | ||||
| 	void addNewQuestInstance(CQuest * quest); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user