1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

ArtifactPosition::TRANSITION_POS now is simple ArtSlotInfo

This commit is contained in:
SoundSSGood 2024-04-30 12:39:20 +03:00
parent 721b15d9de
commit 7abfa7b42a
15 changed files with 120 additions and 142 deletions

View File

@ -126,7 +126,7 @@ size_t CArtifactsOfHeroBackpack::calcRows(size_t slots)
CArtifactsOfHeroQuickBackpack::CArtifactsOfHeroQuickBackpack(const ArtifactPosition filterBySlot)
: CArtifactsOfHeroBackpack(0, 0)
{
assert(filterBySlot != ArtifactPosition::FIRST_AVAILABLE);
assert(ArtifactUtils::checkIfSlotValid(*getHero(), filterBySlot));
if(!ArtifactUtils::isSlotEquipment(filterBySlot))
return;

View File

@ -32,9 +32,9 @@ CArtifactsOfHeroBase::CArtifactsOfHeroBase()
void CArtifactsOfHeroBase::putBackPickedArtifact()
{
// Artifact located in artifactsTransitionPos should be returned
if(getPickedArtifact())
if(const auto art = getPickedArtifact())
{
auto slot = ArtifactUtils::getArtAnyPosition(curHero, curHero->artifactsTransitionPos.begin()->artifact->getTypeId());
auto slot = ArtifactUtils::getArtAnyPosition(curHero, art->getTypeId());
if(slot == ArtifactPosition::PRE_FIRST)
{
LOCPLINT->cb->eraseArtifactByClient(ArtifactLocation(curHero->id, ArtifactPosition::TRANSITION_POS));
@ -196,10 +196,10 @@ void CArtifactsOfHeroBase::updateSlot(const ArtifactPosition & slot)
const CArtifactInstance * CArtifactsOfHeroBase::getPickedArtifact()
{
// Returns only the picked up artifact. Not just highlighted like in the trading window.
if(!curHero || curHero->artifactsTransitionPos.empty())
return nullptr;
else
if(curHero)
return curHero->getArt(ArtifactPosition::TRANSITION_POS);
else
return nullptr;
}
void CArtifactsOfHeroBase::addGestureCallback(CArtPlace::ClickFunctor callback)

View File

@ -222,7 +222,8 @@ void CAltarArtifacts::onSlotClickPressed(const std::shared_ptr<CTradeableItem> &
assert(tradeSlotsMap.at(altarSlot));
const auto slot = altarArtifacts->getSlotByInstance(tradeSlotsMap.at(altarSlot));
assert(slot != ArtifactPosition::PRE_FIRST);
LOCPLINT->cb->swapArtifacts(ArtifactLocation(altarId, slot), ArtifactLocation(hero->id, ArtifactPosition::TRANSITION_POS));
LOCPLINT->cb->swapArtifacts(ArtifactLocation(altarId, slot),
ArtifactLocation(hero->id, GH.isKeyboardCtrlDown() ? ArtifactPosition::FIRST_AVAILABLE : ArtifactPosition::TRANSITION_POS));
tradeSlotsMap.erase(altarSlot);
}
}

View File

@ -20,7 +20,7 @@
#include "render/Canvas.h"
#include "CPlayerInterface.h"
CHeroBackpackWindow::CHeroBackpackWindow(const CGHeroInstance * hero, const std::vector<CArtifactsOfHeroPtr> & artsSets)
CHeroBackpackWindow::CHeroBackpackWindow(const CGHeroInstance * hero, const std::vector<ArtifactsOfHeroVar> & artsSets)
: CWindowWithArtifacts(&artsSets)
{
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);

View File

@ -16,7 +16,7 @@ class CFilledTexture;
class CHeroBackpackWindow : public CStatusbarWindow, public CWindowWithArtifacts
{
public:
CHeroBackpackWindow(const CGHeroInstance * hero, const std::vector<CArtifactsOfHeroPtr> & artsSets);
CHeroBackpackWindow(const CGHeroInstance * hero, const std::vector<ArtifactsOfHeroVar> & artsSets);
protected:
std::shared_ptr<CArtifactsOfHeroBackpack> arts;

View File

@ -548,7 +548,7 @@ std::shared_ptr<CIntObject> CKingdomInterface::createMainTab(size_t index)
switch(index)
{
case 0:
return std::make_shared<CKingdHeroList>(size, [this](const CWindowWithArtifacts::CArtifactsOfHeroPtr & newHeroSet)
return std::make_shared<CKingdHeroList>(size, [this](const CWindowWithArtifacts::ArtifactsOfHeroVar & newHeroSet)
{
addSetAndCallbacks(newHeroSet);
});

View File

@ -334,7 +334,7 @@ private:
std::shared_ptr<CLabel> skillsLabel;
public:
using CreateHeroItemFunctor = std::function<void(const CWindowWithArtifacts::CArtifactsOfHeroPtr)>;
using CreateHeroItemFunctor = std::function<void(const CWindowWithArtifacts::ArtifactsOfHeroVar)>;
CKingdHeroList(size_t maxSize, const CreateHeroItemFunctor & onCreateHeroItemCallback);
void updateGarrisons() override;

View File

@ -106,8 +106,6 @@ void CMarketWindow::artifactRemoved(const ArtifactLocation & artLoc)
void CMarketWindow::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw)
{
if(!getState().has_value())
return;
CWindowWithArtifacts::artifactMoved(srcLoc, destLoc, withRedraw);
assert(marketWidget);
marketWidget->update();

View File

@ -35,18 +35,18 @@
#include "../../CCallback.h"
CWindowWithArtifacts::CWindowWithArtifacts(const std::vector<CArtifactsOfHeroPtr> * artSets)
CWindowWithArtifacts::CWindowWithArtifacts(const std::vector<ArtifactsOfHeroVar> * artSets)
{
if(artSets)
this->artSets.insert(this->artSets.end(), artSets->begin(), artSets->end());
}
void CWindowWithArtifacts::addSet(CArtifactsOfHeroPtr newArtSet)
void CWindowWithArtifacts::addSet(ArtifactsOfHeroVar newArtSet)
{
artSets.emplace_back(newArtSet);
}
void CWindowWithArtifacts::addSetAndCallbacks(CArtifactsOfHeroPtr newArtSet)
void CWindowWithArtifacts::addSetAndCallbacks(ArtifactsOfHeroVar newArtSet)
{
addSet(newArtSet);
std::visit([this](auto artSetWeak)
@ -65,20 +65,36 @@ void CWindowWithArtifacts::addCloseCallback(const CloseCallback & callback)
const CGHeroInstance * CWindowWithArtifacts::getHeroPickedArtifact()
{
auto res = getState();
if(res.has_value())
return std::get<const CGHeroInstance*>(res.value());
else
return nullptr;
const CGHeroInstance * hero = nullptr;
for(auto artSetWeak : artSets)
std::visit([&hero](auto artSetWeak)
{
if(auto artSetPtr = artSetWeak.lock())
if(const auto pickedArt = artSetPtr->getHero()->getArt(ArtifactPosition::TRANSITION_POS))
{
hero = artSetPtr->getHero();
return;
}
}, artSetWeak);
return hero;
}
const CArtifactInstance * CWindowWithArtifacts::getPickedArtifact()
{
auto res = getState();
if(res.has_value())
return std::get<const CArtifactInstance*>(res.value());
else
return nullptr;
const CArtifactInstance * art = nullptr;
for (auto artSetWeak : artSets)
std::visit([&art](auto artSetWeak)
{
if(auto artSetPtr = artSetWeak.lock())
if(const auto pickedArt = artSetPtr->getHero()->getArt(ArtifactPosition::TRANSITION_POS))
{
art = pickedArt;
return;
}
}, artSetWeak);
return art;
}
void CWindowWithArtifacts::clickPressedArtPlaceHero(const CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition)
@ -151,70 +167,46 @@ void CWindowWithArtifacts::clickPressedArtPlaceHero(const CArtifactsOfHeroBase &
{
assert(artSetPtr->getHero()->getSlotByInstance(art) != ArtifactPosition::PRE_FIRST);
if(GH.isKeyboardCmdDown())
auto srcLoc = ArtifactLocation(artSetPtr->getHero()->id, artPlace.slot);
auto dstLoc = ArtifactLocation(artSetPtr->getHero()->id, ArtifactPosition::TRANSITION_POS);
if(GH.isKeyboardCtrlDown())
{
std::shared_ptr<CArtifactsOfHeroMain> anotherHeroEquipmentPointer = nullptr;
std::shared_ptr<CArtifactsOfHeroBase> anotherArtSet = nullptr;
for(auto set : artSets)
{
if(std::holds_alternative<std::weak_ptr<CArtifactsOfHeroMain>>(set))
{
std::shared_ptr<CArtifactsOfHeroMain> heroEquipmentPointer = std::get<std::weak_ptr<CArtifactsOfHeroMain>>(set).lock();
std::shared_ptr<CArtifactsOfHeroBase> heroEquipmentPointer = std::get<std::weak_ptr<CArtifactsOfHeroMain>>(set).lock();
if(heroEquipmentPointer->getHero()->id != artSetPtr->getHero()->id)
{
anotherHeroEquipmentPointer = heroEquipmentPointer;
anotherArtSet = heroEquipmentPointer;
break;
}
}
}
if(anotherHeroEquipmentPointer != nullptr)
if(anotherArtSet != nullptr)
{
ArtifactPosition availablePosition = ArtifactUtils::getArtAnyPosition(anotherHeroEquipmentPointer->getHero(), art->getTypeId());
if(availablePosition != ArtifactPosition::PRE_FIRST)
{
LOCPLINT->cb->swapArtifacts(ArtifactLocation(artSetPtr->getHero()->id, artSetPtr->getHero()->getSlotByInstance(art)),
ArtifactLocation(anotherHeroEquipmentPointer->getHero()->id, availablePosition));
}
dstLoc.slot = ArtifactPosition::FIRST_AVAILABLE;
dstLoc.artHolder = anotherArtSet->getHero()->id;
}
}
else if(GH.isKeyboardAltDown())
{
ArtifactPosition destinationPosition = ArtifactPosition::PRE_FIRST;
if(ArtifactUtils::isSlotEquipment(artPlace.slot))
{
ArtifactPosition availablePosition = ArtifactUtils::getArtBackpackPosition(artSetPtr->getHero(), art->getTypeId());
if(availablePosition != ArtifactPosition::PRE_FIRST)
{
destinationPosition = availablePosition;
}
}
dstLoc.slot = ArtifactUtils::getArtBackpackPosition(artSetPtr->getHero(), art->getTypeId());
else if(ArtifactUtils::isSlotBackpack(artPlace.slot))
{
ArtifactPosition availablePosition = ArtifactUtils::getArtAnyPosition(artSetPtr->getHero(), art->getTypeId());
if(availablePosition != ArtifactPosition::PRE_FIRST && availablePosition != ArtifactPosition::BACKPACK_START)
{
destinationPosition = availablePosition;
}
}
if(destinationPosition != ArtifactPosition::PRE_FIRST)
{
LOCPLINT->cb->swapArtifacts(ArtifactLocation(artSetPtr->getHero()->id, artPlace.slot),
ArtifactLocation(artSetPtr->getHero()->id, destinationPosition));
}
}
else
{
LOCPLINT->cb->swapArtifacts(ArtifactLocation(artSetPtr->getHero()->id, artPlace.slot),
ArtifactLocation(artSetPtr->getHero()->id, ArtifactPosition::TRANSITION_POS));
dstLoc.slot = ArtifactUtils::getArtEquippedPosition(artSetPtr->getHero(), art->getTypeId());
}
if(dstLoc.slot != ArtifactPosition::PRE_FIRST)
LOCPLINT->cb->swapArtifacts(srcLoc, dstLoc);
}
}
else
{
for(const auto artSlot : ArtifactUtils::unmovableSlots())
for(const auto & artSlot : ArtifactUtils::unmovableSlots())
if(artPlace.slot == artSlot)
{
msg = CGI->generaltexth->allTexts[21];
@ -225,7 +217,7 @@ void CWindowWithArtifacts::clickPressedArtPlaceHero(const CArtifactsOfHeroBase &
if constexpr(std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroBackpack>>)
{
if(!isTransferAllowed && artPlace.getArt() && closeCallback)
if(!isTransferAllowed && artPlace.getArt() && !GH.isKeyboardCtrlDown() && !GH.isKeyboardAltDown() && closeCallback)
closeCallback();
}
else
@ -354,8 +346,8 @@ void CWindowWithArtifacts::enableArtifactsCostumeSwitcher() const
{
if constexpr(std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroMain>>)
{
const auto artSetPtr = artSetWeak.lock();
artSetPtr->enableArtifactsCostumeSwitcher();
if(auto artSetPtr = artSetWeak.lock())
artSetPtr->enableArtifactsCostumeSwitcher();
}
}, artSet);
}
@ -367,16 +359,10 @@ void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation & artLoc)
void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw)
{
auto curState = getState();
if(!curState.has_value())
// Transition state. Nothing to do here. Just skip. Need to wait for final state.
return;
auto pickedArtInst = std::get<const CArtifactInstance*>(curState.value());
const auto pickedArtInst = getPickedArtifact();
auto artifactMovedBody = [this, withRedraw, &destLoc, &pickedArtInst](auto artSetWeak) -> void
{
auto artSetPtr = artSetWeak.lock();
if(artSetPtr)
if(auto artSetPtr = artSetWeak.lock())
{
const auto hero = artSetPtr->getHero();
if(pickedArtInst)
@ -446,45 +432,9 @@ void CWindowWithArtifacts::update() const
std::visit(updateSlotBody, artSetWeak);
}
std::optional<std::tuple<const CGHeroInstance*, const CArtifactInstance*>> CWindowWithArtifacts::getState()
std::optional<CWindowWithArtifacts::ArtifactsOfHeroVar> CWindowWithArtifacts::findAOHbyRef(const CArtifactsOfHeroBase & artsInst)
{
const CArtifactInstance * artInst = nullptr;
std::map<const CGHeroInstance*, size_t> pickedCnt;
auto getHeroArtBody = [&artInst, &pickedCnt](auto artSetWeak) -> void
{
auto artSetPtr = artSetWeak.lock();
if(artSetPtr)
{
if(const auto art = artSetPtr->getPickedArtifact())
{
const auto hero = artSetPtr->getHero();
if(pickedCnt.count(hero) == 0)
{
pickedCnt.insert({ hero, hero->artifactsTransitionPos.size() });
artInst = art;
}
}
}
};
for(auto artSetWeak : artSets)
std::visit(getHeroArtBody, artSetWeak);
// The state is possible when the hero has placed an artifact in the ArtifactPosition::TRANSITION_POS,
// and the previous artifact has not yet removed from the ArtifactPosition::TRANSITION_POS.
// This is a transitional state. Then return nullopt.
if(std::accumulate(std::begin(pickedCnt), std::end(pickedCnt), 0, [](size_t accum, const auto & value)
{
return accum + value.second;
}) > 1)
return std::nullopt;
else
return std::make_tuple(pickedCnt.begin()->first, artInst);
}
std::optional<CWindowWithArtifacts::CArtifactsOfHeroPtr> CWindowWithArtifacts::findAOHbyRef(const CArtifactsOfHeroBase & artsInst)
{
std::optional<CArtifactsOfHeroPtr> res;
std::optional<ArtifactsOfHeroVar> res;
auto findAOHBody = [&res, &artsInst](auto & artSetWeak) -> void
{

View File

@ -19,7 +19,7 @@
class CWindowWithArtifacts : virtual public CWindowObject
{
public:
using CArtifactsOfHeroPtr = std::variant<
using ArtifactsOfHeroVar = std::variant<
std::weak_ptr<CArtifactsOfHeroMarket>,
std::weak_ptr<CArtifactsOfHeroAltar>,
std::weak_ptr<CArtifactsOfHeroKingdom>,
@ -28,12 +28,12 @@ public:
std::weak_ptr<CArtifactsOfHeroQuickBackpack>>;
using CloseCallback = std::function<void()>;
std::vector<CArtifactsOfHeroPtr> artSets;
std::vector<ArtifactsOfHeroVar> artSets;
CloseCallback closeCallback;
explicit CWindowWithArtifacts(const std::vector<CArtifactsOfHeroPtr> * artSets = nullptr);
void addSet(CArtifactsOfHeroPtr newArtSet);
void addSetAndCallbacks(CArtifactsOfHeroPtr newArtSet);
explicit CWindowWithArtifacts(const std::vector<ArtifactsOfHeroVar> * artSets = nullptr);
void addSet(ArtifactsOfHeroVar newArtSet);
void addSetAndCallbacks(ArtifactsOfHeroVar newArtSet);
void addCloseCallback(const CloseCallback & callback);
const CGHeroInstance * getHeroPickedArtifact();
const CArtifactInstance * getPickedArtifact();
@ -51,8 +51,7 @@ public:
protected:
void update() const;
std::optional<std::tuple<const CGHeroInstance*, const CArtifactInstance*>> getState();
std::optional<CArtifactsOfHeroPtr> findAOHbyRef(const CArtifactsOfHeroBase & artsInst);
std::optional<ArtifactsOfHeroVar> findAOHbyRef(const CArtifactsOfHeroBase & artsInst);
void markPossibleSlots();
bool checkSpecialArts(const CArtifactInstance & artInst, const CGHeroInstance * hero, bool isTrade) const;
void setCursorAnimation(const CArtifactInstance & artInst);

View File

@ -19,7 +19,39 @@
VCMI_LIB_NAMESPACE_BEGIN
DLL_LINKAGE bool ArtifactUtils::checkIfSlotValid(const CArtifactSet & artSet, const ArtifactPosition & slot)
{
if(artSet.bearerType() == ArtBearer::HERO)
{
if(isSlotEquipment(slot) || isSlotBackpack(slot) || slot == ArtifactPosition::TRANSITION_POS)
return true;
}
else if(artSet.bearerType() == ArtBearer::ALTAR)
{
if(isSlotBackpack(slot))
return true;
}
else if(artSet.bearerType() == ArtBearer::COMMANDER)
{
if(vstd::contains(commanderSlots(), slot))
return true;
}
else if(artSet.bearerType() == ArtBearer::CREATURE)
{
if(slot == ArtifactPosition::CREATURE_SLOT)
return true;
}
return false;
}
DLL_LINKAGE ArtifactPosition ArtifactUtils::getArtAnyPosition(const CArtifactSet * target, const ArtifactID & aid)
{
if(auto targetSlot = getArtEquippedPosition(target, aid); targetSlot != ArtifactPosition::PRE_FIRST)
return targetSlot;
return getArtBackpackPosition(target, aid);
}
DLL_LINKAGE ArtifactPosition ArtifactUtils::getArtEquippedPosition(const CArtifactSet * target, const ArtifactID & aid)
{
const auto * art = aid.toArtifact();
for(const auto & slot : art->getPossibleSlots().at(target->bearerType()))
@ -27,7 +59,7 @@ DLL_LINKAGE ArtifactPosition ArtifactUtils::getArtAnyPosition(const CArtifactSet
if(art->canBePutAt(target, slot))
return slot;
}
return getArtBackpackPosition(target, aid);
return ArtifactPosition::PRE_FIRST;
}
DLL_LINKAGE ArtifactPosition ArtifactUtils::getArtBackpackPosition(const CArtifactSet * target, const ArtifactID & aid)

View File

@ -25,8 +25,9 @@ class CMap;
namespace ArtifactUtils
{
// Calculates where an artifact gets placed when it gets transferred from one hero to another.
DLL_LINKAGE bool checkIfSlotValid(const CArtifactSet & artSet, const ArtifactPosition & slot);
DLL_LINKAGE ArtifactPosition getArtAnyPosition(const CArtifactSet * target, const ArtifactID & aid);
DLL_LINKAGE ArtifactPosition getArtEquippedPosition(const CArtifactSet * target, const ArtifactID & aid);
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();

View File

@ -897,13 +897,7 @@ const CArtifactInstance * CArtifactSet::getAssemblyByConstituent(const ArtifactI
const ArtSlotInfo * CArtifactSet::getSlot(const ArtifactPosition & pos) const
{
if(pos == ArtifactPosition::TRANSITION_POS)
{
// Always add to the end. Always take from the beginning.
if(artifactsTransitionPos.empty())
return nullptr;
else
return &(*artifactsTransitionPos.begin());
}
return &artifactsTransitionPos;
if(vstd::contains(artifactsWorn, pos))
return &artifactsWorn.at(pos);
if(ArtifactUtils::isSlotBackpack(pos))
@ -936,9 +930,7 @@ void CArtifactSet::setNewArtSlot(const ArtifactPosition & slot, ConstTransitiveP
ArtSlotInfo * slotInfo;
if(slot == ArtifactPosition::TRANSITION_POS)
{
// Always add to the end. Always take from the beginning.
artifactsTransitionPos.emplace_back();
slotInfo = &artifactsTransitionPos.back();
slotInfo = &artifactsTransitionPos;
}
else if(ArtifactUtils::isSlotEquipment(slot))
{
@ -957,8 +949,7 @@ void CArtifactSet::eraseArtSlot(const ArtifactPosition & slot)
{
if(slot == ArtifactPosition::TRANSITION_POS)
{
assert(!artifactsTransitionPos.empty());
artifactsTransitionPos.erase(artifactsTransitionPos.begin());
artifactsTransitionPos.artifact = nullptr;
}
else if(ArtifactUtils::isSlotBackpack(slot))
{

View File

@ -194,7 +194,7 @@ public:
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
ArtSlotInfo artifactsTransitionPos; // Used as transition position for dragAndDrop artifact exchange
void setNewArtSlot(const ArtifactPosition & slot, ConstTransitivePtr<CArtifactInstance> art, bool locked);
void eraseArtSlot(const ArtifactPosition & slot);

View File

@ -2721,10 +2721,16 @@ bool CGameHandler::moveArtifact(const PlayerColor & player, const ArtifactLocati
if(!isAllowedExchange(src.artHolder, dst.artHolder))
COMPLAIN_RET("That heroes cannot make any exchange!");
COMPLAIN_RET_FALSE_IF(!ArtifactUtils::checkIfSlotValid(*srcArtSet, src.slot), "moveArtifact: wrong artifact source slot");
const auto srcArtifact = srcArtSet->getArt(src.slot);
const auto dstArtifact = dstArtSet->getArt(dst.slot);
auto dstSlot = dst.slot;
if(dstSlot == ArtifactPosition::FIRST_AVAILABLE)
dstSlot = ArtifactUtils::getArtAnyPosition(dstArtSet, srcArtifact->getTypeId());
if(!ArtifactUtils::checkIfSlotValid(*dstArtSet, dstSlot))
return true;
const auto dstArtifact = dstArtSet->getArt(dstSlot);
const bool isDstSlotOccupied = dstArtSet->bearerType() == ArtBearer::ALTAR ? false : dstArtifact != nullptr;
const bool isDstSlotBackpack = dstArtSet->bearerType() == ArtBearer::HERO ? ArtifactUtils::isSlotBackpack(dst.slot) : false;
const bool isDstSlotBackpack = dstArtSet->bearerType() == ArtBearer::HERO ? ArtifactUtils::isSlotBackpack(dstSlot) : false;
if(srcArtifact == nullptr)
COMPLAIN_RET("No artifact to move!");
@ -2733,23 +2739,23 @@ bool CGameHandler::moveArtifact(const PlayerColor & player, const ArtifactLocati
// Check if src/dest slots are appropriate for the artifacts exchanged.
// Moving to the backpack is always allowed.
if((!srcArtifact || !isDstSlotBackpack) && !srcArtifact->canBePutAt(dstArtSet, dst.slot, true))
if((!srcArtifact || !isDstSlotBackpack) && !srcArtifact->canBePutAt(dstArtSet, dstSlot, true))
COMPLAIN_RET("Cannot move artifact!");
auto srcSlotInfo = srcArtSet->getSlot(src.slot);
auto dstSlotInfo = dstArtSet->getSlot(dst.slot);
auto dstSlotInfo = dstArtSet->getSlot(dstSlot);
if((srcSlotInfo && srcSlotInfo->locked) || (dstSlotInfo && dstSlotInfo->locked))
COMPLAIN_RET("Cannot move artifact locks.");
if(isDstSlotBackpack && srcArtifact->artType->isBig())
COMPLAIN_RET("Cannot put big artifacts in backpack!");
if(src.slot == ArtifactPosition::MACH4 || dst.slot == ArtifactPosition::MACH4)
if(src.slot == ArtifactPosition::MACH4 || dstSlot == ArtifactPosition::MACH4)
COMPLAIN_RET("Cannot move catapult!");
if(isDstSlotBackpack && !ArtifactUtils::isBackpackFreeSlots(dstArtSet))
COMPLAIN_RET("Backpack is full!");
auto dstSlot = std::min(dst.slot, ArtifactPosition(ArtifactPosition::BACKPACK_START + dstArtSet->artifactsInBackpack.size()));
dstSlot = std::min(dstSlot, ArtifactPosition(ArtifactPosition::BACKPACK_START + dstArtSet->artifactsInBackpack.size()));
if(src.slot == dstSlot && src.artHolder == dst.artHolder)
COMPLAIN_RET("Won't move artifact: Dest same as source!");