using Arch.Core;
using HSchool.Ai;
using HSchool.Content;
namespace HSchool.Simulation;
///
/// Drains needs by × simulated hours while the person is on
/// campus. Off campus, needs do not drain and snaps to max
/// — sleep comes back overnight, hunger does not keep falling at home.
///
public static class NeedDecay
{
private static readonly QueryDescription PeopleWithNeeds =
new QueryDescription().WithAll();
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);
}
});
}
}