④T4: 探针断言面——ui_struct 生涯屏四契约(入口点击链=合成点击真路径 pressed.emit→_open_career+开合回返断言/⑩只读巡检=子树游戏语义信号白名单外零连接〔17卡③形制·清单复用·恰 2 连接=返回钮+closed 外发〕/⑪零动效契约=子树零 AnimationPlayer+源码零 tween/⑫登记序树序契约=登记册暂停层后确认弹窗前+addChild 位同步〔P3 甲两序失守即红〕/⑬零跳转契约=页内除返回外七导航词零钮〔P4 甲〕)+ui_click 生涯段(入口点击链行为级复验+零跳转+局内零生涯入口件断言〔board_zone/level_screen 无 career_badge〕+关闭回返恢复开始层)+ui_contrast 测点三对随批入表(生涯页行名 WARM/行值 CANDLE/组帽 INK_L_GOLD 对 BG_BRIGHT——深墨族压深棕底 ~1.3:1 违 §7.2 的返工落闸:career_overlay 文字全换亮墨族 token 零新色值)——probe_gate 全绿(ui_input 十七断言/ui_struct 全屏零红/ui_contrast 15 对)+ui_click done=true 问题=0+ui_layout exit 0+冒烟 834/0
This commit is contained in:
1 parent
e5cd9bd5d4
commit
dc2d514d97
4 files changed
+127
-4
No files matched your search
@@ -47,6 +47,9 @@ func _init() -> void:
|
||||
box.add_child(hint)
|
||||
|
||||
# 组一·冒险战绩(终身计数域——存档 v6:总局数开局即计、通关局数三关全通才计)
|
||||
# 对比度口径:页底=暖亮档深棕(BG_BRIGHT),文字全用亮墨族 token(WARM 9.0:1 / WARM_SOFT 8.0:1 /
|
||||
# CANDLE 7.2:1 / INK_L_GOLD 9.1:1 实测对 BG_BRIGHT 全过 §7.2 ≥4.5:1——深墨族〔INK_LABEL〕
|
||||
# 压深棕底仅 ~1.3:1 属违例,禁用)
|
||||
_section_head(box, "冒险战绩")
|
||||
_total_label = _row(box, "冒险总局数")
|
||||
_cleared_label = _row(box, "通关局数")
|
||||
@@ -59,7 +62,7 @@ func _init() -> void:
|
||||
var bal_row := HBoxContainer.new()
|
||||
bal_row.add_theme_constant_override("separation", 8)
|
||||
box.add_child(bal_row)
|
||||
var bal_name := UiKit.label("钥石余额",UiKit.FS_BODY, false, UiKit.INK_LABEL)
|
||||
var bal_name := UiKit.label("钥石余额",UiKit.FS_BODY, false, UiKit.WARM)
|
||||
bal_row.add_child(bal_name)
|
||||
_keystone_badge = UiKit.keystone_badge("钥石 0")
|
||||
bal_row.add_child(_keystone_badge)
|
||||
@@ -123,16 +126,16 @@ func _emit_closed() -> void:
|
||||
# ---- 行构件(名称列 + 数值列——暂停层行族同构;数值 Label 返回供探针/冒烟投影断言)----
|
||||
|
||||
func _section_head(box: VBoxContainer, text: String) -> void:
|
||||
box.add_child(UiKit.label(text,UiKit.FS_BODY, true, UiKit.INK_LABEL))
|
||||
box.add_child(UiKit.label(text,UiKit.FS_BODY, true, UiKit.INK_L_GOLD))
|
||||
|
||||
|
||||
func _row(box: VBoxContainer, name_text: String) -> Label:
|
||||
var line := HBoxContainer.new()
|
||||
line.add_theme_constant_override("separation", 8)
|
||||
box.add_child(line)
|
||||
var name_l := UiKit.label(name_text,UiKit.FS_BODY, false, UiKit.INK_LABEL)
|
||||
var name_l := UiKit.label(name_text,UiKit.FS_BODY, false, UiKit.WARM)
|
||||
name_l.custom_minimum_size = Vector2(150, 0)
|
||||
line.add_child(name_l)
|
||||
var val_l := UiKit.label("—",UiKit.FS_BODY, true, UiKit.INK_TITLE)
|
||||
var val_l := UiKit.label("—",UiKit.FS_BODY, true, UiKit.CANDLE)
|
||||
line.add_child(val_l)
|
||||
return val_l
|
||||
@@ -154,6 +154,33 @@ func _ready() -> void:
|
||||
_problems.append("开始菜单缺退出游戏按钮(二轮 D1)")
|
||||
if ProbeUiUtil.find_button(main.settings_overlay, "退出游戏", "prefix") != null:
|
||||
_problems.append("设置面仍含退出游戏按钮(二轮 D1——只在一级菜单出现)")
|
||||
# ---- 生涯页段(迭代 18 卡④——入口点击链+关闭回返,真实按钮信号路径;本页只读零写,
|
||||
# 值断言归冒烟投影段与 ui_struct 结构族,此处只验开合路径与零跳转)----
|
||||
var career_btn: Button = ProbeUiUtil.find_button(main._start_overlay, "生涯", "prefix")
|
||||
if career_btn == null:
|
||||
_problems.append("生涯入口按钮缺失(开始层 careerbtn)")
|
||||
else:
|
||||
career_btn.pressed.emit() # 真实按钮信号路径 → 组合根 _open_career
|
||||
await get_tree().process_frame
|
||||
if not main.career_overlay.visible or main._start_overlay.visible:
|
||||
_problems.append("生涯页未打开(点击路径)")
|
||||
else:
|
||||
# 零跳转契约(提纲 P4 甲):页内除「返回」外零导航钮
|
||||
for nav in ["营地", "商店", "设置", "退出", "冒险"]:
|
||||
if ProbeUiUtil.find_button(main.career_overlay, nav, "contains") != null:
|
||||
_problems.append("生涯页内出现导航入口「%s」(零跳转违约——生涯纯只读)" % nav)
|
||||
# 局内入口断言(提纲 P4 甲):生涯入口只在开始层——战斗屏/地图屏零生涯角标
|
||||
if main.board_zone.find_child("career_badge", true, false) != null \
|
||||
or main.level_screen.find_child("career_badge", true, false) != null:
|
||||
_problems.append("局内屏出现生涯入口件(局内不放生涯入口违约)")
|
||||
var career_close: Button = ProbeUiUtil.find_button(main.career_overlay, "返回", "prefix")
|
||||
if career_close == null:
|
||||
_problems.append("生涯页返回按钮缺失")
|
||||
else:
|
||||
career_close.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if main.career_overlay.visible or not main._start_overlay.visible:
|
||||
_problems.append("生涯页关闭后未恢复开始层")
|
||||
# 换回全新零档(营地购买态不泄入后续冒险段——确定性;档案残留下次段首清理兜底)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_click_probe_reset", true, false, true) # 零档换注 + 继续上局按钮重刷(原三行样板收口)
|
||||
var resume_btn0: Button = ProbeUiUtil.find_button(main._start_overlay, "▶ 继续上局", "prefix")
|
||||
|
||||
@@ -29,6 +29,9 @@ func _pairs() -> Array:
|
||||
["锚·暖白/屏根", UiKit.WARM, UiKit.BG_ROOT, 1.0], # 全站锚点:暗底正文
|
||||
["锚·暖白弱/舞台底", UiKit.WARM_FAINT, UiKit.STAGE_BG, 1.0], # 全站锚点:B区辅助墨
|
||||
["钥石徽·深墨/烛光黄", UiKit.INK_ON_GOLD, UiKit.CANDLE, 1.0], # 迭代17卡③——badge 工厂件文字(营地徽+暂停层余额行同形制)
|
||||
["生涯页·行名墨/暖亮页底", UiKit.WARM, UiKit.BG_BRIGHT, 1.0], # 迭代18卡④——生涯页行名列/提示文(WARM_SOFT 同族亮墨)
|
||||
["生涯页·行值墨/暖亮页底", UiKit.CANDLE, UiKit.BG_BRIGHT, 1.0], # 迭代18卡④——生涯页数值列(烛光黄 bold)
|
||||
["生涯页·组帽墨/暖亮页底", UiKit.INK_L_GOLD, UiKit.BG_BRIGHT, 1.0],# 迭代18卡④——生涯页分组小节头(金亮 bold)
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -48,6 +48,27 @@ func _ready() -> void:
|
||||
else:
|
||||
problems.append("[camp] 营地入口按钮缺失(驱动中断)")
|
||||
|
||||
# ---- 生涯页(迭代 18 卡④):入口点击链(合成点击真路径=pressed.emit→组合根 _open_career)→
|
||||
# 结构断言族→只读巡检(契约 3)+零动效契约+登记序/树序契约(P3 甲营地同档)+零跳转契约
|
||||
#(提纲 P4 甲)→组合根真实路径关闭。----
|
||||
var careerbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "生涯", "prefix")
|
||||
if careerbtn != null:
|
||||
careerbtn.pressed.emit()
|
||||
_settle()
|
||||
if not main.career_overlay.visible or main._start_overlay.visible:
|
||||
problems.append("[career] 生涯页未打开或开始层未隐藏(入口点击链断裂)")
|
||||
await _audit("career", [main.career_overlay])
|
||||
_career_readonly_contract(main)
|
||||
_career_zero_motion_contract(main)
|
||||
_career_registry_contract(main)
|
||||
_career_nojump_contract(main)
|
||||
main._on_career_closed()
|
||||
_settle()
|
||||
if main.career_overlay.visible or not main._start_overlay.visible:
|
||||
problems.append("[career] 关闭后页未隐藏或开始层未恢复(模态栈单口失守)")
|
||||
else:
|
||||
problems.append("[career] 生涯入口按钮缺失(开始层 careerbtn)")
|
||||
|
||||
main.confirm_dialog.open("结构探针采样", "确认")
|
||||
_settle()
|
||||
await _audit("confirm", [main.confirm_dialog])
|
||||
@@ -233,6 +254,75 @@ func _pause_zero_motion_contract(main: Node) -> void:
|
||||
problems.append("[pause][motion] 视图源码含「%s」(R5 零动效直开直关破——P4 甲)" % token)
|
||||
|
||||
|
||||
# ---- 生涯页契约族(迭代 18 卡④——任务书契约 3/4+提纲 P3/P4 甲)----
|
||||
|
||||
# ⑩career 只读性契约(契约 3——暂停层 ⑧ 同形制):生涯页子树全控件 × 游戏语义信号连接巡检——
|
||||
# 清单外零连接。白名单={视图自身 _emit_closed〔返回钮〕, 组合根 _on_career_closed};页内任何
|
||||
# 购买/导航/写入方向的新连接一律红,须先入册审查。
|
||||
func _career_readonly_contract(main: Node) -> void:
|
||||
var overlay: Control = main.career_overlay
|
||||
var stack: Array = [overlay]
|
||||
var conn_count := 0
|
||||
while not stack.is_empty():
|
||||
var n: Node = stack.pop_back()
|
||||
for sig_name in _PAUSE_READONLY_SIGNALS:
|
||||
for conn in n.get_signal_connection_list(sig_name):
|
||||
conn_count += 1
|
||||
var cb: Callable = conn["callable"]
|
||||
var host: Object = cb.get_object()
|
||||
var m := String(cb.get_method())
|
||||
if host == overlay and m == "_emit_closed":
|
||||
continue
|
||||
if host == main and m == "_on_career_closed":
|
||||
continue
|
||||
problems.append("[career][readonly] 非法信号连接 %s.%s → %s.%s(零写通路巡检——白名单=视图 _emit_closed/组合根 _on_career_closed)"
|
||||
% [n.name, sig_name, host, m])
|
||||
for ch in n.get_children():
|
||||
stack.append(ch)
|
||||
if conn_count != 2:
|
||||
problems.append("[career][readonly] 信号连接数=%d 应=2(返回钮 pressed+closed 外发——多连接=写通路嫌疑)" % conn_count)
|
||||
|
||||
|
||||
# ⑪career 零动效契约(暂停层 ⑨ 同形制——P4 甲直开直关)
|
||||
func _career_zero_motion_contract(main: Node) -> void:
|
||||
var overlay: Control = main.career_overlay
|
||||
var stack: Array = [overlay]
|
||||
while not stack.is_empty():
|
||||
var n: Node = stack.pop_back()
|
||||
if n is AnimationPlayer:
|
||||
problems.append("[career][motion] 子树含 AnimationPlayer(零动效破)")
|
||||
for ch in n.get_children():
|
||||
stack.append(ch)
|
||||
var src := FileAccess.get_file_as_string("res://presentation/views/career_overlay.gd")
|
||||
for token in ["create_tween", "UiKit.motion"]:
|
||||
if src.contains(token):
|
||||
problems.append("[career][motion] 视图源码含「%s」(零动效直开直关破)" % token)
|
||||
|
||||
|
||||
# ⑫career 登记/树序契约(P3 甲——登记序=营地同档:暂停层之后、确认弹窗之前;树序同步=addChild
|
||||
# 同位。登记序=树序=z 序纪律〔缺陷⑤〕——两序任一失守即红)
|
||||
func _career_registry_contract(main: Node) -> void:
|
||||
var list: Array = main._modals._list
|
||||
var ci: int = list.find(main.career_overlay)
|
||||
var pi: int = list.find(main.pause_overlay)
|
||||
var fi: int = list.find(main.confirm_dialog)
|
||||
if ci < 0 or pi < 0 or fi < 0:
|
||||
problems.append("[career][registry] 生涯页未入登记册(或暂停层/确认弹窗缺登记)")
|
||||
return
|
||||
if ci != pi + 1 or ci > fi:
|
||||
problems.append("[career][registry] 登记序违约(应=暂停层后、确认弹窗前——P3 甲营地同档;pause=%d career=%d confirm=%d)" % [pi, ci, fi])
|
||||
var ti: int = main.career_overlay.get_index()
|
||||
if ti <= main.pause_overlay.get_index() or ti > main.confirm_dialog.get_index():
|
||||
problems.append("[career][registry] 树序与登记序不同步(addChild 位应=暂停层后、确认弹窗前;tree_index=%d)" % ti)
|
||||
|
||||
|
||||
# ⑬career 零跳转契约(提纲 P4 甲——页内零「前往他处」入口:除「返回」外任何导航钮=红)
|
||||
func _career_nojump_contract(main: Node) -> void:
|
||||
for nav in ["营地", "商店", "设置", "冒险", "继续上局", "退出", "前往"]:
|
||||
if ProbeUiUtil.find_button(main.career_overlay, nav, "contains") != null:
|
||||
problems.append("[career][nojump] 页内出现导航入口「%s」(零跳转违约——生涯纯只读)" % nav)
|
||||
|
||||
|
||||
# ⑥standee 专项:B 区站桩内容矩形 ⊆ 252px 舞台矩形(内缩 8px)且不被裁切
|
||||
# (UI 设计对齐批 N2 2026-10-06——名行基线离盒底 1px 同型高危写法返修回归闸;
|
||||
# 内容矩形=StandeeBody.content_rect(),最低绘制元素=底座下缘)
|
||||
|
||||
Reference in new issue
Block a user