Files
gplan-2/game/data/schemas/adventure_table.gd
T
DKChan a33ddaf542 秘宝六件迁移+掘进蓄能受理闸数据化+令牌兑付 match 收敛进效果类型(T4+T5——内容数据驱动扩展批)
T4 秘宝侧(六件按 id 硬编码全部拆除,行为与迁移前逐位一致):
- 淬毒刃纹:begin_battle attune_venom 注入+伤害控制器特判分支拆除——行 triggers clamp_check
  modify(mode:clamp_bonus) 双订阅(pierce_vs_ward / magic_vs_heavy eq 行=旧「pierce|magic × 矩阵>0」
  的精确集;mode 路由=主角攻击面专享,棋盘克制窗只消费无模式 delta——棋盘不吃毒面保持)。
- 偏运硬币:reward_economy.luck_bias 注入拆除——行 triggers reward_roll bias_rewards 订阅,
  发射点命中合计经 _biased_cell_rows 入参(合成序「图级先件级后」不变);冒烟偏斜段断言面随迁。
- 工兵晨令:编排器两处直调入队拆除——行 triggers round_start grant_ap(mode:queue) 订阅,
  when round_index ≤ effective_rounds(when value_from 行字段定影——新查询面,悬空校验同面补齐)。
- 惊巢反制:_grant_routed 按 id 减半特判拆除——mine_hit damage_mult(50) 订阅命中经 halve_pct
  入参(ceil(power×50%) 与旧 ceil(power/2) 逐位一致)+ open_ticket(channel:reflect) 订阅施加。
- 标中殉爆:flag_hit 按 id 开单特判拆除——行 triggers open_ticket(channel:blast, value_from
  magnitude) 订阅施加(施加位=迁移前开单位:殉爆→净化→图谱)。
- 掘进蓄能:use_treasure 按 id 受理闸特判拆除——treasure_used counter_spend 订阅施加(消耗成功
  才受理、积点不足拒绝零消耗,进度文案逐字保留);积点账本迁效果引擎计数器 dig_charge_bank
  (模判定留编排器侧:「每 N 格积 1 点」在发射点施加架构下无法行内表达先增后判——when 于
  dispatch 预评估,逐位等价优先;词汇表边界注记留档,遗留观察项随出口报告呈报)。
- pick_refresh:adventure_runner 按 id 特判拆除——effect_kinds bonus_refresh kind 分发查询
  (装配集行 magnitude 合计;刷新件类加件零 id 分支)。
- 主动件 kind 词族换代(reveal_tiles/preview/grant_ap/remove_mines/refresh_pick)挂账保留:
  本批只要求 pick_refresh 合流;全词族 rename 波及库存/呈现/单测零行为收益,不随批(出口报告
  遗留人闸项呈报)。
- curio_interact_controller 秘宝卡片文案表值化:kind 硬编码映射拆除,读行 desc——13 件 desc
  补齐(措辞按现行卡片文本逐字迁移;掘进蓄能/失义件补实际摘要=文案微调呈报级)。
- schema 适配:triggers 与 effect_kinds 互斥校验收窄至 passive 行(active_charged 双形合法=
  effect_kinds 主动分发+triggers 受理闸);trigger 行豁免「非 N 值 kind magnitude 应 0」与
  「非 ap_rounds_front 行 effective_rounds 应 0」两面(行字段=value_from 取数源)。

T5 令牌/树收尾:
- _apply_curio_pick match 收敛进效果类型:属性值提升四类(attack/max_hp/armor/ap)改
  adventure_table.CURIO_APPLY_ROUTES 声明路由(加算落点键,与效果引擎加法族同构)——加新加算类
  令牌=表行+配额/件值键零代码;gp/heal/refresh/relic 副作用通道面显式分支保留。
- meta_tree 规则键同面:先手压制/稳健拓荒两键已在 T3/T4 随 round_start/damage_taken 订阅行
  走效果引擎同面(rebuild 合成订阅+发射点施加),旧直调零残留。

验证:冒烟 800 项 0 失败(三闸过)· 单元 17 套全绿。

设计权威:design/research/研究-内容数据驱动扩展架构-2026-10-06.md(案乙)。
任务书:design/research/任务书-内容数据驱动扩展批-2026-10-06.md §六 T4/T5、§五映射表秘宝侧。
2026-10-06 23:54:58 +08:00

178 lines
12 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 奖励重构批扩列;2026-10-03 TP0 令牌池换代)
# 数据配置 AdventureTable schema(冒险结构 关卡大奖励行值;单行全局,Rule 4 豁免——HeroTable/SettlementTable 先例)。
# 迭代 10 重构(2026-09-30 用户拍板案丙):大奖励「固定三件套」退役——改三层奖励框架。
# TP0 令牌池换代(2026-10-03 用户全裁 b——node-reward v2.2):三选一池改固定配额令牌池——普通 70/稀有 25/
# 罕见 5=100 张;洗牌不放回抽 3、选中踢池未选回池、池耗即枯竭;种类次数上限退役(池消耗即上限)。
# 档位构成:普通〔小GP 18/小增伤 18/小护甲 17/小生命 17〕+稀有〔大GP/大增伤/大护甲/大生命/恢复 各 5〕
# +罕见〔AP 3〕——罕见档原列「道具件 2」随 treasure_item 池种退役(迭代 11 第①批 T7)不投放,配额缺省收窄。
# 恢复件=新入池种类(当即回血)。旧权重/次数上限字段整代退役。
# 全部 knob provisional-pending-曲线调参批(数值所有权归 难度曲线与Boss,上调须重扫通关率带)。
class_name AdventureTable
extends Resource
## 概念指路:本表的属性值提升与资源,与 feats.tres 的专长,同属一个对象——
## 「奇物」(一次冒险内各渠道给予玩家的增益总称)。定义见 design/gdd/systems/冒险循环/奇物.md。
## 它们是它的分类轴上的枚举(专长 / 属性值提升 / 资源),不是三套系统;
## 本表承载属性值提升与资源的种类配额与件值。
## (2026-10-05 命名统一 + v2.0 改名:旧称「数值件」→ 属性提升;顶层「特性」→「奖励」→「奇物」。
## 常量与字段随之前缀 curio_*,**尚未**随顶层改名换到 reward_*——见 06-待办清单。
## 分类轴三个枚举:属性值提升〔生命上限 / AC / 攻击〕;资源〔行动点上限 /
## 刷新次数 / 金币 / 回复,命名待定〕——本表两类混编;刷新次数与专长获取两项尚未入表。
## 类内异质性:金币与回复是即时兑付,不进持有集、不持续生效。)
## 三选一提升池 kind 词表(封闭——断点附随件与牌库剔除态依赖它;扩件走本表+registry 修订)。
## treasure_item 池种退役(迭代 11 第①批 T7——同调批出池);heal 恢复件新入池(v2.2 令牌池追认 b)。
const CURIO_KINDS: Array[String] = ["attack", "max_hp", "armor", "gp", "ap", "heal", "refresh"] # T6 扩第七类(refresh=资源类成员——作为奇物授予的三选一重抽次数,作用对象=三选一界面非角色;见 registry refresh_boundary)
## 令牌档位词表(v2.2 三档位——稀有度命名对齐 MC 策略判读序 316-f:1 级最稀有=rarest 优先)
const TIERS: Array[String] = ["common", "rare", "rarest"]
const TIER_COMMON := "common"
const TIER_RARE := "rare"
const TIER_RAREST := "rarest"
## 档位配额结构锚(v2.2 追认 b 定稿——validate() 硬断言;改总量=重裁非调参)。
## 罕见档 5→3:原「道具件 2」席位随 treasure_item 池种退役(迭代 11 第①批 T7,落地晚于追认 b)收窄,
## 池总量 100→98——TP0 台账自决+人工清单披露项。
const TIER_QUOTAS := {"common": 70, "rare": 25, "rarest": 3}
# —— 通关部分回血(固定型,非末关通关兑付)——
@export var clear_heal_pct: int = 20 # [0,100] knob——回复生效上限的百分比,封顶上限不回满
# —— 三选一候选数(2026-10-02 修复批 T2 魔法数结构化)——
@export var curio_candidate_count: int = 3 # [1,6] knob——令牌洗牌不放回抽取张数上界
@export var shop_refresh_free: int = 0 # [0,9] knob(MC-1 provisional——进店免费刷新次数;基础 0=Q2 裁,天赋增益位预留)
@export var shop_refresh_cost_base: int = 20 # [1,999] knob(MC-1 provisional——GP 刷新基价)
@export var shop_refresh_cost_curve: float = 1.8 # [1.0,4.0] knob(MC-1 provisional——按已付费刷新数幂曲线,A 链同族)
# —— 令牌配额(kind × tier 计数;未列组合 = 0——heal 只入稀有/ap 只入罕见,v2.2 档位构成)——
@export var curio_quota_attack_common: int = 18 # [0,99]
@export var curio_quota_attack_rare: int = 5 # [0,99]
@export var curio_quota_max_hp_common: int = 17 # [0,99]
@export var curio_quota_max_hp_rare: int = 5 # [0,99]
@export var curio_quota_armor_common: int = 17 # [0,99]
@export var curio_quota_armor_rare: int = 5 # [0,99]
@export var curio_quota_gp_common: int = 18 # [0,99]
@export var curio_quota_gp_rare: int = 5 # [0,99]
@export var curio_quota_heal_rare: int = 3 # [0,99]——恢复件(原 5;T6 挤占 2 席位予 refresh——用户 2026-10-05 裁方案B,总量 98 锚不变)
@export var curio_quota_refresh_rare: int = 2 # [0,99]——刷新次数件(T6 新入池资源类成员;provisional 归曲线调参批)
@export var curio_quota_ap_rarest: int = 3 # [0,99]——AP 件(罕见档;道具件 2 席位随池种退役收窄)
# —— 令牌件值(小/大数值对——v2.2 追认 b 定稿:20/50、+1/+2、+1/+2、+5/+10、恢复+6、AP+1)——
@export var curio_value_attack_common: int = 1 # [0,999] knob——小增伤
@export var curio_value_attack_rare: int = 2 # [0,999] knob——大增伤
@export var curio_value_max_hp_common: int = 5 # [0,999] knob——小生命
@export var curio_value_max_hp_rare: int = 10 # [0,999] knob——大生命
@export var curio_value_armor_common: int = 1 # [0,999] knob——小护甲
@export var curio_value_armor_rare: int = 2 # [0,999] knob——大护甲
@export var curio_value_gp_common: int = 20 # [0,999] knob——小GP
@export var curio_value_gp_rare: int = 50 # [0,999] knob——大GP
@export var curio_value_heal_rare: int = 6 # [0,999] knob——恢复(当即回血,封顶生效上限)
@export var curio_value_refresh_rare: int = 1 # [0,9] knob(provisional)——刷新次数件兑付值(三选一重抽次数 +N——_attune_refresh_x 增量,不进加算区)
@export var curio_value_ap_rarest: int = 1 # [0,10] knob——AP 件每场战斗首轮行动点基线增量
# —— 专长获取门票(迭代 15 卡② T5——非 Boss 渠道的专长入口形态,奇物.md v2.7 渠道轴定位;
# 四口径契约④:拿到即开不可囤积/罕见只在概率不在价格/一局限购一次/计步保底连续 5 展示未出
# 第 6 必出(计数=展示次数、刷新重展计入、节点与商店共享、触发清零、限购满不再触发)。
# 四参数全部 provisional 归曲线调参批;limit/pity_step 系口径定死值调参批可复议)——
@export var feat_ticket_chance: int = 20 # [0,100] knob(provisional)——每次非 Boss 渠道展示门票出现概率 %
@export var feat_ticket_quota: int = 2 # [0,9] knob(provisional)——每局门票出现次数上限
@export var feat_ticket_limit: int = 1 # [1,9] knob(口径定死=1)——一局限购(选中/买下)次数
@export var feat_ticket_pity_step: int = 5 # [1,99] knob(口径定死=5)——保底步数(连续未出展示次数)
## 令牌兑付路由表(内容数据驱动扩展批 T5——_apply_curio_pick match 收敛进效果类型:
## 属性值提升四类 = 「加算落点键」声明路由,加新加算类令牌 = 表行+配额/件值键,零代码;
## 通道面三类(gp 钱包/heal 台账/refresh 界面余量)+relic 持有集 = 副作用通道显式分支不进本表
## ——路由表只承载「纯加算落点」形态,与效果引擎组合规则加法族同构)
const CURIO_APPLY_ROUTES := {
"attack": "atk",
"max_hp": "max_hp",
"armor": "armor_class",
"ap": "ap",
}
## 令牌加算路由读数(空 = 非加算形态——调用方走通道面分支)
func curio_apply_route(kind: String) -> String:
return String(CURIO_APPLY_ROUTES.get(kind, ""))
## 令牌配额读数(未列 kind×tier 组合 = 0——heal 无普通档/ap 无普通稀有档按 v2.2 构成)
func curio_quota(kind: String, tier: String) -> int:
match [kind, tier]:
["attack", TIER_COMMON]: return curio_quota_attack_common
["attack", TIER_RARE]: return curio_quota_attack_rare
["max_hp", TIER_COMMON]: return curio_quota_max_hp_common
["max_hp", TIER_RARE]: return curio_quota_max_hp_rare
["armor", TIER_COMMON]: return curio_quota_armor_common
["armor", TIER_RARE]: return curio_quota_armor_rare
["gp", TIER_COMMON]: return curio_quota_gp_common
["gp", TIER_RARE]: return curio_quota_gp_rare
["heal", TIER_RARE]: return curio_quota_heal_rare
["refresh", TIER_RARE]: return curio_quota_refresh_rare
["ap", TIER_RAREST]: return curio_quota_ap_rarest
return 0
## 令牌件值(kind × tier;v2.2 数值对——小/大两档)
func curio_value(kind: String, tier: String = TIER_COMMON) -> int:
match [kind, tier]:
["attack", TIER_COMMON]: return curio_value_attack_common
["attack", TIER_RARE]: return curio_value_attack_rare
["max_hp", TIER_COMMON]: return curio_value_max_hp_common
["max_hp", TIER_RARE]: return curio_value_max_hp_rare
["armor", TIER_COMMON]: return curio_value_armor_common
["armor", TIER_RARE]: return curio_value_armor_rare
["gp", TIER_COMMON]: return curio_value_gp_common
["gp", TIER_RARE]: return curio_value_gp_rare
["heal", TIER_RARE]: return curio_value_heal_rare
["refresh", TIER_RARE]: return curio_value_refresh_rare
["ap", TIER_RAREST]: return curio_value_ap_rarest
return 0
## 档位判读序(MC 策略 316-f——1 级最稀有:rarest > rare > common;并列同档取最左由调用方稳定序保证)
func tier_rank(tier: String) -> int:
match tier:
TIER_RAREST: return 3
TIER_RARE: return 2
TIER_COMMON: return 1
return 0
## 档位令牌总数(货架/校验读面)
func tier_total(tier: String) -> int:
var total := 0
for kind in CURIO_KINDS:
total += curio_quota(kind, tier)
return total
## 牌库总量(结构锚——罕见档随道具件退役收窄后 98 张)
func deck_total() -> int:
return tier_total(TIER_COMMON) + tier_total(TIER_RARE) + tier_total(TIER_RAREST)
func validate() -> Array:
var errs: Array[Dictionary] = []
for kv in [["feat_ticket_chance", feat_ticket_chance, 0, 100], ["feat_ticket_quota", feat_ticket_quota, 0, 9], ["feat_ticket_limit", feat_ticket_limit, 1, 9], ["feat_ticket_pity_step", feat_ticket_pity_step, 1, 99]]:
if int(kv[1]) < int(kv[2]) or int(kv[1]) > int(kv[3]):
errs.append({"category": "domain", "message": "%s 出域 [%d,%d]: %d" % [kv[0], kv[2], kv[3], kv[1]]})
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 kind in CURIO_KINDS:
for tier in TIERS:
var c := curio_quota(kind, tier)
if c < 0 or c > 99:
errs.append({"category": "domain", "message": "token_count(%s,%s) 越域 [0,99]: %d" % [kind, tier, c]})
var v := curio_value(kind, tier)
if v < 0 or v > 999:
errs.append({"category": "domain", "message": "curio_value(%s,%s) 越域 [0,999]: %d" % [kind, tier, v]})
for tier in TIERS:
var total := tier_total(tier)
if total != int(TIER_QUOTAS.get(tier, -1)):
errs.append({"category": "domain", "message": "档位配额结构失锚(v2.2 追认 b——%s 应=%d 实=%d;改总量须重裁)" % [tier, int(TIER_QUOTAS.get(tier, -1)), total]})
if curio_candidate_count < 1 or curio_candidate_count > 6:
errs.append({"category": "domain", "message": "curio_candidate_count 越域 [1,6]: %d" % curio_candidate_count})
return errs