Commit Graph

119 Commits

Author SHA1 Message Date
ctan 9c6f5e277e feat(cli): render --transcript output as a table 2026-09-11 13:02:31 +02:00
ctan d6c8f88f77 feat(cli): add --simple-monster-death option to kill monsters at hp <= 0 2026-09-11 12:48:43 +02:00
ctan b7c80babfd fix(rules): enforce the action-economy budget on policy output
Apply the PF1e per-turn action budget (CRB Actions in Combat: one
standard + one move, or one full-round in place of both, plus one
swift) unconditionally to every sequence a policy returns, not only
the immediate/staggered/nauseated specializations.

- _action_economy_filter: greedy in-order walk keeping the earliest
  legal prefix-subsequence; a full-round action is only kept while
  both the standard and move slots are still free.
- Exhaustive kind->slot classification (standard / move / swift /
  full_round / free-conditional) over the Action.kind Literal,
  documented and locked by tests.
- Surplus actions dropped and reported as
  ActionResult(ok=False, reason="downgraded:action_economy") via a
  multiset drop diff (reports duplicate-kind surplus the set-based
  _dropped_kinds cannot).
- Composition order: general budget first, then the existing
  immediate/staggered/nauseated filters (unchanged).
- default_policy untouched and its turns verified legal by the
  validator; golden transcripts byte-identical.
2026-09-11 12:26:49 +02:00
ctan a4814b935b fix(rules): apply cover by attacker's best corner for multi-square attackers 2026-09-11 11:43:10 +02:00
ctan 9fb1c2d75a fix(rules): apply energy resistance per damage component 2026-09-11 11:24:11 +02:00
ctan 1960b8f655 fix(rules): scale Power Attack for two-handed weapons and apply its CMB penalty 2026-09-11 00:19:06 +02:00
ctan 890b7959d4 fix(rules): correct metamagic slots, touch-spell delivery, and defensive/grapple casting 2026-09-11 00:06:06 +02:00
ctan 9aee4f6f6b fix(rules): correct P2/P3 PF1e conformance bugs (flanking, touch, blinded, disabled, death, maneuvers, DR, sneak) 2026-09-10 21:45:50 +02:00
ctan 5afe495c4a fix(rules): correct P1 PF1e conformance bugs (area saves, concentration, prone, slots, helpless, nauseated) 2026-09-10 20:52:28 +02:00
ctan 1ca5aed758 data(spells): add batch 3 of PC spell list (32 spells) 2026-09-10 19:43:07 +02:00
ctan 543da6a931 data(spells): add batch 2 of PC spell list (32 spells) 2026-09-10 19:12:57 +02:00
ctan 07e0d83300 data(spells): add batch 1 of PC spell list (32 spells) 2026-09-10 18:49:54 +02:00
ctan 91f70f19ca feat(conditions): add bleeding and confused rules 2026-09-10 18:15:35 +02:00
ctan b3bff85215 feat(conditions): add blinded/invisible/helpless/fascinated combat rules 2026-09-10 18:00:41 +02:00
ctan 79ac190728 feat(combat): use fly speed for movement
Movement budget is now max(land, fly) speed. Updates the harvie golden: Harvie (land 10 / fly 80) is a flyer and now flies at 80 ft, so he wins vs the goblin instead of being pinned crawling at 10 ft.
2026-09-10 17:46:57 +02:00
ctan ec0397351a test(rules): lock in that size is baked into attack/AC values 2026-09-10 17:25:05 +02:00
ctan 582b6c60d1 feat(observation): expose ranged threat grid 2026-09-10 17:12:54 +02:00
ctan f637f87a8c feat(combat): add aid another and run actions 2026-09-10 16:56:38 +02:00
ctan 06555f7b49 test(llm): demonstrate unblocked engine capabilities via observation-only policy 2026-09-10 15:56:21 +02:00
ctan 26f86f416d feat(combat): allow point-targeted spell areas 2026-09-10 15:19:36 +02:00
ctan 7fafbe43cf feat(observation): expose structured spell areas 2026-09-10 14:14:54 +02:00
ctan 61c9b7fa47 feat(observation): expose remaining attacks of opportunity 2026-09-10 14:08:25 +02:00
ctan 6abd29cbc5 feat(observation): expose attack failure reasons 2026-09-10 13:57:34 +02:00
ctan 8f3bd0d0e0 feat(observation): expose per-pair cover bonus 2026-09-10 13:46:05 +02:00
ctan ed04052244 feat(combat): allow selecting the attacking weapon 2026-09-10 13:36:27 +02:00
ctan b91e1ac215 feat(combat): allow explicit movement destinations 2026-09-10 13:21:54 +02:00
ctan 468c22ff57 feat(combat): add stand up and drop prone 2026-09-10 13:07:58 +02:00
ctan ebdff4f7e5 feat(combat): add total defense and fighting defensively 2026-09-10 12:52:47 +02:00
ctan ab02597bc4 feat(combat): add ready action with triggers 2026-09-10 12:39:28 +02:00
ctan f83e4b8016 feat(combat): add delay action 2026-09-10 12:20:33 +02:00
ctan c5cfa78f87 feat(observation): expose initiative order and totals 2026-09-10 12:04:10 +02:00
ctan 4e115f9176 feat(combat): surface explicit action results and reject invalid actions 2026-09-10 11:51:02 +02:00
ctan e6125b04f6 feat(combat): support partial and improved cover levels 2026-09-10 11:32:08 +02:00
ctan 2eed752f7f feat(combat): add dying stabilization and Improved Critical 2026-09-10 10:43:02 +02:00
ctan 97f4429c2b feat(combat): add concealment miss chance, sneak attack, and Precise Shot 2026-09-10 10:22:50 +02:00
ctan a1c43e83af feat(combat): enforce spell resistance checks and energy resistances 2026-09-06 19:18:10 +02:00
ctan a9ccdd3a56 feat(combat): add activate_power_attack action and consume Up Close and Deadly deed
- New Action kind activate_power_attack: free action that sets
  state.power_attack = True when the combatant has the Power Attack feat;
  logged no-op otherwise. Routed via _execute_movement (free-action branch)
  to keep _execute under the C901 complexity ceiling.
- Consume deed_up_close_and_deadly in resolve_attack: the first attack
  resolved while the flag is set gains +1d6 if it is a ranged attack within
  30 ft; the flag is reset in all cases (benefit lost if out of range or
  not ranged). Extracted into _consume_up_close_and_deadly helper.
- Document activate_power_attack, corrected deed semantics, and the
  power_attack snapshot key in README.
- Add tests/test_engine_fixes.py (5 tests): PA activation, no-feat no-op,
  deed+ranged within 30ft, deed out-of-range, deed melee.
2026-09-06 18:37:58 +02:00
ctan e29c472a67 feat(combat): expose DR, conditions, creature type, features, and spell save semantics in observation 2026-09-06 18:18:13 +02:00
ctan d2cd6f0702 docs: document enriched observation snapshot and add LLM demo test 2026-09-06 16:50:42 +02:00
ctan cd796ecffb docs: document LLM observation contract and expanded action options 2026-09-06 11:14:18 +02:00
ctan febd408f29 docs: document B5 engine hardening - reach, sizes, elevation, immediate actions 2026-09-05 18:04:35 +02:00
ctan 7cb3653750 fix(combat): apply save negates to targeted spell damage effects 2026-09-05 12:52:58 +02:00
ctan cd75a4f2bf feat(combat): implement overrun, dirty trick, steal, reposition and drag maneuvers 2026-09-05 12:37:06 +02:00
ctan 2f2acd992f fix(combat): evaluate conditional stat modifiers with action context 2026-09-05 12:17:58 +02:00
ctan 31d970dd5f fix(combat): resolve touch attacks against touch AC and firearms 2026-09-05 11:28:46 +02:00
ctan 8e2753e67a chore: final green gate 2026-09-05 09:09:20 +02:00
ctan 22d76e9677 fix(combat): channel energy targets living vs undead 2026-09-05 00:16:17 +02:00
ctan f4fc66a6ab docs: align README with fixed behavior 2026-09-04 23:02:26 +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