奇物批T3+T4:relic_*→feat_*词族全换(feat_table.gd/feats.tres/feats_engine.gd三文件改名+.uid+feat_flags/feat_id/feat_row等全token+config_db注册键feats两端+entities.yaml换代注记——kind值relic/身份前缀relic:/relics存档键/摘要键按数据契约保留);T4渠道白名单过滤(_draw_curio_candidates(channel):通关渠道只出专长/节点渠道零专长——过滤式不拆池,TIER_QUOTAS锚零改动,devour货架保底随渠道定位退役,迁移保feat_id,pick_curio测试feat_id透传;冒烟773/0+run_all 16全绿+断点往返PASS)
This commit is contained in:
1 parent
8e2694de49
commit
6812ebbb73
24 files changed
+385
-384
No files matched your search
@@ -81,7 +81,7 @@ var _resume_bp := {} # 续玩快照暂存(resume_adventur
|
||||
# ---- 三选一停点态(迭代 10 奖励重构批)----
|
||||
var _curio_taken := {} # 件获取次数计数(kind 维度派生账本——断点附随件与摘要读数承载;池库存正主=_curio_deck)
|
||||
var _curio_deck: Array = [] # 令牌池(TP0 v2.2——持久多重集,元素 {"kind","tier"};洗牌抽候选/选中踢池未选回池/池耗即枯竭;商店货架同库共账;迭代 12 T1 起规则改写型特性带=relic 令牌随表追加)
|
||||
var _relics: Array[String] = [] # 特性持有集(迭代 12 T1——局内随机渠道获得、冒险级跨关携带、收束清零;🔴 层级纪律承载面:不入同调位不入局外树)
|
||||
var _feats: Array[String] = [] # 特性持有集(迭代 12 T1——局内随机渠道获得、冒险级跨关携带、收束清零;🔴 层级纪律承载面:不入同调位不入局外树)
|
||||
var _tree_rules: Array = [] # 树 rule 键集(迭代 12 T10——Fork 激活侧 effects 透传;下传 enc.tree_rules 消费面)
|
||||
var _curio_pending := {} # 停点态:{"candidates": Array, "payload": Dictionary, "chosen"/"incoming": 替换在途}——空 = 无停点
|
||||
var _curio_result := {} # 已兑付待推进态(curio_resolved 载荷副本——中断续玩不重兑付)
|
||||
@@ -130,12 +130,12 @@ func start_adventure(seed_val: int, params: Dictionary = {}) -> bool:
|
||||
_seed_attune_charges() # 迭代 11 第①批 T6——冒险开始充能账本按装备主动件重置(每冒险充能语义)
|
||||
# 特性开局注入(迭代 12 T7——MC 成型画像载体:params.relics_seed 非空=开局持有集〔七流派
|
||||
# 各 2 件档一成型——测量面专用;真实局规则改写型特性只走局内随机渠道,红线②层级纪律不破〕)
|
||||
var relic_seed: Array = params.get("relics_seed", []) if params.get("relics_seed", []) is Array else []
|
||||
var feat_seed: Array = params.get("relics_seed", []) if params.get("relics_seed", []) is Array else []
|
||||
_tree_rules = params.get("tree_rules", []) if params.get("tree_rules", []) is Array else [] # 迭代 12 T10——A/B 面 rule 键集
|
||||
if not relic_seed.is_empty():
|
||||
_relics = []
|
||||
for r in relic_seed:
|
||||
_relics.append(String(r))
|
||||
if not feat_seed.is_empty():
|
||||
_feats = []
|
||||
for r in feat_seed:
|
||||
_feats.append(String(r))
|
||||
ledger["hero_hp"] = effective_max_hp() # 生命账本置满(生效上限口径——T17 修复:含调试浮窗 pct,与战斗内同源)
|
||||
state = "running"
|
||||
return _start_current_level()
|
||||
@@ -179,7 +179,7 @@ func resume_adventure(bp: Dictionary, params: Dictionary = {}) -> bool:
|
||||
for id in _curio_taken.keys():
|
||||
_curio_taken[id] = maxi(0, int(bp_taken.get(id, 0)))
|
||||
# 令牌池余库还原(TP0 v2.2——快照缺键 = 旧版断点,保持满库重建态:旧档只读一版周期的防御口径;
|
||||
# 迭代 12 T1——relic 令牌 relic_id 随还原)
|
||||
# 迭代 12 T1——relic 令牌 feat_id 随还原)
|
||||
var bp_deck = bp.get("bonus_deck", null)
|
||||
if bp_deck is Array:
|
||||
var restored: Array = []
|
||||
@@ -187,13 +187,13 @@ func resume_adventure(bp: Dictionary, params: Dictionary = {}) -> bool:
|
||||
var tok: Dictionary = t as Dictionary
|
||||
var rtok := {"kind": String(tok.get("kind", "")), "tier": String(tok.get("tier", ""))}
|
||||
if String(rtok["kind"]) == "relic":
|
||||
rtok["relic_id"] = String(tok.get("relic_id", ""))
|
||||
rtok["feat_id"] = String(tok.get("feat_id", ""))
|
||||
restored.append(rtok)
|
||||
_curio_deck = restored
|
||||
# 特性持有集还原(迭代 12 T1——缺键 = 旧版断点防御空集)
|
||||
_relics = []
|
||||
_feats = []
|
||||
for r in (bp.get("relics", []) as Array):
|
||||
_relics.append(String(r))
|
||||
_feats.append(String(r))
|
||||
for v in (bp.get("bonus_aux_carry", []) as Array):
|
||||
_bonus_treasure_carry.append(String(v))
|
||||
_keystone_drops = (bp.get("keystone_drops", []) as Array).duplicate(true)
|
||||
@@ -220,7 +220,11 @@ func resume_adventure(bp: Dictionary, params: Dictionary = {}) -> bool:
|
||||
var migrated: Array = []
|
||||
for c in (bp_pending.get("candidates", []) as Array):
|
||||
if c is Dictionary:
|
||||
migrated.append({"kind": String((c as Dictionary).get("kind", "")), "tier": String((c as Dictionary).get("tier", ""))})
|
||||
# T4——feat_id 随迁移(通关渠道候选=纯专长令牌,身份键 relic|tier|feat_id 三段全要)
|
||||
var mig := {"kind": String((c as Dictionary).get("kind", "")), "tier": String((c as Dictionary).get("tier", ""))}
|
||||
if String(mig["kind"]) == "relic":
|
||||
mig["feat_id"] = String((c as Dictionary).get("feat_id", ""))
|
||||
migrated.append(mig)
|
||||
else:
|
||||
migrated.append({"kind": String(c), "tier": db.adventure.TIER_COMMON})
|
||||
_curio_pending = {"candidates": migrated}
|
||||
@@ -259,7 +263,7 @@ func resume_adventure(bp: Dictionary, params: Dictionary = {}) -> bool:
|
||||
func _reset_curio_state() -> void:
|
||||
_curio_taken = {"attack": 0, "max_hp": 0, "armor": 0, "gp": 0, "ap": 0, "heal": 0}
|
||||
_curio_deck = _build_curio_deck()
|
||||
_relics = []
|
||||
_feats = []
|
||||
_curio_pending = {}
|
||||
_curio_result = {}
|
||||
_bonus_treasure_carry = []
|
||||
@@ -276,16 +280,16 @@ func _build_curio_deck() -> Array:
|
||||
for tier in db.adventure.TIERS:
|
||||
for i in int(db.adventure.curio_quota(String(kind), String(tier))):
|
||||
deck.append({"kind": String(kind), "tier": String(tier)})
|
||||
for row in db.relic_rows():
|
||||
for row in db.feat_rows():
|
||||
var rtier := "rarest" if String(row.get("rarity", "")) == "rarest" else "rare"
|
||||
deck.append({"kind": "relic", "tier": rtier, "relic_id": String(row.get("relic_id", ""))})
|
||||
deck.append({"kind": "relic", "tier": rtier, "feat_id": String(row.get("feat_id", ""))})
|
||||
return deck
|
||||
|
||||
|
||||
# 令牌唯一身份(抽签去重/兑付匹配共用——属性加成型特性=kind,规则改写型特性=relic_id;同档多张不同 relic 可同屏)
|
||||
# 令牌唯一身份(抽签去重/兑付匹配共用——属性加成型特性=kind,规则改写型特性=feat_id;同档多张不同 relic 可同屏)
|
||||
func _token_identity(tok: Dictionary) -> String:
|
||||
if String(tok.get("kind", "")) == "relic":
|
||||
return "relic:" + String(tok.get("relic_id", ""))
|
||||
return "relic:" + String(tok.get("feat_id", ""))
|
||||
return String(tok.get("kind", ""))
|
||||
|
||||
|
||||
@@ -337,64 +341,64 @@ func continue_to_next_level() -> bool:
|
||||
|
||||
# ---- 提升三选一(迭代 10 奖励重构批——选择停点零自动推进、重复兑付被拒;兑付恰一件、未选项零生效)----
|
||||
|
||||
# 候选令牌匹配(身份键恒等——属性加成型特性 kind+tier、规则改写型特性 relic_id;迭代 12 T1 规则改写型特性带)
|
||||
func _find_token(candidates: Array, kind: String, tier: String, relic_id: String = "") -> Dictionary:
|
||||
# 候选令牌匹配(身份键恒等——属性加成型特性 kind+tier、规则改写型特性 feat_id;迭代 12 T1 规则改写型特性带)
|
||||
func _find_token(candidates: Array, kind: String, tier: String, feat_id: String = "") -> Dictionary:
|
||||
for t in candidates:
|
||||
var tok: Dictionary = t as Dictionary
|
||||
if String(tok.get("kind", "")) != kind or String(tok.get("tier", "")) != tier:
|
||||
continue
|
||||
if kind == "relic" and String(tok.get("relic_id", "")) != relic_id:
|
||||
if kind == "relic" and String(tok.get("feat_id", "")) != feat_id:
|
||||
continue
|
||||
return tok
|
||||
return {}
|
||||
|
||||
|
||||
# 玩家点选兑付(呈现层/冒烟/自动模拟确认入口):令牌 ∈ 停点候选(身份键精确匹配——relic 件
|
||||
# 另须 relic_id)。属性件写加算区、AP 件写第四轴、GP 件走钱包「奖励入账」入口、恢复件当即回血、
|
||||
# 另须 feat_id)。属性件写加算区、AP 件写第四轴、GP 件走钱包「奖励入账」入口、恢复件当即回血、
|
||||
# relic 件入特性持有集(🔴 层级纪律:只走局内随机渠道)、道具件受同调位约束(随池种退役不可达)。
|
||||
# 消费=选中令牌踢池(未选回池由「抽签不摘牌、兑付才摘牌」语义承载——TP0 v2.2)。
|
||||
func pick_curio(kind: String, tier: String = "", relic_id: String = "") -> bool:
|
||||
func pick_curio(kind: String, tier: String = "", feat_id: String = "") -> bool:
|
||||
if state != "running" or _curio_pending.is_empty():
|
||||
push_error("[冒险结构] pick_curio 拒绝——无待选停点(state=%s)" % state)
|
||||
return false
|
||||
var candidates: Array = _curio_pending.get("candidates", []) as Array
|
||||
if _find_token(candidates, kind, tier, relic_id).is_empty():
|
||||
push_error("[冒险结构] pick_curio 拒绝——令牌不在候选: %s|%s|%s" % [kind, tier, relic_id])
|
||||
if _find_token(candidates, kind, tier, feat_id).is_empty():
|
||||
push_error("[冒险结构] pick_curio 拒绝——令牌不在候选: %s|%s|%s" % [kind, tier, feat_id])
|
||||
return false
|
||||
var value: int = int(db.adventure.curio_value(kind, tier))
|
||||
var hp_before := int(ledger.get("hero_hp", 0))
|
||||
if kind == "treasure_item":
|
||||
return _pick_treasure_item(value) # 道具件分派通关渠道(持有容器 = 跨关携带——与节点渠道分轨;池种退役后不可达)
|
||||
if not _apply_curio_pick(kind, tier, value, relic_id):
|
||||
push_error("[冒险结构] pick_curio 拒绝——未知件: %s|%s|%s" % [kind, tier, relic_id])
|
||||
if not _apply_curio_pick(kind, tier, value, feat_id):
|
||||
push_error("[冒险结构] pick_curio 拒绝——未知件: %s|%s|%s" % [kind, tier, feat_id])
|
||||
return false
|
||||
_finish_curio_pick(kind, value, hp_before, tier, relic_id)
|
||||
_finish_curio_pick(kind, value, hp_before, tier, feat_id)
|
||||
return true
|
||||
|
||||
|
||||
# 兑付载荷 relic 伴随键(迭代 12 T1——反馈行取数面;非 relic 件零新增键)
|
||||
func _relic_payload_keys(relic_id: String) -> Dictionary:
|
||||
if relic_id == "":
|
||||
func _feat_payload_keys(feat_id: String) -> Dictionary:
|
||||
if feat_id == "":
|
||||
return {}
|
||||
var row: Dictionary = db.relic_row(relic_id)
|
||||
return {"relic_id": relic_id, "relic_name": String(row.get("display_name", "")), "relic_archetype": String(row.get("archetype", ""))}
|
||||
var row: Dictionary = db.feat_row(feat_id)
|
||||
return {"feat_id": feat_id, "feat_name": String(row.get("display_name", "")), "feat_archetype": String(row.get("archetype", ""))}
|
||||
|
||||
|
||||
# 三选一件兑付共享体(2026-10-02 修复批双胞胎收口;TP0 改令牌消费——摘牌单点;迭代 12 T1 relic 分支):
|
||||
# 属性件写加算区 + 件获取计数、AP 件写第四轴、GP 件走钱包、恢复件当即回血(封顶生效上限——
|
||||
# 与账本置满/通关回血同式 effective_max_hp)、relic 件入持有集(散件单体保底——效果接线面
|
||||
# 按挂点消费,档位质变由 RelicsEngine 求值)。兑付即从 _curio_deck 摘除该令牌(选中踢池;
|
||||
# 按挂点消费,档位质变由 FeatsEngine 求值)。兑付即从 _curio_deck 摘除该令牌(选中踢池;
|
||||
# 未选候选从未摘牌=自动回池)。道具件不入此体——未知件返回 false 由调用方按渠道名报错。
|
||||
func _apply_curio_pick(kind: String, tier: String, value: int, relic_id: String = "") -> bool:
|
||||
if kind == "relic" and db.relic_row(relic_id).is_empty():
|
||||
push_error("[冒险结构] relic 兑付失败——表无此件: %s" % relic_id)
|
||||
func _apply_curio_pick(kind: String, tier: String, value: int, feat_id: String = "") -> bool:
|
||||
if kind == "relic" and db.feat_row(feat_id).is_empty():
|
||||
push_error("[冒险结构] relic 兑付失败——表无此件: %s" % feat_id)
|
||||
return false # 先校验后摘牌(令牌零丢失)
|
||||
if not _consume_deck_token(kind, tier, relic_id):
|
||||
push_error("[冒险结构] 令牌消费失败——牌库无此令牌: %s|%s|%s" % [kind, tier, relic_id])
|
||||
if not _consume_deck_token(kind, tier, feat_id):
|
||||
push_error("[冒险结构] 令牌消费失败——牌库无此令牌: %s|%s|%s" % [kind, tier, feat_id])
|
||||
return false
|
||||
if kind == "relic":
|
||||
if not _relics.has(relic_id):
|
||||
_relics.append(relic_id)
|
||||
if not _feats.has(feat_id):
|
||||
_feats.append(feat_id)
|
||||
_curio_taken["relic"] = int(_curio_taken.get("relic", 0)) + 1
|
||||
return true
|
||||
match kind:
|
||||
@@ -412,7 +416,7 @@ func _apply_curio_pick(kind: String, tier: String, value: int, relic_id: String
|
||||
_curio_taken["ap"] = int(_curio_taken.get("ap", 0)) + 1
|
||||
"gp":
|
||||
if _runner != null:
|
||||
_runner.grant_bonus_gp(value)
|
||||
_runner.grant_curio_gp(value)
|
||||
_curio_taken["gp"] = int(_curio_taken.get("gp", 0)) + 1
|
||||
"heal":
|
||||
ledger["hero_hp"] = mini(int(ledger.get("hero_hp", 0)) + value, effective_max_hp())
|
||||
@@ -422,13 +426,13 @@ func _apply_curio_pick(kind: String, tier: String, value: int, relic_id: String
|
||||
return true
|
||||
|
||||
|
||||
# 从牌库摘除一枚令牌(TP0——选中踢池单点;迭代 12 T1 relic 按 relic_id 精确摘;找不到 = false)
|
||||
func _consume_deck_token(kind: String, tier: String, relic_id: String = "") -> bool:
|
||||
# 从牌库摘除一枚令牌(TP0——选中踢池单点;迭代 12 T1 relic 按 feat_id 精确摘;找不到 = false)
|
||||
func _consume_deck_token(kind: String, tier: String, feat_id: String = "") -> bool:
|
||||
for i in _curio_deck.size():
|
||||
var tok: Dictionary = _curio_deck[i] as Dictionary
|
||||
if String(tok.get("kind", "")) != kind or String(tok.get("tier", "")) != tier:
|
||||
continue
|
||||
if kind == "relic" and String(tok.get("relic_id", "")) != relic_id:
|
||||
if kind == "relic" and String(tok.get("feat_id", "")) != feat_id:
|
||||
continue
|
||||
_curio_deck.remove_at(i)
|
||||
return true
|
||||
@@ -436,8 +440,8 @@ func _consume_deck_token(kind: String, tier: String, relic_id: String = "") -> b
|
||||
|
||||
|
||||
# 特性持有集读面(效果接线/求值/摘要唯一取数口——副本防外部改写)
|
||||
func relics_held() -> Array:
|
||||
return _relics.duplicate()
|
||||
func feats_held() -> Array:
|
||||
return _feats.duplicate()
|
||||
|
||||
|
||||
# ---- 商店共享池消费面(迭代 11 第②批 T3——P1 共享池单点账本;TP0 令牌池换代——库存=牌库剩余令牌)----
|
||||
@@ -513,7 +517,7 @@ func resolve_treasure_replace(discard_index: int) -> bool:
|
||||
|
||||
# 兑付收口(恰一次):清停点态 → 记已兑付态 → emit → 停点快照(等继续确认——中断续玩不重兑付)。
|
||||
# picked = kind;tier 随载荷(TP0——大小档位读数面);relic 伴随键随载荷(迭代 12 T1——反馈行取数)
|
||||
func _finish_curio_pick(picked: String, value: int, hp_before: int, tier: String = "", relic_id: String = "") -> void:
|
||||
func _finish_curio_pick(picked: String, value: int, hp_before: int, tier: String = "", feat_id: String = "") -> void:
|
||||
_curio_pending = {}
|
||||
_curio_result = {
|
||||
"picked": picked,
|
||||
@@ -523,7 +527,7 @@ func _finish_curio_pick(picked: String, value: int, hp_before: int, tier: String
|
||||
"hp_after": int(ledger.get("hero_hp", 0)),
|
||||
"level_index": level_index,
|
||||
}
|
||||
_curio_result.merge(_relic_payload_keys(relic_id))
|
||||
_curio_result.merge(_feat_payload_keys(feat_id))
|
||||
curio_resolved.emit(_curio_result.duplicate(true))
|
||||
_snapshot_breakpoint()
|
||||
|
||||
@@ -534,7 +538,7 @@ func _finish_curio_pick(picked: String, value: int, hp_before: int, tier: String
|
||||
# 续玩重建到选路停点后重走重抽,恢复的全局计数器保证同候选逐位复现)。
|
||||
# 掷定前置(追加批二):返回 dict 带 aux_detail(道具件具体道具)供卡片直显。
|
||||
func node_curio_candidates() -> Dictionary:
|
||||
var cands: Array = _draw_curio_candidates()
|
||||
var cands: Array = _draw_curio_candidates("reward_node")
|
||||
return {"candidates": cands, "aux_detail": _last_draw_treasure.duplicate()}
|
||||
|
||||
|
||||
@@ -544,21 +548,21 @@ func present_node_curio(candidates: Array, treasure_detail: Array = []) -> void:
|
||||
|
||||
|
||||
# 点选兑付(节点域——无部分回血无钥石;令牌消费与牌库摘牌与通关三选一同库;relic 同权入持有集)
|
||||
func apply_node_curio(kind: String, tier: String = "", relic_id: String = "") -> bool:
|
||||
func apply_node_curio(kind: String, tier: String = "", feat_id: String = "") -> bool:
|
||||
if _node_curio_pending.is_empty():
|
||||
push_error("[冒险结构] apply_node_curio 拒绝——无待选停点")
|
||||
return false
|
||||
var candidates: Array = _node_curio_pending.get("candidates", []) as Array
|
||||
if _find_token(candidates, kind, tier, relic_id).is_empty():
|
||||
push_error("[冒险结构] apply_node_curio 拒绝——令牌不在候选: %s|%s|%s" % [kind, tier, relic_id])
|
||||
if _find_token(candidates, kind, tier, feat_id).is_empty():
|
||||
push_error("[冒险结构] apply_node_curio 拒绝——令牌不在候选: %s|%s|%s" % [kind, tier, feat_id])
|
||||
return false
|
||||
var value: int = int(db.adventure.curio_value(kind, tier))
|
||||
if kind == "treasure_item":
|
||||
return _apply_node_treasure(value) # 道具件分派节点渠道(持有容器 = 关卡域库存——与通关渠道分轨;池种退役后不可达)
|
||||
if not _apply_curio_pick(kind, tier, value, relic_id):
|
||||
push_error("[冒险结构] apply_node_curio 拒绝——未知件: %s|%s|%s" % [kind, tier, relic_id])
|
||||
if not _apply_curio_pick(kind, tier, value, feat_id):
|
||||
push_error("[冒险结构] apply_node_curio 拒绝——未知件: %s|%s|%s" % [kind, tier, feat_id])
|
||||
return false
|
||||
_finish_node_bonus(kind, value, tier, relic_id)
|
||||
_finish_node_bonus(kind, value, tier, feat_id)
|
||||
return true
|
||||
|
||||
|
||||
@@ -646,7 +650,7 @@ func refresh_curio() -> bool:
|
||||
_attune_refresh_x -= 1
|
||||
else:
|
||||
_attune_refresh_y -= 1
|
||||
var cands: Array = _draw_curio_candidates()
|
||||
var cands: Array = _draw_curio_candidates("level_clear")
|
||||
_curio_pending["candidates"] = cands.duplicate(true)
|
||||
_curio_pending["aux_detail"] = _last_draw_treasure.duplicate()
|
||||
var payload: Dictionary = (_curio_pending.get("payload", {}) as Dictionary).duplicate(true)
|
||||
@@ -660,7 +664,7 @@ func refresh_curio() -> bool:
|
||||
_attune_refresh_x -= 1
|
||||
else:
|
||||
_attune_refresh_y -= 1
|
||||
var cands2: Array = _draw_curio_candidates()
|
||||
var cands2: Array = _draw_curio_candidates("reward_node")
|
||||
_node_curio_pending["candidates"] = cands2.duplicate(true)
|
||||
_node_curio_pending["aux_detail"] = _last_draw_treasure.duplicate()
|
||||
return true
|
||||
@@ -700,7 +704,7 @@ func resolve_curio_replace(discard: int) -> bool:
|
||||
return resolve_treasure_replace(discard)
|
||||
|
||||
|
||||
func _finish_node_bonus(picked: String, value: int, tier: String = "", relic_id: String = "") -> void:
|
||||
func _finish_node_bonus(picked: String, value: int, tier: String = "", feat_id: String = "") -> void:
|
||||
_node_curio_pending = {}
|
||||
var payload := {
|
||||
"context": "reward_node",
|
||||
@@ -709,7 +713,7 @@ func _finish_node_bonus(picked: String, value: int, tier: String = "", relic_id:
|
||||
"value": value,
|
||||
"level_index": level_index,
|
||||
}
|
||||
payload.merge(_relic_payload_keys(relic_id))
|
||||
payload.merge(_feat_payload_keys(feat_id))
|
||||
curio_resolved.emit(payload)
|
||||
|
||||
|
||||
@@ -719,9 +723,17 @@ func _finish_node_bonus(picked: String, value: int, tier: String = "", relic_id:
|
||||
# 自动回池;池耗即枯竭——余库不足 N kind 时出齐剩余,空库 = 零候选合法态)。候选 = 令牌字典
|
||||
# {"kind","tier"}。消费 reward_pick 封闭流——一次停点恰一 scope,同种子同候选;道具件掷定前置
|
||||
# 随池种退役拆除(_last_draw_treasure 恒空集,机械惰性承载)。
|
||||
func _draw_curio_candidates() -> Array:
|
||||
# 渠道白名单过滤(迭代 15 卡② T4——渠道轴定位:关底 Boss 击败=通关渠道只出专长(feat 令牌);
|
||||
# 奖励节点/商店只出属性值提升+资源(非 relic 令牌),专长在非 Boss 渠道只以门票形态出现(T5)。
|
||||
# 过滤式而非物理拆池:deck 物理结构/存档键 bonus_deck 混编余库/消耗语义(选中踢池未选回池)原样,
|
||||
# 白名单在候选视图层生效——配额结构锚 TIER_QUOTAS 70/25/3=98 零改动(专长令牌本系活行追加面,在锚外)。
|
||||
func _draw_curio_candidates(channel: String = "reward_node") -> Array:
|
||||
_last_draw_treasure = []
|
||||
var pool := _curio_deck.duplicate()
|
||||
if channel == "level_clear":
|
||||
pool = pool.filter(func(tok): return String((tok as Dictionary).get("kind", "")) == "relic")
|
||||
else:
|
||||
pool = pool.filter(func(tok): return String((tok as Dictionary).get("kind", "")) != "relic")
|
||||
var rg: RandomNumberGenerator = rng.open_stream("reward_pick")
|
||||
for i in pool.size():
|
||||
var j := rg.randi_range(i, pool.size() - 1)
|
||||
@@ -737,7 +749,7 @@ func _draw_curio_candidates() -> Array:
|
||||
seen.append(ident)
|
||||
var cand := {"kind": String((tok as Dictionary).get("kind", "")), "tier": String((tok as Dictionary).get("tier", ""))}
|
||||
if ident.begins_with("relic:"):
|
||||
cand["relic_id"] = String((tok as Dictionary).get("relic_id", ""))
|
||||
cand["feat_id"] = String((tok as Dictionary).get("feat_id", ""))
|
||||
out.append(cand)
|
||||
if out.size() >= int(db.adventure.curio_candidate_count):
|
||||
break
|
||||
@@ -828,7 +840,7 @@ func _start_current_level() -> bool:
|
||||
if ok:
|
||||
_runner.set_attunement(_attunement) # 迭代 11 第①批 T5——同调装配下传(enc 携带进战斗结算)
|
||||
_runner.set_attune_charges(attune_charges) # 迭代 11 第①批 T6——充能账本下传(能力件骑库存面注入)
|
||||
_runner.set_relics(_relics) # 迭代 12 T1——特性持有集下传(begin_battle enc.relics 求值面)
|
||||
_runner.set_feats(_feats) # 迭代 12 T1——特性持有集下传(begin_battle enc.feats 求值面)
|
||||
_runner.set_tree_rules(_tree_rules) # 迭代 12 T10——树 rule 键集下传(A/B 面消费)
|
||||
if _shop_mode == "pool":
|
||||
# 商店共享池注入(迭代 11 第②批 T3——库存账本引用+消费 handler 双下传;legacy 模式零注入零扰动)
|
||||
@@ -876,7 +888,7 @@ func _on_level_finished(payload: Dictionary) -> void:
|
||||
_reset_refresh_x() # 迭代 11 第①批 T5b——碰三选一重置 X 余量(不结转)
|
||||
var pick_payload: Dictionary = {
|
||||
"level_index": level_index,
|
||||
"candidates": _draw_curio_candidates(),
|
||||
"candidates": _draw_curio_candidates("level_clear"), # T4 渠道白名单——关底 Boss 击败=通关渠道只出专长
|
||||
"aux_detail": _last_draw_treasure.duplicate(), # 掷定前置(追加批二——道具件具体道具随候选抽定,卡片直显)
|
||||
"heal_gained": heal,
|
||||
"hp_before": hp_before,
|
||||
@@ -908,7 +920,7 @@ func _settle(result: String) -> void:
|
||||
"aux_cleared_last": _last_treasure_cleared, # additive 扩签(迭代 7 T4——末关清空反馈;非末关走 bonus 载荷)
|
||||
"keystone_drops": _keystone_drops.duplicate(true), # additive 扩签(迭代 10——逐杀掉落明细;settle 入账明细/复盘归因数据源)
|
||||
"pool_stock": _pool_stock_snapshot(), # additive 扩签(迭代 11 第②批 T5——终局池读数:清账前快照,商店买走 vs 奖励领走 vs 枯竭的终局面)
|
||||
"relics": _relics.duplicate(), # additive 扩签(迭代 12 T1——特性终局持有集:清账前快照,成型判读取数面)
|
||||
"relics": _feats.duplicate(), # additive 扩签(迭代 12 T1——特性终局持有集:清账前快照,成型判读取数面)
|
||||
}
|
||||
# 败退明细(数值验证工具取数面 2026-09-22——tools/balance_verifier.py 止步节点分布数据源;
|
||||
# 仅失败局附加,键缺省 = 未败退,既有五件事消费方零感知)
|
||||
@@ -976,7 +988,7 @@ func _snapshot_breakpoint() -> void:
|
||||
"aux_items": treasure_snapshot,
|
||||
"bonus_taken": _curio_taken.duplicate(true), # 三选一件获取次数(kind 维度派生账本——断点附随件与读数承载)
|
||||
"bonus_deck": _curio_deck.duplicate(true), # 令牌池余库(TP0 v2.2——池消耗即上限,续玩余库逐枚还原)
|
||||
"relics": _relics.duplicate(), # 特性持有集(迭代 12 T1——局内随机渠道获得态续玩防丢失)
|
||||
"relics": _feats.duplicate(), # 特性持有集(迭代 12 T1——局内随机渠道获得态续玩防丢失)
|
||||
"bonus_pending": _curio_pending.duplicate(true), # 三选一停点态(空 = 无停点——选择停点可中断契约)
|
||||
"bonus_result": _curio_result.duplicate(true), # 已兑付待推进态(空 = 无——中断续玩不重兑付)
|
||||
"bonus_aux_carry": _bonus_treasure_carry.duplicate(true), # 道具件跨关携带(注入前中断防静默丢失)
|
||||
|
||||
Reference in new issue
Block a user