diff --git a/Content.Shared/Animals/UdderSystem.cs b/Content.Shared/Animals/UdderSystem.cs index cb6e5b307f..177fbab2f2 100644 --- a/Content.Shared/Animals/UdderSystem.cs +++ b/Content.Shared/Animals/UdderSystem.cs @@ -1,7 +1,6 @@ using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.DoAfter; -using Content.Shared.Examine; using Content.Shared.IdentityManagement; using Content.Shared.Mobs.Systems; using Content.Shared.Nutrition.Components; @@ -32,7 +31,6 @@ public sealed class UdderSystem : EntitySystem SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent>(AddMilkVerb); SubscribeLocalEvent(OnDoAfter); - SubscribeLocalEvent(OnExamine); } private void OnMapInit(EntityUid uid, UdderComponent component, MapInitEvent args) @@ -140,50 +138,4 @@ public sealed class UdderSystem : EntitySystem }; args.Verbs.Add(verb); } - - /// - /// Defines the text provided on examine. - /// Changes depending on the amount of hunger the target has. - /// - private void OnExamine(Entity entity, ref ExaminedEvent args) - { - - var entityIdentity = Identity.Entity(args.Examined, EntityManager); - - string message; - - // Check if the target has hunger, otherwise return not hungry. - if (!TryComp(entity, out var hunger)) - { - message = Loc.GetString("udder-system-examine-none", ("entity", entityIdentity)); - args.PushMarkup(message); - return; - } - - // Choose the correct examine string based on HungerThreshold. - switch (_hunger.GetHungerThreshold(hunger)) - { - case >= HungerThreshold.Overfed: - message = Loc.GetString("udder-system-examine-overfed", ("entity", entityIdentity)); - break; - - case HungerThreshold.Okay: - message = Loc.GetString("udder-system-examine-okay", ("entity", entityIdentity)); - break; - - case HungerThreshold.Peckish: - message = Loc.GetString("udder-system-examine-hungry", ("entity", entityIdentity)); - break; - - // There's a final hunger threshold called "dead" but animals don't actually die so we'll re-use this. - case <= HungerThreshold.Starving: - message = Loc.GetString("udder-system-examine-starved", ("entity", entityIdentity)); - break; - - default: - return; - } - - args.PushMarkup(message); - } } diff --git a/Content.Shared/Nutrition/Components/ExamineableHungerComponent.cs b/Content.Shared/Nutrition/Components/ExamineableHungerComponent.cs new file mode 100644 index 0000000000..00aba82e58 --- /dev/null +++ b/Content.Shared/Nutrition/Components/ExamineableHungerComponent.cs @@ -0,0 +1,31 @@ +using Content.Shared.Nutrition.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Nutrition.Components; + +/// +/// Adds text to the entity's description box based on its current hunger threshold. +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(ExamineableHungerSystem))] +public sealed partial class ExamineableHungerComponent : Component +{ + /// + /// Dictionary of hunger thresholds to LocIds of the messages to display. + /// + [DataField] + public Dictionary Descriptions = new() + { + { HungerThreshold.Overfed, "examineable-hunger-component-examine-overfed"}, + { HungerThreshold.Okay, "examineable-hunger-component-examine-okay"}, + { HungerThreshold.Peckish, "examineable-hunger-component-examine-peckish"}, + { HungerThreshold.Starving, "examineable-hunger-component-examine-starving"}, + { HungerThreshold.Dead, "examineable-hunger-component-examine-starving"} + }; + + /// + /// LocId of a fallback message to display if the entity has no + /// or does not have a value in for the current threshold. + /// + public LocId NoHungerDescription = "examineable-hunger-component-examine-none"; +} diff --git a/Content.Shared/Nutrition/EntitySystems/ExamineableHungerSystem.cs b/Content.Shared/Nutrition/EntitySystems/ExamineableHungerSystem.cs new file mode 100644 index 0000000000..e0ac767bcf --- /dev/null +++ b/Content.Shared/Nutrition/EntitySystems/ExamineableHungerSystem.cs @@ -0,0 +1,41 @@ +using Content.Shared.Examine; +using Content.Shared.IdentityManagement; +using Content.Shared.Nutrition.Components; + +namespace Content.Shared.Nutrition.EntitySystems; + +/// +public sealed class ExamineableHungerSystem : EntitySystem +{ + [Dependency] private readonly HungerSystem _hunger = default!; + private EntityQuery _hungerQuery; + + public override void Initialize() + { + base.Initialize(); + + _hungerQuery = GetEntityQuery(); + + SubscribeLocalEvent(OnExamine); + } + + /// + /// Defines the text provided on examine. + /// Changes depending on the amount of hunger the target has. + /// + private void OnExamine(Entity entity, ref ExaminedEvent args) + { + var identity = Identity.Entity(entity, EntityManager); + + if (!_hungerQuery.TryComp(entity, out var hungerComp) + || !entity.Comp.Descriptions.TryGetValue(_hunger.GetHungerThreshold(hungerComp), out var locId)) + { + // Use a fallback message if the entity has no HungerComponent + // or is missing a description for the current threshold + locId = entity.Comp.NoHungerDescription; + } + + var msg = Loc.GetString(locId, ("entity", identity)); + args.PushMarkup(msg); + } +} diff --git a/Resources/Locale/en-US/animals/udder/udder-system.ftl b/Resources/Locale/en-US/animals/udder/udder-system.ftl index 959a4fef59..8479ae08bf 100644 --- a/Resources/Locale/en-US/animals/udder/udder-system.ftl +++ b/Resources/Locale/en-US/animals/udder/udder-system.ftl @@ -5,9 +5,3 @@ udder-system-success = You fill {THE($target)} with {$amount}u from the udder. udder-system-dry = The udder is dry. udder-system-verb-milk = Milk - -udder-system-examine-overfed = {CAPITALIZE(SUBJECT($entity))} looks stuffed! -udder-system-examine-okay = {CAPITALIZE(SUBJECT($entity))} looks content. -udder-system-examine-hungry = {CAPITALIZE(SUBJECT($entity))} looks hungry. -udder-system-examine-starved = {CAPITALIZE(SUBJECT($entity))} looks starved! -udder-system-examine-none = {CAPITALIZE(SUBJECT($entity))} seems not to get hungry. diff --git a/Resources/Locale/en-US/nutrition/components/examineable-hunger-component.ftl b/Resources/Locale/en-US/nutrition/components/examineable-hunger-component.ftl new file mode 100644 index 0000000000..d8d9963908 --- /dev/null +++ b/Resources/Locale/en-US/nutrition/components/examineable-hunger-component.ftl @@ -0,0 +1,5 @@ +examineable-hunger-component-examine-overfed = {CAPITALIZE(SUBJECT($entity))} {CONJUGATE-BASIC($entity, "look", "looks")} stuffed! +examineable-hunger-component-examine-okay = {CAPITALIZE(SUBJECT($entity))} {CONJUGATE-BASIC($entity, "look", "looks")} content. +examineable-hunger-component-examine-peckish = {CAPITALIZE(SUBJECT($entity))} {CONJUGATE-BASIC($entity, "look", "looks")} hungry. +examineable-hunger-component-examine-starving = {CAPITALIZE(SUBJECT($entity))} {CONJUGATE-BASIC($entity, "look", "looks")} starved! +examineable-hunger-component-examine-none = {CAPITALIZE(SUBJECT($entity))} {CONJUGATE-BASIC($entity, "seem", "seems")} not to get hungry. diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index e71902db6b..a33529cc48 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -229,6 +229,7 @@ - type: EggLayer eggSpawn: - id: FoodEgg + - type: ExamineableHunger - type: ReplacementAccent accent: chicken - type: SentienceTarget @@ -663,6 +664,7 @@ - type: EggLayer eggSpawn: - id: FoodEgg + - type: ExamineableHunger - type: ReplacementAccent accent: duck - type: SentienceTarget @@ -828,6 +830,7 @@ reagentId: Milk quantityPerUpdate: 25 growthDelay: 30 + - type: ExamineableHunger - type: Butcherable spawned: - id: FoodMeat @@ -984,6 +987,7 @@ reagentId: MilkGoat quantityPerUpdate: 25 growthDelay: 20 + - type: ExamineableHunger - type: Wooly - type: Food solution: wool