diff --git a/game/smoke/smoke_all.gd b/game/smoke/smoke_all.gd index c39bcf9e..13034700 100644 --- a/game/smoke/smoke_all.gd +++ b/game/smoke/smoke_all.gd @@ -287,6 +287,41 @@ func _smoke_adventure_table() -> void: check(orch_e.begin_battle({"level_index": 1, "node_depth": 0, "hero_hp": int(_db.hero.max_hp)}) and not orch_e.attune_has("morning_order"), "空装配基线:不带 attunement 起战 attune_has=false(off 态零扰动)〔秘宝批换主语〕") + # V9 静态词表断言(迭代 22 T6——棋盘事实不可变契约 3:新 12 行 triggers do.kind 与 effect_kinds + # 全集零棋盘改写类词〔rewrite_board 已除名/remove_mines/cell_removal=改写族——remove_mines 现役 + # 语义=爆破工兵包旧通道随行退役,新表零引用〕;效果只允许信息呈现与开格动作) + var rewrite_words := ["rewrite_board", "remove_mines", "cell_removal"] + var v9_ok := true + for r9 in trows: + for k9 in (r9.get("effect_kinds", []) as Array): + if rewrite_words.has(String(k9)): + v9_ok = false + for tr9 in (r9.get("triggers", []) as Array): + if rewrite_words.has(String((tr9 as Dictionary).get("do", {}).get("kind", ""))): + v9_ok = false + check(v9_ok, "新 12 行效果词零棋盘改写类(危险格/安全格分布同池冻结——真视/开格动作外无写面)〔秘宝批 V9〕") + # 覆盖检查(迭代 22 T6——效果三方向覆盖:信息〔巢穴预告/线香/天眼/阔视野带〕/行动资源〔晨操令/ + # 双管装填/试炼镐/储备罐〕/操作能力〔远程镐/信标网络〕+抉择刷新〔刷新练习/刷新执照〕——dimension_tags 静态投影) + var tag_set := {} + for r10 in trows: + for tg in (r10.get("dimension_tags", []) as Array): + tag_set[String(tg)] = true + check(tag_set.has("info") and tag_set.has("action") and tag_set.has("plan"), + "效果三方向覆盖在册(信息/行动资源/操作能力=plan·抉择刷新——12 件目录结构对齐设计权威)〔秘宝批 V10 覆盖半〕") + # V18 装配面空目录合法态(迭代 22 T6——白板档全未解锁:柜台投影 12 行全未解锁+mode 分派正确; + # 池空兜底/商店空货架两部分归奇物/商店侧另批〔卡片 §4〕) + var mp_v18 = load("res://core/meta_progression.gd").new(_db, _meta_new_save(_META_SMOKE_PATHS[12])) + var v18_ok := true + var locked_n := 0 + for st18 in mp_v18.treasure_shop_status(): + if bool(st18.get("unlocked", false)): + v18_ok = false + else: + locked_n += 1 + if (String(st18.get("mode", "")) != "keystone" and String(st18.get("mode", "")) != "condition"): + v18_ok = false + check(v18_ok and locked_n == 12, + "装配面空目录合法态:白板档 12 件全未解锁且 mode 分派正确(空目录=合法可玩态)〔秘宝批 V18〕") # ② 冒险结构 API 闸(状态机受理面——重复开始拒绝 / 入口停点 / 放弃两态) @@ -4509,7 +4544,7 @@ const _META_SMOKE_PATHS := ["user://smoke_meta_buy.json", "user://smoke_meta_dry "user://smoke_meta_cap.json", "user://smoke_meta_white.json", "user://smoke_meta_attune.json", "user://smoke_meta_attune2.json", "user://smoke_meta_tree.json", "user://smoke_meta_career.json", - "user://smoke_meta_career_v5.json", "user://smoke_meta_treasure_unlock.json"] + "user://smoke_meta_career_v5.json", "user://smoke_meta_treasure_unlock.json", "user://smoke_meta_treasure_blank.json"] func _meta_smoke_cleanup() -> void: diff --git a/game/tests/unit/core/treasure_effects_test.gd b/game/tests/unit/core/treasure_effects_test.gd index 89fc353e..fc39a852 100644 --- a/game/tests/unit/core/treasure_effects_test.gd +++ b/game/tests/unit/core/treasure_effects_test.gd @@ -259,6 +259,20 @@ func _init() -> void: Kit.check_quiet(int(vc13.get("used", 0)) == 1, "计数链正常:受理成功恰 +1(信标网络解锁行为条件数据源)") + # ⑭ 装配不可变(迭代 22 秘宝批 T6——V6:冒险全程装配快照三面同源且零写口—— + # 写口唯一=营地 toggle_attunement〔meta_progression〕,runner/level/battle 无装配写口) + var rng14 = load("res://core/rng_service.gd").new(); rng14.set_master_seed(331) + var adr14 = runner_s.new(db, rng14) + adr14.set_save_manager(save_s.new("user://treasure_effects_v6.json")) + Kit.check_quiet(adr14.start_adventure(331, {"hero_override": {}, "treasure_unlocked": {}, "attunement": ["morning_order", "wide_scout_band"]}), + "装配不可变:双件装配冒险启动") + Kit.check_quiet(adr14.runner().pick_next_node(int(adr14.runner().next_candidate_ids()[0])), "装配不可变:进首战") + var snap14: Array = (adr14.runner()._attunement as Array).duplicate() + var ob14 = adr14.runner().current_battle() + Kit.check_quiet(ob14 != null and (ob14.attunement as Array) == snap14 + and (adr14.runner()._attunement as Array) == snap14, + "装配不可变:战斗运行态装配集与冒险装配集逐位同源(运行零写口——快照对比)") + quit(Kit.finish("treasure_effects_test", "PASS — 新目录 12 件逐件行为断言全绿〔秘宝批 V7 附属表〕"))