2023-03-03 15:23:46 +00:00
import { inject , injectable } from "tsyringe" ;
2023-10-19 17:21:17 +00:00
import { ApplicationContext } from "@spt-aki/context/ApplicationContext" ;
import { ContextVariableType } from "@spt-aki/context/ContextVariableType" ;
import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper" ;
import { IWeather , IWeatherData } from "@spt-aki/models/eft/weather/IWeatherData" ;
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes" ;
import { WindDirection } from "@spt-aki/models/enums/WindDirection" ;
import { IWeatherConfig } from "@spt-aki/models/spt/config/IWeatherConfig" ;
import { ILogger } from "@spt-aki/models/spt/utils/ILogger" ;
import { ConfigServer } from "@spt-aki/servers/ConfigServer" ;
import { RandomUtil } from "@spt-aki/utils/RandomUtil" ;
import { TimeUtil } from "@spt-aki/utils/TimeUtil" ;
2023-03-03 15:23:46 +00:00
@injectable ( )
export class WeatherGenerator
{
protected weatherConfig : IWeatherConfig ;
constructor (
@inject ( "WeightedRandomHelper" ) protected weightedRandomHelper : WeightedRandomHelper ,
@inject ( "WinstonLogger" ) protected logger : ILogger ,
@inject ( "RandomUtil" ) protected randomUtil : RandomUtil ,
@inject ( "TimeUtil" ) protected timeUtil : TimeUtil ,
@inject ( "ApplicationContext" ) protected applicationContext : ApplicationContext ,
2023-11-15 20:35:05 -05:00
@inject ( "ConfigServer" ) protected configServer : ConfigServer ,
2023-03-03 15:23:46 +00:00
)
{
this . weatherConfig = this . configServer . getConfig ( ConfigTypes . WEATHER ) ;
}
2023-07-25 14:04:21 +01:00
/ * *
* Get current + raid datetime and format into correct BSG format and return
* @param data Weather data
* @returns IWeatherData
* /
2023-03-03 15:23:46 +00:00
public calculateGameTime ( data : IWeatherData ) : IWeatherData
{
const computedDate = new Date ( ) ;
const formattedDate = this . timeUtil . formatDate ( computedDate ) ;
data . date = formattedDate ;
data . time = this . getBsgFormattedInRaidTime ( computedDate ) ;
data . acceleration = this . weatherConfig . acceleration ;
2023-12-27 18:55:58 +00:00
data . winterEventEnabled = false ;
2023-03-03 15:23:46 +00:00
return data ;
}
/ * *
* Get server uptime seconds multiplied by a multiplier and add to current time as seconds
* Format to BSGs requirements
* @param currentDate current date
* @returns formatted time
* /
protected getBsgFormattedInRaidTime ( currentDate : Date ) : string
{
const clientAcceleratedDate = this . getInRaidTime ( currentDate ) ;
return this . getBSGFormattedTime ( clientAcceleratedDate ) ;
}
/ * *
* Get the current in - raid time
* @param currentDate ( new Date ( ) )
2023-11-15 20:35:05 -05:00
* @returns Date object of current in - raid time
2023-03-03 15:23:46 +00:00
* /
public getInRaidTime ( currentDate : Date ) : Date
{
// Get timestamp of when client conneted to server
2023-11-15 20:35:05 -05:00
const gameStartTimeStampMS = this . applicationContext . getLatestValue ( ContextVariableType . CLIENT_START_TIMESTAMP )
. getValue < number > ( ) ;
2023-03-03 15:23:46 +00:00
// Get delta between now and when client connected to server in milliseconds
2023-11-15 20:35:05 -05:00
const deltaMSFromNow = Date . now ( ) - gameStartTimeStampMS ;
const acceleratedMS = deltaMSFromNow * ( this . weatherConfig . acceleration - 1 ) ; // For some reason nodejs moves faster than client time, reducing acceleration by 1 when client is 7 helps
2023-03-03 15:23:46 +00:00
const clientAcceleratedDate = new Date ( currentDate . valueOf ( ) + acceleratedMS ) ;
return clientAcceleratedDate ;
}
/ * *
* Get current time formatted to fit BSGs requirement
* @param date date to format into bsg style
2023-07-25 14:04:21 +01:00
* @returns Time formatted in BSG format
2023-03-03 15:23:46 +00:00
* /
protected getBSGFormattedTime ( date : Date ) : string
{
return this . timeUtil . formatTime ( date ) . replace ( "-" , ":" ) . replace ( "-" , ":" ) ;
}
/ * *
* Return randomised Weather data with help of config / weather . json
* @returns Randomised weather data
* /
public generateWeather ( ) : IWeather
{
const rain = this . getWeightedRain ( ) ;
const result : IWeather = {
2023-10-10 11:03:20 +00:00
cloud : this.getWeightedClouds ( ) ,
2023-03-03 15:23:46 +00:00
wind_speed : this.getWeightedWindSpeed ( ) ,
wind_direction : this.getWeightedWindDirection ( ) ,
wind_gustiness : this.getRandomFloat ( "windGustiness" ) ,
rain : rain ,
2023-11-15 20:35:05 -05:00
rain_intensity : ( rain > 1 ) ? this . getRandomFloat ( "rainIntensity" ) : 0 ,
2023-03-03 15:23:46 +00:00
fog : this.getWeightedFog ( ) ,
temp : this.getRandomFloat ( "temp" ) ,
pressure : this.getRandomFloat ( "pressure" ) ,
time : "" ,
date : "" ,
2023-11-15 20:35:05 -05:00
timestamp : 0 ,
2023-03-03 15:23:46 +00:00
} ;
this . setCurrentDateTime ( result ) ;
return result ;
}
/ * *
* Set IWeather date / time / timestamp values to now
* @param weather Object to update
* /
protected setCurrentDateTime ( weather : IWeather ) : void
{
const currentDate = this . getInRaidTime ( new Date ( ) ) ;
const normalTime = this . getBSGFormattedTime ( currentDate ) ;
const formattedDate = this . timeUtil . formatDate ( currentDate ) ;
const datetime = ` ${ formattedDate } ${ normalTime } ` ;
weather . timestamp = Math . floor ( currentDate . getTime ( ) / 1000 ) ; // matches weather.date
weather . date = formattedDate ; // matches weather.timestamp
weather . time = datetime ; // matches weather.timestamp
}
protected getWeightedWindDirection ( ) : WindDirection
{
2023-11-15 20:35:05 -05:00
return this . weightedRandomHelper . weightedRandom (
this . weatherConfig . weather . windDirection . values ,
this . weatherConfig . weather . windDirection . weights ,
) . item ;
2023-03-03 15:23:46 +00:00
}
2023-10-10 11:03:20 +00:00
protected getWeightedClouds ( ) : number
{
2023-11-15 20:35:05 -05:00
return this . weightedRandomHelper . weightedRandom (
this . weatherConfig . weather . clouds . values ,
this . weatherConfig . weather . clouds . weights ,
) . item ;
2023-10-10 11:03:20 +00:00
}
2023-03-03 15:23:46 +00:00
protected getWeightedWindSpeed ( ) : number
{
2023-11-15 20:35:05 -05:00
return this . weightedRandomHelper . weightedRandom (
this . weatherConfig . weather . windSpeed . values ,
this . weatherConfig . weather . windSpeed . weights ,
) . item ;
2023-03-03 15:23:46 +00:00
}
protected getWeightedFog ( ) : number
{
2023-11-15 20:35:05 -05:00
return this . weightedRandomHelper . weightedRandom (
this . weatherConfig . weather . fog . values ,
this . weatherConfig . weather . fog . weights ,
) . item ;
2023-03-03 15:23:46 +00:00
}
protected getWeightedRain ( ) : number
{
2023-11-15 20:35:05 -05:00
return this . weightedRandomHelper . weightedRandom (
this . weatherConfig . weather . rain . values ,
this . weatherConfig . weather . rain . weights ,
) . item ;
2023-03-03 15:23:46 +00:00
}
protected getRandomFloat ( node : string ) : number
{
2023-11-15 20:35:05 -05:00
return parseFloat (
this . randomUtil . getFloat ( this . weatherConfig . weather [ node ] . min , this . weatherConfig . weather [ node ] . max )
. toPrecision ( 3 ) ,
) ;
2023-03-03 15:23:46 +00:00
}
2023-11-15 20:35:05 -05:00
}