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>
60 lines
1.8 KiB
C#
60 lines
1.8 KiB
C#
using Arch.Core;
|
||
using HSchool.Ai;
|
||
using HSchool.Content;
|
||
|
||
namespace HSchool.Simulation;
|
||
|
||
/// <summary>
|
||
/// Drains needs by <see cref="NeedDef.DecayPerHour"/> × simulated hours while the person is on
|
||
/// campus. Off campus, needs do not drain and <see cref="NeedDef.RestoredOffCampus"/> snaps to max
|
||
/// — sleep comes back overnight, hunger does not keep falling at home.
|
||
/// </summary>
|
||
public static class NeedDecay
|
||
{
|
||
private static readonly QueryDescription PeopleWithNeeds =
|
||
new QueryDescription().WithAll<PersonNeeds, Presence>();
|
||
|
||
public static void Apply(World world, DefCatalog catalog, double gameMinutes)
|
||
{
|
||
if (gameMinutes <= 0 || (!catalog.AnyNeedDecays && !catalog.AnyNeedRestoredOffCampus))
|
||
{
|
||
return;
|
||
}
|
||
|
||
var hours = gameMinutes / 60d;
|
||
world.Query(in PeopleWithNeeds, (ref PersonNeeds needs, ref Presence presence) =>
|
||
{
|
||
if (!presence.IsOnCampus)
|
||
{
|
||
foreach (var def in catalog.Needs.Values)
|
||
{
|
||
if (def.Abstract || !def.RestoredOffCampus || !needs.Values.ContainsKey(def.DefName))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
needs.Values[def.DefName] = def.Max;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
if (!catalog.AnyNeedDecays)
|
||
{
|
||
return;
|
||
}
|
||
|
||
foreach (var def in catalog.Needs.Values)
|
||
{
|
||
if (def.Abstract || def.Environmental || !needs.Values.TryGetValue(def.DefName, out var current))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
var next = current - (float)(def.DecayPerHour * hours);
|
||
needs.Values[def.DefName] = Math.Clamp(next, def.Min, def.Max);
|
||
}
|
||
});
|
||
}
|
||
}
|