fix(rules): update initiative when a readied action fires
SRD Ready - Initiative Consequences of Readying: 'your initiative result becomes the count on which you took the readied action' and you 'act immediately ahead of the character whose action triggered your readied action'. _check_readied fired the payload off-turn but never touched the readier's initiative. It now calls _ready_shift_initiative, which rewrites the readier's _initiative_keys entry (trigger total + 0.5, keeping its mod and prior index) using the same tuple shape _execute_delay writes, so _build_round_order holds the new position for all following rounds. Deterministic: no RNG consumed, current round order untouched. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -4242,6 +4242,7 @@ class CombatEngine:
|
||||
f"round {self._current_round} {state.combatant.id}: "
|
||||
f"ready fires ({trigger})"
|
||||
)
|
||||
self._ready_shift_initiative(state, event.actor)
|
||||
target = next(
|
||||
(s for s in self._states if s.combatant.id == payload.target_id),
|
||||
None,
|
||||
@@ -4252,6 +4253,35 @@ class CombatEngine:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _ready_shift_initiative(
|
||||
self, state: CombatantState, trigger_actor: CombatantState
|
||||
) -> None:
|
||||
"""Move the readier's initiative to the count it acted on (PF1e).
|
||||
|
||||
PF1e (SRD "Ready — Initiative Consequences of Readying"): "Your
|
||||
initiative result becomes the count on which you took the readied
|
||||
action" and you "act immediately ahead of the character whose action
|
||||
triggered your readied action" — for the rest of the encounter. The
|
||||
slot is written into ``_initiative_keys`` with the same tuple shape
|
||||
``_execute_delay`` uses (a 0.5 step off the anchor total, keeping the
|
||||
readier's initiative modifier and prior list index) so
|
||||
``_build_round_order`` holds the new position for every following
|
||||
round. The step is ADDED (not subtracted as for delay): a readied
|
||||
action interrupts and acts immediately AHEAD of the trigger, whereas a
|
||||
delay postpones to act after — the two intents are opposite.
|
||||
Deterministic: no RNG is consumed and the current round's order
|
||||
(already built) is untouched — only subsequent rounds reorder.
|
||||
"""
|
||||
key = self._initiative_keys.get(state.combatant.id)
|
||||
prior_index = key[2] if key is not None else self._states.index(state)
|
||||
trigger_key = self._initiative_keys.get(trigger_actor.combatant.id)
|
||||
trigger_total = trigger_key[0] if trigger_key is not None else 0.0
|
||||
self._initiative_keys[state.combatant.id] = (
|
||||
trigger_total + _DELAY_INITIATIVE_STEP,
|
||||
state.combatant.initiative_mod,
|
||||
prior_index,
|
||||
)
|
||||
|
||||
def _ready_trigger_matches(
|
||||
self, state: CombatantState, event: ReactionEvent
|
||||
) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user