fix(combat): _find_ally_needing_heal counts only living allies (SRD Channel Energy: heal mode heals living creatures, positive energy never heals undead) - an undead ally below half triggered heal mode, spending the channel to heal nobody; + trigger regression test
This commit is contained in:
@@ -8311,15 +8311,21 @@ def _find_heal_spell(engine: CombatEngine, spells_known: list[str]) -> str | Non
|
||||
|
||||
|
||||
def _find_ally_needing_heal(engine: CombatEngine, caster: CombatantState) -> CombatantState | None:
|
||||
"""Find an ally below half HP.
|
||||
"""Find a living ally below half HP.
|
||||
|
||||
``hp * 2 < hp_max`` is strictly-below-half for every hp_max; the old
|
||||
``hp < hp_max // 2`` floored the threshold (hp_max 5 -> 2), so a level-1
|
||||
character at 2/5 hp counted as healthy.
|
||||
|
||||
Living-only (SRD Channel Energy: heal mode heals living creatures; undead
|
||||
take damage from positive energy, never healing): an undead ally below
|
||||
half must not trigger the heal paths - channel heal would spend the
|
||||
channel without helping it, and a cure spell would hurt it.
|
||||
"""
|
||||
for ally_state in engine.states:
|
||||
below_half = ally_state.hp * 2 < ally_state.combatant.hp_max
|
||||
if ally_state.side == caster.side and ally_state.active and below_half:
|
||||
living = ally_state.combatant.creature_type == "living"
|
||||
if ally_state.side == caster.side and ally_state.active and living and below_half:
|
||||
return ally_state
|
||||
return None
|
||||
|
||||
|
||||
@@ -156,6 +156,24 @@ def test_oni_silent_when_channel_energy_exhausted() -> None:
|
||||
assert not any(a.kind == "channel_energy" for a in actions)
|
||||
|
||||
|
||||
def test_oni_no_channel_heal_trigger_for_undead_ally() -> None:
|
||||
"""SRD Channel Energy: heal mode heals living creatures. An undead ally
|
||||
below half cannot benefit (positive energy harms undead), so it must not
|
||||
trigger the heal mode - the channel would be spent healing nobody."""
|
||||
oni = _combatant("oni", resources={"channel_energy": 6}, hp_max=30)
|
||||
goblin = _combatant("goblin", hp_max=6)
|
||||
engine, me, _ = _engine(oni, [goblin])
|
||||
undead_ally = _state(
|
||||
_combatant("ghoul", hp_max=20, creature_type="undead"),
|
||||
"players", (5, 5), hp=5,
|
||||
)
|
||||
engine.states.append(undead_ally)
|
||||
|
||||
actions = default_policy(engine, me)
|
||||
|
||||
assert not any(a.kind == "channel_energy" for a in actions)
|
||||
|
||||
|
||||
def test_oni_channel_energy_spends_resource() -> None:
|
||||
oni = _combatant("oni", resources={"channel_energy": 6}, hp_max=30)
|
||||
goblin = _combatant("goblin", hp_max=6)
|
||||
|
||||
Reference in New Issue
Block a user