acdream/src/AcDream.Core/World/SkyDayGroupSelector.cs

40 lines
1.1 KiB
C#

namespace AcDream.Core.World;
/// <summary>
/// Retail-verbatim day-group selection from
/// <c>SkyDesc::CalcPresentDayGroup @ 0x00500E10</c>.
/// </summary>
public static class SkyDayGroupSelector
{
public static int SelectIndex(
int dayGroupCount,
int absoluteYear,
int daysPerYear,
int dayOfYear,
int? forcedIndex = null)
{
if (dayGroupCount <= 0)
return 0;
if (forcedIndex is >= 0 && forcedIndex < dayGroupCount)
return forcedIndex.Value;
if (dayGroupCount == 1)
return 0;
int seed = unchecked(absoluteYear * daysPerYear + dayOfYear);
int mixed = unchecked(
seed * 0x6A42FDB2 + unchecked((int)0x8ABE1652));
float hash = mixed;
if (mixed < 0)
hash += 4294967296.0f;
const float inverseTwoTo32 = 1.0f / 4294967296.0f;
int index = (int)MathF.Floor(
(float)dayGroupCount * hash * inverseTwoTo32);
// Retail snaps the floating-point upper-edge overflow to zero.
return index < 0 || index >= dayGroupCount ? 0 : index;
}
}