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:
parent
721b15d9de
commit
7abfa7b42a
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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!");
|
||||
|
Loading…
Reference in New Issue
Block a user