From a8c1a10035a904218c5190b251b13cbafe34f917 Mon Sep 17 00:00:00 2001 From: newfrenchy83 Date: Fri, 8 Nov 2024 15:49:26 +0100 Subject: [PATCH] add recursion_guard in [filter_(second_)weapon] for [leadership] and [resistance] abilities. In moving recursion_guard from matches_filter() to special_unit_matches() i has forgotten what [leadership] abilities called directly matches_filter(). --- .../ability_cycle_filter_weapon_recursion.cfg | 57 +++++++++++++++++++ src/units/abilities.cpp | 6 ++ wml_test_schedule | 1 + 3 files changed, 64 insertions(+) create mode 100644 data/test/scenarios/wml_tests/UnitsWML/AbilitiesWML/ability_cycle_filter_weapon_recursion.cfg diff --git a/data/test/scenarios/wml_tests/UnitsWML/AbilitiesWML/ability_cycle_filter_weapon_recursion.cfg b/data/test/scenarios/wml_tests/UnitsWML/AbilitiesWML/ability_cycle_filter_weapon_recursion.cfg new file mode 100644 index 000000000000..aadd70fdc8b3 --- /dev/null +++ b/data/test/scenarios/wml_tests/UnitsWML/AbilitiesWML/ability_cycle_filter_weapon_recursion.cfg @@ -0,0 +1,57 @@ +#textdomain wesnoth-test + +##### +# API(s) being tested: [filter_self]ability_id_active= +## +# Actions: +# Alice and Bob are both of type Test Melee Quintain. +# Give Alice a leadership_test_recursion ability, which is active only if it is itself active. +# Have Alice attack with his weapon. +## +# Expected end state: +# Deterministic end state, without crashing, but BROKE STRICT. +# All abilities are inactive. +# Bob takes 10 damage. +##### +{COMMON_KEEP_A_B_UNIT_TEST "leadership_filter_weapon_cycle_recursion" ( + [event] + name=start + + [modify_unit] + [filter] + id=alice + [/filter] + [effect] + apply_to=new_ability + [abilities] + [leadership] + id=leadership_test_recursion + value=50 + cumulative=no + affect_self=yes + [filter_weapon] + special_id_active=leadership_test_recursion + [/filter_weapon] + [/leadership] + [/abilities] + [/effect] + [/modify_unit] + + [test_do_attack_by_id] + attacker=alice + defender=bob + weapon=0 + [/test_do_attack_by_id] + + [store_unit] + [filter] + id=bob + [/filter] + variable=bob + [/store_unit] + + {ASSERT ({VARIABLE_CONDITIONAL bob.hitpoints equals 90})} + + {SUCCEED} + [/event] +) SIDE1_LEADER="Test Melee Quintain" SIDE2_LEADER="Test Melee Quintain"} diff --git a/src/units/abilities.cpp b/src/units/abilities.cpp index cbf30346aebc..a3ba92fbb8e7 100644 --- a/src/units/abilities.cpp +++ b/src/units/abilities.cpp @@ -544,6 +544,12 @@ bool unit::ability_affects_weapon(const config& cfg, const_attack_ptr weapon, bo if(!weapon) { return false; } + attack_type::recursion_guard filter_lock; + filter_lock = weapon->update_variables_recursion(cfg); + if(!filter_lock) { + show_recursion_warning(*this, cfg); + return false; + } return weapon->matches_filter(filter); } diff --git a/wml_test_schedule b/wml_test_schedule index 310d0e6208a4..9d1bb64e457a 100644 --- a/wml_test_schedule +++ b/wml_test_schedule @@ -399,6 +399,7 @@ 9 ability_cycle_recursion_by_id 9 filter_self_ability_cycle_recursion_by_id 9 adjacent_abilities_recursion_by_id +9 leadership_filter_weapon_cycle_recursion 0 negative_resistance_with_two_attack_types 0 positive_resistance_with_two_attack_types 0 taught_resistance_with_two_attack_types