feat(slice): 伤害道具批+护甲类型重配批+营地扩展前置批——①五型→七型字典(穿刺弹/魔法矢单目标克制直伤正负各一行,attack_type 轴查克制矩阵必中全额;负向=主角直伤复用反噬通道),权重再平衡保 spark_aoe 16、总频次 67 不变(attack_up 20→14/ac_up 16→11/heal_minor 3→2/weaken 12→8,等比基准 ×0.686 整取微差登记);②怪物甲重配:L1 全轻甲、L2 除 Boss 卓尔精灵→魔法甲外全轻甲(克制三角读数:L1 中性化/L2 仅 Boss 战非中性);③主角双轴可配置:hero 表新增 armor_type(缺省 light)+attack_type(缺省 normal,基础分量类型读表、原硬编码 normal 退役、同桶充能照加不掷不折)——基础攻击量与攻击类型抽象分离,营地换型=改字段;④棋盘徽标穿/魔+smoke 护甲断言同步(含文档审计批遗留中文标签混编)+先手断言放宽为「存在或授予段终局」(单弱敌可被挖掘期兑付单独击杀);⑤GDD 战斗结算 v0.13/敌人系统 v0.8/registry hero 条目同步;冒烟 295 全绿(行动经济改名在飞 hunks 未入本提交,归并行会话)
This commit is contained in:
1 parent
cdc226e923
commit
a2fc39ff17
11 files changed
+82
-29
No files matched your search
@@ -165,15 +165,15 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 ×
|
|||||||
增益池乘区(含敌方防御池)→ 伏击附加(后置加法、必中全额、不吃 AC)→ 向下取整 → 伤害下限 max(1,·)
|
增益池乘区(含敌方防御池)→ 伏击附加(后置加法、必中全额、不吃 AC)→ 向下取整 → 伤害下限 max(1,·)
|
||||||
```
|
```
|
||||||
|
|
||||||
主角先手攻击由三个分量逐项取整后相加:普通分量(攻击力经增益修正,可被池封顶压到零)、穿刺分量、魔法分量。**攻击类型是伤害的属性轴**——它只决定这个分量查甲效表的哪一行,定义里不含任何棋盘来源。分量各自查表后取整相加;甲效表把攻击类型与敌方护甲类型交叉成一张 3×3 克制倍率:
|
主角先手攻击由三个分量逐项取整后相加:基础分量(攻击力经增益修正,可被池封顶压到零;**类型 = 主角 `attack_type` 表值**——2026-09-18 营地扩展前置批:基础攻击量与攻击类型抽象分离,基础分量不再恒属普通,缺省 normal 向后兼容)、穿刺分量、魔法分量。**攻击类型是伤害的属性轴**——它只决定这个分量查甲效表的哪一行,定义里不含任何棋盘来源。分量各自查表后取整相加;甲效表把攻击类型与敌方护甲类型交叉成一张 3×3 克制倍率:
|
||||||
|
|
||||||
| 攻击类型 \ 护甲类型 | 轻甲 | 魔法护甲 | 重甲 | 语义 |
|
| 攻击类型 \ 护甲类型 | 轻甲 | 魔法护甲 | 重甲 | 语义 |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| 普通 | 中性档 | 中性档 | 中性档 | 基线分量:不吃克制,只吃增益修正 |
|
| 普通 | 中性档 | 中性档 | 中性档 | 基线分量缺省类型:只吃增益修正(基础分量类型可配——换为穿刺/魔法后即按对应行结算,掷点口径不变) |
|
||||||
| 穿刺 | 中性档 | 克制档 | 被克档 | 穿透附魔护甲,破不开重甲 |
|
| 穿刺 | 中性档 | 克制档 | 被克档 | 穿透附魔护甲,破不开重甲 |
|
||||||
| 魔法 | 中性档 | 被克档 | 克制档 | 绕得过重甲,被魔法护甲吸收 |
|
| 魔法 | 中性档 | 被克档 | 克制档 | 绕得过重甲,被魔法护甲吸收 |
|
||||||
|
|
||||||
倍率只三档:克制 / 中性 / 被克(三档倍率读 `settlement.tres` 甲效矩阵)。攻击类型是分量的固有属性(每个分量恒属普通 / 穿刺 / 魔法 之一),护甲类型是敌单位的固有属性,两者都不随层数、来源与轮次漂移。矩阵键集 3×3 满格、结构冻结,数值 provisional。主角增益只修正普通分量,两个充能分量不吃百分比修正。
|
倍率只三档:克制 / 中性 / 被克(三档倍率读 `settlement.tres` 甲效矩阵)。攻击类型是分量的固有属性(每个分量恒属普通 / 穿刺 / 魔法 之一),护甲类型是防守单位的固有属性,两者都不随层数、来源与轮次漂移;基础分量的类型归属是主角表的可配置值(营地永久强化的换型落点),充能分量类型仍归充能定义。矩阵键集 3×3 满格、结构冻结,数值 provisional。主角增益只修正普通分量,两个充能分量不吃百分比修正。
|
||||||
|
|
||||||
普通分量由攻击力基线直接供给;穿刺与魔法分量由**充能**供给——充能是挖掘期攒下、按攻击类型分桶的附加伤害储备,本结算战斗段一次性消费、轮末清零,跨轮零存量。
|
普通分量由攻击力基线直接供给;穿刺与魔法分量由**充能**供给——充能是挖掘期攒下、按攻击类型分桶的附加伤害储备,本结算战斗段一次性消费、轮末清零,跨轮零存量。
|
||||||
|
|
||||||
@@ -345,4 +345,5 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值
|
|||||||
| v0.9 | 2026-09-16 | 新增「呈现只读面」节(06 清单「呈现只读面契约登记缺口」闭合):把切片已实现的呈现面函数与信号登记为对外契约——呈现状态快照 `presentation_snapshot`、战斗进行中谓词 `is_battle_live`、奖励身份查询 `query_reward_identity`、结算快照信号 `settlement_snapshot`、战斗结束信号 `battle_finished` 五件成文(载荷字段、消费方、销毁前捕获语义),并登记"呈现层唯一状态读取出口、禁链式穿透"的出口纪律与诊断观测面的非契约定位;依赖与输出表 HUD 框架下游行补指路 |
|
| v0.9 | 2026-09-16 | 新增「呈现只读面」节(06 清单「呈现只读面契约登记缺口」闭合):把切片已实现的呈现面函数与信号登记为对外契约——呈现状态快照 `presentation_snapshot`、战斗进行中谓词 `is_battle_live`、奖励身份查询 `query_reward_identity`、结算快照信号 `settlement_snapshot`、战斗结束信号 `battle_finished` 五件成文(载荷字段、消费方、销毁前捕获语义),并登记"呈现层唯一状态读取出口、禁链式穿透"的出口纪律与诊断观测面的非契约定位;依赖与输出表 HUD 框架下游行补指路 |
|
||||||
| v0.10 | 2026-09-16 | **护甲等级掷点批·定稿落地(用户拍板,数字即规范——与敌人系统 / 难度曲线与Boss / registry / 切片代码同批)**:判定式定稿——掷 1d20,掷点 ≥ 防守方护甲等级 + 攻击加成(结构位 `attack_bonus`,切片恒 0)→ 全额,低掷按缺口三档折扣(1-3 → ×0.75 · 4-7 → ×0.5 · 8+ → ×0.25,无零档);nat20 暴击该基础攻击分量 ×2 且恒全额(双方同规);伤害下限全局 max(1, ·)(`damage_floor` = 1)——"被减伤归零 v=0"零值伤害行语义退役,重档折扣行文本记"被压制";百分比减伤增益 defense_up 整体退役换装 ac_up(护甲强化 +1 AC/层 ×2 层,`unit=ac` 新量纲、不入任何池,无双轨),off_guard 与池结构零改动;护甲等级与护甲类型分离成文(数值轴 / 属性轴,不做映射)。数值载体:主角 armor_class 10(暂定)、敌方首关 0(暂定,正式行值归怪物设定批,登记待办清单);掷点流归属定稿 = `armor_roll` 封闭流(逐次掷逐次取号,可逐位回放),调参表掷点/档位/下限/加成五行由未定改拍板值;EV 参考数成文(AC10 21.25% / AC11 25% / AC12 28.75%,按判定式复算),换装点锚定(基准 AC10 自带约 −21% 敌方输出期望)与加难杠杆扫描合并处理;验收标准改写掷点条目 + 新增伤害下限与留档条目;切片同批:settlement.tres 七参数入表、战斗段掷点判定/暴击/下限/行留档(roll/ac/tier/crit 字段)、armor_roll 流接入 rng_service(黄金向量 m=42 scope0 = 4806095330042243845)、零值伤害行分支删除、冒烟护栏与掷点行为断言(nat20 种子 / AC12 档位分布 / 池触底保底 / 棋盘必中)、英雄卡与敌人卡 AC 展示、ac_up 状态槽图标、nat20 金框高亮 |
|
| v0.10 | 2026-09-16 | **护甲等级掷点批·定稿落地(用户拍板,数字即规范——与敌人系统 / 难度曲线与Boss / registry / 切片代码同批)**:判定式定稿——掷 1d20,掷点 ≥ 防守方护甲等级 + 攻击加成(结构位 `attack_bonus`,切片恒 0)→ 全额,低掷按缺口三档折扣(1-3 → ×0.75 · 4-7 → ×0.5 · 8+ → ×0.25,无零档);nat20 暴击该基础攻击分量 ×2 且恒全额(双方同规);伤害下限全局 max(1, ·)(`damage_floor` = 1)——"被减伤归零 v=0"零值伤害行语义退役,重档折扣行文本记"被压制";百分比减伤增益 defense_up 整体退役换装 ac_up(护甲强化 +1 AC/层 ×2 层,`unit=ac` 新量纲、不入任何池,无双轨),off_guard 与池结构零改动;护甲等级与护甲类型分离成文(数值轴 / 属性轴,不做映射)。数值载体:主角 armor_class 10(暂定)、敌方首关 0(暂定,正式行值归怪物设定批,登记待办清单);掷点流归属定稿 = `armor_roll` 封闭流(逐次掷逐次取号,可逐位回放),调参表掷点/档位/下限/加成五行由未定改拍板值;EV 参考数成文(AC10 21.25% / AC11 25% / AC12 28.75%,按判定式复算),换装点锚定(基准 AC10 自带约 −21% 敌方输出期望)与加难杠杆扫描合并处理;验收标准改写掷点条目 + 新增伤害下限与留档条目;切片同批:settlement.tres 七参数入表、战斗段掷点判定/暴击/下限/行留档(roll/ac/tier/crit 字段)、armor_roll 流接入 rng_service(黄金向量 m=42 scope0 = 4806095330042243845)、零值伤害行分支删除、冒烟护栏与掷点行为断言(nat20 种子 / AC12 档位分布 / 池触底保底 / 棋盘必中)、英雄卡与敌人卡 AC 展示、ac_up 状态槽图标、nat20 金框高亮 |
|
||||||
| v0.11 | 2026-09-16 | **敌人技能池批(用户拍板,设计权威 docs/proposal-skill-pool.md v1.0——与敌人系统 / 增益状态 / 难度曲线与Boss / 战斗表现 / HUD框架 / registry / 切片代码同批)**:① 随机口径两处 → 三处——技能摇号 `behavior_roll` 封闭流(回合内、开轮时点、步骤流之外,每敌按生成序派生独立子流、单敌轨迹可独立复放)入册,可回放契约扩写为"三处皆封闭流,同种子同输入逐位复现";② 战斗段成文开轮摇号与敌方技能兑现(每轮恰摇一次、轮内刷新不重摇、摇定后兑现前死亡作废)、增益技 = 施放行 + 状态授予(0 伤害不掷不折不兑伏击);③ 三乘法链成文(技能倍率乘在最前:基线 × 倍率 → AC 掷点 → 甲效 → 既有链不动);④ AC 判定对象措辞四处改述("敌方攻击拍与重击拍基线" → "敌方技能基础伤害分量",含正文/公式行/边界表/验收标准);⑤ 敌方防御池入乘区(`enemy_defense` 新池——硬化载体):主角攻击 Σ三分量后 ×(100+enemy_defense)/100,四池对称成文(hero_offense 现行走普通分量直乘的切片现状登记待办);⑥ 行型改型:蓄力行 `charge` → 施放行 `cast`(10 类封闭不变);⑦ 呈现快照敌人数组字段定稿(当前拍/行动环进度 → 摇定动作三字段 + 敌方增益 effects);验收标准新增开轮摇号条目、战斗段次序与可回放条目改写;切片同批:`_roll_round_actions` 开轮编排、技能摇号器独立服务类、单位容器实例池/冷却/执行上报、settlement.tres effect_pool_map 增 empower/fortify、施放行格式化、摇定动画位 |
|
| v0.11 | 2026-09-16 | **敌人技能池批(用户拍板,设计权威 docs/proposal-skill-pool.md v1.0——与敌人系统 / 增益状态 / 难度曲线与Boss / 战斗表现 / HUD框架 / registry / 切片代码同批)**:① 随机口径两处 → 三处——技能摇号 `behavior_roll` 封闭流(回合内、开轮时点、步骤流之外,每敌按生成序派生独立子流、单敌轨迹可独立复放)入册,可回放契约扩写为"三处皆封闭流,同种子同输入逐位复现";② 战斗段成文开轮摇号与敌方技能兑现(每轮恰摇一次、轮内刷新不重摇、摇定后兑现前死亡作废)、增益技 = 施放行 + 状态授予(0 伤害不掷不折不兑伏击);③ 三乘法链成文(技能倍率乘在最前:基线 × 倍率 → AC 掷点 → 甲效 → 既有链不动);④ AC 判定对象措辞四处改述("敌方攻击拍与重击拍基线" → "敌方技能基础伤害分量",含正文/公式行/边界表/验收标准);⑤ 敌方防御池入乘区(`enemy_defense` 新池——硬化载体):主角攻击 Σ三分量后 ×(100+enemy_defense)/100,四池对称成文(hero_offense 现行走普通分量直乘的切片现状登记待办);⑥ 行型改型:蓄力行 `charge` → 施放行 `cast`(10 类封闭不变);⑦ 呈现快照敌人数组字段定稿(当前拍/行动环进度 → 摇定动作三字段 + 敌方增益 effects);验收标准新增开轮摇号条目、战斗段次序与可回放条目改写;切片同批:`_roll_round_actions` 开轮编排、技能摇号器独立服务类、单位容器实例池/冷却/执行上报、settlement.tres effect_pool_map 增 empower/fortify、施放行格式化、摇定动画位 |
|
||||||
|
| v0.13 | 2026-09-18 | **营地扩展前置批·主角双轴可配置(用户指令,与敌人系统 / registry / 切片代码同批)**:① hero 表新增 armor_type({light, ward, heavy},缺省 light)——主角护甲类型轴可配置可修改,消费面 = 甲效矩阵(现行敌方攻击恒 normal 档 = 数值中性的结构位,轴生效待敌方技能攻击类型批);② hero 表新增 attack_type({normal, pierce, magic},缺省 normal)——**基础攻击量与攻击类型抽象分离**:基础分量类型不再硬编码普通、改读主角表值,营地永久强化"换成魔法/穿刺攻击"= 改字段,atk 量轴与掷点口径零改动;③ 同桶充能照加语义成文(基础分量与充能同型时,充能分量保持不掷不折);正文三分量表述、甲效矩阵"普通"行注记、分量固有属性措辞三处同步 |
|
||||||
| v0.12 | 2026-09-17 | **数值纪律收口批:正文与调参表 knob 现行值改指路存根(事实源 `data/tables/*.tres` 与 registry),20 余处失同步值修正**——收益对照表参考敞口 12 / 完美乘数 200 改指路 settlement.tres(equivalence_ref_damage / p_perfect);伏击加层"+2 层"改"+stacks 层(读 reward.tres ambush_double 行)";充能供给表与 charge_grants 行"每格 1 / 上限 8 / 每雷 2"改 per_unit/cap 读表;三乘法链与甲效矩阵 1.5/1.0/0.5、150/100/50 改三档读表;掷点判定 1d20 / nat20 ×2 / 缺口档 ×0.75/×0.5/×0.25 / 边界 [3,7] / 档位 [75,50,25] / damage_floor=1 / AC 10·0 / ac_up +1×2 层全部改指路 settlement.tres·status_effects.tres·hero/enemy 表;EV 参考数(AC10 21.25% 等)与"旧 defense_up 满层 −60%"删除(派生读数 / 退役值,版本历史可查);调参表与验收标准同步 |
|
| v0.12 | 2026-09-17 | **数值纪律收口批:正文与调参表 knob 现行值改指路存根(事实源 `data/tables/*.tres` 与 registry),20 余处失同步值修正**——收益对照表参考敞口 12 / 完美乘数 200 改指路 settlement.tres(equivalence_ref_damage / p_perfect);伏击加层"+2 层"改"+stacks 层(读 reward.tres ambush_double 行)";充能供给表与 charge_grants 行"每格 1 / 上限 8 / 每雷 2"改 per_unit/cap 读表;三乘法链与甲效矩阵 1.5/1.0/0.5、150/100/50 改三档读表;掷点判定 1d20 / nat20 ×2 / 缺口档 ×0.75/×0.5/×0.25 / 边界 [3,7] / 档位 [75,50,25] / damage_floor=1 / AC 10·0 / ac_up +1×2 层全部改指路 settlement.tres·status_effects.tres·hero/enemy 表;EV 参考数(AC10 21.25% 等)与"旧 defense_up 满层 −60%"删除(派生读数 / 退役值,版本历史可查);调参表与验收标准同步 |
|
||||||
@@ -270,6 +270,8 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(现行:酋
|
|||||||
| max_hp | [1, 999] | 主角生命上限 |
|
| max_hp | [1, 999] | 主角生命上限 |
|
||||||
| atk | [1, 999] | 基础攻击;配 0 加载期拒绝——基础攻击恒在 |
|
| atk | [1, 999] | 基础攻击;配 0 加载期拒绝——基础攻击恒在 |
|
||||||
| armor_class(护甲等级) | int [0, 999] | 主角作为防守方的护甲等级基准,ac_up(护甲强化)在其上加算;掷点结算归[战斗结算](战斗结算.md) |
|
| armor_class(护甲等级) | int [0, 999] | 主角作为防守方的护甲等级基准,ac_up(护甲强化)在其上加算;掷点结算归[战斗结算](战斗结算.md) |
|
||||||
|
| armor_type | {轻甲, 魔法护甲, 重甲},缺省轻甲 | 主角护甲类型轴(2026-09-18 营地扩展前置批:可配置可修改);克制结算归[战斗结算](战斗结算.md),现行敌方攻击恒普通档 = 数值中性的结构位 |
|
||||||
|
| attack_type | {普通, 穿刺, 魔法},缺省普通 | 主角基础攻击类型轴(2026-09-18 营地扩展前置批:基础攻击量与攻击类型抽象分离——营地永久强化换型 = 改此字段,atk 量轴不动);消费面 = 战斗结算·战斗段基础分量 |
|
||||||
|
|
||||||
各敌种行值、池权重与池 EV 读数(含闸长期速率实测)一律读配置表与调参日志,本文不登记具体数值;EV 重锚与权重投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)。
|
各敌种行值、池权重与池 EV 读数(含闸长期速率实测)一律读配置表与调参日志,本文不登记具体数值;EV 重锚与权重投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)。
|
||||||
|
|
||||||
@@ -304,4 +306,5 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(现行:酋
|
|||||||
| v0.4 | 2026-09-16 | **护甲等级掷点批·定稿落地(与战斗结算 / 难度曲线与Boss / registry / 切片代码同批)**:armor_class 域定稿 [0, 999](缺省 0 向后兼容);主角行值 10(暂定)、三敌种首关行值 0(暂定)——"行值未定"改"暂定值 + 待办",敌方正式行值归怪物设定批(第一关怪物 AC 相对较低,值待怪物设定投值,登记待办清单);敌种表护甲等级列同步落值;调参表两行改域与现行值 |
|
| v0.4 | 2026-09-16 | **护甲等级掷点批·定稿落地(与战斗结算 / 难度曲线与Boss / registry / 切片代码同批)**:armor_class 域定稿 [0, 999](缺省 0 向后兼容);主角行值 10(暂定)、三敌种首关行值 0(暂定)——"行值未定"改"暂定值 + 待办",敌方正式行值归怪物设定批(第一关怪物 AC 相对较低,值待怪物设定投值,登记待办清单);敌种表护甲等级列同步落值;调参表两行改域与现行值 |
|
||||||
| v0.5 | 2026-09-16 | **敌人技能池批(用户拍板,设计权威 docs/proposal-skill-pool.md v1.0;与战斗结算 / 增益状态 / 难度曲线与Boss / 战斗表现 / HUD框架 / registry / 切片代码同批)**:行为环章节整体退役——固定出招剧本、拍枚举(攻击/蓄力/重击)、环指针、同种锁步、heavy_multiplier 字段全部废除;技能池语义成文(三层对象〔技能行/池模板/实例池〕、技能行词汇表、池构成纪律、两道闸〔全技能各自冷却 + 保底〕、开轮摇号时序、死亡作废、独立子流);蓄力语义改写(纯攻击增益技、与重击无组合语义——纠偏二;施放行继承零兑付伏击);Boss 专属身份改专属池承载;意图呈现改三档可见性(普攻零表示 / 特殊技类型级预告 / 暴击掷点层);敌人表 schema pattern → pool;调参表增技能表与池 EV 锚(含闸长期速率实测登记);验收标准按摇号口径重写 |
|
| v0.5 | 2026-09-16 | **敌人技能池批(用户拍板,设计权威 docs/proposal-skill-pool.md v1.0;与战斗结算 / 增益状态 / 难度曲线与Boss / 战斗表现 / HUD框架 / registry / 切片代码同批)**:行为环章节整体退役——固定出招剧本、拍枚举(攻击/蓄力/重击)、环指针、同种锁步、heavy_multiplier 字段全部废除;技能池语义成文(三层对象〔技能行/池模板/实例池〕、技能行词汇表、池构成纪律、两道闸〔全技能各自冷却 + 保底〕、开轮摇号时序、死亡作废、独立子流);蓄力语义改写(纯攻击增益技、与重击无组合语义——纠偏二;施放行继承零兑付伏击);Boss 专属身份改专属池承载;意图呈现改三档可见性(普攻零表示 / 特殊技类型级预告 / 暴击掷点层);敌人表 schema pattern → pool;调参表增技能表与池 EV 锚(含闸长期速率实测登记);验收标准按摇号口径重写 |
|
||||||
| v0.6 | 2026-09-17 | **文档降级为模板批(用户拍板,与难度曲线与Boss / 战斗结算同批)**:数值纪律定稿——本文只锁字段、取值域与规则,全部具体行值(敌种表池权重 / 护甲等级行值 / 两道闸表值 / 伏击每层附加与上限 / 技能行倍率与冷却 / 主角三字段 / 三敌种行值与池 EV 实测读数)自本文移除、一律读配置表(切片 `data/tables/` 与 registry);调参表三表删除"现行值"列改纯 schema 模板;伏击公式与验算改符号化(a = 每层伏击表值);验收标准同步去数值。背景:切片 `.tres` 数值压缩批后文档行值已滞后,双写失同步被实证 |
|
| v0.6 | 2026-09-17 | **文档降级为模板批(用户拍板,与难度曲线与Boss / 战斗结算同批)**:数值纪律定稿——本文只锁字段、取值域与规则,全部具体行值(敌种表池权重 / 护甲等级行值 / 两道闸表值 / 伏击每层附加与上限 / 技能行倍率与冷却 / 主角三字段 / 三敌种行值与池 EV 实测读数)自本文移除、一律读配置表(切片 `data/tables/` 与 registry);调参表三表删除"现行值"列改纯 schema 模板;伏击公式与验算改符号化(a = 每层伏击表值);验收标准同步去数值。背景:切片 `.tres` 数值压缩批后文档行值已滞后,双写失同步被实证 |
|
||||||
|
| v0.8 | 2026-09-18 | **营地扩展前置批 + 护甲类型重配(用户指令,与战斗结算 / registry / 切片代码同批)**:① hero 表新增 armor_type / attack_type 两根可配置轴(缺省 light / normal;主角字段表同步两行)——护甲类型轴入矩阵消费面(敌方技能攻击类型轴未开前数值中性),基础攻击类型轴 = 量与类型抽象分离的营地换型落点;② 敌种护甲类型行值重配(数据面):关卡 1 全部轻甲(食人魔酋长 heavy→light、熊地精两行 ward→light),关卡 2 除 Boss 蛛化卓尔精灵 heavy→ward(魔法甲)外全部轻甲(熊地精四行 ward→light,巨蜘蛛既有 light 不动);现行克制三角读数效果 = L1 克制轴中性化、L2 仅 Boss 战非中性(魔法矢 ×150 / 穿刺弹 ×50 对 Boss) |
|
||||||
| v0.7 | 2026-09-17 | **数值纪律收口批:正文与调参表 knob 现行值改指路存根(事实源 `data/tables/*.tres` 与 registry),2 处失同步值修正**——共享技能表示例"熊地精 9×2=18"改符号化"基线 A × 技能倍率 M(行值读 enemy.tres / skills.tres)";蓄力语义"施加'攻击×2'状态""×2 遇 ×2 = ×4"改"施加 empower 状态(幅度读 status_effects.tres)",两层乘法组合语义保留符号表述 |
|
| v0.7 | 2026-09-17 | **数值纪律收口批:正文与调参表 knob 现行值改指路存根(事实源 `data/tables/*.tres` 与 registry),2 处失同步值修正**——共享技能表示例"熊地精 9×2=18"改符号化"基线 A × 技能倍率 M(行值读 enemy.tres / skills.tres)";蓄力语义"施加'攻击×2'状态""×2 遇 ×2 = ×4"改"施加 empower 状态(幅度读 status_effects.tres)",两层乘法组合语义保留符号表述 |
|
||||||
@@ -278,6 +278,8 @@ entities:
|
|||||||
max_hp: int [1,999](knob;现行值读 data/tables/hero.tres)
|
max_hp: int [1,999](knob;现行值读 data/tables/hero.tres)
|
||||||
atk: int [1,999](**0 = 加载拒绝**——基础攻击恒存在,"0 基线 × 百分比增益恒零"死锁自 schema 层杜绝〔2026-09-11 用户裁决,原"机制开关 MVP=0、激活裁决归 地图战斗资源/战斗结算"作废〕;现行值读 data/tables/hero.tres〔2026-09-17 数值压缩批改型〕;消费面 = 主角战斗段先手攻击——战斗结算 GDD 2026-09-11 增补)
|
atk: int [1,999](**0 = 加载拒绝**——基础攻击恒存在,"0 基线 × 百分比增益恒零"死锁自 schema 层杜绝〔2026-09-11 用户裁决,原"机制开关 MVP=0、激活裁决归 地图战斗资源/战斗结算"作废〕;现行值读 data/tables/hero.tres〔2026-09-17 数值压缩批改型〕;消费面 = 主角战斗段先手攻击——战斗结算 GDD 2026-09-11 增补)
|
||||||
armor_class: int [0,999](**2026-09-15 护甲等级批新增,2026-09-16 掷点批定稿落地**——主角作为防守方的护甲等级,敌方攻击拍 / 重击拍基线的掷点折扣判定读数;掷点结算归 settlement_table.ac_roll〔战斗结算〕,与 armor_type〔克制属性轴〕两概念不得混用;现行值读 data/tables/hero.tres〔暂定,调参归 难度曲线与Boss〕)
|
armor_class: int [0,999](**2026-09-15 护甲等级批新增,2026-09-16 掷点批定稿落地**——主角作为防守方的护甲等级,敌方攻击拍 / 重击拍基线的掷点折扣判定读数;掷点结算归 settlement_table.ac_roll〔战斗结算〕,与 armor_type〔克制属性轴〕两概念不得混用;现行值读 data/tables/hero.tres〔暂定,调参归 难度曲线与Boss〕)
|
||||||
|
armor_type: enum {light, ward, heavy}(**2026-09-18 营地扩展前置批新增**——主角护甲类型轴可配置可修改,缺省 light 向后兼容;消费面 = 战斗结算甲效矩阵〔现行敌方攻击恒 normal 档 = 数值中性的结构位,轴生效待敌方技能攻击类型批〕;现行值读 data/tables/hero.tres)
|
||||||
|
attack_type: enum {normal, pierce, magic}(**2026-09-18 营地扩展前置批新增**——主角基础攻击量〔atk 量轴〕与攻击类型抽象分离的承载字段:营地永久强化"换成魔法/穿刺攻击" = 改此字段,量轴零改动;消费面 = 战斗结算·战斗段基础分量查甲效矩阵〔原硬编码 normal 退役〕;现行值读 data/tables/hero.tres)
|
||||||
rule4_exemption: 单行全局定义表(主角不随关卡自动成长——成长=天赋 元进度/奖励侧;ActionEconomyTable 先例)
|
rule4_exemption: 单行全局定义表(主角不随关卡自动成长——成长=天赋 元进度/奖励侧;ActionEconomyTable 先例)
|
||||||
hp_persistence: 跨战斗 HP 持久性归 关卡节点地图/冒险结构(provisional)——敌人系统 单位接口以初始 hp 入参,不定义冒险内持久性
|
hp_persistence: 跨战斗 HP 持久性归 关卡节点地图/冒险结构(provisional)——敌人系统 单位接口以初始 hp 入参,不定义冒险内持久性
|
||||||
referenced_by: [战斗结算, 地图战斗资源, 难度曲线与Boss]
|
referenced_by: [战斗结算, 地图战斗资源, 难度曲线与Boss]
|
||||||
|
|||||||
@@ -284,6 +284,7 @@ func _apply_percent_row(row: Dictionary, source_class: String, cell: Vector2i, r
|
|||||||
# flat 行兑付(负向恒即时,无库存语义):
|
# flat 行兑付(负向恒即时,无库存语义):
|
||||||
# blast 正向 = 全体存活敌各 power 点(无敌 → 奖励未生效行);blast 负向 = 敌方伏击 +stacks 层(cap/溢出行协议不变);
|
# blast 正向 = 全体存活敌各 power 点(无敌 → 奖励未生效行);blast 负向 = 敌方伏击 +stacks 层(cap/溢出行协议不变);
|
||||||
# heal 正向 = 主角回复 clamp(满血 → 奖励未生效行);heal 负向 = 主角直伤 power 点(不经增益状态;归零 → 战斗段短路/判定段判负)。
|
# heal 正向 = 主角回复 clamp(满血 → 奖励未生效行);heal 负向 = 主角直伤 power 点(不经增益状态;归零 → 战斗段短路/判定段判负)。
|
||||||
|
# pierce/magic(伤害道具批 2026-09-18)正向 = 单目标克制直伤(必中全额);负向 = 主角直伤。
|
||||||
# 返回 "redeemed" = 实际有效兑付 / "zero" = 零兑付(行已自记)——清图高光只记实际有效兑付。
|
# 返回 "redeemed" = 实际有效兑付 / "zero" = 零兑付(行已自记)——清图高光只记实际有效兑付。
|
||||||
func _apply_flat_row(row: Dictionary, source_class: String, cell: Vector2i, ri: int, highlight: String = "", label_suffix: String = "") -> String:
|
func _apply_flat_row(row: Dictionary, source_class: String, cell: Vector2i, ri: int, highlight: String = "", label_suffix: String = "") -> String:
|
||||||
var ctype := String(row.cell_type)
|
var ctype := String(row.cell_type)
|
||||||
@@ -300,6 +301,23 @@ func _apply_flat_row(row: Dictionary, source_class: String, cell: Vector2i, ri:
|
|||||||
_enemy_system.apply_damage(u, power) # 恒定表值,逐个;受击即死——死亡即不动手
|
_enemy_system.apply_damage(u, power) # 恒定表值,逐个;受击即死——死亡即不动手
|
||||||
_emit_row("damage", source_class, cell, ri, "%s → 全体敌人 ×%d" % [display, alive.size()], power, {"target": "all_enemies", "count": alive.size()}, highlight)
|
_emit_row("damage", source_class, cell, ri, "%s → 全体敌人 ×%d" % [display, alive.size()], power, {"target": "all_enemies", "count": alive.size()}, highlight)
|
||||||
return "redeemed"
|
return "redeemed"
|
||||||
|
if ctype == "pierce" or ctype == "magic":
|
||||||
|
# 伤害道具批(2026-09-18):穿刺/魔法两型——正向 = 单目标克制直伤(attack_type 字段查克制矩阵,
|
||||||
|
# 必中全额不掷点——棋盘来源伤害既有口径;目标 = 固定顺位最前存活敌);负向 = 主角直伤(复用反噬通道)。
|
||||||
|
if String(row.get("polarity", "positive")) == "negative":
|
||||||
|
_enemy_system.apply_damage(_enemy_system.hero_unit(), power)
|
||||||
|
_emit_row("damage", source_class, cell, ri, "%s → 主角" % display, power, {"target": "hero"}, highlight)
|
||||||
|
return "redeemed"
|
||||||
|
var target = _enemy_system.default_target()
|
||||||
|
if target == null:
|
||||||
|
_emit_row("reward_ineffective", source_class, cell, ri, "%s 未生效(无存活敌人)" % display, 0, {"batch_key": String(row.reward_id)}, highlight)
|
||||||
|
return "zero"
|
||||||
|
var atk_type: String = String(row.get("attack_type", ctype))
|
||||||
|
var eff: int = _armor_effectiveness(atk_type, String(target.get("armor_type", "light")))
|
||||||
|
var dealt: int = DamageMath.charge_component(power, eff)
|
||||||
|
_enemy_system.apply_damage(target, dealt)
|
||||||
|
_emit_row("damage", source_class, cell, ri, "%s → %s" % [display, String(target.display_name)], dealt, {"target": String(target.display_name), "attack_type": atk_type, "effectiveness": eff}, highlight)
|
||||||
|
return "redeemed"
|
||||||
if ctype == "heal":
|
if ctype == "heal":
|
||||||
if String(row.get("polarity", "positive")) == "negative":
|
if String(row.get("polarity", "positive")) == "negative":
|
||||||
_enemy_system.apply_damage(_enemy_system.hero_unit(), power)
|
_enemy_system.apply_damage(_enemy_system.hero_unit(), power)
|
||||||
@@ -423,7 +441,8 @@ func _roll_round_actions() -> void:
|
|||||||
func _combat_segment(ri: int) -> void:
|
func _combat_segment(ri: int) -> void:
|
||||||
var L := _status_effects.pool_layers("ambush") # 授予段后的当轮值;池共享不消耗
|
var L := _status_effects.pool_layers("ambush") # 授予段后的当轮值;池共享不消耗
|
||||||
# ⓪ 主角先手攻击(基础攻击恒存在——2026-09-11 用户裁决;先于敌方行动;授予段负向直伤致死 → 致电短路不先手)。
|
# ⓪ 主角先手攻击(基础攻击恒存在——2026-09-11 用户裁决;先于敌方行动;授予段负向直伤致死 → 致电短路不先手)。
|
||||||
# 三段伤害构成(2026-09-12 用户拍板;2026-09-15 命名统一批 + 攻击类型/奖励抽象分离批):普通(atk×(1+attack_up),不吃克制)
|
# 三段伤害构成(2026-09-12 用户拍板;2026-09-15 命名统一批 + 攻击类型/奖励抽象分离批):基础分量(atk×(1+attack_up),吃掷点,
|
||||||
|
# 类型 = 主角 attack_type 表值——2026-09-18 营地扩展前置批:量与类型抽象分离,原硬编码 normal 退役)
|
||||||
# + 穿刺/魔法(由充能供给——充能按攻击类型分桶,谁能充/充哪个桶归奖励定义 charge_grants)。攻击类型只管查甲效矩阵哪一行,与来源无关。
|
# + 穿刺/魔法(由充能供给——充能按攻击类型分桶,谁能充/充哪个桶归奖励定义 charge_grants)。攻击类型只管查甲效矩阵哪一行,与来源无关。
|
||||||
# 护甲等级掷点批(2026-09-16):普通分量吃掷点判定(含暴击);穿刺/魔法充能分量与棋盘来源伤害不掷不折;
|
# 护甲等级掷点批(2026-09-16):普通分量吃掷点判定(含暴击);穿刺/魔法充能分量与棋盘来源伤害不掷不折;
|
||||||
# 任何攻击落地伤害 ≥ damage_floor(全局 max(1,·))——"被减伤归零 v=0"零值伤害行分支随批退役。
|
# 任何攻击落地伤害 ≥ damage_floor(全局 max(1,·))——"被减伤归零 v=0"零值伤害行分支随批退役。
|
||||||
@@ -431,9 +450,10 @@ func _combat_segment(ri: int) -> void:
|
|||||||
var hero_target = _enemy_system.default_target()
|
var hero_target = _enemy_system.default_target()
|
||||||
if hero_alive and hero_target != null:
|
if hero_alive and hero_target != null:
|
||||||
var armor: String = String(hero_target.get("armor_type", "light"))
|
var armor: String = String(hero_target.get("armor_type", "light"))
|
||||||
|
var base_atk_type: String = String(_enemy_system.hero_unit().get("attack_type", "normal")) # 基础分量类型 = 主角表值(营地扩展前置批 2026-09-18)
|
||||||
var up := clampi(_pool_effective("attack_up"), int(db.settlement.pool_clamp_lo), int(db.settlement.pool_clamp_hi))
|
var up := clampi(_pool_effective("attack_up"), int(db.settlement.pool_clamp_lo), int(db.settlement.pool_clamp_hi))
|
||||||
var points := _charge_points() # {攻击类型: 充能点数}——奖励定义投递的结果(本段不认识"开格/标雷")
|
var points := _charge_points() # {攻击类型: 充能点数}——奖励定义投递的结果(本段不认识"开格/标雷")
|
||||||
var roll_read: Dictionary = _armor_roll() # 普通分量掷点(每吃掷点分量逐次掷)
|
var roll_read: Dictionary = _armor_roll() # 基础分量掷点(每吃掷点分量逐次掷——掷点只吃基础分量口径不变)
|
||||||
var threshold: int = _defender_ac(hero_target) + int(db.settlement.attack_bonus)
|
var threshold: int = _defender_ac(hero_target) + int(db.settlement.attack_bonus)
|
||||||
var crit: bool = bool(roll_read.crit)
|
var crit: bool = bool(roll_read.crit)
|
||||||
var discount: int = _roll_discount(int(roll_read.roll), threshold)
|
var discount: int = _roll_discount(int(roll_read.roll), threshold)
|
||||||
@@ -442,8 +462,9 @@ func _combat_segment(ri: int) -> void:
|
|||||||
var d_hero := 0
|
var d_hero := 0
|
||||||
for atk_type in SettlementTable.ATTACK_TYPE_KEYS:
|
for atk_type in SettlementTable.ATTACK_TYPE_KEYS:
|
||||||
var c: int = 0
|
var c: int = 0
|
||||||
if atk_type == "normal":
|
if atk_type == base_atk_type:
|
||||||
c = DamageMath.rolled_component(base_val, discount, crit, int(db.settlement.crit_multiplier), _armor_effectiveness("normal", armor))
|
c = DamageMath.rolled_component(base_val, discount, crit, int(db.settlement.crit_multiplier), _armor_effectiveness(atk_type, armor))
|
||||||
|
c += _charge_component(int(points.get(atk_type, 0)), atk_type, armor) # 同桶充能照加(充能分量不掷不折口径不变)
|
||||||
else:
|
else:
|
||||||
c = _charge_component(int(points.get(atk_type, 0)), atk_type, armor)
|
c = _charge_component(int(points.get(atk_type, 0)), atk_type, armor)
|
||||||
comp[atk_type] = c
|
comp[atk_type] = c
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func spawn(level_index: int, node_depth: int, hero_hp: int, unit_count_override:
|
|||||||
return false
|
return false
|
||||||
# max_hp = 生效上限(非入参 hero_hp)——2026-09-11 关卡扩展批修复:跨战斗携带 HP 时上限不得压扁
|
# 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"}
|
_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 营地扩展前置批——可配置;甲效矩阵消费面)
|
||||||
_enemies.clear() # 难度曲线与Boss DifficultyTable 修饰(2026-09-12 结构位兑现):施加于行值、行值快照之前——MVP 空表 = 恒 1.0 无行为(AC-10)
|
_enemies.clear() # 难度曲线与Boss DifficultyTable 修饰(2026-09-12 结构位兑现):施加于行值、行值快照之前——MVP 空表 = 恒 1.0 无行为(AC-10)
|
||||||
var mod: Dictionary = db.resolve_difficulty_modifiers(level_index, node_depth)
|
var mod: Dictionary = db.resolve_difficulty_modifiers(level_index, node_depth)
|
||||||
var hp_mult: float = float(mod.get("hp_mult", 1.0))
|
var hp_mult: float = float(mod.get("hp_mult", 1.0))
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ extends Resource
|
|||||||
@export var max_hp: int = 50 # [1,999] knob(provisional,溯源 = 原型锚)
|
@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 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_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:
|
func validate() -> Array:
|
||||||
@@ -19,4 +21,8 @@ func validate() -> Array:
|
|||||||
errs.append({"category": "domain", "message": "atk 越域 [1,999]: %d" % atk})
|
errs.append({"category": "domain", "message": "atk 越域 [1,999]: %d" % atk})
|
||||||
if armor_class < 0 or armor_class > 999:
|
if armor_class < 0 or armor_class > 999:
|
||||||
errs.append({"category": "domain", "message": "armor_class 越域 [0,999]: %d" % armor_class})
|
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
|
return errs
|
||||||
@@ -10,10 +10,10 @@ extends Resource
|
|||||||
|
|
||||||
@export var rows: Array = [] # Array[Dictionary]
|
@export var rows: Array = [] # Array[Dictionary]
|
||||||
|
|
||||||
const CELL_TYPES := ["attack", "defense", "heal", "blast", "weaken"] # 五型封闭——清单外加载拒绝
|
const CELL_TYPES := ["attack", "defense", "heal", "blast", "weaken", "pierce", "magic"] # 七型封闭(伤害道具批 2026-09-18 五→七)——清单外加载拒绝
|
||||||
const POLARITIES := ["positive", "negative"]
|
const POLARITIES := ["positive", "negative"]
|
||||||
const POOL_TAGS := ["cell", "clear_default"] # cell = 格面资源单一池;clear_<biome> 命名空间预留拒绝
|
const POOL_TAGS := ["cell", "clear_default"] # cell = 格面资源单一池;clear_<biome> 命名空间预留拒绝
|
||||||
const CELL_TYPE_KEYS := ["attack", "defense", "heal", "blast", "weaken"] # 字典完整性校验轴(类型 × 极性 = 十格)
|
const CELL_TYPE_KEYS := ["attack", "defense", "heal", "blast", "weaken", "pierce", "magic"] # 字典完整性校验轴(类型 × 极性 = 十四格)
|
||||||
|
|
||||||
|
|
||||||
func validate() -> Array:
|
func validate() -> Array:
|
||||||
@@ -39,6 +39,9 @@ func validate() -> Array:
|
|||||||
var pol: String = row.get("polarity", "")
|
var pol: String = row.get("polarity", "")
|
||||||
if not POLARITIES.has(pol):
|
if not POLARITIES.has(pol):
|
||||||
errs.append({"category": "enum", "message": "%s polarity 出域: %s" % [rid, pol]})
|
errs.append({"category": "enum", "message": "%s polarity 出域: %s" % [rid, pol]})
|
||||||
|
var atk_type: String = String(row.get("attack_type", ""))
|
||||||
|
if atk_type != "" and not ["normal", "pierce", "magic"].has(atk_type):
|
||||||
|
errs.append({"category": "enum", "message": "%s attack_type 出域 {normal, pierce, magic}: %s" % [rid, atk_type]})
|
||||||
var pool: String = row.get("pool_tag", "")
|
var pool: String = row.get("pool_tag", "")
|
||||||
var pool_reserved: bool = pool.begins_with("clear_") and pool != "clear_default"
|
var pool_reserved: bool = pool.begins_with("clear_") and pool != "clear_default"
|
||||||
if not POOL_TAGS.has(pool) and not pool_reserved:
|
if not POOL_TAGS.has(pool) and not pool_reserved:
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ rows = [{
|
|||||||
"weight": 2
|
"weight": 2
|
||||||
}],
|
}],
|
||||||
"advantage_per_round_cap": 4,
|
"advantage_per_round_cap": 4,
|
||||||
"armor_type": "ward",
|
"armor_type": "light",
|
||||||
"armor_class": 0
|
"armor_class": 0
|
||||||
}, {
|
}, {
|
||||||
"level_index": 1,
|
"level_index": 1,
|
||||||
@@ -91,7 +91,7 @@ rows = [{
|
|||||||
"weight": 2
|
"weight": 2
|
||||||
}],
|
}],
|
||||||
"advantage_per_round_cap": 4,
|
"advantage_per_round_cap": 4,
|
||||||
"armor_type": "ward",
|
"armor_type": "light",
|
||||||
"armor_class": 0
|
"armor_class": 0
|
||||||
}, {
|
}, {
|
||||||
"level_index": 1,
|
"level_index": 1,
|
||||||
@@ -114,7 +114,7 @@ rows = [{
|
|||||||
"weight": 2
|
"weight": 2
|
||||||
}],
|
}],
|
||||||
"advantage_per_round_cap": 4,
|
"advantage_per_round_cap": 4,
|
||||||
"armor_type": "heavy",
|
"armor_type": "light",
|
||||||
"armor_class": 0
|
"armor_class": 0
|
||||||
}, {
|
}, {
|
||||||
"level_index": 2,
|
"level_index": 2,
|
||||||
@@ -137,7 +137,7 @@ rows = [{
|
|||||||
"weight": 2
|
"weight": 2
|
||||||
}],
|
}],
|
||||||
"advantage_per_round_cap": 4,
|
"advantage_per_round_cap": 4,
|
||||||
"armor_type": "ward",
|
"armor_type": "light",
|
||||||
"armor_class": 0
|
"armor_class": 0
|
||||||
}, {
|
}, {
|
||||||
"level_index": 2,
|
"level_index": 2,
|
||||||
@@ -161,7 +161,7 @@ rows = [{
|
|||||||
"weight": 2
|
"weight": 2
|
||||||
}],
|
}],
|
||||||
"advantage_per_round_cap": 4,
|
"advantage_per_round_cap": 4,
|
||||||
"armor_type": "ward",
|
"armor_type": "light",
|
||||||
"armor_class": 0
|
"armor_class": 0
|
||||||
}, {
|
}, {
|
||||||
"level_index": 2,
|
"level_index": 2,
|
||||||
@@ -207,7 +207,7 @@ rows = [{
|
|||||||
"weight": 2
|
"weight": 2
|
||||||
}],
|
}],
|
||||||
"advantage_per_round_cap": 4,
|
"advantage_per_round_cap": 4,
|
||||||
"armor_type": "ward",
|
"armor_type": "light",
|
||||||
"armor_class": 0
|
"armor_class": 0
|
||||||
}, {
|
}, {
|
||||||
"level_index": 2,
|
"level_index": 2,
|
||||||
@@ -278,7 +278,7 @@ rows = [{
|
|||||||
"weight": 2
|
"weight": 2
|
||||||
}],
|
}],
|
||||||
"advantage_per_round_cap": 4,
|
"advantage_per_round_cap": 4,
|
||||||
"armor_type": "heavy",
|
"armor_type": "ward",
|
||||||
"armor_class": 0
|
"armor_class": 0
|
||||||
}]
|
}]
|
||||||
|
|
||||||
@@ -335,3 +335,9 @@ rows = [{
|
|||||||
; armor_type / armor_class / unit_count 区间 / 技能池权重不动(相对轴与概率轴不压缩)。
|
; armor_type / armor_class / unit_count 区间 / 技能池权重不动(相对轴与概率轴不压缩)。
|
||||||
; 粒度告警登记:atk 1~3 域下掷点折扣 25% 档大量触 damage_floor=1,地板伤害相对权重上升——
|
; 粒度告警登记:atk 1~3 域下掷点折扣 25% 档大量触 damage_floor=1,地板伤害相对权重上升——
|
||||||
; 属压缩的已知效应,难度复测(monte carlo 压缩前后对比)随批产出。行值 provisional 归 难度曲线与Boss。
|
; 属压缩的已知效应,难度复测(monte carlo 压缩前后对比)随批产出。行值 provisional 归 难度曲线与Boss。
|
||||||
|
;
|
||||||
|
; 护甲类型重配批(2026-09-18 用户拍板):关卡 1 全部轻甲(食人魔酋长 heavy→light、熊地精两行 ward→light);
|
||||||
|
; 关卡 2 除 Boss(蛛化卓尔精灵 heavy→ward 魔法甲)外全部轻甲(熊地精四行 ward→light,巨蜘蛛既有 light 不动)。
|
||||||
|
; 现行克制三角(pierce 克 ward ×150 / magic 克 heavy ×150 / 被克 ×50 / light 双向中性)下的读数效果:
|
||||||
|
; L1 克制轴数值中性化(全 light);L2 仅 Boss 战非中性——魔法矢克 Boss ×150、穿刺弹被克 ×50。
|
||||||
|
; hero 侧两轴(armor_type/attack_type)同批入列(hero.tres 批注),敌方技能攻击类型轴仍未开(全部 normal 档)。
|
||||||
@@ -7,6 +7,8 @@ script = ExtResource("1")
|
|||||||
max_hp = 17
|
max_hp = 17
|
||||||
atk = 2
|
atk = 2
|
||||||
armor_class = 10
|
armor_class = 10
|
||||||
|
armor_type = "light"
|
||||||
|
attack_type = "normal"
|
||||||
|
|
||||||
; 数值压缩批(2026-09-17 用户拍板暂定——整体绝对值轴 ÷3):
|
; 数值压缩批(2026-09-17 用户拍板暂定——整体绝对值轴 ÷3):
|
||||||
; max_hp 50→17(16.67 四舍五入)、atk 6→2。armor_class 10 不动(掷点阈值轴,相对量纲不压缩——
|
; max_hp 50→17(16.67 四舍五入)、atk 6→2。armor_class 10 不动(掷点阈值轴,相对量纲不压缩——
|
||||||
@@ -15,3 +17,10 @@ armor_class = 10
|
|||||||
|
|
||||||
; 护甲等级掷点批(2026-09-16 用户拍板):armor_class = 10(暂定基准,归 难度曲线与Boss;
|
; 护甲等级掷点批(2026-09-16 用户拍板):armor_class = 10(暂定基准,归 难度曲线与Boss;
|
||||||
; EV 参考数按判定式复算 = 期望减免 21.25%);ac_up 增益 +1 AC/层(×2 层 = AC+2)在其上加算。
|
; EV 参考数按判定式复算 = 期望减免 21.25%);ac_up 增益 +1 AC/层(×2 层 = AC+2)在其上加算。
|
||||||
|
;
|
||||||
|
; 营地扩展前置批(2026-09-18 用户指令):新增两根可配置轴——
|
||||||
|
; armor_type = 主角护甲类型(light/ward/heavy,缺省 light):甲效矩阵消费面已通(敌方攻击现行恒 normal 档
|
||||||
|
; = 三甲全 100% 数值中性,类型轴生效待敌方技能攻击类型批);
|
||||||
|
; attack_type = 主角基础攻击类型(normal/pierce/magic,缺省 normal):基础攻击量(atk)与攻击类型抽象分离——
|
||||||
|
; 营地永久强化"换成魔法/穿刺攻击"= 改此字段(atk 量轴零改动),战斗段基础分量即按此查甲效矩阵。
|
||||||
|
; 两轴全部 provisional,营地建设批(元进度侧)拍板正式投值。
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# VERTICAL SLICE - NOT FOR PRODUCTION
|
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||||||
# 实现 GDD:design/ux/battle.md(战斗屏 D 区 BoardView——格态/悬停预承诺光标/可挖域呼吸微光/
|
# 实现 GDD:design/ux/battle.md(战斗屏 D 区 BoardView——格态/悬停预承诺光标/可挖域呼吸微光/
|
||||||
# BFS 路径预览/奖励徽章/结算期去饱和锁输入)。
|
# BFS 路径预览/奖励徽章/结算期去饱和锁输入)。
|
||||||
# Date: 2026-09-12(battle.md 五区改造批;基础 = 2026-09-11 HUD框架-lite 版)
|
# Date: 2026-09-12(battle.md 战斗屏改造批;基础 = 2026-09-11 HUD框架-lite 版)
|
||||||
# 棋盘视图:格子渲染(art-bible 明亮风、数字高对比、
|
# 棋盘视图:格子渲染(art-bible 明亮风、数字高对比、
|
||||||
# 绘制优先级 数字>小人>旗>奖励徽章>底色)+ 玩家输入意图翻译 + 悬停预承诺三态。
|
# 绘制优先级 数字>小人>旗>奖励徽章>底色)+ 玩家输入意图翻译 + 悬停预承诺三态。
|
||||||
# 高内聚边界:只读 排雷玩法 查询面(+地图战斗资源 身份解析回调)做渲染与意图识别,动作经信号外发——不调用核心写接口
|
# 高内聚边界:只读 排雷玩法 查询面(+地图战斗资源 身份解析回调)做渲染与意图识别,动作经信号外发——不调用核心写接口
|
||||||
@@ -25,7 +25,7 @@ const COL_PATH := Color8(46, 110, 142) # 路径预览点迹——小人
|
|||||||
const COL_DIG_EDGE := Color8(120, 190, 120) # 可挖域呼吸微光基色(绿相,明度贴格底)
|
const COL_DIG_EDGE := Color8(120, 190, 120) # 可挖域呼吸微光基色(绿相,明度贴格底)
|
||||||
const COL_HL_TARGET := Color8(240, 168, 40) # 悬停目标格边框(金)
|
const COL_HL_TARGET := Color8(240, 168, 40) # 悬停目标格边框(金)
|
||||||
const REWARD_BADGE := { # 已开格格面资源身份 icon(cell_type 五型键;极性视觉归批 2)
|
const REWARD_BADGE := { # 已开格格面资源身份 icon(cell_type 五型键;极性视觉归批 2)
|
||||||
"attack": "攻", "defense": "守", "heal": "医", "blast": "爆", "weaken": "弱",
|
"attack": "攻", "defense": "守", "heal": "医", "blast": "爆", "weaken": "弱", "pierce": "穿", "magic": "魔", # 穿/魔 = 伤害道具批 2026-09-18
|
||||||
}
|
}
|
||||||
const BADGE_PLACEHOLDER := "?" # 未知图标键占位纹样(HUD框架:禁静默空图标)
|
const BADGE_PLACEHOLDER := "?" # 未知图标键占位纹样(HUD框架:禁静默空图标)
|
||||||
const CURSOR_DIG := Input.CURSOR_CROSS # 挖——镐形自绘纹理载体
|
const CURSOR_DIG := Input.CURSOR_CROSS # 挖——镐形自绘纹理载体
|
||||||
@@ -278,7 +278,7 @@ func _update_badge(c: Vector2i, btn: Button) -> void:
|
|||||||
badge.visible = true
|
badge.visible = true
|
||||||
|
|
||||||
|
|
||||||
# 奖励图标键解析(HUD框架:查不到的键立即断言 + ? 占位纹样 + 诊断;键集 = 格面资源 cell_type 五值枚举)
|
# 奖励图标键解析(HUD框架:查不到的键立即断言 + ? 占位纹样 + 诊断;键集 = 格面资源 cell_type 七值枚举——伤害道具批 2026-09-18 五→七)
|
||||||
func _badge_glyph(category: String) -> String:
|
func _badge_glyph(category: String) -> String:
|
||||||
if REWARD_BADGE.has(category):
|
if REWARD_BADGE.has(category):
|
||||||
return REWARD_BADGE[category]
|
return REWARD_BADGE[category]
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ func _run_core_smoke(db, rng) -> void:
|
|||||||
_smoke_armor_roll()
|
_smoke_armor_roll()
|
||||||
_smoke_board_generator()
|
_smoke_board_generator()
|
||||||
_smoke_variation_framework()
|
_smoke_variation_framework()
|
||||||
_smoke_full_battle(1, 0, "L1 · grub")
|
_smoke_full_battle(1, 0, "L1 · 地精")
|
||||||
_smoke_full_battle(2, 0, "L2 · ambusher")
|
_smoke_full_battle(2, 0, "L2 · 兄弟精")
|
||||||
_smoke_level()
|
_smoke_level()
|
||||||
_smoke_flag_ap_exhausted()
|
_smoke_flag_ap_exhausted()
|
||||||
_smoke_reward_identity_unit()
|
_smoke_reward_identity_unit()
|
||||||
@@ -492,7 +492,9 @@ func _smoke_full_battle(L: int, D: int, label: String) -> void:
|
|||||||
if not (row.has("normal") and row.has("pierce") and row.has("magic")):
|
if not (row.has("normal") and row.has("pierce") and row.has("magic")):
|
||||||
hero_breakdown_ok = false
|
hero_breakdown_ok = false
|
||||||
check(has_verdict, "%s 步骤流含判定行" % label)
|
check(has_verdict, "%s 步骤流含判定行" % label)
|
||||||
check(hero_attacks >= 1, "%s 主角先手攻击行存在(2026-09-11 拍板①)×%d" % [label, hero_attacks])
|
# 伤害道具批(2026-09-18):单弱敌遭遇可被挖掘期兑付(穿刺弹/魔法矢/爆裂粉尘)在授予段单独击杀——
|
||||||
|
# 敌全灭后战斗段整段跳过、零先手行为合法结局;先手规则本身由强敌场景(L1/L2 深节点)继续守护。
|
||||||
|
check(hero_attacks >= 1 or run1.terminated, "%s 主角先手攻击行存在或授予段终局(2026-09-11 拍板① + 伤害道具批)×%d" % [label, hero_attacks])
|
||||||
check(hero_breakdown_ok, "%s 主角攻击行携带三分量 normal/pierce/magic(克制批)" % label)
|
check(hero_breakdown_ok, "%s 主角攻击行携带三分量 normal/pierce/magic(克制批)" % label)
|
||||||
|
|
||||||
|
|
||||||
@@ -719,9 +721,9 @@ func _smoke_difficulty_table() -> void:
|
|||||||
# ① 空表零行为:敌人系统.spawn 敌值 = EnemyTable 行值原样
|
# ① 空表零行为:敌人系统.spawn 敌值 = EnemyTable 行值原样
|
||||||
var enemy_system = load("res://core/unit_container.gd").new(_db)
|
var enemy_system = load("res://core/unit_container.gd").new(_db)
|
||||||
check(enemy_system.spawn(1, 0, int(_db.hero.max_hp)), "spawn 受理")
|
check(enemy_system.spawn(1, 0, int(_db.hero.max_hp)), "spawn 受理")
|
||||||
var grub = enemy_system.all_enemies()[0]
|
var unit = enemy_system.all_enemies()[0]
|
||||||
var d0: Dictionary = _db.resolve_enemy_rowset(1, 0)
|
var d0: Dictionary = _db.resolve_enemy_rowset(1, 0)
|
||||||
check(int(grub.hp) == int(d0.hp) and int(grub.atk) == int(d0.atk), "空表零修饰(hp=%d atk=%d = 行值 %d/%d)" % [int(grub.hp), int(grub.atk), int(d0.hp), int(d0.atk)])
|
check(int(unit.hp) == int(d0.hp) and int(unit.atk) == int(d0.atk), "空表零修饰(hp=%d atk=%d = 行值 %d/%d)" % [int(unit.hp), int(unit.atk), int(d0.hp), int(d0.atk)])
|
||||||
# ② 修饰行运行时注入(debug 通道——R3 override 同族):套乘生效于 hp/atk
|
# ② 修饰行运行时注入(debug 通道——R3 override 同族):套乘生效于 hp/atk
|
||||||
_db.difficulty.rows.append({"level_index": 1, "node_depth": 0, "hp_mult": 1.5, "atk_mult": 2.0})
|
_db.difficulty.rows.append({"level_index": 1, "node_depth": 0, "hp_mult": 1.5, "atk_mult": 2.0})
|
||||||
var enemy_system_b = load("res://core/unit_container.gd").new(_db)
|
var enemy_system_b = load("res://core/unit_container.gd").new(_db)
|
||||||
@@ -746,9 +748,9 @@ func _smoke_damage_types() -> void:
|
|||||||
var enemy_system = load("res://core/unit_container.gd").new(_db)
|
var enemy_system = load("res://core/unit_container.gd").new(_db)
|
||||||
check(enemy_system.spawn(1, 0, int(_db.hero.max_hp)) and String(enemy_system.all_enemies()[0].armor_type) == "light", "goblin 护甲 = light(轻甲——教学位)")
|
check(enemy_system.spawn(1, 0, int(_db.hero.max_hp)) and String(enemy_system.all_enemies()[0].armor_type) == "light", "goblin 护甲 = light(轻甲——教学位)")
|
||||||
var enemy_system_b = load("res://core/unit_container.gd").new(_db)
|
var enemy_system_b = load("res://core/unit_container.gd").new(_db)
|
||||||
check(enemy_system_b.spawn(1, 2, int(_db.hero.max_hp)) and String(enemy_system_b.all_enemies()[0].armor_type) == "ward", "bugbear 护甲 = ward(魔法护甲)")
|
check(enemy_system_b.spawn(1, 2, int(_db.hero.max_hp)) and String(enemy_system_b.all_enemies()[0].armor_type) == "light", "bugbear 护甲 = light(护甲类型重配批 2026-09-18:关卡 1 全轻甲)")
|
||||||
var enemy_system_c = load("res://core/unit_container.gd").new(_db)
|
var enemy_system_c = load("res://core/unit_container.gd").new(_db)
|
||||||
check(enemy_system_c.spawn(1, 4, int(_db.hero.max_hp)) and String(enemy_system_c.all_enemies()[0].armor_type) == "heavy", "ogre_chief 护甲 = heavy(重甲)")
|
check(enemy_system_c.spawn(1, 4, int(_db.hero.max_hp)) and String(enemy_system_c.all_enemies()[0].armor_type) == "light", "ogre_chief 护甲 = light(护甲类型重配批 2026-09-18:关卡 1 全轻甲)")
|
||||||
# ② 克制矩阵表值在位(三角:克制 150 / 中性 100 / 被克 50)
|
# ② 克制矩阵表值在位(三角:克制 150 / 中性 100 / 被克 50)
|
||||||
var am: Dictionary = _db.settlement.armor_effectiveness
|
var am: Dictionary = _db.settlement.armor_effectiveness
|
||||||
check(int(am.pierce.ward) == 150 and int(am.pierce.heavy) == 50 and int(am.pierce.light) == 100, "穿刺克制行:魔法护甲 150 / 轻甲 100 / 重甲 50")
|
check(int(am.pierce.ward) == 150 and int(am.pierce.heavy) == 50 and int(am.pierce.light) == 100, "穿刺克制行:魔法护甲 150 / 轻甲 100 / 重甲 50")
|
||||||
@@ -1951,8 +1953,8 @@ func _smoke_level_graph() -> void:
|
|||||||
var l2_spider: Dictionary = _db.enemy.resolve_rowset(2, 4)
|
var l2_spider: Dictionary = _db.enemy.resolve_rowset(2, 4)
|
||||||
check(String(l2_spider.get("enemy_id", "")) == "giant_spider", "巨蜘蛛首遇行集 (2,4) = giant_spider(固定 2 只——首遇教学位不加骰)")
|
check(String(l2_spider.get("enemy_id", "")) == "giant_spider", "巨蜘蛛首遇行集 (2,4) = giant_spider(固定 2 只——首遇教学位不加骰)")
|
||||||
var l2_boss: Dictionary = _db.enemy.resolve_rowset(2, 8)
|
var l2_boss: Dictionary = _db.enemy.resolve_rowset(2, 8)
|
||||||
check(String(l2_boss.get("enemy_id", "")) == "drider" and String(l2_boss.get("armor_type", "")) == "heavy",
|
check(String(l2_boss.get("enemy_id", "")) == "drider" and String(l2_boss.get("armor_type", "")) == "ward",
|
||||||
"蛛化卓尔精灵 Boss 行集 (2,8) = drider(重甲——同关敌种克制面错开)")
|
"蛛化卓尔精灵 Boss 行集 (2,8) = drider(魔法甲——护甲类型重配批 2026-09-18:关卡 2 唯一非轻甲)")
|
||||||
|
|
||||||
|
|
||||||
# 冒烟隔离用全新 RngService(同 master 种子——回放确定性纪律)
|
# 冒烟隔离用全新 RngService(同 master 种子——回放确定性纪律)
|
||||||
|
|||||||
Reference in new issue
Block a user