主卡T4(拆件批wr6): 断点片段化+获得日记键——level_runner关卡域自交片段(breakpoint_fragment五键node_id/visited_ids/aux_items/shop_shelf/shop_visit_buys+restore_fragment收编_resume_bp直读面含道具库存回填);adv拼盘口重写(_bp_parts=三片段收件:主角账账本键+获得日记/停点件停点态+刷新三源+凭证/关卡件节点域五键——池域taken/deck与桶关序应用层自拼,拼盘完整性自断言fail-fast未登记键中止);BREAKPOINT_FIELDS扩列gain_journal键(28键——契约2唯一声明扩展,旧档缺键=hero.restore_fragment汇总直载跳过比对,日记在档=明细推导比对不符拒载);_resume_curio_state relics段去双载(随主角账片段)。验收:bp1对拍292dumps×27键逐位零漂移(五时点一致)+gain_journal单列在档核对全过+P8冻结清单换代28键+bp2旧档回退与推导比对断言(hero_ledger_test hr2段)+bp3续玩真链(breakpoint_resume现役)+十套件零红〔拆件批 V6〕
This commit is contained in:
1 parent
4da7f3e2f2
commit
fa1409f491
4 files changed
+333011
-15
No files matched your search
@@ -568,6 +568,7 @@ const BREAKPOINT_FIELDS := {
|
||||
"attune_refresh_y": {"strategy": "params_fallback"},
|
||||
"bonus_result": {"strategy": "plain"},
|
||||
"keystone_drops": {"strategy": "plain"},
|
||||
"gain_journal": {"strategy": "plain"}, # 获得日记(拆件批 T4 扩列——唯一声明的断点扩展;旧档缺键=汇总直载跳过比对)
|
||||
}
|
||||
|
||||
|
||||
@@ -584,29 +585,28 @@ func _snapshot_breakpoint() -> void:
|
||||
|
||||
# 断点写侧取值(键集以 BREAKPOINT_FIELDS 为准——未登记键即取值越界,fail-fast)
|
||||
func _bp_parts() -> Dictionary[Variant, Variant]:
|
||||
var treasure_snapshot: Array[Variant] = []
|
||||
if _runner != null and _runner.treasure_inventory != null:
|
||||
treasure_snapshot = _runner.treasure_inventory.snapshot_inventory()
|
||||
# 三选一停点续玩分支 _runner 为 null(关卡已收束、下一关未开)——节点域字段按缺省落档,
|
||||
var hero_frag: Dictionary[Variant, Variant] = _hero.breakpoint_fragment()
|
||||
var stop_frag: Dictionary[Variant, Variant] = _stop.breakpoint_fragment()
|
||||
var level_frag: Dictionary[Variant, Variant] = _runner.breakpoint_fragment() if _runner != null else {
|
||||
"node_id": -1, "visited_ids": [] as Array, "aux_items": [] as Array,
|
||||
"shop_shelf": [] as Array, "shop_visit_buys": 0} # 三选一停点续玩分支 _runner 为 null——节点域按缺省落档
|
||||
# 该两态的续玩只消费 bonus_* 附随件(选择停点/已兑付停点快照)
|
||||
var hero_frag: Dictionary[Variant, Variant] = _hero.breakpoint_fragment() # 主角账片段(账本键+获得日记——T4 拼盘收口前先同源取数)
|
||||
var stop_frag: Dictionary[Variant, Variant] = _stop.breakpoint_fragment() # 停点件片段(T4 拼盘收口前先同源取数)
|
||||
return {
|
||||
var parts: Dictionary[Variant, Variant] = {
|
||||
"level_index": level_index,
|
||||
"node_id": _runner.current_node_id() if _runner != null else -1,
|
||||
"node_id": int(level_frag.get("node_id", -1)),
|
||||
"hero_hp": int(hero_frag.get("hero_hp", 0)),
|
||||
"bonus": hero_frag.get("bonus", {}),
|
||||
"gp": int(hero_frag.get("gp", 0)),
|
||||
"shop_purchased": hero_frag.get("shop_purchased", {}),
|
||||
"shop_shelf": _runner.shop_bp_shelf() if _runner != null else [], # 货架入断点(离开店/非店停点 = 空架合法态)
|
||||
"shop_visit_buys": _runner.shop_bp_visit_buys() if _runner != null else 0, # 本次进店已购次数(A 链定价输入)
|
||||
"shop_shelf": level_frag.get("shop_shelf", []), # 货架入断点(离开店/非店停点 = 空架合法态)
|
||||
"shop_visit_buys": int(level_frag.get("shop_visit_buys", 0)), # 本次进店已购次数(A 链定价输入)
|
||||
"attunement_charges": run_ledger.attune_charges.duplicate(true), # 同调主动件充能余量随断点(save v4 域)
|
||||
"graph_gen_v2": 1, # 生成图换代代差标记(缺键 = 换代前旧断点 → resume 显式拒绝)
|
||||
"master_seed": master_seed,
|
||||
"rng_counter": rng.counter(),
|
||||
"keystone": int(hero_frag.get("keystone", 0)),
|
||||
"visited_ids": _runner.visited_ids() if _runner != null else [],
|
||||
"aux_items": treasure_snapshot,
|
||||
"visited_ids": level_frag.get("visited_ids", []),
|
||||
"aux_items": level_frag.get("aux_items", []),
|
||||
"bonus_taken": _curio_taken.duplicate(true), # 三选一件获取次数(kind 维度派生账本——断点附随件与读数承载)
|
||||
"bonus_deck": _curio_deck.duplicate(true), # 令牌池余库(TP0 v2.2——池消耗即上限,续玩余库逐枚还原)
|
||||
"relics": hero_frag.get("relics", []), # 特性持有集(局内随机渠道获得态续玩防丢失)
|
||||
@@ -616,10 +616,20 @@ func _bp_parts() -> Dictionary[Variant, Variant]:
|
||||
"adventure_counters": adventure_counters.duplicate(true), # adventure 域计数器随断点(续玩跨战账不丢——桶归宿主字典)
|
||||
"vision_counter_used": int(hero_frag.get("vision_counter_used", 0)), # 真视使用计数随断点(续玩跨战账不丢)
|
||||
"refresh_stock": int(stop_frag.get("refresh_stock", 0)), # 刷新存量账随断点
|
||||
"attune_refresh_y": int(stop_frag.get("attune_refresh_y", 0)), # Y 冒险周期池余量随断点(续玩不再自参数面整额重注入=堵「用完退菜单再续玩满血复活」可利用漏洞;扩列向后兼容——旧档缺键回退参数面)
|
||||
"attune_refresh_y": int(stop_frag.get("attune_refresh_y", 0)), # Y 冒险周期池余量随断点(扩列向后兼容——旧档缺键回退参数面)
|
||||
"bonus_result": stop_frag.get("bonus_result", {}), # 已兑付待推进态(空 = 无——中断续玩不重兑付)
|
||||
"keystone_drops": hero_frag.get("keystone_drops", []), # 逐杀掉落明细(摘要归因续接)
|
||||
"gain_journal": hero_frag.get("gain_journal", {}), # 获得日记(唯一声明的断点扩列——日记为正主)
|
||||
}
|
||||
# 拼盘完整性自断言(fail-fast——片段并集与登记键集不符即中止落盘)
|
||||
var stray: Array[Variant] = []
|
||||
for key in parts.keys():
|
||||
if not BREAKPOINT_FIELDS.has(key):
|
||||
stray.append(key)
|
||||
if not stray.is_empty():
|
||||
push_error("[冒险结构] 断点拼盘含未登记键: %s(fail-fast——片段与登记单源失同步)" % str(stray))
|
||||
return parts
|
||||
|
||||
|
||||
|
||||
# 读侧单点(BREAKPOINT_FIELDS 策略标签分发;未登记键 fail-fast 不静默按 plain 兜)。
|
||||
|
||||
@@ -295,6 +295,33 @@ func restore_treasure_items(items: Array) -> void:
|
||||
treasure_inventory.restore_inventory(items)
|
||||
|
||||
|
||||
# ---- 断点自交片段(关卡域——拆件批 T4:应用层唯一拼盘落盘口的收件半边)----
|
||||
|
||||
# 关卡域片段(node_id/visited_ids/aux_items/shop_shelf/shop_visit_buys——五键自交;
|
||||
# 停点续玩分支 _runner 为 null 时节点域按缺省落档〔与真机同构〕)
|
||||
func breakpoint_fragment() -> Dictionary[Variant, Variant]:
|
||||
var treasure_snapshot: Array[Variant] = []
|
||||
if treasure_inventory != null:
|
||||
treasure_snapshot = treasure_inventory.snapshot_inventory()
|
||||
return {
|
||||
"node_id": current_node_id(),
|
||||
"visited_ids": visited_ids(),
|
||||
"aux_items": treasure_snapshot,
|
||||
"shop_shelf": _shop.shop_bp_shelf(),
|
||||
"shop_visit_buys": _shop.shop_bp_visit_buys(),
|
||||
}
|
||||
|
||||
|
||||
# 断点重建参数面收口(原 _resume_bp 直读面收编——resume_state = {"node_id": int(-1 = 入口停点),
|
||||
# "visited_ids": Array[int], "aux_items": Array};空字典 = 既有路径逐位不变)。
|
||||
# 返回 resume_state 形态供 start_level_external 分派(_restore_to_stop / restore_treasure_items)。
|
||||
func restore_fragment(resume_state: Dictionary) -> Dictionary:
|
||||
var aux: Array = resume_state.get("aux_items", []) as Array
|
||||
if not aux.is_empty():
|
||||
restore_treasure_items(aux)
|
||||
return resume_state
|
||||
|
||||
|
||||
func _find_level_row(level_index: int) -> Dictionary:
|
||||
return db.level_row(level_index) # 表访问收口(行集直扫归 LevelTable/ConfigDB 访问器)
|
||||
|
||||
|
||||
@@ -191,12 +191,12 @@ func _init() -> void:
|
||||
"P8 登记单源键集 == 写侧实拼断点键集(%d 键逐一对齐)〔wr2〕" % reg_keys.size())
|
||||
var frozen_keys := ["adventure_counters", "attunement_charges", "attune_refresh_y", "aux_items",
|
||||
"bonus", "bonus_deck", "bonus_pending", "bonus_result", "bonus_taken", "feat_ticket_pity",
|
||||
"feat_ticket_sold", "gp", "graph_gen_v2", "hero_hp", "keystone", "keystone_drops",
|
||||
"feat_ticket_sold", "gain_journal", "gp", "graph_gen_v2", "hero_hp", "keystone", "keystone_drops",
|
||||
"level_index", "master_seed", "node_id", "refresh_stock", "relics", "rng_counter",
|
||||
"shop_purchased", "shop_shelf", "shop_visit_buys", "visited_ids", "vision_counter_used"]
|
||||
frozen_keys.sort()
|
||||
Kit.check_quiet(reg_keys == frozen_keys,
|
||||
"P8 键集与冻结清单逐位一致(27 键契约;增删键即红)〔wr2〕")
|
||||
"P8 键集与冻结清单逐位一致(28 键契约——拆件批获得日记键为唯一声明扩展;增删键即红)〔wr2〕")
|
||||
var vocab := ["plain", "clamp", "keep_on_null", "dual_merge", "params_fallback", "token_migration"]
|
||||
var stray: Array = []
|
||||
for k in fields.keys():
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user