92 lines
2.1 KiB
C#
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;
|
|
}
|
|
}
|