Reduce network burden of the hunger system (#32986)

* reduce network burden of the hunger system

* explicit start + last updated

* remove auto reformat changes to otherwise untouched code

add clamp helper

* imagine making breaking changes, documenting them, and then not thinking to check the yaml

* comments

* Remove unused net manager in hunger system
Remove lastAuthoritativeHungerValue from prototypes
This commit is contained in:
Centronias
2024-12-18 05:06:02 -08:00
committed by GitHub
parent 87f39af1cf
commit 6b99493e80
9 changed files with 79 additions and 32 deletions

View File

@@ -6,6 +6,7 @@ using Content.Shared.Movement.Systems;
using Content.Shared.Nutrition.Components;
using Content.Shared.Rejuvenate;
using Content.Shared.StatusIcon;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;
@@ -72,6 +73,16 @@ public sealed class HungerSystem : EntitySystem
SetHunger(uid, component.Thresholds[HungerThreshold.Okay], component);
}
/// <summary>
/// Gets the current hunger value of the given <see cref="HungerComponent"/>.
/// </summary>
public float GetHunger(HungerComponent component)
{
var dt = _timing.CurTime - component.LastAuthoritativeHungerChangeTime;
var value = component.LastAuthoritativeHungerValue - (float)dt.TotalSeconds * component.ActualDecayRate;
return ClampHungerWithinThresholds(component, value);
}
/// <summary>
/// Adds to the current hunger of an entity by the specified value
/// </summary>
@@ -82,7 +93,7 @@ public sealed class HungerSystem : EntitySystem
{
if (!Resolve(uid, ref component))
return;
SetHunger(uid, component.CurrentHunger + amount, component);
SetHunger(uid, GetHunger(component) + amount, component);
}
/// <summary>
@@ -95,11 +106,23 @@ public sealed class HungerSystem : EntitySystem
{
if (!Resolve(uid, ref component))
return;
component.CurrentHunger = Math.Clamp(amount,
component.Thresholds[HungerThreshold.Dead],
component.Thresholds[HungerThreshold.Overfed]);
SetAuthoritativeHungerValue((uid, component), amount);
UpdateCurrentThreshold(uid, component);
Dirty(uid, component);
}
/// <summary>
/// Sets <see cref="HungerComponent.LastAuthoritativeHungerValue"/> and
/// <see cref="HungerComponent.LastAuthoritativeHungerChangeTime"/>, and dirties this entity. This "resets" the
/// starting point for <see cref="GetHunger"/>'s calculation.
/// </summary>
/// <param name="entity">The entity whose hunger will be set.</param>
/// <param name="value">The value to set the entity's hunger to.</param>
private void SetAuthoritativeHungerValue(Entity<HungerComponent> entity, float value)
{
entity.Comp.LastAuthoritativeHungerChangeTime = _timing.CurTime;
entity.Comp.LastAuthoritativeHungerValue = ClampHungerWithinThresholds(entity.Comp, value);
Dirty(entity);
}
private void UpdateCurrentThreshold(EntityUid uid, HungerComponent? component = null)
@@ -112,7 +135,6 @@ public sealed class HungerSystem : EntitySystem
return;
component.CurrentThreshold = calculatedHungerThreshold;
DoHungerThresholdEffects(uid, component);
Dirty(uid, component);
}
private void DoHungerThresholdEffects(EntityUid uid, HungerComponent? component = null, bool force = false)
@@ -140,6 +162,7 @@ public sealed class HungerSystem : EntitySystem
if (component.HungerThresholdDecayModifiers.TryGetValue(component.CurrentThreshold, out var modifier))
{
component.ActualDecayRate = component.BaseDecayRate * modifier;
SetAuthoritativeHungerValue((uid, component), GetHunger(component));
}
component.LastThreshold = component.CurrentThreshold;
@@ -167,7 +190,7 @@ public sealed class HungerSystem : EntitySystem
/// <returns></returns>
public HungerThreshold GetHungerThreshold(HungerComponent component, float? food = null)
{
food ??= component.CurrentHunger;
food ??= GetHunger(component);
var result = HungerThreshold.Dead;
var value = component.Thresholds[HungerThreshold.Overfed];
foreach (var threshold in component.Thresholds)
@@ -178,6 +201,7 @@ public sealed class HungerSystem : EntitySystem
value = threshold.Value;
}
}
return result;
}
@@ -229,6 +253,13 @@ public sealed class HungerSystem : EntitySystem
return prototype != null;
}
private static float ClampHungerWithinThresholds(HungerComponent component, float hungerValue)
{
return Math.Clamp(hungerValue,
component.Thresholds[HungerThreshold.Dead],
component.Thresholds[HungerThreshold.Overfed]);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
@@ -236,13 +267,12 @@ public sealed class HungerSystem : EntitySystem
var query = EntityQueryEnumerator<HungerComponent>();
while (query.MoveNext(out var uid, out var hunger))
{
if (_timing.CurTime < hunger.NextUpdateTime)
if (_timing.CurTime < hunger.NextThresholdUpdateTime)
continue;
hunger.NextUpdateTime = _timing.CurTime + hunger.UpdateRate;
hunger.NextThresholdUpdateTime = _timing.CurTime + hunger.ThresholdUpdateRate;
ModifyHunger(uid, -hunger.ActualDecayRate, hunger);
UpdateCurrentThreshold(uid, hunger);
DoContinuousHungerEffects(uid, hunger);
}
}
}