186 lines
9.7 KiB
GDScript
186 lines
9.7 KiB
GDScript
## VERTICAL SLICE - NOT FOR PRODUCTION
|
||
## 组合根覆盖层流程承接件:设置/状态面板/生涯页/选档界面/图例/钱包事件的开合与数据投喂。
|
||
## 本件是 main.gd 同名函数的逐字搬运(成员访问改 root 前缀)——main 侧留同名薄委托,探针 main.X 路径零改动。
|
||
## 全部开合走组合根模态编排口(root.ui.modals.flow.open/close);本件零成员态。
|
||
extends RefCounted
|
||
|
||
static func _open_settings(root: Variant) -> void:
|
||
root.ui.screens.start_overlay.visible = false
|
||
root.ui.modals.flow.open(root.ui.modals.settings_overlay) # 模态栈单口
|
||
|
||
static func _on_settings_closed(root: Variant) -> void:
|
||
root.ui.modals.flow.close(root.ui.modals.settings_overlay) # 模态栈单口
|
||
root.ui.screens.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.ui.modals.flow.open(root.ui.modals.status_panel) # 模态栈单口(开层前排空排播队列——既有层同款行为,目检确认项)
|
||
root.ui.modals.status_panel.open_status(_status_data(root))
|
||
|
||
static func _on_status_closed(root: Variant) -> void:
|
||
root.ui.modals.flow.close(root.ui.modals.status_panel) # 模态栈单口
|
||
|
||
|
||
|
||
static func _open_career(root: Variant) -> void:
|
||
root.ui.screens.start_overlay.visible = false
|
||
root.ui.modals.flow.open(root.ui.modals.career_overlay) # 模态栈单口
|
||
root.ui.modals.career_overlay.open_career(HudPresenter.career_data(root.db, root.save_manager, root.meta))
|
||
|
||
static func _on_career_closed(root: Variant) -> void:
|
||
root.ui.modals.flow.close(root.ui.modals.career_overlay) # 模态栈单口
|
||
if not root.ui.modals.camp.scene.visible: # 营地语境关生涯不回开始层(笔记本入口——卡④ T3;栈已复现场景根)
|
||
root.ui.screens.start_overlay.visible = true
|
||
|
||
|
||
# ---- 营地场景点选路由(卡④ T3/T4——场景根 object_pressed 组合根分派)----
|
||
# 大门两分支(裁决 5,Q5 甲):点大门永远先出确认不直接进冒险——有断点=三出口弹窗
|
||
#(继续上一段冒险/开始新冒险/取消),无断点=是否开始新冒险(是/否);cancelled 恒=无变更退回营地。
|
||
# 篝火回主菜单必须二次确认(camp.md v2.2 裁定);确认后营地层与选档层同收+开始层恢复(关层收闭)。
|
||
|
||
|
||
static func _on_camp_object_pressed(root: Variant, key: StringName) -> void:
|
||
match key:
|
||
&"forge":
|
||
root._camp_pres.open_camp_forge()
|
||
&"chest":
|
||
root._camp_pres.open_camp_treasure()
|
||
&"dummy":
|
||
root._camp_pres.open_camp_tree()
|
||
&"board":
|
||
root._camp_pres.open_camp_codex()
|
||
&"notebook":
|
||
_open_career(root) # 生涯页入口改挂帐篷旁笔记本(CareerOverlay 本体零改——卡④ T3)
|
||
&"gate":
|
||
_open_gate_confirm(root)
|
||
&"campfire":
|
||
root._confirm_consumer = "campfire_leave"
|
||
root.ui.modals.confirm_dialog.open("确定离开营地回到主菜单?", "离开", "留下")
|
||
|
||
|
||
static func _open_gate_confirm(root: Variant) -> void:
|
||
if root.save_manager.has_breakpoint():
|
||
root._confirm_consumer = "gate"
|
||
root.ui.modals.confirm_dialog.open_three("有未完成的冒险——继续上一段冒险,还是开始新冒险?",
|
||
"继续上一段冒险", "开始新冒险", "取消")
|
||
return
|
||
root._confirm_consumer = "gate_new"
|
||
root.ui.modals.confirm_dialog.open("是否开始新冒险?", "是", "否")
|
||
|
||
|
||
# 生涯页快照投影 —— 承接体见 HudPresenter.career_data(开层调用点直接改引)
|
||
|
||
|
||
# ==================== 选档界面(营地交互重做卡③)====================
|
||
|
||
|
||
# 开层(模态栈单口;与开始层互斥=career 同款先例)。「进入存档」钮归卡② mn3——本函数为
|
||
# 该钮的唯一落点(卡③ 批内探针函数直调=中间态,实现报告「已知中间态」登记)。
|
||
static func _open_save_select(root: Variant) -> void:
|
||
root.ui.screens.start_overlay.visible = false
|
||
root.ui.modals.flow.open(root.ui.modals.save_select_overlay) # 模态栈单口
|
||
root.ui.modals.save_select_overlay.open_save_select(HudPresenter.save_select_data(root.save_manager))
|
||
|
||
static func _on_save_select_closed(root: Variant) -> void:
|
||
root.ui.modals.flow.close(root.ui.modals.save_select_overlay) # 模态栈单口
|
||
root.ui.screens.start_overlay.visible = true
|
||
|
||
|
||
# 槽数据快照 —— 承接体见 HudPresenter.save_select_data(开层调用点直接改引)
|
||
|
||
|
||
|
||
# 空槽新档链(卡④ T3 换代:落点=营地场景根——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 进档即激活):卡① 激活+读盘(兜底/拒读链按槽成立)→落点=营地场景根(卡④ T3)。
|
||
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.ui.modals.flow.open(root.ui.modals.confirm_dialog) # 模态栈单口(显示编排/挂起兜底/遮挡记账——与其余覆盖层同口)
|
||
root.ui.modals.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.ui.modals.level_screen != null and root.ui.modals.level_screen.visible
|
||
# P1 守卫兜底——其他模态开着即拒开(常态防线=角标置灰,探针 pressed.emit 绕过 disabled 时由此兜住;
|
||
# 地图屏自身的登记开态不计;判据排除调试浮窗:对局中浮窗开着时状态角标仍可点)
|
||
if (map_on and root.ui.modals.flow.badge_greyed_map()) or (not map_on and root.ui.modals.flow.badge_greyed_battle()):
|
||
return
|
||
_open_status_panel(root)
|
||
|
||
|
||
|
||
# 入口角标可见性/置灰同步(P1 丁+守卫——单一同步点):战斗屏角标=对局内且地图屏未激活;
|
||
# 地图屏角标=随屏;置灰=登记册上除地图屏自身外任一层开着(防「看得见点不着」态)。
|
||
# 调用面=模态开合单口与屏级互斥口(凡影响开态/屏态的路径必经其一)。
|
||
static func _sync_status_entry(root: Variant) -> void:
|
||
if root.ui.modals.status_panel == null or root.ui.modals.flow == null or root.ui.battle.board_zone == null or root.ui.modals.level_screen == null:
|
||
return
|
||
var map_on: bool = root.ui.modals.level_screen.visible
|
||
root.ui.battle.board_zone.status_badge.visible = root.run_scope.level_active and not map_on
|
||
root.ui.modals.level_screen.status_badge.visible = map_on
|
||
# 置灰判据为排除式(调试浮窗开态不计入:对局中浮窗开着时角标仍可点)
|
||
root.ui.battle.board_zone.status_badge.disabled = root.ui.modals.flow.badge_greyed_battle() # 互斥域谓词
|
||
root.ui.modals.level_screen.status_badge.disabled = root.ui.modals.flow.badge_greyed_map()
|
||
# 调试浮层角标(全局浮层任何 UI 不遮挡——可见性不随场景变,只抬 offset
|
||
# 避让:地图屏底栏 85px 常驻,角标抬至底栏上方 16px;其余场景右下角 16px 贴底)
|
||
root.ui.screens.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.ui.modals.shop_overlay.visible and root.run_scope.runner != null:
|
||
if root.run_scope.runner.shop.is_shop_pool():
|
||
root.ui.modals.shop_overlay.refresh_shelf_state(int(root.run_scope.runner.gp)) # pool 面余额联动(货架内容仅买后重抽变)
|
||
else:
|
||
root.ui.modals.shop_overlay.refresh_state(root.run_scope.runner.shop.shop_products(), int(root.run_scope.runner.gp))
|
||
root._refresh_presentations()
|
||
|
||
|
||
|
||
static func _on_legend_toggled(root: Variant) -> void:
|
||
if root.ui.modals.legend_overlay.is_open():
|
||
root.ui.modals.flow.close(root.ui.modals.legend_overlay)
|
||
else:
|
||
root.ui.modals.flow.open(root.ui.modals.legend_overlay)
|
||
|
||
|