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
@@ -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)
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user