1
0
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:
SoundSSGood 2023-07-24 19:09:17 +03:00
parent c6a86d9a5f
commit a83f290e13
16 changed files with 99 additions and 53 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -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(

View File

@ -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))
{
@ -938,19 +939,26 @@ void CArtifactSet::putArtifact(ArtifactPosition slot, CArtifactInstance * art)
mainPart = part.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));

View File

@ -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();

View File

@ -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)

View File

@ -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)
{

View File

@ -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)

View File

@ -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

View File

@ -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;
}
};

View File

@ -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)

View File

@ -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);

View File

@ -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
{

View File

@ -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);

View File

@ -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();

View File

@ -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)