## VERTICAL SLICE - NOT FOR PRODUCTION ## 组合根覆盖层流程承接件:设置/状态面板/生涯页/选档界面/图例/钱包事件的开合与数据投喂。 ## 本件是 main.gd 同名函数的逐字搬运(成员访问改 root 前缀)——main 侧留同名薄委托,探针 main.X 路径零改动。 ## 全部开合走组合根模态单口(root._open_modal/_close_modal);本件零成员态。 extends RefCounted static func _open_settings(root: Variant) -> void: root._start_overlay.visible = false root._open_modal(root.settings_overlay) # 模态栈单口 static func _on_settings_closed(root: Variant) -> void: root._close_modal(root.settings_overlay) # 模态栈单口 root._start_overlay.visible = true # ---- 局内状态面板·只读(入口角标在两屏装配段;开合与数据喂入归组合根)---- # 状态面板快照投影(数据只读同源:每次开层实时读访问器现值拼装—— # 快照仅服务单次开层生命周期(open_status 重建各行),跨开层零持有;零写调用。 # 八键换代(迭代 36 卡③):跨关解锁概览退役(营地/生涯承载)——只留本局信息; # ledger 直取下标(键缺失=致命,禁 .get 缺省留门——fail-fast 红线);禁 null 守卫软回退 # (两入口开层时 runner 恒在役——状态面板卡 F3 证据链) static func _status_data(root: Variant) -> Dictionary: return HudPresenter.status_data(root.db, root.meta, root.run_scope.runner, root._treasure_ui) static func _open_status_panel(root: Variant) -> void: root._open_modal(root.status_panel) # 模态栈单口(开层前排空排播队列——既有层同款行为,目检确认项) root.status_panel.open_status(_status_data(root)) static func _on_status_closed(root: Variant) -> void: root._close_modal(root.status_panel) # 模态栈单口 static func _open_career(root: Variant) -> void: root._start_overlay.visible = false root._open_modal(root.career_overlay) # 模态栈单口 root.career_overlay.open_career(HudPresenter.career_data(root.db, root.save_manager, root.meta)) static func _on_career_closed(root: Variant) -> void: root._close_modal(root.career_overlay) # 模态栈单口 root._start_overlay.visible = true # 生涯页快照投影 —— 承接体见 HudPresenter.career_data(开层调用点直接改引) # ==================== 选档界面(营地交互重做卡③)==================== # 开层(模态栈单口;与开始层互斥=career 同款先例)。「进入存档」钮归卡② mn3——本函数为 # 该钮的唯一落点(卡③ 批内探针函数直调=中间态,实现报告「已知中间态」登记)。 static func _open_save_select(root: Variant) -> void: root._start_overlay.visible = false root._open_modal(root.save_select_overlay) # 模态栈单口 root.save_select_overlay.open_save_select(HudPresenter.save_select_data(root.save_manager)) static func _on_save_select_closed(root: Variant) -> void: root._close_modal(root.save_select_overlay) # 模态栈单口 root._start_overlay.visible = true # 槽数据快照 —— 承接体见 HudPresenter.save_select_data(开层调用点直接改引) # 空槽新档链(Q3 裁乙暂行落点=现役 CampOverlay;卡④ 重立卡后改挂场景图):卡① 创建=激活=白板落盘, # 落点开层。动线序(禁先关后开):先落点开层(开始层保持隐藏),选档层被模态栈遮挡隐藏、不关闭。 static func _on_save_select_new(root: Variant, slot: int) -> void: root.save_manager.slots.create_slot(slot) root._camp_pres.open_camp() # 有档槽进档链(契约 8 进档即激活):卡① 激活+读盘(兜底/拒读链按槽成立)→暂行落点 CampOverlay。 static func _on_save_select_load(root: Variant, slot: int) -> void: root.save_manager.slots.activate_slot(slot) root._camp_pres.open_camp() # 删档链(契约 3):第一次点击只出确认窗(消费方编排——open 前设消费方=delete_slot), # 确认才删、取消不删;禁长按删/一次点击即删/撤销式软删。 static func _on_save_select_delete(root: Variant, slot: int) -> void: root._confirm_consumer = "delete_slot" root._confirm_consumer_slot = slot root._open_modal(root.confirm_dialog) # 模态栈单口(显示编排/挂起兜底/遮挡记账——与其余覆盖层同口) root.confirm_dialog.open("删除存档位 %d?删除后该档不可恢复。" % slot, "删除", "取消") # 入口角标点击(两屏同款处理器):P1 守卫兜底——其他模态开着即拒开(常态防线=角标置灰, # 探针 pressed.emit 绕过 disabled 时由此兜住;地图屏自身的登记开态不计——has_open_excluding) static func _on_status_badge_pressed(root: Variant) -> void: var map_on: bool = root.level_screen != null and root.level_screen.visible # P1 守卫兜底——其他模态开着即拒开(常态防线=角标置灰,探针 pressed.emit 绕过 disabled 时由此兜住; # 地图屏自身的登记开态不计;判据排除调试浮窗:对局中浮窗开着时状态角标仍可点) if (map_on and root._modal_flow.badge_greyed_map()) or (not map_on and root._modal_flow.badge_greyed_battle()): return _open_status_panel(root) # 入口角标可见性/置灰同步(P1 丁+守卫——单一同步点):战斗屏角标=对局内且地图屏未激活; # 地图屏角标=随屏;置灰=登记册上除地图屏自身外任一层开着(防「看得见点不着」态)。 # 调用面=模态开合单口与屏级互斥口(凡影响开态/屏态的路径必经其一)。 static func _sync_status_entry(root: Variant) -> void: if root.status_panel == null or root._modals == null or root.board_zone == null or root.level_screen == null: return var map_on: bool = root.level_screen.visible root.board_zone.status_badge.visible = root.run_scope.level_active and not map_on root.level_screen.status_badge.visible = map_on # 置灰判据为排除式(调试浮窗开态不计入:对局中浮窗开着时角标仍可点) root.board_zone.status_badge.disabled = root._modal_flow.badge_greyed_battle() # 互斥域谓词 root.level_screen.status_badge.disabled = root._modal_flow.badge_greyed_map() # 调试浮层角标(全局浮层任何 UI 不遮挡——可见性不随场景变,只抬 offset # 避让:地图屏底栏 85px 常驻,角标抬至底栏上方 16px;其余场景右下角 16px 贴底) root.debug_badge.offset_bottom = -101.0 if map_on else -16.0 static func _on_camp_closed(root: Variant) -> void: root._camp_pres.on_camp_closed() static func _camp_data(root: Variant) -> Dictionary: return HudPresenter.camp_data(root._camp_pres) static func _on_wallet_changed(root: Variant, event: String, gp: int, extra: Dictionary) -> void: # wallet 行族转发(到账/购买/清零——试玩日志验收取数面)+ 常驻余额与在开商店覆盖层重刷 root.logger.log_wallet(event, gp, extra) if String(event) == "gain": root.run_scope.last_gain_amount = int(extra.get("amount", 0)) # GP 增量取数(每战恰一笔 gain) if root.shop_overlay.visible and root.run_scope.runner != null: if root.run_scope.runner.is_shop_pool(): root.shop_overlay.refresh_shelf_state(int(root.run_scope.runner.gp)) # pool 面余额联动(货架内容仅买后重抽变) else: root.shop_overlay.refresh_state(root.run_scope.runner.shop_products(), int(root.run_scope.runner.gp)) root._refresh_presentations() static func _on_legend_toggled(root: Variant) -> void: if root.legend_overlay.is_open(): root._close_modal(root.legend_overlay) else: root._open_modal(root.legend_overlay)