mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Saving costume
This commit is contained in:
		| @@ -193,6 +193,14 @@ void CCallback::scrollBackpackArtifacts(ObjectInstanceID hero, bool left) | |||||||
| 	sendRequest(&mba); | 	sendRequest(&mba); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void CCallback::manageHeroCostume(ObjectInstanceID hero, size_t costumeIndex, bool saveCostume) | ||||||
|  | { | ||||||
|  | 	assert(costumeIndex < GameConstants::HERO_COSTUMES_ARTIFACTS); | ||||||
|  |  | ||||||
|  | 	ManageEquippedArtifacts mea(hero, costumeIndex, saveCostume); | ||||||
|  | 	sendRequest(&mea); | ||||||
|  | } | ||||||
|  |  | ||||||
| void CCallback::eraseArtifactByClient(const ArtifactLocation & al) | void CCallback::eraseArtifactByClient(const ArtifactLocation & al) | ||||||
| { | { | ||||||
| 	EraseArtifactByClient ea(al); | 	EraseArtifactByClient ea(al); | ||||||
|   | |||||||
| @@ -92,6 +92,7 @@ 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 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 bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2)=0; | ||||||
| 	virtual void scrollBackpackArtifacts(ObjectInstanceID hero, bool left) = 0; | 	virtual void scrollBackpackArtifacts(ObjectInstanceID hero, bool left) = 0; | ||||||
|  | 	virtual void manageHeroCostume(ObjectInstanceID hero, size_t costumeIndex, bool saveCostume) = 0; | ||||||
| 	virtual void assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)=0; | 	virtual void assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)=0; | ||||||
| 	virtual void eraseArtifactByClient(const ArtifactLocation & al)=0; | 	virtual void eraseArtifactByClient(const ArtifactLocation & al)=0; | ||||||
| 	virtual bool dismissCreature(const CArmedInstance *obj, SlotID stackPos)=0; | 	virtual bool dismissCreature(const CArmedInstance *obj, SlotID stackPos)=0; | ||||||
| @@ -178,6 +179,7 @@ public: | |||||||
| 	void assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo) 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 bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap, bool equipped = true, bool backpack = true) override; | ||||||
| 	void scrollBackpackArtifacts(ObjectInstanceID hero, bool left) override; | 	void scrollBackpackArtifacts(ObjectInstanceID hero, bool left) override; | ||||||
|  | 	void manageHeroCostume(ObjectInstanceID hero, size_t costumeIdx, bool saveCostume) override; | ||||||
| 	void eraseArtifactByClient(const ArtifactLocation & al) override; | 	void eraseArtifactByClient(const ArtifactLocation & al) override; | ||||||
| 	bool buildBuilding(const CGTownInstance *town, BuildingID buildingID) 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; | 	void recruitCreatures(const CGDwelling * obj, const CArmedInstance * dst, CreatureID ID, ui32 amount, si32 level=-1) override; | ||||||
|   | |||||||
| @@ -158,6 +158,16 @@ enum class EShortcut | |||||||
| 	HERO_TIGHT_FORMATION, | 	HERO_TIGHT_FORMATION, | ||||||
| 	HERO_TOGGLE_TACTICS, // b | 	HERO_TOGGLE_TACTICS, // b | ||||||
| 	HERO_BACKPACK, | 	HERO_BACKPACK, | ||||||
|  | 	HERO_COSTUME_0, | ||||||
|  | 	HERO_COSTUME_1, | ||||||
|  | 	HERO_COSTUME_2, | ||||||
|  | 	HERO_COSTUME_3, | ||||||
|  | 	HERO_COSTUME_4, | ||||||
|  | 	HERO_COSTUME_5, | ||||||
|  | 	HERO_COSTUME_6, | ||||||
|  | 	HERO_COSTUME_7, | ||||||
|  | 	HERO_COSTUME_8, | ||||||
|  | 	HERO_COSTUME_9, | ||||||
|  |  | ||||||
| 	// Spellbook screen | 	// Spellbook screen | ||||||
| 	SPELLBOOK_TAB_ADVENTURE, | 	SPELLBOOK_TAB_ADVENTURE, | ||||||
|   | |||||||
| @@ -180,6 +180,16 @@ EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const | |||||||
| 		{"heroLooseFormation",       EShortcut::HERO_LOOSE_FORMATION      }, | 		{"heroLooseFormation",       EShortcut::HERO_LOOSE_FORMATION      }, | ||||||
| 		{"heroTightFormation",       EShortcut::HERO_TIGHT_FORMATION      }, | 		{"heroTightFormation",       EShortcut::HERO_TIGHT_FORMATION      }, | ||||||
| 		{"heroToggleTactics",        EShortcut::HERO_TOGGLE_TACTICS       }, | 		{"heroToggleTactics",        EShortcut::HERO_TOGGLE_TACTICS       }, | ||||||
|  | 		{"heroCostume0",             EShortcut::HERO_COSTUME_0            }, | ||||||
|  | 		{"heroCostume1",             EShortcut::HERO_COSTUME_1            }, | ||||||
|  | 		{"heroCostume2",             EShortcut::HERO_COSTUME_2            }, | ||||||
|  | 		{"heroCostume3",             EShortcut::HERO_COSTUME_3            }, | ||||||
|  | 		{"heroCostume4",             EShortcut::HERO_COSTUME_4            }, | ||||||
|  | 		{"heroCostume5",             EShortcut::HERO_COSTUME_5            }, | ||||||
|  | 		{"heroCostume6",             EShortcut::HERO_COSTUME_6            }, | ||||||
|  | 		{"heroCostume7",             EShortcut::HERO_COSTUME_7            }, | ||||||
|  | 		{"heroCostume8",             EShortcut::HERO_COSTUME_8            }, | ||||||
|  | 		{"heroCostume9",             EShortcut::HERO_COSTUME_9            }, | ||||||
| 		{"spellbookTabAdventure",    EShortcut::SPELLBOOK_TAB_ADVENTURE   }, | 		{"spellbookTabAdventure",    EShortcut::SPELLBOOK_TAB_ADVENTURE   }, | ||||||
| 		{"spellbookTabCombat",       EShortcut::SPELLBOOK_TAB_COMBAT      } | 		{"spellbookTabCombat",       EShortcut::SPELLBOOK_TAB_COMBAT      } | ||||||
| 	}; | 	}; | ||||||
|   | |||||||
| @@ -10,13 +10,15 @@ | |||||||
| #include "StdInc.h" | #include "StdInc.h" | ||||||
| #include "CArtifactsOfHeroMain.h" | #include "CArtifactsOfHeroMain.h" | ||||||
|  |  | ||||||
|  | #include "../gui/CGuiHandler.h" | ||||||
|  |  | ||||||
| #include "../CPlayerInterface.h" | #include "../CPlayerInterface.h" | ||||||
| #include "../../lib/mapObjects/CGHeroInstance.h" | #include "../../lib/mapObjects/CGHeroInstance.h" | ||||||
|  |  | ||||||
| #include "../../CCallback.h" | #include "../../CCallback.h" | ||||||
| #include "../../lib/networkPacks/ArtifactLocation.h" | #include "../../lib/networkPacks/ArtifactLocation.h" | ||||||
|  |  | ||||||
| CArtifactsOfHeroMain::CArtifactsOfHeroMain(const Point & position) | CArtifactsOfHeroMain::CArtifactsOfHeroMain(const Point & position, bool costumesEnabled) | ||||||
| { | { | ||||||
| 	init( | 	init( | ||||||
| 		std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2), | 		std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2), | ||||||
| @@ -24,9 +26,41 @@ CArtifactsOfHeroMain::CArtifactsOfHeroMain(const Point & position) | |||||||
| 		position, | 		position, | ||||||
| 		std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, _1)); | 		std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, _1)); | ||||||
| 	addGestureCallback(std::bind(&CArtifactsOfHeroBase::gestureArtPlace, this, _1, _2)); | 	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() | CArtifactsOfHeroMain::~CArtifactsOfHeroMain() | ||||||
| { | { | ||||||
| 	CArtifactsOfHeroBase::putBackPickedArtifact(); | 	CArtifactsOfHeroBase::putBackPickedArtifact(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void CArtifactsOfHeroMain::onCostumeSelect(const size_t costumeIndex) | ||||||
|  | { | ||||||
|  | 	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(); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -11,15 +11,42 @@ | |||||||
|  |  | ||||||
| #include "CArtifactsOfHeroBase.h" | #include "CArtifactsOfHeroBase.h" | ||||||
|  |  | ||||||
| VCMI_LIB_NAMESPACE_BEGIN | #include "../gui/Shortcut.h" | ||||||
|  |  | ||||||
| struct ArtifactLocation; |  | ||||||
|  |  | ||||||
| VCMI_LIB_NAMESPACE_END |  | ||||||
|  |  | ||||||
| class CArtifactsOfHeroMain : public CArtifactsOfHeroBase | class CArtifactsOfHeroMain : public CArtifactsOfHeroBase | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	CArtifactsOfHeroMain(const Point & position); | 	CArtifactsOfHeroMain(const Point & position, bool costumesEnabled = false); | ||||||
| 	~CArtifactsOfHeroMain() override; | 	~CArtifactsOfHeroMain() override; | ||||||
|  |  | ||||||
|  | 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 = | ||||||
|  | 	{ | ||||||
|  | 		EShortcut::HERO_COSTUME_0, | ||||||
|  | 		EShortcut::HERO_COSTUME_1, | ||||||
|  | 		EShortcut::HERO_COSTUME_2, | ||||||
|  | 		EShortcut::HERO_COSTUME_3, | ||||||
|  | 		EShortcut::HERO_COSTUME_4, | ||||||
|  | 		EShortcut::HERO_COSTUME_5, | ||||||
|  | 		EShortcut::HERO_COSTUME_6, | ||||||
|  | 		EShortcut::HERO_COSTUME_7, | ||||||
|  | 		EShortcut::HERO_COSTUME_8, | ||||||
|  | 		EShortcut::HERO_COSTUME_9 | ||||||
|  | 	}; | ||||||
|  | 	std::vector<std::shared_ptr<CKeyShortcutWrapper>> costumesSwitchers; | ||||||
|  |  | ||||||
|  | 	void onCostumeSelect(const size_t costumeIndex); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -218,7 +218,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded) | |||||||
| 		} | 		} | ||||||
| 		if(!arts) | 		if(!arts) | ||||||
| 		{ | 		{ | ||||||
| 			arts = std::make_shared<CArtifactsOfHeroMain>(Point(-65, -8)); | 			arts = std::make_shared<CArtifactsOfHeroMain>(Point(-65, -8), true); | ||||||
| 			arts->setHero(curHero); | 			arts->setHero(curHero); | ||||||
| 			addSetAndCallbacks(arts); | 			addSetAndCallbacks(arts); | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -125,6 +125,16 @@ | |||||||
| 		"heroTightFormation":       "T", | 		"heroTightFormation":       "T", | ||||||
| 		"heroToggleTactics":        "B", | 		"heroToggleTactics":        "B", | ||||||
| 		"spellbookTabAdventure":    "A", | 		"spellbookTabAdventure":    "A", | ||||||
| 		"spellbookTabCombat":       "C" | 		"spellbookTabCombat":       "C", | ||||||
|  | 		"heroCostume0":             "0", | ||||||
|  | 		"heroCostume1":             "1", | ||||||
|  | 		"heroCostume2":             "2", | ||||||
|  | 		"heroCostume3":             "3", | ||||||
|  | 		"heroCostume4":             "4", | ||||||
|  | 		"heroCostume5":             "5", | ||||||
|  | 		"heroCostume6":             "6", | ||||||
|  | 		"heroCostume7":             "7", | ||||||
|  | 		"heroCostume8":             "8", | ||||||
|  | 		"heroCostume9":             "9" | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -63,6 +63,7 @@ public: | |||||||
| 	std::vector<ConstTransitivePtr<CGDwelling> > dwellings; //used for town growth | 	std::vector<ConstTransitivePtr<CGDwelling> > dwellings; //used for town growth | ||||||
| 	std::vector<QuestInfo> quests; //store info about all received quests | 	std::vector<QuestInfo> quests; //store info about all received quests | ||||||
| 	std::vector<Bonus> battleBonuses; //additional bonuses to be added during battle with neutrals | 	std::vector<Bonus> battleBonuses; //additional bonuses to be added during battle with neutrals | ||||||
|  | 	std::map<size_t, std::map<ArtifactPosition, ArtifactID>> costumesArtifacts; | ||||||
|  |  | ||||||
| 	bool cheated; | 	bool cheated; | ||||||
| 	bool enteredWinningCheatCode, enteredLosingCheatCode; //if true, this player has entered cheat codes for loss / victory | 	bool enteredWinningCheatCode, enteredLosingCheatCode; //if true, this player has entered cheat codes for loss / victory | ||||||
| @@ -111,6 +112,7 @@ public: | |||||||
| 		h & daysWithoutCastle; | 		h & daysWithoutCastle; | ||||||
| 		h & cheated; | 		h & cheated; | ||||||
| 		h & battleBonuses; | 		h & battleBonuses; | ||||||
|  | 		h & costumesArtifacts; | ||||||
| 		h & enteredLosingCheatCode; | 		h & enteredLosingCheatCode; | ||||||
| 		h & enteredWinningCheatCode; | 		h & enteredWinningCheatCode; | ||||||
| 		h & static_cast<CBonusSystemNode&>(*this); | 		h & static_cast<CBonusSystemNode&>(*this); | ||||||
|   | |||||||
| @@ -87,6 +87,7 @@ public: | |||||||
| 	virtual void visitInfoWindow(InfoWindow & pack) {} | 	virtual void visitInfoWindow(InfoWindow & pack) {} | ||||||
| 	virtual void visitSetObjectProperty(SetObjectProperty & pack) {} | 	virtual void visitSetObjectProperty(SetObjectProperty & pack) {} | ||||||
| 	virtual void visitChangeObjectVisitors(ChangeObjectVisitors & pack) {} | 	virtual void visitChangeObjectVisitors(ChangeObjectVisitors & pack) {} | ||||||
|  | 	virtual void visitChangeArtifactsCostume(ChangeArtifactsCostume & pack) {} | ||||||
| 	virtual void visitHeroLevelUp(HeroLevelUp & pack) {} | 	virtual void visitHeroLevelUp(HeroLevelUp & pack) {} | ||||||
| 	virtual void visitCommanderLevelUp(CommanderLevelUp & pack) {} | 	virtual void visitCommanderLevelUp(CommanderLevelUp & pack) {} | ||||||
| 	virtual void visitBlockingDialog(BlockingDialog & pack) {} | 	virtual void visitBlockingDialog(BlockingDialog & pack) {} | ||||||
| @@ -132,6 +133,7 @@ public: | |||||||
| 	virtual void visitExchangeArtifacts(ExchangeArtifacts & pack) {} | 	virtual void visitExchangeArtifacts(ExchangeArtifacts & pack) {} | ||||||
| 	virtual void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) {} | 	virtual void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) {} | ||||||
| 	virtual void visitManageBackpackArtifacts(ManageBackpackArtifacts & pack) {} | 	virtual void visitManageBackpackArtifacts(ManageBackpackArtifacts & pack) {} | ||||||
|  | 	virtual void visitManageEquippedArtifacts(ManageEquippedArtifacts & pack) {} | ||||||
| 	virtual void visitAssembleArtifacts(AssembleArtifacts & pack) {} | 	virtual void visitAssembleArtifacts(AssembleArtifacts & pack) {} | ||||||
| 	virtual void visitEraseArtifactByClient(EraseArtifactByClient & pack) {} | 	virtual void visitEraseArtifactByClient(EraseArtifactByClient & pack) {} | ||||||
| 	virtual void visitBuyArtifact(BuyArtifact & pack) {} | 	virtual void visitBuyArtifact(BuyArtifact & pack) {} | ||||||
|   | |||||||
| @@ -383,6 +383,11 @@ void ChangeObjectVisitors::visitTyped(ICPackVisitor & visitor) | |||||||
| 	visitor.visitChangeObjectVisitors(*this); | 	visitor.visitChangeObjectVisitors(*this); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void ChangeArtifactsCostume::visitTyped(ICPackVisitor & visitor) | ||||||
|  | { | ||||||
|  | 	visitor.visitChangeArtifactsCostume(*this); | ||||||
|  | } | ||||||
|  |  | ||||||
| void HeroLevelUp::visitTyped(ICPackVisitor & visitor) | void HeroLevelUp::visitTyped(ICPackVisitor & visitor) | ||||||
| { | { | ||||||
| 	visitor.visitHeroLevelUp(*this); | 	visitor.visitHeroLevelUp(*this); | ||||||
| @@ -613,6 +618,11 @@ void ManageBackpackArtifacts::visitTyped(ICPackVisitor & visitor) | |||||||
| 	visitor.visitManageBackpackArtifacts(*this); | 	visitor.visitManageBackpackArtifacts(*this); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void ManageEquippedArtifacts::visitTyped(ICPackVisitor & visitor) | ||||||
|  | { | ||||||
|  | 	visitor.visitManageEquippedArtifacts(*this); | ||||||
|  | } | ||||||
|  |  | ||||||
| void AssembleArtifacts::visitTyped(ICPackVisitor & visitor) | void AssembleArtifacts::visitTyped(ICPackVisitor & visitor) | ||||||
| { | { | ||||||
| 	visitor.visitAssembleArtifacts(*this); | 	visitor.visitAssembleArtifacts(*this); | ||||||
| @@ -1062,6 +1072,15 @@ 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()) | ||||||
|  | 		costume->second = costumeSet; | ||||||
|  | 	else | ||||||
|  | 		allCostumes.emplace(costumeIdx, costumeSet); | ||||||
|  | } | ||||||
|  |  | ||||||
| void PlayerEndsGame::applyGs(CGameState * gs) const | void PlayerEndsGame::applyGs(CGameState * gs) const | ||||||
| { | { | ||||||
| 	PlayerState *p = gs->getPlayerState(player); | 	PlayerState *p = gs->getPlayerState(player); | ||||||
|   | |||||||
| @@ -1288,6 +1288,30 @@ struct DLL_LINKAGE ChangeObjectVisitors : public CPackForClient | |||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | struct DLL_LINKAGE ChangeArtifactsCostume : public CPackForClient | ||||||
|  | { | ||||||
|  | 	std::map<ArtifactPosition, ArtifactID> costumeSet; | ||||||
|  | 	size_t costumeIdx; | ||||||
|  | 	const PlayerColor player; | ||||||
|  |  | ||||||
|  | 	void applyGs(CGameState * gs) const; | ||||||
|  | 	void visitTyped(ICPackVisitor & visitor) override; | ||||||
|  |  | ||||||
|  | 	ChangeArtifactsCostume() = default; | ||||||
|  | 	ChangeArtifactsCostume(const PlayerColor & player, const size_t costumeIdx) | ||||||
|  | 		: costumeIdx(costumeIdx) | ||||||
|  | 		, player(player) | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	template <typename Handler> void serialize(Handler & h) | ||||||
|  | 	{ | ||||||
|  | 		h & costumeSet; | ||||||
|  | 		h & costumeIdx; | ||||||
|  | 		h & player; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
| struct DLL_LINKAGE HeroLevelUp : public Query | struct DLL_LINKAGE HeroLevelUp : public Query | ||||||
| { | { | ||||||
| 	PlayerColor player; | 	PlayerColor player; | ||||||
|   | |||||||
| @@ -429,6 +429,31 @@ struct DLL_LINKAGE ManageBackpackArtifacts : public CPackForServer | |||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | struct DLL_LINKAGE ManageEquippedArtifacts : public CPackForServer | ||||||
|  | { | ||||||
|  | 	ManageEquippedArtifacts() = default; | ||||||
|  | 	ManageEquippedArtifacts(const ObjectInstanceID & artHolder, const size_t costumeIdx, bool saveCostume = false) | ||||||
|  | 		: artHolder(artHolder) | ||||||
|  | 		, costumeIdx(costumeIdx) | ||||||
|  | 		, saveCostume(saveCostume) | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ObjectInstanceID artHolder; | ||||||
|  | 	size_t costumeIdx; | ||||||
|  | 	bool saveCostume; | ||||||
|  |  | ||||||
|  | 	void visitTyped(ICPackVisitor & visitor) override; | ||||||
|  |  | ||||||
|  | 	template <typename Handler> void serialize(Handler & h) | ||||||
|  | 	{ | ||||||
|  | 		h & static_cast<CPackForServer&>(*this); | ||||||
|  | 		h & artHolder; | ||||||
|  | 		h & costumeIdx; | ||||||
|  | 		h & saveCostume; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
| struct DLL_LINKAGE AssembleArtifacts : public CPackForServer | struct DLL_LINKAGE AssembleArtifacts : public CPackForServer | ||||||
| { | { | ||||||
| 	AssembleArtifacts() = default; | 	AssembleArtifacts() = default; | ||||||
|   | |||||||
| @@ -67,6 +67,7 @@ void registerTypesClientPacks(Serializer &s) | |||||||
| 	s.template registerType<CPackForClient, HeroVisit>(); | 	s.template registerType<CPackForClient, HeroVisit>(); | ||||||
| 	s.template registerType<CPackForClient, SetCommanderProperty>(); | 	s.template registerType<CPackForClient, SetCommanderProperty>(); | ||||||
| 	s.template registerType<CPackForClient, ChangeObjectVisitors>(); | 	s.template registerType<CPackForClient, ChangeObjectVisitors>(); | ||||||
|  | 	s.template registerType<CPackForClient, ChangeArtifactsCostume>(); | ||||||
| 	s.template registerType<CPackForClient, ShowWorldViewEx>(); | 	s.template registerType<CPackForClient, ShowWorldViewEx>(); | ||||||
| 	s.template registerType<CPackForClient, EntitiesChanged>(); | 	s.template registerType<CPackForClient, EntitiesChanged>(); | ||||||
| 	s.template registerType<CPackForClient, BattleStart>(); | 	s.template registerType<CPackForClient, BattleStart>(); | ||||||
|   | |||||||
| @@ -49,7 +49,8 @@ void registerTypesServerPacks(Serializer &s) | |||||||
| 	s.template registerType<CPackForServer, BulkSmartSplitStack>(); | 	s.template registerType<CPackForServer, BulkSmartSplitStack>(); | ||||||
| 	s.template registerType<CPackForServer, BulkMoveArmy>(); | 	s.template registerType<CPackForServer, BulkMoveArmy>(); | ||||||
| 	s.template registerType<CPackForServer, BulkExchangeArtifacts>(); | 	s.template registerType<CPackForServer, BulkExchangeArtifacts>(); | ||||||
| 	s.template registerType < CPackForServer, ManageBackpackArtifacts>(); | 	s.template registerType<CPackForServer, ManageBackpackArtifacts>(); | ||||||
|  | 	s.template registerType<CPackForServer, ManageEquippedArtifacts>(); | ||||||
| 	s.template registerType<CPackForServer, EraseArtifactByClient>(); | 	s.template registerType<CPackForServer, EraseArtifactByClient>(); | ||||||
| 	s.template registerType<CPackForServer, GamePause>(); | 	s.template registerType<CPackForServer, GamePause>(); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2892,6 +2892,24 @@ bool CGameHandler::scrollBackpackArtifacts(const PlayerColor & player, const Obj | |||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool CGameHandler::saveArtifactsCostume(const PlayerColor & player, const ObjectInstanceID heroID, size_t costumeIdx) | ||||||
|  | { | ||||||
|  | 	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()) | ||||||
|  | 	{ | ||||||
|  | 		if(const auto & slotInfo = artSet->getSlot(slot)) | ||||||
|  | 			if(!slotInfo->locked) | ||||||
|  | 				costume.costumeSet.emplace(slot, slotInfo->getArt()->getTypeId()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	sendAndApply(&costume); | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Assembles or disassembles a combination artifact. |  * Assembles or disassembles a combination artifact. | ||||||
|  * @param heroID ID of hero holding the artifact(s). |  * @param heroID ID of hero holding the artifact(s). | ||||||
|   | |||||||
| @@ -130,6 +130,7 @@ public: | |||||||
| 	bool moveArtifact(const PlayerColor & player, const ArtifactLocation & src, const ArtifactLocation & dst) override; | 	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 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 scrollBackpackArtifacts(const PlayerColor & player, const ObjectInstanceID heroID, bool left); | ||||||
|  | 	bool saveArtifactsCostume(const PlayerColor & player, const ObjectInstanceID heroID, size_t costumeIdx); | ||||||
| 	bool eraseArtifactByClient(const ArtifactLocation & al); | 	bool eraseArtifactByClient(const ArtifactLocation & al); | ||||||
| 	void synchronizeArtifactHandlerLists(); | 	void synchronizeArtifactHandlerLists(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -179,6 +179,14 @@ void ApplyGhNetPackVisitor::visitManageBackpackArtifacts(ManageBackpackArtifacts | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void ApplyGhNetPackVisitor::visitManageEquippedArtifacts(ManageEquippedArtifacts & pack) | ||||||
|  | { | ||||||
|  | 	gh.throwIfWrongOwner(&pack, pack.artHolder); | ||||||
|  | 	if(pack.saveCostume) | ||||||
|  | 		gh.saveArtifactsCostume(pack.player, pack.artHolder, pack.costumeIdx); | ||||||
|  | 	result = true; | ||||||
|  | } | ||||||
|  |  | ||||||
| void ApplyGhNetPackVisitor::visitAssembleArtifacts(AssembleArtifacts & pack) | void ApplyGhNetPackVisitor::visitAssembleArtifacts(AssembleArtifacts & pack) | ||||||
| { | { | ||||||
| 	gh.throwIfWrongOwner(&pack, pack.heroID); | 	gh.throwIfWrongOwner(&pack, pack.heroID); | ||||||
|   | |||||||
| @@ -47,6 +47,7 @@ public: | |||||||
| 	void visitExchangeArtifacts(ExchangeArtifacts & pack) override; | 	void visitExchangeArtifacts(ExchangeArtifacts & pack) override; | ||||||
| 	void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) override; | 	void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) override; | ||||||
| 	void visitManageBackpackArtifacts(ManageBackpackArtifacts & pack) override; | 	void visitManageBackpackArtifacts(ManageBackpackArtifacts & pack) override; | ||||||
|  | 	void visitManageEquippedArtifacts(ManageEquippedArtifacts & pack) override; | ||||||
| 	void visitAssembleArtifacts(AssembleArtifacts & pack) override; | 	void visitAssembleArtifacts(AssembleArtifacts & pack) override; | ||||||
| 	void visitEraseArtifactByClient(EraseArtifactByClient & pack) override; | 	void visitEraseArtifactByClient(EraseArtifactByClient & pack) override; | ||||||
| 	void visitBuyArtifact(BuyArtifact & pack) override; | 	void visitBuyArtifact(BuyArtifact & pack) override; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user