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,81 @@
|
||||
using Arch.Core;
|
||||
using HSchool.Ai;
|
||||
using HSchool.Content;
|
||||
|
||||
namespace HSchool.Simulation;
|
||||
|
||||
/// <summary>
|
||||
/// Drains <c>Warmth</c> from the gap between clothing insulation and the temperature of the
|
||||
/// place the person is in. Off campus the generic need restore already snaps it to max.
|
||||
/// </summary>
|
||||
public static class WarmthDecay
|
||||
{
|
||||
private static readonly QueryDescription People =
|
||||
new QueryDescription().WithAll<PersonNeeds, PersonTraits, PersonInsulation, Presence>();
|
||||
|
||||
public static void Apply(School school, double gameMinutes)
|
||||
{
|
||||
if (gameMinutes <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var catalog = school.Catalog;
|
||||
if (catalog is null || !catalog.Needs.TryGetValue("Warmth", out var warmth) || warmth.Abstract)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var preset = Preset(school, catalog);
|
||||
var hours = gameMinutes / 60d;
|
||||
var world = school.World;
|
||||
world.Query(
|
||||
in People,
|
||||
(ref PersonNeeds needs, ref PersonTraits traits, ref PersonInsulation insulation, ref Presence presence) =>
|
||||
{
|
||||
if (!presence.IsOnCampus || !needs.Values.ContainsKey(warmth.DefName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var place = PlaceClimate.TemperatureC(school, presence.NodeId);
|
||||
var felt = place + insulation.Value * (preset?.InsulationPerC ?? 1f);
|
||||
var center = (preset?.ComfortC ?? 21f) + TraitOffset(catalog, traits);
|
||||
var halfWidth = preset?.ComfortHalfWidthC ?? 3f;
|
||||
var mismatch = Math.Abs(felt - center) - halfWidth;
|
||||
if (mismatch <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var next = needs.Values[warmth.DefName] - (float)(mismatch * warmth.DecayPerHour * hours);
|
||||
needs.Values[warmth.DefName] = Math.Clamp(next, warmth.Min, warmth.Max);
|
||||
});
|
||||
}
|
||||
|
||||
private static ClimatePresetDef? Preset(School school, DefCatalog catalog)
|
||||
{
|
||||
if (school.ClimatePresetId is { } id
|
||||
&& catalog.ClimatePresets.TryGetValue(id, out var preset)
|
||||
&& !preset.Abstract)
|
||||
{
|
||||
return preset;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static float TraitOffset(DefCatalog catalog, PersonTraits traits)
|
||||
{
|
||||
var offset = 0f;
|
||||
foreach (var id in traits.Ids)
|
||||
{
|
||||
if (catalog.Traits.TryGetValue(id, out var trait))
|
||||
{
|
||||
offset += trait.ComfortTemperatureOffset;
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user