From de36bd9f2c1baab2439cd3df8aa3d1554c36c6b1 Mon Sep 17 00:00:00 2001 From: KaenoDev <193943350+KaenoDev@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:50:47 +0000 Subject: [PATCH] Implement GenerateWeather and update getInRaidTime to match Ts server output --- Core/Generators/WeatherGenerator.cs | 79 +++++++++++++++++++++++------ Core/Helpers/WeatherHelper.cs | 10 ++-- Core/Utils/TimeUtil.cs | 12 +++++ 3 files changed, 82 insertions(+), 19 deletions(-) diff --git a/Core/Generators/WeatherGenerator.cs b/Core/Generators/WeatherGenerator.cs index bd254ace..badb981c 100644 --- a/Core/Generators/WeatherGenerator.cs +++ b/Core/Generators/WeatherGenerator.cs @@ -16,19 +16,25 @@ public class WeatherGenerator private readonly SeasonalEventService _seasonalEventService; private readonly WeatherHelper _weatherHelper; private readonly ConfigServer _configServer; - + private readonly WeightedRandomHelper _weightedRandomHelper; + private readonly RandomUtil _randomUtil; private readonly WeatherConfig _weatherConfig; public WeatherGenerator( TimeUtil timeUtil, SeasonalEventService seasonalEventService, WeatherHelper weatherHelper, - ConfigServer configServer) + ConfigServer configServer, + WeightedRandomHelper weightedRandomHelper, + RandomUtil randomUtil + ) { _timeUtil = timeUtil; _seasonalEventService = seasonalEventService; _weatherHelper = weatherHelper; _configServer = configServer; + _weightedRandomHelper = weightedRandomHelper; + _randomUtil = randomUtil; _weatherConfig = _configServer.GetConfig(ConfigTypes.WEATHER); } @@ -81,7 +87,36 @@ public class WeatherGenerator */ public Weather GenerateWeather(Season currentSeason, long? timestamp = null) { - throw new NotImplementedException(); + var weatherValues = GetWeatherValuesBySeason(currentSeason); + var clouds = GetWeightedClouds(weatherValues); + + // Force rain to off if no clouds + var rain = clouds <= 0.6 ? 0 : GetWeightedRain(weatherValues); + + // TODO: Ensure Weather settings match Ts Server GetRandomDouble produces a decimal value way higher than ts server + var result = new Weather + { + Pressure = GetRandomDouble(weatherValues.Pressure.Min ?? 0, weatherValues.Pressure.Max ?? 0), + Temperature = 0, + Fog = GetWeightedFog(weatherValues), + RainIntensity = + rain > 1 ? GetRandomDouble(weatherValues.RainIntensity.Min ?? 0, weatherValues.RainIntensity.Max ?? 0) : 0, + Rain = rain, + WindGustiness = GetRandomDouble(weatherValues.WindGustiness.Min ?? 0, weatherValues.WindGustiness.Max ?? 0, 2), + WindDirection = GetWeightedWindDirection(weatherValues), + WindSpeed = GetWeightedWindSpeed(weatherValues), + Cloud = clouds, + Time = "", + Date = "", + Timestamp = 0, + SptInRaidTimestamp = 0 + }; + + SetCurrentDateTime(result, timestamp); + + result.Temperature = GetRaidTemperature(weatherValues, result.SptInRaidTimestamp ?? 0); + + return result; } protected SeasonalValues GetWeatherValuesBySeason(Season currentSeason) @@ -92,7 +127,7 @@ public class WeatherGenerator return this._weatherConfig.Weather.SeasonValues["default"]; } - return value; + return value!; } /** @@ -101,9 +136,15 @@ public class WeatherGenerator * @param inRaidTimestamp What time is the raid running at * @returns Timestamp */ - protected double GetRaidTemperature(SeasonalValues weather, int inRaidTimestamp) + protected double GetRaidTemperature(SeasonalValues weather, long inRaidTimestamp) { - throw new NotImplementedException(); + // Convert timestamp to date so we can get current hour and check if its day or night + var currentRaidTime = new DateTime(inRaidTimestamp); + var minMax = _weatherHelper.IsHourAtNightTime(currentRaidTime.Hour) + ? weather.Temp.Night + : weather.Temp.Day; + + return Math.Round(_randomUtil.GetDouble(minMax.Min ?? 0, minMax.Max ?? 0), 2); } /** @@ -111,38 +152,46 @@ public class WeatherGenerator * @param weather Object to update * @param timestamp OPTIONAL, define timestamp used */ - protected void SetCurrentDateTime(Weather weather, int? timestamp = null) + protected void SetCurrentDateTime(Weather weather, long? timestamp = null) { - throw new NotImplementedException(); + var inRaidTime = _weatherHelper.GetInRaidTime(timestamp); + var normalTime = GetBsgFormattedTime(inRaidTime); + var formattedDate = _timeUtil.FormatDate(timestamp.HasValue ? _timeUtil.GetDateTimeFromTimeStamp(timestamp.Value) : DateTime.UtcNow); + var datetimeBsgFormat = $"{formattedDate} {normalTime}"; + + weather.Timestamp = timestamp ?? _timeUtil.GetTimeStampFromEpoch(inRaidTime); // matches weather.date We use to divide by 1000 + weather.Date = formattedDate; // matches weather.timestamp + weather.Time = datetimeBsgFormat; // matches weather.timestamp + weather.SptInRaidTimestamp = _timeUtil.GetTimeStampFromEpoch(inRaidTime); } protected WindDirection GetWeightedWindDirection(SeasonalValues weather) { - throw new NotImplementedException(); + return _weightedRandomHelper.WeightedRandom(weather.WindDirection.Values, weather.WindDirection.Weights).Item; } protected double GetWeightedClouds(SeasonalValues weather) { - throw new NotImplementedException(); + return _weightedRandomHelper.WeightedRandom(weather.Clouds.Values, weather.Clouds.Weights).Item; } protected double GetWeightedWindSpeed(SeasonalValues weather) { - throw new NotImplementedException(); + return _weightedRandomHelper.WeightedRandom(weather.WindSpeed.Values, weather.WindSpeed.Weights).Item; } protected double GetWeightedFog(SeasonalValues weather) { - throw new NotImplementedException(); + return _weightedRandomHelper.WeightedRandom(weather.Fog.Values, weather.Fog.Weights).Item; } protected double GetWeightedRain(SeasonalValues weather) { - throw new NotImplementedException(); + return _weightedRandomHelper.WeightedRandom(weather.Rain.Values, weather.Rain.Weights).Item; } - protected double GetRandomFloat(double min, double max, int precision = 3) + protected double GetRandomDouble(double min, double max, int precision = 3) { - throw new NotImplementedException(); + return Math.Round(_randomUtil.GetDouble(min, max), precision); } } diff --git a/Core/Helpers/WeatherHelper.cs b/Core/Helpers/WeatherHelper.cs index 0b3163f4..52987f03 100644 --- a/Core/Helpers/WeatherHelper.cs +++ b/Core/Helpers/WeatherHelper.cs @@ -40,11 +40,13 @@ public class WeatherHelper // tarkov time = (real time * 7 % 24 hr) + 3 hour var russiaOffsetMilliseconds = _timeUtil.GetHoursAsSeconds(3) * 1000; var twentyFourHoursMilliseconds = _timeUtil.GetHoursAsSeconds(24) * 1000; - var currentTimestampMilliSeconds = (timestamp is not null) ? timestamp : _timeUtil.GetTimeStamp(); + var currentTimestampMilliSeconds = timestamp.HasValue + ? timestamp ?? 0 + : (DateTime.UtcNow - DateTime.UnixEpoch).TotalMilliseconds; //_timeUtil.GetTimeStampFromEpoch(); - return new DateTime().AddMilliseconds( - (russiaOffsetMilliseconds + russiaOffsetMilliseconds * _weatherConfig.Acceleration) % - twentyFourHoursMilliseconds); + return _timeUtil.GetDateTimeFromTimeStamp((long) + (russiaOffsetMilliseconds + currentTimestampMilliSeconds * _weatherConfig.Acceleration) % + twentyFourHoursMilliseconds); } /// diff --git a/Core/Utils/TimeUtil.cs b/Core/Utils/TimeUtil.cs index eebc000d..2df541d8 100644 --- a/Core/Utils/TimeUtil.cs +++ b/Core/Utils/TimeUtil.cs @@ -184,4 +184,16 @@ public class TimeUtil { return DateTimeOffset.FromUnixTimeMilliseconds(timeStamp).DateTime; } + + /// + /// Takes a timestamp and gets difference between Epoch time and time provided resulting in a unixtimestamp (date defaults to utcnow) + /// + /// + /// + public long GetTimeStampFromEpoch(DateTime? date = null) + { + var dateToCompare = date ?? DateTime.UtcNow; + return (long)(dateToCompare - DateTime.UnixEpoch).TotalSeconds; + } + }