fix(rules): expire a readied action at the combatant's next turn
SRD 'Ready - Initiative Consequences of Readying': 'If you come to your next action and have not yet performed your readied action, you don't get to take the readied action (though you can ready the same action again).' _take_turn's start-of-turn block now clears state.readied/readied_trigger (logged 'ready expired'), before the policy call; the ready still survives the round boundary and can fire in the next round as long as the readier's own turn has not arrived. Updated the two tests that pinned the old infinite persistence and added cross-round fire + expiry tests. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -478,13 +478,21 @@ Règles modélisées :
|
||||
recalculée, tout pas ennemi déclenche), `enemy_casts` ← incantation d'un
|
||||
ennemi, `enemy_attacks` ← attaque résolue d'un ennemi, `enemy_hits_ally` ←
|
||||
dégâts subis par un allié du préparant infligés par un ennemi. Quand
|
||||
l'événement correspond, le moteur exécute le payload **hors-tour, sans coût
|
||||
de swift** (au plus une action préparée par événement, sans cascade), puis
|
||||
l'action préparée est **consommée** (one-shot). Une nouvelle préparation
|
||||
remplace la précédente ; le reste du tour (action de mouvement) reste
|
||||
exécutable. Le snapshot expose l'état via la clé `readied`
|
||||
(`{kind, trigger}` ou `None`). `default_policy` ne se prépare pas
|
||||
(disponible via une politique personnalisée).
|
||||
l'événement correspond, le moteur exécute le payload **hors-tour, sans coût
|
||||
de swift** (au plus une action préparée par événement, sans cascade), puis
|
||||
l'action préparée est **consommée** (one-shot). Une nouvelle préparation
|
||||
remplace la précédente ; le reste du tour (action de mouvement) reste
|
||||
exécutable. Conformance L4 (SRD « Ready — Initiative Consequences of
|
||||
Readying ») : « If you come to your next action and have not yet performed
|
||||
your readied action, you don't get to take the readied action (though you
|
||||
can ready the same action again) » — la préparation non déclenchée
|
||||
**expire au début du tour suivant** du préparant (bloc de début de tour de
|
||||
`_take_turn`, journalisé `ready expired (trigger never occurred)`), avant
|
||||
l'appel de politique ; elle survit donc à la fin du round courant et peut
|
||||
se déclencher au round suivant tant que le tour du préparant n'est pas
|
||||
arrivé. Le snapshot expose l'état via la clé `readied`
|
||||
(`{kind, trigger}` ou `None`). `default_policy` ne se prépare pas
|
||||
(disponible via une politique personnalisée).
|
||||
- Défense totale (`Action(kind="total_defense")`, action standard) : le
|
||||
combattant se couvre entièrement et gagne **+4 d'esquive à la CA** jusqu'au
|
||||
début de son prochain tour (champ runtime `defensive_ac_bonus`, réinitialisé
|
||||
|
||||
Reference in New Issue
Block a user