feat(迭代23-T2): 两根类型轴所有权移交——hero.tres 两字段删除+ForgeTable 默认值常驻持有+单位快照改读注入面

- hero.tres:armor_type/attack_type 两字段删除(含 2026-09-18 前置批登记注记退役);armor_class=10 保留为甲路线缺失兜底基准
- hero_table.gd schema:两 @export 字段与枚举校验同步删除(三数值轴 max_hp/atk/armor_class)
- unit_container.gd:spawn 签名 +2(hero_attack_type/hero_armor_type,空串=db.forge_default_* 回退)——三参旧调用方零适配,行为逐位连续(normal/light)
- smoke_all.gd::1901 hero_attack 行类型键主语换代为 forge_default_attack_type();新增 _smoke_forge_axes 段(V5 前半:字段不在位+默认值+零注入回退快照)4 断言
- 轻闸:冒烟 902/0(898 基线 +4)+run_all 23 套全绿
This commit is contained in:
DKChan committed 2026-10-12 23:31:50 +08:00
1 parent df666ddf30
commit 00d98b6f74
4 files changed
+40 -21

No files matched your search

+5 -3
View File
@@ -10,7 +10,8 @@
# (pattern 环数组 + steps 指针 + heavy_multiplier)随技能池整体退役——拍结构保留(每结算每存活敌恰行动一次、
# 行序、先作用后推进),"轮到什么"改由开轮摇号决定(死亡即不动手:摇定后兑现前死亡 → 本拍作废、不 commit)。
# 切片登记接口漂移:heal() 为切片新增(战斗结算 治疗 clamp 需要写入口);spawn 签名 +3 参数(E4/区间批/
# 遭遇骰——正式侧 GDD/registry 修订随对应批)。
# 遭遇骰——正式侧 GDD/registry 修订随对应批);迭代 23 T2 +2 参数(hero_attack_type/hero_armor_type——
# 两根类型轴注入面:hero.tres 静态表两轴删除〔契约 2 所有权移交〕,空串=锻造工坊配置默认值回退)。
# 实现 GDD:design/gdd/systems/战斗循环/敌人系统.md(registry 追溯锚,命名规范见 CLAUDE.md)
class_name UnitContainer
extends RefCounted
@@ -44,7 +45,8 @@ func _init(db_ref: ConfigDb) -> void:
# 逐行实例化、生成序 = 文件行序(行序即契约,敌人系统 v0.15);行集实例总数(各行传入数量求和)
# ≤ ENEMY_ROWSET_INSTANCE_MAX 守卫 fail-fast。
func spawn(level_index: int, node_depth: int, hero_hp: int, unit_count_overrides: Array = [],
atk_override: int = -1, max_hp_override: int = -1, enemy_atk_overrides: Array = []) -> bool:
atk_override: int = -1, max_hp_override: int = -1, enemy_atk_overrides: Array = [],
hero_attack_type: String = "", hero_armor_type: String = "") -> bool:
if _spawned:
push_warning("[敌人系统] Alive 相位重复 spawn(相位守卫)")
return false
@@ -61,7 +63,7 @@ func spawn(level_index: int, node_depth: int, hero_hp: int, unit_count_overrides
return false
# max_hp = 生效上限(非入参 hero_hp)——2026-09-11 关卡扩展批修复:跨战斗携带 HP 时上限不得压扁
# (恢复点/治疗包的满血守卫与治疗上限随之失效——切片登记接口语义澄清)
_hero = {"hp": hero_hp, "max_hp": eff_max_hp, "atk": eff_atk, "is_hero": true, "alive": true, "display_name": "探险者", "enemy_id": "hero", "armor_type": String(db.hero.get("armor_type")) if db.hero.get("armor_type") else "light", "attack_type": String(db.hero.get("attack_type")) if db.hero.get("attack_type") else "normal"} # 护甲/攻击类型轴快照(2026-09-18 营地扩展前置批——可配置;甲效矩阵消费面)
_hero = {"hp": hero_hp, "max_hp": eff_max_hp, "atk": eff_atk, "is_hero": true, "alive": true, "display_name": "探险者", "enemy_id": "hero", "armor_type": hero_armor_type if hero_armor_type != "" else db.forge_default_armor_type(), "attack_type": hero_attack_type if hero_attack_type != "" else db.forge_default_attack_type()} # 护甲/攻击类型轴快照(迭代 23 T2——hero.tres 两轴删除后改读注入值,空串回退锻造工坊配置默认值 normal/light=行为连续;甲效矩阵消费面)
_enemies.clear() # 难度曲线与Boss DifficultyTable 修饰(2026-09-12 结构位兑现):施加于行值、行值快照之前——MVP 空表 = 恒 1.0 无行为(AC-10);混编行集内全部敌种同乘((L,D) 精确匹配一次取值——F9 同乘不改变异,敌人系统 v0.15)
var mod: Dictionary = db.resolve_difficulty_modifiers(level_index, node_depth)
var hp_mult: float = float(mod.get("hp_mult", 1.0))
+3 -6
View File
@@ -3,14 +3,15 @@
# Date: 2026-09-10
# 数据配置 HeroTable schema(敌人系统 接口漂移新增;单行全局,Rule 4 豁免)。
# atk = 基础攻击恒存在(2026-09-11 用户裁决):域 [1,999]、0 = 加载拒绝——零基线死锁 schema 层杜绝。
# 〔2026-10-12 迭代 23 锻造工坊实装批 T2:armor_type/attack_type 两根类型轴字段删除——契约 2
# 所有权移交,默认值归锻造工坊配置(forge.tres)常驻持有、选中态写存档经参数面注入;本表只剩
# 三数值轴 max_hp/atk/armor_class(armor_class=甲路线缺失时兜底基准,甲型基础 AC 归 forge.tres 行)。〕
class_name HeroTable
extends Resource
@export var max_hp: int = 50 # [1,999] knob(provisional,溯源 = 原型锚)
@export var atk: int = 6 # [1,999] knob——基础攻击(溯源 = 概念原型 HERO_BASE_ATK,provisional 归 难度曲线与Boss);消费面 = 战斗结算·战斗段先手攻击
@export var armor_class: int = 10 # [0,999] knob——防守方护甲等级基准(2026-09-16 护甲等级掷点批,暂定 10 归 难度曲线与Boss);消费面 = 战斗结算掷点判定阈值基数(ac_up 效果加算其上)
@export var armor_type: String = "light" # enum {light, ward, heavy}——主角护甲类型轴(2026-09-18 营地扩展前置批:可配置可修改;缺省 light 向后兼容);消费面 = 战斗结算甲效矩阵(现行敌方攻击恒 normal 档 = 数值中性的结构位)
@export var attack_type: String = "normal" # enum {normal, pierce, magic}——主角基础攻击类型轴(2026-09-18 营地扩展前置批:基础攻击量(atk)与攻击类型抽象分离——营地永久强化换攻击类型 = 改此字段,量轴不动);消费面 = 战斗结算·战斗段基础分量查甲效矩阵
func validate() -> Array:
@@ -21,8 +22,4 @@ func validate() -> Array:
errs.append({"category": "domain", "message": "atk 越域 [1,999]: %d" % atk})
if armor_class < 0 or armor_class > 999:
errs.append({"category": "domain", "message": "armor_class 越域 [0,999]: %d" % armor_class})
if not ["light", "ward", "heavy"].has(armor_type):
errs.append({"category": "enum", "message": "armor_type 出域 {light, ward, heavy}: %s" % armor_type})
if not ["normal", "pierce", "magic"].has(attack_type):
errs.append({"category": "enum", "message": "attack_type 出域 {normal, pierce, magic}: %s" % attack_type})
return errs
+9 -9
View File
@@ -7,8 +7,12 @@ script = ExtResource("1")
max_hp = 26
atk = 2
armor_class = 10
armor_type = "light"
attack_type = "normal"
; 〔2026-10-12 迭代 23 锻造工坊实装批 T2——两根类型轴删除(契约 2 所有权移交):armor_type/
; attack_type 两字段随本批从静态表删除,默认值归锻造工坊配置常驻持有(forge.tres
; default_attack_type=normal/default_armor_type=light),选中态写存档域 forge_routes、冒险开始
; 经参数面注入;单位快照读取面改读注入值(缺省回退锻造配置默认值——行为连续)。原 2026-09-18
; 营地扩展前置批「两根可配置轴」登记随字段删除退役,历史记载归 git 考古。〕
; 数值压缩批(2026-09-17 用户拍板暂定——整体绝对值轴 ÷3):
; max_hp 50→17(16.67 四舍五入)、atk 6→2。armor_class 10 不动(掷点阈值轴,相对量纲不压缩——
@@ -18,13 +22,9 @@ attack_type = "normal"
; 护甲等级掷点批(2026-09-16 用户拍板):armor_class = 10(暂定基准,归 难度曲线与Boss;
; EV 参考数按判定式复算 = 期望减免 21.25%);ac_up 增益 +1 AC/层(×2 层 = AC+2)在其上加算。
;
; 营地扩展前置批(2026-09-18 用户指令):新增两根可配置轴——
; armor_type = 主角护甲类型(light/ward/heavy,缺省 light):轴现行休眠——甲效矩阵消费面 = 主角侧,
; 敌方攻击不查矩阵(2026-09-18 甲效矩阵调参批归因改述,原「恒 normal 档故三甲全 100% 中性」随旧三档
; 结构退役),类型轴生效待敌方技能攻击类型批;
; attack_type = 主角基础攻击类型(normal/pierce/magic,缺省 normal):基础攻击量(atk)与攻击类型抽象分离——
; 营地永久强化"换成魔法/穿刺攻击"= 改此字段(atk 量轴零改动),战斗段基础分量即按此查甲效矩阵。
; 两轴全部 provisional,营地建设批(元进度侧)拍板正式投值。
; 〔营地扩展前置批(2026-09-18 用户指令)两根可配置轴 armor_type/attack_type 已于 2026-10-12
; 迭代 23 锻造工坊实装批 T2 删除——所有权移交锻造工坊配置(见顶部注记);甲型基础 AC 随甲路线
; 行承载(轻 10/重 12/魔法护甲 9),本表 armor_class=10 保留为甲路线缺失时的兜底基准。〕
;
; Package B 迭代·第 2 轮(2026-09-22——计划书 §6.2,用户拍板一B):max_hp 17→20。第 1 轮读数
; 触发 §6.2(L1 精英承伤 43-55% vs 靶 ≤20%、L1 净消耗 17.7/17=104% 破产、normal L1 通过率
+23 -3
View File
@@ -1462,8 +1462,8 @@ func _ac11_tier_samples() -> Array:
# 同种子停手轮恒同掷点(效果只改乘区、不动掷点流)→ 落地伤害精确关系:
# 增伤 = 基线 ×1.5、乏力 = ×0.75(hero_offense 池乘攻击合计——2026-09-19 充能退役后 = 单分量,直乘旁路退役);
# 硬化 = 基线 ×0.5 且 < 基线(enemy_defense 池负值折半——+100 翻倍符号 bug 随批纠正)。
# 基线构成(加法核 2026-09-18 + 充能退役 2026-09-19):基线 100——hero attack_type=normal 对轻甲中性 0 修正
# (目标 = L1 地精轻甲;AC 0 恒全额非暴击种子)。
# 基线构成(加法核 2026-09-18 + 充能退役 2026-09-19):基线 100——hero 攻击类型=normal(锻造工坊配置默认值,
# 迭代 23 T2 起 hero.tres 两轴删除)对轻甲中性 0 修正(目标 = L1 地精轻甲;AC 0 恒全额非暴击种子)。
func _smoke_pool_wiring() -> void:
print("--- 主角乘区接线 + 硬化折半方向 ---")
var base_row := _hero_attack_row_with({}, 100, 20260918)
@@ -1898,7 +1898,8 @@ func _smoke_full_battle(L: int, D: int, label: String) -> void:
if row.get("source_class", "") == "hero_attack":
hero_attacks += 1
# 单分量伤害构成行(2026-09-19 充能退役批):hero_attack 行必须携带实际攻击类型键 + 掷点读数(P2 归因)
var atk_t: String = String(_db.hero.attack_type)
# 迭代 23 T2:类型键主语换代——hero.tres 两轴删除,实际攻击类型=锻造工坊配置默认值(本夹具零注入)
var atk_t: String = String(_db.forge_default_attack_type())
if not (row.has(atk_t) and row.has("roll") and row.has("ac") and row.has("tier")):
hero_breakdown_ok = false
check(has_verdict, "%s 步骤流含判定行" % label)
@@ -4408,10 +4409,29 @@ func _smoke_meta() -> void:
_meta_pricing_and_buy()
_meta_settle_and_workshop()
_meta_injection()
_smoke_forge_axes()
_pause_overlay_projection()
_career_overlay_projection()
# ---- 锻造工坊·两根类型轴所有权移交(迭代 23 T2——V5 前半:hero.tres 两轴删除+锻造配置默认值)----
# 后半(build_adventure_params 注入默认值/选中覆盖)随 T4 注入接线同批断言;写口/解锁面归 T3。
func _smoke_forge_axes() -> void:
print("--- 锻造工坊·类型轴所有权移交(T2)---")
# V5:hero.tres 静态表两轴已删(全表加载零违例——config_db_test 同款闸;此处钉字段不在位)
check(not ("attack_type" in _db.hero) and not ("armor_type" in _db.hero),
"hero.tres 无 attack_type/armor_type 字段(契约 2——静态表两轴删除)〔锻造工坊批 V5〕")
# 锻造配置默认值 = normal/light(常驻持有——与柜台解锁状态解耦,未点亮也照常可读)
check(_db.forge_default_attack_type() == "normal" and _db.forge_default_armor_type() == "light",
"锻造配置默认值 attack_type=normal / armor_type=light(常驻持有)〔锻造工坊批 V5〕")
# 单位快照回退面:spawn 三参形态(零注入)= 锻造配置默认值(行为连续——原 hero.tres normal/light)
var uc = load("res://core/unit_container.gd").new(_db)
check(uc.spawn(1, 0, int(_db.hero.max_hp)), "spawn 受理(三参形态——两轴缺省回退面)")
check(String(uc.hero_unit().get("attack_type", "")) == "normal"
and String(uc.hero_unit().get("armor_type", "")) == "light",
"主角单位快照两轴 = 锻造配置默认值 normal/light(零注入回退——行为连续)〔锻造工坊批 V5〕")
# ---- 暂停层只读投影一致性(迭代 17 卡③——R4 数据只读同源:暂停层展示值逐项 == MetaProgression
# 访问器读数;投影拼装与 main._pause_data 同构(同访问器族同序)。只读性连接巡检与零动效
# 断言归 ui_struct_probe 呈现侧,本段只管数据面)----