diff --git a/Content.Server/NPC/HTN/Preconditions/HungryPrecondition.cs b/Content.Server/NPC/HTN/Preconditions/HungryPrecondition.cs new file mode 100644 index 0000000000..9f0a46b63b --- /dev/null +++ b/Content.Server/NPC/HTN/Preconditions/HungryPrecondition.cs @@ -0,0 +1,26 @@ +using Content.Shared.Hands.Components; +using Content.Shared.Nutrition.Components; +using Robust.Shared.Prototypes; + +namespace Content.Server.NPC.HTN.Preconditions; + +/// +/// Returns true if the active hand entity has the specified components. +/// +public sealed partial class HungryPrecondition : HTNPrecondition +{ + [Dependency] private readonly IEntityManager _entManager = default!; + + [DataField(required: true)] + public HungerThreshold MinHungerState = HungerThreshold.Starving; + + public override bool IsMet(NPCBlackboard blackboard) + { + if (!blackboard.TryGetValue(NPCBlackboard.Owner, out var owner, _entManager)) + { + return false; + } + + return _entManager.TryGetComponent(owner, out var hunger) ? hunger.CurrentThreshold <= MinHungerState : false; + } +} diff --git a/Content.Server/NPC/HTN/Preconditions/ThirstyPrecondition.cs b/Content.Server/NPC/HTN/Preconditions/ThirstyPrecondition.cs new file mode 100644 index 0000000000..97206dc910 --- /dev/null +++ b/Content.Server/NPC/HTN/Preconditions/ThirstyPrecondition.cs @@ -0,0 +1,26 @@ +using Content.Shared.Hands.Components; +using Content.Shared.Nutrition.Components; +using Robust.Shared.Prototypes; + +namespace Content.Server.NPC.HTN.Preconditions; + +/// +/// Returns true if the active hand entity has the specified components. +/// +public sealed partial class ThirstyPrecondition : HTNPrecondition +{ + [Dependency] private readonly IEntityManager _entManager = default!; + + [DataField(required: true)] + public ThirstThreshold MinThirstState = ThirstThreshold.Parched; + + public override bool IsMet(NPCBlackboard blackboard) + { + if (!blackboard.TryGetValue(NPCBlackboard.Owner, out var owner, _entManager)) + { + return false; + } + + return _entManager.TryGetComponent(owner, out var thirst) ? thirst.CurrentThirstThreshold <= MinThirstState : false; + } +} diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 8f8cb59d5e..74cf35322d 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -1305,7 +1305,17 @@ Dead: Base: splat-0 - type: Food + - type: Thirst + startingThirst: 25 # spawn with Okay thirst state + thresholds: + OverHydrated: 35 + Okay: 25 + Thirsty: 15 + Parched: 10 + Dead: 0 + baseDecayRate: 0.04 - type: Hunger + currentHunger: 25 # spawn with Okay hunger state thresholds: Overfed: 35 Okay: 25 diff --git a/Resources/Prototypes/NPCs/nutrition.yml b/Resources/Prototypes/NPCs/nutrition.yml index da64989c33..dea065c34f 100644 --- a/Resources/Prototypes/NPCs/nutrition.yml +++ b/Resources/Prototypes/NPCs/nutrition.yml @@ -4,6 +4,9 @@ # Picks a nearby food, moves into range, then eats it and waits the idle time. - tasks: - !type:HTNPrimitiveTask + preconditions: + - !type:HungryPrecondition + minHungerState: Starving # See HungerThreshold enum operator: !type:UtilityOperator proto: NearbyFood @@ -31,6 +34,9 @@ # Picks nearby drink then consumes it and waits idle time - tasks: - !type:HTNPrimitiveTask + preconditions: + - !type:ThirstyPrecondition + minThirstState: Parched # See ThirstThreshold enum operator: !type:UtilityOperator proto: NearbyDrink