Files
gplan-2/game/presentation/views/career_overlay.gd
T
DKChan 96fc61c701 feat(tree): 迭代21天赋树实装批 T1-T6 主体——12节点换代+六键接线+营地四柜台(2026-10-12 U0)
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 全绿
2026-10-12 07:54:38 +08:00

106 lines
5.9 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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