fix(rules): bear's endurance +2 hp per Hit Die via split flat scaling, aid morale scoped to fear-descriptor saves (SRD spells/aid.md), charm person range close per SRD spells/charm-person.md, README synced (29 conditions, acid arrow total cap, mirror image instance-level miss chance)

This commit is contained in:
2026-09-19 13:34:30 +02:00
parent 35ce41e5f9
commit b95533d49f
5 changed files with 29 additions and 16 deletions
+12 -8
View File
@@ -1133,11 +1133,11 @@ Règles modélisées :
tire désormais ses cinq missiles.
- Dégâts récurrents de sort (S2c) : un `DamageEffect` peut déclarer
`"recurring": {"formula": "2d4", "types": ["acid"], "base_rounds": 1,
"per_levels": 3, "max": 6}` — le nombre de rounds de récurrence vaut
`base_rounds + niveau // per_levels`, plafonné à `max` (SRD Acid Arrow :
"per_levels": 3, "max": 7}` — le nombre de rounds de récurrence vaut
`base_rounds + niveau // per_levels`, plafonné à `max` **en total** (SRD Acid Arrow :
« For every three caster levels you possess, the acid [...] lasts for another
round [...] dealing another 2d4 points of damage in each round » → 1 round au
niveau 1, 2 au niveau 3, 6 au niveau 18+). À l'attaque initiale réussie, une
niveau 1, 2 au niveau 3, 7 au niveau 18+ : 1 + 6 rounds additionnels). À l'attaque initiale réussie, une
source de dégâts récurrents (`RecurringDamage` sur le `CombatantState`, liste
`recurring_damage`) est posée sur la cible vivante ; au **début du tour** de
la cible (dans `_turn_gate`, après le tick de saignement), chaque source
@@ -1184,7 +1184,11 @@ Règles modélisées :
portent un champ `miss_chance` ; quand la
cible en porte une, après la touche et la confirmation de critique, le moteur
tire un d100 : si `d100 ≤ miss_chance`, l'attaque rate complètement (aucun
dégât, pas de critique, deed non consommé — journalisé « concealment »). Une
dégât, pas de critique, deed non consommé — journalisé « concealment »). Le
champ est porté par l'**instance** de condition, pas seulement par la
définition : Mirror Image (SRD spells/mirror-image.md) jette ses images à
l'incantation (1d4 + 1 par 3 niveaux, max 8) et impose une instance `blurred`
dont le `miss_chance` vaut `images/(images+1)` en pourcentage. Une
cible avec **n'importe quelle dissimulation** (`miss_chance > 0` — flou 20 %
comme dissimulation totale 50 %) ne peut pas être la victime d'une attaque
sournoise (conformance A7 — SRD rogue « Sneak Attack » :
@@ -1259,7 +1263,7 @@ Règles modélisées :
convention de scalage par niveau que `ConditionEffect` (voir « Formes de zone et
scalage »). Les deux sorts importés (`summon_monster_i/ii.json`) portent
`duration_rounds_per_level: 1`.
- Conditions effectives : 28 conditions prédéfinies (`conditions.py`). Leurs drapeaux
- Conditions effectives : 29 conditions prédéfinies (`conditions.py`). Leurs drapeaux
comportementaux sont appliqués par le moteur : `cant_act` (étourdi, paralysé, dazed,
endormi, inerme, fasciné) annule le tour ; `cant_attack` (nauséeux, épinglé) n'autorise qu'une unique action
de mouvement — conformance L9 (SRD « Conditions — Nauseated ») : « The only
@@ -1617,7 +1621,7 @@ Règles modélisées :
case de leur conjurateur),
terrain_semantics (un dict par type de terrain : type, move_cost,
blocks_los, cover, cover_bonus), condition_definitions (C2 : tuple trié de (nom,
{mods, flags, speed_mult, miss_chance}) — définitions complètes des 28
{mods, flags, speed_mult, miss_chance}) — définitions complètes des 29
conditions de CONDITIONS_BY_NAME pour que la LLM interprète les drapeaux,
les modificateurs et les chances de rater (concealment)).
Les helpers publics du moteur (L5) sont désormais embarqués EN DONNÉES dans
@@ -1770,11 +1774,11 @@ Limites de sorts (conformance D6-D9, documentées plutôt que bricolées) :
enhancement…) gardent la valeur la plus élevée. Les pénalités suivent les
mêmes règles. Fondation pour sorts, conditions, dons et capacités de classe.
- `conditions.py` — conditions PF1e : `Condition` (dataclass avec
modificateurs + flags comportementaux + `miss_chance`) et 28 conditions prédéfinies
modificateurs + flags comportementaux + `miss_chance`) et 29 conditions prédéfinies
(shaken, sickened, fatigued, exhausted, entangled, dazzled, blinded,
deafened, flat-footed, prone, stunned, paralyzed, nauseated, dazed,
staggered, frightened, panicked, cowering, helpless, fascinated, invisible,
bleeding, confused).
bleeding, confused, bane).
Les modificateurs sont intégrés
à `resolve_attack` (attaque, dégâts, CA) et `resolve_save` (jets de
sauvegarde) via `_stat_modifiers` qui collecte effets + conditions ; les
+4 -2
View File
@@ -11,10 +11,12 @@
"type": "buff",
"modifiers": [
{ "target": "attack", "value": 1, "bonus_type": "morale" },
{ "target": "will", "value": 1, "bonus_type": "morale" }
{ "target": "fort", "value": 1, "bonus_type": "morale", "condition": "fear" },
{ "target": "ref", "value": 1, "bonus_type": "morale", "condition": "fear" },
{ "target": "will", "value": 1, "bonus_type": "morale", "condition": "fear" }
],
"duration_rounds": 10
}
],
"description": "The subject gains a +1 morale bonus on attack rolls and on saving throws against fear effects (modeled as Will). Duration 10 min/level approximated as 10 rounds."
"description": "SRD spells/aid.md: the subject gains a +1 morale bonus on attack rolls and on saves against fear effects, plus temporary hit points equal to 1d8 + caster level (maximum 1d8+10). The save bonus is scoped to fear effects via the descriptor-conditioned modifiers (all three saves, replacing the previous unconditional Will-only approximation). The temporary hit points are deferred: CombatantState has no temp-HP track (same gap as the virtue cantrip). Duration 1 min/level approximated as 10 rounds."
}
+10 -3
View File
@@ -10,11 +10,18 @@
{
"type": "buff",
"modifiers": [
{ "target": "fort", "value": 2, "bonus_type": "enhancement" },
{ "target": "hp", "value": 2, "bonus_type": "enhancement" }
{ "target": "fort", "value": 2, "bonus_type": "enhancement" }
],
"duration_rounds": 60
},
{
"type": "buff",
"modifiers": [
{ "target": "hp", "value": 0, "bonus_type": "enhancement" }
],
"duration_rounds": 60,
"scaling_flat": { "amount": 2, "per_levels": 1, "max": 40 }
}
],
"description": "The subject gains a +4 enhancement bonus to Constitution, granting +2 to Fortitude saves and +2 hit points per Hit Die (SRD bear's endurance; the hp modifier is informational — the engine has no per-HD hp pool). Will negates (harmless). Duration 10 min/level approximated as 60 rounds."
"description": "SRD spells/bear-s-endurance.md: the subject gains a +4 enhancement bonus to Constitution - +2 to Fortitude saves and +2 hit points per Hit Die - for 10 min./level. The engine has no ability-score track, so the +4 Con is encoded as its combat consequences: an unscaled +2 Fortitude enhancement, and a separate hp modifier carrying the per-HD bonus via flat scaling (+2 per level, capped at +40 for level 20; caster level stands in for the target's Hit Dice, and the hp target is informational - the engine has no per-HD hp pool). Will negates (harmless). Duration 10 min/level approximated as 60 rounds."
}
+2 -2
View File
@@ -2,7 +2,7 @@
"name": "Charm Person",
"level": 1,
"school": "enchantment",
"range": "medium",
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
@@ -14,5 +14,5 @@
"save_negates": true
}
],
"description": "The charmed person regards the caster as a trusted friend (modeled as the fascinated condition; the charmed condition is not in the engine). Duration 1 hour/level approximated as 100 rounds. Will negates."
"description": "SRD spells/charm-person.md: range close (25 ft. + 5 ft./2 levels) - corrected from the previous medium approximation. The charmed person regards the caster as a trusted friend; the engine has no charmed condition, so it is modeled as fascinated (the subject takes no actions). Duration 1 hour/level approximated as 100 rounds. Will negates."
}
+1 -1
View File
@@ -45,7 +45,7 @@ _BATCH1: dict[str, tuple[str, int, str, str, str]] = {
"Bleed": ("bleed", 0, "necromancy", "close", "will"),
"Bless": ("bless", 1, "enchantment", "medium", "none"),
"Blindness/Deafness": ("blindness_deafness", 2, "necromancy", "medium", "fort"),
"Charm Person": ("charm_person", 1, "enchantment", "medium", "will"),
"Charm Person": ("charm_person", 1, "enchantment", "close", "will"),
"Color Spray": ("color_spray", 1, "illusion", "close", "will"),
"Comprehend Languages": ("comprehend_languages", 1, "divination", "personal", "none"),
"Create Alcool": ("create_alcool", 0, "conjuration", "close", "none"),