From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Fri, 12 Sep 2025 22:26:56 +0000 (+0200) Subject: Delete DrinkComponent, migrate prototypes to EdibleComponent (#40308) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=82e7cb020cfd65cad9ebf226b7a3b52897ba7ad4;p=space-station-14.git Delete DrinkComponent, migrate prototypes to EdibleComponent (#40308) --- diff --git a/Content.Client/Nutrition/EntitySystems/DrinkSystem.cs b/Content.Client/Nutrition/EntitySystems/DrinkSystem.cs deleted file mode 100644 index 16dbecb793..0000000000 --- a/Content.Client/Nutrition/EntitySystems/DrinkSystem.cs +++ /dev/null @@ -1,7 +0,0 @@ -using Content.Shared.Nutrition.EntitySystems; - -namespace Content.Client.Nutrition.EntitySystems; - -public sealed class DrinkSystem : SharedDrinkSystem -{ -} diff --git a/Content.Server/Nutrition/Components/BadDrinkComponent.cs b/Content.Server/Nutrition/Components/BadDrinkComponent.cs index 5b9e5a6297..f114a104d0 100644 --- a/Content.Server/Nutrition/Components/BadDrinkComponent.cs +++ b/Content.Server/Nutrition/Components/BadDrinkComponent.cs @@ -6,7 +6,5 @@ namespace Content.Server.Nutrition.Components; /// This component prevents NPC mobs like mice or cows from wanting to drink something that shouldn't be drank from. /// Including but not limited to: puddles /// -[RegisterComponent, Access(typeof(DrinkSystem))] -public sealed partial class BadDrinkComponent : Component -{ -} +[RegisterComponent] +public sealed partial class BadDrinkComponent : Component; diff --git a/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs b/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs deleted file mode 100644 index 1677f1d822..0000000000 --- a/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Content.Shared.Chemistry.Components; -using Content.Shared.Chemistry.Components.SolutionManager; -using Content.Shared.Chemistry.EntitySystems; -using Content.Shared.Nutrition.Components; -using Content.Shared.Nutrition.EntitySystems; - - -namespace Content.Server.Nutrition.EntitySystems; - -public sealed class DrinkSystem : SharedDrinkSystem -{ - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!; - - public override void Initialize() - { - base.Initialize(); - - // TODO add InteractNoHandEvent for entities like mice. - SubscribeLocalEvent(OnSolutionChange); - SubscribeLocalEvent(OnDrinkInit); - // run before inventory so for bucket it always tries to drink before equipping (when empty) - // run after openable so its always open -> drink - } - - private void OnDrinkInit(Entity entity, ref ComponentInit args) - { - if (TryComp(entity, out var existingDrainable)) - { - // Beakers have Drink component but they should use the existing Drainable - entity.Comp.Solution = existingDrainable.Solution; - } - else - { - _solutionContainer.EnsureSolution(entity.Owner, entity.Comp.Solution, out _); - } - - UpdateAppearance(entity, entity.Comp); - - if (TryComp(entity, out RefillableSolutionComponent? refillComp)) - refillComp.Solution = entity.Comp.Solution; - - if (TryComp(entity, out DrainableSolutionComponent? drainComp)) - drainComp.Solution = entity.Comp.Solution; - } - - private void OnSolutionChange(Entity entity, ref SolutionContainerChangedEvent args) - { - UpdateAppearance(entity, entity.Comp); - } - - public void UpdateAppearance(EntityUid uid, DrinkComponent component) - { - if (!TryComp(uid, out var appearance) || - !HasComp(uid)) - { - return; - } - - var drainAvailable = DrinkVolume(uid, component); - _appearance.SetData(uid, FoodVisuals.Visual, drainAvailable.Float(), appearance); - } -} diff --git a/Content.Shared/Nutrition/Components/DrinkComponent.cs b/Content.Shared/Nutrition/Components/DrinkComponent.cs deleted file mode 100644 index a4d1114379..0000000000 --- a/Content.Shared/Nutrition/Components/DrinkComponent.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Content.Shared.Nutrition.EntitySystems; -using Content.Shared.FixedPoint; -using Robust.Shared.Audio; -using Robust.Shared.GameStates; - -namespace Content.Shared.Nutrition.Components; - -[Obsolete("Migration to Content.Shared.Nutrition.Components.EdibleComponent is required")] -[NetworkedComponent, AutoGenerateComponentState] -[RegisterComponent, Access(typeof(SharedDrinkSystem))] -public sealed partial class DrinkComponent : Component -{ - [DataField] - public string Solution = "drink"; - - [DataField, AutoNetworkedField] - public SoundSpecifier UseSound = new SoundPathSpecifier("/Audio/Items/drink.ogg"); - - [DataField, AutoNetworkedField] - public FixedPoint2 TransferAmount = FixedPoint2.New(5); - - /// - /// How long it takes to drink this yourself. - /// - [DataField, AutoNetworkedField] - public float Delay = 1; - - /// - /// If true, trying to drink when empty will not handle the event. - /// This means other systems such as equipping on use can run. - /// Example usecase is the bucket. - /// - [DataField] - public bool IgnoreEmpty; - - /// - /// This is how many seconds it takes to force feed someone this drink. - /// - [DataField, AutoNetworkedField] - public float ForceFeedDelay = 3; -} diff --git a/Content.Shared/Nutrition/EntitySystems/IngestionSystem.Utensils.cs b/Content.Shared/Nutrition/EntitySystems/IngestionSystem.Utensils.cs index 670fdc8dfb..dfdc03cfe6 100644 --- a/Content.Shared/Nutrition/EntitySystems/IngestionSystem.Utensils.cs +++ b/Content.Shared/Nutrition/EntitySystems/IngestionSystem.Utensils.cs @@ -45,7 +45,7 @@ public sealed partial class IngestionSystem //Prevents food usage with a wrong utensil if ((ev.Types & utensil.Comp.Types) == 0) { - _popup.PopupClient(Loc.GetString("ingestion-try-use-wrong-utensil", ("verb", GetEdibleVerb(target)),("food", target), ("utensil", utensil.Owner)), user, user); + _popup.PopupClient(Loc.GetString("ingestion-try-use-wrong-utensil", ("verb", GetEdibleVerb(target)), ("food", target), ("utensil", utensil.Owner)), user, user); return true; } @@ -66,14 +66,13 @@ public sealed partial class IngestionSystem return; // TODO: Once we have predicted randomness delete this for something sane... - var seed = SharedRandomExtensions.HashCodeCombine(new() {(int)_timing.CurTick.Value, GetNetEntity(entity).Id, GetNetEntity(userUid).Id }); + var seed = SharedRandomExtensions.HashCodeCombine(new() { (int)_timing.CurTick.Value, GetNetEntity(entity).Id, GetNetEntity(userUid).Id }); var rand = new System.Random(seed); if (!rand.Prob(entity.Comp.BreakChance)) return; _audio.PlayPredicted(entity.Comp.BreakSound, userUid, userUid, AudioParams.Default.WithVolume(-2f)); - // Not prediced because no random predicted PredictedDel(entity.Owner); } diff --git a/Content.Shared/Nutrition/EntitySystems/IngestionSystem.cs b/Content.Shared/Nutrition/EntitySystems/IngestionSystem.cs index 284bb866f7..caecc2797e 100644 --- a/Content.Shared/Nutrition/EntitySystems/IngestionSystem.cs +++ b/Content.Shared/Nutrition/EntitySystems/IngestionSystem.cs @@ -137,12 +137,12 @@ public sealed partial class IngestionSystem : EntitySystem private void OnEdibleInit(Entity entity, ref ComponentInit args) { - // TODO: When Food and Drink component are kill make sure to nuke both TryComps and just have it update appearance... - // Beakers, Soap and other items have drainable, and we should be able to eat that solution... - // If I could make drainable properly support sound effects and such I'd just have it use TryIngest itself - // Does this exist just to make tests fail? That way you have the proper yaml??? + // Beakers, Soap and other items have drainable, and we should be able to eat that solution. + // This ensures that tests fail when you configured the yaml from and EdibleComponent uses the wrong solution, if (TryComp(entity, out var existingDrainable)) entity.Comp.Solution = existingDrainable.Solution; + else + _solutionContainer.EnsureSolution(entity.Owner, entity.Comp.Solution, out _); UpdateAppearance(entity); @@ -339,7 +339,7 @@ public sealed partial class IngestionSystem : EntitySystem if (!forceFed) return; - _popup.PopupClient(Loc.GetString("ingestion-other-cannot-ingest-any-more", ("target", entity), ("verb", GetEdibleVerb(food))), args.Target.Value, args.User); + _popup.PopupClient(Loc.GetString("ingestion-other-cannot-ingest-any-more", ("target", entity), ("verb", GetEdibleVerb(food))), args.Target.Value, args.User); return; } @@ -354,7 +354,7 @@ public sealed partial class IngestionSystem : EntitySystem if (!forceFed) return; - _popup.PopupClient(Loc.GetString("ingestion-other-cannot-ingest-any-more", ("target", entity), ("verb", GetEdibleVerb(food))), args.Target.Value, args.User); + _popup.PopupClient(Loc.GetString("ingestion-other-cannot-ingest-any-more", ("target", entity), ("verb", GetEdibleVerb(food))), args.Target.Value, args.User); return; } @@ -462,6 +462,7 @@ public sealed partial class IngestionSystem : EntitySystem _popup.PopupClient(Loc.GetString("edible-force-feed-success-user", ("target", targetName), ("verb", edible.Verb)), args.User, args.User); // log successful forced feeding + // TODO: Use correct verb _adminLogger.Add(LogType.ForceFeed, LogImpact.Medium, $"{ToPrettyString(entity):user} forced {ToPrettyString(args.User):target} to eat {ToPrettyString(entity):food}"); } else @@ -472,6 +473,9 @@ public sealed partial class IngestionSystem : EntitySystem args.User); // log successful voluntary eating + // TODO: Use correct verb + // the past tense is tricky here + // localized admin logs when? _adminLogger.Add(LogType.Ingestion, LogImpact.Low, $"{ToPrettyString(args.User):target} ate {ToPrettyString(entity):food}"); } diff --git a/Content.Shared/Nutrition/EntitySystems/SharedDrinkSystem.cs b/Content.Shared/Nutrition/EntitySystems/SharedDrinkSystem.cs deleted file mode 100644 index fe804dd2e6..0000000000 --- a/Content.Shared/Nutrition/EntitySystems/SharedDrinkSystem.cs +++ /dev/null @@ -1,197 +0,0 @@ -using Content.Shared.Administration.Logs; -using Content.Shared.Chemistry.EntitySystems; -using Content.Shared.Database; -using Content.Shared.FixedPoint; -using Content.Shared.Forensics; -using Content.Shared.IdentityManagement; -using Content.Shared.Interaction; -using Content.Shared.Interaction.Events; -using Content.Shared.Inventory; -using Content.Shared.Nutrition.Components; -using Content.Shared.Popups; -using Content.Shared.Verbs; -using Robust.Shared.Audio; -using Robust.Shared.Audio.Systems; -using Robust.Shared.Player; - -namespace Content.Shared.Nutrition.EntitySystems; - -[Obsolete("Migration to Content.Shared.Nutrition.EntitySystems.IngestionSystem is required")] -public abstract partial class SharedDrinkSystem : EntitySystem -{ - [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; - [Dependency] private readonly FlavorProfileSystem _flavorProfile = default!; - [Dependency] private readonly IngestionSystem _ingestion = default!; - [Dependency] private readonly SharedPopupSystem _popup = default!; - [Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnUseDrinkInHand, after: new[] { typeof(OpenableSystem), typeof(InventorySystem) }); - SubscribeLocalEvent(OnUseDrink); - - SubscribeLocalEvent(OnAttemptShake); - - SubscribeLocalEvent>(AddDrinkVerb); - - SubscribeLocalEvent(OnBeforeDrinkEaten); - SubscribeLocalEvent(OnDrinkEaten); - - SubscribeLocalEvent(OnDrink); - - SubscribeLocalEvent(OnIsDigestible); - - SubscribeLocalEvent(OnGetEdibleType); - } - - protected void OnAttemptShake(Entity entity, ref AttemptShakeEvent args) - { - if (IsEmpty(entity, entity.Comp)) - args.Cancelled = true; - } - - protected FixedPoint2 DrinkVolume(EntityUid uid, DrinkComponent? component = null) - { - if (!Resolve(uid, ref component)) - return FixedPoint2.Zero; - - if (!_solutionContainer.TryGetSolution(uid, component.Solution, out _, out var sol)) - return FixedPoint2.Zero; - - return sol.Volume; - } - - protected bool IsEmpty(EntityUid uid, DrinkComponent? component = null) - { - if (!Resolve(uid, ref component)) - return true; - - return DrinkVolume(uid, component) <= 0; - } - - /// - /// Eat or drink an item - /// - private void OnUseDrinkInHand(Entity entity, ref UseInHandEvent ev) - { - if (ev.Handled) - return; - - ev.Handled = _ingestion.TryIngest(ev.User, ev.User, entity); - } - - /// - /// Feed someone else - /// - private void OnUseDrink(Entity entity, ref AfterInteractEvent args) - { - if (args.Handled || args.Target == null || !args.CanReach) - return; - - args.Handled = _ingestion.TryIngest(args.User, args.Target.Value, entity); - } - - private void AddDrinkVerb(Entity entity, ref GetVerbsEvent args) - { - var user = args.User; - - if (entity.Owner == user || !args.CanInteract || !args.CanAccess) - return; - - if (!_ingestion.TryGetIngestionVerb(user, entity, IngestionSystem.Drink, out var verb)) - return; - - args.Verbs.Add(verb); - } - - private void OnBeforeDrinkEaten(Entity food, ref BeforeIngestedEvent args) - { - if (args.Cancelled) - return; - - // Set it to transfer amount if it exists, otherwise eat the whole volume if possible. - args.Transfer = food.Comp.TransferAmount; - } - - private void OnDrinkEaten(Entity entity, ref IngestedEvent args) - { - if (args.Handled) - return; - - args.Handled = true; - - _audio.PlayPredicted(entity.Comp.UseSound, args.Target, args.User, AudioParams.Default.WithVolume(-2f).WithVariation(0.25f)); - - var flavors = _flavorProfile.GetLocalizedFlavorsMessage(entity.Owner, args.Target, args.Split); - - if (args.ForceFed) - { - var targetName = Identity.Entity(args.Target, EntityManager); - var userName = Identity.Entity(args.User, EntityManager); - - _popup.PopupEntity(Loc.GetString("edible-force-feed-success", ("user", userName), ("verb", _ingestion.GetProtoVerb(IngestionSystem.Drink)), ("flavors", flavors)), entity, entity); - - _popup.PopupClient(Loc.GetString("edible-force-feed-success-user", ("target", targetName), ("verb", _ingestion.GetProtoVerb(IngestionSystem.Drink))), args.User, args.User); - - // log successful forced drinking - _adminLogger.Add(LogType.ForceFeed, LogImpact.Medium, $"{ToPrettyString(entity.Owner):user} forced {ToPrettyString(args.User):target} to drink {ToPrettyString(entity.Owner):drink}"); - } - else - { - _popup.PopupPredicted(Loc.GetString("edible-slurp", ("flavors", flavors)), - Loc.GetString("edible-slurp-other"), - args.User, - args.User); - - // log successful voluntary drinking - _adminLogger.Add(LogType.Ingestion, LogImpact.Low, $"{ToPrettyString(args.User):target} drank {ToPrettyString(entity.Owner):drink}"); - } - - if (_ingestion.GetUsesRemaining(entity, entity.Comp.Solution, args.Split.Volume) <= 0) - return; - - // Leave some of the consumer's DNA on the consumed item... - var ev = new TransferDnaEvent - { - Donor = args.Target, - Recipient = entity, - CanDnaBeCleaned = false, - }; - RaiseLocalEvent(args.Target, ref ev); - - args.Repeat = !args.ForceFed; - } - - private void OnDrink(Entity drink, ref EdibleEvent args) - { - if (args.Cancelled || args.Solution != null) - return; - - if (!_solutionContainer.TryGetSolution(drink.Owner, drink.Comp.Solution, out args.Solution) || IsEmpty(drink)) - { - args.Cancelled = true; - - _popup.PopupClient(Loc.GetString("ingestion-try-use-is-empty", ("entity", drink)), drink, args.User); - return; - } - - args.Time += TimeSpan.FromSeconds(drink.Comp.Delay); - } - - private void OnIsDigestible(Entity ent, ref IsDigestibleEvent args) - { - // Anyone can drink from puddles on the floor! - args.UniversalDigestion(); - } - - private void OnGetEdibleType(Entity ent, ref GetEdibleTypeEvent args) - { - if (args.Type != null) - return; - - args.SetPrototype(IngestionSystem.Drink); - } -} diff --git a/Resources/Maps/plasma.yml b/Resources/Maps/plasma.yml index b5d76a75e0..b2ae035e04 100644 --- a/Resources/Maps/plasma.yml +++ b/Resources/Maps/plasma.yml @@ -83601,37 +83601,41 @@ entities: - type: Transform pos: -45.5,-61.5 parent: 2 - - type: Drink - useSound: !type:SoundPathSpecifier - path: /Audio/Items/drink.ogg + - type: Edible + edible: Drink solution: pool + destroyOnEmpty: false + utensil: Spoon - uid: 16868 components: - type: Transform pos: -44.5,-61.5 parent: 2 - - type: Drink - useSound: !type:SoundPathSpecifier - path: /Audio/Items/drink.ogg + - type: Edible + edible: Drink solution: pool + destroyOnEmpty: false + utensil: Spoon - uid: 16872 components: - type: Transform pos: -46.5,-61.5 parent: 2 - - type: Drink - useSound: !type:SoundPathSpecifier - path: /Audio/Items/drink.ogg + - type: Edible + edible: Drink solution: pool + destroyOnEmpty: false + utensil: Spoon - uid: 16907 components: - type: Transform pos: -44.5,-60.5 parent: 2 - - type: Drink - useSound: !type:SoundPathSpecifier - path: /Audio/Items/drink.ogg + - type: Edible + edible: Drink solution: pool + destroyOnEmpty: false + utensil: Spoon - uid: 17621 components: - type: Transform diff --git a/Resources/Prototypes/Entities/Clothing/Head/misc.yml b/Resources/Prototypes/Entities/Clothing/Head/misc.yml index da0f17f324..511f1e1980 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/misc.yml @@ -320,6 +320,7 @@ solution: drink delay: 0.5 forceFeedDelay: 1.5 + utensil: Spoon - type: FlavorProfile flavors: - water diff --git a/Resources/Prototypes/Entities/Effects/puddle.yml b/Resources/Prototypes/Entities/Effects/puddle.yml index cc3df59c55..4e758e4e1c 100644 --- a/Resources/Prototypes/Entities/Effects/puddle.yml +++ b/Resources/Prototypes/Entities/Effects/puddle.yml @@ -206,6 +206,7 @@ delay: 3 transferAmount: 1 solution: puddle + utensil: None - type: ExaminableSolution solution: puddle locVolume: "examinable-solution-on-examine-volume-puddle" diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml index 22054741e3..3b7569022b 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml @@ -2122,7 +2122,6 @@ id: DrinkTomatoJuice suffix: tomato juice components: - - type: Drink - type: SolutionContainerManager solutions: drink: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/bowl.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/bowl.yml index 1ac5dce0e8..ce82ba1e1b 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/bowl.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/bowl.yml @@ -27,6 +27,7 @@ edible: Drink solution: food destroyOnEmpty: false + utensil: Spoon - type: DamageOnLand damage: types: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/condiments.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/condiments.yml index 7c7df07f78..5cfe12d74a 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/condiments.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/condiments.yml @@ -32,8 +32,11 @@ components: - type: Item size: Tiny - - type: Drink + - type: Edible + edible: Food # usually contains powders like flour or condiments like ketchup solution: food + destroyOnEmpty: false + utensil: Spoon - type: Openable sound: collection: packetOpenSounds @@ -74,6 +77,14 @@ - type: ExaminableSolution exactVolume: true +- type: entity + parent: BaseFoodCondimentPacket + id: BaseFoodCondimentPacketDrink + abstract: true + components: + - type: Edible + edible: Drink # slurping sounds! + - type: entity parent: BaseFoodCondimentPacket id: FoodCondimentPacketAstrotame @@ -103,7 +114,7 @@ fillBaseName: packet-trans- - type: entity - parent: BaseFoodCondimentPacket + parent: BaseFoodCondimentPacketDrink id: FoodCondimentPacketBbq name: BBQ sauce description: Hand wipes not included. @@ -123,7 +134,7 @@ fillBaseName: packet-trans- - type: entity - parent: BaseFoodCondimentPacket + parent: BaseFoodCondimentPacketDrink id: FoodCondimentPacketCornoil name: corn oil description: Corn oil. A delicious oil used in cooking. Made from corn. @@ -143,7 +154,7 @@ fillBaseName: packet-trans- - type: entity - parent: BaseFoodCondimentPacket + parent: BaseFoodCondimentPacketDrink id: FoodCondimentPacketColdsauce name: coldsauce description: Coldsauce. Leaves the tongue numb in its passage. @@ -163,7 +174,7 @@ fillBaseName: packet-trans- - type: entity - parent: BaseFoodCondimentPacket + parent: BaseFoodCondimentPacketDrink id: FoodCondimentPacketHorseradish name: horseradish sauce description: A packet of smelly horseradish sauce. @@ -183,7 +194,7 @@ fillBaseName: packet-solid- - type: entity - parent: BaseFoodCondimentPacket + parent: BaseFoodCondimentPacketDrink id: FoodCondimentPacketHotsauce name: hotsauce description: You can almost TASTE the stomach ulcers now! @@ -203,7 +214,7 @@ fillBaseName: packet-trans- - type: entity - parent: BaseFoodCondimentPacket + parent: BaseFoodCondimentPacketDrink id: FoodCondimentPacketKetchup name: ketchup description: You feel more American already. @@ -223,7 +234,7 @@ fillBaseName: packet-solid- - type: entity - parent: BaseFoodCondimentPacket + parent: BaseFoodCondimentPacketDrink id: FoodCondimentPacketMustard name: mustard description: A condiment made from the ground-up seeds of the Mustard plant. @@ -289,7 +300,7 @@ fillBaseName: packet-solid- - type: entity - parent: BaseFoodCondimentPacket + parent: BaseFoodCondimentPacketDrink id: FoodCondimentPacketSoy name: soy sauce description: A salty soy-based flavoring. @@ -335,8 +346,11 @@ name: condiment bottle description: A thin glass bottle used to store condiments. components: - - type: Drink + - type: Edible + edible: Drink solution: food + destroyOnEmpty: false + utensil: None - type: Openable sound: collection: pop @@ -526,7 +540,7 @@ # Shakers - type: entity - parent: BaseFoodCondiment + parent: BaseFoodCondiment # TODO: This should not inherit TrashOnSolutionEmpty, SpaceGarbage and the price of 0 id: BaseFoodShaker abstract: true name: empty shaker @@ -534,8 +548,11 @@ components: - type: Item size: Tiny - - type: Drink + - type: Edible + edible: Drink solution: food + destroyOnEmpty: false + utensil: None # don't conflict with stirring - type: SolutionContainerManager solutions: food: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml index 76ea3073e5..fda43d65fe 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml @@ -25,10 +25,10 @@ solution: food - type: DrainableSolution solution: food - - type: Drink + - type: Edible + edible: Food # usually contains powders like flour or condiments like ketchup solution: food - useSound: - collection: eating + utensil: Spoon - type: Damageable damageContainer: Inorganic - type: Spillable @@ -224,6 +224,8 @@ reagents: - ReagentId: OilOlive Quantity: 20 + - type: Edible + edible: Drink # slurping sounds! - type: entity parent: ReagentPacketBase diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml index 551ea802ca..563a7810d0 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml @@ -9,14 +9,20 @@ - type: SolutionContainerManager - type: Sprite state: produce - # let cows eat raw produce like wheat and oats - - type: Edible - requiresSpecialDigestion: true - type: Produce - type: PotencyVisuals - type: Appearance - type: Extractable grindableSolutionName: food + +- type: entity + parent: ProduceBase + id: ProduceBaseRuminant + abstract: true + components: + # let cows eat raw produce like wheat and oats + - type: Edible + requiresSpecialDigestion: true - type: Tag tags: - Ruminant @@ -43,7 +49,7 @@ name: wheat bushel description: Sigh... wheat... a-grain? id: WheatBushel - parent: ProduceBase + parent: ProduceBaseRuminant components: - type: Sprite sprite: Objects/Specific/Hydroponics/wheat.rsi @@ -66,7 +72,7 @@ name: meatwheat bushel description: Some blood-drenched wheat stalks. You can crush them into what passes for meat if you squint hard enough. id: MeatwheatBushel - parent: ProduceBase + parent: ProduceBaseRuminant components: - type: Sprite sprite: Objects/Specific/Hydroponics/meatwheat.rsi @@ -90,7 +96,7 @@ name: oat bushel description: Eat oats, do squats. id: OatBushel - parent: ProduceBase + parent: ProduceBaseRuminant components: - type: Sprite sprite: Objects/Specific/Hydroponics/oat.rsi @@ -114,7 +120,7 @@ name: sugarcane description: Sickly sweet. id: Sugarcane - parent: ProduceBase + parent: ProduceBaseRuminant components: - type: Sprite sprite: Objects/Specific/Hydroponics/sugarcane.rsi @@ -226,7 +232,7 @@ name: nettle description: Stingy little prick. id: Nettle - parent: ProduceBase + parent: ProduceBaseRuminant components: - type: Sprite sprite: Objects/Specific/Hydroponics/nettle.rsi @@ -1964,7 +1970,7 @@ name: rice bushel description: Can be ground into rice, perfect for pudding or sake. id: RiceBushel - parent: ProduceBase + parent: ProduceBaseRuminant components: - type: Sprite sprite: Objects/Specific/Hydroponics/rice.rsi @@ -1983,7 +1989,7 @@ name: soybeans description: For those who can't stand seeing good old meat. id: FoodSoybeans - parent: ProduceBase + parent: ProduceBaseRuminant components: - type: Sprite sprite: Objects/Specific/Hydroponics/soybeans.rsi @@ -2047,7 +2053,7 @@ name: koibean description: These beans seem a little bit fishy. id: FoodKoibean - parent: ProduceBase + parent: ProduceBaseRuminant components: - type: Sprite sprite: Objects/Specific/Hydroponics/koibean.rsi diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml index 3ef9e99cd2..de3f8e1003 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml @@ -2,7 +2,7 @@ - type: entity name: cannabis leaves - parent: ProduceBase + parent: ProduceBaseRuminant id: LeavesCannabis description: "Recently legalized in most galaxies." components: @@ -167,7 +167,7 @@ - type: entity name: tea leaves - parent: ProduceBase + parent: ProduceBaseRuminant id: LeavesTea description: "Can be dried out to make tea." components: @@ -184,7 +184,7 @@ - type: entity name: dried tea leaves - parent: ProduceBase + parent: ProduceBaseRuminant id: LeavesTeaDried description: "Dried tea leaves, ready to be ground." components: @@ -200,7 +200,7 @@ - type: entity name: tobacco leaves - parent: ProduceBase + parent: ProduceBaseRuminant id: LeavesTobacco description: "Dry them out to make some smokes." components: @@ -208,6 +208,12 @@ sprite: Objects/Specific/Hydroponics/tobacco.rsi - type: Produce seedId: tobacco + - type: SolutionContainerManager + solutions: + food: + reagents: + - ReagentId: Nicotine + Quantity: 2 - type: entity name: dried tobacco leaves diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml index 9ed5972754..f335244806 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml @@ -5,12 +5,16 @@ suffix: Empty description: A spray bottle with an unscrewable top. components: - - type: Drink + - type: Edible + edible: Drink solution: spray - ignoreEmpty: true + destroyOnEmpty: false + utensil: None + transferAmount: 10 useSound: path: /Audio/Effects/spray3.ogg - transferAmount: 10 + params: + variation: 0.2 - type: Tag tags: - Spray diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml b/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml index 84990b10be..bf3501d604 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml @@ -39,8 +39,11 @@ interfaces: enum.TransferAmountUiKey.Key: type: TransferAmountBoundUserInterface - - type: Drink + - type: Edible + edible: Drink solution: beaker + destroyOnEmpty: false + utensil: Spoon - type: Spillable solution: beaker - type: Appearance diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml index c8c275ac23..8f57307760 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml @@ -24,7 +24,11 @@ - type: SolutionContainerVisuals maxFillLevels: 6 fillBaseName: bottle-1- - - type: Drink + - type: Edible + edible: Drink + solution: drink + destroyOnEmpty: false + utensil: None - type: SolutionContainerManager solutions: drink: # This solution name and target volume is hard-coded in ChemMasterComponent diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry-vials.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry-vials.yml index 21b3742d02..2422d7d712 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemistry-vials.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry-vials.yml @@ -29,8 +29,11 @@ fillBaseName: vial-1- inHandsMaxFillLevels: 4 inHandsFillBaseName: -fill- - - type: Drink + - type: Edible + edible: Drink solution: beaker + destroyOnEmpty: false + utensil: None - type: SolutionContainerManager solutions: beaker: diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml index cd4cbb3834..6a0a23eb65 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml @@ -48,8 +48,11 @@ interfaces: enum.TransferAmountUiKey.Key: type: TransferAmountBoundUserInterface - - type: Drink + - type: Edible + edible: Drink solution: beaker + destroyOnEmpty: false + utensil: None - type: Appearance - type: SolutionContainerVisuals maxFillLevels: 6 @@ -145,8 +148,11 @@ interfaces: enum.TransferAmountUiKey.Key: type: TransferAmountBoundUserInterface - - type: Drink + - type: Edible + edible: Drink solution: beaker + destroyOnEmpty: false + utensil: Spoon - type: Appearance - type: SolutionContainerVisuals maxFillLevels: 6 diff --git a/Resources/Prototypes/Entities/Objects/Tools/bucket.yml b/Resources/Prototypes/Entities/Objects/Tools/bucket.yml index d77e6cd2b8..c62b178366 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/bucket.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/bucket.yml @@ -9,6 +9,7 @@ edible: Drink solution: bucket destroyOnEmpty: false + utensil: Spoon - type: Sprite sprite: Objects/Tools/bucket.rsi layers: diff --git a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml index cb25f9199b..c1976ba7a8 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml @@ -971,8 +971,11 @@ - Honk - Carpetium - JuiceThatMakesYouWeh - - type: Drink + - type: Edible + edible: Drink solution: anomaly + destroyOnEmpty: false + utensil: Spoon - type: DrainableSolution solution: anomaly - type: DrawableSolution diff --git a/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml b/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml index 3be6fb7d6f..a24a03da3e 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml @@ -81,8 +81,11 @@ - type: ReactiveContainer solution: bucket container: item_slot - - type: Drink + - type: Edible + edible: Drink solution: bucket + destroyOnEmpty: false + utensil: Spoon - type: Appearance - type: SolutionContainerVisuals maxFillLevels: 3 @@ -358,8 +361,11 @@ interfaces: enum.StorageUiKey.Key: type: StorageBoundUserInterface - - type: Drink + - type: Edible + edible: Drink solution: bucket + destroyOnEmpty: false + utensil: Spoon - type: ContainerContainer containers: storagebase: !type:Container diff --git a/Resources/Prototypes/XenoArch/effects.yml b/Resources/Prototypes/XenoArch/effects.yml index 027c79550c..1506d94aa0 100644 --- a/Resources/Prototypes/XenoArch/effects.yml +++ b/Resources/Prototypes/XenoArch/effects.yml @@ -267,8 +267,11 @@ solution: beaker - type: SolutionTransfer canChangeTransferAmount: true - - type: Drink + - type: Edible + edible: Drink solution: beaker + destroyOnEmpty: false + utensil: None - type: entity id: XenoArtifactSpeedUp