fix(rules): add alchemical/inherent/resistance/size bonus types (UM Table 2-7) as non-stacking

This commit is contained in:
2026-09-16 21:48:40 +02:00
parent ae037c984f
commit b3a7c3787d
2 changed files with 24 additions and 1 deletions
+7
View File
@@ -44,6 +44,13 @@ BonusType = Literal[
"shield", # no stack "shield", # no stack
"armor", # no stack (SRD mage armor: "+4 armor bonus to AC") "armor", # no stack (SRD mage armor: "+4 armor bonus to AC")
"circumstance", # no stack (simulator can't distinguish circumstances) "circumstance", # no stack (simulator can't distinguish circumstances)
# SRD "Ultimate Magic" Table 2-7: Bonus Types and Effects — remaining
# named types, all non-stacking like every typed bonus (CRB "Combining
# Magic Effects": "two bonuses of the same type don't stack").
"alchemical", # no stack (UM T2-7: ability scores, saves; antitoxin)
"inherent", # no stack (UM T2-7: ability scores; Manual of bodily health)
"resistance", # no stack (UM T2-7: saves; cloak of resistance)
"size", # no stack (UM T2-7: ability scores, attacks, AC; enlarge person)
] ]
StatTarget = Literal[ StatTarget = Literal[
+17 -1
View File
@@ -2,7 +2,7 @@
from __future__ import annotations from __future__ import annotations
from pf1e_simulator.effects import StatModifier, resolve_modifiers from pf1e_simulator.effects import BonusType, StatModifier, resolve_modifiers
# ── Stacking types: sum together ────────────────────────────────────────────── # ── Stacking types: sum together ──────────────────────────────────────────────
@@ -228,3 +228,19 @@ class TestEdgeCases:
StatModifier("ac", 3, "morale"), StatModifier("ac", 3, "morale"),
] ]
assert resolve_modifiers(mods) == 3 # same non-stacking type → max(2, 3) assert resolve_modifiers(mods) == 3 # same non-stacking type → max(2, 3)
def test_um_table_2_7_bonus_types_parse_and_do_not_stack(self) -> None:
# SRD "Ultimate Magic" Table 2-7 types: alchemical, inherent,
# resistance, size — accepted by StatModifier, non-stacking.
new_types: tuple[BonusType, ...] = (
"alchemical",
"inherent",
"resistance",
"size",
)
for bonus_type in new_types:
mods = [
StatModifier("ac", 2, bonus_type),
StatModifier("ac", 4, bonus_type),
]
assert resolve_modifiers(mods) == 4, bonus_type