import type { Player } from '../game/Player'; import { BattleBuffCarryStore } from '../manager/battleBuff/BattleBuffCarryStore'; import { BattleBuffSelectService } from '../manager/battleBuff/BattleBuffSelectService'; import { createBattleRuntime, type ProjectBattleHandle } from './runtime/BattleRuntime'; import { TableBattleConfigProvider } from './config/TableBattleConfigProvider'; import { BattleUiPauseGate } from './BattleUiPauseGate'; import { installAtkDebugHooks } from './debug/AtkDebugLog'; import type { IBattleService } from './IBattleService'; import type { BattleDeployParams, BattleStartParams, IBattleRuntimeHandle, } from './types/ProjectBattleTypes'; /** 战斗模块实现:对局生命周期,由 gg.battle 持有单实例 */ export class BattleService implements IBattleService { readonly config = new TableBattleConfigProvider(); private _match: ProjectBattleHandle | null = null; get match(): IBattleRuntimeHandle | null { return this._match; } get localPlayer() { return this._match?.player; } get players(): readonly Player[] { return this._match?.players ?? []; } get remotePlayer() { return this._match?.remotePlayer; } init(): void { this.config.loadStaticTables(); installAtkDebugHooks(); } start(params: BattleStartParams): IBattleRuntimeHandle | null { installAtkDebugHooks(); this.end(); BattleBuffCarryStore.clear(); BattleBuffSelectService.resetAll(); this._seedGmCarryBuffs(params.localPlayerId ?? 0); const runtime = createBattleRuntime(params); if (!runtime) { console.error(`[BattleService] start failed level=${params.levelId} rank=${params.playerRankId} opp=${params.opponentRankId}`); return null; } this._match = runtime; return runtime; } /** * GM 词条:开战 clear 后按 gg.game.gmCarryBuffIds 灌入本机 CarryStore。 * @param localPlayerId 本机槽位 */ private _seedGmCarryBuffs(localPlayerId: number): void { const ids = gg.game.gmCarryBuffIds; if (!ids?.length) return; const pid = Math.max(0, Math.floor(Number(localPlayerId) || 0)); let ok = 0; for (let i = 0; i < ids.length; i++) { const parsed = BattleBuffCarryStore.appendBuffId(pid, ids[i]); if (parsed) ok++; else console.warn('[BattleService] GM 词条灌入失败', ids[i]); } console.log(`[BattleService] GM 词条灌入 player=${pid} count=${ok}/${ids.length}`); } end(): void { BattleUiPauseGate.clear(); const levelId = this._match?.levelId; this._match?.destroy(); this._match = null; if (levelId) { this.config.releaseBattleSession(levelId); } } tick(dt: number): void { this._match?.tick(dt); } deploy(params: BattleDeployParams): boolean { return this._match?.deploy(params) ?? false; } startCombat(): void { this._match?.startCombat(); } startPrep(): void { this._match?.startPrep(); } }