class WeatherSystem { constructor(scene) { this.scene = scene; // --- Time Configuration --- this.fullDaySeconds = 300; // 5 minutes = 24 game hours this.gameTime = 8; // Start at 8:00 this.dayCount = 1; // --- Weather Configuration --- this.currentWeather = 'clear'; this.weatherDuration = 0; this.maxWeatherDuration = 10000; // Random duration logic handles this this.rainEmitter = null; // Replaced manual Array with Emitter // --- SEASONS Configuration --- this.seasons = ['spring', 'summer', 'autumn', 'winter']; // Pomlad, Poletje, Jesen, Zima this.currentSeason = 'spring'; this.daysPerSeason = 7; // Vsak letni ฤas traja 7 dni // --- TEMPERATURE System --- this.baseTemp = 20; // Celsius this.currentTemp = 20; this.tempCheckTimer = 0; this.tempDamageInterval = 5000; // Damage every 5 seconds // --- State --- this.currentPhase = 'day'; this.init(); } init() { // Start weather cycle this.changeWeather(); } getOverlay() { const uiScene = this.scene.scene.get('UIScene'); if (uiScene && uiScene.overlayGraphics) { return uiScene.overlayGraphics; } return null; } update(delta) { // 1. Update Time this.updateTime(delta); // 2. Update Weather Logic (Durations, Changes) this.updateWeatherLogic(delta); // 2.5. Update Temperature System this.updateTemperature(delta); // 3. Update Physics (Rain drops) this.updateWeatherPhysics(delta); // 4. Render Atmosphere (Time + Weather) this.render(); } updateTime(delta) { const seconds = delta / 1000; const gameHoursPerRealSecond = 24 / this.fullDaySeconds; this.gameTime += seconds * gameHoursPerRealSecond; if (this.gameTime >= 24) { this.gameTime -= 24; this.dayCount++; console.log(`๐ŸŒž Day ${this.dayCount} started!`); // Check for Season Change this.checkSeasonChange(); } // Update Phase const phase = this.getPhase(this.gameTime); if (phase !== this.currentPhase) { this.currentPhase = phase; console.log(`๐ŸŒ… Time of Day: ${phase} (${Math.floor(this.gameTime)}:00)`); // Trigger Bat Swarm at Dusk if (phase === 'dusk' && this.scene.worldEventSystem) { this.scene.worldEventSystem.spawnBatSwarm(); } } // Trigger Night Owl at Midnight (00:00) // We check if seconds crossed 0. if (Math.abs(this.gameTime - 0.0) < 0.05) { // Only trigger once per night - check active flag or similar? // Actually, gameTime will pass 0 very quickly but maybe multiple frames. // We can use a flag resetting at day. if (!this.owlTriggered && this.scene.worldEventSystem) { this.scene.worldEventSystem.spawnNightOwl(); this.owlTriggered = true; } } if (this.gameTime > 5) this.owlTriggered = false; // Reset flag at dawn // Update UI Clock const uiScene = this.scene.scene.get('UIScene'); if (uiScene && uiScene.clockText) { const hours = Math.floor(this.gameTime); const minutes = Math.floor((this.gameTime - hours) * 60); const timeString = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`; const seasonIcons = { spring: '๐ŸŒธ', summer: 'โ˜€๏ธ', autumn: '๐Ÿ‚', winter: 'โ„๏ธ' }; const seasonIcon = seasonIcons[this.currentSeason] || ''; uiScene.clockText.setText(`${seasonIcon} Day ${this.dayCount} - ${timeString}`); } } getPhase(hour) { if (hour >= 5 && hour < 7) return 'dawn'; if (hour >= 7 && hour < 18) return 'day'; if (hour >= 18 && hour < 20) return 'dusk'; return 'night'; } updateWeatherLogic(delta) { this.weatherDuration += delta; if (this.weatherDuration > this.maxWeatherDuration) { this.changeWeather(); } } updateWeatherPhysics(delta) { // Optimisation: Physics now handled by Phaser Particles } render() { const overlay = this.getOverlay(); if (!overlay) return; // IMPORTANT: Clear previous frame to avoid buildup overlay.clear(); const width = this.scene.scale.width; const height = this.scene.scale.height; // --- LAYER 1: Day/Night Cycle --- this.renderDayNight(overlay, width, height); // --- LAYER 2: Weather Effects (Fog, Rain darkness) --- this.renderWeatherEffects(overlay, width, height); // --- LAYER 3: Season Tint --- this.renderSeasonOverlay(overlay, width, height); } renderDayNight(overlay, width, height) { const hour = this.gameTime; let color = 0x000033; // Default night let alpha = 0; if (hour >= 0 && hour < 5) { // Deep Night color = 0x000033; alpha = 0.6; } else if (hour >= 5 && hour < 7) { // Dawn color = 0xFF6B35; const progress = (hour - 5) / 2; alpha = 0.6 - (progress * 0.6); } else if (hour >= 7 && hour < 18) { // Day alpha = 0; } else if (hour >= 18 && hour < 20) { // Dusk color = 0x8B4789; const progress = (hour - 18) / 2; alpha = progress * 0.5; } else if (hour >= 20 && hour < 24) { // Night color = 0x000033; const progress = (hour - 20) / 4; alpha = 0.5 + (progress * 0.1); } if (alpha > 0) { overlay.fillStyle(color, alpha); overlay.fillRect(0, 0, width, height); } } renderWeatherEffects(overlay, width, height) { // Fog if (this.currentWeather === 'fog') { overlay.fillStyle(0xcccccc, 0.4); overlay.fillRect(0, 0, width, height); } // Rain / Storm if (this.currentWeather === 'rain' || this.currentWeather === 'storm') { const isDark = this.currentWeather === 'storm' ? 0.3 : 0.2; // Additive darkness for storm overlay.fillStyle(0x000033, isDark); overlay.fillRect(0, 0, width, height); // Rain drops are now particles (separate GameObject) } } changeWeather() { this.clearWeather(); const rand = Math.random(); if (rand < 0.6) { this.currentWeather = 'clear'; this.maxWeatherDuration = Phaser.Math.Between(10000, 30000); } else if (rand < 0.8) { this.currentWeather = 'rain'; this.startRain(false); this.maxWeatherDuration = Phaser.Math.Between(10000, 20000); } else if (rand < 0.9) { this.currentWeather = 'storm'; this.startRain(true); this.maxWeatherDuration = Phaser.Math.Between(8000, 15000); } else { this.currentWeather = 'fog'; this.maxWeatherDuration = Phaser.Math.Between(10000, 20000); } this.weatherDuration = 0; console.log(`Weather changed to: ${this.currentWeather}`); } startRain(heavy) { const uiScene = this.scene.scene.get('UIScene'); if (!uiScene) return; // Check Settings const quality = this.scene.settings ? this.scene.settings.particles : 'HIGH'; if (quality === 'NONE') return; // Ensure texture exists if (!this.scene.textures.exists('rain_drop')) { const graphics = this.scene.make.graphics({ x: 0, y: 0, add: false }); graphics.fillStyle(0x88aaff, 1); graphics.fillRect(0, 0, 2, 8); graphics.generateTexture('rain_drop', 2, 8); graphics.destroy(); } // Clean up old if (this.rainEmitter) { this.rainEmitter.destroy(); } const width = this.scene.scale.width; let pQuantity = heavy ? 5 : 2; let pFreq = heavy ? 10 : 30; if (quality === 'LOW') { pQuantity = heavy ? 2 : 1; pFreq = heavy ? 50 : 100; } // Use modern particles or fallback // Helper to support both if needed, but standard 3.60+ is: this.rainEmitter = uiScene.add.particles(0, 0, 'rain_drop', { x: { min: 0, max: width }, y: -20, quantity: pQuantity, frequency: pFreq, // Emit every X ms lifespan: 1500, speedY: { min: heavy ? 600 : 400, max: heavy ? 900 : 600 }, speedX: { min: -50, max: 0 }, // Slight wind scaleY: { min: 1.0, max: 2.0 }, alpha: { start: 0.6, end: 0 }, emitting: true }); // Depth just above overlay (-1000) this.rainEmitter.setDepth(-990); // Play Sound if (this.scene.soundManager) { this.scene.soundManager.playRainSound(); } } clearWeather() { if (this.rainEmitter) { this.rainEmitter.destroy(); this.rainEmitter = null; } // Stop Sound if (this.scene.soundManager) { this.scene.soundManager.stopRainSound(); } } // --- Getters for Other Systems --- getCurrentHour() { return Math.floor(this.gameTime); } getDayCount() { return this.dayCount; } isNight() { const hour = this.gameTime; return hour >= 20 || hour < 5; } isDay() { const hour = this.gameTime; return hour >= 7 && hour < 18; } isHordeNight() { // Every 3rd night is a Horde Night return this.dayCount > 0 && this.dayCount % 3 === 0; } checkSeasonChange() { const seasonIndex = Math.floor((this.dayCount - 1) / this.daysPerSeason) % 4; const newSeason = this.seasons[seasonIndex]; if (newSeason !== this.currentSeason) { this.currentSeason = newSeason; const seasonNames = { spring: '๐ŸŒธ Pomlad', summer: 'โ˜€๏ธ Poletje', autumn: '๐Ÿ‚ Jesen', winter: 'โ„๏ธ Zima' }; console.log(`๐ŸŒ Letni ฤas: ${seasonNames[newSeason]}`); } } getSeason() { return this.currentSeason; } getSeasonColor() { // Barve/overlay za letne ฤase const colors = { spring: { color: 0x90EE90, alpha: 0.1 }, // Svetlo zelena summer: { color: 0xFFFF00, alpha: 0.05 }, // Rumena autumn: { color: 0xFF8C00, alpha: 0.15 }, // Oranลพna winter: { color: 0xE0F7FF, alpha: 0.25 } // Belo modra }; return colors[this.currentSeason] || { color: 0xFFFFFF, alpha: 0 }; } renderSeasonOverlay(overlay, width, height) { const seasonData = this.getSeasonColor(); if (seasonData.alpha > 0) { overlay.fillStyle(seasonData.color, seasonData.alpha); overlay.fillRect(0, 0, width, height); } } }