Files
gplan-2/game/core/config_db_resolver.gd
T

109 lines
4.7 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
# Date: 2026-10-02(code-quality 修复批 T5——ConfigDb 拆分:R1 难度行解析协作类,自 config_db.gd 迁出)
# 职责单一化(R1 解析域):resolve_board_gen / resolve_enemy_rowset / resolve_difficulty_modifiers
# 及其私有算术(_resolve_progress / _ceil_key)与 R1 专属的告警去重注册表。ConfigDb autoload 门面
# 保持——全部消费方(战斗结算/敌人系统/棋盘生成/呈现层/冒烟)经门面同名方法取数,公有签名零变化。
# 诊断通道归门面:push_diag / _fatal 经 _db 引用回呼(协作类同仓内部通道——不另设公共出口,
# 行为与拆分前逐位一致,含越域 Fatal 退出语义)。
# 迁移注记:_warn_dedup 去重注册表随解析逻辑同迁(唯一消费方 = _resolve_progress)——
# 门面 load_tables / reset_diagnostics 经 reset_warn_dedup() 同步清空,清空时点零变化。
# 实现 GDD:design/archive/gdd-2026-09-14/d2-data-config.md(系统 ID D2·数据配置——registry 追溯锚)
class_name ConfigDbResolver
extends RefCounted
var _db: ConfigDb # 门面引用(表读取 + 诊断/致命通道——_init 注入)
var _warn_dedup: Dictionary[String, bool] = {} # R1 四元组去重注册表(自 ConfigDb 迁入)
func _init(db_ref: ConfigDb) -> void:
_db = db_ref
# 去重注册表清空(门面 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(_db.board_gen.rows, L, D, "board_gen")
func resolve_enemy_rowset(L: int, D: int) -> Dictionary:
return _resolve_progress(_db.enemy.rows, L, D, "enemy")
# 难度曲线与Boss DifficultyTable 消费面(敌人系统.spawn 调用):(L,D) 精确匹配修饰乘数,越域值 clamp(GDD Edge Case——组合事故非配置事故)
func resolve_difficulty_modifiers(L: int, D: int) -> Dictionary:
if _db.difficulty == null:
return {}
for row in _db.difficulty.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) -> Dictionary:
if L < 1 or D < 0:
_db._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():
_db._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 解析(向上取整保证偏难)"
_db.push_diag("warning", "resolve_" + missing, "%s 请求 (%d,%d) %s → (%d,%d) [%s]——2026-09-18 拍板" % [table_id, L, D, verb, l_star, d_star, missing])
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