Moved values into config
moved code to more appropriate locations Reduced duplicate code Added comments
This commit is contained in:
parent
3d4c7795f7
commit
eb6e61c1f0
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"acceleration": 7,
|
"acceleration": 7,
|
||||||
"weather": {
|
"weather": {
|
||||||
|
"generateWeatherAmountHours": 24,
|
||||||
"clouds": {
|
"clouds": {
|
||||||
"values": [-1.5, -1, 0, 0.5, 1, 1.5],
|
"values": [-1.5, -1, 0, 0.5, 1, 1.5],
|
||||||
"weights": [60, 50, 15, 5, 4, 3]
|
"weights": [60, 50, 15, 5, 4, 3]
|
||||||
@ -36,7 +37,11 @@
|
|||||||
"pressure": {
|
"pressure": {
|
||||||
"min": 760,
|
"min": 760,
|
||||||
"max": 764
|
"max": 764
|
||||||
}
|
},
|
||||||
|
"timePeriod": {
|
||||||
|
"values": [15, 30],
|
||||||
|
"weights": [1, 2]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"seasonDates": [
|
"seasonDates": [
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@ import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig";
|
|||||||
export interface IWeatherConfig extends IBaseConfig {
|
export interface IWeatherConfig extends IBaseConfig {
|
||||||
kind: "spt-weather";
|
kind: "spt-weather";
|
||||||
acceleration: number;
|
acceleration: number;
|
||||||
weather: Weather;
|
weather: IWeatherValues;
|
||||||
seasonDates: ISeasonDateTimes[];
|
seasonDates: ISeasonDateTimes[];
|
||||||
overrideSeason?: Season;
|
overrideSeason?: Season;
|
||||||
}
|
}
|
||||||
@ -20,7 +20,9 @@ export interface ISeasonDateTimes {
|
|||||||
endMonth: number;
|
endMonth: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Weather {
|
export interface IWeatherValues {
|
||||||
|
/** How many hours to generate weather data into the future */
|
||||||
|
generateWeatherAmountHours: number;
|
||||||
clouds: WeatherSettings<string>;
|
clouds: WeatherSettings<string>;
|
||||||
windSpeed: WeatherSettings<number>;
|
windSpeed: WeatherSettings<number>;
|
||||||
windDirection: WeatherSettings<WindDirection>;
|
windDirection: WeatherSettings<WindDirection>;
|
||||||
@ -30,6 +32,8 @@ export interface Weather {
|
|||||||
fog: WeatherSettings<string>;
|
fog: WeatherSettings<string>;
|
||||||
temp: MinMax;
|
temp: MinMax;
|
||||||
pressure: MinMax;
|
pressure: MinMax;
|
||||||
|
/** Length of each weather period */
|
||||||
|
timePeriod: WeatherSettings<number>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WeatherSettings<T> {
|
export interface WeatherSettings<T> {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { WeatherGenerator } from "@spt/generators/WeatherGenerator";
|
import { WeatherGenerator } from "@spt/generators/WeatherGenerator";
|
||||||
|
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
||||||
import { IWeather } from "@spt/models/eft/weather/IWeatherData";
|
import { IWeather } from "@spt/models/eft/weather/IWeatherData";
|
||||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
||||||
import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig";
|
import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig";
|
||||||
@ -18,6 +19,7 @@ export class RaidWeatherService {
|
|||||||
@inject("DatabaseService") protected databaseService: DatabaseService,
|
@inject("DatabaseService") protected databaseService: DatabaseService,
|
||||||
@inject("TimeUtil") protected timeUtil: TimeUtil,
|
@inject("TimeUtil") protected timeUtil: TimeUtil,
|
||||||
@inject("WeatherGenerator") protected weatherGenerator: WeatherGenerator,
|
@inject("WeatherGenerator") protected weatherGenerator: WeatherGenerator,
|
||||||
|
@inject("WeightedRandomHelper") protected weightedRandomHelper: WeightedRandomHelper,
|
||||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
@inject("ConfigServer") protected configServer: ConfigServer,
|
||||||
) {
|
) {
|
||||||
this.weatherConfig = this.configServer.getConfig(ConfigTypes.WEATHER);
|
this.weatherConfig = this.configServer.getConfig(ConfigTypes.WEATHER);
|
||||||
@ -25,62 +27,67 @@ export class RaidWeatherService {
|
|||||||
this.generateWeather();
|
this.generateWeather();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate 24 hours of weather data starting from midnight today
|
||||||
|
*/
|
||||||
public generateWeather() {
|
public generateWeather() {
|
||||||
// When to start generating weather from
|
// When to start generating weather from in milliseconds
|
||||||
const staringTimestamp = this.getLastFullHourTimestamp();
|
const staringTimestampMs = this.timeUtil.getTodaysMidnightTimestamp();
|
||||||
|
|
||||||
// How far into future do we generate weather
|
// How far into future do we generate weather
|
||||||
const futureTimestampToReach = staringTimestamp + this.timeUtil.getHoursAsSeconds(24) * 1000; // TODO move 24 to config
|
const futureTimestampToReachMs =
|
||||||
|
staringTimestampMs +
|
||||||
|
this.timeUtil.getHoursAsSeconds(this.weatherConfig.weather.generateWeatherAmountHours) * 1000; // Convert to milliseconds
|
||||||
|
|
||||||
// Keep adding new weather until we have reached desired future date
|
// Keep adding new weather until we have reached desired future date
|
||||||
let nextTimestamp = staringTimestamp;
|
let nextTimestampMs = staringTimestampMs;
|
||||||
while (nextTimestamp <= futureTimestampToReach) {
|
while (nextTimestampMs <= futureTimestampToReachMs) {
|
||||||
const newWeather = this.weatherGenerator.generateWeather(nextTimestamp);
|
const newWeather = this.weatherGenerator.generateWeather(nextTimestampMs);
|
||||||
this.logger.warning(`Handling ${new Date(nextTimestamp)}`);
|
this.logger.warning(`Handling ${new Date(nextTimestampMs)}`);
|
||||||
this.weatherForecast.push(newWeather);
|
this.weatherForecast.push(newWeather);
|
||||||
nextTimestamp += 30 * 60 * 1000; // TODO move to config
|
nextTimestampMs += this.getWeightedWeatherTimePeriodMs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getLastFullHourTimestamp() {
|
protected getWeightedWeatherTimePeriodMs(): number {
|
||||||
const now = new Date();
|
const chosenTimePeriodMinutes = this.weightedRandomHelper.weightedRandom(
|
||||||
let hours = now.getHours();
|
this.weatherConfig.weather.timePeriod.values,
|
||||||
const minutes = now.getMinutes();
|
this.weatherConfig.weather.timePeriod.weights,
|
||||||
|
).item;
|
||||||
|
|
||||||
// If minutes are greater than 0, subtract 1 hour to get last full hour
|
return chosenTimePeriodMinutes * 60 * 1000; // Convert to milliseconds
|
||||||
if (minutes > 0) {
|
|
||||||
hours--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new Date object with the last full hour, 0 minutes, and 0 seconds
|
|
||||||
const lastFullHour = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours, 0, 0);
|
|
||||||
|
|
||||||
// Return timestamp of last full hour
|
|
||||||
return lastFullHour.getTime();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the first matching weather object that applies to the current time
|
||||||
|
*/
|
||||||
public getCurrentWeather(): IWeather {
|
public getCurrentWeather(): IWeather {
|
||||||
// Clear expired weather data
|
this.validateWeatherDataExists();
|
||||||
this.weatherForecast = this.weatherForecast.filter((x) => x.timestamp < this.timeUtil.getTimestamp());
|
|
||||||
|
|
||||||
// return first weather object that is greater than/equal to now
|
|
||||||
const result = this.weatherForecast.find((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
|
||||||
if (!result) {
|
|
||||||
this.generateWeather();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.weatherForecast.find((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
return this.weatherForecast.find((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the first matching weather object that applies to the current time + all following weather data generated
|
||||||
|
*/
|
||||||
public getUpcomingWeather(): IWeather[] {
|
public getUpcomingWeather(): IWeather[] {
|
||||||
// Clear expired weather data
|
this.validateWeatherDataExists();
|
||||||
this.weatherForecast = this.weatherForecast.filter((x) => x.timestamp < this.timeUtil.getTimestamp());
|
|
||||||
|
|
||||||
// return first weather object that is greater than/equal to now
|
|
||||||
const result = this.weatherForecast.filter((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
|
||||||
if (result.length === 0) {
|
|
||||||
this.generateWeather();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.weatherForecast.filter((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
return this.weatherForecast.filter((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure future weather data exists
|
||||||
|
*/
|
||||||
|
protected validateWeatherDataExists() {
|
||||||
|
// Clear expired weather data
|
||||||
|
this.weatherForecast = this.weatherForecast.filter((x) => x.timestamp < this.timeUtil.getTimestamp());
|
||||||
|
|
||||||
|
// Check data exists for current time
|
||||||
|
const result = this.weatherForecast.filter((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
||||||
|
if (result.length === 0) {
|
||||||
|
// TODO - replace with better check, if < 1 hours worth of data exists?
|
||||||
|
this.generateWeather();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,4 +138,26 @@ export class TimeUtil {
|
|||||||
(60 - now.getMinutes()) * 60 * 1000 - now.getSeconds() * 1000 - now.getMilliseconds();
|
(60 - now.getMinutes()) * 60 * 1000 - now.getSeconds() * 1000 - now.getMilliseconds();
|
||||||
return (now.getTime() + millisecondsUntilNextHour) / 1000;
|
return (now.getTime() + millisecondsUntilNextHour) / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current days timestamp at 00:00
|
||||||
|
* e.g. current time: 13th march 14:22 will return 13th march 00:00
|
||||||
|
* @returns Timestamp
|
||||||
|
*/
|
||||||
|
public getTodaysMidnightTimestamp(): number {
|
||||||
|
const now = new Date();
|
||||||
|
let hours = now.getHours();
|
||||||
|
const minutes = now.getMinutes();
|
||||||
|
|
||||||
|
// If minutes greater than 0, subtract 1 hour to get last full hour
|
||||||
|
if (minutes > 0) {
|
||||||
|
hours--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new Date object with the last full hour, 0 minutes, and 0 seconds
|
||||||
|
const lastFullHour = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours, 0, 0);
|
||||||
|
|
||||||
|
// Return above as timestamp
|
||||||
|
return lastFullHour.getTime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user