mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-20 20:23:03 +02:00
bulk move artifacts only equipped, only backpack
This commit is contained in:
parent
c6a86d9a5f
commit
a83f290e13
@ -174,9 +174,9 @@ void CCallback::assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition
|
||||
sendRequest(&aa);
|
||||
}
|
||||
|
||||
void CCallback::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap)
|
||||
void CCallback::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap, bool equipped, bool backpack)
|
||||
{
|
||||
BulkExchangeArtifacts bma(srcHero, dstHero, swap);
|
||||
BulkExchangeArtifacts bma(srcHero, dstHero, swap, equipped, backpack);
|
||||
sendRequest(&bma);
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ public:
|
||||
|
||||
|
||||
// Moves all artifacts from one hero to another
|
||||
virtual void bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap) = 0;
|
||||
virtual void bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap, bool equipped, bool backpack) = 0;
|
||||
};
|
||||
|
||||
class CBattleCallback : public IBattleCallback
|
||||
@ -171,7 +171,7 @@ public:
|
||||
bool dismissHero(const CGHeroInstance * hero) override;
|
||||
bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2) override;
|
||||
void assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo) override;
|
||||
void bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap) override;
|
||||
void bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap, bool equipped = true, bool backpack = true) 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;
|
||||
|
@ -654,7 +654,12 @@ std::function<void()> CExchangeController::onSwapArtifacts()
|
||||
{
|
||||
return [&]()
|
||||
{
|
||||
cb->bulkMoveArtifacts(left->id, right->id, true);
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
||||
@ -810,11 +815,14 @@ void CExchangeController::moveArtifacts(bool leftToRight)
|
||||
const CGHeroInstance * target = leftToRight ? right : left;
|
||||
|
||||
if(source->tempOwner != cb->getPlayerID())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cb->bulkMoveArtifacts(source->id, target->id, false);
|
||||
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(
|
||||
|
@ -9,7 +9,6 @@
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "CArtHandler.h"
|
||||
|
||||
#include "ArtifactUtils.h"
|
||||
#include "CGeneralTextHandler.h"
|
||||
@ -925,8 +924,10 @@ unsigned CArtifactSet::getArtPosCount(const ArtifactID & aid, bool onlyWorn, boo
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CArtifactSet::putArtifact(ArtifactPosition slot, CArtifactInstance * art)
|
||||
CArtifactSet::ArtPlacementMap CArtifactSet::putArtifact(ArtifactPosition slot, CArtifactInstance * art)
|
||||
{
|
||||
ArtPlacementMap resArtPlacement;
|
||||
|
||||
setNewArtSlot(slot, art, false);
|
||||
if(art->artType->isCombined() && ArtifactUtils::isSlotEquipment(slot))
|
||||
{
|
||||
@ -939,18 +940,25 @@ void CArtifactSet::putArtifact(ArtifactPosition slot, CArtifactInstance * art)
|
||||
break;
|
||||
}
|
||||
|
||||
for(auto & part : art->getPartsInfo())
|
||||
for(const auto & part : art->getPartsInfo())
|
||||
{
|
||||
if(part.art != mainPart)
|
||||
{
|
||||
if(!part.art->artType->canBePutAt(this, part.slot))
|
||||
part.slot = ArtifactUtils::getArtAnyPosition(this, part.art->getTypeId());
|
||||
auto partSlot = part.slot;
|
||||
if(!part.art->artType->canBePutAt(this, partSlot))
|
||||
partSlot = ArtifactUtils::getArtAnyPosition(this, part.art->getTypeId());
|
||||
|
||||
assert(ArtifactUtils::isSlotEquipment(part.slot));
|
||||
setNewArtSlot(part.slot, part.art, true);
|
||||
assert(ArtifactUtils::isSlotEquipment(partSlot));
|
||||
setNewArtSlot(partSlot, part.art, true);
|
||||
resArtPlacement.emplace(std::make_pair(part.art, partSlot));
|
||||
}
|
||||
else
|
||||
{
|
||||
resArtPlacement.emplace(std::make_pair(part.art, part.slot));
|
||||
}
|
||||
}
|
||||
}
|
||||
return resArtPlacement;
|
||||
}
|
||||
|
||||
void CArtifactSet::removeArtifact(ArtifactPosition slot)
|
||||
@ -1031,7 +1039,7 @@ bool CArtifactSet::isPositionFree(const ArtifactPosition & pos, bool onlyLockChe
|
||||
return true; //no slot means not used
|
||||
}
|
||||
|
||||
void CArtifactSet::setNewArtSlot(const ArtifactPosition & slot, CArtifactInstance * art, bool locked)
|
||||
void CArtifactSet::setNewArtSlot(const ArtifactPosition & slot, ConstTransitivePtr<CArtifactInstance> art, bool locked)
|
||||
{
|
||||
assert(!vstd::contains(artifactsWorn, slot));
|
||||
|
||||
|
@ -246,11 +246,13 @@ struct DLL_LINKAGE ArtSlotInfo
|
||||
class DLL_LINKAGE CArtifactSet
|
||||
{
|
||||
public:
|
||||
using ArtPlacementMap = std::map<CArtifactInstance*, ArtifactPosition>;
|
||||
|
||||
std::vector<ArtSlotInfo> artifactsInBackpack; //hero's artifacts from bag
|
||||
std::map<ArtifactPosition, ArtSlotInfo> artifactsWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
|
||||
std::vector<ArtSlotInfo> artifactsTransitionPos; // Used as transition position for dragAndDrop artifact exchange
|
||||
|
||||
void setNewArtSlot(const ArtifactPosition & slot, CArtifactInstance * art, bool locked);
|
||||
void setNewArtSlot(const ArtifactPosition & slot, ConstTransitivePtr<CArtifactInstance> art, bool locked);
|
||||
void eraseArtSlot(const ArtifactPosition & slot);
|
||||
|
||||
const ArtSlotInfo * getSlot(const ArtifactPosition & pos) const;
|
||||
@ -275,7 +277,7 @@ public:
|
||||
unsigned getArtPosCount(const ArtifactID & aid, bool onlyWorn = true, bool searchBackpackAssemblies = true, bool allowLocked = true) const;
|
||||
|
||||
virtual ArtBearer::ArtBearer bearerType() const = 0;
|
||||
virtual void putArtifact(ArtifactPosition slot, CArtifactInstance * art);
|
||||
virtual ArtPlacementMap putArtifact(ArtifactPosition slot, CArtifactInstance * art);
|
||||
virtual void removeArtifact(ArtifactPosition slot);
|
||||
virtual ~CArtifactSet();
|
||||
|
||||
|
@ -55,6 +55,16 @@ const std::vector<CCombinedArtifactInstance::PartInfo> & CCombinedArtifactInstan
|
||||
return partsInfo;
|
||||
}
|
||||
|
||||
void CCombinedArtifactInstance::addPlacementMap(CArtifactSet::ArtPlacementMap & placementMap)
|
||||
{
|
||||
if(!placementMap.empty())
|
||||
for(auto& part : partsInfo)
|
||||
{
|
||||
assert(placementMap.find(part.art) != placementMap.end());
|
||||
part.slot = placementMap.at(part.art);
|
||||
}
|
||||
}
|
||||
|
||||
SpellID CScrollArtifactInstance::getScrollSpellID() const
|
||||
{
|
||||
auto artInst = static_cast<const CArtifactInstance*>(this);
|
||||
@ -163,7 +173,7 @@ bool CArtifactInstance::isCombined() const
|
||||
|
||||
void CArtifactInstance::putAt(const ArtifactLocation & al)
|
||||
{
|
||||
al.getHolderArtSet()->putArtifact(al.slot, this);
|
||||
addPlacementMap(al.getHolderArtSet()->putArtifact(al.slot, this));
|
||||
}
|
||||
|
||||
void CArtifactInstance::removeFrom(const ArtifactLocation & al)
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "bonuses/CBonusSystemNode.h"
|
||||
#include "GameConstants.h"
|
||||
#include "ConstTransitivePtr.h"
|
||||
#include "CArtHandler.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -39,6 +40,7 @@ public:
|
||||
bool isPart(const CArtifactInstance * supposedPart) const;
|
||||
std::vector<PartInfo> & getPartsInfo();
|
||||
const std::vector<PartInfo> & getPartsInfo() const;
|
||||
void addPlacementMap(CArtifactSet::ArtPlacementMap & placementMap);
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
|
@ -867,14 +867,13 @@ ArtBearer::ArtBearer CStackInstance::bearerType() const
|
||||
return ArtBearer::CREATURE;
|
||||
}
|
||||
|
||||
void CStackInstance::putArtifact(ArtifactPosition pos, CArtifactInstance * art)
|
||||
CStackInstance::ArtPlacementMap CStackInstance::putArtifact(ArtifactPosition pos, CArtifactInstance * art)
|
||||
{
|
||||
assert(!getArt(pos));
|
||||
assert(art->artType->canBePutAt(this, pos));
|
||||
|
||||
CArtifactSet::putArtifact(pos, art);
|
||||
if(ArtifactUtils::isSlotEquipment(pos))
|
||||
attachTo(*art);
|
||||
attachTo(*art);
|
||||
return CArtifactSet::putArtifact(pos, art);
|
||||
}
|
||||
|
||||
void CStackInstance::removeArtifact(ArtifactPosition pos)
|
||||
|
@ -121,7 +121,7 @@ public:
|
||||
void setArmyObj(const CArmedInstance *ArmyObj);
|
||||
virtual void giveStackExp(TExpType exp);
|
||||
bool valid(bool allowUnrandomized) const;
|
||||
void putArtifact(ArtifactPosition pos, CArtifactInstance * art) override;//from CArtifactSet
|
||||
ArtPlacementMap putArtifact(ArtifactPosition pos, CArtifactInstance * art) override;//from CArtifactSet
|
||||
void removeArtifact(ArtifactPosition pos) override;
|
||||
ArtBearer::ArtBearer bearerType() const override; //from CArtifactSet
|
||||
virtual std::string nodeName() const override; //from CBonusSystemnode
|
||||
|
@ -2413,12 +2413,16 @@ struct DLL_LINKAGE BulkExchangeArtifacts : public CPackForServer
|
||||
ObjectInstanceID srcHero;
|
||||
ObjectInstanceID dstHero;
|
||||
bool swap = false;
|
||||
bool equipped = true;
|
||||
bool backpack = true;
|
||||
|
||||
BulkExchangeArtifacts() = default;
|
||||
BulkExchangeArtifacts(const ObjectInstanceID & srcHero, const ObjectInstanceID & dstHero, bool swap)
|
||||
BulkExchangeArtifacts(const ObjectInstanceID & srcHero, const ObjectInstanceID & dstHero, bool swap, bool equipped, bool backpack)
|
||||
: srcHero(srcHero)
|
||||
, dstHero(dstHero)
|
||||
, swap(swap)
|
||||
, equipped(equipped)
|
||||
, backpack(backpack)
|
||||
{
|
||||
}
|
||||
|
||||
@ -2430,6 +2434,8 @@ struct DLL_LINKAGE BulkExchangeArtifacts : public CPackForServer
|
||||
h & srcHero;
|
||||
h & dstHero;
|
||||
h & swap;
|
||||
h & equipped;
|
||||
h & backpack;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1066,13 +1066,13 @@ std::string CGHeroInstance::getBiographyTextID() const
|
||||
return "";
|
||||
}
|
||||
|
||||
void CGHeroInstance::putArtifact(ArtifactPosition pos, CArtifactInstance *art)
|
||||
CGHeroInstance::ArtPlacementMap CGHeroInstance::putArtifact(ArtifactPosition pos, CArtifactInstance * art)
|
||||
{
|
||||
assert(art->artType->canBePutAt(this, pos));
|
||||
|
||||
CArtifactSet::putArtifact(pos, art);
|
||||
if(ArtifactUtils::isSlotEquipment(pos))
|
||||
attachTo(*art);
|
||||
return CArtifactSet::putArtifact(pos, art);
|
||||
}
|
||||
|
||||
void CGHeroInstance::removeArtifact(ArtifactPosition pos)
|
||||
|
@ -229,7 +229,7 @@ public:
|
||||
void initHero(CRandomGenerator & rand);
|
||||
void initHero(CRandomGenerator & rand, const HeroTypeID & SUBID);
|
||||
|
||||
void putArtifact(ArtifactPosition pos, CArtifactInstance * art) override;
|
||||
ArtPlacementMap putArtifact(ArtifactPosition pos, CArtifactInstance * art) override;
|
||||
void removeArtifact(ArtifactPosition pos) override;
|
||||
void initExp(CRandomGenerator & rand);
|
||||
void initArmy(CRandomGenerator & rand, IArmyDescriptor *dst = nullptr);
|
||||
|
@ -927,10 +927,10 @@ bool CMapLoaderH3M::loadArtifactToSlot(CGHeroInstance * hero, int slot)
|
||||
// He has Shackles of War (normally - MISC slot artifact) in LEFT_HAND slot set in editor
|
||||
// Artifact seems to be missing in game, so skip artifacts that don't fit target slot
|
||||
auto * artifact = ArtifactUtils::createArtifact(map, artifactID);
|
||||
auto artifactPos = ArtifactPosition(slot);
|
||||
if(artifact->canBePutAt(ArtifactLocation(hero, artifactPos)))
|
||||
auto dstLoc = ArtifactLocation(hero, ArtifactPosition(slot));
|
||||
if(artifact->canBePutAt(dstLoc))
|
||||
{
|
||||
hero->putArtifact(artifactPos, artifact);
|
||||
artifact->putAt(dstLoc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2690,7 +2690,7 @@ bool CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocat
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap)
|
||||
bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap, bool equipped, bool backpack)
|
||||
{
|
||||
// Make sure exchange is even possible between the two heroes.
|
||||
if(!isAllowedExchange(srcHero, dstHero))
|
||||
@ -2745,34 +2745,45 @@ bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID
|
||||
slots.push_back(BulkMoveArtifacts::LinkedSlots(slot, slot));
|
||||
}
|
||||
};
|
||||
// Move over artifacts that are worn srcHero -> dstHero
|
||||
moveArtsWorn(psrcHero, pdstHero, slotsSrcDst);
|
||||
artFittingSet.artifactsWorn.clear();
|
||||
// Move over artifacts that are worn dstHero -> srcHero
|
||||
moveArtsWorn(pdstHero, psrcHero, slotsDstSrc);
|
||||
// Move over artifacts that are in backpack srcHero -> dstHero
|
||||
moveArtsInBackpack(psrcHero, slotsSrcDst);
|
||||
// Move over artifacts that are in backpack dstHero -> srcHero
|
||||
moveArtsInBackpack(pdstHero, slotsDstSrc);
|
||||
if(equipped)
|
||||
{
|
||||
// Move over artifacts that are worn srcHero -> dstHero
|
||||
moveArtsWorn(psrcHero, pdstHero, slotsSrcDst);
|
||||
artFittingSet.artifactsWorn.clear();
|
||||
// Move over artifacts that are worn dstHero -> srcHero
|
||||
moveArtsWorn(pdstHero, psrcHero, slotsDstSrc);
|
||||
}
|
||||
if(backpack)
|
||||
{
|
||||
// Move over artifacts that are in backpack srcHero -> dstHero
|
||||
moveArtsInBackpack(psrcHero, slotsSrcDst);
|
||||
// Move over artifacts that are in backpack dstHero -> srcHero
|
||||
moveArtsInBackpack(pdstHero, slotsDstSrc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
artFittingSet.artifactsInBackpack = pdstHero->artifactsInBackpack;
|
||||
artFittingSet.artifactsWorn = pdstHero->artifactsWorn;
|
||||
|
||||
// Move over artifacts that are worn
|
||||
for(auto & artInfo : psrcHero->artifactsWorn)
|
||||
if(equipped)
|
||||
{
|
||||
if(ArtifactUtils::isArtRemovable(artInfo))
|
||||
// Move over artifacts that are worn
|
||||
for(auto & artInfo : psrcHero->artifactsWorn)
|
||||
{
|
||||
moveArtifact(psrcHero->getArt(artInfo.first), artInfo.first, pdstHero, slotsSrcDst);
|
||||
if(ArtifactUtils::isArtRemovable(artInfo))
|
||||
{
|
||||
moveArtifact(psrcHero->getArt(artInfo.first), artInfo.first, pdstHero, slotsSrcDst);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Move over artifacts that are in backpack
|
||||
for(auto & slotInfo : psrcHero->artifactsInBackpack)
|
||||
if(backpack)
|
||||
{
|
||||
moveArtifact(psrcHero->getArt(psrcHero->getArtPos(slotInfo.artifact)),
|
||||
psrcHero->getArtPos(slotInfo.artifact), pdstHero, slotsSrcDst);
|
||||
// Move over artifacts that are in backpack
|
||||
for(auto & slotInfo : psrcHero->artifactsInBackpack)
|
||||
{
|
||||
moveArtifact(psrcHero->getArt(psrcHero->getArtPos(slotInfo.artifact)),
|
||||
psrcHero->getArtPos(slotInfo.artifact), pdstHero, slotsSrcDst);
|
||||
}
|
||||
}
|
||||
}
|
||||
sendAndApply(&ma);
|
||||
|
@ -131,7 +131,7 @@ public:
|
||||
void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) override;
|
||||
void removeArtifact(const ArtifactLocation &al) override;
|
||||
bool moveArtifact(const ArtifactLocation & al1, const ArtifactLocation & al2) override;
|
||||
bool bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap);
|
||||
bool bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap, bool equipped, bool backpack);
|
||||
bool eraseArtifactByClient(const ArtifactLocation & al);
|
||||
void synchronizeArtifactHandlerLists();
|
||||
|
||||
|
@ -132,7 +132,7 @@ void ApplyGhNetPackVisitor::visitExchangeArtifacts(ExchangeArtifacts & pack)
|
||||
void ApplyGhNetPackVisitor::visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack)
|
||||
{
|
||||
gh.throwIfWrongOwner(&pack, pack.srcHero);
|
||||
result = gh.bulkMoveArtifacts(pack.srcHero, pack.dstHero, pack.swap);
|
||||
result = gh.bulkMoveArtifacts(pack.srcHero, pack.dstHero, pack.swap, pack.equipped, pack.backpack);
|
||||
}
|
||||
|
||||
void ApplyGhNetPackVisitor::visitAssembleArtifacts(AssembleArtifacts & pack)
|
||||
|
Loading…
Reference in New Issue
Block a user