Task/food hud (#19312)
* security HUD now shows a job icon on entities with a body * thirst goggles * set starting hud gear * fix build * remove from starting gear * remove * replace * fix thirst and hunger icons * update icons * space * space * ] * ] * fix build * fix comments * fix * spacing * field * move more namespaces * use AutoGenerateComponentState * comments * fix build * not all fields * comments * unpaused * fix Dirty warning --------- Co-authored-by: Slava0135 <super.novalskiy_0135@inbox.ru>
58
Content.Client/Overlays/ShowHungerIconsSystem.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using Content.Shared.Nutrition.Components;
|
||||
using Content.Shared.Overlays;
|
||||
using Content.Shared.StatusIcon;
|
||||
using Content.Shared.StatusIcon.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Overlays;
|
||||
|
||||
public sealed class ShowHungerIconsSystem : EquipmentHudSystem<ShowHungerIconsComponent>
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeMan = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<HungerComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
|
||||
}
|
||||
|
||||
private void OnGetStatusIconsEvent(EntityUid uid, HungerComponent hungerComponent, ref GetStatusIconsEvent args)
|
||||
{
|
||||
if (!IsActive || args.InContainer)
|
||||
return;
|
||||
|
||||
var healthIcons = DecideHungerIcon(uid, hungerComponent);
|
||||
|
||||
args.StatusIcons.AddRange(healthIcons);
|
||||
}
|
||||
|
||||
private IReadOnlyList<StatusIconPrototype> DecideHungerIcon(EntityUid uid, HungerComponent hungerComponent)
|
||||
{
|
||||
var result = new List<StatusIconPrototype>();
|
||||
|
||||
switch (hungerComponent.CurrentThreshold)
|
||||
{
|
||||
case HungerThreshold.Overfed:
|
||||
if (_prototypeMan.TryIndex<StatusIconPrototype>("HungerIconOverfed", out var overfed))
|
||||
{
|
||||
result.Add(overfed);
|
||||
}
|
||||
break;
|
||||
case HungerThreshold.Peckish:
|
||||
if (_prototypeMan.TryIndex<StatusIconPrototype>("HungerIconPeckish", out var peckish))
|
||||
{
|
||||
result.Add(peckish);
|
||||
}
|
||||
break;
|
||||
case HungerThreshold.Starving:
|
||||
if (_prototypeMan.TryIndex<StatusIconPrototype>("HungerIconStarving", out var starving))
|
||||
{
|
||||
result.Add(starving);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
58
Content.Client/Overlays/ShowThirstIconsSystem.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using Content.Shared.Nutrition.Components;
|
||||
using Content.Shared.Overlays;
|
||||
using Content.Shared.StatusIcon;
|
||||
using Content.Shared.StatusIcon.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Overlays;
|
||||
|
||||
public sealed class ShowThirstIconsSystem : EquipmentHudSystem<ShowThirstIconsComponent>
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeMan = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ThirstComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
|
||||
}
|
||||
|
||||
private void OnGetStatusIconsEvent(EntityUid uid, ThirstComponent thirstComponent, ref GetStatusIconsEvent args)
|
||||
{
|
||||
if (!IsActive || args.InContainer)
|
||||
return;
|
||||
|
||||
var healthIcons = DecideThirstIcon(uid, thirstComponent);
|
||||
|
||||
args.StatusIcons.AddRange(healthIcons);
|
||||
}
|
||||
|
||||
private IReadOnlyList<StatusIconPrototype> DecideThirstIcon(EntityUid uid, ThirstComponent thirstComponent)
|
||||
{
|
||||
var result = new List<StatusIconPrototype>();
|
||||
|
||||
switch (thirstComponent.CurrentThirstThreshold)
|
||||
{
|
||||
case ThirstThreshold.OverHydrated:
|
||||
if (_prototypeMan.TryIndex<StatusIconPrototype>("ThirstIconOverhydrated", out var overhydrated))
|
||||
{
|
||||
result.Add(overhydrated);
|
||||
}
|
||||
break;
|
||||
case ThirstThreshold.Thirsty:
|
||||
if (_prototypeMan.TryIndex<StatusIconPrototype>("ThirstIconThirsty", out var thirsty))
|
||||
{
|
||||
result.Add(thirsty);
|
||||
}
|
||||
break;
|
||||
case ThirstThreshold.Parched:
|
||||
if (_prototypeMan.TryIndex<StatusIconPrototype>("ThirstIconParched", out var parched))
|
||||
{
|
||||
result.Add(parched);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Server.Nutrition.Components;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Server.Nutrition.EntitySystems;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Nutrition.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Chemistry.ReagentEffects
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Server.Fluids.Components;
|
||||
using Content.Server.Fluids.EntitySystems;
|
||||
using Content.Server.Forensics;
|
||||
using Content.Server.Nutrition.Components;
|
||||
using Content.Server.Nutrition.EntitySystems;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Stunnable;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Fluids.Components;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Nutrition.Components;
|
||||
using Content.Shared.Nutrition.EntitySystems;
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
using Content.Shared.Alert;
|
||||
|
||||
namespace Content.Server.Nutrition.Components
|
||||
{
|
||||
[Flags]
|
||||
public enum ThirstThreshold : byte
|
||||
{
|
||||
// Hydrohomies
|
||||
Dead = 0,
|
||||
Parched = 1 << 0,
|
||||
Thirsty = 1 << 1,
|
||||
Okay = 1 << 2,
|
||||
OverHydrated = 1 << 3,
|
||||
}
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class ThirstComponent : Component
|
||||
{
|
||||
// Base stuff
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("baseDecayRate")]
|
||||
public float BaseDecayRate = 0.1f;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float ActualDecayRate;
|
||||
|
||||
// Thirst
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public ThirstThreshold CurrentThirstThreshold;
|
||||
|
||||
public ThirstThreshold LastThirstThreshold;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("startingThirst")]
|
||||
public float CurrentThirst = -1f;
|
||||
|
||||
[DataField("thresholds")]
|
||||
public Dictionary<ThirstThreshold, float> ThirstThresholds { get; private set; } = new()
|
||||
{
|
||||
{ThirstThreshold.OverHydrated, 600.0f},
|
||||
{ThirstThreshold.Okay, 450.0f},
|
||||
{ThirstThreshold.Thirsty, 300.0f},
|
||||
{ThirstThreshold.Parched, 150.0f},
|
||||
{ThirstThreshold.Dead, 0.0f},
|
||||
};
|
||||
|
||||
public static readonly Dictionary<ThirstThreshold, AlertType> ThirstThresholdAlertTypes = new()
|
||||
{
|
||||
{ThirstThreshold.Thirsty, AlertType.Thirsty},
|
||||
{ThirstThreshold.Parched, AlertType.Parched},
|
||||
{ThirstThreshold.Dead, AlertType.Parched},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,8 @@ public partial class InventorySystem
|
||||
|
||||
// ComponentActivatedClientSystems
|
||||
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowSecurityIconsComponent>>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowHungerIconsComponent>>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowThirstIconsComponent>>(RelayInventoryEvent);
|
||||
|
||||
SubscribeLocalEvent<InventoryComponent, GetVerbsEvent<EquipmentVerb>>(OnGetStrippingVerbs);
|
||||
}
|
||||
|
||||
@@ -9,12 +9,14 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Generic;
|
||||
namespace Content.Shared.Nutrition.Components;
|
||||
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(HungerSystem))]
|
||||
[AutoGenerateComponentState]
|
||||
public sealed partial class HungerComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The current hunger amount of the entity
|
||||
/// </summary>
|
||||
[DataField("currentHunger"), ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
public float CurrentHunger;
|
||||
|
||||
/// <summary>
|
||||
@@ -28,6 +30,7 @@ public sealed partial class HungerComponent : Component
|
||||
/// Affected by <seealso cref="CurrentThreshold"/>
|
||||
/// </summary>
|
||||
[DataField("actualDecayRate"), ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
public float ActualDecayRate;
|
||||
|
||||
/// <summary>
|
||||
@@ -35,18 +38,21 @@ public sealed partial class HungerComponent : Component
|
||||
/// Stored in order to prevent recalculating
|
||||
/// </summary>
|
||||
[DataField("lastThreshold"), ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
public HungerThreshold LastThreshold;
|
||||
|
||||
/// <summary>
|
||||
/// The current hunger threshold the entity is at
|
||||
/// </summary>
|
||||
[DataField("currentThreshold"), ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
public HungerThreshold CurrentThreshold;
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary relating HungerThreshold to the amount of <see cref="CurrentHunger"/> needed for each one
|
||||
/// </summary>
|
||||
[DataField("thresholds", customTypeSerializer: typeof(DictionarySerializer<HungerThreshold, float>))]
|
||||
[AutoNetworkedField(cloneData: true)]
|
||||
public Dictionary<HungerThreshold, float> Thresholds = new()
|
||||
{
|
||||
{ HungerThreshold.Overfed, 200.0f },
|
||||
@@ -60,6 +66,7 @@ public sealed partial class HungerComponent : Component
|
||||
/// A dictionary relating hunger thresholds to corresponding alerts.
|
||||
/// </summary>
|
||||
[DataField("hungerThresholdAlerts", customTypeSerializer: typeof(DictionarySerializer<HungerThreshold, AlertType>))]
|
||||
[AutoNetworkedField(cloneData: true)]
|
||||
public Dictionary<HungerThreshold, AlertType> HungerThresholdAlerts = new()
|
||||
{
|
||||
{ HungerThreshold.Peckish, AlertType.Peckish },
|
||||
@@ -71,6 +78,7 @@ public sealed partial class HungerComponent : Component
|
||||
/// A dictionary relating HungerThreshold to how much they modify <see cref="BaseDecayRate"/>.
|
||||
/// </summary>
|
||||
[DataField("hungerThresholdDecayModifiers", customTypeSerializer: typeof(DictionarySerializer<HungerThreshold, float>))]
|
||||
[AutoNetworkedField(cloneData: true)]
|
||||
public Dictionary<HungerThreshold, float> HungerThresholdDecayModifiers = new()
|
||||
{
|
||||
{ HungerThreshold.Overfed, 1.2f },
|
||||
@@ -84,6 +92,7 @@ public sealed partial class HungerComponent : Component
|
||||
/// The amount of slowdown applied when an entity is starving
|
||||
/// </summary>
|
||||
[DataField("starvingSlowdownModifier"), ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
public float StarvingSlowdownModifier = 0.75f;
|
||||
|
||||
/// <summary>
|
||||
@@ -96,50 +105,17 @@ public sealed partial class HungerComponent : Component
|
||||
/// The time when the hunger will update next.
|
||||
/// </summary>
|
||||
[DataField("nextUpdateTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
public TimeSpan NextUpdateTime;
|
||||
|
||||
/// <summary>
|
||||
/// The time between each update.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
public TimeSpan UpdateRate = TimeSpan.FromSeconds(1);
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class HungerComponentState : ComponentState
|
||||
{
|
||||
public float CurrentHunger;
|
||||
|
||||
public float BaseDecayRate;
|
||||
|
||||
public float ActualDecayRate;
|
||||
|
||||
public HungerThreshold LastHungerThreshold;
|
||||
|
||||
public HungerThreshold CurrentThreshold;
|
||||
|
||||
public float StarvingSlowdownModifier;
|
||||
|
||||
public TimeSpan NextUpdateTime;
|
||||
|
||||
public HungerComponentState(float currentHunger,
|
||||
float baseDecayRate,
|
||||
float actualDecayRate,
|
||||
HungerThreshold lastHungerThreshold,
|
||||
HungerThreshold currentThreshold,
|
||||
float starvingSlowdownModifier,
|
||||
TimeSpan nextUpdateTime)
|
||||
{
|
||||
CurrentHunger = currentHunger;
|
||||
BaseDecayRate = baseDecayRate;
|
||||
ActualDecayRate = actualDecayRate;
|
||||
LastHungerThreshold = lastHungerThreshold;
|
||||
CurrentThreshold = currentThreshold;
|
||||
StarvingSlowdownModifier = starvingSlowdownModifier;
|
||||
NextUpdateTime = nextUpdateTime;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum HungerThreshold : byte
|
||||
{
|
||||
|
||||
78
Content.Shared/Nutrition/Components/ThirstComponent.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using Content.Server.Nutrition.EntitySystems;
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Shared.Nutrition.Components;
|
||||
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(ThirstSystem))]
|
||||
[AutoGenerateComponentState]
|
||||
public sealed partial class ThirstComponent : Component
|
||||
{
|
||||
// Base stuff
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("baseDecayRate")]
|
||||
[AutoNetworkedField]
|
||||
public float BaseDecayRate = 0.1f;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
public float ActualDecayRate;
|
||||
|
||||
// Thirst
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
[AutoNetworkedField]
|
||||
public ThirstThreshold CurrentThirstThreshold;
|
||||
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
[AutoNetworkedField]
|
||||
public ThirstThreshold LastThirstThreshold;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("startingThirst")]
|
||||
[AutoNetworkedField]
|
||||
public float CurrentThirst = -1f;
|
||||
|
||||
/// <summary>
|
||||
/// The time when the hunger will update next.
|
||||
/// </summary>
|
||||
[DataField("nextUpdateTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
public TimeSpan NextUpdateTime;
|
||||
|
||||
/// <summary>
|
||||
/// The time between each update.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
public TimeSpan UpdateRate = TimeSpan.FromSeconds(1);
|
||||
|
||||
[DataField("thresholds")]
|
||||
[AutoNetworkedField(cloneData: true)]
|
||||
public Dictionary<ThirstThreshold, float> ThirstThresholds = new()
|
||||
{
|
||||
{ThirstThreshold.OverHydrated, 600.0f},
|
||||
{ThirstThreshold.Okay, 450.0f},
|
||||
{ThirstThreshold.Thirsty, 300.0f},
|
||||
{ThirstThreshold.Parched, 150.0f},
|
||||
{ThirstThreshold.Dead, 0.0f},
|
||||
};
|
||||
|
||||
public static readonly Dictionary<ThirstThreshold, AlertType> ThirstThresholdAlertTypes = new()
|
||||
{
|
||||
{ThirstThreshold.Thirsty, AlertType.Thirsty},
|
||||
{ThirstThreshold.Parched, AlertType.Parched},
|
||||
{ThirstThreshold.Dead, AlertType.Parched},
|
||||
};
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ThirstThreshold : byte
|
||||
{
|
||||
// Hydrohomies
|
||||
Dead = 0,
|
||||
Parched = 1 << 0,
|
||||
Thirsty = 1 << 1,
|
||||
Okay = 1 << 2,
|
||||
OverHydrated = 1 << 3,
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Nutrition.Components;
|
||||
using Content.Shared.Rejuvenate;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -24,8 +23,6 @@ public sealed class HungerSystem : EntitySystem
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<HungerComponent, ComponentGetState>(OnGetState);
|
||||
SubscribeLocalEvent<HungerComponent, ComponentHandleState>(OnHandleState);
|
||||
SubscribeLocalEvent<HungerComponent, EntityUnpausedEvent>(OnUnpaused);
|
||||
SubscribeLocalEvent<HungerComponent, MapInitEvent>(OnMapInit);
|
||||
SubscribeLocalEvent<HungerComponent, ComponentShutdown>(OnShutdown);
|
||||
@@ -33,30 +30,6 @@ public sealed class HungerSystem : EntitySystem
|
||||
SubscribeLocalEvent<HungerComponent, RejuvenateEvent>(OnRejuvenate);
|
||||
}
|
||||
|
||||
private void OnGetState(EntityUid uid, HungerComponent component, ref ComponentGetState args)
|
||||
{
|
||||
args.State = new HungerComponentState(component.CurrentHunger,
|
||||
component.BaseDecayRate,
|
||||
component.ActualDecayRate,
|
||||
component.LastThreshold,
|
||||
component.CurrentThreshold,
|
||||
component.StarvingSlowdownModifier,
|
||||
component.NextUpdateTime);
|
||||
}
|
||||
|
||||
private void OnHandleState(EntityUid uid, HungerComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not HungerComponentState state)
|
||||
return;
|
||||
component.CurrentHunger = state.CurrentHunger;
|
||||
component.BaseDecayRate = state.BaseDecayRate;
|
||||
component.ActualDecayRate = state.ActualDecayRate;
|
||||
component.LastThreshold = state.LastHungerThreshold;
|
||||
component.CurrentThreshold = state.CurrentThreshold;
|
||||
component.StarvingSlowdownModifier = state.StarvingSlowdownModifier;
|
||||
component.NextUpdateTime = state.NextUpdateTime;
|
||||
}
|
||||
|
||||
private void OnUnpaused(EntityUid uid, HungerComponent component, ref EntityUnpausedEvent args)
|
||||
{
|
||||
component.NextUpdateTime += args.PausedTime;
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
using Content.Server.Nutrition.Components;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Nutrition.Components;
|
||||
using Content.Shared.Rejuvenate;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Random;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Rejuvenate;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server.Nutrition.EntitySystems;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class ThirstSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
[Dependency] private readonly MovementSpeedModifierSystem _movement = default!;
|
||||
[Dependency] private readonly SharedJetpackSystem _jetpack = default!;
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
private float _accumulatedFrameTime;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -28,6 +29,7 @@ public sealed class ThirstSystem : EntitySystem
|
||||
SubscribeLocalEvent<ThirstComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed);
|
||||
SubscribeLocalEvent<ThirstComponent, ComponentStartup>(OnComponentStartup);
|
||||
SubscribeLocalEvent<ThirstComponent, RejuvenateEvent>(OnRejuvenate);
|
||||
SubscribeLocalEvent<ThirstComponent, EntityUnpausedEvent>(OnUnpaused);
|
||||
}
|
||||
|
||||
private void OnComponentStartup(EntityUid uid, ThirstComponent component, ComponentStartup args)
|
||||
@@ -154,22 +156,30 @@ public sealed class ThirstSystem : EntitySystem
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
_accumulatedFrameTime += frameTime;
|
||||
base.Update(frameTime);
|
||||
|
||||
if (_accumulatedFrameTime > 1)
|
||||
var query = EntityQueryEnumerator<ThirstComponent>();
|
||||
while (query.MoveNext(out var uid, out var thirst))
|
||||
{
|
||||
var query = EntityManager.EntityQueryEnumerator<ThirstComponent>();
|
||||
while (query.MoveNext(out var uid, out var comp))
|
||||
if (_timing.CurTime < thirst.NextUpdateTime)
|
||||
continue;
|
||||
|
||||
thirst.NextUpdateTime += thirst.UpdateRate;
|
||||
|
||||
UpdateThirst(thirst, -thirst.ActualDecayRate);
|
||||
var calculatedThirstThreshold = GetThirstThreshold(thirst, thirst.CurrentThirst);
|
||||
|
||||
if (calculatedThirstThreshold == thirst.CurrentThirstThreshold)
|
||||
continue;
|
||||
|
||||
thirst.CurrentThirstThreshold = calculatedThirstThreshold;
|
||||
UpdateEffects(uid, thirst);
|
||||
Dirty(uid, thirst);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUnpaused(EntityUid uid, ThirstComponent component, ref EntityUnpausedEvent args)
|
||||
{
|
||||
UpdateThirst(comp, - comp.ActualDecayRate);
|
||||
var calculatedThirstThreshold = GetThirstThreshold(comp, comp.CurrentThirst);
|
||||
if (calculatedThirstThreshold != comp.CurrentThirstThreshold)
|
||||
{
|
||||
comp.CurrentThirstThreshold = calculatedThirstThreshold;
|
||||
UpdateEffects(uid, comp);
|
||||
}
|
||||
}
|
||||
_accumulatedFrameTime -= 1;
|
||||
}
|
||||
component.NextUpdateTime += args.PausedTime;
|
||||
}
|
||||
}
|
||||
9
Content.Shared/Overlays/ShowHungerIconsComponent.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Overlays;
|
||||
|
||||
/// <summary>
|
||||
/// This component allows you to see the hungriness of mobs.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class ShowHungerIconsComponent : Component { }
|
||||
@@ -1,10 +1,9 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Overlays
|
||||
{
|
||||
namespace Content.Shared.Overlays;
|
||||
|
||||
/// <summary>
|
||||
/// This component allows you to see job icons above mobs.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class ShowSecurityIconsComponent : Component { }
|
||||
}
|
||||
|
||||
9
Content.Shared/Overlays/ShowThirstIconsComponent.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Overlays;
|
||||
|
||||
/// <summary>
|
||||
/// This component allows you to see the thirstiness of mobs.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class ShowThirstIconsComponent : Component { }
|
||||
@@ -42,6 +42,7 @@
|
||||
sprite: Clothing/Eyes/Hud/beergoggles.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Eyes/Hud/beergoggles.rsi
|
||||
- type: ShowThirstIcons
|
||||
|
||||
- type: entity
|
||||
parent: ClothingEyesBase
|
||||
@@ -53,6 +54,19 @@
|
||||
sprite: Clothing/Eyes/Hud/friedonion.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Eyes/Hud/friedonion.rsi
|
||||
- type: ShowHungerIcons
|
||||
- type: Food
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
food:
|
||||
maxVol: 3
|
||||
reagents:
|
||||
- ReagentId: Nutriment
|
||||
Quantity: 3
|
||||
- type: FlavorProfile
|
||||
flavors:
|
||||
- onion
|
||||
- greasey
|
||||
|
||||
- type: entity
|
||||
parent: ClothingEyesBase
|
||||
@@ -64,6 +78,8 @@
|
||||
sprite: Clothing/Eyes/Hud/onionbeer.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Eyes/Hud/onionbeer.rsi
|
||||
- type: ShowHungerIcons
|
||||
- type: ShowThirstIcons
|
||||
|
||||
- type: entity
|
||||
parent: ClothingEyesBase
|
||||
@@ -75,6 +91,7 @@
|
||||
sprite: Clothing/Eyes/Hud/medonion.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Eyes/Hud/medonion.rsi
|
||||
- type: ShowHungerIcons
|
||||
|
||||
- type: entity
|
||||
parent: ClothingEyesBase
|
||||
@@ -86,6 +103,8 @@
|
||||
sprite: Clothing/Eyes/Hud/medonionbeer.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Eyes/Hud/medonionbeer.rsi
|
||||
- type: ShowHungerIcons
|
||||
- type: ShowThirstIcons
|
||||
|
||||
- type: entity
|
||||
parent: ClothingEyesBase
|
||||
@@ -122,3 +141,5 @@
|
||||
- type: Clothing
|
||||
sprite: Clothing/Eyes/Hud/omni.rsi
|
||||
- type: ShowSecurityIcons
|
||||
- type: ShowHungerIcons
|
||||
- type: ShowThirstIcons
|
||||
|
||||
49
Resources/Prototypes/StatusEffects/hunger.yml
Normal file
@@ -0,0 +1,49 @@
|
||||
#Hunger
|
||||
- type: statusIcon
|
||||
id: HungerIconOverfed
|
||||
priority: 5
|
||||
icon:
|
||||
sprite: Interface/Misc/food_icons.rsi
|
||||
state: overfed
|
||||
locationPreference: Right
|
||||
|
||||
- type: statusIcon
|
||||
id: HungerIconPeckish
|
||||
priority: 5
|
||||
icon:
|
||||
sprite: Interface/Misc/food_icons.rsi
|
||||
state: peckish
|
||||
locationPreference: Right
|
||||
|
||||
- type: statusIcon
|
||||
id: HungerIconStarving
|
||||
priority: 5
|
||||
icon:
|
||||
sprite: Interface/Misc/food_icons.rsi
|
||||
state: starving
|
||||
locationPreference: Right
|
||||
|
||||
#Thirst
|
||||
- type: statusIcon
|
||||
id: ThirstIconOverhydrated
|
||||
priority: 5
|
||||
icon:
|
||||
sprite: Interface/Misc/food_icons.rsi
|
||||
state: overhydrated
|
||||
locationPreference: Left
|
||||
|
||||
- type: statusIcon
|
||||
id: ThirstIconThirsty
|
||||
priority: 5
|
||||
icon:
|
||||
sprite: Interface/Misc/food_icons.rsi
|
||||
state: thirsty
|
||||
locationPreference: Left
|
||||
|
||||
- type: statusIcon
|
||||
id: ThirstIconParched
|
||||
priority: 5
|
||||
icon:
|
||||
sprite: Interface/Misc/food_icons.rsi
|
||||
state: parched
|
||||
locationPreference: Left
|
||||
|
Before Width: | Height: | Size: 292 B After Width: | Height: | Size: 273 B |
|
Before Width: | Height: | Size: 283 B After Width: | Height: | Size: 234 B |
|
Before Width: | Height: | Size: 274 B After Width: | Height: | Size: 237 B |
|
Before Width: | Height: | Size: 296 B After Width: | Height: | Size: 273 B |