Skip to content

Commit

Permalink
Allow to partially check the activity of a special weapon in [has att…
Browse files Browse the repository at this point in the history
…ack]

When using [filter][has_attack]special_id/type_active, if a unit has the special in question and it is still active, it is detected, but if any filter like [filter_self/student] is used, the detection does not work anymore because the weapon is considered as still inactive, no information about the user or the opponent being available. This PR partially fixes this lack by including the information about the filtered unit but not about the opponent or if active only in attack or defense

An unexpected change is that when [abilities][damage_type]replacement_type= is used with the filter[filter_student][has_attack]type=blade on a unit that has multiple attacks including one type=blade, if the selected attack is blade, the ability works, but if another attack is selected, it is the new type that is detected now, and therefore the other attacks are no longer affected
  • Loading branch information
newfrenchy83 committed Dec 28, 2024
1 parent 8cccfb1 commit 7034805
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# Give bob a ability weapon special with an id.
##
# Expected end state:
# special_id_active correctly doesn't find a unit with that weapon special id, since it's given via an ability.
# special_id_active correctly find a unit with that weapon special id.
#####
{GENERIC_UNIT_TEST "filter_ability_special_id_active" (
[event]
Expand All @@ -31,13 +31,11 @@
[/object]

{ASSERT (
[not]
[have_unit]
[has_attack]
special_id_active=test_cth
[/has_attack]
[/have_unit]
[/not]
[have_unit]
[has_attack]
special_id_active=test_cth
[/has_attack]
[/have_unit]
)}

{SUCCEED}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
# API(s) being tested: [has_attack]special_id_active=
##
# Actions:
# Give bob a weapon special with an id.
# Give bob a weapon special with an id active if owner is an orc.
##
# Expected end state:
# special_id_active correctly finds a unit with that weapon special id.
# special_id_active correctly finds a unit with that weapon special id, bob match condition for what special be active.
#####
{GENERIC_UNIT_TEST "filter_special_id_active" (
[event]
Expand All @@ -21,6 +21,9 @@
[chance_to_hit]
id=test_cth
value=100
[filter_self]
race=orc
[/filter_self]
[/chance_to_hit]
[/set_specials]
[/effect]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#textdomain wesnoth-test

#####
# API(s) being tested: [has_attack]special_id_active=
##
# Actions:
# Give bob a weapon special with an id active if owner is an elf.
##
# Expected end state:
# special_id_active cannot finds a unit with that weapon special id, because bob don't match conditions for special be active
#####
{GENERIC_UNIT_TEST "filter_special_id_active_when_no_active" (
[event]
name=start

[object]
silent=yes
[effect]
apply_to=attack
[set_specials]
[chance_to_hit]
id=test_cth
value=100
[filter_self]
race=elf
[/filter_self]
[/chance_to_hit]
[/set_specials]
[/effect]
[filter]
id=bob
[/filter]
[/object]

{ASSERT (
[not]
[have_unit]
[has_attack]
special_id_active=test_cth
[/has_attack]
[/have_unit]
[/not]
)}

{SUCCEED}
[/event]
)}
Original file line number Diff line number Diff line change
Expand Up @@ -282,20 +282,7 @@
[/event]
)}

#####
# API(s) being tested: [filter_self][has_attack]type= in [damage_type]
##
# Actions:
# Give Alice an ability that changes all damage types to arcane if Alice has a blade attack
# Define events that use filter_attack matching Alice's arcane type.
# Have Alice attack Bob during side 1's turn
# Have Bob attack Alice during side 2's turn
##
# Expected end state:
# BROKE STRICT due to infinite recursion.
# The test reaches turn 2 without crashing; this tests for a C++ crash due to infinite recursion in the filters.
#####
{COMMON_KEEP_A_B_UNIT_TEST event_test_filter_damage_type_recursion (
#define RECURSION_DAMAGE_TYPE_TEST WEAPON
[event]
name=start
[object]
Expand Down Expand Up @@ -333,6 +320,7 @@
[test_do_attack_by_id]
attacker=alice
defender=bob
weapon={WEAPON}
[/test_do_attack_by_id]
[end_turn][/end_turn]
[/event]
Expand All @@ -345,6 +333,23 @@
[/test_do_attack_by_id]
[end_turn][/end_turn]
[/event]
#enddef

#####
# API(s) being tested: [filter_self][has_attack]type= in [damage_type]
##
# Actions:
# Give Alice an ability that changes all damage types to arcane if Alice has a blade attack
# Define events that use filter_attack matching Alice's arcane type.
# Have Alice attack Bob with melee weapon during side 1's turn
# Have Bob attack Alice during side 2's turn
##
# Expected end state:
# BROKE STRICT due to infinite recursion.
# The test reaches turn 2 without crashing and event trigered; this tests for a C++ crash due to infinite recursion in the filters.
#####
{COMMON_KEEP_A_B_UNIT_TEST event_test_filter_damage_type_recursion (
{RECURSION_DAMAGE_TYPE_TEST 0}

# Event when Alice attacks
[event]
Expand All @@ -362,3 +367,38 @@
{RETURN ({VARIABLE_CONDITIONAL triggers equals 1})}
[/event]
)}

#####
# API(s) being tested: [filter_self][has_attack]type= in [damage_type]
##
# Actions:
# Give Alice an ability that changes all damage types to arcane if Alice has a blade attack
# Define events that use filter_attack matching Alice's arcane type.
# Have Alice attack Bob with ranged weapon during side 1's turn
# Have Bob attack Alice during side 2's turn
##
# Expected end state:
# BROKE STRICT due to infinite recursion.
# The test reaches turn 2 without crashing and event no trigered because no blade attack exist; this tests for a C++ crash due to infinite recursion in the filters.
#####
{COMMON_KEEP_A_B_UNIT_TEST event_test_failed_filter_damage_type_recursion (
{RECURSION_DAMAGE_TYPE_TEST 1}

# Event when Alice attacks
[event]
name=attack
first_time_only=no
[filter_attack]
type=arcane
[/filter_attack]
{ASSERT ({VARIABLE_CONDITIONAL side_number equals 1})}
{ASSERT ({VARIABLE_CONDITIONAL triggers equals 0})}
{VARIABLE_OP triggers add 1}
[/event]
[event]
name=turn 2
{RETURN ({VARIABLE_CONDITIONAL triggers equals 0})}
[/event]
)}

#undef RECURSION_DAMAGE_TYPE_TEST
1 change: 1 addition & 0 deletions src/units/filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,7 @@ void unit_filter_compound::fill(const vconfig& cfg)
else if (child.first == "has_attack") {
create_child(child.second, [](const vconfig& c, const unit_filter_args& args) {
for(const attack_type& a : args.u.attacks()) {
auto ctx = a.specials_context((args.u).shared_from_this(), args.loc, true);
if(a.matches_filter(c.get_parsed_config())) {
return true;
}
Expand Down
2 changes: 2 additions & 0 deletions wml_test_schedule
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@
0 damage_type_apply_to_both_filter_self_opponent
0 damage_type_apply_to_attacker_filter_attacker_defender
9 event_test_filter_damage_type_recursion
9 event_test_failed_filter_damage_type_recursion
9 four_cycle_recursion_branching
9 four_cycle_recursion_by_id
9 four_cycle_recursion_by_tagname
Expand All @@ -407,6 +408,7 @@
0 swarms_filter_student_by_type
0 swarms_effects_not_checkable
0 filter_special_id_active
0 filter_special_id_active_when_no_active
0 filter_ability_special_id_active
0 filter_special_id_not_exists
0 special_id_active_lua_function
Expand Down

0 comments on commit 7034805

Please sign in to comment.