Server/project/src/generators/WeatherGenerator.ts

184 lines
6.5 KiB
TypeScript
Raw Normal View History

2023-03-03 15:23:46 +00:00
import { inject, injectable } from "tsyringe";
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;
data.winterEventEnabled = this.weatherConfig.forceWinterEvent;
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 = {
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
}
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-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
}