Improved readability of weather and date managers
This commit is contained in:
@ -1,10 +1,10 @@
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
import worldRepository from '#repositories/worldRepository'
|
||||
import worldService from '#services/worldService'
|
||||
import SocketManager from '#managers/socketManager'
|
||||
|
||||
interface WeatherState {
|
||||
type WeatherState = {
|
||||
isRainEnabled: boolean
|
||||
rainPercentage: number
|
||||
isFogEnabled: boolean
|
||||
@ -12,13 +12,18 @@ interface WeatherState {
|
||||
}
|
||||
|
||||
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 readonly logger = Logger.type(LoggerType.APP)
|
||||
private static readonly CONFIG = {
|
||||
UPDATE_INTERVAL_MS: 60_000, // Check weather every minute
|
||||
RAIN_CHANCE: 0.2, // 20% chance
|
||||
FOG_CHANCE: 0.15, // 15% chance
|
||||
RAIN_PERCENTAGE_RANGE: { min: 50, max: 100 },
|
||||
FOG_DENSITY_RANGE: { min: 30, max: 100 }
|
||||
} as const
|
||||
|
||||
private readonly logger = Logger.type(LoggerType.APP)
|
||||
private io: Server | null = null
|
||||
private intervalId: NodeJS.Timeout | null = null
|
||||
|
||||
private weatherState: WeatherState = {
|
||||
isRainEnabled: false,
|
||||
rainPercentage: 0,
|
||||
@ -26,37 +31,34 @@ class WeatherManager {
|
||||
fogDensity: 0
|
||||
}
|
||||
|
||||
public async boot(io: Server): Promise<void> {
|
||||
// this.io = io
|
||||
// await this.loadWeather()
|
||||
// this.startWeatherLoop()
|
||||
public async boot(): Promise<void> {
|
||||
this.io = SocketManager.getIO()
|
||||
await this.loadWeather()
|
||||
this.startWeatherLoop()
|
||||
this.logger.info('Weather manager loaded')
|
||||
}
|
||||
|
||||
public async toggleRain(): Promise<void> {
|
||||
this.weatherState.isRainEnabled = !this.weatherState.isRainEnabled
|
||||
this.weatherState.rainPercentage = this.weatherState.isRainEnabled
|
||||
? Math.floor(Math.random() * 50) + 50 // 50-100%
|
||||
: 0
|
||||
public getWeatherState(): WeatherState {
|
||||
return { ...this.weatherState }
|
||||
}
|
||||
|
||||
await this.saveWeather()
|
||||
this.emitWeather()
|
||||
public async toggleRain(): Promise<void> {
|
||||
this.updateWeatherProperty('rain')
|
||||
await this.saveAndEmitWeather()
|
||||
}
|
||||
|
||||
public async toggleFog(): Promise<void> {
|
||||
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
|
||||
this.updateWeatherProperty('fog')
|
||||
await this.saveAndEmitWeather()
|
||||
}
|
||||
|
||||
await this.saveWeather()
|
||||
this.emitWeather()
|
||||
public cleanup(): void {
|
||||
this.intervalId && clearInterval(this.intervalId)
|
||||
}
|
||||
|
||||
private async loadWeather(): Promise<void> {
|
||||
try {
|
||||
const world = await worldRepository.getFirst()
|
||||
|
||||
if (world) {
|
||||
this.weatherState = {
|
||||
isRainEnabled: world.isRainEnabled,
|
||||
@ -66,64 +68,74 @@ class WeatherManager {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to load weather: ${error instanceof Error ? error.message : String(error)}`)
|
||||
this.logError('load', error)
|
||||
}
|
||||
}
|
||||
|
||||
public getWeatherState(): WeatherState {
|
||||
return this.weatherState
|
||||
}
|
||||
|
||||
private startWeatherLoop(): void {
|
||||
this.intervalId = setInterval(async () => {
|
||||
this.updateWeather()
|
||||
this.emitWeather()
|
||||
await this.saveWeather().catch((error) => {
|
||||
this.logger.error(`Failed to save weather: ${error instanceof Error ? error.message : String(error)}`)
|
||||
})
|
||||
}, WeatherManager.UPDATE_INTERVAL)
|
||||
this.updateRandomWeather()
|
||||
await this.saveAndEmitWeather()
|
||||
}, WeatherManager.CONFIG.UPDATE_INTERVAL_MS)
|
||||
}
|
||||
|
||||
private updateWeather(): void {
|
||||
// Update rain
|
||||
if (Math.random() < WeatherManager.RAIN_CHANCE) {
|
||||
private updateRandomWeather(): void {
|
||||
if (Math.random() < WeatherManager.CONFIG.RAIN_CHANCE) {
|
||||
this.updateWeatherProperty('rain')
|
||||
}
|
||||
if (Math.random() < WeatherManager.CONFIG.FOG_CHANCE) {
|
||||
this.updateWeatherProperty('fog')
|
||||
}
|
||||
}
|
||||
|
||||
private updateWeatherProperty(type: 'rain' | 'fog'): void {
|
||||
if (type === 'rain') {
|
||||
this.weatherState.isRainEnabled = !this.weatherState.isRainEnabled
|
||||
this.weatherState.rainPercentage = this.weatherState.isRainEnabled
|
||||
? Math.floor(Math.random() * 50) + 50 // 50-100%
|
||||
? this.getRandomNumber(
|
||||
WeatherManager.CONFIG.RAIN_PERCENTAGE_RANGE.min,
|
||||
WeatherManager.CONFIG.RAIN_PERCENTAGE_RANGE.max
|
||||
)
|
||||
: 0
|
||||
}
|
||||
|
||||
// Update fog
|
||||
if (Math.random() < WeatherManager.FOG_CHANCE) {
|
||||
if (type === 'fog') {
|
||||
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
|
||||
? this.getRandomNumber(
|
||||
WeatherManager.CONFIG.FOG_DENSITY_RANGE.min,
|
||||
WeatherManager.CONFIG.FOG_DENSITY_RANGE.max
|
||||
)
|
||||
: 0
|
||||
}
|
||||
}
|
||||
|
||||
private async saveAndEmitWeather(): Promise<void> {
|
||||
await this.saveWeather()
|
||||
this.emitWeather()
|
||||
}
|
||||
|
||||
private emitWeather(): void {
|
||||
this.io?.emit('weather', this.weatherState)
|
||||
}
|
||||
|
||||
private async saveWeather(): Promise<void> {
|
||||
try {
|
||||
await worldService.update({
|
||||
isRainEnabled: this.weatherState.isRainEnabled,
|
||||
rainPercentage: this.weatherState.rainPercentage,
|
||||
isFogEnabled: this.weatherState.isFogEnabled,
|
||||
fogDensity: this.weatherState.fogDensity
|
||||
})
|
||||
await worldService.update(this.weatherState)
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to save weather: ${error instanceof Error ? error.message : String(error)}`)
|
||||
this.logError('save', error)
|
||||
}
|
||||
}
|
||||
|
||||
public cleanup(): void {
|
||||
if (this.intervalId) {
|
||||
clearInterval(this.intervalId)
|
||||
}
|
||||
private getRandomNumber(min: number, max: number): number {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min
|
||||
}
|
||||
|
||||
private logError(operation: string, error: unknown): void {
|
||||
this.logger.error(
|
||||
`Failed to ${operation} weather: ${error instanceof Error ? error.message : String(error)}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default new WeatherManager()
|
||||
export default new WeatherManager()
|
Reference in New Issue
Block a user