Browse Source

Merge pull request #6010 from Opuszek/fix_abilities_propagation

Fix abilities propagation
Ivan Savenko 2 months ago
parent
commit
66d1015e10

+ 5 - 0
Mods/vcmi/Content/config/english.json

@@ -952,6 +952,11 @@
 	"creatures.core.marksman.bonus.extraAttack" : "{Shoots twice}\nThis unit can shoot twice",
 	"creatures.core.azureDragon.bonus.fearful" : "{Fear}\nEnemy units have a 10% chance of freezing in fear",
 	"creatures.core.azureDragon.bonus.fearless" : "{Fearless}\nImmune to Fear ability",
+	"creatures.core.halfling.bonus.lucky" : "{Lucky}\nHalfling's luck cannot be decreased below +1",
+	"creatures.core.nomad.bonus.sandWalker" : "{Sand walker}\nHero ignores terrain penalty on sand",
+	"creatures.core.rogue.bonus.visionsMonsters" : "{Visions Monsters}\nHero can see detailed informations about neutral monsters",
+	"creatures.core.rogue.bonus.visionsHeroes" : "{Visions Heroes}\nHero can see detailed informations about enemy heroes",
+	"creatures.core.rogue.bonus.visionsTowns" : "{Visions Towns}\nHero can see detailed informations about enemy towns",
 
 	"core.bonus.ADDITIONAL_ATTACK.description" : "{Additional attacks}\nUnit can attack an additional {$val} times", // TODO: alternative descriptions for melee/ranged effect range
 	"core.bonus.ADDITIONAL_RETALIATION.description" : "{Additional retaliations}\nUnit can retaliate ${val} extra times",

+ 4 - 4
client/windows/CCreatureWindow.cpp

@@ -868,10 +868,10 @@ void CStackWindow::initBonusesList()
 			return  info->stackNode->bonusToString(v1) < info->stackNode->bonusToString(v2);
 	};
 
-	// these bonuses require special handling. For example they come with own descriptions, for use in morale/luck description
-	// also, this information is already available in creature window
-	receivedBonuses.remove_if(Selector::type()(BonusType::MORALE));
-	receivedBonuses.remove_if(Selector::type()(BonusType::LUCK));
+	receivedBonuses.remove_if([](const Bonus* b)
+	{
+		return !LIBRARY->bth->shouldPropagateDescription(b->type);
+	});
 
 	std::vector<BonusList> groupedBonuses;
 	while (!receivedBonuses.empty())

+ 188 - 10
config/bonuses.json

@@ -1,4 +1,14 @@
 {
+	"ARTIFACT_GROWING":
+	{
+		"blockDescriptionPropagation": true
+	},
+	
+	"ARTIFACT_CHARGE":
+	{
+		"blockDescriptionPropagation": true
+	},
+	
 	"ADDITIONAL_ATTACK":
 	{
 	},
@@ -10,6 +20,31 @@
 	"ATTACKS_ALL_ADJACENT":
 	{
 	},
+	
+	"BASE_TILE_MOVEMENT_COST":
+	{
+		"blockDescriptionPropagation": true
+	},
+
+	"BATTLE_NO_FLEEING":
+	{
+		"blockDescriptionPropagation": true
+	},
+
+	"BEFORE_BATTLE_REPOSITION":
+	{
+		"blockDescriptionPropagation": true
+	},
+
+	"BEFORE_BATTLE_REPOSITION_BLOCK":
+	{
+		"blockDescriptionPropagation": true
+	},
+
+	"BIND_EFFECT":
+	{
+		"blockDescriptionPropagation": true
+	},
 
 	"BLOCKS_RANGED_RETALIATION":
 	{
@@ -39,11 +74,32 @@
 	"CHARGE_IMMUNITY":
 	{
 	},
+	
+	"COMBAT_MANA_BONUS":
+	{
+		"blockDescriptionPropagation": true
+	},
+
+	"CREATURE_GROWTH":
+	{
+		"blockDescriptionPropagation": true
+	},
+
+	"CREATURE_GROWTH_PERCENT":
+	{
+		"blockDescriptionPropagation": true
+	},
 
 	"DARKNESS":
 	{
 		"hidden": true
 	},
+	
+	"DISGUISED":
+	{
+		"hidden": true,
+		"blockDescriptionPropagation": true
+	},
 
 	"DEATH_STARE":
 	{
@@ -65,11 +121,6 @@
 	{
 	},
 
-	"DISGUISED":
-	{
-		"hidden": true
-	},
-
 	"ENCHANTER":
 	{
 	},
@@ -112,6 +163,17 @@
 			"bonusSubtype.movementTeleporting" : null,
 		}
 	},
+	
+	"FLYING_MOVEMENT":
+	{
+		"blockDescriptionPropagation": true
+	},
+
+	"FREE_SHIP_BOARDING":
+	{
+		"blockDescriptionPropagation": true
+	},
+	
 
 	"FREE_SHOOTING":
 	{
@@ -119,10 +181,12 @@
 	
 	"FULL_MAP_DARKNESS":
 	{
+		"blockDescriptionPropagation": true
 	},
-	
+
 	"FULL_MAP_SCOUTING":
 	{
+		"blockDescriptionPropagation": true
 	},
 
 	"GARGOYLE":
@@ -137,6 +201,11 @@
 			"bonusSubtype.damageTypeMelee" : null,
 		}
 	},
+	
+	"GENERATE_RESOURCE":
+	{
+		"blockDescriptionPropagation": true
+	},
 
 	"HATE":
 	{
@@ -150,6 +219,21 @@
 	{
 	},
 	
+	"HERO_EXPERIENCE_GAIN_PERCENT":
+	{
+		"blockDescriptionPropagation": true
+	},
+
+	"HERO_SPELL_CASTS_PER_COMBAT_TURN":
+	{
+		"blockDescriptionPropagation": true
+	},
+	
+	"IMPROVED_NECROMANCY":
+	{
+		"blockDescriptionPropagation": true
+	},
+	
 	"JOUSTING":
 	{
 	},
@@ -164,12 +248,19 @@
 
 	"LEARN_BATTLE_SPELL_CHANCE":
 	{
-		"hidden": true
+		"hidden": true,
+		"blockDescriptionPropagation": true
 	},
 
 	"LEARN_BATTLE_SPELL_LEVEL_LIMIT":
 	{
-		"hidden": true
+		"hidden": true,
+		"blockDescriptionPropagation": true
+	},
+	
+	"LEARN_MEETING_SPELL_LIMIT":
+	{
+		"blockDescriptionPropagation": true
 	},
 
 	"LEVEL_SPELL_IMMUNITY":
@@ -188,6 +279,11 @@
 	{
 		"creatureNature" : true
 	},
+	
+	"LUCK":
+	{
+		"blockDescriptionPropagation": true
+	},
 
 	"MANA_CHANNELING":
 	{
@@ -205,6 +301,26 @@
 	{
 	},
 	
+	"MAGIC_SCHOOL_SKILL":
+	{
+		"blockDescriptionPropagation": true
+	},
+
+	"MANA_PERCENTAGE_REGENERATION":
+	{
+		"blockDescriptionPropagation": true
+	},
+
+	"MANA_PER_KNOWLEDGE_PERCENTAGE":
+	{
+		"blockDescriptionPropagation": true
+	},
+
+	"MAX_LEARNABLE_SPELL_LEVEL":
+	{
+		"blockDescriptionPropagation": true
+	},
+	
 	"MECHANICAL":
 	{
 		"creatureNature" : true
@@ -214,6 +330,16 @@
 	{
 	},
 	
+	"MORALE":
+	{
+		"blockDescriptionPropagation": true
+	},
+	
+	"MOVEMENT":
+	{
+		"blockDescriptionPropagation": true
+	},
+	
 	"NEGATIVE_EFFECTS_IMMUNITY" :
 	{
 	},
@@ -241,7 +367,8 @@
 
 	"NO_TERRAIN_PENALTY":
 	{
-		"hidden": true
+		"hidden": true,
+		"blockDescriptionPropagation": true
 	},
 
 	"NON_LIVING":
@@ -270,9 +397,24 @@
 	{
 	},
 	
+	"PRIMARY_SKILL":
+	{
+		"blockDescriptionPropagation": true
+	},
+	
 	"REBIRTH":
 	{
 	},
+	
+	"RESOURCES_CONSTANT_BOOST":
+	{
+		"blockDescriptionPropagation": true
+	},
+
+	"RESOURCES_TOWN_MULTIPLYING_BOOST":
+	{
+		"blockDescriptionPropagation": true
+	},
 
 	"RETURN_AFTER_STRIKE":
 	{
@@ -282,6 +424,11 @@
 	{
 	},
 	
+	"ROUGH_TERRAIN_DISCOUNT":
+	{
+		"blockDescriptionPropagation": true
+	},
+
 	"SIEGE_WEAPON":
 	{
 		"creatureNature" : true
@@ -299,6 +446,11 @@
 	{
 	},
 	
+	"SIGHT_RADIUS":
+	{
+		"blockDescriptionPropagation": true
+	},
+	
 	"SOUL_STEAL":
 	{
 	},
@@ -350,6 +502,11 @@
 	"SUMMON_GUARDIANS":
 	{
 	},
+	
+	"SURRENDER_DISCOUNT":
+	{
+		"blockDescriptionPropagation": true
+	},
 
 	"TWO_HEX_ATTACK_BREATH":
 	{
@@ -370,25 +527,46 @@
 	"TRANSMUTATION_IMMUNITY":
 	{
 	},
+	
+	"THIEVES_GUILD_ACCESS":
+	{
+		"blockDescriptionPropagation": true
+	},
 
 	"UNDEAD":
 	{
 		"creatureNature" : true,
 	},
 	
+	"UNDEAD_RAISE_PERCENTAGE":
+	{
+		"blockDescriptionPropagation": true
+	},
+	
 	"UNLIMITED_RETALIATIONS":
 	{
 	},
 
 	"VISIONS":
 	{
-		"hidden": true
+		"hidden": true,
+		"blockDescriptionPropagation": true
 	},
 	
 	"VULNERABLE_FROM_BACK":
 	{
 	},
 	
+	"WANDERING_CREATURES_JOIN_BONUS":
+	{
+		"blockDescriptionPropagation": true
+	},
+	
+	"WATER_WALKING":
+	{
+		"blockDescriptionPropagation": true
+	},
+	
 	"WIDE_BREATH":
 	{
 	},

+ 10 - 5
config/creatures/neutral.json

@@ -512,7 +512,8 @@
 			{
 				"type" : "LUCK",
 				"val" : 1,
-				"valueType" : "INDEPENDENT_MAX"
+				"valueType" : "INDEPENDENT_MAX",
+				"description" : "PLACEHOLDER"
 			}
 		 },
 		"graphics" :
@@ -621,7 +622,8 @@
 			{
 				"type" : "NO_TERRAIN_PENALTY",
 				"subtype" : "terrain.sand",
-				"propagator" : "HERO"
+				"propagator" : "HERO",
+				"description" : "PLACEHOLDER"
 			}
 		},
 		"graphics" :
@@ -652,7 +654,8 @@
 				"subtype" : "visionsMonsters",
 				"val" : 3,
 				"valueType" : "INDEPENDENT_MAX",
-				"propagator" : "HERO"
+				"propagator" : "HERO",
+				"description" : "PLACEHOLDER"
 			},
 			"visionsHeroes" :
 			{
@@ -660,7 +663,8 @@
 				"subtype" : "visionsHeroes",
 				"val" : 3,
 				"valueType" : "INDEPENDENT_MAX",
-				"propagator" : "HERO"
+				"propagator" : "HERO",
+				"description" : "PLACEHOLDER"
 			},
 			"visionsTowns" :
 			{
@@ -668,7 +672,8 @@
 				"subtype" : "visionsTowns",
 				"val" : 3,
 				"valueType" : "INDEPENDENT_MAX",
-				"propagator" : "HERO"
+				"propagator" : "HERO",
+				"description" : "PLACEHOLDER"
 			}
 		},
 		"graphics" :

+ 5 - 0
config/schemas/bonus.json

@@ -15,6 +15,11 @@
 			"type" : "boolean",
 			"description" : "If set to true, this bonus will be considered 'creature nature' bonus, and such creature won't be automatically granted LIVING bonus"
 		},
+		
+		"blockDescriptionPropagation" : {
+			"type" : "boolean",
+			"description" : "If set to true, this ability description will not be displayed if a creature receives it by propagation"
+		},
 
 		"description" : {
 			"type" : "string"

+ 7 - 0
lib/CBonusTypeHandler.cpp

@@ -142,6 +142,7 @@ void CBonusTypeHandler::loadItem(const JsonNode & source, CBonusType & dest, con
 	dest.identifier = name;
 	dest.hidden = source["hidden"].Bool(); //Null -> false
 	dest.creatureNature = source["creatureNature"].Bool(); //Null -> false
+	dest.blockDescriptionPropagation = source["blockDescriptionPropagation"].Bool(); //Null -> false
 
 	if (!dest.hidden)
 		LIBRARY->generaltexth->registerString( "vcmi", dest.getDescriptionTextID(), source["description"]);
@@ -196,6 +197,12 @@ bool CBonusTypeHandler::isCreatureNatureBonus(BonusType bonus) const
 	return bonusTypes.at(static_cast<int>(bonus))->creatureNature;
 }
 
+bool CBonusTypeHandler::shouldPropagateDescription(BonusType bonus) const
+{
+	return !bonusTypes.at(static_cast<int>(bonus))->blockDescriptionPropagation;
+}
+
+
 std::vector<BonusType> CBonusTypeHandler::getAllObjets() const
 {
 	std::vector<BonusType> ret;

+ 2 - 0
lib/CBonusTypeHandler.h

@@ -38,6 +38,7 @@ private:
 
 	bool creatureNature = false;
 	bool hidden = true;
+	bool blockDescriptionPropagation = false;
 };
 
 class DLL_LINKAGE CBonusTypeHandler : public IBonusTypeHandler
@@ -57,6 +58,7 @@ public:
 	const std::string & bonusToString(BonusType bonus) const;
 
 	bool isCreatureNatureBonus(BonusType bonus) const;
+	bool shouldPropagateDescription(BonusType bonus) const;
 
 	std::vector<BonusType> getAllObjets() const;
 private: