feat(content): 第三关内容批落地——灰矮人矿城行集+词表v1.1+直入口+冒烟断言(台账 113);GP+商店房定稿提案交付
This commit is contained in:
1 parent
931bba7dfa
commit
9ac1540c46
17 files changed
+635
-25
No files matched your search
@@ -10,7 +10,7 @@ extends Resource
|
||||
const SOLVER_RULES := ["single", "single_subset"]
|
||||
const COST_BUDGET := 16384 # F2c provisional 量级护栏(禁墙钟逃生)
|
||||
const TARGET_ABS_FLOOR := 0.85 # 战斗结算 修订——target 域下限(P1 绝对锚)
|
||||
const BOARD_TYPE_VOCABULARY := ["dungeon", "underdark"] # 图类型词表 v1.0(玩家侧显示名「地图类型」)
|
||||
const BOARD_TYPE_VOCABULARY := ["dungeon", "underdark", "deep_underdark"] # 图类型词表 v1.1(2026-09-20 L3 内容批 +deep_underdark 灰矮人矿道;玩家侧显示名「地图类型」)
|
||||
|
||||
|
||||
func validate() -> Array:
|
||||
|
||||
@@ -136,6 +136,83 @@ rows = [{
|
||||
"min_safe_count": 60,
|
||||
"max_gen_attempts": 24,
|
||||
"board_type": "underdark"
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 0,
|
||||
"board_width": 13,
|
||||
"board_height": 13,
|
||||
"mine_density": 0.25,
|
||||
"inferability_target": 0.88,
|
||||
"solver_rules": "single_subset",
|
||||
"min_safe_count": 70,
|
||||
"max_gen_attempts": 32,
|
||||
"board_type": "deep_underdark"
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 1,
|
||||
"board_width": 13,
|
||||
"board_height": 13,
|
||||
"mine_density": 0.25,
|
||||
"inferability_target": 0.88,
|
||||
"solver_rules": "single_subset",
|
||||
"min_safe_count": 70,
|
||||
"max_gen_attempts": 32,
|
||||
"board_type": "deep_underdark"
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 4,
|
||||
"board_width": 13,
|
||||
"board_height": 13,
|
||||
"mine_density": 0.25,
|
||||
"inferability_target": 0.88,
|
||||
"solver_rules": "single_subset",
|
||||
"min_safe_count": 70,
|
||||
"max_gen_attempts": 32,
|
||||
"board_type": "deep_underdark"
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 5,
|
||||
"board_width": 13,
|
||||
"board_height": 13,
|
||||
"mine_density": 0.25,
|
||||
"inferability_target": 0.88,
|
||||
"solver_rules": "single_subset",
|
||||
"min_safe_count": 70,
|
||||
"max_gen_attempts": 32,
|
||||
"board_type": "deep_underdark"
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 6,
|
||||
"board_width": 13,
|
||||
"board_height": 13,
|
||||
"mine_density": 0.25,
|
||||
"inferability_target": 0.88,
|
||||
"solver_rules": "single_subset",
|
||||
"min_safe_count": 70,
|
||||
"max_gen_attempts": 32,
|
||||
"board_type": "deep_underdark"
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 7,
|
||||
"board_width": 13,
|
||||
"board_height": 13,
|
||||
"mine_density": 0.25,
|
||||
"inferability_target": 0.88,
|
||||
"solver_rules": "single_subset",
|
||||
"min_safe_count": 70,
|
||||
"max_gen_attempts": 32,
|
||||
"board_type": "deep_underdark"
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 8,
|
||||
"board_width": 14,
|
||||
"board_height": 14,
|
||||
"mine_density": 0.25,
|
||||
"inferability_target": 0.88,
|
||||
"solver_rules": "single_subset",
|
||||
"min_safe_count": 82,
|
||||
"max_gen_attempts": 32,
|
||||
"board_type": "deep_underdark"
|
||||
}]
|
||||
|
||||
; 切片调参登记(SLICE-TUNED provisional,调参所有权仍归 C3):
|
||||
@@ -152,3 +229,10 @@ rows = [{
|
||||
; 奖励点 (2,2)/恢复点 (2,3) 不开战斗、无板行(跨表校验只查 battle/boss 节点)。
|
||||
; 板面参数与 L1 高档同值(12×12 d0.25 t0.88)——密度/推理率轴差异化留给 难度曲线与Boss 调参批;
|
||||
; board_type 词表 v1.0(2026-09-19 用户拍板):L1=dungeon 地牢基线 / L2=underdark 幽暗地域(玩家侧显示名「地图类型」);域校验在 board_gen_table.gd 词表常量。
|
||||
;
|
||||
; 第三关内容批(2026-09-20):板面 13×13 / Boss 14×14 兑现「Boss 板 = 本关最大板形」纪律;
|
||||
; 密度维持 0.25(0.28 破推理率门槛有失败先例——切片调参登记 best≈0.81 降级告警,加难主杠杆 = 板面 + 地形);
|
||||
; 词表第三值 deep_underdark(灰矮人矿道方向——v1.1 2026-09-20 L3 内容批,显示名归呈现侧);
|
||||
; min_safe_count 按既有 ~0.42 格占比外推(13×13 → 70 / 14×14 → 82)。
|
||||
; 降档登记:Boss max_gen_attempts 批内拟值 36 越 schema 域 [1,32](config_fatal 修行值纪律——不许放宽 schema),
|
||||
; 按域上限取 32(批内降档梯子「Boss 回 13×13 时 attempts 32」同款值)。行值全 provisional 归 难度曲线与Boss。
|
||||
@@ -271,6 +271,163 @@ rows = [{
|
||||
}],
|
||||
"armor_type": "ward",
|
||||
"armor_class": 0
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 0,
|
||||
"enemy_id": "duergar",
|
||||
"display_name": "灰矮人",
|
||||
"unit_count": 1,
|
||||
"hp": 15,
|
||||
"atk": 3,
|
||||
"atk_min": 2,
|
||||
"atk_max": 4,
|
||||
"pool": [{
|
||||
"skill_id": "attack",
|
||||
"weight": 6
|
||||
}, {
|
||||
"skill_id": "charge",
|
||||
"weight": 2
|
||||
}, {
|
||||
"skill_id": "heavy",
|
||||
"weight": 2
|
||||
}],
|
||||
"armor_type": "heavy",
|
||||
"armor_class": 0
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 1,
|
||||
"enemy_id": "hook_horror",
|
||||
"display_name": "钩爪恐魔",
|
||||
"unit_count": 2,
|
||||
"hp": 5,
|
||||
"atk": 2,
|
||||
"atk_min": 1,
|
||||
"atk_max": 3,
|
||||
"pool": [{
|
||||
"skill_id": "attack",
|
||||
"weight": 6
|
||||
}, {
|
||||
"skill_id": "bite",
|
||||
"weight": 2
|
||||
}, {
|
||||
"skill_id": "charge",
|
||||
"weight": 1
|
||||
}],
|
||||
"armor_type": "light",
|
||||
"armor_class": 0
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 4,
|
||||
"enemy_id": "hook_horror",
|
||||
"display_name": "钩爪恐魔",
|
||||
"unit_count": 2,
|
||||
"unit_count_max": 3,
|
||||
"hp": 5,
|
||||
"atk": 2,
|
||||
"atk_min": 1,
|
||||
"atk_max": 3,
|
||||
"pool": [{
|
||||
"skill_id": "attack",
|
||||
"weight": 6
|
||||
}, {
|
||||
"skill_id": "bite",
|
||||
"weight": 2
|
||||
}, {
|
||||
"skill_id": "charge",
|
||||
"weight": 1
|
||||
}],
|
||||
"armor_type": "light",
|
||||
"armor_class": 0
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 5,
|
||||
"enemy_id": "duergar",
|
||||
"display_name": "灰矮人重装手",
|
||||
"unit_count": 1,
|
||||
"hp": 16,
|
||||
"atk": 3,
|
||||
"atk_min": 2,
|
||||
"atk_max": 4,
|
||||
"pool": [{
|
||||
"skill_id": "attack",
|
||||
"weight": 5
|
||||
}, {
|
||||
"skill_id": "lunge",
|
||||
"weight": 2
|
||||
}, {
|
||||
"skill_id": "heavy",
|
||||
"weight": 2
|
||||
}],
|
||||
"armor_type": "heavy",
|
||||
"armor_class": 0
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 6,
|
||||
"enemy_id": "hook_horror",
|
||||
"display_name": "钩爪恐魔巢群",
|
||||
"unit_count": 2,
|
||||
"unit_count_max": 3,
|
||||
"hp": 6,
|
||||
"atk": 2,
|
||||
"atk_min": 1,
|
||||
"atk_max": 3,
|
||||
"pool": [{
|
||||
"skill_id": "attack",
|
||||
"weight": 6
|
||||
}, {
|
||||
"skill_id": "bite",
|
||||
"weight": 2
|
||||
}, {
|
||||
"skill_id": "charge",
|
||||
"weight": 1
|
||||
}],
|
||||
"armor_type": "light",
|
||||
"armor_class": 0
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 7,
|
||||
"enemy_id": "duergar",
|
||||
"display_name": "灰矮人小队",
|
||||
"unit_count": 2,
|
||||
"unit_count_max": 3,
|
||||
"hp": 8,
|
||||
"atk": 3,
|
||||
"atk_min": 2,
|
||||
"atk_max": 4,
|
||||
"pool": [{
|
||||
"skill_id": "attack",
|
||||
"weight": 6
|
||||
}, {
|
||||
"skill_id": "charge",
|
||||
"weight": 2
|
||||
}, {
|
||||
"skill_id": "heavy",
|
||||
"weight": 2
|
||||
}],
|
||||
"armor_type": "heavy",
|
||||
"armor_class": 0
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"node_depth": 8,
|
||||
"enemy_id": "duergar_king",
|
||||
"display_name": "灰矮人石君王",
|
||||
"unit_count": 1,
|
||||
"hp": 75,
|
||||
"atk": 3,
|
||||
"atk_min": 2,
|
||||
"atk_max": 4,
|
||||
"pool": [{
|
||||
"skill_id": "attack",
|
||||
"weight": 6
|
||||
}, {
|
||||
"skill_id": "heavy",
|
||||
"weight": 2
|
||||
}, {
|
||||
"skill_id": "earth_pulse",
|
||||
"weight": 2
|
||||
}],
|
||||
"armor_type": "heavy",
|
||||
"armor_class": 0
|
||||
}]
|
||||
|
||||
; 切片调参登记 v3(2026-09-12 试玩批次 1 触发——F7 流程;C3 GDD F5 对照):
|
||||
@@ -341,3 +498,12 @@ rows = [{
|
||||
; 现行读数效果:L1/L2 小怪全 light → 穿刺类(开格充能/穿刺弹)被克 −1(穿刺弹 2→1、充能 3 点→2)、普通/魔法中性;
|
||||
; L2 仅 Boss 战非中性(魔法甲)——基础攻击与穿刺弹克制 +1、魔法矢被克 −1(原威力 + delta 自行核算后落笔)。
|
||||
; 原重配批注「魔法矢克 Boss ×150、穿刺弹被克 ×50」与当批矩阵正反互倒(系笔误),随本批订正为上行读数。
|
||||
;
|
||||
; 第三关内容批(2026-09-20):新敌种 duergar 灰矮人(单体重甲中坚——关间台阶 ≈L2 单体 ×1.5,落 [1.3,1.6] 域)
|
||||
; 与 hook_horror 钩爪恐魔(群行捕食者,复用 bite 共享技能行——lunge 已有兄弟精复用先例);两敌种首遇位
|
||||
; (节点 0 / 节点 1)固定数量不加骰——新敌种首遇教学位纪律同 L1 D2 / L2 节点 4;克制面重轻错开
|
||||
; (重甲灰矮人 = 重甲首次登台,轻甲钩爪恐魔保穿刺/普通分量有用武之地),Boss duergar_king 灰矮人石君王
|
||||
; 重甲收束「轻甲→魔法甲→重甲」教学梯度;Boss 血量 75 = Σ普通战生命期望 91 × r_boss≈0.82
|
||||
; (provisional 锚,域 [0.5,1.1]);Boss 专属池独占技 earth_pulse(第二妨害词汇 sapped 首发);
|
||||
; armor_class 恒 0(正式投值仍归「敌方护甲等级正式行值」在案条目全表同批)。行值全 provisional
|
||||
; 归 难度曲线与Boss。
|
||||
@@ -68,6 +68,46 @@ rows = [{
|
||||
"node_depth": 8,
|
||||
"type": "boss"
|
||||
}]
|
||||
}, {
|
||||
"level_index": 3,
|
||||
"display_name": "第三层 · 灰矮人矿城",
|
||||
"rest_heal_pct": 30,
|
||||
"nodes": [{
|
||||
"node_depth": 0,
|
||||
"type": "battle",
|
||||
"next": [1, 2]
|
||||
}, {
|
||||
"node_depth": 1,
|
||||
"type": "battle",
|
||||
"next": [3, 4]
|
||||
}, {
|
||||
"node_depth": 2,
|
||||
"type": "reward",
|
||||
"next": [4, 5]
|
||||
}, {
|
||||
"node_depth": 3,
|
||||
"type": "rest",
|
||||
"next": [6]
|
||||
}, {
|
||||
"node_depth": 4,
|
||||
"type": "battle",
|
||||
"next": [6, 7]
|
||||
}, {
|
||||
"node_depth": 5,
|
||||
"type": "battle",
|
||||
"next": [7]
|
||||
}, {
|
||||
"node_depth": 6,
|
||||
"type": "battle",
|
||||
"next": [8]
|
||||
}, {
|
||||
"node_depth": 7,
|
||||
"type": "battle",
|
||||
"next": [8]
|
||||
}, {
|
||||
"node_depth": 8,
|
||||
"type": "boss"
|
||||
}]
|
||||
}]
|
||||
|
||||
; 切片登记(provisional——C1/C3 未设计,结构位与数值均为 SLICE-TUNED):
|
||||
@@ -95,3 +135,8 @@ rows = [{
|
||||
; 层名二改批(2026-09-20 用户拍板):「裂颚洞窟」→「地精洞窟」——不绑定 DND 专名部族
|
||||
; (规避 IP 指涉),直取地精巢穴意象;洞窟纵深连通幽暗地域的取向不变。
|
||||
; 仅 display_name 字面变更,节点结构 / 行值零改动。
|
||||
;
|
||||
; 第三关内容批(2026-09-20 用户拍板走 proposal-level3-content-2026-09-20.md 推荐):
|
||||
; L3 行集复用 L2 九节点图模板(6 战 + Boss + 奖励 + 恢复,真实岔路 4 处);灰矮人矿城主题
|
||||
; (DND 幽暗地域最深层方向)。仅行集落地,正式三关序列推进仍登记 Alpha 验收条件
|
||||
; (测试直入口 ≠ 序列生效)。行值全 provisional 归 难度曲线与Boss。
|
||||
@@ -56,6 +56,13 @@ rows = [{
|
||||
"buff_ref": "off_guard",
|
||||
"buff_duration": 2,
|
||||
"cooldown_beats": 4
|
||||
}, {
|
||||
"skill_id": "earth_pulse",
|
||||
"display_name": "大地脉动",
|
||||
"type": "debuff",
|
||||
"buff_ref": "sapped",
|
||||
"buff_duration": 2,
|
||||
"cooldown_beats": 4
|
||||
}]
|
||||
|
||||
; 敌人技能池批(2026-09-16 用户拍板——设计权威 docs/proposal-skill-pool.md v1.0,全值 provisional 投值归 难度曲线与Boss):
|
||||
@@ -86,3 +93,8 @@ rows = [{
|
||||
; 伏击),字段复用 buff_ref/buff_duration;duration 2 = 1 个有效结算(empower/fortify 先兑付后衰减含
|
||||
; 施放当轮口径);冷却 4;首发载荷 = 失衡(用户拍板),乏力 sapped 为第二词汇暂不实装;
|
||||
; 池纪律 +:每池妨害 ≤1(ConfigDB 跨表校验);实装面 = 仅卓尔池,其余敌种不动。
|
||||
;
|
||||
; 第三关内容批(2026-09-20):大地脉动 earth_pulse = 灰矮人石君王 duergar_king 专属池独占妨害技
|
||||
; (0 伤害施放行,对主角施加 sapped 乏力——第二妨害词汇首发,状态行 status_effects.tres 既有);
|
||||
; 字段口径同 web_snare(duration 2 = 1 个有效结算);每池妨害 ≤1 纪律由跨表校验覆盖。
|
||||
; provisional 归 难度曲线与Boss。
|
||||
@@ -51,6 +51,28 @@ rows = [{
|
||||
"placement": "any",
|
||||
"board_types": ["underdark"],
|
||||
"counter_items": []
|
||||
}, {
|
||||
"variant_id": "rockfall",
|
||||
"display_name": "落石",
|
||||
"unlock_level": 3,
|
||||
"scope": "region",
|
||||
"effect": "flat_damage",
|
||||
"effect_value": 3,
|
||||
"trigger": "on_open",
|
||||
"placement": "closed_only",
|
||||
"board_types": ["deep_underdark"],
|
||||
"counter_items": []
|
||||
}, {
|
||||
"variant_id": "mine_dust",
|
||||
"display_name": "矿尘",
|
||||
"unlock_level": 3,
|
||||
"scope": "region",
|
||||
"effect": "hide_number",
|
||||
"effect_value": 0,
|
||||
"trigger": "on_number_shown",
|
||||
"placement": "any",
|
||||
"board_types": ["deep_underdark"],
|
||||
"counter_items": []
|
||||
}]
|
||||
|
||||
; 地形变异 首批类型定稿批(2026-09-19 用户拍板)——四行两轴×两关:
|
||||
@@ -61,3 +83,8 @@ rows = [{
|
||||
; counter_items 恒空:反制道具配套义务随框架契约保留,兑现归 Alpha 反制批(2026-09-19 用户拍板
|
||||
; 反制道具改排 Alpha——切片期变异暂无反制手段,纯税状态已知悉接受)。
|
||||
; 全部行值 provisional 归 难度曲线与Boss 调参批(effect_value/布置参数均为加法核小整数轴)。
|
||||
;
|
||||
; 第三关内容批(2026-09-20):伤害型关间递进 1(荆棘)→ 2(岩浆)→ 3(落石)+ 信息型矿尘;
|
||||
; counter_items 恒空(反制归 Alpha 反制批);布量走既有公式
|
||||
; (5% + per_level_bonus × 2 = 9%——percent_of_cells 表头字段驱动,不加新配置)。
|
||||
; 行值全 provisional 归 难度曲线与Boss。
|
||||
@@ -138,6 +138,7 @@ func _build_ui() -> void:
|
||||
_seed_edit = start.seed_edit
|
||||
start.lvbtn.pressed.connect(_start_full_level.bind(1))
|
||||
start.lv2btn.pressed.connect(_start_full_level.bind(2))
|
||||
start.lv3btn.pressed.connect(_start_full_level.bind(3))
|
||||
start.tunebtn.pressed.connect(_show_tune_panel)
|
||||
start.dbgbtn.pressed.connect(_start_debug_levels)
|
||||
|
||||
|
||||
@@ -111,6 +111,8 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary:
|
||||
box.add_child(lvbtn)
|
||||
var lv2btn := UiKit.button("▶ 第二关 · 幽暗地域(分支节点图试玩——岔路口选下一跳)")
|
||||
box.add_child(lv2btn)
|
||||
var lv3btn := UiKit.button("▶ 第三关 · 灰矮人矿城(测试直入口——基线红档属预期,配合调整板加成试玩)")
|
||||
box.add_child(lv3btn)
|
||||
var tunebtn := UiKit.button("测试用 · 角色数值调整板(模拟天赋树属性提升)")
|
||||
box.add_child(tunebtn)
|
||||
var dbgbtn := UiKit.button("调试 · 连续关卡两层(HP 关内延续)")
|
||||
@@ -124,7 +126,7 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary:
|
||||
box.add_child(help)
|
||||
|
||||
return {"overlay": overlay, "box": box, "seed_edit": seed_edit,
|
||||
"lvbtn": lvbtn, "lv2btn": lv2btn, "tunebtn": tunebtn, "dbgbtn": dbgbtn}
|
||||
"lvbtn": lvbtn, "lv2btn": lv2btn, "lv3btn": lv3btn, "tunebtn": tunebtn, "dbgbtn": dbgbtn}
|
||||
|
||||
|
||||
# 调试两层模式的层间过渡覆盖层(历史入口专用)。返回 {overlay, label, next_btn}——接线归组合根
|
||||
|
||||
@@ -521,8 +521,8 @@ func _mk_stream(stream_name: String, scope: int) -> RandomNumberGenerator:
|
||||
|
||||
func _smoke_variation_framework() -> void:
|
||||
print("--- 地形变异 框架面(首批四类型 + 候选池门控 + 跨字段互锁)---")
|
||||
check(_db.variation.rows.size() == 4, "变异清单 4 行(荆棘丛/藤蔓缠绕/岩浆/烬覆——首批类型定稿批)")
|
||||
check(_db.variation.validate().is_empty(), "变异表校验零错误(4 行全过域与跨字段互锁)")
|
||||
check(_db.variation.rows.size() == 6, "变异清单 6 行(荆棘丛/藤蔓缠绕/岩浆/烬覆 + 落石/矿尘——首批类型定稿批 + 第三关内容批)")
|
||||
check(_db.variation.validate().is_empty(), "变异表校验零错误(6 行全过域与跨字段互锁)")
|
||||
var pool1_ids: Array = []
|
||||
for r in _db.variant_pool(1, "dungeon"):
|
||||
pool1_ids.append(String(r.variant_id))
|
||||
@@ -1809,7 +1809,7 @@ func _smoke_skill_pool() -> void:
|
||||
|
||||
# ① 数据面:技能表行集 + 普攻锁死 + 建议池行值 + 空池不可能(结构断言)
|
||||
func _smoke_skill_pool_data() -> void:
|
||||
check(_db.skill.rows.size() == 8, "技能表八行(普攻/突刺/蓄力/重击/硬化 + 撕咬/毒爆/蛛网束缚——分支节点图批 + 新效应词汇批)")
|
||||
check(_db.skill.rows.size() == 9, "技能表九行(普攻/突刺/蓄力/重击/硬化 + 撕咬/毒爆/蛛网束缚 + 大地脉动——分支节点图批 + 新效应词汇批 + 第三关内容批)")
|
||||
var basic: Dictionary = _db.skill.row_by_id("attack")
|
||||
check(not basic.is_empty() and String(basic.type) == "basic" and int(basic.cooldown_beats) == 0
|
||||
and (not basic.has("damage_mult") or is_equal_approx(float(basic.damage_mult), 1.0)),
|
||||
@@ -1861,6 +1861,13 @@ func _smoke_skill_pool_data() -> void:
|
||||
"2_6": {"attack": 6, "bite": 2, "charge": 1},
|
||||
"2_7": {"attack": 6, "bite": 2, "charge": 1},
|
||||
"2_8": {"attack": 6, "heavy": 2, "venom_burst": 2, "web_snare": 2},
|
||||
"3_0": {"attack": 6, "charge": 2, "heavy": 2},
|
||||
"3_1": {"attack": 6, "bite": 2, "charge": 1},
|
||||
"3_4": {"attack": 6, "bite": 2, "charge": 1},
|
||||
"3_5": {"attack": 5, "lunge": 2, "heavy": 2},
|
||||
"3_6": {"attack": 6, "bite": 2, "charge": 1},
|
||||
"3_7": {"attack": 6, "charge": 2, "heavy": 2},
|
||||
"3_8": {"attack": 6, "heavy": 2, "earth_pulse": 2},
|
||||
}
|
||||
var pools_ok := true
|
||||
for row in _db.enemy.rows:
|
||||
@@ -1873,7 +1880,7 @@ func _smoke_skill_pool_data() -> void:
|
||||
got[String(entry.skill_id)] = int(entry.weight)
|
||||
if got != expect_pools[rk]:
|
||||
pools_ok = false
|
||||
check(pools_ok, "十二行池模板 = 建议池行值(L1 地精 9/1 · 熊地精 6/2/2 · 酋长 6/2/2;L2 兄弟精 6/1/2 · 蜘蛛 6/2/1 · 重击手 5/2/2 · 蛛化卓尔精灵 6/2/2/2——全部 provisional)")
|
||||
check(pools_ok, "十九行池模板 = 建议池行值(L1 地精 9/1 · 熊地精 6/2/2 · 酋长 6/2/2;L2 兄弟精 6/1/2 · 蜘蛛 6/2/1 · 重击手 5/2/2 · 蛛化卓尔精灵 6/2/2/2;L3 灰矮人 6/2/2 · 钩爪恐魔 6/2/1 · 重装手 5/2/2 · 石君王 6/2/2〔earth_pulse〕——全部 provisional)")
|
||||
var basic_count_ok := true
|
||||
for row in _db.enemy.rows:
|
||||
var n := 0
|
||||
@@ -2339,6 +2346,63 @@ func _smoke_level_graph() -> void:
|
||||
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", "")) == "ward",
|
||||
"蛛化卓尔精灵 Boss 行集 (2,8) = drider(魔法甲——护甲类型重配批 2026-09-18:关卡 2 唯一非轻甲)")
|
||||
# ---- 第三关内容批(2026-09-20)L3 灰矮人矿城断言段 ----
|
||||
# ⑧ L3 行集结构(复用 L2 九节点图模板——6 战 + Boss + 奖励 + 恢复,真实岔路 4 处)
|
||||
var l3 := {}
|
||||
for row in _db.level.rows:
|
||||
if int(row.level_index) == 3:
|
||||
l3 = row
|
||||
check(not l3.is_empty() and l3.nodes.size() == 9, "L3 节点数 = 9(入口 1 + 中间三层 2/3/2 + Boss——L2 同模板)")
|
||||
var tcount3 := {"battle": 0, "reward": 0, "rest": 0, "boss": 0}
|
||||
var branch3 := 0
|
||||
for node in l3.nodes:
|
||||
tcount3[String(node.get("type", ""))] = int(tcount3[String(node.get("type", ""))]) + 1
|
||||
if node.get("next", []).size() >= 2:
|
||||
branch3 += 1
|
||||
check(int(tcount3.battle) == 6 and int(tcount3.boss) == 1, "L3 普通战斗节点 = 6 + Boss 恒一(编号最大恒终点)")
|
||||
check(int(tcount3.reward) == 1 and int(tcount3.rest) == 1, "L3 恢复节点 1(rest_heal_pct 行字段)+ 奖励节点 1(直通空态)")
|
||||
check(branch3 == 4, "L3 真实岔路 = %d 处(0→[1,2] · 1→[3,4] · 2→[4,5] · 4→[6,7])" % branch3)
|
||||
# ⑨ 跨表行完整:L3 每战斗/Boss 节点 (3, 编号) 在 board_gen 与 enemy 精确行(⑦ 的 bg_keys/en_keys 复用)
|
||||
var cross_ok3 := true
|
||||
for node in l3.nodes:
|
||||
var t3 := String(node.get("type", ""))
|
||||
if t3 != "battle" and t3 != "boss":
|
||||
continue
|
||||
var key3 := "3_%d" % int(node.node_depth)
|
||||
if not bg_keys.has(key3) or not en_keys.has(key3):
|
||||
cross_ok3 = false
|
||||
check(cross_ok3, "跨表行完整:L3 全部战斗/Boss 节点在 board_gen + enemy 精确行(7 节点)")
|
||||
# ⑩ 定点:L3 首遇行集与 Boss 行集(克制面重轻错开——重甲灰矮人首次登台)
|
||||
var l3_lead: Dictionary = _db.enemy.resolve_rowset(3, 0)
|
||||
check(String(l3_lead.get("enemy_id", "")) == "duergar" and String(l3_lead.get("armor_type", "")) == "heavy",
|
||||
"灰矮人首遇行集 (3,0) = duergar(重甲首次登台——固定 1 只,首遇教学位不加骰)")
|
||||
var l3_king: Dictionary = _db.enemy.resolve_rowset(3, 8)
|
||||
check(String(l3_king.get("enemy_id", "")) == "duergar_king" and String(l3_king.get("armor_type", "")) == "heavy",
|
||||
"灰矮人石君王 Boss 行集 (3,8) = duergar_king(重甲收束「轻甲→魔法甲→重甲」教学梯度)")
|
||||
# ⑪ L3 成长代理档首遇绿档:模拟 GP 商店成长后的入关参数(atk_pct=200 / hp_pct=100)· 完美档多种子首遇战稳过
|
||||
# (零加成基线红档属预期——断言口径 = 成长代理档,非基线;跑法同 ⑥)
|
||||
var green3_ok := true
|
||||
var green3_min_hp := 99999
|
||||
for i in range(12):
|
||||
var g3_runner = load("res://core/level_runner.gd").new(_db, _fresh_rng(9100 + i))
|
||||
g3_runner.set_hero_override(200, 100)
|
||||
g3_runner.start_level(3, 9100 + i)
|
||||
var g3_st = {"result": "", "rounds": 0, "refreshes": 0, "mine_hits": 0, "hero_dmg": 0, "policy": "perfect"}
|
||||
var g3_first = g3_runner.current_battle()
|
||||
var g3_box := {}
|
||||
g3_first.battle_finished.connect(func(p):
|
||||
g3_box["result"] = String(p.get("result", ""))
|
||||
g3_box["hero_hp"] = int(p.get("hero_hp", 0)))
|
||||
var g3_guard := 6
|
||||
while g3_runner.current_battle() == g3_first and not g3_box.has("result") and g3_guard > 0:
|
||||
g3_guard -= 1
|
||||
autoplay._autoplay_battle(g3_runner, g3_first, g3_st, null)
|
||||
if String(g3_box.get("result", "")) != "victory" or int(g3_st.mine_hits) > 0:
|
||||
green3_ok = false
|
||||
elif int(g3_box.get("hero_hp", 0)) > 0:
|
||||
green3_min_hp = mini(green3_min_hp, int(g3_box.hero_hp))
|
||||
check(green3_ok, "L3 首遇位绿档:成长代理档口径(atk_pct=200/hp_pct=100)完美档 12 种子首遇战(节点 0 灰矮人)全胜且零踩雷")
|
||||
check(green3_min_hp > 0, "L3 首遇战胜后 HP 下探读数 %d(>0——绿档记录)" % green3_min_hp)
|
||||
|
||||
|
||||
# 冒烟隔离用全新 RngService(同 master 种子——回放确定性纪律)
|
||||
|
||||
Reference in new issue
Block a user