主卡T3(拆件批wr4/wr5): 应用层收薄+构造注入+信号直连——adventure_runner六转发信号族与_forward_*方法删除(选路快照双职改核心侧受理_on_level_choices_presented直订level信号;stop信号中继删);level_runner构造注入一次给齐(_init收ctx十二键:hero/ledger瘦壳/adv_bucket/attunement/tree_rules活引用/shop_mode/treasure_unlocked/类型轴/凭证出箱/pool_wiring四参——后置setter群八件与set_hero/set_run_ledger退役,_bind_shop全仓仅构造一处,头注补关卡开始信号前零发射契约,八白盒属性内部改直指_shop);adv _start_current_level组包ctx(_inject_level_params退役改_emit_level_started只广播);呈现/测量信号直连(main_adventure_flow _connect_runner_once六信号level_started重取点is_connected守卫重连+三选一订stop();autoplay增订level_started同关守卫重连三信号;curio_interact_controller 14处adventure.stop()改址);测量面残留换代(bp_baseline_dump直连改level_started重连/ui_tune_probe与main_debug_flow keystone读hero());测试直连面换代(breakpoint_resume P5订stop()/adventure_feats信号序观测level_started回调内重连——bind句柄每回调新建不以Callable相等判重);sc3源码断言落hero_ledger_test(_bind_shop全仓仅构造一处/_forward_族零命中)〔拆件批 V5〕。验收:bp1对拍292dumps×27键逐位零漂移(改前/T1/T2/T3四时点一致)+十套件零红+csf集成绿+冒烟17项0失败〔拆件批 V4〕〔拆件批 V5〕

This commit is contained in:
DKChan committed 2026-10-27 03:51:35 +08:00
1 parent 4a9e4300ad
commit 4da7f3e2f2
13 files changed
+188276 -173

No files matched your search

+32 -71
View File
@@ -10,14 +10,6 @@ signal level_started(level_index: int, display_name: String) ## 每关开始
signal curio_choice_presented(payload: Dictionary) ## 专长三选一停点(非末关的关卡完成恰一次;通道白名单后候选恒专长+回血在载荷)——{level_index, candidates, heal_gained, hp_before, hp_after, keystone_gained, keystone_total, gp, aux_cleared}
signal curio_resolved(result: Dictionary) ## 三选一兑付完成(pick_curio/替换受理后恰一次)——{picked, value, hp_before, hp_after, level_index}
signal adventure_finished(summary: Dictionary) ## 冒险结算(completed/failed/abandoned)——summary 五件事:打穿没有/完成几关/止步第几关/钥石合计/主种子(+additive keystone_drops)
# ---- 转发族(签名与 LevelRunner 同款——呈现层对接透明;S6 经 _forward_* 方法)----
signal node_entered(node: Dictionary, info: Dictionary)
signal choices_presented(candidates: Array)
signal step_row(row: Dictionary)
signal round_started(round_index: int)
signal board_changed()
signal wallet_changed(event: String, gp: int, extra: Dictionary)
var db: ConfigDb
var rng: RngServiceCore
enum State { IDLE, RUNNING, SETTLING } # 会话状态机(内部 enum,外部 String 契约经 getter 词表)
@@ -59,8 +51,6 @@ func _init(db_ref: ConfigDb, rng_ref: RngServiceCore) -> void:
_hero = HeroLedger.new(db, {})
_curio = CurioDeck.new(db, rng)
_stop = CurioStop.new(db, _curio, _hero, _snapshot_breakpoint)
_stop.curio_choice_presented.connect(_relay_stop_choice_presented)
_stop.curio_resolved.connect(_relay_stop_resolved)
# 件出口(组件交出非委托壳——呈现/测量面取主角账单点;拆件批接口块)
@@ -73,15 +63,6 @@ func stop() -> CurioStop:
return _stop
# 停点件信号中继(呈现层直订面在 T3 信号直连前由本类承转——方法转发非 lambda)
func _relay_stop_choice_presented(payload: Dictionary) -> void:
curio_choice_presented.emit(payload)
func _relay_stop_resolved(result: Dictionary) -> void:
curio_resolved.emit(result)
# ---- 冒险生命周期 ----
# 冒险开始(主种子注入恰一次——全冒险唯一 rng.new_adventure 调用点;重开 = 全新一轮:
@@ -160,7 +141,7 @@ func resume_adventure(bp: Dictionary, params: Dictionary = {}) -> bool:
_pending_next_level = true
_stop.restore_resolved(bp_result)
_state = State.RUNNING
curio_resolved.emit(_stop.resolved_payload())
_stop.reemit_resolved() # 已兑付不重兑付只重发(信号面归停点件)
return true
_resume_bp = bp.duplicate(true)
# 充能账本随断点回局(缺键 = 旧档/无断点,保持 _seed_attune_charges 种子态)
@@ -419,7 +400,26 @@ func abandon() -> bool:
# ---- 关卡推进(私有——序列编排单一出口)----
func _start_current_level() -> bool:
_runner = LevelRunner.new(db, rng)
# 关卡对象构造注入一次给齐(拆件批 T3——ctx 键集见 LevelRunner._init 头注;
# 凭证出箱在组包时点取走〔节点级一次性——未用即过期语义不变〕)
var outbox: Dictionary[Variant, Variant] = _stop.voucher_outbox()
var pool_wiring: Dictionary[Variant, Variant] = {"deck": _curio_deck, "consume": _stop.consume_pool_purchase,
"ticket": _feat_ticket_consider, "cap": _curio_cap_ok} if _shop_mode == "pool" else {}
var ctx: Dictionary[Variant, Variant] = {
"hero": _hero,
"ledger": run_ledger,
"adv_bucket": adventure_counters,
"attunement": _attunement,
"tree_rules": _tree_rules,
"shop_mode": _shop_mode,
"treasure_unlocked": _treasure_unlocked,
"hero_attack_type": _hero.attack_type,
"hero_armor_type": _hero.armor_type,
"voucher_rap": int(outbox.get("rap", 0)),
"voucher_time_sand": int(outbox.get("time_sand", 0)),
"pool_wiring": pool_wiring,
}
_runner = LevelRunner.new(db, rng, ctx)
_bind_level_runner()
_stop.rebind_level_runner(_runner, level_index) # 停点件每关注入时点(GP 件入账回调换代——防跨关调死对象)
# 断点续玩分支:图由主种子+参数档重生成同图(产图与计数器号位无关,停点零重抽语义随之消解),
@@ -435,43 +435,24 @@ func _start_current_level() -> bool:
# 呈现零 RNG 消耗、pick 走同一 _enter_node——测量面逐位零漂移。
var ok: bool = _runner.start_level_external(level_index, apply_rest, true, resume_state)
if ok:
_inject_level_params()
_emit_level_started()
_present_level_entry(resume_state)
_resume_bp = {}
return ok
# 关卡行进器接线(每关新实例:信号转发 + 共享账下传)
# 关卡行进器接线(每关新实例:结算受理连接 + 能力件骑库存注入——信号转发族已退役,
# 呈现/模拟器在 level_started 重取点直连 runner 信号〔is_connected 守卫恰好一次〕)
func _bind_level_runner() -> void:
# 树限次计数按关清零现由 LevelRunner.level_counters 随每关 new 天然承载(旧硬编码清除名单函数已删)
# core↔core 接线只许方法 Callable(S6——lambda 捕获 self 会延长 RefCounted 生命周期乃至成环)
_runner.node_entered.connect(_forward_node_entered)
_runner.choices_presented.connect(_forward_choices_presented)
_runner.step_row.connect(_forward_step_row)
_runner.round_started.connect(_forward_round_started)
_runner.board_changed.connect(_forward_board_changed)
_runner.wallet_changed.connect(_forward_wallet_changed)
_runner.level_finished.connect(_on_level_finished)
_runner.set_hero(_hero, adventure_counters) # 主角账与冒险桶注入(账面单点共享——T1 过渡面)
_runner.set_run_ledger(run_ledger) # 充能账瘦壳下传
_runner.sync_attune_inventory() # 能力件骑库存面注入(随账下传同拍)
_runner.choices_presented.connect(_on_level_choices_presented) # 选路停点快照触发(原转发兼快照双职的核心侧受理)
_runner.sync_attune_inventory() # 能力件骑库存面注入(构造注入同拍)
# 关卡参数注入(装配集/特性/rule 键/类型轴/商店池/凭证件 + level_started 广播)
func _inject_level_params() -> void:
_runner.set_attunement(_attunement) # 同调装配下传(enc 携带进战斗结算)
_runner.set_feats(_hero.feats) # 特性持有集下传(活引用——关内兑付 relic 当关生效;begin_battle enc.feats 求值面)
_runner.set_tree_rules(_tree_rules) # 树 rule 键集下传(A/B 面消费)
_runner.set_hero_axes(_hero.attack_type, _hero.armor_type) # 两根类型轴快照下传(enc 携带进 spawn)
if _shop_mode == "pool":
# 商店共享池注入(库存账本引用+消费 handler 双下传——消费经注入 Callable 直达停点件兑付单点;
# legacy 模式零注入零扰动。cap 检查回调四参注入)
_runner.set_shop_pool(_curio_deck, _stop.consume_pool_purchase, _feat_ticket_consider, _curio_cap_ok)
# 凭证件出箱注入(节点级/回合级一次性:注入即清零,未用即过期=寿命档语义)
var outbox: Dictionary[Variant, Variant] = _stop.voucher_outbox()
_runner.set_voucher_grants(int(outbox.get("rap", 0)), int(outbox.get("time_sand", 0)))
# 三选一道具件跨关携带注入面不存在(aux 卡不在池种内→ carry 恒空集;
# 容器字段保留=替换子交互惰性承载,零投放零行为)
# 关卡开始广播(装配已随构造注入进 ctx——本函数只剩信号广播;信号顺序契约:
# 关卡开始信号先于入口候选呈现〔defer_entry 两步式以本发射为界〕)
func _emit_level_started() -> void:
level_started.emit(level_index, String(_runner.level_row.get("display_name", "")))
@@ -548,15 +529,9 @@ func _settle(result: String) -> void:
_state = State.IDLE
# ---- 转发族(签名与 LevelRunner 同款——呈现层对接透明)----
func _forward_node_entered(node: Dictionary, info: Dictionary) -> void:
node_entered.emit(node, info)
func _forward_choices_presented(candidates: Array) -> void:
choices_presented.emit(candidates)
_snapshot_breakpoint() # 停点快照(选路停点=唯一可恢复停点形态;战斗中不存)
# 选路停点快照受理(level.choices_presented 直订——选路停点=唯一可恢复停点形态;战斗中不存)
func _on_level_choices_presented(_candidates: Array) -> void:
_snapshot_breakpoint()
# ---- 断点快照(字段登记单源:写侧拼装与读侧回退策略同登记一表)----
@@ -674,17 +649,3 @@ func _bp_read_int(key: String, bp: Dictionary, fallback: int, params: Dictionary
return int(bp.get(key, fallback))
func _forward_step_row(row: Dictionary) -> void:
step_row.emit(row)
func _forward_round_started(ri: int) -> void:
round_started.emit(ri)
func _forward_board_changed() -> void:
board_changed.emit()
func _forward_wallet_changed(event: String, gp_val: int, extra: Dictionary) -> void:
wallet_changed.emit(event, gp_val, extra)