using Content.Shared.Chemistry.Components; using Content.Shared.DoAfter; using Content.Shared.FixedPoint; using Content.Shared.Inventory; using Content.Shared.Nutrition.Components; using Content.Shared.Nutrition.Prototypes; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; namespace Content.Shared.Nutrition; /// /// Raised on an entity that is trying to be ingested to see if it has universal blockers preventing it from being /// ingested. /// [ByRefEvent] public record struct IngestibleEvent(bool Cancelled = false); /// /// Raised on an entity with the to check if anything is stopping /// another entity from consuming the delicious reagents stored inside. /// /// The entity trying to feed us to an entity. [ByRefEvent] public record struct EdibleEvent(EntityUid User) { public Entity? Solution = null; public TimeSpan Time = TimeSpan.Zero; public bool Cancelled; } /// /// Raised when an entity is trying to ingest an entity to see if it has any component that can ingest it. /// /// Did a system successfully ingest this item? /// The entity that is trying to feed and therefore raising the event /// What are we trying to ingest? /// Should we actually try and ingest? Or are we just testing if it's even possible [ByRefEvent] public record struct AttemptIngestEvent(EntityUid User, EntityUid Ingested, bool Ingest, bool Handled = false); /// /// Raised on an entity that is consuming another entity to see if there is anything attached to the entity /// that is preventing it from doing the consumption. /// [ByRefEvent] public record struct IngestionAttemptEvent(SlotFlags TargetSlots, bool Cancelled = false) : IInventoryRelayEvent { /// /// The equipment that is blocking consumption. Should only be non-null if the event was canceled. /// public EntityUid? Blocker = null; } /// /// Raised on an entity that is trying to be digested, aka turned from an entity into reagents. /// Returns its digestive properties or how difficult it is to convert to reagents. /// /// This method is currently needed for backwards compatibility with food and drink component. /// It also might be needed in the event items like trash and plushies have their edible component removed. /// There's no way to know whether this event will be made obsolete or not after Food and Drink Components /// are removed until after a proper body and digestion rework. Oh well! /// [ByRefEvent] public record struct IsDigestibleEvent() { public bool Digestible = false; public bool SpecialDigestion = false; // If this is true, SpecialDigestion will be ignored public bool Universal = false; // If it requires special digestion then it has to be digestible... public void AddDigestible(bool special) { SpecialDigestion = special; Digestible = true; } // This should only be used for if you're trying to drink pure reagents from a puddle or cup or something... public void UniversalDigestion() { Universal = true; Digestible = true; } } /// /// Do After Event for trying to put food solution into stomach entity. /// [Serializable, NetSerializable] public sealed partial class EatingDoAfterEvent : SimpleDoAfterEvent; /// /// We use this to determine if an entity should abort giving up its reagents at the last minute, /// as well as specifying how much of its reagents it should give up including minimums and maximums. /// If minimum exceeds the maximum, the event will abort. /// /// The minimum amount we can transfer. /// The maximum amount we can transfer. /// The solution we are transferring. [ByRefEvent] public record struct BeforeIngestedEvent(FixedPoint2 Min, FixedPoint2 Max, Solution? Solution) { // How much we would like to transfer, gets clamped by Min and Max. public FixedPoint2 Transfer; // Whether this event, and therefore eat attempt, should be cancelled. public bool Cancelled; // When and if we eat this solution, should we actually remove solution or should it get replaced? // This bool basically only exists because of stackable system. public bool Refresh; public bool TryNewMinimum(FixedPoint2 newMin) { if (newMin > Max) return false; Min = newMin; return true; } public bool TryNewMaximum(FixedPoint2 newMax) { if (newMax < Min) return false; Min = newMax; return true; } } /// /// Raised on an entity while it is eating /// /// The item being ingested /// The solution being ingested /// Whether or not we're being forced [ByRefEvent] public record struct IngestingEvent(EntityUid Food, Solution Split, bool ForceFed); /// /// Raised on an entity when it is being made to be eaten. /// /// Who is doing the action? /// Who is doing the eating? /// The solution we're currently eating. /// Whether we're being fed by someone else, checkec enough I might as well pass it. [ByRefEvent] public record struct IngestedEvent(EntityUid User, EntityUid Target, Solution Split, bool ForceFed) { // Should we destroy the ingested entity? public bool Destroy; // Has this eaten event been handled? Used to prevent duplicate flavor popups and sound effects. public bool Handled; // Should we try eating again? public bool Repeat; } /// /// Raised directed at the food after finishing eating it and before it's deleted. /// [ByRefEvent] public readonly record struct FullyEatenEvent(EntityUid User) { /// /// The entity that ate the food. /// public readonly EntityUid User = User; } /// /// Returns a list of Utensils that can be used to consume the entity, as well as a list of required types. /// [ByRefEvent] public record struct GetUtensilsEvent() { public UtensilType Types = UtensilType.None; public UtensilType RequiredTypes = UtensilType.None; // Forces you to add to both lists if a utensil is required. public void AddRequiredTypes(UtensilType type) { RequiredTypes |= type; Types |= type; } } /// /// Tries to get the best fitting edible type for an entity. /// [ByRefEvent] public record struct GetEdibleTypeEvent { public ProtoId? Type { get; private set; } public void SetPrototype([ForbidLiteral] ProtoId proto) { Type = proto; } } /// /// Raised directed at the food being sliced before it's deleted. /// Cancel this if you want to do something special before a food is deleted. /// public sealed class BeforeFullySlicedEvent : CancellableEntityEventArgs { /// /// The person slicing the food. /// public EntityUid User; }