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:
Leonid Pershin
2026-08-20 03:49:40 +03:00
co-authored by Cursor
parent d8f4958167
commit 8e7ab46e79
40 changed files with 1008 additions and 39 deletions
@@ -0,0 +1,73 @@
using HSchool.Content;
using HSchool.People;
namespace HSchool.Simulation;
/// <summary>
/// Worn insulation in °C-equivalent points, summed from apparel currently on the body.
/// Tests that need a bare frost set <see cref="Naked"/> on the entity explicitly.
/// </summary>
public readonly record struct PersonInsulation(float Value)
{
public static PersonInsulation Naked { get; } = new(0f);
public static PersonInsulation FromWorn(DefCatalog catalog, params string[] defNames)
{
ArgumentNullException.ThrowIfNull(catalog);
var sum = 0f;
foreach (var name in defNames)
{
if (catalog.Things.TryGetValue(name, out var thing) && thing.Layers.Count > 0)
{
sum += thing.Insulation;
}
}
return new PersonInsulation(sum);
}
public static PersonInsulation FromPerson(Person person, DefCatalog? catalog)
{
ArgumentNullException.ThrowIfNull(person);
if (catalog is null)
{
return Naked;
}
var worn = WornDefs(person);
return worn.Count == 0 ? Naked : FromWorn(catalog, [.. worn]);
}
private static List<string> WornDefs(Person person)
{
var worn = new List<string>();
if (person.GetType().GetProperty("Items")?.GetValue(person) is not System.Collections.IEnumerable items)
{
return worn;
}
foreach (var item in items)
{
if (item is null)
{
continue;
}
var type = item.GetType();
var def = type.GetProperty("Def")?.GetValue(item) as string;
var location = type.GetProperty("Location")?.GetValue(item) as string
?? type.GetProperty("Place")?.GetValue(item) as string;
if (def is null || location is null)
{
continue;
}
if (location.Equals("worn", StringComparison.OrdinalIgnoreCase))
{
worn.Add(def);
}
}
return worn;
}
}