feat(combat): add activate_power_attack action and consume Up Close and Deadly deed
- New Action kind activate_power_attack: free action that sets state.power_attack = True when the combatant has the Power Attack feat; logged no-op otherwise. Routed via _execute_movement (free-action branch) to keep _execute under the C901 complexity ceiling. - Consume deed_up_close_and_deadly in resolve_attack: the first attack resolved while the flag is set gains +1d6 if it is a ranged attack within 30 ft; the flag is reset in all cases (benefit lost if out of range or not ranged). Extracted into _consume_up_close_and_deadly helper. - Document activate_power_attack, corrected deed semantics, and the power_attack snapshot key in README. - Add tests/test_engine_fixes.py (5 tests): PA activation, no-feat no-op, deed+ranged within 30ft, deed out-of-range, deed melee.
This commit is contained in:
@@ -446,7 +446,10 @@ Règles modélisées :
|
||||
moins 2 morts-vivants ennemis sont groupés à 30 ft → les blesse en 2d6 ; le camp de la
|
||||
cible n'est pas pris en compte — seul `creature_type` compte, `selective_channeling` non
|
||||
modélisé), sortilège `evil_eye` (nairda), deed `up_close_and_deadly`
|
||||
(tammara, action bonus +1d6 à ≤ 30 ft), `inspire_courage` + `spell_combat` (misty)
|
||||
(tammara, action bonus +1d6 à ≤ 30 ft — consommé sur la première attaque
|
||||
résolue : si elle est à distance ET à ≤ 30 ft, +1d6 s'ajoute aux dégâts ;
|
||||
sinon le bonus est perdu ; le drapeau est réinitialisé dans tous les cas),
|
||||
`inspire_courage` + `spell_combat` (misty)
|
||||
— couvertes par `tests/test_class_abilities.py`.
|
||||
- Le Liche (`data/monsters/lich.json`) : `creature_type: "undead"` (sensible à l'énergie
|
||||
positive canalisée), aura de terreur (30 ft, Volonté DD 22 ou
|
||||
@@ -501,6 +504,10 @@ Règles modélisées :
|
||||
`terrain_semantics` + positions). Les API de décision exposées (items L1-L8)
|
||||
s'y retrouvent : `direction`/`trick_condition`/`weapon_id` sur `Action`,
|
||||
`can_charge` → `ChargeResult`, kinds `retrieve_weapon`/`repair_weapon`.
|
||||
Le kind `activate_power_attack` (action libre) active le don Power Attack
|
||||
(`state.power_attack = True`) si le combattant possède le don ; sans le don,
|
||||
c'est un no-op journalisé. Le snapshot expose l'état courant via la clé
|
||||
`power_attack` (bool) par combattant.
|
||||
|
||||
Non modélisé : la couche `markers` (points nommés de la carte) est validée à
|
||||
la lecture mais non appliquée dans la résolution.
|
||||
@@ -551,8 +558,9 @@ la lecture mais non appliquée dans la résolution.
|
||||
- `abilities.py` — dons et capacités : `AbilitySpec` (dataclass avec
|
||||
catégorie feat/class/racial/trait) et fabriques de dons (Weapon Focus ciblé
|
||||
par arme, Toughness lié au niveau, Power Attack actif −X attaque / +2X
|
||||
dégâts, X = BAB//4 + 1, mêlée uniquement, declared as free action at turn
|
||||
start via `state.power_attack`). Les modificateurs sont collectés par
|
||||
dégâts, X = BAB//4 + 1, mêlée uniquement, activé comme action libre via le
|
||||
kind `activate_power_attack` qui pose `state.power_attack`). Les
|
||||
modificateurs sont collectés par
|
||||
`_stat_modifiers` avec filtrage par arme (`weapon_filter`). Le champ
|
||||
`features` de `Combatant` contient les aptitudes permanentes ; le chargeur
|
||||
(`loaders/combatant.py`) résout les noms de dons des fiches vers des
|
||||
|
||||
Reference in New Issue
Block a user