T1 schema 换代:MetaTreeTable FORK_GROUPS 4→3(fg_mastery 退役)/RULE_KEYS 2→6(sense/economy 四键扩签)/ fork 单行双态(effects_a/b+name_a/b、每组恰一校验)/row 字段退役(行门槛主语=节点等级 level_gate)/ requires 只留点亮前置(R1 裁撤案执行);meta_tree.tres 33→12 行重排(脊柱2/锻造2含彩蛋/钥石2/同调6, att_socket1 改根节点无前置,easter_ley 摘 atk/armor_class 分量=契约9) T2 购买与彩蛋面:tree_can_buy easter 拒购+行门槛换轴;tree_buy_fork=解锁默认A;tree_toggle_fork 零币切态; tree_rule_keys 按激活态 effects_a/b 投影;_check_easter_egg 特化判定(两线拉满+socket全解锁);营地树行板双态钮 T3 六键接线:EVENTS+flag_missed/FACTS+battle_index(L2 扩签两处);rebuild 六键合成订阅 (posture 窗=battle_index&&round_index 双闸/sense 两组=counter 闸+记账双行 domain:adventure 限次2次 provisional); level_runner battle_index 注入(visited battle 型计数);_judge_flag 去重闸后 flag_missed 发射(契约12); 聚=_roll_gp_drop 入账前×1.5 provisional(escrow 不乘);散=_spend_discounted ×80%(current_price/pool_price 双计价点,刷新价不折=§11②定义边界);_start_current_level 限次按关清零(_reset_tree_limited_counters 可测口) T4 注入换代:hero_override=树淬炼flat+FORGE_ROUTE_BONUS预留0(命中不注入=契约6);Attunement.slots 判定源切 树点亮数(谓词表退役);tree_buy(ks_refresh) 同账路由 buy_attune_refresh(V15 双入口) T5 旧档废弃与删除:save_manager tree_struct=2 结构版本标记+_normalize 白名单重建+树域废弃重置(禁迁移折算); migrate_tree/buy_forge/forge_flat/forge_level/forge_price/meta_forge_row/forge_products 行族/ attunement_growth 表+访问器/生涯页三投影/career forge_total 全删;treasure_item_table UNLOCK_COUNTER_KEYS 内联; verifier_batch 花费策略换代树节点;MC slots 画像常量3 T6 营地统一:四柜台并排横滚(树淬炼主界面/锻造工坊钥匙门+零交互占位面板/秘宝匣钥匙门+内容迁入/图鉴常开); 暂停层锻造段连带删;camp data forge 投影删 存量红修复:_flush_pending_reveals 三处空 source_class 补 fx_reveal+类级豁免(a57489e9 落地件,冒烟51行) 测试随批:smoke 树段全重写(V1/V2/V3/V8/V9/V16)+_smoke_tree_rules V10 行为段(窗/限次/守侧五场景编排rig/聚散 同种子对拍)+单元 tree_rules_v11_test(六键合成行闭集校验)+run_all 22 套;ui_probe/ui_click_probe 换代树点击路径 轻闸全绿:冒烟886/0+run_all 22套+probe --click 全绿
106 lines
5.9 KiB
GDScript
106 lines
5.9 KiB
GDScript
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||
# 生涯覆盖层·只读全屏页(迭代 18 卡④ 生涯界面实装批·期一 2026-10-07——需求卡片 v1.2 裁点全甲;
|
||
# 设计权威 design/gdd/systems/跨局循环/生涯.md v0.1 期一范围)。
|
||
# 裁决落形:P1/P2 甲=汇总段两类六项(冒险总局数/通关局数/各关通关次数/Boss 首杀/Boss 总击杀/
|
||
# 钥石余额——逐行只读;原「三柜台解锁完成度概览」三投影〔属性锻造/道具工坊/天赋树〕整行删
|
||
# ——2026-10-12 用户裁:生涯页不统计天赋树与账号成长态,只统计终身计数);P3 甲=登记 modal_stack
|
||
# 营地同档(设置层旁、确认弹窗之前——登记序=树序=z 序,组合根 addChild 同位);P4 甲=零跳转
|
||
# (页内零「前往他处」入口,仅只读展示+关闭)+局内不放生涯入口(开始覆盖层「营地与系统」组唯一入口)。
|
||
# 期二/期三内容(历史回看/图鉴/单局明细)零触碰——页内无任何期二占位件。
|
||
# 只读契约(需求卡片契约 3/4):数据快照由组合根 open_career 喂入(每次开层实时读 SaveManager
|
||
# 计数访问器 + MetaProgression 访问器重建——暂停层 R4 同构,快照仅单次开层生命周期,跨开层
|
||
# 零持有);本类零核心访问、零写通路——唯一信号 closed(关闭意图,组合根经模态栈单口收口)。
|
||
# 零动效(暂停层 P4 甲先例同款):直开直关,无 tween 无 AnimationPlayer。
|
||
# R1 公共件单点:全部构成件经 UiKit 工厂产出(page_shell/label/button/keystone_badge),
|
||
# 零新素材零新色值零新字体零自建样式。页壳=page_shell 暖亮底(商店同壳——主菜单页族形态)。
|
||
class_name CareerOverlay
|
||
extends Control
|
||
|
||
signal closed
|
||
|
||
var _total_label: Label # 冒险总局数(开局即计含放弃与失败)
|
||
var _cleared_label: Label # 通关局数(三关全通才计 1)
|
||
var _clears_label: Label # 各关通关次数(一行三关——display_name ×次数)
|
||
var _boss_first_label: Label # Boss 首杀(已首杀关数/总关数)
|
||
var _boss_kills_label: Label # Boss 总击杀(含重复)
|
||
var _keystone_badge: UiKit.KeystoneBadge # 钥石余额(badge 工厂件——暂停层同形制)
|
||
|
||
|
||
func _init() -> void:
|
||
# 全屏页壳(T6/T7 对齐批先例——暖亮底+石纹弱质感+暗角+56px 通栏顶条+内容列)
|
||
var page: Dictionary = UiKit.page_shell(self, true)
|
||
var top: HBoxContainer = page.top_row
|
||
top.add_child(UiKit.label("生 涯",UiKit.FS_TITLE, true, UiKit.WARM))
|
||
var top_sp := Control.new()
|
||
top_sp.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
top.add_child(top_sp)
|
||
var close_btn := UiKit.button("返回", 90.0) # 紧凑返回钮(设置/暂停面先例形制)
|
||
close_btn.tooltip_text = "关闭生涯页,返回主菜单(本页只读,不发生任何购买或修改)"
|
||
close_btn.pressed.connect(_emit_closed)
|
||
top.add_child(close_btn)
|
||
|
||
var box: VBoxContainer = page.box
|
||
var hint := UiKit.label("跨局生涯汇总(只读——购买与装配在营地;历史冒险回看随后续批次)",
|
||
UiKit.FS_HINT, false, UiKit.WARM_SOFT)
|
||
box.add_child(hint)
|
||
|
||
# 组一·冒险战绩(终身计数域——存档 v6:总局数开局即计、通关局数三关全通才计)
|
||
# 对比度口径:页底=暖亮档深棕(BG_BRIGHT),文字全用亮墨族 token(WARM 9.0:1 / WARM_SOFT 8.0:1 /
|
||
# CANDLE 7.2:1 / INK_L_GOLD 9.1:1 实测对 BG_BRIGHT 全过 §7.2 ≥4.5:1——深墨族〔INK_LABEL〕
|
||
# 压深棕底仅 ~1.3:1 属违例,禁用)
|
||
_section_head(box, "冒险战绩")
|
||
_total_label = _row(box, "冒险总局数")
|
||
_cleared_label = _row(box, "通关局数")
|
||
_clears_label = _row(box, "各关通关次数")
|
||
_boss_first_label = _row(box, "Boss 首杀")
|
||
_boss_kills_label = _row(box, "Boss 总击杀")
|
||
|
||
# 组二·资源(钥石余额——终身计数域同段只读投影;账号成长态概览三投影已删——2026-10-12 用户裁)
|
||
_section_head(box, "资源")
|
||
var bal_row := HBoxContainer.new()
|
||
bal_row.add_theme_constant_override("separation", 8)
|
||
box.add_child(bal_row)
|
||
var bal_name := UiKit.label("钥石余额",UiKit.FS_BODY, false, UiKit.WARM)
|
||
bal_row.add_child(bal_name)
|
||
_keystone_badge = UiKit.keystone_badge("钥石 0")
|
||
bal_row.add_child(_keystone_badge)
|
||
|
||
visible = false # 显式初始化——不靠树序巧合(缺陷⑤家族纪律)
|
||
|
||
|
||
# ---- 开层(组合根唯一调用口——快照随开随建,只读同源口径同暂停层 R4)----
|
||
|
||
func open_career(data: Dictionary) -> void:
|
||
_total_label.text = "%d 局" % int(data.get("total", 0))
|
||
_cleared_label.text = "%d 局(三关全通)" % int(data.get("cleared", 0))
|
||
var parts: Array[String] = []
|
||
for row in (data.get("clears", []) as Array):
|
||
parts.append("%s ×%d" % [String(row.get("display_name", "")), int(row.get("count", 0))])
|
||
_clears_label.text = " · ".join(parts) if not parts.is_empty() else "—"
|
||
_boss_first_label.text = "%d/%d 关" % [int(data.get("boss_first_kills", 0)), int(data.get("boss_first_total", 0))]
|
||
_boss_kills_label.text = "%d 次" % int(data.get("boss_kills", 0))
|
||
_keystone_badge.set_text("钥石 %d" % int(data.get("keystone", 0)))
|
||
visible = true
|
||
|
||
|
||
func _emit_closed() -> void:
|
||
closed.emit()
|
||
|
||
|
||
# ---- 行构件(名称列 + 数值列——暂停层行族同构;数值 Label 返回供探针/冒烟投影断言)----
|
||
|
||
func _section_head(box: VBoxContainer, text: String) -> void:
|
||
box.add_child(UiKit.label(text,UiKit.FS_BODY, true, UiKit.INK_L_GOLD))
|
||
|
||
|
||
func _row(box: VBoxContainer, name_text: String) -> Label:
|
||
var line := HBoxContainer.new()
|
||
line.add_theme_constant_override("separation", 8)
|
||
box.add_child(line)
|
||
var name_l := UiKit.label(name_text,UiKit.FS_BODY, false, UiKit.WARM)
|
||
name_l.custom_minimum_size = Vector2(150, 0)
|
||
line.add_child(name_l)
|
||
var val_l := UiKit.label("—",UiKit.FS_BODY, true, UiKit.CANDLE)
|
||
line.add_child(val_l)
|
||
return val_l
|