/** * PortalNetworkSystem.js * ====================== * KRVAVA Ε½ETEV - Portal Network System (P15) * * Features: * - 9 Portal zones with activation quests * - Portal mechanics (swirl effects, nausea) * - Town Portal Hub (fast travel) * - 3 Secret portals * - Portal upgrades * * @author NovaFarma Team * @date 2025-12-23 */ export default class PortalNetworkSystem { constructor(scene) { this.scene = scene; // Portal registry this.portals = new Map(); this.activePortals = new Set(); // Portal hub this.hubUnlocked = false; this.zlatnikiBalance = 0; // Upgrades this.hasStabilizer = false; this.hasBeacon = false; // Travel state this.isInTransit = false; this.nauseaDebuff = null; console.log('πŸŒ€ PortalNetworkSystem initialized'); // Register all portals this.registerPortals(); } /** * 15.1 - Register all portal zones */ registerPortals() { const portals = [ // Main Zone Portals { id: 'dino_valley', name: 'Dino Valley Portal', zone: 'Dino Valley', location: { x: 50, y: 400 }, activationQuest: { name: 'Jurassic Discovery', objective: 'Find 3 Dino Eggs', items: ['dino_egg'], required: 3 }, icon: 'πŸ¦•' }, { id: 'mythical', name: 'Mythical Realm Portal', zone: 'Mythical Realm', location: { x: 400, y: 50 }, activationQuest: { name: 'Dragon Slayer', objective: 'Slay 5 Dragons', enemies: ['dragon'], required: 5 }, icon: 'πŸ‰' }, { id: 'endless_forest', name: 'Endless Forest Portal', zone: 'Endless Forest', location: { x: 350, y: 200 }, activationQuest: { name: 'Bigfoot Hunt', objective: 'Find Bigfoot', npc: 'bigfoot', required: 1 }, icon: '🌲' }, { id: 'loch_ness', name: 'Loch Ness Portal', zone: 'Loch Ness', location: { x: 100, y: 200 }, activationQuest: { name: 'Nessie Summoning', objective: 'Fish all lakes, summon Nessie', actions: ['fish_all_lakes', 'summon_nessie'], required: 2 }, icon: 'πŸ¦•' }, { id: 'catacombs', name: 'Catacombs Portal', zone: 'Ancient Catacombs', location: { x: 300, y: 300 }, activationQuest: { name: 'Keymaster', objective: 'Find 9 Ancient Keys', items: ['ancient_key'], required: 9 }, icon: 'πŸ—οΈ' }, { id: 'egypt', name: 'Egyptian Portal', zone: 'Egyptian Pyramids', location: { x: 200, y: 400 }, activationQuest: { name: 'Hieroglyph Master', objective: 'Solve hieroglyph puzzle', puzzle: 'hieroglyph', required: 1 }, icon: 'πŸ”Ί' }, { id: 'amazon', name: 'Amazon Portal', zone: 'Amazon Jungle', location: { x: 300, y: 450 }, activationQuest: { name: 'Piranha Survivor', objective: 'Survive piranha river crossing', survival: 'piranha_river', required: 1 }, icon: '🌴' }, { id: 'atlantis', name: 'Atlantis Portal', zone: 'Atlantis Ruins', location: { x: 450, y: 450 }, activationQuest: { name: 'Crystal Collector', objective: 'Find 7 Atlantean Crystals', items: ['atlantean_crystal'], required: 7 }, icon: 'πŸ”±' }, { id: 'chernobyl', name: 'Chernobyl Zone', zone: 'Chernobyl Exclusion Zone', location: { x: 150, y: 450 }, activationQuest: { name: 'Train Access Only', objective: 'Unlock via train system (no portal!)', special: 'train_only', required: 1 }, icon: '☒️', noPortal: true }, // 15.4 - Secret Portals { id: 'developer_realm', name: 'Developer Realm', zone: 'Developer Secret Area', location: { x: 1, y: 1 }, // Hidden! activationQuest: { name: 'Easter Egg Challenge', objective: 'Find the secret developer egg', secret: true, required: 1 }, icon: 'πŸ‘¨β€πŸ’»', secret: true }, { id: 'time_portal', name: 'Time Portal', zone: 'Pre-Outbreak Lab (Flashback)', location: { x: 250, y: 250 }, // Spawn town activationQuest: { name: 'Ana\'s Memories', objective: 'Complete main quest Act 2', quest: 'act_2_complete', required: 1 }, icon: '⏰', secret: true }, { id: 'mirror_world', name: 'Mirror World Portal', zone: 'Reversed Reality', location: { x: 500, y: 500 }, // Far corner activationQuest: { name: 'Shatter Reality', objective: 'Break the Mirror of Truth', item: 'mirror_of_truth', required: 1 }, icon: 'πŸͺž', secret: true } ]; portals.forEach(portal => { this.portals.set(portal.id, portal); }); console.log(`βœ… Registered ${this.portals.size} portals (${portals.filter(p => p.secret).length} secret)`); } /** * 15.1 - Activate portal */ activatePortal(portalId) { const portal = this.portals.get(portalId); if (!portal) { console.error(`Portal ${portalId} not found!`); return false; } if (this.activePortals.has(portalId)) { console.log(`Portal ${portal.name} already active!`); return false; } // Check activation quest completion // TODO: Integrate with quest system // For now, just activate this.activePortals.add(portalId); console.log(`πŸŒ€ ${portal.icon} ${portal.name} ACTIVATED!`); // Play activation animation this.playPortalActivationAnimation(portal); this.showNotification({ title: 'Portal Activated!', text: `πŸŒ€ ${portal.icon} ${portal.name} is now online!`, icon: '✨' }); return true; } /** * 15.2 - Portal activation animation */ playPortalActivationAnimation(portal) { // TODO: Create actual portal sprite/animation console.log(`✨ Portal activation animation for ${portal.name}`); // Screen flash this.scene.cameras.main.flash(1000, 100, 0, 255); // Blue flash // Camera shake this.scene.cameras.main.shake(500, 0.01); } /** * 15.2 - Travel through portal */ travelThroughPortal(portalId, fromHub = false) { const portal = this.portals.get(portalId); if (!portal) { console.error(`Portal ${portalId} not found!`); return false; } if (!this.activePortals.has(portalId) && !fromHub) { this.showNotification({ title: 'Portal Inactive', text: `${portal.name} must be activated first!`, icon: '🚫' }); return false; } // Check payment if using hub if (fromHub) { const cost = this.calculatePortalCost(portal); if (this.zlatnikiBalance < cost) { this.showNotification({ title: 'Insufficient Funds', text: `Need ${cost} Zlatniki for portal travel!`, icon: 'πŸ’°' }); return false; } this.zlatnikiBalance -= cost; } // Start transit this.isInTransit = true; // Swirl effect this.playPortalSwirlEffect(); // Loading screen (2 seconds) setTimeout(() => { this.completePortalTravel(portal); }, 2000); return true; } /** * 15.2 - Portal swirl effect */ playPortalSwirlEffect() { console.log('πŸŒ€ *SWIIIIIRL*'); // Create swirl particles // TODO: Implement actual particle effect // Screen spin effect this.scene.cameras.main.rotateTo(Math.PI * 4, true, 2000); // Fade out/in this.scene.cameras.main.fadeOut(1000); setTimeout(() => { this.scene.cameras.main.fadeIn(1000); }, 1000); } /** * 15.2 - Complete portal travel */ completePortalTravel(portal) { // Teleport player if (this.scene.player) { this.scene.player.x = portal.location.x * 48; this.scene.player.y = portal.location.y * 48; } // Transit zombies this.transitZombies(portal); // Apply nausea debuff (unless stabilizer) if (!this.hasStabilizer) { this.applyNauseaDebuff(); } this.isInTransit = false; console.log(`πŸŒ€ Arrived at ${portal.zone}!`); this.showNotification({ title: 'Portal Travel Complete', text: `${portal.icon} Welcome to ${portal.zone}!`, icon: 'πŸŒ€' }); } /** * 15.2 - Transit zombies through portal */ transitZombies(portal) { // TODO: Move all tamed zombies to portal location console.log('🧟 Zombies followed through portal!'); } /** * 15.2 - Apply nausea debuff */ applyNauseaDebuff() { this.nauseaDebuff = { duration: 5000, // 5 seconds startTime: Date.now() }; // Visual effect (screen wobble) // TODO: Implement screen wobble console.log('🀒 Nausea debuff applied (5s)'); this.showNotification({ title: 'Portal Sickness', text: '🀒 You feel dizzy from portal travel...', icon: '😡' }); // Remove after duration setTimeout(() => { this.nauseaDebuff = null; console.log('βœ… Nausea debuff removed'); }, 5000); } /** * 15.3 - Open town portal hub */ openPortalHub() { if (!this.hubUnlocked) { this.showNotification({ title: 'Hub Locked', text: 'Build the Portal Hub building first! (After Town Hall)', icon: 'πŸ›οΈ' }); return false; } // Show portal hub UI this.showPortalHubUI(); return true; } /** * 15.3 - Portal hub UI */ showPortalHubUI() { console.log('πŸŒ€ Portal Hub UI opened'); // TODO: Create actual UI // For now, list active portals console.log('Available Portals:'); this.activePortals.forEach(portalId => { const portal = this.portals.get(portalId); if (portal && !portal.noPortal) { const cost = this.calculatePortalCost(portal); console.log(`- ${portal.icon} ${portal.name} (${cost}Ε½)`); } }); } /** * 15.3 - Calculate portal cost */ calculatePortalCost(portal) { let cost = 5; // Base: 5 Zlatniki // Add zombie transit cost (1Ε½ per zombie) const zombieCount = this.scene.zombieSystem?.workers?.length || 0; cost += zombieCount; // Add animal transit cost (2Ε½ per animal) const animalCount = this.scene.animalBreeding?.animals?.size || 0; cost += animalCount * 2; return cost; } /** * 15.5 - Install portal stabilizer */ installStabilizer() { // TODO: Check if player has stabilizer item this.hasStabilizer = true; console.log('βœ… Portal Stabilizer installed!'); this.showNotification({ title: 'Stabilizer Installed', text: '✨ Portal travel no longer causes nausea!', icon: 'πŸ”§' }); } /** * 15.5 - Install portal beacon */ installBeacon() { // TODO: Check if player has beacon item this.hasBeacon = true; console.log('βœ… Portal Beacon installed!'); this.showNotification({ title: 'Beacon Installed', text: 'πŸ’‘ Portals now glow brighter and are easier to find!', icon: 'πŸ”¦' }); } /** * Unlock portal hub */ unlockHub() { this.hubUnlocked = true; this.showNotification({ title: 'Portal Hub Unlocked!', text: 'πŸ›οΈ Fast travel to all active portals!', icon: 'πŸŒ€' }); } /** * Get portal info */ getPortalInfo(portalId) { return this.portals.get(portalId); } /** * Get all active portals */ getActivePortals() { return Array.from(this.activePortals).map(id => this.portals.get(id)); } /** * Get all portals */ getAllPortals() { return Array.from(this.portals.values()); } /** * Check if portal active */ isPortalActive(portalId) { return this.activePortals.has(portalId); } /** * Get secret portals */ getSecretPortals() { return this.getAllPortals().filter(p => p.secret); } /** * Add zlatniki */ addZlatniki(amount) { this.zlatnikiBalance += amount; } /** * Helper: Show notification */ showNotification(notification) { console.log(`πŸ“’ ${notification.icon} ${notification.title}: ${notification.text}`); const ui = this.scene.scene.get('UIScene'); if (ui && ui.showNotification) { ui.showNotification(notification); } } /** * Update system */ update(delta) { // Update nausea debuff visual effects if active if (this.nauseaDebuff) { // TODO: Apply screen wobble effect } } }