✅ Buer attack exhausts then passive heals allies
| Category | Interaction |
| Status | Passing |
| Test | tests/test_abilities_passive.py::test_buer_attack_exhausts_then_passive_heals_allies |
Tests interaction between Buer, Sabnock, Morax.
Preconditions
-
P1 Main Phase, P1 has 3 AP
-
Lane 0: P1's Buer (#014) — 12 HP, PWR=3, 0 damage, READIED
-
Lane 0: P1's Ally A (Sabnock #003) — 15 HP, 5 damage, READIED
-
Lane 0: P1's Ally B (Morax #006) — 12 HP, 8 damage, READIED
-
Lane 0: P2's Enemy (any) — 12 HP, 0 damage, READIED
-
Lane 1: P1's Ally C (distant, Azag #066) — 9 HP, 6 damage, READIED
-
Buer passive registered: after exhaust, heal local allies by PWR
Action
-
P1 attacks with Buer targeting the enemy (2 AP, exhaust)
-
Buer exhausts → DEMON_EXHAUSTED event fires
-
Buer's passive triggers: remove 3 damage from each Other Local Allied Demon
from engine.operations import deal_damage, exhaust_demon, get_effective_pwr
from engine.events import fire_event, GameEvent, EventType, clear_triggers
import importlib
import engine.abilities_passive
clear_triggers()
importlib.reload(engine.abilities_passive)
buer = make_demon("014", lane=0, owner=Side.PLAYER_1)
ally_a = make_demon("003", lane=0, owner=Side.PLAYER_1, damage=5)
ally_b = make_demon("006", lane=0, owner=Side.PLAYER_1, damage=8)
enemy = make_demon("004", lane=0, owner=Side.PLAYER_2)
ally_c = make_demon("066", lane=1, owner=Side.PLAYER_1, damage=6) # distant
state = make_game_state(phase=Phase.MAIN, current_player=Side.PLAYER_1)
state.players[Side.PLAYER_1].ap = 3
state = place_demon(state, buer)
state = place_demon(state, ally_a)
state = place_demon(state, ally_b)
state = place_demon(state, enemy)
state = place_demon(state, ally_c)
buer_p = state.demons[0]
enemy_p = state.demons[3]
# Buer attacks enemy — deal PWR damage
pwr = get_effective_pwr(state, buer_p)
Expected Postconditions
-
Enemy: took 3 damage (Buer's PWR, no DEF)
-
Buer: EXHAUSTED, 0 damage (passive says "Other" — Buer does NOT heal itself)
-
Ally A (lane 0): 2 damage (was 5, healed 3 by Buer's PWR)
-
Ally B (lane 0): 5 damage (was 8, healed 3)
-
Ally C (lane 1): 6 damage unchanged (different lane — passive is Local only)
Assertions
assert pwr == 3, f"Buer PWR should be 3, got {pwr}"
state = deal_damage(state, buer_p, enemy_p, pwr)
# Exhaust Buer (attack requires exhaust)
buer_ref = next(d for d in state.demons if d.unit_id == "014")
state = exhaust_demon(state, buer_ref)
# Fire DEMON_EXHAUSTED event — Buer's passive should trigger
buer_ref = next(d for d in state.demons if d.unit_id == "014")
event = GameEvent(
event_type=EventType.DEMON_EXHAUSTED,
source=buer_ref,
target=buer_ref,
value=None,
side=Side.PLAYER_1,
lane=0,
)
result = fire_event(state, event)
# Verify enemy took damage
enemy_after = next(d for d in result.demons if d.unit_id == "004")
assert enemy_after.damage == 3, f"Enemy should have 3 damage from Buer's attack. Got {enemy_after.damage}"
# Verify Buer is exhausted and NOT healed (passive says "Other")
buer_after = next(d for d in result.demons if d.unit_id == "014")
assert buer_after.state == DemonState.EXHAUSTED
assert buer_after.damage == 0, "Buer should NOT heal itself (passive says Other)"
# Verify Ally A healed: 5 - 3 = 2
ally_a_after = next(d for d in result.demons if d.unit_id == "003")
assert ally_a_after.damage == 2, (
f"Ally A should have 2 damage (5 - 3 healed by Buer PWR). Got {ally_a_after.damage}"
)
# Verify Ally B healed: 8 - 3 = 5
ally_b_after = next(d for d in result.demons if d.unit_id == "006")
assert ally_b_after.damage == 5, (
f"Ally B should have 5 damage (8 - 3 healed by Buer PWR). Got {ally_b_after.damage}"
)
# Verify Ally C NOT healed (different lane — passive is Local)
ally_c_after = next(d for d in result.demons if d.unit_id == "066")
assert ally_c_after.damage == 6, (
f"Ally C should still have 6 damage (different lane, not healed). Got {ally_c_after.damage}"
)