T2(迭代22秘宝批): 核心层解锁服务换代+槽位档位约束——工坊渠道面退役(_workshop_progress/workshop_status/refresh_workshop_unlocks/meta_workshop_items/WORKSHOP_ITEM_IDS/workshop_items行族全删)换解锁混合制(buy_treasure_unlock钥石购买=余额闸+重复购拒+条件件误购拒/refresh_treasure_unlocks条件刷新=AND谓词+幂等/treasure_shop_status柜台投影); 计数读数单点_treasure_unlock_progress(adventure_cleared/boss_kill_count/vision_used); save_manager新增vision_used生涯计数域(add_vision_used收束入账+缺键补零不升版本); toggle_attunement三重校验(未解锁拒+满位禁选+件档rank≤装入位序档位格——卸下恒可效果面只读装配集); pause/camp两视图秘宝匣呈现换代+UiKit计数键与档位标签单点; smoke工坊段换V3/V4/V5断言(独立档[11]防路径污染)+meta表段行族规模换代3/3/2。冒烟895/0+单元21套+探针全绿〔秘宝批 V3/V4/V5/V14/V19数据源〕
This commit is contained in:
1 parent
48b0696158
commit
a7bd4e4132
13 files changed
+235
-194
No files matched your search
+66
-48
@@ -4359,10 +4359,10 @@ func _smoke_meta() -> void:
|
||||
print("--- 元进度·MetaTable 表结构 ---")
|
||||
var meta_tbl = _db.meta
|
||||
check(meta_tbl != null and meta_tbl.validate().is_empty(),
|
||||
"MetaTable 非空 + validate 零错(四行族词表封闭/唯一/连续/域界/first≥repeat/ratio 全过)")
|
||||
"MetaTable 非空 + validate 零错(三行族词表封闭/唯一/连续/域界/first≥repeat/ratio 全过)")
|
||||
check(meta_tbl.boss_keystone.size() == 3
|
||||
and meta_tbl.workshop_items.size() == 6 and meta_tbl.conversion.size() == 3,
|
||||
"MetaTable 行族规模 3/6/3(Boss/工坊恰六/换算恰三——forge_products 行族已随迭代 21 T5 退役)")
|
||||
and meta_tbl.conversion.size() == 3 and meta_tbl.attune_refresh_upgrade.size() == 2,
|
||||
"MetaTable 行族规模 3/3/2(Boss/换算恰三/Y 升级两档——forge_products 迭代 21 退役、workshop_items 迭代 22 退役)")
|
||||
var attrs_ok := true
|
||||
for a in ["max_hp", "atk", "armor_class"]:
|
||||
attrs_ok = attrs_ok and not _db.meta_conversion_row(a).is_empty()
|
||||
@@ -4387,22 +4387,21 @@ func _pause_overlay_projection() -> void:
|
||||
_meta_smoke_cleanup()
|
||||
var sv = _meta_new_save(_META_SMOKE_PATHS[0])
|
||||
var mp = load("res://core/meta_progression.gd").new(_db, sv)
|
||||
# 已购态夹具:余额非零 + 工坊首件解锁——投影可辨非全零白板(属性锻造段已随柜台退役删除)
|
||||
# 已购态夹具:余额非零 + 秘宝匣首件解锁——投影可辨非全零白板(属性锻造段已随柜台退役删除)
|
||||
sv.add_keystone(37)
|
||||
var ws_meta: Array = _db.meta_workshop_items()
|
||||
if not ws_meta.is_empty():
|
||||
sv.unlock_item(String(ws_meta[0].get("item_id", "")))
|
||||
sv.unlock_item("morning_order")
|
||||
sv.write_to_disk()
|
||||
# 投影拼装(main._pause_data 同构)+ 视图喂入
|
||||
var data := {"balance": mp.keystone_balance(), "workshop": mp.workshop_status(),
|
||||
var data := {"balance": mp.keystone_balance(), "workshop": mp.treasure_shop_status(),
|
||||
"tree": mp.tree_camp_rows(), "fork_groups": mp.tree_fork_groups()}
|
||||
var po = load("res://presentation/views/pause_overlay.gd").new()
|
||||
po.open_pause(data)
|
||||
check(po.visible, "暂停层开层可见(open_pause 直开——P4 甲零动效路径)")
|
||||
check(String(po._balance_badge.value_label.text) == "钥石 %d" % mp.keystone_balance(),
|
||||
"余额徽投影 = keystone_balance() 读数(%s)" % po._balance_badge.value_label.text)
|
||||
var ws: Array = mp.workshop_status()
|
||||
var ws: Array = mp.treasure_shop_status()
|
||||
var ws_ok: bool = po._workshop_holder.get_child_count() == ws.size()
|
||||
var uikit_s = load("res://presentation/views/ui_kit.gd")
|
||||
for i in mini(ws.size(), po._workshop_holder.get_child_count()):
|
||||
var row: Dictionary = ws[i]
|
||||
var lbls2: Array = []
|
||||
@@ -4410,18 +4409,23 @@ func _pause_overlay_projection() -> void:
|
||||
if ch is Label:
|
||||
lbls2.append(ch)
|
||||
var unlocked: bool = bool(row.get("unlocked", false))
|
||||
var expect_st := "未解锁"
|
||||
if bool(row.get("retired", false)):
|
||||
expect_st = "已退役"
|
||||
elif bool(row.get("deferred", false)) and unlocked:
|
||||
expect_st = "已解锁 · 能力封存中"
|
||||
elif unlocked:
|
||||
expect_st = "已解锁"
|
||||
var expect_prog := "已入手"
|
||||
if not unlocked:
|
||||
if String(row.get("mode", "")) == "keystone":
|
||||
expect_prog = "钥石 %d" % int(row.get("price", 0))
|
||||
elif String(row.get("mode", "")) == "condition":
|
||||
var parts: Array[String] = []
|
||||
for req_v2 in (row.get("reqs", []) as Array):
|
||||
var req2: Dictionary = req_v2 as Dictionary
|
||||
var lbl2 := String(uikit_s.TREASURE_REQ_LABELS.get(String(req2.get("key", "")), "条件"))
|
||||
parts.append("%s %d/%d" % [lbl2, int(req2.get("progress", 0)), int(req2.get("threshold", 0))])
|
||||
expect_prog = "、".join(parts)
|
||||
var expect_st2 := "已解锁" if unlocked else "未解锁"
|
||||
ws_ok = ws_ok and lbls2.size() == 3 \
|
||||
and String(lbls2[0].text) == String(row.get("display_name", "")) \
|
||||
and String(lbls2[1].text) == "累计通关 %d/%d 次" % [int(row.get("progress", 0)), int(row.get("threshold", 0))] \
|
||||
and String(lbls2[2].text) == expect_st
|
||||
check(ws_ok, "工坊六行投影 = workshop_status() 逐项(名称/判定量进度/解锁态——首件解锁夹具在列)")
|
||||
and String(lbls2[1].text) == expect_prog \
|
||||
and String(lbls2[2].text) == expect_st2
|
||||
check(ws_ok, "秘宝匣 12 行投影 = treasure_shop_status() 逐项(名称/钥石价与条件进度/解锁态——首件解锁夹具在列)〔秘宝批 V19 呈现数据源〕")
|
||||
var owned := 0
|
||||
for trow in (mp.tree_camp_rows() as Array):
|
||||
if int(trow.get("level", 0)) > 0:
|
||||
@@ -4507,7 +4511,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_career_v5.json", "user://smoke_meta_treasure_unlock.json"]
|
||||
|
||||
|
||||
func _meta_smoke_cleanup() -> void:
|
||||
@@ -4638,32 +4642,42 @@ func _meta_settle_and_workshop() -> void:
|
||||
"stopped_at": 1, "keystone_total": 0, "master_seed": 15})
|
||||
check(dz["boss_drops"].is_empty() and sv.keystone_balance() == bal_before and sv.clear_count(1) == cc1_before,
|
||||
"败北零通关摘要:零入账零标记(钥石只增不减——验收1;败北局 clear_counts 不变)")
|
||||
# ⑧ 工坊解锁:settle 内已随 refresh——总通关次数达阈值件数 == unlocked 数;重复 refresh 幂等
|
||||
var total_clears: int = sv.clear_count(1) + sv.clear_count(2) + sv.clear_count(3)
|
||||
var expect_n := 0
|
||||
for row in _db.meta_workshop_items():
|
||||
if total_clears >= int(row.get("clear_threshold", 99)):
|
||||
expect_n += 1
|
||||
var got_n := 0
|
||||
for st_row in mp.workshop_status():
|
||||
got_n += 1 if bool(st_row.get("unlocked", false)) else 0
|
||||
check(got_n == expect_n and mp.refresh_workshop_unlocks().is_empty(),
|
||||
"工坊解锁数 = 总通关 %d 次达阈值件数(%d 件)且重复 refresh 幂等" % [total_clears, expect_n])
|
||||
# 渠道可替换轴(2026-09-21 用户拍板):判定量单点正控 + 未知渠道 fail-safe(恒 0 = 永不解锁,非致命)
|
||||
check(mp._workshop_progress("total_clears") == total_clears and mp._workshop_progress("adventure_depth") == 0,
|
||||
"解锁判定量单点:total_clears 正控 + 未知渠道恒 0(channel 可替换轴 fail-safe)")
|
||||
var sv_r = _meta_new_save(_META_SMOKE_PATHS[2])
|
||||
# ⑧ 秘宝解锁服务(迭代 22 T2——V3 钥石购买/V4 条件解锁;注入=直调解锁写口+直置存档生涯计数,
|
||||
# 不走正常资源积累流程——卡片 7.1 测试方式;旧工坊渠道段随行族退役摘除)
|
||||
var sv_u = _meta_new_save(_META_SMOKE_PATHS[11])
|
||||
var mp_u = load("res://core/meta_progression.gd").new(_db, sv_u)
|
||||
sv_u.add_keystone(10)
|
||||
check(not mp_u.buy_treasure_unlock("sky_eye") and not sv_u.item_unlocked("sky_eye")
|
||||
and not mp_u.buy_treasure_unlock("ranged_pick"),
|
||||
"条件件误购拒绝(购买件专属——契约 8 分配面)〔秘宝批 V3 反例〕")
|
||||
check(not mp_u.buy_treasure_unlock("twin_loader") and sv_u.keystone_balance() == 10,
|
||||
"余额不足购买拒绝且零副作用(余额 10 < 价 25)〔秘宝批 V3〕")
|
||||
check(mp_u.buy_treasure_unlock("morning_order") and sv_u.item_unlocked("morning_order")
|
||||
and sv_u.keystone_balance() == 0,
|
||||
"钥石购买解锁:余额足→解锁态落档+余额扣减正确(价 10)〔秘宝批 V3〕")
|
||||
check(not mp_u.buy_treasure_unlock("morning_order"),
|
||||
"已解锁重复购买拒绝〔秘宝批 V3〕")
|
||||
check(mp_u.refresh_treasure_unlocks().is_empty() and not sv_u.item_unlocked("ranged_pick"),
|
||||
"条件未达不解锁(远程镐=通关 1 次)〔秘宝批 V4〕")
|
||||
sv_u._data["meta"]["adventure_cleared"] = 1 # 直置存档生涯计数(调试注入口径)
|
||||
check((mp_u.refresh_treasure_unlocks() as Array).has("ranged_pick")
|
||||
and sv_u.item_unlocked("ranged_pick") and mp_u.refresh_treasure_unlocks().is_empty(),
|
||||
"远程镐=adventure_cleared≥1 达标恰解锁一次+重复刷新幂等(C6:通关=打通整局冒险)〔秘宝批 V4〕")
|
||||
sv_u._data["meta"]["boss_kill_count"] = 3
|
||||
check((mp_u.refresh_treasure_unlocks() as Array).has("refresh_license"),
|
||||
"刷新执照=boss_kill_count≥3(阈值读 unlock_requires 行值不硬编)〔秘宝批 V4〕")
|
||||
sv_u._data["meta"]["adventure_cleared"] = 3
|
||||
check(not sv_u.item_unlocked("sky_eye"), "天眼单条件不足不解锁(AND 语义——cleared 3 达 boss 4 未达)〔秘宝批 V4〕")
|
||||
sv_u._data["meta"]["boss_kill_count"] = 4
|
||||
check((mp_u.refresh_treasure_unlocks() as Array).has("sky_eye"),
|
||||
"天眼双条件 AND(通关≥3 且 Boss≥4)达标解锁〔秘宝批 V4〕")
|
||||
sv_u._data["meta"]["vision_used"] = 10
|
||||
check((mp_u.refresh_treasure_unlocks() as Array).has("beacon_network"),
|
||||
"信标网络=真视类工具累计使用≥10(行为计数新域——use_treasure 受理成功累计)〔秘宝批 V4〕")
|
||||
var r_n := 0
|
||||
for st_row in load("res://core/meta_progression.gd").new(_db, sv_r).workshop_status():
|
||||
for st_row in mp_u.treasure_shop_status():
|
||||
r_n += 1 if bool(st_row.get("unlocked", false)) else 0
|
||||
check(r_n == expect_n, "工坊解锁持久(reload 后一致)")
|
||||
# ⑧ 干净档:通关 1 次 → 恰两件阈值 1 道具新解锁(new_unlocks 明细)
|
||||
var sv_w = _meta_new_save(_META_SMOKE_PATHS[3])
|
||||
var mp_w = load("res://core/meta_progression.gd").new(_db, sv_w)
|
||||
var u1: Dictionary = mp_w.settle_adventure({"result": "failed", "cleared": false, "levels_cleared": 1,
|
||||
"stopped_at": 2, "keystone_total": 0, "master_seed": 16})
|
||||
check(u1["new_unlocks"].size() == 2 and sv_w.item_unlocked("probe_dust") and sv_w.item_unlocked("sapper_order")
|
||||
and not sv_w.item_unlocked("loot_compass"), "通关 1 次 → 恰两件阈值 1 道具解锁(new_unlocks 明细正确)")
|
||||
check(r_n == 5, "解锁态持久投影一致(reload 面同源读数;5 件=购买 1+条件 4)〔秘宝批 V4〕")
|
||||
# ⑩ recent_summaries:元素含 boss_drops 副本、最新在前、cap 10
|
||||
var rs: Array = sv.recent_summaries()
|
||||
check(rs.size() >= 5 and String(rs[0].get("result", "")) != "" and rs[0].has("boss_drops")
|
||||
@@ -4681,9 +4695,11 @@ func _meta_settle_and_workshop() -> void:
|
||||
var mp_a = load("res://core/meta_progression.gd").new(_db, sv_a)
|
||||
check(Attunement.slots(_db, sv_a) == 0 and int(mp_a.attune_camp_status()["refresh"]["charges"]) == 0,
|
||||
"白板档同调位求值 = 0(0 起步裁决)且 Y=0(未购无刷新能力——P1 甲初始 0 同构)")
|
||||
check(mp_a.toggle_attunement("nest_counter") == false,
|
||||
"满位禁选(Slots 0 时装配拒绝)")
|
||||
check(mp_a.toggle_attunement("morning_order") == false,
|
||||
"满位禁选(Slots 0 时装配拒绝;兼未解锁拒绝前置——直置解锁后下方装配)〔秘宝批 V5〕")
|
||||
sv_a.add_keystone(200)
|
||||
sv_a.unlock_item("morning_order")
|
||||
sv_a.unlock_item("twin_loader")
|
||||
check(mp_a.buy_attune_refresh() and sv_a.attune_refresh_level() == 1
|
||||
and int(mp_a.attune_camp_status()["refresh"]["charges"]) == 1,
|
||||
"Y 升级购买入账(Lv1 → 每冒险 +1 次刷新)")
|
||||
@@ -4694,10 +4710,12 @@ func _meta_settle_and_workshop() -> void:
|
||||
sv_a.set_tree_level("att_socket1", 1)
|
||||
check(Attunement.slots(_db, sv_a) == 1,
|
||||
"树上点亮同调位 1 → Slots=1(槽位收编树节点——Q2 裁甲)")
|
||||
check(not mp_a.toggle_attunement("sky_eye"),
|
||||
"稀有件入普通格拒绝(件档 rank 3 > 装入位序 1——契约 2 档位格校验)〔秘宝批 V5〕")
|
||||
check(mp_a.toggle_attunement("morning_order") and mp_a.toggle_attunement("twin_loader") == false,
|
||||
"装配持久写入 + 满位禁选(Slots 1 装第二件拒绝)〔秘宝批 V5 换主语〕")
|
||||
check(mp_a.toggle_attunement("morning_order") and mp_a.toggle_attunement("twin_loader"),
|
||||
"卸下恒可再装配(换装语义——装配序数组承载)〔秘宝批换主语;营地换装=冒险开始前合法面,装配不可变只锁运行中〕")
|
||||
check(mp_a.toggle_attunement("morning_order") and mp_a.toggle_attunement("morning_order"),
|
||||
"卸下恒可再装配(自卸自装——营地换装=冒险开始前合法面,装配不可变只锁运行中)〔秘宝批换主语〕")
|
||||
var sv_a2 = _meta_new_save(_META_SMOKE_PATHS[7])
|
||||
sv_a2.set_attunement_equipped(["morning_order"])
|
||||
var mp_a2 = load("res://core/meta_progression.gd").new(_db, sv_a2)
|
||||
|
||||
Reference in new issue
Block a user