fix action being executed 3 times bug
This commit is contained in:
@@ -141,9 +141,11 @@ class ActionMixin:
|
||||
for e in result.events:
|
||||
self.add_event(e)
|
||||
events, self._pending_events = self._pending_events, []
|
||||
# 本轮已执行过,清除"新设动作"标记(但如果刚刚提交了新动作,commit_next_plan会重新设置为True)
|
||||
if self.current_action is None:
|
||||
# 当前无动作时才清除标记,避免清除新提交动作的标记
|
||||
# 本轮已执行过,清除"新设动作"标记
|
||||
# 1. 动作结束 (None)
|
||||
# 2. 动作继续执行且未发生切换 (is action_instance_before)
|
||||
# 注意:如果动作发生了切换(如 Escape -> Attack),则视为新动作,不清除标记以便 Simulator 进行下一轮调度
|
||||
if self.current_action is None or self.current_action is action_instance_before:
|
||||
self._new_action_set_this_step = False
|
||||
|
||||
return events
|
||||
|
||||
@@ -128,26 +128,39 @@ class Simulator:
|
||||
执行阶段:推进当前动作,支持同月链式抢占即时结算,返回期间产生的事件。
|
||||
|
||||
TODO: 为单个角色的 tick_action() 添加 try-except 处理。
|
||||
当前如果任一角色的动作执行抛出异常,整个 step() 会失败,
|
||||
导致 month_stamp 不会推进,游戏卡在同一个月份无限循环。
|
||||
"""
|
||||
events = []
|
||||
MAX_LOCAL_ROUNDS = 3
|
||||
for _ in range(MAX_LOCAL_ROUNDS):
|
||||
new_action_happened = False
|
||||
for avatar in self.world.avatar_manager.get_living_avatars():
|
||||
# 本轮执行前若标记为新设,则清理,执行后由 Avatar 再统一清除
|
||||
if getattr(avatar, "_new_action_set_this_step", False):
|
||||
new_action_happened = True
|
||||
|
||||
# Round 1: 全员执行一次
|
||||
avatars_needing_retry = set()
|
||||
for avatar in self.world.avatar_manager.get_living_avatars():
|
||||
new_events = await avatar.tick_action()
|
||||
if new_events:
|
||||
events.extend(new_events)
|
||||
|
||||
# 检查是否有新动作产生(抢占/连招),如果有则加入下一轮
|
||||
# 注意:tick_action 内部已处理标记清除逻辑,仅当动作发生切换时才会保留 True
|
||||
if getattr(avatar, "_new_action_set_this_step", False):
|
||||
avatars_needing_retry.add(avatar)
|
||||
|
||||
# Round 2+: 仅执行有新动作的角色,避免无辜角色重复执行
|
||||
round_count = 1
|
||||
while avatars_needing_retry and round_count < MAX_LOCAL_ROUNDS:
|
||||
current_avatars = list(avatars_needing_retry)
|
||||
avatars_needing_retry.clear()
|
||||
|
||||
for avatar in current_avatars:
|
||||
new_events = await avatar.tick_action()
|
||||
if new_events:
|
||||
events.extend(new_events)
|
||||
# 若在本次执行后产生了新的动作(被别人抢占设立),则标志位会在 commit_next_plan 时被置 True
|
||||
|
||||
# 再次检查
|
||||
if getattr(avatar, "_new_action_set_this_step", False):
|
||||
new_action_happened = True
|
||||
# 若本轮未检测到新动作产生,则结束本地循环
|
||||
if not new_action_happened:
|
||||
break
|
||||
avatars_needing_retry.add(avatar)
|
||||
|
||||
round_count += 1
|
||||
|
||||
return events
|
||||
|
||||
def _phase_resolve_death(self):
|
||||
|
||||
@@ -68,7 +68,7 @@ def execute_gather(
|
||||
|
||||
base_quantity = 1
|
||||
extra_items = int(avatar.effects.get(extra_effect_key, 0) or 0)
|
||||
total_quantity = max(1, base_quantity + extra_items)
|
||||
total_quantity = base_quantity + extra_items
|
||||
|
||||
avatar.add_item(item, total_quantity)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user