1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-15 20:03:15 +02:00

Added full parser for Bonus structure, as described in http://wiki.vcmi.eu/index.php?title=Bonus_Format

Untested.
Limiters / propagators are not yet supported.
This commit is contained in:
DjWarmonger
2012-08-23 18:46:43 +00:00
parent c1726be22c
commit d56e7c568a
3 changed files with 175 additions and 25 deletions

View File

@@ -20,6 +20,34 @@
const std::map<std::string, int> bonusNameMap = boost::assign::map_list_of BONUS_LIST;
#undef BONUS_NAME
#define BONUS_VALUE(x) ( #x, Bonus::x )
const std::map<std::string, int> bonusValueMap = boost::assign::map_list_of BONUS_VALUE_LIST;
#undef BONUS_VALUE
#define BONUS_SOURCE(x) ( #x, Bonus::x )
const std::map<std::string, int> bonusSourceMap = boost::assign::map_list_of BONUS_SOURCE_LIST;
#undef BONUS_SOURCE
#define BONUS_ITEM(x) ( #x, Bonus::x )
const std::map<std::string, int> bonusDurationMap = boost::assign::map_list_of
BONUS_ITEM(PERMANENT)
BONUS_ITEM(ONE_BATTLE)
BONUS_ITEM(ONE_DAY)
BONUS_ITEM(ONE_WEEK)
BONUS_ITEM(N_TURNS)
BONUS_ITEM(N_DAYS)
BONUS_ITEM(UNITL_BEING_ATTACKED)
BONUS_ITEM(UNTIL_ATTACK)
BONUS_ITEM(STACK_GETS_TURN)
BONUS_ITEM(COMMANDER_KILLED);
const std::map<std::string, int> bonusLimitEffect = boost::assign::map_list_of
BONUS_ITEM(NO_LIMIT)
BONUS_ITEM(ONLY_DISTANCE_FIGHT)
BONUS_ITEM(ONLY_MELEE_FIGHT)
BONUS_ITEM(ONLY_ENEMY_ARMY);
#define BONUS_LOG_LINE(x) tlog5 << x << std::endl
int CBonusSystemNode::treeChanged = 1;

View File

@@ -176,6 +176,33 @@ typedef boost::function<bool(const Bonus*)> CSelector;
BONUS_NAME(SPOILS_OF_WAR) /*val * 10^-6 * gained exp resources of subtype will be given to hero after battle*/\
BONUS_NAME(BLOCK)
#define BONUS_SOURCE_LIST \
BONUS_SOURCE(ARTIFACT)\
BONUS_SOURCE(ARTIFACT_INSTANCE)\
BONUS_SOURCE(OBJECT)\
BONUS_SOURCE(CREATURE_ABILITY)\
BONUS_SOURCE(TERRAIN_NATIVE)\
BONUS_SOURCE(TERRAIN_OVERLAY)\
BONUS_SOURCE(SPELL_EFFECT)\
BONUS_SOURCE(TOWN_STRUCTURE)\
BONUS_SOURCE(HERO_BASE_SKILL)\
BONUS_SOURCE(SECONDARY_SKILL)\
BONUS_SOURCE(HERO_SPECIAL)\
BONUS_SOURCE(ARMY)\
BONUS_SOURCE(CAMPAIGN_BONUS)\
BONUS_SOURCE(SPECIAL_WEEK)\
BONUS_SOURCE(STACK_EXPERIENCE)\
BONUS_SOURCE(COMMANDER) /*TODO: consider using simply STACK_INSTANCE */\
BONUS_SOURCE(OTHER) /*used for defensive stance and default value of spell level limit*/
#define BONUS_VALUE_LIST \
BONUS_VALUE(ADDITIVE_VALUE)\
BONUS_VALUE(BASE_NUMBER)\
BONUS_VALUE(PERCENT_TO_ALL)\
BONUS_VALUE(PERCENT_TO_BASE)\
BONUS_VALUE(INDEPENDENT_MAX) /*used for SPELL bonus*/ \
BONUS_VALUE(INDEPENDENT_MIN) //used for SECONDARY_SKILL_PREMY bonus
/// Struct for handling bonuses of several types. Can be transferred to any hero
struct DLL_LINKAGE Bonus
{
@@ -200,23 +227,9 @@ struct DLL_LINKAGE Bonus
};
enum BonusSource
{
ARTIFACT,
ARTIFACT_INSTANCE,
OBJECT,
CREATURE_ABILITY,
TERRAIN_NATIVE,
TERRAIN_OVERLAY,
SPELL_EFFECT,
TOWN_STRUCTURE,
HERO_BASE_SKILL,
SECONDARY_SKILL,
HERO_SPECIAL,
ARMY,
CAMPAIGN_BONUS,
SPECIAL_WEEK,
STACK_EXPERIENCE,
COMMANDER, //TODO: consider using simply STACK_INSTANCE
OTHER /*used for defensive stance and default value of spell level limit*/
#define BONUS_SOURCE(x) x,
BONUS_SOURCE_LIST
#undef BONUS_SOURCE
};
enum LimitEffect
@@ -228,12 +241,9 @@ struct DLL_LINKAGE Bonus
enum ValueType
{
ADDITIVE_VALUE,
BASE_NUMBER,
PERCENT_TO_ALL,
PERCENT_TO_BASE,
INDEPENDENT_MAX, //used for SPELL bonus
INDEPENDENT_MIN //used for SECONDARY_SKILL_PREMY bonus
#define BONUS_VALUE(x) x,
BONUS_VALUE_LIST
#undef BONUS_VALUE
};
ui16 duration; //uses BonusDuration values
@@ -854,7 +864,7 @@ namespace Selector
bool DLL_LINKAGE positiveSpellEffects(const Bonus *b);
}
extern DLL_LINKAGE const std::map<std::string, int> bonusNameMap;
extern DLL_LINKAGE const std::map<std::string, int> bonusNameMap, bonusValueMap, bonusSourceMap, bonusDurationMap, bonusLimitEffect;
// BonusList template that requires full interface of CBonusSystemNode
template <class InputIterator>

View File

@@ -889,7 +889,119 @@ Bonus * ParseBonus (const JsonVector &ability_vec) //TODO: merge with AddAbility
b->val = ability_vec[1].Float();
b->subtype = ability_vec[2].Float();
b->additionalInfo = ability_vec[3].Float();
b->duration = Bonus::PERMANENT;
b->duration = Bonus::PERMANENT; //TODO: handle flags (as integer)
b->turnsRemain = 0;
return b;
}
Bonus * ParseBonus (const JsonNode &ability)
{
Bonus * b = new Bonus();
const JsonNode *value;
std::string type = ability["type"].String();
auto it = bonusNameMap.find(type);
if (it == bonusNameMap.end())
{
tlog1 << "Error: invalid ability type " << type << std::endl;
return b;
}
b->type = it->second;
value = &ability["subtype"];
if (!value->isNull())
b->subtype = value->Float();
value = &ability["val"];
if (!value->isNull())
b->val = value->Float();
value = &ability["valueType"];
if (!value->isNull())
{
std::string type = value->String();
auto it = bonusValueMap.find(type);
if (it == bonusValueMap.end())
{
tlog1 << "Error: invalid value type " << type << std::endl;
}
else
{
b->valType = it->second;
}
}
value = &ability["additionalInfo"];
if (!value->isNull())
b->additionalInfo = value->Float();
value = &ability["turns"];
if (!value->isNull())
b->turnsRemain = value->Float();
value = &ability["sourceID"];
if (!value->isNull())
b->sid = value->Float();
value = &ability["description"];
if (!value->isNull())
b->description = value->String();
value = &ability["effectRange"];
if (!value->isNull())
{
std::string type = value->String();
auto it = bonusLimitEffect.find(type);
if (it == bonusLimitEffect.end())
{
tlog1 << "Error: invalid effect range " << type << std::endl;
}
else
{
b->effectRange = it->second;
}
}
value = &ability["duration"];
if (!value->isNull())
{
std::string type = value->String();
auto it = bonusDurationMap.find(type);
if (it == bonusDurationMap.end())
{
tlog1 << "Error: invalid duration type " << type << std::endl;
}
else
{
b->duration = it->second;
}
}
value = &ability["source"];
if (!value->isNull())
{
std::string type = value->String();
auto it = bonusSourceMap.find(type);
if (it == bonusSourceMap.end())
{
tlog1 << "Error: invalid source type " << type << std::endl;
}
else
{
b->source = it->second;
}
}
//TODO:
//value = &ability["limiter"];
//if (!value->isNull())
// b->limiter = value->Float();
//value = &ability["propagator"];
//if (!value->isNull())
// b->propagator = value->Float();
return b;
}