From ee59bc4e71d94fd02bab68588fbc2111aba62607 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 25 Oct 2024 18:36:02 +0000 Subject: [PATCH] Add bonus description generation for map objects --- client/widgets/MiscWidgets.cpp | 6 +++--- config/objects/lighthouse.json | 3 +-- lib/CSkillHandler.cpp | 2 +- lib/battle/BattleInfo.cpp | 4 ++-- lib/bonuses/Bonus.cpp | 9 ++++++++- lib/bonuses/Bonus.h | 3 ++- lib/bonuses/CBonusSystemNode.cpp | 6 +++--- lib/mapObjects/CGTownInstance.cpp | 4 ++-- 8 files changed, 22 insertions(+), 15 deletions(-) diff --git a/client/widgets/MiscWidgets.cpp b/client/widgets/MiscWidgets.cpp index 14cc7b14d..bff6a0407 100644 --- a/client/widgets/MiscWidgets.cpp +++ b/client/widgets/MiscWidgets.cpp @@ -581,13 +581,13 @@ void MoraleLuckBox::set(const AFactionMember * node) else if(morale && node && node->getBonusBearer()->hasBonusOfType(BonusType::NO_MORALE)) { auto noMorale = node->getBonusBearer()->getBonus(Selector::type()(BonusType::NO_MORALE)); - text += "\n" + noMorale->Description(); + text += "\n" + noMorale->Description(LOCPLINT->cb.get()); component.value = 0; } else if (!morale && node && node->getBonusBearer()->hasBonusOfType(BonusType::NO_LUCK)) { auto noLuck = node->getBonusBearer()->getBonus(Selector::type()(BonusType::NO_LUCK)); - text += "\n" + noLuck->Description(); + text += "\n" + noLuck->Description(LOCPLINT->cb.get()); component.value = 0; } else @@ -596,7 +596,7 @@ void MoraleLuckBox::set(const AFactionMember * node) for(auto & bonus : * modifierList) { if(bonus->val) { - const std::string& description = bonus->Description(); + const std::string& description = bonus->Description(LOCPLINT->cb.get()); //arraytxt already contains \n if (description.size() && description[0] != '\n') addInfo += '\n'; diff --git a/config/objects/lighthouse.json b/config/objects/lighthouse.json index cc20d80ef..cecabfc0b 100644 --- a/config/objects/lighthouse.json +++ b/config/objects/lighthouse.json @@ -13,10 +13,9 @@ "index" : 0, "aiValue" : 500, "rmg" : { - } + }, "message" : "@core.advevent.69", - "bonuses" : { "seaMovement" : { "type" : "MOVEMENT", diff --git a/lib/CSkillHandler.cpp b/lib/CSkillHandler.cpp index 87cad05bc..7c9e5fec6 100644 --- a/lib/CSkillHandler.cpp +++ b/lib/CSkillHandler.cpp @@ -122,7 +122,7 @@ CSkill::LevelInfo & CSkill::at(int level) DLL_LINKAGE std::ostream & operator<<(std::ostream & out, const CSkill::LevelInfo & info) { for(int i=0; i < info.effects.size(); i++) - out << (i ? "," : "") << info.effects[i]->Description(); + out << (i ? "," : "") << info.effects[i]->Description(nullptr); return out << "])"; } diff --git a/lib/battle/BattleInfo.cpp b/lib/battle/BattleInfo.cpp index 8a8eb633c..132358391 100644 --- a/lib/battle/BattleInfo.cpp +++ b/lib/battle/BattleInfo.cpp @@ -885,12 +885,12 @@ void BattleInfo::addOrUpdateUnitBonus(CStack * sta, const Bonus & value, bool fo if(forceAdd || !sta->hasBonus(Selector::source(BonusSource::SPELL_EFFECT, value.sid).And(Selector::typeSubtypeValueType(value.type, value.subtype, value.valType)))) { //no such effect or cumulative - add new - logBonus->trace("%s receives a new bonus: %s", sta->nodeName(), value.Description()); + logBonus->trace("%s receives a new bonus: %s", sta->nodeName(), value.Description(nullptr)); sta->addNewBonus(std::make_shared(value)); } else { - logBonus->trace("%s updated bonus: %s", sta->nodeName(), value.Description()); + logBonus->trace("%s updated bonus: %s", sta->nodeName(), value.Description(nullptr)); for(const auto & stackBonus : sta->getExportedBonusList()) //TODO: optimize { diff --git a/lib/bonuses/Bonus.cpp b/lib/bonuses/Bonus.cpp index a11e794f4..95d665d76 100644 --- a/lib/bonuses/Bonus.cpp +++ b/lib/bonuses/Bonus.cpp @@ -18,8 +18,11 @@ #include "../CCreatureHandler.h" #include "../CCreatureSet.h" #include "../CSkillHandler.h" +#include "../IGameCallback.h" #include "../TerrainHandler.h" #include "../VCMI_Lib.h" +#include "../mapObjects/CGObjectInstance.h" +#include "../mapObjectConstructors/CObjectClassesHandler.h" #include "../battle/BattleInfo.h" #include "../constants/StringConstants.h" #include "../entities/hero/CHero.h" @@ -87,7 +90,7 @@ JsonNode CAddInfo::toJsonNode() const return node; } } -std::string Bonus::Description(std::optional customValue) const +std::string Bonus::Description(const IGameInfoCallback * cb, std::optional customValue) const { MetaString descriptionHelper = description; auto valueToShow = customValue.value_or(val); @@ -112,6 +115,10 @@ std::string Bonus::Description(std::optional customValue) const case BonusSource::HERO_SPECIAL: descriptionHelper.appendTextID(sid.as().toEntity(VLC)->getNameTextID()); break; + case BonusSource::OBJECT_INSTANCE: + const auto * object = cb->getObj(sid.as()); + if (object) + descriptionHelper.appendTextID(VLC->objtypeh->getObjectName(object->ID, object->subID)); } } diff --git a/lib/bonuses/Bonus.h b/lib/bonuses/Bonus.h index 63b4d6b1d..caefbc46a 100644 --- a/lib/bonuses/Bonus.h +++ b/lib/bonuses/Bonus.h @@ -26,6 +26,7 @@ class IPropagator; class IUpdater; class BonusList; class CSelector; +class IGameInfoCallback; using BonusSubtypeID = VariantIdentifier; using BonusSourceID = VariantIdentifier; @@ -177,7 +178,7 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this, public Se val += Val; } - std::string Description(std::optional customValue = {}) const; + std::string Description(const IGameInfoCallback * cb, std::optional customValue = {}) const; JsonNode toJsonNode() const; std::shared_ptr addLimiter(const TLimiterPtr & Limiter); //returns this for convenient chain-calls diff --git a/lib/bonuses/CBonusSystemNode.cpp b/lib/bonuses/CBonusSystemNode.cpp index 7b944eefb..b5a2d582d 100644 --- a/lib/bonuses/CBonusSystemNode.cpp +++ b/lib/bonuses/CBonusSystemNode.cpp @@ -378,7 +378,7 @@ void CBonusSystemNode::propagateBonus(const std::shared_ptr & b, const CB ? source.getUpdatedBonus(b, b->propagationUpdater) : b; bonuses.push_back(propagated); - logBonus->trace("#$# %s #propagated to# %s", propagated->Description(), nodeName()); + logBonus->trace("#$# %s #propagated to# %s", propagated->Description(nullptr), nodeName()); } TNodes lchildren; @@ -392,9 +392,9 @@ void CBonusSystemNode::unpropagateBonus(const std::shared_ptr & b) if(b->propagator->shouldBeAttached(this)) { if (bonuses -= b) - logBonus->trace("#$# %s #is no longer propagated to# %s", b->Description(), nodeName()); + logBonus->trace("#$# %s #is no longer propagated to# %s", b->Description(nullptr), nodeName()); else - logBonus->warn("Attempt to remove #$# %s, which is not propagated to %s", b->Description(), nodeName()); + logBonus->warn("Attempt to remove #$# %s, which is not propagated to %s", b->Description(nullptr), nodeName()); bonuses.remove_if([b](const auto & bonus) { diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index 50d9b8b35..5b1a115ce 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -166,7 +166,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const const auto growth = b->val * (base + castleBonus) / 100; if (growth) { - ret.entries.emplace_back(growth, b->Description(growth)); + ret.entries.emplace_back(growth, b->Description(cb, growth)); } } @@ -174,7 +174,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const // Note: bonus uses 1-based levels (Pikeman is level 1), town list uses 0-based (Pikeman in 0-th creatures entry) TConstBonusListPtr bonuses = getBonuses(Selector::typeSubtype(BonusType::CREATURE_GROWTH, BonusCustomSubtype::creatureLevel(level+1))); for(const auto & b : *bonuses) - ret.entries.emplace_back(b->val, b->Description()); + ret.entries.emplace_back(b->val, b->Description(cb)); int dwellingBonus = 0; if(const PlayerState *p = cb->getPlayerState(tempOwner, false))