using Content.Shared.Alert; using Content.Shared.Damage; using Content.Shared.Nutrition.EntitySystems; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Generic; namespace Content.Shared.Nutrition.Components; [RegisterComponent, NetworkedComponent, Access(typeof(HungerSystem))] [AutoGenerateComponentState(fieldDeltas: true), AutoGenerateComponentPause] public sealed partial class HungerComponent : Component { /// /// The hunger value as authoritatively set by the server as of . /// This value should be updated relatively infrequently. To get the current hunger, which changes with each update, /// use . /// [DataField, ViewVariables(VVAccess.ReadOnly)] [AutoNetworkedField] public float LastAuthoritativeHungerValue; /// /// The time at which was last updated. /// [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)] [AutoNetworkedField] public TimeSpan LastAuthoritativeHungerChangeTime; /// /// The base amount at which decays. /// /// Any time this is modified, should be called. [DataField("baseDecayRate"), ViewVariables(VVAccess.ReadWrite)] public float BaseDecayRate = 0.01666666666f; /// /// The actual amount at which decays. /// Affected by /// /// Any time this is modified, should be called. [DataField("actualDecayRate"), ViewVariables(VVAccess.ReadWrite)] [AutoNetworkedField] public float ActualDecayRate; /// /// The last threshold this entity was at. /// Stored in order to prevent recalculating /// [DataField("lastThreshold"), ViewVariables(VVAccess.ReadWrite)] [AutoNetworkedField] public HungerThreshold LastThreshold; /// /// The current hunger threshold the entity is at /// /// Any time this is modified, should be called. [DataField("currentThreshold"), ViewVariables(VVAccess.ReadWrite)] [AutoNetworkedField] public HungerThreshold CurrentThreshold; /// /// A dictionary relating HungerThreshold to the amount of current hunger needed for each one /// [DataField("thresholds", customTypeSerializer: typeof(DictionarySerializer))] [AutoNetworkedField] public Dictionary Thresholds = new() { { HungerThreshold.Overfed, 200.0f }, { HungerThreshold.Okay, 150.0f }, { HungerThreshold.Peckish, 100.0f }, { HungerThreshold.Starving, 50.0f }, { HungerThreshold.Dead, 0.0f } }; /// /// A dictionary relating hunger thresholds to corresponding alerts. /// [DataField("hungerThresholdAlerts")] [AutoNetworkedField] public Dictionary> HungerThresholdAlerts = new() { { HungerThreshold.Peckish, "Peckish" }, { HungerThreshold.Starving, "Starving" }, { HungerThreshold.Dead, "Starving" } }; [DataField] public ProtoId HungerAlertCategory = "Hunger"; /// /// A dictionary relating HungerThreshold to how much they modify . /// [DataField("hungerThresholdDecayModifiers", customTypeSerializer: typeof(DictionarySerializer))] [AutoNetworkedField] public Dictionary HungerThresholdDecayModifiers = new() { { HungerThreshold.Overfed, 1.2f }, { HungerThreshold.Okay, 1f }, { HungerThreshold.Peckish, 0.8f }, { HungerThreshold.Starving, 0.6f }, { HungerThreshold.Dead, 0.6f } }; /// /// The amount of slowdown applied when an entity is starving /// [DataField("starvingSlowdownModifier"), ViewVariables(VVAccess.ReadWrite)] [AutoNetworkedField] public float StarvingSlowdownModifier = 0.75f; /// /// Damage dealt when your current threshold is at HungerThreshold.Dead /// [DataField("starvationDamage")] public DamageSpecifier? StarvationDamage; /// /// The time when the hunger threshold will update next. /// [DataField("nextUpdateTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)] [AutoNetworkedField] [AutoPausedField] public TimeSpan NextThresholdUpdateTime; /// /// The time between each hunger threshold update. /// [ViewVariables(VVAccess.ReadWrite)] [AutoNetworkedField] public TimeSpan ThresholdUpdateRate = TimeSpan.FromSeconds(1); } [Serializable, NetSerializable] public enum HungerThreshold : byte { Overfed = 1 << 3, Okay = 1 << 2, Peckish = 1 << 1, Starving = 1 << 0, Dead = 0, }