|
@@ -20,9 +20,7 @@
|
|
|
|
|
|
#include "../widgets/CComponent.h"
|
|
|
|
|
|
-#include "../windows/CHeroWindow.h"
|
|
|
#include "../windows/CSpellWindow.h"
|
|
|
-#include "../windows/GUIClasses.h"
|
|
|
#include "../windows/CHeroBackpackWindow.h"
|
|
|
#include "../CPlayerInterface.h"
|
|
|
#include "../CGameInfo.h"
|
|
@@ -41,302 +39,115 @@ CWindowWithArtifacts::CWindowWithArtifacts(const std::vector<CArtifactsOfHeroPtr
|
|
|
this->artSets.insert(this->artSets.end(), artSets->begin(), artSets->end());
|
|
|
}
|
|
|
|
|
|
-void CWindowWithArtifacts::addSet(CArtifactsOfHeroPtr newArtSet)
|
|
|
+void CWindowWithArtifacts::addSet(const std::shared_ptr<CArtifactsOfHeroBase> & newArtSet)
|
|
|
{
|
|
|
artSets.emplace_back(newArtSet);
|
|
|
}
|
|
|
|
|
|
-void CWindowWithArtifacts::addSetAndCallbacks(CArtifactsOfHeroPtr newArtSet)
|
|
|
+const CGHeroInstance * CWindowWithArtifacts::getHeroPickedArtifact() const
|
|
|
{
|
|
|
- addSet(newArtSet);
|
|
|
- std::visit([this](auto artSetWeak)
|
|
|
+ const CGHeroInstance * hero = nullptr;
|
|
|
+
|
|
|
+ for(const auto & artSet : artSets)
|
|
|
+ if(const auto pickedArt = artSet->getHero()->getArt(ArtifactPosition::TRANSITION_POS))
|
|
|
{
|
|
|
- auto artSet = artSetWeak.lock();
|
|
|
- artSet->clickPressedCallback = std::bind(&CWindowWithArtifacts::clickPressedArtPlaceHero, this, _1, _2, _3);
|
|
|
- artSet->showPopupCallback = std::bind(&CWindowWithArtifacts::showPopupArtPlaceHero, this, _1, _2, _3);
|
|
|
- artSet->gestureCallback = std::bind(&CWindowWithArtifacts::gestureArtPlaceHero, this, _1, _2, _3);
|
|
|
- }, newArtSet);
|
|
|
+ hero = artSet->getHero();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return hero;
|
|
|
}
|
|
|
|
|
|
-void CWindowWithArtifacts::addCloseCallback(const CloseCallback & callback)
|
|
|
+const CArtifactInstance * CWindowWithArtifacts::getPickedArtifact() const
|
|
|
{
|
|
|
- closeCallback = callback;
|
|
|
-}
|
|
|
+ const CArtifactInstance * art = nullptr;
|
|
|
|
|
|
-const CGHeroInstance * CWindowWithArtifacts::getHeroPickedArtifact()
|
|
|
-{
|
|
|
- auto res = getState();
|
|
|
- if(res.has_value())
|
|
|
- return std::get<const CGHeroInstance*>(res.value());
|
|
|
- else
|
|
|
- return nullptr;
|
|
|
-}
|
|
|
-
|
|
|
-const CArtifactInstance * CWindowWithArtifacts::getPickedArtifact()
|
|
|
-{
|
|
|
- auto res = getState();
|
|
|
- if(res.has_value())
|
|
|
- return std::get<const CArtifactInstance*>(res.value());
|
|
|
- else
|
|
|
- return nullptr;
|
|
|
+ for(const auto & artSet : artSets)
|
|
|
+ if(const auto pickedArt = artSet->getHero()->getArt(ArtifactPosition::TRANSITION_POS))
|
|
|
+ {
|
|
|
+ art = pickedArt;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return art;
|
|
|
}
|
|
|
|
|
|
-void CWindowWithArtifacts::clickPressedArtPlaceHero(const CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition)
|
|
|
+void CWindowWithArtifacts::clickPressedOnArtPlace(const CGHeroInstance * hero, const ArtifactPosition & slot,
|
|
|
+ bool allowExchange, bool altarTrading, bool closeWindow)
|
|
|
{
|
|
|
- const auto currentArtSet = findAOHbyRef(artsInst);
|
|
|
- assert(currentArtSet.has_value());
|
|
|
-
|
|
|
- if(artPlace.isLocked())
|
|
|
+ if(!LOCPLINT->makingTurn)
|
|
|
return;
|
|
|
-
|
|
|
- if (!LOCPLINT->makingTurn)
|
|
|
+ if(hero == nullptr)
|
|
|
return;
|
|
|
|
|
|
- std::visit(
|
|
|
- [this, &artPlace](auto artSetWeak) -> void
|
|
|
+ if(const auto heroArtOwner = getHeroPickedArtifact())
|
|
|
+ {
|
|
|
+ if(allowExchange || hero->id == heroArtOwner->id)
|
|
|
+ putPickedArtifact(*hero, slot);
|
|
|
+ }
|
|
|
+ else if(auto art = hero->getArt(slot))
|
|
|
+ {
|
|
|
+ if(hero->getOwner() == LOCPLINT->playerID)
|
|
|
{
|
|
|
- const auto artSetPtr = artSetWeak.lock();
|
|
|
-
|
|
|
- // Hero(Main, Exchange) window, Kingdom window, Altar window, Backpack window left click handler
|
|
|
- if constexpr(
|
|
|
- std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroMain>> ||
|
|
|
- std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroKingdom>> ||
|
|
|
- std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroAltar>> ||
|
|
|
- std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroBackpack>>)
|
|
|
- {
|
|
|
- const auto pickedArtInst = getPickedArtifact();
|
|
|
- const auto heroPickedArt = getHeroPickedArtifact();
|
|
|
- const auto hero = artSetPtr->getHero();
|
|
|
- auto isTransferAllowed = false;
|
|
|
- std::string msg;
|
|
|
-
|
|
|
- if(pickedArtInst)
|
|
|
- {
|
|
|
- auto srcLoc = ArtifactLocation(heroPickedArt->id, ArtifactPosition::TRANSITION_POS);
|
|
|
- auto dstLoc = ArtifactLocation(hero->id, artPlace.slot);
|
|
|
-
|
|
|
- if(ArtifactUtils::isSlotBackpack(artPlace.slot))
|
|
|
- {
|
|
|
- if(pickedArtInst->artType->isBig())
|
|
|
- {
|
|
|
- // War machines cannot go to backpack
|
|
|
- msg = boost::str(boost::format(CGI->generaltexth->allTexts[153]) % pickedArtInst->artType->getNameTranslated());
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if(ArtifactUtils::isBackpackFreeSlots(heroPickedArt))
|
|
|
- isTransferAllowed = true;
|
|
|
- else
|
|
|
- msg = CGI->generaltexth->translate("core.genrltxt.152");
|
|
|
- }
|
|
|
- }
|
|
|
- // Check if artifact transfer is possible
|
|
|
- else if(pickedArtInst->canBePutAt(hero, artPlace.slot, true) && (!artPlace.getArt() || hero->tempOwner == LOCPLINT->playerID))
|
|
|
- {
|
|
|
- isTransferAllowed = true;
|
|
|
- }
|
|
|
- if constexpr(std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroKingdom>>)
|
|
|
- {
|
|
|
- if(hero != heroPickedArt)
|
|
|
- isTransferAllowed = false;
|
|
|
- }
|
|
|
- if(isTransferAllowed)
|
|
|
- LOCPLINT->cb->swapArtifacts(srcLoc, dstLoc);
|
|
|
- }
|
|
|
- else if(auto art = artPlace.getArt())
|
|
|
- {
|
|
|
- if(artSetPtr->getHero()->getOwner() == LOCPLINT->playerID)
|
|
|
- {
|
|
|
- if(checkSpecialArts(*art, hero, std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroAltar>> ? true : false))
|
|
|
- {
|
|
|
- assert(artSetPtr->getHero()->getSlotByInstance(art) != ArtifactPosition::PRE_FIRST);
|
|
|
-
|
|
|
- if(GH.isKeyboardCmdDown())
|
|
|
- {
|
|
|
- std::shared_ptr<CArtifactsOfHeroMain> anotherHeroEquipmentPointer = 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();
|
|
|
- if(heroEquipmentPointer->getHero()->id != artSetPtr->getHero()->id)
|
|
|
- {
|
|
|
- anotherHeroEquipmentPointer = heroEquipmentPointer;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if(anotherHeroEquipmentPointer != 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));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- 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;
|
|
|
- }
|
|
|
- }
|
|
|
- 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));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- for(const auto artSlot : ArtifactUtils::unmovableSlots())
|
|
|
- if(artPlace.slot == artSlot)
|
|
|
- {
|
|
|
- msg = CGI->generaltexth->allTexts[21];
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if constexpr(std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroBackpack>>)
|
|
|
- {
|
|
|
- if(!isTransferAllowed && artPlace.getArt() && closeCallback)
|
|
|
- closeCallback();
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if(!msg.empty())
|
|
|
- LOCPLINT->showInfoDialog(msg);
|
|
|
- }
|
|
|
- }
|
|
|
- // Market window left click handler
|
|
|
- else if constexpr(std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroMarket>>)
|
|
|
- {
|
|
|
- if(artSetPtr->selectArtCallback && artPlace.getArt())
|
|
|
+ if(checkSpecialArts(*art, *hero, altarTrading))
|
|
|
+ onClickPressedCommonArtifact(*hero, slot, closeWindow);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ for(const auto & artSlot : ArtifactUtils::unmovableSlots())
|
|
|
+ if(slot == artSlot)
|
|
|
{
|
|
|
- if(artPlace.getArt()->artType->isTradable())
|
|
|
- {
|
|
|
- artSetPtr->unmarkSlots();
|
|
|
- artPlace.selectSlot(true);
|
|
|
- artSetPtr->selectArtCallback(&artPlace);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // This item can't be traded
|
|
|
- LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[21]);
|
|
|
- }
|
|
|
+ LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[21]);
|
|
|
+ break;
|
|
|
}
|
|
|
- }
|
|
|
- else if constexpr(std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroQuickBackpack>>)
|
|
|
- {
|
|
|
- const auto hero = artSetPtr->getHero();
|
|
|
- LOCPLINT->cb->swapArtifacts(ArtifactLocation(hero->id, artPlace.slot), ArtifactLocation(hero->id, artSetPtr->getFilterSlot()));
|
|
|
- if(closeCallback)
|
|
|
- closeCallback();
|
|
|
- }
|
|
|
- }, currentArtSet.value());
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-void CWindowWithArtifacts::showPopupArtPlaceHero(const CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition)
|
|
|
+void CWindowWithArtifacts::swapArtifactAndClose(const CArtifactsOfHeroBase & artsInst, const ArtifactPosition & slot,
|
|
|
+ const ArtifactLocation & dstLoc)
|
|
|
{
|
|
|
- const auto currentArtSet = findAOHbyRef(artsInst);
|
|
|
- assert(currentArtSet.has_value());
|
|
|
+ LOCPLINT->cb->swapArtifacts(ArtifactLocation(artsInst.getHero()->id, slot), dstLoc);
|
|
|
+ close();
|
|
|
+}
|
|
|
|
|
|
- if(artPlace.isLocked())
|
|
|
- return;
|
|
|
+void CWindowWithArtifacts::showArtifactAssembling(const CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace,
|
|
|
+ const Point & cursorPosition) const
|
|
|
+{
|
|
|
+ if(artsInst.getArt(artPlace.slot))
|
|
|
+ {
|
|
|
+ if(ArtifactUtilsClient::askToDisassemble(artsInst.getHero(), artPlace.slot))
|
|
|
+ return;
|
|
|
+ if(ArtifactUtilsClient::askToAssemble(artsInst.getHero(), artPlace.slot))
|
|
|
+ return;
|
|
|
+ if(artPlace.text.size())
|
|
|
+ artPlace.LRClickableAreaWTextComp::showPopupWindow(cursorPosition);
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- std::visit(
|
|
|
- [&artPlace, &cursorPosition](auto artSetWeak) -> void
|
|
|
- {
|
|
|
- const auto artSetPtr = artSetWeak.lock();
|
|
|
-
|
|
|
- // Hero (Main, Exchange) window, Kingdom window, Backpack window right click handler
|
|
|
- if constexpr(
|
|
|
- std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroAltar>> ||
|
|
|
- std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroMain>> ||
|
|
|
- std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroKingdom>> ||
|
|
|
- std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroBackpack>>)
|
|
|
- {
|
|
|
- if(artPlace.getArt())
|
|
|
- {
|
|
|
- if(ArtifactUtilsClient::askToDisassemble(artSetPtr->getHero(), artPlace.slot))
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- if(ArtifactUtilsClient::askToAssemble(artSetPtr->getHero(), artPlace.slot))
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- if(artPlace.text.size())
|
|
|
- artPlace.LRClickableAreaWTextComp::showPopupWindow(cursorPosition);
|
|
|
- }
|
|
|
- }
|
|
|
- // Altar window, Market window right click handler
|
|
|
- else if constexpr(
|
|
|
- std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroMarket>> ||
|
|
|
- std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroQuickBackpack>>)
|
|
|
- {
|
|
|
- if(artPlace.getArt() && artPlace.text.size())
|
|
|
- artPlace.LRClickableAreaWTextComp::showPopupWindow(cursorPosition);
|
|
|
- }
|
|
|
- }, currentArtSet.value());
|
|
|
+void CWindowWithArtifacts::showArifactInfo(const CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition) const
|
|
|
+{
|
|
|
+ if(artsInst.getArt(artPlace.slot) && artPlace.text.size())
|
|
|
+ artPlace.LRClickableAreaWTextComp::showPopupWindow(cursorPosition);
|
|
|
}
|
|
|
|
|
|
-void CWindowWithArtifacts::gestureArtPlaceHero(const CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition)
|
|
|
+void CWindowWithArtifacts::showQuickBackpackWindow(const CGHeroInstance * hero, const ArtifactPosition & slot,
|
|
|
+ const Point & cursorPosition) const
|
|
|
{
|
|
|
- const auto currentArtSet = findAOHbyRef(artsInst);
|
|
|
- assert(currentArtSet.has_value());
|
|
|
- if(artPlace.isLocked())
|
|
|
+ if(!settings["general"]["enableUiEnhancements"].Bool())
|
|
|
return;
|
|
|
|
|
|
- std::visit(
|
|
|
- [&artPlace, cursorPosition](auto artSetWeak) -> void
|
|
|
- {
|
|
|
- const auto artSetPtr = artSetWeak.lock();
|
|
|
- if constexpr(
|
|
|
- std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroMain>> ||
|
|
|
- std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroKingdom>>)
|
|
|
- {
|
|
|
- if(!settings["general"]["enableUiEnhancements"].Bool())
|
|
|
- return;
|
|
|
-
|
|
|
- GH.windows().createAndPushWindow<CHeroQuickBackpackWindow>(artSetPtr->getHero(), artPlace.slot);
|
|
|
- auto backpackWindow = GH.windows().topWindow<CHeroQuickBackpackWindow>();
|
|
|
- backpackWindow->moveTo(cursorPosition - Point(1, 1));
|
|
|
- backpackWindow->fitToScreen(15);
|
|
|
- }
|
|
|
- }, currentArtSet.value());
|
|
|
+ GH.windows().createAndPushWindow<CHeroQuickBackpackWindow>(hero, slot);
|
|
|
+ auto backpackWindow = GH.windows().topWindow<CHeroQuickBackpackWindow>();
|
|
|
+ backpackWindow->moveTo(cursorPosition - Point(1, 1));
|
|
|
+ backpackWindow->fitToScreen(15);
|
|
|
}
|
|
|
|
|
|
void CWindowWithArtifacts::activate()
|
|
|
{
|
|
|
if(const auto art = getPickedArtifact())
|
|
|
+ {
|
|
|
+ markPossibleSlots();
|
|
|
setCursorAnimation(*art);
|
|
|
+ }
|
|
|
CWindowObject::activate();
|
|
|
}
|
|
|
|
|
@@ -346,18 +157,10 @@ void CWindowWithArtifacts::deactivate()
|
|
|
CWindowObject::deactivate();
|
|
|
}
|
|
|
|
|
|
-void CWindowWithArtifacts::enableArtifactsCostumeSwitcher() const
|
|
|
+void CWindowWithArtifacts::enableKeyboardShortcuts() const
|
|
|
{
|
|
|
- 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);
|
|
|
+ for(auto & artSet : artSets)
|
|
|
+ artSet->enableKeyboardShortcuts();
|
|
|
}
|
|
|
|
|
|
void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation & artLoc)
|
|
@@ -365,58 +168,19 @@ void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation & artLoc)
|
|
|
update();
|
|
|
}
|
|
|
|
|
|
-void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw)
|
|
|
+void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc)
|
|
|
{
|
|
|
- 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());
|
|
|
- auto artifactMovedBody = [this, withRedraw, &destLoc, &pickedArtInst](auto artSetWeak) -> void
|
|
|
- {
|
|
|
- auto artSetPtr = artSetWeak.lock();
|
|
|
- if(artSetPtr)
|
|
|
+ for(const auto & artSet : artSets)
|
|
|
+ if(const auto pickedArtInst = getPickedArtifact())
|
|
|
{
|
|
|
- const auto hero = artSetPtr->getHero();
|
|
|
- if(pickedArtInst)
|
|
|
- {
|
|
|
- setCursorAnimation(*pickedArtInst);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- artSetPtr->unmarkSlots();
|
|
|
- CCS->curh->dragAndDropCursor(nullptr);
|
|
|
- }
|
|
|
- if(withRedraw)
|
|
|
- {
|
|
|
- artSetPtr->updateWornSlots();
|
|
|
- artSetPtr->updateBackpackSlots();
|
|
|
-
|
|
|
- // Update arts bonuses on window.
|
|
|
- // TODO rework this part when CHeroWindow and CExchangeWindow are reworked
|
|
|
- if(auto * chw = dynamic_cast<CHeroWindow*>(this))
|
|
|
- {
|
|
|
- chw->update(hero, true);
|
|
|
- }
|
|
|
- else if(auto * cew = dynamic_cast<CExchangeWindow*>(this))
|
|
|
- {
|
|
|
- cew->updateWidgets();
|
|
|
- }
|
|
|
- artSetPtr->redraw();
|
|
|
- }
|
|
|
-
|
|
|
- // Make sure the status bar is updated so it does not display old text
|
|
|
- if(destLoc.artHolder == hero->id)
|
|
|
- {
|
|
|
- if(auto artPlace = artSetPtr->getArtPlace(destLoc.slot))
|
|
|
- artPlace->hover(true);
|
|
|
- }
|
|
|
+ markPossibleSlots();
|
|
|
+ setCursorAnimation(*pickedArtInst);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ artSet->unmarkSlots();
|
|
|
+ CCS->curh->dragAndDropCursor(nullptr);
|
|
|
}
|
|
|
- };
|
|
|
-
|
|
|
- for(auto artSetWeak : artSets)
|
|
|
- std::visit(artifactMovedBody, artSetWeak);
|
|
|
}
|
|
|
|
|
|
void CWindowWithArtifacts::artifactDisassembled(const ArtifactLocation & artLoc)
|
|
@@ -430,107 +194,42 @@ void CWindowWithArtifacts::artifactAssembled(const ArtifactLocation & artLoc)
|
|
|
update();
|
|
|
}
|
|
|
|
|
|
-void CWindowWithArtifacts::update() const
|
|
|
-{
|
|
|
- auto updateSlotBody = [](auto artSetWeak) -> void
|
|
|
- {
|
|
|
- if(const auto artSetPtr = artSetWeak.lock())
|
|
|
- {
|
|
|
- artSetPtr->updateWornSlots();
|
|
|
- artSetPtr->updateBackpackSlots();
|
|
|
- artSetPtr->redraw();
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- for(auto artSetWeak : artSets)
|
|
|
- std::visit(updateSlotBody, artSetWeak);
|
|
|
-}
|
|
|
-
|
|
|
-std::optional<std::tuple<const CGHeroInstance*, const CArtifactInstance*>> CWindowWithArtifacts::getState()
|
|
|
+void CWindowWithArtifacts::update()
|
|
|
{
|
|
|
- const CArtifactInstance * artInst = nullptr;
|
|
|
- std::map<const CGHeroInstance*, size_t> pickedCnt;
|
|
|
-
|
|
|
- auto getHeroArtBody = [&artInst, &pickedCnt](auto artSetWeak) -> void
|
|
|
+ for(const auto & artSet : artSets)
|
|
|
{
|
|
|
- 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;
|
|
|
+ artSet->updateWornSlots();
|
|
|
+ artSet->updateBackpackSlots();
|
|
|
|
|
|
- auto findAOHBody = [&res, &artsInst](auto & artSetWeak) -> void
|
|
|
- {
|
|
|
- if(&artsInst == artSetWeak.lock().get())
|
|
|
- res = artSetWeak;
|
|
|
- };
|
|
|
-
|
|
|
- for(auto artSetWeak : artSets)
|
|
|
- {
|
|
|
- std::visit(findAOHBody, artSetWeak);
|
|
|
- if(res.has_value())
|
|
|
- return res;
|
|
|
+ // Make sure the status bar is updated so it does not display old text
|
|
|
+ if(auto artPlace = artSet->getArtPlace(GH.getCursorPosition()))
|
|
|
+ artPlace->hover(true);
|
|
|
}
|
|
|
- return res;
|
|
|
}
|
|
|
|
|
|
-void CWindowWithArtifacts::markPossibleSlots()
|
|
|
+void CWindowWithArtifacts::markPossibleSlots() const
|
|
|
{
|
|
|
if(const auto pickedArtInst = getPickedArtifact())
|
|
|
{
|
|
|
- const auto heroArtOwner = getHeroPickedArtifact();
|
|
|
- auto artifactAssembledBody = [&pickedArtInst, &heroArtOwner](auto artSetWeak) -> void
|
|
|
+ for(const auto & artSet : artSets)
|
|
|
{
|
|
|
- if(auto artSetPtr = artSetWeak.lock())
|
|
|
- {
|
|
|
- if(artSetPtr->isActive())
|
|
|
- {
|
|
|
- const auto hero = artSetPtr->getHero();
|
|
|
- if(heroArtOwner == hero || !std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroKingdom>>)
|
|
|
- artSetPtr->markPossibleSlots(pickedArtInst, hero->tempOwner == LOCPLINT->playerID);
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
+ const auto hero = artSet->getHero();
|
|
|
+ if(hero == nullptr || !artSet->isActive())
|
|
|
+ continue;
|
|
|
|
|
|
- for(auto artSetWeak : artSets)
|
|
|
- std::visit(artifactAssembledBody, artSetWeak);
|
|
|
+ if(getHeroPickedArtifact() == hero || !std::dynamic_pointer_cast<CArtifactsOfHeroKingdom>(artSet))
|
|
|
+ artSet->markPossibleSlots(pickedArtInst, hero->tempOwner == LOCPLINT->playerID);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-bool CWindowWithArtifacts::checkSpecialArts(const CArtifactInstance & artInst, const CGHeroInstance * hero, bool isTrade) const
|
|
|
+bool CWindowWithArtifacts::checkSpecialArts(const CArtifactInstance & artInst, const CGHeroInstance & hero, bool isTrade) const
|
|
|
{
|
|
|
const auto artId = artInst.getTypeId();
|
|
|
|
|
|
if(artId == ArtifactID::SPELLBOOK)
|
|
|
{
|
|
|
- GH.windows().createAndPushWindow<CSpellWindow>(hero, LOCPLINT, LOCPLINT->battleInt.get());
|
|
|
+ GH.windows().createAndPushWindow<CSpellWindow>(&hero, LOCPLINT, LOCPLINT->battleInt.get());
|
|
|
return false;
|
|
|
}
|
|
|
if(artId == ArtifactID::CATAPULT)
|
|
@@ -549,9 +248,8 @@ bool CWindowWithArtifacts::checkSpecialArts(const CArtifactInstance & artInst, c
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-void CWindowWithArtifacts::setCursorAnimation(const CArtifactInstance & artInst)
|
|
|
+void CWindowWithArtifacts::setCursorAnimation(const CArtifactInstance & artInst) const
|
|
|
{
|
|
|
- markPossibleSlots();
|
|
|
if(artInst.isScroll() && settings["general"]["enableUiEnhancements"].Bool())
|
|
|
{
|
|
|
assert(artInst.getScrollSpellID().num >= 0);
|
|
@@ -564,3 +262,72 @@ void CWindowWithArtifacts::setCursorAnimation(const CArtifactInstance & artInst)
|
|
|
CCS->curh->dragAndDropCursor(AnimationPath::builtin("artifact"), artInst.artType->getIconIndex());
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+void CWindowWithArtifacts::putPickedArtifact(const CGHeroInstance & curHero, const ArtifactPosition & targetSlot) const
|
|
|
+{
|
|
|
+ const auto heroArtOwner = getHeroPickedArtifact();
|
|
|
+ const auto pickedArt = getPickedArtifact();
|
|
|
+ auto srcLoc = ArtifactLocation(heroArtOwner->id, ArtifactPosition::TRANSITION_POS);
|
|
|
+ auto dstLoc = ArtifactLocation(curHero.id, targetSlot);
|
|
|
+
|
|
|
+ if(ArtifactUtils::isSlotBackpack(dstLoc.slot))
|
|
|
+ {
|
|
|
+ if(pickedArt->artType->isBig())
|
|
|
+ {
|
|
|
+ // War machines cannot go to backpack
|
|
|
+ LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[153]) % pickedArt->artType->getNameTranslated()));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(ArtifactUtils::isBackpackFreeSlots(heroArtOwner))
|
|
|
+ LOCPLINT->cb->swapArtifacts(srcLoc, dstLoc);
|
|
|
+ else
|
|
|
+ LOCPLINT->showInfoDialog(CGI->generaltexth->translate("core.genrltxt.152"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // Check if artifact transfer is possible
|
|
|
+ else if(pickedArt->canBePutAt(&curHero, dstLoc.slot, true) && (!curHero.getArt(targetSlot) || curHero.tempOwner == LOCPLINT->playerID))
|
|
|
+ {
|
|
|
+ LOCPLINT->cb->swapArtifacts(srcLoc, dstLoc);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CWindowWithArtifacts::onClickPressedCommonArtifact(const CGHeroInstance & curHero, const ArtifactPosition & slot, bool closeWindow)
|
|
|
+{
|
|
|
+ assert(curHero.getArt(slot));
|
|
|
+ auto srcLoc = ArtifactLocation(curHero.id, slot);
|
|
|
+ auto dstLoc = ArtifactLocation(curHero.id, ArtifactPosition::TRANSITION_POS);
|
|
|
+
|
|
|
+ if(GH.isKeyboardCmdDown())
|
|
|
+ {
|
|
|
+ for(const auto & anotherSet : artSets)
|
|
|
+ {
|
|
|
+ if(std::dynamic_pointer_cast<CArtifactsOfHeroMain>(anotherSet) && curHero.id != anotherSet->getHero()->id)
|
|
|
+ {
|
|
|
+ dstLoc.slot = ArtifactPosition::FIRST_AVAILABLE;
|
|
|
+ dstLoc.artHolder = anotherSet->getHero()->id;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if(const auto heroSetAltar = std::dynamic_pointer_cast<CArtifactsOfHeroAltar>(anotherSet))
|
|
|
+ {
|
|
|
+ dstLoc.slot = ArtifactPosition::FIRST_AVAILABLE;
|
|
|
+ dstLoc.artHolder = heroSetAltar->altarId;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(GH.isKeyboardAltDown())
|
|
|
+ {
|
|
|
+ const auto artId = curHero.getArt(slot)->getTypeId();
|
|
|
+ if(ArtifactUtils::isSlotEquipment(slot))
|
|
|
+ dstLoc.slot = ArtifactUtils::getArtBackpackPosition(&curHero, artId);
|
|
|
+ else if(ArtifactUtils::isSlotBackpack(slot))
|
|
|
+ dstLoc.slot = ArtifactUtils::getArtEquippedPosition(&curHero, artId);
|
|
|
+ }
|
|
|
+ else if(closeWindow)
|
|
|
+ {
|
|
|
+ close();
|
|
|
+ }
|
|
|
+ if(dstLoc.slot != ArtifactPosition::PRE_FIRST)
|
|
|
+ LOCPLINT->cb->swapArtifacts(srcLoc, dstLoc);
|
|
|
+}
|