diff --git a/Content.Shared/Chemistry/Components/SolutionManager/ExaminableSolutionComponent.cs b/Content.Shared/Chemistry/Components/SolutionManager/ExaminableSolutionComponent.cs index 1abe81180c..913622e19d 100644 --- a/Content.Shared/Chemistry/Components/SolutionManager/ExaminableSolutionComponent.cs +++ b/Content.Shared/Chemistry/Components/SolutionManager/ExaminableSolutionComponent.cs @@ -1,14 +1,70 @@ -namespace Content.Shared.Chemistry.Components.SolutionManager; +using Content.Shared.Nutrition.Components; +using Robust.Shared.Serialization; +namespace Content.Shared.Chemistry.Components.SolutionManager; + +/// +/// Component for examining a solution with shift click or through . +/// [RegisterComponent] public sealed partial class ExaminableSolutionComponent : Component { - [DataField, ViewVariables(VVAccess.ReadWrite)] + /// + /// The solution being examined. + /// + [DataField] public string Solution = "default"; /// - /// If false then the hidden solution is always visible. + /// If true, the solution must be held to be examined. /// [DataField] public bool HeldOnly; + + /// + /// If false, the examine text will give an approximation of the remaining solution. + /// If true, the exact unit count will be shown. + /// + [DataField] + public bool ExactVolume; + + /// + /// If false, the solution can't be examined when this entity is closed by . + /// + [DataField] + public bool ExaminableWhileClosed = true; + + /// + /// Examine text for the amount of solution. + /// + /// + [DataField] + public LocId LocVolume = "examinable-solution-on-examine-volume"; + + /// + /// Examine text for the physical description of the primary reagent. + /// + [DataField] + public LocId LocPhysicalQuality = "shared-solution-container-component-on-examine-main-text"; + + /// + /// Examine text for reagents that are obvious like water. + /// + [DataField] + public LocId LocRecognizableReagents = "examinable-solution-has-recognizable-chemicals"; +} + +/// +/// Used to choose how to display a volume. +/// +[Serializable, NetSerializable] +public enum ExaminedVolumeDisplay +{ + Exact, + Full, + MostlyFull, + HalfFull, + HalfEmpty, + MostlyEmpty, + Empty, } diff --git a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Capabilities.cs b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Capabilities.cs index ffdb608875..cc511f8db9 100644 --- a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Capabilities.cs +++ b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Capabilities.cs @@ -1,9 +1,7 @@ using Content.Shared.Chemistry.Components; using Content.Shared.Kitchen.Components; using Content.Shared.Chemistry.Components.SolutionManager; -using Content.Shared.Chemistry.Reaction; using Content.Shared.FixedPoint; -using Robust.Shared.Utility; using System.Diagnostics.CodeAnalysis; using System.Text; @@ -139,12 +137,13 @@ public abstract partial class SharedSolutionContainerSystem #endregion Solution Modifiers + /// A value between 0 and 100 inclusive. public float PercentFull(EntityUid uid) { - if (!TryGetDrainableSolution(uid, out _, out var solution) || solution.MaxVolume.Equals(FixedPoint2.Zero)) + if (!TryGetDrainableSolution(uid, out _, out var solution)) return 0; - return solution.FillFraction * 100; + return PercentFull(solution); } #region Static Methods @@ -175,5 +174,14 @@ public abstract partial class SharedSolutionContainerSystem return sb.ToString(); } + /// A value between 0 and 100 inclusive. + public static float PercentFull(Solution sol) + { + if (sol.MaxVolume.Equals(FixedPoint2.Zero)) + return 0; + + return sol.FillFraction * 100; + } + #endregion Static Methods } diff --git a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs index 5cc12a9b69..54210cf195 100644 --- a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs @@ -12,6 +12,9 @@ using Content.Shared.Examine; using Content.Shared.FixedPoint; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; +using Content.Shared.Localizations; +using Content.Shared.Nutrition.Components; +using Content.Shared.Nutrition.EntitySystems; using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Shared.Containers; @@ -61,14 +64,15 @@ public partial record struct SolutionAccessAttemptEvent(string SolutionName) [UsedImplicitly] public abstract partial class SharedSolutionContainerSystem : EntitySystem { - [Robust.Shared.IoC.Dependency] protected readonly IPrototypeManager PrototypeManager = default!; - [Robust.Shared.IoC.Dependency] protected readonly ChemicalReactionSystem ChemicalReactionSystem = default!; - [Robust.Shared.IoC.Dependency] protected readonly ExamineSystemShared ExamineSystem = default!; - [Robust.Shared.IoC.Dependency] protected readonly SharedAppearanceSystem AppearanceSystem = default!; - [Robust.Shared.IoC.Dependency] protected readonly SharedHandsSystem Hands = default!; - [Robust.Shared.IoC.Dependency] protected readonly SharedContainerSystem ContainerSystem = default!; - [Robust.Shared.IoC.Dependency] protected readonly MetaDataSystem MetaDataSys = default!; - [Robust.Shared.IoC.Dependency] protected readonly INetManager NetManager = default!; + [Dependency] protected readonly IPrototypeManager PrototypeManager = default!; + [Dependency] protected readonly ChemicalReactionSystem ChemicalReactionSystem = default!; + [Dependency] protected readonly ExamineSystemShared ExamineSystem = default!; + [Dependency] protected readonly OpenableSystem Openable = default!; + [Dependency] protected readonly SharedAppearanceSystem AppearanceSystem = default!; + [Dependency] protected readonly SharedHandsSystem Hands = default!; + [Dependency] protected readonly SharedContainerSystem ContainerSystem = default!; + [Dependency] protected readonly MetaDataSystem MetaDataSys = default!; + [Dependency] protected readonly INetManager NetManager = default!; public override void Initialize() { @@ -791,52 +795,55 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem } } + /// + /// Shift click examine. + /// private void OnExamineSolution(Entity entity, ref ExaminedEvent args) { - if (!TryGetSolution(entity.Owner, entity.Comp.Solution, out _, out var solution)) - { + if (!args.IsInDetailsRange || + !CanSeeHiddenSolution(entity, args.Examiner) || + !TryGetSolution(entity.Owner, entity.Comp.Solution, out _, out var solution)) return; - } - - if (!CanSeeHiddenSolution(entity, args.Examiner)) - return; - - var primaryReagent = solution.GetPrimaryReagentId(); - - if (string.IsNullOrEmpty(primaryReagent?.Prototype)) - { - args.PushText(Loc.GetString("shared-solution-container-component-on-examine-empty-container")); - return; - } - - if (!PrototypeManager.TryIndex(primaryReagent.Value.Prototype, out ReagentPrototype? primary)) - { - Log.Error($"{nameof(Solution)} could not find the prototype associated with {primaryReagent}."); - return; - } - - var colorHex = solution.GetColor(PrototypeManager) - .ToHexNoAlpha(); //TODO: If the chem has a dark color, the examine text becomes black on a black background, which is unreadable. - var messageString = "shared-solution-container-component-on-examine-main-text"; using (args.PushGroup(nameof(ExaminableSolutionComponent))) { - args.PushMarkup(Loc.GetString(messageString, - ("color", colorHex), - ("wordedAmount", Loc.GetString(solution.Contents.Count == 1 - ? "shared-solution-container-component-on-examine-worded-amount-one-reagent" - : "shared-solution-container-component-on-examine-worded-amount-multiple-reagents")), - ("desc", primary.LocalizedPhysicalDescription))); - var reagentPrototypes = solution.GetReagentPrototypes(PrototypeManager); + var primaryReagent = solution.GetPrimaryReagentId(); + + // If there's no primary reagent, assume the solution is empty and exit early + if (string.IsNullOrEmpty(primaryReagent?.Prototype) || + !PrototypeManager.Resolve(primaryReagent.Value.Prototype, out var primary)) + { + args.PushMarkup(Loc.GetString(entity.Comp.LocVolume, ("fillLevel", ExaminedVolumeDisplay.Empty))); + return; + } + + // Push amount of reagent + + args.PushMarkup(Loc.GetString(entity.Comp.LocVolume, + ("fillLevel", ExaminedVolume(entity, solution, args.Examiner)), + ("current", solution.Volume), + ("max", solution.MaxVolume))); + + // Push the physical description of the primary reagent + + var colorHex = solution.GetColor(PrototypeManager) + .ToHexNoAlpha(); //TODO: If the chem has a dark color, the examine text becomes black on a black background, which is unreadable. + + args.PushMarkup(Loc.GetString(entity.Comp.LocPhysicalQuality, + ("color", colorHex), + ("desc", primary.LocalizedPhysicalDescription), + ("chemCount", solution.Contents.Count) )); + + // Push the recognizable reagents // Sort the reagents by amount, descending then alphabetically - var sortedReagentPrototypes = reagentPrototypes + var sortedReagentPrototypes = solution.GetReagentPrototypes(PrototypeManager) .OrderByDescending(pair => pair.Value.Value) .ThenBy(pair => pair.Key.LocalizedName); - // Add descriptions of immediately recognizable reagents, like water or beer - var recognized = new List(); + // Collect recognizable reagents, like water or beer + var recognized = new List(); foreach (var keyValuePair in sortedReagentPrototypes) { var proto = keyValuePair.Key; @@ -845,41 +852,58 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem continue; } - recognized.Add(proto); + recognized.Add(Loc.GetString("examinable-solution-recognized", + ("color", proto.SubstanceColor.ToHexNoAlpha()), + ("chemical", proto.LocalizedName))); } - // Skip if there's nothing recognizable if (recognized.Count == 0) return; - var msg = new StringBuilder(); - foreach (var reagent in recognized) - { - string part; - if (reagent == recognized[0]) - { - part = "examinable-solution-recognized-first"; - } - else if (reagent == recognized[^1]) - { - // this loc specifically requires space to be appended, fluent doesnt support whitespace - msg.Append(' '); - part = "examinable-solution-recognized-last"; - } - else - { - part = "examinable-solution-recognized-next"; - } + var msg = ContentLocalizationManager.FormatList(recognized); - msg.Append(Loc.GetString(part, ("color", reagent.SubstanceColor.ToHexNoAlpha()), - ("chemical", reagent.LocalizedName))); - } - - args.PushMarkup(Loc.GetString("examinable-solution-has-recognizable-chemicals", - ("recognizedString", msg.ToString()))); + // Finally push the full message + args.PushMarkup(Loc.GetString(entity.Comp.LocRecognizableReagents, + ("recognizedString", msg))); } } + /// An enum for how to display the solution. + public ExaminedVolumeDisplay ExaminedVolume(Entity ent, Solution sol, EntityUid? examiner = null) + { + // Exact measurement + if (ent.Comp.ExactVolume) + return ExaminedVolumeDisplay.Exact; + + // General approximation + return (int)PercentFull(sol) switch + { + 100 => ExaminedVolumeDisplay.Full, + > 66 => ExaminedVolumeDisplay.MostlyFull, + > 33 => HalfEmptyOrHalfFull(examiner), + > 0 => ExaminedVolumeDisplay.MostlyEmpty, + _ => ExaminedVolumeDisplay.Empty, + }; + } + + // Some spessmen see half full, some see half empty, but always the same one. + private ExaminedVolumeDisplay HalfEmptyOrHalfFull(EntityUid? examiner = null) + { + // Optimistic when un-observed + if (examiner == null) + return ExaminedVolumeDisplay.HalfFull; + + var meta = MetaData(examiner.Value); + if (meta.EntityName.Length > 0 && + string.Compare(meta.EntityName.Substring(0, 1), "m", StringComparison.InvariantCultureIgnoreCase) > 0) + return ExaminedVolumeDisplay.HalfFull; + + return ExaminedVolumeDisplay.HalfEmpty; + } + + /// + /// Full reagent scan, such as with chemical analysis goggles. + /// private void OnSolutionExaminableVerb(Entity entity, ref GetVerbsEvent args) { if (!args.CanInteract || !args.CanAccess) @@ -953,15 +977,18 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem } /// - /// Check if examinable solution requires you to hold the item in hand. + /// Check if an examinable solution is hidden by something. /// private bool CanSeeHiddenSolution(Entity entity, EntityUid examiner) { // If not held-only then it's always visible. - if (!entity.Comp.HeldOnly) - return true; + if (entity.Comp.HeldOnly && !Hands.IsHolding(examiner, entity, out _)) + return false; - return Hands.IsHolding(examiner, entity, out _); + if (!entity.Comp.ExaminableWhileClosed && Openable.IsClosed(entity.Owner, predicted: true)) + return false; + + return true; } private void OnMapInit(Entity entity, ref MapInitEvent args) diff --git a/Content.Shared/Nutrition/Components/DrinkComponent.cs b/Content.Shared/Nutrition/Components/DrinkComponent.cs index 17baaef5a3..2211d58071 100644 --- a/Content.Shared/Nutrition/Components/DrinkComponent.cs +++ b/Content.Shared/Nutrition/Components/DrinkComponent.cs @@ -24,9 +24,6 @@ public sealed partial class DrinkComponent : Component [DataField, AutoNetworkedField] public float Delay = 1; - [DataField, AutoNetworkedField] - public bool Examinable = true; - /// /// If true, trying to drink when empty will not handle the event. /// This means other systems such as equipping on use can run. diff --git a/Content.Shared/Nutrition/EntitySystems/SharedDrinkSystem.cs b/Content.Shared/Nutrition/EntitySystems/SharedDrinkSystem.cs index a4b8e13b2f..66e4834d0d 100644 --- a/Content.Shared/Nutrition/EntitySystems/SharedDrinkSystem.cs +++ b/Content.Shared/Nutrition/EntitySystems/SharedDrinkSystem.cs @@ -37,7 +37,6 @@ public abstract partial class SharedDrinkSystem : EntitySystem base.Initialize(); SubscribeLocalEvent(OnAttemptShake); - SubscribeLocalEvent(OnExamined); SubscribeLocalEvent>(AddDrinkVerb); } @@ -47,38 +46,6 @@ public abstract partial class SharedDrinkSystem : EntitySystem args.Cancelled = true; } - protected void OnExamined(Entity entity, ref ExaminedEvent args) - { - TryComp(entity, out var openable); - if (_openable.IsClosed(entity.Owner, null, openable, true) || !args.IsInDetailsRange || !entity.Comp.Examinable) - return; - - var empty = IsEmpty(entity, entity.Comp); - if (empty) - { - args.PushMarkup(Loc.GetString("drink-component-on-examine-is-empty")); - return; - } - - if (HasComp(entity)) - { - //provide exact measurement for beakers - args.PushText(Loc.GetString("drink-component-on-examine-exact-volume", ("amount", DrinkVolume(entity, entity.Comp)))); - } - else - { - //general approximation - var remainingString = (int) _solutionContainer.PercentFull(entity) switch - { - 100 => "drink-component-on-examine-is-full", - > 66 => "drink-component-on-examine-is-mostly-full", - > 33 => HalfEmptyOrHalfFull(args), - _ => "drink-component-on-examine-is-mostly-empty", - }; - args.PushMarkup(Loc.GetString(remainingString)); - } - } - private void AddDrinkVerb(Entity entity, ref GetVerbsEvent ev) { if (entity.Owner == ev.User || @@ -130,18 +97,6 @@ public abstract partial class SharedDrinkSystem : EntitySystem return DrinkVolume(uid, component) <= 0; } - // some see half empty, and others see half full - private string HalfEmptyOrHalfFull(ExaminedEvent args) - { - string remainingString = "drink-component-on-examine-is-half-full"; - - if (TryComp(args.Examiner, out MetaDataComponent? examiner) && examiner.EntityName.Length > 0 - && string.Compare(examiner.EntityName.Substring(0, 1), "m", StringComparison.InvariantCultureIgnoreCase) > 0) - remainingString = "drink-component-on-examine-is-half-empty"; - - return remainingString; - } - /// /// Tries to feed the drink item to the target entity /// diff --git a/Resources/Locale/en-US/chemistry/solution/components/shared-solution-container-component.ftl b/Resources/Locale/en-US/chemistry/solution/components/shared-solution-container-component.ftl index 6f1ba911f7..dd78281b89 100644 --- a/Resources/Locale/en-US/chemistry/solution/components/shared-solution-container-component.ftl +++ b/Resources/Locale/en-US/chemistry/solution/components/shared-solution-container-component.ftl @@ -1,9 +1,37 @@ -shared-solution-container-component-on-examine-empty-container = Contains no chemicals. -shared-solution-container-component-on-examine-main-text = It contains {INDEFINITE($desc)} [color={$color}]{$desc}[/color] {$wordedAmount} -shared-solution-container-component-on-examine-worded-amount-one-reagent = chemical. -shared-solution-container-component-on-examine-worded-amount-multiple-reagents = mixture of chemicals. +shared-solution-container-component-on-examine-main-text = It contains {INDEFINITE($desc)} [color={$color}]{$desc}[/color] { $chemCount -> + [1] chemical. + *[other] mixture of chemicals. + } examinable-solution-has-recognizable-chemicals = You can recognize {$recognizedString} in the solution. -examinable-solution-recognized-first = [color={$color}]{$chemical}[/color] -examinable-solution-recognized-next = , [color={$color}]{$chemical}[/color] -examinable-solution-recognized-last = and [color={$color}]{$chemical}[/color] +examinable-solution-recognized = [color={$color}]{$chemical}[/color] + +examinable-solution-on-examine-volume = The contained solution is { $fillLevel -> + [exact] holding [color=white]{$current}/{$max}u[/color]. + *[other] [bold]{ -solution-vague-fill-level(fillLevel: $fillLevel) }[/bold]. +} + +examinable-solution-on-examine-volume-no-max = The contained solution is { $fillLevel -> + [exact] holding [color=white]{$current}u[/color]. + *[other] [bold]{ -solution-vague-fill-level(fillLevel: $fillLevel) }[/bold]. +} + +examinable-solution-on-examine-volume-puddle = The puddle is { $fillLevel -> + [exact] [color=white]{$current}u[/color]. + [full] huge and overflowing! + [mostlyfull] huge and overflowing! + [halffull] deep and flowing. + [halfempty] very deep. + *[mostlyempty] pooling together. + [empty] forming multiple small pools. +} + +-solution-vague-fill-level = + { $fillLevel -> + [full] [color=white]Full[/color] + [mostlyfull] [color=#DFDFDF]Mostly Full[/color] + [halffull] [color=#C8C8C8]Half Full[/color] + [halfempty] [color=#C8C8C8]Half Empty[/color] + [mostlyempty] [color=#A4A4A4]Mostly Empty[/color] + *[empty] [color=gray]Empty[/color] + } diff --git a/Resources/Locale/en-US/nutrition/components/drink-component.ftl b/Resources/Locale/en-US/nutrition/components/drink-component.ftl index e80787c8d5..ab458746dd 100644 --- a/Resources/Locale/en-US/nutrition/components/drink-component.ftl +++ b/Resources/Locale/en-US/nutrition/components/drink-component.ftl @@ -1,14 +1,7 @@ drink-component-on-use-is-empty = {CAPITALIZE(THE($owner))} is empty! -drink-component-on-examine-is-empty = [color=gray]Empty[/color] drink-component-on-examine-is-opened = [color=yellow]Opened[/color] drink-component-on-examine-is-sealed = The seal is intact. drink-component-on-examine-is-unsealed = The seal is broken. -drink-component-on-examine-is-full = Full -drink-component-on-examine-is-mostly-full = Mostly Full -drink-component-on-examine-is-half-full = Halfway Full -drink-component-on-examine-is-half-empty = Halfway Empty -drink-component-on-examine-is-mostly-empty = Mostly Empty -drink-component-on-examine-exact-volume = It contains {$amount}u. drink-component-try-use-drink-not-open = Open {$owner} first! drink-component-try-use-drink-is-empty = {CAPITALIZE(THE($entity))} is empty! drink-component-try-use-drink-cannot-drink = You can't drink anything! diff --git a/Resources/Prototypes/Entities/Clothing/Back/specific.yml b/Resources/Prototypes/Entities/Clothing/Back/specific.yml index d303aa166c..005dfedba5 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/specific.yml @@ -75,6 +75,7 @@ solution: tank - type: ExaminableSolution solution: tank + exactVolume: true - type: entity parent: ClothingBackpack diff --git a/Resources/Prototypes/Entities/Effects/puddle.yml b/Resources/Prototypes/Entities/Effects/puddle.yml index a426e7aa1c..1b84dcd7d0 100644 --- a/Resources/Prototypes/Entities/Effects/puddle.yml +++ b/Resources/Prototypes/Entities/Effects/puddle.yml @@ -205,9 +205,9 @@ delay: 3 transferAmount: 1 solution: puddle - examinable: false - type: ExaminableSolution solution: puddle + locVolume: "examinable-solution-on-examine-volume-puddle" - type: DrawableSolution solution: puddle - type: BadDrink diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml index c33e24ad3e..834a2c3a8e 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml @@ -17,6 +17,8 @@ maxVol: 50 - type: PressurizedSolution solution: drink + - type: ExaminableSolution + examinableWhileClosed: false - type: Shakeable - type: Sprite state: icon @@ -194,7 +196,7 @@ Quantity: 100 - type: Sprite sprite: Objects/Consumable/Drinks/oatmilk.rsi - + - type: entity parent: [DrinkCartonVisualsOpenable, DrinkCartonBaseFull] id: DrinkJuiceLemonCarton @@ -209,7 +211,7 @@ Quantity: 50 - type: Sprite sprite: Objects/Consumable/Drinks/lemonjuice.rsi - + - type: entity parent: [DrinkCartonVisualsOpenable, DrinkCartonBaseFull] id: DrinkJuicePineappleCarton diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml index aff0aa7a05..2d8fadfa43 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml @@ -31,6 +31,8 @@ solution: drink - type: DrainableSolution solution: drink + - type: ExaminableSolution + solution: drink - type: UserInterface interfaces: enum.TransferAmountUiKey.Key: @@ -75,8 +77,6 @@ - type: PhysicalComposition materialComposition: Glass: 25 - - type: ExaminableSolution - solution: drink - type: FitsInDispenser solution: drink - type: Tag diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles.yml index c2ac4c606f..d432c6d9d5 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles.yml @@ -192,6 +192,8 @@ layers: - state: icon map: ["enum.OpenableVisuals.Layer"] + - type: ExaminableSolution + examinableWhileClosed: false # If you can't see fill levels, it's probably opaque - type: entity id: DrinkBottleVisualsAll @@ -217,6 +219,7 @@ fillBaseName: fill- inHandsMaxFillLevels: 3 inHandsFillBaseName: -fill- + - type: ExaminableSolution # Large Glass Bottles diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml index d933cbcd1b..e6ba0d002e 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml @@ -46,6 +46,9 @@ solution: drink - type: PressurizedSolution solution: drink + - type: ExaminableSolution + solution: drink + examinableWhileClosed: false - type: Appearance - type: GenericVisualizer visuals: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml index 842cf13641..d5bfdefe48 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml @@ -20,6 +20,8 @@ solution: drink - type: DrainableSolution solution: drink + - type: ExaminableSolution + solution: drink - type: SolutionTransfer canChangeTransferAmount: true maxTransferAmount: 10 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_flasks.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_flasks.yml index 9e1b100dbf..8f3b9381f7 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_flasks.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_flasks.yml @@ -15,6 +15,8 @@ Steel: 300 - type: FitsInDispenser solution: drink + - type: ExaminableSolution + examinableWhileClosed: false - type: entity id: DrinkFlaskVisualsOpenable diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml index 02a4346ebc..e7aa6c1252 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml @@ -41,6 +41,10 @@ mixOnInteract: false reactionTypes: - Shake + - type: ExaminableSolution + solution: drink + heldOnly: true + examinableWhileClosed: false - type: entity parent: DrinkGlassBase diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/condiments.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/condiments.yml index c7de98b4a4..7c7df07f78 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/condiments.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/condiments.yml @@ -9,6 +9,8 @@ solution: food - type: DrainableSolution solution: food + - type: ExaminableSolution + solution: food - type: Sprite sprite: Objects/Consumable/Food/condiments.rsi - type: Icon @@ -69,6 +71,8 @@ - type: Tag tags: - Packet + - type: ExaminableSolution + exactVolume: true - type: entity parent: BaseFoodCondimentPacket diff --git a/Resources/Prototypes/Entities/Objects/Misc/arabianlamp.yml b/Resources/Prototypes/Entities/Objects/Misc/arabianlamp.yml index 2b1c2940fe..2a289a95f8 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/arabianlamp.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/arabianlamp.yml @@ -110,6 +110,8 @@ solution: Welder - type: ExaminableSolution solution: Welder + heldOnly: true + exactVolume: true - type: SolutionRegeneration solution: Welder generated: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml index b692f20dd9..9ed5972754 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml @@ -42,6 +42,7 @@ solution: spray - type: ExaminableSolution solution: spray + exactVolume: true - type: entity name: mega spray bottle diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml index bd8e78dd9a..bc0cf16e8e 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml @@ -22,6 +22,7 @@ solution: hypospray - type: ExaminableSolution solution: hypospray + exactVolume: true - type: Hypospray onlyAffectsMobs: false - type: UseDelay @@ -63,6 +64,7 @@ solution: hypospray - type: ExaminableSolution solution: hypospray + exactVolume: true - type: Hypospray onlyAffectsMobs: false - type: UseDelay @@ -142,6 +144,7 @@ maxVol: 15 - type: ExaminableSolution solution: pen + exactVolume: true - type: Hypospray solutionName: pen transferAmount: 15 @@ -661,6 +664,7 @@ - type: ExaminableSolution solution: hypospray heldOnly: true # Allow examination only when held in hand. + exactVolume: true - type: Hypospray onlyAffectsMobs: false - type: UseDelay diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml b/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml index 1bbe05944f..84990b10be 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml @@ -26,6 +26,7 @@ solution: beaker - type: ExaminableSolution solution: beaker + exactVolume: true - type: DrawableSolution solution: beaker - type: InjectableSolution diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml index a892ee6395..0c0c1cf172 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry-bottles.yml @@ -37,6 +37,7 @@ solution: drink - type: ExaminableSolution solution: drink + exactVolume: true - type: DrawableSolution solution: drink - type: SolutionTransfer diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry-vials.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry-vials.yml index 60441bb475..bc8207b673 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemistry-vials.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry-vials.yml @@ -43,6 +43,7 @@ solution: beaker - type: ExaminableSolution solution: beaker + exactVolume: true - type: DrawableSolution solution: beaker - type: SolutionTransfer @@ -137,6 +138,7 @@ solution: beaker - type: ExaminableSolution solution: beaker + exactVolume: true - type: DrawableSolution solution: beaker - type: SolutionTransfer diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml index ebd785ab7e..3a7e44775f 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml @@ -35,6 +35,7 @@ solution: beaker - type: ExaminableSolution solution: beaker + exactVolume: true - type: DrawableSolution solution: beaker - type: InjectableSolution @@ -133,6 +134,7 @@ solution: beaker - type: ExaminableSolution solution: beaker + exactVolume: true - type: DrawableSolution solution: beaker - type: InjectableSolution @@ -189,6 +191,7 @@ solution: beaker - type: ExaminableSolution solution: beaker + exactVolume: true - type: DrawableSolution solution: beaker - type: InjectableSolution @@ -348,6 +351,7 @@ toggleState: 1 # draw - type: ExaminableSolution solution: dropper + exactVolume: true - type: UserInterface interfaces: enum.TransferAmountUiKey.Key: @@ -420,6 +424,7 @@ injectOnly: false - type: ExaminableSolution solution: injector + exactVolume: true - type: Spillable solution: injector - type: TrashOnSolutionEmpty diff --git a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml index 638947af75..cb25f9199b 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml @@ -979,6 +979,8 @@ solution: anomaly - type: ExaminableSolution solution: anomaly + exactVolume: true + locVolume: "examinable-solution-on-examine-volume-no-max" - type: RefillableSolution solution: anomaly - type: InjectableSolution