✅ Cycle of life heals local allies immediately
| Category | Interaction |
| Status | Passing |
| Test | tests/test_abilities_complex.py::TestVapulaCycleOfLife::test_cycle_of_life_heals_local_allies_immediately |
Activating Cycle of Life heals all local allied demons by Vapula's PWR.
Preconditions
-
P1 Main Phase, Vapula (#100, PWR=3) on field in Lane 0
-
Lane 0: P1's Murmur (#002) — 5 damage
-
Lane 0: P1's Vapula — 2 damage (local-allied to itself)
-
Lane 0: P2's Duban (#001) — 4 damage (NOT allied — should not be healed)
-
Lane 1: P1's Sabnock (#003) — 3 damage (NOT local — should not be healed)
Action
- Vapula activates Cycle of Life (ability_idx=1)
result = handler(state, vapula_in, [], {}, None)
vapula_after = next(d for d in result.demons if d.unit_id == "100")
murmur_after = next(d for d in result.demons if d.unit_id == "002")
duban_after = next(d for d in result.demons if d.unit_id == "001")
sabnock_after = next(d for d in result.demons if d.unit_id == "003")
Expected Postconditions
-
Murmur: 5 - 3 = 2 damage (healed by PWR=3)
-
Vapula: 0 damage (healed by 3 from 2 → floor 0)
-
Duban: 4 damage unchanged (enemy, not healed)
-
Sabnock: 3 damage unchanged (different lane, not Local)
-
Vapula has a cycle_of_life_pending status marker for end-of-phase damage
Assertions
assert murmur_after.damage == 2, f"Murmur (ally): 5-3=2. Got {murmur_after.damage}."
assert vapula_after.damage == 0, f"Vapula heals itself: max(0, 2-3)=0. Got {vapula_after.damage}."
assert duban_after.damage == 4, f"Duban (enemy): unchanged. Got {duban_after.damage}."
assert sabnock_after.damage == 3, f"Sabnock (non-local): unchanged. Got {sabnock_after.damage}."
# Marker status for end-of-phase damage
effects = get_active_effects_on(result, vapula_after)
pending = [e for e in effects if e.stat == "cycle_of_life_pending"]
assert len(pending) == 1, "Vapula should have cycle_of_life_pending marker for end-of-phase damage."