/* * CTradeWindow.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/CArtifactHolder.h" #include "CWindowObject.h" #include "../../lib/FunctionList.h" VCMI_LIB_NAMESPACE_BEGIN class IMarket; VCMI_LIB_NAMESPACE_END class CSlider; class CTextBox; class CGStatusBar; class CTradeWindow : public CWindowObject, public CWindowWithArtifacts //base for markets and altar of sacrifice { public: enum EType { RESOURCE, PLAYER, ARTIFACT_TYPE, CREATURE, CREATURE_PLACEHOLDER, ARTIFACT_PLACEHOLDER, ARTIFACT_INSTANCE }; class CTradeableItem : public CIntObject, public std::enable_shared_from_this<CTradeableItem> { std::shared_ptr<CAnimImage> image; std::string getFilename(); int getIndex(); public: const CArtifactInstance * hlp; //holds ptr to artifact instance id type artifact EType type; int id; const int serial; const bool left; std::string subtitle; //empty if default void setType(EType newType); void setID(int newID); const CArtifactInstance * getArtInstance() const; void setArtInstance(const CArtifactInstance * art); CFunctionList<void()> callback; bool downSelection; void showAllAt(const Point & dstPos, const std::string & customSub, SDL_Surface * to); void clickRight(tribool down, bool previousState) override; void hover(bool on) override; void showAll(SDL_Surface * to) override; void clickLeft(tribool down, bool previousState) override; std::string getName(int number = -1) const; CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial); }; const IMarket * market; const CGHeroInstance * hero; std::shared_ptr<CArtifactsOfHero> arts; //all indexes: 1 = left, 0 = right std::array<std::vector<std::shared_ptr<CTradeableItem>>, 2> items; //highlighted items (nullptr if no highlight) std::shared_ptr<CTradeableItem> hLeft; std::shared_ptr<CTradeableItem> hRight; EType itemsType[2]; EMarketMode::EMarketMode mode; std::shared_ptr<CButton> ok; std::shared_ptr<CButton> max; std::shared_ptr<CButton> deal; std::shared_ptr<CSlider> slider; //for choosing amount to be exchanged bool readyToTrade; CTradeWindow(std::string bgName, const IMarket * Market, const CGHeroInstance * Hero, EMarketMode::EMarketMode Mode); //c void showAll(SDL_Surface * to) override; void initSubs(bool Left); void initTypes(); void initItems(bool Left); std::vector<int> *getItemsIds(bool Left); //nullptr if default void getPositionsFor(std::vector<Rect> &poss, bool Left, EType type) const; void removeItems(const std::set<std::shared_ptr<CTradeableItem>> & toRemove); void removeItem(std::shared_ptr<CTradeableItem> item); void getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove); void setMode(EMarketMode::EMarketMode Mode); //mode setter void artifactSelected(CHeroArtPlace *slot); //used when selling artifacts -> called when user clicked on artifact slot virtual void getBaseForPositions(EType type, int &dx, int &dy, int &x, int &y, int &h, int &w, bool Right, int &leftToRightOffset) const = 0; virtual void selectionChanged(bool side) = 0; //true == left virtual Point selectionOffset(bool Left) const = 0; virtual std::string selectionSubtitle(bool Left) const = 0; virtual void garrisonChanged() = 0; virtual void artifactsChanged(bool left) = 0; protected: std::shared_ptr<CGStatusBar> statusBar; std::vector<std::shared_ptr<CLabel>> labels; std::vector<std::shared_ptr<CButton>> buttons; std::vector<std::shared_ptr<CTextBox>> texts; }; class CMarketplaceWindow : public CTradeWindow { std::shared_ptr<CLabel> titleLabel; bool printButtonFor(EMarketMode::EMarketMode M) const; std::string getBackgroundForMode(EMarketMode::EMarketMode mode); public: int r1, r2; //suggested amounts of traded resources bool madeTransaction; //if player made at least one transaction std::shared_ptr<CTextBox> traderText; void setMax(); void sliderMoved(int to); void makeDeal(); void selectionChanged(bool side) override; //true == left CMarketplaceWindow(const IMarket * Market, const CGHeroInstance * Hero = nullptr, EMarketMode::EMarketMode Mode = EMarketMode::RESOURCE_RESOURCE); ~CMarketplaceWindow(); Point selectionOffset(bool Left) const override; std::string selectionSubtitle(bool Left) const override; void garrisonChanged() override; //removes creatures with count 0 from the list (apparently whole stack has been sold) void artifactsChanged(bool left) override; void resourceChanged(); void getBaseForPositions(EType type, int &dx, int &dy, int &x, int &y, int &h, int &w, bool Right, int &leftToRightOffset) const override; void updateTraderText(); }; class CAltarWindow : public CTradeWindow { std::shared_ptr<CAnimImage> artIcon; public: std::vector<int> sacrificedUnits; //[slot_nr] -> how many creatures from that slot will be sacrificed std::vector<int> expPerUnit; std::shared_ptr<CButton> sacrificeAll; std::shared_ptr<CButton> sacrificeBackpack; std::shared_ptr<CLabel> expToLevel; std::shared_ptr<CLabel> expOnAltar; CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, EMarketMode::EMarketMode Mode); ~CAltarWindow(); void getExpValues(); void selectionChanged(bool side) override; //true == left void selectOppositeItem(bool side); void SacrificeAll(); void SacrificeBackpack(); void putOnAltar(int backpackIndex); bool putOnAltar(std::shared_ptr<CTradeableItem> altarSlot, const CArtifactInstance * art); void makeDeal(); void showAll(SDL_Surface * to) override; void blockTrade(); void sliderMoved(int to); void getBaseForPositions(EType type, int &dx, int &dy, int &x, int &y, int &h, int &w, bool Right, int &leftToRightOffset) const override; void mimicCres(); Point selectionOffset(bool Left) const override; std::string selectionSubtitle(bool Left) const override; void garrisonChanged() override; void artifactsChanged(bool left) override; void calcTotalExp(); void setExpToLevel(); void updateRight(std::shared_ptr<CTradeableItem> toUpdate); void artifactPicked(); int firstFreeSlot(); void moveFromSlotToAltar(ArtifactPosition slotID, std::shared_ptr<CTradeableItem>, const CArtifactInstance * art); };