Commit Graph

69 Commits

Author SHA1 Message Date
ctan 0de5452a39 fix(data): lich fear aura, paralyzing touch, slot keys 2026-09-01 16:26:29 +02:00
ctan fdbfc00dd1 feat(data): wire all 55 PC feats 2026-09-01 15:39:10 +02:00
ctan edf8695ff0 fix(combat): single roll to escape grapple 2026-09-01 15:31:30 +02:00
ctan 88bde16e17 fix(combat): sunder damages weapon not HP 2026-09-01 15:25:09 +02:00
ctan e22c2e1d31 feat(combat): Combat Reflexes extra AoOs 2026-09-01 15:18:37 +02:00
ctan 1a4d7d8a2b feat(combat): enforce prone/staggered/nauseated/paralyzed 2026-09-01 14:57:27 +02:00
ctan ce83356931 fix(combat): bound cackle hex extension 2026-09-01 14:33:45 +02:00
ctan a61ab6436c fix(combat): summoned creatures act and expire 2026-09-01 14:25:51 +02:00
ctan 3cebf43642 refactor(combat): single source active_buffs/active_conditions 2026-08-31 14:24:57 +02:00
ctan 12c76a1396 feat(combat): class-ability action kinds, engine RNG only 2026-08-31 14:15:57 +02:00
ctan d50d5809c6 fix(combat): correct hex and AoE DCs, DR bypassed by spells 2026-08-31 14:02:08 +02:00
ctan f1cf353a4d fix(combat): correct concentration DCs by situation 2026-08-31 13:35:34 +02:00
ctan a88187db20 feat(runner): wire spell registry in CLI and Monte Carlo 2026-08-31 13:22:16 +02:00
ctan 3f65e769cf feat(data): per-level spell slots for 8 PCs 2026-08-31 11:15:37 +02:00
ctan 721812f718 chore(lint): restore green gate 2026-08-31 10:57:11 +02:00
ctan 4409b0de17 feat(data): lich monster 2026-08-30 15:24:28 +02:00
ctan ad28dc9921 feat(combat): class action patterns 2026-08-30 15:11:08 +02:00
ctan 92ddefc2d1 feat(combat): channel energy and hexes 2026-08-30 11:14:20 +02:00
ctan 24b6125eb6 feat(data): companions and mounts 2026-08-30 10:33:12 +02:00
ctan 757d17bfbc feat(loaders): map 8-PC feats 2026-08-30 09:39:24 +02:00
ctan eb666993e7 feat(combat): summoning 2026-08-30 09:04:21 +02:00
ctan e158ea7e11 feat(combat): combat maneuvers CMB/CMD 2026-08-30 00:39:33 +02:00
ctan 2615c9ccb2 feat(combat): area-of-effect spells 2026-08-30 00:36:16 +02:00
ctan de6c605808 feat(combat): spellcasting default policy 2026-08-29 23:57:13 +02:00
ctan 99686158cf feat(combat): skills system 2026-08-29 23:29:17 +02:00
ctan de399b74b8 feat(combat): AoO and concentration on casting 2026-08-29 22:47:22 +02:00
ctan aaa1ef5661 feat(combat): enforce behavioral condition flags 2026-08-29 20:58:38 +02:00
ctan beee8e4e6a feat(combat): metamagic 2026-08-29 20:44:17 +02:00
ctan 53aa3567f2 feat(models): combat resources 2026-08-29 20:29:31 +02:00
ctan 5c393ec66c fix(combat): correct spell DC formula 2026-08-29 20:26:00 +02:00
ctan 8b5ba12f46 feat(combat): effect and condition durations 2026-08-29 20:14:36 +02:00
ctan 2e49aa7293 docs(handoff): add finalize-engine plan for session transfer 2026-08-29 13:37:32 +02:00
ctan 52904a0d03 docs(handoff): add session summary for pf1e-simulator transfer 2026-08-29 13:35:47 +02:00
ctan 37f07d90a7 chore(data): drop Plot Armor from misty features (non-combat feat) 2026-08-18 17:34:48 +02:00
ctan 82148cea1e test(loaders): add unit tests for combatant feat resolution and feature/spell handling
Tests for _resolve_feat (known/unknown/Toughness/Weapon Focus),
_resolve_features (filtering, empty lists), load_combatant with
features+spells integration, and backward-compat aliases.

Gate: 401 tests, ruff clean, basedpyright clean.
2026-08-18 15:11:28 +02:00
ctan 36f72dcb37 chore(clean): cleanup .codegraph 2026-08-17 22:54:53 +02:00
ctan 557bb2304a fix(git): fix gitignore for .codegraph 2026-08-17 22:53:58 +02:00
ctan c88d8fd6f4 refactor(loaders): unify combatant loader, migrate PC features/spells
Rename monster.py → combatant.py with _KNOWN_FEATS lookup table
that resolves feat name strings to AbilitySpec constants (Power Attack,
Iron Will, Toughness, Weapon Focus, etc.). Unknown feats produce
minimal AbilitySpec (data preserved for future implementation).

Migrate all 8 PC JSONs (data/pcs/) with complete feat/spell lists
extracted from Foundry sheets — including traits, racial abilities,
and all spells. Monsters (goblin, orc) unchanged (no feats/spells).

Update all imports, add backward-compatible aliases (load_monster,
MonsterLoadError), update CLI to use load_combatant.

Gate: 377 tests, ruff clean, basedpyright clean.
2026-08-17 22:49:50 +02:00
ctan e9e8c26d50 feat(loaders): extend Foundry loader with feat/spell extraction
Map Foundry feat strings to AbilitySpec constants (Power Attack, Iron Will,
Alertness, Point-Blank Shot, Precise Shot, Dodge, Weapon Focus (X)).
Extract spell names from spellcasting.spells into Combatant.spells.
Wire features and spells into load_sheet_detailed return.
Add 41 tests (unit + golden on 8 real sheets).

Gate: 377 tests, ruff clean, basedpyright clean.
2026-08-17 22:49:50 +02:00
ctan 828afc15c0 feat(spells): add spell system with 10 combat spells, cast_spell action
Spells are SpellSpec dataclasses with typed effects: DamageEffect
(dice + types, half-on-save), ConditionEffect (condition lookup +
save negates), HealEffect (capped at hp_max), BuffEffect (transient
StatModifiers). Range categories (personal/touch/close/medium/long)
scale with caster level via spell_range_ft. JSON loader
(load_spell/load_spell_registry) reads data/spells/*.json.

The engine integrates spells via Action(kind='cast_spell') and
_cast_spell: range check, line-of-effect gate, save resolution
(resolve_save), effect application (_apply_spell_effects with DR
via _apply_dr_for_types), transcript logging. The spell_registry
is passed to CombatEngine; Combatant.spells holds known spell names.

- spells.py: SpellSpec, 4 effect types, SpellRange/SaveType literals,
  spell_range_ft, JSON loader (uses Json type from foundry.py)
- conditions.py: CONDITIONS_BY_NAME registry for condition lookup
- combat.py: cast_spell Action kind, _execute_cast_spell dispatch,
  _cast_spell (range/LoE/save/effects/log), _apply_spell_effects,
  _apply_dr_for_types, _save_label helper, SpellSpec/BuffEffect/etc
  imports, spell_registry parameter on CombatEngine
- models.py: spells field on Combatant
- data/spells/: 10 spells (Magic Missile, Burning Hands, Fireball,
  Lightning Bolt, Acid Arrow, Cure Light/Moderate Wounds, Hold Person,
  Fear, Bull's Strength)
- tests/test_spells.py: 29 tests (loading, range, damage/save/condition/
  heal/buff/DR, out-of-range, unknown spell, dispatch, DC scaling)
- pyproject.toml: PLR0913 ignore for combat.py (CombatEngine.__init__)
- README.md: spells.py architecture section, Sorts removed from
  non-modeled list, 336 tests
2026-08-17 22:49:50 +02:00
ctan 97c0431479 feat(abilities): add Power Attack active feat (-X atk / +2X dmg, melee only)
Power Attack is the first active feat: a free-action toggle declared at
turn start. When state.power_attack is True and the combatant has the
POWER_ATTACK feature, melee attacks apply -X to the attack roll and
+2X to damage, where X = BAB//4 + 1 (min 1). Ranged attacks are
unaffected. The flag is cleared at the start of each turn via
_take_turn, like other per-turn state.

- abilities.py: POWER_ATTACK constant (AbilitySpec, no passive effects)
- combat.py: _has_feat helper, _power_attack_amt, resolve_attack
  applies penalty to attack total + crit confirm, bonus to damage
- tests/test_power_attack.py: 14 tests (amount at BAB 1/4/8/12, flag
  false, feat missing, attack penalty, damage bonus, ranged unaffected,
  flag cleared on turn)
- pyproject.toml: add SLF001 + RUF059 to test per-file-ignores (white-box
  testing accesses private helpers, partial tuple unpacking)
- README.md: document Power Attack in abilities.py section, 307 tests
2026-08-17 22:49:50 +02:00
ctan ba1c3c2117 feat(abilities): add passive feats system (Weapon Focus, Iron Will, Dodge, Point-Blank Shot) 2026-08-17 22:49:50 +02:00
ctan a32444f804 feat(conditions): add condition system with 18 PF1e conditions 2026-08-17 22:49:50 +02:00
ctan 2cd8a33a4d feat(combat): add saving throws (fort/ref/will, natural 1/20, effect modifiers) 2026-08-17 22:49:50 +02:00
ctan 88f11de40f refactor(combat): replace ac_penalty with effect system 2026-08-17 22:49:50 +02:00
ctan 8ac6f9eabe feat(effects): add effect system with PF1e bonus stacking rules 2026-08-17 22:49:50 +02:00
ctan 94521394ef feat(combat): add 5-foot step (free action, no AoO, mutual exclusion with move) 2026-08-17 22:49:50 +02:00
ctan 5b8735f001 fix(combat): separate standard attack (single swing) from full attack (iteratives) 2026-08-17 22:49:50 +02:00
ctan 5b1957152c feat(combat): add withdraw action (double move with AoO protection on first square) 2026-08-17 22:49:50 +02:00
ctan 7543c55ed4 feat(combat): add charge action (straight-line 2x speed, +2 attack, -2 AC) 2026-08-17 22:49:50 +02:00