# VERTICAL SLICE - NOT FOR PRODUCTION # Date: 2026-09-13(自 main.gd 拆出——规范 1.1 审视线 / 调试语义单一实现纪律) # 调试模式编排控制器:单场遭遇(第 1/2 层)与连续两层(HP 关内延续)的模式状态机与战斗生命周期。 # 职责边界:层序/携带 HP + 战斗结算 生命周期编排(创建 / begin_battle)。 # 层间延续 = HP 关内延续(库存与共享 地图战斗资源 已下线)。 # 授权边界:与 tune_sim_controller 同款——控制器承接模式编排, # 组合根仍持有全部信号接线(battle_created 先于 begin_battle 发出,ADR-0001 接线唯一归组合根) # 与终局 UI 决策;玩家意图写调用(settle_batch / 刷新)不经本类。 # 加成生效值经注入 Callable 供给(组合根从面板百分比现算)→ encounter # 显式传入战斗——零表写。 extends RefCounted signal battle_created(settlement, level: int, carry_hp: int) # begin_battle 前——组合根完成信号接线(ADR-0001) 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 # 单场遭遇原语(2026-09-13 用户裁决:单场用户入口已删——本方法仅 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