mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
Saving costume
This commit is contained in:
parent
90fa1718a5
commit
25dea7e364
@ -193,6 +193,14 @@ void CCallback::scrollBackpackArtifacts(ObjectInstanceID hero, bool left)
|
||||
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)
|
||||
{
|
||||
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 ArtifactLocation &l1, const ArtifactLocation &l2)=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 eraseArtifactByClient(const ArtifactLocation & al)=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 bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap, bool equipped = true, bool backpack = true) override;
|
||||
void scrollBackpackArtifacts(ObjectInstanceID hero, bool left) override;
|
||||
void manageHeroCostume(ObjectInstanceID hero, size_t costumeIdx, bool saveCostume) override;
|
||||
void eraseArtifactByClient(const ArtifactLocation & al) override;
|
||||
bool buildBuilding(const CGTownInstance *town, BuildingID buildingID) override;
|
||||
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_TOGGLE_TACTICS, // b
|
||||
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_TAB_ADVENTURE,
|
||||
|
@ -180,6 +180,16 @@ EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const
|
||||
{"heroLooseFormation", EShortcut::HERO_LOOSE_FORMATION },
|
||||
{"heroTightFormation", EShortcut::HERO_TIGHT_FORMATION },
|
||||
{"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 },
|
||||
{"spellbookTabCombat", EShortcut::SPELLBOOK_TAB_COMBAT }
|
||||
};
|
||||
|
@ -10,13 +10,15 @@
|
||||
#include "StdInc.h"
|
||||
#include "CArtifactsOfHeroMain.h"
|
||||
|
||||
#include "../gui/CGuiHandler.h"
|
||||
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
#include "../../lib/networkPacks/ArtifactLocation.h"
|
||||
|
||||
CArtifactsOfHeroMain::CArtifactsOfHeroMain(const Point & position)
|
||||
CArtifactsOfHeroMain::CArtifactsOfHeroMain(const Point & position, bool costumesEnabled)
|
||||
{
|
||||
init(
|
||||
std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2),
|
||||
@ -24,9 +26,41 @@ CArtifactsOfHeroMain::CArtifactsOfHeroMain(const Point & position)
|
||||
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()
|
||||
{
|
||||
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"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
struct ArtifactLocation;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
#include "../gui/Shortcut.h"
|
||||
|
||||
class CArtifactsOfHeroMain : public CArtifactsOfHeroBase
|
||||
{
|
||||
public:
|
||||
CArtifactsOfHeroMain(const Point & position);
|
||||
CArtifactsOfHeroMain(const Point & position, bool costumesEnabled = false);
|
||||
~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)
|
||||
{
|
||||
arts = std::make_shared<CArtifactsOfHeroMain>(Point(-65, -8));
|
||||
arts = std::make_shared<CArtifactsOfHeroMain>(Point(-65, -8), true);
|
||||
arts->setHero(curHero);
|
||||
addSetAndCallbacks(arts);
|
||||
}
|
||||
|
@ -125,6 +125,16 @@
|
||||
"heroTightFormation": "T",
|
||||
"heroToggleTactics": "B",
|
||||
"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<QuestInfo> quests; //store info about all received quests
|
||||
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 enteredWinningCheatCode, enteredLosingCheatCode; //if true, this player has entered cheat codes for loss / victory
|
||||
@ -111,6 +112,7 @@ public:
|
||||
h & daysWithoutCastle;
|
||||
h & cheated;
|
||||
h & battleBonuses;
|
||||
h & costumesArtifacts;
|
||||
h & enteredLosingCheatCode;
|
||||
h & enteredWinningCheatCode;
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
|
@ -87,6 +87,7 @@ public:
|
||||
virtual void visitInfoWindow(InfoWindow & pack) {}
|
||||
virtual void visitSetObjectProperty(SetObjectProperty & pack) {}
|
||||
virtual void visitChangeObjectVisitors(ChangeObjectVisitors & pack) {}
|
||||
virtual void visitChangeArtifactsCostume(ChangeArtifactsCostume & pack) {}
|
||||
virtual void visitHeroLevelUp(HeroLevelUp & pack) {}
|
||||
virtual void visitCommanderLevelUp(CommanderLevelUp & pack) {}
|
||||
virtual void visitBlockingDialog(BlockingDialog & pack) {}
|
||||
@ -132,6 +133,7 @@ public:
|
||||
virtual void visitExchangeArtifacts(ExchangeArtifacts & pack) {}
|
||||
virtual void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) {}
|
||||
virtual void visitManageBackpackArtifacts(ManageBackpackArtifacts & pack) {}
|
||||
virtual void visitManageEquippedArtifacts(ManageEquippedArtifacts & pack) {}
|
||||
virtual void visitAssembleArtifacts(AssembleArtifacts & pack) {}
|
||||
virtual void visitEraseArtifactByClient(EraseArtifactByClient & pack) {}
|
||||
virtual void visitBuyArtifact(BuyArtifact & pack) {}
|
||||
|
@ -383,6 +383,11 @@ void ChangeObjectVisitors::visitTyped(ICPackVisitor & visitor)
|
||||
visitor.visitChangeObjectVisitors(*this);
|
||||
}
|
||||
|
||||
void ChangeArtifactsCostume::visitTyped(ICPackVisitor & visitor)
|
||||
{
|
||||
visitor.visitChangeArtifactsCostume(*this);
|
||||
}
|
||||
|
||||
void HeroLevelUp::visitTyped(ICPackVisitor & visitor)
|
||||
{
|
||||
visitor.visitHeroLevelUp(*this);
|
||||
@ -613,6 +618,11 @@ void ManageBackpackArtifacts::visitTyped(ICPackVisitor & visitor)
|
||||
visitor.visitManageBackpackArtifacts(*this);
|
||||
}
|
||||
|
||||
void ManageEquippedArtifacts::visitTyped(ICPackVisitor & visitor)
|
||||
{
|
||||
visitor.visitManageEquippedArtifacts(*this);
|
||||
}
|
||||
|
||||
void AssembleArtifacts::visitTyped(ICPackVisitor & visitor)
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
AssembleArtifacts() = default;
|
||||
|
@ -67,6 +67,7 @@ void registerTypesClientPacks(Serializer &s)
|
||||
s.template registerType<CPackForClient, HeroVisit>();
|
||||
s.template registerType<CPackForClient, SetCommanderProperty>();
|
||||
s.template registerType<CPackForClient, ChangeObjectVisitors>();
|
||||
s.template registerType<CPackForClient, ChangeArtifactsCostume>();
|
||||
s.template registerType<CPackForClient, ShowWorldViewEx>();
|
||||
s.template registerType<CPackForClient, EntitiesChanged>();
|
||||
s.template registerType<CPackForClient, BattleStart>();
|
||||
|
@ -49,7 +49,8 @@ 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, ManageBackpackArtifacts>();
|
||||
s.template registerType<CPackForServer, ManageEquippedArtifacts>();
|
||||
s.template registerType<CPackForServer, EraseArtifactByClient>();
|
||||
s.template registerType<CPackForServer, GamePause>();
|
||||
}
|
||||
|
@ -2892,6 +2892,24 @@ bool CGameHandler::scrollBackpackArtifacts(const PlayerColor & player, const Obj
|
||||
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.
|
||||
* @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 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 eraseArtifactByClient(const ArtifactLocation & al);
|
||||
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)
|
||||
{
|
||||
gh.throwIfWrongOwner(&pack, pack.heroID);
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
void visitExchangeArtifacts(ExchangeArtifacts & pack) override;
|
||||
void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) override;
|
||||
void visitManageBackpackArtifacts(ManageBackpackArtifacts & pack) override;
|
||||
void visitManageEquippedArtifacts(ManageEquippedArtifacts & pack) override;
|
||||
void visitAssembleArtifacts(AssembleArtifacts & pack) override;
|
||||
void visitEraseArtifactByClient(EraseArtifactByClient & pack) override;
|
||||
void visitBuyArtifact(BuyArtifact & pack) override;
|
||||
|
Loading…
Reference in New Issue
Block a user