import { Server } from 'socket.io' import { appLogger } from '#application/logger' import worldService from '#services/worldService' import worldRepository from '#repositories/worldRepository' interface WeatherState { isRainEnabled: boolean rainPercentage: number isFogEnabled: boolean fogDensity: number } class WeatherManager { private static readonly UPDATE_INTERVAL = 60000 // Check weather every minute private static readonly RAIN_CHANCE = 0.2 // 20% chance of rain private static readonly FOG_CHANCE = 0.15 // 15% chance of fog private io: Server | null = null private intervalId: NodeJS.Timeout | null = null private weatherState: WeatherState = { isRainEnabled: false, rainPercentage: 0, isFogEnabled: false, fogDensity: 0 } public async boot(io: Server): Promise { // this.io = io // await this.loadWeather() // this.startWeatherLoop() appLogger.info('Weather manager loaded') } public async toggleRain(): Promise { this.weatherState.isRainEnabled = !this.weatherState.isRainEnabled this.weatherState.rainPercentage = this.weatherState.isRainEnabled ? Math.floor(Math.random() * 50) + 50 // 50-100% : 0 await this.saveWeather() this.emitWeather() } public async toggleFog(): Promise { this.weatherState.isFogEnabled = !this.weatherState.isFogEnabled this.weatherState.fogDensity = this.weatherState.isFogEnabled ? Math.floor((Math.random() * 0.7 + 0.3) * 100) // Convert 0.3-1.0 to 30-100 : 0 await this.saveWeather() this.emitWeather() } private async loadWeather(): Promise { try { const world = await worldRepository.getFirst() if (world) { this.weatherState = { isRainEnabled: world.isRainEnabled, rainPercentage: world.rainPercentage, isFogEnabled: world.isFogEnabled, fogDensity: world.fogDensity } } } catch (error) { appLogger.error(`Failed to load weather: ${error instanceof Error ? error.message : String(error)}`) } } public getWeatherState(): WeatherState { return this.weatherState } private startWeatherLoop(): void { this.intervalId = setInterval(async () => { this.updateWeather() this.emitWeather() await this.saveWeather().catch((error) => { appLogger.error(`Failed to save weather: ${error instanceof Error ? error.message : String(error)}`) }) }, WeatherManager.UPDATE_INTERVAL) } private updateWeather(): void { // Update rain if (Math.random() < WeatherManager.RAIN_CHANCE) { this.weatherState.isRainEnabled = !this.weatherState.isRainEnabled this.weatherState.rainPercentage = this.weatherState.isRainEnabled ? Math.floor(Math.random() * 50) + 50 // 50-100% : 0 } // Update fog if (Math.random() < WeatherManager.FOG_CHANCE) { this.weatherState.isFogEnabled = !this.weatherState.isFogEnabled this.weatherState.fogDensity = this.weatherState.isFogEnabled ? Math.floor((Math.random() * 0.7 + 0.3) * 100) // Convert 0.3-1.0 to 30-100 : 0 } } private emitWeather(): void { this.io?.emit('weather', this.weatherState) } private async saveWeather(): Promise { try { await worldService.update({ isRainEnabled: this.weatherState.isRainEnabled, rainPercentage: this.weatherState.rainPercentage, isFogEnabled: this.weatherState.isFogEnabled, fogDensity: this.weatherState.fogDensity }) } catch (error) { appLogger.error(`Failed to save weather: ${error instanceof Error ? error.message : String(error)}`) } } public cleanup(): void { if (this.intervalId) { clearInterval(this.intervalId) } } } export default new WeatherManager()