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:
@@ -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;
|
||||
|
@@ -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>
|
||||
|
114
lib/JsonNode.cpp
114
lib/JsonNode.cpp
@@ -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;
|
||||
}
|
Reference in New Issue
Block a user