qstbak/LLib/LLib.GameData/WeatherHelper.cs
2026-08-17 20:29:32 +10:00

92 lines
2.1 KiB
C#

using System;
using Dalamud.Plugin.Services;
using Lumina.Excel;
using Lumina.Excel.Sheets;
namespace LLib.GameData;
public sealed class WeatherHelper
{
public const double WeatherPeriodSeconds = 1400.0;
private readonly IDataManager _dataManager;
public WeatherHelper(IDataManager dataManager)
{
_dataManager = dataManager;
}
public Weather? GetCurrentWeather(uint territoryId)
{
return GetWeatherAtTime(territoryId, DateTimeOffset.UtcNow.ToUnixTimeSeconds());
}
public Weather? GetPreviousWeather(uint territoryId)
{
return GetWeatherAtTime(territoryId, DateTimeOffset.UtcNow.ToUnixTimeSeconds() - 1400);
}
public Weather? GetNextWeather(uint territoryId)
{
return GetWeatherAtTime(territoryId, DateTimeOffset.UtcNow.ToUnixTimeSeconds() + 1400);
}
public static double GetSecondsUntilWeatherChange()
{
long num = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
return 1400.0 - (double)(num % 1400);
}
public Weather? GetWeatherAtTime(uint territoryId, long unixSeconds)
{
TerritoryType? rowOrDefault = _dataManager.GetExcelSheet<TerritoryType>().GetRowOrDefault(territoryId);
if (!rowOrDefault.HasValue)
{
return null;
}
if (!rowOrDefault.Value.WeatherRate.IsValid)
{
return null;
}
WeatherRate value = rowOrDefault.Value.WeatherRate.Value;
uint target = CalculateTarget(unixSeconds);
return ResolveWeather(value, target);
}
internal static uint CalculateTarget(long unixSeconds)
{
long num = unixSeconds / 175;
uint num2 = (uint)((num + 8 - num % 8) % 24);
uint num3 = (uint)((int)(unixSeconds / 4200) * 100) + num2;
uint num4 = (num3 << 11) ^ num3;
return ((num4 >> 8) ^ num4) % 100;
}
private static Weather? ResolveWeather(WeatherRate weatherRate, uint target)
{
Weather? result = null;
int num = 0;
for (int i = 0; i < weatherRate.Rate.Count; i++)
{
if (weatherRate.Rate[i] <= 0)
{
continue;
}
RowRef<Weather> rowRef = weatherRate.Weather[i];
if (rowRef.IsValid)
{
result = rowRef.Value;
}
num += weatherRate.Rate[i];
if (target < num)
{
if (!rowRef.IsValid)
{
return null;
}
return rowRef.Value;
}
}
return result;
}
}