Sample outdoor weather from the climate preset so people can freeze and the clock can show it.
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>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user