Unit tests for changing abilites with filters in [event]name=attack

The existing backstab tests' common code is moved to a utility file
for reuse in other tests, because it can be used to check whether a
weapon special was active during the damage calculations.

Git's diff can show a lot of lines being deleted, but that's just
because it's showing a file being copied, and then half of each copy
being removed.
This commit is contained in:
Steve Cotton 2022-10-02 10:28:46 +02:00 committed by Steve Cotton
parent f60f921e64
commit b74216d6c8
4 changed files with 196 additions and 106 deletions

View file

@ -0,0 +1,102 @@
# wmllint: no translatables
#define GENERIC_BACKSTAB_TEST NAME ANTIDIRECTIONS ABILITY_SHOULD_ACTIVATE EXTRA_SETUP
# Test that the backstab ability does double-damage if and only if it should
# be active in the circumstances created by EXTRA_SETUP.
#
# Given a set of directions, create units around Bob. One of those units
# makes an attack, and the damage dealt is compared to the expectation that
# the ABILITY_SHOULD_ACTIVATE.
#
# Note: the directions given are the direction of Bob from the spawn, so
# ('n','se','sw') spawns units ('s,'nw','ne') of Bob. The order that the
# units spawn might not match the order of the ANTIDIRECTIONS argument.
#
# Any commands in EXTRA_SETUP are run after spawning the units but before
# making the attack. This code can access the new units via the
# spawn_points array.
#
# The unit on hex spawn_points[0] then attacks Bob, and the test asserts
# that Bob has the expected number of hit points remaining.
{GENERIC_UNIT_TEST {NAME} (
[event]
# Using this event instead of "start" because units get healed after "start", which makes debugging more confusing
name=side 1 turn 1
# Give Bob enough hitpoints to survive, but put him on bad terrain to give a 100% chance to be hit
[modify_unit]
[filter]
id=bob
[/filter]
hitpoints=100
[/modify_unit]
[terrain]
location_id=2
terrain="Xv"
[/terrain]
# Spawn enemies
[store_locations]
[filter_adjacent_location]
location_id=2
adjacent={ANTIDIRECTIONS}
[/filter_adjacent_location]
variable=spawn_points
[/store_locations]
[foreach]
array=spawn_points
[do]
# Use the L2 unit, because a Thief might be killed by Bob's counterattack
{NOTRAIT_UNIT 1 Rogue $this_item.x $this_item.y}
[/do]
[/foreach]
{EXTRA_SETUP}
[store_locations]
location_id=2
variable=bob_location
[/store_locations]
[do_command]
[attack]
weapon=0
defender_weapon=0
[source]
x=$spawn_points[0].x
y=$spawn_points[0].y
[/source]
[destination]
x=$bob_location[0].x
y=$bob_location[0].y
[/destination]
[/attack]
[/do_command]
[store_unit]
[filter]
id=bob
[/filter]
variable=b
[/store_unit]
# Check whether the amount of damage received matches the ability being active or not.
# The attacker is a Rogue, so does 6x3 base damage before the ability is applied.
{VARIABLE should_activate {ABILITY_SHOULD_ACTIVATE}}
[if]
{VARIABLE_CONDITIONAL should_activate boolean_equals "yes"}
[then]
{ASSERT ({VARIABLE_CONDITIONAL b.hitpoints equals "$(100 - 6 * 3 * 2)"})}
[/then]
[else]
{ASSERT ({VARIABLE_CONDITIONAL b.hitpoints equals "$(100 - 6 * 3)"})}
[/else]
[/if]
{CLEAR_VARIABLE b}
{CLEAR_VARIABLE should_activate}
{CLEAR_VARIABLE spawn_points}
{SUCCEED}
[/event]
)}
#enddef

View file

@ -1,105 +1,5 @@
# wmllint: no translatables
# Test that the backstab ability does double-damage, under the correct circumstances
#define TEST_BACKSTAB NAME ANTIDIRECTIONS ABILITY_SHOULD_ACTIVATE EXTRA_SETUP
# Given a set of directions, create units around Bob. One of those units
# makes an attack, and the damage dealt is compared to the expectation that
# the ABILITY_SHOULD_ACTIVATE.
#
# Note: the directions given are the direction of Bob from the spawn, so
# ('n','se','sw') spawns units ('s,'nw','ne') of Bob. The order that the
# units spawn might not match the order of the ANTIDIRECTIONS argument.
#
# Any commands in EXTRA_SETUP are run after spawning the units but before
# making the attack. This code can access the new units via the
# spawn_points array.
#
# The unit on hex spawn_points[0] then attacks Bob, and the test asserts
# that Bob has the expected number of hit points remaining.
{GENERIC_UNIT_TEST {NAME} (
[event]
# Using this event instead of "start" because units get healed after "start", which makes debugging more confusing
name=side 1 turn 1
# Give Bob enough hitpoints to survive, but put him on bad terrain to give a 100% chance to be hit
[modify_unit]
[filter]
id=bob
[/filter]
hitpoints=100
[/modify_unit]
[terrain]
location_id=2
terrain="Xv"
[/terrain]
# Spawn enemies
[store_locations]
[filter_adjacent_location]
location_id=2
adjacent={ANTIDIRECTIONS}
[/filter_adjacent_location]
variable=spawn_points
[/store_locations]
[foreach]
array=spawn_points
[do]
# Use the L2 unit, because a Thief might be killed by Bob's counterattack
{NOTRAIT_UNIT 1 Rogue $this_item.x $this_item.y}
[/do]
[/foreach]
{EXTRA_SETUP}
[store_locations]
location_id=2
variable=bob_location
[/store_locations]
[do_command]
[attack]
weapon=0
defender_weapon=0
[source]
x=$spawn_points[0].x
y=$spawn_points[0].y
[/source]
[destination]
x=$bob_location[0].x
y=$bob_location[0].y
[/destination]
[/attack]
[/do_command]
[store_unit]
[filter]
id=bob
[/filter]
variable=b
[/store_unit]
# Check whether the amount of damage received matches the ability being active or not.
# The attacker is a Rogue, so does 6x3 base damage before the ability is applied.
{VARIABLE should_activate {ABILITY_SHOULD_ACTIVATE}}
[if]
{VARIABLE_CONDITIONAL should_activate boolean_equals "yes"}
[then]
{ASSERT ({VARIABLE_CONDITIONAL b.hitpoints equals "$(100 - 6 * 3 * 2)"})}
[/then]
[else]
{ASSERT ({VARIABLE_CONDITIONAL b.hitpoints equals "$(100 - 6 * 3)"})}
[/else]
[/if]
{CLEAR_VARIABLE b}
{CLEAR_VARIABLE should_activate}
{CLEAR_VARIABLE spawn_points}
{SUCCEED}
[/event]
)}
#enddef
#####
# API(s) being tested: [damage]+[filter_opponent]formula
##
@ -112,7 +12,7 @@
# The damage shows that Bob was backstabbed.
# Bob gets hit all three times and ends with 100-(6 * 3 * 2) hp.
#####
{TEST_BACKSTAB "backstab_active_with_accomplice_behind_bob" "n,s" yes ()}
{GENERIC_BACKSTAB_TEST "backstab_active_with_accomplice_behind_bob" "n,s" yes ()}
#####
# API(s) being tested: [damage]+[filter_opponent]formula
@ -126,7 +26,7 @@
# The damage shows that the ability was inactive.
# Bob gets hit all three times and ends with 100-(6 * 3 * 1) hp.
#####
{TEST_BACKSTAB "backstab_inactive_with_triangular_formation" "n,se,sw" no ()}
{GENERIC_BACKSTAB_TEST "backstab_inactive_with_triangular_formation" "n,se,sw" no ()}
#####
# API(s) being tested: [damage]+[filter_opponent]formula
@ -141,7 +41,7 @@
# The damage shows that the ability was inactive.
# Bob gets hit all three times and ends with 100-(6 * 3 * 1) hp.
#####
{TEST_BACKSTAB "backstab_inactive_with_statue_behind_bob" "n,s" no (
{GENERIC_BACKSTAB_TEST "backstab_inactive_with_statue_behind_bob" "n,s" no (
[petrify]
x=$spawn_points[1].x
y=$spawn_points[1].y
@ -161,7 +61,7 @@
# The damage shows that the ability was inactive.
# Bob gets hit all three times and ends with 100-(6 * 3 * 1) hp.
#####
{TEST_BACKSTAB "backstab_inactive_with_bobs_ally_behind_bob" "n,s" no (
{GENERIC_BACKSTAB_TEST "backstab_inactive_with_bobs_ally_behind_bob" "n,s" no (
[modify_unit]
[filter]
x=$spawn_points[1].x
@ -170,5 +70,3 @@
side=2
[/modify_unit]
)}
#undef TEST_BACKSTAB

View file

@ -0,0 +1,88 @@
#textdomain wesnoth-test
#define REPLACE_WEAPON_SPECIALS_WITH_STATUE_BACKSTAB
# For use in an [object], will replace all the unit's weapon specials with
# a backstab variant that is active if, and only if, the accomplice is petrified.
[effect]
apply_to=attack
[set_specials]
mode=replace
[damage]
id=backstab_by_statue
name= _ "backstab by statue"
description= _ "A variant of backstab thats only active when the accomplice is petrified."
multiply=2
active_on=offense
[filter_opponent]
formula="
enemy_of(self, flanker) and flanker.petrified
where
flanker = unit_at(direction_from(loc, other.facing))
"
[/filter_opponent]
[/damage]
[/set_specials]
[/effect]
#enddef
#####
# API(s) being tested: [set_specials][damage][filter_opponent] during [event]name=attack
#
# This test is a variation of backstab_inactive_with_statue_behind_bob.
##
# Actions:
# Bob is made to have 0% defense and given 100 hp.
# A Rogue is spawned north and south of Bob.
# The south Rogue is petrified.
# The north Rogue attacks Bob.
# In the pre-attack event, the backstab is replaced by one whose filter passes iff the south Rogue is petrified.
##
# Expected end state:
# The damage shows that the ability was active.
# Bob gets hit all three times and ends with 100-(6 * 3 * 2) hp.
#####
{GENERIC_BACKSTAB_TEST "replace_special_with_filter_in_attack_event_active" "n,s" yes (
[petrify]
x=$spawn_points[1].x
y=$spawn_points[1].y
[/petrify]
[event]
name=attack
[object]
[filter]
x=$spawn_points[0].x
y=$spawn_points[0].y
[/filter]
{REPLACE_WEAPON_SPECIALS_WITH_STATUE_BACKSTAB}
[/object]
[/event]
)}
#####
# API(s) being tested: [set_specials][damage][filter_opponent] during [event]name=attack
##
# Actions:
# Bob is made to have 0% defense and given 100 hp.
# A Rogue is spawned north and south of Bob.
# The north Rogue attacks Bob.
# In the pre-attack event, the backstab is replaced by one whose filter passes iff the south Rogue is petrified.
##
# Expected end state:
# The damage shows that the ability was inactive.
# Bob gets hit all three times and ends with 100-(6 * 3 * 1) hp.
#####
{GENERIC_BACKSTAB_TEST "replace_special_with_filter_in_attack_event_inactive" "n,s" no (
[event]
name=attack
[object]
[filter]
x=$spawn_points[0].x
y=$spawn_points[0].y
[/filter]
{REPLACE_WEAPON_SPECIALS_WITH_STATUE_BACKSTAB}
[/object]
[/event]
)}
#undef REPLACE_WEAPON_SPECIALS_WITH_STATUE_BACKSTAB

View file

@ -280,6 +280,8 @@
0 reflexive_drains
0 reflexive_poison
0 reflexive_slow
0 replace_special_with_filter_in_attack_event_active
0 replace_special_with_filter_in_attack_event_inactive
0 swarm_disables_upgrades
0 swarm_disables_upgrades_with_abilities
0 swarm_disables_upgrades_with_abilities_fail