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
@@ -284,6 +284,7 @@ func _apply_percent_row(row: Dictionary, source_class: String, cell: Vector2i, r
|
||||
# flat 行兑付(负向恒即时,无库存语义):
|
||||
# blast 正向 = 全体存活敌各 power 点(无敌 → 奖励未生效行);blast 负向 = 敌方伏击 +stacks 层(cap/溢出行协议不变);
|
||||
# heal 正向 = 主角回复 clamp(满血 → 奖励未生效行);heal 负向 = 主角直伤 power 点(不经增益状态;归零 → 战斗段短路/判定段判负)。
|
||||
# pierce/magic(伤害道具批 2026-09-18)正向 = 单目标克制直伤(必中全额);负向 = 主角直伤。
|
||||
# 返回 "redeemed" = 实际有效兑付 / "zero" = 零兑付(行已自记)——清图高光只记实际有效兑付。
|
||||
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)
|
||||
@@ -300,6 +301,23 @@ func _apply_flat_row(row: Dictionary, source_class: String, cell: Vector2i, ri:
|
||||
_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)
|
||||
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 String(row.get("polarity", "positive")) == "negative":
|
||||
_enemy_system.apply_damage(_enemy_system.hero_unit(), power)
|
||||
@@ -423,7 +441,8 @@ func _roll_round_actions() -> void:
|
||||
func _combat_segment(ri: int) -> void:
|
||||
var L := _status_effects.pool_layers("ambush") # 授予段后的当轮值;池共享不消耗
|
||||
# ⓪ 主角先手攻击(基础攻击恒存在——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)。攻击类型只管查甲效矩阵哪一行,与来源无关。
|
||||
# 护甲等级掷点批(2026-09-16):普通分量吃掷点判定(含暴击);穿刺/魔法充能分量与棋盘来源伤害不掷不折;
|
||||
# 任何攻击落地伤害 ≥ damage_floor(全局 max(1,·))——"被减伤归零 v=0"零值伤害行分支随批退役。
|
||||
@@ -431,9 +450,10 @@ func _combat_segment(ri: int) -> void:
|
||||
var hero_target = _enemy_system.default_target()
|
||||
if hero_alive and hero_target != null:
|
||||
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 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 crit: bool = bool(roll_read.crit)
|
||||
var discount: int = _roll_discount(int(roll_read.roll), threshold)
|
||||
@@ -442,8 +462,9 @@ func _combat_segment(ri: int) -> void:
|
||||
var d_hero := 0
|
||||
for atk_type in SettlementTable.ATTACK_TYPE_KEYS:
|
||||
var c: int = 0
|
||||
if atk_type == "normal":
|
||||
c = DamageMath.rolled_component(base_val, discount, crit, int(db.settlement.crit_multiplier), _armor_effectiveness("normal", armor))
|
||||
if atk_type == base_atk_type:
|
||||
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:
|
||||
c = _charge_component(int(points.get(atk_type, 0)), atk_type, armor)
|
||||
comp[atk_type] = c
|
||||
|
||||
@@ -51,7 +51,7 @@ func spawn(level_index: int, node_depth: int, hero_hp: int, unit_count_override:
|
||||
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"}
|
||||
_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)
|
||||
var mod: Dictionary = db.resolve_difficulty_modifiers(level_index, node_depth)
|
||||
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 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:
|
||||
@@ -19,4 +21,8 @@ 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
|
||||
@@ -10,10 +10,10 @@ extends Resource
|
||||
|
||||
@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 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:
|
||||
@@ -39,6 +39,9 @@ func validate() -> Array:
|
||||
var pol: String = row.get("polarity", "")
|
||||
if not POLARITIES.has(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_reserved: bool = pool.begins_with("clear_") and pool != "clear_default"
|
||||
if not POOL_TAGS.has(pool) and not pool_reserved:
|
||||
|
||||
@@ -67,7 +67,7 @@ rows = [{
|
||||
"weight": 2
|
||||
}],
|
||||
"advantage_per_round_cap": 4,
|
||||
"armor_type": "ward",
|
||||
"armor_type": "light",
|
||||
"armor_class": 0
|
||||
}, {
|
||||
"level_index": 1,
|
||||
@@ -91,7 +91,7 @@ rows = [{
|
||||
"weight": 2
|
||||
}],
|
||||
"advantage_per_round_cap": 4,
|
||||
"armor_type": "ward",
|
||||
"armor_type": "light",
|
||||
"armor_class": 0
|
||||
}, {
|
||||
"level_index": 1,
|
||||
@@ -114,7 +114,7 @@ rows = [{
|
||||
"weight": 2
|
||||
}],
|
||||
"advantage_per_round_cap": 4,
|
||||
"armor_type": "heavy",
|
||||
"armor_type": "light",
|
||||
"armor_class": 0
|
||||
}, {
|
||||
"level_index": 2,
|
||||
@@ -137,7 +137,7 @@ rows = [{
|
||||
"weight": 2
|
||||
}],
|
||||
"advantage_per_round_cap": 4,
|
||||
"armor_type": "ward",
|
||||
"armor_type": "light",
|
||||
"armor_class": 0
|
||||
}, {
|
||||
"level_index": 2,
|
||||
@@ -161,7 +161,7 @@ rows = [{
|
||||
"weight": 2
|
||||
}],
|
||||
"advantage_per_round_cap": 4,
|
||||
"armor_type": "ward",
|
||||
"armor_type": "light",
|
||||
"armor_class": 0
|
||||
}, {
|
||||
"level_index": 2,
|
||||
@@ -207,7 +207,7 @@ rows = [{
|
||||
"weight": 2
|
||||
}],
|
||||
"advantage_per_round_cap": 4,
|
||||
"armor_type": "ward",
|
||||
"armor_type": "light",
|
||||
"armor_class": 0
|
||||
}, {
|
||||
"level_index": 2,
|
||||
@@ -278,7 +278,7 @@ rows = [{
|
||||
"weight": 2
|
||||
}],
|
||||
"advantage_per_round_cap": 4,
|
||||
"armor_type": "heavy",
|
||||
"armor_type": "ward",
|
||||
"armor_class": 0
|
||||
}]
|
||||
|
||||
@@ -335,3 +335,9 @@ rows = [{
|
||||
; armor_type / armor_class / unit_count 区间 / 技能池权重不动(相对轴与概率轴不压缩)。
|
||||
; 粒度告警登记:atk 1~3 域下掷点折扣 25% 档大量触 damage_floor=1,地板伤害相对权重上升——
|
||||
; 属压缩的已知效应,难度复测(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
|
||||
atk = 2
|
||||
armor_class = 10
|
||||
armor_type = "light"
|
||||
attack_type = "normal"
|
||||
|
||||
; 数值压缩批(2026-09-17 用户拍板暂定——整体绝对值轴 ÷3):
|
||||
; 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;
|
||||
; 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
|
||||
# 实现 GDD:design/ux/battle.md(战斗屏 D 区 BoardView——格态/悬停预承诺光标/可挖域呼吸微光/
|
||||
# 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 明亮风、数字高对比、
|
||||
# 绘制优先级 数字>小人>旗>奖励徽章>底色)+ 玩家输入意图翻译 + 悬停预承诺三态。
|
||||
# 高内聚边界:只读 排雷玩法 查询面(+地图战斗资源 身份解析回调)做渲染与意图识别,动作经信号外发——不调用核心写接口
|
||||
@@ -25,7 +25,7 @@ const COL_PATH := Color8(46, 110, 142) # 路径预览点迹——小人
|
||||
const COL_DIG_EDGE := Color8(120, 190, 120) # 可挖域呼吸微光基色(绿相,明度贴格底)
|
||||
const COL_HL_TARGET := Color8(240, 168, 40) # 悬停目标格边框(金)
|
||||
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 CURSOR_DIG := Input.CURSOR_CROSS # 挖——镐形自绘纹理载体
|
||||
@@ -278,7 +278,7 @@ func _update_badge(c: Vector2i, btn: Button) -> void:
|
||||
badge.visible = true
|
||||
|
||||
|
||||
# 奖励图标键解析(HUD框架:查不到的键立即断言 + ? 占位纹样 + 诊断;键集 = 格面资源 cell_type 五值枚举)
|
||||
# 奖励图标键解析(HUD框架:查不到的键立即断言 + ? 占位纹样 + 诊断;键集 = 格面资源 cell_type 七值枚举——伤害道具批 2026-09-18 五→七)
|
||||
func _badge_glyph(category: String) -> String:
|
||||
if REWARD_BADGE.has(category):
|
||||
return REWARD_BADGE[category]
|
||||
|
||||
@@ -66,8 +66,8 @@ func _run_core_smoke(db, rng) -> void:
|
||||
_smoke_armor_roll()
|
||||
_smoke_board_generator()
|
||||
_smoke_variation_framework()
|
||||
_smoke_full_battle(1, 0, "L1 · grub")
|
||||
_smoke_full_battle(2, 0, "L2 · ambusher")
|
||||
_smoke_full_battle(1, 0, "L1 · 地精")
|
||||
_smoke_full_battle(2, 0, "L2 · 兄弟精")
|
||||
_smoke_level()
|
||||
_smoke_flag_ap_exhausted()
|
||||
_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")):
|
||||
hero_breakdown_ok = false
|
||||
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)
|
||||
|
||||
|
||||
@@ -719,9 +721,9 @@ func _smoke_difficulty_table() -> void:
|
||||
# ① 空表零行为:敌人系统.spawn 敌值 = EnemyTable 行值原样
|
||||
var enemy_system = load("res://core/unit_container.gd").new(_db)
|
||||
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)
|
||||
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
|
||||
_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)
|
||||
@@ -746,9 +748,9 @@ func _smoke_damage_types() -> void:
|
||||
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(轻甲——教学位)")
|
||||
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)
|
||||
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)
|
||||
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")
|
||||
@@ -1951,8 +1953,8 @@ func _smoke_level_graph() -> void:
|
||||
var l2_spider: Dictionary = _db.enemy.resolve_rowset(2, 4)
|
||||
check(String(l2_spider.get("enemy_id", "")) == "giant_spider", "巨蜘蛛首遇行集 (2,4) = giant_spider(固定 2 只——首遇教学位不加骰)")
|
||||
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",
|
||||
"蛛化卓尔精灵 Boss 行集 (2,8) = drider(重甲——同关敌种克制面错开)")
|
||||
check(String(l2_boss.get("enemy_id", "")) == "drider" and String(l2_boss.get("armor_type", "")) == "ward",
|
||||
"蛛化卓尔精灵 Boss 行集 (2,8) = drider(魔法甲——护甲类型重配批 2026-09-18:关卡 2 唯一非轻甲)")
|
||||
|
||||
|
||||
# 冒烟隔离用全新 RngService(同 master 种子——回放确定性纪律)
|
||||
|
||||
Reference in new issue
Block a user