From 554d54f7b3d7865c2bb91f24ffd586b75f06f63b Mon Sep 17 00:00:00 2001 From: zhbaor Date: Sat, 15 Feb 2025 20:31:46 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9A=90=E7=A7=98=E6=88=98=E7=BA=BF=E9=80=82?= =?UTF-8?q?=E9=85=8D=E6=96=B0=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mower/data/scene.json | 22 +- mower/resources/sf/card_confirm.png | 3 + mower/resources/sf/continue_result.png | 3 - mower/resources/sf/event_confirm.png | 3 + .../sf/{confirm.png => exit_confirm.png} | 0 mower/resources/sf/return.png | 3 + mower/solvers/secret_front.py | 344 +++++++++--------- mower/utils/graph/__init__.py | 23 +- mower/utils/graph/secret_front.py | 24 ++ mower/utils/recognize/__init__.py | 28 ++ mower/utils/recognize/data.py | 28 ++ mower/utils/scene.py | 43 +-- mower/utils/typealias/res.py | 6 +- 13 files changed, 300 insertions(+), 230 deletions(-) create mode 100644 mower/resources/sf/card_confirm.png delete mode 100644 mower/resources/sf/continue_result.png create mode 100644 mower/resources/sf/event_confirm.png rename mower/resources/sf/{confirm.png => exit_confirm.png} (100%) create mode 100644 mower/resources/sf/return.png create mode 100644 mower/utils/graph/secret_front.py diff --git a/mower/data/scene.json b/mower/data/scene.json index c9c242c..99f4f87 100644 --- a/mower/data/scene.json +++ b/mower/data/scene.json @@ -640,46 +640,42 @@ "comment": "保全扫荡确认" }, "1101": { - "label": "SF_ENTRANCE", - "comment": "隐秘战线入口" - }, - "1102": { "label": "SF_EXIT", "comment": "暂离行动" }, - "1103": { + "1102": { "label": "SF_SELECT_TEAM", "comment": "选择小队" }, - "1104": { + "1103": { "label": "SF_CONTINUE", "comment": "继续前进" }, - "1105": { + "1104": { "label": "SF_SELECT", "comment": "选择路线" }, - "1106": { + "1105": { "label": "SF_ACTIONS", "comment": "行动选项" }, - "1107": { + "1106": { "label": "SF_RESULT", "comment": "行动结果" }, - "1108": { + "1107": { "label": "SF_EVENT", "comment": "应对危机事件" }, - "1109": { + "1108": { "label": "SF_TEAM_PASS", "comment": "小队通过危机事件" }, - "1110": { + "1109": { "label": "SF_CLICK_ANYWHERE", "comment": "点击任意处继续" }, - "1111": { + "1110": { "label": "SF_END", "comment": "抵达终点" }, diff --git a/mower/resources/sf/card_confirm.png b/mower/resources/sf/card_confirm.png new file mode 100644 index 0000000..da61d44 --- /dev/null +++ b/mower/resources/sf/card_confirm.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ebcb0ff452eac4baf1d6a7513fc1869e60ecdd56ca83f40629b2e439cac73aa1 +size 2726 diff --git a/mower/resources/sf/continue_result.png b/mower/resources/sf/continue_result.png deleted file mode 100644 index 78f6a95..0000000 --- a/mower/resources/sf/continue_result.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdd6e45c65d3ea24b0dd978239ed03ae2d88c67936a20aaaed105d6091e87746 -size 7854 diff --git a/mower/resources/sf/event_confirm.png b/mower/resources/sf/event_confirm.png new file mode 100644 index 0000000..9480eeb --- /dev/null +++ b/mower/resources/sf/event_confirm.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6717ea16eb6f5aa89eafbb4d776aed6f953214a80e0221fa3deafc4d068522e +size 6218 diff --git a/mower/resources/sf/confirm.png b/mower/resources/sf/exit_confirm.png similarity index 100% rename from mower/resources/sf/confirm.png rename to mower/resources/sf/exit_confirm.png diff --git a/mower/resources/sf/return.png b/mower/resources/sf/return.png new file mode 100644 index 0000000..18c72ca --- /dev/null +++ b/mower/resources/sf/return.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc99881eddfc1e2ce30e06d9581f12ea8d7ae1a32ea282c38e444d423467aa62 +size 2172 diff --git a/mower/solvers/secret_front.py b/mower/solvers/secret_front.py index a43f359..349bf35 100644 --- a/mower/solvers/secret_front.py +++ b/mower/solvers/secret_front.py @@ -1,26 +1,37 @@ -from datetime import datetime, timedelta +from difflib import SequenceMatcher import cv2 from mower.static import secret_front from mower.utils import config from mower.utils import typealias as tp -from mower.utils.csleep import MowerExit -from mower.utils.email import send_message +from mower.utils.email import notify +from mower.utils.graph import SceneGraphSolver from mower.utils.image import cropimg from mower.utils.log import logger +from mower.utils.rapidocr import ocr_rec from mower.utils.scene import Scene from mower.utils.solver import BaseSolver from mower.utils.vector import sa, va +CardInfo = tuple[int, int, int, float] -def exp(card): - data = card[:3] - p = card[3] - return [i * p for i in data] + +def exp(card: CardInfo) -> list[float]: + """计算卡片的期望 + + Args: + card (CardInfo): 卡片的值 + + Returns: + list[float]: 三项属性的期望 + """ + return [i * card[3] for i in card[:3]] class SecretFront(BaseSolver): + solver_name = "隐秘战线" + target = { "1A": [20, 20, 20], "2A": [60, 55, 45], @@ -49,50 +60,77 @@ class SecretFront(BaseSolver): "结局E": "medicine", } + def __init__(self): + self.properties: list[int] | None = None + "三项属性值" + self.event: bool = False + "应对危机事件" + self.route_names: list[str] = [] + "匹配路线" + self.series: int | None = None + "支援作战平台、游侠、诡影迷踪" + self.actions: dict[int, dict[int, float]] = {} + "记录页面中卡片的期望" + self.send_email: bool = False + "发送邮件提醒" + + super().__init__() + @property def route(self): + "路线" return self.routes[config.conf.secret_front.target] @property def team(self): + "小队" return self.teams[config.conf.secret_front.target] def run(self): - self.timeout = timedelta(seconds=config.conf.reclamation_algorithm.timeout) - if self.scheduler_stop_time: - self.deadline = self.scheduler_stop_time - timedelta(minutes=1) - else: - self.deadline = None - self.unknown_time = None - - self.properties = None - self.route_matcher = None + self.route_names = [] self.event = False - self.series = None # 支援作战平台、游侠、诡影迷踪 + self.series = None + + self.send_email = False self.reset_actions() - super().run() - return False + return super().run() def reset_actions(self): - self.actions = {} - for page in range(3): - self.actions[page] = {} + "清空缓存的卡片数据" + self.actions = {0: {}, 1: {}, 2: {}} - def number(self, scope: tp.Scope, height: int | None = None): + def number(self, scope: tp.Scope, height: int = 25): return config.recog.num.number_int("secret_front", scope, height) - def card_pos(self, total, idx): - if total == 3: - return [(301, 466), (830, 466), (1360, 466)][idx] - elif total == 2: - return [(565, 466), (1095, 466)][idx] - else: - return (830, 466) + def card_pos(self, total: int, idx: int) -> tp.Coordinate: + """总共有total张卡片时下标为idx(从0开始)卡片的左上角坐标 - def stage_card(self, total, idx): + Args: + total (int): 卡片总数 + idx (int): 下标(从0开始) + + Returns: + tp.Coordinate: 卡片左上角坐标 + """ + return { + 1: [(830, 466)], + 2: [(565, 466), (1095, 466)], + 3: [(301, 466), (830, 466), (1360, 466)], + }[total][idx] + + def event_card(self, total: int, idx: int) -> tuple[str, bool]: + """应对危机事件卡片识别 + + Args: + total (int): 卡片总数 + idx (int): 卡片下标(从0开始) + + Returns: + tuple[str, bool]: 危机事件选项名称及是否可选 + """ pos = self.card_pos(total, idx) scope = sa(((10, 380), (140, 430)), pos) @@ -111,7 +149,16 @@ class SecretFront(BaseSolver): logger.debug(f"{name=} {hue=}") return name, hue > 18 - def card(self, total, idx): + def card(self, total: int, idx: int) -> CardInfo: + """卡片识别 + + Args: + total (int): 总数 + idx (int): 下标(从0开始) + + Returns: + CardInfo: 卡片信息 + """ pos = self.card_pos(total, idx) materiel = sa(((84, 70), (180, 102)), pos) @@ -133,24 +180,32 @@ class SecretFront(BaseSolver): return materiel, intelligence, medicine, percentage - def page_number(self): - title = cropimg(config.recog.gray, ((1020, 230), (1210, 285))) - if self.route_matcher is None: + def page_number(self) -> int | None: + """识别当前页数 + + Returns: + int | None: 页数(从0开始) + """ + if not self.route_names: + self.tap((125, 840)) return None - score, scope = self.route_matcher.match2d(title) - if scope is None: - return None - pos_x = scope[0][0] - if pos_x < 800: - page_number = 0 - elif pos_x < 1330: - page_number = 1 - else: - page_number = 2 + img = cropimg(config.recog.gray, ((915, 230), (1320, 290))) + name = ocr_rec(img) + max_ratio = 0 + page_number = 0 + for i, n in enumerate(self.route_names): + if (ratio := SequenceMatcher(None, name, n).ratio()) > max_ratio: + page_number = i + max_ratio = ratio logger.debug(f"{page_number=}") return page_number - def card_total(self): + def card_total(self) -> int: + """识别当前有几张卡片 + + Returns: + int: 卡片数量 + """ p3 = self.card_pos(3, 0) p2 = self.card_pos(2, 0) up_scope = ((0, 0), (473, 120)) @@ -159,11 +214,11 @@ class SecretFront(BaseSolver): s3d = sa(down_scope, p3) s2u = sa(up_scope, p2) s2d = sa(down_scope, p2) - if (pos := self.find("sf/card", scope=s3u)) and pos[0][0] < 350: + if self.find("sf/card", scope=s3u): total = 3 elif self.find("sf/available", scope=s3d): total = 3 - elif (pos := self.find("sf/card", scope=s2u)) and pos[0][0] < 610: + elif self.find("sf/card", scope=s2u): total = 2 elif self.find("sf/available", scope=s2d): total = 2 @@ -172,14 +227,18 @@ class SecretFront(BaseSolver): logger.debug(f"{total=}") return total - def max_card(self): + def max_card(self) -> tuple[int, int]: + """计算最优选项 + + Returns: + tuple[int, int]: 返回最优页码及卡片下标 + """ max_page = -1 max_card = -1 max_score = -1 logger.debug(f"{self.properties=}") - # 根据目标计算 for page, page_action in self.actions.items(): for card, action in page_action.items(): for stage in self.route: @@ -201,42 +260,40 @@ class SecretFront(BaseSolver): logger.debug(f"{max_page=} {max_card=}") return max_page, max_card - def choose_card(self, total, idx): - self.route_matcher = None - self.properties = None - self.reset_actions() + def choose_card(self, total: int, idx: int): + """点击卡片 - if total == 3: - start = 545 - elif total == 2: - start = 805 - else: - start = 1075 - self.tap((start + idx * 530, 900), interval=0.5) - self.tap((start + idx * 530, 900), interval=2) + Args: + total (int): 卡片总数 + idx (int): 卡片下标(从0开始) + """ + start = {3: 545, 2: 805, 1: 1075}[total] + pos = (start + idx * 530, 900) + self.tap(pos) - def move_forward(self, scene): - # 从首页进入隐秘战线 - if scene == Scene.INDEX: - self.tap_index_element("terminal") - elif scene == Scene.TERMINAL_MAIN: - self.tap_terminal_button("main_theme") - elif scene == Scene.TERMINAL_MAIN_THEME: - self.tap("navigation/main/14") - elif scene == Scene.SF_ENTRANCE: - self.tap("sf/entrance") - - # 选择小队 + def transition(self): + if (scene := self.scene()) == Scene.TERMINAL_MAIN_THEME: + self.main_theme(2, 14) + elif scene == Scene.OPERATOR_CHOOSE_LEVEL: + if pos := self.find("sf/entrance"): + self.tap(pos) + return + if self.animation(): + return + SceneGraphSolver().step(Scene.TERMINAL_MAIN_THEME) elif scene == Scene.SF_SELECT_TEAM: - self.tap(f"sf/team_{self.team}") + if self.animation(): + return + if pos := self.find(f"sf/team_{self.team}"): + self.tap(pos) + return self.tap("sf/select_team_ok") - - # 继续前进 elif scene == Scene.SF_CONTINUE: self.tap("sf/continue") - - # 选择路线时识别已有属性值 elif scene == Scene.SF_SELECT: + if self.animation(((0, 0), (1920, 1030))): + return + self.send_email = True self.event = False if self.properties is None: @@ -247,8 +304,12 @@ class SecretFront(BaseSolver): ] logger.debug(f"{self.properties=}") - if self.route_matcher is None: - self.route_matcher = config.recog.matcher + if not self.route_names: + for i in range(3): + pos = self.card_pos(3, i) + scope = sa(((120, 145), (460, 205)), pos) + img = cropimg(config.recog.gray, scope) + self.route_names.append(ocr_rec(img)) self.series = None if ( @@ -267,39 +328,42 @@ class SecretFront(BaseSolver): self.series = 2 logger.debug(f"{self.series=}") - self.tap((545 + 530 * self.series, 640), interval=1.5) + self.tap((545 + 530 * self.series, 640)) return - self.tap((545, 640), interval=1.5) - - # 行动列表 + self.tap((545, 640)) elif scene == Scene.SF_ACTIONS: + if self.event and (pos := self.find("sf/event_confirm")): + self.tap(pos) + return + elif pos := self.find("sf/card_confirm"): + self.tap(pos) + return + + if self.animation(((0, 0), (1920, 1030))): + return + total = self.card_total() if self.event: - name_list = [self.stage_card(total, i) for i in range(total)] - for idx, data in enumerate(name_list): - name, available = data - if name in self.route: - if available: - self.choose_card(total, idx) - else: - self.exit = "restart" - self.tap("sf/exit_button") + name_list = [self.event_card(total, i) for i in range(total)] + for idx, (name, available) in enumerate(name_list): + if name not in self.route: + continue + if available: + self.choose_card(total, idx) return - self.exit = "restart" + break self.tap("sf/exit_button") return if (page_number := self.page_number()) is None: - self.sleep() return target = self.target[self.route[-1]] distance = [max(t - p, 0) for p, t in zip(self.properties, target)] if sum(distance) == 0: self.choose_card(total, 0) - self.sleep(3) return if self.series is not None: @@ -309,6 +373,7 @@ class SecretFront(BaseSolver): if all(card[3] < 0.8 for card in card_data): logger.debug("成功概率太低") self.series = None + self.solver_update_before_transition = False return elif not all(self.actions.values()): @@ -319,6 +384,7 @@ class SecretFront(BaseSolver): for idx in range(total): self.actions[page_number][idx] = exp(self.card(total, idx)) logger.debug(f"{self.actions=}") + self.solver_update_before_transition = False elif (page_number + 1) % 3 == target_number: self.tap((1785, 225)) # 下一页 else: @@ -329,87 +395,25 @@ class SecretFront(BaseSolver): if max_page == page_number: self.choose_card(len(self.actions[max_page]), max_card) - self.sleep(3) elif (page_number + 1) % 3 == max_page: self.tap((1785, 225)) # 下一页 else: self.tap((350, 225)) # 上一页 - - # 行动结果 elif scene == Scene.SF_RESULT: - if pos := self.find("sf/continue_result"): - self.tap(pos) - else: - self.sleep() - + self.route_names = [] + self.properties = None + self.reset_actions() + self.tap((1640, 945)) elif scene == Scene.SF_EVENT: self.event = True - self.tap("sf/continue_event", interval=1.5) - + self.tap("sf/continue_event") elif scene in [Scene.SF_TEAM_PASS, Scene.SF_CLICK_ANYWHERE, Scene.SF_END]: - self.tap((960, 980), interval=2) - - if scene == Scene.SF_END: - send_message( - f"隐秘战线成功完成{config.conf.secret_front.target}", level="INFO" - ) - - # 关闭说明 - elif scene == Scene.NOTICE: - self.tap("notice") + self.tap((960, 980)) + if scene == Scene.SF_END and self.send_email: + self.send_email = False + notify(f"隐秘战线通关{config.conf.secret_front.target}", level="INFO") elif scene == Scene.SF_EXIT: - if self.exit == "restart": - self.properties = None - self.route_matcher = None - self.event = False - - self.tap("sf/restart") - self.tap("sf/confirm") - elif self.exit == "exit": - self.tap("sf/confirm") - else: - self.tap((480, 590)) - + self.tap("sf/restart") else: - self.sleep() - - def back_to_index(self, scene): - if scene in [Scene.TERMINAL_MAIN, Scene.TERMINAL_MAIN_THEME, Scene.SF_ENTRANCE]: - self.back() - elif scene == Scene.SF_EXIT: - self.move_forward(scene) - else: - self.exit = "exit" - self.tap("sf/exit_button") - - def transition(self): - now = datetime.now() - - if (scene := self.sf_scene()) == Scene.UNKNOWN: - if not self.unknown_time: - self.unknown_time = now - elif now - self.unknown_time > self.timeout: - logger.warning("连续识别到未知场景") - try: - self.properties = None - self.route_matcher = None - self.event = False - self.reset_actions() - super().back_to_index() - except MowerExit: - raise - except Exception as e: - logger.exception(e) - config.device.exit() - self.check_current_focus() - else: - self.unknown_time = None - - if self.deadline and self.deadline < datetime.now(): - if scene == Scene.INDEX: - return True - else: - self.back_to_index(scene) - else: - self.move_forward(scene) + SceneGraphSolver().step(Scene.TERMINAL_MAIN_THEME) diff --git a/mower/utils/graph/__init__.py b/mower/utils/graph/__init__.py index c02aea6..64ff4da 100644 --- a/mower/utils/graph/__init__.py +++ b/mower/utils/graph/__init__.py @@ -1,3 +1,5 @@ +# ruff: noqa: F401 + from . import ( extra, friend, @@ -8,26 +10,9 @@ from . import ( recruit, riic, rogue, + secret_front, shop, sss, terminal, ) -from .utils import DG, SceneGraphSolver, edge - -__all__ = [ - "SceneGraphSolver", - "DG", - "edge", - "extra", - "friend", - "index", - "mission", - "navbar", - "operation", - "recruit", - "riic", - "shop", - "sss", - "terminal", - "rogue", -] +from .utils import SceneGraphSolver diff --git a/mower/utils/graph/secret_front.py b/mower/utils/graph/secret_front.py new file mode 100644 index 0000000..83f1b5d --- /dev/null +++ b/mower/utils/graph/secret_front.py @@ -0,0 +1,24 @@ +from mower.utils.scene import Scene +from mower.utils.solver import BaseSolver + +from .utils import edge + +# 隐秘战线 + + +@edge(Scene.SF_EXIT, Scene.OPERATOR_CHOOSE_LEVEL) +def exit_dialog(solver: BaseSolver): + solver.tap("sf/exit_confirm") + + +@edge(Scene.SF_SELECT_TEAM, Scene.SF_EXIT) +@edge(Scene.SF_CONTINUE, Scene.SF_EXIT) +@edge(Scene.SF_SELECT, Scene.SF_EXIT) +@edge(Scene.SF_ACTIONS, Scene.SF_EXIT) +@edge(Scene.SF_RESULT, Scene.SF_EXIT) +@edge(Scene.SF_EVENT, Scene.SF_EXIT) +@edge(Scene.SF_TEAM_PASS, Scene.SF_EXIT) +@edge(Scene.SF_CLICK_ANYWHERE, Scene.SF_EXIT) +@edge(Scene.SF_END, Scene.SF_EXIT) +def exit_button(solver: BaseSolver): + solver.tap("sf/exit_button") diff --git a/mower/utils/recognize/__init__.py b/mower/utils/recognize/__init__.py index d6e59b2..fd5ff87 100644 --- a/mower/utils/recognize/__init__.py +++ b/mower/utils/recognize/__init__.py @@ -430,6 +430,34 @@ class Recognizer: self.scene = Scene.SIGN_IN_ORUNDUM elif self.find("start_story"): self.scene = Scene.STORY_STAGE + elif self.find("sf/exit_button"): + if self.find("sf/continue"): + self.scene = Scene.SF_CONTINUE + elif self.find("sf/properties"): + if self.find("sf/select"): + self.scene = Scene.SF_SELECT + elif self.find("sf/return"): + self.scene = Scene.SF_ACTIONS + elif self.find("sf/success"): + self.scene = Scene.SF_RESULT + elif self.find("sf/failure"): + self.scene = Scene.SF_RESULT + else: + self.scene = Scene.UNKNOWN + elif self.find("sf/inheritance"): + self.scene = Scene.SF_SELECT_TEAM + elif self.find("sf/continue_event"): + self.scene = Scene.SF_EVENT + elif self.find("sf/click_anywhere"): + self.scene = Scene.SF_CLICK_ANYWHERE + elif self.find("sf/team_pass"): + self.scene = Scene.SF_TEAM_PASS + elif self.find("sf/end"): + self.scene = Scene.SF_END + else: + self.scene = Scene.UNKNOWN + elif self.find("sf/exit"): + self.scene = Scene.SF_EXIT # 模板匹配 elif self.detect_index_scene(): diff --git a/mower/utils/recognize/data.py b/mower/utils/recognize/data.py index e00d0ba..6a256a4 100644 --- a/mower/utils/recognize/data.py +++ b/mower/utils/recognize/data.py @@ -163,6 +163,20 @@ color = { "room_detail": (1291, 33), "sanity_charge": (1111, 382), "sanity_charge_dialog": (570, 529), + "sf/continue": (409, 818), + "sf/continue_event": (346, 815), + "sf/entrance": (32, 139), + "sf/exit": (856, 339), + "sf/exit_button": (30, 28), + "sf/exit_confirm": ((1393, 658), (1153, 658)), + "sf/inheritance": (1501, 26), + "sf/properties": (34, 470), + "sf/restart": (869, 657), + "sf/return": (57, 822), + "sf/select_team_ok": (1706, 917), + "sf/team_intelligence": (66, 530), + "sf/team_management": (55, 288), + "sf/team_medicine": (56, 766), "shop/assist.jpg": (816, 222), "shop/cart": (1252, 842), "shop/collect": (1467, 43), @@ -389,6 +403,19 @@ template_matching = { "rogue/refresh": ((1205, 200), (1256, 350)), "rogue/team_check_to_do": ((0, 800), (1920, 960)), "rogue/view_data_back": (147, 46), + "sf/available": None, + "sf/card": None, + "sf/card_confirm": ((720, 830), (1860, 890)), + "sf/click_anywhere": ((750, 940), (1030, 1000)), + "sf/end": ((1060, 825), (1340, 900)), + "sf/event_confirm": ((260, 845), (1920, 890)), + "sf/failure": ((365, 330), (610, 850)), + "sf/lost_in_the_trick": ((300, 600), (1830, 690)), + "sf/ranger": ((300, 600), (1830, 690)), + "sf/select": (274, 181), + "sf/success": ((365, 330), (610, 850)), + "sf/support_battle_platform": ((300, 600), (1830, 690)), + "sf/team_pass": ((960, 825), (1200, 900)), "sign_in/headhunting/available": (1177, 857), "sign_in/moon_festival/banner": (704, 92), "sign_in/shop/0": (1341, 618), @@ -458,6 +485,7 @@ template_matching_score = { "recruit/stone": 0.7, "recruit/time": 0.8, "rogue/node_be_choosed": 0.7, + "sf/card": 0.8, "sign_in/moon_festival/banner": 0.5, "sss/add_agent": 0.8, "sss/drop_EC": 0.8, diff --git a/mower/utils/scene.py b/mower/utils/scene.py index 52a6229..3b0507d 100644 --- a/mower/utils/scene.py +++ b/mower/utils/scene.py @@ -319,27 +319,25 @@ class Scene: "选择定向元件" SSS_ELIMI_AGENCY = 1019 "保全扫荡确认" - SF_ENTRANCE = 1101 - "隐秘战线入口" - SF_EXIT = 1102 + SF_EXIT = 1101 "暂离行动" - SF_SELECT_TEAM = 1103 + SF_SELECT_TEAM = 1102 "选择小队" - SF_CONTINUE = 1104 + SF_CONTINUE = 1103 "继续前进" - SF_SELECT = 1105 + SF_SELECT = 1104 "选择路线" - SF_ACTIONS = 1106 + SF_ACTIONS = 1105 "行动选项" - SF_RESULT = 1107 + SF_RESULT = 1106 "行动结果" - SF_EVENT = 1108 + SF_EVENT = 1107 "应对危机事件" - SF_TEAM_PASS = 1109 + SF_TEAM_PASS = 1108 "小队通过危机事件" - SF_CLICK_ANYWHERE = 1110 + SF_CLICK_ANYWHERE = 1109 "点击任意处继续" - SF_END = 1111 + SF_END = 1110 "抵达终点" HEADHUNTING = 1201 "干员寻访" @@ -606,17 +604,16 @@ SceneComment = { 1017: "应急模式额外元件", 1018: "选择定向元件", 1019: "保全扫荡确认", - 1101: "隐秘战线入口", - 1102: "暂离行动", - 1103: "选择小队", - 1104: "继续前进", - 1105: "选择路线", - 1106: "行动选项", - 1107: "行动结果", - 1108: "应对危机事件", - 1109: "小队通过危机事件", - 1110: "点击任意处继续", - 1111: "抵达终点", + 1101: "暂离行动", + 1102: "选择小队", + 1103: "继续前进", + 1104: "选择路线", + 1105: "行动选项", + 1106: "行动结果", + 1107: "应对危机事件", + 1108: "小队通过危机事件", + 1109: "点击任意处继续", + 1110: "抵达终点", 1201: "干员寻访", 1202: "使用赠送寻访机会确认对话框", 1203: "限定池单抽结果", diff --git a/mower/utils/typealias/res.py b/mower/utils/typealias/res.py index b54cb6e..7c76953 100644 --- a/mower/utils/typealias/res.py +++ b/mower/utils/typealias/res.py @@ -522,15 +522,16 @@ Res = Literal[ "sanity_charge_dialog", "sf/available", "sf/card", + "sf/card_confirm", "sf/click_anywhere", - "sf/confirm", "sf/continue", "sf/continue_event", - "sf/continue_result", "sf/end", "sf/entrance", + "sf/event_confirm", "sf/exit", "sf/exit_button", + "sf/exit_confirm", "sf/failure", "sf/inheritance", "sf/lost_in_the_trick", @@ -538,6 +539,7 @@ Res = Literal[ "sf/properties", "sf/ranger", "sf/restart", + "sf/return", "sf/select", "sf/select_team_ok", "sf/success",