mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-03 13:01:33 +02:00
vcmi: deprecated bonus converter
It converts almost all sorts of deprecated bonuses from mods when loading json. It can print to console correct new variant or bonus. Also removed a bunch of deprecated bonuses from list. It will break saves!!!
This commit is contained in:
parent
95503d0623
commit
930955f268
@ -1,5 +1,4 @@
|
|||||||
//TODO: selector-based config
|
//TODO: selector-based config
|
||||||
// SECONDARY_SKILL_PREMY
|
|
||||||
// school immunities
|
// school immunities
|
||||||
// LEVEL_SPELL_IMMUNITY
|
// LEVEL_SPELL_IMMUNITY
|
||||||
|
|
||||||
@ -432,12 +431,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"SECONDARY_SKILL_PREMY":
|
|
||||||
{
|
|
||||||
"hidden": true
|
|
||||||
//todo: selector based config
|
|
||||||
},
|
|
||||||
|
|
||||||
"SELF_LUCK":
|
"SELF_LUCK":
|
||||||
{
|
{
|
||||||
"graphics":
|
"graphics":
|
||||||
|
@ -555,12 +555,17 @@ std::vector<std::shared_ptr<Bonus>> SpecialtyInfoToBonuses(const SSpecialtyInfo
|
|||||||
AddSpecialtyForCreature(spec.additionalinfo, bonus, result);
|
AddSpecialtyForCreature(spec.additionalinfo, bonus, result);
|
||||||
break;
|
break;
|
||||||
case 2: //secondary skill
|
case 2: //secondary skill
|
||||||
bonus->type = Bonus::SECONDARY_SKILL_PREMY;
|
{
|
||||||
bonus->valType = Bonus::PERCENT_TO_BASE;
|
auto params = BonusParams("SECONDARY_SKILL_PREMY", "", spec.subtype);
|
||||||
bonus->subtype = spec.subtype;
|
bonus->type = params.type;
|
||||||
bonus->updater.reset(new TimesHeroLevelUpdater());
|
if(params.subtypeRelevant)
|
||||||
result.push_back(bonus);
|
bonus->subtype = params.subtype;
|
||||||
break;
|
bonus->valType = Bonus::PERCENT_TO_TARGET_TYPE;
|
||||||
|
bonus->targetSourceType = Bonus::SECONDARY_SKILL;
|
||||||
|
bonus->updater.reset(new TimesHeroLevelUpdater());
|
||||||
|
result.push_back(bonus);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 3: //spell damage bonus, level dependent but calculated elsewhere
|
case 3: //spell damage bonus, level dependent but calculated elsewhere
|
||||||
bonus->type = Bonus::SPECIAL_SPELL_LEV;
|
bonus->type = Bonus::SPECIAL_SPELL_LEV;
|
||||||
bonus->subtype = spec.subtype;
|
bonus->subtype = spec.subtype;
|
||||||
|
@ -34,7 +34,6 @@ VCMI_LIB_NAMESPACE_BEGIN
|
|||||||
#define BONUS_NAME(x) { #x, Bonus::x },
|
#define BONUS_NAME(x) { #x, Bonus::x },
|
||||||
const std::map<std::string, Bonus::BonusType> bonusNameMap = {
|
const std::map<std::string, Bonus::BonusType> bonusNameMap = {
|
||||||
BONUS_LIST
|
BONUS_LIST
|
||||||
{"SIGHT_RADIOUS", Bonus::SIGHT_RADIUS} /*the correct word is RADIUS, but this one's already used in mods. Deprecated. */
|
|
||||||
};
|
};
|
||||||
#undef BONUS_NAME
|
#undef BONUS_NAME
|
||||||
|
|
||||||
@ -99,6 +98,21 @@ const std::map<std::string, TUpdaterPtr> bonusUpdaterMap =
|
|||||||
{"ARMY_MOVEMENT", std::make_shared<ArmyMovementUpdater>()}
|
{"ARMY_MOVEMENT", std::make_shared<ArmyMovementUpdater>()}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::set<std::string> deprecatedBonusSet = {
|
||||||
|
"SECONDARY_SKILL_PREMY",
|
||||||
|
"SECONDARY_SKILL_VAL2",
|
||||||
|
"MAXED_SPELL",
|
||||||
|
"LAND_MOVEMENT",
|
||||||
|
"SEA_MOVEMENT",
|
||||||
|
"SIGHT_RADIOUS",
|
||||||
|
"NO_TYPE",
|
||||||
|
"SPECIAL_SECONDARY_SKILL",
|
||||||
|
"FULL_HP_REGENERATION",
|
||||||
|
"KING1",
|
||||||
|
"KING2",
|
||||||
|
"KING3",
|
||||||
|
};
|
||||||
|
|
||||||
///CBonusProxy
|
///CBonusProxy
|
||||||
CBonusProxy::CBonusProxy(const IBonusBearer * Target, CSelector Selector)
|
CBonusProxy::CBonusProxy(const IBonusBearer * Target, CSelector Selector)
|
||||||
: bonusListCachedLast(0),
|
: bonusListCachedLast(0),
|
||||||
@ -1655,8 +1669,6 @@ JsonNode subtypeToJson(Bonus::BonusType type, int subtype)
|
|||||||
{
|
{
|
||||||
case Bonus::PRIMARY_SKILL:
|
case Bonus::PRIMARY_SKILL:
|
||||||
return JsonUtils::stringNode("primSkill." + PrimarySkill::names[subtype]);
|
return JsonUtils::stringNode("primSkill." + PrimarySkill::names[subtype]);
|
||||||
case Bonus::SECONDARY_SKILL_PREMY:
|
|
||||||
return JsonUtils::stringNode(CSkillHandler::encodeSkillWithType(subtype));
|
|
||||||
case Bonus::SPECIAL_SPELL_LEV:
|
case Bonus::SPECIAL_SPELL_LEV:
|
||||||
case Bonus::SPECIFIC_SPELL_DAMAGE:
|
case Bonus::SPECIFIC_SPELL_DAMAGE:
|
||||||
case Bonus::SPELL:
|
case Bonus::SPELL:
|
||||||
@ -1762,8 +1774,6 @@ std::string Bonus::nameForBonus() const
|
|||||||
{
|
{
|
||||||
case Bonus::PRIMARY_SKILL:
|
case Bonus::PRIMARY_SKILL:
|
||||||
return PrimarySkill::names[subtype];
|
return PrimarySkill::names[subtype];
|
||||||
case Bonus::SECONDARY_SKILL_PREMY:
|
|
||||||
return CSkillHandler::encodeSkill(subtype);
|
|
||||||
case Bonus::SPECIAL_SPELL_LEV:
|
case Bonus::SPECIAL_SPELL_LEV:
|
||||||
case Bonus::SPECIFIC_SPELL_DAMAGE:
|
case Bonus::SPECIFIC_SPELL_DAMAGE:
|
||||||
case Bonus::SPELL:
|
case Bonus::SPELL:
|
||||||
@ -1782,6 +1792,212 @@ std::string Bonus::nameForBonus() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSubtypeStr, int deprecatedSubtype):
|
||||||
|
isConverted(true)
|
||||||
|
{
|
||||||
|
if(deprecatedTypeStr == "SECONDARY_SKILL_PREMY" || deprecatedTypeStr == "SPECIAL_SECONDARY_SKILL")
|
||||||
|
{
|
||||||
|
if(deprecatedSubtype == SecondarySkill::PATHFINDING || deprecatedSubtypeStr == "skill.pathfinding")
|
||||||
|
type = Bonus::ROUGH_TERRAIN_DISCOUNT;
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::DIPLOMACY || deprecatedSubtypeStr == "skill.diplomacy")
|
||||||
|
type = Bonus::WANDERING_CREATURES_JOIN_BONUS;
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::WISDOM || deprecatedSubtypeStr == "skill.wisdom")
|
||||||
|
type = Bonus::MAX_LEARNABLE_SPELL_LEVEL;
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::MYSTICISM || deprecatedSubtypeStr == "skill.mysticism")
|
||||||
|
type = Bonus::MANA_REGENERATION;
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::NECROMANCY || deprecatedSubtypeStr == "skill.necromancy")
|
||||||
|
type = Bonus::UNDEAD_RAISE_PERCENTAGE;
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::LEARNING || deprecatedSubtypeStr == "skill.learning")
|
||||||
|
type = Bonus::HERO_EXPERIENCE_GAIN_PERCENT;
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::RESISTANCE || deprecatedSubtypeStr == "skill.resistance")
|
||||||
|
type = Bonus::MAGIC_RESISTANCE;
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::EAGLE_EYE || deprecatedSubtypeStr == "skill.eagleEye")
|
||||||
|
type = Bonus::LEARN_BATTLE_SPELL_CHANCE;
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::INTELLIGENCE || deprecatedSubtypeStr == "skill.intelligence")
|
||||||
|
{
|
||||||
|
type = Bonus::MANA_PER_KNOWLEDGE;
|
||||||
|
valueType = Bonus::PERCENT_TO_BASE;
|
||||||
|
valueTypeRelevant = true;
|
||||||
|
}
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::SORCERY || deprecatedSubtypeStr == "skill.sorcery")
|
||||||
|
type = Bonus::SPELL_DAMAGE;
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::SCHOLAR || deprecatedSubtypeStr == "skill.scholar")
|
||||||
|
type = Bonus::LEARN_MEETING_SPELL_LIMIT;
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::ARCHERY|| deprecatedSubtypeStr == "skill.archery")
|
||||||
|
{
|
||||||
|
subtype = 1;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
type = Bonus::PERCENTAGE_DAMAGE_BOOST;
|
||||||
|
}
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::OFFENCE || deprecatedSubtypeStr == "skill.offence")
|
||||||
|
{
|
||||||
|
subtype = 0;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
type = Bonus::PERCENTAGE_DAMAGE_BOOST;
|
||||||
|
}
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::ARMORER || deprecatedSubtypeStr == "skill.armorer")
|
||||||
|
{
|
||||||
|
subtype = -1;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
type = Bonus::GENERAL_DAMAGE_REDUCTION;
|
||||||
|
}
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::NAVIGATION || deprecatedSubtypeStr == "skill.navigation")
|
||||||
|
{
|
||||||
|
subtype = 0;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
valueType = Bonus::PERCENT_TO_BASE;
|
||||||
|
valueTypeRelevant = true;
|
||||||
|
type = Bonus::MOVEMENT;
|
||||||
|
}
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::LOGISTICS || deprecatedSubtypeStr == "skill.logistics")
|
||||||
|
{
|
||||||
|
subtype = 0;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
valueType = Bonus::PERCENT_TO_BASE;
|
||||||
|
valueTypeRelevant = true;
|
||||||
|
type = Bonus::MOVEMENT;
|
||||||
|
}
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::ESTATES || deprecatedSubtypeStr == "skill.estates")
|
||||||
|
{
|
||||||
|
type = Bonus::GENERATE_RESOURCE;
|
||||||
|
subtype = Res::GOLD;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
}
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::AIR_MAGIC || deprecatedSubtypeStr == "skill.airMagic")
|
||||||
|
{
|
||||||
|
type = Bonus::MAGIC_SCHOOL_SKILL;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
subtype = 4;
|
||||||
|
}
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::WATER_MAGIC || deprecatedSubtypeStr == "skill.waterMagic")
|
||||||
|
{
|
||||||
|
type = Bonus::MAGIC_SCHOOL_SKILL;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
subtype = 1;
|
||||||
|
}
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::FIRE_MAGIC || deprecatedSubtypeStr == "skill.fireMagic")
|
||||||
|
{
|
||||||
|
type = Bonus::MAGIC_SCHOOL_SKILL;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
subtype = 2;
|
||||||
|
}
|
||||||
|
else if(deprecatedSubtype == SecondarySkill::EARTH_MAGIC || deprecatedSubtypeStr == "skill.earthMagic")
|
||||||
|
{
|
||||||
|
type = Bonus::MAGIC_SCHOOL_SKILL;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
subtype = 8;
|
||||||
|
}
|
||||||
|
else if (deprecatedSubtype == SecondarySkill::ARTILLERY || deprecatedSubtypeStr == "skill.artillery")
|
||||||
|
{
|
||||||
|
type = Bonus::BONUS_DAMAGE_CHANCE;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
subtypeStr = "core:creature.ballista";
|
||||||
|
}
|
||||||
|
else if (deprecatedSubtype == SecondarySkill::FIRST_AID || deprecatedSubtypeStr == "skill.firstAid")
|
||||||
|
{
|
||||||
|
type = Bonus::SPECIFIC_SPELL_POWER;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
subtypeStr = "core:spell.firstAid";
|
||||||
|
}
|
||||||
|
else if (deprecatedSubtype == SecondarySkill::BALLISTICS || deprecatedSubtypeStr == "skill.ballistics")
|
||||||
|
{
|
||||||
|
type = Bonus::CATAPULT_EXTRA_SHOTS;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
subtypeStr = "core:spell.catapultShot";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
isConverted = false;
|
||||||
|
}
|
||||||
|
else if (deprecatedTypeStr == "SECONDARY_SKILL_VAL2")
|
||||||
|
{
|
||||||
|
if(deprecatedSubtype == SecondarySkill::EAGLE_EYE || deprecatedSubtypeStr == "skill.eagleEye")
|
||||||
|
type = Bonus::LEARN_BATTLE_SPELL_LEVEL_LIMIT;
|
||||||
|
else if (deprecatedSubtype == SecondarySkill::ARTILLERY || deprecatedSubtypeStr == "skill.artillery")
|
||||||
|
{
|
||||||
|
type = Bonus::HERO_GRANTS_ATTACKS;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
subtypeStr = "core:creature.ballista";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
isConverted = false;
|
||||||
|
}
|
||||||
|
else if (deprecatedTypeStr == "SEA_MOVEMENT")
|
||||||
|
{
|
||||||
|
subtype = 0;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
valueType = Bonus::ADDITIVE_VALUE;
|
||||||
|
valueTypeRelevant = true;
|
||||||
|
type = Bonus::MOVEMENT;
|
||||||
|
}
|
||||||
|
else if (deprecatedTypeStr == "LAND_MOVEMENT")
|
||||||
|
{
|
||||||
|
subtype = 1;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
valueType = Bonus::ADDITIVE_VALUE;
|
||||||
|
valueTypeRelevant = true;
|
||||||
|
type = Bonus::MOVEMENT;
|
||||||
|
}
|
||||||
|
else if (deprecatedTypeStr == "MAXED_SPELL")
|
||||||
|
{
|
||||||
|
type = Bonus::SPELL;
|
||||||
|
subtypeStr = deprecatedSubtypeStr;
|
||||||
|
subtypeRelevant = true;
|
||||||
|
valueType = Bonus::INDEPENDENT_MAX;
|
||||||
|
valueTypeRelevant = true;
|
||||||
|
val = 3;
|
||||||
|
valRelevant = true;
|
||||||
|
}
|
||||||
|
else if (deprecatedTypeStr == "FULL_HP_REGENERATION")
|
||||||
|
{
|
||||||
|
type = Bonus::HP_REGENERATION;
|
||||||
|
val = 100000; //very high value to always chose stack health
|
||||||
|
valRelevant = true;
|
||||||
|
}
|
||||||
|
else if (deprecatedTypeStr == "KING1")
|
||||||
|
{
|
||||||
|
type = Bonus::KING;
|
||||||
|
val = 0;
|
||||||
|
valRelevant = true;
|
||||||
|
}
|
||||||
|
else if (deprecatedTypeStr == "KING2")
|
||||||
|
{
|
||||||
|
type = Bonus::KING;
|
||||||
|
val = 2;
|
||||||
|
valRelevant = true;
|
||||||
|
}
|
||||||
|
else if (deprecatedTypeStr == "KING3")
|
||||||
|
{
|
||||||
|
type = Bonus::KING;
|
||||||
|
val = 3;
|
||||||
|
valRelevant = true;
|
||||||
|
}
|
||||||
|
else if (deprecatedTypeStr == "SIGHT_RADIOUS")
|
||||||
|
type = Bonus::SIGHT_RADIUS;
|
||||||
|
else
|
||||||
|
isConverted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const JsonNode & BonusParams::toJson()
|
||||||
|
{
|
||||||
|
assert(isConverted);
|
||||||
|
if(ret.isNull())
|
||||||
|
{
|
||||||
|
ret["type"].String() = vstd::findKey(bonusNameMap, type);
|
||||||
|
if(subtypeRelevant && !subtypeStr.empty())
|
||||||
|
ret["subtype"].String() = subtypeStr;
|
||||||
|
else if(subtypeRelevant)
|
||||||
|
ret["subtype"].Integer() = subtype;
|
||||||
|
if(valueTypeRelevant)
|
||||||
|
ret["valueType"].String() = vstd::findKey(bonusValueMap, valueType);
|
||||||
|
if(valRelevant)
|
||||||
|
ret["val"].Float() = val;
|
||||||
|
if(targetTypeRelevant)
|
||||||
|
ret["targetSourceType"].String() = vstd::findKey(bonusSourceMap, targetType);
|
||||||
|
jsonCreated = true;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
Bonus::Bonus(Bonus::BonusDuration Duration, BonusType Type, BonusSource Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype)
|
Bonus::Bonus(Bonus::BonusDuration Duration, BonusType Type, BonusSource Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype)
|
||||||
: duration((ui16)Duration), type(Type), subtype(Subtype), source(Src), val(Val), sid(ID), description(Desc)
|
: duration((ui16)Duration), type(Type), subtype(Subtype), source(Src), val(Val), sid(ID), description(Desc)
|
||||||
{
|
{
|
||||||
|
@ -179,7 +179,6 @@ public:
|
|||||||
BONUS_NAME(MANA_REGENERATION) /*points per turn apart from normal (1 + mysticism)*/ \
|
BONUS_NAME(MANA_REGENERATION) /*points per turn apart from normal (1 + mysticism)*/ \
|
||||||
BONUS_NAME(FULL_MANA_REGENERATION) /*all mana points are replenished every day*/ \
|
BONUS_NAME(FULL_MANA_REGENERATION) /*all mana points are replenished every day*/ \
|
||||||
BONUS_NAME(NONEVIL_ALIGNMENT_MIX) /*good and neutral creatures can be mixed without morale penalty*/ \
|
BONUS_NAME(NONEVIL_ALIGNMENT_MIX) /*good and neutral creatures can be mixed without morale penalty*/ \
|
||||||
BONUS_NAME(SECONDARY_SKILL_PREMY) /*%*/ \
|
|
||||||
BONUS_NAME(SURRENDER_DISCOUNT) /*%*/ \
|
BONUS_NAME(SURRENDER_DISCOUNT) /*%*/ \
|
||||||
BONUS_NAME(STACKS_SPEED) /*additional info - percent of speed bonus applied after direct bonuses; >0 - added, <0 - subtracted to this part*/ \
|
BONUS_NAME(STACKS_SPEED) /*additional info - percent of speed bonus applied after direct bonuses; >0 - added, <0 - subtracted to this part*/ \
|
||||||
BONUS_NAME(FLYING_MOVEMENT) /*value - penalty percentage*/ \
|
BONUS_NAME(FLYING_MOVEMENT) /*value - penalty percentage*/ \
|
||||||
@ -209,7 +208,6 @@ public:
|
|||||||
BONUS_NAME(IMPROVED_NECROMANCY) /* raise more powerful creatures: subtype - creature type raised, addInfo - [required necromancy level, required stack level], val - necromancy level for this purpose */ \
|
BONUS_NAME(IMPROVED_NECROMANCY) /* raise more powerful creatures: subtype - creature type raised, addInfo - [required necromancy level, required stack level], val - necromancy level for this purpose */ \
|
||||||
BONUS_NAME(CREATURE_GROWTH_PERCENT) /*increases growth of all units in all towns, val - percentage*/ \
|
BONUS_NAME(CREATURE_GROWTH_PERCENT) /*increases growth of all units in all towns, val - percentage*/ \
|
||||||
BONUS_NAME(FREE_SHIP_BOARDING) /*movement points preserved with ship boarding and landing*/ \
|
BONUS_NAME(FREE_SHIP_BOARDING) /*movement points preserved with ship boarding and landing*/ \
|
||||||
BONUS_NAME(NO_TYPE) \
|
|
||||||
BONUS_NAME(FLYING) \
|
BONUS_NAME(FLYING) \
|
||||||
BONUS_NAME(SHOOTER) \
|
BONUS_NAME(SHOOTER) \
|
||||||
BONUS_NAME(CHARGE_IMMUNITY) \
|
BONUS_NAME(CHARGE_IMMUNITY) \
|
||||||
@ -281,7 +279,6 @@ public:
|
|||||||
BONUS_NAME(NO_LUCK) /*eg. when fighting on cursed ground*/ \
|
BONUS_NAME(NO_LUCK) /*eg. when fighting on cursed ground*/ \
|
||||||
BONUS_NAME(NO_MORALE) /*eg. when fighting on cursed ground*/ \
|
BONUS_NAME(NO_MORALE) /*eg. when fighting on cursed ground*/ \
|
||||||
BONUS_NAME(DARKNESS) /*val = radius */ \
|
BONUS_NAME(DARKNESS) /*val = radius */ \
|
||||||
BONUS_NAME(SPECIAL_SECONDARY_SKILL) /*subtype = id, val = value per level in percent*/ \
|
|
||||||
BONUS_NAME(SPECIAL_SPELL_LEV) /*subtype = id, val = value per level in percent*/\
|
BONUS_NAME(SPECIAL_SPELL_LEV) /*subtype = id, val = value per level in percent*/\
|
||||||
BONUS_NAME(SPELL_DAMAGE) /*val = value, now works for sorcery*/\
|
BONUS_NAME(SPELL_DAMAGE) /*val = value, now works for sorcery*/\
|
||||||
BONUS_NAME(SPECIFIC_SPELL_DAMAGE) /*subtype = id of spell, val = value*/\
|
BONUS_NAME(SPECIFIC_SPELL_DAMAGE) /*subtype = id of spell, val = value*/\
|
||||||
@ -315,7 +312,6 @@ public:
|
|||||||
BONUS_NAME(CATAPULT_EXTRA_SHOTS) /*val - power of catapult effect, requires CATAPULT bonus to work*/\
|
BONUS_NAME(CATAPULT_EXTRA_SHOTS) /*val - power of catapult effect, requires CATAPULT bonus to work*/\
|
||||||
BONUS_NAME(RANGED_RETALIATION) /*allows shooters to perform ranged retaliation*/\
|
BONUS_NAME(RANGED_RETALIATION) /*allows shooters to perform ranged retaliation*/\
|
||||||
BONUS_NAME(BLOCKS_RANGED_RETALIATION) /*disallows ranged retaliation for shooter unit, BLOCKS_RETALIATION bonus is for melee retaliation only*/\
|
BONUS_NAME(BLOCKS_RANGED_RETALIATION) /*disallows ranged retaliation for shooter unit, BLOCKS_RETALIATION bonus is for melee retaliation only*/\
|
||||||
BONUS_NAME(SECONDARY_SKILL_VAL2) /*deprecated. has no effect, will be converted to actual bonus*/ \
|
|
||||||
BONUS_NAME(MANUAL_CONTROL) /* manually control warmachine with id = subtype, chance = val */ \
|
BONUS_NAME(MANUAL_CONTROL) /* manually control warmachine with id = subtype, chance = val */ \
|
||||||
BONUS_NAME(WIDE_BREATH) /* initial desigh: dragon breath affecting multiple nearby hexes */\
|
BONUS_NAME(WIDE_BREATH) /* initial desigh: dragon breath affecting multiple nearby hexes */\
|
||||||
BONUS_NAME(FIRST_STRIKE) /* first counterattack, then attack if possible */\
|
BONUS_NAME(FIRST_STRIKE) /* first counterattack, then attack if possible */\
|
||||||
@ -542,6 +538,27 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
|
|||||||
|
|
||||||
DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus);
|
DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus);
|
||||||
|
|
||||||
|
struct DLL_LINKAGE BonusParams {
|
||||||
|
bool isConverted;
|
||||||
|
Bonus::BonusType type = Bonus::NONE;
|
||||||
|
TBonusSubtype subtype = -1;
|
||||||
|
std::string subtypeStr = "";
|
||||||
|
bool subtypeRelevant = false;
|
||||||
|
Bonus::ValueType valueType = Bonus::BASE_NUMBER;
|
||||||
|
bool valueTypeRelevant = false;
|
||||||
|
si32 val = 0;
|
||||||
|
bool valRelevant = false;
|
||||||
|
Bonus::BonusSource targetType = Bonus::SECONDARY_SKILL;
|
||||||
|
bool targetTypeRelevant = false;
|
||||||
|
|
||||||
|
BonusParams(bool isConverted = true) : isConverted(isConverted) {};
|
||||||
|
BonusParams(std::string deprecatedTypeStr, std::string deprecatedSubtypeStr = "", int deprecatedSubtype = 0);
|
||||||
|
const JsonNode & toJson();
|
||||||
|
private:
|
||||||
|
JsonNode ret;
|
||||||
|
bool jsonCreated = false;
|
||||||
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE BonusList
|
class DLL_LINKAGE BonusList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -1232,6 +1249,7 @@ extern DLL_LINKAGE const std::map<std::string, Bonus::LimitEffect> bonusLimitEff
|
|||||||
extern DLL_LINKAGE const std::map<std::string, TLimiterPtr> bonusLimiterMap;
|
extern DLL_LINKAGE const std::map<std::string, TLimiterPtr> bonusLimiterMap;
|
||||||
extern DLL_LINKAGE const std::map<std::string, TPropagatorPtr> bonusPropagatorMap;
|
extern DLL_LINKAGE const std::map<std::string, TPropagatorPtr> bonusPropagatorMap;
|
||||||
extern DLL_LINKAGE const std::map<std::string, TUpdaterPtr> bonusUpdaterMap;
|
extern DLL_LINKAGE const std::map<std::string, TUpdaterPtr> bonusUpdaterMap;
|
||||||
|
extern DLL_LINKAGE const std::set<std::string> deprecatedBonusSet;
|
||||||
|
|
||||||
// BonusList template that requires full interface of CBonusSystemNode
|
// BonusList template that requires full interface of CBonusSystemNode
|
||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
|
@ -805,26 +805,82 @@ std::shared_ptr<Bonus> JsonUtils::parseBuildingBonus(const JsonNode &ability, Bu
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BonusParams convertDeprecatedBonus(const JsonNode &ability)
|
||||||
|
{
|
||||||
|
if(vstd::contains(deprecatedBonusSet, ability["type"].String()))
|
||||||
|
{
|
||||||
|
logMod->warn("There is deprecated bonus found:\n%s\nTrying to convert...", ability.toJson());
|
||||||
|
auto params = BonusParams(ability["type"].String(),
|
||||||
|
ability["subtype"].isString() ? ability["subtype"].String() : "",
|
||||||
|
ability["subtype"].isNumber() ? ability["subtype"].Integer() : -1);
|
||||||
|
if(params.isConverted)
|
||||||
|
{
|
||||||
|
if(!params.valRelevant) {
|
||||||
|
params.val = static_cast<si32>(ability["val"].Float());
|
||||||
|
params.valRelevant = true;
|
||||||
|
if(params.type == Bonus::SPECIFIC_SPELL_POWER) //First Aid value should be substracted by 10
|
||||||
|
params.val -= 10; //Base First Aid value
|
||||||
|
}
|
||||||
|
Bonus::ValueType valueType = Bonus::ADDITIVE_VALUE;
|
||||||
|
if(!ability["valueType"].isNull())
|
||||||
|
valueType = bonusValueMap.find(ability["valueType"].String())->second;
|
||||||
|
|
||||||
|
if(ability["type"].String() == "SECONDARY_SKILL_PREMY" && valueType == Bonus::PERCENT_TO_BASE) //assume secondary skill special
|
||||||
|
{
|
||||||
|
params.valueType = Bonus::PERCENT_TO_TARGET_TYPE;
|
||||||
|
params.targetType = Bonus::SECONDARY_SKILL;
|
||||||
|
params.targetTypeRelevant = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!params.valueTypeRelevant) {
|
||||||
|
params.valueType = valueType;
|
||||||
|
params.valueTypeRelevant = true;
|
||||||
|
}
|
||||||
|
logMod->warn("Please, use this bonus:\n%s\nConverted sucessfully!", params.toJson().toJson());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
logMod->error("Cannot convert bonus!\n%s", ability.toJson());
|
||||||
|
}
|
||||||
|
BonusParams ret;
|
||||||
|
ret.isConverted = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b)
|
bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b)
|
||||||
{
|
{
|
||||||
const JsonNode *value;
|
const JsonNode *value;
|
||||||
|
|
||||||
std::string type = ability["type"].String();
|
std::string type = ability["type"].String();
|
||||||
auto it = bonusNameMap.find(type);
|
auto it = bonusNameMap.find(type);
|
||||||
|
auto params = std::make_unique<BonusParams>(false);
|
||||||
if (it == bonusNameMap.end())
|
if (it == bonusNameMap.end())
|
||||||
{
|
{
|
||||||
logMod->error("Error: invalid ability type %s.", type);
|
params = std::make_unique<BonusParams>(convertDeprecatedBonus(ability));
|
||||||
return false;
|
if(!params->isConverted)
|
||||||
|
{
|
||||||
|
logMod->error("Error: invalid ability type %s.", type);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
b->type = params->type;
|
||||||
|
b->val = params->val;
|
||||||
|
b->valType = params->valueType;
|
||||||
|
if(params->targetTypeRelevant)
|
||||||
|
b->targetSourceType = params->targetType;
|
||||||
}
|
}
|
||||||
b->type = it->second;
|
else
|
||||||
|
b->type = it->second;
|
||||||
|
|
||||||
resolveIdentifier(b->subtype, ability, "subtype");
|
resolveIdentifier(b->subtype, params->isConverted ? params->toJson() : ability, "subtype");
|
||||||
|
|
||||||
b->val = static_cast<si32>(ability["val"].Float());
|
if(!params->isConverted)
|
||||||
|
{
|
||||||
|
b->val = static_cast<si32>(ability["val"].Float());
|
||||||
|
|
||||||
value = &ability["valueType"];
|
value = &ability["valueType"];
|
||||||
if (!value->isNull())
|
if (!value->isNull())
|
||||||
b->valType = static_cast<Bonus::ValueType>(parseByMapN(bonusValueMap, value, "value type "));
|
b->valType = static_cast<Bonus::ValueType>(parseByMapN(bonusValueMap, value, "value type "));
|
||||||
|
}
|
||||||
|
|
||||||
b->stacking = ability["stacking"].String();
|
b->stacking = ability["stacking"].String();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user