2023-04-30 16:35:15 +02:00
|
|
|
/*
|
|
|
|
* BonusParams.cpp, part of VCMI engine
|
|
|
|
*
|
|
|
|
* Authors: listed in file AUTHORS in main folder
|
|
|
|
*
|
|
|
|
* License: GNU General Public License v2.0 or later
|
|
|
|
* Full text of license available in license.txt file, in main folder
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "StdInc.h"
|
|
|
|
|
|
|
|
#include "BonusParams.h"
|
2023-04-30 21:55:04 +02:00
|
|
|
#include "BonusSelector.h"
|
2023-04-30 16:35:15 +02:00
|
|
|
|
|
|
|
#include "../ResourceSet.h"
|
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
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")
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::ROUGH_TERRAIN_DISCOUNT;
|
2023-04-30 16:35:15 +02:00
|
|
|
else if(deprecatedSubtype == SecondarySkill::DIPLOMACY || deprecatedSubtypeStr == "skill.diplomacy")
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::WANDERING_CREATURES_JOIN_BONUS;
|
2023-04-30 16:35:15 +02:00
|
|
|
else if(deprecatedSubtype == SecondarySkill::WISDOM || deprecatedSubtypeStr == "skill.wisdom")
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::MAX_LEARNABLE_SPELL_LEVEL;
|
2023-04-30 16:35:15 +02:00
|
|
|
else if(deprecatedSubtype == SecondarySkill::MYSTICISM || deprecatedSubtypeStr == "skill.mysticism")
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::MANA_REGENERATION;
|
2023-04-30 16:35:15 +02:00
|
|
|
else if(deprecatedSubtype == SecondarySkill::NECROMANCY || deprecatedSubtypeStr == "skill.necromancy")
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::UNDEAD_RAISE_PERCENTAGE;
|
2023-04-30 16:35:15 +02:00
|
|
|
else if(deprecatedSubtype == SecondarySkill::LEARNING || deprecatedSubtypeStr == "skill.learning")
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::HERO_EXPERIENCE_GAIN_PERCENT;
|
2023-04-30 16:35:15 +02:00
|
|
|
else if(deprecatedSubtype == SecondarySkill::RESISTANCE || deprecatedSubtypeStr == "skill.resistance")
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::MAGIC_RESISTANCE;
|
2023-04-30 16:35:15 +02:00
|
|
|
else if(deprecatedSubtype == SecondarySkill::EAGLE_EYE || deprecatedSubtypeStr == "skill.eagleEye")
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::LEARN_BATTLE_SPELL_CHANCE;
|
2023-04-30 16:35:15 +02:00
|
|
|
else if(deprecatedSubtype == SecondarySkill::SCOUTING || deprecatedSubtypeStr == "skill.scouting")
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::SIGHT_RADIUS;
|
2023-04-30 16:35:15 +02:00
|
|
|
else if(deprecatedSubtype == SecondarySkill::INTELLIGENCE || deprecatedSubtypeStr == "skill.intelligence")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::MANA_PER_KNOWLEDGE;
|
|
|
|
valueType = BonusValueType::PERCENT_TO_BASE;
|
2023-04-30 16:35:15 +02:00
|
|
|
valueTypeRelevant = true;
|
|
|
|
}
|
|
|
|
else if(deprecatedSubtype == SecondarySkill::SORCERY || deprecatedSubtypeStr == "skill.sorcery")
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::SPELL_DAMAGE;
|
2023-04-30 16:35:15 +02:00
|
|
|
else if(deprecatedSubtype == SecondarySkill::SCHOLAR || deprecatedSubtypeStr == "skill.scholar")
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::LEARN_MEETING_SPELL_LIMIT;
|
2023-04-30 16:35:15 +02:00
|
|
|
else if(deprecatedSubtype == SecondarySkill::ARCHERY|| deprecatedSubtypeStr == "skill.archery")
|
|
|
|
{
|
|
|
|
subtype = 1;
|
|
|
|
subtypeRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::PERCENTAGE_DAMAGE_BOOST;
|
2023-04-30 16:35:15 +02:00
|
|
|
}
|
|
|
|
else if(deprecatedSubtype == SecondarySkill::OFFENCE || deprecatedSubtypeStr == "skill.offence")
|
|
|
|
{
|
|
|
|
subtype = 0;
|
|
|
|
subtypeRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::PERCENTAGE_DAMAGE_BOOST;
|
2023-04-30 16:35:15 +02:00
|
|
|
}
|
|
|
|
else if(deprecatedSubtype == SecondarySkill::ARMORER || deprecatedSubtypeStr == "skill.armorer")
|
|
|
|
{
|
|
|
|
subtype = -1;
|
|
|
|
subtypeRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::GENERAL_DAMAGE_REDUCTION;
|
2023-04-30 16:35:15 +02:00
|
|
|
}
|
|
|
|
else if(deprecatedSubtype == SecondarySkill::NAVIGATION || deprecatedSubtypeStr == "skill.navigation")
|
|
|
|
{
|
|
|
|
subtype = 0;
|
|
|
|
subtypeRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
valueType = BonusValueType::PERCENT_TO_BASE;
|
2023-04-30 16:35:15 +02:00
|
|
|
valueTypeRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::MOVEMENT;
|
2023-04-30 16:35:15 +02:00
|
|
|
}
|
|
|
|
else if(deprecatedSubtype == SecondarySkill::LOGISTICS || deprecatedSubtypeStr == "skill.logistics")
|
|
|
|
{
|
|
|
|
subtype = 1;
|
|
|
|
subtypeRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
valueType = BonusValueType::PERCENT_TO_BASE;
|
2023-04-30 16:35:15 +02:00
|
|
|
valueTypeRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::MOVEMENT;
|
2023-04-30 16:35:15 +02:00
|
|
|
}
|
|
|
|
else if(deprecatedSubtype == SecondarySkill::ESTATES || deprecatedSubtypeStr == "skill.estates")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::GENERATE_RESOURCE;
|
2023-04-30 16:35:15 +02:00
|
|
|
subtype = GameResID(EGameResID::GOLD);
|
|
|
|
subtypeRelevant = true;
|
|
|
|
}
|
|
|
|
else if(deprecatedSubtype == SecondarySkill::AIR_MAGIC || deprecatedSubtypeStr == "skill.airMagic")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::MAGIC_SCHOOL_SKILL;
|
2023-04-30 16:35:15 +02:00
|
|
|
subtypeRelevant = true;
|
|
|
|
subtype = 4;
|
|
|
|
}
|
|
|
|
else if(deprecatedSubtype == SecondarySkill::WATER_MAGIC || deprecatedSubtypeStr == "skill.waterMagic")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::MAGIC_SCHOOL_SKILL;
|
2023-04-30 16:35:15 +02:00
|
|
|
subtypeRelevant = true;
|
|
|
|
subtype = 1;
|
|
|
|
}
|
|
|
|
else if(deprecatedSubtype == SecondarySkill::FIRE_MAGIC || deprecatedSubtypeStr == "skill.fireMagic")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::MAGIC_SCHOOL_SKILL;
|
2023-04-30 16:35:15 +02:00
|
|
|
subtypeRelevant = true;
|
|
|
|
subtype = 2;
|
|
|
|
}
|
|
|
|
else if(deprecatedSubtype == SecondarySkill::EARTH_MAGIC || deprecatedSubtypeStr == "skill.earthMagic")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::MAGIC_SCHOOL_SKILL;
|
2023-04-30 16:35:15 +02:00
|
|
|
subtypeRelevant = true;
|
|
|
|
subtype = 8;
|
|
|
|
}
|
|
|
|
else if (deprecatedSubtype == SecondarySkill::ARTILLERY || deprecatedSubtypeStr == "skill.artillery")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::BONUS_DAMAGE_CHANCE;
|
2023-04-30 16:35:15 +02:00
|
|
|
subtypeRelevant = true;
|
|
|
|
subtypeStr = "core:creature.ballista";
|
|
|
|
}
|
|
|
|
else if (deprecatedSubtype == SecondarySkill::FIRST_AID || deprecatedSubtypeStr == "skill.firstAid")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::SPECIFIC_SPELL_POWER;
|
2023-04-30 16:35:15 +02:00
|
|
|
subtypeRelevant = true;
|
|
|
|
subtypeStr = "core:spell.firstAid";
|
|
|
|
}
|
|
|
|
else if (deprecatedSubtype == SecondarySkill::BALLISTICS || deprecatedSubtypeStr == "skill.ballistics")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::CATAPULT_EXTRA_SHOTS;
|
2023-04-30 16:35:15 +02:00
|
|
|
subtypeRelevant = true;
|
|
|
|
subtypeStr = "core:spell.catapultShot";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
isConverted = false;
|
|
|
|
}
|
|
|
|
else if (deprecatedTypeStr == "SECONDARY_SKILL_VAL2")
|
|
|
|
{
|
|
|
|
if(deprecatedSubtype == SecondarySkill::EAGLE_EYE || deprecatedSubtypeStr == "skill.eagleEye")
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::LEARN_BATTLE_SPELL_LEVEL_LIMIT;
|
2023-04-30 16:35:15 +02:00
|
|
|
else if (deprecatedSubtype == SecondarySkill::ARTILLERY || deprecatedSubtypeStr == "skill.artillery")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::HERO_GRANTS_ATTACKS;
|
2023-04-30 16:35:15 +02:00
|
|
|
subtypeRelevant = true;
|
|
|
|
subtypeStr = "core:creature.ballista";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
isConverted = false;
|
|
|
|
}
|
|
|
|
else if (deprecatedTypeStr == "SEA_MOVEMENT")
|
|
|
|
{
|
|
|
|
subtype = 0;
|
|
|
|
subtypeRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
valueType = BonusValueType::ADDITIVE_VALUE;
|
2023-04-30 16:35:15 +02:00
|
|
|
valueTypeRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::MOVEMENT;
|
2023-04-30 16:35:15 +02:00
|
|
|
}
|
|
|
|
else if (deprecatedTypeStr == "LAND_MOVEMENT")
|
|
|
|
{
|
|
|
|
subtype = 1;
|
|
|
|
subtypeRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
valueType = BonusValueType::ADDITIVE_VALUE;
|
2023-04-30 16:35:15 +02:00
|
|
|
valueTypeRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::MOVEMENT;
|
2023-04-30 16:35:15 +02:00
|
|
|
}
|
|
|
|
else if (deprecatedTypeStr == "MAXED_SPELL")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::SPELL;
|
2023-04-30 16:35:15 +02:00
|
|
|
subtypeStr = deprecatedSubtypeStr;
|
|
|
|
subtypeRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
valueType = BonusValueType::INDEPENDENT_MAX;
|
2023-04-30 16:35:15 +02:00
|
|
|
valueTypeRelevant = true;
|
|
|
|
val = 3;
|
|
|
|
valRelevant = true;
|
|
|
|
}
|
|
|
|
else if (deprecatedTypeStr == "FULL_HP_REGENERATION")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::HP_REGENERATION;
|
2023-04-30 16:35:15 +02:00
|
|
|
val = 100000; //very high value to always chose stack health
|
|
|
|
valRelevant = true;
|
|
|
|
}
|
|
|
|
else if (deprecatedTypeStr == "KING1")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::KING;
|
2023-04-30 16:35:15 +02:00
|
|
|
val = 0;
|
|
|
|
valRelevant = true;
|
|
|
|
}
|
|
|
|
else if (deprecatedTypeStr == "KING2")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::KING;
|
2023-04-30 16:35:15 +02:00
|
|
|
val = 2;
|
|
|
|
valRelevant = true;
|
|
|
|
}
|
|
|
|
else if (deprecatedTypeStr == "KING3")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::KING;
|
2023-04-30 16:35:15 +02:00
|
|
|
val = 3;
|
|
|
|
valRelevant = true;
|
|
|
|
}
|
|
|
|
else if (deprecatedTypeStr == "SIGHT_RADIOUS")
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::SIGHT_RADIUS;
|
2023-04-30 16:35:15 +02:00
|
|
|
else if (deprecatedTypeStr == "SELF_MORALE")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::MORALE;
|
2023-04-30 16:35:15 +02:00
|
|
|
val = 1;
|
|
|
|
valRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
valueType = BonusValueType::INDEPENDENT_MAX;
|
2023-04-30 16:35:15 +02:00
|
|
|
valueTypeRelevant = true;
|
|
|
|
}
|
|
|
|
else if (deprecatedTypeStr == "SELF_LUCK")
|
|
|
|
{
|
2023-05-01 00:20:01 +02:00
|
|
|
type = BonusType::LUCK;
|
2023-04-30 16:35:15 +02:00
|
|
|
val = 1;
|
|
|
|
valRelevant = true;
|
2023-05-01 00:20:01 +02:00
|
|
|
valueType = BonusValueType::INDEPENDENT_MAX;
|
2023-04-30 16:35:15 +02:00
|
|
|
valueTypeRelevant = true;
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
|
|
|
CSelector BonusParams::toSelector()
|
|
|
|
{
|
|
|
|
assert(isConverted);
|
|
|
|
if(subtypeRelevant && !subtypeStr.empty())
|
|
|
|
JsonUtils::resolveIdentifier(subtype, toJson(), "subtype");
|
|
|
|
|
|
|
|
auto ret = Selector::type()(type);
|
|
|
|
if(subtypeRelevant)
|
|
|
|
ret = ret.And(Selector::subtype()(subtype));
|
|
|
|
if(valueTypeRelevant)
|
|
|
|
ret = ret.And(Selector::valueType(valueType));
|
|
|
|
if(targetTypeRelevant)
|
|
|
|
ret = ret.And(Selector::targetSourceType()(targetType));
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_END
|