1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-15 00:05:02 +02:00

Basic Configuration for bonus types

* introduced new handler BonusTypeHandler
* config\bonusnames.json converted to common format and splitted info main and localizable parts
* hanlders initialization refactored
This commit is contained in:
alexvins
2013-03-06 18:49:56 +00:00
parent 6b5ee0b674
commit 2eb8263e51
28 changed files with 1481 additions and 517 deletions

View File

@ -10,6 +10,7 @@
#include "CGeneralTextHandler.h"
#include "CSpellHandler.h"
#include "CHeroHandler.h"
#include "IBonusTypeHandler.h"
/*
* CCreatureSet.cpp, part of VCMI engine
@ -561,341 +562,20 @@ void CStackInstance::setType(const CCreature *c)
}
std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const
{
std::map<Bonus::BonusType, std::pair<std::string, std::string> >::iterator it = VLC->creh->stackBonuses.find(bonus->type);
if (it != VLC->creh->stackBonuses.end())
if(Bonus::MAGIC_RESISTANCE == bonus->type)
{
std::string text;
if (description) //long ability description
{
text = it->second.second;
switch (bonus->type)
{
//no additional modifiers needed
case Bonus::FLYING:
case Bonus::UNLIMITED_RETALIATIONS:
case Bonus::SHOOTER:
case Bonus::FREE_SHOOTING:
case Bonus::NO_MELEE_PENALTY:
case Bonus::NO_DISTANCE_PENALTY:
case Bonus::NO_WALL_PENALTY:
case Bonus::JOUSTING: //TODO: percent bonus?
case Bonus::RETURN_AFTER_STRIKE:
case Bonus::BLOCKS_RETALIATION:
case Bonus::TWO_HEX_ATTACK_BREATH:
case Bonus::THREE_HEADED_ATTACK:
case Bonus::ATTACKS_ALL_ADJACENT:
case Bonus::ADDITIONAL_ATTACK: //TODO: what with more than one attack? Axe of Ferocity for example
case Bonus::FULL_HP_REGENERATION:
case Bonus::MANA_DRAIN:
case Bonus::LIFE_DRAIN:
case Bonus::REBIRTH:
case Bonus::SELF_MORALE:
case Bonus::SELF_LUCK:
case Bonus::FEAR:
case Bonus::FEARLESS:
case Bonus::CHARGE_IMMUNITY:
case Bonus::HEALER:
case Bonus::CATAPULT:
case Bonus::DRAGON_NATURE:
case Bonus::NON_LIVING:
case Bonus::UNDEAD:
case Bonus::FIRE_IMMUNITY:
case Bonus::WATER_IMMUNITY:
case Bonus::AIR_IMMUNITY:
case Bonus::EARTH_IMMUNITY:
case Bonus::RECEPTIVE:
case Bonus::DIRECT_DAMAGE_IMMUNITY:
break;
//One numeric value. magic resistance handled separately
case Bonus::SPELL_RESISTANCE_AURA:
case Bonus::SPELL_DAMAGE_REDUCTION:
case Bonus::LEVEL_SPELL_IMMUNITY:
case Bonus::HP_REGENERATION:
case Bonus::ADDITIONAL_RETALIATION:
case Bonus::DEFENSIVE_STANCE:
case Bonus::DOUBLE_DAMAGE_CHANCE:
case Bonus::DARKNESS: //Darkness Dragons any1?
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype))));
break;
//Complex descriptions
//case Bonus::SECONDARY_SKILL_PREMY: //only if there's no simple MR
// if (bonus->subtype == CGHeroInstance::RESISTANCE)
// {
// if (!hasBonusOfType(Bonus::MAGIC_RESISTANCE))
// boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>( magicResistance() ));
// }
// break;
//case Bonus::MAGIC_RESISTANCE:
// boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>( magicResistance() ));
// break;
case Bonus::HATE:
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype))));
boost::algorithm::replace_first(text, "%s", VLC->creh->creatures[bonus->subtype]->namePl);
break;
case Bonus::SPELL_AFTER_ATTACK:
case Bonus::SPELL_BEFORE_ATTACK:
{
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype))));
boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name);
break;
}
case Bonus::SPELL_LIKE_ATTACK:
{
boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name);
break;
}
default:
{}//TODO: allow custom bonus types... someday, somehow
}
}
else //short name
{
text = it->second.first;
switch (bonus->type)
{
case Bonus::MANA_CHANNELING:
case Bonus::MAGIC_MIRROR:
case Bonus::CHANGES_SPELL_COST_FOR_ALLY:
case Bonus::CHANGES_SPELL_COST_FOR_ENEMY:
case Bonus::ENEMY_DEFENCE_REDUCTION:
case Bonus::REBIRTH:
case Bonus::DEATH_STARE:
case Bonus::LIFE_DRAIN:
case Bonus::FIRE_SHIELD:
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype))));
break;
case Bonus::HATE:
case Bonus::DAEMON_SUMMONING:
boost::algorithm::replace_first(text, "%s", VLC->creh->creatures[bonus->subtype]->namePl);
break;
case Bonus::LEVEL_SPELL_IMMUNITY:
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(bonus->val));
break;
case Bonus::SPELL_AFTER_ATTACK:
case Bonus::SPELL_BEFORE_ATTACK:
case Bonus::SPELL_IMMUNITY:
case Bonus::SPELLCASTER:
case Bonus::ENCHANTER:
case Bonus::ENCHANTED:
boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name);
break;
case Bonus::MAGIC_RESISTANCE:
text = ""; //handled separately
break;
//case Bonus::SECONDARY_SKILL_PREMY:
// if (bonus->subtype != CGHeroInstance::RESISTANCE || hasBonusOfType(Bonus::MAGIC_RESISTANCE)) //handle it there
// text = "";
// break;
}
}
return text;
return "";
}
else
return "";
{
return VLC->getBth()->bonusToString(bonus, this, description);
}
}
std::string CStackInstance::bonusToGraphics(Bonus *bonus) const
{
std::string fileName;
bool fullPath = false;
switch (bonus->type)
{
//"E_ALIVE.bmp"
//"E_ART.bmp"
case Bonus::ENCHANTED:
fileName = "E_BLESS.bmp"; break;
//"E_BLOCK.bmp"
//"E_BLOCK1.bmp"
//"E_BLOCK2.bmp"
case Bonus::TWO_HEX_ATTACK_BREATH:
fileName = "E_BREATH.bmp"; break;
case Bonus::SPELL_AFTER_ATTACK:
fileName = "E_CAST.bmp"; break;
case Bonus::ENCHANTER:
fileName = "E_CAST1.bmp"; break;
case Bonus::RANDOM_SPELLCASTER:
fileName = "RandomBoost.bmp"; break;
case Bonus::SPELL_BEFORE_ATTACK:
fileName ="E_CAST2.bmp"; break;
case Bonus::SPELLCASTER:
fileName = "E_CASTER.bmp"; break;
case Bonus::JOUSTING:
fileName = "E_CHAMP.bmp"; break;
case Bonus::DOUBLE_DAMAGE_CHANCE:
fileName = "E_DBLOW.bmp"; break;
case Bonus::DEATH_STARE:
fileName = "E_DEATH.bmp"; break;
case Bonus::DEFENSIVE_STANCE:
fileName = "E_DEFBON.bmp"; break;
case Bonus::NO_DISTANCE_PENALTY:
fileName = "E_DIST.bmp"; break;
case Bonus::ADDITIONAL_ATTACK:
fileName = "E_DOUBLE.bmp"; break;
case Bonus::DRAGON_NATURE:
fileName = "E_DRAGON.bmp"; break;
case Bonus::MAGIC_RESISTANCE:
fileName = "E_DWARF.bmp"; break;
case Bonus::SECONDARY_SKILL_PREMY:
if (bonus->subtype == SecondarySkill::RESISTANCE)
{
fileName = "E_DWARF.bmp";
}
break;
case Bonus::FEAR:
fileName = "E_FEAR.bmp"; break;
case Bonus::FEARLESS:
fileName = "E_FEARL.bmp"; break;
case Bonus::FLYING:
fileName = "E_FLY.bmp"; break;
case Bonus::SPELL_DAMAGE_REDUCTION:
fileName = "E_GOLEM.bmp"; break;
case Bonus::RETURN_AFTER_STRIKE:
fileName = "E_HARPY.bmp"; break;
case Bonus::HATE:
fileName = "E_HATE.bmp"; break;
case Bonus::KING1:
fileName = "E_KING1.bmp"; break;
case Bonus::KING2:
fileName = "E_KING2.bmp"; break;
case Bonus::KING3:
fileName = "E_KING3.bmp"; break;
case Bonus::CHANGES_SPELL_COST_FOR_ALLY:
fileName = "E_MANA.bmp"; break;
case Bonus::CHANGES_SPELL_COST_FOR_ENEMY:
fileName = "MagicDamper.bpm"; break;
case Bonus::NO_MELEE_PENALTY:
fileName = "E_MELEE.bmp"; break;
case Bonus::MIND_IMMUNITY:
fileName = "E_MIND.bmp"; break;
case Bonus::SELF_MORALE:
fileName = "E_MINOT.bmp"; break;
case Bonus::NO_MORALE:
fileName = "E_MORAL.bmp"; break;
case Bonus::RECEPTIVE:
fileName = "E_NOFRIM.bmp"; break;
case Bonus::NO_WALL_PENALTY:
fileName = "E_OBST.bmp"; break;
case Bonus::ENEMY_DEFENCE_REDUCTION:
fileName = "E_RDEF.bmp"; break;
case Bonus::REBIRTH:
fileName = "E_REBIRTH.bmp"; break;
case Bonus::BLOCKS_RETALIATION:
fileName = "E_RETAIL.bmp"; break;
case Bonus::UNLIMITED_RETALIATIONS:
case Bonus::ADDITIONAL_RETALIATION:
fileName = "E_RETAIL1.bmp"; break;
case Bonus::ATTACKS_ALL_ADJACENT:
fileName = "E_ROUND.bmp"; break;
//"E_SGNUM.bmp"
//"E_SGTYPE.bmp"
case Bonus::SHOOTER:
fileName = "E_SHOOT.bmp"; break;
case Bonus::FREE_SHOOTING: //shooter is not blocked by enemy
fileName = "E_SHOOTA.bmp"; break;
//"E_SHOOTN.bmp"
case Bonus::SPELL_IMMUNITY:
{
fullPath = true;
const CSpell * sp = SpellID(bonus->subtype).toSpell();
fileName = sp->getIconImmune();
break;
}
//"E_SPAWILL.bmp"
case Bonus::DIRECT_DAMAGE_IMMUNITY:
fileName = "E_SPDIR.bmp"; break;
//"E_SPDISB.bmp"
//"E_SPDISP.bmp"
//"E_SPEATH.bmp"
//"E_SPEATH1.bmp"
case Bonus::FIRE_IMMUNITY:
switch (bonus->subtype)
{
case 0:
fileName = "E_SPFIRE.bmp"; break; //all
case 1:
fileName = "E_SPFIRE1.bmp"; break; //not positive
case 2:
fileName = "E_FIRE.bmp"; break; //direct damage
}
break;
case Bonus::WATER_IMMUNITY:
switch (bonus->subtype)
{
case 0:
fileName = "E_SPWATER.bmp"; break; //all
case 1:
fileName = "E_SPWATER1.bmp"; break; //not positive
case 2:
fileName = "E_SPCOLD.bmp"; break; //direct damage
}
break;
case Bonus::AIR_IMMUNITY:
switch (bonus->subtype)
{
case 0:
fileName = "E_SPAIR.bmp"; break; //all
case 1:
fileName = "E_SPAIR1.bmp"; break; //not positive
case 2:
fileName = "E_LIGHT.bmp"; break;//direct damage
}
break;
case Bonus::EARTH_IMMUNITY:
switch (bonus->subtype)
{
case 0:
fileName = "E_SPEATH.bmp"; break; //all
case 1:
case 2: //no specific icon for direct damage immunity
fileName = "E_SPEATH1.bmp"; break; //not positive
}
break;
case Bonus::LEVEL_SPELL_IMMUNITY:
{
if (vstd::iswithin(bonus->val, 1 , 5))
{
fileName = "E_SPLVL" + boost::lexical_cast<std::string>(bonus->val) + ".bmp";
}
break;
}
//"E_SUMMON.bmp"
//"E_SUMMON1.bmp"
//"E_SUMMON2.bmp"
case Bonus::FULL_HP_REGENERATION:
case Bonus::HP_REGENERATION:
fileName = "E_TROLL.bmp"; break;
case Bonus::UNDEAD:
fileName = "E_UNDEAD.bmp"; break;
case Bonus::SPELL_RESISTANCE_AURA:
fileName = "E_UNIC.bmp"; break;
case Bonus::THREE_HEADED_ATTACK:
fileName = "ThreeHeaded.bmp"; break;
case Bonus::DAEMON_SUMMONING:
fileName = "RiseDemons.bmp"; break;
case Bonus::CHARGE_IMMUNITY:
fileName = "ChargeImmune.bmp"; break;
case Bonus::HEALER:
fileName = "Healer.bmp"; break;
case Bonus::CATAPULT:
fileName = "Catapult.bmp"; break;
case Bonus::MANA_CHANNELING:
fileName = "ManaChannel.bmp"; break;
case Bonus::MANA_DRAIN:
fileName = "ManaDrain.bmp"; break;
case Bonus::LIFE_DRAIN:
fileName = "DrainLife.bmp"; break;
case Bonus::FIRE_SHIELD:
fileName = "FireShield.bmp"; break;
case Bonus::MAGIC_MIRROR:
fileName = "MagicMirror.bmp"; break;
case Bonus::NON_LIVING:
fileName = "NonLiving.bmp"; break;
case Bonus::SPELL_LIKE_ATTACK:
fileName = "SpellLikeAttack.bmp"; break;
}
if(!fileName.empty() && !fullPath)
fileName = "zvs/Lib1.res/" + fileName;
return fileName;
return VLC->getBth()->bonusToGraphics(bonus);
}
void CStackInstance::setArmyObj(const CArmedInstance *ArmyObj)