From 35775b90f83897ec22e004c00f8d3f8ed58389c6 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 17 Jan 2023 12:42:43 +0200 Subject: [PATCH] Moved bonus names to translation --- Mods/vcmi/config/vcmi/english.json | 159 +++++++++- config/bonuses_texts.json | 476 ----------------------------- config/gameConfig.json | 3 +- config/sp_sounds.json | 13 - lib/CBonusTypeHandler.cpp | 151 +++------ lib/CBonusTypeHandler.h | 40 +-- lib/VCMI_Lib.cpp | 4 +- 7 files changed, 203 insertions(+), 643 deletions(-) delete mode 100644 config/bonuses_texts.json delete mode 100644 config/sp_sounds.json diff --git a/Mods/vcmi/config/vcmi/english.json b/Mods/vcmi/config/vcmi/english.json index 847c1203b..6071cc952 100644 --- a/Mods/vcmi/config/vcmi/english.json +++ b/Mods/vcmi/config/vcmi/english.json @@ -82,5 +82,162 @@ "vcmi.stackExperience.rank.8" : "Expert", "vcmi.stackExperience.rank.9" : "Elite", "vcmi.stackExperience.rank.10" : "Master", - "vcmi.stackExperience.rank.11" : "Ace" + "vcmi.stackExperience.rank.11" : "Ace", + + "core.bonus.ADDITIONAL_ATTACK.name": "Double Strike", + "core.bonus.ADDITIONAL_ATTACK.description": "Attacks twice", + "core.bonus.ADDITIONAL_RETALIATION.name": "Additional retaliations", + "core.bonus.ADDITIONAL_RETALIATION.description": "May Retaliate ${val} extra times", + "core.bonus.AIR_IMMUNITY.name": "Air immunity", + "core.bonus.AIR_IMMUNITY.description": "Immune to all Air school spells", + "core.bonus.ATTACKS_ALL_ADJACENT.name": "Attack all around", + "core.bonus.ATTACKS_ALL_ADJACENT.description": "Attacks all adjacent enemies", + "core.bonus.BLOCKS_RETALIATION.name": "No retaliation", + "core.bonus.BLOCKS_RETALIATION.description": "Enemy cannot Retaliate", + "core.bonus.BLOCKS_RANGED_RETALIATION.name": "No ranged retaliation", + "core.bonus.BLOCKS_RANGED_RETALIATION.description": "Enemy cannot Retaliate by shooting", + "core.bonus.CATAPULT.name": "Catapult", + "core.bonus.CATAPULT.description": "Attacks siege walls", + "core.bonus.CATAPULT_EXTRA_SHOTS.name": "Additional siege attacks", + "core.bonus.CATAPULT_EXTRA_SHOTS.description": "Can hit siege walls ${val} extra times per attack", + "core.bonus.CHANGES_SPELL_COST_FOR_ALLY.name": "Reduce Casting Cost (${val})", + "core.bonus.CHANGES_SPELL_COST_FOR_ALLY.description": "Reduces spell cost for hero", + "core.bonus.CHANGES_SPELL_COST_FOR_ENEMY.name": "Magic Damper (${val})", + "core.bonus.CHANGES_SPELL_COST_FOR_ENEMY.description": "Increases Cost of enemy spells", + "core.bonus.CHARGE_IMMUNITY.name": "Immune to Charge", + "core.bonus.CHARGE_IMMUNITY.description": "Immune to Champion charge", + "core.bonus.DARKNESS.name": "Darkness cover", + "core.bonus.DARKNESS.description": "Adds ${val} darkness radius", + "core.bonus.DEATH_STARE.name": "Death Stare (${val}%)", + "core.bonus.DEATH_STARE.description": "${val}% chance to kill single creature", + "core.bonus.DEFENSIVE_STANCE.name": "Defense Bonus", + "core.bonus.DEFENSIVE_STANCE.description": "+${val} Defense when defending", + "core.bonus.DESTRUCTION.name": "Destruction", + "core.bonus.DESTRUCTION.description": "Has ${val}% chance to kill extra units after attack", + "core.bonus.DOUBLE_DAMAGE_CHANCE.name": "Death Blow", + "core.bonus.DOUBLE_DAMAGE_CHANCE.description": "${val}% chance for double damage", + "core.bonus.DRAGON_NATURE.name": "Dragon", + "core.bonus.DRAGON_NATURE.description": "Creature has a Dragon Nature", + "core.bonus.DIRECT_DAMAGE_IMMUNITY.name": "Direct Damage Immunity", + "core.bonus.DIRECT_DAMAGE_IMMUNITY.description": "Immune to direct damage spells", + "core.bonus.EARTH_IMMUNITY.name": "Earth immunity", + "core.bonus.EARTH_IMMUNITY.description": "Immune to all Earth school spells", + "core.bonus.ENCHANTER.name": "Enchanter", + "core.bonus.ENCHANTER.description": "Can cast mass ${subtype.spell} every turn", + "core.bonus.ENCHANTED.name": "Enchanted", + "core.bonus.ENCHANTED.description": "Affected by permanent ${subtype.spell}", + "core.bonus.ENEMY_DEFENCE_REDUCTION.name": "Ignore Defense (${val}%)", + "core.bonus.ENEMY_DEFENCE_REDUCTION.description": "Ignores part of Defence for the attack", + "core.bonus.FIRE_IMMUNITY.name": "Fire immunity", + "core.bonus.FIRE_IMMUNITY.description": "Immune to all Fire school spells", + "core.bonus.FIRE_SHIELD.name": "Fire Shield (${val}%)", + "core.bonus.FIRE_SHIELD.description": "Reflects part of melee damage", + "core.bonus.FIRST_STRIKE.name": "First Strike", + "core.bonus.FIRST_STRIKE.description": "This creature attacks first instead of retaliating", + "core.bonus.FEAR.name": "Fear", + "core.bonus.FEAR.description": "Causes Fear on an enemy stack", + "core.bonus.FEARLESS.name": "Fearless", + "core.bonus.FEARLESS.description": "Immune to Fear ability", + "core.bonus.FLYING.name": "Fly", + "core.bonus.FLYING.description": "Can Fly (ignores obstacles)", + "core.bonus.FREE_SHOOTING.name": "Shoot Close", + "core.bonus.FREE_SHOOTING.description": "Can shoot in Close Combat", + "core.bonus.FULL_HP_REGENERATION.name": "Regeneration", + "core.bonus.FULL_HP_REGENERATION.description": "May Regenerate to full Health", + "core.bonus.GARGOYLE.name": "Gargoyle", + "core.bonus.GARGOYLE.description": "Cannot be rised or healed", + "core.bonus.GENERAL_DAMAGE_REDUCTION.name": "Reduce Damage (${val}%)", + "core.bonus.GENERAL_DAMAGE_REDUCTION.description": "Reduces physical damage from ranged or melee", + "core.bonus.HATE.name": "Hates ${subtype.creature}", + "core.bonus.HATE.description": "Does ${val}% more damage", + "core.bonus.HEALER.name": "Healer", + "core.bonus.HEALER.description": "Heals allied units", + "core.bonus.HP_REGENERATION.name": "Regeneration", + "core.bonus.HP_REGENERATION.description": "Heals ${val} hit points every round", + "core.bonus.JOUSTING.name": "Champion Charge", + "core.bonus.JOUSTING.description": "+5% damage per hex travelled", + "core.bonus.KING1.name": "King 1", + "core.bonus.KING1.description": "Vulnerable to basic SLAYER", + "core.bonus.KING2.name": "King 2", + "core.bonus.KING2.description": "Vulnerable to advanced SLAYER", + "core.bonus.KING3.name": "King 3", + "core.bonus.KING3.description":"Vulnerable to expert SLAYER", + "core.bonus.LEVEL_SPELL_IMMUNITY.name": "Spell immunity 1-${val}", + "core.bonus.LEVEL_SPELL_IMMUNITY.description": "Immune to spells of levels 1-${val}", + "core.bonus.LIMITED_SHOOTING_RANGE.name" : "Limited shooting range", + "core.bonus.LIMITED_SHOOTING_RANGE.description" : "", + "core.bonus.LIFE_DRAIN.name": "Drain life (${val}%)", + "core.bonus.LIFE_DRAIN.description": "Drains ${val}% of damage dealt", + "core.bonus.MANA_CHANNELING.name": "Magic Channel ${val}%", + "core.bonus.MANA_CHANNELING.description": "Gives your hero mana spent by enemy", + "core.bonus.MANA_DRAIN.name": "Mana Drain", + "core.bonus.MANA_DRAIN.description": "Drains ${val} mana every turn", + "core.bonus.MAGIC_MIRROR.name": "Magic Mirror (${val}%)", + "core.bonus.MAGIC_MIRROR.description": "${val}% chance to redirects an offensive spell to enemy", + "core.bonus.MAGIC_RESISTANCE.name": "Magic Resistance(${MR}%)", + "core.bonus.MAGIC_RESISTANCE.description": "${MR}% chance to resist enemy spell", + "core.bonus.MIND_IMMUNITY.name": "Mind Spell Immunity", + "core.bonus.MIND_IMMUNITY.description": "Immune to Mind-type spells", + "core.bonus.NO_DISTANCE_PENALTY.name": "No distance penalty", + "core.bonus.NO_DISTANCE_PENALTY.description": "Full damage from any distance", + "core.bonus.NO_MELEE_PENALTY.name": "No melee penalty", + "core.bonus.NO_MELEE_PENALTY.description": "Creature has no Melee Penalty", + "core.bonus.NO_MORALE.name": "Neutral Morale", + "core.bonus.NO_MORALE.description": "Creature is immune to morale effects", + "core.bonus.NO_WALL_PENALTY.name": "No wall penalty", + "core.bonus.NO_WALL_PENALTY.description": "Full damage during siege", + "core.bonus.NON_LIVING.name": "Non living", + "core.bonus.NON_LIVING.description": "Immunity to many effects", + "core.bonus.RANDOM_SPELLCASTER.name": "Random spellcaster", + "core.bonus.RANDOM_SPELLCASTER.description": "Can cast random spell", + "core.bonus.RANGED_RETALIATION.name": "Ranged retaliation", + "core.bonus.RANGED_RETALIATION.description": "Can perform ranged counterattack", + "core.bonus.RECEPTIVE.name": "Receptive", + "core.bonus.RECEPTIVE.description": "No Immunity to Friendly Spells", + "core.bonus.REBIRTH.name": "Rebirth (${val}%)", + "core.bonus.REBIRTH.description": "${val}% of stack will rise after death", + "core.bonus.RETURN_AFTER_STRIKE.name": "Attack and Return", + "core.bonus.RETURN_AFTER_STRIKE.description": "Returns after melee attack", + "core.bonus.SELF_LUCK.name": "Positive luck", + "core.bonus.SELF_LUCK.description": "Always has Positive Luck", + "core.bonus.SELF_MORALE.name": "Positive morale", + "core.bonus.SELF_MORALE.description": "Always has Positive Morale", + "core.bonus.SHOOTER.name": "Ranged", + "core.bonus.SHOOTER.description": "Creature can shoot", + "core.bonus.SHOOTS_ALL_ADJACENT.name": "Shoot all around", + "core.bonus.SHOOTS_ALL_ADJACENT.description": "This creature's ranged attacks strike all targets in a small area", + "core.bonus.SOUL_STEAL.name": "Soul Steal", + "core.bonus.SOUL_STEAL.description": "Gains ${val} new creatures for each enemy killed", + "core.bonus.SPELLCASTER.name": "Spellcaster", + "core.bonus.SPELLCASTER.description": "Can cast ${subtype.spell}", + "core.bonus.SPELL_AFTER_ATTACK.name": "Cast After Attack", + "core.bonus.SPELL_AFTER_ATTACK.description": "${val}% to cast ${subtype.spell} after attack", + "core.bonus.SPELL_BEFORE_ATTACK.name": "Cast Before Attack", + "core.bonus.SPELL_BEFORE_ATTACK.description": "${val}% to cast ${subtype.spell} before attack", + "core.bonus.SPELL_DAMAGE_REDUCTION.name": "Spell Resistance", + "core.bonus.SPELL_DAMAGE_REDUCTION.description": "Damage from spells reduced ${val}%.", + "core.bonus.SPELL_IMMUNITY.name": "Spell immunity", + "core.bonus.SPELL_IMMUNITY.description": "Immune to ${subtype.spell}", + "core.bonus.SPELL_LIKE_ATTACK.name": "Spell-like attack", + "core.bonus.SPELL_LIKE_ATTACK.description": "Attacks with ${subtype.spell}", + "core.bonus.SPELL_RESISTANCE_AURA.name": "Aura of Resistance", + "core.bonus.SPELL_RESISTANCE_AURA.description": "Nearby stacks get ${val}% resistance", + "core.bonus.SUMMON_GUARDIANS.name": "Summon guardians", + "core.bonus.SUMMON_GUARDIANS.description": "At battle start summons ${subtype.creature} (${val}%)", + "core.bonus.SYNERGY_TARGET.name": "Synergizable", + "core.bonus.SYNERGY_TARGET.description": "This creature is vulnerable to synergy effect", + "core.bonus.TWO_HEX_ATTACK_BREATH.name": "Breath", + "core.bonus.TWO_HEX_ATTACK_BREATH.description": "Breath Attack (2-hex range)", + "core.bonus.THREE_HEADED_ATTACK.name": "Three-headed attack", + "core.bonus.THREE_HEADED_ATTACK.description": "Attacks three adjacent units", + "core.bonus.TRANSMUTATION.name": "Transmutation", + "core.bonus.TRANSMUTATION.description": "${val}% chance to transform attacked unit to other type", + "core.bonus.UNDEAD.name": "Undead", + "core.bonus.UNDEAD.description": "Creature is Undead", + "core.bonus.UNLIMITED_RETALIATIONS.name": "Unlimited retaliations", + "core.bonus.UNLIMITED_RETALIATIONS.description": "Retaliates any number of attacks", + "core.bonus.WATER_IMMUNITY.name": "Water immunity", + "core.bonus.WATER_IMMUNITY.description": "Immune to all Water school spells", + "core.bonus.WIDE_BREATH.name": "Wide breath", + "core.bonus.WIDE_BREATH.description": "Wide breath attack (multiple hexes)" } diff --git a/config/bonuses_texts.json b/config/bonuses_texts.json deleted file mode 100644 index d7f99bdb2..000000000 --- a/config/bonuses_texts.json +++ /dev/null @@ -1,476 +0,0 @@ -// macros: -// ${val} - value of bonuses; Selector: type,subtype -// ${subtype.creature} - creature name -// ${subtype.spell} - spell name -// ${MR} - magic resistance of bearer - - -{ - "ADDITIONAL_ATTACK": - { - "name": "Double Strike", - "description": "Attacks twice" - }, - - "ADDITIONAL_RETALIATION": - { - "name": "Additional retaliations", - "description": "May Retaliate ${val} extra times" - }, - - "AIR_IMMUNITY": - { - "name": "Air immunity", - "description": "Immune to all Air school spells" - }, - - "ATTACKS_ALL_ADJACENT": - { - "name": "Attack all around", - "description": "Attacks all adjacent enemies" - }, - - "BLOCKS_RETALIATION": - { - "name": "No retaliation", - "description": "Enemy cannot Retaliate" - }, - - "BLOCKS_RANGED_RETALIATION": - { - "name": "No ranged retaliation", - "description": "Enemy cannot Retaliate by shooting" - }, - - "CATAPULT": - { - "name": "Catapult", - "description": "Attacks siege walls" - }, - - "CATAPULT_EXTRA_SHOTS": - { - "name": "Additional siege attacks", - "description": "Can hit siege walls ${val} extra times per attack" - }, - - "CHANGES_SPELL_COST_FOR_ALLY": - { - "name": "Reduce Casting Cost (${val})", - "description": "Reduces spell cost for hero" - }, - - "CHANGES_SPELL_COST_FOR_ENEMY": - { - "name": "Magic Damper (${val})", - "description": "Increases Cost of enemy spells" - }, - - "CHARGE_IMMUNITY": - { - "name": "Immune to Charge", - "description": "Immune to Champion charge" - }, - - "DARKNESS": - { - "name": "Darkness cover", - "description": "Adds ${val} darkness radius" - }, - - "DEATH_STARE": - { - "name": "Death Stare (${val}%)", - "description": "${val}% chance to kill single creature" - }, - - "DEFENSIVE_STANCE": - { - "name": "Defense Bonus", - "description": "+${val} Defense when defending" - }, - - "DESTRUCTION": - { - "name": "Destruction", - "description": "Has ${val}% chance to kill extra units after attack" - }, - - "DOUBLE_DAMAGE_CHANCE": - { - "name": "Death Blow", - "description": "${val}% chance for double damage" - }, - - "DRAGON_NATURE": - { - "name": "Dragon", - "description": "Creature has a Dragon Nature" - }, - - "DIRECT_DAMAGE_IMMUNITY": - { - "name": "Direct Damage Immunity", - "description": "Immune to direct damage spells" - }, - - "EARTH_IMMUNITY": - { - "name": "Earth immunity", - "description": "Immune to all Earth school spells" - }, - - "ENCHANTER": - { - "name": "Enchanter", - "description": "Can cast mass ${subtype.spell} every turn" - }, - - "ENCHANTED": - { - "name": "Enchanted", - "description": "Affected by permanent ${subtype.spell}" - }, - - "ENEMY_DEFENCE_REDUCTION": - { - "name": "Ignore Defense (${val}%)", - "description": "Ignores part of Defence for the attack" - }, - - "FIRE_IMMUNITY": - { - "name": "Fire immunity", - "description": "Immune to all Fire school spells" - }, - - "FIRE_SHIELD": - { - "name": "Fire Shield (${val}%)", - "description": "Reflects part of melee damage" - }, - - "FIRST_STRIKE": - { - "name": "First Strike", - "description": "This creature attacks first instead of retaliating" - }, - - "FEAR": - { - "name": "Fear", - "description": "Causes Fear on an enemy stack" - }, - - "FEARLESS": - { - "name": "Fearless", - "description": "Immune to Fear ability" - }, - - "FLYING": - { - "name": "Fly", - "description": "Can Fly (ignores obstacles)" - }, - - "FREE_SHOOTING": - { - "name": "Shoot Close", - "description": "Can shoot in Close Combat" - }, - - "FULL_HP_REGENERATION": - { - "name": "Regeneration", - "description": "May Regenerate to full Health" - }, - - "GARGOYLE": - { - "name": "Gargoyle", - "description": "Cannot be rised or healed" - }, - - "GENERAL_DAMAGE_REDUCTION": - { - "name": "Reduce Damage (${val}%)", - "description": "Reduces physical damage from ranged or melee" - }, - - "HATE": - { - "name": "Hates ${subtype.creature}", - "description": "Does ${val}% more damage" - }, - - "HEALER": - { - "name": "Healer", - "description": "Heals allied units" - }, - - "HP_REGENERATION": - { - "name": "Regeneration", - "description": "Heals ${val} hit points every round" - }, - - "JOUSTING": - { - "name": "Champion Charge", - "description": "+5% damage per hex travelled" - }, - - "KING1": - { - "name": "King 1", - "description": "Vulnerable to basic SLAYER" - }, - - "KING2": - { - "name": "King 2", - "description": "Vulnerable to advanced SLAYER" - }, - - "KING3": - { - "name": "King 3", - "description":"Vulnerable to expert SLAYER" - }, - - "LEVEL_SPELL_IMMUNITY": - { - "name": "Spell immunity 1-${val}", - "description": "Immune to spells of levels 1-${val}" - }, - - "LIFE_DRAIN": - { - "name": "Drain life (${val}%)", - "description": "Drains ${val}% of damage dealt" - }, - - "LIMITED_SHOOTING_RANGE": - { - "name": "Limited shooting range", - "description": "Cannot shoot targets beyond ${val} hexes away" - }, - - "MANA_CHANNELING": - { - "name": "Magic Channel ${val}%", - "description": "Gives your hero mana spent by enemy" - }, - - "MANA_DRAIN": - { - "name": "Mana Drain", - "description": "Drains ${val} mana every turn" - }, - - "MAGIC_MIRROR": - { - "name": "Magic Mirror (${val}%)", - "description": "${val}% chance to redirects an offensive spell to enemy" - }, - - "MAGIC_RESISTANCE": - { - "name": "Magic Resistance(${MR}%)", - "description": "${MR}% chance to resist enemy spell" - }, - - "MIND_IMMUNITY": - { - "name": "Mind Spell Immunity", - "description": "Immune to Mind-type spells" - }, - - "NO_DISTANCE_PENALTY": - { - "name": "No distance penalty", - "description": "Full damage from any distance" - }, - - "NO_MELEE_PENALTY": - { - "name": "No melee penalty", - "description": "Creature has no Melee Penalty" - }, - - "NO_MORALE": - { - "name": "Neutral Morale", - "description": "Creature is immune to morale effects" - }, - - "NO_WALL_PENALTY": - { - "name": "No wall penalty", - "description": "Full damage during siege" - }, - - "NON_LIVING": - { - "name": "Non living", - "description": "Immunity to many effects" - }, - - "RANDOM_SPELLCASTER": - { - "name": "Random spellcaster", - "description": "Can cast random spell" - }, - - "RANGED_RETALIATION": - { - "name": "Ranged retaliation", - "description": "Can perform ranged counterattack" - }, - - "RECEPTIVE": - { - "name": "Receptive", - "description": "No Immunity to Friendly Spells" - }, - - "REBIRTH": - { - "name": "Rebirth (${val}%)", - "description": "${val}% of stack will rise after death" - }, - - "RETURN_AFTER_STRIKE": - { - "name": "Attack and Return", - "description": "Returns after melee attack" - }, - - "SELF_LUCK": - { - "name": "Positive luck", - "description": "Always has Positive Luck" - }, - - "SELF_MORALE": - { - "name": "Positive morale", - "description": "Always has Positive Morale" - }, - - "SHOOTER": - { - "name": "Ranged", - "description": "Creature can shoot" - }, - - "SHOOTS_ALL_ADJACENT": - { - "name": "Shoot all around", - "description": "This creature's ranged attacks strike all targets in a small area" - }, - - "SOUL_STEAL": - { - "name": "Soul Steal", - "description": "Gains ${val} new creatures for each enemy killed" - }, - - "SPELLCASTER": - { - "name": "Spellcaster", - "description": "Can cast ${subtype.spell}" - }, - - "SPELL_AFTER_ATTACK": - { - "name": "Cast After Attack", - "description": "${val}% to cast ${subtype.spell} after attack" - }, - - "SPELL_BEFORE_ATTACK": - { - "name": "Cast Before Attack", - "description": "${val}% to cast ${subtype.spell} before attack" - }, - - "SPELL_DAMAGE_REDUCTION": - { - "name": "Spell Resistance", - "description": "Damage from spells reduced ${val}%." - }, - - "SPELL_IMMUNITY": - { - "name": "Spell immunity", - "description": "Immune to ${subtype.spell}" - }, - - "SPELL_LIKE_ATTACK": - { - "name": "Spell-like attack", - "description": "Attacks with ${subtype.spell}" - }, - - "SPELL_RESISTANCE_AURA": - { - "name": "Aura of Resistance", - "description": "Nearby stacks get ${val}% resistance" - }, - - "SUMMON_GUARDIANS": - { - "name": "Summon guardians", - "description": "At battle start summons ${subtype.creature} (${val}%)" - }, - - "SYNERGY_TARGET": - { - "name": "Synergizable", - "description": "This creature is vulnerable to synergy effect" - }, - - "TWO_HEX_ATTACK_BREATH": - { - "name": "Breath", - "description": "Breath Attack (2-hex range)" - }, - - "THREE_HEADED_ATTACK": - { - "name": "Three-headed attack", - "description": "Attacks three adjacent units" - }, - - "TRANSMUTATION": - { - "name": "Transmutation", - "description": "${val}% chance to transform attacked unit to other type" - }, - - "UNDEAD": - { - "name": "Undead", - "description": "Creature is Undead" - }, - - "UNLIMITED_RETALIATIONS": - { - "name": "Unlimited retaliations", - "description": "Retaliates any number of attacks" - }, - - "WATER_IMMUNITY": - { - "name": "Water immunity", - "description": "Immune to all Water school spells" - }, - - "WIDE_BREATH": - { - "name": "Wide breath", - "description": "Wide breath attack (multiple hexes)" - } -} diff --git a/config/gameConfig.json b/config/gameConfig.json index edd8b7231..7c832b8ea 100644 --- a/config/gameConfig.json +++ b/config/gameConfig.json @@ -66,8 +66,7 @@ "bonuses" : [ - "config/bonuses.json", - "config/bonuses_texts.json" + "config/bonuses.json" ], "spells" : [ diff --git a/config/sp_sounds.json b/config/sp_sounds.json deleted file mode 100644 index 14aafc8fd..000000000 --- a/config/sp_sounds.json +++ /dev/null @@ -1,13 +0,0 @@ - -// Several probably missing sounds of creature abilities -// ACID.WAV Acid breath Rust Dragons -// DEATHBLO.WAV Deathblow Death knigts -// DRAINLIF.WAV Drain life Vampires -// FEAR.WAV Fear Azure dragons -// MAGCHDRN.WAV Steal mana Imps -// MAGCHFIL.WAV Steal mana Either for upgrades or for receiving mana by hero -// MAGICRES.WAV Magic resist Dwarves -// MANADRAI.WAV Mana drain Ghosts -// REGENER.WAV Regeneration Ghosts, Trolls -// RESURECT.WAV Resurrection Both archangels and Demons -// SPONTCOMB.WAV Fireball Magogs diff --git a/lib/CBonusTypeHandler.cpp b/lib/CBonusTypeHandler.cpp index 8e0047f34..51ae51e76 100644 --- a/lib/CBonusTypeHandler.cpp +++ b/lib/CBonusTypeHandler.cpp @@ -18,99 +18,29 @@ #include "GameConstants.h" #include "CCreatureHandler.h" +#include "CGeneralTextHandler.h" #include "spells/CSpellHandler.h" template class std::vector; VCMI_LIB_NAMESPACE_BEGIN -///MacroString - -MacroString::MacroString(const std::string & format) -{ - static const std::string MACRO_START = "${"; - static const std::string MACRO_END = "}"; - static const size_t MACRO_START_L = 2; - static const size_t MACRO_END_L = 1; - - size_t end_pos = 0; - size_t start_pos = std::string::npos; - do - { - start_pos = format.find(MACRO_START, end_pos); - - if(!(start_pos == std::string::npos)) - { - //chunk before macro - items.push_back(Item(Item::STRING, format.substr(end_pos, start_pos - end_pos))); - - start_pos += MACRO_START_L; - end_pos = format.find(MACRO_END, start_pos); - - if(end_pos == std::string::npos) - { - logBonus->warn("Format error in: %s", format); - end_pos = start_pos; - break; - } - else - { - items.push_back(Item(Item::MACRO, format.substr(start_pos, end_pos - start_pos))); - end_pos += MACRO_END_L; - } - } - } - while(start_pos != std::string::npos); - - //no more macros - items.push_back(Item(Item::STRING, format.substr(end_pos))); -} - -std::string MacroString::build(const GetValue & getValue) const -{ - std::string result; - - for(const Item & i : items) - { - switch(i.type) - { - case Item::MACRO: - { - result += getValue(i.value); - break; - } - case Item::STRING: - { - result += i.value; - break; - } - } - } - return result; -} - ///CBonusType -CBonusType::CBonusType() +CBonusType::CBonusType(): + hidden(true) +{} + +std::string CBonusType::getNameTextID() const { - hidden = true; - icon.clear(); - nameTemplate.clear(); - descriptionTemplate.clear(); + return TextIdentifier( "core", "bonus", identifier, "name").get(); } -CBonusType::~CBonusType() +std::string CBonusType::getDescriptionTextID() const { - + return TextIdentifier( "core", "bonus", identifier, "description").get(); } -void CBonusType::buildMacros() -{ - name = MacroString(nameTemplate); - description = MacroString(descriptionTemplate); -} - - ///CBonusTypeHandler CBonusTypeHandler::CBonusTypeHandler() @@ -136,39 +66,26 @@ CBonusTypeHandler::~CBonusTypeHandler() std::string CBonusTypeHandler::bonusToString(const std::shared_ptr & bonus, const IBonusBearer * bearer, bool description) const { - auto getValue = [=](const std::string & name) -> std::string - { - if(name == "val") - { - return boost::lexical_cast(bearer->valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype))); - } - else if(name == "subtype.creature") - { - const CreatureID cre(bonus->subtype); - return cre.toCreature()->getNamePluralTranslated(); - } - else if(name == "subtype.spell") - { - const SpellID sp(bonus->subtype); - return sp.toSpell()->getNameTranslated(); - } - else if(name == "MR") - { - return boost::lexical_cast(bearer->magicResistance()); - } - else - { - logBonus->warn("Unknown macro in bonus config: %s", name); - return "[error]"; - } - }; - const CBonusType & bt = bonusTypes[bonus->type]; if(bt.hidden) return ""; - const MacroString & macro = description ? bt.description : bt.name; - return macro.build(getValue); + std::string textID = description ? bt.getDescriptionTextID() : bt.getNameTextID(); + std::string text = VLC->generaltexth->translate(textID); + + if (text.find("${val}") != std::string::npos) + boost::algorithm::replace_all(text, "${val}", std::to_string(bearer->valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype)))); + + if (text.find("${subtype.creature}") != std::string::npos) + boost::algorithm::replace_all(text, "${subtype.creature}", CreatureID(bonus->subtype).toCreature()->getNamePluralTranslated()); + + if (text.find("${subtype.spell}") != std::string::npos) + boost::algorithm::replace_all(text, "${subtype.spell}", SpellID(bonus->subtype).toSpell()->getNameTranslated()); + + if (text.find("${MR}") != std::string::npos) + boost::algorithm::replace_all(text, "${MR}", std::to_string(bearer->magicResistance())); + + return text; } std::string CBonusTypeHandler::bonusToGraphics(const std::shared_ptr & bonus) const @@ -304,31 +221,33 @@ void CBonusTypeHandler::load(const JsonNode & config) // // bonusTypes.push_back(bt); - logBonus->warn("Adding new bonuses not implemented (%s)", node.first); + logBonus->warn("Unrecognized bonus name! (%s)", node.first); } else { CBonusType & bt = bonusTypes[it->second]; - loadItem(node.second, bt); + loadItem(node.second, bt, node.first); logBonus->trace("Loaded bonus type %s", node.first); } } } -void CBonusTypeHandler::loadItem(const JsonNode & source, CBonusType & dest) +void CBonusTypeHandler::loadItem(const JsonNode & source, CBonusType & dest, const std::string & name) { - dest.nameTemplate = source["name"].String(); - dest.descriptionTemplate = source["description"].String(); + dest.identifier = name; dest.hidden = source["hidden"].Bool(); //Null -> false + if (!dest.hidden) + { + VLC->generaltexth->registerString(dest.getNameTextID(), source["name"].String()); + VLC->generaltexth->registerString(dest.getDescriptionTextID(), source["description"].String()); + } + const JsonNode & graphics = source["graphics"]; if(!graphics.isNull()) - { dest.icon = graphics["icon"].String(); - } - dest.buildMacros(); } VCMI_LIB_NAMESPACE_END diff --git a/lib/CBonusTypeHandler.h b/lib/CBonusTypeHandler.h index 977efe051..61969e07b 100644 --- a/lib/CBonusTypeHandler.h +++ b/lib/CBonusTypeHandler.h @@ -21,53 +21,27 @@ class JsonNode; typedef Bonus::BonusType BonusTypeID; -class MacroString -{ - struct Item - { - enum ItemType - { - STRING, MACRO - }; - Item(ItemType _type, std::string _value): type(_type), value(_value){}; - ItemType type; - std::string value; //constant string or macro name - }; - std::vector items; -public: - typedef std::function GetValue; - - MacroString() = default; - ~MacroString() = default; - explicit MacroString(const std::string & format); - - std::string build(const GetValue & getValue) const; -}; - class DLL_LINKAGE CBonusType { public: CBonusType(); - ~CBonusType(); + + std::string getNameTextID() const; + std::string getDescriptionTextID() const; template void serialize(Handler & h, const int version) { h & icon; - h & nameTemplate; - h & descriptionTemplate; + h & identifier; h & hidden; - if (!h.saving) - buildMacros(); } private: - void buildMacros(); - MacroString name, description; - friend class CBonusTypeHandler; + std::string icon; - std::string nameTemplate, descriptionTemplate; + std::string identifier; bool hidden; }; @@ -91,7 +65,7 @@ public: private: void load(); void load(const JsonNode & config); - void loadItem(const JsonNode & source, CBonusType & dest); + void loadItem(const JsonNode & source, CBonusType & dest, const std::string & name); std::vector bonusTypes; //index = BonusTypeID }; diff --git a/lib/VCMI_Lib.cpp b/lib/VCMI_Lib.cpp index e8245d88a..04c1507fa 100644 --- a/lib/VCMI_Lib.cpp +++ b/lib/VCMI_Lib.cpp @@ -198,14 +198,14 @@ void LibClasses::init(bool onlyEssential) modh->initializeConfig(); + createHandler(generaltexth, "General text", pomtime); + createHandler(bth, "Bonus type", pomtime); createHandler(roadTypeHandler, "Road", pomtime); createHandler(riverTypeHandler, "River", pomtime); createHandler(terrainTypeHandler, "Terrain", pomtime); - createHandler(generaltexth, "General text", pomtime); - createHandler(heroh, "Hero", pomtime); createHandler(arth, "Artifact", pomtime);