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": {
|
||||
"generateWeatherAmountHours": 24,
|
||||
"clouds": {
|
||||
"values": [-1.5, -1, 0, 0.5, 1, 1.5],
|
||||
"weights": [60, 50, 15, 5, 4, 3]
|
||||
"values": [-1, 0, 0.5, 1, 1.5],
|
||||
"weights": [100, 15, 5, 4, 3]
|
||||
},
|
||||
"windSpeed": {
|
||||
"values": [0, 1, 2, 3],
|
||||
"weights": [4, 3, 2, 1]
|
||||
"values": [0, 1, 2, 3, 4],
|
||||
"weights": [6, 3, 2, 1, 1]
|
||||
},
|
||||
"windDirection": {
|
||||
"values": [1, 2, 3, 4, 5, 6, 7, 8],
|
||||
@ -19,8 +19,8 @@
|
||||
"max": 1
|
||||
},
|
||||
"rain": {
|
||||
"values": [1, 2, 3],
|
||||
"weights": [25, 1, 1]
|
||||
"values": [1, 2, 3, 4, 5],
|
||||
"weights": [25, 1, 1, 1, 1]
|
||||
},
|
||||
"rainIntensity": {
|
||||
"min": 0,
|
||||
@ -31,12 +31,30 @@
|
||||
"weights": [25, 8, 5, 5, 1]
|
||||
},
|
||||
"temp": {
|
||||
"min": 0,
|
||||
"max": 24
|
||||
"0": {
|
||||
"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": {
|
||||
"min": 760,
|
||||
"max": 764
|
||||
"max": 780
|
||||
},
|
||||
"timePeriod": {
|
||||
"values": [15, 30],
|
||||
|
@ -30,7 +30,7 @@ export class WeatherController {
|
||||
let result: IWeatherData = { acceleration: 0, time: "", date: "", weather: undefined, season: 1 }; // defaults, hydrated below
|
||||
|
||||
result = this.weatherGenerator.calculateGameTime(result);
|
||||
result.weather = this.weatherGenerator.generateWeather();
|
||||
result.weather = this.weatherGenerator.generateWeather(result.season);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -46,10 +46,7 @@ export class WeatherController {
|
||||
/** Handle client/localGame/weather */
|
||||
public generateLocal(sesssionId: string): IGetLocalWeatherResponseData {
|
||||
const result: IGetLocalWeatherResponseData = {
|
||||
season:
|
||||
this.weatherConfig.overrideSeason !== null
|
||||
? this.weatherConfig.overrideSeason
|
||||
: this.seasonalEventService.getActiveWeatherSeason(),
|
||||
season: this.seasonalEventService.getActiveWeatherSeason(),
|
||||
weather: [],
|
||||
};
|
||||
|
||||
|
@ -3,6 +3,7 @@ import { WeatherHelper } from "@spt/helpers/WeatherHelper";
|
||||
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
||||
import { IWeather, IWeatherData } from "@spt/models/eft/weather/IWeatherData";
|
||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
||||
import { Season } from "@spt/models/enums/Season";
|
||||
import { WindDirection } from "@spt/models/enums/WindDirection";
|
||||
import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig";
|
||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||
@ -46,10 +47,7 @@ export class WeatherGenerator {
|
||||
data.time = this.getBsgFormattedInRaidTime();
|
||||
data.acceleration = this.weatherConfig.acceleration;
|
||||
|
||||
data.season =
|
||||
this.weatherConfig.overrideSeason !== null
|
||||
? this.weatherConfig.overrideSeason
|
||||
: this.seasonalEventService.getActiveWeatherSeason();
|
||||
data.season = this.seasonalEventService.getActiveWeatherSeason();
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -79,7 +77,7 @@ export class WeatherGenerator {
|
||||
* Return randomised Weather data with help of config/weather.json
|
||||
* @returns Randomised weather data
|
||||
*/
|
||||
public generateWeather(timestamp?: number): IWeather {
|
||||
public generateWeather(currentSeason: Season, timestamp?: number): IWeather {
|
||||
const clouds = this.getWeightedClouds();
|
||||
|
||||
// Force rain to off if no clouds
|
||||
@ -93,7 +91,7 @@ export class WeatherGenerator {
|
||||
rain: rain,
|
||||
rain_intensity: rain > 1 ? this.getRandomFloat("rainIntensity") : 0,
|
||||
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"),
|
||||
time: "",
|
||||
date: "",
|
||||
@ -102,9 +100,17 @@ export class WeatherGenerator {
|
||||
|
||||
this.setCurrentDateTime(result, timestamp);
|
||||
|
||||
result.temp = this.getRaidTemperature(currentSeason, result.time);
|
||||
|
||||
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
|
||||
* @param weather Object to update
|
||||
|
@ -30,7 +30,7 @@ export interface IWeatherValues {
|
||||
rain: WeatherSettings<number>;
|
||||
rainIntensity: MinMax;
|
||||
fog: WeatherSettings<string>;
|
||||
temp: MinMax;
|
||||
temp: Record<Season, MinMax>;
|
||||
pressure: MinMax;
|
||||
/** Length of each weather period */
|
||||
timePeriod: WeatherSettings<number>;
|
||||
|
@ -2,10 +2,12 @@ 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 { Season } from "@spt/models/enums/Season";
|
||||
import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig";
|
||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
import { SeasonalEventService } from "@spt/services/SeasonalEventService";
|
||||
import { TimeUtil } from "@spt/utils/TimeUtil";
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
@ -19,18 +21,20 @@ export class RaidWeatherService {
|
||||
@inject("DatabaseService") protected databaseService: DatabaseService,
|
||||
@inject("TimeUtil") protected timeUtil: TimeUtil,
|
||||
@inject("WeatherGenerator") protected weatherGenerator: WeatherGenerator,
|
||||
@inject("SeasonalEventService") protected seasonalEventService: SeasonalEventService,
|
||||
@inject("WeightedRandomHelper") protected weightedRandomHelper: WeightedRandomHelper,
|
||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
||||
) {
|
||||
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
|
||||
*/
|
||||
public generateWeather() {
|
||||
public generateWeather(currentSeason: Season) {
|
||||
// When to start generating weather from in milliseconds
|
||||
const staringTimestampMs = this.timeUtil.getTodaysMidnightTimestamp();
|
||||
|
||||
@ -42,13 +46,20 @@ export class RaidWeatherService {
|
||||
// Keep adding new weather until we have reached desired future date
|
||||
let nextTimestampMs = staringTimestampMs;
|
||||
while (nextTimestampMs <= futureTimestampToReachMs) {
|
||||
const newWeather = this.weatherGenerator.generateWeather(nextTimestampMs);
|
||||
this.logger.warning(`Handling ${new Date(nextTimestampMs)}`);
|
||||
this.weatherForecast.push(newWeather);
|
||||
const newWeatherToAddToCache = this.weatherGenerator.generateWeather(currentSeason, nextTimestampMs);
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a time period to increment by, e.g 15 or 30 minutes as milliseconds
|
||||
* @returns milliseconds
|
||||
*/
|
||||
protected getWeightedWeatherTimePeriodMs(): number {
|
||||
const chosenTimePeriodMinutes = this.weightedRandomHelper.weightedRandom(
|
||||
this.weatherConfig.weather.timePeriod.values,
|
||||
@ -62,7 +73,8 @@ export class RaidWeatherService {
|
||||
* Find the first matching weather object that applies to the current time
|
||||
*/
|
||||
public getCurrentWeather(): IWeather {
|
||||
this.validateWeatherDataExists();
|
||||
const currentSeason = this.seasonalEventService.getActiveWeatherSeason();
|
||||
this.validateWeatherDataExists(currentSeason);
|
||||
|
||||
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
|
||||
*/
|
||||
public getUpcomingWeather(): IWeather[] {
|
||||
this.validateWeatherDataExists();
|
||||
const currentSeason = this.seasonalEventService.getActiveWeatherSeason();
|
||||
this.validateWeatherDataExists(currentSeason);
|
||||
|
||||
return this.weatherForecast.filter((x) => x.timestamp >= this.timeUtil.getTimestamp());
|
||||
}
|
||||
@ -79,7 +92,7 @@ export class RaidWeatherService {
|
||||
/**
|
||||
* Ensure future weather data exists
|
||||
*/
|
||||
protected validateWeatherDataExists() {
|
||||
protected validateWeatherDataExists(currentSeason: Season) {
|
||||
// Clear expired weather data
|
||||
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());
|
||||
if (result.length === 0) {
|
||||
// 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 {
|
||||
if (this.weatherConfig.overrideSeason !== null) {
|
||||
return this.weatherConfig.overrideSeason;
|
||||
}
|
||||
|
||||
const currentDate = new Date();
|
||||
for (const seasonRange of this.weatherConfig.seasonDates) {
|
||||
// Figure out start and end dates to get range of season
|
||||
|
Loading…
x
Reference in New Issue
Block a user