import { SaveManager } from '../managers/SaveManager.js'; export class CampaignScene extends Phaser.Scene { constructor() { super('CampaignScene'); } init(data) { this.campaignId = data.campaignId || 'campaign_raider'; } create() { const allMissions = this.registry.get('missions'); const campaigns = this.registry.get('campaigns'); const save = this.registry.get('save'); const { width, height } = this.scale; const campaign = campaigns.find(c => c.id === this.campaignId); const missions = allMissions.filter(m => m.campaignId === this.campaignId); this.add.rectangle(width / 2, height / 2, width, height, 0x0d1b2a); this.add.text(width / 2, 45, campaign ? campaign.name : 'Campaign', { fontSize: '42px', color: '#d4af37', fontFamily: 'RaiderCrusader' }).setOrigin(0.5); if (campaign) { this.add.text(width / 2, 90, `Level ${campaign.level} — ${campaign.faction.toUpperCase()}`, { fontSize: '18px', color: '#888888', fontFamily: 'Audiowide' }).setOrigin(0.5); } const completed = save.campaignProgress.completedMissions; // Check if campaign is fully complete const allDone = missions.length > 0 && missions.every(m => completed.includes(m.id)); if (allDone && campaign) { this._checkCampaignRewards(campaign, save, campaigns); } missions.forEach((mission, i) => { const isUnlocked = !mission.unlockCondition || completed.includes(mission.unlockCondition); const isDone = completed.includes(mission.id); const x = 300 + (i % 4) * 375; const y = 380 + Math.floor(i / 4) * 260; const color = isDone ? 0x228822 : isUnlocked ? 0x1a3a5c : 0x333333; const borderColor = isDone ? 0x44ff44 : isUnlocked ? 0x4488ff : 0x666666; const node = this.add.rectangle(x, y, 300, 220, color) .setStrokeStyle(2, borderColor); if (isUnlocked) { node.setInteractive({ useHandCursor: true }); node.on('pointerover', () => node.setFillStyle(isDone ? 0x33aa33 : 0x2a5a8c)); node.on('pointerout', () => node.setFillStyle(color)); node.on('pointerdown', () => this._startMission(mission, campaign)); } this.add.text(x, y - 70, mission.name, { fontSize: '20px', color: isUnlocked ? '#ffffff' : '#666666', wordWrap: { width: 270 }, align: 'center', fontFamily: 'Audiowide' }).setOrigin(0.5); this.add.text(x, y - 35, `Mission ${i + 1}`, { fontSize: '16px', color: '#888888', fontFamily: 'Audiowide' }).setOrigin(0.5); this.add.text(x, y, isDone ? 'Complete' : isUnlocked ? 'Click to battle' : 'Locked', { fontSize: '16px', color: isDone ? '#44ff44' : isUnlocked ? '#aaffaa' : '#666666', fontFamily: 'Audiowide' }).setOrigin(0.5); // Rewards this.add.text(x, y + 30, `+${mission.rewards.gold} gold`, { fontSize: '14px', color: '#ffd700', fontFamily: 'Audiowide' }).setOrigin(0.5); if (mission.rewards.cards && mission.rewards.cards.length > 0) { this.add.text(x, y + 55, `Card reward available`, { fontSize: '14px', color: '#aaffaa', fontFamily: 'Audiowide' }).setOrigin(0.5); } }); // Mission lore panel this.loreText = this.add.text(width / 2, height - 70, 'Hover over a mission to learn more.', { fontSize: '18px', color: '#888888', align: 'center', wordWrap: { width: width - 100 }, fontFamily: 'Audiowide' }).setOrigin(0.5); this._makeBackButton(); } _startMission(mission, campaign) { const save = this.registry.get('save'); if (!save.decks || save.decks.length === 0) { this.add.text(960, 940, 'No deck! Create a deck in Deck Builder first.', { fontSize: '22px', color: '#ff4444', fontFamily: 'Audiowide' }).setOrigin(0.5); return; } this.sound.play('sfx_menu_select', { volume: 0.7 }); this.scene.start('BattleScene', { mission, deck: save.decks[0], playerLevel: save.level || 1, enemyLevel: save.level || 1, campaignId: this.campaignId }); } _checkCampaignRewards(campaign, save, allCampaigns) { // Award starter reward cards if not already awarded const rewardKey = `campaignReward_${campaign.id}`; if (campaign.starterReward?.cards?.length > 0 && !save[rewardKey]) { for (const cardId of campaign.starterReward.cards) { save.collection[cardId] = (save.collection[cardId] || 0) + 1; } save[rewardKey] = true; // Level up if completing this campaign grants a new level if (campaign.level >= save.level && save.level < 5) { save.level = Math.min(5, campaign.level + 1); } // Unlock next campaign const nextCampaign = allCampaigns.find(c => c.unlockCondition === campaign.id); if (nextCampaign && !save.unlockedCampaigns.includes(nextCampaign.id)) { save.unlockedCampaigns.push(nextCampaign.id); } SaveManager.save(save); } } _makeBackButton() { const bg = this.add.rectangle(80, 45, 160, 50, 0x333333) .setInteractive({ useHandCursor: true }) .setStrokeStyle(1, 0x888888); this.add.text(80, 45, 'Back', { fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide' }).setOrigin(0.5); bg.on('pointerdown', () => { this.sound.play('sfx_menu_select', { volume: 0.7 }); this.scene.start('CampaignSelectScene'); }); } }