fix(spells): set the correct area shapes
SRD-verified area templates: Burning Hands 15-ft cone, Color Spray 15-ft cone, Fear 30-ft cone, Flurry of Snowballs 30-ft cone, Lightning Bolt 120-ft line (all converted from single-target/burst approximations to proper AreaEffect shapes); Fireball 20-ft burst, Sound Burst 10-ft spread, Sleep 10-ft burst, Web 20-ft spread kept. Close-range spells note the 15/30-ft RAW ranges as an approximation in their descriptions. README: cone/scaling limitations moved out of the limitations list, new area-shape + caster-level scaling rules documented, areas.py added to the architecture. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -391,8 +391,10 @@ def test_tammara_deed_out_of_range_spends_no_grit() -> None:
|
||||
|
||||
|
||||
def test_misty_emits_inspire_courage_and_spell_combat() -> None:
|
||||
# Shocking Grasp (not Burning Hands): the offensive-spell scan reads
|
||||
# top-level damage effects, and Burning Hands is a cone area spell now.
|
||||
misty = _combatant(
|
||||
"misty", resources={"bardic_rounds": 12}, spells=["Burning Hands"]
|
||||
"misty", resources={"bardic_rounds": 12}, spells=["Shocking Grasp"]
|
||||
)
|
||||
goblin = _combatant("goblin", hp_max=6)
|
||||
reg = load_spell_registry(SPELLS_DIR)
|
||||
|
||||
+12
-6
@@ -458,20 +458,26 @@ class TestTargetedSpellSaveNegates:
|
||||
|
||||
|
||||
class TestLightningBoltSave:
|
||||
"""Given: Lightning Bolt (ref save for half, half_on_save=True, 1d6 per
|
||||
caster level max 10d6 — SRD spells/lightning-bolt.md)
|
||||
When: the level-5 target succeeds its save
|
||||
Then: damage is halved from the SCALED 5d6."""
|
||||
"""Given: Lightning Bolt (SRD spells/lightning-bolt.md: a 120-ft. line,
|
||||
1d6 per caster level max 10d6, ref save for half) cast by the level-5
|
||||
fixture at a target straight ahead
|
||||
When: the primary target succeeds its save
|
||||
Then: damage is halved — and the caster, whose own square the line
|
||||
starts in ("the bolt begins at your fingertips"), is caught as well."""
|
||||
|
||||
def test_successful_save_still_halves(self) -> None:
|
||||
caster = _make_caster()
|
||||
target = _make_target(hp_max=200)
|
||||
# 1 save roll (natural 20 = success) + 5 damage dice (caster level 5)
|
||||
engine, c, t = _make_engine(caster, target, [20, 3, 3, 3, 3, 3])
|
||||
# primary save (target) + secondary save (caster, same line) +
|
||||
# 5 damage dice each (1d6/level, level 5)
|
||||
engine, c, t = _make_engine(
|
||||
caster, target, [20, 20] + [3] * 10
|
||||
)
|
||||
hp_before = t.hp
|
||||
engine._cast_spell(c, t, "Lightning Bolt")
|
||||
full = 3 + 3 + 3 + 3 + 3
|
||||
assert t.hp == hp_before - (full // 2)
|
||||
assert c.hp == 20 - (full // 2)
|
||||
|
||||
|
||||
class TestDamageEffectHalfOnSaveDefault:
|
||||
|
||||
Reference in New Issue
Block a user