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,
|
||||
"weather": {
|
||||
"generateWeatherAmountHours": 24,
|
||||
"clouds": {
|
||||
"values": [-1.5, -1, 0, 0.5, 1, 1.5],
|
||||
"weights": [60, 50, 15, 5, 4, 3]
|
||||
@ -36,7 +37,11 @@
|
||||
"pressure": {
|
||||
"min": 760,
|
||||
"max": 764
|
||||
}
|
||||
},
|
||||
"timePeriod": {
|
||||
"values": [15, 30],
|
||||
"weights": [1, 2]
|
||||
}
|
||||
},
|
||||
"seasonDates": [
|
||||
{
|
||||
|
@ -6,7 +6,7 @@ import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig";
|
||||
export interface IWeatherConfig extends IBaseConfig {
|
||||
kind: "spt-weather";
|
||||
acceleration: number;
|
||||
weather: Weather;
|
||||
weather: IWeatherValues;
|
||||
seasonDates: ISeasonDateTimes[];
|
||||
overrideSeason?: Season;
|
||||
}
|
||||
@ -20,7 +20,9 @@ export interface ISeasonDateTimes {
|
||||
endMonth: number;
|
||||
}
|
||||
|
||||
export interface Weather {
|
||||
export interface IWeatherValues {
|
||||
/** How many hours to generate weather data into the future */
|
||||
generateWeatherAmountHours: number;
|
||||
clouds: WeatherSettings<string>;
|
||||
windSpeed: WeatherSettings<number>;
|
||||
windDirection: WeatherSettings<WindDirection>;
|
||||
@ -30,6 +32,8 @@ export interface Weather {
|
||||
fog: WeatherSettings<string>;
|
||||
temp: MinMax;
|
||||
pressure: MinMax;
|
||||
/** Length of each weather period */
|
||||
timePeriod: WeatherSettings<number>;
|
||||
}
|
||||
|
||||
export interface WeatherSettings<T> {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { WeatherGenerator } from "@spt/generators/WeatherGenerator";
|
||||
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
||||
import { IWeather } from "@spt/models/eft/weather/IWeatherData";
|
||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
||||
import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig";
|
||||
@ -18,6 +19,7 @@ export class RaidWeatherService {
|
||||
@inject("DatabaseService") protected databaseService: DatabaseService,
|
||||
@inject("TimeUtil") protected timeUtil: TimeUtil,
|
||||
@inject("WeatherGenerator") protected weatherGenerator: WeatherGenerator,
|
||||
@inject("WeightedRandomHelper") protected weightedRandomHelper: WeightedRandomHelper,
|
||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
||||
) {
|
||||
this.weatherConfig = this.configServer.getConfig(ConfigTypes.WEATHER);
|
||||
@ -25,62 +27,67 @@ export class RaidWeatherService {
|
||||
this.generateWeather();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate 24 hours of weather data starting from midnight today
|
||||
*/
|
||||
public generateWeather() {
|
||||
// When to start generating weather from
|
||||
const staringTimestamp = this.getLastFullHourTimestamp();
|
||||
// When to start generating weather from in milliseconds
|
||||
const staringTimestampMs = this.timeUtil.getTodaysMidnightTimestamp();
|
||||
|
||||
// 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
|
||||
let nextTimestamp = staringTimestamp;
|
||||
while (nextTimestamp <= futureTimestampToReach) {
|
||||
const newWeather = this.weatherGenerator.generateWeather(nextTimestamp);
|
||||
this.logger.warning(`Handling ${new Date(nextTimestamp)}`);
|
||||
let nextTimestampMs = staringTimestampMs;
|
||||
while (nextTimestampMs <= futureTimestampToReachMs) {
|
||||
const newWeather = this.weatherGenerator.generateWeather(nextTimestampMs);
|
||||
this.logger.warning(`Handling ${new Date(nextTimestampMs)}`);
|
||||
this.weatherForecast.push(newWeather);
|
||||
nextTimestamp += 30 * 60 * 1000; // TODO move to config
|
||||
nextTimestampMs += this.getWeightedWeatherTimePeriodMs();
|
||||
}
|
||||
}
|
||||
|
||||
protected getLastFullHourTimestamp() {
|
||||
const now = new Date();
|
||||
let hours = now.getHours();
|
||||
const minutes = now.getMinutes();
|
||||
protected getWeightedWeatherTimePeriodMs(): number {
|
||||
const chosenTimePeriodMinutes = this.weightedRandomHelper.weightedRandom(
|
||||
this.weatherConfig.weather.timePeriod.values,
|
||||
this.weatherConfig.weather.timePeriod.weights,
|
||||
).item;
|
||||
|
||||
// If minutes are 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 timestamp of last full hour
|
||||
return lastFullHour.getTime();
|
||||
return chosenTimePeriodMinutes * 60 * 1000; // Convert to milliseconds
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first matching weather object that applies to the current time
|
||||
*/
|
||||
public getCurrentWeather(): IWeather {
|
||||
// Clear expired weather data
|
||||
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();
|
||||
}
|
||||
this.validateWeatherDataExists();
|
||||
|
||||
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[] {
|
||||
// Clear expired weather data
|
||||
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();
|
||||
}
|
||||
this.validateWeatherDataExists();
|
||||
|
||||
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();
|
||||
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