diff --git a/client/widgets/markets/CAltarArtifacts.cpp b/client/widgets/markets/CAltarArtifacts.cpp index dacebcb84..f008f6b50 100644 --- a/client/widgets/markets/CAltarArtifacts.cpp +++ b/client/widgets/markets/CAltarArtifacts.cpp @@ -26,7 +26,7 @@ #include "../../../lib/mapObjects/CGMarket.h" CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero) + : CTradeBase(market, hero, [this](){return CAltarArtifacts::getSelectionParams();}) { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); @@ -37,10 +37,8 @@ CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance * deal = std::make_shared(dealButtonPos, AnimationPath::builtin("ALTSACR.DEF"), CGI->generaltexth->zelp[585], [this]() {CAltarArtifacts::makeDeal(); }); - labels.emplace_back(std::make_shared(450, 34, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[477])); - labels.emplace_back(std::make_shared(302, 423, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[478])); - selectedSubtitle = std::make_shared(302, 501, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); - selectedArt = std::make_shared(Point(280, 442)); + labels.emplace_back(std::make_shared(450, 32, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[477])); + labels.emplace_back(std::make_shared(302, 424, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[478])); sacrificeAllButton = std::make_shared(Point(393, 520), AnimationPath::builtin("ALTFILL.DEF"), CGI->generaltexth->zelp[571], std::bind(&CExperienceAltar::sacrificeAll, this)); @@ -54,47 +52,49 @@ CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance * heroArts = std::make_shared(Point(-365, -11)); heroArts->setHero(hero); - int slotNum = 0; - for(auto & altarSlotPos : posSlotsAltar) - { - auto altarSlot = std::make_shared(Rect(altarSlotPos, Point(44, 44)), EType::ARTIFACT_PLACEHOLDER, -1, slotNum); - altarSlot->clickPressedCallback = std::bind(&CAltarArtifacts::onSlotClickPressed, this, _1, hRight); - altarSlot->subtitle->clear(); - items.front().emplace_back(altarSlot); - slotNum++; - } + // Altar + offerTradePanel = std::make_shared([this](const std::shared_ptr & altarSlot) + { + CAltarArtifacts::onSlotClickPressed(altarSlot, hRight); + }); + offerTradePanel->updateSlotsCallback = std::bind(&CAltarArtifacts::updateAltarSlots, this); + offerTradePanel->moveTo(pos.topLeft() + Point(315, 52)); - expForHero->setText(std::to_string(0)); - CTradeBase::deselect(); + CTradeBase::updateSelected(); + CAltarArtifacts::deselect(); }; TExpType CAltarArtifacts::calcExpAltarForHero() { TExpType expOnAltar(0); for(const auto & tradeSlot : tradeSlotsMap) - expOnAltar += calcExpCost(tradeSlot.first); + expOnAltar += calcExpCost(tradeSlot.second->getTypeId()); expForHero->setText(std::to_string(expOnAltar)); return expOnAltar; } +void CAltarArtifacts::deselect() +{ + CTradeBase::deselect(); + expForHero->setText(std::to_string(0)); + tradeSlotsMap.clear(); + // The event for removing artifacts from the altar will not be triggered. Therefore, we clean the altar immediately. + for(auto & slot : offerTradePanel->slots) + { + slot->setID(-1); + slot->subtitle->clear(); + } +} + void CAltarArtifacts::makeDeal() { std::vector positions; - for(const auto & [artInst, altarSlot] : tradeSlotsMap) + for(const auto & [altarSlot, artInst] : tradeSlotsMap) { positions.push_back(artInst->getId()); } LOCPLINT->cb->trade(market, EMarketMode::ARTIFACT_EXP, positions, std::vector(), std::vector(), hero); - - tradeSlotsMap.clear(); - // The event for removing artifacts from the altar will not be triggered. Therefore, we clean the altar immediately. - for(auto item : items[0]) - { - item->setID(-1); - item->subtitle->clear(); - } - calcExpAltarForHero(); - deal->block(tradeSlotsMap.empty()); + deselect(); } void CAltarArtifacts::sacrificeAll() @@ -107,10 +107,20 @@ void CAltarArtifacts::sacrificeBackpack() LOCPLINT->cb->bulkMoveArtifacts(heroArts->getHero()->id, altarId, false, false, true); } -void CAltarArtifacts::setSelectedArtifact(const CArtifactInstance * art) +void CAltarArtifacts::setSelectedArtifact(std::optional id) { - selectedArt->setArtifact(art); - selectedSubtitle->setText(art == nullptr ? "" : std::to_string(calcExpCost(art))); + if(id.has_value()) + { + hRight = offerTradePanel->selectedSlot; + hRight->setID(id.value().num); + offerQty = calcExpCost(id.value()); + } + else + { + hRight.reset(); + offerQty = 0; + } + updateSelected(); } std::shared_ptr CAltarArtifacts::getAOHset() const @@ -123,47 +133,54 @@ ObjectInstanceID CAltarArtifacts::getObjId() const return altarId; } -void CAltarArtifacts::updateSlots() +void CAltarArtifacts::updateAltarSlots() { assert(altarArtifacts->artifactsInBackpack.size() <= GameConstants::ALTAR_ARTIFACTS_SLOTS); assert(tradeSlotsMap.size() <= GameConstants::ALTAR_ARTIFACTS_SLOTS); - auto slotsToAdd = tradeSlotsMap; - for(auto & altarSlot : items[0]) + auto tradeSlotsMapNewArts = tradeSlotsMap; + for(auto & altarSlot : offerTradePanel->slots) if(altarSlot->id != -1) { - if(tradeSlotsMap.find(altarSlot->getArtInstance()) == tradeSlotsMap.end()) + if(tradeSlotsMap.find(altarSlot) == tradeSlotsMap.end()) { altarSlot->setID(-1); altarSlot->subtitle->clear(); } else { - slotsToAdd.erase(altarSlot->getArtInstance()); + tradeSlotsMapNewArts.erase(altarSlot); } } - for(auto & tradeSlot : slotsToAdd) + for(auto & tradeSlot : tradeSlotsMapNewArts) { - assert(tradeSlot.second->id == -1); - assert(altarArtifacts->getSlotByInstance(tradeSlot.first) != ArtifactPosition::PRE_FIRST); - tradeSlot.second->setArtInstance(tradeSlot.first); - tradeSlot.second->subtitle->setText(std::to_string(calcExpCost(tradeSlot.first))); + assert(tradeSlot.first->id == -1); + assert(altarArtifacts->getSlotByInstance(tradeSlot.second) != ArtifactPosition::PRE_FIRST); + tradeSlot.first->setID(tradeSlot.second->getTypeId()); + tradeSlot.first->subtitle->setText(std::to_string(calcExpCost(tradeSlot.second->getTypeId()))); } - for(auto & slotInfo : altarArtifacts->artifactsInBackpack) + + auto newArtsFromBulkMove = altarArtifacts->artifactsInBackpack; + for(const auto & [altarSlot, art] : tradeSlotsMap) { - if(tradeSlotsMap.find(slotInfo.artifact) == tradeSlotsMap.end()) - { - for(auto & altarSlot : items[0]) - if(altarSlot->id == -1) - { - altarSlot->setArtInstance(slotInfo.artifact); - altarSlot->subtitle->setText(std::to_string(calcExpCost(slotInfo.artifact))); - tradeSlotsMap.try_emplace(slotInfo.artifact, altarSlot); - break; - } - } + newArtsFromBulkMove.erase(std::remove_if(newArtsFromBulkMove.begin(), newArtsFromBulkMove.end(), [art = art](auto & slotInfo) + { + return slotInfo.artifact == art; + })); } + for(const auto & slotInfo : newArtsFromBulkMove) + { + for(auto & altarSlot : offerTradePanel->slots) + if(altarSlot->id == -1) + { + altarSlot->setID(slotInfo.artifact->getTypeId()); + altarSlot->subtitle->setText(std::to_string(calcExpCost(slotInfo.artifact->getTypeId()))); + tradeSlotsMap.try_emplace(altarSlot, slotInfo.artifact); + break; + } + } + calcExpAltarForHero(); deal->block(tradeSlotsMap.empty()); } @@ -176,6 +193,16 @@ void CAltarArtifacts::putBackArtifacts() LOCPLINT->cb->bulkMoveArtifacts(altarId, heroArts->getHero()->id, false, true, true); } +CTradeBase::SelectionParams CAltarArtifacts::getSelectionParams() const +{ + if(hRight) + return std::make_tuple( + std::nullopt, + SelectionParamOneSide {std::to_string(offerQty), GameResID(hRight->id)} + ); + return std::make_tuple(std::nullopt, std::nullopt); +} + void CAltarArtifacts::onSlotClickPressed(const std::shared_ptr & altarSlot, std::shared_ptr & hCurSlot) { assert(altarSlot); @@ -187,7 +214,7 @@ void CAltarArtifacts::onSlotClickPressed(const std::shared_ptr & if(pickedArtInst->artType->isTradable()) { if(altarSlot->id == -1) - tradeSlotsMap.try_emplace(pickedArtInst, altarSlot); + tradeSlotsMap.try_emplace(altarSlot, pickedArtInst); deal->block(false); LOCPLINT->cb->swapArtifacts(ArtifactLocation(heroArts->getHero()->id, ArtifactPosition::TRANSITION_POS), @@ -200,19 +227,20 @@ void CAltarArtifacts::onSlotClickPressed(const std::shared_ptr & } } } - else if(const CArtifactInstance * art = altarSlot->getArtInstance()) + else if(altarSlot->id != -1) { - const auto slot = altarArtifacts->getSlotByInstance(art); + 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)); - tradeSlotsMap.erase(art); + tradeSlotsMap.erase(altarSlot); } } -TExpType CAltarArtifacts::calcExpCost(const CArtifactInstance * art) +TExpType CAltarArtifacts::calcExpCost(ArtifactID id) { int bidQty = 0; int expOfArt = 0; - market->getOffer(art->getTypeId(), 0, bidQty, expOfArt, EMarketMode::ARTIFACT_EXP); + market->getOffer(id, 0, bidQty, expOfArt, EMarketMode::ARTIFACT_EXP); return hero->calculateXp(expOfArt); } diff --git a/client/widgets/markets/CAltarArtifacts.h b/client/widgets/markets/CAltarArtifacts.h index 0715950dd..250c55ba7 100644 --- a/client/widgets/markets/CAltarArtifacts.h +++ b/client/widgets/markets/CAltarArtifacts.h @@ -17,36 +17,24 @@ class CAltarArtifacts : public CExperienceAltar public: CAltarArtifacts(const IMarket * market, const CGHeroInstance * hero); TExpType calcExpAltarForHero() override; + void deselect() override; void makeDeal() override; void sacrificeAll() override; void sacrificeBackpack(); - void setSelectedArtifact(const CArtifactInstance * art); + void setSelectedArtifact(std::optional id); std::shared_ptr getAOHset() const; ObjectInstanceID getObjId() const; - void updateSlots() override; void putBackArtifacts(); private: ObjectInstanceID altarId; const CArtifactSet * altarArtifacts; - std::shared_ptr selectedArt; - std::shared_ptr selectedSubtitle; std::shared_ptr sacrificeBackpackButton; std::shared_ptr heroArts; - std::map> tradeSlotsMap; - - const std::vector posSlotsAltar = - { - Point(317, 53), Point(371, 53), Point(425, 53), - Point(479, 53), Point(533, 53), Point(317, 123), - Point(371, 123), Point(425, 123), Point(479, 123), - Point(533, 123), Point(317, 193), Point(371, 193), - Point(425, 193), Point(479, 193), Point(533, 193), - Point(317, 263), Point(371, 263), Point(425, 263), - Point(479, 263), Point(533, 263), Point(398, 333), - Point(452, 333) - }; + std::map, const CArtifactInstance*> tradeSlotsMap; + void updateAltarSlots(); + CTradeBase::SelectionParams getSelectionParams() const override; void onSlotClickPressed(const std::shared_ptr & altarSlot, std::shared_ptr & hCurSlot) override; - TExpType calcExpCost(const CArtifactInstance * art); + TExpType calcExpCost(ArtifactID id); }; diff --git a/client/widgets/markets/CAltarCreatures.cpp b/client/widgets/markets/CAltarCreatures.cpp index df777f535..62768f604 100644 --- a/client/widgets/markets/CAltarCreatures.cpp +++ b/client/widgets/markets/CAltarCreatures.cpp @@ -26,8 +26,7 @@ #include "../../../lib/mapObjects/CGMarket.h" CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero) - , CMarketMisc([this](){return CAltarCreatures::getSelectionParams();}) + : CTradeBase(market, hero, [this](){return CAltarCreatures::getSelectionParams();}) { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); @@ -166,7 +165,7 @@ void CAltarCreatures::makeDeal() } } -CMarketMisc::SelectionParams CAltarCreatures::getSelectionParams() +CTradeBase::SelectionParams CAltarCreatures::getSelectionParams() const { std::optional bidSelected = std::nullopt; std::optional offerSelected = std::nullopt; diff --git a/client/widgets/markets/CAltarCreatures.h b/client/widgets/markets/CAltarCreatures.h index d6e594aba..6e8d5ae26 100644 --- a/client/widgets/markets/CAltarCreatures.h +++ b/client/widgets/markets/CAltarCreatures.h @@ -11,7 +11,7 @@ #include "CTradeBase.h" -class CAltarCreatures : public CExperienceAltar, public CCreaturesSelling, public CMarketMisc +class CAltarCreatures : public CExperienceAltar, public CCreaturesSelling { public: CAltarCreatures(const IMarket * market, const CGHeroInstance * hero); @@ -25,7 +25,7 @@ private: std::vector unitsOnAltar; std::vector expPerUnit; - CMarketMisc::SelectionParams getSelectionParams(); + CTradeBase::SelectionParams getSelectionParams() const override; void updateAltarSlot(const std::shared_ptr & slot); void readExpValues(); void updateControls(); diff --git a/client/widgets/markets/CArtifactsBuying.cpp b/client/widgets/markets/CArtifactsBuying.cpp index 1f653cef5..36ef991dc 100644 --- a/client/widgets/markets/CArtifactsBuying.cpp +++ b/client/widgets/markets/CArtifactsBuying.cpp @@ -26,9 +26,8 @@ #include "../../../lib/mapObjects/CGTownInstance.h" CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero) + : CTradeBase(market, hero, [this](){return CArtifactsBuying::getSelectionParams();}) , CResourcesSelling([this](const std::shared_ptr & heroSlot){CArtifactsBuying::onSlotClickPressed(heroSlot, hLeft);}) - , CMarketMisc([this](){return CArtifactsBuying::getSelectionParams();}) { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); @@ -59,7 +58,7 @@ CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance offerTradePanel->moveTo(pos.topLeft() + Point(328, 182)); CTradeBase::updateSlots(); - CMarketMisc::deselect(); + CTradeBase::deselect(); } void CArtifactsBuying::makeDeal() @@ -68,7 +67,7 @@ void CArtifactsBuying::makeDeal() deselect(); } -CMarketMisc::SelectionParams CArtifactsBuying::getSelectionParams() +CTradeBase::SelectionParams CArtifactsBuying::getSelectionParams() const { if(hLeft && hRight) return std::make_tuple( diff --git a/client/widgets/markets/CArtifactsBuying.h b/client/widgets/markets/CArtifactsBuying.h index de3fc7cda..26f20b197 100644 --- a/client/widgets/markets/CArtifactsBuying.h +++ b/client/widgets/markets/CArtifactsBuying.h @@ -11,13 +11,13 @@ #include "CTradeBase.h" -class CArtifactsBuying : public CResourcesSelling, public CMarketMisc +class CArtifactsBuying : public CResourcesSelling { public: CArtifactsBuying(const IMarket * market, const CGHeroInstance * hero); void makeDeal() override; private: - CMarketMisc::SelectionParams getSelectionParams(); + CTradeBase::SelectionParams getSelectionParams() const override; void CArtifactsBuying::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot); }; diff --git a/client/widgets/markets/CArtifactsSelling.cpp b/client/widgets/markets/CArtifactsSelling.cpp index d01ac5c04..f5beed729 100644 --- a/client/widgets/markets/CArtifactsSelling.cpp +++ b/client/widgets/markets/CArtifactsSelling.cpp @@ -23,11 +23,10 @@ #include "../../../lib/mapObjects/CGMarket.h" CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero) + : CTradeBase(market, hero, [this](){return CArtifactsSelling::getSelectionParams();}) , CResourcesBuying( [this](const std::shared_ptr & resSlot){CArtifactsSelling::onSlotClickPressed(resSlot, hRight);}, [this](){CTradeBase::updateSubtitles(EMarketMode::ARTIFACT_RESOURCE);}) - , CMarketMisc([this](){return CArtifactsSelling::getSelectionParams();}) { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); @@ -61,7 +60,7 @@ CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstanc offerTradePanel->selectedSlot->moveTo(pos.topLeft() + Point(409, 473)); CArtifactsSelling::updateSelected(); - CMarketMisc::deselect(); + CTradeBase::deselect(); } void CArtifactsSelling::makeDeal() @@ -71,7 +70,7 @@ void CArtifactsSelling::makeDeal() void CArtifactsSelling::updateSelected() { - CMarketMisc::updateSelected(); + CTradeBase::updateSelected(); if(hLeft && hRight) { @@ -92,7 +91,7 @@ std::shared_ptr CArtifactsSelling::getAOHset() const return heroArts; } -CMarketMisc::SelectionParams CArtifactsSelling::getSelectionParams() +CTradeBase::SelectionParams CArtifactsSelling::getSelectionParams() const { if(hLeft && hRight) return std::make_tuple( diff --git a/client/widgets/markets/CArtifactsSelling.h b/client/widgets/markets/CArtifactsSelling.h index 79c5c845a..d61ec3e95 100644 --- a/client/widgets/markets/CArtifactsSelling.h +++ b/client/widgets/markets/CArtifactsSelling.h @@ -12,12 +12,12 @@ #include "../CArtifactsOfHeroMarket.h" #include "CTradeBase.h" -class CArtifactsSelling : public CResourcesBuying, public CMarketMisc +class CArtifactsSelling : public CResourcesBuying { public: CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero); void makeDeal() override; - void updateSelected(); + void updateSelected() override; std::shared_ptr getAOHset() const; private: @@ -25,6 +25,6 @@ private: std::shared_ptr bidSelectedSubtitle; std::shared_ptr bidSelectedSlot; - CMarketMisc::SelectionParams getSelectionParams(); + CTradeBase::SelectionParams getSelectionParams() const override; void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) override; }; diff --git a/client/widgets/markets/CFreelancerGuild.cpp b/client/widgets/markets/CFreelancerGuild.cpp index 0b581be1c..f8e04da9d 100644 --- a/client/widgets/markets/CFreelancerGuild.cpp +++ b/client/widgets/markets/CFreelancerGuild.cpp @@ -27,11 +27,10 @@ #include "../../../lib/mapObjects/CGTownInstance.h" CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero) + : CTradeBase(market, hero, [this](){return CFreelancerGuild::getSelectionParams();}) , CResourcesBuying( [this](const std::shared_ptr & heroSlot){CFreelancerGuild::onSlotClickPressed(heroSlot, hLeft);}, [this](){CTradeBase::updateSubtitles(EMarketMode::CREATURE_RESOURCE);}) - , CMarketMisc([this](){return CFreelancerGuild::getSelectionParams();}) { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); @@ -71,7 +70,7 @@ CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance }; }); - CMarketMisc::deselect(); + CTradeBase::deselect(); } void CFreelancerGuild::makeDeal() @@ -83,7 +82,7 @@ void CFreelancerGuild::makeDeal() } } -CMarketMisc::SelectionParams CFreelancerGuild::getSelectionParams() +CTradeBase::SelectionParams CFreelancerGuild::getSelectionParams() const { if(hLeft && hRight) return std::make_tuple( diff --git a/client/widgets/markets/CFreelancerGuild.h b/client/widgets/markets/CFreelancerGuild.h index 7f2bbf8b1..078044d5d 100644 --- a/client/widgets/markets/CFreelancerGuild.h +++ b/client/widgets/markets/CFreelancerGuild.h @@ -11,14 +11,14 @@ #include "CTradeBase.h" -class CFreelancerGuild : public CCreaturesSelling , public CResourcesBuying, public CMarketMisc +class CFreelancerGuild : public CCreaturesSelling , public CResourcesBuying { public: CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero); void makeDeal() override; private: - CMarketMisc::SelectionParams getSelectionParams(); + CTradeBase::SelectionParams getSelectionParams() const override; void onOfferSliderMoved(int newVal); void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) override; }; diff --git a/client/widgets/markets/CMarketResources.cpp b/client/widgets/markets/CMarketResources.cpp index 39f451845..8ab982234 100644 --- a/client/widgets/markets/CMarketResources.cpp +++ b/client/widgets/markets/CMarketResources.cpp @@ -25,12 +25,11 @@ #include "../../../lib/mapObjects/CGMarket.h" CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero) + : CTradeBase(market, hero, [this](){return CMarketResources::getSelectionParams();}) , CResourcesBuying( [this](const std::shared_ptr & resSlot){CMarketResources::onSlotClickPressed(resSlot, hRight);}, [this](){CMarketResources::updateSubtitles();}) , CResourcesSelling([this](const std::shared_ptr & heroSlot){CMarketResources::onSlotClickPressed(heroSlot, hLeft);}) - , CMarketMisc([this](){return CMarketResources::getSelectionParams();}) { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); @@ -59,7 +58,7 @@ CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance }); CTradeBase::updateSlots(); - CMarketMisc::deselect(); + CTradeBase::deselect(); } void CMarketResources::makeDeal() @@ -71,7 +70,7 @@ void CMarketResources::makeDeal() } } -CMarketMisc::SelectionParams CMarketResources::getSelectionParams() +CTradeBase::SelectionParams CMarketResources::getSelectionParams() const { if(hLeft && hRight && hLeft->id != hRight->id) return std::make_tuple( diff --git a/client/widgets/markets/CMarketResources.h b/client/widgets/markets/CMarketResources.h index 5a14f49cb..b70e9836b 100644 --- a/client/widgets/markets/CMarketResources.h +++ b/client/widgets/markets/CMarketResources.h @@ -11,14 +11,14 @@ #include "CTradeBase.h" -class CMarketResources : public CResourcesSelling, public CResourcesBuying, public CMarketMisc +class CMarketResources : public CResourcesSelling, public CResourcesBuying { public: CMarketResources(const IMarket * market, const CGHeroInstance * hero); void makeDeal() override; private: - CMarketMisc::SelectionParams getSelectionParams(); + CTradeBase::SelectionParams getSelectionParams() const override; void onOfferSliderMoved(int newVal); void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot); void updateSubtitles(); diff --git a/client/widgets/markets/CTradeBase.cpp b/client/widgets/markets/CTradeBase.cpp index ab4c2b355..5af67e058 100644 --- a/client/widgets/markets/CTradeBase.cpp +++ b/client/widgets/markets/CTradeBase.cpp @@ -27,33 +27,13 @@ #include "../../../lib/mapObjects/CGHeroInstance.h" #include "../../../lib/mapObjects/CGMarket.h" -CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero) +CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero, const SelectionParamsFunctor & getParamsCallback) : market(market) , hero(hero) + , selectionParamsCallback(getParamsCallback) { } -void CTradeBase::removeItems(const std::set> & toRemove) -{ - for(auto item : toRemove) - removeItem(item); -} - -void CTradeBase::removeItem(std::shared_ptr item) -{ - offerTradePanel->slots.erase(std::remove(offerTradePanel->slots.begin(), offerTradePanel->slots.end(), item)); - - if(hRight == item) - hRight.reset(); -} - -void CTradeBase::getEmptySlots(std::set> & toRemove) -{ - for(auto item : bidTradePanel->slots) - if(!hero->getStackCount(SlotID(item->serial))) - toRemove.insert(item); -} - void CTradeBase::deselect() { if(hLeft) @@ -69,6 +49,9 @@ void CTradeBase::deselect() offerSlider->scrollTo(0); offerSlider->block(true); } + bidQty = 0; + offerQty = 0; + updateSelected(); } void CTradeBase::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) @@ -104,6 +87,31 @@ void CTradeBase::updateSubtitles(EMarketMode marketMode) offerTradePanel->clearSubtitles(); }; +void CTradeBase::updateSelected() +{ + const auto updateSelectedBody = [](std::shared_ptr & tradePanel, const std::optional & params) + { + std::optional lImageIndex = std::nullopt; + if(params.has_value()) + { + tradePanel->setSelectedSubtitleText(params.value().text); + lImageIndex = params.value().imageIndex; + } + else + { + tradePanel->clearSelectedSubtitleText(); + } + tradePanel->setSelectedFrameIndex(lImageIndex); + }; + + assert(selectionParamsCallback); + const auto params = selectionParamsCallback(); + if(bidTradePanel) + updateSelectedBody(bidTradePanel, std::get<0>(params)); + if(offerTradePanel) + updateSelectedBody(offerTradePanel, std::get<1>(params)); +} + CExperienceAltar::CExperienceAltar() { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); @@ -128,7 +136,7 @@ CCreaturesSelling::CCreaturesSelling() slots.emplace_back(std::make_tuple(creature->getId(), slotId, hero->getStackCount(slotId))); } bidTradePanel = std::make_shared(nullptr, slots); - bidTradePanel->updateSlotsCallback = std::bind(&CCreaturesSelling::updateSubtitle, this); + bidTradePanel->updateSlotsCallback = std::bind(&CCreaturesSelling::updateSubtitles, this); } bool CCreaturesSelling::slotDeletingCheck(const std::shared_ptr & slot) @@ -136,7 +144,7 @@ bool CCreaturesSelling::slotDeletingCheck(const std::shared_ptr return hero->getStackCount(SlotID(slot->serial)) == 0 ? true : false; } -void CCreaturesSelling::updateSubtitle() +void CCreaturesSelling::updateSubtitles() { for(auto & heroSlot : bidTradePanel->slots) heroSlot->subtitle->setText(std::to_string(this->hero->getStackCount(SlotID(heroSlot->serial)))); @@ -156,50 +164,12 @@ CResourcesSelling::CResourcesSelling(const CTradeableItem::ClickPressedFunctor & { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); - bidTradePanel = std::make_shared(clickPressedCallback, std::bind(&CResourcesSelling::updateSubtitle, this)); + bidTradePanel = std::make_shared(clickPressedCallback, std::bind(&CResourcesSelling::updateSubtitles, this)); labels.emplace_back(std::make_shared(156, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[270])); } -void CResourcesSelling::updateSubtitle() +void CResourcesSelling::updateSubtitles() { for(const auto & slot : bidTradePanel->slots) slot->subtitle->setText(std::to_string(LOCPLINT->cb->getResourceAmount(static_cast(slot->serial)))); } - -CMarketMisc::CMarketMisc(const SelectionParamsFunctor & callback) - : selectionParamsCallback(callback) -{ -} - -void CMarketMisc::deselect() -{ - CTradeBase::deselect(); - bidQty = 0; - offerQty = 0; - updateSelected(); -} - -void CMarketMisc::updateSelected() -{ - const auto updateSelectedBody = [](std::shared_ptr & tradePanel, const std::optional & params) - { - std::optional lImageIndex = std::nullopt; - if(params.has_value()) - { - tradePanel->setSelectedSubtitleText(params.value().text); - lImageIndex = params.value().imageIndex; - } - else - { - tradePanel->clearSelectedSubtitleText(); - } - tradePanel->setSelectedFrameIndex(lImageIndex); - }; - - assert(selectionParamsCallback); - const auto params = selectionParamsCallback(); - if(bidTradePanel) - updateSelectedBody(bidTradePanel, std::get<0>(params)); - if(offerTradePanel) - updateSelectedBody(offerTradePanel, std::get<1>(params)); -} diff --git a/client/widgets/markets/CTradeBase.h b/client/widgets/markets/CTradeBase.h index a8d2b7e5f..ef965abf5 100644 --- a/client/widgets/markets/CTradeBase.h +++ b/client/widgets/markets/CTradeBase.h @@ -24,33 +24,42 @@ class CSlider; class CTradeBase : public CIntObject { public: + struct SelectionParamOneSide + { + std::string text; + int imageIndex; + }; + using SelectionParams = std::tuple, std::optional>; + using SelectionParamsFunctor = std::function; + const IMarket * market; const CGHeroInstance * hero; - //all indexes: 1 = left, 0 = right - std::array>, 2> items; std::shared_ptr bidTradePanel; std::shared_ptr offerTradePanel; - //highlighted items (nullptr if no highlight) + // Highlighted trade slots (nullptr if no highlight) std::shared_ptr hLeft; std::shared_ptr hRight; std::shared_ptr deal; std::shared_ptr offerSlider; std::shared_ptr maxAmount; - std::vector> labels; std::vector> texts; + SelectionParamsFunctor selectionParamsCallback; + int bidQty; + int offerQty; - CTradeBase(const IMarket * market, const CGHeroInstance * hero); - void removeItems(const std::set> & toRemove); - void removeItem(std::shared_ptr item); - void getEmptySlots(std::set> & toRemove); + CTradeBase(const IMarket * market, const CGHeroInstance * hero, const SelectionParamsFunctor & getParamsCallback); virtual void makeDeal() = 0; virtual void deselect(); - virtual void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot); virtual void updateSlots(); + +protected: + virtual void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot); virtual void updateSubtitles(EMarketMode marketMode); + virtual void updateSelected(); + virtual CTradeBase::SelectionParams getSelectionParams() const = 0; }; // Market subclasses @@ -72,7 +81,7 @@ class CCreaturesSelling : virtual public CTradeBase public: CCreaturesSelling(); bool slotDeletingCheck(const std::shared_ptr & slot); - void updateSubtitle(); + void updateSubtitles(); }; class CResourcesBuying : virtual public CTradeBase @@ -86,26 +95,5 @@ class CResourcesSelling : virtual public CTradeBase { public: CResourcesSelling(const CTradeableItem::ClickPressedFunctor & clickPressedCallback); - void updateSubtitle(); -}; - -class CMarketMisc : virtual public CTradeBase -{ -public: - struct SelectionParamOneSide - { - std::string text; - int imageIndex; - }; - using SelectionParams = std::tuple, std::optional>; - using SelectionParamsFunctor = std::function; - - CMarketMisc(const SelectionParamsFunctor & callback); - void deselect() override; - void updateSelected(); - -protected: - int bidQty; - int offerQty; - SelectionParamsFunctor selectionParamsCallback; + void updateSubtitles(); }; diff --git a/client/widgets/markets/CTransferResources.cpp b/client/widgets/markets/CTransferResources.cpp index 58b28cf87..b747d47e7 100644 --- a/client/widgets/markets/CTransferResources.cpp +++ b/client/widgets/markets/CTransferResources.cpp @@ -24,9 +24,8 @@ #include "../../../lib/CGeneralTextHandler.h" CTransferResources::CTransferResources(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero) + : CTradeBase(market, hero, [this](){return CTransferResources::getSelectionParams();}) , CResourcesSelling([this](const std::shared_ptr & heroSlot){CTransferResources::onSlotClickPressed(heroSlot, hLeft);}) - , CMarketMisc([this](){return CTransferResources::getSelectionParams();}) { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); @@ -65,7 +64,7 @@ void CTransferResources::makeDeal() } } -CMarketMisc::SelectionParams CTransferResources::getSelectionParams() +CTradeBase::SelectionParams CTransferResources::getSelectionParams() const { if(hLeft && hRight) return std::make_tuple( diff --git a/client/widgets/markets/CTransferResources.h b/client/widgets/markets/CTransferResources.h index 8765b8f58..e26f98c40 100644 --- a/client/widgets/markets/CTransferResources.h +++ b/client/widgets/markets/CTransferResources.h @@ -11,14 +11,14 @@ #include "CTradeBase.h" -class CTransferResources : public CResourcesSelling, public CMarketMisc +class CTransferResources : public CResourcesSelling { public: CTransferResources(const IMarket * market, const CGHeroInstance * hero); void makeDeal() override; private: - CMarketMisc::SelectionParams getSelectionParams(); + CTradeBase::SelectionParams getSelectionParams() const override; void onOfferSliderMoved(int newVal); void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot); }; diff --git a/client/widgets/markets/TradePanels.cpp b/client/widgets/markets/TradePanels.cpp index c74dd5693..e55ebaef0 100644 --- a/client/widgets/markets/TradePanels.cpp +++ b/client/widgets/markets/TradePanels.cpp @@ -25,7 +25,6 @@ CTradeableItem::CTradeableItem(const Rect & area, EType Type, int ID, int Serial) : SelectableSlot(area, Point(1, 2)) - , artInstance(nullptr) , type(EType(-1)) // set to invalid, will be corrected in setType , id(ID) , serial(Serial) @@ -75,6 +74,7 @@ void CTradeableItem::setType(EType newType) break; case EType::ARTIFACT_PLACEHOLDER: case EType::ARTIFACT_INSTANCE: + subtitle->moveTo(pos.topLeft() + Point(22, 55)); break; case EType::ARTIFACT_TYPE: subtitle->moveTo(pos.topLeft() + Point(35, 57)); @@ -195,28 +195,6 @@ void CTradeableItem::showPopupWindow(const Point & cursorPosition) } } -const CArtifactInstance* CTradeableItem::getArtInstance() const -{ - switch(type) - { - case EType::ARTIFACT_PLACEHOLDER: - case EType::ARTIFACT_INSTANCE: - return artInstance; - default: - return nullptr; - } -} - -void CTradeableItem::setArtInstance(const CArtifactInstance * art) -{ - assert(type == EType::ARTIFACT_PLACEHOLDER || type == EType::ARTIFACT_INSTANCE); - artInstance = art; - if(art) - setID(art->getTypeId()); - else - setID(-1); -} - void TradePanelBase::updateSlots() { if(deleteSlotsCheck) @@ -370,3 +348,19 @@ CreaturesPanel::CreaturesPanel(const CTradeableItem::ClickPressedFunctor & click } selectedSlot = std::make_shared(Rect(selectedPos, slotDimension), EType::CREATURE, 0, 0); } + +ArtifactsAltarPanel::ArtifactsAltarPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback) +{ + OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); + + int slotNum = 0; + for(auto & altarSlotPos : slotsPos) + { + auto slot = slots.emplace_back(std::make_shared(Rect(altarSlotPos, Point(44, 44)), EType::ARTIFACT_PLACEHOLDER, -1, slotNum)); + slot->clickPressedCallback = clickPressedCallback; + slot->subtitle->clear(); + slotNum++; + } + selectedSlot = std::make_shared(Rect(selectedPos, slotDimension), EType::ARTIFACT_TYPE, 0, 0); + selectedSlot->subtitle->moveBy(Point(0, 3)); +} diff --git a/client/widgets/markets/TradePanels.h b/client/widgets/markets/TradePanels.h index dc0847cca..48459187c 100644 --- a/client/widgets/markets/TradePanels.h +++ b/client/widgets/markets/TradePanels.h @@ -27,7 +27,6 @@ public: int getIndex(); using ClickPressedFunctor = std::function&)>; - const CArtifactInstance * artInstance; //holds ptr to artifact instance id type artifact EType type; int id; const int serial; @@ -37,9 +36,6 @@ public: void setType(EType newType); void setID(int newID); - const CArtifactInstance * getArtInstance() const; - void setArtInstance(const CArtifactInstance * art); - void showPopupWindow(const Point & cursorPosition) override; void hover(bool on) override; void clickPressed(const Point & cursorPosition) override; @@ -139,3 +135,23 @@ public: CreaturesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const std::vector> & srcSlots, bool emptySlots = true); }; + +class ArtifactsAltarPanel : public TradePanelBase +{ + const std::vector slotsPos = + { + Point(0, 0), Point(54, 0), Point(108, 0), + Point(162, 0), Point(216, 0), Point(0, 70), + Point(54, 70), Point(108, 70), Point(162, 70), + Point(216, 70), Point(0, 140), Point(54, 140), + Point(108, 140), Point(162, 140), Point(216, 140), + Point(0, 210), Point(54, 210), Point(108, 210), + Point(162, 210), Point(216, 210), Point(81, 280), + Point(135, 280) + }; + const Point slotDimension = Point(69, 66); + const Point selectedPos = Point(-48, 389); + +public: + ArtifactsAltarPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback); +}; diff --git a/client/windows/CAltarWindow.cpp b/client/windows/CAltarWindow.cpp index 6b8bf02f7..5578c5b0f 100644 --- a/client/windows/CAltarWindow.cpp +++ b/client/windows/CAltarWindow.cpp @@ -47,9 +47,9 @@ void CAltarWindow::artifactMoved(const ArtifactLocation & srcLoc, const Artifact altarArtifacts->updateSlots(); if(const auto pickedArt = getPickedArtifact()) - altarArtifacts->setSelectedArtifact(pickedArt); + altarArtifacts->setSelectedArtifact(pickedArt->getTypeId()); else - altarArtifacts->setSelectedArtifact(nullptr); + altarArtifacts->setSelectedArtifact(std::nullopt); } CWindowWithArtifacts::artifactMoved(srcLoc, destLoc, withRedraw); }