From 799ba74e8455e4ca831a3c73afbb35ce88872237 Mon Sep 17 00:00:00 2001 From: bridge Date: Sun, 2 Nov 2025 22:14:28 +0800 Subject: [PATCH] refactor talk & conversation --- src/classes/mutual_action/attack.py | 4 ++++ src/classes/mutual_action/conversation.py | 11 ++--------- src/classes/mutual_action/drive_away.py | 4 ++++ src/classes/mutual_action/dual_cultivation.py | 12 ++---------- src/classes/mutual_action/mutual_action.py | 14 +++++++++++++- src/classes/mutual_action/talk.py | 5 +++++ 6 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/classes/mutual_action/attack.py b/src/classes/mutual_action/attack.py index 94dde8e..10af7ba 100644 --- a/src/classes/mutual_action/attack.py +++ b/src/classes/mutual_action/attack.py @@ -21,6 +21,10 @@ class Attack(MutualAction): # 攻击冷却:避免同月连刷攻击 ACTION_CD_MONTHS: int = 3 + def _can_start(self, target: "Avatar") -> tuple[bool, str]: + """攻击无额外检查条件""" + return True, "" + def _settle_feedback(self, target_avatar: "Avatar", feedback_name: str) -> None: fb = str(feedback_name).strip() if fb == "Escape": diff --git a/src/classes/mutual_action/conversation.py b/src/classes/mutual_action/conversation.py index cb52127..cdf507e 100644 --- a/src/classes/mutual_action/conversation.py +++ b/src/classes/mutual_action/conversation.py @@ -67,15 +67,8 @@ class Conversation(MutualAction): "recent_events": pair_recent_events, } - # 覆盖 can_start:Conversation 不需要检查观察范围,只需要在有效区域即可 - def can_start(self, target_avatar: "Avatar|str|None" = None, **kwargs) -> tuple[bool, str]: - if target_avatar is None: - return False, "缺少参数 target_avatar" - target = self._get_target_avatar(target_avatar) - if target is None: - return False, "目标不存在" - if target.tile is None or self.avatar.tile is None: - return False, "目标未处于有效区域" + def _can_start(self, target: "Avatar") -> tuple[bool, str]: + """交谈无额外检查条件""" return True, "" # 覆盖 start:自定义事件消息 diff --git a/src/classes/mutual_action/drive_away.py b/src/classes/mutual_action/drive_away.py index e98a92b..cb3dae0 100644 --- a/src/classes/mutual_action/drive_away.py +++ b/src/classes/mutual_action/drive_away.py @@ -21,6 +21,10 @@ class DriveAway(MutualAction): # 驱赶冷却:避免反复驱赶刷屏 ACTION_CD_MONTHS: int = 3 + def _can_start(self, target: "Avatar") -> tuple[bool, str]: + """驱赶无额外检查条件""" + return True, "" + def _settle_feedback(self, target_avatar: "Avatar", feedback_name: str) -> None: fb = str(feedback_name).strip() if fb == "MoveAwayFromRegion": diff --git a/src/classes/mutual_action/dual_cultivation.py b/src/classes/mutual_action/dual_cultivation.py index 6d97222..5bc7317 100644 --- a/src/classes/mutual_action/dual_cultivation.py +++ b/src/classes/mutual_action/dual_cultivation.py @@ -39,20 +39,12 @@ class DualCultivation(MutualAction): # 复用 mutual_action 模板,仅需返回 Accept/Reject return CONFIG.paths.templates / "mutual_action.txt" - def can_start(self, target_avatar: "Avatar|str|None" = None) -> tuple[bool, str]: - if target_avatar is None: - return False, "缺少参数 target_avatar" - # 基于 effects 判断是否允许 + def _can_start(self, target: "Avatar") -> tuple[bool, str]: + """检查双修特有的启动条件""" effects = self.avatar.effects legal_actions = effects.get("legal_actions", []) if not isinstance(legal_actions, list) or "DualCultivation" not in legal_actions: return False, "不具有双修的权限" - target = self._get_target_avatar(target_avatar) - if target is None: - return False, "双修目标不存在" - # 先不限定同一区域,之后再限制 - # if target.tile.region != self.avatar.tile.region: - # return False, "目标不在同一区域" return True, "" def start(self, target_avatar: "Avatar|str") -> Event: diff --git a/src/classes/mutual_action/mutual_action.py b/src/classes/mutual_action/mutual_action.py index cfa4202..6a6cade 100644 --- a/src/classes/mutual_action/mutual_action.py +++ b/src/classes/mutual_action/mutual_action.py @@ -162,6 +162,7 @@ class MutualAction(DefineAction, LLMAction, TargetingMixin): def can_start(self, target_avatar: "Avatar|str|None" = None) -> tuple[bool, str]: """ 检查互动动作能否启动:目标需在发起者的交互范围内。 + 子类通过实现 _can_start 来添加额外检查。 """ if target_avatar is None: return False, "缺少参数 target_avatar" @@ -170,7 +171,18 @@ class MutualAction(DefineAction, LLMAction, TargetingMixin): return False, "目标不存在" from src.classes.observe import is_within_observation ok = is_within_observation(self.avatar, target) - return (ok, "" if ok else "目标不在交互范围内") + if not ok: + return False, "目标不在交互范围内" + # 调用子类的额外检查 + return self._can_start(target) + + def _can_start(self, target: "Avatar") -> tuple[bool, str]: + """ + 子类实现此方法来添加特定的启动条件检查。 + 参数 target 已经过基类验证(存在且在交互范围内)。 + 默认返回 True。 + """ + return True, "" def start(self, target_avatar: "Avatar|str") -> Event: """ diff --git a/src/classes/mutual_action/talk.py b/src/classes/mutual_action/talk.py index af0b024..b52df5c 100644 --- a/src/classes/mutual_action/talk.py +++ b/src/classes/mutual_action/talk.py @@ -28,9 +28,14 @@ class Talk(MutualAction): # - _get_template_path() -> mutual_action.txt # - _build_prompt_infos() -> 标准的双方信息和历史事件 # - can_start() -> 检查目标在交互范围内 + # - _can_start() -> 无额外检查 # - start() -> 生成开始事件 # - finish() -> 返回空列表(已在父类实现) + def _can_start(self, target: "Avatar") -> tuple[bool, str]: + """攀谈无额外检查条件""" + return True, "" + def _handle_feedback_result(self, target: "Avatar", result: dict) -> ActionResult: """ 处理 LLM 返回的反馈结果。