奇物批T2:运行层bonus_*→curio_*全族换词(_curio_pending/deck/taken/result/candidates+pick_curio/apply_node_curio/curio_choice_presented/curio_resolved等+两文件改名curio_interact_controller/curio_pick_overlay含.uid+CurioPickOverlay/CurioInteractController类名);T2裁点甲案自裁=五存档键引号字面量禁改(全仓对拍六形态全等);_bonus_treasure_carry按T0澄清剔除(秘宝语义);非奇物bonus语义保全(加算区bonus/price_level_bonus/attack_bonus/bp_bonus等);reward_overlay_test红转绿适配(M7 bcard换PanelContainer致c is Button恒0——改数_choice_box子节点数断言语义不变,run_all 16套全绿历史首次)

This commit is contained in:
DKChan committed 2026-10-05 18:44:51 +08:00
1 parent d4cde73976
commit 8e2694de49
17 files changed
+298 -299

No files matched your search

+13 -13
View File
@@ -151,8 +151,8 @@ static func run_adventure(db, seed_val: int, atk_pct: int, hp_pct: int, collect_
adr.wallet_changed.connect(_on_adventure_wallet.bind(st, logger))
# 三选一停点驱动(迭代 10 奖励重构批——big_reward_paid 退役:确定性策略候选取首件、
# 道具件满位替换放弃新件、兑付后推进下一关——零随机流自开,同种子逐位可复放)
adr.bonus_choice_presented.connect(_on_adventure_bonus.bind(st, adr))
adr.bonus_resolved.connect(_on_adventure_bonus_resolved.bind(st, adr))
adr.curio_choice_presented.connect(_on_adventure_bonus.bind(st, adr))
adr.curio_resolved.connect(_on_adventure_curio_resolved.bind(st, adr))
adr.treasure_replace_presented.connect(_on_adventure_treasure_replace.bind(st, adr))
adr.adventure_finished.connect(_on_adventure_finished.bind(st, logger))
adr.set_hero_override(atk_pct, hp_pct)
@@ -220,17 +220,17 @@ static func _on_adventure_node_entered(node: Dictionary, info: Dictionary, adr,
elif t == "reward":
# 奖励节点三选一(迭代 10 追加批——共享池确定性策略;TP0 起 316-f 判读:1 级最稀有、
# 同档并列取最左;替换放弃新件;兑付后 continue_after_node 回图选路)
var ndraw: Dictionary = adr.node_bonus_candidates()
var ndraw: Dictionary = adr.node_curio_candidates()
var ncands: Array = ndraw.get("candidates", []) as Array
st.reward_events.append({"node_bonus_pick": ncands.duplicate(true)})
st.reward_events.append({"node_curio_pick": ncands.duplicate(true)})
if ncands.is_empty():
r.continue_after_node() # 牌库空合法态直通(池耗即枯竭——防御保留)
else:
adr.present_node_bonus(ncands, ndraw.get("aux_detail", []) as Array)
adr.present_node_curio(ncands, ndraw.get("aux_detail", []) as Array)
var npick: Dictionary = _pick_token(ncands, String(st.get("relic_mode", "off")))
if adr.apply_node_bonus(String(npick.get("kind", "")), String(npick.get("tier", "")), String(npick.get("relic_id", ""))):
if not adr._node_bonus_pending.is_empty() and adr._node_bonus_pending.has("incoming"):
adr.resolve_bonus_replace(-1) # 满位替换:放弃新件
if adr.apply_node_curio(String(npick.get("kind", "")), String(npick.get("tier", "")), String(npick.get("relic_id", ""))):
if not adr._node_curio_pending.is_empty() and adr._node_curio_pending.has("incoming"):
adr.resolve_curio_replace(-1) # 满位替换:放弃新件
else:
st.result = "advance_failed"
elif t == "rest":
@@ -260,13 +260,13 @@ static func _on_adventure_wallet(event: String, gp_val: int, extra: Dictionary,
# 三选一停点驱动(迭代 10——确定性策略;TP0 起 316-f 判读:1 级最稀有、同档并列取最左;
# 奖励事件随 reward_events 留档)
static func _on_adventure_bonus(payload: Dictionary, st: Dictionary, adr) -> void:
st.reward_events.append({"bonus_pick": payload.duplicate(true)})
st.reward_events.append({"curio_pick": payload.duplicate(true)})
var candidates: Array = payload.get("candidates", []) as Array
if candidates.is_empty():
st.result = "advance_failed"
return
var pick: Dictionary = _pick_token(candidates, String(st.get("relic_mode", "off")))
if not adr.pick_bonus(String(pick.get("kind", "")), String(pick.get("tier", "")), String(pick.get("relic_id", ""))):
if not adr.pick_curio(String(pick.get("kind", "")), String(pick.get("tier", "")), String(pick.get("relic_id", ""))):
st.result = "advance_failed"
@@ -304,13 +304,13 @@ static func _pick_token(candidates: Array, relic_mode: String = "off") -> Dictio
# 同调位满位替换子交互(确定性策略:放弃新件不获取——分发面按停点上下文裁决节点/通关渠道)
static func _on_adventure_treasure_replace(items: Array, incoming: Dictionary, st: Dictionary, adr) -> void:
st.reward_events.append({"treasure_replace": incoming.duplicate(true)})
if not adr.resolve_bonus_replace(-1):
if not adr.resolve_curio_replace(-1):
st.result = "advance_failed"
# 三选一兑付完成 → 上下文分派(通关停点=推进下一关 / 奖励节点=回图选路)
static func _on_adventure_bonus_resolved(result: Dictionary, st: Dictionary, adr) -> void:
st.reward_events.append({"bonus_resolved": result.duplicate(true)})
static func _on_adventure_curio_resolved(result: Dictionary, st: Dictionary, adr) -> void:
st.reward_events.append({"curio_resolved": result.duplicate(true)})
if String(result.get("context", "")) == "reward_node":
var r = adr.runner()
if r == null or not r.continue_after_node():
+53 -53
View File
@@ -327,12 +327,12 @@ func _smoke_adventure() -> void:
var resolves: Array = []
var node_picks := 0
for ev in (st["reward_events"] as Array):
if (ev as Dictionary).has("bonus_pick"):
picks.append((ev as Dictionary)["bonus_pick"])
elif (ev as Dictionary).has("node_bonus_pick"):
if (ev as Dictionary).has("curio_pick"):
picks.append((ev as Dictionary)["curio_pick"])
elif (ev as Dictionary).has("node_curio_pick"):
node_picks += 1 # 奖励节点三选一(追加批——每关奖励节点各 1 次)
elif (ev as Dictionary).has("bonus_resolved"):
resolves.append((ev as Dictionary)["bonus_resolved"])
elif (ev as Dictionary).has("curio_resolved"):
resolves.append((ev as Dictionary)["curio_resolved"])
check(picks.size() == 2 and resolves.size() == 2 + node_picks,
"通关三选一恰呈现 2 次、恰兑付 2 次(L1/L2 后——末关不发;resolves 含节点回执另计)")
check(node_picks >= 1, "奖励节点三选一 ≥1 次(L1 链必经 1 个;L2/L3 图可选路经若干——实际经停 %d)" % node_picks)
@@ -467,7 +467,7 @@ func _smoke_adventure() -> void:
for ev in wallet:
if String(ev["event"]) == "clear":
clears += 1
elif String(ev["event"]) == "gain" and String(ev.get("source", "")) != "bonus_pick":
elif String(ev["event"]) == "gain" and String(ev.get("source", "")) != "curio_pick":
gains += 1 # 战斗完成入账计数(三选一 GP 袋件入账另有 source 标记——不计战斗口径)
check(gains == int(st["battles"]), "每战完成入账恰一次(gain %d = battles %d——GP 袋件入账单列)" % [gains, int(st["battles"])])
check(clears == 1 and wallet.size() > 0 and String(wallet[wallet.size() - 1]["event"]) == "clear",
@@ -505,13 +505,13 @@ func _smoke_adventure() -> void:
check(acc_shop >= 3, "统一冒险加算区含商店值(max_hp=%d ≥ 商店 3——L1 三选一件值另计)" % acc_shop)
a8._on_level_finished({"result": "victory", "hp": int(r8.hero_hp), "node_index": r8.node_index,
"node_id": r8.current_node_id(), "node_type": "shop"}) # 模拟 L2 通关(victory 载荷直调——非末关)
check(not a8._bonus_pending.is_empty(), "L2 通关三选一停点在案(直调兑付前——零自动推进)")
check(not a8._curio_pending.is_empty(), "L2 通关三选一停点在案(直调兑付前——零自动推进)")
check(not a8.continue_to_next_level(), "未兑付推进拒绝(选择停点零自动推进契约)")
var l2_cands: Array = a8._bonus_pending["candidates"]
var l2_cands: Array = a8._curio_pending["candidates"]
var l2_pick: Dictionary = l2_cands[0]
check(a8.pick_bonus(String(l2_pick.get("kind", "")), String(l2_pick.get("tier", ""))), "三选一点选兑付受理(候选取首件)")
var picked2: String = String(a8._bonus_result.get("picked", ""))
var expect_acc: int = acc_shop + (int(a8._bonus_result.get("value", 0)) if picked2 == "max_hp" else 0)
check(a8.pick_curio(String(l2_pick.get("kind", "")), String(l2_pick.get("tier", ""))), "三选一点选兑付受理(候选取首件)")
var picked2: String = String(a8._curio_result.get("picked", ""))
var expect_acc: int = acc_shop + (int(a8._curio_result.get("value", 0)) if picked2 == "max_hp" else 0)
check(int(a8.bonus.get("max_hp", -1)) == expect_acc,
"三选一属性件与商店购买同账累加(max_hp=%d = %d + 三选一%s)" % [int(a8.bonus.get("max_hp", -1)), acc_shop, picked2])
var max_eff8: int = a8.effective_max_hp() # T17 口径修复随批:账本生效上限含调试浮窗 pct(a8 已 set 400)
@@ -545,11 +545,11 @@ func _smoke_adventure() -> void:
var a11 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(11))
check(a11.start_adventure(11, {"first_script": true, "treasure_unlocked": {"blast_kit": true}}),
"剔牌库/替换场景:冒险启动(seed 11——道具解锁集只含 blast_kit)")
for di in range(a11._bonus_deck.size() - 1, -1, -1):
var dk := String((a11._bonus_deck[di] as Dictionary).get("kind", ""))
for di in range(a11._curio_deck.size() - 1, -1, -1):
var dk := String((a11._curio_deck[di] as Dictionary).get("kind", ""))
if dk == "attack" or dk == "ap":
a11._bonus_deck.remove_at(di)
var draw: Array = a11._draw_bonus_candidates()
a11._curio_deck.remove_at(di)
var draw: Array = a11._draw_curio_candidates()
var draw_kinds := {}
for t in draw:
draw_kinds[String((t as Dictionary).get("kind", ""))] = true
@@ -560,7 +560,7 @@ func _smoke_adventure() -> void:
# white-box 测试随停点渠道退役拆除——机械惰性承载,零投放零行为)
var treasure_seen := false
for i in 40:
for t in a11._draw_bonus_candidates():
for t in a11._draw_curio_candidates():
if String((t as Dictionary).get("kind", "")) == "treasure_item":
treasure_seen = true
break
@@ -569,7 +569,7 @@ func _smoke_adventure() -> void:
var a12 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(12))
a12.start_adventure(12, {"first_script": true})
var cap := {"payload": {}}
a12.bonus_choice_presented.connect(func(p): cap["payload"] = p)
a12.curio_choice_presented.connect(func(p): cap["payload"] = p)
var max_full := int(_db.hero.max_hp) + int(a12._base_override.get("max_hp", 0))
a12.ledger["hero_hp"] = max_full
a12._on_level_finished({"result": "victory", "hp": max_full, "node_index": 1, "node_id": 1, "node_type": "shop"})
@@ -579,10 +579,10 @@ func _smoke_adventure() -> void:
var a13 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(13))
check(a13.start_adventure(13, {"first_script": true, "treasure_unlocked": {"blast_kit": true}}),
"节点共享池场景:冒险启动(seed 13)")
for di13 in range(a13._bonus_deck.size() - 1, -1, -1):
if String((a13._bonus_deck[di13] as Dictionary).get("kind", "")) == "attack":
a13._bonus_deck.remove_at(di13)
var ndraw: Dictionary = a13.node_bonus_candidates()
for di13 in range(a13._curio_deck.size() - 1, -1, -1):
if String((a13._curio_deck[di13] as Dictionary).get("kind", "")) == "attack":
a13._curio_deck.remove_at(di13)
var ndraw: Dictionary = a13.node_curio_candidates()
var ncands13: Array = ndraw.get("candidates", []) as Array
var has_attack13 := false
for t in ncands13:
@@ -591,12 +591,12 @@ func _smoke_adventure() -> void:
break
check(not has_attack13,
"奖励节点共享池:令牌耗尽同样不出候选(同库同池——%s)" % str(ncands13))
a13.present_node_bonus(ncands13, ndraw.get("aux_detail", []) as Array)
a13.present_node_bonus([{"kind": "gp", "tier": "common"}])
a13.present_node_curio(ncands13, ndraw.get("aux_detail", []) as Array)
a13.present_node_curio([{"kind": "gp", "tier": "common"}])
var gp13 := int(a13.ledger.get("gp", 0))
check(a13.apply_node_bonus("gp", "common") and int(a13.ledger.get("gp", 0)) == gp13 + int(_db.adventure.curio_value("gp", "common")),
check(a13.apply_node_curio("gp", "common") and int(a13.ledger.get("gp", 0)) == gp13 + int(_db.adventure.curio_value("gp", "common")),
"奖励节点 GP 件入账(钱包「奖励入账」收口——+%d)" % int(_db.adventure.curio_value("gp", "common")))
check(a13._node_bonus_pending.is_empty(), "节点停点态兑付后清零(恰一次语义同构)")
check(a13._node_curio_pending.is_empty(), "节点停点态兑付后清零(恰一次语义同构)")
var s10: Dictionary = a10.summary
check(String(s10.get("result", "")) == "abandoned" and not bool(s10.get("cleared", true)),
"放弃摘要:abandoned · 未打穿(已获大奖励不追回——同失败型结算)")
@@ -612,12 +612,12 @@ func _smoke_relics() -> void:
check(a_r0.start_adventure(71, {"first_script": true}), "规则改写型特性带场景:冒险启动(seed 71)")
var relic_tokens := 0
var rarest_tokens := 0
for t in a_r0._bonus_deck:
for t in a_r0._curio_deck:
if String((t as Dictionary).get("kind", "")) == "relic":
relic_tokens += 1
if String((t as Dictionary).get("tier", "")) == "rarest":
rarest_tokens += 1
check(relic_tokens == 27 and rarest_tokens == 6 and a_r0._bonus_deck.size() == 125,
check(relic_tokens == 27 and rarest_tokens == 6 and a_r0._curio_deck.size() == 125,
"规则改写型特性带入池:27 件(rare 档 21 + rarest 锚点 6)——牌库 98+27=125")
check(_db.relics.validate().is_empty(), "relic_table.validate 零违例(有行流派扫雷端铁律——magic first_dig_spell 在案)")
# ② 档位激活引擎(纯函数直测——构造表 4 件 magic + 1 件 flag + 1 件 rarest 锚点)
@@ -646,23 +646,23 @@ func _smoke_relics() -> void:
var a_r = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(72))
check(a_r.start_adventure(72, {"first_script": true}), "规则改写型特性带场景:冒险启动(seed 72——注入 5 行临时表)")
var deck_relic := 0
for t in a_r._bonus_deck:
for t in a_r._curio_deck:
if String((t as Dictionary).get("kind", "")) == "relic":
deck_relic += 1
check(deck_relic == 5 and a_r._bonus_deck.size() == 103,
check(deck_relic == 5 and a_r._curio_deck.size() == 103,
"规则改写型特性带入池:5 行 relic 每件 1 张(common/rare→稀有档 rarest→罕见档)——牌库 98+5=103")
var relic_seen: Dictionary = {}
for i in 60:
for t in a_r._draw_bonus_candidates():
for t in a_r._draw_curio_candidates():
if String((t as Dictionary).get("kind", "")) == "relic":
relic_seen[String(t.get("relic_id", ""))] = true
check(relic_seen.size() >= 2, "抽签出 relic 候选(60 次重抽 ≥2 种不同 relic——身份键 relic_id 同档可多件)")
a_r._bonus_pending = {"candidates": [{"kind": "relic", "tier": "rare", "relic_id": "m3"}, {"kind": "gp", "tier": "common"}], "payload": {}}
a_r._curio_pending = {"candidates": [{"kind": "relic", "tier": "rare", "relic_id": "m3"}, {"kind": "gp", "tier": "common"}], "payload": {}}
var deck_m3 := 0
for t in a_r._bonus_deck:
for t in a_r._curio_deck:
if String((t as Dictionary).get("relic_id", "")) == "m3":
deck_m3 += 1
check(a_r.pick_bonus("relic", "rare", "m3") and (a_r.relics_held() as Array).has("m3") and a_r.pool_stock("relic") == deck_relic - 1,
check(a_r.pick_curio("relic", "rare", "m3") and (a_r.relics_held() as Array).has("m3") and a_r.pool_stock("relic") == deck_relic - 1,
"relic 兑付:入持有集 + 牌库摘牌(选中踢池——池库存 %d→%d)" % [deck_relic, deck_relic - 1])
# 断点往返(持有集+余库 relic_id 随行)
var sm_r = load("res://core/save_manager.gd").new("user://_smoke_relics_bp.json")
@@ -771,10 +771,10 @@ func _adv_drive_to_shop(a, st: Dictionary, autoplay) -> bool:
return false
if a._pending_next_level:
# 三选一停点确认(迭代 10——确定性选件后推进,与 run_adventure 自动策略同口径;TP0 令牌化)
if not a._bonus_pending.is_empty():
var bcands: Array = a._bonus_pending["candidates"]
if not a._curio_pending.is_empty():
var bcands: Array = a._curio_pending["candidates"]
var bpick: Dictionary = autoplay._pick_token(bcands)
a.pick_bonus(String(bpick.get("kind", "")), String(bpick.get("tier", "")), String(bpick.get("relic_id", "")))
a.pick_curio(String(bpick.get("kind", "")), String(bpick.get("tier", "")), String(bpick.get("relic_id", "")))
a.continue_to_next_level()
continue
var r = a.runner()
@@ -788,14 +788,14 @@ func _adv_drive_to_shop(a, st: Dictionary, autoplay) -> bool:
var t := String(r.current_node().get("type", ""))
if t == "reward":
# 奖励节点三选一(迭代 10 追加批——确定性选件、替换放弃新件、兑付确认回图;TP0 令牌化)
var ndraw: Dictionary = a.node_bonus_candidates()
var ndraw: Dictionary = a.node_curio_candidates()
var ncands: Array = ndraw.get("candidates", []) as Array
if not ncands.is_empty():
a.present_node_bonus(ncands, ndraw.get("aux_detail", []) as Array)
a.present_node_curio(ncands, ndraw.get("aux_detail", []) as Array)
var npick: Dictionary = autoplay._pick_token(ncands)
if a.apply_node_bonus(String(npick.get("kind", "")), String(npick.get("tier", "")), String(npick.get("relic_id", ""))):
if not a._node_bonus_pending.is_empty() and a._node_bonus_pending.has("incoming"):
a.resolve_bonus_replace(-1)
if a.apply_node_curio(String(npick.get("kind", "")), String(npick.get("tier", "")), String(npick.get("relic_id", ""))):
if not a._node_curio_pending.is_empty() and a._node_curio_pending.has("incoming"):
a.resolve_curio_replace(-1)
r.continue_after_node()
elif t == "rest":
r.continue_after_node()
@@ -3871,13 +3871,13 @@ func _smoke_shop_pool() -> void:
var tier := String(buy_c.get("tier", ""))
var val_map := {"attack": "atk", "max_hp": "max_hp", "armor": "armor_class", "ap": "ap"}
var gp0: int = int(r8.gp)
var taken0: int = int(a8._bonus_taken.get(kind, 0))
var taken0: int = int(a8._curio_taken.get(kind, 0))
var val0: int = int(a8.bonus.get(String(val_map[kind]), -999))
check(r8.buy_pool_item(kind), "购买受理(pool 口——%s|%s)" % [kind, tier])
check(int(r8.gp) == gp0 - int(buy_c.get("price", 0)), "钱包扣现价(%d → %d)" % [gp0, int(r8.gp)])
check(int(a8.bonus.get(String(val_map[kind]), -999)) == val0 + int(_db.adventure.curio_value(kind, tier)),
"加算区 +令牌档位件值(池件=奖励件本体——%s|%s %+d)" % [kind, tier, int(_db.adventure.curio_value(kind, tier))])
check(int(a8._bonus_taken.get(kind, 0)) == taken0 + 1, "共享池账本 -1(跨渠道单点——taken %d → %d)" % [taken0, int(a8._bonus_taken.get(kind, 0))])
check(int(a8._curio_taken.get(kind, 0)) == taken0 + 1, "共享池账本 -1(跨渠道单点——taken %d → %d)" % [taken0, int(a8._curio_taken.get(kind, 0))])
# A 链:同visit 第二购现价 = ceil(base×b^(l2−1)×A^1)(货架已全重抽——新卡新价同公式)
var second: Dictionary = {}
for c in r8.shop_shelf():
@@ -3899,9 +3899,9 @@ func _smoke_shop_pool() -> void:
cut_seen = true
check(not cut_seen, "切边件零入店(40 次重抽零 gp/aux——负交易切边+三轴 doctrine)")
# ⑤ 池空硬闸(库存尽剔出牌库——TP0:white-box 耗尽 attack 令牌后货架零 attack + 消费口拒绝)
for di8 in range(a8._bonus_deck.size() - 1, -1, -1):
if String((a8._bonus_deck[di8] as Dictionary).get("kind", "")) == "attack":
a8._bonus_deck.remove_at(di8)
for di8 in range(a8._curio_deck.size() - 1, -1, -1):
if String((a8._curio_deck[di8] as Dictionary).get("kind", "")) == "attack":
a8._curio_deck.remove_at(di8)
var attack_seen := false
for i in 40:
r8._shop_draw_shelf()
@@ -3913,10 +3913,10 @@ func _smoke_shop_pool() -> void:
check(not a8._consume_pool_purchase("attack", "common") and a8.pool_stock("attack") == stock_before,
"池空消费拒绝(handler 零副作用——买光即枯竭硬闸)")
# ⑥ 跨渠道共库 shop→reward 向:回填一枚 attack 令牌 → 消费口受理 → 奖励牌库同步摘牌
a8._bonus_deck.append({"kind": "attack", "tier": "common"})
check(a8._consume_pool_purchase("attack", "common"), "商店消费口受理(_apply_bonus_pick 同口——真单点库)")
a8._curio_deck.append({"kind": "attack", "tier": "common"})
check(a8._consume_pool_purchase("attack", "common"), "商店消费口受理(_apply_curio_pick 同口——真单点库)")
var reward_attack_seen := false
for t6 in a8._draw_bonus_candidates():
for t6 in a8._draw_curio_candidates():
if String((t6 as Dictionary).get("kind", "")) == "attack":
reward_attack_seen = true
break
@@ -4265,11 +4265,11 @@ func _meta_settle_and_workshop() -> void:
a12._attunement = ["pick_refresh"]
a12._attune_refresh_x = 1
a12._attune_refresh_y = 2
a12._bonus_pending = {"candidates": [{"kind": "gp", "tier": "common"}, {"kind": "attack", "tier": "common"}, {"kind": "max_hp", "tier": "common"}], "payload": {}}
check(a12.refresh_bonus() and a12._attune_refresh_x == 0 and a12._attune_refresh_y == 2,
a12._curio_pending = {"candidates": [{"kind": "gp", "tier": "common"}, {"kind": "attack", "tier": "common"}, {"kind": "max_hp", "tier": "common"}], "payload": {}}
check(a12.refresh_curio() and a12._attune_refresh_x == 0 and a12._attune_refresh_y == 2,
"刷新双计数器——X 优先消耗(x1y2 → x0y2)")
check(a12.refresh_bonus() and a12.refresh_bonus() and a12._attune_refresh_y == 0
and a12.refresh_bonus() == false,
check(a12.refresh_curio() and a12.refresh_curio() and a12._attune_refresh_y == 0
and a12.refresh_curio() == false,
"刷新双计数器——X 耗尽转 Y 池、池竭拒绝(x0y2 → y0 → 第四次 false 零副作用)")
a12._reset_refresh_x()
check(a12.attune_refresh_left() == 1,
+20 -20
View File
@@ -192,22 +192,22 @@ func _ready() -> void:
main.node_overlay.press_continue()
_flags_placed.clear()
continue
if main.bonus_overlay.visible:
# 迭代 10 三选一停点(BonusPickOverlay——奖励节点/通关兑付共用面;T17 硬锁批适配——
if main.curio_overlay.visible:
# 迭代 10 三选一停点(CurioPickOverlay——奖励节点/通关兑付共用面;T17 硬锁批适配——
# 本探针此前未适配该层,走到即卡死)。三态分派:替换子态(满位——放弃新件)/
# result 态(兑付反馈——点继续推进)/ 待选态(点首件+确认)。真实信号路径全线。
# T1 D1——三选一停点输入锁定断言(停点态断言面:替换子/待选/兑付三态共用此层)。
if not main._input_locked():
_problems.append("三选一停点打开时输入未锁定")
if main.bonus_overlay._replace_box.visible:
main.bonus_overlay.replace_chosen.emit(-1)
elif main.bonus_overlay._continue_btn.visible:
main.bonus_overlay.press_continue()
elif main.adventure != null and not main.adventure._bonus_pending.is_empty():
main.bonus_overlay.press_card(0)
main.bonus_overlay.press_confirm()
if main.curio_overlay._replace_box.visible:
main.curio_overlay.replace_chosen.emit(-1)
elif main.curio_overlay._continue_btn.visible:
main.curio_overlay.press_continue()
elif main.adventure != null and not main.adventure._curio_pending.is_empty():
main.curio_overlay.press_card(0)
main.curio_overlay.press_confirm()
else:
main.bonus_overlay.press_continue() # 停点已消费的残面——继续关屏
main.curio_overlay.press_continue() # 停点已消费的残面——继续关屏
_flags_placed.clear()
continue
if main.shop_overlay.visible:
@@ -324,16 +324,16 @@ func _ready() -> void:
main._end_overlay._btn.pressed.emit()
else:
break
elif main.bonus_overlay.visible:
if main.bonus_overlay._replace_box.visible:
main.bonus_overlay.replace_chosen.emit(-1)
elif main.bonus_overlay._continue_btn.visible:
main.bonus_overlay.press_continue()
elif main.adventure != null and not main.adventure._bonus_pending.is_empty():
main.bonus_overlay.press_card(0)
main.bonus_overlay.press_confirm()
elif main.curio_overlay.visible:
if main.curio_overlay._replace_box.visible:
main.curio_overlay.replace_chosen.emit(-1)
elif main.curio_overlay._continue_btn.visible:
main.curio_overlay.press_continue()
elif main.adventure != null and not main.adventure._curio_pending.is_empty():
main.curio_overlay.press_card(0)
main.curio_overlay.press_confirm()
else:
main.bonus_overlay.press_continue()
main.curio_overlay.press_continue()
elif main.node_overlay.visible:
main.node_overlay.press_continue()
elif main.shop_overlay.visible:
@@ -609,7 +609,7 @@ func _locktest_tick() -> void:
return
_locktest_state = 1
elif _locktest_state == 1:
if main.bonus_overlay.visible or main._inter_overlay.visible or main._end_overlay.is_open() \
if main.curio_overlay.visible or main._inter_overlay.visible or main._end_overlay.is_open() \
or String(settlement.battle_result) != "":
_locktest_state = 2 # 前提消失守卫:终结演播竞态——静默弃测
return
+3 -3
View File
@@ -80,14 +80,14 @@ func _ready() -> void:
main._end_overlay.close()
_settle()
main.bonus_overlay.open_pick("结构探针·三选一", [
main.curio_overlay.open_pick("结构探针·三选一", [
{"id": "probe_heal", "text": "回血\n恢复 3 点"},
{"id": "probe_magic", "text": "爆裂轰击\n下一击 +5"},
{"id": "probe_pierce", "text": "穿甲\n无视护甲"},
])
_settle()
await _audit("bonus_pick", [main.bonus_overlay])
main.bonus_overlay.visible = false
await _audit("curio_pick", [main.curio_overlay])
main.curio_overlay.visible = false
_settle()
main.shop_overlay.open_shop([