From 731ba544a0455c046489ce0b601a0f5048b1d0c8 Mon Sep 17 00:00:00 2001 From: newfrenchy83 Date: Wed, 3 Jul 2024 11:33:01 +0200 Subject: [PATCH] add 'base_type' filter for detect original type of attack reagrdless of [damage_type] modifications if for some reason the original type must be filtered instead of effective type, this attribute is here for that. --- data/schema/filters/weapon.cfg | 1 + .../events-test_filter_attack_type.cfg | 123 ++++++++++++++++++ src/units/attack_type.cpp | 4 + wml_test_schedule | 2 + 4 files changed, 130 insertions(+) diff --git a/data/schema/filters/weapon.cfg b/data/schema/filters/weapon.cfg index b2a92c4d922e..726a59d9aa61 100644 --- a/data/schema/filters/weapon.cfg +++ b/data/schema/filters/weapon.cfg @@ -6,6 +6,7 @@ {SIMPLE_KEY alignment alignment} {SIMPLE_KEY name string_list} {SIMPLE_KEY type string_list} + {SIMPLE_KEY base_type string_list} {SIMPLE_KEY special string_list} {SIMPLE_KEY special_active string_list} {SIMPLE_KEY special_id string_list} diff --git a/data/test/scenarios/wml_tests/ScenarioWML/EventWML/events-test_filter_attack_type.cfg b/data/test/scenarios/wml_tests/ScenarioWML/EventWML/events-test_filter_attack_type.cfg index c72a0f789937..1df290c8fd76 100644 --- a/data/test/scenarios/wml_tests/ScenarioWML/EventWML/events-test_filter_attack_type.cfg +++ b/data/test/scenarios/wml_tests/ScenarioWML/EventWML/events-test_filter_attack_type.cfg @@ -131,3 +131,126 @@ )} #undef FILTER_TYPE + +#define FILTER_BASE_TYPE TYPE + [event] + name=start + [object] + silent=yes + [effect] + apply_to=attack + set_type=pierce + [/effect] + [effect] + apply_to=new_ability + [abilities] + [damage_type] + id=test_arcane_damage + replacement_type=arcane + [/damage_type] + [/abilities] + [/effect] + [filter] + id=alice + [/filter] + [/object] + [modify_unit] + [filter] + [/filter] + # Make sure they don't die during the attacks + [status] + invulnerable=yes + [/status] + [/modify_unit] + {VARIABLE triggers 0} + [/event] + [event] + name=side 1 turn 1 + [do_command] + [move] + x=7,13 + y=3,4 + [/move] + [attack] + [source] + x,y=13,4 + [/source] + [destination] + x,y=13,3 + [/destination] + [/attack] + [/do_command] + [end_turn][/end_turn] + [/event] + + [event] + name=side 2 turn + [do_command] + [attack] + [source] + x,y=13,3 + [/source] + [destination] + x,y=13,4 + [/destination] + [/attack] + [/do_command] + [end_turn][/end_turn] + [/event] + + # Event when Alice attacks + [event] + name=attack + first_time_only=no + [filter_attack] + base_type={TYPE} + [/filter_attack] + {ASSERT ({VARIABLE_CONDITIONAL side_number equals 1})} + {ASSERT ({VARIABLE_CONDITIONAL triggers equals 0})} + {VARIABLE_OP triggers add 1} + [/event] +#enddef + +##### +# API(s) being tested: [event][filter_attack]base_type= +## +# Actions: +# Change Alice attack type to pierce. +# Give Alice an ability that adds a damage special with addition of arcane type to all of his weapons. +# Define events that use filter_attack matching Alice's pierce original type. +# Have Alice attack Bob. +## +# Expected end state: +# The event triggers when Alice attacks, because filter matche with pierce original type +##### +{GENERIC_UNIT_TEST event_test_filter_original_attack_type ( + {FILTER_BASE_TYPE pierce} + + [event] + name=turn 2 + {RETURN ({VARIABLE_CONDITIONAL triggers equals 1})} + [/event] +)} + +##### +# API(s) being tested: [event][filter_attack]base_type= +## +# Actions: +# Change Alice attack type to pierce. +# Give Alice an ability that adds a damage special with addition of arcane type to all of his weapons. +# Define events that use filter_attack matching Alice's arcane original type. +# Have Alice attack Bob. +## +# Expected end state: +# The event does not trigger when Alice attacks, because the original type is pierce +##### +{GENERIC_UNIT_TEST event_test_filter_attack_base_type_no_match ( + {FILTER_BASE_TYPE arcane} + + [event] + name=turn 2 + {RETURN ({VARIABLE_CONDITIONAL triggers equals 0})} + [/event] +)} + +#undef FILTER_BASE_TYPE diff --git a/src/units/attack_type.cpp b/src/units/attack_type.cpp index 64f81251eac8..e3b2c36ca8a2 100644 --- a/src/units/attack_type.cpp +++ b/src/units/attack_type.cpp @@ -116,6 +116,7 @@ static bool matches_simple_filter(const attack_type & attack, const config & fil const std::set filter_alignment = utils::split_set(filter["alignment"].str()); const std::set filter_name = utils::split_set(filter["name"].str()); const std::set filter_type = utils::split_set(filter["type"].str()); + const std::set filter_base_type = utils::split_set(filter["base_type"].str()); const std::vector filter_special = utils::split(filter["special"]); const std::vector filter_special_id = utils::split(filter["special_id"]); const std::vector filter_special_type = utils::split(filter["special_type"]); @@ -157,6 +158,9 @@ static bool matches_simple_filter(const attack_type & attack, const config & fil if ( !filter_name.empty() && filter_name.count(attack.id()) == 0) return false; + if ( !filter_base_type.empty() && filter_base_type.count(attack.type()) == 0 ) + return false; + if (!filter_type.empty()){ // Although there's a general guard against infinite recursion, the "damage_type" special // should always use the base type of the weapon. Otherwise it will flip-flop between the diff --git a/wml_test_schedule b/wml_test_schedule index 1f15337b6111..03650dd8f900 100644 --- a/wml_test_schedule +++ b/wml_test_schedule @@ -167,6 +167,8 @@ 0 event_test_filter_attack_no_defense 0 event_test_filter_attack_type 0 event_test_filter_attack_type_no_used +0 event_test_filter_original_attack_type +0 event_test_filter_attack_base_type_no_match 0 event_test_filter_attack_specials 0 event_test_filter_attack_on_moveto 0 event_test_filter_attack_opponent_weapon_condition