✅ Morax fused with murmur nurture costs 0 ap
| Category | Ability |
| Status | Passing |
| Test | tests/test_abilities_passive.py::test_morax_fused_with_murmur_nurture_costs_0_ap |
Tests interaction between Morax, Sabnock.
Preconditions
-
P1 Main Phase, P1 has 3 AP
-
Lane 0: P1's Morax (#006) fused with Murmur (#002)
-
Fused HP = 12 + 3 (fHP) = 15
-
Fused PWR = 4 + 2 (fPWR) = 6
-
Murmur passive: -2 AP Cost (active as bottom card)
-
READIED
-
Lane 0: P1's ally demon — 15 HP, 10 damage, READIED
Action
-
Morax-Murmur casts Nurture (ability[0], Quick, 1 AP, ready, 1x)
-
Effective AP cost: max(0, 1 - 2) = 0 AP
-
Nurture heals target by PWR = 6
from engine.abilities import execute_ability
from engine.operations import get_effective_pwr, get_effective_ap_cost
import importlib
import engine.abilities_actions
import engine.abilities_passive
importlib.reload(engine.abilities_actions) # force re-registration after fixture clear
importlib.reload(engine.abilities_passive)
# Create fused Morax (top) + Murmur (bottom)
fused = make_fused_demon("006", "002", lane=0, owner=Side.PLAYER_1)
ally = make_demon("003", lane=0, owner=Side.PLAYER_1, damage=10) # Sabnock as ally
state = make_game_state(phase=Phase.MAIN, current_player=Side.PLAYER_1)
state.players[Side.PLAYER_1].ap = 3
state = place_demon(state, fused)
state = place_demon(state, ally)
fused_p = state.demons[0]
ally_p = state.demons[1]
# Verify fusion stats
pwr = get_effective_pwr(state, fused_p)
Expected Postconditions
-
P1 AP: 3 (unchanged — Nurture cost 0 with Murmur's -2 AP)
-
Ally damage: 4 (was 10, healed 6)
-
Morax-Murmur: still READIED (Nurture has ready_required, does NOT exhaust)
Assertions
assert pwr == 6, f"Fused PWR should be 6 (Morax 4 + Murmur fPWR 2). Got {pwr}"
# Verify effective AP cost of Nurture (ability[0], base cost 1)
effective_cost = get_effective_ap_cost(state, fused_p, 1)
assert effective_cost == 0, f"Nurture should cost 0 AP (1 - 2 = 0). Got {effective_cost}"
# Cast Nurture targeting ally
result = execute_ability(state, fused_p, ability_idx=0, targets=[ally_p])
# AP unchanged — cost was 0
assert result.players[Side.PLAYER_1].ap == 3, (
f"AP should be 3 (Nurture cost 0 with Murmur's -2). Got {result.players[Side.PLAYER_1].ap}"
)
# Ally healed by fused PWR (6)
ally_after = next(d for d in result.demons if d.instance_id == ally_p.instance_id)
assert ally_after.damage == 4, (
f"Ally should have 4 damage (10 - 6 healed by PWR). Got {ally_after.damage}"
)
# Morax-Murmur still READIED (ready_required does NOT exhaust)
fused_after = next(d for d in result.demons if d.unit_id == "006")
assert fused_after.state == DemonState.READIED, (
f"Fused demon should still be READIED (Nurture uses ready, not exhaust). Got {fused_after.state}"
)