## VERTICAL SLICE - NOT FOR PRODUCTION ## 调试模式编排控制器:单场遭遇与连续两层(HP 关内延续)的模式状态机与战斗生命周期。 ## 信号接线唯一归组合根——battle_created 必须先于 begin_battle 完成接线;玩家意图写调用(settle_batch/刷新)不经本类。 ## 加成生效值经注入 Callable 现算、随 encounter 显式传参——零表写。 extends RefCounted signal battle_created(settlement, level: int, carry_hp: int) ## begin_battle 前——组合根完成信号接线 signal battle_ready(settlement, level: int, carry_hp: int) ## begin_battle 完成后——组合根 rebuild 棋盘 + 刷新呈现 var db var rng # /root/RngService(组合根注入) var _hero_override: Callable # 组合根生效值供给(→ {atk, max_hp};E4:经 encounter 传参,零表写) var _seed_value: Callable # 组合根种子读取(LineEdit) var _level_mode := false var _level_battles: Array[int] = [] var _level_idx := 0 var _carry_hp := 0 var settlement = null # 当前战斗编排器(组合根在 battle_created 接线、battle_ready 接手) func _init(db_ref, rng_ref, hero_override: Callable, seed_value: Callable) -> void: db = db_ref rng = rng_ref _hero_override = hero_override _seed_value = seed_value # 单场遭遇原语(无单场用户入口——本方法仅 ui_probe 单场段使用; # 无延续、standalone 终局语义保留供探针战斗收尾) func start_single(level: int) -> bool: _level_mode = false return _start_battle(level, -1) # 连续两层(调试入口——HP 关内延续;首层满血开局) func start_debug_levels() -> bool: _level_mode = true _level_battles = [1, 2] _level_idx = 0 _carry_hp = 0 rng.new_adventure(_seed_value.call()) return _start_battle(_level_battles[0], -1) # 层间"进入下一层"(组合根过渡覆盖层确认后调用) func next_layer() -> bool: return _start_battle(_level_battles[_level_idx], _carry_hp) # 终局处置(组合根 battle_finished 处理器调用)→ 决策载荷: # {outcome: "next_layer"|"level_end"|"standalone_end", layer, carry_hp} func on_battle_finished(payload: Dictionary) -> Dictionary: var result: String = String(payload.get("result", "")) if result == "victory" and _level_mode and _level_idx < _level_battles.size() - 1: _carry_hp = maxi(1, int(payload.get("hero_hp", 0))) # despawn 前捕获值 _level_idx += 1 return {"outcome": "next_layer", "layer": _level_idx, "carry_hp": _carry_hp} var is_level_end := result == "victory" and _level_mode return {"outcome": "level_end" if is_level_end else "standalone_end", "layer": _level_idx, "carry_hp": _carry_hp} # 会话复位(组合根终局出口"返回开始界面"调用) func reset() -> void: _level_mode = false settlement = null func _start_battle(level: int, carry_hp: int) -> bool: if not _level_mode or _level_idx == 0: rng.new_adventure(_seed_value.call()) var ov: Dictionary[Variant, Variant] = _hero_override.call() # E4:生效值经 encounter 传入——零表写 settlement = BattleOrchestrator.new(db, rng) battle_created.emit(settlement, level, carry_hp) var hp: int = carry_hp if carry_hp > 0 else int(ov.max_hp) if not settlement.begin_battle({"level_index": level, "node_depth": 0, "hero_hp": hp, "hero_atk": int(ov.atk), "hero_max_hp": int(ov.max_hp)}): push_error("[DebugSession] 战斗启动失败(level %d)" % level) return false battle_ready.emit(settlement, level, carry_hp) return true