mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
Switching costume
This commit is contained in:
parent
25dea7e364
commit
ce9d2d8ab8
@ -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)
|
||||
{
|
||||
// Swap
|
||||
assert(leftSet);
|
||||
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
|
||||
assert(rightSet);
|
||||
CArtifactFittingSet artInitialSetLeft(*leftSet);
|
||||
bulkArtsRemove(artsPack0, *leftSet);
|
||||
if(!artsPack1.empty())
|
||||
{
|
||||
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,13 +2896,11 @@ 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)
|
||||
if(const auto slotInfo = artSet->getSlot(slot); slotInfo != nullptr && !slotInfo->locked)
|
||||
costume.costumeSet.emplace(slot, slotInfo->getArt()->getTypeId());
|
||||
}
|
||||
|
||||
@ -2910,6 +2908,62 @@ bool CGameHandler::saveArtifactsCostume(const PlayerColor & player, const Object
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user