Files
gplan-2/game/data/schemas/status_effect_table.gd
T

79 lines
3.5 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
## 增益状态表 schema:逐 effect_id 行的类型化读取(垂直切片验证:完整战斗逐行归因)。
## validate() 违例加载期致命(fail-fast);表运行期只读,调参只走 data/tables 表值。
class_name StatusEffectTable
extends Resource
@export var rows: Array[Dictionary] = [] # Array[Dictionary]
const TARGET_SIDES := ["hero", "enemy"]
const UNITS := ["percent", "flat", "ac"] # ac——AC 阈值轴效果(ac_up),非池百分比非定点值
const STACK_POLICIES := ["stack", "accumulate", "independent"]
func validate() -> Array:
var errs: Array[Dictionary] = []
if rows.is_empty():
errs.append({"category": "empty_table", "message": "StatusEffectTable 为空"})
return errs
var seen := {}
for row in rows:
var head := _validate_row_head(row, seen)
errs.append_array(head["errs"])
if not head["ok"]:
continue
var eid: String = head["eid"]
errs.append_array(_validate_magnitude_domain(row, eid, head["unit"]))
var dur: int = int(row.get("duration_settlements", 0))
if dur < 1 or dur > 99:
errs.append({"category": "domain", "message": "%s duration_settlements 越域 [1,99]: %d" % [eid, dur]})
var ms: int = int(row.get("max_stack", 0))
if ms < 1 or ms > 16:
errs.append({"category": "domain", "message": "%s max_stack 越域 [1,16]: %d" % [eid, ms]})
return errs
## 行头域:effect_id 非空与查重/display_name/target_side/unit/stack_policy 词表
func _validate_row_head(row: Dictionary, seen: Dictionary) -> Dictionary:
var errs: Array[Dictionary] = []
var eid: String = row.get("effect_id", "")
if eid == "":
errs.append({"category": "domain", "message": "effect_id 缺失/空"})
return {"errs": errs, "eid": eid, "unit": "", "ok": false}
if seen.has(eid):
errs.append({"category": "dup_key", "message": "effect_id 重复: %s" % eid})
seen[eid] = true
return {"errs": errs, "eid": eid, "unit": "", "ok": false}
seen[eid] = true
if String(row.get("display_name", "")) == "":
errs.append({"category": "domain", "message": "%s display_name 空" % eid})
if not TARGET_SIDES.has(row.get("target_side", "")):
errs.append({"category": "enum", "message": "%s target_side 出域" % eid})
var unit: String = row.get("unit", "")
if not UNITS.has(unit):
errs.append({"category": "enum", "message": "%s unit 出域" % eid})
if not STACK_POLICIES.has(row.get("stack_policy", "")):
errs.append({"category": "enum", "message": "%s stack_policy 出域" % eid})
return {"errs": errs, "eid": eid, "unit": unit, "ok": true}
## 幅度量纲域(三段量纲判据——percent/flat/ac 各自值域;
## ac = AC 阈值轴效果,非池百分比非定点值——幅度域独立,防呆上限 20)
func _validate_magnitude_domain(row: Dictionary, eid: String, unit: String) -> Array[Dictionary]:
var errs: Array[Dictionary] = []
var m: int = int(row.get("magnitude", 0))
if unit == "percent" and (m == 0 or m < -100 or m > 100):
errs.append({"category": "cross_field", "message": "%s percent magnitude 域错: %d" % [eid, m]})
if unit == "flat" and m < 1:
errs.append({"category": "cross_field", "message": "%s flat magnitude 须 ≥1: %d" % [eid, m]})
if unit == "ac" and (m == 0 or m < -20 or m > 20):
errs.append({"category": "cross_field", "message": "%s ac magnitude 域错([-20,20] 且 ≠0): %d" % [eid, m]})
return errs
func row_by_id(effect_id: String) -> Dictionary:
for row in rows:
if row.get("effect_id", "") == effect_id:
return row
return {}