iter49-卡2:模态句柄分域批(句柄册三域化):UiModals 14→3纯字段容器+run/menu两新子容器+ModalFlow升格注册面直驻+全仓寻址换代+V1结构断言
This commit is contained in:
1 parent
11beb4fc59
commit
240f1a1769
28 files changed
+552
-513
No files matched your search
@@ -37,14 +37,14 @@ func _ready() -> void:
|
||||
# 等关卡画面出图(choices_presented 异步到达——最多 3s 轮询)
|
||||
for i in 60:
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.level_screen != null and main.ui.modals.level_screen.visible:
|
||||
if main.ui.modals.run.level_screen != null and main.ui.modals.run.level_screen.visible:
|
||||
break
|
||||
if main.ui.modals.level_screen == null or not main.ui.modals.level_screen.visible:
|
||||
if main.ui.modals.run.level_screen == null or not main.ui.modals.run.level_screen.visible:
|
||||
_fail("关卡画面未出现(函数直调中间态路径)")
|
||||
return
|
||||
for i in 5:
|
||||
await get_tree().process_frame
|
||||
main.ui.modals.level_screen.press_candidate(0)
|
||||
main.ui.modals.run.level_screen.press_candidate(0)
|
||||
for i in 20:
|
||||
await get_tree().process_frame
|
||||
var st = main.run_scope.settlement
|
||||
|
||||
@@ -24,12 +24,12 @@ func _ready() -> void:
|
||||
add_child(main)
|
||||
await get_tree().process_frame
|
||||
ProbeUiUtil.isolate_save(main, "smoke_layout_probe", true, false, true)
|
||||
main.ui.modals.debug_overlay.seed_edit.text = "42" # 种子钉死(确定性禁依赖默认随机分支)
|
||||
main.ui.modals.menu.debug_overlay.seed_edit.text = "42" # 种子钉死(确定性禁依赖默认随机分支)
|
||||
main._start_adventure_from_menu()
|
||||
for i in range(8):
|
||||
await get_tree().process_frame
|
||||
# 进战斗屏——三区(B 战斗画面/C 角色信息/D 扫雷图)同屏常驻,菜单屏不构成断言面
|
||||
main.ui.modals.level_screen.press_candidate(0)
|
||||
main.ui.modals.run.level_screen.press_candidate(0)
|
||||
for i in range(20):
|
||||
await get_tree().process_frame
|
||||
for vp in VIEWPORTS:
|
||||
|
||||
@@ -130,7 +130,7 @@ static func open_camp_via_savesel(main, tag: String) -> bool:
|
||||
if FileAccess.file_exists(sp):
|
||||
DirAccess.remove_absolute(sp)
|
||||
main._open_save_select()
|
||||
var new_btn: Button = main.ui.modals.save_select_overlay._new_btns.get(1)
|
||||
var new_btn: Button = main.ui.modals.menu.save_select_overlay._new_btns.get(1)
|
||||
if new_btn == null:
|
||||
return false
|
||||
new_btn.pressed.emit() # 真实按钮信号路径 → _on_save_select_new → create_slot+open_camp
|
||||
|
||||
@@ -54,7 +54,7 @@ func _screen_seals() -> Dictionary:
|
||||
"菜单": main.ui.screens.start_overlay != null and main.ui.screens.start_overlay.visible,
|
||||
"营地": main.ui.modals.camp.scene != null and main.ui.modals.camp.scene.visible,
|
||||
"冒险": main.run_scope != null and main.run_scope.is_adventure,
|
||||
"终局": main.ui.modals.end_overlay != null and main.ui.modals.end_overlay.visible,
|
||||
"终局": main.ui.modals.run.end_overlay != null and main.ui.modals.run.end_overlay.visible,
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ func _frames(n: int = 2) -> void:
|
||||
func _step_boot_menu() -> void:
|
||||
_expect_exclusive("①boot", "菜单")
|
||||
_expect_adventure_seal("①boot", false)
|
||||
if main.ui.modals.debug_overlay != null and main.ui.modals.debug_overlay.visible:
|
||||
if main.ui.modals.menu.debug_overlay != null and main.ui.modals.menu.debug_overlay.visible:
|
||||
_problems.append("①boot:调试浮窗 boot 自动开(菜单优先失守)")
|
||||
|
||||
|
||||
@@ -123,9 +123,9 @@ func _step_camp_back_to_menu() -> void:
|
||||
return
|
||||
main.ui.modals.camp.scene.object_pressed.emit(&"campfire")
|
||||
await _frames()
|
||||
if not main.ui.modals.confirm_dialog.visible:
|
||||
if not main.ui.modals.menu.confirm_dialog.visible:
|
||||
_problems.append("③篝火:二次确认弹窗未现(camp.md v2.2 必须先确认)〔营地图批 V7〕")
|
||||
main.ui.modals.confirm_dialog.confirmed.emit() # 二次确认离场(confirmed 先于关层——卡④ T4)
|
||||
main.ui.modals.menu.confirm_dialog.confirmed.emit() # 二次确认离场(confirmed 先于关层——卡④ T4)
|
||||
await _frames()
|
||||
_expect_exclusive("③营地→菜单(回退)", "菜单")
|
||||
|
||||
@@ -143,15 +143,15 @@ func _step_save_select_open_back() -> void:
|
||||
esb.pressed.emit() # 真实按钮信号路径 → _open_save_select(卡② mn3 点击链——卡③ 直调中间态就此闭环)
|
||||
await get_tree().process_frame
|
||||
var seals := _screen_seals()
|
||||
if not main.ui.modals.save_select_overlay.visible or not seals_check_single(seals):
|
||||
_problems.append("[savesel] sl10 开层后屏级互斥失守(选档=%s)" % str(main.ui.modals.save_select_overlay.visible))
|
||||
var back_btn: Button = ProbeUiUtil.find_button(main.ui.modals.save_select_overlay, "返回", "prefix")
|
||||
if not main.ui.modals.menu.save_select_overlay.visible or not seals_check_single(seals):
|
||||
_problems.append("[savesel] sl10 开层后屏级互斥失守(选档=%s)" % str(main.ui.modals.menu.save_select_overlay.visible))
|
||||
var back_btn: Button = ProbeUiUtil.find_button(main.ui.modals.menu.save_select_overlay, "返回", "prefix")
|
||||
if back_btn == null:
|
||||
_problems.append("[savesel] sl10 返回钮缺失(页壳顶条)")
|
||||
else:
|
||||
back_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.save_select_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
if main.ui.modals.menu.save_select_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
_problems.append("[savesel] sl10 返回后选档未隐藏或开始层未恢复(关闭链失守)")
|
||||
# ESC 语境:再开选档→合成 ESC 键→层不关、流程零扰动(ESC 不属选档语境——零实现断言)
|
||||
main._open_save_select()
|
||||
@@ -162,7 +162,7 @@ func _step_save_select_open_back() -> void:
|
||||
ev.pressed = true
|
||||
main.get_viewport().push_input(ev, true)
|
||||
await get_tree().process_frame
|
||||
if not main.ui.modals.save_select_overlay.visible:
|
||||
if not main.ui.modals.menu.save_select_overlay.visible:
|
||||
_problems.append("[savesel] sl10 ESC 关闭了选档层(选档语境 ESC 应不响应——卡⑤ 范围外)")
|
||||
main._on_save_select_closed()
|
||||
await get_tree().process_frame
|
||||
@@ -174,7 +174,7 @@ func seals_check_single(f: Dictionary) -> bool:
|
||||
for k in f:
|
||||
if bool(f[k]):
|
||||
on += 1
|
||||
if main.ui.modals.save_select_overlay.visible:
|
||||
if main.ui.modals.menu.save_select_overlay.visible:
|
||||
on += 1 # 选档自身计入(调用点已开层)
|
||||
return on == 1
|
||||
|
||||
@@ -187,25 +187,25 @@ func _step_menu_to_adventure() -> void:
|
||||
_expect_adventure_seal("④菜单→冒险", true)
|
||||
if main.run_scope != null and main.run_scope.adventure == null:
|
||||
_problems.append("④菜单→冒险:冒险实例未建立(入口停点未达)")
|
||||
if main.ui.modals.level_screen != null and not main.ui.modals.level_screen.visible:
|
||||
if main.ui.modals.run.level_screen != null and not main.ui.modals.run.level_screen.visible:
|
||||
_problems.append("④菜单→冒险:入口停点未落在关卡地图屏(level_screen 不可见)")
|
||||
|
||||
|
||||
# ---- ⑤ 冒险内屏切换:关卡地图屏 ⇄ 战斗屏(屏内两态,屏级仍独占)----
|
||||
func _step_level_to_battle_and_back() -> void:
|
||||
if not main.ui.modals.level_screen.visible:
|
||||
if not main.ui.modals.run.level_screen.visible:
|
||||
_problems.append("⑤冒险内切换:前置不在关卡地图屏")
|
||||
return
|
||||
main._exit_level_screen()
|
||||
await _frames()
|
||||
if main.ui.modals.level_screen.visible:
|
||||
if main.ui.modals.run.level_screen.visible:
|
||||
_problems.append("⑤冒险内切换:退出关卡屏后 level_screen 仍可见")
|
||||
if main.ui.screens.battle_root != null and not main.ui.screens.battle_root.visible:
|
||||
_problems.append("⑤冒险内切换:战斗屏未接手(battle_root 不可见)")
|
||||
_expect_exclusive("⑤冒险内切换(关卡→战斗)", "冒险")
|
||||
main._enter_level_screen()
|
||||
await _frames()
|
||||
if not main.ui.modals.level_screen.visible:
|
||||
if not main.ui.modals.run.level_screen.visible:
|
||||
_problems.append("⑤冒险内切换:回到关卡地图屏失败")
|
||||
_expect_exclusive("⑤冒险内切换(战斗→关卡)", "冒险")
|
||||
|
||||
@@ -218,16 +218,16 @@ func _step_abandon_to_end() -> void:
|
||||
main._on_abandon_requested()
|
||||
await _frames(4)
|
||||
_expect_exclusive("⑥放弃→终局", "终局")
|
||||
if main.ui.modals.end_overlay != null and not main.ui.modals.end_overlay.visible:
|
||||
if main.ui.modals.run.end_overlay != null and not main.ui.modals.run.end_overlay.visible:
|
||||
_problems.append("⑥放弃→终局:终局覆盖层未开")
|
||||
|
||||
|
||||
# ---- ⑦ 终局 → 菜单(终局出口返回开始界面)----
|
||||
func _step_end_back_to_menu() -> void:
|
||||
if main.ui.modals.end_overlay == null or not main.ui.modals.end_overlay.visible:
|
||||
if main.ui.modals.run.end_overlay == null or not main.ui.modals.run.end_overlay.visible:
|
||||
_problems.append("⑦终局→菜单:前置不在终局")
|
||||
return
|
||||
main.ui.modals.end_overlay.continue_pressed.emit()
|
||||
main.ui.modals.run.end_overlay.continue_pressed.emit()
|
||||
await _frames(3)
|
||||
_expect_exclusive("⑦终局→菜单", "菜单")
|
||||
if main.run_scope != null and main.run_scope.is_adventure:
|
||||
@@ -273,7 +273,7 @@ func _step_camp_esc_and_hud() -> void:
|
||||
await _frames()
|
||||
main._on_esc_settings()
|
||||
await _frames()
|
||||
if not main.ui.modals.settings_overlay.visible:
|
||||
if not main.ui.modals.menu.settings_overlay.visible:
|
||||
_problems.append("[esc] 浮窗设置出口断裂〔ESC批 V4〕")
|
||||
_push_esc()
|
||||
await _frames()
|
||||
@@ -286,7 +286,7 @@ func _step_camp_esc_and_hud() -> void:
|
||||
# 返回主菜单动线(契约 4——浮窗自收+营地隐+选档收+菜单显)
|
||||
main.ui.modals.camp.esc_overlay.return_requested.emit()
|
||||
await _frames()
|
||||
if main.ui.modals.camp.esc_overlay.visible or main.ui.modals.camp.scene.visible or main.ui.modals.save_select_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
if main.ui.modals.camp.esc_overlay.visible or main.ui.modals.camp.scene.visible or main.ui.modals.menu.save_select_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
_problems.append("[esc] 返回主菜单动线失守(浮窗自收/营地隐/选档收/菜单显)〔ESC批 V3〕〔ESC批 B3〕")
|
||||
# 非营地语境(boot 菜单)Esc→无响应(契约 9④ 回归面)
|
||||
_push_esc()
|
||||
|
||||
+20
-20
@@ -52,9 +52,9 @@ func _ready() -> void:
|
||||
var top_rx := -1
|
||||
var top_ry := -1
|
||||
for c: Node in [main.ui.screens.start_overlay, main.ui.screens.battle_root, main.ui.screens.inter_overlay,
|
||||
main.ui.modals.legend_overlay, main.ui.modals.node_overlay, main.ui.modals.level_screen, main.ui.modals.curio_overlay,
|
||||
main.ui.modals.end_overlay, main.ui.modals.shop_overlay, main.ui.modals.camp.scene, main.ui.modals.settings_overlay,
|
||||
main.ui.modals.status_panel, main.ui.modals.career_overlay, main.ui.modals.confirm_dialog, main.ui.modals.debug_overlay]:
|
||||
main.ui.modals.run.legend_overlay, main.ui.modals.run.node_overlay, main.ui.modals.run.level_screen, main.ui.modals.run.curio_overlay,
|
||||
main.ui.modals.run.end_overlay, main.ui.modals.menu.shop_overlay, main.ui.modals.camp.scene, main.ui.modals.menu.settings_overlay,
|
||||
main.ui.modals.run.status_panel, main.ui.modals.menu.career_overlay, main.ui.modals.menu.confirm_dialog, main.ui.modals.menu.debug_overlay]:
|
||||
if c == null or not (c is CanvasItem) or not (c as CanvasItem).visible:
|
||||
continue
|
||||
var rx: int = c.get_parent().get_index()
|
||||
@@ -89,12 +89,12 @@ func _ready() -> void:
|
||||
setbtn.pressed.emit()
|
||||
for i in 3:
|
||||
await get_tree().process_frame
|
||||
if not main.ui.modals.settings_overlay.visible:
|
||||
if not main.ui.modals.menu.settings_overlay.visible:
|
||||
_problems.append("设置面未打开(settingsbtn 路径)")
|
||||
else:
|
||||
_meta["settings_title"] = ProbeUiUtil.label_rect(main.ui.modals.settings_overlay, "设置")
|
||||
_meta["settings_title"] = ProbeUiUtil.label_rect(main.ui.modals.menu.settings_overlay, "设置")
|
||||
await _snap("settings")
|
||||
var set_close: Button = ProbeUiUtil.find_button(main.ui.modals.settings_overlay, "返回", "prefix")
|
||||
var set_close: Button = ProbeUiUtil.find_button(main.ui.modals.menu.settings_overlay, "返回", "prefix")
|
||||
if set_close == null:
|
||||
_problems.append("设置面返回钮缺失")
|
||||
else:
|
||||
@@ -105,19 +105,19 @@ func _ready() -> void:
|
||||
main._open_career()
|
||||
for i in 3:
|
||||
await get_tree().process_frame
|
||||
if not main.ui.modals.career_overlay.visible or main.ui.screens.start_overlay.visible:
|
||||
if not main.ui.modals.menu.career_overlay.visible or main.ui.screens.start_overlay.visible:
|
||||
_problems.append("生涯页未打开或开始层未隐藏(函数直调中间态路径)")
|
||||
else:
|
||||
_meta["career_title"] = ProbeUiUtil.label_rect(main.ui.modals.career_overlay, "生 涯")
|
||||
_meta["career_title"] = ProbeUiUtil.label_rect(main.ui.modals.menu.career_overlay, "生 涯")
|
||||
await _snap("career")
|
||||
var career_close: Button = ProbeUiUtil.find_button(main.ui.modals.career_overlay, "返回", "prefix")
|
||||
var career_close: Button = ProbeUiUtil.find_button(main.ui.modals.menu.career_overlay, "返回", "prefix")
|
||||
if career_close == null:
|
||||
_problems.append("生涯页返回钮缺失")
|
||||
else:
|
||||
career_close.pressed.emit()
|
||||
for i in 3:
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.career_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
if main.ui.modals.menu.career_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
_problems.append("生涯页关闭后页未隐藏或开始层未恢复")
|
||||
# ② 营地场景图(进档开层新路径——卡② mn9;截图=可点击场景图形态——卡④ 契约 9 V1 验收载体)
|
||||
if not ProbeUiUtil.open_camp_via_savesel(main, "smoke_shot_probe_camp"):
|
||||
@@ -127,7 +127,7 @@ func _ready() -> void:
|
||||
await _snap("camp")
|
||||
main.ui.modals.camp.scene.object_pressed.emit(&"campfire") # 收闭改接篝火动线(营地根态无关闭钮——卡④ T5)
|
||||
await get_tree().process_frame
|
||||
main.ui.modals.confirm_dialog.confirmed.emit() # 二次确认离场(关层收闭——选档层随收)
|
||||
main.ui.modals.menu.confirm_dialog.confirmed.emit() # 二次确认离场(关层收闭——选档层随收)
|
||||
await get_tree().process_frame
|
||||
# ③ 关卡画面(开始冒险→停点出图——入口停点语义;函数直调中间态 mn10)
|
||||
main._start_adventure_from_menu()
|
||||
@@ -135,16 +135,16 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
await _snap("level")
|
||||
# GP 常驻徽章断言(读数=runner.gp 现值,刷新=写路径回执后重查〔open_choices〕)
|
||||
var gp_label: Label = ProbeUiUtil.find_label(main.ui.modals.level_screen, "◈ ")
|
||||
var gp_label: Label = ProbeUiUtil.find_label(main.ui.modals.run.level_screen, "◈ ")
|
||||
if gp_label == null or not gp_label.is_visible_in_tree():
|
||||
_problems.append("GP 徽章不可见(关卡画面顶栏)")
|
||||
elif main.ui.modals.level_screen.get("_runner") != null:
|
||||
var expect := "◈ %d" % int(main.ui.modals.level_screen.get("_runner").gp)
|
||||
elif main.ui.modals.run.level_screen.get("_runner") != null:
|
||||
var expect := "◈ %d" % int(main.ui.modals.run.level_screen.get("_runner").gp)
|
||||
if gp_label.text != expect:
|
||||
_problems.append("GP 徽章读数不符: %s != %s" % [gp_label.text, expect])
|
||||
# ④ 战斗(节点一——真实选路提交路径 press_candidate,ui_click_probe :199 同款)
|
||||
if main.ui.modals.level_screen != null and main.ui.modals.level_screen.visible:
|
||||
main.ui.modals.level_screen.press_candidate(0)
|
||||
if main.ui.modals.run.level_screen != null and main.ui.modals.run.level_screen.visible:
|
||||
main.ui.modals.run.level_screen.press_candidate(0)
|
||||
for i in 10:
|
||||
await get_tree().process_frame
|
||||
await _snap("battle")
|
||||
@@ -167,18 +167,18 @@ func _ready() -> void:
|
||||
pb.pressed.emit()
|
||||
for i in 3:
|
||||
await get_tree().process_frame
|
||||
if not main.ui.modals.status_panel.visible:
|
||||
if not main.ui.modals.run.status_panel.visible:
|
||||
_problems.append("状态面板未打开(角标路径)")
|
||||
else:
|
||||
_meta["status_title"] = ProbeUiUtil.label_rect(main.ui.modals.status_panel, "状态")
|
||||
_meta["status_title"] = ProbeUiUtil.label_rect(main.ui.modals.run.status_panel, "状态")
|
||||
await _snap("status")
|
||||
var status_close: Button = ProbeUiUtil.find_button(main.ui.modals.status_panel, "继续", "prefix")
|
||||
var status_close: Button = ProbeUiUtil.find_button(main.ui.modals.run.status_panel, "继续", "prefix")
|
||||
if status_close == null:
|
||||
_problems.append("状态面板继续钮缺失")
|
||||
else:
|
||||
status_close.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.status_panel.visible:
|
||||
if main.ui.modals.run.status_panel.visible:
|
||||
_problems.append("状态面板关闭后未隐藏(继续钮路径)")
|
||||
else:
|
||||
_problems.append("关卡画面未出现(函数直调中间态路径)")
|
||||
|
||||
@@ -29,14 +29,14 @@ func _ready() -> void:
|
||||
main._start_adventure_from_menu() # 函数直调中间态(卡② mn10——开始冒险钮已撤)
|
||||
for i in 60:
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.level_screen != null and main.ui.modals.level_screen.visible:
|
||||
if main.ui.modals.run.level_screen != null and main.ui.modals.run.level_screen.visible:
|
||||
break
|
||||
if main.ui.modals.level_screen == null or not main.ui.modals.level_screen.visible:
|
||||
if main.ui.modals.run.level_screen == null or not main.ui.modals.run.level_screen.visible:
|
||||
_fail("关卡画面未出现")
|
||||
return
|
||||
for i in 5:
|
||||
await get_tree().process_frame
|
||||
main.ui.modals.level_screen.press_candidate(0)
|
||||
main.ui.modals.run.level_screen.press_candidate(0)
|
||||
for i in 20:
|
||||
await get_tree().process_frame
|
||||
if main.run_scope.settlement == null:
|
||||
@@ -69,16 +69,16 @@ func _ready() -> void:
|
||||
var t_settle := Time.get_ticks_msec()
|
||||
var _rows_at_victory: int = main.ui.screens.row_pacer.pending_rows().size() # 时间戳①:结算入队完成帧(AP 耗尽/停手→五行段同步跑完→行全在队)
|
||||
# 断言①胜利同帧:终局面未开 + 挂起在案 + 队列非空(判别性——旧行为同帧开窗即红)
|
||||
if main.ui.modals.end_overlay.is_open():
|
||||
if main.ui.modals.run.end_overlay.is_open():
|
||||
_problems.append("胜利同帧终局面已开(演播后排窗失效——同帧 flush 旧路径回潮)")
|
||||
if main.ui.modals.flow._deferred == null:
|
||||
if main.ui.flow._deferred == null:
|
||||
_problems.append("胜利同帧挂起态缺失(_deferred_modal == null)")
|
||||
if main.ui.screens.row_pacer.pending_rows().is_empty():
|
||||
_problems.append("胜利同帧排播队列已空(结算行未走排播链)")
|
||||
var _played_rows: int = _rows_at_victory
|
||||
# 断言②排播放完:终局面开启(20s 守卫——0.22s×行数 ×10 余量)
|
||||
var waited := 0.0
|
||||
while not main.ui.modals.end_overlay.is_open() and waited < 20.0:
|
||||
while not main.ui.modals.run.end_overlay.is_open() and waited < 20.0:
|
||||
await get_tree().process_frame
|
||||
waited += get_process_delta_time()
|
||||
var t_popup := Time.get_ticks_msec()
|
||||
@@ -86,7 +86,7 @@ func _ready() -> void:
|
||||
print("[t17_defer] AP点用完: %s" % ap_clock)
|
||||
print("[t17_defer] 触发结算: %s(与 AP 用完同帧——核心同步,相差 0ms)" % settle_clock)
|
||||
print("[t17_defer] 弹窗出现: %s(距触发结算 %d ms = 逐行演播时长,行数 %d)" % [popup_clock, t_popup - t_ap_out, _played_rows])
|
||||
if not main.ui.modals.end_overlay.is_open():
|
||||
if not main.ui.modals.run.end_overlay.is_open():
|
||||
_problems.append("排播放完后终局面未开(%.1fs——演播完边沿派发失守)" % waited)
|
||||
if _problems.is_empty():
|
||||
print("[t17_defer] PASS — 胜利同帧挂起+排播完开窗 两断言全过(waited=%.1fs)" % waited)
|
||||
|
||||
+118
-118
@@ -51,7 +51,7 @@ func _ready() -> void:
|
||||
var t_ui_ready := Time.get_ticks_msec() - t0
|
||||
# 调试浮窗 boot 不开(菜单优先——入口=UI 最顶层全局浮层角标,
|
||||
# 任何 UI 不遮挡;浮层角标遮挡判据见设置面段)
|
||||
if main.ui.modals.debug_overlay.visible:
|
||||
if main.ui.modals.menu.debug_overlay.visible:
|
||||
_problems.append("调试浮窗 boot 自动开(菜单优先失守)")
|
||||
# ---- 营地购买合成点击路径(选档进档开层→购买→关闭全走真实按钮信号路径;
|
||||
# 隔离存档换注 main.meta 保确定性(禁碰真实档 user://save.json);陈旧档段首清理)----
|
||||
@@ -204,11 +204,11 @@ func _ready() -> void:
|
||||
f_c2.close() # 槽2 有档异值(进档链夹具);槽1/3 空
|
||||
main._open_save_select()
|
||||
await get_tree().process_frame
|
||||
if not main.ui.modals.save_select_overlay.visible:
|
||||
if not main.ui.modals.menu.save_select_overlay.visible:
|
||||
_problems.append("[savesel] 选档层未打开(click 段前置)")
|
||||
# sl12 动线序(新档链同拍采样):逐帧可见性次序——首帧选档隐藏时营地层必须已可见、开始层保持隐藏
|
||||
#(禁先关后开——_close_modal 会恢复开始层=回闪一帧)
|
||||
var new_btn: Button = main.ui.modals.save_select_overlay._new_btns.get(1)
|
||||
var new_btn: Button = main.ui.modals.menu.save_select_overlay._new_btns.get(1)
|
||||
if new_btn == null:
|
||||
_problems.append("[savesel] 槽1 新档钮缺失(sl5/sl12 驱动中断)")
|
||||
else:
|
||||
@@ -216,7 +216,7 @@ func _ready() -> void:
|
||||
new_btn.pressed.emit() # 真实按钮信号路径 → _on_save_select_new → create_slot+open_camp
|
||||
for fi in 3:
|
||||
await get_tree().process_frame
|
||||
samples.append([main.ui.modals.save_select_overlay.visible, main.ui.modals.camp.scene.visible, main.ui.screens.start_overlay.visible])
|
||||
samples.append([main.ui.modals.menu.save_select_overlay.visible, main.ui.modals.camp.scene.visible, main.ui.screens.start_overlay.visible])
|
||||
if samples[0][0]:
|
||||
_problems.append("[savesel] sl12 新档后选档层仍可见(落点开层未发生)")
|
||||
elif not samples[0][1]:
|
||||
@@ -225,8 +225,8 @@ func _ready() -> void:
|
||||
_problems.append("[savesel] sl12 动线序违约:开始层在落点帧恢复(回闪一帧)")
|
||||
if main.save_manager.slots.active_slot() != 1 or not FileAccess.file_exists(csel_tpl % 1):
|
||||
_problems.append("[savesel] sl5 新档链失守(active=%d 应=1 且槽1 白板应落盘)" % main.save_manager.slots.active_slot())
|
||||
var occluded: Array = main.ui.modals.flow.stack._occluded.get(main.ui.modals.camp.scene, [])
|
||||
if not occluded.has(main.ui.modals.save_select_overlay):
|
||||
var occluded: Array = main.ui.flow.stack._occluded.get(main.ui.modals.camp.scene, [])
|
||||
if not occluded.has(main.ui.modals.menu.save_select_overlay):
|
||||
_problems.append("[savesel] sl12 选档层被关闭而非栈记账挂起(先关后开形态——遮挡挂起中间态钉死)")
|
||||
if int((JSON.parse_string(FileAccess.get_file_as_string(csel_tpl % 1)) as Dictionary).get("meta", {}).get("keystone_balance", -1)) != 0:
|
||||
_problems.append("[savesel] sl5 新档非白板(槽1 落盘应全零)")
|
||||
@@ -235,7 +235,7 @@ func _ready() -> void:
|
||||
# sl6 进档链:槽2 进档 → 激活=2(camp 数据随激活槽)
|
||||
main._open_save_select()
|
||||
await get_tree().process_frame
|
||||
var load_btn: Button = main.ui.modals.save_select_overlay._load_btns.get(2)
|
||||
var load_btn: Button = main.ui.modals.menu.save_select_overlay._load_btns.get(2)
|
||||
if load_btn == null:
|
||||
_problems.append("[savesel] 槽2 进档钮缺失(sl6 驱动中断——夹具应有档)")
|
||||
else:
|
||||
@@ -243,51 +243,51 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
if main.save_manager.slots.active_slot() != 2:
|
||||
_problems.append("[savesel] sl6 进档链失守(active=%d 应=2——激活该槽)" % main.save_manager.slots.active_slot())
|
||||
if not main.ui.modals.camp.scene.visible or main.ui.modals.save_select_overlay.visible:
|
||||
if not main.ui.modals.camp.scene.visible or main.ui.modals.menu.save_select_overlay.visible:
|
||||
_problems.append("[savesel] sl6 落点未开营地层或选档未隐藏")
|
||||
main._on_camp_closed()
|
||||
await get_tree().process_frame
|
||||
# sl7 删档二次确认双路径:一击只开窗(文件仍在)→取消只关窗(文件仍在)→再开窗确认才删(槽回空)
|
||||
main._open_save_select()
|
||||
await get_tree().process_frame
|
||||
var del_btn: Button = main.ui.modals.save_select_overlay._delete_btns.get(2)
|
||||
var del_btn: Button = main.ui.modals.menu.save_select_overlay._delete_btns.get(2)
|
||||
if del_btn == null:
|
||||
_problems.append("[savesel] 槽2 删档钮缺失(sl7 驱动中断)")
|
||||
else:
|
||||
del_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if not main.ui.modals.confirm_dialog.is_open():
|
||||
if not main.ui.modals.menu.confirm_dialog.is_open():
|
||||
_problems.append("[savesel] sl7 一击未只开确认窗(直删形态)")
|
||||
elif not FileAccess.file_exists(csel_tpl % 2):
|
||||
_problems.append("[savesel] sl7 确认前文件已被删(一次点击即删违契)")
|
||||
else:
|
||||
if not main.ui.modals.flow.stack._occluded.has(main.ui.modals.confirm_dialog):
|
||||
if not main.ui.flow.stack._occluded.has(main.ui.modals.menu.confirm_dialog):
|
||||
_problems.append("[savesel] sl7 确认窗未经模态栈开(直开旁路——wr2 单口失守)")
|
||||
elif not main.ui.modals.flow.locks_input():
|
||||
elif not main.ui.flow.locks_input():
|
||||
_problems.append("[savesel] sl7 确认窗开时输入锁未生效(锁域失守——wr2)")
|
||||
main.ui.modals.confirm_dialog.cancelled.emit() # 取消路径(真实信号——cancelled 钮同源)
|
||||
main.ui.modals.menu.confirm_dialog.cancelled.emit() # 取消路径(真实信号——cancelled 钮同源)
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.confirm_dialog.is_open() or not FileAccess.file_exists(csel_tpl % 2):
|
||||
if main.ui.modals.menu.confirm_dialog.is_open() or not FileAccess.file_exists(csel_tpl % 2):
|
||||
_problems.append("[savesel] sl7 取消路径失守(应只关窗、文件仍在)")
|
||||
elif main._confirm_consumer != "":
|
||||
_problems.append("[savesel] sl8 取消后消费方状态量未清(分派面残留)")
|
||||
if main.ui.modals.flow.stack._occluded.has(main.ui.modals.confirm_dialog):
|
||||
if main.ui.flow.stack._occluded.has(main.ui.modals.menu.confirm_dialog):
|
||||
_problems.append("[savesel] sl7 取消后确认窗遮挡账未清(关侧未走模态栈——wr2)")
|
||||
del_btn.pressed.emit() # 再开窗走确认路径
|
||||
await get_tree().process_frame
|
||||
main.ui.modals.confirm_dialog.confirmed.emit() # 确认路径(真实信号——confirmed 钮同源)
|
||||
main.ui.modals.menu.confirm_dialog.confirmed.emit() # 确认路径(真实信号——confirmed 钮同源)
|
||||
await get_tree().process_frame
|
||||
if FileAccess.file_exists(csel_tpl % 2) or main.ui.modals.confirm_dialog.is_open():
|
||||
if FileAccess.file_exists(csel_tpl % 2) or main.ui.modals.menu.confirm_dialog.is_open():
|
||||
_problems.append("[savesel] sl7 确认路径失守(应删档+关窗)")
|
||||
elif main.run_scope.is_adventure or main.ui.screens.start_overlay.visible:
|
||||
_problems.append("[savesel] sl8 删档确认误触发开局(双常驻接线形态——分派单口失守)")
|
||||
elif bool(main.ui.modals.save_select_overlay._occupied_flags.get(2, true)):
|
||||
elif bool(main.ui.modals.menu.save_select_overlay._occupied_flags.get(2, true)):
|
||||
_problems.append("[savesel] sl7 删后选档面未就地刷新(槽2 应回空态)")
|
||||
elif main._confirm_consumer != "":
|
||||
_problems.append("[savesel] sl8 确认后消费方状态量未清(分派面残留)")
|
||||
main._on_save_select_closed()
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.save_select_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
if main.ui.modals.menu.save_select_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
_problems.append("[savesel] 关闭后层未隐藏或开始层未恢复(模态栈单口失守)")
|
||||
|
||||
# ---- 设置面段(隔离 store 换注禁碰真实 user://settings.cfg;真实按钮信号路径)----
|
||||
@@ -297,19 +297,19 @@ func _ready() -> void:
|
||||
var iso_s = load("res://presentation/settings_store.gd").new("user://smoke_click_probe_settings.cfg")
|
||||
iso_s.load_settings()
|
||||
main.settings_store = iso_s
|
||||
main.ui.modals.settings_overlay.retarget(iso_s)
|
||||
main.ui.modals.menu.settings_overlay.retarget(iso_s)
|
||||
var settings_btn: Button = ProbeUiUtil.find_button(main.ui.screens.start_overlay, "设置", "prefix")
|
||||
if settings_btn == null:
|
||||
_problems.append("设置入口按钮缺失(开始层 settingsbtn)")
|
||||
else:
|
||||
settings_btn.pressed.emit() # 真实按钮信号路径 → _open_settings
|
||||
await get_tree().process_frame
|
||||
if not main.ui.modals.settings_overlay.visible or main.ui.screens.start_overlay.visible:
|
||||
if not main.ui.modals.menu.settings_overlay.visible or main.ui.screens.start_overlay.visible:
|
||||
_problems.append("设置面未打开(点击路径)")
|
||||
else:
|
||||
# 减动效转正双态(卡④ AC③)——M4 适配:拨杆开关(_motion_btn)语义翻转 on=完整/off=快速,
|
||||
# 状态字随行 _motion_st;查找由文字改成员引用(拨杆无文字)
|
||||
var motion_btn: Button = main.ui.modals.settings_overlay._motion_btn
|
||||
var motion_btn: Button = main.ui.modals.menu.settings_overlay._motion_btn
|
||||
if motion_btn == null:
|
||||
_problems.append("设置面减动效开关缺失")
|
||||
else:
|
||||
@@ -326,7 +326,7 @@ func _ready() -> void:
|
||||
if UiKit.motion_scale != 1.0:
|
||||
_problems.append("减动效关未恢复(motion_scale != 1.0)")
|
||||
# 音量实时生效(卡④ AC①):滑杆 30% → master bus db 与 store 双读
|
||||
var vol: HSlider = main.ui.modals.settings_overlay._volume
|
||||
var vol: HSlider = main.ui.modals.menu.settings_overlay._volume
|
||||
vol.value = 30
|
||||
await get_tree().process_frame
|
||||
var master_idx := AudioServer.get_bus_index("Master")
|
||||
@@ -339,22 +339,22 @@ func _ready() -> void:
|
||||
# 回归语义随调试浮层发布态退役,申报见迭代 38 实现报告 §8.2)
|
||||
if main.ui.screens.debug_badge == null or main.ui.screens.debug_badge.visible:
|
||||
_problems.append("设置面开中调试角标可见(发布态恒隐失守)")
|
||||
var settings_close: Button = ProbeUiUtil.find_button(main.ui.modals.settings_overlay, "返回", "prefix")
|
||||
var settings_close: Button = ProbeUiUtil.find_button(main.ui.modals.menu.settings_overlay, "返回", "prefix")
|
||||
if settings_close == null:
|
||||
_problems.append("设置面返回按钮缺失")
|
||||
else:
|
||||
settings_close.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.settings_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
if main.ui.modals.menu.settings_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
_problems.append("设置面关闭后未恢复开始层")
|
||||
# 旧入口零残留断言(卡④ AC③——测试调整板不含减动效开关;14.5 起载体=调试浮窗)
|
||||
var legacy_motion = ProbeUiUtil.find_check_button(main.ui.modals.debug_overlay, "减动效")
|
||||
var legacy_motion = ProbeUiUtil.find_check_button(main.ui.modals.menu.debug_overlay, "减动效")
|
||||
if legacy_motion != null:
|
||||
_problems.append("调整板减动效旧入口未退役(设置面唯一入口失守——卡④ AC③)")
|
||||
# D1 断言(二轮):退出游戏只在一级菜单——开始菜单有、设置面无
|
||||
if ProbeUiUtil.find_button(main.ui.screens.start_overlay, "退出游戏", "prefix") == null:
|
||||
_problems.append("开始菜单缺退出游戏按钮(二轮 D1)")
|
||||
if ProbeUiUtil.find_button(main.ui.modals.settings_overlay, "退出游戏", "prefix") != null:
|
||||
if ProbeUiUtil.find_button(main.ui.modals.menu.settings_overlay, "退出游戏", "prefix") != null:
|
||||
_problems.append("设置面仍含退出游戏按钮(二轮 D1——只在一级菜单出现)")
|
||||
# ---- 生涯页段(入口点击链+关闭回返,真实按钮信号路径;本页只读零写,
|
||||
# 值断言归冒烟投影段与 ui_struct 结构族,此处只验开合路径与零跳转)----
|
||||
@@ -362,29 +362,29 @@ func _ready() -> void:
|
||||
if true:
|
||||
main._open_career()
|
||||
await get_tree().process_frame
|
||||
if not main.ui.modals.career_overlay.visible or main.ui.screens.start_overlay.visible:
|
||||
if not main.ui.modals.menu.career_overlay.visible or main.ui.screens.start_overlay.visible:
|
||||
_problems.append("生涯页未打开(点击路径)")
|
||||
else:
|
||||
# 零跳转契约(提纲 P4 甲):页内除「返回」外零导航钮
|
||||
for nav in ["营地", "商店", "设置", "退出", "冒险"]:
|
||||
if ProbeUiUtil.find_button(main.ui.modals.career_overlay, nav, "contains") != null:
|
||||
if ProbeUiUtil.find_button(main.ui.modals.menu.career_overlay, nav, "contains") != null:
|
||||
_problems.append("生涯页内出现导航入口「%s」(零跳转违约——生涯纯只读)" % nav)
|
||||
# 局内入口断言(提纲 P4 甲):生涯入口只在开始层——战斗屏/地图屏零生涯角标
|
||||
if main.ui.battle.board_zone.find_child("career_badge", true, false) != null \
|
||||
or main.ui.modals.level_screen.find_child("career_badge", true, false) != null:
|
||||
or main.ui.modals.run.level_screen.find_child("career_badge", true, false) != null:
|
||||
_problems.append("局内屏出现生涯入口件(局内不放生涯入口违约)")
|
||||
var career_close: Button = ProbeUiUtil.find_button(main.ui.modals.career_overlay, "返回", "prefix")
|
||||
var career_close: Button = ProbeUiUtil.find_button(main.ui.modals.menu.career_overlay, "返回", "prefix")
|
||||
if career_close == null:
|
||||
_problems.append("生涯页返回按钮缺失")
|
||||
else:
|
||||
career_close.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.career_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
if main.ui.modals.menu.career_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
_problems.append("生涯页关闭后未恢复开始层")
|
||||
# 换回全新零档(营地购买态不泄入后续冒险段——确定性;档案残留下次段首清理兜底)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_click_probe_reset", true, false, true) # 零档换注(继续上局钮已随三入口化撤出——卡② mn8)
|
||||
main.ui.modals.debug_overlay.set_sliders(400, 200) # 高加成保 L1 可完成——L2 岔路选路段只能经冒险推进到达(单关直入口退役)
|
||||
main.ui.modals.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机,行为走查确定性禁依赖默认分支)
|
||||
main.ui.modals.menu.debug_overlay.set_sliders(400, 200) # 高加成保 L1 可完成——L2 岔路选路段只能经冒险推进到达(单关直入口退役)
|
||||
main.ui.modals.menu.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机,行为走查确定性禁依赖默认分支)
|
||||
var t1 := Time.get_ticks_msec()
|
||||
main._start_adventure_from_menu()
|
||||
await get_tree().process_frame
|
||||
@@ -396,11 +396,11 @@ func _ready() -> void:
|
||||
_problems.append("开场行回归失守:局外加成(pct>0)局的开场行应带「(含面板加成)」(wc3)")
|
||||
# 关卡开始 = 入口选路停点——press_candidate 图上命中路径选入口候选进首战
|
||||
#(首格可点 AC 口径随之含入口选路一步:菜单点击 → 停点呈现 → pick → 棋盘安装)
|
||||
if main.ui.modals.level_screen.visible:
|
||||
if main.ui.modals.run.level_screen.visible:
|
||||
# 独立性断言:独立屏激活期战斗屏宿主整体隐藏
|
||||
if main.ui.screens.battle_root.visible:
|
||||
_problems.append("独立屏激活期战斗屏宿主未隐藏(零透出契约失守)")
|
||||
main.ui.modals.level_screen.press_candidate(0)
|
||||
main.ui.modals.run.level_screen.press_candidate(0)
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
var t_entry := Time.get_ticks_msec() - t1
|
||||
@@ -421,21 +421,21 @@ func _ready() -> void:
|
||||
while not _done and action_budget > 0:
|
||||
action_budget -= 1
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.node_overlay.visible:
|
||||
main.ui.modals.node_overlay.press_continue()
|
||||
if main.ui.modals.run.node_overlay.visible:
|
||||
main.ui.modals.run.node_overlay.press_continue()
|
||||
_seals_placed.clear()
|
||||
continue
|
||||
if main.ui.modals.curio_overlay.visible:
|
||||
if main.ui.modals.run.curio_overlay.visible:
|
||||
# 三选一停点(CurioPickOverlay——奖励节点/关卡完成兑付共用面,须与硬锁态适配,
|
||||
# 未适配则走到即卡死)。两态分派:result 态(兑付反馈——点继续推进)/
|
||||
# 待选态(点首件+确认)。真实信号路径全线。〔无替换子态——装配不可变契约。〕
|
||||
# 三选一停点输入锁定断言(停点态断言面:待选/兑付两态共用此层)。
|
||||
if not _tested_curio_head and main.run_scope.adventure != null and not main.run_scope.adventure.stop()._node_pending.is_empty() and String(main.ui.modals.curio_overlay._header).contains("关卡奖励点"):
|
||||
if not _tested_curio_head and main.run_scope.adventure != null and not main.run_scope.adventure.stop()._node_pending.is_empty() and String(main.ui.modals.run.curio_overlay._header).contains("关卡奖励点"):
|
||||
# 停点态判据 = _node_curio_pending(奖励节点三选一停点住此——原条件查
|
||||
# _curio_pending〔关卡完成三选一态〕与奖励头部互斥、恒不可命中=拦截能力未证病根,
|
||||
# 卡⑤ d4 转正随修;头部校验串本体零触碰)
|
||||
_tested_curio_head = true
|
||||
var ch := String(main.ui.modals.curio_overlay._header)
|
||||
var ch := String(main.ui.modals.run.curio_overlay._header)
|
||||
if not ch.contains("冒险牌库") or not ch.contains("属性值提升与补给") or ch.contains("同权重") or ch.contains("同上限") or ch.contains("提升池"):
|
||||
_problems.append("三选一头部旧话残留或新话缺失(wa4——%s)" % ch.replace("
|
||||
", "|"))
|
||||
@@ -444,45 +444,45 @@ func _ready() -> void:
|
||||
var logtext: String = main.ui.battle.log_view.parsed_text()
|
||||
if not logtext.contains("关卡奖励点(三选一——选毕推进)") or logtext.contains("内容待定"):
|
||||
_problems.append("奖励节点战报文案未换代(卡⑤ wr2——旧话残留或新话缺失)")
|
||||
if not main.ui.modals.flow.locks_input():
|
||||
if not main.ui.flow.locks_input():
|
||||
_problems.append("三选一停点打开时输入未锁定")
|
||||
if main.ui.modals.curio_overlay._continue_btn.visible:
|
||||
main.ui.modals.curio_overlay.press_continue()
|
||||
if main.ui.modals.run.curio_overlay._continue_btn.visible:
|
||||
main.ui.modals.run.curio_overlay.press_continue()
|
||||
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._node_pending.is_empty():
|
||||
main.ui.modals.curio_overlay.press_card(0) # 奖励节点待选态:点首件+确认(真实按钮信号路径——与关卡完成停点同形)
|
||||
main.ui.modals.curio_overlay.press_confirm()
|
||||
main.ui.modals.run.curio_overlay.press_card(0) # 奖励节点待选态:点首件+确认(真实按钮信号路径——与关卡完成停点同形)
|
||||
main.ui.modals.run.curio_overlay.press_confirm()
|
||||
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._pending.is_empty():
|
||||
main.ui.modals.curio_overlay.press_card(0)
|
||||
main.ui.modals.curio_overlay.press_confirm()
|
||||
main.ui.modals.run.curio_overlay.press_card(0)
|
||||
main.ui.modals.run.curio_overlay.press_confirm()
|
||||
else:
|
||||
main.ui.modals.curio_overlay.press_continue() # 停点已消费的残面——继续关屏
|
||||
main.ui.modals.run.curio_overlay.press_continue() # 停点已消费的残面——继续关屏
|
||||
_seals_placed.clear()
|
||||
continue
|
||||
if main.ui.modals.shop_overlay.visible:
|
||||
if main.ui.modals.menu.shop_overlay.visible:
|
||||
# 商店房覆盖层(摆放约束:每终点前一位恰一店,真实路径恒必经一店):零购离开(真实 leave 信号路径)放行选路。
|
||||
# 分派链序:商店层=选路页上的模态覆盖(停点呈现为
|
||||
# level_screen+shop 双 visible)——必须先于 level_screen 分派,否则下层候选点击
|
||||
# 空转烧尽预算(实证:lv2 商店停点双 visible 循环 12000 帧 done=false)。
|
||||
main.ui.modals.shop_overlay.leave_pressed.emit()
|
||||
main.ui.modals.menu.shop_overlay.leave_pressed.emit()
|
||||
_seals_placed.clear()
|
||||
continue
|
||||
if main.ui.modals.level_screen.visible:
|
||||
if main.ui.modals.run.level_screen.visible:
|
||||
# 节点图选路口(零自动推进停点)——图上命中路径交替选候选(岔路使用行为;布局决策 2 改造)
|
||||
# 地图屏角标一次性 case:选路前经角标开/关状态面板(层在地图屏之上开合,
|
||||
# 关闭后地图屏选路态零扰动——P2 甲层级语义)
|
||||
if not _tested_map_status and not main.ui.modals.status_panel.visible:
|
||||
if not _tested_map_status and not main.ui.modals.run.status_panel.visible:
|
||||
_tested_map_status = true
|
||||
var mpb: Button = main.ui.modals.level_screen.status_badge
|
||||
var mpb: Button = main.ui.modals.run.level_screen.status_badge
|
||||
if mpb == null or not mpb.visible or mpb.disabled:
|
||||
_problems.append("地图屏状态角标缺失/未点亮/被置灰(P1 丁)")
|
||||
else:
|
||||
mpb.pressed.emit()
|
||||
if not main.ui.modals.status_panel.visible or not main.ui.modals.level_screen.visible:
|
||||
if not main.ui.modals.run.status_panel.visible or not main.ui.modals.run.level_screen.visible:
|
||||
_problems.append("地图屏角标开状态面板失败或地图屏被误藏(P2 甲层级失守)")
|
||||
var rbtn2: Button = ProbeUiUtil.find_button(main.ui.modals.status_panel, "继续", "prefix")
|
||||
var rbtn2: Button = ProbeUiUtil.find_button(main.ui.modals.run.status_panel, "继续", "prefix")
|
||||
if rbtn2 != null:
|
||||
rbtn2.pressed.emit()
|
||||
if main.ui.modals.status_panel.visible or not main.ui.modals.level_screen.visible:
|
||||
if main.ui.modals.run.status_panel.visible or not main.ui.modals.run.level_screen.visible:
|
||||
_problems.append("状态面板关闭后地图屏态失守(恢复语义破)")
|
||||
# 地图屏加成帽换代断言(迭代36 卡A wa2——「特性」→「属性值提升」;帽 Label 常在树;
|
||||
# 独立旗标——_tested_map_status 在同拍前置块已置位,禁复用其门控)
|
||||
@@ -490,7 +490,7 @@ func _ready() -> void:
|
||||
_tested_map_cap = true
|
||||
var cap_found := false
|
||||
var ls_labels: Array = []
|
||||
_collect_labels_by_text(main.ui.modals.level_screen, ls_labels)
|
||||
_collect_labels_by_text(main.ui.modals.run.level_screen, ls_labels)
|
||||
for l in ls_labels:
|
||||
if l.text == "属性值提升":
|
||||
cap_found = true
|
||||
@@ -502,16 +502,16 @@ func _ready() -> void:
|
||||
if main.run_scope.runner != null:
|
||||
for nd in main.run_scope.runner.nodes():
|
||||
var nd_id: int = main.run_scope.runner.node_id_of(nd)
|
||||
if String(nd.get("type", "")) == "reward" and main.ui.modals.level_screen._cand_ids.has(nd_id):
|
||||
pick = main.ui.modals.level_screen._cand_ids.find(nd_id)
|
||||
if String(nd.get("type", "")) == "reward" and main.ui.modals.run.level_screen._cand_ids.has(nd_id):
|
||||
pick = main.ui.modals.run.level_screen._cand_ids.find(nd_id)
|
||||
break
|
||||
main.ui.modals.level_screen.press_candidate(pick)
|
||||
main.ui.modals.run.level_screen.press_candidate(pick)
|
||||
_route_clicks += 1
|
||||
_seals_placed.clear()
|
||||
continue
|
||||
if main.ui.screens.inter_overlay.visible:
|
||||
# 大奖励屏(冒险级停点——非末关的关卡完成恰一次):首见确认推进 L2(真实按钮信号路径);再见 = L2 已关卡完成,收口
|
||||
if not main.ui.modals.flow.locks_input():
|
||||
if not main.ui.flow.locks_input():
|
||||
_problems.append("大奖励屏打开时输入未锁定")
|
||||
_inter_confirms += 1
|
||||
if _inter_confirms == 1:
|
||||
@@ -530,23 +530,23 @@ func _ready() -> void:
|
||||
break
|
||||
_seals_placed.clear()
|
||||
continue
|
||||
if main.ui.modals.end_overlay.is_open() and main.run_scope.settlement_stop_timer.is_armed():
|
||||
if main.ui.modals.run.end_overlay.is_open() and main.run_scope.settlement_stop_timer.is_armed():
|
||||
# 战斗胜利总结结算框(真实信号路径——每场普通胜利到达):断言已拍板面后点「下一节点」
|
||||
if not main.ui.modals.flow.locks_input():
|
||||
if not main.ui.flow.locks_input():
|
||||
_problems.append("胜利结算框打开时输入未锁定")
|
||||
var gp_line: String = "%s %s" % [main.ui.modals.end_overlay._gp_name.text, main.ui.modals.end_overlay._gp_val.text] # 两列账行(审计差距④)——名/值列拼回整串断言
|
||||
var gp_line: String = "%s %s" % [main.ui.modals.run.end_overlay._gp_name.text, main.ui.modals.run.end_overlay._gp_val.text] # 两列账行(审计差距④)——名/值列拼回整串断言
|
||||
if not gp_line.contains("GP +%d" % main.run_scope.last_gain_amount) or not gp_line.contains("合计 %d" % int(main.run_scope.runner.gp)):
|
||||
_problems.append("胜利结算框 GP 增量/总量与钱包实态不符(%s|实态 +%d/%d)" % [gp_line, main.run_scope.last_gain_amount, int(main.run_scope.runner.gp)])
|
||||
if main.ui.modals.end_overlay.verdict_text() == "":
|
||||
if main.ui.modals.run.end_overlay.verdict_text() == "":
|
||||
_problems.append("胜利结算框判定行缺失")
|
||||
_settlement_confirms += 1
|
||||
main.ui.modals.end_overlay._btn.pressed.emit() # 「下一节点」真实信号路径
|
||||
main.ui.modals.run.end_overlay._btn.pressed.emit() # 「下一节点」真实信号路径
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
if main.run_scope.settlement_stop_timer.is_armed() or not main.ui.modals.level_screen.visible:
|
||||
if main.run_scope.settlement_stop_timer.is_armed() or not main.ui.modals.run.level_screen.visible:
|
||||
_problems.append("胜利结算框「下一节点」未进选路页(卡⑥ AC②)")
|
||||
continue
|
||||
if main.ui.modals.end_overlay.is_open():
|
||||
if main.ui.modals.run.end_overlay.is_open():
|
||||
# 冒险终局(失败/放弃/打穿)——无单关直入口,见终局即收口(模态断言照旧)
|
||||
# 三选一链适配:_adventure_mode 仍真且非选路挂起=中途结算面(Boss 胜利
|
||||
# 总结「继续」后挂三选一→真终局未到)——真实信号路径点继续推进。
|
||||
@@ -555,13 +555,13 @@ func _ready() -> void:
|
||||
# (_adventure_mode)在真终局仍 true——会把真终局当中途面点掉返回键(实证)。
|
||||
var _adv_running: bool = main.run_scope.adventure != null and String(main.run_scope.adventure.state) == "running"
|
||||
if main.run_scope.is_adventure and _adv_running:
|
||||
main.ui.modals.end_overlay._btn.pressed.emit()
|
||||
main.ui.modals.run.end_overlay._btn.pressed.emit()
|
||||
continue
|
||||
if not main.ui.modals.flow.locks_input():
|
||||
if not main.ui.flow.locks_input():
|
||||
_problems.append("终局 overlay 打开时输入未锁定")
|
||||
_done = true
|
||||
print("[click_probe] 冒险终局:%s · 选路口点击 %d 次" % [
|
||||
main.ui.modals.end_overlay.verdict_text().replace("\n", " "), _route_clicks])
|
||||
main.ui.modals.run.end_overlay.verdict_text().replace("\n", " "), _route_clicks])
|
||||
break
|
||||
if main.run_scope.settlement == null or main.run_scope.runner == null:
|
||||
continue
|
||||
@@ -603,36 +603,36 @@ func _ready() -> void:
|
||||
# ---- 预算耗尽收口(T17 硬锁批适配):选件变强后 probe 可能活过预算不再战败——断点段前提
|
||||
# (冒险终局面在案)须主动满足。收口驱动:任何停点层逐个推进(复用主循环分支语义)至
|
||||
# level_screen 选路停点→真实放弃二击→终局面。战斗中则继续 autoplay 打完。
|
||||
if not _done and not main.ui.modals.end_overlay.is_open():
|
||||
if not _done and not main.ui.modals.run.end_overlay.is_open():
|
||||
var close_guard := 8000
|
||||
var dbg_frame := 0 # T17 演播后排窗:每场胜利 +~400 帧演播等待(旧同帧 flush 零等待)——守卫按多场战斗放大
|
||||
while close_guard > 0:
|
||||
close_guard -= 1
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.end_overlay.is_open():
|
||||
if main.ui.modals.run.end_overlay.is_open():
|
||||
# 中途结算面(state=running)=点继续推进;真终局(settling)=断点段前提满足,收口。
|
||||
if main.run_scope.is_adventure and main.run_scope.adventure != null and String(main.run_scope.adventure.state) == "running":
|
||||
main.ui.modals.end_overlay._btn.pressed.emit()
|
||||
main.ui.modals.run.end_overlay._btn.pressed.emit()
|
||||
else:
|
||||
break
|
||||
elif main.ui.modals.curio_overlay.visible:
|
||||
if main.ui.modals.curio_overlay._continue_btn.visible:
|
||||
main.ui.modals.curio_overlay.press_continue()
|
||||
elif main.ui.modals.run.curio_overlay.visible:
|
||||
if main.ui.modals.run.curio_overlay._continue_btn.visible:
|
||||
main.ui.modals.run.curio_overlay.press_continue()
|
||||
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._pending.is_empty():
|
||||
main.ui.modals.curio_overlay.press_card(0)
|
||||
main.ui.modals.curio_overlay.press_confirm()
|
||||
main.ui.modals.run.curio_overlay.press_card(0)
|
||||
main.ui.modals.run.curio_overlay.press_confirm()
|
||||
else:
|
||||
main.ui.modals.curio_overlay.press_continue()
|
||||
elif main.ui.modals.node_overlay.visible:
|
||||
main.ui.modals.node_overlay.press_continue()
|
||||
elif main.ui.modals.shop_overlay.visible:
|
||||
main.ui.modals.shop_overlay.leave_pressed.emit()
|
||||
main.ui.modals.run.curio_overlay.press_continue()
|
||||
elif main.ui.modals.run.node_overlay.visible:
|
||||
main.ui.modals.run.node_overlay.press_continue()
|
||||
elif main.ui.modals.menu.shop_overlay.visible:
|
||||
main.ui.modals.menu.shop_overlay.leave_pressed.emit()
|
||||
elif main.ui.screens.inter_overlay.visible:
|
||||
var next_btn2: Button = ProbeUiUtil.find_button(main.ui.screens.inter_overlay, "进入下一层", "prefix")
|
||||
if next_btn2 != null:
|
||||
next_btn2.pressed.emit()
|
||||
elif main.ui.modals.level_screen.visible:
|
||||
var abandon_btn: Button = ProbeUiUtil.find_button(main.ui.modals.level_screen, "放弃", "prefix")
|
||||
elif main.ui.modals.run.level_screen.visible:
|
||||
var abandon_btn: Button = ProbeUiUtil.find_button(main.ui.modals.run.level_screen, "放弃", "prefix")
|
||||
if abandon_btn != null:
|
||||
_closed_via_abandon = true
|
||||
abandon_btn.pressed.emit()
|
||||
@@ -660,12 +660,12 @@ func _ready() -> void:
|
||||
str(((bpf as Dictionary).get("bonus_deck", []) as Array).size()),
|
||||
str((bpf as Dictionary).get("bonus_pending"))])
|
||||
_problems.append("断点段:战败结算后断点未清(T3 三结局清断点失守)")
|
||||
if not main.ui.modals.end_overlay.is_open():
|
||||
if not main.ui.modals.run.end_overlay.is_open():
|
||||
_problems.append("断点段:战败后未出冒险终局面")
|
||||
if main.ui.modals.end_overlay._btn == null:
|
||||
if main.ui.modals.run.end_overlay._btn == null:
|
||||
_problems.append("断点段:终局面返回按钮缺失")
|
||||
else:
|
||||
main.ui.modals.end_overlay._btn.pressed.emit() # 真实按钮信号路径(_btn=继续/返回共用句柄)
|
||||
main.ui.modals.run.end_overlay._btn.pressed.emit() # 真实按钮信号路径(_btn=继续/返回共用句柄)
|
||||
await get_tree().process_frame
|
||||
if not main.ui.screens.start_overlay.visible:
|
||||
# 豁免:放弃路径收口时终局「返回」后仍挂三选一/关卡推进残留态(停点链),
|
||||
@@ -687,19 +687,19 @@ func _ready() -> void:
|
||||
var bal_gate: int = main._camp_data()["balance"]
|
||||
main.ui.modals.camp.scene.object_pressed.emit(&"gate")
|
||||
await get_tree().process_frame
|
||||
if not main.ui.modals.confirm_dialog.is_open():
|
||||
if not main.ui.modals.menu.confirm_dialog.is_open():
|
||||
_problems.append("大门无断点:确认弹窗未开(点大门应先出确认不直接进冒险)〔营地图批 V3〕")
|
||||
if main.run_scope.is_adventure:
|
||||
_problems.append("大门无断点:未确认即进冒险〔营地图批 V3〕")
|
||||
if main.ui.modals.confirm_dialog._secondary_btn.visible:
|
||||
if main.ui.modals.menu.confirm_dialog._secondary_btn.visible:
|
||||
_problems.append("大门无断点:次钮应隐藏(两出口形态)〔营地图批 V3〕")
|
||||
main.ui.modals.confirm_dialog.cancelled.emit()
|
||||
main.ui.modals.menu.confirm_dialog.cancelled.emit()
|
||||
await get_tree().process_frame
|
||||
if not main.ui.modals.camp.scene.visible or main.run_scope.is_adventure or main._camp_data()["balance"] != bal_gate:
|
||||
_problems.append("大门取消:未无变更退回营地(写口零调用/营地根 visible 失守)〔营地图批 V3〕")
|
||||
main.ui.modals.camp.scene.object_pressed.emit(&"gate")
|
||||
await get_tree().process_frame
|
||||
main.ui.modals.confirm_dialog.confirmed.emit() # 「是」→开始新冒险
|
||||
main.ui.modals.menu.confirm_dialog.confirmed.emit() # 「是」→开始新冒险
|
||||
await get_tree().process_frame
|
||||
if not main.run_scope.is_adventure or main.ui.modals.camp.scene.visible:
|
||||
_problems.append("大门确认:冒险未发起或营地场景屏未隐藏〔营地图批 V3〕〔营地图批 B1〕")
|
||||
@@ -714,9 +714,9 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
main.ui.modals.camp.scene.object_pressed.emit(&"gate")
|
||||
await get_tree().process_frame
|
||||
if not main.ui.modals.confirm_dialog.is_open() or not main.ui.modals.confirm_dialog._secondary_btn.visible:
|
||||
if not main.ui.modals.menu.confirm_dialog.is_open() or not main.ui.modals.menu.confirm_dialog._secondary_btn.visible:
|
||||
_problems.append("大门有断点:三出口形态失守(次钮应现形)〔营地图批 V3〕")
|
||||
main.ui.modals.confirm_dialog.secondary_confirmed.emit() # 「开始新冒险」出口
|
||||
main.ui.modals.menu.confirm_dialog.secondary_confirmed.emit() # 「开始新冒险」出口
|
||||
await get_tree().process_frame
|
||||
if not main.run_scope.is_adventure or main.ui.modals.camp.scene.visible:
|
||||
_problems.append("大门有断点次确认:冒险未发起或营地未隐藏〔营地图批 V3〕")
|
||||
@@ -736,8 +736,8 @@ func _ready() -> void:
|
||||
if FileAccess.file_exists(p_ol):
|
||||
DirAccess.remove_absolute(p_ol)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_click_probe_openline", true, false, true)
|
||||
main.ui.modals.debug_overlay.reset_sliders() # ① 白板反向前提(_start_adventure 只关窗不清值——残值跨段存活防坑)
|
||||
main.ui.modals.debug_overlay.seed_edit.text = "42"
|
||||
main.ui.modals.menu.debug_overlay.reset_sliders() # ① 白板反向前提(_start_adventure 只关窗不清值——残值跨段存活防坑)
|
||||
main.ui.modals.menu.debug_overlay.seed_edit.text = "42"
|
||||
main._start_adventure_from_menu()
|
||||
var ol_l1_wait := 0
|
||||
while ol_l1_wait < 24 and String(main.ui.battle.log_view._log.get_parsed_text()).count("· 种子 ") < 1:
|
||||
@@ -822,14 +822,14 @@ func _run_modal_probes_once() -> void:
|
||||
if not _tested_legend:
|
||||
_tested_legend = true
|
||||
main.ui.battle.board_zone.ap_bar._btn_legend.pressed.emit()
|
||||
if not main.ui.modals.legend_overlay.is_open():
|
||||
if not main.ui.modals.run.legend_overlay.is_open():
|
||||
_problems.append("图例打开失败")
|
||||
if main.ui.modals.end_overlay.is_open() or main.ui.screens.start_overlay.visible:
|
||||
if main.ui.modals.run.end_overlay.is_open() or main.ui.screens.start_overlay.visible:
|
||||
_problems.append("图例打开时上方遮挡层未隐藏(缺陷⑤复发)")
|
||||
if not main.ui.modals.flow.locks_input():
|
||||
if not main.ui.flow.locks_input():
|
||||
_problems.append("图例打开时棋盘输入未锁定")
|
||||
var legend_has_seal := false
|
||||
for e in main.ui.modals.legend_overlay.ENTRIES:
|
||||
for e in main.ui.modals.run.legend_overlay.ENTRIES:
|
||||
if String(e[1]) == "封印":
|
||||
legend_has_seal = true
|
||||
# 图例封印行换代断言(迭代36 卡A wa5——真实 AP 条图例钮开层路径)
|
||||
@@ -838,13 +838,13 @@ func _run_modal_probes_once() -> void:
|
||||
", "|"))
|
||||
if not legend_has_seal:
|
||||
_problems.append("图例缺『封印』格态条目(格态图例基线)")
|
||||
main.ui.modals.legend_overlay.close()
|
||||
if main.ui.modals.legend_overlay.is_open() or main.ui.modals.flow.locks_input():
|
||||
main.ui.modals.run.legend_overlay.close()
|
||||
if main.ui.modals.run.legend_overlay.is_open() or main.ui.flow.locks_input():
|
||||
_problems.append("图例关闭后未恢复输入/可见性")
|
||||
# ②/②b 明细回看模态无探针(M9/P-C7——冒险中回看归「生涯」,06 登记)
|
||||
# ⑤ 状态面板(P1 丁角标真实信号路径 + P2 甲模态语义 + P1 守卫 + R3 锁恢复):
|
||||
# 角标打开 → 只读层可见+输入锁定+余额徽非空 → 「继续」关闭恢复;图例开着 → 角标置灰且点击被守卫兜住
|
||||
if not _tested_status and not main.ui.modals.legend_overlay.is_open() and not main.ui.modals.status_panel.visible:
|
||||
if not _tested_status and not main.ui.modals.run.legend_overlay.is_open() and not main.ui.modals.run.status_panel.visible:
|
||||
_tested_status = true
|
||||
var pbtn: Button = main.ui.battle.board_zone.status_badge
|
||||
if pbtn == null or not pbtn.visible or pbtn.disabled:
|
||||
@@ -852,17 +852,17 @@ func _run_modal_probes_once() -> void:
|
||||
% [str(pbtn != null and pbtn.visible), str(pbtn != null and pbtn.disabled)])
|
||||
else:
|
||||
pbtn.pressed.emit() # 真实按钮信号路径 → 组合根 _on_status_badge_pressed
|
||||
if not main.ui.modals.status_panel.visible:
|
||||
if not main.ui.modals.run.status_panel.visible:
|
||||
_problems.append("状态面板未随角标打开(组合根接线失守)")
|
||||
if not main.ui.modals.flow.locks_input():
|
||||
if not main.ui.flow.locks_input():
|
||||
_problems.append("状态面板打开时输入未锁定(R3)")
|
||||
var bal_txt: String = main.ui.modals.status_panel._balance_badge.value_label.text
|
||||
var bal_txt: String = main.ui.modals.run.status_panel._balance_badge.value_label.text
|
||||
if not bal_txt.begins_with("钥石 "):
|
||||
_problems.append("状态面板余额徽投影缺失(%s)" % bal_txt)
|
||||
# ---- 本局信息面板换代断言(迭代36 卡③——真实入口三断言)----
|
||||
# ① 面板子树零旧段文案(跨关概览退役零残留)
|
||||
var sv_labels: Array = []
|
||||
_collect_labels_by_text(main.ui.modals.status_panel, sv_labels)
|
||||
_collect_labels_by_text(main.ui.modals.run.status_panel, sv_labels)
|
||||
for l in sv_labels:
|
||||
if String(l.text).contains("道具工坊") or String(l.text).contains("天赋树"):
|
||||
_problems.append("状态面板子树残留旧段文案「%s」(sv6①——零旧段失守)" % String(l.text))
|
||||
@@ -874,8 +874,8 @@ func _run_modal_probes_once() -> void:
|
||||
var attr_expect := "生命 %d/%d · 攻击 %d · 护甲 AC %d · GP %d" % [
|
||||
int(rnr.hero_hp), rnr.effective_max_hp(), rnr.effective_atk(),
|
||||
rnr.effective_ac(), int(rnr.gp)]
|
||||
if String(main.ui.modals.status_panel._attrs_label.text) != attr_expect:
|
||||
_problems.append("状态面板属性行投影失真(sv6②——期望 %s 实测 %s)" % [attr_expect, main.ui.modals.status_panel._attrs_label.text])
|
||||
if String(main.ui.modals.run.status_panel._attrs_label.text) != attr_expect:
|
||||
_problems.append("状态面板属性行投影失真(sv6②——期望 %s 实测 %s)" % [attr_expect, main.ui.modals.run.status_panel._attrs_label.text])
|
||||
# ③ _status_data() 直调对拍(sv7——键集恰八键+curios/feats 独立 oracle)
|
||||
var sd: Dictionary = main._status_data()
|
||||
var keys := ["balance", "hero_hp", "max_hp", "atk", "ac", "gp", "curios", "feats"]
|
||||
@@ -899,22 +899,22 @@ func _run_modal_probes_once() -> void:
|
||||
var feats_expect: Array = load("res://presentation/hud_presenter.gd").feat_holdings_lines(main.db, rnr.feats_held())
|
||||
if str((sd as Dictionary).get("feats", [])) != str(feats_expect):
|
||||
_problems.append("_status_data().feats 对拍 feat_holdings_lines 失守(sv7)")
|
||||
var resume_btn: Button = ProbeUiUtil.find_button(main.ui.modals.status_panel, "继续", "prefix")
|
||||
var resume_btn: Button = ProbeUiUtil.find_button(main.ui.modals.run.status_panel, "继续", "prefix")
|
||||
if resume_btn == null:
|
||||
_problems.append("状态面板关闭钮缺失(「继续」)")
|
||||
else:
|
||||
resume_btn.pressed.emit()
|
||||
if main.ui.modals.status_panel.visible or main.ui.modals.flow.locks_input():
|
||||
if main.ui.modals.run.status_panel.visible or main.ui.flow.locks_input():
|
||||
_problems.append("状态面板关闭后未恢复(visible=%s locked=%s——R3 残留)"
|
||||
% [str(main.ui.modals.status_panel.visible), str(main.ui.modals.flow.locks_input())])
|
||||
% [str(main.ui.modals.run.status_panel.visible), str(main.ui.flow.locks_input())])
|
||||
# P1 守卫:图例开着 → 两处入口角标置灰;置灰态点击被处理器兜住(探针 emit 绕过 disabled)
|
||||
main.ui.battle.board_zone.ap_bar._btn_legend.pressed.emit()
|
||||
if not main.ui.battle.board_zone.status_badge.disabled:
|
||||
_problems.append("图例开着时战斗屏状态角标未置灰(P1 守卫失守)")
|
||||
main.ui.battle.board_zone.status_badge.pressed.emit()
|
||||
if main.ui.modals.status_panel.visible:
|
||||
if main.ui.modals.run.status_panel.visible:
|
||||
_problems.append("置灰态仍可开状态面板(守卫兜底失守)")
|
||||
main.ui.modals.legend_overlay.close()
|
||||
main.ui.modals.run.legend_overlay.close()
|
||||
# ③ tooltip(状态效果槽悬停——来源+语义+剩余):有槽可见时触发
|
||||
if not _tested_tooltip:
|
||||
var row = main.ui.battle.stage.hero_standee.slot_row # 状态 tooltip 载体(B 区站桩)
|
||||
@@ -1045,7 +1045,7 @@ func _locktest_tick() -> void:
|
||||
if settlement == null or settlement.minesweeper.current_board() == null:
|
||||
return
|
||||
if _locktest_state == 0:
|
||||
if main.ui.screens.row_pacer.pending_rows().is_empty() or main.ui.modals.flow.locks_input():
|
||||
if main.ui.screens.row_pacer.pending_rows().is_empty() or main.ui.flow.locks_input():
|
||||
return
|
||||
if String(settlement.battle_result) != "" or String(settlement.action_economy.phase) != "Active":
|
||||
return
|
||||
@@ -1067,7 +1067,7 @@ func _locktest_tick() -> void:
|
||||
return
|
||||
_locktest_state = 1
|
||||
elif _locktest_state == 1:
|
||||
if main.ui.modals.curio_overlay.visible or main.ui.screens.inter_overlay.visible or main.ui.modals.end_overlay.is_open() \
|
||||
if main.ui.modals.run.curio_overlay.visible or main.ui.screens.inter_overlay.visible or main.ui.modals.run.end_overlay.is_open() \
|
||||
or String(settlement.battle_result) != "":
|
||||
_locktest_state = 2 # 前提消失守卫:终结演播竞态——静默弃测
|
||||
return
|
||||
|
||||
@@ -31,15 +31,15 @@ func _ready() -> void:
|
||||
# 同 ui_click_probe 隔离纪律。首次冒险布尔位置位=对齐真实档游玩史口径,模板抽签路径不变;
|
||||
# isolate_save 先删后建——上次运行的残留断点会触发互斥确认早退)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_input_probe_save", true, false, true)
|
||||
main.ui.modals.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机,探针确定性禁依赖默认分支)
|
||||
main.ui.modals.menu.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机,探针确定性禁依赖默认分支)
|
||||
main._start_adventure_from_menu()
|
||||
await get_tree().process_frame
|
||||
# ---- ⑫ 图上命中真实输入(回归闸):入口停点候选节点中心
|
||||
# push_input 真实鼠标路径 motion+click → 悬停预承诺置位 → route_chosen 到达组合根。
|
||||
# 由来=真机 bug:深层节点(L1 Boss 内容 x=802)在固定画布命中区外,press_candidate 直调
|
||||
# 命中函数探针全绿、真鼠标点不中——本 case 封住输入管线,⑬封住几何拟合。
|
||||
if main.ui.modals.level_screen.visible:
|
||||
var ro = main.ui.modals.level_screen
|
||||
if main.ui.modals.run.level_screen.visible:
|
||||
var ro = main.ui.modals.run.level_screen
|
||||
var cands: Array = main.run_scope.runner.next_candidate_ids()
|
||||
# ---- ⑱ 信息迷雾呈现接线(回归闸):真机 display_probe 读实际绘制记录(雾下节点类型未画、
|
||||
# Boss 描边画了、候选类型画了)+点击雾下非候选节点零提交(雾不扩大可点域——候选集即合法集)----
|
||||
@@ -90,9 +90,9 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
ro.route_chosen.disconnect(on_route)
|
||||
if not submitted.is_empty() or not main.ui.modals.level_screen.visible or not main.run_scope.runner.awaiting_choice():
|
||||
if not submitted.is_empty() or not main.ui.modals.run.level_screen.visible or not main.run_scope.runner.awaiting_choice():
|
||||
_pre_fail("case⑱ 雾下节点点击产生提交(提交=%s visible=%s 选路态=%s——雾不扩大可点域)〔fv9〕"
|
||||
% [str(submitted), str(main.ui.modals.level_screen.visible), str(main.run_scope.runner.awaiting_choice())])
|
||||
% [str(submitted), str(main.ui.modals.run.level_screen.visible), str(main.run_scope.runner.awaiting_choice())])
|
||||
return
|
||||
var nds: Array = main.run_scope.runner.nodes()
|
||||
var tgt := {}
|
||||
@@ -116,13 +116,13 @@ func _ready() -> void:
|
||||
main.get_viewport().push_input(evc, true)
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.level_screen.visible or main.run_scope.runner.awaiting_choice():
|
||||
_pre_fail("图上真实点击未提交选路(overlay 可见=%s 选路态=%s)" % [str(main.ui.modals.level_screen.visible), str(main.run_scope.runner.awaiting_choice())])
|
||||
if main.ui.modals.run.level_screen.visible or main.run_scope.runner.awaiting_choice():
|
||||
_pre_fail("图上真实点击未提交选路(overlay 可见=%s 选路态=%s)" % [str(main.ui.modals.run.level_screen.visible), str(main.run_scope.runner.awaiting_choice())])
|
||||
for i in range(3):
|
||||
await get_tree().process_frame
|
||||
# ---- ⑬ 画布随图拟合(同 bug 的几何面回归):复刻分层公式独立推导最深节点内容 x,
|
||||
# 断言画布 min 尺寸覆盖之(open_choices 每 stop 拟合——L1 单链 Boss x=70+6*122=802 曾越界)
|
||||
var ro2 = main.ui.modals.level_screen
|
||||
var ro2 = main.ui.modals.run.level_screen
|
||||
var nds2: Array = main.run_scope.runner.nodes()
|
||||
var layer2 := {}
|
||||
var inbound2 := {}
|
||||
@@ -522,24 +522,24 @@ func _ready() -> void:
|
||||
_push_click(bpos, MOUSE_BUTTON_LEFT)
|
||||
_push_release(bpos, MOUSE_BUTTON_LEFT) # Button pressed 信号走 release 沿——按压+释放成对
|
||||
await get_tree().process_frame
|
||||
if not main.ui.modals.status_panel.visible or not main.ui.modals.flow.locks_input():
|
||||
if not main.ui.modals.run.status_panel.visible or not main.ui.flow.locks_input():
|
||||
_problems.append("case⑯ 角标真点击未开状态面板(visible=%s locked=%s——入口可达性失守)"
|
||||
% [str(main.ui.modals.status_panel.visible), str(main.ui.modals.flow.locks_input())])
|
||||
% [str(main.ui.modals.run.status_panel.visible), str(main.ui.flow.locks_input())])
|
||||
else:
|
||||
_push_click(_pos(bv, status_dig), MOUSE_BUTTON_LEFT)
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
if _has_action(status_dig, "dig") or ms.is_revealed(status_dig):
|
||||
_problems.append("case⑯ 状态面板开启时挖掘穿透(R3 输入锁破——目标=%s)" % status_dig)
|
||||
var resume_btn: Button = ProbeUiUtil.find_button(main.ui.modals.status_panel, "继续", "prefix")
|
||||
var resume_btn: Button = ProbeUiUtil.find_button(main.ui.modals.run.status_panel, "继续", "prefix")
|
||||
if resume_btn == null:
|
||||
_problems.append("case⑯ 状态面板关闭钮缺失")
|
||||
else:
|
||||
resume_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.status_panel.visible or main.ui.modals.flow.locks_input():
|
||||
if main.ui.modals.run.status_panel.visible or main.ui.flow.locks_input():
|
||||
_problems.append("case⑯ 关闭后未恢复(visible=%s locked=%s——R3 残留)"
|
||||
% [str(main.ui.modals.status_panel.visible), str(main.ui.modals.flow.locks_input())])
|
||||
% [str(main.ui.modals.run.status_panel.visible), str(main.ui.flow.locks_input())])
|
||||
_push_click(_pos(bv, status_dig), MOUSE_BUTTON_LEFT)
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
|
||||
+12
-12
@@ -16,7 +16,7 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
var problems: Array = []
|
||||
# ---- 放弃入口(台账 119):默认隐藏(非冒险模式无冒险可放弃——开始层/调试两层)----
|
||||
if main.ui.modals.level_screen.abandon_btn == null or main.ui.modals.level_screen.abandon_btn.visible:
|
||||
if main.ui.modals.run.level_screen.abandon_btn == null or main.ui.modals.run.level_screen.abandon_btn.visible:
|
||||
print("[ui_probe] FAIL — 放弃按钮默认应隐藏(非冒险模式关)")
|
||||
get_tree().quit(1)
|
||||
return
|
||||
@@ -65,14 +65,14 @@ func _ready() -> void:
|
||||
problems.append("营地关闭后未恢复开始层(开合往返失守)〔句柄子容器批 V1〕")
|
||||
# 换回全新零档(营地段购买态不泄入后续冒险段——确定性;先删后建防陈旧档泄入)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_ui_probe_camp", true, false, true)
|
||||
main.ui.modals.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机;本探针 start_single 第五路同吃此框,确定性禁依赖默认分支)
|
||||
main.ui.modals.menu.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机;本探针 start_single 第五路同吃此框,确定性禁依赖默认分支)
|
||||
main._start_adventure_from_menu()
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
# ---- 入口选路停点(关卡开始即出节点图——level_started 后、首战前弹选路层;
|
||||
# press_candidate 图上命中路径 pick 入口单候选进首战)----
|
||||
# ---- 独立性断言(独立屏激活期战斗屏宿主整体隐藏,零透出)----
|
||||
if not main.ui.modals.level_screen.visible:
|
||||
if not main.ui.modals.run.level_screen.visible:
|
||||
problems.append("关卡开始未弹入口选路停点(level_screen 应可见)")
|
||||
elif main.ui.screens.battle_root.visible:
|
||||
problems.append("独立屏激活期战斗屏宿主未隐藏(零透出契约失守)")
|
||||
@@ -80,16 +80,16 @@ func _ready() -> void:
|
||||
or main.run_scope.runner.next_candidate_ids().size() != 1:
|
||||
problems.append("入口停点状态失守(选路态 + 入口单候选)")
|
||||
else:
|
||||
main.ui.modals.level_screen.press_candidate(0)
|
||||
main.ui.modals.run.level_screen.press_candidate(0)
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
if not main.ui.screens.battle_root.visible or main.ui.modals.level_screen.visible:
|
||||
if not main.ui.screens.battle_root.visible or main.ui.modals.run.level_screen.visible:
|
||||
problems.append("选路提交战斗节点后未切回战斗屏(屏级互斥恢复失守)")
|
||||
# ---- 放弃入口·冒险模式可见 + 战斗中按下被拒(真实按钮路径——入口挂选路停点,战斗中拒绝为防御分支)----
|
||||
if main.ui.modals.level_screen.abandon_btn == null or not main.ui.modals.level_screen.abandon_btn.visible:
|
||||
if main.ui.modals.run.level_screen.abandon_btn == null or not main.ui.modals.run.level_screen.abandon_btn.visible:
|
||||
problems.append("冒险模式放弃按钮未开放(选路停点入口在案)")
|
||||
else:
|
||||
main.ui.modals.level_screen.abandon_btn.pressed.emit()
|
||||
main.ui.modals.run.level_screen.abandon_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if main.run_scope.adventure == null or String(main.run_scope.adventure.state) != "running":
|
||||
problems.append("首战中放弃未被拒(战斗域单事务在飞——state 应保持 running)")
|
||||
@@ -233,12 +233,12 @@ func _ready() -> void:
|
||||
main._on_adventure_finished({"result": "completed", "cleared": true, "levels_cleared": 3,
|
||||
"stopped_at": 0, "keystone_total": 30, "master_seed": 42, "gp_final": 57})
|
||||
main.meta.save = meta_saved
|
||||
if not main.ui.modals.end_overlay.is_open():
|
||||
if not main.ui.modals.run.end_overlay.is_open():
|
||||
problems.append("冒险终局面板未开(合成摘要路径)")
|
||||
elif not main.ui.modals.end_overlay._gp_row.visible or not main.ui.modals.end_overlay._gp_val.text.contains("57"):
|
||||
problems.append("终局面板 GP 行缺失或取数不对(%s)" % main.ui.modals.end_overlay._gp_val.text)
|
||||
main.ui.modals.end_overlay.close()
|
||||
main.ui.modals.flow.close(main.ui.modals.end_overlay)
|
||||
elif not main.ui.modals.run.end_overlay._gp_row.visible or not main.ui.modals.run.end_overlay._gp_val.text.contains("57"):
|
||||
problems.append("终局面板 GP 行缺失或取数不对(%s)" % main.ui.modals.run.end_overlay._gp_val.text)
|
||||
main.ui.modals.run.end_overlay.close()
|
||||
main.ui.flow.close(main.ui.modals.run.end_overlay)
|
||||
if problems.is_empty():
|
||||
print("[ui_probe] PASS — cells=%d board=%dx%d hp='%s' enemies=%d ap_dots=%d" % [
|
||||
main.ui.battle.board_zone.board_view.cells_probe().size(), main.ui.battle.board_zone.board_view.board().width, main.ui.battle.board_zone.board_view.board().height,
|
||||
|
||||
@@ -34,7 +34,7 @@ func _ready() -> void:
|
||||
|
||||
main._open_settings()
|
||||
_settle()
|
||||
await _audit("settings", [main.ui.modals.settings_overlay])
|
||||
await _audit("settings", [main.ui.modals.menu.settings_overlay])
|
||||
main._on_settings_closed()
|
||||
_settle()
|
||||
|
||||
@@ -94,22 +94,22 @@ func _ready() -> void:
|
||||
_settle()
|
||||
main.ui.modals.camp.scene.object_pressed.emit(&"notebook")
|
||||
_settle()
|
||||
if not main.ui.modals.career_overlay.visible or main.ui.screens.start_overlay.visible:
|
||||
if not main.ui.modals.menu.career_overlay.visible or main.ui.screens.start_overlay.visible:
|
||||
problems.append("[career] 生涯页未打开或开始层未隐藏(笔记本改挂路径断裂)〔营地图批 V5〕")
|
||||
await _audit("career", [main.ui.modals.career_overlay])
|
||||
await _audit("career", [main.ui.modals.menu.career_overlay])
|
||||
_career_readonly_contract(main)
|
||||
_career_zero_motion_contract(main)
|
||||
_career_nojump_contract(main)
|
||||
main._on_career_closed()
|
||||
_settle()
|
||||
if main.ui.modals.career_overlay.visible or main.ui.screens.start_overlay.visible:
|
||||
if main.ui.modals.menu.career_overlay.visible or main.ui.screens.start_overlay.visible:
|
||||
problems.append("[career] 关闭后页未隐藏或开始层回弹(营地语境分支失守)〔营地图批 V5〕")
|
||||
# ---- Esc 浮窗结构段(卡⑤——三钮在位且仅三+零动效契约+登记序在册+debug_badge 不波及)----
|
||||
main._camp_pres.open_camp()
|
||||
_settle()
|
||||
main.ui.modals.camp.scene.object_pressed.emit(&"gate")
|
||||
_settle()
|
||||
main.ui.modals.confirm_dialog.cancelled.emit() # 关大门弹窗(清场——浮窗段前提)
|
||||
main.ui.modals.menu.confirm_dialog.cancelled.emit() # 关大门弹窗(清场——浮窗段前提)
|
||||
_settle()
|
||||
var push_esc := func() -> void:
|
||||
var ev := InputEventKey.new()
|
||||
@@ -175,37 +175,37 @@ func _ready() -> void:
|
||||
problems.append("[savesel] 开层前激活态非零(sl9 重启链——boot/注入面后应无激活)")
|
||||
main._open_save_select()
|
||||
_settle()
|
||||
if not main.ui.modals.save_select_overlay.visible or main.ui.screens.start_overlay.visible:
|
||||
if not main.ui.modals.menu.save_select_overlay.visible or main.ui.screens.start_overlay.visible:
|
||||
problems.append("[savesel] 选档层未打开或开始层未隐藏(开层函数断裂)")
|
||||
await _audit("savesel", [main.ui.modals.save_select_overlay])
|
||||
await _audit("savesel", [main.ui.modals.menu.save_select_overlay])
|
||||
_save_select_contract(main, ssel_tpl)
|
||||
main._on_save_select_closed()
|
||||
_settle()
|
||||
if main.ui.modals.save_select_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
if main.ui.modals.menu.save_select_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
problems.append("[savesel] 关闭后层未隐藏或开始层未恢复(模态栈单口失守)")
|
||||
|
||||
main.ui.modals.confirm_dialog.open("结构探针采样", "确认")
|
||||
main.ui.modals.menu.confirm_dialog.open("结构探针采样", "确认")
|
||||
_settle()
|
||||
await _audit("confirm", [main.ui.modals.confirm_dialog])
|
||||
main.ui.modals.confirm_dialog.close()
|
||||
await _audit("confirm", [main.ui.modals.menu.confirm_dialog])
|
||||
main.ui.modals.menu.confirm_dialog.close()
|
||||
_settle()
|
||||
|
||||
main._show_debug_overlay()
|
||||
_settle()
|
||||
await _audit("debug", [main.ui.modals.debug_overlay])
|
||||
await _audit("debug", [main.ui.modals.menu.debug_overlay])
|
||||
main._close_debug_overlay()
|
||||
_settle()
|
||||
|
||||
# ---- 冒险簇(真流推进:开冒险→地图选路态→选战斗节点→战斗 HUD)----
|
||||
ProbeUiUtil.isolate_save(main, "smoke_ui_struct_probe_adv", true, false, true)
|
||||
main.ui.modals.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机,结构采样确定性禁依赖默认分支)
|
||||
main.ui.modals.menu.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机,结构采样确定性禁依赖默认分支)
|
||||
main._start_adventure_from_menu()
|
||||
_settle(4)
|
||||
await _audit("level_map", [main.ui.modals.level_screen])
|
||||
await _audit("level_map", [main.ui.modals.run.level_screen])
|
||||
|
||||
var battle_id := _pick_battle_node(main)
|
||||
if battle_id >= 0:
|
||||
main.ui.modals.level_screen.route_chosen.emit(battle_id)
|
||||
main.ui.modals.run.level_screen.route_chosen.emit(battle_id)
|
||||
_settle(6)
|
||||
_audit("battle_hud", [main.ui.battle.board_zone, main.ui.battle.info_panel, main.ui.battle.stage])
|
||||
_standeefit_contract(main)
|
||||
@@ -215,12 +215,12 @@ func _ready() -> void:
|
||||
# 一律红,须先入册审查);白名单={视图自身 _emit_closed, 组合根 _on_status_closed}。
|
||||
main._open_status_panel()
|
||||
_settle()
|
||||
await _audit("status", [main.ui.modals.status_panel])
|
||||
await _audit("status", [main.ui.modals.run.status_panel])
|
||||
_status_readonly_contract(main)
|
||||
_status_zero_motion_contract(main)
|
||||
main._on_status_closed()
|
||||
_settle()
|
||||
if main.ui.modals.status_panel.visible:
|
||||
if main.ui.modals.run.status_panel.visible:
|
||||
problems.append("[status] 关闭后层未隐藏(模态栈单口失守)")
|
||||
|
||||
# ---- 图例层(旧模态、首过结构族):ap_bar legend_toggled
|
||||
@@ -228,61 +228,61 @@ func _ready() -> void:
|
||||
# closed 信号真路径关(close()→组合根 _on_modal_closed)。
|
||||
main.ui.battle.board_zone.legend_toggled.emit()
|
||||
_settle()
|
||||
if not main.ui.modals.legend_overlay.visible:
|
||||
if not main.ui.modals.run.legend_overlay.visible:
|
||||
problems.append("[legend] 图例层未打开(legend_toggled 路径中断)")
|
||||
await _audit("legend", [main.ui.modals.legend_overlay])
|
||||
main.ui.modals.legend_overlay.close()
|
||||
await _audit("legend", [main.ui.modals.run.legend_overlay])
|
||||
main.ui.modals.run.legend_overlay.close()
|
||||
_settle()
|
||||
if main.ui.modals.legend_overlay.visible:
|
||||
if main.ui.modals.run.legend_overlay.visible:
|
||||
problems.append("[legend] 关闭后层未隐藏(模态栈单口失守)")
|
||||
else:
|
||||
problems.append("[battle_hud] 候选中无战斗节点(驱动中断——候选=%s)" % str(main.ui.modals.level_screen._cand_ids))
|
||||
problems.append("[battle_hud] 候选中无战斗节点(驱动中断——候选=%s)" % str(main.ui.modals.run.level_screen._cand_ids))
|
||||
|
||||
# ---- 兑付屏(真实 open 面 + 合成最小数据——结构断言只看矩形/宽度/可见性)----
|
||||
main.ui.modals.end_overlay.open_victory("结构探针·胜利演算", "返回", Rect2(200, 200, 400, 300), {"gp_summary": "GP 0"})
|
||||
main.ui.modals.run.end_overlay.open_victory("结构探针·胜利演算", "返回", Rect2(200, 200, 400, 300), {"gp_summary": "GP 0"})
|
||||
_settle()
|
||||
await _audit("battle_end", [main.ui.modals.end_overlay])
|
||||
main.ui.modals.end_overlay.close()
|
||||
await _audit("battle_end", [main.ui.modals.run.end_overlay])
|
||||
main.ui.modals.run.end_overlay.close()
|
||||
_settle()
|
||||
|
||||
# ---- 节点结算层(旧模态、首过结构族):rest 兑付真路径开
|
||||
#(组合根 _open_modal 登记册+show_rest 合成喂入)→结构断言族→continue_pressed 信号真路径关
|
||||
#(press_continue→组合根 _on_node_continue→_close_modal)。
|
||||
main.ui.modals.flow.open(main.ui.modals.node_overlay)
|
||||
main.ui.modals.node_overlay.show_rest(3, 15, 20)
|
||||
main.ui.flow.open(main.ui.modals.run.node_overlay)
|
||||
main.ui.modals.run.node_overlay.show_rest(3, 15, 20)
|
||||
_settle()
|
||||
if not main.ui.modals.node_overlay.visible:
|
||||
if not main.ui.modals.run.node_overlay.visible:
|
||||
problems.append("[node] 节点结算层未打开(rest 兑付路径中断)")
|
||||
await _audit("node_overlay", [main.ui.modals.node_overlay])
|
||||
main.ui.modals.node_overlay.press_continue()
|
||||
await _audit("node_overlay", [main.ui.modals.run.node_overlay])
|
||||
main.ui.modals.run.node_overlay.press_continue()
|
||||
_settle()
|
||||
if main.ui.modals.node_overlay.visible:
|
||||
if main.ui.modals.run.node_overlay.visible:
|
||||
problems.append("[node] 关闭后层未隐藏(continue_pressed 路径中断)")
|
||||
|
||||
main.ui.modals.curio_overlay.open_pick("结构探针·三选一", [
|
||||
main.ui.modals.run.curio_overlay.open_pick("结构探针·三选一", [
|
||||
{"id": "probe_heal", "text": "回血\n恢复 3 点"},
|
||||
{"id": "probe_magic", "text": "爆裂轰击\n下一击 +5"},
|
||||
{"id": "probe_pierce", "text": "穿甲\n无视护甲"},
|
||||
])
|
||||
_settle()
|
||||
await _audit("curio_pick", [main.ui.modals.curio_overlay])
|
||||
main.ui.modals.curio_overlay.visible = false
|
||||
await _audit("curio_pick", [main.ui.modals.run.curio_overlay])
|
||||
main.ui.modals.run.curio_overlay.visible = false
|
||||
_settle()
|
||||
|
||||
main.ui.modals.shop_overlay.open_shop([
|
||||
main.ui.modals.menu.shop_overlay.open_shop([
|
||||
{"product_id": "probe_p1", "display_name": "探针商品甲", "attr": "atk", "flat_value": 1, "price": 10, "purchased": 0},
|
||||
{"product_id": "probe_p2", "display_name": "探针商品乙", "attr": "hp", "flat_value": 2, "price": 20, "purchased": 0},
|
||||
], 100)
|
||||
_settle()
|
||||
await _audit("shop", [main.ui.modals.shop_overlay])
|
||||
await _audit("shop", [main.ui.modals.menu.shop_overlay])
|
||||
|
||||
# ---- 术语传导:货架卡与三选一卡片的玩家面文案(物品名=专长获取、分类=专长凭证)
|
||||
main.ui.modals.shop_overlay.open_shelf([
|
||||
main.ui.modals.menu.shop_overlay.open_shelf([
|
||||
{"kind_id": "feat_ticket", "display_name": "专长获取", "value": 0, "price": 5},
|
||||
{"kind_id": "heal", "display_name": "应急回复", "value": 6, "price": 5},
|
||||
], 20)
|
||||
_settle()
|
||||
var ticket_row: Dictionary = main.ui.modals.shop_overlay._shelf_rows[0]
|
||||
var ticket_row: Dictionary = main.ui.modals.menu.shop_overlay._shelf_rows[0]
|
||||
if String(main.db.run.shop.pool_row("feat_ticket").get("display_name", "")) != "专长获取":
|
||||
problems.append("[shop_term] shop.tres 专长凭证件名未换代(现=%s)" % String(main.db.run.shop.pool_row("feat_ticket").get("display_name", "")))
|
||||
if ticket_row.card.name_l.text != "专长获取":
|
||||
@@ -293,7 +293,7 @@ func _ready() -> void:
|
||||
problems.append("[shop_term] 专长凭证件描述未用规范流程句(现=%s)" % ticket_row.card.desc_l.text)
|
||||
if ticket_row.card.foot_l.text != "专长凭证":
|
||||
problems.append("[shop_term] 专长凭证件分类标注未用「专长凭证」(现=%s)" % ticket_row.card.foot_l.text)
|
||||
var heal_row: Dictionary = main.ui.modals.shop_overlay._shelf_rows[1]
|
||||
var heal_row: Dictionary = main.ui.modals.menu.shop_overlay._shelf_rows[1]
|
||||
if heal_row.card.desc_l.text != "回复 +6(本冒险)":
|
||||
problems.append("[shop_term] 回复件描述漏了 heal 词表(现=%s)" % heal_row.card.desc_l.text)
|
||||
if heal_row.card.foot_l.text != "回复":
|
||||
@@ -305,7 +305,7 @@ func _ready() -> void:
|
||||
problems.append("[curio_term] 专长凭证三选一卡未用物品名/规范流程句(现=%s)" % ticket_text)
|
||||
if ticket_text.contains("门票") or ticket_text.contains("T5") or ticket_text.contains("持有集") or ticket_text.contains("奇物三选一"):
|
||||
problems.append("[curio_term] 专长凭证三选一卡残留退役词/内部任务号(现=%s)" % ticket_text)
|
||||
main.ui.modals.shop_overlay.visible = false
|
||||
main.ui.modals.menu.shop_overlay.visible = false
|
||||
_settle()
|
||||
|
||||
# ---- ⑦resume 专项:续玩停点恢复(main.gd:717 报错回归闸)----
|
||||
@@ -316,11 +316,11 @@ func _ready() -> void:
|
||||
main.run_scope.runner = null # 全新启动等价态(真机=菜单直进续玩,无前置冒险——runner 从未赋值;探针此前推流会残留旧 runner)
|
||||
main._resume_from_menu()
|
||||
_settle(8)
|
||||
if not main.ui.modals.end_overlay.visible:
|
||||
if not main.ui.modals.run.end_overlay.visible:
|
||||
problems.append("[resume] 续玩恢复后胜利总结面未开(三选一停点分支中断)")
|
||||
else:
|
||||
var found := {"ok": false}
|
||||
_find_label_text(main.ui.modals.end_overlay, "合计 24", found)
|
||||
_find_label_text(main.ui.modals.run.end_overlay, "合计 24", found)
|
||||
if not found.ok:
|
||||
problems.append("[resume] 胜利总结面 GP 行未见快照合计「合计 24」(runner 缺位守卫缺位——717 回归)")
|
||||
var s: String = main._gp_summary_text({"gp_dropped": 0})
|
||||
@@ -362,7 +362,7 @@ func _find_label_text(node: Node, needle: String, found: Dictionary) -> void:
|
||||
func _pick_battle_node(main: Node) -> int:
|
||||
# 入口/兑付停点走 level_screen.open_choices 直传(不写 _pending_candidates)——
|
||||
# 候选从视图态取:_cand_ids × runner.nodes() 的 type(编号解析=node_id_of 单一出口)
|
||||
var ls: Node = main.ui.modals.level_screen
|
||||
var ls: Node = main.ui.modals.run.level_screen
|
||||
if ls._map._runner == null:
|
||||
return -1
|
||||
for nd in ls._map._runner.nodes():
|
||||
@@ -388,7 +388,7 @@ const _PAUSE_READONLY_SIGNALS: Array[String] = [
|
||||
|
||||
|
||||
func _status_readonly_contract(main: Node) -> void:
|
||||
var overlay: Control = main.ui.modals.status_panel
|
||||
var overlay: Control = main.ui.modals.run.status_panel
|
||||
var stack: Array = [overlay]
|
||||
var conn_count := 0
|
||||
while not stack.is_empty():
|
||||
@@ -414,7 +414,7 @@ func _status_readonly_contract(main: Node) -> void:
|
||||
# ⑨status 零动效契约(R5/P4 甲——零动效直开直关路径存在断言):
|
||||
# 子树零 AnimationPlayer + 视图源码零 tween/动效包装调用(源码 token 扫描=ui_contrast 静态段同手法)
|
||||
func _status_zero_motion_contract(main: Node) -> void:
|
||||
var overlay: Control = main.ui.modals.status_panel
|
||||
var overlay: Control = main.ui.modals.run.status_panel
|
||||
var stack: Array = [overlay]
|
||||
while not stack.is_empty():
|
||||
var n: Node = stack.pop_back()
|
||||
@@ -434,7 +434,7 @@ func _status_zero_motion_contract(main: Node) -> void:
|
||||
# 清单外零连接。白名单={视图自身 _emit_closed〔返回钮〕, 组合根 _on_career_closed};页内任何
|
||||
# 购买/导航/写入方向的新连接一律红,须先入册审查。
|
||||
func _career_readonly_contract(main: Node) -> void:
|
||||
var overlay: Control = main.ui.modals.career_overlay
|
||||
var overlay: Control = main.ui.modals.menu.career_overlay
|
||||
var stack: Array = [overlay]
|
||||
var conn_count := 0
|
||||
while not stack.is_empty():
|
||||
@@ -459,7 +459,7 @@ func _career_readonly_contract(main: Node) -> void:
|
||||
|
||||
# ⑪career 零动效契约(状态面板 ⑨ 同形制——P4 甲直开直关)
|
||||
func _career_zero_motion_contract(main: Node) -> void:
|
||||
var overlay: Control = main.ui.modals.career_overlay
|
||||
var overlay: Control = main.ui.modals.menu.career_overlay
|
||||
var stack: Array = [overlay]
|
||||
while not stack.is_empty():
|
||||
var n: Node = stack.pop_back()
|
||||
@@ -480,7 +480,7 @@ func _career_zero_motion_contract(main: Node) -> void:
|
||||
# _career_registry_contract 的断言(career=状态面板后/确认弹窗前、树序同步)由本全量合同覆盖)
|
||||
# ⑭选档界面契约(卡③ sl1/sl2/sl3/sl4/sl9——呈现面全部来自喂入数据,视图零自判)
|
||||
func _save_select_contract(main: Node, tpl: String) -> void:
|
||||
var sso: Node = main.ui.modals.save_select_overlay
|
||||
var sso: Node = main.ui.modals.menu.save_select_overlay
|
||||
# sl1 三槽呈现:槽卡计数==3+零滚动容器(禁滚动长列表形态——契约 1)
|
||||
var rows: VBoxContainer = sso._rows_box
|
||||
var live_rows := 0
|
||||
@@ -559,7 +559,7 @@ func _collect_labels(node: Node, out: Array[String]) -> void:
|
||||
|
||||
|
||||
func _modal_registry_contract(main: Node) -> void:
|
||||
var list: Array = main.ui.modals.flow.stack._list
|
||||
var list: Array = main.ui.flow.stack._list
|
||||
# ① 登记册序==合同模态序(逐位点名——合同是登记序唯一事实源)
|
||||
var contract_modals: Array = []
|
||||
for entry: Dictionary in main.ui.LAYER_CONTRACT:
|
||||
@@ -592,23 +592,42 @@ func _modal_registry_contract(main: Node) -> void:
|
||||
prev.name, node.name, node.get_index(), prev.get_index()])
|
||||
prev = node
|
||||
# ③ 宿住层特例:level_screen 宿主=冒险屏壳且在全直接子模态之下(遮挡语义归模态栈 screen_state)
|
||||
var lv: Node = main.ui.modals.level_screen
|
||||
var lv: Node = main.ui.modals.run.level_screen
|
||||
if lv.get_parent() != main.ui.screens.adventure_screen:
|
||||
problems.append("[registry] level_screen 宿主应=冒险屏壳(实测 %s)〔装配生命批 V1〕" % lv.get_parent().name)
|
||||
elif lv.get_parent().get_index() >= main.ui.modals.legend_overlay.get_index():
|
||||
elif lv.get_parent().get_index() >= main.ui.modals.run.legend_overlay.get_index():
|
||||
problems.append("[registry] 冒险屏壳应在全模态之下(宿主 idx=%d legend idx=%d)〔装配生命批 V1〕" % [
|
||||
lv.get_parent().get_index(), main.ui.modals.legend_overlay.get_index()])
|
||||
lv.get_parent().get_index(), main.ui.modals.run.legend_overlay.get_index()])
|
||||
# ④ 营地同槽特例:camp_screen 屏壳树序夹商店层与设置层之间(成员 camp_scene 登记位代言)
|
||||
var cs: Node = main.ui.screens.camp_screen
|
||||
if cs.get_index() <= main.ui.modals.shop_overlay.get_index() or cs.get_index() >= main.ui.modals.settings_overlay.get_index():
|
||||
if cs.get_index() <= main.ui.modals.menu.shop_overlay.get_index() or cs.get_index() >= main.ui.modals.menu.settings_overlay.get_index():
|
||||
problems.append("[registry] camp_screen 屏壳树序应夹商店与设置层之间(idx=%d shop=%d settings=%d)〔装配生命批 V1〕" % [
|
||||
cs.get_index(), main.ui.modals.shop_overlay.get_index(), main.ui.modals.settings_overlay.get_index()])
|
||||
cs.get_index(), main.ui.modals.menu.shop_overlay.get_index(), main.ui.modals.menu.settings_overlay.get_index()])
|
||||
# ⑤ 分域结构(句柄分域批 T1——两新子容器在座/平铺面清零/编排口独立)
|
||||
# V1a 分域在座:run/menu 各六句柄经新二段式寻址逐件非 null(12 检)
|
||||
var run_names: Array[String] = ["legend_overlay", "node_overlay", "level_screen", "curio_overlay", "end_overlay", "status_panel"]
|
||||
var menu_names: Array[String] = ["shop_overlay", "settings_overlay", "career_overlay", "save_select_overlay", "confirm_dialog", "debug_overlay"]
|
||||
for n in run_names:
|
||||
if main.ui.modals.run.get(n) == null:
|
||||
problems.append("[registry] run 域句柄缺失: %s〔句柄分域批 V1〕" % n)
|
||||
for n in menu_names:
|
||||
if main.ui.modals.menu.get(n) == null:
|
||||
problems.append("[registry] menu 域句柄缺失: %s〔句柄分域批 V1〕" % n)
|
||||
# V1b 平铺面清零:12 旧平铺名经 get() 逐件为 null(旧寻址成员不存在——纯搬家零别名)
|
||||
for n in run_names + menu_names:
|
||||
if main.ui.modals.get(n) != null:
|
||||
problems.append("[registry] 平铺残留: modals.%s 应已迁域(get 非 null)〔句柄分域批 V1〕" % n)
|
||||
# V1c 编排口独立:ModalFlow 直驻注册面(ui.flow 非 null)且 modals 无 flow 成员
|
||||
if main.ui.flow == null:
|
||||
problems.append("[registry] ui.flow 直驻缺失〔句柄分域批 V1〕")
|
||||
if main.ui.modals.get("flow") != null:
|
||||
problems.append("[registry] modals.flow 残留(应升格独立持有)〔句柄分域批 V1〕")
|
||||
|
||||
|
||||
# ⑬career 零跳转契约(提纲 P4 甲——页内零「前往他处」入口:除「返回」外任何导航钮=红)
|
||||
func _career_nojump_contract(main: Node) -> void:
|
||||
for nav in ["营地", "商店", "设置", "冒险", "继续上局", "退出", "前往"]:
|
||||
if ProbeUiUtil.find_button(main.ui.modals.career_overlay, nav, "contains") != null:
|
||||
if ProbeUiUtil.find_button(main.ui.modals.menu.career_overlay, nav, "contains") != null:
|
||||
problems.append("[career][nojump] 页内出现导航入口「%s」(零跳转违约——生涯纯只读)" % nav)
|
||||
|
||||
|
||||
|
||||
+35
-35
@@ -45,33 +45,33 @@ func _ready() -> void:
|
||||
# 悬浮于菜单之上——开始层不隐藏;树序新基准=登记册末位(确认弹窗之后=绘制序最上))
|
||||
main.ui.screens.debug_badge.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if not main.ui.modals.debug_overlay.visible:
|
||||
if not main.ui.modals.menu.debug_overlay.visible:
|
||||
problems.append("调试浮层角标点击后浮窗未开(全局浮层入口失守)")
|
||||
if not main.ui.screens.start_overlay.visible:
|
||||
problems.append("开始覆盖层被隐藏——浮窗应悬浮于菜单之上(14.5 形态失守)")
|
||||
if main.ui.modals.debug_overlay.get_index() < main.ui.modals.confirm_dialog.get_index():
|
||||
if main.ui.modals.menu.debug_overlay.get_index() < main.ui.modals.menu.confirm_dialog.get_index():
|
||||
problems.append("调试浮窗树序不在确认弹窗之后——登记册末位失守")
|
||||
# ② 滑条 → 生效预览联动
|
||||
main.ui.modals.debug_overlay.set_sliders(100, 50)
|
||||
if str(boosted_atk) not in main.ui.modals.debug_overlay.effect_text() or str(boosted_hp) not in main.ui.modals.debug_overlay.effect_text():
|
||||
problems.append("生效预览未联动(%s)" % main.ui.modals.debug_overlay.effect_text())
|
||||
main.ui.modals.menu.debug_overlay.set_sliders(100, 50)
|
||||
if str(boosted_atk) not in main.ui.modals.menu.debug_overlay.effect_text() or str(boosted_hp) not in main.ui.modals.menu.debug_overlay.effect_text():
|
||||
problems.append("生效预览未联动(%s)" % main.ui.modals.menu.debug_overlay.effect_text())
|
||||
# ③ 应用(真实信号路径:apply_requested → 组合根)——E4 后加成零表写,生效断言移至 ⑧ 战斗快照
|
||||
main.ui.modals.debug_overlay.press_apply_for_probe()
|
||||
main.ui.modals.menu.debug_overlay.press_apply_for_probe()
|
||||
# ④ 重置(重开浮窗 → 重置按钮真实路径;面板百分比归零——下一场战斗生效值回到基线)
|
||||
main._show_debug_overlay()
|
||||
main.ui.modals.debug_overlay.press_reset_for_probe()
|
||||
main.ui.modals.menu.debug_overlay.press_reset_for_probe()
|
||||
# ⑤ 批量模拟全链路(N=10——走 level_autoplay 与 headless 扫描同口径;表基线由组合根复位;
|
||||
# 菜单态上下文未锁定=按钮可点,is_running 语义=模拟在跑〔18卡⑦ 与对局禁用态拆分〕)
|
||||
main.ui.modals.debug_overlay.set_sliders(100, 0)
|
||||
main.ui.modals.debug_overlay.set_sim_count(10)
|
||||
main.ui.modals.debug_overlay.press_simulate_for_probe()
|
||||
main.ui.modals.menu.debug_overlay.set_sliders(100, 0)
|
||||
main.ui.modals.menu.debug_overlay.set_sim_count(10)
|
||||
main.ui.modals.menu.debug_overlay.press_simulate_for_probe()
|
||||
var guard := SIM_GUARD_FRAMES
|
||||
while main.ui.modals.debug_overlay.is_running() and guard > 0:
|
||||
while main.ui.modals.menu.debug_overlay.is_running() and guard > 0:
|
||||
guard -= 1
|
||||
await get_tree().process_frame
|
||||
if main.ui.modals.debug_overlay.is_running():
|
||||
if main.ui.modals.menu.debug_overlay.is_running():
|
||||
problems.append("模拟未在预算帧内完成(疑似挂死)")
|
||||
var out: String = main.ui.modals.debug_overlay.output_text()
|
||||
var out: String = main.ui.modals.menu.debug_overlay.output_text()
|
||||
if not out.contains("关卡完成率"):
|
||||
problems.append("模拟输出缺关卡完成率")
|
||||
# 口径换代 V7:胜局统计行措辞钉子(atk+100% 加成档 10 局必有胜局——hp_left_win 非空路径恒出)
|
||||
@@ -83,7 +83,7 @@ func _ready() -> void:
|
||||
problems.append("模拟输出 N 标注错误(%s)" % out.substr(0, 40))
|
||||
# ⑥ 关闭 → 浮窗收起、开始层全程在屏
|
||||
main._close_debug_overlay()
|
||||
if main.ui.modals.debug_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
if main.ui.modals.menu.debug_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
problems.append("关闭后层级状态错误")
|
||||
# ⑦ hero 表运行期不可变(E4 收口回归断言:任何代码 reintroduce 表写在此被抓获——原"表值残留"断言语义升级)
|
||||
if int(main.db.combat.hero.atk) != base_atk or int(main.db.combat.hero.max_hp) != base_hp:
|
||||
@@ -93,20 +93,20 @@ func _ready() -> void:
|
||||
# 存档隔离(停点断点写盘随 main.save_manager;探针禁碰真实档,同族探针隔离纪律;
|
||||
# isolate_save 先删后建——上次运行的残留断点会触发互斥确认早退)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_tune_probe_save", true, false, true) # 末参=swap_save(卡②签名换代——断点写盘经 autoload 落隔离档)
|
||||
main.ui.modals.debug_overlay.set_sliders(100, 50)
|
||||
main.ui.modals.debug_overlay.press_apply_for_probe()
|
||||
main.ui.modals.debug_overlay.seed_edit.text = "42" # 种子钉死(18卡⑦审计🔴——空框=非首局随机,显式优先经真实路径断言 master_seed)
|
||||
main.ui.modals.menu.debug_overlay.set_sliders(100, 50)
|
||||
main.ui.modals.menu.debug_overlay.press_apply_for_probe()
|
||||
main.ui.modals.menu.debug_overlay.seed_edit.text = "42" # 种子钉死(18卡⑦审计🔴——空框=非首局随机,显式优先经真实路径断言 master_seed)
|
||||
main._start_adventure_from_menu() # 完整冒险路径(唯一试玩入口;_start_single 按语义清零滑条 = 恒基线,不承载加成断言)
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
# ⑧b 开冒险路径显式关浮窗(18卡⑦ T2 防护——调试会话默认开态下开局不带窗,对局中经角标再开)
|
||||
if main.ui.modals.debug_overlay.visible:
|
||||
if main.ui.modals.menu.debug_overlay.visible:
|
||||
problems.append("开冒险路径未显式关浮窗(T2 防护失守)")
|
||||
if int(main.run_scope.adventure.master_seed) != 42:
|
||||
problems.append("显式种子未达冒险(master_seed=%s ≠ 42——真实路径显式优先失守)" % str(main.run_scope.adventure.master_seed))
|
||||
# 关卡开始 = 入口选路停点——真实按钮路径选入口候选进首战再读呈现快照
|
||||
if main.ui.modals.level_screen.visible:
|
||||
main.ui.modals.level_screen.press_candidate(0)
|
||||
if main.ui.modals.run.level_screen.visible:
|
||||
main.ui.modals.run.level_screen.press_candidate(0)
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
var hero: Dictionary = main.run_scope.settlement.presentation_snapshot().hero
|
||||
@@ -121,18 +121,18 @@ func _ready() -> void:
|
||||
problems.append("对局中调试浮层角标非恒隐(发布态语义失守——卡⑦ 删写死行批)")
|
||||
else:
|
||||
main._show_debug_overlay() # 对局中开浮窗回归经直调承载(:61 既有直调先例——发布态角标恒隐,按钮信号路径退役)
|
||||
if not main.ui.modals.debug_overlay.visible:
|
||||
if not main.ui.modals.menu.debug_overlay.visible:
|
||||
problems.append("对局中角标开浮窗失败(P2 甲对局中可达失守)")
|
||||
if main.ui.modals.flow.locks_input():
|
||||
if main.ui.flow.locks_input():
|
||||
problems.append("对局中开浮窗后棋盘输入锁死(T2 防护失守——S1+ 停机点)")
|
||||
if main.ui.battle.board_zone.status_badge.disabled:
|
||||
problems.append("对局中开浮窗后状态角标置灰(T2 防护失守——S1+ 停机点)")
|
||||
if main.ui.modals.debug_overlay.is_running():
|
||||
if main.ui.modals.menu.debug_overlay.is_running():
|
||||
problems.append("对局中上下文锁定误判为模拟在跑(is_running 语义互扰)")
|
||||
if not main.ui.modals.debug_overlay._sim_btn.disabled or not main.ui.modals.debug_overlay._dbg_btn.disabled:
|
||||
if not main.ui.modals.menu.debug_overlay._sim_btn.disabled or not main.ui.modals.menu.debug_overlay._dbg_btn.disabled:
|
||||
problems.append("对局中批量模拟/两层调试按钮未禁用(T2 并存态不开放失守)")
|
||||
# 当局数据六项值对(T3——数值与只读访问器逐项一致;种子=adventure.master_seed 现值非 _seed_value 重算)
|
||||
var rd: Dictionary = main.ui.modals.debug_overlay.run_data_probe()
|
||||
var rd: Dictionary = main.ui.modals.menu.debug_overlay.run_data_probe()
|
||||
var r = main.run_scope.adventure.runner()
|
||||
if String(rd.get("seed", "")) != "42":
|
||||
problems.append("当局数据种子 ≠ master_seed 现值(%s)" % str(rd.get("seed")))
|
||||
@@ -146,27 +146,27 @@ func _ready() -> void:
|
||||
problems.append("当局数据 GP 失对(%s ≠ %s)" % [str(rd.get("gp")), str(r.gp)])
|
||||
if int(rd.get("keystone", -1)) != main.run_scope.adventure.journal().keystone_gained():
|
||||
problems.append("当局数据钥石失对(%s ≠ %s)" % [str(rd.get("keystone")), str(main.run_scope.adventure.journal().keystone_gained())])
|
||||
var close_btn: Button = ProbeUiUtil.find_button(main.ui.modals.debug_overlay, "关闭", "prefix")
|
||||
var close_btn: Button = ProbeUiUtil.find_button(main.ui.modals.menu.debug_overlay, "关闭", "prefix")
|
||||
if close_btn == null:
|
||||
problems.append("浮窗关闭钮缺失(真实收窗路径中断)")
|
||||
else:
|
||||
close_btn.pressed.emit()
|
||||
if main.ui.modals.debug_overlay.visible or main.ui.modals.flow.locks_input():
|
||||
if main.ui.modals.menu.debug_overlay.visible or main.ui.flow.locks_input():
|
||||
problems.append("对局中关闭浮窗后态失守(visible=%s locked=%s)"
|
||||
% [str(main.ui.modals.debug_overlay.visible), str(main.ui.modals.flow.locks_input())])
|
||||
% [str(main.ui.modals.menu.debug_overlay.visible), str(main.ui.flow.locks_input())])
|
||||
# ⑨b 只读巡检(17卡③形制)+零动效契约(17卡③ R5——零 AnimationPlayer+源码零 tween)
|
||||
_overlay_readonly_contract(main, problems)
|
||||
_overlay_zero_motion_contract(main, problems)
|
||||
# ⑩ 种子三分单点断言(18卡⑦ C1——判定只落 _seed_value() 单点;对局态不影响本判定面):
|
||||
# 显式合法整数全场景优先(含首局)→ 首局(存档布尔 false)恒 42 → 非首局空框引擎熵连抽不全等 42
|
||||
main.ui.modals.debug_overlay.seed_edit.text = "777"
|
||||
main.ui.modals.menu.debug_overlay.seed_edit.text = "777"
|
||||
if main._seed_value() != 777:
|
||||
problems.append("显式种子输入未优先(_seed_value != 777——C1 ①失守)")
|
||||
# SaveManager 是 autoload 单例——换注走原地 attach(首局态挂载+恢复隔离档);
|
||||
# --script 模式无裸 autoload 标识符——经 main 节点路径解析
|
||||
var sm = main.get_node("/root/SaveManager")
|
||||
sm.slots.attach_path("user://smoke_tune_probe_seed.json") # 全新空档——first_adventure_done=false(首局态;新档缺省面)
|
||||
main.ui.modals.debug_overlay.seed_edit.text = ""
|
||||
main.ui.modals.menu.debug_overlay.seed_edit.text = ""
|
||||
if main._seed_value() != 42:
|
||||
problems.append("首局空框种子 != 42(P5 甲失守——教学态可复现破约)")
|
||||
sm.slots.attach_path("user://smoke_tune_probe_save.json") # 恢复隔离档(非首局态——isolate_save 已建档置位)
|
||||
@@ -181,7 +181,7 @@ func _ready() -> void:
|
||||
all42 = false
|
||||
if all42:
|
||||
problems.append("非首局空框连抽 4 次全等 42(随机化失守——C1 ③)")
|
||||
main.ui.modals.debug_overlay.seed_edit.text = "42" # 钉回显式值(现场整洁)
|
||||
main.ui.modals.menu.debug_overlay.seed_edit.text = "42" # 钉回显式值(现场整洁)
|
||||
for f0 in ["user://smoke_tune_probe_seed.json", "user://smoke_tune_probe_seed.json.tmp"]:
|
||||
if FileAccess.file_exists(f0):
|
||||
DirAccess.remove_absolute(f0)
|
||||
@@ -196,11 +196,11 @@ func _ready() -> void:
|
||||
|
||||
|
||||
# 只读巡检(18卡⑦ T3——17卡③「白名单外零连接」形制沿用):浮窗子树全控件 × 游戏语义信号名清单
|
||||
# 全连接巡检——白名单={视图自身八方法 + 注册面模态编排口 ui.modals.flow.close(closed 外发消费——
|
||||
# 全连接巡检——白名单={视图自身八方法 + 注册面模态编排口 ui.flow.close(closed 外发消费——
|
||||
# 注册面批把该连接目标从组合根转发壳改为 flow 真方法,机检白名单随批登记同一连接)};
|
||||
# 当局数据区块=纯标签零连接在此被一并约束(新增任何连接=红须入册审查)。
|
||||
func _overlay_readonly_contract(main: Node, problems: Array) -> void:
|
||||
var overlay: Control = main.ui.modals.debug_overlay
|
||||
var overlay: Control = main.ui.modals.menu.debug_overlay
|
||||
var stack: Array = [overlay]
|
||||
var conn_count := 0
|
||||
while not stack.is_empty():
|
||||
@@ -211,7 +211,7 @@ func _overlay_readonly_contract(main: Node, problems: Array) -> void:
|
||||
var cb: Callable = conn["callable"]
|
||||
var host: Object = cb.get_object()
|
||||
var m := String(cb.get_method())
|
||||
var flow_host: Object = main.ui.modals.flow # 注册面模态编排口(closed 外发消费白名单宿主)
|
||||
var flow_host: Object = main.ui.flow # 注册面模态编排口(closed 外发消费白名单宿主)
|
||||
var ok := (host == overlay and m in _OVERLAY_VIEW_METHODS) \
|
||||
or (host == flow_host and m == "close") \
|
||||
or (host is VScrollBar or host is HScrollBar) # 引擎滚动机构内部 drag 接线(RichTextLabel 自动滚动条——17卡③布局生命线同类豁免,零游戏写通路)
|
||||
@@ -226,7 +226,7 @@ func _overlay_readonly_contract(main: Node, problems: Array) -> void:
|
||||
|
||||
# 零动效契约(17卡③ R5 形制——子树零 AnimationPlayer + 视图源码零 tween/动效包装调用)
|
||||
func _overlay_zero_motion_contract(main: Node, problems: Array) -> void:
|
||||
var overlay: Control = main.ui.modals.debug_overlay
|
||||
var overlay: Control = main.ui.modals.menu.debug_overlay
|
||||
var stack: Array = [overlay]
|
||||
while not stack.is_empty():
|
||||
var n: Node = stack.pop_back()
|
||||
|
||||
Reference in new issue
Block a user