1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-25 12:14:46 +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). 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 - subtype: type of terrain
### TERRAIN_NATIVE
Affected units will view any terrain as native
### PRIMARY_SKILL ### PRIMARY_SKILL
Changes selected primary skill for affected heroes and units 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 Changes duration of timed spells casted by affected hero
- val: additional duration, turns - val: additional duration, turns
- subtype: optional, identifier of affected spells, or all if not set
### SPELL ### 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 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? TODO: additional info?
@ -893,6 +900,12 @@ Affected unit will never retaliate to an attack (Blind, Paralyze)
# Others # Others
### NEGATIVE_EFFECTS_IMMUNITY
Affected unit is immune to all negative spells of specified spell school
- subtype: affected spell school
### BLOCK_MAGIC_ABOVE ### BLOCK_MAGIC_ABOVE
Blocks casting spells of the level above specified one in battles affected by this bonus 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 TerrainId AFactionMember::getNativeTerrain() const
{ {
constexpr auto any = TerrainId(ETerrainId::ANY_TERRAIN); const std::string cachingStringNoTerrainPenalty = "type_TERRAIN_NATIVE_NONE";
const std::string cachingStringNoTerrainPenalty = "type_NO_TERRAIN_PENALTY_sANY"; static const auto selectorNoTerrainPenalty = Selector::typeSubtype(BonusType::TERRAIN_NATIVE, BonusSubtypeID());
static const auto selectorNoTerrainPenalty = Selector::typeSubtype(BonusType::NO_TERRAIN_PENALTY, BonusSubtypeID(any));
//this code is used in the CreatureTerrainLimiter::limit to setup battle bonuses //this code is used in the CreatureTerrainLimiter::limit to setup battle bonuses
//and in the CGHeroInstance::getNativeTerrain() to setup movement bonuses or/and penalties. //and in the CGHeroInstance::getNativeTerrain() to setup movement bonuses or/and penalties.
return getBonusBearer()->hasBonus(selectorNoTerrainPenalty, cachingStringNoTerrainPenalty) return getBonusBearer()->hasBonus(selectorNoTerrainPenalty, cachingStringNoTerrainPenalty)
? any : VLC->factions()->getById(getFaction())->getNativeTerrain(); ? TerrainId::ANY_TERRAIN : VLC->factions()->getById(getFaction())->getNativeTerrain();
} }
int32_t AFactionMember::magicResistance() const 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::SPELLS_OF_SCHOOL:
case BonusType::SPELL_DAMAGE_REDUCTION: case BonusType::SPELL_DAMAGE_REDUCTION:
case BonusType::SPELL_SCHOOL_IMMUNITY: case BonusType::SPELL_SCHOOL_IMMUNITY:
case BonusType::NEGATIVE_EFFECTS_IMMUNITY:
{ {
VLC->identifiers()->requestIdentifier( "spellSchool", node, [&subtype](int32_t identifier) VLC->identifiers()->requestIdentifier( "spellSchool", node, [&subtype](int32_t identifier)
{ {
@ -485,6 +486,7 @@ static void loadBonusSubtype(BonusSubtypeID & subtype, BonusType type, const Jso
break; break;
} }
case BonusType::SPELL_IMMUNITY: case BonusType::SPELL_IMMUNITY:
case BonusType::SPELL_DURATION:
case BonusType::SPECIAL_ADD_VALUE_ENCHANT: case BonusType::SPECIAL_ADD_VALUE_ENCHANT:
case BonusType::SPECIAL_FIXED_VALUE_ENCHANT: case BonusType::SPECIAL_FIXED_VALUE_ENCHANT:
case BonusType::SPECIAL_PECULIAR_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(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(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(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 */ /* 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 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 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) for(const auto & terrain : VLC->terrainTypeHandler->objects)
{ {
noTerrainPenalty.push_back(static_cast<bool>( auto selector = Selector::typeSubtype(BonusType::NO_TERRAIN_PENALTY, BonusSubtypeID(terrain->getId()));
bl->getFirst(Selector::type()(BonusType::NO_TERRAIN_PENALTY).And(Selector::subtype()(BonusSubtypeID(terrain->getId())))))); noTerrainPenalty.push_back(static_cast<bool>(bl->getFirst(selector)));
} }
freeShipBoarding = static_cast<bool>(bl->getFirst(Selector::type()(BonusType::FREE_SHIP_BOARDING))); freeShipBoarding = static_cast<bool>(bl->getFirst(Selector::type()(BonusType::FREE_SHIP_BOARDING)));