refactor(迭代35卡②T2·二口+T3 S1/S2/S6/S8): 消费侧切源落定+断言面换代主体——① level_runner 图源换代(_generator 取代模板解析,_assign_generated_graph 读 level_gen_params 参数档产图并过 LevelTable.validate_graph,违规起关拒绝零兜底)+_entry_nodes 多入口首跳+_node_id 句柄单空间+enc node_depth 取节点 depth 值;② adventure_runner/main/save_manager 模板链路退役(first_script 参数与 template_pick 计算全删,断点 template_pick 键换生成图代差标记键 graph_gen_v2,缺键旧断点 resume 显式拒绝禁静默回放);③ level.tres 三行 templates 键清出(15 张模板数据出表,行级字段留,表尾注释改指参数档+生成器);④ sim/probe 随动(run_level/run_adventure 尾参退役、MC 出数字段 level_templates→level_maps 值=关卡#主种子、探针注释性质化、boss_depth 取节点 depth 键);⑤ 断言面换代:node_map_templates 宿主整段重写为生成图确定性套(纯函数复现/换种子变图/零计数器号位依赖/单一图源/种子 42 两开局同图/断点重生成同图/缺代差键拒绝/表无 templates/收束置位三条保留),breakpoint_resume 新增 P7 六断言(快照无已抽模板键、代差标记、停点句柄与已到序往返、续玩同图、旧断点拒绝、同种子重开局同图),S8 单测随动 first_script 键清退+断点夹具换代+meta 参数面 extra 键样换 treasure_unlocked(语义保持),S2 生成图取数面三宿主替换(level_active_nodes 走参数档+种子 42,消费点深度键换 depth,round_flow 死件 _boss_depth 随删),adventure_feats 覆盖义务段改真实解析链判据(敌侧落带≥请求深度+板侧命中+非空扫描面)、奖励节点段换「图侧含件+真实选路点选呈停兑付」双断言(旧单链必经形状前提随模板消亡,非放宽:经停即呈候选由真实 pick_next_node 入口证明)、商店余额段按每关恰一店投影改三关读数
This commit is contained in:
1 parent
6566200220
commit
9ee3bea194
22 files changed
+460
-362
No files matched your search
@@ -29,7 +29,7 @@ func _run() -> void:
|
||||
quit(Kit.finish("level_map_info_fog_test"))
|
||||
|
||||
|
||||
# 白盒 runner:夹具行集注入 db.level + level_row,入口停点态(node_index=-1,候选=入边首节点)
|
||||
# 白盒 runner:夹具行集注入 db.level + level_row,入口停点态(node_index=-1,候选=首层首节点句柄 1)
|
||||
func _runner(db, nodes: Array, candidates: Array, n: int = 2):
|
||||
var t := LevelTableScript.new()
|
||||
t.info_visible_layers = n
|
||||
@@ -37,7 +37,6 @@ func _runner(db, nodes: Array, candidates: Array, n: int = 2):
|
||||
db.level = t
|
||||
var r = load("res://core/level_runner.gd").new(db, load("res://core/rng_service.gd").new())
|
||||
r.level_row.assign({"level_index": 1, "display_name": "夹具关", "rest_heal_pct": 30, "nodes": nodes})
|
||||
r._graph_mode = true
|
||||
r.node_index = -1
|
||||
r._candidates.assign(candidates)
|
||||
return r
|
||||
@@ -46,7 +45,7 @@ func _runner(db, nodes: Array, candidates: Array, n: int = 2):
|
||||
# ---- ① 范围外只见结构:雾下节点类型图标与文字均不绘制〔fv2〕----
|
||||
|
||||
func _test_fog_hides_type() -> void:
|
||||
var node := {"node_depth": 3, "type": "battle"}
|
||||
var node := {"id": 3, "type": "battle", "depth": 3, "next": []}
|
||||
var shown: Dictionary = ScreenScript.node_display(node, 2, [2], false, false)
|
||||
Kit.check("可见集内节点:图标/类型文字均绘制〔fv2〕",
|
||||
bool(shown["draw_icon"]) and bool(shown["draw_label"]))
|
||||
@@ -60,24 +59,24 @@ func _test_fog_hides_type() -> void:
|
||||
|
||||
func _test_boss_exempt_and_multi_boss() -> void:
|
||||
var type_vis: Array = [1, 7, 9] # 双 Boss 图:7/9 均在可见集
|
||||
var boss_a: Dictionary = ScreenScript.node_display({"node_depth": 7, "type": "boss"}, 7, type_vis, false, false)
|
||||
var boss_b: Dictionary = ScreenScript.node_display({"node_depth": 9, "type": "boss"}, 9, type_vis, false, false)
|
||||
var boss_a: Dictionary = ScreenScript.node_display({"id": 7, "type": "boss", "depth": 7, "next": []}, 7, type_vis, false, false)
|
||||
var boss_b: Dictionary = ScreenScript.node_display({"id": 9, "type": "boss", "depth": 9, "next": []}, 9, type_vis, false, false)
|
||||
Kit.check("多终点:两个 Boss 节点均带 Boss 描边〔fv3〕",
|
||||
bool(boss_a["boss_border"]) and bool(boss_b["boss_border"]))
|
||||
Kit.check("Boss 不入雾:可见集与图标/文字三通道均在〔fv3〕",
|
||||
bool(boss_a["draw_icon"]) and bool(boss_a["draw_label"]) and bool(boss_b["draw_icon"]))
|
||||
var far_boss: Dictionary = ScreenScript.node_display({"node_depth": 9, "type": "boss"}, 9, [1], false, false)
|
||||
var far_boss: Dictionary = ScreenScript.node_display({"id": 9, "type": "boss", "depth": 9, "next": []}, 9, [1], false, false)
|
||||
Kit.check("Boss 豁免独立于可见集:不在 type_vis 的 Boss 仍出示类型〔fv3〕",
|
||||
bool(far_boss["draw_icon"]) and bool(far_boss["draw_label"]))
|
||||
var fogged_battle: Dictionary = ScreenScript.node_display({"node_depth": 5, "type": "battle"}, 5, type_vis, false, false)
|
||||
var fogged_battle: Dictionary = ScreenScript.node_display({"id": 5, "type": "battle", "depth": 5, "next": []}, 5, type_vis, false, false)
|
||||
Kit.check("Boss 豁免不扩散:雾下非 Boss 仍隐类型〔fv3〕", not bool(fogged_battle["draw_icon"]))
|
||||
|
||||
|
||||
# ---- ③ 节点内详情图上从不显示〔fv5〕----
|
||||
|
||||
func _test_details_never_shown() -> void:
|
||||
var plain := {"node_depth": 3, "type": "battle"}
|
||||
var loaded := {"node_depth": 3, "type": "battle", "enemy_id": "goblin_secret", "reward_id": "reward_secret"}
|
||||
var plain := {"id": 3, "type": "battle", "depth": 3, "next": [4]}
|
||||
var loaded := {"id": 3, "type": "battle", "depth": 3, "next": [4], "enemy_id": "goblin_secret", "reward_id": "reward_secret"}
|
||||
var a: Dictionary = ScreenScript.node_display(plain, 3, [3], false, true)
|
||||
var b: Dictionary = ScreenScript.node_display(loaded, 3, [3], false, true)
|
||||
var same := true
|
||||
@@ -92,7 +91,7 @@ func _test_details_never_shown() -> void:
|
||||
# ---- ④ label_text 三态文案〔fv2〕----
|
||||
|
||||
func _test_label_three_states() -> void:
|
||||
var node := {"node_depth": 3, "type": "battle"}
|
||||
var node := {"id": 3, "type": "battle", "depth": 3, "next": [4]}
|
||||
Kit.check("当前位文案=「当前位置」〔fv2〕",
|
||||
String(ScreenScript.node_display(node, 3, [3], true, false)["label_text"]) == "当前位置")
|
||||
Kit.check("候选文案=「战斗 · 可选」〔fv2〕",
|
||||
@@ -103,9 +102,10 @@ func _test_label_three_states() -> void:
|
||||
|
||||
# ---- 大图(11 层×6 槽含双 Boss)画布拟合与布局包络〔fv8〕----
|
||||
|
||||
# 大图夹具:编号按 12 层×6 槽构造,层 0 入口、末层双 Boss;含层 1 首节点→第 3 层节点的跨层跳边。
|
||||
# 跳边目标按 BFS 最短路径提前一层,其后继链随之提前——布局落 11 层(最大槽 7:
|
||||
# 跳边目标并入第 2 层槽组)。断言按布局实测取最大层/最大槽,画布公式与之同源。
|
||||
# 大图夹具:按 12 层×6 槽构造(id = 图内句柄 = 构造序号;depth 随构造序号严格前进——生成图连线铁律),
|
||||
# 层 0 入口、末层双 Boss(id 61/62,句柄互异、next 恒空);含层 1 首节点→第 3 层节点的跨层长跳边。
|
||||
# 跳边目标按 BFS 最短路径提前一层,其后继链随之逐层提前(目标并入第 2 层槽组)——布局落 11 层。
|
||||
# 断言按布局实测取最大层/最大槽,画布公式与之同源。
|
||||
func _big_graph_nodes() -> Array:
|
||||
var layers: Array = []
|
||||
var total := 0
|
||||
@@ -118,30 +118,25 @@ func _big_graph_nodes() -> Array:
|
||||
total += 1
|
||||
layers.append(ids)
|
||||
var nodes: Array = []
|
||||
var jump_from := -1
|
||||
var jump_to := -1
|
||||
for l in tiers:
|
||||
for i in layers[l].size():
|
||||
var nid: int = layers[l][i]
|
||||
var n := {"node_depth": nid}
|
||||
if l == 0:
|
||||
n["type"] = "battle"
|
||||
n["next"] = layers[1].duplicate() # 入口扇出到全层(层宽 6)
|
||||
elif l == tiers - 1:
|
||||
n["type"] = "boss"
|
||||
n["next"] = []
|
||||
var t := "battle"
|
||||
var next_ids: Array = []
|
||||
if l == tiers - 1:
|
||||
t = "boss"
|
||||
elif l == 0:
|
||||
next_ids = layers[1].duplicate() # 入口扇出到全层(层宽 6)
|
||||
else:
|
||||
if i % 5 == 0:
|
||||
n["type"] = "reward" if l % 2 == 0 else "rest"
|
||||
else:
|
||||
n["type"] = "battle"
|
||||
t = "reward" if l % 2 == 0 else "rest"
|
||||
var w2: int = layers[l + 1].size()
|
||||
n["next"] = [layers[l + 1][i % w2], layers[l + 1][(i + 1) % w2]]
|
||||
nodes.append(n)
|
||||
jump_from = layers[1][0]
|
||||
jump_to = layers[3][2]
|
||||
next_ids = [layers[l + 1][i % w2], layers[l + 1][(i + 1) % w2]]
|
||||
nodes.append({"id": nid, "type": t, "depth": nid, "next": next_ids})
|
||||
var jump_from: int = layers[1][0]
|
||||
var jump_to: int = layers[3][2]
|
||||
for n in nodes:
|
||||
if int(n["node_depth"]) == jump_from:
|
||||
if int(n["id"]) == jump_from:
|
||||
(n["next"] as Array).append(jump_to)
|
||||
break
|
||||
return nodes
|
||||
@@ -188,9 +183,9 @@ func _test_big_graph_fit(db) -> void:
|
||||
var boss_ids: Array = []
|
||||
for node in nodes:
|
||||
if String(node["type"]) == "boss":
|
||||
boss_ids.append(int(node["node_depth"]))
|
||||
boss_ids.append(int(node["id"]))
|
||||
Kit.check("大图呈现:两个终点 Boss 均有描边标记〔fv8〕",
|
||||
disp.has(boss_ids[0]) and disp.has(boss_ids[1])
|
||||
and bool(disp[boss_ids[0]]["boss_border"]) and bool(disp[boss_ids[1]]["boss_border"]))
|
||||
Kit.check("大图呈现:入口停点远处战斗节点(编号 32,层 6)类型入雾〔fv8〕", not bool(disp[32]["draw_icon"]))
|
||||
Kit.check("大图呈现:入口停点远处战斗节点(句柄 32,层 6)类型入雾〔fv8〕", not bool(disp[32]["draw_icon"]))
|
||||
screen.queue_free()
|
||||
Reference in new issue
Block a user