iter44-卡1:卡①(组合根注册面批): ui_registry+三域容器建件·main.gd 49→15·全消费面改址main.ui.*·四闸主证行为零变化
This commit is contained in:
1 parent
14054d9dfb
commit
d2b36e59cb
41 files changed
+1073
-1070
No files matched your search
+171
-171
@@ -51,7 +51,7 @@ func _ready() -> void:
|
||||
var t_ui_ready := Time.get_ticks_msec() - t0
|
||||
# 调试浮窗 boot 不开(菜单优先——入口=UI 最顶层全局浮层角标,
|
||||
# 任何 UI 不遮挡;浮层角标遮挡判据见设置面段)
|
||||
if main.debug_overlay.visible:
|
||||
if main.ui.modals.debug_overlay.visible:
|
||||
_problems.append("调试浮窗 boot 自动开(菜单优先失守)")
|
||||
# ---- 营地购买合成点击路径(选档进档开层→购买→关闭全走真实按钮信号路径;
|
||||
# 隔离存档换注 main.meta 保确定性(禁碰真实档 user://save.json);陈旧档段首清理)----
|
||||
@@ -65,17 +65,17 @@ func _ready() -> void:
|
||||
_problems.append("营地入口缺失(选档层新档钮——mn9 新路径驱动中断)")
|
||||
else:
|
||||
await get_tree().process_frame
|
||||
if not main.camp_overlay.visible:
|
||||
if not main.ui.modals.camp_overlay.visible:
|
||||
_problems.append("营地层未打开(进档开层新路径)")
|
||||
elif main.camp_overlay._tree_buy_btns.is_empty():
|
||||
elif main.ui.modals.camp_overlay._tree_buy_btns.is_empty():
|
||||
_problems.append("树淬炼柜台购买钮缺失(点击路径——四柜台重排后树=主界面)")
|
||||
else:
|
||||
# 树钮句柄用后即取(refresh_camp 随刷重建树行板——旧钮 queue_free,跨刷新句柄必失效)
|
||||
iso_c.meta_state._add_keystone(9999)
|
||||
main.camp_overlay.refresh_camp(main._camp_data())
|
||||
main.ui.modals.camp_overlay.refresh_camp(main._camp_data())
|
||||
await get_tree().process_frame
|
||||
var buy_btn: Button = null
|
||||
for card in main.camp_overlay._tree_buy_btns:
|
||||
for card in main.ui.modals.camp_overlay._tree_buy_btns:
|
||||
if String(card.node_id) == "sp_hp":
|
||||
buy_btn = card.btn
|
||||
if buy_btn == null:
|
||||
@@ -93,16 +93,16 @@ func _ready() -> void:
|
||||
_problems.append("营地树购买未持久(reload 后级 != 1)")
|
||||
# Fork 双态切换点击路径(V20——购=解锁默认 A,钮切 B;前置=同调位 1,先点亮)
|
||||
var socket_btn: Button = null
|
||||
for card in main.camp_overlay._tree_buy_btns:
|
||||
for card in main.ui.modals.camp_overlay._tree_buy_btns:
|
||||
if String(card.node_id) == "att_socket1":
|
||||
socket_btn = card.btn
|
||||
if socket_btn != null:
|
||||
socket_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
main.camp_overlay.refresh_camp(main._camp_data())
|
||||
main.ui.modals.camp_overlay.refresh_camp(main._camp_data())
|
||||
await get_tree().process_frame
|
||||
var fork_btn: Button = null
|
||||
for card in main.camp_overlay._tree_buy_btns:
|
||||
for card in main.ui.modals.camp_overlay._tree_buy_btns:
|
||||
if String(card.node_id) == "fork_posture":
|
||||
fork_btn = card.btn
|
||||
if fork_btn == null:
|
||||
@@ -110,10 +110,10 @@ func _ready() -> void:
|
||||
else:
|
||||
fork_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
main.camp_overlay.refresh_camp(main._camp_data())
|
||||
main.ui.modals.camp_overlay.refresh_camp(main._camp_data())
|
||||
await get_tree().process_frame
|
||||
var side_b: Button = null
|
||||
for fk in main.camp_overlay._tree_fork_btns:
|
||||
for fk in main.ui.modals.camp_overlay._tree_fork_btns:
|
||||
if String(fk.group) == "fg_posture" and String(fk.side) == "b":
|
||||
side_b = fk.btn
|
||||
if side_b == null:
|
||||
@@ -128,7 +128,7 @@ func _ready() -> void:
|
||||
# ---- 营地六处灰字取色断言(迭代36 wc4——真实入口开营地后按文本锚取 label,
|
||||
# font_color 逐处 == STONE_DEEP;六源位 :167 图鉴锁文/:417+:476 行状态字/:509 同调形态/:513 档位标签/:525 刷新行)----
|
||||
var camp_labels: Array = []
|
||||
_collect_labels_by_text(main.camp_overlay, camp_labels)
|
||||
_collect_labels_by_text(main.ui.modals.camp_overlay, camp_labels)
|
||||
var atlas_locks := _labels_with_text(camp_labels, "柜台结构位预留")
|
||||
if atlas_locks.is_empty():
|
||||
_problems.append("营地灰字:图鉴柜台锁文 label 未找到(wc4 定位锚失守)")
|
||||
@@ -137,9 +137,9 @@ func _ready() -> void:
|
||||
_problems.append("营地灰字:图鉴锁文未用 STONE_DEEP(wc4 :167)")
|
||||
# 「未解锁」锚收窄到秘宝匣行容器子树(树行/锻造行也有「未解锁」态字样——非 wc4 目标位)
|
||||
var locked_status: Array = []
|
||||
if main.camp_overlay.get("_workshop_holder") != null:
|
||||
if main.ui.modals.camp_overlay.get("_workshop_holder") != null:
|
||||
var ws_labels: Array = []
|
||||
_collect_labels_by_text(main.camp_overlay._workshop_holder, ws_labels)
|
||||
_collect_labels_by_text(main.ui.modals.camp_overlay._workshop_holder, ws_labels)
|
||||
locked_status = _labels_with_text(ws_labels, "未解锁")
|
||||
if locked_status.is_empty():
|
||||
_problems.append("营地灰字:秘宝匣行「未解锁」态 label 未找到(wc4 夹具前提失守——新档应有锁定秘宝行)")
|
||||
@@ -177,7 +177,7 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
main._on_save_select_closed() # 关闭被栈还原的选档层(动线序中间态——卡④ 换代点)
|
||||
await get_tree().process_frame
|
||||
if main.camp_overlay.visible or not main._start_overlay.visible:
|
||||
if main.ui.modals.camp_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
_problems.append("营地关闭后未恢复开始层")
|
||||
# ---- 选档界面行为走查(迭代 33 卡③):sl5 空槽新档链/sl6 有档槽进档链/sl7 删档二次确认双路径
|
||||
# /sl8 消费方分派单口/sl12 动线序不回闪。开层=函数直调(「进入存档」钮归卡② mn3——中间态在案);
|
||||
@@ -196,11 +196,11 @@ func _ready() -> void:
|
||||
f_c2.close() # 槽2 有档异值(进档链夹具);槽1/3 空
|
||||
main._open_save_select()
|
||||
await get_tree().process_frame
|
||||
if not main.save_select_overlay.visible:
|
||||
if not main.ui.modals.save_select_overlay.visible:
|
||||
_problems.append("[savesel] 选档层未打开(click 段前置)")
|
||||
# sl12 动线序(新档链同拍采样):逐帧可见性次序——首帧选档隐藏时营地层必须已可见、开始层保持隐藏
|
||||
#(禁先关后开——_close_modal 会恢复开始层=回闪一帧)
|
||||
var new_btn: Button = main.save_select_overlay._new_btns.get(1)
|
||||
var new_btn: Button = main.ui.modals.save_select_overlay._new_btns.get(1)
|
||||
if new_btn == null:
|
||||
_problems.append("[savesel] 槽1 新档钮缺失(sl5/sl12 驱动中断)")
|
||||
else:
|
||||
@@ -208,7 +208,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.save_select_overlay.visible, main.camp_overlay.visible, main._start_overlay.visible])
|
||||
samples.append([main.ui.modals.save_select_overlay.visible, main.ui.modals.camp_overlay.visible, main.ui.screens.start_overlay.visible])
|
||||
if samples[0][0]:
|
||||
_problems.append("[savesel] sl12 新档后选档层仍可见(落点开层未发生)")
|
||||
elif not samples[0][1]:
|
||||
@@ -217,8 +217,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._modals._occluded.get(main.camp_overlay, [])
|
||||
if not occluded.has(main.save_select_overlay):
|
||||
var occluded: Array = main.ui.modals.flow.stack._occluded.get(main.ui.modals.camp_overlay, [])
|
||||
if not occluded.has(main.ui.modals.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 落盘应全零)")
|
||||
@@ -227,7 +227,7 @@ func _ready() -> void:
|
||||
# sl6 进档链:槽2 进档 → 激活=2(camp 数据随激活槽)
|
||||
main._open_save_select()
|
||||
await get_tree().process_frame
|
||||
var load_btn: Button = main.save_select_overlay._load_btns.get(2)
|
||||
var load_btn: Button = main.ui.modals.save_select_overlay._load_btns.get(2)
|
||||
if load_btn == null:
|
||||
_problems.append("[savesel] 槽2 进档钮缺失(sl6 驱动中断——夹具应有档)")
|
||||
else:
|
||||
@@ -235,51 +235,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.camp_overlay.visible or main.save_select_overlay.visible:
|
||||
if not main.ui.modals.camp_overlay.visible or main.ui.modals.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.save_select_overlay._delete_btns.get(2)
|
||||
var del_btn: Button = main.ui.modals.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.confirm_dialog.is_open():
|
||||
if not main.ui.modals.confirm_dialog.is_open():
|
||||
_problems.append("[savesel] sl7 一击未只开确认窗(直删形态)")
|
||||
elif not FileAccess.file_exists(csel_tpl % 2):
|
||||
_problems.append("[savesel] sl7 确认前文件已被删(一次点击即删违契)")
|
||||
else:
|
||||
if not main._modal_flow.stack._occluded.has(main.confirm_dialog):
|
||||
if not main.ui.modals.flow.stack._occluded.has(main.ui.modals.confirm_dialog):
|
||||
_problems.append("[savesel] sl7 确认窗未经模态栈开(直开旁路——wr2 单口失守)")
|
||||
elif not main._input_locked():
|
||||
elif not main.ui.modals.flow.locks_input():
|
||||
_problems.append("[savesel] sl7 确认窗开时输入锁未生效(锁域失守——wr2)")
|
||||
main.confirm_dialog.cancelled.emit() # 取消路径(真实信号——cancelled 钮同源)
|
||||
main.ui.modals.confirm_dialog.cancelled.emit() # 取消路径(真实信号——cancelled 钮同源)
|
||||
await get_tree().process_frame
|
||||
if main.confirm_dialog.is_open() or not FileAccess.file_exists(csel_tpl % 2):
|
||||
if main.ui.modals.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._modal_flow.stack._occluded.has(main.confirm_dialog):
|
||||
if main.ui.modals.flow.stack._occluded.has(main.ui.modals.confirm_dialog):
|
||||
_problems.append("[savesel] sl7 取消后确认窗遮挡账未清(关侧未走模态栈——wr2)")
|
||||
del_btn.pressed.emit() # 再开窗走确认路径
|
||||
await get_tree().process_frame
|
||||
main.confirm_dialog.confirmed.emit() # 确认路径(真实信号——confirmed 钮同源)
|
||||
main.ui.modals.confirm_dialog.confirmed.emit() # 确认路径(真实信号——confirmed 钮同源)
|
||||
await get_tree().process_frame
|
||||
if FileAccess.file_exists(csel_tpl % 2) or main.confirm_dialog.is_open():
|
||||
if FileAccess.file_exists(csel_tpl % 2) or main.ui.modals.confirm_dialog.is_open():
|
||||
_problems.append("[savesel] sl7 确认路径失守(应删档+关窗)")
|
||||
elif main.run_scope.is_adventure or main._start_overlay.visible:
|
||||
elif main.run_scope.is_adventure or main.ui.screens.start_overlay.visible:
|
||||
_problems.append("[savesel] sl8 删档确认误触发开局(双常驻接线形态——分派单口失守)")
|
||||
elif bool(main.save_select_overlay._occupied_flags.get(2, true)):
|
||||
elif bool(main.ui.modals.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.save_select_overlay.visible or not main._start_overlay.visible:
|
||||
if main.ui.modals.save_select_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
_problems.append("[savesel] 关闭后层未隐藏或开始层未恢复(模态栈单口失守)")
|
||||
|
||||
# ---- 设置面段(隔离 store 换注禁碰真实 user://settings.cfg;真实按钮信号路径)----
|
||||
@@ -289,19 +289,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.settings_overlay.retarget(iso_s)
|
||||
var settings_btn: Button = ProbeUiUtil.find_button(main._start_overlay, "设置", "prefix")
|
||||
main.ui.modals.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.settings_overlay.visible or main._start_overlay.visible:
|
||||
if not main.ui.modals.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.settings_overlay._motion_btn
|
||||
var motion_btn: Button = main.ui.modals.settings_overlay._motion_btn
|
||||
if motion_btn == null:
|
||||
_problems.append("设置面减动效开关缺失")
|
||||
else:
|
||||
@@ -318,7 +318,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.settings_overlay._volume
|
||||
var vol: HSlider = main.ui.modals.settings_overlay._volume
|
||||
vol.value = 30
|
||||
await get_tree().process_frame
|
||||
var master_idx := AudioServer.get_bus_index("Master")
|
||||
@@ -329,24 +329,24 @@ func _ready() -> void:
|
||||
_problems.append("音量未入 store(%f ≠ 0.3)" % iso_s.volume_linear)
|
||||
# 调试入口断言(卡⑦ c4 发布态换代——角标恒隐;原「最顶层浮层不被遮挡」
|
||||
# 回归语义随调试浮层发布态退役,申报见迭代 38 实现报告 §8.2)
|
||||
if main.debug_badge == null or main.debug_badge.visible:
|
||||
if main.ui.screens.debug_badge == null or main.ui.screens.debug_badge.visible:
|
||||
_problems.append("设置面开中调试角标可见(发布态恒隐失守)")
|
||||
var settings_close: Button = ProbeUiUtil.find_button(main.settings_overlay, "返回", "prefix")
|
||||
var settings_close: Button = ProbeUiUtil.find_button(main.ui.modals.settings_overlay, "返回", "prefix")
|
||||
if settings_close == null:
|
||||
_problems.append("设置面返回按钮缺失")
|
||||
else:
|
||||
settings_close.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if main.settings_overlay.visible or not main._start_overlay.visible:
|
||||
if main.ui.modals.settings_overlay.visible or not main.ui.screens.start_overlay.visible:
|
||||
_problems.append("设置面关闭后未恢复开始层")
|
||||
# 旧入口零残留断言(卡④ AC③——测试调整板不含减动效开关;14.5 起载体=调试浮窗)
|
||||
var legacy_motion = ProbeUiUtil.find_check_button(main.debug_overlay, "减动效")
|
||||
var legacy_motion = ProbeUiUtil.find_check_button(main.ui.modals.debug_overlay, "减动效")
|
||||
if legacy_motion != null:
|
||||
_problems.append("调整板减动效旧入口未退役(设置面唯一入口失守——卡④ AC③)")
|
||||
# D1 断言(二轮):退出游戏只在一级菜单——开始菜单有、设置面无
|
||||
if ProbeUiUtil.find_button(main._start_overlay, "退出游戏", "prefix") == null:
|
||||
if ProbeUiUtil.find_button(main.ui.screens.start_overlay, "退出游戏", "prefix") == null:
|
||||
_problems.append("开始菜单缺退出游戏按钮(二轮 D1)")
|
||||
if ProbeUiUtil.find_button(main.settings_overlay, "退出游戏", "prefix") != null:
|
||||
if ProbeUiUtil.find_button(main.ui.modals.settings_overlay, "退出游戏", "prefix") != null:
|
||||
_problems.append("设置面仍含退出游戏按钮(二轮 D1——只在一级菜单出现)")
|
||||
# ---- 生涯页段(入口点击链+关闭回返,真实按钮信号路径;本页只读零写,
|
||||
# 值断言归冒烟投影段与 ui_struct 结构族,此处只验开合路径与零跳转)----
|
||||
@@ -354,45 +354,45 @@ func _ready() -> void:
|
||||
if true:
|
||||
main._open_career()
|
||||
await get_tree().process_frame
|
||||
if not main.career_overlay.visible or main._start_overlay.visible:
|
||||
if not main.ui.modals.career_overlay.visible or main.ui.screens.start_overlay.visible:
|
||||
_problems.append("生涯页未打开(点击路径)")
|
||||
else:
|
||||
# 零跳转契约(提纲 P4 甲):页内除「返回」外零导航钮
|
||||
for nav in ["营地", "商店", "设置", "退出", "冒险"]:
|
||||
if ProbeUiUtil.find_button(main.career_overlay, nav, "contains") != null:
|
||||
if ProbeUiUtil.find_button(main.ui.modals.career_overlay, nav, "contains") != null:
|
||||
_problems.append("生涯页内出现导航入口「%s」(零跳转违约——生涯纯只读)" % nav)
|
||||
# 局内入口断言(提纲 P4 甲):生涯入口只在开始层——战斗屏/地图屏零生涯角标
|
||||
if main.board_zone.find_child("career_badge", true, false) != null \
|
||||
or main.level_screen.find_child("career_badge", true, false) != null:
|
||||
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:
|
||||
_problems.append("局内屏出现生涯入口件(局内不放生涯入口违约)")
|
||||
var career_close: Button = ProbeUiUtil.find_button(main.career_overlay, "返回", "prefix")
|
||||
var career_close: Button = ProbeUiUtil.find_button(main.ui.modals.career_overlay, "返回", "prefix")
|
||||
if career_close == null:
|
||||
_problems.append("生涯页返回按钮缺失")
|
||||
else:
|
||||
career_close.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if main.career_overlay.visible or not main._start_overlay.visible:
|
||||
if main.ui.modals.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.debug_overlay.set_sliders(400, 200) # 高加成保 L1 可完成——L2 岔路选路段只能经冒险推进到达(单关直入口退役)
|
||||
main.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机,行为走查确定性禁依赖默认分支)
|
||||
main.ui.modals.debug_overlay.set_sliders(400, 200) # 高加成保 L1 可完成——L2 岔路选路段只能经冒险推进到达(单关直入口退役)
|
||||
main.ui.modals.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机,行为走查确定性禁依赖默认分支)
|
||||
var t1 := Time.get_ticks_msec()
|
||||
main._start_adventure_from_menu()
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
# 既有口径回归(迭代36 wc3——调试滑条 400/200=局外加成 pct>0,开场行应带「(含面板加成)」;
|
||||
# 本局为本探针首个冒险,日志无先前行,全文本判即可)
|
||||
var wc3_txt: String = main.log_view._log.get_parsed_text()
|
||||
var wc3_txt: String = main.ui.battle.log_view._log.get_parsed_text()
|
||||
if not wc3_txt.contains("种子 42") or not wc3_txt.contains("(含面板加成)"):
|
||||
_problems.append("开场行回归失守:局外加成(pct>0)局的开场行应带「(含面板加成)」(wc3)")
|
||||
# 关卡开始 = 入口选路停点——press_candidate 图上命中路径选入口候选进首战
|
||||
#(首格可点 AC 口径随之含入口选路一步:菜单点击 → 停点呈现 → pick → 棋盘安装)
|
||||
if main.level_screen.visible:
|
||||
if main.ui.modals.level_screen.visible:
|
||||
# 独立性断言:独立屏激活期战斗屏宿主整体隐藏
|
||||
if main._battle_root.visible:
|
||||
if main.ui.screens.battle_root.visible:
|
||||
_problems.append("独立屏激活期战斗屏宿主未隐藏(零透出契约失守)")
|
||||
main.level_screen.press_candidate(0)
|
||||
main.ui.modals.level_screen.press_candidate(0)
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
var t_entry := Time.get_ticks_msec() - t1
|
||||
@@ -402,7 +402,7 @@ func _ready() -> void:
|
||||
var first_cell_ms := t_entry
|
||||
if first_cell_ms > 500:
|
||||
_problems.append("进入战斗屏首格可点超时 %dms > 500ms" % first_cell_ms)
|
||||
if main.board_view.cells_probe().is_empty():
|
||||
if main.ui.battle.board_zone.board_view.cells_probe().is_empty():
|
||||
_problems.append("首格未可点(cells=0)")
|
||||
print("[click_probe] 首格可点计时 %dms(进入战斗屏口径,≤500ms AC)· 场景冷启动 %dms(含 UI 构建 %dms,观测项)" % [
|
||||
first_cell_ms, t_total, t_ui_ready])
|
||||
@@ -413,68 +413,68 @@ func _ready() -> void:
|
||||
while not _done and action_budget > 0:
|
||||
action_budget -= 1
|
||||
await get_tree().process_frame
|
||||
if main.node_overlay.visible:
|
||||
main.node_overlay.press_continue()
|
||||
if main.ui.modals.node_overlay.visible:
|
||||
main.ui.modals.node_overlay.press_continue()
|
||||
_seals_placed.clear()
|
||||
continue
|
||||
if main.curio_overlay.visible:
|
||||
if main.ui.modals.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.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.curio_overlay._header).contains("关卡奖励点"):
|
||||
# 停点态判据 = _node_curio_pending(奖励节点三选一停点住此——原条件查
|
||||
# _curio_pending〔关卡完成三选一态〕与奖励头部互斥、恒不可命中=拦截能力未证病根,
|
||||
# 卡⑤ d4 转正随修;头部校验串本体零触碰)
|
||||
_tested_curio_head = true
|
||||
var ch := String(main.curio_overlay._header)
|
||||
var ch := String(main.ui.modals.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("
|
||||
", "|"))
|
||||
# 奖励节点战报文案换代断言(卡⑤ wr2——reward_line 同屏打印于停点拉起前,
|
||||
# 同一驱动路径承载;旧「内容待定」残留或新话缺失即红)
|
||||
var logtext: String = main.log_view.parsed_text()
|
||||
var logtext: String = main.ui.battle.log_view.parsed_text()
|
||||
if not logtext.contains("关卡奖励点(三选一——选毕推进)") or logtext.contains("内容待定"):
|
||||
_problems.append("奖励节点战报文案未换代(卡⑤ wr2——旧话残留或新话缺失)")
|
||||
if not main._input_locked():
|
||||
if not main.ui.modals.flow.locks_input():
|
||||
_problems.append("三选一停点打开时输入未锁定")
|
||||
if main.curio_overlay._continue_btn.visible:
|
||||
main.curio_overlay.press_continue()
|
||||
if main.ui.modals.curio_overlay._continue_btn.visible:
|
||||
main.ui.modals.curio_overlay.press_continue()
|
||||
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._node_pending.is_empty():
|
||||
main.curio_overlay.press_card(0) # 奖励节点待选态:点首件+确认(真实按钮信号路径——与关卡完成停点同形)
|
||||
main.curio_overlay.press_confirm()
|
||||
main.ui.modals.curio_overlay.press_card(0) # 奖励节点待选态:点首件+确认(真实按钮信号路径——与关卡完成停点同形)
|
||||
main.ui.modals.curio_overlay.press_confirm()
|
||||
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._pending.is_empty():
|
||||
main.curio_overlay.press_card(0)
|
||||
main.curio_overlay.press_confirm()
|
||||
main.ui.modals.curio_overlay.press_card(0)
|
||||
main.ui.modals.curio_overlay.press_confirm()
|
||||
else:
|
||||
main.curio_overlay.press_continue() # 停点已消费的残面——继续关屏
|
||||
main.ui.modals.curio_overlay.press_continue() # 停点已消费的残面——继续关屏
|
||||
_seals_placed.clear()
|
||||
continue
|
||||
if main.shop_overlay.visible:
|
||||
if main.ui.modals.shop_overlay.visible:
|
||||
# 商店房覆盖层(摆放约束:每终点前一位恰一店,真实路径恒必经一店):零购离开(真实 leave 信号路径)放行选路。
|
||||
# 分派链序:商店层=选路页上的模态覆盖(停点呈现为
|
||||
# level_screen+shop 双 visible)——必须先于 level_screen 分派,否则下层候选点击
|
||||
# 空转烧尽预算(实证:lv2 商店停点双 visible 循环 12000 帧 done=false)。
|
||||
main.shop_overlay.leave_pressed.emit()
|
||||
main.ui.modals.shop_overlay.leave_pressed.emit()
|
||||
_seals_placed.clear()
|
||||
continue
|
||||
if main.level_screen.visible:
|
||||
if main.ui.modals.level_screen.visible:
|
||||
# 节点图选路口(零自动推进停点)——图上命中路径交替选候选(岔路使用行为;布局决策 2 改造)
|
||||
# 地图屏角标一次性 case:选路前经角标开/关状态面板(层在地图屏之上开合,
|
||||
# 关闭后地图屏选路态零扰动——P2 甲层级语义)
|
||||
if not _tested_map_status and not main.status_panel.visible:
|
||||
if not _tested_map_status and not main.ui.modals.status_panel.visible:
|
||||
_tested_map_status = true
|
||||
var mpb: Button = main.level_screen.status_badge
|
||||
var mpb: Button = main.ui.modals.level_screen.status_badge
|
||||
if mpb == null or not mpb.visible or mpb.disabled:
|
||||
_problems.append("地图屏状态角标缺失/未点亮/被置灰(P1 丁)")
|
||||
else:
|
||||
mpb.pressed.emit()
|
||||
if not main.status_panel.visible or not main.level_screen.visible:
|
||||
if not main.ui.modals.status_panel.visible or not main.ui.modals.level_screen.visible:
|
||||
_problems.append("地图屏角标开状态面板失败或地图屏被误藏(P2 甲层级失守)")
|
||||
var rbtn2: Button = ProbeUiUtil.find_button(main.status_panel, "继续", "prefix")
|
||||
var rbtn2: Button = ProbeUiUtil.find_button(main.ui.modals.status_panel, "继续", "prefix")
|
||||
if rbtn2 != null:
|
||||
rbtn2.pressed.emit()
|
||||
if main.status_panel.visible or not main.level_screen.visible:
|
||||
if main.ui.modals.status_panel.visible or not main.ui.modals.level_screen.visible:
|
||||
_problems.append("状态面板关闭后地图屏态失守(恢复语义破)")
|
||||
# 地图屏加成帽换代断言(迭代36 卡A wa2——「特性」→「属性值提升」;帽 Label 常在树;
|
||||
# 独立旗标——_tested_map_status 在同拍前置块已置位,禁复用其门控)
|
||||
@@ -482,7 +482,7 @@ func _ready() -> void:
|
||||
_tested_map_cap = true
|
||||
var cap_found := false
|
||||
var ls_labels: Array = []
|
||||
_collect_labels_by_text(main.level_screen, ls_labels)
|
||||
_collect_labels_by_text(main.ui.modals.level_screen, ls_labels)
|
||||
for l in ls_labels:
|
||||
if l.text == "属性值提升":
|
||||
cap_found = true
|
||||
@@ -494,20 +494,20 @@ 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.level_screen._cand_ids.has(nd_id):
|
||||
pick = main.level_screen._cand_ids.find(nd_id)
|
||||
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)
|
||||
break
|
||||
main.level_screen.press_candidate(pick)
|
||||
main.ui.modals.level_screen.press_candidate(pick)
|
||||
_route_clicks += 1
|
||||
_seals_placed.clear()
|
||||
continue
|
||||
if main._inter_overlay.visible:
|
||||
if main.ui.screens.inter_overlay.visible:
|
||||
# 大奖励屏(冒险级停点——非末关的关卡完成恰一次):首见确认推进 L2(真实按钮信号路径);再见 = L2 已关卡完成,收口
|
||||
if not main._input_locked():
|
||||
if not main.ui.modals.flow.locks_input():
|
||||
_problems.append("大奖励屏打开时输入未锁定")
|
||||
_inter_confirms += 1
|
||||
if _inter_confirms == 1:
|
||||
var next_btn: Button = ProbeUiUtil.find_button(main._inter_overlay, "进入下一层", "prefix")
|
||||
var next_btn: Button = ProbeUiUtil.find_button(main.ui.screens.inter_overlay, "进入下一层", "prefix")
|
||||
if next_btn == null:
|
||||
_problems.append("大奖励屏确认按钮缺失")
|
||||
else:
|
||||
@@ -522,23 +522,23 @@ func _ready() -> void:
|
||||
break
|
||||
_seals_placed.clear()
|
||||
continue
|
||||
if main._end_overlay.is_open() and main._settlement_stop_pending:
|
||||
if main.ui.modals.end_overlay.is_open() and main.run_scope.settlement_stop_timer.is_armed():
|
||||
# 战斗胜利总结结算框(真实信号路径——每场普通胜利到达):断言已拍板面后点「下一节点」
|
||||
if not main._input_locked():
|
||||
if not main.ui.modals.flow.locks_input():
|
||||
_problems.append("胜利结算框打开时输入未锁定")
|
||||
var gp_line: String = "%s %s" % [main._end_overlay._gp_name.text, main._end_overlay._gp_val.text] # 两列账行(审计差距④)——名/值列拼回整串断言
|
||||
var gp_line: String = "%s %s" % [main.ui.modals.end_overlay._gp_name.text, main.ui.modals.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._end_overlay.verdict_text() == "":
|
||||
if main.ui.modals.end_overlay.verdict_text() == "":
|
||||
_problems.append("胜利结算框判定行缺失")
|
||||
_settlement_confirms += 1
|
||||
main._end_overlay._btn.pressed.emit() # 「下一节点」真实信号路径
|
||||
main.ui.modals.end_overlay._btn.pressed.emit() # 「下一节点」真实信号路径
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
if main._settlement_stop_pending or not main.level_screen.visible:
|
||||
if main.run_scope.settlement_stop_timer.is_armed() or not main.ui.modals.level_screen.visible:
|
||||
_problems.append("胜利结算框「下一节点」未进选路页(卡⑥ AC②)")
|
||||
continue
|
||||
if main._end_overlay.is_open():
|
||||
if main.ui.modals.end_overlay.is_open():
|
||||
# 冒险终局(失败/放弃/打穿)——无单关直入口,见终局即收口(模态断言照旧)
|
||||
# 三选一链适配:_adventure_mode 仍真且非选路挂起=中途结算面(Boss 胜利
|
||||
# 总结「继续」后挂三选一→真终局未到)——真实信号路径点继续推进。
|
||||
@@ -547,13 +547,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._end_overlay._btn.pressed.emit()
|
||||
main.ui.modals.end_overlay._btn.pressed.emit()
|
||||
continue
|
||||
if not main._input_locked():
|
||||
if not main.ui.modals.flow.locks_input():
|
||||
_problems.append("终局 overlay 打开时输入未锁定")
|
||||
_done = true
|
||||
print("[click_probe] 冒险终局:%s · 选路口点击 %d 次" % [
|
||||
main._end_overlay.verdict_text().replace("\n", " "), _route_clicks])
|
||||
main.ui.modals.end_overlay.verdict_text().replace("\n", " "), _route_clicks])
|
||||
break
|
||||
if main.run_scope.settlement == null or main.run_scope.runner == null:
|
||||
continue
|
||||
@@ -566,16 +566,16 @@ func _ready() -> void:
|
||||
# 上轮摘要恢复断言(卡⑥ wr1-b——改前 _round_rows 类型错 append 全数失败、缓冲恒空、
|
||||
# 摘要自引入类型错以来从未显示):战中场观测点=round≥2 且排播队列已排空(轮首分隔行
|
||||
# 已消费=finish_settlement_round 已刷);不挂循环出口——收尾的续玩重建段会再走 log_view.clear()
|
||||
if not _tested_round_summary and int(st["round"]) >= 2 and main._row_queue.is_empty():
|
||||
if not _tested_round_summary and int(st["round"]) >= 2 and main.ui.screens.row_pacer.pending_rows().is_empty():
|
||||
_tested_round_summary = true
|
||||
if main.log_view._summary.text == "":
|
||||
if main.ui.battle.log_view._summary.text == "":
|
||||
_problems.append("上轮摘要恒空(卡⑥ wr1-b——结算行缓冲仍失真)")
|
||||
if JSON.stringify(st) == JSON.stringify(_last_state): # 排播演播期豁免(硬锁 v3——合法停顿态):演播期棋盘锁生效、probe 点击被吞、
|
||||
# 逻辑态恒定属预期。判据=纯队列(与 main 锁同源)。Waiting 收尾等待期**不豁免**——
|
||||
# 锁若把收尾链卡死,此处 stall 照报(探测面)。
|
||||
# T1 D1 处置=保留豁免+注记:冻结/缓存/重放语义不再靠豁免绕行,由 _locktest_tick
|
||||
# 脚本化断言正面承载(每 run 一次;逻辑态恒定本豁免继续作 stall 判据)。
|
||||
if main._row_queue.is_empty():
|
||||
if main.ui.screens.row_pacer.pending_rows().is_empty():
|
||||
_stall_frames += 1
|
||||
if _stall_frames == 30:
|
||||
_report_stall(st)
|
||||
@@ -595,36 +595,36 @@ func _ready() -> void:
|
||||
# ---- 预算耗尽收口(T17 硬锁批适配):选件变强后 probe 可能活过预算不再战败——断点段前提
|
||||
# (冒险终局面在案)须主动满足。收口驱动:任何停点层逐个推进(复用主循环分支语义)至
|
||||
# level_screen 选路停点→真实放弃二击→终局面。战斗中则继续 autoplay 打完。
|
||||
if not _done and not main._end_overlay.is_open():
|
||||
if not _done and not main.ui.modals.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._end_overlay.is_open():
|
||||
if main.ui.modals.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._end_overlay._btn.pressed.emit()
|
||||
main.ui.modals.end_overlay._btn.pressed.emit()
|
||||
else:
|
||||
break
|
||||
elif main.curio_overlay.visible:
|
||||
if main.curio_overlay._continue_btn.visible:
|
||||
main.curio_overlay.press_continue()
|
||||
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.run_scope.adventure != null and not main.run_scope.adventure.stop()._pending.is_empty():
|
||||
main.curio_overlay.press_card(0)
|
||||
main.curio_overlay.press_confirm()
|
||||
main.ui.modals.curio_overlay.press_card(0)
|
||||
main.ui.modals.curio_overlay.press_confirm()
|
||||
else:
|
||||
main.curio_overlay.press_continue()
|
||||
elif main.node_overlay.visible:
|
||||
main.node_overlay.press_continue()
|
||||
elif main.shop_overlay.visible:
|
||||
main.shop_overlay.leave_pressed.emit()
|
||||
elif main._inter_overlay.visible:
|
||||
var next_btn2: Button = ProbeUiUtil.find_button(main._inter_overlay, "进入下一层", "prefix")
|
||||
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()
|
||||
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.level_screen.visible:
|
||||
var abandon_btn: Button = ProbeUiUtil.find_button(main.level_screen, "放弃", "prefix")
|
||||
elif main.ui.modals.level_screen.visible:
|
||||
var abandon_btn: Button = ProbeUiUtil.find_button(main.ui.modals.level_screen, "放弃", "prefix")
|
||||
if abandon_btn != null:
|
||||
_closed_via_abandon = true
|
||||
abandon_btn.pressed.emit()
|
||||
@@ -652,14 +652,14 @@ 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._end_overlay.is_open():
|
||||
if not main.ui.modals.end_overlay.is_open():
|
||||
_problems.append("断点段:战败后未出冒险终局面")
|
||||
if main._end_overlay._btn == null:
|
||||
if main.ui.modals.end_overlay._btn == null:
|
||||
_problems.append("断点段:终局面返回按钮缺失")
|
||||
else:
|
||||
main._end_overlay._btn.pressed.emit() # 真实按钮信号路径(_btn=继续/返回共用句柄)
|
||||
main.ui.modals.end_overlay._btn.pressed.emit() # 真实按钮信号路径(_btn=继续/返回共用句柄)
|
||||
await get_tree().process_frame
|
||||
if not main._start_overlay.visible:
|
||||
if not main.ui.screens.start_overlay.visible:
|
||||
# 豁免:放弃路径收口时终局「返回」后仍挂三选一/关卡推进残留态(停点链),
|
||||
# 战败态前提失配——记录不计 problem(返回路径已实机目检)。
|
||||
if not _closed_via_abandon:
|
||||
@@ -683,16 +683,16 @@ 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.debug_overlay.reset_sliders() # ① 白板反向前提(_start_adventure 只关窗不清值——残值跨段存活防坑)
|
||||
main.debug_overlay.seed_edit.text = "42"
|
||||
main.ui.modals.debug_overlay.reset_sliders() # ① 白板反向前提(_start_adventure 只关窗不清值——残值跨段存活防坑)
|
||||
main.ui.modals.debug_overlay.seed_edit.text = "42"
|
||||
main._start_adventure_from_menu()
|
||||
var ol_l1_wait := 0
|
||||
while ol_l1_wait < 24 and String(main.log_view._log.get_parsed_text()).count("· 种子 ") < 1:
|
||||
while ol_l1_wait < 24 and String(main.ui.battle.log_view._log.get_parsed_text()).count("· 种子 ") < 1:
|
||||
ol_l1_wait += 1
|
||||
await get_tree().process_frame
|
||||
if ol_l1_wait >= 24:
|
||||
_problems.append("开场行路径①:L1 开场行未达日志(开局清日志后 24 帧内未现种子行)")
|
||||
elif String(main.log_view._log.get_parsed_text()).count("(含面板加成)") > 0:
|
||||
elif String(main.ui.battle.log_view._log.get_parsed_text()).count("(含面板加成)") > 0:
|
||||
_problems.append("开场行路径①失守:白板局 L1 开场行带「(含面板加成)」(wc1 反向)")
|
||||
print("[click_probe] 开场行①判定 wait=%d 帧断言完成" % ol_l1_wait)
|
||||
# ②③ 断点续玩正向(既有快照喂入形态——代拍板 2 预授权;生产「继续上局」钮已随三入口化
|
||||
@@ -716,14 +716,14 @@ func _ready() -> void:
|
||||
# resume 同步重建开场行,返回时已在日志)
|
||||
main._resume_from_menu()
|
||||
var ol_r_wait := 0
|
||||
while ol_r_wait < 24 and String(main.log_view._log.get_parsed_text()).count("· 种子 ") < 1:
|
||||
while ol_r_wait < 24 and String(main.ui.battle.log_view._log.get_parsed_text()).count("· 种子 ") < 1:
|
||||
ol_r_wait += 1
|
||||
await get_tree().process_frame
|
||||
if main.run_scope.runner == null or main.run_scope.runner.journal().bonus_total("atk") != 5:
|
||||
_problems.append("开场行路径②③前提失守:续玩重建后加算区 atk!=5(断点回填链断)")
|
||||
if ol_r_wait >= 24:
|
||||
_problems.append("开场行路径②③失守:续玩重建未发开场行(选路停点形应重发——形态/驱动复核)")
|
||||
elif String(main.log_view._log.get_parsed_text()).count("(含面板加成)") < 1:
|
||||
elif String(main.ui.battle.log_view._log.get_parsed_text()).count("(含面板加成)") < 1:
|
||||
_problems.append("开场行路径②③失守:bonus 已入账(pct=0/ov=0)的续玩重建开场行未带「(含面板加成)」(wc1 正向/wc2)")
|
||||
else:
|
||||
print("[click_probe] 开场行②③判定:续玩重建开场行带后缀(bonus.atk=5、pct=0)— wait=%d 帧" % ol_r_wait)
|
||||
@@ -749,15 +749,15 @@ func _ready() -> void:
|
||||
|
||||
func _run_modal_probes_once() -> void:
|
||||
# ⓪ 玩家面文案真实入口断言(迭代36 卡A wa1——C 区两段头随战斗常驻)
|
||||
if not _tested_copy and main.info_panel != null and main.info_panel.visible:
|
||||
if not _tested_copy and main.ui.battle.info_panel != null and main.ui.battle.info_panel.visible:
|
||||
_tested_copy = true
|
||||
var feat_head: Label = null
|
||||
var curio_head: Label = null
|
||||
for child in main.info_panel._feat_section.get_children():
|
||||
for child in main.ui.battle.info_panel._feat_section.get_children():
|
||||
if child is Label:
|
||||
feat_head = child
|
||||
break
|
||||
for child in main.info_panel._curio_section.get_children():
|
||||
for child in main.ui.battle.info_panel._curio_section.get_children():
|
||||
if child is Label:
|
||||
curio_head = child
|
||||
break
|
||||
@@ -768,15 +768,15 @@ func _run_modal_probes_once() -> void:
|
||||
# ① 图例模态(pattern 6):打开 → 遮挡物隐藏 + 输入锁定;关闭 → 恢复
|
||||
if not _tested_legend:
|
||||
_tested_legend = true
|
||||
main.ap_bar._btn_legend.pressed.emit()
|
||||
if not main.legend_overlay.is_open():
|
||||
main.ui.battle.board_zone.ap_bar._btn_legend.pressed.emit()
|
||||
if not main.ui.modals.legend_overlay.is_open():
|
||||
_problems.append("图例打开失败")
|
||||
if main._end_overlay.is_open() or main._start_overlay.visible:
|
||||
if main.ui.modals.end_overlay.is_open() or main.ui.screens.start_overlay.visible:
|
||||
_problems.append("图例打开时上方遮挡层未隐藏(缺陷⑤复发)")
|
||||
if not main._input_locked():
|
||||
if not main.ui.modals.flow.locks_input():
|
||||
_problems.append("图例打开时棋盘输入未锁定")
|
||||
var legend_has_seal := false
|
||||
for e in main.legend_overlay.ENTRIES:
|
||||
for e in main.ui.modals.legend_overlay.ENTRIES:
|
||||
if String(e[1]) == "封印":
|
||||
legend_has_seal = true
|
||||
# 图例封印行换代断言(迭代36 卡A wa5——真实 AP 条图例钮开层路径)
|
||||
@@ -785,31 +785,31 @@ func _run_modal_probes_once() -> void:
|
||||
", "|"))
|
||||
if not legend_has_seal:
|
||||
_problems.append("图例缺『封印』格态条目(格态图例基线)")
|
||||
main.legend_overlay.close()
|
||||
if main.legend_overlay.is_open() or main._input_locked():
|
||||
main.ui.modals.legend_overlay.close()
|
||||
if main.ui.modals.legend_overlay.is_open() or main.ui.modals.flow.locks_input():
|
||||
_problems.append("图例关闭后未恢复输入/可见性")
|
||||
# ②/②b 明细回看模态无探针(M9/P-C7——冒险中回看归「生涯」,06 登记)
|
||||
# ⑤ 状态面板(P1 丁角标真实信号路径 + P2 甲模态语义 + P1 守卫 + R3 锁恢复):
|
||||
# 角标打开 → 只读层可见+输入锁定+余额徽非空 → 「继续」关闭恢复;图例开着 → 角标置灰且点击被守卫兜住
|
||||
if not _tested_status and not main.legend_overlay.is_open() and not main.status_panel.visible:
|
||||
if not _tested_status and not main.ui.modals.legend_overlay.is_open() and not main.ui.modals.status_panel.visible:
|
||||
_tested_status = true
|
||||
var pbtn: Button = main.board_zone.status_badge
|
||||
var pbtn: Button = main.ui.battle.board_zone.status_badge
|
||||
if pbtn == null or not pbtn.visible or pbtn.disabled:
|
||||
_problems.append("战斗屏状态角标缺失/未点亮/被置灰(P1 丁入口失守 visible=%s disabled=%s)"
|
||||
% [str(pbtn != null and pbtn.visible), str(pbtn != null and pbtn.disabled)])
|
||||
else:
|
||||
pbtn.pressed.emit() # 真实按钮信号路径 → 组合根 _on_status_badge_pressed
|
||||
if not main.status_panel.visible:
|
||||
if not main.ui.modals.status_panel.visible:
|
||||
_problems.append("状态面板未随角标打开(组合根接线失守)")
|
||||
if not main._input_locked():
|
||||
if not main.ui.modals.flow.locks_input():
|
||||
_problems.append("状态面板打开时输入未锁定(R3)")
|
||||
var bal_txt: String = main.status_panel._balance_badge.value_label.text
|
||||
var bal_txt: String = main.ui.modals.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.status_panel, sv_labels)
|
||||
_collect_labels_by_text(main.ui.modals.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))
|
||||
@@ -821,8 +821,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.status_panel._attrs_label.text) != attr_expect:
|
||||
_problems.append("状态面板属性行投影失真(sv6②——期望 %s 实测 %s)" % [attr_expect, main.status_panel._attrs_label.text])
|
||||
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])
|
||||
# ③ _status_data() 直调对拍(sv7——键集恰八键+curios/feats 独立 oracle)
|
||||
var sd: Dictionary = main._status_data()
|
||||
var keys := ["balance", "hero_hp", "max_hp", "atk", "ac", "gp", "curios", "feats"]
|
||||
@@ -846,25 +846,25 @@ 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.status_panel, "继续", "prefix")
|
||||
var resume_btn: Button = ProbeUiUtil.find_button(main.ui.modals.status_panel, "继续", "prefix")
|
||||
if resume_btn == null:
|
||||
_problems.append("状态面板关闭钮缺失(「继续」)")
|
||||
else:
|
||||
resume_btn.pressed.emit()
|
||||
if main.status_panel.visible or main._input_locked():
|
||||
if main.ui.modals.status_panel.visible or main.ui.modals.flow.locks_input():
|
||||
_problems.append("状态面板关闭后未恢复(visible=%s locked=%s——R3 残留)"
|
||||
% [str(main.status_panel.visible), str(main._input_locked())])
|
||||
% [str(main.ui.modals.status_panel.visible), str(main.ui.modals.flow.locks_input())])
|
||||
# P1 守卫:图例开着 → 两处入口角标置灰;置灰态点击被处理器兜住(探针 emit 绕过 disabled)
|
||||
main.ap_bar._btn_legend.pressed.emit()
|
||||
if not main.board_zone.status_badge.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.board_zone.status_badge.pressed.emit()
|
||||
if main.status_panel.visible:
|
||||
main.ui.battle.board_zone.status_badge.pressed.emit()
|
||||
if main.ui.modals.status_panel.visible:
|
||||
_problems.append("置灰态仍可开状态面板(守卫兜底失守)")
|
||||
main.legend_overlay.close()
|
||||
main.ui.modals.legend_overlay.close()
|
||||
# ③ tooltip(状态效果槽悬停——来源+语义+剩余):有槽可见时触发
|
||||
if not _tested_tooltip:
|
||||
var row = main.stage.hero_standee.slot_row # 状态 tooltip 载体(B 区站桩)
|
||||
var row = main.ui.battle.stage.hero_standee.slot_row # 状态 tooltip 载体(B 区站桩)
|
||||
for child in row.get_children():
|
||||
if child is PanelContainer and child.visible and child.has_meta("eff"):
|
||||
_tested_tooltip = true
|
||||
@@ -878,14 +878,14 @@ func _run_modal_probes_once() -> void:
|
||||
_problems.append("状态槽 tooltip 未随移出隐藏")
|
||||
break
|
||||
# ④ 弃图刷新确认链(pattern 7 异位:确认 chips 与常规确认不同位 + 显式代价文案)
|
||||
if not _tested_refresh_chain and main.ap_bar.is_refresh_ready():
|
||||
if not _tested_refresh_chain and main.ui.battle.board_zone.ap_bar.is_refresh_ready():
|
||||
_tested_refresh_chain = true
|
||||
var rap_before: int = int(main.run_scope.settlement.action_economy.rap)
|
||||
var board_before = main.run_scope.settlement.minesweeper.current_board()
|
||||
main.ap_bar.press_refresh_for_probe()
|
||||
if not main.ap_bar.confirm_visible():
|
||||
main.ui.battle.board_zone.ap_bar.press_refresh_for_probe()
|
||||
if not main.ui.battle.board_zone.ap_bar.confirm_visible():
|
||||
_problems.append("弃图刷新确认 chips 未出现(异位确认缺失)")
|
||||
main.ap_bar.press_confirm_for_probe()
|
||||
main.ui.battle.board_zone.ap_bar.press_confirm_for_probe()
|
||||
if int(main.run_scope.settlement.action_economy.rap) != rap_before - 8:
|
||||
_problems.append("弃图刷新未扣 RAP8(%d→%d)" % [rap_before, int(main.run_scope.settlement.action_economy.rap)])
|
||||
if main.run_scope.settlement.action_economy.phase != "Active":
|
||||
@@ -897,8 +897,8 @@ func _run_modal_probes_once() -> void:
|
||||
if used_now != 1:
|
||||
_problems.append("刷新轮内计数错误(%d)" % used_now)
|
||||
var remain_expect: int = maxi(0, int(main.db.run.action_economy.refresh_cap_per_round) - used_now)
|
||||
if not main.ap_bar.refresh_remaining_text().contains(str(remain_expect)):
|
||||
_problems.append("HUD 刷新余量与快照推导失符(HUD='%s' 应含 %d)" % [main.ap_bar.refresh_remaining_text(), remain_expect])
|
||||
if not main.ui.battle.board_zone.ap_bar.refresh_remaining_text().contains(str(remain_expect)):
|
||||
_problems.append("HUD 刷新余量与快照推导失符(HUD='%s' 应含 %d)" % [main.ui.battle.board_zone.ap_bar.refresh_remaining_text(), remain_expect])
|
||||
|
||||
|
||||
# ---- 营地灰字取色断言辅助(迭代36 wc4——文本锚定位,全 Label 递归收集)----
|
||||
@@ -922,14 +922,14 @@ func _play_one_action() -> void:
|
||||
var settlement = main.run_scope.settlement
|
||||
if settlement == null:
|
||||
return # 结算竞态防抖:battle_finished 与本轮动作调度同帧到达时 settlement 可能已被置空(基线既有噪声——加固)
|
||||
if not main._row_queue.is_empty():
|
||||
if not main.ui.screens.row_pacer.pending_rows().is_empty():
|
||||
return # T1 D1——演播期不出手:此时点击只会进锁期缓存被「最后一次」覆盖(原逐帧连点语义无行为覆盖价值,且毁锁期断言注入的独占前提)
|
||||
var minesweeper = settlement.minesweeper
|
||||
# 行为①:随机封印(右键——未开相邻格),约 20% 轮次
|
||||
if _ap_spent_this_round == 0 and _rand.randf() < 0.2:
|
||||
var target := _random_unknown_adjacent(minesweeper)
|
||||
if target.x >= 0:
|
||||
main.board_view.click_cell(target, MOUSE_BUTTON_RIGHT)
|
||||
main.ui.battle.board_zone.board_view.click_cell(target, MOUSE_BUTTON_RIGHT)
|
||||
_seals_placed.append(target)
|
||||
_ap_spent_this_round += 1
|
||||
return
|
||||
@@ -937,19 +937,19 @@ func _play_one_action() -> void:
|
||||
if _rand.randf() < 0.1 and not _seals_placed.is_empty():
|
||||
var fc: Vector2i = _seals_placed.pop_back()
|
||||
if minesweeper.has_seal(fc) and not minesweeper.is_revealed(fc):
|
||||
main.board_view.click_cell(fc, MOUSE_BUTTON_RIGHT)
|
||||
main.ui.battle.board_zone.board_view.click_cell(fc, MOUSE_BUTTON_RIGHT)
|
||||
_ap_spent_this_round += 1
|
||||
return
|
||||
# 行为③:随机无效点击(非相邻格/已开格),约 8% 轮次
|
||||
if _rand.randf() < 0.08:
|
||||
main.board_view.click_cell(Vector2i(_rand.randi_range(0, minesweeper.current_board().width - 1), _rand.randi_range(0, minesweeper.current_board().height - 1)), MOUSE_BUTTON_LEFT)
|
||||
main.ui.battle.board_zone.board_view.click_cell(Vector2i(_rand.randi_range(0, minesweeper.current_board().width - 1), _rand.randi_range(0, minesweeper.current_board().height - 1)), MOUSE_BUTTON_LEFT)
|
||||
return
|
||||
# 挖掘主策略(最近可挖格)
|
||||
var plan = AutoPlayer.choose_dig(minesweeper) # O4 收口:策略单一实现
|
||||
if not plan.is_empty():
|
||||
if plan.hero_cell != minesweeper.hero_pos():
|
||||
main.board_view.click_cell(plan.hero_cell, MOUSE_BUTTON_LEFT)
|
||||
main.board_view.click_cell(plan.dig_cell, MOUSE_BUTTON_LEFT)
|
||||
main.ui.battle.board_zone.board_view.click_cell(plan.hero_cell, MOUSE_BUTTON_LEFT)
|
||||
main.ui.battle.board_zone.board_view.click_cell(plan.dig_cell, MOUSE_BUTTON_LEFT)
|
||||
_ap_spent_this_round += 1
|
||||
# 行为④:提前停手(已花 ≥3 AP 时 15%)——停手经 AP 条按钮真实信号路径
|
||||
if _ap_spent_this_round >= 3 and settlement.action_economy.phase == "Active" and _rand.randf() < 0.15:
|
||||
@@ -975,7 +975,7 @@ func _random_unknown_adjacent(minesweeper) -> Vector2i:
|
||||
|
||||
func _click_stop() -> void:
|
||||
# 停手走真实按钮信号路径(AP 条 → 组合根 settle_batch——排雷玩法 D1×6① 回归载体)
|
||||
main.ap_bar._btn_stop.pressed.emit()
|
||||
main.ui.battle.board_zone.ap_bar._btn_stop.pressed.emit()
|
||||
|
||||
|
||||
# ---- T1 D1:锁期/重放断言(每 run 一次,脚本化场景——演播期豁免的断言化承载) ----
|
||||
@@ -992,7 +992,7 @@ func _locktest_tick() -> void:
|
||||
if settlement == null or settlement.minesweeper.current_board() == null:
|
||||
return
|
||||
if _locktest_state == 0:
|
||||
if main._row_queue.is_empty() or main._input_locked():
|
||||
if main.ui.screens.row_pacer.pending_rows().is_empty() or main.ui.modals.flow.locks_input():
|
||||
return
|
||||
if String(settlement.battle_result) != "" or String(settlement.action_economy.phase) != "Active":
|
||||
return
|
||||
@@ -1003,7 +1003,7 @@ func _locktest_tick() -> void:
|
||||
return # 无合法邻格/目标被并发封印行为占位——下帧重挑
|
||||
_locktest_cell = target
|
||||
_locktest_frames = 0
|
||||
main.board_view.click_cell(target, MOUSE_BUTTON_RIGHT)
|
||||
main.ui.battle.board_zone.board_view.click_cell(target, MOUSE_BUTTON_RIGHT)
|
||||
if settlement.minesweeper.has_seal(target):
|
||||
_problems.append("锁期断言:演播期点击未被冻结(封印即时受理——v3 冻结失守)")
|
||||
_locktest_state = 2
|
||||
@@ -1014,11 +1014,11 @@ func _locktest_tick() -> void:
|
||||
return
|
||||
_locktest_state = 1
|
||||
elif _locktest_state == 1:
|
||||
if main.curio_overlay.visible or main._inter_overlay.visible or main._end_overlay.is_open() \
|
||||
if main.ui.modals.curio_overlay.visible or main.ui.screens.inter_overlay.visible or main.ui.modals.end_overlay.is_open() \
|
||||
or String(settlement.battle_result) != "":
|
||||
_locktest_state = 2 # 前提消失守卫:终结演播竞态——静默弃测
|
||||
return
|
||||
if not main._row_queue.is_empty():
|
||||
if not main.ui.screens.row_pacer.pending_rows().is_empty():
|
||||
_locktest_frames = 0 # 演播未完——重放耐心只在排空后起算(链式大演播数百帧不占预算)
|
||||
return
|
||||
_locktest_frames += 1
|
||||
@@ -1038,7 +1038,7 @@ func _locktest_tick() -> void:
|
||||
b.width, b.height, str(settlement.minesweeper.hero_pos())])
|
||||
_problems.append("重放断言:锁期缓存点击未受理恰一次(封印未置位——零发或双发)")
|
||||
_locktest_state = 2
|
||||
main.board_view.click_cell(_locktest_cell, MOUSE_BUTTON_RIGHT) # 撤封印恢复现场(尽力而为不判定)
|
||||
main.ui.battle.board_zone.board_view.click_cell(_locktest_cell, MOUSE_BUTTON_RIGHT) # 撤封印恢复现场(尽力而为不判定)
|
||||
|
||||
|
||||
func _locktest_pick_cell(minesweeper) -> Vector2i:
|
||||
|
||||
Reference in new issue
Block a user