feat(combat): support partial and improved cover levels

This commit is contained in:
2026-09-10 11:32:08 +02:00
parent 2eed752f7f
commit e6125b04f6
6 changed files with 401 additions and 23 deletions
+14 -9
View File
@@ -164,7 +164,8 @@ legend: # un caractère = un type de terrain
".": { type: floor, move_cost: 1 }
"T": { type: rubble, move_cost: 2 } # terrain difficile
"~": { type: water, move_cost: 2 }
"C": { type: pillar, move_cost: null, cover: true } # bloque le pas, couvert
"C": { type: pillar, move_cost: null, cover: true } # bloque le pas, couvert (+4)
"W": { type: ruin, move_cost: null, cover_bonus: 2 } # couvert partiel (+2) ; 4 = standard, 8 = amélioré
elevation: | # optionnel : chiffres = hauteur (appliqué : coût de pas + high ground)
....................
@@ -189,7 +190,10 @@ deployment: # obligatoire si zones : nom de camp -> lettre de zone
Valeur du `move_cost` : entier > 0 pour un terrain praticable, `null` pour un
terrain infranchissable (mur, pilier). `blocks_los` et `cover` sont appliqués
par la résolution des attaques (module `los.py`, règle des coins) : pas de
ligne d'effet ⇒ l'attaque est impossible ; couvert ⇒ bonus de +4 CA.
ligne d'effet ⇒ l'attaque est impossible ; couvert ⇒ bonus de CA. Le champ
optionnel `cover_bonus` (`2`, `4` ou `8`) encode le niveau de couvert PF1e
(partiel +2, standard +4, amélioré +8) ; `cover: true` sans `cover_bonus`
vaut couvert standard (+4), idem pour un terrain `blocks_los`.
### Monstre (JSON)
@@ -331,7 +335,8 @@ Règles modélisées :
- Ligne d'effet : une cible entièrement derrière un terrain `blocks_los` ne
peut pas être attaquée — la politique se déplace jusqu'à gagner une ligne de
visée.
- Couvert (règle des coins) : la cible gagne +4 CA sur la touche et la
- Couvert (règle des coins) : la cible gagne le bonus de couvert du terrain
(+2 partiel, +4 standard, +8 amélioré via `cover_bonus`) sur la touche et la
confirmation de critique ; couvert mou : une créature active entre
l'attaquant et la cible octroie aussi +4 CA aux attaques à distance (les
attaques de mêlée ignorent les créatures).
@@ -447,9 +452,9 @@ Règles modélisées :
cases) ; la pénalité tombe à −2 si la cible ou l'adversaire menaçant est à
≥ 10 ft (2 cases) de l'attaquant. Le don « Precise Shot » annule la pénalité.
Les attaques de mêlée ne sont pas concernées.
- Couvert : seul le couvert standard (+4, terrain et couvert mou des créatures)
est modélisé ; le couvert partiel (+2) et le couvert amélioré (+8) ne sont PAS
modélisés.
- Couvert : les trois niveaux PF1e sont modélisés via `cover_bonus` sur le
terrain — partiel +2, standard +4 (ou `cover: true`), amélioré +8 ; le
couvert mou des créatures reste +4 (couvert standard).
- Invocation : les créatures invoquées agissent (calées sur la case d'initiative de
leur conjurateur via `_build_round_order`) puis expirent après leur `summon_duration`
(`_expire_summons` décrémente puis retire).
@@ -549,7 +554,7 @@ Règles modélisées :
- Top-level : round, acting_combatant, combatants, pairs, terrain, elevation,
threatened (grille bool des cases menacées par les ennemis),
terrain_semantics (un dict par type de terrain : type, move_cost,
blocks_los, cover), condition_definitions (C2 : tuple trié de (nom,
blocks_los, cover, cover_bonus), condition_definitions (C2 : tuple trié de (nom,
{mods, flags, speed_mult, miss_chance}) — définitions complètes des 23
conditions de CONDITIONS_BY_NAME pour que la LLM interprète les drapeaux,
les modificateurs et les chances de rater (concealment)).
@@ -588,8 +593,8 @@ la lecture mais non appliquée dans la résolution.
règle des coins (`diagonal_allowed`), Dijkstra `reachable` avec ou sans
budget.
- `los.py` — ligne d'effet et couvert par la règle des coins : gate de ligne
d'effet dans `weapon_for`, bonus de couvert +4 CA (terrain et couvert mou
des créatures) dans `resolve_attack`.
d'effet dans `weapon_for`, bonus de couvert par niveau (+2/+4/+8 terrain via
`cover_bonus`, +4 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, CA de contact
pour les attaques touch et firearms), tailles et allonges (occupation