Files
gplan-2/game/smoke/probe_ui_util.gd
T

113 lines
4.8 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# VERTICAL SLICE - NOT FOR PRODUCTION
# 探针共用面:树寻址助手 + 存档/设置/元进度隔离样板单点(T6 样板收口批 2026-10-02)。
# 收口范围:ui_probe / ui_click_probe / shot_probe / fx_shot_probe 四探针的 7 处树寻址样板
# 与 7 处隔离样板(各探针隔离文件名后缀 tag 保持不变)。
# 用法:探针侧 `const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd")` 后静态调用
#(探针载体含 --script 场景两种,均无全局标识符——禁 class_name 裸引用)。
extends RefCounted
const SaveManagerScript := preload("res://core/save_manager.gd")
const MetaProgressionScript := preload("res://core/meta_progression.gd")
const SettingsStoreScript := preload("res://presentation/settings_store.gd")
# ── 树寻址(递归只读——按钮/标签句柄未存组合根成员的探针专用面) ──────────────
# 匹配模式参数化(历史两种语义,禁混用禁静默改变):
# mode="prefix" = text.begins_with(needle)(ui_probe / ui_click_probe 历史语义)
# mode="contains" = text.contains(needle)(shot_probe / fx_shot_probe 历史语义)
# 调用点替换时逐一核对原语义后选参。
static func find_button(root: Node, needle: String, mode: String = "prefix") -> Button:
if root == null:
return null
if root is Button and _text_match(String(root.text), needle, mode):
return root
for child in root.get_children():
var found := find_button(child, needle, mode)
if found != null:
return found
return null
# CheckButton 同款寻址(ui_click_probe 历史语义 = contains——设置面旧入口退役断言用)
static func find_check_button(root: Node, needle: String) -> CheckButton:
if root == null:
return null
if root is CheckButton and String(root.text).contains(needle):
return root
for child in root.get_children():
var found := find_check_button(child, needle)
if found != null:
return found
return null
# Label 按文案包含寻址(shot_probe GP 徽章读数锚)
static func find_label(root: Node, text_fragment: String) -> Label:
if root == null:
return null
if root is Label and String(root.text).contains(text_fragment):
return root
for child in root.get_children():
var found := find_label(child, text_fragment)
if found != null:
return found
return null
# 控件实测几何(shot_probe checker 文字框取样坐标源——禁硬编码像素,分辨率档位自适应)
static func label_rect(root: Node, text_fragment: String) -> Dictionary:
if root == null:
return {}
if root is Label and String(root.text).contains(text_fragment):
return {"x": root.global_position.x, "y": root.global_position.y,
"w": root.size.x, "h": root.size.y}
for child in root.get_children():
var r := label_rect(child, text_fragment)
if not r.is_empty():
return r
return {}
# 按脚本名寻址(resource_path contains——shot_probe hero 面板锚)
static func find_by_script(root: Node, script_name: String) -> Node:
if root == null:
return null
var s: Script = root.get_script()
if s != null and String(s.resource_path).contains(script_name):
return root
for child in root.get_children():
var r := find_by_script(child, script_name)
if r != null:
return r
return null
static func _text_match(text: String, needle: String, mode: String) -> bool:
return text.begins_with(needle) if mode == "prefix" else text.contains(needle)
# ── 存档/设置/元进度三面隔离(探针禁碰真实档 user://save.json——SaveManager 路径注入纪律) ──
# tag = 隔离档名(不带扩展名,如 "smoke_input_probe_save"——各探针后缀保持不变);先删后建防陈旧档泄入。
# mark_first_done = 对齐真实档游玩史口径(模板抽签路径不变);with_settings = 连设置面换注
#(隔离 cfg 名 = <tag>_settings.cfg,与被收口探针原文件名逐一同名);refresh_resume = 组合根
# 「继续上局」按钮重刷;swap_save = 是否换注 main.save_manager(营地先行段只换 meta 不换 save_manager)。
# 返回隔离 SaveManager 实例(调用方常需后续直读余额/重读档)。
static func isolate_save(main, tag: String, mark_first_done: bool = false, with_settings: bool = false,
refresh_resume: bool = false, swap_save: bool = true):
var save_path := "user://%s.json" % tag
for p in [save_path, save_path + ".tmp", "user://%s_settings.cfg" % tag]:
if FileAccess.file_exists(p):
DirAccess.remove_absolute(p)
var iso = SaveManagerScript.new(save_path)
iso.load_from_disk()
if mark_first_done:
iso.mark_first_adventure_done()
if swap_save:
main.save_manager = iso
main.meta = MetaProgressionScript.new(main.db, iso)
if with_settings:
main.settings_store = SettingsStoreScript.new("user://%s_settings.cfg" % tag)
if refresh_resume:
main._refresh_resume_button()
return iso