/** * PortalRepairSystem.js * ====================== * KRVAVA Ε½ETEV - Portal Repair & Construction (Phase 20) * * Features: * - 18 portal locations across biomes * - Repair mechanics with materials * - 1-8 day construction time * - Defend from attacks during repair * - Lv8+ zombie builders (independent work!) * - Portal network benefits * - Portable Personal Portal (endgame!) * * @author NovaFarma Team * @date 2025-12-23 */ class PortalRepairSystem { constructor(scene) { this.scene = scene; // Portal registry this.portals = new Map(); // Repair progress this.activeRepairs = new Map(); // Network status this.networkActive = false; this.portalsRepaired = 0; this.totalPortals = 18; // Personal portal (endgame unlock) this.hasPersonalPortal = false; console.log('πŸŒ€ PortalRepairSystem initialized'); // Register all portals this.registerPortals(); } /** * Register all 18 portals */ registerPortals() { const portals = [ // Tier 1 - Easy (1-2 days) { id: 'grassland_portal', name: 'Grassland Portal', biome: 'grassland', materials: { stone: 100, crystal: 10 }, days: 1, difficulty: 'easy' }, { id: 'forest_portal', name: 'Forest Portal', biome: 'forest', materials: { wood: 200, crystal: 15 }, days: 2, difficulty: 'easy' }, // Tier 2 - Medium (3-4 days) { id: 'desert_portal', name: 'Desert Portal', biome: 'desert', materials: { sandstone: 300, crystal: 20, gold: 10 }, days: 3, difficulty: 'medium' }, { id: 'swamp_portal', name: 'Swamp Portal', biome: 'swamp', materials: { clay: 250, crystal: 25 }, days: 3, difficulty: 'medium' }, { id: 'beach_portal', name: 'Beach Portal', biome: 'beach', materials: { coral: 200, crystal: 20, pearl: 5 }, days: 3, difficulty: 'medium' }, { id: 'mountain_portal', name: 'Mountain Portal', biome: 'mountain', materials: { stone: 400, iron: 50, crystal: 30 }, days: 4, difficulty: 'medium' }, // Tier 3 - Hard (5-6 days) { id: 'frozen_portal', name: 'Frozen Portal', biome: 'frozen', materials: { ice: 500, crystal: 40, diamond: 5 }, days: 5, difficulty: 'hard' }, { id: 'volcanic_portal', name: 'Volcanic Portal', biome: 'volcanic', materials: { obsidian: 400, crystal: 50, ruby: 10 }, days: 5, difficulty: 'hard' }, { id: 'wasteland_portal', name: 'Wasteland Portal', biome: 'wasteland', materials: { scrap: 600, uranium: 20, crystal: 60 }, days: 6, difficulty: 'hard' }, { id: 'jungle_portal', name: 'Jungle Portal', biome: 'jungle', materials: { vine: 300, emerald: 15, crystal: 45 }, days: 5, difficulty: 'hard' }, // Tier 4 - Very Hard (7-8 days) { id: 'egypt_portal', name: 'Egypt Portal', biome: 'egypt', materials: { sandstone: 800, gold: 100, crystal: 80 }, days: 7, difficulty: 'very_hard' }, { id: 'atlantis_portal', name: 'Atlantis Portal', biome: 'underwater', materials: { orichalcum: 200, pearl: 50, crystal: 100 }, days: 8, difficulty: 'very_hard' }, { id: 'lochness_portal', name: 'Loch Ness Portal', biome: 'lochness', materials: { stone: 1000, emerald: 20, crystal: 90 }, days: 7, difficulty: 'very_hard' }, { id: 'chernobyl_portal', name: 'Chernobyl Portal', biome: 'chernobyl', materials: { concrete: 900, uranium: 50, crystal: 100 }, days: 8, difficulty: 'very_hard' }, { id: 'amazon_portal', name: 'Amazon Portal', biome: 'amazon', materials: { wood: 1000, vine: 500, crystal: 85 }, days: 7, difficulty: 'very_hard' }, // Tier 5 - Legendary (8 days) { id: 'mythical_portal', name: 'Mythical Realm Portal', biome: 'mythical', materials: { mythril: 100, dragon_scale: 20, crystal: 150 }, days: 8, difficulty: 'legendary' }, { id: 'anomaly_portal', name: 'Anomalous Zone Portal', biome: 'anomaly', materials: { artifact: 50, uranium: 100, crystal: 200 }, days: 8, difficulty: 'legendary' }, { id: 'void_portal', name: 'The Void Portal', biome: 'void', materials: { void_essence: 10, cosmic_dust: 50, crystal: 250 }, days: 8, difficulty: 'legendary' } ]; portals.forEach(portal => { this.portals.set(portal.id, { ...portal, isRepaired: false, repairProgress: 0, isUnderAttack: false, questCompleted: false }); }); console.log(`βœ… Registered ${this.portals.size} portals`); } /** * Start portal repair */ startRepair(portalId, zombieBuilders = []) { const portal = this.portals.get(portalId); if (!portal) { console.error(`Portal ${portalId} not found!`); return false; } if (portal.isRepaired) { console.log(`${portal.name} is already repaired!`); return false; } // Check if quest is completed if (!portal.questCompleted) { console.log(`Complete the ${portal.name} quest first!`); return false; } // Check materials if (!this.hasMaterials(portal.materials)) { console.log(`Not enough materials for ${portal.name}!`); return false; } // Consume materials this.consumeMaterials(portal.materials); // Calculate repair time (zombie builders reduce time) const builderBonus = this.calculateBuilderBonus(zombieBuilders); const repairTime = portal.days * (1 - builderBonus); // Start repair const repair = { portalId: portalId, startTime: Date.now(), duration: repairTime * 24 * 60 * 60 * 1000, // Days to ms builders: zombieBuilders, defendPhase: false }; this.activeRepairs.set(portalId, repair); portal.repairProgress = 0; console.log(`πŸŒ€ Started repairing ${portal.name} (${repairTime} days with ${zombieBuilders.length} workers)`); // Start defend events this.scheduleDefendEvents(portalId, repairTime); this.showNotification({ title: 'Portal Repair Started!', text: `πŸŒ€ ${portal.name} - ${repairTime.toFixed(1)} days`, icon: 'πŸ”¨' }); return true; } /** * Calculate builder bonus */ calculateBuilderBonus(builders) { if (builders.length === 0) return 0; let bonus = 0; builders.forEach(builder => { // Lv8+ zombies are 50% faster if (builder.level >= 8) { bonus += 0.15; // 15% per Lv8+ zombie } else { bonus += 0.05; // 5% per lower level zombie } }); return Math.min(bonus, 0.6); // Max 60% reduction } /** * Schedule defend events */ scheduleDefendEvents(portalId, repairDays) { const portal = this.portals.get(portalId); // Attack waves based on difficulty const attackCount = { easy: 1, medium: 2, hard: 3, very_hard: 4, legendary: 5 }[portal.difficulty] || 2; // Schedule attacks at intervals for (let i = 0; i < attackCount; i++) { const attackTime = (repairDays / attackCount) * (i + 0.5); setTimeout(() => { this.triggerAttack(portalId); }, attackTime * 24 * 60 * 60 * 1000); } } /** * Trigger attack on portal */ triggerAttack(portalId) { const portal = this.portals.get(portalId); const repair = this.activeRepairs.get(portalId); if (!repair) return; portal.isUnderAttack = true; repair.defendPhase = true; console.log(`βš”οΈ ${portal.name} is under attack!`); this.showNotification({ title: 'PORTAL UNDER ATTACK!', text: `βš”οΈ Defend ${portal.name}!`, icon: '⚠️' }); // TODO: Spawn enemies // Attack ends after 5 minutes or all enemies defeated setTimeout(() => { portal.isUnderAttack = false; repair.defendPhase = false; console.log(`βœ… ${portal.name} defended successfully!`); }, 5 * 60 * 1000); } /** * Complete portal repair */ completeRepair(portalId) { const portal = this.portals.get(portalId); if (!portal) return; portal.isRepaired = true; portal.repairProgress = 100; this.portalsRepaired++; this.activeRepairs.delete(portalId); console.log(`βœ… ${portal.name} repaired! (${this.portalsRepaired}/${this.totalPortals})`); // Activate portal network if this is the first portal if (this.portalsRepaired === 1) { this.activateNetwork(); } // Check for personal portal unlock if (this.portalsRepaired === this.totalPortals) { this.unlockPersonalPortal(); } this.showNotification({ title: 'Portal Complete!', text: `βœ… ${portal.name} is now operational!`, icon: 'πŸŒ€' }); } /** * Activate portal network */ activateNetwork() { this.networkActive = true; console.log('🌐 Portal Network activated!'); this.showNotification({ title: 'PORTAL NETWORK ONLINE!', text: '🌐 Fast travel between portals unlocked!', icon: '✨' }); } /** * Unlock personal portal */ unlockPersonalPortal() { this.hasPersonalPortal = true; console.log('πŸ‘‘ PERSONAL PORTAL UNLOCKED!'); this.showNotification({ title: 'PERSONAL PORTAL!', text: 'πŸ‘‘ Portable portal unlocked! Teleport anywhere!', icon: '🎊' }); } /** * Use portal (teleport) */ usePortal(fromPortalId, toPortalId) { if (!this.networkActive) { console.log('Portal network is not active yet!'); return false; } const from = this.portals.get(fromPortalId); const to = this.portals.get(toPortalId); if (!from || !to) { console.error('Portal not found!'); return false; } if (!from.isRepaired || !to.isRepaired) { console.log('Both portals must be repaired!'); return false; } console.log(`πŸŒ€ Teleporting from ${from.name} to ${to.name}!`); // Instant teleport // TODO: Actual player teleport // TODO: Can bring zombies for FREE (network benefit) this.showNotification({ title: 'Teleported!', text: `πŸŒ€ Arrived at ${to.name}`, icon: '✨' }); return true; } /** * Check if Lv8+ zombie can work independently */ canWorkIndependently(zombie) { return zombie.level >= 8; } /** * Send Lv8+ zombie to repair portal alone */ sendIndependentBuilder(portalId, zombie) { if (!this.canWorkIndependently(zombie)) { console.log(`${zombie.name} must be Lv8+ to work alone!`); return false; } console.log(`πŸ€– Sending ${zombie.name} (Lv${zombie.level}) to repair ${portalId} independently!`); // Zombie travels, gathers materials, repairs portal autonomously! this.startRepair(portalId, [zombie]); this.showNotification({ title: 'Independent Builder!', text: `πŸ€– ${zombie.name} will repair portal alone!`, icon: '✨' }); return true; } /** * Check materials */ hasMaterials(required) { // TODO: Check actual inventory return true; // For now } /** * Consume materials */ consumeMaterials(materials) { // TODO: Remove from inventory console.log('πŸ“¦ Materials consumed:', materials); } /** * Get repair progress */ getProgress() { return { repaired: this.portalsRepaired, total: this.totalPortals, percentage: ((this.portalsRepaired / this.totalPortals) * 100).toFixed(1), networkActive: this.networkActive, hasPersonalPortal: this.hasPersonalPortal }; } /** * Get portal info */ getPortalInfo(portalId) { return this.portals.get(portalId); } /** * Get all portals */ getAllPortals() { return Array.from(this.portals.values()); } /** * Update repair progress (called from game loop) */ update(delta) { this.activeRepairs.forEach((repair, portalId) => { const elapsed = Date.now() - repair.startTime; const progress = (elapsed / repair.duration) * 100; const portal = this.portals.get(portalId); if (portal) { portal.repairProgress = Math.min(100, progress); } // Check completion if (progress >= 100) { this.completeRepair(portalId); } }); } /** * 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); } } }