From dd7d190a58544c4f0db55bf20ecd4e32c80e04a0 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 30 Oct 2024 13:20:21 +0000 Subject: [PATCH] Implemented optional descriptions for market map objects It is now possible to define description of an object with 'market' handler that will be shown on right-clicking the object. Similarly, added description to right-click popup to Hill Fort. --- .../CommonConstructors.cpp | 11 +++++++++ .../CommonConstructors.h | 2 ++ lib/mapObjects/CGMarket.cpp | 24 +++++++++++++++++-- lib/mapObjects/CGMarket.h | 7 ++++++ lib/mapObjects/MiscObjects.cpp | 16 +++++++++++++ lib/mapObjects/MiscObjects.h | 3 +++ 6 files changed, 61 insertions(+), 2 deletions(-) diff --git a/lib/mapObjectConstructors/CommonConstructors.cpp b/lib/mapObjectConstructors/CommonConstructors.cpp index b8194937c..ef2969b62 100644 --- a/lib/mapObjectConstructors/CommonConstructors.cpp +++ b/lib/mapObjectConstructors/CommonConstructors.cpp @@ -205,6 +205,12 @@ AnimationPath BoatInstanceConstructor::getBoatAnimationName() const void MarketInstanceConstructor::initTypeData(const JsonNode & input) { + if (!input["description"].isNull()) + { + description = input["description"].String(); + VLC->generaltexth->registerString(input.getModScope(), TextIdentifier(getBaseTextID(), "description"), description); + } + for(auto & element : input["modes"].Vector()) { if(MappedKeys::MARKET_NAMES_TO_TYPES.count(element.String())) @@ -218,6 +224,11 @@ void MarketInstanceConstructor::initTypeData(const JsonNode & input) speech = input["speech"].String(); } +bool MarketInstanceConstructor::hasDescription() const +{ + return !description.empty(); +} + CGMarket * MarketInstanceConstructor::createObject(IGameCallback * cb) const { if(marketModes.size() == 1) diff --git a/lib/mapObjectConstructors/CommonConstructors.h b/lib/mapObjectConstructors/CommonConstructors.h index 2089acdf7..1a048df20 100644 --- a/lib/mapObjectConstructors/CommonConstructors.h +++ b/lib/mapObjectConstructors/CommonConstructors.h @@ -118,6 +118,7 @@ protected: JsonNode predefinedOffer; int marketEfficiency; + std::string description; std::string title; std::string speech; @@ -127,6 +128,7 @@ public: void randomizeObject(CGMarket * object, vstd::RNG & rng) const override; const std::set & availableModes() const; + bool hasDescription() const; }; diff --git a/lib/mapObjects/CGMarket.cpp b/lib/mapObjects/CGMarket.cpp index b2a44455c..772aa3930 100644 --- a/lib/mapObjects/CGMarket.cpp +++ b/lib/mapObjects/CGMarket.cpp @@ -39,6 +39,22 @@ void CGMarket::onHeroVisit(const CGHeroInstance * h) const cb->showObjectWindow(this, EOpenWindowMode::MARKET_WINDOW, h, true); } +std::string CGMarket::getPopupText(PlayerColor player) const +{ + if (!getMarketHandler()->hasDescription()) + return getHoverText(player); + + MetaString message = MetaString::createFromRawString("{%s}\r\n\r\n%s"); + message.replaceName(ID); + message.replaceTextID(TextIdentifier(getObjectHandler()->getBaseTextID(), "description").get()); + return message.toString(); +} + +std::string CGMarket::getPopupText(const CGHeroInstance * hero) const +{ + return getPopupText(hero->getOwner()); +} + int CGMarket::getMarketEfficiency() const { return marketEfficiency; @@ -49,12 +65,16 @@ int CGMarket::availableUnits(EMarketMode mode, int marketItemSerial) const return -1; } -std::set CGMarket::availableModes() const +std::shared_ptr CGMarket::getMarketHandler() const { const auto & baseHandler = getObjectHandler(); const auto & ourHandler = std::dynamic_pointer_cast(baseHandler); + return ourHandler; +} - return ourHandler->availableModes(); +std::set CGMarket::availableModes() const +{ + return getMarketHandler()->availableModes(); } CGMarket::CGMarket(IGameCallback *cb): diff --git a/lib/mapObjects/CGMarket.h b/lib/mapObjects/CGMarket.h index e1bc5b7df..b3423125b 100644 --- a/lib/mapObjects/CGMarket.h +++ b/lib/mapObjects/CGMarket.h @@ -15,8 +15,12 @@ VCMI_LIB_NAMESPACE_BEGIN +class MarketInstanceConstructor; + class DLL_LINKAGE CGMarket : public CGObjectInstance, public IMarket { + std::shared_ptr getMarketHandler() const; + public: int marketEfficiency; @@ -25,6 +29,9 @@ public: void onHeroVisit(const CGHeroInstance * h) const override; //open trading window void initObj(vstd::RNG & rand) override;//set skills for trade + std::string getPopupText(PlayerColor player) const override; + std::string getPopupText(const CGHeroInstance * hero) const override; + ///IMarket ObjectInstanceID getObjInstanceID() const override; int getMarketEfficiency() const override; diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index c959292a9..720615921 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -1333,6 +1333,22 @@ void HillFort::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack) } } +std::string HillFort::getPopupText(PlayerColor player) const +{ + MetaString message = MetaString::createFromRawString("{%s}\r\n\r\n%s"); + + message.replaceName(ID); + message.replaceTextID(getDescriptionToolTip()); + + return message.toString(); +} + +std::string HillFort::getPopupText(const CGHeroInstance * hero) const +{ + return getPopupText(hero->getOwner()); +} + + std::string HillFort::getDescriptionToolTip() const { return TextIdentifier(getObjectHandler()->getBaseTextID(), "description").get(); diff --git a/lib/mapObjects/MiscObjects.h b/lib/mapObjects/MiscObjects.h index d6c40b3ca..aa5d2ac46 100644 --- a/lib/mapObjects/MiscObjects.h +++ b/lib/mapObjects/MiscObjects.h @@ -437,6 +437,9 @@ protected: public: using CGObjectInstance::CGObjectInstance; + std::string getPopupText(PlayerColor player) const override; + std::string getPopupText(const CGHeroInstance * hero) const override; + std::string getDescriptionToolTip() const; std::string getUnavailableUpgradeMessage() const;