Skip to main content

✅ Morax fused with murmur nurture costs 0 ap

CategoryAbility
StatusPassing
Testtests/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}"
)