fix(rules): stop delay from double-processing the turn start
A freshly-delayed combatant is re-inserted into the round order and _take_turn runs a second time in the same round. That second pass re-ran _decrement_durations and _turn_gate, double-ticking bleed, double-decrementing buff/condition durations and re-firing the fear aura. The start-of-turn block is now skipped when delayed_this_round is already set at entry (cleared at round start, set only by a delay action); the delayed turn still gets its policy call, budget and execution. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -1398,21 +1398,29 @@ class CombatEngine:
|
||||
|
||||
def _take_turn(self, state: CombatantState) -> bool:
|
||||
"""Execute one combatant's full turn; return True if the battle is over."""
|
||||
self._decrement_durations(state)
|
||||
gate = self._turn_gate(state)
|
||||
if gate is not None:
|
||||
# A start-of-turn effect (bleed, confusion, cant_act) forfeited
|
||||
# the turn; the value is the battle-over flag.
|
||||
state.last_action_results = []
|
||||
return gate
|
||||
self._apply_fear_aura(state)
|
||||
state.moved_this_turn = False
|
||||
state.power_attack = False
|
||||
state.defensive_ac_bonus = 0
|
||||
state.fight_defensively = False
|
||||
state.aid_attack_bonus = 0
|
||||
state.aid_ac_bonus = 0
|
||||
state.running = False
|
||||
# A freshly-delayed combatant is re-inserted into the round order and
|
||||
# ``_take_turn`` runs a second time in the SAME round. The start-of-turn
|
||||
# block below (duration decrement, the bleed/confusion/cant_act gate,
|
||||
# the fear aura and the per-turn flag resets) must run only ONCE per
|
||||
# round, so it is skipped when ``delayed_this_round`` is already set at
|
||||
# entry (it was cleared at round start and only a delay action sets it).
|
||||
# The delayed turn still gets its policy call, budget and execution.
|
||||
if not state.delayed_this_round:
|
||||
self._decrement_durations(state)
|
||||
gate = self._turn_gate(state)
|
||||
if gate is not None:
|
||||
# A start-of-turn effect (bleed, confusion, cant_act) forfeited
|
||||
# the turn; the value is the battle-over flag.
|
||||
state.last_action_results = []
|
||||
return gate
|
||||
self._apply_fear_aura(state)
|
||||
state.moved_this_turn = False
|
||||
state.power_attack = False
|
||||
state.defensive_ac_bonus = 0
|
||||
state.fight_defensively = False
|
||||
state.aid_attack_bonus = 0
|
||||
state.aid_ac_bonus = 0
|
||||
state.running = False
|
||||
original = self._policy(self, state)
|
||||
results: list[ActionResult] = []
|
||||
actions = self._filter_turn_actions(state, original, results)
|
||||
|
||||
Reference in New Issue
Block a user