wesnoth/data/test/macros/generic_backstab_test.cfg
Steve Cotton 84b1a778ae Backstab unit tests: check that backstab works in a free-for-all
The units on the outsides of a backstab don't have to be allied
to each other, they just have to be enemies of the victim. That's
hardcoded into the AI via attack.cpp's backstab_check() function,
hence a unit test to check that WEAPON_SPECIAL_BACKSTAB activates
in that situation.

Add a new map with 4 sides all on separate castles. This is a
variation of the generic 2p unit test map, extended in the south
with a horizontal reflection of existing map.

Add a MAP_FILE argument to COMMON_KEEP_A_B_C_D_UNIT_TEST,
because it's the same setup except for the map file.
2024-01-26 14:35:07 +00:00

106 lines
3.9 KiB
INI

# 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.
#
# The map has 4 sides, none of the allied to each other, with the leaders
# of the other sides far enough away to not interfere with the test.
{COMMON_KEEP_A_B_C_D_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]
) (MAP_FILE="data/test/maps/4p_separate_castles.map")}
#enddef