- modal_stack.gd 新增 has_open_excluding(skip):排除式开态查询(地图屏系登记册模态成员=常态 屏态,其上角标必须可点;只读查询零副作用,登记序/开合记账语义零改动) - board_zone_view.gd 战斗屏 HUD 右下角+level_map_screen.gd 地图屏顶栏 GP 徽右——各一枚「暂停」 角标(debug 角标同形制:UiKit.button 紧凑豁免宽度基准+FS_HINT 字号降档;可见性/置灰归组合根, 信号连接归组合根 ADR-0001;非对局期显式不可见防菜单误现——P1 丁) - main.gd 接线:两角标 pressed→_on_pause_badge_pressed(守卫兜底处理器:他层开着即拒开—— 常态防线=置灰,探针 emit 绕过 disabled 时由此兜住;地图屏开态经 has_open_excluding 不计自身) +_sync_pause_entry 单一同步点(可见性=_level_active∧屏态;置灰=has_open)挂模态开合单口与 屏级互斥口/进局/离局/续玩五路径 - ui_struct_probe:pause 结构断言+只读性契约(游戏语义信号清单巡检——pressed/toggled/text/ value/item/gui_input/focus/closed 十二名,白名单外零连接,合法连接恰 2=关闭钮+closed 外发) +零动效契约(子树零 AnimationPlayer+源码零 create_tween——R5/P4 甲)【首跑 L1 修正:全集 巡检把 Godot 容器布局生命线连接(child_order_changed/item_rect_changed 等引擎自动脏标记) 误判非法——收敛为信号名清单,任务书 v1.1「巡检信号名清单落码列全」本意】 - ui_input_probe case⑯:暂停层输入锁语义(角标真点击 press+release 开层→锁期挖掘零穿透→ 「继续」关层→同格挖掘重新到达;十七断言 PASS)【首跑 L1 修正:域恰 2 枚时 flag_t 带旗+dig_t 揭开后零无旗格可取——case 挪全 case 之尾+前沿移位扩大可挖域兜底(板面扰动零波及)】 - ui_click_probe:战斗屏角标开合/守卫断言(图例开着=置灰+emit 兜底拒开)+地图屏角标一次性 case(选路前开/关,地图屏选路态零扰动);ui_contrast_probe 增钥石徽深墨/烛光黄对(12 对全绿) - smoke_all._pause_overlay_projection:暂停层投影==MetaProgression 访问器逐项(余额徽/锻造三行/ 工坊六行解锁态/天赋树概览——隔离档 smoke_meta 复用,+5 check) - 任务书回填 T0 基线注记(冒烟 783/0·run_all 17 套·交集核对零命中,HEAD=44328b1 时点) - T2 闸读数:冒烟 788/0(基线 783/0,+5 本批)· ui_input 十七断言 PASS · ui_struct 全绿 · ui_contrast 12 对 PASS · ui_click 问题=0 · ui_layout_probe 退出码 0;纯呈现零数值=零 MC
56 lines
2.1 KiB
GDScript
56 lines
2.1 KiB
GDScript
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||
# 实现 GDD:design/ux/interaction-patterns.md(pattern 6 模态 overlay 层级纪律)。
|
||
# Date: 2026-09-12(code-review 修复批——自 main.gd 拆出,规范 1.1 状态装配独立成类)
|
||
# 模态层级状态机:登记序 = 树序 = z 遮挡序;打开时显式隐藏树序在其上方的可见层、关闭恢复
|
||
# (缺陷⑤纪律载体:功能存在 ≠ 功能可达——遮挡关系不得靠树序巧合)。
|
||
# 纯逻辑零节点构建——组合根持有本类并喂入 Control;不持久化核心状态。
|
||
extends RefCounted
|
||
|
||
var _list: Array[Control] = [] # 登记序 = z 遮挡序(低 → 高)
|
||
var _occluded := {} # modal → 被其隐藏的上方层(关闭恢复)
|
||
|
||
|
||
func register(m: Control) -> void:
|
||
_list.append(m)
|
||
|
||
|
||
func open(m: Control) -> void:
|
||
var hidden: Array[Control] = []
|
||
var idx := _list.find(m)
|
||
for i in range(idx + 1, _list.size()):
|
||
var higher: Control = _list[i]
|
||
if is_instance_valid(higher) and higher.visible:
|
||
higher.visible = false
|
||
hidden.append(higher)
|
||
_occluded[m] = hidden
|
||
m.visible = true
|
||
|
||
|
||
func close(m: Control) -> void:
|
||
m.visible = false
|
||
for h in _occluded.get(m, []):
|
||
if is_instance_valid(h):
|
||
h.visible = true
|
||
_occluded.erase(m)
|
||
|
||
|
||
# 开态查询(T3 模态收口批 2026-10-02——组合根输入锁唯一判据:登记册上是否有任一层处于开态;
|
||
# 可见性即开态,与 open/close 记账同源——组合根不再手工罗列各层)
|
||
func has_open() -> bool:
|
||
for m in _list:
|
||
if is_instance_valid(m) and m.visible:
|
||
return true
|
||
return false
|
||
|
||
|
||
# 排除式开态查询(迭代 17 卡③ 2026-10-06——暂停层入口守卫判据):skip 层自身的开态不计入
|
||
#(关卡地图屏系登记册模态成员=常态屏态,其上的地图屏角标必须可点;其余任一层开着=角标置灰)。
|
||
# 只读查询零副作用——登记序/开合记账语义零改动。
|
||
func has_open_excluding(skip: Control) -> bool:
|
||
for m in _list:
|
||
if m == skip:
|
||
continue
|
||
if is_instance_valid(m) and m.visible:
|
||
return true
|
||
return false
|