Improvements to how weather temperature is calculated - takes into account current season
Centralised the season override into `getActiveWeatherSeason()` Adjusted weather values based on client data
This commit is contained in:
parent
eb6e61c1f0
commit
0b729fba11
@ -3,12 +3,12 @@
|
|||||||
"weather": {
|
"weather": {
|
||||||
"generateWeatherAmountHours": 24,
|
"generateWeatherAmountHours": 24,
|
||||||
"clouds": {
|
"clouds": {
|
||||||
"values": [-1.5, -1, 0, 0.5, 1, 1.5],
|
"values": [-1, 0, 0.5, 1, 1.5],
|
||||||
"weights": [60, 50, 15, 5, 4, 3]
|
"weights": [100, 15, 5, 4, 3]
|
||||||
},
|
},
|
||||||
"windSpeed": {
|
"windSpeed": {
|
||||||
"values": [0, 1, 2, 3],
|
"values": [0, 1, 2, 3, 4],
|
||||||
"weights": [4, 3, 2, 1]
|
"weights": [6, 3, 2, 1, 1]
|
||||||
},
|
},
|
||||||
"windDirection": {
|
"windDirection": {
|
||||||
"values": [1, 2, 3, 4, 5, 6, 7, 8],
|
"values": [1, 2, 3, 4, 5, 6, 7, 8],
|
||||||
@ -19,8 +19,8 @@
|
|||||||
"max": 1
|
"max": 1
|
||||||
},
|
},
|
||||||
"rain": {
|
"rain": {
|
||||||
"values": [1, 2, 3],
|
"values": [1, 2, 3, 4, 5],
|
||||||
"weights": [25, 1, 1]
|
"weights": [25, 1, 1, 1, 1]
|
||||||
},
|
},
|
||||||
"rainIntensity": {
|
"rainIntensity": {
|
||||||
"min": 0,
|
"min": 0,
|
||||||
@ -31,12 +31,30 @@
|
|||||||
"weights": [25, 8, 5, 5, 1]
|
"weights": [25, 8, 5, 5, 1]
|
||||||
},
|
},
|
||||||
"temp": {
|
"temp": {
|
||||||
"min": 0,
|
"0": {
|
||||||
"max": 24
|
"min": 17,
|
||||||
|
"max": 32
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"min": 7,
|
||||||
|
"max": 15
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"min": -10,
|
||||||
|
"max": 5
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"min": 1,
|
||||||
|
"max": 15
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"min": 0,
|
||||||
|
"max": 24
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"pressure": {
|
"pressure": {
|
||||||
"min": 760,
|
"min": 760,
|
||||||
"max": 764
|
"max": 780
|
||||||
},
|
},
|
||||||
"timePeriod": {
|
"timePeriod": {
|
||||||
"values": [15, 30],
|
"values": [15, 30],
|
||||||
|
@ -30,7 +30,7 @@ export class WeatherController {
|
|||||||
let result: IWeatherData = { acceleration: 0, time: "", date: "", weather: undefined, season: 1 }; // defaults, hydrated below
|
let result: IWeatherData = { acceleration: 0, time: "", date: "", weather: undefined, season: 1 }; // defaults, hydrated below
|
||||||
|
|
||||||
result = this.weatherGenerator.calculateGameTime(result);
|
result = this.weatherGenerator.calculateGameTime(result);
|
||||||
result.weather = this.weatherGenerator.generateWeather();
|
result.weather = this.weatherGenerator.generateWeather(result.season);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -46,10 +46,7 @@ export class WeatherController {
|
|||||||
/** Handle client/localGame/weather */
|
/** Handle client/localGame/weather */
|
||||||
public generateLocal(sesssionId: string): IGetLocalWeatherResponseData {
|
public generateLocal(sesssionId: string): IGetLocalWeatherResponseData {
|
||||||
const result: IGetLocalWeatherResponseData = {
|
const result: IGetLocalWeatherResponseData = {
|
||||||
season:
|
season: this.seasonalEventService.getActiveWeatherSeason(),
|
||||||
this.weatherConfig.overrideSeason !== null
|
|
||||||
? this.weatherConfig.overrideSeason
|
|
||||||
: this.seasonalEventService.getActiveWeatherSeason(),
|
|
||||||
weather: [],
|
weather: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import { WeatherHelper } from "@spt/helpers/WeatherHelper";
|
|||||||
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
||||||
import { IWeather, IWeatherData } from "@spt/models/eft/weather/IWeatherData";
|
import { IWeather, IWeatherData } from "@spt/models/eft/weather/IWeatherData";
|
||||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
||||||
|
import { Season } from "@spt/models/enums/Season";
|
||||||
import { WindDirection } from "@spt/models/enums/WindDirection";
|
import { WindDirection } from "@spt/models/enums/WindDirection";
|
||||||
import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig";
|
import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig";
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||||
@ -46,10 +47,7 @@ export class WeatherGenerator {
|
|||||||
data.time = this.getBsgFormattedInRaidTime();
|
data.time = this.getBsgFormattedInRaidTime();
|
||||||
data.acceleration = this.weatherConfig.acceleration;
|
data.acceleration = this.weatherConfig.acceleration;
|
||||||
|
|
||||||
data.season =
|
data.season = this.seasonalEventService.getActiveWeatherSeason();
|
||||||
this.weatherConfig.overrideSeason !== null
|
|
||||||
? this.weatherConfig.overrideSeason
|
|
||||||
: this.seasonalEventService.getActiveWeatherSeason();
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -79,7 +77,7 @@ export class WeatherGenerator {
|
|||||||
* Return randomised Weather data with help of config/weather.json
|
* Return randomised Weather data with help of config/weather.json
|
||||||
* @returns Randomised weather data
|
* @returns Randomised weather data
|
||||||
*/
|
*/
|
||||||
public generateWeather(timestamp?: number): IWeather {
|
public generateWeather(currentSeason: Season, timestamp?: number): IWeather {
|
||||||
const clouds = this.getWeightedClouds();
|
const clouds = this.getWeightedClouds();
|
||||||
|
|
||||||
// Force rain to off if no clouds
|
// Force rain to off if no clouds
|
||||||
@ -93,7 +91,7 @@ export class WeatherGenerator {
|
|||||||
rain: rain,
|
rain: rain,
|
||||||
rain_intensity: rain > 1 ? this.getRandomFloat("rainIntensity") : 0,
|
rain_intensity: rain > 1 ? this.getRandomFloat("rainIntensity") : 0,
|
||||||
fog: this.getWeightedFog(),
|
fog: this.getWeightedFog(),
|
||||||
temp: this.getRandomFloat("temp"), // TODO - lower value at night / take into account season
|
temp: 0, // TODO - lower value at night / take into account season
|
||||||
pressure: this.getRandomFloat("pressure"),
|
pressure: this.getRandomFloat("pressure"),
|
||||||
time: "",
|
time: "",
|
||||||
date: "",
|
date: "",
|
||||||
@ -102,9 +100,17 @@ export class WeatherGenerator {
|
|||||||
|
|
||||||
this.setCurrentDateTime(result, timestamp);
|
this.setCurrentDateTime(result, timestamp);
|
||||||
|
|
||||||
|
result.temp = this.getRaidTemperature(currentSeason, result.time);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected getRaidTemperature(currentSeason: Season, currentTimeBsgFormatted: string): number {
|
||||||
|
// TODO, take into account time of day
|
||||||
|
const minMax = this.weatherConfig.weather.temp[currentSeason];
|
||||||
|
return Number.parseFloat(this.randomUtil.getFloat(minMax.min, minMax.max).toPrecision(2));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set IWeather date/time/timestamp values to now
|
* Set IWeather date/time/timestamp values to now
|
||||||
* @param weather Object to update
|
* @param weather Object to update
|
||||||
|
@ -30,7 +30,7 @@ export interface IWeatherValues {
|
|||||||
rain: WeatherSettings<number>;
|
rain: WeatherSettings<number>;
|
||||||
rainIntensity: MinMax;
|
rainIntensity: MinMax;
|
||||||
fog: WeatherSettings<string>;
|
fog: WeatherSettings<string>;
|
||||||
temp: MinMax;
|
temp: Record<Season, MinMax>;
|
||||||
pressure: MinMax;
|
pressure: MinMax;
|
||||||
/** Length of each weather period */
|
/** Length of each weather period */
|
||||||
timePeriod: WeatherSettings<number>;
|
timePeriod: WeatherSettings<number>;
|
||||||
|
@ -2,10 +2,12 @@ import { WeatherGenerator } from "@spt/generators/WeatherGenerator";
|
|||||||
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
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 { Season } from "@spt/models/enums/Season";
|
||||||
import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig";
|
import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig";
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
import { DatabaseService } from "@spt/services/DatabaseService";
|
||||||
|
import { SeasonalEventService } from "@spt/services/SeasonalEventService";
|
||||||
import { TimeUtil } from "@spt/utils/TimeUtil";
|
import { TimeUtil } from "@spt/utils/TimeUtil";
|
||||||
import { inject, injectable } from "tsyringe";
|
import { inject, injectable } from "tsyringe";
|
||||||
|
|
||||||
@ -19,18 +21,20 @@ 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("SeasonalEventService") protected seasonalEventService: SeasonalEventService,
|
||||||
@inject("WeightedRandomHelper") protected weightedRandomHelper: WeightedRandomHelper,
|
@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);
|
||||||
|
|
||||||
this.generateWeather();
|
const currentSeason = this.seasonalEventService.getActiveWeatherSeason();
|
||||||
|
this.generateWeather(currentSeason);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate 24 hours of weather data starting from midnight today
|
* Generate 24 hours of weather data starting from midnight today
|
||||||
*/
|
*/
|
||||||
public generateWeather() {
|
public generateWeather(currentSeason: Season) {
|
||||||
// When to start generating weather from in milliseconds
|
// When to start generating weather from in milliseconds
|
||||||
const staringTimestampMs = this.timeUtil.getTodaysMidnightTimestamp();
|
const staringTimestampMs = this.timeUtil.getTodaysMidnightTimestamp();
|
||||||
|
|
||||||
@ -42,13 +46,20 @@ export class RaidWeatherService {
|
|||||||
// Keep adding new weather until we have reached desired future date
|
// Keep adding new weather until we have reached desired future date
|
||||||
let nextTimestampMs = staringTimestampMs;
|
let nextTimestampMs = staringTimestampMs;
|
||||||
while (nextTimestampMs <= futureTimestampToReachMs) {
|
while (nextTimestampMs <= futureTimestampToReachMs) {
|
||||||
const newWeather = this.weatherGenerator.generateWeather(nextTimestampMs);
|
const newWeatherToAddToCache = this.weatherGenerator.generateWeather(currentSeason, nextTimestampMs);
|
||||||
this.logger.warning(`Handling ${new Date(nextTimestampMs)}`);
|
|
||||||
this.weatherForecast.push(newWeather);
|
// Add generated weather for time period to cache
|
||||||
|
this.weatherForecast.push(newWeatherToAddToCache);
|
||||||
|
|
||||||
|
// Increment timestamp so next loop can begin at correct time
|
||||||
nextTimestampMs += this.getWeightedWeatherTimePeriodMs();
|
nextTimestampMs += this.getWeightedWeatherTimePeriodMs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a time period to increment by, e.g 15 or 30 minutes as milliseconds
|
||||||
|
* @returns milliseconds
|
||||||
|
*/
|
||||||
protected getWeightedWeatherTimePeriodMs(): number {
|
protected getWeightedWeatherTimePeriodMs(): number {
|
||||||
const chosenTimePeriodMinutes = this.weightedRandomHelper.weightedRandom(
|
const chosenTimePeriodMinutes = this.weightedRandomHelper.weightedRandom(
|
||||||
this.weatherConfig.weather.timePeriod.values,
|
this.weatherConfig.weather.timePeriod.values,
|
||||||
@ -62,7 +73,8 @@ export class RaidWeatherService {
|
|||||||
* Find the first matching weather object that applies to the current time
|
* Find the first matching weather object that applies to the current time
|
||||||
*/
|
*/
|
||||||
public getCurrentWeather(): IWeather {
|
public getCurrentWeather(): IWeather {
|
||||||
this.validateWeatherDataExists();
|
const currentSeason = this.seasonalEventService.getActiveWeatherSeason();
|
||||||
|
this.validateWeatherDataExists(currentSeason);
|
||||||
|
|
||||||
return this.weatherForecast.find((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
return this.weatherForecast.find((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
||||||
}
|
}
|
||||||
@ -71,7 +83,8 @@ export class RaidWeatherService {
|
|||||||
* Find the first matching weather object that applies to the current time + all following weather data generated
|
* Find the first matching weather object that applies to the current time + all following weather data generated
|
||||||
*/
|
*/
|
||||||
public getUpcomingWeather(): IWeather[] {
|
public getUpcomingWeather(): IWeather[] {
|
||||||
this.validateWeatherDataExists();
|
const currentSeason = this.seasonalEventService.getActiveWeatherSeason();
|
||||||
|
this.validateWeatherDataExists(currentSeason);
|
||||||
|
|
||||||
return this.weatherForecast.filter((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
return this.weatherForecast.filter((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
||||||
}
|
}
|
||||||
@ -79,7 +92,7 @@ export class RaidWeatherService {
|
|||||||
/**
|
/**
|
||||||
* Ensure future weather data exists
|
* Ensure future weather data exists
|
||||||
*/
|
*/
|
||||||
protected validateWeatherDataExists() {
|
protected validateWeatherDataExists(currentSeason: Season) {
|
||||||
// Clear expired weather data
|
// Clear expired weather data
|
||||||
this.weatherForecast = this.weatherForecast.filter((x) => x.timestamp < this.timeUtil.getTimestamp());
|
this.weatherForecast = this.weatherForecast.filter((x) => x.timestamp < this.timeUtil.getTimestamp());
|
||||||
|
|
||||||
@ -87,7 +100,7 @@ export class RaidWeatherService {
|
|||||||
const result = this.weatherForecast.filter((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
const result = this.weatherForecast.filter((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
||||||
if (result.length === 0) {
|
if (result.length === 0) {
|
||||||
// TODO - replace with better check, if < 1 hours worth of data exists?
|
// TODO - replace with better check, if < 1 hours worth of data exists?
|
||||||
this.generateWeather();
|
this.generateWeather(currentSeason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,6 +232,10 @@ export class SeasonalEventService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getActiveWeatherSeason(): Season {
|
public getActiveWeatherSeason(): Season {
|
||||||
|
if (this.weatherConfig.overrideSeason !== null) {
|
||||||
|
return this.weatherConfig.overrideSeason;
|
||||||
|
}
|
||||||
|
|
||||||
const currentDate = new Date();
|
const currentDate = new Date();
|
||||||
for (const seasonRange of this.weatherConfig.seasonDates) {
|
for (const seasonRange of this.weatherConfig.seasonDates) {
|
||||||
// Figure out start and end dates to get range of season
|
// Figure out start and end dates to get range of season
|
||||||
|
Loading…
x
Reference in New Issue
Block a user