From d9b590ebce75a2480997958f5ceff9eda0c4021f Mon Sep 17 00:00:00 2001 From: ctan Date: Sat, 19 Sep 2026 13:12:36 +0200 Subject: [PATCH] fix(rules): acid arrow recurring total cap (1+6=7 rounds at 18th, the SRD max counts additional rounds) and ice slick flat scaling 1d6+1/level max +10 (SRD spells/acid-arrow.md, spells/ice-slick.md) --- data/spells/acid_arrow.json | 4 ++-- data/spells/ice_slick.json | 5 +++-- src/pf1e_simulator/spells.py | 6 ++++-- tests/test_recurring_damage.py | 12 +++++++----- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/data/spells/acid_arrow.json b/data/spells/acid_arrow.json index 6a6b268..667de8a 100644 --- a/data/spells/acid_arrow.json +++ b/data/spells/acid_arrow.json @@ -19,9 +19,9 @@ "types": ["acid"], "base_rounds": 1, "per_levels": 3, - "max": 6 + "max": 7 } } ], - "description": "SRD spells/acid-arrow.md: ranged touch attack dealing 2d4 acid damage, plus another 2d4 acid damage at the start of each of the target's turns for 1 round + 1 round per three caster levels (maximum 6 additional rounds). Recurring damage is reduced by energy resistance/immunity, not by DR. No save." + "description": "SRD spells/acid-arrow.md: ranged touch attack dealing 2d4 acid damage, plus another 2d4 acid damage at the start of each of the target's turns for 1 round + 1 round per three caster levels (maximum 6 ADDITIONAL rounds at 18th level, i.e. 7 recurring rounds total). Recurring damage is reduced by energy resistance/immunity, not by DR. No save." } diff --git a/data/spells/ice_slick.json b/data/spells/ice_slick.json index f38fc84..56a9499 100644 --- a/data/spells/ice_slick.json +++ b/data/spells/ice_slick.json @@ -16,7 +16,8 @@ "type": "damage", "formula": "1d6", "types": ["cold"], - "half_on_save": true + "half_on_save": true, + "scaling_flat": { "amount": 1, "per_levels": 1, "max": 10 } }, { "type": "condition", @@ -27,5 +28,5 @@ ] } ], - "description": "A blast of intense cold coats a 5-ft-radius burst in ice: creatures in the area take 1d6 points of cold damage (Reflex half) and fall prone (no prone on a successful save). The lingering slippery surface (half speed, Acrobatics checks) is not modeled." + "description": "SRD spells/ice-slick.md: a blast of intense cold coats a 5-ft-radius burst in ice: creatures in the area take 1d6 points of cold damage + 1 point per caster level (maximum +10) and fall prone; a successful Reflex save halves the damage and avoids falling prone. The lingering slippery surface (half speed, Acrobatics checks) is not modeled." } diff --git a/src/pf1e_simulator/spells.py b/src/pf1e_simulator/spells.py index 1ed6218..d3cd9cc 100644 --- a/src/pf1e_simulator/spells.py +++ b/src/pf1e_simulator/spells.py @@ -108,8 +108,10 @@ class RecurringDamageSpec: never by DR (it is spell damage) - base_rounds / per_levels / max_rounds: rounds of recurrence scale with caster level as ``base_rounds + caster_level // per_levels`` capped at - ``max_rounds`` (SRD spells/acid-arrow.md: "1 round + 1 round per three - levels [...] to a maximum of 6 additional rounds"). + ``max_rounds`` TOTAL rounds (JSON key "max" is the total, not the + additional count: SRD spells/acid-arrow.md "1 round + 1 round per three + levels [...] to a maximum of 6 additional rounds" = base_rounds 1, + max_rounds 7). """ formula: DiceExpr types: tuple[str, ...] diff --git a/tests/test_recurring_damage.py b/tests/test_recurring_damage.py index aca8778..31592ab 100644 --- a/tests/test_recurring_damage.py +++ b/tests/test_recurring_damage.py @@ -118,9 +118,11 @@ def _acid_rounds(level: int) -> int: class TestAcidArrowRecurringRounds: """Given: Acid Arrow's recurring scaling (1 + one round per three levels, - max 6) + max 6 ADDITIONAL rounds = 7 total at 18th) When: resolved for caster levels 1 / 3 / 18 - Then: it is 1 / 2 / 6 rounds (SRD spells/acid-arrow.md).""" + Then: it is 1 / 2 / 7 rounds (SRD spells/acid-arrow.md: "1 round + 1 round + per three levels [...] to a maximum of 6 additional rounds at 18th level" + - the cap counts ADDITIONAL rounds, so the total is 1 + 6 = 7).""" def test_one_round_at_low_level(self) -> None: assert _acid_rounds(1) == 1 @@ -128,9 +130,9 @@ class TestAcidArrowRecurringRounds: def test_two_rounds_at_level_3(self) -> None: assert _acid_rounds(3) == 2 - def test_caps_at_six(self) -> None: - assert _acid_rounds(18) == 6 - assert _acid_rounds(20) == 6 + def test_caps_at_seven_total(self) -> None: + assert _acid_rounds(18) == 7 + assert _acid_rounds(20) == 7 class TestAcidArrowAttachesRecurring: