import { RNG } from '../utils/RNG.js'; export class PackManager { constructor(packsData, cardManager) { this.packs = new Map(packsData.map(p => [p.id, p])); this.cardManager = cardManager; } getPack(id) { return this.packs.get(id); } getAllPacks() { return [...this.packs.values()]; } isPackUnlocked(pack, save, campaigns) { if (!pack.unlockCondition) return true; const campaign = campaigns.find(c => c.id === pack.unlockCondition); if (!campaign) return false; if (campaign.missions.length === 0) return false; const completed = save.campaignProgress?.completedMissions || []; return campaign.missions.every(m => completed.includes(m)); } openPack(packId, save) { const pack = this.getPack(packId); if (!pack) return null; const rng = new RNG(Date.now() ^ (Math.random() * 0xffffffff)); const results = []; for (const slot of pack.slots) { const rarity = this._rollRarity(slot.dropRates, rng); const pool = this.cardManager.getAllCards().filter(c => c.rarity === rarity && c.type !== 'commander' && c.type !== 'token' && slot.cardPool.includes(c.faction) ); if (pool.length === 0) continue; const card = pool[rng.nextInt(0, pool.length - 1)]; results.push({ ...card, _slotSpecial: !!slot.special }); } return results; } _rollRarity(dropRates, rng) { const r = rng.next(); let cumulative = 0; for (const [rarity, rate] of Object.entries(dropRates)) { cumulative += rate; if (r < cumulative) return rarity; } return 'common'; } }