Protocol v8 adds tenths of a °C and precipitation to the clock frame; warmth drains from insulation versus place temperature. Co-authored-by: Cursor <cursoragent@cursor.com>
54 lines
1.8 KiB
C#
54 lines
1.8 KiB
C#
using HSchool.Content;
|
|
using HSchool.People;
|
|
|
|
namespace HSchool.Simulation;
|
|
|
|
/// <summary>
|
|
/// Outdoor temperature and precipitation from a climate preset, the school seed, and the
|
|
/// calendar. Same inputs always produce the same street. Not a tick accumulator — sample it
|
|
/// when the clock label or warmth would move.
|
|
/// </summary>
|
|
public static class WeatherSampler
|
|
{
|
|
private const int DaySalt = 0x57EA11;
|
|
private const int HourSalt = 0x57EA12;
|
|
|
|
public static OutdoorWeather Sample(ClimatePresetDef preset, int schoolSeed, DateTime time)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(preset);
|
|
|
|
var utc = DateTime.SpecifyKind(time, DateTimeKind.Utc);
|
|
var month = utc.Month;
|
|
var norm = MonthNorm(preset, month);
|
|
var dayNumber = DateOnly.FromDateTime(utc).DayNumber;
|
|
var dayNoise = SignedUnit(Seed.Mix(schoolSeed, dayNumber, DaySalt)) * preset.DaySpread;
|
|
var hour = utc.Hour + utc.Minute / 60d + utc.Second / 3600d;
|
|
var diurnal = -Math.Cos((hour - 3d) / 24d * 2d * Math.PI) * preset.HourSpread;
|
|
var temperature = (float)(norm + dayNoise + diurnal);
|
|
|
|
var wet = Unit(Seed.Mix(schoolSeed, dayNumber * 24 + utc.Hour, HourSalt)) < preset.PrecipitationChance;
|
|
var precipitation = !wet
|
|
? Precipitation.None
|
|
: temperature < 0f ? Precipitation.Snow : Precipitation.Rain;
|
|
|
|
return new OutdoorWeather(temperature, precipitation);
|
|
}
|
|
|
|
private static float MonthNorm(ClimatePresetDef preset, int month)
|
|
{
|
|
if (preset.MonthlyNorms.Count != 12)
|
|
{
|
|
return 0f;
|
|
}
|
|
|
|
return preset.MonthlyNorms[month - 1];
|
|
}
|
|
|
|
private static double Unit(int mixed)
|
|
{
|
|
return (uint)mixed / (double)uint.MaxValue;
|
|
}
|
|
|
|
private static double SignedUnit(int mixed) => Unit(mixed) * 2d - 1d;
|
|
}
|