feat(combat): add dying stabilization and Improved Critical

This commit is contained in:
2026-09-10 10:43:02 +02:00
parent 97f4429c2b
commit 2eed752f7f
4 changed files with 395 additions and 3 deletions
+20 -2
View File
@@ -267,6 +267,22 @@ Règles modélisées :
- 1 naturel = échec automatique ; 20 naturel = touche + menace de critique.
- Critique : (dés + bonus) × multiplicateur ; la RD s'applique après
multiplication, les types perforants annulent la RD, les dégâts plancher à 0.
- Critique améliorée (« Improved Critical ») : le don double la plage de
menace — plage effective = `21 - 2 × (21 - crit_range)` (20 → 19-20,
19 → 17-20, 18 → 15-20). Il n'affecte que le jet de menace, jamais le jet de
confirmation. Simplification moteur : le don s'applique à toutes les armes
de l'attaquant (pas de sélection par type d'arme comme sur table).
- Mourir et stabilisation : une créature à `hp < 0` mais pas morte est
mourante — inconsciente (inactive), elle perd 1 pv par tour si elle échoue
son jet de Constitution DD 10 à son tour d'initiative : `d20 + mod de CON −
|hp|` contre 10 ; un 20 naturel réussit automatiquement. En cas d'échec, elle
perd 1 pv de plus ; en cas de réussite, elle est stabilisée (plus de perte de
pv, reste inconsciente). Une nouvelle blessure sous le seuil de stabilisation
(`hp < stabilized_hp`) fait reprendre l'agonie (nouveau jet) ; un soin
ramenant à `hp ≥ 0` réinitialise la stabilisation pour toute chute future.
La mort survient au seuil existant `hp < min(-10, -CON)` — divergence RAW
documentée : la règle du jeu meurt quand les pv négatifs atteignent le score
de CON (le moteur est donc d'un pv plus permissif) ; sémantique inchangée.
- Mort quand `hp < min(-10, -CON)` ; `hp ≤ 0` = inactif.
- Initiative : triée sur (total, modificateur, ordre de liste), sans re-jet.
- Économie d'action : un tour normal donne une action standard + une action de
@@ -502,7 +518,7 @@ Règles modélisées :
se branche via `CombatEngine(..., llm_policy=...)` (`LLMPolicy(observation,
state) -> tuple[Action, ...]`). Schéma enrichi (E1-E5) :
- Par combattant : id, side, pos, occupied_cells, hp/hp_max, active/dead,
conditions (noms + rounds_left), resources_left (+ `spell_slot_{level}`),
dying/stabilized, conditions (noms + rounds_left), resources_left (+ `spell_slot_{level}`),
weapon_broken/weapon_stolen, grappled_with, moved_this_turn, power_attack,
name, level, size, dr {amount, bypass} ou None (C1), creature_type (C3),
bab (E1), initiative_mod (E2), casting_ability ou None pour non-jeteur
@@ -524,7 +540,9 @@ Règles modélisées :
(tuple triée des types immunisés), sneak_dice (dés de précision disponibles :
(niveau + 1) // 2 avec « Sneak Attack », sinon 0), engaged_in_melee (bool —
une cible engagée dans une mêlée, signal pour le tir dans la mêlée et
l'attaque sournoise).
l'attaque sournoise), dying (bool — `hp < 0` et pas morte : agonisante,
inconsciente), stabilized (bool — stabilisée pendant son agonie, ne perd
plus de pv tant qu'aucune nouvelle blessure ne la remet en agonie).
- Par paire combattant actif × cible : target_index, distance_ft, weapon_for,
range_penalty, can_charge, can_step5_to_attack, has_line_of_effect,
flanking, movement_cost_ft, target_threatens_me, enemies_threatening_me.