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";
|
2024-04-03 19:48:45 +01:00
|
|
|
import { Season } from "@spt-aki/models/enums/Season";
|
2023-10-19 17:21:17 +00:00
|
|
|
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";
|
2024-04-03 19:48:45 +01:00
|
|
|
import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService";
|
2023-10-19 17:21:17 +00:00
|
|
|
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;
|
|
|
|
|
2024-01-23 10:13:53 +00:00
|
|
|
// Note: If this value gets save/load support, raid time could be tracked across server restarts
|
|
|
|
// Currently it will set the In Raid time to your current real time on server launch
|
|
|
|
private serverStartTimestampMS = Date.now();
|
|
|
|
|
2023-03-03 15:23:46 +00:00
|
|
|
constructor(
|
|
|
|
@inject("WeightedRandomHelper") protected weightedRandomHelper: WeightedRandomHelper,
|
|
|
|
@inject("WinstonLogger") protected logger: ILogger,
|
|
|
|
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
|
|
|
@inject("TimeUtil") protected timeUtil: TimeUtil,
|
2024-04-03 19:48:45 +01:00
|
|
|
@inject("SeasonalEventService") protected seasonalEventService: SeasonalEventService,
|
2023-03-03 15:23:46 +00:00
|
|
|
@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;
|
2024-02-23 16:05:30 +00:00
|
|
|
data.time = this.getBsgFormattedInRaidTime();
|
2023-03-03 15:23:46 +00:00
|
|
|
data.acceleration = this.weatherConfig.acceleration;
|
|
|
|
|
2024-04-03 19:48:45 +01:00
|
|
|
data.season = this.weatherConfig.overrideSeason
|
|
|
|
? this.weatherConfig.overrideSeason
|
|
|
|
: this.seasonalEventService.getActiveWeatherSeason();
|
|
|
|
|
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
|
|
|
|
*/
|
2024-02-23 16:05:30 +00:00
|
|
|
protected getBsgFormattedInRaidTime(): string
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
2024-02-23 16:05:30 +00:00
|
|
|
const clientAcceleratedDate = this.getInRaidTime();
|
2023-03-03 15:23:46 +00:00
|
|
|
|
|
|
|
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
|
|
|
*/
|
2024-02-23 16:05:30 +00:00
|
|
|
public getInRaidTime(): Date
|
2023-03-03 15:23:46 +00:00
|
|
|
{
|
2024-02-23 16:05:30 +00:00
|
|
|
// tarkov time = (real time * 7 % 24 hr) + 3 hour
|
2024-05-07 23:57:08 -04:00
|
|
|
const russiaOffset = this.timeUtil.getHoursAsSeconds(3) * 1000;
|
2024-02-23 16:10:18 +00:00
|
|
|
return new Date(
|
2024-05-07 23:57:08 -04:00
|
|
|
(russiaOffset + new Date().getTime() * this.weatherConfig.acceleration)
|
|
|
|
% (this.timeUtil.getHoursAsSeconds(24) * 1000),
|
2024-02-23 16:05:30 +00:00
|
|
|
);
|
2023-03-03 15:23:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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,
|
2024-05-07 23:57:08 -04: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
|
|
|
|
{
|
2024-02-23 16:05:30 +00:00
|
|
|
const currentDate = this.getInRaidTime();
|
2023-03-03 15:23:46 +00:00
|
|
|
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
|
|
|
|
{
|
2024-03-30 14:25:46 -04:00
|
|
|
return Number.parseFloat(
|
2023-11-15 20:35:05 -05:00
|
|
|
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
|
|
|
}
|