mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-25 22:42:04 +02:00
More generic support for bonus subtypes descriptions
This commit is contained in:
@@ -621,9 +621,8 @@
|
||||
|
||||
"mapObject.core.hillFort.object.description" : "Upgrades creatures. Levels 1 - 4 are less expensive than in associated town.",
|
||||
|
||||
"core.bonus.ADDITIONAL_ATTACK.description" : "{Additional attacks}\nUnit can attack an additional {$val} times",
|
||||
"core.bonus.ADDITIONAL_ATTACK.description" : "{Additional attacks}\nUnit can attack an additional {$val} times", // TODO: alternative descriptions for effect range
|
||||
"core.bonus.ADDITIONAL_RETALIATION.description" : "{Additional retaliations}\nUnit can retaliate ${val} extra times",
|
||||
"core.bonus.AIR_IMMUNITY.description" : "{Immune to Air Magic}\nImmune to all spells from the school of Air magic",
|
||||
"core.bonus.ATTACKS_ALL_ADJACENT.description" : "{Attack all around}\nAttacks all adjacent enemies in addition to the primary target",
|
||||
"core.bonus.BLOCKS_RANGED_RETALIATION.description" : "{No ranged retaliation}\nThe enemy cannot retaliate when shot by this unit",
|
||||
"core.bonus.BLOCKS_RETALIATION.description" : "{No retaliation}\nThe enemy cannot retaliate when attacked in melee by this unit",
|
||||
@@ -637,7 +636,6 @@
|
||||
"core.bonus.DISINTEGRATE.description" : "{Disintegrate}\nWhen this unit dies, it will leave no corpse behind",
|
||||
"core.bonus.DOUBLE_DAMAGE_CHANCE.description" : "{Death Blow}\nHas a ${val}% chance of dealing double base damage when attacking",
|
||||
"core.bonus.DRAGON_NATURE.description" : "{Dragon}\nThis creature is a Dragon",
|
||||
"core.bonus.EARTH_IMMUNITY.description" : "{Immune to Earth Magic}\nImmune to all spells from the school of Earth magic",
|
||||
"core.bonus.ENCHANTED.description" : "{Enchanted}\nPermanently affected by ${subtype.spell}",
|
||||
"core.bonus.ENCHANTER.description" : "{Enchanter}\nCan cast ${subtype.spell} every turn",
|
||||
"core.bonus.ENEMY_ATTACK_REDUCTION.description" : "{Ignore Attack (${val}%) }\nWhen being attacked, ${val}% of the attacker's attack is ignored",
|
||||
@@ -645,19 +643,25 @@
|
||||
"core.bonus.FEAR.description" : "{Fear}\nEnemy units have a 10% chance of freezing in fear",
|
||||
"core.bonus.FEARLESS.description" : "{Fearless}\nImmune to Fear ability",
|
||||
"core.bonus.FEROCITY.description" : "{Ferocity}\nAttacks ${val} additional times if killed anybody",
|
||||
"core.bonus.FIRE_IMMUNITY.description" : "{Immune to Fire Magic}\nImmune to all spells from the school of Fire magic",
|
||||
"core.bonus.FIRE_SHIELD.description" : "{Fire Shield (${val}%) }\nThe unit reflects ${val} of the melee damage received",
|
||||
"core.bonus.FIRST_STRIKE.description" : "{First Strike}\nThe unit retaliates before being attacked",
|
||||
"core.bonus.FIRST_STRIKE.description.bonusSubtype.damageTypeRanged" : "{First Strike}\nThe unit retaliates before being attacked by ranged attack",
|
||||
"core.bonus.FIRST_STRIKE.description.bonusSubtype.damageTypeMelee" : "{First Strike}\nThe unit retaliates before being attacked in melee",
|
||||
"core.bonus.FLYING.description" : "{Can Fly}\nThis unit can fly while moving and will ignore battlefield obstacles",
|
||||
"core.bonus.FLYING.description.bonusSubtype.movementTeleporting" : "{Teleportation}\nThis unit can teleport to any hex and ignore battlefield obstacles",
|
||||
"core.bonus.FREE_SHOOTING.description" : "{Shoot Close}\nRanged attacks of this unit can not be blocked by adjacent enemies",
|
||||
"core.bonus.GARGOYLE.description" : "{Gargoyle}\nThis unit cannot be raised from the dead or healed",
|
||||
"core.bonus.GENERAL_DAMAGE_REDUCTION.description" : "{Reduce Damage (${val}%) }\nReduces physical damage from ranged or melee attacks by ${val}%",
|
||||
"core.bonus.GENERAL_DAMAGE_REDUCTION.description.bonusSubtype.damageTypeRanged" : "{Reduce Damage (${val}%) }\nReduces physical damage from ranged attacks by ${val}%",
|
||||
"core.bonus.GENERAL_DAMAGE_REDUCTION.description.bonusSubtype.damageTypeMelee" : "{Reduce Damage (${val}%) }\nReduces physical damage from melee attacks by ${val}%",
|
||||
"core.bonus.HATE.description" : "{Hates ${subtype.creature}}\nDoes ${val}% more damage to ${subtype.creature}",
|
||||
"core.bonus.HEALER.description" : "{Healer}\nHeals allied units",
|
||||
"core.bonus.HP_REGENERATION.description" : "{Regeneration}\nHeals ${val} hit points every round",
|
||||
"core.bonus.INVINCIBLE.description" : "{Invincible}\nCannot be affected by anything",
|
||||
"core.bonus.JOUSTING.description" : "{Jousting bonus}\nMoving before an attack increases the damage by ${val} for each hex travelled",
|
||||
"core.bonus.KING.description" : "{King}\nReceives additional damage from units under Slayer effect of level ${val} or higher",
|
||||
"core.bonus.KING.description" : "{King}\nReceives additional damage from units under Slayer spell",
|
||||
"core.bonus.KING.description.2" : "{Advanced King}\nReceives additional damage from units under Advanced Slayer spell",
|
||||
"core.bonus.KING.description.3" : "{Expert King}\nReceives additional damage from units under Expert Slayer spell",
|
||||
"core.bonus.LEVEL_SPELL_IMMUNITY.description" : "{Immune to spells level 1-${val}}\nThis unit cannot be targeted by spells of levels 1-${val}",
|
||||
"core.bonus.LIFE_DRAIN.description" : "{Drain life}\nDrains ${val}% of damage dealt",
|
||||
"core.bonus.LIMITED_SHOOTING_RANGE.description" : "{Limited shooting range}\nUnable to use a ranged attack against units more than ${val} hexes away",
|
||||
@@ -667,7 +671,7 @@
|
||||
"core.bonus.MANA_DRAIN.description" : "{Drains enemy mana}\nDrains ${val} mana every turn from enemy hero",
|
||||
"core.bonus.MECHANICAL.description" : "{Mechanical}\nThis unit is immune to effects that only affect living and can be repaired",
|
||||
"core.bonus.MIND_IMMUNITY.description" : "{Mind Spell Immunity}\nThis unit cannot be targeted by spells that affect its mind",
|
||||
"core.bonus.NO_DISTANCE_PENALTY.description" : "{No distance penalty}\nRanged attacks deal full damage at any range",
|
||||
"core.bonus.NO_DISTANCE_PENALTY.description" : "{No distance penalty}\nRanged attacks deal full damage at any distance",
|
||||
"core.bonus.NO_MELEE_PENALTY.description" : "{No melee penalty}\nThis ranged unit deals full damage with melee attacks",
|
||||
"core.bonus.NO_MORALE.description" : "{Neutral Morale}\nCreature is immune to morale effects",
|
||||
"core.bonus.NO_WALL_PENALTY.description" : "{No wall penalty}\nRanged attacks deal full damage to units behind walls",
|
||||
@@ -685,30 +689,28 @@
|
||||
"core.bonus.SPELL_AFTER_ATTACK.description" : "{Cast After Attack}\nHas a ${val}% chance to cast ${subtype.spell} after it attacks",
|
||||
"core.bonus.SPELL_BEFORE_ATTACK.description" : "{Cast Before Attack}\nHas a ${val}% chance to cast ${subtype.spell} before it attacks",
|
||||
"core.bonus.SPELL_DAMAGE_REDUCTION.description" : "{Spell Resistance}\nDamage from all spells reduced by ${val}%",
|
||||
"core.bonus.SPELL_DAMAGE_REDUCTION.description.air" : "{Air Spells Resistance}\nDamage from Air Magic spells reduced by ${val}%",
|
||||
"core.bonus.SPELL_DAMAGE_REDUCTION.description.earth" : "{Earth Spells Resistance}\nDamage from Earth Magic spells reduced by ${val}%",
|
||||
"core.bonus.SPELL_DAMAGE_REDUCTION.description.fire" : "{Fire Spells Resistance}\nDamage from Fire Magic spells reduced by ${val}%",
|
||||
"core.bonus.SPELL_DAMAGE_REDUCTION.description.water" : "{Water Spells Resistance}\nDamage from Water Magic spells reduced by ${val}%",
|
||||
"core.bonus.SPELL_DAMAGE_REDUCTION.description.spellSchool.air" : "{Air Spells Resistance}\nDamage from Air Magic spells reduced by ${val}%",
|
||||
"core.bonus.SPELL_DAMAGE_REDUCTION.description.spellSchool.earth" : "{Earth Spells Resistance}\nDamage from Earth Magic spells reduced by ${val}%",
|
||||
"core.bonus.SPELL_DAMAGE_REDUCTION.description.spellSchool.fire" : "{Fire Spells Resistance}\nDamage from Fire Magic spells reduced by ${val}%",
|
||||
"core.bonus.SPELL_DAMAGE_REDUCTION.description.spellSchool.water" : "{Water Spells Resistance}\nDamage from Water Magic spells reduced by ${val}%",
|
||||
"core.bonus.SPELL_IMMUNITY.description" : "{Spell immunity}\nThis unit can not be affected by ${subtype.spell}",
|
||||
"core.bonus.SPELL_LIKE_ATTACK.description" : "{Spell-like attack}\nAttacks with ${subtype.spell}",
|
||||
"core.bonus.SPELL_RESISTANCE_AURA.description" : "{Aura of Resistance}\nAdjacent units get ${val}% magic resistance",
|
||||
"core.bonus.SPELL_SCHOOL_IMMUNITY.description" : "{Spell immunity}\nThis unit is immune to all spells",
|
||||
"core.bonus.SPELL_SCHOOL_IMMUNITY.description.air" : "{Air immunity}\nThis unit is immune to all Air school spells",
|
||||
"core.bonus.SPELL_SCHOOL_IMMUNITY.description.earth" : "{Earth immunity}\nThis unit is immune to all Earth school spells",
|
||||
"core.bonus.SPELL_SCHOOL_IMMUNITY.description.fire" : "{Fire immunity}\nThis unit is immune to all Fire school spells",
|
||||
"core.bonus.SPELL_SCHOOL_IMMUNITY.description.water" : "{Water immunity}\nThis unit is immune to all Water school spells",
|
||||
"core.bonus.SPELL_SCHOOL_IMMUNITY.description.spellSchool.air" : "{Immune to Air Magic}\nImmune to all spells from the school of Air Magic",
|
||||
"core.bonus.SPELL_SCHOOL_IMMUNITY.description.spellSchool.earth" : "{Immune to Earth Magic}\nImmune to all spells from the school of Earth Magic",
|
||||
"core.bonus.SPELL_SCHOOL_IMMUNITY.description.spellSchool.fire" : "{Immune to Fire Magic}\nImmune to all spells from the school of Fire Magic",
|
||||
"core.bonus.SPELL_SCHOOL_IMMUNITY.description.spellSchool.water" : "{Immune to Water Magic}\nImmune to all spells from the school of Water Magic",
|
||||
"core.bonus.SPELLCASTER.description" : "{Spellcaster}\nCan cast ${subtype.spell}",
|
||||
"core.bonus.SUMMON_GUARDIANS.description" : "{Summon guardians}\nAt the start of battle summons ${subtype.creature} (${val}%)",
|
||||
"core.bonus.SYNERGY_TARGET.description" : "{Synergizable}\nThis creature is vulnerable to synergy effect",
|
||||
"core.bonus.THREE_HEADED_ATTACK.description" : "{Three-headed attack}\nAttacks three adjacent units",
|
||||
"core.bonus.TRANSMUTATION.description" : "{Transmutation}\n${val}% chance to transform attacked unit to a different type",
|
||||
"core.bonus.TWO_HEX_ATTACK_BREATH.description" : "{Dragon Breath}\nAttacks by this unit will also hit any unit positioned immediately behind the target",
|
||||
"core.bonus.TWO_HEX_ATTACK_BREATH.description" : "{Breath Attack}\nAttacks by this unit will also hit any unit positioned immediately behind the target",
|
||||
"core.bonus.UNDEAD.description" : "{Undead}\nCreature is Undead and is immune to effects that only affect living",
|
||||
"core.bonus.UNLIMITED_RETALIATIONS.description" : "{Unlimited retaliations}\nThis unit can retaliate against an unlimited number of attacks",
|
||||
"core.bonus.WATER_IMMUNITY.description" : "{Immune to Water Magic}\nImmune to all spells from the school of Water magic",
|
||||
"core.bonus.WIDE_BREATH.description" : "{Wide breath}\nThis unit attacks all units around its target",
|
||||
|
||||
|
||||
"spell.core.castleMoat.name" : "Moat",
|
||||
"spell.core.castleMoatTrigger.name" : "Moat",
|
||||
"spell.core.catapultShot.name" : "Catapult shot",
|
||||
|
||||
@@ -92,6 +92,10 @@
|
||||
|
||||
"FIRST_STRIKE":
|
||||
{
|
||||
"subtypeDescriptions" : {
|
||||
"bonusSubtype.damageTypeRanged" : null,
|
||||
"bonusSubtype.damageTypeMelee" : null,
|
||||
}
|
||||
},
|
||||
|
||||
"FEAR":
|
||||
@@ -108,6 +112,9 @@
|
||||
|
||||
"FLYING":
|
||||
{
|
||||
"subtypeDescriptions" : {
|
||||
"bonusSubtype.movementTeleporting" : null,
|
||||
}
|
||||
},
|
||||
|
||||
"FREE_SHOOTING":
|
||||
@@ -120,6 +127,10 @@
|
||||
|
||||
"GENERAL_DAMAGE_REDUCTION":
|
||||
{
|
||||
"subtypeDescriptions" : {
|
||||
"bonusSubtype.damageTypeRanged" : null,
|
||||
"bonusSubtype.damageTypeMelee" : null,
|
||||
}
|
||||
},
|
||||
|
||||
"HATE":
|
||||
@@ -140,6 +151,10 @@
|
||||
|
||||
"KING":
|
||||
{
|
||||
"valueDescriptions" : {
|
||||
"2" : null,
|
||||
"3" : null
|
||||
}
|
||||
},
|
||||
|
||||
"LEARN_BATTLE_SPELL_CHANCE":
|
||||
@@ -281,6 +296,12 @@
|
||||
|
||||
"SPELL_DAMAGE_REDUCTION":
|
||||
{
|
||||
"subtypeDescriptions" : {
|
||||
"spellSchool.air" : null,
|
||||
"spellSchool.earth" : null,
|
||||
"spellSchool.fire" : null,
|
||||
"spellSchool.water" : null,
|
||||
}
|
||||
},
|
||||
|
||||
"SPELL_IMMUNITY":
|
||||
@@ -293,6 +314,12 @@
|
||||
|
||||
"SPELL_SCHOOL_IMMUNITY":
|
||||
{
|
||||
"subtypeDescriptions" : {
|
||||
"spellSchool.air" : null,
|
||||
"spellSchool.earth" : null,
|
||||
"spellSchool.fire" : null,
|
||||
"spellSchool.water" : null,
|
||||
}
|
||||
},
|
||||
|
||||
"SPELL_RESISTANCE_AURA":
|
||||
|
||||
@@ -60,23 +60,27 @@ CBonusTypeHandler::~CBonusTypeHandler() = default;
|
||||
std::string CBonusTypeHandler::bonusToString(const std::shared_ptr<Bonus> & bonus, const IBonusBearer * bearer) const
|
||||
{
|
||||
const CBonusType & bt = bonusTypes[vstd::to_underlying(bonus->type)];
|
||||
int bonusValue = bearer->valOfBonuses(bonus->type, bonus->subtype);
|
||||
if(bt.hidden)
|
||||
return "";
|
||||
|
||||
std::string textID = bt.getDescriptionTextID();
|
||||
std::string text = LIBRARY->generaltexth->translate(textID);
|
||||
|
||||
auto school = bonus->subtype.as<SpellSchool>();
|
||||
if (school.hasValue() && school != SpellSchool::ANY)
|
||||
auto subtype = bonus->subtype.getNum();
|
||||
if (bt.subtypeDescriptions.count(subtype))
|
||||
{
|
||||
std::string schoolName = school.encode(school.getNum());
|
||||
std::string baseTextID = bt.getDescriptionTextID();
|
||||
std::string fullTextID = baseTextID + '.' + schoolName;
|
||||
std::string fullTextID = textID + '.' + bt.subtypeDescriptions.at(subtype);
|
||||
text = LIBRARY->generaltexth->translate(fullTextID);
|
||||
}
|
||||
else if (bt.valueDescriptions.count(bonusValue))
|
||||
{
|
||||
std::string fullTextID = textID + '.' + bt.valueDescriptions.at(bonusValue);
|
||||
text = LIBRARY->generaltexth->translate(fullTextID);
|
||||
}
|
||||
|
||||
if (text.find("${val}") != std::string::npos)
|
||||
boost::algorithm::replace_all(text, "${val}", std::to_string(bearer->valOfBonuses(bonus->type, bonus->subtype)));
|
||||
boost::algorithm::replace_all(text, "${val}", std::to_string(bonusValue));
|
||||
|
||||
if (text.find("${subtype.creature}") != std::string::npos && bonus->subtype.as<CreatureID>().hasValue())
|
||||
boost::algorithm::replace_all(text, "${subtype.creature}", bonus->subtype.as<CreatureID>().toCreature()->getNamePluralTranslated());
|
||||
@@ -161,6 +165,24 @@ void CBonusTypeHandler::loadItem(const JsonNode & source, CBonusType & dest, con
|
||||
int value = std::stoi(additionalIcon.first);
|
||||
dest.valueIcons[value] = path;
|
||||
}
|
||||
|
||||
for (const auto & additionalDescription : source["subtypeDescriptions"].Struct())
|
||||
{
|
||||
LIBRARY->generaltexth->registerString( "vcmi", dest.getDescriptionTextID() + "." + additionalDescription.first, additionalDescription.second);
|
||||
auto stringID = additionalDescription.first;
|
||||
LIBRARY->identifiers()->requestIdentifier(additionalDescription.second.getModScope(), additionalDescription.first, [&dest, stringID](int32_t index)
|
||||
{
|
||||
dest.subtypeDescriptions[index] = stringID;
|
||||
});
|
||||
}
|
||||
|
||||
for (const auto & additionalDescription : source["valueDescriptions"].Struct())
|
||||
{
|
||||
LIBRARY->generaltexth->registerString( "vcmi", dest.getDescriptionTextID() + "." + additionalDescription.first, additionalDescription.second);
|
||||
auto stringID = additionalDescription.first;
|
||||
int value = std::stoi(additionalDescription.first);
|
||||
dest.valueDescriptions[value] = stringID;
|
||||
}
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
@@ -32,6 +32,8 @@ private:
|
||||
ImagePath icon;
|
||||
std::map<int, ImagePath> subtypeIcons;
|
||||
std::map<int, ImagePath> valueIcons;
|
||||
std::map<int, std::string> subtypeDescriptions;
|
||||
std::map<int, std::string> valueDescriptions;
|
||||
std::string identifier;
|
||||
|
||||
bool hidden;
|
||||
|
||||
Reference in New Issue
Block a user