Files
gplan-2/game/core/config_db_resolver.gd
T
DKChan 9a72394652 chore(代码卫生): 头注存量清偿批——82 文件按两类白名单改写为 ## 文档注释载体
按 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)
2026-10-16 23:28:07 +08:00

119 lines
5.2 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
## R1 难度行解析协作类:进度坐标 ceil 取行、越域 Fatal、告警去重,由 ConfigDb 门面持有(垂直切片验证:数值缺行不静默)。
## 非直调面——全部消费方经 ConfigDb 同名方法取数;数据面与诊断通道均经构造注入 Callable(类型环断根)。
class_name ConfigDbResolver
extends RefCounted
var _diag: Callable # 诊断/致命通道(迭代 27 T6——门面类型反持解耦,validator 先例:签名 (level, category, message))
var _board_gen_rows_get: Callable # () -> Array——board_gen 行集活读(数据面经 Callable 注入,ConfigDb 类型环断根)
var _enemy_rows_get: Callable # () -> Array——enemy 行集活读
var _difficulty_get: Callable # () -> DifficultyTable(可空——表缺省合法态)
var _warn_dedup: Dictionary[String, bool] = {} # R1 四元组去重注册表(自 ConfigDb 迁入)
func _init(diag_cb: Callable, board_gen_rows_cb: Callable,
enemy_rows_cb: Callable, difficulty_cb: Callable) -> void:
_diag = diag_cb
_board_gen_rows_get = board_gen_rows_cb
_enemy_rows_get = enemy_rows_cb
_difficulty_get = difficulty_cb
# 去重注册表清空(门面 load_tables / reset_diagnostics 调用——与拆分前清空时点逐位一致)
func reset_warn_dedup() -> void:
_warn_dedup.clear()
# ---- R1 难度行解析(2026-09-18 用户拍板修订:ceil 向上取整保证偏难;域越界与内容缺口 Fatal 退出)----
func resolve_board_gen(L: int, D: int) -> Dictionary:
return _resolve_progress(_board_gen_rows_get.call(), L, D, "board_gen")
func resolve_enemy_rowset(L: int, D: int) -> Array[Dictionary]:
# 行集数组形态(2026-10-07 敌人表行集多行批——原单行 Dictionary 退役):ceil 命中 (l*,d*) 后
# 返回该坐标全部行、按表文件行序(行序即契约——同坐标多行文件内相邻由 EnemyTable.validate 兜底)。
# 空集表达 = 空数组(生产表下 ceil 命中坐标恒有行,空集仅表空时可达——validate 已拦)。
return _resolve_progress(_enemy_rows_get.call(), L, D, "enemy", true)
# 难度曲线与Boss DifficultyTable 消费面(敌人系统.spawn 调用):(L,D) 精确匹配修饰乘数,越域值 clamp(GDD Edge Case——组合事故非配置事故)
func resolve_difficulty_modifiers(L: int, D: int) -> Dictionary:
var dt = _difficulty_get.call()
if dt == null:
return {}
for row in dt.rows:
if int(row.get("level_index", 0)) == L and int(row.get("node_depth", -1)) == D:
return {
"hp_mult": clampf(float(row.get("hp_mult", 1.0)), 0.1, 10.0),
"atk_mult": clampf(float(row.get("atk_mult", 1.0)), 0.1, 10.0),
}
return {}
func _resolve_progress(rows: Array, L: int, D: int, table_id: String, return_all := false) -> Variant:
if L < 1 or D < 0:
_diag.call("fatal", "request_oob", "%s 请求越域 (%d,%d)——进度坐标低于合法域(关卡序号≥1、节点深度≥0)" % [table_id, L, D])
return {}
var level_keys: Array[int] = []
for row in rows:
var lv := int(row.get("level_index", 0))
if not level_keys.has(lv):
level_keys.append(lv)
if level_keys.is_empty():
_diag.call("fatal", "structural", "%s 行集为空——锚行校验应已拦截" % table_id)
return {}
level_keys.sort()
var l_star := _ceil_key(level_keys, L)
var l_clamped := l_star < 0
if l_clamped:
l_star = int(level_keys[-1]) # 超出最大行 → 取最大行封顶(2026-09-18 追加拍板:可取范围内向上取整,超出用最大值)
var depth_keys: Array[int] = []
for row in rows:
if int(row.get("level_index", 0)) == l_star:
var dv := int(row.get("node_depth", 0))
if not depth_keys.has(dv):
depth_keys.append(dv)
depth_keys.sort()
var d_star := _ceil_key(depth_keys, D)
var d_clamped := d_star < 0
if d_clamped:
d_star = int(depth_keys[-1])
var missing := ""
if l_clamped and d_clamped:
missing = "both_clamp"
elif l_clamped:
missing = "level_clamp"
elif d_clamped:
missing = "depth_clamp"
elif l_star != L and d_star != D:
missing = "both_ceil"
elif l_star != L:
missing = "level_ceil"
elif d_star != D:
missing = "depth_ceil"
if missing != "":
var dedup_key := "%s|%s|%d|%d" % [table_id, missing, l_star, d_star]
if not _warn_dedup.has(dedup_key):
_warn_dedup[dedup_key] = true
var verb := "clamp 解析(超出最大行取最大值)" if missing.contains("clamp") else "ceil 解析(向上取整保证偏难)"
_diag.call("warning", "resolve_" + missing, "%s 请求 (%d,%d) %s → (%d,%d) [%s]——2026-09-18 拍板" % [table_id, L, D, verb, l_star, d_star, missing])
if return_all:
var all_out: Array[Dictionary] = []
for row in rows:
if int(row.get("level_index", 0)) == l_star and int(row.get("node_depth", 0)) == d_star:
all_out.append(row)
return all_out
for row in rows:
if int(row.get("level_index", 0)) == l_star and int(row.get("node_depth", 0)) == d_star:
return row
return {}
# 取 sorted_keys 中第一个 >= request 的键;无(请求高于最大行)返回 -1 → 调用方 Fatal
func _ceil_key(sorted_keys: Array, request: int) -> int:
for k in sorted_keys:
if int(k) >= request:
return int(k)
return -1