import { TableNames } from '../../game/ConfigTableData'; import { parseBattleBuffRow } from '../../manager/BattleBuffParse'; import type { DailyShopParsed } from '../../manager/DailyShopTypes'; import { DailyShopKind } from '../../manager/DailyShopTypes'; /** 单玩家本局携带的 Battlebuff 解析结果 */ interface BattleBuffPlayerCarry { /** playerId */ playerId: number; /** 主动 */ actives: DailyShopParsed[]; /** 被动 */ passives: DailyShopParsed[]; } /** * 局内按 playerId 的 buff 携带库(单局有效,开战 clear)。 */ 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, DailyShopKind.Active); const passives = this._parseIds(passiveIds, DailyShopKind.Passive); const existing = this._ensure(pid); existing.actives = actives; existing.passives = passives; } /** * 追加一个本局获得的 buff(默认入被动列表)。 * @param playerId 槽位 * @param buffId Battlebuff.id */ static appendBuffId(playerId: number, buffId: number): DailyShopParsed | null { const id = Math.floor(Number(buffId) || 0); if (id <= 0) { console.warn('[BattleBuffCarryStore] append 非法 id', buffId); return null; } const row = gg.data.table.getTableData(TableNames.Battlebuff, id); if (!row) { console.warn('[BattleBuffCarryStore] Battlebuff 缺失', id); return null; } const parsed = parseBattleBuffRow(row); if (!parsed) return null; const pid = Math.max(0, Math.floor(Number(playerId) || 0)); const carry = this._ensure(pid); if (parsed.kind === DailyShopKind.Active) { carry.actives.push(parsed); } else { carry.passives.push(parsed); } return parsed; } /** * 本局某 buff 已获得次数(主动+被动合计)。 * @param playerId 槽位 * @param buffId Battlebuff.id */ static getObtainCount(playerId: number, buffId: number): number { const id = Math.floor(Number(buffId) || 0); if (id <= 0) return 0; const row = this._find(Math.max(0, Math.floor(Number(playerId) || 0))); if (!row) return 0; let n = 0; for (let i = 0; i < row.passives.length; i++) { if (row.passives[i].id === id) n++; } for (let i = 0; i < row.actives.length; i++) { if (row.actives[i].id === id) n++; } return n; } /** * 本局被动列表。 * @param playerId 槽位 */ static getPassives(playerId: number): DailyShopParsed[] { const row = this._find(Math.max(0, Math.floor(Number(playerId) || 0))); return row ? row.passives.slice() : []; } /** * 本局主动列表。 * @param playerId 槽位 */ static getActives(playerId: number): DailyShopParsed[] { const row = this._find(Math.max(0, Math.floor(Number(playerId) || 0))); return row ? row.actives.slice() : []; } /** 是否已为该玩家写入携带(含空列表) */ static hasOverride(playerId: number): boolean { return !!this._find(Math.max(0, Math.floor(Number(playerId) || 0))); } private static _ensure(playerId: number): BattleBuffPlayerCarry { const existing = this._find(playerId); if (existing) return existing; const created: BattleBuffPlayerCarry = { playerId, actives: [], passives: [] }; this._players.push(created); return created; } 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。 * @param ids id 列表 * @param expectKind 期望 kind */ private static _parseIds(ids: readonly number[], expectKind: DailyShopKind): DailyShopParsed[] { const out: DailyShopParsed[] = []; for (let i = 0; i < ids.length; i++) { const id = Math.floor(Number(ids[i]) || 0); if (id <= 0) continue; const row = gg.data.table.getTableData(TableNames.Battlebuff, id); if (!row) { console.warn('[BattleBuffCarryStore] Battlebuff 缺失', id); continue; } const parsed = parseBattleBuffRow(row); if (!parsed) continue; if (parsed.kind !== expectKind) { console.warn('[BattleBuffCarryStore] kind 不符', id, parsed.kind, 'expect', expectKind); continue; } out.push(parsed); } return out; } }