Add tests for recursive weapon filters
This commit is contained in:
parent
743b146efc
commit
f272d9022e
3 changed files with 272 additions and 96 deletions
|
@ -294,20 +294,7 @@
|
|||
[/event]
|
||||
)}
|
||||
|
||||
#####
|
||||
# API(s) being tested: [event][filter_attack],[event][filter_second_attack]
|
||||
##
|
||||
# Actions:
|
||||
# Define events filtering based on weapon specials.
|
||||
# Give Bob a poison special iff the opponent has a specific drain special.
|
||||
# Give Alice a drain special iff the opponent has a specific poison special.
|
||||
# Have side 1's unit attack side 2's unit.
|
||||
# Have side 2's unit attack side 1's unit.
|
||||
##
|
||||
# Expected end state:
|
||||
# Both events that should trigger for Bob do trigger.
|
||||
#####
|
||||
{GENERIC_UNIT_TEST event_test_filter_attack_opponent_weapon_condition (
|
||||
#define SPECIAL_CONDITION FILTER
|
||||
[event]
|
||||
name=turn 1
|
||||
# Make sure the attacks hit
|
||||
|
@ -339,9 +326,183 @@
|
|||
[abilities]
|
||||
[drains]
|
||||
id=ability_drain_blade
|
||||
[filter_opponent]
|
||||
[filter_weapon]
|
||||
{FILTER}
|
||||
[/filter_weapon]
|
||||
[/filter_opponent]
|
||||
[/drains]
|
||||
[/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}
|
||||
{VARIABLE triggers_on_attack 0}
|
||||
{VARIABLE triggers_on_defense 0}
|
||||
[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]
|
||||
name=attack
|
||||
first_time_only=no
|
||||
[filter_attack]
|
||||
special_id_active=ability_poison_blade
|
||||
[/filter_attack]
|
||||
{ASSERT ({VARIABLE_CONDITIONAL side_number equals 2})}
|
||||
{VARIABLE_OP triggers_on_attack add 1}
|
||||
[/event]
|
||||
[event]
|
||||
name=attack
|
||||
first_time_only=no
|
||||
[filter_second_attack]
|
||||
special_id_active=ability_poison_blade
|
||||
[/filter_second_attack]
|
||||
{ASSERT ({VARIABLE_CONDITIONAL side_number equals 1})}
|
||||
{VARIABLE_OP triggers_on_defense add 1}
|
||||
[/event]
|
||||
#enddef
|
||||
|
||||
#####
|
||||
# API(s) being tested: [event][filter_attack],[event][filter_second_attack]
|
||||
##
|
||||
# Actions:
|
||||
# Define events filtering based on weapon specials.
|
||||
# Give Bob a poison special iff the opponent has a specific drain special.
|
||||
# Give Alice that drain special iff the opponent has a blade attack.
|
||||
# Have side 1's unit attack side 2's unit.
|
||||
# Have side 2's unit attack side 1's unit.
|
||||
##
|
||||
# Expected end state:
|
||||
# Both events that should trigger for Bob do trigger.
|
||||
#####
|
||||
{GENERIC_UNIT_TEST event_test_filter_attack_opponent_weapon_condition (
|
||||
{SPECIAL_CONDITION (type=blade)}
|
||||
[event]
|
||||
name=turn 2
|
||||
{ASSERT ({VARIABLE_CONDITIONAL triggers_on_attack equals 1})}
|
||||
{ASSERT ({VARIABLE_CONDITIONAL triggers_on_defense equals 1})}
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
)}
|
||||
|
||||
#####
|
||||
# API(s) being tested: [event][filter_attack],[event][filter_second_attack]
|
||||
##
|
||||
# Actions:
|
||||
# Define events filtering based on absence of weapon specials.
|
||||
# Give Bob a poison special iff the opponent has a specific drain special, and that special is active.
|
||||
# Give Alice a drain special iff the opponent has a specific poison special, and that special is active.
|
||||
# Have side 1's unit attack side 2's unit.
|
||||
# Have side 2's unit attack side 1's unit.
|
||||
##
|
||||
# Expected end state:
|
||||
# BROKE STRICT because testing the special_id_active conditions led to infinite recursion.
|
||||
# The events don't trigger. Both specials depend on the other one being active, so the calculation would need infinate recursion; instead, the engine decides that both are inactive.
|
||||
#####
|
||||
{GENERIC_UNIT_TEST event_test_filter_attack_opponent_weapon_condition_no_triggered (
|
||||
{SPECIAL_CONDITION (special_id_active=ability_poison_blade)}
|
||||
[event]
|
||||
name=turn 2
|
||||
{ASSERT ({VARIABLE_CONDITIONAL triggers_on_attack equals 0})}
|
||||
{ASSERT ({VARIABLE_CONDITIONAL triggers_on_defense equals 0})}
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
)}
|
||||
|
||||
#undef SPECIAL_CONDITION
|
||||
|
||||
#####
|
||||
# API(s) being tested: [event][filter_attack],[event][filter_second_attack]
|
||||
##
|
||||
# Actions:
|
||||
# Define specials filtering based on weapon specials.
|
||||
# Give Bob a poison special iff own a same special active or a blade or pierce attack.
|
||||
# Give Alice a drain special iff own a same special active or a blade or pierce attack.
|
||||
# Have side 1's unit attack side 2's unit.
|
||||
# Have side 2's unit attack side 1's unit.
|
||||
##
|
||||
# Expected end state:
|
||||
# BROKE STRICT because testing the special_id_active conditions led to infinite recursion.
|
||||
# Both events trigger for Bob because testing type=blade,pierce only requires a reasonable depth of recursion.
|
||||
#####
|
||||
{GENERIC_UNIT_TEST event_test_filter_attack_student_weapon_condition (
|
||||
[event]
|
||||
name=turn 1
|
||||
# Make sure the attacks hit
|
||||
{FORCE_CHANCE_TO_HIT (id=bob) (id=alice) 100 ()}
|
||||
{FORCE_CHANCE_TO_HIT (id=alice) (id=bob) 100 ()}
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
apply_to=new_ability
|
||||
[abilities]
|
||||
[poison]
|
||||
id=ability_poison_blade
|
||||
[filter_student]
|
||||
[filter_weapon]
|
||||
type=blade
|
||||
special_id_active=ability_poison_blade
|
||||
[or]
|
||||
type=blade,pierce
|
||||
[/or]
|
||||
[/filter_weapon]
|
||||
[/filter_student]
|
||||
[/poison]
|
||||
[/abilities]
|
||||
[/effect]
|
||||
[filter]
|
||||
id=bob
|
||||
[/filter]
|
||||
[/object]
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
apply_to=new_ability
|
||||
[abilities]
|
||||
[drains]
|
||||
id=ability_drain_blade
|
||||
[filter_student]
|
||||
[filter_weapon]
|
||||
special_id_active=ability_drain_blade
|
||||
[or]
|
||||
type=blade,pierce
|
||||
[/or]
|
||||
[/filter_weapon]
|
||||
[/filter_student]
|
||||
[/drains]
|
||||
|
@ -360,6 +521,8 @@
|
|||
[/status]
|
||||
[/modify_unit]
|
||||
{VARIABLE triggers 0}
|
||||
{VARIABLE triggers_on_attack 0}
|
||||
{VARIABLE triggers_on_defense 0}
|
||||
[do_command]
|
||||
[move]
|
||||
x=7,13
|
||||
|
|
|
@ -196,12 +196,14 @@
|
|||
# Move Alice next to Bob, and have Alice attack Bob.
|
||||
##
|
||||
# Expected end state:
|
||||
# Alice attack with fire; and Bob use cold because Bob [damage] filter must check type=blade and not the replacement type, that who cause infinite recursion.
|
||||
# Alice attack with fire; and Bob use cold because Bob [damage] filter must check type=blade and not the replacement type. That's partly because it could otherwise cause infinite recursion, and partly because having a set limit to the number of recursions would make it unpredicatable which specials are active.
|
||||
#####
|
||||
{GENERIC_UNIT_TEST "damage_type_with_filter_test" (
|
||||
{DAMAGE_TYPE_TEST {FILTER_TYPE_BLADE}}
|
||||
)}
|
||||
|
||||
#undef FILTER_TYPE_BLADE
|
||||
|
||||
#####
|
||||
# API(s) being tested: [damage]alternative_type=
|
||||
##
|
||||
|
@ -216,16 +218,10 @@
|
|||
# Expected end state:
|
||||
# Alice attack with blade and Bob use cold.
|
||||
#####
|
||||
{GENERIC_UNIT_TEST "damage_secondary_type_test" (
|
||||
{COMMON_KEEP_A_B_UNIT_TEST "damage_secondary_type_test" (
|
||||
[event]
|
||||
name=start
|
||||
[modify_unit]
|
||||
[filter]
|
||||
[/filter]
|
||||
max_hitpoints=100
|
||||
hitpoints=100
|
||||
attacks_left=1
|
||||
[/modify_unit]
|
||||
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
|
@ -240,27 +236,19 @@
|
|||
apply_to=attack
|
||||
[set_specials]
|
||||
mode=append
|
||||
[attacks]
|
||||
value=1
|
||||
[/attacks]
|
||||
[damage]
|
||||
value=12
|
||||
[/damage]
|
||||
[damage_type]
|
||||
alternative_type=pierce
|
||||
[/damage_type]
|
||||
[damage_type]
|
||||
alternative_type=cold
|
||||
[/damage_type]
|
||||
[chance_to_hit]
|
||||
value=100
|
||||
[/chance_to_hit]
|
||||
[/set_specials]
|
||||
[/effect]
|
||||
[filter]
|
||||
id=bob
|
||||
[/filter]
|
||||
[/object]
|
||||
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
|
@ -276,18 +264,9 @@
|
|||
apply_to=attack
|
||||
[set_specials]
|
||||
mode=append
|
||||
[attacks]
|
||||
value=1
|
||||
[/attacks]
|
||||
[damage]
|
||||
value=12
|
||||
[/damage]
|
||||
[damage_type]
|
||||
alternative_type=fire
|
||||
[/damage_type]
|
||||
[chance_to_hit]
|
||||
value=100
|
||||
[/chance_to_hit]
|
||||
[/set_specials]
|
||||
[/effect]
|
||||
[filter]
|
||||
|
@ -295,60 +274,91 @@
|
|||
[/filter]
|
||||
[/object]
|
||||
|
||||
[store_unit]
|
||||
[filter]
|
||||
id=alice
|
||||
[/filter]
|
||||
variable=a
|
||||
kill=yes
|
||||
[/store_unit]
|
||||
[store_unit]
|
||||
[filter]
|
||||
id=bob
|
||||
[/filter]
|
||||
variable=b
|
||||
[/store_unit]
|
||||
[unstore_unit]
|
||||
variable=a
|
||||
find_vacant=yes
|
||||
x,y=$b.x,$b.y
|
||||
[/unstore_unit]
|
||||
[store_unit]
|
||||
[filter]
|
||||
id=alice
|
||||
[/filter]
|
||||
variable=a
|
||||
[/store_unit]
|
||||
|
||||
[do_command]
|
||||
[attack]
|
||||
weapon=0
|
||||
defender_weapon=0
|
||||
[source]
|
||||
x,y=$a.x,$a.y
|
||||
[/source]
|
||||
[destination]
|
||||
x,y=$b.x,$b.y
|
||||
[/destination]
|
||||
[/attack]
|
||||
[/do_command]
|
||||
[store_unit]
|
||||
[filter]
|
||||
id=alice
|
||||
[/filter]
|
||||
variable=a
|
||||
[/store_unit]
|
||||
[store_unit]
|
||||
[filter]
|
||||
id=bob
|
||||
[/filter]
|
||||
variable=b
|
||||
[/store_unit]
|
||||
#damage without modification are 12, if test fail hitpoints !=76
|
||||
#if succed then damage by alice 24(bob more vulnerable to blade)
|
||||
#if succed then damage by bob 24(alice vulnerable to cold, cold [damage] is used)
|
||||
{ASSERT ({VARIABLE_CONDITIONAL a.hitpoints equals 76})}
|
||||
{ASSERT ({VARIABLE_CONDITIONAL b.hitpoints equals 76})}
|
||||
# damage without modification is 100
|
||||
# expected damage by alice is 200 (bob is vulnerable to blade, so the alternative isn't used)
|
||||
# expected damage by bob is 200 (alice is most vulnerable to cold, so that alternative is used)
|
||||
{ATTACK_AND_VALIDATE 200}
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
)}
|
||||
|
||||
#####
|
||||
# API(s) being tested: [filter_self][has_attack]type= in [damage_type]
|
||||
##
|
||||
# Actions:
|
||||
# Give Alice an ability that replace all damage by 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 (
|
||||
[event]
|
||||
name=start
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
apply_to=new_ability
|
||||
[abilities]
|
||||
[damage_type]
|
||||
id=test_arcane_damage
|
||||
replacement_type=arcane
|
||||
[filter_student]
|
||||
[has_attack]
|
||||
type=blade
|
||||
[/has_attack]
|
||||
[/filter_student]
|
||||
[/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
|
||||
[test_do_attack_by_id]
|
||||
attacker=alice
|
||||
defender=bob
|
||||
[/test_do_attack_by_id]
|
||||
[end_turn][/end_turn]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=side 2 turn
|
||||
[test_do_attack_by_id]
|
||||
attacker=bob
|
||||
defender=alice
|
||||
[/test_do_attack_by_id]
|
||||
[end_turn][/end_turn]
|
||||
[/event]
|
||||
|
||||
# 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 1})}
|
||||
[/event]
|
||||
)}
|
||||
|
|
|
@ -166,6 +166,8 @@
|
|||
0 event_test_filter_attack_specials
|
||||
0 event_test_filter_attack_on_moveto
|
||||
0 event_test_filter_attack_opponent_weapon_condition
|
||||
0 event_test_filter_attack_opponent_weapon_condition_no_triggered
|
||||
0 event_test_filter_attack_student_weapon_condition
|
||||
0 event_test_filter_wfl
|
||||
0 event_test_filter_wfl2
|
||||
0 event_test_filter_lua_serializable
|
||||
|
@ -375,6 +377,7 @@
|
|||
0 damage_type_test
|
||||
0 damage_type_with_filter_test
|
||||
0 damage_secondary_type_test
|
||||
0 event_test_filter_damage_type_recursion
|
||||
0 negative_resistance_with_two_attack_types
|
||||
0 positive_resistance_with_two_attack_types
|
||||
0 taught_resistance_with_two_attack_types
|
||||
|
|
Loading…
Add table
Reference in a new issue