import { TableNames } from '../../game/ConfigTableData'; import { parseBattleBuffRow } from '../../manager/BattleBuffParse'; import { DailyShopDataManager } from '../../manager/DailyShopDataManager'; import type { DailyShopParsed } from '../../manager/DailyShopTypes'; /** 单玩家本局携带的 Battlebuff 解析结果 */ interface BattleBuffPlayerCarry { /** playerId */ playerId: number; /** 主动 */ actives: DailyShopParsed[]; /** 被动 */ passives: DailyShopParsed[]; } /** * 局内按 playerId 的 buff 携带库。 * 本机(默认 0)读 DailyShop;AI 等非本机由匹配档案写入。 */ export class BattleBuffCarryStore { private static readonly _players: BattleBuffPlayerCarry[] = []; /** 清空本局非本机携带(开战/结束时调用) */ static clear(): void { this._players.length = 0; } /** * 写入某玩家本局主动/被动 Battlebuff.id 列表。 * @param playerId 槽位 * @param activeIds 主动 id * @param passiveIds 被动 id */ static setFromBuffIds(playerId: number, activeIds: readonly number[], passiveIds: readonly number[]): void { const pid = Math.max(0, Math.floor(Number(playerId) || 0)); const actives = this._parseIds(activeIds, 1); const passives = this._parseIds(passiveIds, 2); const existing = this._find(pid); if (existing) { existing.actives = actives; existing.passives = passives; return; } this._players.push({ playerId: pid, actives, passives }); } /** * 本局被动列表。 * @param playerId 槽位;本机未写入库时回退 DailyShop */ static getPassives(playerId: number): DailyShopParsed[] { const pid = Math.max(0, Math.floor(Number(playerId) || 0)); const row = this._find(pid); if (row) return row.passives.slice(); if (pid === 0) return DailyShopDataManager.getOwnedPassive(); return []; } /** * 本局主动列表。 * @param playerId 槽位;本机未写入库时回退 DailyShop */ static getActives(playerId: number): DailyShopParsed[] { const pid = Math.max(0, Math.floor(Number(playerId) || 0)); const row = this._find(pid); if (row) return row.actives.slice(); if (pid === 0) return DailyShopDataManager.getOwnedActive(); return []; } /** 是否已为该玩家写入携带(含空列表) */ static hasOverride(playerId: number): boolean { return !!this._find(Math.max(0, Math.floor(Number(playerId) || 0))); } private static _find(playerId: number): BattleBuffPlayerCarry | null { for (let i = 0; i < this._players.length; i++) { if (this._players[i].playerId === playerId) return this._players[i]; } return null; } /** * Battlebuff.id → DailyShopParsed;校验 type。 * @param ids id 列表 * @param expectType 1 主动 / 2 被动 */ private static _parseIds(ids: readonly number[], expectType: 1 | 2): DailyShopParsed[] { const out: DailyShopParsed[] = []; const seen: number[] = []; for (let i = 0; i < ids.length; i++) { const id = Math.floor(Number(ids[i]) || 0); if (id <= 0) continue; let dup = false; for (let s = 0; s < seen.length; s++) { if (seen[s] === id) { dup = true; break; } } if (dup) continue; seen.push(id); const row = gg.data.table.getTableData(TableNames.Battlebuff, id); if (!row) { console.log('[BattleBuffCarryStore] Battlebuff 缺失', id); continue; } if (Math.floor(Number(row.type) || 0) !== expectType) { console.log('[BattleBuffCarryStore] type 不符', id, row.type, 'expect', expectType); continue; } const parsed = parseBattleBuffRow(row); if (!parsed) continue; out.push(parsed); } return out; } }