- arcane_caster true: misty (Magus/Bard sheet class), nairda (Witch/
Sorcerer), thrune_agent (Human magus 8, KB bestiary/thrune-agent.md);
lich already true. False: oni (Cleric), tammara (Gunslinger/
Warpriest - divine), esha (Cavalier/Rogue, spell-like only), the
companions harvie/ierlieth/jeanne/esha_mount and the remaining
monsters.
- armor_spell_failure stays 0 everywhere, as the effective PF1e value:
nairda and the lich wear no armor (sheet note "Pas d'armure", KB lich
block); misty's mithral shirt (RAW ASF 10%, magic-items/mithral-shirt
.md) and the thrune agent's +1 studded leather (15%) are light armor
and every spell they cast is on their own class list - magus and bard
cast their own spells in light armor with no arcane spell failure
(classes/magus.md, classes/bard.md).
- tests/test_spell_failure.py: the lich/oni smoke test becomes a
full-data table pinning all 15 combatants' flags with per-entry
sources. No shipped combatant incurs a non-zero ASF; the failure roll
itself stays covered by the synthetic armored-caster tests.
Adds the PF1e two-axis alignment code (LG/NG/CG/LN/N/CN/LE/NE/CE,
default N) to the Combatant model with a strict validator, derived
is_lawful/is_chaotic/is_good/is_evil properties, exposure in the
observation snapshot, and alignment values for all monsters and PCs
sourced from the bestiary KB and the Foundry sheets.
PF1e (CRB "Natural Attacks"):
- Natural weapons (natural=true) get exactly one swing per full attack,
regardless of BAB (no BAB iteratives for natural attacks).
- Secondary natural attacks (secondary=true) attack at BAB -5; the
Multiattack feat reduces this to -2.
- Manifested in combat.py (_full_attack_weapon, _resolve_swing),
models.py (AttackSpec.natural/secondary), 6 data JSONs, 4 new tests,
and README documentation.
1461 passed, ruff clean, basedpyright 0 errors.