Fix attack::damage_type bug for ability resistance
When [damage_type] is used but the opponent uses the resistance ability against the added type, the ability filter only detected the original type and the new type was not affected.
This commit is contained in:
parent
c66b6d6c85
commit
57c8e0cce0
4 changed files with 171 additions and 4 deletions
|
@ -0,0 +1,138 @@
|
|||
# wmllint: no translatables
|
||||
|
||||
#####
|
||||
# API(s) being tested: [resistance]apply_to= when opponent use [damage_type]alternative_type=
|
||||
##
|
||||
# Actions:
|
||||
# Give all units vulnerability to arcane damage with a value of -100%
|
||||
# Attack each other with blade,arcane weapons
|
||||
##
|
||||
# Expected end state:
|
||||
# The damage from the attack is increased by 100%
|
||||
#####
|
||||
{COMMON_KEEP_A_B_UNIT_TEST "negative_resistance_with_two_attack_types" (
|
||||
[event]
|
||||
name = start
|
||||
|
||||
[modify_unit]
|
||||
[filter]
|
||||
[/filter]
|
||||
[effect]
|
||||
apply_to = new_ability
|
||||
[abilities]
|
||||
{TEST_ABILITY resistance -100 (max_value=100
|
||||
apply_to=arcane) SELF=yes}
|
||||
[/abilities]
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=attack
|
||||
[set_specials]
|
||||
mode=append
|
||||
[damage_type]
|
||||
alternative_type=arcane
|
||||
[/damage_type]
|
||||
[/set_specials]
|
||||
[/effect]
|
||||
[/modify_unit]
|
||||
|
||||
{ATTACK_AND_VALIDATE 200}
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
) SIDE1_LEADER="Orcish Grunt"}
|
||||
|
||||
#####
|
||||
# API(s) being tested: [resistance]apply_to= when opponent use [damage_type]alternative_type=
|
||||
##
|
||||
# Actions:
|
||||
# Give all units resistance to arcane damage with a value of 50%
|
||||
# Attack each other with blade,arcane weapons
|
||||
##
|
||||
# Expected end state:
|
||||
# The damage from the attack is not changed because blade does more damage than arcane
|
||||
#####
|
||||
{COMMON_KEEP_A_B_UNIT_TEST "positive_resistance_with_two_attack_types" (
|
||||
[event]
|
||||
name = start
|
||||
|
||||
[modify_unit]
|
||||
[filter]
|
||||
[/filter]
|
||||
[effect]
|
||||
apply_to = new_ability
|
||||
[abilities]
|
||||
{TEST_ABILITY resistance 50 (max_value=50
|
||||
apply_to=arcane) SELF=yes}
|
||||
[/abilities]
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=attack
|
||||
[set_specials]
|
||||
mode=append
|
||||
[damage_type]
|
||||
alternative_type=arcane
|
||||
[/damage_type]
|
||||
[/set_specials]
|
||||
[/effect]
|
||||
[/modify_unit]
|
||||
|
||||
{ATTACK_AND_VALIDATE 100}
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
) SIDE1_LEADER="Orcish Grunt"}
|
||||
|
||||
#####
|
||||
# API(s) being tested: [damage_type]alternative_type=
|
||||
##
|
||||
# Actions:
|
||||
# Bob is a Skeleton, with resistance to blade but weakness to arcane
|
||||
# Give Alice's attacks alternative_type=arcane
|
||||
# Make Alice teach anti-magic, so that Bob's resistance to arcane is more than his resistance to blade
|
||||
# Have Alice attack Bob
|
||||
##
|
||||
# Expected end state:
|
||||
# Alice attacked using the blade stats, not the arcane ones.
|
||||
#####
|
||||
{COMMON_KEEP_A_B_UNIT_TEST "taught_resistance_with_two_attack_types" (
|
||||
[event]
|
||||
name = start
|
||||
|
||||
[modify_unit]
|
||||
[filter]
|
||||
id=alice
|
||||
[/filter]
|
||||
[effect]
|
||||
apply_to=attack
|
||||
[set_specials]
|
||||
mode=replace
|
||||
[damage_type]
|
||||
alternative_type=arcane
|
||||
[/damage_type]
|
||||
[/set_specials]
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=new_ability
|
||||
# An ability which reduces damage to both friend and foe, based on the anti-magi aura of EoMa's Matriarch of Emptiness
|
||||
# This doesn't use the TEST_ABILITY macro, because it tests add= rather than value=
|
||||
[abilities]
|
||||
[resistance]
|
||||
add=70
|
||||
max_value=70
|
||||
apply_to=fire,cold,arcane
|
||||
affect_self=no
|
||||
affect_allies=yes
|
||||
affect_enemies=yes
|
||||
[affect_adjacent]
|
||||
[/affect_adjacent]
|
||||
[filter_base_value]
|
||||
less_than=70
|
||||
[/filter_base_value]
|
||||
[/resistance]
|
||||
[/abilities]
|
||||
[/effect]
|
||||
[/modify_unit]
|
||||
|
||||
# Skeletons have base +40% vs blade, -20% vs arcane. With the +70% buff, is weaker to blade than arcane.
|
||||
{ATTACK_AND_VALIDATE 100 DAMAGE2=60}
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
) SIDE2_LEADER=Skeleton}
|
|
@ -1789,11 +1789,9 @@ bool unit::resistance_filter_matches(const config& cfg, bool attacker, const std
|
|||
return true;
|
||||
}
|
||||
|
||||
int unit::resistance_against(const std::string& damage_name,bool attacker,const map_location& loc, const_attack_ptr weapon, const_attack_ptr opp_weapon) const
|
||||
int unit::resistance_ability(unit_ability_list resistance_abilities, const std::string& damage_name, bool attacker) const
|
||||
{
|
||||
int res = opp_weapon ? movement_type_.resistance_against(*opp_weapon) : movement_type_.resistance_against(damage_name);
|
||||
|
||||
unit_ability_list resistance_abilities = get_abilities_weapons("resistance",loc, weapon, opp_weapon);
|
||||
int res = movement_type_.resistance_against(damage_name);
|
||||
utils::erase_if(resistance_abilities, [&](const unit_ability& i) {
|
||||
return !resistance_filter_matches(*i.ability_cfg, attacker, damage_name, 100-res);
|
||||
});
|
||||
|
@ -1818,6 +1816,24 @@ int unit::resistance_against(const std::string& damage_name,bool attacker,const
|
|||
return res;
|
||||
}
|
||||
|
||||
int unit::resistance_against(const std::string& damage_name,bool attacker,const map_location& loc, const_attack_ptr weapon, const_attack_ptr opp_weapon) const
|
||||
{
|
||||
std::pair<std::string, std::string> types;
|
||||
if(opp_weapon){
|
||||
types = opp_weapon->damage_type();
|
||||
} else{
|
||||
types.first = damage_name;
|
||||
}
|
||||
|
||||
unit_ability_list resistance_abilities = get_abilities_weapons("resistance",loc, weapon, opp_weapon);
|
||||
int res = resistance_ability(resistance_abilities, types.first, attacker);
|
||||
if(!(types.second).empty()){
|
||||
res = std::max(res , resistance_ability(resistance_abilities, types.second, attacker));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> unit::advancement_icons() const
|
||||
{
|
||||
std::map<std::string,std::string> temp;
|
||||
|
|
|
@ -1054,6 +1054,16 @@ public:
|
|||
private:
|
||||
bool resistance_filter_matches(const config& cfg, bool attacker, const std::string& damage_name, int res) const;
|
||||
|
||||
/**
|
||||
* For the provided list of resistance abilities, determine the damage resistance based on which are active and any max_value that's present.
|
||||
*
|
||||
* @param resistance_abilities A list of resistance abilities that the unit has.
|
||||
* @param damage_name The name of the damage type, for example "blade".
|
||||
* @param attacker True if the unit is attacking, false if defending.
|
||||
* @return The resistance value for a unit with the provided resistance abilities to the provided damage type.
|
||||
*/
|
||||
int resistance_ability(unit_ability_list resistance_abilities, const std::string& damage_name, bool attacker) const;
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @defgroup unit_trait Trait and upkeep functions
|
||||
|
|
|
@ -369,6 +369,9 @@
|
|||
0 damage_type_test
|
||||
0 damage_type_with_filter_test
|
||||
0 damage_secondary_type_test
|
||||
0 negative_resistance_with_two_attack_types
|
||||
0 positive_resistance_with_two_attack_types
|
||||
0 taught_resistance_with_two_attack_types
|
||||
0 swarms_filter_student_by_type
|
||||
0 swarms_effects_not_checkable
|
||||
0 filter_special_id_active
|
||||
|
|
Loading…
Add table
Reference in a new issue