Преглед на файлове

Add bonus description generation for map objects

Ivan Savenko преди 1 година
родител
ревизия
ee59bc4e71

+ 3 - 3
client/widgets/MiscWidgets.cpp

@@ -581,13 +581,13 @@ void MoraleLuckBox::set(const AFactionMember * node)
 	else if(morale && node && node->getBonusBearer()->hasBonusOfType(BonusType::NO_MORALE))
 	else if(morale && node && node->getBonusBearer()->hasBonusOfType(BonusType::NO_MORALE))
 	{
 	{
 		auto noMorale = node->getBonusBearer()->getBonus(Selector::type()(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;
 		component.value = 0;
 	}
 	}
 	else if (!morale && node && node->getBonusBearer()->hasBonusOfType(BonusType::NO_LUCK))
 	else if (!morale && node && node->getBonusBearer()->hasBonusOfType(BonusType::NO_LUCK))
 	{
 	{
 		auto noLuck = node->getBonusBearer()->getBonus(Selector::type()(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;
 		component.value = 0;
 	}
 	}
 	else
 	else
@@ -596,7 +596,7 @@ void MoraleLuckBox::set(const AFactionMember * node)
 		for(auto & bonus : * modifierList)
 		for(auto & bonus : * modifierList)
 		{
 		{
 			if(bonus->val) {
 			if(bonus->val) {
-				const std::string& description = bonus->Description();
+				const std::string& description = bonus->Description(LOCPLINT->cb.get());
 				//arraytxt already contains \n
 				//arraytxt already contains \n
 				if (description.size() && description[0] != '\n')
 				if (description.size() && description[0] != '\n')
 					addInfo += '\n';
 					addInfo += '\n';

+ 1 - 2
config/objects/lighthouse.json

@@ -13,10 +13,9 @@
 				"index" : 0,
 				"index" : 0,
 				"aiValue" : 500,
 				"aiValue" : 500,
 				"rmg" : {
 				"rmg" : {
-				}
+				},
 				
 				
 				"message" : "@core.advevent.69",
 				"message" : "@core.advevent.69",
-				
 				"bonuses" : {
 				"bonuses" : {
 					"seaMovement" : {
 					"seaMovement" : {
 						"type" : "MOVEMENT",
 						"type" : "MOVEMENT",

+ 1 - 1
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)
 DLL_LINKAGE std::ostream & operator<<(std::ostream & out, const CSkill::LevelInfo & info)
 {
 {
 	for(int i=0; i < info.effects.size(); i++)
 	for(int i=0; i < info.effects.size(); i++)
-		out << (i ? "," : "") << info.effects[i]->Description();
+		out << (i ? "," : "") << info.effects[i]->Description(nullptr);
 	return out << "])";
 	return out << "])";
 }
 }
 
 

+ 2 - 2
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))))
 	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
 		//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<Bonus>(value));
 		sta->addNewBonus(std::make_shared<Bonus>(value));
 	}
 	}
 	else
 	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
 		for(const auto & stackBonus : sta->getExportedBonusList()) //TODO: optimize
 		{
 		{

+ 8 - 1
lib/bonuses/Bonus.cpp

@@ -18,8 +18,11 @@
 #include "../CCreatureHandler.h"
 #include "../CCreatureHandler.h"
 #include "../CCreatureSet.h"
 #include "../CCreatureSet.h"
 #include "../CSkillHandler.h"
 #include "../CSkillHandler.h"
+#include "../IGameCallback.h"
 #include "../TerrainHandler.h"
 #include "../TerrainHandler.h"
 #include "../VCMI_Lib.h"
 #include "../VCMI_Lib.h"
+#include "../mapObjects/CGObjectInstance.h"
+#include "../mapObjectConstructors/CObjectClassesHandler.h"
 #include "../battle/BattleInfo.h"
 #include "../battle/BattleInfo.h"
 #include "../constants/StringConstants.h"
 #include "../constants/StringConstants.h"
 #include "../entities/hero/CHero.h"
 #include "../entities/hero/CHero.h"
@@ -87,7 +90,7 @@ JsonNode CAddInfo::toJsonNode() const
 		return node;
 		return node;
 	}
 	}
 }
 }
-std::string Bonus::Description(std::optional<si32> customValue) const
+std::string Bonus::Description(const IGameInfoCallback * cb, std::optional<si32> customValue) const
 {
 {
 	MetaString descriptionHelper = description;
 	MetaString descriptionHelper = description;
 	auto valueToShow = customValue.value_or(val);
 	auto valueToShow = customValue.value_or(val);
@@ -112,6 +115,10 @@ std::string Bonus::Description(std::optional<si32> customValue) const
 			case BonusSource::HERO_SPECIAL:
 			case BonusSource::HERO_SPECIAL:
 				descriptionHelper.appendTextID(sid.as<HeroTypeID>().toEntity(VLC)->getNameTextID());
 				descriptionHelper.appendTextID(sid.as<HeroTypeID>().toEntity(VLC)->getNameTextID());
 				break;
 				break;
+			case BonusSource::OBJECT_INSTANCE:
+				const auto * object = cb->getObj(sid.as<ObjectInstanceID>());
+				if (object)
+					descriptionHelper.appendTextID(VLC->objtypeh->getObjectName(object->ID, object->subID));
 		}
 		}
 	}
 	}
 
 

+ 2 - 1
lib/bonuses/Bonus.h

@@ -26,6 +26,7 @@ class IPropagator;
 class IUpdater;
 class IUpdater;
 class BonusList;
 class BonusList;
 class CSelector;
 class CSelector;
+class IGameInfoCallback;
 
 
 using BonusSubtypeID = VariantIdentifier<BonusCustomSubtype, SpellID, CreatureID, PrimarySkill, TerrainId, GameResID, SpellSchool>;
 using BonusSubtypeID = VariantIdentifier<BonusCustomSubtype, SpellID, CreatureID, PrimarySkill, TerrainId, GameResID, SpellSchool>;
 using BonusSourceID = VariantIdentifier<BonusCustomSource, SpellID, CreatureID, ArtifactID, CampaignScenarioID, SecondarySkill, HeroTypeID, Obj, ObjectInstanceID, BuildingTypeUniqueID, BattleField>;
 using BonusSourceID = VariantIdentifier<BonusCustomSource, SpellID, CreatureID, ArtifactID, CampaignScenarioID, SecondarySkill, HeroTypeID, Obj, ObjectInstanceID, BuildingTypeUniqueID, BattleField>;
@@ -177,7 +178,7 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>, public Se
 		val += Val;
 		val += Val;
 	}
 	}
 
 
-	std::string Description(std::optional<si32> customValue = {}) const;
+	std::string Description(const IGameInfoCallback * cb, std::optional<si32> customValue = {}) const;
 	JsonNode toJsonNode() const;
 	JsonNode toJsonNode() const;
 
 
 	std::shared_ptr<Bonus> addLimiter(const TLimiterPtr & Limiter); //returns this for convenient chain-calls
 	std::shared_ptr<Bonus> addLimiter(const TLimiterPtr & Limiter); //returns this for convenient chain-calls

+ 3 - 3
lib/bonuses/CBonusSystemNode.cpp

@@ -378,7 +378,7 @@ void CBonusSystemNode::propagateBonus(const std::shared_ptr<Bonus> & b, const CB
 			? source.getUpdatedBonus(b, b->propagationUpdater)
 			? source.getUpdatedBonus(b, b->propagationUpdater)
 			: b;
 			: b;
 		bonuses.push_back(propagated);
 		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;
 	TNodes lchildren;
@@ -392,9 +392,9 @@ void CBonusSystemNode::unpropagateBonus(const std::shared_ptr<Bonus> & b)
 	if(b->propagator->shouldBeAttached(this))
 	if(b->propagator->shouldBeAttached(this))
 	{
 	{
 		if (bonuses -= b)
 		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
 		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)
 		bonuses.remove_if([b](const auto & bonus)
 		{
 		{

+ 2 - 2
lib/mapObjects/CGTownInstance.cpp

@@ -166,7 +166,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
 		const auto growth = b->val * (base + castleBonus) / 100;
 		const auto growth = b->val * (base + castleBonus) / 100;
 		if (growth)
 		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)
 	// 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)));
 	TConstBonusListPtr bonuses = getBonuses(Selector::typeSubtype(BonusType::CREATURE_GROWTH, BonusCustomSubtype::creatureLevel(level+1)));
 	for(const auto & b : *bonuses)
 	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;
 	int dwellingBonus = 0;
 	if(const PlayerState *p = cb->getPlayerState(tempOwner, false))
 	if(const PlayerState *p = cb->getPlayerState(tempOwner, false))