1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Merge pull request #3116 from IvanSavenko/bonus_fixes

Bonuses fixes
This commit is contained in:
Ivan Savenko 2023-10-29 16:32:48 +02:00 committed by GitHub
commit 207968ced3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 27 additions and 8 deletions

View File

@ -60,8 +60,14 @@ Allows flying movement for affected heroes
Eliminates terrain penalty on certain terrain types for affected heroes (Nomads ability).
Note: to eliminate all terrain penalties see ROUGH_TERRAIN_DISCOUNT bonus
- subtype: type of terrain
### TERRAIN_NATIVE
Affected units will view any terrain as native
### PRIMARY_SKILL
Changes selected primary skill for affected heroes and units
@ -252,6 +258,7 @@ Allows creature upgrade for affected armies
Changes duration of timed spells casted by affected hero
- val: additional duration, turns
- subtype: optional, identifier of affected spells, or all if not set
### SPELL
@ -791,7 +798,7 @@ Affected unit is permanently enchanted with a spell, that is cast again every tu
Affected unit is immune to all spell with level below or equal to value of this bonus
- val: level to which this unit is immune to
- val: level up to which this unit is immune to
TODO: additional info?
@ -893,6 +900,12 @@ Affected unit will never retaliate to an attack (Blind, Paralyze)
# Others
### NEGATIVE_EFFECTS_IMMUNITY
Affected unit is immune to all negative spells of specified spell school
- subtype: affected spell school
### BLOCK_MAGIC_ABOVE
Blocks casting spells of the level above specified one in battles affected by this bonus

View File

@ -33,14 +33,13 @@ bool INativeTerrainProvider::isNativeTerrain(TerrainId terrain) const
TerrainId AFactionMember::getNativeTerrain() const
{
constexpr auto any = TerrainId(ETerrainId::ANY_TERRAIN);
const std::string cachingStringNoTerrainPenalty = "type_NO_TERRAIN_PENALTY_sANY";
static const auto selectorNoTerrainPenalty = Selector::typeSubtype(BonusType::NO_TERRAIN_PENALTY, BonusSubtypeID(any));
const std::string cachingStringNoTerrainPenalty = "type_TERRAIN_NATIVE_NONE";
static const auto selectorNoTerrainPenalty = Selector::typeSubtype(BonusType::TERRAIN_NATIVE, BonusSubtypeID());
//this code is used in the CreatureTerrainLimiter::limit to setup battle bonuses
//and in the CGHeroInstance::getNativeTerrain() to setup movement bonuses or/and penalties.
return getBonusBearer()->hasBonus(selectorNoTerrainPenalty, cachingStringNoTerrainPenalty)
? any : VLC->factions()->getById(getFaction())->getNativeTerrain();
? TerrainId::ANY_TERRAIN : VLC->factions()->getById(getFaction())->getNativeTerrain();
}
int32_t AFactionMember::magicResistance() const

View File

@ -446,6 +446,7 @@ static void loadBonusSubtype(BonusSubtypeID & subtype, BonusType type, const Jso
case BonusType::SPELLS_OF_SCHOOL:
case BonusType::SPELL_DAMAGE_REDUCTION:
case BonusType::SPELL_SCHOOL_IMMUNITY:
case BonusType::NEGATIVE_EFFECTS_IMMUNITY:
{
VLC->identifiers()->requestIdentifier( "spellSchool", node, [&subtype](int32_t identifier)
{
@ -485,6 +486,7 @@ static void loadBonusSubtype(BonusSubtypeID & subtype, BonusType type, const Jso
break;
}
case BonusType::SPELL_IMMUNITY:
case BonusType::SPELL_DURATION:
case BonusType::SPECIAL_ADD_VALUE_ENCHANT:
case BonusType::SPECIAL_FIXED_VALUE_ENCHANT:
case BonusType::SPECIAL_PECULIAR_ENCHANT:

View File

@ -169,6 +169,7 @@ class JsonNode;
BONUS_NAME(MAX_LEARNABLE_SPELL_LEVEL) /*This can work as wisdom before. val = max learnable spell level*/\
BONUS_NAME(SPELL_SCHOOL_IMMUNITY) /*This bonus will work as spell school immunity for all spells, subtype - spell school: 0 - air, 1 - fire, 2 - water, 3 - earth. Any is not handled for reducing overlap from LEVEL_SPELL_IMMUNITY*/\
BONUS_NAME(NEGATIVE_EFFECTS_IMMUNITY) /*This bonus will work as spell school immunity for negative effects from spells of school, subtype - spell school: -1 - any, 0 - air, 1 - fire, 2 - water, 3 - earth*/\
BONUS_NAME(TERRAIN_NATIVE)
/* end of list */

View File

@ -700,7 +700,11 @@ int32_t CGHeroInstance::getEffectPower(const spells::Spell * spell) const
int32_t CGHeroInstance::getEnchantPower(const spells::Spell * spell) const
{
return getPrimSkillLevel(PrimarySkill::SPELL_POWER) + valOfBonuses(BonusType::SPELL_DURATION);
int32_t spellpower = getPrimSkillLevel(PrimarySkill::SPELL_POWER);
int32_t durationCommon = valOfBonuses(BonusType::SPELL_DURATION, BonusSubtypeID());
int32_t durationSpecific = valOfBonuses(BonusType::SPELL_DURATION, BonusSubtypeID(spell->getId()));
return spellpower + durationCommon + durationSpecific;
}
int64_t CGHeroInstance::getEffectValue(const spells::Spell * spell) const

View File

@ -22,8 +22,8 @@ TurnInfo::BonusCache::BonusCache(const TConstBonusListPtr & bl)
{
for(const auto & terrain : VLC->terrainTypeHandler->objects)
{
noTerrainPenalty.push_back(static_cast<bool>(
bl->getFirst(Selector::type()(BonusType::NO_TERRAIN_PENALTY).And(Selector::subtype()(BonusSubtypeID(terrain->getId()))))));
auto selector = Selector::typeSubtype(BonusType::NO_TERRAIN_PENALTY, BonusSubtypeID(terrain->getId()));
noTerrainPenalty.push_back(static_cast<bool>(bl->getFirst(selector)));
}
freeShipBoarding = static_cast<bool>(bl->getFirst(Selector::type()(BonusType::FREE_SHIP_BOARDING)));