diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 61f13b0ba..73f21b800 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -133,7 +133,6 @@ set(client_SRCS widgets/markets/CTradeBase.cpp widgets/markets/TradePanels.cpp - windows/CAltarWindow.cpp windows/CCastleInterface.cpp windows/CCreatureWindow.cpp windows/CHeroOverview.cpp @@ -322,7 +321,6 @@ set(client_HEADERS widgets/markets/CTradeBase.h widgets/markets/TradePanels.h - windows/CAltarWindow.h windows/CCastleInterface.h windows/CCreatureWindow.h windows/CHeroOverview.h diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index ca5c4c99c..2e372a609 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -419,8 +419,8 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, Prim EVENT_HANDLER_CALLED_BY_CLIENT; if (which == PrimarySkill::EXPERIENCE) { - for (auto ctw : GH.windows().findWindows()) - ctw->updateExpToLevel(); + for(auto ctw : GH.windows().findWindows()) + ctw->updateHero(); } else adventureInt->onHeroChanged(hero); @@ -450,7 +450,7 @@ void CPlayerInterface::receivedResource() { EVENT_HANDLER_CALLED_BY_CLIENT; for (auto mw : GH.windows().findWindows()) - mw->resourceChanged(); + mw->updateResource(); GH.windows().totalRedraw(); } @@ -1696,7 +1696,7 @@ void CPlayerInterface::availableArtifactsChanged(const CGBlackMarket * bm) { EVENT_HANDLER_CALLED_BY_CLIENT; for (auto cmw : GH.windows().findWindows()) - cmw->artifactsChanged(); + cmw->updateArtifacts(); } void CPlayerInterface::showTavernWindow(const CGObjectInstance * object, const CGHeroInstance * visitor, QueryID queryID) diff --git a/client/widgets/markets/CAltarArtifacts.cpp b/client/widgets/markets/CAltarArtifacts.cpp index f008f6b50..12163c5a4 100644 --- a/client/widgets/markets/CAltarArtifacts.cpp +++ b/client/widgets/markets/CAltarArtifacts.cpp @@ -86,6 +86,23 @@ void CAltarArtifacts::deselect() } } +void CAltarArtifacts::updateSlots() +{ + CExperienceAltar::updateSlots(); + if(const auto art = hero->getArt(ArtifactPosition::TRANSITION_POS)) + { + hRight = offerTradePanel->selectedSlot; + hRight->setID(art->getTypeId().num); + offerQty = calcExpCost(art->getTypeId()); + } + else + { + hRight.reset(); + offerQty = 0; + } + updateSelected(); +} + void CAltarArtifacts::makeDeal() { std::vector positions; @@ -107,32 +124,11 @@ void CAltarArtifacts::sacrificeBackpack() LOCPLINT->cb->bulkMoveArtifacts(heroArts->getHero()->id, altarId, false, false, true); } -void CAltarArtifacts::setSelectedArtifact(std::optional id) -{ - 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 { return heroArts; } -ObjectInstanceID CAltarArtifacts::getObjId() const -{ - return altarId; -} - void CAltarArtifacts::updateAltarSlots() { assert(altarArtifacts->artifactsInBackpack.size() <= GameConstants::ALTAR_ARTIFACTS_SLOTS); @@ -157,7 +153,7 @@ void CAltarArtifacts::updateAltarSlots() { assert(tradeSlot.first->id == -1); assert(altarArtifacts->getSlotByInstance(tradeSlot.second) != ArtifactPosition::PRE_FIRST); - tradeSlot.first->setID(tradeSlot.second->getTypeId()); + tradeSlot.first->setID(tradeSlot.second->getTypeId().num); tradeSlot.first->subtitle->setText(std::to_string(calcExpCost(tradeSlot.second->getTypeId()))); } @@ -174,7 +170,7 @@ void CAltarArtifacts::updateAltarSlots() for(auto & altarSlot : offerTradePanel->slots) if(altarSlot->id == -1) { - altarSlot->setID(slotInfo.artifact->getTypeId()); + altarSlot->setID(slotInfo.artifact->getTypeId().num); altarSlot->subtitle->setText(std::to_string(calcExpCost(slotInfo.artifact->getTypeId()))); tradeSlotsMap.try_emplace(altarSlot, slotInfo.artifact); break; @@ -198,7 +194,7 @@ CTradeBase::SelectionParams CAltarArtifacts::getSelectionParams() const if(hRight) return std::make_tuple( std::nullopt, - SelectionParamOneSide {std::to_string(offerQty), GameResID(hRight->id)} + SelectionParamOneSide {std::to_string(offerQty), CGI->artifacts()->getByIndex(hRight->id)->getIconIndex()} ); return std::make_tuple(std::nullopt, std::nullopt); } diff --git a/client/widgets/markets/CAltarArtifacts.h b/client/widgets/markets/CAltarArtifacts.h index 250c55ba7..e7de8d7c6 100644 --- a/client/widgets/markets/CAltarArtifacts.h +++ b/client/widgets/markets/CAltarArtifacts.h @@ -19,11 +19,10 @@ public: TExpType calcExpAltarForHero() override; void deselect() override; void makeDeal() override; + void updateSlots() override; void sacrificeAll() override; void sacrificeBackpack(); - void setSelectedArtifact(std::optional id); std::shared_ptr getAOHset() const; - ObjectInstanceID getObjId() const; void putBackArtifacts(); private: diff --git a/client/widgets/markets/CAltarCreatures.cpp b/client/widgets/markets/CAltarCreatures.cpp index 62768f604..5d6fa6db1 100644 --- a/client/widgets/markets/CAltarCreatures.cpp +++ b/client/widgets/markets/CAltarCreatures.cpp @@ -115,7 +115,7 @@ void CAltarCreatures::updateControls() void CAltarCreatures::updateSlots() { - CTradeBase::updateSlots(); + CExperienceAltar::updateSlots(); assert(bidTradePanel->slots.size() == offerTradePanel->slots.size()); } diff --git a/client/widgets/markets/CArtifactsBuying.cpp b/client/widgets/markets/CArtifactsBuying.cpp index 36ef991dc..d7545110f 100644 --- a/client/widgets/markets/CArtifactsBuying.cpp +++ b/client/widgets/markets/CArtifactsBuying.cpp @@ -55,7 +55,7 @@ CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance { return vstd::contains(this->market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT), ArtifactID(slot->id)) ? false : true; }; - offerTradePanel->moveTo(pos.topLeft() + Point(328, 182)); + offerTradePanel->moveTo(pos.topLeft() + Point(328, 181)); CTradeBase::updateSlots(); CTradeBase::deselect(); diff --git a/client/widgets/markets/CArtifactsSelling.cpp b/client/widgets/markets/CArtifactsSelling.cpp index f5beed729..c0e5d194d 100644 --- a/client/widgets/markets/CArtifactsSelling.cpp +++ b/client/widgets/markets/CArtifactsSelling.cpp @@ -17,9 +17,13 @@ #include "../../widgets/TextControls.h" #include "../../CGameInfo.h" +#include "../../CPlayerInterface.h" + +#include "../../../CCallback.h" #include "../../../lib/CArtifactInstance.h" #include "../../../lib/CGeneralTextHandler.h" +#include "../../../lib/mapObjects/CGHeroInstance.h" #include "../../../lib/mapObjects/CGMarket.h" CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero) @@ -44,6 +48,7 @@ CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstanc assert(artForTrade); bidSelectedSlot->setID(artForTrade->getTypeId().num); hLeft = bidSelectedSlot; + selectedHeroSlot = artPlace->slot; if(hRight) { // dublicate this->market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE); @@ -58,14 +63,24 @@ CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstanc assert(offerTradePanel); offerTradePanel->moveTo(pos.topLeft() + Point(326, 184)); offerTradePanel->selectedSlot->moveTo(pos.topLeft() + Point(409, 473)); + offerTradePanel->selectedSlot->subtitle->moveBy(Point(0, 1)); CArtifactsSelling::updateSelected(); + CArtifactsSelling::deselect(); +} + +void CArtifactsSelling::deselect() +{ CTradeBase::deselect(); + selectedHeroSlot = ArtifactPosition::PRE_FIRST; + heroArts->unmarkSlots(); } void CArtifactsSelling::makeDeal() { - + const auto art = hero->getArt(selectedHeroSlot); + assert(art); + LOCPLINT->cb->trade(market, EMarketMode::ARTIFACT_RESOURCE, art->getId(), GameResID(hRight->id), offerQty, hero); } void CArtifactsSelling::updateSelected() @@ -86,6 +101,16 @@ void CArtifactsSelling::updateSelected() } } +void CArtifactsSelling::updateSlots() +{ + CTradeBase::updateSlots(); + if(selectedHeroSlot != ArtifactPosition::PRE_FIRST) + { + if(hero->getArt(selectedHeroSlot) == nullptr) + deselect(); + } +} + std::shared_ptr CArtifactsSelling::getAOHset() const { return heroArts; @@ -96,7 +121,7 @@ CTradeBase::SelectionParams CArtifactsSelling::getSelectionParams() const if(hLeft && hRight) return std::make_tuple( std::nullopt, - SelectionParamOneSide {std::to_string(offerQty), GameResID(hRight->id)} + SelectionParamOneSide {std::to_string(offerQty), hRight->id} ); else return std::make_tuple(std::nullopt, std::nullopt); diff --git a/client/widgets/markets/CArtifactsSelling.h b/client/widgets/markets/CArtifactsSelling.h index d61ec3e95..f450c6906 100644 --- a/client/widgets/markets/CArtifactsSelling.h +++ b/client/widgets/markets/CArtifactsSelling.h @@ -16,14 +16,17 @@ class CArtifactsSelling : public CResourcesBuying { public: CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero); + void deselect() override; void makeDeal() override; void updateSelected() override; + void updateSlots() override; std::shared_ptr getAOHset() const; private: std::shared_ptr heroArts; std::shared_ptr bidSelectedSubtitle; std::shared_ptr bidSelectedSlot; + ArtifactPosition selectedHeroSlot; CTradeBase::SelectionParams getSelectionParams() const override; void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) override; diff --git a/client/widgets/markets/CTradeBase.cpp b/client/widgets/markets/CTradeBase.cpp index 5af67e058..bcc368adc 100644 --- a/client/widgets/markets/CTradeBase.cpp +++ b/client/widgets/markets/CTradeBase.cpp @@ -25,6 +25,7 @@ #include "../../../lib/CGeneralTextHandler.h" #include "../../../lib/mapObjects/CGHeroInstance.h" +#include "../../../lib/CHeroHandler.h" #include "../../../lib/mapObjects/CGMarket.h" CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero, const SelectionParamsFunctor & getParamsCallback) @@ -120,8 +121,14 @@ CExperienceAltar::CExperienceAltar() texts.emplace_back(std::make_shared(CGI->generaltexth->allTexts[475], Rect(15, 415, 125, 50), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW)); // Total experience on the Altar texts.emplace_back(std::make_shared(CGI->generaltexth->allTexts[476], Rect(15, 495, 125, 40), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW)); - expToLevel = std::make_shared(75, 477, FONT_SMALL, ETextAlignment::CENTER); - expForHero = std::make_shared(75, 545, FONT_SMALL, ETextAlignment::CENTER); + expToLevel = std::make_shared(76, 477, FONT_SMALL, ETextAlignment::CENTER); + expForHero = std::make_shared(76, 545, FONT_SMALL, ETextAlignment::CENTER); +} + +void CExperienceAltar::updateSlots() +{ + CTradeBase::updateSlots(); + expToLevel->setText(std::to_string(CGI->heroh->reqExp(CGI->heroh->level(hero->exp) + 1) - hero->exp)); } CCreaturesSelling::CCreaturesSelling() diff --git a/client/widgets/markets/CTradeBase.h b/client/widgets/markets/CTradeBase.h index ef965abf5..8bca0cfd8 100644 --- a/client/widgets/markets/CTradeBase.h +++ b/client/widgets/markets/CTradeBase.h @@ -72,6 +72,7 @@ public: const Point dealButtonPos = Point(269, 520); CExperienceAltar(); + void updateSlots() override; virtual void sacrificeAll() = 0; virtual TExpType calcExpAltarForHero() = 0; }; diff --git a/client/widgets/markets/TradePanels.cpp b/client/widgets/markets/TradePanels.cpp index e55ebaef0..959ea3747 100644 --- a/client/widgets/markets/TradePanels.cpp +++ b/client/widgets/markets/TradePanels.cpp @@ -24,7 +24,7 @@ #include "../../../lib/mapObjects/CGHeroInstance.h" CTradeableItem::CTradeableItem(const Rect & area, EType Type, int ID, int Serial) - : SelectableSlot(area, Point(1, 2)) + : SelectableSlot(area, Point(1, 1)) , type(EType(-1)) // set to invalid, will be corrected in setType , id(ID) , serial(Serial) @@ -74,7 +74,8 @@ void CTradeableItem::setType(EType newType) break; case EType::ARTIFACT_PLACEHOLDER: case EType::ARTIFACT_INSTANCE: - subtitle->moveTo(pos.topLeft() + Point(22, 55)); + image->moveTo(pos.topLeft() + Point(0, 1)); + subtitle->moveTo(pos.topLeft() + Point(22, 56)); break; case EType::ARTIFACT_TYPE: subtitle->moveTo(pos.topLeft() + Point(35, 57)); @@ -287,6 +288,7 @@ ArtifactsPanel::ArtifactsPanel(const CTradeableItem::ClickPressedFunctor & click } updateSlotsCallback = updateSubtitles; selectedSlot = std::make_shared(Rect(selectedPos, slotDimension), EType::ARTIFACT_TYPE, 0, 0); + selectedSlot->subtitle->moveBy(Point(0, 1)); } PlayersPanel::PlayersPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback) @@ -359,6 +361,7 @@ ArtifactsAltarPanel::ArtifactsAltarPanel(const CTradeableItem::ClickPressedFunct auto slot = slots.emplace_back(std::make_shared(Rect(altarSlotPos, Point(44, 44)), EType::ARTIFACT_PLACEHOLDER, -1, slotNum)); slot->clickPressedCallback = clickPressedCallback; slot->subtitle->clear(); + slot->subtitle->moveBy(Point(0, -1)); slotNum++; } selectedSlot = std::make_shared(Rect(selectedPos, slotDimension), EType::ARTIFACT_TYPE, 0, 0); diff --git a/client/widgets/markets/TradePanels.h b/client/widgets/markets/TradePanels.h index 48459187c..4a0516e72 100644 --- a/client/widgets/markets/TradePanels.h +++ b/client/widgets/markets/TradePanels.h @@ -94,7 +94,7 @@ class ArtifactsPanel : public TradePanelBase Point(83, 158) }; const size_t slotsForTrade = 7; - const Point slotDimension = Point(69, 66); + const Point slotDimension = Point(69, 68); const Point selectedPos = Point(83, 266); public: diff --git a/client/windows/CAltarWindow.cpp b/client/windows/CAltarWindow.cpp deleted file mode 100644 index 5578c5b0f..000000000 --- a/client/windows/CAltarWindow.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * CAltarWindow.cpp, part of VCMI engine - * - * Authors: listed in file AUTHORS in main folder - * - * License: GNU General Public License v2.0 or later - * Full text of license available in license.txt file, in main folder - * - */ - -#include "StdInc.h" -#include "CAltarWindow.h" - -#include "../widgets/TextControls.h" - -#include "../CGameInfo.h" - -#include "../lib/networkPacks/ArtifactLocation.h" -#include "../../lib/CHeroHandler.h" -#include "../../lib/mapObjects/CGHeroInstance.h" - -void CAltarWindow::updateExpToLevel() -{ - assert(altar); - altar->expToLevel->setText(std::to_string(CGI->heroh->reqExp(CGI->heroh->level(altar->hero->exp) + 1) - altar->hero->exp)); -} - -void CAltarWindow::updateGarrisons() -{ - if(auto altarCreatures = std::static_pointer_cast(altar)) - altarCreatures->updateSlots(); -} - -bool CAltarWindow::holdsGarrison(const CArmedInstance * army) -{ - return getHero() == army; -} - -void CAltarWindow::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw) -{ - if(!getState().has_value()) - return; - - if(auto altarArtifacts = std::static_pointer_cast(altar)) - { - if(srcLoc.artHolder == altarArtifacts->getObjId() || destLoc.artHolder == altarArtifacts->getObjId()) - altarArtifacts->updateSlots(); - - if(const auto pickedArt = getPickedArtifact()) - altarArtifacts->setSelectedArtifact(pickedArt->getTypeId()); - else - altarArtifacts->setSelectedArtifact(std::nullopt); - } - CWindowWithArtifacts::artifactMoved(srcLoc, destLoc, withRedraw); -} diff --git a/client/windows/CAltarWindow.h b/client/windows/CAltarWindow.h deleted file mode 100644 index e76ff0f13..000000000 --- a/client/windows/CAltarWindow.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * CAltarWindow.h, part of VCMI engine - * - * Authors: listed in file AUTHORS in main folder - * - * License: GNU General Public License v2.0 or later - * Full text of license available in license.txt file, in main folder - * - */ -#pragma once - -#include "../widgets/CWindowWithArtifacts.h" -#include "../widgets/markets/CAltarArtifacts.h" -#include "../widgets/markets/CAltarCreatures.h" - -class CExperienceAltar; - -class CAltarWindow : public CWindowWithArtifacts, public IGarrisonHolder -{ -public: - void updateExpToLevel(); - void updateGarrisons() override; - bool holdsGarrison(const CArmedInstance * army) override; - virtual const CGHeroInstance * getHero() const = 0; - - void artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw) override; - - std::shared_ptr altar; -}; diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index dadea1812..9439ebf1e 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -685,7 +685,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil logGlobal->trace("You've clicked on %d", (int)building.toEnum()); const CBuilding *b = town->town->buildings.find(building)->second; - if(building >= BuildingID::DWELL_FIRST) + if (building >= BuildingID::DWELL_FIRST) { enterDwelling((building-BuildingID::DWELL_FIRST)%GameConstants::CREATURES_PER_TOWN); } @@ -744,7 +744,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil case BuildingID::SPECIAL_1: case BuildingID::SPECIAL_2: case BuildingID::SPECIAL_3: - switch(subID) + switch (subID) { case BuildingSubID::NONE: enterBuilding(building); diff --git a/client/windows/CMarketWindow.cpp b/client/windows/CMarketWindow.cpp index 2db6537b5..75c708a03 100644 --- a/client/windows/CMarketWindow.cpp +++ b/client/windows/CMarketWindow.cpp @@ -16,6 +16,8 @@ #include "../widgets/Buttons.h" #include "../widgets/TextControls.h" +#include "../widgets/markets/CAltarArtifacts.h" +#include "../widgets/markets/CAltarCreatures.h" #include "../widgets/markets/CArtifactsBuying.h" #include "../widgets/markets/CArtifactsSelling.h" #include "../widgets/markets/CFreelancerGuild.h" @@ -32,13 +34,14 @@ CMarketWindow::CMarketWindow(const IMarket * market, const CGHeroInstance * hero, const std::function & onWindowClosed, EMarketMode mode) : CStatusbarWindow(PLAYER_COLORED) - , hero(hero) , windowClosedCallback(onWindowClosed) { assert(mode == EMarketMode::RESOURCE_RESOURCE || mode == EMarketMode::RESOURCE_PLAYER || mode == EMarketMode::CREATURE_RESOURCE || mode == EMarketMode::RESOURCE_ARTIFACT || mode == EMarketMode::ARTIFACT_RESOURCE || mode == EMarketMode::ARTIFACT_EXP || mode == EMarketMode::CREATURE_EXP); + OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); + if(mode == EMarketMode::RESOURCE_RESOURCE) createMarketResources(market, hero); else if(mode == EMarketMode::RESOURCE_PLAYER) @@ -54,31 +57,31 @@ CMarketWindow::CMarketWindow(const IMarket * market, const CGHeroInstance * hero else if(mode == EMarketMode::CREATURE_EXP) createAltarCreatures(market, hero); - OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); statusbar = CGStatusBar::create(std::make_shared(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); } -void CMarketWindow::artifactsChanged() +void CMarketWindow::updateArtifacts() { - //market->artifactsChanged(false); - if(artsBuy) - artsBuy->updateSlots(); + assert(marketWidget); + marketWidget->updateSlots(); } void CMarketWindow::updateGarrisons() { - if(guild) - guild->updateSlots(); - if(altar) - altar->updateSlots(); + assert(marketWidget); + marketWidget->updateSlots(); } -void CMarketWindow::resourceChanged() +void CMarketWindow::updateResource() { - if(resRes) - resRes->updateSlots(); - if(trRes) - trRes->updateSlots(); + assert(marketWidget); + marketWidget->updateSlots(); +} + +void CMarketWindow::updateHero() +{ + assert(marketWidget); + marketWidget->updateSlots(); } void CMarketWindow::close() @@ -89,9 +92,25 @@ void CMarketWindow::close() CWindowObject::close(); } -const CGHeroInstance * CMarketWindow::getHero() const +bool CMarketWindow::holdsGarrison(const CArmedInstance * army) { - return hero; + assert(marketWidget); + return marketWidget->hero == army; +} + +void CMarketWindow::artifactRemoved(const ArtifactLocation & artLoc) +{ + marketWidget->updateSlots(); + CWindowWithArtifacts::artifactRemoved(artLoc); +} + +void CMarketWindow::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw) +{ + if(!getState().has_value()) + return; + assert(marketWidget); + marketWidget->updateSlots(); + CWindowWithArtifacts::artifactMoved(srcLoc, destLoc, withRedraw); } void CMarketWindow::createChangeModeButtons(EMarketMode currentMode, const IMarket * market, const CGHeroInstance * hero) @@ -117,82 +136,76 @@ void CMarketWindow::createChangeModeButtons(EMarketMode currentMode, const IMark } }; - auto buttonPosY = 520; changeModeButtons.clear(); + auto buttonPos = Point(18, 520); + + auto addButton = [this, &buttonPos](const AnimationPath & picPath, const std::pair & buttonHelpContainer, + const std::function & pressButtonFunctor) + { + changeModeButtons.emplace_back(std::make_shared(buttonPos, picPath, buttonHelpContainer, pressButtonFunctor)); + buttonPos -= Point(0, buttonHeightWithMargin); + }; if(isButton(EMarketMode::RESOURCE_PLAYER)) - changeModeButtons.emplace_back(std::make_shared(Point(18, buttonPosY), AnimationPath::builtin("TPMRKBU1.DEF"), - CGI->generaltexth->zelp[612], std::bind(&CMarketWindow::createTransferResources, this, market, hero))); - - buttonPosY -= buttonHeightWithMargin; + addButton(AnimationPath::builtin("TPMRKBU1.DEF"), CGI->generaltexth->zelp[612], std::bind(&CMarketWindow::createTransferResources, this, market, hero)); if(isButton(EMarketMode::ARTIFACT_RESOURCE)) - { - changeModeButtons.emplace_back(std::make_shared(Point(18, buttonPosY), AnimationPath::builtin("TPMRKBU3.DEF"), - CGI->generaltexth->zelp[613], std::bind(&CMarketWindow::createArtifactsSelling, this, market, hero))); - buttonPosY -= buttonHeightWithMargin; - } - if(isButton(EMarketMode::CREATURE_RESOURCE)) - changeModeButtons.emplace_back(std::make_shared(Point(516, buttonPosY), AnimationPath::builtin("TPMRKBU4.DEF"), - CGI->generaltexth->zelp[599], std::bind(&CMarketWindow::createFreelancersGuild, this, market, hero))); - if(isButton(EMarketMode::RESOURCE_RESOURCE)) - changeModeButtons.emplace_back(std::make_shared(Point(516, buttonPosY), AnimationPath::builtin("TPMRKBU5.DEF"), - CGI->generaltexth->zelp[605], std::bind(&CMarketWindow::createMarketResources, this, market, hero))); + addButton(AnimationPath::builtin("TPMRKBU3.DEF"), CGI->generaltexth->zelp[613], std::bind(&CMarketWindow::createArtifactsSelling, this, market, hero)); if(isButton(EMarketMode::RESOURCE_ARTIFACT)) - changeModeButtons.emplace_back(std::make_shared(Point(18, buttonPosY), AnimationPath::builtin("TPMRKBU2.DEF"), - CGI->generaltexth->zelp[598], std::bind(&CMarketWindow::createArtifactsBuying, this, market, hero))); + addButton(AnimationPath::builtin("TPMRKBU2.DEF"), CGI->generaltexth->zelp[598], std::bind(&CMarketWindow::createArtifactsBuying, this, market, hero)); + + buttonPos = Point(516, 520 - buttonHeightWithMargin); + if(isButton(EMarketMode::CREATURE_RESOURCE)) + addButton(AnimationPath::builtin("TPMRKBU4.DEF"), CGI->generaltexth->zelp[599], std::bind(&CMarketWindow::createFreelancersGuild, this, market, hero)); + if(isButton(EMarketMode::RESOURCE_RESOURCE)) + addButton(AnimationPath::builtin("TPMRKBU5.DEF"), CGI->generaltexth->zelp[605], std::bind(&CMarketWindow::createMarketResources, this, market, hero)); + + buttonPos = Point(516, 421); if(isButton(EMarketMode::CREATURE_EXP)) { - changeModeButtons.emplace_back(std::make_shared(Point(516, 421), AnimationPath::builtin("ALTSACC.DEF"), - CGI->generaltexth->zelp[572], std::bind(&CMarketWindow::createAltarCreatures, this, market, hero))); - if(altar->hero->getAlignment() == EAlignment::GOOD) + addButton(AnimationPath::builtin("ALTSACC.DEF"), CGI->generaltexth->zelp[572], std::bind(&CMarketWindow::createAltarCreatures, this, market, hero)); + if(marketWidget->hero->getAlignment() == EAlignment::GOOD) changeModeButtons.back()->block(true); } if(isButton(EMarketMode::ARTIFACT_EXP)) { - changeModeButtons.emplace_back(std::make_shared(Point(516, 421), AnimationPath::builtin("ALTART.DEF"), - CGI->generaltexth->zelp[580], std::bind(&CMarketWindow::createAltarArtifacts, this, market, hero))); - if(altar->hero->getAlignment() == EAlignment::EVIL) + addButton(AnimationPath::builtin("ALTART.DEF"), CGI->generaltexth->zelp[580], std::bind(&CMarketWindow::createAltarArtifacts, this, market, hero)); + if(marketWidget->hero->getAlignment() == EAlignment::EVIL) changeModeButtons.back()->block(true); } } +void CMarketWindow::initWidgetInternals(const EMarketMode mode, const std::pair & quitButtonHelpContainer) +{ + background->center(); + pos = background->pos; + marketWidget->setRedrawParent(true); + marketWidget->moveTo(pos.topLeft()); + + createChangeModeButtons(mode, marketWidget->market, marketWidget->hero); + quitButton = std::make_shared(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"), + quitButtonHelpContainer, [this](){close();}, EShortcut::GLOBAL_RETURN); + redraw(); +} + void CMarketWindow::createArtifactsBuying(const IMarket * market, const CGHeroInstance * hero) { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); background = createBg(ImagePath::builtin("TPMRKABS.bmp"), PLAYER_COLORED); - artsBuy = std::make_shared(market, hero); - - background->center(); - pos = background->pos; - artsBuy->setRedrawParent(true); - artsBuy->moveTo(pos.topLeft()); - - createChangeModeButtons(EMarketMode::RESOURCE_ARTIFACT, market, hero); - quitButton = std::make_shared(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"), - CGI->generaltexth->zelp[600], [this]() {close(); }, EShortcut::GLOBAL_RETURN); - redraw(); + marketWidget = std::make_shared(market, hero); + initWidgetInternals(EMarketMode::RESOURCE_ARTIFACT, CGI->generaltexth->zelp[600]); } void CMarketWindow::createArtifactsSelling(const IMarket * market, const CGHeroInstance * hero) { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); - artsBuy.reset(); + background = createBg(ImagePath::builtin("TPMRKASS.bmp"), PLAYER_COLORED); - - artsSel = std::make_shared(market, hero); + auto artsSellingMarket = std::make_shared(market, hero); artSets.clear(); - addSetAndCallbacks(artsSel->getAOHset()); - - background->center(); - pos = background->pos; - artsSel->setRedrawParent(true); - artsSel->moveTo(pos.topLeft()); - - createChangeModeButtons(EMarketMode::ARTIFACT_RESOURCE, market, hero); - quitButton = std::make_shared(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"), - CGI->generaltexth->zelp[600], [this]() {close(); }, EShortcut::GLOBAL_RETURN); - redraw(); + addSetAndCallbacks(artsSellingMarket->getAOHset()); + marketWidget = artsSellingMarket; + initWidgetInternals(EMarketMode::ARTIFACT_RESOURCE, CGI->generaltexth->zelp[600]); } void CMarketWindow::createMarketResources(const IMarket * market, const CGHeroInstance * hero) @@ -200,17 +213,8 @@ void CMarketWindow::createMarketResources(const IMarket * market, const CGHeroIn OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); background = createBg(ImagePath::builtin("TPMRKRES.bmp"), PLAYER_COLORED); - resRes = std::make_shared(market, hero); - - background->center(); - pos = background->pos; - resRes->setRedrawParent(true); - resRes->moveTo(pos.topLeft()); - - createChangeModeButtons(EMarketMode::RESOURCE_RESOURCE, market, hero); - quitButton = std::make_shared(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"), - CGI->generaltexth->zelp[600], [this]() {close(); }, EShortcut::GLOBAL_RETURN); - redraw(); + marketWidget = std::make_shared(market, hero); + initWidgetInternals(EMarketMode::RESOURCE_RESOURCE, CGI->generaltexth->zelp[600]); } void CMarketWindow::createFreelancersGuild(const IMarket * market, const CGHeroInstance * hero) @@ -218,17 +222,8 @@ void CMarketWindow::createFreelancersGuild(const IMarket * market, const CGHeroI OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); background = createBg(ImagePath::builtin("TPMRKCRS.bmp"), PLAYER_COLORED); - guild = std::make_shared(market, hero); - - background->center(); - pos = background->pos; - guild->setRedrawParent(true); - guild->moveTo(pos.topLeft()); - - createChangeModeButtons(EMarketMode::CREATURE_RESOURCE, market, hero); - quitButton = std::make_shared(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"), - CGI->generaltexth->zelp[600], [this]() {close(); }, EShortcut::GLOBAL_RETURN); - redraw(); + marketWidget = std::make_shared(market, hero); + initWidgetInternals(EMarketMode::CREATURE_RESOURCE, CGI->generaltexth->zelp[600]); } void CMarketWindow::createTransferResources(const IMarket * market, const CGHeroInstance * hero) @@ -236,17 +231,8 @@ void CMarketWindow::createTransferResources(const IMarket * market, const CGHero OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); background = createBg(ImagePath::builtin("TPMRKPTS.bmp"), PLAYER_COLORED); - trRes = std::make_shared(market, hero); - - background->center(); - pos = background->pos; - trRes->setRedrawParent(true); - trRes->moveTo(pos.topLeft()); - - createChangeModeButtons(EMarketMode::RESOURCE_PLAYER, market, hero); - quitButton = std::make_shared(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"), - CGI->generaltexth->zelp[600], [this]() {close(); }, EShortcut::GLOBAL_RETURN); - redraw(); + marketWidget = std::make_shared(market, hero); + initWidgetInternals(EMarketMode::RESOURCE_PLAYER, CGI->generaltexth->zelp[600]); } void CMarketWindow::createAltarArtifacts(const IMarket * market, const CGHeroInstance * hero) @@ -255,25 +241,12 @@ void CMarketWindow::createAltarArtifacts(const IMarket * market, const CGHeroIns background = createBg(ImagePath::builtin("ALTRART2.bmp"), PLAYER_COLORED); auto altarArtifacts = std::make_shared(market, hero); - altar = altarArtifacts; + marketWidget = altarArtifacts; artSets.clear(); addSetAndCallbacks(altarArtifacts->getAOHset()); - - background->center(); - pos = background->pos; - altar->setRedrawParent(true); - createChangeModeButtons(EMarketMode::ARTIFACT_EXP, market, hero); - altar->moveTo(pos.topLeft()); - - quitButton = std::make_shared(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"), - CGI->generaltexth->zelp[568], [this, altarArtifacts]() - { - altarArtifacts->putBackArtifacts(); - CMarketWindow::close(); - }, EShortcut::GLOBAL_RETURN); - - updateExpToLevel(); - redraw(); + initWidgetInternals(EMarketMode::ARTIFACT_EXP, CGI->generaltexth->zelp[568]); + updateHero(); + quitButton->addCallback([altarArtifacts](){altarArtifacts->putBackArtifacts();}); } void CMarketWindow::createAltarCreatures(const IMarket * market, const CGHeroInstance * hero) @@ -281,17 +254,7 @@ void CMarketWindow::createAltarCreatures(const IMarket * market, const CGHeroIns OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); background = createBg(ImagePath::builtin("ALTARMON.bmp"), PLAYER_COLORED); - altar = std::make_shared(market, hero); - - background->center(); - pos = background->pos; - altar->setRedrawParent(true); - createChangeModeButtons(EMarketMode::CREATURE_EXP, market, hero); - altar->moveTo(pos.topLeft()); - - quitButton = std::make_shared(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"), - CGI->generaltexth->zelp[568], std::bind(&CMarketWindow::close, this), EShortcut::GLOBAL_RETURN); - - updateExpToLevel(); - redraw(); + marketWidget = std::make_shared(market, hero); + initWidgetInternals(EMarketMode::CREATURE_EXP, CGI->generaltexth->zelp[568]); + updateHero(); } diff --git a/client/windows/CMarketWindow.h b/client/windows/CMarketWindow.h index 6ca6537c3..0e404522d 100644 --- a/client/windows/CMarketWindow.h +++ b/client/windows/CMarketWindow.h @@ -10,27 +10,25 @@ #pragma once #include "../widgets/markets/CTradeBase.h" +#include "../widgets/CWindowWithArtifacts.h" #include "CWindowObject.h" -#include "CAltarWindow.h" -class CArtifactsBuying; -class CArtifactsSelling; -class CFreelancerGuild; -class CMarketResources; -class CTransferResources; - -class CMarketWindow : public CStatusbarWindow, public CAltarWindow // TODO remove CAltarWindow +class CMarketWindow : public CStatusbarWindow, public CWindowWithArtifacts, public IGarrisonHolder { public: CMarketWindow(const IMarket * market, const CGHeroInstance * hero, const std::function & onWindowClosed, EMarketMode mode); - void resourceChanged(); - void artifactsChanged(); + void updateResource(); + void updateArtifacts(); void updateGarrisons() override; + void updateHero(); void close() override; - const CGHeroInstance * getHero() const; + bool holdsGarrison(const CArmedInstance * army) override; + void artifactRemoved(const ArtifactLocation & artLoc) override; + void artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw) override; private: void createChangeModeButtons(EMarketMode currentMode, const IMarket * market, const CGHeroInstance * hero); + void initWidgetInternals(const EMarketMode mode, const std::pair & quitButtonHelpContainer); void createArtifactsBuying(const IMarket * market, const CGHeroInstance * hero); void createArtifactsSelling(const IMarket * market, const CGHeroInstance * hero); @@ -41,15 +39,9 @@ private: void createAltarCreatures(const IMarket * market, const CGHeroInstance * hero); const int buttonHeightWithMargin = 32 + 3; - const CGHeroInstance * hero; std::vector> changeModeButtons; std::shared_ptr quitButton; std::function windowClosedCallback; const Point quitButtonPos = Point(516, 520); - - std::shared_ptr guild; - std::shared_ptr resRes; - std::shared_ptr trRes; - std::shared_ptr artsBuy; - std::shared_ptr artsSel; + std::shared_ptr marketWidget; };