fix(rules): undead and constructs are destroyed at hp <= 0
SRD Undead/Construct traits: 'immediately destroyed when reduced to 0 hit points or fewer' — undead and constructs have no Constitution score, so the PF1e hp <= -CON death rule does not apply to them. - combat.py: CombatantState.death_threshold returns 0 for creature_type undead/construct (in addition to the opt-in dies_at_zero flag) - tests: TestUndeadDeathThreshold pins undead dead at 0 and below, living keeps the disabled band at 0 and the dying band down to -CON - golden unchanged: tammara-vs-lich has the lich winning in 1 round without taking damage
This commit is contained in:
@@ -34,6 +34,7 @@ def _make_lich() -> Combatant:
|
||||
name="Lich",
|
||||
level=11,
|
||||
size="Medium",
|
||||
creature_type="undead",
|
||||
abilities=AbilityScores(
|
||||
str_score=12, dex_score=14, con_score=14,
|
||||
int_score=20, wis_score=14, cha_score=16,
|
||||
@@ -173,6 +174,42 @@ class TestFearAura:
|
||||
assert all(ac.condition.name != "shaken" for ac in foe_state.active_conditions)
|
||||
|
||||
|
||||
# ── Undead death threshold ────────────────────────────────────────────────────
|
||||
|
||||
|
||||
class TestUndeadDeathThreshold:
|
||||
"""Given: an undead creature (no CON score, SRD Undead traits)
|
||||
When: its hp reaches 0 or below
|
||||
Then: it is immediately destroyed (dead), unlike a living creature
|
||||
which keeps the disabled band at 0 and the dying band down to -CON."""
|
||||
|
||||
def test_undead_dead_at_zero(self) -> None:
|
||||
lich = _make_lich()
|
||||
state = _make_state(lich, "monsters", (1, 1))
|
||||
state.hp = 0
|
||||
assert state.dead is True
|
||||
assert state.active is False
|
||||
|
||||
def test_undead_dead_below_zero(self) -> None:
|
||||
lich = _make_lich()
|
||||
state = _make_state(lich, "monsters", (1, 1))
|
||||
state.hp = -1
|
||||
assert state.dead is True
|
||||
|
||||
def test_living_not_dead_at_zero(self) -> None:
|
||||
foe = _make_foe()
|
||||
state = _make_state(foe, "players", (1, 1))
|
||||
state.hp = 0
|
||||
assert state.dead is False
|
||||
assert state.active is True
|
||||
|
||||
def test_living_not_dead_in_dying_band(self) -> None:
|
||||
foe = _make_foe()
|
||||
state = _make_state(foe, "players", (1, 1))
|
||||
state.hp = -1 # -1 > -CON (12)
|
||||
assert state.dead is False
|
||||
|
||||
|
||||
# ── JSON integrity ────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user