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

105 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
# Validation Question: 三关连探冒险(地精洞窟 → 幽暗地域 → 灰矮人矿城)能否以一条命走完,通关兑付的
# 部分回血与提升三选一、Boss 逐杀钥石掉落在冒险摘要里成立(P0)
# Date: 2026-09-21(冒险结构实现批建表;2026-10-01 迭代 10 奖励重构批扩列——registry adventure_table 条目同批改写)
# 数据配置 AdventureTable schema(冒险结构 关卡大奖励行值;单行全局,Rule 4 豁免——HeroTable/SettlementTable 先例)。
# 迭代 10 重构(2026-09-30 用户拍板案丙):大奖励「固定三件套」退役——level_clear_hp_bonus(血回满+上限提升件)
# 与 keystone_per_level(钥石每关入账)两字段退役;改三层奖励框架 = 部分回血(clear_heal_pct)+ 提升三选一
# (池六种:件值/权重/次数上限三组列)+ Boss/精英击杀钥石掉落(行值归 meta.tres boss_keystone,不在本表)。
# 全部 knob provisional-pending-曲线调参批(数值所有权归 难度曲线与Boss,上调须重扫通关率带)。
class_name AdventureTable
extends Resource
## 三选一提升池件 id 词表(封闭——断点附随件与牌库剔除态依赖它;扩件走本表+registry 修订)
const BONUS_IDS: Array[String] = ["attack", "max_hp", "armor", "gp", "aux_item", "ap"]
## 无次数上限件的 cap 哨兵值(gp/aux_item——牌库恒非空的结构保证)
const BONUS_CAP_UNLIMITED := -1
# —— 通关部分回血(固定型,非末关通关兑付)——
@export var clear_heal_pct: int = 20 # [0,100] knob——回复生效上限的百分比,封顶上限不回满
# —— 三选一候选数(2026-10-02 修复批 T2 魔法数结构化:自 adventure_runner 抽签字面量 3 收口进表;
# 默认 3 = 现行行为零改动——加权洗牌不放回掷 N 的 N,改值须重扫三选一体验与牌库剔除节奏)——
@export var bonus_candidate_count: int = 3 # [1,6] knob——候选数上界受 BONUS_IDS 词表封闭约束
# —— 三选一件值(兑付面)——
@export var bonus_attack_flat: int = 1 # [0,999] knob——攻击轴累加(覆盖值通道)
@export var bonus_max_hp_flat: int = 5 # [0,999] knob——生命上限轴累加(不连带当前生命)
@export var bonus_armor_flat: int = 1 # [0,999] knob——护甲轴累加
@export var bonus_gp_amount: int = 20 # [0,999] knob——GP 袋定额入钱包
@export var bonus_ap_flat: int = 1 # [0,10] knob——AP 件每场战斗首轮行动点基线增量
@export var bonus_aux_item_count: int = 1 # [1,9] knob——魔法道具件授予件数(受同调位约束)
# —— 三选一权重(加权洗牌不放回,E-S weight-key)——
@export var bonus_weight_attack: int = 3 # [1,99] knob
@export var bonus_weight_max_hp: int = 3 # [1,99] knob
@export var bonus_weight_armor: int = 3 # [1,99] knob
@export var bonus_weight_gp: int = 3 # [1,99] knob
@export var bonus_weight_aux: int = 1 # [1,99] knob——魔法道具件(受同调位约束)
@export var bonus_weight_ap: int = 1 # [1,99] knob——AP 件(全冒险最紧上限)
# —— 全冒险获取次数上限(达上限件先剔出牌库;gp/aux_item 无上限)——
@export var bonus_cap_attack: int = 3 # [0,99] knob
@export var bonus_cap_max_hp: int = 3 # [0,99] knob
@export var bonus_cap_armor: int = 3 # [0,99] knob
@export var bonus_cap_ap: int = 2 # [0,99] knob——全冒险最紧
# —— 同调位过渡读数源(正主 = attunement_growth.tres 谓词表,同调实施批落地后切换)——
@export var transitional_sync_slots: int = 1 # [0,9] knob——道具持有上限
func bonus_value(id: String) -> int:
match id:
"attack": return bonus_attack_flat
"max_hp": return bonus_max_hp_flat
"armor": return bonus_armor_flat
"gp": return bonus_gp_amount
"ap": return bonus_ap_flat
"aux_item": return bonus_aux_item_count
return 0
func bonus_weight(id: String) -> int:
match id:
"attack": return bonus_weight_attack
"max_hp": return bonus_weight_max_hp
"armor": return bonus_weight_armor
"gp": return bonus_weight_gp
"aux_item": return bonus_weight_aux
"ap": return bonus_weight_ap
return 0
## 次数上限(gp/aux_item 返回 BONUS_CAP_UNLIMITED = 无上限,牌库恒非空的结构保证)
func bonus_cap(id: String) -> int:
match id:
"attack": return bonus_cap_attack
"max_hp": return bonus_cap_max_hp
"armor": return bonus_cap_armor
"ap": return bonus_cap_ap
return BONUS_CAP_UNLIMITED
func validate() -> Array:
var errs: Array[Dictionary] = []
if clear_heal_pct < 0 or clear_heal_pct > 100:
errs.append({"category": "domain", "message": "clear_heal_pct 越域 [0,100]: %d" % clear_heal_pct})
for id in BONUS_IDS:
var v := bonus_value(id)
if v < 0 or v > 999:
errs.append({"category": "domain", "message": "bonus_value(%s) 越域 [0,999]: %d" % [id, v]})
var w := bonus_weight(id)
if w < 1 or w > 99:
errs.append({"category": "domain", "message": "bonus_weight(%s) 越域 [1,99]: %d" % [id, w]})
for id in ["attack", "max_hp", "armor", "ap"]:
var c := bonus_cap(id)
if c < 0 or c > 99:
errs.append({"category": "domain", "message": "bonus_cap(%s) 越域 [0,99]: %d" % [id, c]})
if bonus_aux_item_count < 1 or bonus_aux_item_count > 9:
errs.append({"category": "domain", "message": "bonus_aux_item_count 越域 [1,9]: %d" % bonus_aux_item_count})
if bonus_candidate_count < 1 or bonus_candidate_count > BONUS_IDS.size():
errs.append({"category": "domain", "message": "bonus_candidate_count 越域 [1,%d]: %d" % [BONUS_IDS.size(), bonus_candidate_count]})
if transitional_sync_slots < 0 or transitional_sync_slots > 9:
errs.append({"category": "domain", "message": "transitional_sync_slots 越域 [0,9]: %d" % transitional_sync_slots})
return errs