隐秘战线适配新写法
Some checks failed
ci/woodpecker/push/check_format Pipeline failed

This commit is contained in:
zhbaor 2025-02-15 20:31:46 +08:00
parent dd300fd7af
commit 554d54f7b3
13 changed files with 300 additions and 230 deletions

View file

@ -640,46 +640,42 @@
"comment": "保全扫荡确认" "comment": "保全扫荡确认"
}, },
"1101": { "1101": {
"label": "SF_ENTRANCE",
"comment": "隐秘战线入口"
},
"1102": {
"label": "SF_EXIT", "label": "SF_EXIT",
"comment": "暂离行动" "comment": "暂离行动"
}, },
"1103": { "1102": {
"label": "SF_SELECT_TEAM", "label": "SF_SELECT_TEAM",
"comment": "选择小队" "comment": "选择小队"
}, },
"1104": { "1103": {
"label": "SF_CONTINUE", "label": "SF_CONTINUE",
"comment": "继续前进" "comment": "继续前进"
}, },
"1105": { "1104": {
"label": "SF_SELECT", "label": "SF_SELECT",
"comment": "选择路线" "comment": "选择路线"
}, },
"1106": { "1105": {
"label": "SF_ACTIONS", "label": "SF_ACTIONS",
"comment": "行动选项" "comment": "行动选项"
}, },
"1107": { "1106": {
"label": "SF_RESULT", "label": "SF_RESULT",
"comment": "行动结果" "comment": "行动结果"
}, },
"1108": { "1107": {
"label": "SF_EVENT", "label": "SF_EVENT",
"comment": "应对危机事件" "comment": "应对危机事件"
}, },
"1109": { "1108": {
"label": "SF_TEAM_PASS", "label": "SF_TEAM_PASS",
"comment": "小队通过危机事件" "comment": "小队通过危机事件"
}, },
"1110": { "1109": {
"label": "SF_CLICK_ANYWHERE", "label": "SF_CLICK_ANYWHERE",
"comment": "点击任意处继续" "comment": "点击任意处继续"
}, },
"1111": { "1110": {
"label": "SF_END", "label": "SF_END",
"comment": "抵达终点" "comment": "抵达终点"
}, },

BIN
mower/resources/sf/card_confirm.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
mower/resources/sf/continue_result.png (Stored with Git LFS)

Binary file not shown.

BIN
mower/resources/sf/event_confirm.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
mower/resources/sf/return.png (Stored with Git LFS) Normal file

Binary file not shown.

View file

@ -1,26 +1,37 @@
from datetime import datetime, timedelta from difflib import SequenceMatcher
import cv2 import cv2
from mower.static import secret_front from mower.static import secret_front
from mower.utils import config from mower.utils import config
from mower.utils import typealias as tp from mower.utils import typealias as tp
from mower.utils.csleep import MowerExit from mower.utils.email import notify
from mower.utils.email import send_message from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg from mower.utils.image import cropimg
from mower.utils.log import logger from mower.utils.log import logger
from mower.utils.rapidocr import ocr_rec
from mower.utils.scene import Scene from mower.utils.scene import Scene
from mower.utils.solver import BaseSolver from mower.utils.solver import BaseSolver
from mower.utils.vector import sa, va from mower.utils.vector import sa, va
CardInfo = tuple[int, int, int, float]
def exp(card):
data = card[:3] def exp(card: CardInfo) -> list[float]:
p = card[3] """计算卡片的期望
return [i * p for i in data]
Args:
card (CardInfo): 卡片的值
Returns:
list[float]: 三项属性的期望
"""
return [i * card[3] for i in card[:3]]
class SecretFront(BaseSolver): class SecretFront(BaseSolver):
solver_name = "隐秘战线"
target = { target = {
"1A": [20, 20, 20], "1A": [20, 20, 20],
"2A": [60, 55, 45], "2A": [60, 55, 45],
@ -49,50 +60,77 @@ class SecretFront(BaseSolver):
"结局E": "medicine", "结局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 @property
def route(self): def route(self):
"路线"
return self.routes[config.conf.secret_front.target] return self.routes[config.conf.secret_front.target]
@property @property
def team(self): def team(self):
"小队"
return self.teams[config.conf.secret_front.target] return self.teams[config.conf.secret_front.target]
def run(self): def run(self):
self.timeout = timedelta(seconds=config.conf.reclamation_algorithm.timeout) self.route_names = []
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.event = False self.event = False
self.series = None # 支援作战平台、游侠、诡影迷踪 self.series = None
self.send_email = False
self.reset_actions() self.reset_actions()
super().run() return super().run()
return False
def reset_actions(self): def reset_actions(self):
self.actions = {} "清空缓存的卡片数据"
for page in range(3): self.actions = {0: {}, 1: {}, 2: {}}
self.actions[page] = {}
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) return config.recog.num.number_int("secret_front", scope, height)
def card_pos(self, total, idx): def card_pos(self, total: int, idx: int) -> tp.Coordinate:
if total == 3: """总共有total张卡片时下标为idx(从0开始)卡片的左上角坐标
return [(301, 466), (830, 466), (1360, 466)][idx]
elif total == 2:
return [(565, 466), (1095, 466)][idx]
else:
return (830, 466)
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) pos = self.card_pos(total, idx)
scope = sa(((10, 380), (140, 430)), pos) scope = sa(((10, 380), (140, 430)), pos)
@ -111,7 +149,16 @@ class SecretFront(BaseSolver):
logger.debug(f"{name=} {hue=}") logger.debug(f"{name=} {hue=}")
return name, hue > 18 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) pos = self.card_pos(total, idx)
materiel = sa(((84, 70), (180, 102)), pos) materiel = sa(((84, 70), (180, 102)), pos)
@ -133,24 +180,32 @@ class SecretFront(BaseSolver):
return materiel, intelligence, medicine, percentage return materiel, intelligence, medicine, percentage
def page_number(self): def page_number(self) -> int | None:
title = cropimg(config.recog.gray, ((1020, 230), (1210, 285))) """识别当前页数
if self.route_matcher is None:
Returns:
int | None: 页数从0开始
"""
if not self.route_names:
self.tap((125, 840))
return None return None
score, scope = self.route_matcher.match2d(title) img = cropimg(config.recog.gray, ((915, 230), (1320, 290)))
if scope is None: name = ocr_rec(img)
return None max_ratio = 0
pos_x = scope[0][0] page_number = 0
if pos_x < 800: for i, n in enumerate(self.route_names):
page_number = 0 if (ratio := SequenceMatcher(None, name, n).ratio()) > max_ratio:
elif pos_x < 1330: page_number = i
page_number = 1 max_ratio = ratio
else:
page_number = 2
logger.debug(f"{page_number=}") logger.debug(f"{page_number=}")
return page_number return page_number
def card_total(self): def card_total(self) -> int:
"""识别当前有几张卡片
Returns:
int: 卡片数量
"""
p3 = self.card_pos(3, 0) p3 = self.card_pos(3, 0)
p2 = self.card_pos(2, 0) p2 = self.card_pos(2, 0)
up_scope = ((0, 0), (473, 120)) up_scope = ((0, 0), (473, 120))
@ -159,11 +214,11 @@ class SecretFront(BaseSolver):
s3d = sa(down_scope, p3) s3d = sa(down_scope, p3)
s2u = sa(up_scope, p2) s2u = sa(up_scope, p2)
s2d = sa(down_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 total = 3
elif self.find("sf/available", scope=s3d): elif self.find("sf/available", scope=s3d):
total = 3 total = 3
elif (pos := self.find("sf/card", scope=s2u)) and pos[0][0] < 610: elif self.find("sf/card", scope=s2u):
total = 2 total = 2
elif self.find("sf/available", scope=s2d): elif self.find("sf/available", scope=s2d):
total = 2 total = 2
@ -172,14 +227,18 @@ class SecretFront(BaseSolver):
logger.debug(f"{total=}") logger.debug(f"{total=}")
return total return total
def max_card(self): def max_card(self) -> tuple[int, int]:
"""计算最优选项
Returns:
tuple[int, int]: 返回最优页码及卡片下标
"""
max_page = -1 max_page = -1
max_card = -1 max_card = -1
max_score = -1 max_score = -1
logger.debug(f"{self.properties=}") logger.debug(f"{self.properties=}")
# 根据目标计算
for page, page_action in self.actions.items(): for page, page_action in self.actions.items():
for card, action in page_action.items(): for card, action in page_action.items():
for stage in self.route: for stage in self.route:
@ -201,42 +260,40 @@ class SecretFront(BaseSolver):
logger.debug(f"{max_page=} {max_card=}") logger.debug(f"{max_page=} {max_card=}")
return max_page, max_card return max_page, max_card
def choose_card(self, total, idx): def choose_card(self, total: int, idx: int):
self.route_matcher = None """点击卡片
self.properties = None
self.reset_actions()
if total == 3: Args:
start = 545 total (int): 卡片总数
elif total == 2: idx (int): 卡片下标从0开始
start = 805 """
else: start = {3: 545, 2: 805, 1: 1075}[total]
start = 1075 pos = (start + idx * 530, 900)
self.tap((start + idx * 530, 900), interval=0.5) self.tap(pos)
self.tap((start + idx * 530, 900), interval=2)
def move_forward(self, scene): def transition(self):
# 从首页进入隐秘战线 if (scene := self.scene()) == Scene.TERMINAL_MAIN_THEME:
if scene == Scene.INDEX: self.main_theme(2, 14)
self.tap_index_element("terminal") elif scene == Scene.OPERATOR_CHOOSE_LEVEL:
elif scene == Scene.TERMINAL_MAIN: if pos := self.find("sf/entrance"):
self.tap_terminal_button("main_theme") self.tap(pos)
elif scene == Scene.TERMINAL_MAIN_THEME: return
self.tap("navigation/main/14") if self.animation():
elif scene == Scene.SF_ENTRANCE: return
self.tap("sf/entrance") SceneGraphSolver().step(Scene.TERMINAL_MAIN_THEME)
# 选择小队
elif scene == Scene.SF_SELECT_TEAM: 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") self.tap("sf/select_team_ok")
# 继续前进
elif scene == Scene.SF_CONTINUE: elif scene == Scene.SF_CONTINUE:
self.tap("sf/continue") self.tap("sf/continue")
# 选择路线时识别已有属性值
elif scene == Scene.SF_SELECT: elif scene == Scene.SF_SELECT:
if self.animation(((0, 0), (1920, 1030))):
return
self.send_email = True
self.event = False self.event = False
if self.properties is None: if self.properties is None:
@ -247,8 +304,12 @@ class SecretFront(BaseSolver):
] ]
logger.debug(f"{self.properties=}") logger.debug(f"{self.properties=}")
if self.route_matcher is None: if not self.route_names:
self.route_matcher = config.recog.matcher 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 self.series = None
if ( if (
@ -267,39 +328,42 @@ class SecretFront(BaseSolver):
self.series = 2 self.series = 2
logger.debug(f"{self.series=}") logger.debug(f"{self.series=}")
self.tap((545 + 530 * self.series, 640), interval=1.5) self.tap((545 + 530 * self.series, 640))
return return
self.tap((545, 640), interval=1.5) self.tap((545, 640))
# 行动列表
elif scene == Scene.SF_ACTIONS: 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() total = self.card_total()
if self.event: if self.event:
name_list = [self.stage_card(total, i) for i in range(total)] name_list = [self.event_card(total, i) for i in range(total)]
for idx, data in enumerate(name_list): for idx, (name, available) in enumerate(name_list):
name, available = data if name not in self.route:
if name in self.route: continue
if available: if available:
self.choose_card(total, idx) self.choose_card(total, idx)
else:
self.exit = "restart"
self.tap("sf/exit_button")
return return
self.exit = "restart" break
self.tap("sf/exit_button") self.tap("sf/exit_button")
return return
if (page_number := self.page_number()) is None: if (page_number := self.page_number()) is None:
self.sleep()
return return
target = self.target[self.route[-1]] target = self.target[self.route[-1]]
distance = [max(t - p, 0) for p, t in zip(self.properties, target)] distance = [max(t - p, 0) for p, t in zip(self.properties, target)]
if sum(distance) == 0: if sum(distance) == 0:
self.choose_card(total, 0) self.choose_card(total, 0)
self.sleep(3)
return return
if self.series is not None: if self.series is not None:
@ -309,6 +373,7 @@ class SecretFront(BaseSolver):
if all(card[3] < 0.8 for card in card_data): if all(card[3] < 0.8 for card in card_data):
logger.debug("成功概率太低") logger.debug("成功概率太低")
self.series = None self.series = None
self.solver_update_before_transition = False
return return
elif not all(self.actions.values()): elif not all(self.actions.values()):
@ -319,6 +384,7 @@ class SecretFront(BaseSolver):
for idx in range(total): for idx in range(total):
self.actions[page_number][idx] = exp(self.card(total, idx)) self.actions[page_number][idx] = exp(self.card(total, idx))
logger.debug(f"{self.actions=}") logger.debug(f"{self.actions=}")
self.solver_update_before_transition = False
elif (page_number + 1) % 3 == target_number: elif (page_number + 1) % 3 == target_number:
self.tap((1785, 225)) # 下一页 self.tap((1785, 225)) # 下一页
else: else:
@ -329,87 +395,25 @@ class SecretFront(BaseSolver):
if max_page == page_number: if max_page == page_number:
self.choose_card(len(self.actions[max_page]), max_card) self.choose_card(len(self.actions[max_page]), max_card)
self.sleep(3)
elif (page_number + 1) % 3 == max_page: elif (page_number + 1) % 3 == max_page:
self.tap((1785, 225)) # 下一页 self.tap((1785, 225)) # 下一页
else: else:
self.tap((350, 225)) # 上一页 self.tap((350, 225)) # 上一页
# 行动结果
elif scene == Scene.SF_RESULT: elif scene == Scene.SF_RESULT:
if pos := self.find("sf/continue_result"): self.route_names = []
self.tap(pos) self.properties = None
else: self.reset_actions()
self.sleep() self.tap((1640, 945))
elif scene == Scene.SF_EVENT: elif scene == Scene.SF_EVENT:
self.event = True 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]: elif scene in [Scene.SF_TEAM_PASS, Scene.SF_CLICK_ANYWHERE, Scene.SF_END]:
self.tap((960, 980), interval=2) self.tap((960, 980))
if scene == Scene.SF_END:
send_message(
f"隐秘战线成功完成{config.conf.secret_front.target}", level="INFO"
)
# 关闭说明
elif scene == Scene.NOTICE:
self.tap("notice")
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: elif scene == Scene.SF_EXIT:
if self.exit == "restart": self.tap("sf/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))
else: else:
self.sleep() SceneGraphSolver().step(Scene.TERMINAL_MAIN_THEME)
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)

View file

@ -1,3 +1,5 @@
# ruff: noqa: F401
from . import ( from . import (
extra, extra,
friend, friend,
@ -8,26 +10,9 @@ from . import (
recruit, recruit,
riic, riic,
rogue, rogue,
secret_front,
shop, shop,
sss, sss,
terminal, terminal,
) )
from .utils import DG, SceneGraphSolver, edge from .utils import SceneGraphSolver
__all__ = [
"SceneGraphSolver",
"DG",
"edge",
"extra",
"friend",
"index",
"mission",
"navbar",
"operation",
"recruit",
"riic",
"shop",
"sss",
"terminal",
"rogue",
]

View file

@ -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")

View file

@ -430,6 +430,34 @@ class Recognizer:
self.scene = Scene.SIGN_IN_ORUNDUM self.scene = Scene.SIGN_IN_ORUNDUM
elif self.find("start_story"): elif self.find("start_story"):
self.scene = Scene.STORY_STAGE 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(): elif self.detect_index_scene():

View file

@ -163,6 +163,20 @@ color = {
"room_detail": (1291, 33), "room_detail": (1291, 33),
"sanity_charge": (1111, 382), "sanity_charge": (1111, 382),
"sanity_charge_dialog": (570, 529), "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/assist.jpg": (816, 222),
"shop/cart": (1252, 842), "shop/cart": (1252, 842),
"shop/collect": (1467, 43), "shop/collect": (1467, 43),
@ -389,6 +403,19 @@ template_matching = {
"rogue/refresh": ((1205, 200), (1256, 350)), "rogue/refresh": ((1205, 200), (1256, 350)),
"rogue/team_check_to_do": ((0, 800), (1920, 960)), "rogue/team_check_to_do": ((0, 800), (1920, 960)),
"rogue/view_data_back": (147, 46), "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/headhunting/available": (1177, 857),
"sign_in/moon_festival/banner": (704, 92), "sign_in/moon_festival/banner": (704, 92),
"sign_in/shop/0": (1341, 618), "sign_in/shop/0": (1341, 618),
@ -458,6 +485,7 @@ template_matching_score = {
"recruit/stone": 0.7, "recruit/stone": 0.7,
"recruit/time": 0.8, "recruit/time": 0.8,
"rogue/node_be_choosed": 0.7, "rogue/node_be_choosed": 0.7,
"sf/card": 0.8,
"sign_in/moon_festival/banner": 0.5, "sign_in/moon_festival/banner": 0.5,
"sss/add_agent": 0.8, "sss/add_agent": 0.8,
"sss/drop_EC": 0.8, "sss/drop_EC": 0.8,

View file

@ -319,27 +319,25 @@ class Scene:
"选择定向元件" "选择定向元件"
SSS_ELIMI_AGENCY = 1019 SSS_ELIMI_AGENCY = 1019
"保全扫荡确认" "保全扫荡确认"
SF_ENTRANCE = 1101 SF_EXIT = 1101
"隐秘战线入口"
SF_EXIT = 1102
"暂离行动" "暂离行动"
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 HEADHUNTING = 1201
"干员寻访" "干员寻访"
@ -606,17 +604,16 @@ SceneComment = {
1017: "应急模式额外元件", 1017: "应急模式额外元件",
1018: "选择定向元件", 1018: "选择定向元件",
1019: "保全扫荡确认", 1019: "保全扫荡确认",
1101: "隐秘战线入口", 1101: "暂离行动",
1102: "暂离行动", 1102: "选择小队",
1103: "选择小队", 1103: "继续前进",
1104: "继续前进", 1104: "选择路线",
1105: "选择路线", 1105: "行动选项",
1106: "行动选项", 1106: "行动结果",
1107: "行动结果", 1107: "应对危机事件",
1108: "应对危机事件", 1108: "小队通过危机事件",
1109: "小队通过危机事件", 1109: "点击任意处继续",
1110: "点击任意处继续", 1110: "抵达终点",
1111: "抵达终点",
1201: "干员寻访", 1201: "干员寻访",
1202: "使用赠送寻访机会确认对话框", 1202: "使用赠送寻访机会确认对话框",
1203: "限定池单抽结果", 1203: "限定池单抽结果",

View file

@ -522,15 +522,16 @@ Res = Literal[
"sanity_charge_dialog", "sanity_charge_dialog",
"sf/available", "sf/available",
"sf/card", "sf/card",
"sf/card_confirm",
"sf/click_anywhere", "sf/click_anywhere",
"sf/confirm",
"sf/continue", "sf/continue",
"sf/continue_event", "sf/continue_event",
"sf/continue_result",
"sf/end", "sf/end",
"sf/entrance", "sf/entrance",
"sf/event_confirm",
"sf/exit", "sf/exit",
"sf/exit_button", "sf/exit_button",
"sf/exit_confirm",
"sf/failure", "sf/failure",
"sf/inheritance", "sf/inheritance",
"sf/lost_in_the_trick", "sf/lost_in_the_trick",
@ -538,6 +539,7 @@ Res = Literal[
"sf/properties", "sf/properties",
"sf/ranger", "sf/ranger",
"sf/restart", "sf/restart",
"sf/return",
"sf/select", "sf/select",
"sf/select_team_ok", "sf/select_team_ok",
"sf/success", "sf/success",