fix(combat): resolve touch attacks against touch AC and firearms

This commit is contained in:
2026-09-05 11:28:46 +02:00
parent 8e2753e67a
commit 31d970dd5f
6 changed files with 358 additions and 27 deletions
+23 -11
View File
@@ -232,10 +232,11 @@ ligne d'effet ⇒ l'attaque est impossible ; couvert ⇒ bonus de +4 CA.
}
```
Champ `range_increment_ft` (optionnel, uniquement pour `kind: ranged`) :
incrément de portée en pieds. La pénalité de portée vaut −2 par incrément
complet au-delà du premier ; l'arme reste utilisable jusqu'à 10 incréments,
au-delà elle n'est pas sélectionnable. `damage_bonus` et `dr` sont optionnels.
Champ `range_increment_ft` (optionnel, uniquement pour `kind: ranged` ou
`kind: touch`) : incrément de portée en pieds. La pénalité de portée vaut −2
par incrément complet au-delà du premier ; une arme `ranged` reste utilisable
jusqu'à 10 incréments, une arme `touch` jusqu'à 5 (jet/firearm), au-delà elle
n'est pas sélectionnable. `damage_bonus` et `dr` sont optionnels.
Deux monstres d'exemple sont fournis : gobelin et orc.
### Fiches de personnages (PJ)
@@ -328,8 +329,18 @@ Règles modélisées :
portée.
- Distance : pénalité cumulative de −2 par incrément de portée complet au-delà
du premier, appliquée au jet d'attaque et à la confirmation de critique ;
l'arme ranged reste utilisable jusqu'à 10 incréments. Les armes de jet
(5 incréments max) ne sont pas distinguées des armes à projectiles.
les armes ranged restent utilisables jusqu'à 10 incréments, les armes touch
avec incrément (armes de jet, firearms) jusqu'à 5.
- Touch AC et armes à feu : les attaques `kind: touch` résolvent leur touche
contre la CA de contact de la cible (`ac.touch`) ; si la cible perd son bonus
de Dextérité à la CA (flat-footed, `denies_dex_to_ac`), la CA de contact est
amputée du modificateur de Dextérité. Les armes marquées `firearm: true`
(pistolets) résolvent contre la CA de contact uniquement dans leur premier
incrément de portée — au-delà, elles frappent la CA totale. Une attaque touch
avec incrément est une attaque à distance : elle provoque des attaques
d'opportunité depuis une case menacée, subit −4 si l'attaquant est à plat
ventre et bénéficie du couvert mou ; un contact de mêlée (sans incrément,
ex. le contact paralysant du liche) n'en fait rien.
- Jets de sauvegarde : `resolve_save(state, save_type, dc)` — fort/ref/will.
1 naturel = échec automatique, 20 naturel = succès automatique. Les
modificateurs d'effets (`StatModifier` avec `target` correspondant) sont
@@ -415,7 +426,8 @@ dans la résolution) :
- `rng.py` — `SeededRng` (flux reproductible par graine) et `ScriptedRng`
(séquence de dés scriptée pour les tests de transcripts).
- `models.py` — schémas Pydantic v2 : `Combatant`, `AbilityScores`,
`ACProfile`, `AttackSpec`, `DamageComponent`, `Saves`, `DamageReduction`.
`ACProfile`, `AttackSpec` (avec `firearm` pour les armes touch à feu),
`DamageComponent`, `Saves`, `DamageReduction`.
- `map.py` — `MapSpec`/`TerrainType`, chargement YAML et validation
(dimensions, caractères connus, zones, déploiement, markers).
- `grid.py` — grille 5-10-5 : `distance`, `step_cost`, règle des coins
@@ -424,10 +436,10 @@ dans la résolution) :
d'effet dans `weapon_for`, bonus de couvert +4 CA (terrain et couvert mou
des créatures) dans `resolve_attack`.
- `combat.py` — `CombatEngine` déterministe : initiative, actions, résolution
des attaques (couvert, ligne d'effet, pénalités de portée), états de vie,
incantation (emplacements, concentration par situation, AoO d'incantation),
invocation, manœuvres, capacités de classe, transcripts, politique par
défaut.
des attaques (couvert, ligne d'effet, pénalités de portée, CA de contact
pour les attaques touch et firearms), états de vie, incantation
(emplacements, concentration par situation, AoO d'incantation), invocation,
manœuvres, capacités de classe, transcripts, politique par défaut.
- `effects.py` — système d'effets : `StatModifier` (modificateur de
caractéristique avec type de bonus) et `resolve_modifiers` (application des
règles d'empilement PF1e). Types de bonus cumulables (dodge, racial, trait,