ctan
66b6d1f387
feat(combat): support off-turn immediate actions via reaction policy
2026-09-05 17:03:51 +02:00
ctan
ab99ab67e3
feat(grid): apply elevation to movement cost and high ground
2026-09-05 16:18:56 +02:00
ctan
30f8905a3e
feat(combat): support multi-cell occupancy for large and larger creatures
2026-09-05 16:01:28 +02:00
ctan
7f57df16a6
feat(combat): support variable melee reach for weapons and creature size
2026-09-05 15:10:21 +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
22d76e9677
fix(combat): channel energy targets living vs undead
2026-09-05 00:16:17 +02:00
ctan
83a5250ca6
fix(combat): deed range gating
2026-09-04 23:02:27 +02:00
ctan
c5f31c30d1
fix(combat): summon spawns only on passable cells
2026-09-04 23:02:27 +02:00
ctan
6e08df6eb6
feat(combat): class abilities from default_policy
2026-09-04 23:02:26 +02:00
ctan
66a664ad85
fix(data): lich fear aura, paralyzing touch, slot keys
2026-09-04 23:02:26 +02:00
ctan
5353018c80
fix(combat): single roll to escape grapple
2026-09-04 23:02:25 +02:00
ctan
f575c77037
fix(combat): sunder damages weapon not HP
2026-09-04 23:02:25 +02:00
ctan
6e4a9d8323
feat(combat): Combat Reflexes extra AoOs
2026-09-04 23:02:24 +02:00
ctan
679d405943
feat(combat): enforce prone/staggered/nauseated/paralyzed
2026-09-04 23:02:24 +02:00
ctan
0d61ad44ab
fix(combat): bound cackle hex extension
2026-09-04 23:02:24 +02:00
ctan
735642a607
fix(combat): summoned creatures act and expire
2026-09-04 23:02:23 +02:00
ctan
2e4d192522
refactor(combat): single source active_buffs/active_conditions
2026-09-04 23:02:23 +02:00
ctan
073da40fca
feat(combat): class-ability action kinds, engine RNG only
2026-09-04 23:02:22 +02:00
ctan
0058e71550
fix(combat): correct hex and AoE DCs, DR bypassed by spells
2026-09-04 23:02:22 +02:00
ctan
a7729eebf1
fix(combat): correct concentration DCs by situation
2026-09-04 23:02:22 +02:00
ctan
fd94522546
feat(data): per-level spell slots for 8 PCs
2026-09-04 23:02:21 +02:00
ctan
1893072b5d
chore(lint): restore green gate
2026-09-04 23:02:20 +02:00
ctan
510990188a
feat(combat): class action patterns
2026-09-04 23:02:20 +02:00
ctan
a6366edd33
feat(combat): channel energy and hexes
2026-09-04 23:02:19 +02:00
ctan
4d7f1b8233
feat(loaders): map 8-PC feats
2026-09-04 23:02:18 +02:00
ctan
934d443d7d
feat(combat): summoning
2026-09-04 23:02:18 +02:00
ctan
136ddcf7aa
feat(combat): combat maneuvers CMB/CMD
2026-09-04 23:02:18 +02:00
ctan
8ae344fd16
feat(combat): area-of-effect spells
2026-09-04 23:02:17 +02:00
ctan
09062b37ea
feat(combat): spellcasting default policy
2026-09-04 23:02:17 +02:00
ctan
ab2874d79b
feat(combat): skills system
2026-09-04 23:02:17 +02:00
ctan
d792b6e28f
feat(combat): AoO and concentration on casting
2026-09-04 23:02:16 +02:00
ctan
0c2e3383d7
feat(combat): enforce behavioral condition flags
2026-09-04 23:02:16 +02:00
ctan
d2c80c0d61
feat(combat): metamagic
2026-09-04 23:02:16 +02:00
ctan
eb8072ace7
feat(models): combat resources
2026-09-04 23:02:15 +02:00
ctan
789d2f5396
fix(combat): correct spell DC formula
2026-09-04 23:02:15 +02:00
ctan
43303cf28e
feat(combat): effect and condition durations
2026-09-04 23:01:57 +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
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
ctan
004d6f1c2b
feat(combat): add attacks of opportunity (movement + ranged-in-melee triggers)
2026-08-17 22:49:50 +02:00