按 code-conventions §1.4.1 第三轮定稿执行:core 22+schemas 18+presentation 根 14+views 28,全部头注 #→##、删日期/变更叙事/GDD 与架构反向链接/字段与域清单/机制描述,保留职责摘要+真实使用约束(防事故禁令/单一入口/信号契约每信号一行)。main.gd 31→5 行、save_manager 45→5 行、adventure_runner 37→5 行为最大单件。子代理分模块执行(波一 core+schemas、波二 presentation+views,并发≤2)。验收=tools/verify_comment_only_change.py 逐字节校验(82 文件头注区外逐行一致=零行为变更)+audit_file_headers 全绿;纯注释批免冒烟(先例 5843270)
76 lines
4.4 KiB
GDScript
76 lines
4.4 KiB
GDScript
## VERTICAL SLICE - NOT FOR PRODUCTION
|
||
## 元进度表 schema:Boss 钥石两档/属性换算/Y 刷新升级三行族的类型化读取(行值 provisional;垂直切片验证:钥石换永久强化下局生效)。
|
||
## 消费面一律走 ConfigDB.meta_* 访问器,禁直读行集。
|
||
## 道具解锁条件不在本表:单一事实源住 treasure_items 行内(unlock_keystone_cost + unlock_requires)。
|
||
class_name MetaTable
|
||
extends Resource
|
||
|
||
@export var boss_keystone: Array[Dictionary] = [] # Array[Dictionary] 键 level_index
|
||
@export var conversion: Array[Dictionary] = [] # Array[Dictionary] 键 attr
|
||
@export var attune_refresh_upgrade: Array[Dictionary] = [] # Array[Dictionary] 键 level——Y 刷新升级行族(迭代 11 第①批 T4)
|
||
|
||
const FORGE_ATTRS := ["max_hp", "atk", "armor_class"] # 三属性轴词表(conversion 行键域——原 forge 词表名沿用作轴名)
|
||
|
||
|
||
func validate() -> Array:
|
||
var errs: Array[Dictionary] = []
|
||
# 行族空护栏(三族皆为 ConfigDB 消费面——缺族即致命)
|
||
for family in ["boss_keystone", "conversion", "attune_refresh_upgrade"]:
|
||
if get(family).is_empty():
|
||
errs.append({"category": "empty_table", "message": "MetaTable 行族为空: %s" % family})
|
||
# boss_keystone:level_index 唯一 + 连续从 1 + 两档域 + first ≥ repeat(首杀全量、重复小额恒定)
|
||
var seen_li := {}
|
||
for row in boss_keystone:
|
||
var li: int = int(row.get("level_index", 0))
|
||
if seen_li.has(li):
|
||
errs.append({"category": "dup_key", "message": "boss_keystone level_index 重复: %d" % li})
|
||
seen_li[li] = true
|
||
var first: int = int(row.get("first_kill", -1))
|
||
var rep: int = int(row.get("repeat_kill", -1))
|
||
if first < 1 or first > 999 or rep < 0 or rep > 999:
|
||
errs.append({"category": "domain", "message": "boss_keystone L%d 两档金额越域 first [1,999] / repeat [0,999]: %d/%d" % [li, first, rep]})
|
||
if first < rep:
|
||
errs.append({"category": "cross_field", "message": "boss_keystone L%d 违反 first_kill(%d) ≥ repeat_kill(%d)——首杀全量、重复杀小额" % [li, first, rep]})
|
||
for i in boss_keystone.size():
|
||
var li_at: int = int(boss_keystone[i].get("level_index", 0))
|
||
if li_at != i + 1:
|
||
errs.append({"category": "structural", "message": "boss_keystone level_index 不连续(须从 1 连续递增): 位 %d = %d" % [i + 1, li_at]})
|
||
break
|
||
# workshop_items 行族已退役(迭代 22 T2——解锁混合制换代,条件谓词挂 treasure_items 行内;
|
||
# 校验段随批删除——秘宝解锁条件校验单点=TreasureItemTable.validate)
|
||
# conversion:attr 词表与 forge 一致 + 唯一 + 覆盖恰三 + 平移量域 [0,100]
|
||
var seen_conv := {}
|
||
for row in conversion:
|
||
var cattr: String = row.get("attr", "")
|
||
if not FORGE_ATTRS.has(cattr):
|
||
errs.append({"category": "enum", "message": "conversion attr 出域 {max_hp, atk, armor_class}: %s" % cattr})
|
||
if seen_conv.has(cattr):
|
||
errs.append({"category": "dup_key", "message": "conversion attr 重复: %s" % cattr})
|
||
seen_conv[cattr] = true
|
||
var shift: int = int(row.get("per_level_shift_pct", -1))
|
||
if shift < 0 or shift > 100:
|
||
errs.append({"category": "domain", "message": "conversion %s per_level_shift_pct 越域 [0,100]: %d" % [cattr, shift]})
|
||
if not conversion.is_empty():
|
||
for conv_key in FORGE_ATTRS:
|
||
if not seen_conv.has(conv_key):
|
||
errs.append({"category": "coverage", "message": "conversion 缺属性行: %s(三行与 forge 词表一致)" % conv_key})
|
||
# attune_refresh_upgrade:level 唯一 + 连续从 1 + charges/cost 域(迭代 11 第①批 T4)
|
||
var seen_al := {}
|
||
for row in attune_refresh_upgrade:
|
||
var al: int = int(row.get("level", -1))
|
||
if seen_al.has(al):
|
||
errs.append({"category": "dup_key", "message": "attune_refresh_upgrade level 重复: %d" % al})
|
||
seen_al[al] = true
|
||
var ach: int = int(row.get("refresh_charges", -1))
|
||
if ach < 1 or ach > 9:
|
||
errs.append({"category": "domain", "message": "attune_refresh_upgrade L%d refresh_charges 越域 [1,9]: %d" % [al, ach]})
|
||
var acost: int = int(row.get("keystone_cost", -1))
|
||
if acost < 1 or acost > 999:
|
||
errs.append({"category": "domain", "message": "attune_refresh_upgrade L%d keystone_cost 越域 [1,999]: %d" % [al, acost]})
|
||
for i in attune_refresh_upgrade.size():
|
||
var al_at: int = int(attune_refresh_upgrade[i].get("level", 0))
|
||
if al_at != i + 1:
|
||
errs.append({"category": "structural", "message": "attune_refresh_upgrade level 不连续(须从 1 连续递增): 位 %d = %d" % [i + 1, al_at]})
|
||
break
|
||
return errs
|