From 91f8e9490dc62cd0fee9ca15afa417b23c64fd5b Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Thu, 23 Apr 2026 18:46:37 -0700 Subject: [PATCH 01/65] Fix Max Cap Heisentest (#43704) * fix max cap test fails * oop * remove suffix --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- Content.IntegrationTests/Tests/EntityTest.cs | 4 ++-- .../Catalog/Fills/Items/gas_tanks.yml | 18 ++++++++++++------ .../Storage/Canisters/gas_canisters.yml | 3 ++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Content.IntegrationTests/Tests/EntityTest.cs b/Content.IntegrationTests/Tests/EntityTest.cs index 13293b7d46..c82535dd36 100644 --- a/Content.IntegrationTests/Tests/EntityTest.cs +++ b/Content.IntegrationTests/Tests/EntityTest.cs @@ -20,7 +20,7 @@ namespace Content.IntegrationTests.Tests [TestOf(typeof(EntityUid))] public sealed class EntityTest : GameTest { - private static readonly ProtoId SpawnerCategory = "Spawner"; + private static readonly HashSet> IgnoredCategories = ["Spawner", "Debug"]; public override PoolSettings PoolSettings => new() { @@ -255,7 +255,7 @@ namespace Content.IntegrationTests.Tests .Where(p => !p.Abstract) .Where(p => !pair.IsTestPrototype(p)) .Where(p => !excluded.Any(p.Components.ContainsKey)) - .Where(p => p.Categories.All(x => x.ID != SpawnerCategory)) + .Where(p => p.Categories.All(x => !IgnoredCategories.Contains(x.ID))) .Select(p => p.ID) .ToList(); diff --git a/Resources/Prototypes/Catalog/Fills/Items/gas_tanks.yml b/Resources/Prototypes/Catalog/Fills/Items/gas_tanks.yml index f377d96db9..9bf95604fe 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/gas_tanks.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/gas_tanks.yml @@ -206,7 +206,8 @@ - type: entity parent: AirTank id: MaxCap # As of currently writing, tanks have an explosion intensity of about 125, which is about as powerful as an explosive grenade. - suffix: DEBUG, Max Cap + categories: [ Debug ] + suffix: Max Cap components: - type: GasTank air: @@ -219,7 +220,8 @@ - type: entity parent: EmergencyOxygenTank id: MaxCapSmall # As of currently writing, mini tanks have an explosion intensity of about 40. - suffix: DEBUG, Max Cap + categories: [ Debug ] + suffix: Max Cap components: - type: GasTank air: @@ -233,7 +235,8 @@ - type: entity parent: ExtendedEmergencyOxygenTank id: MaxCapSmallEx # As of currently writing, extended tanks currently have an explosive intensity of about 65 - suffix: DEBUG, Max Cap + categories: [ Debug ] + suffix: Max Cap components: - type: GasTank air: @@ -246,7 +249,8 @@ - type: entity parent: DoubleEmergencyOxygenTank id: MaxCapSmallDouble # As of currently writing, extended tanks currently have an explosive intensity of about 85 - suffix: DEBUG, Max Cap + categories: [ Debug ] + suffix: Max Cap components: - type: GasTank air: @@ -259,8 +263,9 @@ - type: entity parent: AirTank id: MaxCapSilly + categories: [ Debug ] name: max cap - suffix: DEBUG, Max Cap, Impossible + suffix: Max Cap, Impossible components: - type: GasTank air: @@ -273,8 +278,9 @@ - type: entity parent: AirTank id: MaxCapBluespace + categories: [ Debug ] name: max cap - suffix: DEBUG, Max Cap, Canister + suffix: Max Cap, Canister components: - type: Explosive maxIntensity: 200 diff --git a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml index 7ffc594342..a47a8e2104 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml @@ -774,8 +774,9 @@ - type: entity parent: GasCanister id: MaxCapCanister # As of writing canisters currently have about 9000 explosive intensity. 95% the total damage of a syndicate bomb but spread across a larger area. + categories: [ Debug ] name: max cap in a can - suffix: DEBUG, Max Cap + suffix: Max Cap components: - type: GasCanister air: From ebe5d47cc64451af08f38465d415cc3310487527 Mon Sep 17 00:00:00 2001 From: Jessica M Date: Thu, 23 Apr 2026 20:29:17 -0700 Subject: [PATCH 02/65] Minor door animation tweak (#43708) is this bad --- Content.Client/Doors/DoorSystem.cs | 29 ++++++++++++++----- .../Doors/Components/DoorComponent.cs | 8 ++--- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/Content.Client/Doors/DoorSystem.cs b/Content.Client/Doors/DoorSystem.cs index cba9ba1d49..31c98b6ab7 100644 --- a/Content.Client/Doors/DoorSystem.cs +++ b/Content.Client/Doors/DoorSystem.cs @@ -81,7 +81,10 @@ public sealed class DoorSystem : SharedDoorSystem private void OnAnimationCompleted(Entity ent, ref AnimationCompletedEvent args) { - if (args.Key != DoorComponent.OpenCloseKey || !TryComp(ent, out var sprite)) + if (args.Key != DoorComponent.OpenKey && args.Key != DoorComponent.CloseKey) + return; + + if (!TryComp(ent, out var sprite)) return; switch (ent.Comp.State) @@ -130,9 +133,15 @@ public sealed class DoorSystem : SharedDoorSystem switch (state) { case DoorState.Open: - if (_animationSystem.HasRunningAnimation(entity, DoorComponent.OpenCloseKey)) + if (_animationSystem.HasRunningAnimation(entity, DoorComponent.OpenKey)) return; + if (_animationSystem.HasRunningAnimation(entity, DoorComponent.CloseKey)) + { + _animationSystem.Stop(entity, null, DoorComponent.CloseKey); + _animationSystem.Play(entity, (Animation)entity.Comp.OpeningAnimation, DoorComponent.OpenKey); + } + foreach (var (layer, layerState) in entity.Comp.OpenSpriteStates) { // Allow animations to play while it's open (e.g., pinion); @@ -143,9 +152,15 @@ public sealed class DoorSystem : SharedDoorSystem return; case DoorState.Closed: - if (_animationSystem.HasRunningAnimation(entity, DoorComponent.OpenCloseKey)) + if (_animationSystem.HasRunningAnimation(entity, DoorComponent.CloseKey)) return; + if (_animationSystem.HasRunningAnimation(entity, DoorComponent.OpenKey)) + { + _animationSystem.Stop(entity, null, DoorComponent.OpenKey); + _animationSystem.Play(entity, (Animation)entity.Comp.OpeningAnimation, DoorComponent.CloseKey); + } + foreach (var (layer, layerState) in entity.Comp.ClosedSpriteStates) { _sprite.LayerSetAutoAnimated((entity.Owner, sprite), layer, true); @@ -157,20 +172,20 @@ public sealed class DoorSystem : SharedDoorSystem if (entity.Comp.OpeningAnimationTime == TimeSpan.Zero) return; - if (_animationSystem.HasRunningAnimation(entity, DoorComponent.OpenCloseKey)) + if (_animationSystem.HasRunningAnimation(entity, DoorComponent.OpenKey)) return; - _animationSystem.Play(entity, (Animation)entity.Comp.OpeningAnimation, DoorComponent.OpenCloseKey); + _animationSystem.Play(entity, (Animation)entity.Comp.OpeningAnimation, DoorComponent.OpenKey); return; case DoorState.Closing: if (entity.Comp.ClosingAnimationTime == TimeSpan.Zero) return; - if (_animationSystem.HasRunningAnimation(entity, DoorComponent.OpenCloseKey)) + if (_animationSystem.HasRunningAnimation(entity, DoorComponent.CloseKey)) return; - _animationSystem.Play(entity, (Animation)entity.Comp.ClosingAnimation, DoorComponent.OpenCloseKey); + _animationSystem.Play(entity, (Animation)entity.Comp.ClosingAnimation, DoorComponent.CloseKey); return; case DoorState.Denying: diff --git a/Content.Shared/Doors/Components/DoorComponent.cs b/Content.Shared/Doors/Components/DoorComponent.cs index 057fd5982d..714e45b604 100644 --- a/Content.Shared/Doors/Components/DoorComponent.cs +++ b/Content.Shared/Doors/Components/DoorComponent.cs @@ -137,10 +137,10 @@ public sealed partial class DoorComponent : Component #region Graphics - /// - /// The key used when playing door opening/closing/emagging/deny animations. - /// - public const string OpenCloseKey = "door_animation_openclose"; + + public const string OpenKey = "door_animation_open"; + + public const string CloseKey = "door_animation_close"; /// /// The key used when playing door deny animations. From 5a7540edb250ee1901c7898754fb2e4658a80aaa Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Fri, 24 Apr 2026 05:54:57 +0200 Subject: [PATCH 03/65] HeatContainer tests, bugfixes and API cleanup (#43690) tests and fixes --- .../HeatContainer/HeatContainer.cs | 19 +- .../HeatContainerHelpers.Divide.cs | 70 -- .../HeatContainerHelpers.Exchange.cs | 19 +- .../HeatContainerHelpers.Merge.cs | 73 +-- .../HeatContainerHelpers.Split.cs | 90 +++ .../HeatContainer/HeatContainerHelpers.cs | 8 +- .../Shared/Temperature/HeatContainerTest.cs | 612 ++++++++++++++++++ 7 files changed, 755 insertions(+), 136 deletions(-) delete mode 100644 Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Divide.cs create mode 100644 Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Split.cs create mode 100644 Content.Tests/Shared/Temperature/HeatContainerTest.cs diff --git a/Content.Shared/Temperature/HeatContainer/HeatContainer.cs b/Content.Shared/Temperature/HeatContainer/HeatContainer.cs index cfa5a43c59..adc1d51a9a 100644 --- a/Content.Shared/Temperature/HeatContainer/HeatContainer.cs +++ b/Content.Shared/Temperature/HeatContainer/HeatContainer.cs @@ -9,7 +9,7 @@ namespace Content.Shared.Temperature.HeatContainer; /// [Serializable, NetSerializable, DataDefinition] [Access(typeof(HeatContainerHelpers), typeof(SharedAtmosphereSystem))] -public partial struct HeatContainer : IRobustCloneable, IHeatContainer +public partial struct HeatContainer : IHeatContainer { /// [DataField] @@ -29,22 +29,15 @@ public partial struct HeatContainer : IRobustCloneable, IHeatCont public HeatContainer(float heatCapacity, float temperature) { + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(heatCapacity); + ArgumentOutOfRangeException.ThrowIfNegative(temperature); HeatCapacity = heatCapacity; Temperature = temperature; } - /// - /// Copy constructor for implementing ICloneable. - /// - /// The HeatContainer to copy. - private HeatContainer(HeatContainer c) + public HeatContainer(float heatCapacity) { - HeatCapacity = c.HeatCapacity; - Temperature = c.Temperature; - } - - public HeatContainer Clone() - { - return new HeatContainer(this); + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(heatCapacity); + HeatCapacity = heatCapacity; } } diff --git a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Divide.cs b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Divide.cs deleted file mode 100644 index 0e516446da..0000000000 --- a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Divide.cs +++ /dev/null @@ -1,70 +0,0 @@ -using JetBrains.Annotations; - -namespace Content.Shared.Temperature.HeatContainer; - -public static partial class HeatContainerHelpers -{ - /// - /// Splits a into two. - /// - /// The to split. This will be modified to contain the remaining heat capacity. - /// A that will be modified to contain - /// the specified fraction of the original container's heat capacity and the same temperature. - /// The fraction of the heat capacity to move to the new container. Clamped between 0 and 1. - [PublicAPI] - public static void Split(ref T1 c, ref T2 cSplit, float fraction = 0.5f) - where T1 : IHeatContainer - where T2 : IHeatContainer - { - fraction = Math.Clamp(fraction, 0f, 1f); - var newHeatCapacity = c.HeatCapacity * fraction; - - cSplit.HeatCapacity = newHeatCapacity; - cSplit.Temperature = c.Temperature; - - c.HeatCapacity -= newHeatCapacity; - } - - /// - /// Splits a into two, - /// modifying the original container to contain the specified fraction of the original heat capacity and the same temperature. - /// - /// A that will be modified to contain - /// the specified fraction of the original container's heat capacity and the same temperature. - /// The fraction of the heat capacity to move to the new container. Clamped between 0 and 1. - /// This discards the leftover fraction. Be very careful with using this as you may void heat unintentionally. - [PublicAPI] - public static void Split(ref T c, float fraction = 0.5f) - where T : IHeatContainer - { - fraction = Math.Clamp(fraction, 0f, 1f); - var newHeatCapacity = c.HeatCapacity * fraction; - c.HeatCapacity = newHeatCapacity; - } - - /// - /// Divides a source into a specified number of equal parts. - /// - /// The input to split. - /// An array of s equally split from the source . - /// This will be written to. This must be the same length as num. - /// The number of s - /// to split the source into. - /// Thrown when attempting to divide the source container by zero. - /// Thrown when the length of the divided array does not match the specified number of divisions. - [PublicAPI] - public static void Divide(this T c, T[] dividedArray, int num) - where T : struct, IHeatContainer // if we allowed classes you'd just have an array reffing the same obj - { - ArgumentOutOfRangeException.ThrowIfNegativeOrZero(num); - ArgumentOutOfRangeException.ThrowIfNotEqual(dividedArray.Length, num); - - var fraction = 1f / num; - Split(ref c, fraction); - - for (var i = 0; i < num; i++) - { - dividedArray[i] = c; - } - } -} diff --git a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Exchange.cs b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Exchange.cs index b12dd026ef..00719621e6 100644 --- a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Exchange.cs +++ b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Exchange.cs @@ -16,15 +16,11 @@ public static partial class HeatContainerHelpers /// The amount of transferred heat in joules that is needed /// to bring the containers to thermal equilibrium. /// A positive value indicates heat transfer from a hot cA to a cold cB. - /// Thrown when the combined heat capacity of both containers is zero or negative. [PublicAPI] public static float EquilibriumHeatQuery(ref T1 cA, ref T2 cB) where T1 : IHeatContainer where T2 : IHeatContainer { - var cTotal = cA.HeatCapacity + cB.HeatCapacity; - ArgumentOutOfRangeException.ThrowIfNegativeOrZero(cTotal); - /* The solution is derived from the following facts: 1. Let Q be the amount of heat energy transferred from cA to cB. @@ -37,6 +33,7 @@ public static partial class HeatContainerHelpers 6. At thermal equilibrium, T_A_final = T_B_final. 7. Solve for Q. */ + var cTotal = cA.HeatCapacity + cB.HeatCapacity; return (cA.Temperature - cB.Temperature) * (cA.HeatCapacity * cB.HeatCapacity / cTotal); } @@ -48,14 +45,12 @@ public static partial class HeatContainerHelpers /// The first to exchange heat. /// The second to exchange heat with. /// The resulting equilibrium temperature both containers will be at. - /// Thrown when the combined heat capacity of both containers is zero or negative. [PublicAPI] public static float EquilibriumTemperatureQuery(ref T1 cA, ref T2 cB) where T1 : IHeatContainer where T2 : IHeatContainer { var cTotal = cA.HeatCapacity + cB.HeatCapacity; - ArgumentOutOfRangeException.ThrowIfNegativeOrZero(cTotal); // Insert the above solution for Q into T_A_final = T_A_initial - Q / C_A and rearrange the result. return (cA.HeatCapacity * cA.Temperature + cB.HeatCapacity * cB.Temperature) / cTotal; } @@ -91,7 +86,7 @@ public static partial class HeatContainerHelpers cA.Temperature = tFinal; cB.Temperature = tFinal; // Guarded against div/0 in EquilibriumTemperatureQuery: totalHeatCapacity > 0. - dQ = (tInitialA - tFinal) / cA.HeatCapacity; + dQ = (tInitialA - tFinal) * cA.HeatCapacity; } #endregion @@ -103,7 +98,7 @@ public static partial class HeatContainerHelpers /// /// The array of s to bring into thermal equilibrium. [PublicAPI] - public static void Equilibrate(this T[] cN) where T : IHeatContainer + public static void Equilibrate(T[] cN) where T : IHeatContainer { var tF = EquilibriumTemperatureQuery(cN); for (var i = 0; i < cN.Length; i++) @@ -140,7 +135,7 @@ public static partial class HeatContainerHelpers /// The temperature of all s involved after reaching thermal equilibrium. /// Thrown when the combined heat capacity of all containers is zero or negative. [PublicAPI] - public static float EquilibriumTemperatureQuery(this T[] cN) where T : IHeatContainer + public static float EquilibriumTemperatureQuery(T[] cN) where T : IHeatContainer { /* The solution is derived via the following: @@ -194,7 +189,7 @@ public static partial class HeatContainerHelpers /// to reach thermal equilibrium. /// The temperature of all s involved after reaching thermal equilibrium. [PublicAPI] - public static float EquilibriumTemperatureQuery(this T[] cN, out float[] dQ) where T : IHeatContainer + public static float EquilibriumTemperatureQuery(T[] cN, out float[] dQ) where T : IHeatContainer { /* For finding the total heat exchanged during the equalization between a group of bodies @@ -203,7 +198,7 @@ public static partial class HeatContainerHelpers dQ = C * (T_f - T_i) for each container */ - var tF = cN.EquilibriumTemperatureQuery(); + var tF = EquilibriumTemperatureQuery(cN); dQ = new float[cN.Length]; for (var i = 0; i < cN.Length; i++) @@ -230,7 +225,7 @@ public static partial class HeatContainerHelpers cAll[0] = cA; cN.CopyTo(cAll, 1); - return cAll.EquilibriumTemperatureQuery(); + return EquilibriumTemperatureQuery(cAll); } #endregion diff --git a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Merge.cs b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Merge.cs index d3cb2e258a..fd75fb4af7 100644 --- a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Merge.cs +++ b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Merge.cs @@ -5,64 +5,65 @@ namespace Content.Shared.Temperature.HeatContainer; public static partial class HeatContainerHelpers { /// - /// Merges two heat containers into one, conserving total internal energy. + /// Merges one heat container into another. /// /// The first to merge. This will be modified to contain the merged result. - /// The second to merge. + /// The second to merge. This will remain unmodified. /// Thrown when the combined heat capacity of both containers is zero or negative. [PublicAPI] - public static void Merge(ref T1 cA, ref T2 cB) + public static void MergeInto(ref T1 cA, ref T2 cB) where T1 : IHeatContainer where T2 : IHeatContainer { var combinedHeatCapacity = cA.HeatCapacity + cB.HeatCapacity; ArgumentOutOfRangeException.ThrowIfNegativeOrZero(combinedHeatCapacity); - cA.HeatCapacity = combinedHeatCapacity; cA.Temperature = (cA.InternalEnergy + cB.InternalEnergy) / combinedHeatCapacity; + cA.HeatCapacity = combinedHeatCapacity; } /// - /// Merges an array of s into a single heat container, conserving total internal energy. + /// Merges an array of s into a single heat container. + /// This means you combine N+1 containers into 1. /// - /// The first to merge. - /// This will be modified to contain the merged result. - /// The array of s to merge. + /// The first to merge. This will be modified to contain the merged result. + /// The array of s to merge. These will remain unmodified. [PublicAPI] - public static void Merge(ref T1 cA, T2[] cN) + public static void MergeInto(ref T1 cA, T2[] cN) where T1 : IHeatContainer where T2 : IHeatContainer { - // merge the first array and then merge the result with cA to avoid alloc - var temp = new HeatContainer(); - cN.Merge(ref temp); - Merge(ref cA, ref temp); - } - - /// - /// Merges an array of s into a single heat container, conserving total internal energy. - /// - /// The array of s to merge. - /// The modified containing the merged result. - /// Thrown when the combined heat capacity of all containers is zero or negative. - [PublicAPI] - public static void Merge(this T1[] cN, ref T2 result) - where T1 : IHeatContainer - where T2 : IHeatContainer - { - var totalHeatCapacity = 0f; - var totalEnergy = 0f; - - foreach (var c in cN) + var totalEnergy = cA.InternalEnergy; + var totalHeatCapacity = cA.HeatCapacity; + for (var i = 0; i < cN.Length; i++) { - totalHeatCapacity += c.HeatCapacity; - totalEnergy += c.InternalEnergy; + totalEnergy += cN[i].InternalEnergy; + totalHeatCapacity += cN[i].HeatCapacity; } + cA.Temperature = totalEnergy / totalHeatCapacity; + cA.HeatCapacity = totalHeatCapacity; + } - ArgumentOutOfRangeException.ThrowIfNegativeOrZero(totalHeatCapacity); - - result.HeatCapacity = totalHeatCapacity; - result.Temperature = totalEnergy / totalHeatCapacity; + /// + /// Merges an array of s into a single new output heat container. + /// This means you combine N containers into 1. + /// + /// The to write the result to. + /// The array of s to merge. These will remain unmodified. + [PublicAPI] + public static void MergeAndCopy(ref T1 cA, T2[] cN) + where T1 : IHeatContainer + where T2 : IHeatContainer + { + var totalEnergy = 0f; + var totalHeatCapacity = 0f; + for (var i = 0; i < cN.Length; i++) + { + totalEnergy += cN[i].InternalEnergy; + totalHeatCapacity += cN[i].HeatCapacity; + } + cA.Temperature = totalEnergy / totalHeatCapacity; + cA.HeatCapacity = totalHeatCapacity; } } diff --git a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Split.cs b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Split.cs new file mode 100644 index 0000000000..6c3dd8b812 --- /dev/null +++ b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Split.cs @@ -0,0 +1,90 @@ +using JetBrains.Annotations; + +namespace Content.Shared.Temperature.HeatContainer; + +public static partial class HeatContainerHelpers +{ + /// + /// Splits a into two, modifying the original container + /// to contain the remaining fraction of the original heat capacity and the same temperature. + /// + /// The to split. This will be modified to contain the remaining heat capacity. + /// A that will be modified to contain + /// the specified fraction of the original container's heat capacity and the same temperature. Any previous value will be overwritten. + /// The fraction of the heat capacity to move to the new container. Clamped between 0 and 1. + [PublicAPI] + public static void SplitFrom(ref T1 c, ref T2 cSplit, float fraction = 0.5f) + where T1 : IHeatContainer + where T2 : IHeatContainer + { + fraction = Math.Clamp(fraction, 0f, 1f); + var newHeatCapacity = c.HeatCapacity * fraction; + + cSplit.HeatCapacity = newHeatCapacity; + cSplit.Temperature = c.Temperature; + + c.HeatCapacity -= newHeatCapacity; + } + + /// + /// Splits a into two, modifying the original container + /// to contain the remaining fraction of the original heat capacity and the same temperature, + /// while discarding the rest. + /// + /// The to split off. This will be modified to contain the remaining heat capacity. + /// The fraction of the heat capacity to remove from the original container. Clamped between 0 and 1. + /// This discards the leftover fraction. Be very careful with using this as you may void heat unintentionally. + [PublicAPI] + public static void SplitFrom(ref T c, float fraction = 0.5f) + where T : IHeatContainer + { + fraction = Math.Clamp(fraction, 0f, 1f); + var newHeatCapacity = c.HeatCapacity * fraction; + + c.HeatCapacity -= newHeatCapacity; + } + + /// + /// Splits a source into a specified number of equal parts. + /// This means you will get N + 1 equal parts where N is the length of the given array. + /// + /// The input to split. It will be modified such that it is equal to each entry in . + /// An array of s equally split from the source.. + /// This will be written to. + [PublicAPI] + public static void SplitFrom(ref T1 c, T2[] dividedArray) + where T1 : IHeatContainer + where T2 : struct, IHeatContainer // if we allowed classes you'd just have an array reffing the same obj + { + var num = dividedArray.Length + 1; + for (var i = 0; i < dividedArray.Length; i++) + { + dividedArray[i].Temperature = c.Temperature; + dividedArray[i].HeatCapacity = c.HeatCapacity / num; + } + + c.HeatCapacity /= num; + } + + /// + /// Splits a source into a specified number of equal parts, keeping the source unmodified. + /// This means you will get N equal parts where N is the length of the given array. + /// + /// The input to split into equal parts. This container is not modified, so make sure to discard it to avoid breaking energy conservation. + /// An array of s the source will be split into. + /// This will be written to. + /// Thrown when attempting to divide the source container by zero. + [PublicAPI] + public static void SplitAndCopy(ref T1 c, T2[] dividedArray) + where T1 : IHeatContainer + where T2 : struct, IHeatContainer // if we allowed classes you'd just have an array reffing the same obj + { + var num = dividedArray.Length; + ArgumentOutOfRangeException.ThrowIfZero(num); + for (var i = 0; i < num; i++) + { + dividedArray[i].Temperature = c.Temperature; + dividedArray[i].HeatCapacity = c.HeatCapacity / num; + } + } +} diff --git a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.cs b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.cs index 42b7ae7ca8..b58e5f94b9 100644 --- a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.cs +++ b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.cs @@ -13,8 +13,8 @@ public static partial class HeatContainerHelpers /// Positive values add heat, negative values remove heat. /// The temperature can never become lower than 0K even if more heat is removed. /// - /// The to add or remove energy. - /// The energy in joules to add or remove. + /// The to add heat to or remove heat from. + /// The amount of energy in joules to add or remove. [PublicAPI] public static void AddHeat(ref T c, float dQ) where T : IHeatContainer { @@ -27,13 +27,11 @@ public static partial class HeatContainerHelpers /// The temperature can never become lower than 0K even if more heat is removed. /// /// The to query. - /// The energy in joules to add or remove. + /// The amount of energy in joules to add or remove. /// The resulting temperature in kelvin after the heat change. - /// Thrown when the heat capacity of the container is zero or negative. [PublicAPI] public static float AddHeatQuery(ref T c, float dQ) where T : IHeatContainer { - ArgumentOutOfRangeException.ThrowIfNegativeOrZero(c.HeatCapacity); // Don't allow the temperature to go below the absolute minimum. return Math.Max(0f, c.Temperature + dQ / c.HeatCapacity); } diff --git a/Content.Tests/Shared/Temperature/HeatContainerTest.cs b/Content.Tests/Shared/Temperature/HeatContainerTest.cs new file mode 100644 index 0000000000..92d0351194 --- /dev/null +++ b/Content.Tests/Shared/Temperature/HeatContainerTest.cs @@ -0,0 +1,612 @@ +using System.Linq; +using Content.Shared.Temperature.HeatContainer; +using NUnit.Framework; + +namespace Content.Tests.Shared.Temperature; + +[TestFixture, TestOf(typeof(HeatContainer))] +[Parallelizable(ParallelScope.All)] +public sealed class HeatContainerTest +{ + #region HeatContainerHelpers + [Test] + public void AddHeatTest() + { + // T = 100 K + // C = 1000 J/K + var c = new HeatContainer(1000f, 100f); + var originalEnergy = c.InternalEnergy; + + // Check initial values. + Assert.That(c.Temperature, Is.EqualTo(100f)); + Assert.That(c.HeatCapacity, Is.EqualTo(1000f)); + + // Add 5000 J, the temperature should rise by 5 K. + HeatContainerHelpers.AddHeat(ref c, 5000); + Assert.That(c.Temperature, Is.EqualTo(105f).Within(1).Ulps); + Assert.That(c.HeatCapacity, Is.EqualTo(1000f)); + Assert.That(c.InternalEnergy, Is.EqualTo(originalEnergy + 5000).Within(1).Ulps); + + // Subtract 15000 J, the temperature should lower by 15 K. + HeatContainerHelpers.AddHeat(ref c, -15000); + Assert.That(c.Temperature, Is.EqualTo(90f).Within(1).Ulps); + Assert.That(c.HeatCapacity, Is.EqualTo(1000f)); + Assert.That(c.InternalEnergy, Is.EqualTo(originalEnergy + 5000 - 15000).Within(1).Ulps); + + // Check that we cannot go below 0 K. + HeatContainerHelpers.AddHeat(ref c, -200000f); + Assert.That(c.Temperature, Is.Zero); + Assert.That(c.HeatCapacity, Is.EqualTo(1000f)); + Assert.That(c.InternalEnergy, Is.Zero); + } + + [Test] + public void AddHeatQueryTest() + { + // T = 100 K + // C = 1000 J/K + var c = new HeatContainer(1000f, 100f); + + // Check initial values. + Assert.That(c.Temperature, Is.EqualTo(100f)); + Assert.That(c.HeatCapacity, Is.EqualTo(1000f)); + + // Add 5000 J, the temperature should rise by 5 K from the original value. + Assert.That(HeatContainerHelpers.AddHeatQuery(ref c, 5000), Is.EqualTo(105f).Within(1).Ulps); + + // Subtract 15000 J, the temperature should lower by 15 K from the original value. + Assert.That(HeatContainerHelpers.AddHeatQuery(ref c, -15000), Is.EqualTo(85f).Within(1).Ulps); + + // Check that we cannot go below 0 K. + Assert.That(HeatContainerHelpers.AddHeatQuery(ref c, -200000f), Is.Zero); + + // The original container should be unchanged. + Assert.That(c.Temperature, Is.EqualTo(100f)); + Assert.That(c.HeatCapacity, Is.EqualTo(1000f)); + } + + [Test] + public void SetHeatCapacityTest() + { + // T = 300 K + // C = 1000 J/K + var c = new HeatContainer(1000f, 300f); + var originalEnergy = c.InternalEnergy; + + // We triple the heat capacity, resulting in the temeperature to become one third of the original. + HeatContainerHelpers.SetHeatCapacity(ref c, 3000f); + + // The original container should be unchanged. + Assert.That(c.Temperature, Is.EqualTo(100f).Within(1).Ulps); + Assert.That(c.HeatCapacity, Is.EqualTo(3000f)); + + // The total energy is conserved. + Assert.That(c.InternalEnergy, Is.EqualTo(originalEnergy).Within(1).Ulps); + } + #endregion + + #region Divide + [Test] + public void SplitTest() + { + // T = 42 K + // C = 3000 J/K + var c1 = new HeatContainer(3000f, 42f); + var c2 = new HeatContainer(); + var totalEnergy = c1.InternalEnergy; + + // Split equally. + HeatContainerHelpers.SplitFrom(ref c1, ref c2, fraction: 0.5f); + + // The heat capacity should be split equally. + // The temperature should be the same. + // The total energy should be conserved. + Assert.That(c1.Temperature, Is.EqualTo(42f)); + Assert.That(c1.HeatCapacity, Is.EqualTo(1500f).Within(1).Ulps); + Assert.That(c2.Temperature, Is.EqualTo(42f)); + Assert.That(c2.HeatCapacity, Is.EqualTo(1500f).Within(1).Ulps); + Assert.That(c1.InternalEnergy + c2.InternalEnergy, Is.EqualTo(totalEnergy).Within(1).Ulps); + + // Reset the first container. + c1 = new HeatContainer(3000f, 42f); + + // Split into 2/3 + 1/3. + HeatContainerHelpers.SplitFrom(ref c1, ref c2, fraction: 1f / 3); + + // The heat capacity should be split according to the fraction. + // The temperature should be the same. + // The total energy should be conserved. + Assert.That(c1.Temperature, Is.EqualTo(42f)); + Assert.That(c1.HeatCapacity, Is.EqualTo(2000f).Within(1).Ulps); + Assert.That(c2.Temperature, Is.EqualTo(42f)); + Assert.That(c2.HeatCapacity, Is.EqualTo(1000f).Within(1).Ulps); + Assert.That(c1.InternalEnergy + c2.InternalEnergy, Is.EqualTo(totalEnergy).Within(1).Ulps); + } + + [Test] + public void SplitDiscardTest() + { + // T = 42 K + // C = 3000 J/K + var c1 = new HeatContainer(3000f, 42f); + + // Split equally. + HeatContainerHelpers.SplitFrom(ref c1, fraction: 0.5f); + + // The heat capacity should be split equally, the temperature should be the same. + Assert.That(c1.Temperature, Is.EqualTo(42f)); + Assert.That(c1.HeatCapacity, Is.EqualTo(1500f).Within(1).Ulps); + + // Reset the container. + c1 = new HeatContainer(3000f, 42f); + + // Split into 1/3 + 2/3. + HeatContainerHelpers.SplitFrom(ref c1, fraction: 1f / 3); + + // The heat capacity should be split according to the fraction, the temperature should be the same. + Assert.That(c1.Temperature, Is.EqualTo(42f)); + Assert.That(c1.HeatCapacity, Is.EqualTo(2000f).Within(1).Ulps); + } + + [Test] + public void SplitArrayTest() + { + // T = 42 K + // C = 1000 J/K + const int n = 4; + var c1 = new HeatContainer(1000f, 42f); + var cA = new HeatContainer[n]; + + // Split into n + 1 equal parts. + HeatContainerHelpers.SplitFrom(ref c1, cA); + + for (var i = 0; i < n; i++) + { + // The temperature should be the same as the initial one. + // The heat capacities should be equally split. + Assert.That(cA[i].Temperature, Is.EqualTo(42f)); + Assert.That(cA[i].HeatCapacity, Is.EqualTo(1000f / (n + 1)).Within(1).Ulps); + } + + // Check that the initital container is the same as the output containers. + Assert.That(c1.Temperature, Is.EqualTo(42f)); + Assert.That(c1.HeatCapacity, Is.EqualTo(1000f / (n + 1)).Within(1).Ulps); + } + + [Test] + public void SplitAndCopyTest() + { + // T = 42 K + // C = 1000 J/K + const int n = 5; + var c1 = new HeatContainer(1000f, 42f); + var cA = new HeatContainer[n]; + + // Divide into n equal parts. + HeatContainerHelpers.SplitAndCopy(ref c1, cA); + + for (var i = 0; i < n; i++) + { + // The temperature should be the same as the initial one. + // The heat capacities should be equally split. + Assert.That(cA[i].Temperature, Is.EqualTo(42f)); + Assert.That(cA[i].HeatCapacity, Is.EqualTo(1000f / n).Within(1).Ulps); + } + + // Check that the initital container is unmodified. + Assert.That(c1.Temperature, Is.EqualTo(42f)); + Assert.That(c1.HeatCapacity, Is.EqualTo(1000f)); + } + #endregion + + #region Merge + [Test] + public void Merge2Test() + { + // T = 42 K + // C = 5000 J/K + var c1 = new HeatContainer(5000f, 42f); + var energy1 = c1.InternalEnergy; + // T = 100 K + // C = 5000 J/K + var c2 = new HeatContainer(5000f, 100f); + var energy2 = c2.InternalEnergy; + + // Merge 2 containers of the same capacity and different temperatures. + HeatContainerHelpers.MergeInto(ref c1, ref c2); + + // The temperature should be the average of the two initial ones. + // The total heat capacity should be the sum of the two initial capacities. + // The total energy should be conserved. + Assert.That(c1.Temperature, Is.EqualTo((42f + 100f) / 2).Within(1).Ulps); + Assert.That(c1.HeatCapacity, Is.EqualTo(10000f).Within(1).Ulps); + Assert.That(c1.InternalEnergy, Is.EqualTo(energy1 + energy2).Within(1).Ulps); + + // The second container should remain unchanged. + Assert.That(c2.Temperature, Is.EqualTo(100)); + Assert.That(c2.HeatCapacity, Is.EqualTo(5000f)); + + // T = 100 K + // C = 750 J/K + // E = 75000 J + c1 = new HeatContainer(750f, 100f); + energy1 = c1.InternalEnergy; + // T = 300 K + // C = 250 J/K + // E = 75000 J + c2 = new HeatContainer(250f, 300f); + energy2 = c2.InternalEnergy; + + // Merge 2 containers with different temperature and capacity. + HeatContainerHelpers.MergeInto(ref c1, ref c2); + + // The temperature should averaged weighted by capacity. + // (100*750+300*250)/(750+250)=150 + // The total heat capacity should be the sum of the two initial capacities. + // The total energy should be conserved. + Assert.That(c1.Temperature, Is.EqualTo(150f).Within(1).Ulps); + Assert.That(c1.HeatCapacity, Is.EqualTo(750f + 250f).Within(1).Ulps); + Assert.That(c1.InternalEnergy, Is.EqualTo(energy1 + energy2).Within(1).Ulps); + + // The second container should remain unchanged. + Assert.That(c2.Temperature, Is.EqualTo(300)); + Assert.That(c2.HeatCapacity, Is.EqualTo(250f)); + } + + [Test] + public void Merge1PlusArrayTest() + { + // T = 200 K + // C = 50 J/K + var c1 = new HeatContainer(50f, 200f); + var energy1 = c1.InternalEnergy; + + // Array of 40 heat containers, each with + // T = 100 K + // C = 5 J/K + const int n = 40; + var cA1 = new HeatContainer(5f, 100); + var cA = new HeatContainer[n]; + var energyA = cA1.InternalEnergy * n; + for (var i = 0; i < cA.Length; i++) + { + cA[i] = cA1; + } + + // Merge the array into the single heat container. + HeatContainerHelpers.MergeInto(ref c1, cA); + + // The temperature should averaged weighted by capacity. + // (200*50+100*5*40)/(50+5*40)=120 + // The total heat capacity should be the sum of the initial capacities. + // The total energy should be conserved. + Assert.That(c1.Temperature, Is.EqualTo(120f).Within(1).Ulps); + Assert.That(c1.HeatCapacity, Is.EqualTo(50f + 5 * n).Within(1).Ulps); + Assert.That(c1.InternalEnergy, Is.EqualTo(energy1 + energyA).Within(1).Ulps); + } + + [Test] + public void MergeArrayTest() + { + // This heat container will be overwritten. + var c1 = new HeatContainer(50f, 200f); + + // Array of 40 heat containers, each with + // T = 100 K + // C = 5 J/K + const int n = 40; + var cA1 = new HeatContainer(5f, 100); + var cA = new HeatContainer[n]; + var energyA = cA1.InternalEnergy * n; + for (var i = 0; i < cA.Length; i++) + { + cA[i] = cA1; + } + + // Merge the array into the single heat container. + HeatContainerHelpers.MergeAndCopy(ref c1, cA); + + // The temperature of all merged containers was the same. + // The total heat capacity should be the sum of the initial capacities. + // The total energy should be the sum of the intial energies. + Assert.That(c1.Temperature, Is.EqualTo(100f)); + Assert.That(c1.HeatCapacity, Is.EqualTo(5 * n).Within(1).Ulps); + Assert.That(c1.InternalEnergy, Is.EqualTo(energyA).Within(1).Ulps); + } + #endregion + + #region Exchange + [Test] + public void EquilibriumQuery2BodyTest() + { + // Cold c1, hot c2. + var c1 = new HeatContainer(123f, 456f); + var c2 = new HeatContainer(987f, 654f); + + var dQ11 = HeatContainerHelpers.EquilibriumHeatQuery(ref c1, ref c1); + var dQ12 = HeatContainerHelpers.EquilibriumHeatQuery(ref c1, ref c2); + var dQ21 = HeatContainerHelpers.EquilibriumHeatQuery(ref c2, ref c1); + var dQ22 = HeatContainerHelpers.EquilibriumHeatQuery(ref c2, ref c2); + var t11 = HeatContainerHelpers.EquilibriumTemperatureQuery(ref c1, ref c1); + var t12 = HeatContainerHelpers.EquilibriumTemperatureQuery(ref c1, ref c2); + var t21 = HeatContainerHelpers.EquilibriumTemperatureQuery(ref c2, ref c1); + var t22 = HeatContainerHelpers.EquilibriumTemperatureQuery(ref c2, ref c2); + + // Containers should be in equilibrium with themselves. + Assert.That(dQ11, Is.Zero.Within(1).Ulps); + Assert.That(dQ22, Is.Zero.Within(1).Ulps); + Assert.That(t11, Is.EqualTo(c1.Temperature).Within(1).Ulps); + Assert.That(t22, Is.EqualTo(c2.Temperature).Within(1).Ulps); + + // Heat should flow from hot to cold. + Assert.That(dQ12, Is.LessThan(0f)); + Assert.That(dQ21, Is.GreaterThan(0f)); + Assert.That(t12, Is.LessThan(c2.Temperature)); + Assert.That(t21, Is.LessThan(c2.Temperature)); + Assert.That(t12, Is.GreaterThan(c1.Temperature)); + Assert.That(t21, Is.GreaterThan(c1.Temperature)); + // The result should be symmetric. + Assert.That(dQ21, Is.EqualTo(-dQ12).Within(1).Ulps); + Assert.That(t12, Is.EqualTo(t21).Within(1).Ulps); + + // Check that the heat flow indeed brings them into equilibrium. + HeatContainerHelpers.AddHeat(ref c1, -dQ12); + HeatContainerHelpers.AddHeat(ref c2, dQ12); + + Assert.That(c1.Temperature, Is.EqualTo(c2.Temperature).Within(1).Ulps); + Assert.That(c1.Temperature, Is.EqualTo(t12).Within(1).Ulps); + Assert.That(c1.Temperature, Is.EqualTo(t21).Within(1).Ulps); + Assert.That(c2.Temperature, Is.EqualTo(t12).Within(1).Ulps); + Assert.That(c2.Temperature, Is.EqualTo(t21).Within(1).Ulps); + } + + [Test] + public void Equilibrium2BodyTest() + { + // Cold c1, hot c2. + var c1 = new HeatContainer(123f, 456f); + var c2 = new HeatContainer(987f, 654f); + var totalEnergy = c1.InternalEnergy + c2.InternalEnergy; + + // Bring them into equilibrium. + HeatContainerHelpers.Equilibrate(ref c1, ref c2); + + // Total energy should be conserved. + Assert.That(c1.InternalEnergy + c2.InternalEnergy, Is.EqualTo(totalEnergy).Within(1).Ulps); + + // The temperature should be equal, the capacities unchanged. + Assert.That(c1.Temperature, Is.EqualTo(c2.Temperature).Within(1).Ulps); + Assert.That(c1.HeatCapacity, Is.EqualTo(123f)); + Assert.That(c2.HeatCapacity, Is.EqualTo(987f)); + + // Repeat with the out dQ overload. + c1 = new HeatContainer(123f, 456f); + c2 = new HeatContainer(987f, 654f); + totalEnergy = c1.InternalEnergy + c2.InternalEnergy; + var dQQuery = HeatContainerHelpers.EquilibriumHeatQuery(ref c1, ref c2); + + // Bring them into equilibrium. + HeatContainerHelpers.Equilibrate(ref c1, ref c2, out var dQresult); + + // Total energy should be conserved. + Assert.That(c1.InternalEnergy + c2.InternalEnergy, Is.EqualTo(totalEnergy).Within(1).Ulps); + + // The temperature should be equal, the capacities unchanged. + Assert.That(c1.Temperature, Is.EqualTo(c2.Temperature).Within(1).Ulps); + Assert.That(c1.HeatCapacity, Is.EqualTo(123f)); + Assert.That(c2.HeatCapacity, Is.EqualTo(987f)); + + // The output dQ should be the same as the query we did before. + Assert.That(dQQuery, Is.EqualTo(dQresult).Within(1).Ulps); + } + + [Test] + public void Equilibrium3BodyTest() + { + // Cold c1, medium c2, hot c3. + var c1 = new HeatContainer(300f, 123f); + var c2 = new HeatContainer(200f, 234f); + var c3 = new HeatContainer(100f, 456f); + var totalEnergy = c1.InternalEnergy + c2.InternalEnergy + c3.InternalEnergy; + + // Save as array. + var cN = new HeatContainer[3]; + cN[0] = c1; + cN[1] = c2; + cN[2] = c3; + + var tQuery = HeatContainerHelpers.EquilibriumTemperatureQuery(cN); + var tQuerydQ = HeatContainerHelpers.EquilibriumTemperatureQuery(cN, out var dQQuery); + + // Both queries should result in the same temperature. + Assert.That(tQuery, Is.EqualTo(tQuerydQ).Within(1).Ulps); + + // Heat flows from hot to cold. + Assert.That(tQuery, Is.GreaterThan(c1.Temperature)); + Assert.That(tQuery, Is.LessThan(c3.Temperature)); + Assert.That(dQQuery[0], Is.GreaterThan(0f)); + Assert.That(dQQuery[2], Is.LessThan(0f)); + + // Total energy should be conserved. + Assert.That(dQQuery.Sum(), Is.Zero.Within(1).Ulps); + + // Check if we actually reach equilibrium with the calculated heat flow. + HeatContainerHelpers.AddHeat(ref c1, dQQuery[0]); + HeatContainerHelpers.AddHeat(ref c2, dQQuery[1]); + HeatContainerHelpers.AddHeat(ref c3, dQQuery[2]); + + Assert.That(c1.Temperature, Is.EqualTo(tQuery).Within(1).Ulps); + Assert.That(c2.Temperature, Is.EqualTo(tQuery).Within(1).Ulps); + Assert.That(c3.Temperature, Is.EqualTo(tQuery).Within(1).Ulps); + + // Put the array into equilibrium. + HeatContainerHelpers.Equilibrate(cN); + + // Check if we actually reached equilibrium. + Assert.That(cN[0].Temperature, Is.EqualTo(tQuery).Within(1).Ulps); + Assert.That(cN[1].Temperature, Is.EqualTo(tQuery).Within(1).Ulps); + Assert.That(cN[2].Temperature, Is.EqualTo(tQuery).Within(1).Ulps); + + // Total energy should be conserved. + var newTotalEnergy = cN[0].InternalEnergy + cN[1].InternalEnergy + cN[2].InternalEnergy; + Assert.That(newTotalEnergy, Is.EqualTo(totalEnergy).Within(1).Ulps); + } + + [Test] + public void Equilibrium1Plus3BodyTest() + { + // Cold c1, medium c2 and c3, hot c4. + var c1 = new HeatContainer(400f, 123f); + var c2 = new HeatContainer(300f, 234f); + var c3 = new HeatContainer(200f, 456f); + var c4 = new HeatContainer(100f, 567f); + var totalEnergy = c1.InternalEnergy + c2.InternalEnergy + c3.InternalEnergy + c4.InternalEnergy; + + // Save as array. + var cN = new HeatContainer[3]; + cN[0] = c1; + cN[1] = c2; + cN[2] = c3; + + var tQuery = HeatContainerHelpers.EquilibriumTemperatureQuery(ref c4, cN); + + // Heat flows from hot to cold. + Assert.That(tQuery, Is.GreaterThan(c1.Temperature)); + Assert.That(tQuery, Is.LessThan(c4.Temperature)); + + // Total energy should be conserved. + Assert.That(tQuery * (c1.HeatCapacity + c2.HeatCapacity + c3.HeatCapacity + c4.HeatCapacity), Is.EqualTo(totalEnergy).Within(1).Ulps); + + // Put everything into equilibrium. + HeatContainerHelpers.Equilibrate(ref c4, cN); + + // Check if we actually reached equilibrium. + Assert.That(cN[0].Temperature, Is.EqualTo(tQuery).Within(1).Ulps); + Assert.That(cN[1].Temperature, Is.EqualTo(tQuery).Within(1).Ulps); + Assert.That(cN[2].Temperature, Is.EqualTo(tQuery).Within(1).Ulps); + Assert.That(c4.Temperature, Is.EqualTo(tQuery).Within(1).Ulps); + + // Total energy should be conserved. + var newTotalEnergy = cN[0].InternalEnergy + cN[1].InternalEnergy + cN[2].InternalEnergy + c4.InternalEnergy; + Assert.That(newTotalEnergy, Is.EqualTo(totalEnergy).Within(1).Ulps); + } + #endregion + + #region Conduct + [Test] + public void Conduct1Test() + { + // T = 100 K + // C = 42 J/K + var c1 = new HeatContainer(42f, 100f); + var c2 = new HeatContainer(42f, 100f); + var c3 = new HeatContainer(42f, 100f); + var c4 = new HeatContainer(42f, 100f); + + // Conduct heat with a heat bath of 200K for a small time step of 0.01s and a conductance of 1. + var dQ1 = HeatContainerHelpers.ConductHeat(ref c1, 200f, 0.01f, 100f); + + // The temperature should be between 100 and 200K. + // The heat capacity should be unchanged. + Assert.That(c1.Temperature, Is.GreaterThan(100f)); + Assert.That(c1.Temperature, Is.LessThan(200f)); + Assert.That(c1.HeatCapacity, Is.EqualTo(42f)); + + // The conducted heat should positive, since the temperature got higher. + Assert.That(dQ1, Is.GreaterThan(0f)); + + // Check that removing the heat again brings us back where we were originally. + var c1Copy = c1; + HeatContainerHelpers.AddHeat(ref c1Copy, -dQ1); + Assert.That(c1Copy.Temperature, Is.EqualTo(100f).Within(1).Ulps); + + // A greater temperature difference means a greater heat transfer. + var dQ2 = HeatContainerHelpers.ConductHeat(ref c2, 300f, 0.01f, 100f); + Assert.That(dQ2, Is.GreaterThan(dQ1)); + Assert.That(c2.Temperature, Is.GreaterThan(c1.Temperature)); + + // A greater time step means a greater heat transfer. + var dQ3 = HeatContainerHelpers.ConductHeat(ref c3, 200f, 0.02f, 100f); + Assert.That(dQ3, Is.GreaterThan(dQ1)); + Assert.That(c3.Temperature, Is.GreaterThan(c1.Temperature)); + + // A greater conductance means a greater heat transfer. + var dQ4 = HeatContainerHelpers.ConductHeat(ref c4, 200f, 0.01f, 200f); + Assert.That(dQ4, Is.GreaterThan(dQ1)); + Assert.That(c4.Temperature, Is.GreaterThan(c1.Temperature)); + + // Make sure we don't overshoot with a too large time step and conductance. + var c5 = new HeatContainer(42f, 100f); + var dQ5 = HeatContainerHelpers.ConductHeat(ref c5, 200f, 10f, 10000f); + Assert.That(c5.Temperature, Is.EqualTo(200f).Within(1).Ulps); + + // Check that the heat diff is still correct even when we would have overshot. + HeatContainerHelpers.AddHeat(ref c5, -dQ5); + Assert.That(c5.Temperature, Is.EqualTo(100f).Within(1).Ulps); + + // Check that consecutive steps become smaller, but still get us closer to equilibrium. + var c6 = new HeatContainer(42f, 100f); + var t6Init = c6.Temperature; + var dQ6A = HeatContainerHelpers.ConductHeat(ref c6, 200f, 1f, 1f); + var t6A = c6.Temperature; + var dQ6B = HeatContainerHelpers.ConductHeat(ref c6, 200f, 1f, 1f); + var t6B = c6.Temperature; + Assert.That(dQ6A, Is.GreaterThan(dQ6B)); + Assert.That(t6A, Is.GreaterThan(t6Init)); + Assert.That(t6B, Is.GreaterThan(t6A)); + + // Check that we converge towards the heat bath temperature. + var c7 = new HeatContainer(42f, 100f); + var e7Init = c7.InternalEnergy; + var dQ7 = 0f; + for (var i = 0; i < 10000; i++) + { + dQ7 += HeatContainerHelpers.ConductHeat(ref c7, 200f, 1f, 1f); + } + Assert.That(c7.Temperature, Is.EqualTo(200f).Within(0.1).Percent); + Assert.That(c7.InternalEnergy - dQ7, Is.EqualTo(e7Init).Within(0.2).Percent); + } + + [Test] + public void Conduct2Test() + { + // Temperatures at 100 K and 200 K + var cA = new HeatContainer(42f, 100f); + var cB = new HeatContainer(123f, 200f); + var totalEnergy = cA.InternalEnergy + cB.InternalEnergy; + var tEquilibrium = HeatContainerHelpers.EquilibriumTemperatureQuery(ref cA, ref cB); + var dQ = HeatContainerHelpers.ConductHeat(ref cA, ref cB, 1f, 1f); + + // Heat flow from hot B to cold A should be positive. + Assert.That(dQ, Is.GreaterThan(0f)); + + // Energy should be conserved. + Assert.That(cA.InternalEnergy + cB.InternalEnergy, Is.EqualTo(totalEnergy)); + + // Check that we got closer to equilibrium, but did not reach it. + Assert.That(cA.Temperature, Is.GreaterThan(100f)); + Assert.That(cA.Temperature, Is.LessThan(tEquilibrium)); + Assert.That(cB.Temperature, Is.LessThan(200f)); + Assert.That(cB.Temperature, Is.GreaterThan(tEquilibrium)); + + // Check that the given heat transfer amount is correct. + HeatContainerHelpers.AddHeat(ref cA, -dQ); + HeatContainerHelpers.AddHeat(ref cB, dQ); + + Assert.That(cA.Temperature, Is.EqualTo(100f).Within(1).Ulps); + Assert.That(cB.Temperature, Is.EqualTo(200f).Within(1).Ulps); + + // Reset containers. + cA = new HeatContainer(42f, 100f); + cB = new HeatContainer(123f, 200f); + + // Check that we converge towards equilibrium. + for (var i = 0; i < 10000; i++) + { + HeatContainerHelpers.ConductHeat(ref cA, ref cB, 1f, 1f); + } + Assert.That(cA.Temperature, Is.EqualTo(tEquilibrium).Within(0.1).Percent); + Assert.That(cB.Temperature, Is.EqualTo(tEquilibrium).Within(0.1).Percent); + } + #endregion +} From 39be43c60fe08a640549d93d02b67efc639bfd9e Mon Sep 17 00:00:00 2001 From: pathetic meowmeow Date: Fri, 24 Apr 2026 00:12:34 -0400 Subject: [PATCH 04/65] Start splitting out DamageableComponent (#43515) * Start splitting out DamageableComponent * don't change that * fix testies * not needed * forgot you --- Content.Client/Damage/DamageVisualsSystem.cs | 10 ++--- .../Overlays/EntityHealthBarOverlay.cs | 16 ++++--- .../Overlays/ShowHealthIconsSystem.cs | 18 ++++---- .../DamageOverlayUiController.cs | 7 +-- .../Tests/Atmos/DeltaPressureTest.cs | 1 + .../Tests/Commands/RejuvenateTest.cs | 1 + .../Tests/Damageable/DamageableTest.cs | 1 + .../DestructibleTestPrototypes.cs | 4 ++ .../Tests/Disposal/DisposalUnitTest.cs | 1 + .../Tests/Minds/MindTests.cs | 1 + .../Tests/Storage/EntityStorageTests.cs | 1 + .../Tests/VendingMachineRestockTest.cs | 3 +- .../EntitySystems/ExplosionSystem.Airtight.cs | 6 +-- .../EntitySystems/ExplosionSystem.cs | 1 + .../Damage/Components/DamageableComponent.cs | 36 +-------------- .../Damage/Components/InjurableComponent.cs | 41 +++++++++++++++++ .../Damage/Systems/DamageableSystem.API.cs | 38 ++++------------ .../Damage/Systems/DamageableSystem.Events.cs | 45 ++++++++++++++++--- .../Damage/Systems/DamageableSystem.cs | 1 + .../Medical/Healing/HealingSystem.cs | 14 ++++-- .../Prototypes/Body/Species/skeleton.yml | 3 +- .../Entities/Clothing/Head/misc.yml | 1 + .../Entities/Effects/chemistry_effects.yml | 6 ++- .../Mobs/Cyborgs/base_borg_chassis.yml | 1 + .../Prototypes/Entities/Mobs/NPCs/animals.yml | 8 +--- .../Entities/Mobs/NPCs/elemental.yml | 3 +- .../Entities/Mobs/NPCs/hellspawn.yml | 3 +- .../Entities/Mobs/NPCs/living_light.yml | 3 +- .../Entities/Mobs/NPCs/revenant.yml | 3 +- .../Prototypes/Entities/Mobs/NPCs/silicon.yml | 1 + .../Prototypes/Entities/Mobs/NPCs/slimes.yml | 1 - .../Entities/Mobs/Player/guardian.yml | 1 + .../Entities/Mobs/Player/mothershipcore.yml | 1 + Resources/Prototypes/Entities/Mobs/base.yml | 1 + .../Drinks/drinks_base_materials.yml | 13 ++++-- .../Consumable/Food/Containers/plate.yml | 1 + .../Consumable/Food/Containers/tin.yml | 1 + .../Entities/Objects/Consumable/Food/egg.yml | 1 + .../Objects/Consumable/Food/ingredients.yml | 1 + .../Objects/Consumable/Food/produce.yml | 8 ++++ .../Entities/Objects/Consumable/Food/soup.yml | 1 + .../Entities/Objects/Decoration/flora.yml | 6 ++- .../Entities/Objects/Decoration/mining.yml | 9 ++-- .../Objects/Deliveries/deliveries.yml | 1 + .../Entities/Objects/Devices/payload.yml | 1 + .../Objects/Devices/station_beacon.yml | 3 +- .../Entities/Objects/Devices/station_map.yml | 1 + .../Entities/Objects/Devices/wristwatch.yml | 1 + .../Fun/Instruments/base_instruments.yml | 3 +- .../Fun/Instruments/instruments_string.yml | 1 + .../Entities/Objects/Fun/balloons.yml | 1 + .../Prototypes/Entities/Objects/Fun/darts.yml | 1 + .../Prototypes/Entities/Objects/Fun/orbs.yml | 1 + .../Prototypes/Entities/Objects/Fun/toys.yml | 1 + .../Objects/Materials/Sheets/glass.yml | 3 +- .../Objects/Materials/Sheets/metal.yml | 3 +- .../Objects/Materials/Sheets/other.yml | 1 + .../Objects/Materials/crystal_shard.yml | 3 +- .../Entities/Objects/Materials/ingots.yml | 3 +- .../Entities/Objects/Materials/materials.yml | 1 + .../Entities/Objects/Materials/parts.yml | 3 +- .../Entities/Objects/Materials/scrap.yml | 6 ++- .../Entities/Objects/Materials/shards.yml | 3 +- .../Entities/Objects/Misc/candy_bowl.yml | 1 + .../Entities/Objects/Misc/fluff_lights.yml | 6 ++- .../Entities/Objects/Misc/land_mine.yml | 1 + .../Entities/Objects/Misc/parcel_wrap.yml | 1 + .../Entities/Objects/Misc/pet_carrier.yml | 3 +- .../Entities/Objects/Misc/spaceshroom.yml | 3 +- .../Entities/Objects/Misc/tiles.yml | 1 + .../Entities/Objects/Power/lights.yml | 1 + .../Entities/Objects/Shields/shields.yml | 2 + .../Objects/Specific/Cargo/cargo_pallet.yml | 3 +- .../Specific/Chemistry/chemistry-bottles.yml | 1 + .../Objects/Specific/Chemistry/chemistry.yml | 7 ++- .../Objects/Specific/Kitchen/equipment.yml | 1 + .../Objects/Specific/Kitchen/foodcarts.yml | 3 +- .../Entities/Objects/Specific/Mech/mechs.yml | 3 +- .../Objects/Specific/Security/barrier.yml | 3 +- .../Objects/Specific/Security/target.yml | 1 + .../Service/vending_machine_restock.yml | 3 +- .../Xenoarchaeology/artifact_equipment.yml | 6 ++- .../Entities/Objects/Tools/cable_coils.yml | 3 +- .../Entities/Objects/Tools/decoys.yml | 1 + .../Entities/Objects/Tools/fulton.yml | 1 + .../Entities/Objects/Tools/toolbox.yml | 1 + .../Entities/Objects/Weapons/Bombs/cord.yml | 1 + .../Objects/Weapons/Bombs/detonator.yml | 1 + .../Objects/Weapons/Bombs/firebomb.yml | 1 + .../Entities/Objects/Weapons/Bombs/funny.yml | 1 + .../Objects/Weapons/Bombs/plastic.yml | 1 + .../Ammunition/Cartridges/base_cartridge.yml | 3 +- .../Weapons/Guns/Projectiles/meteors.yml | 1 + .../Guns/Turrets/turrets_ballistic.yml | 1 + .../Weapons/Guns/Turrets/turrets_base.yml | 1 + .../Weapons/Guns/Turrets/turrets_broken.yml | 1 + .../Entities/Objects/Weapons/Melee/spear.yml | 1 + .../Weapons/Throwable/base_grenades.yml | 1 + .../Objects/Weapons/Throwable/bola.yml | 1 + .../Objects/Weapons/Throwable/grenades.yml | 1 + .../Weapons/Throwable/projectile_grenades.yml | 1 + .../Entities/Objects/base_shadow.yml | 1 + .../Structures/Decoration/banners.yml | 1 + .../Structures/Decoration/bonfire.yml | 3 +- .../Structures/Decoration/cobwebs.yml | 3 +- .../Structures/Decoration/crystals.yml | 3 +- .../Structures/Decoration/curtains.yml | 3 +- .../Decoration/decorated_fir_tree.yml | 3 +- .../Structures/Decoration/fireplace.yml | 3 +- .../Structures/Decoration/mannequin.yml | 3 +- .../Structures/Decoration/showcase.yml | 3 +- .../Structures/Decoration/statues.yml | 3 +- .../Dispensers/base_structuredispensers.yml | 3 +- .../Doors/Airlocks/base_assembly.yml | 3 +- .../Doors/Airlocks/base_structureairlocks.yml | 3 +- .../Structures/Doors/Airlocks/highsec.yml | 3 +- .../Structures/Doors/Firelocks/firelock.yml | 3 +- .../Structures/Doors/Firelocks/frame.yml | 3 +- .../Doors/MaterialDoors/material_doors.yml | 3 +- .../Doors/SecretDoor/secret_door.yml | 6 ++- .../Structures/Doors/Shutter/blast_door.yml | 9 ++-- .../Structures/Doors/Shutter/shutters.yml | 6 ++- .../Structures/Doors/Windoors/assembly.yml | 3 +- .../Doors/Windoors/base_structurewindoors.yml | 3 +- .../Entities/Structures/Doors/turnstile.yml | 3 +- .../Furniture/Tables/base_structuretables.yml | 3 +- .../Structures/Furniture/Tables/tables.yml | 24 ++++++---- .../Entities/Structures/Furniture/altar.yml | 3 +- .../Entities/Structures/Furniture/beds.yml | 3 +- .../Structures/Furniture/bookshelf.yml | 1 + .../Entities/Structures/Furniture/carpets.yml | 5 ++- .../Entities/Structures/Furniture/chairs.yml | 6 ++- .../Entities/Structures/Furniture/dresser.yml | 1 + .../Structures/Furniture/potted_plants.yml | 1 + .../Entities/Structures/Furniture/sink.yml | 3 +- .../Structures/Holographic/projections.yml | 1 + .../Structures/Lighting/base_lighting.yml | 4 +- .../Structures/Lighting/ground_lighting.yml | 3 +- .../Structures/Lighting/strobe_lighting.yml | 3 +- .../Machines/Computers/computers.yml | 6 ++- .../Structures/Machines/Computers/frame.yml | 3 +- .../Structures/Machines/Medical/cryo_pod.yml | 3 +- .../Machines/base_structuremachines.yml | 3 +- .../Structures/Machines/cloning_machine.yml | 3 +- .../Structures/Machines/fatextractor.yml | 3 +- .../Entities/Structures/Machines/frame.yml | 9 ++-- .../Entities/Structures/Machines/jukebox.yml | 3 +- .../Structures/Machines/mail_teleporter.yml | 3 +- .../Structures/Machines/medical_scanner.yml | 3 +- .../Structures/Machines/smartfridge.yml | 3 +- .../Structures/Machines/stasisbed.yml | 3 +- .../Machines/wireless_surveillance_camera.yml | 3 +- .../Structures/Piping/Atmospherics/pipes.yml | 3 +- .../Piping/Atmospherics/portable.yml | 6 ++- .../Disposal/high_pressure_machine_frame.yml | 3 +- .../Structures/Piping/Disposal/pipes.yml | 3 +- .../Power/Generation/Singularity/emitter.yml | 3 +- .../Power/Generation/Tesla/coil.yml | 2 + .../Structures/Power/Generation/ame.yml | 6 ++- .../Power/Generation/generators.yml | 3 +- .../Structures/Power/Generation/solar.yml | 9 ++-- .../Entities/Structures/Power/apc.yml | 3 +- .../Structures/Power/cable_terminal.yml | 3 +- .../Entities/Structures/Power/cables.yml | 4 +- .../Entities/Structures/Power/debug_power.yml | 3 +- .../Entities/Structures/Power/smes.yml | 3 +- .../Entities/Structures/Power/substation.yml | 3 +- .../Entities/Structures/Shuttles/cannons.yml | 6 ++- .../Structures/Shuttles/station_anchor.yml | 3 +- .../Structures/Shuttles/thrusters.yml | 9 ++-- .../Structures/Specific/Anomaly/anomalies.yml | 3 +- .../Specific/Atmospherics/sensor.yml | 3 +- .../Structures/Specific/Cargo/mailcart.yml | 3 +- .../Structures/Specific/Janitor/drain.yml | 3 +- .../Structures/Specific/Janitor/janicart.yml | 4 +- .../Structures/Specific/church-bell.yml | 1 + .../Entities/Structures/Specific/dragon.yml | 3 +- .../Entities/Structures/Specific/xeno.yml | 3 +- .../Storage/Canisters/gas_canisters.yml | 6 ++- .../Closets/Lockers/base_structurelockers.yml | 3 +- .../Storage/Closets/base_structureclosets.yml | 6 ++- .../Structures/Storage/Closets/big_boxes.yml | 1 + .../Storage/Crates/base_structurecrates.yml | 6 ++- .../Storage/Tanks/base_structuretanks.yml | 3 +- .../Structures/Storage/filing_cabinets.yml | 3 +- .../Entities/Structures/Storage/glass_box.yml | 3 +- .../Entities/Structures/Storage/ore_box.yml | 3 +- .../Entities/Structures/Storage/storage.yml | 3 +- .../Wallmounts/Misc/noticeboard.yml | 1 + .../Structures/Wallmounts/Signs/posters.yml | 3 +- .../Structures/Wallmounts/Storage/shelfs.yml | 3 ++ .../WallmountMachines/air_alarm.yml | 3 +- .../WallmountMachines/fire_alarm.yml | 3 +- .../WallmountMachines/surveillance_camera.yml | 6 ++- .../Structures/Wallmounts/base_wallmount.yml | 6 ++- .../Structures/Wallmounts/turret_controls.yml | 3 +- .../Entities/Structures/Walls/asteroid.yml | 6 ++- .../Entities/Structures/Walls/fence_metal.yml | 3 +- .../Entities/Structures/Walls/fence_wood.yml | 3 +- .../Entities/Structures/Walls/girders.yml | 3 +- .../Entities/Structures/Walls/grille.yml | 6 ++- .../Structures/Walls/inflatable_wall.yml | 6 ++- .../Entities/Structures/Walls/railing.yml | 3 +- .../Entities/Structures/Walls/walls.yml | 33 +++++++++----- .../Entities/Structures/Windows/clockwork.yml | 3 +- .../Entities/Structures/Windows/mining.yml | 3 +- .../Entities/Structures/Windows/plasma.yml | 3 +- .../Structures/Windows/plastitanium.yml | 6 ++- .../Structures/Windows/reinforced.yml | 3 +- .../Entities/Structures/Windows/rplasma.yml | 3 +- .../Entities/Structures/Windows/ruranium.yml | 3 +- .../Entities/Structures/Windows/shuttle.yml | 3 +- .../Entities/Structures/Windows/uranium.yml | 3 +- .../Entities/Structures/Windows/window.yml | 6 ++- .../Entities/Structures/barricades.yml | 1 + .../Entities/Structures/cargo_telepad.yml | 3 +- .../Entities/Structures/catwalk.yml | 3 +- .../Entities/Structures/conveyor.yml | 3 +- .../Entities/Structures/ironsand_steps.yml | 3 +- .../Prototypes/Entities/Structures/lever.yml | 3 +- .../Entities/Structures/meat_spike.yml | 3 +- .../Entities/Structures/plastic_flaps.yml | 3 +- .../Prototypes/Entities/Structures/soil.yml | 3 +- .../Prototypes/Entities/Structures/stairs.yml | 3 +- .../Prototypes/Entities/Tiles/bananium.yml | 3 +- Resources/Prototypes/Magic/animate_spell.yml | 3 +- 226 files changed, 617 insertions(+), 305 deletions(-) create mode 100644 Content.Shared/Damage/Components/InjurableComponent.cs diff --git a/Content.Client/Damage/DamageVisualsSystem.cs b/Content.Client/Damage/DamageVisualsSystem.cs index a7eed4b06c..2541c27e5d 100644 --- a/Content.Client/Damage/DamageVisualsSystem.cs +++ b/Content.Client/Damage/DamageVisualsSystem.cs @@ -136,7 +136,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem(entity, out var damageComponent) + || !TryComp(entity, out var injurableComponent) || !HasComp(entity)) return; @@ -152,8 +152,8 @@ public sealed class DamageVisualsSystem : VisualizerSystem(damageComponent.DamageContainerID, out var damageContainer)) + if (injurableComponent.DamageContainer != null + && _prototypeManager.Resolve(injurableComponent.DamageContainer, out var damageContainer)) { // Are we using damage overlay sprites by group? // Check if the container matches the supported groups, @@ -559,12 +559,12 @@ public sealed class DamageVisualsSystem : VisualizerSystem= 0) { threshold = damageVisComp.Thresholds[thresholdIndex]; } diff --git a/Content.Client/Overlays/EntityHealthBarOverlay.cs b/Content.Client/Overlays/EntityHealthBarOverlay.cs index e0bc50a33c..db4e9a7873 100644 --- a/Content.Client/Overlays/EntityHealthBarOverlay.cs +++ b/Content.Client/Overlays/EntityHealthBarOverlay.cs @@ -56,18 +56,19 @@ public sealed class EntityHealthBarOverlay : Overlay var handle = args.WorldHandle; var rotation = args.Viewport.Eye?.Rotation ?? Angle.Zero; var xformQuery = _entManager.GetEntityQuery(); + var spriteQuery = _entManager.GetEntityQuery(); const float scale = 1f; var scaleMatrix = Matrix3Helpers.CreateScale(new Vector2(scale, scale)); var rotationMatrix = Matrix3Helpers.CreateRotation(-rotation); _prototype.Resolve(StatusIcon, out var statusIcon); - var query = _entManager.AllEntityQueryEnumerator(); + var query = _entManager.AllEntityQueryEnumerator(); while (query.MoveNext(out var uid, out var mobThresholdsComponent, out var mobStateComponent, out var damageableComponent, - out var spriteComponent)) + out var injurableComponent)) { if (statusIcon != null && !_statusIconSystem.IsVisible((uid, _entManager.GetComponent(uid)), statusIcon)) continue; @@ -77,11 +78,15 @@ public sealed class EntityHealthBarOverlay : Overlay xform.MapID != args.MapId) continue; - if (damageableComponent.DamageContainerID == null || !DamageContainers.Contains(damageableComponent.DamageContainerID)) + if (injurableComponent.DamageContainer == null || !DamageContainers.Contains(injurableComponent.DamageContainer)) + continue; + + if (!spriteQuery.TryGetComponent(uid, out var sprite)) continue; // we use the status icon component bounds if specified otherwise use sprite - var bounds = _entManager.GetComponentOrNull(uid)?.Bounds ?? _spriteSystem.GetLocalBounds((uid, spriteComponent)); + var bounds = _entManager.GetComponentOrNull(uid)?.Bounds ?? _spriteSystem.GetLocalBounds( + (uid, sprite)); var worldPos = _transform.GetWorldPosition(xform, xformQuery); if (!bounds.Translated(worldPos).Intersects(args.WorldAABB)) @@ -135,9 +140,6 @@ public sealed class EntityHealthBarOverlay : Overlay var totalDamage = _damageable.GetTotalDamage((uid, dmg)); if (_mobStateSystem.IsAlive(uid, component)) { - if (dmg.HealthBarThreshold != null && totalDamage < dmg.HealthBarThreshold) - return null; - if (!_mobThresholdSystem.TryGetThresholdForState(uid, MobState.Critical, out var threshold, thresholds) && !_mobThresholdSystem.TryGetThresholdForState(uid, MobState.Dead, out threshold, thresholds)) return (1, false); diff --git a/Content.Client/Overlays/ShowHealthIconsSystem.cs b/Content.Client/Overlays/ShowHealthIconsSystem.cs index 42697098cb..b7dd0cfddd 100644 --- a/Content.Client/Overlays/ShowHealthIconsSystem.cs +++ b/Content.Client/Overlays/ShowHealthIconsSystem.cs @@ -23,7 +23,7 @@ public sealed class ShowHealthIconsSystem : EquipmentHudSystem(OnGetStatusIconsEvent); + SubscribeLocalEvent(OnGetStatusIconsEvent); SubscribeLocalEvent(OnHandleState); } @@ -53,7 +53,7 @@ public sealed class ShowHealthIconsSystem : EquipmentHudSystem entity, ref GetStatusIconsEvent args) + private void OnGetStatusIconsEvent(Entity entity, ref GetStatusIconsEvent args) { if (!IsActive) return; @@ -63,12 +63,12 @@ public sealed class ShowHealthIconsSystem : EquipmentHudSystem DecideHealthIcons(Entity entity) + private IReadOnlyList DecideHealthIcons(Entity entity) { - var damageableComponent = entity.Comp; + var injurableComp = entity.Comp; - if (damageableComponent.DamageContainerID == null || - !DamageContainers.Contains(damageableComponent.DamageContainerID)) + if (injurableComp.DamageContainer == null || + !DamageContainers.Contains(injurableComp.DamageContainer)) { return Array.Empty(); } @@ -76,14 +76,14 @@ public sealed class ShowHealthIconsSystem : EquipmentHudSystem(); // Here you could check health status, diseases, mind status, etc. and pick a good icon, or multiple depending on whatever. - if (damageableComponent?.DamageContainerID == "Biological") + if (injurableComp?.DamageContainer == "Biological") { if (TryComp(entity, out var state)) { // Since there is no MobState for a rotting mob, we have to deal with this case first. - if (HasComp(entity) && _prototypeMan.Resolve(damageableComponent.RottingIcon, out var rottingIcon)) + if (HasComp(entity) && _prototypeMan.Resolve(injurableComp.RottingIcon, out var rottingIcon)) result.Add(rottingIcon); - else if (damageableComponent.HealthIcons.TryGetValue(state.CurrentState, out var value) && _prototypeMan.Resolve(value, out var icon)) + else if (injurableComp.HealthIcons.TryGetValue(state.CurrentState, out var value) && _prototypeMan.Resolve(value, out var icon)) result.Add(icon); } } diff --git a/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs b/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs index 3c14e7c6b7..a97d25fdab 100644 --- a/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs +++ b/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs @@ -76,11 +76,12 @@ public sealed class DamageOverlayUiController : UIController } //TODO: Jezi: adjust oxygen and hp overlays to use appropriate systems once bodysim is implemented - private void UpdateOverlays(EntityUid entity, MobStateComponent? mobState, DamageableComponent? damageable = null, MobThresholdsComponent? thresholds = null) + private void UpdateOverlays(EntityUid entity, MobStateComponent? mobState, DamageableComponent? damageable = null, MobThresholdsComponent? thresholds = null, InjurableComponent? injurable = null) { if (mobState == null && !EntityManager.TryGetComponent(entity, out mobState) || thresholds == null && !EntityManager.TryGetComponent(entity, out thresholds) || - damageable == null && !EntityManager.TryGetComponent(entity, out damageable)) + damageable == null && !EntityManager.TryGetComponent(entity, out damageable) || + injurable == null && !EntityManager.TryGetComponent(entity, out injurable)) return; if (!_mobThresholdSystem.TryGetIncapThreshold(entity, out var foundThreshold, thresholds)) @@ -105,7 +106,7 @@ public sealed class DamageOverlayUiController : UIController if (!_statusEffects.TryEffectsWithComp(entity, out _)) { - foreach (var painDamageType in damageable.PainDamageGroups) + foreach (var painDamageType in injurable.PainDamageGroups) { damagePerGroup.TryGetValue(painDamageType, out var painDamage); diff --git a/Content.IntegrationTests/Tests/Atmos/DeltaPressureTest.cs b/Content.IntegrationTests/Tests/Atmos/DeltaPressureTest.cs index d4283568e8..5c7ddc6726 100644 --- a/Content.IntegrationTests/Tests/Atmos/DeltaPressureTest.cs +++ b/Content.IntegrationTests/Tests/Atmos/DeltaPressureTest.cs @@ -52,6 +52,7 @@ public sealed class DeltaPressureTest : AtmosTest types: Structural: 1000 - type: Damageable + - type: Injurable - type: Destructible thresholds: - trigger: diff --git a/Content.IntegrationTests/Tests/Commands/RejuvenateTest.cs b/Content.IntegrationTests/Tests/Commands/RejuvenateTest.cs index 15d93c40ae..2b62926dc1 100644 --- a/Content.IntegrationTests/Tests/Commands/RejuvenateTest.cs +++ b/Content.IntegrationTests/Tests/Commands/RejuvenateTest.cs @@ -26,6 +26,7 @@ namespace Content.IntegrationTests.Tests.Commands id: DamageableDummy components: - type: Damageable + - type: Injurable damageContainer: Biological - type: MobState - type: MobThresholds diff --git a/Content.IntegrationTests/Tests/Damageable/DamageableTest.cs b/Content.IntegrationTests/Tests/Damageable/DamageableTest.cs index 758bbe0a50..f274e1e419 100644 --- a/Content.IntegrationTests/Tests/Damageable/DamageableTest.cs +++ b/Content.IntegrationTests/Tests/Damageable/DamageableTest.cs @@ -90,6 +90,7 @@ namespace Content.IntegrationTests.Tests.Damageable name: {TestDamageableEntityId} components: - type: Damageable + - type: Injurable damageContainer: testDamageContainer "; diff --git a/Content.IntegrationTests/Tests/Destructible/DestructibleTestPrototypes.cs b/Content.IntegrationTests/Tests/Destructible/DestructibleTestPrototypes.cs index 872e414ac3..65af8ca0f1 100644 --- a/Content.IntegrationTests/Tests/Destructible/DestructibleTestPrototypes.cs +++ b/Content.IntegrationTests/Tests/Destructible/DestructibleTestPrototypes.cs @@ -67,6 +67,7 @@ namespace Content.IntegrationTests.Tests.Destructible name: {DestructibleEntityId} components: - type: Damageable + - type: Injurable - type: Destructible thresholds: - trigger: @@ -94,6 +95,7 @@ namespace Content.IntegrationTests.Tests.Destructible name: {DestructibleDestructionEntityId} components: - type: Damageable + - type: Injurable - type: Destructible thresholds: - trigger: @@ -116,6 +118,7 @@ namespace Content.IntegrationTests.Tests.Destructible name: {DestructibleDamageTypeEntityId} components: - type: Damageable + - type: Injurable - type: Destructible thresholds: - trigger: @@ -133,6 +136,7 @@ namespace Content.IntegrationTests.Tests.Destructible name: {DestructibleDamageGroupEntityId} components: - type: Damageable + - type: Injurable - type: Destructible thresholds: - trigger: diff --git a/Content.IntegrationTests/Tests/Disposal/DisposalUnitTest.cs b/Content.IntegrationTests/Tests/Disposal/DisposalUnitTest.cs index f7b20819c2..79496f5a0e 100644 --- a/Content.IntegrationTests/Tests/Disposal/DisposalUnitTest.cs +++ b/Content.IntegrationTests/Tests/Disposal/DisposalUnitTest.cs @@ -85,6 +85,7 @@ namespace Content.IntegrationTests.Tests.Disposal 0: Alive 200: Dead - type: Damageable + - type: Injurable damageContainer: Biological - type: Physics bodyType: KinematicController diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.cs b/Content.IntegrationTests/Tests/Minds/MindTests.cs index 08cfbaed5e..7abc0ce9da 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.cs @@ -35,6 +35,7 @@ public sealed partial class MindTests : GameTest components: - type: MindContainer - type: Damageable + - type: Injurable damageContainer: Biological - type: Body prototype: Human diff --git a/Content.IntegrationTests/Tests/Storage/EntityStorageTests.cs b/Content.IntegrationTests/Tests/Storage/EntityStorageTests.cs index 6b100f89fd..ada5ebbde1 100644 --- a/Content.IntegrationTests/Tests/Storage/EntityStorageTests.cs +++ b/Content.IntegrationTests/Tests/Storage/EntityStorageTests.cs @@ -18,6 +18,7 @@ public sealed class EntityStorageTests : GameTest components: - type: EntityStorage - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Content.IntegrationTests/Tests/VendingMachineRestockTest.cs b/Content.IntegrationTests/Tests/VendingMachineRestockTest.cs index dfaaae05ad..70bff34f63 100644 --- a/Content.IntegrationTests/Tests/VendingMachineRestockTest.cs +++ b/Content.IntegrationTests/Tests/VendingMachineRestockTest.cs @@ -81,8 +81,9 @@ namespace Content.IntegrationTests.Tests name: TestRestockExplode components: - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Airtight.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Airtight.cs index 4428c8eb0e..1f6949f491 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Airtight.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Airtight.cs @@ -219,7 +219,7 @@ public sealed partial class ExplosionSystem totalDamageTarget = _destructibleSystem.DestroyedAt(uid, destructible); } - if (totalDamageTarget == FixedPoint2.MaxValue || !_damageableQuery.TryGetComponent(uid, out var damageable)) + if (totalDamageTarget == FixedPoint2.MaxValue || !_injurableQuery.TryGetComponent(uid, out var injurable)) { for (var i = 0; i < explosionTolerance.Length; i++) { @@ -245,7 +245,7 @@ public sealed partial class ExplosionSystem var damagePerIntensity = FixedPoint2.Zero; foreach (var (type, value) in explosionType.DamagePerIntensity.DamageDict) { - if (!_damageableSystem.CanBeDamagedBy((uid, damageable), type)) + if (!_damageableSystem.CanBeDamagedBy((uid, injurable), type)) continue; // TODO EXPLOSION SYSTEM @@ -260,7 +260,7 @@ public sealed partial class ExplosionSystem } var toleranceValue = damagePerIntensity > 0 - ? (float) ((totalDamageTarget - _damageableSystem.GetTotalDamage((uid, damageable))) / damagePerIntensity) + ? (float) ((totalDamageTarget - _damageableSystem.GetTotalDamage(uid)) / damagePerIntensity) : ToleranceValues.Invulnerable; explosionTolerance[index] = toleranceValue; diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs index 400f555db4..60de86401f 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs @@ -65,6 +65,7 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem private EntityQuery _actorQuery; private EntityQuery _destructibleQuery; private EntityQuery _damageableQuery; + [Dependency] private readonly EntityQuery _injurableQuery = default!; private EntityQuery _airtightQuery; private EntityQuery _tileHistoryQuery; diff --git a/Content.Shared/Damage/Components/DamageableComponent.cs b/Content.Shared/Damage/Components/DamageableComponent.cs index a78cacf16a..7476199829 100644 --- a/Content.Shared/Damage/Components/DamageableComponent.cs +++ b/Content.Shared/Damage/Components/DamageableComponent.cs @@ -21,14 +21,6 @@ namespace Content.Shared.Damage.Components; [Access(typeof(DamageableSystem), Other = AccessPermissions.ReadExecute)] public sealed partial class DamageableComponent : Component { - /// - /// This specifies what damage types are supported by this component. - /// If null, all damage types will be supported. - /// - [DataField("damageContainer")] - // ReSharper disable once InconsistentNaming - This is wrong but fixing it is potentially annoying for downstreams. - public ProtoId? DamageContainerID; - /// /// This will be applied to any damage that is dealt to this container, /// unless the damage explicitly ignores resistances. @@ -71,40 +63,14 @@ public sealed partial class DamageableComponent : Component [DataField("radiationDamageTypes")] // ReSharper disable once UseCollectionExpression - Cannot refactor this as it's a potential sandbox violation. public List> RadiationDamageTypeIDs = new() { "Radiation" }; - - /// - /// Group types that affect the pain overlay. - /// - /// TODO: Add support for adding damage types specifically rather than whole damage groups - [DataField] - // ReSharper disable once UseCollectionExpression - Cannot refactor this as it's a potential sandbox volation. - public List> PainDamageGroups = new() { "Brute", "Burn" }; - - [DataField] - public Dictionary> HealthIcons = new() - { - { MobState.Alive, "HealthIconFine" }, - { MobState.Critical, "HealthIconCritical" }, - { MobState.Dead, "HealthIconDead" }, - }; - - [DataField] - public ProtoId RottingIcon = "HealthIconRotting"; - - [DataField] - public FixedPoint2? HealthBarThreshold; } [Serializable, NetSerializable] public sealed class DamageableComponentState( DamageSpecifier damage, - ProtoId? damageContainerId, - ProtoId? modifierSetId, - FixedPoint2? healthBarThreshold) + ProtoId? modifierSetId) : ComponentState { public readonly DamageSpecifier Damage = damage; - public readonly ProtoId? DamageContainerId = damageContainerId; public readonly ProtoId? ModifierSetId = modifierSetId; - public readonly FixedPoint2? HealthBarThreshold = healthBarThreshold; } diff --git a/Content.Shared/Damage/Components/InjurableComponent.cs b/Content.Shared/Damage/Components/InjurableComponent.cs new file mode 100644 index 0000000000..e79d9e0811 --- /dev/null +++ b/Content.Shared/Damage/Components/InjurableComponent.cs @@ -0,0 +1,41 @@ +using Content.Shared.Damage.Prototypes; +using Content.Shared.Mobs; +using Content.Shared.StatusIcon; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Damage.Components; + +/// +/// Manages the damage of a with a 'simple damage' model +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class InjurableComponent : Component +{ + /// + /// This specifies what damage types are supported by this component. + /// If null, all damage types will be supported. + /// + [DataField, AutoNetworkedField] + // ReSharper disable once InconsistentNaming - This is wrong but fixing it is potentially annoying for downstreams. + public ProtoId? DamageContainer; + + /// + /// Group types that affect the pain overlay. + /// + /// TODO: Add support for adding damage types specifically rather than whole damage groups + [DataField] + // ReSharper disable once UseCollectionExpression - Cannot refactor this as it's a potential sandbox volation. + public List> PainDamageGroups = new() { "Brute", "Burn" }; + + [DataField] + public Dictionary> HealthIcons = new() + { + { MobState.Alive, "HealthIconFine" }, + { MobState.Critical, "HealthIconCritical" }, + { MobState.Dead, "HealthIconDead" }, + }; + + [DataField] + public ProtoId RottingIcon = "HealthIconRotting"; +} diff --git a/Content.Shared/Damage/Systems/DamageableSystem.API.cs b/Content.Shared/Damage/Systems/DamageableSystem.API.cs index 2975f22762..c2b92bf566 100644 --- a/Content.Shared/Damage/Systems/DamageableSystem.API.cs +++ b/Content.Shared/Damage/Systems/DamageableSystem.API.cs @@ -19,9 +19,6 @@ public sealed partial class DamageableSystem /// /// Directly sets the damage in a damageable component. - /// This method keeps the damage types supported by the DamageContainerPrototype in the component. - /// If a type is given in , but not supported then it will not be set. - /// If a type is supported but not given in then it will be set to 0. /// /// /// Useful for some unfriendly folk. Also ensures that cached values are updated and that a damage changed @@ -40,8 +37,7 @@ public sealed partial class DamageableSystem foreach (var (type, amount) in damage.DamageDict) { - if (SupportsType(ent.Comp.DamageContainerID, type)) - ent.Comp.Damage.DamageDict[type] = amount; + ent.Comp.Damage.DamageDict[type] = amount; } OnEntityDamageChanged((ent, ent.Comp)); @@ -108,7 +104,7 @@ public sealed partial class DamageableSystem /// stored damage data. Division of group damage into types is managed by . /// /// - /// The actual amount of damage taken, as a DamageSpecifier. + /// The actual amount of damage dealt, as a DamageSpecifier. /// public DamageSpecifier ChangeDamage( Entity ent, @@ -155,28 +151,10 @@ public sealed partial class DamageableSystem if (!ignoreGlobalModifiers) damage = ApplyUniversalAllModifiers(damage); + var evt = new DamageDealtEvent(damage, origin, interruptsDoAfters); + RaiseLocalEvent(ent, ref evt); - damageDone.DamageDict.EnsureCapacity(damage.DamageDict.Count); - - var dict = ent.Comp.Damage.DamageDict; - foreach (var (type, value) in damage.DamageDict) - { - if (!SupportsType(ent.Comp.DamageContainerID, type)) - continue; - - var oldValue = dict.GetValueOrDefault(type); - var newValue = FixedPoint2.Max(FixedPoint2.Zero, oldValue + value); - if (newValue == oldValue) - continue; - - dict[type] = newValue; - damageDone.DamageDict[type] = newValue - oldValue; - } - - if (!damageDone.Empty) - OnEntityDamageChanged((ent, ent.Comp), damageDone, interruptsDoAfters, origin); - - return damageDone; + return damage; } /// @@ -469,11 +447,11 @@ public sealed partial class DamageableSystem /// Returns whether the entity can be damaged by the given type of damage /// [Obsolete("Do not rely on the ability to determine if an entity will be able to be damaged by something")] - public bool CanBeDamagedBy(Entity ent, ProtoId type) + public bool CanBeDamagedBy(Entity ent, ProtoId type) { - if (!_damageableQuery.Resolve(ent, ref ent.Comp, false)) + if (!_injurableQuery.Resolve(ent, ref ent.Comp, false)) return false; - return SupportsType(ent.Comp.DamageContainerID, type); + return SupportsType(ent.Comp.DamageContainer, type); } } diff --git a/Content.Shared/Damage/Systems/DamageableSystem.Events.cs b/Content.Shared/Damage/Systems/DamageableSystem.Events.cs index 36f997c5a9..fbcb9b94a0 100644 --- a/Content.Shared/Damage/Systems/DamageableSystem.Events.cs +++ b/Content.Shared/Damage/Systems/DamageableSystem.Events.cs @@ -22,6 +22,7 @@ public sealed partial class DamageableSystem SubscribeLocalEvent(OnRejuvenate); SubscribeLocalEvent(DamageableHandleState); SubscribeLocalEvent(DamageableGetState); + SubscribeLocalEvent(OnDamageDealt); // Damage modifier CVars are updated and stored here to be queried in other systems. // Note that certain modifiers requires reloading the guidebook. @@ -188,9 +189,7 @@ public sealed partial class DamageableSystem { args.State = new DamageableComponentState( _netMan.IsServer ? ent.Comp.Damage : ent.Comp.Damage.Clone(), - ent.Comp.DamageContainerID, - ent.Comp.DamageModifierSetId, - ent.Comp.HealthBarThreshold + ent.Comp.DamageModifierSetId ); } @@ -199,9 +198,7 @@ public sealed partial class DamageableSystem if (args.Current is not DamageableComponentState state) return; - ent.Comp.DamageContainerID = state.DamageContainerId; ent.Comp.DamageModifierSetId = state.ModifierSetId; - ent.Comp.HealthBarThreshold = state.HealthBarThreshold; // Has the damage actually changed? var newDamage = state.Damage.Clone(); @@ -215,6 +212,34 @@ public sealed partial class DamageableSystem OnEntityDamageChanged(ent, delta); } + + private void OnDamageDealt(Entity ent, ref DamageDealtEvent args) + { + if (!_damageableQuery.TryGetComponent(ent, out var damageable)) + return; + + var damageDone = new DamageSpecifier(); + + damageDone.DamageDict.EnsureCapacity(args.Damage.DamageDict.Count); + + var dict = damageable.Damage.DamageDict; + foreach (var (type, value) in args.Damage.DamageDict) + { + if (!SupportsType(ent.Comp.DamageContainer, type)) + continue; + + var oldValue = dict.GetValueOrDefault(type); + var newValue = FixedPoint2.Max(FixedPoint2.Zero, oldValue + value); + if (newValue == oldValue) + continue; + + dict[type] = newValue; + damageDone.DamageDict[type] = newValue - oldValue; + } + + if (!damageDone.Empty) + OnEntityDamageChanged((ent, damageable), damageDone, args.InterruptsDoAfters, args.Origin); + } } /// @@ -256,6 +281,16 @@ public sealed class DamageModifyEvent(DamageSpecifier damage, EntityUid? origin public readonly EntityUid? Origin = origin; } +/// +/// Event raised when an entity with has taken some amount of damage. +/// +/// The amount of damage the entity is being subject to. +/// The originator of the damage +/// If the damage being dealt will interrupt do-afters +[ByRefEvent] +public readonly record struct DamageDealtEvent(DamageSpecifier Damage, EntityUid? Origin, bool InterruptsDoAfters); + +[Obsolete("Will be replaced with damage-model specific events; general 'took damage' can be served by DamageDealtEvent")] public sealed class DamageChangedEvent : EntityEventArgs { /// diff --git a/Content.Shared/Damage/Systems/DamageableSystem.cs b/Content.Shared/Damage/Systems/DamageableSystem.cs index fd8564cf3c..a9b4f2dede 100644 --- a/Content.Shared/Damage/Systems/DamageableSystem.cs +++ b/Content.Shared/Damage/Systems/DamageableSystem.cs @@ -25,6 +25,7 @@ public sealed partial class DamageableSystem : EntitySystem [Dependency] private readonly EntityQuery _appearanceQuery = default!; [Dependency] private readonly EntityQuery _damageableQuery = default!; + [Dependency] private readonly EntityQuery _injurableQuery = default!; public float UniversalAllDamageModifier { get; private set; } = 1f; public float UniversalAllHealModifier { get; private set; } = 1f; diff --git a/Content.Shared/Medical/Healing/HealingSystem.cs b/Content.Shared/Medical/Healing/HealingSystem.cs index 0e9c4bf991..93d0727b7f 100644 --- a/Content.Shared/Medical/Healing/HealingSystem.cs +++ b/Content.Shared/Medical/Healing/HealingSystem.cs @@ -50,9 +50,12 @@ public sealed class HealingSystem : EntitySystem if (!TryComp(args.Used, out HealingComponent? healing)) return; + if (!TryComp(target, out var injurable)) + return; + if (healing.DamageContainers is not null && - target.Comp.DamageContainerID is not null && - !healing.DamageContainers.Contains(target.Comp.DamageContainerID.Value)) + injurable.DamageContainer is not null && + !healing.DamageContainers.Contains(injurable.DamageContainer.Value)) { return; } @@ -179,9 +182,12 @@ public sealed class HealingSystem : EntitySystem if (!Resolve(target, ref target.Comp, false)) return false; + if (!TryComp(target, out var injurable)) + return false; + if (healing.Comp.DamageContainers is not null && - target.Comp.DamageContainerID is not null && - !healing.Comp.DamageContainers.Contains(target.Comp.DamageContainerID.Value)) + injurable.DamageContainer is not null && + !healing.Comp.DamageContainers.Contains(injurable.DamageContainer.Value)) { return false; } diff --git a/Resources/Prototypes/Body/Species/skeleton.yml b/Resources/Prototypes/Body/Species/skeleton.yml index 953a8c7bae..1677643478 100644 --- a/Resources/Prototypes/Body/Species/skeleton.yml +++ b/Resources/Prototypes/Body/Species/skeleton.yml @@ -75,8 +75,9 @@ name: Urist McBones components: - type: Damageable - damageContainer: BiologicalMetaphysical damageModifierSet: Skeleton + - type: Injurable + damageContainer: BiologicalMetaphysical - type: DamageVisuals damageOverlayGroups: Brute: diff --git a/Resources/Prototypes/Entities/Clothing/Head/misc.yml b/Resources/Prototypes/Entities/Clothing/Head/misc.yml index 332efb731b..5584a7c076 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/misc.yml @@ -341,6 +341,7 @@ types: Blunt: 1 - type: Damageable + - type: Injurable damageContainer: Biological - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Effects/chemistry_effects.yml b/Resources/Prototypes/Entities/Effects/chemistry_effects.yml index 1bf3d351b3..05660888e8 100644 --- a/Resources/Prototypes/Entities/Effects/chemistry_effects.yml +++ b/Resources/Prototypes/Entities/Effects/chemistry_effects.yml @@ -199,8 +199,9 @@ replacementTiles: - FloorMetalFoam - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -254,8 +255,9 @@ - map: [ "enum.EdgeLayer.West" ] state: metal_foam-west - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: FlimsyMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index e45fd88686..ad08e1969f 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -167,6 +167,7 @@ - enum.BorgUiKey.Key - type: LockedWiresPanel - type: Damageable + - type: Injurable damageContainer: Silicon - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index c30a1f4d63..1ec65e2dc6 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -422,7 +422,6 @@ spawned: - id: FoodMeatSlime - type: Damageable - damageContainer: Biological damageModifierSet: Cockroach - type: Tag tags: @@ -561,7 +560,6 @@ weightlessFriction: 1 baseWeightlessModifier: 1 - type: Damageable - damageContainer: Biological damageModifierSet: Moth - type: Bloodstream bloodReferenceSolution: @@ -2034,7 +2032,6 @@ - id: SheetUranium1 amount: 1 - type: Damageable - damageContainer: Biological damageModifierSet: Zombie - type: entity @@ -2089,7 +2086,6 @@ - ReagentId: Blood Quantity: 150 - type: Damageable - damageContainer: Biological damageModifierSet: Scale - type: Tag tags: @@ -2491,7 +2487,6 @@ - ReagentId: Blood Quantity: 50 - type: Damageable - damageContainer: Biological damageModifierSet: Scale # Code unique spider prototypes or combine them all into one spider and get a @@ -3045,8 +3040,9 @@ - ReagentId: DemonsBlood Quantity: 150 - type: Damageable - damageContainer: BiologicalMetaphysical damageModifierSet: Infernal + - type: Injurable + damageContainer: BiologicalMetaphysical - type: Temperature currentTemperature: 310.15 specificHeat: 42 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml b/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml index b3f7749246..7a4f20d164 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml @@ -7,6 +7,7 @@ groups: Acidic: [Touch] - type: Damageable + - type: Injurable damageContainer: Inorganic - type: MovementSpeedModifier baseWalkSpeed : 2 @@ -66,7 +67,7 @@ - type: NpcFactionMember factions: - SimpleHostile - - type: Damageable + - type: Injurable damageContainer: StructuralInorganic - type: entity diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml b/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml index 2cdbad7924..180da97f76 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml @@ -29,8 +29,9 @@ factions: - SimpleHostile - type: Damageable - damageContainer: BiologicalMetaphysical damageModifierSet: HellSpawn + - type: Injurable + damageContainer: BiologicalMetaphysical - type: MovementSpeedModifier baseWalkSpeed: 2 baseSprintSpeed: 3 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/living_light.yml b/Resources/Prototypes/Entities/Mobs/NPCs/living_light.yml index 74ab0102d5..b982b4b07c 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/living_light.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/living_light.yml @@ -62,8 +62,9 @@ layer: - Opaque - type: Damageable - damageContainer: Inorganic damageModifierSet: LivingLight + - type: Injurable + damageContainer: Inorganic - type: PassiveDamage allowedStates: - Alive diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml index 04b1554cef..799fd3d5ef 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml @@ -22,8 +22,9 @@ allowed: - Corporeal - type: Damageable - damageContainer: ManifestedSpirit damageModifierSet: ManifestedSpirit + - type: Injurable + damageContainer: ManifestedSpirit - type: NoSlip - type: Eye drawFov: false diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml index 8cf988c68e..b489ff3767 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml @@ -9,6 +9,7 @@ groups: Acidic: [Touch] - type: Damageable + - type: Injurable damageContainer: Inorganic - type: MovedByPressure - type: Physics diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml index 8d8b4f763e..89d1fdbbf8 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml @@ -50,7 +50,6 @@ Asphyxiation: -1.0 maxSaturation: 15 - type: Damageable - damageContainer: Biological damageModifierSet: Slime - type: Bloodstream bloodReferenceSolution: diff --git a/Resources/Prototypes/Entities/Mobs/Player/guardian.yml b/Resources/Prototypes/Entities/Mobs/Player/guardian.yml index 44ddd11954..31fd3bfd18 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/guardian.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/guardian.yml @@ -73,6 +73,7 @@ layer: - Opaque - type: Damageable + - type: Injurable damageContainer: Biological - type: MobState allowedStates: diff --git a/Resources/Prototypes/Entities/Mobs/Player/mothershipcore.yml b/Resources/Prototypes/Entities/Mobs/Player/mothershipcore.yml index f5897fd2c9..7cf26940e9 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/mothershipcore.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/mothershipcore.yml @@ -11,6 +11,7 @@ - type: Appearance - type: WiresVisuals - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Fixtures fixtures: diff --git a/Resources/Prototypes/Entities/Mobs/base.yml b/Resources/Prototypes/Entities/Mobs/base.yml index c09faf40bd..8c74d49989 100644 --- a/Resources/Prototypes/Entities/Mobs/base.yml +++ b/Resources/Prototypes/Entities/Mobs/base.yml @@ -69,6 +69,7 @@ abstract: true components: - type: Damageable + - type: Injurable damageContainer: Biological - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base_materials.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base_materials.yml index 939d17ca21..9ae86ca016 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base_materials.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base_materials.yml @@ -8,8 +8,9 @@ id: DrinkBaseMaterialGlass components: - type: Damageable - damageContainer: Inorganic damageModifierSet: FlimsyGlass + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: # Overkill threshold @@ -84,6 +85,7 @@ id: DrinkBaseMaterialPlastic components: - type: Damageable + - type: Injurable damageContainer: Inorganic # damageModifierSet: FlimsyPlastic TODO - type: Destructible @@ -159,8 +161,9 @@ id: DrinkBaseMaterialCardboard components: - type: Damageable - damageContainer: Inorganic damageModifierSet: Card + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: # Overkill threshold @@ -198,8 +201,9 @@ id: DrinkBaseMaterialMetal components: - type: Damageable - damageContainer: Inorganic damageModifierSet: FlimsyMetallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: # Overkill threshold @@ -267,8 +271,9 @@ id: DrinkBaseMaterialGold components: - type: Damageable - damageContainer: Inorganic damageModifierSet: FlimsyMetallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: # Overkill threshold diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/plate.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/plate.yml index 36dff3a8d6..62a09538dc 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/plate.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/plate.yml @@ -33,6 +33,7 @@ types: Blunt: 5 - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml index ff92ad0417..cda1735790 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml @@ -47,6 +47,7 @@ types: Blunt: 3 - type: Damageable + - type: Injurable damageContainer: Inorganic - type: StaticPrice price: 50 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml index e19859f16e..80e7123abe 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml @@ -38,6 +38,7 @@ types: Blunt: 1 - type: Damageable + - type: Injurable damageContainer: Biological - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml index d9a06b89ef..9b3f0520a3 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml @@ -30,6 +30,7 @@ solution: food utensil: Spoon - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Spillable solution: food diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml index 118c008291..b45c77966d 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml @@ -306,6 +306,7 @@ stunChance: 0.10 stunSeconds: 1.5 - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: @@ -926,6 +927,7 @@ - ReagentId: JuiceTomato Quantity: 10 - type: Damageable + - type: Injurable damageContainer: Biological - type: DamageOnHighSpeedImpact minimumSpeed: 0.1 @@ -1815,6 +1817,7 @@ - type: Extractable grindableSolutionName: food - type: Damageable + - type: Injurable damageContainer: Inorganic - type: ToolRefinable refineResult: @@ -2131,6 +2134,7 @@ - ReagentId: JuiceWatermelon Quantity: 20 - type: Damageable + - type: Injurable damageContainer: Biological - type: DamageOnHighSpeedImpact minimumSpeed: 0.1 @@ -2234,6 +2238,7 @@ - ReagentId: Wine Quantity: 20 - type: Damageable + - type: Injurable damageContainer: Biological - type: DamageOnHighSpeedImpact minimumSpeed: 0.1 @@ -2536,6 +2541,7 @@ - type: Produce seedId: pumpkin - type: Damageable + - type: Injurable damageContainer: Biological - type: Destructible thresholds: @@ -2593,6 +2599,7 @@ - type: Produce seedId: bluePumpkin - type: Damageable + - type: Injurable damageContainer: Biological - type: Destructible thresholds: @@ -2838,6 +2845,7 @@ intensitySlope: 1 totalIntensity: 0.1 - type: Damageable + - type: Injurable damageContainer: Biological - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/soup.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/soup.yml index 47db7366f7..0adee3d271 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/soup.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/soup.yml @@ -40,6 +40,7 @@ types: Blunt: 0 - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Tag tags: diff --git a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml index b4a6cef811..cd1b3402c6 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml @@ -22,8 +22,9 @@ - Opaque - type: Climbable - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: @@ -57,8 +58,9 @@ layer: - WallLayer - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: MeleeSound soundGroups: Brute: diff --git a/Resources/Prototypes/Entities/Objects/Decoration/mining.yml b/Resources/Prototypes/Entities/Objects/Decoration/mining.yml index 690841b3e2..aa3fa056a5 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/mining.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/mining.yml @@ -18,8 +18,9 @@ bounds: "-0.35,-0.4,0.35,0.4" density: 100 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: MeleeSound soundGroups: Brute: @@ -72,8 +73,9 @@ sprite: Objects/Decoration/mines.rsi state: support - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: Physics bodyType: Static - type: Fixtures @@ -153,8 +155,9 @@ sprite: Objects/Decoration/mines.rsi state: support_wall - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: Physics bodyType: Static - type: Fixtures diff --git a/Resources/Prototypes/Entities/Objects/Deliveries/deliveries.yml b/Resources/Prototypes/Entities/Objects/Deliveries/deliveries.yml index 9267009b3e..8c43e76ecd 100644 --- a/Resources/Prototypes/Entities/Objects/Deliveries/deliveries.yml +++ b/Resources/Prototypes/Entities/Objects/Deliveries/deliveries.yml @@ -180,6 +180,7 @@ components: - type: DeliveryFragile - type: Damageable + - type: Injurable damageContainer: Inorganic - type: DamageOnHighSpeedImpact minimumSpeed: 0.1 diff --git a/Resources/Prototypes/Entities/Objects/Devices/payload.yml b/Resources/Prototypes/Entities/Objects/Devices/payload.yml index e5dc07c7c1..a18d533fd8 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/payload.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/payload.yml @@ -9,6 +9,7 @@ tags: - Payload - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Devices/station_beacon.yml b/Resources/Prototypes/Entities/Objects/Devices/station_beacon.yml index ff6d5a6a4a..ecc506862b 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/station_beacon.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/station_beacon.yml @@ -48,8 +48,9 @@ - type: Transform anchored: true - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: # for nukes diff --git a/Resources/Prototypes/Entities/Objects/Devices/station_map.yml b/Resources/Prototypes/Entities/Objects/Devices/station_map.yml index 8724a4060b..9efe6afc7a 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/station_map.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/station_map.yml @@ -17,6 +17,7 @@ singleUser: true key: enum.StationMapUiKey.Key - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml b/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml index 5153c9dc39..621b086084 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml @@ -20,6 +20,7 @@ - gloves - type: Appearance - type: Damageable + - type: Injurable damageContainer: Inorganic - type: StaticPrice price: 50 diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml index 61b976c4d3..d39a9e0e7d 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml @@ -40,8 +40,9 @@ - type: Sprite sprite: Objects/Fun/Instruments/structureinstruments.rsi - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml index 157dd56731..48478e1f0e 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml @@ -95,6 +95,7 @@ sprite: Objects/Fun/Instruments/guitar.rsi - type: Wieldable - type: Damageable # Smash it! Does 20 damage a hit, but breaks after 1 hit. + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Fun/balloons.yml b/Resources/Prototypes/Entities/Objects/Fun/balloons.yml index f5193896a0..6a56c8b258 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/balloons.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/balloons.yml @@ -15,6 +15,7 @@ - type: EmitSoundOnLand sound: *SoundBalloonHit - type: Damageable + - type: Injurable damageContainer: Inorganic - type: TileFrictionModifier modifier: 0.3 diff --git a/Resources/Prototypes/Entities/Objects/Fun/darts.yml b/Resources/Prototypes/Entities/Objects/Fun/darts.yml index 538cfaffa0..9ecf62715e 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/darts.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/darts.yml @@ -61,6 +61,7 @@ - type: SolutionTransfer maxTransferAmount: 2 - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Fun/orbs.yml b/Resources/Prototypes/Entities/Objects/Fun/orbs.yml index 86d645ee85..3f04c6b80b 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/orbs.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/orbs.yml @@ -142,6 +142,7 @@ - ReagentId: Ethanol Quantity: 20 - type: Damageable + - type: Injurable damageContainer: Inorganic - type: DamageOnLand damage: diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index 65c47dfd5c..112f9e8f58 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -13,6 +13,7 @@ - type: Item size: Tiny - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml index 70c823b765..5ae1f06089 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml @@ -18,8 +18,9 @@ - ConstructionMaterial - type: Material - type: Damageable - damageContainer: Inorganic damageModifierSet: Glass + - type: Injurable + damageContainer: Inorganic - type: Appearance - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml index 1cc4c3a5f5..fad87e7f69 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml @@ -17,8 +17,9 @@ - Metal - ConstructionMaterial - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml index 66edafe763..280c1f71bf 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml @@ -14,6 +14,7 @@ - Sheet - ConstructionMaterial - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml b/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml index 25d80eaee6..57fa544df1 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml @@ -27,8 +27,9 @@ types: Slash: 3.5 - type: Damageable - damageContainer: Inorganic damageModifierSet: Glass + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml index 8d9b8259da..77e39bfb9d 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml @@ -16,8 +16,9 @@ - Ingot - ConstructionMaterial - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Materials/materials.yml b/Resources/Prototypes/Entities/Objects/Materials/materials.yml index 6d5bd964be..db66583163 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/materials.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/materials.yml @@ -13,6 +13,7 @@ tags: - RawMaterial - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Materials/parts.yml b/Resources/Prototypes/Entities/Objects/Materials/parts.yml index 5a3c0992f0..3322531dd3 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/parts.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/parts.yml @@ -9,8 +9,9 @@ - type: Item sprite: Objects/Materials/parts.rsi - type: Damageable - damageContainer: Inorganic damageModifierSet: FlimsyMetallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Materials/scrap.yml b/Resources/Prototypes/Entities/Objects/Materials/scrap.yml index 82d2d115d8..3fe1e6d2fe 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/scrap.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/scrap.yml @@ -12,8 +12,9 @@ sprite: Objects/Materials/Scrap/generic.rsi size: Normal - type: Damageable - damageContainer: Inorganic damageModifierSet: FlimsyMetallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: @@ -37,8 +38,9 @@ components: - type: InteractionOutline - type: Damageable - damageContainer: Inorganic damageModifierSet: FlimsyMetallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Materials/shards.yml b/Resources/Prototypes/Entities/Objects/Materials/shards.yml index 33da82de7c..d699cb1d2e 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/shards.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/shards.yml @@ -53,8 +53,9 @@ - Trash - type: SpaceGarbage - type: Damageable - damageContainer: Inorganic damageModifierSet: Glass + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Misc/candy_bowl.yml b/Resources/Prototypes/Entities/Objects/Misc/candy_bowl.yml index fe275e3be3..a6e4bf3489 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/candy_bowl.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/candy_bowl.yml @@ -21,6 +21,7 @@ containers: bin-container: !type:Container - type: Damageable + - type: Injurable damageContainer: Inorganic - type: DamageOnLand damage: diff --git a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml index 56c3b475c4..b9cc2db65b 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml @@ -226,8 +226,9 @@ startingItem: PowerCellMedium - type: Anchorable - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -264,8 +265,9 @@ state: floodlight-broken - type: Anchorable - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Misc/land_mine.yml b/Resources/Prototypes/Entities/Objects/Misc/land_mine.yml index a3a2b60401..8c80663c28 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/land_mine.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/land_mine.yml @@ -39,6 +39,7 @@ True: {visible: true} False: {visible: false} - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Misc/parcel_wrap.yml b/Resources/Prototypes/Entities/Objects/Misc/parcel_wrap.yml index 0bf7ab9813..296711d2ec 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/parcel_wrap.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/parcel_wrap.yml @@ -64,6 +64,7 @@ volume: -4 unwrapTrash: ParcelWrapTrash - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Misc/pet_carrier.yml b/Resources/Prototypes/Entities/Objects/Misc/pet_carrier.yml index e690e1d587..3b28f62ae1 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/pet_carrier.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/pet_carrier.yml @@ -42,8 +42,9 @@ - type: PlaceableSurface isPlaceable: false - type: Damageable - damageContainer: Inorganic damageModifierSet: Wood + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml b/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml index 6e96dbbadc..d047049433 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml @@ -28,8 +28,9 @@ children: - id: FoodSpaceshroom - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Misc/tiles.yml b/Resources/Prototypes/Entities/Objects/Misc/tiles.yml index 3e9a89c0d2..6cec6bb32f 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/tiles.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/tiles.yml @@ -16,6 +16,7 @@ - type: Stack count: 1 - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Power/lights.yml b/Resources/Prototypes/Entities/Objects/Power/lights.yml index 29f6b7142c..14db07dbf3 100644 --- a/Resources/Prototypes/Entities/Objects/Power/lights.yml +++ b/Resources/Prototypes/Entities/Objects/Power/lights.yml @@ -14,6 +14,7 @@ state: normal - type: LightBulb - type: Damageable + - type: Injurable damageContainer: Inorganic - type: DamageOnLand damage: diff --git a/Resources/Prototypes/Entities/Objects/Shields/shields.yml b/Resources/Prototypes/Entities/Objects/Shields/shields.yml index 51aca993f7..c18316e7e6 100644 --- a/Resources/Prototypes/Entities/Objects/Shields/shields.yml +++ b/Resources/Prototypes/Entities/Objects/Shields/shields.yml @@ -31,6 +31,7 @@ Piercing: 1 Heat: 1 - type: Damageable + - type: Injurable damageContainer: Shield - type: ExaminableDamage messages: ShieldMessages @@ -511,6 +512,7 @@ Piercing: 1 - type: Appearance - type: Damageable + - type: Injurable damageContainer: Shield - type: ExaminableDamage messages: EnergyShieldMessages diff --git a/Resources/Prototypes/Entities/Objects/Specific/Cargo/cargo_pallet.yml b/Resources/Prototypes/Entities/Objects/Specific/Cargo/cargo_pallet.yml index 017296f5b3..0f8371a548 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Cargo/cargo_pallet.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Cargo/cargo_pallet.yml @@ -37,8 +37,9 @@ parent: BaseCargoPallet components: - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-bottles.yml b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-bottles.yml index 9b2a13f823..2f492adc28 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-bottles.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-bottles.yml @@ -77,6 +77,7 @@ types: Blunt: 4 - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry.yml b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry.yml index 63c15c0aa4..ae6f7a4476 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry.yml @@ -58,8 +58,9 @@ maxFillLevels: 6 fillBaseName: beaker - type: Damageable - damageContainer: Inorganic damageModifierSet: Glass + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: @@ -158,8 +159,9 @@ maxFillLevels: 6 fillBaseName: beaker - type: Damageable - damageContainer: Inorganic damageModifierSet: Glass + - type: Injurable + damageContainer: Inorganic - type: StaticPrice price: 30 - type: DnaSubstanceTrace @@ -652,6 +654,7 @@ - type: ExplosionResistance damageCoefficient: 0.025 # survives conventional explosives but not minibombs and nukes - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Kitchen/equipment.yml b/Resources/Prototypes/Entities/Objects/Specific/Kitchen/equipment.yml index fa1a96a81c..a6274bf5d5 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Kitchen/equipment.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Kitchen/equipment.yml @@ -31,6 +31,7 @@ fillBaseName: fill- - type: DnaSubstanceTrace - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Spillable solution: grinderOutput diff --git a/Resources/Prototypes/Entities/Objects/Specific/Kitchen/foodcarts.yml b/Resources/Prototypes/Entities/Objects/Specific/Kitchen/foodcarts.yml index 5fc9883306..bc724b006d 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Kitchen/foodcarts.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Kitchen/foodcarts.yml @@ -21,8 +21,9 @@ mask: - MobMask - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml b/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml index c9362ae159..7a84a3423f 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml @@ -85,8 +85,9 @@ mech-equipment-container: !type:Container mech-battery-slot: !type:ContainerSlot - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: FootstepModifier footstepSoundCollection: path: /Audio/Mecha/mechmove03.ogg diff --git a/Resources/Prototypes/Entities/Objects/Specific/Security/barrier.yml b/Resources/Prototypes/Entities/Objects/Specific/Security/barrier.yml index c299c4b511..6551c639ba 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Security/barrier.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Security/barrier.yml @@ -44,8 +44,9 @@ lockTime: 5 unlockTime: 5 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Security/target.yml b/Resources/Prototypes/Entities/Objects/Specific/Security/target.yml index a17c892169..c9f90aeea2 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Security/target.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Security/target.yml @@ -25,6 +25,7 @@ - type: InteractionOutline - type: Physics - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml b/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml index 5c78f305c2..b50adb1e40 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml @@ -23,8 +23,9 @@ - type: Item size: Normal - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifact_equipment.yml b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifact_equipment.yml index fd9d11f90e..55de741a0b 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifact_equipment.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifact_equipment.yml @@ -54,8 +54,9 @@ - type: PlaceableSurface isPlaceable: false - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -136,8 +137,9 @@ path: /Audio/Items/toolbox_drop.ogg - type: LockVisuals - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml index 0fa0d6aa57..23266e2d51 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml @@ -34,8 +34,9 @@ - VoltageNetworks - Power - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Tools/decoys.yml b/Resources/Prototypes/Entities/Objects/Tools/decoys.yml index 1ea52c3f70..c8cae4871e 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/decoys.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/decoys.yml @@ -35,6 +35,7 @@ - NamesSyndicateNormal nameFormat: name-format-nukie-generic - type: Damageable + - type: Injurable damageContainer: Inorganic - type: ToggleableVisuals spriteLayer: light diff --git a/Resources/Prototypes/Entities/Objects/Tools/fulton.yml b/Resources/Prototypes/Entities/Objects/Tools/fulton.yml index fd748df0e7..a50896cc95 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/fulton.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/fulton.yml @@ -76,6 +76,7 @@ sprite: Objects/Tools/fulton.rsi state: extraction_pack - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml b/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml index cf8927caf1..e1d479af08 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml @@ -81,6 +81,7 @@ description: A toolbox typically stocked with electrical gear. components: - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml index 4b91c444b7..e28996656e 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml @@ -39,6 +39,7 @@ - ReagentId: Charcoal Quantity: 2 - type: Damageable + - type: Injurable damageContainer: StructuralInorganic - type: Destructible # should have the same general explosive behavior as in cables.yml & detonator.yml thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/detonator.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/detonator.yml index d92cf1f77b..b59459bd10 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/detonator.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/detonator.yml @@ -16,6 +16,7 @@ graph: DetonatorGraph node: emptyDetonator - type: Damageable + - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml index fec2cca3ab..a8c3ecfd30 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml @@ -42,6 +42,7 @@ - type: TimerTriggerVisuals unprimedSprite: base - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/funny.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/funny.yml index ce0fbab45d..f59a74467a 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/funny.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/funny.yml @@ -96,6 +96,7 @@ - type: DeleteOnTrigger - type: AnimationPlayer - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml index 5c6e07ed9c..9da25ee736 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml @@ -17,6 +17,7 @@ - Item - Spectral # special case for the rev since it can go incorporeal and ghost bomb you. Also, Idk, its like a ghost or something no touchy. - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml index e6b42e749e..b5abc8abb9 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml @@ -17,8 +17,9 @@ restitution: 0.3 # fite me friction: 0.2 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StrongMetallic # We only want explosions breaking them (for the most part) + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml index dcdc8e19b7..45aadfbc57 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml @@ -34,6 +34,7 @@ - Impassable - BulletImpassable - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Explosive explosionType: Default diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml index 5259f71f58..67413d0b24 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml @@ -112,6 +112,7 @@ SoundTargetInLOS: !type:SoundPathSpecifier path: /Audio/Animals/snake_hiss.ogg - type: Damageable + - type: Injurable damageContainer: Biological - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_base.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_base.yml index ca56ae0c6c..da479f4172 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_base.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_base.yml @@ -33,6 +33,7 @@ - type: CombatMode toggleMouseRotator: false - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_broken.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_broken.yml index 9c5f22a1e7..927c52d30f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_broken.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_broken.yml @@ -12,6 +12,7 @@ layers: - state: syndie_broken - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml index 01e31bc467..b86b849874 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml @@ -79,6 +79,7 @@ types: Piercing: 4 - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml index b681bdbd0b..cde8ee3145 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml @@ -15,6 +15,7 @@ slots: - Belt - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Appearance - type: AnimationPlayer diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml index 69f3700426..6f335405bd 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/bola.yml @@ -17,6 +17,7 @@ graph: Bola node: bola - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml index e1080684c0..711cc27d21 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml @@ -337,6 +337,7 @@ graph: ModularGrenadeGraph node: emptyCase - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml index 5a3cedb901..ab37f18b1b 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml @@ -5,6 +5,7 @@ components: - type: Appearance - type: Damageable + - type: Injurable damageContainer: Inorganic - type: DeleteOnTrigger keysIn: diff --git a/Resources/Prototypes/Entities/Objects/base_shadow.yml b/Resources/Prototypes/Entities/Objects/base_shadow.yml index 1cefef9e56..8c30219dbd 100644 --- a/Resources/Prototypes/Entities/Objects/base_shadow.yml +++ b/Resources/Prototypes/Entities/Objects/base_shadow.yml @@ -20,4 +20,5 @@ types: Heat: 10 - type: Damageable + - type: Injurable damageContainer: ShadowHaze diff --git a/Resources/Prototypes/Entities/Structures/Decoration/banners.yml b/Resources/Prototypes/Entities/Structures/Decoration/banners.yml index 12f112dfc5..f5c6055a9a 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/banners.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/banners.yml @@ -27,6 +27,7 @@ - BulletImpassable - type: InteractionOutline - type: Damageable + - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Structures/Decoration/bonfire.yml b/Resources/Prototypes/Entities/Structures/Decoration/bonfire.yml index fcce070476..8de1c238da 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/bonfire.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/bonfire.yml @@ -22,8 +22,9 @@ energy: 3 color: "#FFC90C" - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Decoration/cobwebs.yml b/Resources/Prototypes/Entities/Structures/Decoration/cobwebs.yml index 95aa115310..0a1dad1685 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/cobwebs.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/cobwebs.yml @@ -18,8 +18,9 @@ - type: Transform anchored: true - type: Damageable - damageContainer: Inorganic damageModifierSet: Wood + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml b/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml index d68d163b5e..7ba8798d4c 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml @@ -38,8 +38,9 @@ energy: 3 color: "#52ff39" - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Decoration/curtains.yml b/Resources/Prototypes/Entities/Structures/Decoration/curtains.yml index 883bd32c4a..f40ef5aae8 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/curtains.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/curtains.yml @@ -35,8 +35,9 @@ path: /Audio/Effects/curtain_openclose.ogg - type: Appearance - type: Damageable - damageContainer: Inorganic damageModifierSet: Wood + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities diff --git a/Resources/Prototypes/Entities/Structures/Decoration/decorated_fir_tree.yml b/Resources/Prototypes/Entities/Structures/Decoration/decorated_fir_tree.yml index 06afa3785e..86e335f7ea 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/decorated_fir_tree.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/decorated_fir_tree.yml @@ -19,8 +19,9 @@ autoRot: true offset: "0, 0.6" - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Decoration/fireplace.yml b/Resources/Prototypes/Entities/Structures/Decoration/fireplace.yml index dbff3d458e..594e5b6b04 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/fireplace.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/fireplace.yml @@ -35,8 +35,9 @@ energy: 3 color: "#FF6F00" - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Decoration/mannequin.yml b/Resources/Prototypes/Entities/Structures/Decoration/mannequin.yml index 001245d71d..8afdbd767a 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/mannequin.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/mannequin.yml @@ -38,8 +38,9 @@ graph: Mannequin node: mannequin - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Decoration/showcase.yml b/Resources/Prototypes/Entities/Structures/Decoration/showcase.yml index 0805ad1e9d..061160ee3d 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/showcase.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/showcase.yml @@ -7,8 +7,9 @@ components: - type: Anchorable - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Decoration/statues.yml b/Resources/Prototypes/Entities/Structures/Decoration/statues.yml index 3e6f874ce1..1b67e93351 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/statues.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/statues.yml @@ -54,8 +54,9 @@ noRot: true drawdepth: Mobs - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Rock + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml index b3a885713f..0be3cb900c 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml @@ -37,8 +37,9 @@ - type: Anchorable - type: Pullable - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_assembly.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_assembly.yml index 375c5ce37c..d6ee43638c 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_assembly.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_assembly.yml @@ -28,8 +28,9 @@ anchored: true noRot: true - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: RCDDeconstructable cost: 6 delay: 8 diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml index 60ca503adc..a721f4f271 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml @@ -141,8 +141,9 @@ resistance: 3 - type: Occluder - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StrongMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: RCDDeconstructable cost: 6 delay: 8 diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml index 579e2a761e..7235e0655c 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml @@ -114,8 +114,9 @@ - type: Airtight - type: Occluder - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StrongMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml b/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml index bde406f5cb..7529d6ceae 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml @@ -21,8 +21,9 @@ - type: DeviceNetworkRequiresPower - type: InteractionOutline - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: RCDDeconstructable cost: 4 delay: 6 diff --git a/Resources/Prototypes/Entities/Structures/Doors/Firelocks/frame.yml b/Resources/Prototypes/Entities/Structures/Doors/Firelocks/frame.yml index f33cb817e5..178a179334 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Firelocks/frame.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Firelocks/frame.yml @@ -23,8 +23,9 @@ node: frame1 - type: InteractionOutline - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: RCDDeconstructable cost: 4 delay: 6 diff --git a/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml b/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml index 35261b1506..b184c6f62f 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml @@ -45,8 +45,9 @@ - type: Appearance - type: Airtight - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: RCDDeconstructable cost: 6 delay: 6 diff --git a/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml b/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml index c8fdbec326..7c91dc3343 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml @@ -44,8 +44,9 @@ weldedExamineMessage: null - type: Airtight - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: RCDDeconstructable cost: 6 delay: 8 @@ -104,8 +105,9 @@ anchored: true noRot: false - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: RCDDeconstructable cost: 6 delay: 8 diff --git a/Resources/Prototypes/Entities/Structures/Doors/Shutter/blast_door.yml b/Resources/Prototypes/Entities/Structures/Doors/Shutter/blast_door.yml index 2fab7953d7..d924f67da4 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Shutter/blast_door.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Shutter/blast_door.yml @@ -33,8 +33,9 @@ - type: RadiationBlocker resistance: 8 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StrongMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: ContainerFill containers: board: [ DoorElectronics ] @@ -78,8 +79,9 @@ state: assembly - type: InteractionOutline - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -163,8 +165,9 @@ state: assembly - type: InteractionOutline - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Doors/Shutter/shutters.yml b/Resources/Prototypes/Entities/Structures/Doors/Shutter/shutters.yml index 055df8acd2..f39eb49280 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Shutter/shutters.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Shutter/shutters.yml @@ -71,8 +71,9 @@ - type: RadiationBlocker resistance: 2 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -221,8 +222,9 @@ - board - type: InteractionOutline - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml index cbc3d13fb4..2e820f8056 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml @@ -24,8 +24,9 @@ - type: Pullable - type: Rotatable - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: RCDDeconstructable cost: 6 delay: 8 diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml index 2eede48cfd..276a4915d2 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml @@ -83,8 +83,9 @@ lastSignals: DoorStatus: false - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: ExaminableDamage messages: WindowMessages - type: RCDDeconstructable diff --git a/Resources/Prototypes/Entities/Structures/Doors/turnstile.yml b/Resources/Prototypes/Entities/Structures/Doors/turnstile.yml index c8a52e925c..2ec3a0ec59 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/turnstile.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/turnstile.yml @@ -45,8 +45,9 @@ - Pullable # no dragging things in - type: Appearance - type: Damageable - damageContainer: Inorganic damageModifierSet: StrongMetallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml b/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml index 27cb4d8b68..aa914b544a 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml @@ -7,8 +7,9 @@ components: - type: Animateable - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: PlaceableSurface - type: Fixtures fixtures: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml b/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml index d41346d220..55d611808c 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml @@ -22,8 +22,9 @@ layer: - TableLayer - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: IconSmooth key: state base: state_ @@ -79,8 +80,9 @@ layer: - TableLayer - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: IconSmooth key: state base: state_ @@ -122,8 +124,9 @@ sprite: Structures/Furniture/Tables/frame.rsi state: full - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: IconSmooth key: state base: state_ @@ -166,8 +169,9 @@ - type: Icon sprite: Structures/Furniture/Tables/generic.rsi - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -319,8 +323,9 @@ Blunt: 15 tableMassLimit: 40 - type: Damageable - damageContainer: Inorganic damageModifierSet: Card + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: @@ -480,8 +485,9 @@ - type: Icon sprite: Structures/Furniture/Tables/brass.rsi - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -933,8 +939,9 @@ sprite: Structures/Furniture/Tables/counterwood.rsi state: full - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -979,8 +986,9 @@ sprite: Structures/Furniture/Tables/countermetal.rsi state: full - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/altar.yml b/Resources/Prototypes/Entities/Structures/Furniture/altar.yml index 09ec0a9ea8..2ba494e850 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/altar.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/altar.yml @@ -9,8 +9,9 @@ - type: Transform - type: Prayable - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: PlaceableSurface - type: Fixtures fixtures: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/beds.yml b/Resources/Prototypes/Entities/Structures/Furniture/beds.yml index d16c65dffe..bc862fa36d 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/beds.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/beds.yml @@ -36,8 +36,9 @@ - type: PlaceableSurface placeCentered: true - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities diff --git a/Resources/Prototypes/Entities/Structures/Furniture/bookshelf.yml b/Resources/Prototypes/Entities/Structures/Furniture/bookshelf.yml index 8e92616a9e..0c65eac8f1 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/bookshelf.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/bookshelf.yml @@ -17,6 +17,7 @@ fillBaseName: book - type: Damageable damageModifierSet: Wood + - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/carpets.yml b/Resources/Prototypes/Entities/Structures/Furniture/carpets.yml index 5186598aa2..d4f0c4ba35 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/carpets.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/carpets.yml @@ -29,6 +29,7 @@ layer: - DoorPassable - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: @@ -365,6 +366,7 @@ canCollide: false - type: Fixtures - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: @@ -404,8 +406,9 @@ - type: Clickable - type: Fixtures - type: Damageable - damageContainer: Inorganic damageModifierSet: Card + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml b/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml index 4a680de3d3..2fc058f00f 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml @@ -28,8 +28,9 @@ buckleOffset: "0,-0.05" - type: Pullable - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: @@ -413,8 +414,9 @@ graph: Seat node: stoolCard - type: Damageable - damageContainer: Inorganic damageModifierSet: Card + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml b/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml index 2bbe6b004e..8c2974d9e7 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml @@ -9,6 +9,7 @@ state: dresser - type: Damageable damageModifierSet: Wood + - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/potted_plants.yml b/Resources/Prototypes/Entities/Structures/Furniture/potted_plants.yml index 23d8c7b174..ce44af839b 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/potted_plants.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/potted_plants.yml @@ -40,6 +40,7 @@ sprite: Structures/Furniture/potted_plants.rsi size: Huge - type: Damageable + - type: Injurable damageContainer: StructuralInorganic # The pot. Not the plant. Or is it plastic? - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/sink.yml b/Resources/Prototypes/Entities/Structures/Furniture/sink.yml index 22f0e2dc2a..8bfe0dcc06 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/sink.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/sink.yml @@ -40,8 +40,9 @@ - type: DumpableSolution solution: drainBuffer - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Holographic/projections.yml b/Resources/Prototypes/Entities/Structures/Holographic/projections.yml index ba51f12e3e..3c4238eff9 100644 --- a/Resources/Prototypes/Entities/Structures/Holographic/projections.yml +++ b/Resources/Prototypes/Entities/Structures/Holographic/projections.yml @@ -17,6 +17,7 @@ lifetime: 90 - type: Clickable - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml index e930e105e1..926ca78eb8 100644 --- a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml +++ b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml @@ -38,8 +38,9 @@ softness: 1 offset: "0, -0.5" - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: RCDDeconstructable cost: 4 delay: 2 @@ -282,6 +283,7 @@ layer: - TabletopMachineLayer - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Structures/Lighting/ground_lighting.yml b/Resources/Prototypes/Entities/Structures/Lighting/ground_lighting.yml index 2642d4217e..ebde012f45 100644 --- a/Resources/Prototypes/Entities/Structures/Lighting/ground_lighting.yml +++ b/Resources/Prototypes/Entities/Structures/Lighting/ground_lighting.yml @@ -38,8 +38,9 @@ - type: Anchorable - type: InteractionOutline - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Lighting/strobe_lighting.yml b/Resources/Prototypes/Entities/Structures/Lighting/strobe_lighting.yml index eb8c658fe5..9ae7550ad7 100644 --- a/Resources/Prototypes/Entities/Structures/Lighting/strobe_lighting.yml +++ b/Resources/Prototypes/Entities/Structures/Lighting/strobe_lighting.yml @@ -52,8 +52,9 @@ layer: - TabletopMachineLayer - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml index 5a96e342fb..fd4a6711c3 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml @@ -680,8 +680,9 @@ energy: 4.0 color: "#3c5eb5" - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: entity parent: ComputerComms @@ -1195,8 +1196,9 @@ speechVerb: Robotic speechSounds: Pai - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: GuideHelp guides: - Cloning diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml index 4ddabbd1e2..a4fb6951f8 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml @@ -25,8 +25,9 @@ - type: Sprite drawdepth: Objects - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Electronic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml index af948741a1..02310ba196 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml @@ -54,8 +54,9 @@ boardName: wires-board-name-cryopod layoutId: CryoPod - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml b/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml index 5a5d026f0e..a250df351c 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml @@ -23,8 +23,9 @@ layer: - MachineLayer - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml b/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml index 09902be970..bfbd05033f 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml @@ -31,8 +31,9 @@ containers: - clonepod-bodyContainer - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StrongMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml b/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml index c4b26e043b..252cbdb91d 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml @@ -80,8 +80,9 @@ containers: - entity_storage - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Machines/frame.yml b/Resources/Prototypes/Entities/Structures/Machines/frame.yml index 6236f3263d..f8d44f2b40 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/frame.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/frame.yml @@ -37,8 +37,9 @@ machine_board: !type:Container machine_parts: !type:Container - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities @@ -101,8 +102,9 @@ - machine_board - machine_parts - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities @@ -160,8 +162,9 @@ graph: Machine node: destroyedMachineFrame - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities diff --git a/Resources/Prototypes/Entities/Structures/Machines/jukebox.yml b/Resources/Prototypes/Entities/Structures/Machines/jukebox.yml index 8cf8b7bd7e..e69e8ad4dc 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/jukebox.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/jukebox.yml @@ -36,8 +36,9 @@ boardName: wires-board-name-jukebox layoutId: Jukebox - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Machines/mail_teleporter.yml b/Resources/Prototypes/Entities/Structures/Machines/mail_teleporter.yml index 6842e3c958..e1223ed614 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/mail_teleporter.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/mail_teleporter.yml @@ -28,8 +28,9 @@ visible: false map: [ "enum.PowerDeviceVisualLayers.Powered" ] - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: ApcPowerReceiver powerLoad: 1000 - type: Appearance diff --git a/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml b/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml index 54f7218b10..79aa7c2747 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml @@ -51,8 +51,9 @@ machine_board: !type:Container machine_parts: !type:Container - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StrongMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml b/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml index 2c58e36923..c670172ee4 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml @@ -105,8 +105,9 @@ - !type:DoActsBehavior acts: ["Destruction"] - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: DamageOnHighSpeedImpact damage: types: diff --git a/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml b/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml index 89d24b35d3..88dc9de3a0 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml @@ -30,8 +30,9 @@ powerLoad: 1000 - type: ExtensionCableReceiver - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Machines/wireless_surveillance_camera.yml b/Resources/Prototypes/Entities/Structures/Machines/wireless_surveillance_camera.yml index c5891d1143..a2c97e9439 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/wireless_surveillance_camera.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/wireless_surveillance_camera.yml @@ -10,8 +10,9 @@ - type: WirelessNetworkConnection range: 200 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Rotatable rotateWhileAnchored: true - type: Fixtures diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml index 0e7db8d02b..560ed07dc9 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml @@ -14,8 +14,9 @@ - type: Transform anchored: true - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: SubFloorHide - type: CollideOnAnchor - type: Anchorable diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml index 832a23e8ac..a7f534dfe0 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml @@ -68,8 +68,9 @@ - type: Machine board: PortableScrubberMachineCircuitBoard - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -159,8 +160,9 @@ temperatureTolerance: 0.2 atmospheric: true - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Piping/Disposal/high_pressure_machine_frame.yml b/Resources/Prototypes/Entities/Structures/Piping/Disposal/high_pressure_machine_frame.yml index 6eb90bcb7c..6f290791d6 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Disposal/high_pressure_machine_frame.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Disposal/high_pressure_machine_frame.yml @@ -29,8 +29,9 @@ graph: DisposalMachine node: frame - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Piping/Disposal/pipes.yml b/Resources/Prototypes/Entities/Structures/Piping/Disposal/pipes.yml index 839247fc3f..d6d2322d63 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Disposal/pipes.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Disposal/pipes.yml @@ -33,8 +33,9 @@ anchored: true - type: Anchorable - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml index 7647fe8d6a..eca8da0b61 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml @@ -54,8 +54,9 @@ !type:CableDeviceNode nodeGroupID: MVPower - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: ActiveRadio channels: - Engineering diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml index e7f6082734..0f58aa9d60 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml @@ -80,6 +80,7 @@ - type: Clickable - type: InteractionOutline - type: Damageable + - type: Injurable damageContainer: StructuralInorganic - type: ExaminableDamage messages: WindowMessages @@ -178,6 +179,7 @@ messages: WindowMessages - type: Repairable - type: Damageable + - type: Injurable damageContainer: StructuralInorganic - type: DamageVisuals thresholds: [8, 16, 25] diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/ame.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/ame.yml index 67142d861d..e213aab339 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/ame.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/ame.yml @@ -29,8 +29,9 @@ layer: - WallLayer - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities @@ -161,8 +162,9 @@ layer: - WallLayer - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml index 8c1682b39e..797ffd7959 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml @@ -45,8 +45,9 @@ supplyRampTolerance: 500 - type: Anchorable # Reduces anchor time to 1 second - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: PacifismDangerousAttack - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/solar.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/solar.yml index bf04eaaab4..9de622d4d3 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/solar.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/solar.yml @@ -14,8 +14,9 @@ - type: Transform anchored: true - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Physics bodyType: Static - type: Fixtures @@ -317,8 +318,9 @@ anchored: true noRot: true - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities @@ -372,8 +374,9 @@ anchored: true noRot: true - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Power/apc.yml b/Resources/Prototypes/Entities/Structures/Power/apc.yml index 4efc5d0fe6..8ccd311ea3 100644 --- a/Resources/Prototypes/Entities/Structures/Power/apc.yml +++ b/Resources/Prototypes/Entities/Structures/Power/apc.yml @@ -112,8 +112,9 @@ layoutId: APC - type: WiresVisuals - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Power/cable_terminal.yml b/Resources/Prototypes/Entities/Structures/Power/cable_terminal.yml index 4112dffd5e..d57748a5df 100644 --- a/Resources/Prototypes/Entities/Structures/Power/cable_terminal.yml +++ b/Resources/Prototypes/Entities/Structures/Power/cable_terminal.yml @@ -15,8 +15,9 @@ - type: Transform anchored: true - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: RCDDeconstructable cost: 2 delay: 0 diff --git a/Resources/Prototypes/Entities/Structures/Power/cables.yml b/Resources/Prototypes/Entities/Structures/Power/cables.yml index 4722b6e0b7..e898e28f51 100644 --- a/Resources/Prototypes/Entities/Structures/Power/cables.yml +++ b/Resources/Prototypes/Entities/Structures/Power/cables.yml @@ -32,8 +32,9 @@ drawdepth: ThinWire visible: false - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: @@ -242,6 +243,7 @@ sprite: Structures/Power/Cables/ex_cable.rsi state: excable_4 - type: Damageable + - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Structures/Power/debug_power.yml b/Resources/Prototypes/Entities/Structures/Power/debug_power.yml index e4268a25c5..ee137acd47 100644 --- a/Resources/Prototypes/Entities/Structures/Power/debug_power.yml +++ b/Resources/Prototypes/Entities/Structures/Power/debug_power.yml @@ -38,8 +38,9 @@ - type: PowerConsumer drawRate: 50 - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Power/smes.yml b/Resources/Prototypes/Entities/Structures/Power/smes.yml index c29f7a972c..612947af07 100644 --- a/Resources/Prototypes/Entities/Structures/Power/smes.yml +++ b/Resources/Prototypes/Entities/Structures/Power/smes.yml @@ -86,8 +86,9 @@ highVoltageNode: input mediumVoltageNode: output - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: BatterySensor - type: DeviceNetwork deviceNetId: AtmosDevices diff --git a/Resources/Prototypes/Entities/Structures/Power/substation.yml b/Resources/Prototypes/Entities/Structures/Power/substation.yml index a2b5a0a006..bb478a532b 100644 --- a/Resources/Prototypes/Entities/Structures/Power/substation.yml +++ b/Resources/Prototypes/Entities/Structures/Power/substation.yml @@ -52,8 +52,9 @@ # Damage - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: PacifismDangerousAttack # Guidebook diff --git a/Resources/Prototypes/Entities/Structures/Shuttles/cannons.yml b/Resources/Prototypes/Entities/Structures/Shuttles/cannons.yml index 516b90ed27..786ec54b23 100644 --- a/Resources/Prototypes/Entities/Structures/Shuttles/cannons.yml +++ b/Resources/Prototypes/Entities/Structures/Shuttles/cannons.yml @@ -16,8 +16,9 @@ availableModes: - SemiAuto - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Electronic + - type: Injurable + damageContainer: StructuralInorganic - type: DeviceNetwork deviceNetId: Wireless receiveFrequencyId: BasicDevice @@ -281,8 +282,9 @@ containers: ballistic-ammo: !type:Container - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Shuttles/station_anchor.yml b/Resources/Prototypes/Entities/Structures/Shuttles/station_anchor.yml index d9a30df5d8..5de18edfc4 100644 --- a/Resources/Prototypes/Entities/Structures/Shuttles/station_anchor.yml +++ b/Resources/Prototypes/Entities/Structures/Shuttles/station_anchor.yml @@ -71,8 +71,9 @@ powerLoad: 2500 - type: ExtensionCableReceiver - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Repairable fuelCost: 10 doAfterDelay: 5 diff --git a/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml b/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml index eafaae4450..3264d9bd6f 100644 --- a/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml +++ b/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml @@ -39,8 +39,9 @@ powerLoad: 1500 - type: ExtensionCableReceiver - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Electronic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -273,8 +274,9 @@ - !type:ChangeConstructionNodeBehavior node: machineFrame - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Electronic + - type: Injurable + damageContainer: StructuralInorganic - type: StaticPrice price: 2000 @@ -342,8 +344,9 @@ sprite: Structures/Shuttles/old_thruster.rsi state: base - type: Damageable - damageContainer: Inorganic damageModifierSet: Electronic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml index c1976ba7a8..36d61bcc5f 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml @@ -845,8 +845,9 @@ radius: 0.2 - type: InteractionOutline - type: Damageable - damageContainer: Biological damageModifierSet: Diona + - type: Injurable + damageContainer: Biological - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml b/Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml index 9a5cbbce15..6f40ae1df5 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml @@ -41,8 +41,9 @@ - type: Transform anchored: true - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Specific/Cargo/mailcart.yml b/Resources/Prototypes/Entities/Structures/Specific/Cargo/mailcart.yml index dcbfc756f1..f0ff7f578c 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Cargo/mailcart.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Cargo/mailcart.yml @@ -37,8 +37,9 @@ layer: - LargeMobLayer - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger diff --git a/Resources/Prototypes/Entities/Structures/Specific/Janitor/drain.yml b/Resources/Prototypes/Entities/Structures/Specific/Janitor/drain.yml index 770d87fd1d..7e7264c9a7 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Janitor/drain.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Janitor/drain.yml @@ -39,8 +39,9 @@ drainBuffer: maxVol: 1000 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml b/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml index 4311cd389e..d38321ba8d 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml @@ -96,6 +96,7 @@ guides: - Janitorial - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: @@ -260,8 +261,9 @@ - type: ExaminableSolution solution: bucket - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Specific/church-bell.yml b/Resources/Prototypes/Entities/Structures/Specific/church-bell.yml index 837a7bc0b3..02fb62aa8f 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/church-bell.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/church-bell.yml @@ -27,6 +27,7 @@ - type: Fixtures - type: InteractionOutline - type: Damageable + - type: Injurable damageContainer: Inorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Structures/Specific/dragon.yml b/Resources/Prototypes/Entities/Structures/Specific/dragon.yml index 8a7f13d1a4..033a7516c4 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/dragon.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/dragon.yml @@ -32,8 +32,9 @@ # only show after making the announcement at 50% enabled: false - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Specific/xeno.yml b/Resources/Prototypes/Entities/Structures/Specific/xeno.yml index fdb57e6619..bfcfca0342 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/xeno.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/xeno.yml @@ -26,8 +26,9 @@ - state: wardingtower-unshaded shader: unshaded - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Physics bodyType: Static - type: Fixtures diff --git a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml index a47a8e2104..ef749cfafe 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml @@ -91,8 +91,9 @@ acts: [ "Destruction" ] - !type:DumpCanisterBehavior - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Physics bodyType: Dynamic - type: Fixtures @@ -817,8 +818,9 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: InteractionOutline - type: Sprite sprite: Structures/Storage/canister.rsi diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml index 27d29fb3d0..70d813d6b0 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml @@ -63,8 +63,9 @@ abstract: true components: - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml index 839e5ef1fb..8d16d778aa 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml @@ -54,8 +54,9 @@ placeCentered: true isPlaceable: false - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -273,8 +274,9 @@ placeCentered: true isPlaceable: false - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/big_boxes.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/big_boxes.yml index 9861bcae69..31e3e211d2 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/big_boxes.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/big_boxes.yml @@ -34,6 +34,7 @@ containers: entity_storage: !type:Container - type: Damageable + - type: Injurable damageContainer: Box - type: Sprite noRot: true diff --git a/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml b/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml index 6d5d48c767..b571b7b287 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml @@ -42,8 +42,9 @@ - type: PlaceableSurface isPlaceable: false # defaults to closed. - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -107,8 +108,9 @@ offset: "-0.5,0" map: ["enum.PaperLabelVisuals.Layer"] - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml b/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml index ec960013f1..ef0ca38e74 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml @@ -23,8 +23,9 @@ - MachineLayer - InteractImpassable - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml b/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml index c53dfb5d78..842a300c95 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml @@ -75,8 +75,9 @@ containers: storagebase: !type:Container - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities diff --git a/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml b/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml index f1ce706847..7fce8e81ba 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml @@ -70,8 +70,9 @@ damageOverlay: sprite: Structures/Storage/glassbox.rsi - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: MeleeSound soundGroups: Brute: diff --git a/Resources/Prototypes/Entities/Structures/Storage/ore_box.yml b/Resources/Prototypes/Entities/Structures/Storage/ore_box.yml index a23818ee46..79b94eac49 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/ore_box.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/ore_box.yml @@ -9,8 +9,9 @@ - type: Anchorable - type: InteractionOutline - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Storage/storage.yml b/Resources/Prototypes/Entities/Structures/Storage/storage.yml index bd8a9c2fd6..57c2ddedb8 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/storage.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/storage.yml @@ -31,8 +31,9 @@ layer: - TableLayer - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/Misc/noticeboard.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/Misc/noticeboard.yml index 7f38f6c5ab..5bbce36076 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/Misc/noticeboard.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/Misc/noticeboard.yml @@ -17,6 +17,7 @@ - type: Appearance - type: Damageable damageModifierSet: Wood + - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml index 4c03c3107f..e4ec45e2d6 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml @@ -6,8 +6,9 @@ - type: Sprite sprite: Structures/Wallmounts/posters.rsi - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Card + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/shelfs.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/shelfs.yml index dd3e7dd0a4..cff55ef7cb 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/shelfs.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/shelfs.yml @@ -12,6 +12,7 @@ state: base - type: Damageable damageModifierSet: Wood + - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: @@ -118,6 +119,7 @@ state: base - type: Damageable damageModifierSet: Metallic + - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: @@ -159,6 +161,7 @@ state: base - type: Damageable damageModifierSet: Glass + - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/air_alarm.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/air_alarm.yml index 8958d6e8d0..3f7c6b4c2d 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/air_alarm.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/air_alarm.yml @@ -84,8 +84,9 @@ graph: AirAlarm node: air_alarm - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/fire_alarm.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/fire_alarm.yml index 1f2a20dc30..99c1645c4e 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/fire_alarm.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/fire_alarm.yml @@ -82,8 +82,9 @@ graph: FireAlarm node: fire_alarm - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: GuideHelp guides: - Networking diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/surveillance_camera.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/surveillance_camera.yml index a12bca758d..b5d354ba39 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/surveillance_camera.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/surveillance_camera.yml @@ -53,8 +53,9 @@ alwaysRandomize: true layoutId: SurveillanceCamera - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Sprite drawdepth: WallMountedItems sprite: Structures/Wallmounts/camera.rsi @@ -238,8 +239,9 @@ - type: Transform anchored: true - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Sprite drawdepth: WallMountedItems sprite: Structures/Wallmounts/camera.rsi diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/base_wallmount.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/base_wallmount.yml index b064d4a231..3207cee0ea 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/base_wallmount.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/base_wallmount.yml @@ -33,8 +33,9 @@ Brute: collection: GlassSmash - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: entity parent: BaseWallmount @@ -42,8 +43,9 @@ abstract: true components: - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: entity parent: BaseWallmountMetallic diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/turret_controls.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/turret_controls.yml index 651a5fe10a..1998afc1c6 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/turret_controls.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/turret_controls.yml @@ -11,8 +11,9 @@ layers: - state: base - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml index af76eca087..f2c7570589 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml @@ -33,8 +33,9 @@ state: rock_asteroid_west - type: MiningScannerViewable - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Rock + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -810,8 +811,9 @@ tags: - Pickaxe - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml b/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml index b5fa7d9190..7a1e162978 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml @@ -18,8 +18,9 @@ - type: Transform anchored: true - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: FlimsyMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml b/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml index d4b9667ce7..f0a27214cf 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml @@ -21,8 +21,9 @@ - type: Transform anchored: true - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: RCDDeconstructable cost: 2 delay: 2 diff --git a/Resources/Prototypes/Entities/Structures/Walls/girders.yml b/Resources/Prototypes/Entities/Structures/Walls/girders.yml index 2bca0ea41d..15893d76c7 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/girders.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/girders.yml @@ -28,8 +28,9 @@ sprite: Structures/Walls/solid.rsi state: wall_girder - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Walls/grille.yml b/Resources/Prototypes/Entities/Structures/Walls/grille.yml index b20256ec7e..2a561f0278 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/grille.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/grille.yml @@ -32,8 +32,9 @@ node: grille deconstructionTarget: start - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: PerforatedMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Electrified requirePower: true noWindowInTile: true @@ -137,8 +138,9 @@ tags: - ForceNoFixRotations - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: FlimsyMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml b/Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml index 2bb93c682b..a771291bda 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml @@ -21,8 +21,9 @@ layer: - WallLayer - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Inflatable + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -70,8 +71,9 @@ closeSound: path: /Audio/Misc/zip.ogg - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Inflatable + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Walls/railing.yml b/Resources/Prototypes/Entities/Structures/Walls/railing.yml index 869f423887..433ffc9a9f 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/railing.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/railing.yml @@ -15,8 +15,9 @@ - type: InteractionOutline - type: Repairable - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: FlimsyMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Climbable - type: Construction graph: Railing diff --git a/Resources/Prototypes/Entities/Structures/Walls/walls.yml b/Resources/Prototypes/Entities/Structures/Walls/walls.yml index ca6012d9e5..a9872366ee 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/walls.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/walls.yml @@ -33,8 +33,9 @@ - type: PlacementReplacement key: walls - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Physics bodyType: Static - type: Fixtures @@ -509,8 +510,9 @@ - WallLayer density: 4000 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: RadiationBlocker resistance: 5 @@ -548,8 +550,9 @@ sprite: Structures/Walls/plastitanium_diagonal.rsi state: state0 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: RadiationBlocker resistance: 5 @@ -597,8 +600,9 @@ graph: Girder node: reinforcedWall - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -705,8 +709,9 @@ sprite: Structures/Walls/reinforced_diagonal.rsi state: state0 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -743,8 +748,9 @@ - type: Icon sprite: Structures/Walls/riveted.rsi - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -872,8 +878,9 @@ - WallLayer density: 2000 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -910,8 +917,9 @@ name: shuttle wall components: - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -1148,8 +1156,9 @@ sprite: Structures/Walls/xeno.rsi state: rgeneric - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -1424,8 +1433,9 @@ sprite: Structures/Walls/mining_diagonal.rsi state: state0 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -1724,8 +1734,9 @@ node: cardwall deconstructionTarget: start - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Card + - type: Injurable + damageContainer: StructuralInorganic - type: Physics bodyType: Static - type: Fixtures diff --git a/Resources/Prototypes/Entities/Structures/Windows/clockwork.yml b/Resources/Prototypes/Entities/Structures/Windows/clockwork.yml index 876fefd332..7c58e5fc97 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/clockwork.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/clockwork.yml @@ -13,8 +13,9 @@ fuelCost: 10 doAfterDelay: 2 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: RGlass + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/mining.yml b/Resources/Prototypes/Entities/Structures/Windows/mining.yml index 8e276b0bb9..5d2eef32d9 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/mining.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/mining.yml @@ -12,8 +12,9 @@ fuelCost: 15 doAfterDelay: 3 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: RGlass + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/plasma.yml b/Resources/Prototypes/Entities/Structures/Windows/plasma.yml index b48de80ce0..0112f3103d 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/plasma.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/plasma.yml @@ -9,8 +9,9 @@ - type: Icon sprite: Structures/Windows/plasma_window.rsi - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/plastitanium.yml b/Resources/Prototypes/Entities/Structures/Windows/plastitanium.yml index 295e9d59ce..6327ed316c 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/plastitanium.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/plastitanium.yml @@ -121,8 +121,9 @@ fuelCost: 15 doAfterDelay: 3 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: RGlass + - type: Injurable + damageContainer: StructuralInorganic - type: entity id: PlastitaniumWindowDiagonalBase @@ -216,5 +217,6 @@ fuelCost: 15 doAfterDelay: 3 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: RGlass + - type: Injurable + damageContainer: StructuralInorganic diff --git a/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml b/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml index c4284a1377..b85289e3e8 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml @@ -12,8 +12,9 @@ fuelCost: 10 doAfterDelay: 2 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: RGlass + - type: Injurable + damageContainer: StructuralInorganic - type: RCDDeconstructable cost: 6 delay: 6 diff --git a/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml b/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml index 5a4a6ceacc..a34c201b88 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml @@ -9,8 +9,9 @@ - type: Icon sprite: Structures/Windows/reinforced_plasma_window.rsi - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: RGlass + - type: Injurable + damageContainer: StructuralInorganic - type: RadiationBlocker resistance: 4 - type: Destructible diff --git a/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml b/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml index 57e9a03c83..36d8981321 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml @@ -9,8 +9,9 @@ - type: Icon sprite: Structures/Windows/reinforced_uranium_window.rsi - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: RGlass + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml b/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml index 581983a8f2..a09b04c727 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml @@ -12,8 +12,9 @@ fuelCost: 15 doAfterDelay: 3 - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: RGlass + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/uranium.yml b/Resources/Prototypes/Entities/Structures/Windows/uranium.yml index 06c450092b..161fb7d9fe 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/uranium.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/uranium.yml @@ -10,8 +10,9 @@ sprite: Structures/Windows/uranium_window.rsi state: full - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/window.yml b/Resources/Prototypes/Entities/Structures/Windows/window.yml index 02e0513aa1..ee5a9242fe 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/window.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/window.yml @@ -40,8 +40,9 @@ layer: - GlassLayer - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: ExaminableDamage messages: WindowMessages - type: Repairable @@ -169,8 +170,9 @@ - GlassLayer - type: Repairable - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: ExaminableDamage messages: WindowMessages - type: RCDDeconstructable diff --git a/Resources/Prototypes/Entities/Structures/barricades.yml b/Resources/Prototypes/Entities/Structures/barricades.yml index 5f6dc04b57..4737e56528 100644 --- a/Resources/Prototypes/Entities/Structures/barricades.yml +++ b/Resources/Prototypes/Entities/Structures/barricades.yml @@ -28,6 +28,7 @@ - WallLayer - type: Damageable damageModifierSet: Wood + - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Structures/cargo_telepad.yml b/Resources/Prototypes/Entities/Structures/cargo_telepad.yml index a3198b58ea..eb96ebf609 100644 --- a/Resources/Prototypes/Entities/Structures/cargo_telepad.yml +++ b/Resources/Prototypes/Entities/Structures/cargo_telepad.yml @@ -30,8 +30,9 @@ map: [ "enum.CargoTelepadLayers.Beam" ] shader: unshaded - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: DeviceNetwork deviceNetId: Wireless receiveFrequencyId: BasicDevice diff --git a/Resources/Prototypes/Entities/Structures/catwalk.yml b/Resources/Prototypes/Entities/Structures/catwalk.yml index 669f4a6800..58d2ff773c 100644 --- a/Resources/Prototypes/Entities/Structures/catwalk.yml +++ b/Resources/Prototypes/Entities/Structures/catwalk.yml @@ -34,8 +34,9 @@ graph: Catwalk node: Catwalk - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/conveyor.yml b/Resources/Prototypes/Entities/Structures/conveyor.yml index feec88eeaf..4de44f8b7c 100644 --- a/Resources/Prototypes/Entities/Structures/conveyor.yml +++ b/Resources/Prototypes/Entities/Structures/conveyor.yml @@ -54,8 +54,9 @@ graph: ConveyorGraph node: entity - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/ironsand_steps.yml b/Resources/Prototypes/Entities/Structures/ironsand_steps.yml index 67ce012c2e..95a6dac95b 100644 --- a/Resources/Prototypes/Entities/Structures/ironsand_steps.yml +++ b/Resources/Prototypes/Entities/Structures/ironsand_steps.yml @@ -8,8 +8,9 @@ sprite: Structures/ironsand_steps.rsi state: straight - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Rock + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/lever.yml b/Resources/Prototypes/Entities/Structures/lever.yml index 7efb4cea57..08eb8f01e2 100644 --- a/Resources/Prototypes/Entities/Structures/lever.yml +++ b/Resources/Prototypes/Entities/Structures/lever.yml @@ -26,8 +26,9 @@ Middle: { state: switch-off } Left: { state: switch-rev } - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/meat_spike.yml b/Resources/Prototypes/Entities/Structures/meat_spike.yml index b8714d9d5e..c8532b553f 100644 --- a/Resources/Prototypes/Entities/Structures/meat_spike.yml +++ b/Resources/Prototypes/Entities/Structures/meat_spike.yml @@ -13,8 +13,9 @@ - state: spike map: ["base"] - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/plastic_flaps.yml b/Resources/Prototypes/Entities/Structures/plastic_flaps.yml index a8fa40b69d..fa9079b632 100644 --- a/Resources/Prototypes/Entities/Structures/plastic_flaps.yml +++ b/Resources/Prototypes/Entities/Structures/plastic_flaps.yml @@ -29,8 +29,9 @@ layer: - MidImpassable - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/soil.yml b/Resources/Prototypes/Entities/Structures/soil.yml index 276b053157..9aa084dd92 100644 --- a/Resources/Prototypes/Entities/Structures/soil.yml +++ b/Resources/Prototypes/Entities/Structures/soil.yml @@ -22,8 +22,9 @@ layer: - FullTileMask - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/stairs.yml b/Resources/Prototypes/Entities/Structures/stairs.yml index 57b2947c95..2b1b4b9d83 100644 --- a/Resources/Prototypes/Entities/Structures/stairs.yml +++ b/Resources/Prototypes/Entities/Structures/stairs.yml @@ -25,8 +25,9 @@ sprite: Structures/stairs.rsi state: stairs_steel - type: Damageable - damageContainer: StructuralInorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Tiles/bananium.yml b/Resources/Prototypes/Entities/Tiles/bananium.yml index fa8cfdd001..42a436aa5a 100644 --- a/Resources/Prototypes/Entities/Tiles/bananium.yml +++ b/Resources/Prototypes/Entities/Tiles/bananium.yml @@ -22,8 +22,9 @@ graph: FloorBananium node: BananiumFloor - type: Damageable - damageContainer: Inorganic damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Magic/animate_spell.yml b/Resources/Prototypes/Magic/animate_spell.yml index 9b4481d168..68994cce9b 100644 --- a/Resources/Prototypes/Magic/animate_spell.yml +++ b/Resources/Prototypes/Magic/animate_spell.yml @@ -52,8 +52,9 @@ - type: MovementAlwaysTouching - type: CanMoveInAir - type: Damageable - damageContainer: ManifestedSpirit damageModifierSet: ManifestedSpirit + - type: Injurable + damageContainer: ManifestedSpirit - type: Destructible thresholds: - trigger: From 5ca65503f7dcab6dc5744fa65d83546c0f5a88dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=81da?= Date: Fri, 24 Apr 2026 01:12:38 -0500 Subject: [PATCH 05/65] StatusEffect On Trigger (#43665) commit Co-authored-by: iaada --- .../RemoveStatusEffectOnTriggerComponent.cs | 19 ++++++++++++++ .../SetStatusEffectOnTriggerComponent.cs | 25 +++++++++++++++++++ .../Systems/StatusEffectOnTriggerSystem.cs | 24 ++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 Content.Shared/Trigger/Components/Effects/RemoveStatusEffectOnTriggerComponent.cs create mode 100644 Content.Shared/Trigger/Components/Effects/SetStatusEffectOnTriggerComponent.cs create mode 100644 Content.Shared/Trigger/Systems/StatusEffectOnTriggerSystem.cs diff --git a/Content.Shared/Trigger/Components/Effects/RemoveStatusEffectOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/RemoveStatusEffectOnTriggerComponent.cs new file mode 100644 index 0000000000..7ea9f9a059 --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/RemoveStatusEffectOnTriggerComponent.cs @@ -0,0 +1,19 @@ +using Content.Shared.StatusEffectNew.Components; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Removes a status effect when triggered. +/// If TargetUser is true the user loses the status. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class RemoveStatusEffectOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// Status effect to be removed. + /// + [DataField, AutoNetworkedField] + public EntProtoId Status; +} diff --git a/Content.Shared/Trigger/Components/Effects/SetStatusEffectOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/SetStatusEffectOnTriggerComponent.cs new file mode 100644 index 0000000000..7e7fbda021 --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/SetStatusEffectOnTriggerComponent.cs @@ -0,0 +1,25 @@ +using Content.Shared.StatusEffectNew.Components; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Adds a status effect when triggered. +/// If TargetUser is true the user will gain the effect. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class SetStatusEffectOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// Status effect to be added. + /// + [DataField, AutoNetworkedField] + public EntProtoId Status; + + /// + /// How long the status lasts. Permanent until removed if null. + /// + [DataField, AutoNetworkedField] + public TimeSpan? Duration; +} diff --git a/Content.Shared/Trigger/Systems/StatusEffectOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/StatusEffectOnTriggerSystem.cs new file mode 100644 index 0000000000..c766d7b467 --- /dev/null +++ b/Content.Shared/Trigger/Systems/StatusEffectOnTriggerSystem.cs @@ -0,0 +1,24 @@ +using Content.Shared.StatusEffectNew; +using Content.Shared.Trigger.Components.Effects; + +namespace Content.Shared.Trigger.Systems; + +public sealed class SetStatusEffectOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly StatusEffectsSystem _status = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + args.Handled |= _status.TrySetStatusEffectDuration(target, ent.Comp.Status, ent.Comp.Duration); + } +} + +public sealed class RemoveStatusEffectOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly StatusEffectsSystem _status = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + args.Handled |= _status.TryRemoveStatusEffect(target, ent.Comp.Status); + } +} From 1a3ead7c7ab0ea478c257dca44ed56a40ab65f4f Mon Sep 17 00:00:00 2001 From: themias <89101928+themias@users.noreply.github.com> Date: Fri, 24 Apr 2026 02:23:26 -0400 Subject: [PATCH 06/65] Fix RCD doafter cancelling (#43655) Fix RCD drop doafter --- Content.Shared/RCD/Systems/RCDSystem.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Content.Shared/RCD/Systems/RCDSystem.cs b/Content.Shared/RCD/Systems/RCDSystem.cs index 86977eea3b..1ed71a57f6 100644 --- a/Content.Shared/RCD/Systems/RCDSystem.cs +++ b/Content.Shared/RCD/Systems/RCDSystem.cs @@ -224,6 +224,7 @@ public sealed class RCDSystem : EntitySystem GetNetEntity(effect)); var doAfterArgs = new DoAfterArgs(EntityManager, user, delay, ev, uid, target: args.Target, used: uid) { + NeedHand = true, BreakOnDamage = true, BreakOnHandChange = true, BreakOnMove = true, From bb5e734cabab8e3a3f13bdeb5700af78462ecb0c Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 24 Apr 2026 06:39:05 +0000 Subject: [PATCH 07/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 15e491ec4c..be8d7e3e01 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: ToastEnjoyer - changes: - - message: A security flashlight now spawns in the HoS's locker roundstart. - type: Add - id: 9146 - time: '2025-10-22T13:32:43.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/41031 - author: SolidSyn changes: - message: Wizards Slippery Slope spell no longer requires a robe and hat to be @@ -4052,3 +4045,10 @@ id: 9657 time: '2026-04-23T03:07:21.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/40714 +- author: themias + changes: + - message: Dropping or putting away an RCD now cancels the construction + type: Fix + id: 9658 + time: '2026-04-24T06:37:52.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/43655 From 1fb84ca3ff5a4ca7dbe681a3ba2570dfa5261a6c Mon Sep 17 00:00:00 2001 From: Red <96445749+TheShuEd@users.noreply.github.com> Date: Fri, 24 Apr 2026 09:26:51 +0300 Subject: [PATCH 08/65] Supports markup in entity descriptions (#43630) Change message.AddText to message.PushMarkup --- Content.Shared/Examine/ExamineSystemShared.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Shared/Examine/ExamineSystemShared.cs b/Content.Shared/Examine/ExamineSystemShared.cs index 8af9a91e5c..da10e99c62 100644 --- a/Content.Shared/Examine/ExamineSystemShared.cs +++ b/Content.Shared/Examine/ExamineSystemShared.cs @@ -268,7 +268,7 @@ namespace Content.Shared.Examine //Add an entity description if one is declared if (!string.IsNullOrEmpty(metadata.EntityDescription)) { - message.AddText(metadata.EntityDescription); + message.PushMarkup(metadata.EntityDescription); hasDescription = true; } From 79f1b6a358fb822b35c55019198fce276f12d431 Mon Sep 17 00:00:00 2001 From: Tad Hardesty Date: Fri, 24 Apr 2026 01:32:02 -0700 Subject: [PATCH 09/65] Prevent opening doors in map editor by accident (#37210) * Prevent opening/closing doors in map editor * Move checks from StartOpening to CanOpen, ditto Close --- Content.Shared/Doors/Systems/SharedDoorSystem.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Content.Shared/Doors/Systems/SharedDoorSystem.cs b/Content.Shared/Doors/Systems/SharedDoorSystem.cs index 310ea70bdc..eaaec3fdd6 100644 --- a/Content.Shared/Doors/Systems/SharedDoorSystem.cs +++ b/Content.Shared/Doors/Systems/SharedDoorSystem.cs @@ -329,6 +329,9 @@ public abstract partial class SharedDoorSystem : EntitySystem if (door.State == DoorState.Welded) return false; + if (Paused(uid)) + return false; + var ev = new BeforeDoorOpenedEvent() { User = user }; RaiseLocalEvent(uid, ev); if (ev.Cancelled) @@ -436,6 +439,9 @@ public abstract partial class SharedDoorSystem : EntitySystem if (door.State is DoorState.Welded or DoorState.Closed) return false; + if (Paused(uid)) + return false; + var ev = new BeforeDoorClosedEvent(door.PerformCollisionCheck, partial); RaiseLocalEvent(uid, ev); if (ev.Cancelled) From a91d5b46c768192308925704f5c221835033546a Mon Sep 17 00:00:00 2001 From: psykana <36602558+psykana@users.noreply.github.com> Date: Fri, 24 Apr 2026 09:32:39 +0100 Subject: [PATCH 10/65] T-ray scanner modes (#43161) * T-ray scanner modes * Remove dead dep * review * PollingItemStatusControl --- Content.Client/SubFloor/TrayScannerSystem.cs | 120 ++++++++++++++---- .../SubFloor/SharedTrayScannerSystem.cs | 114 ++++++++++------- .../SubFloor/TrayScannerComponent.cs | 37 ++++-- .../Locale/en-US/devices/tray-scanner.ftl | 7 + .../Entities/Objects/Tools/t-ray.yml | 2 + 5 files changed, 193 insertions(+), 87 deletions(-) create mode 100644 Resources/Locale/en-US/devices/tray-scanner.ftl diff --git a/Content.Client/SubFloor/TrayScannerSystem.cs b/Content.Client/SubFloor/TrayScannerSystem.cs index a23d67a98b..677be8c753 100644 --- a/Content.Client/SubFloor/TrayScannerSystem.cs +++ b/Content.Client/SubFloor/TrayScannerSystem.cs @@ -1,9 +1,19 @@ -using Content.Shared.Hands.EntitySystems; +using Content.Client.Items; +using Content.Client.Items.UI; +using Content.Client.Message; +using Content.Client.Power.Visualizers; +using Content.Client.Stylesheets; +using Content.Shared.Atmos.Components; +using Content.Shared.Disposal.Components; +using Content.Shared.Input; using Content.Shared.Inventory; using Content.Shared.SubFloor; using Robust.Client.Animations; using Robust.Client.GameObjects; +using Robust.Client.Input; using Robust.Client.Player; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; using Robust.Shared.Timing; namespace Content.Client.SubFloor; @@ -16,10 +26,10 @@ public sealed class TrayScannerSystem : SharedTrayScannerSystem [Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly InventorySystem _inventory = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly SharedHandsSystem _hands = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SpriteSystem _sprite = default!; [Dependency] private readonly TrayScanRevealSystem _trayScanReveal = default!; + [Dependency] private readonly IInputManager _inputManager = default!; [Dependency] private readonly EntityQuery _trayScannerQuery = default!; [Dependency] private readonly EntityQuery _subFloorHideQuery = default!; @@ -28,6 +38,12 @@ public sealed class TrayScannerSystem : SharedTrayScannerSystem public const LookupFlags Flags = LookupFlags.Static | LookupFlags.Sundries | LookupFlags.Approximate; + public override void Initialize() + { + base.Initialize(); + Subs.ItemStatus(OnCollectItemStatus); + } + public override void Update(float frameTime) { base.Update(frameTime); @@ -44,37 +60,20 @@ public sealed class TrayScannerSystem : SharedTrayScannerSystem var playerPos = _transform.GetWorldPosition(playerXform); var playerMap = playerXform.MapID; var range = 0f; + var mode = TrayScannerMode.All; HashSet> inRange; // TODO: Should probably sub to player attached changes / inventory changes but inventory's // API is extremely skrungly. If this ever shows up on dottrace ping me and laugh. var canSee = false; - // TODO: Common iterator for both systems. - if (_inventory.TryGetContainerSlotEnumerator(player.Value, out var enumerator)) + foreach (var item in _inventory.GetHandOrInventoryEntities(player.Value, SlotFlags.POCKET)) { - while (enumerator.MoveNext(out var slot)) - { - foreach (var ent in slot.ContainedEntities) - { - if (!_trayScannerQuery.TryGetComponent(ent, out var sneakScanner) || !sneakScanner.Enabled) - continue; - - canSee = true; - range = MathF.Max(range, sneakScanner.Range); - } - } - } - - foreach (var hand in _hands.EnumerateHands(player.Value)) - { - if (!_hands.TryGetHeldItem(player.Value, hand, out var heldEntity)) + if (!_trayScannerQuery.TryGetComponent(item, out var scanner) || !scanner.Enabled) continue; - if (!_trayScannerQuery.TryGetComponent(heldEntity, out var heldScanner) || !heldScanner.Enabled) - continue; - - range = MathF.Max(heldScanner.Range, range); + range = MathF.Max(scanner.Range, range); + mode = scanner.Mode; canSee = true; break; } @@ -83,10 +82,16 @@ public sealed class TrayScannerSystem : SharedTrayScannerSystem if (canSee) { - _lookup.GetEntitiesInRange(playerMap, playerPos, range, inRange, flags: Flags); + var entitiesInRange = new HashSet>(); + _lookup.GetEntitiesInRange(playerMap, playerPos, range, entitiesInRange, flags: Flags); - foreach (var (uid, comp) in inRange) + foreach (var (uid, comp) in entitiesInRange) { + if (!MatchesMode(uid, mode)) + continue; + + inRange.Add((uid, comp)); + if (comp.IsUnderCover || _trayScanReveal.IsUnderRevealingEntity(uid)) EnsureComp(uid); } @@ -173,4 +178,67 @@ public sealed class TrayScannerSystem : SharedTrayScannerSystem { _appearance.SetData(uid, SubFloorVisuals.ScannerRevealed, value); } + + private bool MatchesMode(EntityUid uid, TrayScannerMode mode) + { + return mode switch + { + TrayScannerMode.All => true, + TrayScannerMode.Wiring => HasComp(uid), + // TODO: proper comp query after disposals refactor + TrayScannerMode.Piping => HasComp(uid) || _appearance.TryGetData(uid, DisposalTubeVisuals.VisualState, out _), + _ => false, + }; + } + + #region UI + private Control OnCollectItemStatus(Entity entity) + { + _inputManager.TryGetKeyBinding((ContentKeyFunctions.AltUseItemInHand), out var binding); + return new StatusControl(entity, binding?.GetKeyString() ?? ""); + } + + private sealed class StatusControl : PollingItemStatusControl + { + private readonly RichTextLabel _label; + private readonly TrayScannerComponent _scanner; + private readonly string _keyBindingName; + + public StatusControl(TrayScannerComponent scanner, string keyBindingName) + { + _scanner = scanner; + _keyBindingName = keyBindingName; + _label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } }; + AddChild(_label); + } + + protected override TRayData PollData() + { + return new TRayData(_scanner.Enabled, _scanner.Mode); + } + + protected override void Update(in TRayData data) + { + if (!data.Enabled) + { + _label.SetMarkup(string.Empty); + return; + } + + var modeLocString = data.Mode switch + { + TrayScannerMode.All => "tray-scanner-examine-mode-all", + TrayScannerMode.Wiring => "tray-scanner-examine-mode-wiring", + TrayScannerMode.Piping => "tray-scanner-examine-mode-piping", + _ => "", + }; + + _label.SetMarkup(Robust.Shared.Localization.Loc.GetString("tray-scanner-item-status-label", + ("mode", Robust.Shared.Localization.Loc.GetString(modeLocString)), + ("keybinding", _keyBindingName))); + } + + public readonly record struct TRayData(bool Enabled, TrayScannerMode Mode); + } + #endregion } diff --git a/Content.Shared/SubFloor/SharedTrayScannerSystem.cs b/Content.Shared/SubFloor/SharedTrayScannerSystem.cs index 03e5e517d6..1c0b1c3d95 100644 --- a/Content.Shared/SubFloor/SharedTrayScannerSystem.cs +++ b/Content.Shared/SubFloor/SharedTrayScannerSystem.cs @@ -1,18 +1,24 @@ +using Content.Shared.Database; using Content.Shared.Eye; using Content.Shared.Hands; using Content.Shared.Interaction; using Content.Shared.Inventory.Events; -using Robust.Shared.GameStates; +using Content.Shared.Timing; +using Content.Shared.Verbs; +using Robust.Shared.Audio; +using Robust.Shared.Audio.Systems; using Robust.Shared.Network; -using Robust.Shared.Serialization; +using Robust.Shared.Utility; namespace Content.Shared.SubFloor; public abstract class SharedTrayScannerSystem : EntitySystem { - [Dependency] private readonly INetManager _netMan = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedEyeSystem _eye = default!; + [Dependency] private readonly UseDelaySystem _delay = default!; + [Dependency] private readonly INetManager _netMan = default!; public const float SubfloorRevealAlpha = 0.8f; @@ -20,19 +26,61 @@ public abstract class SharedTrayScannerSystem : EntitySystem { base.Initialize(); - SubscribeLocalEvent(OnTrayScannerGetState); - SubscribeLocalEvent(OnTrayScannerHandleState); SubscribeLocalEvent(OnTrayScannerActivate); - + SubscribeLocalEvent>(OnAddSwitchModeVerb); SubscribeLocalEvent(OnTrayHandEquipped); SubscribeLocalEvent(OnTrayHandUnequipped); SubscribeLocalEvent(OnTrayEquipped); SubscribeLocalEvent(OnTrayUnequipped); - SubscribeLocalEvent(OnUserGetVis); } - private void OnUserGetVis(Entity ent, ref GetVisMaskEvent args) + private void OnAddSwitchModeVerb(Entity scanner, ref GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract || !args.Using.HasValue || !scanner.Comp.Enabled) + return; + + var user = args.User; + + AlternativeVerb verb = new() + { + Text = Loc.GetString("tray-scanner-switch-mode"), + Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/settings.svg.192dpi.png")), + Act = () => SwitchMode(scanner, user), + Impact = LogImpact.Low + }; + args.Verbs.Add(verb); + } + + private static TrayScannerMode Next(TrayScannerMode mode) + { + return mode switch + { + TrayScannerMode.All => TrayScannerMode.Wiring, + TrayScannerMode.Wiring => TrayScannerMode.Piping, + TrayScannerMode.Piping => TrayScannerMode.All, + _ => TrayScannerMode.All, + }; + } + + private void SwitchMode(Entity scanner, EntityUid? userUid) + { + if (!userUid.HasValue) + return; + + // Prevents ping spam + if (!_delay.TryResetDelay(scanner, checkDelayed: true)) + return; + + scanner.Comp.Mode = Next(scanner.Comp.Mode); + Dirty(scanner); + + // Play a slightly different sound when we're back to All mode + var pitch = scanner.Comp.Mode == TrayScannerMode.All ? 1 : 0.8f; + _audio.PlayPredicted(scanner.Comp.SoundSwitchMode, scanner, userUid, AudioParams.Default.WithVolume(1.5f).WithPitchScale(pitch)); + } + + private void OnUserGetVis(Entity scanner, ref GetVisMaskEvent args) { args.VisibilityMask |= (int)VisibilityFlags.Subfloor; } @@ -88,51 +136,19 @@ public abstract class SharedTrayScannerSystem : EntitySystem OnEquip(args.EquipTarget); } - private void OnTrayScannerActivate(EntityUid uid, TrayScannerComponent scanner, ActivateInWorldEvent args) + private void OnTrayScannerActivate(Entity ent, ref ActivateInWorldEvent args) { if (args.Handled || !args.Complex) return; - SetScannerEnabled(uid, !scanner.Enabled, scanner); + ent.Comp.Enabled = !ent.Comp.Enabled; + Dirty(ent); + + if (TryComp(ent, out var appearance)) + { + _appearance.SetData(ent, TrayScannerVisual.Visual, ent.Comp.Enabled ? TrayScannerVisual.On : TrayScannerVisual.Off, appearance); + } + args.Handled = true; } - - private void SetScannerEnabled(EntityUid uid, bool enabled, TrayScannerComponent? scanner = null) - { - if (!Resolve(uid, ref scanner) || scanner.Enabled == enabled) - return; - - scanner.Enabled = enabled; - Dirty(uid, scanner); - - // We don't remove from _activeScanners on disabled, because the update function will handle that, as well as - // managing the revealed subfloor entities - - if (TryComp(uid, out var appearance)) - { - _appearance.SetData(uid, TrayScannerVisual.Visual, scanner.Enabled ? TrayScannerVisual.On : TrayScannerVisual.Off, appearance); - } - } - - private void OnTrayScannerGetState(EntityUid uid, TrayScannerComponent scanner, ref ComponentGetState args) - { - args.State = new TrayScannerState(scanner.Enabled, scanner.Range); - } - - private void OnTrayScannerHandleState(EntityUid uid, TrayScannerComponent scanner, ref ComponentHandleState args) - { - if (args.Current is not TrayScannerState state) - return; - - scanner.Range = state.Range; - SetScannerEnabled(uid, state.Enabled, scanner); - } -} - -[Serializable, NetSerializable] -public enum TrayScannerVisual : sbyte -{ - Visual, - On, - Off } diff --git a/Content.Shared/SubFloor/TrayScannerComponent.cs b/Content.Shared/SubFloor/TrayScannerComponent.cs index 52c950e108..cacb345718 100644 --- a/Content.Shared/SubFloor/TrayScannerComponent.cs +++ b/Content.Shared/SubFloor/TrayScannerComponent.cs @@ -1,33 +1,46 @@ +using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Serialization; namespace Content.Shared.SubFloor; -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class TrayScannerComponent : Component { /// /// Whether the scanner is currently on. /// - [DataField] + [DataField, AutoNetworkedField] public bool Enabled; + /// + /// Current mode of operation, defines which subfloor entities are shown. + /// + [DataField, AutoNetworkedField] + public TrayScannerMode Mode = TrayScannerMode.All; + /// /// Radius in which the scanner will reveal entities. Centered on the . /// - [DataField] + [DataField, AutoNetworkedField] public float Range = 4f; + + [DataField] + public SoundSpecifier SoundSwitchMode = new SoundPathSpecifier("/Audio/Machines/quickbeep.ogg"); } [Serializable, NetSerializable] -public sealed class TrayScannerState : ComponentState +public enum TrayScannerMode { - public bool Enabled; - public float Range; - - public TrayScannerState(bool enabled, float range) - { - Enabled = enabled; - Range = range; - } + All, + Piping, + Wiring +} + +[Serializable, NetSerializable] +public enum TrayScannerVisual : byte +{ + Visual, + On, + Off } diff --git a/Resources/Locale/en-US/devices/tray-scanner.ftl b/Resources/Locale/en-US/devices/tray-scanner.ftl new file mode 100644 index 0000000000..ea06fd19e5 --- /dev/null +++ b/Resources/Locale/en-US/devices/tray-scanner.ftl @@ -0,0 +1,7 @@ +tray-scanner-examine-mode-all = [color=green]All[/color] +tray-scanner-examine-mode-wiring = [color=yellow]Wiring[/color] +tray-scanner-examine-mode-piping = [color=dodgerblue]Piping[/color] + +tray-scanner-switch-mode = Switch mode +tray-scanner-item-status-label = Mode: {$mode} + Switch: {$keybinding} diff --git a/Resources/Prototypes/Entities/Objects/Tools/t-ray.yml b/Resources/Prototypes/Entities/Objects/Tools/t-ray.yml index 091a345d77..edc8e1b089 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/t-ray.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/t-ray.yml @@ -25,3 +25,5 @@ Glass: 150 - type: StaticPrice price: 85 + - type: UseDelay + delay: 1 From 8fc559dc48585db0c051551ecdb55e27d0cfa37a Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 24 Apr 2026 08:47:57 +0000 Subject: [PATCH 11/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index be8d7e3e01..3c091018b0 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: SolidSyn - changes: - - message: Wizards Slippery Slope spell no longer requires a robe and hat to be - cast. - type: Tweak - id: 9147 - time: '2025-10-23T01:28:45.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/41038 - author: Moomoobeef changes: - message: Fixed banana bread being missing from the guidebook. @@ -4052,3 +4044,10 @@ id: 9658 time: '2026-04-24T06:37:52.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/43655 +- author: psykana + changes: + - message: T-ray scanner now has dedicated wiring and piping modes. + type: Add + id: 9659 + time: '2026-04-24T08:46:48.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/43161 From 03da583ee84174407343e394b89d6c2247ca2e4c Mon Sep 17 00:00:00 2001 From: Nox Date: Fri, 24 Apr 2026 01:33:45 -0700 Subject: [PATCH 12/65] Injury slowdown resistance for combat and merc boots (#35653) * Added ClothingSlowOnDamageModifier 0.5 to combat boots, merc boots, and sec/syndie winter boots. * Removed slowdown resist from sec/syndie winter boots Signed-off-by: Nox38 * Reverted format change Signed-off-by: Nox38 --------- Signed-off-by: Nox38 --- Resources/Prototypes/Entities/Clothing/Shoes/boots.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/boots.yml b/Resources/Prototypes/Entities/Clothing/Shoes/boots.yml index 04da517413..0fd65eaccb 100644 --- a/Resources/Prototypes/Entities/Clothing/Shoes/boots.yml +++ b/Resources/Prototypes/Entities/Clothing/Shoes/boots.yml @@ -56,6 +56,8 @@ sprite: Clothing/Shoes/Boots/combatboots.rsi - type: Clothing sprite: Clothing/Shoes/Boots/combatboots.rsi + - type: ClothingSlowOnDamageModifier + modifier: 0.5 - type: entity parent: ClothingShoesMilitaryBase @@ -88,6 +90,8 @@ sprite: Clothing/Shoes/Boots/mercboots.rsi - type: Clothing sprite: Clothing/Shoes/Boots/mercboots.rsi + - type: ClothingSlowOnDamageModifier + modifier: 0.5 - type: entity parent: ClothingShoesBaseButcherable From 7367a83807cde42859ed5aa1577340fafa674e81 Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 24 Apr 2026 09:02:42 +0000 Subject: [PATCH 13/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 3c091018b0..51dcbd3af5 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Moomoobeef - changes: - - message: Fixed banana bread being missing from the guidebook. - type: Fix - id: 9148 - time: '2025-10-23T07:00:24.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/41047 - author: Absotively changes: - message: Minor hand labeler UI improvements @@ -4051,3 +4044,11 @@ id: 9659 time: '2026-04-24T08:46:48.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/43161 +- author: Nox38 + changes: + - message: All military boots (jack, combat, merc) now have the 50% injury slowdown + resistance effect. + type: Tweak + id: 9660 + time: '2026-04-24T09:01:35.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/35653 From fd4e19e2ee134afff9068c3012a8b506c739e2e7 Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Fri, 24 Apr 2026 02:17:29 -0700 Subject: [PATCH 14/65] Air Friction changes for Mobs that can move in air (#38691) * Very minor change * Query * Fix * It should already be static? Why is the test failing * WRONG BRANCH --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- Content.Shared/Friction/TileFrictionController.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Content.Shared/Friction/TileFrictionController.cs b/Content.Shared/Friction/TileFrictionController.cs index 71e269b98c..34e911995c 100644 --- a/Content.Shared/Friction/TileFrictionController.cs +++ b/Content.Shared/Friction/TileFrictionController.cs @@ -2,7 +2,6 @@ using System.Numerics; using Content.Shared.CCVar; using Content.Shared.Gravity; using Content.Shared.Interaction.Components; -using Content.Shared.Interaction.Events; using Content.Shared.Movement.Components; using Content.Shared.Movement.Events; using Content.Shared.Movement.Pulling.Components; @@ -28,6 +27,7 @@ namespace Content.Shared.Friction [Dependency] private readonly SharedMoverController _mover = default!; [Dependency] private readonly SharedMapSystem _map = default!; + [Dependency] private readonly EntityQuery _canMoveInAirQuery = default!; [Dependency] private readonly EntityQuery _frictionQuery = default!; [Dependency] private readonly EntityQuery _pullerQuery = default!; [Dependency] private readonly EntityQuery _pullableQuery = default!; @@ -73,8 +73,8 @@ namespace Content.Shared.Friction float friction; // If we're not touching the ground, don't use tileFriction. - // TODO: Make IsWeightless event-based; we already have grid traversals tracked so just raise events - if (body.BodyStatus == BodyStatus.InAir || _gravity.IsWeightless(uid) || !xform.Coordinates.IsValid(EntityManager)) + if (body.BodyStatus != BodyStatus.OnGround && !_canMoveInAirQuery.HasComp(uid) + || _gravity.IsWeightless(uid) || !xform.Coordinates.IsValid(EntityManager)) friction = xform.GridUid == null || !_gridQuery.HasComp(xform.GridUid) ? _offGridDamping : _airDamping; else friction = _frictionModifier * GetTileFriction(uid, body, xform); From cde56fbf8e0c1c49bd12d577adda45242173dc9b Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 24 Apr 2026 09:33:01 +0000 Subject: [PATCH 15/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 51dcbd3af5..fcf75fa89f 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Absotively - changes: - - message: Minor hand labeler UI improvements - type: Tweak - id: 9149 - time: '2025-10-23T15:27:38.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/40318 - author: Silverfur-underscore changes: - message: The Mime Job Lizard plushie no longer breaks its vow when being thrown @@ -4052,3 +4045,10 @@ id: 9660 time: '2026-04-24T09:01:35.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/35653 +- author: Princess-Cheeseballs + changes: + - message: Dragons and other flying mobs no longer continue sliding while dead. + type: Fix + id: 9661 + time: '2026-04-24T09:31:53.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/38691 From 994fd17e07306090728ced971e5ce64b6f189ed6 Mon Sep 17 00:00:00 2001 From: K-Dynamic <20566341+K-Dynamic@users.noreply.github.com> Date: Fri, 24 Apr 2026 21:52:28 +1200 Subject: [PATCH 16/65] Detective coat changes, let detectives start with a winter coat (#39044) * rename detective coat, give detective a winter coat * Resolve merge conflict --------- Co-authored-by: SlamBamActionman --- .../Prototypes/Entities/Clothing/OuterClothing/coats.yml | 4 ++-- .../Prototypes/Loadouts/LoadoutGroups/loadout_groups.yml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml index a05cf9baa4..bf92009013 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml @@ -12,8 +12,8 @@ - type: entity parent: [ ClothingOuterArmorBase, ClothingOuterStorageBase, AllowSuitStorageClothing, BaseSecurityContraband ] id: ClothingOuterCoatDetective - name: detective armored trenchcoat - description: An 18th-century multi-purpose trenchcoat. Someone who wears this means serious business. + name: detective's armored trenchcoat + description: An 20th-century trenchcoat with an armored underlay. Someone who wears this means serious business. components: - type: Sprite sprite: Clothing/OuterClothing/Coats/detective.rsi diff --git a/Resources/Prototypes/Loadouts/LoadoutGroups/loadout_groups.yml b/Resources/Prototypes/Loadouts/LoadoutGroups/loadout_groups.yml index 34a26f28ec..bc36356143 100644 --- a/Resources/Prototypes/Loadouts/LoadoutGroups/loadout_groups.yml +++ b/Resources/Prototypes/Loadouts/LoadoutGroups/loadout_groups.yml @@ -1268,6 +1268,7 @@ - DetectiveArmorVest - DetectiveCoat - DetectiveCoatGrey + - SecurityOfficerWintercoat - type: loadoutGroup id: DetectiveJobTrinkets From 1029432cabeac1f97e0df9a4cb71208ca363cda5 Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 24 Apr 2026 10:08:13 +0000 Subject: [PATCH 17/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index fcf75fa89f..0a2c20c7a3 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Silverfur-underscore - changes: - - message: The Mime Job Lizard plushie no longer breaks its vow when being thrown - against something or eaten. - type: Fix - id: 9150 - time: '2025-10-24T00:02:31.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/41063 - author: MDuch369 changes: - message: Added guidebook entry for gas recycler. @@ -4052,3 +4044,10 @@ id: 9661 time: '2026-04-24T09:31:53.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/38691 +- author: K-Dynamic + changes: + - message: Detectives can now choose to start the shift in a winter coat. + type: Tweak + id: 9662 + time: '2026-04-24T10:07:05.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/39044 From c9fda46f88bb9815ea30c290d1f33dd68626942d Mon Sep 17 00:00:00 2001 From: zHonys Date: Fri, 24 Apr 2026 07:32:55 -0300 Subject: [PATCH 18/65] Fixed talking when sleeping while on crit (#37572) * Fixed talking when sleeping while on crit * Changed fix location to DamageForceSaySystem from SleepingSystem --- Content.Server/Damage/ForceSay/DamageForceSaySystem.cs | 4 ++++ Content.Shared/Bed/Sleep/SleepingSystem.cs | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs b/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs index 5597c47fdb..88f8092aa7 100644 --- a/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs +++ b/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Damage.ForceSay; using Content.Shared.Damage.Systems; using Content.Shared.FixedPoint; using Content.Shared.Mobs; +using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Stunnable; using Robust.Shared.Player; @@ -88,6 +89,9 @@ public sealed class DamageForceSaySystem : EntitySystem if (!args.FellAsleep) return; + if (Comp(uid).CurrentState != MobState.Alive) + return; + TryForceSay(uid, component); AllowNextSpeech(uid); } diff --git a/Content.Shared/Bed/Sleep/SleepingSystem.cs b/Content.Shared/Bed/Sleep/SleepingSystem.cs index 661c8399a1..e9c08570c4 100644 --- a/Content.Shared/Bed/Sleep/SleepingSystem.cs +++ b/Content.Shared/Bed/Sleep/SleepingSystem.cs @@ -163,7 +163,6 @@ public sealed partial class SleepingSystem : EntitySystem private void OnSpeakAttempt(Entity ent, ref SpeakAttemptEvent args) { - // TODO reduce duplication of this behavior with MobStateSystem somehow if (HasComp(ent)) { RemCompDeferred(ent); From 3afd1cdd49050cc40a6304f42b423ca9a85da7b6 Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 24 Apr 2026 10:49:25 +0000 Subject: [PATCH 19/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 0a2c20c7a3..bcb417e14f 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,4 @@ Entries: -- author: MDuch369 - changes: - - message: Added guidebook entry for gas recycler. - type: Add - - message: Gas recycler can now be rotated. - type: Fix - id: 9151 - time: '2025-10-24T01:07:47.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/39212 - author: Princess_Chzblz, AdmiralObvious, hyphenation, Is-A-Slark, beck changes: - message: PAIs will no longer get uplinks instead of traitors when a player is @@ -4051,3 +4042,11 @@ id: 9662 time: '2026-04-24T10:07:05.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/39044 +- author: zHonys + changes: + - message: Falling asleep while crit will no longer cause you to say whatever is + typed in your chatbox. + type: Fix + id: 9663 + time: '2026-04-24T10:48:17.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/37572 From 658abcbc7b27d8a4bbb447828c0e2b8013832813 Mon Sep 17 00:00:00 2001 From: Jackson Bailey <7296578+JacksonBailey@users.noreply.github.com> Date: Fri, 24 Apr 2026 07:37:24 -0400 Subject: [PATCH 20/65] Enable safety on windoors (#40519) Cuts back on audio spam when people stand in windoors. --- .../Structures/Doors/Windoors/base_structurewindoors.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml index 276a4915d2..dd82d594ef 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml @@ -138,8 +138,8 @@ denyAnimationTime: 0.4 animatePanel: false openUnlitVisible: true - # needed so that windoors will close regardless of whether there are people in it; it doesn't crush after all - safety: false + # needed so that windoors loop between closing and reopening less often even though they don't crush + safety: true - type: NavMapDoor - type: DoorBolt - type: Electrified From 0431a99b5c0f15ec4e3e80f5c0324a768b8524ff Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 24 Apr 2026 11:53:31 +0000 Subject: [PATCH 21/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index bcb417e14f..5f6285c63b 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Princess_Chzblz, AdmiralObvious, hyphenation, Is-A-Slark, beck - changes: - - message: PAIs will no longer get uplinks instead of traitors when a player is - selected as an traitor and holding a pAI - type: Fix - id: 9152 - time: '2025-10-24T05:58:49.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/41069 - author: slarticodefast changes: - message: Fixed being able to wield two-handed weapons when having only one hand. @@ -4050,3 +4042,10 @@ id: 9663 time: '2026-04-24T10:48:17.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/37572 +- author: JacksonBailey + changes: + - message: Windoors no longer close on their own when someone is standing in them. + type: Tweak + id: 9664 + time: '2026-04-24T11:52:23.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/40519 From c5bef48b94e205693e61434cfb96692b93636f79 Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:42:40 -0700 Subject: [PATCH 22/65] Actually Apply Skin Color to Markings when randomly generating a character. (#43380) * me when I forget to apply valid marking data when making random characters :( * actually fuck that TODO * tests * fix skeleton test fails * accurate descriptions * SKELETON FAILING AGAIN * end the skeleton problem permanently * better number * remove spaces * GRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- .../Tests/Humanoid/HumanoidProfileTests.cs | 135 +++++++++++++++++- .../GameTicking/GameTicker.Spawning.cs | 1 - .../Humanoid/HumanoidCharacterAppearance.cs | 7 +- .../Humanoid/Markings/MarkingManager.cs | 2 +- .../Humanoid/SkinColorationPrototype.cs | 17 ++- .../Systems/DnaScrambleOnTriggerSystem.cs | 1 - 6 files changed, 151 insertions(+), 12 deletions(-) diff --git a/Content.IntegrationTests/Tests/Humanoid/HumanoidProfileTests.cs b/Content.IntegrationTests/Tests/Humanoid/HumanoidProfileTests.cs index 48eb521c5e..417d9f0641 100644 --- a/Content.IntegrationTests/Tests/Humanoid/HumanoidProfileTests.cs +++ b/Content.IntegrationTests/Tests/Humanoid/HumanoidProfileTests.cs @@ -1,5 +1,9 @@ +using System.Collections.Generic; using Content.IntegrationTests.Fixtures; +using Content.IntegrationTests.Utility; +using Content.Shared.Body; using Content.Shared.Humanoid; +using Content.Shared.Humanoid.Markings; using Content.Shared.Humanoid.Prototypes; using Content.Shared.Preferences; using Content.Shared.Speech.Components; @@ -13,7 +17,14 @@ namespace Content.IntegrationTests.Tests.Humanoid; [TestOf(typeof(HumanoidProfileSystem))] public sealed class HumanoidProfileTests : GameTest { + private static readonly EntProtoId BaseSpecies = "MobHuman"; private static readonly ProtoId Vox = "Vox"; + private static string[] _species = GameDataScrounger.PrototypesOfKind(); + + private BodySystem _bodySystem; + private HumanoidProfileSystem _humanoidProfile; + private MarkingManager _markingManager; + private SharedVisualBodySystem _visualBody; [Test] public async Task EnsureValidLoading() @@ -27,8 +38,9 @@ public sealed class HumanoidProfileTests : GameTest { var entityManager = server.ResolveDependency(); var humanoidProfile = entityManager.System(); - var human = entityManager.Spawn("MobHuman"); - humanoidProfile.ApplyProfileTo(human, new HumanoidCharacterProfile() + var human = entityManager.Spawn(BaseSpecies); + humanoidProfile.ApplyProfileTo(human, + new HumanoidCharacterProfile() .WithSex(Sex.Female) .WithAge(67) .WithGender(Gender.Neuter) @@ -45,4 +57,123 @@ public sealed class HumanoidProfileTests : GameTest Assert.That(voiceComponent.Sounds![Sex.Female], Is.EqualTo(voiceComponent.EmoteSounds)); }); } + + [Test] + [TestOf(typeof(HumanoidCharacterProfile)), TestOf(typeof(VisualBodyComponent))] + [Description("Tests that the game can generate a completely random profile with a completely random species and apply it to a blank body.")] + public async Task EnsureValidRandom() + { + var pair = Pair; + var server = pair.Server; + + await server.WaitIdleAsync(); + + await server.WaitAssertion(() => + { + LoadDependencies(out var body, out var humanoidComponent); + var profile = HumanoidCharacterProfile.Random(); + _humanoidProfile.ApplyProfileTo(body, profile); + _visualBody.ApplyProfileTo(body, profile); + + AssertValidProfile((body, humanoidComponent), profile); + }); + } + + [Test] + [TestOf(typeof(HumanoidCharacterProfile)), TestOf(typeof(VisualBodyComponent))] + [TestCaseSource(nameof(_species))] + [Description("Tests that every species is able to randomly generate a valid appearance without issues.")] + public async Task EnsureValidRandomSpecies(string species) + { + await Server.WaitIdleAsync(); + + await Server.WaitAssertion(() => + { + LoadDependencies(out var body, out var humanoidComponent); + + var proto = Server.ProtoMan.Index(species); + var profile = HumanoidCharacterProfile.RandomWithSpecies(species); + _humanoidProfile.ApplyProfileTo(body, profile); + _visualBody.ApplyProfileTo(body, profile); + + Assert.That(humanoidComponent.Age, Is.LessThanOrEqualTo(proto.MaxAge)); + Assert.That(humanoidComponent.Age, Is.GreaterThanOrEqualTo(proto.MinAge)); + Assert.That(proto.Sexes.Contains(humanoidComponent.Sex), Is.True); + Assert.That(humanoidComponent.Species, Is.EqualTo(species)); + var strategy = Server.ProtoMan.Index(proto.SkinColoration).Strategy; + Assert.That(strategy.VerifySkinColor(profile.Appearance.SkinColor), Is.True); + + AssertValidProfile((body, humanoidComponent), profile); + }); + } + + private void LoadDependencies(out EntityUid body, out HumanoidProfileComponent humanoidComponent) + { + var entityManager = Server.ResolveDependency(); + _humanoidProfile = entityManager.System(); + _markingManager = Server.ResolveDependency(); + _visualBody = entityManager.System(); + _bodySystem = entityManager.System(); + body = entityManager.Spawn(BaseSpecies); + humanoidComponent = entityManager.GetComponent(body); + } + + private void AssertValidProfile(Entity body, HumanoidCharacterProfile profile) + { + _bodySystem.TryGetOrgansWithComponent(body.Owner, out var organs); + + foreach (var (_, visualOrgan) in organs) + { + Assert.That(visualOrgan.Profile.Sex, Is.EqualTo(profile.Sex)); + Assert.That(visualOrgan.Profile.EyeColor, Is.EqualTo(profile.Appearance.EyeColor)); + Assert.That(visualOrgan.Profile.SkinColor, Is.EqualTo(profile.Appearance.SkinColor)); + } + + _bodySystem.TryGetOrgansWithComponent(body.Owner, out var markings); + + foreach (var (_, markingOrgan) in markings) + { + // Needed to avoid access restrictions + var data = markingOrgan.MarkingData; + var groupProto = Server.ProtoMan.Index(data.Group); + var counts = new Dictionary(); + var freeMarkings = new List(); + + foreach (var marking in markingOrgan.AppliedMarkings) + { + var markingProto = Server.ProtoMan.Index(marking.MarkingId); + + Assert.That(markingProto.Sprites.Count, Is.EqualTo(marking.MarkingColors.Count)); + Assert.That(_markingManager.CanBeApplied(data.Group, profile.Sex, markingProto), Is.True); + Assert.That(data.Layers.Contains(markingProto.BodyPart), Is.True); + if (!markingProto.ForcedColoring && groupProto.Appearances.GetValueOrDefault(markingProto.BodyPart)?.MatchSkin != true) + freeMarkings.Add(marking); + + if (!groupProto.Limits.TryGetValue(markingProto.BodyPart, out var limits)) + continue; + + var count = counts.GetValueOrDefault(markingProto.BodyPart); + Assert.That(count, Is.LessThanOrEqualTo(limits.Limit)); + counts[markingProto.BodyPart] = count + 1; + } + + if (freeMarkings.Count == markingOrgan.AppliedMarkings.Count) + continue; + + // Go through the whole list a second time just for the colors! + foreach (var marking in markingOrgan.AppliedMarkings) + { + if (freeMarkings.Contains(marking)) + continue; + + var markingProto = Server.ProtoMan.Index(marking.MarkingId); + + Assert.That(marking.MarkingColors, + Is.EqualTo(MarkingColoring.GetMarkingLayerColors(markingProto, profile.Appearance.SkinColor, profile.Appearance.EyeColor, markingOrgan.AppliedMarkings))); + + if (markingProto.SexRestriction != null) + Assert.That(markingProto.SexRestriction, Is.EqualTo(profile.Sex)); + } + } + } } diff --git a/Content.Server/GameTicking/GameTicker.Spawning.cs b/Content.Server/GameTicking/GameTicker.Spawning.cs index 4b00dc3143..584bd343d6 100644 --- a/Content.Server/GameTicking/GameTicker.Spawning.cs +++ b/Content.Server/GameTicking/GameTicker.Spawning.cs @@ -211,7 +211,6 @@ namespace Content.Server.GameTicking } character = HumanoidCharacterProfile.RandomWithSpecies(speciesId); - character.Appearance = HumanoidCharacterAppearance.EnsureValid(character.Appearance, character.Species, character.Sex); } // We raise this event to allow other systems to handle spawning this player themselves. (e.g. late-join wizard, etc) diff --git a/Content.Shared/Humanoid/HumanoidCharacterAppearance.cs b/Content.Shared/Humanoid/HumanoidCharacterAppearance.cs index e9b1f0a076..12241f1e49 100644 --- a/Content.Shared/Humanoid/HumanoidCharacterAppearance.cs +++ b/Content.Shared/Humanoid/HumanoidCharacterAppearance.cs @@ -103,7 +103,12 @@ public sealed partial class HumanoidCharacterAppearance : IEquatable strategy.ClosestSkinColor(new Color(random.NextFloat(1), random.NextFloat(1), random.NextFloat(1), 1)), }; - return new HumanoidCharacterAppearance(newEyeColor, newSkinColor, new()); + // Safety step. Most systems which called Random() also called this, and not doing so caused issues with markings. + // In the future it could *maybe* be removed, but it's probably worth the extra CPU cycles to validate this info. + return EnsureValid( + new HumanoidCharacterAppearance(newEyeColor, newSkinColor, new()), + species, + sex); } public static Color ClampColor(Color color) diff --git a/Content.Shared/Humanoid/Markings/MarkingManager.cs b/Content.Shared/Humanoid/Markings/MarkingManager.cs index 22ef73e1ba..e5a8a2f3a3 100644 --- a/Content.Shared/Humanoid/Markings/MarkingManager.cs +++ b/Content.Shared/Humanoid/Markings/MarkingManager.cs @@ -216,7 +216,7 @@ public sealed class MarkingManager continue; } - counts[marking.BodyPart] = counts.GetValueOrDefault(marking.BodyPart) + 1; + counts[marking.BodyPart] = count + 1; } } diff --git a/Content.Shared/Humanoid/SkinColorationPrototype.cs b/Content.Shared/Humanoid/SkinColorationPrototype.cs index afb90bf39a..86d83d9abf 100644 --- a/Content.Shared/Humanoid/SkinColorationPrototype.cs +++ b/Content.Shared/Humanoid/SkinColorationPrototype.cs @@ -308,11 +308,16 @@ public sealed partial class ClampedHslColoration : ISkinColorationStrategy internal static class SkinColorationUtils { /// - /// An empirically determined epsilon to account for floating-point drift during RGB -> HSL/HSV -> RGB conversions. - /// Based on high-iteration testing (50M+ samples) which showed a max drift of ~4.9E-6 for HSL. - /// A value of 1E-5f provides a robust safety margin. + /// A value derived by dividing 1 by 361, rounding down. + /// Due to the way these values are stored and deconstructed we can't expect much more precision than this.. /// - public const float Epsilon = 1e-5f; // 0.00001 + public const float EpsilonHue = 0.00277f; + + /// + /// A value derived by dividing 1 by 256. + /// Due to the way these values are stored and deconstructed we can't expect much more precision than this.. + /// + public const float Epsilon = 0.00390625f; /// /// Checks if a hue value is within a specified range, correctly handling ranges that wrap around 1.0 (e.g., reds). @@ -324,8 +329,8 @@ internal static class SkinColorationUtils public static bool IsHueInRange(float hue, float minHue, float maxHue) { if (minHue > maxHue) // Wraps around 1.0 (e.g., reds) - return hue >= minHue - Epsilon || hue <= maxHue + Epsilon; - return hue >= minHue - Epsilon && hue <= maxHue + Epsilon; + return hue >= minHue - EpsilonHue || hue <= maxHue + EpsilonHue; + return hue >= minHue - EpsilonHue && hue <= maxHue + EpsilonHue; } /// diff --git a/Content.Shared/Trigger/Systems/DnaScrambleOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/DnaScrambleOnTriggerSystem.cs index 8d592f444e..9e2dc0ad9f 100644 --- a/Content.Shared/Trigger/Systems/DnaScrambleOnTriggerSystem.cs +++ b/Content.Shared/Trigger/Systems/DnaScrambleOnTriggerSystem.cs @@ -33,7 +33,6 @@ public sealed class DnaScrambleOnTriggerSystem : XOnTriggerSystem Date: Fri, 24 Apr 2026 15:59:08 +0000 Subject: [PATCH 23/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 5f6285c63b..5bfbb462b3 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: slarticodefast - changes: - - message: Fixed being able to wield two-handed weapons when having only one hand. - type: Fix - id: 9153 - time: '2025-10-24T07:36:29.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/40966 - author: TheGrimbeeper changes: - message: Fix artifact radiation trigger not being triggered by ambient radiation. @@ -4049,3 +4042,10 @@ id: 9664 time: '2026-04-24T11:52:23.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/40519 +- author: Princess-Cheeseballs + changes: + - message: Randomly generated characters will now be colored correctly. + type: Fix + id: 9665 + time: '2026-04-24T15:57:58.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/43380 From 3279840bf0011cf94cd546ad4cfff5dc0a7e8e7f Mon Sep 17 00:00:00 2001 From: Pok <113675512+Pok27@users.noreply.github.com> Date: Fri, 24 Apr 2026 19:49:54 +0300 Subject: [PATCH 24/65] TemporaryBlindness StatusEffect (#43705) * TemporaryBlindnessStatusEffect * review --- ...t.cs => BlindnessStatusEffectComponent.cs} | 6 +-- .../Eye/Blinding/Systems/BlindnessSystem.cs | 47 +++++++++++++++++++ .../Blinding/Systems/EyeProtectionSystem.cs | 6 +-- .../Systems/TemporaryBlindnessSystem.cs | 37 --------------- Content.Shared/Flash/SharedFlashSystem.cs | 6 --- .../StatusEffectSystem.Relay.cs | 4 ++ .../entity-effects/statuseffects.ftl | 1 - Resources/Prototypes/Body/species_base.yml | 1 - .../Entities/Mobs/NPCs/asteroid.yml | 1 - .../Entities/Mobs/NPCs/simplemob.yml | 2 - .../Entities/Mobs/Player/dragon.yml | 1 - .../Entities/StatusEffects/misc.yml | 13 +++++ Resources/Prototypes/Reagents/narcotics.yml | 12 ++--- Resources/Prototypes/status_effects.yml | 3 -- 14 files changed, 75 insertions(+), 65 deletions(-) rename Content.Shared/Eye/Blinding/Components/{TemporaryBlindnessComponent.cs => BlindnessStatusEffectComponent.cs} (55%) create mode 100644 Content.Shared/Eye/Blinding/Systems/BlindnessSystem.cs delete mode 100644 Content.Shared/Eye/Blinding/Systems/TemporaryBlindnessSystem.cs diff --git a/Content.Shared/Eye/Blinding/Components/TemporaryBlindnessComponent.cs b/Content.Shared/Eye/Blinding/Components/BlindnessStatusEffectComponent.cs similarity index 55% rename from Content.Shared/Eye/Blinding/Components/TemporaryBlindnessComponent.cs rename to Content.Shared/Eye/Blinding/Components/BlindnessStatusEffectComponent.cs index 1f89c3df86..7e8016d8d7 100644 --- a/Content.Shared/Eye/Blinding/Components/TemporaryBlindnessComponent.cs +++ b/Content.Shared/Eye/Blinding/Components/BlindnessStatusEffectComponent.cs @@ -3,9 +3,7 @@ using Robust.Shared.GameStates; namespace Content.Shared.Eye.Blinding.Components; /// -/// Component used for the blind status effect. +/// Prevents the target from seeing while active. /// [NetworkedComponent, RegisterComponent] -public sealed partial class TemporaryBlindnessComponent : Component -{ -} +public sealed partial class BlindnessStatusEffectComponent : Component; diff --git a/Content.Shared/Eye/Blinding/Systems/BlindnessSystem.cs b/Content.Shared/Eye/Blinding/Systems/BlindnessSystem.cs new file mode 100644 index 0000000000..79822485d0 --- /dev/null +++ b/Content.Shared/Eye/Blinding/Systems/BlindnessSystem.cs @@ -0,0 +1,47 @@ +using Content.Shared.Eye.Blinding.Components; +using Content.Shared.Flash; +using Content.Shared.StatusEffectNew; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Eye.Blinding.Systems; + +public sealed class BlindnessSystem : EntitySystem +{ + public static readonly EntProtoId BlindingStatusEffect = "StatusEffectBlindness"; + + [Dependency] private readonly BlindableSystem _blindableSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnApplied); + SubscribeLocalEvent(OnRemoved); + SubscribeLocalEvent>(OnBlindTrySee); + SubscribeLocalEvent>(OnFlashAttempt); + } + + private void OnApplied(Entity ent, ref StatusEffectAppliedEvent args) + { + _blindableSystem.UpdateIsBlind(args.Target); + } + + private void OnRemoved(Entity ent, ref StatusEffectRemovedEvent args) + { + _blindableSystem.UpdateIsBlind(args.Target); + } + + private void OnBlindTrySee(Entity ent, ref StatusEffectRelayedEvent args) + { + var ev = args.Args; + ev.Cancel(); + args.Args = ev; + } + + private void OnFlashAttempt(Entity ent, ref StatusEffectRelayedEvent args) + { + var ev = args.Args; + ev.Cancelled = true; + args.Args = ev; + } +} diff --git a/Content.Shared/Eye/Blinding/Systems/EyeProtectionSystem.cs b/Content.Shared/Eye/Blinding/Systems/EyeProtectionSystem.cs index 0b4353eeda..cf1dc2f15d 100644 --- a/Content.Shared/Eye/Blinding/Systems/EyeProtectionSystem.cs +++ b/Content.Shared/Eye/Blinding/Systems/EyeProtectionSystem.cs @@ -1,4 +1,4 @@ -using Content.Shared.StatusEffect; +using Content.Shared.StatusEffectNew; using Content.Shared.Inventory; using Content.Shared.Eye.Blinding.Components; using Content.Shared.Tools.Components; @@ -55,9 +55,9 @@ namespace Content.Shared.Eye.Blinding.Systems // how much damage they already accumulated. _blindingSystem.AdjustEyeDamage((args.User, blindable), 1); var statusTimeSpan = TimeSpan.FromSeconds(time * MathF.Sqrt(blindable.EyeDamage)); - _statusEffectsSystem.TryAddStatusEffect(args.User, TemporaryBlindnessSystem.BlindingStatusEffect, - statusTimeSpan, false, TemporaryBlindnessSystem.BlindingStatusEffect); + _statusEffectsSystem.TryAddStatusEffectDuration(args.User, BlindnessSystem.BlindingStatusEffect, statusTimeSpan); } + private void OnWelderToggled(EntityUid uid, RequiresEyeProtectionComponent component, ItemToggledEvent args) { component.Toggled = args.Activated; diff --git a/Content.Shared/Eye/Blinding/Systems/TemporaryBlindnessSystem.cs b/Content.Shared/Eye/Blinding/Systems/TemporaryBlindnessSystem.cs deleted file mode 100644 index 34680b12ef..0000000000 --- a/Content.Shared/Eye/Blinding/Systems/TemporaryBlindnessSystem.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Content.Shared.Eye.Blinding.Components; -using Content.Shared.StatusEffect; -using Robust.Shared.Prototypes; - -namespace Content.Shared.Eye.Blinding.Systems; - -public sealed class TemporaryBlindnessSystem : EntitySystem -{ - public static readonly ProtoId BlindingStatusEffect = "TemporaryBlindness"; - - [Dependency] private readonly BlindableSystem _blindableSystem = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnStartup); - SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnBlindTrySee); - } - - private void OnStartup(EntityUid uid, TemporaryBlindnessComponent component, ComponentStartup args) - { - _blindableSystem.UpdateIsBlind(uid); - } - - private void OnShutdown(EntityUid uid, TemporaryBlindnessComponent component, ComponentShutdown args) - { - _blindableSystem.UpdateIsBlind(uid); - } - - private void OnBlindTrySee(EntityUid uid, TemporaryBlindnessComponent component, CanSeeAttemptEvent args) - { - if (component.LifeStage <= ComponentLifeStage.Running) - args.Cancel(); - } -} diff --git a/Content.Shared/Flash/SharedFlashSystem.cs b/Content.Shared/Flash/SharedFlashSystem.cs index 30f11efdeb..ada70e49b8 100644 --- a/Content.Shared/Flash/SharedFlashSystem.cs +++ b/Content.Shared/Flash/SharedFlashSystem.cs @@ -61,7 +61,6 @@ public abstract class SharedFlashSystem : EntitySystem SubscribeLocalEvent(OnRangedInteract); SubscribeLocalEvent(OnLightToggle); SubscribeLocalEvent(OnPermanentBlindnessFlashAttempt); - SubscribeLocalEvent(OnTemporaryBlindnessFlashAttempt); Subs.SubscribeWithRelay(OnFlashImmunityFlashAttempt, held: false); SubscribeLocalEvent(OnExamine); } @@ -273,11 +272,6 @@ public abstract class SharedFlashSystem : EntitySystem args.Cancelled = true; } - private void OnTemporaryBlindnessFlashAttempt(Entity ent, ref FlashAttemptEvent args) - { - args.Cancelled = true; - } - private void OnFlashImmunityFlashAttempt(Entity ent, ref FlashAttemptEvent args) { if (TryComp(ent, out var mask) && mask.IsToggled) diff --git a/Content.Shared/StatusEffectNew/StatusEffectSystem.Relay.cs b/Content.Shared/StatusEffectNew/StatusEffectSystem.Relay.cs index cf81f66d9f..77fe0cb612 100644 --- a/Content.Shared/StatusEffectNew/StatusEffectSystem.Relay.cs +++ b/Content.Shared/StatusEffectNew/StatusEffectSystem.Relay.cs @@ -1,6 +1,8 @@ using Content.Shared.Body.Events; using Content.Shared.Damage.Events; using Content.Shared.Damage.Systems; +using Content.Shared.Eye.Blinding.Systems; +using Content.Shared.Flash; using Content.Shared.Mobs.Events; using Content.Shared.Movement.Events; using Content.Shared.Movement.Systems; @@ -29,6 +31,8 @@ public sealed partial class StatusEffectsSystem SubscribeLocalEvent(RefRelayStatusEffectEvent); SubscribeLocalEvent(RefRelayStatusEffectEvent); SubscribeLocalEvent(RefRelayStatusEffectEvent); + SubscribeLocalEvent(RelayStatusEffectEvent); + SubscribeLocalEvent(RefRelayStatusEffectEvent); SubscribeLocalEvent(RelayStatusEffectEvent); SubscribeLocalEvent(RelayStatusEffectEvent); diff --git a/Resources/Locale/en-US/guidebook/entity-effects/statuseffects.ftl b/Resources/Locale/en-US/guidebook/entity-effects/statuseffects.ftl index 435041dc68..98c97ed138 100644 --- a/Resources/Locale/en-US/guidebook/entity-effects/statuseffects.ftl +++ b/Resources/Locale/en-US/guidebook/entity-effects/statuseffects.ftl @@ -1,7 +1,6 @@ entity-effect-status-effect-Stun = stunning entity-effect-status-effect-KnockedDown = knockdown entity-effect-status-effect-Jitter = jittering -entity-effect-status-effect-TemporaryBlindness = blindness entity-effect-status-effect-SeeingRainbows = hallucinations entity-effect-status-effect-Muted = inability to speak entity-effect-status-effect-Stutter = stuttering diff --git a/Resources/Prototypes/Body/species_base.yml b/Resources/Prototypes/Body/species_base.yml index 4716e3ca7f..d03b2f3e2c 100644 --- a/Resources/Prototypes/Body/species_base.yml +++ b/Resources/Prototypes/Body/species_base.yml @@ -75,7 +75,6 @@ - RatvarianLanguage - PressureImmunity - Muted - - TemporaryBlindness - Pacified - Flashed - Adrenaline diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml b/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml index f790b4abf9..61eb23c929 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml @@ -19,7 +19,6 @@ - type: StatusEffects allowed: - Electrocution - - TemporaryBlindness - Adrenaline - type: StandingState - type: Tag diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml index 0bdfcdfa27..1fda20dbf3 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml @@ -19,7 +19,6 @@ - type: StatusEffects allowed: - Electrocution - - TemporaryBlindness - Pacified - Flashed - Adrenaline @@ -91,7 +90,6 @@ - type: StatusEffects allowed: - Electrocution - - TemporaryBlindness - Pacified - Flashed - Adrenaline diff --git a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml index 7a1dbd7144..6f8b225ed7 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml @@ -104,7 +104,6 @@ - type: StatusEffects # Overwriting basesimplemob to remove flash, getting flashed as dragon just feelsbad allowed: - Electrocution - - TemporaryBlindness - Pacified - Adrenaline - type: Temperature diff --git a/Resources/Prototypes/Entities/StatusEffects/misc.yml b/Resources/Prototypes/Entities/StatusEffects/misc.yml index 14c6b5b649..430003fe8f 100644 --- a/Resources/Prototypes/Entities/StatusEffects/misc.yml +++ b/Resources/Prototypes/Entities/StatusEffects/misc.yml @@ -92,3 +92,16 @@ parent: [ StatusEffectWoozy, StatusEffectSlurred ] id: StatusEffectDrunk name: drunk + +# Prevents the target from seeing +- type: entity + parent: MobStatusEffectDebuff + id: StatusEffectBlindness + name: temporary blindness + components: + - type: StatusEffect + whitelist: + components: + - MobState + - Blindable + - type: BlindnessStatusEffect diff --git a/Resources/Prototypes/Reagents/narcotics.yml b/Resources/Prototypes/Reagents/narcotics.yml index 65674bb5a2..87828bc000 100644 --- a/Resources/Prototypes/Reagents/narcotics.yml +++ b/Resources/Prototypes/Reagents/narcotics.yml @@ -388,9 +388,9 @@ min: 20 probability: 0.03 #If anyone wants to add a light dimming or grayscale effect when under 20u, be my guest - - !type:GenericStatusEffect - key: TemporaryBlindness - component: TemporaryBlindness + - !type:ModifyStatusEffect + effectProto: StatusEffectBlindness + type: Add conditions: - !type:ReagentCondition reagent: NorepinephricAcid @@ -441,9 +441,9 @@ - !type:Emote emote: Cough probability: 0.08 - - !type:GenericStatusEffect - key: TemporaryBlindness - component: TemporaryBlindness + - !type:ModifyStatusEffect + effectProto: StatusEffectBlindness + type: Add conditions: - !type:ReagentCondition reagent: TearGas diff --git a/Resources/Prototypes/status_effects.yml b/Resources/Prototypes/status_effects.yml index c40b26fe85..201e1e2aa1 100644 --- a/Resources/Prototypes/status_effects.yml +++ b/Resources/Prototypes/status_effects.yml @@ -41,9 +41,6 @@ id: Corporeal alert: Corporeal -- type: statusEffect - id: TemporaryBlindness - - type: statusEffect id: Pacified #cannot attack From ad3a5e0365e7f90f4c22c7206980a6c77df6d6ad Mon Sep 17 00:00:00 2001 From: WS01 <151183296+Tuchila-Adi-Bogdan@users.noreply.github.com> Date: Fri, 24 Apr 2026 20:16:51 +0300 Subject: [PATCH 25/65] Added IngestionBlocker modifier to radiation hood (#43699) Co-authored-by: beck-thompson --- Resources/Prototypes/Entities/Clothing/Head/hoods.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Clothing/Head/hoods.yml b/Resources/Prototypes/Entities/Clothing/Head/hoods.yml index 21d8d06b3f..a9f119146b 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hoods.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hoods.yml @@ -165,6 +165,7 @@ Heat: 0.95 Radiation: 0.65 - type: IdentityBlocker + - type: IngestionBlocker - type: BreathMask - type: HideLayerClothing slots: From 8e5c6e77acd6f406f976f83ab9c8d1136487aea2 Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 24 Apr 2026 17:32:20 +0000 Subject: [PATCH 26/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 5bfbb462b3..b0aafabf72 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: TheGrimbeeper - changes: - - message: Fix artifact radiation trigger not being triggered by ambient radiation. - type: Fix - id: 9154 - time: '2025-10-24T09:21:26.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/41065 - author: PicklOH changes: - message: Space Dragon and Carp are more heat resistant. Carp no longer take fire @@ -4049,3 +4042,10 @@ id: 9665 time: '2026-04-24T15:57:58.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/43380 +- author: Tuchila-Adi-Bogdan + changes: + - message: You can no longer eat with the radiation hood on. + type: Tweak + id: 9666 + time: '2026-04-24T17:31:12.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/43699 From 1ce53841df8a886abe5504c5bfce2a9d5ddc7636 Mon Sep 17 00:00:00 2001 From: korczoczek Date: Sat, 25 Apr 2026 00:06:23 +0200 Subject: [PATCH 27/65] Let borg modules exclude other modules (#43282) * comp and ftl * all the logic to tie it together * forgot * review * review * lambda it up * make ftl more distinct * review * forgot to remove those * move ModuleTypes to Whitelistcomponent * actually use the correct whitelist * make blacklist detection more robust and add whitelisting logic * buncha tweaks * comment * finishing touches * Minor style changes --------- Co-authored-by: beck-thompson --- .../Borgs/Components/BorgModuleComponent.cs | 9 +- .../BorgModuleWhitelistComponent.cs | 31 +++++ .../Silicons/Borgs/SharedBorgSystem.API.cs | 3 +- .../Silicons/Borgs/SharedBorgSystem.Module.cs | 129 ++++++++++++++++-- .../Silicons/Borgs/SharedBorgSystem.cs | 2 + Resources/Locale/en-US/borg/borg.ftl | 5 +- 6 files changed, 159 insertions(+), 20 deletions(-) create mode 100644 Content.Shared/Silicons/Borgs/Components/BorgModuleWhitelistComponent.cs diff --git a/Content.Shared/Silicons/Borgs/Components/BorgModuleComponent.cs b/Content.Shared/Silicons/Borgs/Components/BorgModuleComponent.cs index a677d240fe..f826bd0ad1 100644 --- a/Content.Shared/Silicons/Borgs/Components/BorgModuleComponent.cs +++ b/Content.Shared/Silicons/Borgs/Components/BorgModuleComponent.cs @@ -33,15 +33,16 @@ public sealed partial class BorgModuleComponent : Component /// This only affects examine text. The actual whitelist for modules that can be inserted into a borg is defined in its . /// [DataField] - public HashSet? BorgFitTypes; + public List? BorgFitTypes; } /// -/// Raised on a chassis before a module is inserted into it. +/// Raised on a chassis and module before a module is inserted into it. /// /// The module being added. +/// The chassis being added to. [ByRefEvent] -public record struct BorgModuleInsertAttemptEvent(EntityUid ModuleEnt, bool Cancelled = false, string? Reason = null); +public record struct BorgModuleInsertAttemptEvent(EntityUid ModuleEnt, EntityUid ChassisEnt, bool Cancelled = false, string? Reason = null); /// /// Raised on a module when it is installed in order to add specific behavior to an entity. @@ -51,7 +52,7 @@ public record struct BorgModuleInsertAttemptEvent(EntityUid ModuleEnt, bool Canc public readonly record struct BorgModuleInstalledEvent(EntityUid ChassisEnt); /// -/// Raised on a module when it's uninstalled in order to +/// Raised on a module when it is uninstalled /// /// The borg the module is being uninstalled from. [ByRefEvent] diff --git a/Content.Shared/Silicons/Borgs/Components/BorgModuleWhitelistComponent.cs b/Content.Shared/Silicons/Borgs/Components/BorgModuleWhitelistComponent.cs new file mode 100644 index 0000000000..16696a6577 --- /dev/null +++ b/Content.Shared/Silicons/Borgs/Components/BorgModuleWhitelistComponent.cs @@ -0,0 +1,31 @@ +using Content.Shared.Whitelist; +using Robust.Shared.GameStates; + +namespace Content.Shared.Silicons.Borgs.Components; + +/// +/// This is used for modules which require the presence or absence +/// of a specific type of module to be installed +/// +[RegisterComponent, Access(typeof(SharedBorgSystem))] +public sealed partial class BorgModuleWhitelistComponent : Component +{ + /// + /// Examine text informing the player of what type of module this is + /// as well as which modules are incompatible or required + /// + [DataField] + public LocId WhitelistInfo; + + /// + /// List of module tags this module is incompatible with + /// + [DataField] + public EntityWhitelist? ModuleBlacklist; + + /// + /// List of module tags required for the module to be installed + /// + [DataField] + public EntityWhitelist? ModuleWhitelist; +} diff --git a/Content.Shared/Silicons/Borgs/SharedBorgSystem.API.cs b/Content.Shared/Silicons/Borgs/SharedBorgSystem.API.cs index 941bf990bc..ddbce3c1df 100644 --- a/Content.Shared/Silicons/Borgs/SharedBorgSystem.API.cs +++ b/Content.Shared/Silicons/Borgs/SharedBorgSystem.API.cs @@ -236,8 +236,9 @@ public abstract partial class SharedBorgSystem } } - var attemptEv = new BorgModuleInsertAttemptEvent(module.Owner); + var attemptEv = new BorgModuleInsertAttemptEvent(module.Owner, chassis.Owner); RaiseLocalEvent(chassis, ref attemptEv); + RaiseLocalEvent(module, ref attemptEv); if (attemptEv.Cancelled) { diff --git a/Content.Shared/Silicons/Borgs/SharedBorgSystem.Module.cs b/Content.Shared/Silicons/Borgs/SharedBorgSystem.Module.cs index 5d6f162414..5413216ee9 100644 --- a/Content.Shared/Silicons/Borgs/SharedBorgSystem.Module.cs +++ b/Content.Shared/Silicons/Borgs/SharedBorgSystem.Module.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; +using System.Linq; using Content.Shared.Examine; using Content.Shared.Hands.Components; using Content.Shared.Interaction.Components; @@ -14,6 +16,7 @@ public abstract partial class SharedBorgSystem public void InitializeModule() { SubscribeLocalEvent(OnModuleExamine); + SubscribeLocalEvent(OnWhitelistExamine); SubscribeLocalEvent(OnModuleGotInserted); SubscribeLocalEvent(OnModuleGotRemoved); @@ -30,26 +33,42 @@ public abstract partial class SharedBorgSystem SubscribeLocalEvent>( OnComponentModuleInstalledRelay); + + SubscribeLocalEvent(OnCheckWhitelist); + SubscribeLocalEvent>( + OnCheckBlacklistRelay); } #region BorgModule private void OnModuleExamine(Entity ent, ref ExaminedEvent args) { - if (ent.Comp.BorgFitTypes == null) - return; - - if (ent.Comp.BorgFitTypes.Count == 0) - return; - - var typeList = new List(); - - foreach (var type in ent.Comp.BorgFitTypes) + using (args.PushGroup(nameof(BorgModuleComponent))) { - typeList.Add(Loc.GetString(type)); + if (TryFormatList(ent.Comp.BorgFitTypes, "borg-module-fit", "types", out var list)) + args.PushMarkup(list); } + } + + private void OnWhitelistExamine(Entity ent, ref ExaminedEvent args) + { + using (args.PushGroup(nameof(BorgModuleComponent), 1)) + { + args.PushMarkup(Loc.GetString(ent.Comp.WhitelistInfo)); + } + } + + private bool TryFormatList(List? list, string messageId, string listId, [NotNullWhen(true)] out string? formattedList) + { + formattedList = null; + + if (list == null || list.Count == 0) + return false; + + var entries = ContentLocalizationManager.FormatList([.. list.Select(s => Loc.GetString(s))]); + + formattedList = Loc.GetString(messageId, (listId, entries)); + return true; - var types = ContentLocalizationManager.FormatList(typeList); - args.PushMarkup(Loc.GetString("borg-module-fit", ("types", types))); } private void OnModuleGotInserted(Entity module, ref EntGotInsertedIntoContainerMessage args) @@ -259,7 +278,8 @@ public abstract partial class SharedBorgSystem private void OnComponentModuleInstalledRelay(Entity ent, ref BorgModuleRelayedEvent args) { - if (!TryComp(args.Args.ModuleEnt, out var newModule)) + if (args.Args.Cancelled || + !TryComp(args.Args.ModuleEnt, out var newModule)) return; foreach (var comp in newModule.Components) @@ -270,6 +290,89 @@ public abstract partial class SharedBorgSystem args.Args.Reason = Loc.GetString("borg-module-incompatible", ("existing", ent)); } } + } #endregion + + #region ModuleWhitelist + + private void OnCheckWhitelist(Entity ent, ref BorgModuleInsertAttemptEvent args) + { + if (args.Cancelled || !TryComp(args.ChassisEnt, out var chassis)) + return; + + //loop over all other contained modules to see if any conflict with this module's blacklist + //while simultaneously checking if any module fits its prerequisite criteria + var prerequisiteFulfilled = false; + foreach (var containedModuleUid in chassis.ModuleContainer.ContainedEntities) + { + if (_whitelist.IsWhitelistPass(ent.Comp.ModuleBlacklist, containedModuleUid)) + { + args.Reason = Loc.GetString("borg-module-incompatible", ("existing", containedModuleUid)); + args.Cancelled = true; + return; + } + if (!prerequisiteFulfilled && _whitelist.IsWhitelistPassOrNull(ent.Comp.ModuleWhitelist, containedModuleUid)) + prerequisiteFulfilled = true; + } + if (!prerequisiteFulfilled) + { + args.Reason = Loc.GetString("borg-module-prerequisite-unfulfilled"); + args.Cancelled = true; + } + } + + private void OnCheckBlacklistRelay(Entity ent, ref BorgModuleRelayedEvent args) + { + if (args.Args.Cancelled) + return; + + if (_whitelist.IsWhitelistPass(ent.Comp.ModuleBlacklist, args.Args.ModuleEnt)) + { + args.Args.Cancelled = true; + args.Args.Reason = Loc.GetString("borg-module-incompatible", ("existing", ent)); + } + } + + //TODO: Replace this with a relayed event based system once there's a QueueRemove + //or something similar implemented that defers entity removal from containers to the following tick + //this cannot be implemented as a relayed event because the act of removing a module + //from a chassis modifies the relay's foreach loop collection to be modified, thus throwing an error + + /// This function removes all modules who are now invalidated by the removal of removedModule + private void ValidateWhitelists(Entity chassis, EntityUid removedModule) + { + var toRemove = new List(); + foreach (var containedModuleUid in chassis.Comp.ModuleContainer.ContainedEntities) + { + if (containedModuleUid == removedModule || + !TryComp(containedModuleUid, out var whitelist) || + whitelist.ModuleWhitelist == null) + continue; + + var keep = false; + + foreach (var checkAgainstModuleUid in chassis.Comp.ModuleContainer.ContainedEntities) + { + if (checkAgainstModuleUid == containedModuleUid || + checkAgainstModuleUid == removedModule) + continue; + + if (_whitelist.IsWhitelistPass(whitelist.ModuleWhitelist, checkAgainstModuleUid)) + { + keep = true; + break; + } + } + if (!keep) + toRemove.Add(containedModuleUid); + } + + foreach (var moduleUid in toRemove) + { + _container.Remove(moduleUid, chassis.Comp.ModuleContainer); + } + } + + #endregion } diff --git a/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs b/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs index 42da1c6d5d..ebdef9ed1c 100644 --- a/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs +++ b/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs @@ -184,6 +184,8 @@ public abstract partial class SharedBorgSystem : EntitySystem if (_timing.ApplyingState) return; // The changes are already networked with the same game state + ValidateWhitelists(chassis, args.Entity); + if (args.Container != chassis.Comp.BrainContainer) return; diff --git a/Resources/Locale/en-US/borg/borg.ftl b/Resources/Locale/en-US/borg/borg.ftl index f8f4c7d0ee..836abde606 100644 --- a/Resources/Locale/en-US/borg/borg.ftl +++ b/Resources/Locale/en-US/borg/borg.ftl @@ -7,9 +7,10 @@ borg-mind-added = {CAPITALIZE($name)} powered on! borg-mind-removed = {CAPITALIZE($name)} shut off! borg-module-too-many = There's not enough room for another module... -borg-module-duplicate = This module is already installed in this cyborg. +borg-module-duplicate = This module is already installed in this cyborg... borg-module-whitelist-deny = This module doesn't fit in this type of cyborg... -borg-module-incompatible = This module isn't compatible with {THE($existing)}. +borg-module-incompatible = This module isn't compatible with {THE($existing)}... +borg-module-prerequisite-unfulfilled = This module requires another module to function... borg-module-action-name = Activate {$moduleName} borg-module-action-description = Select the {$moduleName}, enabling you to use the tools it provides. From de1caaf3eec78200184e467d130b46a319af1213 Mon Sep 17 00:00:00 2001 From: Menshin Date: Sat, 25 Apr 2026 03:20:10 +0200 Subject: [PATCH 28/65] Updates GeneralUser GS soundfont to v2.0.3 (#43702) Updates GeneralUser GS soundfont to v2.0.3. --- Resources/Audio/MidiCustom/GeneralUser-GS.sf2 | Bin 32322864 -> 32319396 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Resources/Audio/MidiCustom/GeneralUser-GS.sf2 b/Resources/Audio/MidiCustom/GeneralUser-GS.sf2 index 2fdd31c69ee01a97ccf9efc99eba904822cae802..298b552d2e9d1307e03e5c5c99d2c046aaed9ec3 100644 GIT binary patch delta 838171 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

@MC~Og;r1h~hI*?|yQvU=a`N85+nf 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 z

8SDg9--gHXs?wY_wg%FIVshC^ZL7LmMi;$k^uu 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�rAxfq2PgyMV5LivXMY&4jo=Q;m(v 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

-=z*c& zX^*|yEaeLdj^r`kPH3CoFZJ7?kiUH|z1s2}Uli>zW(%)W{_f%==bwo^^YY@>d%C{c z(lP~X9WZ7g*JqRFSxE4(*`sqaqLx`}?zbK=1fB!NJWd|xt!Whgy*nXro@x4skZpR; zE`8m)7hf$Mi?W$(cvE4KV^MLh*Y%?}_kH>*=yy(IZf4YL>v0d}9W;XPjzu{Ri)1qe z*AB=0tsK8#-u_fx$WlGm%hR`xh2>5~IjlVXauT|nii+r$8D|`yMlH;7F3M)*NEh+p zf^$(3i_1Ms;=4&v5pk9SCy=rh$c}L#!Ua(g_aq7X5itT_fNN1Pt4IsnLg}R4WulBYV>JDHsABgXRL2IhJ0Xq5=6)=a9 z{a~CoD$mx>t%nwGR1U1V3NWNEUQs5yTMhgBqKwCx$p^oFh{n`p%3*Uq)HcghxI?=? z%GPl1@<2|bmMZ*3XXAs~4)LEF;P_xezSRW*a{yi5m=mj|Y|`18{ikt0uyMfTBWuclGfKU+@n^C12nIn*vd3S=|rZ zgNh0bHmTjppJPSYAiQus&ls!+p>}t54Ac)o*E8zo@+i;`E-GYA<-e+g)xmh#vdWKq z_!f+p^-xZ)@PVZvsCMKxS3yq*_IOfNKgbEi&@)p5^;hFfkmjJch@Bli}E9M#X9Y3>%DH=Ex%|Zm8ifVrDKk2>c_kVV^4^U`qrx ztXBTKY$|w0VxM|y%|H=}%5xRt!FC8LqhVaR5AYB&1sr$KABus=wZ}wIHWZt3OuDBW zz755um~u>D=`i#>TJ8(4hG8!j%NCWv?BUqSUDfYv;2w=6l9g*AXd*fg)!iJ}PNPrdNhEkr!X{0`EFP*!=&-u> zO)c0@M&;+SDJV`ypaJ zu84%WQ*rPMrFSaf!BkYf#e@}*9EZxh@~Lnw4sWEL)Ep*F!?0`XUe?2zX{h^LX%8c( zqoWJCuL2sUqhs&71zZT8flBWx2iP$K9e2nEL7#YZTu|T00c|{5eXPJAKaMl8vEOC= zKrj=ZfR*(DV4Q$fvg$4pDicu0kVnH$6fxg&f}wC0>MW~s@rTST>_;#xtAV^kjP;4D zs)t92m@BJBLP`=|@g+pTwIsB^!rjY*Daoias2v1t$=FnX<>G1>m4c3cxViYF0TFXf zO(=wa7ahxQT|aLh|^Jdq;4$?jehEgv?+k2pQC$=iXJXVywLiSeL`RWm5f|oXq2t}ULVzb(=;*1%gE6Vu z=*Sn1fE(HLhoOE9OwGZzM(NsW;cO1t?-W1c!I;^I)b-CvXhKA^a3C}n{q{*Gz^+^j zKZJXa1fMzhC2t10IVdMq0J17X2(G-AP1B*a@h8B~C;<<>B* z5Tz5S_QIlp?v$^7VX`4HPYcy%g=gtmvpDm@2ttBIVa*HA5O+vwx<%n(CU)G|rtlxD zGji#6rD0tB#If&s4k$4-#66ord!kJOUu+6@_D)tasgLh#?G{;^{78R3;eEaH$w-c$ z^*8UmW^mlLu#M3ls_Y8eh?W|d(yQ!m&(~JfFVwWr3t%`Gwy`{`QWW?f9hF7m=d~d1U3dm(UQ%38HBkJI9QwJU zz!%=Qq9Bvpp@l{_6a>KRbx4e13!r;;kqbTiz@p#;ZeS-vHi=busgHFGcNh| z?K!!zrxMPj6$IG#k^4)18jZg|SX2-!K@d?6Ff6@b4Bovp=><_l znG#MTOKg>ZQAWWS=5>J^#AXzXW|{DRkRZ+|7{%%<`!0o>h?tvHL%}H%z3{`Fo{2#) zzc9__i{Tl~j)DPM1yQW!g69fYl7+5c1q(&&~H>pOp=(HkX(8Vjsn&%#8~c_p$MMQ=n5uB z2j4}A3Y6O=kiQ7y*u%a>80VA-z937?z?r)I|IyVnT`YoANSO&jOE6rFaYsuySlxFq z#yBp)+R#E86_J}{aGgfq0dthEJgZG2n&(o z+{T`z_^8B+PpIL`QtYygtQSNs!)s;BY5`U+!)W7`b0lzzMlqVZ5-?bf{_90Bk*0e@ zz^CbZ5nQF|Um@5R;BC4sxuSv80`#euo>0L$8eM`n_|Jz%Ta-KTySNZ9m#Cc#3kq?B z`@kL~#1{#CD#Uh00>1u55htXuvIxT#$)E)(>oGK`z@Qi%pDS4qQ;hA*P_GBz7o*X0 zDO{y#i45%77-JYDu`z~H23ll^)41~hDH9hWpnnN^u2B~&U||Wir$zf-4tq<`#}z)7 zpid31DV3tndJHvCa!$%fYK}={kCO{WMZs z$;s_k+Q9Nq-zCAMKPqth%1)%rLz=-b)u*(9c}?I99}y5|`9Kap%{{PzNZ-;1oO`~5 zgq0!xj9(A~OV_db2z#{P?T1l*3E>P<)*?w4zFEvU$1r$MeDLl76Y!I6C!g{Os2ce)97yN?JTaQe}e>EW(Pbz}5NLkjZ zvocs1id}IB^Du1AaZNMUEDuA0G0X@r-9Uf}zJ()e0E)q=f3C${Pa`5Q#Cjz>K#G&* zYa`Jv4J(ukDP1_1c%lJm1M2a=R`~kT^#oT5UF(srQNYR#rR#AnzD*1oS4mvJcr)@W*nxy)L5igiw*@aS1U_s*L7cQ3Pa$umBk>_(8#cZWeoNpkBI1e= zR&PhiQ(QX&uN^4)jz zSuMFEav}>fSgbgEtiDDQp`1(|P-GA9#hR?e7mZK5v&Wn8R7d1eOlG)33uE_Wk23St zM9b@Bm9i;vwFZPJF^SXMf>4>A9QROk?a3Zv)PcDKGnLm>l=t53A8tku6mMlkB<_Xi zcM08vvK>4_PI!I3=oP*-T*@A1u>g+M->qD_R#x7RgUdioC^OHMJ>ghl&Mej1^4eg~ zznneXqD^kYe^J%8c5vmadR$_PyPQ43)C3ZFLpYXPQWy@3%h{t%-N`n=SuAt#SZWMU zFK3T5<;!Y#*0q^619-L&cm>1EQ-2cWac)*Eu7dh{5=yUR4>Rkfm5_TyPW;FG1yVS5 z1-sy+d<0eU)3}f4YW62z;*u7K-`UalT0l+yogH9lpwnJZW~-shEN85NiMktFu>w7f zIjXaO>za1vh*zrlN=)dMZl2>iiNNHZoWz{*`d!L!g&y2U%!x8#Y8%P75(`+Z0k5Q- zQO4G)HUHEviIeP| z0$dJcMjL%l7L!#nxf~WA$egI3tjbX`sbdE+t8y9M)M%%yc?PUgn9K%tyJt<-AE&#a z90z~hvtkV=V2=71m|k{O%J!ojvth5tf zslQiO$+^VylHJ9fbA7VLT0E3L6!~&%>h1U!L;^Vo`(%wbn+p4d{rCs?14Z;d4wP6l zsbghhL?u}LWQnXu4dLEdeB$oHh8e_Ri>nQ2NGvTb}OyzHs zxWP5rv=bf(zH&^kfsqI(STyHB9;O~@vcqJ{aO6Jv{ z;jF3u#?yoLe%PQG?M>Mjp_;dlmm}CJ!?`Q$-DibR_FC9S&?L$sVM+h2XtT@82$@pc zE;)b)OyM+bqtQ-Mj3EEP6~y-{u=mM|Hf~YhmsiTFr9m*)2X8JzlN3r)d+J zgba6}zDSEOz_T5(P)<4m^)@ZTpueI+mZ_jz-ldH)(KlB9CC5P4ca+N&9n!=6C}D_9lAdN_trbYa_%{3!ko`zcH5sXU zC3BG!OO9f7ct(1|%3GWdb zO;Chlg%7C)5}BwuscM&(XsHv-^quC!GYz%SI-PCL5@Ov6c+o#S-QO!7seLb9>`Y4x<~JKT2w zdwtWBO?E4$3oCgy1sMQ#1JhHDRN4aal5`nR?1Aay_4PY29XsyY2ujZ|a_TO=$P zFep94XbkA2CuP-I5Dr48aq0>3H;VQ6KW0#RI_r*>Qc(%P>E$fu6Ab}(!f}Y7Yd{_b z*X6iZW6WS|+Z?Q$Tqd~3|0Ps`Icyo6KFi{fw0~`7<(jI9+BE)Gtmht)o?z8qo>uQ& z;aJ8hpHt^6#$}*oC^f$-ep|N!v)emWSaWe=A|id3aO|zsI42{Iz zt|pHQj_`*F!h~%KSQm-CouS-H_EQd1VHRfAko4>0^=lOmq~oExEIq?GLqQ4`@G`~v zFm7#nn$Zt@WjxHQlfw43>FGuy)duN1$s!eHRi552ggW1ntewmhs6%0adCFpDlV$|f zZJyH0RDYM&P|bv|jwy33R;qrHUqx1ew*rB95AK?9O3AjoPF8XU)l90IQnjykqR<<< zol>%FoHPv4tQueJP;!}TRS0)FK%8?*rgeqVNEFG5ta^j>0#et?Ypmd;b4rdSNat{= z+B4O4RTrz(^^p+LJ0-{bv8Id+5Z@IP3y;eTs13bS7*?!9+A=k49hkDvM5&!6KPK}e z7i+=IFD1{oP4$p0ketUEZh>FQJfnfCd3Y+OU31t!C0<6IdXu=_-lRq431(RObGj0W zSV={g3oc9SFRJ5@5k8P_(o#QIN$YC}m4?!Cleqm^RvP@j7jQ7C)W}48l>7&lW9Dq+ z3}!1oN_8>_I+Rpun5JAVeIuI;`wk_QU?se#3RgK6Itf0URLXQz>r;CUC;9iHnhs{T zc^KSK-BO%VQV*_YaLf$vYhNk#R6f+whZ(j^vpR)Tq81j4o=Z35ubU?sa+AZdG7*R$ z$v>;8;HMdc4em7w`8cBU5TH6!T3cC@7=& z%mi~>;jo0PtW2GLn)ZV{g3`~#FVFA z6+JZ#f=~F<^kr(3?PcY1?hJf!D=2$X;Zz&L`BQHVOM6mV^{sXGng}ZLRcfpWYk~T) zn&Ny;t#l$@s3|MUG%J0hS(;AicnM!g`Pik|yR#&k<60OKl6Km3sBWBgy|!6<9KRT> zL(`5M`Y3XxHYC18g{HL{`f0^-e~6)UVQJT_jF=j=YMizRw-$|0J7qRs-o&%uu*VBpe#Uoob-TelhfJ^cWAb% zZmD9ZhS)S7gXN;zu7TjGX=j<&)Z^jz)U-C{Sj|Xii%UC)TgOGy(q5S|U#s4XKBC(Da9 z%e7(fb7S&t<^^peb!$`dM`!9sW!Cj61|pRQw5h1;*Rnhq`rk3vMlALHde&bPvj$b5 zbibfb=#P0&DAt24dxk{^R0*DP>T6rL&a!xXjvu1XeBvc#8{ZvP^RLh`jtb2D=b6R;>?nl*!WZN<<RVe`R(_%qk8KDAO6qc0wh6;bPqTpgyF9&|T;+hb(jn1 zJJv7goiVE3&{AC@)5!vH14+h1<~B_*yxNkn)}&DJuW)(&k@~qZs%UG*crz;gR7&PI zD*5>=GRyplwl}O6ofAZh>Sfl{@94yr4Ce*1v)nZ7lU|ukWqa-A`Za=aq6l#zrpr1! zDe(cr{Jgqa{s{I$lYG0jOuv z*`WP+z9r;j#J(Awy$7Bw6n37t-*0xPJpO*~&Hro?UpUh>U|mR2f}T^vxk~ZAi#h$9 zgD1@(dQCf{tB=39*}GSSbIL`hTkWUou3mBQvK=x%h2J~jTw9g<f87F74LX%^4+x-b4EAK%Jx~`@ek)n7uRIN z=(h=3fx64{g#UJXnq-Z+5*O+}s@+_8>b8XS&j{y99|N>!r%R4^FEFf%YM)jf-g;)T z;Mz&E}Ia^D;@`_S*Jb07WERO4|+fBiWA z1wORAFG>%sJmpGV(|75Ab> zm@q7se?84~9Uq&UZ0GX&)}B1!jo0NCry1k_-O=Z1Zs`!`AAPS?)%dh385d1m-tT9c z#pR{eS|)vq(dcbTeaWzC{8|6;*}!d!BmBU&<)3a?*uKD|(!~1XT!YqJ=a^Z2e!utC zt%cF90k$KLDehkgV(@jP`7{qxKAJ#iG8?Y+a1~Opa=ZdDF&SrRS6D}i#}h|!bZ1%=|roR`sNn!??5=a zJHXj9pmth2)%BqJ{NrAqN9(;b>vo*eSLZj>Z&hRiVc%c!K7wNI39uXqJEsSZATHpl z=k&mE;tLt%l=a^=_IBI z^Pj=crygJNzaLHYObpn}Aeyn#-sAui1|d{{Ha4J~$Wl{YQv&w07$c|~(*r)HP&RJ^ z@W{#=4VCadAR(KwSmWOjM>*HGm+BMUS|Ek(ZbX9?4$~B;4Q|r(jt0Ka6elX}MeS}l z3mGPAcV`eV6A96#h9Z;_tx6zi`cMvsX^NACH)-p!n7k3qzLH=sMsbz`!fA>V`3W># ztAHY!_MkgbmIiRgbECN3h4m4*8tA0a4JgL>Fhop35d{vCc30L-Rg(fDB&ZBfeZ$RI zG;+X#b-<=kkrG!$<%pO*Dm|cRhi3}hvDrzBjw$=YS6Xymxk>_#QaXnEjszlTG*xv= z28oE6yHzewENypX4p0sPph1wv2q+rZXd|&44My0d?GnQ`+Ip}?9~@*Ta#n8@Lxc=N z4N&qVkVvD;>P```W!OtxmXOo*fe5EH&}|oP{JllHP1CeU;2Ul1tiC7)M-tIy6VzbClKqH0Yxq0~7+*KzdE2lQv%5fQT(2H|svA>v3Ae0f8wXHuCG8fmK)(iwOf0}*i?7dcgU zhgXWhUXAo05riYft<*Es_%Tq3p@l4#<>7n&aCg1rundqbEG)d%Y#fo4OXkY>+tfJBziaN#gbYq@Zf zrtEt7LYs|+Uh6P+9|%K2oWoYHLn&@KpxHv4i$`|N2Z7zWi6^^GKfXpVdQW$oDV_JP z{k{Q)Gfwoawf%VWxP~d}I@@*f1?FgfNhHKKO>dm6}#<03)dQ4}`+hDB#gd~V*3llEpctik~z6LSC~?x_`nn zmFE%550@9N(WoWoJItF`pY^}C(CFR_hgn4KBkQ<;Ve!j6``FCAd_mnRX}%bGY|**O z%Y9AXPj^mSoV~%uI`G@H=N@}32VdN$x-LG`5qVsFzWhp&Mcs_>B%ka=tIl9aoL!&2 z79TIJmnX`+I;@+1wl`dhw^fI@#pr%QY-`9kE(IQG>L6|o>Dw@anaY?Y#h;Yh$FAsO!C1pN^<5;`Y}Y{? z+0}9NCe`=)j2Wp{XO3pgiTOAt*YmWV-$^%N%;w^Yja2`RJDu11Kb(0lC3ePr{m(J2 z%!&Yy9(=5@~tudEssL5CV zbawk^#XZbyoaks`KI!?G+wSkz{0={sFUZ^Oaw&;gf5pGEF(_f$-7Mn?ZpQJGnWNXa z*ZgceqUGD}&cAFyaWC(lm$QoFW> z9G|v5qiWn^gUT6}Lyvk6|2E?2Q~s2L@$J7U`>P9X&kfC;HZ$YMxFN>J;-!(F-PcV2 zWZ!7dTYd0-`htdAh}F|CXR1cE8S!UMA7bWV@Y(NhE6Kl(=WcG`z09X?d!VKYt*Defg3#Ay$>nRF%agU5`QgLj4)eqXwOVeMJ|TS zlycwug?G!zN!$F2JtjUY+qu~Iy=0yPD;Ml+ zYpT03;q1Ee&F>f0`NTaN%gu3UU(@MM;%VRiJS>lrb{;UPuXj0Bc;Vl@#J~Qro5%i{ z^`h+|pO=#)zAsxED_Z4UGatEe{`AEQUiZ%YQ^ecHubq?ETF`Cwq-|$=G`RmRFUx*u zX>u#*bkJq#{T9MbW4*`jnA6eSy;ssiL(ksspUS&%Pl$atOHM7mbgu+LL66-S_h;^Q z_mse|zmn7EI2)y&Aa}`K3y-mr}b!)P(D#T?Wj}4poMPH zt-5+SI^0Mku4VtZBe&(;m|D84wbS_S6aJerL*fyhGWucHsgg(69$15S#NWGR+kPv$ zv|HO*J8eNXTRk|_Zuhw4iII~=NkkE6N6z$N zL~)lA@aDU2blCRL@@#jyn_bY5S7SYQ|9hhQ9?@(qzi zYwsl4X58uibWm?{?A>X@Bg-Ai;+_q>--)c9a?%$TTyJz3_SG1D-1YYJW0y;=RKDmV zj@>ppWKip-1@YW~nD%8=t&e>$G%5ak6CJx#GVz&tP}!J)bN=?pbD5uzHDIgv$R8Ju z2=KAH;a_k!d?koZwL1CPrdJD(x4j?rx@&kue9t5e6Wx2Kd3%0LIRe`rd21j1 z9&bJ0pu6zz;`LME4@Q4%8Wk8fGWm_K*7MZ(0lmk!>GZaEZ(qE50a$zDy+I7CFvMIb zKbL5)e^B*3eDszv`g!4Dz#?@s5v z=S^(ab7mXAC-?RQ;|6GETZ4JPtplg4&+oYJ_xDdUim#c`!Hevwop7N?UynJD&hA`6 zhCq4jrG)#p|16IUi!Yk}$zxvkpmFIvU0dyY^kGK>x&HR3lg%#WJQ&)<5bGBEH%ZYV zyq7v|Xb-9TkMb|MWpv2BJ*SRbFqG`TG7?0wx8_E=H3^&_hxzVmKE2#CBBz#}c=x}P z^DfUSEf&R%C1W?wDtBucI5@%5eNc1H`#w1ZjB`nR@trFp9=wy(#}y_7&agGB3mTi? z*Dc*WyCf;MCBAacjlqI1Fo(Pc-i6kIn;0)sScv8gvYNr&3PEOqqdhOD!rBQ)`0iX@ z2yaCUh3k3M4?h4ZteoHB*-sD(oHyP?;BI?CzJu)>yo9;L1YXwS_zGT5grz-R9)jf& zkg%EN&R(cK0em}o`Ui!(?E`uM9=H$af6z6kf_W^yf|oR`q4N@UupZ>iT=6@+*=Nr7 zZQqSSm|zx%2ONO%^9&xxOV~EKjF*|4V{U`r0wJiS@GpERxE{D31j$l( z07xtfk3D!J#a8_HMn-4bgSj`Ny4$=S-^lK4>l}FFaH#F@!5a&D+T5pjJeOb{@t?Ci z6j%$zrr930O|v~iPS~C%ghlkW%`Oi;)gSp>e}_%jwvRy4X^SI+T?#tv?9!`jm8O}> z(B@*t5h)A8zqVHIsw|l~bjsJOR$ctR!7H5xT-;N_X*+nV5A{%4uOBlGJ-5QCs#dMM zvwqs?S?eAg(cb&AdFhbIdB@Ypmn}}Lp*ywDClB-vTex%`_6%3u=sDIht!GhDVtPz#LnlBU}d1;aYD`0(o2p$4_iG=I;7<5-E;pK-pgrncQ$wc0-RTIiw{ ziVqVn*Kq4IhM**9qiv^RDnq@L{c&AZ-z6YuLYG;WlJ3rHI`N(F^XkPHoU&&T%@NDn ziGHgu8PF-dThU;B4TCBH_UTkb{iZVZE;;w^=~YpXU)=cUC9US0V#$C87vGPYZ$uP^ zp%9<<*c3rIg|q+?1$#L34uH4d8FxV1^*t6V_^Pryt$L3w!!U3AhSl$}ztQOB1Gt_7 zxe@g%eTQup-nH~cHb6rKYSvx{;AV{J+uCs3^Z9Y1%WSV+#&pA+4$*kVc9oa)3x~IS z6%#Ifgs(}Bm4j#L^j9$vO(mu#u=ZA{{ANmmH1CD4Vg^eG7#v_m6I_SBfq_Fz)-YMB z+86KtI%b&DYr1*Ht_+FxH-l%qhPKWc-=uw1o-^Y&U&lm9bF)^YKT=&X;~sB7YtXz= z#A`SbpADL%C#2H`=fB;6oeDHKy#(8#)8iQEKV^T)egi9-$8{m?w4+q4%~HX z-a%VYrYnl|N^gAV`$mF_F@CI+Y?q!?O5;_t0)@ZA&G%!nOMVZ4EQt z*7UEPv+}!G~OMw|2 z9$O5B+6D^m_zCbpomRgHTy{Reh<-E2G!wx6>By&;;o_03($E~Q{}eMq5>37^EP&7~ zpJ51A!$xf{T=zL*9m7)H{~ z@Ubjj479{fR`OW%9q-oU^rbMtv2koJYN+Pg$>6Yt7As~*Cp-CZokH)#`m{H(A{I)t~B<%UdgKA<% z2{>3u;^j?nUf|^n7I&?UF@kQ(t&M^EDALyaS4^`s8?h%g0%A4ej|*d$iWXQY1|PFG zc8Op&Z7bdzn>k6aiNT|Uac3p1v`w~Wfz!Gu?yP$|RZ99`Q}M1-M|4Ngfvr0ZKy)Wj z++l}~RwDg~sws|(cZPc+Ik36`Ea1|J@J z)Or80+>W@vL)=mKF_vn>P5RLuO;N$&5xa(PtKgP!h$|AUW4|%@UTNHUQ6JI>!Ezkq zDxCPe?_*lVUBpJ%nzxF(GtRbRT+DRLaT!yf2;bf{b&#!ed`u@yYEw4ZemkQ|Z)=zk z(-Cv{q-~kLY5PE1*GYV#ueFQ(aE9Gvi<=CEj$L)&(J`q`jL*3h+@`6k=3q!=GeywNH!53)U* z6Vn9~{xY|;iIZcxV&V+;j5Wd*m;x+JT2_#@N%P=|hDmH&=Euz6WHScDZpEb4*5XuA z>UoQ;bx`bK%yAQUBXfc#-x6lK-#hjwCi!RXW&Q$j??PgaW8%}KD}=<035&I1l9iU> z`n9-C+Bdccb9m17*6zw`ZM)D9>WI(L=SpG8AaH|A@JaKu)lwQ6uT8+Z=H4&yFT9@b)g7z zS!l0|F2ZhmV9o7Ul8Ug`LIC?xim*H0_Hlkkv8xm9MAZ>&_9XtnkAFKJEk&Cb!=eCM z0e@ZW?`no&JH=QtyYA00>|_`G`7S?^{nNAvjF9r%jA*+uIRc}G`;B3Axyz3Xx!B|K z)MK)pTUb}RmU)^lJ-Gkyrow=o#XI8j2W6jR$3XJ#YR(?FI|4f^5-fxa3;QA439z|fV=n63@;h|CUPedO)0k2LlSP32% zHQxy@_WS2#*LH+xTcWAW(GiP}p|@d=@vy2suN@90t-%Fw7pzhefi^-k0-wSe_r}B{ASti)gMs=fhI;>uk%Do!_y{#}u{ODr&c9E1_&*3vK0q4r>1Wy7$!W$M5{^C;kP?%`F1Rl1R z%ZEUiiMf}{hrwIk4iJJ|27hWzmviNb7c$#Unk+MoHAH&F~bQ<~_=yMQ2UmBmNwa#Dlz}+Xcb7Ji+1(`9^Ur z3*YJq7N;%KboforvN6IieGj~C>#`W(Gc$%S1R%c2wALozCjg4tn>K@Iew(sr@g2qw z3@5h%@~&x#5#I@<#2xaaJtFZMz@lpNH8URR1?+Gp*H{ZX+5wB+Tkqkpz6WdubH}tC zoJHD}MGN1V6YyV_|FR~9RJW}ZXfr+8{16@)vs z2P(-7QB9_{2P%n3z;^)!PX1l++V;@G4;-fTqrBmmI$7Lti#JdX#6b)G3Mf$zJeS2o zJHU|qD3-v}I+TqOKnR_?AVpd9arjr>v1|-nhNT^$mox@E|IPpb;qP&mPGGWu`3h@L zfCNSw-vd%u2`eAJI+eu=ZZi0&&QP~0cqEp^^C53K1FPcj&@N?h0)n$;bSazO8!sv? zT_wDy?~eBP7*#f55ixUmrjPD z0fQ?_9WgA%gk%r-Ed3P!^OfbTs$ru`EaT5H+W;N9{F&ww2V8e zZK?l{!{3a2xJd9A0@93n_>|vj6FmCiGC?i;s~r8X+mv1AVHKEoJ9AYNf|C&y9|g-8 zTt2*Fm4smPP5*FP!|;lJ2{zY9Wiv793>H&)WPH`)YaW*=1sf^6;c;1}Xa=q(Z0gFg z{V}%LY}o|N{VdVVIvM|Ft^-Gm-5K%PBOHF2E90a%dC;)ipaI7lRK~c-xkHv?>ha1` zS#ZHyW|whJ*YUsFA6X*9KL$UQ4HhNrJX1>68C5U+JlGDD11&Ve7wezu!KKwHw=7${ zf^xPDzz^h>JcVTjdrieN z_{PAqYbz>+tJrqj;Mr6{;Qh#oAC5mD zpX+Y(4XY;}LRI{fKBA6W1;lmmI-@IoIMi`tsR`6jygO4-E&j;9W;)wCu@$wLs55tq z#oM8Z8p%Fp6%Ft7t+Okt#3|f;8Up&{RMd(GbC;MN;FncVD=cOP;tqKL{=r%pmS0gT z>4^q1S_W^(hx!y7#Lyi6dq+i$Xg+J?Y*jleT!+~P_?9P(wLPCuwtbY%-Bh|>;Qg3+ zPZGGmx)dCpS8eWi`jCz|FGZnpk->1wRwGkP?B-{`FK*7#`q8^ef4Y;I1goYRbeC^2`i>>+J8 ziPCwPk1wkxW>}Y4f8nKMA>?>_ZP~0}ml-DemztY8Bx8YUxc(h(n?#ka!rE=;&JtOs zp}HpOXR1TW*~%Ivp1D#(7%Hu27~3nlbPd*VDa7ec)3nSSsDjCPZ47LHI!Ml^94Q_7 zj?_VhAKQAibP47?k$FQQN=@w~*W$g*JMkOG zfLCO(^{9n32b=$yJ#jAz0&JbCFaIL7(nkmp`Gdv}|0(xzGFcyMC2EZpVoN^%Q?B)m zLJm}=Wv%JE5jV9o_cBqCo?=VpXVqVb+Stt;gTE(sk{tCIK9K%GTf13)=SVe$s~gHs z^{8bxkq4|xEceXkP3sKLG`Xr8nOg>%u}nc^*>#VMSIyqm0{jb!;Vb`@zn1E#dc2aD z%UEVsTGW5 zQgIGzna8D5_11;vcBWvH0&-K?NO0`lE3LSSxgO^hF}tawFl>eq{orGvgw$D8V%rwL<`UhtbXVN57p}_wQGsOShiQrUWcf_Wknl?U6r3 zP|^EOcmBR=80Q||wOj1dIZZ?TK0P=(9GReAU~nK?aNyYC4D9}A|$aGC7`BUG03usiucL?*A_CeW^matfSM3|th|f09_r5ct`8+hp_ye)wgLpo1`| zxx4R|i3{hg?3w>^(XnaFfa06qrq@?DIo@)KZ{~!wx#hj)z8rDrC6{nM^2fp2J9Q`A z-uVxiwr{~!KgSpG`v`941^VNIs#{ImTB(DaW_l!b?^IJ6UGS8gd--kMv~3NHa9FE( ze$uJ!lbUpJEqh+bv8r>z-wMeBL6jTT>sR8QB=7E~7mC7{R^!=OHEN6&t!n8L;55U1 zu2-j*CCT~!Smmug^}qg9V&IkO|6rypDXd*mDN(S8^1IIb+1ii}Uz2Nl{hR5Kyr@$^ zS^kcuRK%sEKb-|HL?>D<_wN!lOP5mD?(6L%`PZ51OZs|)kPxkHbtSNN+T>ZoJKTDp z-Qk25=0T=e2!n57&|!d)g0~#11E3X5=8!T!5}PSF4YO(h0=)Xt@jJ&n_Nkxwx0l1F zw(o{sT^Kd~xLAIUW>L@%{=~bZSs+Jx37Ee-bDl&r)HKYJ{_xBk7Qftith->xx!E*2 z3kDu-T9cOx_C3x2qieEG`n>hmVO0>OAnR{HaX9)4<(`6vkosUJwAdzv8n-K{QdHOW zx3cM|4kN>*ODyAtU>8mXp?E0w6y%X;0f7ItQ&86kb7}P7(|=Bg{&T0%YK} zVtnlB`mb$&eQOxhGNs4!DL%^|h0<@b_9dDsY~)w$cW^_m=EXhNPV2BNwD-f8%MLyy zNddFanj*+Cx`ES?{r|Ywfx}xH(ot!H`Mt!yYy^5wa?lM5$KcSz9Yt8 zN1A_%tFNp*BRSrw-NXrN7mhstb3@T+WZ2CQ_$=OeZ{Vx)n*KlMi$dEU8`W*Y<*EAm z09z|svE%QPKfmYyoF%^A@yh6~t34CL1==$-eQ^gW^QaO29_8TUy+0~vdHAG0nC#>h zX3>sePjmhebvMPYS{eIRE-jyR(B;Xs3br|3SF%ws=@-#tOsn?&r7NiU6Pn?d1UW;v z;Uz}*n)n~Z|3-Q}AAEb&+4-sNQI`VI*aA4C+d8l;6JQ|9o5JhnW{y=67oG z>CS;Y<#g1|(ptCb=e2vAFAf{I=*^1%I!E3VX1_KO7vq2T{v-R_zS;YL@|4)6qq?;# zuiV*!{(Ny!mE!li+CaxY{%2E`t~uK~r1I0wSj*0Xzo)~a3`Q1vZUu8wm zt_J+T>A-E(OX_Y_M>Z=D_&3#asj#>8S(kk>_L#lo)61XAKc!9k`AnYNd!=>Iq<7_q z`qNjBZT#@Drb*o%=gnP$#`~}670!K3Kk}a3aJcoSH4PCpC88!BjwhtAy%;0?nRH}< zX~@21Z|BrE`I{`=)lL%=ydre;!&+7GA4DDwwqjfE zy1IJxxSE)|^3OoGHxrK(GTc7CrwN9J{ewQ-{~P&7<+8S`d0h3{?~!vpb~)G<1wy%} zmxWg3HG7uz%dHmBujPLlr?XkY!sKPQmn%&rdAGLSiy5~dx9<6yM^7i?cP`Y+k z{Jy&3$NC~2lm`kRHSk#gQC_vg>Ajbqe68zVGfX7wTpVAs+B7x{TV&g(M;-U`$Fkfy zAm8@1{V&hI8(m*^RE#WG;urV&@9q;-Bud~7+WaEuy*HmS|Bn3On#}V&F>=|O_7i_L z8FtDGZG&>pw%_q%r2DPTU#`?#ZraR$^yE_;^Cn%Zes`#^xg|OT7OlKySWUYlp1l0t zP<7L#tM8|TJO2~KAFNt=c$@`2=evj=Mb_lIJvmUfs&=_!TqjlZkTpXmw8CP}^|BPP zR7ICxpMPDIhIKT=^j#M@x$<9`&CN>f7*o;f=fc|k&W0{q#!Oo^YJ5B$<(Cn$?Y^+!5c*Di0C}^WQ#}a7i$K)Ei{0=qz>( z+xo%o-`#)h{FmVoG|Fk+v>7*~Z!To9OX&K$!n()Ra`7#1zsT6t=cmggea_$E?q#pO z{j+x4Z)eeH?~-9JmIO^Z?G$yXo#^i)!)m%?=`4B`-~3Uv^gn5s5x=Zs^RuNy#M=5ZJ{u` z{fIG<|2sL!{+l@F&D87&e3pRCsLgFMvc22rpfzJBG_U`3vM-816p85spK0_QfQQ#p zqW#W$&zIKwH96w8yhq^JX0Q&3|2%#aR_ELfgF&0A%#os|Z=TgYXcFMLG*Fo+nSZ1A z?6>5>rf4XXk8G35X^vIBYl-Px4W0o(qbEkp@a-k8G!}Rx1m$y`mcJTwdBA}I+zSSk z{4Wyo6Aj@Yo2+16BsLujL$g5665NBFfB*tSX(UUd9{~LX>#eBcdf)_*uRQ_4O!$9! z0A!%x1B;#m@Dnz$?NGA~{3RNKhJu_SQc#!RRtGp;a2nE80SFMhqEWy`9@LR&W+S)* ziH-oA!CIr(O_7+ts0%vCpsfJ?M3Y&_j=P_S!a&p?JpnWWf|;N}ns8&9M>g$JgV?Wg9=9srVo?5RktphgwXdC5_~L9P*1c zl8AwuZI8sJiVL_yW)aE)>@U~`Y25$>2$r+x0}rrR)Fzcb zm5yjMF9kC!Xd{4`f=UWK0uUgqq$S8XEfO+PHe=!3016abgrvj(W(pX{76l+c@E5Y) z0+=r90QpSN)O3D47zZ!KnT_y0pJcGO5ems7=p0}Gq<(CZ!8b=UC>nsD5Mwa30g%6N zBHIiVG@^k-Z}gByqPc7;gPdf1(|wuQRx|)$fI!QkMUC7;Y8#HIMi@xkw4m!e6b`2x z&@Vu<1eX~!RnAu~etBCOsd^LSOx_RBPc)mpY(Yd)ogW@M@OFhBS z%SO1DW*}9ymS-23-y2Z`zyQHp2Cd=&7Kw5|24XGIJzk0&>9-UT>3EyhED8kx3nRoQ zD@x{}upcErCP4n;!E~Il1-iszECT%mIZHI$I?;?K>EX95x@=A3&~bo%q9SuHi{3TD zJ%pS_tqnXIZn9X>C>{zOs06eQkiV$JvK5}^jbw>A8kIMaHuHaGBsKCwn$4kp0Q^M9 zxDPa1z(XO}c36hC1Y z)f$}u)JrnhI#$0LM;~}vkc^|&W&o1QETz9`K+(J+qG4JVZRDX)O}0S=fM#J`k)s9b zi+6L`L|fFK$C4`g3#89Ri$L)cC0SD}h~lAe7~_bp0rD4(BBsM9Ok;T{Q-!0RRwx%Q zCxZ3SXd2*N5)O8I-ei#)l%68evI6cc9!fGfWVv8PANUHwAi6thgYyl(GR@SXXn=mA zC|m*09UcnrnL|+lUoO#`Zfnl5s1lT(A`NxPikt}Ecmnm;ga+_XsKf`Lg@F7;QOs%r zQH|vfmAA)c8J}5yhCip#t4jX}m3LjefqQ!v1gaPCb zl*c3SA$*WA7(HoZe^Omhs|a94Q}FWyiUSxb8bd>VW;wt?BUjp3o> z6myS+461Taf?*Nks_8q9&NLdew#>j$4bMwAaO2Ejx@US6G=f*-3B4{u2lJAPcvU#r z;D8XIFi8N@-T00}k9bG{-bOUuWHckck^B%9mj5h288i=+V99#xR%<1PI9?Gm){Dj_s1$IBq@I0m zSq*6+NAXrIxf$jy78C_as8~k~B_q)`z#-y1_LzAPvH=bg!L}YV`o^1xdf^`kmm(r|@UO!z9tfp;>^#gySsX2I}Gy-sl zWRm%@eintcf)XnFhLdnR@ldiJLh~0g=v$+bXNuJuSk!YG-`9ETD5E<{0vskv zn8a%G)=>m$aQ~VLU`S4JZh#xZ66DSRoVDUlj804Tn0XR(fgzbpF^GN)b-E53Q zy=L*fZDnuke;V4O6kZc2k^8kH5eqm>a?IE-tAs!mpahE>sOl^TjXs;N9%sF4=!8ZC z?(NWyZfd##Il)sw3lZ-mMrhij6TFoqhx%t(PM|7Kf+geVvBv8LrII}t*c zf)XrQLPYDwnGnY-(gwVVGF9=$f+~1b+=T9GX^Wc8;hSzjEY`Z9k$}U*a}1GL0+h=0 zu@LY$AK?#-ypr(4yOn8;4;#G;9TCPpZLVj~cU`lkh%Lr_g^A++(=55suRsXEc zsD;l6EXCP_Xs%kTIwU`;>Wk8O#^t2-n)0ozm3)0>1FSy)mFzOw;-S^3l2l9d^&Cp> z3Y3$J(W0tTPEcfNPzez8oCEbHSqEjVsx(uIhIfO8oNj9(7>IdJ+1fPu z8pSf@GCk_t9SFx8`m)R}ncWq^$N+kZiz8E{k}5hwu!TYk68J(t&NJ~vvaqyy>7Mf8 zXeBTyF6q=_O;F}KrJoYE&cEc1T%K7Y)SuJ_Ywr@@>va!mfU})7{kR3`fl78!Sv@n$u`7R?D$TO>~@R_8_&(J8BThI!ga?Z2R z%6)R5w8#&W0(_EIjE3|G zv<;XPXK(hVx}BoC@|!XYeFbK|i=);{xn9*$aXj-ei{^yz)z0Zkl$30wtf#g;x(7^( z%Twd0tUj4TxeviVjw>~? zQA$LjS3o7Z3^rBBuPR4EIJoa7G@&m~72~bcA(}+xJkblovBI zl$`Rj5k(E;sl#}B)-%;}S(03-L&qAaQqns!P5DLDRt~G`-3IaFysWNMQd#E}`!&eQ z6D|)muN5(>Ah{e8Lm}y4zNPot_lif#or();xINbMlyjbXkNh5lOp?euqqo4MxUAN< zQn;&}vfR}F!%^Z8-YDHvtqfI6R_U`6&=p`(oM)P48A3&};+X=RMTYX#aP2(#JLQ%1 z)2cN1Km{t-Fq|cJ&WX`pq)<+^S&c)xXRBTA^E<2o+PonccF)rmyaaNCvl5|qF-GCMq@mA-p zPn5+O`(#1tw>WBf6e#D;`V;AOsohoUje+PiFs#c#%Vhb-?T6Dcl^P40cMOaiMcNSA zv$Qb^A!=%i#E{Eyx-9EbMiW_XX1W<22a0nZXz-N9rU~VPv;vfLoNs3rC(tmm&+-|n z+j``5g71F@k(@bIc1`Y@^#T6dH&R;TPsPQIm-061+3+e+%ny7n`!6d%mL>0`dapy0 zlYGV1c%{-szC_`ewb_ggHd6OZqm?f*W~p3tGe|V`6mM0j+a_-*_f~o7{&Glkns3XI zF=xG(U6Mzt>rH4cP@Hp?MWzhT$dl!%nxlzl;BcH-Jt@azFBBuR9nn8vSeN(Ik<8y2 zNPbymH=x~izHtTBLfu>0OI47$&VEWMoPhd?nSG@BLCiV<+VYk@&7(YRmcI{7xmK=pAPB95e^1|&_C~(XfU1DXb{wgDt8h|=WcnfYQY4n+)J!k&K0g7`eHT@?alCei2$((6M#0{Q$WB4Uk%HAj*XTftP;wFD=ovFtV z(`jjHsa&H)AAsUqG`ekRvr}E6rx=M{?$XwYrmD#5Teea`lt zGJ6)xkG%nkah`(5L!Q@=w2N{Fq`4D`6`-?UA~DM8m1Sy1VJen&%z~1?Mq*`7{mp-6 z$J4yCuHz{38&6c~Md_V0tQrN0e7^GpWzxu>W_(hwfT^q>k=O&r8&sw0TH5~$KI{y=DI6gF&%XVj6$Qpohs=&ap(0EfOmbvR3P--==TMbXso5|Yh z{7_O&Bv$Hlm%5}poaUwcW<=q&e3u)^fy%Vh|EY3d%Ds*!w75(@Ewy!49>M+Mdzh?o zO5@VEYFnabpqD$nG(F0=mp)N@fI??~^9HvK4jF&bD0K^j>iI4{TYtg%2vnq-(AGbE zi@}T`t336Y?5Y9H{L2%st)2?!)ClD=3mVeE6SRI<+Q+p2vMvzF`yWrl8f!Dyv>%yY z2-MI>ECbJdDm_sTQBR+az#cf2o9r3iw)a-qtmqUr0&2iZPWqg*_G%f07y(!~I^io6 zv0uO{ld5 z2p0^onPI8!8Cng@9@X)b(;%v8=BU(FvMeJibKtvmCRlmb)I^olijGNnqKmmAeR1jv zjgCTAM}8cw=r8b6(N#VKt#;zavEA}nc47NMl`|Ue%#Y)bu3cK|^aDD6*3yM74^t7~rx@-=WxB?-KFb2uIWYq?Auvufd zb(CU3T770Yf%I-X@tJIv<(H9|HJv~!n)5^im7e)HEhaM+)(hQ%a2!Ic%c{t@qw+(6 zEk@uRet)S3JX;vwgDIV!R zapDU)3SKCzLyGW$tK7x8;X-i@-8NWY5*T(Ra|xoji!L%)|0p%`ys=w1acx zT*rxYmQ+p_WE_SLwI6|%I*vBwW{{~PHG`4Po3A1@Es+JwCm7aoXhjG9w3bCvt>8X0=zjnQ3GOrY zA^>Omz(Uc@DUaln(?NC(G-yVg$}F> zvH-pp)N7jR>BzS>0;y2z^zIphX)tgbow3tEVD z2P4-mF~G`LzZQJevt+$?s=f}^KzP;R9@WX1Z5V_KK?{*Sqmp%xOn+GPrqQ-1&FN>G z>~MBkf~|NA>#Gk&lL3cGPSLK$A68@pB~*;KpC(Uqqp@HgBQ&okkfarVtQVOJ<|PaY z=N0iB?jki9Z2;UCi?<&FnG}e{qZT88kPJo_DY%{qpoB`6KsA_g&TLfH6GHPo23>4a zJn^6K4UQTbl^<4D<0%^Ti{e`kw)pDDpp}3_9PG?&6Q}Qq3VBWXhkay9);*)p8&HF# zgP3eXC*wT|bsWj7bqx3vX~At`YNJXsOAK=D4v75Is5WO}bsN+mfN;SeeYrSqhafW_6*fWpK+sDg|`wT-L`=YV?0@IU^+XfZGOpZZP!d$ED`@nbk_ zxBzYkM8xqw{?_Oo$o_D@ILGs*a05jF=qJ3%grQVGePISa8lB`3fA3ZCg|GtXpTO6W zqWO)oCCUN08gAZJV|jj*Js#wNR`#+!2z%5P^FW8jAuL5uL88{<5w-v-rh-fnw#DPn zdq8s~N9ZeD9gD_IK-e4yBNNU&fR)>mpv@I#F%GEHM1So6v^zK9iKwkh73OMo^Ps`#Y)w zFdGZ8Pq~G#)I=-453O){?&K6yxW-%zz7fK}c#C3WShxUUqTM`e0zXNXvJ)jY3B;AirVCJ%DE2uLi zJGlKs3WHwqW#UU*AG#kJ-4g~O9mu(}FRkk-bQsh*qL8mxGOuxFay!@ zlR20{@{kP5JHjH#sT@q*^rodXlbD-D2JKN5L?Q&7%w?Z-QhxvJo%EeO;9n7RItR;e ziDQ&|3Qa%gWn7j8odrtm(u&N@{b6la_$22jgA&g`Kdy7x7C8%Z3aoc`8`#GT`oxn? zHCz(Ap4pvuhDDq0IhfYT&Iac0-z8ywv#8}+uyDW0wcFvg<7Up1-7^@nAh|Gyv+sq1 zmKZkLe(qcjX2}#>zU;=o<%8kp#^w?l~NPI5V1(UjPv4pGu zya;9{q969}HrcGpRb+)mDZaWdaHCPZ%& zb1{S9EN$O7h3~{U95Dr-a=o(q>;-R!skxX&0H?0sH0V~eiak!Dn*f#4FU+JIA7VR> zrcZ~Cr8Zm!TYKKH=m)4umqp}W?jK&38T2F?P`MMuWLwuLLEhvWqo-3ChTnu5Dn zlgwN7tt~_7Jq(&NI~PlHJr66os|;Rhcgsg}h5`KmGQ+(kVhx}5fu;!UCj)8z!QF!y zg``|;d(#l~!c<`%2H* zq~u&I)x8gQm-SL`LL{K(Z95&}h; zpN}StK3h*dGd?0iO{>8r21vO}67!0hX6;HYgzUR$`U0Swg^ZqI$om#&Iuv~dM&a^> z8bRHqXX7)dVis**2u4mR^myDa`#n(sn=%*i*S{I(m2)m<5o6B=b#p6w!#oaK{NEngfeWXg%Vv+k($l`>1RVd}$o#aGu2N{R{J2q0c!ScFE~K_5tg8 zP`|5?K&Ns!?0mCdRQ{2mLaos~?|i{>CID&jIP9FqIj*Qceq<;;0(Cs_hIZn`Ai=BJSI%G`Tz6A;E;4U$-bQW_wU0v` z70`m)X?DlXC%G%~*XBCG-BbmB97-4g=4x-IVzB!n!Cuz>O2c3k0{CxqTF+qBm_W(d zi;N7G>4LfIh9U;D4@E3i-qB7aWMe*#UFLA2>|vY(Wz99@KFDdt+#s{}jL7|M_1x{W zBaME$>)GxW=*5(5>{sv?c4_Vk#xeUBlVMy=+{|r4Z8nW1_YrMKH}(k05hCg$kw`gm zqnUg<0{vzdFvw+EHdfX9FnCSTIWpLFIGvnLMbTEvG|Ouyp87&HW&hwysqpNB)@<{l z{J{LJ=<&Anz&&Iy?dCN`XJaY%+rswFWdANzukxq0Hm2NeWz3?(Jls<#+q%x^3 zL?bHvt8rz%JJJ&Km3Ztmfe&|AP&%DiPpq( zM#jFdy3%=he@JKAEhm~T0@s3>Fy6jG=6>#)9q-w#-2R;Qw3qolgE3Eu)SOTv30JU} z$mUFM0kb3LTK2iTi8}=-Z&o(;dB6g$Oa7xAAL>H3GaJr^BTwUcd`MoH zH6H)NO(L2x9%u^LgqfPXhl$DVox2QQO771~+?BBdUVpC7&c;3kwc4T+VuedC1OY zhC;N-ID7!}gxkj5q%D@`c*mU=2zQH1L0yiN?2DSsg-aR~#VT@W@(3wndRblQam)wn zPrNU^l++NZY$!RN@TH@yZSqrgIg^e#EpzkWNuHdI)%f*i)2Ok#U*|Ym`mz19EtHu3 z%Ow#O>%{D1c`xY?)Yt5O%tltWdvQ)Fg{G!Jm9BQqEw`F^PG8EGanr~FY#G;t{$(CT zVQ3Z;!-5|kwZh#O%MC=^_D_F31MJX2S4SVm1 zis;u~PzdRDl1#Ry&=CQN8WlCz1r<@T_uji8_V>hl@ALfLCx7I$IWs#uJ3BKwb3WE^ z`xRzqy2Q4LGH_>E4KtnjP9vIOmDW>qgmqFH;i8vX2`?h-3D@3wHe;Gqhl=n ztVut>2Dpe7R-z^0Lvnl5(sG;FB3$j`-6d;c1DPW`Z*gPtCt7FgA9McMOIV@xYvvWYqpQzWE8#%|Ej1suHOjb#*D(Fl5^bG0Ls|&; zQitsOvIu$$9K^5hnz;=CkcdEz>CTO_H??}xgDgWc2AU6&WPew$0`~)6%pP>^sv2I+0US59r@qM^~L>_oa3*vsIb#Im5U( z>md6}+LL{g{we(gy~5nX+9v%klSB1Q>y&lWs^cDKW~5)?EJIS@aSU9|4X_ev`{|a} zeUNQkt1kTj*NA+>DC`@u+NaHBU9-gQA~)7@r5P79ywmmRhisG6*DyxAFt?h#SI&SmM9B(yP<85!!%QGb0XjhuVZRRhuT(%!dU&1`K&da6K zr!cM(sgr#KGnV6l03x&=4>ZnVgKYQA zHQW!|I^$`|GEHSA{&ewzjbI7vA5u(ivR`Dg^*c>sQ;qJjp#gQ7w3(XGAMsb+Pja%= z!xF_zqbwBye&RH@w za8FuglKs+T>4&LudI*P^aHAaMQlpp^wqe!-#xT;?bzJ-J0dlboxW3i_bbs;;M3RZ3 zW38UHU@Wv0TM=3CQs-_xCN`JL$n>#|X9hB5>?bPAw4S1=VeCD7JX4qTu*Q*fT)xPC zYnlWz>FgNl8YyL^Oq@-Wv6X$wdRlAXt#5$qZd=>ZH;u^}4UfVl>nl2iDd9S@Vf1&Z z9o@x}Y$cg+8*Llnnq+kMD8WN5eC7++gr1F4m?~=^6GlFOvyXA?6Z;!xqdmk%nO&Pr z?q(JEi__7K?UU>;89x1ktL7eK#ER3$Fn(-w#ySo@jlpSa;!j{0H!HVK+F5fZd&gR0 z98TKOJsDq8O^v$k3~i1uoKy6 z>wg(JnT}kMbpmJkOuFyQYo^?4XNJ)Q%w!zKe21Z961SVJ$1P+c=pyzDUCVxM_xX(9 zjHLk$_a?Y4!_sO>K;EY}(!c3%w4h;4K@hdz<9lQmQ6X>HPY79UHb^}c?=%K&dNQ|$s}=Bf=ARFO*yS^ z()`&?beWY*&*m0zE`!DWq%@jO$1?Zq$LTQ2C(D_!i*<3`xf7i0h}BB?6ZKbe-5Ile zxh>1SJ?p%+o{dT$;(B1S5_JjBEczVl`f9hrp-bL1&NVQ@>YjF8^!ooFALvBK`> zI=RzEC_D+FYh0?0XhrxH(Sg<%>Cf2ev>mqjtZS>p21WC~MfXVWmVJ}4Srss6{K2^x zse3M1XBz#=x+SfSRb%U5AIOEdTrwLJH^9k!O+S$J9tNjP(tBDwtsyp(wQ1T^+l!2? z*@xi$Ah$uC5}qzEr42%N5&d1!Y8%WIdA~SUoW|y!NABlbTCI&}Mi4_>yLDhiKzJ8V zCvVBaX-gu2hlc=TaDV*6V%{1hPF(r$pvO+OAMU&gH;qjem>J%?|u<7rC zS^f+G;DYRI|J8!`=1bPgIV*m|Pac={wvEB(=lgFU z>fy)*{{MO2G@iux$O8W*b%MyN`_G(7-50rMdsenB5_ek&>LAM@BhFpuzm7MX#(|6c z*LnDH%`jdBDy(<1*nhGAI-)HWFZTbB807r9*#B9mb9_gCXffY7Z0_uz?a`1LizB=E zM|$pKuK}=p7ys7;;ruVmU(w0=`9mFu9Tdi1lDiBc8RMOMKGnHQG`GO!l|J$i=|k~6 zS#!n3l%%9}spnKRiYdx)On#}eoZr>#GQMJ+g0FSP6AiC%#|=o8Ep5Bge`lASM9K@< zOzCLn%Bni0M6-NTBg0NZmiDG}WlECxnB=BxlvMMp(@zf z`g@&=M5A0yW3@ZS`C;m&NDmtKkHNw9=+J{&Rf6gZ0O=V)|BA42OU*=>1JT`hj3aWb)P%VI;XR1d{i=bCA5 z%Lhz-*>IWO>>M`3ZCRx{CKVf;&1Sh7ZxkdupaUc@ce1y5kgT2)8+-S7FCJ34+AKilg67_Vu?BMWOIN{KOvtwe0Fl|EkGd{Mwv+#5<^bl=P^!Ff-!Q3FU{CkjR zI~a~3_4hztCWi{Y2NMI))$gr6>a(NJ_wPZx9V}|`BN%ER{6}lvZWb;25zN!GND6=X zEXo7b7Zlb#pX6ij9IuzXAN|jEa5DqAq^}ymqk?ZaA9ow-tXRv&3D@ z^`P&@^o7w9qJZ>dvKgr9V_=%Y^k8}D5ttUkOtzXc@`(ViI&2C%$QS~lGgmNcStCR> z^7>4lW(FA75UsqXFdJEs(MYuNKunO)Nd)o7)AiVOobf&p5F(~`v(LH9`-XqewTm3O zeSYPdOY_H#o*RBOXo$yuAHwdOI<8OuL-7Gpwk<)l;#=r5EMS+$K=?|2Q@S_1A7Y^b z4F_t71;0LSr&0FS9`XRP2sRzoZUnHm}wf{=e50NQTQxDrx%`miPj*SMv@maoix2Dk74 z`Y5-Pp&2~Hg9z*p$L@u3|Lc?a9&5YgjqJ3%!|D#xFOK-uXKZ8ZuQ#tAT%GG2!S!SA zGFS>Jy+%M#mnL|(2b6arH<782F98`^#onhIvHR?eN?!>4yDc5_W<|oPT~j-cc-iw< z{U<+iUVOSTZQl?sfdSywCZ6Es4BM9(jR$ywm-j4U+TpoCh7`j&wMJ~W^m`Ys)_&Y= z;rO(b(W?@t_>Cy-9#nV5_vmMI#g@H^Yzf;RXMs6i!7O4{Gx!2HFo_KQ2y`gR z3}O$$OyonwfqE4^4oqCLYEOKJNneLu?dn&jYt4qItIMAi)M93{&l%j;3kpNhPno`W zrWd$Oq@!6EprnF0bSM3piDKGh8?XB{s_H#<%7@i=dxzoS`F|Hjk&)|^`UbNtCj z&yJ6UjiAMMDND;;MvE8-m^%&Z`I+=z`V3$myIX1-xJ!K4-VT+sn|?`0vG;eEK1pxc za^QxU+QflNB;!gWYIo=$aD7?&!0%jc7DcxO(2Eyf?nTi8XiUD|Kt7?n!1aXz8Tx}h z3yQ|P_HC%0t`f~O{d z#R35&Jxk><&2dKo)UY?5&P-(Sco2umVbQ6W@z@{#c|^O95e*jZTU#|hbBr+D95~H` z{V?-xcFDoC0J<+s*svMw`M2me2!4Z)xLt0gf6~$T0k{mkMDv(k+%xBz8hiVrQBjL- zCH9-+99=wUc|bp2?)${s#mA1=S}}j=SAZDm14(bt_2~9^ln<1~Mt`8R98Lgnh>5vE z*S2~Why7k2I(=CFlIw|8vr0y78u+LA!dheAzq~o&=t}ECI5gS{JAH_jUL!4Q0UGg^ z+si4K*24hu4|oYp;9_V#-Q3c*B#BUVIX<#S-0(#2S*v3n_H#BV`yKW6*7akD1Fa1i zupcIbYl^Tea@TO25T4cbOag<|AoV)Ky@bG4dxhZqI_JSmVDNRfaSzKbhGp;%w@C&! zp6QBP`a%V?;nu;UV6&%}brrSgc4F+U_%W*+P0bi->{VQU>aRMlhE;xWEMNtUi^fZQ z!41q5nF<=q-LyZujaftEe4s;9nI%jt9hJWS;!6LL?j;j8t-7)b!qJXM?Xj@#xgYs2 zE?hoWq=Ui$YEQL0ZFA-$W21315frB$wA9*okO+!Xk9p6;(;G5-UHwphMX%YD;#cR! zKb#~Sez)tyI_GNW=QZWgg;n%hW(SQ^-AOCxC?*W&KvMo2x|m){;c^g%Ok^^ckMw_8 zb#J|G*sM>tDTaia;|SE?gu2lfSJVr z2DhE4eI4Rq*8xAT=~8AMqb@SNa|G87&!0OnanFMLV}B0a)+U~R?DOCU=_jd- z>r@{)p2o3Y&%a9zhIuXC47AsDXy*}_t@E!pa8X_GaUl6En69*y!Oz{+dznWRyat5+ zKtF)kVG!H93(%q2jGV4vKRP8fAKPgotP6J~`ppR*qYRI3b)EO(FJ}TFblB$KiFC-${5p^U|nq{VSX1{vGpf;LQt% zwp!28hv?6MQRPm$lfFX*;6sqq)0+4&3Am!%IERRrwkZ*qsQL5r++kkHSO|| zqL+-5xk%w<^`Qiv;H`R*#7Z~)m)*!-gz*5-q4BV=-G<(rvGiK=dX+s2C#+vJByQK_ z#Ur?G!~OgGu)VNd8edS!T%yY@6menVKDN z_iv*)y~L9>t4o)LPTVkD+2vL3IzQSzKT!TH?>!Sk&!(^x?D?Hp9{fufYzS_4 zu!~uUgFnzs?`ImY@QBR=IRWuuC`AjsE=z*1oM-|vl>BRzA@Kn=$Vs%4k1|&W+Mbc z+4^BeV7)=5v$GOxbEl5g4XxFBx0m0S9S^RYYMc3r9SJYcvu-z+StkrQ@msf>4{S>q zGh_e8a80*ZZ^ptlK5*h|b?X;{6X$(Tm^WwJn7Koi1QvO`|Fr$?ljG*JGprv2F%qYN zJ-;2h?B7_yO}~dhPd==-x&5?*-u@eVaG|4%abwfi4#a+`X*zCw_A?uqOfQ*^Y_j@R9nw-kwW2Cx@%u)IAmgI(BUUiH^f-xdE@Y zM_bEaoYnx6&1La@x8f=TEfc&A#1k6w`T?k(0{(cD8GObqZHE84rQ>kFM)21kuZ2JO zW{dM1LDDHu;qL!J76&&5V-cR&*zLk;guelf*TqS`ygw|8KRd$n8FPz62hR@kgwZ~W zc;|+B-l1l*X!N;Z9*3!+$arqJ#{f!%9-JHQ8B4CGQD|utzZKWZe1<~nfNaV3H-9G4 zvC=57MNA+bfxOG2VFdNTc+HF^mPPSf(?1Na&4>XqoGLaPGNb2ZQC_j+Rx}EQosZ^Y z^L;&QMw`z^@w2c%f6|Oj0Xf~YQTNh}{4PZCgN;pem1Z>ULX=mLp@FVBvR#PgpFyN% z5{ce|zFfaSbDTuIFGdKGxCZ(dO&N)jE=G7~!iKaGbuUzUF;cLa9;GW*t)NkZ@(Axh zTBUuZ5~A7Vk%BBLS5u_g&!Ft`2*G{xQ}tL?C4)W#^BnWlAC<3IH1JY{w-{s9Je3HE zFGcbPn5HXts!;i*DE@3?cjZJiYElu!4>VLOOlq_M$PiSiP^eK}MU>ZkeVN~iBfSZ3tu{v91hu>p>Ai`)pxG^Jhn8N6 z6l`Jks9(r_BUE%HLZG5YsF%w!4Cogy-$W4Z9lQEhDp)Mbc47b2U-`pH>y^ zWE(KLeKkTL#7JHxy^B$s$_T+S<9FF(X`&ges*LasG3=LFrK6FvGEy)OdB|=^7t)A# zEkY2Yzalv)wa{oZFo(29BzvS#Kc;ID-v4PrB-5o`(SvJ|{NL&}sV}6c!}SP3eM`D} zg4iTOiNIj)tcntA<>&}7W_FNjp!l;K@oz*3ycnDEX-cjFjR)p6y+e5^<&F}LAVdhp z)10Cr<%kMB1txl~*WtegPV{m9NjMD=2r05B6nqZvqxaNWJ2aDsM@L~mCrkCpV1}THf++4Nk zzWN4Aqj86)zz|Jb#nu$W$H-XEi;aI23!igTaC5vFt!3G ze9A;>8fm|nR&l21yvafY8+Ig`;ieK6&w0*^^^Vfk)?^w*xcE75s^FfsSpCfK0><1g zKt=0FwbIZBZ+HQ!%eu3wY_tI27u>4-`Wlr9b;dnjf~qSLt6CtM#QK+@Dn((cU3w4v z0aQLs4cC>m^lQy6@VHmJDZ-XUt8%LDGtS^}{wpX-o- zEs#H+{*E`*yPmp6u}j|-JAn~c)K*0^{a-U~^qv>%^GWkc;h}e!`{MuJgX3P>Rf;XT zZf1BpR=x*EwDy(!ueJ~m!`(iB`nRr=;*kLd0~A(Gcax35f=}SS1=cANHE)gW@#0V5{v1wH z_-RPvT^gSPwXiLzQ_N7;HmYbG{29!fQo9u$)h7+@@s7`6UXMPZxT>-l06gP9sD(S3 zVaixlEkito2YvzbM(hY>jq)BE3G44*evGSDURH|HbrRQnfwmQ-`lz_1*8ouJSK!{M zsud^o@g&~o=AzU(#dQ5QGp<(!+!~Ed(L#U0j1zzpR%#k57~NpAmBSTPkj+=^Sg5nl zI1+cR=1uYGqK{Av)*Z!-umV_NKh#`d(gxvOEPh=L*0l_~<)1Vf00MXJZl-e#_N;+RO2Aze-QlU4$KVBSe!h8t;)`18ZWkqPz9A`8%v1L@ z!b?5iJMemHt0G9vH^L-stD85`Hxz$WPYf{WxedI}8Rm~drWyy~+57x}?0h-9a)PS8 zArsJHe?WsbswSweqEYzE4`?+8^?21m)C5oX39V*=rj{xItpb3PpI{fInXY`G?~iN$ zf(K)qc9Jqh|I|DNulxl*w`mQEGTi|4aSmVj1z9HRk`>!@ry=rl$Zxpd=K8t{zHT>e zh9$rX%k48xMZ|8wz|1osoCd7MK7uCh8CHcEbia()=_6?33Niml-K}lBTX{ z0%Q6M&aazn^7fh^#x{8NU+^~0{7YV`jx_@0#}T)>HhDzeL|tg8Wo+s(#YagkRI~=J zopFQ56k!ZgqbO4iF~}(6b&ttDMQnmHMa47p$2|zpUgQody;N!hlLS5C5i8iB`l8&4 zc9ZxcaNhe=Ta>@`QFsi`W2#`Ry1A0pe>LMgo=2?DRdu?;TW>Je!@eHiCrL9=aYr}H z3~{*QJUk`~Pii+nV>yifviO{vAEA3E_tUMxHWs(@gklWVUzDe7o8nP8*%Oj)LEeg; z+9Re420sS1aGSv;7inWmDX=2x1-#isKf_>_qk6sQ5LDo4FcTI8?yVrh*Tx&Ja>Co=MCy4Hcxp^ zRfSsO%b@n5;0cnd>KgoTm;f&Ph-#J!A(q5y0n|yNdYWnm>WJUCRgctXl(+TI%s9pe z>O`wS%2WF5=9W0e2Xa}W?W~-l*PAOjED%DWM(GwR*Xrk(7jk$B@IImX0Odzr4Hn^( zLNNcSZ=u|;yM~X$K+qS=CmHG~7wDE@7=~u7tE)aLX;1*uS_o) zJWvGcqc}}@Uu!lE!K4VTVGa37Dbda~jmF>H>@8}BYMVA0y5%XgA+e6`s;Z^^VcbvS zeYGL+ZYEZx)QFA4aa}*K{>)xcP1MXZ2H@4e3ZpG`)t}TJMwr)@`+4kg_I*Wk6?l;_ z@2ZDaej?Tg?$fu-z7#wO&p#2X1jnhnrUv*Hg=c*xRtdAIW5(u2JH82B?Pnt1M?}9e zIMG-@*cthSSSh?nBg1J39=+C#OTG~C!b{9{L%4p2ez^(v{z}CA+Sug=tfO=$LonX+ zl~^J2;m)80?HcVHJx$>@RYaUkZ(ny=9tajKg?qKj7MD5t3b^x+rqzQ=V}6g!mFDh37Owcj9{SY0iJUC~!1)n`MG z_Kk@1eX9E)uT)G_4b?Zrb8Eolr!HSUL{X%S(?Lgmy$14~tk0IuQe0N{)vcoO=Voj`@5BngGx#r zsc(r}|Ac(j8J;Vo%5Lfhx&suZenLLK(KJO%Wj*zGT?Ih1{epaw(M9=UMTDv&coF}C zL{TVLzF+Z3^-1>#mJ!@0rTYGILgAwtsvC{h{05Wd`cm0pd6_awmq6i{zrk;i{)DWl zB2ty3yGP+Ue?W3xN6YrePbwGcPEokhE!m@U$QCJ%sYdCK(m3WXNZxB#$==I5sd)Ml z=&nKHJ45Fu@2SjD4?sc2Uc42)zPf1nPep{fC2DNk&08UwpevNSlt0x+&}V4u1TRiB zSJz!JNtK~t3}4~HG)R2TYJbWjRHd3)*q6s!>65Cvp^&SCbiMITHyfjiRc=(@*LK9; zfE8}lURA`Z|7v%c@G1{pys)A6iDH|&N}FrKPd#{XzIHfD@>ro)N9ac4>7G!cnQS>= z+w@bv(ZU)82t@gGtctJHYoegf#>2dzNIYhPI$wEGvk9Vl;3ICyCaPHVpK^ibfSx3A zcRols(oZ!&IZ{)gcab=o&&zcTSwBa}TgxG9lHTJ96NGy0)bWqQV%QlDUD&DSms3~F zk7+b-m)gsN3dh0d%Px)gYVxeHF>Zon$tv${Qtj2*a-Q;r z4#1H!L9mPpQYXnnm2LG_2K84;eaBNDRmHh#V}st(E$&GH#YvNN*^{p(wOc zClhrsj)UMEp2|6BCWm->sc50$x@?W~ks<@VHP( zlfF^(Ld6KGP5)XNDQ&BqWNNM0zz&{-@K zd9vdaTf`$JK`IKPS!SuPoSrQY6)%)nRAbNwvrN>Gnl7`Zyh&B6PMc8*DfQiMUM`)O zax1k`)de-CWFi{hlr&BGliEprpG0|-)VI5-j>ML{G4-Av z+O8={$uRrWE{DAU90)W6Q(}{QOLl8>S#%Ht*HoXA2Pdl}kvb!6DzHHHDl?K3lAlPv z>w2IE7MagH<>q9s6o=Fwt+6VE*X0wFk0)P~9z}?6lZr~Yy7Jn|!jw4KK?9;d5X^p) z)=wUh;wxWfL|yCe8| zI7K=}uR-wKl$iQu*9Ng!dB=>lr%Oe7#=fa-lSiaBRPUrvy$q@EJG35ZqFt&5bu`5 zszG6n+-I8NVDbuatRf6W=E_7a?x4IwN|V%?%BdLL%$54yW=_azrF;}GSNftAyJeyp zYM<1VJR>z&bF6o-GTvDm-fZFeoiLy;`5-uf7T30)d zK}YsTMRwy1Nk8!yX+xcqMdS0OzS9kNQ^$!vNVn@cq9^$>As^+W7KvZW_Uh640=Z9x zZf2@W93uBZK7|UOw%THGs(6B&k67Ron)l*0sf!h@P`AAb;Zijct5bIj6y z)e7t)pOviBsxZt>2U? z7jKpg&2u9kx|_GpyDzy~H(x&(N9OSy-b!vNQmT97-+8?K-YxM1)lO9;KD3AD5WZs8 zYj4VjYv6<6`g~rI_gO=Yyt_OEhZXP~K65Ew)lJDcRSbRutapy?lk|&>k24B+4uKvk z6;|neEuOcRSLBn<4bVuWTa?kbc@Zcdpl7nzvH~N%Uc@UB1e(Vweo1a=vDU%s&O5^5 zQx4vC;TkSaeO>Zaxe+GB`*>YFH!wC1C+*{H7qr!%k?xV3&6vL*c{t9^~FV*|BK6z5#Aq z!rS51mF#E=#yKUtFu_sQ4~@~~0C-CYZ@b4TN{HtlhjIp5-l3^Fm^mDW3meJo#E&=} za02{aL3!E%#{W1RdxE!>?_|m_Ahg{Cjdu+U!e7F|TAh<{$~f2> z#siwo`Z+YNaf_RhJ@BS8Ans{;t=XlA4@gC4;A&$?fPU+F7RusjYM=?%wZbdTLZ#gx zZ!q{hhy@y4rJ1k00H~hlzAzUDFNzp6YV-gN;=@}8VSV$X|U4xu{KUh3g^z(p{>Lw+#h zV;~lEC+Dj}RqGA7`XZQLrj#V!SkCL}vw~c&9;51G@Wp$}dD}cORb$58FY&qxyHK?> z^HpUiiNo=icw0T@!B&Acmw4TL9#R7}FO*f#b+oO36jKu5RH@gB!>N5rnp}MD^$KuIXAV~ms45kEb zO>?HUwvI}qFJZ9XRnWLNm~*JFf+mNNYfUPhz8rSMT;*-&<ETP*z-u4}B(@`N`8#I6cDt&D9@bf5Gvan40{?fNx54>7 zo`~7%IN;MjC};r@Ue8mQaa^en`xBd4{HW2U3d2--DcLke^<*=uo2$wAc(?AX<$1>twa+)q1E@^shJ z436}`078^#9<6LC36N!Ik1~$(pcaI0HXESbDXB@7DZ?FA!GKd*&p1;)Su#k` z*3q&}D?&7yTBNQm^H#KnV>FHtZNckm04USQF3T7V1WQV27eM&P3=%fQwwibfs0%Lt9BXio$@8 zGqqDKQFPE8F*|N|1wIv5sx*p;nq)J)UV!(aT4)QD&opnaBeVzbP3S1CpK7gU26jyB z3H&E2UGq!PNqxfT*xU=QsEoa%k5hlwv~bvZL-zN%0m!Icr#)qIl=T6))p-U|L+F-b z$LGGlB^v5#7+92aH0uwbu)fALO@?-yW9Wb&!h5tKNHa(q?N~k#m;?Grs(I=Nhi(us zUWUQyDVhe3LxX`q#^IU^npTcS;eaDM$PA}-b(F~=918BFrq7z*+SZP45kZ8{Fw+{% zTurEvK$w{u6*pqJ|)YzRcuUFcCOAEj8>wrPv{#1Y9L~LBB}9)#NCe4BQPeUEf5%(B!y1 z1-Nw5rSG9fCI@dSaINTQ!yuFgH*y+qdDKc&rhjR2Oq>oynMF4+G(}w;n`S^!j!=ux zDg9lO!#)#K>9ovHfqWgMvp}_sNi~)lKAIh$XM>OF%rfI%!+Eo#*<9e7FwKoe4L{6| zh-EYxcR{KV06a*#$?i=UjW<|=7cfUXdoSj7Xo*H9$;)?X5(abZvgY4%xo)|>%1?)HTddl%~Z7{)?v6bWv+Ts6S zSHf97k=MPh=SS`*>-1d2TSo}qv(eNh(#klK7V{DbK`Edv+wd#K`C|z$fe`Mb`Wh*u zHf`se>z46W5kh~ukKu>bQ-9R#e7oE&7)VE>J?iUfKW@qkyZl_=A1l=b2RrxQy zGjN03=`1WzM=44)JSX1hb`eYkYC9-CDWxW--)2bRBVZ)DGx9?D7-#Yp-fF_}ZPOy#9ZDj-XZ4-XEgSVCFj29>IJ_s|ok%rUC z_sW$9JZC4o+w!?T@XdcG@4cV^7pmixv-P-g7sy9hW&sj+GVi@ljJXQdFz%?E<54NR zE&PFi^#-rA3n{#}J{PIW+AWH3br?P_=4}yd=Q=R0nE4!zO69%wNnu-}3groaTJIy_ zZSl5oujwSZFFqvUz40+~O$>gjSIVY%j}%6X1*$JJu8 zXn=b)sCci1X1askN8L!b2zL0YA*F(=rq|Fdu#W~(E@vY2-BtZG-SKY?eZ?W7jz?OK@$kH#=2 z)p4JhO)M_QpqWOuh0(3c1X0vsU>CxT!jU9oaheS_PS>9>VZblg?wP|;96n5e`Ft+T z*irx7i1TTX-)A!c^q1ki=UYuV`lCkNh6QOdw~WJ?EJ*v{%ldUjOmQH+%K=Vn3kyi! zn&%nvO-_F+JX0{-uYiHP$SJY$))3B$msOrT(O>FR(V|?#9#z@~h4bO-Du!tGh6*>8 zSRZg#6#Sg)d!(mx@_HTpoEw}SZ^EXxRX2s@fX5AI7BAJ0GnW zTQM!QDr+pZW<>3;m9(OuR?@D*T1k24T1jy?Y9-x;plZ^zAajr;?+_)+D*ZxT%k)ia z@p78fIq_pvD$(K!qkQk}dQzP12+K@sJT5!CK+Sf#Ju$P)HB00C`l)I>;nh}r?s_Dw z6*Q-uXEMGoB7(@hMd3t zllHmd1$mX}kAucme-ove_A6>7)k-Q&s+3wTKWs&`;Wga(j|d2EF7K7`t|)SUyTd*A zv?>01ymR&lWit2Q*(>L_9`?vx$~=aw$5rPM-V4n|n)}+Zc+iCErme5w9z}ci49yO* z>`LElt0af&^U~TK&A4#-*1H>~<6_s9qcP4+6RO7%?f%HzIm@M|sp&R@#!dhKf8$f1 zDa#c2{lx0ti_TJYnZROM##K6Ef7Rv3XD=K$nE4^wbf(1#&w_*O=YQAm|EA_aBtQ3W zowk9whxqBvp7tGwgU|CTpWGfc9EFmL+EhHGM!U8sd@;}PsIdf ze>gn#df)wZ%!4Ggl9njfv3X=i#=`B)se>nqmH2SJbIC9EFZq&IO((FGX*Ji_>zy*2LIM8gm#{MtjY^(|xBTyw{g3p$9@m>%eTJ8e@a?J9 z&1SUYD)nt}?4j##V?J(t_4}pl*}T&9(hG-A6~|wL7@B07yq^4AwvX#+L6?2=@|$LI z)R3%2*-`(Bv{~Yl{?(S9-sQlL!)Xupz6-ASde-w)`R=z+hVL3Yc3Slko{Pf=rd9VO zJe_Z*RWBt1XX3}XowM$m>*g;zvhKzY(Gah5PyW34^ZA!^jMSl|kuz~d^>xDY6<4mt zqi0nw3Dto!EjOrS{cV#^Ki;QDf+s`X?SCY`+|%(upN`MxEpgQ8{?ygpIpfiq@T zhwvU5aK-HEMeUMR$ITB(Thji+f9@|WJAG|$MYFwL^6r|3B?)&I-)eI{nEOe+G5u@s zJuDBQ{d;xZl(lBhQr-Vm`&;F(w7I*zUp;)j{PLrVA5Q%&2uiKc+&J>eskziSqlwcs zr+PJmO? zB(F&k7S28Ko!zW{0ypj8t}A)YlMOCiyJ5W|JSjP|J3lN#;uw|@j^E9%Zq9S4ox%mx zGYC(XEH&e03#$X0yfJ=Herlg_4S!9#qpH|=ZR&}#Oj7?shph{%bDJC%BU$L)xmWzZ z4EnY9Y5J8G*^K0ibfyw7SX6yM(8lSOhE@)bu1-#PoIcE}N*StSz@ z(qR6Q>dYODEI&2x>1O9XUgMWZjxPG&)*dB2sUN4f@xP6?y>8IIXXgKE`G5Z7$*{dY zGnyDyz}35d=3N((YbA+gzwII1ZF^qkT4SN=x;%lh?=IpJvK!@3&@WGUsXk8|ZJCBQ zx_HI)6azpnd=lm&tR@^TyKC`!?!9Pzfv-9xM z>SeqxT^NY&DH9c(ztjBDi?i_ueD-D^7@YN19HR>>h(34ge#*o4m!nSkpJ?maY`vt# z3`Ey)&^-zLHpecDH?)?)=ElLVgD7?h5ZL4 zU)<@NPCqDo)$R13yngvf`?B}FJKp&8s{MDN**ugiV#3LZ1=CN?zHs>dg!@tFW)_Y9 z*B^dJcK%pV9Zy8;*N1SLbSkfJ=JD*gR<~=ZDhrGM_g>6Yu1;$LFQ@$zy4>SF z)fz8cTYV__5ZWV;O`fP&XnmaXBn>eEC>W}lmvryn)vZigqHzvhSMBHFd6`^E30?BZ-+sxDr+x%#`8Ou03+xpT#q>a+xl{d57*f*5OY z!T%TkS^9j%eN}fw9m&U()v7q`I&r3e&Kx)c&un?M|@aMM7;W8+k)*x`l5T@OJCEim^s@26b@ zM->7-k#IcQn2I&;F(0R0>qfiX`YOoNhTi&-`jN)5uCy_QM0-NCfPHUXV47iSPUdp1 z>thRvKtg1suNv+8$@(9Lsg#R1zL4lZ2s&{_2;?ATT-_(QT?sQtp7A2OVKh;ec@v?c zMQ2HszMp!VYQOe0c9nn#9DU%1QdPLFc@+iG2i{I{I}$A;C!nFQ)Zg16pBfk_buiolMPJujT=odmimhdi7A3| zW(HZGGy!lXu;pH5+yHirD{^rm@yNr^%+A8G5T#;RFkpj_T`d)E*%EY~^kDM*+v~OgA zmqL&fyX#}|$cnbiyyWV_Cly9`N4!qS|JOg)O1hsE{jc*diw}}=H4?nNis7D1b2c%h_Fb206`ZBE{jWmMS?G~ zxD#UI?cUQ}aRUMo7zi@B`{IkcFAj@@?{uE`d#?ZcUb&K~yG~VgPj{ue^!!fZM-oqO zw1;eLl2nW6B`hLOz`L|#!u$WWTmN&gsEw5zo2fNIu(#eHCx=`zr5|e4&>e{t^_r>BfIf8axu&^`4 zH)+nze{T-YI49mG>k}^KnmAhO%14q#_FJ}JoK;;uj$f>gEJ@Zuj!q1rQ1VUcgry+v z(8j6Bo$O=VxV}3@+x^7AgmOt8tZNB|Y;FHF`Gl*T`$p!A%)`oCqNQUTc~3Yl4q$6B zv!p0*^9AFvY;1$eou`~r_6Rj8tMiAmBb^KX*D*?S`JODxp?ofWz&hVD!s>5ZX|p=c z;u;LQHE<71y{27}f0IkWyget2Xy=ekI<_VRrrV{PHcO_d`!Y*YOF?We! z_}@fJ8fUKv-MmW{jmKVLhD#cnws<_&#IRWPCPN^?U_7nfbfz1OE^IH0bb`#*JTXmYo$i??r1OJfqL8$xA!!v9o_fshV|-?fytA~zOX zQw9F}|5TdZs2x8RYaQlN?ZSFFGOOJ7io1{G{{hXs`v0f=f8%<>a-akM=}xw(Tw&t_ zSk3vLT6Z!Io~EavoDgi(TPa@}lu>6(X~7sz?#}8vn|LA$2j+fDNp(lbOZX;SOQxSQ z0;**9jbE%HIiDZszA0DdVS`ipv9xDGCuh7R%l5?OaBZ@Vv)Y~W@ea;QiDeD?nk_>& z_W$oW4T@LnWAPefHZw|npOd-GQ8ae5Ec=($^}9)Vg4ZsN#rj|y0>p335ZRKxIHRvJ zlse{Y%5(uUl_IDQw(s>p*6`v`)yO z9OOyr7Cz6C4oB}E*K;GikxEQUKAF@dxsqjg((3q2$q%Sl<(5`HB|Yt3dOdJ^H!RCH zZ+GsA45Od+RY`=$r#uz|Z_y3Zw$e~`CSAbXVC!=@^9vP440nBXxE#YA6Ja@6ecnTl zwaf8e<9a8LcD}PhXUIFTE!Uc2{;kRx5ems$;P&*t9ThvAdVnH#IiRH)Cy9t?aLvdop}7k7qnc z*)JVtuQHRF2jnq4ifqr+VSk}L#BiL)o04D1abz^!*b!ruk{>5eu?0Fk&a)1KGYB6} ze-QHJ$>7^*9D9bQm>uH2l(FD()Y#H}Tyd#HN$Ob4Tar2sTYU`ub}a^5xxtrjpVs3* zrK^S`X@?eHe01o|k%x!&L2K7Y{)#j%tHk>77BpE$7j_Epd2^oDD^(R+-9zYPWwl(~ z`v2bZ|5Uae3D=cAMSm1r;!B_&=f=;FqVSCor85Eq^BC~=^* zwUznr_gtJDPfWwx{x=PmTnD^qjUrcDTfnl9;llU~V{V@M#-10)CI#}>H_zRDx8zM; zMe(s~Bs}xx#Yy(p>|vpAS!4e{*X)s%VIQ+5{6saf2immx*MgPXHsp>~>e0o_6Suej z?HKGaX56XtV*iv;`@1pNm<`j!H_R|tzPm{@aE$AS{XBanBWer2sZnOOI!Eg4=F-jC zy|d`bRpHVd1{yJR%)Bkz#i(iCa2lAWgHG|W2SPGASp7lq5(*3>@g3?YNfr3djz zY1-ypn=Whj85h-^S(2 z7wz6x6q+&^4camWs~?r?9t3wpe~iq8-|hS+wXeJ(zs>&{uDTjWrgq&n-(gGI$GyuO zaiPkQ15T6%1svbdjDPFu>e^vXOZNQte(Bd(vb9PL*(w%A=9f#I|38mKJw89q6E`rS z$$#%8?z0*Ft(wM_SmsvW7mzZtpq(%S)Fz? zr+mTGqKN#VS+aUx^2h;-079AxFhl>8>d6cwK9|+la&Zgew>ZW+7ACz<>}wn5VE)gs z+9h7I!pf|~X7NoDH(9>euDV#z0Njy1DZfWygYD$@?H>8?u4rWRjKRM38^LvF zlhmr4b`(|Ix!?0^aohZXS({P|(ye)c1t+!z=XFA<>=V~*+eXV=OLu&_v@)eNDwY1` z2l0#Py{`F=1&(U?6|SDQbI};AEjH>o*N}^mziFLPC#GFW_hydECbRmc)l?P>t@(q@ zHax<9G`V_WkN;lb-x4>I7r0T}9dfyIt}WY=og8X?=?EsP(Z5pfaSi4T3l;Ca;xX7j zY{+f*0^WzNL|@~o$P?ARX`QqBXDU*kj}F|U5%zxk{3 zNDosyz9b^MTpS2uzJm;VVAG>ND)=xOtJCnLq-BJb*w1dhG4-l+XhuGpdnC7KX8*D( z`NI;8ogPYaWUONr)yxZF_P~6%-vI9^TLGmULw2!_6Bry-&5KSl!+qPF&oz2^1oi z9*M*vT2IubN~Z1pMGw?PX*WxXPjB{y!8qWVjkPj|o*94dp!W;$!4jyp++X!vlVgVp zYk4n2E&>}@iHuPf?pb=V&8hcW>N4-}Gw!+BwX;%`@6h8YN}ec z6*p1t2yYbq$C_-Xb_+(TDTKwuDKeLJGBrzj&yFTJ&b#MWB>2z*H}0+zkyw3$p;Y#6 zJ{5^|_l2#t#LIJ$nD^zmj@Y8+ThH4%V1`C*VF;$3v&x=n54t|?vhOB&CO(1h=Q(#g z_vo!+kGz#bZyX)4Am6r%Lq?UI9k8fMfm+*whj%gqL#n>}+pZYB<01AJ!-lO|-j<#R z#vI?hZ`Y>5>LX=n`p|+a`}cXrRjV?(r;R z=DzGYS&vgJX|Ak~ssC^(iM5h(IKjI%OHwZ!LsWy%nIoL%VQkEIUF{Q&G;y{7U&FvpZ_rd4(;f zJj`Z`R&4*7S6g{WUSp1?9^7)T=uFXvOW&-s9`zj zS%0$q{R$|>_7uxA{;8bgz@zSO_NUlN|31WVtG`PE;noYlHe)_>3$`MmDUPRDn(t-t zsv8-dPcf(O7PZLjVh{3*r~jCy|jP8DN&f&1rH7o zUfW>WU8rJ}QhOaONAPe{d^YGp9 zpaAqTxGfeESS~JV47db(a7ujWg@SjxxLxJ$vfJHZl0-C#(^K`}Ja%8g46| zaY3;|eGEyQC#PZTQXj)1)zhG9?0y5*-*cyV>{|?j&0Q^GPZ*vt9(PFW7=vLfW%&>m z3%@hqcc$k<*sS#pJX7*Yoeez2=Fp?Q{PmOl6O41V&%>gUrzX)RoR`6Jyg zN~y+#2^(JhNcFYBM7*cj>mP40-vR71MyUPfM}}`MT||5KzxnZ@mZ$2x(uZclPq*jG zlG3iVJhe~!NUj57>wfYL)su1mM-*1et}GWPt9P>x7PR)P-QHr$Z>i@vjOy$8_~1tu z%x{)>itXv?@aRV^gJM`v57g&JsGjaEOQ#uXE>+*lcf{tx7j7wchWi34 z*?Z(X)w82jX-lkuQ>*W;B`+5T3%mH{{2lH)cYuE-DAF9Ij=ERd(WdkwR>`XQtF_%n z!GqRFcc9u4g6A`U~h8c z1&dVP-Pp6YU1_b_)mtceLMv_yoNOTdfQqAEF|VCM;|rFlyOT;V?*tFs=I7>EpYK9r z%dgze-M?~JzviBo$4l1+`0mkWYMwv-Dh;0Goz@+ExK%J*P*5T`fg5PJs(8;sz+4{d zjINKyutA2I6bc@rn+idd00LnFSb3yQ(M=mg?{f&OEpHevqS=37*m?uSpr>VlbT^tk z9|J*@8t4>!Zt$&0fPU3b@GiF&^poulbQXfJ_!O6T^xHx`w!NB8q4N-2Z`dz;e_MoM zq>q8&(ETM4g$+VemtxpP!%{bT2!ZvmsmU9=48z_Tuxe=RN;m@65na_k4J%kQZk3+L zh_1rt2G9T)yBfpl1Q-+nElvbWvqE8Y#*;g--|PMz?uk3K?fs=MAFt<}5YJtHQCK;m z@x>3J`Ck=OJqg1mH|`-s92xd)>)UT$^WJqY45pwL*N>+h4Smqqze2Ou<)aQ)Mhv9; z9lqy#_}pmN&Y|VW`U%<3N+joyt7#hOREm2T0R%UF8dDC;QBm-;3We%@GZ&1 zu>D5ga_&DQw7viXnT0uS@0daiJMQoO!&8WzH~W57?t^U8{z5Fn9~5Y~S_USLcfb!Ww zEYr_ldO(48jvh8P7HZM!K?LhuA-pwHq(22z@jM*Ncd|rDXa@w-{EDrP`X)RFWY}5Kwm8H z5*W?XNTX%2^RR?QT`t5@0%p78Y^8}W@M2Jt(j$ybs28>oG|IRFiH$#)(WD@w!B=&t z!1brktLTFcz5-h;Ao-epvRj3}LG<>z9y}<_ap@}zeYiK0Wy5!1rRl|-i9E^B>i#+ zuBRbEL02G<Kh`k7AaEQF*uOiHgVdcE-E*D{{0RzYE zSBtPa23hkKUMs>hgHJncAR76%UIg^zG}Qj4et@T%xB9IjEWVaEuL2yqf*CwaiC*D} z;>GI}>63KPS}wnoPNU-lZ%N%EeKzT~dj~TTABk^dy-({E!Ki7#5V;N2$MrjTTlUti zuct9>6z4L(a<#qD4T`{rvq{i~2`9KF-h~ZyG&9;G_9{uTUb#^bOdgp{d`)T#Q>=QA zH!kDuQU$sWeOUH>YNE5>6P{!1dmA?^f=Mvn1@2L9@8IUT!MCdlcW!yGeiFW2luxQR zt%V-;dnkVwqP*uqim*`3XPvu?_giQY_N|3?Fj;`L3^Y&VuP4opyJPppsRfu7Gnuq& zWKTyqZzWWKxv+p7_f^NVgdGJ0^8b+PIm@|@E8fH$-EK@~CJ@g>Z}mLg>N}g? z$9Xe0>0u+LTx4a%8@Z(bbde0(-QJ`51(-3y`)PO)MuPK5We5LJ_By8(VYLm$s)`M~ zGkEi2i?GTD<72KGZ`Zv0XBJ@<4W_I7?xb4DVcyHLi=e?}uEShTT4x(Adf&{|6Ps6y zdtoc^F~Mt|UzYr=T7<8_t9t7%EW)Z7%roRGj@`}#$s74+5mwb;Oy#fADYAFylCmRN z)EEJ|;ccMXd=_Xv-c>7#uqCa$r|%YE6YCjSg%a0;#^86jx_-tj;!QR~^zOk5v3-Vs zn(8QGuv-iiT**nWeFqRsexwvqR8 zg+k10FvqZ(^DXW2s!%0oFUMY9V&eV6M#HC1$bUU%h1wJ-abT4rM0r z-gmVMvBL)6M)DI8Dsmxq)Zp6#-v8dj`i0oFZl;SeB_av)PLCnSUyxM|wt$g$wI zN+g_M^@OstYq(tJ7t2uVI@dhzz2-Gr_1M5vZn5)j^0%bdwvW^h?>A>5_RP0p1%9J5 zCV5O!v`r@WN#1vqeo_@XiVKMtTU*OCTNnZVz)yMoV1c>PDB`501oqWUbXD?RR|>I5 zz7<Sj%tZLD?%87h)F;-otnl zcH8K;3|xd5Q8pKaMOXH!aa&g&r;aqv+G(3&y&$3Q5Z%3eH!a9XyQMA-@2xP3&M>8cd!HQ7qHAF2T6?%VQ@OHfVDYJfn_E6?Nh$~}_>>+< zSt!&}gwm>?gHGT7{wcPg)nMxBTSq&>qkRzUQ+f3NT3U2mL{+6ItbLG$s9_tJHm@jg zd&5J~H)=iY{gl2oX3wy6n~6f<$vg$t^kH&$qYt2^fU&w{rv2F3EqR#f*H9KV{gVSR~Zyp$DW5)Wf zZgC*=UK>SW8fbA9(Tf?VRr>&2!9&sgI~4V}Qe$Pqx~U*pe58dAHGxlz^9Y3`t^2)q{S9(o?h_Rl)nu-Xkeb`FGl;!^eIo9edB}vHZZ4L2Z_Q zjyiTCXNN+m%l4MO|J1tW^bIQ;&#uuq09$Z2dedlmzGN;+*zmMsi{6tutai>f_auy& z=c8fa@DFKR;ps=K8xI*1v~t7ZgaMN(FS|B-o4-6=XuqlUjUmF@pI*{t@cPOp zubtaES=lPS-L&dvZq38PmMtB=bk&F#b?@FgS=3u;#+S=dF0`q5C%X2c_bYqF%rZBh z{Or|^V@h{)Cg(9$t6o=bfEInw_1)WX!ORP5@@L#@m-A)ck%t*>u_^iqDQeW~>wcnC zDX8)!viZfBAFB>8nist@;LOGMn|^mUN3C-qMNofbth7H*yHcmJU-a%pk5``wJ%*ciRem%j4iQ-nVW^uv` zwZ)E@nJa3|yWJzw{QA=1t;<04Wm4hy`=Q`_8ua>K*y#rmNRp zR!JCG_-FZLn@8=cSMT1kq8Dn6x_Gnma_tJCzYdveUbKlZ}5h6v4|Gv z#()*_P^t$pivc;F6o?28*q|Qc0vID`!J+edg#SnPY<3Mx@V}v-dI6^DLKUVhHxRX+ zt`|2}4Cj95&njpNV2Ej}+?!u2G(v=KG^Hp$EYJBNFHpGgBG;RpDWNw2VF06E@p286>+F=BtNkgtUVpiq+yHZ|4a z`=etznKiX0H-*br&=QOGR)49M$64flg=8Y(3jFcPH3xYe0j5!i_HB1BYa^79h;8 znmk+Ri8kp5Gp=42Z%gkrbi2&-SQ)QWLxFSjJavRf0eWoR0m97VVMFL1@gWG81BRF% zseb%JezF^-=vL!b{s%*d=)4Z5p2~RcB5y$0T)h;B6b;IMC;}kNTveGPxJ3|Yj|B`d zb(YWZBgKx00SYxY(GKzJ1Qy=BdRpTi-iQ51Kp)C7)|93*3O`Ck!SnRPcUOmUPr9FG$T`aRI z;#JZ`;UY3DfW!gQ+!V>e9K{?JwbvueU4_T^OZ*3qV$1NfvW$LD&E*jb7-qgk3se?g zsG*}}*6yN*>PlNh^hviGQ@9kyDxlzn0DdK~6rceb4dHOpByJL!3o8jNK%u6_>J#!T z(FA#Pn^~dfyZ)qLw&*!vh{X#rgX3^QG$p5QgvXymh4{|dCU6Yq@o zLhXRUO{19?L^&oB&CqS;vs`y#C2f}w4;T{gNSnd9DUo}qqT_l5_z!(bjfc5;^hHP0 zJ0*r$&U8U7mOy6zWm+zoMTGGYXuQs*A6#Ah6?|cvP5~8_KZ$SnUiPYr_CQ34$-|R) z1+o)*p_|PI#4w^fHC9AHOZ97q=uDzLcTq({0Ygl)rTh3qA`Gnq3O6sLuDbd$xQe!w z87GR9iN;iUbO$Ijz!x2&CzBlLTB54U^m87=za*N`sUqrChIN%#JPT)dv=}hVG>j?2 zztbTo9Vpb)Pm&2l4ncqE6oAx2iZb!t62jOvPx0fn1)^2^AP`u+Y|mUV=}QzAtQC~SqEHH%h>W-L6+ zCIW_-uZlHknId@PEW?({8?rlfgGYPx#HJBc82*##iCzJPnk~E;$B9(}YOoTr1{~EC zyt-o)wZx5n(<97d#3}f4oZ?U%V3_GGIm^|F0eNtsP;(MLlWL|= z(ub(Y8jxwVeq~>?QMg97K^=86zZI_HC9ok6%?1oJZv|%nU1$)AmH|WHLcXw{bRFQ) zNge%VwKLHLy5l|3H$Af{R4}@l;|);w8lZr`lv89TafLkrOROOx#N2}oAs5qj@Otnc z6j$NJ_-+pE0}L~_CwDqmP|sxarp(%%``}!J{|*x6YxP6T(>T)RY)=`{aNtn$bZ)O} z1p!aKc-g)7FrBiM2d-Pg2 z>I)cR-p1U;6X+>2TCSsMgp6Frob^#AP`GI*yMcH@w?bEeLd~iC0%8IARzT+U`eE0B zL#xZKC+raoMd=adT~t?R6bZL&u8yXULZNe#vm%m!LIWiA1$h~NNe@@h>9W*qnU=0= zuzVAJ*U{gj3?zEvUe+J|vH{YY4$yWYf~kfk=>&J?ExCd|FCiQ-#Q%;;(9g-eTutOH zGv8wl5hixA8@qb$4A?7XuN3@{` zxNc?WqZShc{s~_BWr@$Tf4Tx;nIbw}X0=NlsLy(1@Vjm`b*1-%H`PYymjwMJnusg$ zND@PnbTTheFAxRzDh}a*Vdg*hp04$Hrik_fh6F^af8(>A59sY69;io{-?NADSL8hr zHA&R5nUqV6C847>0x-<9kG${f%nU>cK%wUT{0i`$mMWlP-Dq~uFI)}i_ipsKEbA!Y zC*G47l+W%)R55XoN2374%pF;?=S%Do$p2i0Yl84+{3A% zWWIn_1BRK3m_fv3rUBXn6l%I69iT#JBl=sS zq=cW~(1J4C5FvwH#=L~~A0Rx}v?J6kGF?FDb*t$U|AWe9J0Z-Wf3Z@v54)bphBhD| zG=0P#+$W&~+JJx|=GAfq`X)0QCOmYju_-f6@7W(NOL~{;KY$3#ok~vI0V@hYh19@MxzF=2y~Psy+K$LC?!b%f(8MF8=F&qkfTMkRyUb9b1jHiW~_?x0Ygkt>PccU5sGf0`Xqh^hG!N;mlyN9%@1ASLv&`iD*Kd1wCiLFk?IFBe>Q>b{)(=qyW4h4(*3M zI-1Tiq-!VD54{2kHK&We60OL;;q6Q588Lbqv4TTGbub?j8shOJ$hpSp=r@r0hiHzr zLO9&q4|c62vtML%zbxBBnx!@fs4A^z>%p}rb~9%|Z5=Sg{7D-_Zg>5Jw{DsBt?-*` z4Y5f^S!LD%8bv1KFyVEj%nCk@T$@NjMrKCOTc{4Ea)@Lebpi}C-)1hlCemx%Xs&KG z<+zuSgW;7d0fn2-!6K`Qtg52ZWm$)6;D(r508hWNtS|W*lnobDZP@Nq@X68e*7oeudw+( z8Vv^uH~+=cWDjT3Kf8!GyTZQF~y9vdsFYd5SZ1i>*)L7x4aa3_+{3=#hJK2 zF;&n+-5AJhb`7I;D<}dGnhN4JVl@$jrUHeVrcoHtj%|z>piuKb_Zq4iHA+H<^_<32 z%q4L8g+AzD-o)>qwz5t)3YK)+AvTYGAfPd2P@j*XR|_av2Xllxnr_IRgbrPq?E-t2 zvJ2>`4yIr}k66Tnp*k`g+$hlRaVv)g0)&}X3Nfz!cr~;JDAXTmhv=?E8Vw^NI-6#( z1IcR8T)d@|`HS$t*~7JfLlqT0>pEhQeLFD>^#BSr*X1ucd*dT{w5ZG&N?mq#qidj4 z-DpY|^YOZ{l>I_k(!T0aYAyLeKnAy74#PK~E<*pL9Z;xwxBDS`id&?BLKPVOKC+#- zx`=^rxUs7+ieAs7!@9w&$TV$azscwmV2F9E+ssf*ri_ABJzEjO!R+X02#1>pxgY+B zsE;f(&5;8%NXENvQLi%S``rfy6VqKDq@IYCa|B5|zoV(C0<^iAHgo$QgPswI^VR zIaczeyXg=5MLL?AtK*24cr-#l;pP*}2iI%rBg`$A8QUlih*?A=!cuhOV)DD=CH(=W zRRN(HA^e6r2zZvq0*0A7F(>d@Y!u>vLQSXmg~VFAIyzED`Py`*I$ali1PV8G=ToS) zTrJchRX^JYVhK5)o~WR4fMG^6lK~FKkyQtCAE6fY8#`A;C4eF3ac(=cjM7B(T(|ng zauwim)JfCJJSnNvX{H<+q?54&8%|Fb&{}{nQx7hNXvrAR7NAhGP5B1>?(;ClrW=jF zu&=2dJgS)f7>oBVKl~VL)7zWZ?g@6qr+99|VBu~nyB|u$c7Az4haH7FwmIg|7=O!90D6`a; zPA9FfA{?NB?^M@64zx{AwBfa5ob`gc;^7gmR#%(U_Ilq-BQK2!9+A_lSJ*al{{2>7 zDs`6YiM6Zp_Rzk6quZ{TG;?XM#a$=2>|3!-aJ}t6({HuhX_J4W_PVi>a<{u0o;SVO zt<~^KF)PRI>h~_Zb@`T0qmNw6oJsa_*4I`YUhuI(i<-j+&TF^OcbYnAMEh6ufBxdz z?`fZ-Az9<;9B%oxT323tM-8S#zUq5#MADe616Q?>Pr318*t z_^P$tJ>^IxN*N^&RDMw#sa93MmFUDO^I#v?EoFib%g>c&DEFmGLQ{A2#;Sj78B!wK zg`Pqk2UV8sWPu>;a7QQB9Eu9$ZOnPsB72(sgX4tj4Ed9tE(^b@(d+9S)IKX;rKWs3 zaluYnPgw5TRN^hyQv50P6P~HjYwFe%Cs8|HG) zc1{-=AmpOxb#<5Ue-rCnf%cT7O$oCTFC-1J46^)U{oVD57kZ{duWYnXa|m^rDEbuD znmBL&n54$9+9<_WwXpWau93_HaD$i+o#%xTiPVewg$q;lOU!=uWT5rwGy+b*N$bjk=7N-p-IOQ4<)`%>}2`s z@T1ORp0 zuj~l4^Un472Ipz3nv`srN;HMdIngT`RRZUE54j|=ExzB?!g0(ZCw)vzNcLK`TWr== z(03BvWJIrQfVuk$6xr3`upO|*B*!H@+Soeron^W0l>H8Aa|_9t(W~nB+y_*5KuY z0!Y%}gZkP%L`tD6xh6Pgx)$5lCx<8V@U3QBZLWM?=${?EzV>o=KI=z}aZR+ZOH7Yz zuyJ%kyW|1Rd7N-NJ9>3cx_gQ;QM^g_#J7UDNCKV(TQc6+{;)?AM@3<24%8)s_E}2g z^XLskj&rm9to@XIfTM!z15sD-&xNY8M?=zT_B&A(jK0nqE(7i&R#J`G)uND+8@;wJ zp-zw;LNm5GvCMJD=CxgSv?l*$mhzxm7?~Hnz80r;l)G{mUd=KgaX`{!aPm?}9OHf! zPUS^!sC&)bMs%<&>2z#OzMgc;zKvSNyQGfp3z`tS2@0R8ZiW7aiQebJZJjO6tpToJ zW~Q)OIt;3ho8Y_m)h5d(ek^Db62;LICHfV)=lk}Y*!-&KuC*#--4z{K{f4UA3huA+=Vc!ZJ3aO|Z4H$2&6dL~0E^gFPY&aa*HTH@K;773Q%ybbGSYRo?Z(Il~$5 zEOJFqZmy36BB-^uL0zgPr7)|>HTYE55?3!*GTx3#Wxle0LKE3v*s?8pO;As@lC+#P z5k-zthv349dmspKgjvU(7p5yhp8~iT7gV=&5MFBU$wM$w%o4s-3R^*Z4Vodkm2?*i zTj&pXUstI!-Z{|`?wmm`;D0K@qQdC)b??e=1rPU*{lGM%9yzDk{OxmH1r#kD0YTFu z$lY7X5w^4zoWO^&QPM+I zh%Am?Uo%!+E{^328HSwes_b0lJcK`>^CaP9addpmo6=(L3Ehj@PUaGQh{wcjssp!H z7N%{Fj;lRfs?RzomK;Tnph{s*s4iur{Q32&@D;2zij)_^c=lhiJPgh6Wg5cj+3b+k)9CjfkHFXGvIai1+$A7fG?!>a@EBqQl3o1 z0%lM2+IoXDU#+rxxmb~|CuQWGuJ#Z{?}Y!BP_01rN5!@zp;ollb#YXJ$MLlVs9K#jJwD>&@NKi4_~G&!kg4$=2W`vDhsv z*b{B9FkbQSx7cj<9&c3y-@Vb!fThX+p+0|7%z@P;IxkaY zs2+E=>N&nI`l-QiOY;;Sh)(S18S%Q_N`K#U`FF*0_H#YbXiCt2@E^%q!i>^-XUdOO zP71xKYSOLLfkL;R^-e`B*4}8NG*0#k^W~WeEf-5O!SiE;wX(A@b1Ee*w@dMzePg^` z_m0>mNnx({$-BU-VbG5H|4MJz-O`nmnEW~0&+P8GKf&A4Qzh@YM)Dh(DxN?r=p1J5 z4El+U<+G~r&=7RiIG^pp|E+m;`UIWD0&pc+nd+V<#)I0CU(h>PQFR0a3&6Fr-57My z9O#}ZWr(qg5Nis$-*BNaLKrUK+*nrJ4>Fb5qAnz%=bKIN(qHn%>8t)O$F7*G5$eE8&p;|t8G#~sgiVo zu85y^9I$<~7CQonzU;5k6;+4|2s$1-K)KHk<@`mjvP0Xiea?88^-L?zr&7mV->nT3 z?AD<$=<-w*Ldpjnjku)wsiJyL8LaG-@4DBxONBK&&m1N%5iRKH@&m0x`k>5**^6_l zWfrIWDgP^h|GGvMf_65g;KF~VmXg0izh*DrRQ#&M@K0Q3TOFIp?y;pfXVZ;@Zxw>h zwEXJ6FL!a@(B>=O_%ED`T7LYb>PJ=h5E!&4?1WpB z2S`S#xpYMF6F#urh^sEnu2_;SzBVKHFTKaS5=OZTb+_3!Dh3^Fvs%gER=|e+FSOOg zx+anfi6MAxlBe$AU0nUhCZs>5P*#@Xdhr|i3esprI9(}dXUm=L!3yhc#)I4*bqX)C zpRqQwSGV3x$cbycu}AWBS4Hl)cw8{cnQri3x2MLl3+xlY`1#>2&d zH&Fw9m1=@V*>hb-iK}!uVW&_cRS<)v^#Vv?q*Mti3I0c!!u=#y5NC;e<{sx^`V!ro zxyjWMh9u5No@sAJ%@KTrHL?&_HRxc(HKl+V!K~qCi?CNjI>wI>5Oaw<K1 z>!&+YGhuZu#bxkr37j5Is~)r`^r+e`qkYbhj5Er9F^~y%d139_6-zzX>mKWjWv)v5 zM6;MI`~aQiel>y)g`{aCv|;KDcOaKf+;@$kJIEIIT4@14oX_Q=xwAr7DOM_#K-(;$ zX3*i_SZ%#~k@A_1a;4Zjj@Qm$R~Dh+LzwnVO#zo$wHF`2<}>SmojoTI*p1Unvrv;C+sA7 zf-2ms6Lh%wUU56SkfB*C*H~PjESLUac2OXR(SVfses!^HKIGy?TA=nFcIhK>B=Ds z8H$#PE8Jfo(H9hSytyWpa;x~3&}fyQ4O1&MJL7U%qSjSzCjKto68osR@<*|);HV$u z4S%QhPnnup71l0Q7Dc+Nt8UV1Sk)M8Uuo}eop0R>&4h^{s#Z~ME_M}`H3&M?>Y>&$ zl~6D9!^zWlj%&EHy_0b6wYPHJVLQmV$}Ay{3MN9SX!;#-JZNC?~}{5E?v2Z)fIE!zh(L$xPtGCE8Drl^er2YLPu)w^wraA{S&`+w za!bLlSZ&`oaY?qRPfWT_cY=Ds0mM-1sxCB=Ds0hi>=&> z(ubKuJs@8b9hiRXR5p}dNT-rL$Z6DfcA~sQ6|OahC+{)YD69h=npI2+wTS(To=q{t zYCMzJap!xLgnP%)^GOFgN6cpRFRiLOKu&@d?o6f;Q%dD9@w{7T!VeaQN_*u`(hk`p z<*7o~UxH3I>ZU%WH@Zq(8T4mrsB5j|lx3-{#MO^|Dts4?@Zdf@q*c(t@PpcB#VViV z&3q2OfGc6_bPTK=3_me1ogtSXbc3;*6W1FC(jjAdl|4BH(-T?2w?fKf$cX@|$TRg;+a;Idw zS_-YWHc%@TXnm!7>|92qPmu3m8+v*20Qa}Bo~uVT!V~a|cvY%84-%X=+6EnNIRw#a zfIOX@OGXguC=FVo!JNi-ViNJ^FspHdn*z0KD!WiDP@si%G9qYy$VqK)N+owBf18dZ z!kkIYV~&G1o8_QA(sAC}+g{H3FZqHUrj%+zVLK?_u6>rv3%&SyTsR|hllUqy_1lS> zNzEfFl8u?I;Avj59dnFlvIRyH(%J_d4qvE!6Q;3U;MkPhL`r6Zm_mUXjP1z`V{WrB6=aYIF%Y(&DyOBF*Dx5JfJp<12X<{HFC0pYb=L*K!y1 zoz7Wz+HbpP*v^S{4LZ>zLAlHp5sUG*;Hl*-wU!-68;FI(P~sP&E1AUoDe{W&vMano zzk)O4T-bZ~nSKmjwsr`KP+6Pvq;sG3y6u*&*gD1f(e;9b4#2f;K}Xvd)Hi%*rV2HS z8V9qGPS;NRNc$cbH%hV^EORVZ!SUN&W*^&-KPCJwc9g)^@7eA_`&x}tn#m4%nKVIC z4Kde@3_k?wErh~2O>rQzV^D5}{i2}Qk-9O~Z2EAg?E#5|?fQmJJ7 z!0+z!9<%Qm{**q?Ga#Zo9%TBV(;cx1)h5s&K6yT`G9NKdh@ZX7+@0L_JOzGm@jx8J_ks9d zlWI=Xz&8*Z>60SbKh(7U?W5YqYNZ?n5V!qw6H@S<^^}z#E`Q(S33!N3#5}@6Y$mMq z3)m=Bpsr}+Fw>q+N44f^wmMFH!QE$4$UOi5+&SKP-ih8NzE-|Zyl;EI^ED;MQWoMO zo`Tn;Hw!y8#1A*^ZMPfnX-_K?WP*PbXymQ#YvoT4kbd6oz7f8?{%-?6`AU6Ua3qn& zY?9E*5g;(X)cT4C`7o`}4(3DVE$UgYn0P`lfYh{r9l&O@2Bs$hwZQC=rXy{uXcvWj zjDhSPc;->OvZtu26`ibdj93UO0U6pAQ*@9=#PaFXrRq>xXEL&0V6Y$$?bTaZ?5;1 z$LMG2zj*>c6{quU_=kK!DQ=${qtk|9rVX*h~M3uM4#EedOyHs71DA=Azg96|x#}gZPr220oF-fVlR)(2y-> z3WzbpBC3RIDP+R;{XUzZzh{Qi4~dDvnZYb_1+OdU##mUs=g2Mj&h!&9Mm(lJU?W0? z_%^#5C-J`IQ0}?(g@#UyGo5HzsdbaTlFkcuVH%puc459?Fm@_{)tG!^e8n)kULy|k ztE3dPXT0fX(}RE?*^M2;e#kLsvour~#~IkJs0cmdNWLRKO8iG^iPlXp9d9*O`&|Bj zqqub}O@EF55ZH!W1D-$-^ooffMsE@G)Jkc*^h`zkdmuu0ksfkq*dlfi{TsfW*h&6Q z33xqnHYkRg1Q+@K^XUFM#5|@4pNjn8H)x{iNXyMiA8Cu2$=#w}`!)ph;12(W;6rjJ z2(K5Jf#{6XRjXH#TG0hLCYdVXgs_7=SGgv4k$Q>$gDvU=rX_oZIzt`^UUW?_s~2cR zzhJvE0eY!`CQgQzev+lh7wjO;%X~riq8d{I{SUnjKNAQBrjrlZ6T;u9lek2x%dZfS ziiW&zI@lpwUsADHd5w-RC^*(9dE0qC-qWsSB^k~!C6CK4`zFwXDGOczs4fpRV?`^} zbBbwC`v!Us{#`UfdLW&Z4x=;F1H4|aAaK{48Qg(q;WLP6;JK%{zklFB;10P_M9n^c zZzEG2O0OWU1P-jm>G&~v1RLP?32VU=z7@)wYTDDTwKhbR zl}3`E8^FAUY6~9W1?9nm;K;U+U~q}Jju+si)OVbZ|3pPErh-ItMe!;##P_H!^djaN zok}(%RuXVGk(dxX;A=_#$avYt?0!~8GliDuFFVM!g~~1QiCm;KXV>9_@x_FQ&%&32 zyO_PcUHB+)b~sAF%iOkhw==$)#}=7+9|7H^tNMn2}3|N`4!tyq1Loq zyJdBq&`+wYq65=Sr_2wu+TtzV&2h{GY96H!kAn=!vOKenN~baz8`B(ZnPK|TJW@F% zP8QQEENj+=E@--ZS=_Evk>BN}asTl7;smu1l4qKJG<8>o%kQc)l<&nqxk(}~^^gV& zcero(yTV!xmCb@3Za*zw{!yt7c%hSpz9^IFPCX_zgFR$Jd=uqmQ-rtmk5;#-xS*mh zK7?6qywU_(Mkv$NU&REwi>zSIbAM1*ng4-{&0_X{^mYEQ^d)HTXPZtm{6hOozAMwJ zRURw;g$@a;_@hjH_BZ~BXcqgSp>s?>wZ1NPV+*+=;cN6aw+#SDJ2Ml=8Tb!y&eJ<^ zAFgQ{&>e9YbaY$PcdqGV{f($9_mX-S{Kbw%KJXal)-NEb>F*Ec1}tOIwIsGRSmCg{Tt` z9?tiEVmi^RNG_F*0d(7a;XFTBut;^~{@PDkEpa%116`7vsG}7SFg7_%$IM%l6_QOF zD;*VXv7MOC>_^-yW(6?-pN*d)i`hj&SHye@+ogfp9c3Y)f!d`};`{tyej|zq3D9YL z#5d!!ktEa>#*3Va%04rlXz-QBhU%>zQlV6=gL5NfV@YB{Yvf6P3KL6;rS8zEN!Sf zM4AXH(aZeD{Ci?|dAKBMDCG;&iN+r*yQP;XgP$NQ)mrQSsLd-Dte(B5v|^t!KpZZd zSJB-sOs5<61ay(ALT7ohs;YD3hU`7MKQ~1fC0K+`aIpK!GSkUcDSD35PQ1n=Ii}1; z-_aj)#}G}oqb6}pxZUJa;xU^JV5z^tPH;J>lkTVsK~#yd3&9}g7(a^hbHk*qFnKl? zE5yUnBzXZ~AdWzh6{eG>s=8IKl*Y(YWtdy}GDpAmcHaa2TjqJ!b_Yf@?nxLy3k0ib^ z;q$fgnLUfjk9+?0zX%u!hV6;^mx8itg?3&XEq^VVxyOu+%jYJtmr!eA4j?CwU@kC+ z*+TT5WCo;I)Ts<~V1H-@ay4l(e^U6B`hH;WjbL71&Xjt_)WYif2PjjKVuqEENx{L zkmmy^@Fj`!b~tz*Jd4(u)#xj^m42(@2%Nxs zK#IDgHj?{G`O-T=Phm0t7B>c#sxEAOR%U9U&ceHrqM-v`)0svwMUq}iBNV%OjW43@ zbbnffx899^D7-J-g+nACd@0rR2f{^u4jRixL6Z)i?qP?%Rpg}UatnE~f+WA`eEnD2 zf1%r{6dN6x|Cp})Fy74% z5^%9n>WUTxP3Ibat;WUse4J}U_XTUM`}_yohg>hAomwk&z9J2j-e@*%I@aW<)>8dO z8pB_u>(fg>B|DM(N_xEy1;tVUKyqQCsx7`Z9tn&nhSJ6w1ZooHhde@QR*b0PmW;n zdweQUgY6}ZfeRuTjOlpOn)(45mv4&?(64ZScZ2PY#z-naM0;8?q zMg<+g|DvfW>6+#r zR6A-H1E z{42UG^AGzGO2}xM46^PuX(QT6Pr-W^>Ns{YCmgiada?g$ZOSR|R!fO~>1ps{hH;q|d~a z{LkD!)ECr3_88gT>+(&5?Q3T^Jl_mJAL}_xoFp}n-<42%4V1=x^@-YK*(Gk|OX#um z9%$1VVI4Zee#&P`o%O91tx=wCI@z4jGSm)g53z*J1wEaGnZ=A{7Smlo$G3^O%gbV^ znQIE=R z%lp8-@EF&fYCxO{WCxxF_Yy6F_u+87E;Edu!Cz*F@FfTU9DfgiCV#MAu1%0n@z;qt zAR-n~bGTK!ow-du0BSYw;i|9&Xrw#}om>rL@D;#i77Giwxo`kkn^;J6AxeqGR2tk< zpGi((}fP>E$FfQC;TsL1T2zX!^*!MTzjoG zooI1D{grRb9)b1*NS&Gm4%%n3hZqMnp6W{7q`I=b;XwO+3GwSpN18Rz`hX7bDw9X< zB{ui{$Sr>JAxAXl#I!(q;=?=v{R4(KT7erLB2_(36>W@lQF-!PD93j7yuc$@JD15+#eWx~)KS1J4du}3khinF?s9BVZs!1H2R-rXa>QjWLVm1B{{}cBwzm>htUgWlk z#j0OJJHIiVZjz_|EUgoKuqEHclfr#;j_)q*WQD+wcrF|q&XW&mXl)pd4lgL_@+@V} z>iFs{vd*nX$N8SH?dXeE@Q0WbZm>9eb+a{bxHYuhbgGF#Ut3|5OV}f zH8!#otd>K?xzc254!8~4VLH_^SDUU{E8fx{D-)z;!c~@Ki}^WxE7rly5Q0i=xKTJ< zX(3lbj-96CjoWFL#g<$S-3GqgS2r%r#~f zo6jODMv;JNTfnJeedU;jUVUde(x!>BfStlbnJjJz*Ockav1l9nEty6vh1)F!bSj@F zU6R_VjtWpI-2dKmu*GR*6PnAL`4GQ@ZA1+Z{uvxi-lV(05n+&;PZtW^XbfIE? zIs24dDm>$>G1>GCrWspPST7$^=D>x}gWzC#pXpSy5o(I`hg2X>hBGn@M3gyHCbf>1 znFYcSd8D#s^^DbL;2>o`NMEni7HFU_SuPPe@B{df>|FpzSpmJ!m-&|=*g3*rYnI)z3+c|)d<9mSO=DJuST^1H{H>jRe zlQLX2`@tr04a}%!KFU3#$8!C79S)DIKbTIo*`c|` zh5Q2kEbFB{V!vU&C7bw*y>WjB@TY);59O(154t{6M*tkkZik@pm$h^9V0JIHnSDkb z$6r%5*qV$JKI@fm7T=O5#3?FjbQlKAJsCDX!sk*mz&xuG6M@>IB93}tAe!^B~cEYWDnD^lu9V^^H zQL!cLep;Ykj)B_FtgonO9~!8c#NFI*Vhlcu*a^lG^T?&lW7J;dmEOwqiaOdB4IMiU zt!b~e7N)SXNjtHcY)bwH%j%cpbb38|mu^peKz&V}=U$<+654gbbflFEI+z9^ybmUv zaN8?Nj1Arn&cN#s^@%!g_|uW302!*5@TG#*o`eIR549OmJK;m2P*@<0=3y(&Y@*Yt zO+*&am72=-5w@c?d|zQDTvIw_I?+_pR*BiLDQ?C7%b%9+@gGr5iH5{7>L&Y)Zz=^P zw>%uJ_z|SfufYTB3}LJENW23F*=0;VQ^wFl8zM$N$M+Mx=vJV@m~-0nW2=3_P42p| zRT-cbz+!NaxgH!I*nt0mJHcPgGNG#4drjTd{dCysPWj1nphY`UYL;tbK{vRQgBoNRx$j+)Va5Xyq8Dn0`UFqkSOB z%mm54oNWox;&$bQc11x2G1HNHTeLhSC@n)hm_P7Z_-mq&>d!9VD^UTech+>F>Ay-G zU0`;=)!$d3xA~8gxsy~7??c{&b!$00lv^r}LWXmuqs`yZH_7LvJ^W8h1HOweS6nZ@ z5G&ajS(Q0Jo9G|dey~p%iC&&F9XH?B_VXCbbq%=p;5_U)KLRQ?9%QFxR0%bjso+|o zKhK*^Hf^UJhU?+KD)TCi!;$$|t*oL_eI&G{pAyh2<|-#F@V4Db2}TC? z2an($awl<(C}k@d1~JlCa$H;w1MMOVw2}H8b-21x+Q^*2zY5;*4f1ut>rm@JK-nb& z)`rkrXdwB;f555x|3D5W)ZO6Sp65QMt$634nesCCndOv^d;}-~KX9M$|ADXHY_#GM zY|HPclVqDXhj-99RGiSM59wimX>yvJgl~kC?|h0NinzYgw=$Z0*>tSgT;(#Tw_a)0O zVaKXs&GqABY5}rTcQjkkv&YuLic*K6Ci-xodSwn4&Ts)U|#odU&t6}`^5T3FAFkI-QLe6X$l9&qnu16ZKAm0U{_BtU3t5Y(fZLZ~Pl zw0N`ht8X4rwSSm~zA1PE<`UAIjfY3FzLn$TYbxN|$?LNqpdf2AQ}~4|30VBHclaxDNW4!1cruLfH<XP#J=sUow7UWY2noOxW-8iwg%qF3x)0dm)DChL{YRjBr`hE%MLlN*BuK5R z73(&jtW}$+*VNuR0=jn!4D^dY+-L=sO8bJf0L|`g9mC;2WwWdg0HRN7nOdy-lR;@A zB`jB-1(L;5w(|OH5~9<)Xg;9~S_e#F)g8)f&Y&lN?wyee_KcUAYI=7nS(5?mXQKWE zki}^=l=lFD?+wYR)1g6hvY$WHD*FMEgQa`{xI0WOY(UCY@T3bwQJP1aA?nwF?2|f* zuAw()lR3VxT$A+KK%T%Xm7Td-Sg3W%a#jC%e=V$EibK;)mC3huK-(#F((OR^%KTax zAl+7f0^ki``(PRRZTRnt73yyvNd9-z9m)SRw=_=GcLQ0N*;Vgcu|@k=(O&>tl-^Pp z#r+My!%>I>IE7Jyhb_`ef$NoJg3Z_u=r$_R^b^VG%;v&HTt_c7z2-r9?^%*spMOB7 zFz*7!R5GC2S*@A!1NSR~=^XIAsy0=ALj&|*fbN}fObDR`N^8C056QtsXrtNBz&Ri= zMVXH!G1N|Z1Z{Z3wwEf<8TqxU-%YYm!Aa~PS?_o#S;5o%NU4ULu73txuZ&c!4ewIh z>yab}&dnomJogKr=K@<)HA8)Cbw|DT;bgylr!C?25+IAK8npHmZSIl6J4bY41o4B9o(acs!zX(imY7?oq-ry+oDmbgurvgz7 z80-3KAo^hj{m(ZsYgN77F~~IqEIsD~;YmHuzg_t+P-8o!9MvjEJgtR|!cx8hG=OK2 zLD~W3Bc<{Nkd0E{9j3m3+*5x6Eat&UDkTQ^B|sFXg(LvCIGZF>DYb*1_Y%f_%5k-F z0ub3)%5+7a^$Mzy_KtE!(YFFwoZ44zt0#c!UA3n^TOCl@^>r=m7cAu=yhIq7eNw&= zD@OxSl7`jQFI3He(l~H5nVy4T5ZJ%kP0x{>Y%GhIt@pU04*BG;`9&r zlgv>tGtNyWpP((LKV?f)eQuJi_6dKHdoE5A8|&ME@0mGI93?zq4h#B2V2d(jzLWR` zD%86hlQo$joaHYGdo+DHu!U8(feNBX-V=^p~!E8`z^Dmuqi*Ea*#yXq#C z&tdw5H!({UQr*ip*E`pR=Q7VI>nk>jKZ^QNV2jdQC?E6VHGS_J#wET&6Ev+}@>O?I z{|0OWAdjWKk}Z0z`tXKR?+NwwcY*4ic3m3}7g&HSPAyhD>HkYcr%jdtw53r42u#@s zA0QB(w7belO~3ml%q!{bP07g5RQ(em`lTFKDt7@vV`(cjFUSXtaxhoQ-&*B)Af}~Y zHTCZ19ISuJ5`bn0q9}c!K3baqLkXBZ;88(OZ<0&^qYek6IPJW4P1DZ;Sp?Mwn^$Ag zWatmVRzaTtWKm{`nkuYfu7i}7WHS~Ei%?Cek$xSxUg^h#T^zvVw`i6u=@ab*SIOve zlT6wL^n%sD2C`4u2MR#%JxqqCxD~xq^JLh+(h5ai3S@EmKGmi@RrLM9KyASb!Wvmm zX#wvsW08C*P|mj2`vcdj+8}l(=>ly_RoxGK&#Y@)0e^>o&LqE62q?&!q3%T8XgddZ z>Bg22ka;y$F7(4zagL?Ycls; z&_{O`09d?B>tr4S)pywgTPSVEJ=603792U_x*t%rcWaM#G8N~N|@M7 z&0zs3t!CR~lFrgIVj`%54)OZvHvy;Qjod`~BO3ho@(@s%5#*P#?^9X&|A6b2`8&Oz zIl%);S)+Ezz8b=Bh4TymyPuY1voZj*tErGK{UPfcAfO!;6Odq>mLJ43mtB_OH}1gdw{<-&cX zneI>0SYQ1l{P#_J2^%!Mb{BXsq&ZpqL0zVJJvF9otFeU$Q0+@a`ulT1}knYp@y{u=1ssj|>hw{}k^?56{c zqYKDBX&ux!z@z|Kls;B!Ai^w>(*u~){osVb29!1J5PJy*P%<#1j@|gibaL`vpzW`jXjMCsOLJRiL>-7RI%NA@FJb>TfL7blo0R`1&vWviI z42)3_}XILs*QoqTAT+9epKk8;;h zAN@-Rd8fLnO4R4%1I{4#)_;JIo>|N2&iLQ#r}8pQ&n!+RIxS2lH!>l(z}#3L3L)=g zuTx%2a5IfPAste65`qdct?VgkE4>>)7L#oDLCFl@PG)|Ka#GRjT64g4!Y%C>*M{y( zu469(vJeFI$X*W0>5W_=I4*|Qq9uc}M(6|3K=wa!D(np)pdkBCxWjReUnhJfRKlXs zCt0EU{1bki^nvs(oKnt#kax09$P#}A6$l_~ehmQy>BFT@$%`OB15;FWs&bERs(0v{ z9C9xt*u<&&LSTxj))sP6Q#}H-HO;I7VC#!F!MWfK0vty4OAdJ*aEF~hm8Z4Qe6aKE zpG@~yJHNWGJ{;)YDX{;>#m3I0fpsZ;dg)ae_BpI0QmKtfhHElT5HGLspQ@$wc{gO=DKyenU zyWWuCWJuJH0oe~5rq>ve%zYd{)dA5b<%z2EKoo;S{0sbBQ~Sv&dV`V4S!RL!Ox33W zS)ArTuu)(ChP()_+4MU=_DR{RR<<9NgPBrNCTsez(ID7hBlNs?b1*m7rBa3eu~^FY zivDN}WRdcls&^X;sj$xa=kR|rC81Rg7?*?b7?!60Ha^*n6nH_L0B=1r<)NbgJ~am` zOSvrTv+Zx{DeGS+32c=90RH=?z{a!7G{`u$x!PD?0#x6W4XnO58B{f0SLG2pHa*$9 zjkL+2ap(_pUnts}3`_e~1ySo1kY!j8*i`3$L%0{J-gssXb|P)60`5ER16h=2QeiUd zI16&bdR02$pTkm4gQtMmIpE*~YhJl+ZVom$Ei(H`?&8eac9{ZCPqCmS5D(Z1j0I0p zf8WeKpK35GVa`EX0~A~?jrya6Idb7nE;u>2D^bDBo4EvM6P!xq(EZ#ism3szI$4-7 z-0Zal;sCK~MR6^%>tXK2RHH?UBRd@m8hjy--D?S0DZ3C^{UrBNYOYywvJ_$WV_vJ* z;kOV_lL+x&?k}mim>xqIZ4ElSlpFKdeHdYleEtez^5dErVN^Ka@WjhQE=U&)u}&>A zE5-P8s?i}PXbT5JlK&Y?v{r6;2dikUN$4ror;6Y_=e5F1w_1zE-}sgV|I zjfXO_ky;N^%)Eni z_?_-}snZ!H;RK{?9=azvr_9P zw1jBqtdt{Y@mW1~x7ibgcA7a#jV#><57e>410fEhW4I%L`9r>tKZH|^HS+j?aZYMo zhek;jgu!`e7-X6dZXhwniK1#`@gd{v)Vem+DcZozj+LUo`>_?b5mw5|#ihuTqsIBE z`A*HEP~c$5z(>KYm6@~i4$-bfmYy_zl3LrL#TBQFfh}HCz(kvrP$K`GHZD%h4r_MR zrbOkq3_;7!8ds)P#dND?jl8~K+>;*BO7j+Xh%BgKtVpX9mnl9(CkP8}4#E$Q5i#0^ zERp85jaM;KLWt9eK*&v%Q6*Lr3-z=F~GmH|Om-2)?VP6clu?Z=X-X0P{WQ?&B zaev5b^Txe~fSpWm@Y$tzgof4)X=cGnCxQll*lX}YzF^sqNPc?hogg|NQz$M9I4fbF z(;M?z{TSg)W}Ma~nQ=@2ICDJivv}>En8)S^M9gHyY2A`3or-~vkyIe=4S6V!)fW#M zn3xzz=>aK?nCOHm*#j}31IA<&4@1c4fWdBn?=y_Y*|;2e)eDm5h2#X()fsU3tT5q({C2|186wYnze%Xrc>@Kb z1KJVthW%zD2J_Tc|5=SGDHer^FPa?r{#WCHjO^{|YNoSmT+t8Z>YnQJSz^tQL9ef$=-6Mt}J_ zn$Mr+X9=SuW8{y&jS;L?SNT5w1N#=6#&tyZ#jcUf4~^eqwcYYXZV3Qeye4Bja|=Xjf|?Fg+(;2h)hxND37twvt` zYy1YwJ*N%@OOZCgE5645p~3p(X=Z37`pmckGwu_g(f5P%ea*ekyj|gb=M^R(Mm*0U zQT}3W5}!rV{xoli=b3k0;24p{os%LXUM3^$(ldGsIJm9lx#3ZL^@Bf9qmsoLUmLe# z`EIQzUmuM2^StLgZ2-+_1EgFneS0zQ8_YOKbkiynILo`mHvkIk$SPt)Nr9-m{_=f> z#*6*Oypw#i|9;R7-q-s_>}h%1u>63M#-+i>aNFC)x5KXnA5qR^%Uh)9ZN>5&>O~F_ zG$eF;_xaicUz5+cYLVL+$%MzW(*P=T&OgqZ=Uwh|Lo2qkv=rG|Em@haf}KKv4N%S7 z-ZZek*}^OrBcE1JR%SceLU#14?pdz+Zb%zY$t-?oqGq1jAr_T8wfCqH9%jS9D zOCtc-H1fP=GH$4Hnwb>L^KNjZxl}h8`2kWu|43yH#MLos{W&K-%iG*lQhwW&2SuuI zC;qKSdF^D%0N<6^;7xPQFSC``hm;QdH1k$uurV3eUzkMp^fh<2Et_06z?J6xUm%T6 zi`2+Z=DJ;S(+>Y`NVmJRxO|KIwXZ(8o2wN$S0`@^R%bB?uRCzJcYv$7d=}KUqyIKB zjw^_udJtRpk($PB3EDib%QloQFKg~P=TU>tXy}B=4WMK5hw|qj>5cN9WyMe>xA!f4 z5(BTRal>TfYSf0@;(O+z%hO!T-SvGATxITyksFPYuVlAypWNZE26U7)OP0(Wb`RWWUwF$X@)5|?xO+*GRztxfBXndFvgV-8^c48 z#Nu}XI1$B%VCnt|k{F$kgz_7_nAhP82hFq-*|bRQ81$6UtQuH*&;Zg`%x&>m@F?K1 zN7kQBrm{$|_W2X;xGUyPfG5EiLrIas^T{ZyWTtHa%xmyiV5LeBaW*7J&R%#Eg$!iO z2dUgvFUXW6EYC`0_AgLYeoTeuf>BT01zCEi07ixQ1WafbAu`t>IVfn9D_ZV!VctZ5 zqRbKM5;QC~&Lx7dIF)1NVOQLX0m`=_((+g6rF;kM?5sY!D_&+Ox4Uir1YzbuF53TF zvSkTAj9a~SSNQ*=N9cJmGWu$=A_fIUfFE`NZ7+>FZ6zR{d0^>htr7Es zWL#8C5H^nkq}`Y^R0@3?u+Wysw|_%iU8ibh;yzosvji(~mPTD6znO|6kf(+{OxD-R zCjuc?w1jd}C0Mz^Yr!ond^y+tfyg{39C1fo&Ju$&?o5=1pfMPOMLv6+>;`J{g`NIOR*B-G0lUjuVskp6r6CV|Q6N^JBhT}8Me@D56Y8elQCBJ7sgZ@DTqBm% zO#MJQDSje>_eXklZVpy!f%ZbYz`x=;@->C)QoBfaO>PaWRx`D`2uMMU4e)}d3fYk# z*FtFRzvS*{AKbbaDLurt1poX5;T|0t2HuW~c7 zd_o(9Sb7G2!2gZEL2w0;$tM~w8_m`rzB zzR7CDaQ`^ZIrkK=?jH)*T@Ff-X`6D>u{x>xX4IO>4K(*GbuD$}c?$g+F_$Zfe7QL{ z1FJhgZp=2pM|iur8kMgu54l(RIr3BfjvCRv&P~JWRA_$ywD={T==!`YzwBPwcK6u8 zeyV2VyDiDY-Q)*=>p0HyvdmFhTspFRoTqJY9`izsT-*wY>*eYaxlBsUE4b?+gLeD3?9 zd~-=g$)J)!Wdp!=@d~K$BOSLVv%jv$Tzz7kXF^#c}YZe*4Bbi(h zA5ew<*{&~2?ys^zd^eZwZ%s`VB6D{_^7?Mo&o#lvc}A5E1`lHXRhvsjx)EIThWtI> zCLfT**3<(3x$?%&Dy!Nps38vxA0iJS_0IKudM?T`wSIAb9l z1nd*&5FeJ&qmdA9P~x18#waTZvk?~(Y#Mqp%6PwaSP3CJWS*d6bexR}2^BrDy$Lr6 zPAcCzudZG=?5efMk?RF%H=L$K4pLS}|`Z z7^NuzJ$cV~C*LO7nM5$=b-EocgFEWAf#q==p(hg|4ihb~7d3bdZiCAPSw@3SItu9~ zL2+?pr(o~pak@g~PFM+@K{I1Tk0(QMF`gn5ehWl7Tu`LnKv=+?9(wY=@mAf0YUZ7U z(-(4w%FX3()=At9TQBrv3dBYgJ8Q)qUbBlTv%^Z0@P>mHCLy9H9~f`dvCC#A5x_jr zGJ9#F#84iCCDB4dp;L{w>)K=|odAVHa^AO9+VWkgnm~KAmp7S>G<(XhXo@rb-h|i!)K; zbeVl&BE*MO^mGQqCuE8a`>hafa3)s8O5)|1&q=_zg7}%noAsg!#w7d(x4AU2%CgGt zOu*t13dX@y_1{^>KkGYH3u_C+UCvSrz96UoL_32v)+wW>A42v9z!i@Mtg!M};qwWt zqDrBeunyQH^mH~fF3!hst0!7&fz(x2MN6!%nD0&Fp3Z^BQDTS;d9CHN*qwRsMA^=^2YHn=Kxg1d62uAhj-wCRREfXl|;*|UIXmH z?Et4aAKr--7Tb_FRBkUxtg<@8rD1nC5Q1^{>?3$57RAm){V`X(G~~28q59CT1`0;r ze+!Iv>Nt4^j)9`WTmnskJ`2Gz9_9?_`Nxoy5)+Uw)D>ElaKdQtID!-dqv*va##{Al zs+lzeY|vvCX9zmn;lkjB#XyPj(qU|kMdr82J5?P#CPtMERna2Fo$?M~)w?KRX`#47 z$d$T8s&~n&#A>GNRg^)}&q8&vo1`g`i(T^$Vi~X0_3A6NH41gli>E)*YH8!ZQmsec zmDJXHPc-M9yz7~l)eqD{wNi_WDabp7r9ILfX%SOl-VrQ)96VeJs8PN0u7Jw2QcFiC zi}J2!b=ImVMKUjI3fkElqF$-2+8LqZysOp5X-^bQDOA(Zm)5-BGCPCOPKJ71MKk*3 z{aU>eB2UU2AYD2d+BffVHmm+BFPAE$4Klo)PW|#O)@-d0P%0#s=o05i=K%V%f8M3) zno>>PDDD9Z%C_ib|GfXztkif2*dhEZY!rW$(TxFl7i&4xZqiDj5lY@@=qA-dCkN*J zlCxetFI5*8qs1tJFbPa1whzktIVY;v#COp@+sC@q9m{7ZHhJX-_Z zlu*av5V}G3pet$3G+@<-(TY^aci@~v5p&IGu<$ILZU3%wkXcfrs=KEgZM z6Z8{mDg^I^;OisvF4R6Rt>TBXpV9{*_y9P=dIi?8qw>zzE&|otF7_4VvYVd5wh$fx zte-9KJY>@d9fNFo(Hz~HT`9Ci+-S%Kll}o+Sue092vW15P%zb5{%+p+T0aXQq%)aN zDn}1zP3VI$c^7gYX$dq1$~;LHkvz%K3Dgq}9GiEpwW6&QyquW{0@6+<6uVFy5?Z`@ z)2%7L#&^x%(=^iJGvj~R)y*P?+dQ!S z0A+F8RYnJv<)9PpkSi3V5L)jv4okK1fZ*aZuFG_SIu7GPGFn|?T$~<*YuZi$H7Yd@ z%ff`X*XD_mVID0kHCDirR#1?_L|`g24#{+=6l^Q)B3e*pT%7G-EMN$7W%u~k}3gDJSC z+c+!}Q)9S=fZ9%T8<(a#0i(~Rp=(JRHVs@@LsLA)#eni?4mxls2>s?UE=jW>$Z~?$ zxHQ9}o9Qrvpz z)NCgU=^aem6)p{t&>5XL;4#7J3zu5)sEocz@*&X~ph|82Fc>WI$8b8gpNakR2D`%mja9ceYVuN>MffdIABj0U1kyUU6w&A6yKrWgoYX}HV= zOQk_KepcP0$EjFZv;!hR?qkmL>U(U?nYo-jgL zA>hsM{lPNna&pK6eD#=WhAM_j6SM(ktcDB|jNKJ=ItX|xuGNsh$r?O~RSrLVB57-Y z#{`St;&gc68!K63T#LqyUH3&!TkV;cE1coyqQydr{Jn~XQU&?O!_&3p9CVo73|7=rKvb$tTo=u6sbr!u zrask#Tt%*kd}#@jucl$Pq-4SVPVOw3?TwtNaqGHfi17I%^bg zv;=;yy!cprJu#O0n(^`9h=s^IdELJH|5MKJS@iqFo#3|MA%Oe*o}LOvcnjqFfcO9Y zy6@}#qAch4QeWdzkO-^q`6Bf^e~`L__X}x8oD-b5~5m3T__ zU{d&3!Yw(dp{-Nb?ajZf{e}LbYm+u&H2Ebhb9Q07ENN(!ecgc^Np!PEp_lTRb=+2Q zEzC{R)*Y%jPoBkhW6J?G#VhRrYrW~~j?`$Tv4RFjLzB?&k`XyBkV6&*Z4d-Bc2N(C*P1y6mfe1-lWU+*2) z#L~r$Gn){KY(%<>V!?t1u`4#P8x*_OUa?=5YvI~WC?UNklih4KC@2<0tgBc8c4Ncd zv0y<(#a^yg-?KjVKF|C9{`h_J$9(6UGiTbF*~#wA8En00e!p)#3)e}0qxCe+pA@RIVBji(%gDhe%_o+#mFMLkpAxn<+k_3_dOXO>MLxA$(QIcnoO|{#&xvX+cFv*O+xOXO z*=E^je1__XtrdB*;fk3gwl&=G5XX5x&Wk}ox18lPZJ&Ty+hiW%j=$i|No5|30^T`;p+;3`? z=AXe1ao%QHIv2Ct)0cU9NT^|9Wu|+TH{QP|>wv{#0Gq{f?_NPhflJsUOrfJ8_`=@l zc)`eFPw|^P3kr#H?Pey^6R11z(eep(mTu2%V!6I=^K2;SiF3W9nyN=NrcP4_>7mR~ zmaBTlm$}^8o*D0G;#luk#N2XnmJd)oe}6d6mFL{<)UjOmPkD8waLqsGE=92M10Df=mw>n+F&K@ke)EvguIv01JAtxat0!ToCjJ%EAQ zEEMwWbY>#e6jxdOt>dh9ZNV5$JJQP-JLM@3WY|P22|X zIMtpS$VCO_)q|bnbZ?w!Wh_0dCL3$-;uypYsg+k3)f&nMz-t_#?SOTaZ9KGEZ*D~p z$Oj&9PNm~u-JOn?**n1zTy9fvUVT(EjD1dzq+Z&`QbqK7rZsmZBrghyYp{DAdT{UXR+Lvh`hBU+H{3eUMuat+m^!$ zJIw`%hheQ<+{HNv&`*m3#fjaV18Z`L92=2inbN~4iAKb zq>`#GVgM@kg8M z!99Uj^aZ-t+WFd-nq=)^tyzclw+&+RI;+BNaD##^H$~?Evu&#q+{%h2Y6rZzFGZv-a`t_EQ`2nuW5P zsQPF-87r;9+;8c5tp$x^8Gq`!^|ncDV6;2c1Hr53Y{dh`5#=LQkaoBJgK4)-#N}t@ zwGl+G1P`u1Y>O;kzyakPU8QENMywg8iPbKI%jtTU$JqR6*wpe(0Yzx4V3#_U+RfJK z=9h*p;Aiy@%`5dI^*yyn+e0_TaMZNbYN4b~Zm=dVPEhZmbAzKTMd54KA>aZ$$5dcy zV!jH#zeIQ$HH4$|d7TAy>adNO+O)^M24Azywl%Yzu}#CJb^|y-=U$ld;ss%!oLcyk zKb_u1EvA-I*Qi4@!4x>Tcw1hAKpf`k$zE`#JLOKq!X^X-mAAAHH%jFx77+WvGmy@6 zRgeNMQl9BNv%SC4pKYD-NWJF@kp&Kn4W2o|t+0m~TMV9s+{Cq>n8fd;Xw+#s zs@f@~%5&hoCD=I0I+^BfS9zL?$YHMK%nW)gT}r1i{kWR%J*`prLuVa(N7G|%ta^^> zu)3x0gyF3DAr^8YKX_tLM6SKLX{J`8nyL5=_JsVUf}6ukd3Y>*JN)QrifRj}E5@3d z5XF?ND{whZntZe3i)N2un5`SW^2y`m43|BteT28!%dpwywx>P{_{*^bx3WcInkt6Q zy5k8$b-OsDtlxDVHFGs_x(|k8bF8f+_Oj>NpHM;E{JS1MRNvy9WzlGpRQ}3I;8?Lh zKh!kSQe{19OTpl!$jO=Rc|@q;KITu;D^-B}UdE=3PFef2o2jzY1)34sDcY^NP}4?h z5AHy@M}VTIJ8BzmDnc_NWoB883}xmW`D*1-{+p!wv1W*VfhipyVz~$RJp^iS%a*Sr zlvlH)S;ytx${*@w+Qs@YhEzjCW3p)vY|Q6~haMqn^o@CA`l;TSJxq?WjfzRC-r9!x zo`!LT1Owc1Y>BkH;8V#X5NvoGSL$1<(iE|Z-pYgOqZ*+u3S8A2b<=g9^bbw-;Hf&K z!c)P89QC{wc(-+pW?OSUCq4ZL@fo%@Q%F}(52!niB`i1ov?qb^4|F!6dr>-S75owN zc%uD|GaG3HUh3-OOCC=%{}^YmLkpg4W-%Ob*7FGYKXFcV406OWBUt?UoF}@*XlD;N z9T!MnW)g6{^PYx51i5p}Aq_J-$ScgB{|K!Sf}}+}qOKW~V+f zc-}=%WY|&qy?LO{uI!cFLf$odu5y@my~zd3%Zr`>qI)qctfo0;GGo{o8ddiUOw(`2!U$gU+jWs^tWxF93J4UcvVWHgS54*}>VJvdQdFWw}bED>O#iByYy4!ShnMfdP-Sec(F6Bi1+evyO&b)*g=!;?_Dm zbCBPk&P&*AjkXWq-Y}k06jm3uMYb{bGTheo({|8C=xdp;*|s~lldR_us;#!KFs@Mt zWJhFZrER2*Wi>OGDf(##nuOSq<5?EQu$SlnTN6`+zPF}Y;|)D520I)~|H)r5AQ ztJJNPw1QGTQ`a@TwASO!=E2Ms*$O|>PgFmXdoudSdP--?K4c_iH&bubS6EjtIAoJ& zVcl{zmHKMQF)Y#cRZY!qkws;_l&?^VbQj@q>D=ULgThLg>v*hrg`u-9UpHBwY0#MS zU_&*2lO#?V}vq#DiM$c-0uJRAC*qTOm zlp#z`OY2L2OCPO`!q1j?_WCXb&p9WpB`|=OdiIlL=DXS3q%)*((j{3*cp;xvnoz6I} zR9o=E<(@sh&7JdXyDV!c++u~NxJEN`ALYpmdDaeW3u;8jSa$({$0OV~w;NHJk{Ic5ZS8DAI^hxLW!lxf3lC3H51g(G zJS67Bb+BCl2nIN#TyFsB3AnRY8gD`d;tuN$>Slr$IK)&qWILD_KMv;-hM3SiVifBt z0MJN)T=iX-0L>?8I18Q(B;i)@uIowxI0tr{pNFuCV6wfp>m#7KDA+Y+s0lR|tfShx zvH;B$ZgUnpUGD%k5)@heT;aobF_B9KVPo$}^cQnI*A~FDg@o$`Ts00ak{StXS@KM- zcz|<+!{Bx$*Cv1sM7`;q##dI?Ii8MsxjK#j4WjMVZN?>V2nHf5k(&Krh6}7;LqsDQ zNXJ?Zz)im+AtLN+gX?+&NAdLI%zn#z%C&)y2&1TZ*wt<{-)!BeJ&fx(K#j1T3r;YN z8pAhd+R-S~-{mJs zMk5Iw?V1c=1hE9Jr#)l`@R!XcN&*V1=Nbp$NaCa2Rmc;F*Q{&uVLRGPq|>f~!MsR} z>nDUG(O~zEBX;x^5kDAr^3Y_|AcDwc+^MsZk%S*dZH+oY;!Wo zhktG{TlgHx9j>(iMi8@DcWhk>eSk!?`*cAvTJG)o5ubz#8=Lj#WmRggtVr#jN~~Y4 z9dGJoOt4m1`q)$KNseodnQS}v#coNcC8`gfEp2_|+std!<(B<=w{4~Qo&7ub0U1l* zbLyP#h#pC(1B#rZIS!6)I)UGvccwNLk2MNz5)je~#~Wq=>z>my33Y zFi$r3uw~dj+cnf)hk?mt-TQkbp)RQQ8RcSYn68<%k*N*5k5*Ej?Twhm%o(<;+b=N* zbwy#rw2Q4}hWXY!%W-@QFQlvKPH>RZJ+^le>W)HRDo4_<^vCQ+EmCk0eU7;bE~I?j zTlyrS9w_LMax$~TI33(a1~W1AbT-53{?a!IjuX_Jre8&$fGa}IQj3_cOg;C2{z-5? zK|J5OiQ?=Dj<=5Q&abT7J|GEBJc!R(Pcm!lb(jEVBMa2Zfk|+Z!+(W!p)=QUo!QE| zJ4uqzK;#`@ukWhs&PYl^Ly&izvplD^``X|n-e}e`?ncQ;Xc!WGru*fuXWh$(CLx9( zUeoTd5lJYAKsEH-s3hd(Mh!+$Lx>!3E3ker8jOg)S$FDg8;>?S-ADG=kOcW%wfN;8 zqW)f=i|@-hQABx!$V1eOT6#_tgu>>hs524~$u_8XevL#7zK$)=&os4mPs z<_GH@UoaS2J?y6`$GXro-iEDL?C0!hj(d(+_8H9D+j(yAZA}kbL-1&J&bG;Zi<;-S z!t`?gRX7-WBs5h!1p649*-9)~;Jc)bBi3=u+08wqh-Zd%)?ByVH8uoyzd7K8d4K~u zyx0w_J7?!$6ptcGDV2T$_%N)E1FgfT`SweW9LH>yW8K}4*?=E@SKkpF@eeQ`w90IY z?Q5vMFoV}&lik|mHq;G;ozYD)zcQ}0)Q4@$_3eLCe$aKVo$m4zHoii=6?Lc{+8*|9 zrrlJu?WAKHRhNa472bD@1Oz7OtPmO0lu-KqmTzYdXEgE^qe!kGrjzSW|lyW6iaPRC%^4c1*=JQzkn zxQ)#-Y=U=0+bpZCL-AsJG(F9MoPFJ`5B+Kxqa$5E)H=(YZ2M|^00%ucJKixXS-14? zVAK?^VU8JdX@hMP)0JMzPI9^zmf66n zYrWLfVUjIbj%)TwPBAknC&^uU$p(ib#Ywi2)P37#dLt!tZe-knS8S+15T^-z2Nf8A}ahYr5y27>ouX|4Nf{eSNz&XA9##baF6Qt7sfPk#ox7 z4mi!*v%k%(-FTRKk_+dv3U2Y%OuTfu3q6DRv2oDG=Ff4ulkf8O?!Cqlo`%E)7OqN$!&+tvQJXb5R@8?hwM!`kglJM_w8@I=F}NuuW<8iLVrw zx+zUTLCLO`O&SMoNo$G{xz1bCf>FpB=jC&npYo97 zVUrtfYThT{>X}OzPu`l=f`E(IR9n*mQOFJY@iD>Q%DPOm{q4@gw)e#+CfK>cZE4ee z2-s&Hv^#CNkoXR-K{>t{r)gZiKP`-S4I72_r*$WuV6MY~v>{B1z@8)Z8)*PiXXeveh6#3m%~QNWhjpZtYjuV%1#ItM>q!f$M`T$!)3dZOMlN#4lF8o0 zat*h7&yrb)plI&#ULK^v`xS19L?~?R%1(!pEjdRBzQkovcxs7IL>#r_ zcITHgf`%V`e#vY^7#!S@3rj{peH~m#*^);DaRv?sT?UOvgr{6x5=tD`a%oqWj6k8o zona?B{&m&o@Y`*7Dj&4-8y~jpN`3C$wIw^I5@T6T*J&wTk246F5`p_}#S9dUh;2?c z@ni;C*x8*oWg6-rBz{=jw`WX4u?V$x`^}t&#v#IGaHq_ghMEdcZ?}5xG}Lb{uOk7u z#|)f;A7g3xmY3LM`O}uxyuL1~|@lTG@ zmnldj2porP+eUAixa~#R>YVmv9{~wmMmI*jaoY)>$7? zkcqIc?rH!!0yTE6`wWQ)@CniA3n)juUB@7F5pcdZf73&s#OX0`dDywV6UqBLi z=v1fs6TnXh1-V}R4GLhrtN+1=zV5a^QxLgg$JFuDkheRq!whsB1-Vr}58r!#7`?64 z{OrBrM+c@j+)q2sK#LJE(d-`Ic?KH8dpX$Ibp~<^8#4+c92lN~N{9@bt5dfb=m?zI z{0LzwaaQZz-+c!7Vn9vZvV<9ELhe6}=s$BRI_h1&p+3=^yep^N_w_JOqEnkQ^myK} zsb!nbOxt}mZ?x0(V%}8rNZ=(+c3qr56@`jEIS=ZWXxuL#(vBeZo80vmPDO`=1k1Yb zE}n`a{D>->`_rnasIbDF8kvH?l8dyiv_>f?I^YF+@mZ|~%l%i~y2QFS0cjK=40BXb zt{>4UD2(_6*1t_a4qRT~-RsYpPA{e1eSy%F5d0~v;abov1w{o$&~52q1s%SY*DHFH zR{X-@W`NuY5qFjDtIbnTAWU4YCow6gwYOdON#W}bZ;=8kP88}|&?*JBCFa@OIRHix zgbDg17CPymyX^8bSjZDk9PY`trXeXoEO)pc+?j@8n)qt`mg#PHZyGu$Aoc3Z^;a%F zzLj`-(O%@P@o*ZtBp~KG+~tp_fyojk+TGykG*s{y3Dxc6-0PUO=}@81w#qHn3Sx6|aS4mIkJ|La(Zv1pz!c;{wKp*d&i?C5X)9cT z{s$Fk=}h@;EiJgdUgYKuPC-Tlmw@`@j^92#cLd&~FNYmLNX6N{I2X{*4M&whhAYOl zu5Vil@}k(Qtb6g{DM*7l_I0!|kD`#n>R_nNil5SL+8BGhX@Tm!`5cqGA$s!^>zS+? zx*?2o=kUG1ZIf?ZzIA(U7k7L26qJQxP8uW3H%zITx5m%THe00|$5TU8UQ&@}d`_Pt zTySgsl?_jv_cxs1(82w%gip}^0sa$r$_w7wW`ks7i>+(B+|*GR<_LU?N95;j>gybyb1T=r_5Jom&V%OJc364QPeC^1ZHKoSzV3%7rl9B0mlLO>O#&jDcC%BbBOQY2sP**e zC|4M4JwUmy0*oh!^Q=2?=5&-ABAU(YvK2FK`HJaCwb#A4Ng`_MO*~{=bc;kZ4_tL* zFfQMgiLmZLaB;0H9dc zc?jnd+x4#a%RFb5$+hVh*lBeIUExI{U27nWf|NyV00t6=!I#msUhrp8;2HwqAozoWA)HU_G`fV>`CRsCT&cgn&1~1*|9}kFz#Ba4 z&n(v-9>AZfsGEGEH%gZVz&v8M-u2}dSYdai+~P&L=`TX)zIZDE%5oSyrivgz1tNsVT`Fzg*V);NEfEr z&oW%|I~9cy_?^2V#CtL*s)K8kRAhMnv_6O3K<1JPC92ESE3KFxUh6c`^n2Mm#p6ro z-eNClBWV==xTPXru!S1Hxwck}3~hAJYx`TvZZBzK#?I0`BDhQkve(OMADZys((x9w zSN3rmcc^2XWKK)R!e~G zHU3BoxZT|=hNGHSn4#2NoD8nPeu6h$#0B@P7!7~P*jY>#Jq5llgI@-QOY2oJ5eY}L z@M+|FLWOuPce-a~SqAqs|Cz`q(A)X7uP6SbTY%`=*^?5_J{3shS!VcDJ1m&v^hL8doa zZ^KdwuU=i{iMUOTx5?opwaS=fT4TOwX-IWoGU%BMp1h{&WW-M>W30L=GeaTMZPpd2 z9%YNvLO8vQyRWS}9ekfHq(kUM@DbS8)CTUt)4-e4@O4$^YaL=6I^&oq`)FOujC9$4 zbz}T-UDY+;I<`-yVYYn?zAUY}Dt^uGr{?1d>q)EFo(e745`J2 z!yPngXKe0){3n|}vfuC`id&gcHF!2>KU#U$J1|zy!8`J<85Oc%%`ptSKQm8P{-`Z7 z4WXq)JNEp(afs17D_rK5=E4ZgV@~V*Nw9lix2F=J$Pchx_{xTx z+uI#r_ngi7X_{)q`p$ z1f*WBY)<$+qhrC_|1|3`Zv9nAFIvV%JFc?ap=*_4h`8qDu3oPUL4m{B=C)NPn{^>m zWBnm!4CcPvs1ze&Bg^^T0zuNtsid225a-9_BIi)9^k4m!~v+t{bCh?DV39a7^+rbS!7x@?jg%0>r$#r-F(B}v>%35R|#tnT6 zsl2n8`*;{P_gQ5)65fSBzFcM{2>Et%>@`0#9=CHj&-vsn*zGj8{{_@Wbi|Q?A2_(H zFM%%dbNIoXW8CYi$~Zz4O}J;4=R*lUJCkao)lyYAt`~mZ1bN@3U>^uK*Z#a2@)l4p4gEMP z1$5tH^D)^%`3jahNZW~&UlY#zrb_K3Zq zK3DFNe#=l9IkEQXR8)5cey>*<3N0KJw&7>~f{hL7O6||=uBt8i1Wu`YIs-*)aKtm> zyjumkcD5>#Z298sXL6}W>3^d*q2Xz=Pv`^Y084L-E7)B4TY)jZPHwZD0c>M#Hh$U? zc5A(U@ySQ9%Nobc`1GR5PEOG-!0teaxZ#C>euT`-&AAY;71d8<awD@Udu~rCWyV3q`HwUVQ7gs z&RzXF^^(-jYjn}UQk*c#YmC$@flPf+bi3#$Y#KFt%`RCdB~lL;T`#&?blGc3!X(5L zy)Nl5ZQ<3<%d4n5^>N(pQhOp-uO>MJL3_*(B*#JCCj!aFf>Ijcmw{wGi2KzdM?)~B z7I_SU#zAB+qBI?+1d;uHO0&KCB(zS%JA=segbd?R!DK8b$_OU^LSA@X2ss5(+z%nw z36LfcPYWgW&~k4>$)5xvbK-XqW97Xm9y~Cr(R}l1SKxP5=L<6#+0Q5g=OeTWbm}rtjgv`!$X+jcxFFxk&g_QG)@?h zi0||x|AtE7+x^K7kWtM6WGMVQ!c7N|8b6t;=x)N8g!+m2-~jRuC~WJ2WL<&Gh;Y(C zvJ~RvAhJjOQm2e9)m3q2rBXa+5N}}ImOT0Q#SSLLNFamtPp={5Ug!Z>AtaMIP#ipzZ0{pWPl!)QNaQXJCG!y| zTrr%S4f#JDPIiVUS9>IxjcOz^UUj4iMGva?z}D_jWH-KvN0CvW!)G)(g(%hHIityy z5Um(ZHX~q|1dJg&LFztZNC$#Jh#&k$Ci6o%ZY&uGMS$J?IBJS%XvK!%(XpVbY^a*j@rjoV5&>URybg~T00Y}XwE5JOkaMmxw8!(GB z3rlUK*&N`$ym?@ry2er4-v2f>h>R` zh8LKup}4P8>c@wgjO=yixv>Ewz~S$cIz$-0Erh><45Re4EE8hM2wu2}{QY2MD$ zGs)WlkYG5 z;5%Y38O|r|vX^WQdu_A4q*9*}Z`hkYZy)(PA+zC|`^eRVEFF*G$Ye;ikt3ZxFqk3| zY9-=9`^gyu$QJG=KQv8bO5ncOqGzeki^_^_NjsGIRX>+bjr%6kC;XPsIW=F}x+GYp zz^4z8w;|u$VloNp_NJI@!uMV1A#xA|Qx1_agiOz=4v`bRA^xnCyh6xS+@Yi7^)H#|kQ6eVJrvs8^ooPtRaVc98ixUdw<%=r2#vO58`6mps*Ae9qGc*qjoif?tG7u}aUnHM`s&!@L8n8k9ql_%#M?=viG6V{H;u1NV zpUYZbC6oAY#dUHt5nqan4wZ~bs8#*Us~z<0_k>^3(N0co;wv z9(Y7rA&a3E3+OIkv>Ret) zGW>8`{hZ7LJzT?=@UY+XGtXQ7pq_;hn|3XF9e8zUYA^sE?h3>4Cci&}_Vf!=#9 z#2i%A+EUyMQXg(9e#UdTO|79WAikoFIEnA06CK18fZ^mCbrKi*^2@67p5j^1SuF0~ zTf7!Doaik+3xfum`iT2O^j05nA5dSfuec)wBm4e};lAPnplocpKj>nq+Y!i0()h z?*ui|hKj8OEE9_!NqeQft^SdKs_%RCOXwVTC+@XZyM$q>Wu+!AWP}*D6O>xGP9w$e zic`ko<)g$)#VEb{6RZNNsy|7a!o>J(l-R_NQ0;Hxx_%IDnJRXO;F-bopDpeVz=AUu zh;95#6S+_fkKsga!XmL5ngiqN#o}R5ro<&;Scd7j^d;iSsG-bObO#nF7vuga2`&2W z730;yizumIlHe5)S6=-#?gHY_GI1%d=UAF}uK?1oSSfzPuQTSY5|0p;@@FwiR*A<1 zmpZE53C&^{>WVuv)x>Z=?Ea#OL^DRMi?W3=VG9T5&%iC@xJG zui>lID@**woA2T{wO9kQ8^%Yp;@kYwfYyoq#r#8d6C-X;2um%c6nB{w2SRh1xyLSX z7z&aptKTN{j{91DHtuKK&!U1-Jq}nej({F+vR(``FN24z7cYh4pI8rLE0H5Nh!He0 z+<%cPj)! z!GrJck8oAZyGyy(`z1C4Hd$c#K}jQG0)@BoVI_qxK!|$dw+AH+i5nCSIRxZO7Tkpo zbFFydAxQ(laJn5{cL)T)`O^kqpdfsLkHWs;NU21}ZTe4p1GIG$2?C6GtEp^rlB3KFxs#^6`y!{5v1ch1IH$*qFxThPWx4_kjZb@IrGv6&~jB4PsJQwbWc@5m?NsdN`=D+ME z_HE3x59#__uPcMHd)I6{=S#``6)(jW6bQ$RxJ9X?fv^GW2*$~Ph;2rk%2S%KFOAs3qtC|i4BpT4 z?&%)frDXCTS>Wsq2K-9g{>gqaF9O`a<)QTD2t6E!rEq|JHZP$iIiJYx~mc=ba^w z=r5ZqTkW~8?TJr-u<(N8paxg+D#z&-V;pc?0yn%lPiS!LacGcAT}wRtIEWo&Cu{Ih zAPHOP-&(L85V1gmi+Kv8&$HliKqwmjJPswX8G7NyC!iU3t8xDmAW@?K+l1!)nYNHO70 zAdA9r_({+&GW5sY01*3Cc=Aa}gC+`ni9u34<=yhyCt8HWUrY>6YB{m#nABL&=SEk; z?>%^vb;G@(JI;k9!WDXj0iT9MV8PFMWjl0Hm^=l_?kjNIDX4Rb&IgYKfiDGZ8TrYXz>G}H90MR<1D^3Q1rUt^S0#)3;NqejhVJ^$fY_% zDvV__A76e-9ekq^<0hve^G@h)ZpJwLw3#Oepr865+$gw3C25lsVQ0O zU_&l1)mC#)jlY1DurLc|y2vv?8?LETg z!I@y};idk_48yN@sY|MkxTZ(au<5yszp04xO9a0+>e{wAq4j{UQ6E#@j2Yg{{i?&| zy!(wGbB8{uS1a%s52T)y;f+^#pba$IVmW4jBpjOY!Hi2hlKRal{j*G0{-eA7#oL=c z?3mFfbC63$pj&S&t4@?sXQe-66jhP2dt>zMhkehqfFnc6F)|C*sG)0>T7 z(dNdNJ~y}BkALicBuU*1&o~E7CYH@JV#PTaNRiqYyoDz%mKEsn)GLw@ap;dVw?fN{ zpUgVu)-6xR)u6lCCt0Fy%fb8aUqh{cg4WHUi%riWb zy~Jm(KtYY^Pc(S^c_>_S(*hY@eID9xKn7Oh9H7>{ZEH@ql` z@-r$!vkJGyJlu%yT$9xGqolu^jnIY@@y~0L+CJ5)9+`!kkKw56lDeW=x%Z@xjkxe4 z=$frrk%7xDN*Z`~mCZDGGTtMUvAwce{1H2cV3r-3wOvq>2Q3Rq`r?? zADe!6gBicQE~)LSyHl~HSGrM)rNC-7z?d)lJ16$q4F8a(t`5(8w;r%>bk`JS=*ap* zU$nfTef;8Xr-I7#9{5C=BuZ4%+(nkg;unxmxHaRG3I|+*dOo+5OW`nT9N@NDnI%fU zJ(pjWM{H>s*R4&z!;-%yU7XsdXPj@xd!ct8K7D=es?8~_pveoTghaHXT`{h8QxYm% znS~YD4hp=>?0-mO@WD&al5)8$8jfS?pkdWMe?C^y%yneeJ zL%$z)L;rC8qjy|E_A2?|?S~)V4*3$(xNAY*L4)KI=;_gY8`N|>m~rdm(`}dEF*Br> ztoZg#D1D_uk%i}7h77}8>C#SEdl@q9q1u#*i!MtV`0ST%GW~vZ9iDqjQkUGUzL~Kr z-*|6CV9(~T8RwQH)VocdpR5tC4F)HO(bmJ=uKZs{TwnNK(-nM@^~M`{v*axlpS}Xd zXiR^q!BtnF48IIid{xq*`G5?&x-XafW=9=at2W(d^s^?_ow9XG`))^tr|$&ZEqr?S z%zq3QkGTrz{-3Y0eOm2T4Ni;ujU5jm-K;~s{7>4RgY zPM#dxB?YN&i|-A7y8R??%ecc0nC~jnd*a`2{Lf-n-vI5uES3c{n77z1%>1%FqT=X& z?VI*K-v8Ce$duv{pBmkLCA_huV%q&DMZ6{ZgC*bp|5$RHe=PacKbDMrd3##H8*mFi z{}}L)oBtYcDiE9h&wy9`KL&g$hWf{V-*Vf)fbl+%7V(C9`TsW5@4VvBUxpfWOA^(b zH`Kx{pYK1eb)~txbC1632A&+Za7OunbHRNp(r%7_+Vc9R_4}pyCOqpFlr3Lux&;E|Ln&$bZ&R@rxE;dVS4LSN3rDS*76I%Z{c!k9>E?R}2XW;VlT0E(j7o0$%9 zEX2!>m0KwsD*!YuD+lALJbIJ0#)eHidX=@sijM;ltjy|#KMJ6Pr{#Z|aC0FrcW3Dh zcs!3<$hYXQhDWcncI)sF9?h4-a-f<=$=RpWxREy?OZHSX9>t^M*$b6e4oEOVDZrdJ zD1M|^qQEbB5?0j0bwxmGqAFA1WD$_!Rn71^p444+Asg=kl5mxJk^(>GQBBRvY#inT zC{_c{+JQVWsP|^$l{^}zU9P|dfCRlXjqyF7q&5PJ7FHL&0B&h|;zR(#0_|-jUg`_t zFE!s4coUEMgJW@glSjieKNZ;D50FZ;Pl>w&5+rFt@d7_c`dV#O;vAlIK;08x;z=De zuasEm5Avz%FG}1AkU*eG!n6H>`B<%2VVWo1R<*-tfh16#CTQZZObi8&)DFYD0SE_Z_hjIwywoD?hjbiK6Oc~Jq+ze}eOku~Y zW$;dkN6#|fDe*TRIWm{3aH|kNBQn3iYM)0nGSk)A07!5mBLJ6%fV%VyhX#M(Nxd^# z;U=L#5`l9XJT?^M&!msjVHJ-|>F;&;P-s#s(K~irxBTITm6>oQFS5@ek*zi3I^iJF+R;?j1}BAs z$VOTudu+jLfh?*=KauaQ{$fj&hT}WD_)^3tfDYlBF&b*glm11Io!fpwBJjlqind%v_y zmiEKBwPBK)XPE{muK^T2H_w(nXR&Xcq*lVY=2R)}QU@C4xoM3Q&*Ra2lU9lu9=$Q< zNbv<8EjDseTU`L33>T%i9gkKSUP*BZAOSLv*jg8CPpNN>hux3*0|JZHQdP%=KN)8|)HxNtu zdm}N{Gm?J7ua-O--()1c1y$yDxSmteN8oKr#xnqTw=_S=ZilxyC5hf2?RzpK@LQg( z%ItkI3;CK%x`b_RNe5lGK^Bq%T zd?O#S-D5pryv*SGn?XTC`%Xg@g;RJO>RhM)WW!rGL)O1*4;gVaAn&8PCAwy~^A z&FEI|w&S&1K=`H2rTlKj$9de>xkT|zkNvkoNyC+_2K<R7DbCFvGWtN9=A?K@AZ zqLe!++_L}_4bVBWf3xAp-I7kYxIp6X{nAt*Z;sCtfVRW-xuC7)cF^`#zE+FJZ2zw| z=XR*TDbTYEc028nG{ydfk~;q?Yf%WL;`P8^-@;#d=7FBQh5wf7d!eLvjfskS>R6{} z&-*hc@WZ{5HhB3CNdTy9z!y!m<5$sGzG!8DYrf*^Xui5R(7pHSg{Qf=)?P^{?ocFY zE1ys#>ErVT3b}NBG48=hYU3kClBQ7gy6QGq#z~rB@lHvk=%1R$?fjp5@qS59 zpYA7LnF^t}2Y3Ec+;$l4`nR~yh&}zfRIc6p--b;5R}nN}1b)3s(j2PJ{L_yAsd{rf zZTBx-^X2Vu{_cO9@b&IrO$b%T9rye{P57U#7;D2v_x$S9LU{|m^+IvvUP&wH3ci*@ z_WoNY%ijO$xw9AaoK!XB+pW>Q|5a=bVDDGIdSUxMC<@i{rU}dh=HU z{kKY|x&Ntvw&Bf-Z<&$%B~EkoG9ivjy(r{twpR&G4St;tDeGlV z&&mVGiWxvR7(1jdHQ)d^k1YDrc|P-_9MhQ~b4Qh%{=|k`WJwg>KP|)4+h8sWRNj*> zlmE@&fpQQJR?o=zYQ@)ieA0YMzQBT0vH_2BOi-LO;CICdpOS#|7b8f#_>Z*Q^p7;?4l#ptV>Ogy1E7D)-Oln$_pfr7 z@Yo8qgqOO>)?d=q8hjTJNdGGL?>5OzT>j~&h_lyAnpH#4j*i7BCg~tti+IHdPv@gC zNyWlOme*!1ZIM(A%Z<&ZJMc7VnN;juWc_BSjeoXG$|hETKhai6aiZPM75Zf+e54hK zX4!)E7hu9{og^n-u~-zF)XuvAt|}jdd&DLk5Ury z$I*Co93*?sVqx2)IPWm}B>d6s+7^msG_TNCQ21M0U~ge@dOKjZrak&#%(Vk{o_U%6 zI)#_F2eyi}bpUQ#`j*}gckBS%o#wUr)8Kix18`GWytX5-o6|3Vy}Ki@cbhf(5(+Qv z1Z?pg-yx;vHRpjm?|%=P8`p71-cb z@Jm-^Z>TZoT-07;TJuCeHa{x^#pc3`k1~E&hMFY$z5k?Go z13qM#Y>Brvwa2(t0Bv|s7Q52^!AuxZG|koXwUdk{?79n#QT|JuI~>=jk@Qc-6+bx| zjR^5~7Fs(Say8+q0M!T8KwXY`k;9b(tYLw9_E)A?`dq!$aKLom_JCoh05xch^AK)i zj?=f&9@FIOhMLCPUDJOtOgPRIum7M8(T&$PFc#NbR*ranzus7cZM zr5kB!?P@YL8VwB=P=O{B_$$7e*(visJZp@-s`53ASg|dBGN^r3W6Y2d8LEW6eJ4Y9KPrNx;t~`>`vc3yE{}! z?29mf4D}_VkUmHD2|d})%u_Zbj?%&|x(A?PzC4xX8j-6jNqeL+1m&8`WAYKv%-Btw9 zY7bPav*B^95%xG(9M}Uz40hn7*qbW4_73=~u~aBWClQ&E{o&J*{dgvAh-WO+^J922 zezLhmV!5rLI^Bp)WHeJ>Xo?(w427FBwu&d9L`wR*tDbZH@!=g*iR{ky-p5&Qd7GMz z&xHHyQz93zo^ZuGbY}WH;2G=a&%$jcA$MAB{(v?l}O-^>Tt>*fHhTHl_;hkQ7)1m&WXh1 z2T7KD58VaW(3_1QX5rhL#`Zxqo`hr%H2aAxpopid|mX-_3c zlR=*VnBkkH@8U0z3bq1U1m%v-fl@<1<38~^bKblr^kL%Q+KfGsAplNb9*e6jw9o_A zoUi)W9XJ;LI&i^X97qr6l6AyHbQWMkeHq3)eiCKlFE9~jiOu8-1~j|vJWmay)mPjY zvL!Y?5{I3@ZV|^>FliA$8MQL(7`Z3glI(;fMG7M$@f>xG|drV|<-)U&-A`i4v+YD-U zH1Z}?9G;5pA}{ju4Rquk=&4pBWYIhDI4l8p*^`_@aA63A-wWo{7S0FvoDqm;0xiKCGx;U^%S%S4D< zrlDs58s;0NiNa(04xSll6RD5Sfx+b&=%eL8uVx)Ne7uR zbN%%caWezYfX3#MlUScT%0b<;y`CJ^M}el_f;-#p;FrPs zr*K=9MC1T$sPC=Xk}su_h#vTHyglV(D@#D}&AZ2Dxy$59>>?QWIdBdo_zvoh&=XBr z2`s5GT&V-P@C4tCmEiZuque?T9Rk2G-!AaqJ=u6_53z^nNu6N!ihmiX@hT6rPD=oR zcEW^kIq;X|==#De9fjV3F6*4QpUt8-llRGN#wWlxTNm8{P)4m*U^QDggH9nD0lVVy zmQ1M(0X{tkfbqkv%VG>$ADrS=aEVLVEZ}enKr-XE>Y|Xx%%nS!oybzEggq)YKryR5 z$Wdhyn+v>u86mNGB*o;2AE0>v8CvtAJz37-%F*-4TyhR|ls>~{-G zrN$GPL@xP~F7m|EdW|xFkv>>IqCeeJ*kzzv>pW12)=d=IC)6&|rW9r~e^~()Sml9glxXLK zW^5Y85{rl@R3DyF(dBo~j54>1OWFJ64&2j@QPlrD-R`y?o{2Bjt_ePN7nww)5G{d; zbA)Ed0!U_!X5c}N(iE8oX40Nb7j~)WU+-vC;)Yb&5*8{=n#OwS?MK^e-zRzy_u=Qof9|(JWJzT;Gpk;eNLVUTxtW_ zTL@jR%xA0cZNz)(fi23fxJ7VC>ok#0yaAnHx??A(?$Kng-36)O8Q(NgwE?wp< zG{EmYH6P-3TZs2bL@AyC%63SaW}{62%BZ=`-KuQnqZyl8O7*92f++u|v_dff=zV-& z^g>+(I@*>#NMfK*6x0fy3y@6TA68GeFJ&u8s~Ztd9cQ1)kOrLs&@f+heH|FyK{AJ! zM}qaRrJhZ;4g#opUt^23nNMdy+u6oEF4sW}v}eYbcO4mHZLptG81Ff%CEo%4=|OxU zYnfb`&w;eHK9xgP=10j8%0`AfVvadk&gI`S6qCZ$7n;c#Xa}^9s6I!lCQgD3ISm+* z0gFJxQGD2Y$x~;q(vqLXT%~NPlzI!CYm8RBgDi9Q%hUM#Ob#tlW0({C8KoJzsEE+S26uL9NMMVv9kK9ftTP+oAb`O1(nn_<^uECi60LhH+040Me zLoCmP)VDpgi;0$+qW^giUr2u?Rs#*H%v9s@_?FTrZMBOA5MIZdnI%GqZb_ElIfPAJ zWp8?Zu^2#}hu$fiU?4q(jPV7T07s)sG*prFIEg8fQH3)HY!WU*-Qu%c@PJ(IM5CB=evgvse53;9}S-gl8CERH;z-lmyV?2 zp&A(wic{!Z5)v=+G5Fv88rtard>QsSIm8_YE9*y4KyRsVSw}v`17+#2I2-&%44wve z0c9N11O_bBI>MW^DOkC5g83rq|VGy(Xh~E59kZKl~wQz%n7paT_`AJA!F;p zdL&0VE!AmIvJt~=ybUpm>d!&&Ha$@MHSlg@7zH9rHOR(K(+)_n6d;+t|G``=M7O7| zQdx8iyOkRyL$*Dc^IkRIZV6dzCvrc&6z>Q0uCl6%4ghFa{1)Q@pGM_j#o_%By6aO3 zd{fkb_vj6WtZF~C4sQwRUkQF3GLKOv3INC(S6}r7?_(d+<>)N%1M~Qh=a7E)fFNQ+ zoCeyo6x?Mrxrjc*$Dj`dpcp?{+r?)y_sQenN>3A8={Z6M+V~EV03u=OG2~-lZWi62 z+ags)6+}?zTHk;|?_h7joJNlvjbQkG>Zt(Z`UHR(zSUNObOAEd61)Urb7y9b@Ki%5 z05r_kRBsE4mO!@0S719J?=UzB5G^GS^cYgA)4-^fWHxkfD|biEhZ5QV%BXeG&XY#5 zJ*oPTrYVpwrn6bfFD`oG0e!3WIpD0~$WmOy_YfDrcl%W|T=uxw8789?NaZDwN2XJc z>26|qv;!bRYyArDxjdH+iQiV}|7@6({Z9n<=Tp4bH8w6vd$<_t4vvAGZ;~afBX4t2 zwg-&wYjBWZr&D?47;+uZjDacAMSx_+?^X72bEtHD2(}pu5t;NIVGt!hj?*S^f*o$pbK>=6N$DUSKHDf^>*Ijllk@DSc6?_n@zt_KF(?!cM>%L1c=d zGWd{=CTd20%YiKJcq{&bO1mf)hcq=tEs$?JQhw0P7B?};@SG@8W*L#^eHZp5JQ$zba+4ZZGy z+DD~CjgD`LaAho89k?I{Izsut2TV(30c5Q2r8z`8%gi8FVX@dDJev7W`ouxyqrJDJ z8kOXDwg`V5UJ)5j*5=!x1<*d$x8EsIpYtoJijhU3LE(?dvf?>#$nPG>0lu}TBA6A< ziX0`j@f}gG_fn$9*Z5M6<2hI~Y8dW-U7_2{l7lt_U`!3(o}v`+f0C21Nf<}Qfd--) zWdYzj;q+4kE`>UTPsJOPpK+85TCmmw)p%mx2EG7!YzC1=%lsV3$N(^|Mx1d&oW;V9 zQv4CYvhC%)HX2sW8%a$lQB#{wqq`A1@jR-P_#xT_?c;0sw5tM6cgCAUcH*ts%F1^( zYFHj9L1mwr;$h}r@+eV>s?GZl2Cd_(-#7QmhznC6lW#%!OVrNjDYTER(GA&JEAdzM zYic}H8k{D8Mr2j+I@AQJO;nKfafNhmO5g^n|G`>{2dFj*D0SppFwx8#F442EmK8nx zbTm$j60Xp#i1ow>`n3qRBB}t$s#4FqBv%yoX9v+P+KFGUF* z`6Xh4{vIlX*74P19iR3A;5K6SLGRX@C@$7}UpZ@v(p>1y{zboH&WXPmDBEkUG7Tz8 z1f;q`0Y5|nk9WgstSULB&^U=73?y#LJ<-58cwIH#Zlm>-;I><~i_lV?J2;qYOZ`;mp>AYU!v8(A_F$%4L-Q>0m}7XwIru)4r}c(kLNHXdu4lQTW4a zu3}l=YLeVaTr2FC84Hbp^E?x)+&3v0az`ka(MWslphM7@Rdv79=v{B0^Shv&E8KEe z)f=(u&eCSTBm05)P>nc9gyxBrJ2>AMhT2~4BPZ)EQ7N=dfLFCtcM5&^IDWQt$3Qcy z0b*RVS*RSBZivt1H#$1yHC1VeKG)mJhlHy_rVMKzovNoqO^$tG98@-mZKXz92ZW$y zQk-mDlJ`pgNtG4Qnu;~NCo`RP`g>|+MTH6+pfO9|HNJ-mjOprr`HE7i&9>1suQ9eI z+F+#`eyz9O5PcXAe9p6aTyMQShqr7X43R%o0Y_tNYEoU8+U1oxik^Parowzfk0 zS@kFF1GE8Jro`5DUz)x3hw3b?A-eCi#8tGD^&Lt-rMJG-K_AtG$Ko2GUyQ-pboG_0 zn`l2YO^#jV3^)E#nkj}_5vA1fC~bABLXn0!I%Z@d&TENz-<}MQwb8num+*gD+;{d< z{Y!P6R?ocWqL~RE<@ZnxtGDjcSk1D~DQKD;d(SOr#ppe>H+pB(G0~&^oqY&OmCMF` zGaVslnH0Ceo}=GWp2-i@nHH*8+Z$~kr=#(?KHq30XyjXyNZXo@~e@(8bS$5IAnG} z8{q%6iun%QS#4dg(LMM(y<)`aVq(TIm@U=y{xViaBgy#6Li^$G)Jo0VYvynRGe9Iw z>v_}~pj-A*cs>?!@PAsxOU_K|r3v`2JaDB?fT_P~sRnqk>GeJQoi1a2VGgo7qm%G| zT1+?eo&5-I&8~tvHh}+?E;+}nY4CiJi}Ijha;4|a7v?^FyGNm7Lyy8I&U|Bz9%s}< zOW^;sm|J!eA`|y8SrGPyj#E@iwIeyf{qnKqE7=nJs0FEB; z8YtudDr(DM~xNAL`uHdrCK1txy@KfyU-R!{pf6;Pfs* zVVsug2Ph^LP~sX|4^>s6)H?bKm?{`%-PAMI%4__be;U zc&Jipg8tefYx7Awb%%IFJ# z=QQkLrKy{RQpQK65emKy-%tEQR$-oSmh@IVYg~3v#@y7X`jw+S*+lkAQy3U3Qt3eAH`(+}_{`T+NfG#Ba# zq3lmmqn0+_?6x*yVeWT}szF$h+o8R|?ZG{vD{!IpZ;+CYSBorEX&z8)V%pLAFH%*0 z3;mi%z}H3=g~x|)!UF4XVhQc?Gn5AA`zRkUmo@Hb)=>ohGCi9piYy5w28qBEs7cuc z`<$%D)suhG;f~=>^Woje3C{Og3+WvD2)+kw3q=RV1>X331n^*LFPZ3H0z^6*qqQkzmZ#<`-6W&utnr5@dcAF1e7lg)Nm0D zE#SFT{|xpB*;gshr$9m%9!nLM3Vmo_=%2FzpXFH%F{5qp-dK>a|RCr*1k{`VVL}hcGiGAcp0colN;6$ZI*PGJ3?O~LfF>u&`?z9<8U_CgRI5e;aAH;v`q8^ zU@mET+3pY;l+W@G z6HR@IFN~B0Yv97mB1f>d#Chg-p@}-&)0`K8yf``D8Kl$lZ+wKY$ocrG$oOzhXnm-0 zqzuu3InLjZT4--9gs<=z))w71cxAsJvA3uk0%6r6)59CXR-`xnKXM40CeByd=&FtC zXM1#;IjUYx!Gs~~FzOFnz-~l{$iBz~>`VL!S&{81?o{E5^PPaYw8=l#DeZ-n&7WbW zQqzgL_)=^x_7DpYyQqVJxJ3!+UD3dmz=kHg^ML_XXN8a1xztPi`^dJ?(%`FLMmQ1U zhyvQ=e)iI7EC!Hl)Y1O~k+9>i*vxw0ISmc_Yyx zw2M*-AH#f1Zovz&dY}n2@Ko|L-I`bAD#iz>TnWN=xdq~)q(%yEzns7o7t1~o)S%6ma&e>&Ca`Igv7=mZP1i{We;Ayys+F|qbK7*L}&_MiF*;87+13uYHAbo3=VkX@)MOd>Bz zL$tnDeYDNPYuLo8IhW2yqVM;dVFGN5HQ%(k!V>!DW91K#33VrMYjnEg=F?g&3is;#xK zF1cvo20*L-%3f_m)Kd~C{KuVU>$7oen7zxD0;ijK(Iz@KHELD;bJiMNR^p@!d<(84 zo5ZrL%01^(rA6u&CafyzfRx>!3|tp>R6C*kBXtzF^If=7W--%~ox%^0o&s7O)XJY4 zwXz;=7aIe#p-Kyh=ELkE<~;L^8P7i9rb%~U&EqiO9NgRobFN8J$th5Rj-- z#%*go)Q4#6mCvPl;tZjaP)oce>1u}A0B!Lw>XvgWTHSSC=^_P$3H%LiC_fs`b4AqA zrt6@-Vd!bYRI~_cjCE25it+sSY<0FG`!zdbgW>2Nl3lYKx*U zkAXiq?+zxIpjQx)MmG-*{b95b$vKw?nUt96UX|y) zRp=}Bk+v!E#xT1rYJ~$SVB&FOqSi^7C{e;tzAm37w2{)4Sbdyz-bF_MWp$nM&KRSX zs!FmD#ZTm>a=W;1_`YHtWxM_X8cTRY3hgb%F{rXNO)3?V1rr$EK_@O=v)b4r7 zx0Vz2g*J+20jc4aAg@dQhSxoy722SGWh`!pxJ@Zz&I1ec(CRgC-?RSG_R3{p zBA$h^;#Wp{9CQ1rf$-U7AYfJ+VfIVX%mYJYjRND1F@6}T2KM3rkMG?ogKIR;z{ z3|K1~B%u~oQ@x$y7whuFp~Bj7=3}-zpCo3>nkHIZ(OBNI)mL^D#J0b{g^c2wunsdC zI6440nhYi9qS3>5IE&pO7Svl(ddq#Jo??#BOt>bDl2#~>K(%|K4Fbp|X_sBr+@Xz7 z21s8B31CCtLXosA<$`_yR)|FqeqBJcOO1nCW%Z=|l{8TrApI!C!+c<|iNPwAhf-$< zind?r4b*AUzkCtbg`3N{ye95fE*lL{FUgZWvRfP7Ah+Jd?SU^~W!YowLvEWe5{&Go ziGBu@Rdr(R3wkj~>=oCR9nHv~WJ`Dwi1aez(Oemb)VT<3>7_K5CWFU_#MLvH~ir`|Ou$F#JQ@;xzGc*Qm4ZnBwN9buLNdQaOdYgM(Tg7Ta*j(5&2JfhEhxYTq^@bIH4*D zpd{6^r|MbCH0hZz2UM>MH--NlY;-Gx5%h`W(ZKD_U{!sj8p2GzJHHFGVGjSEl%`fP zmO_no5Ov*`&Q?>@l9f!UtazPYz<&uO>dCOkV#0cj3@EGX?spGby^IPV%R|uD?R*gY zk`0qF*?<{!bH_s|g&FgAFkDw&CH~6~<;w`m!A6FwuRPm5^bTdTyUfbgbCki-e&G+k zgijV$foH#>9kU?!9OD9&I`K}7IZc}?X9!EV@7XKt0q#rwXEC6ZGg8n)z{sgn6BSu| z^^WQ$X||BaZ{qs%>B2-%sexuH+JHP8Dt22~vHG_PoC+653t#e81V7ZxZKPkckS{Ma zYHi{_R+dp;Yp9%(8cT6tKUqpOZHqC}L7M=)zV-=cv)M-PrmmI;OOK$y_5t~s;)B{B zO;E3VpkI43Nadm4Q@sWJ`j`KWpCSAuj!@R!Ju{R`mSTA$fLqp`L^X(S(%66IFP zH0?N4A46gxbS~kt(-GFc)+-~ys>+Is#AQ-D<$J9yN-au_+K_m_Ze@P2eG7>N3mUfu zM#h3kQ!Y9H;I&Cv?qjoyzFYlQ?f@QWk@%y;D^Iim7WnCpHhKti?VpUQdJ`3wEoqt5 zTfU}zq9s6SieeW%0EE>^TV2cgQ$MZ7D=Vd^;!d%Jlp=RiOZ2-?Sfv;!)DD7wZmN^& z9eIs(NVLUVsDj*IkF~p^_!5sfCmhWJ=c=^=EjTT16l+RT<;L0}bF+&!1H#(GAMG*V zl`nvE8z6lmm6sbT%d~IJ$xv`;lShArBbh!uO`Ra`6z>Zy#Z0I)+CzJ6)m?~ z=9zzKmlPT}hoqUZtcWnGI_MjKu1h>=V~~i>lqGSqa0%|0{X}XAZvS&wU;E5^xY9d~ z%TR~OE2TD45p?>Pde~@(?gDgOLW+|QLoQW(Ao7nyKWL;3Wj4E@HJ^jX>kI{D>H;a} zDCt*WF~o~`;z|(vRDG@WKB~DDEGDUyJI=bUKUNdKA{GKqZ%NPPovPt2U2Ot{wMnk? zgV|qyU;R%S4q=HC^2E;aZ6#5kYNMXp0HMwl$2N0`Us3(nnXUC;-r3*=GKI`LC+l(Y** z+1e05?EzsuM4SX;qdHc8Uu-6P!yn-TLTzb^a$Rq3_e9DLAW?Ud9b;Ai|J?vy(VKq( z5obOmkUyv$P00A0@AQ1x7-ux}biJ|$ymx2Ftov{?`HkXX$kSkEc>qvW*9*aW)~P}8 z%FD&~#jYYNPLmFTuK%u9w_2jnUqGa&pXJ^&qxC(CDCG-v`2pM&b`94{2tx7gd~-hB zst-u3>bp(=!rNYXzpxJiAZ#q=uJcdDGU|`|JrmXybHDVGnmv$;T?NVe!L|11X+A^f zDAtztLPmGlGiu*1FWA1YpMgUvl#|4vycZ@Xa!a5zU^B?#E1?p=$Z5D6yla%Bx-fLxiRKC^@-G1{1Qg>J!^3n_#V9u$dEGb>t1ktp=?YL;|*PeshVSi{68m8O@@9@63 zTl^0~oM4xDR)_oU!e83aW5cJ6UMc=CCD8u9s`1-#@pIoXO(A%Sz0N;@C z3KXgcCYU3^8?BVa%IQjNh;Y3TbI^+t<=iJwxo4twTRAH$@&gEOkF;(k7-I4vFvMyb zU<%R}@_`#tO=&PZEd91(;z9FTN)%bG>`o}9jnW>cM7ia6>W9=tupXhoQlWofksn(la9WEzh@qDDSCWzi|Om^N*ncimJ+2`I_R8NMzSt(j7N8%!Hi*?by6|i zkWECy^OPtf_O11gLh!FioQ^}SUO-Dsdt;%no{nMKqO4cdJ+5lk;os1jQZrFTVni7RW zBu>uD&c9a}SA1n-i^8RDKfQz4gUk(Y;L&*xp>8MlqPqhSwBnm3uZt%Xj513_C~QfT zVa~(H&VK==b_&{?*Pvih;U`7YH*PGt>-3ZFkS8%eQw1gbml8$P+3No1KFkXj${XW1 z_9$rS#_M}HlK2hZ!wp4W1BMnCug9@J5)4_Jo2{bBZ$L*9yP{w6yA=Jt@uy<3DBYO{ zBxhqMsh6_*7G7DW4qBG?GXHSl^o{d3{#CRof0S8Cm`^MVoy0OwAz%=7Pr9aiG|wpP zQT+SHW(8HuGy&>E;eX-R*_*DD-ZV-Ee!SJn2*=^6oy1MkdC)XUjXMBe%b!ytB5Sa@ z5~8D^sme+_Lwmq&!}Z{D{F;H6TqaO~zUiXq@=ZZdbKK5(cM38$<`*w2o?W=!x*@itwuOEPj}%c6An0)qwH>@h z4kVB9kkzMG@SYipPUkHwC|~qfQOCld6Qh47e#*=zvWYhmdH@J|T%NI5wD47d^*HRF zW-EFexMq}!pHrtp4??#E)HbGR6q)qlJNb4girLtu=tbTWFoWa7fk-u+kkJJ|P(dAA zs2$iqvq zWMXx&MX(i`64w+&7ja9S@_7de{wn%$%9s4^}+*(VG4mApvLl2?Fh}~}87UGHakw1uG zh^q=XanIe;+Rt1e=7gv5s9iOWDVvQ1@g_wQ(JV0KXJ}HZ>~XV{|EN`w9pU9PZlTrH zy^dEv2b2jU9l1ufLUn3*wK>a`&6jKKn zSSJEzEaW}TKUw%2=-=1*@qjUcY!?_6tcpH=hjG{0;zZoNc{DKjaelfpNPWe`!l|31 zcxyDGZqq2N{(aD=IqnqjQ5i++iv|{?+UulF)Vk1D!AJB-7yS)LYTP*82Offk(|+d_ zq}PL{%9pIV@)ou|IWy9p9E?7w547r5K&9}uZSc0!MGuR1RLj{6qDm!Zky9j8rLjlZwV#R~5Ked}5sP*}i&nY0vjm2F0c#&ArsL7* zCY~TZL@)9-7o03CTUZCJw=QY71)JVYRppLq=rthVb&t3oqHg(R3(FT}6g4PV0=wwz zF&s8Gbe#CaLT+-?s7T%C?n$=|!t#dYKh9s4XIl-Fa@_AkATo{^rJ~*`9+m3oh&wuO zetup-VPVaJAMK7R0^v>ydJY!-?x7@|bnm+r^A{F;Ss>>py8HDNyi05gMMd&i6lv3q9v$FXmOgS=haca{LLWX%#E`PJ2+p<@ytnVL?o2~e)^gL*=mi=r{ZP$f8i2; zA$7Ef+50XZc>`aSf3IA=J8BODM)$g;L~V-M>MpP)YlPh#8C_GNO5$4BEg{Q!uAMgE zvwTLkl&FGgH{89}F`ZUlD2mqD%yyvYr`O!U*>3DmM=418Pfav$IB5F^DN%V1U%QR1 z9a?oIMOrMqP0?w%4QHr(ix7=zR|(ih@jDH%2{l2&q_ zTezz5MZvAS1x~Jw8uv(v;u{@yJDLv_M(oRf$)yO3rA>+-KD~=hw%gFnwomJ|(NBOU zByYE%fR@x0cJ=O}hcbV2HNDi#PHqtSZXMf&$X6ZZG`1m zy|g?jD8bp12k%h*=2>|T|BCKM7U9$JABeg1-&_uSEvRZxx}v=SE|uuW?hPGiI>Y@{ zTP$tieDpZ{aHJi6o?OO!2@AWmja)m?KBiApD`+!d<60j;P9fZpdTVhPbB7oJXV1n* z+7aK=TVSvHAnmC6%v=QrPj{#-&|AP|n&#TyD*1ebo=0qq^a$?>Psh`!dhAHTTfc;BE>c9E}eWFGyZ)6zV%nv(E3Sf!zN7I*ISx5~HS`_eGAaKWm!$*ja`JWLM#v5|guTgAsY+}Y@oTlG zx!rgnj~2QJol#DIZ+P2{+0ysSa$wRmp;GMP5q38*3d1L{3& zZ?LL=ravpVA`(Z$(rfsD@?1Y^ypcEaZFr<2ejuQyZgWOzG2&F_I({Tn4o+=04|R`R z$9?p7+^5nl`K+`==*q?LO;De7Z-@^xO(=lFTPMRa;In^r2*=XMv9t!HOY~~m-@+PR zm3pG*?{Ej{eZ)WL>$n&`5|jdagJR@!;x^qBzBWGBM(VAU)nba!8f_fpvE#I!Cw|C0 z!RLp|1&;)V!w93vgYj(^Sr`!_74DkpbHCIbr+0Q|KHVkfHkO*hu(bR`*o^Vz^14J2diSR;3 z`vI9wn`wR_bz?rq%fj~6qyCnkRPUW5gZW0Q3`JQ)yWiEiYvo5Cg(JgXIEy{Z61qcsX7lhWV+y zO8;7WA^#nIu73kIo9?-Sr9r8JbcW5tvc39>uY5RtZA+Se*oxosvnAHbL>2# za^zwtE3_wcI1)$tm?faBRn2==Rb!_-N4NzW+@0Y-95m`bHARS`qk-weL)oGBkvsS+ zO6NY3dl?t)nbu|Hk$7B6N0}o$?Dp;=(3`bPG;F&$8J-`04IHmef5{D&Tk4I?o~B=~ zBhMClp{S8w$L~3t)VKUpdN-aBeimpE93P&C-60MzgQbAhN$;&rl5UARbOBfL<4H5?fF?>e218B?e zV2^MdUXu!gy&qG*);#iOW$v#=W35Um^Sb>*2k z7&!hpu>vftfaip<2Sga!t( zK+o@n1w57hk^fq$YCboTR87d>9xCXThn~9EYNc#}jq>BLgwQE})xbcI=s035h(Adg zq(6YgjTG@CDG^CyJqgXQA1dE*(bR=VR`90(l)pvrb@)1dmFf!)>X=T!PSZU2IMNaI zALsRagk2rn&nHwSb~9M)AK~8{C>s{AXle_q3CG10DFwcQv{Ei<=oO%o&F?v1tE2h) zRAyvga35?t+LwDT@HBh~Z_At&Td5x_L&R@{H&Q^oXQ9u=dqdp^XD-sH`H|vaPuPWD zCih?e3>fMk)D*r6EJOdMR+p>Goz!9|0-xofH+Q~OuCQMbTf?WoVJ-A`2f!V9Sw zJ{js{H#SyjiW<=1=y0_O9{K_&2h8X;c^zUy&%pECQ+_ct9kyY$Wmijs^ykJZeUSQ_ z@}Gu|06H8J(_#R*S)^yM1iI2Pw_LCxm_}Q6iP%JKrLEE)K%TKlf%5U$6FurXbkKDA zA8b#kL!hz0h5usUb@&NB6*f&(P>&jZ<2N-$>Lc#cQQ9OA-7`Bldqp%4|LiZx9pN7l zI1*Zc!HGl;$rFqPmZAlvk7U_ES3LCQ!<`3e7oi)y8(R>1=06G!sZr1hAI3hT=I|Be zGti-1@+}d`klnD8VJhBi8yM4Q{u8on1{-|mV_v}G_Zeloft~@n*Pk494qpgS zt2nsbKOuKy?lb>AVEzwOQ$ATat-D%p$WJb5_iR)=)f;a|^Oode1zZFNIRW}3`!|H1 zU=fg2btRxt`Yip0I!K#oqH)ta`Zt^%AgiHNGwfpUsQ+|sM}J~)1H_nDpvT|Jr?rJf zZO9Z#3`p|grhD`|SP!Lo;KnwFOToGq1ZD)chNIs(8&zItG`33gO<-KlV0!DJH@o39 z(P{|qLt;}J+6ECUE6^cyJ<<Qg%Vk@!NHU{-+y&M|(4HM*3Uo?TTn@*uU~i4CAW&p@~xz^)33UCbKc zvQlE42GvXgr!x>;^03n+8>!#$h16lJVfbR;XNXQj=mao-D5D9#De2}2YlK;1fU1$R zKr@^FY%W$FbJxhjk-ebzM*`b|hr|Ei=cy@N9qB)Hp?T4^opSbl^OTKxe+1T&wFqnn&+ruDJP+pb zskjKlnr@~W5A+ch8aKzIU)J5BJrerSnGlYv1Sk0Y{+{5~hCvDuBfOEz>t3YaskG9H zEfhD`d*EmDvOIk&%JkQ}LS})`^;AB@|mBR~yHzApL4_gO=-3%%0 zX-Lp}!hp-0iRcnwQ)wsNUPc$l2-AR@!y&6#5X=t$g!`Duke&FA4o-7aC$B7m<#}?x z=Xi#@E%h#9J;<1DgcCv+gBwEgu=lC&*t24i*1<-3i}QLwv2yT&Jr{TZyoysz3keZO z+$v+);SHho;eUWJVRp2DASY}Lhp{?X3#=aKDPU90E2CaUMOlYKqs_49VLNmL#Pk8V zix~oZf3CN%M?hxZ!K!Kk=ZhBt=Tk}Rp%UW%paeW2QW{$DF5>?{&1E(5S4jQ`xTIB0 zU#Ry$V;2Eq(yCfJmA+ntz*oQtnx~K`e~u5O^SKo1Yrwwi-gAnr5f&_=#x3^5`r6%R zJe14uvGj8MdSn3n*5k2|!MzpEDEFcCdgr_gZXM*^n;Cqv^P{Cvk9mtaO|725-yY$p?4 z0&J#1sk2Y-Bma-O8|Jz*wVA1ht?vGg?JZiIl0sTo!i`kN0vUeT&r z_neKe^?jAm7(EAUD(#4~Lz^sa@lqgc25jUU5Z;a529^C=2&km_)Gq7%Y*w|vM;5Q} zh%c}zC{wr(NF3%R7Xw+r($IAXe`7#vlho}d;S97}m(?CN<5hyZ?|xRpS>UbaoESK#uBJ9u}P(}|&{;dbDyyTY8| zH2Aq)fTJb1Fn7vr_a6b~+!XXR&k{c=xYb zqP53G=K)P_upN|BGtc6)ewbOr$k9$ew02~YRY~9i9%Vh zkdqJx@8F-&Z9pf>n|tkSrwW|W5FONe4UD_#O)CHiSOGl`*kr?XLVLpV@b~F9d>vp? zsU6JE$*wrNN6W4SL^NVdnGhB}0vLh9EJlC2E>Q)#50ZTE0*+7qCdD=JL0jQ zWCO74WOz4pxi0jgw!YmW+&yj&2aG6gJrGXo0aNwKFfD9Hl#NsgWd)mqQ4fQuP+vYr z-e+uZKhE!*x6Scf={xim_9eBAu_lWb2ze^CmQ4|nGSax{;06$LDl=N>tSrB?yMN9VFTL~#P`f(aff=-%*i`bFgULmWRG5W==BzWANm_S%XGYb zxOu2-XnyzvUJ2G2DyXtq7CAvM{buvs+QxC%&%X|$A_O6Dwe7+93+TsOMflcy(Hie2 zfcMFT6|D&&Fu3HSpq``owJ@tL3v;U~p^KsRSS(eETP!uv6YV2TbC-Y}=V4fFYTCl? zr2YsCC|?n~vFVYG5dmKZ9zO<_hfW(%?=-(p-grYw?XT z)73X=0|yAc{sdB!%vd?P>R3^?#v8G8+WAH%Pa-!m~nZ(!#Pdmu#5j*x?) zDl{;&83YxhwOqhPlLNrm?gh5P3dlI@JkWfXg-5;5^W}h*Rkkcx71fDh)Oa*MitmiTg_&q-9y%QJC|bCE->zRB)EdiG(nG z&&xwoQQ>>*$jUYsRgHfKcnh#lf{RSTuD~8iwXo-nyr^;A@Jw7 zsV9*4ba>arJ6J#JB@43}tsEL5LdZ!a%_In@g>bpT^vD2k8P_9+h|j>&-GXeV*qY(o z1=o1P8IGz-!2A@_st(gEgNCJ0+lTQ_Xo!<~0_Ha|nLh$V) zu4QkN-60hz3px`={6Tev+0|*t74AV+cha?;MreiXiM6uZOK0BY77f68U5M0z%f-4e z@v#531Ss#%tC+XI_T;2Mn5YMn8F>y@pW2EIhk@PmRtR7w2@8AjEMqwO32?Mz+4vMD zR6IEyVyP7=!qyWX!t4SmEsatL&2&DU2d2QPKrUr3n8IY?4+ewPVF8<1$9e=J=EloUs| zX4Y}H#bH^)f;$9)hu|c^HCS+Wc6Z!o+PzpbEV5W|7(BQI2_7K06D0Wis{eQPaH#IN z)m3%t>Q~)Wzv02};?f{{mxHBCymm-POTa-#Oe_$!+mXg;-vK;TdntS$yAUpw}k{ zK_Qel9rY}ZbTqZy0; zPsmD3IMMw!7vRz#0FdwE3d{RpsH8DIqz)l zeF~FyO6W+M8kpx)&G;l)p<#8s)7{a~h8HkR4uAPDvS8_^)(4XpW5hs=$$udCRWFTf zpgNL=z3wo~=m$GZBkv*PK_2eOJ#I~J!9?vKDdcMC^4lG>Zdn2))h z`KCY@|CX2Qqq4tUl9&zE9lRJqROw%-4Vw?X>{ocx2R66e<$R8Guu0g5;3-|NO!8-g zH7T0@H-g6R{0h*m{_tThk-LoZR0!CR>imN2ENOA$#V?I?atPG^iX##2UI`xcE^{ry zw?!lDEu8HDz@G^}Mn;WvXz~*HkkoW?Kpur`YpM4-?5*lJ=17H}O%1kzfhmKOqG)#G z>~x|Tq~=m;VmfNG#Z}DMz<-`Jm&@UT9|^hJ`L1BfA4xzXE`ms?@Cs`+fHA?Pea=Ou z{~QXv2*swkzVmh0fAQHI4!P`v#WkG51L-M4B(h@y?& zDRd!%#Q#Pm=7upqKFtQ9A}^fl5D)ir{E3LPeCP}Nuee=XwRqB!TG=rMLYc!L_aSBb zix0rqF2wrEOuGs<`P}m^unTT-y}D{KS<*PWG+}fE2Xj}!hX9%JBJ!Dr8UEln4g{F7 zx5t9hQ|!E%C1fi7^&U_vRxP6`nCO{zOmGwX8F`*P$7iyV8A zrDO+3v#rI6N)^4O(SYWn#d4__$3X2HbNPZ!tT>g%B&v>|U3We9;1@O%Hk<4Mkx=m? zKG#fuf&0~68DZcJ1Vq4?ATR=)3YHNkuct&4wAaFu@Ks+o^fCs|s^n_t&4Ybc3IB;o zRni6!Rp_q{;){nYh^&vn^mTy5`~+0D4Wf>VNM$d9hEJKP8%T`u1@^jC47Y{jS7&pq z9u7gMF+l2%NPSc`fw^cw*o~C${jtz62JzRgaE|H7WUs@KoWn%=kdYh!H1$&NubUnA0J$$Y7m2{rPzhgi zXv$1GU;syR7{xpA>g(mwhHuHEWuKQoV%KcOG*#=V6vf!;A~Ri%UhjkJO+`XtV-kf~ zN#lx^(Yu%-s+n@@Jqdhby2S9skS<_B0=9m7KovUMwsKgfZ zqCyRA68vgABxp0x>CzxS>VD=w9Ik~2r<2{F;ZqkG2PGR4oO`Z*_#&~2?V~LX=uFpO z0{a@c_Z+;jurphr0n*&9bYT1SUqqVWRKfz7h7@t8UBS9gd7v8&^jC~z|)}a7NCIfmbO$KF;Uc6s}>Flrr+)TbG7v=1M zi03-YSbgwl9ir+zSQNX3_;j5ydNE_1(11dJ0I@GA11Z>)&@_lueHe?5wlunW3rO5l zCZsg`bq30`lg?6Q^0!=$%NIBb3Frq9_k^_r5Xx!DcC9d`C!nbX$$(v0LQi?1H4?vP z&ia3X*IW+BDD3ahoFbTy?0T4l0oaXJC;bpxb< z)El}1NvnXx=YsgQw;*hEdzg9=Hf)1bNGpg}W72{3AnM`v!iJ{ahk8s#+&m81$qj@_ z1z|jnx+@?Ic+7W%mEO2y(Bcak68sMP!1k0H+AZOGtVXm)##a!wCe1|QisR`MG3qV| z0v_lOpnLB@?M+>dC}b}C4zXlqxSa=h_;Lj0XZ@SPgYa6!Ohl853_!{nS+gGxPd%Z< zBl`IrfsG4*U`s%JFcv^n`+%j4esIa8r5}t}DnwxD0qQSaBIG}eHTio0)fn4NYZY5R z#}=&WJ;A5O53$hE6TYG_Rstc7B@WWD_S8Ba+;2CFFmYSo`+AA0NhT5Jk%%Y2CLSTUt-_cL-hF_wZ{DB z;2KDKOS>CTerd#n*XY8Yi8;DqmM+SV!~xjo<}k?9>Knfy%wGa1d^|FoSpeIQ+Y7iY z{;#1!`~j$W@9Yj_q{<;KzX^J8>H#$iS^N*)pPfCdRWn;qQ{G&RAy@(k9AS70Ee@r&lkGykj%+j^V(vMj(1y1i)_^0KYGAXbk{= zHUP@rkqkIS?R!C^ES3o7Be-7VcnRFAGFCB5!m*TtH|q$eUIpW%SV-aHpsqdu{kFrp z4@ao!wsy4khZ$Uo{QmoJB5jc&kVjS;*tGz?oJO|4xt;JtNkNgp@ zrJtlsnWZH0^Mcbo-5m&eGuLC)vyd(9T;Sate9aw@TWK!=IDZyB3b{tf(+c4ozpnuJ zwz?|Yw`aY|+@5(8tC*EMo3R6WYq5rM0O`p`FsCI6o-zeM`Iher2)8*lkhow=w>_}k zgRP(;$7_Jj7XbLwls_XiCT&mS@$jly$jKwVy?8%DvyRMSG2Ua&{62f|G|YGdtssK0 zS!x6FFQ~ogJpkPuX1k*I{gCq40Akj_w$3pfrf3zDC00RnH+k_*;95Y6emg@4yBseO zO~EvkM1l@PJM&@Yb}LqLun+Yc0QeoXnOY}#r37!$|18MU>k|+1`4RyIYw$g=mfaD{ z&E4T#y8`dOBotQ40HvL%%%TfFh0f6mGxgS3_*{bpD!EnN}^DNO#73L zH&<_svl5mfW}09oR^#DI}beaXGn0a-d}A*E#A~Cl)RM|4}{?-?+d)m5{tF7R@NJ~_pbSfH{$t6lBPA# z8)z5kib(QRO3ulH*!h5}w_*iny}7VkAFop#fjT7$+p*qLQ~H86djQH;K)yF3U@yYI z^XKyz<+OMTpL>@QMBOOfXC9r?M!P3aqT6Se?do@CimWFq#oaxe|U&Tu-5 z^GX#`c}0?CSF!QNYtg~%3{3a03{(!+6Mk38Gx|f3*U})iOVI7t{aVmY-$mK661NK# z1I|z-R3*40{8b>>0PMFU%iaX9CIVczuSL49O0sl_ib*o?orADC$#O8kt2a|;E9k}W zHRxOd(Np9B;-4z1xi-mS)Vya5*X!urvX8G8amQ|HkO6eQEG@LW*0TGHv(yga zEq;mk5y0>|RI2&W@M_(az0v@&9^S?n#mnH%aj~xar+QBJF3wy$-0-PiMBL?2omxKrVDra0-jKFLCA?$IZx z&E>q}C_asQ!t`ds;T_=yOfN1k8XBoglv_wAIalz5=eci=M9OcV<4+^7jVC-}8udF7`3MVu^5Wv2UUc^ig5Y2+TQQe(U^3$3gbAM=m75UVnynRIqP zmntlgnk%c-^2%fGP|)pLQ`q}$U@1>#Z%VQ(PUkUaJ>;)~%n#(Iu)WyPY%lH?!78m*zENyKv}u&i?mOu$lqoyY;UGBMm?85F1D8^N%{D1Lm#~N+`oF6;1-FTrxj9peX(kle-Q`r z^DyeSOnx@RR^pcObHsY0gB=pw<4xE6*1qh z#U5b7C2mJ}XYjCpH@4%r$dgf9@$?klD5|Z&-d>Z1`usZXEjy3v$afU#i2>m)*MONG zaC>+8mWNYFt!+t`r74Lt`l1d8)2;UFY=xab|>#Z zot;AERYaJzROrYrzYSgS|L7g(Yegd4L7m=~RM%H4{iWjK zMc$4*=nk;kFjJF-0fLNe8%E|FYGgzn&(nU-z9qTr3GGAP* zAbk-lh*P)%;pjjcf0@8?1~EaOoph|-^c%`esh$|*D{)U)2di-V`Mlyj@hir@BfKH7 z$ur#D)mM*{+eQ0xPG1da8z4>w-xYjDd#0Co_55D*P27}=L&hC zTT@ttEy>CFTKR%x#YctPndrbC_jm5G!JHZ4jJ?OJ* z{;Ypi>PnL#>Ako?YzWq&0k)(4$`_aRO0QvMqQWn{FWobIt=JskXa}j)8jp`b2Z(9- zI`vNYAl~t<62h)u;VJAu{wx2MyBuolJL0P2`sm&f%G5~c5DajQm-zDjH9py1$8BdS zhr^-M!4<*(f~P|v<}LL2UAR%OjqjXGv`=uRlb;S#PSMYW^GXBIuiF?!DJDOoGTS(t zuoWS$ozIWcK>qM%V4w6$EUEej<P*Ven) z`N~n%KT;-7P{F8Km=x8v$ddRKdfACR7_JO^{gye2vG){8@S~Zi&U~W1b!Y!EIdQkrXPzEM=&ePPD=$Rjex5_w5D;$N@g5Y2-O0xNx z!QrQP!*m{Oz*0Eqa9H;xd9Jx*e1pSBRnp}c?Nkw%_Z~2GYhf9mFb$Z$@KRzB61Wex z@t7PC^Rs;eFFe0`riJbUoH>p*phFR*KkQLU;Usqe#ySryl1=bS2`~#(rhfA#xoi1G z@#GpMPu~RRd|oatm4L>yV$CAZyY$l`l;crUtQ((jLaid@c z@``VSAZ*BJ#30i`{{>2g&&#CQDcYmquwf!5Vm~HAVgG`ot;E^+RM?G&QVYq>ugA*Q zOwY661eL^`radC?Xb<5}Wmt`ToP(uSN#?f-bHpX$2|k?}8{FU@=MRUglarv&PRl?8 zvoQ~E;LzT}3Os>Q+u#tspn_LYAID z-3G#2U4;KEuQXH7D;1=9To_#|9egN}&6hCp)HonA&0)ch!{MIbFY;?)F#5~!YIS`N zT!F%^2u%y-XOBx{{$KDv=|}W_@NW_%!;Y!j&aQ(hP?vRFTr1izp$fYq)HP;Ap zyn-E}=YCk1dg4v#yz)vF)SED*^Vq2H>0sxuUnVzbmDJ7pEAVy+6#5c(5-zJ3;+L($ zUbJu=;)<|56diaL+$)h4SE&z;qg?{|TErtA`TBf4p#vhjk$9*5sQSBtBPH1yAt&B| zAd|0A@*J%n98gb_r2{e7%P`;;a6l7f_-*MT=K8Ro3EbjIv+Muse!4bc7~R*$7G`1L68F5xipj59L-*V{;hWx~ z*@mI$AflirsIWMFGs3cw@a}nqThO9Tu*WpuZXw;2XDi2)CDJHt3p&Gh*td-*Tkg>w z?LolZ9NugjwCEJ`E<75uR|2})L)s!wl(!1Y!!iCO;y;@RMNh%c(h9 zIqh$8Iivfl`u_??R8s08W&)9SH&`b>BJ}|DbU(uA5<*^4l9H8VM5vPyLR=2@^>6Sm zbddloBu>d66Bhk-95Kk-KL@OSiLhtIEqkB%o7qzCcE#RC=-{JuSKwsT=vOce16H zCH94pk9;4Q(I?qb!xG0EE@O!iS7o(2_@jB1j~u1H#r>RYscDJJHFAwR zMx;rLUljQNw zUVN-+)Qy}Rm~5$HDZ0zZ(f4YSwp`n*jnyj|r6XSlC0i<4it@%*eUtV{9jPtEk7MDM|UyMt7Z44=DGrv2!}Q+e>;T{fMVb(fSyXQoquHC!W-Lt7DXsa(k&g9yDGm zDKEqN!Y1vg5$Q1Aq-d+(R+q^OWCy(MHF2%9*zCzB`iz+qOp3>P7x<+UF#2=Q+c}69 zH_8>&EA$yFCYlug>G!oQNIwP0bPdyeO&lUc zz=FKmYsyB?TvKv}8Ji&B|KbrvBvl+OMng_T@ZlS+ZDjkrWJ_^NrMe`f$EXp^R)4W9 z0++kOal}P`NQp{CwGg=Zcz&{_sHJjg(p_(={wSwQKZqq@ME>Lt^OP_FQa@6|=4Ry= zCR>VGDn8bGtC!^>cvuyfvS0ZR{CuIlxERCd)Ps7Y>!M^!5liLIMmfErIs#8qMK_)n zkH1O64;aHec_(xzGCzaTRh?*jgLid{NSXMKrX9bJ>&mUjz?m`;!-hbaXSXHq3~$ zvYU@|89!-x(9NYnV>p##>~5A)H|8e^Z^eRmWX;F~hxy1CMoVNHZ^h%_ji0NBhn7Kt za+UkQ*B4L7G3r=7VmQt5bVMp$2cucT=f_5t=a|Z@fsC>Y_kdf9eg>73TI7_AQYMYn z8(=H6;ex`gXIC@jn7!fG;nmDBfGd54AyPNkq+P}yPqL+erP>Wl;R3n8IG8WP#j&%P z9?bplHl`yx4Wx6V6Y^dyDN@IqY$<4|Qps4Sw!ldOPx;N@&=Y1G6UX*p{T$)H73;`z z)$Wl&K02f-7QKz)koI8Y$JpX*96OGA&$!r^>>G6SBRXn{`28kf2>qnYEYJ60-!q4p z?=Yrg>`HDp##2&00xPsTU=mvOGYTvHC0xbcZWBTJ1b-9R%^btO#ph=0)Y!<=pvlcE z+6?6nX_Byp?+U^=^s*UPznO~{9)g>U^kSTtC>a^5zltT zbgJS;$Q*R08)Gu5yZ#Q%&lfT{7dwbK8TN(uhR5N_^)O4P#Rkxw(vbx$Wm45*#!$7S zTp#?b$5lr2Pnervd_Qh5_6n*aH&v~AWDRFZ$XMvucQ5K`^U(w5n>`lgo;qzd86%ZyuHQ*Q`!Ke@R^@9`q(N9wSr2z)LigG zjkYmz_++>ca}Fuz8*aX^R(hlqiliClLzfu0RgXMc{FVO#eqIUx68;&2--B7tp5pch zxA6AMKt0l*nBzJK6yX|1)sH&|^>`8DLPPQQOE}C_M;CfYSqjzPAfeDee&DBs)|r6pKG+=zHKM zqcCH=q*V$u`q7ePOFm0-Gwi9@9(p>8Ys5?qH^uI~GlP0CJ2Vy4{kTa2D`l&2Z;8uH z>KpnaWxP~H=*roc(&1tu9kF{uz*cucvzXRgZBX}C|I;H~mYdWA^;Ot@t^}yV*eJ9T zda*TFEOaNd0_uGVdupDCcS1P}5LOFch2%>M$%!Pd-@` zT8oDnNJQADaOw8jdA z4AMKHqxd%nd&8aL1mT%9mv%TI$D9$bmZ+SDamml!WEO>Yfyb3VO=qMlSg}Kjq0XYo zYTDiER&=+QwB3}mU6>Ebwwjp3`{9ldivkE@Ca4`Fqu0tpKN8p# zlJWF-*zXv%Smcj&lst7IZ1*0hMj>WyND8zJH1YRB1=gR4y-UBtj0+IExv;j8|8kQp z36|;?a2CZ=Y%D5cM(zRbt>|xpKPg}h9>pxC^FQGIheDC+8_b7KG&7Ry^pRJ z42}%!^sn=OLSKr7>V}W8orJ|wQ}wYP`EetCcuF~NB^iA`$J7mP4MxzNyn&H{je&!~ zso|Txne+~3~j(=g`MzB@*JyV$fU7Vqmi`@C$?7gJbktYc+ zkujbPo(LTAx5vK12Yg5Tc`#G=!}TzyIG0U@nwQv`Y>Bg^#u|^5-^HukYGy)cAy`w^ zcig+oTh>of)d+&N*dAInU`@2Jh zwlQzG{h|iVoU+}V*t}W=iSTi3-EhI+I)69cUGE4yT=SIz@9Sc#zQg=@$*Go(WbZJU zQ^`1>>=zsJgD|n)fWyDV_to3Y*9N`$DUcJ~8=i)p6E1_Bkuy8Z-h6^HsUqxVe+gTI zM?hWHx6GU33;HhjX9j)YIJO<{fOAnk0A=+%7Qz=Y5_=5HMQAZaiFfxRa8v(Nuw>K;W&iMZD1kjx-_?v`|wex7cyn(rRp{4*F+*Um@`>@%mkbYV2 zBphPSqEmIe58X>$+nqg}ADl~Fs@vlo;=h5H;Xm-55e7w8{6TBf$VI363h$Z65W3EI zHN1ptvtyb=aSU?ScI9`M^>qnkhg@uZaj4oVa^Xm_CE8N+ds0*#jor29hJFhC<^9ba z?<(x{qslmE71!_X5#CS!-l5{)?-FQ=E38}n(*^1v(aHFs?^@!38K+rgZ2^mScxzw&wm z`NI7mB^T7l&=a(Ynlp6|CZrKFFc|bzKobhavBZAV-qrD)^ILZUrtwCw7F!!9-e5{X zCzCBvmYNfd2Fl;OjcFJ>fa8gWyP}-c9kuK?ZM^-e#6~ANP(7EDEp0$KPEdk5ALV)I6a4 zAWmd&1h4xVd;WHI#TTt(ZK<}lw)c2tOmH!tN4~ScCG1~93=PuCpEbL7MVo`kuZg22 z8hbk7L&NUannJcVv>mclcYJUbfdJeH9>QC#1r@|#UCxW)LUU#wgfmvuWUueG?n zurt5Ajjv#E9Mc!ueAkU!xR7kISZcY96Y^nxZ@5(8yr+sQpQEj<6)N>cwIo!k?kMB_ z(fdDUrzjmG(U)kY+I@^IO1y9-JTfrZd&xD*u^KHM$$FeQ0fTC2+hw2c`sjJ?UlCrz z|AGDeAa-O^gJ*on?v;)wwkv38E}BZR9(;c`Roe9>Tc zE&C>GHd?xo`8?};u%W#3v^&LjIWUfi7ZMd+&wX-@R?0`VD7A$_PzJlFwrigKzI86z z>XtbJ-MeDlWiR2{;VBhZ5gyFn!&wZui8oN`n^xqEGG9nzP6X@sq@+(flnHBsoJQZp>Ji@o&bB z%)Hj_wl|J{Tw{EXgO%Amc%QmhWY*uPW2xO#{Yxm$b`OpK_ewiXqSC*3$!dAVy^Pqb zP1Za1=GY-c3T(nWQSHlJaf^=Xi2AK)Fl~dKz4Kj5>{G2xv+jX=3p0Y5#j;jdOFM?U zMtFDPb8WktQALB3$9!{ZRsa-SBiv;Jefzbu2`d-*W8bM7ejt- zv2;btjrxaIP?v#qu zxl5dwpGjCA&eQk(TkJ}o2 z<^92(59Xn1*20XI_?wcElDQ5$n503LvV6TmyV>7Fgc*+>QaP_ZR81CVL36))U%Kj{ zmNToHDd$1RM98+%p}I9+2zIipI6=K*?TYjtM*2ccaD zg*R;9Ie&wrNDYRWDncE+r1YoRv%)iw`nNL_trfNEuFOPM1><+&$ISIjH5<3&V;&=CVPM7_)wX`(}l{Q&B+Wn6D?gieT0>6YGK#IPJSYDa}VMROT`TJNA z8v(Po+0hZoy9oXBK`%Z-2ctbT{7p@loDEA^_Z6MmTKRA?L;-OLhE&wQ1K#4QqnUlR zZ6N;oz%x~GHTGor8U}6f%A#B@GUQ*{Qth_-GpRg3HM|ZsdA;j_V<7DK?X0?JZLBTV zKF%3%4}gIk#MFlM&w(?0ZJIqCK_L!fbAnmE(|B<_1BS0V&U%_@dt$2xk5K{VPqz&k zn4`-w>g;)A)~N)6jTgeq%-{f@3O75-G0c7lbvoLI*?TzuaaHwBfupSlxx1}Kp1d_3 z?Q1PT9?ZWEUk=QGqwVBsqL=Q9G<-Hj*;`_aV3&^PcFjXjePWJEb1AS@Y<=;yBYg1=HI z4hlX7b~W;GtV4nU|bqgLKqCrfFECtAgDH+-gy7#P-{*_bQ#-xq;S*@;9|VCDVGd}ZQ5WW5A_AIk z5j}l&^McNm))?*R_ex2T5sA$A?p}%@C#+w=p@v3w{qW zwe_y2PJ$}&uHDG*3iy74g`@f4Wx0E#ckvV&urJh}AsMH3;gf%vcedx4tG27JE8g`F zIwpE+ASL&O6^>3Um|!bmGNBb&r=~+Qu7nRFBj1Bs0rw9`@_ukXbeHsw@!j@wIJFqK zr1VLRY%G~V)6OeeRUC19jyZ}`gID<`<2<7xo(lMP%QL{Y&i@z(*i7RBVmIZi9=To0 ztg#$}=_`~$E8Q`i2EGN}I^Of1^Pa!Ft9(-e{{n830oge^LC)8@LRZW(CM60Y{slVrlS9d2_&}38z*-ZoULy zfdsH?i*JP2 zz`k0A`>=xn@|{tz+W4%RIpkd9y7Cr?ZY`iwZPBAgzAWDi{1pY9)jjwbZm%$)xGb6} zR;+H;=wlScJj_O?7C~I60Q{n8)(l@0OxwU<5)huo=28H>akpf%Mlrx;*8r(L0h)O) zP%2OnH6CFYbNnL%y@7yzVL!l!U00A?FHE5|(q@{dji2km3=QQ0inI#US!iVr@DwLR zV?APoAts8nHq{(>cjQI|#C=>Ea|dYRIta!92;UeCV~Qyp^VsG<$k(YD_>DB`zu=8W z0!doK?*CdB4~WqLhSLI{`>{N7%HbGMM^iJg8TL>{R{Iy5!=eG-PCL4Uu3u8pl@e_fqKwJ%2iQ~XHK|QmX$@O7IHuRo> z;P@bF)O5Xr&O5-zw!x<8`&I5QxST6M;+mWE5IK1%7H}FdHBEJCZz@a^|2OE*E&ytc zv5xnzEFltYVbVWWpJDZ69{W9HW+$-g>%K8iFb(c32U0T;C;5Gpc2Ywc*UFT#iI~;X zP~g?3*(wDo)1X;RAUk=2xuJ550)Ue)kVYD`rq54l3E$LLmvC7cPpJf`AUj7RR z8+JkL5AzSj>wo}8d`rb1J0ZTqK{xxj?;vD(g6&~I%lbrb1K&FUl`|m-FA+$0#*$@H zgl%Ig;uI(%#ei4fRF@0Tk-J_>{>tm{djn^KX-pY#KM!8-i0p4`N~H^Cv4V7pdkr;w zj=p=mKYDL@MgYd1uIN&q!&;jIWx6~Z}W ztaL<;dcOl*#hCn$V4#yQxCk7xeO=$j= z5nR9SVGd?Fg6n-)x;WymYUcG6l=~UEwgr%GVSvCJfJ+uaoIFBq7^%{WhLkni0?vNJ ztqA7{Za_0V(9Agm|J`i{66f+*1gHaK=tZb2;!wa8J$ln-YK4$%rUO3k296_dEbpY* z*+AP^+fD2Xm*(v2n(TcJXv2ljdIHjgMSWW( zNbKT)Ib26NGYrw|8Rh%P+P-G*sL)(u?;u0H<+$y#^xBUm6GAw2l;M403PMc>h_VDsvtm4b>?<*=b~9_Lh0x|l%xK=9&1PuwJQyoV z1CgViM(R8Yxx!6b2tBKgD*N4EakTP^@KtUO4S1XMGnv36fNyT*7g@-K4+Ev3DJKQo zDHDDG?6MHicm|-^olt_&{mlSATb(XeW+wnaN$@Upr2(TK2Hw3#K6lFT5?P=FXfDrw zi-pX(5q^N#x1Cs_=n9y19Wu^KfaobcG11N=t^LzU!JWKV)>zLbBeXt>mqiDrSk^^a z^v|(m)r^!_vdXfzprts@EL&w+9#e_Gz>$UPS6LRv;nT*D;>Si8t1L_6>Vz+54X~0E z^dg}H8RoC#L2`B_--8zT-tQn%twT5z zXU8sMhq%&6(XDtyOfz|}LRz3WJK>;k(_PBD${@RNnG{n_yeE)<=r8eE@?OtbcS$m0 z+bT=-m@9HNPkboOPB^RK;Aqb~juhCAD$zsKN~AtY^WsJYzj0p;kr;f~;T z&9_w|EUv0Y9X7}gdOOa^ZF5aZ=f(Yejszqx+0@4`2$zgqRSg4 z$y1c(#VrorwcfRoiAO;l^M{77{{<9h$4}PB`2NYPLP{Q^)7MI!tCLnJ&Q6F^bkCfu zS3a@_mq}6m6!H%Wa}zr7y`4(tRE~@~zRFTHW}1FNB0d!7#+?aou&=U`0w-t_r&MfB z-vGtg35ATRfkfLW2iZ)2iT(!%qF+U6PJBR_?|qh4oD4Wg+t#F48nK}`J3ftX?iyw7 zL84F5Iq6`$kx4p=bK~l=rJRdxBnKBs(XF)3j^$JIe_SQ9lFzZc ziCL`$Z~&S>Z!Th^2odpwn0d0DBZ`z``4HQlz3fdTvP^I9WHzycQ*tc-#bpJ0I$tt` zQSs>54s!EwG2+)i6WiIl*ZLi{VnsRbx^gO%!Qs%c9Lwv30@_?hob5D6vIy-?62E3A%2I@sUylVwd2LDE@to7NgG32LJ z_$mHR>5Fr|yAbJ{gGzCcP$S3qAnCCh9Y}b}e{`JnELBOjHK-MLfS=-i93-9A;J=o5pZ7v;1kl*7N;+=-wkk`{e{t~$ClO)n?1AdE_8?l8eg|FbKHmU)15$kp9ZVs) zj%R`AibRsO(prVNv5qnx=u72o^s*RP=pEvm#E|maX>&WZQto+RTda+6a_=yG{z!M9tb0Ck`w#pQ|5lx5 zpPCg#t{=e=;@Z0_+V%v=m80~hzDjHRW@}?|;TRpyS9Pm{x6NnBx#RT5CUSYl2uH=p z$rCx2mX-+f=PJv$jUwFORhDsuqc-b%Ca$tfwOkHJ}W{K_W?wyesc{q(;#DA}3XZFs>8yPVJj@}Z4=O$r(e`OaZN6Nf33B$fG&f1X+uS~+Rftt?ce1v;#{($c{r-OqFuk1koFed%{utLuVx3oAk*=Rmss&XFfWK#O_J>s$Jdu7Q~cgOP6e&Ds;-Z-xXSg$kNiZM_CV4vZeFm3RE^?{7NuH>D zvR%q}&E_fM;k{b0;BtBZO6d}Lk z|FkG8NB%Z{`NWWX(9p8|`^1xP%;I06w*u*J7Ket2LTqNSU*KPjtV1y==A$+#KrWhhSBgUd#tho( z8?G`*Ln$TZL3m+^^r1InCIqK2WTE-{J$$^g5~b>K7Lw${(G=%!krZ29t>7y{KGGjz zzKT;2tj?rQd(T?P4=AO?jA8CDWVU&;U9c0$rZ=PC1}l=|C{>Sj8utS=$QxRYuBOJ5 z3bSaXZXy>Vols1U5pno1nQ9ihvYSPsnZ+mJhZ;Fdi%~DaLZGje}!1O)ly>FC_40&J{+Y1j_Qfv;TT*`drNei=hJUCDx zqfktWDWkp*kN~|K{fciywxX00Q;pddCb!L-&4RT^{<(Be33|~$W73e8W3r?H0WuiH zLD$>xrZ;_i!u1G{u`#3V1yW(3F!N*?nucqvR07lI_V zn0C*fPQF9AdTdp3q`wQ9K+Dm?vHb>*QcBE=z%mB=c+=;ltHgguB#-DtY(svB4_l-y z0(DF&e49yHpqLa_nJo8T43kmxBDSVn+*gVODNWoE?qBaco$R1L#Ds#3pWHSp;HxfQ zzc49~L2Iv+UU*z0X+$rgPcd!CAe2&~)j$v8M5%h*7VWb4Bc{xxek;uL|cCsPYseu%h6{-oyaPbQexTxoh9cfaa<|o zp-14z7kUx9ksInQLsGIp9djKYCzBp1CdHl6@A`0_CsreIktQwi?i0x}dJ(gPx#A-y zP)v?)7idD>pj17!lUl>qkyNsx9GA;?^^MX<7hEL86bXOylc}^AyVO|W?@m;cX1?^q zJ3}IeO`4|cYae-rVsiAqfhwf5jXtHMy2!ViBW-b!6wC03e4WUz^oQu1q3(n=Nh%m6 z0`s6+lqAlOWZyN3JfIgbv)MI%Qp8S~R5UmuOq!vX6gOFU>mMPKk@O<^IoE=CQA&x~ z9_}9|TTF^5y>swKf&6V=q)WdAU+W~FgOW>ZBB_f~^|+$%`ZE$r+P4%*~L=2lMxSMki9mMSuTJy)TfiC?-cYm#UE&^kx(^)G%*t zGFp*8OuC1vTPLsR%_wvv(M`?&k2pyfh2$ugLB^YR2&|P^z@eRcQRor%%7_&6bg-<5 zwX`7HgVc?D)W|<5q(;rtNudxOMI1R}kS4Skg*hLJLTc0=nRsZy(t&Kk|0yv}<1c)i zOo?J{%i~m%5T?al!f@<5L5opGInp16)TqN8v6(;C!tUN=oms3e;AQ^5XfgUV)YZb! zM_vmrz%D>2LS4zl&@AlwN-tuzD7QmoA&SY-H+i@alQ@Q5&XRNH%`w4_afE-3KIl44go;){ihQkk7lE~AW z?L+OzcPORA3=aLRkcsqW43?Y?BB7WRvq_&ECVNfNyGnlY&?KECz2`^?fs$4dpG%~b zS!~JA*2oxIjN*9`LLoH@5&RCbFh?Z+m{f;!xYa@;t-FwBi%n=TYLh~SqL3PO8hgZ; zh2aX>Y!=3<}^*5@Nwd@AyB>Ql41p|4~Th*P*b?@_nSY+`$sxFY=*8XUnd< zQ4fvCwu+rCqoOT6B9*Fkw$zV;O!ZFcY>}f@YvdUUBcnEGq)&AeEOBHz{{KIc&O4yy z?|tCz=r#~VX%A6}rb3}edq-AFduyreZ}^yL+&$j+-uJ0!YABJB3QH4;()tf&tm27s|A#Ri%)t3bw5zlhLTfEelnF)}d0 zDLQBsNNeh0_%mVyl?x%K0IaAz67)f4VM~yKDYmqT(MkXt>MJ-nPG*5fp{He*Vgh}T zS&#(j&A~qJ;S~m8MTKx;du0|lk?=GIiY9sw(wbt2bj?80q+%5mhzUO1e=+VUX0WaEffWG5~MY?laJoYTymg;WsbA_EEtud0E`qTv>T)~?FfW$J&B337`?%gu1~%d zARPK=nF)b zAqonh1#KK!s0~2YG-uHy^a>NTlZ`ZNz>l^V!gG29S<(tfEwmHJnwBo`K@FHF7U+e{ zVkex7X3WPIc5sjvfEC39ZN~$Iyn>@&0WIit(kE=BZi_1tB!t_~3nTS5 z7wwSQ_KG2n+HpV&nk5`9@(jqD9!9|bLfsDMJps9cw5FFz-igr;nMn@S%1oD~YsBa| zHsL1t^aZ$xB~pO^d0?biqOBmUY2IiVss)Or3czb2_S!DxNs$Le$`rH}5aTi}0^>4qO4OsGA714O`%0Tno~gT1=v+G6NM&v&Wf0upkeB7|H@v3sOYw zA?rOHJSmFQE_jQtz<;xI5_B8@SMM3f`PB39NnOA|yFkoFo|Y`pEJB3bpao+-tMm{&?QY2~$PudNujL`C52VmynSN+KkR|PkZ~=1HThikf6;pCJ~R3~FI? zb0zkMBTBq5&>SQIXeW>*#Q@cUoKLYr&p=vJe9^R3xNr!0?FJAm?}n! zDf$G`8YXZI!*CTAq17O*DfZ|9mefiZqzAB}_@j?9Lz5I4gyUxdgo+FTu!7fg+kSvx z73vQXJx}wb@ToA7u`L~^y@Ekm40KDf2c8r%TPaKjWZ<&rpcNqDAu2>U*g#VvtWlNB zB!vJ`*hH`6Cc+sMnfSM4al=H&86)GBbS|e8BGF=n=EI(gDu68M5?&vi*)H?YL?)aF zh?cquUunzv1qXFwq|FuDpbQ{udM_^xLVC*5-@@)G)Gxyla-|q4W#Q^Mpv54qsS#vb zDnPqF#T{94;oGP9ARb6-Dm zMsoz1g5Y@>0%T2J$^0ckOh5}-DU5Dkz{zq0gplQpzGJ5MvLU*tsSxMCf(QN4U>T-L z68R_}&$E$ih1yNFJqPHbPy*1gvp7ivP4JA4f%uINre-eda!}IokYr) zFzh6eAHW|fEDZ4JaHoViw}rlQrTm>tJxrp|QCDaIFGRH9#dq7}bz(l_BCJDi8Opm-@nic(nb zm`Nh^8mn^C1WhpPVfP#S6jt!t3uB5##pocY9tsCYA^Tp@2p{!>>Lnk=y9H6mmZLdi zt`txCHt{NEd=Uk01k;zJig zNFa1dhST7@a>Ss4RW4O3gg4+?U~joUl45uwRRH_a9f&N5AdX$=xxx$)@}OhvBA{I+ zlp#Tci_lvcMoTjYv`7wTrv(Q@n4v?!-g50ES2PC=U}jWE-w5EVFk^rdjW6^;TY-G( z_k1kz+!``hpo%6cz}2+V;z=k3 z6FnY6)SwzbA6fzoB8*|9+(wD5a0T*J#18+#S|LON`p`ro2lNpeX_n%pXsHrT{w4_% zqe4I*`YIBh8;=3~XjdTJaw1NDLy*v92lSzf#2sREONQEH6Liuhfh+X~fzmNRr=$&} zKRsR23+H%D##i)_`OtU(^rOOYtc^1GE=E*ku+aBQpTNTa(1+eDhR=Ugh9^ikC-oaf zMi;F8x=kXtDWK2>#8VLu$d?u_l}E3D{HZXyv0y4>MVlj8hzTNsyGR9Pr^WJC8_8fkU#Z3i6%|MX+`if00@AmYb{8BcyWwl zN%KSoZT{2UD9b4nDq^X*Q37#a_9cKH1=?2X;6vX?Wv z;e&@}qOG8NDui=(9KL^OoQbZ1>YOJ+lX==RsFF1q>eY z72Klyjd_mf9B7_Oy1dcD-3J5(&=ytJ$N6hWyjUpjUcN301KnNeG8xVOFK>QcFbCCv z!9y{e|KxD*!P^jj^`Fc^NXQor9$H&i41+}mIEM*jA!~hJdch2YK=+hi%qz^VD$qlp zu%^Hfju$>H_{>Ag3?Vm#m&9hKLE#lPVq#TENXE1K3vD?sp$#TWf5lr;q{#guMK&|B z`)8pY`#ATH1nrTju(^h-$b&JF+cI@ITFoEjZH4x)5&RHxkA?aIID!M%o3T~2K=4hB zF5(1+sbqqvAKGuTuor`DA?#2jus2Oex}bU>e`qL^v+?aGfiVLa3`kKi28u5F1kxW` zj%~|~-6-iaigH`S95+e^jd}xK{pR>84xF(k19;JQ$N*m4(=Bik9CaBZgI+j`UIxQb zM7M+_`UDBweQN-H=$UY^A}W{R0dce#{gB~RNhP$Ut+0chvHpdh)=Drt@wEm?rSo~L4zkAdDH9+jZSfIjp< zDRh}E7Gj)0!eG|_0R1Rl=mtoC+EcL$(qDwLQ6*u_Djm>|qKDc*`h(LHdysTP5}q+p zfPT~mBx;mFDg4zP+$hCVfTI8;bqCqzve=E%MFT?0PS~3%Md1Je(2lML=}%3TlFJ~0 z_D$-D0)c#K4`D#71e2T!sV<&}zG9|7BjUu!WjU_&7a|i5OT)+rlv<0Sk@XrBFGd+T zfq>4y0%z>xO5B8zH;i)gh^27f-Us$(tdQImJQg9-75M6X!XCj&=#+rs#keB+PZ%vh z*JO&n zTX*cl7rTl2AWX4L(I$t5(FA%5iVuu*r-+c12gdKj9|G;dNNbenqMJazjE~Z9qC)ul zdSWvieTg!FeCcz|l0^?`cN-;(hZ~QxjOVLVz z0E#&}0@9b>C*2NRYd}9dQt#pe0Ao@dkp5Iy(C`u)s6iyM^~EU`=s%DpFd{bF4?HNI zDEt3q+hveW6pCD%T!0(&o~TI>2XLhuw3%Umck?PY3X4K*g`-wi<6HvT)`NUPfxedg zS~m)U!QlarCAf{hV;wGVFNv;WfQG#GdR)*vlq{3l=$uSipozh_iW%@e1t4LBa|~o4 z^mKefaF$AKA3@GhrnXCwMv@!lGc3$=LKBnmXAYOb{TmACN3DnM1qSH;je+!s_p)~i zNcu98MIsW=hgM5M0|&^LK1Sx_Bf{~8@Q*CS05y9A(w}~eTty#j zOp9}O-=}8!EVR)ES?jAp05~_~3DT9?2b~iDb*(^hQ{_nOhG)Cg8G(OOUqrrMa*6)v z`n2-BaKtcnm@!0h8?A5bA5F9R6j7Sgv-;wk{7>yI4D=D_r|BhKU0!)!`3b4Kz$ceL`m1-<@CY1#;Rg=$yjDpv zj@~_I_Sjx!xyN|I{-|#&E~=dCe{-x|99G%bmh>`KT&Z)G=|7-o%xDk=Y?}H&@(K`T2OP`6Hah3CZfz zN*ESfu1c}UwU=C~NV!xrmbqM%W}X)9uc~MAA*XFuv9IJ&Mc7q_(#e&JHeX1#bC*-) zJS{kBPY#ysu1~wyr8XKIxpgSMb6JRdY+q{ixZp$a(UUDN@0(ahQ8%C8kZY$#q263p z`B7X|A~;+B$;QrcqiU8;u;;wXU(GMxC}|R_l|8)B|7%m~GNUX>X2{CDGnIzAPN#}j zNE)hl-egR=;I|=XYU*k4R`r*U9UAvaOeOKhZrquvX&!cDb7x$X(@uqhciU@Mh_*;0 z8?QgJFzZd4w(a!>y9Mfh2d=TpCK9Gc_MWTz=w)lMu_t?L*oAq_FZ%5VNOffBtV&Vy znnkiD^Qtnh_bW{gRNDF?t=ubp+SG^J>)S-| zf5p-!{Z|fVtVGF{-y3*#Hh;F=*jB+6qFs>TbnOypFma<&eA(<@w@Y7^PR7X~4WpUw z9-q`C3{gEUGB-;2R8n1cYrsb@Goo+vwYYRgf!vJV{S{*(`y;Anz7Ba>w3eVYh2S+M?tizHjw@y{SCaEm4;m z*Sg%XQk%1GdbVM_mNRe4tHF$VhGZRCeZ2iqlU{dZ{U(?2=EW~)HMg{?)=JGQqR$z9 zw6*C-Y~46ulg)S zQ(aUkF7U)$4boLpot$4NqbfQfOTS0XsI)#6(Z6}h z5kJ$6{>TH4b`z)f3yv>BDz5O{!6Plp0Ms=##ox=j&KNyxRdZRzOrH`N>5xn-y1BjD zAEiP1j2UOh@diov;h#AUJsS%*4*C7l+4FMNNiQVDskw7Sobrrwzn*^8TONY4u11V3 zpiFSycpNLabYLXLf*1EPbLLu2GsCa`7fYnW()NbZ8y_iCS4h&DQ zF7T_ix!C{3$kA>}vS;S#>hmVOpGsSQ2z^Dy$62=+@~_;V!$hZHl}P|x1K)F{%b+IuJk+cq3S^wb;6tF>Zwj?-htb6=`Yn!922fBzIZ}%|J$_9 ztCh0+6aHJ_Jc)NdrdmVTcJ%G(sZU*vvSV5|vm#O!DE@8gWRX*eua$`xBEL{J+LdqY z-n1ataqiR4J?9sRy`(Ga&UeSsW8J2w-%PghU7^|j$fZtBBwyx#iaqdi`lq#~n~x@p zIn9;-@7COkJkiQ3%M1I4v`vX9_soT1Zg%^B+-;v;+#^|Dn|kHL4@-x}0(msw&T(e)3Lld2n9pkH~a;4@%(Gr=@bp64KSQc8ZpkOguTg_uB*u zr)w!OiI038wWmCfJU%Q$;W&d07sQ`yf47GX>CAZ$z9n^fh{Vo)e7Iu?87o56CGzF@XXib(o9?peT&7io)>0bA}SP9bd#DB`W zl1=5uPxsxUP851OXE0;jmNS&I?)%q07o!MpP>1*aW{~EZvxxk%Yb}c(ZBXL{x@SC( zNmv%6aQxNWA7GN;LzZkxzeAqF>Irk?sB&?A*kDc$|4uv*#oe2&k?30^KL zmUq8bIiW}|sFY@|sJD9bg2u;E%aX*cISV6R*u42R_YA>Zf>@BQruCNHB_2Paa{t`a zx2s&X+HO4RA)FT1FFpFM2(^R5bRBhxHD_me^`)RMRGYuatSw1l$E~J}PHP+Ir*P3{ z?2_BY$&@T?2)xrV^MKig%=4duQ<>=`7 zq2V>wLy7y-bAzL;?0)55R*;$yoZ9XynPZ+SEYq5j^aD!_^xxW@K1L)+z3UzB*i3Qp zAIf6JZ+5j)Z6BSb*s-l~+HG`y@J-5(kg z)N>>%2AHlHLmC$AoIdyP;FKTk>Zykl_pZ=TJ@nwtaT9a{(r0My5RF$R+;Wh{UXkUF)u8hWUdhR45qPF1rjz94WdJ~sz$_UzG^y=Nu^A^&>B2mNSyNOD{ zu7cD>X_tLAYV3Vf+Ehl&AikWqGdORWu5bOO&nfBd&QsUi|L^#7J}Q23_V4qP+8S%R zva@3UIv!RSzg=B5!VNEFwrYNuX?$yaf7atD$wHg)RaXUN1Ka~;_b#pZwj|f~Yy9EO zx?xW&zJCk9IIp;d>rkw{RduJgR5({?tlQ$r1D_@ z_4+D)E-|wyGUt^ao@n1gU8Cyyok8JTU;V3cDMiR?EX;E z%l0kyYA^WSJwGI_Vsl$)mPO9@*vnT-2==ujMwjP~PhIjZnVR!@F`7Rft#8#E_n^k*#F|)X%-9tmmS;J@1R*9xFl;d#lp2_+RDe# z4H3K^{`>l{r=RpS)*Q|ri78leV6yzfjVC?%#{_XF4Bl)v=?e|mvL`BY;bnU3ZI#+y z?gz2Snfeb@i-bsa*6;AwwjGqd9<_=!Y=Pu)OQzZP$_4H5yR%i+O|zi>iR->szMr$Q zc*>>L-{0)bl2o%k2YoO;F|w{>=!h=TUkMe~u_Ze=k1OnYgcCP;T-Z1x?WFff-P3Qo zTKc5xVK^OJrt2gSb9ldNY#yX)GlQO|ZjB9c4plkxSmWd((SGP>%3O?LD{b6K;*Gw^ zoZ!N=&hUwg3gi#o;~ozZ1i{J$?4oT>Y%kf=dieWV>t~_aY1`IuEY-(rx@)T}_;Tn8 zu8P(k{?}5*nMh8_A^u zobl&Hr&Z0bqtN$?(SU5BkBC6(!rGnlAlKpv+;c|=9LPm6*b0Pm_)nH-aJ) zbRwvZS0`T@a6a?6%1ts+XjQA!zgl_ga_hB8QHm+2B9=OJO`3Xt%gMH*2ZZI~J&o>n zM<}GFw)^(roW#iB^|t^1P3XCDVoRC4s6#AnvU)z#;Dxte@PBc~6V=xJXLtXfY4`aC z`6Jszb)_Sxn-E7&1qKl8(J_$P^mo#2B6JNsZKD{gG4y&1ESo^I{{T*RC*}+WS!c>`3`@k&kdsjpN;*DN!!^ z>vE&iQYcYD&SO)r5BN9UDBUHtL(BDXajD{TSnCO>MGNBFp`F-Bg)?plY|7nFjtL(e zS#{pvrQM9b4#$0SqIV^n_Ej|qdoghSXzf}FOK{`J^($?EdmNO4UWXPW>&K7#HW*HS zbNPJ6u@P~p@MY!U&UYi}`U{+F0&C+p#jkbSJ@v@F{8L%w{-SHbsM_*7*C#)4>JLhd zmP^l%@pEZX{XMXz*|)r$cqhp{-h}2Gz*j>j`Ry=}2dF{QM7AgqNIPt@WRSPHIJsr- zrv|fUKDnU=NsCjG*1oe^@yD|3V$E)enUGOF)VA(v&*a#JvwWzr1&Lq$FB*P$t=~4G zdVmn~*B!li`SqCkLcP`I5vP*#;~V^~O=CZ!_QZ;D;bQa*mq8c8c|fEgd=YekuoV6> zGSn0$!>BKyMsBxMz$=tgoT|O&Oer(3a19Q-nCcp)Z}sMfdWTi@6tqS7TiSIlf0$x6 z;!UnIPQ0{HKip%{*?)(-%Bo$ZgS@QbPv>4ezN=Je%k~|J9!l*Gnr?XXjdJUu3V-n% zo^2TfA{ozJU>~?JWO35*UJ#JW(EuXUghkBuwI? zNi*?J_li3zOlaKx#8G$1&0%$NlzFmAw8Z73^0&UchM!~zH&}B1#7Lh3<*PaJxDa_c z?Om9Y&8*SfEB~u~LAG$6C6#AKKfE%%~A?8A1Z#qPnQ;-iW=;f&zqOy z@-{p>bue5opYmPzicZ5~bc|;&Ej#Trlx>pW6&GBVd^lAc^33sp{;j(LcZCEb8fKjM&syJiwh~ouV)^= zUy>q-m3%!#e-^FT?0hjWC$2tyLbRgeDw@{yih8T!1fH#AU-PHO?kW-UZ@R}vs-?&W zt63O){&1J*hLZ&ZTsXNWbKF^URlpdRv_x17^iAQbQwO+kc&~ zwx_ecrR1j&O`VMkGlUhH=0Mu?+b}bZe6W$ej7S!tB#fa$B4gq5y4LQd(FL*@ zj(@3DT{r5jj%*RQ7hh|xd?L_Zv}DNpYn)|n38dkIA1Txpjiis&4W zHeH8=)tL{lF{E9@5lw0MG2l7%(8BF*juG|g>*F`Lc+w5J?=(uwn#8Ko6Ak0{`zIDy zJXzimF37Nsb6To8UV24Zcc=6rtj29=Uizlf&}7L~A4!5FQ#%sbjC{^H|L@qVQdm7> zieJoXXd_5%x`h}T0r`MhFm-<(roS*Q)q?Za4%gkkyF|&v(#tV7#3&;+&durNzu_+H z6SZYOMeXFrlMA04Y7Hzp;<-10pYtPb@{*rl_qW}s;lbJj${hSrVQSg{K#N{R#KLMx z8BP=b5TQ^RUJ@3H(Kd{sPC`@Z_LE^RS~WXu6WmOq7i9g8-{iRA-^dky-E5@Jcal|f z$)dAzAEp|)FZt?cl5!!N74g{8<9*{9tEz31Zo#s$OYQu3)ta$3yM3;v|1YOMxYFp> z3$=6E)oY|dd`X#R=ijkL^Qle-!3o(vGu8xgX1u?va#E>$1g1KRpagBYmk@Su)#1YE zi2qN5uFJ}u#2=8%Z}xt3T6gy%5C0iyAzLG($8Ek0`L=94<}6VbEG)g#y8nHkX6AfT zKc9@YEkx*jBmZZw&%8gjOd7-2KJwyX<*yra);jJFzPNcb%V*62ZRvo2Q&HKN&4z?@Uw z)yE}w1o~z6mxF#e7@67sZ-eCyc1F2(=H$D#t~5ndQpHK4hU#N|J(EvcOj{8fm$&6j zO0>%s>X+`U6NiqN69W>mzV@z{Qjyt-;b-KA*6DiLF?~*@P1v3qm1may*0qhS-%@f`Fs+1smV^4B7HaeqIM)n) zz*VC^k;3vSB}>2%MdGVat@hf$jH!0!>dWQgF7DuNv~`^RXKH6jLt*&{5iYeo?%V%p z@?z7~D@u|!ZzbbP7j%5>>#}YZmM#}4kd4g`-p$aPXe;um%6PElZ^YL*eXp(Cf7jZh z6(|=<(59D*V_+s17e;?X{v%L}3`c~U#OMLWrJ7)C#VA#VLh)S@%Ew3zm!L`jou$k97o?i!_6+~hS#L4huOm}oYksJb;lZc$Hn$Vk zO1p^uip&oCABh?d&AI}^v&*;KS~FSW$>R_0kLv7-6%fT5mo}M%`A!2sE!r+Z6D`F? zYAk_*0dy#;XfsINr3}Kbl6o!b_cooc=Al6cHyuvz^B+)o{P4|%;0E2|OM-h9Eq4^; zzv@l0Z3uq6r8{$;=Lo~`9<`NLl}ao^y*N`kDTT$Hp8>UKz9KI)*#?ZT#Ayze^g?Lu zBM(5GCFjLqHJk1;6tnbf7cSf|b@P*?PRAFt>vzpsFV}vSW=l6VnLgT}a8q~E;*j{Q z+xI7kZRUOn?w-@4d<+&472_=ElO@lg-vy{etr4S#*hW!Azd-6PRwG^N_z%A;iDud? zR@v}AYjM2q;uGUH`d*z^t!@?XkXoO%ev_;`qUXFcD@JkirIFv^~m+VG`Gx|(LUOve)(yy=f)_L~AqI=C5wTfoaqx?YUiJ!}-JDT{1*Xj4g#*#JFi!R4} zx;kamyq&9xGip<{0u=RwK6>`FHC-Tgh%Z%Echr35Pyb=5yq>)&G3mZn#f*xT|vRUTL(I;C&i~_b6XWy07s^@7|x6b%vJuN9W~qCth*?rE2={ z`5DWSQPyI@`gl-Z7~&pq=LOWbh2O7j|(4jW*()tw4)bL z3pKfMK?z$CjRR}aBly{{UvC9eI4ql!#wn?=@2DIu(u{PFh7WB$okd@rYjpPQ<%@TP$K>o!pA(p+oAF$}#Xfi^i=0zn!*n0!78Ag~WyKsy^Jy?@7upM|)Z|-VUhWUO0PQTh`RgJ3>?}x`rLjUOMuEeSr1s=#q=95m$rU z#gEpPW$)fpwEl@1>tp9x_K_g=4yMx4d+0wG{57RZGm5;C6j+lXCRK{UUG|fomii;N`{ZX?E%Ep--fqjD~wu!raati9(Q6HlhJoowZfRMS~yMm>GYe&HB)!m z1O^=1czUa6+-3W*zowUcDx_Sed{@a9w8|B~ulaCXHcADAp(NJrLX?j&SDm$*8BrE> zrRqD!=(VHv`lt+)S-qBHJT|oORE*S$*;X`Ok=IrIV|=#figytoH=oG%S#4y{^4z@P zqbMnVEBi?8!JEb7{iZuz`hp{~e9}Mo9oEfybf+dl#4lp;tm~%thEK>azu_Jey?SeQ z`W)XsGZ=&KkMa1Y4^QNJHY`Q6-QcTZyyY?rcM8!mP&63z+&%f7u)HnR|U4mXx0BxIHY@U+r{rrESv3 z480I5>$IPx=M~9DHj}AWzM%8`M|&M>$Lb*WRBARixYDfTQv$3&a9}H-5hz1b?xM7d zYlNn_<6lugd|_VVA`4J77~`T#>_+J7VI}vNFpYDQ=sYDFn8p~f*z9^VjGewH{-;ZY ziq`##>K#HeR*FP?KJ;1eL~9#~$G5Plsgq(XmwlT!a67u-Us8`*uO9hXiHX;0@Z$nvt?khjqzeC>if>XB>dM{D^8T+_0p z=mpeb2A#*d$wPkuwdfK7?4i{0z&|OA*Uu}c`PAF+^M~P*Wvv1GW2PnC@P9v>^J&%T z>ry+xQ)0o1{5!jU`Wv-7zV!JV*%5uf`|4o6*Z8fXRc{J zm`YEz)Np$l^eM(-!^PzX)o6n=Yfr$a9O}XKqx&K*bQfjF5Qo6l6;F8TE}kgqKh|@_ z@69X~($3RebG<^W-uSPYc`u#g^&_wC+|id}MB;*|5R{??z=7i1 zHVRUpfS3I-SK>ERIEfgmaFTJ`a**+q(mw*ZT%--))F>s4T_B^4I7 zriQCf*am}=$CcZ9Y7{jsT5NX*PR*Q=buwV5{Dmv=^)WSBWi_z(cLT1%RJ0VNHte=t z4{|ZJ1lEKCT&Fd`mfF||JRGmqhCq(Of;A+FQlVtSmX0>%XedM8ppWD?_})D6IT-%V zzJ@k-<5u0g;!EO^s&5xmpZiU0vk7)s*Oz)Q2Y5Bs)6932#W7awdm-1}ivU?_3)2sDaINjT&;ICK4n z$g>XRt&**hca67un|}1`$1iE|&xm~yx4|dc;M^;t=DMSX;(wAwCugHg8*z6A))D6e z=ulyRry2w7s_O))8*Kr}2XIZPZV^S|Kt z%vJvR-0#acL2qN!!ge{HR-Sy1S?^IANTinaT!?#_rYx{J>|z{rBPt^Jz~UW~9PS0z zA1w|*PO13kfFNbz06G|U$l#EqjR07p)D{t}O5v(doYD7WRmwApd)xgKRmwC?yq@pF zK2^$N{6Dz9UzOrPh20S92UH<6+E*!BA_KUuqX1^Yy}A$NY*>YP3`;6WqT8|rE%aSx zD1d!B2f>rhm7Is|bTZUK4J1myNISq^feL_(sM)YGPL>)jgg}G+7^xp&pPS6K3=Z=_ zGY{bs>Btr2Y`Oyv*1D!*6ZNMUu`$4ShXZN`GJ+n&AeQtr;ZY8v=0PHTNEApQQ;f7! zp%d~2GNjdrVSgTw5j{YZBSb<#0|tW}=iyfsR%n`HAM^}+&>{p2k^Euo>&D$KL>7Ps zjPnp1x?hTdutJ-}S4W$H4CO505C=6R#Y|fzvPKtxjOc6Fy&UuwyE1M{)p*}vCNdus zxh!4)Zwi_ZY)Jdf^FnJeF-C>YSuc3#f7r$Bxqu}&C5dP{ccb&o#VISS%Dvk+aO2h_ zy2XF@Jf?T*>(6T%4Q|ratlKQqCCk%97%QBDKH{9rG&$c22ZaAScJa!Yp~tEQR))UM zqRbL>)4wHM^jxY_I6T%xIZ-YRWBul#MFqG*D+SR^a})+_I8Ti`4PKY-4G*vGe{ZMK zV=3}oA7&f(DDiyM4But5{(U#S;c&u{QyeYIG@(_F(-KEg9?T1IpH9=`x%-5)KtY#UhOZq@{r3DPW7rRX!v_>YZld`tHTFa3ofhGb(g^WjbkGW5Lq;gGvLG3jYvTk3U(tG&N#PD5V#@qt`I&{& z&rmANeoyeu_yZT*S~3Oe(A|M6*CKVEC~1-z4Avojk?d(xW$gFhP(uE%u0eynf!u*vN~Rr} z!Nni)ro^1HgO8SgVqoSZn8QrvjaO2-l!wZcoaVe-p1WQe-JA3?k+w3ywD{MyKC&4d z5eu>*5F@^TQ9xcO%3`7#tjwE6cJOnB%gei4>mJ>u>^JaTI=ZGU`apt70(YIzb}g;w zVRP%$3Om79HVjJtlwE&FxR}37iu8E!HOd*02|Q=C9N18xt&7ob#( z5DaR7UnNCcnNmoE^IIYKh|Fn#I3`4o0cSG)@h=EqZ!1H9FMb0@6(BQ=3__wR7?Gd= znY~PWmOxp6GwFnIy8sa~9G1Yubi2&kQ920o!{{|u9 z9RkvbevX8e>K<%@*;G2JkQtF=hXnNide8=?sz{SirFg<_lxQsR3Wz!YFX}oH{l-9< z)aEKyrPOLde3!3HkSVORm~j%n@g9niBfu;OYY`372-X^;z_I-&=VW%^ErL-~;1$hD)(QSDl@G!wfxiZ*2LPtDcLz*&g5juk%Xgk<)=n1yT zQ6>FM3X(gGe}_CC#4s`gG+<~-8#xd%BmgUNgG4OX5oODKI#@p-hN;Zw0=#%(gIK#v zdCHArj={cP*#+6G;6jM-b_V`ca+QQt;T&WMY{*FB)G*KT&>B$mU}I`{kptQ)OIRov zU>2}ZF(?L%5w?8MkQiOTirjqG+oBcdJup1tg!c=$Tr~A8_BzV8hSfZ10VsM3nc^#j zb6C(W3B@X-h1;2*z(TuZX;Y92TfcBnh{~}l?<@9X%H`XjZqW1@RlNI$IUMvE6azVB zX2~Hlq;?J`m`h6YQwxy;CKeq zC}qDsc%}&5l3kXS|12Mx6+dK`jS1=wJUe8Lv|DiY-?+?!Cs}A2Cfz3O7{|)TD&trYe}8--I*uLXq6@MQDx?dc?aq&S(7J^{s9{@Vv1HDh9{$OE3Tj|`J*5-Um}2r&bWg9qKk+BW1@6W3>a4I z?}tW<5MQQz=58(^pka>P}aViHQ)DNcOyrmWksu}d@rr$wV2+0~BRn4;G_B*6;( z1{*?Xwae^GqN4ypN4}ORk^Bs1y%0@m$3?iYjXAHyi<|b`FCC?+{jyx^xhCXE;;fB> z8+w-7DObJwar5Ju$Hks37%p3bFOX9p>)38+JFuagK2gZ>MJ1T&CwQyi?FKlLHlMQy zB2a^I-giRCelG5*dvwkElb3R-*_Y+yYHFNX%AV*x_l?>YM(*8t)wZFs1OB*S@T9tc zYaJ|zk)TkF^ExH*>xmYVx(~qm%K`HR)CfO&ZG%o8(<`m5p7)LhzC&)ZwvJ2!|4VjyftRs zhYe8lad8vG@&YuY8A&zKZXk2m-PbLK9!e7^ri=j5S`mDK&#@2O$Xz0cEvDKJDGF1_ zXug6F_K7-URnC%7709DB;5kYrWTjw~%i;^As1yvw@~xseZV%5N-NeZX`l4*EIWJdC z4nUfcANiJZsYsVAf&E+9pm3Ww#rw#<&qd*&nkxJjm@xZUq!1O#+^23VRDQM zi;AEr^-bmxD;h8I$nz_NuKcWrIFD1@)A>flO7DSlwM00a~Bne4rf7tPnk!G zFt4a1pI`J^gc@ZYFGwakw}71o@e!ZOJOtt|MWF@SMRx>f>LZ+~mhd_ASz$99I=aii zFiUBi;Isec_vAyA_f(n3Z+;z1y(pJ0gvbKeL(vpX<83K?oIee9gKnba32({21!YAX zA^L-_kpC-8D5Mk^p*fFna)9(3N4>~D{~-qjgTYwQMEZnti)qKAphKX~Rx(970y?LX z34x$bV+SQ0GLqePXlcPJh`b;(oEItc(%3^BXmV*h!6hh*jumMa8Y5TGOcaMiuQ(p8 zE9?N2jdcYkQO6lA%Hg1+*jZ^78W2okt!BZN)jP7Q2SjVQTZW2AZ)pgoB>!i_6&bllToMe0H5GZLf)X8D78ygh}4DA{6rXwzz#}p#JarKyeiy( zt_Fj#;(#PixJBT@S3?7!&sMr7`N7ZQt%9j*r0^V<5hETGwTO0#(%``fhFMCgk~_TT z+=+s{ViYIya3db`1iVwiWD@bQK|X>vh4(?|h%SLMvOu+5})mUkl$c6oh^H%^P7{_G>hWHgb zma~!vb6ihl8MsS*IMFOmfgPIs5*IltJk1goY49NKfg>1<6)K>0^Oy}$F;cLqWF$Sy z*~Q{>pp7b#rH}B&3ys;^`RE#`rV3o{EY=e?Oep@wsfy0fKaF7?hlnI|{*S#ke~+@r z`iHAKNvG54gmi$Agg_!o*h5G{*r7mn5NJdc$3av^86SsHA4eT^Oo<4j)7#zK-FrEV zgQ$p#5)_p#0ofF!0oi4fghh6cB@p<2>WuB#b!t0x>eQ*F>ux~y=}!N4 zcLIk_4@=DSM&to6@r>}{%EJ;6N{v4RYCZWL)z9mJc2Do1{;IsGjOPuK+gKAC<5rw_ zUb0Q2Eb0D0ny1+FcRwEuwA7?T=XlO5wZ8K~{*ol5*9Vt*|LNBAe*^1g`g{CQ-zxWE zmlczOj5g{c&w2N|8v^lDGP9C!p>MJePC_}*Qqz6>gOC!4_>aZ;97#xjGM=Fhfi5|K z^)TKa{a5&A=z}<4Cleb6#ZQHxN9Q!;-|;gM7=psn(mF4Te~L8>z@B)^qEF%#K;u#q zH|OW*p6j5;gQrj1b995{5#&+;E9E0QjvU?RdOX%;aOUU+rncdD%W9Mc=J1+0e^Y{Z z*CO#HfVn!HsdjMZ=mzN@!7Ek(2Bu7lPvc%m!kZV{5x$~-BF4umGO8qQ=5GNSgzc}d z5x%0!B&F_(Ba2R6)Gwui58=B34bej|IX)RH z;(x}2Jpe}=@Z0@r?hWVY2Bgf4b>!Ot{R4N*`RE85i9O{SgoE_;c(7LzkYjJ)@#_787{#*)V86L|9Fc{50gYX|IlcTr<_AaWOniIPe=23tH zQ=O6K2;VP3J$@0K`)>d#pGJoB2LKI9tB)ANl-B_skTN7@i>lKG7VW6?i|G3f)g6s7tw*CEg@d?zGUkeR#jYJ zdqhKq2VeB#mlHl9RmNu`7Xv+2{DOI>L=Eo9auw?j({do`1@WR_i8_^!0oLD;7kSBl z0agu2b=tsSI?VLfGQzktJ~?3b;SlepOl4dinc-jN#hXA?9{^386RPo!620 z2JZSl!M3)HGVW0qc|Y}IecPy^RsN;;KJQh0uH(ZTU4?N##OQ0Qgz@$;(5m#fzmI2{ zHx-}7$kA1r4uyiAa`zDro>1GPaW4;)xx>z5UY`9C5@*!M(*4IBZ5*k50`N*xd2qC+ z-ZfTv6c46KhV-7kC62@P;XEOuGhPT@aqhGoapdyb5;qR?ChRZO**&~^1(;2TBD39p ztJ`Ux@8d5@LWWIUq+~mXx$tcd;FTG6U#b&ZX3AK826#V{Bec`C!m+}A6|XaWEE8m_ zXO&CN)9#`Cap0B4QeSW9eEa(f56fs%Q+T@jrMi9gy(-_U5w@$J*@x9$azx=Mt^|ki zh_cf5tj*`)lO<|e7$|a2v6nfaFH1B63tV$uuM4>5h51Gh%1sMn*~+cD9*$cceplm| z7+B(byl#}^Qh*QsMAoU;yWB2nixq720q>U)4L#*5ugk|9zn=iF%$V%Uvs>)U-JSm? zannZkG}|`YLke~wx_^oyGA4&yPPgq*Nbw2amB{dQyU(#esp2u<{Y-|a+x4ow-tiP3 zhX$d-G*%5e-oppDF8X{Itb4;#XTero_ZIUBnqi>IW zcWoPcDgPdLrD>G6jeVGHksY@e^{bE~^H}&B=eFA4mRxgX@?oI#Gj;JESzNz(qyyUq zuSyp4#KTe{3!5B4AW8W$*vWCUbse%+I^l?bvqr$R6Y}EMMj@krSphwuxkugfJ00CC5|^8 zvpnBM_zsPM1?-B+-QexXGrpABrTdw)hjSC02A~zD9q~o3MUIWiKO&q-f-zfN>RjP^ zCcxJMtupF@yPV|;6y&;wZt+d`_Ce%Do{yB6ACJ6z zC<(@+;nlv2zGs5`q{jYSXugu?!5)0cT4_@*sgHW{y+in)fb}<+{k!m`Zyu0Q#z*7l zd_DZwhTEl~v*XMBwZ2(lp8d5#0^z?RxM^zSf#QG#hN$A*TD{A0ia3#7qGgx{vXKbiGi4t^hYC&ta|F@>faijnNeuW3JH=!=6#`sOVN(QjX@CH7cT7xbHQf(*= zZwRi#Yi$z2#LdEbegklSvLJtIRy>%t7rn*gma zdEyH~^MaRx(A(3JVC)<@66m4+JH$I}k)6`0zV5%I>iD05^-td)>=Ae&FouUT%%;Ti6ShmgBfW_>nv&13Nd16Tx1(Fl|A#XaInS6_~C8wlm*vE1x0 z^ptxx25@C>lO&nSB5U2J9nUKDq4+kL$=*QBHOF<$yCTYmNxj`xC9C)Q^OlYd>x}(N37ncXM1bW{{*IZ>@pn|viQCcw;3n(*{dhgia zOt>i^m1i6Z&r?d3a=gLm0A6X@q2dt7@t6lL#WoNsGB$aLt;{jQXW(huWgbKLG-tSO zzH^yxDcly2$}^&Bqhq?W3%=y=I`B$Usb{-=o@<%+wJ`q@1WcHogU%I-&kx&qO{U0P z5nkV7 z@e?4FnDeGSE*;IGfxy*Yg%*TRIo>{_Ixd%HYD{}+g z`CFj$GffN*cMfy9J$JD)2||VGMPI=Frc?OV;yFY~$k>B>WzQ(D2gdTsq)d?-8Q>c3 znx%Y%GZPRhOfRS_997QQ-ZLTop+-1@{q9GVfhro;2tv78A3g0hyPol^RpC)~+9lij ziNC$$73Xta9QZs2LPf^=?!opd*L)lrtHAr2I!0HxE$)?`Ljk@^W4P-t#uoHaZywLu zjm8=GJKnP$a^Vv4c%T*LKGF8h_wDnQLw@`$b`ePBrUk)k_D+tC9*iO(c`}&$h^@pO z4vyisf%nUJBKEj#PTeg}5%0eTS!Rq?J2`rz--`GP5;x8EyyD1r#r@ad(}PfvUZj{D ztKFIWl*ayAbdRITan{?1cm7$j_X&;1jK9nm#)AVOR2U1rRrXm9TqO=mG$R?CZlC9f zs4gg+hTIOYrDz`6yFFV*IgR#k-Z~vQX zU5Ia#sA+7ttZtuer0>7+_&(t2#53EO>z&940qbwvj!&_+Rc7E*k3g%^UvA@0sFDtxwF7tv+YqBXD>!v%m`wrnWYrib3t@6IzD3i~XsOgLFn|0sV8oW4P zc~>Ls_r&eF&d&Z5QGQrUut3ST8Kq~EcR(7v@s38@bOldoP6t|H8t>m$o9<}#WAWvb z1mgl_N?pG5SwG*Rv6r}>wUs)z1$gQ~#Acj{q}P?zO;ZZ^2;h~bq5hJ^p(W|wRd5Y7 zh8L8TilG?eh+3*as=-NoBJ=@;Jm&^MclIaUVc9+?4+Iu#}p9P`9 z==D|By<*?s=kEcnG7k03v0-xyhshc`$-Tf{qRhh@sG+LL7#n+V6=EJ7CrG0-vPABC^hYU&pF%)`$eL~%6R)q1((Lh0v@X#>1O8N&Ytc!1$i*I_5F z@qGxS$~ZMV)ou3T#IaFB-v~E)uLtV!CfQNMrfmzGeWmcf&`6czJLMkm|I}k+&myzClLdReZGR zF2I3lZ6l9H`|%;iQBA|(SW)NOQCdb{%m;FWNdOWkwb>+l;z-s!Al*x_B}=;B@w zF!MhHuQYb@SsXoGxL*+jT9y8k_Z=r@e7+l4|MXj)OO8u)-m%_s-8+_V&=QOZeB-Eco$xus@pF>@kT>QWu3Yuy z@gcw~Gj4f%;N)wt-^gFl@M+#7b)Pw>!7cq<;-=H?*BvWemwb5Jdf(nKpQn+gshDK!!(Ds4_&x7?l9V~wS6)|A_oge;ujfZW z>1Up;yk0lhG1Oh=pNaQ*FUYK3S5{)CU8`*O`6B!gkjk=$^052E+C00!CxoDeK8>%p zyGPv$7>2>xoUHK`hnwsj>+mSO;f!5bNE6~aD zs_pCA6^?y=z5t|h^K;%?wnerk`$I~z%GXI!W}Y(BzSjPZOYa@SZ-LU!yutg5W0Rw| z`zi1IFt5HOnYwuEozq?I-8DWuBnnDD^D0+~qu4cG86Mb(xeTPT>`%foopbCT>RLoN$d&iUaVFOD}^nb8z4(=dikT$LlyIc^s5}*|YJOtHE}~Aw1#0 zGkAwjvYFdBde**cFL9stzzXk|r0lcNMfMW=Mps++T+fsEpv4tQ93R?N_imlrQR2F! zIPmEdNzBR*G}!}n^?3E#3)ia-w7ywm0;}yi>*nF0bU9kPS<Qyzb&@-mTj$lnzA&+ z>ouayH>`H+l4tFYxx8LA%&%xfi}ST5`)V!d@LfLGy|Qbvkkiga+g4k9`wABdnI}ov zg?yK5Uv2f0leI6n-+)3%V%Fv$t?jyGdEL9NJ=jJ%3R>T+m;LK)Cu*N{c$IU39NzwS z+21QX)9iEViX4^hJHpwH-gU#B%;Q#z_zlqdnk&M^_OES|9b>$XFt4~FGrR74f605b zJDscjyI^57(o3$ci(j%Y@U9Kww~QZxRF?IRxZQrxHqSjbutROd8$j!8u8zIv3OhQv z{^ps5wdqZn*@@6Y&MEe(u9$ZPeio{cX2ITaUzuO{L((txd*2b*s`4rVp-b2dO;s8nl15lX#xR6U)squdGiaW%hcT%T?^ftN(mZldS!M;HAYq zmW+3t@H`UXFM(8UzU#@aEwZh0E%IY${Zoz9+dgn{w!M$HR=t346oFJ`J`>JboV|FO z)9bw%;-$A`LZ|;k?ef~=&U)$bJ*ko2@J_Rjwp-kX{kQ}jmn72(_tLsYorgU5wa9)D zDl*187um)-=fXC&z9ZXmHBw}^*p|B1`flR!Vvx$sHQ{Ua$8AqJcX*rd60JrO-ov#Y z+P-wZuHxKuizJzryPjQ~XUq1WLi%P9vNl9+)uuvGi@i0$QG5hwea&jPz2ls1uFK*- zhwsfuw#-$&cWvc1i`$L0*J@DuWsG*VS^R8W%sZT4lz8Uw_>?-&k{-^R{xaU{uA~%3 zuG?R%d&#}sU&^166q7C3rtX}LD7d`36oiV5k)Aj0?>T4qa`-R6D>Ja}vKgHN1Gs;5 z54drbYen6sZnw&30Ie{Wsv}(%cOU@0o-Qsm7HX2xnj$e0;g>6R;-(%4sEH?lS#^oqT$w**%2!)mbq8E_cs&F7)Gc^f{mvCKel@1l>bb_>;>e!RQS=jW5+> zyqo}9WxVbWD0xBbnRnC!HO%saeTy)4NF;;Bs=V_(BB0}b;FTG8Da>Q@e-kR=Nr|VQ z!)?k2oQh_q$bxg#LyFP=YJ`smiY+SdRnOEQyy%5MF>%Ib`Oo=m7`h4Im8J{vJ-%7q zsd90DM>61p&PHF8KOW)LsWQ1cu)(`I2p8%_i5kiSJ^bDfUjd}r;Po%_|0o~1*BE2V z{43-;`(4r`+88qXW(NfhtR!l#7VS9^OGyT5k*?tb1kG4af}dfhl(t}SxW z|Ag|ev(!=GoTHf3Bk_b7ueG;BygD@8zrva$4vVROO2t4o2@|^ID z3(SosUYt~qr-m~-#QTINsrtZyz>vh&$&%4LKhmr&^Ednc75FQD)iFh@+?v?c;5FYE z&jO{?Tc;k1C*GJU%gXUb1_YKW&pSsuK5`a%*M}2(rfGB<+om>o=DP4{NaudV5lr-+ zuF+42di#dCme&>840T7G4gSQ!2PHjsQFxtC#SU^~t=CrRyy3%hQAcJ-Nw#?^eo%c^ z>1J=e#IoqSMK9Z4#93*gdZs4-Z$s_8=k1M)cQ1TyVduqD9G3$L=fg6_ay6{;z2InG zJbU4cxBu~up)M!U@Q4&!o980W`F?P;UDAEwnFWc3#J0zi#2tr6>vc;L%Ri~t-8HA5 zj&F#Fa8}~uZ|Zd)>C)FnhlP#dX^F?z)$6ur8fi%OpYQL^53ni}Xtk*?# zxsGV9S8xAr(F+S7ej-V?LoPT z6R2;;R@rBQ2b3S|n{6N1?VjdHBKz5TUADf}fyf-swc5>Zr@i(3f+GSJ#ZS*;@ahW(LLMudN}dTOB(%5d{~$V{^~p9{i|OWa>WzJ zUarSOVA)Hfe+oYDul5=J&FT$|kAK$d^7UEU!YcylzVY65z88Z16Fpw9*R|E>GzY_; zCdc=6bM0qcBLmmsi7Ee*S+{y2w9FH7+_gPi_m#7qpCn$W(b#8&cX+Pa->rSD_D}YA zJ?}>nfw#1p4~_olH8|EU`S0SBwG&)#sfjP&*0Px$9Of>teY@y`MJcwA-F*{>-l^C9 zBRAtn_-pSO*W2!t#H?VwZdOXx#9+eNe~E69ZOJFDeu+e+UiVarVSVi5=#qG%JFnNV zoHYwiH4HZDlTlS%YM|{?UDI?6DUid(+YSFk;J<^6ltpXK-jNwu zqw2A{$iP~wF1pt+T}RXd_Zl8FCj)G%xIuP`d~1C5z(&a!SIhK`WA(|!>dX2@6tG0y zrf+-<8Fou)9H&?6)aO$gr^||_G(M=ede!{Y#+!PpqUNSaZm0TmTH||&&NLuec}tyR zkYq*u!k}ehNtdYt>eJ~cL-DIC(-EEYsCr`~T4z(28@0@D8yi1ECLd=sj?1z{NF$v= zf2KNi$)f5^s6|pyCz_DZ8d2k>#`m%gT8r?Eet*Z3LwXH9Oq#+|5e zL_L|0cx!acz=Fnly-aYaJqXF@n$bm#sXBc!zGh;F#!*ry939c7q^h3iC>erkb+HU% zYiz}hmyj~1zR?K;CAMZ~Cz%p5+}l|bPLD2)Dsqac>$^&Zu$ot@rBt6q2;qHO+L)G! za6`Yw2h$*tHTeS?FBYw_W;a-R=#{8CcR<6_ki?oF2Q=*0qayzu-0+O-lI$U%Tm9#)>P8tVUbXiWi3ivCrZnuu;Eb(#&f2gmPs)+blN|ql`2PVp zbWtb2(eURrx0`?ci&1a2t4|tEE-1Bzgq}Uk+Odn`1RF;GDaMM8bOo^zebOc}>1~op zE0Y1$lzwtfX)?|pqGj}?_*L8%kCH#JG`3Q-VI!<@ag4Nu`5DFzS>ICK=_eOL3)>n` zHp@ZZCgbEhjF5k2oNTwWNU0Tf$pE^A?4iH03|2~R(M@!R=*2E218YA0=;X#iIeuT> zbdt5xCu`N4znt7DZT7Y!CwIVRhmM~72|54u*vX`9z|iA}g(1s6adL;=TBjb-!swcn zzn=V0&%}LCl;|R6gAyVv>F4YJR)VjqCH?XFCAv3Ll#qqL1!x4uXktBpkF1G@8jE$4 zOt@ZP#n0k!*%jx*mx^`In=PTFFX^#*lL1^AEWHd;jx}z<#WQQbqFRDVI2lhY19?d* z^qiMpFV?+mvc|08WY8LfJO3#NFJ&hq$&fXKRKa9WiDEOLST`?MiCMx{{DKf!$jGo2 z_x%wu7n70IZ*?bKNw-zOKexqYbt`^EcfVPzdp64&Pe!d_3sNK_mIMdwab2box5g|{ znW2SeG!^UqH_gIPK;kXH{OQDVqC{6>OjTk@+&|hqM^j*}@$%zA&k< z%k-YeVRK0dX-522wqCTRKPK@}cv(Q9;v?4yA^B{sC=mDP{p>foNm$4RjF1a0463*# z2rU**lGZGRjuZ{#N0CFmh8R1pkX2N|qFE5qmCd1<#7IYyV=PH>=qd|;0Pz^LasD)b z(KQxMJ|OAvTB_;8up@b5Fx$gUurzCweoRd)g$x!m(T037Q0yWNus1>WDFK}gr4O=O ztO#aeH#maJwE^>z4PWr_fk|hj`vdQ8)?Zm1`Qk*3>tv>b* z$tE>MI*N@Wzq2l+0ukrw?^Z7pEL#}KXflReXWc{}wv%0=m#tp%J?ACwq9PP17FokY5bR8mb^i9PfJ+hUC+9$VQ# zw<`zZt8YS6xS05jwHLR=KrsRh7%z&*XY2skhw-PyC!^wuC}el&Ffx?M2Ih%R*%7+i z!d)`H5b;g4fZk>!$sm%;9-!G|r8q9O!^{XUiCi{Kq_B@fBi#(6 za0v`mx&kH2zG7X;T~Y`=YDIg933M|RXgro+W*vWuL> zxNa$73EKzB-VjxE8cks%ShZM1_mf8J5`I@J!Md0oM+w*2P%;SyVhrgcR+3}%sC5x9 zTd!4N5j#V=(wkxw2EC3=fY?`H9^J1j;hdVU} z%OcW5yRc?5g$yAnVk&FRRB)*AzNCfGk=SJ+ocJAP;*#gKHS$0O(y~iIZjGJ{YbxD6B2(K&P;y^jmS> z5@R2bPP7%tV^-u;%qEe;WF7ep3cQk(vQ{FWSZQl^ADze!FhS2M0rDB?#v-rX4BBx1jVWR!SK&ZrM)|m)evzKj6y4g9=OPE9jsiv*z7^sFI z`^6@!M_d#=QPWBcgtlTV?5v>s#RiK{T!rZ1?Xi9|PmC4$7-I*7Q2gX3=}FD3KPxBs zVjOA91UX2)P5N0A>rTy7&Z7lnqOgdBILOv2D!Vt9^q^UY=!GFW0j(3_AX%e?sGf8K zHh}b^9q0sVqTi8&^b1&sG*ODqs%G6uM>d|Nlkda1I*HifCt1 zDLSA*ed$s91Ni|H%n!69Vmga{m=-D_!=vm+vK2nh<_@|~GW#hpwuKfDGbzMeQz+Wg zVsVL_hmRT~+i4+WP(%l@0@i_bAQ#wqdceY;*bPOWU=52sqL5^e`_R8_SuuEjqnE@k zB}fji_S6U=4`6L+CsshtVxmY|gX9;|o}`Pev_EMhI@3IM24-=)g?}gWD^P-%MGG*4 z^&l0Hc{fZEXUGk@#lkOZ@yQ6gK-;oZ(T9|aJkpbx*;#grthey{_8>i`)Wl!_E98=v zpZ>Xn+@?$P-P=L;kiH-pCmZNBagCNSN;`<2)C5zMORrgYY`+||)-c<|uEI1`k`bba z_JXjF)3)?Heqpf#40(kXmHj9g=s-H07Lh(g4~BN4Q3>$78iUnO3W3aDf2ece~WFMxpTkr)2VXEpY?qI{Bi0#LZDQ9a8ioymyS*(<*Wb$?V>n`p5JH< z@C#Z7mLNMrE|N4dnf4ZiP`q>WvM3@63-54HW?+eubK(Ncpp#h-Qbc-SGvgY1a&0oo zr+^_3^W9$%p0BaS>E}@F3#2o%iXzd0=942VO-QF@HN8zQqKmDph<1bp`-K@qN-{#e z#MFIBl+tNvdy!~Ej}W6EN?3eNo9SiRi&{0hh5kZJ;%+iT*3mocvgkvng5Hs~5=TfT zyJZQH?^v^_xhBfVG?6dbvn(icCb@}-_4E$;T~x3sq=0k)?YJ=0YsnzpNSo1ZRhSX- z(I)ge?As-)N;Z?b>=vtr8=FtsGb260%=Chy(k<+sXu>d?MB0(|BAxsy%mOBs{Xhx1 z!v@hwqHPT=WCrpp%)n_y#ULT#4jarSi9AtA(?S%&=m_*~8&)WEqLE~YU#u#e6dlu(k!&n&D+}2M=L!{^vuY{Fe)sp9q7NI0XwZB_KVQNWR9bhTF|s6c2;Dt?Vun3GfQQe z@EV5^3(Xg|=s96x+ma#iD@&zWn6`(oRuJk<_(Vpw36|>=O{F<(5`>q-^4WE9ju^!T z&`*<8Vj+{*0G7krk>A;QVG!S05+D82LH9TP1Z!M;2WO}w>nlcKyz9|F=wY@G%C~{E zp~a$1jAVIKC(NW7BYU3`6B}qAEylnY$=X0R*{qpeCGh&6I0o&mNygw26_65EMn|z+ z^nSLuLoTshN|bCRMKV8nKg%J_G+Q)5g?B-jx6zKGnDwRilWg>TE7C+RiexejQ&2)n zL|=+ojNPF*q6wo0bh?9e62-I}{F&@Fv9Md@g4mf1(Veu5sOgB==YDELL~C)Ao)9@3K*vwrBrRM6Yf8|*CG4jtJ~dXtW%f{vm((DTIa zRMG?NpeTbSs1zf~J>01i3};v3zlvo)()GA8jQ4A){(GoZb+3X+F6O+qB8*hXt<| z?P;|bCVpo+sO<%EN_-DPb)F5Rg>Z+5(W_K13ee>>r|3qDk6nTVEntH&$6ux?tU#QF z72II;p~iz*K4$a55OEqQWM`0(P`u)%7%bY+p>&Wq4;dAR)3lK$P{18FRJ0Sr*+6y{ zGA+R9YGmJHde+flG>=eHElx9&D1iIeK)*)*X*Fax$s?mkf7U26kbPW@uk%#q`Lu+fR>XJQqAcRc8b+2e$g6jwa{^_k2ogUKyts3)AVy| z0F@sma>;nogC0Z0+KNN;H2V}?Q-r2k$V4`?8#zh}X&Z5XohB=js<@90ra5rHIe)E>u6g7^Xi=jm$4LDd z7E9rmGzO~+KG0-ZLfc`pyh)s;mFTLy;w0ARB`0MORvQM!G*U=9U?FgYUV?EwOZT(m zaP+5X43@=gFL_Y3C7rNEaGu;GRpca`n_u9CGs#epe21M7Ggyx3N+y%jqM1~(BkVAP zYw-!<;R-CI=jlVt%zDxB1XhKW)BWTq+iT%RWqe`sZE}mvpczo&`!Vxm(%xh@JHdWR zF6224niLi>gP1N1tQzWY7_#U=eqtwKq!x49!cZ%6=~URIp<)0#Bnse;Y^SHN!ng6~ zH3r4bI$#daGs?NZOK7FSC0|*@V`4bz)D3P+01^U^@@-0)EKNP zs}RH3Jvv^Lki(=mZ6!953*r-NDBg%VVlr)q5Fdcy>=QAL^<)Mzm6@RS1LU+l_YiaksP6-`nO$LnU`c<(T!WwF zXc;I9{fSJc`Ow|T;)b|I2Gd6I6FZK1|CG!CJ${fqNODO&n<%bOLI;W?A}M}BTc>~l zO64G@h2cmisbYl4PR1~Ir_wvL zx9BQPuqKuP`f!$Mjj|mgRorHMSZ8`1cHbn@C=~{bpj|YT+#%)cK6;GZr5VB?C{0nq zWRFONfcuJ$?3f_b#L_`0mJr=X478@1z@)-V=!r?B(~<19H7E`V12XQ%3dj+WCQQso zM$#MBAUQ_USu<9kdGs(#N2h17QS_RkvR`RBCg4iamcS3986<;_qL+|QBh>j0=?^P$ zNSI;QKo{pML2-tpiDp(UTG7KbBpcahvQZf8L3W;{p{CU&n;sT9Xn~22qzy`tUV>-P zOa~A%>{Bi=BCC<)crqxiF=Rvrg7Xk{NCb)-IK1k_Sf6pD_hClN51J45lgM2s$y9ndxw`(;9)e^zgd4wDPj%CzYpC78Q+JrWh~di`(-1)0*tY*7JKJ<6Y(kkv72-uSum&r1vU#P6ib{YBQR|C(5_IiGi)$B1;Lqwft_X}NDc(o zO&G*kI+*@yjZ!l)kl)BiWVcszqp9LII+z?qS4?l!QO7>2Nk*}3>?e$(2m6yC#6&9C zPVyr?V~L2J@VnDVANDA8&Mf+o?Q}am4NviBG&>D`+9RTgwi4xZo7f>5twC{s^e3sL zAA6YH6c$>>Hi@020rv6;sUj(~O3a|wF$DUsjUq{YMbl5PDq54m24F(E3N`F0*3&(h zZvv1e-BPEbE`50m;t_FD~P*ol5gf5DQ?&oJ0w z879$jcC32`hLBfrvtXiAy*6S*ZUteR}1-@)|9#VJwEnrS(mC2p{`qDrh68(cTJ zHmf9$&>L`(bMZ1w)b|2=SQkF?F z$TlTRzNIIjZrz|loyY`QN;6@&He14C9Xo{_yNVovjVvZr-#|7cgV^vqEgsDxrPP99 zKaq9;dm7sSef&m}+eAux81dx;F%i%i3KP9=J}(h`KSUlQ#|FP1_3h$*CvNTY;)lnjx* z>=IJZ^^++R*=(J&Ub^%?y})*ytqqp*zZ<_zbhGV zU_)22vsj$;CS6&xklVkvp^FzS{3pcY1LSq$OYs}IO8bdUXZLW(BOjzIMms*N=Tl^xUH9 zT%3cpjv)7_Sv-z;@-{6XpC;i~w=me~DSD1%qYh0pS3Du|*jqt^W%c6=R>#27roC0c zQsXK)OFGa2?7Zko=TNvO#HhF|ywx^jQh?pvrSx}lPL$9}aSj7~HuT%f^f+liJlxSG z>;rn8ofBO|A9{{eu}2A(|Ma$XF`o|x>HX7B#C3XscBehbc`=ASEOgAGZN_OCBo~N! zah+U%Hg%;J*hujpxkp;lbJn-`4lM(P(QjdVu81;L%r25Kbc(n~+K^ufZ*Hlauw|LnPQqtB1Vk;Ej78qKSoAd!D*VApVv|qqyONIjL+w>=P zlQxrbnoVzGyL~uKp>60^oFF0|3b~N(p|^-0i>C~Fmp(`aiB#5F2zkz+m0(#c4$|8! zjg`?--PSdEFuD05E#~)=CEOqp_Xcn2I zOb~Pct`wlBGT0|LXFxovU}uelkSx}V-lJLMA(#_`Fpv-7w7)4csIj=AEB9zN>&37a zL1&UuW)vxOX;Pu*#XZ=-UgWlD&1Qw7tN4sPw~4bq>r!;G=tp6VRRIty-RA^ksj=K+L1gA z?r-6Rze%ca|gw;?j`xsqumvt1K*)`FphCIkDL~g~s zBR-?|#2s3K7F`wP%t~`eCj5#;q#pEU+KCmDYowA)BRMRS9#!69UqU{2MJLjc{!Xju zRN4x|@o;h>`vzTcmv*5Y(DH%g0bvGxfAVddnhx)w zP726%n7s)sli*uo$+zhif;~XigSEpr7{SI7GcnWc)`fDD5%iuU4qXj#n*=v^ULVIOZ0kXeRV!qjeD+zI!!-h+ednz+su7 z5S*EQms~{mv3n#%^dVW~4w*=X3lq&G-&mK>gQA(G&@yn{1$`(rlMMP*vJMmVT?!=@ z8T1~!ok0wT*`z*cCr8;Gnoi1zQRu{EIsol8h|d%!IWBIq3|7WcSxqWdqg5z;s z4?7{6Sf+rovvm3Zgqc#3X^?MliKmRC;#{>%(AHpy~ znJ|+#lMZw&xsPVUOOBBh;w&go8rn>Y>1b9gvaqci!>Qjn2)%@KW_Ls}y&r0oMH(@O z@5JD%Nk+&QFi<+yi58>9UDzm5M6>8|RHU9tih~d@-@9g(nvR``5o3njG%?oEDl&h^lMl)15~6?+@`(6a8>}-*>4GB zqPr;gDb&JJV+|33F>55fMILD;WpuFQV)CSWy|_qCqz{bR9Z@C*vU~`C2Ws~{yDY^G zb9$HcWdle7$)rD`7Ms{*mc{x|3r0ja?GJuz=~`l9Gdz!0v=6$AkP22s3PlFN0XW-2 zF0-B%6q!YIqC!;A0`%YamN+&^E|b>iXS2|=3S^bf3}S=`4w_5I*%6c?Q~X zK(U+)B5<5LV~mtTN$;>;P}xo77;Au)Lp-cph%~^jxJRp@tWBaX>qj0quSVVFz7}B?_OiROGPE(3o`5QB<)5Y_~WGF>Ds4EJt(^ z6!a2Nf!%%F14)K(iK07tr5hVT4XhI@XFrR*;uw6^9ilsHMS6%~Bn<|#FWbfTvm+Qd zyG0KSjh=J}O%pv>Z<3@3$)Tj5?Wa9OO*ZWVB}s$AbSFEo>2p9)$uFcQ&8B5+08Jx( zp_)I!P26Wu#WB`XWV61c8q-rh(gps}VYUb2K1qAhR-!MYX=D}jJ_0)3g?>8CdJ@n{ zCCeaHq?l}@zlfibL2;I%LbM<2$1-bJH70|t@PlyaLR?_7rWLd=$)p2l0j6XeSXv|O zGAai;DI;0X+<0+mei8(m;zv1?k1I$RO65Y!ycZmN?`V>rQh-6+!VtZmDi%$LM-X zoZhD0fc2-{MGhUxvY@kx;vvPlJ;ub_@3+@k;_}2WFs4X%7XV zpcOG!0*LWyF;Ll!S`7BQuC=h>)uR;}Z-CGEKVYE-SpEEq7K)#r)BvPv^Knal_ap49 zNBv%s1l+9U?`eR7pSA&bOt!OP=ex-$?@J^pdW<}xCTL3p- zpaDrYUnK#w;W)y+k|p<3jn~6RwE$lJVhiBsOEti%@?9+eej4_fRtx;FSOcv1x&eT1 zkYDktBHiP-Q_L9vl#N&a{tr0z2aw45yhxYb7DDDFTUu%{6(N2?#cO1UJGlH)86ms# z*dH9NwzhDLXbBU4NB9-)@5Xu0?OH+j6q*KD1Kg$oxE8jyCCbImwnRC3;f|I9Cm@ss z{!@nfWF7wyK<^aX*y9HP^-0A&JqI`a1Y)YJHMs;` zwyh<8F)Gv~K|R(e-FIq@Sim1?0T^E*0UhCM5Tc!opVkQ2Q%<(jXPgZ6)`k3401)3| zz8paBlw{Px_W|mI4|bvVjJssTtSZ)O12xd%hi=T1AZ}Lk006DuH)#Ow_+6I(+S_%v z%pcu7698E76uSn%YSy<<@H{{ZCCc;m6zS};FW&il?2>3 zSFIJMC@ZwIY-ve@lk4maG1VINm~l3htAcpn0P-z^d>UC4e;lMu;?i zzDtY2kkjwic%gv+dgCfCpCc*Ybs+?=%Ecdqi!B5{FFDY{F%=|a_7&*5%k0}53UMRV!e5u6)X>8KX6uy@ADS)!^g~nvV7ZO( z&r&Fl8nu`pU#kHaqJ7}0g9U+Yymucu&E_=2;rYoE%M@Q6F>+Rue@Yx$^87w z7C`0sW=VlSUey5f&Hffjln>0(qT-1l0Jkc~V$c7!)TGysC0(MD3xD_;PBfbcY9Ta72cUz7lpYpV5&CZ6LSauJd|YO|{tv=^-Txpg0HD?Q1b}a3nsN{r9D_iSNF z2mtHfNZ2y+b;dzbAAFXWXB!`vx`#wP-UMpcKk338Y#hP)*MmjfRKp#>xcA za3W_M@-WDuS@?jKMiSXI4{UPIyuWLXoaRfkj80t7Tek4g?+R_5V`H~ef89Ht3$1)0%Gpqyv$$gIy zlEVdczUULJyf7dAsm2uKsh@$8l8jsU20-7+bPHB#=@KJ9&&PwR$lzbA5u;5u!|ElE zf^QK6K>2tIU=7lvuTk(DUuv1FeDGI)L^c7?n)l_}mMmZSI$viQB86+au2J}e8~M5f z`X^z!*`fq^EasL>ZjJHrO)@#u+HgBxcm8nV@4NGK>0Kn@)f;)bmvm-pJQ<&Io3IB&KwZbdIDrpsdM`pEI-?6xpQ3XGb;8!Hkj2bCcki>fm+!}p5-539l zrK^CeV)_2g-b;vpTtG2U5xWZuvAYGkyM1=Q_mpmK@1E_&LhNQi!Hey+p4bW431YYY z&-(j+{NVRHXU?37ot-;7=^1W8b14NJ?has;#X1yKuz)44z*;U{dps@l0px&pI20rn zL|ak}Ot>9e%rX@2_Y9XTrh=pb8^*vZyInM626K2^c&x=@;qWC{=!zmY+*Oboj@^?+ zZUIE~3KuZxaafNb9CuHYpzM&V!Gdn9lIb3RxevD+aHj;06ml4sq%16tF}b6;v~VLP zxuHh@$?`IAmV|PVmN*L@$Zk+xq3n<=?i?|PrnpTZu#YM%k8k(4YAmJ zyoU<-rn3rP4T)<(swJj?Q6^N^q?od5fm-|q-jYy|;<$s3wZz3>!wfja)(jxCasLNj zAQnjZ8_H$k7;JX8ymAMzq8JUPaM5w6RsbHuTnz(r1wyz~ZcDdq`FrwnaNuHl0feVn zXvdh^nnn$S5N^d9fE~$h8RfR+?~gpv?I2c48D@NuZ^_T> zwlgvtmG*W^$1<=P9HZ-MD#77WIABV)MrKCt%-@l}ALnzj^LG?rw-oE05H8{idaqsp z{v-t%ut4%ruiOspAEqcT@?g0PtU_k2L~OX=7}p?xOd&PG<$Nr(Zo6=G{m#h!_!*y9 zZhwJnv4q>g8H3|y!vH+($vqq_<^o#*I7T%NAghU+!D29Lsk+`o^Ts-FNwb&?j^WJ$ z$Qpu2Z55cptp$?fTJr$hoa0^~q054yBU=71G+MKm4UU3V{|l{z+X{>Z$Iv!fXsk;H zdx6DqDdc}oLaS!0K4Fh3!#5p7P`P( zAUFnv1(1cr2TM#Ux2@cE9P*d&V}fy<>l{E96Q2UH+?H~?G2fY3YP3ai4Ct!q;~pa% zFv^JB)@^IIbj%_S?K{qO`(w$%8)Pi^ZIKxk(Lh^RN539_EMa*nkz2ZDL~g_qvxf7I zvpxS8vtZ#OH{eKZ1~x6Y=g85g_y6=+gBY2PPjPd&Xt5Wtj?;ZK{fY%5J{K`uF1I;y z3$`1Mp8W#I5>gS9EtlJvzd3S8w@i%KaiYH__O{@&E|Bv#=WmbPj8C)2zyPw8cw1z=-cK3t02n7;$Z0v%n4Xhp7d#IlF}DaLTzOy%eh{-@v!N;r!Z zC_6%PX}_G{Xg5ORE(ST=Zg3nLsXYbP0?~p8zBt;A{-b6PEu7=vm_NoWJiZelqLzCtg&E}zYAmO+&j0pw0F+IkO~ zE$w%0DHlN2{V9ca{QsEbSSsR+>ZT8uF)4R81&|;3lkB*e5kS`eugjGACl-r@Ilr~- zf3fh6Q9CrI3&+QDeWzv}!wlc85uE{dmR;TRzXFpAtl^Sl#J>L(42y}rvj0y&1J>>E zgMad35W^YAe_0I~MQ?*zxRUs`H0jt9RrPrU`}i(?x3^NWtJ zS23kA{CdVZHAP>A%pz68WgK6`nue8U5ALaObjyp}i!yweMJ`qF*w*R>$zrz%Sdlhj z)3pOtj^<}YZnZGsn6k-kRY()c(Zi(@8HF3SWd}c|63NucrRVrcWTXocZb~I`1P?lq zv4wh4i44cGk{vsrRwBP}=e=XcOH}()&eZElq_GS3yzoV9`L+@n=HhC=`W4PO;y+a) z8I(R8xAQq#e$}{Z0aHL@Zts1sL^e~d;kcI(3qAgq=5n)e;j{$|j#fBCxP{W8r{lIx zqaFoP0d1fQI7~pIYh~2cDpm9HmC>RHrjIY+E!u{_!U~niAQumd_It6RK*kCZVyH|) zkE@G&2fwVOn+h&4aeVM_-8g0#9MH)3v^r3JLU6eLB8)b|qzS5;9)K; z`5Ot%p!`JiE^p6IgGm$7`)^K3gM-L)t!-_g{G{OF`r64aWSBB3ID$%N;ozj;5qQSE z>M=QZrwj1{bw=<=1h1JGn>*70rX$f`ihBZZcxLc0{SWSD3V6>#!)Zpw2s37(%tL&c z2-zqjO%p224puA7u9J2`6-PFj5v02Wp`csY=r4T_c3OgbQ&K)70Yc=&c7afmR!m8ubm-R!JS^TVn(v-PA39 zHAWI$tUOr#>0cw9=sm?XazaGq8u(XJji_8}OtE9ZYJYMg)zP%KANgf=v^(cZV%Int z-|!&t%OCj4!b~BD&*$wDeCuP% zuW(nYBh=+8^QXmOaH_BAm}iveDJ&LRiU&ob1lE2S?5^BPGz!7OHNL7aQG`kT(Rg=d zl1xiI#A(7B2^tSD9rrjQrwZ-3>Uakod_uQ-8*vkR9p3SfKhSj2ZLM&eb>{;iWsvEF z`w)2-_my3Yw^R={opiSgDqEYk$`CxnbkfyN7{O1I;5BmG!~8<%0EdQ}&gjFGR2d?N znXXV%Wf&1|I;*=a1wgF`(-~b2xeL6AFgbO#Bu_Xr9F;rE^CXBIflB^zD|O&V)A{!5 z4Ayvoc;`t|h1uLic*tynFFbVNjhl%JJmQVReHZfM==au1wha0J1aRer_Y(9IjNhuK z+N-8jOr0_ND<1}?xcn!T}s%J@Frn$;>pB; zNm0rFq$Zo{*c-xMlJR4WGc2)xFfTP7Ha0h|N}HOxC8b8{XyaYHykHX74A#rWH?`_1 z*O_6K`go+nSNXA*8DlqFtEwxrd!RHa?G29Ty0-`1Kh$Fq&?`R4Cww^DW{k4tWz z;+eM8)Wv$+o&?AE79gb?-v(9`*E62hb;jo@`N>sNgw%7!2+K>`d}bH-P=f6njPI&{ zlx=Kto409msv~7w>V~v3V=|srGma5?A5b?MKUOpH8F&-RIOEmS`l*SjZpNv26;v3r zpUaWp^d{qnD)p3jb|s$v@;%L#R^K?x^wTWaX2LlEu531b3D_ijq5Z7AP4m<8Qq$8K zm}T1lc*Zw@2V0C^E1hIp+A5h&rp`*uL$5ZrB<2>^1>R(!R~c`%|1^cB4NvWnmSD13 z&(jpw5Pohoeyws}`kSd}xtq2-wL@A1Q?6yNJqKR%OJ(rhX8cllEZ5UE(Zr;!O510= zX8zY^WNP!zBnaGY{8DL($kTVtAJQDDfoUg=GcB9#Em_Y)&>@oiE%ixaL^jM-BjbM(py=9j2 zUa)Mh@w@+giN{mGBTd1kIp)jOEBLI}iV(fe_`|=Ln{RJsDKhmo|FWdo*W*p?XJoMM zH-7VLA(z5ATe9W5`5Hdi6HG0>GAIX(KYjld1~XM`l4ZB0i7l7*=E_9aebD&BH$b7d zEB2Yz1C}*b#eNBr1js#P{N*c%(}1#%w$8&Fh>kKd__Z=z$TI%&S<1I$&f1#Tn%QHR z91fd`J1R=&O0C&)bgJ#JZ6!UPEfKap&o&aDs(3+&Vy|oOPSbE!dyT*3pzdw?Ja>qh zL?5P?L2F)>wz?iM60eEkSUhz-pT5Xc=K8CCxkerFzQP}drOXLtCEHavCvUBrXC&Sg zWf%S_EX12ePVqk^we?XWMJlM`4sIU1mmSRqs9haK7gAx7Fo1i>KIF=a4b-9eXw0*d z947qa2J`<3(`0qhF{7S%43b(1JNUW6Y&@6bxY3oAzb>xD+kYO3!_>b|pcRi6N}1SE zyeICJ)#Q_?;FcrTm3*WwDx5NwCwOzvFzK$OW}G&95Z4CsW9gTyW}QKY?ws6KJ#p6P zR$Co0(D;k^uaMoC{-#dJQ3?48d~%_&hJ6yR&Khj&LJSA^t&9N=l2~NzVauYIa@EvB zLyX;tKPPo(bM0TPyR4&Zv^|wc=0;bC)wGF@r*W6yn;N1eEx;Fy7D!C}td0=YVSK&1We%5%~OZqK4NY#xnb|wBp zmFN5gAWSH|gch0c>`DH(q>dVik@>!oeT6yfRi-<05k2ro;26geA)EVlxfbh%&|?P|AKoQE2`s4jpvBpJ!!GnOlZ#2+!8Ju zuTSt52dnMNjAI9>YiGr7cA<`l2|){D)u07&iFg>)rbsiPj?fAJY>8C=*%B4)uI?<1 zk9eULSB&wXT-FO64%LS@hL|_{Bi6ADJoJrO?(P}W!ZMMYh`mO?nC1HaVm`#d4P?~% zw1h$aG3p@y*ya(C`7SP%+99g#-p8?e{U&~n3|BtKEui9AwcD4tX@q#Ho4&@Cf1>`{ z6;+pz_G+CyQQs-*FHGG2C^cw*bpAxgyc^j#KUkv?onNPPPBRj4ui=$?L4)g3)SX}7 zt}MF+T}up2l%BV;iK8Y@KX5reJN8G-n_i!ie@ygQ)Rcdl|EiHkmnJ@6zsBP%PBw`p zRg^7=BPl2E_<C|uZ{Z!nyq$#u=%l^U@lF9Oj=#@FsWCGjCBYsYHmYBMy_@j8Iz`99c+uP*kB!`R0OtI$9p;_}ev?bakPYu}W?QO>Mhi>f)J899=x~ z$favk32uydkVhh@B*`%i$t*(QtpVpA=8-x2z?2xH((X|n8RAO#5mA6c+2|OCCtcq~ z98TeJ*)1REk$IGYS2ZFThFL5@{HpIMia3_`MDr_2c8q$OM|=sDCMxru#q#48FhP`okQuNk>J?rnOIV2>y4NIMzNrLMjKSPb1!ZQ%Ey-@a_%H@PXm|n-gMK$VEFAEneS5guxIR0Q8osMQg=e?srSBv^`0YBWZyA-b<<7>*Ht zM%*hwYYm;)ozxKfLskuoF>Vbf$nZ|XR}ut&L9-1Z{0o|$EJHLpsTBOQ(9j{nLk&O4 z;QRH>B+^e^^7YLoPc@q^>Chh2^7cZ>R?=AIE|#>SNP9T{UrBo^K?eQhl6KT$8NxKY zgolSAlBTfZGI}%kourAEi4a(T;t&{KfZ}Zeq@t4&1URW-gaAJ@@5a#P3VLHtbioxA zf8b%Wh5`@wG<5Rde--f%4}<<6V>NukL#~G3c=&*bkvF-9W-$1SYv}9?0y;?;T-BtD z1n|6G(oVlqI4eV+>m?!jbHZvF)@iIv_##1;#u|%e2}(6KOvIn&`Zti}U`HD!A=5n( z`v85Tq^;8+6@-ge^`S=|CIj)upj;OIov1~UTW+Gdxph!0NFft83*H#=@vr;uzbOg zW0+Rp)W|8i50I}&hR`*kqejZpePIa_{TX|b4BNk!git0s6o17uwt#?dSU!DWs0M8z z0f92xA^#hu_^}sj+&@0<4M1ba!YEc%!Lx!3$8J;ZGFh+4V5_XGvQs(hkf|jQNWl zE@?>H!Sxs7C>px_LMtz&JUr1)V|B!-4D8leS7AQDQ)D_1J_Ks~M$7FvJHD8|(KC%b z%Y#v4wb`j6oYvSt7%9OojlE@V%XGWa5b8TaFDPwCtp<8C!bG6&Avgj2NohOM4hE9a z_EZiFv6{0F9MPP|IryMCn?Vx_op10Pgu+12MG!T-Ex|PnFUqQ?uGCxwOIoU4+Me`) z>l%cDS0I8P^hTgIO0X^vZ8d;Hn$sjgDLScD*nHJMd@H~t4gVH^LB#rZu?DIwz-Fr^ zibrCjrQtmRR@N*H(S4AH!mgU7ZS{(H5ibcsk$#A#?(cd+wEZ1@U|V!qFmotc|bGu zkTjPV20Cc0r7#v?vBoZN4i+*s7RVjvp;%*)tWAU}^^xU*8Bg~_M%@F5ua8Dk0FEM( zF7UBFmQNZs#|_Zg8fG@Y2j~kD0%aHA21=$>#@PpBe=TFrBoUderyK;1K3Jgpq+akD2^M>#3@!Vj z-yNYl%3WV%Q;5H=0M z`mzP!&LA{{9k;=lr>@W+ftmvlJs1O+WjhOpHRd9Yz~)tB|7brmjfWs}ndbOE4-9#n>&} zsG$RUG#bW85E_rTUV?ZHKZ_a}zKU9HG;oACN?Z5EzW0RY^V(b+cu7 zs$nK}J(CcxU=IpW7pk;{^GRj>v304GTsBbeqpXo(MzW?U!(I&q8GdMpJ;#12h?qq? zB0j646pY6onxtYp=OtL3ioRJgoYe5G1U_kqyCs;Q;eH7+5s3%9Peb)cJQdf7&M-(Z zqSGY7EzQ{q>X^_uUxLLZ476N?Tn!(I;BH17DZ&U1-;0p0A^zOI*6@S~9W02GMTkWt z)!{!2CaoG&x1zNS5$0IY_pJyAHIyXAhDrnm+EA$r0D|^%KDL#~wXstaa|qpsB)EJC zwOT;+EOcTq&dI{CztKikSwH~9PFa8bKoMW8DLLr*NWdTbof_LA#IQKjqp1lkpy%PT{<=~e ztTiFg#|lpY?j1(0Mk4ArJc6vDaFv1O8oR)MXCNP$Zi3(n6>>4ackwR3m|XOHCS)?O zS!0zY4xkK~?z9vFo$^raoxGlf#5~MVJ-C{ORfB4(&QUhKI({;LKko^T|+Xv#?}7euYB%LX`W96~Sv!$y~j+{8NOri!exx08cec z5Flc4$vl0Oh?OpXamgIrC3!G3S%RTA;xk=>Dz8M)FGZCN@^l%NBBN*t3N?HnsRNdk zu+>OQc$8K$UsqS|3E{?)xqq7PJS2Kb!uGeZsbr4JHrWns08A+Si#f)E-dr+A-wBp5 zuo#)kUu?MD1@489PxL3e9$*v>qJN zU>J1Xjh>|foZgK=@eLTV2XO}vH#Gdr!lb>3v#{_r6ggP94~-0fkNYrKJO}Iczm3<4 zY;$ls@HP&+aVI4(A9x$9cL(f+S2>7m2s{uVU1M3yKLRv7^fp!}GZkUap|^3mPB0kS zXJN?8%oGmtv(Rs}5CDBu6y4zWv2a<%fML>Md?m7x{g5UC6lY^nb^^@F(UQhN8KQm* zS0KUK!)V|?p)Qakm^^HblaHWEHh%2qB4XNj4X?{;aNgSyUf7*pbq@6wi_Ce<)KEw` zkFMVUJ{QnA2;c%b7xEBv5$$(@_X2Fch-tvjMjl#ULUxu;!*2|GW&QAA}*t62PTt;JAWAaLV#%nD67n3S-;fS7Y;jyORpeXA>J3^8#3*UjJ%3z zXaH{4-Y!uuPcNRYdtSV;HqDZQX(!=dnu3*>LjPk z&uNuFtDUo2s>$Miw zUCGf4NnxVn))$`SpH;+(Jc;z|#~ow0a6`FSTmr8Bn#7ab3NQE${9rzd^WE$nRlF5-Dw^`B zD=!jm3+=^+czf$Ko*ebyMVWuXpB3=F)@z!;{k-s+4;AtLT7EjF%JrDAP?(Mvip=22 zaov2uTd6mbC#R@r$?+PAd!l}-P{Jx-N_cY8bqQ0B#@pAAmtsJda>{ypKPBM}PfoZw zgyFU)_D)K88BdP6Ch;F_GNV*^izZ#mINtsg*Mj|V_;TJ1;L7E9=;OYV(?fs$U%Uhb zFOA4|&*T$uBt9O?_X9fJh>!?nY#)VuM3e6SaPR4ffR~D$LubC*XLvxH@U|7pC(Tm; z3sVGpaTWMy%wUDFax>V?tb-NoAf*nL{2|AuGaSjF6IR|1S6AMSm{VC58w^W5s}{bA z&~H?$c>6}{^pkkS2C~6-ik?fmX$Q*JcY^+fRWQLcWG-I(kHl(l!q<1AOFR4YSOWF@ ze8=m~+gn16AIhfC;}ZMA6O_4plI^KOptnEL?!t;>7ue$OJ5g8L)IxQsqUrYJ3}z=^jI6s9M!`yuO9tq+xYc6wL+v`b3e=BGrYq)qE%F=U5YI zV5<3!bFIQvvKHYX?8tQ+Y>i=fb=30_%fr6vs5el!hwpEo?>PN05$9JI2l`IH_u^up z??mjSHL2k{k@_1aD{A;&amO_R6YHbwx6BajP27L#Pb5|p5tf5(U?5^37hL@#g6*TxqdeNZutfc3+JI%F*Aw*{d{Dj z?bt8k=lhxU>v0qXnlC_E6T5c)J2LFFj{XY+_Fx1WO8-JZCx}{zg4yuG4pkQUS*ck7 zI}vqNp*D11>}SKZvT$QD8hHj*R$Z{fuRhUN|P&s+UGA(Do7B|c^PXyy^G zJ}vd}CVs_o)1BMSjJUVq-q15;JF1C3Y&~!*^C|JTz%Q|mFeTbk1^89w^U?#j*tDT3 z?<_c8^X{$BVI1z-_0Fe-8^^ja^`Is^dgqgejq`^0K26FCkdy2kUzS=MuD|y=f*oqh z2cKr%6~s0+n{isoL6gzGmW2x+d>(t1XUCXJjjc>`EyJvhA@8G)N*%-R@J~LCea;C- z?3-R8*p($2sMaBUU!%^x2F6^NUrPOc%HtP(fI(H7gFZG5J-6?(m#JLzs^dRFm=}K2a zDSiaZbTho6p7Jot9fRN$V4w1a=qBpUd|#YatgUuB<=d6G)`T9mgQ6OF+80OTv*lx{ zT~o@l^sZmdSr1EIEqR=Go4Gxs@JrFAn*k>;?T8T6%V&J65m&|j-ntpP=4X8y5_c#2 zCaG2Y&NK)*=UYYB%TiA5bPkv021T*A+1{J4I@Uc{_I_yTy9Y%@r=QPwOWt@EK0fw# za}KXAJ@4yD>NF5(^B~(uncACoX52lmN9*r(TAaz()VTy{nQN?d@B)s znlN2Z4`1}HPux~T+g!Xoqd-esj2yx| zrZ4j9+AEsV-!wOEv2~W9ZojHIPw}g*CQBBr-nphZ4fdnvy0%0?^|*mfm&1@tw^!TW zM6<4YU_HGDXG3rKHYP5!nAy-yrEjB$%RBxR-9SBY$F~V_*^Hxf-PQMZQSMfrU1I6X zbWrQu*IaYhI9oW~Mjc-0+km)vinT2jtd-QLBF%I|E)$mV>fT~B?fQiM#b$|W@dM5A zoV&ptmQ0(AXP-2ZJ1wdFQ*`K0it&8Mv|&$XBIi~TC8v9D1@cTlXL?kmAO=E-Xznj*e=kI+q%7U1@J?anf&42P`+NCaz!PbH=9_WCd#J`dRv^y;m70U zo0Mc%Pp;N<8YP{IyUeRS)*4n4*MC@##Fu9E=-=q0Uuyf?tcL!pDJ2QXriq-Iy$&6^ zYo;KzO{8Whl;zA=KKr9IaXoWiwONcNzG{cm`MkO_Rul87UDXEhn)rvsFL?#4W+b3k zPaFSEQ-hO`V!`%Jy=7O^lQnh0*jBBcit4(_Hk}G-TEJX>t>u-ZRyJt?tJ;^@RjXN} zD!&MSVXT-r{TItBPEECG(yPn?yXsDB(yO-Rq8iU=(sb(;R;5^^x)iI2`Y)$N@s%E^ ze&vzrH_+2ST`6js!??4I`cBelrXbqYg$kM?<<%GISibt5_Pc^QXQSr(kIf3|<4qdf zM`Qh-vPGjIjKr$h^3c$Wm^UEQ9sTos~e9Xr4E4_n5Wf;^6X%hJF1!4Ppkg(gHD=~*$)k5ZouUNI|buBu9 zo6f18H#L<5@*X%UsIPBnMhf{Vs`HL!B#Tw?ao^K~`?*ePLZQzlq7EDBoA2s+Osr?- zIkoZx-*FU9K&wk9`HrFVCtw?`UYg=Nf^uCgU$N}Kg_zUPp}Q=USJ%(<9ZBh1ibn+X z)@&3KAGO&$O*C3t*%H6NH-f^J=k`JrQU6M6%Oxn#69rp<_+^@U74_~4-{F)#M>;R4 ztyiP3&YKTb6V__NHrzBxE&N9lj^V1SZPsf-C%0HslcO{{?_mr!%P|@~COqNQcJUew z5VwJvnuyl*9oZ*>`Z!rL@D6_`I;Lp`RCzM?Ax&EBq3RQh?`TRd!eLqMX4gW$5dULU zhCyE)BZjFZtd^PS@Sa!u2%4QrQe#z+G~sjZBd>l?w0NqslVx?#M)Y^BDgVMv4eI92 znz1WFE~9?S&{Vv*_lz2`O{4zYK}OxaL!bKE(iCufk5(tCnzTAzJ*{TtXwq?9Hm!Q*YSLt8tff4V}dIW4EOZ{g{-?+Wd zhS^I8Fax1GzT1mr$654pr5bEyKU-F%dM47bp3&1I%l-NHDspx7yx6z#H#Tl)mLCz3eOQAD-403kV z4H4@@tJ=;Du78VbQa9S+R&Dfk;p#)hVD!Dpd&9tBXL~&kgRu}F?3|+?VLD`ncfqK2 z7J5OWI;gc;=mj(Dpw?Hx$wGP^)Jlg-7Vxa=4AINHYKLBRogHv$|KGaKj`~{MXq?8V zi%NQBH{KRj&l%#{N<{*wk zAtU`^Pkm=6{cU>$2c`9$3vlXgd;@1&{WT_51bYKa9!UM*d;?5g1ltbW8an^NfwdJ4 zQN_;TlFi)>wH)Be-X{&6ov1Pzf*Uy(;K&Y`8==QOp#q#~UB! z1Wgi!pY^Dt%fUs^ZJT1^h)@fbG z2jMjXUz%b5dtilicEm}w+0C7ubWPb{*wWlNS6>670eo9Hx9dLO_ne~z8XnGcfhH}T zJE$ZEZnebX>`3Eycb`_yOnqzdr5)b2LRnqL0WhUCrZ8CornPgaKAg?AfoB`^yT(W1 zOk^93v<~cP<6NdcO`oNqeh8M=6dvp$7-%N0bqK*gC+$0M!9-hpidZbG+hULa*wxnA z7Dq%MwRJAjjj+{+vF)&2N8<;6I}CUlX8<&e!_U)pXu#WM;b3`tXFDAE-q9XQ<1r5p z+oQsI9;$S3F4bk>;@PwgXkkAGr#t*F>K_{7T9wuvQ6b+R09!laW1cKqab~k4rXdt6 zg`z3c7!->2us_6wVr4Cs;&F;U)Y(oyRkR84E%Z+YTXaHA9C)172{l`T(g`(_#XB_I z>EvvO)BJwm7ls-O@S4Lg4B!Rp!<_APYvrntgG3)H;8K+jVQ926mxYVrJ7dbiC77Y% z6cPB&=+jo>ab8?w-aM|M@$Q1TZ3?}+V5V@?eO(u<=ha1AqmZSs0n&M#_d*q&!1aa( zUA3I!6iHVs;x{<6&=pl;#Wb9rL54pL9^lpuRf;(1*3H?0`U@XiH&n$XRr|Z4YO;tG z@TJD8i})cN+#UU{;UbFesEexw?3%kof(zYI!ztJ$(Dy(VB_5X`tOuq62OeQX52v;o zX%_sRAg!mfBZW&e&h~UN>a~8(cvt;LZYmFxhC2J` z$4HN4$Q2a4no)VmRE;U|I9}aasClvmsTnKkI)i*b7x51BaXG0gOeAA3esUw^l zRG*5@YI+=5Z{p`{qUVJqoa^v&*3|o&uB5>~e$GPu7UqEjll+~5I1E$;{`Gg((B}Y4 zgY54NUVodOo^CqgcYleld~4^#mMepnY#;Wl{xR2gAFn=(JwJJCW3ymixOd$3kS}wp z*67l2LZvyM#tjVHUM-g-msBelwr4OC$K2nkUKCz`*Z&IY-;0?NJNMnV!C~vGuKenM z^WLHUk{f5=cKl>S(bBi0sS&|52X>mfXyNNI&)U58%zfI@?O3JFEt!2d3sK1#q^rh; z!rV%jz8)YNA-NJ}qp$tB1UoA^7pRkZIro!_newsIi4nsmWqdMUKX9}y)av6LyMBV4 z^4Qk0?o8ii6>mS~LXThmG`a8h8Ld3rceU8~;Ay3RtodcVFM7t@bg+}Ie(Str@y6;M zp6^Ka*akj8XWEb6wtJ88ue#f#$SEU0-7QOQedp_quKv_;zsj#rB&#jq( zL#}#vEymG$=d{-D%YN6*E7`XB!!~gFJ))iZxevb3zJ#0k(R;$UdV7tNiZ4%2IrA(5 zy7Y50%Hf`Vr2cwGO3;gcfBfY-({qK_Z2c0yPA{wj!dnieYZeaGH~-$uFvN9pdA(Pi zx5+(HI=H1!&ntd2lj9!$d3@0yHF&=C>OZzwu>EM!8`ALmBA*Iw&D~kgy`}4V%x={r z_2%;h-|gilc^$8?+Vz(ArdML0BaLoaTR)melD>DU*r0qL_qN{sl*zsPh|9P&rj5@( z|Cs%Ix>qNU_in#EKfQj?b5Nsc_ODMrmaFx%cExiZOI-JOt$z(YKQ=sJTlHekFYf0{ z?~mm-l;P~QZ<17y(mCy&%>~b@ zFCuShca<|)o&A>Co_s8U#Ga0-8zW;^seSzGq-Ti@EV*>3GWKy1c~$?2d`tK(uIAg* zsdxkQ(`2^<5|-uS813sI+Z<}bDmNq^)BC&JA z!T5b~b>fV1Wr;;;$wtN&$VE%aKTnHDY4B6w6}!lO+7yyHKk;M2Roq8@F{VrG==gcb zcGEfAC2p>yq&_PmWkIgWSiTm!*7nSJEO~iCn|P0eE(xQPAmwdJbxSa;5)|=y5&2Ma zmh_nG1x9+gxj5xUa#CXB#Ij_2T9Gl{I+Srr%I+6fkb&EUbpAJHrm9u8EJ-_?G%BSa z&2DnB*l8?kJ}JHSEFarW9j{t!}NRMqS#0ISW-m3Rv#hm z5KLSZv6h&_RE9)$F)U)U`8vWKp}A82O%eI+e?$%xtFT9b;%>ryuA=x$Tp%ieWoX>+L}S3`)h$EMy$UXi#m<-KKsEt2lXz7UlKT?)zOx)1nPTqt)L2}yRzk}^lOT6xnz z+(megJ0mM2dK8kq)h0b3{ArphDqJyhkmd{jOmZ%kjh;X6Bq&Y?wmEIUgO1Z8ipLUPdmsoXC; za$`$zExR4&TMjd|g!{a*x_2STGPG7!Zx|+D0~?)1H)o%64V12Z3W=ivE!|4@lUDKf zz9{j`k?Y_dvky}3^f5RwhoaNe3CSV$D?}Q&;;#Zk@QTTL2pMu-A zX3BX@ua-&^`(x$}dw@A{nbLD~QeMJ!Nv41m)XXPRi8`zoU;5feq_a8N|4^8Wk;A2UVyQh1yp0pE` zotjF`dyxd|zO!GLPGai~v(rEE%f-6s8)d~@rHB}P>{3<6!FJuy zbyMty({ie$G_P7jtQ7^WCf|AE`K=GPRNEA^siN{9N^KNwW|&c}h{(F<;sA$B^&*lt z-Z5-UF~QkOcX_W=BBaOz(ziiPC1+wWnOjYi?!gk(aN|_&8J-0&MpzB~g#>9fRxnM$KbRJch1Nqb3|C3qm2ahY5HCtf z=;UIuz|WT*olKGqDT9-DTlNcUcpX<&$w8k*K8-D15}PKEHw~c|NKG~zmX!`uipgSc zA1TFVO&*-I*f`Yoh*PpqxU^youBGXpm~zqEqHOWE>_e3HQ;W%xiha52DW9XtqS{3d zirSOVT~Rfu?_Tk#Nsay;bs;Jux=qyU#QmZYIt?vXkt|75SBbew@!y!^T6=3z-$F`r|98~v3Wlr8c0ke@-mv3pY2!z@iJ%j!%CNp%>9TB3O+TN8Qguysxy zVNS7LV3c;VH65c^Z24_Yvu?I6#{=awQH8&yPL@{Y`F1N^PiZ@+n5^(zF3h#|vIW|6 z?CY^CQMA(iBy*4M!CYsRkh#TVwR>0G<8|ErgHsM_PPeYY1okx3Q)x4=n5=R4mA%*& zkS!<&(Ye;uo4?ANWF=(2=Ge-O;{TSFgMS=daN6S@`Yb>n{TKO?r0hq!j`USp{Z&lX zi${YYxj{Mb=z|S7#Og)rD+Rj?$y{7MsD$m& zbdn_{6UiL?R%wx>`0qukt04|m)+3u;;g~#;zaxH-Pf1mjw%AaBdy%QAZDjd z$k}mk%Jbj=zn)iSoSAUGSIahia76y!4ZmW~?rr%v>h04?a@S|$L#EX3UfL+x<<^Dh zji2$jZ46$e-8SRCt-GE(yn`yow>1uYHQ|2$0X1{K%{;H{c}S1SIQ(#^Pijzc+je~h zjcDBeY*5hW!)GEgGq6MRp^&t!=BW83j8xO%y!+PO6>x23?{!-(q#WE_x0SK0uGk|4^^03k%ij8Q`!^1n4lZh1{;a)!+H*L{ zwuPyKiyBmDF2)#NTS`)!MhAdxa8VQYqxN}m+Y@)CLCxMOfpYdmX1 zZ9JqX(`R-B&u(pfZ0d)o`c1~pSh92B@rbGQQ(jfcug@H{z=m=+YP%lk88~CkiVIU3 z_S~i4c%=m!n${~m;J}=sqH1G%_n7x$-saIm8@s+6oBa}QCO+p5<{IBy>dhFDw;*%g z)qW>xRCsdva8)i;?KrvU4W%r<7e+EjBc=NNFw&j+k5?ukiKLzhN->f!?cA}Ng<*ts zaESi^@Z&rMchmjk#eE3_*x}2CV zqkYqTe>8g4drX9WeBQ8z^->---prB)(Czk3GW@oEw9 zsZCJ#3qw+d$A!H37@VCfD<4p0EtQX_5uOYqBdUKBdY*3TIj2Sa;DNOdwtCTVK+pO8 zSGC;tsdBc9QiK|-NJnM#DYS}fb(OtHs*vW26LFcYG2PD5^>i4X5#zXaHH_S%aMEa` z$+7oF7{M1}u;cp8F!EDJ-N*jr-7u1_{<9?H+Yse>>&c|0?lh(b#YT&{TG@6_0GjjLmD}94|F7#s*(DR zluI26P4Fk9_T`Rb7qyIcTt+fQk9)+F*4I0d*QAQ0){Tzjc6n-!?D$sHk?hssb|c5m zM;%Fzs?;{T==n!Sl1fNZ$G^WiV#`gH*&J6~LP>}>9L5fzB*TqbjPnTHLdj`A>W%F9H9V9sm_`RZ zGL-y9RP(&c`+Yrj%Cay}s4cz|V9>vp6RRAP<2KgZP+gSR>bOOx9&hG4vWG!r)z|-C zu0pEcl3ml!i~0OW{+SReE*D;K3^$ygDa;ZYtF_i&e&Fl-ju}Ir;dh9qIl|0jYO>FG z)z^ACtFx_ah2G)2>KMtM@AyBa-aHVh?~NaKuCb&OHGaY!+x!p0k1H~MAWxDVPuI;U&GXJ* zbJ;xm2TW(zC@7ca2k6Qxg2%5xLa zhLA#ernr?~Pf}qIOW>oiG!&<0cxSCVn|tn6uKSfaIhEv3@qhd>mRrn zz;LisVI{6oP~o+MDf<+cG^I!s|}(yfG9 zNoR$Wa|m7BArFOX*bVGoygAg?HFTCCNs<%E2??iC=2NHF4n~-hMm#O2*)4IWb zJWjlw6OvLUpv*!CpJFUvvdrS@Iet{ohEn8)v<=DsM6Y@9R=FGL44NTitE@{wRcxZ4 zsIgh`N-~T>VT1Sb!3E;&;^Qz|+e|0Iq+d-KE$mcKhqusS%}B*d$qN~kyOpjWhFPfl$t=gldFi>ky(n(?)>g)+R zUSqU;u51FOI!RZtR+)4yFF{~KSuh8K=lN#5T=5j@pGdlBTGNz|g!jS68$XJ^Qae)W zBONM(4da?pw?d* z3|j~T6T0Iv`IPJ`9UdYe4<;2b&&H}#b@_v@U^{0@Oj@)BWq6$q>R3phBv?e7vd)R9 zz#DYc=p2_%Ph7`*8N=gKDK`gWEEJ+7$H=(I4JlN`ty1s|hcu|3d!^u1URNbHOgPD0 z$6S=SjyIbsC@Mv!2)RD1iPQgjy$%@mp?|A~!>bxl&o zy5*&)ZkU!3Cz-KUC6{s52;m^9QdFW8JML5D>?;$P#2iJHKXbVVs@ zBz`F{ud)=q1@*~8k4lk>(ITmkf>Zla)J%ks*yk}2joorDsV}y9Qi_^1t;BD5{owq! zx)i<9jFMj$T#-?qAW#HqCW<6^J}hr*O3?$_iN%rHQY3u_uE;5ab7kPuozVk|EL28L z8L}h{Lb&UguOh$lK1y_Xd5K}ku$@wKp$wk-TS?_#EQ9tqEJOLvx#_uUFLh*fDsg9S z89L|15|2--JcrNspPPkuD#OprI2(VVCU4Khva7vCmKB0xxBRD>=_(TC0U;BsGfp`1SFJ zXs6}_-ez$TOteotM7uN|3%>CuVG8(8EtaGO6e_i`+erwS)N_s|@Z#RGc42esRt083aGQ3QNK0rTkaBPzovLLm z+97_!p`P^YJS>q%Dx-r6-Vua=bJWuGIM^i{aSAf;@?j3kM?@@+nd& zIf?rgTnR@(jv>dSrNUKW%Y@PRG=#TnuT*T#s7>3+#UrEXlAIOIRveV%B;zOF}@6e4Vsivi+!GrjYrTa9pZHfce(f^9bjBcE@I&pnrcJ~ zyPi^^3ZdsPGO9%R7DSyAKb}PYyAhPTdnJ0;j=U)o>qlsaI`X1y#?pj# zH0f;j2$eGkuu)+w=v(<4-f#^WD=z61$p0yxttU``T26J&sI0QwU7@=JX{ z5SoL3PM{-JNwJp;o%KHw|3?#8Yu^I&B|_kU3m{Ci7$0+e1Y$I<0{;Rs18Gs-6Ca_U zyTOJQdnh3bu?9T30wK2$B5+iyQ3b*+u-C?gnpMb)IH<(GfJ6}M<@m4`9V3(DD}&@C zi92Wlu22gU*jbxSgfed%Bv;t@%pjqCI0K0wz(H5Y5IPV1LD3+Ig+8@- znF_p^CdinI2ejXXX5mYRtH9guIP7?&3f!OnCGi#@UZ4_>GibuNulPyg=E1o85^Nqp zUp@&30eUl*$bQ4a2BXH~r*ss!PuD$4-{=T9@&y87!*&H8e~i9rKHd!I&G;pH1c$l+ z^<+%rrweiO|ELJ|L(PxVvGu&I0vt?Jbpd+@<^!9?xEYto#npq6lVb=x^aLI07@x<- z{y;s|Z-bmUdN6WM{0TTP9H@sTQ+XwRn;ie50~-F~U})u2PgbF+njIW*Lc0*m?<5{ zVOt|P%cqbs6qo8 z=FfP#`lsP3EIK7xj`stBH;pgS5ip*%4JJI5V!H%LAbv~mra_V=!AhDSU;Gl#n-;$q zC(>D}r8tl#jDHm>*zW-9$=Iy~vHc@D7EJK8lIUA&;Mp`1wPMT!;zc|MKly_sh{SzB ze4tfKNv5+Tl6XH5FQSvAa)ES@AaWEqLrFJa*tIvu^wWfjPOuZBDN!xKqCxUif@=m7 z2NYETte*ynaDvPtKyP(5=@6U%Y#QUZ;>p^*@0ncFLh&;uyhc5nGP8LBK;ZPofb211B}n0gYYq zV989}1biB?R)WpW)AvT;RSz5*SJB5th~ZF*Ji457upDrjdIjl^>jqh%VktJf0&xsi zd@>aW0QF+bVDFLP6ri4rZ|rsnt{9~MB?YEp&8u{2r5qzX6WBDyQQ^Hre3FjTT!sVV zH^Doj1B^<}4X`B~q^*K~_;_+Y+*o~e@>skN*fhp?F}&VfI+7Oud>TwW%y+={*XZ)? zliK2cfq4^2LYxM~i}6Fa4~{FNDR_OsX4mPsPEn!^2h$YkQGCG7M#M`w?ysyu`4DsI zQ5DkCLLT_WGx}CLB=|cJFCtcqC)U!1G*vE#6EFtpJLx0v;ZIZbD&Y|P4%jsHHkfo+ zJ*SKNRF)*bYk_()n2N1ZEE%Nx<-6gKtU)?XSxjR67gea8?$!SQIZWJF;=^@x;pX8y zKyMH_;SL~&iEm20rJhdl#p!_F#7gjrPe;JWjm=)tBt?o>(*!)0r2={rC&5H@Fa?&f zIt^9m_6YC_hf6!JH)o$V6m9B>`3vuon{4Q-wxEg8Az9 z!;fLH^Ddn#rPmiVA+!e_&1DlP7VN3 z+-xN|LPkonrQwnu!AkC>q~HWWf-Nf|RvH(NLiRNCwWNHvBXcT5piuXvtkd#%40mD zb)(it21P0(A4j@IqCvId2<8jsmPn_l_^9w`pO_Ib-O;CFp2m!f&5H9%xRThG^4pjzf5>q+$!EBbP=5+sr{(|P^-a&XsL8kX5O8svVZRQT#P&$ zm~sEKYnDBJ%3sXUOj5EGDf`4XC0MdqlAL0mxGH50?-iIOoe@}Y^VpgRR`Eo#nEfbW zZ~V`gzNlBRhKXLOcCrp~KZs>`0qETOQ-@_vsa2w$^u<|oPp67@Bqqex$6aJii_2$j zV*Z#&=33xDlLNTwnJ7glDnaqVUsZD`Y+T zY?J}$CM72~uziyISgbhBxRCfMiH4kRfhJXUjK0sQ)ABB|JH!3lo{PDceJ|RjcXO}A zg~vbSs!69S4bPaSPY{R`A0}mSuWE+WPf#6 z?&{2)AjR3nvs4~Co0Fa>otx^I|lXZm`N@`=etcpD}|6FVbh`MP7({8gn+v zDsmx{VCpfKGIxkmsokT;EM^{zycA^{T^qF#dVqOR%cB-Y&5Ejx`Zs1}d|^_5YPOVG zyFU;fjv8?=5RRMC*d%OE z-iRk0g24J=l3OBm*?`m`gS^snr{mV_i`}GF>gD8BoacNV?`le9;@Y@r$xp>;vM~Z} z?)TJVl5ynm)Xl7EaEOf>Gbwg)(gIfH|E=l#$fYTB_%DS%(zD!sNvBdj$f*o?$SgF} zll+i6B(W@NX!Hd9^>83sz?dL=Af$Yb1fmc$`#c#Ua1*W;$BNRp$M`Gc$7EQhP~^!C zMMf!M(ezuC#&{<8CH-a_^LHnmWD25F*^yiiUKOu3!7urVBv87MdKnRj&VLujPa39g z{g?Uibo1T%+)HE=>lEwq=^w&VvCNCxw7B<=#9R{l*T5k!0cZwh$yT9J%X~$8_;OQ3 z<+jh|ros1?#c7vS_gazvYdS2K^2YzM|L=ECj8`oZNwhx~|4 z;P@-tb+pe^(T1E+HgH<)&%HUE*h`$UesWl_~> z%=|KCoh&%x3AjO!uR=wGU5-0$hK|Q}@OP-$p2QpcBZDo-K3bgQS!~@Ia6U*De1QW8 z1WgG*8K?fTw z_%crQRW*t(%LnNV>Ho^~|Nr&79QuDt8qbE0i0R7u@c(u{|I6nq@w;(q@X9Ar)S_EU^ms%Pq6Mx8c#Y z*THW)v(%W&;(Vo3qs!v48D53*&7f{sl4s1je-m*0h6>MO`hm^&MqRgx8N9uD;8f24 z^Jjfiv~zFfYC+k3Q#|j~m)FVFm`9ZUZ@1O$?fhS3SQdHny#EKa+w>I^`#iPhr>Zec z$PM2vTQ;}UKZ$s7L@+;+QsUKVt5D&oPrQiZcsn0@$t;0Gt^XbRrp$96+nM)h=F1GYtyaK%;5ShHmHV^_{<#|ST#jGw zWzF*8{+b`3-bfA-oMO60Wl3*V-n>Sqsxhr34xhAh)tF!9g$xHA=@o!1)FB?H12bhT z6M*i?J)q^M=*&%mo2PH)`sM7sr`ERj^|o9Js`-bQ^**5e2>kEDJZ%;8ffx$+H9DT} zdE?_F?OWDo>Fdg(=40k*hpWwRCU%!M@2zsU#LB6z`&f8NXp*9R-LH)aCx>r41Mfkm z-xDyEyR6)#x!7K6-B9jYJ=zbQbJ{zh5SyM}h2E*3;;Z4mz-)*;u>Czf0FBX~AI%{h zu3at}m0w@=vEqml`$4p&x>%w{Z3LzZ?r8;k$f>L#Ik)cec{QeAdc-@m$|Ff-tis#p z(xF|)pDSTiVqw5pwddAF+F2%2J&b1rASV4)akW!7@Bk;Ua{j&bKzbg1$+N=87fLkAg zczn32`xX4!%stYy>!v&Xx?*+ZWO+s%_!HN+r6FnE*61jj+hBz@x z{9OD?Yz`hJw@8{L1(KQ4(NZaR%Kjq#D4iu+ER)GD$a-a3@>TLM`FVMjycaf(=a33A zo%~7;HB)#g4k%I-j};vX8|5zntY__w=`5N zkorq@NVTPFq*uUh(@&Npy&!ukCFEmefuN$NkUy8bk^9Q^$*XcdP=!889w*DlT2far zS+PJNSHvoQC~6hHN>^o^GD`Ve`Alhr$5Zn4EeJChpj02zb(-C?GL3cK0Q@ZlQvU^(xT-I97R@vcI-8!newjk zrt*z)79Ng+(iTx?x3-|4gndk^_vyuw+i4-P3T(NhAFjTZwp#LXgG=% zWm{6|`&&>F(l8XQ${t0z9c)1l5n@mShgx7V3oemhh;D)1a#{o9V?+yR`2K;jdXKiC z7w7Jj*zdG-Ivdjhm%gEwPJ+gDX166C>xZn z)RBP}G@vmTCU(*tY$MSFuBY%BZ?tfOAV_#cct`kJG)vSf?i7`QxG#7%JQ^XREbV2ddaZgpJ<6Y_~S?i z@kzO-^pLzvc1u2%^dXlk-jYE|nPM^iSNSAu4ppK@XCHnf(HQsfN0V+~WiUfJ_*`wH zR>VWP`kX~)W=k{Et4aTKcPh)c6&b4QwsQJTCrFQ^cal!&^QbaYI#T~N=l5xr^kDjT z(lLEDR;G)azl>f_`CGKYbW7uW>hW_L6vwg^9V0Y4Q)ix=M(NoM2HvMGJ7-UE#>*tV5!0q^;R=jTu>?C8Mo27cA~srYfW|Ct3jiY&T>*x#WQWe~72+zw<0 zBDkA)#5mcd6)C}OCw6wF$vZKA z1SE|ZP~z~3t!NXh+Mfdc3#;}iZmpnDqlGI0mw|9>^duVfshxoF9%wi9ZCfj}PuR0^ z-$4^_xQGw#gd(7Wc=oPVREBopp}T2x!Os9G2=l{Rp|#Gz?t5tT#LocJ(I$LoFFca~ zt)>Pbn@}L0zK?#mCVmFEjObBd+x@L*DFJ(+2Z4m^1pDAx*b$pdUXVM=6*3E1iqudVEm4=85`Pm#h&~B-3*QMg3tsWp^I!A)`F?`o z!Y<)+(P=S95+?PMImkcDUxD>O6znG?x56=)OB$3bm8H=4-6Y+~i}G=Dnao-iFEx@f zC4}U-xCiQ>18U%{V2j`de*^y|Z#mybU?l7jR*Uk$T4lR*j?7&CTV6|ERB)ARs0pd9 z$VqeZa`?*jDFwoN)wq9!gACc`5}@G4T5@m~qHiw4AzQX{#HbfT#AR3?PF@@JaM9WN@QyWwydz zo8b|~JDHcHRQQp1D|NYGEu1XkNqJ|t!ubP+hZN1SX_7)=JMVI8m|&rJvCM%wmeY!w zkZ!Z$p>(sbDfP49vD6=Lz0eB&*g6&Y(*44k)P6ykbUEdEu@w}|J7rT7H|IvD$fZ=|?9uN5t3 zL$+ph*zh0gcXa2~|F5(8rDEs*sHt-v#HH^W!0gWmy8 zATGdh;RVgG$Mi&u1wb|sclo#%h!??2#gpzdqcB@;LLnn)c;N7zleYFc%a8S0f;SPr zfuNUKProj{9(YRCKP#Waw;`)Fvcj(b^Pux!-))9}6o4r}@em{2;H_4BI2&yH?lr^7 zgA4I1z(e{!B~`tJqia59RjU_Ic@&n2H&D%JB*B5LEFfH>DFJI2HX}P@jpU|}t8)A% zwLRST^|uEe5x^&=saSXpBsRd-lhyrZG>*uK!t;Q*O#hHzIWBbEfJ>Vq>`V0@^$lzL z?^j{3`Q~AvjmU2ulRuv*eirLj=C*eEyv~wsoxc)V=fOP;p@=1b z)4-|VUqE+oo{c9LH6vS4g2N#|tO-^!J`ThjnPVy7a`5$y+kq@L|DIHSa7f&BvViqAaX4-<_Pph9qrS8 zZ1Exf%iI^=iMk>F&1c2fvZNV#674BC7|6m=HOZ_O%XA7YIiKFbY&N4jag1Z1YQ0!U z-G*cX_&|6XQ>WQRk87C`+FmqqB3i8a+$4T>foqFfOPkSHA}tl`lr^K3#078(2*d}Z z)Cxe;QHgSc`R7L-aGkhQjVW;SY%Fv!`gVV%ScD%#@@iOSk1KDcHACukaUgif zxDbdj!6k7$5c44%Ue)NlkDY4X_&0<{>&Q|ya>xq*fx|*P<`LZ{e~Iw=LGmPtk^#|& zLpB8XLKRdVkuSkIkDF0H6hY%jGn%dWN6s`&NWx1YAcGz4Ho#-BBe1!;8I=*cMU>0a zW?G9lOokWMG$VgB8}k95qY%9PSu?U4+M$@+y|blYM2Q)J`4Dp&?mV@&8C``j^E045 zkxNn|pTma-<1C*4q8V9?g!87BEV8UrQy63x?CV;LXK#YNkO)Y!9_gv@>NcEMb-r(% z%R{E_iQBrS5nyKoNwbKzskjr!7UHiI2iG-&ze!SpQ-C-S`;zfZASt8&keAVJ-4Xp$ ze$;s6>DInEKSE&g`iE*!W6v18vA!9kR+jiE;B@2$2eve$vzjqH9k*Qyyy;~#nn;wS zU;&U#L_;L*12UO_%^jD9X5>dS@bO+CVdH0r57vCuNZ06@!2Y%K@70fsUb3|-!tS1{ zt91KgR#4#@J1@a$J09%c(o6#J*h?I_=+1)y0d(^k;WqLZN zY@92e5$YUac43N<#eu%(!)w3x&6TlmBV=wLp~md(f70Rn>w0h8yN<4n!{_0bZ=lhj zRk#Pxo~RIE%O+@EmYbC2ZsHls%xbb-rp~s@?LL%!I9F{>Pf^nY194XZ4uniIhOHy> zZeA|vy;;`-T_OolTeO{IIr`zwpi83D3=L&exnk9<%J!4`1)A5&bFC~qG>io`ydID& z`9Sg}WQ0Kmg%+8-mF;5cesR)?b-HS!uDh!6O~V;YvxRCHshSZ7b{tayXG42=4j81< zDpQGbTW7kr$g#&;cp0E%a0GBV^eNW>Pq~!J%{*HO(=YQa|NcmC-fGpbGbb#*VYBb+|0O(}k7>8~EBziQ#K}M4#Cqu!Ut;Lrnq@; z-E6ha7*+QD{-KPh^Fmw!2|2{BM0~gnK6LA=$xj^X#yNk#$yqedb$nqzd#UnQQthts zvACxhoo2T;!w5bUn|z@MzXm3r2gJjKtC%~W z{-Y~nBGk={Y2=>g53}xeRq0|rq#hu|pkUt740HAE0$dH`Bsgov0bl73(FSJ$x`74{ zZU7Pox?XrwXEPc@{7%7fK&puoaX7dO23BN(ZvjpjvLWvMG80$kQ%C#*!heaoa@^Mq zV;mIA>RU4czifB`;7p=Hh?9XN>YQP%_|C2W=^_we>+jH0jeHJ*IhU7$0a=?{OWNqr z`~p>H6h00~iN?XwdGC*o<`~7^y1w#jV!@R5PhEA{iP*fS8I2;^!N3fN7r|uX{Xm$* zk19?$3@Z(HnX=3y=dMuMOOL)!;;}IhA9HO^R*%c;Kpmr(QQE3I4bI;fC$o*UZvEkD zf(darWa%a%lJKSwnQ5=4KA&0F!IviK9MRP68<=5*jy3$uVsGPWhz{Y86)0jlbH_thRhfwbKqlu*o2L8l+VQ5;mk$p2HIs8FGh028H+;ldeBt=i9? z*X0##|Mh<0eNWcBdQL=t)jJj=@uQx;`n^>hORQEJY~NBV-ttAL`TNUad%KB|v2)e6 z?&|$R{EgF6AC9%K_CKpnHslEKL8OAs;h`82DmZEjls;Ai*;` zO#0pC@d>-6mmNl&DK;Op-0p$B5o8->W5?TgDzN9=QmZx%qxam#FR^=Mhoz-o`~06a z&W@;D(C&{-)m5-#Y=QRyF84UheR=EU-GX&i>&|u?B+s32Vqqzzdu5?%ldd?QIWbF- z@@(al_}BhF*Y_OGx2+7bIXNNQ0ZXYqxETD(+2R8lDzIw^!B(0onEL3cv|j)pVVUIC6JZpoEeDzw^R8sDT(t^2AqXN{iQ?-wQ4 z-qd@&3Yb|TIPJzRD(r855%uo0@i%aqiBCdyYeLGyX+Xk2eP2Ucg@i;G99srtGQr~D z8X$gff(0HqL^XJj*=E2AL?|B%fOry}T>Kaalh`Am0(4Y}0rMR$UOiL=^Bp&g0p+8# zm=>~;6)P=^3_7enwE?K8& zn>_t|-&(v+R|T7?X1EM+862dGM-5jY7n7IrF5L>XM-6XstUMcMJ=Hz0J#A4+UJ@oUKE3rbNIMkEAgn&Dl}%8dpz%X zV^b-EXg>~0m=Lv)_%6XbIt>lO*8oF_T_S93u0pojJPGgBDjrOfXF+fwxF=@=y2E_q zKA;V(V%`CsB5oz)FblddO~VfXDPk87Ct9k|VY4RbuEy-o=|4P6!#9^}&i-0-*WAv# zwIl?C#*GzS^93^O1%#{LD~w%`8OrJJ^IfK^{9Px(4G=w^*pP@dtyRbw_6^+ur;Mse zVj4Kl=b5g5?f1dt_t5dmdHGfjYE>j=Lh>CLF{azVH%x4g!(1Sbi6SB1Fh+%X!N@CU zEdAj?eI2k>f&L3$`Wnt_W^izbBmH%PqTq2LlZiGdbp?nW@@$C< z8@kbk{IhLJMG>1}WZpKgVQ$6P>#1t>XHa&xH|}lqyUgt5PWJp#w@d4C`NK%vFyg+I z5X|kIRG@3gj>AiV@Zg=P06z@X#oLY42GadAoyOv4&d~jVV`=O>L4`J$O_zD>)OXAx zv^|y?oBcg}t!LcTyHn-m#`j2^2^p3Wuh>*C5PxKRN?xFqbnV!u4nvcX6=wfvx`kQ& z{mH{CU7<@dE?|$CFnMToV~?Yd=m_urYjAY*#D*wb2#Gv158+d@c1Dwa|81o$IF}xE zU_lEC6K{W1o{D!(RDqh30nP$k0|i!hQ=!=ox>60hxes>!&KOfLtx9&?^pL$tX_2O` z|G>ZJx(dBZS~m(F>3zH2l!U_}yNCHn$w)Q-pVRF7J{6CtFq?IH-+457z1x(AJX3mS z3bM=r#agU63Hmcw#`ywn_0W>`Dw$LNSbevhtoF^WV?eh^o$bgG|7P1gzxaK>pWn3K zT#3tAe_fu%vf7ml+rL%?M}KC($^kB(h}^NRJG^Lwa5SJB^#9iYRbU5+C6l2#plAFF z_^**rDgD^&aX@?L--^yJBTjC29N$u8inmUoJAx)5ZUEv>C=;-)2fPeI#-`$cz`)`U z;#26UwbMBK0_IYfTPPveM?4T<$ut$(0`2-Qps(>txkZ_a(|LEd0P!oEp6A+L#%r5G zxp<`)l#(cx<2WEnm=BKghHi=I72}>{cY*y@w1{))(7-h}gMH`;6t-uDxGcggC|r znlto*Wq|*nAZ#-oUIuY98E*ly7Cy^jz%2OgcEVI(IS7;Q0-6%{ShyaDi!nRd((pW^ ziDFf&F%@t9#&R~0HYzzb_f>&fdA0zj0C7RV_%7gSB1uGT@>8MVV1$bI&4jMRK$iI6 zr=EFGjO|r(-C6x%V9tSO&4R9lka6*CAZElq1@!_53lX>2c*7jJ)1Hgp0iFi+)A+eC zHV_?btTT^pRDO6aV7B%;$wEi%^phm+gR>z`4Qr8Q@L=%nL;xD5Ju!ygLj zn)?&SAr(E2|K%;wu|C|Ri7!El0zSwk0dxmC8*c~nB|?*N4iL{#ZL%Q)1AQg`>Jig3 zau?0@)G;gZtToB!;(kaTL;Om@mdokRR1Gfx^d@%2;y551h&BQK2xJTKmW=}fp6*W-!S-m##YWjo4Inv@5^;mvpL*ulnE8)$a&BI!Z za2@0Zn+5^aS)oD_n3$gi+)YFY!0o9D#b|Qn%YJi(n1sM&;s6-A05L{H6DW$VQlUo# zM}%*#rrY5{`~h(8Nb{tZpAri*#^`PdnNVi6amu?%`{md#2x@cUFR@*PpK4cQV)lre zXB(s25+BB@u|9;`cdY0Z3{>B@cd0kiBub0Fh<_j2_`teLjLYG&K%|dH2g7^~RwllH zLBwXz`2?Z_vCq_hROsahuIzO?@maX)!We@`dzu?;;8P1xfjF!q7Jmd{O)z;_XALxB z0?d@=0og$8l;d+iXg%guz_C`RCip>o#vp%oNu>z!8F7AG=cohjlvFv7)HW2K8DNW~oou**gjY@|H_g>4{*jV^GT%r1?SXn5Xz`_5x-(@5tzsad6_|t*$i|`)kh`!qQ;>HWlm{HcRlN?Jy#Y3RFZ5@BRI`vv-%ynL^EP7sKir z{@9y@OO-q5N%Sh%1cYfP8oejcz{*AC_d2L;{yVEJ(X|{)R(*Q&%xBd%X5#dn^sA#t zOzfgZ+>1%rAIN%W5Ltj0gp7krfqa4^hw+u&^ydI4!Gx`uaEI8fAFbeib@Hgz~V#0eWnmiP?Z-iOVtg3J@PS!xVP{@q*)jvGYNCL2y`# zqkznVv!QVXkPRlW!UoeW!*4%y+PbEszYBkN=85qA)tv!&<{^6c55xxmCqSo{4rnvN zM7*&yI#5&d<(0OMZ{<7&;|$%%wltO}jR~6kJdLd#d9xIO8?@Y_V1AzF=Kh*uFlkr*pD9i>eBS z9c%UIs(R-9UJbv3J1TTh{LOn;n+yI7=s#a&fn$%*>%FfEFq)y)a4peT3B+z*70>Nx z^3{U|yR0_;_r&5swC-(L&+JeCysB3IGdj?)vHx|wx)+Z;pmm{@U76+khZ|y(ZRGjm zNn6L)F-GcHxvz?Tf7pFVfpw082msdVn*pZ|t02SvEMChTyTv|MiO)fl<**LU&Iy8n zSatt_Vj-@9sD(s9EVlel1;!THNmv5Ji^!AXS|B@!i>cV}7<7MVB;E*U1dcq808Sk? zT-N)!Z|v8$2=z1IViKb42oNB>1#*Rml4H?v=sbwr6kG%(!`KE_8xkr^bfyNl_$?5- z;Wd(ohq}&Nl`WU5aNy+y@wY9NF-XiSiU20wf9!8^mvbT!6onltPaH+riKb z$SwlBR9SQAf$uSiX91}7FJQeU7kp=$n zfLIg1Iar^sLKXCCun~wSe8NTom@0!`lq|p|MB9t7L@-k$;z?{ErWZnu26LVO2E1o2veJu+0_8zm4|0Xm|k_y^#0 zqA3}BoTdkhn9GXX*EaN<1S=g&dGB-U^sUoZ(`#a}W_Qo1^{ikLjBC?>>j^ z@z&p-?)K+>l}neEovj(^)8(JXtqTe_TDw)ZlDPM8N2{?y=G-)A=(oo6ohIf7M|6Mm zcMe)M)UdD==PtMA7Ck!CAjLemtq-!Io&fFvGk@%x1EL3_5IoBQF*Z-<3=C7vUT-nB zD|UL#tj{&qziw>On6m5~JM0&XR*+>soT^NPomYXGI#DIW{uk-{x!_p9L*Sko{{j*R z_l?elIT&$}jV}Y)LgazQz$I8o8hXbRtnRBk>e5u~e(A!m5|2V?lVdN#7;m{$#(Op8 z$NL4pjLKC(1~#>ttIW)DpH6-}bkf>(u$dJ=rnSUY9_|J*hPVrcdU-V2$iZGf#v2W= z@AcY_n976L8eD5R}3VhUPD>HN$u4}93=bZt6sy?Cnk=%M&Cq*)Ey zD!QtB>kDI}de3JNzFdL9pU9TtZ9sT1D;fZFhqvx}6~+TNP!(?j;zfv4@EIU0-MtkV zeJWGGMU^jN+h%n<`ljdT;_E0|^kiRt?1#&I-F#KybtkUDW!KP~5#yG;*imRhEyYgx zu$mo?5^HCE?VmgEn%kLYus_obkqe0q5<6dmKdSRQZu+aE1H1ae#h3>XI~c0uc%||> zEd*GC-2hF8>*4~z%O9*4>=F0d+GD|_3Px&Z58^>$mJ!18D#-I=`q6Dfb&;)CKbb>z)c+I8jeFP|$h}Wbw1?u+MbJ5z zjEmlgCRV!4v};lPF!7FkP`voYaFcyOcsHbW5j`xtp_mqFze>R}Am#)}`ECL!BDR1S z`2pR~w6R_ZbX|58oLA!yPMSXAxx2~50q>i!EhAZ#fzP%*UT9p{pI571?d_iHUo55q zATtQWg-LjIDLs``39tajjv?(5?UC6d_c_Zti4YTw^?J*eK?hX)bpvSVz0I*Q*a#$6qQ{ zh%!DV3HhB!O!xCV)Y2c_&5}1(o6P&3fQuf{l90*xC*TC4l7$_rREPwDR0*IJ5zfZ% zfq>8ii~t_frLo7C04<1oFpdY}O#I>FUqD<&`SE(1+(#Q&hKvk&^;1jB^YF_W!vmZ5 ziKtmm=*6D7WAX`;7OR4mjh^~%@2X}0s!?F$0L7MxI^#iv#j2)<);2M|4dktErsSiR zg?Yr^V~uk^I^yi7FcE-RghdVAD`?>5fL25$SoQ*Oh9Y4=M_BYe1oQ@%xmfcV6x!&5 zLiQ`DKHu>DXU|c2o(o&H5Z{gL@DfNnMqGzeBY|upj>18owY0G59_V!daUgbq1tXB} zhJi{GTW#Y`C(Cg&+?oAJUvte}@v-O7ix4f~?B#_DHG)Df3lsJ9F#1Z2#{*eRThK-T znGD0}MZkYyD`3P+=xWE83aM#cfiHLGp6ye)%c>rf1@WI4i0ykIoEt>_{5+ZlZra?VQG53o-0*k=xBxAF(>w~ zvT-+qFZ9$5Tlgar#kSOq5>(>jTlDb>G|;k9Y$Udv*QP z8Q2lnTq2W=_X1f=?+)Ap(oG!a;VVth;0?M+cJMcbyXoB4mvvE%8{HeCu~{?hR;hQ9 zj(8ognaBxrCTK}Z2rdTPip(h|)!-z%TZY%ZrCTG+gA##QLZ_1r$Rkk3 zjXr@Jzt1fpHkl0gaW;fzazV;DWF$HEd##i9(D&v>ZSCNN5ArS}x@6ew1AG*QrNXds zUQvrm+!*52Up=|yZfg);11X#JpNn%fPWF>4?>*OZ8LRzAj;kTM&^Da&L94Il<(tnX zAs_qgc&)^g-Z6f9WnS8EqP3fz|2>^2d6zYK+zay7NdJ2%^Ba<)3KXJ~p4kft;YK^2s=e2lYCS zI8D$}p)H#PgM7`{K+1sgsQp~>7~}vYL0XSV+SX8u{7oP$DV4W^D?5+9-6M1OVQDdO zo~Anhmt*s6$Z2M0*@8|vSx>H_;(K-S9cq5Eiz1C*n=B!kmVS(^s?%y}2+U^XNVXOETOk?^E%*hY=8V8y6j=LgKEe6`UelG34x=5YuM6D$R z_8FiqRv{eV0_uJic>qE?mEQx+G1aNg&}-dmX~Y%8g6b2HaF7SkwGC(K7Ba*exR)B^ zk>5a^bX8ew59}GVWUMG#HMv5q`kWH!Mx8dbpF_q$B#iK)mm)?L)sA>RD5qaj zIhkYvgrDmk~euraE*&8F>AJp~~)egkT-c76Pyw%ev zJlkiw^Zew*fY|5qter1w!M^-Sjj%hekG}abz$77aM2reLQwb#}g74*AjxZGD2!oo2 zk3n7pn^;Fa`B_24$fwHrLJdU`0`XPk;=>z~R&94F4ZNR+6elA1#Uy<47f3C2I)fZh z5@DeoK$3ty)QN229gt-Vc(oZSA}mfQVh=3DvgbZ915^73RS}-qjWpptkWf01;HsL4 zahtk`ln&~64mdfN{0ZVg9g8EcLG&=&eFSc%Vvt@@Lj?JSpV_V{`hWDnTrCmIQ2N9N zxN5F)e1hQ@@7gEJNCrM1r*`EPYl|QO*AR2y0!qXqYe5d73seCQZ`J0ew~nv1smaog zSYV|XIbX#@w6dcqNx-V^ofFvMQ=hK2>zcn=_tY!TFr$z(i>)?B1@$Szp7kg8IoqD# z$bKo34D|XKx7nD_D1Clp7c14Ob{o^GR(-rhem(hBM+6<&qPS`Fc;KK5bK&7{>xxJz z3Z1F_MdTSsoO*TU=(xdjn^xSii(UKHn3BD^B3L(l$X%chp5iPJ!MO#*Mvs0Zt?6VN z2ooLjJlX z@=ZlZ=dv#iSHDNt@GpiUEMgG#@EeE;X6PDV6l0rE*GL3Sg4&%){ES5i?>U4_G$6~U z6UoHFM1+aqo`9SHSwbZzlFK0UA?ReWsR&7SoXJ_BF4a&>DnXdEw>`uR7o>ft__DZT zY>&{WL3T&aQh}7E;zoq1xoXytKWQ5~*CpmbSM*42lgY|KrQ?-h^LLrl8wNLEZyeJc z*Ei=?Q5KI}26aH!c?mQIegY;?8_F-(h8P(C=7U!uhms7o|(w}9c;n~6ITPx)|ybM-c(KYtaZrpoyF1%=#BJ5>q zFNBjFS1$jeNN%PjpG@Gx9z56WRwC?kS7phNAHm#l%NKz5ID3&i1KC1#rjv#9=ywoK z3V?1@Oe(1Z38Bs*rIoda5pB9suy=LI#M0+-pA1&r8t#(1uF>jI*?(npFytS;DIsW+ zLuJGh*ZH)lc#d3bASbAV1kwzW%5V{Gwh>|fBE`pg(U$HZw{l4_h@M$oe35lnxwlqt z>RH#jUOp{NqNXqRnWP1c;3|tJpF!#j+F4gLcj?EEI9q(Jc799IC)WGp zb5@<|z`hkb5#twXNeN8&-eAY`k6E9eN4X^@OndmsO$$|dbMVOUAoETflCE#+6?xZ@?o$~C8nNRoM`_JqyATuaFEx(=ZGcs00 z;vGeBr+h_BoiJ#j%dP?LVrY}Ufi7xme;A)A@}) zK9kitmpyg8bn|Q+x2WVGrTGF8*8dY(gbfl62eOg)kVa3kND?UI1tj!aAa%Z84u~62$NS%BFn@9bGfIxSMK?HIi28K~3DdYwS+c&*X z-+Q9FSfq3LDd$vRD^>B;j22UM+`h8Eh*|&d%75zTKJW;fzFJqeD2yG{_n@}Ir|RX<4_3^XfWt@6Am(H&~CCJFdPI}!wwZC-dJRDB*v1$m|@lQXfsOJ^#L>|2C~ zjEx38zzdoIEW^27k1o7&QxWK?-z3vv7X*6TR5ls$7123T$f;!_hNHt&;ROw;Myl=#YEnM+ zWtgS9@!rBC=6h_@sZpKcnQPM`kI^cv?^r%9d87qj2*!pDxZUadhYc$jB!oh^N!)uFxepZIv2Pfp7}}OB9p!}t57AGk~>M$`Jaz9-L@NklP{W@wx44) ze@GwGQ=2GgqTR6sq;!ZHV}MJC`gC5W%84 zpZoyy#;L62GKe)b$|cW0)>2bvh|NlxV8s;!Vxu7uH2y2AHr2_xrMtN;@~2`_j$&s^ zx#Gr^el=g_7q{DvbOyC)&-g3a|1kez=&h`QRb!?*1GUK%+BqTzjcp*Udx&Aa2ML;U zJo{-9aS9SaZA&aB!5|^VAB!ft%dDS{wZFGq61z;Y`{-k{lLCrR_b=jG5Ece@FKuM-znMQ#VzmPUIiN+DGx4s`mO7db-)eOR3SMBvW4n_2Nfh;`(x@( z-7sw(jlDeqpPW1untZgvNMSfeX4FvbDGke2BU!v}Iw@OR5$!nJE}Im#suK%A)d z4B;5a4F+bIOB+QDoFz&&M~N8UDJ2!3-Q22lc4#D%w4h*{M>eNvG@a!$=ph7z)}_&0&%5|6%vbW zXgYUWk$n5vd%;E6hqRrR1$7+41&OB$a)`+e`aOG-Rlo(*k69!J#7XaY=GA*vO+6lK zUQkqlO`nO;;Nn|VI37@}i=N_;=#k$C< zaW?YOvpOvukMF)VxlMMLqep-F{5aF_H%cq)Z`?66A?n|V7cwppP4Rw-&k}{}QZhN5+&&kM$W|3x49avL)fZkLQ3>f?90vF;5yiHXkkqMA< zRC+2A?Ek+=W0N`%f2xc{R1VOc!;-838dI0^$PSQ7JU;z{B5dvMN+Mc^MDRET5Fv0Y zo|N%n5hH~{v{MO)K>lp;Peb`dB_!;9Tt#5VNBYEXpbga@HQ2a-qjI>yYCp*+p+CdIkbRb^)R#2Hq(jzE(K2s>DIvQsz}ya%5PO1shFT9mCn0HShYN|?mP0^ zu4lsMBZF$-!=8s8+K{H7Xmw%_ zn~Z^MqkhUG;Xh*$X7(T};H_6~Q1-T$S`qh67b{;6AGftpZf+XaYYK|aCC;(X?vyI| zb-GPjE#{M4vK9p!joOkL&UwAw)5-0qn`fonE;`{+Gd1t=1$AmBOgl2GSe}brbkB9(py7bv?mSAid+NfSUe1kM9N9X} zW~uoWE$_y==JTN?-@q4}4K50{^;DXk|9oqvP)^AzYg(g!Kw1$9yT-Xhyc8HmW`Uk+ z*NPRd{Pf=jnHf7rMmL-IC(+tO4TtbSY&0eDfx}bGFlqgu^0InUM_81epxjh5EA7fU z`FZ>m+q=)s#?D`(xQ)!B+=t3f5-v@~%*;^cC;Pge)8DPW?>iT=D}|o_oQ0D>WdL@DaEZpG+J%0yEBFS#-w}6 zXae~F;-}=5l=_yx;<)Z`ws2{#h@nIq2Uf8}j2~4hrx7leKvSg>)TaVov}=t!Q3aTHzl6>t&Us=E0YCmQ<6U7yxA7JYi^ z7k_!(?9V*%Gm2fY&b|Ol!8*vjK!kHx){<^u9wou{TQ=r1qc*P0oRQ{H#o1p+7xvGD z7dXo-tJ_>V^9h@Hv^Y@1O*;}(cbD_;tQ>kP8+f?xa8=){GQF&>fUSYjFA7fNZ?tKc z^OTLi+h4eJpU1GM09mUgh!VyCqk-&t3{*|B$`UdA$ELv za*QI8z(5L31R!R#a&Z&H1Li;}@CSO=!GS{hJuW3pz*PvuB?bc8gtMAN0S{`#u&!|G zXU`Q~(Q9@||E4jAG^4nm;^dJVMYNKuK}LbLdM-(+?rxq9tx~O{U4i!cz4zbPFRd#i zuElssFjpJ{?xot&$a4@TRbE665fO}`8p2CJWrpc_?jxHQYgEU({)>M(Aa~+r>Zf^j zw(Kk7`VS_iR;2wmdf@aF5}mWO5o?4?9)S#Ml;pRDThwfE*wy}Of8)=HE3P|-R{fxH#r>%Z!x63gky?8svgD$ABh`l` z42S_-NpsJ`u0dUeZ5m{;vMO8Iu9Qmt*sG#T7=O}hEjOYMJg*tRlQ_uEJ#Rg;^MdAI z!%9BpqzUEK)DK*eStddv^b6QE_LqnuGTE7OK;^SR-^&wo6{lJ=8%i`T8QQfX3vI zY!If_rt|}k%|>$8#Pt1`{Z*E`Z(b5{y+qGTz8UXrrh{86B_7Xm3bXFk2)4lIzXHk-AXO|=u{&aQd#`&NgKN+Ft|dYbWlxac&djZiaO}I zv}?`&ner3s`3RSxQbWNNSb(+XpS5Ap>a&%%iEH4)Aj@+N7(byO^Z+d-_* zkG=rysi!#d^g8Yg&Ib}zLF=Bo@`Y>=BL=K&SN;_-WEoUbDygW1z@$ntNqiN?j8$^Z z`lrn%N7$>JHyr<=O4Us9K~;0OOB}y!+-fRB(Dnj>lM*x>bKVs<(Oc{NenRki=UgM% zs4nOFhad0v{-ZJ_Q(C;e{*q$1Lfmkj?2&Kn?mcunk7WJTSc@B$75ls0&($?59}2!% zZF*s6Dv}MTH-*;t9qos~nl__&+G*@Dv`eh3Qp71DOT?PN3XclmKvlemmS zs9KCxI=Xoi$QEjdBfJKp$Y9JNHMgN{*tRokofJD2lulAjt2(b`PD;c07JjbnJaJ#X zQO?G5*9taHj>k`JC#UW};G20Tji=!*rS)>Jx zvMGK6*?pH5VEg$vs0u@iYQ$EId$dB@SWH+Tq0|-FNkQu90NKCp(`Gsi;{E`glVTy_ z8{{PJMD8KI%H2#B06i&Wyx0S>kK(40M<9!-k_;kWhnuGjv%w%1MlE?VI|SQ0HL~2Z z=PC}dK9sF$F_?H=Z%jBO9t|!kUuB+@O7&#N4?4-?^maTjqs4-WQBRd-7pttRSz7Zg zA5E1jHYZeVG;F{U8V$0cxXuEx->Mm|+Xniz1(UCUixBsk0n|n^{ao_fBlLPhqm=#s zB|R7oZ|Y86!t!h!=&(Edz&ynAO#l(2egoCPB3_O3i#U`=SRga{uUG+}JL~cf{`0bY z@>Y-Ag?X(#-s8t~$@#}3WD&py_@hmALhr&=X0)0W(=}Yh(Q~E4tDviKsOD=!ZTm7ZiEe~_XIC^^lx4|5un(JN=YV_ zAQ5<&s?XrKFtH-RGiA?9-Zm(tF3E3M{BFb8!M8i(OP?hT)#Z_RG_lf^<__)Gog zYQ^!~ccS>|8L75nB&kB33pJBT-hu?_f1N*6Ra<6a(jltM-)XeV^j3dG9geCZtJ>+= zkuXUj$Q`PdM}nV2Rgm}1i~O&ZNd)*1WYAo+l(9o+=#_~=%bWvUv2&xxD&OY$B!*5nc}mU@OTp_kC0sWLX1 z0XabR!35n&KOG%%0k}#xoWDld@oBf?g^B@Rp9fz|X9gbJMf}Svdg;i?BE=xfbk?xf zC$D{PsT`{;tF}(Z=l1z&PV%J@R3ZK_g?xA|Lew-)S$N%r$wcobexL0rE9=s!i}t}v zN|htJhA!_LcqHTvbQ^VBW`g#;hnL^))MYxzeU>9XqV!ve4Mml%);lH$Q+~1dvf8`1 z;U-DtEekK1+q}G$MvS`YPL)?gmV%5?1w}X@Peg~@(KH8WpAUyc7K234Dq1#(6QoErT?5J5 z4Ya4EOrr7@`kvmdA}#NhXTCw>rZ1lq2gbHJnS~in!oP@016YL0fDKeVERFBzC2#;~ z0|vqnVmt`@wQ)j$hdP!5O%2^i>!kG&b~R4f&u%>!)ofJtCJAT}3q$-Yup3^q?)M@_ z4^;{)#1L)XNzNh;!{{>`2rM z`&Q$6^H8VgNa?N4v7@F9a>gq9#`i6nEQ_2VvMD@U9@Ckig zbN!hYMxN)b-v#+R)%2O(sh~j)qdX6p&59>Pj1HY)ftK&ko$8^s(LS?-p4;`@WKuH8 z5ULhKbFiHhF`iOC!GjE9hV_Q=XLJIsBl&mLyqf&nwv3lXMOG@Y;FH~miuFe7xhIy% zwCtKS{Pc76$-PP{v2wkRw;l55!z5RW2Cj3D7u9^=1*pH&CzJS`MSY4VsZ%g7T6J*W zsWd*h`sV24v#*9l8LQHTNw4(m&F4BDSfy6|b)Z{8HfcdaYl@jlCP2dVVhh=`TV$Wf zRn+n#yaL9Tj^5B$swonFJx#kCATqkX&?c&L8DttH7)Is585k*HKDiF$!PdKO7B(@8 zlH`#=h8V%sQ+Y(55@P}GMZN(dw>qpnAZzJeUi~1;sEaTx$%+{cvIPPS5(&0~+KI4w z5DNxFSOt`082wb_zPPD9aMpwh(T~qB4@`2J8rZVj_A%m6pU)99oXpBHqutk?=OsGv;Ax*a~c?uBHe* zl;~@wV!7B`E@nK3h22F3e@6|lNjZo$m61+bKz2~av&ceKF@tGRm8s9r4ce0WlSR_p zik3?k>+_?$S=-hWvaDm%$!jzT#RTrCCWb+Q$}1-K)Nv68b%iWXL;2MG;(M2eF8AF3 z9J^%xK%70yfs}?A1{fxngn}fhk8u?IZry$Dp&C?fIpFL@x={Kfm4pmRnqqkVlt>Qn zp@GYp0n5{r|IO_S&fS%doR_@B=!-&RPdS%FYl*Q4i9?1Wkk4AB+>cH%Twe#yxVw1g z%L8&p`Q(u{eOob1@&V)@dMkUWj+o(WyCg5vF#p~}NTp@%hT%@@9X~B|H0iMN$_X)~ z7O!kLZFR8X%fpM2=41-3E$Ka-X1Zdm-P5p%3dA4Aj(5OS2#t2v6Ej?_wj@5)F@JHx z%w0|8z5P2Y;f%aMU*gwb5sQK`=Ss%aO zs(G+AqCGmD1fejQYAPa+LHG=H;Xwm2+$GeB6q0C&PN){Zl(idNnrJc7HS|D~LT;k) zPYMaE_8Ey8E!1c}Sz;_^95CIJaeuZ$qN~l+e{A2YIcTzHO7NhjH%3mR(=-`EglJO+ zljlJbG3>OlhkDgxxfnhJIu0CUMB!Y@-S_)%`(dBCm{DY1e}?n^ zg-89*7hY;aUQuE8Uv{68aalDMdB8+cyX-}6mAAwBG%|*!C+XJ}Z7GHWHH5qZ{!Jw? zNv0J#J;f;?8uP@EbQ2lEUqGA~I!Yuke^g%T@nzu4#OA*ZkE~LHvG}Gn-O;1SE1*%xKoCEYO;|;$FqCuJHf# za70@!6(_veiV^xv9b=KBcJwHOS3MKNpMu@08N^GoCiA&-&IjKmR>9jGD-=HU%MpEh zF?Jy+k-b1q+)5$v6vbx|BL{kXhLB@GV>*T>8w5F|(nuwUGxfTV^n)y=sxa0a#Zb{< zum2jvf{M+C$6Czr(CFa!jbFTxs%o!%@VO=<9dSn}b~3-1TEAqSS7p;#1-B@>Mn8R>qX6ffbDpiPGZJkNX1jYNO&@y0uvzmq85me4{imS>nvv2%f@mdi6@w? z3Pnn++oMXanavU9kpn2Y2$`Yp0@1{f6|M%(qcmpnTC`5t#;-Kh6?|J-I*Fb3ZerM7 z4TLeda3r^PD&JeT)`xU26hno?d0A%ev;gkITnJK0?K(p~fY@2oB&jZ4 zr_K3%Owg`WqN~)_XznUsE>l0Z+OkblH*`CbEb*YFg9AARw5MN+0OSPrHxMmPJV5=< zv}&IAzoq_8SbZ%%OGDH-sWej zq|e)PO)Nk*jMu+UFeaocPl6CQ3id zy3F9q+B*MlhVJB&L^OQFFcfZBOph=sI-g8?LnNA=%QHIOEStkH8K}MAco>QYtNxR_Sv`kZ@Sx%3w0Zsg+gmA z1I}kekS5?FYz`-i%ki`^y_^E-(PaIlAcu6~ijKcX zaeXIOrgh8r*ypqDzt4Y=P1XnE9;tnW!eWqp428$sD+Rl!t%>p~F=K^6bTVfoM&{db z*%uMJJiaw|Rd{UqKFtLu741Q_9b*;A0vhT{nCl1P9;$c+R=xf}DHw{bc-XvABGsr{ z1ozx1Fu*y8U+4UT&Haw*UCf0IJsUeBbX8|gv6lDD(~F)-SmMi*@|-VCxt{3TGv71t zX0mWkF#U*e6E9XnxKbx^?oSAW7d6Tv@gRP%=G_HGQK>9qvIg=Vf0P7_f(G#l=(A^k zQC@k7`g5&os@*I5w0*2gB`1fr#c||ont5)vPfee?&YXPhAuh~TdLI&!BUUsIQIh=K z_ON{Op5(!+hnMcO4eCsq>Xj|>oYL8%>mQvtJZ^mDQ~eM#?X<3ax;4K=L;c;w1oBHL zEx7(oC8Z!XjP1fk;28$h#Utz2im`4%G|vRc4m#9s(>h2ni;m!j?Qc-yIa!5}tqquB{+9B+C(R0JxcnB;?`E1u6RQMy{TD@SOv0b`s& zjj+kaa50QJNBF|OKo&BnOHA_mD~M;MnYd?v=0A@z>_A?a2>d;kCcA)9kQr6LNF3Tp zG$QGFJb-)!TtoeqPksZjMlZe({1qKDaHANuhF{VN7i2=Mpdd!gRZm^NaY}GCmQ9MI z&>_`S6TFv32GwlReO=NsnM59=@HAD)Cu=u}8Ljk*Xx5vd@IYJm78ptOa>+fAX0-%< zUFfBe59%Mk^;Jh;#@u0zQ4)NbcPYor7Dy z`egNX2yB&(BAJ{Y9^1Rx*B&e;CsDMLJ^<_%$UfZl{2dsMbRbO-$VzyOGl0t}RuQ(5 z%V|`e&@<2TzPWChpTm&zBmH;lwVHQWJBoK>hstg!oyzk0Ey~Mg!-J#S7Lngk z;*Qy*9frvy3Q*=SNosn&#v!f{qP?4U^G%KeDV*-GFZo?z{7O#^Nzi=Jn|v2z%*()mB{bI z^OX-E@Afq%kd^pggYkG6xJYk}K)Gw5>gTdj)x-0I;%d#GtXsN~W33XEf6>;#J^Se& zr}}b)B?r(==uno22gTUiEk}$GL9#&HZ3h;rPv^UDHR?U(c;e~i?yY}o6NSTK`1BRY zUSJnA_rN1~kQ6V4903V6`LDQnfssbvf`aZdK?)f< zeM<|5oNTfK#E!aT?I)9=~x`D|$`$3fA86ln-_hJ@r1)4`ERnxR~*b5+xA{$U?)8 ze6y}?l;VfcKjI%rZoiiH1%x>Y%+5ZDA}%NBX?{18YyqMDeDi;RLJ7PJbTPAM?+MYd zKP4A4QPv=+ksbFTJFe?1h5h4h;5>m%DH<_i1e9UhiVcW0V~cPN(2$|=9lJozx?ei? z!h@I&*FI*p@WhW|1pLw&wBt|GTIfR#nFhH*Ri%*1pJCPZlzhLCTr+OA>Pd$eF2*idu2k$$`4XP5G)=r6W(q%w=)O5P?Jj0DW zHmY?cd#KQvs~Q(;W)#;k3})d>KMm=l;#@fM@P?yMZFUL?oL-}7DRnT3nEXnsiJ1FB zLB2+3`WyH=G}{evVr*tQmPC}!;6=mSDf|n>pFxTE!l8I9V2}nz_+z4&0XIM^wqqsH zveB5l1VRL+6T4(F96(4Ms+2-cx8LOvXAo!4g5r?rbd|Eciel@xU6L5<==onp8#icA z`xzYJ4L*n-tX=($);9+N&5yhI*ZIh(tL@X$+rFLT;=5l_ovEZ31Y41aW-2sbjJX`3 zv4eH4W{dkAIqCk#UZaC;qvAr*HJ;`w!-$T+ZS!k;R;}pne_?vrw##9th_vDhr>R%j zBqB|WEqH;X5ZG?wp0Q`_RJY?i^(U9#c2K9~Ek8tP2M@mTGosFOh1u!!G@)lDi03t} zWAtTdWi-2gm!qpcC(jwq!j=qLjo3^qGsQ6OM6=0hkOwN(S;yzu*i>IIv*^QWAdCJ5 zE%GanP!mjIku8R26Tv%vAbYelil|TDFYK(Ai7UP76xowx_alSw-@J=7$yu7 zR5zEjg3!yDkHAQ(B~2KbOW(ic>C7dcOYDwsKNx!Z#cAtCUH$j3Wd;`fQsk%7R97Z@ z=cXdL%EHi~Cew)oWIdIR#HD%k-N=!>!0)IdIpi5g92Ff;Hsy^KmXdY0LD-&`LLxx7QBfOA|SVV-wg; zx&@VwVT-Zn;u9xEYt%KYjlct!1=TTMyp7S?4^n%2WW|V zx&nNmC=&&(0ZG8-AyI=yN{#6J)pAah?u?xukyaS>I#abQUov5i@2e9`X+U zK}!O65&&GSu1Ky&o_O3mE&ek5Ys|v6q!6XX#{8l+&O7b9ovjRFzK^k&RnWR!ae3X2 zvfq5G9LW>3I7X!wkd>wMWEVw#0Pdu!k+~hjnO;oFpT|3gsGbkpPSvNAL=ZoyVE2JP zP)Vs|>7TeYotMlV+rLz=RIIj+8%t0l zNF;O0VAIg(<4!MBT%V|5{W97?7|?;@zc4dUe>2HakUdm8lsOPPo$^%OJMrInb#3w+ zeYU~9;of+7*90HvBML;adX>H4r>;?V=J);Y#3uW{p(1kv8 z(&ld%jr79uV>ZTAIE_YsiFonu%N)D2&wjDqpGy8j8 zFIuEaK>R6AGO@diL9B9%qu(a?W=ru-I@1diMMjuVF8~vucDP)j)ej}2{tw-!eT8no z1ctsF=j8rfT5Za8H;kGpd)Mh^^_&jVbCVM`T%}E*Fe5y4$#Nbe*<0 zC=#CvF=Db{bbSW0O{t_feU5EQll3i_ivERs!kmx=wAbh>443#Xb9)`x$5|M-T9QE? zp!gRh_cP+jl1;ZtvG@$Fgodo#nJVZtu(Kc5*Iz|!tHg{;)CVqk4w6sre2Bh*wK8n$ z+pF=L`df0_@BJrDRlMaa_hwvc(q+4_W6e9Q#iR(e$EcEYqH$Az zpOjo2*mAC^DzNLzNQ~#*u&(Nwr+VQoZKG|(4=K!trEUesUdq!{EfbrG9RAJMv-IY|Mo(rCylVN44yOkUQyHB&hR zZ_;ZN`_X?PKN z6Q-l;S9k7cY{^UgaKAImw9iFa>o59A%i76SqDXc<7Bl`pc%DKN{lH;hvH`KC8na0# zNF3&gMqm`RFNxSR(~G|&g=7mz1SIYyV4-F>Nw|Hwb@FY}r^DUb>N~~D$kr!NF%_5P zOfK8uxeJFF;G+$76dA%==yjMUNde~0Q!T#bwEmLp@)cVoPlp4$I{F)00@P9zrA5My z)>SoD+GljMh|g16>p|93F33vEX0L$r(cxuV(VdLE$gT?6v2`X+eD}91>QCBKjba1$ zsLAz1u?#_j6VxsasRdbT)|C-{u100mgR}36TUpP*K=j?4rl$f-nR?oe|8*7;qc)5z zJo;+j8gw#+XY^ZYI3sid*}}l~7n0geUx5K>1a6)Clz&8Xv@;$z>-HRTBJG4a3bMq3 z$t>77Aw8zoDvEt6q6A3g*deb(7>lfsclcrTU^WSLZi7&v$#;*6C}yk*!@A26N<# z6EaCDC>NWZmcM~yf;sCva1os){SAmKG(pX7F{4@|qxkeD>AWtDu$E|ZN0SUL=|r&= zy6`M8j9yHy712{{0LcNm!)9<7=!to55*Pq=-B*lR%sES7;-vF%&FJPeC37;CxHqQ{ zUajgbE_@oR96OTi82S14S0`1InhsJ2d(S=1$|HPy=?KNf*&-5JRuyxF3qdY2)NG1Q zsfJt+y=>WaYTI588S0_OL0dA>>%~Aq4EbuH3l_pZ0qvYORj&K7vh&58+t74(v@E0YY%cR$4O&_F>c6Q z(GP`CZJg)zl;@`Y(x+W_Ha3r}MB#1~WxjuPX$TJ#Nq%@0NHS@+PP7 zoiqcIE4!|JHn*ecxvf=!pwuq@o%xzk{R$+wdP~bvoK$@oWC_*4CxamCse(AN>>a(} z7~zm?kfrqT6puhWw0Gqx&X3k|9ZOgC-L&Vz7u$2vV4^*UD^qpP(2}Zt4xGAwq@Z7m zY(SZ<(!W^=i#lb-R=z4A@hHgG7iBr$DVVMre`*)GMQ*A@)u5PrUCF_iEO;+QI2sN} zISuj~gH8x%F^sojKAD~_*E?-(a@^{o(TvZ*$-Vrgp64qLyiOi+?7#nD8QF_gpQyeJ zvSS1`9ldhiz&gq=Af@~Lm+N7scihL>uZ#U zGV;CJ@gnVv@OxBINDsy(F(1STH(+kE!dI$#)99l{i{HXmMV$|2OPiV#3fdK?mYRB7_t@NvVRMviWHcDB z^2rRoWJF;Q7>&cz)mvw0ZMGWe6GWq<87WOO_v6z4r6f3BQz!eme zO_V0_btPBsr8XnWzU45$Iimm(T>@b^hy_KRE+i+W=&29OpAnGnse7qp&orKnet5AD zwdD^h`&+MHs~I|)PgQGI$mjmDo;0Gijk=glO1@xxP)x+l&(J^0Ng*dewo!j!iv&op z-T=R%=g+6wyId#ZRUeut9q5=>{txzZdd!NEjG()KWP|uq-?2#xNC`ETS%kCl?6BMX ztOP-s&D^4X34>3irU(*MklZFhCKX)=d=p7WlsC+{en zdkB}3kE{ecD=o=E;1y`J#&aZ$GP44<&Eu82aYN&8f&yZKSW2?)Te|ny&MtDZJE+V| zCn7ZRq8_9ZBRL5apG?@LK%P;&Lb6z10{hA~@-J`^okL&*WU*;A*I`yUoid2<^O8yK zps3z}{Z@v2f#O;I=Z3iiNn8;*y@ree_acw^Wxt_@n~FL#>lDVdFdz zx^86ls?DWhGJ(Q9xaRG1aUdXdvzXigaZs2Me0cRkRVW$7r)nxYM|fFDg0;0;cV>+A zYLDM^!jzV0fj~H@EI|MY^@d4;RB`b-L4|+r_~zM8si(%r?N^#`*oesw zv%g-LPI6&PCoReO{;V}r{1P;C!m9NNFaYYfuDS%C5O?AWG&GFJ{Uq6;l+~R&RO&bL zL1w>?f4alNiRyk|;diLlWYF1W;x#1D%8)4&==f0sklQPeojna{P0L65) zsiCF>M`FMMV5B91c=>}(Hi0~v`yi_~F(&X#*D|s|TY^{$Bud*2l5E&mU?aZcFEh_$ z^kS!v`8WCr!MWaBD&{mP5QYv8@T7hdkiS6ssrxLFuPb4=8r{y5p0IK`IX3XAr2Tly z;omcAR~YzBcmDS(jl4#K^;9*UogR88RaQ*4fYcjWv2wbjJq1Tu?WMy>ol>S@Gp{qk z{@}lE#8+PePb>0{Yyq*RSBY^T3zfGqLwsEI^2eODyhsg74rA`JH;};Re9P8e`e1I%Pi}hqJkguO%>GT)POpWeVi>JPG3!W?o_~fhn*ym5hPJL(%+kz62{vYr+HCVoJUZ zoUh|i)HJnJrT+Glj?(W-+GW3+@~*&g302N>>aqmI#K{IDO7~oPe&;S`n^IQ9t2|0A zX{zq#emNZOg*r#*8ux)Ib6fb$k>l$)8sQ|;R)S?7GE>)q*il!~kVjqu2gIekJ(6oJ z9@Pz6Azc#TxWSdMt1cCAUfZF+Qgtjc$6f+c)MHM(!D+|;ibym*`p?NKZY(6%K;x;_ zOtRPk4{gq08N0b86*NvUjP?4X?HD3=H5}>3VohEF4;#c6zY97)=j6E|7nY^QORbx7 zUpqHj?nJol*G>|~Wr!oq1@tuzBE$p41}f_XU?dbUhBF?El3mfqMXOHi9l_@5_kQs#km!&AH;j5*{*S;Y)oU3; z3od(@RUVZ5^>u?h@Dsw-JVigt1fIiP_xe6R>zHUMKzabw?%g9ZI|C zmFap zeRnSG?V_2^=`XroR>um3ab6PGg6MeB-xf&_lZ#|iT8q(h@yK@p52GVC0*_<3uke;2 zSYZo^1)kB{pC-7ubJ1O$4<;5a52 z3my1kK6GI?L?Mb0ly}j`wZ-{L821eJ2sBQZcX6Dx_D`%BYEBnSSl-ny-87yBA3d&P z&Qs3OVj==vHrKsa!DV>rp@I&vUrx{2aXfMqWFx&ry$&P@UIKML2}9THN`dpBn@Lp9 zkVehR#s`&$*S`whMZHiAh-eJ)IF(BL(a4Fq&m>1dXxmT*(9^P|u+u&N+%a8=QTV_2 zjXm_J*Q4&$5hWut!}0U<+Du2BNH^N)Q+-HQ4zdJ`DB`t30uL~B9X3cQGN}0aOAweV zN+qozTdb>@DJ?Q#OBUd$Zr!Zup0_Xh@0i`=>dZa%#qr&h$k#5jn|rfKcmM=8Ba|co zdGbzqeg`TFiSfj zD5L|092d_(Y~*VA3U}5KMi}Ha^{R+ifH+e~GPfQ?hZ4n+eIT2#sb2^@m^bo+%D;)N zQZHEr7r_T!BhQ6%yIs0L?N6Ru{xtI+<}m9Tr=*x;@mw0B`EPM@{*tV{Y5df;>AgA6 z*he|B&!wxi?h2w=S?Mp6eoL%M{yig)^^wnc_FNjQtx+7B=aKO~=}tmy;%LgTtmgbc zj@t|AYRwb*Z_^JZ>Yb6swI%qa9boR@WT0641t&4c# z=VIYKrX)2Z!RO4)GhY(h)9YDJ3pxHB(qOHJoORicQ_K_RCLBymNqv$%z~%^0uKlja zHt(NwkEBoWcM@b%R%hDgrExxW;9BFjf}HWx=ZPm1Jd%pil$kRePWVe{u+Ft23fHOJCanFWSn*)dqKfM4zj(h)^sX#&oxVzNw!J~OL>ni;k!7i-=O&0 z;y?51GDeb5CsidMNH=3@a(;h-HnTXQKX+=nYlZ) zD%ml0He)uok;mE6Ee%l*=DIS2GSbsx)625rST>xi-O@Fhfkn;vPqMFPFf$%!d9luM zf;s9U=^Bkcd4I5cvr99pvn+E>*?3%sMA8tAoT=wCNx{UJd>O8#KdnnZkF77Q* zW>#j-W*B6zX3cOq(a*(box?f6?8w-dKASO_~ObIxx zbm>QaLY`tyV%CZ5pxhq|(Dj`qxZ(#zdkR`}Y_rO;vY6pGK{rJr4O6?p`!i3OS)MJ( z@y=s$IUQ4b2N+rsuflHs|YeI6cxZ)n>jp ze^ah9bAaiPzk?%1k@~fwE9_|20CP51oPU%T&k5^AI~xq#!@1XUFXZpwF*xVxBGsZu zb{^|oZfM>!b{dD#Ck@k>SA37Xl{L*=%~CAz=Hcb;=#z%34s&Rz8IZ1@TfkFh|5$K{qrhn!z&AD&4zL## zxUv&?-*VjE;x~UOs^|X9c4a@r;m{dxr5jW}@chxjls(MF3+aC=U8`JDoXq#)YI2wI z=W$lNlWv&XFX-a^%T3^!atiTL<(DEG-Z{=6T&F_Z-^4ro=>`4_N0Xb(|CY015ba$A zo!oic8$1in1^Q#L;9u@FjyEKr+4#Y7IBRh;?@^$%mOsVLWN+p66mo*4_(3k;g40{z&S~az&f&94PvI%fL;+#% z;Jqv2%%Eg$Gp^W+tIv<(M18>H%ETQ_;Sacc$g67~q-#}%is#@e&v6=gIYk_`QIy1! z8%PQl$=2jvEaV&*#dRk02|KM|ioJ`!hI4lmuX?}W9Or34CjJMvW;TZR#2{Tfca8;~ zY!v6mG2BXF;WO?5P(`n=#!t*=IQ|0)KqUN7I)FH>8;P*tidIH^bnSamsXuYOIL zm{HrWXuJU0+5}yN{V(_msl0`1mZ;p-9JiKEgTN{m?Y*I?E2+zWCsJhEkdZzElZwL9jTiGR@koG1J*;V?^A!Blf!{e`2KD1qZL zE?e`3Gok=v-DJytLW*XhrktmZ#;BBHdYS4+@C{9nfb)l`#2tn`(Q(>LW0?ji8K~K#pXxmJv&PfnhPZu39LnAe2 z=xnA7vwmbS=1et2`MVj|zQMm!y#_f%eHG5jq-&u2pxEs>q1+lX!_F>r3A*A zM7id=Nv%F=UceoCDKk{z^caXX?ZgsQ8UDSz7aBq7Mp)=3wldXtDb@1fibz!esV#Jq zTKn@2R0f||!VIGkBsO+hd-Za~4tc!tusV zS+Fclk*T&LGb`N$n?wxgp@@;YC>8L*(N^gGuzI+n6pr4NAo0Uix{2T_LlvetCihpC zs$rc!S?hvr)@t3=x#0AMG6gn7Rs6Z(^xJQLFkQm0dZ4Ww{aJdf#_$-@*StldT% zv>VP9C@(`UC8~b()du6+VJa@lr-}y3rO9ouPA9M}Ibm6n)a__@8;B%POj5Ujt{ADI zXVz_@8htnk%4}bVZ42Fb!u6*xMJo_MxlXhNzYXvtP0FcspJ|g*J7DazGt~v~qTVX( zhD+O_li}O~IBR%Os%wW~`w3EPe&uj@uGG^OjBOQ5|8Lj;%CvesA5iWPpnQU%Jc; z_aaJGmEt3fLj6$_NIf0U&PI5GPJ$>C1#^jz#zTMZI_Q2gl?afhcSqfCChf#Pl62HX zm^JYQd?LN-sGDM5%`fB7;}}O>I9i4C*ugdewh(y>?gW=eO^)b0QS{`~cq5wPghD$p zmn(yl-OUPXwf%$u!H%ptf!noO5gkL{<2vcW%~lH4802Ut-4wH0F+y-72WO18Nr>m6 zS4*5Ro{@He0P4S;!R2%jkh=@Gd?ln)x{EHtBtmed1^{Lif~ycj13T-cnAC~`X+vk- zH2m=%J@2gBYg#En-^DJv-^`i?1Tyrs3kGQxL>`k4cf}xq7#k~82H0$?*u=LZi>_d4 zu=Y70KrsN#*&LuBN4n~MGp`Vyvk7$k8PpAi4wHY@MHpj@^FQmR8pCmSbJOiLxhoE) z1~>4yNmxn!y8)Oky3qyz=Iulq0c0<`p@#_Ykxrw!V-Q!tn$2764s-zEe)Jh=i*!gf zp0}gP?hs}*?*PZ_O1oI0R!rl=(b}R1TDxF>s^)2S540BfGHxYRF?18}!h`dle!)Da zW1bL75`)iRTrB_jUm(~80*39@6HB^DaN;=5j?#Og`+g`q;V=snuwD2;AJJk!FI||0 z3ty`4i5+-DFH}VceYiNbGd^ckE3tL#Kp-@-H>%R1oFCcl%lAgrD^wj;=h8=3bw-Fm z0d7B}4>Yv``$RLDYTRi@AJ~mGpQvi47!9~J_rNaD4x6SAb~?E4Ssv&qlncVH-i{7= zprFAQCCkiazTckt--ukdZJM+ zWSq+d&~;WdSZmF59F)V$3$pa*LpfK<^@1z|gnB08e}T5N5r!iifYyxo6=vtc@6ep! zz^w))i|71N!$A69p+z_NaxC72e(2ap>%v>}m_unlbnMB;as9}sKWO4%N#PU;(6XAp ztXak;bFe@9T_Ai!PguY915kP^y6~Pn>JkPROrwHn?HLA77oYQ30M~&~@_sOdwe-h8 z%y_WY69W#U>#VR+=!p$KjXb^Kr`*ICO{qE*tDEl)FXpbzz77+r6y1}F$1i~cDD3>k$#K8tG`Y~fI1q@RQ=Of6-2UAMYhC>Nq zA2WSWF7jv%9dtmH5qWNG3^J0k_a)2+T(UJ4yp! zwh5lgjjj(tb-KY?J^cV0X{%waxqhH@gA;oUz${Rd2u3t~D7-?V*p6r@jIWx1Vu<2~ zVj#vqI!zb`UY>(RXm{zb|KoiD84X9TuLMu@8VS&1fso6E^J}ScI3_+&moo6DgEmY4;O&R4jlzllok?IjRJ8JeHaDe2Kc@SqcO`0kZc>Rn`UH3Mgia}_|-R{})yQ<#ATBU&7We%5M@Dr>`ZTg(hIp`@wce4uDld10zfVQLgq z855=RFfm$NDVe4FVTReeR~FCJ#TywVRep^J1~p$3b!3W37B4YK8cX$h2}ZZ0fE4T> znBK+|6hW7wvoXSCu&UOnU?E8BMzN_aB*#+W^x1x}%+NAe!(b@pU}lF=!k(x@ z-s3`cYtaf>iYf!aS>jqmkV#roWCt%0hC?Ff*CJjl=NFKN;-uo83X9P#6On57lZn}2RU$OdW4R@|#k5O-Y30P_Dw2^zG*de=T8~C?K)jO%%e<7>M`x@@qX^*z zvV)njDN4k{2U;+$R3}T8Jykr?P`ez^)Qa9JwcHGu2QUkA5SAJtJ5kGPaH3V6gH^e& zo`Q6K6}ga0E{YR1{>m^#8yZf_S+NgSjv}^1x`Lv$A8MT-zoQ!JlZUOkR2`1s;12aptnF?5r^^psHp(-k2Lk@-$UV!{v$Sk z{tGgbrSe>bLQQ)%Ac17(XCKjFCOT|Y2!bcv3gr%YE2KpfR|taX;$4*&QVJg|_;C;* zhdqx|lmewa%R`(bkYELL;(@GG7SE)-6qr^6#XyylVyRqN&uW&=Ybca$xsCs^b#rq$x3L8u`EM6T!GcwDFaD0Utqv|l=~s=GidH|g{|~#aW5=jG(#kc ztH?o~EGtu((jhrGzl#Ob$yzCKI%cncaPErDv_n2gj)YJ{ixiM(lG+K$uLn*?lc-jK zakG(S>SV`|!NTQsQ({~ZyX-OK<5E>1tx{r`Cy2&|E55)`-RLF|t*bGeY?wnJGlzbp zn~0+VFD#sw5}KAr7=~Fgub2XBH=-v5OAZhsRqULuCk<6Was3U)X*I|U2}PW1u@0RS zm5hl-6*!-$xhy{~t&>#{hM1@Zrk?XxDrHMyaY%YffoWC7O;J984Q|FMoRJ2M?$9{F z29>gMr8PwY(K?rFr7T6}y@0Ld0S$VIF_2`+UMS&0+i~dSqsBuKDV5w|h{C4qqX}Qvdmh))ShbvR`z{$fDjC_S5 zhT|wAS@r;J;;FZQP88}o*;MrEuSEWqEua%0buV-x1EzrPGZI&**Gb9L;-?Bk>AoUJ z0#)y%T|rW#3?P|^Zf#ZLq@9bV7JpIL&>J9HSI~KB|KfYn1q6c#)MAF-stjpOQ3iNJ zFPj-AQ=Kh8DAhrhh_Sx`gCiFv-748@nod(TqMMHz9w#S$@&?w;o{ea<15(J4+T&~; zzTJ8g8XeVGD!io`5R?nWZUQrh)oOX9w1=z>+0apjaN+9}_kdthaM%pQWzAB9oN6Ga zWFT6*@Lo!L_{18<+~1qgE5~Ka`{Q7LInLp`Zvn|8%`t=c!BjuoM<&ELaLx3^#@Gpp`689wD(y7G{WSKN% z2gK7L)GHPi*A!*SN>rrW0r7m{mdaNYO(~iwGop7O!J(BG?p9V6XUe=)2)=@M>ViQO z1ENty#I3&pTcQPN$1EFv7y(D%o8XIqk-& zUxW~*cv0k4bWm!milWrrx(V3QaczSeADt|S>UN{maBhcuGqfz5`RHHv;LI;LNCnpFs75I}DY2BiF197R{a8?(x67_c z9v5~k_EI7mP1>&uZsVXiFMV9NzHln$fvD^}aF`on0tqk4ke($YaytO2EaTL;Mz1OA zA;WP$tpcibispgrCQt?qx^V!L`Tu;qlfI@P`n3}6(!lDN;!#B<=qiZvfx;D8HUxaL zNGWrt$Ca3l3va2oS@cvgPTC*0pTiGgI?u76zApZT>6~TL(Hz8dnh?g#lo=!XNTCl0 zA(w$-fwG%)OmUseo`Mbm(TsaUZ#c&X=(&U;kYZxbwU>p#Df~DDBXWlWvxk*A(6qzQ zJa#bbhfNHjSjAx&QIgtHQ3d}13vW{eml&j#B3PS=fC?1zfWd`Gf69P|F2!1$tOD~A z!9}^bcplV+>7vUK2&MpY?q9qYg28R}vLoo{m2g9OUiza&87~8agV6r;PTEZx1N-lJ z6rocC-IEqU4Vo#P)*Xf9YGJXE2+SrBc61-8Hi=@B@*tuNGkKy4F}3e8td*U%fs$q8 zqz>{*RS?OJf$XignV4sq32%=jeR~WXu%m6W|G(b`9*29eHe6*QE+Fl3NX7-l;ffc^ zW%QL5*-mSQh}eiGpD=9KCl%+V$ubGyWM4eG*fO(JWUeaSDDH zIvINs()UErumjOxB?9rIKpL_B_Ai$xyEr_g4luz)7Xd%-Ek z(*+<}2MD-bz>Vu!wxPRMW8`L`0as#iXaim{stwClk8(3%-@1*mRjJxb$s=^{NBwIs zmr~rgvI{a7+E9ZbqHwjqD=ZZO!)?w2x`F#ksEXHl zh$#j)t1Fa->xMj(t#s-exXWQT)%a20P^)asR0_c9ej*LMfI0ghm3S;)MTme@7toqr zzASCoEOi&KbW%i`YIzJURpKe=Z!|DM11DTLU={xS8w63>yGYfBV;utM$KMcZk~YH- zts=IjX?18}5A)lB{TBOgMIBn4G2~CBvi`WEvbl&BIQmfWNEn$0#RGwxTsPHnTofso z=uTY(TQiZ;c(i1H&X-U&)vUlIGubY>>=LwPx>!Nk@?$Nj-DO}922_wAGO!iM7J6RB zD2${R*1rIec_u@g5vC$*vqzL|LH8J<0ZAsizFCF1XV4WODiK`FM0g)S5md|&?go`H z!{t!{y#k{30s&XY2>0Vzb~xrL#vP2;5Rc`T}Jcs*ufji|g#VbJ?BR#q95Fo1AKV0jH?oZmu=`x8zBW}}S6kv(S!!;W8d&Cp#v z;)Ufb-uUS{$V*XehU+Hywj`8sSuzEeMp|Vk)m{fPhjHB&gG4Na+-^W=169eg{dj2c znxZKE2KMko#1k3PNpiTfTQ|_%OoOYeXYohBn)?ki;OOsgqqsUY6#|D!kv=h!Aoy#UG!q)p zk0v#MBn2U92?EX<7F7S$fCbJ32@6|s&%~4IZ8SQn8IGi&3X5YyQMa);%aEzxLzciE zrc^S-4n&;ZQe)%<{mAwX5W_hSg-kkA=87f@8KQv4Rh>)?wZT~^Lqxz2J%%&0#Z^|9 zyFjoE&kv^x4N!qJh6sT6J}{&n3#c9lr24o!hH^^SlJ&g@&LRXY@(MrbQ2?#KXCNuT zSw)$`TLtDH-GdzcaKGTM+{{+h?;kAFVWg%`@XMj3_y?<+4fS@y`3NrP-?QrbaAkft zOjt(a?xPwfPPq1qR3Ty7dLO+xA%$WLz=)e!`3u)THA*SFW}W%~65-3B~ChXF9oR?0TaMQ(h8IV`}X z;|n~Yh@-Elwn~Eg-Avwiq%rv^inWFr-^KOxE)?Mmg5U-F!#O9B)ibPOJ24T9R*wUw zbczK6hdOwxf>m^57rw`yVHImdclhse`0prkc#b~VrDde*GCX!ND?Wm|Z-U=Vrwb^; zZg1d8hhd*|e_>eBa=2Ych|*txx)0v7v_X2CNDZvm6Yo&IUw ztUly5m`TB5z*6}XWgpu98pD<0{;TWUdpc>bi@&`DPkZ(?}5Vz+qbB$R4tXilP*OBKnZU#m_1IPlHrjMfuCVzZ=^i;q-r@%gIwRCIm-j= zkx)5M+B=BePWu|6j5i4UsGcFtAh)=OL_H3E*yBCcq9tltgtP{y8#(V`{S`1eCETn( zOWGa*(<+X$RNOA^hDLFO-&2{?8hR@ID%o44mZOpK14v>tX7atrbbMq<^bRD*?vwFe ztbg$_xf6}k0pWw!cdd%r6c0z{y9J2WGu1L_CxpaxGFV=-4kNpx+j&J}ik%dQ3a09T zd7=DPbgXbn(MLJNw^xtgI!f!WoL6L4I0x-;$kVzJ0oyBKxZu=$IT%L(dRFaw1j>XFPC@~naNWq z^eYhTz{5k*Nzx5j)Q+#1_gd`>W&dJJ$&{iPIfQ8bADD7e*-AeZhDq#Y(4|=n6R9e} zP*aK?$e`+n874!uNV;6|RHBq&%d>9+CfjhH5h*QW>?{JNRXq-EN^p$uSRO-Xo3PFz z-wIC*y`f=P=byiUqyZ7BPF5w;;)vsqZ_sjfi0Xi(0orr}1c*r@5!RHpqzzu*bs^vd zp*QkXTNb4kd`Ga&c1I**I170E9bK?fJC^KYZyweRLttk|e)4*pc0jj6;W6#;%%(s2 z(FYV;OGO19UNpgFVCS6pLl;JP@NW`w(4;Gj^r3j+wF-ys?&?i~ zVurruffu{m9jMr^54EzvX=(so1Nu{2&|1C1#qU&dgKwPAif0Uu``AmxYF1?L-6|*$ z52;*?^^+}BaNAPVGFpxTIJQ+a;Ep(m>Wx8K&n4oOpbjq2!vs7;2s81Dqvhe737BXn z)}f5IM)c4GJ=NpR*aCOKLrhT!#g#+~Jf;E#%i-KRyve|B_1;v^Zaa5qQZxlL&I}_) z;JuXsm!@l}#0*0iX@_%lcwJE|D$Oy%U~L@UmT|cBm}YLMRpDWmDZ4kVVAV$26pcNG z8Avu37$%g$)$~bp5dxx27iAg5mwTZ1N z60c1zv0@PVjKteG7wTyR(xcduY_TC`qF}WQyHy4C)I`yJD}5*?Y=o^dlm=OYP~_d! z=OOZ96!6xIU7x_5Ut8rZGH2c=`rCh~tmU6A%NM8=-%K0%!&d$H)lp4p9XfJ|@;ha?ZqTf<78h_n=}t`Q{+ zKT+cVo0!lM&D=18j%iP6M}4??IUY;EYa2TPUMU!!4b5P16z)M`2nSl=avt(&=cEtE z^=3G4Q#s#B-_+YEoaT(t4>1YXTGJK)#wSF2Fh=idB$>W89w+F1P%d=&VYJQ3rm zzNOqY5NK-(Vjq86kB^D7HkM8UFxH4j#@Tir#!IEglb~v2anKoj{sA6td_UQ0AY-9>QllMhemo zHa*X87icyh6B0U*5Ty4p3lZ<}&U6PLaIxeN3?N$QL6ZTPrHV2>m5PJ)gUqjr4ctAv z)e1&8@A-o`^PZp|Y@RGMb6`9WFt861qyjRz$1kGe6EJqNP{9G&JVEbmo+@tQz_IT{ z11X?ofXt(XKpyk0n5g$Q8-^jW=-otcaGsB*-jl$=dp;8E&7Y(nWJbbk&YVgBnmcP> zGiDx5!t8^EgM1ow2?2$%(2wgtkpL~u^E=hg@$gd}q917SP|&EasI%xgYRsQ&tTgX= zY9ERb|I>8DCaL#zl^Dzu;^$_O5P=1{Zw*0kS zxa%56T8x7Ef126qO&sl^EI*5Jsbs%=&bpq?m;o(XfhY9 zNDv%^qseP7Rb36!y2Gg6^T)w{Z*rIdzIKULnw@G)GJFaI-vx9SrUxE$zAy!> zWC=UfeKqD}^_zheXARbL%x|E%4z?m_4bYY=xd$pM%`W^Q%Wn{hjIUGmf>4@%!x$$p zhMBsVqrnkq^RL=n)t6Et&_>i4fePxnHv(;vg-Pn!YF~O2fi|DT*5uF@R$#2{#FXz(1#2t0$r=dNc^ZaU#OG^lDPkJf_Z3EJY&cI+ zOhbcRVzs6kv%i8Gvj9%iB$Lf_fQ$J5G{!WJfx&_e=S}Mv_!)ZUMkl93y%s^e(&z`n zW(kpe4h@OKkU8Qa9uxRI61tqh8`Hi>=yEVL6_U_JLZrQ6aU@XR8Q>{RTf+O&{29>N zWWkt90GNk}#sakZ-x<*LBLZ5vMghuUmOX<()>`0HQScaW4N(SH(RL=B!BsJhCd`B# zJ8MCjH&gG+T+11JjU34+T0g|pQG|+)hz4UlVBmj5V-8uuJ-&brMT7BSFlIFT6b-&S zwLOGX`gIog(gR2YfM4iLoRK>#E#aDif)&FV+ch`HqVGiMy^XKbJjNswg zE;P(72p>~V!;}{O-<0q*3L&EeRD>8DUIN52OoT64$skWH#y*$;VtgC%HNs=CME!D; z6JiK$PsCI_@sGRcX(G5I!IRt;VVc2$BSkZyx0p&C0Mn}?h;A)H^I>GS7z^X6O=b%d zwip7874aGbNRt9BCbSsyMU8n9#=MFn7ko{2VL8&1K;fwkr>Z2(#gjg>Pb&3KZlO;~ z*1tDOtBhHqUuo zc%Ba-Z8~(>Q~Mq}!W~v0$ivlk%z#XL2+Sh@f+sx)r&^o=$|F!7XR2dhs#wAgBdaw4 zuZod;76q(9`$%5K)7mv?-+^s7#{ijZ$NumYm1e!Mx5U$+wP^B0WJ9K`1#kDzb~gjE zprWrBkSbOo#|`XuS^1#4=S0WRSHMP!=GQcx?_HUk8zc=-WE1-!QcE$ws?W)^1rgXq-V) zo^9y*4f~`~&-EB#m>5p+>-9dY>E`ulng&kpqXq<>a$pf@B+G%W7BIcMnqwHuk!*6& z)Lith49eA8wKfW`oTAVVHwCRi-J%^=)dnpJr?wi*E*5JR1OUt*5hzE4UNmAdRRd)f zD`xQKWW>RUKZ^%>tm!b$ux5Z(05a^!`#DgaH|&UdP@3K2u?LVRk4C+*`0yzSJS_h+ zyiX2o<1yqg==fs>5NxB1fUzA#IIbB2dJMs$kbo&VQawJV+XV=+y=bV(p$Q^d`9oT{ z3`o;D(rNMkRMJF?ehkzjw4l~w_5NTe4O^3gK*2ZxHL}VyZ3ua8L}ePY*MyA-a7ciV z|JsPkBVh9hDj~z()O8bp5YdsM06;`=N}5fE^@Xr*05U7kZilJcZ3dkqJk=xs&`jg{cP=(W!mQOMJ_)}d=$!Z@;X%v7DJQ(JewGVT7 z!lZiwkjZB-(S%B-tb;4y+?*+;0{v>>F3Kyw+*L6CrUC;x)298PL&JaexA;=01E9y> z!yJHv3a3_;1}?_3k27VmPg>>iO8rA4jKAp+`t;X^SKdFQ$5X_#%CS{?4_1+S1XFUR zH%D6L-Rmg2#t?Jyh0FA;+;UW3Z2}XHKZ*VdXv;}(;z<#w41>tn$C@tTgULZ`ZK}ah zIE||YKD=^Wwcf=T#Vx1NsDL8QfCo=4ws`=M(3La#<;*>gKMQ?u#tvsq>(63^i0N(( zkS6cpe0~50wKS(8=g=yimY)NOK`ScGfmf{Wd-g?>KD7qjK!jNf62s>DXDx(n2*Mu$ zg2S*Tm-Fb)Sv!oTokxGEq(B)84b!}O9?a*E%>}UeS@fr%3!r==#?pEKP-2AJH5bsI zKNL~0f_^0$7A5%edP9@c?)7c}1Gq5&|cX$KimofHv7Nh@u8Dd(*yYbev|1!Kp2|#qCyNnoy zMb_x3?-jtwh;1N^1%S=A3*NjVm0W>;IU=0pdeB1#CJX;*BFW_{z#MS_BB^NrEv||Z zZWHHBbQRIvRWX2z;2_*>M?3G zMh&4K44oyEFed%30UazfAm(3w4d~dGpsWID#8-y+>pg>=wFg^z*0K@kqEO=?)6wKdcD0BFJhgax??aY$_ zn8#yhhSa66P@4t6Tn8lLMf73)8Ys4R1-wQB4d%Fp0VmM%=xZ=!4!6?;OiQFY_zkEp z3cV@i4N#v&Onnbfh-lH(>o+at_sd&@*`?8(x9I61tauZEmPqiQx1c`3+Bv-gWZ2$+ z1B9()7!|*RTzXR-KFoZr-$O3`6!0Ewq`{460)W>z{@x(kK_B#|O%R@bZ`6OagirbW z9ks)#e{;)K==sM26B}(hWetN&@*< zg+n9D8!EVH#pK38=H}vA?me$4YVeC{E=xnqJB$pAgc!4!OM2Z)ivO)-)q;)WcO01dDMVzUbj zyedXxO)Sg+h8rTbQ4EaN9sxnR83s*;hE%mwCnLG|%)qM%I~=LMIlweD%Av&o&37TH zgcsatj=>1iGNxyYA{DcBBsU9yIS75SD4K!hu!V0H$2PV8<5kaE`$m3<*UywE}F8NEY-X0GsJCdl$e?WuJkM7ntAEVEV4(}JU0MO`AY2DFl7YVPleR<* z%mV05^#I{tyKqRA+qK4U?|B<;5e2n2Oe}&OiR1un-b1L?oaLy7k@%uNTlxVKj2(bc zhS&fkun|bh0V3LKfO=7d4I0LZ6&ynJ_kf{mXF=V&je(lwyYT=mdI)_r{qRRSC2bl9 zTHNE;t4C^5=^-oh5dKyFj)Ml5wvFsGV-ij?uvXLCHV&|SC|GGmY9KmgTXZbpY~Y8l zw8hw6xKC<~*QOoNziS?-Y-n6Np!;zhao|GP3@tOH=_i3U2w@R@XB7CYcBcQnw$RY` z*rrl#p-AuHq{|sl!e`JM0A|hHS}4BOH=dvtpQ zn+|>hg@NWc^va>{3~WiMd^(`lT^J0~Sk?i(#)@t@pDJhQt2mlNTJ;ua>=VswIeYzt zF}!gEHs>dd(SU`Ir!7CBw-W5Qc*@Ga4p7}3>csp<2K2#~A{gi^EZ~w!1`tVrVYtf< z7%oj42r0Gd2r1b@B4YuduMCJ`T}O~+VHWV*r#ga#-Yo|Y%?#E6h8Oj9L>K;AUzlmC zBf4NoemMXnMQ{Rd9l>lo0<4}+K&7#BiMdXVgONidBeUBAB)o|=-DkDESs3ix2@TAV zg-3J(%8;?k8R`i#(@P9h!1`$Ij6STjEHxkJ+~|XtDbu-e2wW8EPN5C~ODcUwjcK$1 zsrtIWCuXsIbQyyTnd)9Z7(1BWxPXaNF`9aI#>CT*1o%@tKs3N+y|pvQlHqvn17&d8 zow@)ZG>l+?IU33UAf$t8U+w~Gf5h&sTpNcVL`~Kna5nx^cnjJ?} zw*94XJv%0#-aw>c&$`|loqa~YZ`-GFIcu5M$I#+*pO%h{JsRI51lD^rvPjsoZ{u#az#;7t z(CbO|fycs!Etl^YFjhdRV}OOJBW!58hFzEu?EUcfsOB4 zMAT*+M1-EkKQCe7w?j8t3r89j%5i992 z8J~EXj}Hr||C|i1%z-&Qo{Y{?S-|KTjOH+Q-H4Pf9f(7-K4PJZ z&tMB*KqfO=#uzb^ja>Q1%*LUnaC?Vlx1c}Gh8f}oWh@5i&CWKu#WfDbdF^}Vx@X71 zU0=lcGw>pVdn1B@GrY~<6QBY9r#TRM7H()l=b(#=EVwUZD3=A$AK0=*wKgFy3sK0rA)&a`Z0Wyq1;b@rC7tQv<5llH1S6^qngw&2KS>LkkRR_Oa#j>q3;$ zC~={|5j;VOHTgLKeR#sPMkhc$nC);3@Q1?O1OS!9n%F0z-&C5Eh&EuqfE97YnAo@v ziT!7>a`mFd2lx;56rI$#4+kva)FByTIa4V6c+v*;39qb8ZVWPx>MX9+?B4VFmZe2h zzvhsr*%9-)Pq*^E*2?!upPJa6vo-4#OLu6lYs~ue-x1z0Cu`y5nFD*$;=7*^Ybab;4(x1%C7?d1+%Ox8LPg^4|#`&u9Et zI3PUo=fu`24)gd?UpsVrwX%BqpW~&CIsUYJX``cgRk20(O$A+C+St+jPO*FTVJW=^ zoZeL2F>94%-QmmcZg)?ZJUO8@wJte7T-D?Be;+QI?Z}gM%=+Jk@dxZ*AN{#+=#%-q zQvX`Ie(Jhj{@-U_dA##?`IoGb`E`3cKA+X4Xp-52@u}lemqw24`~JthtDATIE}xnu z%gxw*_pzI^*ChGEL#ely+RaG!dSiU&T5;Jkg?Dyr?p4Z6ZFDgAR-Rq=WIb(61#<_K z>(_nCreh4=s`@Q^+d8@nI9;k4o%1})V~gX>;xWi8x2VyE4~XVphG@&W6IteLIpaN(Gd znXg~$!DTJhcDwhnSuawTtnyEc@?U5__r*rkR^$|9*!!s*YB&D);$1dNv(#Akwa}p4FJp z&SSo|x%y+ze(IMuTeGkxSbxN=--MTO7n7FHdl3-R`PrA|E0fCSptdVlRdY{w*G)P> zGpBQMWjr@}wo8vMWmkrm52UquAGj5#{q#+4A0{}?-Ics8e#WSpPF9~+qwPSF=8fQQ zQ*0WP{Hbzw9wPXRH1IZs!t%P1kOr2|D3|2D!_Q~{9W_^ZHSfE4pmy%p4!!PADxJGH zsW9e|Uyeh8zUY#6kGXPW{_%|;&!_%(z1NRPx8@#8(#{$% ziImUkQt6F^{z6^)Ps-LsWBz&x-_&Zr!tgJ1GZP%9-urc}jrmK5+Mmn*RQ_EQx1;CH zT=U)onkFBddo>|`>i1t~+Z=eY{+uytUl(25k#n=bJb%FX@NMz46Q4!2^%~G>?DOYm z?RMQ%aK)Q@uy*b`~eQ*6&fjNfQmY+P|J4jvA>(y`iW0q#Gmux7TyiZ>ixR~_pj!3{m!S# zud+*fCf}`Zea5F_1kGz)P#4;*_j8NCp1eFgVCP(AF8+_1-M!5=>wM=$+?ZFt@JQHb z)M}o*syY4FEqO1pU5UYN$(xGFYbD0NC0{`k7%C8dtw#w!nZA&LlRQA_^JRC6)A#t_ zdt_5Hv&;NL}^&k50bXh_%YOjHlosY{-zWB3u@#~`15*t`{LiDK zt+yshrc3)&TzcTr-o^iZbem+GB}2o$c0c~VEqD7L{d>yjyTAR*W_c`m zle{~ms@w4YO}@MD$j~j#g}0@>_a7s>)nKqq;dJs?4Q*??A)kT(n4ZkvSwss~V=edQ zB^1p+pn3AFLEp>u{&0YSE_Re6G0RfbWyaj#gu4#@tq>^ zuiPH|IDOl!s@=w`dE=$3O3f2*$8%#mW>=+LS}Y58c01WT5Vbbi*?H6H;c8gfF|j(g zs#uwhO+^&@3^!!$&j=nYq5w9)~KQk8-XId=+~kB`k5-xQSh7e|Kp3 z?a&EcmU~FH?(m;4{9U}qImgaG?Y6+SuCj0Ox6U5i$hXgPP}EfY^zwttfpNjHO)1hu zi@;f3Ous$9x%^-|esb<}d1F<;%aNVCk8c%com!rlGxlNU(M^swzf_*&GIJ{x`<#!2 zzjE!;VSH1pZ)(3ppD~YI%$f$@v^@BbYo9ll-ho3iFJ7NJmuxaHoe>!Dlal&mU}K!c z_sd&HCyrlvyQpiop!~Stl)3ZyQP(p@WBzhF3(N9=w!S1E+AoNHFWGwOpPP4~9%0<|osA z#%&j&T|qHN&EVGjzVN=_A%53v4LBFY`y0G?znbO`Gu#G_FPpVzk<*+mBNR@bzo>7V zIrLrZTC@L+H#Lf|LO?8*|Z(YX*Zj8Q?*eNb!_&TTV|Iw`q)J91@a6_G|CGVSE zEezGI;w}xh?^N>Nvs>X+yEpz**p4o(fsX!D_<^IhYhdq-3c+>jwa}SW+T9zvQqQ%p ztj>ix&Bc?&Z%=k^2ndV1ny_Nd-~KV3{lCw-J^IL`O&1G)<;qUBf4iphUjbKV>`l+$vx!?DJx4Rwj+~gtoAK&@Zqch>a5@Kltyb zlHa;^`DLup%q5A_=V(Vvc5ZC)Zs>s8p^|iAXSFR=uZ3m(Qy5M6)aP!quP z&f@M3ZG~4g6F)@#++n@zP`M^9JTj1Toh~11nd9n zW)ggHmVcr!`_#}Ij%UC8bv^!I7u2@fs3KV={P!&W#|A3Pge&^Mt)>f^kmm@#tdL#; zm7c^m7jD>We%|_%kNeV~NwdNdkH)z9-Ex@!iMw{Lau2^tVzcE&?d^|g?)sqgS?v?s z#F+TScg+11bnSVir_j1+!j_-TzeH_)kapIo1W#;)5gi*oIbZv|GFrG>*wm8(@X>{s78XU$Z^o{W!`l(~i z=T6rTRvs6Q6z$r4^IY%7PTls8kDfIu;b_dMp<^7se4c*&R%N=-nnKrMu+Abj+@y6- zuhrsr2^9h|anZJ>9qSrh;J;ny0;o(9idNGL0O@{3i$uSgjCWes1LOV|JvqU8&Z3c{ zoUi{EcysQdDD4}`MAX{8OLtvnsCAlCI5O7Rtf}|8cTlJN<@494<8xfs? zw&F;cb2me+hjxSHl5nK@V175e=iMDjOQ-q4khl=8vAb`X;$^kH7~rWeM}=t{nBjW#6~TTYnzjPtE$``8VE*yQO^X%^y4c>=WX$uRBxz#7#UO#p|ICkXB0Sl+i^$m!2 zUDNE{V1BsWMzOFfcj-j&<3@w>&?@a)7~%h%PbgkKacT(I z9A&!DGCp_Av96Q;xBqtP;gF3s68tpIdIr*`#FtjYJ-Qgh+y*AE^xVJzVOHv7ZSRHwi7H5bau+?6NuH*8KlAMs^! zpEjYLP+Jx2I(%!VrpCvA7wvwk{E)wTQx6)I2MZlYC-Z4$9z?Z{z}QMaW^t;M`5wgO zLF@XfjS9-d>8BTcSkZm&gblOXCZ)~&=D)Ga!2ecX`Mx((?OO0oh^$%seqpz;39Dwm zTYPKool%oq4a8~q(MESz%plR-ljKN&bnB&o*i^>xvA^UrArm44Y9=s&1&8wCD;&Sls$F)DL2$&W9V3F72H=#AX z$C=yTJ#c8XD9!szN+Sxu?LXq?yzvxO02R>X?I@;|1(5m3{BK310hE3+|L>y2y_t85 z+O8hyA9W@1Uh?+eiab-TB@gsRI&bzW=u7$N%1fCE9SZ%%WjwE2CliBCjT_T9Q5O zb-%7{djI?2c<|Pu0?CHWyPi}34N!)Rf)fQaaRc;rV}UCz+yK4RZorT306->sCI7&7 zoBANr^@C}u*@7cWHb+?w+R)zp1z)Y&cCj!fe|hQKD}77?2i=UgKEF@OrkS4y71#y5 z>{HXRbeAM1-)EcG<-SH%-lY-B`72YRXN~a*vLF5GRn7X+qY`PJ^`9RuX8hm=SVox7 z=TgL&{k|(Y$X@q4b6|ULkv=zn>soRv1cOKLJMuKF5R%(jRFgw97<8nlB8OH0O8=uc zF6a2h1GP85T=fW^JZW4VlkC`ZZG>_9tc1@g;BW{ailreB6X3rxNUgg1Y_NH0(;3@-xaa+3w1I$5LMZ)Ah=P zs@Pr0KPTD+kMAD#eb?1tdry=3`sIqSqj9gat};Asew$RD7&hUM`<3Rq^&b1;R0pyH z<=u|_^zwgQDuO&vo4jbv#L^xQe!RMNci+FNr`g+O0nSyQpRaYd#(zj<`fVd~gP zvwkdolN=eorO#hxb8dgByd=nSzf1a5bb0u-L)w`8(f1cmSh8TsUJtc-+?~${%f!dI zLnXrA5%)XUI|X<}7cG9hu6%|msVrc23ykznyhL-B`W>XLV(_izqpu6| ztDY@Bv2d$V!N>LE|BSloYnJNUIDK-$^JN9GjlOs7Za!ah^1{~g{2SRjwjRG+U^2$1 zV!B0?jHaeLf-*7Gqf5tRS3W?4v z%*nchw|juoJtR}JPVn2#-S~RR>(*~i=F{?S3wI*981~`Z**Sj&7tPDs#QB_!{}SR^ zJH>qdyyevkgGTRjKB~KUZpx0x;@`8vGp{@Uav*XjC^eWt4InRSxDgSAiFyTk>(o_!&uAmvC{K(9n&^^I2*DeAA8Z3=tQV;R_N zud&KHQJ|EA%gq2sl8YQ%>NJD1@Uvb3(?{?Q>mKLM+P(Q+AG`4Zon!bVmdi_~7yg=R z9s19*Lz4tr*O+r^*R?yHZI6uVGV4w9)a7n7{Q8@;zI=b(;YH$a*=9MWJKb-Gv~}?x z5iKM;{JuFVf4~x(whxz94b?u)E?KYmYwWG|Hrf%J{vS=>9Z2>6{a;qHHSCc{$|{BI zqLhS6_TGE1@GdL!a_=>t_MTah${v|XLJ|=wS;^iR-*fx?et&t~=kdDd+~@N=*I6$^ zRhNXv#zs4$Su{_6@YJ8lJRO=4(#ckMafpYqSuV?v!$s43+}K)tnYRAtl?J)2_|QjK0Qp0)_BAU=C_2AfW= zGfs+1yZ230Z&p$sKT`}*M6HmxL`Ity8r&I-CJC}V1q~xd`v}IoBSZ(WCW1bE4($#^l8LZh zt%vyp9?5L&IdUXSoLfKI(bK!#W=vj#C1`=OWg$mC;&*^wT5$J?{r6W%^j2W>&Fyw? znz0>S+J8%#_W*+lh)%KUI=9<+nO8^N;gz?D1NrS}j;AZ{+bHtSMA`+!Ce^kVZsCPz zwAAhMyq6utl+?}$tl4yQ6?}}63iyTU*;@auiwG8Jn%gmWy{F&Eh- zBWl-YzIUu1$g-aDog%HnrXLF#4d9f?a{l<6tZpwho00w9h)k`8YY}-90#?zqZ@Xl23%8_TPyWZb@0M6uhIwZJ+B? z;+m~;k6U*mu~VtQKa$$tHs(eX&FcEa=Njv_q(1N6oYg4KX>T2ShYAm)sQvAtxf`69 zwD^=CwcCVv*Sas>ui;JD5q&TAJPk+fFO4UKQgX14@JCboQ=p=lONE`UI*vbp9@9|S@PmZ)$31V$S7w@4t|nJkNAh zdB7N%mqD0A5%fL%vAB< zks!1PvXPdjZ3QzU$~2H33$xY-T}XokdNTwQ@FYW|H;pJy(!`L~`I&E(t>X=A7?=l* z!dbsUsREkPuJ#BYxqa=dfw5Do?-hG01u^E+zwu4ISd!(|Ng$hqj%Zyrth*N`R$)Dy-VNj!Q>b4pGw?iZ%5mP zmw)M0IJo;7Ig=^%b8xJ%wT*J~Ym!d+eJ?9L$gdT|5bUe29 zdahw{(dD4|V^B#7Xn}L&UGy>?`nooT+W#{82=b7PK;+h1IFz^oF|}YG-$axdAZC8T zo_|M3U}?-Z%&E;gI+jYFgFcx?dRIM2y@aifAK5^on-=z0wLsG2Z~ znNtpq`c~y8UJNXJ=2>)p#F$q1R=4?ccM{)7v!QF1)R)Kaz9veZ4=f5A$)^|^q}-F| zH?MVH^F3~vD`iACF**EZH90)UHc%hsWWbW`oSOKoE&w%WKzFL9&ji=|qwx$l!HI_U z_=6wm0NP1Ug_ZdGBi2li*)6=@|3=D8m-%1&E8O}^PO-jtr^4GO*#`dfwov7|V59=n zlaxBpw(8|vy>d{BGG|MrO7`WYg;t+D|469-3#8wgywNXoOSjo^(5J!WnQ}9y!>Urp zPQGx|J^%CZaxK(rgZ!b|D-ISuQLe5k>}M%An7a514YAVx-cZQlWhQj3AkNyC{IS?C)tYm1XN2!-+Gu&TDl=hphnado@s;{kQJ&$`bX+hFj#=Ayl6#Tq zR0=*J@*Sjmu?@R+3+7%G|I{=r!{k;Ho}FH&bz6iMh*^dlD;N@30tX^W*(wjdS2Jqd zWwwm)xcxX+PwkQ}Y1o(2%IO53KoQiG1=8{)QUv9Op>dFwj63OF(5q0iN09t%vi7sn zq0fr*zB<#^EBt3R>SpQfXz~u+{HEW$U%yQ*d}bM<_nM41B$vKsL<5SM2Do_JsR>RWwhr+DvA-~sMpR9Fyt ztDhT zz+lt_@{oSR{S6R9-vE+P;eQ9fYO$9C-TWW^Vjy|k_2!A?#PdEH?snE*-(0d)o}9hC zZPs(T*f-iI@ItIhW7gs>Po27kZI`Em>!fNb_w)`?uUX0080H|K7}JK6e+0Or9_HDE zdrG?XddkH#Qi3W4KD9I@^mi=Gm~k2^?CI+nJn~v zq$3K-gEe9$#XRgqB+AT#wV*GxD(n(!$OD=E(oTkhIc*G@{U*}f!lN-FWrL#?Gz;=7 zrj5?;Jcta+E{h%SAAenAn64f^5D`;)ZuA5-#|=XhBj*T@Y=bC~a}<3OVzp)ICn7Fm z)=E6Sno%9f`58Ak6?ya!q^DIC9Ft;c3vj|4j(J|8S6&XE-uRQ5l# zfR3iilMM$ z>e7>jE{+i%!p3(+v#D8saWx6%I7QK82$%10GIOaLhFp$C9*xE$qL*oWfU1(?7e$0j z3g8&L6h)8x2tXG50HqOt5SAX*0U*hUg8kuZ0m$JLczrh1XW>0oga`EppBh#EMcDdzIKf`t5BA-gkE8%Kz z8Nw&hOsmEHY46Mkw_tKJqM-IlA#nAJ3PMf*NDiZ3h9hht%;YAZ6%(2!2u&>_O3-t_jha=MVYKW~-u8nKlT-FZuWjYr>!aqF8p*m^jaZix%i zDbCrqQsggUT_e8carUPl4Hx?f&q{h2z_SN*Wb+HHck{=w^5{kp2-1iZK}G~nhBZY` z0FWGD-$tO+A{dziV1Q}?893kuB3SZi`-P5ni}L7I+UvQe!?~4)o)pY!@A3tKdNE(P zzwxMzSS~oVQ``=WtHmeiEaow7Bl$8oS1`7f^&cF)AZD%?YhV12N<$w!51}CW)Hr!` z`8lv%#KuIR`_F-GFF^oDK*WMLB7`9j9dMvQ&!Nd63U@TJus~+u;OKMFbGo1G?zs^z z#gnvT^Q`R>1r9j6Nb*7zpw5YU0Cmrm&S*rmkG5m3u8q0i32p_mUC=P_gy@1;Fu3OJ z-I@*Wiu%*Oo=X8qqHxZLs~DK6;4&l8^OPY!(ut3M2iV#`vi#`eG!LxS9Sd{k!))6S^HM0 zypK^wqShhWLWhi3;v^VXsoc2r)BaKK!4eEcDMViaTo0p+kT3y!1fcT&fgJ!64s25t ziYS3w91WnL66-I8$ATrf^;hkwT`hEFFXvEc&qTH+=h0w=u%@NMUxts}l5Ev`YtQa_ zTKD56Gpge=C9Plc4x=2gL}h%#iN}6PnClTasJL$E_+8?rVuoku^9-?N*dL{{UlNaz zN}7Wicg!_d7k84%Ev%uDtv-F0QqkZ7XUR6sEf|zS`UOC zQEJcdx04tC!Ik2o%if@qW#Cf%hI@hp%b+hm;AD_80FV@9wk?C9e1dDl%9nKxD;}Sc zB-M?xQ*%D986#*;IXtu5{-)3YmyUf1-W##w!IHmp+<|&QlU^u}a(3ooM`xh{P8LL9 z9C`iEx8rUn3{)s z0`hBsAJkuFIWj}8C}E|&ZtLW1qj^JU3V3~OpDEnO3F5Lq&Nt+i60dNH*;H~lj>L)6(Iqwe7|3@wOCw~|i<^7!~G)x6w0#&I)yod@v zj{RPyIkH9WDM2vV8$0bjsuVm+tq9cHMQl*;E2|8uI=ui1|KJSKK1fIm?o-5C0RTLu zNCJStAKYQokJ9ra3CC|qii5wb9OPROd`Rs%cdic%=m8a_|H zd971x1D;j-_Zt%CYC%Wz@j@_RI#FvSOv_Xl4m4f~189$jq1*!mGCxJkFQKPOafUEf zAtRy`;7Zp%4SvVsNAiLq)S7e2Ftr46Phm7VU`JnY)Eq9uKlr2a^-8riZQ_BFf ziN1V##Dbz-GE}<_p0#`QP%ww;_ADis_Xu+>8dv}?HdGFPL;w$gLA@{kv8P182~E;? zaMV*&!Sox$`$qRx@QhVa-juS^-mnR9{7=1&KaXN=It6?+QqdGKixs(}ag@)bhP3l+ zZaBVIcN6$UF#=S+!Ug=_=*5bu(KgDH(v~_2Hh~WMKz&7_Gc5q_QN3tg6i@|%)I}?y z3<7u`&4d~Nkc>tr#-TA_Pkb@v7}|j*zvAd)@!hYkPXy4sm1)z>v5RqNQkywnL{{=M z>TOZJ6qHdN{1AE@p06A|6Mx}N#-tqG5jlc&|DnTo zmD+QoB!WK{Tf*~4qdOA1-W*OI&^62P=(XAf*$>>KIA=%F`@OftJHIZP6kV%UMX|47 z$QJN$u`YWBa_!?R(fd~*vjdJ7%>nR}!FeX+*I=f8pQ4sG(_gczvNcyu;n^qhpYU(` zFJ~N^pTJu?I(6~1jC?FmEo@)i{mmUk_G7!YYCS^6|&yg{w+%z$awNJECQq1J+KL{H8RR1(f21k^9 zxrt$Zh}rhmvf&AbPOIm)S~yns2S?TGX|t$tBFX+u!Slf^%!)^hL>v;W>TV9OyY7>~ zvuate(4z-$fY~DU6Vz3G13LW#R|%!901=ns0#Gp!VLdQL?*PC;dYGE_cJtyWUeNT1G-4v(W*M@oZUXAltl`f8)_i&5lpBp* z9oS73q-Pl)LljEa8@aS^xPvUzWw)+-?vwH&#Q9L0K9b^Ne78yYIq}V5>NlKf_6)jG z14}3;1gxmkK$mf*2_QQHz(X;QZ~zAPQ}5x~a({J)Z(f7dQ}m*3^0_~VZ!_|}1**EeiD9+4 z-6_3w=}#1|10bR9Xf5yxNKr9EfqpFv>stcy0c22_ynx>>xc~7p zM8{rMtv9{wxT-&YRptcEDrdiM)z73zJX2xj$GE?_{1vKWrd*Ch26sjG>Bm=O`=zVY zlfL1q3;I5u+*{*sR;4ndcYJ6tC)#jAaP_cn;U#gB3R)rXuSyg|v~>X76WNg<0Sp3A z20+4{1eZbEI*_9+5sRhB@9!mn@9I-cHGAMFZxAjvcJkg@V}DAOS&}2RJ1@Go?e8E^ zrOmh;T@ALy^iI{UE%w`0T}hI~^5;E(XSoIF)b!z5F6fZmQ>^Pk1MjO&Cdr}i1g=*T zA%mU3wJmWn5^>Z+Kjb9A5l0vsZU9j$li@5Z&;X)lC-+67yMX*|q!>Z8*qu)5wK|9;6EazGs5h;Y`3zBd zyPxM?_ov{Z1T$(nq96{f3gXaWAkwT-CZ6TiuJ@4An=`3RQTypd9V)ATxt}RJ8Jjxn znbOPtV)?Z@GQ|9bE_DK^-W`IgsobZOIgLdeV8~_7S#SO&P*+lfu$MC7O+pPIAwHEI z?Gq$aO9NvRTO&wlL_m^&{Nw;RWc+T+Tr%X+fHy_wo|dG?3< zox|6Ftcq=f;u4Kue88s~V$-3zMH8$Wlc~Mfr-;7^){V(j!g9jj{$fe^%;uc{!yG#) z^QSjVIBpy$j@+r9OocOeI&1s&C4bH#h{t+l_t(r2r~wBFBM4;c#qOv3v^y_3b6VZ` zZm@0}X?Acunj`BVf8orK3|`u?Sg^~lu%F%E8vas^OLM?cL%*L{YT>B9O>fw0ch_P} z{yRtZ{+D5`e-c3P&$gDuERN3G-wopIcFoh|vpC*DAg>p!m=HUdVTWEegM8(Xy!ip7 zA#F-y!yBMK&0v4xNN<1xBV`Np;nQ>hh`6(Fb^TMxZVlgb#eT8Mf3*uyWT>$iSdc*y?ccC+D{ouoyYd^Bue zLnFMk4*#BwY(4vj2%cRwJZZmcE+|jWL3H5p)dGSI_@fuo!RICa=O^2>+gXM$?Y^3; z0ArJbS6@FvOj`-w5H+_KPdJs zSjrmVUujYKTd+E%L;T<&6!d!w%K9{25SN*X76ALfJNO`iSGDEY??WBK$Z~oca@b{G0@Kgq&GzIy9bP*U zmvO>Lq$!FaVY8-g>isDh`9OoW_K)m-+#^4Km-NMiLc>xfE@~^@vu5un>#1)y-sRG;<=mp$wk2LN0Bi*(*Tbm~c^?ud0?jW9M~zb`4Iio{?SgQs5V-ri)>aWA#2MPP&E`0aI$uVmeVGYIF?qy6s&MqezW2D;XUuA!Zia)?~2pbN;Mz@5%&S-h6kv zRbdHSJ#vc$2HA*hMZJMaqu_FHHUTphwYUI`dllNi_HHzv0x$efm z#igVJ7VhUUa7*q6WZ)CSfn_X`?aw@n61k|+Y31b1tv@2VaI$~V^WCjt+nA;(uR_{> z{Gp7<*GJk`a?Wq{--%&PU0>>Wr%~(^lM%&K=+qZ*pn6&A5tEgXbBsZ?xX)?MW!~<# z;_etubfXjck3aRKns3J|b5?gqmA4?I9c0Q|ZjjFTgqp__dBDu3hsWQ%F5Vxpka3MPtCR_5+1>E}NXR(q2kMtDiOr1*z4w(YqyAAp zv)F7le>8d_mhc_JnWfc50SR2=_jN2&ftn4Qd(Ea?pAqCE^_N@rG|nEyAL~McV9y%sG~kP0s$Ziqk-C%B=4E zy&ekGB9MO1^riF$^Se#q{`3k`LaxFp+@K~ zDf2AZo2=Gb#P4Nzy! zFR9I0U|s6Wj>r+Sd2O?QVt+aPFAa>PgKAy-ytA4lq?r*i7R=bhc1k|!zuZiaha@o_ zwvMs2ZC*OHUC2@UYlfFoXXD+`|0MI$0#!z+BDwbveb$b?W03xPn82SAyrSwo^x-Q+ z8|9ca+o=qUh40_BfT%c=6L65K-a6=~sffekXHk!LJ-gQ z3#j8+1zo@4S${P>bG*|BlUC`|EY@2F1Ai)c5^2#2upn_y%!opCJ;1dpQ5FgIzz|j? zK7|*M0F7`UMz%onYfD_jj^&7TOKcYKT~{lHGiR^yAenvfXIvJE%AXJf#0U zD|X?d+NfExBdxKAWEbP_^-FzEEAmho_I>VYMEn7+qKq?H)K^FqNqqoO;}IO0 z0r&+YELJ&Bq38Ct=tY7EFC6`i5+ukOeb>+Q8N$~X;O6t(daQu@QSGnUvLoKeQ^K2J zZ>{;GVFhH-;aKwBddRm=UlhLYYktY;zR}P%9R_}Q_Gv{h8plTD@c>oyqTGEc^B0b1 z;4nVNkg~4US5^@ZeD(4a&>BI&UkI!(G`;^uP!RF=f`Fgl%`-{>3`i2c;Uo%ve0aU{ z>Y}q+iuoC*K!aJa->3A~j`a0bkR;y24;P5^-r9}hSGzB1ao=e`|2SMOKCEVbOb4nx zUc0cO_w#P6fY5_viz80N`nsa5r=F}{|M;|`9qFSM0h zzIrC?!@(GkUkD)aBF_G-1Ak%mhs>7Cj#IjnS5;2XEpva!Ea!#v!4Oz|TMqETG7pt3 z`y54e|GTnCKe@#H;XyfBLL^@Ed2c`6;h}KpLmkTpj+QzNB2Vcvmrj20FK0*?!*4t{ z7|1-tU6NMsvb^m0T3behgZ}!`%bv^SGx3r5SI^VXr;o61oR5d%a34X!!Z?tNst>yC zSiC*FJqCKJFiszG6eB-19^Dg>)bO$naJ1HHx->~kv}pdmvUE1?KfFe9$)|&(R9Ctm zZCSZEl4}VAHDHmXhp6mvoIQTM*ly5)Xiud05u-J|W4Pv$FrJnRr~{?saRMj{SdetV ztG7@ya3$G}gNW&I0^%c}J%S|K@UlbZevssGTyhM)oNu_6R8sV=2BS5RLy7tifwR$Sf8c+G^?6^9WhU6P92Ae_KELBE6aq>GeMI9YQ-m!`(U;wzz$1uP4!!>i+IlW!fTEWtZMcK4Su_+2QY6A}ul!Hh;PFQcfV3DhcOX5J(+%3t-Z zHu)uZ2ITSy`2U9wK{x`qhqpwf1Yi#>?*Tw4-%tXY{{(XIN1sDOH6=e6=~sZ$h7GTc z#$7v}_aygzQiIcrA7c5YYf^t2oXC>R*AcZ9vuRhNoIkkiWcsErv$Kpn@}KnDY?&?VZW^7z9_^c0Zju2iJ$mpNm{H+dQs4zc zFb*GZ{V51bKu>VcRsx9l5AF=SZU`2@Ke)+MmA9=63T(Q!hzzdUrJ9vrUuAPSIQeb0 zAwBC4*t%rk&f*4CQ-f!A0%nJDC)igGxW6eh&}I>`lNMT6|KzaUy>-;k&EDQD6E-NK zgVwRN`umv;xU%$OxRd>0mr%@tL-c=;@e#)=vabLJJA({%+*7!X(jl{<_0yz+8RJ+( z^kfLO-bKh8dWup2Lb9MBZX8lQ=$0>W)+o{$5w7A{vhH9-Hy_Qd8;47VOvZeB#>fJ_z%y8d;yTyMOQ%O`r&``ZzZL#NpTJ_ z-BY-t?{1fD!KUEMIev6`f(ul}H@Z2ssX2e{4U@D2xBe-+i;%V0&mnZwdEzMe#(kqX z(}Y_r<}I23Q&88xYKJkGkw3yYaU^=YqR~F*FQgOEj{vj3(GzLt(g^%|%4iOxLTFlm z>oBq>G%es&P&hQnP)0jtrnLR|bC!J$^y#YIz6lo$=-Yj>F}M1ROiVOqmQ=gTVm3Ro zA|b8I(PTx&9W-Wr)UCceQxAO~S!XADAD!?OzOpwRgV?_Um+|zJXe13yfa;==E+8tmGfh^C zJy%TIfAw#|g)8?AO-|Zd>adGU&^fH84HQ?2B-h09l+X;Q?@e74QE4zyut(Yluvc-c zJng?%m7RPoF1Dm}AaMVrz>122=_k7|t!CjB8mHxtePb^xlV{`9OQ}CSI9L^MQGH_S zZda{&UpR|KcsZlb{-u2Kc3gI85BfO@0um*kNBaZ;gOUp35!)CDsF1{qB*s8<*Autm z)he`x$A}FttKI+43~~U}fAYIiDlDA*(DY&|(K4a8qF}g=#6g7P!F#hucJ}I5`7J1T zexK^0dy$*ikq}iGGLlTHf91mie)C*ghllYONhyNoZ@zy~UX^$bRR9Z;M~SdK^bxp{ zB$A>(&;-Xa3q<)1fCUOh7XTQ%PB@2rUdewOI$kKg`-s`n!xpb*eg5&W>X|oP3Z)?l z(+Re(2EGMT9J_W=gV{3J)>-Y&dGcd-X0*CmOA-=1Q0=SiZ}Ak2*C;fUEG=yNAa+}V z%zL`9^JmF9bP8nw3zGZ<$Ovry269*?XrOO|CeMU+g!Z6`L@WW^87$+VQw$02iL-Ci zCPk=kNrr2_v8u9_S1IPHBcc3N)G<}8nNXE@ty*pJAru&x)!edLw>_c4&!b0DH)Yc? zSnQb)m$>~#ZZeSil+?B+qcw@$2^Cfzev(n3o-5vpCs2(h2dHmK-O*ySuCk52*TYRo zk}@UP;a<#}V4irVniIVohavkC{|J2;2MI&tVVhY1xk$X=X+$vrv%E0QJ(00y{QC;c zn$#C9aqDxoYs!(_{2+sEdq>f5Tvg(9O~Vgo+LO|STIa1rZL5@}xqFDErdZow7afZy zP7X;Pd_2QW#Qqc0Hd8npx0-BLkC~!AaYXL3 zj-}1CHM&!N#_%Z35305=h1GFylilk7PL-ax4%7sj*VbFNjn0f8RryihivB(8R)6uA z{mCWRgFoAJT6HPD;8Z=z@guU8sW2?gCFM#(EsC9lp5lWS36)NQq~vjs#@#aslJ3O% zqd92OzZ2J#Cf71FXU+KMMzAh}jh=bgja=63{Yw+$Ej9VGalPr|Egti?nbPE^fch6K zp{HOKY8jVnk<9OkGsyVx*8KMuragIgy#yP5vyXDOSYr21j5{?)XhTBxbl8^V z$ftVQY_KHV|M8E#!w=vKA0r7LkE0^O$K4pz1t0a4V)^rKzGvR7=N41SG90r0q0b;8 zdHUMc7s!Oao_QfwFR$wTg-v^I2Bk^Ed~0=muWNOu<~Fs435K-YnCE#xJ$ze#xjkWB zO|Uts|5%*$RQM+Oa9*uJh7ywd37X)LA%P44kih;NgZ}#oeQ%IqgOZ@h4>HMPs|zYW zgl-q{4uSsGP>Zw&&o2vQJ;U z?maYAQs82wu1vv&YaBix)v14b##}72Cm<|5jv@g0Ii??v)hRgJo4<36?~}5j z$tgPz-MXuLz$Sc%v1TbPB1WRXq<4B}`21B!11GV|1L~g>5gYG@G;2Pl-Gv=srI&0s z@%*d1a>kGB-1Q{k=lQNDf8MHIN=t^_Lj;~>(tTni z^SKfCFVNqQP?k;R7xW=64el5Ezn~8%(v*=mG#MPE@kjUMv_mF6D{N7I#y{4|mjny%ukulLu5O9#7b!KG~fCCDCE%0z*2%2l*dfCdZtNl-%#>)k zETs;*WfKkw#eUFbNb8q*#L5N7$DDe(EMIg;;A4l_XMp>A*yCrQP~vac;R%0X&wmVm z^)S&NGg;eDEVi=kfKj;0mKq!`ZSWmG$6D(TGwY%cGw%ZR6Ho&UL~RXCqGeCA(I2Rf z#R7--K=oEvbnmNVq95H%pPYqO2mY2{s z8$hMP%VmuKHIq~8&KaX@d#uS7>0p+%y534S)}0sNc$YIiCuzm>3W{Hx2Yo4y9?SXCC9^utg@CGVe`rK1Db93jx8NVOE}AWu z@m)n4kSLGCvvTm; zk1>huFn^JF^F0N^qHlk6Qr4w-ZYr072u46}b}syLK(fM6Zgo+wNpn8}7k(v32`3IlOX#TCH{F$bvq=mJRS1P(g1OOTKgVio8zB|9>pmdajaUgE>jeW(sbwV{rCv#E!$g?8Oou+>ri8SL`Fr zCgg(H0{1sZ&eu4ljbmlu(n!Dbox=-4FVrFQ;^6v2_SJpfuL(6A>AhIBv>p`u2i#3U z=@3JS%Kw17i6&hZ0ya?ZAMl4hO@9iNTz(Up33Vc}QV_)=h`b2(B(66P&22I%->d+y zUNuyk*ys8~ba^}o96AQLAIX_bjB{R0Qa1y^^LPi!NqjqNPn-pnAmp+faA%XxHYU#8 zVJuOQH^{N;w3@k1FbnukTxn>`Qi0%>)_R@kZm1$b1b!zkYhESYa~H^jAQAo`>nYX) zxz|C+`yzCz5EfEe8$ld!G?AgvMHqi-oEO>wV6ccCj)M{-lXSFaWln>2q0N?F_1r~w z%A#qGxA$_(uye6CuZ1W3X@aDAbw1me+hwZVfqSQC2?VMKU+5e(`B6qU zV%(gtuxK7a=%(aPCrP`6gp=d=-&kI*Qlh*^&8EEMjKJ}|so{D|D@ zzEiH=u-H3>gO!c$nG*euZ%l zFyFG{yXQ7fgIQJ2Jj1CBYP7Vm7H;`}#FuNu(__-Jj=i(p_yX4Yzh)o7c40rSL9;RDI22e6-d(n}~wm(i@g;LjO<_o+#S6R%C-?NJ`pqt#!eAj0BPxOw9D z#`bwGj@PiKUvm0v!>eS&+d#xPqVxJ;^2_jel-+P_?j)Pn9bw}>$6(v_yNrBxB*9;m z-f*RS3Rg@Zsee49!SWaiMl?IR+o|9C!skQUHhQhv7>YKHPac)$E`hhG7WVA0jhiR3Hyr89+rfY7mmlq!a>hBQ{GISvl{UoLtH98OiE!UJ*E57uEC{EcSKa>gx4&#r6(r<^8k}uoP^xg zKpj>vt|)2^6c-)RwDvCAcy|nea;&I`0%Z zVtK+Aa!h(}9H@xYXdvrIxBtvcWT%-qR=m1Gib`=Cp+ebLdr0=mFHvY%Su49sTD*|^ z#S*nT{m$aKH2zg+Q|7Ji>76seDUZHb@w+QoE?%EvU04%+KUmBkEgD*uj@Y}Zx8wzX zt9JtVj+LPNL-vRbv!0hFV50~DW03zk^fE=vRj4wi_ms`H#X%5e%xE(p5%IUlM` z^Bo)w`%(v4Xsh+y#r zm2Z4qrEa>OZ7|`a5cwW*{Gp5jxCmumqeO;~M~H`x3yQ4!!{&aQQV%vu z|AD0;FD>d==u{EX1qgl3xb zH^GdkW*cT>en?GFPtK)2YNBJ;%=8zX-F?F?iDZ-*KF?<~(`F5YJP$0(TK&*>s3dk( z&)8|u=a@B}+$>}4g34RN?Do)zK)+10ob=>G0sQB_S+2&mZMA3ZEU&R;qL>S z((>O~>>gY?ul>+r%16PT|E3$8;mU4%a$Zb?UBKlOZKS>f2ZINgF@FW*v;$(|BlrA2 zBZS?7&OVIV^M^qw0qi%9z2|QeJJ4|U4=YdEgAE%}A69o~wHn?N`$ziBN+8t19}`Vd zzcFvfwWP*i^UFKQ+$-Pn@@$jb~r5e0k zt_SI*s#xteEYk{XIrpwvbvzb-ysi0Au!oppsQkrO$T#(m#2|%TkaIguD&Ph(+69}p zXF^H5RciL3=reeS5^eB(e=?Tpsx{!dT3oJ~nqBD##uS*$w1i%g*XOJkljTps(h9 z)AzGY`VGY7{(A{Remg>Rk=oyNR>82kUj_BH0Q+S@ zF0g09L5suc(1i$%ANE&$*w1~aKR()-zlATL+69y{G%SQ7j|KSn)Ph91;G5Y?r$Y>9= zqy|z=D=_Hk9w_rLq=275DbVc4n@}831r-<6$7tv!Z>5;)dMJ7yF`|H+?Z9srU;jdN z0n;H@OKyGTqIn|EX6Eaj=Y3$zBrZaYpD28zkTf625Hek)HM~yAdHpHm>WljPXXYv4 zOgsMld`)2TNYL%z!~)yTq2%9XoQ&)LWqGbiHPTZ}<<+jFFb0zc!y9?_Vd+py6AOWY zE%*1KS9{aRLLsfwaUYID8=({kvkyZs7-ky?Ilv|G4}KyMwt;l1T3u*+S*Sq!vSYB% z1IJ-SH@5QSh<5(GEKGM`WwK3&_hzhswN}5wpby?D^bS2o+NyS^cm8suL{My!U0dqf z#svw@3Wr>ubm!A|ojEbc?XM9glWFG_)CzwlV4AbWgg^&HHRK$Q-# z=FWMfs)zF3Kdk@sqMR?zCg=k$@y*3wr&+k~F9l$%Gj>vO&Z&7EHpy%8avQ9~Kf{m5 z8*H$WibPxpdK&*^gPF84LNd@lK4pX1&jphb;F=7HHrw<<=e1iL&iPz+WL6wxrCDX_ zvWD_2?*j%CrP?Vsc=*FL2kbYX!p7EZdXC@gV%^7zIIz9}n+cJv)N9jxEE+%UEWMqa z6O^1ebvCD9<5PjcD_`O{-uA9sJ8!RUVVm$+)x}+zhU@(Hj}JFX#$c~YjJwX(?7TF} zv;QE(X3I;(6?_m-K_~Il3 z%dkwg%ibun~IPErbdiVP4i+ZTxJ+ z+h6{BnUD|>_#LzGGVRAZhUq)ZmW7_;kI8f%3jQX^9~rIs1yz5DFf^4Dle?!9Z%bMn z_e_9|a8d|TLPvLBorJnR#1Z!qH_-+onQ3y^v-L1^ooIuJEGy-F@aIruNWl11tKiom z=s&=43_2Dv1NAtbg;>%V%#rb43Xn`r|WPO;59?!pMVtbDs<- zll+pHG<0-n_tv%WkYqm*I;+-9lWi8h{Vb9#r>T#fi1C_qly}gXR81&8eP38i z$Hg(k`;=YT4F+b%6{{}oLLsb9(2wMl@vQP@>^N&=e>bW?l5+JB>BFp~n>twzq=VA~qCyM2jQw zML{HqJ&2oRgOM~Px+o|F$&r9cP(ar9d1L^PEF$K4AlPXCBY~d25W5>VA5+;7w7|h- ztTqExc!XTs?on~S+@t<<=|y7P@n^O%>ablKb3RaIvMTaObNR0Fm;2%V*r&r6q4CHc1%@IT|TkaeqSQgz`-TQvtUKk7L^OLbJzO#zSh1 zQ$<6wF!x^!d^@ClBA;%;=CSLz3 znuM}VFar^J&*z4;$aAGu41`>iJk=qM^#t|bsmo0tvW+9@(F(92IU4yR0?{1;nxL{IBhI8=L5n-*MaIAQ*~ z7~)IDu~*P{0O1 zUfOwkQdqc2Gcn?pQ5Pd*=KTsS&un}D>@O$OPMfkV@`$j=mYHQ#U9o&e$RCUkRmq6& z7Tui`V%A)@-SJSeY?0+$Nd%drb_V{Rh`Xu``j=c&YGh}6?B?>7eBBNns z6H0#9+xPd^b2+!?Irn>>^PJ~A=Un%7b4HxHrI2!yOs||3hMFft2YJ|M*RoVaz(aW; zR!y2kHlrWP2Q?DoR_r=YwSK3p14|8!fw`=&_q^oHh{+<4lPTZ+lwpL5K; zliLExoW|1@?(1|1SIp6LpY#Zw*b+;;7Wq8PXE9&ko6C%z5C>;G39dIXLfK0Stpkw^f(EDxmmaZiy7>EG22@bpfgoqOz^FZ-rg$wZy#MY}kaKIPx zAaItn)tHYIt&2Ro;39fTl{$CewdCU^j*g|`cVrq?shVhrh3g$|bQ$qirEWjSEv52j zp=0#Hs#yO(R^s?*#jvAz$)O9d7Ezxbd?m%VeDD1(ytQU-or!6vJ~nhm%pBG(|4Hg; z1B!Ir@{SL=C8uHsZ~YfNNE$dXk~+ot2mVKTInk>0)g)oEM2CCgBLmfmC>I*o5il;& zqC8>np78Vi)=q{e?S0w|12=Ion|EnEd=ozq=n*;pP;9Vq^#^?|$0WZLpCV}HU1DC< z{Q_3{!jZ^B@qrv65q)vTJU<^_BrK2_Wxn3Mvb;Ec=GI7rL0L$D?y7jmlWCpI_YE+% z*qqB^`iYdQBnSq2MO+{cxbSZ6OHiXPHMMeK^x2)L7r2Z3fNu~xateF|N*^~`GazX? zFfS~xShr___lItc{h05PpO^Xc7U7jCpHE?KH4ykG^mUQrr#2oV-5#i*gq-|neqDY$ z`|G|Z7~J;UejQp{c)eSN$8Pr#`y@Y#|LvoZ@@4El`X5yP!If>XX64+)#I3YD#ooy8 z_eslR#R~g4f(O#^(jEv*3ArLx@a3Z#*KVC&yVt(mP=vgSknxLyel>ils<)L$EjPTq zoH88<6@VUiyFx3aArL`Xzqv6^_y=AgB0Lzc`~%y91oN^mZZc_owoUfU_0P2Yq@v5S z8FG%xsSg5Gg3Ryl|8NuIrh{#b@0L@umP;x{Jmue7V4V*13)*mhB_hh7VB9?78|+^S zYa7r0?@IN&X$^r_Nd&53nGT!`B85Dt_2g||@(M-FOhHOygbo;kc?df%#;d~Mf)K$x z_xH!yZfdk!efA!O)~c2&1Ml%zi&+r(DF7IrQsEWkxLo z3TS!i?-y45-0>6>m{)!tpl$l`lnrfp`ZA*+#FqH+p*3_u){!s(R1Zh;`QS)FNI?i` zrlaMMu;S9i5krF#3t;c5)Lv%`T9KU&7QW_k0_Va`&YwM?U~ z^AkB%s8ocQ?6uDVGkro*LZ{C``BN~-wbbwLQ0=|7^#W<10? zJfQI3kNY@|Y7U-=@IK;8F_ThY=KApM(372zYY6^peaf+6=Uv=uUf*g2i`<2fg4dJV zuu{Sc3io!Ea7MxE=e^tKkx9uGbIupv68>5_iHQIzTMogJl&=8lHwwK#Lg+=_p_Mdp zA4NbPY2+mk#CI(tb4${CCVBd_u3Hy+n^MyaU&!2JJ2YtX*z0a+sCv|JX<=_Gub=iE z>s0Sz${j?=EUe%fq+&P2DD+&ET-oQ|BYYFu{nmBfY7~g&ZL(aEIADl#^FzN!4V5i_ z_U5B~ewfUx!xz-jiml?6cq9V4t@nmFY7$Z+2-ZAzNc3tKGl-6t>nYw4Ly#XLxA= z0aLkmPfb|rMDUH+YtU}~Z%vaPU1{dH+m^jL61@xpJ$jE6QVN6Bh{`IA0!zsg!C22V zUWHM>JNa`k)W*GmS+$c3gHMtm{7b-il6~;W_}aQvqf+AY`Ze}SzL3?{RavL<=iSG5 zm920NZex74->y7%Fsx@FT7!Cu2QValhLX0y)0T;3$|q)&dT6#M*Sk#_w7rl3r$tOCV{c$7+ms z4hgj((#U?a; z_jIVE5t}RlAw20Fjq$UVo0trdAHt`=E=&D5wwWzEG|L9!T0%ahyC9Tdjm$|y#A5g` z*s-Yxu3kA``L43GA#OZ`at8qi!n49)(eV&*VLUm~aR`LiC5&!)H`bO|qR7TPb~$8c z#-3NJ7cymcBfO>7N6O~*Hmg-15g#p9vLSXIf(9I4omn`FfP+q#ai8l5Y2LD`a<&@Q zQ;2!U$tZrc5dqJIu-5uSSyiiv2^!4)Znwh9zBp+^70fq~ICY#}{VBv(5S}%7KK91q z-6~He1$y$U>Y>)XJKA2nG z&dXq|^vYz7o1}N=QC-D)p4tiJ)+0qRF$odv_Y=s#8a%>hV!#ym19y<|2N|?Q;Ptm? z3^$r0@GvWSnATeG;e8Mbms*!unR`EF%=nq?3@2D6uTu-oMt=lTKI_9v)@C(M^Gx^0 zloVrE*{z({e)PYZgo;-sEv4{SXZDKWt-0oN?r$hz#y4eIIQ>WOG@IrhkIJF76wY;? zW4jHO{c4X$3a{}o*;Sx7&NS)ec|@L|^%f$Rpa^c}OWFzY1AZ}U($*5rwEzY*P2@Di zz0{;#pcxfMbsb|rzJvXktA`WC{>Td1Sq|2buh{T3pjFb6ir;pf0d+C(Sd51rWx~j9 z^HI` zW)baC7T#;h{Z@1T@tYoV?q3d8Z8*nv_WOS?=Cb8zn__N3nnIUn?@o*3XFPVe&mH(B zy|CiNw-3*6!U~dRxouxPkNM91$6dj=+kYTYI&j5iByVEN)}%cpXDVKk2cl>w$eEK@ zqVQ{&HUn-V{9<0DnGtp|JeKja>A1bs34=BQD%u-Qtn!j|P1KuM7sA9f*z`mr>jJGm z-tkd9XnlM-GbfzAI$gN*uCD80v>uRu;*n`UOG|L5>HONXYFXz7)G;(&Ug=&FU&r_e zlt9hQ6ST<$#@h04!$K*$r>&;Fyqp8TU*};=>Q98q)dgB%VqxuBaz_k(EjI#-)iq-9 zt1H5Xbips?+z4&50HEa+@fsnrsy_xrtM*RX_*0CKnxsRdc*(c7pzcSyR|GZX&=Zw0 zDRE5@-JK{rh{`)7vImqvySi8DUc^LvR-B3c-V~n|W0WHy^gp|>vm=fN&L#z{n3q5S zipg6dc7k`zIZJ2Wjf4Ae$693j38Cln5KgOts6_b7jG3mFvlqcE_JMFhq_xI&Pa(JY zW1UYceZbDpM68jN8)v}zu#y?^l@8Ho_dGJSR6=k1NN2W!9?*=zMn ztyxh0r^SakFfwvz&+knVr**hXt%(}s@;cn5)WpU}lDH17k(%gEDo_+~HNibf8rd2w-(IB2$A7ZM{tEdY}Y*c3>?-c2BT7*tXbdhHbFHBM!?oj9*o2g=M=Jakttl zAnwB;KcM-nG)E?yKj8t`tz3dvwOJu%CF5?b_g1v+k72*&vww3yZAj>U6!`Vxsydwv zh`hTaZIij^)jxmwZiBx|C$#cQqFoL|F%Ts>I2YwZ4F6Z+O}qdQi?oC+y^^zQt%oA{ zQg=PM_Tz~tlCIdCq$)VhYIq7gTVVdgThEcXIZ7wZ^XVi)Gb;B<+V)faK!`qQ)${pP z-FAOTta<4k&r%U;UxC1lH<0&m2gh^e{Kl@jTF;F6s2C~q@>@h)YE~SFo%F*RVu=Ht zaC#0#tL(^wS#Mt5TyWd$blAqRpR&o4SGkR6Y09$W3pk|Nkq7Saw?r= z#Ov+{Qt_)vJ*s7Pin~dA>A*kEg)Gq>xf`27h}Z@=@`Zpht_fr_O9bPdmwWd`@UUt& z9{uJP>$YZp>w0b`&M#$+bp^A;DehTCQoj=4sh#B@g_pa=@8eq^%J_RgxKX#@G#QA? zsH`5y=V#J-kJzn77q7i(>$Dju18ZJPWH{8tr8Eu?;xM9`kSCPwm zoULX(k`XHUe9ea?e}gWj$kYu+ukcZWQ-$i7KZHsbdG zM;_4+ZlntbCK62+H=>K|C&HU%#jTLRFQfG3#Tly9xBXXbS9$eg(Ay=*F}LHx)T3W_ ze@36rENQwu+b#X|K%H%gr?j;uWLPw3W#6BC6m&N$S|h8WIS|1XLI$;VZ#_3yS#4Di zsG70t*jlY{hmC}x0!A5|uWmA$K zMw2TtxU-)V@zav&NSThRftYtEx{^-(o6Tf`5P4NR*LeX66nB|5x|De88U<|_X8rly ztU0e(GGT9QQ%O|UakhnRFU>7o-+4SZOp#7tx%cf<(^%29_$RRjWsaY|t!&&*XHE%0 zxhY?gi`nC=%S)XiT0BzoZpIBYjW;DebRZQkNkRZv1mbbm?{9`558@Eeg(4fXxWdE- z)tp}r3)*88xr5*_`p&KMug|@nPo3_Y$0{ZDKZ^T0EcB1AvsIMWdDpPrKZQ>(I`oV- zY|AYry-D`97T?byv`h^uP-|T#wATp7EC_zed;D(>zO{(1EUMp!;8Z&R#(m_XEZTY> ziK8Ec$U_{gSV{Gr1JCm(dn9APFMdp!u+`jV$Co>E7WeyO##{_%hJNGy>27Hjkf)g` zjy5A|_Po2MW#2PD+5)RVCTr7$*%KQ}K(cK2VzxF!Vi@X_T*qKl!d(}lB!_yA5<~jo zH1WcLDVmVmaH^YRr;Ju994DYuWZ%6(^J8Rcs|Uv@bK**o*9 z-mYW(qnu~D)@9mjr}=i-b8LG@`d+^*6;E*?j9c*g@{_lc^>omibc$%vL2KexVnqji z39HC?02|$e8?n1eA~AonQ2&1Hn_D!pN4=KJXB-(6ZVV{wkH3rCeeF{T=Qhpf2&b6! z7&v4rxsH)*FzdzcLdW-r1HNKKc*dq*3b zb5E1L1i?q@-#k{+Wxe)6y@R?Zdad+tm7X7uGjd!=Vd9>evxp?Tq<61?0Tt!6p7F(A<7le2B{xunk*FGse&dlzJX-NvG`$Cu%@XmIPF(Tp$ zaBF*vA=wGQs81{u@c6~Vgr?CIX(aH8T5EU5YaKL&I9FxQ{rsR>qnY_Wx+jg}S?vU` zM8^RgWLxX8Kc-PFcz*6ZdWu!X4pM|mU{GnHA7sdn|NX_Oh@1W`n#d_)h;bwP@u!ws zbSy#&zRkbiOxI9Sqx_2$8&ljZ6T$7S6`^Tv(dzf=UvFESmGwo0w;CnWGDX>un*n3M zf8{Bu79{QeuUMyurnX5rMn2ICFz@|Mui`WjQNsPcoDxmm?ATa3pZ!~4?rna_XiXyh%DNMwp1DPif(T6ti{W{dsqF&@%~ zFH0>kX?)FWR4$x~Z-}cb6~qi_zxpktLH*)!>X4D-AI1w`*cuB99AOPC)9qp5+^+G> z;_KgT8785~7&Q3bi|_)0`1UxBhxX)-GUh-6@mTAqfjfvD1L~%uy|EAC$Rd!MRL`?`9>x@GI@t_x$J3}ioRzyFjt#=BIC5BR_u12XGFM7NrXuV;AGKm2s> z{S3mGFk2an_g<^^wiBf|*K?o0Ska$#{gqFnayw#Fh@T4Dssr!6FaVaXF$iwWS3&(} zVvvQPnU0>tAQo{L$Z8|WPp+-oKJ-F3QBT#T!OO~7SNojsR`hVi$NRHciB?K-{l4MV zB0Kli+c;4~otd;OS7$61f6A}Vx_2|?a>}~Lv%}lg%3+d}4x%#it{kDS3#ynxeaJdP z>{QW9o?}o{#pv@snk3?gZdySvMg;Z;{An#5os?byqVzh+e+`nMcGYW_z1>EjbM9H^ z)T6Gu7ST)Tvd=>yax{qCNA*+*yUJ}n{DE^fI~^a1-HnanzVjVAZxrdML*kB%-VAo0 z+l=@>&c6T9P|bY@lXqh^R2WF8YIr=!fh znKXve&%D2Xu;-5Cr((uHg$agtfZ~XogDQcNkxICsb9@Uc{*zp_jHaCrTw*fIV?RBFMC z_rIAF)jpb^b8GMlGd?G?f?aQv_KK%i0Mp1`tWAutSZy^pdd|(2CzONac8gq2Lv>vE0RMtFAstd4OZ3IHrWqe}@nyaNtxkGVlS zP!zBt#y_sCVyuss@39u^iCK>!mnJ>Gbw8L4z63sFMf~E)_*p#AM*LT`Gfr&tjCc9H z=drjJQ^KI!Gnbt2Q3CNS)m4Kbi0Ip3b=PyP%MaalF>l7^ft;sv+3HaPasJhdU#wQ? z>~=<)MNK5Bd?2RH$UQLfWPkQhS))5xb%6+Y{hB^rD zdcTHwNu?*HP7WVZ|0IvquOicQ2RkDT3AY9u^oYDnwg50{ko_8XJ!wP+q+Wb7iKMYV z_pe7#Mz39_hR155#i*{d8nL?`ku9ksPj-(huRnVr1y%{WhY%4ty;#!aP{VcCgQVdS z^yjQj1JBz67J+bN^dP@b%qT)cG;s(dJ8-Z%AK8Tn8?Tv!4bq3T@L?5Yb#be;;KJPZ z_g^ZPQyU{cW<+6m;R2REM;!$zZ%Qm$MIkxmBZr*dP@W;8Ie_oS6nDF3nSEjo?cu%F zmJPoKp>fjWB#7+dwaQ9ZiR5lKz`2&>DyqQr8?BJK6CJZIaV2?#A}n33BwciyJw^nw z2wOm5VroWx$DM#T6bYwA^2WUzyipm!XM+c7Y?tHaO> zHI(zN{S8aui<;Aer$J32(ElC>iYd= za$O6 zy;dx4j}w8_@J;=n&x+#EdZAIzS&S?7@zjmmw-^-<#IZ+~LhHrh4}+3|>4M81>H&*Z zB|hGXao-jjoSQ?_&&h8y`D3E^$z;Jr6<1!5-9DcQzE%jG#mCcPvRjD1HavVBkIkk~ zZFqPsJ_j36K==YOAdT98hi(JfS*UwH`6Vb%*WQVwoIReb(!wV`m5&7_-2|L)uMpaw zH@48jK+GunkK3yBqC+XZu`2OPV2^xwZ+8ppFXt`c5G9)SvcS3HeB9HQ-vq&0i7WHB zoL+n?SBrC*|6aM5&wBdDn~{>Vgxl!IZNy0jcexJ{{+D%dm-`ZiX(Ukx4oW1-k_r@I zn)Z@5pOuDa)G}GVBRS4Y)U4w_RC@SFr+2mQES13Pjof3zBFH|uR-<1|>4@;JQBmZ- zG#%W2p>#Joy81oc*FuXM@wEKHly&ZSh-wf2?`g5Oa%IMel{8CCcW*9qU^FL(-4DUNWrrfoHRJBm&T>LwavigK7td^QJm;Wr6nLPc9Kh1hW} z{YO|uyv&Fq(t2npi9|1=r3asl5lm=B2lfEx0gzYwKB6P%8WU!^HVhm>upL#`)=j-} z_1XEMjy2^IiSps%$Z5?rL)Qx)MI8>dU)663Z%1Bm_44IJuJA|5T222R-wO}?yeDis z)Y%Z-`2yAnL{=K5tG_rreMx%jq5F;w5XZ{YkXa+NI1jOl*2Fxh3C|P3z3}gIB9$oY zMN@u8mTz)+FPgG05z>5~Kml~+Q>~Q6r$;6VkjMHT2M6!V$RIu_DzJ2>^CuG8CWq!H z?|fP}{(1e}fgbxlD7TtuPm4M(eMP|FktEx{A%T-)e0V>G*%wg{JAKx^Bc=j<${ny8 zg(58ai3yf6%lGTp*F$f4S%)Ux25n1ve#PDprKDiOybrvSfTWg?@I)f94?Bl{lE#rm zR%;)&KWz~_7?D7%Q4IA@#ZZ%kBX!S)wu^k+n`)=xJ@1;Z*IV*36I0I(2+kNG?{r-) z+t5$pUwRCXqxtS?fG9$1=E)wcMx~60m_ojK&G$xZI6K&;Q6ECnXP0yri_+(TYKGMD zkUMcEH3z=M3)SeR+Z0hP+`sGJm)2w*|D67aFEu4ZFRq_V)BU8TgoR*%nNJ^0_)jQQ z9u$F?$3o4?A${C-!>|p+1HdLPj3qXs@^Zg6f1OUT^&~agbNfM#jSDL%1Il$acMQX} zk+}+<{$9Q-I#bpv-lsjY4peOzS|L9$Q7e9j8nzEgN9+1|_*-=7xqZKQJUoy9>-_<{ zIxSd*NFTi}2#S+sI-rJaC*u17mY_AhlMe1fT*(r^raAmrOk-I@k12PSV7uQ1q=NmWMV&Bp*!4-a34VRzr)XxEp$*FE<+9i z*xV048-2TUpgV(O5SbwSDGgpH4d*t`a>#raLt-L?G(~&Dx{7m9^E8&$A9zU_W^I1Q zvF5uK@)3@P{})Xc88PRaL5>N3N|YCqA=&(tWB>PEPvSFzQCB^xV7VWj6-_=LfFBh2 zu|zMT&|MQdh$6HD(KrZ4L?c{dK9(|nddCrsixpD@DSd|9WjAt&d}~HZjf+sT`dE6W z`wK?~+PdEHP{ejp zgesW5BJ@cM0E<<`&uB76ubwl)f^ZtZW(6P%5D*mM7Hw7Xw#xI5hfYG4bZ1WBjRaf?I8>cRT0B9-Xij0C7YXire%~@F-6hjjyxmJ(_xY4`?I?u zF3@TVcYM%T@dC`B8(!(KGAX3-+!(p{+%>xiR-eLq?=P@^-~RPD7L_Slrf(FCd09q3 zJdc63DW$80Pct{-VuVUT9C>gEugIzh^o`eWhh-!J zJL983%)cV63HxE(OHJCYaC6M3k{PYG{u&Kw<&%K&xIO|1*U~PBIpQqCsV4fwcS@*8MDxs8Xe$2zp_umr+2)w;KHQhXY|9qrksQNwQ7M9-;ik#;9 zkY8P8Rk^KF=*N`lE4{qNNJZjjh|1KXKwAzsL_@eofg6=iM>5giMm5tBTQrDU!$8>K z>J53BVFq2p3^@f;H+LStbQ?DHa^VY52$cj&Q#*8L#*L=$KL_P5n}R#)$B38FEeJjq zw&-HZemo=>((&#;XXHjr=iH6__-+4F|1P{ZtK3>w@G$xaaWH}_7SR*Io&~)RT%1B|E>YbzQjBei_=FlR<_ll}|&aIyW6LzJ+r`9hi6R6`fn?hV^TV zA9Ou)p7KmtZYnU&a!Y~`tN$)$v2BZDZ$JID+N4wx|05W$=kTv!q=X*<3Fs(s2tqVY zJ{@Ne$)J=Z(hLlGs7X*ulGl@ziC@xvhMF#RzFLk&+WhPMf3NNED%l%*^{+K-qFTDx za4oD-OPXCErEpi1A4JFl_pG>!EG}UvPRnqDG=d_}9%IyyT>VlePAYN!T%*{rZ*;j< z_$D$2N5-|)>>Iu#Mh<8>rubA~0V7X}%4F8vQSlk)I>lYB**@efdTak9hZdjnu7~!D zNn11T`Q%cmlLQWWoNA5m(3iE}^%Wh)eLlE)?H!fc#r)>eJ6M&2_2L|eo+SV+uFzk|Kh(k^~e7q$U;x-Hm1MF+u=FnG z^iLU;b%|*~H)7Kto&7#5VhL-lPpn%btUs8peTuGBO6m*R8fywx+E)=-{T^gG-|v1< z-k)@@Zsk|cv%NF+kQ^+nF>dpjKQCGPY3J2zA_3-kz8`6M|6&Be@!RV{pdzNT_t zjeUX7Gxr1gb2lWgF!q*I{YknSq)(2Rfi3KvTn|X4!=7ZuV0{t<7|@gK7eu132 z4&D*{zFd63YSj{^J}0R$9zq7{GBPU<57^gwr_}||N7218IJO3IiC9SEXzNe6P0>nf~5EB`VSmjQ0ocN+tAABbz zGZ_b;3GXh}*ox&?+FjYyT@_UaN_scu*d_l^koDAF0stDU6tg^Eo(u?_ds(>Ne<_`AqZx_MweHC^OvpTcxx17^E`(bsWI32zxvz`6cx27i_Gk%1X zM|qVrbenN8?~<~q^^v9wU?T6ze(u|^Cvutc;pI^mORkXtOWe#$m`#&EbPt2Ww-eD5 z@IEnIh-d%=P>?EUKSbz^_;>5{*`#_u$L>y&)WH=ezASTZd8VG^UvpZb?U!uk;w88=fU_r()~ zOsXAn+PXIHSzf=yRMRI>cR5`wTq=HVbv$W50S77Jct?z#fP+b4DumMtO*j@>pFrfS zuqQMIoz9y2QzJ9j*U7i%gEaP=U2jDTmmPZ49!aE9!~P_RH$;v~iyhQ|1BsmI zwRAny4b{oX;t(Xg_(XS1a-G`&c~C$L>^5r7iZ~)g(L2y}#Yqais=7o-CDfoQe4}3` zT_}PU?7$ycCAfa6d`CguGdPSVRqIy$s!Mk;sPo*6ml8k0^_p|L0ze z$+z>CDeka|iI#k*P7l+}@^as5GxjKtn00`cscmvpj=tf_-;z@3LMkFB^X15O8$5DC zWHU)Z2rJazg-I11e2rlvod5wpqh+EMi&uYK$u_iYrNzIV8@%=yc5eC#63L}PbQv~A?sS*2zu2+=I8sl0WR%^~wz!q|qL|`Yt3LHl@IKkO$?~*kCm1?MB&t|Czn*)(BIkJ2 zoA?LS7YE1r26nEtbn)Z>r_p%5D9hTfYo9&5=MGWA^hX!IC-L#B`^%0VNP?>@T zIiITEI~Qe7bnVa@?qGP?(ZPWzBXSvlX$X63c3A&+ClBqg;(sgZ2dG+;kTBES$6z-_ zDZt*rN1>yO1KoW!Hh0{ksv#vfKGC->PQS&DiTW9-h1LokTVUx{tuabph|Im4^&)gq zM}iIe4yx258;|Xrt1RY)x&$AErX3(k_SjiCM-1tQHN?vvZctO)Ng#lYc#2!Je$M1; zxB1RZ?T4(L1gJZXUs2NKxja?*ZbyYeifc?sZc3}mqQ&OO!`4o3DC!n|il*53>w2qR zo}7F$=KB5Qwy0lavL_9_oCT;uM;qj?bMa1&wrf00NpdBO4yemFQJ<`*1Bt|&M2ij_ z5^fSJ04%CwbN+$@hC}`Y7cy3~`9m}FYn41xVX%DHBYg85+ssH^%jkot_-&-7Xyu0> zmcwdWzz}ApTs89CxRPzdh{NkVEQfy~pNjQ67g;ZET{K_qvBB%XUozplVX4>9yovil z4wtZY9bhxqmIH?HQS_llQgW;tho@fI7CnibB|A&+5J5-u668iBM9~p_qm=9=haBPR zhFCM=0buimsKu2(ywZD;`>kfy@e)sA_l13QYOCzmxklA|ArQpQmiv5;;9*93x>d-l zmata})YjWyWE%DIVq&JTjUL+93QeeuC(OO*!=bd;#Bu`m;|K1$f&$h@uj{{PDY8rl zFQOQUxD(o^JPHe4yPV+AttcI0i6ZNjQ3Xl7^_fGrghTeI*iKS+I`{9IU%mHNTF<)2 z8d{|76KC-)|jw2HsQH77EBlo2E)cKB?s*v=u7?&K$7Pf_R zG7kR8) zf7Sh9eG+2=N7;t%ayE`_nn#a$2w|{jU0=h<{_RdP<-zB~h=f}YrFu?t9N3Y4ObCkM zoA;}VhcCbUGT3yvSRzp(aesvldEkPf&LKgEymG-^a*PikBLFN;aR|HMa0OZOZmdE| zOP%Y`X5moX>(+vlDyRNk7ld3F1bPx1GIF-Y{*z|iU_PQRQmrQmA?sHT?=<8EV}C|= zQ^CWTB}wU9o)-TQ6zkl#+pd_xYky!zGQaE`Yu9q!fA`QauejpoU>HlLA2SH4#*xv5 zbh=_!5iK;2Kdqf(8}9#UyZ+k=X#zA{)2J`aEj9J=1TT?!s$`TuqpZm6MIb4Yg z8B0{DmrXS`$+4~;mTc)Pvq||vj0@S{KVsrmtu#OD?nEg((k)$$)^mI{Qo@srl}ukZ z+>N?KaG65sNFuQ~p4_J+$%M27@)9UOApT0CP?hz-I(|lNbE|a98IQ_+TcH%F+$;a& z`hBxFyCi80mWhJAyCbb>)UWP|dfP?j7N$W#Je4aLXPaD9bNn0oYUE3@Rq@Vp`=lEy zEHiJ82H2EyDt0NEuP*ERPvI?l3+#;Xz2&RJzWTt=6(0+0U9)e*?oQRI&md0jv%+)& z*(LY?wNX5djH}2)cl6x5u?cryJkOgF-9W?p+SaedE?7;FOL_codq(Bj%)waA%rlJ_ zXDl~eIWq4$=IdzVqr8!WX-x6WnTnCScVlm5J!v}d^O)=_6Jhrwz8NRd70AlS(U#UV z<&-e7l5qIV{20{KW-l# z5LBL59J_5NwwpF9S%GN6NlcGR(fVU zC0uu9pN~!MlBO9}xbXPZ*pH~4;`AG{d9%Ob@ZD%aCOq+jA7^j8d4|V`-gjZ70|8O`X7=0Iu%yS}-c_vT*q7|E+vl5`x9)Xke7TkLw8i zPqY*V6@P9dGE~qCo|4$CNMtUFk+m`1?!kSs$fiz-ZROM9tKc$@rF|i;*?q4|7tQ2% zn(y;W@@uzxqmaGAb;$IUXz6(BX>yf{A7zvBFG-<;akSqS{KX2437zY+txHo!U zNi3us^XbSL?MIq{pbxH1hVXA%??_LwPW|=K1~L7ET~1@Z=iDT8ehU~*<-Xlk)tH$< zBvO+e3m^$xDHOD{{XAT!cIERYPd2yfS1xAkBf36l!)GzX-Un^CiCo5?jH^iky)-MD zRMJZ=$b0;0B^-S_qoMih!qzSFX3yNme6QIks<3jDVA>FmwmTc0ovDg^j;ab<5LlG# z+iz{ByosGo<`XOFNuG~dd5@vhaj8gA?r4n1n6IF02}2*{TQiy_xF{o=eK8CPEr2x>pVKY$%rwp-}2d&0*1tA zF;@!Se^6&*Qy)A*qt^Han{{nC!qC$f|1>RMH-VLm7rK0WzVZyRj;nYF_;Q;bmNs7I z?W=lHoM#$;lt}uaE`j(}LKflW@c}#*`@0!FKTZkX~Grg+yaFj&c%ykZ5HR zh$5T+qL&lx5J5R8TE4&8@gKi3_i>$3LHTL9jyu%`ng2zHAwNO;sH6CH3{atd@7?OP ztp)R@F1*`N9gk>*@ub)F#XtPkoi?y?4)wd|dQ$6?K**HAySr6Qcip3G38O!1U4sb_ zk?@~g%ea~B^hduyKm!g;jR?o6g@k zhyxRd4(_Kg=Eu`6A-~sI?5fuoAIG9|fgMGSnQQ7tP21*jzSNgA>$@dQWd5e?nDGl& zJ6{I7`)X#e=C`dZH%xg+>q1^JHtg5`F`jo__VKf=RvX~DI#$zG{%|bWfb^b1Grvwg zL6+zsKUt25o(AYizCbhpY+gfs`gX?Dt7nMXxN>B{#n^}6wpr~OcQ}5edim?*McN7U z`i_OONXE3_67JJyW39#nt3vzPa`6<)NDo+7EI$8xuCh;&%_Ue<$E(}FmDeQSCPk=% z#XA|>?5(G9Zxxd{$Pao^D7}d53_4(Pa#sYA1G2FNI+P*!%58qLjGs{_>Z-S?Rx3gn zk|=nK|0L(aDh=!WCS9WwF3LVMn_yU>%lWPYBH%$0UC6$+5+5d$hKtU8J`T1CTa9@y zPknqhS5cE}MbggvZ3j+L3ji@?Xc6?#>t9C~SpH2%w#oOy$=b8@MZDx-DCX{MlAHZ4 z)qZHvdA)BhD4IMVVXpbGqOt~O7~VMrN|m*A$)StR%RZ@g7q->%y_`M!;V7)X!!N<= zIh!c$boe4Xq0>7R`CrcN{{Z@H3MYv;3s1BF3g{p|nL=LC!E1mK0G66$#C>y|gC7bh zT;XGB`(EbGC`j!yKvGnSl#T3muT}qoBvw+zow6%j5t67QGs%*xvAvFEOPh-AxvSnS zvUH!S`UgtW)b!GqTV@JCv(9svqL|no$7kS|#Z}$gsuYvu$<=eH)f+n3DRe;Bxqd_k zIFWP#uxKMiBw2(X$jGu3)|)yHa{uS`vv}IBdVj{XDutwf-|3FR2KkS$+SC`%Z6^!Y z3t{)b!MoM=+>QmIJHG`#-K|PSvdG=3=b#l{_xD^xpxX(nd#rx&dm86zC)b2tPAPw$ zJn6eW23K|f-PKL~fUxP(K=-@KmLzT@Wz`^&=dq7*Bqyv6jFtY{>P(rCs5+`zr_KTlAaNm*NJH@^Pt2l+rOg*KQpAkZ=l+=V-3llg4Nsd>& z6&Az;Bs*$Nixx0k?Ri(ZK8ZJEGJ%3znuDU} z^UkLyPS-5`o;e+GWKr6Dtvgb zDM`72{ejvfU+hSbnhW?1wumD4CtWCpjCX7BU~FCO+>qOv#l4CSCf=1u5*mO-h2*~J z>d<80VDni1+L$5XHN$(296o!~6O68tIFyXD? zI->Vl@*}HFfBGY>l)B*4B5yIkRO zF*_=3!7yFM!k`}IfZKunO&i{?T!hsN){YoxNB2$e*6GySm?3ZY^ZjeF+@tYT@p04L z;P7WL|CRTW>zD8`{u_Ug9Eas!MRSIeZi81hCORjwgTPJO*&Dxp`fGg{%~9q6D<2%Bfo|b^ zXns=+yZSfrhAkNs&=5>6qb{!S;xuG zgI%XMopuRY3s6<5I>s4tcR91Z9|BoHJj@CS?>Bb+%W)S<4UZ`&sjrQ^3Ig|^s z0yS(47Mo{3Zsgdz)7;9RQcuk{dAp^7D`uz(!LoT_-Qg{TUprT`mujxEa-yhsUp8%! zKgqpu*z>7K){ig>R?@!_r++ZBl@Avqm;ZrZ!QqhmP5cKVUr@wS7^wsTdmse)J`Z+` zu-w}5#Zr%w;gqu~dCg{Fo2QW1OkoQ{;qfT`psu@2;PORnF*IH6 zQGL?H_WSk)p{^N*R^`I)QCEX@;dQlo!F-E?X{I~%B!gW!*kf|DDXqN_FGI-ZRXFl3 zT7@V9ATb|mHM)vhRTk40L@575Q@6=&pa52~=XO}?j>auBw>SD3&AX1Ce1v$LoA^{t zcx#P(lLEIdr>ul@eA5O-qd3=H{+AsGHOoYV7DeB6KiEi^Z`UMiJQqh^`C>y2S1$iu zPSZO#uHCli`R-!LQ_>#Tl63xA{$wJys5M-FpS=L-iX^T@B1kGkU8${E!B7`l4|io zC%e*l#Q&CC&u+hUpOHgYy?hUJh|JsO6J)%&0oRF&Vm)#!$=U&r{i>tXrhcr&Os z*@@R>4C~=@*2>u$<|SPn32r9;?&syI@po_Gi%a=B24zI#-Etv@*YPX(peETk3xi7@={>i(ZYxXxw2VozTwdzWu!0lr(GgU9Yh+q``;m~~YhS#_K zhcR`^siWQ-KdXKnMt_HB|$iyr;%~$?q}cG=`^pY+C(H&=Z^t z+Dz8pKv$6nUP-j*pbo$afMp`MGm>1mf&TG1_#pO1(|RO%CbSvsc>LO^Qic|r%h)}? z)YjRiLjp9?vy`dlB)6{iXQ&FQcsm+C+mQ{ng;dfG|J^*grsZcF=Bwg;75l1pIS+j6spr097otfsd@x7^|HVV? z6H*mH6#vDuG#(N}4*d&P3qq`j2Y`)t=$44_LYYpPl^ZqntQmZCy=#ok>4{96Fzaya<-ONfA&hT&U09b)Ocj)Q z2S+TiOPCZ!A$|0^DB+jLG96Th?;_$i0lLGv$W8!kYe6LA#7#8RrSLyc!RLJUh-q=_ z3T%po`*a>%2j0)**ncnBvN$~V9_0e$Q4Syj|KSayNwXtM z@P?U##!EzRp$R!?VCiVy!l*bBQ5YPXrQFK@hX)QKZo=;-2*g&a#wKT)Zsc}FTnRq+ z*V>{?w?6XQcEW0Fx1jc9Nz=aEixCpR2mk-v^T!@|z4Ci|;^S7URiTqlnw)c+BJ4>K zDuar{Zqh;rBN2?`2fcbtT2T<;3PeMB(j16vAiC6TnhHi(e{Wfz(PlFk zxXsg7Ul-?T(xh&4--&AKSTI$nG&lDeJ=tdSZAaYdoimIrQ&1~qzWpeD_T}n@b_nTh z_4<9X&*sIB?A0SPbuDT6vXLiA8meH z6{ScC$w|K;c2q=E?9sKYYj11s*mYfX#kT76xry2G{r&xf*PC?Wdb>*qv4lTdCRIA_8d07+S90Hpe8app>ueT?hWc4{`B$E*wXLS+m_wck2!qi zkGT!24V)S2kk~9DyZh_97jb6TTe?Plc-avB$wS@$=+f|2(AvliiFGDd=~2DjpPxqk zR(G2>ty&hZd-3y~myVeBSmaYgzjhyrk2dwYtjF_u|6F!nx3AvM;>(~0cY`kDiGNKo zaeTcue`zj%+V+;(E?=pm1LVc)%eHAI960p+jz_=`?c5mTD802UBqd+IC2*TwboB(-}A)Ho(*N@Rs6p_;@bgAv{UY z-+Tm50CXKNI-+huZ9Mwns|OPfU!Q@~(xTzKMkvUr2qN|eZu?6G5!-Vs|z9?i@YbRP- zChtEWqD#WA2!>zoU_$8)^{&^t+_Xd5KgVd{{tRhg$p+-cKPf1>diMddX`W(vY&f+W_ex>(HKcp27^hUHvKLet5Fsp2={QEcLyFCpH(j~ec_!e89dj~|j zO+St=(&b|zls9Vb9*mEjUC`b!;|CZ~^ABOC<7P)}_V>Uq$_~A`efLDe>$C*z9SY7y zGX-9t*z9j@!=AJv8@-k1T*MpT@RL&v=hN^#baPF#q(i?wVKLMFCQs{m#&eqFXVli( zkee2+DcQdRpO>52_r@gW>5uWOpZ)l)oguh>euY(nk2~&f{KVVseV=KFK8l>v>lUKZ zZ}r|Y*zjig5?rK4KCX!mv2{iC9o`WA?A1bg?$)+F9>#@fuGE$Sa?s8R#@A`>X+jR# z8Eec&E~z>L{pqPYI&dM4W`-^-^tx~8lQsOpJlP%fHT zk9no<%%hlGoShb=*QWGboUmS{V{EnoQnHw_Ub$ynN7s(*;{FZ4@4;*S)Gok2~X?r%#%e zho4t|teAt(ywzWsjp*_nTW)`?Ql-ZMJc=@Y+Wo-ejTM!O%BvilwlXE7sdChg0~Dad zkRv+-kKP)uL<_fMjHWqCv@k#8Sq|wSB~Q#q&uOu(&8-sW1KnFsSTVgSesiP)K3sJ5 zq4DQvJPvYhc2Mcon_kXmF?!rLJv-KGAblsR{NdrLpZ6AKXN=80wYA~R^G*l5Z5h8} z`qx;`L4BGYsjPYQ0@I2aH?!(*wYw4KD0VAAw0oR+(1WJo4(}g*#;1Y?XUxmmTymJ& z=AnguWMGUoFb{*G37NQ7jfN+!l8IlJ&BM8#W%^_Z_>|V#O1(P;<7W#@arkGhAf(`dh6CT zH~Z(Taht1Maj10B@7}0IQ_sa_3{UhiIRrf(eYDy7so6hf#ckexg_l>&E7gzf2Yx=r!5jvgp`7XA*tIkPparSd)ueRF5{l8 z>?Nv{xhav0hAexR$?^(})F=P#veuKAHP^m5mf^5xXmMid+kSQU_!p7%?(UEZUdW6Be`JC&Kr1In&>SCv=t z9P&n}#^&u%9nMpzeN`jXM%4zjgZhnnvAQh@lt?pZFFm44nqis{&0ft$jl0%S8>@}i z9@d`GHr9FQvUG8}-*snoUG<&ysrps=%X+z?g(2Lq$Y3_yu4`~H_Ao{ob;cvcr^fG0 zT}%s28q-D7dsAaJ%zSE3xwu-EymnDTEz8)d>X((0_gnUR<;$GI%9FWe%53FcrGMTP z6UQ-puPx#wS&q>sb)eP1g)U4Ok*H+U0 zr2SEQLVHTK^J^>HYP~^(Or-y=Z7@qy6Yj8C7GEOn7jHitE zjIB%^OiN8_(95GRQcy*; z+i0Ri1{dw``ntNc`scc3n9Cx4dxK72Y&fN_VytNxXPjzSWjthfY;0ikFs(2SG<`HK zGEFe;HXSj&!s_rfKl-&?EVJwHka4b{j;hGGk!BidX6rebE=gak|4H8o72-CF zUSX_j7-@{QR9J3oVyt7zG5%osWSnoBY$`FGFug#9ZOo6(@Cuz}8CMIcsY;9+D9PZV zwY0s`rE)P>bi${_*4gPztF*=+3+tNK{#Gu!NS$irI<2duXRDOPq(Ue2v8!BkcFuKP z=cuPuCgYSscV?-h*UfUVrzlP{r`{?TlO^Irv*IpyWaHI=8^@c|@0W|MM6sWFPkFhR zC5mIrfe*hq*B_OO4x(g>-u(D+x!6sVY}cE=dus6x=-HHK<>G0vIqUGeTs$Vav9A_e z(|qhjx!Aw5*>h33xKx_V7LU>N%&exVliaO6{$_qh6(Mgb$`AQVJcX$KGQjWO}O(W>wAWkYiN(=gv@8RVFKUD_1Flu=8EYtCcrI z6_&S8bs(>nx}_>qy;ika-9Y_VZBjR-Iut{hw1?hP70m=qnC6&fho+_0L7T0O(mv2$ z)V9*~)Ftay>8_)Ve)>`R9Q_`Bx!%Lj!H{CeGF&q}cQdp#_BQ5V=X+^vRo{(8{RS_ zAb((9j-f!kKrd?E>+H2#byu_oGD(|cMVf`_qS+lZSoGpFaU^fX`JP%d^C#TI7wjpgE0Q5?%sH}PH>W*)S; zT=WvfQEYl~xyU37jI8>Wa`Cx1gnfk#69<^XO3KAe@`+!+en}PtA?5#F8MNHP9c(84f56{x(Yxl_1(!^E|X^uzV{*RwAp8M3qe$@txEj=oE6%Hy`zdCe{pCLQv_dIio zK3I$s2V`sdX$n>uHm}^;ee1hT)7FTqYOe7%eNs+Qz1B`HxLb5^bJnKI#Vs~|Z#RNNet73>Fhb?-6Vp8@Z{HIqbl)(!dS= z8~UuPRxs7Hr>M<=l%tOO-fr!`x{E5#e8Chf#){td#;5s`^}RPAD4DrgzeciV>XyDc zy6*UK&yd|MitN}W;|5)B-Z*n)ez52*trunt&6lh#-1K={hb?zaQ&m;$FO ze60;MuP+Q1n@U@**6&(5d41;kU$;KlxqfY(+{c;nob|?%t>;TWt+~49?$&|kLHq6( ze^~v8>9X#qVgK4-@w=R|&2?(ms3lG;JJh;%rb2p8->WRRW9`VFtF319^4*?3>*3Au5dDU?jr@>fX9h z(^_AQ6&L&)^{TQ+;o*L+MhC|^ij}oO@3byUZr!N4L_A1EzKxoS7t1dBHkvTKtb9|q z&CAOUoX_9lfDgk=zm-2ubf+`7@>_{+^p%&k(74+urBfz1d9?3#zK?j7p7GL1a=!!f z3kBYRSe<6^(gRx0jhwDRlq!rJ$o?*(d#J-*$WJJeo8ClRtW8IF=?uN)<^Xx$gJ`7S zdnh^5B9x?u*&-_Ca#y;`3GCNBoHxmqX|bm&?=-=qr~6@+pVB zjK-Bi?xwb*OgQ2o+Qa2idd6itZ6UcofV`RdKY+XqzYPuf1G&ww*`QlQb)G_gM17w^?nN_Dl2oW^&C~prVkf$UqVy;H%DC(qvbIv&XUJ+n zVJJyI>(WWd<-T-~%YpQY%O|w1;Y)rOq!f`DU7mlJvSRob+7wr{i4iOCPxW3g_CUzeCnj$nTIRP%28&>SUlYE}x|b zTpmrXFCjls-=N-bL?=pk3Hcfoa``Id(FHE=Bk>Q&1E|d(TvqR;P&nvVSzJyfGnW;H z4fK-Baa8XWNVsCq~&s! z`d2#6Wdpr~EP0(n-@Uc>Va`_XoI|cj+*+>5i zCBPAHQURBBbdJk@#@!^o#Y%pjN3Gvto%f&#C`!YO?v%y#4=UQv^>TW__0{@zRIdWn zI8a~(s+mc1P?C<*@1i0&l4rSetpe$8Wd9EOEuDe<;E0|S`3~uOh`3y+OQU04-cE11 zJe<7WLvD#@JPd~;uBJurA%{{am&1&HbRUl7t&*yLKu4&^qMjeH2KJgHH2nkegNS`V zei@zN<}7`MDAj9zp;jLeRnfSQkk3;lO41VJe%i<7y7Y|8MsoiI(~kl_A^J$;Ky%=T zF|?k`QFN7?-DLk4qKCB$$PbPU5u*8szc?(ft|$KgNcrnx=n&yqpTS388abTt#1b={mLg3e%M)e1+JV zGEtH|SJM8kSk;s11yt!#qe)e-z(*`s1s1dttE%P{_(-RiE~tv2{iM1IZ6w)?Fipu% zgyun!ymXO>n<;b*qSSx~RlMU-M&1(0DjF_ zKD~o#cb-1z={rS13$cWTD=^s|TB5*Ys|<~4I~*LI?sK_1xm1F|uj5tXm1^5i0vu6F z1zc`U=eY4C(H>Eg<_fiegQcBd4|x=2aoJhFlgwN$qZeErfnUynnMXmD5uK|oqIqz{ zdQ`+^U%JlaNBT%|a47JRe9WUx4rq5zigG~s4r!rETj(dzaX47b@3`zhO&lR#G8Iw? z92~lqI6~e|+qtPv54iYQGyf1N>sp0_!b*CHAr-Zi07&}qtuxua5I~- zxHz5m@lq_k;3l5xRe`vG0;{0(1I^(kkcuEm=hHE|&ZEU-Ulp>J{Hj9UrS+yLIAS3Y zm#@$ZR=ljwrz2<=E}14r^#E=_d7O1wi^Tp!Mg$P7okOfOuJ9zpeLzywfG4MaT* zt!N$`@dOodxdUD2rYkwPLaar8t|$dk6gLT^g@}H=n2z&kV|vHs1JtA@O+L3JP=ra8RSi;B3>(RGN@-gvf^gBzmb$@n!o#XNd66?Y2r8YP!N%31o6v_`zI8$=@Aemt#UzPMnJ=8f) z9Y7xS5$-@i^$|AXx#yT_51v%BiOVhNI+t6Jg9nTcb@o8?kggR?g(FTPEtgNxaV}>Y zZ_)=Y@24i7ka6DUCY4e>5xu3GMP+cXJ3ruZ3b}g0=%}|Bwnr2CsHdO2usse_A=g*Y z1?W--gPEiaFx3WX(*SZ9g>o~Wav(~l&=ESwqm}W*Ysh!WqaoyG#uysZuwYTy(qV<3 z_Be;E9aq>81KbnbG^3Z}3Nt023^adyVFSr)Ev>7|A;W8735Z;{3IbtE1>HH>o6>2s56Va-+ak!3w>^#}vy;4@e0k`I19BCt@C5 z=sJSZ&c+4wm1ngiuTW$yrQY1!ps3J7FUflqWrQNR0~K?%6Ru@X=j&xZL6~hr{(7DNleQ{c-6AAf-GJv{r=htP;C=?D3ZHpoi&!rPw z{$86!FS)a5#bR=qg7{TxKLzzW(I{>Nng>zprr%8k+}WI+L`S$&nCd}Kcs`Ls6cV@K z3n?(YDLAUo%dUpu#d4Y%Rp^NiwYicW5{9VzctU%+%S|ZBeuUXdO@BmX73%F2#GP~L zyJm`21DHo&-f zRtyqr8`qPOJ4u-BK{z-W-A5kIGKyH3k<>gE(RYSgG>AL9a*k3091MC?Jf1_lU?k6$ z(XCjl=nd+zB*r0}L=EE*9!7n+aiXaZr6=`1l*OI5EApt6r?sa`Jbs%#aC4LDO-FP# z`IA3)y5l{Z2sk+4q)x|N{#-;Gr(-S`jd$n_Pk6rqPp;$%d&xB(74#xMZidmgctkHK zAJGChIL#Jv*-Xc{iKAycx?gjSswD8PpFzF}SR*10Pryt*q|)pJ%w&Kuij0U$6LV7N zARMgX`$)hC;1!855_|w2(bmdx8UzQ?>0G`;DsDE?E*{;I7ezODR8C*He3=?1VIJ=@ zs9zH1(J#lHrY0f0hccn#xKe_W)B{7vOWb+BVk&*$@gd~?6XG?g`%jSDm}*lPcMjz^ zQ7Rlrqk0I zXj6XfSaO<)@Cj-)6X9kQ%*_az0a3a`i9HF94C*x-^~xx6HquT| zI#g*BN~dBt*huHN97%7vxk`2BAlg=)M_u7aK4;LxIhgngEt-SyZCcC25^WQF(iaoQ z(+e(3soGqa0BS#%Ppn-nMRw(T0edbF>E&;+$}k zm%5NRAEqmL&&N!D(AT5>aBz_}6|&?Fo?|p0i}9FBxmrY*cyf38z)bjp=m-6TdH;2h-0cLek^Mu;KL6;9+0C@<_;N~9bd320=H<@|#Jl*ATSCTD+ ze3)fWQ#hzOa3SQ;6w6IjQbM$I(7o5w&V^{keY(o^GWyKTF!EZ2X}l<45lW{ik{dat zLzFHx4x?foy-Vk~tfIHvY^OSlAugxRi&2_S6JR7?vuN?+LQlIS;|m?FgNMETIFGNQ z7u?*ZYD+NDaca8+rF;tE=044VDD8?bPBR{zM+dpwlpb&sPWDS7HlgNAQSzceFp@7s ziAz!YWm0i<7VYBZHr?c@I8X4>0&18F)1UgLqIQFEF-?VoL2V{vNyQ4L5@2Sy65X4I zYU@ARRKUf$bcmOh&?6Yh`%H2qoH45DYf~#+kD#g{gm808;s*BzxtNU`oG5)yx4Ds% zRD;?4t}UY`a4?kXuYsIK)4175Ib0k?rM$G2E^{-GK5?;}>S<9rN&eiNqX;eP*`e!6 z%i-XFSOi(}EQ`)+u^v?PhN}z6RfpsYsHav2Pt?RrYxfw+zcW8I!oL3@lpug z<))Nm>oK#jMh!KEgFP^CJ>(q}%S{(j^5|14p)wxzqN`kPLZ7+0LS7pn>M39Y8ul`s zrffj-^C=ywUAp$Yj<#&T_FG2hcpM}C3KXTqrutN;2-97s&PAxjktT4npB6!sE~lHc zmPZ*K=duUA;If2urfM6plJL$;yN#Gj0EKKs_$JMPierG0mxAaZH+|^=7q5|G6G}Cx zIX6lgvlobmV^8N!$C|~~O{${%^x*X$_u1LM^ai@brzoL!yrNCy zUW|$cvu4yC4z86$iy^O~CESdp^$_{l_+&8_&4XTYwH3K+LFz9*oNfaXbd+aDH)>lXZ>_4WDTO@BV3H`H3}SzZ;H3t%oSSIc#6?^P^HMs!;UaR#-8gE8CiT^4y3H}PcL zRTx@^x4v~E_)4< zs_<@Qg|A((;Z-gzg;s4?s*v*g0wJaTLLp^8m`sucP_62%T4e195}Rj>86|eowmG86H=5*5*9kGEk3<%*={`Z z?)Hm{V25pau__I7&x=_+hr0e=5$PV1*J5#vg2}&@-*Dg8=xAU`o$V(#HQlx~rRTC= z$ozXn=h_C{!z;?$lg;b$_ivoN{`2x<#xa+i_rAy5X)i05V!^d9D{|~pv+KW^bH}5k zCbj*eq9L9Y_D(GST%}$?*H9rG z$|EfC{Ut&Q-iZ67BFeRNiTxpCz0F0pKB}(IDHBo#%YQwE;l-`>Tpp zGDlX^bcqsPRZK^pd+@5FxokZ7zwb=0uPfT4y9K_k2<=c!Id);+|xscyO> z>0b}jJ3V9X>ElgSZ(o&=_Dtt-&u42pb=}P+>RqMoSC`69z8`p(trJoz7G;+y|EvfQ z@t(=$w-rA2%W@~^Le)ZwJ2_QUe6T-~wW;Lj=3%E#l~s9H(Y~J9&~TF&7smFx6pJ;) z5Ox8!#Nk5b)r{zL^`fSk{mof5ibX#;K8tkRtyol67T1}_c^8Y#D=9u@d|A{r&C#6Y zQ!JK>3I|QIWna=BnESUX7MIw`N=&)xhvo}yi^Wa#6h0TjL!|f zG5_FV@tmTu(M)|b`^|NRS!$`F8Lm>(a&}>OvDjVVgC|xDR7INWj3^eTiHf~>qjGxY zm9fka1S=hITT*0DBY-&v0CGc#YJ^ zI!q|WN11%h=U`>k6-#v2@@A@v%{QkPi>D;AGW}}W$cht-#hbFNx**LymXm}U>~CxH zluo&Ys(CE-CzKUejhD$=9mE1>6pI(^b-E+UKDplN#jMH9V)3$Ujp31Q7L(3GOmWwA zNA*;>j@?A5yP}_J!V1?FKd^?gdF;LJ4k@(J>@!N2?PK&SbE{|TlsDMTImO}``)R@cze?db=W}|qY4dr_-|4R?U6p%SDM~8E4&7$e z1yzuFP;#;8D%w9YRaN&@x~oIX(^87XV$pt!QAzVvm()v{_d-7Pb4`ir4wbU0C}ku?QAt(dr|SnMk6t4-3bGzY*h6=egBP4(m1r^S3R!;Jg&ec0tCym5b-9#9Kav3f8o zTgoT8sz0S!!al$!=^*18voaM;me^m>N^|FAz0ECS)6$B?tN7J`{pSAZXp&SK&+^Ql zRuqeaYD$;reOSTFRb~P2Nf5K!8OfeKW!D;NyG~*=kr#v zxu|6OV4I4Y%#UFEOT{AA1`FI&9Kgm{>=w4fV)rq=BIb!Jn2&_V@30VyjbsZf_A)E7 z*nR90w>U9`Fj2}gFPWRedW+%_HpGq#(QJ;zR$;3xb}c(&vFYrC#fs*JvQjZs!RE&0 zik`CXOtUoeSpocdifwqG_O7}rJA#sj*qA+l?Ju3HPh)MS=Zap^SmSCo9Ntth!F&+b zZ@RdjeY%$`=7=>|=KWkT3(3LEqdZq^C?>N2*s0PM>cgz$n{o*@O18srCASX?c)+tN zSR`ze^txs{y8tgsdLvI{5f6Fn23rn0Ra&ZA!`{Kmloc7&ssgtB5q#-qO%AK`m`|b6 z`m-YLiMi&^PjbZ9X|8e{6aV5<+p(#z4P}2A0+mrrY0)mT&s>x4)M!}4 z&pb!8!)mq%o|i1o)LXfq-Q}t{mjzZso?SY9$YJqt`-s=r zE?6(=3EfC`lLw`aIh~obIy}jH1N#n+r!-eDWr6VUCWd+EoPz%pRNr1oj1IO(xZC(o;5rV=~7)Lo5rI}8>uelmKx%V z+y4^#aF6|=mi-3J3D-?YAJemU%NA6%>Fe?54{eoeCud$^WtQ6hGP<$rybjq$c{;U-3Qb&wZ(=OJ>vHdC2Vb&*?hLvH0UP3$q)s?H0egsdA1F zyUMd=fhA^S*2a%QoqT$heB%w<_zZMxm`K$B|P zu~GK(hMN&zsx~;>({ohvq>KsTkYD{K*Q@qd$mNAQCNPsy$}U@`j8bQ@Pw*N_SL+Tk zubO;*LyeaMHacClf_PBZ(;k3@#gMzl;Xi^;sGW$=bbf+DPgn3?yO-8SUVH@OV4(| zT_M(Dy?uB;zGb?^F2n09?qnVjZ zB3di4U&m3OCT3Bzfs`(VG%+CDyy;9ub z=5l~FKlW6b)OpjGK7&u!tbQ?m!)sRLk|#Dy{*}d=E4@o@J0s-cK$+*r`wuo%)|c)+ zR8hNK<*`jioo_VqR@kPY+Be1TUSH~{9KA85rf>M88S8#CEGd2bpjnF^V?Ga?*y7f! z3EST4N0eT9a=Y2w5l=?+@;UeW%&mSjVaw>J8O=M6`C($SHuazUQnFEfaZUe+16sR| zemLe!XZJt%ZThvJcFe}vH{2U^3yB`pvR$7~tM*0qv3HE_ zWYPIsp7q}i?H&4OXUBIf_6^bx&8N%$UblzV9e=t{A6fM71g5Hi#c7hN@3_kCykpf% zflI=F>6<1yb?galBh>x1%*7*UX=v}ksWloMO)`vPw~_7DWIo%?MjoFdZQrv~c*&rh z)s~+xDO{P?$~;{@F@Pql9bThB-;3*4j%7_;QMWffws_#n+p6D(hh~o$RDas7r$txu z25#H;ep1J$V;+poZQ1Q!hYfgkhb1>pS952tr?s0l7&~QbwPrs*_1LjeJ$QrS*}3Ku zhyOf&X{U*=ZfvX0%6P8JI^E=wb$9yJ{W5Ib#Kr9b z#oB#N?P?7A`EE~R+}kZ<^SxiMAH8i=yW-IY?}N0{IJW-dX>g*P4|fzRsPJN@qILP)co&@cf_pw)1!EF#HXih-|Yc|dbVG> z_iNE}uR3Gzzi*&xeLXVxTK72zd<%6oK8?OAKft_Os_@-`%jO8!w!<(IdVflfK8`iqdGtt!48MbhPK-sL+^LTMoC5!Wx0Cy7xqEMtcSu&)*e6`-Bk2Rl3j5(Wmu5?5L$bm?p5fA5$y`WQ z*o~81S}s`*$qF0&fJ-@&97tB!++QIj=SlJ)*$BY){LiLDQ=0*;M2jpNBcfuXqhk1C z{PX$_ZlRBL*qPqh9)F<`u?5f4R4EN3$nh!*w0VII*$7!`=D82C(ol{A%`S~ zAlVoZ5gp67a8yiWf@e^yrN6a7M>`=ofh-%r(XliBZz%vX&ITcPrTFi48mDztaidVZxr$p2)H>Aapk0`Tq0r zL{^+M4p~-MRbG8ElQKv){yrxCvjznb6P}lzN0trVt)e5suyVrw-WO$l6 zIKKTI|EDbt>>42B8;yj1u`yF;`3%GVe{wM|A=oY$X%^TC96Q||SJ`hL*L_e$06D17aAXz5al^IH2j~cMxv^db|;Z#g-6<}e zw>uBX3QOV3<9o^O5+obJvtkmb{N25*rwP7cuGn2cmKC<2@1YLY?5;twz+Upkx4B_= z1Bwl6RRL3?rbYbS)JbURExTLDvcR-=FkSK;yE{;9{I?11EYtd8x_fr_kYytvIwCa2 zvu{#VVraZ==X1x-Qf^m{EE_$O;u8`*2gXJv{L_Ycg1zv{?iI4W(MSjgjgP`X;qNWT z=jn{JH+FB3W`PCX;EVXd?gJDX)~5E1=Ldkc-xjhPj(VT$J|W8j(_X2u&z|k zkkFqZc#X5sdIy;UvcAFE;A~XK!Aa%>%>uKB;+|YxRvn6s!5A1=Pb&Yc3m44MRpyE; z8u-F+9-_DtQj?P%@+Opcnve73AJG8Y&@C3`NF6wfVxgqNt-om#&(fGfJD3?*6J2Co zko66AaKm%awc{+bx0|dRbQ{**6BHU9{m&3;5{`X6WId2&gAE?=Osp|xu3#qw$N~_s z(K9MO{NEdjH(?IwE$fXe8$X05M8roX{ikau3lgEPtS_=GuoAv#&VjN(C^py~3<7Jg z?4wUayO9HB0}-;}9~PUGkjO_)==XfCczJ?hvSG-w(JMA-QuO~E^qM1UjBE_DtgvS1 zcvqb$n+VB9@RZPL*kAwC;vX^LB-tcn*$7UIh=}&=g#oCo34*|TM~o~6SvLA$$PySa z%QGN4>f4qUgjra{ak4mMeS>9U`Rj~~m&HS~F*qqE?0?UC^98ApBuhe;jlQvy{?8~O z0T zVuAJNN}DuU8WbD-B0}R6J$puk{%f2+AH6X{mVqn_tUK>Pjw@sZZ>mB4=4eq`AQj>VXC#DA`kgyG0KAUl988>~k#w&GYP1P;j#Az(QfgdlXpy7*Q0E3$0xvE%<9xZP0K1=$5;Sz#Oa1)TF0*%e4O*x6o~ZxwzFzb3ne zfCX0N5EeJ&k?au^8~$NovGL*m8l_OMqZx^_BNU);E}k zA8z5W6kH_RB@d7fK*WZ1)DeJDM^tRww>b^P^g;3o_ z*{t;heisD7$^Dza=0`Y9ql zJU;3tezvi7&U(m-k;fp*221J0_m%(z;^c7%SYciGb%DcA@}D4CVDtFZSIA8HOei*R z;Kqef2yQlE`fsmM7=q50&qkIF4CNCNF@kAgOMxATthw^J$g;phevRfhUp^m-6*k^- z>u7;|0VFHzuLEe6<0APYNLJWxtROeXCGsVZtgs%3AvveYQz6-4*+cn3ygg>UT)rFu z3#=acu6uHZJOhf2;JDDR2%L_h!v5Js#$dWEc^0y41V!K|{@*KPVH~n@<+;eR(H}Jp z4gK#eo{7j($yLbu21~|atd6r$ZiHsT)C28hcM!32%$MgQVgvcd-Q5w>KnoJGTFB-t-#x!f6fKz;y8Hu^_vN0lRQhcaoXk*L4nFH=&`C(*PVSA78m2gyk6p|Iz&C)l1k^ch83Oj&K<>q)& zeiD)u6Tjl}y(Yf~#YP)npKqhLe|D5QI2}KdKSGujcH=g$>M!|UkgPD%V=jG>e}QC$ zrCHk0LeWAY2v*o^%b~lKq7@_ytQbk|zP<`yC^r6mqrtY=?r^?We2*+E%#HVJ$Ign* zkgTw}mU}SW6x|?MVPpA8#<7>87bGhzgHI?Kq+sjdG;$oO7>bw`_JzkBhAW0cvcO`o zZry!HDn>%F(FfP;wi`CK_O*sHRxuV?R#;1nP~03t6`_!N3#wuc=SYe$` zAW1Sy!A8JoG;pqBE@C!@Ma6hpk59PS@a@h;Al?#~ub7W48~@6(ExiyZ)D{*inDaxt z@xgw;e@Dl3MLH(3!dmmY!r$d6av<3Vo}LsMAMu~Fs^v`wrGl;GjdL_83`n=avMqO? z*C^INvckIXo!_BMQ3lBZyUG{X*Q_u@u@TI#F>E(YzBPC-dh~I{ab#IxfAL|yeT@HHAfR1y1gY>$@eEntU>?}Z>quTGSSL7*+PqY}M9_xy zrf3-6g9!JGiN$?%R3S&deXV$nEDJ0O)45CDD%et9f#kh{ZRC#QN5x0vSYe+0y%&j4 ziFJX~NFuGoCUK{YqLKpFMm7Rslj5Qy!acv;i?z&Aj-{_$sWP%GuqQYKx%)a*a)M%G zXzc&ofkQJZ2`NJFO1+U~g`LJlt()V_N;4r@VOw~AaGYIfHY6*|?J1=1=2n^u$;RJz z(%X0jM*V%UK2tbQiKSpCXe9Z)5?f<&Jnh*@i!;!ky|y?D>{;zcJZG0Z>t=DD+p}{9R%P~^#aUaK{bg~^S7r^cz>OR~SN@E5(5$eNmK)6e4*obv*a(Q9 zg?o&A1O4-w1h=J#(_`}0j7YdU>b-Av%ir7%Sru4I&3Cb0djy6sDKfy z0mYyU9013`8Sopp2_Asw$@upt_yk0WT&M)9fLfqFXbgNnE8q*-f$u>_;0HQ`p%R5K zMN&yfme>nwNo8S^#6dVLaTJb#qu?0$72E)KB~HRaiL>xbQbl+vsVXG@DXAuWkW?4G zNL&OvX$`?%>MB%`))ZW&wFGx*Z2=Dk5SmEc1Rtrp;47^wbd=T;x=HH`y`&z(Sda*o zN<9UQ)JxbPZ6NHGHWW@t8wqE?IdBnN2G_t%a8K$jJOod{?^5q%;WeE1(#FCUX%oB= z^_@`JuBqSvs(}V}&4i|)HRu4kf!^Q;5DZ3xP%s4~*)wZI!N zErk2vckmuaWXUZAM_CJ@CTJ-05n6#xpf?xi=$mQjh_ZKnDuII#3LDfRl>vg?ow)!h1zW9Jc+0s-PCA54=GO&=zz8{-7Ti z1V(~MAi9!YvhWj}6p#k;00SGqc5nck0GGfW@C;M{(cVvR1hqgT`%Xe@&>8drgTZJJ z4r0I@`_4it$OT5Q7Lr*vfnYe8 z0HQzwNU7XS$N(Bp2sVK-a1fjTS1NZG?t|aKdmwS>E;xdkz%v>Dyuo+C2lzVl5IO)q z;1BwO{$L;&0meJ{3zNZAkO=01g&^0Vr?Ao?K-lWgOE~DzTe#xTM|kPbSNQ7CPjGPT zFH{Atz|C=h;Nci3G;;hwXzCawB)4=ND71APBy@BfEOd1oBJ^||D)e;>7KS>e z31Bu@0MeYp1trjfLa^cgvG*o$SylVu_u5RN#TdiXjcXRC`^=R$6>M?i*o`=2g0qld%-~fCB z-@#$<9pmRj?P3*Fr&xv7DN*5218PFuI`dRCG=g|&UT3~)0j(ed+Se&nouDfWt5c@N zK`zXOGPoG7fa~B^*Z}vzL-05}Q>V9gRw9b3Sd4gfy-e9+zjjCUf34tD^pJ+ya;c?yYN1I2p_|z@CAGg|A6n{ zdpH6|;Yauxj>9Pkt6QdOLo~#L2Qr{Nbb~%H7)HTF$o27403~oCEQKp!C9H-U;byoM z*1%d=4|l>Q*a8p2Bk(9Z0nfoscnx;JTd)V-hIe2uyzk)KS9gK>JA4jb!MAV-et@6g zH#iL;^%kfaPzM@76KD#F&>UJoDx^be=vD7R)dvQ`(0Ys1aL9o%Fdint!YB27 zi`0IEAL=buf7Dx|!s;(kHR@laYSq73)vbStimJa zcnMyH*Wqn=7e0V}Z~(r8!|($f2j2;PPJtD*RE0xLh=eF;1o4mz?V%rxgDH>?g)k2m z!7{iq%BPk`EmNyuEoitKHpBh!Qq-mDb=U=O!~0Q}`P9Cs%hUm=fS=%Z2x)McstNTV z781Y%Ug!utpbrd&9GD2xVK&T%a##q9UmclZ)4E_dJz)H9UG~5f@;AwasUWMK80elKy z!yz~Zzrh)(7ITHF72~@?H9%+riO>w1LksXgDx^beXa}938}x!cFaQR@P#6v4U@A<5 zT$m2|FbihGTquG0PzDQp{49h;unew&)vy-sf(PIccp7%X>+m*w1pDD@I0Qe!Nw8wC zP}QLh)PwpE1q~nu8bM=d0tw(tgsCtCWURika)XM1x)1~LkPI13R;doq1Ny;G7!8wPI?QRZT9v^? za5*f8Rj>xu!{#P8sz=}%@V(5>Tkt-73SYtDCO4_$a0)`=Zc-6Y7h<3(w1jrh69&Wh zxSLfTl)w_W5^jvUMd`R()xB|R)I;zD?0}bH7rX->#;x(G{c*Rcf52fl4!?ud^fpxu zYC=@gwWN?mwcleznIJ|A5-(@Ok`JCH%wT5T@{h!%y)K zD&g1ohtw&s5*|{a5DpPgJ7Jru2hk7<@d*#B6i9=%4jnQ3Bs{7{z*z82=4U$0g4s|4 z^P${fA?6}j;;hRt@W*k&)Nrp;bdNzGnTo@OtrR?S{f z8ITDbpbK<`o{$ZFVQjNk)kK&IGhi0Xff6W#3*jP%WthU{a0Ofq%fTlin8Je&4`T|CJ3NIcJmatvQ+UPTQ?DZkZ#wM76h3VBy3M|3 zZz$nYhtDyEFCD(d{06>-@8Jjd(cw7eiDtXhDX@}usZgj6wIK=`CHZ!#1cVewgAPe= zsqCcPYFN@9H8JUJo7|*#)O45$3*ln8JZZ1`8(a-5;0Cw}*1#QbZ_>N!e%J<&!!xiG zUV*pZJ@^zp_wn-;d<%yhe#Sfrr@(6dt_p?fP^=4qw7C_yzuepp*kD9BM)R6yE{W z7$FW4APG{S6=XmrbbwCK4SG5B#uWOce5nSce5EGCOqieYwYntb8+9ez1h>F#py8pE zZ`G422i0pS->J9ZBlz5xQlSpO*KiDeg;NmHqC!PLq(cMD7>I?&5Z~gEYSH3*<$+cX zZCV^wLgyAoYk9&7Q7dLH(`d+<$*U)7KBON-ywOYQkh)q!Y8 z_nc6DJSWv8&+lp~Oox0Zfcdc0^M|_Db4uL;_rQIg)9OLb8MO@__9#nu)ZuZ=?eHu- z4==*Y@G86kZ^1hr_Ncz^v8;XYDSQqG;2&@Zj>2*H1^$3jaK<61WsoI=K?Ga?kx&<+ zAqE;j6G&|tY-K=O=mb5W4-E40lLM2W1TKS{VLfbV8Dc%vGSqq&UVvBOEqE6`hA-ed z_ycOEhFXcxI<=bB1$w52TYXZiTLV*TSi@2ytWl{KSmRS`T2oSMSu;{=TLr0gthuR? zmaiR4{VLVKPsW1a(!5k=oQdj^Nwu-Zs!Bucgt9WZQ+}6q$Z*4@l3+{pYU>iKz zD#3aZw!^dVBJ6^_@Fn~Vp=k+L^|VB*RvO$bFx*19zLOAlSFd*FezZq{RIJ*=nU*|c8P&a`anWq1YNOzUm!N$YF9 zo7Ug@I&F}35RO1d`cSJH_-gP|6Y4-cXb4Rp5mKOY`Y@|I^iCgP^?|-H7>2<}7!6}# z0!)J$FcS)44irNvEQX802baO$;HvZyKIyNLVr!0fi8a@IkyYZo*qZOX#47VHwU&B))|K96)^*-Xt=qkqSsT5VTlabY zW^MOgY3+npU>AJsy~_IByWINHd#%kkn8IN=3cjED`2~LSuC%PyE3I&-0X3nvLlkBr zv;uGI>#Vk|ueUn3zQO9!dX<$0eV{)Kf#EO;#=>}*1o<$F?-9&{3t=%_0++VF(Pv$b za0SSR3$B3`a0A=~Yv2x851Zg2cnWsH8}KfC44=b4;0PRtQxL*u4r)LoG=z9afedI5 zU7%|l-;Gu`gznG_dcz|q2?t*(@Gu#hb;URb! z9)-u@Id~P`_VM!(d;#CV5AX||g3!zxtqY(&G=cSEF#eeeYwgdgBX_z8Z7xoDRM< z)+B^{m;Vps-O!b-Ra?tr`Ces~0)gs0$X z*bdLZPIwLWzz6Ut?C(VSe~Iuld<#Fp9}wJ`kU|tRfEZ{DO(6l2AO$>-3Tco5Ug!wD zU?7ZyiI4}gVLmK^WpEW-@8jndxC8EjE$|3D4KKj!up9QkJMbR74cR^_4TyjXpeED-UtNCcK?7(Av5*L<&=$Hv9~cUwU?NP1*)Sg#!!o!M zR>Dni2iyhs!z1t*JPA+3Gw>YjfSp}P|Bt%dW*zRb)(Yu*yVa=c9afvJ>#PA?*INT& z5DbQ4Fak!wSQrlzVKPjGX;1+3VF_FY*TPM(7B<3W*alC+^YALX)z!D&dJo|f_!7Q@ zWAGcCg43Y7t+#?87($^s)PzWgf*5E5agYElAQjp`JLmwNpfhxVuFwN|L2n;F{a^qL zf*~*rhQm0>h1pOF7s20PIjn*;umSFchu{f#7G8o~@Gk6w18@)y!S`?&j=(YS{lw4D z@GJb@O~}oPz@rWHq?V?h=nH56cV91q<{xfAq~=@J@kP7FdW9ibSQulSO`nI zYoB!m!b-Ra*1|^E4BOyIcphGbH((dM347oj*bDE&$K5wrpTOtv6&!>^a14HhQxM!^ zgB1qhP!sC**l0!f@NKl3BD8?k&~W`c2oA#$_z`}BU*R-ZJ@2$aAROvI zLud?fkOVED6?mZobcLSK8wSEK7!AIBeip)2uo7;9HK5^McnBWvd6)Hc&%3P`;0@RV z@4-j#3H;de9_v>)0e`@0uzKBN1wjp{2aO>K(x5$bg3i6}@mXCFxM#5+q z2NPj3Ooi!?2Q#4nWeLTn5WwHQWkoLBl<;1s;S);K^RTd#oJ@FTrc@ChUa| z;Zyh?PC>1#d#osE4DpZxY0wV3L3Y+AYhu>D*3_)c)+{K2a##$P!?kcd+yHlG-Dhpd z+G0HfkNL75u%6D^YCV_rko7{=HtV&lhpoL?k68P%9<>g@k*vq9Um+;_39AOw%YM>o zl>L;|47}Oftxk}g{fsp@`&nyL_H))mn3?^&RSb)=cUtr2mgFsuR4S-?xH@`_ecXXk zs8{KsF%?z|{YhMf^{_s}Z(n_F(+WOYw}#*5Iy$Tq<${8 zg0JJPN8d(oMiZx}Ja)(m(`%7y)cHGyWX-mGBk64fVzlnZZ(kkCO-=L#%`2?#A>rzs zYWgVek`~I-`~R%>6Q0JpKEI9hJvgkdha}*mK8&VjgAKp9f$DkKmaK5q@Eg4o%UFF2 zL8@m*Omxt*L3$hS*I4gFSxw*Gj1bnwvEzZ2sOr?x1F_38x5W^@&&pYH6@;tJU%S#B z|Ipirxfsnc1VSOP9%sUG!OkySM@Nt8W$`?$rITt^{ObR+>r71J|HsDzeGRqU+nTgc zo?hp;o<>Z^=->IRub<~VYU-oBVn%Jh&vshrR~uDWUO5sV9;51Z+>XHBdK%%Wp*!;1 zLf^q}oPJ6&K!DRl-|L;k>|55&x(7)St-Zu{m`>!kq5c?6BRjX$(68VsPhZRXx3S;9 zrgekP<+=5AI=^*w0l)D&i{E5@H}@s$J&ncf*WA%mN7;Gic@n<5z6`mmZb%$HE~%}) zb<*garIK@gM(@#Aky0kjFiF=|WK3G4?`?c5Gh@ggg z8V-_dIZ7fcUcPn2)^V>I7o_L$A~E_SGU$DEB$bE%Zd)R)`9Uuu{JnGrA=h<9ZT`)h zm0$dIO}==#y;p^m?wP1kmFn3_m2z5Tl=7 ztFKU$9{E^6; zm~ixBi~M4r3EKqQkB2M$5IYIuia(q%@-Cvwn;ow1{@ttCJZ-;==&FQQTiNcrh+UO1 zI)3yY8m?aa#jENE_#xq~IPQd3j}Sksi8>#%nRQxUgPDT)uw(ASOy#=uUfc~B!danh zAzroTj7JS7p2ZyGm;)VifMfP23`t3HCf~#7`%+bMvR5S|SGPQ>uU>V4OlV!LAI9Vl z0qOaBjJfeMqkjQY^u0bbX6~01g`ks4FGUe6LihcSF!XKmp=gQ`VuLPK`UsBWM5y(Z zqe=gW{3&ks+ino1*j5Njv9fPpk6_uTdp%~R$!yMb zvYItd%7ov+e4i_)s`z*l!|nCf5mXIUkbVQRY0y^Q5TSt;tb2(?rx21r71bfDd)0D6 z5=yA!kR|JT`M>8(rm~RFNydMpr0R63lN1@YY4T@ldGT(NY?$pO>7;y_WbDq1OEhQd zz281jCVG!$j~ zfvwc+@^IDFicpO&@Nlx-=q4A2t9v*ec(jIJH*6ATj;eF5SLIULJg(bhGR)G`5u9Q5 zyX9<%y7g29pK`F>_o%RVnaQ)hY9iZ#+?S-A0A0foF_*x?n-yx+r(Q|2WS1<7`mB-i~XC#sVio9aqR%C+j3sEVs4 ztA0UT>$%()9aGJ|FH*g(5{YoR*Q*-hzM5Vq_U*);J@dBxwh+13vBzB-0^gStfh+!K z2uaX_GlCvfLyx$t!s?@UJVE_p4bu;E)d+L9V@5t{uG1Vd;cj!?%`q=^^y?gRm7{;b zLo(O4oRbwo!!62rWgJve^-qBP56ANU}E5#rG3IV*N>=c89BNc^|z7`)&l= zzv~ce|F*lrk*D!b+|=6Q2;H|k!W36?9U9x8?PzR&DiCac;+{dUgOk}yUq>kH;LIij zCXi_NyV~udl}A-@lkH#JvyOj55p4gKxWf7e9LIam*moUqHF3{5n(kX2f0m%J!?nc~ zK0&ZOJdGRs_VgW&F!Vu3Sn6ulqp`#D2^w=38e3@jkmGp5^Nz5@)ogJ!yIjplG$Vb( z$XBI{O!Xx4ocUhGSqLTajM-lDtC1&7_p05FoHNm@&Nyt2D3T>;1MHl}*P_)h53((os?R&7BoiJ8Pu2UZB{9jlh@LKD`5FR?u*z_pE0e zBRRGkIWttM&|&(pE!$z#HM@)64x>)9Wjl;|h%MV;)N^gw4x?Ua%XS#`R$I2isCSDT zW5Q@E&INR%UbP}r|C&-^SyX)W^s)_%r()dd(qFZD)iK)Qp}Mv0YFiao*>sHtQkAU< z_o_E+SGl&UFRHlmSF>KV(RQ^8SJ9!y-^fd)yrolFhBc9=pIgnkeviOSBd4m34mCan zR<>d{qNm^IxgzVM+!cb2UC~x^{gTR7+)GvK`ZWOESW;`Fm~LtfMZ8`}?{nV%l1PSUK)=n_xXVwotOVDg75^#RO!)>ryC zW)JCrw|_Oi9 zmbTVZSi_{zE?(s{?hDb_y_DpZ2yRzo&uST`;qD0TVr>C;wov0XN7%#-cK=|PD->g8 z`*ocwJm@;!C4%jHQX5^%^*!!J$FI1xj$aR^BGi-)QD(1JDr;D{`aoaGqwCpWz|sVf zj!0z?_q(3##}o4mtZVT=`wfa)IbL_Z-4UiB*uh-t3hNQfoms>69=X#FDi@VOt#z{# z)LM5q-V8-!zyI1anMk{i%Pc*-~n543qQ;G?+EFxu=G~miLZGis~z;oakA94*(8FMpjUaM*|@G< zg;h)UB-6B#sQ4?FNy7Y<%g)Yaak?QH>H^7Y$p|e)kh~VB=ec^xakgG^TAY5})qf~@ z^4m98(t+8gAhE8eDwTlm=Rt8nURtv&XffIy z=8jR!8O9y=D3Ry*jM+6OTooTRvPzW}Oy(uq@(o{f+PacDuDQ6EmgXd%sj>B3w_={K z_-KGmkH4HZYx06UNRW?EnilAJ1`O_fFX)xMX-RcYTwYM~Eyv~rZPHsh_u>kxgkI=g z%w}O`NTcH}q4Lmm_zlM@2D2GvH^9dI6CxWJ2b}}7d4lWhWH|V z_j0+*Gp_M+px#Q(C?j6#y-hdSC-bCcX1VILcB*RACX#PNWisXIQ9jC>*Bhy}Fzqc

my(5y{#~rmF5- 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 Date: Sat, 25 Apr 2026 04:59:28 +0300 Subject: [PATCH 29/65] AllCaps accent and refactoring (#43666) * AllCapsStatusEffects * refactor * review * two minor changes --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- .../Speech/EntitySystems/SlurredSystem.cs | 5 + .../Speech/EntitySystems/StutteringSystem.cs | 11 +- .../Administration/Commands/OwoifyCommand.cs | 2 - .../Systems/AdminVerbSystem.Smites.cs | 1 + .../Components/SlurredAccentComponent.cs | 4 - .../Components/StutteringAccentComponent.cs | 30 ---- .../Speech/EntitySystems/BarkAccentSystem.cs | 46 ++---- .../Speech/EntitySystems/OwOAccentSystem.cs | 52 +++---- .../EntitySystems/ScrambledAccentSystem.cs | 62 +++----- .../Speech/EntitySystems/SlurredSystem.cs | 29 +--- .../Speech/EntitySystems/StutteringSystem.cs | 135 ++++++++---------- .../Components/AllCapsAccentComponent.cs | 7 + .../Components/SlurredAccentComponent.cs | 4 + .../Components/StutteringAccentComponent.cs | 29 ++++ .../EntitySystems/AllCapsAccentSystem.cs | 12 ++ .../Speech/EntitySystems/RelayAccentSystem.cs | 37 +++++ .../EntitySystems/SharedSlurredSystem.cs | 3 +- .../EntitySystems/SharedStutteringSystem.cs | 3 +- .../Entities/StatusEffects/speech.yml | 8 ++ Resources/Prototypes/status_effects.yml | 3 - 20 files changed, 234 insertions(+), 249 deletions(-) delete mode 100644 Content.Server/Speech/Components/SlurredAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/StutteringAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/AllCapsAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/SlurredAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/StutteringAccentComponent.cs create mode 100644 Content.Shared/Speech/EntitySystems/AllCapsAccentSystem.cs create mode 100644 Content.Shared/Speech/EntitySystems/RelayAccentSystem.cs diff --git a/Content.Client/Speech/EntitySystems/SlurredSystem.cs b/Content.Client/Speech/EntitySystems/SlurredSystem.cs index 28f05cb1c6..5a18676c34 100644 --- a/Content.Client/Speech/EntitySystems/SlurredSystem.cs +++ b/Content.Client/Speech/EntitySystems/SlurredSystem.cs @@ -1,7 +1,12 @@ +using Content.Shared.Speech.Components; using Content.Shared.Speech.EntitySystems; namespace Content.Client.Speech.EntitySystems; public sealed class SlurredSystem : SharedSlurredSystem { + protected override string AccentuateInternal(EntityUid uid, SlurredAccentComponent comp, string message) + { + return message; + } } diff --git a/Content.Client/Speech/EntitySystems/StutteringSystem.cs b/Content.Client/Speech/EntitySystems/StutteringSystem.cs index e475ab8c30..dc8646f217 100644 --- a/Content.Client/Speech/EntitySystems/StutteringSystem.cs +++ b/Content.Client/Speech/EntitySystems/StutteringSystem.cs @@ -1,9 +1,12 @@ +using Content.Shared.Speech.Components; using Content.Shared.Speech.EntitySystems; -namespace Content.Client.Speech.EntitySystems -{ - public sealed class StutteringSystem : SharedStutteringSystem - { +namespace Content.Client.Speech.EntitySystems; +public sealed class StutteringSystem : SharedStutteringSystem +{ + protected override string AccentuateInternal(EntityUid uid, StutteringAccentComponent comp, string message) + { + return message; } } diff --git a/Content.Server/Administration/Commands/OwoifyCommand.cs b/Content.Server/Administration/Commands/OwoifyCommand.cs index 8ca35b1b42..978ddee31b 100644 --- a/Content.Server/Administration/Commands/OwoifyCommand.cs +++ b/Content.Server/Administration/Commands/OwoifyCommand.cs @@ -1,7 +1,6 @@ using Content.Server.Speech.EntitySystems; using Content.Shared.Administration; using Robust.Shared.Console; -using Robust.Shared.Random; namespace Content.Server.Administration.Commands; @@ -41,7 +40,6 @@ public sealed class OwoifyCommand : IConsoleCommand var owoSys = _entManager.System(); var metaDataSys = _entManager.System(); - metaDataSys.SetEntityName(eUid.Value, owoSys.Accentuate(meta.EntityName), meta); metaDataSys.SetEntityDescription(eUid.Value, owoSys.Accentuate(meta.EntityDescription), meta); } diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs index 63b4b5646b..63a01ac736 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs @@ -13,6 +13,7 @@ using Content.Server.Polymorph.Systems; using Content.Server.Popups; using Content.Server.Roles; using Content.Server.Speech.Components; +using Content.Shared.Speech.Components; using Content.Server.Storage.EntitySystems; using Content.Server.Tabletop; using Content.Server.Tabletop.Components; diff --git a/Content.Server/Speech/Components/SlurredAccentComponent.cs b/Content.Server/Speech/Components/SlurredAccentComponent.cs deleted file mode 100644 index b50ba86cb5..0000000000 --- a/Content.Server/Speech/Components/SlurredAccentComponent.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Content.Server.Speech.Components; - -[RegisterComponent] -public sealed partial class SlurredAccentComponent : Component { } diff --git a/Content.Server/Speech/Components/StutteringAccentComponent.cs b/Content.Server/Speech/Components/StutteringAccentComponent.cs deleted file mode 100644 index dd65ef66e0..0000000000 --- a/Content.Server/Speech/Components/StutteringAccentComponent.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace Content.Server.Speech.Components -{ - [RegisterComponent] - public sealed partial class StutteringAccentComponent : Component - { - ///

- /// Percentage chance that a stutter will occur if it matches. - /// - [DataField] - public float MatchRandomProb = 0.8f; - - /// - /// Percentage chance that a stutter occurs f-f-f-f-four times. - /// - [DataField] - public float FourRandomProb = 0.1f; - - /// - /// Percentage chance that a stutter occurs t-t-t-three times. - /// - [DataField] - public float ThreeRandomProb = 0.2f; - - /// - /// Percentage chance that a stutter cut off. - /// - [DataField] - public float CutRandomProb = 0.05f; - } -} diff --git a/Content.Server/Speech/EntitySystems/BarkAccentSystem.cs b/Content.Server/Speech/EntitySystems/BarkAccentSystem.cs index 27e42c70ed..cb157d91b2 100644 --- a/Content.Server/Speech/EntitySystems/BarkAccentSystem.cs +++ b/Content.Server/Speech/EntitySystems/BarkAccentSystem.cs @@ -1,19 +1,18 @@ -using Content.Shared.StatusEffectNew; using Content.Server.Speech.Components; -using Content.Shared.Speech; +using Content.Shared.Speech.EntitySystems; using Robust.Shared.Random; -namespace Content.Server.Speech.EntitySystems -{ - public sealed class BarkAccentSystem : EntitySystem - { - [Dependency] private readonly IRobustRandom _random = default!; +namespace Content.Server.Speech.EntitySystems; - private static readonly IReadOnlyList Barks = new List{ +public sealed class BarkAccentSystem : RelayAccentSystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + + private static readonly IReadOnlyList Barks = new List{ " Woof!", " WOOF", " wof-wof" }.AsReadOnly(); - private static readonly IReadOnlyDictionary SpecialWords = new Dictionary() + private static readonly IReadOnlyDictionary SpecialWords = new Dictionary() { { "ah", "arf" }, { "Ah", "Arf" }, @@ -21,31 +20,14 @@ namespace Content.Server.Speech.EntitySystems { "Oh", "Oof" }, }; - public override void Initialize() + protected override string AccentuateInternal(EntityUid uid, BarkAccentComponent comp, string message) + { + foreach (var (word, repl) in SpecialWords) { - SubscribeLocalEvent(OnAccent); - SubscribeLocalEvent>(OnAccentRelayed); + message = message.Replace(word, repl); } - public string Accentuate(string message) - { - foreach (var (word, repl) in SpecialWords) - { - message = message.Replace(word, repl); - } - - return message.Replace("!", _random.Pick(Barks)) - .Replace("l", "r").Replace("L", "R"); - } - - private void OnAccent(Entity entity, ref AccentGetEvent args) - { - args.Message = Accentuate(args.Message); - } - - private void OnAccentRelayed(Entity entity, ref StatusEffectRelayedEvent args) - { - args.Args.Message = Accentuate(args.Args.Message); - } + return message.Replace("!", _random.Pick(Barks)) + .Replace("l", "r").Replace("L", "R"); } } diff --git a/Content.Server/Speech/EntitySystems/OwOAccentSystem.cs b/Content.Server/Speech/EntitySystems/OwOAccentSystem.cs index 804c711ea7..fcfddfadaa 100644 --- a/Content.Server/Speech/EntitySystems/OwOAccentSystem.cs +++ b/Content.Server/Speech/EntitySystems/OwOAccentSystem.cs @@ -1,50 +1,36 @@ using Content.Server.Speech.Components; -using Content.Shared.Speech; -using Content.Shared.StatusEffectNew; +using Content.Shared.Speech.EntitySystems; using Robust.Shared.Random; -namespace Content.Server.Speech.EntitySystems -{ - public sealed class OwOAccentSystem : EntitySystem - { - [Dependency] private readonly IRobustRandom _random = default!; +namespace Content.Server.Speech.EntitySystems; - private static readonly IReadOnlyList Faces = new List{ +public sealed class OwOAccentSystem : RelayAccentSystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + + private static readonly IReadOnlyList Faces = new List{ " (•`ω´•)", " ;;w;;", " owo", " UwU", " >w<", " ^w^" }.AsReadOnly(); - private static readonly IReadOnlyDictionary SpecialWords = new Dictionary() + private static readonly IReadOnlyDictionary SpecialWords = new Dictionary() { { "you", "wu" }, }; - public override void Initialize() + public string Accentuate(string message) + { + foreach (var (word, repl) in SpecialWords) { - SubscribeLocalEvent(OnAccent); - SubscribeLocalEvent>(OnAccentRelayed); + message = message.Replace(word, repl); } - public string Accentuate(string message) - { - foreach (var (word, repl) in SpecialWords) - { - message = message.Replace(word, repl); - } - - return message.Replace("!", _random.Pick(Faces)) - .Replace("r", "w").Replace("R", "W") - .Replace("l", "w").Replace("L", "W"); - } - - private void OnAccent(Entity entity, ref AccentGetEvent args) - { - args.Message = Accentuate(args.Message); - } - - private void OnAccentRelayed(Entity entity, ref StatusEffectRelayedEvent args) - { - args.Args.Message = Accentuate(args.Args.Message); - } + return message.Replace("!", _random.Pick(Faces)) + .Replace("r", "w").Replace("R", "W") + .Replace("l", "w").Replace("L", "W"); + } + protected override string AccentuateInternal(EntityUid uid, OwOAccentComponent comp, string message) + { + return Accentuate(message); } } diff --git a/Content.Server/Speech/EntitySystems/ScrambledAccentSystem.cs b/Content.Server/Speech/EntitySystems/ScrambledAccentSystem.cs index 2f67bfad08..47fde6db86 100644 --- a/Content.Server/Speech/EntitySystems/ScrambledAccentSystem.cs +++ b/Content.Server/Speech/EntitySystems/ScrambledAccentSystem.cs @@ -1,56 +1,38 @@ using System.Linq; using System.Text.RegularExpressions; using Content.Server.Speech.Components; -using Content.Shared.Speech; -using Content.Shared.StatusEffectNew; +using Content.Shared.Speech.EntitySystems; using Robust.Shared.Random; -namespace Content.Server.Speech.EntitySystems +namespace Content.Server.Speech.EntitySystems; + +public sealed class ScrambledAccentSystem : RelayAccentSystem { - public sealed class ScrambledAccentSystem : EntitySystem + private static readonly Regex RegexLoneI = new(@"(?<=\ )i(?=[\ \.\?]|$)"); + + [Dependency] private readonly IRobustRandom _random = default!; + + protected override string AccentuateInternal(EntityUid uid, ScrambledAccentComponent comp, string message) { - private static readonly Regex RegexLoneI = new(@"(?<=\ )i(?=[\ \.\?]|$)"); + var words = message.ToLower().Split(); - [Dependency] private readonly IRobustRandom _random = default!; - - public override void Initialize() + if (words.Length < 2) { - SubscribeLocalEvent(OnAccent); - SubscribeLocalEvent>(OnAccentRelayed); + var pick = _random.Next(1, 8); + // If they try to weasel out of it by saying one word at a time we give them this. + return Loc.GetString($"accent-scrambled-words-{pick}"); } - public string Accentuate(string message) - { - var words = message.ToLower().Split(); + // Scramble the words + var scrambled = words.OrderBy(x => _random.Next()).ToArray(); - if (words.Length < 2) - { - var pick = _random.Next(1, 8); - // If they try to weasel out of it by saying one word at a time we give them this. - return Loc.GetString($"accent-scrambled-words-{pick}"); - } + var msg = string.Join(" ", scrambled); - // Scramble the words - var scrambled = words.OrderBy(x => _random.Next()).ToArray(); + // First letter should be capital + msg = msg[0].ToString().ToUpper() + msg.Remove(0, 1); - var msg = string.Join(" ", scrambled); - - // First letter should be capital - msg = msg[0].ToString().ToUpper() + msg.Remove(0, 1); - - // Capitalize lone i's - msg = RegexLoneI.Replace(msg, "I"); - return msg; - } - - private void OnAccent(Entity entity, ref AccentGetEvent args) - { - args.Message = Accentuate(args.Message); - } - - private void OnAccentRelayed(Entity entity, ref StatusEffectRelayedEvent args) - { - args.Args.Message = Accentuate(args.Args.Message); - } + // Capitalize lone i's + msg = RegexLoneI.Replace(msg, "I"); + return msg; } } diff --git a/Content.Server/Speech/EntitySystems/SlurredSystem.cs b/Content.Server/Speech/EntitySystems/SlurredSystem.cs index 34cd050439..deac680035 100644 --- a/Content.Server/Speech/EntitySystems/SlurredSystem.cs +++ b/Content.Server/Speech/EntitySystems/SlurredSystem.cs @@ -1,7 +1,6 @@ using System.Text; -using Content.Server.Speech.Components; using Content.Shared.Drunk; -using Content.Shared.Speech; +using Content.Shared.Speech.Components; using Content.Shared.Speech.EntitySystems; using Content.Shared.StatusEffectNew; using Robust.Shared.Random; @@ -25,13 +24,6 @@ public sealed class SlurredSystem : SharedSlurredSystem ///
private const float SlurredThreshold = 80f; - public override void Initialize() - { - SubscribeLocalEvent(OnAccent); - - SubscribeLocalEvent>(OnAccentRelayed); - } - /// /// Slur chance scales with the time remaining on any status effect with the SlurredAccentComponent. /// Typically, this is equivalent to "drunkenness" on the DrunkStatusEffect @@ -42,26 +34,15 @@ public sealed class SlurredSystem : SharedSlurredSystem return 0; // This is a magic number. Why this value? No clue it was made 3 years before I refactored this. - var magic = time.Item2 == null ? SlurredModifier : (float) (time.Item2 - _timing.CurTime).Value.TotalSeconds - SlurredThreshold; + var magic = time.Item2 == null ? SlurredModifier : (float)(time.Item2 - _timing.CurTime).Value.TotalSeconds - SlurredThreshold; return Math.Clamp(magic / SlurredModifier, 0f, 1f); } - private void OnAccent(Entity entity, ref AccentGetEvent args) - { - GetAccent(entity, ref args); - } - - private void OnAccentRelayed(Entity entity, ref StatusEffectRelayedEvent args) - { - var ev = args.Args; - GetAccent(args.Args.Entity, ref ev); - } - - private void GetAccent(EntityUid uid, ref AccentGetEvent args) + protected override string AccentuateInternal(EntityUid uid, SlurredAccentComponent comp, string message) { var scale = GetProbabilityScale(uid); - args.Message = Accentuate(args.Message, scale); + return Accentuate(message, scale); } private string Accentuate(string message, float scale) @@ -100,7 +81,7 @@ public sealed class SlurredSystem : SharedSlurredSystem } } - if (!_random.Prob(scale * 3/20)) + if (!_random.Prob(scale * 3 / 20)) { sb.Append(character); continue; diff --git a/Content.Server/Speech/EntitySystems/StutteringSystem.cs b/Content.Server/Speech/EntitySystems/StutteringSystem.cs index 2c78eb181e..d610423dd8 100644 --- a/Content.Server/Speech/EntitySystems/StutteringSystem.cs +++ b/Content.Server/Speech/EntitySystems/StutteringSystem.cs @@ -1,91 +1,76 @@ +using Content.Shared.Speech.Components; +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.Random; using System.Text; using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Shared.Speech; -using Content.Shared.Speech.EntitySystems; -using Content.Shared.StatusEffectNew; -using Robust.Shared.Random; -namespace Content.Server.Speech.EntitySystems +namespace Content.Server.Speech.EntitySystems; + +public sealed class StutteringSystem : SharedStutteringSystem { - public sealed class StutteringSystem : SharedStutteringSystem + [Dependency] private readonly IRobustRandom _random = default!; + + // Regex of characters to stutter. + private static readonly Regex Stutter = new(@"[b-df-hj-np-tv-wxyz]", + RegexOptions.Compiled | RegexOptions.IgnoreCase); + + public override void DoStutter(EntityUid uid, TimeSpan time, bool refresh) { - [Dependency] private readonly IRobustRandom _random = default!; + if (refresh) + Status.TryUpdateStatusEffectDuration(uid, SharedStutteringSystem.Stuttering, time); + else + Status.TryAddStatusEffectDuration(uid, SharedStutteringSystem.Stuttering, time); + } - // Regex of characters to stutter. - private static readonly Regex Stutter = new(@"[b-df-hj-np-tv-wxyz]", - RegexOptions.Compiled | RegexOptions.IgnoreCase); + public override void DoRemoveStutterTime(EntityUid uid, TimeSpan timeRemoved) + { + Status.TryAddTime(uid, SharedStutteringSystem.Stuttering, -timeRemoved); + } - public override void Initialize() + public override void DoRemoveStutter(EntityUid uid) + { + Status.TryRemoveStatusEffect(uid, SharedStutteringSystem.Stuttering); + } + + protected override string AccentuateInternal(EntityUid uid, StutteringAccentComponent comp, string message) + { + return Accentuate(message, comp); + } + + public string Accentuate(string message, StutteringAccentComponent component) + { + var length = message.Length; + + var finalMessage = new StringBuilder(); + + string newLetter; + + for (var i = 0; i < length; i++) { - SubscribeLocalEvent(OnAccent); - - SubscribeLocalEvent>(OnAccent); - } - - public override void DoStutter(EntityUid uid, TimeSpan time, bool refresh) - { - if (refresh) - Status.TryUpdateStatusEffectDuration(uid, Stuttering, time); - else - Status.TryAddStatusEffectDuration(uid, Stuttering, time); - } - - public override void DoRemoveStutterTime(EntityUid uid, TimeSpan timeRemoved) - { - Status.TryAddTime(uid, Stuttering, -timeRemoved); - } - - public override void DoRemoveStutter(EntityUid uid) - { - Status.TryRemoveStatusEffect(uid, Stuttering); - } - - private void OnAccent(Entity entity, ref AccentGetEvent args) - { - args.Message = Accentuate(args.Message, entity.Comp); - } - - private void OnAccent(Entity entity, ref StatusEffectRelayedEvent args) - { - args.Args.Message = Accentuate(args.Args.Message, entity.Comp); - } - - public string Accentuate(string message, StutteringAccentComponent component) - { - var length = message.Length; - - var finalMessage = new StringBuilder(); - - string newLetter; - - for (var i = 0; i < length; i++) + newLetter = message[i].ToString(); + if (Stutter.IsMatch(newLetter) && _random.Prob(component.MatchRandomProb)) { - newLetter = message[i].ToString(); - if (Stutter.IsMatch(newLetter) && _random.Prob(component.MatchRandomProb)) + if (_random.Prob(component.FourRandomProb)) { - if (_random.Prob(component.FourRandomProb)) - { - newLetter = $"{newLetter}-{newLetter}-{newLetter}-{newLetter}"; - } - else if (_random.Prob(component.ThreeRandomProb)) - { - newLetter = $"{newLetter}-{newLetter}-{newLetter}"; - } - else if (_random.Prob(component.CutRandomProb)) - { - newLetter = ""; - } - else - { - newLetter = $"{newLetter}-{newLetter}"; - } + newLetter = $"{newLetter}-{newLetter}-{newLetter}-{newLetter}"; + } + else if (_random.Prob(component.ThreeRandomProb)) + { + newLetter = $"{newLetter}-{newLetter}-{newLetter}"; + } + else if (_random.Prob(component.CutRandomProb)) + { + newLetter = ""; + } + else + { + newLetter = $"{newLetter}-{newLetter}"; } - - finalMessage.Append(newLetter); } - return finalMessage.ToString(); + finalMessage.Append(newLetter); } + + return finalMessage.ToString(); } } diff --git a/Content.Shared/Speech/Components/AllCapsAccentComponent.cs b/Content.Shared/Speech/Components/AllCapsAccentComponent.cs new file mode 100644 index 0000000000..d10c7b83fe --- /dev/null +++ b/Content.Shared/Speech/Components/AllCapsAccentComponent.cs @@ -0,0 +1,7 @@ +namespace Content.Shared.Speech.Components; + +/// +/// Marks a speech status effect that transforms spoken text to uppercase. +/// +[RegisterComponent] +public sealed partial class AllCapsAccentComponent : Component; diff --git a/Content.Shared/Speech/Components/SlurredAccentComponent.cs b/Content.Shared/Speech/Components/SlurredAccentComponent.cs new file mode 100644 index 0000000000..1d41c0c0e8 --- /dev/null +++ b/Content.Shared/Speech/Components/SlurredAccentComponent.cs @@ -0,0 +1,4 @@ +namespace Content.Shared.Speech.Components; + +[RegisterComponent] +public sealed partial class SlurredAccentComponent : Component; diff --git a/Content.Shared/Speech/Components/StutteringAccentComponent.cs b/Content.Shared/Speech/Components/StutteringAccentComponent.cs new file mode 100644 index 0000000000..07a076c1d9 --- /dev/null +++ b/Content.Shared/Speech/Components/StutteringAccentComponent.cs @@ -0,0 +1,29 @@ +namespace Content.Shared.Speech.Components; + +[RegisterComponent] +public sealed partial class StutteringAccentComponent : Component +{ + /// + /// Percentage chance that a stutter will occur if it matches. + /// + [DataField] + public float MatchRandomProb = 0.8f; + + /// + /// Percentage chance that a stutter occurs f-f-f-f-four times. + /// + [DataField] + public float FourRandomProb = 0.1f; + + /// + /// Percentage chance that a stutter occurs t-t-t-three times. + /// + [DataField] + public float ThreeRandomProb = 0.2f; + + /// + /// Percentage chance that a stutter cut off. + /// + [DataField] + public float CutRandomProb = 0.05f; +} diff --git a/Content.Shared/Speech/EntitySystems/AllCapsAccentSystem.cs b/Content.Shared/Speech/EntitySystems/AllCapsAccentSystem.cs new file mode 100644 index 0000000000..efe1455fd4 --- /dev/null +++ b/Content.Shared/Speech/EntitySystems/AllCapsAccentSystem.cs @@ -0,0 +1,12 @@ +namespace Content.Shared.Speech.EntitySystems; + +/// +/// Applies the all-caps accent to speech and relayed speech status effect events. +/// +public sealed class AllCapsAccentSystem : RelayAccentSystem +{ + protected override string AccentuateInternal(EntityUid uid, Components.AllCapsAccentComponent comp, string message) + { + return message.ToUpperInvariant(); + } +} diff --git a/Content.Shared/Speech/EntitySystems/RelayAccentSystem.cs b/Content.Shared/Speech/EntitySystems/RelayAccentSystem.cs new file mode 100644 index 0000000000..fe2051b950 --- /dev/null +++ b/Content.Shared/Speech/EntitySystems/RelayAccentSystem.cs @@ -0,0 +1,37 @@ +using Content.Shared.Speech; +using Content.Shared.StatusEffectNew; + +namespace Content.Shared.Speech.EntitySystems; + +/// +/// Base system for accents that should apply both directly and when relayed through other entities. +/// +public abstract class RelayAccentSystem : EntitySystem where T : Component +{ + /// + public override void Initialize() + { + SubscribeLocalEvent(OnAccent); + SubscribeLocalEvent>(OnAccentRelayed); + } + + /// + /// Applies the accent transformation to the provided message. + /// + private string Accentuate(EntityUid uid, T comp, string message) + { + return AccentuateInternal(uid, comp, message); + } + + protected abstract string AccentuateInternal(EntityUid uid, T comp, string message); + + private void OnAccent(Entity ent, ref AccentGetEvent args) + { + args.Message = Accentuate(args.Entity, ent.Comp, args.Message); + } + + private void OnAccentRelayed(Entity ent, ref StatusEffectRelayedEvent args) + { + args.Args.Message = Accentuate(args.Args.Entity, ent.Comp, args.Args.Message); + } +} diff --git a/Content.Shared/Speech/EntitySystems/SharedSlurredSystem.cs b/Content.Shared/Speech/EntitySystems/SharedSlurredSystem.cs index aadda6aa09..b53a7743ee 100644 --- a/Content.Shared/Speech/EntitySystems/SharedSlurredSystem.cs +++ b/Content.Shared/Speech/EntitySystems/SharedSlurredSystem.cs @@ -1,9 +1,10 @@ +using Content.Shared.Speech.Components; using Content.Shared.StatusEffect; using Robust.Shared.Prototypes; namespace Content.Shared.Speech.EntitySystems; -public abstract class SharedSlurredSystem : EntitySystem +public abstract class SharedSlurredSystem : RelayAccentSystem { public static readonly EntProtoId Stutter = "StatusEffectSlurred"; diff --git a/Content.Shared/Speech/EntitySystems/SharedStutteringSystem.cs b/Content.Shared/Speech/EntitySystems/SharedStutteringSystem.cs index 90cd8bc4de..827853cca1 100644 --- a/Content.Shared/Speech/EntitySystems/SharedStutteringSystem.cs +++ b/Content.Shared/Speech/EntitySystems/SharedStutteringSystem.cs @@ -1,9 +1,10 @@ +using Content.Shared.Speech.Components; using Content.Shared.StatusEffectNew; using Robust.Shared.Prototypes; namespace Content.Shared.Speech.EntitySystems; -public abstract class SharedStutteringSystem : EntitySystem +public abstract class SharedStutteringSystem : RelayAccentSystem { public static readonly EntProtoId Stuttering = "StatusEffectStutter"; diff --git a/Resources/Prototypes/Entities/StatusEffects/speech.yml b/Resources/Prototypes/Entities/StatusEffects/speech.yml index 0f957bfe56..407807db7c 100644 --- a/Resources/Prototypes/Entities/StatusEffects/speech.yml +++ b/Resources/Prototypes/Entities/StatusEffects/speech.yml @@ -42,6 +42,14 @@ components: - type: OwOAccent +# Causes you to shout everything. +- type: entity + parent: SpeechStatusEffectBase + id: StatusEffectAllCaps + name: allcapsaccent + components: + - type: AllCapsAccent + # Causes you to tark rike a dog. Woof! - type: entity parent: SpeechStatusEffectBase diff --git a/Resources/Prototypes/status_effects.yml b/Resources/Prototypes/status_effects.yml index 201e1e2aa1..1df44c6b88 100644 --- a/Resources/Prototypes/status_effects.yml +++ b/Resources/Prototypes/status_effects.yml @@ -18,9 +18,6 @@ - type: statusEffect id: Stutter -- type: statusEffect - id: AllCaps - - type: statusEffect id: Electrocution From ef3a0ecc2ac16ad9174c387fc2cd1e2fbeeb3ab2 Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Fri, 24 Apr 2026 19:00:34 -0700 Subject: [PATCH 30/65] Solutions Refactor Part 1 - Solution Prototypes (#43412) * Everything except the YAML slop... * She solution on my manager till I sajfslkahfsjakfhaskjfshajksafhfsakhfasjfas * another 1000 lines * fix chem dispenser size * go my shnelf * Implicit ass * rider is being mean for some reason * dasdas * borger * better formatting go! * clothes/bloodstream * Cartons * cups and bottles * mmm soder * bar drinks * Spray bottles and some size tweaks with hindsight * 99 bottles of beer on the wall I hate YAML * push that shit * mmm burger * Sneed * sheets * condiments * mmm yummy * fridge yummyfood * meat... * sub 300 * burger... * bready * let them eat cake * does she know how to make a grilled cheese? * pizza pie! * misc shit * soup or salad * Food and drinks, vanquished * the cubes!!! * Almost free from YAML... * fix test fails and some yaml issues * fix prediction, almost done * fix all test fails * remove master merge artifacts and undo autonetworking * review and compatibility * graaah * unfuck master merge I hate github * merg conflicts * sfsa * ehoop * sadas * afsafsaasf * merge conflicts * fucked up the merge conflicts * merge conflict is fucked I might need to completely redo this branch * test fail * no calcium???? --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- .../EntitySystems/SolutionContainerSystem.cs | 7 +- .../EntitySystems/ChemistryGuideDataSystem.cs | 3 +- .../Tests/Chemistry/DrainTest.cs | 16 +- .../Tests/Chemistry/SolutionRoundingTest.cs | 8 +- .../Tests/Chemistry/SolutionSystemTests.cs | 8 +- .../Tests/Chemistry/TryAllReactionsTest.cs | 9 +- .../Tests/Fluids/AbsorbentTest.cs | 24 +- .../Administration/Commands/AddReagent.cs | 17 +- .../Commands/SetSolutionCapacity.cs | 19 +- .../Commands/SetSolutionTemperature.cs | 17 +- .../Commands/SetSolutionThermalEnergy.cs | 17 +- .../Administration/Systems/AdminVerbSystem.cs | 14 +- .../Toolshed/SolutionCommand.cs | 5 +- .../Administration/UI/EditSolutionsEui.cs | 17 +- .../Body/Systems/BloodstreamSystem.cs | 29 - .../Botany/Systems/BotanySystem.Produce.cs | 12 +- Content.Server/Cargo/Systems/PricingSystem.cs | 59 +- .../EntitySystems/SolutionContainerSystem.cs | 45 - .../EntitySystems/ChemMasterSystem.cs | 15 +- .../DeleteOnSolutionEmptySystem.cs | 18 +- .../EntitySystems/ReagentDispenserSystem.cs | 3 +- .../EntitySystems/SolutionContainerSystem.cs | 5 + .../EntitySystems/SolutionHeaterSystem.cs | 7 +- .../EntitySystems/SolutionRandomFillSystem.cs | 9 +- .../TransformableContainerSystem.cs | 4 +- .../Chemistry/EntitySystems/VaporSystem.cs | 7 +- .../Thresholds/Behaviors/SpillBehavior.cs | 3 +- .../Fluids/EntitySystems/PuddleSystem.cs | 13 +- .../Fluids/EntitySystems/SmokeSystem.cs | 2 +- .../Systems/ForensicScannerSystem.cs | 2 - .../Forensics/Systems/ForensicsSystem.cs | 11 +- .../Kitchen/EntitySystems/MicrowaveSystem.cs | 8 +- .../Materials/MaterialReclaimerSystem.cs | 9 +- .../EntitySystems/SliceableFoodSystem.cs | 7 +- .../SmokingSystem.SmokingPipe.cs | 5 +- .../TrashOnSolutionEmptySystem.cs | 7 +- .../Power/EntitySystems/RiggableSystem.cs | 9 +- .../ChemicalFuelGeneratorAdapterComponent.cs | 2 +- .../Stunnable/Systems/StunbatonSystem.cs | 4 +- .../Ranged/Systems/GunSystem.Solution.cs | 8 +- .../Administration/EditSolutionsEuiState.cs | 2 +- .../Body/Components/BloodstreamComponent.cs | 4 +- Content.Shared/Body/Systems/LungSystem.cs | 13 +- .../Body/Systems/SharedBloodstreamSystem.cs | 25 +- Content.Shared/Body/Systems/StomachSystem.cs | 28 +- .../Chemistry/Components/Solution.cs | 9 +- .../Chemistry/Components/SolutionComponent.cs | 21 +- .../ContainedSolutionComponent.cs | 9 +- .../SolutionContainerManagerComponent.cs | 19 +- .../SolutionManagerComponent.cs | 37 + .../Components/SolutionTransferComponent.cs | 2 +- .../EntitySystems/ReactiveContainerSystem.cs | 8 +- .../EntitySystems/RehydratableSystem.cs | 8 +- ...redSolutionContainerSystem.Capabilities.cs | 30 +- ...edSolutionContainerSystem.Compatibility.cs | 79 + .../SharedSolutionContainerSystem.Relays.cs | 51 +- .../SharedSolutionContainerSystem.cs | 587 +++---- .../EntitySystems/SolutionPurgeSystem.cs | 3 +- .../SolutionRegenerationSystem.cs | 3 +- .../EntitySystems/SolutionSpikerSystem.cs | 24 +- .../EntitySystems/SolutionTransferSystem.cs | 3 +- .../AddReagentToSolutionEntityEffectSystem.cs | 6 +- .../Fluids/EntitySystems/DrainSystem.cs | 15 +- .../Fluids/SharedAbsorbentSystem.cs | 4 +- Content.Shared/Fluids/SharedPuddleSystem.cs | 14 +- .../SharedReagentGrinderSystem.cs | 11 +- .../Medical/Cryogenics/SharedCryoPodSystem.cs | 25 +- .../Metabolism/MetabolizerSystem.cs | 35 +- .../EntitySystems/IngestionSystem.API.cs | 17 +- .../EntitySystems/IngestionSystem.cs | 11 +- .../PressurizedSolutionSystem.cs | 11 +- .../FoodMetamorphRules/FoodMetamorphRule.cs | 3 - .../Tools/Components/WelderComponent.cs | 2 +- .../Tools/Systems/SharedToolSystem.Welder.cs | 7 +- Resources/Locale/en-US/reagents/meta/fun.ftl | 4 +- .../Prototypes/Body/Animals/ruminant.yml | 14 +- .../Prototypes/Body/Species/arachnid.yml | 2 +- Resources/Prototypes/Body/Species/diona.yml | 2 +- .../Prototypes/Body/Species/gingerbread.yml | 4 +- Resources/Prototypes/Body/Species/moth.yml | 2 +- Resources/Prototypes/Body/Species/slime.yml | 7 +- Resources/Prototypes/Body/Species/vox.yml | 2 +- .../Prototypes/Body/Species/vulpkanin.yml | 2 +- Resources/Prototypes/Body/base_organs.yml | 32 +- .../Catalog/Fills/Backpacks/duffelbag.yml | 10 +- .../Prototypes/Chemistry/injector_modes.yml | 11 +- .../Entities/Clothing/Back/specific.yml | 6 +- .../Prototypes/Entities/Clothing/Eyes/hud.yml | 16 +- .../Clothing/Hands/base_clothinghands.yml | 14 +- .../Clothing/Head/base_clothinghead.yml | 16 +- .../Entities/Clothing/Head/misc.yml | 15 +- .../Clothing/Masks/base_clothingmask.yml | 16 +- .../Entities/Clothing/Multiple/towel.yml | 14 +- .../Clothing/Neck/base_clothingneck.yml | 14 +- .../Entities/Clothing/Neck/pins.yml | 14 +- .../OuterClothing/base_clothingouter.yml | 13 + .../Entities/Clothing/OuterClothing/coats.yml | 11 +- .../Clothing/OuterClothing/wintercoats.yml | 23 +- .../Clothing/Shoes/base_clothingshoes.yml | 14 +- .../Entities/Clothing/Shoes/boots.yml | 12 +- .../Entities/Clothing/Shoes/misc.yml | 16 +- .../Uniforms/base_clothinguniforms.yml | 14 +- .../Entities/Clothing/Uniforms/jumpskirts.yml | 7 - .../Entities/Clothing/Uniforms/jumpsuits.yml | 7 - .../Prototypes/Entities/Debugging/drugs.yml | 16 - .../Entities/Effects/chemistry_effects.yml | 10 +- .../Prototypes/Entities/Effects/puddle.yml | 118 +- .../Prototypes/Entities/Mobs/NPCs/animals.yml | 178 +- .../Entities/Mobs/NPCs/argocyte.yml | 3 +- .../Entities/Mobs/NPCs/asteroid.yml | 12 +- .../Entities/Mobs/NPCs/moproach.yml | 11 +- .../Prototypes/Entities/Mobs/NPCs/silicon.yml | 17 +- .../Prototypes/Entities/Mobs/NPCs/space.yml | 59 +- .../Entities/Mobs/NPCs/spacetick.yml | 19 +- .../Prototypes/Entities/Mobs/NPCs/xeno.yml | 46 +- Resources/Prototypes/Entities/Mobs/base.yml | 2 +- .../Consumable/Drinks/drinks-cartons.yml | 303 ++-- .../Objects/Consumable/Drinks/drinks_base.yml | 9 +- .../Drinks/drinks_bottles_glass.yml | 522 +++--- .../Drinks/drinks_bottles_plastic.yml | 293 ++-- .../Objects/Consumable/Drinks/drinks_cans.yml | 344 ++-- .../Objects/Consumable/Drinks/drinks_cups.yml | 91 +- .../Consumable/Drinks/drinks_flasks.yml | 23 +- .../Objects/Consumable/Drinks/drinks_fun.yml | 56 +- .../Consumable/Drinks/drinks_metamorphic.yml | 1481 +++++++---------- .../drinks_solutioncontainerexample.yml | 57 - .../Consumable/Drinks/drinks_special.yml | 66 +- .../Consumable/Drinks/trash_drinks.yml | 166 -- .../Objects/Consumable/Food/Baked/bagel.yml | 47 +- .../Objects/Consumable/Food/Baked/bread.yml | 595 +++---- .../Objects/Consumable/Food/Baked/cake.yml | 508 +++--- .../Consumable/Food/Baked/donkpocket.yml | 238 +-- .../Objects/Consumable/Food/Baked/donut.yml | 246 +-- .../Objects/Consumable/Food/Baked/misc.yml | 454 ++--- .../Objects/Consumable/Food/Baked/pie.yml | 100 +- .../Objects/Consumable/Food/Baked/pizza.yml | 340 ++-- .../Consumable/Food/Containers/bowl.yml | 7 +- .../Consumable/Food/Containers/condiments.yml | 250 ++- .../Consumable/Food/Containers/tin.yml | 19 +- .../Objects/Consumable/Food/breakfast.yml | 18 +- .../Objects/Consumable/Food/burger.yml | 624 +++---- .../Objects/Consumable/Food/cottonburger.yml | 51 +- .../Entities/Objects/Consumable/Food/egg.yml | 33 +- .../Objects/Consumable/Food/food_base.yml | 12 +- .../Objects/Consumable/Food/frozen.yml | 78 +- .../Objects/Consumable/Food/ingredients.yml | 633 ++++--- .../Objects/Consumable/Food/meals.yml | 335 ++-- .../Entities/Objects/Consumable/Food/meat.yml | 1113 ++++--------- .../Objects/Consumable/Food/noodles.yml | 103 +- .../Objects/Consumable/Food/produce.yml | 1318 +++++++-------- .../Objects/Consumable/Food/skewer.yml | 7 +- .../Objects/Consumable/Food/snacks.yml | 179 +- .../Entities/Objects/Consumable/Food/soup.yml | 868 +++++----- .../Entities/Objects/Consumable/Food/taco.yml | 138 +- .../Smokeables/Cigarettes/cigarette.yml | 420 ++--- .../Smokeables/Cigarettes/joints.yml | 88 +- .../Consumable/Smokeables/Cigars/cigar.yml | 8 - .../Consumable/Smokeables/base_smokeables.yml | 24 +- .../Fun/Instruments/instruments_wind.yml | 17 +- .../Objects/Fun/Plushies/plushies.yml | 91 +- .../Entities/Objects/Fun/crayons.yml | 17 +- .../Prototypes/Entities/Objects/Fun/darts.yml | 23 +- .../Prototypes/Entities/Objects/Fun/orbs.yml | 14 +- .../Prototypes/Entities/Objects/Fun/toys.yml | 57 +- .../Objects/Materials/Sheets/glass.yml | 168 +- .../Objects/Materials/Sheets/metal.yml | 81 +- .../Objects/Materials/Sheets/other.yml | 115 +- .../Entities/Objects/Materials/base.yml | 41 + .../Objects/Materials/crystal_shard.yml | 12 +- .../Entities/Objects/Materials/ingots.yml | 35 +- .../Entities/Objects/Materials/materials.yml | 215 +-- .../Entities/Objects/Materials/ore.yml | 131 +- .../Entities/Objects/Materials/parts.yml | 31 +- .../Entities/Objects/Materials/shards.yml | 88 +- .../Entities/Objects/Misc/arabianlamp.yml | 11 +- .../Objects/Misc/fire_extinguisher.yml | 103 +- .../Entities/Objects/Misc/kudzu.yml | 30 +- .../Entities/Objects/Misc/paper.yml | 15 +- .../Entities/Objects/Misc/spaceshroom.yml | 36 +- .../Entities/Objects/Power/powercells.yml | 34 +- .../Chemistry/chemical-containers.yml | 438 +++-- .../Specific/Chemistry/chemistry-bottles.yml | 978 +++++------ .../Specific/Chemistry/chemistry-vials.yml | 60 +- .../Objects/Specific/Chemistry/chemistry.yml | 173 +- .../Specific/Chemistry/paper_centrifuge.yml | 22 +- .../Objects/Specific/Hydroponics/leaves.yml | 165 +- .../Objects/Specific/Hydroponics/seeds.yml | 1 - .../Objects/Specific/Hydroponics/sprays.yml | 36 +- .../Objects/Specific/Janitorial/janitor.yml | 30 +- .../Objects/Specific/Janitorial/soap.yml | 73 +- .../Objects/Specific/Janitorial/spray.yml | 83 +- .../Objects/Specific/Kitchen/equipment.yml | 22 +- .../Objects/Specific/Medical/healing.yml | 438 +++-- .../Objects/Specific/Medical/hypospray.yml | 288 ++-- .../Objects/Specific/Medical/morgue.yml | 48 +- .../Objects/Specific/Medical/randompill.yml | 4 - .../Specific/Xenoborg/nocturine_hypo.yml | 13 +- .../Objects/Specific/rehydrateable.yml | 66 +- .../Entities/Objects/Tools/bucket.yml | 28 +- .../Entities/Objects/Tools/cable_coils.yml | 70 +- .../Entities/Objects/Tools/flare.yml | 42 +- .../Entities/Objects/Tools/lighters.yml | 211 +-- .../Entities/Objects/Tools/welders.yml | 136 +- .../Entities/Objects/Weapons/Bombs/cord.yml | 17 +- .../Objects/Weapons/Bombs/firebomb.yml | 12 +- .../Guns/Ammunition/Cartridges/shotgun.yml | 13 +- .../Guns/Ammunition/Projectiles/shotgun.yml | 8 +- .../Objects/Weapons/Guns/Basic/watergun.yml | 26 +- .../Weapons/Guns/Projectiles/arrows.yml | 12 +- .../Weapons/Guns/Projectiles/meteors.yml | 67 +- .../Weapons/Guns/Projectiles/projectiles.yml | 22 +- .../Objects/Weapons/Guns/Snipers/snipers.yml | 6 +- .../Objects/Weapons/Melee/chainsaw.yml | 13 +- .../Entities/Objects/Weapons/Melee/spear.yml | 7 +- .../Entities/Objects/Weapons/security.yml | 5 +- .../Entities/Objects/base_solution.yml | 363 ++++ .../Dispensers/base_structuredispensers.yml | 4 +- .../Structures/Furniture/Tables/tables.yml | 7 +- .../Entities/Structures/Furniture/sink.yml | 45 +- .../Entities/Structures/Furniture/toilet.yml | 50 +- .../Structures/Machines/Medical/cryo_pod.yml | 13 +- .../Structures/Machines/chem_master.yml | 5 +- .../Entities/Structures/Machines/lathe.yml | 10 +- .../Entities/Structures/Machines/nuke.yml | 13 +- .../Structures/Machines/reagent_grinder.yml | 12 +- .../Structures/Piping/Atmospherics/unary.yml | 6 +- .../Power/Generation/portable_generator.yml | 8 +- .../Structures/Specific/Anomaly/anomalies.yml | 8 +- .../Structures/Specific/Janitor/drain.yml | 10 +- .../Structures/Specific/Janitor/janicart.yml | 480 +++--- .../Storage/Tanks/base_structuretanks.yml | 10 +- .../Structures/Storage/Tanks/tanks.yml | 61 +- .../Entities/Structures/Storage/barrels.yml | 126 +- .../Wallmounts/Storage/wall_dispensers.yml | 28 +- .../Entities/Structures/Walls/walls.yml | 2 +- .../Prototypes/Entities/Structures/soil.yml | 7 +- .../Entities/Structures/spider_web.yml | 17 +- Resources/Prototypes/Entities/Tiles/water.yml | 16 +- Resources/Prototypes/Reagents/fun.yml | 6 +- .../Recipes/Cooking/meal_recipes.yml | 102 +- .../Crafting/Graphs/improvised/firebomb.yml | 2 +- .../Prototypes/Recipes/Reactions/food.yml | 32 +- .../Prototypes/Recipes/Reactions/fun.yml | 2 +- .../Prototypes/Recipes/Reactions/soap.yml | 30 +- Resources/Prototypes/XenoArch/effects.yml | 8 +- Resources/migration.yml | 4 + 246 files changed, 9297 insertions(+), 11888 deletions(-) delete mode 100644 Content.Server/Chemistry/Containers/EntitySystems/SolutionContainerSystem.cs create mode 100644 Content.Server/Chemistry/EntitySystems/SolutionContainerSystem.cs create mode 100644 Content.Shared/Chemistry/Components/SolutionManager/SolutionManagerComponent.cs create mode 100644 Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Compatibility.cs delete mode 100644 Resources/Prototypes/Entities/Debugging/drugs.yml delete mode 100644 Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_solutioncontainerexample.yml delete mode 100644 Resources/Prototypes/Entities/Objects/Consumable/Drinks/trash_drinks.yml create mode 100644 Resources/Prototypes/Entities/Objects/Materials/base.yml create mode 100644 Resources/Prototypes/Entities/Objects/base_solution.yml diff --git a/Content.Client/Chemistry/Containers/EntitySystems/SolutionContainerSystem.cs b/Content.Client/Chemistry/Containers/EntitySystems/SolutionContainerSystem.cs index 0c38d605d2..29a58e792b 100644 --- a/Content.Client/Chemistry/Containers/EntitySystems/SolutionContainerSystem.cs +++ b/Content.Client/Chemistry/Containers/EntitySystems/SolutionContainerSystem.cs @@ -1,7 +1,8 @@ +using Content.Shared.Chemistry.Components; +using Content.Shared.Chemistry.Components.SolutionManager; using Content.Shared.Chemistry.EntitySystems; +using Robust.Shared.GameStates; namespace Content.Client.Chemistry.Containers.EntitySystems; -public sealed partial class SolutionContainerSystem : SharedSolutionContainerSystem -{ -} +public sealed partial class SolutionContainerSystem : SharedSolutionContainerSystem; diff --git a/Content.Client/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs b/Content.Client/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs index 7c2efbc471..1a619a55f9 100644 --- a/Content.Client/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs +++ b/Content.Client/Chemistry/EntitySystems/ChemistryGuideDataSystem.cs @@ -117,8 +117,7 @@ public sealed class ChemistryGuideDataSystem : SharedChemistryGuideDataSystem if (extractableComponent.GrindableSolutionName is { } grindableSolutionId && - entProto.TryGetComponent(out var manager, EntityManager.ComponentFactory) && - _solutionContainer.TryGetSolution(manager, grindableSolutionId, out var grindableSolution)) + _solutionContainer.TryGetSolution(entProto, grindableSolutionId, out var grindableSolution)) { var data = new ReagentEntitySourceData( new() { DefaultGrindCategory }, diff --git a/Content.IntegrationTests/Tests/Chemistry/DrainTest.cs b/Content.IntegrationTests/Tests/Chemistry/DrainTest.cs index 55f405f039..1e67dedd5e 100644 --- a/Content.IntegrationTests/Tests/Chemistry/DrainTest.cs +++ b/Content.IntegrationTests/Tests/Chemistry/DrainTest.cs @@ -23,15 +23,15 @@ public sealed class DrainTest : InteractionTest - type: entity parent: Puddle id: PuddleBloodTest - suffix: Blood (30u) + suffix: Blood components: - - type: SolutionContainerManager - solutions: - puddle: - maxVol: 1000 - reagents: - - ReagentId: {BloodReagent} - Quantity: {PuddleVolume} + - type: Solution + id: puddle + solution: + maxVol: 1000 + reagents: + - ReagentId: {BloodReagent} + Quantity: {PuddleVolume} "; diff --git a/Content.IntegrationTests/Tests/Chemistry/SolutionRoundingTest.cs b/Content.IntegrationTests/Tests/Chemistry/SolutionRoundingTest.cs index f188fd0f66..10ae219063 100644 --- a/Content.IntegrationTests/Tests/Chemistry/SolutionRoundingTest.cs +++ b/Content.IntegrationTests/Tests/Chemistry/SolutionRoundingTest.cs @@ -21,10 +21,10 @@ public sealed class SolutionRoundingTest : GameTest - type: entity id: SolutionRoundingTestContainer components: - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 100 + - type: Solution + id: beaker + solution: + maxVol: 100 # This is the Chloral Hydrate recipe fyi. - type: reagent diff --git a/Content.IntegrationTests/Tests/Chemistry/SolutionSystemTests.cs b/Content.IntegrationTests/Tests/Chemistry/SolutionSystemTests.cs index ffaca012a3..0b55c44266 100644 --- a/Content.IntegrationTests/Tests/Chemistry/SolutionSystemTests.cs +++ b/Content.IntegrationTests/Tests/Chemistry/SolutionSystemTests.cs @@ -20,10 +20,10 @@ public sealed class SolutionSystemTests : GameTest - type: entity id: SolutionTarget components: - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 50 + - type: Solution + id: beaker + solution: + maxVol: 50 - type: reagent id: TestReagentA diff --git a/Content.IntegrationTests/Tests/Chemistry/TryAllReactionsTest.cs b/Content.IntegrationTests/Tests/Chemistry/TryAllReactionsTest.cs index e720387425..1cec5d0d22 100644 --- a/Content.IntegrationTests/Tests/Chemistry/TryAllReactionsTest.cs +++ b/Content.IntegrationTests/Tests/Chemistry/TryAllReactionsTest.cs @@ -20,11 +20,10 @@ namespace Content.IntegrationTests.Tests.Chemistry - type: entity id: TestSolutionContainer components: - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 50 - canMix: true"; + - type: Solution + id: beaker + solution: + maxVol: 120"; private static string[] _reactions = GameDataScrounger.PrototypesOfKind(); diff --git a/Content.IntegrationTests/Tests/Fluids/AbsorbentTest.cs b/Content.IntegrationTests/Tests/Fluids/AbsorbentTest.cs index 3d9ff61a2d..93289254fd 100644 --- a/Content.IntegrationTests/Tests/Fluids/AbsorbentTest.cs +++ b/Content.IntegrationTests/Tests/Fluids/AbsorbentTest.cs @@ -35,19 +35,19 @@ public sealed class AbsorbentTest : GameTest components: - type: Absorbent useAbsorberSolution: true - - type: SolutionContainerManager - solutions: - absorbed: - maxVol: 100 + - type: Solution + id: absorbed + solution: + maxVol: 100 - type: entity name: {RefillableDummyId} id: {RefillableDummyId} components: - - type: SolutionContainerManager - solutions: - refillable: - maxVol: 200 + - type: Solution + id: refillable + solution: + maxVol: 200 - type: RefillableSolution solution: refillable @@ -55,10 +55,10 @@ public sealed class AbsorbentTest : GameTest name: {SmallRefillableDummyId} id: {SmallRefillableDummyId} components: - - type: SolutionContainerManager - solutions: - refillable: - maxVol: 20 + - type: Solution + id: refillable + solution: + maxVol: 20 - type: RefillableSolution solution: refillable "; diff --git a/Content.Server/Administration/Commands/AddReagent.cs b/Content.Server/Administration/Commands/AddReagent.cs index 9194031009..ac341566ae 100644 --- a/Content.Server/Administration/Commands/AddReagent.cs +++ b/Content.Server/Administration/Commands/AddReagent.cs @@ -36,16 +36,17 @@ namespace Content.Server.Administration.Commands return; } - if (!_entManager.TryGetComponent(uid, out SolutionContainerManagerComponent? man)) - { - shell.WriteLine($"Entity does not have any solutions."); - return; - } - var solutionContainerSystem = _entManager.System(); - if (!solutionContainerSystem.TryGetSolution((uid.Value, man), args[1], out var solution)) + if (!solutionContainerSystem.TryGetSolution(uid.Value, args[1], out var solution)) { - var validSolutions = string.Join(", ", solutionContainerSystem.EnumerateSolutions((uid.Value, man)).Select(s => s.Name)); + var solutions = solutionContainerSystem.EnumerateSolutions(uid.Value).ToArray(); + if (!solutions.Any()) + { + shell.WriteLine("Entity does not have any solutions!"); + return; + } + + var validSolutions = string.Join(", ", solutions.Select(s => s.Name)); shell.WriteLine($"Entity does not have a \"{args[1]}\" solution. Valid solutions are:\n{validSolutions}"); return; } diff --git a/Content.Server/Administration/Commands/SetSolutionCapacity.cs b/Content.Server/Administration/Commands/SetSolutionCapacity.cs index 0c529d7b5b..ff387ecd4e 100644 --- a/Content.Server/Administration/Commands/SetSolutionCapacity.cs +++ b/Content.Server/Administration/Commands/SetSolutionCapacity.cs @@ -24,22 +24,23 @@ namespace Content.Server.Administration.Commands return; } - if (!NetEntity.TryParse(args[0], out var uidNet)) + if (!NetEntity.TryParse(args[0], out var uidNet) || !_entManager.TryGetEntity(uidNet, out var uid)) { shell.WriteLine($"Invalid entity id."); return; } - if (!_entManager.TryGetEntity(uidNet, out var uid) || !_entManager.TryGetComponent(uid, out SolutionContainerManagerComponent? man)) - { - shell.WriteLine($"Entity does not have any solutions."); - return; - } - var solutionContainerSystem = _entManager.System(); - if (!solutionContainerSystem.TryGetSolution((uid.Value, man), args[1], out var solution)) + if (!solutionContainerSystem.TryGetSolution(uid.Value, args[1], out var solution)) { - var validSolutions = string.Join(", ", solutionContainerSystem.EnumerateSolutions((uid.Value, man)).Select(s => s.Name)); + var solutions = solutionContainerSystem.EnumerateSolutions(uid.Value).ToArray(); + if (!solutions.Any()) + { + shell.WriteLine("Entity does not have any solutions!"); + return; + } + + var validSolutions = string.Join(", ", solutions.Select(s => s.Name)); shell.WriteLine($"Entity does not have a \"{args[1]}\" solution. Valid solutions are:\n{validSolutions}"); return; } diff --git a/Content.Server/Administration/Commands/SetSolutionTemperature.cs b/Content.Server/Administration/Commands/SetSolutionTemperature.cs index 85911f168a..0049b09f37 100644 --- a/Content.Server/Administration/Commands/SetSolutionTemperature.cs +++ b/Content.Server/Administration/Commands/SetSolutionTemperature.cs @@ -29,16 +29,17 @@ namespace Content.Server.Administration.Commands return; } - if (!_entManager.TryGetComponent(uid, out SolutionContainerManagerComponent? man)) - { - shell.WriteLine($"Entity does not have any solutions."); - return; - } - var solutionContainerSystem = _entManager.System(); - if (!solutionContainerSystem.TryGetSolution((uid.Value, man), args[1], out var solution)) + if (!solutionContainerSystem.TryGetSolution(uid.Value, args[1], out var solution)) { - var validSolutions = string.Join(", ", solutionContainerSystem.EnumerateSolutions((uid.Value, man)).Select(s => s.Name)); + var solutions = solutionContainerSystem.EnumerateSolutions(uid.Value).ToArray(); + if (!solutions.Any()) + { + shell.WriteLine("Entity does not have any solutions!"); + return; + } + + var validSolutions = string.Join(", ", solutions.Select(s => s.Name)); shell.WriteLine($"Entity does not have a \"{args[1]}\" solution. Valid solutions are:\n{validSolutions}"); return; } diff --git a/Content.Server/Administration/Commands/SetSolutionThermalEnergy.cs b/Content.Server/Administration/Commands/SetSolutionThermalEnergy.cs index 54b6c092e9..24fd603bec 100644 --- a/Content.Server/Administration/Commands/SetSolutionThermalEnergy.cs +++ b/Content.Server/Administration/Commands/SetSolutionThermalEnergy.cs @@ -29,16 +29,17 @@ namespace Content.Server.Administration.Commands return; } - if (!_entManager.TryGetComponent(uid, out SolutionContainerManagerComponent? man)) - { - shell.WriteLine($"Entity does not have any solutions."); - return; - } - var solutionContainerSystem = _entManager.System(); - if (!solutionContainerSystem.TryGetSolution((uid.Value, man), args[1], out var solutionEnt, out var solution)) + if (!solutionContainerSystem.TryGetSolution(uid.Value, args[1], out var solutionEnt, out var solution)) { - var validSolutions = string.Join(", ", solutionContainerSystem.EnumerateSolutions((uid.Value, man)).Select(s => s.Name)); + var solutions = solutionContainerSystem.EnumerateSolutions(uid.Value).ToArray(); + if (!solutions.Any()) + { + shell.WriteLine("Entity does not have any solutions!"); + return; + } + + var validSolutions = string.Join(", ", solutions.Select(s => s.Name)); shell.WriteLine($"Entity does not have a \"{args[1]}\" solution. Valid solutions are:\n{validSolutions}"); return; } diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.cs b/Content.Server/Administration/Systems/AdminVerbSystem.cs index 4a2ebbb7c6..638d1821c1 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.cs @@ -35,6 +35,7 @@ using Robust.Shared.Timing; using Robust.Shared.Toolshed; using Robust.Shared.Utility; using System.Linq; +using Content.Shared.Chemistry.Components; using static Content.Shared.Configurable.ConfigurationComponent; namespace Content.Server.Administration.Systems @@ -73,7 +74,10 @@ namespace Content.Server.Administration.Systems { SubscribeLocalEvent>(GetVerbs); SubscribeLocalEvent(Reset); - SubscribeLocalEvent(OnSolutionChanged); + + // TODO: This is genuinely terrible, solutions are already networked and we shouldn't need to update the BUI like this. + SubscribeLocalEvent((x, ref _) => OnSolutionChanged(x.Owner)); + SubscribeLocalEvent((x, ref _) => OnSolutionChanged(x.Owner)); } private void GetVerbs(GetVerbsEvent ev) @@ -445,7 +449,7 @@ namespace Content.Server.Administration.Systems } // Control mob verb - if ((_toolshed.ActivePermissionController?.CheckInvokable(new CommandSpec(_toolshed.DefaultEnvironment.GetCommand("mind"), "control"), player, out _) ?? false) && + if (_toolshed.ActivePermissionController?.CheckInvokable(new CommandSpec(_toolshed.DefaultEnvironment.GetCommand("mind"), "control"), player, out _) ?? false && args.User != args.Target) { Verb verb = new() @@ -573,7 +577,7 @@ namespace Content.Server.Administration.Systems // Add verb to open Solution Editor if (_groupController.CanCommand(player, "addreagent") && - HasComp(args.Target)) + (HasComp(args.Target) || HasComp(args.Target))) { Verb verb = new() { @@ -588,13 +592,13 @@ namespace Content.Server.Administration.Systems } #region SolutionsEui - private void OnSolutionChanged(Entity entity, ref SolutionContainerChangedEvent args) + private void OnSolutionChanged(EntityUid uid) { foreach (var list in _openSolutionUis.Values) { foreach (var eui in list) { - if (eui.Target == entity.Owner) + if (eui.Target == uid) eui.StateDirty(); } } diff --git a/Content.Server/Administration/Toolshed/SolutionCommand.cs b/Content.Server/Administration/Toolshed/SolutionCommand.cs index d184afcb4d..079deb62c5 100644 --- a/Content.Server/Administration/Toolshed/SolutionCommand.cs +++ b/Content.Server/Administration/Toolshed/SolutionCommand.cs @@ -1,12 +1,9 @@ -using Content.Server.Chemistry.Containers.EntitySystems; -using Content.Shared.Administration; +using Content.Shared.Administration; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Reagent; using Content.Shared.FixedPoint; using Content.Shared.Chemistry.EntitySystems; using Robust.Shared.Toolshed; -using Robust.Shared.Toolshed.Syntax; -using Robust.Shared.Toolshed.TypeParsers; using System.Linq; using Robust.Shared.Prototypes; diff --git a/Content.Server/Administration/UI/EditSolutionsEui.cs b/Content.Server/Administration/UI/EditSolutionsEui.cs index 6bee7d19fc..4ecc315f9e 100644 --- a/Content.Server/Administration/UI/EditSolutionsEui.cs +++ b/Content.Server/Administration/UI/EditSolutionsEui.cs @@ -1,5 +1,4 @@ using Content.Server.Administration.Systems; -using Content.Server.Chemistry.Containers.EntitySystems; using Content.Server.EUI; using Content.Shared.Administration; using Content.Shared.Chemistry.Components.SolutionManager; @@ -42,21 +41,15 @@ namespace Content.Server.Administration.UI public override EuiStateBase GetNewState() { - List<(string Name, NetEntity Solution)>? netSolutions; + List<(string Name, NetEntity Solution)>? netSolutions = new(); - if (_entityManager.TryGetComponent(Target, out SolutionContainerManagerComponent? container) && container.Containers.Count > 0) + foreach (var (name, solution) in _solutionContainerSystem.EnumerateSolutions(Target)) { - netSolutions = new(); - foreach (var (name, solution) in _solutionContainerSystem.EnumerateSolutions((Target, container))) - { - if (name is null || !_entityManager.TryGetNetEntity(solution, out var netSolution)) - continue; + if (name is null || !_entityManager.TryGetNetEntity(solution, out var netSolution)) + continue; - netSolutions.Add((name, netSolution.Value)); - } + netSolutions.Add((name, netSolution.Value)); } - else - netSolutions = null; return new EditSolutionsEuiState(_entityManager.GetNetEntity(Target), netSolutions, _gameTiming.CurTick); } diff --git a/Content.Server/Body/Systems/BloodstreamSystem.cs b/Content.Server/Body/Systems/BloodstreamSystem.cs index ff6ee5ceec..8318e41045 100644 --- a/Content.Server/Body/Systems/BloodstreamSystem.cs +++ b/Content.Server/Body/Systems/BloodstreamSystem.cs @@ -11,38 +11,9 @@ public sealed class BloodstreamSystem : SharedBloodstreamSystem { base.Initialize(); - SubscribeLocalEvent(OnComponentInit); SubscribeLocalEvent(OnDnaGenerated); } - // not sure if we can move this to shared or not - // it would certainly help if SolutionContainer was documented - // but since we usually don't add the component dynamically to entities we can keep this unpredicted for now - private void OnComponentInit(Entity entity, ref ComponentInit args) - { - if (!SolutionContainer.EnsureSolution(entity.Owner, - entity.Comp.BloodSolutionName, - out var bloodSolution) || - !SolutionContainer.EnsureSolution(entity.Owner, - entity.Comp.BloodTemporarySolutionName, - out var tempSolution) || - !SolutionContainer.EnsureSolution(entity.Owner, - entity.Comp.MetabolitesSolutionName, - out var metabolitesSolution)) - return; - - bloodSolution.MaxVolume = entity.Comp.BloodReferenceSolution.Volume * entity.Comp.MaxVolumeModifier; - metabolitesSolution.MaxVolume = bloodSolution.MaxVolume; - tempSolution.MaxVolume = entity.Comp.BleedPuddleThreshold * 4; // give some leeway, for chemstream as well - entity.Comp.BloodReferenceSolution.SetReagentData(GetEntityBloodData((entity, entity.Comp))); - - // Fill blood solution with BLOOD - // The DNA string might not be initialized yet, but the reagent data gets updated in the GenerateDnaEvent subscription - var solution = entity.Comp.BloodReferenceSolution.Clone(); - solution.ScaleTo(entity.Comp.BloodReferenceSolution.Volume - bloodSolution.Volume); - bloodSolution.AddSolution(solution, PrototypeManager); - } - // forensics is not predicted yet private void OnDnaGenerated(Entity entity, ref GenerateDnaEvent args) { diff --git a/Content.Server/Botany/Systems/BotanySystem.Produce.cs b/Content.Server/Botany/Systems/BotanySystem.Produce.cs index bba3c48b86..aa7d6412e5 100644 --- a/Content.Server/Botany/Systems/BotanySystem.Produce.cs +++ b/Content.Server/Botany/Systems/BotanySystem.Produce.cs @@ -20,21 +20,17 @@ public sealed partial class BotanySystem _entityEffects.TryApplyEffect(uid, mutation.Effect); } - if (!_solutionContainerSystem.EnsureSolution(uid, - produce.SolutionName, - out var solutionContainer, - FixedPoint2.Zero)) - return; + _solutionContainerSystem.EnsureSolution(uid, produce.SolutionName, out var solution); - solutionContainer.RemoveAllSolution(); + solution.Comp.Solution.RemoveAllSolution(); foreach (var (chem, quantity) in seed.Chemicals) { var amount = quantity.Min; if (quantity.PotencyDivisor > 0 && seed.Potency > 0) amount += seed.Potency / quantity.PotencyDivisor; amount = FixedPoint2.Clamp(amount, quantity.Min, quantity.Max); - solutionContainer.MaxVolume += amount; - solutionContainer.AddReagent(chem, amount); + solution.Comp.Solution.MaxVolume += amount; + solution.Comp.Solution.AddReagent(chem, amount); } } diff --git a/Content.Server/Cargo/Systems/PricingSystem.cs b/Content.Server/Cargo/Systems/PricingSystem.cs index bbf8176035..97ba858819 100644 --- a/Content.Server/Cargo/Systems/PricingSystem.cs +++ b/Content.Server/Cargo/Systems/PricingSystem.cs @@ -130,14 +130,11 @@ public sealed class PricingSystem : EntitySystem args.Price += entity.Comp.RandomPrice ?? 0; } - private double GetSolutionPrice(Entity entity) + private double GetSolutionPrice(EntityUid entity) { - if (Comp(entity).EntityLifeStage < EntityLifeStage.MapInitialized) - return GetSolutionPrice(entity.Comp); - var price = 0.0; - foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions((entity.Owner, entity.Comp))) + foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions(entity)) { var solution = soln.Comp.Solution; foreach (var (reagent, quantity) in solution.Contents) @@ -153,25 +150,6 @@ public sealed class PricingSystem : EntitySystem return price; } - private double GetSolutionPrice(SolutionContainerManagerComponent component) - { - var price = 0.0; - - foreach (var (_, prototype) in _solutionContainerSystem.EnumerateSolutions(component)) - { - foreach (var (reagent, quantity) in prototype.Contents) - { - if (!_prototypeManager.TryIndex(reagent.Prototype, out var reagentProto)) - continue; - - // TODO check ReagentData for price information? - price += (float) quantity * reagentProto.PricePerUnit; - } - } - - return price; - } - private double GetMaterialPrice(PhysicalCompositionComponent component) { double price = 0; @@ -319,22 +297,43 @@ public sealed class PricingSystem : EntitySystem { var price = 0.0; - if (TryComp(uid, out var solComp)) + var meta = MetaData(uid); + if (meta.EntityLifeStage < EntityLifeStage.MapInitialized) + return GetSolutionsPrice(meta.EntityPrototype); + + foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions(uid)) { - price += GetSolutionPrice((uid, solComp)); + var solution = soln.Comp.Solution; + foreach (var (reagent, quantity) in solution.Contents) + { + if (!_prototypeManager.TryIndex(reagent.Prototype, out var reagentProto)) + continue; + + // TODO check ReagentData for price information? + price += (float) quantity * reagentProto.PricePerUnit; + } } return price; } - private double GetSolutionsPrice(EntityPrototype prototype) + private double GetSolutionsPrice(EntityPrototype? prototype) { var price = 0.0; - if (prototype.Components.TryGetValue(Factory.GetComponentName(), out var solManager)) + if (prototype == null) + return price; + + foreach (var (_, solution) in _solutionContainerSystem.EnumerateSolutions(prototype)) { - var solComp = (SolutionContainerManagerComponent) solManager.Component; - price += GetSolutionPrice(solComp); + foreach (var (reagent, quantity) in solution.Contents) + { + if (!_prototypeManager.TryIndex(reagent.Prototype, out var reagentProto)) + continue; + + // TODO check ReagentData for price information? + price += (float) quantity * reagentProto.PricePerUnit; + } } return price; diff --git a/Content.Server/Chemistry/Containers/EntitySystems/SolutionContainerSystem.cs b/Content.Server/Chemistry/Containers/EntitySystems/SolutionContainerSystem.cs deleted file mode 100644 index 3d99db1129..0000000000 --- a/Content.Server/Chemistry/Containers/EntitySystems/SolutionContainerSystem.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Content.Shared.Chemistry.Components; -using Content.Shared.Chemistry.Components.SolutionManager; -using Content.Shared.Chemistry.EntitySystems; -using Content.Shared.FixedPoint; -using Robust.Shared.Containers; -using Robust.Shared.Map; -using Robust.Shared.Utility; -using System.Numerics; - -namespace Content.Server.Chemistry.Containers.EntitySystems; - -[Obsolete("This is being depreciated. Use SharedSolutionContainerSystem instead!")] -public sealed partial class SolutionContainerSystem : SharedSolutionContainerSystem -{ - [Obsolete("This is being depreciated. Use the ensure methods in SharedSolutionContainerSystem instead!")] - public Solution EnsureSolution(Entity entity, string name) - => EnsureSolution(entity, name, out _); - - [Obsolete("This is being depreciated. Use the ensure methods in SharedSolutionContainerSystem instead!")] - public Solution EnsureSolution(Entity entity, string name, out bool existed) - => EnsureSolution(entity, name, FixedPoint2.Zero, out existed); - - [Obsolete("This is being depreciated. Use the ensure methods in SharedSolutionContainerSystem instead!")] - public Solution EnsureSolution(Entity entity, string name, FixedPoint2 maxVol, out bool existed) - => EnsureSolution(entity, name, maxVol, null, out existed); - - [Obsolete("This is being depreciated. Use the ensure methods in SharedSolutionContainerSystem instead!")] - public Solution EnsureSolution(Entity entity, string name, FixedPoint2 maxVol, Solution? prototype, out bool existed) - { - EnsureSolution(entity, name, maxVol, prototype, out existed, out var solution); - return solution!;//solution is only ever null on the client, so we can suppress this - } - - [Obsolete("This is being depreciated. Use the ensure methods in SharedSolutionContainerSystem instead!")] - public Entity EnsureSolutionEntity( - Entity entity, - string name, - FixedPoint2 maxVol, - Solution? prototype, - out bool existed) - { - EnsureSolutionEntity(entity, name, out existed, out var solEnt, maxVol, prototype); - return solEnt!.Value;//solEnt is only ever null on the client, so we can suppress this - } -} diff --git a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs index e4dc4fb8f9..8d8971fecc 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs @@ -47,7 +47,7 @@ namespace Content.Server.Chemistry.EntitySystems base.Initialize(); SubscribeLocalEvent(SubscribeUpdateUiState); - SubscribeLocalEvent(SubscribeUpdateUiState); + SubscribeLocalEvent(SubscribeUpdateUiState); SubscribeLocalEvent(SubscribeUpdateUiState); SubscribeLocalEvent(SubscribeUpdateUiState); // Subscribing to DragDropTargetEvent is a quick fix to ensure the UI updates when fluids are dragged and dropped into the ChemMaster, since Shared.Fluids.EntitySystems.SolutionDumpingSystem.cs bypasses UpdateChemicals(). @@ -235,22 +235,17 @@ namespace Content.Server.Chemistry.EntitySystems _storageSystem.Insert(container, item, out _, user: user, storage); _labelSystem.Label(item, message.Label); - _solutionContainerSystem.EnsureSolutionEntity(item, - SharedChemMaster.PillSolutionName, - out var itemSolution, - message.Dosage); - if (!itemSolution.HasValue) - return; + _solutionContainerSystem.EnsureSolution(item, SharedChemMaster.PillSolutionName, out var itemSolution); + itemSolution.Comp.Solution.MaxVolume = message.Dosage; - _solutionContainerSystem.TryAddSolution(itemSolution.Value, withdrawal.SplitSolution(message.Dosage)); + _solutionContainerSystem.TryAddSolution(itemSolution, withdrawal.SplitSolution(message.Dosage)); var pill = EnsureComp(item); pill.PillType = chemMaster.Comp.PillType; Dirty(item, pill); // Log pill creation by a user - _adminLogger.Add(LogType.Action, LogImpact.Low, - $"{ToPrettyString(user):user} printed {ToPrettyString(item):pill} {SharedSolutionContainerSystem.ToPrettyString(itemSolution.Value.Comp.Solution)}"); + _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(user):user} printed {ToPrettyString(item):pill} {SharedSolutionContainerSystem.ToPrettyString(itemSolution.Comp.Solution)}"); } UpdateUiState(chemMaster); diff --git a/Content.Server/Chemistry/EntitySystems/DeleteOnSolutionEmptySystem.cs b/Content.Server/Chemistry/EntitySystems/DeleteOnSolutionEmptySystem.cs index d4e03b0967..16707b26ea 100644 --- a/Content.Server/Chemistry/EntitySystems/DeleteOnSolutionEmptySystem.cs +++ b/Content.Server/Chemistry/EntitySystems/DeleteOnSolutionEmptySystem.cs @@ -12,7 +12,7 @@ namespace Content.Server.Chemistry.EntitySystems.DeleteOnSolutionEmptySystem { base.Initialize(); SubscribeLocalEvent(OnStartup); - SubscribeLocalEvent(OnSolutionChange); + SubscribeLocalEvent(OnSolutionChange); } public void OnStartup(Entity entity, ref ComponentStartup args) @@ -20,19 +20,23 @@ namespace Content.Server.Chemistry.EntitySystems.DeleteOnSolutionEmptySystem CheckSolutions(entity); } - public void OnSolutionChange(Entity entity, ref SolutionContainerChangedEvent args) + public void OnSolutionChange(Entity entity, ref SolutionChangedEvent args) { - CheckSolutions(entity); + var solution = args.Solution.Comp.Solution; + if (args.Solution.Comp.Id != entity.Comp.Solution) + return; + + if (solution.Volume <= 0) + QueueDel(entity); } public void CheckSolutions(Entity entity) { - if (!TryComp(entity, out SolutionContainerManagerComponent? solutions)) + if (!_solutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.Solution, out _, out var solution)) return; - if (_solutionContainerSystem.TryGetSolution((entity.Owner, solutions), entity.Comp.Solution, out _, out var solution)) - if (solution.Volume <= 0) - QueueDel(entity); + if (solution.Volume <= 0) + QueueDel(entity); } } } diff --git a/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs b/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs index 2d751ba441..f968851c4f 100644 --- a/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs @@ -1,6 +1,5 @@ using System.Linq; using Content.Server.Chemistry.Components; -using Content.Server.Chemistry.Containers.EntitySystems; using Content.Shared.Chemistry; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Containers.ItemSlots; @@ -40,7 +39,7 @@ namespace Content.Server.Chemistry.EntitySystems base.Initialize(); SubscribeLocalEvent(SubscribeUpdateUiState); - SubscribeLocalEvent(SubscribeUpdateUiState); + SubscribeLocalEvent(SubscribeUpdateUiState); SubscribeLocalEvent(SubscribeUpdateUiState, after: [typeof(SharedStorageSystem)]); SubscribeLocalEvent(SubscribeUpdateUiState, after: [typeof(SharedStorageSystem)]); SubscribeLocalEvent(SubscribeUpdateUiState); diff --git a/Content.Server/Chemistry/EntitySystems/SolutionContainerSystem.cs b/Content.Server/Chemistry/EntitySystems/SolutionContainerSystem.cs new file mode 100644 index 0000000000..62f924b5ad --- /dev/null +++ b/Content.Server/Chemistry/EntitySystems/SolutionContainerSystem.cs @@ -0,0 +1,5 @@ +using Content.Shared.Chemistry.EntitySystems; + +namespace Content.Server.Chemistry.EntitySystems; + +public sealed class SolutionContainerSystem : SharedSolutionContainerSystem; diff --git a/Content.Server/Chemistry/EntitySystems/SolutionHeaterSystem.cs b/Content.Server/Chemistry/EntitySystems/SolutionHeaterSystem.cs index 4227af577f..e2067bdc2c 100644 --- a/Content.Server/Chemistry/EntitySystems/SolutionHeaterSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/SolutionHeaterSystem.cs @@ -81,13 +81,10 @@ public sealed class SolutionHeaterSystem : EntitySystem var query = EntityQueryEnumerator(); while (query.MoveNext(out _, out _, out var heater, out var placer)) { + var energy = heater.HeatPerSecond * frameTime; foreach (var heatingEntity in placer.PlacedEntities) { - if (!TryComp(heatingEntity, out var container)) - continue; - - var energy = heater.HeatPerSecond * frameTime; - foreach (var (_, soln) in _solutionContainer.EnumerateSolutions((heatingEntity, container))) + foreach (var (_, soln) in _solutionContainer.EnumerateSolutions(heatingEntity)) { _solutionContainer.AddThermalEnergy(soln, energy); } diff --git a/Content.Server/Chemistry/EntitySystems/SolutionRandomFillSystem.cs b/Content.Server/Chemistry/EntitySystems/SolutionRandomFillSystem.cs index 62dd2d3a75..84f96e6ba7 100644 --- a/Content.Server/Chemistry/EntitySystems/SolutionRandomFillSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/SolutionRandomFillSystem.cs @@ -3,6 +3,7 @@ using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Chemistry.Reagent; using Content.Shared.Random; using Content.Shared.Random.Helpers; +using Content.Shared.Storage.Components; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -37,8 +38,10 @@ public sealed class SolutionRandomFillSystem : EntitySystem return; } - _solutionsSystem.EnsureSolutionEntity(entity.Owner, entity.Comp.Solution, out var target , pick.quantity); - if(target.HasValue) - _solutionsSystem.TryAddReagent(target.Value, reagent, quantity); + _solutionsSystem.EnsureSolution(entity.Owner, entity.Comp.Solution, out var target); + if (target.Comp.Solution.AvailableVolume < quantity) + Log.Error($"A random solution fill {entity.Comp.WeightedRandomId} tried to put {pick.quantity} of {pick.reagent} into {ToPrettyString(target)} but there was not enough space!"); + + _solutionsSystem.TryAddReagent(target, reagent, quantity); } } diff --git a/Content.Server/Chemistry/EntitySystems/TransformableContainerSystem.cs b/Content.Server/Chemistry/EntitySystems/TransformableContainerSystem.cs index d5b220c3e8..45bb84f23f 100644 --- a/Content.Server/Chemistry/EntitySystems/TransformableContainerSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/TransformableContainerSystem.cs @@ -18,7 +18,7 @@ public sealed class TransformableContainerSystem : EntitySystem base.Initialize(); SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(OnSolutionChange); + SubscribeLocalEvent(OnSolutionChange); SubscribeLocalEvent(OnRefreshNameModifiers); } @@ -31,7 +31,7 @@ public sealed class TransformableContainerSystem : EntitySystem } } - private void OnSolutionChange(Entity entity, ref SolutionContainerChangedEvent args) + private void OnSolutionChange(Entity entity, ref SolutionChangedEvent args) { if (!_solutionsSystem.TryGetFitsInDispenser(entity.Owner, out _, out var solution)) return; diff --git a/Content.Server/Chemistry/EntitySystems/VaporSystem.cs b/Content.Server/Chemistry/EntitySystems/VaporSystem.cs index a6725856ec..b6b3433bf5 100644 --- a/Content.Server/Chemistry/EntitySystems/VaporSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/VaporSystem.cs @@ -39,9 +39,7 @@ namespace Content.Server.Chemistry.EntitySystems private void HandleCollide(Entity entity, ref StartCollideEvent args) { - if (!TryComp(entity.Owner, out SolutionContainerManagerComponent? contents)) return; - - foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions((entity.Owner, contents))) + foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions(entity.Owner)) { var solution = soln.Comp.Solution; _reactive.DoEntityReaction(args.OtherEntity, solution, ReactionMethod.Touch); @@ -102,7 +100,8 @@ namespace Content.Server.Chemistry.EntitySystems base.Update(frameTime); // Enumerate over all VaporComponents - var query = EntityQueryEnumerator(); + // TODO: Vapor should just use SolutionComponent and not be capable of having multiple solutions. + var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var vaporComp, out var container, out var xform)) { // Return early if we're not active diff --git a/Content.Server/Destructible/Thresholds/Behaviors/SpillBehavior.cs b/Content.Server/Destructible/Thresholds/Behaviors/SpillBehavior.cs index ad34f05edd..d261b3cb79 100644 --- a/Content.Server/Destructible/Thresholds/Behaviors/SpillBehavior.cs +++ b/Content.Server/Destructible/Thresholds/Behaviors/SpillBehavior.cs @@ -30,7 +30,8 @@ public sealed partial class SpillBehavior : IThresholdBehavior var coordinates = system.EntityManager.GetComponent(owner).Coordinates; // Spill the solution that was drained/split - if (solutionContainer.TryGetSolution(owner, Solution, out _, out var solution)) + // TODO: ??? Top 10 reasons for solution entity prototypes right here bruh. + if (Solution != null && solutionContainer.TryGetSolution(owner, Solution, out _, out var solution)) puddleSystem.TrySplashSpillAt(owner, coordinates, solution, out _, false, cause); else puddleSystem.TrySplashSpillAt(owner, coordinates, out _, out _, false, cause); diff --git a/Content.Server/Fluids/EntitySystems/PuddleSystem.cs b/Content.Server/Fluids/EntitySystems/PuddleSystem.cs index aca8c5383d..5e5ca85673 100644 --- a/Content.Server/Fluids/EntitySystems/PuddleSystem.cs +++ b/Content.Server/Fluids/EntitySystems/PuddleSystem.cs @@ -294,20 +294,13 @@ public sealed partial class PuddleSystem : SharedPuddleSystem Solution addedSolution, bool sound = true, bool checkForOverflow = true, - PuddleComponent? puddleComponent = null, - SolutionContainerManagerComponent? sol = null) + PuddleComponent? puddleComponent = null) { - if (!Resolve(puddleUid, ref puddleComponent, ref sol)) + if (!Resolve(puddleUid, ref puddleComponent)) return false; - _solutionContainerSystem.EnsureAllSolutions((puddleUid, sol)); - - if (addedSolution.Volume == 0 || - !_solutionContainerSystem.ResolveSolution(puddleUid, puddleComponent.SolutionName, - ref puddleComponent.Solution)) - { + if (addedSolution.Volume == 0 || !_solutionContainerSystem.ResolveSolution(puddleUid, puddleComponent.SolutionName, ref puddleComponent.Solution)) return false; - } _solutionContainerSystem.AddSolution(puddleComponent.Solution.Value, addedSolution); diff --git a/Content.Server/Fluids/EntitySystems/SmokeSystem.cs b/Content.Server/Fluids/EntitySystems/SmokeSystem.cs index c787132504..e8e2d44988 100644 --- a/Content.Server/Fluids/EntitySystems/SmokeSystem.cs +++ b/Content.Server/Fluids/EntitySystems/SmokeSystem.cs @@ -204,7 +204,7 @@ public sealed class SmokeSystem : EntitySystem private void OnReactionAttempt(Entity entity, ref SolutionRelayEvent args) { - if (args.Name == SmokeComponent.SolutionName) + if (args.Solution.Comp.Id == SmokeComponent.SolutionName) OnReactionAttempt(entity, ref args.Event); } diff --git a/Content.Server/Forensics/Systems/ForensicScannerSystem.cs b/Content.Server/Forensics/Systems/ForensicScannerSystem.cs index b75c0ae32a..4c90921e74 100644 --- a/Content.Server/Forensics/Systems/ForensicScannerSystem.cs +++ b/Content.Server/Forensics/Systems/ForensicScannerSystem.cs @@ -13,9 +13,7 @@ using Content.Shared.Tag; using Robust.Shared.Audio.Systems; using Robust.Server.GameObjects; using Robust.Shared.Audio; -using Robust.Shared.Player; using Robust.Shared.Timing; -using Content.Server.Chemistry.Containers.EntitySystems; using Robust.Shared.Prototypes; // todo: remove this stinky LINQy diff --git a/Content.Server/Forensics/Systems/ForensicsSystem.cs b/Content.Server/Forensics/Systems/ForensicsSystem.cs index 4c28265fed..21f09c3fe5 100644 --- a/Content.Server/Forensics/Systems/ForensicsSystem.cs +++ b/Content.Server/Forensics/Systems/ForensicsSystem.cs @@ -47,11 +47,11 @@ namespace Content.Server.Forensics SubscribeLocalEvent(OnAfterInteract, after: new[] { typeof(AbsorbentSystem) }); SubscribeLocalEvent(OnCleanForensicsDoAfter); SubscribeLocalEvent(OnTransferDnaEvent); - SubscribeLocalEvent(OnSolutionChanged); + SubscribeLocalEvent(OnSolutionChanged); SubscribeLocalEvent>(OnUtilityVerb); } - private void OnSolutionChanged(Entity ent, ref SolutionContainerChangedEvent ev) + private void OnSolutionChanged(Entity ent, ref SolutionChangedEvent ev) { var soln = GetSolutionsDNA(ev.Solution); if (soln.Count > 0) @@ -152,12 +152,9 @@ namespace Content.Server.Forensics public List GetSolutionsDNA(EntityUid uid) { List list = new(); - if (TryComp(uid, out var comp)) + foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions(uid)) { - foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions((uid, comp))) - { - list.AddRange(GetSolutionsDNA(soln.Comp.Solution)); - } + list.AddRange(GetSolutionsDNA(soln.Comp.Solution)); } return list; } diff --git a/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs b/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs index d1df5177d1..3a4a93e732 100644 --- a/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs +++ b/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs @@ -78,7 +78,7 @@ namespace Content.Server.Kitchen.EntitySystems SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(OnSolutionChange); + SubscribeLocalEvent(OnSolutionChange); SubscribeLocalEvent(OnContentUpdate); SubscribeLocalEvent(OnContentUpdate); SubscribeLocalEvent(OnInteractUsing, after: new[] { typeof(AnchorableSystem) }); @@ -181,9 +181,7 @@ namespace Content.Server.Kitchen.EntitySystems if (TryComp(entity, out var tempComp)) _temperature.ChangeHeat(entity, heatToAdd * component.ObjectHeatMultiplier, false, tempComp); - if (!TryComp(entity, out var solutions)) - continue; - foreach (var (_, soln) in _solutionContainer.EnumerateSolutions((entity, solutions))) + foreach (var (_, soln) in _solutionContainer.EnumerateSolutions(entity)) { var solution = soln.Comp.Solution; if (solution.Temperature > component.TemperatureUpperThreshold) @@ -319,7 +317,7 @@ namespace Content.Server.Kitchen.EntitySystems args.Handled = true; } - private void OnSolutionChange(Entity ent, ref SolutionContainerChangedEvent args) + private void OnSolutionChange(Entity ent, ref SolutionChangedEvent args) { UpdateUserInterfaceState(ent, ent.Comp); } diff --git a/Content.Server/Materials/MaterialReclaimerSystem.cs b/Content.Server/Materials/MaterialReclaimerSystem.cs index c00c938865..7e3d998f55 100644 --- a/Content.Server/Materials/MaterialReclaimerSystem.cs +++ b/Content.Server/Materials/MaterialReclaimerSystem.cs @@ -69,20 +69,19 @@ public sealed class MaterialReclaimerSystem : SharedMaterialReclaimerSystem private void OnInteractUsing(Entity entity, ref InteractUsingEvent args) { - if (args.Handled) + if (args.Handled || entity.Comp.SolutionContainerId == null) return; // if we're trying to get a solution out of the reclaimer, don't destroy it if (_solutionContainer.TryGetSolution(entity.Owner, entity.Comp.SolutionContainerId, out _, out var outputSolution) && outputSolution.Contents.Any()) { - if (TryComp(args.Used, out var managerComponent) && - _solutionContainer.EnumerateSolutions((args.Used, managerComponent)).Any(s => s.Solution.Comp.Solution.AvailableVolume > 0)) + if (_solutionContainer.EnumerateSolutions(args.Used).Any(s => s.Solution.Comp.Solution.AvailableVolume > 0)) { if (_openable.IsClosed(args.Used)) return; if (TryComp(args.Used, out var transfer) && - transfer.CanReceive) + transfer.CanSend) return; } } @@ -250,7 +249,7 @@ public sealed class MaterialReclaimerSystem : SharedMaterialReclaimerSystem TransformComponent? xform = null, PhysicalCompositionComponent? composition = null) { - if (!Resolve(reclaimer, ref reclaimerComponent, ref xform)) + if (!Resolve(reclaimer, ref reclaimerComponent, ref xform) || reclaimerComponent.SolutionContainerId == null) return; efficiency *= reclaimerComponent.Efficiency; diff --git a/Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs b/Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs index 2a13d07797..470e61fb87 100644 --- a/Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs @@ -34,7 +34,7 @@ public sealed class SliceableFoodSystem : EntitySystem SubscribeLocalEvent(OnInteractUsing); SubscribeLocalEvent(OnSlicedoAfter); - SubscribeLocalEvent(OnComponentStartup); + SubscribeLocalEvent(OnMapInit); } private void OnInteractUsing(Entity entity, ref InteractUsingEvent args) @@ -156,10 +156,9 @@ public sealed class SliceableFoodSystem : EntitySystem _solutionContainer.TryAddSolution(itsSoln.Value, lostSolutionPart); } - private void OnComponentStartup(Entity entity, ref ComponentStartup args) + private void OnMapInit(Entity entity, ref MapInitEvent args) { - // TODO: When Food Component is fully kill delete this awful method - // This exists just to make tests fail I guess, awesome! + // This exists just to make tests fail! // If you're here because your test just failed, make sure that: // Your food has the edible component // The solution listed in the edible component exists diff --git a/Content.Server/Nutrition/EntitySystems/SmokingSystem.SmokingPipe.cs b/Content.Server/Nutrition/EntitySystems/SmokingSystem.SmokingPipe.cs index 9a1d64b2eb..006cbcc42c 100644 --- a/Content.Server/Nutrition/EntitySystems/SmokingSystem.SmokingPipe.cs +++ b/Content.Server/Nutrition/EntitySystems/SmokingSystem.SmokingPipe.cs @@ -81,11 +81,10 @@ namespace Content.Server.Nutrition.EntitySystems EntityUid contents = entity.Comp.BowlSlot.Item.Value; - if (!TryComp(contents, out var reagents) || - !_solutionContainerSystem.TryGetSolution(smokable.Owner, smokable.Comp.Solution, out var pipeSolution, out _)) + if (!_solutionContainerSystem.TryGetSolution(smokable.Owner, smokable.Comp.Solution, out var pipeSolution, out _)) return false; - foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions((contents, reagents))) + foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions(contents)) { var reagentSolution = soln.Comp.Solution; _solutionContainerSystem.TryAddSolution(pipeSolution.Value, reagentSolution); diff --git a/Content.Server/Nutrition/EntitySystems/TrashOnSolutionEmptySystem.cs b/Content.Server/Nutrition/EntitySystems/TrashOnSolutionEmptySystem.cs index 08ff0c1d41..a74376c608 100644 --- a/Content.Server/Nutrition/EntitySystems/TrashOnSolutionEmptySystem.cs +++ b/Content.Server/Nutrition/EntitySystems/TrashOnSolutionEmptySystem.cs @@ -18,7 +18,7 @@ namespace Content.Server.Nutrition.EntitySystems { base.Initialize(); SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(OnSolutionChange); + SubscribeLocalEvent(OnSolutionChange); } public void OnMapInit(Entity entity, ref MapInitEvent args) @@ -26,16 +26,13 @@ namespace Content.Server.Nutrition.EntitySystems CheckSolutions(entity); } - public void OnSolutionChange(Entity entity, ref SolutionContainerChangedEvent args) + public void OnSolutionChange(Entity entity, ref SolutionChangedEvent args) { CheckSolutions(entity); } public void CheckSolutions(Entity entity) { - if (!HasComp(entity)) - return; - if (_solutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.Solution, out _, out var solution)) UpdateTags(entity, solution); } diff --git a/Content.Server/Power/EntitySystems/RiggableSystem.cs b/Content.Server/Power/EntitySystems/RiggableSystem.cs index 0bff0f4ba8..fd65afb370 100644 --- a/Content.Server/Power/EntitySystems/RiggableSystem.cs +++ b/Content.Server/Power/EntitySystems/RiggableSystem.cs @@ -25,7 +25,7 @@ public sealed class RiggableSystem : EntitySystem base.Initialize(); SubscribeLocalEvent(OnRejuvenate); SubscribeLocalEvent(OnMicrowaved); - SubscribeLocalEvent(OnSolutionChanged); + SubscribeLocalEvent(OnSolutionChanged); SubscribeLocalEvent(OnChargeChanged); } @@ -47,13 +47,14 @@ public sealed class RiggableSystem : EntitySystem } } - private void OnSolutionChanged(Entity entity, ref SolutionContainerChangedEvent args) + private void OnSolutionChanged(Entity entity, ref SolutionChangedEvent args) { - if (args.SolutionId != entity.Comp.Solution) + if (args.Solution.Comp.Id != entity.Comp.Solution) return; var wasRigged = entity.Comp.IsRigged; - var quantity = args.Solution.GetReagentQuantity(entity.Comp.RequiredQuantity.Reagent); + var solution = args.Solution.Comp.Solution; + var quantity = solution.GetReagentQuantity(entity.Comp.RequiredQuantity.Reagent); entity.Comp.IsRigged = quantity >= entity.Comp.RequiredQuantity.Quantity; if (entity.Comp.IsRigged && !wasRigged) diff --git a/Content.Server/Power/Generator/ChemicalFuelGeneratorAdapterComponent.cs b/Content.Server/Power/Generator/ChemicalFuelGeneratorAdapterComponent.cs index d36828eb83..1c601cec7f 100644 --- a/Content.Server/Power/Generator/ChemicalFuelGeneratorAdapterComponent.cs +++ b/Content.Server/Power/Generator/ChemicalFuelGeneratorAdapterComponent.cs @@ -27,7 +27,7 @@ public sealed partial class ChemicalFuelGeneratorAdapterComponent : Component public string SolutionName = "tank"; /// - /// The solution on the to use. + /// The solution to use. /// [ViewVariables] public Entity? Solution = null; diff --git a/Content.Server/Stunnable/Systems/StunbatonSystem.cs b/Content.Server/Stunnable/Systems/StunbatonSystem.cs index 90d2dc7588..48b2715cac 100644 --- a/Content.Server/Stunnable/Systems/StunbatonSystem.cs +++ b/Content.Server/Stunnable/Systems/StunbatonSystem.cs @@ -26,7 +26,7 @@ namespace Content.Server.Stunnable.Systems base.Initialize(); SubscribeLocalEvent(OnExamined); - SubscribeLocalEvent(OnSolutionChange); + SubscribeLocalEvent(OnSolutionChange); SubscribeLocalEvent(OnStaminaHitAttempt); SubscribeLocalEvent(OnChargeChanged); } @@ -75,7 +75,7 @@ namespace Content.Server.Stunnable.Systems } // https://github.com/space-wizards/space-station-14/pull/17288#discussion_r1241213341 - private void OnSolutionChange(Entity entity, ref SolutionContainerChangedEvent args) + private void OnSolutionChange(Entity entity, ref SolutionChangedEvent args) { // Explode if baton is activated and rigged. if (!TryComp(entity, out var riggable) || diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.Solution.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.Solution.cs index eddc8739bb..166f52b920 100644 --- a/Content.Server/Weapons/Ranged/Systems/GunSystem.Solution.cs +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.Solution.cs @@ -18,7 +18,7 @@ public sealed partial class GunSystem base.InitializeSolution(); SubscribeLocalEvent(OnSolutionMapInit); - SubscribeLocalEvent(OnSolutionChanged); + SubscribeLocalEvent(OnSolutionChanged); } private void OnSolutionMapInit(Entity entity, ref MapInitEvent args) @@ -26,10 +26,10 @@ public sealed partial class GunSystem UpdateSolutionShots(entity); } - private void OnSolutionChanged(Entity entity, ref SolutionContainerChangedEvent args) + private void OnSolutionChanged(Entity entity, ref SolutionChangedEvent args) { - if (args.Solution.Name == entity.Comp.SolutionId) - UpdateSolutionShots(entity, args.Solution); + if (args.Solution.Comp.Id == entity.Comp.SolutionId) + UpdateSolutionShots(entity, args.Solution.Comp.Solution); } protected override void UpdateSolutionShots(Entity ent, Solution? solution = null) diff --git a/Content.Shared/Administration/EditSolutionsEuiState.cs b/Content.Shared/Administration/EditSolutionsEuiState.cs index 636a57c520..7fee516d9d 100644 --- a/Content.Shared/Administration/EditSolutionsEuiState.cs +++ b/Content.Shared/Administration/EditSolutionsEuiState.cs @@ -11,7 +11,7 @@ namespace Content.Shared.Administration public readonly List<(string, NetEntity)>? Solutions; public readonly GameTick Tick; - public EditSolutionsEuiState(NetEntity target, List<(string, NetEntity)>? solutions, GameTick tick) + public EditSolutionsEuiState(NetEntity target, List<(string, NetEntity)> solutions, GameTick tick) { Target = target; Solutions = solutions; diff --git a/Content.Shared/Body/Components/BloodstreamComponent.cs b/Content.Shared/Body/Components/BloodstreamComponent.cs index e1f60f0376..dca7d58be7 100644 --- a/Content.Shared/Body/Components/BloodstreamComponent.cs +++ b/Content.Shared/Body/Components/BloodstreamComponent.cs @@ -148,10 +148,10 @@ public sealed partial class BloodstreamComponent : Component /// Defines which reagents are considered as 'blood' and how much of it is normal. /// /// - /// Slime-people might use slime as their blood or something like that. + /// Default is human blood at 5 liters (600u) of blood. /// [DataField, AutoNetworkedField] - public Solution BloodReferenceSolution = new([new("Blood", 300)]); + public Solution BloodReferenceSolution = new([new("Blood", 600)]); /// /// Caches the blood data of an entity. diff --git a/Content.Shared/Body/Systems/LungSystem.cs b/Content.Shared/Body/Systems/LungSystem.cs index 8a7a00001a..ec11d417bb 100644 --- a/Content.Shared/Body/Systems/LungSystem.cs +++ b/Content.Shared/Body/Systems/LungSystem.cs @@ -20,7 +20,7 @@ public sealed class LungSystem : EntitySystem public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnComponentInit); + SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnGotEquipped); SubscribeLocalEvent(OnGotUnequipped); } @@ -44,13 +44,12 @@ public sealed class LungSystem : EntitySystem } } - private void OnComponentInit(Entity entity, ref ComponentInit args) + private void OnMapInit(Entity entity, ref MapInitEvent args) { - if (_solutionContainerSystem.EnsureSolution(entity.Owner, entity.Comp.SolutionName, out var solution)) - { - solution.MaxVolume = 100.0f; - solution.CanReact = false; // No dexalin lungs - } + _solutionContainerSystem.EnsureSolution(entity.Owner, entity.Comp.SolutionName, out var solution); + + solution.Comp.Solution.MaxVolume = 100.0f; + solution.Comp.Solution.CanReact = false; // No dexalin lungs } // TODO: JUST METABOLIZE GASES DIRECTLY DON'T CONVERT TO REAGENTS!!! (Needs Metabolism refactor :B) diff --git a/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs b/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs index bde65b99fe..6e8724494b 100644 --- a/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs +++ b/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs @@ -110,10 +110,25 @@ public abstract class SharedBloodstreamSystem : EntitySystem } } - private void OnMapInit(Entity ent, ref MapInitEvent args) + private void OnMapInit(Entity entity, ref MapInitEvent args) { - ent.Comp.NextUpdate = _timing.CurTime + ent.Comp.AdjustedUpdateInterval; - DirtyField(ent, ent.Comp, nameof(BloodstreamComponent.NextUpdate)); + entity.Comp.NextUpdate = _timing.CurTime + entity.Comp.AdjustedUpdateInterval; + DirtyField(entity, entity.Comp, nameof(BloodstreamComponent.NextUpdate)); + + SolutionContainer.EnsureSolution(entity.Owner, entity.Comp.BloodSolutionName, out var bloodSolution); + SolutionContainer.EnsureSolution(entity.Owner, entity.Comp.BloodTemporarySolutionName, out var tempSolution); + SolutionContainer.EnsureSolution(entity.Owner, entity.Comp.MetabolitesSolutionName, out var metabolitesSolution); + + bloodSolution.Comp.Solution.MaxVolume = entity.Comp.BloodReferenceSolution.Volume * entity.Comp.MaxVolumeModifier; + metabolitesSolution.Comp.Solution.MaxVolume = bloodSolution.Comp.Solution.MaxVolume; + tempSolution.Comp.Solution.MaxVolume = entity.Comp.BleedPuddleThreshold * 4; // give some leeway, for chemstream as well + entity.Comp.BloodReferenceSolution.SetReagentData(GetEntityBloodData((entity, entity.Comp))); + + // Fill blood solution with BLOOD + // The DNA string might not be initialized yet, but the reagent data gets updated in the GenerateDnaEvent subscription + var solution = entity.Comp.BloodReferenceSolution.Clone(); + solution.ScaleTo(entity.Comp.BloodReferenceSolution.Volume - bloodSolution.Comp.Solution.Volume); + bloodSolution.Comp.Solution.AddSolution(solution, PrototypeManager); } // prevent the infamous UdderSystem debug assert, see https://github.com/space-wizards/space-station-14/pull/35314 @@ -157,8 +172,8 @@ public abstract class SharedBloodstreamSystem : EntitySystem private void OnReactionAttempt(Entity ent, ref SolutionRelayEvent args) { - if (args.Name != ent.Comp.BloodSolutionName - && args.Name != ent.Comp.BloodTemporarySolutionName) + if (args.Solution.Comp.Id != ent.Comp.BloodSolutionName + && args.Solution.Comp.Id != ent.Comp.BloodTemporarySolutionName) { return; } diff --git a/Content.Shared/Body/Systems/StomachSystem.cs b/Content.Shared/Body/Systems/StomachSystem.cs index 9adc79c6ea..16d2f54f75 100644 --- a/Content.Shared/Body/Systems/StomachSystem.cs +++ b/Content.Shared/Body/Systems/StomachSystem.cs @@ -2,7 +2,6 @@ using Content.Shared.Body.Components; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Components.SolutionManager; using Content.Shared.Chemistry.EntitySystems; -using Robust.Shared.Utility; namespace Content.Shared.Body.Systems; @@ -12,33 +11,22 @@ public sealed class StomachSystem : EntitySystem public const string DefaultSolutionName = "stomach"; - public bool CanTransferSolution( - EntityUid uid, - Solution solution, - StomachComponent? stomach = null, - SolutionContainerManagerComponent? solutions = null) + public bool CanTransferSolution(Entity entity, Solution solution) { - return Resolve(uid, ref stomach, ref solutions, logMissing: false) - && _solutionContainerSystem.ResolveSolution((uid, solutions), DefaultSolutionName, ref stomach.Solution, out var stomachSolution) + return Resolve(entity, ref entity.Comp1, logMissing: false) + && _solutionContainerSystem.ResolveSolution((entity, entity.Comp2), DefaultSolutionName, ref entity.Comp1.Solution, out var stomachSolution) // TODO: For now no partial transfers. Potentially change by design && stomachSolution.CanAddSolution(solution); } - public bool TryTransferSolution( - EntityUid uid, - Solution solution, - StomachComponent? stomach = null, - SolutionContainerManagerComponent? solutions = null) + public bool TryTransferSolution(Entity entity, Solution solution) { - if (!Resolve(uid, ref stomach, ref solutions, logMissing: false) - || !_solutionContainerSystem.ResolveSolution((uid, solutions), DefaultSolutionName, ref stomach.Solution) - || !CanTransferSolution(uid, solution, stomach, solutions)) - { + if (!Resolve(entity, ref entity.Comp1, logMissing: false) + || !_solutionContainerSystem.ResolveSolution((entity, entity.Comp2), DefaultSolutionName, ref entity.Comp1.Solution) + || !CanTransferSolution(entity, solution)) return false; - } - - _solutionContainerSystem.TryAddSolution(stomach.Solution.Value, solution); + _solutionContainerSystem.TryAddSolution(entity.Comp1.Solution.Value, solution); return true; } } diff --git a/Content.Shared/Chemistry/Components/Solution.cs b/Content.Shared/Chemistry/Components/Solution.cs index bea7a0a071..129140b66c 100644 --- a/Content.Shared/Chemistry/Components/Solution.cs +++ b/Content.Shared/Chemistry/Components/Solution.cs @@ -1,6 +1,5 @@ using System.Collections; using System.Linq; -using Content.Shared.Chemistry.Components.SolutionManager; using Content.Shared.Chemistry.Reagent; using Content.Shared.FixedPoint; using JetBrains.Annotations; @@ -59,12 +58,6 @@ namespace Content.Shared.Chemistry.Components [DataField] public float Temperature { get; set; } = 293.15f; - /// - /// The name of this solution, if it is contained in some - /// - [DataField] - public string? Name; - /// /// Checks if a solution can fit into the container. /// @@ -205,7 +198,7 @@ namespace Content.Shared.Chemistry.Components DebugTools.Assert(!Contents.Any(x => x.Quantity <= FixedPoint2.Zero)); // No duplicate reagents iDs - DebugTools.Assert(Contents.Select(x => x.Reagent).ToHashSet().Count == Contents.Count); + DebugTools.Assert(Contents.Select(x => x.Reagent).ToHashSet().Count == Contents.Count, $"Solution: {this}, contained duplcate contents {Contents}"); // If it isn't flagged as dirty, check heat capacity is correct. if (!_heatCapacityDirty) diff --git a/Content.Shared/Chemistry/Components/SolutionComponent.cs b/Content.Shared/Chemistry/Components/SolutionComponent.cs index 847f8f03c9..e06919dccb 100644 --- a/Content.Shared/Chemistry/Components/SolutionComponent.cs +++ b/Content.Shared/Chemistry/Components/SolutionComponent.cs @@ -1,6 +1,7 @@ using Content.Shared.Chemistry.Components.SolutionManager; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Materials; +using Content.Shared.Temperature.Components; using Robust.Shared.GameStates; using Robust.Shared.Serialization; @@ -8,23 +9,33 @@ namespace Content.Shared.Chemistry.Components; /// /// Holds the composition of an entity made from reagents and its reagent temperature. -/// If the entity is used to represent a collection of reagents inside of a container such as a beaker, syringe, bloodstream, food, or similar the entity is tracked by a on the container and has a tracking which container it's in. +/// If the entity is used to represent a collection of reagents inside of a container such as a beaker, syringe, bloodstream, food, or similar the entity is tracked by a on the container and has a tracking which container it's in. /// /// -/// Once reagents and materials have been merged this component should be depricated in favor of using a combination of and . May require minor reworks to both. +/// Once reagents and materials have been merged this component should be depricated in favor of using a combination of and . May require minor reworks to both. /// [RegisterComponent, NetworkedComponent] -[Access(typeof(SharedSolutionContainerSystem))] public sealed partial class SolutionComponent : Component { + public const string DefaultSolutionId = "solution"; + + /// + /// The name of this solution. This value should *never* change once the solution is initialized. + /// + [DataField] + [Access(typeof(SharedSolutionContainerSystem))] + public string Id = DefaultSolutionId; + /// /// The reagents the entity is composed of and their temperature. /// - [DataField] + [DataField, AlwaysPushInheritance] public Solution Solution = new(); } - +/// +/// We manually network the component state as it raises one less event and therefore is better performance wise. +/// [Serializable, NetSerializable] public sealed class SolutionComponentState(Solution solution) : ComponentState { diff --git a/Content.Shared/Chemistry/Components/SolutionManager/ContainedSolutionComponent.cs b/Content.Shared/Chemistry/Components/SolutionManager/ContainedSolutionComponent.cs index d648a9f00c..25c36e0f16 100644 --- a/Content.Shared/Chemistry/Components/SolutionManager/ContainedSolutionComponent.cs +++ b/Content.Shared/Chemistry/Components/SolutionManager/ContainedSolutionComponent.cs @@ -12,6 +12,7 @@ namespace Content.Shared.Chemistry.Components.SolutionManager; /// The field should then be extracted out into this component. /// Solution entities would just become an apporpriately composed entity hanging out in the container. /// Will probably require entities in components being given a relation to associate themselves with their container. +/// TODO: Proper relations system so this can be initialized with a SolutionComponent attached to it :) /// [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedSolutionContainerSystem))] @@ -20,12 +21,6 @@ public sealed partial class ContainedSolutionComponent : Component /// /// The entity that the solution is contained in. /// - [DataField(required: true), AutoNetworkedField] + [DataField, AutoNetworkedField] public EntityUid Container; - - /// - /// The name/key of the container the solution is located in. - /// - [DataField(required: true), AutoNetworkedField] - public string ContainerName = default!; } diff --git a/Content.Shared/Chemistry/Components/SolutionManager/SolutionContainerManagerComponent.cs b/Content.Shared/Chemistry/Components/SolutionManager/SolutionContainerManagerComponent.cs index 4000a29021..26e6346c8a 100644 --- a/Content.Shared/Chemistry/Components/SolutionManager/SolutionContainerManagerComponent.cs +++ b/Content.Shared/Chemistry/Components/SolutionManager/SolutionContainerManagerComponent.cs @@ -4,11 +4,14 @@ using Robust.Shared.GameStates; namespace Content.Shared.Chemistry.Components.SolutionManager; -/// -/// A map of the solution entities contained within this entity. -/// Every solution entity this maps should have a to track its state and a to track its container. -/// -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +/// +/// Exists for simple backwards compatibility. +/// On this component will transfer all its data where it can to a +/// Then it will delete itself. +/// This component will be deleted in the indeterminate future. +/// +[Obsolete] +[RegisterComponent] [Access(typeof(SharedSolutionContainerSystem))] public sealed partial class SolutionContainerManagerComponent : Component { @@ -22,7 +25,7 @@ public sealed partial class SolutionContainerManagerComponent : Component /// The names of each solution container attached to this entity. /// Actually accessing them must be done via . /// - [DataField, AutoNetworkedField] + [DataField] public HashSet Containers = new(DefaultCapacity); /// @@ -31,6 +34,6 @@ public sealed partial class SolutionContainerManagerComponent : Component /// /// Should be null after mapinit. /// - [DataField, AutoNetworkedField] - public Dictionary? Solutions = null; + [DataField] + public Dictionary? Solutions; } diff --git a/Content.Shared/Chemistry/Components/SolutionManager/SolutionManagerComponent.cs b/Content.Shared/Chemistry/Components/SolutionManager/SolutionManagerComponent.cs new file mode 100644 index 0000000000..99f7355bba --- /dev/null +++ b/Content.Shared/Chemistry/Components/SolutionManager/SolutionManagerComponent.cs @@ -0,0 +1,37 @@ +using Content.Shared.Chemistry.EntitySystems; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Chemistry.Components.SolutionManager; + +/// +/// Allows for an entity to have and manage multiple solutions. +/// Spawns additional solutions from their prototypes, and stores them in a container. +/// Also used in the case another component spawns a solution for this entity. +/// Every solution entity this maps should have a to track its state and a to track its container. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SharedSolutionContainerSystem))] +public sealed partial class SolutionManagerComponent : Component +{ + public static readonly string DefaultContainerId = "solutions"; + + /// + /// The names of the container for solutions attached to this entity. + /// + [DataField, AutoNetworkedField] + public string Container = DefaultContainerId; + + /// + /// A cache of solutions currently attached to this entity. + /// + [ViewVariables] + [Access(typeof(SharedSolutionContainerSystem), Other = AccessPermissions.None)] + public Dictionary> Solutions = new (); + + /// + /// A list of solution entities to spawn when this component starts up. + /// + [DataField("solutions", readOnly: true)] + public List SolutionEnts = new (); +} diff --git a/Content.Shared/Chemistry/Components/SolutionTransferComponent.cs b/Content.Shared/Chemistry/Components/SolutionTransferComponent.cs index 149fe3f643..639506cd4d 100644 --- a/Content.Shared/Chemistry/Components/SolutionTransferComponent.cs +++ b/Content.Shared/Chemistry/Components/SolutionTransferComponent.cs @@ -25,7 +25,7 @@ public sealed partial class SolutionTransferComponent : Component /// The maximum amount of solution that can be transferred at once from this solution. /// [DataField("maxTransferAmount"), AutoNetworkedField] - public FixedPoint2 MaximumTransferAmount = FixedPoint2.New(100); + public FixedPoint2 MaximumTransferAmount = FixedPoint2.New(120); /// /// Can this entity take reagent from reagent tanks? diff --git a/Content.Shared/Chemistry/EntitySystems/ReactiveContainerSystem.cs b/Content.Shared/Chemistry/EntitySystems/ReactiveContainerSystem.cs index 2bfa1c9de3..34acfee504 100644 --- a/Content.Shared/Chemistry/EntitySystems/ReactiveContainerSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/ReactiveContainerSystem.cs @@ -17,7 +17,7 @@ public sealed class ReactiveContainerSystem : EntitySystem base.Initialize(); SubscribeLocalEvent(OnInserted); - SubscribeLocalEvent(OnSolutionChange); + SubscribeLocalEvent(OnSolutionChange); } private void OnInserted(EntityUid uid, ReactiveContainerComponent comp, EntInsertedIntoContainerMessage args) @@ -34,7 +34,7 @@ public sealed class ReactiveContainerSystem : EntitySystem _reactiveSystem.DoEntityReaction(args.Entity, solution, ReactionMethod.Touch); } - private void OnSolutionChange(EntityUid uid, ReactiveContainerComponent comp, SolutionContainerChangedEvent args) + private void OnSolutionChange(EntityUid uid, ReactiveContainerComponent comp, SolutionChangedEvent args) { // The changes are already networked as part of the same game state. if (_timing.ApplyingState) @@ -42,10 +42,10 @@ public sealed class ReactiveContainerSystem : EntitySystem if (!_solutionContainerSystem.TryGetSolution(uid, comp.Solution, out _, out var solution)) return; + if (solution.Volume == 0) return; - if (!TryComp(uid, out var manager)) - return; + if (!_containerSystem.TryGetContainer(uid, comp.Container, out var container)) return; diff --git a/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs b/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs index 697605af1d..a944b9ffd9 100644 --- a/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs @@ -23,17 +23,17 @@ public sealed class RehydratableSystem : EntitySystem { base.Initialize(); - SubscribeLocalEvent(OnSolutionChange); + SubscribeLocalEvent(OnSolutionChange); } - private void OnSolutionChange(Entity ent, ref SolutionContainerChangedEvent args) + private void OnSolutionChange(Entity ent, ref SolutionChangedEvent args) { // The changes are already networked as part of the same game state. if (_timing.ApplyingState) return; - var quantity = _solutions.GetTotalPrototypeQuantity(ent, ent.Comp.CatalystPrototype); - _adminLogger.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(ent.Owner)} was hydrated, now contains a solution of: {SharedSolutionContainerSystem.ToPrettyString(args.Solution)}."); + var quantity = _solutions.GetTotalPrototypeQuantity(ent.Owner, ent.Comp.CatalystPrototype); + _adminLogger.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(ent.Owner)} was hydrated, now contains a solution of: {SharedSolutionContainerSystem.ToPrettyString(args.Solution.Comp.Solution)}."); if (quantity != FixedPoint2.Zero && quantity >= ent.Comp.CatalystMinimum) { Expand(ent); diff --git a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Capabilities.cs b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Capabilities.cs index aa4c59e89f..6039c30c58 100644 --- a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Capabilities.cs +++ b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Capabilities.cs @@ -11,7 +11,7 @@ public abstract partial class SharedSolutionContainerSystem { #region Solution Accessors - public bool TryGetRefillableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) + public bool TryGetRefillableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) { if (!Resolve(entity, ref entity.Comp1, logMissing: false)) { @@ -22,7 +22,7 @@ public abstract partial class SharedSolutionContainerSystem return TryGetSolution((entity.Owner, entity.Comp2), entity.Comp1.Solution, out soln, out solution); } - public bool TryGetDrainableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) + public bool TryGetDrainableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) { if (!Resolve(entity, ref entity.Comp1, logMissing: false)) { @@ -33,9 +33,9 @@ public abstract partial class SharedSolutionContainerSystem return TryGetSolution((entity.Owner, entity.Comp2), entity.Comp1.Solution, out soln, out solution); } - public bool TryGetExtractableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) + public bool TryGetExtractableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) { - if (!Resolve(entity, ref entity.Comp1, logMissing: false)) + if (!Resolve(entity, ref entity.Comp1, logMissing: false) || entity.Comp1.GrindableSolutionName == null) { (soln, solution) = (default!, null); return false; @@ -44,7 +44,7 @@ public abstract partial class SharedSolutionContainerSystem return TryGetSolution((entity.Owner, entity.Comp2), entity.Comp1.GrindableSolutionName, out soln, out solution); } - public bool TryGetDumpableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) + public bool TryGetDumpableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) { if (!Resolve(entity, ref entity.Comp1, logMissing: false)) { @@ -55,7 +55,7 @@ public abstract partial class SharedSolutionContainerSystem return TryGetSolution((entity.Owner, entity.Comp2), entity.Comp1.Solution, out soln, out solution); } - public bool TryGetDrawableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) + public bool TryGetDrawableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) { if (!Resolve(entity, ref entity.Comp1, logMissing: false)) { @@ -66,7 +66,7 @@ public abstract partial class SharedSolutionContainerSystem return TryGetSolution((entity.Owner, entity.Comp2), entity.Comp1.Solution, out soln, out solution); } - public bool TryGetInjectableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) + public bool TryGetInjectableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) { if (!Resolve(entity, ref entity.Comp1, logMissing: false)) { @@ -77,7 +77,7 @@ public abstract partial class SharedSolutionContainerSystem return TryGetSolution((entity.Owner, entity.Comp2), entity.Comp1.Solution, out soln, out solution); } - public bool TryGetFitsInDispenser(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) + public bool TryGetFitsInDispenser(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) { if (!Resolve(entity, ref entity.Comp1, logMissing: false)) { @@ -88,7 +88,7 @@ public abstract partial class SharedSolutionContainerSystem return TryGetSolution((entity.Owner, entity.Comp2), entity.Comp1.Solution, out soln, out solution); } - public bool TryGetMixableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) + public bool TryGetMixableSolution(Entity entity, [NotNullWhen(true)] out Entity? soln, [NotNullWhen(true)] out Solution? solution) { if (!Resolve(entity, ref entity.Comp1, logMissing: false)) { @@ -148,13 +148,17 @@ public abstract partial class SharedSolutionContainerSystem #region Static Methods + public static string ToPrettyString(SolutionComponent solution) + { + var sb = new StringBuilder($"{solution.Id}:"); + sb.Append(ToPrettyString(solution.Solution)); + return sb.ToString(); + } + public static string ToPrettyString(Solution solution) { var sb = new StringBuilder(); - if (solution.Name == null) - sb.Append("["); - else - sb.Append($"{solution.Name}:["); + sb.Append("["); var first = true; foreach (var (id, quantity) in solution.Contents) { diff --git a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Compatibility.cs b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Compatibility.cs new file mode 100644 index 0000000000..4ae9aba173 --- /dev/null +++ b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Compatibility.cs @@ -0,0 +1,79 @@ +using Content.Shared.Chemistry.Components.SolutionManager; +using Robust.Shared.Containers; + +namespace Content.Shared.Chemistry.EntitySystems; + +/// +/// This exists so that entity prototypes and maps with can load their solutions. +/// This system is extremely simple and will not have compatibility for new features that come as a result of future refactors. +/// This compatibility layer will degrade over time and eventually break as more solution logic relies on well-defined prototypes. +/// This is only here to give you more time to port your solutions to the new system. It is going to be deleted eventually. +/// You have been warned. +/// +public abstract partial class SharedSolutionContainerSystem +{ + public void InitializeContainerManager() + { + SubscribeLocalEvent(OnSolutionContainerInit); + } + + private void OnSolutionContainerInit(Entity container, ref MapInitEvent args) + { + // Create the manager, this should also create a container, so we ensure it exists. + EnsureComp(container, out var manager); + var solutionContainer = ContainerSystem.EnsureContainer(container, manager.Container); + + // First, if this entity was saved with an entity in a container, try to put it in the SolutionManager + foreach (var name in container.Comp.Containers) + { + if (ContainerSystem.GetContainer(container, $"solution@{name}") is not ContainerSlot slot || slot.ContainedEntity is not { } solutionUid) + continue; + + if (!SolutionQuery.TryComp(solutionUid, out var solution)) + continue; + + if (TryGetSolution(container.Owner, name, out var solutionEnt)) + { + // Only a warning so tests don't fail. If you're using this to find maps/prototypes which need porting, change this to Log.Error so tests fail. + Log.Warning($"Attempted to port a solution id: {name} entity: {ToPrettyString(solutionUid)} " + + $"from a {nameof(SolutionContainerManagerComponent)} on {ToPrettyString(container)}, {MetaData(container).EntityPrototype}, " + + $"but the entity already had a solution with that id."); + solutionEnt.Value.Comp.Solution = solution.Solution; + } + else + { + ContainerSystem.Insert(solutionUid, solutionContainer, force: true); + } + + // We don't need it anymore + ContainerSystem.ShutdownContainer(slot); + } + + if (container.Comp.Solutions == null) + { + RemCompDeferred(container); + return; + } + + + // Next, if this entity was never initialized, create its solutions. + foreach (var (name, solution) in container.Comp.Solutions) + { + // Solution already exists so we ignore it. + if (EnsureSolution(container.Owner, name, out var solutionEnt)) + { + // Only a warning so tests don't fail. If you're using this to find maps/prototypes which need porting, change this to Log.Error so tests fail. + Log.Warning($"Attempted to port a solution id: {name} " + + $"from a {nameof(SolutionContainerManagerComponent)} on {ToPrettyString(container)}, {MetaData(container).EntityPrototype}, " + + $"but the entity already had a solution with that id."); + } + + // Clone the solution to the component. + solutionEnt.Comp.Solution = solution; + } + + // Clear its data + container.Comp.Solutions = null; + RemCompDeferred(container); + } +} diff --git a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Relays.cs b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Relays.cs index 11122415c5..cecc3e7210 100644 --- a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Relays.cs +++ b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.Relays.cs @@ -7,23 +7,6 @@ namespace Content.Shared.Chemistry.EntitySystems; #region Events -/// -/// Raised on the container of the solution entity when the contained solution is changed. -/// If you want to subscribe with the solution entity itself -/// then use instead. -/// -/// -/// This is always raised on the client when handling the component state so that we can update UIs accordingly. -/// You might need an IGameTiming.ApplyingState guard to prevent mispredicts if the changes from your subscription are -/// networked with the same game state. -/// -[ByRefEvent] -public record struct SolutionContainerChangedEvent(Solution Solution, string SolutionId) -{ - public readonly Solution Solution = Solution; - public readonly string SolutionId = SolutionId; -} - /// /// An event raised when more reagents are added to a (managed) solution than it can hold. /// @@ -47,13 +30,11 @@ public record struct SolutionContainerOverflowEvent(EntityUid SolutionEnt, Solut /// /// /// The event that is being relayed. -/// The container entity that the event is being relayed to. -/// The name of the solution entity that the event is being relayed from. +/// The container entity that the event is being relayed to. [ByRefEvent] -public record struct SolutionRelayEvent(TEvent Event, EntityUid ContainerEnt, string Name) +public record struct SolutionRelayEvent(TEvent Event, Entity Solution) { - public readonly EntityUid ContainerEnt = ContainerEnt; - public readonly string Name = Name; + public readonly Entity Solution = Solution; public TEvent Event = Event; } @@ -78,28 +59,12 @@ public abstract partial class SharedSolutionContainerSystem { protected void InitializeRelays() { - SubscribeLocalEvent(OnSolutionChanged); SubscribeLocalEvent(OnSolutionOverflow); SubscribeLocalEvent(RelaySolutionRefEvent); } #region Event Handlers - protected virtual void OnSolutionChanged(Entity entity, ref SolutionChangedEvent args) - { - var (solutionId, solutionComp) = args.Solution; - var solution = solutionComp.Solution; - - var relayEvent = new SolutionContainerChangedEvent(solution, entity.Comp.ContainerName); - RaiseLocalEvent(entity.Comp.Container, ref relayEvent); - - // The appearance changes are already networked as part of the same game state. - if (_timing.ApplyingState) - return; - - UpdateAppearance(entity.Comp.Container, (solutionId, solutionComp, entity.Comp)); - } - protected virtual void OnSolutionOverflow(Entity entity, ref SolutionOverflowEvent args) { var solution = args.Solution.Comp.Solution; @@ -117,18 +82,20 @@ public abstract partial class SharedSolutionContainerSystem private void RelaySolutionValEvent(EntityUid uid, ContainedSolutionComponent comp, TEvent @event) { - var relayEvent = new SolutionRelayEvent(@event, uid, comp.ContainerName); + var solution = Comp(uid); + var relayEvent = new SolutionRelayEvent(@event, (uid, solution)); RaiseLocalEvent(comp.Container, ref relayEvent); } private void RelaySolutionRefEvent(Entity entity, ref TEvent @event) { - var relayEvent = new SolutionRelayEvent(@event, entity.Owner, entity.Comp.ContainerName); + var solution = Comp(entity); + var relayEvent = new SolutionRelayEvent(@event, (entity, solution)); RaiseLocalEvent(entity.Comp.Container, ref relayEvent); @event = relayEvent.Event; } - private void RelaySolutionContainerEvent(EntityUid uid, SolutionContainerManagerComponent comp, TEvent @event) + private void RelaySolutionContainerEvent(EntityUid uid, SolutionManagerComponent comp, TEvent @event) { foreach (var (name, soln) in EnumerateSolutions((uid, comp))) { @@ -137,7 +104,7 @@ public abstract partial class SharedSolutionContainerSystem } } - private void RelaySolutionContainerEvent(Entity entity, ref TEvent @event) + private void RelaySolutionContainerEvent(Entity entity, ref TEvent @event) { foreach (var (name, soln) in EnumerateSolutions((entity.Owner, entity.Comp))) { diff --git a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs index e6e50b23b5..e921bc6442 100644 --- a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs @@ -1,6 +1,5 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Numerics; using System.Runtime.CompilerServices; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Components.SolutionManager; @@ -16,7 +15,6 @@ using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Shared.Containers; using Robust.Shared.GameStates; -using Robust.Shared.Map; using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Timing; @@ -27,9 +25,8 @@ namespace Content.Shared.Chemistry.EntitySystems; /// /// The event raised whenever a solution entity is modified. -/// Raised on the solution entity itself. -/// If you want to subscribe with the entity containing the solution entity -/// then use instead. +/// This event is raised on the owner of the solution. +/// If the changed solution is contained in a , it will be raised on the owner of that component. /// /// /// Raised after chemcial reactions and are handled. @@ -69,38 +66,42 @@ public partial record struct SolutionAccessAttemptEvent(string SolutionName) [UsedImplicitly] public abstract partial class SharedSolutionContainerSystem : EntitySystem { + public static readonly EntProtoId DefaultSolution = "Solution"; + + [Dependency] protected readonly IGameTiming Timing = default!; + [Dependency] protected readonly INetManager Net = 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!; - [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] protected readonly SharedHandsSystem Hands = default!; + + [Dependency] protected readonly EntityQuery ContainedQuery = default!; + [Dependency] protected readonly EntityQuery SolutionQuery = default!; + [Dependency] protected readonly EntityQuery SolutionManagerQuery = default!; public override void Initialize() { base.Initialize(); InitializeRelays(); + InitializeContainerManager(); SubscribeLocalEvent(OnSolutionGetState); SubscribeLocalEvent(OnSolutionHandleState); SubscribeLocalEvent(OnComponentInit); - SubscribeLocalEvent(OnSolutionStartup); + SubscribeLocalEvent(OnSolutionInit); SubscribeLocalEvent(OnSolutionShutdown); - SubscribeLocalEvent(OnContainerManagerInit); + SubscribeLocalEvent(OnExamineSolution); SubscribeLocalEvent>(OnSolutionExaminableVerb); - SubscribeLocalEvent(OnMapInit); - if (NetManager.IsServer) - { - SubscribeLocalEvent(OnContainerManagerShutdown); - SubscribeLocalEvent(OnContainedSolutionShutdown); - } + SubscribeLocalEvent(OnManagerInit); + SubscribeLocalEvent(OnManagerShutdown); + SubscribeLocalEvent(OnSolutionAdded); + SubscribeLocalEvent(OnSolutionRemoved); } private void OnSolutionGetState(Entity ent, ref ComponentGetState args) @@ -118,32 +119,37 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem // Always raise the event on the client so that we can update UIs accordingly. var changedEv = new SolutionChangedEvent(ent); RaiseLocalEvent(ent, ref changedEv); + + if (!ContainedQuery.TryComp(ent, out var contained) || !SolutionManagerQuery.TryComp(contained.Container, out var manager)) + return; + + manager.Solutions[ent.Comp.Id] = ent; } /// /// Attempts to resolve a solution associated with an entity. /// - /// The entity that holdes the container the solution entity is in. + /// The entity that holdes the container the solution entity is in. /// The name of the solution entities container. - /// A reference to a solution entity to load the associated solution entity into. Will be unchanged if not null. + /// A reference to a solution entity to load the associated solution entity into. Will be unchanged if not null. /// Returns the solution state of the solution entity. /// Whether the solution was successfully resolved. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool ResolveSolution(Entity container, string? name, [NotNullWhen(true)] ref Entity? entity, [NotNullWhen(true)] out Solution? solution) + public bool ResolveSolution(Entity entity, string name, [NotNullWhen(true)] ref Entity? solutionEnt, [NotNullWhen(true)] out Solution? solution) { - if (!ResolveSolution(container, name, ref entity)) + if (!ResolveSolution(entity, name, ref solutionEnt)) { solution = null; return false; } - solution = entity.Value.Comp.Solution; + solution = solutionEnt.Value.Comp.Solution; return true; } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool ResolveSolution(Entity container, string? name, [NotNullWhen(true)] ref Entity? entity) + public bool ResolveSolution(Entity container, string name, [NotNullWhen(true)] ref Entity? entity) { if (entity is not null) { @@ -159,171 +165,217 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem /// Attempts to fetch a solution entity associated with an entity. ///
/// - /// If the solution entity will be frequently accessed please use the equivalent method and cache the result. + /// If the solution entity will be frequently accessed please use the equivalent + /// + /// method and cache the result. /// - /// The entity the solution entity should be associated with. + /// The entity the solution entity should be associated with. /// The name of the solution entity to fetch. - /// Returns the solution entity that was fetched. + /// Returns the solution entity that was fetched. /// Returns the solution state of the solution entity that was fetched. /// /// Should we print an error if the solution specified by name is missing /// public bool TryGetSolution( - Entity container, - string? name, - [NotNullWhen(true)] out Entity? entity, + Entity entity, + string name, + [NotNullWhen(true)] out Entity? solutionEnt, [NotNullWhen(true)] out Solution? solution, bool errorOnMissing = false) { - if (!TryGetSolution(container, name, out entity, errorOnMissing: errorOnMissing)) + if (!TryGetSolution(entity, name, out solutionEnt, errorOnMissing: errorOnMissing)) { solution = null; return false; } - solution = entity.Value.Comp.Solution; + solution = solutionEnt.Value.Comp.Solution; return true; } - /// + /// public bool TryGetSolution( - Entity container, - string? name, - [NotNullWhen(true)] out Entity? entity, + Entity entity, + string name, + [NotNullWhen(true)] out Entity? solutionEnt, bool errorOnMissing = false) { // use connected container instead of entity from arguments, if it exists. - var ev = new GetConnectedContainerEvent(); - RaiseLocalEvent(container, ref ev); - if (ev.ContainerEntity.HasValue) - container = ev.ContainerEntity.Value; + solutionEnt = null; - EntityUid uid; - if (name is null) - uid = container; - else if ( - ContainerSystem.TryGetContainer(container, $"solution@{name}", out var solutionContainer) && - solutionContainer is ContainerSlot solutionSlot && - solutionSlot.ContainedEntity is { } containedSolution - ) + var ev = new GetConnectedContainerEvent(); + RaiseLocalEvent(entity, ref ev); + if (ev.ContainerEntity.HasValue) + entity = ev.ContainerEntity.Value; + + if (SolutionQuery.TryComp(entity, out var comp) && comp.Id == name) + { + solutionEnt = (entity.Owner, comp); + return true; + } + + if (!SolutionManagerQuery.Resolve(entity, ref entity.Comp, errorOnMissing)) + return false; + + if (entity.Comp.Solutions.TryGetValue(name, out var solution)) { var attemptEv = new SolutionAccessAttemptEvent(name); - RaiseLocalEvent(container, ref attemptEv); + RaiseLocalEvent(entity, ref attemptEv); if (attemptEv.Cancelled) - { - entity = null; return false; - } - uid = containedSolution; - } - else - { - entity = null; - if (!errorOnMissing) - return false; - Log.Error($"{ToPrettyString(container)} does not have a solution with ID: {name}"); - return false; + solutionEnt = solution; + return true; } - if (!TryComp(uid, out SolutionComponent? comp)) - { - entity = null; - if (!errorOnMissing) - return false; - Log.Error($"{ToPrettyString(container)} does not have a solution with ID: {name}"); - return false; - } + if (errorOnMissing) + Log.Error($"{ToPrettyString(entity)} does not have a solution with ID: {name}"); - entity = (uid, comp); - return true; + return false; } /// /// Version of TryGetSolution that doesn't take or return an entity. - /// Used for prototypes and with old code parity. - public bool TryGetSolution(SolutionContainerManagerComponent container, + /// Used for prototypes. + /// + public bool TryGetSolution(EntProtoId entProtoId, string name, [NotNullWhen(true)] out Solution? solution, bool errorOnMissing = false) { solution = null; - if (container.Solutions != null) - return container.Solutions.TryGetValue(name, out solution); - if (!errorOnMissing) + + if (!PrototypeManager.Resolve(entProtoId, out var proto)) return false; - Log.Error($"{container} does not have a solution with ID: {name}"); + + return TryGetSolution(proto, name, out solution, errorOnMissing); + } + + public bool TryGetSolution(EntityPrototype entProto, + string name, + [NotNullWhen(true)] out Solution? solution, + bool errorOnMissing = false) + { + solution = null; + + if (!TryGetSolutionFill(entProto, out var solutions)) + return false; + + foreach (var protoId in solutions) + { + if (!PrototypeManager.Resolve(protoId, out var proto)) + continue; + + if (!proto.TryGetComponent(out var sol, Factory)) + { + Log.Error($"Entity prototype {proto}, tried to spawn in a solution container in prototype {entProto.ID}, but had no {nameof(SolutionComponent)}"); + continue; + } + + if (sol.Id != name) + continue; + + solution = sol.Solution; + return true; + } + + if (errorOnMissing) + Log.Error($"{entProto.ID} does not have a solution with ID: {name}"); + return false; } - public IEnumerable<(string? Name, Entity Solution)> EnumerateSolutions(Entity container, bool includeSelf = true) + public IEnumerable<(string? Name, Entity Solution)> EnumerateSolutions(Entity entity, bool includeSelf = true) { - if (includeSelf && TryComp(container, out SolutionComponent? solutionComp)) - yield return (null, (container.Owner, solutionComp)); + if (includeSelf && SolutionQuery.TryComp(entity, out var solutionComp)) + yield return (solutionComp.Id, (entity.Owner, solutionComp)); - if (!Resolve(container, ref container.Comp, logMissing: false)) + if (!SolutionManagerQuery.Resolve(entity, ref entity.Comp, logMissing: false)) yield break; - foreach (var name in container.Comp.Containers) + foreach (var (id, solution) in entity.Comp.Solutions) { - var attemptEv = new SolutionAccessAttemptEvent(name); - RaiseLocalEvent(container, ref attemptEv); + var attemptEv = new SolutionAccessAttemptEvent(id); + RaiseLocalEvent(entity, ref attemptEv); if (attemptEv.Cancelled) continue; - if (ContainerSystem.GetContainer(container, $"solution@{name}") is ContainerSlot slot && slot.ContainedEntity is { } solutionId) - yield return (name, (solutionId, Comp(solutionId))); + yield return (id, solution); } } - public IEnumerable<(string Name, Solution Solution)> EnumerateSolutions(SolutionContainerManagerComponent container) + public IEnumerable<(string Id, Solution Solution)> EnumerateSolutions(EntityPrototype entProto) { - if (container.Solutions is not { Count: > 0 } solutions) + if (!TryGetSolutionFill(entProto, out var solutions)) yield break; - foreach (var (name, solution) in solutions) + foreach (var protoId in solutions) { - yield return (name, solution); + if (!PrototypeManager.Resolve(protoId, out var proto)) + continue; + + if (!proto.TryGetComponent(out var sol, Factory)) + { + Log.Error($"Entity prototype {proto}, tried to spawn in a solution container in prototype {entProto.ID}, but had no {nameof(SolutionComponent)}"); + continue; + } + + yield return (sol.Id, sol.Solution); } } + private bool TryGetSolutionFill(Entity entity, [NotNullWhen(true)] out List? fill) + { + fill = null; + if (!SolutionManagerQuery.Resolve(entity, ref entity.Comp)) + return false; - protected void UpdateAppearance(Entity container, Entity soln) + fill = entity.Comp.SolutionEnts; + return true; + } + + private bool TryGetSolutionFill(EntityPrototype entProto, [NotNullWhen(true)] out List? fill) + { + fill = null; + if (!entProto.TryGetComponent(out var manager, Factory)) + return false; + + fill = manager.SolutionEnts; + return true; + } + + protected void UpdateAppearance(Entity container, Entity soln) { var (uid, appearanceComponent) = container; if (!HasComp(uid) || !Resolve(uid, ref appearanceComponent, logMissing: false)) return; - var (_, comp, relation) = soln; - var solution = comp.Solution; + var solution = soln.Comp.Solution; AppearanceSystem.SetData(uid, SolutionContainerVisuals.FillFraction, solution.FillFraction, appearanceComponent); AppearanceSystem.SetData(uid, SolutionContainerVisuals.Color, solution.GetColor(PrototypeManager), appearanceComponent); - AppearanceSystem.SetData(uid, SolutionContainerVisuals.SolutionName, relation.ContainerName, appearanceComponent); + AppearanceSystem.SetData(uid, SolutionContainerVisuals.SolutionName, soln.Comp.Id, appearanceComponent); if (solution.GetPrimaryReagentId() is { } reagent) AppearanceSystem.SetData(uid, SolutionContainerVisuals.BaseOverride, reagent.ToString(), appearanceComponent); } - public FixedPoint2 GetTotalPrototypeQuantity(EntityUid owner, string reagentId) + public FixedPoint2 GetTotalPrototypeQuantity(Entity owner, string reagentId) { var reagentQuantity = FixedPoint2.New(0); - if (Exists(owner) - && TryComp(owner, out SolutionContainerManagerComponent? managerComponent)) + if (Exists(owner)) { - foreach (var (_, soln) in EnumerateSolutions((owner, managerComponent))) + foreach (var (_, solution) in EnumerateSolutions(owner)) { - var solution = soln.Comp.Solution; - reagentQuantity += solution.GetTotalPrototypeQuantity(reagentId); + reagentQuantity += solution.Comp.Solution.GetTotalPrototypeQuantity(reagentId); } } return reagentQuantity; } - /// /// Dirties a solution entity that has been modified and prompts updates to chemical reactions and overflow state. /// Should be invoked whenever a solution entity is modified. @@ -331,46 +383,37 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem /// /// 90% of this system is ensuring that this proc is invoked whenever a solution entity is changed. The other 10% is this proc. /// - /// + /// /// /// - public void UpdateChemicals(Entity soln, bool needsReactionsProcessing = true, ReactionMixerComponent? mixerComponent = null) + public void UpdateChemicals(Entity solution, bool needsReactionsProcessing = true, ReactionMixerComponent? mixerComponent = null) { - Dirty(soln); - - var (uid, comp) = soln; - var solution = comp.Solution; - // Process reactions - if (needsReactionsProcessing && solution.CanReact) - ChemicalReactionSystem.FullyReactSolution(soln, mixerComponent); + if (needsReactionsProcessing && solution.Comp.Solution.CanReact) + ChemicalReactionSystem.FullyReactSolution(solution, mixerComponent); - var overflow = solution.Volume - solution.MaxVolume; + var overflow = solution.Comp.Solution.Volume - solution.Comp.Solution.MaxVolume; if (overflow > FixedPoint2.Zero) { - var overflowEv = new SolutionOverflowEvent(soln, overflow); - RaiseLocalEvent(uid, ref overflowEv); + var overflowEv = new SolutionOverflowEvent(solution, overflow); + RaiseLocalEvent(solution, ref overflowEv); } - UpdateAppearance((uid, comp, null)); + var owner = GetSolutionOwner(solution); - var changedEv = new SolutionChangedEvent(soln); - RaiseLocalEvent(uid, ref changedEv); - } + var changedEv = new SolutionChangedEvent(solution); + RaiseLocalEvent(owner, ref changedEv); + Dirty(solution); - public void UpdateAppearance(Entity soln) - { - var (uid, comp, appearanceComponent) = soln; - var solution = comp.Solution; - - if (!Exists(uid) || !Resolve(uid, ref appearanceComponent, false)) + if (Timing.ApplyingState) return; - AppearanceSystem.SetData(uid, SolutionContainerVisuals.FillFraction, solution.FillFraction, appearanceComponent); - AppearanceSystem.SetData(uid, SolutionContainerVisuals.Color, solution.GetColor(PrototypeManager), appearanceComponent); + UpdateAppearance(owner, solution); + } - if (solution.GetPrimaryReagentId() is { } reagent) - AppearanceSystem.SetData(uid, SolutionContainerVisuals.BaseOverride, reagent.ToString(), appearanceComponent); + public EntityUid GetSolutionOwner(Entity entity) + { + return ContainedQuery.CompOrNull(entity)?.Container ?? entity.Owner; } /// @@ -830,27 +873,16 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem entity.Comp.Solution.ValidateSolution(); } - private void OnSolutionStartup(Entity entity, ref ComponentStartup args) + private void OnSolutionInit(Entity entity, ref MapInitEvent args) { UpdateChemicals(entity); } private void OnSolutionShutdown(Entity entity, ref ComponentShutdown args) { - RemoveAllSolution(entity); - } - - private void OnContainerManagerInit(Entity entity, ref ComponentInit args) - { - if (entity.Comp.Containers is not { Count: > 0 } containers) - return; - - var containerManager = EnsureComp(entity); - foreach (var name in containers) - { - // The actual solution entity should be directly held within the corresponding slot. - ContainerSystem.EnsureContainer(entity.Owner, $"solution@{name}", containerManager); - } + // If we are contained within another entity, update that entity. Otherwise, don't update if we're being deleted. + if (ContainedQuery.HasComp(entity) || !Terminating(entity)) + RemoveAllSolution(entity); } /// @@ -1049,211 +1081,132 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem return true; } - private void OnMapInit(Entity entity, ref MapInitEvent args) + /// + /// We want all our solutions spawned before MapInit. + /// They should only ever be attached to this entity so spawning them before MapInit should be fine. + /// + private void OnManagerInit(Entity entity, ref MapInitEvent args) { - EnsureAllSolutions(entity); + var container = ContainerSystem.EnsureContainer(entity.Owner, entity.Comp.Container); + foreach (var solution in entity.Comp.SolutionEnts) + { + CreateSolution(solution, container); + } } - private void OnContainerManagerShutdown(Entity entity, ref ComponentShutdown args) + private void OnManagerShutdown(Entity entity, ref ComponentShutdown args) { - foreach (var name in entity.Comp.Containers) - { - if (ContainerSystem.TryGetContainer(entity, $"solution@{name}", out var solutionContainer)) - ContainerSystem.ShutdownContainer(solutionContainer); - } - entity.Comp.Containers.Clear(); - } - - private void OnContainedSolutionShutdown(Entity entity, ref ComponentShutdown args) - { - if (TryComp(entity.Comp.Container, out SolutionContainerManagerComponent? container)) - { - container.Containers.Remove(entity.Comp.ContainerName); - Dirty(entity.Comp.Container, container); - } - - if (ContainerSystem.TryGetContainer(entity, $"solution@{entity.Comp.ContainerName}", out var solutionContainer)) + if (ContainerSystem.TryGetContainer(entity, entity.Comp.Container, out var solutionContainer)) ContainerSystem.ShutdownContainer(solutionContainer); } + private void OnSolutionAdded(Entity entity, ref EntInsertedIntoContainerMessage args) + { + // Container networking boilerplate + if (args.Container.ID != entity.Comp.Container || !SolutionQuery.TryComp(args.Entity, out var solution)) + return; + + // Don't add a solution entity with the same id as this entity's solution if it exists! + DebugTools.Assert(!TryComp(entity, out var sol) || sol.Id != solution.Id, $"Tried to add a solution {MetaData(args.Entity).EntityPrototype} {solution.Id} to {ToPrettyString(entity)} but it itself was a solution with a matching id!"); + + EnsureComp(args.Entity, out var contained); + contained.Container = entity.Owner; + + // Throw if we already have a solution with the same ID. Only throw on server to avoid prediction causing issues. + if (!entity.Comp.Solutions.TryAdd(solution.Id, (args.Entity, solution)) && Net.IsServer) + Log.Error($"Solution {ToPrettyString(entity)}, tried to add a solution with a duplicate id: {solution.Id}"); + } + + private void OnSolutionRemoved(Entity entity, ref EntRemovedFromContainerMessage args) + { + // Container networking jank + if (args.Container.ID != entity.Comp.Container || !SolutionQuery.TryComp(args.Entity, out var solution)) + return; + + RemComp(args.Entity); + entity.Comp.Solutions.Remove(solution.Id); + } + #endregion Event Handlers + /// + /// A method which ensures a solution with a given ID exists. + /// + /// Entity we're trying to attach a new solution to. + /// Name of the new solution. + /// Solution entity found or created. + /// Returns true if the solution already existed, and false if it had to create a new solution. + /// + /// Only run this after the entity is already initialized. + /// If you're running this when your entity is created, it is recommended to run on + /// Deviance from these instructions may prevent your game from building. YOU HAVE BEEN WARNED. + /// public bool EnsureSolution( - Entity entity, + Entity entity, string name, - [NotNullWhen(true)] out Solution? solution, - FixedPoint2 maxVol = default) + out Entity solutionEntity) { - return EnsureSolution(entity, name, maxVol, null, out _, out solution); - } - - public bool EnsureSolution( - Entity entity, - string name, - out bool existed, - [NotNullWhen(true)] out Solution? solution, - FixedPoint2 maxVol = default) - { - return EnsureSolution(entity, name, maxVol, null, out existed, out solution); - } - - public bool EnsureSolution( - Entity entity, - string name, - FixedPoint2 maxVol, - Solution? prototype, - out bool existed, - [NotNullWhen(true)] out Solution? solution) - { - solution = null; - existed = false; - - var (uid, meta) = entity; - if (!Resolve(uid, ref meta)) - throw new InvalidOperationException("Attempted to ensure solution on invalid entity."); - var manager = EnsureComp(uid); - if (meta.EntityLifeStage >= EntityLifeStage.MapInitialized) + if (SolutionQuery.TryComp(entity, out var comp) && comp.Id == name) { - EnsureSolutionEntity((uid, manager), name, out existed, - out var solEnt, maxVol, prototype); - solution = solEnt!.Value.Comp.Solution; + solutionEntity = (entity.Owner, comp); return true; } - solution = EnsureSolutionPrototype((uid, manager), name, maxVol, prototype, out existed); - return true; - } - public void EnsureAllSolutions(Entity entity) - { - if (NetManager.IsClient) - return; + // Ensure we have a SolutionManagerComponent + // EnsureComp should ensure a container and fill that container with default spawns! + if (entity.Comp == null) + EnsureComp(entity, out entity.Comp); - if (entity.Comp.Solutions is not { } prototypes) - return; - - foreach (var (name, prototype) in prototypes) + // Check the cache first, even if the component didn't exist before, creating one may have spawned and cached solutions! + if (entity.Comp.Solutions.TryGetValue(name, out var solution)) { - EnsureSolutionEntity((entity.Owner, entity.Comp), name, out _, out _, prototype.MaxVolume, prototype); + solutionEntity = solution; + return true; } - entity.Comp.Solutions = null; - Dirty(entity); + // Create a default entity if one doesn't already exist! + solutionEntity = CreateDefaultSolution((entity, entity.Comp), name); + return false; } - public bool EnsureSolutionEntity( - Entity entity, + /// This is private since you should really be specifying a solution prototype to create. + private Entity CreateDefaultSolution( + Entity entity, + string name) + { + var container = ContainerSystem.EnsureContainer(entity.Owner, entity.Comp.Container); + return CreateDefaultSolution(name, container); + } + + private Entity CreateDefaultSolution( string name, - [NotNullWhen(true)] out Entity? solutionEntity, - FixedPoint2 maxVol = default) => - EnsureSolutionEntity(entity, name, out _, out solutionEntity, maxVol); - - public bool EnsureSolutionEntity( - Entity entity, - string name, - out bool existed, - [NotNullWhen(true)] out Entity? solutionEntity, - FixedPoint2 maxVol = default, - Solution? prototype = null - ) + Container container) { - existed = true; - solutionEntity = null; - - var (uid, container) = entity; - - var solutionSlot = ContainerSystem.EnsureContainer(uid, $"solution@{name}", out existed); - if (!Resolve(uid, ref container, logMissing: false)) - { - existed = false; - container = AddComp(uid); - container.Containers.Add(name); - if (NetManager.IsClient) - return false; - } - else if (!existed) - { - container.Containers.Add(name); - Dirty(uid, container); - } - - var needsInit = false; - SolutionComponent solutionComp; - if (solutionSlot.ContainedEntity is not { } solutionId) - { - if (NetManager.IsClient) - return false; - prototype ??= new() { MaxVolume = maxVol }; - prototype.Name = name; - (solutionId, solutionComp, _) = SpawnSolutionUninitialized(solutionSlot, name, maxVol, prototype); - existed = false; - needsInit = true; - Dirty(uid, container); - } - else - { - solutionComp = Comp(solutionId); - DebugTools.Assert(TryComp(solutionId, out ContainedSolutionComponent? relation) && relation.Container == uid && relation.ContainerName == name); - DebugTools.Assert(solutionComp.Solution.Name == name); - - var solution = solutionComp.Solution; - solution.MaxVolume = FixedPoint2.Max(solution.MaxVolume, maxVol); - - // Depending on MapInitEvent order some systems can ensure solution empty solutions and conflict with the prototype solutions. - // We want the reagents from the prototype to exist even if something else already created the solution. - if (prototype is { Volume.Value: > 0 }) - solution.AddSolution(prototype, PrototypeManager); - - Dirty(solutionId, solutionComp); - } - - if (needsInit) - EntityManager.InitializeAndStartEntity(solutionId, Transform(solutionId).MapID); - solutionEntity = (solutionId, solutionComp); - return true; - } - - private Solution EnsureSolutionPrototype(Entity entity, string name, FixedPoint2 maxVol, Solution? prototype, out bool existed) - { - existed = true; - - var (uid, container) = entity; - if (!Resolve(uid, ref container, logMissing: false)) - { - container = AddComp(uid); - existed = false; - } - - if (container.Solutions is null) - container.Solutions = new(SolutionContainerManagerComponent.DefaultCapacity); - - if (!container.Solutions.TryGetValue(name, out var solution)) - { - solution = prototype ?? new() { Name = name, MaxVolume = maxVol }; - container.Solutions.Add(name, solution); - existed = false; - } - else - solution.MaxVolume = FixedPoint2.Max(solution.MaxVolume, maxVol); - - Dirty(uid, container); + var solution = SpawnSolutionUninitialized(DefaultSolution); + solution.Comp.Id = name; + ContainerSystem.Insert(solution.Owner, container, force: true); + EntityManager.InitializeAndStartEntity(solution); return solution; } - private Entity SpawnSolutionUninitialized(ContainerSlot container, string name, FixedPoint2 maxVol, Solution prototype) + public Entity CreateSolution( + EntProtoId proto, + Container container) { - var coords = new EntityCoordinates(container.Owner, Vector2.Zero); - var uid = EntityManager.CreateEntityUninitialized(null, coords, null); + // TODO: Replace this with an engine bound method when e#6192 is merged. + var solution = SpawnSolutionUninitialized(proto); + ContainerSystem.Insert(solution.Owner, container, force: true); + EntityManager.InitializeAndStartEntity(solution); + return solution; + } - var solution = new SolutionComponent() { Solution = prototype }; - AddComp(uid, solution); + private Entity SpawnSolutionUninitialized(EntProtoId solution) + { + var uid = EntityManager.CreateEntityUninitialized(solution); - var relation = new ContainedSolutionComponent() { Container = container.Owner, ContainerName = name }; - AddComp(uid, relation); - - MetaDataSys.SetEntityName(uid, $"solution - {name}", raiseEvents: false); - ContainerSystem.Insert(uid, container, force: true); - - return (uid, solution, relation); + // If you pass in a ProtoId without a SolutionComponent that's your own damn fault! + var comp = SolutionQuery.Comp(uid); + return (uid, comp); } public void AdjustDissolvedReagent( diff --git a/Content.Shared/Chemistry/EntitySystems/SolutionPurgeSystem.cs b/Content.Shared/Chemistry/EntitySystems/SolutionPurgeSystem.cs index bf39aaecc4..b31320e5ac 100644 --- a/Content.Shared/Chemistry/EntitySystems/SolutionPurgeSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/SolutionPurgeSystem.cs @@ -27,7 +27,8 @@ public sealed class SolutionPurgeSystem : EntitySystem { base.Update(frameTime); - var query = EntityQueryEnumerator(); + // TODO: SolutionPurgeComponent on Solution Entities! + var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var purge, out var manager)) { if (_timing.CurTime < purge.NextPurgeTime) diff --git a/Content.Shared/Chemistry/EntitySystems/SolutionRegenerationSystem.cs b/Content.Shared/Chemistry/EntitySystems/SolutionRegenerationSystem.cs index 369b837202..6aeaa7fd6f 100644 --- a/Content.Shared/Chemistry/EntitySystems/SolutionRegenerationSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/SolutionRegenerationSystem.cs @@ -38,7 +38,8 @@ public sealed class SolutionRegenerationSystem : EntitySystem { base.Update(frameTime); - var query = EntityQueryEnumerator(); + // TODO: SolutionRegenerationComponent on Solution Entities! + var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var regen, out var manager)) { if (_timing.CurTime < regen.NextRegenTime) diff --git a/Content.Shared/Chemistry/EntitySystems/SolutionSpikerSystem.cs b/Content.Shared/Chemistry/EntitySystems/SolutionSpikerSystem.cs index 468e28f65f..2e030594e6 100644 --- a/Content.Shared/Chemistry/EntitySystems/SolutionSpikerSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/SolutionSpikerSystem.cs @@ -26,7 +26,7 @@ public sealed class SolutionSpikerSystem : EntitySystem private void OnInteractUsing(Entity entity, ref InteractUsingEvent args) { - if (TrySpike(args.Used, args.Target, args.User, entity.Comp)) + if (TrySpike(args.Used, (args.Target, entity.Comp), args.User)) args.Handled = true; } @@ -37,31 +37,29 @@ public sealed class SolutionSpikerSystem : EntitySystem /// Source of the solution. /// Target to spike with the solution from source. /// User spiking the target solution. - private bool TrySpike(EntityUid source, EntityUid target, EntityUid user, RefillableSolutionComponent? spikableTarget = null, - SolutionSpikerComponent? spikableSource = null, - SolutionContainerManagerComponent? managerSource = null, - SolutionContainerManagerComponent? managerTarget = null) + private bool TrySpike(Entity source, + Entity target, + EntityUid user) { - if (!Resolve(source, ref spikableSource, ref managerSource, false) - || !Resolve(target, ref spikableTarget, ref managerTarget, false) - || !_solution.TryGetRefillableSolution((target, spikableTarget, managerTarget), out var targetSoln, out var targetSolution) - || !_solution.TryGetSolution((source, managerSource), spikableSource.SourceSolution, out _, out var sourceSolution)) + if (!Resolve(source, ref source.Comp, false) + || !_solution.TryGetRefillableSolution((target, target.Comp), out var targetSoln, out var targetSolution) + || !_solution.TryGetSolution(source.Owner, source.Comp.SourceSolution, out _, out var sourceSolution)) { return false; } - if (targetSolution.Volume == 0 && !spikableSource.IgnoreEmpty) + if (targetSolution.Volume == 0 && !source.Comp.IgnoreEmpty) { - _popup.PopupClient(Loc.GetString(spikableSource.PopupEmpty, ("spiked-entity", target), ("spike-entity", source)), user, user); + _popup.PopupClient(Loc.GetString(source.Comp.PopupEmpty, ("spiked-entity", target), ("spike-entity", source)), user, user); return false; } if (!_solution.ForceAddSolution(targetSoln.Value, sourceSolution)) return false; - _popup.PopupClient(Loc.GetString(spikableSource.Popup, ("spiked-entity", target), ("spike-entity", source)), user, user); + _popup.PopupClient(Loc.GetString(source.Comp.Popup, ("spiked-entity", target), ("spike-entity", source)), user, user); sourceSolution.RemoveAllSolution(); - if (spikableSource.Delete) + if (source.Comp.Delete) QueueDel(source); return true; diff --git a/Content.Shared/Chemistry/EntitySystems/SolutionTransferSystem.cs b/Content.Shared/Chemistry/EntitySystems/SolutionTransferSystem.cs index 3928ff7179..4ba58952b6 100644 --- a/Content.Shared/Chemistry/EntitySystems/SolutionTransferSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/SolutionTransferSystem.cs @@ -29,7 +29,8 @@ public sealed class SolutionTransferSystem : EntitySystem /// /// Default transfer amounts for the set-transfer verb. /// - public static readonly FixedPoint2[] DefaultTransferAmounts = new FixedPoint2[] { 1, 5, 10, 25, 50, 100, 250, 500, 1000 }; + /// TODO: Turn this into a prototype just like with injectors. + public static readonly FixedPoint2[] DefaultTransferAmounts = new FixedPoint2[] { 1, 5, 10, 15, 30, 60, 120, 240, 480, 960 }; public override void Initialize() { diff --git a/Content.Shared/EntityEffects/Effects/Solution/AddReagentToSolutionEntityEffectSystem.cs b/Content.Shared/EntityEffects/Effects/Solution/AddReagentToSolutionEntityEffectSystem.cs index ef96723cff..e6c9090339 100644 --- a/Content.Shared/EntityEffects/Effects/Solution/AddReagentToSolutionEntityEffectSystem.cs +++ b/Content.Shared/EntityEffects/Effects/Solution/AddReagentToSolutionEntityEffectSystem.cs @@ -11,11 +11,11 @@ namespace Content.Shared.EntityEffects.Effects.Solution; /// Quantity is modified by scale. /// /// -public sealed class AddReagentToSolutionEntityEffectSystem : EntityEffectSystem +public sealed class AddReagentToSolutionEntityEffectSystem : EntityEffectSystem { [Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!; - protected override void Effect(Entity entity, ref EntityEffectEvent args) + protected override void Effect(Entity entity, ref EntityEffectEvent args) { var solution = args.Effect.Solution; var reagent = args.Effect.Reagent; @@ -40,7 +40,7 @@ public sealed partial class AddReagentToSolution : EntityEffectBase [DataField(required: true)] - public string? Solution = "reagents"; + public string Solution = "reagents"; /// /// A modifier for how much reagent we're creating. diff --git a/Content.Shared/Fluids/EntitySystems/DrainSystem.cs b/Content.Shared/Fluids/EntitySystems/DrainSystem.cs index 8b5fefdd8b..4a11eed714 100644 --- a/Content.Shared/Fluids/EntitySystems/DrainSystem.cs +++ b/Content.Shared/Fluids/EntitySystems/DrainSystem.cs @@ -1,5 +1,4 @@ using Content.Shared.Audio; -using Content.Shared.Chemistry.Components.SolutionManager; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Database; using Content.Shared.DoAfter; @@ -23,6 +22,7 @@ namespace Content.Shared.Fluids.EntitySystems; /// /// Handles the draining of solutions from containers into drains. +/// TODO: This system is very bad, and needs to be rewritten. /// public sealed class DrainSystem : EntitySystem { @@ -130,9 +130,9 @@ public sealed class DrainSystem : EntitySystem { base.Update(frameTime); - var query = EntityQueryEnumerator(); + var query = EntityQueryEnumerator(); var curTime = _timing.CurTime; - while (query.MoveNext(out var uid, out var drain, out var manager)) + while (query.MoveNext(out var uid, out var drain)) { if (curTime < drain.NextUpdate) continue; @@ -141,7 +141,7 @@ public sealed class DrainSystem : EntitySystem Dirty(uid, drain); // Best to do this one every second rather than once every tick... - if (!_solutionContainerSystem.ResolveSolution((uid, manager), DrainComponent.SolutionName, ref drain.Solution, out var drainSolution)) + if (!_solutionContainerSystem.ResolveSolution(uid, DrainComponent.SolutionName, ref drain.Solution, out var drainSolution)) continue; if (drainSolution.Volume <= 0 && !drain.AutoDrain) @@ -201,12 +201,9 @@ public sealed class DrainSystem : EntitySystem private void OnExamined(Entity ent, ref ExaminedEvent args) { - if (!args.IsInDetailsRange || - !HasComp(ent) || - !_solutionContainerSystem.ResolveSolution(ent.Owner, DrainComponent.SolutionName, ref ent.Comp.Solution, out var drainSolution)) - { + if (!args.IsInDetailsRange + || !_solutionContainerSystem.ResolveSolution(ent.Owner, DrainComponent.SolutionName, ref ent.Comp.Solution, out var drainSolution)) return; - } var text = drainSolution.AvailableVolume != 0 ? Loc.GetString("drain-component-examine-volume", ("volume", drainSolution.AvailableVolume)) diff --git a/Content.Shared/Fluids/SharedAbsorbentSystem.cs b/Content.Shared/Fluids/SharedAbsorbentSystem.cs index 62c59b8227..36e7520641 100644 --- a/Content.Shared/Fluids/SharedAbsorbentSystem.cs +++ b/Content.Shared/Fluids/SharedAbsorbentSystem.cs @@ -38,7 +38,7 @@ public abstract class SharedAbsorbentSystem : EntitySystem SubscribeLocalEvent(OnAfterInteract); SubscribeLocalEvent(OnActivateInWorld); - SubscribeLocalEvent(OnAbsorbentSolutionChange); + SubscribeLocalEvent(OnAbsorbentSolutionChange); } private void OnActivateInWorld(Entity ent, ref UserActivateInWorldEvent args) @@ -59,7 +59,7 @@ public abstract class SharedAbsorbentSystem : EntitySystem args.Handled = true; } - private void OnAbsorbentSolutionChange(Entity ent, ref SolutionContainerChangedEvent args) + private void OnAbsorbentSolutionChange(Entity ent, ref SolutionChangedEvent args) { // The changes are already networked as part of the same game state. if (_timing.ApplyingState) diff --git a/Content.Shared/Fluids/SharedPuddleSystem.cs b/Content.Shared/Fluids/SharedPuddleSystem.cs index 18cae762f8..8c44009724 100644 --- a/Content.Shared/Fluids/SharedPuddleSystem.cs +++ b/Content.Shared/Fluids/SharedPuddleSystem.cs @@ -66,7 +66,7 @@ public abstract partial class SharedPuddleSystem : EntitySystem base.Initialize(); // Shouldn't need re-anchoring. SubscribeLocalEvent(OnAnchorChanged); - SubscribeLocalEvent(OnSolutionUpdate); + SubscribeLocalEvent(OnSolutionUpdate); SubscribeLocalEvent(OnGetFootstepSound); SubscribeLocalEvent(HandlePuddleExamined); SubscribeLocalEvent(OnEntRemoved); @@ -110,25 +110,25 @@ public abstract partial class SharedPuddleSystem : EntitySystem _standoutReagents = [.. _prototypeManager.EnumeratePrototypes().Where(x => x.Standsout).Select(x => x.ID)]; } - private void OnSolutionUpdate(Entity entity, ref SolutionContainerChangedEvent args) + private void OnSolutionUpdate(Entity entity, ref SolutionChangedEvent args) { // The changes are already networked as part of the same game state. if (_timing.ApplyingState) return; - if (args.SolutionId != entity.Comp.SolutionName) + if (args.Solution.Comp.Id != entity.Comp.SolutionName) return; - if (args.Solution.Volume <= 0) + if (args.Solution.Comp.Solution.Volume <= 0) { _deletionQueue.Add(entity); return; } _deletionQueue.Remove(entity); - UpdateSlip((entity, entity.Comp), args.Solution); - UpdateSlow(entity, args.Solution); - UpdateEvaporation(entity, args.Solution); + UpdateSlip((entity, entity.Comp), args.Solution.Comp.Solution); + UpdateSlow(entity, args.Solution.Comp.Solution); + UpdateEvaporation(entity, args.Solution.Comp.Solution); UpdateAppearance((entity, entity.Comp)); } diff --git a/Content.Shared/Kitchen/EntitySystems/SharedReagentGrinderSystem.cs b/Content.Shared/Kitchen/EntitySystems/SharedReagentGrinderSystem.cs index 811aabf3eb..9dca252eb4 100644 --- a/Content.Shared/Kitchen/EntitySystems/SharedReagentGrinderSystem.cs +++ b/Content.Shared/Kitchen/EntitySystems/SharedReagentGrinderSystem.cs @@ -41,7 +41,7 @@ public abstract class SharedReagentGrinderSystem : EntitySystem { base.Initialize(); - SubscribeLocalEvent(OnBeakerSolutionContainerChanged); + SubscribeLocalEvent(OnBeakerSolutionContainerChanged); SubscribeLocalEvent(OnGrinderStartup); SubscribeLocalEvent(OnEntRemovingAttempt); @@ -56,7 +56,7 @@ public abstract class SharedReagentGrinderSystem : EntitySystem SubscribeLocalEvent(OnEjectChamberContentMessage); } - private void OnBeakerSolutionContainerChanged(Entity ent, ref SolutionContainerChangedEvent args) + private void OnBeakerSolutionContainerChanged(Entity ent, ref SolutionChangedEvent args) { // Update the UI if the reagents inside the beaker are changed. // This is needed in case the component state for the container is applied before that of the solution container @@ -356,10 +356,11 @@ public abstract class SharedReagentGrinderSystem : EntitySystem switch (program) { case GrinderProgram.Grind: - if (_solutionContainersSystem.TryGetSolution(ent.Owner, ent.Comp.GrindableSolutionName, out _, out var solution)) - { + if (ent.Comp.GrindableSolutionName is not { } solutionId) + return null; + + if (_solutionContainersSystem.TryGetSolution(ent.Owner, solutionId, out _, out var solution)) return solution; - } break; case GrinderProgram.Juice: return ent.Comp.JuiceSolution; diff --git a/Content.Shared/Medical/Cryogenics/SharedCryoPodSystem.cs b/Content.Shared/Medical/Cryogenics/SharedCryoPodSystem.cs index f3b8024d6d..b3862bd422 100644 --- a/Content.Shared/Medical/Cryogenics/SharedCryoPodSystem.cs +++ b/Content.Shared/Medical/Cryogenics/SharedCryoPodSystem.cs @@ -5,7 +5,6 @@ using Content.Shared.Body.Components; using Content.Shared.Body.Systems; using Content.Shared.Chemistry; using Content.Shared.Chemistry.Components; -using Content.Shared.Chemistry.Components.SolutionManager; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Chemistry.Reagent; using Content.Shared.Climbing.Systems; @@ -57,8 +56,6 @@ public abstract partial class SharedCryoPodSystem : EntitySystem [Dependency] private readonly EntityQuery _bloodstreamQuery = default!; [Dependency] private readonly EntityQuery _itemSlotsQuery = default!; [Dependency] private readonly EntityQuery _dispenserQuery = default!; - [Dependency] private readonly EntityQuery _solutionContainerQuery = default!; - public override void Initialize() { @@ -111,9 +108,8 @@ public abstract partial class SharedCryoPodSystem : EntitySystem var patient = entity.Comp.BodyContainer.ContainedEntity; if (patient == null - || !_solutionContainerQuery.TryComp(entity, out var podSolutionManager) || !_solutionContainer.TryGetSolution( - (entity.Owner, podSolutionManager), + entity.Owner, CryoPodComponent.InjectionBufferSolutionName, out var injectingSolution, out _) @@ -352,14 +348,12 @@ public abstract partial class SharedCryoPodSystem : EntitySystem if (beaker == null || !beaker.Value.Valid || !_dispenserQuery.TryComp(beaker, out var fitsInDispenserComponent) - || !_solutionContainerQuery.TryComp(beaker, out var beakerSolutionManager) - || !_solutionContainerQuery.TryComp(cryoPod, out var podSolutionManager) || !_solutionContainer.TryGetFitsInDispenser( - (beaker.Value, fitsInDispenserComponent, beakerSolutionManager), + (beaker.Value, fitsInDispenserComponent), out var beakerSolution, out _) || !_solutionContainer.TryGetSolution( - (cryoPod.Owner, podSolutionManager), + cryoPod.Owner, CryoPodComponent.InjectionBufferSolutionName, out var injectionSolutionComp, out var injectionSolution)) @@ -377,9 +371,8 @@ public abstract partial class SharedCryoPodSystem : EntitySystem public void ClearInjectionBuffer(Entity cryoPod) { - if (_solutionContainerQuery.TryComp(cryoPod, out var podSolutionManager) - && _solutionContainer.TryGetSolution( - (cryoPod.Owner, podSolutionManager), + if (_solutionContainer.TryGetSolution( + cryoPod.Owner, CryoPodComponent.InjectionBufferSolutionName, out var injectingSolution, out _)) @@ -402,9 +395,8 @@ public abstract partial class SharedCryoPodSystem : EntitySystem if (beaker == null || !beaker.Value.Valid || !_dispenserQuery.TryComp(beaker, out var fitsInDispenserComponent) - || !_solutionContainerQuery.TryComp(beaker, out var solutionContainerManagerComponent) || !_solutionContainer.TryGetFitsInDispenser( - (beaker.Value, fitsInDispenserComponent, solutionContainerManagerComponent), + (beaker.Value, fitsInDispenserComponent), out var containerSolution, out _)) return (null, null); @@ -419,9 +411,8 @@ public abstract partial class SharedCryoPodSystem : EntitySystem protected List? GetInjectingReagents(Entity entity) { - if (!_solutionContainerQuery.TryComp(entity, out var solutionManager) - || !_solutionContainer.TryGetSolution( - (entity.Owner, solutionManager), + if (!_solutionContainer.TryGetSolution( + entity.Owner, CryoPodComponent.InjectionBufferSolutionName, out var injectingSolution, out _)) diff --git a/Content.Shared/Metabolism/MetabolizerSystem.cs b/Content.Shared/Metabolism/MetabolizerSystem.cs index af9ee038e2..dfc6e9cde9 100644 --- a/Content.Shared/Metabolism/MetabolizerSystem.cs +++ b/Content.Shared/Metabolism/MetabolizerSystem.cs @@ -32,7 +32,7 @@ public sealed class MetabolizerSystem : EntitySystem [Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!; [Dependency] private readonly EntityQuery _organQuery = default!; - [Dependency] private readonly EntityQuery _solutionQuery = default!; + [Dependency] private readonly EntityQuery _solutionQuery = default!; public override void Initialize() { @@ -87,7 +87,7 @@ public sealed class MetabolizerSystem : EntitySystem } private bool LookupSolution( - Entity ent, + Entity ent, MetabolismSolutionEntry solutionData, bool lookupTransfer, [NotNullWhen(true)] out Solution? solution, @@ -106,28 +106,24 @@ public sealed class MetabolizerSystem : EntitySystem if (lookupTransfer ? solutionData.TransferSolutionOnBody : solutionData.SolutionOnBody) { - if (ent.Comp2?.Body is { } body) - { - if (!_solutionQuery.TryComp(body, out var bodySolution)) - return false; - - solutionOwner = body; - return _solutionContainerSystem.TryGetSolution((body, bodySolution), solutionName, out solutionEntity, out solution); - } - } - else - { - if (!_solutionQuery.Resolve(ent, ref ent.Comp3, logMissing: false)) + if (ent.Comp2?.Body is not { } body) return false; - solutionOwner = ent; - return _solutionContainerSystem.TryGetSolution((ent, ent), solutionName, out solutionEntity, out solution); + if (!_solutionContainerSystem.TryGetSolution(body, solutionName, out solutionEntity, out solution)) + return false; + + solutionOwner = body; + return true; } - return false; + if (!_solutionContainerSystem.TryGetSolution((ent, ent.Comp3), solutionName, out solutionEntity, out solution)) + return false; + + solutionOwner = ent; + return true; } - private void TryMetabolizeStage(Entity ent, ProtoId stage) + private void TryMetabolizeStage(Entity ent, ProtoId stage) { if (!ent.Comp1.Solutions.TryGetValue(stage, out var solutionData)) return; @@ -261,9 +257,10 @@ public sealed class MetabolizerSystem : EntitySystem } } - private void TryMetabolize(Entity ent) + private void TryMetabolize(Entity ent) { _organQuery.Resolve(ent, ref ent.Comp2, logMissing: false); + _solutionQuery.Resolve(ent, ref ent.Comp3, logMissing: false); foreach (var stage in ent.Comp1.Stages) { diff --git a/Content.Shared/Nutrition/EntitySystems/IngestionSystem.API.cs b/Content.Shared/Nutrition/EntitySystems/IngestionSystem.API.cs index dbd75597ea..6c29e4fb0d 100644 --- a/Content.Shared/Nutrition/EntitySystems/IngestionSystem.API.cs +++ b/Content.Shared/Nutrition/EntitySystems/IngestionSystem.API.cs @@ -298,7 +298,7 @@ public sealed partial class IngestionSystem /// The entity trying to make the ingestion happening, not necessarily the one eating /// Solution we're returning /// The time it takes us to eat this entity - public bool CanAccessSolution(Entity ingested, + public bool CanAccessSolution(EntityUid ingested, EntityUid user, [NotNullWhen(true)] out Entity? solution, out TimeSpan? time) @@ -306,19 +306,20 @@ public sealed partial class IngestionSystem solution = null; time = null; - if (!Resolve(ingested, ref ingested.Comp)) - { - _popup.PopupClient(Loc.GetString("ingestion-try-use-is-empty", ("entity", ingested)), ingested, user); - return false; - } - + // TODO: Relay this event to solutions using solution relay var ev = new EdibleEvent(user); RaiseLocalEvent(ingested, ref ev); solution = ev.Solution; time = ev.Time; - return !ev.Cancelled && solution != null; + if (solution == null) + { + _popup.PopupClient(Loc.GetString("ingestion-try-use-is-empty", ("entity", ingested)), ingested, user); + return false; + } + + return !ev.Cancelled; } /// diff --git a/Content.Shared/Nutrition/EntitySystems/IngestionSystem.cs b/Content.Shared/Nutrition/EntitySystems/IngestionSystem.cs index 7733aa2cb7..e906bb93e6 100644 --- a/Content.Shared/Nutrition/EntitySystems/IngestionSystem.cs +++ b/Content.Shared/Nutrition/EntitySystems/IngestionSystem.cs @@ -23,6 +23,7 @@ using Content.Shared.UserInterface; using Content.Shared.Verbs; using Content.Shared.Whitelist; using Robust.Shared.Audio.Systems; +using Robust.Shared.Network; using Robust.Shared.Prototypes; namespace Content.Shared.Nutrition.EntitySystems; @@ -66,7 +67,7 @@ public sealed partial class IngestionSystem : EntitySystem { base.Initialize(); - SubscribeLocalEvent(OnEdibleInit); + SubscribeLocalEvent(OnEdibleInit); // Interactions SubscribeLocalEvent(OnUseEdibleInHand, after: [typeof(OpenableSystem), typeof(InventorySystem), typeof(ActivatableUISystem)]); @@ -83,7 +84,7 @@ public sealed partial class IngestionSystem : EntitySystem // Verbs SubscribeLocalEvent>(AddEdibleVerbs); - SubscribeLocalEvent(OnSolutionContainerChanged); + SubscribeLocalEvent(OnSolutionContainerChanged); // Misc SubscribeLocalEvent(OnAttemptShake); @@ -135,7 +136,7 @@ public sealed partial class IngestionSystem : EntitySystem return ingestionEv.Handled; } - private void OnEdibleInit(Entity entity, ref ComponentInit args) + private void OnEdibleInit(Entity entity, ref MapInitEvent args) { // 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, @@ -161,7 +162,7 @@ public sealed partial class IngestionSystem : EntitySystem _appearance.SetData(entity, FoodVisuals.Visual, drainAvailable.Float(), entity.Comp2); } - private void OnSolutionContainerChanged(Entity entity, ref SolutionContainerChangedEvent args) + private void OnSolutionContainerChanged(Entity entity, ref SolutionChangedEvent args) { // The changes are already networked as part of the same game state. if (_timing.ApplyingState) @@ -381,7 +382,7 @@ public sealed partial class IngestionSystem : EntitySystem var afterEv = new IngestedEvent(args.User, entity, split, forceFed, beforeEv.Transfer >= beforeEv.Max); RaiseLocalEvent(food, ref afterEv); - _stomach.TryTransferSolution(stomachToUse.Value.Owner, split, stomachToUse); + _stomach.TryTransferSolution((stomachToUse.Value, stomachToUse.Value.Comp), split); if (!afterEv.Destroy) { diff --git a/Content.Shared/Nutrition/EntitySystems/PressurizedSolutionSystem.cs b/Content.Shared/Nutrition/EntitySystems/PressurizedSolutionSystem.cs index 1ddb9965b7..4f594f0f44 100644 --- a/Content.Shared/Nutrition/EntitySystems/PressurizedSolutionSystem.cs +++ b/Content.Shared/Nutrition/EntitySystems/PressurizedSolutionSystem.cs @@ -30,11 +30,10 @@ public sealed partial class PressurizedSolutionSystem : EntitySystem { base.Initialize(); - SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnShake); SubscribeLocalEvent(OnOpened); SubscribeLocalEvent(OnLand); - SubscribeLocalEvent(OnSolutionUpdate); + SubscribeLocalEvent(OnSolutionUpdate); } /// @@ -242,10 +241,6 @@ public sealed partial class PressurizedSolutionSystem : EntitySystem #endregion #region Event Handlers - private void OnMapInit(Entity entity, ref MapInitEvent args) - { - RollSprayThreshold(entity); - } private void OnOpened(Entity entity, ref OpenableOpenedEvent args) { @@ -265,13 +260,13 @@ public sealed partial class PressurizedSolutionSystem : EntitySystem SprayOrAddFizziness(entity, entity.Comp.SprayChanceModOnLand, entity.Comp.FizzinessAddedOnLand); } - private void OnSolutionUpdate(Entity entity, ref SolutionContainerChangedEvent args) + private void OnSolutionUpdate(Entity entity, ref SolutionChangedEvent args) { // The changes are already networked as part of the same game state. if (_timing.ApplyingState) return; - if (args.SolutionId != entity.Comp.Solution) + if (args.Solution.Comp.Id != entity.Comp.Solution) return; // If the solution is no longer capable of being fizzy, clear any built up fizziness diff --git a/Content.Shared/Nutrition/FoodMetamorphRules/FoodMetamorphRule.cs b/Content.Shared/Nutrition/FoodMetamorphRules/FoodMetamorphRule.cs index b5c8ad08c5..928a9977ab 100644 --- a/Content.Shared/Nutrition/FoodMetamorphRules/FoodMetamorphRule.cs +++ b/Content.Shared/Nutrition/FoodMetamorphRules/FoodMetamorphRule.cs @@ -136,9 +136,6 @@ public sealed partial class FoodHasReagent : FoodMetamorphRule public override bool Check(IPrototypeManager protoMan, EntityManager entMan, EntityUid food, List ingredients) { - if (!entMan.TryGetComponent(food, out var solMan)) - return false; - var solutionMan = entMan.System(); if (!solutionMan.TryGetSolution(food, Solution, out var foodSoln, out var foodSolution)) diff --git a/Content.Shared/Tools/Components/WelderComponent.cs b/Content.Shared/Tools/Components/WelderComponent.cs index a9111c7f53..59a7bd51e1 100644 --- a/Content.Shared/Tools/Components/WelderComponent.cs +++ b/Content.Shared/Tools/Components/WelderComponent.cs @@ -41,7 +41,7 @@ public sealed partial class WelderComponent : Component /// Name of the fuel solution. /// [DataField] - public string FuelSolutionName = "Welder"; + public string FuelSolutionName = "welder"; /// /// Reagent that will be used as fuel for welding. diff --git a/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs b/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs index 1507b1d6e8..b0da547a27 100644 --- a/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs +++ b/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs @@ -57,9 +57,9 @@ public abstract partial class SharedToolSystem Dirty(entity, entity.Comp); } - public (FixedPoint2 fuel, FixedPoint2 capacity) GetWelderFuelAndCapacity(EntityUid uid, WelderComponent? welder = null, SolutionContainerManagerComponent? solutionContainer = null) + public (FixedPoint2 fuel, FixedPoint2 capacity) GetWelderFuelAndCapacity(EntityUid uid, WelderComponent? welder = null, SolutionManagerComponent? solutionContainer = null) { - if (!Resolve(uid, ref welder, ref solutionContainer)) + if (!Resolve(uid, ref welder)) return default; if (!SolutionContainerSystem.TryGetSolution( @@ -209,7 +209,8 @@ public abstract partial class SharedToolSystem private void UpdateWelders() { - var query = EntityQueryEnumerator(); + // TODO: Same as the other EntityQueryEnumerators... + var query = EntityQueryEnumerator(); var curTime = _timing.CurTime; while (query.MoveNext(out var uid, out var welder, out var solutionContainer)) { diff --git a/Resources/Locale/en-US/reagents/meta/fun.ftl b/Resources/Locale/en-US/reagents/meta/fun.ftl index eb4ff634d7..ce9a08170a 100644 --- a/Resources/Locale/en-US/reagents/meta/fun.ftl +++ b/Resources/Locale/en-US/reagents/meta/fun.ftl @@ -10,8 +10,8 @@ reagent-desc-buzzochloric-bees = Liquid bees. Oh god it's LIQUID BEES NO- reagent-name-ground-bee = ground Bee reagent-desc-ground-bee = Bee grounds. Gross. -reagent-name-saxoite = saxoite -reagent-desc-saxoite = Smells like jazz. +reagent-name-brass = brass +reagent-desc-brass = Smells like clockwork. reagent-name-licoxide = licoxide reagent-desc-licoxide = A synthetic battery acid. It looks... electrifying. diff --git a/Resources/Prototypes/Body/Animals/ruminant.yml b/Resources/Prototypes/Body/Animals/ruminant.yml index a6ca80975e..f880f129e3 100644 --- a/Resources/Prototypes/Body/Animals/ruminant.yml +++ b/Resources/Prototypes/Body/Animals/ruminant.yml @@ -9,10 +9,18 @@ - Ruminant - Wheat - BananaPeel - - type: SolutionContainerManager + - type: SolutionManager solutions: - stomach: - maxVol: 80 + - SolutionStomachRuminant + +- type: entity + parent: SolutionStomach + id: SolutionStomachRuminant + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 240 - type: entity id: BaseMobRuminant diff --git a/Resources/Prototypes/Body/Species/arachnid.yml b/Resources/Prototypes/Body/Species/arachnid.yml index e1b8e5dcdd..92c9a0c496 100644 --- a/Resources/Prototypes/Body/Species/arachnid.yml +++ b/Resources/Prototypes/Body/Species/arachnid.yml @@ -112,7 +112,7 @@ bloodReferenceSolution: reagents: - ReagentId: CopperBlood - Quantity: 300 + Quantity: 600 - type: MeleeWeapon animation: WeaponArcBite soundHit: diff --git a/Resources/Prototypes/Body/Species/diona.yml b/Resources/Prototypes/Body/Species/diona.yml index bab251032b..5673853e48 100644 --- a/Resources/Prototypes/Body/Species/diona.yml +++ b/Resources/Prototypes/Body/Species/diona.yml @@ -101,7 +101,7 @@ bloodReferenceSolution: reagents: - ReagentId: Sap - Quantity: 300 + Quantity: 600 - type: Reactive groups: Flammable: [ Touch ] diff --git a/Resources/Prototypes/Body/Species/gingerbread.yml b/Resources/Prototypes/Body/Species/gingerbread.yml index 5c429af01c..088d7d685a 100644 --- a/Resources/Prototypes/Body/Species/gingerbread.yml +++ b/Resources/Prototypes/Body/Species/gingerbread.yml @@ -60,9 +60,9 @@ bloodReferenceSolution: reagents: - ReagentId: Sugar - Quantity: 100 - - ReagentId: Butter Quantity: 200 + - ReagentId: Butter + Quantity: 400 - type: Fixtures fixtures: fix1: diff --git a/Resources/Prototypes/Body/Species/moth.yml b/Resources/Prototypes/Body/Species/moth.yml index 4b46381c3c..d40ccad10d 100644 --- a/Resources/Prototypes/Body/Species/moth.yml +++ b/Resources/Prototypes/Body/Species/moth.yml @@ -157,7 +157,7 @@ bloodReferenceSolution: reagents: - ReagentId: InsectBlood - Quantity: 300 + Quantity: 600 - type: DamageVisuals damageOverlayGroups: Brute: diff --git a/Resources/Prototypes/Body/Species/slime.yml b/Resources/Prototypes/Body/Species/slime.yml index f0ba746a6f..6f0a03b1e7 100644 --- a/Resources/Prototypes/Body/Species/slime.yml +++ b/Resources/Prototypes/Body/Species/slime.yml @@ -134,7 +134,7 @@ bloodReferenceSolution: # TODO Color slime blood based on their slime color or smth reagents: - ReagentId: Slime - Quantity: 300 + Quantity: 600 - type: Barotrauma damage: types: @@ -255,10 +255,9 @@ id: OrganSlimePersonCore name: sentient slime core components: - - type: SolutionContainerManager + - type: SolutionManager solutions: - stomach: - maxVol: 50.0 + - SolutionStomach - type: Stomach - type: Metabolizer maxReagents: 6 diff --git a/Resources/Prototypes/Body/Species/vox.yml b/Resources/Prototypes/Body/Species/vox.yml index dabfebcb55..b889d5acc3 100644 --- a/Resources/Prototypes/Body/Species/vox.yml +++ b/Resources/Prototypes/Body/Species/vox.yml @@ -247,7 +247,7 @@ bloodReferenceSolution: reagents: - ReagentId: AmmoniaBlood - Quantity: 300 + Quantity: 600 - type: MeleeWeapon soundHit: collection: AlienClaw diff --git a/Resources/Prototypes/Body/Species/vulpkanin.yml b/Resources/Prototypes/Body/Species/vulpkanin.yml index 616b371361..9daf7b2997 100644 --- a/Resources/Prototypes/Body/Species/vulpkanin.yml +++ b/Resources/Prototypes/Body/Species/vulpkanin.yml @@ -204,7 +204,7 @@ bloodReferenceSolution: reagents: - ReagentId: SulfurBlood - Quantity: 300 + Quantity: 600 - type: CreamPied sprite: sprite: Effects/creampie.rsi diff --git a/Resources/Prototypes/Body/base_organs.yml b/Resources/Prototypes/Body/base_organs.yml index 0cfaf8b4ac..924759a43e 100644 --- a/Resources/Prototypes/Body/base_organs.yml +++ b/Resources/Prototypes/Body/base_organs.yml @@ -334,11 +334,9 @@ - type: Lung - type: Metabolizer stages: [ Respiration ] - - type: SolutionContainerManager + - type: SolutionManager solutions: - Lung: - maxVol: 100.0 - canReact: false + - SolutionLungGas - type: Sprite layers: - state: lung-l @@ -346,6 +344,17 @@ - type: Item heldPrefix: lungs +- type: entity + parent: Solution + id: SolutionLungGas # TODO: Metabolize directly from gasses :( + categories: [ HideSpawnMenu ] + components: + - type: Solution + id: Lung + solution: + maxVol: 100.0 + canReact: false + - type: entity parent: OrganBase id: OrganBaseHeart @@ -372,10 +381,9 @@ - type: Organ category: Stomach - type: Stomach - - type: SolutionContainerManager + - type: SolutionManager solutions: - stomach: - maxVol: 50 + - SolutionStomach - type: Metabolizer maxReagents: 3 stages: [ Digestion ] @@ -385,6 +393,16 @@ - type: Item heldPrefix: stomach +- type: entity + parent: Solution + id: SolutionStomach + categories: [ HideSpawnMenu ] + components: + - type: Solution + id: stomach + solution: + maxVol: 150 # 1.25 liters which is average for a human + - type: entity parent: OrganBase id: OrganBaseLiver diff --git a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml index 4dfe9a6613..3dbe34a1a4 100644 --- a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml +++ b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml @@ -45,13 +45,9 @@ storagebase: !type:AllSelector children: - id: JugBicaridine - - id: JugPuncturase - - id: JugDermaline - - id: JugDylovene - - id: JugHyronalin - - id: JugSaline - - id: JugDexalinPlus - - id: JugTranexamicAcid + - id: JugPunctTranex + - id: JugPyraDerma + - id: JugDexPlusSaline - type: entity parent: ClothingBackpackDuffelSyndicateBundle diff --git a/Resources/Prototypes/Chemistry/injector_modes.yml b/Resources/Prototypes/Chemistry/injector_modes.yml index 1e2b38aa41..6b2e0b96f7 100644 --- a/Resources/Prototypes/Chemistry/injector_modes.yml +++ b/Resources/Prototypes/Chemistry/injector_modes.yml @@ -48,7 +48,8 @@ - 5 - 10 - 15 - - 50 + - 30 + - 60 - type: injectorMode parent: [ BaseSyringeMode, BaseInjectMode ] @@ -66,14 +67,6 @@ parent: [ BaseBluespaceSyringeMode, BaseDrawMode ] id: BluespaceSyringeDrawMode -- type: injectorMode - parent: [ BaseCryostasisSyringeMode, BaseInjectMode ] - id: CryostasisSyringeInjectMode - -- type: injectorMode - parent: [ BaseCryostasisSyringeMode, BaseDrawMode ] - id: CryostasisSyringeDrawMode - ## Dropper - type: injectorMode abstract: true diff --git a/Resources/Prototypes/Entities/Clothing/Back/specific.yml b/Resources/Prototypes/Entities/Clothing/Back/specific.yml index c440fe9a66..9188f7f064 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/specific.yml @@ -20,7 +20,7 @@ type: ChameleonBoundUserInterface - type: entity - parent: [Clothing, ClothingSlotBase] + parent: [SolutionTank, SolutionGinormous, Clothing, ClothingSlotBase] id: ClothingBackpackWaterTank name: backpack water tank description: Holds a large amount of fluids. Supplies to spray nozzles in your hands, and has a slot on the side for said spray nozzles. @@ -54,10 +54,6 @@ - type: SolutionAmmoProvider solutionId: tank proto: BulletWaterShot - - type: SolutionContainerManager - solutions: - tank: - maxVol: 1000 #much water - type: SolutionTransfer transferAmount: 50 maxTransferAmount: 100 diff --git a/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml b/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml index c5baa4f4ad..aea649be5e 100644 --- a/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml +++ b/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml @@ -107,8 +107,8 @@ - WhitelistChameleon - type: entity - parent: ClothingEyesHudBase - id: ClothingEyesHudFriedOnion + parent: [SolutionFood, SolutionSmall, ClothingEyesHudBase] + id: ClothingEyesHudFriedOnion # It's been too long since I've had good onion rings... name: fried onion goggles description: Filler components: @@ -118,13 +118,11 @@ sprite: Clothing/Eyes/Hud/friedonion.rsi - type: ShowHungerIcons - type: Edible - - type: SolutionContainerManager - solutions: - food: - maxVol: 3 - reagents: - - ReagentId: Nutriment - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 30 - type: FlavorProfile flavors: - onion diff --git a/Resources/Prototypes/Entities/Clothing/Hands/base_clothinghands.yml b/Resources/Prototypes/Entities/Clothing/Hands/base_clothinghands.yml index d90e02b16e..3c30cae415 100644 --- a/Resources/Prototypes/Entities/Clothing/Hands/base_clothinghands.yml +++ b/Resources/Prototypes/Entities/Clothing/Hands/base_clothinghands.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: Clothing + parent: [SolutionFood, SolutionToolSmall, Clothing] id: ClothingHandsBase components: - type: Sprite @@ -12,13 +12,11 @@ - type: Item size: Small storedRotation: -90 - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Fiber - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 15 - type: Tag tags: - ClothMade diff --git a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml index 3b85ce94c9..d3845f5fb0 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: Clothing + parent: [SolutionFood, SolutionToolSmall, Clothing] id: ClothingHeadBase components: - type: Clothing @@ -13,13 +13,11 @@ storedRotation: -90 - type: Edible requiresSpecialDigestion: true - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Fiber - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 15 - type: Tag tags: - ClothMade @@ -61,7 +59,7 @@ equippedPrefix: off - type: Item heldPrefix: off - size: Normal + size: Normal # I'm not updating the solution because these probably shouldn't be edible... - type: ToggleableVisuals spriteLayer: light - type: ItemTogglePointLight diff --git a/Resources/Prototypes/Entities/Clothing/Head/misc.yml b/Resources/Prototypes/Entities/Clothing/Head/misc.yml index 5584a7c076..b9167595b5 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/misc.yml @@ -302,7 +302,7 @@ - FacialHair - type: entity - parent: Clothing + parent: [SolutionDrink, Clothing] id: WaterDropletHat name: water droplet description: Makes 8-eyed friends 8 times more adorable! @@ -328,13 +328,12 @@ - water - type: DrainableSolution solution: drink - - type: SolutionContainerManager - solutions: - drink: - maxVol: 2 - reagents: - - ReagentId: Water - Quantity: 2 + - type: Solution + solution: + maxVol: 2 # Droplets are pretty small. + reagents: + - ReagentId: Water + Quantity: 2 - type: DamageOnHighSpeedImpact minimumSpeed: 0.1 damage: diff --git a/Resources/Prototypes/Entities/Clothing/Masks/base_clothingmask.yml b/Resources/Prototypes/Entities/Clothing/Masks/base_clothingmask.yml index 6ab6da4c0f..952e3da407 100644 --- a/Resources/Prototypes/Entities/Clothing/Masks/base_clothingmask.yml +++ b/Resources/Prototypes/Entities/Clothing/Masks/base_clothingmask.yml @@ -32,9 +32,9 @@ event: !type:ToggleMaskEvent - type: entity - id: ClothingMaskBaseButcherable - parent: ClothingMaskBase abstract: true + parent: [SolutionFood, SolutionToolSmall, ClothingMaskBase] + id: ClothingMaskBaseButcherable components: - type: Butcherable butcheringType: Knife @@ -46,13 +46,11 @@ Cloth: 50 - type: Edible requiresSpecialDigestion: true - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Fiber - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 15 - type: Tag tags: - ClothMade diff --git a/Resources/Prototypes/Entities/Clothing/Multiple/towel.yml b/Resources/Prototypes/Entities/Clothing/Multiple/towel.yml index dff5aa7901..c80fd341cc 100644 --- a/Resources/Prototypes/Entities/Clothing/Multiple/towel.yml +++ b/Resources/Prototypes/Entities/Clothing/Multiple/towel.yml @@ -1,9 +1,9 @@ - type: entity + abstract: true + parent: [UnsensoredClothingUniformBase, ClothingHeadBase, ClothingBeltBase] id: BaseTowel name: base towel - abstract: true description: If you want to survive out here, you gotta know where your towel is. - parent: [ UnsensoredClothingUniformBase, ClothingHeadBase, ClothingBeltBase ] components: - type: Sprite sprite: Clothing/Multiple/towel.rsi @@ -21,15 +21,9 @@ spillWhenThrown: false - type: Absorbent pickupAmount: 15 - - type: SolutionContainerManager + - type: SolutionManager solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Fiber - Quantity: 30 - absorbed: - maxVol: 30 + - SolutionMopSmall - type: UseDelay delay: 1 - type: Fiber diff --git a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml index 2e1b0dea73..c4e0bb6e02 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: Clothing + parent: [SolutionFood, SolutionToolSmall, Clothing] id: ClothingNeckBase components: - type: Item @@ -21,13 +21,11 @@ Cloth: 100 - type: Edible requiresSpecialDigestion: true - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Fiber - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 15 - type: Tag tags: - ClothMade diff --git a/Resources/Prototypes/Entities/Clothing/Neck/pins.yml b/Resources/Prototypes/Entities/Clothing/Neck/pins.yml index af23e97116..876fc2fde8 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/pins.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/pins.yml @@ -263,7 +263,7 @@ equippedPrefix: goldautism - type: entity - parent: BaseItem + parent: [SolutionSpray, SolutionTiny, BaseItem] id: SprayFlowerPin name: flower pin description: A cute flower pin. Something seems off with it... @@ -281,13 +281,11 @@ - neck - type: EquipSpray verbLocId: equip-spray-verb-press - - type: SolutionContainerManager - solutions: - spray: - maxVol: 30 - reagents: - - ReagentId: Water - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 30 - type: RefillableSolution solution: spray - type: DrainableSolution diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml index b6cf2e4e6a..762f92e355 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml @@ -48,6 +48,19 @@ - type: StaticPrice price: 70 +- type: entity + abstract: true + parent: [SolutionFood, SolutionNormal, ClothingOuterStorageBase] + id: ClothingOuterStorageEdible + components: + - type: Edible + requiresSpecialDigestion: true + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 60 + - type: entity abstract: true parent: [ClothingOuterStorageBase, BaseFoldable] diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml index bf92009013..235650d789 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml @@ -123,7 +123,7 @@ id: SyndieHandyFlag - type: entity - parent: ClothingOuterStorageBase + parent: ClothingOuterStorageEdible id: ClothingOuterCoatTrench name: trench coat description: A comfy trench coat. @@ -139,15 +139,6 @@ modifiers: coefficients: Slash: 0.95 - - type: Edible - requiresSpecialDigestion: true - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Fiber - Quantity: 20 - type: entity parent: ClothingOuterStorageFoldableBase diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml index 8c78b46277..f67d9eb82e 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml @@ -1,5 +1,5 @@ - type: entity - parent: ClothingOuterStorageBase + parent: ClothingOuterStorageEdible id: ClothingOuterWinterCoat name: winter coat description: A heavy jacket made from 'synthetic' animal furs. @@ -21,15 +21,6 @@ priceMultiplier: 0 - type: ZombificationResistance zombificationResistanceCoefficient: 0.55 - - type: Edible - requiresSpecialDigestion: true - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Fiber - Quantity: 30 - type: Tag tags: - ClothMade @@ -875,13 +866,11 @@ - cobwebs ignoreReagents: - Fiber - - type: SolutionContainerManager - solutions: # 15 (3 (fiber count of web) * 5 (to craft)) + 5 (magical crafting bonus) - food: - maxVol: 20 - reagents: - - ReagentId: Fiber - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 50 # 50 (10 (fiber count of web) * 5 (to craft)) - type: ToggleableClothing clothingPrototype: ClothingHeadHatHoodWinterWeb diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml b/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml index cd945af5e3..73a0d66464 100644 --- a/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml +++ b/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: Clothing + parent: [SolutionFood, SolutionToolNormal, Clothing] id: ClothingShoesBase components: - type: Clothing @@ -12,13 +12,11 @@ size: Normal - type: Edible requiresSpecialDigestion: true - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Fiber - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 30 - type: Tag tags: - ClothMade diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/boots.yml b/Resources/Prototypes/Entities/Clothing/Shoes/boots.yml index 0fd65eaccb..67596970ca 100644 --- a/Resources/Prototypes/Entities/Clothing/Shoes/boots.yml +++ b/Resources/Prototypes/Entities/Clothing/Shoes/boots.yml @@ -190,13 +190,11 @@ - cobwebs ignoreReagents: - Fiber - - type: SolutionContainerManager - solutions: # 6 (3 (fiber count of web) * 2 (to craft)) + 4 (magical crafting bonus) - food: - maxVol: 10 - reagents: - - ReagentId: Fiber - Quantity: 10 + - type: Solution + solution: # 20 (10 (fiber count of web) * 2 (to craft)) + reagents: + - ReagentId: Fiber + Quantity: 20 - type: Butcherable spawned: - id: MaterialWebSilk1 diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/misc.yml b/Resources/Prototypes/Entities/Clothing/Shoes/misc.yml index db8e3bb603..2f499bc2e6 100644 --- a/Resources/Prototypes/Entities/Clothing/Shoes/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/Shoes/misc.yml @@ -79,15 +79,13 @@ reagents: - ReagentId: JuiceThatMakesYouWeh Quantity: 60 - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Fiber - Quantity: 20 - - ReagentId: JuiceThatMakesYouWeh - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Fiber # Lose some fiber from gutting the lizard and turning it into a shoe. You monster. + Quantity: 20 + - ReagentId: JuiceThatMakesYouWeh + Quantity: 20 - type: entity parent: ClothingShoesBaseButcherable diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/base_clothinguniforms.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/base_clothinguniforms.yml index 0abbfebc2a..7039858584 100644 --- a/Resources/Prototypes/Entities/Clothing/Uniforms/base_clothinguniforms.yml +++ b/Resources/Prototypes/Entities/Clothing/Uniforms/base_clothinguniforms.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: Clothing + parent: [SolutionFood, SolutionToolNormal, Clothing] id: UnsensoredClothingUniformBase components: - type: Sprite @@ -19,13 +19,11 @@ Cloth: 150 - type: Edible requiresSpecialDigestion: true - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Fiber - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 30 - type: Tag tags: - ClothMade diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpskirts.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpskirts.yml index 64cd197c69..2a7a6b38c0 100644 --- a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpskirts.yml +++ b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpskirts.yml @@ -735,13 +735,6 @@ - cobwebs ignoreReagents: - Fiber - - type: SolutionContainerManager - solutions: # 24 (3 (fiber count of web) * 8 (to craft)) + 6 (magical crafting bonus) - food: - maxVol: 30 - reagents: - - ReagentId: Fiber - Quantity: 30 - type: Construction graph: WebObjects node: jumpskirt diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml index b94b8dcd66..9051a15c7b 100644 --- a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml @@ -1204,13 +1204,6 @@ - cobwebs ignoreReagents: - Fiber - - type: SolutionContainerManager - solutions: # 24 (3 (fiber count of web) * 8 (to craft)) + 6 (magical crafting bonus) - food: - maxVol: 30 - reagents: - - ReagentId: Fiber - Quantity: 30 - type: Construction graph: WebObjects node: jumpsuit diff --git a/Resources/Prototypes/Entities/Debugging/drugs.yml b/Resources/Prototypes/Entities/Debugging/drugs.yml deleted file mode 100644 index 0ba92443ad..0000000000 --- a/Resources/Prototypes/Entities/Debugging/drugs.yml +++ /dev/null @@ -1,16 +0,0 @@ -- type: entity - parent: [DrinkBaseMaterialGlass, DrinkBase] - id: DrinkMeth - name: meth # beer it is. coffee. beer? coff-ee? be-er? c-o... b-e - description: Just a whole glass of meth. - suffix: DEBUG - components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 20 - reagents: - - ReagentId: Desoxyephedrine - Quantity: 20 - - type: Sprite - sprite: Objects/Consumable/Drinks/beer.rsi diff --git a/Resources/Prototypes/Entities/Effects/chemistry_effects.yml b/Resources/Prototypes/Entities/Effects/chemistry_effects.yml index 05660888e8..ca837b7acc 100644 --- a/Resources/Prototypes/Entities/Effects/chemistry_effects.yml +++ b/Resources/Prototypes/Entities/Effects/chemistry_effects.yml @@ -25,11 +25,11 @@ - type: ActiveEdgeSpreader - type: EdgeSpreader id: Smoke - - type: SolutionContainerManager - solutions: - solutionArea: - maxVol: 600 - canReact: false + - type: Solution + id: solutionArea + solution: + maxVol: 600 # Required for it to spawn correctly, but should be removed in the future:tm: Arguably could move the solution to SmokeComponent as well considering it's nonreactive + canReact: false - type: entity parent: BaseFoam diff --git a/Resources/Prototypes/Entities/Effects/puddle.yml b/Resources/Prototypes/Entities/Effects/puddle.yml index dbde82b534..05b3106ad3 100644 --- a/Resources/Prototypes/Entities/Effects/puddle.yml +++ b/Resources/Prototypes/Entities/Effects/puddle.yml @@ -1,4 +1,5 @@ # TODO: Fix - The idea is that blood and vomit is potentially not tile-bound versions of puddles(?) +# TODO: Replace this whole thing with a SolutionFillComponent that uses a reagent table. - type: entity id: PuddleTemporary parent: Puddle @@ -18,117 +19,99 @@ parent: PuddleTemporary suffix: Vomit components: - - type: SolutionContainerManager - solutions: - puddle: - maxVol: 1000 - reagents: - - ReagentId: Vomit - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Vomit + Quantity: 10 - type: entity id: PuddleEgg parent: PuddleTemporary suffix: Egg components: - - type: SolutionContainerManager - solutions: - puddle: - maxVol: 1000 - reagents: - - ReagentId: Egg - Quantity: 6 # same as when cooking + - type: Solution + solution: + reagents: + - ReagentId: Egg + Quantity: 6 # same as when cooking - type: entity id: PuddleTomato parent: PuddleTemporary suffix: Tomato components: - - type: SolutionContainerManager - solutions: - puddle: - maxVol: 1000 - reagents: - - ReagentId: JuiceTomato - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: JuiceTomato + Quantity: 10 - type: entity parent: PuddleTemporary id: PuddleBloodSmall suffix: Blood (5u) components: - - type: SolutionContainerManager - solutions: - puddle: - maxVol: 1000 - reagents: - - ReagentId: Blood - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Blood + Quantity: 5 - type: entity parent: PuddleTemporary id: PuddleBlood suffix: Blood (30u) components: - - type: SolutionContainerManager - solutions: - puddle: - maxVol: 1000 - reagents: - - ReagentId: Blood - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Blood + Quantity: 30 - type: entity parent: PuddleTemporary id: PuddleFluorosulfuricAcidSmall suffix: FluorosulfuricAcid (5u) components: - - type: SolutionContainerManager - solutions: - puddle: - maxVol: 1000 - reagents: - - ReagentId: FluorosulfuricAcid - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: FluorosulfuricAcid + Quantity: 5 - type: entity parent: PuddleTemporary id: PuddleFluorosulfuricAcid suffix: FluorosulfuricAcid (15u) components: - - type: SolutionContainerManager - solutions: - puddle: - maxVol: 1000 - reagents: - - ReagentId: FluorosulfuricAcid - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: FluorosulfuricAcid + Quantity: 15 - type: entity id: PuddleWatermelon parent: PuddleTemporary suffix: Watermelon components: - - type: SolutionContainerManager - solutions: - puddle: - maxVol: 1000 - reagents: - - ReagentId: JuiceWatermelon - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: JuiceWatermelon + Quantity: 30 - type: entity id: PuddleFlour parent: PuddleTemporary suffix: Flour components: - - type: SolutionContainerManager - solutions: - puddle: - maxVol: 1000 - reagents: - - ReagentId: Flour - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Flour + Quantity: 15 - type: entity id: PuddleSparkle @@ -151,8 +134,9 @@ color: "#FFFFFF80" - type: entity - name: puddle + parent: SolutionTile id: Puddle + name: puddle description: A puddle of liquid. placement: mode: SnapgridCenter @@ -189,11 +173,9 @@ - walls base: splat mode: CardinalFlags - - type: SolutionContainerManager - solutions: - puddle: - maxVol: 1000 - type: Puddle + - type: Solution + id: puddle - type: MixableSolution solution: puddle - type: Appearance diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 1ec65e2dc6..a4cc78054b 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -84,7 +84,7 @@ - type: entity name: bee - parent: [ SimpleMobBase, FlyingMobBase ] + parent: [ SolutionFood, SolutionTiny, SimpleMobBase, FlyingMobBase ] id: MobBee description: Nice to have, but you can't build a civilization on a foundation of honey alone. components: @@ -127,12 +127,11 @@ Base: dead - type: Extractable grindableSolutionName: food - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: GroundBee - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: GroundBee + Quantity: 1 - type: Butcherable spawned: - id: null # Should give nothing when you butcher it so we set the item id it needs to spawn to null @@ -353,7 +352,7 @@ - type: entity name: cockroach - parent: SimpleMobBase + parent: [SolutionFood, SolutionTiny, SimpleMobBase] id: MobCockroach description: This station is just crawling with bugs. components: @@ -412,12 +411,11 @@ baseDecayRate: 0.25 - type: Extractable grindableSolutionName: food - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Slime - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Slime + Quantity: 5 - type: Butcherable spawned: - id: FoodMeatSlime @@ -789,7 +787,7 @@ - type: entity name: butterfly - parent: [ SimpleMobBase, FlyingMobBase ] + parent: [ SolutionFood, SolutionTiny, SimpleMobBase, FlyingMobBase ] id: MobButterfly description: Despite popular misconceptions, it's not actually made of butter. components: @@ -832,12 +830,11 @@ Base: dead - type: Extractable grindableSolutionName: food - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 1 - type: Butcherable spawned: - id: null # Should give nothing when you butcher it so we set the item id it needs to spawn to null @@ -907,13 +904,9 @@ Base: dead Dead: Base: dead - - type: SolutionContainerManager + - type: SolutionManager solutions: - udder: - maxVol: 250 - reagents: - - ReagentId: Milk - Quantity: 30 + - SolutionUdder - type: Udder reagentId: Milk quantityPerUpdate: 25 @@ -947,6 +940,19 @@ - Chef - FoodRecipes +- type: entity + parent: Solution + id: SolutionUdder + categories: [ HideSpawnMenu ] + components: + - type: Solution + id: food # TODO This should really use a different id... + solution: + maxVol: 240 + reagents: + - ReagentId: Milk + Quantity: 30 + - type: entity name: crab parent: [ SimpleMobBase, BaseMobHemocyanin ] @@ -1060,15 +1066,10 @@ Base: dead Dead: Base: dead - - type: SolutionContainerManager + - type: SolutionManager solutions: - udder: - maxVol: 250 - reagents: - - ReagentId: MilkGoat - Quantity: 30 - wool: - maxVol: 250 + - SolutionUdderGoat + - SolutionWool - type: Udder reagentId: MilkGoat quantityPerUpdate: 25 @@ -1116,6 +1117,29 @@ rootTask: task: RuminantHostileCompound +- type: entity + parent: SolutionUdder + id: SolutionUdderGoat + categories: [ HideSpawnMenu ] + components: + - type: Solution + id: food + solution: + maxVol: 240 + reagents: + - ReagentId: MilkGoat + Quantity: 30 + +- type: entity + parent: Solution + id: SolutionWool + categories: [ HideSpawnMenu ] + components: + - type: Solution + id: wool + solution: + maxVol: 240 + # Note that we gotta make this bitch vomit someday when you feed it anthrax or sumthin. Needs to be a small item thief too and aggressive if attacked. - type: entity name: goose @@ -1716,9 +1740,7 @@ - type: entity name: mouse - parent: - - SimpleMobBase - - BaseMobAnimal + parent: [SimpleMobBase, BaseMobAnimal, SolutionVermin] id: MobMouse description: Squeak! components: @@ -1750,7 +1772,6 @@ movement: state: mouse-0 - type: Item - size: Tiny heldPrefix: 0 - type: Clothing quickEquip: false @@ -1826,12 +1847,6 @@ baseDecayRate: 0.5 # I'm very hungry! Give me. The cheese. - type: Extractable grindableSolutionName: food - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 3 - type: Butcherable spawned: - id: FoodMeatRat @@ -1900,6 +1915,17 @@ - !type:GibBehavior recursive: false +- type: entity + abstract: true + parent: [SolutionFood, SolutionTiny] + id: SolutionVermin + components: + - type: Solution + solution: + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 15 + - type: entity parent: MobMouse suffix: Dead @@ -1916,22 +1942,6 @@ Slash: 7 Blunt: 3 -- type: entity - parent: MobMouse - id: MobMouseAdmeme - suffix: Admeme - components: - # allow admeme mouse to eat pills - - type: IgnoreBadFood - # intended for swarms that eat pills so only temporary - - type: TimedDespawn - lifetime: 60 - - type: Hunger - baseDecayRate: 10 # always hungry - starvingSlowdownModifier: 1 - - type: Thirst - baseDecayRate: 10 # always thirsty - - type: entity parent: MobMouse id: MobMouse1 @@ -2017,14 +2027,13 @@ reagents: - ReagentId: UnstableMutagen Quantity: 50 - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 3 - - ReagentId: Uranium - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 5 + - ReagentId: Uranium + Quantity: 10 - type: Butcherable spawned: - id: FoodMeatRat @@ -2091,7 +2100,6 @@ tags: - VimPilot - - type: entity name: slug parent: SimpleMobBase @@ -2517,10 +2525,9 @@ thresholds: 0: Alive 90: Dead - - type: SolutionContainerManager + - type: SolutionManager solutions: - melee: - maxVol: 30 + - SolutionVenomSpider - type: SolutionRegeneration solution: melee generated: @@ -2583,6 +2590,11 @@ Cold: -0.03 Shock: -0.03 +- type: entity + parent: [SolutionWeapon, SolutionTiny] + id: SolutionVenomSpider + categories: [ HideSpawnMenu ] + - type: entity parent: MobSpiderBase id: MobSpiderAngryBase @@ -3512,16 +3524,16 @@ baseDecayRate: 0.3 - type: Extractable grindableSolutionName: food - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Blood - Quantity: 55 - - ReagentId: Fat - Quantity: 5 + - type: Solution + id: food + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Blood # TODO Instead of this, eat from the bloodstream directly + Quantity: 55 + - ReagentId: Fat + Quantity: 5 - type: Butcherable spawned: - id: FoodMeat diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml b/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml index 921f88de36..3b5cb7b982 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml @@ -1,6 +1,6 @@ - type: entity save: false - parent: [ BaseSimpleMob, BaseMobAnimal, MobCombat ] + parent: [ BaseSimpleMob, BaseMobAnimal, MobCombat, MobBloodstream ] id: BaseMobArgocyte suffix: AI description: A dangerous alien found on the wrong side of planets, known for their propensity for munching on ruins. @@ -14,7 +14,6 @@ task: SimpleHostileCompound #todo custom argocyte AI - type: Sprite sprite: Mobs/Aliens/Argocyte/argocyte_common.rsi - - type: SolutionContainerManager - type: ReplacementAccent accent: xeno - type: Bloodstream diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml b/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml index 61eb23c929..950fd3c510 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml @@ -306,13 +306,11 @@ name: hivelord remains description: All that remains of a hivelord, it seems to be what allows it to break pieces of itself off without being hurt... its healing properties will soon become inert if not used quickly. Try not to think about what you're eating. components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Rororium - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Rororium + Quantity: 5 - type: Sprite sprite: Objects/Consumable/Food/rorocore.rsi state: boiled diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/moproach.yml b/Resources/Prototypes/Entities/Mobs/NPCs/moproach.yml index c38b2cedf7..60f8c0f138 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/moproach.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/moproach.yml @@ -40,16 +40,9 @@ preserve: - Water quantity: 10 - - type: SolutionContainerManager + - type: SolutionManager solutions: - absorbed: - maxVol: 50 - food: - reagents: - - ReagentId: Slime - Quantity: 5 - - type: DrainableSolution - solution: drainBuffer + - SolutionMopNormal - type: InteractionPopup interactSuccessString: petting-success-cleanbot interactFailureString: petting-failure-cleanbot diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml index b489ff3767..a615e5ebab 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml @@ -112,7 +112,7 @@ speechSounds: Pai #couldn't decide if this should be borg or pai sounds so I flipped a coin. - type: entity - parent: MobSiliconBase + parent: [MobSiliconBase, SolutionFireExtinguisherMini] id: MobFireBot name: firebot description: A little fire extinguishing bot. He looks rather anxious. @@ -126,13 +126,6 @@ - type: HTN rootTask: task: FirebotCompound - - type: SolutionContainerManager - solutions: - spray: - maxVol: 10 - reagents: - - ReagentId: Water - Quantity: 10 - type: SolutionRegeneration solution: spray generated: @@ -264,7 +257,7 @@ canCreateVacuum: false - type: entity - parent: MobSiliconBase + parent: [MobSiliconBase, SolutionMopNormal] id: MobCleanBot name: cleanbot description: The creep of automation now threatening space janitors. @@ -290,18 +283,12 @@ preserve: - Water quantity: 10 - - type: SolutionContainerManager - solutions: - absorbed: - maxVol: 50 - type: MovementSpeedModifier baseWalkSpeed: 2 baseSprintSpeed: 3 - type: HTN rootTask: task: CleanbotCompound - - type: DrainableSolution - solution: drainBuffer - type: InteractionPopup interactSuccessString: petting-success-cleanbot interactFailureString: petting-failure-cleanbot diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml index 1cffe9cb71..3a21fde727 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml @@ -243,12 +243,9 @@ types: Piercing: 6 Poison: 4 - - type: SolutionContainerManager + - type: SolutionManager solutions: - melee: - reagents: - - ReagentId: ChloralHydrate - Quantity: 80 + - SolutionVenomSpiderSpace - type: MeleeChemicalInjector solution: melee transferAmount: 4 @@ -276,6 +273,17 @@ - type: TypingIndicator proto: spider +- type: entity + parent: [SolutionWeapon, SolutionTiny] + id: SolutionVenomSpiderSpace + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + reagents: + - ReagentId: ChloralHydrate + Quantity: 30 + - type: entity id: MobSpiderSpaceSalvage parent: MobSpiderSpace @@ -349,12 +357,9 @@ types: Piercing: 6 Poison: 4 - - type: SolutionContainerManager + - type: SolutionManager solutions: - melee: - reagents: - - ReagentId: NorepinephricAcid - Quantity: 90 + - SolutionVenomCobraSpace - type: MeleeChemicalInjector solution: melee transferAmount: 6 @@ -375,6 +380,17 @@ passiveVisibilityRate: -0.25 movementVisibilityRate: 0.25 +- type: entity + parent: [SolutionWeapon, SolutionTiny] + id: SolutionVenomCobraSpace + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + reagents: + - ReagentId: NorepinephricAcid + Quantity: 30 + - type: entity id: MobCobraSpaceSalvage parent: MobCobraSpace @@ -383,9 +399,7 @@ - type: SalvageMobRestrictions - type: entity - parent: - - SimpleSpaceMobBase - - BaseMobAnimal + parent: [SimpleSpaceMobBase, BaseMobAnimal, SolutionVermin] id: MobSnail name: snail description: Revolting unless you're french. @@ -462,6 +476,15 @@ Dead: Base: dead - type: Edible + - type: Solution + solution: + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 8 + - ReagentId: Fat + Quantity: 3 + - ReagentId: Water + Quantity: 4 #It makes saline if you add salt! - type: Thirst startingThirst: 25 # spawn with Okay thirst state thresholds: @@ -481,16 +504,6 @@ baseDecayRate: 0.1 - type: Extractable grindableSolutionName: food - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 3 - - type: Butcherable - spawned: - - id: FoodMeatSnail - amount: 1 - type: Tag tags: - Trash diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml b/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml index 0a35ebf5e5..df26033c6b 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml @@ -79,12 +79,9 @@ damage: types: Piercing: 2 - - type: SolutionContainerManager + - type: SolutionManager solutions: - melee: - reagents: - - ReagentId: Toxin - Quantity: 5 + - SolutionVenomTick - type: MeleeChemicalInjector solution: melee - type: ReplacementAccent @@ -93,6 +90,18 @@ speechVerb: SmallMob - type: NonSpreaderZombie +- type: entity + parent: Solution + id: SolutionVenomTick + categories: [ HideSpawnMenu ] + components: + - type: Solution + id: melee + solution: + reagents: + - ReagentId: Toxin + Quantity: 5 + - type: entity id: MobTickSalvage parent: MobTick diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index 29793609e1..bf5faa5fef 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -70,7 +70,7 @@ bloodReferenceSolution: reagents: - ReagentId: FluorosulfuricAcid - Quantity: 650 + Quantity: 1300 - type: MeleeWeapon altDisarm: false angle: 0 @@ -403,12 +403,9 @@ damage: types: Piercing: 5 - - type: SolutionContainerManager + - type: SolutionManager solutions: - melee: - reagents: - - ReagentId: Toxin - Quantity: 50 + - SolutionVenomPurpleSnake - type: MeleeChemicalInjector solution: melee - type: Fixtures @@ -430,6 +427,17 @@ - DoorBumpOpener - FootstepSound +- type: entity + parent: [SolutionWeapon, SolutionTiny] + id: SolutionVenomPurpleSnake + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + reagents: + - ReagentId: Toxin + Quantity: 30 + - type: entity name: space adder parent: MobPurpleSnake @@ -498,7 +506,7 @@ bloodReferenceSolution: reagents: - ReagentId: FluorosulfuricAcid - Quantity: 300 + Quantity: 600 - type: MeleeWeapon altDisarm: false angle: 0 @@ -565,15 +573,23 @@ - type: Tag tags: - CannotSuicide - - type: SolutionContainerManager # Being hit speeds you up so you can escape + - type: SolutionManager # Being hit speeds you up so you can escape solutions: - bite: - reagents: - - ReagentId: Stimulants - Quantity: 50 - - ReagentId: TranexamicAcid - Quantity: 50 + - SolutionVenomDale - type: MeleeChemicalInjector transferAmount: 1 - solution: bite + solution: melee pierceArmor: true + +- type: entity + parent: [SolutionWeapon, SolutionNormal] + id: SolutionVenomDale + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + reagents: + - ReagentId: Stimulants + Quantity: 50 + - ReagentId: TranexamicAcid + Quantity: 50 diff --git a/Resources/Prototypes/Entities/Mobs/base.yml b/Resources/Prototypes/Entities/Mobs/base.yml index 8c74d49989..45e3b9a3fe 100644 --- a/Resources/Prototypes/Entities/Mobs/base.yml +++ b/Resources/Prototypes/Entities/Mobs/base.yml @@ -262,7 +262,7 @@ id: MobBloodstream abstract: true components: - - type: SolutionContainerManager + - type: SolutionManager - type: InjectableSolution solution: bloodstream - type: Bloodstream diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml index f1f4ad06d0..d655517df9 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml @@ -1,8 +1,7 @@ - type: entity abstract: true - parent: [ DrinkBaseMaterialCardboard, DrinkBase, DrinkBaseOpenable, DrinkVisualsOpenable ] - id: DrinkCartonBaseFull - suffix: Full + parent: [ DrinkBaseMaterialCardboard, SolutionNormal, DrinkBase, DrinkBaseOpenable, DrinkVisualsOpenable, DrinkBaseEmptyTrash ] + id: DrinkCartonBase components: - type: Openable sound: @@ -10,36 +9,53 @@ closeable: true closeSound: collection: bottleCloseSounds - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - - type: TrashOnSolutionEmpty - solution: drink - - type: Item - size: Normal - type: entity abstract: true - parent: DrinkCartonBaseFull - id: DrinkCartonSmallBaseFull + parent: DrinkCartonBase + id: DrinkCartonBaseFull + suffix: Full + components: + - type: Tag + tags: [] + +- type: entity + abstract: true + parent: [SolutionSmall, DrinkCartonBase ] + id: DrinkCartonSmallBase components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 50 - type: Item size: Small - type: entity abstract: true - parent: DrinkCartonBaseFull - id: DrinkCartonBaseXtraLargeFull + parent: DrinkCartonSmallBase + id: DrinkCartonSmallBaseFull + suffix: Full + components: + - type: Tag + tags: [ ] + +- type: entity + abstract: true + parent: [SolutionLarge, DrinkCartonBase ] + id: DrinkCartonBaseLarge + components: + - type: Item + size: Large + shape: + - 0,0,1,3 + - type: Tag + tags: + - DrinkBottle # Need this to fit in the soda dispenser, probably needs a better name + - Trash + +- type: entity + abstract: true + parent: DrinkCartonBaseLarge + id: DrinkCartonBaseLargeFull + suffix: Full components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 150 - type: Tag tags: - DrinkBottle # Need this to fit in the soda dispenser, probably needs a better name @@ -47,92 +63,118 @@ # Small carton - type: entity - parent: [DrinkBaseMaterialPlastic, DrinkCartonSmallBaseFull] - id: DrinkJuiceLimeCarton + parent: [DrinkBaseMaterialPlastic, DrinkCartonSmallBase] + id: DrinkCartonLime name: lime juice description: Sweet-sour goodness. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: JuiceLime - Quantity: 50 - type: Sprite sprite: Objects/Consumable/Drinks/limejuice.rsi - type: entity - parent: DrinkCartonSmallBaseFull - id: DrinkJuiceOrangeCarton + parent: DrinkCartonLime + id: DrinkJuiceLimeCarton + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: JuiceLime + Quantity: 60 + - type: Tag + tags: [ ] + +- type: entity + parent: DrinkCartonSmallBase + id: DrinkCartonOrange name: orange juice description: Full of vitamins and deliciousness! components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: JuiceOrange - Quantity: 50 - type: Sprite sprite: Objects/Consumable/Drinks/orangejuice.rsi - type: entity - parent: DrinkCartonSmallBaseFull - id: DrinkJuiceTomatoCarton + parent: DrinkCartonOrange + id: DrinkJuiceOrangeCarton + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: JuiceOrange + Quantity: 60 + - type: Tag + tags: [ ] + +- type: entity + parent: DrinkCartonSmallBase + id: DrinkCartonTomato name: tomato juice description: Well, at least it LOOKS like tomato juice. You can't tell with all that redness. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: JuiceTomato - Quantity: 50 - type: Sprite sprite: Objects/Consumable/Drinks/tomatojuice.rsi +- type: entity + parent: DrinkCartonTomato + id: DrinkJuiceTomatoCarton + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: JuiceTomato + Quantity: 60 + - type: Tag + tags: [] + - type: entity parent: DrinkCartonSmallBaseFull id: DrinkCoconutWaterCarton name: coconut water description: It's the inside of the coconut that counts. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: CoconutWater - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: CoconutWater + Quantity: 60 - type: Sprite sprite: Objects/Consumable/Drinks/coconutwater.rsi - type: entity - parent: DrinkCartonSmallBaseFull - id: DrinkCreamCarton + parent: DrinkCartonSmallBase + id: DrinkCartonCream name: milk cream description: It's cream. Made from milk. What else did you think you'd find in there? components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Cream - Quantity: 50 - type: Sprite sprite: Objects/Consumable/Drinks/cream.rsi +- type: entity + parent: DrinkCartonCream + id: DrinkCreamCarton + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Cream + Quantity: 60 + - type: Tag + tags: [ ] + - type: entity parent: [DrinkBaseMaterialPlastic, DrinkCartonSmallBaseFull] id: DrinkJuiceLemonCarton name: lemon juice description: First it's sour, then it's still sour. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: JuiceLemon - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: JuiceLemon + Quantity: 60 - type: Sprite sprite: Objects/Consumable/Drinks/lemonjuice.rsi @@ -142,113 +184,128 @@ name: pineapple juice description: Tastes like a tropical vacation far from space. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: JuicePineapple - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: JuicePineapple + Quantity: 60 - type: Sprite sprite: Objects/Consumable/Drinks/pineapplejuice.rsi -# Large carton +# Normal sized cartons - type: entity - parent: [DrinkBaseMaterialPlastic, DrinkCartonBaseFull] # Looks like a plastic jug, fight me - id: DrinkMilkCarton + parent: [DrinkBaseMaterialPlastic, DrinkCartonBase] # Looks like a plastic jug, fight me + id: DrinkCartonMilk name: milk description: An opaque white liquid produced by the mammary glands of mammals. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Milk - Quantity: 100 - type: Sprite sprite: Objects/Consumable/Drinks/milk.rsi - type: entity - parent: DrinkCartonBaseFull - id: DrinkSoyMilkCarton + parent: DrinkCartonMilk + id: DrinkMilkCarton + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Milk + Quantity: 120 + - type: Tag + tags: [ ] + +- type: entity + parent: DrinkCartonBase + id: DrinkCartonSoyMilk name: soy milk description: White and nutritious soy goodness! components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: MilkSoy - Quantity: 100 - type: Sprite sprite: Objects/Consumable/Drinks/soymilk.rsi - type: entity - parent: [DrinkBaseMaterialPlastic, DrinkCartonBaseFull] - id: DrinkOatMilkCarton + parent: DrinkCartonSoyMilk + id: DrinkSoyMilkCarton + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: MilkSoy + Quantity: 120 + - type: Tag + tags: [ ] + +- type: entity + parent: [DrinkBaseMaterialPlastic, DrinkCartonBase] + id: DrinkCartonOatMilk name: oat milk description: It's oat milk. Tan and nutritious goodness! components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: MilkOat - Quantity: 100 - type: Sprite sprite: Objects/Consumable/Drinks/oatmilk.rsi -# Xtra large +- type: entity + parent: DrinkCartonOatMilk + id: DrinkOatMilkCarton + name: oat milk + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: MilkOat + Quantity: 120 + - type: Tag + tags: [ ] + +# Large cartons - type: entity - parent: [DrinkBaseMaterialPlastic, DrinkCartonBaseXtraLargeFull] + parent: [DrinkBaseMaterialPlastic, DrinkCartonBaseLargeFull] id: DrinkJuiceLimeCartonXL name: lime juice XL description: Sweet-sour goodness. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 150 - reagents: - - ReagentId: JuiceLime - Quantity: 150 + - type: Solution + solution: + reagents: + - ReagentId: JuiceLime + Quantity: 240 - type: Label currentLabel: reagent-name-juice-lime - type: Sprite sprite: Objects/Consumable/Drinks/limejuice.rsi - type: entity - parent: DrinkCartonBaseXtraLargeFull + parent: DrinkCartonBaseLargeFull id: DrinkJuiceOrangeCartonXL name: orange juice XL description: Full of vitamins and deliciousness! components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 150 - reagents: - - ReagentId: JuiceOrange - Quantity: 150 + - type: Solution + solution: + reagents: + - ReagentId: JuiceOrange + Quantity: 240 - type: Label currentLabel: reagent-name-juice-orange - type: Sprite sprite: Objects/Consumable/Drinks/orangejuice.rsi - type: entity - parent: DrinkCartonBaseXtraLargeFull + parent: DrinkCartonBaseLargeFull id: DrinkCreamCartonXL name: milk cream XL description: It's cream. Made from milk. What else did you think you'd find in there? components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 150 - reagents: - - ReagentId: Cream - Quantity: 150 + - type: Solution + solution: + reagents: + - ReagentId: Cream + Quantity: 240 - type: Label currentLabel: reagent-name-cream - type: Sprite diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base.yml index 14e4b741c5..c264d88acb 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base.yml @@ -3,7 +3,7 @@ # Inheritors are an easily and freely accessible solution like cups, teapots, cans, flasks, bottles, or beakers. - type: entity abstract: true - parent: BaseItem + parent: [SolutionDrink, BaseItem] id: DrinkBase components: - type: Sprite @@ -36,10 +36,6 @@ solution: *sol - type: SolutionItemStatus solution: *sol - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - type: SolutionTransfer canChangeTransferAmount: true - type: UserInterface @@ -52,12 +48,13 @@ # This drink is empty trash - type: entity abstract: true + parent: SolutionDrink id: DrinkBaseEmptyTrash suffix: Empty components: - type: SpaceGarbage - type: TrashOnSolutionEmpty - solution: *sol + solution: drink - type: Tag tags: - Trash diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_glass.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_glass.yml index 3aa1e1d547..ee608ddf1b 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_glass.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_glass.yml @@ -2,33 +2,27 @@ - type: entity abstract: true - parent: [ DrinkBaseMaterialGlass, DrinkBase, DrinkBaseOpenable ] - id: DrinkBottleGlassBaseFull - suffix: Full + parent: [ DrinkBaseMaterialGlass, SolutionNormal, DrinkBase, DrinkBaseOpenable, DrinkBaseEmptyTrash ] + id: DrinkBottleGlassBase components: - - type: Item - size: Normal - type: Openable sound: collection: bottleOpenSounds closeable: true closeSound: collection: bottleCloseSounds - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - type: Sprite sprite: Objects/Consumable/Drinks/alco-bottle.rsi # fallback - type: Tool qualities: - Rolling speedModifier: 0.75 # not as good as a rolling pin but does the job - - type: TrashOnSolutionEmpty - solution: drink + - type: Item + size: Normal - type: Tag tags: - DrinkBottle + - Trash - type: Destructible # Same as parent, but spawns BrokenBottle instead of ShardGlass thresholds: - trigger: # Overkill threshold @@ -56,13 +50,19 @@ - type: entity abstract: true - parent: DrinkBottleGlassBaseFull - id: DrinkBottleGlassSmallBaseFull + parent: DrinkBottleGlassBase + id: DrinkBottleGlassBaseFull + suffix: Full + components: + - type: Tag + tags: + - DrinkBottle + +- type: entity + abstract: true + parent: [ SolutionSmall, DrinkBottleGlassBase ] + id: DrinkBottleGlassSmallBase components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 50 - type: Item size: Small - type: Sprite @@ -70,61 +70,87 @@ - type: FitsInDispenser solution: drink +- type: entity + abstract: true + parent: DrinkBottleGlassSmallBase + id: DrinkBottleGlassSmallBaseFull + suffix: Full + +- type: entity + abstract: true + parent: [ SolutionLarge, DrinkBottleGlassBase ] + id: DrinkBottleGlassLargeBaseFull + suffix: Full + components: + - type: Item + size: Large + shape: + - 0,0,1,3 + # Large Glass Bottles - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] - id: DrinkAbsintheBottleFull + parent: [DrinkVisualsAllFilled, DrinkBottleGlassBase] + id: DrinkBottleAbsinthe name: Jailbreaker Verte description: One sip of this and you just know you're gonna have a good time. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Absinthe - Quantity: 100 - type: Label currentLabel: reagent-name-absinthe - type: Sprite sprite: Objects/Consumable/Drinks/absinthebottle.rsi - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] - id: DrinkBlueCuracaoBottleFull + parent: DrinkBottleAbsinthe + id: DrinkAbsintheBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Absinthe + Quantity: 120 + +- type: entity + parent: [DrinkVisualsAllFilled, DrinkBottleGlassBase] + id: DrinkBottleAlcoClear name: Miss Blue Curaçao description: A fruity, exceptionally azure drink. Does not allow the imbiber to use the fifth magic. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: BlueCuracao - Quantity: 100 - type: Label currentLabel: reagent-name-blue-curacao - type: Sprite sprite: Objects/Consumable/Drinks/alco-bottle.rsi layers: - - state: icon_empty - map: ["enum.OpenableVisuals.Layer"] - - state: fill-6 - map: ["enum.SolutionContainerLayers.Fill"] + - state: icon_empty + map: ["enum.OpenableVisuals.Layer"] + - state: fill-6 + map: ["enum.SolutionContainerLayers.Fill"] - type: SolutionContainerVisuals maxFillLevels: 6 +- type: entity + parent: DrinkBottleAlcoClear + id: DrinkBlueCuracaoBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: BlueCuracao + Quantity: 120 + - type: entity parent: [DrinkVisualsOpenable, DrinkBottleGlassBaseFull] id: DrinkBottleOfNothingFull name: bottle of nothing description: A bottle filled with nothing. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Nothing - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: Nothing + Quantity: 120 - type: Label currentLabel: reagent-name-nothing - type: Sprite @@ -136,12 +162,11 @@ name: champagne bottle description: Only people devoid of imagination can't find an excuse for champagne. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Champagne - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: Champagne + Quantity: 120 - type: Label currentLabel: reagent-name-champagne - type: Sprite @@ -152,34 +177,38 @@ examineTextUnsealed: "sealable-component-on-examine-is-unsealed-no-cork" # tell the player why it can't close - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] - id: DrinkCognacBottleFull + parent: [DrinkVisualsAllFilled, DrinkBottleGlassBase] + id: DrinkBottleCognac name: cognac bottle description: A sweet and strongly alcoholic drink, made after numerous distillations and years of maturing. You might as well not scream 'SHITCURITY' this time. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Cognac - Quantity: 100 - type: Label currentLabel: reagent-name-cognac - type: Sprite sprite: Objects/Consumable/Drinks/cognacbottle.rsi +- type: entity + parent: DrinkBottleCognac + id: DrinkCognacBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Cognac + Quantity: 120 + - type: entity parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] id: DrinkGrenadineBottleFull name: Briar Rose grenadine syrup bottle description: Sweet and tangy, a bar syrup used to add color or flavor to drinks. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Grenadine - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: Grenadine + Quantity: 120 - type: Label currentLabel: reagent-name-grenadine - type: Sprite @@ -193,68 +222,82 @@ maxFillLevels: 6 - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] - id: DrinkGinBottleFull + parent: [DrinkVisualsAllFilled, DrinkBottleGlassBase] + id: DrinkBottleGin name: Griffeater gin description: A bottle of high quality gin, produced in the New London Space Station. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Gin - Quantity: 100 - type: Label currentLabel: reagent-name-gin - type: Sprite sprite: Objects/Consumable/Drinks/ginbottle.rsi - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] - id: DrinkGildlagerBottleFull + parent: DrinkBottleGin + id: DrinkGinBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Gin + Quantity: 120 + +- type: entity + parent: [DrinkVisualsAllFilled, DrinkBottleGlassBase] + id: DrinkBottleGildlager name: Gildlager bottle description: 100 proof cinnamon schnapps, made for alcoholic teen girls on spring break. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Gildlager - Quantity: 100 - type: Label currentLabel: reagent-name-gildlager - type: Sprite sprite: Objects/Consumable/Drinks/gildlagerbottle.rsi - type: entity - parent: [DrinkVisualsOpenable, DrinkBottleGlassBaseFull] - id: DrinkCoffeeLiqueurBottleFull + parent: DrinkBottleGildlager + id: DrinkGildlagerBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Gildlager + Quantity: 120 + +- type: entity + parent: [ DrinkVisualsOpenable, DrinkBottleGlassBase ] + id: DrinkBottleCoffeeLiqueur name: coffee liqueur bottle description: The great taste of coffee with none of the benifits. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: CoffeeLiqueur - Quantity: 100 - type: Label currentLabel: reagent-name-coffeeliqueur - type: Sprite sprite: Objects/Consumable/Drinks/coffeeliqueurbottle.rsi +- type: entity + parent: DrinkBottleCoffeeLiqueur + id: DrinkCoffeeLiqueurBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: CoffeeLiqueur + Quantity: 120 + - type: entity parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] id: DrinkMelonLiquorBottleFull name: Emeraldine melon liquor description: A bottle of 46 proof Emeraldine melon liquor. Sweet and light. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: MelonLiquor - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: MelonLiquor + Quantity: 120 - type: Label currentLabel: reagent-name-melon-liquor - type: Sprite @@ -268,138 +311,173 @@ maxFillLevels: 6 - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] - id: DrinkPatronBottleFull + parent: [DrinkVisualsAllFilled, DrinkBottleGlassBase] + id: DrinkBottlePatron name: Wrapp Artiste Patrón bottle description: Silver laced tequila, served in space night clubs across the galaxy. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Patron - Quantity: 100 - type: Label currentLabel: reagent-name-patron - type: Sprite sprite: Objects/Consumable/Drinks/patronbottle.rsi - type: entity - parent: [DrinkVisualsOpenable, DrinkBottleGlassBaseFull] - id: DrinkPoisonWinebottleFull + parent: DrinkBottlePatron + id: DrinkPatronBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Patron + Quantity: 120 + +- type: entity + parent: [DrinkVisualsOpenable, DrinkBottleGlassBase] + id: DrinkBottlePoisonWine name: Warlock's Velvet bottle description: What a delightful packaging for a surely high quality wine! The vintage must be amazing! components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: PoisonWine - Quantity: 100 - type: Sprite sprite: Objects/Consumable/Drinks/pwinebottle.rsi - type: Tag tags: - Wine - DrinkBottle + - Trash - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] - id: DrinkRumBottleFull + parent: DrinkBottlePoisonWine + id: DrinkPoisonWinebottleFull + name: Warlock's Velvet bottle + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: PoisonWine + Quantity: 120 + - type: Tag + tags: + - Wine + - DrinkBottle + +- type: entity + parent: [DrinkVisualsAllFilled, DrinkBottleGlassBase] + id: DrinkBottleRum name: Captain Pete's Cuban spiced rum description: This isn't just rum, oh no. It's practically GRIFF in a bottle. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Rum - Quantity: 100 - type: Label currentLabel: reagent-name-rum - type: Sprite sprite: Objects/Consumable/Drinks/rumbottle.rsi - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] - id: DrinkTequilaBottleFull + parent: DrinkBottleRum + id: DrinkRumBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Rum + Quantity: 120 + +- type: entity + parent: [DrinkVisualsAllFilled, DrinkBottleGlassBase] + id: DrinkBottleTequila name: Caccavo Guaranteed Quality tequila bottle description: Made from premium petroleum distillates, pure thalidomide and other fine quality ingredients! components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Tequila - Quantity: 100 - type: Label currentLabel: reagent-name-tequila - type: Sprite sprite: Objects/Consumable/Drinks/tequillabottle.rsi - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] - id: DrinkVermouthBottleFull + parent: DrinkBottleTequila + id: DrinkTequilaBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Tequila + Quantity: 120 + +- type: entity + parent: [DrinkVisualsAllFilled, DrinkBottleGlassBase] + id: DrinkBottleVermouth name: Goldeneye vermouth bottle description: Sweet, sweet dryness! components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Vermouth - Quantity: 100 - type: Label currentLabel: reagent-name-vermouth - type: Sprite sprite: Objects/Consumable/Drinks/vermouthbottle.rsi - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] - id: DrinkVodkaBottleFull + parent: DrinkBottleVermouth + id: DrinkVermouthBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Vermouth + Quantity: 120 + +- type: entity + parent: [DrinkVisualsAllFilled, DrinkBottleGlassBase] + id: DrinkBottleVodka name: vodka bottle description: Aah, vodka. Prime choice of drink AND fuel by Russians worldwide. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Vodka - Quantity: 100 - type: Label currentLabel: reagent-name-vodka - type: Sprite sprite: Objects/Consumable/Drinks/vodkabottle.rsi - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] - id: DrinkWhiskeyBottleFull + parent: DrinkBottleVodka + id: DrinkVodkaBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Vodka + Quantity: 120 + +- type: entity + parent: [DrinkVisualsAllFilled, DrinkBottleGlassBase] + id: DrinkBottleWhiskey name: Uncle Git's Special Reserve description: A premium single-malt whiskey, gently matured inside the tunnels of a nuclear shelter. TUNNEL WHISKEY RULES. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Whiskey - Quantity: 100 - type: Label currentLabel: reagent-name-whiskey - type: Sprite sprite: Objects/Consumable/Drinks/whiskeybottle.rsi - type: entity - parent: [DrinkVisualsOpenable, DrinkBottleGlassBaseFull] - id: DrinkWineBottleFull + parent: DrinkBottleWhiskey + id: DrinkWhiskeyBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Whiskey + Quantity: 120 + +- type: entity + parent: [DrinkVisualsOpenable, DrinkBottleGlassBase] + id: DrinkBottleWine name: Doublebearded Bearded Special wine bottle description: A faint aura of unease and asspainery surrounds the bottle. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Wine - Quantity: 100 - type: Label currentLabel: reagent-name-wine - type: Sprite @@ -408,22 +486,65 @@ tags: - Wine - DrinkBottle - -# Extra large bottles + - Trash - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] + parent: DrinkBottleWine + id: DrinkWineBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Wine + Quantity: 120 + - type: Tag + tags: + - Wine + - DrinkBottle + +- type: entity + name: nt cahors bottle + parent: DrinkBottleGlassBase + id: DrinkBottleNTCahors + components: + - type: Sprite + sprite: Objects/Consumable/Drinks/ntcahors.rsi + - type: Tag + tags: + - Wine + - DrinkBottle + - Trash + +- type: entity + name: nt cahors bottle + parent: DrinkBottleNTCahors + id: DrinkNTCahorsBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: NTCahors + Quantity: 120 + - type: Tag + tags: + - Wine + - DrinkBottle + +# Large bottles + +- type: entity + parent: [DrinkVisualsAllFilled, DrinkBottleGlassLargeBaseFull] id: DrinkBeerGrowler # todo Needs to be renamed DrinkBeerBottleFullGrowler name: beer growler # beer it is. coffee. beer? coff-ee? be-er? c-o... b-e description: An alcoholic beverage made from malted grains, hops, yeast, and water. XL growler bottle. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 150 - reagents: - - ReagentId: Beer - Quantity: 150 + - type: Solution + solution: + reagents: + - ReagentId: Beer + Quantity: 240 - type: Label currentLabel: reagent-name-beer - type: Sprite @@ -438,18 +559,16 @@ - DrinkBottle - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassBaseFull] + parent: [DrinkVisualsAllFilled, DrinkBottleGlassLargeBaseFull] id: DrinkAleBottleFullGrowler name: Magm-Ale growler description: A true dorf's drink of choice. XL growler bottle. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 150 - reagents: - - ReagentId: Ale - Quantity: 150 + - type: Solution + solution: + reagents: + - ReagentId: Ale + Quantity: 240 - type: Label currentLabel: reagent-name-ale - type: Sprite @@ -463,17 +582,11 @@ # Small glass bottles - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassSmallBaseFull] - id: DrinkBeerBottleFull + parent: [DrinkVisualsAllFilled, DrinkBottleGlassSmallBase] + id: DrinkBottleBeer name: beer bottle # beer it is. coffee. beer? coff-ee? be-er? c-o... b-e description: An alcoholic beverage made from malted grains, hops, yeast, and water. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Beer - Quantity: 50 - type: Label currentLabel: reagent-name-beer - type: Sprite @@ -487,17 +600,22 @@ - Beer - type: entity - parent: [DrinkVisualsAllFilled, DrinkBottleGlassSmallBaseFull] - id: DrinkAleBottleFull + parent: DrinkBottleBeer + id: DrinkBeerBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Beer + Quantity: 60 + +- type: entity + parent: [DrinkVisualsAllFilled, DrinkBottleGlassSmallBase] + id: DrinkBottleAle name: Magm-Ale bottle description: A true dorf's drink of choice. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Ale - Quantity: 50 - type: Label currentLabel: reagent-name-ale - type: Sprite @@ -507,18 +625,28 @@ - type: Sealable examineTextUnsealed: "sealable-component-on-examine-is-unsealed-crown-cap" # tell the player why it can't close +- type: entity + parent: DrinkBottleAle + id: DrinkAleBottleFull + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Ale + Quantity: 60 + - type: entity parent: [DrinkVisualsOpenable, DrinkBottleGlassSmallBaseFull] id: DrinkSakeBottleFull name: small sake bottle description: The regret of the next morning seems to be nipping on the bottle too. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Sake - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Sake + Quantity: 60 - type: Label currentLabel: reagent-name-sake - type: Sprite diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_plastic.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_plastic.yml index 3343ad42ce..4cae4c027f 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_plastic.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_plastic.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [ DrinkBaseMaterialPlastic, DrinkBase, DrinkBaseOpenable ] + parent: [ DrinkBaseMaterialPlastic, SolutionNormal, DrinkBase, DrinkBaseOpenable ] id: DrinkBottlePlasticBaseFull suffix: Full components: @@ -12,10 +12,6 @@ closeable: true closeSound: collection: bottleCloseSounds - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - type: Sprite sprite: Objects/Consumable/Drinks/generic_jug.rsi # fallback to generic plastic jug - type: TrashOnSolutionEmpty @@ -26,15 +22,11 @@ - type: entity abstract: true - parent: DrinkBottlePlasticBaseFull + parent: [SolutionSmall, DrinkBottlePlasticBaseFull] id: DrinkBottlePlasticSmallBaseFull components: - type: Item size: Small - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - type: Sprite sprite: Objects/Consumable/Drinks/waterbottle.rsi # fallback - type: FitsInDispenser @@ -43,15 +35,15 @@ # Empty - type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] + parent: [DrinkVisualsOpenable, SolutionLarge, DrinkBottlePlasticBaseFull] id: CustomDrinkJug name: beverage jug description: A jug for storing custom made drinks. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 150 + - type: Item + size: Large + shape: + - 0,0,1,3 # Small Plastic Bottles @@ -61,12 +53,11 @@ name: water bottle description: Simple clean water of unknown origin. You think that maybe you dont want to know it. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Water - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 60 - type: Sprite sprite: Objects/Consumable/Drinks/waterbottle.rsi - type: Label @@ -80,12 +71,11 @@ name: Space Cola bottle description: Cola. In spaaace! components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Cola - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: Cola + Quantity: 120 - type: Label currentLabel: reagent-name-cola - type: Sprite @@ -97,12 +87,11 @@ name: Space Solar Wind bottle description: Blows right through you like a solar wind. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: SpaceMountainWind - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: SpaceMountainWind + Quantity: 120 - type: Label currentLabel: reagent-name-space-mountain-wind - type: Sprite @@ -114,12 +103,11 @@ name: Space-Up bottle description: Tastes like a hull breach in your mouth. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: SpaceUp - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: SpaceUp + Quantity: 120 - type: Label currentLabel: reagent-name-space-up - type: Sprite @@ -131,13 +119,11 @@ name: soda water bottle description: Like water, but angry! components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - reagents: - - ReagentId: SodaWater - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: SodaWater + Quantity: 120 - type: Sprite sprite: Objects/Consumable/Drinks/sodawater-bottle.rsi - type: Label @@ -149,239 +135,210 @@ name: tonic water bottle description: Like soda water, but angrier maybe? Often sweeter. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - reagents: - - ReagentId: TonicWater - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: TonicWater + Quantity: 120 - type: Sprite sprite: Objects/Consumable/Drinks/tonic-bottle.rsi - type: Label currentLabel: reagent-name-tonic-water -- type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] - id: DrinkEnergyDrinkJug - name: Red Bool jug - description: A jug of Red Bool, with enough caffeine to kill a whole station. - components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - reagents: - - ReagentId: EnergyDrink - Quantity: 100 - - type: Label - currentLabel: reagent-name-energy-drink - # TODO new sprite - -# Xtra large -# TODO these have too much volume +# Large - type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] + parent: CustomDrinkJug id: DrinkSugarJug name: sugar jug suffix: For Drinks, Full description: Some people put this in their coffee... components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 300 - reagents: - - ReagentId: Sugar - Quantity: 300 + - type: Solution + solution: + reagents: + - ReagentId: Sugar + Quantity: 240 - type: Label currentLabel: reagent-name-sugar # TODO new sprite - type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] + parent: CustomDrinkJug id: DrinkLemonLimeJug name: Smite jug description: A dual citrus sensation. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 300 - reagents: - - ReagentId: LemonLime - Quantity: 300 + - type: Solution + solution: + reagents: + - ReagentId: LemonLime + Quantity: 240 - type: Label currentLabel: reagent-name-lemon-lime # TODO new sprite - type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] + parent: CustomDrinkJug id: DrinkMeadJug name: mead jug description: Storing mead in a plastic jug should be a crime. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 150 - reagents: - - ReagentId: Mead - Quantity: 150 + - type: Solution + solution: + reagents: + - ReagentId: Mead + Quantity: 240 - type: Label currentLabel: reagent-name-mead # TODO new sprite - type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] + parent: CustomDrinkJug id: DrinkIceJug name: ice jug description: Stubborn water. Pretty cool. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 300 - reagents: - - ReagentId: Ice - Quantity: 300 + - type: Solution + solution: + reagents: + - ReagentId: Ice + Quantity: 240 - type: Label currentLabel: reagent-name-ice # TODO new sprite - type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] + parent: CustomDrinkJug id: DrinkCoconutWaterJug name: coconut water jug description: It's on the inside of the coconut that counts. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 300 - reagents: - - ReagentId: CoconutWater - Quantity: 300 + - type: Solution + solution: + reagents: + - ReagentId: CoconutWater + Quantity: 240 - type: Label currentLabel: reagent-name-coconut-water # TODO new sprite - type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] + parent: CustomDrinkJug id: DrinkCoffeeJug name: coffee jug description: Wake up juice, of the heated kind. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 300 - reagents: - - ReagentId: Coffee - Quantity: 300 + - type: Solution + solution: + reagents: + - ReagentId: Coffee + Quantity: 240 - type: Label currentLabel: reagent-name-coffee # TODO new sprite - type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] + parent: CustomDrinkJug id: DrinkTeaJug name: tea jug description: The drink of choice for the Bri'ish and hipsters. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 300 - reagents: - - ReagentId: Tea - Quantity: 300 + - type: Solution + solution: + reagents: + - ReagentId: Tea + Quantity: 240 - type: Label currentLabel: reagent-name-tea # TODO new sprite - type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] + parent: CustomDrinkJug id: DrinkGreenTeaJug name: green tea jug description: It's like tea... but green! great for settling the stomach. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 300 - reagents: - - ReagentId: GreenTea - Quantity: 300 + - type: Solution + solution: + reagents: + - ReagentId: GreenTea + Quantity: 240 - type: Label currentLabel: reagent-name-green-tea # TODO new sprite - type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] + parent: CustomDrinkJug id: DrinkIcedTeaJug name: iced tea jug description: For when the regular tea is too hot for you. Boohoo. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 300 - reagents: - - ReagentId: IcedTea - Quantity: 300 + - type: Solution + solution: + reagents: + - ReagentId: IcedTea + Quantity: 240 - type: Label currentLabel: reagent-name-iced-tea # TODO new sprite - type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] + parent: CustomDrinkJug id: DrinkDrGibbJug name: Dr. Gibb jug description: 42 different flavours... in a jug! components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 300 - reagents: - - ReagentId: DrGibb - Quantity: 300 + - type: Solution + solution: + reagents: + - ReagentId: DrGibb + Quantity: 240 - type: Label currentLabel: reagent-name-dr-gibb # TODO new sprite - type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] + parent: CustomDrinkJug id: DrinkRootBeerJug name: root beer jug description: This drink makes Australians giggle. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 300 - reagents: - - ReagentId: RootBeer - Quantity: 300 + - type: Solution + solution: + reagents: + - ReagentId: RootBeer + Quantity: 240 - type: Label currentLabel: reagent-name-root-beer # TODO new sprite - type: entity - parent: [DrinkVisualsOpenable, DrinkBottlePlasticBaseFull] + parent: CustomDrinkJug id: DrinkWaterMelonJuiceJug name: watermelon juice jug description: May include leftover seeds. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 300 - reagents: - - ReagentId: JuiceWatermelon - Quantity: 300 + - type: Solution + solution: + reagents: + - ReagentId: JuiceWatermelon + Quantity: 240 - type: Label currentLabel: reagent-name-juice-watermelon # TODO new sprite + +- type: entity + parent: CustomDrinkJug + id: DrinkEnergyDrinkJug + name: Red Bool jug + description: A jug of Red Bool, with enough caffeine to kill a whole station. + components: + - type: Solution + solution: + reagents: + - ReagentId: EnergyDrink + Quantity: 240 + - type: Label + currentLabel: reagent-name-energy-drink + # TODO new sprite diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml index bb3eb76c29..4adf9404aa 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml @@ -1,25 +1,20 @@ # When adding new drinks also add to random spawner located in Resources\Prototypes\Entities\Markers\Spawners\Random\Food_Drinks\drinks_soda.yml - type: entity abstract: true - parent: [ DrinkBaseMaterialMetal, DrinkBase, DrinkBaseOpenable, DrinkVisualsOpenable ] - id: DrinkCanBaseFull - suffix: Full + parent: [ DrinkBaseMaterialMetal, SolutionSmall, DrinkBase, DrinkBaseOpenable, DrinkVisualsOpenable ] + id: DrinkCanBase components: - - type: SolutionContainerManager + - type: Solution + solution: + maxVol: 40 # Cans are about 330ml which translates to about 40u + - type: SolutionManager solutions: - drink: - maxVol: 30 - grindable: &grindable - reagents: # 5u -> 1/2 steel sheet (10u) - - ReagentId: Aluminium # Fun fact: soda can makeup is approx. 75% aluminium and 25% tin/iron. - Quantity: 4 - - ReagentId: Iron - Quantity: 1 + - SolutionCanComposite - type: SolutionTransfer canChangeTransferAmount: true maxTransferAmount: 15 - type: Extractable - grindableSolutionName: grindable + grindableSolutionName: composite - type: FitsInDispenser solution: drink - type: Tool @@ -36,22 +31,37 @@ tags: - DrinkCan -## Filled +# When adding new drinks also add to random spawner located in Resources\Prototypes\Entities\Markers\Spawners\Random\Food_Drinks\drinks_soda.yml +- type: entity + abstract: true + parent: DrinkCanBase + id: DrinkCanBaseFull + suffix: Full # :) - type: entity - parent: DrinkCanBaseFull - id: DrinkColaCan + parent: SolutionComposite + id: SolutionCanComposite + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 5 + reagents: # 5u -> 1/2 steel sheet (10u) + - ReagentId: Aluminium # Fun fact: soda can makeup is approx. 75% aluminium and 25% tin/iron. + Quantity: 4 + - ReagentId: Iron + Quantity: 1 + +## Filled + +### Needed because empty cola is important to construction +- type: entity + abstract: true + parent: DrinkCanBase + id: DrinkColaCanBase name: Space Cola can description: A sweet, carbonated soft drink. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Cola - Quantity: 30 - grindable: *grindable - type: Tag tags: - Cola @@ -61,17 +71,23 @@ - type: Item sprite: Objects/Consumable/Drinks/cola.rsi +- type: entity + parent: DrinkColaCanBase + id: DrinkColaCan + suffix: Full + components: + - type: Solution + solution: + reagents: + - ReagentId: Cola + Quantity: 40 + # created when taking apart an ied - type: entity - parent: [ DrinkBaseOpenableOpen, DrinkColaCan ] + parent: [ DrinkBaseOpenableOpen, DrinkColaCanBase ] id: DrinkColaCanEmpty suffix: Empty components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - grindable: *grindable - type: Tag tags: - Cola @@ -84,14 +100,11 @@ name: iced tea can description: A refreshing can of iced tea. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: IcedTea - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: IcedTea + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/ice_tea_can.rsi - type: Item @@ -103,14 +116,11 @@ name: Smite can description: You wanted ORANGE. It gave you Lemon-Lime. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: LemonLime - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: LemonLime + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/lemon-lime.rsi - type: Item @@ -122,14 +132,11 @@ name: Smite Cranberry can description: Y'all want a Smite Cranberry? Beloved by administrators everywhere. Drink in moderation. A limited run for the holidays! components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: LemonLimeCranberry - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: LemonLimeCranberry + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/lemon-lime-cranberry.rsi - type: Item @@ -174,14 +181,11 @@ name: grape soda can description: Sweetened drink with a grape flavor and a deep purple color. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: GrapeSoda - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: GrapeSoda + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/purple_can.rsi - type: Item @@ -193,14 +197,11 @@ name: root beer can description: Some of that tasty root beer goodness, now in a portable can! components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: RootBeer - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: RootBeer + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/rootbeer.rsi - type: Item @@ -216,14 +217,11 @@ name: soda water can description: Soda water. Why not make a scotch and soda? components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: SodaWater - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: SodaWater + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/sodawater.rsi - type: Item @@ -235,14 +233,11 @@ name: Space Solar Wind can description: Blows right through you like a solar wind. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: SpaceMountainWind - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: SpaceMountainWind + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/space_mountain_wind.rsi - type: Item @@ -254,14 +249,11 @@ name: Space-Up can description: Tastes like a hull breach in your mouth. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: SpaceUp - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: SpaceUp + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/space-up.rsi - type: Item @@ -273,14 +265,11 @@ name: Sol Dry can description: Sweet ginger soda from outer space! components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: SolDry - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: SolDry + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/sol_dry.rsi - type: Item @@ -292,14 +281,11 @@ name: Starkist can description: The taste of a star in liquid form. And, a bit of tuna...? components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Starkist - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: Starkist + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/starkist.rsi - type: Item @@ -311,14 +297,11 @@ name: tonic water can description: Quinine tastes funny, but at least it'll keep that Space Malaria away. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: TonicWater - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: TonicWater + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/tonic.rsi - type: Item @@ -330,14 +313,11 @@ name: Fourteen Loko can description: The MBO has advised crew members that consumption of Fourteen Loko may result in seizures, blindness, drunkeness, or even death. Please Drink Responsibly. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: FourteenLoko - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: FourteenLoko + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/fourteen_loko.rsi - type: Item @@ -349,14 +329,11 @@ name: Changeling Sting can description: You take a tiny sip and feel a burning sensation... components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: ChangelingSting - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: ChangelingSting + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/changelingsting.rsi - type: Item @@ -368,14 +345,11 @@ name: Dr. Gibb can description: A delicious blend of 42 different flavours. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: DrGibb - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: DrGibb + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/dr_gibb.rsi - type: Item @@ -387,18 +361,15 @@ name: Blood-red Brew can description: A home-brewed drink made from the crazed minds at the Syndicate. Not recommended by doctors. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Stimulants - Quantity: 5 - - ReagentId: NuclearCola - Quantity: 20 - - ReagentId: Ice - Quantity: 5 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: Stimulants + Quantity: 10 + - ReagentId: NuclearCola + Quantity: 25 + - ReagentId: Ice + Quantity: 5 - type: Sprite sprite: Objects/Consumable/Drinks/robustnukie.rsi - type: Item @@ -410,14 +381,11 @@ name: Red Bool can description: A can of Red Bool, with enough caffeine to kill a horse. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: EnergyDrink - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: EnergyDrink + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/energy_drink.rsi - type: Item @@ -429,14 +397,11 @@ name: Shambler's Juice can description: ~Shake me up some of that Shambler's Juice!~ components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: ShamblersJuice - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: ShamblersJuice + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/shamblersjuice.rsi - type: Item @@ -448,14 +413,11 @@ name: PWR Game can description: The only drink with the PWR that true gamers crave. When a gamer talks about gamerfuel, this is what they're literally referring to. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: PwrGame - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: PwrGame + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/pwrgame.rsi - type: Item @@ -467,14 +429,11 @@ name: beer can description: Small joy, big taste, no worries! components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Beer - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: Beer + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/beer_can.rsi - type: Item @@ -490,14 +449,11 @@ name: wine can description: Your way to forgetting all worries and having fun! components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Wine - Quantity: 30 - grindable: *grindable + - type: Solution + solution: + reagents: + - ReagentId: Wine + Quantity: 40 - type: Sprite sprite: Objects/Consumable/Drinks/wine_can.rsi - type: Item diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml index 896142562f..e7f4c3b56f 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml @@ -1,13 +1,11 @@ # A cup is a small container used to hold liquids for drinking.[1] - type: entity abstract: true - parent: DrinkBase + parent: [SolutionTiny, DrinkBase] id: DrinkBaseCup components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 20 + - type: Item + size: Tiny - type: FitsInDispenser solution: drink - type: SolutionTransfer @@ -49,6 +47,9 @@ name: teacup description: A plain white porcelain teacup. components: + - type: Solution + solution: + maxVol: 17 # About 5 imperial fluid ounces which is the english measurement for a teacup. Also I think fucked up volume sizes are funny. HAHAHAHAHAHAHA - type: Sprite sprite: Objects/Consumable/Drinks/teacup.rsi - type: SolutionContainerVisuals @@ -60,6 +61,8 @@ name: coupe glass description: A classic thin neck coupe glass, the icon of fragile labels on crates around the galaxy. components: + - type: Item + size: Small - type: Sprite sprite: Objects/Consumable/Drinks/glass_coupe_shape.rsi - type: SolutionContainerVisuals @@ -71,12 +74,9 @@ name: water cup description: A paper water cup. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 5 # One sip at a time. No rushing at the water cooler - - type: Item - size: Tiny + - type: Solution + solution: + maxVol: 10 # Miserably small - type: Sprite sprite: Objects/Consumable/Drinks/water_cup.rsi - type: SolutionContainerVisuals @@ -203,12 +203,11 @@ suffix: Full description: A heated drink consisting melted chocolate and heated milk. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: HotCocoa - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: HotCocoa + Quantity: 30 - type: Icon sprite: Objects/Consumable/Drinks/mug.rsi state: icon-vend-brown @@ -227,12 +226,11 @@ suffix: Full description: Coffee is a brewed drink prepared from roasted seeds, commonly called coffee beans, of the coffee plant. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Coffee - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Coffee + Quantity: 30 - type: Icon sprite: Objects/Consumable/Drinks/mug.rsi state: icon-vend-brown @@ -251,12 +249,11 @@ suffix: Full description: A nice, strong and tasty beverage while you are reading. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: CafeLatte - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: CafeLatte + Quantity: 30 - type: Icon sprite: Objects/Consumable/Drinks/cafe_latte.rsi state: icon-vend @@ -277,12 +274,11 @@ id: DrinkTeacup name: tea components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Tea - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Tea + Quantity: 17 - type: Icon sprite: Objects/Consumable/Drinks/teacup.rsi state: icon-vend-tea @@ -294,12 +290,11 @@ id: DrinkGreenTea name: green tea components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: GreenTea - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: GreenTea + Quantity: 17 - type: Icon sprite: Objects/Consumable/Drinks/teacup.rsi state: icon-vend-green-tea @@ -308,21 +303,21 @@ # TODO this needs fill levels - type: entity - parent: [DrinkBaseMaterialPlastic, DrinkBaseCup] + parent: [DrinkBaseMaterialPlastic, SolutionSmall, DrinkBaseCup] id: DrinkLean name: grape juice description: Damn, no fun allowed. components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: JuiceGrape - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: JuiceGrape + Quantity: 60 - type: Sprite sprite: Objects/Consumable/Drinks/lean.rsi - type: Item sprite: Objects/Consumable/Drinks/lean.rsi + size: Small - type: TrashOnSolutionEmpty solution: drink diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_flasks.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_flasks.yml index 31680db9ed..e03b922e70 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_flasks.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_flasks.yml @@ -1,12 +1,8 @@ - type: entity abstract: true - parent: [DrinkBaseMaterialStrongMetal, DrinkBase, DrinkBaseOpenable, DrinkVisualsOpenable] + parent: [DrinkBaseMaterialStrongMetal, SolutionSmall, DrinkBase, DrinkBaseOpenable, DrinkVisualsOpenable] id: FlaskBase components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - type: Sprite sprite: Objects/Consumable/Drinks/flask.rsi - type: FitsInDispenser @@ -21,15 +17,11 @@ # Flasks - type: entity - parent: [DrinkBaseMaterialStrongMetal, DrinkBase] + parent: [DrinkBaseMaterialStrongMetal, SolutionSmall, DrinkBase] id: DrinkFlaskOld name: old flask description: A decrepit old flask, its lid seems to be missing. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - type: Sprite sprite: Objects/Consumable/Drinks/flask_old.rsi - type: FitsInDispenser @@ -53,12 +45,11 @@ components: - type: Sprite sprite: Objects/Consumable/Drinks/mreflask.rsi - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Water - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 60 - type: TrashOnSolutionEmpty solution: drink diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_fun.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_fun.yml index 3ae53b077b..d7b87aeb24 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_fun.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_fun.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [ DrinkBaseMaterialPlastic, DrinkBase, DrinkBaseOpenable, DrinkVisualsAllFilled ] + parent: [ DrinkBaseMaterialPlastic, SolutionSmall, DrinkBase, DrinkBaseOpenable, DrinkVisualsAllFilled ] id: BaseSqueezeBottle components: - type: Openable @@ -14,10 +14,6 @@ map: [ "enum.SolutionContainerLayers.Fill" ] # already has liquid, so no visible: false - state: icon-front map: [ "enum.SolutionContainerLayers.Overlay" ] - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - type: SolutionContainerVisuals maxFillLevels: 6 - type: TrashOnSolutionEmpty @@ -31,13 +27,11 @@ components: - type: Sprite sprite: Objects/Consumable/Drinks/glue-tube.rsi - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: SpaceGlue - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: SpaceGlue + Quantity: 60 - type: Glue - type: entity @@ -48,13 +42,11 @@ components: - type: Sprite sprite: Objects/Consumable/Drinks/lube-tube.rsi - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: SpaceLube - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: SpaceLube + Quantity: 60 - type: Lube # Find your nearest clown and give them a gift :o) @@ -65,19 +57,17 @@ suffix: DEBUG description: This anomalous beaker infinitely produces space lube and as such is to be closely guarded such that it doesn't fall in the wrong hands. components: - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 1000 - reagents: - - ReagentId: SpaceLube - Quantity: 1000 + - type: Solution + solution: + reagents: + - ReagentId: SpaceLube + Quantity: 960 - type: SolutionRegeneration solution: beaker generated: reagents: - ReagentId: SpaceLube - Quantity: 200 + Quantity: 240 - type: entity parent: [DrinkBaseMaterialGlass, DrinkBase] @@ -143,13 +133,11 @@ name: delicious mopwata description: A foggy brown bottle with a faded label depicting a mop. It comes full of murky... vintage. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 50 - reagents: - - ReagentId: Mopwata - Quantity: 40 + - type: Solution + solution: + reagents: + - ReagentId: Mopwata + Quantity: 50 # Extra space for the random fill - type: RandomFillSolution solution: drink weightedRandomId: RandomFillMopwata diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml index 2b2ae6117d..f7ab48976b 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml @@ -4,24 +4,21 @@ # Transformable container - normal glass - type: entity - parent: [DrinkBaseMaterialGlass, DrinkBaseCup, DrinkVisualsFillOverlay] + parent: [DrinkBaseMaterialGlass, SolutionSmall, DrinkBaseCup, DrinkVisualsFillOverlay] id: DrinkGlass name: metamorphic glass description: A metamorphic glass that automagically turns into a glass appropriate for the drink within. There's a sanded off patent number on the bottom. components: + - type: Item + size: Small - type: Sprite sprite: Objects/Consumable/Drinks/glass_clear.rsi - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - type: SolutionContainerVisuals maxFillLevels: 9 metamorphic: true metamorphicDefaultSprite: sprite: Objects/Consumable/Drinks/glass_clear.rsi state: icon - - type: TransformableContainer - type: entity parent: DrinkGlass @@ -31,10 +28,6 @@ components: - type: Sprite sprite: Objects/Consumable/Drinks/jar.rsi - - type: SolutionContainerManager - solutions: - drink: - maxVol: 50 - type: SolutionContainerVisuals metamorphicDefaultSprite: sprite: Objects/Consumable/Drinks/jar.rsi @@ -49,13 +42,11 @@ id: DrinkAbsintheGlass suffix: absinthe components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Absinthe - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Absinthe + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/absintheglass.rsi state: icon @@ -65,13 +56,11 @@ id: DrinkAcidSpitGlass suffix: acid spit components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: AcidSpit - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: AcidSpit + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/acidspitglass.rsi state: icon @@ -81,13 +70,11 @@ id: DrinkAleGlass suffix: ale components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Ale - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Ale + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/aleglass.rsi state: icon @@ -97,13 +84,11 @@ id: DrinkAlienBrainHemorrhage suffix: alien brain hemorrhage components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: AlienBrainHemorrhage - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: AlienBrainHemorrhage + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/alienbrainhemorrhage.rsi state: icon @@ -113,13 +98,11 @@ id: DrinkAlliesCocktail suffix: allies cocktail components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: AlliesCocktail - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: AlliesCocktail + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/alliescocktail.rsi state: icon @@ -129,13 +112,11 @@ id: DrinkAloe suffix: aloe components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Aloe - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Aloe + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/aloe.rsi state: icon @@ -145,13 +126,11 @@ id: DrinkAmasecGlass suffix: amasec components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Amasec - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Amasec + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/amasecglass.rsi state: icon @@ -161,13 +140,11 @@ id: DrinkAndalusia suffix: andalusia components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Andalusia - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Andalusia + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/andalusia.rsi state: icon @@ -177,13 +154,11 @@ id: DrinkAntifreeze suffix: antifreeze components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Antifreeze - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Antifreeze + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/antifreeze.rsi state: icon @@ -193,13 +168,11 @@ id: DrinkArnoldPalmer suffix: arnold palmer components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: ArnoldPalmer - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: ArnoldPalmer + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/arnoldpalmer.rsi state: icon @@ -209,13 +182,11 @@ id: DrinkAtomicBombGlass suffix: atomic bomb components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: AtomicBomb - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: AtomicBomb + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/atomicbombglass.rsi state: icon @@ -225,13 +196,11 @@ id: DrinkB52Glass suffix: b-52 components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: B52 - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: B52 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/b52glass.rsi state: icon @@ -241,13 +210,11 @@ id: DrinkBahamaMama suffix: bahama mama components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: BahamaMama - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: BahamaMama + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/bahama_mama.rsi state: icon @@ -257,13 +224,11 @@ id: DrinkBananaHonkGlass suffix: banana honk components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: BananaHonk - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: BananaHonk + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/bananahonkglass.rsi state: icon @@ -273,13 +238,11 @@ id: DrinkBarefootGlass suffix: barefoot components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Barefoot - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Barefoot + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/b&p.rsi state: icon @@ -289,13 +252,11 @@ id: DrinkBeepskySmashGlass suffix: beepsky smash components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: BeepskySmash - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: BeepskySmash + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/beepskysmashglass.rsi state: icon @@ -305,13 +266,11 @@ id: DrinkBeerglass suffix: beer components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Beer - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Beer + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/beerglass.rsi state: icon @@ -321,13 +280,11 @@ id: DrinkBerryJuice suffix: berry juice components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: JuiceBerry - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: JuiceBerry + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/berryjuice.rsi state: icon @@ -337,13 +294,11 @@ id: DrinkBlackRussianGlass suffix: black russian components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: BlackRussian - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: BlackRussian + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/blackrussianglass.rsi state: icon @@ -353,13 +308,11 @@ id: DrinkBlueCuracaoGlass suffix: blue curacao components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: BlueCuracao - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: BlueCuracao + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/curacaoglass.rsi state: icon @@ -369,13 +322,11 @@ id: DrinkBloodyMaryGlass suffix: bloody mary components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: BloodyMary - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: BloodyMary + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/bloodymaryglass.rsi state: icon @@ -385,13 +336,11 @@ id: DrinkBlueHawaiianGlass suffix: blue hawaiian components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: BlueHawaiian - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: BlueHawaiian + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/bluehawaiian.rsi state: icon @@ -401,13 +350,11 @@ id: DrinkBooger suffix: booger components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Booger - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Booger + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/booger.rsi state: icon @@ -417,13 +364,11 @@ id: DrinkBraveBullGlass suffix: brave bull components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: BraveBull - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: BraveBull + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/bravebullglass.rsi state: icon @@ -433,13 +378,11 @@ id: DrinkBronxGlass suffix: bronx components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Bronx - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Bronx + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/bronx.rsi state: icon @@ -449,13 +392,11 @@ id: BudgetInsulsDrinkGlass suffix: budget insuls components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: BudgetInsulsDrink - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: BudgetInsulsDrink + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/budgetinsulsdrink.rsi state: icon @@ -465,13 +406,11 @@ id: DrinkCarrotJuice suffix: carrot juice components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: JuiceCarrot - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: JuiceCarrot + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/carrotjuice.rsi state: icon @@ -481,13 +420,11 @@ id: DrinkChocolateGlass suffix: chocolate components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: HotCocoa - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: HotCocoa + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/chocolateglass.rsi state: icon @@ -497,13 +434,11 @@ id: RubberneckGlass suffix: rubberneck components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Rubberneck - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Rubberneck + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/rubberneck.rsi state: icon @@ -513,13 +448,11 @@ id: DrinkCoconutRum suffix: coconut rum components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: CoconutRum - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: CoconutRum + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/coconutrum.rsi state: icon @@ -529,13 +462,11 @@ id: DrinkCoconutWaterGlass suffix: coconut water components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: CoconutWater - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: CoconutWater + Quantity: 60 #TODO - type: Icon - type: entity @@ -543,13 +474,11 @@ id: DrinkCoffee suffix: coffee components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Coffee - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Coffee + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/coffee.rsi state: icon @@ -559,13 +488,11 @@ id: DrinkCognacGlass suffix: cognac components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Cognac - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Cognac + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/cognacglass.rsi state: icon @@ -575,13 +502,11 @@ id: DrinkCosmopolitan suffix: cosmopolitan components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Cosmopolitan - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Cosmopolitan + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/cosmopolitan.rsi state: icon @@ -591,26 +516,22 @@ id: DrinkCream suffix: cream components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Cream - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Cream + Quantity: 60 - type: entity parent: DrinkGlass id: DrinkCrushDepthGlass suffix: crush depth components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: CrushDepth - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: CrushDepth + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/crushdepth.rsi state: icon @@ -620,13 +541,11 @@ id: DrinkCubaLibreGlass suffix: cuba libre components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: CubaLibre - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: CubaLibre + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/cubalibreglass.rsi state: icon @@ -636,13 +555,11 @@ id: DrinkDarkandStormyGlass suffix: dark and stormy components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: DarkandStormy - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: DarkandStormy + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/dark&stormy.rsi state: icon @@ -652,13 +569,11 @@ id: DrinkDeadRumGlass suffix: dead rum components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: DeadRum - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: DeadRum + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/rumglass.rsi state: icon @@ -668,13 +583,11 @@ id: DrinkDemonsBlood suffix: demon's blood components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: DemonsBlood - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: DemonsBlood + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/demonsblood.rsi state: icon @@ -684,13 +597,11 @@ id: DrinkDevilsKiss suffix: devil's kiss components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: DevilsKiss - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: DevilsKiss + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/devilskiss.rsi state: icon @@ -700,13 +611,11 @@ id: DrinkDoctorsDelightGlass suffix: doctor's delight components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: DoctorsDelight - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: DoctorsDelight + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/doctorsdelightglass.rsi state: icon @@ -716,13 +625,11 @@ id: DrinkDriestMartiniGlass suffix: driest martini components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: DriestMartini - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: DriestMartini + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/driestmartiniglass.rsi state: icon @@ -732,13 +639,11 @@ id: DrinkDrGibbGlass suffix: dr gibb components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: DrGibb - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: DrGibb + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/dr_gibb_glass.rsi state: icon @@ -748,13 +653,11 @@ id: DrinkEggnog suffix: eggnog components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Eggnog - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Eggnog + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/eggnogglass.rsi state: icon @@ -764,13 +667,11 @@ id: DrinkElectricSharkGlass suffix: electric shark components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: ElectricShark - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: ElectricShark + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/electricshark.rsi state: icon @@ -780,13 +681,11 @@ id: DrinkErikaSurprise suffix: erika surprise components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: ErikaSurprise - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: ErikaSurprise + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/erikasurprise.rsi state: icon @@ -796,13 +695,11 @@ id: DrinkFourteenLokoGlass suffix: fourteen loko components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: FourteenLoko - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/fourteen_loko_glass.rsi state: icon @@ -812,13 +709,11 @@ id: DrinkGargleBlasterGlass suffix: pan-galactic gargle blaster components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: GargleBlaster - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/gargleblasterglass.rsi state: icon @@ -828,13 +723,11 @@ id: DrinkGinGlass suffix: gin components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Gin - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/ginvodkaglass.rsi state: icon @@ -844,13 +737,11 @@ id: DrinkGinFizzGlass suffix: gin fizz components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: GinFizz - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/ginfizzglass.rsi state: icon @@ -860,13 +751,11 @@ id: DrinkGinTonicglass suffix: gin and tonic components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: GinTonic - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/gintonicglass.rsi state: icon @@ -876,13 +765,11 @@ id: DrinkGildlagerGlass suffix: gildlager components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Gildlager - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/gildlagerglass.rsi state: icon @@ -892,13 +779,11 @@ id: DrinkGrapeJuice suffix: grape juice components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: JuiceGrape - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/grapejuice.rsi state: icon @@ -908,13 +793,11 @@ id: DrinkGrapeSodaGlass suffix: grape soda components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: GrapeSoda - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/gsodaglass.rsi state: icon @@ -924,13 +807,11 @@ id: DrinkGreenTeaGlass suffix: green tea components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: GreenTea - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/greenteaglass.rsi state: icon @@ -940,13 +821,11 @@ id: DrinkGrenadineGlass suffix: grenadine components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Grenadine - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/grenadineglass.rsi state: icon @@ -956,13 +835,11 @@ id: DrinkGrogGlass suffix: grog components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Grog - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/grogglass.rsi state: icon @@ -972,13 +849,11 @@ id: DrinkHippiesDelightGlass suffix: hippies' delight components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: HippiesDelight - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/hippiesdelightglass.rsi state: icon @@ -989,13 +864,11 @@ suffix: hooch description: You've really hit rock bottom now... your liver packed its bags and left last night. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Hooch - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/glass_brown2.rsi state: icon @@ -1005,13 +878,11 @@ id: DrinkIcedCoffeeGlass suffix: iced coffee components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: IcedCoffee - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/icedcoffeeglass.rsi state: icon @@ -1021,13 +892,11 @@ id: DrinkIcedGreenTeaGlass suffix: iced green tea components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: IcedGreenTea - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/icedgreenteaglass.rsi state: icon @@ -1037,13 +906,11 @@ id: DrinkIcedTeaGlass suffix: iced tea components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: IcedTea - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/icedteaglass.rsi state: icon @@ -1053,13 +920,11 @@ id: DrinkIcedBeerGlass suffix: iced beer components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: IcedBeer - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/iced_beerglass.rsi state: icon @@ -1069,13 +934,11 @@ id: DrinkIceGlass suffix: ice components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Ice - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/iceglass.rsi state: icon @@ -1085,13 +948,11 @@ id: DrinkIceCreamGlass suffix: ice cream components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: IceCream - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/icecreamglass.rsi state: icon @@ -1101,13 +962,11 @@ id: IrishBoolGlass suffix: irish bool components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: IrishBool - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/beerglass.rsi state: icon @@ -1117,13 +976,11 @@ id: DrinkIrishSlammer suffix: grenade penguin components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: IrishSlammer - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/irishslammer.rsi state: icon @@ -1133,13 +990,11 @@ id: DrinkIrishCoffeeGlass suffix: irish coffee components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: IrishCoffee - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/irishcoffeeglass.rsi state: icon @@ -1149,13 +1004,11 @@ id: DrinkIrishCreamGlass suffix: irish cream components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: IrishCream - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/irishcreamglass.rsi state: icon @@ -1165,13 +1018,11 @@ id: DrinkCoffeeLiqueurGlass suffix: coffee liqueur components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: CoffeeLiqueur - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/coffeeliqueurglass.rsi state: icon @@ -1181,13 +1032,11 @@ id: DrinkJackRoseGlass suffix: jack rose components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: JackRose - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/jackrose.rsi state: icon @@ -1197,13 +1046,11 @@ id: DrinkJungleBirdGlass suffix: jungle bird components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: JungleBird - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/junglebird.rsi state: icon @@ -1213,13 +1060,11 @@ id: DrinkKalimotxoGlass suffix: kalimotxo components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Kalimotxo - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/kalimotxo.rsi state: icon @@ -1229,13 +1074,11 @@ id: DrinkOrangeLimeSodaGlass suffix: citrus bikeshed components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: OrangeLimeSoda - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/orangelime_soda.rsi state: icon @@ -1245,13 +1088,11 @@ id: DrinkLemonadeGlass suffix: lemonade components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Lemonade - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/lemonadeglass.rsi state: icon @@ -1261,13 +1102,11 @@ id: DrinkLemonJuice suffix: lemon juice components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: JuiceLemon - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/lemonjuiceglass.rsi state: icon @@ -1277,13 +1116,11 @@ id: DrinkLemonLime suffix: lemon lime components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: LemonLime - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/lemonlime.rsi state: icon @@ -1293,13 +1130,11 @@ id: DrinkLimeJuice suffix: lime juice components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: JuiceLime - Quantity: 30 + Quantity: 60 #TODO Icon - type: entity @@ -1307,13 +1142,11 @@ id: DrinkLongIslandIcedTeaGlass suffix: long island iced tea components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: LongIslandIcedTea - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/longislandicedteaglass.rsi state: icon @@ -1323,13 +1156,11 @@ id: DrinkManhattanGlass suffix: manhattan components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Manhattan - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/manhattanglass.rsi state: icon @@ -1339,13 +1170,11 @@ id: DrinkManhattanProjectGlass suffix: manhattan project components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: ManhattanProject - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/proj_manhattanglass.rsi state: icon @@ -1355,13 +1184,11 @@ id: DrinkManlyDorfGlass suffix: manly dorf components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: ManlyDorf - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/manlydorfglass.rsi state: icon @@ -1371,13 +1198,11 @@ id: DrinkMargaritaGlass suffix: margarita components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Margarita - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/margaritaglass.rsi state: icon @@ -1387,13 +1212,11 @@ id: DrinkMartiniGlass suffix: classic martini components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Martini - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/martiniglass.rsi state: icon @@ -1403,13 +1226,11 @@ id: DrinkMeadGlass suffix: mead components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Mead - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/meadglass.rsi state: icon @@ -1428,13 +1249,11 @@ id: DrinkMojito suffix: mojito components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Mojito - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/mojito.rsi state: icon @@ -1444,13 +1263,11 @@ id: DrinkMonkeyBusinessGlass suffix: monkey business components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: MonkeyBusiness - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/monkeybusiness.rsi state: icon @@ -1460,13 +1277,11 @@ id: DrinkNeurotoxinGlass suffix: neurotoxin components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Neurotoxin - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/neurotoxinglass.rsi state: icon @@ -1476,13 +1291,11 @@ id: DrinkNothing suffix: nothing components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Nothing - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/nothing.rsi state: icon @@ -1492,13 +1305,11 @@ id: DrinkNTCahors suffix: neotheology cahors whine components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: NTCahors - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/wineglass.rsi state: icon @@ -1508,13 +1319,11 @@ id: DrinkNuclearColaGlass suffix: nuclear cola components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: NuclearCola - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/nuclear_colaglass.rsi state: icon @@ -1524,13 +1333,11 @@ id: DrinkOrangeJuice suffix: orange juice components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: JuiceOrange - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/orangejuice.rsi state: icon @@ -1540,13 +1347,11 @@ id: DrinkPainkillerGlass suffix: painkiller components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Painkiller - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/painkiller.rsi state: icon @@ -1556,13 +1361,11 @@ id: DrinkPatronGlass suffix: patron components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Patron - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/patronglass.rsi state: icon @@ -1572,13 +1375,11 @@ id: DrinkPinaColadaGlass suffix: piña colada components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: PinaColada - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/pinacolada.rsi state: icon @@ -1588,13 +1389,11 @@ id: DrinkPoisonBerryJuice suffix: poison berry juice components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: JuiceBerryPoison - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/poisonberryjuice.rsi state: icon @@ -1604,13 +1403,11 @@ id: DrinkPoisonWineGlass suffix: poison wine components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: PoisonWine - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/pwineglass.rsi state: icon @@ -1620,13 +1417,11 @@ id: DrinkPoscaGlass suffix: posca components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Posca - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/glass_light_yellow.rsi state: icon @@ -1636,13 +1431,11 @@ id: DrinkRadlerGlass suffix: radler components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Radler - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/radler.rsi state: icon @@ -1652,13 +1445,11 @@ id: DrinkRedMeadGlass suffix: red mead components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: RedMead - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/red_meadglass.rsi state: icon @@ -1668,13 +1459,11 @@ id: DrinkRewriter suffix: rewriter components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Rewriter - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/rewriter.rsi state: icon @@ -1684,13 +1473,11 @@ id: DrinkRootBeerGlass suffix: root beer components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: RootBeer - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/rootbeerglass.rsi state: icon @@ -1700,13 +1487,11 @@ id: DrinkRootBeerFloatGlass suffix: root beer float components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: RootBeerFloat - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/rootbeerfloatglass.rsi state: icon @@ -1716,13 +1501,11 @@ id: DrinkRumGlass suffix: rum components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Rum - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/rumglass.rsi state: icon @@ -1732,13 +1515,11 @@ id: DrinkRoyRogersGlass suffix: roy rogers components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: RoyRogers - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/royrogers.rsi state: icon @@ -1748,13 +1529,11 @@ id: DrinkSakeGlass suffix: sake components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Sake - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/sakeglass.rsi state: icon @@ -1764,13 +1543,11 @@ id: DrinkSbitenGlass suffix: sbiten components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Sbiten - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/sbitenglass.rsi state: icon @@ -1780,13 +1557,11 @@ id: DrinkScrewdriverCocktailGlass suffix: screwdriver components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: ScrewdriverCocktail - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/screwdriverglass.rsi state: icon @@ -1796,13 +1571,11 @@ id: DrinkCogChampBase suffix: cogchamp components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: CogChamp - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/cogchamp.rsi state: icon @@ -1812,13 +1585,11 @@ id: DrinkSuiDreamGlass suffix: sui dream components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: SuiDream - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/sdreamglass.rsi state: icon @@ -1828,13 +1599,11 @@ id: DrinkEmeraldGlass suffix: melon liquor components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: MelonLiquor - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/emeraldglass.rsi state: icon @@ -1844,13 +1613,11 @@ id: DrinkMoonshineGlass suffix: moonshine components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Moonshine - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/glass_clear.rsi state: icon @@ -1860,13 +1627,11 @@ id: DrinkGlassWhite suffix: milk components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Milk - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/glass_white.rsi state: icon @@ -1876,13 +1641,11 @@ id: DrinkShirleyTempleGlass suffix: shirley temple components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: ShirleyTemple - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/shirleytemple.rsi state: icon @@ -1892,13 +1655,11 @@ id: DrinkSilencerGlass suffix: silencer components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Silencer - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/silencerglass.rsi state: icon @@ -1908,13 +1669,11 @@ id: DrinkSingulo suffix: singulo components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Singulo - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/singulo.rsi state: icon @@ -1924,13 +1683,11 @@ id: DrinkSolDryGlass suffix: sol dry components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: SolDry - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/sol_dry_glass.rsi state: icon @@ -1940,13 +1697,11 @@ id: DrinkSnowWhite suffix: snow white components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: SnowWhite - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/snowwhite.rsi state: icon @@ -1956,13 +1711,11 @@ id: DrinkSoyLatte suffix: soy latte components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: SoyLatte - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/soy_latte.rsi state: icon @@ -1972,13 +1725,11 @@ id: DrinkSpaceUpGlass suffix: space-up components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: SpaceUp - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/space-up_glass.rsi state: icon @@ -1988,13 +1739,11 @@ id: DrinkSpaceMountainWindGlass suffix: space mountain wind components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: SpaceMountainWind - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/space_mountain_wind_glass.rsi state: icon @@ -2004,13 +1753,11 @@ id: DrinkSyndicatebomb suffix: syndicate bomb components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: SyndicateBomb - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/syndicatebomb.rsi state: icon @@ -2020,13 +1767,11 @@ id: DrinkTeaGlass suffix: tea components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Tea - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/teaglass.rsi state: icon @@ -2036,13 +1781,11 @@ id: DrinkTequilaGlass suffix: tequila components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Tequila - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/tequillaglass.rsi state: icon @@ -2052,13 +1795,11 @@ id: DrinkTequilaSunriseGlass suffix: tequila sunrise components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: TequilaSunrise - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/tequillasunriseglass.rsi state: icon @@ -2068,13 +1809,11 @@ id: DrinkTheMartinez suffix: the martinez components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: TheMartinez - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: TheMartinez + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/the_martinez.rsi state: icon @@ -2084,13 +1823,11 @@ id: DrinkThreeMileIslandGlass suffix: three mile island components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: ThreeMileIsland - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: ThreeMileIsland + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/threemileislandglass.rsi state: icon @@ -2100,26 +1837,22 @@ id: DrinkTomatoJuice suffix: tomato juice components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: JuiceTomato - Quantity: 30 + Quantity: 60 - type: entity parent: DrinkGlass id: DrinkTortugaGlass suffix: tortuga components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Tortuga - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/tortuga.rsi state: icon @@ -2129,13 +1862,11 @@ id: DrinkToxinsSpecialGlass suffix: toxins special components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: ToxinsSpecial - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/toxinsspecialglass.rsi state: icon @@ -2145,13 +1876,11 @@ id: DrinkVampiroGlass suffix: vampiro components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Vampiro - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/vampiro.rsi state: icon @@ -2161,13 +1890,11 @@ id: DrinkVermouthGlass suffix: vermouth components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Vermouth - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/vermouthglass.rsi state: icon @@ -2177,13 +1904,11 @@ id: DrinkVodkaGlass suffix: vodka components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Vodka - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/ginvodkaglass.rsi state: icon @@ -2193,13 +1918,11 @@ id: DrinkVodkaMartiniGlass suffix: vodka martini components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: VodkaMartini - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/martiniglass.rsi state: icon @@ -2209,13 +1932,11 @@ id: DrinkVodkaRedBool suffix: vodka red bool components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: VodkaRedBool - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/ginvodkaglass.rsi state: icon @@ -2225,13 +1946,11 @@ id: DrinkVodkaTonicGlass suffix: vodka tonic components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: VodkaTonic - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/vodkatonicglass.rsi state: icon @@ -2242,13 +1961,11 @@ name: water jug description: Stay hydrated. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Water - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/water.rsi state: icon @@ -2258,13 +1975,11 @@ id: DrinkWatermelonJuice suffix: watermelon juice components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: JuiceWatermelon - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/watermelonglass.rsi state: icon @@ -2274,13 +1989,11 @@ id: DrinkWatermelonWakeup suffix: watermelon wakeup components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: WatermelonWakeup - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/champagneglass.rsi state: icon @@ -2290,13 +2003,11 @@ id: DrinkWhiskeyColaGlass suffix: whiskey cola components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: WhiskeyCola - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/whiskeycolaglass.rsi state: icon @@ -2306,13 +2017,11 @@ id: DrinkWhiskeyGlass suffix: whiskey components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Whiskey - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/whiskeyglass.rsi state: icon @@ -2322,13 +2031,11 @@ id: DrinkWhiskeySodaGlass suffix: whiskey soda components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: WhiskeySoda - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/whiskeysodaglass.rsi state: icon @@ -2338,13 +2045,11 @@ id: DrinkWhiteRussianGlass suffix: white russian components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: WhiteRussian - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/whiterussianglass.rsi state: icon @@ -2354,13 +2059,11 @@ id: DrinkWineGlass suffix: wine components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Wine - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/wineglass.rsi state: icon @@ -2370,13 +2073,11 @@ id: XenoBasherGlass suffix: xeno basher components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: XenoBasher - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/xenobasher.rsi state: icon @@ -2386,13 +2087,11 @@ id: DrinkCaipirinha suffix: caipirinha components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Caipirinha - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/caipirinha.rsi state: icon @@ -2402,13 +2101,11 @@ id: DrinkDaiquiri suffix: daiquiri components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Daiquiri - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/daiquiri.rsi state: icon @@ -2418,13 +2115,11 @@ id: DrinkDeathInTheAfternoon suffix: death in the afternoon components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: DeathInTheAfternoon - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/deathintheafternoon.rsi state: icon @@ -2434,13 +2129,11 @@ id: DrinkEmpress75 suffix: empress 75 components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Empress75 - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/empress75.rsi state: icon @@ -2450,13 +2143,11 @@ id: DrinkEspressoMartini suffix: espresso martini components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: EspressoMartini - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/espressomartini.rsi state: icon @@ -2466,13 +2157,11 @@ id: DrinkMayojito suffix: mayojito components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Mayojito - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/mayojito.rsi state: icon @@ -2482,13 +2171,11 @@ id: DrinkMimeosa suffix: mimeosa components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Mimeosa - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/mimeosa.rsi state: icon @@ -2498,13 +2185,11 @@ id: DrinkMimosa suffix: mimosa components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Mimosa - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/mimosa.rsi state: icon @@ -2514,13 +2199,11 @@ id: DrinkMoscowMule suffix: moscow mule components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: MoscowMule - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/moscowmule.rsi state: icon @@ -2530,13 +2213,11 @@ id: DrinkTheSunAlsoRises suffix: the sun also rises components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: TheSunAlsoRises - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/thesunalsorises.rsi state: icon @@ -2546,13 +2227,11 @@ id: DrinkWhiskeySour suffix: whiskey sour components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: WhiskeySour - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/whiskeysour.rsi state: icon @@ -2562,13 +2241,11 @@ id: DrinkBloodGlass suffix: blood components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: Blood - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/bloodglass.rsi state: icon @@ -2579,13 +2256,11 @@ suffix: bacchus blessing description: You didn't think it was possible for a liquid to be so utterly revolting. Are you sure about this...? components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 + - type: Solution + solution: reagents: - ReagentId: BacchusBlessing - Quantity: 30 + Quantity: 60 - type: Icon sprite: Objects/Consumable/Drinks/bacchusblessing.rsi state: icon diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_solutioncontainerexample.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_solutioncontainerexample.yml deleted file mode 100644 index 3a491e9373..0000000000 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_solutioncontainerexample.yml +++ /dev/null @@ -1,57 +0,0 @@ -# For empty check out chemistry bottles - -# With cut-out - -- type: entity - parent: DrinkBaseCup - id: DrinkVisualizerTestCut - name: solution container vis cut-out - description: A stainless steel insulated pitcher. Everyone's best friend in the morning. - components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: JuiceWatermelon - Quantity: 30 - - type: Sprite - sprite: Objects/Consumable/Drinks/pitcher.rsi - layers: - - state: icon - - state: fill-6 - map: ["enum.SolutionContainerLayers.Fill"] - # REMEMBER IF YOU'RE SPAWNING WITH LIQUID ALREADY IN IT YOU WANT THIS TRUE - visible: true - - type: Appearance - - type: SolutionContainerVisuals - maxFillLevels: 6 - fillBaseName: fill- - -# Without (For food, non cut-out stuff) - -- type: entity - parent: DrinkBaseCup - id: DrinkVisualizerTestNot - name: solution container vis cut-not - description: A stainless steel insulated pitcher. Everyone's best friend in the morning. - components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: JuiceWatermelon - Quantity: 30 - - type: Sprite - sprite: Objects/Consumable/Drinks/pitcher.rsi - layers: - - state: icon-6 - map: ["enum.SolutionContainerLayers.Fill"] - visible: true - - type: Appearance - - type: SolutionContainerVisuals - maxFillLevels: 6 - fillBaseName: icon- - changeColor: false - emptySpriteName: icon diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml index 2a44c451ab..9d23f09eb8 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml @@ -4,10 +4,9 @@ name: shot glass description: Perfect for slamming down onto the table angrily. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 5 + - type: Solution + solution: + maxVol: 5 # Shot glass translates to about 5.3u so we round down because Nanotrasen is cheap. - type: Item size: Tiny - type: Sprite @@ -19,17 +18,18 @@ solution: drink - type: entity - parent: [DrinkBaseMaterialMetal, DrinkBase] + parent: [DrinkBaseMaterialMetal, SolutionLarge, DrinkBase] id: DrinkIceBucket name: ice bucket description: A special bucket of refreshy ice. Prohibited use for challenge with the same name! components: - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Ice - Quantity: 200 + - type: Item + size: Large + - type: Solution + solution: + reagents: + - ReagentId: Ice + Quantity: 240 - type: Sprite sprite: Objects/Consumable/Drinks/icebucket.rsi state: icon @@ -38,18 +38,18 @@ Steel: 75 - type: entity - parent: [DrinkBaseMaterialPorcelain, DrinkBase] + parent: [DrinkBaseMaterialPorcelain, SolutionNormal, DrinkBase] id: DrinkTeapot name: teapot # short and stout description: An elegant teapot. It simply oozes class. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - reagents: - - ReagentId: Tea - Quantity: 100 + - type: Item + size: Normal + - type: Solution + solution: + reagents: + - ReagentId: Tea + Quantity: 120 - type: Sprite sprite: Objects/Consumable/Drinks/teapot.rsi - type: FitsInDispenser @@ -108,15 +108,14 @@ # Bartender tools - type: entity - parent: [DrinkBaseMaterialStrongMetal, DrinkBase] + parent: [DrinkBaseMaterialStrongMetal, SolutionSmall, DrinkBase] id: DrinkShaker name: shaker description: The trusty mixing buddy of the bartender. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 + - type: Solution + solution: + maxVol: 90 # Shakers are often about 700ml give or take and I like weird sizes so. - type: FitsInDispenser solution: drink - type: ExaminableSolution @@ -126,6 +125,8 @@ state: icon - type: Item sprite: Objects/Consumable/Drinks/shaker.rsi + shape: + - 0,0,0,2 # 3 tall - type: PhysicalComposition materialComposition: Steel: 50 @@ -156,10 +157,11 @@ name: jigger description: Like a shaker, but smaller. Used to control the amount of ingredients. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 20 + - type: Item + size: Tiny + - type: Solution + solution: + maxVol: 10 # Two shot glasses in size - type: SolutionTransfer canChangeTransferAmount: true minTransferAmount: 1 @@ -177,15 +179,13 @@ Steel: 20 - type: entity - parent: [DrinkBaseMaterialStrongMetal, DrinkBase, DrinkVisualsFill] + parent: [DrinkBaseMaterialStrongMetal, SolutionNormal, DrinkBase, DrinkVisualsFill] id: Pitcher name: metal pitcher description: A stainless steel insulated pitcher. Everyone's best friend in the morning. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 60 + - type: Item + size: Normal - type: Sprite sprite: Objects/Consumable/Drinks/pitcher.rsi - type: SolutionContainerVisuals diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/trash_drinks.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/trash_drinks.yml deleted file mode 100644 index 879ab62ba4..0000000000 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/trash_drinks.yml +++ /dev/null @@ -1,166 +0,0 @@ -# File for containers like bottles or milk jugs that are empty -# TODO these prototypes have ambiguous names and should be renamed to match their filled versions, with "Full" replaced by "Empty" - -# When used as the first parent, this empties a bottle's reagent and spawns it already opened -- type: entity - abstract: true - parent: [ DrinkBaseOpenableOpen, DrinkBaseEmptyTrash ] - id: DrinkBottleBaseEmpty - components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - - type: Tag - tags: - - DrinkBottle - - Trash - -- type: entity - abstract: true - parent: [ DrinkBaseOpenableOpen, DrinkBaseEmptyTrash ] - id: DrinkBottleBaseSmallEmpty - components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 50 - - type: Tag - tags: - - DrinkBottle - - Trash - -- type: entity - abstract: true - parent: [ DrinkBaseOpenableOpen, DrinkBaseEmptyTrash ] - id: DrinkCartonBaseEmpty - components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 50 - -- type: entity - abstract: true - parent: [ DrinkBaseOpenableOpen, DrinkBaseEmptyTrash ] - id: DrinkCartonBaseLargeEmpty - components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - -# Small bottles - -- type: entity - parent: [ DrinkBottleBaseSmallEmpty, DrinkAleBottleFull ] - id: DrinkBottleAle - -- type: entity - parent: [ DrinkBottleBaseSmallEmpty, DrinkBeerBottleFull ] - id: DrinkBottleBeer - components: - - type: Tag - tags: - - Beer - - Trash - -# Large bottles - -- type: entity - parent: [ DrinkBottleBaseEmpty, DrinkAbsintheBottleFull ] - id: DrinkBottleAbsinthe - -- type: entity - parent: [DrinkBottleBaseEmpty, DrinkBlueCuracaoBottleFull] - id: DrinkBottleAlcoClear - -- type: entity - parent: [ DrinkBottleBaseEmpty, DrinkCognacBottleFull ] - id: DrinkBottleCognac - -- type: entity - parent: [ DrinkBottleBaseEmpty, DrinkGinBottleFull ] - id: DrinkBottleGin - -- type: entity - parent: [DrinkBottleBaseEmpty, DrinkGildlagerBottleFull] - id: DrinkBottleGildlager - -- type: entity - name: coffee liqueur bottle - parent: [DrinkBottleBaseEmpty, DrinkCoffeeLiqueurBottleFull] - id: DrinkBottleCoffeeLiqueur - -# todo make a real cahors bottle -- type: entity - name: nt cahors bottle - parent: [DrinkBottleBaseEmpty, DrinkBottleGlassBaseFull] - id: DrinkBottleNTCahors - components: - - type: Sprite - sprite: Objects/Consumable/Drinks/ntcahors.rsi - -- type: entity - parent: [DrinkBottleBaseEmpty, DrinkPatronBottleFull] - id: DrinkBottlePatron - -- type: entity - parent: [DrinkBottleBaseEmpty, DrinkPoisonWinebottleFull] - id: DrinkBottlePoisonWine - -- type: entity - parent: [DrinkBottleBaseEmpty, DrinkRumBottleFull] - id: DrinkBottleRum - -- type: entity - parent: [DrinkBottleBaseEmpty, DrinkTequilaBottleFull] - id: DrinkBottleTequila - -- type: entity - parent: [DrinkBottleBaseEmpty, DrinkVermouthBottleFull] - id: DrinkBottleVermouth - -- type: entity - parent: [DrinkBottleBaseEmpty, DrinkVodkaBottleFull] - id: DrinkBottleVodka - -- type: entity - parent: [DrinkBottleBaseEmpty, DrinkWhiskeyBottleFull] - id: DrinkBottleWhiskey - -- type: entity - parent: [DrinkBottleBaseEmpty, DrinkWineBottleFull] - id: DrinkBottleWine - -# Small cartons - -- type: entity - parent: [DrinkCartonBaseEmpty, DrinkJuiceLimeCarton] - id: DrinkCartonLime - -- type: entity - parent: [DrinkCartonBaseEmpty, DrinkJuiceOrangeCarton] - id: DrinkCartonOrange - -- type: entity - parent: [DrinkCartonBaseEmpty, DrinkJuiceTomatoCarton] - id: DrinkCartonTomato - -- type: entity - parent: [DrinkCartonBaseEmpty, DrinkCreamCarton] - id: DrinkCartonCream - -# Large cartons - -- type: entity - parent: [DrinkCartonBaseLargeEmpty, DrinkMilkCarton] - id: DrinkCartonMilk - -- type: entity - parent: [DrinkCartonBaseLargeEmpty, DrinkSoyMilkCarton] - id: DrinkCartonSoyMilk - -- type: entity - parent: [DrinkCartonBaseLargeEmpty, DrinkOatMilkCarton] - id: DrinkCartonOatMilk diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bagel.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bagel.yml index 9a905db90a..cacdaa6102 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bagel.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bagel.yml @@ -3,7 +3,7 @@ - type: entity abstract: true - parent: FoodInjectableBase + parent: [SolutionVeryTiny, FoodInjectableBase] id: FoodBagelBase description: A delicious bagel. components: @@ -15,13 +15,11 @@ - type: Sprite sprite: Objects/Consumable/Food/Baked/bagel.rsi state: bagel - - type: SolutionContainerManager - solutions: - food: - maxVol: 7 - reagents: - - ReagentId: Nutriment - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 - type: entity parent: FoodBagelBase @@ -40,15 +38,13 @@ - medicine - type: Sprite state: bagel-poppy - - type: SolutionContainerManager - solutions: - food: - maxVol: 12 - reagents: - - ReagentId: Bicaridine - Quantity: 5 - - ReagentId: Nutriment - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Bicaridine + Quantity: 5 + - ReagentId: Nutriment + Quantity: 10 - type: entity parent: FoodBagelBase @@ -67,13 +63,10 @@ - type: Tag tags: - ClothMade - - type: SolutionContainerManager - solutions: - food: - maxVol: 12 - reagents: - - ReagentId: Nutriment - Quantity: 2.5 - - ReagentId: Fiber - Quantity: 2.5 - + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Fiber + Quantity: 5 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bread.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bread.yml index 1913f6b4e1..9809b64b5c 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bread.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bread.yml @@ -3,7 +3,7 @@ - type: entity abstract: true - parent: FoodInjectableBase + parent: [SolutionNormal, FoodInjectableBase] id: FoodBreadBase components: - type: Item @@ -16,16 +16,14 @@ - type: Tag tags: - Bread - - type: SolutionContainerManager - solutions: - food: - maxVol: 26 - reagents: - - ReagentId: Nutriment - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 80 - type: entity - parent: FoodBreadBase + parent: [SolutionVeryTiny, FoodBreadBase] id: FoodBreadSliceBase abstract: true components: @@ -38,13 +36,11 @@ tags: - Bread - Slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 8 - reagents: - - ReagentId: Nutriment - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 # 1/8 of a loaf of bread # Custom Bread Example @@ -61,6 +57,7 @@ - state: alpha-filling color: "#FF613F" - type: SliceableFood + count: 8 slice: FoodBreadVolcanicSlice - type: entity @@ -92,6 +89,7 @@ layers: - state: banana - type: SliceableFood + count: 8 slice: FoodBreadBananaSlice - type: Tag tags: @@ -134,20 +132,19 @@ layers: - state: cotton - type: SliceableFood + count: 8 slice: FoodBreadCottonSlice - type: Tag tags: - ClothMade - Bread - - type: SolutionContainerManager - solutions: - food: - maxVol: 26 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Fiber - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 40 + - ReagentId: Fiber + Quantity: 40 - type: entity name: cotton bread slice @@ -169,15 +166,13 @@ - ClothMade - Bread - Slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 8 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Fiber - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Fiber + Quantity: 5 - type: entity name: cornbread @@ -193,14 +188,8 @@ layers: - state: cornbread - type: SliceableFood + count: 8 slice: FoodBreadCornSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 15 # Tastes like bread, banana, nut. - type: entity @@ -216,13 +205,6 @@ - type: Sprite layers: - state: cornbread-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - type: entity name: cream cheese bread @@ -239,16 +221,15 @@ layers: - state: creamcheese - type: SliceableFood + count: 8 slice: FoodBreadCreamcheeseSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 35 - reagents: - - ReagentId: Nutriment - Quantity: 20 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 100 + - ReagentId: Vitamin + Quantity: 4 # Tastes like bread, cheese. - type: entity @@ -265,15 +246,13 @@ - type: Sprite layers: - state: creamcheese-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: Vitamin - Quantity: 1.2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 12.5 + - ReagentId: Vitamin + Quantity: 0.5 - type: entity name: meat bread @@ -289,16 +268,17 @@ layers: - state: meat - type: SliceableFood + count: 8 slice: FoodBreadMeatSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 45 - reagents: - - ReagentId: Nutriment - Quantity: 30 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 104 + - ReagentId: Protein + Quantity: 4 + - ReagentId: Vitamin + Quantity: 4 - type: Tag tags: - Meat @@ -318,15 +298,15 @@ - type: Sprite layers: - state: meat-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 1.2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 13 + - ReagentId: Protein + Quantity: 0.5 + - ReagentId: Vitamin + Quantity: 0.5 - type: Tag tags: - Meat @@ -347,20 +327,17 @@ layers: - state: mimana - type: SliceableFood + count: 8 slice: FoodBreadMimanaSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 15 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: Nothing - Quantity: 5 - - ReagentId: MuteToxin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 96 + - ReagentId: Vitamin + Quantity: 4 + - ReagentId: MuteToxin + Quantity: 10 # Tastes like bread, cheese. - type: entity @@ -376,19 +353,15 @@ - type: Sprite layers: - state: mimana-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 1 - - ReagentId: Nothing - Quantity: 1 - - ReagentId: MuteToxin - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 12 + - ReagentId: Vitamin + Quantity: 0.5 + - ReagentId: MuteToxin + Quantity: 1.25 - type: entity name: bread @@ -400,6 +373,7 @@ layers: - state: plain - type: SliceableFood + count: 8 slice: FoodBreadPlainSlice - type: entity @@ -426,18 +400,15 @@ layers: - state: sausage - type: SliceableFood + count: 8 slice: FoodBreadSausageSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 45 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: Protein - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 100 + - ReagentId: Protein + Quantity: 10 - type: Tag tags: - Meat @@ -456,17 +427,13 @@ - type: Sprite layers: - state: sausage-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Vitamin - Quantity: 1 - - ReagentId: Protein - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 12.5 + - ReagentId: Protein + Quantity: 1.25 - type: Tag tags: - Meat @@ -487,16 +454,17 @@ layers: - state: spidermeat - type: SliceableFood + count: 8 slice: FoodBreadMeatSpiderSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 45 - reagents: - - ReagentId: Nutriment - Quantity: 30 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 104 + - ReagentId: Protein + Quantity: 4 + - ReagentId: Vitamin + Quantity: 4 - type: Tag tags: - Meat @@ -516,15 +484,15 @@ - type: Sprite layers: - state: spidermeat-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 12 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 1.2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 13 + - ReagentId: Protein + Quantity: 0.5 + - ReagentId: Vitamin + Quantity: 0.5 - type: Tag tags: - Meat @@ -545,16 +513,15 @@ layers: - state: tofu - type: SliceableFood + count: 8 slice: FoodBreadTofuSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 48 - reagents: - - ReagentId: Nutriment - Quantity: 30 - - ReagentId: Protein - Quantity: 12 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 90 + - ReagentId: Protein + Quantity: 10 # Tastes like bread, tofu. - type: entity @@ -570,15 +537,13 @@ - type: Sprite layers: - state: tofu-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 2.4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 11.25 + - ReagentId: Protein + Quantity: 1.25 - type: entity name: xeno meat bread @@ -594,16 +559,17 @@ layers: - state: xenomeat - type: SliceableFood + count: 8 slice: FoodBreadMeatXenoSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 45 - reagents: - - ReagentId: Nutriment - Quantity: 30 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 104 + - ReagentId: Protein + Quantity: 4 + - ReagentId: Vitamin + Quantity: 4 - type: Tag tags: - Meat @@ -623,15 +589,15 @@ - type: Sprite layers: - state: xenomeat-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 1.2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 13 + - ReagentId: Protein + Quantity: 0.5 + - ReagentId: Vitamin + Quantity: 0.5 - type: Tag tags: - Meat @@ -651,19 +617,17 @@ - type: SliceableFood count: 12 slice: FoodBreadBaguetteSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 1 - - ReagentId: TableSalt - Quantity: 1 - - ReagentId: Blackpepper - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 78 + - ReagentId: Vitamin + Quantity: 3 + - ReagentId: TableSalt + Quantity: 3 + - ReagentId: Blackpepper + Quantity: 3 - type: Clothing slots: [ BELT ] equippedPrefix: baguette @@ -711,21 +675,19 @@ - state: baguette-cotton-inhand-left right: - state: baguette-cotton-inhand-right - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Fiber - Quantity: 3 - - ReagentId: Vitamin - Quantity: 1 - - ReagentId: TableSalt - Quantity: 1 - - ReagentId: Blackpepper - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 39 + - ReagentId: Fiber + Quantity: 39 + - ReagentId: Vitamin + Quantity: 0.6 + - ReagentId: TableSalt + Quantity: 0.6 + - ReagentId: Blackpepper + Quantity: 0.6 - type: entity name: crostini @@ -735,19 +697,17 @@ components: - type: Sprite state: crostini - - type: SolutionContainerManager - solutions: - food: - maxVol: 2 - reagents: - - ReagentId: Nutriment - Quantity: 0.5 - - ReagentId: Vitamin - Quantity: 0.1 - - ReagentId: TableSalt - Quantity: 0.1 - - ReagentId: Blackpepper - Quantity: 0.1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 6.5 + - ReagentId: Vitamin + Quantity: 0.05 + - ReagentId: TableSalt + Quantity: 0.05 + - ReagentId: Blackpepper + Quantity: 0.05 - type: entity parent: FoodBreadBaguetteSlice @@ -764,21 +724,19 @@ - Bread - Slice - ClothMade - - type: SolutionContainerManager - solutions: - food: - maxVol: 2 - reagents: - - ReagentId: Nutriment - Quantity: 0.25 - - ReagentId: Fiber - Quantity: 0.25 - - ReagentId: Vitamin - Quantity: 0.1 - - ReagentId: TableSalt - Quantity: 0.1 - - ReagentId: Blackpepper - Quantity: 0.1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 3.25 + - ReagentId: Fiber + Quantity: 3.25 + - ReagentId: Vitamin + Quantity: 0.05 + - ReagentId: TableSalt + Quantity: 0.05 + - ReagentId: Blackpepper + Quantity: 0.05 - type: entity name: buttered toast @@ -792,20 +750,18 @@ - bread - type: Sprite state: buttered-toast - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Butter + Quantity: 2.5 # Tastes like bread, butter. - type: entity name: french toast - parent: FoodBreadSliceBase + parent: [SolutionTiny, FoodBreadSliceBase] id: FoodBreadFrenchToast description: A slice of bread soaked in a beaten egg mixture. components: @@ -815,20 +771,22 @@ - bread - type: Sprite state: french-toast - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: Vitamin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: EggCooked + Quantity: 6 + - ReagentId: Protein + Quantity: 6 + - ReagentId: Vitamin + Quantity: 3 # Tastes like bread, butter. - type: entity name: garlic bread - parent: FoodBreadSliceBase + parent: [SolutionTiny, FoodBreadSliceBase] id: FoodBreadGarlicSlice description: Alas, it is limited. components: @@ -839,20 +797,22 @@ - type: Sprite layers: - state: garlic-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 16 + - ReagentId: Vitamin + Quantity: 4 + - ReagentId: Allicin + Quantity: 4 + - ReagentId: Butter + Quantity: 2.5 # Tastes like garlic, Italy. - type: entity name: jelly toast - parent: FoodBreadSliceBase + parent: [SolutionTiny, FoodBreadSliceBase] id: FoodBreadJellySlice description: As if science are gonna give up their slimes for toast! components: @@ -863,15 +823,13 @@ - type: Sprite layers: - state: jelly-toast - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 15 + - ReagentId: Vitamin + Quantity: 5 # Tastes like garlic, Italy. - type: entity @@ -886,43 +844,37 @@ - type: Tag tags: - Trash - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: Mold - Quantity: 7 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 2.5 + - ReagentId: Mold + Quantity: 10 # Tastes like decaying fungus. - type: entity name: two slice - parent: FoodBreadSliceBase + parent: [SolutionTiny, FoodBreadSliceBase] id: FoodBreadTwoSlice description: Classy. components: - type: Sprite layers: - state: two-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 2 - - ReagentId: Wine - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Wine + Quantity: 5 # Tastes like decaying fungus. - type: entity name: bread dog id: MobBreadDog - parent: EdibleBase + parent: [SolutionLarge, FoodBase] description: It's a bread. It's a dog. It's a... breaddog? components: - type: FlavorProfile @@ -930,18 +882,19 @@ - meaty - bread - type: SliceableFood + count: 8 slice: FoodBreadSausageSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 45 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: Protein - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 105 + - ReagentId: Vitamin + Quantity: 10 + - ReagentId: Protein + Quantity: 10 + - ReagentId: UncookedAnimalProteins + Quantity: 25 - type: Sprite noRot: true drawdepth: Mobs @@ -1003,7 +956,7 @@ Blunt: 1 - type: entity - parent: FoodBreadBase + parent: [SolutionVeryTiny, FoodBreadSliceBase] id: FoodBreadNutriBatard name: nutri-bâtard description: bon 'pétite! @@ -1048,10 +1001,8 @@ size: Small storedOffset: -1,0 heldPrefix: batard-cotton - - type: SolutionContainerManager - solutions: - food: - maxVol: 26 - reagents: - - ReagentId: Fiber - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 10 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml index 9436776d0d..01a594ab2d 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml @@ -2,7 +2,7 @@ # Base - type: entity - parent: FoodInjectableBase + parent: [SolutionNormal, FoodInjectableBase] id: FoodCakeBase abstract: true components: @@ -11,15 +11,15 @@ - sweet - type: Sprite sprite: Objects/Consumable/Food/Baked/cake.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 55 # flavored cakes have less room for spiking - reagents: - - ReagentId: Nutriment - Quantity: 40 - - ReagentId: Vitamin - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 60 + - ReagentId: Vitamin + Quantity: 10 + - ReagentId: Sugar + Quantity: 10 - type: Item size: Normal - type: Tag @@ -40,7 +40,7 @@ stash: !type:ContainerSlot {} - type: entity - parent: FoodCakeBase + parent: [SolutionVeryTiny, FoodCakeBase] id: FoodCakeSliceBase abstract: true description: Just a slice of cake, it is enough for everyone. @@ -49,15 +49,15 @@ flavors: - sweet - type: Edible - - type: SolutionContainerManager - solutions: - food: - maxVol: 12 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 7.5 + - ReagentId: Vitamin + Quantity: 1.25 + - ReagentId: Sugar + Quantity: 1.25 - type: Item size: Tiny - type: Tag @@ -79,6 +79,7 @@ - state: alpha-filling color: blue - type: SliceableFood + count: 8 slice: FoodCakeBlueberrySlice - type: Tag tags: @@ -133,16 +134,8 @@ - type: Sprite state: plain - type: SliceableFood + count: 8 slice: FoodCakePlainSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 55 - reagents: - - ReagentId: Nutriment - Quantity: 20 - - ReagentId: Vitamin - Quantity: 5 - type: Item heldPrefix: plain @@ -155,15 +148,6 @@ components: - type: Sprite state: plain-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: Vitamin - Quantity: 1 - type: Item heldPrefix: plain-slice # Tastes like sweetness, cake. @@ -177,18 +161,21 @@ - type: Sprite state: carrot - type: SliceableFood + count: 8 slice: FoodCakeCarrotSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: JuiceCarrot - Quantity: 15 - - ReagentId: Sugar - Quantity: 5 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 60 + - ReagentId: Vitamin + Quantity: 24 + - ReagentId: Sugar + Quantity: 10 + - ReagentId: JuiceCarrot + Quantity: 10 + - ReagentId: Oculine + Quantity: 6 - type: Tag tags: - Cake @@ -214,17 +201,19 @@ components: - type: Sprite state: carrot-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: JuiceCarrot - Quantity: 3 - - ReagentId: Sugar - Quantity: 1 - - ReagentId: Vitamin - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 7.5 + - ReagentId: Vitamin + Quantity: 3 + - ReagentId: Sugar + Quantity: 1.25 + - ReagentId: JuiceCarrot + Quantity: 1.25 + - ReagentId: Oculine + Quantity: 0.75 - type: Tag tags: - Cake @@ -254,6 +243,7 @@ - type: Sprite state: brain - type: SliceableFood + count: 8 slice: FoodCakeBrainSlice - type: Tag tags: @@ -308,6 +298,7 @@ - type: Sprite state: cheese - type: SliceableFood + count: 8 slice: FoodCakeCheeseSlice - type: Item inhandVisuals: @@ -352,6 +343,7 @@ - state: alpha-filling color: "#ff9900" - type: SliceableFood + count: 8 slice: FoodCakeOrangeSlice - type: Tag tags: @@ -407,6 +399,7 @@ - state: alpha-filling color: "#00ff00" - type: SliceableFood + count: 8 slice: FoodCakeLimeSlice - type: Tag tags: @@ -462,6 +455,7 @@ - state: alpha-filling color: "#ffff00" - type: SliceableFood + count: 8 slice: FoodCakeLemonSlice - type: Tag tags: @@ -518,18 +512,21 @@ - lemoon - berry - type: SliceableFood + count: 8 slice: FoodCakeLemoonSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 70 - reagents: - - ReagentId: Nutriment - Quantity: 40 - - ReagentId: Vitamin - Quantity: 20 - - ReagentId: Milk - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 64 + - ReagentId: Vitamin + Quantity: 20 + - ReagentId: Sugar + Quantity: 10 + - ReagentId: Milk + Quantity: 10 + - ReagentId: JuiceBerry + Quantity: 6 - type: Tag tags: - Cake @@ -549,17 +546,19 @@ flavors: - lemoon - berry - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 4 - - ReagentId: Milk - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 8 + - ReagentId: Vitamin + Quantity: 2.5 + - ReagentId: Sugar + Quantity: 1.25 + - ReagentId: Milk + Quantity: 1.25 + - ReagentId: JuiceBerry + Quantity: 0.75 - type: Tag tags: - Cake @@ -589,18 +588,21 @@ - state: alpha color: "#ba672e" - type: SliceableFood + count: 8 slice: FoodCakeChocolateSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 55 - reagents: - - ReagentId: Nutriment - Quantity: 40 - - ReagentId: Theobromine - Quantity: 5 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 60 + - ReagentId: Vitamin + Quantity: 10 + - ReagentId: Sugar + Quantity: 16 + - ReagentId: CocoaPowder + Quantity: 8 + - ReagentId: Theobromine + Quantity: 8 - type: Item inhandVisuals: left: @@ -619,17 +621,19 @@ layers: - state: alpha-slice color: "#ba672e" - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Theobromine - Quantity: 1 - - ReagentId: Vitamin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 7.5 + - ReagentId: Vitamin + Quantity: 1.25 + - ReagentId: Sugar + Quantity: 2 + - ReagentId: CocoaPowder + Quantity: 1 + - ReagentId: Theobromine + Quantity: 1 - type: Item inhandVisuals: left: @@ -652,6 +656,7 @@ - state: alpha-filling color: "#ff4300" - type: SliceableFood + count: 8 slice: FoodCakeAppleSlice - type: Tag tags: @@ -706,6 +711,7 @@ - type: Sprite state: slime - type: SliceableFood + count: 8 slice: FoodCakeSlimeSlice - type: Tag tags: @@ -760,16 +766,17 @@ - type: Sprite state: pumpkinspice - type: SliceableFood + count: 8 slice: FoodCakePumpkinSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 60 - reagents: - - ReagentId: Nutriment - Quantity: 35 - - ReagentId: Vitamin - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 84 + - ReagentId: Vitamin + Quantity: 16 + - ReagentId: Sugar + Quantity: 10 - type: Tag tags: - Cake @@ -793,15 +800,15 @@ components: - type: Sprite state: pumpkinspice-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 7 - - ReagentId: Vitamin - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10.5 + - ReagentId: Vitamin + Quantity: 2 + - ReagentId: Sugar + Quantity: 1.25 - type: Tag tags: - Cake @@ -828,6 +835,7 @@ - type: Sprite state: christmas - type: SliceableFood + count: 8 slice: FoodCakeChristmasSlice - type: Tag tags: @@ -873,6 +881,7 @@ - type: Sprite state: birthday - type: SliceableFood + count: 8 slice: FoodCakeBirthdaySlice - type: Item heldPrefix: birthday @@ -898,18 +907,8 @@ - type: Sprite state: vanilla - type: SliceableFood + count: 8 slice: FoodCakeVanillaSlice - - type: SolutionContainerManager #TODO Sprinkles - solutions: - food: - maxVol: 55 - reagents: - - ReagentId: Nutriment - Quantity: 25 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: Sugar - Quantity: 15 - type: Item heldPrefix: vanilla @@ -921,17 +920,6 @@ components: - type: Sprite state: vanilla-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 2 - - ReagentId: Sugar - Quantity: 5 - type: Item inhandVisuals: left: @@ -951,18 +939,8 @@ - type: Sprite state: clown - type: SliceableFood + count: 8 slice: FoodCakeClownSlice - - type: SolutionContainerManager #TODO Sprinkles - solutions: - food: - maxVol: 55 - reagents: - - ReagentId: Nutriment - Quantity: 30 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: Sugar - Quantity: 15 - type: Item heldPrefix: clown @@ -974,17 +952,6 @@ components: - type: Sprite state: clown-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 1 - - ReagentId: Sugar - Quantity: 5 - type: Item heldPrefix: clown-slice # Tastes like sweetness, cake, clown. @@ -998,18 +965,19 @@ - type: Sprite state: trumpet - type: SliceableFood + count: 8 slice: FoodCakeSpacemanSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 55 - reagents: - - ReagentId: Nutriment - Quantity: 30 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: PolypyryliumOligomers - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 60 + - ReagentId: Vitamin + Quantity: 16 + - ReagentId: Sugar + Quantity: 10 + - ReagentId: PolypyryliumOligomers + Quantity: 12 - type: Item heldPrefix: trumpet @@ -1021,17 +989,17 @@ components: - type: Sprite state: trumpet-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 1 - - ReagentId: PolypyryliumOligomers - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 7.5 + - ReagentId: Vitamin + Quantity: 2 + - ReagentId: Sugar + Quantity: 1.25 + - ReagentId: PolypyryliumOligomers + Quantity: 1.5 - type: Item heldPrefix: trumpet-slice # Tastes like sweetness, cake, jam. @@ -1039,7 +1007,7 @@ - type: entity name: cak id: MobCatCake - parent: EdibleBase + parent: [SolutionLarge, FoodBase] description: It's a cake. It's a cat. It's a cak. components: - type: FlavorProfile @@ -1049,15 +1017,19 @@ solution: food - type: RefillableSolution solution: food - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Nutriment - Quantity: 20 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 88 + - ReagentId: Vitamin + Quantity: 16 + - ReagentId: Sugar + Quantity: 10 + - ReagentId: Protein + Quantity: 12 + - ReagentId: UncookedAnimalProteins + Quantity: 24 - type: Sprite noRot: true drawdepth: Mobs @@ -1129,28 +1101,30 @@ - type: entity name: suppermatter - parent: FoodCakeBase + parent: [SolutionLarge, FoodCakeBase] id: FoodCakeSuppermatter description: Extremely dense and powerful food. components: - type: Sprite state: suppermatter - type: SliceableFood - slice: FoodCakeSuppermatterSlice count: 8 - - type: SolutionContainerManager - solutions: - food: - maxVol: 125 # SUPER dense cake - reagents: - - ReagentId: Nutriment - Quantity: 80 - - ReagentId: Sugar - Quantity: 30 + slice: FoodCakeSuppermatterSlice + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 120 + - ReagentId: Vitamin + Quantity: 20 + - ReagentId: Sugar + Quantity: 50 + - ReagentId: Plasma + Quantity: 10 - type: Edible transferAmount: 12 - type: Item - size: Normal + size: Large heldPrefix: suppermatter - type: PointLight color: "#FFFF00" @@ -1165,15 +1139,17 @@ components: - type: Sprite state: suppermatter-shard - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Sugar - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 15 + - ReagentId: Vitamin + Quantity: 2.5 + - ReagentId: Sugar + Quantity: 6.25 + - ReagentId: Plasma + Quantity: 1.25 - type: Edible transferAmount: 3 - type: PointLight @@ -1199,22 +1175,23 @@ - type: Sprite state: cotton - type: SliceableFood + count: 8 slice: FoodCakeCottonSlice - type: Tag tags: - Cake - ClothMade - - type: SolutionContainerManager - solutions: - food: - maxVol: 55 - reagents: - - ReagentId: Nutriment - Quantity: 30 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: Fiber - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 60 + - ReagentId: Vitamin + Quantity: 10 + - ReagentId: Sugar + Quantity: 10 + - ReagentId: Fiber + Quantity: 10 - type: Item heldPrefix: cotton @@ -1231,17 +1208,17 @@ - Cake - ClothMade - Slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 1 - - ReagentId: Fiber - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 7.5 + - ReagentId: Vitamin + Quantity: 1.25 + - ReagentId: Sugar + Quantity: 1.25 + - ReagentId: Fiber + Quantity: 1.25 - type: Item heldPrefix: cotton-slice @@ -1260,18 +1237,21 @@ - sweet - berry - motivating - - type: SolutionContainerManager - solutions: - food: - maxVol: 55 - reagents: - - ReagentId: Nutriment - Quantity: 40 - - ReagentId: Vitamin - Quantity: 10 - - ReagentId: Milk - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 70 + - ReagentId: Vitamin + Quantity: 20 + - ReagentId: Sugar + Quantity: 10 + - ReagentId: Milk + Quantity: 10 + - ReagentId: JuiceBerry + Quantity: 10 - type: SliceableFood + count: 8 slice: FoodCakeBerryDelightSlice - type: Tag tags: @@ -1301,17 +1281,19 @@ - sweet - berry - motivating - - type: SolutionContainerManager - solutions: - food: - maxVol: 12 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 2 - - ReagentId: Milk - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 8.75 + - ReagentId: Vitamin + Quantity: 2.5 + - ReagentId: Sugar + Quantity: 1.25 + - ReagentId: Milk + Quantity: 1.25 + - ReagentId: JuiceBerry + Quantity: 1.25 - type: Tag tags: - Cake diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donkpocket.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donkpocket.yml index 05bbf930ab..bf8955a4fb 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donkpocket.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donkpocket.yml @@ -1,20 +1,18 @@ # Base - type: entity - parent: FoodInjectableBase + parent: [SolutionTiny, FoodInjectableBase] id: FoodDonkpocketBase abstract: true components: - type: Edible - type: Sprite sprite: Objects/Consumable/Food/Baked/donkpocket.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 - type: Item size: Tiny - type: Tag @@ -41,9 +39,22 @@ - type: Sprite state: plain +- type: entity + parent: [SolutionFood, SolutionTiny] + id: SolutionFoodDonkpocketWarm + categories: [ HideSpawnMenu ] # Needed for a very specific lighter so can't be abstract + components: + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 12 + - ReagentId: Omnizine + Quantity: 3 + - type: entity name: warm donk-pocket - parent: FoodDonkpocket + parent: [SolutionFoodDonkpocketWarm, FoodDonkpocket] id: FoodDonkpocketWarm description: The heated food of choice for the seasoned traitor. components: @@ -52,15 +63,6 @@ - bread - meaty - cheap - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Omnizine - Quantity: 2 - type: entity name: dank-pocket @@ -72,18 +74,12 @@ flavors: - leafy - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - type: Sprite state: dank - type: entity name: warm dank-pocket - parent: FoodDonkpocketDank + parent: [SolutionFoodDonkpocketWarm, FoodDonkpocketDank] id: FoodDonkpocketDankWarm description: The heated food of choice for the seasoned botanist. components: @@ -91,14 +87,6 @@ flavors: - leafy - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Omnizine - Quantity: 4 - type: entity name: spicy-pocket @@ -116,7 +104,7 @@ - type: entity name: warm spicy-pocket - parent: FoodDonkpocketSpicy + parent: [SolutionFoodDonkpocketWarm, FoodDonkpocketSpicy] id: FoodDonkpocketSpicyWarm description: The classic snack food, now maybe a bit too spicy. components: @@ -125,14 +113,6 @@ - spicy - meaty - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Omnizine - Quantity: 2 - type: Sprite state: spicy @@ -152,7 +132,7 @@ - type: entity name: warm teriyaki-pocket - parent: FoodDonkpocketTeriyaki + parent: [SolutionFoodDonkpocketWarm, FoodDonkpocketTeriyaki] id: FoodDonkpocketTeriyakiWarm description: An East Asian take on the classic stationside snack, now steamy and warm. components: @@ -161,14 +141,6 @@ - meaty - sweet - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Omnizine - Quantity: 2 - type: entity name: pizza-pocket @@ -182,18 +154,12 @@ - cheesy - tomato - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 10 - type: Sprite state: pizza - type: entity name: warm pizza-pocket - parent: FoodDonkpocketPizza + parent: [SolutionFoodDonkpocketWarm, FoodDonkpocketPizza] id: FoodDonkpocketPizzaWarm description: Cheese filling really hits the spot when warm. components: @@ -203,14 +169,6 @@ - cheesy - tomato - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 15 - - ReagentId: Omnizine - Quantity: 2 - type: entity name: honk-pocket @@ -222,20 +180,19 @@ flavors: - funny - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Honk - Quantity: 0.50 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 8 + - ReagentId: Honk + Quantity: 2 - type: Sprite state: banana - type: entity name: warm honk-pocket - parent: FoodDonkpocketHonk + parent: [SolutionFoodDonkpocketWarm, FoodDonkpocketHonk] id: FoodDonkpocketHonkWarm description: The award-winning donk-pocket, now warm and toasty. components: @@ -243,16 +200,15 @@ flavors: - funny - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Honk - Quantity: 1 - - ReagentId: Omnizine - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Honk + Quantity: 2 + - ReagentId: Omnizine + Quantity: 3 - type: entity name: berry-pocket @@ -264,18 +220,12 @@ flavors: - sweet - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - type: Sprite state: berry - type: entity name: warm berry-pocket - parent: FoodDonkpocketBerry + parent: [SolutionFoodDonkpocketWarm, FoodDonkpocketBerry] id: FoodDonkpocketBerryWarm description: A relentlessly sweet donk-pocket, now warm and delicious. components: @@ -283,16 +233,15 @@ flavors: - sweet - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Omnizine - Quantity: 2 - - ReagentId: Sugar - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Omnizine + Quantity: 3 + - ReagentId: JuiceBerry + Quantity: 2 - type: entity name: stonk-pocket @@ -304,32 +253,18 @@ flavors: - profits - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - type: Sprite state: stonk - type: entity name: warm stonk-pocket - parent: FoodDonkpocketStonk + parent: [SolutionFoodDonkpocketWarm, FoodDonkpocketStonk] id: FoodDonkpocketStonkWarm components: - type: FlavorProfile flavors: - profits - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Omnizine - Quantity: 2 - type: entity name: carp-pocket @@ -341,32 +276,18 @@ flavors: - cheap - fishops - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - type: Sprite state: carp - type: entity name: warm carp-pocket - parent: FoodDonkpocketCarp + parent: [SolutionFoodDonkpocketWarm, FoodDonkpocketCarp] id: FoodDonkpocketCarpWarm components: - type: FlavorProfile flavors: - cheap - fishops - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Omnizine - Quantity: 2 - type: entity name: dink-pocket @@ -378,14 +299,15 @@ flavors: - cold - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: JuiceCarrot - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 2 + - ReagentId: JuiceCarrot + Quantity: 1 + - ReagentId: Cellulose + Quantity: 7 - type: Sprite state: dink @@ -399,14 +321,13 @@ flavors: - cotton - cheap - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Fiber - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Fiber + Quantity: 5 - type: Sprite state: moth - type: Edible @@ -418,16 +339,15 @@ - type: entity name: warm moth-pocket - parent: FoodDonkpocketMoth + parent: [SolutionFoodDonkpocketWarm, FoodDonkpocketMoth] id: FoodDonkpocketMothWarm components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Fiber - Quantity: 5 - - ReagentId: Omnizine - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 10 + - ReagentId: Nutriment + Quantity: 2 + - ReagentId: Omnizine + Quantity: 3 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donut.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donut.yml index 2403aefe6d..ae3b36f15b 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donut.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/donut.yml @@ -1,9 +1,9 @@ # Base - type: entity - parent: FoodInjectableBase - id: FoodDonutBase abstract: true + parent: [SolutionVeryTiny, FoodInjectableBase] + id: FoodDonutBase description: Goes great with robust coffee. components: - type: Tag @@ -11,13 +11,13 @@ - Donut - type: Sprite sprite: Objects/Consumable/Food/Baked/donut.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 6 + - ReagentId: Sugar + Quantity: 3 - type: Item sprite: Objects/Consumable/Food/Baked/donut.rsi size: Tiny @@ -31,6 +31,15 @@ tags: - Donut - Fruit + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 6 + - ReagentId: Sugar + Quantity: 3 + - ReagentId: Vitamin + Quantity: 1 # Tastes like donut. # The sprinkles are now an overlay, so you can put them on any donut! If we really @@ -43,9 +52,9 @@ # Plain Donuts - type: entity - name: plain donut parent: FoodDonutBase id: FoodDonutPlain + name: plain donut components: - type: FlavorProfile flavors: @@ -54,31 +63,22 @@ state: plain - type: entity - name: plain jelly-donut - parent: FoodDonutBase + parent: FoodDonutFruitBase id: FoodDonutJellyPlain + name: plain jelly-donut components: - type: FlavorProfile flavors: - jelly - type: Sprite state: jelly-plain - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 1 # Donuts - type: entity - name: donut parent: FoodDonutBase id: FoodDonutHomer + name: donut components: - type: FlavorProfile flavors: @@ -89,9 +89,9 @@ heldPrefix: pink - type: entity - name: chaos donut parent: FoodDonutBase id: FoodDonutChaos + name: chaos donut description: Like life, it never quite tastes the same. components: - type: FlavorProfile @@ -105,9 +105,9 @@ # Tastes like donut, chaos. - type: entity - name: meat donut parent: FoodDonutBase id: FoodDonutMeat + name: meat donut description: Tastes as gross as it looks. components: - type: FlavorProfile @@ -122,9 +122,9 @@ # Tastes like meat. - type: entity - name: pink donut parent: FoodDonutBase id: FoodDonutPink + name: pink donut description: Goes great with a soy latte. components: - type: FlavorProfile @@ -136,9 +136,9 @@ heldPrefix: pink - type: entity - name: spaceman's donut parent: FoodDonutBase id: FoodDonutSpaceman + name: spaceman's donut description: Goes great with a cold beaker of malk. components: - type: Sprite @@ -146,9 +146,9 @@ # Tastes like donut, violets. - type: entity - name: apple donut parent: FoodDonutBase id: FoodDonutApple + name: apple donut description: Goes great with a shot of cinnamon schnapps. components: - type: FlavorProfile @@ -160,9 +160,9 @@ # Tastes like donut, green apples. - type: entity - name: caramel donut parent: FoodDonutBase id: FoodDonutCaramel + name: caramel donut description: Goes great with a mug of hot coco. components: - type: Sprite @@ -170,9 +170,9 @@ # Tastes like donut, buttery sweetness. - type: entity - name: chocolate donut parent: FoodDonutBase id: FoodDonutChocolate + name: chocolate donut description: Goes great with a glass of warm milk. components: - type: FlavorProfile @@ -180,21 +180,21 @@ - chocolate - type: Sprite state: choc - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Theobromine - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 6 + - ReagentId: Sugar + Quantity: 3 + - ReagentId: Theobromine + Quantity: 1 # Tastes like donut, bitterness. - type: entity - name: blue pumpkin donut parent: FoodDonutBase id: FoodDonutBluePumpkin + name: blue pumpkin donut description: Goes great with a mug of soothing drunken blue pumpkin. components: - type: FlavorProfile @@ -206,9 +206,9 @@ # Tastes like donut, blue pumpkin. - type: entity - name: bungo donut parent: FoodDonutBase id: FoodDonutBungo + name: bungo donut description: Goes great with a mason jar of hippie's delight. components: - type: FlavorProfile @@ -220,9 +220,9 @@ # Tastes like donut, tropical sweetness. - type: entity - name: matcha donut parent: FoodDonutBase id: FoodDonut + name: matcha donut description: The L-theanine in this donut is relaxing, yet not euphoric. Goes great with a cup of tea. components: - type: FlavorProfile @@ -233,9 +233,9 @@ # Tastes like donut, matcha. - type: entity - name: sweet pea donut parent: FoodDonutBase id: FoodDonutSweetpea + name: sweet pea donut description: Goes great with a bottle of Bastion Burbon! components: - type: Sprite @@ -245,128 +245,83 @@ # Jelly Donuts - type: entity - name: jelly-donut - parent: FoodDonutBase + parent: FoodDonutFruitBase id: FoodDonutJellyHomer + name: jelly-donut description: You jelly? components: - type: Sprite state: jelly-homer - type: Item heldPrefix: pink - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 1 - type: entity - name: pink jelly-donut - parent: FoodDonutBase + parent: FoodDonutFruitBase id: FoodDonutJellyPink + name: pink jelly-donut description: Goes great with a soy latte. components: - type: Sprite state: jelly-pink - type: Item heldPrefix: pink - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 1 - type: entity - name: spaceman's jelly-donut - parent: FoodDonutBase + parent: FoodDonutFruitBase id: FoodDonutJellySpaceman + name: spaceman's jelly-donut description: Goes great with a cold beaker of malk. components: - type: Sprite state: jelly-purple - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 1 # Tastes like jelly-donut, violets. - type: entity - name: apple jelly-donut parent: FoodDonutFruitBase id: FoodDonutJellyApple + name: apple jelly-donut description: Goes great with a shot of cinnamon schnapps. components: - type: Sprite state: jelly-green - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 1 # Tastes like jelly-donut, green apples. - type: entity - name: caramel jelly-donut - parent: FoodDonutBase + parent: FoodDonutFruitBase id: FoodDonutJellyCaramel + name: caramel jelly-donut description: Goes great with a mug of hot coco. components: - type: Sprite state: jelly-beige - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 1 # Tastes like jelly-donut, buttery sweetness. - type: entity - name: chocolate jelly-donut - parent: FoodDonutBase + parent: FoodDonutFruitBase id: FoodDonutJellyChocolate + name: chocolate jelly-donut description: Goes great with a glass of warm milk. components: - type: Sprite state: jelly-choc - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Theobromine - Quantity: 1 - - ReagentId: Vitamin - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 6 + - ReagentId: Sugar + Quantity: 3 + - ReagentId: Vitamin + Quantity: 1 + - ReagentId: Theobromine + Quantity: 1 # Tastes like jelly-donut, bitterness. - type: entity - name: blue pumpkin jelly-donut parent: FoodDonutFruitBase id: FoodDonutJellyBluePumpkin + name: blue pumpkin jelly-donut description: Goes great with a mug of soothing drunken blue pumpkin. components: - type: FlavorProfile @@ -375,91 +330,46 @@ - bluepumpkin - type: Sprite state: jelly-blue - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 1 # Tastes like jelly-donut, blue pumpkin. - type: entity - name: bungo jelly-donut parent: FoodDonutFruitBase id: FoodDonutJellyBungo + name: bungo jelly-donut description: Goes great with a mason jar of hippie's delight. components: - type: Sprite state: jelly-yellow - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 1 # Tastes like jelly-donut, tropical sweetness. - type: entity - name: matcha jelly-donut - parent: FoodDonutBase + parent: FoodDonutFruitBase id: FoodDonutJelly + name: matcha jelly-donut description: The L-theanine in this jelly-donut is relaxing, yet not euphoric. Goes great with a cup of tea. components: - type: Sprite state: jelly-olive - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 1 # Tastes like jelly-donut, matcha. - type: entity - name: sweet pea jelly-donut - parent: FoodDonutBase + parent: FoodDonutFruitBase id: FoodDonutJellySweetpea + name: sweet pea jelly-donut description: Goes great with a bottle of Bastion Burbon! components: - type: Sprite state: jelly-laugh - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 1 # Tastes like jelly-donut, fizzy tutti frutti. - type: entity - name: scurret jelly-donut - parent: FoodDonutBase + parent: FoodDonutFruitBase id: FoodDonutJellyScurret + name: scurret jelly-donut description: No holes in this donut in case a suspicious looking pole shows up. components: - type: Sprite state: jelly-slug - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 1 # Tastes like jelly-donut, fizzy tutti frutti. # Poison donut @@ -468,10 +378,8 @@ id: FoodDonutPoison suffix: Poison components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Amatoxin - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Amatoxin + Quantity: 10 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/misc.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/misc.yml index 81293d76fc..16ad404a8d 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/misc.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/misc.yml @@ -2,19 +2,17 @@ # Base - type: entity - parent: FoodInjectableBase + parent: [SolutionVeryTiny, FoodInjectableBase] id: FoodBakedBase abstract: true components: - type: Sprite sprite: Objects/Consumable/Food/Baked/misc.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: Nutriment - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 - type: Item size: Tiny @@ -32,15 +30,6 @@ - type: Sprite sprite: Objects/Consumable/Food/Baked/misc.rsi state: muffin - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 2 - type: FlavorProfile flavors: - sweet @@ -55,17 +44,15 @@ components: - type: Sprite state: muffin-berry - - type: SolutionContainerManager - solutions: - food: - maxVol: 12 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 2 - - ReagentId: JuiceBerry - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Vitamin + Quantity: 1 + - ReagentId: JuiceBerry + Quantity: 1 - type: Tag tags: - Fruit @@ -78,17 +65,15 @@ components: - type: Sprite state: muffin-cherry - - type: SolutionContainerManager - solutions: - food: - maxVol: 12 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 2 - - ReagentId: JuiceCherry - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Vitamin + Quantity: 1 + - ReagentId: JuiceCherry + Quantity: 1 - type: Tag tags: - Fruit @@ -113,17 +98,15 @@ components: - type: Sprite state: muffin-chocolate - - type: SolutionContainerManager - solutions: - food: - maxVol: 12 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 2 - - ReagentId: CocoaPowder - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Vitamin + Quantity: 1 + - ReagentId: CocoaPowder + Quantity: 1 - type: entity name: banana muffin @@ -133,17 +116,15 @@ components: - type: Sprite state: muffin-banana - - type: SolutionContainerManager - solutions: - food: - maxVol: 12 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 2 - - ReagentId: JuiceBanana - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Vitamin + Quantity: 1 + - ReagentId: JuiceBanana + Quantity: 1 - type: Tag tags: - Fruit @@ -176,15 +157,6 @@ components: - type: Sprite state: bun-meat - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 2 # Cookies @@ -205,15 +177,6 @@ components: - type: Sprite state: cookie-oatmeal - - type: SolutionContainerManager - solutions: - food: - maxVol: 8 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 1 - type: entity name: raisin cookie @@ -223,15 +186,6 @@ components: - type: Sprite state: cookie-raisin - - type: SolutionContainerManager - solutions: - food: - maxVol: 8 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 1 - type: Tag tags: - Fruit @@ -269,17 +223,6 @@ lizard: "" star: "" corgi: "" - - type: SolutionContainerManager - solutions: - food: - maxVol: 8 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Protein - Quantity: 2 - - ReagentId: Vitamin - Quantity: 1 # Waffles/Pancakes @@ -441,15 +384,13 @@ - state: pancakescc9 map: ["pancakescc9"] visible: false - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Theobromine - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Theobromine + Quantity: 1 - type: entity name: waffles @@ -461,15 +402,6 @@ layers: - state: tray - state: waffles - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 1 - type: entity name: soy waffles @@ -481,15 +413,6 @@ layers: - state: tray - state: waffles-soy - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 1 - type: entity name: soylent waffles @@ -501,15 +424,6 @@ layers: - state: tray - state: waffles-soylent - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 1 - type: entity name: roffle waffles @@ -521,15 +435,6 @@ layers: - state: tray - state: waffles-roffle - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 2 # Misc @@ -550,15 +455,6 @@ components: - type: Sprite state: cannoli - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 1 - type: entity name: dumplings @@ -568,15 +464,13 @@ components: - type: Sprite state: dumplings - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Protein - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Protein + Quantity: 2 - type: FlavorProfile flavors: - meaty @@ -599,15 +493,17 @@ - smokey - type: Sprite state: chevrechaud - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Vitamin - Quantity: 0.5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10.5 + - ReagentId: Vitamin + Quantity: 1.05 + - ReagentId: TableSalt + Quantity: 0.05 + - ReagentId: Blackpepper + Quantity: 0.05 - type: entity name: cotton chèvre chaud @@ -629,20 +525,22 @@ - type: Tag tags: - ClothMade - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 1 - - ReagentId: Fiber - Quantity: 1 - - ReagentId: Vitamin - Quantity: 0.5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 7.25 + - ReagentId: Fiber + Quantity: 3.25 + - ReagentId: Vitamin + Quantity: 1.05 + - ReagentId: TableSalt + Quantity: 0.05 + - ReagentId: Blackpepper + Quantity: 0.05 - type: entity - parent: FoodBakedBase + parent: [SolutionNormal, FoodBakedBase] id: FoodBakedBrownieBatch name: brownies description: A pan of brownies. @@ -657,17 +555,17 @@ - type: Sprite sprite: Objects/Consumable/Food/Baked/brownie.rsi state: brownie-batch - - type: SolutionContainerManager - solutions: - food: - maxVol: 78 - reagents: - - ReagentId: Nutriment - Quantity: 30 - - ReagentId: Theobromine - Quantity: 18 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 48 + - ReagentId: Sugar + Quantity: 32 + - ReagentId: Theobromine + Quantity: 8 - type: SliceableFood - count: 6 + count: 8 slice: FoodBakedBrownie - type: entity @@ -684,21 +582,21 @@ - type: Sprite sprite: Objects/Consumable/Food/snacks.rsi state: mre-brownie-open - - type: SolutionContainerManager - solutions: - food: - maxVol: 13 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Theobromine - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 6 + - ReagentId: Sugar + Quantity: 4 + - ReagentId: Theobromine + Quantity: 2 - type: Tag tags: - Slice - type: entity - parent: FoodBakedBase + parent: [SolutionNormal, FoodBakedBase] id: FoodBakedCannabisBrownieBatch name: special brownies description: A pan of "special" brownies. @@ -714,19 +612,19 @@ - type: Sprite sprite: Objects/Consumable/Food/Baked/brownie.rsi state: brownie-batch - - type: SolutionContainerManager - solutions: - food: - maxVol: 228 - reagents: - - ReagentId: Nutriment - Quantity: 30 - - ReagentId: Theobromine - Quantity: 18 - - ReagentId: THC - Quantity: 150 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 48 + - ReagentId: Sugar + Quantity: 32 + - ReagentId: Theobromine + Quantity: 8 + - ReagentId: THC + Quantity: 16 - type: SliceableFood - count: 6 + count: 8 slice: FoodBakedCannabisBrownie - type: entity @@ -743,17 +641,17 @@ - type: Sprite sprite: Objects/Consumable/Food/snacks.rsi state: mre-brownie-open - - type: SolutionContainerManager - solutions: - food: - maxVol: 38 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Theobromine - Quantity: 3 - - ReagentId: THC - Quantity: 25 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 6 + - ReagentId: Sugar + Quantity: 4 + - ReagentId: Theobromine + Quantity: 1 + - ReagentId: THC + Quantity: 2 - type: Tag tags: - Slice @@ -770,20 +668,18 @@ - oily - type: Sprite state: onionrings - - type: SolutionContainerManager - solutions: - food: - maxVol: 4 - reagents: - - ReagentId: Nutriment - Quantity: 1 - - ReagentId: Allicin - Quantity: 1 - - ReagentId: Vitamin - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 2 + - ReagentId: Allicin + Quantity: 1 + - ReagentId: Vitamin + Quantity: 1 - type: entity - parent: FoodBakedBase + parent: [SolutionSmall, FoodBakedBase] id: FoodBakedCroissant name: croissant description: Buttery, flaky goodness. @@ -800,17 +696,13 @@ - butter - type: Sprite state: croissant - - type: SolutionContainerManager - solutions: - food: - maxVol: 7 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Butter - Quantity: 2 - - ReagentId: Vitamin - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Butter + Quantity: 2.5 - type: entity parent: FoodBakedCroissant @@ -835,22 +727,18 @@ - type: Tag tags: - ClothMade - - type: SolutionContainerManager - solutions: - food: - maxVol: 7 - reagents: - - ReagentId: Nutriment - Quantity: 1.5 - - ReagentId: Fiber - Quantity: 1.5 - - ReagentId: Butter - Quantity: 2 - - ReagentId: Vitamin - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Fiber + Quantity: 10 + - ReagentId: Butter + Quantity: 2.5 - type: entity - parent: FoodBakedBase + parent: [SolutionSmall, FoodBakedBase] id: FoodBakedGrilledCheeseSandwich name: grilled cheese sandwich description: Bread and cheese toasted with butter, perfect for a chilly day in space. @@ -866,17 +754,13 @@ - type: Sprite sprite: Objects/Consumable/Food/Baked/misc.rsi state: grilled-cheese - - type: SolutionContainerManager - solutions: - food: - maxVol: 21 - reagents: - - ReagentId: Nutriment - Quantity: 11 - - ReagentId: Butter - Quantity: 2 - - ReagentId: Vitamin - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 37.5 + - ReagentId: Butter + Quantity: 2.5 - type: entity parent: FoodBakedGrilledCheeseSandwich @@ -897,19 +781,15 @@ - type: Tag tags: - ClothMade - - type: SolutionContainerManager - solutions: - food: - maxVol: 21 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Fiber - Quantity: 5 - - ReagentId: Butter - Quantity: 2 - - ReagentId: Vitamin - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 25 + - ReagentId: Fiber + Quantity: 12.5 + - ReagentId: Butter + Quantity: 2.5 # Entity Tables diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pie.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pie.yml index b2dd9257b5..303166429a 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pie.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pie.yml @@ -3,33 +3,30 @@ - type: entity abstract: true - parent: FoodInjectableBase + parent: [SolutionNormal, FoodInjectableBase] id: FoodPieBase components: - type: Item - shape: - - 0,0,1,0 + size: Normal - type: FlavorProfile flavors: - sweet - type: Sprite sprite: Objects/Consumable/Food/Baked/pie.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 - reagents: #Most of these are this with slight variations, not worth changing until we have the rest of the reagents - - ReagentId: Nutriment - Quantity: 30 - - ReagentId: Vitamin - Quantity: 14 - - ReagentId: Sugar - Quantity: 5 + - type: Solution + solution: + reagents: #Most of these are this with slight variations, not worth changing until we have the rest of the reagents + - ReagentId: Nutriment + Quantity: 64 + - ReagentId: Vitamin + Quantity: 8 + - ReagentId: Sugar + Quantity: 8 - type: Edible #It's actually possible now to have a pie stored in a tin rather than spawning trash when you finish eating it. But right now I'm just cleaning up. trash: - FoodPlateTin - type: SliceableFood - count: 4 + count: 8 - type: Tag tags: - Pie @@ -47,17 +44,15 @@ - sweet - type: Sprite sprite: Objects/Consumable/Food/Baked/pie.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 7 - reagents: - - ReagentId: Nutriment - Quantity: 7.5 - - ReagentId: Vitamin - Quantity: 3.5 - - ReagentId: Sugar - Quantity: 1.25 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 8 + - ReagentId: Vitamin + Quantity: 1 + - ReagentId: Sugar + Quantity: 1 - type: Tag tags: - Pie @@ -475,17 +470,17 @@ - mushroom - type: Sprite state: amanita - - type: SolutionContainerManager - solutions: - food: - maxVol: 17 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Amatoxin - Quantity: 3 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 64 + - ReagentId: Vitamin + Quantity: 8 + - ReagentId: Sugar + Quantity: 8 + - ReagentId: Amatoxin + Quantity: 10 # Tastes like pie, mushrooms. - type: entity @@ -514,17 +509,6 @@ - sweet - type: Sprite state: grape - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Nutriment - Quantity: 15 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: Sugar - Quantity: 5 - type: Tag tags: - Fruit @@ -559,13 +543,15 @@ - chocolate - type: Sprite state: cocolava - - type: SolutionContainerManager - solutions: - food: - maxVol: 35 - reagents: - - ReagentId: Nutriment - Quantity: 25 - - ReagentId: Theobromine - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 64 + - ReagentId: Vitamin + Quantity: 8 + - ReagentId: Sugar + Quantity: 8 + - ReagentId: Theobromine + Quantity: 8 # Tastes like tart, dark chocolate. diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pizza.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pizza.yml index a288ad001c..20c002a818 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pizza.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/pizza.yml @@ -3,7 +3,7 @@ - type: entity abstract: true - parent: FoodInjectableBase + parent: [SolutionNormal, FoodInjectableBase] id: FoodPizzaBase components: - type: FlavorProfile @@ -12,17 +12,16 @@ - bread - type: Sprite sprite: Objects/Consumable/Food/Baked/pizza.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 30 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + maxVol: 180 + reagents: + - ReagentId: Nutriment + Quantity: 120 + - ReagentId: Vitamin + Quantity: 12 - type: SliceableFood - count: 8 + count: 12 - type: Item size: Normal shape: @@ -34,7 +33,7 @@ - ReptilianFood - type: entity - parent: FoodInjectableBase # Not sliceable + parent: [SolutionVeryTiny, FoodInjectableBase] # Not sliceable id: FoodPizzaSliceBase abstract: true components: @@ -44,16 +43,13 @@ - bread - type: Sprite sprite: Objects/Consumable/Food/Baked/pizza.rsi - - type: SolutionContainerManager - solutions: - food: - # Note: Keep FoodPizzaMoldySlice & FoodPizzaSliceBase roughly in sync - maxVol: 6 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 0.8 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Vitamin + Quantity: 1 - type: Item size: Tiny - type: Tag @@ -198,17 +194,6 @@ - state: vegetable - type: SliceableFood slice: FoodPizzaVegetableSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 25 - - ReagentId: JuiceCarrot - Quantity: 5 - - ReagentId: Vitamin - Quantity: 5 - type: entity name: slice of vegetable pizza @@ -230,17 +215,6 @@ - state: vegetable-slice - type: Item heldPrefix: vegetable-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: JuiceCarrot - Quantity: 1 - - ReagentId: Vitamin - Quantity: 1 # Tastes like crust, tomato, cheese, carrot. @@ -258,23 +232,20 @@ - state: donkpocket - type: SliceableFood slice: FoodPizzaDonkpocketSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 - reagents: - - ReagentId: Nutriment - Quantity: 27 - - ReagentId: Vitamin - Quantity: 6 - - ReagentId: Omnizine - Quantity: 9 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 120 + - ReagentId: Vitamin + Quantity: 3 + - ReagentId: Omnizine + Quantity: 9 - type: Tag tags: - Meat - Pizza - - type: entity name: slice of donk-pocket pizza parent: FoodPizzaSliceBase @@ -289,17 +260,15 @@ - state: donkpocket-slice - type: Item heldPrefix: donkpocket-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 4.5 - - ReagentId: Vitamin - Quantity: 1 - - ReagentId: Omnizine - Quantity: 1.5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Vitamin + Quantity: 0.25 + - ReagentId: Omnizine + Quantity: 0.75 - type: Tag tags: - Meat @@ -324,15 +293,15 @@ - state: dank - type: SliceableFood slice: FoodPizzaDankSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 - reagents: - - ReagentId: Nutriment - Quantity: 20 - - ReagentId: THC - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 102 + - ReagentId: Vitamin + Quantity: 3 + - ReagentId: THC + Quantity: 30 - type: entity name: slice of dank pizza @@ -351,15 +320,15 @@ - state: dank-slice - type: Item heldPrefix: dank-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 3.5 - - ReagentId: THC - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 0.5 + - ReagentId: Vitamin + Quantity: 0.25 + - ReagentId: THC + Quantity: 2.5 # Tastes like crust, tomato, cheese, meat, satisfaction. - type: entity @@ -475,19 +444,19 @@ - state: arnold - type: SliceableFood slice: FoodPizzaArnoldSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 85 - reagents: - - ReagentId: Nutriment - Quantity: 30 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: Iron - Quantity: 10 - - ReagentId: Omnizine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 60 + - ReagentId: Protein + Quantity: 18 + - ReagentId: Vitamin + Quantity: 12 + - ReagentId: Iron + Quantity: 18 + - ReagentId: Omnizine + Quantity: 30 - type: Tag tags: - Meat @@ -511,19 +480,19 @@ - state: arnold-slice - type: Item heldPrefix: arnold-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 0.8 - - ReagentId: Iron - Quantity: 1.6 - - ReagentId: Omnizine - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Protein + Quantity: 1.5 + - ReagentId: Vitamin + Quantity: 1 + - ReagentId: Iron + Quantity: 1.5 + - ReagentId: Omnizine + Quantity: 2.5 - type: Tag tags: - Meat @@ -551,18 +520,15 @@ - type: Tag tags: - Trash - - type: SolutionContainerManager - solutions: - food: - # Note: Keep FoodPizzaMoldySlice & FoodPizzaSliceBase roughly in sync - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Mold - Quantity: 2 - - ReagentId: Vitamin - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 2 + - ReagentId: Vitamin + Quantity: 1 + - ReagentId: Mold + Quantity: 8 # Tastes like stale crust, rancid cheese, mushroom. - type: entity @@ -589,17 +555,19 @@ - type: PointLight enabled: true radius: 2 - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 20 - - ReagentId: Radium - Quantity: 4 - - ReagentId: Uranium - Quantity: 16 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 102 + - ReagentId: Vitamin + Quantity: 15 + - ReagentId: CapsaicinOil + Quantity: 20 + - ReagentId: Radium + Quantity: 4 + - ReagentId: Uranium + Quantity: 16 - type: entity name: slice of spicy rock pizza @@ -626,17 +594,19 @@ - type: PointLight enabled: true radius: 2 - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 2.5 - - ReagentId: Radium - Quantity: 0.5 - - ReagentId: Uranium - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 8.5 + - ReagentId: Vitamin + Quantity: 1.25 + - ReagentId: CapsaicinOil + Quantity: 1.66 + - ReagentId: Radium + Quantity: 0.33 + - ReagentId: Uranium + Quantity: 1.33 # Tastes like crust, tomato, cheese, radiation. @@ -661,17 +631,15 @@ tags: - ClothMade - Pizza - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 20 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: Fiber - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Fiber + Quantity: 90 + - ReagentId: Vitamin + Quantity: 20 - type: entity name: slice of cotton pizza @@ -693,17 +661,15 @@ - ClothMade - Pizza - Slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: Nutriment - Quantity: 3.5 - - ReagentId: Vitamin - Quantity: 0.8 - - ReagentId: Fiber - Quantity: 1.5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 2.66 + - ReagentId: Fiber + Quantity: 7.5 + - ReagentId: Vitamin + Quantity: 2.66 - type: entity name: world peazza @@ -720,17 +686,15 @@ - state: worldpeas - type: SliceableFood slice: FoodPizzaWorldpeasSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 45 - reagents: - - ReagentId: Nutriment - Quantity: 20 - - ReagentId: Happiness - Quantity: 12 - - ReagentId: Pax - Quantity: 8 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 90 + - ReagentId: Happiness + Quantity: 15 + - ReagentId: Pax + Quantity: 15 - type: entity name: slice of world peazza @@ -747,14 +711,12 @@ - state: worldpeas-slice - type: Item heldPrefix: worldpeas-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 3.5 - - ReagentId: Happiness - Quantity: 2 - - ReagentId: Pax - Quantity: 1.5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 7.5 + - ReagentId: Happiness + Quantity: 1.25 + - ReagentId: Pax + Quantity: 1.25 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/bowl.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/bowl.yml index ce82ba1e1b..8f71eebafa 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/bowl.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/bowl.yml @@ -10,10 +10,6 @@ shape: - 0,0,1,0 storedOffset: 0,-3 - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 # enough to make cheese in. - type: Sprite sprite: Objects/Consumable/Food/bowl.rsi layers: @@ -21,6 +17,9 @@ - map: ["enum.SolutionContainerLayers.Fill"] state: fill-1 visible: false + - type: Solution + solution: + maxVol: 50 - type: MixableSolution solution: food - type: Edible diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/condiments.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/condiments.yml index 5cfe12d74a..da8e5ce239 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/condiments.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/condiments.yml @@ -1,7 +1,7 @@ # TODO: Removes the icon components from all these when that gets fixed. - type: entity - parent: BaseItem + parent: [SolutionFood, BaseItem] id: BaseFoodCondiment abstract: true components: @@ -46,12 +46,11 @@ # Note NOT refillable. # It be a shame if it turned out ALL drinks were ALWAYS refillable.... ffs. # Well its fixed now, but I want to share my pain. - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 + - type: Solution + solution: + maxVol: 1 # Cheap - type: SolutionTransfer - maxTransferAmount: 10 + maxTransferAmount: 1 - type: Sprite layers: - state: packet-trans-2 @@ -91,13 +90,11 @@ name: Astrotame description: The sweetness of a thousand sugars but none of the calories. components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Astrotame - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Astrotame + Quantity: 1 - type: Sprite layers: - state: packet-trans-2 @@ -119,13 +116,11 @@ name: BBQ sauce description: Hand wipes not included. components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: BbqSauce - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: BbqSauce + Quantity: 1 - type: Icon state: packet-bbq - type: Appearance @@ -139,13 +134,11 @@ name: corn oil description: Corn oil. A delicious oil used in cooking. Made from corn. components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Cornoil - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Cornoil + Quantity: 1 - type: Icon state: packet-cornoil - type: Appearance @@ -159,13 +152,11 @@ name: coldsauce description: Coldsauce. Leaves the tongue numb in its passage. components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Coldsauce - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Coldsauce + Quantity: 1 - type: Icon state: packet-frostoil - type: Appearance @@ -179,13 +170,11 @@ name: horseradish sauce description: A packet of smelly horseradish sauce. components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: HorseradishSauce - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: HorseradishSauce + Quantity: 1 - type: Icon state: packet-greygoo - type: Appearance @@ -199,13 +188,11 @@ name: hotsauce description: You can almost TASTE the stomach ulcers now! components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Hotsauce - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Hotsauce + Quantity: 1 - type: Icon state: packet-hotsauce - type: Appearance @@ -219,12 +206,11 @@ name: ketchup description: You feel more American already. components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Ketchup - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Ketchup + Quantity: 1 - type: Sprite - type: Icon state: packet-ketchup @@ -239,12 +225,11 @@ name: mustard description: A condiment made from the ground-up seeds of the Mustard plant. components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Mustard - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Mustard + Quantity: 1 - type: Icon state: packet-mustard - type: Appearance @@ -258,12 +243,11 @@ name: black pepper description: Often used to flavor food or make people sneeze. components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Blackpepper - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Blackpepper + Quantity: 1 - type: Icon state: packet-pepper - type: Appearance @@ -277,12 +261,11 @@ name: salt description: Salt. From space oceans, presumably. components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: TableSalt - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: TableSalt + Quantity: 1 - type: Sprite layers: - state: packet-solid-2 @@ -305,12 +288,11 @@ name: soy sauce description: A salty soy-based flavoring. components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Soysauce - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Soysauce + Quantity: 1 - type: Icon state: packet-soysauce - type: Appearance @@ -324,12 +306,11 @@ name: sugar description: Tasty spacey sugar! components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Sugar - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Sugar + Quantity: 1 - type: Icon state: packet-sugar - type: Appearance @@ -355,10 +336,9 @@ sound: collection: pop closeable: true - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 + - type: Solution + solution: + maxVol: 50 # ~ 400 to 450ml - type: RefillableSolution solution: food - type: Spillable @@ -389,12 +369,11 @@ name: coldsauce bottle description: Leaves the tongue numb in its passage. components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Coldsauce - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Coldsauce + Quantity: 50 - type: Sprite layers: - state: bottle-empty @@ -415,12 +394,11 @@ name: universal enzyme description: Used in cooking various dishes. components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Enzyme - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Enzyme + Quantity: 50 - type: Sprite layers: - state: bottle-empty @@ -441,12 +419,11 @@ name: vinegar bottle description: Used in cooking to enhance flavor. components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Vinegar - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Vinegar + Quantity: 50 - type: Sprite layers: - state: bottle-empty @@ -464,12 +441,11 @@ name: hotsauce bottle description: You can almost TASTE the stomach ulcers now! components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Hotsauce - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Hotsauce + Quantity: 50 - type: Sprite layers: - state: bottle-empty @@ -490,12 +466,11 @@ name: ketchup bottle description: You feel more American already. components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Ketchup - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Ketchup + Quantity: 50 - type: Sprite layers: - state: bottle-empty @@ -516,12 +491,11 @@ name: BBQ sauce bottle description: Hand wipes not included. components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: BbqSauce - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: BbqSauce + Quantity: 50 - type: Sprite layers: - state: bottle-empty @@ -540,7 +514,7 @@ # Shakers - type: entity - parent: BaseFoodCondiment # TODO: This should not inherit TrashOnSolutionEmpty, SpaceGarbage and the price of 0 + parent: [SolutionVeryTiny, BaseFoodCondiment] # TODO: This should not inherit TrashOnSolutionEmpty, SpaceGarbage and the price of 0 id: BaseFoodShaker abstract: true name: empty shaker @@ -553,10 +527,6 @@ solution: food destroyOnEmpty: false utensil: None # don't conflict with stirring - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - type: SolutionTransfer canChangeTransferAmount: true minTransferAmount: 5 @@ -590,12 +560,11 @@ name: salt shaker description: Salt. From space oceans, presumably. components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: TableSalt - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: TableSalt + Quantity: 15 - type: Sprite state: shaker-salt - type: Icon @@ -610,12 +579,11 @@ name: pepper shaker description: Often used to flavor food or make people sneeze. components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Blackpepper - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Blackpepper + Quantity: 15 - type: Sprite state: shaker-pepper - type: Icon diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml index cda1735790..c95ff41a2e 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/tin.yml @@ -4,18 +4,21 @@ # trash prototypes use "trash" state - type: entity abstract: true - parent: [FoodBase, FoodOpenableBase] + parent: [FoodBaseTrash, FoodOpenableBase] id: FoodTinBase name: tin description: A tin of something, sealed tight. components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 15 + - type: Solution + solution: + maxVol: 50 # about 400-450ml + reagents: + - ReagentId: Nutriment + Quantity: 40 + - ReagentId: Sugar + Quantity: 5 + - ReagentId: TableSalt + Quantity: 5 - type: Openable openableByHand: false sound: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/breakfast.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/breakfast.yml index c9b9cdcce1..49b8e9f937 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/breakfast.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/breakfast.yml @@ -12,15 +12,15 @@ size: Normal - type: Sprite sprite: Objects/Consumable/Food/breakfast.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 60 - reagents: - - ReagentId: Nutriment - Quantity: 40 - - ReagentId: Vitamin - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 45 + - ReagentId: Protein + Quantity: 15 + - ReagentId: Vitamin + Quantity: 15 # Breakfasts diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/burger.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/burger.yml index 30f307b6eb..25627fb085 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/burger.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/burger.yml @@ -11,13 +11,6 @@ sprite: Objects/Consumable/Food/burger.rsi layers: - state: bun - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 6.66 # 1/3 of a loaf of bread, technically losing 0.01 nutriment per batch of three buns over making bread loaves/slices - type: Butcherable butcherDelay: 1 spawned: @@ -51,14 +44,13 @@ nameGeneration: food-sequence-burger-gen - type: Appearance - type: FoodMetamorphableByAdding - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - canReact: false # Dont want cause reactions inside burgers after merging ingredients - reagents: - - ReagentId: Nutriment - Quantity: 3.3 # 1/2 of a bun + - type: Solution + solution: + maxVol: 7.5 + canReact: false # Dont want cause reactions inside burgers after merging ingredients, TODO Remove + reagents: + - ReagentId: Nutriment + Quantity: 5 # 1/2 of a bun - type: entity parent: FoodBreadSliceBase @@ -70,13 +62,13 @@ sprite: Objects/Consumable/Food/burger_sequence.rsi layers: - state: bun_top - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3.3 # 1/2 of a bun + - type: Solution + solution: + maxVol: 7.5 + canReact: false # Dont want cause reactions inside burgers after merging ingredients, TODO Remove + reagents: + - ReagentId: Nutriment + Quantity: 5 # 1/2 of a bun - type: FoodSequenceElement entries: Burger: BunTopBurger @@ -94,15 +86,15 @@ - meaty - type: Sprite sprite: Objects/Consumable/Food/burger.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 7 - - ReagentId: Vitamin - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 30 + - ReagentId: Protein + Quantity: 10 + - ReagentId: Vitamin + Quantity: 10 - type: Item sprite: Objects/Consumable/Food/burger.rsi shape: @@ -111,9 +103,9 @@ # Custom Burger Example - type: entity - name: jelly burger parent: FoodBurgerBase id: FoodBurgerJelly + name: jelly burger description: Culinary delight..? components: - type: FlavorProfile @@ -144,9 +136,9 @@ # Burger - type: entity - name: appendix burger parent: FoodBurgerBase id: FoodBurgerAppendix + name: appendix burger description: Tastes like appendicitis. components: - type: FlavorProfile @@ -155,17 +147,6 @@ - grass - type: Sprite state: appendix - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Protein - Quantity: 6 - - ReagentId: Vitamin - Quantity: 6 - type: Tag tags: - Meat @@ -186,9 +167,9 @@ # Tastes like bun, grass. - type: entity - name: bacon burger parent: FoodBurgerBase id: FoodBurgerBacon + name: bacon burger description: The perfect combination of all things American. components: - type: FlavorProfile @@ -197,15 +178,15 @@ - bacon - type: Sprite state: bacon - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Nutriment - Quantity: 19 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 35 + - ReagentId: Protein + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 - type: Tag tags: - Meat @@ -226,9 +207,9 @@ # Tastes like bun, bacon. - type: entity - name: baseball burger parent: FoodBurgerBase id: FoodBurgerBaseball + name: baseball burger description: It's still warm. The steam coming off of it smells kinda sweaty. components: - type: FlavorProfile @@ -237,17 +218,15 @@ - homerun - type: Sprite state: baseball - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Protein - Quantity: 5 - - ReagentId: Vitamin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Cellulose + Quantity: 30 + - ReagentId: Vitamin + Quantity: 5 - type: Tag tags: - Meat @@ -281,23 +260,12 @@ - meaty - type: Sprite state: bearger - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Protein - Quantity: 6 - - ReagentId: Vitamin - Quantity: 5 - type: Tag tags: - Meat - type: entity - parent: FoodBurgerBase + parent: [SolutionNormal, FoodBurgerBase] id: FoodBurgerBig name: big bite burger description: Forget the Big Mac. THIS is the future! @@ -305,7 +273,6 @@ - type: Item size: Normal shape: - - 0,0,1,1 storedOffset: 0,3 inhandVisuals: left: @@ -317,17 +284,17 @@ - meaty - oily - cheesy - - type: SolutionContainerManager - solutions: - food: - maxVol: 45 - reagents: - - ReagentId: Nutriment - Quantity: 18 - - ReagentId: Protein - Quantity: 18 - - ReagentId: Vitamin - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 75 + - ReagentId: Protein + Quantity: 20 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: Allicin + Quantity: 2 - type: Sprite state: bigbite - type: Tag @@ -354,17 +321,6 @@ - meaty - type: Sprite state: brain - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Protein - Quantity: 6 - - ReagentId: Vitamin - Quantity: 5 - type: Tag tags: - Meat @@ -392,25 +348,14 @@ - bun - meaty - cat - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Protein - Quantity: 3 - - ReagentId: Vitamin - Quantity: 2 - type: Tag tags: - Meat - type: entity - name: cheese burger parent: FoodBurgerBase id: FoodBurgerCheese + name: cheese burger description: This noble burger stands proudly clad in golden cheese. components: - type: FlavorProfile @@ -420,17 +365,13 @@ - cheesy - type: Sprite state: cheese - - type: SolutionContainerManager - solutions: - food: - maxVol: 26 - reagents: - - ReagentId: Nutriment - Quantity: 7 - - ReagentId: Vitamin - Quantity: 7 - - ReagentId: Protein - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 45 + - ReagentId: Protein + Quantity: 10 - type: Tag tags: - Meat @@ -451,9 +392,9 @@ # Tastes like bun, beef patty, cheese. - type: entity - name: chicken sandwich # Burger for you euro-cucks parent: FoodBurgerBase id: FoodBurgerChicken + name: chicken sandwich description: A delicious chicken sandwich, it is said the proceeds from this treat helps criminalize disarming people on the space frontier. components: - type: FlavorProfile @@ -462,19 +403,17 @@ - chicken - type: Sprite state: chicken - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 7 - - ReagentId: Vitamin - Quantity: 1 - - ReagentId: Mayo - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 30 + - ReagentId: Protein + Quantity: 10 + - ReagentId: Vitamin + Quantity: 10 + - ReagentId: Mayo + Quantity: 2 - type: Tag tags: - Meat @@ -513,25 +452,14 @@ - funny - type: Sprite state: clown - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: Protein - Quantity: 6 - - ReagentId: Vitamin - Quantity: 6 - type: Tag tags: - Meat - type: entity - name: corger #not curger parent: FoodBurgerBase id: FoodBurgerCorgi + name: corger #not curger description: The Head of Personnel's favorite! components: - type: FlavorProfile @@ -540,15 +468,15 @@ - validhunting - type: Sprite state: ian - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Bicaridine #keeping it somewhat consistent with the meat itself - Quantity: 7 - - ReagentId: Vitamin - Quantity: 12 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Bicaridine #keeping it somewhat consistent with the meat itself + Quantity: 20 + - ReagentId: Vitamin + Quantity: 10 - type: Tag tags: - Meat @@ -560,9 +488,9 @@ - state: dog-inhand-right - type: entity - name: crab burger parent: FoodBurgerBase id: FoodBurgerCrab + name: crab burger description: A delicious patty of the crabby kind, slapped in between a bun. components: - type: FlavorProfile @@ -571,17 +499,6 @@ - crabby - type: Sprite state: crab - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: Protein - Quantity: 5 - - ReagentId: Vitamin - Quantity: 4 - type: Tag tags: - Meat @@ -601,7 +518,7 @@ color: "#7e1a07" - type: entity - parent: FoodBurgerBase + parent: [SolutionNormal, FoodBurgerBase] id: FoodBurgerCrazy name: crazy hamburger # Burger for you euro-cucks description: This looks like the sort of food that a demented clown in a trenchcoat would make. @@ -609,7 +526,7 @@ - type: Item size: Normal shape: - - 0,0,1,1 + - 0,0,1,2 storedOffset: -2,0 inhandVisuals: left: @@ -624,21 +541,33 @@ - flare - type: Sprite state: crazy - - type: SolutionContainerManager - solutions: - food: - maxVol: 65 - reagents: - - ReagentId: Nutriment - Quantity: 31 - - ReagentId: Protein - Quantity: 15 - - ReagentId: CapsaicinOil - Quantity: 3 - - ReagentId: Vitamin - Quantity: 8 - - ReagentId: Sulfur # What you get for eating something with a flare in it - Quantity: 5 + - type: Solution + solution: + maxVol: 180 + reagents: + - ReagentId: Nutriment # Adds up to 180, completely filled to the brim. + Quantity: 100 + - ReagentId: Protein + Quantity: 20 + - ReagentId: CapsaicinOil + Quantity: 10 + - ReagentId: Vitamin + Quantity: 10 + - ReagentId: MindbreakerToxin + Quantity: 10 + # Taken from flare entity :) + - ReagentId: Iron + Quantity: 10 + - ReagentId: Phosphorus + Quantity: 6 + - ReagentId: Carbon + Quantity: 2 + - ReagentId: Oxygen + Quantity: 4 + - ReagentId: Charcoal + Quantity: 4 + - ReagentId: Sulfur + Quantity: 4 - type: Tag tags: - Meat @@ -670,15 +599,6 @@ - duck - type: Sprite state: chicken - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 15 - - ReagentId: Protein - Quantity: 5 - type: Tag tags: - Meat @@ -703,15 +623,15 @@ flavors: - bun - shocking - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Licoxide - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Plasma + Quantity: 20 + - ReagentId: Licoxide + Quantity: 10 # Tastes like bun, pure electricity. - type: entity @@ -747,7 +667,7 @@ # Tastes like bun, fish. - type: entity - parent: FoodBurgerBase + parent: [SolutionNormal, FoodBurgerBase] id: FoodBurgerFive name: five alarm burger description: HOT! HOT! HOT! @@ -755,7 +675,6 @@ - type: Item size: Normal shape: - - 0,0,1,1 storedOffset: 0,1 inhandVisuals: left: @@ -768,21 +687,19 @@ - spicy - type: Sprite state: fivealarm - - type: SolutionContainerManager - solutions: - food: - maxVol: 55 - reagents: - - ReagentId: Nutriment - Quantity: 25 - - ReagentId: Protein - Quantity: 5 - - ReagentId: CapsaicinOil - Quantity: 5 - - ReagentId: Blackpepper - Quantity: 5 - - ReagentId: Vitamin - Quantity: 12 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 45 + - ReagentId: Protein + Quantity: 10 + - ReagentId: CapsaicinOil + Quantity: 30 + - ReagentId: Blackpepper + Quantity: 3 + - ReagentId: Vitamin + Quantity: 12 - type: Tag tags: - Meat @@ -796,9 +713,8 @@ description: Too spooky! components: - type: Item - size: Normal + size: Normal # Just annoying to store not actually that big :) shape: - - 0,0,1,1 storedOffset: 0,3 inhandVisuals: left: @@ -821,15 +737,15 @@ - spooky - type: Sprite state: ghost - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 7 - - ReagentId: Vitamin - Quantity: 12 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Vitamin + Quantity: 10 + - ReagentId: Fresium + Quantity: 15 - type: Tag tags: - ClothMade @@ -848,17 +764,6 @@ - people - type: Sprite state: human - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 6 - - ReagentId: Vitamin - Quantity: 5 - type: Tag tags: - Meat @@ -896,23 +801,23 @@ - egg - type: Sprite state: mcguffin - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 8 - - ReagentId: Vitamin - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 25 + - ReagentId: EggCooked + Quantity: 6 + - ReagentId: Protein + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 - type: Tag tags: - Meat - type: entity - parent: FoodBurgerBase + parent: [SolutionNormal, FoodBurgerBase] id: FoodBurgerMcrib name: BBQ Rib Sandwich description: An elusive rib shaped burger with limited availability across the galaxy. Not as good as you remember it. @@ -926,23 +831,25 @@ - bacon - type: Sprite state: mcrib - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Nutriment - Quantity: 11 - - ReagentId: Protein - Quantity: 10 - - ReagentId: Vitamin - Quantity: 4 - - ReagentId: BbqSauce - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 70 + - ReagentId: Protein + Quantity: 30 + - ReagentId: BbqSauce + Quantity: 10 + - ReagentId: Allicin + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 - type: Tag tags: - Meat - type: Item + size: Normal + shape: inhandVisuals: left: - state: bun-inhand-left @@ -970,19 +877,15 @@ - nothing - type: Sprite state: mime - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Protein - Quantity: 9 - - ReagentId: Vitamin - Quantity: 4 - - ReagentId: Nothing - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: Nothing + Quantity: 30 - type: Item inhandVisuals: left: @@ -1003,17 +906,6 @@ - meaty - type: Sprite state: plain - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Protein - Quantity: 6 - - ReagentId: Vitamin - Quantity: 3 - type: Tag tags: - Meat @@ -1036,17 +928,17 @@ - meaty - type: Sprite state: rat - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Protein - Quantity: 6 - - ReagentId: Vitamin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 15 + - ReagentId: Protein + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: Fat + Quantity: 1 - type: Tag tags: - Meat @@ -1074,15 +966,23 @@ - metallic - type: Sprite state: ro - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: SulfuricAcid - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 15 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: SulfuricAcid + Quantity: 5 + - ReagentId: Oil + Quantity: 5 + - ReagentId: Phosphorus + Quantity: 5 + - ReagentId: Iron + Quantity: 9 + - ReagentId: Carbon + Quantity: 1 - type: Tag tags: - Meat @@ -1131,15 +1031,15 @@ - soy - type: Sprite state: soylent - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 13 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 37 + - ReagentId: Protein + Quantity: 8 + - ReagentId: Vitamin + Quantity: 5 # Tastes like bun, redditors. - type: entity @@ -1164,17 +1064,6 @@ - magical - type: Sprite state: spell - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: Protein - Quantity: 5 - - ReagentId: Vitamin - Quantity: 10 # Tastes like bun, silver. - type: entity @@ -1186,7 +1075,6 @@ - type: Item size: Normal shape: - - 0,0,1,1 storedOffset: 0,4 inhandVisuals: left: @@ -1198,19 +1086,19 @@ - meaty - oily - cheesy - - type: SolutionContainerManager - solutions: - food: - maxVol: 90 - reagents: - - ReagentId: Nutriment - Quantity: 44 - - ReagentId: Vitamin - Quantity: 24 - - ReagentId: TableSalt - Quantity: 5 - - ReagentId: Blackpepper - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 79 + - ReagentId: Protein + Quantity: 20 + - ReagentId: Vitamin + Quantity: 11 + - ReagentId: TableSalt + Quantity: 5 + - ReagentId: Blackpepper + Quantity: 5 - type: Sprite state: superbite - type: Tag @@ -1230,15 +1118,15 @@ - tofu - type: Sprite state: tofu - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Protein - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 16 + - ReagentId: Protein + Quantity: 9 + - ReagentId: Vitamin + Quantity: 5 - type: Item inhandVisuals: left: @@ -1268,17 +1156,6 @@ - acid - type: Sprite state: x - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Protein - Quantity: 6 - - ReagentId: Vitamin - Quantity: 5 - type: Tag tags: - Meat @@ -1322,17 +1199,6 @@ - light - type: Sprite state: mothroach - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Protein - Quantity: 4 - - ReagentId: Vitamin - Quantity: 7 - type: Tag tags: - Meat diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/cottonburger.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/cottonburger.yml index af417c2d11..1a2162f250 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/cottonburger.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/cottonburger.yml @@ -12,15 +12,13 @@ sprite: Objects/Consumable/Food/cottonburger.rsi layers: - state: cottonbun - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 3.33 - - ReagentId: Fiber - Quantity: 3.33 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Fiber + Quantity: 5 - type: Butcherable butcherDelay: 1 spawned: @@ -62,16 +60,14 @@ nameGeneration: food-sequence-cotton-burger-gen - type: Appearance - type: FoodMetamorphableByAdding - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - canReact: false # Dont want cause reactions inside burgers after merging ingredients - reagents: - - ReagentId: Nutriment - Quantity: 1.665 - - ReagentId: Fiber - Quantity: 1.665 + - type: Solution + solution: + maxVol: 7.5 + reagents: + - ReagentId: Nutriment + Quantity: 2.5 + - ReagentId: Fiber + Quantity: 2.5 - type: Tag tags: - ClothMade @@ -90,15 +86,14 @@ sprite: Objects/Consumable/Food/cottonburger.rsi layers: - state: cottonbun_top - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 1.665 - - ReagentId: Fiber - Quantity: 1.665 + - type: Solution + solution: + maxVol: 7.5 + reagents: + - ReagentId: Nutriment + Quantity: 2.5 + - ReagentId: Fiber + Quantity: 2.5 - type: FoodSequenceElement entries: CottonBurger: CottonBunTopBurger diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml index 80e7123abe..ca6c7ca508 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml @@ -1,7 +1,7 @@ # Base - type: entity - parent: [FoodInjectableBase, ItemHeftyBase] + parent: [SolutionVeryTiny, FoodInjectableBase, ItemHeftyBase] id: FoodEggBase description: An egg! abstract: true @@ -18,13 +18,11 @@ - type: Item sprite: Objects/Consumable/Food/egg.rsi size: Tiny - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: Egg - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: Egg + Quantity: 6 # About 50ml which is the expected size of an egg - type: DrawableSolution solution: food - type: SolutionSpiker @@ -83,13 +81,6 @@ state: eggshells - type: Item size: Tiny - - type: SolutionContainerManager - solutions: - food: - maxVol: 2 - reagents: - - ReagentId: Egg - Quantity: 1 - type: Tag tags: - Egg @@ -126,13 +117,11 @@ layers: - state: icon map: [ "enum.DamageStateVisualLayers.Base" ] - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: EggCooked - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: EggCooked + Quantity: 6 - type: Temperature # preserve temperature from the boiling step currentTemperature: 344 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/food_base.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/food_base.yml index 6ba1895548..3a9540bc80 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/food_base.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/food_base.yml @@ -1,10 +1,10 @@ # -# Base component for edible food-like items +# Base component for edible food-like items, different from BaseDrink # - type: entity abstract: true - parent: BaseItem - id: EdibleBase + parent: [BaseItem, SolutionFood, SolutionSmall] + id: FoodBase components: - type: FlavorProfile flavors: @@ -20,8 +20,8 @@ # - type: entity abstract: true - parent: EdibleBase - id: FoodBase + parent: FoodBase + id: FoodBaseTrash components: - type: SpaceGarbage @@ -31,7 +31,7 @@ - type: entity abstract: true - parent: FoodBase + parent: FoodBaseTrash id: FoodInjectableBase components: - type: InjectableSolution diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/frozen.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/frozen.yml index cc343d900b..f111364226 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/frozen.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/frozen.yml @@ -2,19 +2,17 @@ # Base - type: entity - parent: FoodInjectableBase + parent: [SolutionVeryTiny, FoodInjectableBase] id: FoodFrozenBase abstract: true components: - type: Sprite sprite: Objects/Consumable/Food/frozen.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 # For sprinkles or something? Idk. - reagents: - - ReagentId: Nutriment - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 # Ice-cream @@ -70,15 +68,13 @@ storedRotation: -45 - type: Sprite state: cornuto - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Theobromine - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Theobromine + Quantity: 1 # Popsicle @@ -135,15 +131,13 @@ - type: Edible trash: - FoodFrozenPopsicleTrash - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Theobromine - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Theobromine + Quantity: 1 # Snowcone @@ -166,17 +160,15 @@ - type: Edible trash: - FoodFrozenSnowconeTrash - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 # For sprinkles or something? Idk. - reagents: - - ReagentId: Ice - Quantity: 8 - - ReagentId: Water - Quantity: 2 - - ReagentId: Sugar - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Ice + Quantity: 8 + - ReagentId: Water + Quantity: 2 + - ReagentId: Sugar + Quantity: 2 - type: entity name: flavorless snowcone @@ -184,13 +176,11 @@ id: FoodFrozenSnowcone description: It's just shaved ice. Still fun to chew on. components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Ice - Quantity: 8 + - type: Solution + solution: + reagents: + - ReagentId: Ice + Quantity: 8 - type: entity name: berry snowcone diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml index 9b3f0520a3..f7e39cb684 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml @@ -7,15 +7,11 @@ - type: entity abstract: true - parent: BaseItem - id: ReagentContainerBase + parent: [SolutionFood, SolutionSmall, BaseItem] + id: ReagentContainerBase # Despite the name its basically only used for ingredients components: - type: Sprite sprite: Objects/Consumable/Food/ingredients.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 - type: SolutionTransfer # This is potentially badly-handled due to 'drink opening', # but it lets the flour be tampered with, refilled, etc. @@ -29,6 +25,7 @@ edible: Food # usually contains powders like flour or condiments like ketchup solution: food utensil: Spoon + destroyOnEmpty: false - type: Damageable - type: Injurable damageContainer: Inorganic @@ -36,6 +33,7 @@ solution: food - type: TrashOnSolutionEmpty solution: food + - type: entity abstract: true parent: ReagentContainerBase @@ -66,6 +64,22 @@ types: Blunt: 0 +- type: entity + abstract: true + parent: [SolutionNormal, ReagentPacketBase] + id: ReagentPacket + components: + - type: Item + size: Normal + +- type: entity + abstract: true + parent: [SolutionSmall, ReagentPacketBase] + id: ReagentPacketSmall + components: + - type: Item + size: Small + - type: entity abstract: true id: ItemHeftyBase @@ -80,7 +94,7 @@ Blunt: 1 - type: entity - parent: [ReagentPacketBase, ItemHeftyBase] + parent: [ReagentPacket, ItemHeftyBase] id: ReagentContainerFlour name: flour bag description: A big bag of flour. Good for baking! @@ -96,32 +110,28 @@ layers: - state: flour-big map: ["enum.OpenableVisuals.Layer"] - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 - reagents: - - ReagentId: Flour - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Flour + Quantity: 120 # About a pound of flour - type: entity - parent: [ReagentPacketBase, ItemHeftyBase] + parent: [ReagentPacketSmall, ItemHeftyBase] id: ReagentContainerFlourSmall name: flour pack description: A pack of flour. Good for baking! components: - type: Sprite state: flour-small - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Flour - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Flour + Quantity: 60 - type: entity - parent: ReagentPacketBase + parent: [ReagentPacket, ItemHeftyBase] id: ReagentContainerCornmeal name: cornmeal bag description: A big bag of cornmeal. Good for cooking! @@ -137,31 +147,28 @@ layers: - state: cornmeal-big map: ["enum.OpenableVisuals.Layer"] - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Cornmeal - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Cornmeal + Quantity: 120 - type: entity - parent: ReagentPacketBase + parent: [ReagentPacketSmall, ItemHeftyBase] id: ReagentContainerCornmealSmall name: cornmeal pack description: A pack of cornmeal. Good for cooking! components: - type: Sprite state: cornmeal - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Cornmeal - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Cornmeal + Quantity: 60 - type: entity - parent: ReagentPacketBase + parent: [ReagentPacket, ItemHeftyBase] id: ReagentContainerRice name: rice bag description: A big bag of rice. Good for cooking! @@ -177,31 +184,28 @@ layers: - state: rice-big map: ["enum.OpenableVisuals.Layer"] - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Rice - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Rice + Quantity: 120 - type: entity - parent: ReagentPacketBase + parent: [ReagentPacketSmall, ItemHeftyBase] id: ReagentContainerRiceSmall name: rice pack description: A pack of rice. Good for cooking! components: - type: Sprite state: rice-small - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Rice - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Rice + Quantity: 60 - type: entity - parent: ReagentPacketBase + parent: [ReagentPacket, ItemHeftyBase] id: ReagentContainerSugar name: sugar bag description: A big bag of tasty spacey sugar. @@ -217,33 +221,30 @@ layers: - state: sugar-big map: ["enum.OpenableVisuals.Layer"] - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Sugar - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Sugar + Quantity: 120 - type: entity - parent: ReagentPacketBase + parent: [ReagentPacketSmall, ItemHeftyBase] id: ReagentContainerSugarSmall name: sugar pack description: A pack of tasty spacey sugar. components: - type: Sprite state: sugar-small - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Sugar - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Sugar + Quantity: 60 # Misc - type: entity - parent: ReagentPacketBase + parent: ReagentPacketBase # TODO Move to condiments.yml and parent off of BaseFoodCondimentBottle id: ReagentContainerOliveoil name: olive oil description: Olive oil. From space olives presumably. @@ -259,18 +260,17 @@ layers: - state: oliveoil map: ["enum.OpenableVisuals.Layer"] - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: OilOlive - Quantity: 20 + - type: Solution + solution: + maxVol: 50 + reagents: + - ReagentId: OilOlive + Quantity: 50 - type: Edible edible: Drink # slurping sounds! - type: entity - parent: ReagentPacketBase + parent: ReagentPacketBase # TODO Move to condiments.yml and parent off of BaseFoodCondimentBottle id: ReagentContainerMayo name: mayonnaise description: Bottle of mayonnaise. @@ -286,222 +286,186 @@ layers: - state: mayo map: ["enum.OpenableVisuals.Layer"] - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 # you always need more mayo - reagents: - - ReagentId: Mayo - Quantity: 50 + - type: Solution + solution: + maxVol: 50 + reagents: + - ReagentId: Mayo + Quantity: 50 - type: Tag tags: - Mayo -# - type: entity -# parent: ReagentPacketBase -# id: ReagentContainerAllspice -# name: all-spice -# description: -# components: -# - type: Sprite -# state: spice -# - type: SolutionContainerManager -# maxVol: 10 -# contents: -# reagents: -# - ReagentId: Allspice -# Quantity: 10 - # Baking - type: entity abstract: true - parent: FoodBase + parent: FoodBaseTrash id: FoodBakingBase description: Used in various recipes. components: - type: Sprite sprite: Objects/Consumable/Food/ingredients.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 18 - reagents: - - ReagentId: Nutriment - Quantity: 15 + +# TODO Replace all nutriment in dough with something that is less metabolically efficient - type: entity - parent: FoodBakingBase - id: FoodDough - name: dough - description: A piece of dough. + abstract: true + parent: [SolutionNormal, FoodBakingBase] + id: FoodDoughBase components: - type: Item size: Normal - type: FlavorProfile flavors: - - dough + - chalky + - dough + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 60 + +- type: entity + abstract: true + parent: [SolutionVeryTiny, FoodBakingBase] + id: FoodDoughSliceBase + components: + - type: Item + size: Tiny + - type: FlavorProfile + flavors: + - chalky + - dough + - type: Sprite + state: dough-slice + - type: Tag + tags: + - Slice + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 7.5 + +- type: entity + abstract: true + parent: FoodDoughSliceBase + id: FoodDoughRopeBase + components: + - type: Item + size: Small + storedRotation: -45 + - type: Tag + tags: [] + +- type: entity + parent: FoodDoughBase + id: FoodDough + name: dough + description: A piece of dough. + components: - type: Sprite state: dough - type: SliceableFood - count: 3 + count: 8 slice: FoodDoughSlice - type: Construction graph: Pizza node: start - type: entity - parent: FoodBakingBase + parent: FoodDoughSliceBase id: FoodDoughSlice name: dough slice description: A slice of dough. Can be cooked into a bun. components: - - type: Item - size: Tiny - - type: FlavorProfile - flavors: - - dough - type: Sprite state: dough-slice - - type: Tag - tags: - - Slice - type: Construction graph: DoughRope node: start - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: Nutriment - Quantity: 5 - type: entity - parent: FoodBakingBase + parent: FoodDoughRopeBase id: FoodDoughRope name: dough rope description: A thin noodle of dough. Can be cooked into a bagel. components: - - type: Item - storedRotation: -45 - - type: FlavorProfile - flavors: - - dough - type: Sprite state: dough-rope - type: Construction graph: DoughRope node: rolled - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: Nutriment - Quantity: 5 - type: entity - parent: FoodBakingBase + parent: FoodDoughBase id: FoodDoughCornmeal name: cornmeal dough description: A piece of cornmeal dough. components: - - type: Item - size: Normal - - type: FlavorProfile - flavors: - - chalky - - dough - type: Sprite state: cornmealdough - type: SliceableFood - count: 3 + count: 8 slice: FoodDoughCornmealSlice - type: entity - parent: FoodBakingBase + parent: FoodDoughSliceBase id: FoodDoughCornmealSlice name: cornmeal dough slice description: A slice of cornmeal dough. components: - - type: Item - size: Tiny - - type: FlavorProfile - flavors: - - chalky - - dough - type: Sprite state: cornmealdough-slice - - type: Tag - tags: - - Slice - type: entity - parent: FoodBakingBase + parent: FoodDoughBase id: FoodDoughTortilla name: tortilla dough description: A piece of tortilla dough. components: - - type: Item - size: Normal - - type: FlavorProfile - flavors: - - chalky - - dough - type: Sprite state: tortilladough - type: SliceableFood - count: 3 + count: 8 slice: FoodDoughTortillaSlice - type: entity - parent: FoodBakingBase + parent: FoodDoughSliceBase id: FoodDoughTortillaSlice name: tortilla dough slice description: A slice of tortilla dough. components: - - type: Item - size: Tiny - - type: FlavorProfile - flavors: - - chalky - - dough - type: Sprite state: tortilladough-slice - type: Construction graph: Tortilla node: start - - type: Tag - tags: - - Slice - type: entity - parent: FoodBakingBase + parent: [SolutionVeryTiny, FoodDoughBase] id: FoodDoughTortillaFlat name: flattened tortilla dough description: A flattened slice of tortilla dough, cook this to get a taco shell. components: - - type: Item - size: Tiny - - type: FlavorProfile - flavors: - - chalky - - dough - type: Sprite state: tortilladough-flat - type: Construction graph: Tortilla node: flat + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 7.5 - type: entity - parent: FoodBakingBase + parent: FoodDoughBase id: FoodDoughCotton name: cotton dough description: A piece of fabric dough. components: - - type: Item - size: Normal - type: FlavorProfile flavors: - dough @@ -509,7 +473,7 @@ - type: Sprite state: cotton-dough - type: SliceableFood - count: 3 + count: 8 slice: FoodDoughCottonSlice - type: Construction graph: CottonPizza @@ -517,24 +481,20 @@ - type: Tag tags: - ClothMade - - type: SolutionContainerManager - solutions: - food: - maxVol: 18 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Fiber - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Fiber + Quantity: 40 - type: entity - parent: FoodBakingBase + parent: FoodDoughSliceBase id: FoodDoughCottonSlice name: cotton dough slice description: A slice of cotton dough. components: - - type: Item - size: Tiny - type: FlavorProfile flavors: - dough @@ -548,24 +508,20 @@ - type: Construction graph: DoughRopeCotton node: start - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: Nutriment - Quantity: 1.5 - - ReagentId: Fiber - Quantity: 3.5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 2.5 + - ReagentId: Fiber + Quantity: 5 - type: entity - parent: FoodBakingBase + parent: FoodDoughRopeBase id: FoodDoughCottonRope name: cotton dough rope description: A thin noodle of cotton dough. Can be cooked into a cotton bagel. components: - - type: Item - storedRotation: -45 - type: FlavorProfile flavors: - dough @@ -575,15 +531,13 @@ - type: Construction graph: DoughRopeCotton node: rolled - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: Nutriment - Quantity: 1.5 - - ReagentId: Fiber - Quantity: 3.5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 2.5 + - ReagentId: Fiber + Quantity: 5 - type: Tag tags: - ClothMade @@ -591,7 +545,7 @@ - type: entity name: raw pastry base parent: FoodBakingBase - id: FoodDoughPastryBaseRaw + id: FoodDoughPastryBaseRaw # Unused description: Must be cooked before use. components: - type: Sprite @@ -600,31 +554,28 @@ - type: entity name: pastry base parent: FoodBakingBase - id: FoodDoughPastryBase + id: FoodDoughPastryBase # Unused description: A base for any self-respecting pastry. components: - type: Sprite state: dough-pastry-baked - type: entity - parent: FoodBakingBase + parent: FoodDoughBase id: FoodDoughPie name: pie dough description: Cook it to get a pie. components: - - type: Item - size: Normal - type: Sprite state: dough-pie - type: entity - parent: FoodBakingBase + parent: FoodDough id: FoodDoughFlat name: flat dough description: A flattened dough. components: - type: Item - size: Normal shape: - 0,0,2,1 - type: Sprite @@ -633,17 +584,16 @@ graph: Pizza node: flat - type: SliceableFood - count: 3 + count: 4 slice: FoodCroissantRaw - type: entity - parent: FoodBakingBase + parent: FoodDoughCotton id: FoodDoughCottonFlat name: flat cotton dough description: A flattened cotton dough. components: - type: Item - size: Normal shape: - 0,0,2,1 - type: Sprite @@ -652,15 +602,18 @@ graph: CottonPizza node: flat - type: SliceableFood - count: 3 + count: 4 slice: FoodCroissantRawCotton - type: entity - parent: FoodBakingBase + parent: FoodDough id: FoodDoughPizzaBaked name: pizza bread description: Add ingredients to make a pizza. components: + - type: FlavorProfile + flavors: + - bread - type: Item size: Normal shape: @@ -669,13 +622,11 @@ state: pizzabread - type: entity - parent: FoodBakingBase + parent: FoodDoughBase id: FoodCakeBatter name: cake batter description: Cook it to get a cake. components: - - type: Item - size: Normal - type: FlavorProfile flavors: - sweetdough @@ -683,7 +634,7 @@ state: cakebatter - type: entity - parent: FoodBakingBase + parent: [SolutionSmall, FoodBakingBase] id: FoodButter name: stick of butter description: A stick of delicious, golden, fatty goodness. @@ -716,19 +667,17 @@ density: 10 mask: - ItemMask - - type: SolutionContainerManager - solutions: - food: - maxVol: 18 - reagents: - - ReagentId: Butter - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Butter + Quantity: 30 - type: SliceableFood - count: 3 + count: 12 slice: FoodButterSlice - type: entity - parent: FoodBakingBase + parent: [SolutionVeryTiny, FoodBakingBase] id: FoodButterSlice name: butter slice description: A pat of delicious, golden, fatty goodness. @@ -737,13 +686,12 @@ size: Tiny - type: Sprite state: butter-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: Butter - Quantity: 5 + - type: Solution + solution: + maxVol: 5 + reagents: + - ReagentId: Butter + Quantity: 2.5 - type: Tag tags: - Slice @@ -757,21 +705,19 @@ - type: Sprite state: butter color: "#82C36E" - - type: SolutionContainerManager - solutions: - food: - maxVol: 100 - reagents: - - ReagentId: Butter - Quantity: 10 - - ReagentId: THC - Quantity: 82 + - type: Solution + solution: + reagents: + - ReagentId: Butter + Quantity: 30 + - ReagentId: THC + Quantity: 15 - type: Extractable grindableSolutionName: food - type: entity name: cheese wheel - parent: FoodBakingBase + parent: [SolutionNormal, FoodBakingBase] id: FoodCheese description: A big wheel of delicious Cheddar. components: @@ -785,9 +731,14 @@ - type: SliceableFood count: 4 slice: FoodCheeseSlice + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 60 - type: entity - parent: FoodBakingBase + parent: [SolutionTiny, FoodBakingBase] id: FoodCheeseSlice name: cheese wedge description: A wedge of delicious Cheddar. The cheese wheel it was cut from can't have gone far. @@ -797,13 +748,11 @@ - cheesy - type: Sprite state: cheesewedge - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: Nutriment - Quantity: 3.75 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 15 - type: Tag tags: - Slice @@ -821,7 +770,7 @@ - state: cheesewedge-inhand-right - type: entity - parent: FoodBakingBase + parent: [SolutionSmall, FoodBakingBase] id: FoodChevre name: chèvre log description: A soft log of creamy Chèvre. @@ -837,20 +786,18 @@ - type: Sprite state: chevrelog - type: SliceableFood - count: 3 + count: 6 slice: FoodChevreSlice - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 0.6 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 24 + - ReagentId: Vitamin + Quantity: 6 - type: entity - parent: FoodBakingBase + parent: [SolutionTiny, FoodBakingBase] id: FoodChevreSlice name: chèvre disk description: A small disk of creamy Chèvre. An ideal adornment for French side dishes. @@ -863,21 +810,20 @@ - creamy - type: Sprite state: chevredisk - - type: SolutionContainerManager - solutions: - food: - maxVol: 2 - reagents: - - ReagentId: Nutriment - Quantity: 1 - - ReagentId: Vitamin - Quantity: 0.2 + - type: Solution + solution: + maxVol: 10 + reagents: + - ReagentId: Nutriment + Quantity: 4 + - ReagentId: Vitamin + Quantity: 1 - type: Tag tags: - Slice - type: entity - parent: FoodBakingBase + parent: [SolutionNormal, FoodBakingBase] id: FoodTofu name: tofu description: Solid white block with a subtle flavor. @@ -889,21 +835,19 @@ - tofu - type: Sprite state: tofu - - type: SolutionContainerManager - solutions: - food: - maxVol: 18 - reagents: - - ReagentId: Protein - Quantity: 9 - - ReagentId: Nutriment - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: Protein + Quantity: 45 + - ReagentId: Nutriment + Quantity: 30 - type: SliceableFood - count: 3 + count: 5 slice: FoodTofuSlice - type: entity - parent: FoodBakingBase + parent: [SolutionTiny, FoodBakingBase] id: FoodTofuSlice name: tofu slice description: A slice of tofu. Ingredient of various vegetarian dishes. @@ -915,22 +859,20 @@ - tofu - type: Sprite state: tofu-slice - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: Protein - Quantity: 3 - - ReagentId: Nutriment - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Protein + Quantity: 9 + - ReagentId: Nutriment + Quantity: 6 - type: Tag tags: - Slice - type: entity name: burned mess - parent: FoodBakingBase + parent: [SolutionSmall, FoodBakingBase] id: FoodBadRecipe description: Someone should be demoted from cook for this. components: @@ -939,15 +881,15 @@ - terrible - type: Sprite state: badrecipe - - type: SolutionContainerManager - solutions: - food: - maxVol: 8 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: GastroToxin - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: GastroToxin + Quantity: 15 + - ReagentId: Carbon + Quantity: 10 - type: Tag tags: - Trash @@ -958,31 +900,31 @@ id: FoodCocoaBeans description: You can never have too much chocolate! components: + - type: Item + size: Tiny - type: FlavorProfile flavors: - chocolate - type: Sprite sprite: Objects/Specific/Hydroponics/cocoa.rsi state: produce-beans - - type: SolutionContainerManager - solutions: - food: - maxVol: 14 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Vitamin - Quantity: 1 - - ReagentId: CocoaPowder - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 6 + - ReagentId: Vitamin + Quantity: 3 + - ReagentId: CocoaPowder + Quantity: 6 - type: Extractable juiceSolution: reagents: - ReagentId: CocoaPowder - Quantity: 2 + Quantity: 10 - type: entity - parent: FoodBakingBase + parent: [SolutionSmall, FoodBakingBase] id: FoodCroissantRaw name: raw croissant description: Buttery, flaky goodness waiting to happen. @@ -997,13 +939,11 @@ - dough - type: Sprite state: croissant-raw - - type: SolutionContainerManager - solutions: - food: - maxVol: 4 - reagents: - - ReagentId: Nutriment - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 15 - type: entity parent: FoodCroissantRaw @@ -1022,3 +962,10 @@ - cotton - type: Sprite state: croissant-raw-cotton + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Fiber + Quantity: 10 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/meals.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/meals.yml index 4561464d18..8889e2b3a0 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/meals.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/meals.yml @@ -15,13 +15,11 @@ - 0,0,1,0 - type: Sprite sprite: Objects/Consumable/Food/meals.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 26 - reagents: - - ReagentId: Nutriment - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 40 # Bonus for complete meal # Meals @@ -91,13 +89,13 @@ - type: Tag tags: - CarrotFries - - type: SolutionContainerManager - solutions: - food: - maxVol: 26 - reagents: - - ReagentId: JuiceCarrot - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: JuiceCarrot + Quantity: 20 + - ReagentId: Nutriment + Quantity: 20 # Tastes like carrots, salt. - type: entity @@ -116,15 +114,13 @@ - nachos - type: Sprite state: nachos - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 15 - - ReagentId: TableSalt - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: TableSalt + Quantity: 2 # Tastes like nachos. - type: entity @@ -144,15 +140,13 @@ - cheesy - type: Sprite state: nachos-cheesy - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 20 - - ReagentId: TableSalt - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 25 + - ReagentId: TableSalt + Quantity: 2 # Tastes like nachos, cheese. - type: entity @@ -173,17 +167,15 @@ - spicy - type: Sprite state: nachos-cuban - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 25 - - ReagentId: CapsaicinOil - Quantity: 7 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 15 + - ReagentId: CapsaicinOil + Quantity: 10 + - ReagentId: Vitamin + Quantity: 5 # Tastes like nachos, hot pepper. - type: entity @@ -192,6 +184,9 @@ name: mint description: It's wafer thin. components: + - type: Edible + trash: + - FoodPlateSmall - type: Item storedOffset: 0,-1 - type: FlavorProfile @@ -199,14 +194,13 @@ - minty - type: Sprite state: mint - - type: SolutionContainerManager - solutions: - food: - # Note that this acts as the limiter against injecting anything. - maxVol: 1 - reagents: - - ReagentId: Nutriment - Quantity: 1 + - type: Solution + solution: + # Note that this acts as the limiter against injecting anything. + maxVol: 2 + reagents: + - ReagentId: Nutriment + Quantity: 1 # Tastes like parsnips, salt. - type: entity @@ -223,15 +217,6 @@ - cheesy - type: Sprite state: eggplantparm - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 2 - type: Tag tags: - Fruit @@ -254,12 +239,14 @@ # Tastes like sweet potato. - type: entity - parent: FoodMealBase + parent: [SolutionNormal, FoodMealBase] id: FoodMealCubancarp name: Cuban carp description: A grifftastic sandwich that burns your tongue and then leaves it numb! components: - type: Item + size: Normal + shape: storedOffset: 3,-7 - type: FlavorProfile flavors: @@ -268,19 +255,17 @@ - spicy - type: Sprite state: cubancarp - - type: SolutionContainerManager - solutions: - food: - maxVol: 55 - reagents: - - ReagentId: Nutriment - Quantity: 40 - - ReagentId: CarpoToxin - Quantity: 3 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: CapsaicinOil - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 100 + - ReagentId: CarpoToxin + Quantity: 5 + - ReagentId: CapsaicinOil + Quantity: 10 + - ReagentId: Vitamin + Quantity: 5 - type: Tag tags: - CubanCarp @@ -301,22 +286,13 @@ - cabbage - type: Sprite state: cornedbeef - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 4 - type: Tag tags: - Meat # Tastes like meat, cabbage. - type: entity - parent: FoodMealBase + parent: [SolutionNormal, FoodMealBase] id: FoodMealBearsteak name: filet migrawr description: Because eating bear wasn't manly enough. @@ -324,7 +300,6 @@ - type: Item size: Normal shape: - - 0,0,1,1 storedOffset: -1,4 - type: FlavorProfile flavors: @@ -332,22 +307,13 @@ - fishy - type: Sprite state: bearsteak - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Vitamin - Quantity: 5 - type: Tag tags: - Meat # Tastes like meat, salmon. - type: entity - parent: FoodMealBase + parent: [SolutionTiny, FoodMealBase] id: FoodMealPigblanket name: pig in a blanket description: A tiny sausage wrapped in a flakey, buttery roll. Free this pig from its blanket prison by eating it. @@ -355,34 +321,26 @@ - type: Item size: Tiny shape: - - 0,0,0,0 - type: FlavorProfile flavors: - meaty - butter - type: Sprite state: pigblanket - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 1 - type: Tag tags: - Meat # Tastes like meat, butter. - type: entity - parent: FoodMealBase + parent: [SolutionNormal, FoodMealBase] id: FoodMealRibs name: bbq ribs description: BBQ ribs, slathered in a healthy coating of BBQ sauce. The least vegan thing to ever exist. components: - type: Item + size: Normal + shape: storedOffset: 0,-4 - type: Edible trash: @@ -393,17 +351,15 @@ - smokey - type: Sprite state: ribs - - type: SolutionContainerManager - solutions: - food: - maxVol: 35 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Protein - Quantity: 20 - - ReagentId: BbqSauce - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 60 + - ReagentId: Protein + Quantity: 30 + - ReagentId: BbqSauce + Quantity: 10 - type: Tag tags: - Meat @@ -422,15 +378,6 @@ - bun - type: Sprite state: benedict - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 4 - type: Tag tags: - Meat @@ -450,13 +397,6 @@ - cheesy - type: Sprite state: omelette - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 9 - type: Tag tags: - Meat @@ -477,24 +417,13 @@ - peppery - type: Sprite state: friedegg - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: TableSalt - Quantity: 1 - - ReagentId: Blackpepper - Quantity: 1 - type: Tag tags: - Meat # Tastes like egg, salt, pepper. - type: entity - parent: FoodMealBase + parent: [SolutionNormal, FoodMealBase] id: FoodMealMilkape name: milk ape description: The king of Jungle Thick. @@ -502,7 +431,6 @@ - type: Item size: Normal shape: - - 0,0,1,1 - type: FlavorProfile flavors: - milk @@ -525,19 +453,10 @@ - memoryleek - type: Sprite state: memoryLeek - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Allicin - Quantity: 5 # Tastes like pain. - type: entity - parent: FoodMealBase + parent: [SolutionNormal, FoodMealBase] id: DisgustingSweptSoup name: salty sweet miso cola soup description: Jesus christ. @@ -545,21 +464,9 @@ - type: Item size: Normal shape: - - 0,0,1,1 storedOffset: 0,-2 - type: Sprite state: saltysweet - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 9 - - ReagentId: Water - Quantity: 10 - - ReagentId: Blackpepper - Quantity: 3 # Tastes awesome. - type: entity @@ -588,15 +495,15 @@ - fishy - type: Sprite state: sashimi - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: CarpoToxin - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 30 + - ReagentId: CarpoToxin + Quantity: 5 + - ReagentId: TableSalt + Quantity: 1 - type: Tag tags: - Meat @@ -615,31 +522,31 @@ - meaty - type: Sprite state: enchiladas - - type: SolutionContainerManager - solutions: - food: - maxVol: 35 - reagents: - - ReagentId: Nutriment - Quantity: 20 - - ReagentId: Protein - Quantity: 5 - - ReagentId: CapsaicinOil - Quantity: 6 - - ReagentId: Vitamin - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 25 + - ReagentId: Protein + Quantity: 5 + - ReagentId: CapsaicinOil + Quantity: 10 + - ReagentId: Vitamin + Quantity: 5 - type: Tag tags: - Meat # What do Europeans eat instead of enchiladas? 25.4 millimeter-iladas. - type: entity - parent: FoodMealBase + parent: [SolutionNormal, FoodMealBase] id: FoodSaladWatermelonFruitBowl name: melon fruit bowl description: The only salad where you can eat the bowl. components: - type: Item + size: Normal + shape: storedOffset: 0,-3 - type: FlavorProfile flavors: @@ -647,21 +554,19 @@ - sour - type: Sprite state: melonfruitbowl - - type: SolutionContainerManager - solutions: - food: - maxVol: 65 - reagents: - - ReagentId: Nutriment - Quantity: 30 - - ReagentId: Vitamin - Quantity: 15 - - ReagentId: Water - Quantity: 5 - - ReagentId: Bicaridine - Quantity: 5 - - ReagentId: Kelotane - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 45 + - ReagentId: Vitamin + Quantity: 60 + - ReagentId: Water + Quantity: 5 + - ReagentId: Bicaridine + Quantity: 5 + - ReagentId: Kelotane + Quantity: 5 - type: Tag tags: - Fruit @@ -683,12 +588,12 @@ - butter - type: Sprite state: corn-in-butter - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Vitamin + Quantity: 15 + - ReagentId: Butter + Quantity: 2.5 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml index 41c8f65885..bd3ca13ca4 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml @@ -12,17 +12,15 @@ sprite: Objects/Consumable/Food/meat.rsi - type: Extractable grindableSolutionName: food - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: UncookedAnimalProteins - Quantity: 1 - - ReagentId: Fat - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: UncookedAnimalProteins + Quantity: 20 + - ReagentId: Fat + Quantity: 5 - type: Item shape: - 0,0,1,0 @@ -81,16 +79,8 @@ components: - type: Sprite state: plain - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 9 - - ReagentId: Fat - Quantity: 9 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatCutlet - type: InternalTemperature conductivity: 0.43 @@ -117,14 +107,8 @@ components: - type: Sprite state: plain - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 9 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatCutlet - type: Item storedOffset: -2,1 @@ -150,12 +134,15 @@ - Meat - type: Sprite state: fish - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: CarpoToxin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: CarpoToxin + Quantity: 5 + - ReagentId: UncookedAnimalProteins + Quantity: 20 + - ReagentId: Fat + Quantity: 5 - type: Extractable juiceSolution: reagents: @@ -171,7 +158,7 @@ - type: entity # bacon is cured so not raw = cant rot - parent: FoodMeatBase + parent: [SolutionTiny, FoodMeatBase] id: FoodMeatBacon name: raw bacon description: A raw piece of bacon. @@ -182,14 +169,13 @@ - Meat - type: Sprite state: bacon - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 2 - - ReagentId: Fat - Quantity: 9 + - type: Solution + solution: + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 6 + - ReagentId: Fat + Quantity: 9 - type: InternalTemperature conductivity: 0.44 thickness: 0.004 # bacon is thin so faster to cook than a steak @@ -214,16 +200,8 @@ components: - type: Sprite state: bear - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 9 - - ReagentId: Fat - Quantity: 9 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatBearCutlet - type: Construction graph: BearSteak @@ -247,16 +225,8 @@ components: - type: Sprite state: bird - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 9 - - ReagentId: Fat - Quantity: 9 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatPenguinCutlet - type: Construction graph: PenguinSteak @@ -278,16 +248,8 @@ components: - type: Sprite state: bird - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 9 - - ReagentId: Fat - Quantity: 9 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatChickenCutlet - type: InternalTemperature conductivity: 0.41 @@ -311,16 +273,8 @@ components: - type: Sprite state: bird - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 9 - - ReagentId: Fat - Quantity: 9 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatDuckCutlet - type: Construction graph: DuckSteak @@ -348,12 +302,13 @@ - Meat - type: Sprite state: corgi - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Bicaridine - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Bicaridine + Quantity: 20 - type: StaticPrice price: 750 - type: StealTarget @@ -378,14 +333,6 @@ - crabby - type: Sprite state: crab - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 1 - - ReagentId: Fat - Quantity: 2 - type: Construction graph: CrabSteak node: start @@ -399,14 +346,6 @@ components: - type: Sprite state: goliath - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 5 - - ReagentId: Fat - Quantity: 3 - type: InternalTemperature thickness: 0.1 # very big, do cook it in lava - type: Construction @@ -436,19 +375,20 @@ - state: dragon - state: dragon_veins shader: unshaded - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Ichor - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Protein + Quantity: 20 + - ReagentId: Ichor + Quantity: 10 - type: Extractable juiceSolution: reagents: - ReagentId: Ichor Quantity: 10 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatDragonCutlet - type: Construction graph: DragonSteak @@ -463,23 +403,24 @@ - state: dragon-inhand-right - type: entity - parent: FoodMeatRawBase + parent: [SolutionVeryTiny, FoodMeatRawBase] id: FoodMeatRat name: raw rat meat description: Prime meat from maintenance! components: - type: Sprite state: plain - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 3 - - ReagentId: Fat - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 1 + - ReagentId: UncookedAnimalProteins + Quantity: 4 + - ReagentId: Fat + Quantity: 1 - type: SliceableFood - count: 3 + count: 1 slice: FoodMeatCutlet - type: Item storedOffset: -2,1 @@ -497,16 +438,8 @@ components: - type: Sprite state: lizard - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 9 - - ReagentId: Fat - Quantity: 9 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatLizardCutlet - type: Construction graph: LizardSteak @@ -545,16 +478,15 @@ - Recyclable - type: Sprite state: rotten - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 5 - - ReagentId: GastroToxin - Quantity: 4 - - ReagentId: Fat - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 10 + - ReagentId: GastroToxin + Quantity: 16 + - ReagentId: Fat + Quantity: 4 - type: Item storedOffset: -2,1 inhandVisuals: @@ -571,16 +503,8 @@ components: - type: Sprite state: spider - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 9 - - ReagentId: Fat - Quantity: 9 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatSpiderCutlet - type: Item storedOffset: 0,2 @@ -594,14 +518,6 @@ components: - type: Sprite state: spiderleg - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 10 - - ReagentId: Fat - Quantity: 3 - type: Item size: Normal shape: @@ -615,7 +531,7 @@ color: "#333333" - type: entity - parent: FoodMeatBase + parent: [SolutionTiny, FoodMeatBase] id: FoodMeatWheat name: meatwheat clump description: This doesn't look like meat, but your standards aren't that high to begin with. @@ -625,16 +541,14 @@ - falsemeat - type: Sprite state: clump - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 15 - type: Item size: Tiny shape: - - 0,0,0,0 inhandVisuals: left: - state: generic-pink-inhand-left @@ -644,7 +558,7 @@ color: "#934C64" - type: entity - parent: FoodMeatBase + parent: [SolutionTiny, FoodMeatBase] id: FoodMeatSnake name: raw snake meat description: A long piece of snake meat, hopefully not poisonous. @@ -655,14 +569,15 @@ - Meat - type: Sprite state: snake - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 10 - - ReagentId: Toxin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 10 + - ReagentId: Fat + Quantity: 3 + - ReagentId: Toxin + Quantity: 2 - type: Item storedOffset: -1,3 inhandVisuals: @@ -688,14 +603,13 @@ - Meat - type: Sprite state: xeno - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: SulfuricAcid - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: SulfuricAcid + Quantity: 30 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatXenoCutlet - type: Item storedOffset: -2,1 @@ -725,12 +639,11 @@ - Meat - type: Sprite state: rouny - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: SulfuricAcid - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: SulfuricAcid + Quantity: 30 - type: Construction graph: RounySteak node: start @@ -751,7 +664,7 @@ - type: Sprite state: tomato - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatTomatoCutlet - type: StaticPrice price: 100 @@ -813,7 +726,7 @@ slice: FoodMeatSalamiSlice - type: entity - parent: FoodMeatBase + parent: [SolutionTiny, FoodMeatBase] id: FoodMeatMeatball name: meatball description: A raw ball of meat. Meat ball. @@ -821,8 +734,16 @@ - type: Item size: Tiny shape: - - 0,0,0,0 storedOffset: -1,2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 7 + - ReagentId: UncookedAnimalProteins + Quantity: 5 + - ReagentId: Fat + Quantity: 3 - type: Tag tags: - Raw @@ -836,7 +757,7 @@ # meat patty - grillin' time - type: entity - parent: FoodMeatBase + parent: [SolutionTiny, FoodMeatBase] id: FoodMeatPatty name: meat patty description: A flat slab of ground meat. Ready for grillin'. @@ -856,8 +777,16 @@ - type: Item size: Tiny shape: - - 0,0,0,0 heldPrefix: generic-pink + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 2.5 + - ReagentId: UncookedAnimalProteins + Quantity: 10 + - ReagentId: Fat + Quantity: 2.5 - type: entity parent: FoodMeatBase @@ -888,52 +817,24 @@ - state: slime-inhand-right - type: entity - parent: FoodMeatRawBase - id: FoodMeatSnail - name: raw snail meat - description: Improved with salt. - components: - - type: Sprite - state: snail - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 3 - - ReagentId: Fat - Quantity: 3 - - ReagentId: Water - Quantity: 4 #It makes saline if you add salt! - - type: Item - storedOffset: -1,-3 - inhandVisuals: - left: - - state: generic-pink-inhand-left - color: "#E2AE7C" - right: - - state: generic-pink-inhand-right - color: "#E2AE7C" - -- type: entity - parent: FoodMeatRawBase + parent: [SolutionHuge, FoodMeatRawBase] id: FoodMeatAnomaly name: anomalous meat mass description: An impossibly dense slab of meat. Just looking at it makes you uncomfortable. components: - type: Sprite state: anomalymeat - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 90 - - ReagentId: Fat - Quantity: 90 + - type: Solution # Literally no space for anything but meat. + solution: + reagents: + - ReagentId: Nutriment + Quantity: 80 + - ReagentId: UncookedAnimalProteins + Quantity: 320 + - ReagentId: Fat + Quantity: 80 - type: SliceableFood - count: 10 + count: 16 sliceTime: 5 slice: FoodMeat #That's... So much meat - type: InternalTemperature @@ -958,13 +859,11 @@ # Cooked - type: entity - parent: FoodBase + parent: FoodBaseTrash id: MaterialSmileExtract name: smile extract description: It's a real panacea. But at what cost? components: - - type: Item - size: Tiny - type: Extractable grindableSolutionName: food - type: FlavorProfile @@ -975,16 +874,15 @@ layers: - map: [ "enum.DamageStateVisualLayers.Base" ] state: rainbow_slime_extract - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Omnizine - Quantity: 30 - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Iron - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Omnizine + Quantity: 30 + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Iron + Quantity: 10 - type: StaticPrice price: 3000 #It has so much Omnizin in it - type: Tag @@ -992,7 +890,24 @@ - Meat - type: entity + abstract: true parent: FoodMeatBase + id: FoodMeatCookedBase + components: + - type: Tag + tags: + - Cooked + - Meat + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Protein + Quantity: 10 + +- type: entity + parent: FoodMeatCookedBase id: FoodMeatCooked name: steak description: A cooked slab of meat. Smells primal. @@ -1005,16 +920,8 @@ - type: Sprite layers: - state: plain-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Protein - Quantity: 5 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatCutletCooked - type: Construction graph: MeatSteak @@ -1032,15 +939,11 @@ - state: plain-cooked-inhand-right - type: entity - parent: FoodMeatBase + parent: [SolutionVeryTiny, FoodMeatCookedBase] # Bacon shrinks when its cooked so we shrink solution size as well. id: FoodMeatBaconCooked name: bacon description: A delicious piece of cooked bacon. components: - - type: Tag - tags: - - Cooked - - Meat - type: Sprite layers: - state: bacon-cooked @@ -1050,14 +953,13 @@ - enum.DamageStateVisualLayers.Base: bacon-cooked: "" bacon2-cooked: "" - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Protein + Quantity: 5 - type: Construction graph: Bacon node: bacon @@ -1076,7 +978,7 @@ color: "#5B3E2A" - type: entity - parent: FoodMeatBase + parent: FoodMeatCookedBase id: FoodMeatBearCooked name: cooked bear description: A well-cooked slab of bear meat. Tough, but tasty with the right sides. @@ -1089,16 +991,8 @@ - type: Sprite layers: - state: product-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 5 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatBearCutletCooked - type: Construction graph: BearSteak @@ -1112,28 +1006,16 @@ heldPrefix: meatball - type: entity - parent: FoodMeatBase + parent: FoodMeatCookedBase id: FoodMeatPenguinCooked name: penguin filet description: A cooked filet of penguin. Can be used as a substitute for fish in recipes. components: - - type: Tag - tags: - - Cooked - - Meat - type: Sprite layers: - state: bird-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 5 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatPenguinCutletCooked - type: Construction graph: PenguinSteak @@ -1153,28 +1035,16 @@ color: "#F7E3A3" - type: entity - parent: FoodMeatBase + parent: FoodMeatCookedBase id: FoodMeatChickenCooked name: cooked chicken description: A cooked piece of chicken. Best used in other recipes. components: - - type: Tag - tags: - - Cooked - - Meat - type: Sprite layers: - state: bird-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 5 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatChickenCutletCooked - type: Construction graph: ChickenSteak @@ -1195,14 +1065,10 @@ - type: entity name: fried chicken - parent: FoodMeatBase + parent: FoodMeatCookedBase id: FoodMeatChickenFried description: A juicy hunk of chicken meat, fried to perfection. components: - - type: Tag - tags: - - Cooked - - Meat - type: Sprite layers: - state: chicken-fried @@ -1212,14 +1078,6 @@ - enum.DamageStateVisualLayers.Base: chicken-fried: "" chicken2-fried: "" - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 5 - type: FoodSequenceElement entries: Burger: MeatChicken @@ -1239,40 +1097,27 @@ name: mystery fried chicken description: “Eleven secret herbs and… oh no. That’s not chicken." components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Protein - Quantity: 5 - - ReagentId: Ammonia - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 15 + - ReagentId: Protein + Quantity: 10 + - ReagentId: Ammonia + Quantity: 5 - type: entity - parent: FoodMeatBase + parent: FoodMeatCookedBase id: FoodMeatDuckCooked name: cooked duck description: A cooked piece of duck. Best used in other recipes. components: - - type: Tag - tags: - - Cooked - - Meat - type: Sprite layers: - state: bird-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 5 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatDuckCutletCooked - type: Construction graph: DuckSteak @@ -1292,7 +1137,7 @@ color: "#F7E3A3" - type: entity - parent: FoodMeatBase + parent: FoodMeatCookedBase id: FoodMeatCrabCooked name: cooked crab description: Some deliciously cooked crab meat. @@ -1300,21 +1145,9 @@ - type: FlavorProfile flavors: - crabby - - type: Tag - tags: - - Cooked - - Meat - type: Sprite layers: - state: crab-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 5 - type: Construction graph: CrabSteak node: cooked crab @@ -1331,7 +1164,7 @@ - state: plain-cooked-inhand-right - type: entity - parent: FoodMeatBase + parent: FoodMeatCookedBase id: FoodMeatGoliathCooked name: goliath steak description: A delicious, lava cooked steak. @@ -1344,14 +1177,6 @@ - type: Sprite layers: - state: goliath-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 5 - type: Construction graph: GoliathSteak node: goliath steak @@ -1369,7 +1194,7 @@ - type: entity name: rouny steak - parent: FoodMeatBase + parent: FoodMeatCookedBase id: FoodMeatRounyCooked description: Some kill to survive. You on the other hand, kill for fun. components: @@ -1385,14 +1210,6 @@ - type: Sprite layers: - state: rouny-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Protein - Quantity: 10 - type: Construction graph: RounySteak node: rouny steak @@ -1408,7 +1225,7 @@ - state: plain-cooked-inhand-right - type: entity - parent: FoodMeatBase + parent: FoodMeatCookedBase id: FoodMeatLizardCooked name: lizard steak description: Cooked, tough lizard meat. @@ -1421,16 +1238,8 @@ - type: Sprite layers: - state: lizard-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 5 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatLizardCutletCooked - type: Construction graph: LizardSteak @@ -1448,26 +1257,14 @@ - state: plain-cooked-inhand-right - type: entity - parent: FoodMeatBase + parent: FoodMeatCookedBase id: FoodMeatSpiderlegCooked name: boiled spider leg description: A giant spider's leg that's still twitching after being cooked. Gross! components: - - type: Tag - tags: - - Cooked - - Meat - type: Sprite layers: - state: spiderleg-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 5 - type: FoodSequenceElement entries: Burger: MeatSpiderBurger @@ -1483,25 +1280,20 @@ color: "#44201A" - type: entity - parent: FoodMeatBase + parent: [SolutionTiny, FoodMeatCookedBase] id: FoodMeatMeatballCooked name: meatball description: A cooked meatball. Perfect to add to other dishes... except fruity ones. components: - - type: Tag - tags: - - Cooked - - Meat - type: Sprite state: meatball-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Protein + Quantity: 5 - type: FoodSequenceElement entries: Burger: MeatBall @@ -1512,12 +1304,11 @@ - type: Item size: Tiny shape: - - 0,0,0,0 storedOffset: -1,2 heldPrefix: meatball - type: entity - parent: FoodMeatBase + parent: [SolutionTiny, FoodMeatCookedBase] id: FoodMeatPattyCooked name: cooked meat patty description: A cooked meat patty. @@ -1529,14 +1320,13 @@ - Steak - type: Sprite state: patty - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 7.5 - - ReagentId: Protein - Quantity: 7.5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Protein + Quantity: 5 - type: Construction graph: CookedPatty node: cooked meat patty @@ -1547,33 +1337,26 @@ - type: Item size: Tiny shape: - - 0,0,0,0 heldPrefix: meatball - type: entity - parent: FoodMeatBase + parent: [SolutionTiny, FoodMeatCookedBase] id: FoodMeatSnailCooked name: boiled snail description: Improved with salt. components: - - type: Tag - tags: - - Cooked - - Meat - type: Sprite layers: - state: snail-cooked - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Protein - Quantity: 3 - - ReagentId: Water - Quantity: 4 # makes saline if you add salt! + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Protein + Quantity: 5 + - ReagentId: Water + Quantity: 4 # makes saline if you add salt! - type: FoodSequenceElement entries: Burger: MeatSnail @@ -1589,28 +1372,23 @@ color: "#5B3E2A" - type: entity - parent: FoodMeatBase + parent: [SolutionLarge, FoodMeatCookedBase] # Intentionlly gets smaller when cooked id: FoodMeatAnomalyCooked name: anomalous steak description: A gigantic mass of cooked meat. A meal for a dinner party, or someone REALLY hungry. components: - - type: Tag - tags: - - Cooked - - Meat - type: Sprite layers: - state: anomalymeat-cooked #Kinda hard to cook this... thing evenly - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 100 - - ReagentId: Protein - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 160 + - ReagentId: Protein + Quantity: 80 - type: SliceableFood - count: 10 + count: 8 sliceTime: 5 slice: FoodMeatCooked - type: Construction @@ -1619,7 +1397,6 @@ - type: Item size: Normal shape: - - 0,0,1,1 inhandVisuals: left: - state: plain-cooked-inhand-left @@ -1627,7 +1404,7 @@ - state: plain-cooked-inhand-right - type: entity - parent: FoodMeatBase + parent: FoodMeatCookedBase id: FoodMeatDragonCooked name: dragon steak description: Pouring ketchup on this is considered a capital crime on most stations. @@ -1640,18 +1417,17 @@ - type: Sprite layers: - state: dragon-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Ichor - Quantity: 6 - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Protein - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: Ichor + Quantity: 5 + - ReagentId: Nutriment + Quantity: 15 + - ReagentId: Protein + Quantity: 15 - type: SliceableFood - count: 3 + count: 5 slice: FoodMeatDragonCutletCooked - type: Construction graph: DragonSteak @@ -1673,7 +1449,35 @@ # Raw - type: entity - parent: FoodMeatBase + abstract: true + parent: [SolutionVeryTiny, FoodMeatBase] + id: FoodMeatCutletBase + components: + - type: Tag + tags: + - Raw + - Cutlet + - Meat + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 1 + - ReagentId: UncookedAnimalProteins + Quantity: 4 + - ReagentId: Fat + Quantity: 1 + - type: Item + size: Tiny + shape: + inhandVisuals: + left: + - state: generic-pink-inhand-left + right: + - state: generic-pink-inhand-right + +- type: entity + parent: FoodMeatCutletBase id: FoodMeatCutlet name: raw cutlet description: A raw meat cutlet. @@ -1685,60 +1489,27 @@ - Meat - type: Sprite state: cutlet - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 3 - - ReagentId: Fat - Quantity: 2 - type: Construction graph: Cutlet node: start defaultTarget: cutlet - - type: Item - size: Tiny - shape: - - 0,0,0,0 - inhandVisuals: - left: - - state: generic-pink-inhand-left - right: - - state: generic-pink-inhand-right - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletBase id: FoodMeatBearCutlet name: raw bear cutlet description: A very manly cutlet of raw bear meat. components: - - type: Tag - tags: - - Raw - - Cutlet - - Meat - type: Sprite layers: - state: cutlet - state: cutlet-alpha color: brown - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 3 - - ReagentId: Fat - Quantity: 2 - type: Construction graph: BearCutlet node: start defaultTarget: bear cutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 inhandVisuals: left: - state: generic-pink-inhand-left @@ -1748,35 +1519,19 @@ color: brown - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletBase id: FoodMeatPenguinCutlet name: raw penguin cutlet description: A cutlet of raw penguin meat. Can be used as a substitute for fish in recipes. components: - - type: Tag - tags: - - Raw - - Cutlet - - Meat - type: Sprite state: cutlet color: white - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 3 - - ReagentId: Fat - Quantity: 2 - type: Construction graph: PenguinCutlet node: start defaultTarget: penguin cutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 inhandVisuals: left: - state: generic-pink-inhand-left @@ -1786,110 +1541,50 @@ color: white - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletBase id: FoodMeatChickenCutlet name: raw chicken cutlet description: A cutlet of raw chicken. Remember to wash your hands! components: - - type: Tag - tags: - - Raw - - Cutlet - - Meat - type: Sprite state: cutlet color: white - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 3 - - ReagentId: Fat - Quantity: 2 - type: Construction graph: ChickenCutlet node: start defaultTarget: chicken cutlet - - type: Item - size: Tiny - shape: - - 0,0,0,0 - inhandVisuals: - left: - - state: generic-pink-inhand-left - right: - - state: generic-pink-inhand-right - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletBase id: FoodMeatDuckCutlet name: raw duck cutlet description: A cutlet of raw duck. Remember to wash your hands! components: - - type: Tag - tags: - - Raw - - Cutlet - - Meat - type: Sprite state: cutlet color: white - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 3 - - ReagentId: Fat - Quantity: 2 - type: Construction graph: DuckCutlet node: start defaultTarget: duck cutlet - - type: Item - size: Tiny - shape: - - 0,0,0,0 - inhandVisuals: - left: - - state: generic-pink-inhand-left - right: - - state: generic-pink-inhand-right - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletBase id: FoodMeatLizardCutlet name: raw lizard cutlet description: Delicious dino cutlet. components: - - type: Tag - tags: - - Raw - - Cutlet - - Meat - type: Sprite layers: - state: cutlet color: green - state: cutlet-alpha color: pink - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 3 - - ReagentId: Fat - Quantity: 2 - type: Construction graph: LizardCutlet node: start defaultTarget: lizard cutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 inhandVisuals: left: - state: generic-pink-inhand-left @@ -1899,34 +1594,18 @@ color: green - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletBase id: FoodMeatSpiderCutlet name: raw spider cutlet description: A cutlet of raw spider meat. So Kafkaesque. components: - - type: Tag - tags: - - Raw - - Cutlet - - Meat - type: Sprite state: spidercutlet - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 3 - - ReagentId: Fat - Quantity: 2 - type: Construction graph: SpiderCutlet node: start defaultTarget: spider cutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 inhandVisuals: left: - state: generic-pink-inhand-left @@ -1936,7 +1615,7 @@ color: green - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletBase id: FoodMeatXenoCutlet name: raw xeno cutlet description: A slab of raw xeno meat, dripping with acid. @@ -1945,27 +1624,18 @@ flavors: - meaty - acid - - type: Tag - tags: - - Raw - - Cutlet - - Meat - type: Sprite state: xenocutlet - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: SulfuricAcid - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: SulfuricAcid + Quantity: 6 - type: Construction graph: XenoCutlet node: start defaultTarget: xeno cutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 inhandVisuals: left: - state: generic-pink-inhand-left @@ -1975,15 +1645,12 @@ color: green - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletBase id: FoodMeatTomatoCutlet name: raw killer tomato cutlet description: A cutlet from a slab of tomato. components: - type: Item - size: Tiny - shape: - - 0,0,0,0 storedOffset: -1,0 - type: Tag tags: @@ -1996,62 +1663,39 @@ price: 30 - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletBase id: FoodMeatSalamiSlice name: salami slice description: A slice of cured salami. components: - type: Item - size: Tiny - shape: - - 0,0,0,0 storedOffset: -1,0 - - type: Tag - tags: - - Raw - - Cutlet - - Meat - type: Sprite state: salami-slice - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 1 - - ReagentId: Protein - Quantity: 1 - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletBase id: FoodMeatDragonCutlet name: raw dragon cutlet description: A raw dragon meat cutlet. components: - - type: Tag - tags: - - Raw - - Cutlet - - Meat - type: Sprite layers: - state: dragoncutlet - state: dragoncutlet_veins shader: unshaded - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Ichor - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Protein + Quantity: 4 + - ReagentId: Ichor + Quantity: 2 - type: Construction graph: DragonCutlet node: start defaultTarget: dragon cutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 inhandVisuals: left: - state: generic-pink-inhand-left @@ -2063,26 +1707,31 @@ # Cooked - type: entity - parent: FoodMeatBase - id: FoodMeatCutletCooked - name: cutlet - description: A cooked meat cutlet. Needs some seasoning. + abstract: true + parent: FoodMeatCutletBase + id: FoodMeatCutletCookedBase components: - type: Tag tags: - Cooked - Cutlet - Meat + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 4 + - ReagentId: Protein + Quantity: 2 + +- type: entity + parent: FoodMeatCutletCookedBase + id: FoodMeatCutletCooked + name: cutlet + description: A cooked meat cutlet. Needs some seasoning. + components: - type: Sprite state: cutlet-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Protein - Quantity: 2 - type: Construction graph: Cutlet node: cutlet @@ -2091,9 +1740,6 @@ Burger: MeatCutlet Taco: MeatCutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 storedOffset: -1,1 inhandVisuals: left: @@ -2104,29 +1750,16 @@ color: "#5B3614" - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletCookedBase id: FoodMeatBearCutletCooked name: bear cutlet description: A very manly cutlet of cooked bear meat. components: - - type: Tag - tags: - - Cooked - - Cutlet - - Meat - type: Sprite layers: - state: cutlet-cooked - state: cutlet-alpha color: brown - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Protein - Quantity: 2 - type: Construction graph: BearCutlet node: bear cutlet @@ -2135,9 +1768,6 @@ Burger: BearCutletBurger Taco: BearCutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 storedOffset: -1,1 inhandVisuals: left: @@ -2148,27 +1778,14 @@ color: "#5B3614" - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletCookedBase id: FoodMeatPenguinCutletCooked name: penguin cutlet description: A cutlet of cooked penguin meat. components: - - type: Tag - tags: - - Cooked - - Cutlet - - Meat - type: Sprite state: cutlet-cooked color: white - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Protein - Quantity: 2 - type: Construction graph: PenguinCutlet node: penguin cutlet @@ -2177,9 +1794,6 @@ Burger: PenguinCutletBurger Taco: PenguinCutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 storedOffset: -1,1 inhandVisuals: left: @@ -2190,27 +1804,14 @@ color: "#5B3614" - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletCookedBase id: FoodMeatChickenCutletCooked name: chicken cutlet description: A cutlet of cooked chicken. Remember to wash your hands! components: - - type: Tag - tags: - - Cooked - - Cutlet - - Meat - type: Sprite state: cutlet-cooked color: white - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Protein - Quantity: 2 - type: Construction graph: ChickenCutlet node: chicken cutlet @@ -2219,9 +1820,6 @@ Burger: ChickenCutlet Taco: ChickenCutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 storedOffset: -1,1 inhandVisuals: left: @@ -2232,27 +1830,14 @@ color: "#5B3614" - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletCookedBase id: FoodMeatDuckCutletCooked name: duck cutlet description: A cutlet of cooked duck. Remember to wash your hands! components: - - type: Tag - tags: - - Cooked - - Cutlet - - Meat - type: Sprite state: cutlet-cooked color: white - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Protein - Quantity: 2 - type: Construction graph: DuckCutlet node: duck cutlet @@ -2261,9 +1846,6 @@ Burger: DuckCutlet Taco: DuckCutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 storedOffset: -1,1 inhandVisuals: left: @@ -2274,28 +1856,15 @@ color: "#5B3614" - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletCookedBase id: FoodMeatLizardCutletCooked name: lizard cutlet description: Delicious cooked dino cutlet. components: - - type: Tag - tags: - - Cooked - - Cutlet - - Meat - type: Sprite layers: - state: cutlet-cooked color: green - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Protein - Quantity: 2 - type: Construction graph: LizardCutlet node: lizard cutlet @@ -2304,9 +1873,6 @@ Burger: LizardCutletBurger Taco: LizardCutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 storedOffset: -1,1 inhandVisuals: left: @@ -2317,26 +1883,13 @@ color: "#153F06" - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletCookedBase id: FoodMeatSpiderCutletCooked name: spider cutlet description: A cutlet of cooked spider meat. Finally edible. components: - - type: Tag - tags: - - Cooked - - Cutlet - - Meat - type: Sprite state: spidercutlet-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 1 - - ReagentId: Protein - Quantity: 1 - type: Construction graph: SpiderCutlet node: spider cutlet @@ -2345,9 +1898,6 @@ Burger: SpiderCutletBurger Taco: SpiderCutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 storedOffset: -1,0 inhandVisuals: left: @@ -2358,26 +1908,13 @@ color: "#153F06" - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletCookedBase id: FoodMeatXenoCutletCooked name: xeno cutlet description: A cutlet of cooked xeno, dripping with... tastiness? components: - - type: Tag - tags: - - Cooked - - Cutlet - - Meat - type: Sprite state: xenocutlet-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 1 - - ReagentId: Protein - Quantity: 1 - type: Construction graph: XenoCutlet node: xeno cutlet @@ -2386,9 +1923,6 @@ Burger: XenoCutlet Taco: XenoCutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 storedOffset: -1,1 inhandVisuals: left: @@ -2399,28 +1933,22 @@ color: "#153F06" - type: entity - parent: FoodMeatBase + parent: FoodMeatCutletCookedBase id: FoodMeatDragonCutletCooked name: dragon cutlet description: It's a meal for kings! components: - - type: Tag - tags: - - Cooked - - Cutlet - - Meat - type: Sprite state: dragoncutlet-cooked - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Ichor - Quantity: 2 - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Protein - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Ichor + Quantity: 1 + - ReagentId: Nutriment + Quantity: 3 + - ReagentId: Protein + Quantity: 3 - type: Construction graph: DragonCutlet node: dragon cutlet @@ -2429,9 +1957,6 @@ Burger: DragonCutlet Taco: DragonCutlet - type: Item - size: Tiny - shape: - - 0,0,0,0 storedOffset: -1,1 inhandVisuals: left: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/noodles.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/noodles.yml index ce20fbb46c..ffdc81c2d2 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/noodles.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/noodles.yml @@ -3,7 +3,7 @@ - type: entity abstract: true - parent: FoodInjectableBase + parent: [SolutionSmall, FoodInjectableBase] id: FoodNoodlesBase description: Now that's a nice pasta! components: @@ -12,13 +12,11 @@ - 0,0,1,0 - type: Sprite sprite: Objects/Consumable/Food/noodles.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 30 # Noodles @@ -51,20 +49,20 @@ - tomato - type: Sprite state: tomato - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 35 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 45 + - ReagentId: Vitamin + Quantity: 5 - type: Tag tags: - - Fruit + - Fruit # ??? # Tastes like pasta, tomato. - type: entity - parent: FoodNoodlesBase + parent: [SolutionNormal, FoodNoodlesBase] id: FoodNoodlesCopy name: copypasta description: You probably shouldn't try this, you always hear people talking about how bad it is... @@ -82,13 +80,13 @@ - copypasta - type: Sprite state: copypasta - - type: SolutionContainerManager - solutions: - food: - maxVol: 80 - reagents: - - ReagentId: Nutriment - Quantity: 70 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 90 + - ReagentId: Vitamin + Quantity: 10 # Tastes like pasta, bad humor. - type: entity @@ -105,15 +103,13 @@ - meaty - type: Sprite state: meatball - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 15 - - ReagentId: Protein - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 40 + - ReagentId: Protein + Quantity: 5 - type: Tag tags: - Meat @@ -133,15 +129,6 @@ - meaty - type: Sprite state: spesslaw - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 6 # Tastes like pasta, meat. - type: entity @@ -158,17 +145,13 @@ - carrot - type: Sprite state: chowmein - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 - reagents: - - ReagentId: Nutriment - Quantity: 20 - - ReagentId: Protein - Quantity: 6 - - ReagentId: Vitamin - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 45 + - ReagentId: Vitamin + Quantity: 12 # Tastes like pasta, tomato. - type: entity @@ -185,11 +168,11 @@ - butter - type: Sprite state: butter - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 23 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 30 + - ReagentId: Butter + Quantity: 5 # Tastes like pasta, butter. diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml index b45c77966d..2a497f9b12 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml @@ -2,23 +2,29 @@ # For produce that can't be immediately eaten - type: entity - parent: BaseItem - id: ProduceBase abstract: true + parent: [SolutionFood, SolutionTiny, BaseItem] # Produce should be less efficient volume wise + id: ProduceBase components: - - type: SolutionContainerManager - type: Sprite state: produce - type: Produce - type: PotencyVisuals - type: Appearance + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Vitamin + Quantity: 5 - type: Extractable grindableSolutionName: food - type: entity + abstract: true parent: ProduceBase id: ProduceBaseRuminant - abstract: true components: # let cows eat raw produce like wheat and oats - type: Edible @@ -30,11 +36,10 @@ # For produce that can be immediately eaten - type: entity - parent: FoodInjectableBase + parent: [SolutionTiny, FoodInjectableBase] id: FoodProduceBase abstract: true components: - - type: SolutionContainerManager - type: Sprite state: produce - type: Produce @@ -46,21 +51,20 @@ # Subclasses - type: entity + parent: ProduceBaseRuminant + id: WheatBushel name: wheat bushel description: Sigh... wheat... a-grain? - id: WheatBushel - parent: ProduceBaseRuminant components: - type: Sprite sprite: Objects/Specific/Hydroponics/wheat.rsi - type: Item heldPrefix: produce - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Flour - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Flour + Quantity: 15 - type: Produce seedId: wheat - type: Tag @@ -69,21 +73,20 @@ - Ruminant - type: entity + parent: ProduceBaseRuminant + id: MeatwheatBushel 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: ProduceBaseRuminant components: - type: Sprite sprite: Objects/Specific/Hydroponics/meatwheat.rsi - type: Item heldPrefix: produce - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: UncookedAnimalProteins - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 15 - type: SpawnItemsOnUse items: - id: FoodMeatWheat @@ -93,21 +96,20 @@ seedId: meatwheat - type: entity + parent: ProduceBaseRuminant + id: OatBushel name: oat bushel description: Eat oats, do squats. - id: OatBushel - parent: ProduceBaseRuminant components: - type: Sprite sprite: Objects/Specific/Hydroponics/oat.rsi - type: Item heldPrefix: produce - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Oats - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Oats + Quantity: 15 - type: Produce seedId: oat - type: Extractable @@ -117,35 +119,33 @@ Quantity: 5 - type: entity + parent: ProduceBaseRuminant + id: Sugarcane name: sugarcane description: Sickly sweet. - id: Sugarcane - parent: ProduceBaseRuminant components: - type: Sprite sprite: Objects/Specific/Hydroponics/sugarcane.rsi - type: Item heldPrefix: produce - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Sugar - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Sugar + Quantity: 15 - type: Produce seedId: sugarcane - type: entity + parent: ProduceBase + id: Papercane name: papercane roll description: Why do we even need to grow paper? - id: Papercane - parent: ProduceBase components: - type: Sprite sprite: Objects/Specific/Hydroponics/papercane.rsi - type: Item heldPrefix: produce - - type: SolutionContainerManager - type: Produce seedId: papercane - type: Log @@ -161,17 +161,15 @@ - type: FlavorProfile flavors: - peas - - type: SolutionContainerManager - solutions: - food: - maxVol: 13 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Sugar - Quantity: 5 - - ReagentId: Laughter - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Sugar + Quantity: 5 + - ReagentId: Laughter + Quantity: 5 - type: Extractable juiceSolution: reagents: @@ -189,16 +187,15 @@ - Ruminant - type: entity + parent: ProduceBase + id: Log name: tower-cap log description: It's better than bad, it's good! - id: Log - parent: ProduceBase components: - type: Sprite sprite: Objects/Specific/Hydroponics/towercap.rsi - type: Item heldPrefix: produce - - type: SolutionContainerManager - type: MeleeWeapon damage: types: @@ -208,16 +205,15 @@ - type: Log - type: entity + parent: ProduceBase + id: SteelLog name: steel-cap log description: Steel doesn't grow on trees! It grows on mushrooms, of course. - id: SteelLog - parent: ProduceBase components: - type: Sprite sprite: Objects/Specific/Hydroponics/steelcap.rsi - type: Item heldPrefix: produce - - type: SolutionContainerManager - type: MeleeWeapon damage: types: @@ -229,10 +225,10 @@ spawnCount: 1 - type: entity + parent: ProduceBaseRuminant + id: Nettle name: nettle description: Stingy little prick. - id: Nettle - parent: ProduceBaseRuminant components: - type: Sprite sprite: Objects/Specific/Hydroponics/nettle.rsi @@ -244,12 +240,12 @@ damage: types: Heat: 10 - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Histamine - Quantity: 3 + - type: Solution + solution: + maxVol: 6 + reagents: + - ReagentId: Histamine + Quantity: 3 - type: Produce seedId: nettle - type: MeleeChemicalInjector @@ -260,10 +256,10 @@ grindableSolutionName: food - type: entity + parent: [ ProduceBase, BaseMajorContraband ] + id: DeathNettle name: death nettle description: This nettle's out for blood. - id: DeathNettle - parent: [ProduceBase, BaseMajorContraband] components: - type: Sprite sprite: Objects/Specific/Hydroponics/death_nettle.rsi @@ -276,14 +272,13 @@ types: Heat: 8 Caustic: 8 - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: SulfuricAcid - Quantity: 15 - - ReagentId: FluorosulfuricAcid - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: SulfuricAcid + Quantity: 7.5 + - ReagentId: FluorosulfuricAcid + Quantity: 7.5 - type: Produce seedId: deathNettle - type: MeleeChemicalInjector @@ -342,15 +337,15 @@ butcheringType: Knife spawned: - id: TrashBananaPeel - - type: SolutionContainerManager - solutions: - food: - maxVol: 6 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: Vitamin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 8 + - ReagentId: Vitamin + Quantity: 2 + - ReagentId: JuiceBanana + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/banana.rsi - type: Item @@ -388,15 +383,15 @@ butcheringType: Knife spawned: - id: TrashMimanaPeel - - type: SolutionContainerManager - solutions: - food: - maxVol: 7 - reagents: - - ReagentId: MuteToxin - Quantity: 5 - - ReagentId: Vitamin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 8 + - ReagentId: Vitamin + Quantity: 2 + - ReagentId: MuteToxin + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/mimana.rsi - type: Item @@ -407,7 +402,7 @@ juiceSolution: reagents: - ReagentId: JuiceBanana - Quantity: 10 + Quantity: 5 - ReagentId: Nothing Quantity: 5 - type: Tag @@ -419,7 +414,7 @@ Taco: Mimana - type: entity - parent: BaseItem + parent: [SolutionFood, SolutionVeryTiny, BaseItem] id: TrashBananaPeel name: banana peel components: @@ -458,16 +453,14 @@ - Trash - BananaPeel - Ruminant - - WhitelistChameleon - HamsterWearable - - type: SolutionContainerManager - solutions: - food: - maxVol: 4 - reagents: - - ReagentId: PulpedBananaPeel - Quantity: 4 + - type: Solution + solution: + maxVol: 7.5 + reagents: + - ReagentId: PulpedBananaPeel + Quantity: 4 - type: Extractable grindableSolutionName: food - type: SpaceGarbage @@ -494,16 +487,15 @@ - type: Item sprite: Objects/Specific/Hydroponics/banana.rsi heldPrefix: baked-peel - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: PulpedBananaPeel - Quantity: 1 - - ReagentId: Bananadine - Quantity: 1 - - ReagentId: Carbon - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: PulpedBananaPeel + Quantity: 1 + - ReagentId: Bananadine + Quantity: 1 + - ReagentId: Carbon + Quantity: 2 - type: entity parent: TrashBananaPeel @@ -554,17 +546,15 @@ tags: - Carrot - Vegetable - - type: SolutionContainerManager - solutions: - food: - maxVol: 12 - reagents: - - ReagentId: JuiceCarrot - Quantity: 5 - - ReagentId: Vitamin - Quantity: 4 - - ReagentId: Oculine - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: JuiceCarrot + Quantity: 5 + - ReagentId: Vitamin + Quantity: 7 + - ReagentId: Oculine + Quantity: 3 - type: Sprite sprite: Objects/Specific/Hydroponics/carrot.rsi - type: Item @@ -592,15 +582,15 @@ - type: FlavorProfile flavors: - cabbage - - type: SolutionContainerManager - solutions: - food: - maxVol: 14 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: Water + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/cabbage.rsi - type: Item @@ -624,17 +614,15 @@ - type: FlavorProfile flavors: - garlic - - type: SolutionContainerManager - solutions: - food: - maxVol: 18 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 4 - - ReagentId: Allicin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 6 + - ReagentId: Vitamin + Quantity: 4 + - ReagentId: Allicin + Quantity: 4 - type: Sprite sprite: Objects/Specific/Hydroponics/garlic.rsi - type: Produce @@ -656,15 +644,15 @@ - type: FlavorProfile flavors: - sour - - type: SolutionContainerManager - solutions: - food: - maxVol: 9 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: JuiceLemon + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/lemon.rsi - type: Item @@ -694,15 +682,13 @@ - type: FlavorProfile flavors: - lemoon - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Vitamin - Quantity: 4 - - ReagentId: Milk - Quantity: 16 + - type: Solution + solution: + reagents: + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: Milk + Quantity: 10 - type: Sprite sprite: Objects/Specific/Hydroponics/lemoon.rsi - type: Item @@ -731,6 +717,15 @@ - type: FlavorProfile flavors: - sour + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: JuiceLime + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/lime.rsi - type: Item @@ -760,6 +755,15 @@ - type: FlavorProfile flavors: - orange + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: JuiceOrange + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/orange.rsi - type: Item @@ -788,17 +792,15 @@ - type: FlavorProfile flavors: - truenature - - type: SolutionContainerManager - solutions: - food: - maxVol: 14 - reagents: - - ReagentId: Haloperidol - Quantity: 5 - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Haloperidol + Quantity: 5 + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/extradimensional_orange.rsi scale: 0.5,0.5 @@ -831,17 +833,15 @@ - type: FlavorProfile flavors: - pineapple - - type: SolutionContainerManager - solutions: - food: - maxVol: 16 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 2 - - ReagentId: Water - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 8 + - ReagentId: Vitamin + Quantity: 2 + - ReagentId: JuicePineapple + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/pineapple.rsi - type: Item @@ -869,15 +869,6 @@ - type: FlavorProfile flavors: - potatoes - - type: SolutionContainerManager - solutions: - food: - maxVol: 14 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 4 - type: Sprite sprite: Objects/Specific/Hydroponics/potato.rsi - type: Item @@ -893,7 +884,6 @@ Burger: Potato Taco: Potato - - type: entity name: tomato parent: [FoodProduceBase, ItemHeftyBase] @@ -903,17 +893,15 @@ - type: FlavorProfile flavors: - tomato - - type: SolutionContainerManager - solutions: - food: - maxVol: 14 - reagents: - - ReagentId: Nutriment - Quantity: 7 - - ReagentId: Vitamin - Quantity: 3 - - ReagentId: Water - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 7 + - ReagentId: Vitamin + Quantity: 3 + - ReagentId: Water + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/tomato.rsi - type: Item @@ -963,17 +951,15 @@ id: FoodBlueTomato description: This one is blue. components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 24 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: SpaceLube - Quantity: 15 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: SpaceLube + Quantity: 15 + - ReagentId: Vitamin + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/blue_tomato.rsi - type: Item @@ -1014,15 +1000,13 @@ id: FoodBloodTomato description: Wait, that's not ketchup... components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 14 - reagents: - - ReagentId: Blood - Quantity: 10 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Blood + Quantity: 10 + - ReagentId: Vitamin + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/blood_tomato.rsi - type: Item @@ -1067,15 +1051,6 @@ - type: FlavorProfile flavors: - eggplant - - type: SolutionContainerManager - solutions: - food: - maxVol: 14 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 4 - type: Sprite sprite: Objects/Specific/Hydroponics/eggplant.rsi - type: Item @@ -1096,15 +1071,15 @@ - type: FlavorProfile flavors: - apple - - type: SolutionContainerManager - solutions: - food: - maxVol: 14 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: JuiceApple + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/apple.rsi - type: Item @@ -1134,17 +1109,15 @@ flavors: - apple - metallic - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 4 - - ReagentId: DoctorsDelight - Quantity: 13 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: DoctorsDelight + Quantity: 15 - type: Sprite sprite: Objects/Specific/Hydroponics/golden_apple.rsi - type: Item @@ -1175,17 +1148,15 @@ - type: FlavorProfile flavors: - chocolate - - type: SolutionContainerManager - solutions: - food: - maxVol: 14 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Vitamin - Quantity: 1 - - ReagentId: CocoaPowder - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 6 + - ReagentId: Vitamin + Quantity: 3 + - ReagentId: CocoaPowder + Quantity: 6 - type: Sprite sprite: Objects/Specific/Hydroponics/cocoa.rsi - type: Produce @@ -1215,15 +1186,13 @@ butcheringType: Knife spawned: - id: FoodCornTrash #no idea why you'd ever do this, but it's just here for consistency - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Cornmeal - Quantity: 15 - - ReagentId: Nutriment - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Cornmeal + Quantity: 15 + - ReagentId: Nutriment + Quantity: 5 - type: Tag tags: - Corn @@ -1260,13 +1229,11 @@ - type: Tag tags: - Trash - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Cornmeal - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Cornmeal + Quantity: 15 - type: entity name: onion @@ -1277,17 +1244,15 @@ - type: FlavorProfile flavors: - onion - - type: SolutionContainerManager - solutions: - food: - maxVol: 18 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 4 - - ReagentId: Allicin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: Allicin + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/onion.rsi - type: Item @@ -1310,17 +1275,15 @@ - type: FlavorProfile flavors: - onion - - type: SolutionContainerManager - solutions: - food: - maxVol: 18 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 4 - - ReagentId: Allicin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: Allicin + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/onion_red.rsi - type: Item @@ -1340,12 +1303,13 @@ id: FoodMushroom description: "Cantharellus Cibarius: These jolly yellow little shrooms sure look tasty!" components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 12 + - ReagentId: Vitamin + Quantity: 8 - type: Sprite sprite: Objects/Specific/Hydroponics/chanterelle.rsi - type: Item @@ -1364,13 +1328,14 @@ id: ProduceSliceBase abstract: true components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 3 - reagents: - - ReagentId: Nutriment - Quantity: 2 + - type: Solution + solution: + maxVol: 7.5 + reagents: + - ReagentId: Nutriment + Quantity: 2 + - ReagentId: Vitamin + Quantity: 1 - type: Sprite state: slice - type: Extractable @@ -1415,17 +1380,15 @@ - onion - type: Sprite sprite: Objects/Specific/Hydroponics/onion.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Allicin - Quantity: 1 - - ReagentId: Vitamin - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 1 + - ReagentId: Allicin + Quantity: 1 + - ReagentId: Vitamin + Quantity: 1 - type: Tag tags: - Vegetable @@ -1446,17 +1409,15 @@ - onion - type: Sprite sprite: Objects/Specific/Hydroponics/onion_red.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Allicin - Quantity: 1 - - ReagentId: Vitamin - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 1 + - ReagentId: Allicin + Quantity: 1 + - ReagentId: Vitamin + Quantity: 1 - type: Tag tags: - Vegetable @@ -1475,17 +1436,15 @@ - type: FlavorProfile flavors: - spicy - - type: SolutionContainerManager - solutions: - food: - maxVol: 18 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: CapsaicinOil - Quantity: 10 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 2 + - ReagentId: CapsaicinOil + Quantity: 10 + - ReagentId: Vitamin + Quantity: 3 - type: Sprite sprite: Objects/Specific/Hydroponics/chili.rsi - type: Item @@ -1511,17 +1470,15 @@ flavors: - spicy - cold - - type: SolutionContainerManager - solutions: - food: - maxVol: 18 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: FrostOil - Quantity: 10 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 4 + - ReagentId: FrostOil + Quantity: 10 + - ReagentId: Vitamin + Quantity: 4 - type: Sprite sprite: Objects/Specific/Hydroponics/chilly.rsi - type: Item @@ -1543,15 +1500,13 @@ - type: FlavorProfile flavors: - medicine - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 ##I'm pretty sure this has to match the total of 100 potency yields - reagents: - - ReagentId: Aloe - Quantity: 10 - - ReagentId: Dermaline - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Aloe + Quantity: 10 + - ReagentId: Dermaline + Quantity: 10 - type: Sprite sprite: Objects/Specific/Hydroponics/aloe.rsi - type: Item @@ -1581,15 +1536,13 @@ - type: FlavorProfile flavors: - medicine - - type: SolutionContainerManager - solutions: - food: - maxVol: 22 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Bicaridine - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Bicaridine + Quantity: 10 - type: Sprite sprite: Objects/Specific/Hydroponics/poppy.rsi - type: Produce @@ -1613,15 +1566,13 @@ - type: FlavorProfile flavors: - medicine - - type: SolutionContainerManager - solutions: - food: - maxVol: 22 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Bicaridine - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Bicaridine + Quantity: 10 - type: Sprite sprite: Objects/Specific/Hydroponics/lily.rsi - type: Produce @@ -1638,7 +1589,7 @@ - type: entity name: lingzhi - parent: FoodProduceBase + parent: [SolutionSmall, FoodProduceBase] id: FoodLingzhi description: A potent medicinal mushroom. Don't go overboard. components: @@ -1646,15 +1597,13 @@ flavors: - mushroom - medicine - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Ultravasculine - Quantity: 20 - - ReagentId: Epinephrine - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Ultravasculine + Quantity: 20 + - ReagentId: Epinephrine + Quantity: 20 - type: Sprite sprite: Objects/Specific/Hydroponics/lingzhi.rsi - type: Item @@ -1681,19 +1630,17 @@ flavors: - leafy - medicine - - type: SolutionContainerManager - solutions: - food: - maxVol: 14 - reagents: - - ReagentId: Bicaridine - Quantity: 5 - - ReagentId: Kelotane - Quantity: 5 - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Vitamin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Bicaridine + Quantity: 5 + - ReagentId: Kelotane + Quantity: 5 + - ReagentId: Nutriment + Quantity: 3 + - ReagentId: Vitamin + Quantity: 2 - type: Sprite sprite: Objects/Specific/Hydroponics/ambrosia_vulgaris.rsi - type: Item @@ -1724,17 +1671,15 @@ flavors: - leafy - medicine - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Omnizine - Quantity: 3 - - ReagentId: SpaceDrugs - Quantity: 5 - - ReagentId: Nutriment - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Omnizine + Quantity: 3 + - ReagentId: SpaceDrugs + Quantity: 10 + - ReagentId: Nutriment + Quantity: 2 - type: Sprite sprite: Objects/Specific/Hydroponics/ambrosia_deus.rsi - type: Item @@ -1757,20 +1702,18 @@ - type: entity name: galaxythistle - parent: FoodProduceBase + parent: [SolutionSmall, FoodProduceBase] id: FoodGalaxythistle description: A medicinal plant used for its antitoxin. components: - type: FlavorProfile flavors: - medicine - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Stellibinin - Quantity: 25 + - type: Solution + solution: + reagents: + - ReagentId: Stellibinin + Quantity: 30 - type: Sprite sprite: Objects/Specific/Hydroponics/galaxythistle.rsi - type: Item @@ -1790,7 +1733,7 @@ - type: entity name: glasstle - parent: FoodProduceBase + parent: [SolutionSmall, FoodProduceBase] id: FoodGlasstle description: A fragile crystal plant with lot of spiky thorns. components: @@ -1801,15 +1744,13 @@ - type: FlavorProfile flavors: - sharp - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Razorium - Quantity: 15 - - ReagentId: Desoxyephedrine - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Razorium + Quantity: 20 + - ReagentId: Desoxyephedrine + Quantity: 10 - type: Sprite sprite: Objects/Specific/Hydroponics/glasstle.rsi - type: Produce @@ -1868,15 +1809,13 @@ - type: FlavorProfile flavors: - mushroom - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Amatoxin - Quantity: 10 - - ReagentId: Nutriment - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Amatoxin + Quantity: 10 + - ReagentId: Nutriment + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/fly_amanita.rsi - type: Item @@ -1903,15 +1842,15 @@ - type: FlavorProfile flavors: - gunpowder - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Sulfur - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Iron + Quantity: 5 + - ReagentId: Sulfur + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/gatfruit.rsi - type: Produce @@ -1940,15 +1879,15 @@ - type: FlavorProfile flavors: - plastic - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Sulfur - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Iron + Quantity: 5 + - ReagentId: Sulfur + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/capfruit.rsi - type: Item @@ -1996,12 +1935,11 @@ sprite: Objects/Specific/Hydroponics/rice.rsi - type: Item heldPrefix: produce - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Rice - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Rice + Quantity: 15 - type: Produce seedId: rice @@ -2013,20 +1951,20 @@ components: - type: Sprite sprite: Objects/Specific/Hydroponics/soybeans.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 4 - reagents: - - ReagentId: Nutriment - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Protein + Quantity: 12 + - ReagentId: Nutriment + Quantity: 8 - type: Produce seedId: soybeans - type: Extractable juiceSolution: reagents: - ReagentId: MilkSoy - Quantity: 5 + Quantity: 15 - type: Tag tags: - Vegetable @@ -2048,15 +1986,15 @@ sprite: Objects/Specific/Hydroponics/spacemans_trumpet.rsi - type: Item heldPrefix: produce - - type: SolutionContainerManager - solutions: - food: - maxVol: 4 - reagents: - - ReagentId: Nutriment - Quantity: 1 - - ReagentId: PolypyryliumOligomers - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 2 + - ReagentId: Cellulose + Quantity: 10 + - ReagentId: PolypyryliumOligomers + Quantity: 3 - type: Produce seedId: spacemansTrumpet - type: Tag @@ -2077,15 +2015,15 @@ components: - type: Sprite sprite: Objects/Specific/Hydroponics/koibean.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 7 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: CarpoToxin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Protein + Quantity: 12 + - ReagentId: Nutriment + Quantity: 4 + - ReagentId: CarpoToxin + Quantity: 4 - type: Produce seedId: koibean - type: Extractable @@ -2108,22 +2046,24 @@ description: Round green object that you can slice and eat. components: - type: Item - size: Small + size: Normal heldPrefix: produce - type: FlavorProfile flavors: - watermelon - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: Water - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 4 + - ReagentId: Vitamin + Quantity: 4 + - ReagentId: Sugar + Quantity: 4 + - ReagentId: JuiceWatermelon + Quantity: 8 + - ReagentId: Water + Quantity: 40 - type: Sprite sprite: Objects/Specific/Hydroponics/watermelon.rsi - type: Produce @@ -2132,7 +2072,7 @@ juiceSolution: reagents: - ReagentId: JuiceWatermelon - Quantity: 20 + Quantity: 40 - type: Damageable - type: Injurable damageContainer: Biological @@ -2155,7 +2095,7 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - type: SliceableFood - count: 5 + count: 4 slice: FoodWatermelonSlice - type: Butcherable butcheringType: Knife @@ -2167,7 +2107,7 @@ - type: entity name: watermelon slice - parent: ProduceSliceBase + parent: [SolutionTiny, ProduceSliceBase] id: FoodWatermelonSlice description: Juicy green and red slice. components: @@ -2178,22 +2118,24 @@ - watermelon - type: Sprite sprite: Objects/Specific/Hydroponics/watermelon.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Vitamin - Quantity: 1 - - ReagentId: Water - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 1 + - ReagentId: Vitamin + Quantity: 1 + - ReagentId: Sugar + Quantity: 1 + - ReagentId: JuiceWatermelon + Quantity: 2 + - ReagentId: Water + Quantity: 10 - type: Extractable juiceSolution: reagents: - ReagentId: JuiceWatermelon - Quantity: 4 + Quantity: 10 - type: Tag tags: - Fruit @@ -2211,23 +2153,23 @@ description: The water within this melon has been blessed by some deity that's particularly fond of watermelon. components: - type: Item - size: Small + size: Normal heldPrefix: produce - type: FlavorProfile flavors: - holy - watermelon - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: Holywater - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 4 + - ReagentId: Vitamin + Quantity: 4 + - ReagentId: Sugar + Quantity: 4 + - ReagentId: Holywater + Quantity: 48 - type: Sprite sprite: Objects/Specific/Hydroponics/holymelon.rsi - type: Produce @@ -2259,7 +2201,7 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - type: SliceableFood - count: 5 + count: 4 slice: FoodHolymelonSlice - type: Butcherable butcheringType: Knife @@ -2271,7 +2213,7 @@ - type: entity name: holymelon slice - parent: ProduceSliceBase + parent: [SolutionTiny, ProduceSliceBase] id: FoodHolymelonSlice description: Juicy golden and red slice. components: @@ -2283,22 +2225,22 @@ - watermelon - type: Sprite sprite: Objects/Specific/Hydroponics/holymelon.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Vitamin - Quantity: 1 - - ReagentId: Holywater - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 1 + - ReagentId: Vitamin + Quantity: 1 + - ReagentId: Sugar + Quantity: 1 + - ReagentId: Holywater + Quantity: 12 - type: Extractable juiceSolution: reagents: - ReagentId: Wine - Quantity: 4 + Quantity: 5 - type: Tag tags: - Fruit @@ -2318,15 +2260,15 @@ - type: FlavorProfile flavors: - grape - - type: SolutionContainerManager - solutions: - food: - maxVol: 9 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: JuiceGrape + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/grape.rsi - type: Item @@ -2351,15 +2293,15 @@ - type: FlavorProfile flavors: - berry - - type: SolutionContainerManager - solutions: - food: - maxVol: 11 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: JuiceBerry + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/berries.rsi - type: Item @@ -2395,15 +2337,13 @@ butcheringType: Knife spawned: - id: FoodBungoPit - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Enzyme - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Enzyme + Quantity: 10 - type: Sprite sprite: Objects/Specific/Hydroponics/bungo.rsi - type: Produce @@ -2433,15 +2373,14 @@ tags: - Recyclable - Trash - - type: SolutionContainerManager - solutions: - food: - maxVol: 7 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Bungotoxin - Quantity: 5 + - type: Solution + solution: + maxVol: 7.5 + reagents: + - ReagentId: Nutriment + Quantity: 2 + - ReagentId: Bungotoxin + Quantity: 5 - type: Extractable grindableSolutionName: food - type: Seed @@ -2458,15 +2397,13 @@ - type: FlavorProfile flavors: - peas - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Vitamin + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/pea.rsi - type: Item @@ -2490,17 +2427,15 @@ - type: FlavorProfile flavors: - numbingtranquility - - type: SolutionContainerManager - solutions: - food: - maxVol: 8 - reagents: - - ReagentId: Happiness - Quantity: 3 - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Pax - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Happiness + Quantity: 5 + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Pax + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/world_pea.rsi - type: Item @@ -2522,20 +2457,20 @@ description: A large, orange... berry. Seriously. components: - type: Item - size: Small + size: Normal heldPrefix: produce - type: FlavorProfile flavors: - pumpkin - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: PumpkinFlesh - Quantity: 20 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: PumpkinFlesh # Mostly empty space + Quantity: 20 + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/pumpkin.rsi - type: Produce @@ -2578,17 +2513,19 @@ - type: FlavorProfile flavors: - bluepumpkin - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Ammonia - Quantity: 10 - - ReagentId: Chlorine - Quantity: 5 - - ReagentId: Vitamin - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: PumpkinFlesh # Mostly empty space + Quantity: 20 + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Ammonia + Quantity: 10 + - ReagentId: Chlorine + Quantity: 10 + - ReagentId: Vitamin + Quantity: 10 - type: Extractable juiceSolution: reagents: @@ -2631,12 +2568,13 @@ - cotton - type: Edible requiresSpecialDigestion: true - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Fiber - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 5 + - ReagentId: Cellulose + Quantity: 10 - type: Log spawnedPrototype: MaterialCotton1 spawnCount: 2 @@ -2663,14 +2601,15 @@ - pyrotton - type: Edible requiresSpecialDigestion: true - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Fiber - Quantity: 5 - - ReagentId: Phlogiston - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 5 + - ReagentId: Phlogiston + Quantity: 5 + - ReagentId: Cellulose + Quantity: 5 - type: Log spawnedPrototype: MaterialPyrotton1 spawnCount: 2 @@ -2702,15 +2641,14 @@ butcheringType: Knife spawned: - id: TrashCherryPit - - type: SolutionContainerManager - solutions: - food: - maxVol: 8 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 3 + - type: Solution + solution: + maxVol: 15 + reagents: + - ReagentId: Nutriment + Quantity: 3.5 + - ReagentId: Vitamin + Quantity: 3.5 - type: Sprite sprite: Objects/Specific/Hydroponics/cherry.rsi - type: Produce @@ -2744,13 +2682,12 @@ tags: - Recyclable - Trash - - type: SolutionContainerManager - solutions: - food: - maxVol: 1 - reagents: - - ReagentId: Toxin - Quantity: 1 + - type: Solution + solution: + maxVol: 1 + reagents: + - ReagentId: Toxin + Quantity: 1 - type: Extractable grindableSolutionName: food - type: Seed @@ -2759,10 +2696,10 @@ - type: BadFood - type: entity + parent: [SolutionNormal, FoodProduceBase] # Anomalously large + id: FoodAnomalyBerry name: anomaly berry description: A strange blue fruit. Something about it doesn't seem right. - parent: FoodProduceBase - id: FoodAnomalyBerry components: - type: FlavorProfile flavors: @@ -2777,17 +2714,22 @@ - type: Edible trash: - EffectAnomalyFloraBulb # Random loot - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Vitamin - Quantity: 2 - - ReagentId: Artifexium - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Vitamin + Quantity: 20 + - ReagentId: JuiceBerry + Quantity: 20 + - ReagentId: Artifexium + Quantity: 1 + - type: Extractable + juiceSolution: + reagents: + - ReagentId: JuiceBerry + Quantity: 30 - type: Tag tags: - Fruit @@ -2799,7 +2741,7 @@ - type: entity name: bloonion bulb description: A strange floating bulb.. Nothing worth crying over. - parent: BaseStructureDynamic + parent: [SolutionCryo, BaseStructureDynamic, ProduceBase] id: FoodBloonion components: - type: Appearance @@ -2809,7 +2751,6 @@ sprite: Objects/Specific/Hydroponics/bloonion.rsi state: produce - type: Item - size: Small sprite: Objects/Specific/Hydroponics/bloonion.rsi heldPrefix: produce - type: Produce @@ -2822,22 +2763,19 @@ flavors: - onion - strange - - type: SolutionContainerManager - solutions: - food: - maxVol: 7 - canReact: false - reagents: - - ReagentId: Potassium - Quantity: 1 - - ReagentId: Phosphorus - Quantity: 1 - - ReagentId: Sugar - Quantity: 1 - - ReagentId: Allicin - Quantity: 4 - - type: Extractable - grindableSolutionName: food + - type: Solution + solution: + reagents: + - ReagentId: Potassium + Quantity: 1 + - ReagentId: Phosphorus + Quantity: 1 + - ReagentId: Sugar + Quantity: 3 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: Allicin + Quantity: 5 - type: ExplodeOnTrigger - type: Explosive explosionType: Default diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/skewer.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/skewer.yml index f49e3a1256..3f0245a985 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/skewer.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/skewer.yml @@ -56,11 +56,8 @@ - type: Edible trash: - FoodKebabSkewer - - type: SolutionContainerManager - solutions: - food: - canReact: false # Dont want cause reactions inside skewers after merging ingredients - maxVol: 0 + - type: Solution + id: food # I'm not having this inherit from basefood because this shouldn't be edible, nor have a solution until you attach an entity to it. - type: FoodSequenceStartPoint key: Skewer maxLayers: 4 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml index 27cc06023c..a59d7961aa 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml @@ -2,7 +2,7 @@ # Base - type: entity - parent: FoodBase + parent: [SolutionTiny, FoodBaseTrash] id: FoodSnackBase abstract: true components: @@ -11,13 +11,11 @@ - FoodSnack - type: Sprite sprite: Objects/Consumable/Food/snacks.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 # Room for extra condiments - reagents: - - ReagentId: Nutriment - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 - type: Item sprite: Objects/Consumable/Food/snacks.rsi heldPrefix: packet @@ -139,17 +137,15 @@ tags: - FoodSnack - ReptilianFood - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Theobromine - Quantity: 3 - - ReagentId: CocoaPowder - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Theobromine + Quantity: 3 + - ReagentId: CocoaPowder + Quantity: 2 - type: entity parent: FoodSnackBase @@ -314,15 +310,13 @@ solution: food - type: InjectableSolution solution: food - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 #big cup - reagents: - - ReagentId: DryRamen - Quantity: 30 - - ReagentId: Soysauce - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: DryRamen + Quantity: 20 + - ReagentId: Soysauce + Quantity: 5 - type: Sprite state: ramen - type: Edible @@ -338,15 +332,13 @@ name: hell ramen description: Super spicy flavor! components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 - reagents: - - ReagentId: DryRamen - Quantity: 30 - - ReagentId: CapsaicinOil - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: DryRamen + Quantity: 20 + - ReagentId: CapsaicinOil + Quantity: 5 - type: entity parent: FoodSnackBase @@ -364,15 +356,13 @@ - type: Item heldPrefix: chinese1 storedOffset: 1,-2 - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 # Room for extra condiments - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Soysauce - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Soysauce + Quantity: 2 - type: Edible trash: - FoodPacketChowMeinTrash @@ -393,17 +383,15 @@ - type: Item heldPrefix: chinese2 storedOffset: 0,-2 - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 # Room for extra condiments - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: CapsaicinOil - Quantity: 2 - - ReagentId: Soysauce - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: CapsaicinOil + Quantity: 2 + - ReagentId: Soysauce + Quantity: 2 - type: Edible trash: - FoodPacketDanDanTrash @@ -419,13 +407,12 @@ - fortunecookie - type: Sprite state: cookie_fortune - - type: SolutionContainerManager - solutions: - food: - maxVol: 1 - reagents: - - ReagentId: Nutriment - Quantity: 1 + - type: Solution + solution: + maxVol: 2.5 + reagents: + - ReagentId: Nutriment + Quantity: 1 - type: Item sprite: Objects/Consumable/Food/snacks.rsi heldPrefix: cookie_fortune @@ -476,13 +463,6 @@ - ReptilianFood - type: Sprite state: nutribrick-open - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 20 - type: entity parent: BaseItem @@ -508,7 +488,7 @@ path: /Audio/Effects/unwrap.ogg - type: entity - parent: FoodSnackBase + parent: [SolutionVeryTiny, FoodSnackBase] id: FoodSnackMREBrownieOpen name: brownie suffix: MRE @@ -522,15 +502,13 @@ - type: Item heldPrefix: mre-brownie-open storedOffset: -1,-1 - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Theobromine - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: Theobromine + Quantity: 1 - type: entity parent: FoodSnackBase @@ -551,13 +529,11 @@ tags: - FoodSnack - ReptilianFood - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 # Room for extra condiments - reagents: - - ReagentId: Sugar - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Sugar + Quantity: 15 - type: FlavorProfile flavors: - sweet @@ -573,7 +549,7 @@ - type: entity categories: [ HideSpawnMenu ] - parent: BaseItem + parent: [SolutionFood, SolutionVeryTiny, BaseItem] id: FoodPacketTrash description: This is rubbish. abstract: true @@ -592,13 +568,12 @@ - type: SpaceGarbage - type: StaticPrice price: 0 - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: ToxinTrash - Quantity: 5 + - type: Solution + solution: + maxVol: 7.5 + reagents: + - ReagentId: ToxinTrash + Quantity: 7.5 - type: Edible requiresSpecialDigestion: true @@ -861,13 +836,11 @@ components: - type: Edible requiresSpecialDigestion: true - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Fiber - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 10 - type: Tag tags: - ClothMade diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/soup.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/soup.yml index 0adee3d271..1a693d352e 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/soup.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/soup.yml @@ -1,8 +1,9 @@ # When adding new food also add to random spawner located in Resources\Prototypes\Entities\Markers\Spawners\Random\Food_Drinks\food_meal.yml +# This is actually soups AND salads. Wild. - type: entity abstract: true - parent: FoodInjectableBase + parent: [SolutionSmall, FoodInjectableBase] id: FoodBowlBase components: - type: Item @@ -13,13 +14,11 @@ trash: - FoodBowlBig utensil: Spoon - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 30 - type: Sprite sprite: Objects/Consumable/Food/bowl.rsi - type: DamageOnLand @@ -83,15 +82,15 @@ - state: bowl - state: alpha-filling color: green - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 30 + - ReagentId: Vitamin + Quantity: 15 + - ReagentId: Water + Quantity: 15 # Salad @@ -108,17 +107,15 @@ layers: - state: bowl - state: aesir - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 6 - - ReagentId: Omnizine - Quantity: 8 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 30 + - ReagentId: Vitamin + Quantity: 15 + - ReagentId: Omnizine + Quantity: 8 - type: Tag tags: - Soup @@ -138,19 +135,17 @@ layers: - state: bowl - state: herb - - type: SolutionContainerManager - solutions: - food: - maxVol: 70 - reagents: - - ReagentId: Nutriment - Quantity: 20 - - ReagentId: Kelotane - Quantity: 12 - - ReagentId: Bicaridine - Quantity: 12 - - ReagentId: Vitamin - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 19 + - ReagentId: Vitamin + Quantity: 11 + - ReagentId: Bicaridine + Quantity: 15 + - ReagentId: Kelotane + Quantity: 15 - type: Tag tags: - Fruit @@ -172,17 +167,19 @@ layers: - state: bowl - state: valid - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 25 - - ReagentId: DoctorsDelight - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 26 + - ReagentId: Vitamin + Quantity: 9 + - ReagentId: Bicaridine + Quantity: 10 + - ReagentId: Kelotane + Quantity: 10 + - ReagentId: Protein + Quantity: 5 - type: Tag tags: - Meat @@ -204,17 +201,17 @@ layers: - state: bowl - state: coleslaw - - type: SolutionContainerManager - solutions: - food: - maxVol: 45 - reagents: - - ReagentId: Nutriment - Quantity: 20 - - ReagentId: Vitamin - Quantity: 10 - - ReagentId: Allicin - Quantity: 8 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Vitamin + Quantity: 20 + - ReagentId: Allicin + Quantity: 10 + - ReagentId: Water + Quantity: 10 - type: entity name: caesar salad @@ -232,15 +229,17 @@ layers: - state: bowl - state: caesar - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 - reagents: - - ReagentId: Nutriment - Quantity: 15 - - ReagentId: Vitamin - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 31 + - ReagentId: Vitamin + Quantity: 6 + - ReagentId: Water + Quantity: 5 + - ReagentId: Allicin + Quantity: 1 - type: entity name: kimchi salad @@ -257,17 +256,21 @@ layers: - state: bowl - state: kimchi - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 15 - - ReagentId: Allicin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 16 + - ReagentId: Vitamin + Quantity: 21 + - ReagentId: Water + Quantity: 10 + - ReagentId: JuiceCarrot + Quantity: 5 + - ReagentId: Oculine + Quantity: 3 + - ReagentId: Allicin + Quantity: 4 - type: entity name: fruit salad @@ -282,15 +285,23 @@ layers: - state: bowl - state: fruit - - type: SolutionContainerManager - solutions: - food: - maxVol: 35 - reagents: - - ReagentId: Sugar - Quantity: 10 - - ReagentId: Vitamin - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 16 + - ReagentId: Vitamin + Quantity: 16 + - ReagentId: JuiceOrange + Quantity: 5 + - ReagentId: JuiceApple + Quantity: 5 + - ReagentId: JuiceGrape + Quantity: 5 + - ReagentId: Sugar + Quantity: 1 + - ReagentId: JuiceWatermelon + Quantity: 12 - type: Tag tags: - Fruit @@ -310,15 +321,23 @@ layers: - state: bowl - state: fruit - - type: SolutionContainerManager - solutions: - food: - maxVol: 35 - reagents: - - ReagentId: Sugar - Quantity: 8 - - ReagentId: Vitamin - Quantity: 17 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 19 + - ReagentId: Vitamin + Quantity: 13 + - ReagentId: JuiceBanana + Quantity: 5 + - ReagentId: JuiceApple + Quantity: 5 + - ReagentId: JuiceGrape + Quantity: 5 + - ReagentId: Sugar + Quantity: 1 + - ReagentId: JuiceWatermelon + Quantity: 12 - type: Tag tags: - Fruit @@ -338,15 +357,19 @@ layers: - state: bowl - state: citrusdelight - - type: SolutionContainerManager - solutions: - food: - maxVol: 38 - reagents: - - ReagentId: Nutriment - Quantity: 18 - - ReagentId: Vitamin - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 15 + - ReagentId: Vitamin + Quantity: 15 + - ReagentId: JuiceOrange + Quantity: 5 + - ReagentId: JuiceLemon + Quantity: 5 + - ReagentId: JuiceLime + Quantity: 5 - type: Tag tags: - Fruit @@ -366,17 +389,15 @@ layers: - state: bowl - state: eden - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: Omnizine - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 25 + - ReagentId: Vitamin + Quantity: 15 + - ReagentId: Omnizine + Quantity: 5 # Rice @@ -408,17 +429,19 @@ layers: - state: bowl - state: rice-egg - - type: SolutionContainerManager - solutions: - food: - maxVol: 35 - reagents: - - ReagentId: Nutriment - Quantity: 25 - - ReagentId: Vitamin - Quantity: 4 - - ReagentId: Protein - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 30 + - ReagentId: EggCooked + Quantity: 6 + - ReagentId: JuiceCarrot + Quantity: 5 + - ReagentId: Vitamin + Quantity: 7 + - ReagentId: Oculine + Quantity: 3 - type: Tag tags: - Meat @@ -438,19 +461,17 @@ layers: - state: bowl - state: rice-pork - - type: SolutionContainerManager - solutions: - food: - maxVol: 40.5 - reagents: - - ReagentId: Nutriment - Quantity: 18 - - ReagentId: Vitamin - Quantity: 7 - - ReagentId: Dexalin ##This is probably a reference to something but I don't get it - Quantity: 6.5 - - ReagentId: Epinephrine - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 42 + - ReagentId: Protein + Quantity: 6 + - ReagentId: Dexalin #This is probably a reference to something but I don't get it. Same. + Quantity: 6.5 + - ReagentId: Epinephrine + Quantity: 2 - type: Tag tags: - Meat @@ -470,19 +491,19 @@ layers: - state: bowl - state: rice-pudding - - type: SolutionContainerManager - solutions: - food: - maxVol: 25 - reagents: - - ReagentId: Nutriment - Quantity: 9 - - ReagentId: Vitamin - Quantity: 3 - - ReagentId: Milk ##This is probably a reference to something but I don't get it - Quantity: 5 - - ReagentId: Sugar - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Protein + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: Milk + Quantity: 5 + - ReagentId: Sugar + Quantity: 5 - type: entity name: black-eyed gumbo @@ -500,17 +521,17 @@ layers: - state: bowl - state: gumbo - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 15 - - ReagentId: CapsaicinOil - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 40 + - ReagentId: Protein + Quantity: 4 + - ReagentId: Vitamin + Quantity: 3 + - ReagentId: CapsaicinOil + Quantity: 10 - type: Tag tags: - Meat @@ -532,17 +553,6 @@ layers: - state: bowl - state: oatmeal - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 7 - - ReagentId: Vitamin - Quantity: 2 - - ReagentId: Milk - Quantity: 10 - type: entity name: space liberty duff @@ -575,15 +585,15 @@ - type: Sprite sprite: Objects/Consumable/Food/meals.rsi state: amanita-jelly - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Amatoxin - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: Amatoxin + Quantity: 30 + - ReagentId: Nutriment + Quantity: 15 + - ReagentId: Vodka + Quantity: 5 # Soup @@ -600,17 +610,21 @@ layers: - state: bowl - state: meatball - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 17 - - ReagentId: Water - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Protein + Quantity: 5 + - ReagentId: JuiceCarrot + Quantity: 5 + - ReagentId: Vitamin + Quantity: 12 + - ReagentId: Oculine + Quantity: 3 + - ReagentId: Water + Quantity: 10 - type: Tag tags: - Meat @@ -629,17 +643,6 @@ layers: - state: bowl - state: slime - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 1 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: Water - Quantity: 10 - type: entity name: tomato soup @@ -655,17 +658,13 @@ layers: - state: bowl - state: tomato - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Iron - Quantity: 10 - - ReagentId: Blood - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Blood + Quantity: 20 + - ReagentId: Vitamin + Quantity: 10 - type: Tag tags: - Fruit @@ -685,17 +684,15 @@ layers: - state: bowl - state: wingfangchu - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Protein - Quantity: 15 - - ReagentId: Soysauce - Quantity: 10 - - ReagentId: Vitamin - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Protein + Quantity: 10 + - ReagentId: Soysauce + Quantity: 10 - type: entity name: clown's tears @@ -710,19 +707,21 @@ layers: - state: bowl - state: clowntears - - type: SolutionContainerManager - solutions: - food: - maxVol: 55 - reagents: - - ReagentId: Nutriment - Quantity: 2 - - ReagentId: Vitamin - Quantity: 9 - - ReagentId: Water - Quantity: 10 - - ReagentId: Razorium - Quantity: 1 # silly + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 12 + - ReagentId: Vitamin + Quantity: 4 + - ReagentId: JuiceBanana + Quantity: 5 + - ReagentId: Honk + Quantity: 4 + - ReagentId: Silicon + Quantity: 5 + - ReagentId: Razorium + Quantity: 1 # silly - type: entity name: vegetable soup @@ -738,19 +737,17 @@ layers: - state: bowl - state: vegetable - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 15 - - ReagentId: Water - Quantity: 10 - - ReagentId: Oculine - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 25 + - ReagentId: Vitamin + Quantity: 17 + - ReagentId: JuiceCarrot + Quantity: 5 + - ReagentId: Oculine + Quantity: 3 - type: entity name: nettle soup @@ -765,21 +762,19 @@ layers: - state: bowl - state: nettle - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 15 - - ReagentId: Water - Quantity: 10 - - ReagentId: Omnizine - Quantity: 5 - - ReagentId: Histamine - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 12 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: Omnizine + Quantity: 3 + - ReagentId: SpaceDrugs + Quantity: 10 + - ReagentId: Histamine + Quantity: 3 - type: entity name: mystery soup @@ -808,19 +803,21 @@ layers: - state: bowl - state: chili-hot - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: CapsaicinOil - Quantity: 5 - - ReagentId: Vitamin - Quantity: 20 - - ReagentId: Allicin - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 14 + - ReagentId: CapsaicinOil + Quantity: 10 + - ReagentId: Vitamin + Quantity: 7 + - ReagentId: Protein + Quantity: 2 + - ReagentId: Allicin + Quantity: 1 + - ReagentId: Water + Quantity: 4 - type: Tag tags: - ChiliBowl @@ -840,22 +837,28 @@ layers: - state: bowl - state: chili-cold - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 8 - - ReagentId: Vitamin - Quantity: 25 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 14 + - ReagentId: FrostOil + Quantity: 10 + - ReagentId: Vitamin + Quantity: 7 + - ReagentId: Protein + Quantity: 2 + - ReagentId: Allicin + Quantity: 1 + - ReagentId: Water + Quantity: 4 - type: Tag tags: - ChiliBowl - type: entity name: chili con carnival - parent: FoodBowlBase + parent: FoodSoupChiliHot id: FoodSoupChiliClown description: A delicious stew of meat, chilies, and salty, salty clown tears. components: @@ -869,19 +872,6 @@ layers: - state: bowl - state: chili-clown - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 12 - - ReagentId: CapsaicinOil - Quantity: 5 - - ReagentId: Vitamin - Quantity: 20 - - ReagentId: Allicin - Quantity: 3 - type: Tag tags: - ChiliBowl @@ -900,19 +890,21 @@ layers: - state: bowl - state: monkeydelight - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 15 - - ReagentId: Vitamin - Quantity: 5 - - ReagentId: TableSalt - Quantity: 1 - - ReagentId: Blackpepper - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 25 + - ReagentId: Protein + Quantity: 10 + - ReagentId: Vitamin + Quantity: 2 + - ReagentId: JuiceBanana + Quantity: 5 + - ReagentId: TableSalt + Quantity: 1 + - ReagentId: Blackpepper + Quantity: 1 - type: Tag tags: - Meat @@ -931,17 +923,15 @@ layers: - state: bowl - state: tomato - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 20 - - ReagentId: Water - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 14 + - ReagentId: Vitamin + Quantity: 6 + - ReagentId: Water + Quantity: 10 - type: Tag tags: - Fruit @@ -961,15 +951,17 @@ layers: - state: bowl - state: eyeball - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 10 # Eyes are yummy - - ReagentId: Vitamin - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 # Eyes are yummy + - ReagentId: Vitamin + Quantity: 12 + - ReagentId: JuiceCarrot + Quantity: 5 + - ReagentId: Oculine + Quantity: 8 - type: Tag tags: - Meat @@ -992,17 +984,6 @@ - state: bowl2 - state: miso #rip milo - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 9 - - ReagentId: Vitamin - Quantity: 3 - - ReagentId: Water - Quantity: 10 - type: Tag tags: - Meat @@ -1021,19 +1002,15 @@ layers: - state: bowl - state: mushroom - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 20 - - ReagentId: Water - Quantity: 5 - - ReagentId: Milk - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 24 + - ReagentId: Vitamin + Quantity: 16 + - ReagentId: Milk + Quantity: 5 - type: entity name: beet soup @@ -1045,17 +1022,6 @@ layers: - state: bowl - state: beet - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 15 - - ReagentId: Vitamin - Quantity: 7 - - ReagentId: Water - Quantity: 10 # Tastes like borsch, bortsch, borstch, borsh, borshch, borscht. - type: entity @@ -1068,15 +1034,6 @@ layers: - state: bowl - state: redbeet - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 15 - - ReagentId: Vitamin - Quantity: 15 # Tastes like beet. - type: entity @@ -1094,17 +1051,19 @@ layers: - state: bowl - state: stew - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Protein - Quantity: 20 - - ReagentId: Vitamin - Quantity: 15 + - type: Solution + solution: + reagents: # This loses a lot of reagents because it takes so many ingredients, if you're refactoring cooking, redo these numbers. + - ReagentId: Nutriment + Quantity: 30 + - ReagentId: Protein + Quantity: 6 + - ReagentId: Vitamin + Quantity: 15 + - ReagentId: JuiceCarrot + Quantity: 5 + - ReagentId: Oculine + Quantity: 3 - type: Tag tags: - Meat @@ -1124,15 +1083,6 @@ layers: - state: bowl - state: sweetpotato - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 15 - - ReagentId: Vitamin - Quantity: 15 # Tastes like sweet potato. - type: entity @@ -1148,17 +1098,15 @@ layers: - state: bowl - state: onion - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 25 - - ReagentId: Allicin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: Allicin + Quantity: 5 - type: entity name: bisque @@ -1173,19 +1121,17 @@ layers: - state: bowl - state: bisque - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 5 - - ReagentId: Vitamin - Quantity: 15 - - ReagentId: Protein - Quantity: 5 - - ReagentId: Water - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 29 + - ReagentId: Vitamin + Quantity: 11 + - ReagentId: Protein + Quantity: 10 + - ReagentId: Water + Quantity: 5 # Tastes like crab. - type: entity @@ -1207,15 +1153,13 @@ layers: - state: bowl - state: electron - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 15 - - ReagentId: Licoxide - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 25 + - ReagentId: Licoxide + Quantity: 10 - type: entity name: bungo curry @@ -1230,17 +1174,15 @@ layers: - state: bowl - state: bungo - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 15 - - ReagentId: CapsaicinOil - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Vitamin + Quantity: 3 + - ReagentId: CapsaicinOil + Quantity: 10 - type: Tag tags: - Fruit @@ -1261,17 +1203,19 @@ layers: - state: bowl - state: escargot - - type: SolutionContainerManager - solutions: - food: - maxVol: 40 - reagents: - - ReagentId: Nutriment - Quantity: 15 - - ReagentId: Vitamin - Quantity: 15 - - ReagentId: Allicin - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 27 + - ReagentId: Protein + Quantity: 10 + - ReagentId: Butter + Quantity: 5 + - ReagentId: Vitamin + Quantity: 5 + - ReagentId: Allicin + Quantity: 5 - type: Tag tags: - Meat diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/taco.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/taco.yml index ff647216c0..c0fd9a3510 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/taco.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/taco.yml @@ -1,7 +1,7 @@ # When adding new food also add to random spawner located in Resources\Prototypes\Entities\Markers\Spawners\Random\Food_Drinks\food_single.yml - type: entity - parent: FoodMealBase + parent: [SolutionSmall, FoodMealBase] id: FoodTacoShell name: taco shell description: A taco shell, easy to hold, but falls on its side when put down. @@ -16,14 +16,12 @@ - state: tacoshell_back - map: ["foodSequenceLayers"] - state: tacoshell_forward - - type: SolutionContainerManager - solutions: - food: - canReact: false # Dont want cause reactions inside tacos after merging ingredients - maxVol: 10 - reagents: - - ReagentId: Nutriment - Quantity: 6.66 + - type: Solution + solution: + canReact: false # Dont want cause reactions inside tacos after merging ingredients, TODO KILL + reagents: + - ReagentId: Nutriment + Quantity: 10 - type: FoodSequenceStartPoint key: Taco maxLayers: 3 @@ -39,7 +37,7 @@ - type: entity abstract: true - parent: FoodInjectableBase + parent: [SolutionSmall, FoodInjectableBase] id: FoodTacoBase components: - type: FlavorProfile @@ -50,15 +48,13 @@ transferAmount: 3 - type: Sprite sprite: Objects/Consumable/Food/taco.rsi - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 4 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 29 + - ReagentId: Protein + Quantity: 2 - type: Item sprite: Objects/Consumable/Food/taco.rsi shape: @@ -98,15 +94,17 @@ - fishy - type: Sprite state: fishtaco - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 42 + - ReagentId: Protein + Quantity: 2 + - ReagentId: Allicin + Quantity: 1 + - ReagentId: Vitamin + Quantity: 9 - type: entity name: rat taco @@ -116,15 +114,6 @@ components: - type: Sprite state: rattaco - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 6 - - ReagentId: Vitamin - Quantity: 4 - type: entity name: beef taco supreme @@ -134,15 +123,17 @@ components: - type: Sprite state: beeftacosupreme - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Nutriment - Quantity: 22 - - ReagentId: Vitamin - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 42 + - ReagentId: Protein + Quantity: 2 + - ReagentId: Allicin + Quantity: 1 + - ReagentId: Vitamin + Quantity: 9 - type: entity name: chicken taco supreme @@ -152,15 +143,17 @@ components: - type: Sprite state: chickentacosupreme - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Nutriment - Quantity: 22 - - ReagentId: Vitamin - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 42 + - ReagentId: Protein + Quantity: 2 + - ReagentId: Allicin + Quantity: 1 + - ReagentId: Vitamin + Quantity: 9 - type: entity parent: FoodTacoBase @@ -176,19 +169,19 @@ - spicy - type: Sprite state: dragontaco - - type: SolutionContainerManager - solutions: - food: - maxVol: 32 - reagents: - - ReagentId: Nutriment - Quantity: 14 - - ReagentId: Vitamin - Quantity: 4 - - ReagentId: Ichor - Quantity: 4 - - ReagentId: CapsaicinOil - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 18 + - ReagentId: Protein + Quantity: 6 + - ReagentId: Ichor + Quantity: 2 + - ReagentId: CapsaicinOil + Quantity: 10 + - ReagentId: Vitamin + Quantity: 3 - type: entity name: soft taco @@ -204,15 +197,6 @@ - onion - type: Sprite state: softtaco - - type: SolutionContainerManager - solutions: - food: - maxVol: 30 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 18 - type: Tag tags: - Meat diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml index e9a54e6867..30f03b8703 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/cigarette.yml @@ -58,10 +58,6 @@ state: burnt-icon - type: Smokable state: Burnt - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 20 - type: Tag tags: - Cigarette @@ -74,387 +70,335 @@ parent: Cigarette name: cigarette components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Omnizine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Omnizine + Quantity: 20 - type: entity id: CigaretteOmnizine parent: SoakedCigarette name: Hot Dog Water Flavor Explosion components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Omnizine - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Omnizine + Quantity: 10 - type: entity id: CigaretteIron parent: SoakedCigarette name: Rusty Orange Baja Blast components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Iron - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Iron + Quantity: 10 - type: entity id: CigaretteTricordrazine parent: SoakedCigarette name: Licorice Allsorts components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Tricordrazine - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Tricordrazine + Quantity: 10 - type: entity id: CigaretteDylovene parent: SoakedCigarette name: Urinal Cake Dissolver components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Dylovene - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Dylovene + Quantity: 10 - type: entity id: CigaretteDermaline parent: SoakedCigarette name: Aloe Peanut Butter Medley components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Dermaline - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Dermaline + Quantity: 10 - type: entity id: CigaretteArithrazine parent: SoakedCigarette name: Roman Pipe Works components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Arithrazine - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Arithrazine + Quantity: 10 - type: entity id: CigaretteNutriment parent: SoakedCigarette name: Grandma's Christmas Fruitcake components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Nutriment - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Nutriment + Quantity: 10 - type: entity id: CigaretteBicaridine parent: SoakedCigarette name: Wet Dog Enhanced Cigarette components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Bicaridine - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Bicaridine + Quantity: 10 - type: entity id: CigaretteDexalin parent: SoakedCigarette name: Rocky Mountain Musk components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Dexalin - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Dexalin + Quantity: 10 - type: entity id: CigaretteSaline parent: SoakedCigarette name: North Atlantic Cruise components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Saline - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Saline + Quantity: 10 - type: entity id: CigaretteBbqSauce parent: SoakedCigarette name: Spicy Wood Aroma components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: BbqSauce - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: BbqSauce + Quantity: 10 - type: entity id: CigaretteFrezon parent: SoakedCigarette name: Atmospheric Adventure components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Frezon - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Frezon + Quantity: 10 - type: entity id: CigaretteCapsaicinOil parent: SoakedCigarette name: Chilly P components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: CapsaicinOil - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: CapsaicinOil + Quantity: 10 - type: entity id: CigaretteRadium parent: SoakedCigarette name: Ex Ray components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Radium - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Radium + Quantity: 10 - type: entity id: CigaretteHaloperidol parent: SoakedCigarette name: Warm Bovine Extract components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Haloperidol - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Haloperidol + Quantity: 10 - type: entity id: CigaretteLaughter parent: SoakedCigarette name: Clown Adjacency Bonus components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Laughter - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Laughter + Quantity: 10 - type: entity id: CigaretteLipolicide parent: SoakedCigarette name: 80's Workout Routine components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Lipolicide - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Lipolicide + Quantity: 10 - type: entity id: CigaretteSodiumPolyacrylate parent: SoakedCigarette name: Unhealthy Habits components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: SodiumPolyacrylate - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: SodiumPolyacrylate + Quantity: 10 - type: entity id: CigaretteMold parent: SoakedCigarette name: Beneath The Sink Experience components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Mold - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Mold + Quantity: 10 - type: entity id: CigaretteLicoxide parent: SoakedCigarette name: Wake Up Call components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Licoxide - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Licoxide + Quantity: 10 - type: entity id: CigaretteWeldingFuel parent: SoakedCigarette name: Plasma Sauce components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: WeldingFuel - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: WeldingFuel + Quantity: 10 - type: entity id: CigaretteRobustHarvest parent: SoakedCigarette name: Hippie Romance Novel components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: RobustHarvest - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: RobustHarvest + Quantity: 10 - type: entity id: CigarettePhlogiston parent: SoakedCigarette name: Dragon Dating Sim components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Phlogiston - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Phlogiston + Quantity: 10 - type: entity id: CigaretteBanana parent: SoakedCigarette name: Pun Pun's Tropical Getaway components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Potassium - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Potassium + Quantity: 10 - type: entity id: CigaretteBlackPepper parent: SoakedCigarette name: English Spice components: - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 40 - reagents: - - ReagentId: Nicotine - Quantity: 10 - - ReagentId: Blackpepper - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 + - ReagentId: Blackpepper + Quantity: 10 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/joints.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/joints.yml index 25d6865f20..d1515f611d 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/joints.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/joints.yml @@ -21,13 +21,11 @@ - type: Construction graph: smokeableJoint node: joint - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 30 - reagents: - - ReagentId: THC - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: THC + Quantity: 20 - type: RandomMetadata nameSegments: [NamesRollie] @@ -41,23 +39,21 @@ - type: Construction graph: smokeableJointRainbow node: jointRainbow - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 20 - reagents: - - ReagentId: SpaceDrugs - Quantity: 4 - - ReagentId: Lipolicide - Quantity: 4 - - ReagentId: MindbreakerToxin - Quantity: 2.66 - - ReagentId: Happiness - Quantity: 2.66 -# - ReagentId: ColorfulReagent -# Quantity: 1.33 - - ReagentId: Psicodine - Quantity: 0.8 + - type: Solution + solution: + reagents: + - ReagentId: SpaceDrugs + Quantity: 10 + - ReagentId: Lipolicide + Quantity: 5 + - ReagentId: MindbreakerToxin + Quantity: 5 + - ReagentId: Happiness + Quantity: 5 + # - ReagentId: ColorfulReagent + # Quantity: 1.33 + - ReagentId: Psicodine + Quantity: 3.67 - type: entity id: Blunt @@ -82,13 +78,11 @@ - type: Construction graph: smokeableBlunt node: blunt - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 30 - reagents: - - ReagentId: THC - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: THC + Quantity: 20 - type: RandomMetadata nameSegments: [NamesRollie] @@ -102,20 +96,18 @@ - type: Construction graph: smokeableBluntRainbow node: bluntRainbow - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 20 - reagents: - - ReagentId: SpaceDrugs - Quantity: 4 - - ReagentId: Lipolicide - Quantity: 4 - - ReagentId: MindbreakerToxin - Quantity: 2.66 - - ReagentId: Happiness - Quantity: 2.66 -# - ReagentId: ColorfulReagent -# Quantity: 1.33 - - ReagentId: Psicodine - Quantity: 0.8 + - type: Solution + solution: + reagents: + - ReagentId: SpaceDrugs + Quantity: 10 + - ReagentId: Lipolicide + Quantity: 5 + - ReagentId: MindbreakerToxin + Quantity: 5 + - ReagentId: Happiness + Quantity: 5 + # - ReagentId: ColorfulReagent + # Quantity: 1.33 + - ReagentId: Psicodine + Quantity: 3.67 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml index a17bedd446..b2479f0765 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigars/cigar.yml @@ -29,10 +29,6 @@ state: burnt-icon - type: Smokable state: Burnt - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 20 - type: Tag tags: - Cigar @@ -64,7 +60,3 @@ state: burnt-icon - type: Smokable state: Burnt - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 20 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/base_smokeables.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/base_smokeables.yml index 39baa36b8b..e10996b39b 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/base_smokeables.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/base_smokeables.yml @@ -1,7 +1,7 @@ - type: entity description: "If you want to get cancer, might as well do it in style." id: BaseSmokable - parent: BaseItem + parent: [SolutionSmokable, SolutionTiny, BaseItem] abstract: true components: - type: Reactive @@ -33,13 +33,11 @@ - type: Tag tags: - Trash - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 20 - reagents: - - ReagentId: Nicotine - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 - type: entity parent: BaseSmokable @@ -62,13 +60,9 @@ path: /Audio/Weapons/Guns/Empty/empty.ogg ejectSound: path: /Audio/Weapons/Guns/Empty/empty.ogg - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 30 - type: entity - parent: BaseItem + parent: [SolutionSmokable, SolutionTiny, BaseItem] id: BaseVape abstract: true components: @@ -76,10 +70,6 @@ damage: types: Heat: 2 - - type: SolutionContainerManager - solutions: - smokable: - maxVol: 10 - type: RefillableSolution solution: smokable - type: ExaminableSolution diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_wind.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_wind.yml index 3247728b5f..6efa7080c5 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_wind.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_wind.yml @@ -24,13 +24,14 @@ - type: Sprite sprite: Objects/Fun/Instruments/saxophone.rsi - type: Extractable - grindableSolutionName: sax - - type: SolutionContainerManager - solutions: - sax: - reagents: - - ReagentId: Saxoite - Quantity: 10 + grindableSolutionName: instrument + - type: Solution + id: instrument + solution: + maxVol: 20 # Based on material balance and not container balance so no size parent. + reagents: + - ReagentId: Brass + Quantity: 10 - type: entity parent: BaseWoodwindInstrument @@ -49,7 +50,7 @@ slots: - neck - type: ActivatableUI - inHandsOnly: false + inHandsOnly: false - type: entity parent: BaseWoodwindInstrument diff --git a/Resources/Prototypes/Entities/Objects/Fun/Plushies/plushies.yml b/Resources/Prototypes/Entities/Objects/Fun/Plushies/plushies.yml index 55994be348..b25c3cc993 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Plushies/plushies.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Plushies/plushies.yml @@ -4,7 +4,7 @@ - type: entity abstract: true - parent: [BaseItem, BaseStash] + parent: [SolutionFood, SolutionSmall, BaseItem, BaseStash] id: BasePlushie components: - type: EmitSoundOnUse @@ -39,13 +39,11 @@ requiresSpecialDigestion: true useSound: *BasePlushieSound delay: 2 - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Fiber - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 30 - type: Tag tags: - Payload @@ -70,7 +68,6 @@ entries: CottonBurger: ThronglerPlushie - - type: entity parent: BasePlushie id: PlushieGhost @@ -148,20 +145,14 @@ size: Normal sprite: Objects/Fun/Plushies/bee.rsi - type: Extractable - grindableSolutionName: bee - - type: SolutionContainerManager - solutions: - bee: - reagents: - - ReagentId: GroundBee - Quantity: 10 - food: - maxVol: 10 - reagents: - - ReagentId: GroundBee - Quantity: 5 - - ReagentId: Fiber - Quantity: 5 + grindableSolutionName: food + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 25 + - ReagentId: GroundBee + Quantity: 5 - type: Clothing quickEquip: false sprite: Objects/Fun/Plushies/bee.rsi @@ -357,20 +348,6 @@ transferAmount: 10 - type: MeleeWeapon soundHit: *PlushieLizardSound - - type: Extractable - juiceSolution: - reagents: - - ReagentId: JuiceThatMakesYouWeh - Quantity: 30 - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Fiber - Quantity: 10 - - ReagentId: JuiceThatMakesYouWeh - Quantity: 10 - type: Clothing quickEquip: false sprite: Objects/Fun/Plushies/lizard.rsi @@ -386,6 +363,18 @@ - Payload - ClothMade - PlushieLizard + - type: Extractable + juiceSolution: + reagents: + - ReagentId: JuiceThatMakesYouWeh + Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 20 + - ReagentId: JuiceThatMakesYouWeh + Quantity: 10 - type: entity parent: BasePlushie @@ -549,15 +538,13 @@ reagents: - ReagentId: JuiceThatMakesYouHew Quantity: 30 - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Fiber - Quantity: 10 - - ReagentId: JuiceThatMakesYouHew - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 20 + - ReagentId: JuiceThatMakesYouHew + Quantity: 10 - type: Clothing quickEquip: false sprite: Objects/Fun/Plushies/lizard.rsi @@ -568,10 +555,9 @@ entries: CottonBurger: InversedLizardPlushie - - type: entity parent: BasePlushie - id: PlushieDiona + id: PlushieDiona # TODO Better way of doing the flowering visuals. Probably make it an "AppearanceChangeEntityEffect" on reactive? name: diona plushie description: An adorable stuffed toy that resembles a diona. Love water and cuddles. Do not wet! components: @@ -599,13 +585,6 @@ soundHit: *PlushieDionaSound - type: Edible useSound: *PlushieDionaSound - - type: SolutionContainerManager - solutions: - food: - maxVol: 11 - reagents: - - ReagentId: Fiber - Quantity: 10 - type: RefillableSolution solution: food - type: SolutionContainerVisuals @@ -621,7 +600,7 @@ effects: - !type:AddReagentToSolution reagent: Water - solution: plushie + solution: food - type: Fixtures fixtures: fix1: diff --git a/Resources/Prototypes/Entities/Objects/Fun/crayons.yml b/Resources/Prototypes/Entities/Objects/Fun/crayons.yml index 7a67993df7..a585fae134 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/crayons.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/crayons.yml @@ -2,7 +2,7 @@ - type: entity abstract: true - parent: BaseItem + parent: [SolutionFood, SolutionVeryTiny, BaseItem] # Crayons are less pourous than most foods, so we just assume they have less capacity. id: CrayonInedible name: crayon description: A colourful crayon. A forbidden flavor. @@ -41,14 +41,13 @@ flavors: - chewy - bitter - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: MindbreakerToxin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: MindbreakerToxin + Quantity: 10 # special crayons diff --git a/Resources/Prototypes/Entities/Objects/Fun/darts.yml b/Resources/Prototypes/Entities/Objects/Fun/darts.yml index 9ecf62715e..6eebd41731 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/darts.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/darts.yml @@ -1,5 +1,5 @@ - type: entity - parent: BaseItem + parent: [BaseItem, SolutionDart] id: Dart name: dart description: Light throwing dart for playing darts. Don't get in the eye! @@ -44,10 +44,6 @@ - type: Item size: Tiny sprite: Objects/Fun/Darts/dart_red.rsi - - type: SolutionContainerManager - solutions: - melee: - maxVol: 2 - type: MeleeChemicalInjector solution: melee - type: RefillableSolution @@ -87,6 +83,16 @@ acts: [ "Destruction" ] - type: BalloonPopper +- type: entity + parent: Solution + id: SolutionDart + categories: [ HideSpawnMenu ] # Not abstract so weapons with multiple solutions can exist + components: + - type: Solution + id: melee + solution: + maxVol: 2 + - type: entity parent: Dart id: DartBlue @@ -119,10 +125,9 @@ id: HypoDart suffix: HypoDart components: - - type: SolutionContainerManager - solutions: - melee: - maxVol: 10 + - type: Solution + solution: + maxVol: 10 - type: SolutionInjectOnEmbed transferAmount: 10 blockSlots: NONE diff --git a/Resources/Prototypes/Entities/Objects/Fun/orbs.yml b/Resources/Prototypes/Entities/Objects/Fun/orbs.yml index 3f04c6b80b..f91dd8e031 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/orbs.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/orbs.yml @@ -134,13 +134,11 @@ - type: DeviceLinkSink ports: - Trigger - - type: SolutionContainerManager - solutions: - magic9ball: - maxVol: 20 - reagents: - - ReagentId: Ethanol - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Ethanol + Quantity: 30 - type: Damageable - type: Injurable damageContainer: Inorganic @@ -169,7 +167,7 @@ params: volume: -4 - !type:SpillBehavior - solution: magic9ball + solution: solution - !type:DoActsBehavior acts: [ "Destruction" ] - type: PhysicalComposition diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index 112f9e8f58..ce3eaa20aa 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -65,7 +65,7 @@ - type: Dumpable - type: entity - parent: FoodProduceBase + parent: [SolutionSmall, FoodProduceBase] id: PlasticBanana name: banana suffix: Plastic @@ -77,18 +77,17 @@ flavors: - plastic - type: Edible - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nothing - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: Nothing + Quantity: 30 - type: Tag tags: - Banana - type: entity - parent: DrinkBase + parent: [SolutionSmall, DrinkBase] id: CrazyGlue name: crazy glue description: A bottle of crazy glue manufactured by Honk! Co. @@ -110,13 +109,11 @@ consumptionUnit: 10 - type: Item sprite: Objects/Fun/glue.rsi - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - reagents: - - ReagentId: SpaceGlue - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: SpaceGlue + Quantity: 60 - type: Openable sound: collection: packetOpenSounds @@ -124,7 +121,7 @@ solution: drink - type: entity - parent: DrinkBase + parent: [SolutionSmall, DrinkBase] id: CrazyLube name: crazy lube description: A bottle of super slipery crazy lube manufactured by Honk! Co. @@ -138,13 +135,11 @@ - state: icon map: ["enum.OpenableVisuals.Layer"] - type: Appearance - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - reagents: - - ReagentId: SpaceLube - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: SpaceLube + Quantity: 60 - type: GenericVisualizer visuals: enum.OpenableVisuals.Opened: @@ -197,7 +192,7 @@ sprite: Objects/Fun/mrdips.rsi - type: entity - parent: BaseItem + parent: [ SolutionFood, SolutionSmall, BaseItem ] id: Error name: error description: Hmmmm. Something went wrong. @@ -206,13 +201,13 @@ sprite: error.rsi state: error - type: Edible - - type: SolutionContainerManager - solutions: - food: - maxVol: 26 - reagents: - - ReagentId: Nutriment - Quantity: 5 + - type: Solution + id: food + solution: + maxVol: 26 # I'm assuming these values are some kind of reference so I'm leaving them as is + reagents: + - ReagentId: Nutriment + Quantity: 5 - type: Slippery slipData: knockdownTime: 3 diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml index 5ae1f06089..0856fd0d83 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: BaseItem + parent: BaseSheet id: SheetGlassBase name: glass description: A sheet of glass, used often on the station in various applications. @@ -9,19 +9,8 @@ sprite: Objects/Materials/Sheets/glass.rsi - type: Item sprite: Objects/Materials/Sheets/glass.rsi - size: Normal - - type: StaticPrice - price: 0 - - type: Tag - tags: - - Sheet - - ConstructionMaterial - - type: Material - type: Damageable damageModifierSet: Glass - - type: Injurable - damageContainer: Inorganic - - type: Appearance - type: Destructible thresholds: - trigger: @@ -46,10 +35,6 @@ max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - - type: SolutionContainerManager - solutions: - glass: - canReact: false - type: entity parent: SheetGlassBase @@ -79,14 +64,11 @@ - type: Construction graph: Glass node: SheetGlass - - type: Extractable - grindableSolutionName: glass - - type: SolutionContainerManager - solutions: - glass: - reagents: - - ReagentId: Silicon - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Silicon + Quantity: 10 - type: entity parent: SheetGlass @@ -164,6 +146,16 @@ max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] + - type: Solution + solution: + maxVol: 15 + reagents: + - ReagentId: Silicon + Quantity: 10 + - ReagentId: Iron + Quantity: 4.5 + - ReagentId: Carbon + Quantity: 0.5 - type: entity parent: SheetRGlass @@ -176,19 +168,6 @@ - type: Stack stackType: ReinforcedGlass count: 1 - - type: Extractable - grindableSolutionName: rglass - - type: SolutionContainerManager - solutions: - rglass: - reagents: - - ReagentId: Silicon - Quantity: 10 - - ReagentId: Iron - Quantity: 4.5 - - ReagentId: Carbon - Quantity: 0.5 - canReact: false - type: entity parent: SheetGlassBase @@ -241,6 +220,14 @@ max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] + - type: Solution + solution: + maxVol: 20 + reagents: + - ReagentId: Silicon + Quantity: 10 + - ReagentId: Plasma + Quantity: 10 - type: entity parent: SheetPGlass @@ -253,17 +240,6 @@ - type: Stack stackType: PlasmaGlass count: 1 - - type: Extractable - grindableSolutionName: pglass - - type: SolutionContainerManager - solutions: - pglass: - reagents: - - ReagentId: Silicon - Quantity: 10 - - ReagentId: Plasma - Quantity: 10 - canReact: false - type: entity parent: SheetPGlass @@ -292,21 +268,18 @@ - type: Construction graph: Glass node: SheetRPGlass - - type: Extractable - grindableSolutionName: rpglass - - type: SolutionContainerManager - solutions: - rpglass: - reagents: - - ReagentId: Silicon - Quantity: 10 - - ReagentId: Plasma - Quantity: 10 - - ReagentId: Iron - Quantity: 4.5 - - ReagentId: Carbon - Quantity: 0.5 - canReact: false + - type: Solution + solution: + maxVol: 25 + reagents: + - ReagentId: Silicon + Quantity: 10 + - ReagentId: Plasma + Quantity: 10 + - ReagentId: Iron + Quantity: 4.5 + - ReagentId: Carbon + Quantity: 0.5 - type: entity parent: SheetRPGlass @@ -371,17 +344,14 @@ max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - - type: Extractable - grindableSolutionName: uglass - - type: SolutionContainerManager - solutions: - uglass: - reagents: - - ReagentId: Silicon - Quantity: 10 - - ReagentId: Uranium - Quantity: 10 - canReact: false + - type: Solution + solution: + maxVol: 20 + reagents: + - ReagentId: Silicon + Quantity: 10 + - ReagentId: Uranium + Quantity: 10 - type: entity parent: SheetUGlass @@ -421,21 +391,18 @@ - type: Construction graph: Glass node: SheetRUGlass - - type: Extractable - grindableSolutionName: ruglass - - type: SolutionContainerManager - solutions: - ruglass: - reagents: - - ReagentId: Silicon - Quantity: 10 - - ReagentId: Uranium - Quantity: 10 - - ReagentId: Iron - Quantity: 4.5 - - ReagentId: Carbon - Quantity: 0.5 - canReact: false + - type: Solution + solution: + maxVol: 25 + reagents: + - ReagentId: Silicon + Quantity: 10 + - ReagentId: Uranium + Quantity: 10 + - ReagentId: Iron + Quantity: 4.5 + - ReagentId: Carbon + Quantity: 0.5 - type: entity parent: SheetRUGlass @@ -500,19 +467,16 @@ max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - - type: Extractable - grindableSolutionName: cglass - - type: SolutionContainerManager - solutions: - cglass: - reagents: - - ReagentId: Silicon - Quantity: 10 - - ReagentId: Zinc - Quantity: 3.3 - - ReagentId: Copper - Quantity: 6.7 - canReact: false + - type: Solution + solution: + maxVol: 20 + reagents: + - ReagentId: Silicon + Quantity: 10 + - ReagentId: Zinc + Quantity: 3.3 + - ReagentId: Copper + Quantity: 6.7 - type: entity parent: SheetClockworkGlass diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml index fad87e7f69..357fe7ddd3 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: BaseItem + parent: BaseSheet id: SheetMetalBase description: A sheet of metal, used often on the station in various applications. components: @@ -8,9 +8,6 @@ sprite: Objects/Materials/Sheets/metal.rsi - type: Item sprite: Objects/Materials/Sheets/metal.rsi - size: Normal - - type: StaticPrice - price: 0 - type: Tag tags: - Sheet @@ -18,20 +15,6 @@ - ConstructionMaterial - type: Damageable damageModifierSet: Metallic - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - type: SolutionContainerManager - solutions: - steel: - canReact: false - type: GuideHelp guides: - ExpandingRepairingStation @@ -60,17 +43,13 @@ map: ["base"] - type: Item heldPrefix: steel - - type: Appearance - - type: Extractable - grindableSolutionName: steel - - type: SolutionContainerManager - solutions: - steel: - reagents: - - ReagentId: Iron - Quantity: 9 - - ReagentId: Carbon - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Iron + Quantity: 9 + - ReagentId: Carbon + Quantity: 1 - type: entity parent: SheetSteel @@ -103,7 +82,6 @@ description: A sheet of brass, primarily used by clockwork enthusiasts and the remnants of Ratvarian cults. suffix: Full components: - - type: Material - type: PhysicalComposition materialComposition: Brass: 100 @@ -121,20 +99,16 @@ map: ["base"] - type: Item heldPrefix: brass - - type: Appearance - type: FloorTile outputs: - PlatingBrass - - type: Extractable - grindableSolutionName: brass - - type: SolutionContainerManager - solutions: - brass: - reagents: - - ReagentId: Zinc - Quantity: 3.3 - - ReagentId: Copper - Quantity: 6.7 + - type: Solution + solution: + reagents: + - ReagentId: Zinc + Quantity: 3.3 + - ReagentId: Copper + Quantity: 6.7 - type: entity parent: SheetBrass @@ -166,7 +140,6 @@ name: plasteel suffix: Full components: - - type: Material - type: PhysicalComposition materialComposition: Plasteel: 100 @@ -184,20 +157,16 @@ map: ["base"] - type: Item heldPrefix: plasteel - - type: Appearance - - type: Extractable - grindableSolutionName: plasteel - - type: SolutionContainerManager - solutions: - plasteel: - reagents: - - ReagentId: Plasma - Quantity: 10 - - ReagentId: Iron - Quantity: 9 - - ReagentId: Carbon - Quantity: 1 - canReact: false + - type: Solution + solution: + maxVol: 20 + reagents: + - ReagentId: Plasma + Quantity: 10 + - ReagentId: Iron + Quantity: 9 + - ReagentId: Carbon + Quantity: 1 - type: entity parent: SheetPlasteel diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml index 280c1f71bf..387be2348c 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: BaseItem + parent: BaseSheet id: SheetOtherBase description: A sheet of material, used often on the station in various applications. components: @@ -8,26 +8,6 @@ sprite: Objects/Materials/Sheets/other.rsi - type: Item sprite: Objects/Materials/Sheets/other.rsi - size: Normal - - type: Tag - tags: - - Sheet - - ConstructionMaterial - - type: Damageable - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - type: SolutionContainerManager - solutions: - paper: - canReact: false - type: entity parent: SheetOtherBase @@ -42,7 +22,6 @@ - paper - paper_2 - paper_3 - - type: Material - type: PhysicalComposition materialComposition: Paper: 100 @@ -53,16 +32,11 @@ map: ["base"] - type: Item heldPrefix: paper - - type: Appearance - - type: Extractable - grindableSolutionName: paper - - type: SolutionContainerManager - solutions: - paper: - reagents: - - ReagentId: Cellulose - Quantity: 3 - + - type: Solution + solution: + reagents: + - ReagentId: Cellulose + Quantity: 5 - type: entity parent: SheetPaper @@ -81,7 +55,6 @@ name: plasma suffix: Full components: - - type: Material - type: PhysicalComposition materialComposition: Plasma: 100 @@ -99,16 +72,11 @@ map: ["base"] - type: Item heldPrefix: plasma - - type: Appearance - - type: Extractable - grindableSolutionName: plasma - - type: SolutionContainerManager - solutions: - plasma: - reagents: - - ReagentId: Plasma - Quantity: 10 - canReact: false + - type: Solution + solution: + reagents: + - ReagentId: Plasma + Quantity: 10 - type: entity parent: SheetPlasma @@ -142,7 +110,6 @@ - Plastic - Sheet - ConstructionMaterial - - type: Material - type: PhysicalComposition materialComposition: Plastic: 100 @@ -160,18 +127,13 @@ map: ["base"] - type: Item heldPrefix: plastic - - type: Appearance - - type: Extractable - grindableSolutionName: plastic - - type: SolutionContainerManager - solutions: - plastic: - reagents: - - ReagentId: Oil - Quantity: 5 - - ReagentId: Phosphorus - Quantity: 5 - canReact: false + - type: Solution + solution: + reagents: + - ReagentId: Oil + Quantity: 5 + - ReagentId: Phosphorus + Quantity: 5 - type: entity parent: SheetPlastic @@ -196,14 +158,14 @@ count: 1 - type: entity - parent: [SheetOtherBase, EdibleBase] + parent: [SheetOtherBase, FoodBase] id: SheetUranium name: uranium suffix: Full components: - - type: Material - type: Edible transferAmount: 10 + solution: composite - type: BadFood - type: PhysicalComposition materialComposition: @@ -220,20 +182,15 @@ layers: - state: uranium_3 map: ["base"] - - type: Appearance - type: Item heldPrefix: uranium - - type: Extractable - grindableSolutionName: food - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Uranium - Quantity: 8 - - ReagentId: Radium - Quantity: 2 - canReact: false + - type: Solution + solution: + reagents: + - ReagentId: Uranium + Quantity: 8 + - ReagentId: Radium + Quantity: 2 - type: entity parent: SheetUranium @@ -272,17 +229,13 @@ - type: Item sprite: Objects/Materials/Sheets/meaterial.rsi heldPrefix: meat - - type: Extractable - grindableSolutionName: meatsheet - - type: SolutionContainerManager - solutions: - meatsheet: - reagents: - - ReagentId: Protein - Quantity: 7 - - ReagentId: Fat - Quantity: 3 - canReact: false + - type: Solution + solution: + reagents: + - ReagentId: Protein + Quantity: 7 + - ReagentId: Fat + Quantity: 3 - type: entity parent: MaterialSheetMeat diff --git a/Resources/Prototypes/Entities/Objects/Materials/base.yml b/Resources/Prototypes/Entities/Objects/Materials/base.yml new file mode 100644 index 0000000000..0d49a037b5 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Materials/base.yml @@ -0,0 +1,41 @@ +- type: entity + abstract: true + parent: [SolutionCryo, SolutionCompositeNormalStackable, BaseItem] + id: MaterialBase + description: A raw material. + components: + - type: Appearance + - type: Sprite + sprite: Objects/Materials/materials.rsi + - type: Item + sprite: Objects/Materials/materials.rsi + size: Normal + - type: Material + - type: Tag + tags: + - RawMaterial + - type: Damageable + - type: Injurable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: Extractable + grindableSolutionName: composite + +- type: entity + abstract: true + parent: MaterialBase + id: BaseSheet + components: + - type: Tag + tags: + - Sheet + - ConstructionMaterial + - type: StaticPrice + price: 0 diff --git a/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml b/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml index 57fa544df1..b7057b7912 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: BaseItem + parent: MaterialBase id: ShardCrystalBase name: crystal shard description: A small piece of crystal. @@ -28,16 +28,6 @@ Slash: 3.5 - type: Damageable damageModifierSet: Glass - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: StaticPrice price: 50 diff --git a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml index 77e39bfb9d..feb79ff44b 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: BaseItem + parent: MaterialBase id: IngotBase description: A heavy metal ingot stamped with the Nanotrasen logo. components: @@ -8,9 +8,6 @@ sprite: Objects/Materials/ingots.rsi - type: Item sprite: Objects/Materials/ingots.rsi - size: Normal - - type: StaticPrice - price: 0 - type: Tag tags: - Ingot @@ -34,7 +31,6 @@ name: gold bar suffix: Full components: - - type: Material - type: PhysicalComposition materialComposition: Gold: 100 @@ -52,15 +48,11 @@ map: ["base"] - type: Item heldPrefix: gold - - type: Appearance - - type: Extractable - grindableSolutionName: gold - - type: SolutionContainerManager - solutions: - gold: - reagents: - - ReagentId: Gold - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Gold + Quantity: 10 - type: entity parent: IngotGold @@ -79,7 +71,6 @@ name: silver bar suffix: Full components: - - type: Material - type: PhysicalComposition materialComposition: Silver: 100 @@ -97,15 +88,11 @@ map: ["base"] - type: Item heldPrefix: silver - - type: Appearance - - type: Extractable - grindableSolutionName: gold - - type: SolutionContainerManager - solutions: - gold: - reagents: - - ReagentId: Silver - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Silver + Quantity: 10 - type: entity parent: IngotSilver diff --git a/Resources/Prototypes/Entities/Objects/Materials/materials.yml b/Resources/Prototypes/Entities/Objects/Materials/materials.yml index db66583163..6aea06edff 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/materials.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/materials.yml @@ -1,36 +1,9 @@ -- type: entity - abstract: true - parent: BaseItem - id: MaterialBase - description: A raw material. - components: - - type: Sprite - sprite: Objects/Materials/materials.rsi - - type: Item - sprite: Objects/Materials/materials.rsi - size: Normal - - type: Tag - tags: - - RawMaterial - - type: Damageable - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - type: entity parent: MaterialBase id: MaterialCardboard name: cardboard suffix: Full components: - - type: Material - type: PhysicalComposition materialComposition: Cardboard: 100 @@ -46,15 +19,11 @@ layers: - state: cardboard_3 map: ["base"] - - type: Appearance - - type: Extractable - grindableSolutionName: cardboard - - type: SolutionContainerManager - solutions: - cardboard: - reagents: - - ReagentId: Cellulose - Quantity: 6 + - type: Solution + solution: + reagents: + - ReagentId: Cellulose + Quantity: 10 - type: Item heldPrefix: cardboard - type: FloorTile @@ -86,7 +55,7 @@ count: 1 - type: entity - parent: MaterialBase + parent: [MaterialBase, FoodBase] id: MaterialCloth name: cloth suffix: Full @@ -120,11 +89,6 @@ - type: PhysicalComposition materialComposition: Cloth: 100 - - type: Extractable - juiceSolution: - reagents: - - ReagentId: Fiber - Quantity: 3 - type: Sprite state: cloth_3 layers: @@ -133,16 +97,15 @@ - type: Appearance - type: Edible requiresSpecialDigestion: true + solution: composite - type: FlavorProfile flavors: - fiber - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Fiber - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Fiber + Quantity: 10 - type: Tag tags: - ClothMade @@ -176,7 +139,7 @@ count: 1 - type: entity - parent: MaterialBase + parent: [MaterialBase, FoodBase] id: MaterialDurathread name: durathread suffix: Full @@ -188,7 +151,6 @@ - durathread - durathread_2 - durathread_3 - - type: Material - type: PhysicalComposition materialComposition: Durathread: 100 @@ -197,19 +159,22 @@ layers: - state: durathread_3 map: ["base"] - - type: Appearance - type: Construction graph: Durathread node: MaterialDurathread - type: Edible requiresSpecialDigestion: true - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Fiber - Quantity: 5 + solution: composite + - type: Solution + solution: + maxVol: 20 + reagents: + - ReagentId: Fiber + Quantity: 10 + - ReagentId: Oil + Quantity: 5 + - ReagentId: Phosphorus + Quantity: 5 - type: Tag tags: - ClothMade @@ -234,7 +199,6 @@ name: wood suffix: Full components: - - type: Material - type: PhysicalComposition materialComposition: Wood: 100 @@ -250,7 +214,6 @@ layers: - state: wood map: ["base"] - - type: Appearance - type: Item heldPrefix: wood - type: Tag @@ -258,14 +221,11 @@ - Wooden - RawMaterial - ConstructionMaterial - - type: Extractable - grindableSolutionName: wood - - type: SolutionContainerManager - solutions: - wood: - reagents: - - ReagentId: Cellulose - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Cellulose + Quantity: 10 - type: entity parent: MaterialWoodPlank @@ -289,7 +249,6 @@ name: biomass suffix: Full components: - - type: Material - type: PhysicalComposition materialComposition: Biomass: 1 @@ -302,7 +261,7 @@ color: "#8A9A5B" - type: GuideHelp guides: - - Cloning + - Cloning # Should remove this, we don't have cloning and don't want cloning - type: entity parent: MaterialBiomass @@ -378,18 +337,14 @@ layers: - state: diamond map: ["base"] - - type: Appearance - type: Item heldPrefix: diamond - - type: Extractable - grindableSolutionName: diamond - - type: SolutionContainerManager - solutions: - diamond: - reagents: - - ReagentId: Carbon - Quantity: 20 - - type: Material + - type: Solution + solution: + maxVol: 30 + reagents: + - ReagentId: Carbon + Quantity: 30 - type: PhysicalComposition materialComposition: Diamond: 100 @@ -407,7 +362,7 @@ count: 1 - type: entity - parent: MaterialBase + parent: [SolutionCompositeSmallStackable, MaterialBase, FoodBase] id: MaterialCotton name: cotton suffix: Full @@ -427,34 +382,26 @@ - type: Appearance - type: Edible requiresSpecialDigestion: true + solution: composite - type: FlavorProfile flavors: - fiber - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Fiber - Quantity: 5 - - type: Extractable - juiceSolution: + - type: Solution + solution: reagents: - ReagentId: Fiber - Quantity: 3 + Quantity: 2.5 - type: Tag tags: - ClothMade - RawMaterial - Boll - - type: Material - type: PhysicalComposition materialComposition: Cotton: 100 - type: Item heldPrefix: cotton - - type: entity parent: MaterialCotton id: MaterialCotton1 @@ -466,7 +413,7 @@ count: 1 - type: entity - parent: MaterialBase + parent: [SolutionCompositeSmallStackable, MaterialBase, FoodBase] id: MaterialPyrotton name: pyrotton suffix: Full @@ -483,25 +430,16 @@ layers: - state: pyrotton_3 map: ["base"] - - type: Appearance - type: Edible requiresSpecialDigestion: true - - type: SolutionContainerManager - solutions: - food: - maxVol: 10 - reagents: - - ReagentId: Fiber - Quantity: 5 - - ReagentId: Phlogiston - Quantity: 5 - - type: Extractable - juiceSolution: + solution: composite + - type: Solution + solution: reagents: - ReagentId: Fiber - Quantity: 3 + Quantity: 2.5 - ReagentId: Phlogiston - Quantity: 3 + Quantity: 2.5 - type: Tag tags: - ClothMade @@ -520,12 +458,11 @@ count: 1 - type: entity - parent: MaterialBase + parent: [MaterialBase, FoodBase] id: MaterialBananium name: bananium suffix: Full components: - - type: Material - type: PhysicalComposition materialComposition: Bananium: 150 @@ -545,20 +482,19 @@ flavors: - banana - type: Edible + solution: composite trash: - TrashBananiumPeel - type: BadFood - - type: SolutionContainerManager - solutions: - food: - maxVol: 11 - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: Vitamin - Quantity: 2 - - ReagentId: Honk - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 4 + - ReagentId: Vitamin + Quantity: 2 + - ReagentId: Honk + Quantity: 4 - type: Extractable juiceSolution: reagents: @@ -566,7 +502,6 @@ Quantity: 5 - ReagentId: Honk Quantity: 5 - - type: Appearance - type: Item heldPrefix: bananium @@ -581,7 +516,7 @@ count: 1 - type: entity - parent: MaterialBase + parent: [SolutionCompositeNormalStackable, MaterialBase, FoodBase] id: MaterialWebSilk name: silk description: A webby material. @@ -598,23 +533,17 @@ stackType: WebSilk - type: Edible requiresSpecialDigestion: true + solution: composite - type: FlavorProfile flavors: - cobwebs ignoreReagents: - Fiber - - type: Extractable - juiceSolution: + - type: Solution + solution: reagents: - ReagentId: Fiber - Quantity: 3 - - type: SolutionContainerManager - solutions: - food: - maxVol: 3 - reagents: - - ReagentId: Fiber - Quantity: 3 + Quantity: 10 - type: Tag tags: - ClothMade @@ -721,7 +650,7 @@ count: 1 - type: entity - parent: MaterialBase + parent: [MaterialBase, FoodBase] id: MaterialBones name: bones suffix: Full @@ -738,16 +667,16 @@ layers: - state: cotton_3 map: ["base"] - - type: Appearance - type: Edible + solution: composite - type: BadFood - - type: SolutionContainerManager - solutions: - food: - maxVol: 5 - reagents: - - ReagentId: Vitamin - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Vitamin + Quantity: 3 + - ReagentId: Carbon + Quantity: 7 - type: Item heldPrefix: bones diff --git a/Resources/Prototypes/Entities/Objects/Materials/ore.yml b/Resources/Prototypes/Entities/Objects/Materials/ore.yml index 708d175a51..44ecbb82f5 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/ore.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/ore.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: BaseItem + parent: MaterialBase id: OreBase description: A piece of unrefined ore. components: @@ -8,7 +8,6 @@ sprite: Objects/Materials/ore.rsi - type: Item sprite: Objects/Materials/ore.rsi - size: Normal - type: Tag tags: - Ore @@ -24,6 +23,8 @@ restitution: 0.3 friction: 0.2 +# Ores have twice the reagents compared to their smelted forms + - type: entity parent: OreBase id: GoldOre @@ -34,18 +35,9 @@ stackType: GoldOre - type: Sprite state: gold - - type: Material - type: PhysicalComposition materialComposition: RawGold: 100 - - type: Extractable - grindableSolutionName: goldore - - type: SolutionContainerManager - solutions: - goldore: - reagents: - - ReagentId: Gold - Quantity: 10 - type: Item heldPrefix: gold - type: Tag @@ -71,18 +63,11 @@ stackType: DiamondOre - type: Sprite state: diamond - - type: Material - type: PhysicalComposition materialComposition: RawDiamond: 100 - type: Extractable grindableSolutionName: diamondore - - type: SolutionContainerManager - solutions: - diamondore: - reagents: - - ReagentId: Carbon - Quantity: 20 - type: Item heldPrefix: diamond @@ -104,18 +89,9 @@ stackType: SteelOre - type: Sprite state: iron - - type: Material - type: PhysicalComposition materialComposition: RawIron: 100 - - type: Extractable - grindableSolutionName: ironore - - type: SolutionContainerManager - solutions: - ironore: - reagents: - - ReagentId: Iron - Quantity: 10 - type: Item heldPrefix: iron @@ -137,7 +113,6 @@ stackType: PlasmaOre - type: Sprite state: plasma - - type: Material - type: PhysicalComposition materialComposition: RawPlasma: 100 @@ -146,14 +121,6 @@ energy: 0.6 castShadows: false color: "#e592e7" - - type: Extractable - grindableSolutionName: plasmaore - - type: SolutionContainerManager - solutions: - plasmaore: - reagents: - - ReagentId: Plasma - Quantity: 10 - type: Item heldPrefix: plasma - type: Tag @@ -179,18 +146,9 @@ stackType: SilverOre - type: Sprite state: silver - - type: Material - type: PhysicalComposition materialComposition: RawSilver: 100 - - type: Extractable - grindableSolutionName: silverore - - type: SolutionContainerManager - solutions: - silverore: - reagents: - - ReagentId: Silver - Quantity: 10 - type: Item heldPrefix: silver - type: Tag @@ -216,18 +174,9 @@ stackType: SpaceQuartz - type: Sprite state: spacequartz - - type: Material - type: PhysicalComposition materialComposition: RawQuartz: 100 - - type: Extractable - grindableSolutionName: quartzore - - type: SolutionContainerManager - solutions: - quartzaore: - reagents: - - ReagentId: Silicon - Quantity: 10 - type: Item heldPrefix: spacequartz @@ -249,7 +198,6 @@ stackType: UraniumOre - type: Sprite state: uranium - - type: Material - type: PhysicalComposition materialComposition: RawUranium: 100 @@ -258,17 +206,6 @@ energy: 0.8 castShadows: false color: "#9be792" - - type: Extractable - grindableSolutionName: uraniumore - - type: SolutionContainerManager - solutions: - uraniumore: - reagents: - - ReagentId: Uranium - Quantity: 8 - - ReagentId: Radium - Quantity: 2 - canReact: false - type: Item heldPrefix: uranium - type: Tag @@ -294,7 +231,6 @@ stackType: BananiumOre - type: Sprite state: bananium - - type: Material - type: PhysicalComposition materialComposition: RawBananium: 100 @@ -303,18 +239,6 @@ energy: 1 castShadows: false color: "#eef066" - - type: Extractable - grindableSolutionName: bananiumore - - type: SolutionContainerManager - solutions: - bananiumore: - reagents: - - ReagentId: Nutriment - Quantity: 4 - - ReagentId: Vitamin - Quantity: 2 - - ReagentId: Honk - Quantity: 5 - type: Item heldPrefix: bananium - type: Tag @@ -340,23 +264,19 @@ stackType: Coal - type: Sprite state: coal - - type: Material - - type: Extractable - grindableSolutionName: coal - - type: SolutionContainerManager - solutions: - coal: - reagents: - - ReagentId: Carbon - Quantity: 8.4 - - ReagentId: Ammonia - Quantity: 0.8 - - ReagentId: Hydrogen - Quantity: 0.5 - - ReagentId: Sulfur - Quantity: 0.2 - - ReagentId: Mercury - Quantity: 0.1 + - type: Solution + solution: + reagents: + - ReagentId: Carbon + Quantity: 8.4 + - ReagentId: Ammonia + Quantity: 0.8 + - ReagentId: Hydrogen + Quantity: 0.5 + - ReagentId: Sulfur + Quantity: 0.2 + - ReagentId: Mercury + Quantity: 0.1 - type: PhysicalComposition materialComposition: Coal: 100 @@ -405,20 +325,16 @@ stackType: SaltOre - type: Sprite state: salt - - type: Material - type: PhysicalComposition materialComposition: RawSalt: 100 - - type: Extractable - grindableSolutionName: saltore - - type: SolutionContainerManager - solutions: - saltore: - reagents: - - ReagentId: TableSalt - Quantity: 10 - - ReagentId: Iodine - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: TableSalt + Quantity: 9.99 + - ReagentId: Iodine + Quantity: 0.01 - type: Item heldPrefix: salt @@ -429,4 +345,3 @@ components: - type: Stack count: 1 - diff --git a/Resources/Prototypes/Entities/Objects/Materials/parts.yml b/Resources/Prototypes/Entities/Objects/Materials/parts.yml index 3322531dd3..c65d497137 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/parts.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/parts.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: BaseItem + parent: MaterialBase id: PartBase components: - type: Sprite @@ -10,16 +10,6 @@ sprite: Objects/Materials/parts.rsi - type: Damageable damageModifierSet: FlimsyMetallic - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: Tag tags: - ConstructionMaterial @@ -48,12 +38,10 @@ - state: rods_5 map: ["base"] - type: Item - size: Normal heldPrefix: rods - type: Construction graph: MetalRod node: MetalRod - - type: Appearance - type: FloorTile outputs: - Lattice @@ -62,16 +50,13 @@ price: 0 - type: StackPrice price: 7.5 - - type: Extractable - grindableSolutionName: rod - - type: SolutionContainerManager - solutions: - rod: - reagents: - - ReagentId: Iron - Quantity: 4.5 - - ReagentId: Carbon - Quantity: 0.5 + - type: Solution + solution: + reagents: + - ReagentId: Iron + Quantity: 4.5 + - ReagentId: Carbon + Quantity: 0.5 - type: GuideHelp guides: - ExpandingRepairingStation diff --git a/Resources/Prototypes/Entities/Objects/Materials/shards.yml b/Resources/Prototypes/Entities/Objects/Materials/shards.yml index d699cb1d2e..7b51fefe82 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/shards.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/shards.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: BaseItem + parent: MaterialBase id: ShardBase description: It's a shard of some unknown material. components: @@ -101,14 +101,12 @@ tags: - GlassShard - Trash - - type: Extractable - grindableSolutionName: shardglass - - type: SolutionContainerManager - solutions: - shardglass: - reagents: - - ReagentId: Silicon - Quantity: 5 #Half of the value of regular glass. TECHNICALLY, welding a single shard of glass gives you the full thing back with just 1 sheet, but that is stupid so I am making it half. + - type: Solution + solution: + maxVol: 5 + reagents: + - ReagentId: Silicon + Quantity: 5 #Half of the value of regular glass. TECHNICALLY, welding a single shard of glass gives you the full thing back with just 1 sheet, but that is stupid so I am making it half. - type: Construction graph: ShivConstruct node: start @@ -137,14 +135,15 @@ tags: - ReinforcedGlassShard - Trash - - type: Extractable - grindableSolutionName: shardrglass - - type: SolutionContainerManager - solutions: - shardrglass: - reagents: - - ReagentId: Silicon - Quantity: 5 #I don't care enough to divide all of the reinforced glass materials by 2 because reinforced glass shards are due for removal anyways. + - type: Solution + solution: + reagents: + - ReagentId: Silicon + Quantity: 5 + - ReagentId: Iron + Quantity: 2.25 + - ReagentId: Carbon + Quantity: 0.25 - type: Construction graph: ReinforcedShivConstruct node: start @@ -173,16 +172,13 @@ tags: - PlasmaGlassShard - Trash - - type: Extractable - grindableSolutionName: shardpglass - - type: SolutionContainerManager - solutions: - shardpglass: - reagents: - - ReagentId: Silicon - Quantity: 5 - - ReagentId: Plasma - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Silicon + Quantity: 5 + - ReagentId: Plasma + Quantity: 5 - type: Construction graph: PlasmaShivConstruct node: start @@ -213,16 +209,13 @@ tags: - UraniumGlassShard - Trash - - type: Extractable - grindableSolutionName: sharduglass - - type: SolutionContainerManager - solutions: - sharduglass: - reagents: - - ReagentId: Silicon - Quantity: 5 - - ReagentId: Uranium - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Silicon + Quantity: 5 + - ReagentId: Uranium + Quantity: 5 - type: Construction graph: UraniumShivConstruct node: start @@ -243,15 +236,12 @@ damage: types: Piercing: 5 - - type: Extractable - grindableSolutionName: shardcglass - - type: SolutionContainerManager - solutions: - shardcglass: - reagents: - - ReagentId: Silicon - Quantity: 5 - - ReagentId: Zinc - Quantity: 1.65 - - ReagentId: Copper - Quantity: 3.35 + - type: Solution + solution: + reagents: + - ReagentId: Silicon + Quantity: 5 + - ReagentId: Zinc + Quantity: 1.65 + - ReagentId: Copper + Quantity: 3.35 diff --git a/Resources/Prototypes/Entities/Objects/Misc/arabianlamp.yml b/Resources/Prototypes/Entities/Objects/Misc/arabianlamp.yml index 4ddfabd793..363ad4d95f 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/arabianlamp.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/arabianlamp.yml @@ -1,6 +1,6 @@ - type: entity name: lamp - parent: BaseItem + parent: [SolutionToolWelderIndsutrial, BaseItem] id: ArabianLamp description: Why the heck won't this piece of junk open!? components: @@ -91,13 +91,6 @@ right: - state: inhand-right-flame shader: unshaded - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: WeldingFuel - Quantity: 25 - maxVol: 25 - type: SolutionTransfer transferAmount: 5 canChangeTransferAmount: false @@ -114,7 +107,7 @@ heldOnly: true exactVolume: true - type: SolutionRegeneration - solution: Welder + solution: welder generated: reagents: - ReagentId: WeldingFuel diff --git a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml index 5d4ca1a7ee..c86f97eaab 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml @@ -1,24 +1,8 @@ - type: entity - name: fire extinguisher - parent: BaseItem - id: FireExtinguisher - description: It extinguishes fires. + abstract: true + parent: [SolutionSpray, BaseItem] + id: BaseFireExtinguisher components: - - type: Sprite - sprite: Objects/Misc/fire_extinguisher.rsi - layers: - - state: fire_extinguisher_closed - map: [ "enum.ToggleableVisuals.Layer" ] - - type: Item - sprite: Objects/Misc/fire_extinguisher.rsi - size: Normal - - type: SolutionContainerManager - solutions: - spray: - maxVol: 100 - reagents: - - ReagentId: Water - Quantity: 100 - type: RefillableSolution solution: spray - type: DrainableSolution @@ -50,13 +34,6 @@ verbToggleOn: fire-extinguisher-component-verb-remove verbToggleOff: fire-extinguisher-component-verb-engage - type: SpraySafety - - type: MeleeWeapon - wideAnimationRotation: 180 - damage: - types: - Blunt: 10 - soundHit: - path: /Audio/Weapons/smash.ogg - type: Tool qualities: - Rolling @@ -64,30 +41,66 @@ - type: Appearance - type: Tag tags: - - FireExtinguisher + - FireExtinguisher - type: GenericVisualizer visuals: enum.ToggleableVisuals.Enabled: enum.ToggleableVisuals.Layer: True: { state: fire_extinguisher_open } False: { state: fire_extinguisher_closed } + +- type: entity + parent: [SolutionFireExtinguisher, BaseFireExtinguisher] + id: FireExtinguisher + name: fire extinguisher + description: It extinguishes fires. + components: + - type: Sprite + sprite: Objects/Misc/fire_extinguisher.rsi + layers: + - state: fire_extinguisher_closed + map: [ "enum.ToggleableVisuals.Layer" ] + - type: Item + sprite: Objects/Misc/fire_extinguisher.rsi + size: Normal + - type: MeleeWeapon + wideAnimationRotation: 180 + damage: + types: + Blunt: 10 + soundHit: + path: /Audio/Weapons/smash.ogg - type: PhysicalComposition materialComposition: Steel: 100 - type: entity - parent: FireExtinguisher + parent: [SolutionSpray, SolutionNormal] + id: SolutionFireExtinguisher + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 120 + +- type: entity + parent: [SolutionFireExtinguisherLarge, FireExtinguisher] id: BorgFireExtinguisher name: maneuvering jet description: Based on fire extinguisher technology, the maneuvering jet is... well yes, its just a bigger fire extinguisher. + +- type: entity + parent: [SolutionSpray, SolutionLarge] + id: SolutionFireExtinguisherLarge + categories: [ HideSpawnMenu ] components: - - type: SolutionContainerManager - solutions: - spray: - maxVol: 200 - reagents: - - ReagentId: Water - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 240 - type: entity name: extinguisher spray @@ -109,7 +122,7 @@ - type: entity name: pocket fire extinguisher - parent: FireExtinguisher + parent: [SolutionFireExtinguisherMini, BaseFireExtinguisher] id: FireExtinguisherMini description: A light and compact fibreglass-framed model fire extinguisher. It holds less water than its bigger brother. components: @@ -121,13 +134,6 @@ - type: Item sprite: Objects/Misc/fire_extinguisher_mini.rsi size: Small - - type: SolutionContainerManager - solutions: - spray: - maxVol: 30 - reagents: - - ReagentId: Water - Quantity: 30 - type: MeleeWeapon wideAnimationRotation: 180 damage: @@ -140,6 +146,17 @@ Steel: 50 Glass: 40 +- type: entity + parent: [SolutionSpray, SolutionSmall] + id: SolutionFireExtinguisherMini + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 60 + # used for a engi xenoborg module - type: entity parent: [ FireExtinguisher, BaseXenoborgContraband ] diff --git a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml index 1f1b9a9c6a..13dadc47ed 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml @@ -19,9 +19,9 @@ affectAirborne: true - type: entity + parent: [ BaseKudzu, SolutionFood ] id: Kudzu name: kudzu - parent: BaseKudzu description: A rapidly growing, dangerous plant. WHY ARE YOU STOPPING TO LOOK AT IT?! components: - type: MeleeSound @@ -95,12 +95,11 @@ - type: FlavorProfile flavors: - fiber - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nutriment - Quantity: 0.1 + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 0.1 - type: Tag tags: - Ruminant @@ -169,9 +168,9 @@ - MobLuminousPerson - type: entity + parent: [BaseKudzu, SolutionFood] id: FleshKudzu name: tendons - parent: BaseKudzu description: A rapidly growing cluster of meaty tendons. WHY ARE YOU STOPPING TO LOOK AT IT?! placement: mode: SnapgridCenter @@ -252,14 +251,13 @@ ignoreWhitelist: tags: - Flesh - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Razorium - Quantity: 2 - - ReagentId: Protein - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Razorium + Quantity: 2 + - ReagentId: Protein + Quantity: 1 - type: AutoEmote # Meat Kudzu used to have respirator, but couldn't breathe so all it would do is gasp. emotes: - MeatGasp diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml index 6218da86eb..ba2a7b2e3a 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml @@ -1,5 +1,5 @@ - type: entity - parent: BaseItem + parent: [SolutionFood, BaseItem] id: BasePaper abstract: true components: @@ -51,13 +51,12 @@ flavors: - paper - type: BadFood - - type: SolutionContainerManager - solutions: - food: - maxVol: 1 - reagents: - - ReagentId: Fiber - Quantity: 1 + - type: Solution + solution: + maxVol: 2.5 # I consider paper to be like material sheets, so we divide their capacity by 12 + reagents: + - ReagentId: Fiber + Quantity: 1.25 - type: Item size: Tiny - type: PhysicalComposition diff --git a/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml b/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml index d047049433..24e8cb090d 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml @@ -42,7 +42,7 @@ - type: entity name: spaceshroom - parent: FoodProduceBase + parent: [SolutionSmall, FoodProduceBase] id: FoodSpaceshroom description: A wild mushroom. There's no telling what effect it could have... components: @@ -58,15 +58,13 @@ reagents: - ReagentId: SpaceDrugs Quantity: 10 - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 3 - - ReagentId: Vitamin - Quantity: 2 + - type: Solution + solution: + reagents: # 20u out of 60u space, with 10-15 extra from solution random fill + - ReagentId: Nutriment + Quantity: 12 + - ReagentId: Vitamin + Quantity: 8 - type: RandomFillSolution solution: food weightedRandomId: RandomFillSpaceshroom @@ -126,22 +124,20 @@ # Cooked Object - type: entity name: cooked spaceshroom - parent: FoodProduceBase + parent: [SolutionSmall, FoodProduceBase] id: FoodSpaceshroomCooked description: A wild mushroom that has been cooked through. It seems the heat has removed its chemical effects. components: - type: FlavorProfile flavors: - spaceshroomcooked - - type: SolutionContainerManager - solutions: - food: - maxVol: 15 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Vitamin - Quantity: 5 + - type: Solution + solution: + reagents: # Cooked means no drugs I guess? Lame! + - ReagentId: Nutriment + Quantity: 20 + - ReagentId: Vitamin + Quantity: 10 - type: Sprite sprite: Objects/Misc/spaceshroom.rsi state: spaceshroom_cooked diff --git a/Resources/Prototypes/Entities/Objects/Power/powercells.yml b/Resources/Prototypes/Entities/Objects/Power/powercells.yml index 0c318dd20d..119604c074 100644 --- a/Resources/Prototypes/Entities/Objects/Power/powercells.yml +++ b/Resources/Prototypes/Entities/Objects/Power/powercells.yml @@ -14,10 +14,9 @@ intensitySlope: 1.5 - type: Sprite sprite: Objects/Power/power_cells.rsi - - type: SolutionContainerManager + - type: SolutionManager solutions: - battery: - maxVol: 5 + - SolutionRiggable - type: InjectableSolution solution: battery - type: DrawableSolution @@ -41,6 +40,16 @@ Neither: {visible: true, state: o1} Empty: {visible: false} +- type: entity + parent: Solution + id: SolutionRiggable + categories: [ HideSpawnMenu ] + components: + - type: Solution + id: battery + solution: + maxVol: 5 + - type: entity name: potato battery description: Someone's stuck two nails and some wire in a large potato. Somehow it provides a little charge. @@ -278,10 +287,13 @@ - type: Item size: Ginormous - type: MultiHandedItem - - type: SolutionContainerManager + - type: SolutionManager solutions: - battery: - maxVol: 15 + - SolutionRiggableLarge + - type: Riggable + reagent: + ReagentId: Plasma + Quantity: 15 - type: Extractable juiceSolution: reagents: @@ -295,6 +307,16 @@ sprintModifier: 0.8 - type: HeldSpeedModifier +- type: entity + parent: SolutionRiggable + id: SolutionRiggableLarge + categories: [ HideSpawnMenu ] + components: + - type: Solution + id: battery + solution: + maxVol: 15 + - type: entity id: PowerCageSmall parent: BasePowerCage diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemical-containers.yml b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemical-containers.yml index 34868ac653..b1f58a91e8 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemical-containers.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemical-containers.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ DrinkBaseMaterialStrongPlastic, DrinkBase, DrinkVisualsAll ] + parent: [ SolutionLarge, DrinkBaseMaterialStrongPlastic, DrinkBase, DrinkVisualsAll ] id: Jug name: jug description: Used to contain a very large amount of chemicals or solutions. Chugging is extremely ill-advised. @@ -7,12 +7,8 @@ - type: Sprite sprite: Objects/Specific/Chemistry/jug.rsi - type: Item - size: Normal + size: Large sprite: Objects/Specific/Chemistry/jug.rsi - - type: SolutionContainerManager - solutions: - drink: - maxVol: 200 - type: SolutionContainerVisuals maxFillLevels: 6 inHandsMaxFillLevels: 5 @@ -31,14 +27,13 @@ components: - type: Label currentLabel: reagent-name-puncturase-tranexamic - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Puncturase - Quantity: 160 - - ReagentId: TranexamicAcid - Quantity: 40 + - type: Solution + solution: + reagents: + - ReagentId: Puncturase + Quantity: 192 + - ReagentId: TranexamicAcid + Quantity: 48 - type: entity parent: Jug @@ -47,14 +42,13 @@ components: - type: Label currentLabel: reagent-name-pyrazine-dermaline - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Pyrazine - Quantity: 50 - - ReagentId: Dermaline - Quantity: 150 + - type: Solution + solution: + reagents: + - ReagentId: Pyrazine + Quantity: 60 + - ReagentId: Dermaline + Quantity: 180 - type: entity parent: Jug @@ -63,14 +57,13 @@ components: - type: Label currentLabel: reagent-name-dexalin-plus-saline - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: DexalinPlus - Quantity: 100 - - ReagentId: Saline - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: DexalinPlus + Quantity: 120 + - ReagentId: Saline + Quantity: 120 - type: entity parent: Jug @@ -79,12 +72,11 @@ components: - type: Label currentLabel: reagent-name-tricordrazine - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Tricordrazine - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Tricordrazine + Quantity: 240 - type: entity parent: Jug @@ -93,12 +85,11 @@ components: - type: Label currentLabel: reagent-name-blood - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Blood - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Blood + Quantity: 240 - type: entity parent: Jug @@ -107,12 +98,11 @@ components: - type: Label currentLabel: reagent-name-water - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Water - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 240 - type: entity parent: Jug @@ -122,12 +112,11 @@ components: - type: Label currentLabel: reagent-name-carbon - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Carbon - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Carbon + Quantity: 240 - type: entity parent: Jug @@ -137,12 +126,11 @@ components: - type: Label currentLabel: reagent-name-iodine - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Iodine - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Iodine + Quantity: 240 - type: entity parent: Jug @@ -152,12 +140,11 @@ components: - type: Label currentLabel: reagent-name-fluorine - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Fluorine - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Fluorine + Quantity: 240 - type: entity parent: Jug @@ -167,12 +154,11 @@ components: - type: Label currentLabel: reagent-name-chlorine - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Chlorine - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Chlorine + Quantity: 240 - type: entity parent: Jug @@ -182,12 +168,11 @@ components: - type: Label currentLabel: reagent-name-aluminium - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Aluminium - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Aluminium + Quantity: 240 - type: entity parent: Jug @@ -197,12 +182,11 @@ components: - type: Label currentLabel: reagent-name-phosphorus - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Phosphorus - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Phosphorus + Quantity: 240 - type: entity parent: Jug @@ -212,12 +196,11 @@ components: - type: Label currentLabel: reagent-name-sulfur - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Sulfur - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Sulfur + Quantity: 240 - type: entity parent: Jug @@ -227,12 +210,11 @@ components: - type: Label currentLabel: reagent-name-silicon - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Silicon - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Silicon + Quantity: 240 - type: entity parent: Jug @@ -242,12 +224,11 @@ components: - type: Label currentLabel: reagent-name-hydrogen - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Hydrogen - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Hydrogen + Quantity: 240 - type: entity parent: Jug @@ -257,12 +238,11 @@ components: - type: Label currentLabel: reagent-name-lithium - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Lithium - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Lithium + Quantity: 240 - type: entity parent: Jug @@ -272,12 +252,11 @@ components: - type: Label currentLabel: reagent-name-sodium - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Sodium - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Sodium + Quantity: 240 - type: entity parent: Jug @@ -287,12 +266,11 @@ components: - type: Label currentLabel: reagent-name-potassium - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Potassium - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Potassium + Quantity: 240 - type: entity parent: Jug @@ -302,12 +280,11 @@ components: - type: Label currentLabel: reagent-name-radium - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Radium - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Radium + Quantity: 240 - type: entity parent: Jug @@ -317,12 +294,11 @@ components: - type: Label currentLabel: reagent-name-iron - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Iron - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Iron + Quantity: 240 - type: entity parent: Jug @@ -332,12 +308,11 @@ components: - type: Label currentLabel: reagent-name-copper - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Copper - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Copper + Quantity: 240 - type: entity parent: Jug @@ -347,12 +322,11 @@ components: - type: Label currentLabel: reagent-name-gold - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Gold - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Gold + Quantity: 240 - type: entity parent: Jug @@ -362,12 +336,11 @@ components: - type: Label currentLabel: reagent-name-mercury - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Mercury - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Mercury + Quantity: 240 - type: entity parent: Jug @@ -377,12 +350,11 @@ components: - type: Label currentLabel: reagent-name-silver - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Silver - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Silver + Quantity: 240 - type: entity parent: Jug @@ -392,12 +364,11 @@ components: - type: Label currentLabel: reagent-name-ethanol - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Ethanol - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Ethanol + Quantity: 240 - type: entity parent: Jug @@ -407,12 +378,11 @@ components: - type: Label currentLabel: reagent-name-sugar - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Sugar - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Sugar + Quantity: 240 - type: entity parent: Jug @@ -422,12 +392,11 @@ components: - type: Label currentLabel: reagent-name-nitrogen - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Nitrogen - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Nitrogen + Quantity: 240 - type: entity parent: Jug @@ -437,12 +406,11 @@ components: - type: Label currentLabel: reagent-name-oxygen - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Oxygen - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Oxygen + Quantity: 240 - type: entity parent: Jug @@ -452,12 +420,11 @@ components: - type: Label currentLabel: reagent-name-plant-b-gone - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: PlantBGone - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: PlantBGone + Quantity: 240 - type: entity parent: Jug @@ -467,12 +434,11 @@ components: - type: Label currentLabel: reagent-name-welding-fuel - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: WeldingFuel - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: WeldingFuel + Quantity: 240 - type: entity parent: Jug @@ -482,12 +448,11 @@ components: - type: Label currentLabel: reagent-name-bicaridine - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Bicaridine - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Bicaridine + Quantity: 240 - type: entity parent: Jug @@ -497,12 +462,11 @@ components: - type: Label currentLabel: reagent-name-puncturase - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Puncturase - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Puncturase + Quantity: 240 - type: entity parent: Jug @@ -512,12 +476,11 @@ components: - type: Label currentLabel: reagent-name-dermaline - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Dermaline - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Dermaline + Quantity: 240 - type: entity parent: Jug @@ -527,12 +490,11 @@ components: - type: Label currentLabel: reagent-name-dylovene - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Dylovene - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Dylovene + Quantity: 240 - type: entity parent: Jug @@ -542,12 +504,11 @@ components: - type: Label currentLabel: reagent-name-tranexamic-acid - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: TranexamicAcid - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: TranexamicAcid + Quantity: 240 - type: entity parent: Jug @@ -557,12 +518,11 @@ components: - type: Label currentLabel: reagent-name-hyronalin - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Hyronalin - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Hyronalin + Quantity: 240 - type: entity parent: Jug @@ -572,12 +532,11 @@ components: - type: Label currentLabel: reagent-name-saline - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: Saline - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: Saline + Quantity: 240 - type: entity parent: Jug @@ -587,9 +546,8 @@ components: - type: Label currentLabel: reagent-name-dexalin-plus - - type: SolutionContainerManager - solutions: - drink: - reagents: - - ReagentId: DexalinPlus - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: DexalinPlus + Quantity: 240 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-bottles.yml b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-bottles.yml index 2f492adc28..8f5ac040d0 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-bottles.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-bottles.yml @@ -1,6 +1,6 @@ - type: entity name: bottle - parent: BaseItem + parent: [SolutionDrink, SolutionTiny, BaseItem] # This solution name is hardcoded in ChemMasterComponent id: BaseChemistryEmptyBottle abstract: true description: A small bottle. @@ -29,10 +29,6 @@ solution: drink destroyOnEmpty: false utensil: None - - type: SolutionContainerManager - solutions: - drink: # This solution name and target volume is hard-coded in ChemMasterComponent - maxVol: 30 - type: MixableSolution solution: drink - type: RefillableSolution @@ -162,13 +158,11 @@ components: - type: Label currentLabel: reagent-name-aloxadone - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Aloxadone - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Aloxadone + Quantity: 30 - type: entity id: ChemistryBottleAmbuzol @@ -177,13 +171,11 @@ components: - type: Label currentLabel: reagent-name-ambuzol - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Ambuzol - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Ambuzol + Quantity: 30 - type: entity id: ChemistryBottleAmbuzolPlus @@ -192,13 +184,11 @@ components: - type: Label currentLabel: reagent-name-ambuzol-plus - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: AmbuzolPlus - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: AmbuzolPlus + Quantity: 30 - type: entity id: ChemistryBottleArithrazine @@ -207,13 +197,11 @@ components: - type: Label currentLabel: reagent-name-arithrazine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Arithrazine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Arithrazine + Quantity: 30 - type: entity id: ChemistryBottleBarozine @@ -222,13 +210,11 @@ components: - type: Label currentLabel: reagent-name-barozine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Barozine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Barozine + Quantity: 30 - type: entity id: ChemistryBottleBicaridine @@ -237,13 +223,11 @@ components: - type: Label currentLabel: reagent-name-bicaridine - - type: SolutionContainerManager - solutions: - drink: # This solution name and target volume is hard-coded in ChemMasterComponent - maxVol: 30 - reagents: - - ReagentId: Bicaridine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Bicaridine + Quantity: 30 - type: entity id: ChemistryBottleBruizine @@ -252,13 +236,11 @@ components: - type: Label currentLabel: reagent-name-bruizine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Bruizine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Bruizine + Quantity: 30 - type: entity id: ChemistryBottleCognizine @@ -267,13 +249,11 @@ components: - type: Label currentLabel: reagent-name-cognizine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Cognizine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Cognizine + Quantity: 30 - type: entity id: ChemistryBottleCryoxadone @@ -282,13 +262,11 @@ components: - type: Label currentLabel: reagent-name-cryoxadone - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Cryoxadone - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Cryoxadone + Quantity: 30 - type: entity id: ChemistryBottleCryptobiolin @@ -297,13 +275,11 @@ components: - type: Label currentLabel: reagent-name-cryptobiolin - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Cryptobiolin - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Cryptobiolin + Quantity: 30 - type: entity id: ChemistryBottleDermaline @@ -312,13 +288,11 @@ components: - type: Label currentLabel: reagent-name-dermaline - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Dermaline - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Dermaline + Quantity: 30 - type: entity id: ChemistryBottleDexalin @@ -327,13 +301,11 @@ components: - type: Label currentLabel: reagent-name-dexalin - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Dexalin - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Dexalin + Quantity: 30 - type: entity id: ChemistryBottleDexalinPlus @@ -342,13 +314,11 @@ components: - type: Label currentLabel: reagent-name-dexalin-plus - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: DexalinPlus - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: DexalinPlus + Quantity: 30 - type: entity id: ChemistryBottleDiphenhydramine @@ -357,13 +327,11 @@ components: - type: Label currentLabel: reagent-name-diphenhydramine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Diphenhydramine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Diphenhydramine + Quantity: 30 - type: entity id: ChemistryBottleDiphenylmethylamine @@ -372,13 +340,11 @@ components: - type: Label currentLabel: reagent-name-diphenylmethylamine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Diphenylmethylamine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Diphenylmethylamine + Quantity: 30 - type: entity id: ChemistryBottleDoxarubixadone @@ -387,13 +353,11 @@ components: - type: Label currentLabel: reagent-name-doxarubixadone - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Doxarubixadone - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Doxarubixadone + Quantity: 30 - type: entity id: ChemistryBottleDylovene @@ -402,13 +366,11 @@ components: - type: Label currentLabel: reagent-name-dylovene - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Dylovene - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Dylovene + Quantity: 30 - type: entity id: ChemistryBottleEpinephrine @@ -417,13 +379,11 @@ components: - type: Label currentLabel: reagent-name-epinephrine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Epinephrine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Epinephrine + Quantity: 30 - type: entity id: ChemistryBottleEthyloxyephedrine @@ -432,13 +392,11 @@ components: - type: Label currentLabel: reagent-name-ethyloxyephedrine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Ethyloxyephedrine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Ethyloxyephedrine + Quantity: 30 - type: entity id: ChemistryBottleEthylredoxrazine @@ -447,13 +405,11 @@ components: - type: Label currentLabel: reagent-name-ethylredoxrazine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Ethylredoxrazine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Ethylredoxrazine + Quantity: 30 - type: entity id: ChemistryBottleHaloperidol @@ -462,13 +418,11 @@ components: - type: Label currentLabel: reagent-name-haloperidol - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Haloperidol - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Haloperidol + Quantity: 30 - type: entity id: ChemistryBottleHolywater @@ -477,13 +431,11 @@ components: - type: Label currentLabel: reagent-name-holywater - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Holywater - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Holywater + Quantity: 30 - type: entity id: ChemistryBottleHyronalin @@ -492,13 +444,11 @@ components: - type: Label currentLabel: reagent-name-hyronalin - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Hyronalin - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Hyronalin + Quantity: 30 - type: entity id: ChemistryBottleInaprovaline @@ -507,13 +457,11 @@ components: - type: Label currentLabel: reagent-name-inaprovaline - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Inaprovaline - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Inaprovaline + Quantity: 30 - type: entity id: ChemistryBottleInsuzine @@ -522,13 +470,11 @@ components: - type: Label currentLabel: reagent-name-insuzine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Insuzine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Insuzine + Quantity: 30 - type: entity id: ChemistryBottleIpecac @@ -537,13 +483,11 @@ components: - type: Label currentLabel: reagent-name-ipecac - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Ipecac - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Ipecac + Quantity: 30 - type: entity id: ChemistryBottleKelotane @@ -552,13 +496,11 @@ components: - type: Label currentLabel: reagent-name-kelotane - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Kelotane - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Kelotane + Quantity: 30 - type: entity id: ChemistryBottleLacerinol @@ -567,13 +509,11 @@ components: - type: Label currentLabel: reagent-name-lacerinol - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Lacerinol - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Lacerinol + Quantity: 30 - type: entity id: ChemistryBottleLeporazine @@ -582,13 +522,11 @@ components: - type: Label currentLabel: reagent-name-leporazine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Leporazine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Leporazine + Quantity: 30 - type: entity id: ChemistryBottleLipozine @@ -597,13 +535,11 @@ components: - type: Label currentLabel: reagent-name-lipozine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Lipozine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Lipozine + Quantity: 30 - type: entity id: ChemistryBottleMannitol @@ -612,13 +548,11 @@ components: - type: Label currentLabel: reagent-name-mannitol - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Mannitol - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Mannitol + Quantity: 30 - type: entity id: ChemistryBottleOculine @@ -627,13 +561,11 @@ components: - type: Label currentLabel: reagent-name-oculine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Oculine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Oculine + Quantity: 30 - type: entity id: ChemistryBottleOmnizine @@ -642,13 +574,11 @@ components: - type: Label currentLabel: reagent-name-omnizine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Omnizine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Omnizine + Quantity: 30 - type: entity id: ChemistryBottleOpporozidone @@ -657,13 +587,11 @@ components: - type: Label currentLabel: reagent-name-opporozidone - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Opporozidone - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Opporozidone + Quantity: 30 - type: entity id: ChemistryBottlePhalanximine @@ -672,13 +600,11 @@ components: - type: Label currentLabel: reagent-name-phalanximine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Phalanximine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Phalanximine + Quantity: 30 - type: entity id: ChemistryBottlePolypyryliumOligomers @@ -687,13 +613,11 @@ components: - type: Label currentLabel: reagent-name-polypyrylium-oligomers - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: PolypyryliumOligomers - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: PolypyryliumOligomers + Quantity: 30 - type: entity id: ChemistryBottlePotassiumIodide @@ -702,13 +626,11 @@ components: - type: Label currentLabel: reagent-name-potassium-iodide - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: PotassiumIodide - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: PotassiumIodide + Quantity: 30 - type: entity id: ChemistryBottlePsicodine @@ -717,13 +639,11 @@ components: - type: Label currentLabel: reagent-name-psicodine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Psicodine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Psicodine + Quantity: 30 - type: entity id: ChemistryBottlePulpedBananaPeel @@ -732,13 +652,11 @@ components: - type: Label currentLabel: reagent-name-pulped-banana-peel - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: PulpedBananaPeel - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: PulpedBananaPeel + Quantity: 30 - type: entity id: ChemistryBottlePuncturase @@ -747,13 +665,11 @@ components: - type: Label currentLabel: reagent-name-puncturase - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Puncturase - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Puncturase + Quantity: 30 - type: entity id: ChemistryBottlePyrazine @@ -762,13 +678,11 @@ components: - type: Label currentLabel: reagent-name-pyrazine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Pyrazine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Pyrazine + Quantity: 30 - type: entity id: ChemistryBottleSaline @@ -777,13 +691,11 @@ components: - type: Label currentLabel: reagent-name-saline - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Saline - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Saline + Quantity: 30 - type: entity id: ChemistryBottleSiderlac @@ -792,13 +704,11 @@ components: - type: Label currentLabel: reagent-name-siderlac - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Siderlac - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Siderlac + Quantity: 30 - type: entity id: ChemistryBottleSigynate @@ -807,13 +717,11 @@ components: - type: Label currentLabel: reagent-name-sigynate - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Sigynate - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Sigynate + Quantity: 30 - type: entity id: ChemistryBottleStellibinin @@ -822,13 +730,11 @@ components: - type: Label currentLabel: reagent-name-stellibinin - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Stellibinin - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Stellibinin + Quantity: 30 - type: entity id: ChemistryBottleSynaptizine @@ -837,13 +743,11 @@ components: - type: Label currentLabel: reagent-name-synaptizine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Synaptizine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Synaptizine + Quantity: 30 - type: entity id: ChemistryBottleTranexamicAcid @@ -852,13 +756,11 @@ components: - type: Label currentLabel: reagent-name-tranexamic-acid - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: TranexamicAcid - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: TranexamicAcid + Quantity: 30 - type: entity id: ChemistryBottleTricordrazine @@ -867,13 +769,11 @@ components: - type: Label currentLabel: reagent-name-tricordrazine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Tricordrazine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Tricordrazine + Quantity: 30 - type: entity id: ChemistryBottleUltravasculine @@ -882,13 +782,11 @@ components: - type: Label currentLabel: reagent-name-ultravasculine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Ultravasculine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Ultravasculine + Quantity: 30 - type: entity parent: BaseChemistryBottleFilled @@ -897,13 +795,11 @@ components: - type: Label currentLabel: reagent-name-charcoal - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Charcoal - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Charcoal + Quantity: 30 # Other bottles @@ -914,13 +810,11 @@ components: - type: Label currentLabel: reagent-name-robust-harvest - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: RobustHarvest - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: RobustHarvest + Quantity: 30 - type: entity id: ChemistryBottleEZNutrient @@ -929,13 +823,11 @@ components: - type: Label currentLabel: reagent-name-e-z-nutrient - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: EZNutrient - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: EZNutrient + Quantity: 30 - type: entity id: ChemistryBottleLeft4Zed @@ -944,13 +836,11 @@ components: - type: Label currentLabel: reagent-name-left4-zed - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Left4Zed - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Left4Zed + Quantity: 30 - type: entity id: ChemistryBottleUnstableMutagen @@ -959,13 +849,11 @@ components: - type: Label currentLabel: reagent-name-unstable-mutagen - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: UnstableMutagen - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: UnstableMutagen + Quantity: 30 - type: entity id: ChemistryBottleNocturine @@ -974,13 +862,11 @@ components: - type: Label currentLabel: reagent-name-nocturine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Nocturine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Nocturine + Quantity: 30 - type: entity id: ChemistryBottleEphedrine @@ -989,13 +875,11 @@ components: - type: Label currentLabel: reagent-name-ephedrine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Ephedrine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Ephedrine + Quantity: 30 - type: entity id: ChemistryBottlePax @@ -1004,13 +888,11 @@ components: - type: Label currentLabel: reagent-name-pax - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Pax - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Pax + Quantity: 30 - type: entity id: ChemistryBottleMuteToxin @@ -1019,13 +901,11 @@ components: - type: Label currentLabel: reagent-name-mute-toxin - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: MuteToxin - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: MuteToxin + Quantity: 30 - type: entity id: ChemistryBottleLead @@ -1034,13 +914,11 @@ components: - type: Label currentLabel: reagent-name-lead - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Lead - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Lead + Quantity: 30 - type: entity id: ChemistryBottleToxin @@ -1049,13 +927,11 @@ components: - type: Label currentLabel: reagent-name-toxin - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Toxin - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Toxin + Quantity: 30 - type: entity parent: BaseChemistryBottleFilled @@ -1064,13 +940,11 @@ components: - type: Label currentLabel: reagent-name-laughter - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Laughter - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Laughter + Quantity: 30 # Base reagent bottles - type: entity @@ -1080,13 +954,11 @@ components: - type: Label currentLabel: reagent-name-aluminium - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Aluminium - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Aluminium + Quantity: 30 - type: entity id: ChemistryBottleCarbon @@ -1095,13 +967,11 @@ components: - type: Label currentLabel: reagent-name-carbon - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Carbon - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Carbon + Quantity: 30 - type: entity id: ChemistryBottleChlorine @@ -1110,13 +980,11 @@ components: - type: Label currentLabel: reagent-name-chlorine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Chlorine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Chlorine + Quantity: 30 - type: entity id: ChemistryBottleCopper @@ -1125,13 +993,11 @@ components: - type: Label currentLabel: reagent-name-copper - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Copper - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Copper + Quantity: 30 - type: entity id: ChemistryBottleEthanol @@ -1140,13 +1006,11 @@ components: - type: Label currentLabel: reagent-name-ethanol - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Ethanol - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Ethanol + Quantity: 30 - type: entity id: ChemistryBottleFluorine @@ -1155,13 +1019,11 @@ components: - type: Label currentLabel: reagent-name-fluorine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Fluorine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Fluorine + Quantity: 30 - type: entity id: ChemistryBottleHydrogen @@ -1170,13 +1032,11 @@ components: - type: Label currentLabel: reagent-name-hydrogen - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Hydrogen - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Hydrogen + Quantity: 30 - type: entity id: ChemistryBottleIodine @@ -1185,13 +1045,11 @@ components: - type: Label currentLabel: reagent-name-iodine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Iodine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Iodine + Quantity: 30 - type: entity id: ChemistryBottleIron @@ -1200,13 +1058,11 @@ components: - type: Label currentLabel: reagent-name-iron - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Iron - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Iron + Quantity: 30 - type: entity id: ChemistryBottleLithium @@ -1215,13 +1071,11 @@ components: - type: Label currentLabel: reagent-name-lithium - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Lithium - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Lithium + Quantity: 30 - type: entity id: ChemistryBottleMercury @@ -1230,13 +1084,11 @@ components: - type: Label currentLabel: reagent-name-mercury - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Mercury - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Mercury + Quantity: 30 - type: entity id: ChemistryBottleNitrogen @@ -1245,13 +1097,11 @@ components: - type: Label currentLabel: reagent-name-nitrogen - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Nitrogen - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Nitrogen + Quantity: 30 - type: entity id: ChemistryBottleOxygen @@ -1260,13 +1110,11 @@ components: - type: Label currentLabel: reagent-name-oxygen - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Oxygen - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Oxygen + Quantity: 30 - type: entity id: ChemistryBottlePhosphorus @@ -1275,13 +1123,11 @@ components: - type: Label currentLabel: reagent-name-phosphorus - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Phosphorus - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Phosphorus + Quantity: 30 - type: entity id: ChemistryBottlePotassium @@ -1290,13 +1136,11 @@ components: - type: Label currentLabel: reagent-name-potassium - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Potassium - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Potassium + Quantity: 30 - type: entity id: ChemistryBottleRadium @@ -1305,13 +1149,11 @@ components: - type: Label currentLabel: reagent-name-radium - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Radium - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Radium + Quantity: 30 - type: entity id: ChemistryBottleSilicon @@ -1320,13 +1162,11 @@ components: - type: Label currentLabel: reagent-name-silicon - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Silicon - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Silicon + Quantity: 30 - type: entity id: ChemistryBottleSodium @@ -1335,13 +1175,11 @@ components: - type: Label currentLabel: reagent-name-sodium - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Sodium - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Sodium + Quantity: 30 - type: entity id: ChemistryBottleSugar @@ -1350,13 +1188,11 @@ components: - type: Label currentLabel: reagent-name-sugar - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Sugar - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Sugar + Quantity: 30 - type: entity id: ChemistryBottleSulfur @@ -1365,13 +1201,11 @@ components: - type: Label currentLabel: reagent-name-sulfur - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Sulfur - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Sulfur + Quantity: 30 # Entity tables - type: entityTable diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-vials.yml b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-vials.yml index 0ecaf17aeb..5bc8c0c054 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-vials.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-vials.yml @@ -23,7 +23,7 @@ ## Entities - type: entity - parent: BaseChemistryVial + parent: [SolutionTiny, BaseChemistryVial] id: ChemistryEmptyVial name: vial description: A small vial. @@ -35,10 +35,6 @@ - type: SolutionContainerVisuals maxFillLevels: 6 inHandsMaxFillLevels: 4 - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - type: SolutionTransfer maxTransferAmount: 30 - type: StaticPrice @@ -69,7 +65,7 @@ acts: [ "Destruction" ] - type: entity - parent: BaseChemistryVial + parent: [SolutionVeryTiny, BaseChemistryVial] id: ChemistryEmptyVialSmall name: mini vial description: A smaller vial. @@ -81,10 +77,6 @@ - type: SolutionContainerVisuals maxFillLevels: 5 inHandsMaxFillLevels: 4 - - type: SolutionContainerManager - solutions: - drink: - maxVol: 10 - type: SolutionTransfer maxTransferAmount: 10 - type: StaticPrice @@ -114,13 +106,11 @@ components: - type: Label currentLabel: reagent-name-vestine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: Vestine - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Vestine + Quantity: 30 - type: Tag tags: &TagVial # Remove trash tag when we have a filled solution - CentrifugeCompatible @@ -132,13 +122,11 @@ components: - type: Label currentLabel: reagent-name-radium - - type: SolutionContainerManager - solutions: - drink: - maxVol: 10 - reagents: - - ReagentId: Radium - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Radium + Quantity: 5 - type: Tag tags: *TagVial @@ -149,13 +137,11 @@ components: - type: Label currentLabel: reagent-name-chlorine - - type: SolutionContainerManager - solutions: - drink: - maxVol: 10 - reagents: - - ReagentId: Chlorine - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Chlorine + Quantity: 5 - type: Tag tags: *TagVial @@ -166,12 +152,10 @@ components: - type: Label currentLabel: reagent-name-plasma - - type: SolutionContainerManager - solutions: - drink: - maxVol: 10 - reagents: - - ReagentId: Plasma - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Plasma + Quantity: 15 - type: Tag tags: *TagVial diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry.yml b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry.yml index ae6f7a4476..f09f84dc99 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry.yml @@ -1,5 +1,5 @@ - type: entity - parent: BaseItem + parent: [SolutionBeaker, SolutionSmall, BaseItem] id: BaseBeaker abstract: true components: @@ -21,10 +21,6 @@ damage: types: Blunt: 0 - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 50 - type: MixableSolution solution: beaker - type: FitsInDispenser @@ -100,7 +96,7 @@ - type: DnaSubstanceTrace - type: entity - parent: BaseItem + parent: [SolutionBeaker, SolutionSmall, BaseItem] id: BaseBeakerMetallic abstract: true components: @@ -122,10 +118,6 @@ damage: types: Blunt: 0 - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 50 - type: MixableSolution solution: beaker - type: FitsInDispenser @@ -192,13 +184,11 @@ components: - type: Label currentLabel: reagent-name-cryoxadone - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 50 - reagents: - - ReagentId: Cryoxadone - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Cryoxadone + Quantity: 60 - type: entity parent: Beaker @@ -207,13 +197,11 @@ components: - type: Label currentLabel: reagent-name-arithrazine - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 50 - reagents: - - ReagentId: Arithrazine - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Arithrazine + Quantity: 60 - type: entity parent: Beaker @@ -222,13 +210,11 @@ components: - type: Label currentLabel: reagent-name-sigynate - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 50 - reagents: - - ReagentId: Sigynate - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Sigynate + Quantity: 60 - type: entity parent: Beaker @@ -237,13 +223,11 @@ components: - type: Label currentLabel: reagent-name-phalanximine - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 50 - reagents: - - ReagentId: Phalanximine - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Phalanximine + Quantity: 60 - type: entity parent: Beaker @@ -252,13 +236,11 @@ components: - type: Label currentLabel: reagent-name-diphenhydramine - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 50 - reagents: - - ReagentId: Diphenhydramine - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Diphenhydramine + Quantity: 60 - type: entity parent: Beaker @@ -267,13 +249,11 @@ components: - type: Label currentLabel: reagent-name-bruizine - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 50 - reagents: - - ReagentId: Bruizine - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Bruizine + Quantity: 60 - type: entity parent: Beaker @@ -282,17 +262,15 @@ components: - type: Label currentLabel: reagent-name-lacerinol - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 50 - reagents: - - ReagentId: Lacerinol - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: Lacerinol + Quantity: 60 - type: entity name: large beaker - parent: BaseBeaker + parent: [SolutionNormal, BaseBeaker] description: Used to contain a large amount of chemicals or solutions. id: LargeBeaker components: @@ -308,10 +286,6 @@ - type: Item size: Normal sprite: Objects/Specific/Chemistry/beaker_large.rsi - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 100 - type: Appearance - type: SolutionContainerVisuals maxFillLevels: 6 @@ -326,7 +300,7 @@ - type: entity name: cryostasis beaker - parent: BaseBeakerMetallic + parent: [SolutionCryo, BaseBeakerMetallic] description: Used to contain chemicals or solutions without reactions. id: CryostasisBeaker components: @@ -338,15 +312,10 @@ - state: beakernoreact - type: SolutionContainerVisuals maxFillLevels: 0 - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 60 - canReact: false - type: entity name: bluespace beaker - parent: BaseBeakerMetallic + parent: [SolutionGinormous, BaseBeakerMetallic] description: Powered by experimental bluespace technology. id: BluespaceBeaker components: @@ -358,14 +327,10 @@ - state: beakerbluespace - type: SolutionContainerVisuals maxFillLevels: 0 - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 1000 - type: entity name: dropper - parent: BaseItem + parent: [SolutionInjector, SolutionToolTiny, BaseItem] description: Used to transfer small amounts of chemical solution between containers. id: Dropper components: @@ -376,10 +341,6 @@ - state: dropper1 map: ["enum.SolutionContainerLayers.Fill"] visible: false - - type: SolutionContainerManager - solutions: - injector: - maxVol: 5 - type: Injector ignoreMobs: true ignoreClosed: false @@ -417,7 +378,7 @@ parent: Dropper id: BorgDropper name: hydraulic pipette - description: State-of-the-art hydraulic dropper built for cyborgs. It features a higher capacity than hand-powered droppers, able to hold 15 units of liquid. + description: State-of-the-art hydraulic dropper built for cyborgs. components: - type: Sprite sprite: Objects/Specific/Chemistry/dropper.rsi @@ -426,16 +387,12 @@ - state: dropper1 map: ["enum.SolutionContainerLayers.Fill"] visible: false - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - type: Item sprite: Objects/Specific/Chemistry/dropper.rsi - type: entity name: syringe - parent: BaseItem + parent: [SolutionInjector, SolutionToolTiny, BaseItem] description: Used to draw blood samples from mobs, or to inject them with reagents. id: BaseSyringe abstract: true @@ -454,10 +411,6 @@ - type: Item size: Tiny sprite: Objects/Specific/Chemistry/syringe.rsi - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - type: Injector activeModeProtoId: SyringeDrawMode allowedModes: @@ -491,7 +444,7 @@ - type: entity name: mini syringe - parent: Syringe + parent: [SolutionToolVeryTiny, Syringe] description: A regular syringe, reshaped to fit inside of a gun. id: MiniSyringe components: @@ -502,10 +455,6 @@ map: ["enum.SolutionContainerLayers.Fill"] visible: false - state: syringeproj - - type: SolutionContainerManager - solutions: - injector: - maxVol: 5 - type: SolutionContainerVisuals maxFillLevels: 3 fillBaseName: minisyringe @@ -563,7 +512,7 @@ - type: entity id: SyringeBluespace - parent: BaseSyringe + parent: [SolutionToolLarge, BaseSyringe] name: bluespace syringe description: Injecting with advanced bluespace technology. components: @@ -577,10 +526,6 @@ - type: Icon sprite: Objects/Specific/Chemistry/syringe.rsi state: bluespace_base0 - - type: SolutionContainerManager - solutions: - injector: - maxVol: 100 - type: Injector activeModeProtoId: BluespaceSyringeDrawMode allowedModes: @@ -596,7 +541,7 @@ - type: entity id: SyringeCryostasis - parent: BaseSyringe + parent: [SolutionCryo, BaseSyringe] name: cryostasis syringe description: A syringe used to contain chemicals or solutions without reactions. components: @@ -610,16 +555,6 @@ - type: Icon sprite: Objects/Specific/Chemistry/syringe.rsi state: cryo_base0 - - type: SolutionContainerManager - solutions: - injector: - maxVol: 10 - canReact: false - - type: Injector - activeModeProtoId: CryostasisSyringeDrawMode - allowedModes: - - CryostasisSyringeInjectMode - - CryostasisSyringeDrawMode - type: Tag tags: - Syringe @@ -627,7 +562,7 @@ - type: entity name: pill - parent: BaseItem + parent: [SolutionPill, BaseItem] id: Pill description: It's not a suppository. components: @@ -646,11 +581,6 @@ - type: BadFood - type: FlavorProfile ignoreReagents: [] - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - canReact: false - type: ExplosionResistance damageCoefficient: 0.025 # survives conventional explosives but not minibombs and nukes - type: Damageable @@ -676,6 +606,15 @@ tags: - Pill +- type: entity + abstract: true + parent: [SolutionFood, SolutionTiny] + id: SolutionPill + components: + - type: Solution + solution: + maxVol: 20 + - type: entity name: pill canister id: PillCanister diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/paper_centrifuge.yml b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/paper_centrifuge.yml index aaeeb17bf8..dafca05c97 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/paper_centrifuge.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/paper_centrifuge.yml @@ -1,30 +1,26 @@ - type: entity abstract: true - parent: BaseItem + parent: [SolutionTiny, BaseItem] id: BaseHandheldMixer components: - - type: SolutionContainerManager - solutions: - mixer: - maxVol: 10 - type: MixableSolution - solution: mixer + solution: solution - type: RefillableSolution - solution: mixer + solution: solution - type: DrainableSolution - solution: mixer + solution: solution - type: ExaminableSolution - solution: mixer + solution: solution exactVolume: true - type: DrawableSolution - solution: mixer + solution: solution - type: InjectableSolution - solution: mixer + solution: solution - type: Spillable - solution: mixer + solution: solution - type: SolutionTransfer - type: SolutionItemStatus - solution: mixer + solution: solution - type: Appearance - type: DnaSubstanceTrace - type: ReactionMixer diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml index ef8700476d..2a762a2e8f 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/leaves.yml @@ -1,4 +1,5 @@ # Leaves +# TODO We have mortar and pestle, all these ground items are very stupid and should just be made by grinding leaves instead of through construction. - type: entity name: cannabis leaves @@ -11,48 +12,39 @@ - type: Produce seedId: cannabis - type: Edible # Precursor to the one true edible - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: THC - Quantity: 15 - + - type: Solution + solution: + reagents: + - ReagentId: THC + Quantity: 15 - type: entity name: dried cannabis leaves - parent: BaseItem + parent: ProduceBaseRuminant id: LeavesCannabisDried description: "Dried cannabis leaves, ready to be ground." components: - type: Stack stackType: LeavesCannabisDried count: 1 - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: THC - Quantity: 12 - type: Sprite sprite: Objects/Specific/Hydroponics/tobacco.rsi state: dried - type: entity name: ground cannabis - parent: BaseItem + parent: [SolutionFood, SolutionTiny, BaseItem] id: GroundCannabis description: "Ground cannabis, ready to take you on a trip." components: - type: Stack stackType: GroundCannabis count: 1 - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: THC - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: THC + Quantity: 30 # Takes 2 dried leaves to make one ground cannabis. - type: Sprite sprite: Objects/Misc/reagent_fillings.rsi state: powderpile @@ -85,49 +77,31 @@ # energy: 2 #- type: RgbLightController # cycleRate: 0.6 - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: SpaceDrugs - Quantity: 3 - - ReagentId: Lipolicide - Quantity: 3 - - ReagentId: MindbreakerToxin - Quantity: 2 - - ReagentId: Happiness - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: SpaceDrugs + Quantity: 6 + - ReagentId: Lipolicide + Quantity: 3 + - ReagentId: MindbreakerToxin + Quantity: 2 + - ReagentId: Happiness + Quantity: 2 # - ReagentId: ColorfulReagent # Quantity: 1 - - ReagentId: Psicodine - Quantity: 0.6 + - ReagentId: Psicodine + Quantity: 1 - type: entity name: dried rainbow cannabis leaves - parent: LeavesCannabisDried + parent: LeavesCannabisRainbow id: LeavesCannabisRainbowDried description: "Dried rainbow cannabis leaves, ready to be ground." components: - type: Stack stackType: LeavesCannabisRainbowDried count: 1 - - type: SolutionContainerManager - solutions: - food: - maxVol: 8.5 #fuck you saveload test fail - reagents: - - ReagentId: SpaceDrugs - Quantity: 2.4 - - ReagentId: Lipolicide - Quantity: 2.4 - - ReagentId: MindbreakerToxin - Quantity: 1.6 - - ReagentId: Happiness - Quantity: 1.6 -# - ReagentId: ColorfulReagent -# Quantity: 0.8 - - ReagentId: Psicodine - Quantity: 0.48 - type: Sprite sprite: Objects/Specific/Hydroponics/rainbow_cannabis.rsi state: dried @@ -141,22 +115,21 @@ - type: Stack stackType: GroundCannabisRainbow count: 1 - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: SpaceDrugs - Quantity: 4 - - ReagentId: Lipolicide - Quantity: 4 - - ReagentId: MindbreakerToxin - Quantity: 2.66 - - ReagentId: Happiness - Quantity: 2.66 + - type: Solution + solution: + reagents: + - ReagentId: SpaceDrugs + Quantity: 12 + - ReagentId: Lipolicide + Quantity: 6 + - ReagentId: MindbreakerToxin + Quantity: 4 + - ReagentId: Happiness + Quantity: 4 # - ReagentId: ColorfulReagent -# Quantity: 1.33 - - ReagentId: Psicodine - Quantity: 0.8 +# Quantity: 2 + - ReagentId: Psicodine + Quantity: 2 - type: Sprite sprite: Objects/Specific/Hydroponics/rainbow_cannabis.rsi state: powderpile_rainbow @@ -175,12 +148,11 @@ sprite: Objects/Specific/Hydroponics/tea_plant.rsi - type: Produce seedId: teaPlant - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Vitamin - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Vitamin + Quantity: 15 - type: entity name: dried tea leaves @@ -188,12 +160,13 @@ id: LeavesTeaDried description: "Dried tea leaves, ready to be ground." components: - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: TeaPowder - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Vitamin + Quantity: 10 + - ReagentId: TeaPowder # Convert some of the Vitamin to Tea + Quantity: 5 - type: Sprite sprite: Objects/Specific/Hydroponics/tea_plant.rsi state: dried @@ -208,47 +181,39 @@ sprite: Objects/Specific/Hydroponics/tobacco.rsi - type: Produce seedId: tobacco - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nicotine - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 5 - type: entity name: dried tobacco leaves - parent: BaseItem + parent: LeavesTobacco id: LeavesTobaccoDried description: "Dried tobacco leaves, ready to be ground." components: - type: Stack stackType: LeavesTobaccoDried count: 1 - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nicotine - Quantity: 2 - type: Sprite sprite: Objects/Specific/Hydroponics/tobacco.rsi state: dried - type: entity name: ground tobacco - parent: BaseItem + parent: [SolutionFood, SolutionTiny, BaseItem] id: GroundTobacco description: "Ground tobacco, perfect for hand-rolled cigarettes." components: - type: Stack stackType: GroundTobacco count: 1 - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Nicotine - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Nicotine + Quantity: 10 - type: Sprite sprite: Objects/Misc/reagent_fillings.rsi state: powderpile diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml index d8b458a0b3..b5733897f6 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml @@ -3,7 +3,6 @@ id: SeedBase abstract: true components: - - type: SolutionContainerManager - type: Sprite sprite: Objects/Specific/Hydroponics/seeds.rsi layers: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/sprays.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/sprays.yml index 7bca0fb699..665a7505aa 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/sprays.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/sprays.yml @@ -11,13 +11,11 @@ - type: Sprite sprite: Objects/Tools/Hydroponics/sprays.rsi state: plantbgone - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - reagents: - - ReagentId: PlantBGone - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: PlantBGone + Quantity: 60 - type: Item sprite: Objects/Tools/Hydroponics/sprays.rsi heldPrefix: plantbgone @@ -32,13 +30,11 @@ - type: Sprite sprite: Objects/Tools/Hydroponics/sprays.rsi state: weedspray - - type: SolutionContainerManager - solutions: - drink: - maxVol: 50 - reagents: - - ReagentId: WeedKiller - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: WeedKiller + Quantity: 60 - type: Tag tags: - Spray @@ -56,12 +52,10 @@ components: - type: Sprite state: pestspray - - type: SolutionContainerManager - solutions: - drink: - maxVol: 50 - reagents: - - ReagentId: PestKiller - Quantity: 50 + - type: Solution + solution: + reagents: + - ReagentId: PestKiller + Quantity: 60 - type: Item sprite: Objects/Tools/Hydroponics/sprays.rsi diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml index a4b7f604f6..757260aa7a 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml @@ -1,5 +1,5 @@ - type: entity - parent: BaseItem + parent: [SolutionMopLarge, BaseItem] name: mop id: MopItem description: A mop that can't be stopped, viscera cleanup detail awaits. @@ -39,10 +39,6 @@ sprite: Objects/Specific/Janitorial/mop.rsi - type: Absorbent useAbsorberSolution: true - - type: SolutionContainerManager - solutions: - absorbed: - maxVol: 100 - type: UseDelay delay: 1 - type: PhysicalComposition @@ -57,6 +53,22 @@ - Janitorial - type: DnaSubstanceTrace +# There's a surprising amount of non-mop mops so we need to define these. +- type: entity + parent: [SolutionMop, SolutionToolSmall] + id: SolutionMopSmall + categories: [ HideSpawnMenu ] + +- type: entity + parent: [SolutionMop, SolutionToolNormal] + id: SolutionMopNormal + categories: [ HideSpawnMenu ] + +- type: entity + parent: [SolutionMop, SolutionToolLarge] + id: SolutionMopLarge + categories: [ HideSpawnMenu ] + - type: entity parent: MopItem name: advanced mop @@ -287,9 +299,9 @@ SpawnMobMoproach: 2 - type: entity - parent: BaseItem - name: damp rag + parent: [SolutionMopSmall, BaseItem] id: RagItem + name: damp rag description: For cleaning up messes, you suppose. components: - type: Sprite @@ -323,10 +335,6 @@ - type: Construction graph: Rag node: rag - - type: SolutionContainerManager - solutions: - absorbed: - maxVol: 30 - type: UseDelay delay: 1.5 - type: Tag diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/soap.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/soap.yml index 69eff77aeb..c258cd8580 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/soap.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/soap.yml @@ -2,7 +2,7 @@ - type: entity abstract: true - parent: BaseItem + parent: [SolutionSoapBase, BaseItem] id: BaseSoap name: soap components: @@ -42,13 +42,6 @@ density: 10 mask: - ItemMask - - type: SolutionContainerManager - solutions: - soap: - maxVol: 50 - reagents: - - ReagentId: SoapReagent - Quantity: 50 - type: SolutionTransfer transferAmount: 10 minTransferAmount: 1 @@ -69,6 +62,14 @@ - type: Residue residueAdjective: residue-slippery +- type: entity + abstract: true + parent: [SolutionFood, SolutionSmall] + id: SolutionSoapBase + components: + - type: Solution + id: soap + - type: entity parent: BaseSoap id: Soap @@ -80,9 +81,14 @@ map: ["enum.SolutionContainerLayers.Fill"] - type: Residue residueColor: residue-green + - type: Solution + solution: + reagents: + - ReagentId: SoapReagent + Quantity: 60 - type: entity - parent: BaseSoap + parent: Soap id: SoapNT description: A Nanotrasen brand bar of soap. Smells of plasma. components: @@ -94,18 +100,18 @@ fillBaseName: nt- - type: Item heldPrefix: nt - - type: SolutionContainerManager - solutions: - soap: - maxVol: 100 - reagents: - - ReagentId: SoapReagent - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: SoapReagent + Quantity: 55 + - ReagentId: Plasma + Quantity: 5 - type: Residue residueColor: residue-grey - type: entity - parent: BaseSoap + parent: Soap id: SoapDeluxe description: A deluxe Waffle Co. brand bar of soap. Smells of strawberries. components: @@ -121,7 +127,7 @@ residueColor: residue-brown - type: entity - parent: [BaseSoap, BaseSyndicateContraband] + parent: [Soap, BaseSyndicateContraband] id: SoapSyndie description: An untrustworthy bar of soap. Smells of fear. components: @@ -156,13 +162,13 @@ description: A tiny piece of syndicate soap. categories: [ HideSpawnMenu ] components: - - type: SolutionContainerManager - solutions: - soap: - maxVol: 1.5 # 50 / 30 = 1.666 - reagents: - - ReagentId: SoapReagent - Quantity: 1.5 + - type: Solution + id: soap + solution: + maxVol: 2 # 60 / 30 = 2 + reagents: + - ReagentId: SoapReagent + Quantity: 2 - type: SolutionContainerVisuals maxFillLevels: 0 - type: Sprite @@ -203,7 +209,7 @@ residueColor: residue-red - type: entity - parent: BaseSoap + parent: Soap id: SoapHomemade description: A homemade bar of soap. Smells of... well.... components: @@ -223,7 +229,7 @@ residueColor: residue-red - type: entity - parent: BaseSoap + parent: [SolutionLarge, BaseSoap] id: SoapOmega name: omega soap description: The most advanced soap known to mankind. Smells of bluespace. @@ -241,12 +247,11 @@ launchForwardsMultiplier: 3.0 - type: Item heldPrefix: omega - - type: SolutionContainerManager - solutions: - soap: - maxVol: 240 #In the Greek alphabet, Omega is the 24th letter - reagents: - - ReagentId: SoapReagent - Quantity: 240 + - type: Solution + id: soap + solution: + reagents: + - ReagentId: SoapReagent + Quantity: 240 #In the Greek alphabet, Omega is the 24th letter - type: Residue residueColor: residue-blue diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml index 5276bdc1b9..1df2c803cf 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [ DrinkBaseMaterialPlastic, DrinkBase ] + parent: [ DrinkBaseMaterialPlastic, SolutionSmall, DrinkBase ] id: SprayBottleBase components: - type: Edible @@ -20,10 +20,6 @@ state: cleaner - type: Item sprite: Objects/Specific/Janitorial/spray_bottle.rsi - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - type: UseDelay - type: Spray solution: drink @@ -53,7 +49,7 @@ inHandsMaxFillLevels: 4 - type: entity - parent: SprayBottle + parent: [SolutionNormal, SprayBottle] id: MegaSprayBottle name: mega spray bottle suffix: Empty @@ -66,13 +62,11 @@ - state: cleaner_large-fill-1 map: ["enum.SolutionContainerLayers.Fill"] visible: false + - type: Item + size: Normal - type: SolutionContainerVisuals maxFillLevels: 7 fillBaseName: cleaner_large-fill- - - type: SolutionContainerManager - solutions: - drink: - maxVol: 250 - type: Spray transferAmount: 15 sprayedPrototype: BigVapor @@ -90,13 +84,11 @@ - type: Tag tags: - Spray - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - reagents: - - ReagentId: Water - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 60 - type: entity parent: SprayBottle @@ -104,13 +96,11 @@ suffix: Space Cleaner description: BLAM!-brand non-foaming space cleaner! components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 100 - reagents: - - ReagentId: SpaceCleaner - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: SpaceCleaner + Quantity: 60 - type: Label currentLabel: space cleaner - type: Tag @@ -123,45 +113,39 @@ suffix: Space Cleaner description: BLAM!-brand non-foaming space cleaner, now in a bigger package for those huge blood puddles! components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 250 - reagents: - - ReagentId: SpaceCleaner - Quantity: 250 + - type: Solution + solution: + reagents: + - ReagentId: SpaceCleaner + Quantity: 120 - type: Label currentLabel: space cleaner - type: entity - parent: SprayBottle + parent: [SolutionNormal, SprayBottle] id: BorgSprayBottle name: internal spray jet suffix: Filled description: A pressurized vessel for spraying reagents, installed directly into a custodial cyborg. Typically filled with space cleaner for dealing with those nasty spills. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 200 - reagents: - - ReagentId: SpaceCleaner - Quantity: 200 + - type: Solution + solution: + reagents: + - ReagentId: SpaceCleaner + Quantity: 120 - type: entity - parent: MegaSprayBottle + parent: [SolutionLarge, MegaSprayBottle] id: BorgMegaSprayBottle name: adv. internal spray jet suffix: Filled description: An upgraded version of the integrated spray bottle, installed directly into a custodial cyborg. This one is capable of creating space cleaner from moisture in the air. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 250 - reagents: - - ReagentId: SpaceCleaner - Quantity: 250 + - type: Solution + solution: + reagents: + - ReagentId: SpaceCleaner + Quantity: 240 - type: SolutionTransfer canSend: false # No giving away infinite space cleaner! - type: SolutionRegeneration @@ -173,14 +157,11 @@ # Vapor - type: entity + parent: [SolutionSmall, SolutionVapor] id: Vapor categories: [ HideSpawnMenu ] name: "vapor" components: - - type: SolutionContainerManager - solutions: - vapor: - maxVol: 50 - type: Vapor active: true transferAmountPercentage: 0.5 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Kitchen/equipment.yml b/Resources/Prototypes/Entities/Objects/Specific/Kitchen/equipment.yml index a6274bf5d5..8c7fa0a9eb 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Kitchen/equipment.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Kitchen/equipment.yml @@ -1,31 +1,27 @@ - type: entity abstract: true - parent: BaseItem + parent: [SolutionToolSmall, BaseItem] id: BaseHandheldGrinder components: - - type: SolutionContainerManager - solutions: - grinderOutput: - maxVol: 20 - type: SolutionTransfer - type: DrawableSolution - solution: grinderOutput + solution: solution - type: RefillableSolution - solution: grinderOutput + solution: solution - type: DrainableSolution - solution: grinderOutput + solution: solution - type: Edible edible: Drink - solution: grinderOutput + solution: solution destroyOnEmpty: false utensil: Spoon - type: MixableSolution - solution: grinderOutput + solution: solution - type: ExaminableSolution - solution: grinderOutput + solution: solution exactVolume: true - type: SolutionItemStatus - solution: grinderOutput + solution: solution - type: SolutionContainerVisuals maxFillLevels: 4 fillBaseName: fill- @@ -34,7 +30,7 @@ - type: Injurable damageContainer: Inorganic - type: Spillable - solution: grinderOutput + solution: solution - type: Appearance - type: HandheldGrinder diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml index 7555e88861..a6444943b6 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml @@ -396,7 +396,7 @@ # Pills - type: entity name: pill - suffix: Dexalin 10u + suffix: Dexalin 20u parent: Pill id: PillDexalin components: @@ -405,20 +405,18 @@ - type: Sprite state: pill16 - type: Label - currentLabel: dexalin 10u - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Dexalin - Quantity: 10 + currentLabel: dexalin 20u + - type: Solution + solution: + reagents: + - ReagentId: Dexalin + Quantity: 20 - type: entity name: pill canister parent: PillCanister id: PillCanisterDexalin - suffix: Dexalin 10u, 7 + suffix: Dexalin 20u, 7 components: - type: Label currentLabel: dexalin 10u @@ -430,7 +428,7 @@ - type: entity name: pill - suffix: Dylovene 10u + suffix: Dylovene 20u parent: Pill id: PillDylovene components: @@ -439,23 +437,21 @@ - type: Sprite state: pill10 - type: Label - currentLabel: dylovene 10u - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Dylovene - Quantity: 10 + currentLabel: dylovene 20u + - type: Solution + solution: + reagents: + - ReagentId: Dylovene + Quantity: 20 - type: entity name: pill canister parent: PillCanister id: PillCanisterDylovene - suffix: Dylovene 10u, 5 + suffix: Dylovene 20u, 5 components: - type: Label - currentLabel: dylovene 10u + currentLabel: dylovene 20u - type: EntityTableContainerFill containers: storagebase: @@ -464,7 +460,7 @@ - type: entity name: pill - suffix: Hyronalin 10u + suffix: Hyronalin 20u parent: Pill id: PillHyronalin components: @@ -473,23 +469,21 @@ - type: Sprite state: pill17 - type: Label - currentLabel: hyronalin 10u - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Hyronalin - Quantity: 10 + currentLabel: hyronalin 20u + - type: Solution + solution: + reagents: + - ReagentId: Hyronalin + Quantity: 20 - type: entity name: pill canister parent: PillCanister id: PillCanisterHyronalin - suffix: Hyronalin 10u, 5 + suffix: Hyronalin 20u, 5 components: - type: Label - currentLabel: hyronalin 10u + currentLabel: hyronalin 20u - type: EntityTableContainerFill containers: storagebase: @@ -498,7 +492,7 @@ - type: entity name: pill - suffix: Potassium iodide 10u + suffix: Potassium iodide 20u parent: Pill id: PillPotassiumIodide components: @@ -507,23 +501,21 @@ - type: Sprite state: pill9 - type: Label - currentLabel: potassium iodide 10u - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: PotassiumIodide - Quantity: 10 + currentLabel: potassium iodide 20u + - type: Solution + solution: + reagents: + - ReagentId: PotassiumIodide + Quantity: 20 - type: entity name: pill canister parent: PillCanister id: PillCanisterPotassiumIodide - suffix: Potassium iodide 10u, 5 + suffix: Potassium iodide 20u, 5 components: - type: Label - currentLabel: potassium iodide 10u + currentLabel: potassium iodide 20u - type: EntityTableContainerFill containers: storagebase: @@ -532,7 +524,7 @@ - type: entity name: pill - suffix: Iron 10u + suffix: Iron 20u parent: Pill id: PillIron components: @@ -541,18 +533,16 @@ - type: Sprite state: pill14 - type: Label - currentLabel: iron 10u - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Iron - Quantity: 10 + currentLabel: iron 20u + - type: Solution + solution: + reagents: + - ReagentId: Iron + Quantity: 20 - type: entity name: pill - suffix: Copper 10u + suffix: Copper 20u parent: Pill id: PillCopper components: @@ -561,23 +551,21 @@ - type: Sprite state: pill13 - type: Label - currentLabel: copper 10u - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Copper - Quantity: 10 + currentLabel: copper 20u + - type: Solution + solution: + reagents: + - ReagentId: Copper + Quantity: 20 - type: entity name: pill canister parent: PillCanister id: PillCanisterIron - suffix: Iron 10u, 5 + suffix: Iron 20u, 5 components: - type: Label - currentLabel: iron 10u + currentLabel: iron 20u - type: EntityTableContainerFill containers: storagebase: @@ -588,10 +576,10 @@ name: pill canister parent: PillCanister id: PillCanisterCopper - suffix: Copper 10u, 5 + suffix: Copper 20u, 5 components: - type: Label - currentLabel: copper 10u + currentLabel: copper 20u - type: EntityTableContainerFill containers: storagebase: @@ -600,7 +588,7 @@ - type: entity name: pill - suffix: Kelotane 10u + suffix: Kelotane 20u parent: Pill id: PillKelotane components: @@ -609,23 +597,21 @@ - type: Sprite state: pill4 - type: Label - currentLabel: kelotane 10u - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Kelotane - Quantity: 10 + currentLabel: kelotane 20u + - type: Solution + solution: + reagents: + - ReagentId: Kelotane + Quantity: 20 - type: entity name: pill canister parent: PillCanister id: PillCanisterKelotane - suffix: Kelotane 10u, 5 + suffix: Kelotane 20u, 5 components: - type: Label - currentLabel: kelotane 10u + currentLabel: kelotane 20u - type: EntityTableContainerFill containers: storagebase: @@ -644,22 +630,20 @@ state: pill8 - type: Label currentLabel: dermaline 10u - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Dermaline - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Dermaline + Quantity: 20 - type: entity name: pill canister parent: PillCanister id: PillCanisterDermaline - suffix: Dermaline 10u, 5 + suffix: Dermaline 20u, 5 components: - type: Label - currentLabel: dermaline 10u + currentLabel: dermaline 20u - type: EntityTableContainerFill containers: storagebase: @@ -671,17 +655,15 @@ parent: Pill id: PillSpaceDrugs components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: SpaceDrugs - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: SpaceDrugs + Quantity: 20 - type: entity name: pill - suffix: Tricordrazine 10u + suffix: Tricordrazine 20u parent: Pill id: PillTricordrazine components: @@ -690,23 +672,21 @@ - type: Sprite state: pill3 - type: Label - currentLabel: tricordrazine 10u - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Tricordrazine - Quantity: 10 + currentLabel: tricordrazine 20u + - type: Solution + solution: + reagents: + - ReagentId: Tricordrazine + Quantity: 20 - type: entity name: pill canister parent: PillCanister id: PillCanisterTricordrazine - suffix: Tricordrazine 10u, 5 + suffix: Tricordrazine 20u, 5 components: - type: Label - currentLabel: tricordrazine 10u + currentLabel: tricordrazine 20u - type: EntityTableContainerFill containers: storagebase: @@ -715,7 +695,7 @@ - type: entity name: pill - suffix: Bicaridine 10u + suffix: Bicaridine 20u parent: Pill id: PillBicaridine components: @@ -724,23 +704,21 @@ - type: Sprite state: pill5 - type: Label - currentLabel: bicaridine 10u - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Bicaridine - Quantity: 10 + currentLabel: bicaridine 20u + - type: Solution + solution: + reagents: + - ReagentId: Bicaridine + Quantity: 20 - type: entity name: pill canister parent: PillCanister id: PillCanisterBicaridine - suffix: Bicaridine 10u, 5 + suffix: Bicaridine 20u, 5 components: - type: Label - currentLabel: bicaridine 10u + currentLabel: bicaridine 20u - type: EntityTableContainerFill containers: storagebase: @@ -749,7 +727,7 @@ - type: entity name: pill - suffix: Charcoal 10u + suffix: Charcoal 20u parent: Pill id: PillCharcoal components: @@ -758,23 +736,21 @@ - type: Sprite state: pill21 - type: Label - currentLabel: charcoal 10u - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Charcoal - Quantity: 10 + currentLabel: charcoal 20u + - type: Solution + solution: + reagents: + - ReagentId: Charcoal + Quantity: 20 - type: entity name: pill canister parent: PillCanister id: PillCanisterCharcoal - suffix: Charcoal 10u, 3 + suffix: Charcoal 20u, 3 components: - type: Label - currentLabel: charcoal 10u + currentLabel: charcoal 20u - type: EntityTableContainerFill containers: storagebase: @@ -786,43 +762,37 @@ parent: Pill id: PillRomerol components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Romerol - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Romerol + Quantity: 20 - type: entity name: ambuzol pill parent: Pill id: PillAmbuzol components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: Ambuzol - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Ambuzol + Quantity: 10 - type: entity name: ambuzol plus pill parent: Pill id: PillAmbuzolPlus components: - - type: Pill - pillType: 2 - - type: Sprite - state: pill3 - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - reagents: - - ReagentId: AmbuzolPlus - Quantity: 5 + - type: Pill + pillType: 2 + - type: Sprite + state: pill3 + - type: Solution + solution: + reagents: + - ReagentId: AmbuzolPlus + Quantity: 5 - type: entity parent: PillCanister @@ -870,13 +840,11 @@ components: - type: Label currentLabel: reagent-name-ephedrine - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: Ephedrine - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Ephedrine + Quantity: 15 - type: entity suffix: inaprovaline @@ -885,13 +853,11 @@ components: - type: Label currentLabel: reagent-name-inaprovaline - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: Inaprovaline - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Inaprovaline + Quantity: 15 - type: entity suffix: tranexamic acid @@ -900,13 +866,11 @@ components: - type: Label currentLabel: reagent-name-tranexamic-acid - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: TranexamicAcid - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: TranexamicAcid + Quantity: 15 - type: entity suffix: bicaridine @@ -915,13 +879,11 @@ components: - type: Label currentLabel: reagent-name-bicaridine - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: Bicaridine - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Bicaridine + Quantity: 15 - type: entity suffix: dermaline @@ -930,13 +892,11 @@ components: - type: Label currentLabel: reagent-name-dermaline - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: Dermaline - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Dermaline + Quantity: 15 - type: entity suffix: hyronalin @@ -945,13 +905,11 @@ components: - type: Label currentLabel: reagent-name-hyronalin - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: Hyronalin - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Hyronalin + Quantity: 15 - type: entity suffix: ipecac @@ -960,13 +918,11 @@ components: - type: Label currentLabel: reagent-name-ipecac - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: Ipecac - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Ipecac + Quantity: 15 - type: entity suffix: ambuzol @@ -975,13 +931,11 @@ components: - type: Label currentLabel: reagent-name-ambuzol - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: Ambuzol - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Ambuzol + Quantity: 15 - type: entity suffix: sigynate @@ -990,13 +944,11 @@ components: - type: Label currentLabel: reagent-name-sigynate - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: Sigynate - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Sigynate + Quantity: 15 - type: entity suffix: ethylredoxrazine @@ -1005,13 +957,11 @@ components: - type: Label currentLabel: reagent-name-ethylredoxrazine - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: Ethylredoxrazine - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Ethylredoxrazine + Quantity: 15 - type: entity suffix: phalanximine @@ -1020,13 +970,11 @@ components: - type: Label currentLabel: reagent-name-phalanximine - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: Phalanximine - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Phalanximine + Quantity: 15 - type: entity suffix: saline @@ -1035,13 +983,11 @@ components: - type: Label currentLabel: reagent-name-saline - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: Saline - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Saline + Quantity: 15 #this is where all the syringes are so i didn't know where to put it - type: entity @@ -1051,13 +997,11 @@ components: - type: Label currentLabel: reagent-name-romerol - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: Romerol - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Romerol + Quantity: 15 - type: entity suffix: hyperzine @@ -1066,13 +1010,11 @@ components: - type: Label currentLabel: reagent-name-stimulants - - type: SolutionContainerManager - solutions: - injector: - maxVol: 15 - reagents: - - ReagentId: Stimulants - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Stimulants + Quantity: 15 # Entity Tables - type: entityTable diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml index 8bf35659e5..0daac3ac84 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: BaseItem + parent: [SolutionHypospraySmall, BaseItem] id: BaseHypospray components: - type: Injector @@ -18,7 +18,25 @@ - type: Appearance - type: entity - parent: [BaseHypospray, BaseGrandTheftContraband] + abstract: true + parent: [SolutionHypospray, SolutionToolSmall] + id: SolutionHypospraySmall + components: + - type: Solution + solution: + maxVol: 20 + +- type: entity + abstract: true + parent: [SolutionHypospray, SolutionToolTiny] + id: SolutionHyposprayTiny + components: + - type: Solution + solution: + maxVol: 10 + +- type: entity + parent: [SolutionToolSmall, BaseHypospray, BaseGrandTheftContraband] id: Hypospray name: hypospray description: A sterile injector for rapid administration of drugs to patients. @@ -33,10 +51,6 @@ visible: false - type: Item sprite: Objects/Specific/Medical/hypospray.rsi - - type: SolutionContainerManager - solutions: - hypospray: - maxVol: 30 - type: RefillableSolution solution: hypospray - type: UseDelay @@ -69,17 +83,13 @@ visible: false - type: Item sprite: Objects/Specific/Medical/syndihypo.rsi - - type: SolutionContainerManager - solutions: - hypospray: - maxVol: 20 - type: SolutionContainerVisuals maxFillLevels: 4 fillBaseName: hypo_fill solutionName: hypospray - type: entity - parent: BaseHypospray + parent: [SolutionHyposprayTiny, BaseHypospray] id: BorgHypo name: borghypo description: A sterile injector for rapid administration of drugs to patients. This integrated model is specialized for use by medical borgs. @@ -94,10 +104,6 @@ visible: false - type: Item sprite: Objects/Specific/Medical/hypospray.rsi - - type: SolutionContainerManager - solutions: - hypospray: - maxVol: 10 - type: RefillableSolution solution: hypospray - type: SolutionContainerVisuals @@ -125,10 +131,9 @@ sprite: Objects/Specific/Medical/jetinjector.rsi - type: UseDelay delay: 1.5 - - type: SolutionContainerManager - solutions: - hypospray: - maxVol: 15 + - type: Solution + solution: + maxVol: 15 # Same as a syringe - type: SolutionContainerVisuals maxFillLevels: 3 fillBaseName: jetinjector_filled @@ -142,7 +147,7 @@ - JetInjectorInjectMode - type: entity - parent: JetInjector + parent: [SolutionHypospraySmall, JetInjector] id: AdvancedJetInjector name: advanced jet injector description: A pristine, fashionable, high quality injector. Allows for a faster injection, with a slightly larger capacity. @@ -157,10 +162,6 @@ visible: false - type: Item sprite: Objects/Specific/Medical/advanced_jetinjector.rsi - - type: SolutionContainerManager - solutions: - hypospray: - maxVol: 20 - type: SolutionContainerVisuals maxFillLevels: 4 - type: Injector @@ -176,15 +177,14 @@ suffix: Admeme description: The ultimate application of bluespace technology and rapid chemical administration. components: - - type: SolutionContainerManager - solutions: - hypospray: - maxVol: 3000 - - type: UseDelay - delay: 0.0 + - type: Solution + solution: + maxVol: 3000 # Badmin abuse + - type: UseDelay + delay: 0.0 - type: entity - parent: BaseHypospray + parent: BaseHypospray # I plan to resize medipens to 1x2 eventually:tm: id: ChemicalMedipen name: chemical medipen description: A single-dose, non-refillable medipen. @@ -208,14 +208,7 @@ color: "#439822" - state: base-colorB-inhand-right size: Tiny - - type: SolutionContainerManager - solutions: - pen: - maxVol: 15 - - type: ExaminableSolution - solution: pen - type: Injector - solutionName: pen currentTransferAmount: null activeModeProtoId: HyposprayInjectMode allowedModes: @@ -224,6 +217,7 @@ maxFillLevels: 1 changeColor: false emptySpriteName: firstaid_empty + solutionName: hypospray - type: PhysicalComposition materialComposition: Plastic: 50 @@ -231,7 +225,7 @@ - type: StaticPrice price: 75 # These are limited supply items. - type: TrashOnSolutionEmpty - solution: pen + solution: hypospray - type: entity parent: ChemicalMedipen @@ -248,15 +242,13 @@ maxFillLevels: 1 changeColor: false emptySpriteName: medipen_empty - - type: SolutionContainerManager - solutions: - pen: - maxVol: 15 - reagents: - - ReagentId: Epinephrine - Quantity: 12 - - ReagentId: TranexamicAcid - Quantity: 3 + - type: Solution + solution: + reagents: + - ReagentId: Epinephrine + Quantity: 15 + - ReagentId: TranexamicAcid + Quantity: 5 - type: entity parent: ChemicalMedipen @@ -285,15 +277,13 @@ maxFillLevels: 1 changeColor: false emptySpriteName: penacid_empty - - type: SolutionContainerManager - solutions: - pen: - maxVol: 15 - reagents: - - ReagentId: Ultravasculine - Quantity: 10 - - ReagentId: Epinephrine - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Ultravasculine + Quantity: 15 + - ReagentId: Epinephrine + Quantity: 5 - type: entity parent: ChemicalMedipen @@ -322,15 +312,13 @@ maxFillLevels: 1 changeColor: false emptySpriteName: bicpen_empty - - type: SolutionContainerManager - solutions: - pen: - maxVol: 20 - reagents: - - ReagentId: Bicaridine - Quantity: 15 - - ReagentId: TranexamicAcid - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Bicaridine + Quantity: 15 + - ReagentId: TranexamicAcid + Quantity: 5 - type: entity parent: ChemicalMedipen @@ -359,15 +347,13 @@ maxFillLevels: 1 changeColor: false emptySpriteName: dermpen_empty - - type: SolutionContainerManager - solutions: - pen: - maxVol: 20 - reagents: - - ReagentId: Dermaline - Quantity: 10 - - ReagentId: Leporazine - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Dermaline + Quantity: 10 + - ReagentId: Leporazine + Quantity: 10 - type: entity parent: ChemicalMedipen @@ -396,15 +382,13 @@ maxFillLevels: 1 changeColor: false emptySpriteName: arithpen_empty - - type: SolutionContainerManager - solutions: - pen: - maxVol: 20 - reagents: - - ReagentId: Arithrazine - Quantity: 15 - - ReagentId: Bicaridine - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Arithrazine + Quantity: 10 + - ReagentId: Bicaridine + Quantity: 10 - type: entity parent: ChemicalMedipen @@ -433,15 +417,15 @@ maxFillLevels: 1 changeColor: false emptySpriteName: punctpen_empty - - type: SolutionContainerManager - solutions: - pen: - maxVol: 15 - reagents: - - ReagentId: Puncturase - Quantity: 10 - - ReagentId: TranexamicAcid - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Puncturase + Quantity: 12 + - ReagentId: TranexamicAcid + Quantity: 5 + - ReagentId: Nothing # Needed for visuals to work, idk what else to put here :P + Quantity: 3 - type: entity parent: ChemicalMedipen @@ -470,15 +454,13 @@ maxFillLevels: 1 changeColor: false emptySpriteName: pyrapen_empty - - type: SolutionContainerManager - solutions: - pen: - maxVol: 20 - reagents: - - ReagentId: Pyrazine - Quantity: 10 - - ReagentId: Dermaline - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Pyrazine + Quantity: 10 + - ReagentId: Dermaline + Quantity: 10 - type: entity parent: ChemicalMedipen @@ -507,15 +489,13 @@ maxFillLevels: 1 changeColor: false emptySpriteName: dexpen_empty - - type: SolutionContainerManager - solutions: - pen: - maxVol: 40 - reagents: - - ReagentId: Saline - Quantity: 20 - - ReagentId: DexalinPlus - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Saline + Quantity: 10 + - ReagentId: DexalinPlus + Quantity: 10 - type: entity parent: ChemicalMedipen @@ -544,18 +524,21 @@ maxFillLevels: 1 changeColor: false emptySpriteName: hypovolemic_empty - - type: SolutionContainerManager - solutions: - pen: - maxVol: 30 - reagents: - - ReagentId: Leporazine - Quantity: 10 - - ReagentId: Barozine - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Leporazine + Quantity: 10 + - ReagentId: Barozine + Quantity: 10 - type: entity - parent: [ChemicalMedipen, BaseSyndicateContraband] + abstract: true + parent: [SolutionToolSmall, ChemicalMedipen, BaseSyndicateContraband] + id: SyndicateMedipen # Interdyne gets more capacity + +- type: entity + parent: SyndicateMedipen id: Stimpack name: hyperzine injector description: A chemical injector containing a large shot of pure hyperzine. For when it's time to throw down. Effects last for about 60 seconds. @@ -579,13 +562,11 @@ layers: - state: stimpen map: ["enum.SolutionContainerLayers.Fill"] - - type: SolutionContainerManager - solutions: - pen: - maxVol: 30 - reagents: - - ReagentId: Stimulants - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: Stimulants + Quantity: 30 - type: SolutionContainerVisuals maxFillLevels: 1 changeColor: false @@ -594,7 +575,7 @@ price: 1500 - type: entity - parent: [ChemicalMedipen, BaseSyndicateContraband] + parent: [ SolutionToolTiny, SyndicateMedipen ] id: StimpackMini name: hyperzine microinjector description: A chemical microinjector containing a small shot of pure hyperzine. Effects last for about 30 seconds. @@ -618,13 +599,11 @@ layers: - state: microstimpen map: ["enum.SolutionContainerLayers.Fill"] - - type: SolutionContainerManager - solutions: - pen: - maxVol: 15 - reagents: - - ReagentId: Stimulants - Quantity: 15 + - type: Solution + solution: + reagents: + - ReagentId: Stimulants + Quantity: 15 - type: SolutionContainerVisuals maxFillLevels: 1 changeColor: false @@ -633,7 +612,7 @@ price: 583 # 3500 for 6 as a freaky fraction - type: entity - parent: [ChemicalMedipen, BaseSyndicateContraband] + parent: SyndicateMedipen id: CombatMedipen name: combat medipen description: A single-dose, non-refillable medipen containing a chemical cocktail that treats most forms of damage. @@ -659,27 +638,21 @@ maxFillLevels: 1 changeColor: false emptySpriteName: morphen_empty - - type: SolutionContainerManager - solutions: - pen: - maxVol: 30 - reagents: - - ReagentId: Omnizine - Quantity: 25 - - ReagentId: TranexamicAcid - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: Omnizine + Quantity: 25 + - ReagentId: TranexamicAcid + Quantity: 5 - type: StaticPrice price: 1500 - type: entity - parent: Pen # It is just like normal pen, isn't it? + parent: [Pen, SolutionHyposprayTiny] # It is just like normal pen, isn't it? id: Hypopen suffix: Hypopen components: - - type: SolutionContainerManager - solutions: - hypospray: - maxVol: 10 - type: RefillableSolution solution: hypospray refillTime: 0.75 @@ -733,10 +706,9 @@ maxFillLevels: 1 changeColor: false emptySpriteName: medipen_empty - - type: SolutionContainerManager - solutions: - pen: - maxVol: 60 - reagents: - - ReagentId: JuiceThatMakesYouWeh - Quantity: 60 + - type: Solution + solution: + maxVol: 60 + reagents: + - ReagentId: JuiceThatMakesYouWeh + Quantity: 60 # Need at least 50 to transform diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml index 9e1ca7236b..f4125ca77e 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml @@ -100,7 +100,7 @@ # snap: Center - type: entity - parent: BaseItem + parent: [SolutionFood, SolutionTiny, BaseItem] id: Ash name: ash description: This used to be something, but now it's not. @@ -114,13 +114,11 @@ tags: - Burnt - Trash - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 - reagents: - - ReagentId: Ash - Quantity: 10 + - type: Solution + solution: + reagents: + - ReagentId: Ash + Quantity: 15 - type: SolutionSpiker sourceSolution: food ignoreEmpty: true @@ -135,22 +133,18 @@ name: ectoplasm description: Much less deadly in this form. components: - - type: Sprite - sprite: Mobs/Ghosts/revenant.rsi - state: ectoplasm - - type: Tag - tags: - - Trash - - Ectoplasm - - type: SolutionContainerManager - solutions: - food: - maxVol: 50 - reagents: - - ReagentId: Ash - Quantity: 25 - - ReagentId: Arcryox - Quantity: 25 - - type: GuideHelp - guides: - - MinorAntagonists + - type: Sprite + sprite: Mobs/Ghosts/revenant.rsi + state: ectoplasm + - type: Tag + tags: + - Trash + - Ectoplasm + - type: Solution + solution: + reagents: + - ReagentId: Fresium + Quantity: 15 + - type: GuideHelp + guides: + - MinorAntagonists diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/randompill.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/randompill.yml index aefcc5c8b4..68d3b0172c 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/randompill.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/randompill.yml @@ -96,10 +96,6 @@ id: StrangePill description: This unusual pill bears no markings. There's no telling what it contains. components: - - type: SolutionContainerManager - solutions: - food: - maxVol: 20 - type: RandomFillSolution solution: food weightedRandomId: RandomFillStrangePill diff --git a/Resources/Prototypes/Entities/Objects/Specific/Xenoborg/nocturine_hypo.yml b/Resources/Prototypes/Entities/Objects/Specific/Xenoborg/nocturine_hypo.yml index 120e7c9a0f..58aa84b927 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Xenoborg/nocturine_hypo.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Xenoborg/nocturine_hypo.yml @@ -4,13 +4,12 @@ name: nocturine hypo description: A self-refilling injector for rapid administration of nocturine to victms. components: - - type: SolutionContainerManager - solutions: - hypospray: - maxVol: 12 - reagents: - - ReagentId: Nocturine - Quantity: 12 + - type: Solution + solution: + maxVol: 12 + reagents: + - ReagentId: Nocturine + Quantity: 12 - type: SolutionRegeneration solution: hypospray generated: diff --git a/Resources/Prototypes/Entities/Objects/Specific/rehydrateable.yml b/Resources/Prototypes/Entities/Objects/Specific/rehydrateable.yml index 71b09ce007..8dcb1b8a4a 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/rehydrateable.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/rehydrateable.yml @@ -5,10 +5,9 @@ components: - type: Item size: Tiny - - type: SolutionContainerManager + - type: SolutionManager solutions: - cube: - maxVol: 1 # needs room for water + - SolutionCube - type: RefillableSolution solution: cube - type: Reactive @@ -40,25 +39,36 @@ - LowImpassable - type: entity - parent: RehydratableItem + parent: Solution + id: SolutionCube # This will be deleted at a later date. Using solutions for this is really dumb. + name: cube + description: if you're reading this, nuh uh! file a bug report. + categories: [ HideSpawnMenu ] + components: + - type: Solution + id: cube + solution: + maxVol: 1 + +- type: entity + abstract: true + parent: [SolutionTiny, SolutionFood, RehydratableItem] id: RehydratableAnimalCube description: Just add water! - abstract: true components: - type: Sprite sprite: Objects/Misc/monkeycube.rsi state: cube - - type: SolutionContainerManager - solutions: - cube: - maxVol: 19 # needs 1u room for water - reagents: # equals one piece of raw meat, ideally should vary depending on the animal type, but idk how to link this to biomass costs - - ReagentId: UncookedAnimalProteins - Quantity: 9 - - ReagentId: Fat - Quantity: 9 + - type: Solution + solution: + reagents: # Same as raw meat. + - ReagentId: Nutriment + Quantity: 5 + - ReagentId: UncookedAnimalProteins + Quantity: 20 + - ReagentId: Fat + Quantity: 5 - type: Edible - solution: cube - type: FlavorProfile flavors: - chewy @@ -151,17 +161,15 @@ name: carp cube description: Just add water! At your own risk. components: - - type: SolutionContainerManager - solutions: - cube: - maxVol: 24 # needs 1u room for water - reagents: # equals one piece of raw meat - plus a deadly toxin! - - ReagentId: UncookedAnimalProteins - Quantity: 9 - - ReagentId: Fat - Quantity: 9 - - ReagentId: CarpoToxin - Quantity: 5 + - type: Solution + solution: + reagents: + - ReagentId: CarpoToxin + Quantity: 5 + - ReagentId: UncookedAnimalProteins + Quantity: 20 + - ReagentId: Fat + Quantity: 5 - type: Rehydratable possibleSpawns: - MobCarp @@ -203,12 +211,6 @@ name: dehydrated space carp description: Looks like a plush toy carp, but just add water and it becomes a real-life space carp! components: - - type: SolutionContainerManager - solutions: - cube: - maxVol: 1 # needs room for water - - type: Edible - solution: cube - type: Fixtures # BaseItem from PlushieCarp overrides fixtures, making carp not react to extinguishers fixtures: fix1: diff --git a/Resources/Prototypes/Entities/Objects/Tools/bucket.yml b/Resources/Prototypes/Entities/Objects/Tools/bucket.yml index 3c95afe69e..1f5c494299 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/bucket.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/bucket.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ DrinkBaseMaterialStrongPlastic, DrinkBase, DrinkVisualsFill ] + parent: [ SolutionLarge, DrinkBaseMaterialStrongPlastic, DrinkBase, DrinkVisualsFill ] id: Bucket name: bucket description: It's a boring old bucket. @@ -9,20 +9,21 @@ - type: Sprite sprite: Objects/Tools/bucket.rsi - type: Item - size: Normal + size: Large + shape: + - 0,0,2,3 + - type: Solution + solution: + maxVol: 360 # 3 litres - type: Clothing sprite: Objects/Tools/bucket.rsi slots: - HEAD quickEquip: false - - type: SolutionContainerManager - solutions: - drink: - maxVol: 250 - type: SolutionTransfer - transferAmount: 100 - maxTransferAmount: 100 - minTransferAmount: 10 + transferAmount: 120 + maxTransferAmount: 360 + minTransferAmount: 60 - type: SpillWhenWorn solution: drink - type: SolutionContainerVisuals @@ -36,12 +37,11 @@ Plastic: 50 - type: entity - parent: Bucket + parent: [SolutionHuge, Bucket] id: BorgBucket name: internal tank description: The internal reservoir of a custodial cyborg, capable of holding a entire mop bucket worth of water. components: - - type: SolutionContainerManager - solutions: - drink: - maxVol: 500 + - type: SolutionTransfer + transferAmount: 240 + maxTransferAmount: 480 diff --git a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml index 23266e2d51..76d48ed4e3 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml @@ -3,9 +3,9 @@ # ability to have applied colors yet in GUIs. And also inhands... -Swept - type: entity - id: CableStack abstract: true - parent: BaseItem + parent: [SolutionCompositeSmallStackable, BaseItem] + id: CableStack name: cable stack suffix: Full components: @@ -16,6 +16,7 @@ stackType: Cable - type: Sprite sprite: Objects/Tools/cable-coils.rsi + - type: Appearance - type: Item sprite: Objects/Tools/cable-coils.rsi size: Small @@ -37,6 +38,8 @@ damageModifierSet: Metallic - type: Injurable damageContainer: Inorganic + - type: Extractable + grindableSolutionName: composite - type: Destructible thresholds: - trigger: @@ -70,19 +73,15 @@ - type: CablePlacer cablePrototypeID: CableHV blockingWireType: HighVoltage - - type: Appearance - - type: Extractable - grindableSolutionName: hvcable - - type: SolutionContainerManager - solutions: - hvcable: - reagents: - - ReagentId: Iron - Quantity: 3 - - ReagentId: Copper - Quantity: 2 - - ReagentId: Carbon #steel-reinforced - Quantity: 1 + - type: Solution + solution: + reagents: + - ReagentId: Iron + Quantity: 2.5 + - ReagentId: Copper + Quantity: 2 + - ReagentId: Carbon #steel-reinforced + Quantity: 0.5 - type: entity parent: CableHVStack @@ -105,7 +104,7 @@ count: 1 - type: entity - parent: CableStack + parent: [SolutionCompositeCable, CableStack] id: CableMVStack name: MV cable coil suffix: Full @@ -124,21 +123,23 @@ - state: coilmv-30 map: ["base"] - type: Item - heldPrefix: coilmv + heldPrefix: composite - type: CablePlacer cablePrototypeID: CableMV blockingWireType: MediumVoltage - - type: Appearance - - type: Extractable - grindableSolutionName: mvcable - - type: SolutionContainerManager - solutions: - mvcable: - reagents: - - ReagentId: Iron - Quantity: 3 - - ReagentId: Copper - Quantity: 2 + +- type: entity + abstract: true + parent: SolutionCompositeSmallStackable + id: SolutionCompositeCable + components: + - type: Solution + solution: + reagents: + - ReagentId: Iron + Quantity: 3 + - ReagentId: Copper + Quantity: 2 - type: entity parent: CableMVStack @@ -161,7 +162,7 @@ count: 1 - type: entity - parent: CableStack + parent: [SolutionCompositeCable, CableStack] id: CableApcStack name: LV cable coil description: Low-Voltage stack of wires for connecting APCs to machines and other purposes. @@ -183,17 +184,6 @@ - type: CablePlacer cablePrototypeID: CableApcExtension blockingWireType: Apc - - type: Appearance - - type: Extractable - grindableSolutionName: lvcable - - type: SolutionContainerManager - solutions: - lvcable: - reagents: - - ReagentId: Iron - Quantity: 3 - - ReagentId: Copper - Quantity: 2 - type: entity parent: CableApcStack diff --git a/Resources/Prototypes/Entities/Objects/Tools/flare.yml b/Resources/Prototypes/Entities/Objects/Tools/flare.yml index 34c233921e..f0e27833c8 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/flare.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/flare.yml @@ -1,6 +1,6 @@ - type: entity name: emergency flare - parent: BaseItem + parent: [SolutionComposite, SolutionTiny, BaseItem] id: Flare description: A flare that produces a very bright light for a short while. Point the flame away from yourself. components: @@ -75,24 +75,22 @@ startValue: 10.0 endValue: 1.0 - type: Extractable - grindableSolutionName: flare - - type: SolutionContainerManager - solutions: - flare: - maxVol: 20 - reagents: - # flare casing - - ReagentId: Iron - Quantity: 10 - # red phosphorus = red flare trust - - ReagentId: Phosphorus - Quantity: 3 - - ReagentId: Carbon - Quantity: 1 - - ReagentId: Oxygen - Quantity: 2 - # fuel or something - - ReagentId: Charcoal - Quantity: 2 - - ReagentId: Sulfur - Quantity: 2 + grindableSolutionName: composite + - type: Solution + solution: + reagents: + # flare casing + - ReagentId: Iron + Quantity: 10 + # red phosphorus = red flare trust + - ReagentId: Phosphorus + Quantity: 6 + - ReagentId: Carbon + Quantity: 2 + - ReagentId: Oxygen + Quantity: 4 + # fuel or something + - ReagentId: Charcoal + Quantity: 4 + - ReagentId: Sulfur + Quantity: 4 diff --git a/Resources/Prototypes/Entities/Objects/Tools/lighters.yml b/Resources/Prototypes/Entities/Objects/Tools/lighters.yml index 2d3e55c6ed..159da3c5f4 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/lighters.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/lighters.yml @@ -1,8 +1,8 @@ - type: entity + abstract: true + parent: [SolutionWelder, BaseItem] + id: BaseLighter name: basic lighter - parent: BaseItem - id: Lighter - description: "A simple plastic cigarette lighter." components: - type: IgnitionSource ignited: false @@ -14,11 +14,51 @@ collection: lighterOffSounds - type: ItemToggleMeleeWeapon activatedDamage: - types: - Heat: 1 + types: + Heat: 1 - type: ItemToggleSize activatedSize: Small - type: ItemToggleHot + - type: Appearance + - type: Item + size: Tiny + - type: UseDelay + - type: RefillableSolution + solution: Welder + - type: MeleeWeapon + wideAnimationRotation: 180 + damage: + types: + Blunt: 0 + - type: Welder + fuelConsumption: 0.01 + fuelLitCost: 0.1 + tankSafe: true + - type: PointLight + enabled: false + netsync: false + radius: 1.1 #smallest possible + color: orange + - type: ItemTogglePointLight + - type: PhysicalComposition + +- type: entity + abstract: true + parent: [SolutionWelder, SolutionToolVeryTiny] + id: SolutionLighter + components: + - type: Solution + solution: + reagents: + - ReagentId: WeldingFuel + Quantity: 7.5 + +- type: entity + name: basic lighter + parent: [SolutionLighter, BaseLighter] + id: Lighter + description: "A simple plastic cigarette lighter." + components: - type: Sprite sprite: Objects/Tools/Lighters/lighters.rsi layers: @@ -30,7 +70,6 @@ visible: false shader: unshaded map: [ "flame" ] - - type: Appearance - type: RandomSprite available: - skin: @@ -61,38 +100,11 @@ - state: inhand-right-flame shader: unshaded - type: Item - size: Tiny sprite: Objects/Tools/Lighters/lighters.rsi - - type: UseDelay - - type: RefillableSolution - solution: Welder - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: WeldingFuel - Quantity: 8 - maxVol: 8 #uses less fuel than a welder, so this isnt as bad as it looks - - type: MeleeWeapon - wideAnimationRotation: 180 - damage: - types: - Blunt: 0 - - type: Welder - fuelConsumption: 0.01 - fuelLitCost: 0.1 - tankSafe: true - - type: PointLight - enabled: false - netsync: false - radius: 1.1 #smallest possible - color: orange - - type: ItemTogglePointLight - - type: PhysicalComposition - type: entity name: cheap lighter - parent: Lighter + parent: BaseLighter id: CheapLighter description: "A dangerously inexpensive plastic lighter, don't burn your thumb!" components: @@ -111,17 +123,13 @@ available: - skin: cheap_icon_base: Rainbow - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: WeldingFuel - Quantity: 4 - maxVol: 4 #uses less fuel than a welder, so this isnt as bad as it looks + - type: Welder + fuelConsumption: 0.02 + fuelLitCost: 0.2 - type: entity name: flippo lighter - parent: BaseItem + parent: BaseBrandedLighter id: FlippoLighter description: "A rugged metal lighter, lasts quite a while." components: @@ -140,28 +148,9 @@ map: ["flame"] visible: false shader: unshaded - - type: ItemToggle - predictable: false - soundActivate: - path: /Audio/Items/Lighters/zippo_open.ogg - params: - volume: -5 - soundDeactivate: - path: /Audio/Items/Lighters/zippo_close.ogg - params: - volume: -5 - - type: ItemToggleMeleeWeapon - activatedDamage: - types: - Heat: 1 - - type: ItemToggleSize - activatedSize: Small - - type: ItemToggleHot - type: Item - size: Tiny sprite: Objects/Tools/Lighters/lighters.rsi heldPrefix: zippo - - type: Appearance - type: GenericVisualizer visuals: enum.ToggleableVisuals.Enabled: @@ -177,17 +166,6 @@ base: True: { visible: false } False: { visible: true } - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: WeldingFuel - Quantity: 12 - maxVol: 12 #uses less fuel than a welder, so this isnt as bad as it looks - - type: Welder - fuelConsumption: 0.01 - fuelLitCost: 0.1 - tankSafe: true - type: ToggleableVisuals spriteLayer: lighter_flame inhandVisuals: @@ -197,20 +175,8 @@ right: - state: zippo-inhand-right-flame shader: unshaded - - type: MeleeWeapon - wideAnimationRotation: 180 - damage: - types: - Blunt: 1 # does a little bit of damage on hit when off - type: PointLight - enabled: false - netsync: false radius: 1.2 #slightly stronger than the other lighters - color: orange - - type: ItemTogglePointLight - - type: UseDelay - - type: IgnitionSource - ignited: false - type: entity name: flippo engraved lighter @@ -238,7 +204,7 @@ - type: entity abstract: true - parent: BaseItem + parent: [SolutionToolWelderMini, BaseLighter] id: BaseBrandedLighter components: - type: ItemToggle @@ -251,23 +217,6 @@ path: /Audio/Items/Lighters/zippo_close.ogg params: volume: -5 - - type: ItemToggleMeleeWeapon - activatedDamage: - types: - Heat: 1 - - type: ItemToggleSize - activatedSize: Small - - type: ItemToggleHot - - type: Item - size: Tiny - - type: Appearance - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: WeldingFuel - Quantity: 12 - maxVol: 12 - type: Sprite layers: - state: icon @@ -306,10 +255,6 @@ right: - state: inhand-right-lit shader: unshaded - - type: ItemTogglePointLight - - type: UseDelay - - type: IgnitionSource - ignited: false - type: entity parent: [BaseBrandedLighter, BaseSyndicateContraband] @@ -349,8 +294,8 @@ shader: unshaded map: [ "flame" ] - type: Welder # the single worst lighter invented by mankind - fuelConsumption: 0.2 - fuelLitCost: 0.1 + fuelConsumption: 0.4 + fuelLitCost: 0.2 tankSafe: false - type: Item sprite: Objects/Tools/Lighters/lighters.rsi @@ -378,13 +323,6 @@ damage: types: Heat: 2 - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: WeldingFuel - Quantity: 3 - maxVol: 3 - type: entity parent: [BaseBrandedLighter, BaseSyndicateContraband] @@ -451,17 +389,15 @@ radius: 2 color: blue - type: RefillableSolution - solution: Welder - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: Plasma - Quantity: 10 - maxVol: 10 + solution: welder + - type: Solution + solution: + reagents: + - ReagentId: Plasma + Quantity: 15 - type: entity - parent: [BaseBrandedLighter, BaseCentcommContraband] + parent: [SolutionGinormous, BaseBrandedLighter, BaseCentcommContraband] id: CentCommFlippo name: Gilded CentComm Flippo description: "An Ornate, jade embossed and gilded flippo frame containing a bluespace powered jet. The latch is secured by a miniature access reader that only responds to CentComm officials. The nicest lighter known to man." @@ -485,13 +421,11 @@ color: Gold - type: RefillableSolution solution: Welder - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: Plasma - Quantity: 999 - maxVol: 999 + - type: Solution + solution: + reagents: + - ReagentId: Plasma + Quantity: 480 - type: Tool useSound: collection: Welder @@ -609,20 +543,9 @@ tags: - DonkPocket - Meat - - type: SolutionContainerManager + - type: SolutionManager solutions: - Welder: - reagents: - - ReagentId: WeldingFuel - Quantity: 12 - maxVol: 12 - food: - maxVol: 20 - reagents: - - ReagentId: Nutriment - Quantity: 10 - - ReagentId: Omnizine - Quantity: 10 + - SolutionFoodDonkpocketWarm - type: FlavorProfile flavors: - bread diff --git a/Resources/Prototypes/Entities/Objects/Tools/welders.yml b/Resources/Prototypes/Entities/Objects/Tools/welders.yml index 8833047777..6162f25a66 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/welders.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/welders.yml @@ -1,20 +1,18 @@ - type: entity - name: welding tool - parent: BaseItem - id: Welder - description: "Melts anything as long as it's fueled, don't forget your eye protection!" + abstract: true + parent: [SolutionWelder, BaseItem] + id: BaseWelder components: - - type: EmitSoundOnLand - sound: - path: /Audio/Items/welder_drop.ogg - type: Sprite - sprite: Objects/Tools/welder.rsi layers: - state: icon - state: welder_flame visible: false shader: unshaded - map: ["enum.ToggleableVisuals.Layer"] + map: [ "enum.ToggleableVisuals.Layer" ] + - type: EmitSoundOnLand + sound: + path: /Audio/Items/welder_drop.ogg - type: GenericVisualizer visuals: enum.ToggleableVisuals.Enabled: @@ -50,8 +48,8 @@ deactivatedSoundOnHitNoDamage: collection: MetalThud activatedDamage: - types: - Heat: 8 + types: + Heat: 8 - type: ItemToggleSize activatedSize: Large - type: ItemToggleHot @@ -77,14 +75,7 @@ soundHit: collection: MetalThud - type: RefillableSolution - solution: Welder - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: WeldingFuel - Quantity: 100 - maxVol: 100 + solution: welder - type: Tool useSound: collection: Welder @@ -106,9 +97,30 @@ - type: IgnitionSource temperature: 700 +- type: entity + parent: [SolutionToolWelder, BaseWelder] + id: Welder + name: welding tool + description: "Melts anything as long as it's fueled, don't forget your eye protection!" + components: + - type: Sprite + sprite: Objects/Tools/welder.rsi + +- type: entity + parent: [SolutionWelder, SolutionSmall] + id: SolutionToolWelder + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 100 # TODO: This needs to be dropped to 30 + reagents: + - ReagentId: WeldingFuel + Quantity: 100 + - type: entity name: industrial welding tool - parent: Welder + parent: [SolutionToolWelderIndsutrial, BaseWelder] id: WelderIndustrial description: "An industrial welder with over double the fuel capacity." components: @@ -116,13 +128,18 @@ sprite: Objects/Tools/welder_industrial.rsi - type: Item sprite: Objects/Tools/welder_industrial.rsi - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: WeldingFuel - Quantity: 250 - maxVol: 250 + +- type: entity + parent: [SolutionWelder, SolutionToolNormal] + id: SolutionToolWelderIndsutrial + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 250 # TODO: This needs to be dropped to 60 + reagents: + - ReagentId: WeldingFuel + Quantity: 250 - type: entity name: advanced industrial welding tool @@ -134,19 +151,12 @@ sprite: Objects/Tools/welder_industrialadv.rsi - type: Item sprite: Objects/Tools/welder_industrialadv.rsi - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: WeldingFuel - Quantity: 250 - maxVol: 250 - type: Tool speedModifier: 1.3 - type: entity name: experimental welding tool - parent: Welder + parent: [SolutionToolWelderExperimental, BaseWelder] id: WelderExperimental description: "An experimental welder capable of self-fuel generation and less harmful to the eyes." components: @@ -154,19 +164,12 @@ sprite: Objects/Tools/welder_experimental.rsi - type: Item sprite: Objects/Tools/welder_experimental.rsi - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: WeldingFuel - Quantity: 1000 - maxVol: 1000 - type: PointLight enabled: false radius: 1.5 color: lightblue - type: SolutionRegeneration - solution: Welder + solution: welder generated: reagents: - ReagentId: WeldingFuel @@ -174,9 +177,20 @@ - type: RequiresEyeProtection statusEffectTime: 5 # less harmful; sunglasses can block it +- type: entity + parent: [SolutionWelder, SolutionToolGinormous] # Bluespace technology + id: SolutionToolWelderExperimental + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + reagents: + - ReagentId: WeldingFuel + Quantity: 480 # Literally infinite so this number basically doesn't matter, also this should be a battery tbqh. + - type: entity name: emergency welding tool - parent: Welder + parent: [SolutionToolWelderMiniEmergency, BaseWelder] id: WelderMini description: "A miniature welder used during emergencies." components: @@ -186,14 +200,7 @@ size: Tiny sprite: Objects/Tools/welder_mini.rsi - type: RefillableSolution - solution: Welder - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: WeldingFuel - Quantity: 50 - maxVol: 50 + solution: welder - type: Tool speedModifier: 0.7 - type: PointLight @@ -201,6 +208,29 @@ radius: 1.0 color: orange +- type: entity + parent: [SolutionWelder, SolutionTiny] + id: SolutionToolWelderMiniEmergency # TODO, replace with below :( + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 50 # TODO: This needs to be dropped to 15 + reagents: + - ReagentId: WeldingFuel + Quantity: 50 + +- type: entity + parent: [SolutionWelder, SolutionToolTiny] + id: SolutionToolWelderMini + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + reagents: + - ReagentId: WeldingFuel + Quantity: 15 + - type: entity parent: [ Welder, BaseXenoborgContraband ] id: RefuelingWelder @@ -213,7 +243,7 @@ fuelConsumption: 2 fuelLitCost: 1 - type: SolutionRegeneration - solution: Welder + solution: welder generated: reagents: - ReagentId: WeldingFuel diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml index e28996656e..27862d7a4f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml @@ -28,16 +28,13 @@ - ExCable overTile: true - type: Appearance - - type: Extractable - grindableSolutionName: excable - - type: SolutionContainerManager - solutions: - mvcable: - reagents: - - ReagentId: Thermite - Quantity: 3 - - ReagentId: Charcoal - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Thermite + Quantity: 3 + - ReagentId: Charcoal + Quantity: 2 - type: Damageable - type: Injurable damageContainer: StructuralInorganic diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml index a8c3ecfd30..5eabdd8515 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml @@ -97,13 +97,11 @@ - state: base map: ["enum.OpenableVisuals.Layer"] - state: fuel - - type: SolutionContainerManager - solutions: - drink: - maxVol: 30 - reagents: - - ReagentId: WeldingFuel - Quantity: 30 + - type: Solution + solution: + reagents: + - ReagentId: WeldingFuel + Quantity: 60 - type: Construction node: fuel defaultTarget: firebomb diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/shotgun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/shotgun.yml index fe1e7641c4..e02400e892 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/shotgun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/shotgun.yml @@ -115,7 +115,7 @@ state: "practice" - type: entity - parent: [ BaseShellShotgun, BaseSecurityContraband ] + parent: [ SolutionAmmo, SolutionToolVeryTiny, BaseShellShotgun, BaseSecurityContraband ] id: ShellTranquilizer name: shell (.50 tranquilizer) description: The standard cartridge used by most modern shotguns. Tranquilizer ammunition contains a single ballistic syringe loaded with a strong sedative that harmlessly puts targets to sleep. @@ -131,12 +131,11 @@ - type: CartridgeAmmo proto: PelletShotgunTranquilizer - type: ChemicalAmmo - - type: SolutionContainerManager - solutions: - ammo: - reagents: - - ReagentId: ChloralHydrate - Quantity: 7 + - type: Solution + solution: + reagents: + - ReagentId: ChloralHydrate + Quantity: 7.5 - type: SolutionTransfer maxTransferAmount: 7 - type: SpentAmmoVisuals diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml index 2a4f513650..a490c77211 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml @@ -126,7 +126,7 @@ spread: 45 - type: entity - parent: BaseBulletPractice + parent: [SolutionAmmo, SolutionToolVeryTiny, BaseBulletPractice] id: PelletShotgunTranquilizer categories: [ HideSpawnMenu ] name: pellet (.50 tranquilizer) @@ -135,12 +135,8 @@ damage: types: Blunt: 1 - - type: SolutionContainerManager - solutions: - ammo: - maxVol: 15 - type: SolutionInjectOnProjectileHit - transferAmount: 15 + transferAmount: 7.5 solution: ammo - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/watergun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/watergun.yml index 2d4d00ac76..47817e981c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/watergun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/watergun.yml @@ -1,7 +1,7 @@ - type: entity - id: WeaponWaterGunBase abstract: true - parent: BaseItem + parent: [SolutionGun, SolutionSmall, BaseItem] # 12 shots + id: WeaponWaterGunBase components: - type: Sprite sprite: Objects/Weapons/Guns/Pistols/water_pistol.rsi @@ -20,10 +20,6 @@ - SemiAuto soundGunshot: path: /Audio/Weapons/Guns/Gunshots/water_spray.ogg - - type: SolutionContainerManager - solutions: - chamber: - maxVol: 50 #10 shots - type: SolutionAmmoProvider solutionId: chamber proto: BulletWaterShot @@ -51,8 +47,8 @@ Plastic: 150 - type: entity - id: WeaponWaterPistol parent: WeaponWaterGunBase + id: WeaponWaterPistol name: water pistol description: The dinkiest of water-based weaponry. You swear the trigger doesn't do anything. components: @@ -73,8 +69,8 @@ icon: Rainbow - type: entity + parent: [SolutionNormal, WeaponWaterGunBase] # 24 shots id: WeaponWaterBlaster - parent: WeaponWaterGunBase name: water blaster description: With this bad boy, you'll be the coolest kid at the summer barbecue. components: @@ -86,10 +82,6 @@ - FullAuto soundGunshot: path: /Audio/Weapons/Guns/Gunshots/water_spray.ogg - - type: SolutionContainerManager - solutions: - chamber: - maxVol: 100 #20 shots - type: Sprite sprite: Objects/Weapons/Guns/Pistols/soaker.rsi layers: @@ -112,8 +104,8 @@ detail2: Sixteen - type: entity + parent: [SolutionHuge, WeaponWaterGunBase] # 96 shots id: WeaponWaterBlasterSuper - parent: WeaponWaterGunBase name: super water blaster description: No! No! Not in the eyes! components: @@ -125,10 +117,6 @@ - FullAuto soundGunshot: path: /Audio/Weapons/Guns/Gunshots/water_spray.ogg - - type: SolutionContainerManager - solutions: - chamber: - maxVol: 500 #100 shots - type: Sprite sprite: Objects/Weapons/Guns/Pistols/soaker.rsi layers: @@ -140,8 +128,8 @@ - type: Item sprite: Objects/Weapons/Guns/Pistols/soaker.rsi size: Large - shape: # SMG size. - - 0,0,2,1 + shape: # Rifle Size. + - 0,0,2,2 - type: RandomSprite getAllGroups: true available: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml index d61b78f1ed..43a8190780 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml @@ -1,5 +1,5 @@ - type: entity - parent: BaseItem + parent: [BaseItem, SolutionDart] id: BaseArrow abstract: true components: @@ -41,17 +41,13 @@ damage: types: Piercing: 25 - - type: SolutionContainerManager - solutions: - ammo: - maxVol: 2 - type: RefillableSolution # This is sus. You can't really just run an arrowhead under a sink faucet. - solution: ammo + solution: melee - type: InjectableSolution - solution: ammo + solution: melee - type: SolutionInjectOnEmbed transferAmount: 2 - solution: ammo + solution: melee - type: SolutionTransfer maxTransferAmount: 2 - type: Appearance diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml index 45aadfbc57..bf22e87158 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml @@ -191,6 +191,11 @@ maxSpawn: 8 spawnAfter: 0.5 +- type: entity + abstract: true + parent: [SolutionHuge, BaseMeteor] + id: BaseSolutionMeteor + - type: entity parent: BaseMeteor id: MeteorUrist @@ -200,13 +205,11 @@ components: - type: Sprite state: human_pixel - - type: SolutionContainerManager - solutions: - blood: - maxVol: 1000 - reagents: - - ReagentId: Blood - Quantity: 1000 + - type: Solution + solution: + reagents: + - ReagentId: Blood + Quantity: 480 - type: Explosive totalIntensity: 25 - type: Destructible @@ -223,7 +226,7 @@ params: volume: 10 - !type:SpillBehavior - solution: blood + solution: solution - !type:SpawnEntitiesBehavior spawn: FoodMeatHuman: @@ -233,7 +236,7 @@ # Cow Meteor - type: entity - parent: BaseMeteor + parent: BaseSolutionMeteor id: MeteorCow name: Cosmic cow description: Moo-ving at relativistic speeds! @@ -243,13 +246,11 @@ state: cow_pixel - type: Explosive totalIntensity: 25 - - type: SolutionContainerManager - solutions: - milk: - maxVol: 500 - reagents: - - ReagentId: Milk - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Milk + Quantity: 480 - type: Destructible thresholds: - trigger: @@ -262,7 +263,7 @@ sound: path: /Audio/Animals/cow_moo.ogg - !type:SpillBehavior - solution: milk + solution: solution - !type:SpawnEntitiesBehavior spawn: FoodMeat: @@ -275,7 +276,7 @@ # Clown Meteor - type: entity - parent: BaseMeteor + parent: BaseSolutionMeteor id: MeteorClown name: Honksteroid description: The final honkening! @@ -285,13 +286,11 @@ state: clown_pixel - type: Explosive totalIntensity: 25 - - type: SolutionContainerManager - solutions: - laughter: - maxVol: 500 - reagents: - - ReagentId: Laughter - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Laughter + Quantity: 480 - type: Destructible thresholds: - trigger: @@ -304,7 +303,7 @@ sound: path: /Audio/Items/bikehorn.ogg - !type:SpillBehavior - solution: laughter + solution: solution - !type:SpawnEntitiesBehavior spawn: FoodMeatClown: @@ -320,7 +319,7 @@ # Potato Meteor - type: entity - parent: BaseMeteor + parent: BaseSolutionMeteor id: MeteorPotato name: Space potato description: A starchy threat from the depths of the space. Contains 200% of your daily sodium intake! @@ -329,13 +328,11 @@ state: potato - type: Explosive totalIntensity: 25 - - type: SolutionContainerManager - solutions: - ketchup: - maxVol: 100 - reagents: - - ReagentId: Ketchup - Quantity: 100 + - type: Solution + solution: + reagents: + - ReagentId: Ketchup + Quantity: 120 - type: Destructible thresholds: - trigger: @@ -345,7 +342,7 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - !type:SpillBehavior - solution: ketchup + solution: solution - !type:SpawnEntitiesBehavior spawn: FoodMealFries: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml index 721a89964b..b3c49b1d65 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml @@ -1012,6 +1012,7 @@ muzzleFlash: null - type: entity + parent: [SolutionVapor, SolutionSmall] id: BulletWaterShot name: water categories: [ HideSpawnMenu ] @@ -1034,10 +1035,6 @@ map: ["enum.VaporVisualLayers.Base"] - type: Ammo muzzleFlash: null - - type: SolutionContainerManager - solutions: - vapor: - maxVol: 50 - type: Fixtures fixtures: projectile: @@ -1407,7 +1404,7 @@ - Opaque - type: entity - parent: BaseBullet + parent: [SolutionAmmo, BaseBullet] id: EnergyCrossbowBolt categories: [ HideSpawnMenu ] name: energy bolt @@ -1436,13 +1433,12 @@ drop: false - type: StaminaDamageOnCollide #additional stam damage to make repeated pushups less of a viable counter damage: 45 - - type: SolutionContainerManager - solutions: - bolt: - maxVol: 1.5 - reagents: - - ReagentId: Toxin - Quantity: 1.5 + - type: Solution + solution: + maxVol: 1.5 + reagents: + - ReagentId: Toxin + Quantity: 1.5 - type: SolutionInjectOnProjectileHit transferAmount: 1.5 - solution: bolt + solution: ammo diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml index 13bac56bcd..8062684d08 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml @@ -40,7 +40,7 @@ - type: entity name: Kardashev-Mosin - parent: [BaseWeaponSniper, BaseGunWieldable, BaseMajorContraband] + parent: [BaseWeaponSniper, BaseGunWieldable, SolutionDart, BaseMajorContraband] id: WeaponSniperMosin description: A true relic, the Kardashev-Mosin has served in nearly every armed conflict since its creation 670 years ago. The bolt-action design of the rifle remains virtually identical to its original design, whether used for hunting, sniping, or endless trench warfare. Loads 10 rounds of .30 rifle. components: @@ -71,10 +71,6 @@ - type: MeleeRequiresWield - type: AltFireMelee attackType: Heavy - - type: SolutionContainerManager - solutions: - melee: - maxVol: 2 - type: MeleeChemicalInjector solution: melee - type: RefillableSolution diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/chainsaw.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/chainsaw.yml index bfdd94add6..c1fc5668b5 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/chainsaw.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/chainsaw.yml @@ -33,17 +33,10 @@ Slash: 4 Structural: 4 - type: Item - size: Normal + size: Large + shape: + - 0,0,2,2 sprite: Objects/Weapons/Melee/chainsaw.rsi - type: DisarmMalus - - type: RefillableSolution - solution: Welder - - type: SolutionContainerManager - solutions: - Welder: - reagents: - - ReagentId: WeldingFuel - Quantity: 300 - maxVol: 300 - type: UseDelay delay: 1 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml index b86b849874..0399ac8a1f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml @@ -1,6 +1,6 @@ - type: entity name: spear - parent: [BaseItem, BaseMinorContraband] + parent: [BaseItem, SolutionDart, BaseMinorContraband] id: Spear description: Definition of a Classic. Keeping murder affordable since 200,000 BCE. components: @@ -58,10 +58,6 @@ - type: Construction graph: Spear node: spear - - type: SolutionContainerManager - solutions: - melee: - maxVol: 2 - type: MeleeChemicalInjector solution: melee - type: RefillableSolution @@ -119,7 +115,6 @@ equippedFillBaseName: -fill- equippedMaxFillLevels: 1 - - type: entity name: reinforced spear parent: Spear diff --git a/Resources/Prototypes/Entities/Objects/Weapons/security.yml b/Resources/Prototypes/Entities/Objects/Weapons/security.yml index 6d5830e161..c839af07f0 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/security.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/security.yml @@ -71,10 +71,9 @@ - type: StaticPrice price: 80 - type: Riggable - - type: SolutionContainerManager + - type: SolutionManager solutions: - battery: - maxVol: 5 + - SolutionRiggable - type: InjectableSolution solution: battery - type: DrawableSolution diff --git a/Resources/Prototypes/Entities/Objects/base_solution.yml b/Resources/Prototypes/Entities/Objects/base_solution.yml new file mode 100644 index 0000000000..e492424779 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/base_solution.yml @@ -0,0 +1,363 @@ +- type: entity + id: Solution # Not abstract because it's a fallback for missing solution protos! + categories: [ HideSpawnMenu ] + name: solution + components: + - type: Solution + +- type: entity + id: SolutionCryo + categories: [ HideSpawnMenu ] + name: solution + components: + - type: Solution + solution: + canReact: false + +# Solution Types + +- type: entity + abstract: true + parent: Solution + id: SolutionBeaker + components: + - type: Solution + id: beaker + +- type: entity + abstract: true + parent: Solution + id: SolutionInjector + components: + - type: Solution + id: injector + +- type: entity + abstract: true + parent: Solution + id: SolutionHypospray + components: + - type: Solution + id: hypospray + +- type: entity + abstract: true + parent: Solution + id: SolutionFood # Generally these should only ever be half full. That way they can be poisoned! + components: + - type: Solution + id: food + +- type: entity + abstract: true + parent: Solution + id: SolutionDrink + components: + - type: Solution + id: drink + +- type: entity + abstract: true + parent: Solution + id: SolutionSmokable + components: + - type: Solution + id: smokable + +- type: entity + abstract: true + parent: Solution + id: SolutionWeapon + components: + - type: Solution + id: melee + +- type: entity + abstract: true + parent: Solution + id: SolutionGun + components: + - type: Solution + id: chamber + +- type: entity + abstract: true + parent: Solution + id: SolutionAmmo + components: + - type: Solution + id: ammo + +- type: entity + abstract: true + parent: Solution + id: SolutionVapor # TODO Check if this compsystem is identical to spray... + components: + - type: Solution + id: vapor + +- type: entity + abstract: true + parent: Solution + id: SolutionSpray + components: + - type: Solution + id: spray + +- type: entity + abstract: true + parent: Solution + id: SolutionTank + components: + - type: Solution + id: tank + +- type: entity + abstract: true + parent: Solution + id: SolutionMop + components: + - type: Solution + id: absorbed + +- type: entity + abstract: true + parent: Solution + id: SolutionDrain + components: + - type: Solution + id: drainBuffer + +- type: entity + abstract: true + parent: Solution + id: SolutionWelder # TODO Refactor fuel usage to comply with welders becoming 30u-60u + components: + - type: Solution + id: welder + +- type: entity + abstract: true + parent: Solution + id: SolutionComposite + components: + - type: Solution + id: composite + +- type: entity + abstract: true + parent: Solution + id: SolutionLube + components: + - type: Solution + id: lube # For autolathes to run faster or slower + +# Solution Sizes + +## Of note, maxVol will be moved out of the Solution class into the SolutionComponent in the future +## These prototypes are meant to generally correspond to an itemSizePrototype, and be used with containers of the same type +## So a beaker will use solutions with a parent of SolutionSmall and a large beaker uses SolutionNormal +## Items with utility or tool functionality should generally inherit from one sizer smaller than their item size. +## It's fine to fine tune these values for specific applications, but generally you shouldn't go above the value the most relevant parent would have. +## Lastly, 120u equals about 1 liter. It was random before but that's the conversion now. + +## Very Tiny + +- type: entity + parent: Solution + id: SolutionVeryTiny # For things smaller than tiny + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 15 + +- type: entity + parent: Solution + id: SolutionToolVeryTiny + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 7.5 + +## Tiny + +- type: entity + parent: Solution + id: SolutionTiny + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 30 + +- type: entity + abstract: true + parent: [SolutionComposite, BaseItem] + id: SolutionCompositeTinyStackable + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 2.5 + - type: Item + size: Tiny + +- type: entity + parent: Solution + id: SolutionToolTiny + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 15 + +## Small + +- type: entity + parent: Solution + id: SolutionSmall + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 60 + +- type: entity + abstract: true + parent: [SolutionComposite, BaseItem] + id: SolutionCompositeSmallStackable + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 5 + - type: Item + size: Small + +- type: entity + parent: Solution + id: SolutionToolSmall + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 30 + +## Normal + +- type: entity + parent: Solution + id: SolutionNormal + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 120 + +- type: entity + abstract: true + parent: [SolutionComposite, BaseItem] + id: SolutionCompositeNormalStackable + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 10 + - type: Item + size: Normal + +- type: entity + parent: Solution + id: SolutionToolNormal + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 60 + +## Large + +- type: entity + parent: Solution + id: SolutionLarge + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 240 + +- type: entity + parent: Solution + id: SolutionToolLarge + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 120 + +## Huge + +- type: entity + parent: Solution + id: SolutionHuge + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 480 + +- type: entity + parent: [SolutionDrink, SolutionHuge] + id: SolutionDrinkHuge + categories: [ HideSpawnMenu ] + +## Ginormous + +- type: entity + parent: Solution + id: SolutionGinormous + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 960 + +- type: entity + parent: Solution + id: SolutionToolGinormous + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 480 + +## Below sizes are for solutions attached to entities bigger than Ginormous, aka not items or maybe two handed? + +# List of sizes neede still + +## Huge +# 400 - GasCondenser + +## IDK +# 3000 - Nuclear Tap + +- type: entity + parent: Solution + id: Solution3840 # I can't think of a better name, fight me + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 3840 + +- type: entity + abstract: true + parent: Solution + id: SolutionTile # Tile Anchored, Cannot be moved. Anything more than this and you should just not impose a max volume. + categories: [ HideSpawnMenu ] + components: + - type: Solution + solution: + maxVol: 7680 diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml index 0be3cb900c..571ece4518 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml @@ -58,9 +58,9 @@ sound: collection: MetalGlassBreak - type: Storage - maxItemSize: Normal + maxItemSize: Large grid: - - 0,0,19,5 + - 0,0,15,11 - type: ReagentDispenser beakerSlot: whitelistFailPopup: reagent-dispenser-component-cannot-put-entity-message diff --git a/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml b/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml index 55d611808c..6e2979b653 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml @@ -233,8 +233,11 @@ - !type:SpawnEntitiesBehavior spawn: SheetSteel1: - min: 2 - max: 2 + min: 0 + max: 1 + SheetPlasteel1: + min: 0 + max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - type: IconSmooth diff --git a/Resources/Prototypes/Entities/Structures/Furniture/sink.yml b/Resources/Prototypes/Entities/Structures/Furniture/sink.yml index 8bfe0dcc06..19fb548789 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/sink.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/sink.yml @@ -1,8 +1,9 @@ - type: entity - name: sink + parent: [SolutionTank, SolutionHuge] id: SinkEmpty - suffix: Empty + name: sink description: The faucets have been tightened to the maximum possible torque but are still known to drip. + suffix: Empty placement: mode: SnapgridCenter components: @@ -20,12 +21,9 @@ maxFillLevels: 1 fillBaseName: sink-fill- solutionName: drainBuffer - - type: SolutionContainerManager + - type: SolutionManager solutions: - drainBuffer: - maxVol: 100 - tank: - maxVol: 500 + - SolutionDrainNormal - type: SolutionRegeneration solution: tank generated: @@ -69,24 +67,20 @@ - type: entity - name: sink - id: Sink parent: SinkEmpty + id: Sink suffix: Water components: - - type: SolutionContainerManager - solutions: - drainBuffer: - maxVol: 200 - tank: - reagents: - - ReagentId: Water - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 480 - type: entity - name: wide sink - id: SinkWide parent: Sink + id: SinkWide + name: wide sink components: - type: Sprite sprite: Structures/Furniture/sink.rsi @@ -121,11 +115,8 @@ parent: SinkStemless suffix: Water components: - - type: SolutionContainerManager - solutions: - drainBuffer: - maxVol: 100 - tank: - reagents: - - ReagentId: Water - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 480 diff --git a/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml b/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml index 79fc6f4ad9..c2853701c4 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [ DisposalUnitBase, SeatBase ] + parent: [ SolutionTank, SolutionHuge, DisposalUnitBase, SeatBase] id: BaseToilet name: toilet description: The HT-451, a torque rotation-based, waste disposal unit for small matter. This one seems remarkably clean. @@ -48,6 +48,7 @@ containers: stash: !type:ContainerSlot {} disposals: !type:Container + solutions: !type:Container - type: Physics bodyType: Static - type: Fixtures @@ -83,12 +84,9 @@ - type: Rummageable table: !type:NestedSelector tableId: RatKingLoot - - type: SolutionContainerManager + - type: SolutionManager solutions: - drainBuffer: - maxVol: 100 - tank: - maxVol: 500 + - SolutionDrainNormal - type: SolutionRegeneration solution: tank generated: @@ -134,17 +132,13 @@ id: ToiletDirtyWater suffix: Dirty Water components: - - type: SolutionContainerManager - solutions: - drainBuffer: - maxVol: 100 - tank: - maxVol: 500 - reagents: - - ReagentId: Water - Quantity: 180 - - ReagentId: GastroToxin - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 180 + - ReagentId: GastroToxin + Quantity: 20 - type: entity parent: ToiletEmpty @@ -213,16 +207,12 @@ components: - type: StealTarget stealGroup: ToiletGoldenDirtyWater - - type: SolutionContainerManager - solutions: - drainBuffer: - maxVol: 100 - tank: - maxVol: 500 - reagents: - - ReagentId: Water - Quantity: 160 - - ReagentId: Gold - Quantity: 20 - - ReagentId: GastroToxin - Quantity: 20 + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 160 + - ReagentId: Gold + Quantity: 20 + - ReagentId: GastroToxin + Quantity: 20 diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml index 02310ba196..d858bdcba0 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml @@ -106,10 +106,9 @@ - type: EmptyOnMachineDeconstruct containers: - scanner-body - - type: SolutionContainerManager + - type: SolutionManager solutions: - injectionBuffer: - maxVol: 50 + - SolutionCryoBuffer - type: CryoPod - type: CryoPodAir - type: Climbable # so that ejected bodies don't get stuck @@ -120,6 +119,14 @@ guides: - Cryogenics +- type: entity + parent: SolutionSmall + id: SolutionCryoBuffer + categories: [ HideSpawnMenu ] + components: + - type: Solution + id: injectionBuffer + - type: entity parent: BaseMachine id: CryoPodDestroyed diff --git a/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml b/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml index 7578820bd8..9fd79cc739 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml @@ -90,9 +90,8 @@ tags: - Bottle - PillCanister - - type: SolutionContainerManager - solutions: - buffer: {} + - type: Solution # Chemmaster is special in how it interacts with reagents. For now. + id: buffer - type: DumpableSolution solution: buffer unlimited: true diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index a34bab04da..7045fd3a24 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -66,10 +66,9 @@ modifiers: SpaceLube: 0.25 SpaceGlue: 5 - - type: SolutionContainerManager + - type: SolutionManager solutions: - lube: - maxVol: 250 + - SolutionLatheLube - type: Spillable solution: lube - type: RefillableSolution @@ -77,6 +76,11 @@ - type: ExaminableSolution solution: lube +- type: entity + parent: [SolutionLube, SolutionLarge] + id: SolutionLatheLube # Its own prototype since some lathes might interface with solutions in other ways + categories: [ HideSpawnMenu ] + - type: entity abstract: true id: BaseHyperlathe diff --git a/Resources/Prototypes/Entities/Structures/Machines/nuke.yml b/Resources/Prototypes/Entities/Structures/Machines/nuke.yml index 0ac4a9e98f..ae163cfacc 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/nuke.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/nuke.yml @@ -129,7 +129,7 @@ bodyType: Dynamic - type: entity - parent: StorageTank + parent: StorageTankBig id: NuclearBombKeg name: nuclear fission explosive suffix: keg @@ -175,12 +175,11 @@ - MachineMask layer: - WallLayer - - type: SolutionContainerManager - solutions: - tank: - reagents: - - ReagentId: NuclearCola - Quantity: 3000 + - type: Solution + solution: + reagents: + - ReagentId: NuclearCola + Quantity: 3840 - type: ReagentTank transferAmount: 100 - type: StaticPrice diff --git a/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml b/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml index 5109268189..abdd302ee4 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml @@ -78,15 +78,11 @@ - LargeBeaker - type: entity - parent: Recycler #too different so different parent + parent: [SolutionToolGinormous, Recycler] #too different so different parent id: ReagentGrinderIndustrial name: industrial reagent grinder description: An industrial reagent grinder. components: - - type: SolutionContainerManager - solutions: - output: - maxVol: 400 #*slaps roof of machine* This baby can fit so much omnizine in it - type: MaterialReclaimer whitelist: components: @@ -97,7 +93,7 @@ efficiency: 0.9 reclaimMaterials: false # Materials have ExtractableComponent, which is whitelisted, so we have to avoid infinite recycling loops onlyReclaimDrainable: false - solutionContainerId: output + solutionContainerId: solution - type: Sprite sprite: Structures/Machines/recycling.rsi layers: @@ -122,6 +118,6 @@ - machine_parts - machine_board - type: DrainableSolution - solution: output + solution: solution - type: ExaminableSolution - solution: output + solution: solution diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml index 612e144e53..663861db03 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml @@ -388,7 +388,7 @@ board: HellfireHeaterMachineCircuitBoard - type: entity - parent: [ BaseMachinePowered, SmallConstructibleMachine ] + parent: [ SolutionTank, SolutionHuge, BaseMachinePowered, SmallConstructibleMachine ] id: BaseGasCondenser name: condenser description: Condenses gases into liquids. Now we just need some plumbing. @@ -466,10 +466,6 @@ pipeDirection: South - type: Transform noRot: false - - type: SolutionContainerManager - solutions: - tank: - maxVol: 400 - type: MixableSolution solution: tank - type: DrainableSolution diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml index a7b55841e5..873ecd636e 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml @@ -245,13 +245,13 @@ supplyRampTolerance: 2500 - type: entity + parent: [SolutionTank, SolutionSmall, PortableGeneratorBase] + id: PortableGeneratorJrPacman name: J.R.P.A.C.M.A.N.-type portable generator description: |- A small generator capable of powering individual rooms, in case of emergencies. Runs off welding fuel and is rated for up to 8 kW. Rated ages 3 and up. - parent: PortableGeneratorBase - id: PortableGeneratorJrPacman suffix: Welding Fuel, 8 kW components: - type: AmbientSound @@ -303,10 +303,6 @@ solution: tank reagents: WeldingFuel: 1 - - type: SolutionContainerManager - solutions: - tank: - maxVol: 50 - type: RefillableSolution solution: tank - type: PortableGenerator diff --git a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml index 36d61bcc5f..d8dea2e463 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml @@ -910,10 +910,10 @@ maxRange: 2 spawns: - ReagentSlimeSpawner - - type: SolutionContainerManager - solutions: - anomaly: - maxVol: 1500 + - type: Solution + id: anomaly + solution: + maxVol: 1550 # Doesn't really matter since it's an anom anyways - type: PuddleCreateAnomaly solution: anomaly - type: InjectionAnomaly diff --git a/Resources/Prototypes/Entities/Structures/Specific/Janitor/drain.yml b/Resources/Prototypes/Entities/Structures/Specific/Janitor/drain.yml index 7e7264c9a7..0520a0e330 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Janitor/drain.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Janitor/drain.yml @@ -1,4 +1,5 @@ - type: entity + parent: [SolutionDrain, SolutionGinormous] id: FloorDrain name: drain description: Drains puddles around it. Useful for dumping mop buckets or keeping certain rooms clean. @@ -34,10 +35,6 @@ maxFillLevels: 1 fillBaseName: fill- solutionName: drainBuffer - - type: SolutionContainerManager - solutions: - drainBuffer: - maxVol: 1000 - type: Damageable damageModifierSet: StructuralMetallic - type: Injurable @@ -59,3 +56,8 @@ - !type:PlaySoundBehavior sound: collection: MetalBreak + +- type: entity + parent: [SolutionDrain, SolutionNormal] + id: SolutionDrainNormal + categories: [ HideSpawnMenu ] diff --git a/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml b/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml index d38321ba8d..84c8208320 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml @@ -1,8 +1,8 @@ # Mop Bucket - type: entity - name: mop bucket + parent: [SolutionGinormous, SolutionTank, BaseStructureDynamic, StructureWheeled] id: MopBucket - parent: [BaseStructureDynamic, StructureWheeled] + name: mop bucket description: Holds water and the tears of the janitor. components: - type: Clickable @@ -16,20 +16,16 @@ visible: false drawdepth: Objects - type: InteractionOutline - - type: SolutionContainerManager - solutions: - bucket: - maxVol: 600 - type: Spillable - solution: bucket + solution: tank spillDelay: 3.0 spillWhenThrown: false - type: DrainableSolution - solution: bucket + solution: tank - type: RefillableSolution - solution: bucket + solution: tank - type: ExaminableSolution - solution: bucket + solution: tank - type: ItemMapper mapLayers: mopbucket_shark_blue: @@ -76,11 +72,11 @@ - Rehydratable priority: 3 # Higher than drinking priority - type: ReactiveContainer - solution: bucket + solution: tank container: item_slot - type: Edible edible: Drink - solution: bucket + solution: tank destroyOnEmpty: false utensil: Spoon - type: Appearance @@ -125,16 +121,14 @@ components: - type: Sprite layers: - - state: mopbucket - - state: mopbucket_water-3 - map: [ "enum.SolutionContainerLayers.Fill" ] - - type: SolutionContainerManager - solutions: - bucket: - maxVol: 600 - reagents: - - ReagentId: Water - Quantity: 600 + - state: mopbucket + - state: mopbucket_water-3 + map: [ "enum.SolutionContainerLayers.Fill" ] + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 960 - type: entity parent: BaseWrappedCube @@ -150,226 +144,232 @@ # Janicart - type: entity - name: janitorial trolley + parent: [SolutionGinormous, SolutionTank, BaseStructureDynamic, StructureWheeled] id: JanitorialTrolley - parent: [BaseStructureDynamic, StructureWheeled] + name: janitorial trolley description: This is the alpha and omega of sanitation. components: - - type: Sprite - noRot: true - sprite: Objects/Specific/Janitorial/janitorial_cart.rsi - layers: - - state: cart - - state: cart_water-1 - map: ["enum.SolutionContainerLayers.Fill"] - visible: false - - type: Rotatable - - type: InteractionOutline - - type: ItemSlots - slots: - mop_slot: - name: janitorial-trolley-slot-component-slot-name-mop - whitelist: - tags: - - Mop - insertOnInteract: false # or it conflicts with bucket logic - priority: 9 # Higher than bucket slot - plunger_slot: - name: janitorial-trolley-slot-component-slot-name-plunger - whitelist: - tags: - - Plunger - - GoldenPlunger - priority: 8 - wetfloorsign_slot4: - name: janitorial-trolley-slot-component-slot-name-sign - whitelist: - tags: - - WetFloorSign - priority: 7 - wetfloorsign_slot3: - name: janitorial-trolley-slot-component-slot-name-sign - whitelist: - tags: - - WetFloorSign - priority: 7 - wetfloorsign_slot2: - name: janitorial-trolley-slot-component-slot-name-sign - whitelist: - tags: - - WetFloorSign - priority: 7 - wetfloorsign_slot1: - name: janitorial-trolley-slot-component-slot-name-sign - whitelist: - tags: - - WetFloorSign - priority: 7 - lightreplacer_slot: - name: janitorial-trolley-slot-component-slot-name-lightreplacer - whitelist: - components: - - LightReplacer - priority: 6 - spraybottle_slot: - name: janitorial-trolley-slot-component-slot-name-spray - whitelist: - tags: - - Spray - insertOnInteract: false # or it conflicts with bucket logic - priority: 5 # Higher than bucket slot - bucket_slot: - name: janitorial-trolley-slot-component-slot-name-bucket - whitelist: - tags: - - Bucket - insertOnInteract: false # or it also conflicts with bucket logic - priority: 4 # Higher than trash bag slot - trashbag_slot: - name: janitorial-trolley-slot-component-slot-name-trashbag - whitelist: - tags: - - TrashBag - - TrashBagBlue - priority: 3 # Higher than drinking priority - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeCircle - radius: 0.3 - density: 250 - layer: - - MobLayer - mask: - - MobMask - - type: Spillable - solution: bucket - spillDelay: 3.0 - spillWhenThrown: false - - type: SolutionContainerManager - solutions: - bucket: - maxVol: 800 + - type: Sprite + noRot: true + sprite: Objects/Specific/Janitorial/janitorial_cart.rsi + layers: + - state: cart + - state: cart_water-1 + map: ["enum.SolutionContainerLayers.Fill"] + visible: false + - type: Rotatable + - type: InteractionOutline + # Removing storage until OnInteractUsing logic resolved + #- type: Storage + # popup: false + # capacity: 80 + # blacklist: # there is exclusive item slots for that + # tags: + # - Mop + # - TrashBag + # - Bucket + - type: ItemSlots + slots: + mop_slot: + name: janitorial-trolley-slot-component-slot-name-mop + whitelist: + tags: + - Mop + insertOnInteract: false # or it conflicts with bucket logic + priority: 9 # Higher than bucket slot + plunger_slot: + name: janitorial-trolley-slot-component-slot-name-plunger + whitelist: + tags: + - Plunger + - GoldenPlunger + priority: 8 + wetfloorsign_slot4: + name: janitorial-trolley-slot-component-slot-name-sign + whitelist: + tags: + - WetFloorSign + priority: 7 + wetfloorsign_slot3: + name: janitorial-trolley-slot-component-slot-name-sign + whitelist: + tags: + - WetFloorSign + priority: 7 + wetfloorsign_slot2: + name: janitorial-trolley-slot-component-slot-name-sign + whitelist: + tags: + - WetFloorSign + priority: 7 + wetfloorsign_slot1: + name: janitorial-trolley-slot-component-slot-name-sign + whitelist: + tags: + - WetFloorSign + priority: 7 + lightreplacer_slot: + name: janitorial-trolley-slot-component-slot-name-lightreplacer + whitelist: + components: + - LightReplacer + priority: 6 + spraybottle_slot: + name: janitorial-trolley-slot-component-slot-name-spray + whitelist: + tags: + - Spray + insertOnInteract: false # or it conflicts with bucket logic + priority: 5 # Higher than bucket slot + bucket_slot: + name: janitorial-trolley-slot-component-slot-name-bucket + whitelist: + tags: + - Bucket + insertOnInteract: false # or it also conflicts with bucket logic + priority: 4 # Higher than trash bag slot + trashbag_slot: + name: janitorial-trolley-slot-component-slot-name-trashbag + whitelist: + tags: + - TrashBag + priority: 3 # Higher than drinking priority + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.3 + density: 250 + layer: + - MobLayer + mask: + - MobMask + - type: Spillable + solution: tank + spillDelay: 3.0 + spillWhenThrown: false + - type: Solution + solution: reagents: - ReagentId: Water - Quantity: 600 # 3 quarters full at roundstart to make it more appealing - - type: DrainableSolution - solution: bucket - - type: RefillableSolution - solution: bucket - - type: ExaminableSolution - solution: bucket - - type: Damageable - damageModifierSet: Metallic - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 400 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - trigger: - !type:DamageTrigger - damage: 200 - behaviors: - - !type:EmptyAllContainersBehaviour - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - - type: ItemMapper - mapLayers: - cart_plunger: - whitelist: - tags: - - Plunger - cart_goldenplunger: - whitelist: - tags: - - GoldenPlunger - cart_mop: - whitelist: - tags: - - MopBasic - cart_advmop: - whitelist: - tags: - - MopAdv - cart_garbage: - whitelist: - tags: - - TrashBag - cart_garbage_blue: - whitelist: - tags: - - TrashBagBlue - cart_replacer: - whitelist: - components: - - LightReplacer - cart_spray: - whitelist: - tags: - - Spray - cart_sign1: # this is like stack of floor signs - minCount: 1 - whitelist: - tags: - - WetFloorSign - cart_sign2: - minCount: 2 - whitelist: - tags: - - WetFloorSign - cart_sign3: - minCount: 3 - whitelist: - tags: - - WetFloorSign - cart_sign4: - minCount: 4 - whitelist: - tags: - - WetFloorSign - cart_bucket: - whitelist: - tags: - - Bucket - sprite: Objects/Specific/Janitorial/janitorial_cart.rsi - - type: Appearance - - type: SolutionContainerVisuals - maxFillLevels: 3 - fillBaseName: cart_water- - - type: UserInterface - interfaces: - enum.StorageUiKey.Key: - type: StorageBoundUserInterface - - type: Edible - edible: Drink - solution: bucket - destroyOnEmpty: false - utensil: Spoon - - type: ContainerContainer - containers: - storagebase: !type:Container - ents: [] - mop_slot: !type:ContainerSlot {} - trashbag_slot: !type:ContainerSlot {} - bucket_slot: !type:ContainerSlot {} - plunger_slot: !type:ContainerSlot {} - goldenplunger_slot: !type:ContainerSlot {} - wetfloorsign_slot4: !type:ContainerSlot {} - wetfloorsign_slot3: !type:ContainerSlot {} - wetfloorsign_slot2: !type:ContainerSlot {} - wetfloorsign_slot1: !type:ContainerSlot {} - lightreplacer_slot: !type:ContainerSlot {} - spraybottle_slot: !type:ContainerSlot {} - - type: GuideHelp - guides: - - Janitorial - - type: DnaSubstanceTrace + Quantity: 960 + - type: DrainableSolution + solution: tank + - type: RefillableSolution + solution: tank + - type: ExaminableSolution + solution: tank + - type: Damageable + damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 400 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - trigger: + !type:DamageTrigger + damage: 200 + behaviors: + - !type:EmptyAllContainersBehaviour + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - type: ItemMapper + mapLayers: + cart_plunger: + whitelist: + tags: + - Plunger + cart_goldenplunger: + whitelist: + tags: + - GoldenPlunger + cart_mop: + whitelist: + tags: + - MopBasic + cart_advmop: + whitelist: + tags: + - MopAdv + cart_garbage: + whitelist: + tags: + - TrashBag + cart_garbage_blue: + whitelist: + tags: + - TrashBagBlue + cart_replacer: + whitelist: + components: + - LightReplacer + cart_spray: + whitelist: + tags: + - Spray + cart_sign1: # this is like stack of floor signs + minCount: 1 + whitelist: + tags: + - WetFloorSign + cart_sign2: + minCount: 2 + whitelist: + tags: + - WetFloorSign + cart_sign3: + minCount: 3 + whitelist: + tags: + - WetFloorSign + cart_sign4: + minCount: 4 + whitelist: + tags: + - WetFloorSign + cart_bucket: + whitelist: + tags: + - Bucket + sprite: Objects/Specific/Janitorial/janitorial_cart.rsi + - type: Appearance + - type: SolutionContainerVisuals + maxFillLevels: 3 + fillBaseName: cart_water- + - type: UserInterface + interfaces: + enum.StorageUiKey.Key: + type: StorageBoundUserInterface + - type: Edible + edible: Drink + solution: tank + destroyOnEmpty: false + utensil: Spoon + - type: ContainerContainer + containers: + storagebase: !type:Container + ents: [] + mop_slot: !type:ContainerSlot {} + trashbag_slot: !type:ContainerSlot {} + bucket_slot: !type:ContainerSlot {} + plunger_slot: !type:ContainerSlot {} + goldenplunger_slot: !type:ContainerSlot {} + wetfloorsign_slot4: !type:ContainerSlot {} + wetfloorsign_slot3: !type:ContainerSlot {} + wetfloorsign_slot2: !type:ContainerSlot {} + wetfloorsign_slot1: !type:ContainerSlot {} + lightreplacer_slot: !type:ContainerSlot {} + spraybottle_slot: !type:ContainerSlot {} + - type: GuideHelp + guides: + - Janitorial + - type: DnaSubstanceTrace diff --git a/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml b/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml index ef0ca38e74..bf2b443e6a 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml @@ -1,6 +1,6 @@ - type: entity id: StorageTank - parent: BaseStructureDynamic + parent: [SolutionTank, SolutionGinormous, BaseStructureDynamic] name: storage tank description: A liquids storage tank. abstract: true @@ -59,10 +59,6 @@ collection: MetalBreak - !type:DoActsBehavior acts: ["Destruction"] - - type: SolutionContainerManager - solutions: - tank: - maxVol: 1500 - type: DrainableSolution solution: tank - type: ReagentTank @@ -71,9 +67,9 @@ # For highcap tanks - type: entity - id: StorageTankBig - parent: StorageTank abstract: true + parent: [SolutionTank, Solution3840, StorageTank] + id: StorageTankBig components: - type: Fixtures fixtures: diff --git a/Resources/Prototypes/Entities/Structures/Storage/Tanks/tanks.yml b/Resources/Prototypes/Entities/Structures/Storage/Tanks/tanks.yml index e7fcf964d1..2f812e302f 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Tanks/tanks.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Tanks/tanks.yml @@ -39,12 +39,11 @@ parent: WeldingFuelTank suffix: Full components: - - type: SolutionContainerManager - solutions: - tank: - reagents: - - ReagentId: WeldingFuel - Quantity: 1500 + - type: Solution + solution: + reagents: + - ReagentId: WeldingFuel + Quantity: 960 - type: entity parent: [StorageTankBig, WeldingFuelTank] # StorageTankBig must come first, or else the desnity won't get inherited. @@ -65,13 +64,11 @@ - type: SolutionContainerVisuals maxFillLevels: 7 fillBaseName: highfueltank-2- - - type: SolutionContainerManager - solutions: - tank: - reagents: - - ReagentId: WeldingFuel - Quantity: 5000 - maxVol: 5000 + - type: Solution + solution: + reagents: + - ReagentId: WeldingFuel + Quantity: 3840 - type: Explosive explosionType: Default totalIntensity: 120 @@ -106,15 +103,14 @@ id: WaterTankFull suffix: Full components: - - type: SolutionContainerManager - solutions: - tank: - reagents: - - ReagentId: Water - Quantity: 1500 + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 960 - type: entity - parent: StorageTank + parent: [SolutionHuge, StorageTank] id: WaterCooler name: water cooler description: Seems like a good place to stand and waste time. It has a stock of paper cups on the side. @@ -130,12 +126,11 @@ - type: SolutionContainerVisuals maxFillLevels: 4 fillBaseName: watercooler-2- - - type: SolutionContainerManager - solutions: - tank: - reagents: - - ReagentId: Water - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 480 - type: ContainerContainer containers: bin-container: !type:Container @@ -182,15 +177,11 @@ - type: SolutionContainerVisuals maxFillLevels: 7 fillBaseName: highwatertank-2- - - type: SolutionContainerManager - solutions: - tank: - reagents: - - ReagentId: Water -# This is *100, 000* on /tg/ - Quantity: 10000 - maxVol: 10000 -# It's pressurized... + - type: Solution + solution: + reagents: + - ReagentId: Water + Quantity: 3840 # This is *100, 000* on /tg/ - type: ExaminableSolution solution: tank - type: ReagentTank diff --git a/Resources/Prototypes/Entities/Structures/Storage/barrels.yml b/Resources/Prototypes/Entities/Structures/Storage/barrels.yml index cbc71babe0..b429f69584 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/barrels.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/barrels.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ StorageTank ] + parent: StorageTank id: BaseBarrelChem abstract: true name: chemical barrel @@ -39,10 +39,6 @@ collection: MetalBreak - !type:DoActsBehavior acts: ["Destruction"] - - type: SolutionContainerManager - solutions: - tank: - maxVol: 500 - type: PhysicalComposition materialComposition: Steel: 3000 # 30 sheets, 1 stack @@ -97,78 +93,66 @@ id: BarrelChemFilledIodine suffix: Iodine components: - - type: SolutionContainerManager - solutions: - tank: - maxVol: 500 - reagents: - - ReagentId: Iodine - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Iodine + Quantity: 960 - type: entity parent: BaseBarrelChem id: BarrelChemFilledFluorine suffix: Fluorine components: - - type: SolutionContainerManager - solutions: - tank: - maxVol: 500 - reagents: - - ReagentId: Fluorine - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Fluorine + Quantity: 960 - type: entity parent: BaseBarrelChem id: BarrelChemFilledChlorine suffix: Chlorine components: - - type: SolutionContainerManager - solutions: - tank: - maxVol: 500 - reagents: - - ReagentId: Chlorine - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Chlorine + Quantity: 960 - type: entity parent: BaseBarrelChem id: BarrelChemFilledEthanol suffix: Ethanol components: - - type: SolutionContainerManager - solutions: - tank: - maxVol: 500 - reagents: - - ReagentId: Ethanol - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Ethanol + Quantity: 960 - type: entity parent: BaseBarrelChem id: BarrelChemFilledPhosphorus suffix: Phosphorus components: - - type: SolutionContainerManager - solutions: - tank: - maxVol: 500 - reagents: - - ReagentId: Phosphorus - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Phosphorus + Quantity: 960 - type: entity parent: BaseBarrelChem id: BarrelChemFilledMercury suffix: Mercury components: - - type: SolutionContainerManager - solutions: - tank: - maxVol: 500 - reagents: - - ReagentId: Mercury - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Mercury + Quantity: 960 - type: entity parent: BaseBarrelChem @@ -177,13 +161,11 @@ components: - type: Sprite state: silicatebarrel - - type: SolutionContainerManager - solutions: - tank: - maxVol: 500 - reagents: - - ReagentId: Silicon - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Silicon + Quantity: 960 - type: entity parent: BaseBarrelChem @@ -193,13 +175,11 @@ components: - type: Sprite state: silicatebarrel - - type: SolutionContainerManager - solutions: - tank: - maxVol: 500 - reagents: - - ReagentId: SpaceLube - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: SpaceLube + Quantity: 960 - type: entity parent: BaseBarrelChemRadioactive @@ -211,23 +191,19 @@ id: BaseBarrelChemRadioactiveFilledRadium suffix: Radium components: - - type: SolutionContainerManager - solutions: - tank: - maxVol: 500 - reagents: - - ReagentId: Radium - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Radium + Quantity: 960 - type: entity parent: BaseBarrelChemRadioactive id: BaseBarrelChemRadioactiveFilledUranium suffix: Uranium components: - - type: SolutionContainerManager - solutions: - tank: - maxVol: 500 - reagents: - - ReagentId: Uranium - Quantity: 500 + - type: Solution + solution: + reagents: + - ReagentId: Uranium + Quantity: 960 diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/wall_dispensers.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/wall_dispensers.yml index cfcbd59dc2..e4d7607b9f 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/wall_dispensers.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/wall_dispensers.yml @@ -1,7 +1,7 @@ - type: entity - parent: BaseWallmountMetallic - id: BaseDispenser abstract: true + parent: [SolutionTank, SolutionGinormous, BaseWallmountMetallic] + id: BaseDispenser components: - type: Sprite sprite: Structures/Wallmounts/walldispenser.rsi @@ -60,13 +60,11 @@ - type: SolutionContainerVisuals maxFillLevels: 5 fillBaseName: fill- - - type: SolutionContainerManager - solutions: - tank: - maxVol: 5000 - reagents: - - ReagentId: SpaceCleaner - Quantity: 5000 + - type: Solution + solution: + reagents: + - ReagentId: SpaceCleaner + Quantity: 960 - type: entity parent: BaseDispenser @@ -83,13 +81,11 @@ - type: SolutionContainerVisuals maxFillLevels: 5 fillBaseName: fill- - - type: SolutionContainerManager - solutions: - tank: - maxVol: 1000 - reagents: - - ReagentId: WeldingFuel - Quantity: 1000 + - type: Solution + solution: + reagents: + - ReagentId: WeldingFuel + Quantity: 960 - type: ReagentTank tankType: Fuel - type: DamageOnToolInteract diff --git a/Resources/Prototypes/Entities/Structures/Walls/walls.yml b/Resources/Prototypes/Entities/Structures/Walls/walls.yml index a9872366ee..828b20059c 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/walls.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/walls.yml @@ -943,7 +943,7 @@ - !type:DoActsBehavior acts: ["Destruction"] - type: StaticPrice - price: 250 + price: 300 - type: RadiationBlocker resistance: 5 - type: Sprite diff --git a/Resources/Prototypes/Entities/Structures/soil.yml b/Resources/Prototypes/Entities/Structures/soil.yml index 9aa084dd92..a999781300 100644 --- a/Resources/Prototypes/Entities/Structures/soil.yml +++ b/Resources/Prototypes/Entities/Structures/soil.yml @@ -1,4 +1,5 @@ - type: entity + parent: SolutionLarge id: hydroponicsSoil name: soil description: A mix of organic matter and minerals creating a soil to grow your plant in space. Seems to be dry. @@ -39,10 +40,8 @@ noRot: true - type: PlantHolder drawWarnings: false - - type: SolutionContainerManager - solutions: - soil: - maxVol: 200 + - type: Solution + id: soil - type: RefillableSolution solution: soil maxRefill: 50 diff --git a/Resources/Prototypes/Entities/Structures/spider_web.yml b/Resources/Prototypes/Entities/Structures/spider_web.yml index 1b039be8ea..e421c99577 100644 --- a/Resources/Prototypes/Entities/Structures/spider_web.yml +++ b/Resources/Prototypes/Entities/Structures/spider_web.yml @@ -95,7 +95,7 @@ - type: entity id: SpiderWebClown - parent: SpiderWebBase + parent: [SolutionFood, SolutionVeryTiny, SpiderWebBase] name: clown spider web description: It's stringy and slippy. components: @@ -127,9 +127,12 @@ - sweet - type: Edible delay: 2 - - type: SolutionContainerManager - solutions: - food: - reagents: - - ReagentId: Sugar - Quantity: 2 + - type: Solution + solution: + reagents: + - ReagentId: Sugar + Quantity: 2.5 + - ReagentId: Honk + Quantity: 2.5 + - ReagentId: SpaceLube + Quantity: 2.5 diff --git a/Resources/Prototypes/Entities/Tiles/water.yml b/Resources/Prototypes/Entities/Tiles/water.yml index a4478b5e58..d4f2616bf0 100644 --- a/Resources/Prototypes/Entities/Tiles/water.yml +++ b/Resources/Prototypes/Entities/Tiles/water.yml @@ -1,4 +1,5 @@ - type: entity + parent: SolutionTile id: FloorWaterEntity name: water description: A real thirst quencher. @@ -17,15 +18,14 @@ drawdepth: BelowFloor layers: - state: shoreline_water - - type: SolutionContainerManager - solutions: - pool: - maxVol: 9999999 #.inf seems to break the whole yaml file, but would definitely be preferable. - reagents: - - ReagentId: Water - Quantity: 9999999 + - type: Solution + id: pool + solution: + reagents: + - ReagentId: Water + Quantity: 7680 - type: SolutionRegeneration - solution: tank + solution: pool generated: reagents: - ReagentId: Water diff --git a/Resources/Prototypes/Reagents/fun.yml b/Resources/Prototypes/Reagents/fun.yml index f9b99cc5b9..6552f99cdd 100644 --- a/Resources/Prototypes/Reagents/fun.yml +++ b/Resources/Prototypes/Reagents/fun.yml @@ -146,9 +146,9 @@ color: "#86530E" - type: reagent - id: Saxoite - name: reagent-name-saxoite - desc: reagent-desc-saxoite + id: Brass + name: reagent-name-brass + desc: reagent-desc-brass physicalDesc: reagent-physical-desc-ground-brass flavor: sax color: "#B8A603" diff --git a/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml b/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml index 8499e88470..97ee7e8595 100644 --- a/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml +++ b/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml @@ -140,7 +140,7 @@ time: 10 group: Savory reagents: - Mayo: 5 + Mayo: 2 solids: FoodBreadBun: 1 FoodMeatChicken: 1 @@ -272,7 +272,7 @@ time: 10 group: Savory reagents: - Egg: 12 + Egg: 6 solids: FoodBreadBun: 1 FoodCheeseSlice: 1 @@ -286,7 +286,7 @@ solids: FoodBreadBun: 1 FoodMealRibs: 1 - FoodOnionSlice: 1 + FoodOnionSlice: 5 - type: microwaveMealRecipe id: RecipeMimeBurger @@ -337,7 +337,7 @@ group: Savory solids: FoodBreadBun: 1 - FoodCheeseSlice: 2 + FoodCheeseSlice: 1 FoodSoybeans: 2 #replace with soylent green when those become craftable - type: microwaveMealRecipe @@ -362,7 +362,7 @@ solids: FoodBreadBun: 1 FoodMeat: 2 - FoodCheeseSlice: 2 + FoodCheeseSlice: 1 FoodTomato: 2 - type: microwaveMealRecipe @@ -425,7 +425,7 @@ Milk: 5 solids: FoodDough: 1 - FoodCheeseSlice: 2 + FoodCheeseSlice: 1 - type: microwaveMealRecipe id: RecipeMeatBread @@ -436,7 +436,7 @@ solids: FoodDough: 1 FoodMeatCutlet: 2 - FoodCheeseSlice: 2 + FoodCheeseSlice: 1 - type: microwaveMealRecipe id: RecipeMimanaBread @@ -448,7 +448,7 @@ Nothing: 5 solids: FoodDough: 1 - FoodMimana: 1 + FoodMimana: 2 - type: microwaveMealRecipe id: RecipeBread @@ -487,7 +487,7 @@ solids: FoodDough: 1 FoodMeatSpiderCutlet: 2 - FoodCheeseSlice: 2 + FoodCheeseSlice: 1 - type: microwaveMealRecipe id: RecipeTofuBread @@ -497,7 +497,7 @@ group: Breads solids: FoodDough: 1 - FoodTofu: 1 + FoodTofuSlice: 1 - type: microwaveMealRecipe id: RecipeXenoMeatBread @@ -568,7 +568,7 @@ group: Breakfast reagents: Milk: 5 - Egg: 12 + Egg: 6 solids: FoodBreadPlainSlice: 1 @@ -766,7 +766,7 @@ group: Pasta solids: FoodNoodlesBoiled: 1 - FoodMeatMeatball: 2 + FoodMeatMeatball: 1 - type: microwaveMealRecipe id: RecipeButterNoodles @@ -776,7 +776,7 @@ group: Pasta solids: FoodNoodlesBoiled: 1 - FoodButter: 1 + FoodButterSlice: 2 - type: microwaveMealRecipe id: RecipeChowMein @@ -799,8 +799,8 @@ time: 15 group: Savory reagents: - Oats: 15 - Water: 10 + Oats: 20 + Water: 20 solids: FoodBowlBig: 1 @@ -811,8 +811,8 @@ time: 15 group: Savory reagents: - Rice: 15 - Water: 10 + Rice: 20 + Water: 20 solids: FoodBowlBig: 1 @@ -823,8 +823,9 @@ time: 15 group: Dessert reagents: - Rice: 15 - Milk: 10 + Rice: 10 + Milk: 30 + Egg: 6 Sugar: 5 solids: FoodBowlBig: 1 @@ -847,7 +848,7 @@ group: Savory solids: FoodRiceBoiled: 1 - FoodMeatCutlet: 3 + FoodMeatCutlet: 2 FoodChiliPepper: 2 - type: microwaveMealRecipe @@ -894,7 +895,7 @@ time: 10 group: Soup reagents: - Water: 10 + Water: 20 solids: FoodBowlBig: 1 FoodMeatMeatball: 1 @@ -913,6 +914,7 @@ solids: FoodBowlBig: 1 Nettle: 1 + FoodAmbrosiaDeus: 1 FoodPotato: 1 - type: microwaveMealRecipe @@ -1015,10 +1017,10 @@ time: 10 group: Soup reagents: - Soysauce: 5 + Soysauce: 10 solids: FoodBowlBig: 1 - FoodMeatXenoCutlet: 2 + FoodMeatXenoCutlet: 5 - type: microwaveMealRecipe id: RecipeWingFangChuSoupSpider @@ -1058,6 +1060,7 @@ solids: FoodBowlBig: 1 FoodBanana: 1 + MaterialBananium: 1 ShardGlass: 1 #idk probably replace shard with someting bananium when #14663 merged @@ -1098,7 +1101,7 @@ reagents: Water: 10 solids: - FoodMeatSnail: 1 + MobSnail: 1 - type: microwaveMealRecipe id: RecipeEscargotSoup @@ -1111,7 +1114,8 @@ solids: FoodBowlBig: 1 FoodOnionSlice: 1 - FoodButter: 1 + FoodGarlic: 1 + FoodButterSlice: 2 FoodMeatSnailCooked: 1 #Pies @@ -1304,7 +1308,7 @@ time: 15 group: Savory solids: - FoodDough: 1 + FoodDoughSlice: 1 FoodCheeseSlice: 2 FoodChiliPepper: 1 FoodMeatFish: 2 @@ -1318,7 +1322,7 @@ reagents: TableSalt: 1 solids: - FoodMeatFish: 2 + FoodMeatFish: 1 - type: microwaveMealRecipe id: RecipeMisoColaSoup @@ -1550,7 +1554,7 @@ group: Cake solids: FoodCakePlain: 1 - FoodCarrot: 3 + FoodCarrot: 2 - type: microwaveMealRecipe id: RecipeLemonCake @@ -1570,7 +1574,7 @@ group: Cake solids: FoodCakePlain: 1 - FoodLemoon: 2 + FoodLemoon: 1 FoodBerries: 1 #dark colouring - type: microwaveMealRecipe @@ -1733,9 +1737,9 @@ group: Savory reagents: Water: 10 - UncookedAnimalProteins: 6 + UncookedAnimalProteins: 2 solids: - FoodDoughSlice: 3 + FoodDoughSlice: 1 - type: microwaveMealRecipe id: RecipeBrownies @@ -1748,7 +1752,7 @@ Sugar: 30 Egg: 18 solids: - FoodButter: 2 + FoodButter: 1 FoodSnackChocolateBar: 2 #Donks i guess @@ -1861,7 +1865,7 @@ time: 5 group: Soup reagents: - Nitrogen: 5 + FrostOil: 10 solids: FoodSoupChiliHot: 1 @@ -1911,7 +1915,7 @@ time: 15 group: Savory reagents: - BbqSauce: 5 + BbqSauce: 10 solids: FoodMeat: 2 FoodKebabSkewer: 1 @@ -1923,9 +1927,9 @@ time: 20 group: Savory solids: - FoodChiliPepper: 2 - FoodMeatCutlet: 1 - FoodCorn: 1 + FoodChiliPepper: 1 + FoodMeatCutlet: 2 + FoodDoughTortillaFlat: 1 # SALADS: These should be moved out of the microwave as soon as possible - type: microwaveMealRecipe @@ -1947,7 +1951,7 @@ group: Salad solids: FoodBowlBig: 1 - FoodAmbrosiaVulgaris: 3 + FoodAmbrosiaVulgaris: 2 FoodPotato: 1 FoodMeatMeatball: 1 @@ -1961,8 +1965,8 @@ Vinaigrette: 5 solids: FoodBowlBig: 1 - FoodOnionRed: 1 - FoodCabbage: 1 + FoodOnionRed: 2 + FoodCabbage: 2 - type: microwaveMealRecipe id: RecipeCaesarSalad @@ -2002,7 +2006,7 @@ solids: FoodBowlBig: 1 FoodCarrot: 1 - FoodCabbage: 1 + FoodCabbage: 2 FoodGarlic: 1 - type: microwaveMealRecipe @@ -2016,7 +2020,7 @@ FoodOrange: 1 FoodApple: 1 FoodGrape: 1 - FoodWatermelonSlice: 2 + FoodWatermelonSlice: 1 - type: microwaveMealRecipe id: RecipeJungleSalad @@ -2029,7 +2033,7 @@ FoodBanana: 1 FoodApple: 1 FoodGrape: 1 - FoodWatermelonSlice: 2 + FoodWatermelonSlice: 1 - type: microwaveMealRecipe id: RecipeWatermelonFruitBowlSalad @@ -2196,7 +2200,7 @@ time: 15 solids: FoodButter: 1 - LeavesCannabis: 6 + LeavesCannabis: 1 - type: microwaveMealRecipe id: RecipeCannabisBrownies @@ -2209,7 +2213,7 @@ Sugar: 30 Egg: 18 solids: - FoodCannabisButter: 2 + FoodCannabisButter: 1 FoodSnackChocolateBar: 2 - type: microwaveMealRecipe @@ -2221,7 +2225,7 @@ solids: FoodCorn: 1 FoodPlate: 1 - FoodButter: 1 + FoodButterSlice: 1 - type: microwaveMealRecipe id: RecipePeaSoup @@ -2230,10 +2234,10 @@ time: 10 group: Soup solids: - FoodPeaPod: 2 + FoodPeaPod: 3 FoodBowlBig: 1 reagents: - Water: 10 + Water: 20 - type: microwaveMealRecipe id: RecipeTacoShell @@ -2242,7 +2246,7 @@ time: 5 group: Breads solids: - FoodDoughTortillaFlat: 1 # one third of a standard bread dough recipe + FoodDoughTortillaFlat: 1 # one eighth a standard bread dough recipe - type: microwaveMealRecipe id: RecipeTacoBeef diff --git a/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/firebomb.yml b/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/firebomb.yml index e2519b765c..eaf9d3aea3 100644 --- a/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/firebomb.yml +++ b/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/firebomb.yml @@ -37,7 +37,7 @@ solution: drink reagent: ReagentId: WeldingFuel - quantity: 30 + quantity: 60 steps: - tool: Screwing doAfter: 1 diff --git a/Resources/Prototypes/Recipes/Reactions/food.yml b/Resources/Prototypes/Recipes/Reactions/food.yml index f9b819e43e..b9f7d84d78 100644 --- a/Resources/Prototypes/Recipes/Reactions/food.yml +++ b/Resources/Prototypes/Recipes/Reactions/food.yml @@ -35,9 +35,9 @@ conserveEnergy: false reactants: Flour: - amount: 15 + amount: 45 Water: - amount: 10 + amount: 15 effects: - !type:SpawnEntity entity: FoodDough @@ -79,11 +79,11 @@ conserveEnergy: false reactants: Fiber: - amount: 10 + amount: 40 Flour: amount: 5 Water: - amount: 10 + amount: 15 effects: - !type:SpawnEntity entity: FoodDoughCotton @@ -95,13 +95,15 @@ conserveEnergy: false reactants: Flour: - amount: 15 + amount: 20 + Butter: + amount: 10 Egg: - amount: 12 + amount: 6 Sugar: - amount: 5 + amount: 10 Milk: - amount: 5 + amount: 10 effects: - !type:SpawnEntity entity: FoodCakeBatter @@ -113,7 +115,7 @@ conserveEnergy: false reactants: Milk: - amount: 15 + amount: 30 TableSalt: amount: 5 catalyst: true @@ -128,10 +130,12 @@ conserveEnergy: false reactants: Flour: - amount: 15 - Egg: - amount: 12 - TableSalt: + amount: 40 + Butter: + amount: 10 + Water: + amount: 5 + Sugar: amount: 5 effects: - !type:SpawnEntity @@ -163,7 +167,7 @@ conserveEnergy: false reactants: MilkSoy: - amount: 30 + amount: 55 Enzyme: amount: 5 catalyst: true diff --git a/Resources/Prototypes/Recipes/Reactions/fun.yml b/Resources/Prototypes/Recipes/Reactions/fun.yml index 5a3764a504..a0b3c0eb01 100644 --- a/Resources/Prototypes/Recipes/Reactions/fun.yml +++ b/Resources/Prototypes/Recipes/Reactions/fun.yml @@ -11,7 +11,7 @@ - type: reaction id: BuzzochloricBees reactants: - Saxoite: # do you like jazz (not sorry) + Brass: # do you like jazz (not sorry) amount: 1 Fiber: # bees are fuzzy amount: 1 diff --git a/Resources/Prototypes/Recipes/Reactions/soap.yml b/Resources/Prototypes/Recipes/Reactions/soap.yml index 0a1b2e4ad6..e54ebf3020 100644 --- a/Resources/Prototypes/Recipes/Reactions/soap.yml +++ b/Resources/Prototypes/Recipes/Reactions/soap.yml @@ -6,11 +6,11 @@ priority: -1 # Ensures that the more complicated soaps get made instead reactants: Oil: - amount: 10 + amount: 20 Lye: - amount: 15 + amount: 30 TableSalt: - amount: 5 + amount: 10 effects: - !type:SpawnEntity entity: Soap @@ -22,11 +22,11 @@ minTemp: 373 reactants: Oil: - amount: 15 - Lye: amount: 20 + Lye: + amount: 25 TableSalt: - amount: 5 + amount: 10 Plasma: amount: 5 effects: @@ -40,11 +40,11 @@ minTemp: 373 reactants: Oil: - amount: 15 - Lye: amount: 20 + Lye: + amount: 25 TableSalt: - amount: 5 + amount: 10 JuiceBerry: amount: 5 effects: @@ -58,11 +58,11 @@ minTemp: 373 reactants: Fat: - amount: 10 + amount: 15 Lye: - amount: 20 + amount: 25 TableSalt: - amount: 5 + amount: 10 Blood: amount: 10 effects: @@ -76,11 +76,11 @@ minTemp: 373 reactants: Oil: - amount: 15 - Lye: amount: 20 + Lye: + amount: 25 TableSalt: - amount: 5 + amount: 10 Stimulants: amount: 5 effects: diff --git a/Resources/Prototypes/XenoArch/effects.yml b/Resources/Prototypes/XenoArch/effects.yml index 0ceb48401a..cbe56df1f4 100644 --- a/Resources/Prototypes/XenoArch/effects.yml +++ b/Resources/Prototypes/XenoArch/effects.yml @@ -251,10 +251,10 @@ components: - type: XAEApplyComponents components: - - type: SolutionContainerManager - solutions: - beaker: - maxVol: 150 + - type: Solution + id: beaker + solution: + maxVol: 120 - type: FitsInDispenser solution: beaker - type: RefillableSolution diff --git a/Resources/migration.yml b/Resources/migration.yml index 420fa73922..a31ec9ebb0 100644 --- a/Resources/migration.yml +++ b/Resources/migration.yml @@ -827,3 +827,7 @@ CrateVendingMachineRestockGetmoreChocolateCorpFilled: VendingMachineRestockGetmo CrateVendingMachineRestockChangFilled: VendingMachineRestockChang CrateVendingMachineRestockDiscountDansFilled: VendingMachineRestockDiscountDans CrateVendingMachineRestockDonutFilled: VendingMachineRestockDonut + +# 2026-03-28 +# The great solutions YAML nuke +FoodMeatSnail: MobSnail From 187aa894549cca5c3d2b57690ede23eeac4b9695 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 25 Apr 2026 02:16:27 +0000 Subject: [PATCH 31/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 36 ++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index b0aafabf72..0c91234b2d 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: PicklOH - changes: - - message: Space Dragon and Carp are more heat resistant. Carp no longer take fire - damage. - type: Tweak - id: 9155 - time: '2025-10-24T19:26:43.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/40820 - author: Centronias changes: - message: Solution reactions which create items scale their resulting products @@ -4049,3 +4041,31 @@ id: 9666 time: '2026-04-24T17:31:12.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/43699 +- author: Princess-Cheeseballs + changes: + - message: You can now boil snails alive in the microwave. + type: Add + - message: Blood volume has been doubled. + type: Tweak + - message: Many chef recipes have been changed so the final result better matches + the ingredients put in. This means overall the nutritional value of the chef's + meals have increased. + type: Tweak + - message: Many chef recipes have had their ingredients changed + type: Tweak + - message: Most slicable foods now give a lot more slices. + type: Tweak + - message: Reagent container sizes have been standardized, at a base of 30 units + per inventory square. Most containers can now hold more than they did before. + type: Tweak + - message: Chemical jugs and bar jugs are now Large (2x4) items. + type: Tweak + - message: Buckets now hold 360u and are 3x4 items. + type: Tweak + - message: Nukie medical duffel bag now comes with a bicaridine jug, a mixed puncturase + & tranexamic acid jug, a mixed dermaline & pyrazine jug, and a mixed saline + & dexalin plus jug. + type: Tweak + id: 9667 + time: '2026-04-25T02:15:12.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/43412 From 9e40aec55a1d1fd9cfd48e8eb0ee29c257419063 Mon Sep 17 00:00:00 2001 From: SnappingOpossum Date: Sat, 25 Apr 2026 14:51:04 +1000 Subject: [PATCH 32/65] Move kudzu random spawners to entity tables + minor cleanup (#42277) * Move kudzu random spawners to entity tables * Forgot to remove those --- .../Markers/Spawners/Random/shadowkudzu.yml | 47 +- .../Entities/Objects/Misc/kudzu.yml | 552 +++++++++--------- 2 files changed, 305 insertions(+), 294 deletions(-) diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/shadowkudzu.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/shadowkudzu.yml index a65ce47c54..50febb17ce 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/Random/shadowkudzu.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/shadowkudzu.yml @@ -1,27 +1,28 @@ - type: entity + parent: MarkerBase id: ShadowKudzuLootSpawner name: shadow kudzu loot spawner - parent: MarkerBase components: - - type: Sprite - layers: - - state: red - - sprite: Structures/Specific/Anomalies/shadow_anom.rsi - state: anom - - type: RandomSpawner - offset: 0.05 - chance: 0.7 - prototypes: - - CrystalPink - - CrystalPink - - ShadowPortal - - ShadowTree #TODO: transform into EntityTable with weight - - ShadowTree - - ShadowTree - - ShadowTree - - ShadowTree - - ShadowTree - rareChance: 0.05 - rarePrototypes: - - MobCatShadow - - ArtifactFragment1 + - type: Sprite + layers: + - state: red + - sprite: Structures/Specific/Anomalies/shadow_anom.rsi + state: anom + - type: EntityTableSpawner + table: !type:GroupSelector + children: + - !type:GroupSelector + weight: 0.95 + prob: 0.7 + children: + - id: CrystalPink + weight: 2 + - id: ShadowPortal + - id: ShadowTree + weight: 6 + - !type:GroupSelector + weight: 0.05 + children: + - id: MobCatShadow + - id: ArtifactFragment1 + offset: 0.05 diff --git a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml index 13dadc47ed..82ba09f0a4 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml @@ -1,22 +1,22 @@ - type: entity - id: BaseKudzu abstract: true + id: BaseKudzu placement: mode: SnapgridCenter snap: - - Wall + - Wall components: - - type: Appearance - - type: Transform - anchored: true - - type: Physics - - type: Kudzu - - type: GrowingKudzu - - type: ActiveEdgeSpreader - - type: EdgeSpreader - id: Kudzu - - type: SpeedModifierContacts - affectAirborne: true + - type: Appearance + - type: Transform + anchored: true + - type: Physics + - type: Kudzu + - type: GrowingKudzu + - type: ActiveEdgeSpreader + - type: EdgeSpreader + id: Kudzu + - type: SpeedModifierContacts + affectAirborne: true - type: entity parent: [ BaseKudzu, SolutionFood ] @@ -24,292 +24,302 @@ name: kudzu description: A rapidly growing, dangerous plant. WHY ARE YOU STOPPING TO LOOK AT IT?! components: - - type: MeleeSound - soundGroups: - Brute: - path: - "/Audio/Weapons/slash.ogg" - - type: Sprite - sprite: Objects/Misc/kudzu.rsi - state: kudzu_11 - drawdepth: Overdoors - - type: KudzuVisuals - - type: Clickable - - type: Fixtures - fixtures: - fix1: - hard: false - density: 7 - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.5" - layer: - - MidImpassable - - type: Damageable - damageModifierSet: Wood - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 10 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - type: Temperature - - type: TemperatureDamage - heatDamage: - types: - Heat: 5 - coldDamage: {} - coldDamageThreshold: 0 - - type: Flammable - fireSpread: true #If you walk into incredibly dense, flaming vines, you can expect to burn. - damage: - types: - Heat: 3 - - type: Reactive - groups: - Flammable: [Touch] - Extinguish: [Touch] - reactions: - - reagents: [WeedKiller, PlantBGone] - methods: [Touch] - effects: - - !type:HealthChange - damage: - types: - Heat: 0.5 - - type: AtmosExposed - - type: Kudzu - growthTickChance: 0.3 - spreadChance: 0.4 - - type: SpeedModifierContacts - walkSpeedModifier: 0.2 - sprintSpeedModifier: 0.2 - ignoreWhitelist: - components: - - IgnoreKudzu - - type: Edible - requiresSpecialDigestion: true - delay: 0.5 - - type: FlavorProfile - flavors: - - fiber - - type: Solution - solution: - reagents: - - ReagentId: Nutriment - Quantity: 0.1 - - type: Tag - tags: - - Ruminant + - type: MeleeSound + soundGroups: + Brute: + path: + "/Audio/Weapons/slash.ogg" + - type: Sprite + sprite: Objects/Misc/kudzu.rsi + state: kudzu_11 + drawdepth: Overdoors + - type: KudzuVisuals + - type: Clickable + - type: Fixtures + fixtures: + fix1: + hard: false + density: 7 + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + layer: + - MidImpassable + - type: Damageable + damageModifierSet: Wood + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 10 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: Temperature + - type: TemperatureDamage + heatDamage: + types: + Heat: 5 + coldDamage: {} + coldDamageThreshold: 0 + - type: Flammable + fireSpread: true #If you walk into incredibly dense, flaming vines, you can expect to burn. + damage: + types: + Heat: 3 + - type: Reactive + groups: + Flammable: [Touch] + Extinguish: [Touch] + reactions: + - reagents: [WeedKiller, PlantBGone] + methods: [Touch] + effects: + - !type:HealthChange + damage: + types: + Heat: 0.5 + - type: AtmosExposed + - type: Kudzu + growthTickChance: 0.3 + spreadChance: 0.4 + - type: SpeedModifierContacts + walkSpeedModifier: 0.2 + sprintSpeedModifier: 0.2 + ignoreWhitelist: + components: + - IgnoreKudzu + - type: Edible + requiresSpecialDigestion: true + delay: 0.5 + - type: FlavorProfile + flavors: + - fiber + - type: Solution + solution: + reagents: + - ReagentId: Nutriment + Quantity: 0.1 + - type: Tag + tags: + - Ruminant - type: entity - id: WeakKudzu parent: Kudzu + id: WeakKudzu suffix: Weak components: - - type: Kudzu - spreadChance: 0.3 + - type: Kudzu + spreadChance: 0.3 + +- type: entityTable + id: kudzuStructureTable + table: !type:GroupSelector + children: + - id: LightTree + weight: 6 + - id: CrystalCyan - type: entity + parent: Kudzu id: KudzuFlowerFriendly name: floral carpet - suffix: Friendly, Floral Anomaly description: A colorful carpet of flowers sprawling in every direction. You're not sure whether to take it down or leave it up. - parent: Kudzu + suffix: Friendly, Floral Anomaly components: - - type: Sprite - drawdepth: HighFloorObjects - sprite: Objects/Misc/kudzuflower.rsi - state: kudzu_11 - - type: Kudzu - spriteVariants: 5 - spreadChance: 0.01 - - type: SpeedModifierContacts - walkSpeedModifier: 0.8 - sprintSpeedModifier: 0.8 - ignoreWhitelist: - components: - - IgnoreKudzu - - type: RandomSpawner - deleteSpawnerAfterSpawn: false - rareChance: 0.15 - offset: 0.2 - chance: 0.05 - prototypes: - - LightTree #TODO: transform into EntityTable with weight - - LightTree - - LightTree - - LightTree - - LightTree - - LightTree - - CrystalCyan - rarePrototypes: - - AnomalyFloraBulb - - type: Tag - tags: - - Ruminant + - type: Sprite + drawdepth: HighFloorObjects + sprite: Objects/Misc/kudzuflower.rsi + state: kudzu_11 + - type: Kudzu + spriteVariants: 5 + spreadChance: 0.01 + - type: SpeedModifierContacts + walkSpeedModifier: 0.8 + sprintSpeedModifier: 0.8 + ignoreWhitelist: + components: + - IgnoreKudzu + - type: EntityTableSpawner + table: !type:GroupSelector + children: + - id: AnomalyFloraBulb + weight: 0.15 + - !type:NestedSelector + tableId: kudzuStructureTable + weight: 0.85 + prob: 0.05 + deleteSpawnerAfterSpawn: false + offset: 0.2 + - type: Tag + tags: + - Ruminant - type: entity + parent: KudzuFlowerFriendly id: KudzuFlowerAngry suffix: Angry, Floral Anomaly - parent: KudzuFlowerFriendly components: - - type: Kudzu - spreadChance: 0.2 - - type: RandomSpawner - chance: 0.05 - rarePrototypes: - - AnomalyFloraBulb - - AnomalyFloraBulb - - MobLuminousEntity - - MobLuminousObject - - MobLuminousPerson + - type: Kudzu + spreadChance: 0.2 + - type: EntityTableSpawner + table: !type:GroupSelector + children: + - !type:NestedSelector + tableId: kudzuStructureTable + weight: 0.85 + prob: 0.05 + - !type:GroupSelector + weight: 0.15 + children: + - id: AnomalyFloraBulb + weight: 2 + - id: MobLuminousEntity + - id: MobLuminousObject + - id: MobLuminousPerson - type: entity - parent: [BaseKudzu, SolutionFood] + parent: [ BaseKudzu, SolutionFood ] id: FleshKudzu name: tendons description: A rapidly growing cluster of meaty tendons. WHY ARE YOU STOPPING TO LOOK AT IT?! - placement: - mode: SnapgridCenter - snap: - - Wall components: - - type: MeleeSound - soundGroups: - Brute: - path: - "/Audio/Weapons/slash.ogg" - - type: Sprite - sprite: Objects/Misc/fleshkudzu.rsi - state: kudzu_11 - drawdepth: Overdoors - - type: KudzuVisuals - - type: Clickable - - type: Fixtures - fixtures: - fix1: - hard: false - density: 7 - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.5" - layer: - - MidImpassable - - type: Damageable - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 40 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - type: DamageContacts - damage: - types: - Slash: 1.5 - Piercing: 1.5 - ignoreWhitelist: - tags: - - Flesh - - type: Kudzu - growthTickChance: 0.1 - spreadChance: 0.4 - # Heals each time it manages to do a growth tick: - damageRecovery: - types: - Slash: -0.5 - Heat: -1.0 - Cold: -1.0 - Blunt: -0.5 # Needs to be balanced (approx 3x) with vacuum damage to stall but not kill Kudzu - - type: Temperature - - type: TemperatureDamage - heatDamage: - types: - Heat: 10 - coldDamage: - types: - Cold: 5 #per second, scales with temperature & other constants - - type: Barotrauma - damage: - types: - Blunt: 0.10 #per second, scales with pressure and other constants. - - type: Flammable - fireSpread: true - damage: - types: - Heat: 3 - - type: AtmosExposed - - type: Edible # delightfully devilish ! - delay: 0.5 - - type: SpeedModifierContacts - walkSpeedModifier: 0.3 - sprintSpeedModifier: 0.3 - ignoreWhitelist: - tags: - - Flesh - - type: Solution - solution: - reagents: - - ReagentId: Razorium - Quantity: 2 - - ReagentId: Protein - Quantity: 1 - - type: AutoEmote # Meat Kudzu used to have respirator, but couldn't breathe so all it would do is gasp. - emotes: - - MeatGasp - - type: Tag + - type: MeleeSound + soundGroups: + Brute: + path: + "/Audio/Weapons/slash.ogg" + - type: Sprite + sprite: Objects/Misc/fleshkudzu.rsi + state: kudzu_11 + drawdepth: Overdoors + - type: KudzuVisuals + - type: Clickable + - type: Fixtures + fixtures: + fix1: + hard: false + density: 7 + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + layer: + - MidImpassable + - type: Damageable + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 40 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: DamageContacts + damage: + types: + Slash: 1.5 + Piercing: 1.5 + ignoreWhitelist: tags: - - Meat - - Ruminant + - Flesh + - type: Kudzu + growthTickChance: 0.1 + spreadChance: 0.4 + # Heals each time it manages to do a growth tick: + damageRecovery: + types: + Slash: -0.5 + Heat: -1.0 + Cold: -1.0 + Blunt: -0.5 # Needs to be balanced (approx 3x) with vacuum damage to stall but not kill Kudzu + - type: Temperature + - type: TemperatureDamage + heatDamage: + types: + Heat: 10 + coldDamage: + types: + Cold: 5 #per second, scales with temperature & other constants + - type: Barotrauma + damage: + types: + Blunt: 0.10 #per second, scales with pressure and other constants. + - type: Flammable + fireSpread: true + damage: + types: + Heat: 3 + - type: AtmosExposed + - type: Edible # delightfully devilish ! + delay: 0.5 + - type: SpeedModifierContacts + walkSpeedModifier: 0.3 + sprintSpeedModifier: 0.3 + ignoreWhitelist: + tags: + - Flesh + - type: Solution + solution: + reagents: + - ReagentId: Razorium + Quantity: 2 + - ReagentId: Protein + Quantity: 1 + - type: AutoEmote # Meat Kudzu used to have respirator, but couldn't breathe so all it would do is gasp. + emotes: + - MeatGasp + - type: Tag + tags: + - Meat + - Ruminant - type: entity - name: dark haze - id: ShadowKudzu parent: [ BaseKudzu, BaseShadow ] + id: ShadowKudzu + name: dark haze components: - - type: Physics - canCollide: false - - type: Occluder - - type: Sprite - drawdepth: Effects - sprite: Effects/spookysmoke.rsi - layers: - - state: spookysmoke - color: "#793a80dd" - map: [base] - - type: Kudzu - growthTickChance: 0.2 - spreadChance: 0.99 - - type: RandomSpawner - deleteSpawnerAfterSpawn: false - rareChance: 0.05 - offset: 0.2 - chance: 0.45 - prototypes: - - ShadowBasaltRandom - rarePrototypes: - - ShadowPortal - - ShadowKudzuLootSpawner - - type: Tag - tags: - - HideContextMenu - - SpookyFog - - type: OptionsVisualizer - visuals: - base: - - options: Default - data: { state: spookysmoke } - - options: ReducedMotion - data: { state: spookysmoke_static } + - type: Physics + canCollide: false + - type: Occluder + - type: Sprite + drawdepth: Effects + sprite: Effects/spookysmoke.rsi + layers: + - state: spookysmoke + color: "#793a80dd" + map: [base] + - type: Kudzu + growthTickChance: 0.2 + spreadChance: 0.99 + - type: EntityTableSpawner + table: !type:GroupSelector + children: + - id: ShadowBasaltRandom + weight: 0.95 + prob: 0.45 + - !type:GroupSelector + weight: 0.05 + children: + - id: ShadowPortal + - id: ShadowKudzuLootSpawner # Also has its own offset + deleteSpawnerAfterSpawn: false + offset: 0.2 + - type: Tag + tags: + - HideContextMenu + - SpookyFog + - type: OptionsVisualizer + visuals: + base: + - options: Default + data: { state: spookysmoke } + - options: ReducedMotion + data: { state: spookysmoke_static } - type: entity - name: haze - id: ShadowKudzuWeak parent: ShadowKudzu + id: ShadowKudzuWeak + name: haze components: - - type: Kudzu - spreadChance: 0 #appears during pulsation. It shouldnt spreading. + - type: Kudzu + spreadChance: 0 #appears during pulsation. It shouldnt spreading. From 999d17685b42980af2be6eb7893b667c87875a4f Mon Sep 17 00:00:00 2001 From: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Date: Sat, 25 Apr 2026 07:16:43 +0200 Subject: [PATCH 33/65] Rejuvenate restores wires (#43717) yeah --- Content.Server/Wires/WiresSystem.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Content.Server/Wires/WiresSystem.cs b/Content.Server/Wires/WiresSystem.cs index e4d7861029..ba1a056811 100644 --- a/Content.Server/Wires/WiresSystem.cs +++ b/Content.Server/Wires/WiresSystem.cs @@ -11,6 +11,7 @@ using Content.Shared.Hands.Components; using Content.Shared.Interaction; using Content.Shared.Popups; using Content.Shared.Power; +using Content.Shared.Rejuvenate; using Content.Shared.Tools; using Content.Shared.Tools.Components; using Content.Shared.Wires; @@ -54,6 +55,7 @@ public sealed class WiresSystem : SharedWiresSystem SubscribeLocalEvent(OnTimedWire); SubscribeLocalEvent(OnWiresPowered); SubscribeLocalEvent(OnDoAfter); + SubscribeLocalEvent(OnRejuvenate); SubscribeLocalEvent(SetWiresPanelSecurity); } @@ -482,6 +484,21 @@ public sealed class WiresSystem : SharedWiresSystem UpdateUserInterface(uid); } + + private void OnRejuvenate(Entity ent, ref RejuvenateEvent args) + { + foreach (var wire in ent.Comp.WiresList) + { + // Rejuvenate has no user so we mend as the entity having the wire. + if (wire.Action == null || wire.Action.Mend(ent, wire)) + { + wire.IsCut = false; + } + } + + // If we don't update the interface wires will be desynced on client. + UpdateUserInterface(ent.Owner, ent.Comp); + } #endregion #region Entity API From 086479313fcf8ebfe93708d5b28f3c904bf92358 Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Sat, 25 Apr 2026 02:20:56 -0700 Subject: [PATCH 34/65] Completely Rewrite Antag Selection Code to fix 1 bug but this time without breaking the game. Add Test For All Game Presets. (#43191) * "fixes" it but the logic just needs to be rewritten. * init commit * almost there * commit * Scrounger * actually spawn the ghost roles, and better assertion behavior! * update the warning because I know someone is gonna touch it * hhng * fix Traitor assignment * Prune the list and ignore dummy antags * game test * skip dummy antag * crisaskjfshj * It's time, it's fucking time * fixing the secret gamemode bug once and for all. * docs * burger * dssdgdsgds * so hungry for test fails * job whitelist * review --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- .../GameRules/AllGamePresetsStartTest.cs | 209 +++ .../Tests/GameRules/AntagPreferenceTest.cs | 78 -- .../Tests/Station/StationJobsTest.cs | 34 +- .../Administration/Managers/BanManager.cs | 6 +- .../Administration/Managers/IBanManager.cs | 4 +- .../Antag/AntagMultipleRoleSpawnerSystem.cs | 19 +- .../Antag/AntagSelectionPlayerPool.cs | 27 - .../AntagSelectionSystem.API.Assignment.cs | 501 ++++++++ .../Antag/AntagSelectionSystem.API.cs | 663 +++++++--- Content.Server/Antag/AntagSelectionSystem.cs | 1130 ++++++++++------- .../AntagMultipleRoleSpawnerComponent.cs | 3 +- .../Components/AntagSelectionComponent.cs | 209 +-- .../GhostRoleAntagSpawnerComponent.cs | 7 +- .../Antag/Selectors/AntagCountSelector.cs | 39 + .../Antag/Selectors/FixedAntagCount.cs | 18 + .../Antag/Selectors/LinearAntagCount.cs | 14 + .../GameTicking/GameTicker.GamePreset.cs | 43 +- .../GameTicking/GameTicker.GameRule.cs | 34 +- .../Rules/AntagLoadProfileRuleSystem.cs | 9 +- .../GameTicking/Rules/GameRuleSystem.cs | 58 +- .../Rules/RevolutionaryRuleSystem.cs | 3 +- .../GameTicking/Rules/RuleGridsSystem.cs | 4 +- .../GameTicking/Rules/SecretRuleSystem.cs | 15 +- .../GameTicking/Rules/ZombieRuleSystem.cs | 3 +- Content.Server/Objectives/ObjectivesSystem.cs | 29 +- .../AntagGridSpawnPointComponent.cs | 19 + .../GridSpawnPointWhitelistComponent.cs | 22 - .../Systems/StationJobsSystem.Roundstart.cs | 14 +- Content.Server/Xenoborgs/XenoborgSystem.cs | 4 +- Content.Shared/Antag/AntagAcceptability.cs | 41 - .../Antag/AntagSpecifierPrototype.cs | 181 +++ Content.Shared/CCVar/CCVars.Game.cs | 6 + .../Destructible/Thresholds/MinMax.cs | 5 + Content.Shared/Roles/JobPrototype.cs | 3 - Content.Shared/Roles/Jobs/SharedJobSystem.cs | 16 - Content.Shared/Roles/SharedRoleSystem.cs | 21 + .../Spawners/Conditional/xenoborgs.yml | 19 +- Resources/Prototypes/GameRules/events.yml | 275 +--- Resources/Prototypes/GameRules/roundstart.yml | 276 ++-- .../Prototypes/GameRules/subgamemodes.yml | 75 +- Resources/Prototypes/Roles/Antags/base.yml | 73 ++ .../Prototypes/Roles/Antags/changeling.yml | 26 + Resources/Prototypes/Roles/Antags/dragon.yml | 8 + Resources/Prototypes/Roles/Antags/generic.yml | 12 +- Resources/Prototypes/Roles/Antags/ninja.yml | 28 + Resources/Prototypes/Roles/Antags/nukeops.yml | 74 ++ .../Prototypes/Roles/Antags/paradoxClone.yml | 15 + .../Prototypes/Roles/Antags/revolutionary.yml | 28 + Resources/Prototypes/Roles/Antags/silicon.yml | 46 + Resources/Prototypes/Roles/Antags/thief.yml | 18 + Resources/Prototypes/Roles/Antags/traitor.yml | 33 + Resources/Prototypes/Roles/Antags/wizard.yml | 25 + .../Prototypes/Roles/Antags/xenoborgs.yml | 21 + Resources/Prototypes/Roles/Antags/zombie.yml | 24 + .../Roles/Jobs/Cargo/quartermaster.yml | 1 - .../Prototypes/Roles/Jobs/CentComm/cburn.yml | 1 - .../Roles/Jobs/CentComm/deathsquad.yml | 1 - .../Jobs/CentComm/emergencyresponseteam.yml | 6 - .../Roles/Jobs/CentComm/official.yml | 1 - .../Roles/Jobs/Civilian/visitor.yml | 1 - .../Prototypes/Roles/Jobs/Command/captain.yml | 1 - .../Roles/Jobs/Command/head_of_personnel.yml | 1 - .../Roles/Jobs/Engineering/chief_engineer.yml | 1 - .../Jobs/Engineering/technical_assistant.yml | 1 - .../Jobs/Medical/chief_medical_officer.yml | 1 - .../Roles/Jobs/Medical/medical_intern.yml | 1 - .../Prototypes/Roles/Jobs/Science/borg.yml | 2 - .../Roles/Jobs/Science/research_assistant.yml | 1 - .../Roles/Jobs/Science/research_director.yml | 1 - .../Roles/Jobs/Security/detective.yml | 1 - .../Roles/Jobs/Security/head_of_security.yml | 1 - .../Roles/Jobs/Security/security_cadet.yml | 1 - .../Roles/Jobs/Security/security_officer.yml | 1 - .../Prototypes/Roles/Jobs/Security/warden.yml | 1 - 74 files changed, 2950 insertions(+), 1643 deletions(-) create mode 100644 Content.IntegrationTests/Tests/GameRules/AllGamePresetsStartTest.cs delete mode 100644 Content.IntegrationTests/Tests/GameRules/AntagPreferenceTest.cs delete mode 100644 Content.Server/Antag/AntagSelectionPlayerPool.cs create mode 100644 Content.Server/Antag/AntagSelectionSystem.API.Assignment.cs create mode 100644 Content.Server/Antag/Selectors/AntagCountSelector.cs create mode 100644 Content.Server/Antag/Selectors/FixedAntagCount.cs create mode 100644 Content.Server/Antag/Selectors/LinearAntagCount.cs create mode 100644 Content.Server/Spawners/Components/AntagGridSpawnPointComponent.cs delete mode 100644 Content.Server/Spawners/Components/GridSpawnPointWhitelistComponent.cs delete mode 100644 Content.Shared/Antag/AntagAcceptability.cs create mode 100644 Content.Shared/Antag/AntagSpecifierPrototype.cs create mode 100644 Resources/Prototypes/Roles/Antags/base.yml diff --git a/Content.IntegrationTests/Tests/GameRules/AllGamePresetsStartTest.cs b/Content.IntegrationTests/Tests/GameRules/AllGamePresetsStartTest.cs new file mode 100644 index 0000000000..2c8cad5603 --- /dev/null +++ b/Content.IntegrationTests/Tests/GameRules/AllGamePresetsStartTest.cs @@ -0,0 +1,209 @@ +using System.Collections.Generic; +using System.Linq; +using Content.IntegrationTests.Fixtures; +using Content.IntegrationTests.Utility; +using Content.Server.Antag; +using Content.Server.Antag.Components; +using Content.Server.GameTicking; +using Content.Server.GameTicking.Presets; +using Content.Server.Shuttles.Components; +using Content.Shared.Antag; +using Content.Shared.CCVar; +using Content.Shared.GameTicking; +using Content.Shared.Mind; +using Robust.Shared.Map.Components; +using Robust.Shared.Player; + +namespace Content.IntegrationTests.Tests.GameRules; + +[TestFixture] +public sealed class AllGamePresetsStartTest : GameTest +{ + /// + /// A list of blacklisted for this test. Some down streams might make changes which nuke upstream game modes they don't use. + /// This prevents them from being tested. If you use this to silence valid test fails and your game fails to start. Skill issue. Do 100 push-ups. + /// + private static readonly HashSet IgnoredPresets = []; // Is a string to prevent YAML Linter from freaking if this is empty. + + private static string[] _gamePresets = GameDataScrounger.PrototypesOfKind().Where(p => !IgnoredPresets.Contains(p)).ToArray(); + + public override PoolSettings PoolSettings => new() + { + Dirty = true, + DummyTicker = false, + Connected = true, + InLobby = true + }; + + // Tests that all game modes can start given ideal circumstances. + [Test] + [TestOf(typeof(GameTicker)), TestOf(typeof(AntagSelectionSystem)), TestOf(typeof(AntagSelectionComponent))] + [TestCaseSource(nameof(_gamePresets))] + [Description("Ensures all Game Presets are able to start and assign all antags correctly without spawning anyone in nullspace.")] + public async Task TestAllGamemodesCanStart(string presetId) + { + var server = Pair.Server; + var client = Pair.Client; + var protoMan = server.ProtoMan; + var entMan = server.EntMan; + var ticker = server.System(); + var antagSys = server.System(); + var mind = server.System(); + + // Initially in the lobby + Assert.That(ticker.RunLevel, Is.EqualTo(GameRunLevel.PreRoundLobby)); + Assert.That(client.AttachedEntity, Is.Null); + Assert.That(ticker.PlayerGameStatuses[client.User!.Value], Is.EqualTo(PlayerGameStatus.NotReadyToPlay)); + + // Don't start dummy antag game rule because we want our antags to be predictable for the test. + server.CfgMan.SetCVar(CCVars.GameTickerIgnoredPresets, GameTicker.DummyGameRule); + + var preset = protoMan.Index(presetId); + + // Spawn the minimum number of players. + var players = new List(); + players.Add(client.Session); + var min = 0; + await server.WaitPost(() => + { + min = ticker.GetMinimumPlayerCount(preset); + }); + + // We should already have one client connected, and we need to check the min + + // If we have antags, make sure that those with the correct preferences can spawn with them! + List<(AntagSpecifierPrototype, int)> rules = []; + + var antags = 0; + await server.WaitPost(() => + { + foreach (var ruleId in preset.Rules) + { + if (ruleId == GameTicker.DummyGameRule) + continue; + + if (!protoMan.Resolve(ruleId, out var rule )) + continue; // Bruh moment + + // Ignore non-antag game-rules. + if (!rule.TryGetComponent(out var antag, entMan.ComponentFactory)) + continue; + + var runningCount = 0; + + foreach (var selector in antag.Antags) + { + // Throw on invalid prototypes, skip roundstart ghost roles. + if (!protoMan.Resolve(selector.Proto, out var definition) || definition.PrefRoles.Count == 0) + continue; + + var count = antagSys.GetTargetAntagCount(selector, min, ref runningCount); + antags += count; + rules.Add((definition, count)); + } + } + }); + + // No preset should ever try to spawn more antags roundstart than it can spawn players. + Assert.That(antags <= min, Is.True); + if (min > 1) + { + var dummies = await server.AddDummySessions(min - 1); + // Put our client at the front of the list. + players = players.Union(dummies).ToList(); + } + + await Pair.RunUntilSynced(); + + // This also ensures that admin commands work properly :P + await server.WaitPost(() => + { + ticker.ToggleReadyAll(true); + }); + + var i = 0; + foreach (var (antag, amount) in rules) + { + for (var count = 0; count < amount; count++) + { + await Pair.SetAntagPreference(antag.PrefRoles.FirstOrDefault(), true, players[i++].UserId); + Assert.That(i < min, $"Tried to assign more antags than there were players"); + } + } + + await Pair.RunUntilSynced(); + await Pair.WaitCommand($"setgamepreset {presetId}"); + await Pair.WaitCommand("startround"); + await Pair.RunUntilSynced(); + + // Game should have started + Assert.That(ticker.RunLevel, Is.EqualTo(GameRunLevel.InRound)); + Assert.That(ticker.PlayerGameStatuses.Values.All(x => x == PlayerGameStatus.JoinedGame)); + Assert.That(ticker.PlayerGameStatuses.Count == players.Count); + Assert.That(client.EntMan.EntityExists(client.AttachedEntity)); + + var player = Pair.Player!.AttachedEntity!.Value; + Assert.That(entMan.EntityExists(player)); + + // Start all game presets so antags spawn! + await server.WaitPost(() => + { + ticker.StartGamePresetRules(); + }); + await Pair.RunUntilSynced(); + + await server.WaitPost(() => + { + var j = 0; + foreach (var (antag, amount) in rules) + { + for (var count = 0; count < amount; count++) + { + AssertAntagInitialized(antag, players[j++]); + } + } + }); + + // Maps now exist + Assert.That(entMan.Count(), Is.GreaterThan(0)); + Assert.That(entMan.Count(), Is.GreaterThan(0)); + Assert.That(entMan.Count(), Is.EqualTo(1)); + + await Pair.WaitCommand("golobby"); + await Pair.RunUntilSynced(); + void AssertAntagInitialized(AntagSpecifierPrototype antag, ICommonSession session) + { + Assert.That(mind.TryGetMind(session, out var mindEnt, out var mindComp), + $"Session {session} spawned into the game as an antag but had no mind!"); + Assert.That(entMan.EntityExists(mindComp!.CurrentEntity), + $"Session {session} spawned into the game as an antag, but had no entity!"); + var ent = mindComp.CurrentEntity!.Value; + + // Make sure all components were added + foreach (var comp in antag.Components) + { + Assert.That(entMan.HasComponent(ent, comp.Value.Component.GetType()), + $"Entity {entMan.ToPrettyString(ent)} owned by {session} failed to acquire {comp.Key} component, while becoming {antag.ID}"); + } + + // Make sure all mind components were added + foreach (var comp in antag.MindComponents) + { + Assert.That(entMan.HasComponent(mindEnt, comp.Value.Component.GetType()), + $"Mind {entMan.ToPrettyString(mindEnt)} owned by {session} failed to acquire {comp.Key} component, while becoming {antag.ID}"); + } + + if (antag.MindRoles != null) + { + Assert.Multiple(() => + { + foreach (var role in antag.MindRoles) + { + Assert.That(mindComp!.MindRoleContainer.ContainedEntities.Any(x => entMan.MetaQuery.Comp(x).EntityPrototype?.ID == role), + $"{SToPrettyString(mindEnt)} owned by {session}, failed to acquire role {role} for antagonist {antag}"); + } + }); + } + } + } +} diff --git a/Content.IntegrationTests/Tests/GameRules/AntagPreferenceTest.cs b/Content.IntegrationTests/Tests/GameRules/AntagPreferenceTest.cs deleted file mode 100644 index 4a059eb1cc..0000000000 --- a/Content.IntegrationTests/Tests/GameRules/AntagPreferenceTest.cs +++ /dev/null @@ -1,78 +0,0 @@ -#nullable enable -using System.Collections.Generic; -using System.Linq; -using Content.IntegrationTests.Fixtures; -using Content.Server.Antag; -using Content.Server.Antag.Components; -using Content.Server.GameTicking; -using Content.Shared.GameTicking; -using Robust.Shared.GameObjects; -using Robust.Shared.Player; -using Robust.Shared.Random; - -namespace Content.IntegrationTests.Tests.GameRules; - -// Once upon a time, players in the lobby weren't ever considered eligible for antag roles. -// Lets not let that happen again. -[TestFixture] -public sealed class AntagPreferenceTest : GameTest -{ - public override PoolSettings PoolSettings => new PoolSettings - { - DummyTicker = false, - Connected = true, - InLobby = true - }; - - [Test] - public async Task TestLobbyPlayersValid() - { - var pair = Pair; - - var server = pair.Server; - var client = pair.Client; - var ticker = server.System(); - var sys = server.System(); - - // Initially in the lobby - Assert.That(ticker.RunLevel, Is.EqualTo(GameRunLevel.PreRoundLobby)); - Assert.That(client.AttachedEntity, Is.Null); - Assert.That(ticker.PlayerGameStatuses[client.User!.Value], Is.EqualTo(PlayerGameStatus.NotReadyToPlay)); - - EntityUid uid = default; - await server.WaitPost(() => uid = server.EntMan.Spawn("Traitor")); - var rule = new Entity(uid, server.EntMan.GetComponent(uid)); - var def = rule.Comp.Definitions.Single(); - - // IsSessionValid & IsEntityValid are preference agnostic and should always be true for players in the lobby. - // Though maybe that will change in the future, but then GetPlayerPool() needs to be updated to reflect that. - Assert.That(sys.IsSessionValid(rule, pair.Player, def), Is.True); - Assert.That(sys.IsEntityValid(client.AttachedEntity, def), Is.True); - - // By default, traitor/antag preferences are disabled, so the pool should be empty. - var sessions = new List { pair.Player! }; - var pool = sys.GetPlayerPool(rule, sessions, def); - Assert.That(pool.Count, Is.EqualTo(0)); - - // Opt into the traitor role. - await pair.SetAntagPreference("Traitor", true); - - Assert.That(sys.IsSessionValid(rule, pair.Player, def), Is.True); - Assert.That(sys.IsEntityValid(client.AttachedEntity, def), Is.True); - pool = sys.GetPlayerPool(rule, sessions, def); - Assert.That(pool.Count, Is.EqualTo(1)); - pool.TryPickAndTake(pair.Server.ResolveDependency(), out var picked); - Assert.That(picked, Is.EqualTo(pair.Player)); - Assert.That(sessions.Count, Is.EqualTo(1)); - - // opt back out - await pair.SetAntagPreference("Traitor", false); - - Assert.That(sys.IsSessionValid(rule, pair.Player, def), Is.True); - Assert.That(sys.IsEntityValid(client.AttachedEntity, def), Is.True); - pool = sys.GetPlayerPool(rule, sessions, def); - Assert.That(pool.Count, Is.EqualTo(0)); - - await server.WaitPost(() => server.EntMan.DeleteEntity(uid)); - } -} diff --git a/Content.IntegrationTests/Tests/Station/StationJobsTest.cs b/Content.IntegrationTests/Tests/Station/StationJobsTest.cs index c0f0b19b19..c4a81d0561 100644 --- a/Content.IntegrationTests/Tests/Station/StationJobsTest.cs +++ b/Content.IntegrationTests/Tests/Station/StationJobsTest.cs @@ -9,6 +9,7 @@ using Content.Shared.Roles; using Robust.Shared.GameObjects; using Robust.Shared.Log; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Timing; @@ -105,16 +106,25 @@ public sealed class StationJobsTest : GameTest } }); + var dummies = await server.AddDummySessions(TotalPlayers); await server.WaitAssertion(() => { - var fakePlayers = new Dictionary() - .AddJob("TAssistant", JobPriority.Medium, PlayerCount) - .AddPreference("TClown", JobPriority.Low) - .AddPreference("TMime", JobPriority.High) - .WithPlayers( - new Dictionary() - .AddJob("TCaptain", JobPriority.High, CaptainCount) - ); + var fakePlayers = new Dictionary(TotalPlayers); + var i = 0; + foreach (var dummy in dummies) + { + if (i < PlayerCount) + { + fakePlayers.AddJob(dummy, "TAssistant", JobPriority.Medium) + .AddPreference("TClown", JobPriority.Low) + .AddPreference("TMime", JobPriority.High); + i++; + } + else + { + fakePlayers.AddJob(dummy, "TCaptain", JobPriority.High); + } + } Assert.That(fakePlayers, Is.Not.Empty); var start = new Stopwatch(); @@ -252,13 +262,9 @@ public sealed class StationJobsTest : GameTest internal static class JobExtensions { public static Dictionary AddJob( - this Dictionary inp, string jobId, JobPriority prio = JobPriority.Medium, - int amount = 1) + this Dictionary inp, ICommonSession session, string jobId, JobPriority prio = JobPriority.Medium) { - for (var i = 0; i < amount; i++) - { - inp.Add(new NetUserId(Guid.NewGuid()), HumanoidCharacterProfile.Random().WithJobPriority(jobId, prio)); - } + inp.Add(session.UserId, HumanoidCharacterProfile.Random().WithJobPriority(jobId, prio)); return inp; } diff --git a/Content.Server/Administration/Managers/BanManager.cs b/Content.Server/Administration/Managers/BanManager.cs index 650e1a1872..9114b1c957 100644 --- a/Content.Server/Administration/Managers/BanManager.cs +++ b/Content.Server/Administration/Managers/BanManager.cs @@ -441,17 +441,17 @@ public sealed partial class BanManager : IBanManager, IPostInjectInit : null; } - public bool IsRoleBanned(ICommonSession player, List> jobs) + public bool IsRoleBanned(ICommonSession player, params List> jobs) { return IsRoleBanned(player, jobs); } - public bool IsRoleBanned(ICommonSession player, List> antags) + public bool IsRoleBanned(ICommonSession player, params List> antags) { return IsRoleBanned(player, antags); } - private bool IsRoleBanned(ICommonSession player, List> roles) where T : class, IPrototype + private bool IsRoleBanned(ICommonSession player, params List> roles) where T : class, IPrototype { var bans = GetRoleBans(player.UserId); diff --git a/Content.Server/Administration/Managers/IBanManager.cs b/Content.Server/Administration/Managers/IBanManager.cs index 633ae968db..3633f9cdde 100644 --- a/Content.Server/Administration/Managers/IBanManager.cs +++ b/Content.Server/Administration/Managers/IBanManager.cs @@ -74,7 +74,7 @@ public interface IBanManager /// The player. /// A list of valid antag prototype IDs. /// Returns True if an active role ban is found for this player for any of the listed roles. - public bool IsRoleBanned(ICommonSession player, List> antags); + public bool IsRoleBanned(ICommonSession player, params List> antags); /// /// Checks if the player is currently banned from any of the listed roles. @@ -82,7 +82,7 @@ public interface IBanManager /// The player. /// A list of valid job prototype IDs. /// Returns True if an active role ban is found for this player for any of the listed roles. - public bool IsRoleBanned(ICommonSession player, List> jobs); + public bool IsRoleBanned(ICommonSession player, params List> jobs); /// /// Gets a list of prototype IDs with the player's job bans. diff --git a/Content.Server/Antag/AntagMultipleRoleSpawnerSystem.cs b/Content.Server/Antag/AntagMultipleRoleSpawnerSystem.cs index d59fbc82b4..06f5403497 100644 --- a/Content.Server/Antag/AntagMultipleRoleSpawnerSystem.cs +++ b/Content.Server/Antag/AntagMultipleRoleSpawnerSystem.cs @@ -6,35 +6,22 @@ namespace Content.Server.Antag; public sealed class AntagMultipleRoleSpawnerSystem : EntitySystem { [Dependency] private readonly IRobustRandom _random = default!; - [Dependency] private readonly ILogManager _log = default!; - - private ISawmill _sawmill = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnSelectEntity); - - _sawmill = _log.GetSawmill("antag_multiple_spawner"); } private void OnSelectEntity(Entity ent, ref AntagSelectEntityEvent args) { - // If its more than one the logic breaks - if (args.AntagRoles.Count != 1) - { - _sawmill.Fatal($"Antag multiple role spawner had more than one antag ({args.AntagRoles.Count})"); - return; - } - - var role = args.AntagRoles[0]; - - var entProtos = ent.Comp.AntagRoleToPrototypes[role]; + var entProtos = ent.Comp.AntagRoleToPrototypes[args.Antag]; if (entProtos.Count == 0) return; // You will just get a normal job - args.Entity = Spawn(ent.Comp.PickAndTake ? _random.PickAndTake(entProtos) : _random.Pick(entProtos)); + // TODO: Could probably turn this into a dictionary that takes an antag prototype and spits out an entity? + args.Entity = Spawn(ent.Comp.PickAndTake ? _random.PickAndTake(entProtos) : _random.Pick(entProtos), args.Coords); } } diff --git a/Content.Server/Antag/AntagSelectionPlayerPool.cs b/Content.Server/Antag/AntagSelectionPlayerPool.cs deleted file mode 100644 index 87873e96d1..0000000000 --- a/Content.Server/Antag/AntagSelectionPlayerPool.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using Robust.Shared.Player; -using Robust.Shared.Random; - -namespace Content.Server.Antag; - -public sealed class AntagSelectionPlayerPool (List> orderedPools) -{ - public bool TryPickAndTake(IRobustRandom random, [NotNullWhen(true)] out ICommonSession? session) - { - session = null; - - foreach (var pool in orderedPools) - { - if (pool.Count == 0) - continue; - - session = random.PickAndTake(pool); - break; - } - - return session != null; - } - - public int Count => orderedPools.Sum(p => p.Count); -} diff --git a/Content.Server/Antag/AntagSelectionSystem.API.Assignment.cs b/Content.Server/Antag/AntagSelectionSystem.API.Assignment.cs new file mode 100644 index 0000000000..aef77fe6a8 --- /dev/null +++ b/Content.Server/Antag/AntagSelectionSystem.API.Assignment.cs @@ -0,0 +1,501 @@ +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Content.Server.Antag.Components; +using Content.Server.GameTicking.Rules.Components; +using Content.Shared.Antag; +using Content.Shared.Database; +using Content.Shared.Ghost; +using Content.Shared.Humanoid; +using Content.Shared.Players; +using JetBrains.Annotations; +using Robust.Shared.Player; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using static Content.Server.Antag.Components.AntagSelectionTime; + +namespace Content.Server.Antag; + +public sealed partial class AntagSelectionSystem +{ + /// + [PublicAPI] + public bool CanBeAntag(ICommonSession player, AntagRule antagRule, bool checkPref = true) + { + return CanBeAntag(player, antagRule.GameRule, antagRule.Definition, checkPref); + } + + /// + [PublicAPI] + public bool CanBeAntag(ICommonSession player, + Entity gameRule, + ProtoId proto, + bool checkPref = true) + { + // Can't be this antag if it doesn't exist :) + if (!Proto.Resolve(proto, out var antag)) + return false; + + return CanBeAntag(player, gameRule, antag, checkPref); + } + + /// + /// Verifies that a player is able to be an antag performing a wide variety of checks. + /// + /// Player we're checking + /// Game rule which we want to be an antag for, needed to ensure we haven't already been selected. + /// Antag definition we want to become + /// Whether we want to check our antag preferences or not. + /// True if this player can be an antagonist. + [PublicAPI] + public bool CanBeAntag(ICommonSession player, + Entity gameRule, + AntagSpecifierPrototype def, + bool checkPref = true) + { + if (!IsSessionValid(player, gameRule, def)) + return false; + + if (IsAssignedAntag(gameRule, def, player)) + return false; + + // Add player to the appropriate antag pool + if (checkPref && !TryGetValidAntagPreferences(player, def.PrefRoles)) + return false; + + return true; + } + + /// + public bool IsSessionValid(ICommonSession player, + Entity gameRule, + ProtoId def) + { + if (!Proto.Resolve(def, out var antag)) + return false; + + return IsSessionValid(player, gameRule, antag); + } + + /// + /// Checks if our session can play a given antagonist, checking if the session is role banned from the antag, + /// + /// Player which we are checking antag viability for + /// Game that's trying to make this player an antag. + /// Antag definition we're checking against. + /// True if there is nothing stopping this session from becoming this antagonist. + [PublicAPI] + public bool IsSessionValid(ICommonSession player, + Entity gameRule, + AntagSpecifierPrototype def) + { + // Cannot be antag if you're not in the game. + if (IsDisconnected(player)) + return false; + + if (IsAntagBanned(player, def)) + return false; + + // If our antag is mutually exclusive with other antags, yell about it! + switch (def.MultiAntagSetting) + { + case AntagAcceptability.None: + { + if (IsAssignedAntag(player, gameRule)) + return false; + break; + } + case AntagAcceptability.NotExclusive: + { + if (IsAssignedExclusiveAntag(player, gameRule)) + return false; + break; + } + } + + return player.AttachedEntity == null || IsEntityValid(player, def); + } + + /// + public bool IsMindValid(ICommonSession session, AntagSpecifierPrototype def) + { + return IsMindValid(session.GetMind(), def); + } + + /// + /// Checks if the given mind entity is valid for the specified antag. + /// + /// Mind we are checking + /// Antag definition we want to give this mind. + /// True if there is nothing stopping this mind entity from being this antag. + private bool IsMindValid([NotNullWhen(true)] EntityUid? mind, AntagSpecifierPrototype def) + { + // The jobless can always be antag! + if (!_jobs.MindTryGetJob(mind, out var job)) + return true; + + // "Sorry buddy, but you can't be a traitor and the head of security" - Urist 1984 + // This checks nullability for our mind for free as well! + if (def.JobBlacklist?.Contains(job) ?? false) + return false; + + if (!def.JobWhitelist?.Contains(job) ?? false) + return false; + + return true; + } + + /// + /// Checks both the mind and attached entity of the given session to see if anything is blocking it from being converted to an antag. + /// + /// Entity whose validity we're checking. + /// Antag definition we want to give them. + /// True if there is nothing stopping this entity from being this antag. Or if there is no entity. + public bool IsEntityValid(ICommonSession session, AntagSpecifierPrototype def) + { + return IsMindValid(session, def) && IsEntityValid(session.AttachedEntity, def); + } + + /// + public bool IsEntityValid([NotNullWhen(true)] EntityUid? uid, ProtoId def) + { + if (!Proto.Resolve(def, out var antag)) + return false; + + return IsEntityValid(uid, antag); + } + + /// + /// Checks if the given entity is able to become the given antagonist. + /// Note that this does not check if the entity had a mind or if that mind can become an antag. + /// + /// Entity whose validity we're checking. + /// Antag definition we want to give them. + /// True if there is nothing stopping this entity from being this antag. Or if there is no entity. + public bool IsEntityValid([NotNullWhen(true)] EntityUid? uid, AntagSpecifierPrototype def) + { + // If the player has not spawned in as any entity (e.g., in the lobby), they can be given an antag role/entity. + if (!_whitelist.CheckBoth(uid, def.Blacklist, def.Whitelist)) + return false; + + if (_arrivals.IsOnArrivals((uid.Value, null))) + return false; + + // No ghosts!!! + if (HasComp(uid)) + return false; + + if (!def.AllowNonHumans && !HasComp(uid)) + return false; + + return true; + } + + /// + /// Checks if our session is banned from playing this antag. If so returns true. + /// This is separate so that methods which normally force antag can return early. + /// + /// Player who may or may not be banned from an antagonist + /// The definition which a player may or may not be banned from + /// True if any of the preferred roles within the definition hit a ban. + [PublicAPI] + public bool IsAntagBanned(ICommonSession session, AntagSpecifierPrototype definition) + { + if (_ban.GetAntagBans(session.UserId) is not { } bans) + return false; + + foreach (var role in definition.PrefRoles) + { + // banned! + if (bans.Contains(role)) + return true; + } + + return false; + } + + /// + [PublicAPI] + public bool TryMakeAntag(Entity gameRule, + ProtoId proto, + ICommonSession session, + bool checkPref = true) + { + if (!Proto.Resolve(proto, out var def)) + return false; + + return TryMakeAntag(gameRule, def, session, checkPref); + } + + /// + /// Tries to make a given player into the specified antagonist for the given game rule. + /// + [PublicAPI] + public bool TryMakeAntag(Entity gameRule, + AntagSpecifierPrototype prototype, + ICommonSession session, + bool checkPref = true) + { + _adminLogger.Add(LogType.AntagSelection, + $"Start trying to make {session} become the antagonist: {ToPrettyString(gameRule)}, {prototype.ID}"); + + if (!CanBeAntag(session, gameRule, prototype, checkPref)) + return false; + + PreSelectSession(gameRule, prototype, session); + return TryInitializeAntag(gameRule, prototype, session); + } + + /// + public bool TryAssignNextAvailableAntag(Entity gameRule, ICommonSession session) + { + return TryAssignNextAvailableAntag(gameRule, session, GetActivePlayerCount()); + } + + /// + /// Tries to find an open antag slot for a given player and assign it to that player. + /// + /// GameRule we are checking for antags. + /// Player we're trying to assign antag to. + /// Current number of players in the round. Used to determine antag count. + /// Returns true if an open antag slot was found and successfully assigned, false otherwise. + public bool TryAssignNextAvailableAntag(Entity gameRule, + ICommonSession session, + int players) + { + foreach (var selector in gameRule.Comp.Antags) + { + if (!Proto.Resolve(selector.Proto, out var antag)) + continue; + + // Because this value can theoretically fluctuate as players leave and join, we don't want to cache it. + if (AllAntagsAssigned(gameRule, antag, players)) + continue; + + // Try and assign this antag, if we fail, then try the next definition! + if (TryMakeAntag(gameRule, antag, session)) + return true; + } + + return false; + } + + /// + /// Attempt to make this player be a late-join antag. + /// + /// The session to attempt to make antag. + [PublicAPI] + public bool TryMakeLateJoinAntag(ICommonSession session) + { + // Sorry buddy, no antag for you! + if (!RobustRandom.Prob(LateJoinRandomChance)) + return false; + + // TODO: We may want to query all rules to add late joins to pre-selections? + // This logic is effectively copy-pasted from the old system with some fixes. + var query = QueryActiveRules(); + var rules = new List<(EntityUid, AntagSelectionComponent)>(); + while (query.MoveNext(out var uid, out _, out var antag, out _)) + { + // This is intended to only be used for ghost roles so it shouldn't be assigned for late joins + if (antag.SelectionTime == Never || !antag.LateJoinAdditional) + continue; + + rules.Add((uid, antag)); + } + + RobustRandom.Shuffle(rules); + + var players = GetActivePlayerCount(); + + foreach (var (uid, antag) in rules) + { + if (TryAssignNextAvailableAntag((uid, antag), session, players)) + return true; + } + + return false; + } + + /// + /// Takes a list of AntagRules and tries to make ghost roles out of them. + /// + /// list of antag rules we wish to turn into ghost roles. + /// Note, a ghost role can only be created if the rule has the ghost role spawner protoId set to a valid prototype. + /// Whether we should throw if the spawner prototype doesn't exist. + [PublicAPI] + public void SpawnGhostRoles(List antagRules, bool assert = false) + { + foreach (var rule in antagRules) + { + SpawnGhostRoles(rule.GameRule, rule.Definition, rule.Count, assert); + } + } + + /// + [PublicAPI] + public void SpawnGhostRoles(Entity gameRule, int playerCount, bool assert = false) + { + SpawnGhostRoles(gameRule, GetAntags(gameRule, playerCount), assert); + } + + /// + /// Takes a list of AntagCounts and tries to make ghost roles out of them + /// + /// Game rule with the associated antags we're spawning + /// Antags we want to make into ghost roles, with paired counts we need to spawn + /// Whether we should throw if the spawner prototype doesn't exist. + [PublicAPI] + public void SpawnGhostRoles(Entity gameRule, AntagCount[] antagRules, bool assert = false) + { + foreach (var rule in antagRules) + { + SpawnGhostRoles(gameRule, rule.Definition, rule.Count, assert); + } + } + + /// + [PublicAPI] + public void SpawnGhostRoles(Entity gameRule, + ProtoId protoId, + int count, + bool assert = false) + { + if (!Proto.Resolve(protoId, out var antag)) + return; + + SpawnGhostRoles(gameRule, antag, count, assert); + } + + /// + /// Creates ghost role spawners for a given antag definition equivalent to the count. + /// + /// Game rule with the associated antags we're spawning + /// Antag prototype we're spawning. + /// Amount of ghost roles we are spawning. + /// Whether we should throw if the spawner prototype doesn't exist. + [PublicAPI] + public void SpawnGhostRoles(Entity gameRule, AntagSpecifierPrototype proto, int count, bool assert = false) + { + for (var i = 0; i < count; i++) + { + SpawnGhostRole(gameRule, proto, assert); + } + } + + /// + /// Creates a ghost role spawner of a given antag for a given game rule. + /// + /// Game rule with the associated antags we're spawning + /// Antag prototype we're spawning. + /// Whether we should throw if the spawner prototype doesn't exist. + [PublicAPI] + public void SpawnGhostRole(Entity gameRule, AntagSpecifierPrototype proto, bool assert = false) + { + if (proto.SpawnerPrototype is not { } spawnerPrototype) + { + Debug.Assert(!assert, $"Tried to spawn a ghost role for {proto.ID}, but it had no prototype!"); + return; + } + + + if (!TryGetValidSpawnPosition(gameRule, proto, out var coordinates)) + { + Log.Error( + $"Found no valid positions to place antag spawner for game rule: {ToPrettyString(gameRule)}, antag: {proto.ID}"); + return; + } + + var spawner = Spawn(spawnerPrototype, coordinates.Value); + if (!TryComp(spawner, out var spawnerComp)) + { + Log.Error($"Antag spawner {spawner} does not have a {nameof(GhostRoleAntagSpawnerComponent)}."); + _adminLogger.Add(LogType.AntagSelection, + $"Antag spawner {spawner} in game rule {ToPrettyString(gameRule)} failed due to not having {nameof(GhostRoleAntagSpawnerComponent)}."); + Del(spawner); + return; + } + + spawnerComp.Rule = gameRule; + spawnerComp.Definition = proto; + } + + /// + /// Attempts to find a valid existing game rule for our antag, creating a new one if none exist. + /// Then attempts to ticket an existing antag slot to our player, forcing one if there are no open slots. + /// You shouldn't be using this basically ever except for debug and admin stuff. + /// + [Obsolete] + public void ForceMakeAntag(ICommonSession player, EntProtoId defaultRule) where T : Component + { + var rule = ForceGetGameRuleEnt(defaultRule); + + if (TryAssignNextAvailableAntag(rule, player)) + return; + + if (rule.Comp.Antags.LastOrDefault() is not { } antag || !Proto.Resolve(antag.Proto, out var proto)) + return; + + PreSelectSession(rule, proto, player); + TryInitializeAntag(rule, proto, player); + } + + /// + public void ForceMakeAntag(ICommonSession player, EntProtoId ruleProto, ProtoId antagProto) where T : Component + { + if (!Proto.Resolve(antagProto, out var antag)) + return; + + ForceMakeAntag(player, ruleProto, antag); + } + + /// + /// Attempts to create a specific antag from a specific game rule prototype. Checking if the game rule already exists first. + /// + /// Player we are making into an antag + /// Game rule prototype associated with the antag we are creating. + /// Prototype for the antag we are creating. + /// Component from the game rule we are creating, for faster querying. + /// + /// Do not use this method for anything other than debugging purposes. + /// This ignores antag bans and the like so genuinely *do not use this unless it's for debugging purposes* + /// + public void ForceMakeAntag(ICommonSession player, EntProtoId ruleProto, AntagSpecifierPrototype proto) where T : Component + { + var rule = ForceGetGameRuleEnt(ruleProto); + + foreach (var antag in rule.Comp.Antags) + { + if (antag.Proto != proto) + continue; + + // Try and assign this antag, if we fail, then try the next definition! + PreSelectSession(rule, proto, player); + if (TryInitializeAntag(rule, proto, player)) + return; + } + + Log.Error($"Antag Prototype {proto.ID} does not exist in {ToPrettyString(rule)}, {ruleProto}"); + } + + /// + /// Tries to find a valid gamerule which matches a specific prototype and component. + /// Note that this is private because you generally should not be forcing a gamerule and this code is evil. + /// I'm not touching it any more than I have to. + /// + private Entity ForceGetGameRuleEnt(string id) where T : Component + { + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out _, out var comp)) + { + if (MetaData(uid).EntityPrototype?.ID == id) + return (uid, comp); + } + var ruleEnt = GameTicker.AddGameRule(id); + RemComp(ruleEnt); + var antag = RuleQuery.Comp(ruleEnt); + antag.AssignmentHandled = true; // don't do normal selection. + GameTicker.StartGameRule(ruleEnt); + return (ruleEnt, antag); + } +} diff --git a/Content.Server/Antag/AntagSelectionSystem.API.cs b/Content.Server/Antag/AntagSelectionSystem.API.cs index 5debd10b6e..3fcaf9dde8 100644 --- a/Content.Server/Antag/AntagSelectionSystem.API.cs +++ b/Content.Server/Antag/AntagSelectionSystem.API.cs @@ -1,12 +1,11 @@ -using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Server.Antag.Components; -using Content.Server.GameTicking.Rules.Components; +using Content.Server.Antag.Selectors; using Content.Shared.Antag; using Content.Shared.Chat; using Content.Shared.GameTicking.Components; +using Content.Shared.Ghost; using Content.Shared.Mind; -using Content.Shared.Preferences; using Content.Shared.Roles; using JetBrains.Annotations; using Robust.Shared.Audio; @@ -18,62 +17,29 @@ namespace Content.Server.Antag; public sealed partial class AntagSelectionSystem { - /// - /// Tries to get the next non-filled definition based on the current amount of selected minds and other factors. - /// - public bool TryGetNextAvailableDefinition(Entity ent, - [NotNullWhen(true)] out AntagSelectionDefinition? definition, - int? players = null) + /// + [PublicAPI] + public int GetActivePlayerCount() { - definition = null; - - var totalTargetCount = GetTargetAntagCount(ent, players); - var mindCount = ent.Comp.AssignedMinds.Count; - if (mindCount >= totalTargetCount) - return false; - - // TODO ANTAG fix this - // If here are two definitions with 1/10 and 10/10 slots filled, this will always return the second definition - // even though it has already met its target - // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA I fucking hate game ticker code. - // It needs to track selected minds for each definition independently. - foreach (var def in ent.Comp.Definitions) - { - var target = GetTargetAntagCount(ent, null, def); - - if (mindCount < target) - { - definition = def; - return true; - } - - mindCount -= target; - } - - return false; + return GetActivePlayerCount(_playerManager.Sessions); } /// - /// Gets the number of antagonists that should be present for a given rule based on the provided pool. - /// A null pool will simply use the player count. + /// Returns the total number of valid players from the given player pool. + /// For a player to be valid, they must have a connection to the server, be in the round, and have a non-ghost entity. /// - public int GetTargetAntagCount(Entity ent, int? playerCount = null) - { - var count = 0; - foreach (var def in ent.Comp.Definitions) - { - count += GetTargetAntagCount(ent, playerCount, def); - } - - return count; - } - - public int GetTotalPlayerCount(IList pool) + /// Player pool we're querying, this typically includes all players connected to the server. + /// The number of valid players + [PublicAPI] + public int GetActivePlayerCount(IList pool) { var count = 0; foreach (var session in pool) { - if (session.Status is SessionStatus.Disconnected or SessionStatus.Zombie) + if (IsDisconnected(session)) + continue; + + if (session.AttachedEntity is not { } uid || HasComp(uid)) continue; count++; @@ -82,28 +48,129 @@ public sealed partial class AntagSelectionSystem return count; } - /// - /// Gets the number of antagonists that should be present for a given antag definition based on the provided pool. - /// A null pool will simply use the player count. - /// - public int GetTargetAntagCount(Entity ent, int? playerCount, AntagSelectionDefinition def) + [PublicAPI] + public IEnumerable GetActivePlayers() { - // TODO ANTAG - // make pool non-nullable - // Review uses and ensure that people are INTENTIONALLY including players in the lobby if this is a mid-round - // antag selection. - var poolSize = playerCount ?? GetTotalPlayerCount(_playerManager.Sessions); + return GetActivePlayers(_playerManager.Sessions); + } - // factor in other definitions' affect on the count. - var countOffset = 0; - foreach (var otherDef in ent.Comp.Definitions) + [PublicAPI] + public IEnumerable GetActivePlayers(IList pool) + { + foreach (var session in pool) { - countOffset += Math.Clamp((poolSize - countOffset) / otherDef.PlayerRatio, otherDef.Min, otherDef.Max) * otherDef.PlayerRatio; // Note: Is the PlayerRatio necessary here? Seems like it can cause issues for defs with varied PlayerRatio. - } - // make sure we don't double-count the current selection - countOffset -= Math.Clamp(poolSize / def.PlayerRatio, def.Min, def.Max) * def.PlayerRatio; + if (IsDisconnected(session)) + continue; - return Math.Clamp((poolSize - countOffset) / def.PlayerRatio, def.Min, def.Max); + if (session.AttachedEntity is not { } uid || HasComp(uid)) + continue; + + yield return session; + } + } + + public bool IsDisconnected(ICommonSession session) + { + return session.Status is SessionStatus.Disconnected or SessionStatus.Zombie; + } + + /// + /// Gets the total number of antags a game rule wishes to spawn. + /// + /// Game rule which is spawning antags + /// Simulated player count + /// Total number of antags this gamerule will spawn + [PublicAPI] + public int GetTotalAntagCount(Entity gameRule, int playerCount) + { + var runningCount = 0; + var count = 0; + + // We assume that antag definitions are prioritized by order, and take up slots that other roles may take. + // I.E for Nukies, it selects 1 commander which takes up 10 players, then one corpsman which takes up another 10, then we select X nukies based on the remaining player count. + // This is how the system worked when I got here, and I decided not to change it to avoid fucking with team antag balance + foreach (var antag in gameRule.Comp.Antags) + { + if (!Proto.Resolve(antag.Proto, out _)) + continue; + + count += GetTargetAntagCount(antag, playerCount, ref runningCount); + runningCount += count * antag.PlayerRatio; + } + + return count; + } + + /// + /// Gets the number of antags of a given type this game rule is attempting to spawn, for a given player count. + /// + /// Game rule which is spawning the antags + /// Current player count + /// Antag prototype we're spawning + /// Number of antags of this type we're spawning. + [PublicAPI] + public int GetTargetAntagCount(Entity gameRule, int playerCount, ProtoId proto) + { + if (!Proto.Resolve(proto, out var antag)) + return 0; + + return GetTargetAntagCount(gameRule, playerCount, antag); + } + + /// + [PublicAPI] + public int GetTargetAntagCount(Entity gameRule, int playerCount, AntagSpecifierPrototype proto) + { + var runningCount = 0; + + // We assume that antag definitions are prioritized by order, and take up slots that other roles may take. + // I.E for Nukies, it selects 1 commander which takes up 10 players, then one corpsman which takes up another 10, then we select X nukies based on the remaining player count. + // This is how the system worked when I got here, and I decided not to change it to avoid fucking with team antag balance + foreach (var antag in gameRule.Comp.Antags) + { + if (!Proto.Resolve(antag.Proto, out _)) + continue; + + // We need to update our running count which is why we get the count for definitions we may not be assigning. + var count = GetTargetAntagCount(antag, playerCount, ref runningCount); + + if (antag.Proto == proto) + return count; + } + + Log.Error($"Error, attempted to get the antag count for an antagonist, {proto.ID} not included in gamerule: {ToPrettyString(gameRule)}"); + return 0; + } + + /// + /// Do not use this if you don't know what you're doing. This is public for test purposes only. + /// + public int GetTargetAntagCount(AntagCountSelector selector, int playerCount, ref int runningCount) + { + var count = selector.GetTargetAntagCount(RobustRandom, playerCount - runningCount); + runningCount += count * selector.PlayerRatio; + return count; + } + + /// + /// Gets the total number of assigned antags of a given type from a game rule. + /// + /// Game rule entity + /// The antag prototype we're checking + /// The amount of sessions which this game rule has assigned our given prototype to. + [PublicAPI] + public int GetAssignedAntagCount(Entity gameRule, ProtoId proto) + { + return !gameRule.Comp.AssignedMinds.TryGetValue(proto, out var assigned) ? 0 : assigned.Count; + } + + /// + /// Checks if all antags of this specific type from this specific game rule have been assigned. + /// + [PublicAPI] + public bool AllAntagsAssigned(Entity gameRule, AntagSpecifierPrototype proto, int players) + { + return GetAssignedAntagCount(gameRule, proto) < GetTargetAntagCount(gameRule, players, proto); } /// @@ -112,95 +179,76 @@ public sealed partial class AntagSelectionSystem /// /// A list containing, in order, the antag's mind, the session data, and the original name stored as a string. /// - public List<(EntityUid, SessionData, string)> GetAntagIdentifiers(Entity ent) + [PublicAPI] + public IEnumerable<(EntityUid, SessionData, string)> GetAntagIdentifiers(Entity ent) { - if (!Resolve(ent, ref ent.Comp, false)) - return new List<(EntityUid, SessionData, string)>(); + if (!RuleQuery.Resolve(ent, ref ent.Comp, false)) + yield break; - var output = new List<(EntityUid, SessionData, string)>(); - foreach (var (mind, name) in ent.Comp.AssignedMinds) + foreach (var (_, minds) in ent.Comp.AssignedMinds) { - if (!TryComp(mind, out var mindComp) || mindComp.OriginalOwnerUserId == null) - continue; + foreach (var (mind, name) in minds) + { + if (!TryComp(mind, out var mindComp) || mindComp.OriginalOwnerUserId == null) + continue; - if (!_playerManager.TryGetPlayerData(mindComp.OriginalOwnerUserId.Value, out var data)) - continue; + if (!_playerManager.TryGetPlayerData(mindComp.OriginalOwnerUserId.Value, out var data)) + continue; - output.Add((mind, data, name)); + yield return (mind, data, name); + } + } + } + + /// + /// Returns identifiable information for all antagonists to be used in a round end summary. + /// + /// + /// A list containing, in order, the antag's mind, the session data, and the original name stored as a string. + /// + [PublicAPI] + public IEnumerable<(EntityUid, string)> GetAntagIdentities(Entity ent) + { + if (!RuleQuery.Resolve(ent, ref ent.Comp, false)) + yield break; + + foreach (var (_, minds) in ent.Comp.AssignedMinds) + { + foreach (var identity in minds) + { + yield return identity; + } } - return output; } /// /// Returns all the minds of antagonists. /// - public List> GetAntagMinds(Entity ent) + [PublicAPI] + public IEnumerable> GetAntagMinds(Entity ent) { - if (!Resolve(ent, ref ent.Comp, false)) - return new(); + if (!RuleQuery.Resolve(ent, ref ent.Comp, false)) + yield break; - var output = new List>(); - foreach (var (mind, _) in ent.Comp.AssignedMinds) + foreach (var (_, minds) in ent.Comp.AssignedMinds) { - if (!TryComp(mind, out var mindComp) || mindComp.OriginalOwnerUserId == null) - continue; + foreach (var (mind, _) in minds) + { + if (!TryComp(mind, out var mindComp) || mindComp.OriginalOwnerUserId == null) + continue; - output.Add((mind, mindComp)); + yield return (mind, mindComp); + } } - return output; - } - - /// - /// Helper to get just the mind entities and not names. - /// - public List GetAntagMindEntityUids(Entity ent) - { - if (!Resolve(ent, ref ent.Comp, false)) - return new(); - - return ent.Comp.AssignedMinds.Select(p => p.Item1).ToList(); - } - - /// - /// Checks if a given session has enabled the antag preferences for a given definition, - /// and if it is blocked by any requirements or bans. - /// - /// Returns true if at least one role from the provided list passes every condition> - public bool ValidAntagPreference(ICommonSession? session, List> roles) - { - if (session == null) - return true; - - if (roles.Count == 0) - return false; - - if (!_pref.TryGetCachedPreferences(session.UserId, out var pref)) - return false; - - var character = (HumanoidCharacterProfile) pref.SelectedCharacter; - - var valid = false; - - // Check each individual antag role - foreach (var role in roles) - { - var list = new List>{role}; - - if (character.AntagPreferences.Contains(role) - && !_ban.IsRoleBanned(session, list) - && _playTime.IsAllowed(session, list)) - valid = true; - } - - return valid; } /// /// Returns all the antagonists for this rule who are currently alive /// + [PublicAPI] public IEnumerable GetAliveAntags(Entity ent) { - if (!Resolve(ent, ref ent.Comp, false)) + if (!RuleQuery.Resolve(ent, ref ent.Comp, false)) yield break; var minds = GetAntagMinds(ent); @@ -217,9 +265,10 @@ public sealed partial class AntagSelectionSystem /// /// Returns the number of alive antagonists for this rule. /// + [PublicAPI] public int GetAliveAntagCount(Entity ent) { - if (!Resolve(ent, ref ent.Comp, false)) + if (!RuleQuery.Resolve(ent, ref ent.Comp, false)) return 0; var numbah = 0; @@ -238,9 +287,10 @@ public sealed partial class AntagSelectionSystem /// /// Returns if there are any remaining antagonists alive for this rule. /// + [PublicAPI] public bool AnyAliveAntags(Entity ent) { - if (!Resolve(ent, ref ent.Comp, false)) + if (!RuleQuery.Resolve(ent, ref ent.Comp, false)) return false; return GetAliveAntags(ent).Any(); @@ -249,9 +299,10 @@ public sealed partial class AntagSelectionSystem /// /// Checks if all the antagonists for this rule are alive. /// + [PublicAPI] public bool AllAntagsAlive(Entity ent) { - if (!Resolve(ent, ref ent.Comp, false)) + if (!RuleQuery.Resolve(ent, ref ent.Comp, false)) return false; return GetAliveAntagCount(ent) == ent.Comp.AssignedMinds.Count; @@ -264,6 +315,7 @@ public sealed partial class AntagSelectionSystem /// The briefing text to send /// The color the briefing should be, null for default /// The sound to briefing/greeting sound to play + [PublicAPI] public void SendBriefing(EntityUid entity, string briefing, Color? briefingColor, SoundSpecifier? briefingSound) { if (!_mind.TryGetMind(entity, out _, out var mindComponent)) @@ -296,7 +348,7 @@ public sealed partial class AntagSelectionSystem /// /// The player chosen to be an antag /// The briefing data - public void SendBriefing( + private void SendBriefing( ICommonSession? session, BriefingData? data) { @@ -314,6 +366,7 @@ public sealed partial class AntagSelectionSystem /// The briefing text to send /// The color the briefing should be, null for default /// The sound to briefing/greeting sound to play + // TODO: It might take a bit of effort but this can probably be privated. public void SendBriefing( ICommonSession? session, string briefing, @@ -327,98 +380,292 @@ public sealed partial class AntagSelectionSystem if (!string.IsNullOrEmpty(briefing)) { var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", briefing)); - _chat.ChatMessageToOne(ChatChannel.Server, briefing, wrappedMessage, default, false, session.Channel, - briefingColor); + _chat.ChatMessageToOne(ChatChannel.Server, briefing, wrappedMessage, default, false, session.Channel, briefingColor); } } /// - /// This technically is a gamerule-ent-less way to make an entity an antag. - /// You should almost never be using this. + /// Returns a list of all antag players who are constrained by a job whitelist or blacklist from an antag. /// - public void ForceMakeAntag(ICommonSession? player, string defaultRule) where T : Component + /// Antag prototypes we're excluding for our returned job whitelist/blacklist. + /// A dictionary of antag sessions, and their job blacklists. + [PublicAPI] + public Dictionary>? Whitelist, HashSet>? Blacklist)> + GetAntagJobs(params HashSet> except) { - var rule = ForceGetGameRuleEnt(defaultRule); - - if (!TryGetNextAvailableDefinition(rule, out var def)) - def = rule.Comp.Definitions.Last(); - MakeAntag(rule, player, def.Value); - } - - /// - /// Tries to grab one of the weird specific antag gamerule ents or starts a new one. - /// This is gross code but also most of this is pretty gross to begin with. - /// - public Entity ForceGetGameRuleEnt(string id) where T : Component - { - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out _, out var comp)) - { - return (uid, comp); - } - var ruleEnt = GameTicker.AddGameRule(id); - RemComp(ruleEnt); - var antag = Comp(ruleEnt); - antag.AssignmentComplete = true; // don't do normal selection. - GameTicker.StartGameRule(ruleEnt); - return (ruleEnt, antag); - } - - /// - /// Get all sessions that have been preselected for antag. - /// - /// A specific definition to be excluded from the check. - public HashSet GetPreSelectedAntagSessions(AntagSelectionDefinition? except = null) - { - var result = new HashSet(); + var result = new Dictionary>? Whitelist, HashSet>? Blacklist)>(); var query = QueryAllRules(); while (query.MoveNext(out var uid, out var comp, out _)) { if (HasComp(uid)) continue; - foreach (var def in comp.Definitions) + foreach (var antag in comp.Antags) { - if (def.Equals(except)) + if (except.Contains(antag)) continue; - if (comp.PreSelectedSessions.TryGetValue(def, out var set)) - result.UnionWith(set); - } - } - - return result; - } - - /// - /// Get all sessions that have been preselected for antag and are exclusive, i.e. should not be paired with other antags. - /// - /// A specific definition to be excluded from the check. - // Note: This is a bit iffy since technically this exclusive definition is defined via the MultiAntagSetting, while there's a separately tracked antagExclusive variable in the mindrole. - // We can't query that however since there's no guarantee the mindrole has been given out yet when checking pre-selected antags. - // I don't think there's any instance where they differ, but it's something to be aware of for a potential future refactor. - public HashSet GetPreSelectedExclusiveAntagSessions(AntagSelectionDefinition? except = null) - { - var result = new HashSet(); - var query = QueryAllRules(); - while (query.MoveNext(out var uid, out var comp, out _)) - { - if (HasComp(uid)) - continue; - - foreach (var def in comp.Definitions) - { - if (def.Equals(except)) + if (!comp.PreSelectedSessions.TryGetValue(antag, out var set) || !Proto.Resolve(antag.Proto, out var proto)) continue; - if (def.MultiAntagSetting == AntagAcceptability.None && comp.PreSelectedSessions.TryGetValue(def, out var set)) + // Check this here so we don't make a dictionary entry for a bunch of players, with empty blacklists and whitelists. + if (proto.JobBlacklist == null && proto.JobWhitelist == null) + continue; + + foreach (var player in set) { - result.UnionWith(set); - break; + if (result.TryGetValue(player, out var jobs)) + { + if (proto.JobWhitelist != null) + { + if (jobs.Whitelist == null) + jobs.Whitelist = proto.JobWhitelist; + else + jobs.Whitelist.UnionWith(proto.JobWhitelist); + } + + if (proto.JobBlacklist != null) + { + if (jobs.Blacklist == null) + jobs.Blacklist = proto.JobBlacklist; + else + jobs.Blacklist.UnionWith(proto.JobBlacklist); + } + } + else + { + result.Add(player, (proto.JobWhitelist, proto.JobBlacklist)); + } } } } return result; } + + /// + /// Returns a list of all blacklisted and whitelisted jobs for this player + /// + /// Player we're checking the blocked jobs of + /// Antag prototypes we're excluding in our search + /// A tuple of a whitelist and blacklist hashset for this player. + [PublicAPI] + public (HashSet>? Whitelist, HashSet>? Blacklist) + GetAntagJobs(ICommonSession player, params HashSet> except) + { + HashSet>? whitelist = null; + HashSet>? blacklist = null; + var query = QueryAllRules(); + while (query.MoveNext(out var uid, out var comp, out _)) + { + if (HasComp(uid)) + continue; + + foreach (var antag in comp.Antags) + { + if (except.Contains(antag)) + continue; + + if (!comp.PreSelectedSessions.TryGetValue(antag, out var set) || !set.Contains(player)) + continue; + + if (!Proto.Resolve(antag.Proto, out var proto)) + continue; + + if (proto.JobWhitelist != null) + { + if (whitelist == null) + whitelist = proto.JobWhitelist; + else + whitelist.UnionWith(proto.JobWhitelist); + } + + if (proto.JobBlacklist != null) + { + if (blacklist == null) + blacklist = proto.JobBlacklist; + else + blacklist.UnionWith(proto.JobBlacklist); + } + } + } + + return (whitelist, blacklist); + } + + /// + /// Get all sessions that have been preselected for antag. + /// + /// A specific definition to be excluded from the check. + [PublicAPI] + public HashSet GetPreSelectedAntagSessions(params HashSet> except) + { + var result = new HashSet(); + var query = QueryAllRules(); + while (query.MoveNext(out var uid, out var comp, out _)) + { + if (HasComp(uid)) + continue; + + foreach (var antag in comp.Antags) + { + if (except.Contains(antag)) + continue; + + if (comp.PreSelectedSessions.TryGetValue(antag, out var set)) + result.UnionWith(set); + } + } + + return result; + } + + public bool TryGetValidAntagPreferences(ICommonSession session, List>? filter = null) + { + return TryGetValidAntagPreferences(session, out _, filter); + } + + /// + /// Gets the antag preferences for a specific session, excluding banned antags or antags this player lacks the playtime for. + /// + /// Session we want the antag preferences for + /// List of valid antag prototypes this player can play as. + /// Optional list of antag prototypes we're specifically looking for. + /// True if this player has any antags enabled they can play and pass our filter + [PublicAPI] + public bool TryGetValidAntagPreferences(ICommonSession session, out List> antags, List>? filter = null) + { + antags = new List>(GetValidAntagPreferences(session, filter)); + return antags.Count > 0; + } + + /// + /// Gets the antag preferences for a specific session, excluding banned antags or antags this player lacks the playtime for. + /// Optionally takes a filter for antag preferences we're specifically looking for. + /// + /// Session we want the antag preferences for + /// Optional list of antag preferences we're specifically looking for. + /// A list of all antags which the player meets the requirement for, and are contained in the filter + [PublicAPI] + public IEnumerable> GetValidAntagPreferences(ICommonSession session, List>? filter = null) + { + if (!_pref.TryGetCachedPreferences(session.UserId, out var prefs)) + yield break; + + foreach (var antag in prefs.SelectedCharacter.AntagPreferences) + { + // We also check this in IsSessionValid, but we also check it here since this is public API. + if (_ban.IsRoleBanned(session, antag) || !_playTime.IsAllowed(session, antag)) + continue; + + if (filter != null && !filter.Contains(antag)) + continue; + + yield return antag; + } + } + + /// + /// Checks if a player has been assigned antag for a specific game rule. + /// Does not check if that game rule is active or ended so check that beforehand if it matters. + /// + /// + [PublicAPI] + public bool IsAssignedAntag(Entity gameRule, ICommonSession player) + { + // First check our mindroles. + if (_role.PlayerIsAntagonist(player)) + return true; + + foreach (var (_, sessions) in gameRule.Comp.PreSelectedSessions) + { + // Session has already been preselected as antagonist, and therefore *has* been assigned antag! + if (sessions.Contains(player)) + return true; + } + + return false; + } + + /// + /// Checks if a player has been assigned a specific antag for a specific game rule. + /// Does not check if that game rule is active or ended so check that beforehand if it matters. + /// Also does not check mind roles, but if the game rule data is messed up you have bigger problems. + /// + /// + [PublicAPI] + public bool IsAssignedAntag(Entity gameRule, ProtoId antag, ICommonSession player) + { + if (!gameRule.Comp.PreSelectedSessions.TryGetValue(antag, out var sessions)) + return false; + + // Session has already been preselected as antagonist, and therefore *has* been assigned antag! + return sessions.Contains(player); + } + + /// + /// Checks if the given player is currently assigned antag for any game rule. + /// + /// Player who may or may not be the antagonist. + /// Game rule entities we're ignoring. + /// You can only get one antag per game rule so it's fine to ignore by uid. + /// True if there is a game rule giving this player antag status + [PublicAPI] + public bool IsAssignedAntag(ICommonSession player, params HashSet ignored) + { + // First check our mindroles. + if (_role.PlayerIsAntagonist(player)) + return true; + + var query = QueryAllRules(); + while (query.MoveNext(out var uid, out var comp, out _)) + { + if (ignored.Contains(uid) || HasComp(uid)) + continue; + + foreach (var (_, sessions) in comp.PreSelectedSessions) + { + // Session has already been preselected as antagonist, and therefore *has* been assigned antag! + if (sessions.Contains(player)) + return true; + } + } + + return false; + } + + /// + /// Checks if the given player is currently assigned antag for any game rule that is incompatible with other antag prototypes. + /// + /// Player who may or may not be the antagonist. + /// Game rule entities we're ignoring. + /// True if there is a game rule giving this player antag status that is exclusive with other antags + [PublicAPI] + public bool IsAssignedExclusiveAntag(ICommonSession player, params HashSet ignored) + { + // First check our mindroles. + if (_role.MindIsExclusiveAntagonist(player.AttachedEntity)) + return true; + + var query = QueryAllRules(); + while (query.MoveNext(out var uid, out var comp, out _)) + { + if (ignored.Contains(uid) || HasComp(uid)) + continue; + + foreach (var (proto, sessions) in comp.PreSelectedSessions) + { + if (!Proto.Resolve(proto, out var def)) + continue; // How did you even get here? + + if (!sessions.Contains(player)) + continue; + + if (def.MultiAntagSetting == AntagAcceptability.None) + return true; + } + } + + return false; + } } diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index 5c94942c9a..da21b1f6d5 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -1,3 +1,5 @@ +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Server.Administration.Managers; using Content.Server.Antag.Components; @@ -20,45 +22,79 @@ using Content.Shared.Clothing; using Content.Shared.Database; using Content.Shared.GameTicking; using Content.Shared.GameTicking.Components; -using Content.Shared.Ghost; -using Content.Shared.Humanoid; using Content.Shared.Mind; using Content.Shared.Players; +using Content.Shared.Random.Helpers; using Content.Shared.Roles; using Content.Shared.Whitelist; using Robust.Server.Audio; using Robust.Server.GameObjects; using Robust.Server.Player; -using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Utility; +using static Content.Server.Antag.Components.AntagSelectionTime; namespace Content.Server.Antag; +/// +/// Turns players into antags. +/// When the round starts, all active game rules select players for antagonist. +/// When a game rule is started, all selected players are given their antagonist status (including entities and components) +/// If selection was not done before the game rule has been started, it will happen during that step. +/// Antag entities spawned by this system are always prioritized over the player's current entity. +/// +/// +/// I leave this remark here as a reminder of two things: +/// Never initialize entities while they're still in nullspace, I had to refactor this system to fix that. +/// Do not touch the spawning logic unless you understand how spawning works in engine to ensure the above. +/// Never do a patchwork refactor for a bad system, I had to refactor this system twice because of that mistake. +/// I hope this system is now readable and significantly less buggy thanks to my efforts. +/// I could do more, but I've been soaped enough. Now it's your turn to fix it. +/// public sealed partial class AntagSelectionSystem : GameRuleSystem { - [Dependency] private readonly AudioSystem _audio = default!; [Dependency] private readonly IBanManager _ban = default!; [Dependency] private readonly IChatManager _chat = default!; + [Dependency] private readonly IPlayerManager _playerManager = default!; + [Dependency] private readonly IServerPreferencesManager _pref = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly ArrivalsSystem _arrivals = default!; + [Dependency] private readonly AudioSystem _audio = default!; + [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; [Dependency] private readonly GhostRoleSystem _ghostRole = default!; [Dependency] private readonly JobSystem _jobs = default!; [Dependency] private readonly LoadoutSystem _loadout = default!; [Dependency] private readonly MindSystem _mind = default!; - [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly PlayTimeTrackingSystem _playTime = default!; - [Dependency] private readonly IServerPreferencesManager _pref = default!; [Dependency] private readonly RoleSystem _role = default!; [Dependency] private readonly TransformSystem _transform = default!; - [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; - [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; - [Dependency] private readonly ArrivalsSystem _arrivals = default!; // arbitrary random number to give late joining some mild interest. public const float LateJoinRandomChance = 0.5f; + /// + /// List of game rules and antags that are assigned during + /// Should only ever include game rules with of + /// + private List? _preSpawnRules; + + /// + /// List of game rules and antags that are assigned during + /// Includes both game rules with of + /// and active game rules with of + /// + private List? _postSpawnRules; + + /// + /// A list of players which were selected by a game rule for a specific antag during + /// but were not spawned during that step, and now must be spawned during . + /// This is also used to check for errors during to see if any players were assigned + /// + private List<(Entity gameRule, AntagSpecifierPrototype antag, ICommonSession player)> _delayedAntags = []; + /// public override void Initialize() { @@ -70,100 +106,62 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem(OnObjectivesTextGetInfo); - SubscribeLocalEvent(OnJobNotAssigned); + // In order of how these occur. SubscribeLocalEvent(OnPlayerSpawning); + SubscribeLocalEvent(OnJobNotAssigned); SubscribeLocalEvent(OnJobsAssigned); SubscribeLocalEvent(OnSpawnComplete); } + protected override void Started(EntityUid uid, AntagSelectionComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args) + { + base.Started(uid, component, gameRule, args); + + // If we're not in round, don't spawn or assign antags. Those will be handled by RulePlayerSpawning, and RulePlayerJobs + if (GameTicker.RunLevel != GameRunLevel.InRound) + return; + + if (component.AssignmentHandled) + return; + + // Antags haven't been selected so we need to select them! Only if we select when the game rule starts though! + if (component.PreSelectionsComplete) + AssignPreSelectedSessions((uid, component)); + else if (component.SelectionTime == RuleStarted) // Only pre-select antags if we pre-select on rule start + AssignAntags((uid, component)); + } + private void OnTakeGhostRole(Entity ent, ref TakeGhostRoleEvent args) { if (args.TookRole) return; - if (ent.Comp.Rule is not { } rule || ent.Comp.Definition is not { } def) + if (ent.Comp.Rule is not { } rule || ent.Comp.Definition is not { } proto) return; - if (!Exists(rule) || !TryComp(rule, out var select)) + if (!Proto.Resolve(proto, out var def)) return; - MakeAntag((rule, select), args.Player, def, ignoreSpawner: true); + if (!Exists(rule) || !RuleQuery.TryComp(rule, out var select)) + return; + + // This likely means player was banned or lacks playtime. + if (!CanBeAntag(args.Player, (rule, select), def, false)) + return; + + if (!TrySpawnAntagonist((rule, select), def, args.Player, _transform.GetMapCoordinates(ent), out var uid)) + { + Log.Error($"Tried to make {args.Player.UserId} into an antagonist but was unable to spawn an entity for them. Game rule {ToPrettyString(ent)}"); + return; + } + + // We do this after TrySpawnAntagonist so we don't have to worry about a failed spawn adding permanent pre selections to a game rule. + PreSelectSession((rule, select), def, args.Player); + InitializeAntag((rule, select), def, uid.Value, args.Player); args.TookRole = true; _ghostRole.UnregisterGhostRole((ent, Comp(ent))); } - private void OnPlayerSpawning(RulePlayerSpawningEvent args) - { - var pool = args.PlayerPool; - - var query = QueryActiveRules(); - while (query.MoveNext(out var uid, out _, out var comp, out _)) - { - if (comp.SelectionTime != AntagSelectionTime.PrePlayerSpawn && comp.SelectionTime != AntagSelectionTime.IntraPlayerSpawn) - continue; - - if (comp.AssignmentComplete) - continue; - - ChooseAntags((uid, comp), pool); // We choose the antags here... - - if (comp.SelectionTime == AntagSelectionTime.PrePlayerSpawn) - { - AssignPreSelectedSessions((uid, comp)); // ...But only assign them if PrePlayerSpawn - foreach (var session in comp.AssignedSessions) - { - args.PlayerPool.Remove(session); - GameTicker.PlayerJoinGame(session); - } - } - } - - // If IntraPlayerSpawn is selected, delayed rules should choose at this point too. - var queryDelayed = QueryDelayedRules(); - while (queryDelayed.MoveNext(out var uid, out _, out var comp, out _)) - { - if (comp.SelectionTime != AntagSelectionTime.IntraPlayerSpawn) - continue; - - ChooseAntags((uid, comp), pool); - } - } - - private void OnJobsAssigned(RulePlayerJobsAssignedEvent args) - { - var query = QueryActiveRules(); - while (query.MoveNext(out var uid, out _, out var comp, out _)) - { - if (comp.SelectionTime != AntagSelectionTime.PostPlayerSpawn && comp.SelectionTime != AntagSelectionTime.IntraPlayerSpawn) - continue; - - ChooseAntags((uid, comp), args.Players); - AssignPreSelectedSessions((uid, comp)); - } - } - - private void OnJobNotAssigned(NoJobsAvailableSpawningEvent args) - { - // If someone fails to spawn in due to there being no jobs, they should be removed from any preselected antags. - // We only care about delayed rules, since if they're active the player should have already been removed via MakeAntag. - var query = QueryDelayedRules(); - while (query.MoveNext(out var uid, out _, out var comp, out _)) - { - if (comp.SelectionTime != AntagSelectionTime.IntraPlayerSpawn) - continue; - - if (!comp.RemoveUponFailedSpawn) - continue; - - foreach (var def in comp.Definitions) - { - if (!comp.PreSelectedSessions.TryGetValue(def, out var session)) - break; - session.Remove(args.Player); - } - } - } - private void OnSpawnComplete(PlayerSpawnCompleteEvent args) { if (!args.LateJoin) @@ -172,435 +170,633 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem - /// Attempt to make this player be a late-join antag. - /// - /// The session to attempt to make antag. - public void TryMakeLateJoinAntag(ICommonSession session) + // This is called when the round starts, before jobs are selected + private void OnPlayerSpawning(RulePlayerSpawningEvent args) { - // TODO: this really doesn't handle multiple latejoin definitions well - // eventually this should probably store the players per definition with some kind of unique identifier. - // something to figure out later. + var pool = args.PlayerPool; - var query = QueryAllRules(); - var rules = new List<(EntityUid, AntagSelectionComponent)>(); - while (query.MoveNext(out var uid, out var antag, out _)) + // Get all GameRules and store all antags from them in two lists, one we query now and another we query later! + _preSpawnRules = []; + _postSpawnRules = []; + var rulesQuery = QueryAllRules(); + while (rulesQuery.MoveNext(out var uid, out var antag, out var rule)) { - if (HasComp(uid)) - rules.Add((uid, antag)); + // Add it to the list of pre selections then mark it as complete. + // This is the best query to do it in, and we're not returning early so might as well do it here. + AddGameRuleDefinitions((uid, antag), pool.Count, ref _preSpawnRules, ref _postSpawnRules, GameTicker.IsGameRuleActive(uid, rule)); + antag.PreSelectionsComplete = true; } - RobustRandom.Shuffle(rules); - foreach (var (uid, antag) in rules) + // Pick a random player session and then try to assign the currently available antags from it! + // This means each player has the same chance at rolling antag, with minimal alterations to the odds by number of antags selected. + var weightedPool = GetWeightedPlayerPool(pool); + while (RobustRandom.TryPickAndTake(weightedPool, out var session)) { - if (!RobustRandom.Prob(LateJoinRandomChance)) + // Antag distributed so we remove the session. + if (!PreAssignAntag(session, ref _preSpawnRules)) continue; - if (!antag.Definitions.Any(p => p.LateJoinAdditional)) + args.PlayerPool.Remove(session); + GameTicker.PlayerJoinGame(session); + } + + // Make ghost role spawners for any remaining rules! + SpawnGhostRoles(_preSpawnRules); + _preSpawnRules = null; // Clear the list, we don't want it anymore + } + + private void OnJobsAssigned(RulePlayerJobsAssignedEvent args) + { + if (_postSpawnRules == null) + { + Log.Error($"Error! _postSpawnRules was null when {nameof(RulePlayerJobsAssignedEvent)} was run, this should have been initialized and populated before jobs were assigned."); + return; + } + + // Pick a random player session and then try to assign the currently available antags from it! + // This means each player has the same chance at rolling antag, with minimal alterations to the odds by number of antags selected. + var weightedPool = GetWeightedPlayerPool(args.Players); + while (RobustRandom.TryPickAndTake(weightedPool, out var session)) + { + AssignAntag(session, ref _postSpawnRules); + } + + // Make ghost role spawners for any remaining rules! + SpawnGhostRoles(_postSpawnRules); + _postSpawnRules = null; // Clear the list since it's been used up! + + foreach (var antag in _delayedAntags) + { + if (!TryInitializeAntag(antag.gameRule, antag.antag, antag.player)) + Log.Error($"Gamerule {ToPrettyString(antag.gameRule)} failed to spawn {antag.player.Name} as antag {antag.antag.ID} after spawning."); + } + + _delayedAntags.Clear(); + } + + private void OnJobNotAssigned(NoJobsAvailableSpawningEvent args) + { + // If someone fails to spawn in due to there being no jobs, they should be removed from any preselected antags. + // We only care about delayed rules, since if they're active the player should have already been removed via MakeAntag. + var query = QueryDelayedRules(); + while (query.MoveNext(out var uid, out _, out var comp, out _)) + { + if (comp.SelectionTime == RuleStarted) continue; - DebugTools.AssertNotEqual(antag.SelectionTime, AntagSelectionTime.PrePlayerSpawn); + Debug.Assert(comp.SelectionTime != Never, $"Player: {args.Player.Name}, was pre selected for an game rule {ToPrettyString(uid)} which does not do pre-selections"); - // do not count players in the lobby for the antag ratio - var players = _playerManager.NetworkedSessions.Count(x => x.AttachedEntity != null); - - if (!TryGetNextAvailableDefinition((uid, antag), out var def, players)) + if (!comp.RemoveUponFailedSpawn) continue; - if (TryMakeAntag((uid, antag), session, def.Value)) + foreach (var antag in comp.Antags) + { + if (!comp.PreSelectedSessions.TryGetValue(antag, out var session)) + break; + session.Remove(args.Player); + } + } + } + + private void AddGameRuleDefinitions(Entity gameRule, + int playerCount, + ref List preSpawnRoles, + ref List postSpawnRoles, + bool active) + { + switch (gameRule.Comp.SelectionTime) + { + case PrePlayerSpawn: + AddGameRuleDefinitions(gameRule, playerCount, ref preSpawnRoles, active); + break; + case JobsAssigned: + AddGameRuleDefinitions(gameRule, playerCount, ref postSpawnRoles, active); + break; + case RuleStarted: + if (active) // Only if the game rule is active to we preselect, since the event for activation already ran and was skipped. + AddGameRuleDefinitions(gameRule, playerCount, ref postSpawnRoles, active); + break; + case Never: + SpawnGhostRoles(gameRule, playerCount, true); break; } } - protected override void Added(EntityUid uid, AntagSelectionComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args) + private void AddGameRuleDefinitions(Entity gameRule, + int playerCount, + ref List roles, + bool active) { - base.Added(uid, component, gameRule, args); + var runningCount = 0; - for (var i = 0; i < component.Definitions.Count; i++) + foreach (var antag in gameRule.Comp.Antags) { - var def = component.Definitions[i]; + if (!Proto.Resolve(antag.Proto, out var proto)) + continue; - if (def.MinRange != null) - { - def.Min = def.MinRange.Value.Next(RobustRandom); - } - - if (def.MaxRange != null) - { - def.Max = def.MaxRange.Value.Next(RobustRandom); - } + // We do it this way in case our resolve fails. + roles.Add((gameRule, proto, active, GetTargetAntagCount(antag, playerCount, ref runningCount))); } } - protected override void Started(EntityUid uid, AntagSelectionComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args) + private AntagCount[] GetAntags(Entity gameRule, + int playerCount) { - base.Started(uid, component, gameRule, args); + var runningCount = 0; + var antags = new AntagCount[gameRule.Comp.Antags.Length]; - // If the round has not yet started, we defer antag selection until roundstart - if (GameTicker.RunLevel != GameRunLevel.InRound) - return; + // We assume that antag definitions are prioritized by order, and take up slots that other roles may take. + // I.E for Nukies, it selects 1 commander which takes up 10 players, then one corpsman which takes up another 10, then we select X nukies based on the remaining player count. + // This is how the system worked when I got here, and I decided not to change it to avoid fucking with team antag balance + var i = 0; + foreach (var antag in gameRule.Comp.Antags) + { + if (!Proto.Resolve(antag.Proto, out var definition)) + continue; - if (component.AssignmentComplete) - return; + // We do it this way in case our resolve fails. + antags[i] = (definition, GetTargetAntagCount(antag, playerCount, ref runningCount)); + i++; + } - var players = _playerManager.Sessions - .Where(x => GameTicker.PlayerGameStatuses.TryGetValue(x.UserId, out var status) && - status == PlayerGameStatus.JoinedGame) - .ToList(); + return antags; + } - ChooseAntags((uid, component), players, midround: true); - AssignPreSelectedSessions((uid, component)); + private Dictionary GetWeightedPlayerPool(IEnumerable players) + { + var dict = new Dictionary(); + foreach (var player in players) + { + dict.Add(player, GetWeight(player)); + } + + return dict; + } + + private float GetWeight(ICommonSession player) + { + // TODO: Actually add weights! This is placeholder for a future PR. + return 1f; + } + + private void AssignAntags(Entity gameRule) + { + AssignAntags(gameRule, GetActivePlayers().ToArray()); + } + + private void AssignAntags(Entity gameRule, IList players) + { + var antags = GetAntags(gameRule, players.Count); + AssignAntags(gameRule, players, antags); + gameRule.Comp.PreSelectionsComplete = true; + } + + private void AssignAntags(Entity gameRule, IList players, AntagCount[] antags) + { + AssignAntags(gameRule, GetWeightedPlayerPool(players), antags); + } + + private void AssignAntags(Entity gameRule, Dictionary weightedPool, AntagCount[] antags) + { + while (RobustRandom.TryPickAndTake(weightedPool, out var session)) + { + AssignAntag(gameRule, session, ref antags); + + // Assignment complete, return early. + if (antags.Length == 0) + return; + } + + // We didn't assign all antags, so we try and make ghost roles for the remaining antags! + SpawnGhostRoles(gameRule, antags); } /// - /// Chooses antagonists from the given selection of players + /// Selects and assigns antags from a list, this is called before the game has started. + /// Is private because it has it should only ever be run in very specific scenarios. /// - /// The antagonist rule entity - /// The players to choose from - /// Disable picking players for pre-spawn antags in the middle of a round - public void ChooseAntags(Entity ent, IList pool, bool midround = false) + private bool PreAssignAntag(ICommonSession player, ref List antags) { - foreach (var def in ent.Comp.Definitions) + // If this session cannot be an antag, then get the next session! + if (!TryGetValidAntagPreferences(player, out var prefs)) + return false; + + for (var i = antags.Count - 1; i >= 0; i--) { - ChooseAntags(ent, pool, def, midround: midround); - } + var antag = antags[i]; - ent.Comp.PreSelectionsComplete = true; - } - - /// - /// Chooses antagonists from the given selection of players for the given antag definition. - /// - /// The antagonist rule entity - /// The players to choose from - /// The antagonist selection parameters and criteria - /// Disable picking players for pre-spawn antags in the middle of a round - public void ChooseAntags(Entity ent, - IList pool, - AntagSelectionDefinition def, - bool midround = false) - { - var playerPool = GetPlayerPool(ent, pool, def); - var existingAntagCount = ent.Comp.PreSelectedSessions.TryGetValue(def, out var existingAntags) ? existingAntags.Count : 0; - var count = GetTargetAntagCount(ent, GetTotalPlayerCount(pool), def) - existingAntagCount; - - // if there is both a spawner and players getting picked, let it fall back to a spawner. - var noSpawner = def.SpawnerPrototype == null; - var picking = def.PickPlayer; - if (midround && ent.Comp.SelectionTime == AntagSelectionTime.PrePlayerSpawn) - { - // prevent antag selection from happening if the round is on-going, requiring a spawner if used midround. - // this is so rules like nukies, if added by an admin midround, dont make random living people nukies - Log.Info($"Antags for rule {ent:?} get picked pre-spawn so only spawners will be made."); - DebugTools.Assert(def.SpawnerPrototype != null, $"Rule {ent:?} had no spawner for pre-spawn rule added mid-round!"); - picking = false; - } - - for (var i = 0; i < count; i++) - { - var session = (ICommonSession?)null; - if (picking) + // Skip definitions that don't want a player assigned to them. + if (!antag.Definition.PickPlayer) { - if (!playerPool.TryPickAndTake(RobustRandom, out session) && noSpawner) - { - Log.Warning($"Couldn't pick a player for {ToPrettyString(ent):rule}, no longer choosing antags for this definition"); - break; - } - - if (session != null && ent.Comp.PreSelectedSessions.Values.Any(x => x.Contains(session))) - { - Log.Warning($"Somehow picked {session} for an antag when this rule already selected them previously"); - continue; - } + Debug.Assert(antag.Definition.SpawnerPrototype != null, + $"Antag prototype {antag.Definition.ID} was set to not pre-select, but it also had no ghost spawner to spawn."); + continue; } - if (session == null) - MakeAntag(ent, null, def); // This is for spawner antags + if (!PrefsContain(prefs, antag.Definition.PrefRoles)) + continue; + + // We break it up like this to not log the server trying to make sessions without valid antag prefs into antags. + if (!CanBeAntag(player, antag.GameRule, antag.Definition, false)) + continue; + + // Pre-select the session then deprecate the selection count. + PreSelectSession(antag.GameRule, antag.Definition, player); + + // Reduce the slots left by one + // If we finish assigning all slots + antag.Count--; + if (antag.Count == 0) + antags.RemoveSwap(i); else + antags[i] = antag; + + if (!antag.Active) + return false; + + // Try to assign them an entity if the game rule allows it. + // We don't deselect fails since we may have to wait until the player has spawned first! + if (TryGetAntagEntity(antag.GameRule, antag.Definition, player, out var antagEnt)) { - if (!ent.Comp.PreSelectedSessions.TryGetValue(def, out var set)) - ent.Comp.PreSelectedSessions.Add(def, set = new HashSet()); - set.Add(session); // Selection done! - Log.Debug($"Pre-selected {session.Name} as antagonist: {ToPrettyString(ent)}"); - _adminLogger.Add(LogType.AntagSelection, $"Pre-selected {session.Name} as antagonist: {ToPrettyString(ent)}"); + InitializeAntag(antag.GameRule, antag.Definition, antagEnt.Value, player); + return true; } + + // If we didn't assign an antag, try again after the player has spawned. + _delayedAntags.Add((antag.GameRule, antag.Definition, player)); + return false; } + + // If we're here, then we didn't assign a single antag! + return false; + } + + /// + /// Selects and assigns antags from a list, this is called before the game has started. + /// Is private because it has it should only ever be run in very specific scenarios. + /// + private bool AssignAntag(ICommonSession player, ref List antags) + { + // If this session cannot be an antag, then get the next session! + if (!TryGetValidAntagPreferences(player, out var prefs)) + return false; + + for (var i = antags.Count - 1; i >= 0; i--) + { + var antag = antags[i]; + + // Skip definitions that don't want a player assigned to them. + if (!antag.Definition.PickPlayer) + { + Debug.Assert(antag.Definition.SpawnerPrototype != null, + $"Antag prototype {antag.Definition.ID} was set to not pre-select, but it also had no ghost spawner to spawn."); + continue; + } + + if (!PrefsContain(prefs, antag.Definition.PrefRoles)) + continue; + + // We break it up like this to not log the server trying to make sessions without valid antag prefs into antags. + if (!CanBeAntag(player, antag, false)) + continue; + + // Try to get a valid antag entity. + if (!TryGetAntagEntity(antag.GameRule, antag.Definition, player, out var antagEnt)) + continue; // Something has gone horribly wrong if this happens, check your error log! + + // Pre-select the sesssion, then initialize the antag! + PreSelectSession(antag.GameRule, antag.Definition, player); + InitializeAntag(antag.GameRule, antag.Definition, antagEnt.Value, player); + + // Reduce the slots left by one + // If we finish assigning all slots + antag.Count--; + if (antag.Count == 0) + antags.RemoveSwap(i); + else + antags[i] = antag; + + return true; + } + + // If we're here, then we didn't assign a single antag! + return false; + } + + /// + /// Selects and assigns antags from a list. + /// Is private because it has it should only ever be run in very specific scenarios. + /// + private bool AssignAntag(Entity gameRule, ICommonSession player, ref AntagCount[] antags) + { + // If this session cannot be an antag, then get the next session! + if (!TryGetValidAntagPreferences(player, out var prefs)) + return false; + + for (var i = antags.Length - 1; i >= 0; i--) + { + var antag = antags[i]; + + // Skip definitions that don't want a player assigned to them. + if (!antag.Definition.PickPlayer) + { + Debug.Assert(antag.Definition.SpawnerPrototype != null, + $"Antag prototype {antag.Definition.ID} was set to not pre-select, but it also had no ghost spawner to spawn."); + continue; + } + + if (!PrefsContain(prefs, antag.Definition.PrefRoles)) + continue; + + // We break it up like this to not log the server trying to make sessions without valid antag prefs into antags. + if (!CanBeAntag(player, gameRule, antag.Definition, false)) + continue; + + // Try to get a valid antag entity. + if (!TryGetAntagEntity(gameRule, antag.Definition, player, out var antagEnt)) + continue; // Something has likely gone horribly wrong if this happens, check your error log! + + // Pre-select the session, then initialize the antag! + PreSelectSession(gameRule, antag.Definition, player); + InitializeAntag(gameRule, antag.Definition, antagEnt.Value, player); + + // Reduce the slots left by one + // If we finish assigning all slots + antag.Count--; + if (antag.Count == 0) + antags.RemoveSwap(i); + else + antags[i] = antag; + + return true; + } + + // If we're here, then we didn't assign a single antag! + return false; + } + + /// + /// Checks all preferences from a session to see if they match any of the valid roles from a list of roles available. + /// + /// Antag preferences, this list *should* be prefiltered for bans hence private method + /// List of roles we are searching for. + /// True if any preferences match roles available. + private bool PrefsContain(List> prefs, List> roles) + { + foreach (var role in roles) + { + if (prefs.Contains(role)) + return true; + } + + return false; + } + + /// + /// Marks a player as being chosen by a game rule for antag. + /// This happens before the antag initializes. + /// A player will only be removed from pre-selection if they fail to initialize as antag later. Which will be logged. + /// + /// Game rule which has chosen this player for antag. + /// Antag prototype this player will become. + /// Player. + private void PreSelectSession(Entity gameRule, ProtoId protoId, ICommonSession player) + { + if (!gameRule.Comp.PreSelectedSessions.TryGetValue(protoId, out var set)) + gameRule.Comp.PreSelectedSessions.Add(protoId, set = new HashSet()); + + // Element already exists, don't need to log it twice, this typically happens when a pre-selected antag is initialized! + if (!set.Add(player)) + return; + + Log.Debug($"Pre-selected {player.Name} as antagonist: {ToPrettyString(gameRule)}, {protoId}"); + _adminLogger.Add(LogType.AntagSelection, $"Pre-selected {player.Name} as antagonist: {ToPrettyString(gameRule)}, {protoId}"); + } + + /// + /// Removes a player from pre-selection, this can occur naturally due to a player disconnecting or dying, or due to errors. + /// This should only be called if a player cannot become antag, don't call this if a player becomes antag, we want that cached still. + /// + /// Game rule which had chosen this player for antag, but failed to make them an antag. + /// Antag prototype this player didn't become. + /// Player. + private void DeSelectSession(Entity gameRule, + ProtoId protoId, + ICommonSession player) + { + if (!gameRule.Comp.PreSelectedSessions.TryGetValue(protoId, out var set)) + { + Log.Error($"Attempted to remove {player.Name} from antag pre-selection, but the rule {protoId} hasn't been pre-selected!"); + return; + } + + DeSelectSession(gameRule, protoId, player, set); + } + + private void DeSelectSession(Entity gameRule, + ProtoId protoId, + ICommonSession player, + HashSet set) + { + if (!set.Remove(player)) + { + Log.Error($"Attempted to remove {player.Name} from antag pre-selection, but they weren't pre-selected in the first place!"); + return; + } + + // Not an error because player could've disconnected or died or something. + Log.Debug($"De-selected {player.Name} as antagonist: {ToPrettyString(gameRule)}, {protoId}"); + _adminLogger.Add(LogType.AntagSelection, $"De-selected {player.Name} as antagonist: {ToPrettyString(gameRule)}, {protoId}"); + } + + /// + /// Attempts to initialize a valid antag entity for a player. + /// Will de-select the player if they fail to initialize. + /// + /// Game rule which is trying to create an antag right now! + /// Antag prototype the player is becoming. + /// Player. + /// True if the player initialized as the selected antag. + private bool TryInitializeAntag(Entity gameRule, + AntagSpecifierPrototype prototype, + ICommonSession player) + { + // Get a valid entity to initialize + if (!TryGetAntagEntity(gameRule, prototype, player, out var antagEnt)) + { + DeSelectSession(gameRule, prototype, player); + return false; + } + + InitializeAntag(gameRule, prototype, antagEnt.Value, player); + return true; + } + + private bool TryGetAntagEntity(Entity gameRule, + AntagSpecifierPrototype prototype, + ICommonSession player, + [NotNullWhen(true)]out EntityUid? antagEnt) + { + antagEnt = GetAntagEntity(gameRule, prototype, player); + return antagEnt != null; + } + + /// + /// Attempts to get an entity to assign antag to for a session. + /// First by raising an event to see if the associated has an entity it wants to spawn, + /// Then falling back to the attached entity for the player's session if the game rule doesn't have a specific entity. + /// Private because it can create an entity, and it needs to be called with + /// + /// Associated game rule entity for our antag + /// Antag prototype we are trying to create + /// Player session we are making into an antag + /// Entity of the antagonist + private EntityUid? GetAntagEntity(Entity gameRule, + AntagSpecifierPrototype prototype, + ICommonSession player) + { + // If there's no valid position for us to be moved to, then just return the entity currently attached to the session. + // We need a position to spawn a new entity so we can't spawn a new entity without a proper position. + // Doesn't throw an error since for some antags this is intended behavior. + if (!TryGetValidSpawnPosition(gameRule, prototype, out var coordinates, player)) + return player.AttachedEntity; + + if (TrySpawnAntagonist(gameRule, prototype, player, coordinates.Value, out var entity)) + return entity; + + if (player.AttachedEntity is not { } uid) + { + Log.Error($"Tried to make {player.UserId} into an antagonist at Map: { coordinates.Value.MapId } ({ coordinates.Value.X }, { coordinates.Value.Y }) but was unable to find an entity for them. Gamerule {ToPrettyString(gameRule)}. Antag {prototype.ID}"); + return null; + } + + // Move our entity to the new coordinates we found! + var xform = Transform(uid); + _transform.SetMapCoordinates((uid, xform), coordinates.Value); + return uid; + } + + /// + /// Attempts to create a new antagonist entity at the specified coordinates and attach a player session to it. + /// If it cannot spawn an antagonist entity, it does nothing. + /// + private bool TrySpawnAntagonist(Entity gameRule, + AntagSpecifierPrototype prototype, + ICommonSession player, + MapCoordinates coordinates, + [NotNullWhen(true)]out EntityUid? uid) + { + var ev = new AntagSelectEntityEvent(gameRule, prototype, coordinates, player); + RaiseLocalEvent(gameRule, ref ev, true); + + uid = ev.Entity; + return ev.Handled; } /// /// Assigns antag roles to sessions selected for it. /// - public void AssignPreSelectedSessions(Entity ent) + private void AssignPreSelectedSessions(Entity gameRule) { - // Only assign if there's been a pre-selection, and the selection hasn't already been made - if (!ent.Comp.PreSelectionsComplete || ent.Comp.AssignmentComplete) - return; - - foreach (var def in ent.Comp.Definitions) + foreach (var (proto, set) in gameRule.Comp.PreSelectedSessions) { - if (!ent.Comp.PreSelectedSessions.TryGetValue(def, out var set)) + // How did we even get here? + if (!Proto.Resolve(proto, out var def)) continue; foreach (var session in set) { - TryMakeAntag(ent, session, def); - } - } + _adminLogger.Add(LogType.AntagSelection, $"Start trying to make {session} become the antagonist: {ToPrettyString(gameRule)}, {proto}"); - ent.Comp.AssignmentComplete = true; - } - - /// - /// Tries to makes a given player into the specified antagonist. - /// - public bool TryMakeAntag(Entity ent, ICommonSession? session, AntagSelectionDefinition def, bool ignoreSpawner = false, bool checkPref = true, bool onlyPreSelect = false) - { - _adminLogger.Add(LogType.AntagSelection, $"Start trying to make {session} become the antagonist: {ToPrettyString(ent)}"); - - if (checkPref && !ValidAntagPreference(session, def.PrefRoles)) - return false; - - if (!IsSessionValid(ent, session, def) || !IsEntityValid(session?.AttachedEntity, def)) - return false; - - if (onlyPreSelect && session != null) - { - if (!ent.Comp.PreSelectedSessions.TryGetValue(def, out var set)) - ent.Comp.PreSelectedSessions.Add(def, set = new HashSet()); - set.Add(session); - Log.Debug($"Pre-selected {session!.Name} as antagonist: {ToPrettyString(ent)}"); - _adminLogger.Add(LogType.AntagSelection, $"Pre-selected {session.Name} as antagonist: {ToPrettyString(ent)}"); - } - else - { - MakeAntag(ent, session, def, ignoreSpawner); - } - - return true; - } - - /// - /// Makes a given player into the specified antagonist. - /// - public void MakeAntag(Entity ent, ICommonSession? session, AntagSelectionDefinition def, bool ignoreSpawner = false) - { - EntityUid? antagEnt = null; - var isSpawner = false; - - if (session != null) - { - if (!ent.Comp.PreSelectedSessions.TryGetValue(def, out var set)) - ent.Comp.PreSelectedSessions.Add(def, set = new HashSet()); - set.Add(session); - ent.Comp.AssignedSessions.Add(session); - - // we shouldn't be blocking the entity if they're just a ghost or smth. - if (!HasComp(session.AttachedEntity)) - antagEnt = session.AttachedEntity; - } - else if (!ignoreSpawner && def.SpawnerPrototype != null) // don't add spawners if we have a player, dummy. - { - antagEnt = Spawn(def.SpawnerPrototype); - isSpawner = true; - } - - if (!antagEnt.HasValue) - { - var getEntEv = new AntagSelectEntityEvent(session, ent, def.PrefRoles); - - RaiseLocalEvent(ent, ref getEntEv, true); - antagEnt = getEntEv.Entity; - } - - if (antagEnt is not { } player) - { - Log.Error($"Attempted to make {session} antagonist in gamerule {ToPrettyString(ent)} but there was no valid entity for player."); - _adminLogger.Add(LogType.AntagSelection, $"Attempted to make {session} antagonist in gamerule {ToPrettyString(ent)} but there was no valid entity for player."); - if (session != null && ent.Comp.RemoveUponFailedSpawn) - { - ent.Comp.AssignedSessions.Remove(session); - ent.Comp.PreSelectedSessions[def].Remove(session); - } - - return; - } - - // TODO: This is really messy because this part runs twice for midround events. - // Once when the ghostrole spawner is created and once when a player takes it. - // Therefore any component subscribing to this has to make sure both subscriptions return the same value - // or the ghost role raffle location preview will be wrong. - - var getPosEv = new AntagSelectLocationEvent(session, ent, player); - RaiseLocalEvent(ent, ref getPosEv, true); - if (getPosEv.Handled) - { - var playerXform = Transform(player); - var pos = RobustRandom.Pick(getPosEv.Coordinates); - _transform.SetMapCoordinates((player, playerXform), pos); - } - - // If we want to just do a ghost role spawner, set up data here and then return early. - // This could probably be an event in the future if we want to be more refined about it. - if (isSpawner) - { - if (!TryComp(player, out var spawnerComp)) - { - Log.Error($"Antag spawner {player} does not have a GhostRoleAntagSpawnerComponent."); - _adminLogger.Add(LogType.AntagSelection, $"Antag spawner {player} in gamerule {ToPrettyString(ent)} failed due to not having GhostRoleAntagSpawnerComponent."); - if (session != null) + if (!IsSessionValid(session, gameRule, def)) { - ent.Comp.AssignedSessions.Remove(session); - ent.Comp.PreSelectedSessions[def].Remove(session); + DeSelectSession(gameRule, proto, session, set); + continue; } - return; + TryInitializeAntag(gameRule, def, session); } - - spawnerComp.Rule = ent; - spawnerComp.Definition = def; - return; } + gameRule.Comp.AssignmentHandled = true; + } + + /// + /// Raises an event to the gamerule to check all valid possible spawning points for this rule. + /// Returns a random spawnpoint from a list of valid spawnpoints, or null if there weren't any. + /// + private bool TryGetValidSpawnPosition(Entity ent, AntagSpecifierPrototype antag, [NotNullWhen(true)] out MapCoordinates? coordinates, ICommonSession? session = null) + { + coordinates = GetValidSpawnPosition(ent, antag, session); + return coordinates != null; + } + + /// + /// Raises an event to the gamerule to check all valid possible spawning points for this rule. + /// Returns a random spawnpoint from a list of valid spawnpoints, or null if there weren't any. + /// + private MapCoordinates? GetValidSpawnPosition(Entity ent, AntagSpecifierPrototype antag, ICommonSession? session = null) + { + var getPosEv = new AntagSelectLocationEvent(ent, antag, session); + RaiseLocalEvent(ent, ref getPosEv, true); + + if (!getPosEv.Handled) + return null; + + return RobustRandom.Pick(getPosEv.Coordinates); + } + + /// + /// Initializes the antagonist status on the specified entity. + /// Adds the needed components, loadouts, items, attaches the player and fires off an event. + /// + private void InitializeAntag(Entity gameRule, AntagSpecifierPrototype prototype, EntityUid antag, ICommonSession player) + { + // Make sure player was properly pre-selected. + Debug.Assert(gameRule.Comp.PreSelectedSessions.TryGetValue(prototype.ID, out var value) && value.Contains(player), + $"Game rule {ToPrettyString(gameRule)}, failed to pre-assign {player.Name} to antag {prototype.ID}"); + // The following is where we apply components, equipment, and other changes to our antagonist entity. - EntityManager.AddComponents(player, def.Components); + EntityManager.AddComponents(antag, prototype.Components); // Equip the entity's RoleLoadout and LoadoutGroup List> gear = new(); - if (def.StartingGear is not null) - gear.Add(def.StartingGear.Value); + if (prototype.StartingGear is not null) + gear.Add(prototype.StartingGear.Value); - _loadout.Equip(player, gear, def.RoleLoadout); + _loadout.Equip(antag, gear, prototype.RoleLoadout); - if (session != null) - { - var curMind = session.GetMind(); + // Ensure that we have a mind for our entity! + if (player.GetMind() is not { } mind + || !TryComp(mind, out var mindComp) + || mindComp.OwnedEntity != antag) + mind = _mind.CreateMind(player.UserId, Name(antag)); - if (curMind == null || - !TryComp(curMind.Value, out var mindComp) || - mindComp.OwnedEntity != antagEnt) - { - curMind = _mind.CreateMind(session.UserId, Name(antagEnt.Value)); - _mind.SetUserId(curMind.Value, session.UserId); - } + _mind.TransferTo(mind, antag, ghostCheckOverride: true); + _role.MindAddRoles(mind, prototype.MindRoles, silent: true); + AssignMind(gameRule, prototype, mind, antag); - _mind.TransferTo(curMind.Value, antagEnt, ghostCheckOverride: true); - _role.MindAddRoles(curMind.Value, def.MindRoles, null, true); - ent.Comp.AssignedMinds.Add((curMind.Value, Name(player))); - SendBriefing(session, def.Briefing); + Log.Debug($"Assigned {ToPrettyString(antag):target}, mind {ToPrettyString(mind):target} as antagonist: {ToPrettyString(gameRule):user}"); + _adminLogger.Add(LogType.AntagSelection, $"Assigned {ToPrettyString(antag):target}, mind {ToPrettyString(mind):target} as antagonist: {ToPrettyString(gameRule):user}"); - Log.Debug($"Assigned {ToPrettyString(curMind)} as antagonist: {ToPrettyString(ent)}"); - _adminLogger.Add(LogType.AntagSelection, $"Assigned {ToPrettyString(curMind)} as antagonist: {ToPrettyString(ent)}"); - } + SendBriefing(player, prototype.Briefing); - var afterEv = new AfterAntagEntitySelectedEvent(session, player, ent, def); - RaiseLocalEvent(ent, ref afterEv, true); + var afterEv = new AfterAntagEntitySelectedEvent(player, antag, gameRule, prototype); + RaiseLocalEvent(gameRule, ref afterEv, true); } - /// - /// Gets an ordered player pool based on player preferences and the antagonist definition. - /// - public AntagSelectionPlayerPool GetPlayerPool(Entity ent, IList sessions, AntagSelectionDefinition def) + private void AssignMind(Entity gameRule, ProtoId proto, EntityUid mind, EntityUid antag) { - var preferredList = new List(); - var fallbackList = new List(); - foreach (var session in sessions) + if (gameRule.Comp.AssignedMinds.TryGetValue(proto, out var minds)) { - if (!IsSessionValid(ent, session, def) || !IsEntityValid(session.AttachedEntity, def)) - continue; - - if (ent.Comp.PreSelectedSessions.TryGetValue(def, out var preSelected) && preSelected.Contains(session)) - continue; - - // Add player to the appropriate antag pool - if (ValidAntagPreference(session, def.PrefRoles)) - { - preferredList.Add(session); - } - else if (ValidAntagPreference(session, def.FallbackRoles)) - { - fallbackList.Add(session); - } + minds.Add((mind, Name(antag))); } - - return new AntagSelectionPlayerPool(new() { preferredList, fallbackList }); - } - - /// - /// Checks if a given session is valid for an antagonist. - /// - public bool IsSessionValid(Entity ent, ICommonSession? session, AntagSelectionDefinition def, EntityUid? mind = null) - { - // TODO ROLE TIMERS - // Check if antag role requirements are met - - if (session == null) - return true; - - if (session.Status is SessionStatus.Disconnected or SessionStatus.Zombie) - return false; - - if (ent.Comp.AssignedSessions.Contains(session)) - return false; - - mind ??= session.GetMind(); - - //todo: we need some way to check that we're not getting the same role twice. (double picking thieves or zombies through midrounds) - - switch (def.MultiAntagSetting) + else { - case AntagAcceptability.None: - { - if (_role.MindIsAntagonist(mind)) - return false; - if (GetPreSelectedAntagSessions(def).Contains(session)) // Used for rules where the antag has been selected, but not started yet - return false; - break; - } - case AntagAcceptability.NotExclusive: - { - if (_role.MindIsExclusiveAntagonist(mind)) - return false; - if (GetPreSelectedExclusiveAntagSessions(def).Contains(session)) - return false; - break; - } + var hashset = new HashSet<(EntityUid, string)>(); + hashset.Add((mind, Name(antag))); + gameRule.Comp.AssignedMinds.Add(proto, hashset); } - - // todo: expand this to allow for more fine antag-selection logic for game rules. - if (!_jobs.CanBeAntag(session)) - return false; - - return true; - } - - /// - /// Checks if a given entity (mind/session not included) is valid for a given antagonist. - /// - public bool IsEntityValid(EntityUid? entity, AntagSelectionDefinition def) - { - // If the player has not spawned in as any entity (e.g., in the lobby), they can be given an antag role/entity. - if (entity == null) - return true; - - if (_arrivals.IsOnArrivals((entity.Value, null))) - return false; - - if (!def.AllowNonHumans && !HasComp(entity)) - return false; - - if (def.Whitelist != null) - { - if (!_whitelist.IsValid(def.Whitelist, entity.Value)) - return false; - } - - if (def.Blacklist != null) - { - if (_whitelist.IsValid(def.Blacklist, entity.Value)) - return false; - } - - return true; } private void OnObjectivesTextGetInfo(Entity ent, ref ObjectivesTextGetInfoEvent args) @@ -608,7 +804,7 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem [ByRefEvent] -public record struct AntagSelectEntityEvent(ICommonSession? Session, Entity GameRule, List> AntagRoles) +public record struct AntagSelectEntityEvent(Entity GameRule, AntagSpecifierPrototype Antag, MapCoordinates Coords, ICommonSession? Session) { public readonly ICommonSession? Session = Session; /// list of antag role prototypes associated with a entity. used by the - public readonly List> AntagRoles = AntagRoles; + public readonly AntagSpecifierPrototype Antag = Antag; + + public readonly MapCoordinates Coords = Coords; public bool Handled => Entity != null; @@ -632,23 +830,69 @@ public record struct AntagSelectEntityEvent(ICommonSession? Session, Entity /// Event raised on a game rule entity to determine the location for the antagonist. +/// Methods responding to this event should not be making any changed as future methods can fail causing an antag to not spawn. /// [ByRefEvent] -public record struct AntagSelectLocationEvent(ICommonSession? Session, Entity GameRule, EntityUid Entity) +public record struct AntagSelectLocationEvent(Entity GameRule, AntagSpecifierPrototype Antag, ICommonSession? Session = null) { public readonly ICommonSession? Session = Session; public bool Handled => Coordinates.Any(); // the entity of the antagonist - public EntityUid Entity = Entity; + public AntagSpecifierPrototype Antag = Antag; public List Coordinates = new(); } /// -/// Event raised on a game rule entity after the setup logic for an antag is complete. +/// Event raised on a game ruleR entity after the setup logic for an antag is complete. /// Used for applying additional more complex setup logic. /// [ByRefEvent] -public readonly record struct AfterAntagEntitySelectedEvent(ICommonSession? Session, EntityUid EntityUid, Entity GameRule, AntagSelectionDefinition Def); +public readonly record struct AfterAntagEntitySelectedEvent(ICommonSession? Session, EntityUid EntityUid, Entity GameRule, AntagSpecifierPrototype Def); + +/// +/// A given antag definition provided by a game rule. +/// This struct is created to store data for ticketing multiple antags out at once, typically for multiple gamerules, and then is destroyed when reaches 0. +/// +/// The game rule which has the specified antag. +/// The specified antag. +/// Whether or not this game rule is currently active, cached to avoid needless HasComps. +/// The number of specified antags left to ticket. This value does change as antags are assigned. +public record struct AntagRule(Entity GameRule, AntagSpecifierPrototype Definition, bool Active, int Count) +{ + public static implicit operator AntagRule((Entity GameRule, AntagSpecifierPrototype Defintion, bool active) quad) + { + return new AntagRule(quad.GameRule, quad.Defintion, quad.active, 1); + } + + public static implicit operator AntagRule((Entity GameRule, AntagSpecifierPrototype Defintion, bool active, int Count) quad) + { + return new AntagRule(quad.GameRule, quad.Defintion, quad.active, quad.Count); + } +} + +/// +/// A simple struct that stores an antag definition and the number of remaining slots available. +/// Typically, is paired with a or else it's worthless. +/// +/// The antag definition we have a count of +/// The number of slots remaining for this antag +public record struct AntagCount(AntagSpecifierPrototype Definition, int Count) +{ + /// + /// Remaining number of slots for this antag. + /// + public int Count = Count; + + public static implicit operator AntagCount(AntagSpecifierPrototype definition) + { + return new AntagCount(definition, 1); + } + + public static implicit operator AntagCount((AntagSpecifierPrototype Defintion, int Count) tuple) + { + return new AntagCount(tuple.Defintion, tuple.Count); + } +} diff --git a/Content.Server/Antag/Components/AntagMultipleRoleSpawnerComponent.cs b/Content.Server/Antag/Components/AntagMultipleRoleSpawnerComponent.cs index 5a9103a82a..f375dd6dc3 100644 --- a/Content.Server/Antag/Components/AntagMultipleRoleSpawnerComponent.cs +++ b/Content.Server/Antag/Components/AntagMultipleRoleSpawnerComponent.cs @@ -1,3 +1,4 @@ +using Content.Shared.Antag; using Content.Shared.Roles; using Robust.Shared.Prototypes; @@ -13,7 +14,7 @@ public sealed partial class AntagMultipleRoleSpawnerComponent : Component /// antag prototype -> list of possible entities to spawn for that antag prototype. Will choose from the list randomly once with replacement unless is set to true /// [DataField] - public Dictionary, List> AntagRoleToPrototypes; + public Dictionary, List> AntagRoleToPrototypes; /// /// Should you remove ent prototypes from the list after spawning one. diff --git a/Content.Server/Antag/Components/AntagSelectionComponent.cs b/Content.Server/Antag/Components/AntagSelectionComponent.cs index 71bc564c73..de26f81843 100644 --- a/Content.Server/Antag/Components/AntagSelectionComponent.cs +++ b/Content.Server/Antag/Components/AntagSelectionComponent.cs @@ -1,10 +1,8 @@ using Content.Server.Administration.Systems; +using Content.Server.Antag.Selectors; +using Content.Server.GameTicking; using Content.Shared.Antag; -using Content.Shared.Destructible.Thresholds; -using Content.Shared.Preferences.Loadouts; -using Content.Shared.Roles; -using Content.Shared.Whitelist; -using Robust.Shared.Audio; +using Content.Shared.GameTicking.Components; using Robust.Shared.Player; using Robust.Shared.Prototypes; @@ -14,10 +12,12 @@ namespace Content.Server.Antag.Components; public sealed partial class AntagSelectionComponent : Component { /// - /// Has the primary assignment of antagonists finished yet? + /// Has the primary assignment of antagonists been handled yet? + /// This is typically set to true at the start of antag assignment for a game rule. + /// Note that this can be true even before all antags have been assigned. /// [DataField] - public bool AssignmentComplete; + public bool AssignmentHandled; /// /// Has the antagonists been preselected but yet to be fully assigned? @@ -26,34 +26,35 @@ public sealed partial class AntagSelectionComponent : Component public bool PreSelectionsComplete; /// - /// The definitions for the antagonists + /// If true, players that late join into a round have a chance of being converted into antagonists for this game rule. /// [DataField] - public List Definitions = new(); + public bool LateJoinAdditional; /// - /// The minds and original names of the players assigned to be antagonists. + /// The antag specifiers for the antagonists + /// + [DataField(required: true)] + public AntagCountSelector[] Antags; + + /// + /// Cached sessions of antag definitions and selected players. + /// Players in this dict are not guaranteed to have been assigned the role yet, and may be removed if they fail to initialize as an antag. /// [DataField] - public List<(EntityUid, string)> AssignedMinds = new(); + public Dictionary, HashSet> PreSelectedSessions = new(); + + /// + /// The minds and original names of the players assigned to be antagonists, as well as their assigned antag. + /// + [DataField] + public Dictionary, HashSet<(EntityUid uid, string name)>> AssignedMinds = new(); /// /// When the antag selection will occur. /// [DataField] - public AntagSelectionTime SelectionTime = AntagSelectionTime.PostPlayerSpawn; - - /// - /// Cached sessions of antag definitions and selected players. Players in this dict are not guaranteed to have been assigned the role yet. - /// - [DataField] - public Dictionary>PreSelectedSessions = new(); - - /// - /// Cached sessions of players who are chosen. Used so we don't have to rebuild the pool multiple times in a tick. - /// Is not serialized. - /// - public HashSet AssignedSessions = new(); + public AntagSelectionTime SelectionTime = AntagSelectionTime.RuleStarted; /// /// Locale id for the name of the antag. @@ -70,160 +71,32 @@ public sealed partial class AntagSelectionComponent : Component public bool RemoveUponFailedSpawn = true; } -[DataDefinition] -public partial struct AntagSelectionDefinition() +/// +/// Regardless of this value, antags are only initialized after the game rule activates. +/// If a game rule does not have a delayed activation, the antag will be initialized at the same time as this enum. +/// Otherwise, it will not be initialized until the game rule becomes active. +/// +public enum AntagSelectionTime : byte { /// - /// A list of antagonist roles that are used for selecting which players will be antagonists. + /// Antag roles are selected at /// - [DataField] - public List> PrefRoles = new(); + PrePlayerSpawn, /// - /// Fallback for . Useful if you need multiple role preferences for a team antagonist. + /// Antag roles are selected at /// - [DataField] - public List> FallbackRoles = new(); + JobsAssigned, /// - /// Should we allow people who already have an antagonist role? + /// Antag roles are selected at + /// or if the game rule was started before spawning. + /// This is the latest an antag can be selected. /// - [DataField] - public AntagAcceptability MultiAntagSetting = AntagAcceptability.None; + RuleStarted, /// - /// The minimum number of this antag. + /// Antag roles are *never* selected. Instead, this definition only makes ghost roles. /// - [DataField] - public int Min = 1; - - /// - /// The maximum number of this antag. - /// - [DataField] - public int Max = 1; - - /// - /// A range used to randomly select - /// - [DataField] - public MinMax? MinRange; - - /// - /// A range used to randomly select - /// - [DataField] - public MinMax? MaxRange; - - /// - /// a player to antag ratio: used to determine the amount of antags that will be present. - /// - [DataField] - public int PlayerRatio = 10; - - /// - /// Whether or not players should be picked to inhabit this antag or not. - /// If no players are left and is set, it will make a ghost role. - /// - [DataField] - public bool PickPlayer = true; - - /// - /// If true, players that latejoin into a round have a chance of being converted into antagonists. - /// - [DataField] - public bool LateJoinAdditional = false; - - //todo: find out how to do this with minimal boilerplate: filler department, maybe? - //public HashSet> JobBlacklist = new() - - /// - /// Mostly just here for legacy compatibility and reducing boilerplate - /// - [DataField] - public bool AllowNonHumans = false; - - /// - /// A whitelist for selecting which players can become this antag. - /// - [DataField] - public EntityWhitelist? Whitelist; - - /// - /// A blacklist for selecting which players can become this antag. - /// - [DataField] - public EntityWhitelist? Blacklist; - - /// - /// Components added to the player. - /// - [DataField] - public ComponentRegistry Components = new(); - - /// - /// Components added to the player's mind. - /// Do NOT use this to add role-type components. Add those as MindRoles instead - /// - [DataField] - public ComponentRegistry MindComponents = new(); - - /// - /// List of Mind Role Prototypes to be added to the player's mind. - /// - [DataField] - public List? MindRoles; - - /// - /// A set of starting gear that's equipped to the player. - /// - [DataField] - public ProtoId? StartingGear; - - /// - /// A list of role loadouts, from which a randomly selected one will be equipped. - /// - [DataField] - public List>? RoleLoadout; - - /// - /// A briefing shown to the player. - /// - [DataField] - public BriefingData? Briefing; - - /// - /// A spawner used to defer the selection of this particular definition. - /// - /// - /// Not the cleanest way of doing this code but it's just an odd specific behavior. - /// Sue me. - /// - [DataField] - public EntProtoId? SpawnerPrototype; -} - -/// -/// Contains data used to generate a briefing. -/// -[DataDefinition] -public partial struct BriefingData -{ - /// - /// The text shown - /// - [DataField] - public LocId? Text; - - /// - /// The color of the text. - /// - [DataField] - public Color? Color; - - /// - /// The sound played. - /// - [DataField] - public SoundSpecifier? Sound; + Never, } diff --git a/Content.Server/Antag/Components/GhostRoleAntagSpawnerComponent.cs b/Content.Server/Antag/Components/GhostRoleAntagSpawnerComponent.cs index fcaa4d4267..0c563f3c40 100644 --- a/Content.Server/Antag/Components/GhostRoleAntagSpawnerComponent.cs +++ b/Content.Server/Antag/Components/GhostRoleAntagSpawnerComponent.cs @@ -1,7 +1,10 @@ +using Content.Shared.Antag; +using Robust.Shared.Prototypes; + namespace Content.Server.Antag.Components; /// -/// Ghost role spawner that creates an antag for the associated gamerule. +/// Ghost role spawner that creates an antag for the associated game rule. /// [RegisterComponent, Access(typeof(AntagSelectionSystem))] public sealed partial class GhostRoleAntagSpawnerComponent : Component @@ -10,5 +13,5 @@ public sealed partial class GhostRoleAntagSpawnerComponent : Component public EntityUid? Rule; [DataField] - public AntagSelectionDefinition? Definition; + public ProtoId? Definition; } diff --git a/Content.Server/Antag/Selectors/AntagCountSelector.cs b/Content.Server/Antag/Selectors/AntagCountSelector.cs new file mode 100644 index 0000000000..3f02581385 --- /dev/null +++ b/Content.Server/Antag/Selectors/AntagCountSelector.cs @@ -0,0 +1,39 @@ +using Content.Shared.Antag; +using Content.Shared.Destructible.Thresholds; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; + +namespace Content.Server.Antag.Selectors; + +/// +/// An abstract class meant to return the amount of antags to spawn. +/// +[ImplicitDataDefinitionForInheritors] +public abstract partial class AntagCountSelector +{ + /// + /// How many players does this antag count as? + /// Each antag spawned by a game rule "takes" a select group of players from the pool. + /// + [DataField] + public int PlayerRatio = 10; + + [DataField(required: true)] + public ProtoId Proto; + + public abstract int GetTargetAntagCount(IRobustRandom random, int playerCount); + + public static implicit operator ProtoId(AntagCountSelector selector) + { + return selector.Proto; + } +} + +/// +/// An abstract version of which constrains the amount of antags spawned to a minimum and maximum. +/// +public abstract partial class MinMaxAntagCountSelector : AntagCountSelector +{ + [DataField(required: true)] + public MinMax Range; +} diff --git a/Content.Server/Antag/Selectors/FixedAntagCount.cs b/Content.Server/Antag/Selectors/FixedAntagCount.cs new file mode 100644 index 0000000000..17b4dc30d0 --- /dev/null +++ b/Content.Server/Antag/Selectors/FixedAntagCount.cs @@ -0,0 +1,18 @@ +using Robust.Shared.Random; + +namespace Content.Server.Antag.Selectors; + +/// +/// Always spawns this many antags. +/// +public sealed partial class FixedAntagCount : AntagCountSelector +{ + [DataField] + public int Count = 1; + + public override int GetTargetAntagCount(IRobustRandom random, int playerCount) + { + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(Count); + return Count; + } +} diff --git a/Content.Server/Antag/Selectors/LinearAntagCount.cs b/Content.Server/Antag/Selectors/LinearAntagCount.cs new file mode 100644 index 0000000000..c2668f2f0f --- /dev/null +++ b/Content.Server/Antag/Selectors/LinearAntagCount.cs @@ -0,0 +1,14 @@ +using Robust.Shared.Random; + +namespace Content.Server.Antag.Selectors; + +/// +/// Spawns a constrained number of antags that scales linearly. +/// +public sealed partial class LinearAntagCount : MinMaxAntagCountSelector +{ + public override int GetTargetAntagCount(IRobustRandom random, int playerCount) + { + return Math.Clamp(playerCount / PlayerRatio, Range.Min, Range.Max); + } +} diff --git a/Content.Server/GameTicking/GameTicker.GamePreset.cs b/Content.Server/GameTicking/GameTicker.GamePreset.cs index 4634b7820b..d49287e539 100644 --- a/Content.Server/GameTicking/GameTicker.GamePreset.cs +++ b/Content.Server/GameTicking/GameTicker.GamePreset.cs @@ -4,9 +4,11 @@ using System.Threading.Tasks; using Content.Server.GameTicking.Presets; using Content.Server.Maps; using Content.Shared.CCVar; +using Content.Shared.GameTicking.Components; using Content.Shared.Maps; using JetBrains.Annotations; using Robust.Shared.Player; +using Robust.Shared.Prototypes; namespace Content.Server.GameTicking; @@ -14,6 +16,8 @@ public sealed partial class GameTicker { public const float PresetFailedCooldownIncrease = 30f; + public static readonly EntProtoId DummyGameRule = "DummyNonAntag"; + /// /// The selected preset that will be used at the start of the next round. /// @@ -193,16 +197,17 @@ public sealed partial class GameTicker _gameMapManager.SelectMapRandom(); } - [PublicAPI] private bool AddGamePresetRules() { if (DummyTicker || Preset == null) return false; CurrentPreset = Preset; + var ignored = _cfg.GetCVar(CCVars.GameTickerIgnoredPresets).Split(","); foreach (var rule in Preset.Rules) { - AddGameRule(rule); + if (!ignored.Contains(rule)) + AddGameRule(rule); } return true; @@ -227,6 +232,40 @@ public sealed partial class GameTicker } } + /// + [PublicAPI] + public int GetMinimumPlayerCount(ProtoId proto) + { + if (!_prototypeManager.Resolve(proto, out var preset)) + return 0; + + return GetMinimumPlayerCount(preset); + } + + /// + /// Gets the minimum number of players required for a game preset to start. + /// Checks both the preset itself, and all rules to find the minimum. + /// + /// Game preset prototype we're checking. + /// Minimum number of players required for the rule to start. + [PublicAPI] + public int GetMinimumPlayerCount(GamePresetPrototype proto) + { + var min = proto.MinPlayers ?? 0; + foreach (var entProto in proto.Rules) + { + if (!_prototypeManager.Resolve(entProto, out var ent)) + continue; + + if (!ent.TryGetComponent(out var rule, Factory)) + continue; + + min = Math.Max(min, rule.MinPlayers); + } + + return min; + } + private void IncrementRoundNumber() { var playerIds = _playerGameStatuses.Keys.Select(player => player.UserId).ToArray(); diff --git a/Content.Server/GameTicking/GameTicker.GameRule.cs b/Content.Server/GameTicking/GameTicker.GameRule.cs index cf1d6eb1a8..e34a4ca718 100644 --- a/Content.Server/GameTicking/GameTicker.GameRule.cs +++ b/Content.Server/GameTicking/GameTicker.GameRule.cs @@ -10,7 +10,6 @@ using JetBrains.Annotations; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Prototypes; -using Robust.Shared.Localization; namespace Content.Server.GameTicking; @@ -55,6 +54,8 @@ public sealed partial class GameTicker string.Empty, $"listgamerules - {localizedHelp}", ListGameRuleCommand); + + SubscribeLocalEvent(OnStartAttempt); } private void ShutdownGameRules() @@ -386,6 +387,37 @@ public sealed partial class GameTicker } } + private void OnStartAttempt(RoundStartAttemptEvent args) + { + if (args.Forced || args.Cancelled) + return; + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var gameRule)) + { + var minPlayers = gameRule.MinPlayers; + var name = ToPrettyString(uid); + + if (args.Players.Length >= minPlayers) + continue; + + if (gameRule.CancelPresetOnTooFewPlayers) + { + _chatManager.SendAdminAnnouncement(Loc.GetString("preset-not-enough-ready-players", + ("readyPlayersCount", args.Players.Length), + ("minimumPlayers", minPlayers), + ("presetName", name))); + args.Cancel(); + //TODO remove this once announcements are logged + Log.Info($"Rule '{name}' requires {minPlayers} players, but only {args.Players.Length} are ready."); + } + else + { + EndGameRule(uid, gameRule); + } + } + } + #region Command Implementations [AdminCommand(AdminFlags.Fun)] diff --git a/Content.Server/GameTicking/Rules/AntagLoadProfileRuleSystem.cs b/Content.Server/GameTicking/Rules/AntagLoadProfileRuleSystem.cs index 22916f0c18..5e875271e0 100644 --- a/Content.Server/GameTicking/Rules/AntagLoadProfileRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/AntagLoadProfileRuleSystem.cs @@ -13,7 +13,6 @@ namespace Content.Server.GameTicking.Rules; public sealed class AntagLoadProfileRuleSystem : GameRuleSystem { [Dependency] private readonly HumanoidProfileSystem _humanoidProfile = default!; - [Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly IServerPreferencesManager _prefs = default!; [Dependency] private readonly SharedVisualBodySystem _visualBody = default!; @@ -34,18 +33,18 @@ public sealed class AntagLoadProfileRuleSystem : GameRuleSystem(HumanoidCharacterProfile.DefaultSpecies); + species = Proto.Index(HumanoidCharacterProfile.DefaultSpecies); } if (ent.Comp.SpeciesOverride != null && (ent.Comp.SpeciesOverrideBlacklist?.Contains(new ProtoId(species.ID)) ?? false)) { - species = _proto.Index(ent.Comp.SpeciesOverride.Value); + species = Proto.Index(ent.Comp.SpeciesOverride.Value); } - args.Entity = Spawn(species.Prototype); + args.Entity = Spawn(species.Prototype, args.Coords); if (profile?.WithSpecies(species.ID) is { } humanoidProfile) { _visualBody.ApplyProfileTo(args.Entity.Value, humanoidProfile); diff --git a/Content.Server/GameTicking/Rules/GameRuleSystem.cs b/Content.Server/GameTicking/Rules/GameRuleSystem.cs index 6b4240dd7f..ddb95f1a31 100644 --- a/Content.Server/GameTicking/Rules/GameRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/GameRuleSystem.cs @@ -2,6 +2,7 @@ using Content.Server.Atmos.EntitySystems; using Content.Server.Chat.Managers; using Content.Shared.GameTicking.Components; using Robust.Server.GameObjects; +using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -9,86 +10,57 @@ namespace Content.Server.GameTicking.Rules; public abstract partial class GameRuleSystem : EntitySystem where T : IComponent { - [Dependency] protected readonly IRobustRandom RobustRandom = default!; - [Dependency] protected readonly IChatManager ChatManager = default!; - [Dependency] protected readonly GameTicker GameTicker = default!; [Dependency] protected readonly IGameTiming Timing = default!; + [Dependency] protected readonly IPrototypeManager Proto = default!; + [Dependency] protected readonly IRobustRandom RobustRandom = default!; + [Dependency] protected readonly GameTicker GameTicker = default!; // Not protected, just to be used in utility methods [Dependency] private readonly AtmosphereSystem _atmosphere = default!; [Dependency] private readonly MapSystem _map = default!; + [Dependency] protected readonly EntityQuery GameRuleQuery = default!; + [Dependency] protected readonly EntityQuery RuleQuery = default!; + public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnStartAttempt); SubscribeLocalEvent(OnGameRuleAdded); SubscribeLocalEvent(OnGameRuleStarted); SubscribeLocalEvent(OnGameRuleEnded); SubscribeLocalEvent(OnRoundEndTextAppend); } - private void OnStartAttempt(RoundStartAttemptEvent args) - { - if (args.Forced || args.Cancelled) - return; - - var query = QueryAllRules(); - while (query.MoveNext(out var uid, out _, out var gameRule)) - { - var minPlayers = gameRule.MinPlayers; - var name = ToPrettyString(uid); - - if (args.Players.Length >= minPlayers) - continue; - - if (gameRule.CancelPresetOnTooFewPlayers) - { - ChatManager.SendAdminAnnouncement(Loc.GetString("preset-not-enough-ready-players", - ("readyPlayersCount", args.Players.Length), - ("minimumPlayers", minPlayers), - ("presetName", name))); - args.Cancel(); - //TODO remove this once announcements are logged - Log.Info($"Rule '{name}' requires {minPlayers} players, but only {args.Players.Length} are ready."); - } - else - { - ForceEndSelf(uid, gameRule); - } - } - } - private void OnGameRuleAdded(EntityUid uid, T component, ref GameRuleAddedEvent args) { - if (!TryComp(uid, out var ruleData)) + if (!GameRuleQuery.TryComp(uid, out var ruleData)) return; + Added(uid, component, ruleData, args); } private void OnGameRuleStarted(EntityUid uid, T component, ref GameRuleStartedEvent args) { - if (!TryComp(uid, out var ruleData)) + if (!GameRuleQuery.TryComp(uid, out var ruleData)) return; + Started(uid, component, ruleData, args); } private void OnGameRuleEnded(EntityUid uid, T component, ref GameRuleEndedEvent args) { - if (!TryComp(uid, out var ruleData)) + if (!GameRuleQuery.TryComp(uid, out var ruleData)) return; + Ended(uid, component, ruleData, args); } private void OnRoundEndTextAppend(RoundEndTextAppendEvent ev) { - var query = AllEntityQuery(); - while (query.MoveNext(out var uid, out var comp)) + var query = QueryAllRules(); + while (query.MoveNext(out var uid, out var comp, out var ruleData)) { - if (!TryComp(uid, out var ruleData)) - continue; - AppendRoundEndText(uid, comp, ruleData, ref ev); } } diff --git a/Content.Server/GameTicking/Rules/RevolutionaryRuleSystem.cs b/Content.Server/GameTicking/Rules/RevolutionaryRuleSystem.cs index f0cf3087ff..22cfe650d9 100644 --- a/Content.Server/GameTicking/Rules/RevolutionaryRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RevolutionaryRuleSystem.cs @@ -1,3 +1,4 @@ +using System.Linq; using Content.Server.Administration.Logs; using Content.Server.Antag; using Content.Server.EUI; @@ -104,7 +105,7 @@ public sealed class RevolutionaryRuleSystem : GameRuleSystem if (_whitelist.IsWhitelistFail(ent.Comp.SpawnerWhitelist, uid)) continue; - if (TryComp(uid, out var gridSpawnPointWhitelistComponent)) + if (TryComp(uid, out var comp)) { - if (!_whitelist.CheckBoth(args.Entity, gridSpawnPointWhitelistComponent.Blacklist, gridSpawnPointWhitelistComponent.Whitelist)) + if (args.Antag == null || !comp.Whitelist.Contains(args.Antag)) continue; } diff --git a/Content.Server/GameTicking/Rules/SecretRuleSystem.cs b/Content.Server/GameTicking/Rules/SecretRuleSystem.cs index 5e8e599d10..db892aaa7c 100644 --- a/Content.Server/GameTicking/Rules/SecretRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/SecretRuleSystem.cs @@ -153,19 +153,6 @@ public sealed class SecretRuleSystem : GameRuleSystem if (selected == null) return false; - foreach (var ruleId in selected.Rules) - { - if (!_prototypeManager.TryIndex(ruleId, out EntityPrototype? rule) - || !rule.TryGetComponent(_ruleCompName, out GameRuleComponent? ruleComp)) - { - Log.Error($"Encountered invalid rule {ruleId} in preset {selected.ID}"); - return false; - } - - if (ruleComp.MinPlayers > players && ruleComp.CancelPresetOnTooFewPlayers) - return false; - } - - return true; + return players >= GameTicker.GetMinimumPlayerCount(selected); } } diff --git a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs index a15d1d9981..5604d84dca 100644 --- a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs @@ -18,6 +18,7 @@ using Content.Shared.Zombies; using Robust.Shared.Player; using Robust.Shared.Timing; using System.Globalization; +using System.Linq; namespace Content.Server.GameTicking.Rules; @@ -76,7 +77,7 @@ public sealed class ZombieRuleSystem : GameRuleSystem else args.AddLine(Loc.GetString("zombie-round-end-amount-all")); - var antags = _antag.GetAntagIdentifiers(uid); + var antags = _antag.GetAntagIdentifiers(uid).ToList(); args.AddLine(Loc.GetString("zombie-round-end-initial-count", ("initialCount", antags.Count))); foreach (var (_, data, entName) in antags) { diff --git a/Content.Server/Objectives/ObjectivesSystem.cs b/Content.Server/Objectives/ObjectivesSystem.cs index 1b20d65c45..8c973bd7eb 100644 --- a/Content.Server/Objectives/ObjectivesSystem.cs +++ b/Content.Server/Objectives/ObjectivesSystem.cs @@ -11,6 +11,8 @@ using Robust.Shared.Prototypes; using Robust.Shared.Random; using System.Linq; using System.Text; +using Content.Server.Antag; +using Content.Server.Antag.Components; using Content.Server.Objectives.Commands; using Content.Shared.CCVar; using Content.Shared.Prototypes; @@ -23,13 +25,13 @@ namespace Content.Server.Objectives; public sealed class ObjectivesSystem : SharedObjectivesSystem { - [Dependency] private readonly GameTicker _gameTicker = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly AntagSelectionSystem _antag = default!; [Dependency] private readonly EmergencyShuttleSystem _emergencyShuttle = default!; [Dependency] private readonly SharedJobSystem _job = default!; - [Dependency] private readonly IConfigurationManager _cfg = default!; private IEnumerable? _objectives; @@ -60,19 +62,14 @@ public sealed class ObjectivesSystem : SharedObjectivesSystem { // go through each gamerule getting data for the roundend summary. var summaries = new Dictionary>>(); - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var gameRule)) + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out _, out var comp)) { - if (!_gameTicker.IsGameRuleAdded(uid, gameRule)) + if (comp.AgentName is not { } agent) continue; - var info = new ObjectivesTextGetInfoEvent(new List<(EntityUid, string)>(), string.Empty); - RaiseLocalEvent(uid, ref info); - if (info.Minds.Count == 0) - continue; + var minds = _antag.GetAntagIdentities((uid, comp)); - // first group the gamerules by their agents, for example 2 different dragons - var agent = info.AgentName; if (!summaries.ContainsKey(agent)) summaries[agent] = new Dictionary>(); @@ -85,11 +82,11 @@ public sealed class ObjectivesSystem : SharedObjectivesSystem if (summary.ContainsKey(prepend.Text)) { // same prepended text (usually empty) so combine them - summary[prepend.Text].AddRange(info.Minds); + summary[prepend.Text].AddRange(minds); } else { - summary[prepend.Text] = info.Minds; + summary[prepend.Text] = minds.ToList(); } } @@ -102,7 +99,7 @@ public sealed class ObjectivesSystem : SharedObjectivesSystem foreach (var (_, minds) in summary) { total += minds.Count; - totalInCustody += minds.Where(pair => IsInCustody(pair.Item1)).Count(); + totalInCustody += minds.Count(pair => IsInCustody(pair.Item1)); } var result = new StringBuilder(); @@ -258,7 +255,7 @@ public sealed class ObjectivesSystem : SharedObjectivesSystem /// /// Returns whether a target is considered 'in custody' (cuffed on the shuttle). /// - private bool IsInCustody(EntityUid mindId, MindComponent? mind = null) + public bool IsInCustody(EntityUid mindId, MindComponent? mind = null) { if (!Resolve(mindId, ref mind)) return false; diff --git a/Content.Server/Spawners/Components/AntagGridSpawnPointComponent.cs b/Content.Server/Spawners/Components/AntagGridSpawnPointComponent.cs new file mode 100644 index 0000000000..2f817fb023 --- /dev/null +++ b/Content.Server/Spawners/Components/AntagGridSpawnPointComponent.cs @@ -0,0 +1,19 @@ +using Content.Server.GameTicking.Rules; +using Content.Shared.Antag; +using Robust.Shared.Prototypes; + +namespace Content.Server.Spawners.Components; + +/// +/// Defines a list of antag prototypes which can spawn at a given spawn point with +/// There's probably a better way of doing this but there's only so much I can refactor before I drown in soap. +/// +[RegisterComponent] +public sealed partial class AntagGridSpawnPointComponent : Component +{ + /// + /// Whitelist of entities that can be spawned at this SpawnPoint + /// + [DataField] + public HashSet> Whitelist; +} diff --git a/Content.Server/Spawners/Components/GridSpawnPointWhitelistComponent.cs b/Content.Server/Spawners/Components/GridSpawnPointWhitelistComponent.cs deleted file mode 100644 index de9f71f0f8..0000000000 --- a/Content.Server/Spawners/Components/GridSpawnPointWhitelistComponent.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Content.Shared.Whitelist; - -namespace Content.Server.Spawners.Components; - -/// -/// Defines whitelist and blacklist for entities that can spawn at a spawnpoint when they are spawned via the -/// -[RegisterComponent] -public sealed partial class GridSpawnPointWhitelistComponent : Component -{ - /// - /// Whitelist of entities that can be spawned at this SpawnPoint - /// - [DataField] - public EntityWhitelist? Whitelist; - - /// - /// Whitelist of entities that can't be spawned at this SpawnPoint - /// - [DataField] - public EntityWhitelist? Blacklist; -} diff --git a/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs b/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs index 1dd7b70f8d..96483cc25e 100644 --- a/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs +++ b/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs @@ -345,14 +345,21 @@ public sealed partial class StationJobsSystem { var outputDict = new Dictionary>(profiles.Count); + var antags = _antag.GetAntagJobs(); + foreach (var (player, profile) in profiles) { var roleBans = _banManager.GetJobBans(player); - var antagBlocked = _antag.GetPreSelectedAntagSessions(); var profileJobs = profile.JobPriorities.Keys.Select(k => new ProtoId(k)).ToList(); var ev = new StationJobsGetCandidatesEvent(player, profileJobs); RaiseLocalEvent(ref ev); + // Shouldn't happen but you know :P + if (!_player.TryGetSessionById(player, out var session)) + continue; + + var (whitelist, blacklist) = antags.GetValueOrDefault(session); + List? availableJobs = null; foreach (var jobId in profileJobs) @@ -365,7 +372,10 @@ public sealed partial class StationJobsSystem if (!_prototypeManager.Resolve(jobId, out var job)) continue; - if (!job.CanBeAntag && (!_player.TryGetSessionById(player, out var session) || antagBlocked.Contains(session))) + if (whitelist != null && !whitelist.Contains(jobId)) + continue; + + if (blacklist != null && blacklist.Contains(jobId)) continue; if (weight is not null && job.Weight != weight.Value) diff --git a/Content.Server/Xenoborgs/XenoborgSystem.cs b/Content.Server/Xenoborgs/XenoborgSystem.cs index 8a046ce3c7..2c7d0b5f44 100644 --- a/Content.Server/Xenoborgs/XenoborgSystem.cs +++ b/Content.Server/Xenoborgs/XenoborgSystem.cs @@ -96,6 +96,8 @@ public sealed partial class XenoborgSystem : EntitySystem private void OnXenoborgMindRemoved(EntityUid ent, XenoborgComponent comp, MindRemovedMessage args) { - _roles.MindRemoveRole(args.Mind.Owner, comp.MindRole); + // We don't need to update the mind if the mind is being fully detached! + if (args.TransferEntity != null) + _roles.MindRemoveRole(args.Mind.Owner, comp.MindRole); } } diff --git a/Content.Shared/Antag/AntagAcceptability.cs b/Content.Shared/Antag/AntagAcceptability.cs deleted file mode 100644 index 33323aacf3..0000000000 --- a/Content.Shared/Antag/AntagAcceptability.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace Content.Shared.Antag; - -/// -/// Used by AntagSelectionSystem to indicate which types of antag roles are allowed to choose the same entity -/// For example, Thief HeadRev -/// -public enum AntagAcceptability -{ - /// - /// Dont choose anyone who already has an antag role - /// - None, - /// - /// Dont choose anyone who has an exclusive antag role - /// - NotExclusive, - /// - /// Choose anyone - /// - All, -} - -public enum AntagSelectionTime : byte -{ - /// - /// Antag roles are assigned before players are assigned jobs and spawned in. - /// This prevents antag selection from happening if the round is on-going. - /// - PrePlayerSpawn, - - /// - /// Antag roles are selected to the player session before job assignment and spawning. - /// Unlike PrePlayerSpawn, this does not remove you from the job spawn pool. - /// - IntraPlayerSpawn, - - /// - /// Antag roles get assigned after players have been assigned jobs and have spawned in. - /// - PostPlayerSpawn, -} diff --git a/Content.Shared/Antag/AntagSpecifierPrototype.cs b/Content.Shared/Antag/AntagSpecifierPrototype.cs new file mode 100644 index 0000000000..9171684759 --- /dev/null +++ b/Content.Shared/Antag/AntagSpecifierPrototype.cs @@ -0,0 +1,181 @@ +using Content.Shared.Preferences.Loadouts; +using Content.Shared.Roles; +using Content.Shared.Whitelist; +using Robust.Shared.Audio; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array; + +namespace Content.Shared.Antag; + +/// +/// A more specific version of which includes additional information that can vary between antags of the same type. +/// +/// +/// Some of this should be moved to at a later date. +/// Specifically MinMax, PlayerRatio and LateJoin logic. +/// This would allow for greater control over spawning that a static prototype doesn't offer. +/// +[Prototype] +[DataDefinition] +public sealed partial class AntagSpecifierPrototype : IPrototype, IInheritingPrototype +{ + [ParentDataField(typeof(AbstractPrototypeIdArraySerializer))] + public string[]? Parents { get; private set; } + + [NeverPushInheritance] + [AbstractDataField] + public bool Abstract { get; private set; } + + [ViewVariables, IdDataField] + public string ID { get; private set; } = default!; + + /// + /// A list of antagonist roles that are used for selecting which players will be antagonists. + /// + [DataField] + public List> PrefRoles = new(); + + /// + /// Should we allow people who already have an antagonist role? + /// + [DataField] + public AntagAcceptability MultiAntagSetting = AntagAcceptability.None; + + /// + /// Whether or not players should be picked to inhabit this antag or not. + /// If no players are left and is set, it will make a ghost role. + /// + [DataField] + public bool PickPlayer = true; + + /// + /// A list of whitelisted jobs for this antagonist. + /// Useful for antags that should only roll on a specific job, such as Malf AI. + /// + [DataField] + [AlwaysPushInheritance] + public HashSet>? JobWhitelist; + + /// + /// A list of blacklisted jobs for this antagonist. + /// + [DataField] + [AlwaysPushInheritance] + public HashSet>? JobBlacklist; + + /// + /// Mostly just here for legacy compatibility and reducing boilerplate + /// + [DataField] + public bool AllowNonHumans; + + /// + /// A whitelist for selecting which players can become this antag. + /// + [DataField] + [AlwaysPushInheritance] + public EntityWhitelist? Whitelist; + + /// + /// A blacklist for selecting which players can become this antag. + /// + [DataField] + [AlwaysPushInheritance] + public EntityWhitelist? Blacklist; + + /// + /// Components added to the player. + /// + [DataField] + [AlwaysPushInheritance] + public ComponentRegistry Components = new(); + + /// + /// Components added to the player's mind. + /// Do NOT use this to add role-type components. Add those as MindRoles instead + /// + [DataField] + [AlwaysPushInheritance] + public ComponentRegistry MindComponents = new(); + + /// + /// List of Mind Role Prototypes to be added to the player's mind. + /// + [DataField] + [AlwaysPushInheritance] + public List? MindRoles; + + /// + /// A set of starting gear that's equipped to the player. + /// + [DataField] + public ProtoId? StartingGear; + + /// + /// A list of role loadouts, from which a randomly selected one will be equipped. + /// + [DataField] + public List>? RoleLoadout; + + /// + /// A briefing shown to the player. + /// + [DataField] + public BriefingData? Briefing; + + /// + /// A spawner used to defer the selection of this particular definition. + /// + /// + /// Not the cleanest way of doing this code but it's just an odd specific behavior. + /// Sue me. + /// + [DataField] + public EntProtoId? SpawnerPrototype; +} + +/// +/// Used by AntagSelectionSystem to indicate which types of antag roles are allowed to choose the same entity +/// For example, Thief HeadRev +/// +public enum AntagAcceptability +{ + /// + /// Dont choose anyone who already has an antag role + /// + None, + /// + /// Dont choose anyone who has an exclusive antag role + /// + NotExclusive, + /// + /// Choose anyone + /// + All, +} + +/// +/// Contains data used to generate a briefing. +/// +[DataDefinition] +public partial struct BriefingData +{ + /// + /// The text shown + /// + [DataField] + public LocId? Text; + + /// + /// The color of the text. + /// + [DataField] + public Color? Color; + + /// + /// The sound played. + /// + [DataField] + public SoundSpecifier? Sound; +} + diff --git a/Content.Shared/CCVar/CCVars.Game.cs b/Content.Shared/CCVar/CCVars.Game.cs index 03cf6a673a..2a923da7f8 100644 --- a/Content.Shared/CCVar/CCVars.Game.cs +++ b/Content.Shared/CCVar/CCVars.Game.cs @@ -47,6 +47,12 @@ public sealed partial class CCVars public static readonly CVarDef GameLobbyFallbackPreset = CVarDef.Create("game.fallbackpreset", "Traitor,Extended", CVar.ARCHIVE); + /// + /// The preset for the game to fall back to if the selected preset could not be used, and fallback is enabled. + /// + public static readonly CVarDef + GameTickerIgnoredPresets = CVarDef.Create("game.ignoredpresets", "", CVar.ARCHIVE); + /// /// Controls if people can win the game in Suspicion or Deathmatch. /// diff --git a/Content.Shared/Destructible/Thresholds/MinMax.cs b/Content.Shared/Destructible/Thresholds/MinMax.cs index 8487b98b49..9b7d572fd9 100644 --- a/Content.Shared/Destructible/Thresholds/MinMax.cs +++ b/Content.Shared/Destructible/Thresholds/MinMax.cs @@ -26,4 +26,9 @@ public partial struct MinMax { return random.Next(Min, Max + 1); } + + public static implicit operator MinMax((int Min, int Max) tuple) + { + return new MinMax(tuple.Min, tuple.Max); + } } diff --git a/Content.Shared/Roles/JobPrototype.cs b/Content.Shared/Roles/JobPrototype.cs index 6b58c42428..7b25045905 100644 --- a/Content.Shared/Roles/JobPrototype.cs +++ b/Content.Shared/Roles/JobPrototype.cs @@ -81,9 +81,6 @@ namespace Content.Shared.Roles [DataField] public bool? OverrideConsoleVisibility { get; private set; } = null; - [DataField] - public bool CanBeAntag { get; private set; } = true; - /// /// The "weight" or importance of this job. If this number is large, the job system will assign this job /// before assigning other jobs. diff --git a/Content.Shared/Roles/Jobs/SharedJobSystem.cs b/Content.Shared/Roles/Jobs/SharedJobSystem.cs index 867842308e..c7e0fb17d6 100644 --- a/Content.Shared/Roles/Jobs/SharedJobSystem.cs +++ b/Content.Shared/Roles/Jobs/SharedJobSystem.cs @@ -1,9 +1,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; -using Content.Shared.Players; using Content.Shared.Players.PlayTimeTracking; using Content.Shared.Roles.Components; -using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -14,7 +12,6 @@ namespace Content.Shared.Roles.Jobs; /// public abstract class SharedJobSystem : EntitySystem { - [Dependency] private readonly SharedPlayerSystem _playerSystem = default!; [Dependency] private readonly IPrototypeManager _prototypes = default!; [Dependency] private readonly SharedRoleSystem _roles = default!; @@ -204,17 +201,4 @@ public abstract class SharedJobSystem : EntitySystem MindTryGetJobName(mindId, out var name); return name; } - - public bool CanBeAntag(ICommonSession player) - { - // If the player does not have any mind associated with them (e.g., has not spawned in or is in the lobby), then - // they are eligible to be given an antag role/entity. - if (_playerSystem.ContentData(player) is not { Mind: { } mindId }) - return true; - - if (!MindTryGetJob(mindId, out var prototype)) - return true; - - return prototype.CanBeAntag; - } } diff --git a/Content.Shared/Roles/SharedRoleSystem.cs b/Content.Shared/Roles/SharedRoleSystem.cs index 47db09ebdb..b95c9c4857 100644 --- a/Content.Shared/Roles/SharedRoleSystem.cs +++ b/Content.Shared/Roles/SharedRoleSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.CCVar; using Content.Shared.Database; using Content.Shared.GameTicking; using Content.Shared.Mind; +using Content.Shared.Players; using Content.Shared.Roles.Components; using Content.Shared.Whitelist; using Robust.Shared.Audio; @@ -605,6 +606,16 @@ public abstract class SharedRoleSystem : EntitySystem return roleInfo; } + /// + /// Does this player's mind possess an antagonist role + /// + /// The player session we want the mind of + /// True if the mind possesses any antag roles + public bool PlayerIsAntagonist(ICommonSession player) + { + return MindIsAntagonist(player.GetMind()); + } + /// /// Does this mind possess an antagonist role /// @@ -618,6 +629,16 @@ public abstract class SharedRoleSystem : EntitySystem return CheckAntagonistStatus(mindId.Value).Antag; } + /// + /// Does this player's mind possess an exclusive antagonist role + /// + /// The player session we want the mind of + /// True if the mind possesses any antag roles + public bool PlayerIsExclusiveAntagonist(ICommonSession player) + { + return MindIsExclusiveAntagonist(player.GetMind()); + } + /// /// Does this mind possess an exclusive antagonist role /// diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Conditional/xenoborgs.yml b/Resources/Prototypes/Entities/Markers/Spawners/Conditional/xenoborgs.yml index a8251739ac..39aace14d7 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/Conditional/xenoborgs.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/Conditional/xenoborgs.yml @@ -3,17 +3,9 @@ parent: MarkerBase name: xenoborgs components: - - type: GridSpawnPointWhitelist + - type: AntagGridSpawnPoint whitelist: - components: - - Xenoborg - tags: - - XenoborgGhostrole - blacklist: - components: - - MothershipCore - tags: - - MothershipCoreGhostrole + - Xenoborg - type: SpawnPoint - type: Sprite layers: @@ -26,12 +18,9 @@ parent: MarkerBase name: mothership core components: - - type: GridSpawnPointWhitelist + - type: AntagGridSpawnPoint whitelist: - components: - - MothershipCore - tags: - - MothershipCoreGhostrole + - MothershipCore - type: SpawnPoint - type: Sprite layers: diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index 6368d2e23e..62beb6be01 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -66,6 +66,14 @@ children: - id: DerelictSyndicateAssaultCyborgSpawn +- type: entity + abstract: true + parent: BaseGameRule + id: BaseAntagGhostRoleRule + components: + - type: AntagSelection + selectionTime: Never + - type: entity id: BaseStationEvent parent: BaseGameRule @@ -185,7 +193,7 @@ prototype: MobSkeletonCloset - type: entity - parent: BaseGameRule + parent: BaseAntagGhostRoleRule id: DragonSpawn components: - type: StationEvent @@ -205,18 +213,14 @@ - DragonSurviveObjective - type: AntagSelection agentName: dragon-round-end-agent-name - definitions: - - spawnerPrototype: SpawnPointGhostDragon - min: 1 - max: 1 - pickPlayer: false - mindRoles: - - MindRoleDragon + antags: + - !type:FixedAntagCount + proto: Dragon - type: DynamicRuleCost cost: 75 - type: entity - parent: BaseGameRule + parent: BaseAntagGhostRoleRule id: NinjaSpawn components: - type: StationEvent @@ -237,38 +241,14 @@ - NinjaSurviveObjective - type: AntagSelection agentName: ninja-round-end-agent-name - definitions: - - spawnerPrototype: SpawnPointGhostSpaceNinja - min: 1 - max: 1 - pickPlayer: false - startingGear: SpaceNinjaGear - roleLoadout: - - RoleSurvivalSpaceNinja - briefing: - text: ninja-role-greeting - color: Green - sound: /Audio/Misc/ninja_greeting.ogg - components: - - type: SpaceNinja - - type: NpcFactionMember - factions: - - Syndicate - - type: AutoImplant - implants: - - DeathAcidifierImplant - - type: RandomMetadata - nameSegments: - - NamesNinjaTitle - - NamesNinja - nameFormat: name-format-ninja - mindRoles: - - MindRoleNinja + antags: + - !type:FixedAntagCount + proto: SpaceNinja - type: DynamicRuleCost cost: 75 - type: entity - parent: BaseGameRule + parent: BaseAntagGhostRoleRule id: ParadoxCloneSpawn components: - type: StationEvent @@ -288,20 +268,9 @@ - type: AntagRandomSpawn # TODO: improve spawning so they only start in maints - type: AntagSelection agentName: paradox-clone-round-end-agent-name - definitions: - - spawnerPrototype: SpawnPointGhostParadoxClone - min: 1 - max: 1 - pickPlayer: false - startingGear: ParadoxCloneGear - roleLoadout: - - RoleSurvivalVoxTank # give vox something to breath in case they don't get a copy - briefing: - text: paradox-clone-role-greeting - color: lightblue - sound: /Audio/Misc/paradox_clone_greeting.ogg - mindRoles: - - MindRoleParadoxClone + antags: + - !type:FixedAntagCount + proto: ParadoxClone - type: DynamicRuleCost cost: 50 @@ -318,7 +287,7 @@ prototype: MobRevenant - type: entity - parent: BaseWizardRule + parent: [ BaseAntagGhostRoleRule, BaseWizardRule ] id: WizardSpawn components: - type: StationEvent @@ -327,34 +296,6 @@ earliestStart: 30 reoccurrenceDelay: 60 minimumPlayers: 30 - - type: AntagSelection - agentName: wizard-round-end-name - definitions: - - spawnerPrototype: SpawnPointGhostWizard - min: 1 - max: 1 - playerRatio: 1 - pickPlayer: false - startingGear: WizardBlueGear - roleLoadout: - - RoleSurvivalExtended - briefing: - text: wizard-role-greeting - color: Turquoise - # TODO: Need Wizard Start sound - #sound: "/Audio/Ambience/Antag/wizard_start.ogg" - # TODO: WizardComp as needed - components: - - type: NpcFactionMember - factions: - - Wizard - - type: RandomMetadata - nameSegments: - - NamesWizardFirst - - NamesWizardLast - nameFormat: name-format-wizard - mindRoles: - - MindRoleWizard # disabled until event is rewritten to be more interesting #- type: entity @@ -541,32 +482,17 @@ occursDuringRoundEnd: false - type: ZombieRule - type: AntagSelection - definitions: - - prefRoles: [ InitialInfected ] - max: 3 - playerRatio: 10 - blacklist: - components: - - ZombieImmune - - AntagImmune - briefing: - text: zombie-patientzero-role-greeting - color: Plum - sound: "/Audio/Ambience/Antag/zombie_start.ogg" - components: - - type: PendingZombie #less time to prepare than normal - minInitialInfectedGrace: 300 - maxInitialInfectedGrace: 450 - - type: ZombifyOnDeath - - type: IncurableZombie - - type: InitialInfected - mindRoles: - - MindRoleInitialInfected + antags: + - !type:LinearAntagCount + proto: InitialInfected + range: + min: 1 + max: 3 - type: DynamicRuleCost cost: 200 - type: entity - parent: BaseNukeopsRule + parent: [ BaseAntagGhostRoleRule, BaseNukeopsRule ] id: LoneOpsSpawn components: - type: StationEvent @@ -580,26 +506,9 @@ - type: NukeopsRule roundEndBehavior: Nothing - type: AntagSelection - definitions: - - spawnerPrototype: SpawnPointLoneNukeOperative - min: 1 - max: 1 - pickPlayer: false - startingGear: SyndicateLoneOperativeGearFull - roleLoadout: - - RoleSurvivalNukie - components: - - type: NukeOperative - - type: RandomMetadata - nameSegments: - - NamesSyndicatePrefix - - NamesSyndicateNormal - nameFormat: name-format-nukie-generic - - type: NpcFactionMember - factions: - - Syndicate - mindRoles: - - MindRoleLoneops + antags: + - !type:FixedAntagCount + proto: LoneOp - type: DynamicRuleCost cost: 75 @@ -619,17 +528,12 @@ occursDuringRoundEnd: false - type: AlertLevelInterceptionRule - type: AntagSelection - definitions: - - prefRoles: [ TraitorSleeper ] - fallbackRoles: [ Traitor ] - min: 1 - max: 2 - playerRatio: 10 - blacklist: - components: - - AntagImmune - mindRoles: - - MindRoleTraitorSleeper + antags: + - !type:LinearAntagCount + proto: TraitorSleeper + range: + min: 1 + max: 2 - type: entity id: MassHallucinations @@ -703,8 +607,9 @@ prototype: RandomSatchelSpawner - type: entity - parent: BaseGameRule - id: DerelictEngineerCyborgSpawn + abstract: true + parent: BaseAntagGhostRoleRule + id: BaseDerelictCyborgSpawn components: - type: StationEvent weight: 2.5 @@ -714,116 +619,72 @@ duration: null - type: SpaceSpawnRule spawnDistance: 0 + +- type: entity + parent: BaseDerelictCyborgSpawn + id: DerelictEngineerCyborgSpawn + components: - type: AntagSpawner prototype: PlayerEngineeringBorgDerelictGhostRole - type: AntagSelection - definitions: - - spawnerPrototype: SpawnPointGhostDerelictEngineeringCyborg - min: 1 - max: 1 - pickPlayer: false + antags: + - !type:FixedAntagCount + proto: DerelictEngineeringCyborg - type: entity - parent: BaseGameRule + parent: BaseDerelictCyborgSpawn id: DerelictGenericCyborgSpawn components: - - type: StationEvent - weight: 2.5 - earliestStart: 15 - reoccurrenceDelay: 20 - minimumPlayers: 4 - duration: null - - type: SpaceSpawnRule - spawnDistance: 0 - type: AntagSpawner prototype: PlayerBorgDerelictGhostRole - type: AntagSelection - definitions: - - spawnerPrototype: SpawnPointGhostDerelictCyborg - min: 1 - max: 1 - pickPlayer: false + antags: + - !type:FixedAntagCount + proto: DerelictGenericCyborg - type: entity - parent: BaseGameRule + parent: BaseDerelictCyborgSpawn id: DerelictJanitorCyborgSpawn components: - - type: StationEvent - weight: 2.5 - earliestStart: 15 - reoccurrenceDelay: 20 - minimumPlayers: 4 - duration: null - - type: SpaceSpawnRule - spawnDistance: 0 - type: AntagSpawner prototype: PlayerJanitorBorgDerelictGhostRole - type: AntagSelection - definitions: - - spawnerPrototype: SpawnPointGhostDerelictJanitorCyborg - min: 1 - max: 1 - pickPlayer: false + antags: + - !type:FixedAntagCount + proto: DerelictJanitorCyborg - type: entity - parent: BaseGameRule + parent: BaseDerelictCyborgSpawn id: DerelictMedicalCyborgSpawn components: - - type: StationEvent - weight: 2.5 - earliestStart: 15 - reoccurrenceDelay: 20 - minimumPlayers: 4 - duration: null - - type: SpaceSpawnRule - spawnDistance: 0 - type: AntagSpawner prototype: PlayerMedicalBorgDerelictGhostRole - type: AntagSelection - definitions: - - spawnerPrototype: SpawnPointGhostDerelictMedicalCyborg - min: 1 - max: 1 - pickPlayer: false + antags: + - !type:FixedAntagCount + proto: DerelictMedicalCyborg - type: entity - parent: BaseGameRule + parent: BaseDerelictCyborgSpawn id: DerelictMiningCyborgSpawn components: - - type: StationEvent - weight: 2.5 - earliestStart: 15 - reoccurrenceDelay: 20 - minimumPlayers: 4 - duration: null - - type: SpaceSpawnRule - spawnDistance: 0 - type: AntagSpawner prototype: PlayerMiningBorgDerelictGhostRole - type: AntagSelection - definitions: - - spawnerPrototype: SpawnPointGhostDerelictMiningCyborg - min: 1 - max: 1 - pickPlayer: false + antags: + - !type:FixedAntagCount + proto: DerelictMiningCyborg - type: entity - parent: BaseGameRule + parent: BaseDerelictCyborgSpawn id: DerelictSyndicateAssaultCyborgSpawn components: - type: StationEvent - weight: 2.5 earliestStart: 25 - reoccurrenceDelay: 20 minimumPlayers: 15 - duration: null - - type: SpaceSpawnRule - spawnDistance: 0 - type: AntagSpawner prototype: PlayerBorgSyndicateDerelictGhostRole - type: AntagSelection - definitions: - - spawnerPrototype: SpawnPointGhostDerelictSyndicateAssaultCyborg - min: 1 - max: 1 - pickPlayer: false + antags: + - !type:FixedAntagCount + proto: DerelictSyndicateAssaultCyborg diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index 76c2ade9d4..80eeff9cfb 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -4,6 +4,14 @@ components: - type: GameRule +- type: entity + parent: BaseGameRule + id: BaseRoundstartAntagRule + abstract: true + components: + - type: AntagSelection + selectionTime: PrePlayerSpawn + - type: entity parent: BaseGameRule id: RespawnDeadRule @@ -134,7 +142,7 @@ #- Vox - type: entity - parent: BaseNukeopsRule + parent: [ BaseNukeopsRule, BaseRoundstartAntagRule ] id: Nukeops components: - type: GameRule @@ -142,61 +150,16 @@ - type: LoadMapRule mapPath: /Maps/Nonstations/nukieplanet.yml - type: AntagSelection - selectionTime: PrePlayerSpawn - definitions: - - prefRoles: [ NukeopsCommander ] - fallbackRoles: [ Nukeops, NukeopsMedic ] - spawnerPrototype: SpawnPointNukeopsCommander - startingGear: SyndicateCommanderGearFull - roleLoadout: - - RoleSurvivalNukie - components: - - type: NukeOperative - - type: RandomMetadata - nameSegments: - - NamesSyndicateElite - nameFormat: name-format-nukie-commander - - type: NpcFactionMember - factions: - - Syndicate - mindRoles: - - MindRoleNukeopsCommander - - prefRoles: [ NukeopsMedic ] - fallbackRoles: [ Nukeops, NukeopsCommander ] - spawnerPrototype: SpawnPointNukeopsMedic - startingGear: SyndicateOperativeMedicFull - roleLoadout: - - RoleSurvivalNukie - components: - - type: NukeOperative - - type: RandomMetadata - nameSegments: - - NamesSyndicateNormal - nameFormat: name-format-nukie-agent - - type: NpcFactionMember - factions: - - Syndicate - mindRoles: - - MindRoleNukeopsMedic - - prefRoles: [ Nukeops ] - fallbackRoles: [ NukeopsCommander, NukeopsMedic ] - spawnerPrototype: SpawnPointNukeopsOperative - max: 3 - playerRatio: 10 - startingGear: SyndicateOperativeGearFull - roleLoadout: - - RoleSurvivalNukie - components: - - type: NukeOperative - - type: RandomMetadata - nameSegments: - - NamesSyndicateNormal - nameFormat: name-format-nukie-operator - - type: NpcFactionMember - factions: - - Syndicate - mindRoles: - - MindRoleNukeops + antags: + - !type:FixedAntagCount + proto: NukeopsCommander + - !type:FixedAntagCount + proto: NukeopsMedic + - !type:LinearAntagCount + proto: NukeopsOperative + range: + min: 1 + max: 3 - type: DynamicRuleCost cost: 200 @@ -218,7 +181,7 @@ cost: 100 - type: entity - parent: BaseTraitorRule + parent: [ BaseTraitorRule, BaseRoundstartAntagRule ] id: Traitor components: - type: GameRule @@ -227,94 +190,61 @@ min: 240 max: 420 - type: AntagSelection - selectionTime: IntraPlayerSpawn - definitions: - - prefRoles: [ Traitor ] - max: 8 - playerRatio: 10 - blacklist: - components: - - AntagImmune - lateJoinAdditional: false - mindRoles: - - MindRoleTraitor + lateJoinAdditional: true + antags: + - !type:LinearAntagCount + proto: Traitor + range: + min: 1 + max: 8 - type: entity - id: TraitorReinforcement + id: TraitorReinforcement # This shouldn't be in here but I'm not sure where to put it :( parent: BaseTraitorRule components: - type: TraitorRule giveUplink: false - giveCodewords: false # It would actually give them a different set of codewords than the regular traitors, anyway giveBriefing: false - type: AntagSelection - definitions: - - prefRoles: [ Traitor ] - mindRoles: - - MindRoleTraitorReinforcement + antags: + - !type:FixedAntagCount + proto: TraitorReinforcement - type: entity id: Changeling - parent: BaseGameRule + parent: [BaseGameRule, BaseRoundstartAntagRule] components: - type: GameRule minPlayers: 25 - type: AntagSelection agentName: changeling-round-end-agent-name - selectionTime: IntraPlayerSpawn - definitions: - - prefRoles: [ Changeling ] - max: 3 + antags: + - !type:LinearAntagCount + proto: Changeling playerRatio: 15 - briefing: - text: changeling-role-greeting - color: Red - sound: /Audio/Ambience/Antag/changeling_start.ogg - components: - - type: ChangelingDevour - - type: ChangelingIdentity - - type: ChangelingTransform - - type: ActionGrant - actions: - - ActionChangelingStore - # TODO: Make it so the changeling gamerule changeling can inherit from the changeling store preset somehow - - type: Store - name: store-preset-name-changeling - categories: - - ChangelingAbilities - currencyWhitelist: - - ChangelingDNA - balance: - ChangelingDNA: 50 - mindRoles: - - MindRoleChangeling + range: + min: 1 + max: 3 - type: AntagObjectives objectives: - ChangelingSurviveObjective - type: entity id: Revolutionary - parent: BaseGameRule + parent: [BaseGameRule, BaseRoundstartAntagRule] components: - type: GameRule minPlayers: 15 - type: RevolutionaryRule - type: AntagSelection - selectionTime: IntraPlayerSpawn - definitions: - - prefRoles: [ HeadRev ] - max: 3 + selectionTime: PrePlayerSpawn + antags: + - !type:LinearAntagCount + proto: HeadRev playerRatio: 15 - briefing: - text: head-rev-role-greeting - color: CornflowerBlue - sound: "/Audio/Ambience/Antag/headrev_start.ogg" - startingGear: HeadRevGear - components: - - type: Revolutionary - - type: HeadRevolutionary - mindRoles: - - MindRoleHeadRevolutionary + range: + min: 1 + max: 3 - type: DynamicRuleCost cost: 200 @@ -343,49 +273,25 @@ mapPath: /Maps/Nonstations/wizardsden.yml - type: RuleGrids - type: AntagSelection + agentName: wizard-round-end-name + antags: + - !type:FixedAntagCount + proto: Wizard - type: AntagLoadProfileRule speciesOverride: Human - type: entity - parent: BaseWizardRule + parent: [ BaseWizardRule, BaseRoundstartAntagRule ] id: Wizard components: - type: GameRule minPlayers: 10 - - type: AntagSelection - agentName: wizard-round-end-name - selectionTime: PrePlayerSpawn - definitions: - - prefRoles: [ Wizard ] - max: 1 - playerRatio: 1 - spawnerPrototype: SpawnPointGhostWizard - roleLoadout: - - RoleSurvivalExtended - briefing: - text: wizard-role-greeting - color: Turquoise - # TODO: Need Wizard Start sound - #sound: "/Audio/Ambience/Antag/wizard_start.ogg" - startingGear: WizardBlueGear - # TODO: WizardComp as needed - components: - - type: NpcFactionMember - factions: - - Wizard - - type: RandomMetadata - nameSegments: - - NamesWizardFirst - - NamesWizardLast - nameFormat: name-format-wizard - mindRoles: - - MindRoleWizard - type: DynamicRuleCost cost: 150 - type: entity id: Zombie - parent: BaseGameRule + parent: [ BaseGameRule, BaseRoundstartAntagRule] components: - type: GameRule minPlayers: 20 @@ -394,26 +300,12 @@ max: 900 - type: ZombieRule - type: AntagSelection - selectionTime: IntraPlayerSpawn - definitions: - - prefRoles: [ InitialInfected ] - max: 6 - playerRatio: 10 - blacklist: - components: - - ZombieImmune - - AntagImmune - briefing: - text: zombie-patientzero-role-greeting - color: Plum - sound: "/Audio/Ambience/Antag/zombie_start.ogg" - components: - - type: PendingZombie - - type: ZombifyOnDeath - - type: IncurableZombie - - type: InitialInfected - mindRoles: - - MindRoleInitialInfected + antags: + - !type:LinearAntagCount + proto: InitialInfected + range: + min: 1 + max: 6 - type: DynamicRuleCost cost: 200 @@ -426,13 +318,6 @@ - type: RuleGrids - type: LoadMapRule gridPath: /Maps/Shuttles/mothership.yml - -- type: entity - parent: BaseXenoborgsRule - id: Xenoborgs - components: - - type: GameRule - minPlayers: 30 - type: AntagMultipleRoleSpawner antagRoleToPrototypes: MothershipCore: [ MothershipCore ] @@ -440,22 +325,21 @@ pickAndTake: true - type: AntagSelection selectionTime: PrePlayerSpawn - definitions: - - prefRoles: [ MothershipCore ] - fallbackRoles: [ Xenoborg ] - spawnerPrototype: SpawnPointGhostRoleMothershipCore - mindRoles: - - MindRoleMothershipCore - - prefRoles: [ Xenoborg ] - fallbackRoles: [ MothershipCore ] - spawnerPrototype: SpawnPointGhostRoleXenoborg - mindRoles: - - MindRoleXenoborg - min: 4 - max: 4 + antags: + - !type:FixedAntagCount + proto: MothershipCore + - !type:FixedAntagCount + proto: Xenoborg + count: 4 - type: DynamicRuleCost cost: 200 +- type: entity + parent: [ BaseXenoborgsRule, BaseRoundstartAntagRule] + id: Xenoborgs + components: + - type: GameRule + minPlayers: 30 # This rule makes the chosen players unable to get other antag rules, as a way to prevent metagaming job rolls. # Put this before antags assigned to station jobs, but after non-job antags (NukeOps/Wiz). @@ -466,12 +350,24 @@ - type: GameRule minPlayers: 5 - type: AntagSelection - selectionTime: IntraPlayerSpawn # Pre-selection before jobs; assignment doesn't really matter though, we only care about the pre-selection to block other antags. + selectionTime: PrePlayerSpawn # Pre-selection before jobs; assignment doesn't really matter though, we only care about the pre-selection to block other antags. removeUponFailedSpawn: false - definitions: - - prefRoles: [ InitialInfected, Traitor, Thief, HeadRev ] - max: 2 + antags: + - !type:LinearAntagCount + proto: DummyAntag playerRatio: 30 + range: + min: 1 + max: 2 + +- type: antagSpecifier + parent: RestrictedAntag + id: DummyAntag + prefRoles: # Only Station bound roles. + - InitialInfected + - Traitor + - Thief + - HeadRev # event schedulers diff --git a/Resources/Prototypes/GameRules/subgamemodes.yml b/Resources/Prototypes/GameRules/subgamemodes.yml index 596f14217b..dfe815cf13 100644 --- a/Resources/Prototypes/GameRules/subgamemodes.yml +++ b/Resources/Prototypes/GameRules/subgamemodes.yml @@ -16,24 +16,15 @@ maxDifficulty: 2.5 - type: AntagSelection agentName: thief-round-end-agent-name - selectionTime: IntraPlayerSpawn - definitions: - - prefRoles: [ Thief ] - max: 3 + selectionTime: PrePlayerSpawn + lateJoinAdditional: true + antags: + - !type:LinearAntagCount + proto: Thief playerRatio: 20 - lateJoinAdditional: true - allowNonHumans: true - multiAntagSetting: NotExclusive - startingGear: ThiefGear - components: - - type: Pacified - - type: Thieving - stripTimeReduction: 2 - stealthy: true - mindRoles: - - MindRoleThief - briefing: - sound: "/Audio/Misc/thief_greeting.ogg" + range: + min: 1 + max: 3 - type: DynamicRuleCost cost: 75 - type: GameRule @@ -44,34 +35,6 @@ parent: BaseWizardRule id: SubWizard components: - - type: AntagSelection - agentName: wizard-round-end-name - selectionTime: PrePlayerSpawn - definitions: - - prefRoles: [ Wizard ] - max: 1 - playerRatio: 1 - spawnerPrototype: SpawnPointGhostWizard - roleLoadout: - - RoleSurvivalExtended - briefing: - text: wizard-role-greeting - color: Turquoise - # TODO: Need Wizard Start sound - #sound: "/Audio/Ambience/Antag/wizard_start.ogg" - startingGear: WizardBlueGear - # TODO: WizardComp as needed - components: - - type: NpcFactionMember - factions: - - Wizard - - type: RandomMetadata - nameSegments: - - NamesWizardFirst - - NamesWizardLast - nameFormat: name-format-wizard - mindRoles: - - MindRoleWizard - type: GameRule cancelPresetOnTooFewPlayers: false @@ -82,25 +45,3 @@ - type: GameRule minPlayers: 30 cancelPresetOnTooFewPlayers: false - - type: AntagMultipleRoleSpawner - antagRoleToPrototypes: - MothershipCore: [ MothershipCore ] - Xenoborg: [ XenoborgEngi, XenoborgHeavy, XenoborgScout, XenoborgStealth ] - pickAndTake: true - - type: AntagSelection - selectionTime: PrePlayerSpawn - definitions: - - prefRoles: [ MothershipCore ] - fallbackRoles: [ Xenoborg ] - spawnerPrototype: SpawnPointGhostRoleMothershipCore - mindRoles: - - MindRoleMothershipCore - - prefRoles: [ Xenoborg ] - fallbackRoles: [ MothershipCore ] - spawnerPrototype: SpawnPointGhostRoleXenoborg - mindRoles: - - MindRoleXenoborg - min: 4 - max: 4 - - type: DynamicRuleCost - cost: 200 diff --git a/Resources/Prototypes/Roles/Antags/base.yml b/Resources/Prototypes/Roles/Antags/base.yml new file mode 100644 index 0000000000..d90635dd41 --- /dev/null +++ b/Resources/Prototypes/Roles/Antags/base.yml @@ -0,0 +1,73 @@ +- type: antagSpecifier + abstract: true + id: BaseAntagSpecifier + jobBlacklist: + - CentralCommandOfficial + - DeathSquad + - ERTLeader + - ERTChaplain + - ERTEngineer + - ERTSecurity + - ERTMedical + - ERTJanitor + - CBURN + blacklist: + components: + - AntagImmune + +# Command +- type: antagSpecifier + abstract: true + parent: BaseAntagSpecifier + id: CommandBlacklistedAntag + jobBlacklist: + - Captain + - HeadOfPersonnel + - HeadOfSecurity + - ChiefMedicalOfficer + - ResearchDirector + - ChiefEngineer + - Quartermaster + +# Borgs +- type: antagSpecifier + abstract: true + parent: BaseAntagSpecifier + id: CyborgBlacklistedAntag + jobBlacklist: + - StationAi + - Borg + +# Learner Roles +- type: antagSpecifier + abstract: true + parent: BaseAntagSpecifier + id: InternBlacklistedAntag + jobBlacklist: + - SecurityCadet + - MedicalIntern + - ResearchAssistant + - TechnicalAssistant + - Visitor + +# Security +- type: antagSpecifier + abstract: true + parent: BaseAntagSpecifier + id: SecurityBlacklistedAntag + jobBlacklist: + - HeadOfSecurity + - Warden + - Detective + - SecurityOfficer + - SecurityCadet + +- type: antagSpecifier + abstract: true + parent: [ CommandBlacklistedAntag, SecurityBlacklistedAntag ] + id: MindshieldRestrictedAntag + +- type: antagSpecifier + abstract: true + parent: [ MindshieldRestrictedAntag, CyborgBlacklistedAntag, InternBlacklistedAntag ] + id: RestrictedAntag diff --git a/Resources/Prototypes/Roles/Antags/changeling.yml b/Resources/Prototypes/Roles/Antags/changeling.yml index 3b19c993e6..bef0fb71d1 100644 --- a/Resources/Prototypes/Roles/Antags/changeling.yml +++ b/Resources/Prototypes/Roles/Antags/changeling.yml @@ -4,3 +4,29 @@ antagonist: true setPreference: false # TODO: set this to true once Changeling exits WIP status objective: roles-antag-changeling-objective + +- type: antagSpecifier + parent: RestrictedAntag + id: Changeling + prefRoles: [ Changeling ] + briefing: + text: changeling-role-greeting + color: Red + sound: /Audio/Ambience/Antag/changeling_start.ogg + components: + - type: ChangelingDevour + - type: ChangelingIdentity + - type: ChangelingTransform + - type: ActionGrant + actions: + - ActionChangelingStore + - type: Store + name: store-preset-name-changeling + categories: + - ChangelingAbilities + currencyWhitelist: + - ChangelingDNA + balance: + ChangelingDNA: 50 + mindRoles: + - MindRoleChangeling diff --git a/Resources/Prototypes/Roles/Antags/dragon.yml b/Resources/Prototypes/Roles/Antags/dragon.yml index 6630b812e3..52da68a602 100644 --- a/Resources/Prototypes/Roles/Antags/dragon.yml +++ b/Resources/Prototypes/Roles/Antags/dragon.yml @@ -3,3 +3,11 @@ name: roles-antag-dragon-name antagonist: true objective: roles-antag-dragon-objective + +- type: antagSpecifier + parent: RestrictedAntag + id: Dragon + spawnerPrototype: SpawnPointGhostDragon + pickPlayer: false + mindRoles: + - MindRoleDragon diff --git a/Resources/Prototypes/Roles/Antags/generic.yml b/Resources/Prototypes/Roles/Antags/generic.yml index 6a1cd12aea..7d9c6986ef 100644 --- a/Resources/Prototypes/Roles/Antags/generic.yml +++ b/Resources/Prototypes/Roles/Antags/generic.yml @@ -1,23 +1,23 @@ +# Non Descript Solo Antags + - type: antag id: GenericAntagonist name: roles-antag-generic-solo-antagonist-name antagonist: true objective: never-shown +# Non Descript Team Antags + - type: antag id: GenericTeamAntagonist name: roles-antag-generic-team-antagonist-name antagonist: true objective: never-shown +# Free Agents + - type: antag id: GenericFreeAgent name: roles-antag-generic-free-agent-name antagonist: true objective: never-shown - -- type: antag - id: GenericSiliconAntagonist - name: roles-antag-generic-silicon-antagonist-name - antagonist: true - objective: never-shown diff --git a/Resources/Prototypes/Roles/Antags/ninja.yml b/Resources/Prototypes/Roles/Antags/ninja.yml index 919471a61c..8334b8b1cc 100644 --- a/Resources/Prototypes/Roles/Antags/ninja.yml +++ b/Resources/Prototypes/Roles/Antags/ninja.yml @@ -6,6 +6,34 @@ objective: roles-antag-space-ninja-objective guides: [ SpaceNinja ] +- type: antagSpecifier + parent: RestrictedAntag + id: SpaceNinja + spawnerPrototype: SpawnPointGhostSpaceNinja + pickPlayer: false + startingGear: SpaceNinjaGear + roleLoadout: + - RoleSurvivalSpaceNinja + briefing: + text: ninja-role-greeting + color: Green + sound: /Audio/Misc/ninja_greeting.ogg + components: + - type: SpaceNinja + - type: NpcFactionMember + factions: + - Syndicate + - type: AutoImplant + implants: + - DeathAcidifierImplant + - type: RandomMetadata + nameSegments: + - NamesNinjaTitle + - NamesNinja + nameFormat: name-format-ninja + mindRoles: + - MindRoleNinja + #Ninja Gear - type: startingGear id: SpaceNinjaGear diff --git a/Resources/Prototypes/Roles/Antags/nukeops.yml b/Resources/Prototypes/Roles/Antags/nukeops.yml index de86b70560..828b06dcde 100644 --- a/Resources/Prototypes/Roles/Antags/nukeops.yml +++ b/Resources/Prototypes/Roles/Antags/nukeops.yml @@ -38,6 +38,80 @@ # should be changed to nukie playtime when thats tracked (wyci) guides: [ NuclearOperatives ] +- type: antagSpecifier + abstract: true + parent: RestrictedAntag + id: BaseNukeops + prefRoles: + - GenericTeamAntagonist # For antag ban purposes + roleLoadout: + - RoleSurvivalNukie + components: + - type: NukeOperative + - type: NpcFactionMember + factions: + - Syndicate + +- type: antagSpecifier + parent: BaseNukeops + id: NukeopsCommander + prefRoles: + - NukeopsCommander + spawnerPrototype: SpawnPointNukeopsCommander + startingGear: SyndicateCommanderGearFull + components: + - type: RandomMetadata + nameSegments: + - NamesSyndicateElite + nameFormat: name-format-nukie-commander + mindRoles: + - MindRoleNukeopsCommander + +- type: antagSpecifier + parent: BaseNukeops + id: NukeopsMedic + prefRoles: + - NukeopsMedic + spawnerPrototype: SpawnPointNukeopsMedic + startingGear: SyndicateOperativeMedicFull + components: + - type: RandomMetadata + nameSegments: + - NamesSyndicateNormal + nameFormat: name-format-nukie-agent + mindRoles: + - MindRoleNukeopsMedic + +- type: antagSpecifier + parent: BaseNukeops + id: NukeopsOperative + prefRoles: + - Nukeops + spawnerPrototype: SpawnPointNukeopsOperative + startingGear: SyndicateOperativeGearFull + components: + - type: RandomMetadata + nameSegments: + - NamesSyndicateNormal + nameFormat: name-format-nukie-operator + mindRoles: + - MindRoleNukeops + +- type: antagSpecifier + parent: BaseNukeops + id: LoneOp + spawnerPrototype: SpawnPointLoneNukeOperative + pickPlayer: false + startingGear: SyndicateLoneOperativeGearFull + components: + - type: RandomMetadata + nameSegments: + - NamesSyndicatePrefix + - NamesSyndicateNormal + nameFormat: name-format-nukie-generic + mindRoles: + - MindRoleLoneops + - type: startingGear id: SyndicateOperativeGearFullNoUplink equipment: diff --git a/Resources/Prototypes/Roles/Antags/paradoxClone.yml b/Resources/Prototypes/Roles/Antags/paradoxClone.yml index 6e8daf16b4..67990b7f0a 100644 --- a/Resources/Prototypes/Roles/Antags/paradoxClone.yml +++ b/Resources/Prototypes/Roles/Antags/paradoxClone.yml @@ -5,6 +5,21 @@ objective: roles-antag-paradox-clone-objective setPreference: false +- type: antagSpecifier + parent: RestrictedAntag + id: ParadoxClone + spawnerPrototype: SpawnPointGhostParadoxClone + pickPlayer: false + startingGear: ParadoxCloneGear + roleLoadout: + - RoleSurvivalVoxTank # give vox something to breath in case they don't get a copy + briefing: + text: paradox-clone-role-greeting + color: lightblue + sound: /Audio/Misc/paradox_clone_greeting.ogg + mindRoles: + - MindRoleParadoxClone + # they need to be able to espace when spawning inside a locked room # TODO: remove this once we got a better spawning loacation selection - type: startingGear diff --git a/Resources/Prototypes/Roles/Antags/revolutionary.yml b/Resources/Prototypes/Roles/Antags/revolutionary.yml index 172876040a..2411e0e968 100644 --- a/Resources/Prototypes/Roles/Antags/revolutionary.yml +++ b/Resources/Prototypes/Roles/Antags/revolutionary.yml @@ -9,6 +9,34 @@ - !type:OverallPlaytimeRequirement time: 1h +- type: antagSpecifier + abstract: true + parent: RestrictedAntag + id: BaseRev + name: revolutionary + prefRoles: + - GenericTeamAntagonist # For antag ban purposes + components: + - type: Revolutionary + +- type: antagSpecifier + parent: BaseRev + id: HeadRev + prefRoles: + - HeadRev + briefing: + text: head-rev-role-greeting + color: CornflowerBlue + sound: "/Audio/Ambience/Antag/headrev_start.ogg" + startingGear: HeadRevGear + components: + - type: Revolutionary + - type: HeadRevolutionary + mindRoles: + - MindRoleHeadRevolutionary + +# TODO: Make it so creating new revolutionaries uses antag prototypes! This saves a *lot* of boilerplate for conversion antags. + - type: antag id: Rev name: roles-antag-rev-name diff --git a/Resources/Prototypes/Roles/Antags/silicon.yml b/Resources/Prototypes/Roles/Antags/silicon.yml index b3ebe60a60..b69f1c18d0 100644 --- a/Resources/Prototypes/Roles/Antags/silicon.yml +++ b/Resources/Prototypes/Roles/Antags/silicon.yml @@ -4,3 +4,49 @@ antagonist: true setPreference: false objective: roles-antag-subverted-silicon-objective + +- type: antag + id: GenericSiliconAntagonist + name: roles-antag-generic-silicon-antagonist-name + antagonist: true + objective: never-shown + +## Derelict Borgs + +- type: antagSpecifier + abstract: true + parent: RestrictedAntag + id: DerelictCyborg + pickPlayer: false + prefRoles: + - GenericSiliconAntagonist + +- type: antagSpecifier + parent: DerelictCyborg + id: DerelictGenericCyborg + spawnerPrototype: SpawnPointGhostDerelictCyborg + +- type: antagSpecifier + parent: DerelictCyborg + id: DerelictEngineeringCyborg + spawnerPrototype: SpawnPointGhostDerelictEngineeringCyborg + +- type: antagSpecifier + parent: DerelictCyborg + id: DerelictJanitorCyborg + spawnerPrototype: SpawnPointGhostDerelictJanitorCyborg + +- type: antagSpecifier + parent: DerelictCyborg + id: DerelictMedicalCyborg + spawnerPrototype: SpawnPointGhostDerelictMedicalCyborg + +- type: antagSpecifier + parent: DerelictCyborg + id: DerelictMiningCyborg + spawnerPrototype: SpawnPointGhostDerelictMiningCyborg + +- type: antagSpecifier + parent: DerelictCyborg + id: DerelictSyndicateAssaultCyborg + spawnerPrototype: SpawnPointGhostDerelictSyndicateAssaultCyborg diff --git a/Resources/Prototypes/Roles/Antags/thief.yml b/Resources/Prototypes/Roles/Antags/thief.yml index 740a7e217f..7584a164c6 100644 --- a/Resources/Prototypes/Roles/Antags/thief.yml +++ b/Resources/Prototypes/Roles/Antags/thief.yml @@ -9,6 +9,24 @@ - !type:OverallPlaytimeRequirement time: 1h +- type: antagSpecifier + parent: RestrictedAntag + id: Thief + prefRoles: + - Thief + allowNonHumans: true + multiAntagSetting: NotExclusive + startingGear: ThiefGear + components: + - type: Pacified + - type: Thieving + stripTimeReduction: 2 + stealthy: true + mindRoles: + - MindRoleThief + briefing: + sound: "/Audio/Misc/thief_greeting.ogg" + - type: startingGear id: ThiefGear storage: diff --git a/Resources/Prototypes/Roles/Antags/traitor.yml b/Resources/Prototypes/Roles/Antags/traitor.yml index 2920b2c56f..16c64014c0 100644 --- a/Resources/Prototypes/Roles/Antags/traitor.yml +++ b/Resources/Prototypes/Roles/Antags/traitor.yml @@ -9,6 +9,22 @@ - !type:OverallPlaytimeRequirement time: 1h +- type: antagSpecifier + abstract: true + parent: RestrictedAntag + id: BaseTraitor + +- type: antagSpecifier + parent: BaseTraitor + id: Traitor + prefRoles: + - Traitor + blacklist: + components: + - AntagImmune + mindRoles: + - MindRoleTraitor + - type: antag id: TraitorSleeper name: roles-antag-syndicate-agent-sleeper-name @@ -20,6 +36,23 @@ - !type:OverallPlaytimeRequirement time: 1h +- type: antagSpecifier + parent: BaseTraitor + id: TraitorSleeper + prefRoles: + - TraitorSleeper + mindRoles: + - MindRoleTraitorSleeper + +- type: antagSpecifier + parent: BaseTraitor + id: TraitorReinforcement + prefRoles: + - Traitor + - GenericTeamAntagonist # Matters for Antag bans. + mindRoles: + - MindRoleTraitorReinforcement + # Syndicate Operative Outfit - Monkey - type: startingGear id: SyndicateOperativeGearMonkey diff --git a/Resources/Prototypes/Roles/Antags/wizard.yml b/Resources/Prototypes/Roles/Antags/wizard.yml index 9d528f9b79..8ab571fc98 100644 --- a/Resources/Prototypes/Roles/Antags/wizard.yml +++ b/Resources/Prototypes/Roles/Antags/wizard.yml @@ -16,4 +16,29 @@ time: 5h guides: [ Wizard ] +- type: antagSpecifier + parent: RestrictedAntag + id: Wizard + spawnerPrototype: SpawnPointGhostWizard + startingGear: WizardBlueGear + roleLoadout: + - RoleSurvivalExtended + briefing: + text: wizard-role-greeting + color: Turquoise + # TODO: Need Wizard Start sound + #sound: "/Audio/Ambience/Antag/wizard_start.ogg" + # TODO: WizardComp as needed + components: + - type: NpcFactionMember + factions: + - Wizard + - type: RandomMetadata + nameSegments: + - NamesWizardFirst + - NamesWizardLast + nameFormat: name-format-wizard + mindRoles: + - MindRoleWizard + # See wizard_startinggear for wiz start gear options diff --git a/Resources/Prototypes/Roles/Antags/xenoborgs.yml b/Resources/Prototypes/Roles/Antags/xenoborgs.yml index 4e1989be8d..64772485e1 100644 --- a/Resources/Prototypes/Roles/Antags/xenoborgs.yml +++ b/Resources/Prototypes/Roles/Antags/xenoborgs.yml @@ -10,6 +10,14 @@ time: 18000 # 5 hrs guides: [ Xenoborgs ] +- type: antagSpecifier + parent: RestrictedAntag + id: MothershipCore + prefRoles: [ MothershipCore ] + spawnerPrototype: SpawnPointGhostRoleMothershipCore + mindRoles: + - MindRoleMothershipCore + - type: antag id: Xenoborg name: roles-antag-xenoborg-name @@ -21,3 +29,16 @@ role: JobBorg time: 18000 # 5 hrs guides: [ Xenoborgs ] + +- type: antagSpecifier + abstract: true + parent: RestrictedAntag + id: BaseXenoborg + prefRoles: [ Xenoborg ] + spawnerPrototype: SpawnPointGhostRoleXenoborg + mindRoles: + - MindRoleXenoborg + +- type: antagSpecifier + parent: BaseXenoborg + id: Xenoborg diff --git a/Resources/Prototypes/Roles/Antags/zombie.yml b/Resources/Prototypes/Roles/Antags/zombie.yml index fa6561aa5e..11c44afacf 100644 --- a/Resources/Prototypes/Roles/Antags/zombie.yml +++ b/Resources/Prototypes/Roles/Antags/zombie.yml @@ -9,6 +9,30 @@ - !type:OverallPlaytimeRequirement time: 1h +- type: antagSpecifier + parent: RestrictedAntag + id: InitialInfected + prefRoles: [ InitialInfected ] + blacklist: + components: + - ZombieImmune + - AntagImmune + briefing: + text: zombie-patientzero-role-greeting + color: Plum + sound: "/Audio/Ambience/Antag/zombie_start.ogg" + components: + - type: PendingZombie #less time to prepare than normal + minInitialInfectedGrace: 300 + maxInitialInfectedGrace: 450 + - type: ZombifyOnDeath + - type: IncurableZombie + - type: InitialInfected + mindRoles: + - MindRoleInitialInfected + +# TODO: Make it so creating new zombies uses antag prototypes! This saves a *lot* of boilerplate for conversion antags. + - type: antag id: Zombie name: roles-antag-zombie-name diff --git a/Resources/Prototypes/Roles/Jobs/Cargo/quartermaster.yml b/Resources/Prototypes/Roles/Jobs/Cargo/quartermaster.yml index 92b9b93671..bf69f568e4 100644 --- a/Resources/Prototypes/Roles/Jobs/Cargo/quartermaster.yml +++ b/Resources/Prototypes/Roles/Jobs/Cargo/quartermaster.yml @@ -17,7 +17,6 @@ startingGear: QuartermasterGear icon: "JobIconQuarterMaster" supervisors: job-supervisors-captain - canBeAntag: false access: - Cargo - Salvage diff --git a/Resources/Prototypes/Roles/Jobs/CentComm/cburn.yml b/Resources/Prototypes/Roles/Jobs/CentComm/cburn.yml index a17acc9898..df2bbf0efd 100644 --- a/Resources/Prototypes/Roles/Jobs/CentComm/cburn.yml +++ b/Resources/Prototypes/Roles/Jobs/CentComm/cburn.yml @@ -7,7 +7,6 @@ startingGear: CBURNGear icon: "JobIconCBURN" supervisors: job-supervisors-centcom - canBeAntag: false accessGroups: - AllAccess access: diff --git a/Resources/Prototypes/Roles/Jobs/CentComm/deathsquad.yml b/Resources/Prototypes/Roles/Jobs/CentComm/deathsquad.yml index 0b197af4d8..8418d54486 100644 --- a/Resources/Prototypes/Roles/Jobs/CentComm/deathsquad.yml +++ b/Resources/Prototypes/Roles/Jobs/CentComm/deathsquad.yml @@ -7,7 +7,6 @@ startingGear: DeathSquadGear icon: "JobIconDeathSquad" supervisors: job-supervisors-centcom - canBeAntag: false accessGroups: - AllAccess access: diff --git a/Resources/Prototypes/Roles/Jobs/CentComm/emergencyresponseteam.yml b/Resources/Prototypes/Roles/Jobs/CentComm/emergencyresponseteam.yml index 27c61ac337..e5de415b21 100644 --- a/Resources/Prototypes/Roles/Jobs/CentComm/emergencyresponseteam.yml +++ b/Resources/Prototypes/Roles/Jobs/CentComm/emergencyresponseteam.yml @@ -8,7 +8,6 @@ startingGear: ERTLeaderGearEVA icon: "JobIconERTLeader" supervisors: job-supervisors-centcom - canBeAntag: false accessGroups: - AllAccess access: @@ -107,7 +106,6 @@ startingGear: ERTChaplainGear icon: "JobIconERTChaplain" supervisors: job-supervisors-centcom - canBeAntag: false accessGroups: - AllAccess access: @@ -184,7 +182,6 @@ startingGear: ERTEngineerGearEVA icon: "JobIconERTEngineer" supervisors: job-supervisors-centcom - canBeAntag: false accessGroups: - AllAccess access: @@ -278,7 +275,6 @@ startingGear: ERTSecurityGearEVA icon: "JobIconERTSecurity" supervisors: job-supervisors-centcom - canBeAntag: false accessGroups: - AllAccess access: @@ -465,7 +461,6 @@ startingGear: ERTMedicalGearEVA icon: "JobIconERTMedic" supervisors: job-supervisors-centcom - canBeAntag: false accessGroups: - AllAccess access: @@ -565,7 +560,6 @@ startingGear: ERTJanitorGearEVA icon: "JobIconERTJanitor" supervisors: job-supervisors-centcom - canBeAntag: false accessGroups: - AllAccess access: diff --git a/Resources/Prototypes/Roles/Jobs/CentComm/official.yml b/Resources/Prototypes/Roles/Jobs/CentComm/official.yml index 0ec4910b7c..737d635bf5 100644 --- a/Resources/Prototypes/Roles/Jobs/CentComm/official.yml +++ b/Resources/Prototypes/Roles/Jobs/CentComm/official.yml @@ -7,7 +7,6 @@ startingGear: CentcommGear icon: "JobIconNanotrasen" supervisors: job-supervisors-hos - canBeAntag: false accessGroups: - AllAccess access: diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/visitor.yml b/Resources/Prototypes/Roles/Jobs/Civilian/visitor.yml index 0e060b0eb1..3239c2251d 100644 --- a/Resources/Prototypes/Roles/Jobs/Civilian/visitor.yml +++ b/Resources/Prototypes/Roles/Jobs/Civilian/visitor.yml @@ -3,7 +3,6 @@ name: job-name-visitor description: job-description-visitor playTimeTracker: JobVisitor - canBeAntag: false icon: JobIconVisitor setPreference: false overrideConsoleVisibility: true diff --git a/Resources/Prototypes/Roles/Jobs/Command/captain.yml b/Resources/Prototypes/Roles/Jobs/Command/captain.yml index 54251b263b..d25f7c96d9 100644 --- a/Resources/Prototypes/Roles/Jobs/Command/captain.yml +++ b/Resources/Prototypes/Roles/Jobs/Command/captain.yml @@ -24,7 +24,6 @@ icon: "JobIconCaptain" joinNotifyCrew: true supervisors: job-supervisors-centcom - canBeAntag: false accessGroups: - AllAccess special: diff --git a/Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml b/Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml index 9150ca39f3..dfac2b1bc7 100644 --- a/Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml +++ b/Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml @@ -23,7 +23,6 @@ startingGear: HoPGear icon: "JobIconHeadOfPersonnel" supervisors: job-supervisors-captain - canBeAntag: false access: - Command - HeadOfPersonnel diff --git a/Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml b/Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml index 561d026020..d1e1509455 100644 --- a/Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml +++ b/Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml @@ -17,7 +17,6 @@ startingGear: ChiefEngineerGear icon: "JobIconChiefEngineer" supervisors: job-supervisors-captain - canBeAntag: false access: - Maintenance - Engineering diff --git a/Resources/Prototypes/Roles/Jobs/Engineering/technical_assistant.yml b/Resources/Prototypes/Roles/Jobs/Engineering/technical_assistant.yml index ee4431bded..761dd09d20 100644 --- a/Resources/Prototypes/Roles/Jobs/Engineering/technical_assistant.yml +++ b/Resources/Prototypes/Roles/Jobs/Engineering/technical_assistant.yml @@ -13,7 +13,6 @@ startingGear: TechnicalAssistantGear icon: "JobIconTechnicalAssistant" supervisors: job-supervisors-engineering - canBeAntag: false access: - Maintenance - Engineering diff --git a/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml b/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml index 5abd370503..92c52d5d06 100644 --- a/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml +++ b/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml @@ -19,7 +19,6 @@ startingGear: CMOGear icon: "JobIconChiefMedicalOfficer" supervisors: job-supervisors-captain - canBeAntag: false access: - Medical - Command diff --git a/Resources/Prototypes/Roles/Jobs/Medical/medical_intern.yml b/Resources/Prototypes/Roles/Jobs/Medical/medical_intern.yml index cc96b6bee2..ff3a8673b7 100644 --- a/Resources/Prototypes/Roles/Jobs/Medical/medical_intern.yml +++ b/Resources/Prototypes/Roles/Jobs/Medical/medical_intern.yml @@ -11,7 +11,6 @@ startingGear: MedicalInternGear icon: "JobIconMedicalIntern" supervisors: job-supervisors-medicine - canBeAntag: false access: - Medical - Maintenance diff --git a/Resources/Prototypes/Roles/Jobs/Science/borg.yml b/Resources/Prototypes/Roles/Jobs/Science/borg.yml index 7834043799..7d7292c18e 100644 --- a/Resources/Prototypes/Roles/Jobs/Science/borg.yml +++ b/Resources/Prototypes/Roles/Jobs/Science/borg.yml @@ -10,7 +10,6 @@ role: JobBorg time: 5h weight: 10 - canBeAntag: false icon: JobIconStationAi supervisors: job-supervisors-rd jobEntity: StationAiBrain @@ -25,7 +24,6 @@ requirements: - !type:OverallPlaytimeRequirement time: 10h - canBeAntag: false icon: JobIconBorg supervisors: job-supervisors-rd jobEntity: PlayerBorgBattery diff --git a/Resources/Prototypes/Roles/Jobs/Science/research_assistant.yml b/Resources/Prototypes/Roles/Jobs/Science/research_assistant.yml index 4805985822..5db6e304b5 100644 --- a/Resources/Prototypes/Roles/Jobs/Science/research_assistant.yml +++ b/Resources/Prototypes/Roles/Jobs/Science/research_assistant.yml @@ -11,7 +11,6 @@ startingGear: ResearchAssistantGear icon: "JobIconResearchAssistant" supervisors: job-supervisors-science - canBeAntag: false access: - Research - Maintenance diff --git a/Resources/Prototypes/Roles/Jobs/Science/research_director.yml b/Resources/Prototypes/Roles/Jobs/Science/research_director.yml index a7b057dc1b..b068374f4c 100644 --- a/Resources/Prototypes/Roles/Jobs/Science/research_director.yml +++ b/Resources/Prototypes/Roles/Jobs/Science/research_director.yml @@ -14,7 +14,6 @@ startingGear: ResearchDirectorGear icon: "JobIconResearchDirector" supervisors: job-supervisors-captain - canBeAntag: false access: - Research - Command diff --git a/Resources/Prototypes/Roles/Jobs/Security/detective.yml b/Resources/Prototypes/Roles/Jobs/Security/detective.yml index b38f2c8b1c..3dda03ea0b 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/detective.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/detective.yml @@ -10,7 +10,6 @@ startingGear: DetectiveGear icon: "JobIconDetective" supervisors: job-supervisors-hos - canBeAntag: false access: - Security - Brig diff --git a/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml b/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml index e8fdc6f738..7aa12b24cc 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml @@ -20,7 +20,6 @@ startingGear: HoSGear icon: "JobIconHeadOfSecurity" supervisors: job-supervisors-captain - canBeAntag: false access: - HeadOfSecurity - Command diff --git a/Resources/Prototypes/Roles/Jobs/Security/security_cadet.yml b/Resources/Prototypes/Roles/Jobs/Security/security_cadet.yml index 47b7472541..f54f8ead20 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/security_cadet.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/security_cadet.yml @@ -13,7 +13,6 @@ startingGear: SecurityCadetGear icon: "JobIconSecurityCadet" supervisors: job-supervisors-security - canBeAntag: false access: - Security - Brig diff --git a/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml b/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml index af8a274d77..e3c77d94a9 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml @@ -10,7 +10,6 @@ startingGear: SecurityOfficerGear icon: "JobIconSecurityOfficer" supervisors: job-supervisors-hos - canBeAntag: false access: - Security - Brig diff --git a/Resources/Prototypes/Roles/Jobs/Security/warden.yml b/Resources/Prototypes/Roles/Jobs/Security/warden.yml index 2d8813a69e..8d8cd092fc 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/warden.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/warden.yml @@ -14,7 +14,6 @@ startingGear: WardenGear icon: "JobIconWarden" supervisors: job-supervisors-hos - canBeAntag: false access: - Security - Brig From ff40e861143bee9f55b29d7b2e723557af3769fa Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 25 Apr 2026 09:36:51 +0000 Subject: [PATCH 35/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 0c91234b2d..2a400fc131 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Centronias - changes: - - message: Solution reactions which create items scale their resulting products - with the reactants, instead of eating extra reactants. - type: Fix - id: 9156 - time: '2025-10-25T00:29:28.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/41091 - author: Princess-Cheeseballs changes: - message: Eating stacks of items no longer consumes the whole stack in one bite. @@ -4069,3 +4061,12 @@ id: 9667 time: '2026-04-25T02:15:12.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/43412 +- author: Princess-Cheeseballs + changes: + - message: You can now late join as Traitor + type: Tweak + - message: Late join antag odds have been lowered to a fixed 50% + type: Tweak + id: 9668 + time: '2026-04-25T09:35:40.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/43191 From cf0a855a8f3291b94aff449c92683b2f29a7a095 Mon Sep 17 00:00:00 2001 From: Tortosaur <135037883+AffleWaffle@users.noreply.github.com> Date: Sat, 25 Apr 2026 11:27:49 +0200 Subject: [PATCH 36/65] E-dagger Pen missing inspectable damage (#43720) Add deactivatedSecret property to e_sword.yml --- Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml index 97ac9e0980..3d7fd9680b 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml @@ -188,6 +188,7 @@ types: Slash: 10 Heat: 10 + deactivatedSecret: true - type: ComponentToggler components: - type: Sharp From f0de8dd415be7e37a7e497deac4a3504f158893c Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 25 Apr 2026 09:52:59 +0000 Subject: [PATCH 37/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 2a400fc131..464422b795 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Princess-Cheeseballs - changes: - - message: Eating stacks of items no longer consumes the whole stack in one bite. - type: Fix - id: 9157 - time: '2025-10-26T01:09:43.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/41092 - author: TheGrimbeeper changes: - message: Artifact instantly teleporting themselves fixed. @@ -4070,3 +4063,10 @@ id: 9668 time: '2026-04-25T09:35:40.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/43191 +- author: AffleWaffle + changes: + - message: Fixed Pen Energy dagger not showing it's damage upon activation + type: Fix + id: 9669 + time: '2026-04-25T09:51:50.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/43720 From 6c29a6eecb8fbb7f7b824c52dbf502f2f1d12bd6 Mon Sep 17 00:00:00 2001 From: Tortosaur <135037883+AffleWaffle@users.noreply.github.com> Date: Sat, 25 Apr 2026 12:33:57 +0200 Subject: [PATCH 38/65] SpaceMath (#43721) Space Counting --- Resources/Prototypes/Entities/Clothing/Belt/belts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml index 2fa68934fa..cc820b1f9e 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml @@ -36,7 +36,7 @@ parent: ClothingBeltStorageBase id: ClothingBeltQuiver name: quiver - description: Can hold up to 15 arrows, and fits snug around your waist. + description: Can hold up to 16 arrows, and fits snug around your waist. components: - type: Sprite sprite: Clothing/Belt/quiver.rsi From ab96ec8b2027b35d0bd5ce99ef193483ef48d9d8 Mon Sep 17 00:00:00 2001 From: Samuka <47865393+Samuka-C@users.noreply.github.com> Date: Sat, 25 Apr 2026 19:32:31 -0300 Subject: [PATCH 39/65] SpawnOnBatteryFull component (#43727) * code stuff * fix error * now its fixed * use the charge from the arg * only on battery full * remove whitespace Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * use default! instead of null! Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * use set charge --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- .../Components/SpawnOnBatteryFullComponent.cs | 25 ++++++++++ .../EntitySystems/SpawnOnBatteryFullSystem.cs | 48 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 Content.Server/Power/Components/SpawnOnBatteryFullComponent.cs create mode 100644 Content.Server/Power/EntitySystems/SpawnOnBatteryFullSystem.cs diff --git a/Content.Server/Power/Components/SpawnOnBatteryFullComponent.cs b/Content.Server/Power/Components/SpawnOnBatteryFullComponent.cs new file mode 100644 index 0000000000..f21eaec82e --- /dev/null +++ b/Content.Server/Power/Components/SpawnOnBatteryFullComponent.cs @@ -0,0 +1,25 @@ +using Content.Shared.EntityTable.EntitySelectors; +using Robust.Shared.Prototypes; + +namespace Content.Server.Power.Components; + +/// +/// Spawns a entity when the battery reaches max charge. +/// It also consumes all power when spawning the entity. +/// +[RegisterComponent] +public sealed partial class SpawnOnBatteryFullComponent : Component +{ + /// + /// A entity proto to spawn. + /// + /// Takes priority over + [DataField] + public EntProtoId? Proto; + + /// + /// A entity table to spawn stuff from. + /// + [DataField] + public EntityTableSelector? Table; +} diff --git a/Content.Server/Power/EntitySystems/SpawnOnBatteryFullSystem.cs b/Content.Server/Power/EntitySystems/SpawnOnBatteryFullSystem.cs new file mode 100644 index 0000000000..365e25459c --- /dev/null +++ b/Content.Server/Power/EntitySystems/SpawnOnBatteryFullSystem.cs @@ -0,0 +1,48 @@ +using Content.Server.Power.Components; +using Content.Shared.EntityTable; +using Content.Shared.EntityTable.EntitySelectors; +using Content.Shared.Power; +using Content.Shared.Power.Components; +using Robust.Shared.Prototypes; + +namespace Content.Server.Power.EntitySystems; + +public sealed class SpawnOnBatteryFullSystem : EntitySystem +{ + [Dependency] private readonly BatterySystem _battery = default!; + [Dependency] private readonly EntityTableSystem _entityTable = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnBatteryStateChange); + } + + private void OnBatteryStateChange(Entity entity, ref BatteryStateChangedEvent args) + { + if (args.NewState != BatteryState.Full) + return; + + if (entity.Comp.Proto == null) + SpawnFromEntityTable(entity, entity.Comp.Table); + else + SpawnFromProto(entity, entity.Comp.Proto.Value); + + _battery.SetCharge(entity.Owner, 0); + } + + private void SpawnFromEntityTable(EntityUid entity, EntityTableSelector? table) + { + var spawns = _entityTable.GetSpawns(table); + foreach (var spawn in spawns) + { + Spawn(spawn, Transform(entity).Coordinates); + } + } + + private void SpawnFromProto(EntityUid entity, EntProtoId proto) + { + Spawn(proto, Transform(entity).Coordinates); + } +} From be86aa2b5f68d656da4da7990837eb7fe434a9be Mon Sep 17 00:00:00 2001 From: Sidzaru <110207359+Sidzaru@users.noreply.github.com> Date: Sun, 26 Apr 2026 04:17:43 +0000 Subject: [PATCH 40/65] Fix dupe bug caused by StackSystem (#43738) * Fix dupe bug caused by StackSystem * Removed TryComp --- Content.Shared/Stacks/SharedStackSystem.API.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Content.Shared/Stacks/SharedStackSystem.API.cs b/Content.Shared/Stacks/SharedStackSystem.API.cs index 372255701c..cdb8306a31 100644 --- a/Content.Shared/Stacks/SharedStackSystem.API.cs +++ b/Content.Shared/Stacks/SharedStackSystem.API.cs @@ -26,7 +26,10 @@ public abstract partial class SharedStackSystem ReduceCount(stackEnt, 1); var stackId = _prototype.Index(stackEnt.Comp.StackTypeId); - return PredictedSpawnNextToOrDrop(stackId.Spawn, stackEnt.Owner); + var entityUid = PredictedSpawnNextToOrDrop(stackId.Spawn, stackEnt.Owner); + + SetCount(entityUid, 1); + return entityUid; } #endregion From b99e7c23e9b939c3814eca222286e50a7e07abe9 Mon Sep 17 00:00:00 2001 From: ThatGuyUSA Date: Sun, 26 Apr 2026 00:17:44 -0700 Subject: [PATCH 41/65] Added new AME controller flatpack, deleted unused crates (#43477) * cleanup cleanup everbody cleanup * deleted debug gen crate * YOU FOOL!!! --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- Resources/Maps/Salvage/hauling-shuttle.yml | 7 ---- .../Catalog/Fills/Crates/engines.yml | 13 +------ .../Catalog/Fills/Crates/salvage.yml | 39 ------------------- .../Entities/Objects/Devices/flatpack.yml | 20 ++++++++++ .../Prototypes/Procedural/salvage_rewards.yml | 3 -- Resources/migration.yml | 5 +++ 6 files changed, 26 insertions(+), 61 deletions(-) diff --git a/Resources/Maps/Salvage/hauling-shuttle.yml b/Resources/Maps/Salvage/hauling-shuttle.yml index d90c3c6b42..89e09bb106 100644 --- a/Resources/Maps/Salvage/hauling-shuttle.yml +++ b/Resources/Maps/Salvage/hauling-shuttle.yml @@ -666,13 +666,6 @@ entities: - type: Transform pos: 3.5,-5.5 parent: 1 -- proto: CratePartsT3 - entities: - - uid: 187 - components: - - type: Transform - pos: -2.5,2.5 - parent: 1 - proto: CratePlasma entities: - uid: 191 diff --git a/Resources/Prototypes/Catalog/Fills/Crates/engines.yml b/Resources/Prototypes/Catalog/Fills/Crates/engines.yml index 92a3eabe08..11c5dc30f6 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/engines.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/engines.yml @@ -33,7 +33,7 @@ - type: EntityTableContainerFill containers: entity_storage: - id: AmeControllerUnanchored + id: AmeControllerFlatpack # Singularity @@ -116,17 +116,6 @@ # entity_storage: # id: Singularity -- type: entity - parent: CrateEngineering - id: CrateEngineeringGenerator - name: generator crate - suffix: DEBUG - components: - - type: EntityTableContainerFill - containers: - entity_storage: - id: DebugGenerator # TODO change to flatpack - - type: entity parent: CrateEngineering id: CrateEngineeringSolar diff --git a/Resources/Prototypes/Catalog/Fills/Crates/salvage.yml b/Resources/Prototypes/Catalog/Fills/Crates/salvage.yml index 8e97d530c5..3a4af8a045 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/salvage.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/salvage.yml @@ -207,42 +207,3 @@ containers: entity_storage: id: ClothingNeckCloakSalvagerSupreme - -- type: entity - parent: CrateGenericSteel - id: CratePartsT3 - name: tier 3 parts crate - description: Contains 5 random tier 3 parts for upgrading machines. - # TODO add contents. - #components: - #- type: EntityTableContainerFill - # containers: - # entity_storage: !type:AllSelector - # id: SalvagePartsT3Spawner - # amount: 5 - -- type: entity - parent: CrateGenericSteel - id: CratePartsT3T4 - name: tier 3/4 parts crate - description: Contains 5 random tier 3 or 4 parts for upgrading machines. - # TODO add contents. - #components: - #- type: EntityTableContainerFill - # containers: - # entity_storage: - # id: SalvagePartsT3T4Spawner - # amount: 5 - -- type: entity - parent: CrateGenericSteel - id: CratePartsT4 - name: tier 4 parts crate - description: Contains 5 random tier 4 parts for upgrading machines. - # TODO add contents. - #components: - #- type: EntityTableContainerFill - # containers: - # entity_storage: - # id: SalvagePartsT4Spawner - # amount: 5 diff --git a/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml b/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml index 8034dd0c66..82c3cc7131 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml @@ -50,6 +50,26 @@ - type: StaticPrice price: 75 +- type: entity + parent: BaseFlatpack + id: AmeControllerFlatpack + name: AME controller flatpack + description: A flatpack used for constructing the terminal that controls the antimatter engine. + components: + - type: Sprite + layers: + - state: ame-part + - state: overlay + color: "#EFB341" + - type: Flatpack + entity: AmeController + - type: StaticPrice + price: 1000 + - type: GuideHelp + guides: + - AME + - Power + - type: entity parent: BaseFlatpack id: AmePartFlatpack diff --git a/Resources/Prototypes/Procedural/salvage_rewards.yml b/Resources/Prototypes/Procedural/salvage_rewards.yml index 984ccc26d2..d284f2804d 100644 --- a/Resources/Prototypes/Procedural/salvage_rewards.yml +++ b/Resources/Prototypes/Procedural/salvage_rewards.yml @@ -27,8 +27,6 @@ IngotSilver: 1.0 SheetPlasma: 1.0 SheetUranium: 1.0 - CratePartsT3: 1.0 - CratePartsT3T4: 0.5 TechnologyDiskRare: 0.5 # cloning boards CloningPodMachineCircuitboard: 0.5 @@ -57,7 +55,6 @@ # rare machinery AmmoTechFabCircuitboard: 1.0 ResearchAndDevelopmentServerMachineCircuitboard: 1.0 - CratePartsT4: 1.0 PowerCellAntiqueProto: 0.25 # basic weapons CrateArmorySMG: 1.0 diff --git a/Resources/migration.yml b/Resources/migration.yml index a31ec9ebb0..367afbe92f 100644 --- a/Resources/migration.yml +++ b/Resources/migration.yml @@ -831,3 +831,8 @@ CrateVendingMachineRestockDonutFilled: VendingMachineRestockDonut # 2026-03-28 # The great solutions YAML nuke FoodMeatSnail: MobSnail + +# 2026-04-25 +CratePartsT3: null +CratePartsT3T4: null +CratePartsT4: null From f6eeb88c62ab04e430dd8e749d314ffc773509b6 Mon Sep 17 00:00:00 2001 From: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Date: Sun, 26 Apr 2026 10:37:55 +0200 Subject: [PATCH 42/65] Redo Changeling Identity Networking + New Objective (#43673) * i dont know whether this works or not * holy shit TODO: Devour X identities objective * imports, API cleanup * event * objective * partial review * Update ChangelingIdentitySystem.cs * yippee!! * events * fuck * another one * small fix --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- .../Systems/ChangelingIdentitySystem.cs | 29 ++- .../ChangelingTransformBoundUserInterface.cs | 29 +-- .../Systems/ChangelingIdentitySystem.cs | 37 +++- ...ngelingUniqueIdentityConditionComponent.cs | 17 ++ .../Systems/ChangelingObjectiveSystem.cs | 48 +++++ .../Components/ChangelingDevourComponent.cs | 20 ++ .../Components/ChangelingDevouredComponent.cs | 7 + .../Components/ChangelingIdentityComponent.cs | 116 ++++++++++- .../Systems/ChangelingDevourSystem.cs | 56 +++-- .../Systems/ChangelingTransformSystem.cs | 6 +- .../Systems/SharedChangelingIdentitySystem.cs | 195 +++++++++++++++--- .../Locale/en-US/changeling/changeling.ftl | 1 + .../objectives/conditions/changeling.ftl | 2 + Resources/Prototypes/GameRules/roundstart.yml | 1 + .../Prototypes/Objectives/changeling.yml | 16 ++ 15 files changed, 514 insertions(+), 66 deletions(-) create mode 100644 Content.Server/Objectives/Components/ChangelingUniqueIdentityConditionComponent.cs create mode 100644 Content.Server/Objectives/Systems/ChangelingObjectiveSystem.cs create mode 100644 Resources/Locale/en-US/objectives/conditions/changeling.ftl diff --git a/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs b/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs index 348cfee0f8..270a6a7a84 100644 --- a/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs +++ b/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs @@ -1,6 +1,7 @@ using Content.Shared.Changeling.Components; using Content.Shared.Changeling.Systems; using Robust.Client.GameObjects; +using Robust.Shared.GameStates; namespace Content.Client.Changeling.Systems; @@ -12,11 +13,35 @@ public sealed class ChangelingIdentitySystem : SharedChangelingIdentitySystem { base.Initialize(); - SubscribeLocalEvent(OnAfterAutoHandleState); + SubscribeLocalEvent(OnHandleState); } - private void OnAfterAutoHandleState(Entity ent, ref AfterAutoHandleStateEvent args) + private void OnHandleState(Entity ent, ref ComponentHandleState args) { + if (args.Current is not ChangelingIdentityComponentState state) + return; + + ent.Comp.ConsumedIdentities = new List(); + + foreach (var identity in state.ConsumedIdentities) + { + ChangelingIdentityData data = new() + { + Identity = EnsureEntity(identity.Identity, ent), + Original = EnsureEntity(identity.Original, ent), + OriginalMind = null, // Don't network the mind! + OriginalJob = identity.OriginalJob, + OriginalName = identity.OriginalName, + Starting = identity.Starting, + }; + + ent.Comp.ConsumedIdentities.Add(data); + } + + ent.Comp.CurrentIdentity = EnsureEntity(state.CurrentIdentity, ent); + + ent.Comp.IdentityCloningSettings = state.IdentityCloningSettings; + UpdateUi(ent); } diff --git a/Content.Client/Changeling/UI/ChangelingTransformBoundUserInterface.cs b/Content.Client/Changeling/UI/ChangelingTransformBoundUserInterface.cs index 25cfb1ae82..f2ff3ebb76 100644 --- a/Content.Client/Changeling/UI/ChangelingTransformBoundUserInterface.cs +++ b/Content.Client/Changeling/UI/ChangelingTransformBoundUserInterface.cs @@ -34,13 +34,13 @@ public sealed partial class ChangelingTransformBoundUserInterface(EntityUid owne if (!EntMan.TryGetComponent(Owner, out var lingIdentity)) return; - var models = ConvertToButtons(lingIdentity.ConsumedIdentities.Keys, lingIdentity?.CurrentIdentity); + var models = ConvertToButtons(lingIdentity.ConsumedIdentities, lingIdentity.CurrentIdentity); _menu.SetButtons(models); } private IEnumerable ConvertToButtons( - IEnumerable identities, + IEnumerable identities, EntityUid? currentIdentity ) { @@ -49,25 +49,28 @@ public sealed partial class ChangelingTransformBoundUserInterface(EntityUid owne foreach (var identity in identities) { + if (identity.Identity == null) + continue; + // Options for selecting identities. - var option = new RadialMenuActionOption(SendIdentitySelect, EntMan.GetNetEntity(identity)) + var option = new RadialMenuActionOption(SendIdentitySelect, EntMan.GetNetEntity(identity.Identity.Value)) { - IconSpecifier = RadialMenuIconSpecifier.With(identity), - ToolTip = Loc.GetString("changeling-transform-bui-select-entity", ("entity", identity)), - BackgroundColor = (currentIdentity == identity) ? SelectedOptionBackground : null, // mark as selected - HoverBackgroundColor = (currentIdentity == identity) ? SelectedOptionHoverBackground : null + IconSpecifier = RadialMenuIconSpecifier.With(identity.Identity.Value), + ToolTip = Loc.GetString("changeling-transform-bui-select-entity", ("entity", identity.Identity)), + BackgroundColor = (currentIdentity == identity.Identity) ? SelectedOptionBackground : null, // mark as selected + HoverBackgroundColor = (currentIdentity == identity.Identity) ? SelectedOptionHoverBackground : null }; buttons.Add(option); // Options for dropping identities. - var dropOption = new RadialMenuActionOption(SendIdentityDrop, EntMan.GetNetEntity(identity)) + var dropOption = new RadialMenuActionOption(SendIdentityDrop, EntMan.GetNetEntity(identity.Identity.Value)) { - IconSpecifier = RadialMenuIconSpecifier.With(identity), - ToolTip = (currentIdentity == identity) + IconSpecifier = RadialMenuIconSpecifier.With(identity.Identity.Value), + ToolTip = (currentIdentity == identity.Identity) ? Loc.GetString("changeling-transform-bui-drop-identity-cannot-drop") - : Loc.GetString("changeling-transform-bui-drop-identity-entity", ("entity", identity)), - BackgroundColor = (currentIdentity == identity) ? DisabledOptionBackground : null, // cannot drop your current identity - HoverBackgroundColor = (currentIdentity == identity) ? DisabledOptionHoverBackground : null + : Loc.GetString("changeling-transform-bui-drop-identity-entity", ("entity", identity.Identity)), + BackgroundColor = (currentIdentity == identity.Identity) ? DisabledOptionBackground : null, // cannot drop your current identity + HoverBackgroundColor = (currentIdentity == identity.Identity) ? DisabledOptionHoverBackground : null }; dropButtons.Add(dropOption); } diff --git a/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs b/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs index 8cb3dec3d6..36b681015a 100644 --- a/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs +++ b/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs @@ -1,5 +1,40 @@ +using Content.Shared.Changeling.Components; using Content.Shared.Changeling.Systems; +using Robust.Shared.GameStates; namespace Content.Server.Changeling.Systems; -public sealed class ChangelingIdentitySystem : SharedChangelingIdentitySystem; +public sealed class ChangelingIdentitySystem : SharedChangelingIdentitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnGetState); + } + + private void OnGetState(Entity entity, ref ComponentGetState args) + { + List sentIdentities = new(); + + foreach (var identity in entity.Comp.ConsumedIdentities) + { + ChangelingNetworkedIdentityData netData = new() + { + Identity = GetNetEntity(identity.Identity), + Original = GetNetEntity(identity.Original), + OriginalJob = identity.OriginalJob, + OriginalName = identity.Original != null ? Name(identity.Original.Value) : string.Empty, + Starting = identity.Starting, + }; + + sentIdentities.Add(netData); + } + + var current = entity.Comp.CurrentIdentity; + + var netCurrent = GetNetEntity(current); + + args.State = new ChangelingIdentityComponentState(sentIdentities, netCurrent, entity.Comp.IdentityCloningSettings); + } +} diff --git a/Content.Server/Objectives/Components/ChangelingUniqueIdentityConditionComponent.cs b/Content.Server/Objectives/Components/ChangelingUniqueIdentityConditionComponent.cs new file mode 100644 index 0000000000..7e76d3a02a --- /dev/null +++ b/Content.Server/Objectives/Components/ChangelingUniqueIdentityConditionComponent.cs @@ -0,0 +1,17 @@ +using Content.Server.Objectives.Systems; + +namespace Content.Server.Objectives.Components; + +/// +/// Requires that a changeling has obtained X unique identities. +/// Depends on to function. +/// +[RegisterComponent, Access(typeof(ChangelingObjectiveSystem))] +public sealed partial class ChangelingUniqueIdentityConditionComponent : Component +{ + /// + /// The amount of identities that have been already devoured. + /// + [DataField] + public int UniqueIdentities; +} diff --git a/Content.Server/Objectives/Systems/ChangelingObjectiveSystem.cs b/Content.Server/Objectives/Systems/ChangelingObjectiveSystem.cs new file mode 100644 index 0000000000..451e56426c --- /dev/null +++ b/Content.Server/Objectives/Systems/ChangelingObjectiveSystem.cs @@ -0,0 +1,48 @@ +using Content.Server.Objectives.Components; +using Content.Shared.Changeling.Components; +using Content.Shared.Mind; +using Content.Shared.Objectives.Components; + +namespace Content.Server.Objectives.Systems; + +public sealed class ChangelingObjectiveSystem : EntitySystem +{ + [Dependency] private readonly NumberObjectiveSystem _number = default!; + [Dependency] private readonly SharedMindSystem _mind = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnGetProgress); + SubscribeLocalEvent(OnChangelingDevoured); + } + + private void OnChangelingDevoured(ref ChangelingDevouredEvent args) + { + if (!args.Unique) + return; + + if (!_mind.TryGetObjectiveComp(args.Changeling, out var obj)) + return; + + obj.UniqueIdentities++; + } + + private void OnGetProgress(Entity ent, ref ObjectiveGetProgressEvent args) + { + args.Progress = GetProgress(ent.Comp, _number.GetTarget(ent)); + } + + private float GetProgress(ChangelingUniqueIdentityConditionComponent comp, int target) + { + // prevent divide-by-zero + if (target == 0) + return 1f; + + if (comp.UniqueIdentities >= target) + return 1f; + + return (float)comp.UniqueIdentities / (float)target; + } +} diff --git a/Content.Shared/Changeling/Components/ChangelingDevourComponent.cs b/Content.Shared/Changeling/Components/ChangelingDevourComponent.cs index f0a7bb44ba..1f8b3c81d3 100644 --- a/Content.Shared/Changeling/Components/ChangelingDevourComponent.cs +++ b/Content.Shared/Changeling/Components/ChangelingDevourComponent.cs @@ -127,3 +127,23 @@ public sealed partial class ChangelingDevourComponent : Component public override bool SendOnlyToOwner => true; } + +/// +/// Event raised on the changeling and broadcast when a given changeling devours an entity. +/// +/// The changeling devouring this entity. +/// The entity that was devoured. +/// Whether the changeling is going to be given the target's identity after devouring. +/// Whether this entity was eaten by the changeling before. +[ByRefEvent] +public record struct ChangelingDevouredEvent(EntityUid Changeling, EntityUid Devoured, bool ObtainedIdentity, bool Unique); + +/// +/// Event raised on an entity when devoured by a changeling. +/// +/// The changeling devouring this entity. +/// The entity that was devoured. +/// Whether the changeling is going to be given the target's identity after devouring. +/// Whether this entity was eaten by the changeling before. +[ByRefEvent] +public record struct ChangelingGotDevouredEvent(EntityUid Changeling, EntityUid Devoured, bool ObtainedIdentity, bool Unique); diff --git a/Content.Shared/Changeling/Components/ChangelingDevouredComponent.cs b/Content.Shared/Changeling/Components/ChangelingDevouredComponent.cs index c235ea071a..f25489fe1f 100644 --- a/Content.Shared/Changeling/Components/ChangelingDevouredComponent.cs +++ b/Content.Shared/Changeling/Components/ChangelingDevouredComponent.cs @@ -9,6 +9,13 @@ namespace Content.Shared.Changeling.Components; [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class ChangelingDevouredComponent : Component { + /// + /// Whether this entity has been devoured recently. + /// Gets set back to False when the entity with this component becomes again. + /// + [DataField, AutoNetworkedField] + public bool Recent; + /// /// HashSet of all changelings that have devoured this entity. /// diff --git a/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs b/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs index bef822b720..f202365740 100644 --- a/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs +++ b/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs @@ -1,6 +1,8 @@ using Content.Shared.Cloning; +using Content.Shared.Roles; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; namespace Content.Shared.Changeling.Components; @@ -8,22 +10,24 @@ namespace Content.Shared.Changeling.Components; /// The storage component for Changelings, it handles the link between a changeling and its consumed identities /// that exist on a paused map. /// -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(raiseAfterAutoHandleState: true)] +[RegisterComponent, NetworkedComponent] public sealed partial class ChangelingIdentityComponent : Component { /// - /// The list of entities that exist on a paused map. They are paused clones of the victims that the ling has consumed, with all relevant components copied from the original. - /// The key is the EntityUid of the stored identity, the value is the original entity the identity came from. - /// The value will be set to null if that entity is deleted. + /// List containing data regarding all devoured identities. + /// The identities are paused clones of the victims that the ling has consumed, with all relevant components copied from the original. /// - // TODO: This should be handled via a relation system in the future. - [DataField, AutoNetworkedField] - public Dictionary ConsumedIdentities = new(); + /// + /// Entries in this list do not get deleted for keeping track of total and unique identities. + /// To check if an identity is valid compare to null. + /// + [DataField] + public List ConsumedIdentities = new(); /// /// The currently assumed identity. /// - [DataField, AutoNetworkedField] + [DataField] public EntityUid? CurrentIdentity; /// @@ -35,3 +39,99 @@ public sealed partial class ChangelingIdentityComponent : Component public override bool SendOnlyToOwner => true; } + +[Serializable, NetSerializable] +public sealed class ChangelingIdentityComponentState : ComponentState +{ + public List ConsumedIdentities; + public NetEntity? CurrentIdentity; + + public ProtoId IdentityCloningSettings; + + public ChangelingIdentityComponentState(List consumedIdentities, + NetEntity? currentIdentity, + ProtoId identityCloningSettings) + { + ConsumedIdentities = consumedIdentities; + CurrentIdentity = currentIdentity; + IdentityCloningSettings = identityCloningSettings; + } +} + +/// +/// Stores data related to an identity a changeling has devoured. +/// +[DataDefinition] +public sealed partial class ChangelingIdentityData +{ + /// + /// The stored identity used for cloning appearance and components. + /// Set to null if the identity is ever deleted. + /// + [DataField] + public EntityUid? Identity; + + /// + /// The original entity that was devoured to obtain this identity. + /// Set to null if the entity is ever deleted. + /// + [DataField] + public EntityUid? Original; + + /// + /// The mind of the original entity that was devoured to obtain this identity. + /// Always null on Client. + /// + [DataField] + public EntityUid? OriginalMind; + + /// + /// Job prototype of the original entity at the time of devouring. + /// + [DataField] + public ProtoId? OriginalJob; + + /// + /// Name of the original entity at the time of being devoured. + /// + [DataField] + public string OriginalName = "Unnamed"; + + /// + /// Whether this is the identity the entity started with. + /// + [DataField] + public bool Starting = false; + + /// + /// Convert to a string representation. This if for logging & debugging. This is not localized and should not be + /// shown to players. + /// + public override string ToString() + { + return $"{OriginalName} ({OriginalJob ?? "Unknown"}) - {Original}"; + } +} + +/// +/// A net-serializable version of used for networking purposes. +/// It needs to be like this because EntityUid cannot be networked, so we convert it to NetEntity and send it over to the client using this class. +/// +[Serializable, NetSerializable] +public sealed partial class ChangelingNetworkedIdentityData +{ + [DataField] + public NetEntity? Identity; + + [DataField] + public NetEntity? Original; + + [DataField] + public ProtoId? OriginalJob; + + [DataField] + public string OriginalName = ""; + + [DataField] + public bool Starting; +} diff --git a/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs b/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs index e0cb17f51f..588eedb6a3 100644 --- a/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs +++ b/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs @@ -1,3 +1,4 @@ +using System.Linq; using Content.Shared.Actions; using Content.Shared.Administration.Logs; using Content.Shared.Armor; @@ -59,8 +60,7 @@ public sealed class ChangelingDevourSystem : EntitySystem private void OnDevourAction(Entity ent, ref ChangelingDevourActionEvent args) { if (args.Handled - || _whitelistSystem.IsWhitelistFailOrNull(ent.Comp.Whitelist, args.Target) - || !HasComp(ent)) + || _whitelistSystem.IsWhitelistFailOrNull(ent.Comp.Whitelist, args.Target)) return; args.Handled = true; @@ -167,27 +167,39 @@ public sealed class ChangelingDevourSystem : EntitySystem _adminLogger.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(ent.Owner):player} successfully devoured {ToPrettyString(target):player}'s identity"); - if (!TryComp(ent.Owner, out var identityStorage)) - return; + // If this entity has never been devoured before, it counts as unique. + var unique = !_changelingIdentitySystem.TryGetDataFromOriginal(ent.Owner, target, out _); - _changelingIdentitySystem.CloneToPausedMap((ent, identityStorage), target); + // Even if not unique, target is supposed to give us an identity if it is not currently in our identity list. + var becomesIdentity = !HasIdentity(ent.Owner, target); - // We add a reference to ourselves to prevent repeated identity gain. - var targetDevoured = EnsureComp(target); - targetDevoured.DevouredBy.Add(ent.Owner); - Dirty(target, targetDevoured); - Dirty(ent); + var ev = new ChangelingDevouredEvent(ent.Owner, target, becomesIdentity, unique); + RaiseLocalEvent(ent, ref ev, true); // We broadcast the event to allow relevant objectives to update. + + var devouredEv = new ChangelingGotDevouredEvent(ent.Owner, target, becomesIdentity, unique); + RaiseLocalEvent(target, ref devouredEv); // Don't broadcast this one, all neccessary data is in the previous event already. Just use that one if a broadcast is needed. } /// - /// Has the given victim been devoured by the given changeling before? + /// Whether the given changeling has a valid identity of the given entity. /// - public bool HasDevoured(Entity changeling, EntityUid devoured) + public bool HasIdentity(Entity changeling, EntityUid devoured) { if (!Resolve(changeling, ref changeling.Comp, false)) return false; - return changeling.Comp.ConsumedIdentities.ContainsValue(devoured); + return changeling.Comp.ConsumedIdentities.FirstOrDefault(data => data.Original == devoured && data.Identity != null) != null; + } + + /// + /// Has this entity been devoured by a changeling already before getting revived? + /// + public bool WasDevouredRecently(Entity entity) + { + if (!Resolve(entity, ref entity.Comp, false)) + return false; + + return entity.Comp.Recent; } /// @@ -208,10 +220,10 @@ public sealed class ChangelingDevourSystem : EntitySystem return false; } - if (HasDevoured(changeling.Owner, victim)) + if (WasDevouredRecently(victim)) { if (showPopup) - _popupSystem.PopupClient(Loc.GetString("changeling-devour-attempt-failed-already-devoured"), changeling.Owner, changeling.Owner, PopupType.Medium); + _popupSystem.PopupClient(Loc.GetString("changeling-devour-attempt-failed-devoured-recently"), changeling.Owner, changeling.Owner, PopupType.Medium); return false; } @@ -261,4 +273,18 @@ public sealed class ChangelingDevourSystem : EntitySystem return false; } + + /// + /// Checks whether this changeling has devoured the target entity at any point before. + /// + /// The changeling. + /// The target entity. + /// True if target was previously devoured, False otherwise. + public bool IsUniqueDevour(Entity ent, EntityUid devoured) + { + if (!Resolve(ent, ref ent.Comp, false)) + return false; + + return _changelingIdentitySystem.TryGetDataFromOriginal(ent, devoured, out _); + } } diff --git a/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs b/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs index 8ec2d36cd8..28eb55110e 100644 --- a/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs +++ b/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs @@ -70,7 +70,7 @@ public sealed partial class ChangelingTransformSystem : EntitySystem if (!TryComp(ent, out var userInterfaceComp)) return; - if (!TryComp(ent, out var userIdentity)) + if (!HasComp(ent)) return; if (!_ui.IsUiOpen((ent, userInterfaceComp), ChangelingTransformUiKey.Key, args.Performer)) @@ -93,7 +93,7 @@ public sealed partial class ChangelingTransformSystem : EntitySystem if (identity.CurrentIdentity == targetIdentity) return; // don't transform into ourselves - if (!identity.ConsumedIdentities.ContainsKey(targetIdentity.Value)) + if (!_changelingIdentity.TryGetDataFromIdentity((ent.Owner, identity), targetIdentity.Value, out _)) return; // this identity does not belong to this player TransformInto(ent.AsNullable(), targetIdentity.Value); @@ -111,7 +111,7 @@ public sealed partial class ChangelingTransformSystem : EntitySystem if (identity.CurrentIdentity == targetIdentity) return; // don't drop our current identity - if (!identity.ConsumedIdentities.ContainsKey(targetIdentity.Value)) + if (!_changelingIdentity.TryGetDataFromIdentity((ent.Owner, identity), targetIdentity.Value, out _)) return; // this identity does not belong to this player _popup.PopupClient(Loc.GetString("changeling-transform-bui-drop-identity-entity-popup", ("entity", targetIdentity.Value)), ent.Owner, PopupType.Large); diff --git a/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs b/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs index 8e28cd48ad..60ea667cf7 100644 --- a/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs +++ b/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs @@ -1,6 +1,10 @@ -using System.Linq; +using System.Diagnostics.CodeAnalysis; +using System.Linq; using Content.Shared.Changeling.Components; using Content.Shared.Cloning; +using Content.Shared.Mind; +using Content.Shared.Mobs; +using Content.Shared.Roles.Jobs; using Robust.Shared.GameStates; using Robust.Shared.Map; using Robust.Shared.Network; @@ -16,6 +20,8 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem [Dependency] private readonly SharedCloningSystem _cloningSystem = default!; [Dependency] private readonly SharedMapSystem _map = default!; [Dependency] private readonly SharedPvsOverrideSystem _pvsOverrideSystem = default!; + [Dependency] private readonly SharedMindSystem _mind = default!; + [Dependency] private readonly SharedJobSystem _job = default!; public MapId? PausedMapId; @@ -27,9 +33,27 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem SubscribeLocalEvent(OnShutdown); SubscribeLocalEvent(OnPlayerAttached); SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnDevouredEntity); SubscribeLocalEvent(OnStoredRemove); SubscribeLocalEvent(OnDevouredShutdown); + SubscribeLocalEvent(OnDevouredMobState); + } + + private void OnDevouredEntity(Entity ent, ref ChangelingDevouredEvent args) + { + // We're not supposed to be given an identity. + if (!args.ObtainedIdentity) + return; + + CloneToPausedMap(ent, args.Devoured); + + // We add a reference to ourselves to prevent repeated identity gain. + var targetDevoured = EnsureComp(args.Devoured); + targetDevoured.DevouredBy.Add(ent.Owner); + targetDevoured.Recent = true; + Dirty(args.Devoured, targetDevoured); + Dirty(ent); } private void OnPlayerAttached(Entity ent, ref PlayerAttachedEvent args) @@ -45,8 +69,14 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem private void OnMapInit(Entity ent, ref MapInitEvent args) { // Make a backup of our current identity so we can transform back. - var clone = CloneToPausedMap(ent, ent.Owner); - ent.Comp.CurrentIdentity = clone; + CloneToPausedMap(ent, ent.Owner); + + if (!TryGetDataFromOriginal(ent.AsNullable(), ent, out var data)) + return; + + data.Starting = true; + + ent.Comp.CurrentIdentity = data.Identity; } private void OnShutdown(Entity ent, ref ComponentShutdown args) @@ -66,21 +96,20 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem if (!TryComp(ling, out var identityComp)) continue; - var keysToUpdate = identityComp.ConsumedIdentities - .Where(kvp => kvp.Value == ent.Owner) - .Select(kvp => kvp.Key) - .ToList(); - - if (keysToUpdate.Count == 0) - continue; // No need to dirty. - - foreach (var key in keysToUpdate) - identityComp.ConsumedIdentities[key] = null; - - Dirty(ling, identityComp); + RemoveOriginalReference((ling, identityComp), ent); } } + private void OnDevouredMobState(Entity ent, ref MobStateChangedEvent args) + { + // Once we are revived the body is no longer "recent". + if (args.NewMobState != MobState.Alive) + return; + + ent.Comp.Recent = false; + Dirty(ent); + } + private void OnStoredRemove(Entity ent, ref ComponentRemove args) { // The last stored identity is being deleted, we can clean up the map. @@ -99,7 +128,7 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem foreach (var consumedIdentity in ent.Comp.ConsumedIdentities) { - QueueDel(consumedIdentity.Key); + QueueDel(consumedIdentity.Identity); } } @@ -109,16 +138,32 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem /// The changeling entity private void CleanupDevouredReferences(Entity ent) { - foreach (var devouredUid in ent.Comp.ConsumedIdentities.Values) + foreach (var devouredUid in ent.Comp.ConsumedIdentities) { - if (!TryComp(devouredUid, out var devouredComp)) + if (!TryComp(devouredUid.Original, out var devouredComp)) continue; if (devouredComp.DevouredBy.Remove(ent.Owner)) - Dirty(devouredUid.Value, devouredComp); + Dirty(devouredUid.Original.Value, devouredComp); } } + /// + /// Removes reference to an original entity from . + /// + /// The changeling. + /// The entity to remove from identity originals. + private void RemoveOriginalReference(Entity ent, EntityUid original) + { + foreach (var identity in ent.Comp.ConsumedIdentities) + { + if (identity.Original == original) + identity.Original = null; + } + + Dirty(ent); + } + /// /// Clone a target humanoid to a paused map. /// It creates a perfect copy of the target and can be used to pull components down for future use. @@ -161,10 +206,18 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem if (clone == null) return null; - ent.Comp.ConsumedIdentities.Add(clone.Value, target); + // We see if we already have a identity slot for this entity. + // This can happen if we devoured them before, but then dropped their stored identity. + if (!TryGetDataFromOriginal(ent.AsNullable(), target, out var newIdentity)) + { + newIdentity = new ChangelingIdentityData(); + ent.Comp.ConsumedIdentities.Add(newIdentity); + } + + UpdateIdentityData(newIdentity, clone.Value, target); - Dirty(ent); HandlePvsOverride(ent, clone.Value); + Dirty(ent); return clone; } @@ -180,9 +233,25 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem if (!HasComp(identity)) return; // Not a stored identity. + var toDrop = ent.Comp.ConsumedIdentities.Where(data => data.Identity == identity).ToList(); + + foreach (var dropped in toDrop) + { + if (TryComp(dropped.Original, out var devoured)) + { + if (devoured.DevouredBy.Remove(ent)) + Dirty(dropped.Original.Value, devoured); + } + + dropped.Identity = null; + } + PredictedQueueDel(identity); - if (ent.Comp.ConsumedIdentities.Remove(identity)) + + if (toDrop.Count > 0) + { Dirty(ent); + } } /// @@ -207,7 +276,10 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem { foreach (var identity in ent.Comp.ConsumedIdentities) { - _pvsOverrideSystem.RemoveSessionOverride(identity.Key, session); + if (identity.Identity == null) + continue; + + _pvsOverrideSystem.RemoveSessionOverride(identity.Identity.Value, session); } } @@ -220,7 +292,10 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem { foreach (var identity in ent.Comp.ConsumedIdentities) { - _pvsOverrideSystem.AddSessionOverride(identity.Key, session); + if (identity.Identity == null) + continue; + + _pvsOverrideSystem.AddSessionOverride(identity.Identity.Value, session); } } @@ -237,4 +312,76 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem PausedMapId = newMapId; _map.SetPaused(mapUid, true); } + + /// + /// Creates a ChangelingIdentityData for given entities. + /// + /// The created identity this is supposed to refer to. + /// The original entity this is supposed to refer to. + /// Identity data based on the given parameters. + public ChangelingIdentityData CreateIdentityData(EntityUid identity, EntityUid original) + { + ChangelingIdentityData identityData = new ChangelingIdentityData(); + UpdateIdentityData(identityData, identity, original); + + return identityData; + } + + /// + /// Updates an existing identity data with information from a new identity and original entity. + /// + /// The existing data. + /// The changeling identity to use. + /// The original entity of the identity. + public void UpdateIdentityData(ChangelingIdentityData data, EntityUid identity, EntityUid original) + { + data.Identity = identity; + data.Original = original; + data.OriginalName = Name(identity); + + var foundMind = _mind.TryGetMind(original, out var mindId, out _); + data.OriginalMind = mindId; + + if (foundMind) + { + _job.MindTryGetJobId(mindId, out var jobId); + data.OriginalJob = jobId; + } + } + + /// + /// Fetches the relevant from an entity's based on the identity's EntityUid. + /// + /// The changeling entity. + /// The identity's EntityUid. + /// The returned if one is found. + /// True if identity data is found, otherwise False. + public bool TryGetDataFromIdentity(Entity ent, EntityUid identity, [NotNullWhen(true)] out ChangelingIdentityData? identityData) + { + identityData = null; + if (!Resolve(ent, ref ent.Comp, false)) + return false; + + identityData = ent.Comp.ConsumedIdentities.FirstOrDefault(data => data.Identity == identity); + + return identityData != null; + } + + /// + /// Fetches the relevant from an entity's based on the original entity's EntityUid. + /// + /// The changeling entity. + /// The original entity's EntityUid. + /// The returned if one is found. + /// True if identity data is found, otherwise False. + public bool TryGetDataFromOriginal(Entity ent, EntityUid original, [NotNullWhen(true)] out ChangelingIdentityData? identityData) + { + identityData = null; + if (!Resolve(ent, ref ent.Comp, false)) + return false; + + identityData = ent.Comp.ConsumedIdentities.FirstOrDefault(data => data.Original == original); + + return identityData != null; + } } diff --git a/Resources/Locale/en-US/changeling/changeling.ftl b/Resources/Locale/en-US/changeling/changeling.ftl index 4c639ec77b..6aa167d5c6 100644 --- a/Resources/Locale/en-US/changeling/changeling.ftl +++ b/Resources/Locale/en-US/changeling/changeling.ftl @@ -5,6 +5,7 @@ roles-antag-changeling-objective = A intelligent predator that assumes the ident # devour changeling-devour-attempt-failed-cannot-devour = We cannot devour this! changeling-devour-attempt-failed-already-devoured = We already consumed this body! +changeling-devour-attempt-failed-devoured-recently = This body is too mangled to devour! changeling-devour-attempt-failed-not-dead = This body yet lives! We cannot consume it alive! changeling-devour-attempt-failed-rotting = This corpse has only rotted biomass. changeling-devour-attempt-failed-protected = This victim's biomass is protected by armor! diff --git a/Resources/Locale/en-US/objectives/conditions/changeling.ftl b/Resources/Locale/en-US/objectives/conditions/changeling.ftl new file mode 100644 index 0000000000..b0418cd040 --- /dev/null +++ b/Resources/Locale/en-US/objectives/conditions/changeling.ftl @@ -0,0 +1,2 @@ +objective-unique-identity-name = Devour {$count} unique humanoids. +objective-unique-identity-description = We must devour {$count} different humanoids for sustenance. diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index 80eeff9cfb..7400f95d34 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -228,6 +228,7 @@ - type: AntagObjectives objectives: - ChangelingSurviveObjective + - ChangelingUniqueIdentityObjective - type: entity id: Revolutionary diff --git a/Resources/Prototypes/Objectives/changeling.yml b/Resources/Prototypes/Objectives/changeling.yml index a1a4612217..f74f027b35 100644 --- a/Resources/Prototypes/Objectives/changeling.yml +++ b/Resources/Prototypes/Objectives/changeling.yml @@ -21,3 +21,19 @@ icon: sprite: Mobs/Species/Human/organs.rsi state: heart-on + +- type: entity + parent: BaseChangelingObjective + id: ChangelingUniqueIdentityObjective + components: + - type: Objective + difficulty: 1 + icon: + sprite: Mobs/Aliens/flesh.rsi + state: golem + - type: NumberObjective + min: 3 + max: 4 + title: objective-unique-identity-name + description: objective-unique-identity-description + - type: ChangelingUniqueIdentityCondition From a2438dee50cf8d6a345aadb0e3d9209860f076f3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 15:55:16 +0200 Subject: [PATCH 43/65] Update Credits (#43734) Co-authored-by: PJBot --- Resources/Credits/GitHub.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Credits/GitHub.txt b/Resources/Credits/GitHub.txt index 01ff4724d6..c49c7e77bb 100644 --- a/Resources/Credits/GitHub.txt +++ b/Resources/Credits/GitHub.txt @@ -1 +1 @@ -0-Anon, 0leshe, 0tito, 0x6273, 11BelowStudio, 12rabbits, 1337dakota, 13spacemen, 154942, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 27alaing, 2DSiggy, 3nderall, 4310v343k, 4dplanner, 5tickman, 612git, 778b, 96flo, aaron, abadaba695, Ablankmann, abregado, Absolute-Potato, Absotively, achookh, Acruid, actioninja, ActiveMammmoth, actually-reb, ada-please, adamsong, Adeinitas, adm2play, Admiral-Obvious-001, adrian, Adrian16199, Ady4ik, Aearo-Deepwater, Aerocrux, Aeshus, Aexolott, Aexxie, AffleWaffle, africalimedrop, afrokada, AftrLite, AgentSmithRadio, Agoichi, ahandleman, Ahion, aiden, aidenkrz, Aidenkrz, Aisu9, ajcm, AJCM-git, AjexRose, Alekshhh, alexalexmax, alexkar598, AlexMorgan3817, alexum418, alexumandxgabriel08x, Alice4267, Alithsko, Alkheemist, alliephante, ALMv1, Alpaccalypse, AlphaQwerty, Altoids1, amatwiedle, amylizzle, Andre19926, Andrew-Fall, AndrewEyeke, AndrewFenriz, AndreyCamper, Androclast, anri, Anzarot121, ApolloVector, Appiah, april-gras, ar4ill, Arcane-Waffle, arcanevaliance, archee1, ArchPigeon, ArchRBX, areitpog, Arendian, areyouconfused, arimah, Arkanic, ArkiveDev, armoks, Arteben, arthropodia, ArthurMousatov, ArtisticRoomba, artur, Artxmisery, ArZarLordOfMango, as334, AshBats, AsikKEsel, AsnDen, asperger-sind, aspiringLich, astriloqua, Atakku, Ataman, august-sun, AutoOtter, AverageNotDoingAnythingEnjoyer, avghdev, AwareFoxy, Awlod, Axionyxx, azloserbits, AzzyIsNotHere, azzyisnothere, B-Kirill, B3CKDOOR, baa14453, BackeTako, BadaBoomie, Bakke, BananaFlambe, Baptr0b0t, BarryNorfolk, BasedUser, baynarikattu, bea, BeatusCrow, bebr3ght, beck-thompson, beesterman, bellwetherlogic, ben, benbryant0, benev0, benjamin-burges, BGare, bhespiritu, bibbly, BigfootBravo, BIGZi0348, bingojohnson, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, blitzthesquishy, Blobadoodle, bloodrizer, Bloody2372, blueDev2, Boaz1111, BobdaBiscuit, BobTheSleder, boiled-water-tsar, Bokser815, bolantej, BombasterDS, Booblesnoot42, Boolean-Buckeye, botanySupremist, brainfood1183, BramvanZijp, Brandon-Huu, breeplayx3, BriBrooo, BRINGit34, brndd, bryce0110, BubblegumBlue, buletsponge, buntobaggins, buunie099, bvelliquette, BWTCK, byondfuckery, c0rigin, c4llv07e, CaasGit, Caconym27, Calecute, Callmore, Camdot, cammusubi, capnsockless, CaptainMaru, captainsqrbeard, Carbonhell, Carolyn3114, Carou02, carteblanche4me, catdotjs, catlord, Catofquestionableethics, CatTheSystem, CawsForConcern, CDWimmer, Centronias, Chaboricks, chairbender, chaisftw, Chaoticaa, Charlese2, charlie, chartman, ChaseFlorom, chavonadelal, Cheackraze, CheddaCheez, cheesePizza2, CheesePlated, Chief-Engineer, chillyconmor, christhirtle, chromiumboy, Chronophylos, Chubbicous, Chubbygummibear, Ciac32, ciaran, citrea, civilCornball, claustro305, Clement-O, cloudyias, clyf, Clyybber, CMDR-Piboy314, cnv41, coco, cohanna, Cohnway, Cojoke-dot, ColdAutumnRain, Colin-Tel, collinlunn, ComicIronic, Compilatron144, CookieMasterT, coolboy911, CoolioDudio, coolmankid12345, Coolsurf6, cooperwallace, corentt, CormosLemming, CrafterKolyan, CraftyRenter, crazybrain23, Crazydave91920, CrazyPhantom779, creadth, CrigCrag, CroilBird, Crotalus, CrudeWax, cryals, CrzyPotato, cubixthree, cutemoongod, Cyberboss, d34d10cc, DaCookieCakes, DadeKuma, Daemon, daerSeebaer, dahnte, dakamakat, DamianX, dangerrevolution, daniel-cr, DanSAussieITS, Daracke, Darkie, DaturoDewitt, david, DawBla, Daxxi3, dch-GH, ddeegan, de0rix, Deahaka, dean, DEATHB4DEFEAT, Deatherd, deathride58, debugok, Decappi, Decortex, Deeeeja, deepdarkdepths, DeepwaterCreations, Deerstop, degradka, Delete69, deltanedas, DenisShvalov, DerbyX, derek, dersheppard, Deserty0, Detintinto, DevilishMilk, devinschubert14, dexlerxd, dffdff2423, DieselMohawk, DieselMohawkTheSequel, digitalic, Dimastra, dimmoon1, DinnerCalzone, DinoWattz, Disp-Dev, DisposableCrewmember42, dissidentbullet, DjfjdfofdjfjD, doc-michael, docnite, Doctor-Cpu, DogZeroX, dolgovmi, dontbetank, Doomsdrayk, Doru991, DoubleRiceEddiedd, DoutorWhite, DR-DOCTOR-EVIL-EVIL, Dragonjspider, dragonryan06, drakewill-CRL, Drayff, dreamlyjack, DrEnzyme, dribblydrone, DrMelon, drongood12, DrSingh, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, DuckManZach, Duddino, dukevanity, duskyjay, Dutch-VanDerLinde, dvir001, dylanstrategie, dylanwhittingham, Dynexust, Easypoller, echo, EchoOfNothing, eclips_e, eden077, EEASAS, Efruit, efzapa, Ekkosangen, ElectroSR, elsie, elthundercloud, Elysium206, emberwinters, Emisse, emmafornash, EmoGarbage404, Endecc, EnrichedCaramel, Entvari, eoineoineoin, ephememory, eris, erohrs2, erorr404v1, Errant-4, ertanic, esguard, estacaoespacialpirata, eternally-confused, eugene, eveloop, ewokswagger, exincore, exp111, f0x-n3rd, F1restar4, FacePluslll, Fahasor, FairlySadPanda, farrellka-dev, FATFSAAM2, Feluk6174, ficcialfaint, Fiftyllama, Fildrance, fillervk, FinnishPaladin, firenamefn, Firewars763, FirinMaLazors, Fishfish458, fl-oz, Flareguy, flashgnash, FlipBrooke, FluffiestFloof, FluffMe, FluidRock, flymo5678, foboscheshir, FoLoKe, fooberticus, ForestNoises, forgotmyotheraccount, forkeyboards, forthbridge, Fortune117, foxhorn, freeman2651, freeze2222, frobnic8, Froffy025, Fromoriss, froozigiusz, FrostMando, FrostRibbon, Fruitsalad, Funce, FungiFellow, FunkySphere, FunTust, Futuristic-OK, GalacticChimp, gamer3107, Gamewar360, gansulalan, GaussiArson, Gaxeer, gbasood, gcoremans, Geekyhobo, gem, genderGeometries, GeneralGaws, Genkail, Gentleman-Bird, geraeumig, Ghagliiarghii, Git-Nivrak, githubuser508, GitHubUser53123, gituhabu, GlassEclipse, Glissadia, GnarpGnarp, GNF54, godisdeadLOL, goet, GoldenCan, Goldminermac, Golinth, golubgik, GoodWheatley, Gorox221, GR1231, gradientvera, graevy, GraniteSidewalk, GreaseMonk, greenrock64, GreyMario, GrownSamoyedDog, GTRsound, gusxyz, Gyrandola, h3half, hamurlik, Hanzdegloker, HappyRoach, happyrobot33, Hardly3D, harikattar, Hayden, he1acdvv, Hebi, Helix-ctrl, helm4142, Henry, HerCoyote23, Hi-Im-Shot, HighTechPuddle, Hitlinemoss, hiucko, hivehum, Hmeister-fake, Hmeister-real, Hobbitmax, hobnob, HoidC, Holinka4ever, holyssss, HoofedEar, Hoolny, hord-brayden, hoshizora-sayo, Hreno, Hrosts, htmlsystem, Huaqas, hubismal, Hugal31, Hyenh, hyperb1, hyperDelegate, hyphenationc, i-justuser-i, iaada, iacore, IamVelcroboy, Ian321, icekot8, icesickleone, iczero, iglov, IgorAnt028, igorsaux, ike709, illersaver, Illiux, Ilushkins33, Ilya246, IlyaElDunaev, imatsoup, IMCB, impubbi, imrenq, imweax, indeano, Injazz, Insineer, insoPL, IntegerTempest, Interrobang01, Intoxicating-Innocence, IProduceWidgets, itsmethom, Itzbenz, iztokbajcar, Jackal298, Jackrost, JackRyd3r, jacksonzck, JackspajfMain, Jacktastic09, Jackw2As, jacob, jamessimo, janekvap-havok, Jark255, Jarmer123, Jaskanbe, JasperJRoth, jbox144, JCGWE30, jerryimmouse, JerryImMouse, Jessetriesagain, jessicamaybe, JesterX666, Jewelots, Jezithyr, jicksaw, JiimBob, JimGamemaster, jimmy12or, JIPDawg, jjtParadox, jkwookee, jmcb, JohnGinnane, JohnJJohn, johnjjohn, johnku1, Jophire, Jopogrechkin, joshepvodka, JpegOfAFrog, jproads, JrInventor05, Jrpl, jukereise, juliangiebel, JustArt1m, JustCone14, justdie12, justin, justintether, JustinTrotter, JustinWinningham, justtne, K-Dynamic, k3yw, Kadeo64, Kaga-404, kaiserbirch, KaiShibaa, kalane15, kalanosh, KamTheSythe, Kanashi-Panda, katzenminer, kbailey-git, Keelin, Keer-Sar, KEEYNy, keikiru, Kelrak, kerisargit, keronshb, KeTuFaisPiKiNut, KIBORG04, KieueCaprie, Kimpes, kin98, KingFroozy, kipdotnet, kira-er, kiri-yoshikage, Kirillcas, Kirus59, Kistras, Kit, Kit0vras, KittenColony, Kittygyat, klaypexx, kleinerstation13, Kmc2000, Ko4ergaPunk, kognise, kokoc9n, komunre, KonstantinAngelov, kontakt, korczoczek, koteq, kotobdev, Kowlin, KrasnoshchekovPavel, kresny, Krosus777, Krunklehorn, Kryyto, Kupie, kxvvv, Kyoth25f, kyupolaris, kzhanik, LaCumbiaDelCoronavirus, lajolico, Lamrr, lanedon, LankLTE, laok233, lapatison, larryrussian, lawdog4817, Lazzi0706, Le-Arctic-Fox, leahcat, leander-0, leonardo-dabepis, leonidussaks, leonsfriedrich, LeoSantich, lettern, LetterN, Level10Cybermancer, LEVELcat, lever1209, LevitatingTree, Lgibb18, lgruthes, liem161, LightVillet, lilazero, liltenhead, linkbro1, LinkUyx, Litraxx, little-meow-meow, LittleBuilderJane, LittleNorthStar, LittleNyanCat, lizelive, ljm862, lmsnoise, localcc, lokachop, lolman360, Lomcastar, Lordbrandon12, LordCarve, LordEclipse, lucas, LucasTheDrgn, luckyshotpictures, LudwigVonChesterfield, luegamer, luizwritescode, LukaSlade, luminight, lunarcomets, Lusatia, Luxeator, lvvova1, Lyndomen, lyroth001, lyxcaster, lzimann, lzk228, M1tht1c, M3739, M4rchy-S, M87S, mac6na6na, MACMAN2003, Macoron, magicalus, magmodius, magnnusson, magnuscrowe, maland1, malchanceux, MaloTV, ManelNavola, manelnavola, Mangohydra, marboww, Markek1, MarkerWicker, marlyn, mastermiller01, matt, Matz05, max, MaxNox7, maylokana, mdrkrg, MDuch369, meara1179, meganerobot, MehimoNemo, Mehnix, MeltedPixel, memeproof, MendaxxDev, Menshin, Mephisto72, MerrytheManokit, Mervill, metalgearsloth, MetalSage, MFMessage, mhamsterr, michaelcu, micheel665, mifia, mikeysaurus, MilenVolf, MilonPL, Minemoder5000, Minty642, minus1over12, Mirino97, mirrorcult, MishaUnity, MissKay1994, MisterImp, MisterMecky, Mith-randalf, Mixelz, mjarduk, MjrLandWhale, mkanke-real, MLGTASTICa, mnva0, moderatelyaware, modern-nm, mohamedwidar, mokiros, momo, Moneyl, monotheonist, Moomoobeef, moony, Morb0, MossyGreySlope, mqole, mr-bo-jangles, Mr0maks, MrFippik, MrPersival, mrrobdemo, mtrs163, muburu, MureixloI, murolem, murphyneko, musicmanvr, MWKane, Myakot, Myctai, N3X15, nabegator, nails-n-tape, Nairodian, Naive817, NakataRin, namespace-Memory, Nannek, naxel11, NazrinNya, neborsh, nekokiwa, neomoth, neutrino-laser, NickPowers43, nikitosych, nikthechampiongr, Nimfar11, ninruB, Nirnael, NIXC, nkokic, NkoKirkto, nmajask, noctyrnal, noelkathegod, noirogen, nok-ko, NonchalantNoob, NoobyLegion, Nopey, NoreUhh, Not-A-Chair, not-gavnaed, NotActuallyMarty, notafet, notquitehadouken, notsodana, noudoit, noverd, Nox38, NuclearWinter, Nuggets219, nukashimika, nuke-haus, NULL882, nullarmo, nyeogmi, Nylux, Nyranu, Nyxilath, och-och, OctoRocket, Ohelig, OldDanceJacket, OliverOtter, onesch, OneZerooo0, OnsenCapy, OnyxTheBrave, opl-, Orange-Winds, OrangeMoronage9622, OrbitSystem07, Orsoniks, osjarw, Ostaf, othymer, OttoMaticode, Owai-Seek, packmore, PAFFhassoocks, paige404, paigemaeforrest, pali6, Palladinium, Pangogie, panzer-iv1, partyaddict, patrikturi, PaulRitter, pavlockblaine03, peccneck, Peptide90, peptron1, perryprog, PeterFuto, PetMudstone, pewter-wiz, pgraycs, PGrayCS, Pgriha, phantom-lily, Pharaz4, philingham, Phill101, Phonix, Phooooooooooooooooooooooooooooooosphate, phunnyguy, PicklOH, PilgrimViis, Pill-U, pinkbat5, Piras314, Pireax, piskaczek, Pissachu, pissdemon, Pixel8-dev, PixeltheAertistContrib, PixelTheKermit, PJB3005, Plasmaguy, plinyvic, Plykiya, poeMota, pofitlo, pointer-to-null, Pok27, poklj, PolterTzi, PoorMansDreams, PopGamer45, portfiend, potato1234x, PotentiallyTom, PotRoastPiggy, Princess-Cheeseballs, ProfanedBane, Prole0, ProPandaBear, ProPeperos, PrPleGoo, ps3moira, Pspritechologist, Psychpsyo, psykana, psykzz, PuceTint, pumkin69, PuroSlavKing, PursuitInAshes, Putnam3145, py01, Pyrovi, qrtDaniil, qrwas, Quantum-cross, quasr-9, quatre, QueerNB, QuietlyWhisper, qwerltaz, Radezolid, RadioMull, Radosvik, Radrark, Rainbeon, Rainfey, RainyGale, Raitononai, Ramlik, RamZ, randy10122, Rane, Ranger6012, Rapidgame7, ravage123321, rbertoche, RedBookcase, Redfire1331, Redict, RedlineTriad, redmushie, RednoWCirabrab, Redrover1760, redspyy, ReeZer2, RemberBM, RemieRichards, RemTim, rene-descartes2021, Renlou, retequizzle, rewafflution, rhailrake, rhsvenson, rich-dunne, RieBi, riggleprime, RIKELOLDABOSS, rinary1, Rinkashikachi, riolume, rlebell33, RobbyTheFish, robinthedragon, robinthegirlthing, Rockdtben, Rohesie, rok-povsic, rokudara-sen, rolfero, RomanNovo, roryflowers, rosieposieeee, Roudenn, router, ruddygreat, rumaks-xyz, RumiTiger, Ruzihm, rwrv, S1rFl0, S1ss3l, Saakra, SabreML, Sadie-silly, saga3152, saintmuntzer, salarua, Salex08, sam, samgithubaccount, Samuka-C, SaphireLattice, SapphicOverload, sarahon, sativaleanne, SaveliyM360, sBasalto, ScalyChimp, ScarKy0, ScholarNZL, schrodinger71, scrato, Scribbles0, scrivoy, scruq445, scuffedjays, ScumbagDog, SeamLesss, Segonist, semensponge, sephtasm, ser1-1y, Serkket, sewerpig, SG6732, sh18rw, Shaddap1, ShadeAware, ShadowCommander, shadowtheprotogen546, shaeone, shampunj, shariathotpatrol, SharkSnake98, Shegare, shepardtothestars, shibechef, Siginanto, signalsender, SignalWalker, siigiil, silicon14wastaken, Silverfur-underscore, Simyon264, sirdragooon, Sirionaut, SirWarock, Sk1tch, SkaldetSkaeg, Skarletto, skeeka-dev, skrybl, Skybailey-dev, skye, Skyedra, SlamBamActionman, slarticodefast, Slava0135, sleepyyapril, slimmslamm, Slyfox333, Smugman, SnappingOpossum, snebl, snicket, sniperchance, Snowni, snowsignal, SolidSyn, SolidusSnek, solstar2, SomegnihT, SonarZeBat, SonicHDC, SoulFN, SoulSloth, Soundwavesghost, soupkilove, southbridge-fur, sowelipililimute, Soydium, SpaceLizard24, SpaceLizardSky, SpaceManiac, SpaceRox1244, SpaceyLady, Spangs04, spanky-spanky, Sparlight, spartak, SpartanKadence, spderman3333, SpeltIncorrectyl, Spessmann, SphiraI, SplinterGP, spoogemonster, sporekto, sporkyz, ssdaniel24, stalengd, stanberytrask, Stanislav4ix, StanTheCarpenter, starbuckss14, Stealthbomber16, steel, Steffo99, stellar-novas, stewie523, stomf, Stop-Signs, stopbreaking, stopka-html, StrawberryMoses, Stray-Pyramid, strO0pwafel, Strol20, StStevens, Subversionary, sunbear-dev, SuperGDPWYL, superjj18, Supernorn, SurrealShibe, SweetAplle, SweptWasTaken, SyaoranFox, Sybil, SYNCHRONIC, Synthestra, Szunti, t, Tainakov, takemysoult, taonewt, tap, TaralGit, Taran, taserthefox, taurie, Tayrtahn, tday93, teamaki, TeenSarlacc, TekuNut, telavivgamers, telyonok, temm1ie, TemporalOroboros, tentekal, terezi4real, Terraspark4941, texcruize, Tezzaide, TGODiamond, TGRCdev, tgrkzus, thanosdegraf, ThatGuyUSA, ThatOneGoblin25, thatrandomcanadianguy, TheArturZh, TheBlueYowie, thecopbennet, TheCze, TheDarkElites, thedraccx, TheEmber, theexetron, TheFlyingSentry, thefoty, TheGrimbeeper, TheIntoxicatedCat, thekilk, themias, theomund, TheProNoob678, TherapyGoth, ThereDrD0, TheSecondLord, TheShuEd, thetolbean, thevinter, TheWaffleJesus, Thinbug0, ThunderBear2006, timothyteakettle, TimrodDX, timurjavid, tin-man-tim, TiniestShark, Titian3, tk-a369, tkdrg, tmtmtl30, ToastEnjoyer, Toby222, TokenStyle, Tollhouse, Toly65, tom-leys, tomasalves8, Tomeno, Tonydatguy, topy, tornado-technology, TornadoTechnology, tosatur, TotallyLemon, ToxicSonicFan04, Tr1bute, travis-g-reid, treytipton, TriviaSolari, trixxedbit, TrixxedHeart, tropicalhibi, truepaintgit, Truoizys, Tryded, TsjipTsjip, tuchila-adi-bogdan, Tunguso4ka, TurboTrackerss14, TVK-04, tyashley, Tyler-IN, TytosB, Tyzemol, UbaserB, Uberration, ubis1, UBlueberry, uhbg, UKNOWH, UltimateJester, Unbelievable-Salmon, underscorex5, UnicornOnLSD, Unisol, Unkn0wnGh0st333, unusualcrow, UpAndLeaves, Uriende, UristMcDorf, user424242420, Utmanarn, Vaaankas, valentfingerov, valquaint, VanderslootAssgiraffe, Varen, Vasilis, VasilisThePikachu, veliebm, Velken, VelonacepsCalyxEggs, veprolet, VerinSenpai, veritable-calamity, Veritius, Vermidia, vero5123, verslebas, vexerot, viceemargo, VigersRay, violet754, Visne, vitopigno, vitusveit, vlad, vlados1408, VMSolidus, vmzd, VoidMeticulous, voidnull000, volotomite, volundr-, Voomra, Vordenburg, vorkathbruh, Vortebo, vulppine, wachte1, wafehling, walksanatora, Warentan, WarMechanic, Watermelon914, weaversam8, wertanchik, whateverusername0, whatston3, widgetbeck, Will-Oliver-Br, Willhelm53, WilliamECrew, willicassi, Winkarst-cpu, wirdal, wixoaGit, WlarusFromDaSpace, Wolfkey-SomeoneElseTookMyUsername, Worldwaker, wrexbe, wtcwr68, xeri7, xkreksx, xprospero, xRiriq, xsainteer, YanehCheck, yathxyz, Ygg01, YotaXP, youarereadingthis, YoungThugSS14, Yousifb26, youtissoum, yunii, yuriykiss, YuriyKiss, zach-hill, Zadeon, Zalycon, zamp, Zandario, Zap527, Zealith-Gamer, zekins3366, ZelteHonor, zero, ZeroDiamond, ZeWaka, zHonys, zionnBE, ZNixian, Zokkie, ZoldorfTheWizard, zonespace27, Zylofan, Zymem, zzylex +0-Anon, 0leshe, 0tito, 0x6273, 11BelowStudio, 12rabbits, 1337dakota, 13spacemen, 154942, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 27alaing, 2DSiggy, 3nderall, 4310v343k, 4dplanner, 5tickman, 612git, 778b, 96flo, aaron, abadaba695, Ablankmann, abregado, Absolute-Potato, Absotively, achookh, Acruid, actioninja, ActiveMammmoth, actually-reb, ada-please, adamsong, Adeinitas, adm2play, Admiral-Obvious-001, adrian, Adrian16199, Ady4ik, Aearo-Deepwater, Aerocrux, Aeshus, Aexolott, Aexxie, afflewaffle, africalimedrop, afrokada, AftrLite, AgentSmithRadio, Agoichi, ahandleman, Ahion, aiden, Aidenkrz, aidenkrz, Aisu9, ajcm, AJCM-git, AjexRose, Alekshhh, alexalexmax, alexkar598, AlexMorgan3817, alexum418, alexumandxgabriel08x, Alice4267, Alithsko, Alkheemist, alliephante, ALMv1, Alpaccalypse, AlphaQwerty, Altoids1, amatwiedle, amylizzle, Andre19926, Andrew-Fall, AndrewEyeke, AndrewFenriz, AndreyCamper, Androclast, anri, Anzarot121, ApolloVector, Appiah, april-gras, ar4ill, Arcane-Waffle, arcanevaliance, archee1, ArchPigeon, ArchRBX, areitpog, Arendian, areyouconfused, arimah, Arkanic, ArkiveDev, armoks, Arteben, arthropodia, ArthurMousatov, ArtisticRoomba, artur, Artxmisery, ArZarLordOfMango, as334, AshBats, AsikKEsel, AsnDen, asperger-sind, aspiringLich, astriloqua, Atakku, Ataman, august-sun, AutoOtter, AverageNotDoingAnythingEnjoyer, avghdev, AwareFoxy, Awlod, Axionyxx, azloserbits, azzyisnothere, AzzyIsNotHere, B-Kirill, B3CKDOOR, baa14453, BackeTako, BadaBoomie, Bakke, BananaFlambe, Baptr0b0t, BarryNorfolk, BasedUser, baynarikattu, bea, BeatusCrow, bebr3ght, beck-thompson, beesterman, bellwetherlogic, ben, benbryant0, benev0, benjamin-burges, BGare, bhespiritu, bibbly, BigfootBravo, BIGZi0348, bingojohnson, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, blitzthesquishy, Blobadoodle, bloodrizer, Bloody2372, blueDev2, Boaz1111, BobdaBiscuit, BobTheSleder, boiled-water-tsar, Bokser815, bolantej, BombasterDS, Booblesnoot42, Boolean-Buckeye, botanySupremist, brainfood1183, BramvanZijp, Brandon-Huu, breeplayx3, BriBrooo, BRINGit34, brndd, bryce0110, BubblegumBlue, buletsponge, buntobaggins, buunie099, bvelliquette, BWTCK, byondfuckery, c0rigin, c4llv07e, CaasGit, Caconym27, Calecute, Callmore, Camdot, cammusubi, capnsockless, CaptainMaru, captainsqrbeard, Carbonhell, Carolyn3114, Carou02, carteblanche4me, catdotjs, catlord, Catofquestionableethics, CatTheSystem, CawsForConcern, CDWimmer, Centronias, Chaboricks, chairbender, chaisftw, Chaoticaa, Charlese2, charlie, chartman, ChaseFlorom, chavonadelal, Cheackraze, CheddaCheez, cheesePizza2, CheesePlated, Chief-Engineer, chillyconmor, christhirtle, chromiumboy, Chronophylos, Chubbicous, Chubbygummibear, Ciac32, ciaran, citrea, civilCornball, claustro305, Clement-O, cloudyias, clyf, Clyybber, CMDR-Piboy314, cnv41, coco, cohanna, Cohnway, Cojoke-dot, ColdAutumnRain, Colin-Tel, collinlunn, ComicIronic, Compilatron144, CookieMasterT, coolboy911, CoolioDudio, coolmankid12345, Coolsurf6, cooperwallace, corentt, CormosLemming, CrafterKolyan, CraftyRenter, crazybrain23, Crazydave91920, CrazyPhantom779, creadth, CrigCrag, CroilBird, Crotalus, CrudeWax, cryals, CrzyPotato, cubixthree, cutemoongod, Cyberboss, d34d10cc, DaCookieCakes, DadeKuma, Daemon, daerSeebaer, dahnte, dakamakat, DamianX, dangerrevolution, daniel-cr, DanSAussieITS, Daracke, Darkie, DaturoDewitt, david, DawBla, Daxxi3, dch-GH, ddeegan, de0rix, Deahaka, dean, DEATHB4DEFEAT, Deatherd, deathride58, debugok, Decappi, Decortex, Deeeeja, deepdarkdepths, DeepwaterCreations, Deerstop, degradka, Delete69, deltanedas, DenisShvalov, DerbyX, derek, dersheppard, Deserty0, Detintinto, DevilishMilk, devinschubert14, dexlerxd, dffdff2423, DieselMohawk, DieselMohawkTheSequel, digitalic, Dimastra, dimmoon1, DinnerCalzone, DinoWattz, Disp-Dev, DisposableCrewmember42, dissidentbullet, DjfjdfofdjfjD, doc-michael, docnite, Doctor-Cpu, DogZeroX, dolgovmi, dontbetank, Doomsdrayk, Doru991, DoubleRiceEddiedd, DoutorWhite, DR-DOCTOR-EVIL-EVIL, Dragonjspider, dragonryan06, drakewill-CRL, Drayff, dreamlyjack, DrEnzyme, dribblydrone, DrMelon, drongood12, DrSingh, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, DuckManZach, Duddino, dukevanity, duskyjay, Dutch-VanDerLinde, dvir001, dylanstrategie, dylanwhittingham, Dynexust, Easypoller, echo, EchoOfNothing, eclips_e, eden077, EEASAS, Efruit, efzapa, Ekkosangen, ElectroSR, elsie, elthundercloud, Elysium206, emberwinters, Emisse, emmafornash, EmoGarbage404, Endecc, EnrichedCaramel, Entvari, eoineoineoin, ephememory, eris, erohrs2, erorr404v1, Errant-4, ertanic, esguard, estacaoespacialpirata, eternally-confused, eugene, eveloop, ewokswagger, exincore, exp111, f0x-n3rd, F1restar4, FacePluslll, Fahasor, FairlySadPanda, farrellka-dev, FATFSAAM2, Feluk6174, ficcialfaint, Fiftyllama, Fildrance, fillervk, FinnishPaladin, firenamefn, Firewars763, FirinMaLazors, Fishfish458, fl-oz, Flareguy, flashgnash, FlipBrooke, FluffiestFloof, FluffMe, FluidRock, flymo5678, foboscheshir, FoLoKe, fooberticus, ForestNoises, forgotmyotheraccount, forkeyboards, forthbridge, Fortune117, foxhorn, freeman2651, freeze2222, frobnic8, Froffy025, Fromoriss, froozigiusz, FrostMando, FrostRibbon, Fruitsalad, Funce, FungiFellow, FunkySphere, FunTust, Futuristic-OK, GalacticChimp, gamer3107, Gamewar360, gansulalan, GaussiArson, Gaxeer, gbasood, gcoremans, Geekyhobo, gem, genderGeometries, GeneralGaws, Genkail, Gentleman-Bird, geraeumig, Ghagliiarghii, Git-Nivrak, githubuser508, GitHubUser53123, gituhabu, GlassEclipse, Glissadia, GnarpGnarp, GNF54, godisdeadLOL, goet, GoldenCan, Goldminermac, Golinth, golubgik, GoodWheatley, Gorox221, GR1231, gradientvera, graevy, GraniteSidewalk, GreaseMonk, greenrock64, GreyMario, GrownSamoyedDog, GTRsound, gusxyz, Gyrandola, h3half, hamurlik, Hanzdegloker, HappyRoach, happyrobot33, Hardly3D, harikattar, Hayden, he1acdvv, Hebi, Helix-ctrl, helm4142, Henry, HerCoyote23, Hi-Im-Shot, HighTechPuddle, Hitlinemoss, hiucko, hivehum, Hmeister-fake, Hmeister-real, Hobbitmax, hobnob, HoidC, Holinka4ever, holyssss, HoofedEar, Hoolny, hord-brayden, hoshizora-sayo, Hreno, Hrosts, htmlsystem, Huaqas, hubismal, Hugal31, Hyenh, hyperb1, hyperDelegate, hyphenationc, i-justuser-i, iaada, iacore, IamVelcroboy, Ian321, icekot8, icesickleone, iczero, iglov, IgorAnt028, igorsaux, ike709, illersaver, Illiux, Ilushkins33, Ilya246, IlyaElDunaev, imatsoup, IMCB, impubbi, imrenq, imweax, indeano, Injazz, Insineer, insoPL, IntegerTempest, Interrobang01, Intoxicating-Innocence, IProduceWidgets, itsmethom, Itzbenz, iztokbajcar, Jackal298, Jackrost, JackRyd3r, jacksonbailey, jacksonzck, JackspajfMain, Jacktastic09, Jackw2As, jacob, jamessimo, janekvap-havok, Jark255, Jarmer123, Jaskanbe, JasperJRoth, jbox144, JCGWE30, jerryimmouse, JerryImMouse, Jessetriesagain, jessicamaybe, JesterX666, Jewelots, Jezithyr, jicksaw, JiimBob, JimGamemaster, jimmy12or, JIPDawg, jjtParadox, jkwookee, jmcb, JohnGinnane, JohnJJohn, johnjjohn, johnku1, Jophire, Jopogrechkin, joshepvodka, JpegOfAFrog, jproads, JrInventor05, Jrpl, jukereise, juliangiebel, JustArt1m, JustCone14, justdie12, justin, justintether, JustinTrotter, JustinWinningham, justtne, K-Dynamic, k3yw, Kadeo64, Kaga-404, kaiserbirch, KaiShibaa, kalane15, kalanosh, KamTheSythe, Kanashi-Panda, katzenminer, kbailey-git, Keelin, Keer-Sar, KEEYNy, keikiru, Kelrak, kerisargit, keronshb, KeTuFaisPiKiNut, KIBORG04, KieueCaprie, Kimpes, kin98, KingFroozy, kipdotnet, kira-er, kiri-yoshikage, Kirillcas, Kirus59, Kistras, Kit, Kit0vras, KittenColony, Kittygyat, klaypexx, kleinerstation13, Kmc2000, Ko4ergaPunk, kognise, kokoc9n, komunre, KonstantinAngelov, kontakt, korczoczek, koteq, kotobdev, Kowlin, KrasnoshchekovPavel, kresny, Krosus777, Krunklehorn, Kryyto, Kupie, kxvvv, Kyoth25f, kyupolaris, kzhanik, LaCumbiaDelCoronavirus, lajolico, Lamrr, lanedon, LankLTE, laok233, lapatison, larryrussian, lawdog4817, Lazzi0706, Le-Arctic-Fox, leahcat, leander-0, leonardo-dabepis, leonidussaks, leonsfriedrich, LeoSantich, LetterN, lettern, Level10Cybermancer, LEVELcat, lever1209, LevitatingTree, Lgibb18, lgruthes, liem161, LightVillet, lilazero, liltenhead, linkbro1, LinkUyx, Litraxx, little-meow-meow, LittleBuilderJane, LittleNorthStar, LittleNyanCat, lizelive, ljm862, lmsnoise, localcc, lokachop, lolman360, Lomcastar, Lordbrandon12, LordCarve, LordEclipse, lucas, LucasTheDrgn, luckyshotpictures, LudwigVonChesterfield, luegamer, luizwritescode, LukaSlade, luminight, lunarcomets, Lusatia, Luxeator, lvvova1, Lyndomen, lyroth001, lyxcaster, lzimann, lzk228, M1tht1c, M3739, M4rchy-S, M87S, mac6na6na, MACMAN2003, Macoron, magicalus, magmodius, magnnusson, magnuscrowe, maland1, malchanceux, MaloTV, manelnavola, ManelNavola, Mangohydra, marboww, Markek1, MarkerWicker, marlyn, mastermiller01, matt, Matz05, max, MaxNox7, maylokana, mdrkrg, MDuch369, meara1179, meganerobot, MehimoNemo, Mehnix, MeltedPixel, memeproof, MendaxxDev, Menshin, Mephisto72, MerrytheManokit, Mervill, metalgearsloth, MetalSage, MFMessage, mhamsterr, michaelcu, micheel665, mifia, mikeysaurus, MilenVolf, MilonPL, Minemoder5000, Minty642, minus1over12, Mirino97, mirrorcult, MishaUnity, MissKay1994, MisterImp, MisterMecky, Mith-randalf, Mixelz, mjarduk, MjrLandWhale, mkanke-real, MLGTASTICa, mnva0, moderatelyaware, modern-nm, mohamedwidar, mokiros, momo, Moneyl, monotheonist, Moomoobeef, moony, Morb0, MossyGreySlope, mqole, mr-bo-jangles, Mr0maks, MrFippik, MrPersival, mrrobdemo, mtrs163, muburu, MureixloI, murolem, murphyneko, musicmanvr, MWKane, Myakot, Myctai, N3X15, nabegator, nails-n-tape, Nairodian, Naive817, NakataRin, namespace-Memory, Nannek, naxel11, NazrinNya, neborsh, nekokiwa, neomoth, neutrino-laser, NickPowers43, nikitosych, nikthechampiongr, Nimfar11, ninruB, Nirnael, NIXC, nkokic, NkoKirkto, nmajask, noctyrnal, noelkathegod, noirogen, nok-ko, NonchalantNoob, NoobyLegion, Nopey, NoreUhh, Not-A-Chair, not-gavnaed, NotActuallyMarty, notafet, notquitehadouken, notsodana, noudoit, noverd, Nox38, NuclearWinter, Nuggets219, nukashimika, nuke-haus, NULL882, nullarmo, nyeogmi, Nylux, Nyranu, Nyxilath, och-och, OctoRocket, Ohelig, OldDanceJacket, OliverOtter, onesch, OneZerooo0, OnsenCapy, OnyxTheBrave, opl-, Orange-Winds, OrangeMoronage9622, OrbitSystem07, Orsoniks, osjarw, Ostaf, othymer, OttoMaticode, Owai-Seek, packmore, PAFFhassoocks, paige404, paigemaeforrest, pali6, Palladinium, Pangogie, panzer-iv1, partyaddict, patrikturi, PaulRitter, pavlockblaine03, peccneck, Peptide90, peptron1, perryprog, PeterFuto, PetMudstone, pewter-wiz, pgraycs, PGrayCS, Pgriha, phantom-lily, Pharaz4, pheenty, philingham, Phill101, Phonix, Phooooooooooooooooooooooooooooooosphate, phunnyguy, PicklOH, PilgrimViis, Pill-U, pinkbat5, Piras314, Pireax, piskaczek, Pissachu, pissdemon, Pixel8-dev, PixeltheAertistContrib, PixelTheKermit, PJB3005, Plasmaguy, plinyvic, Plykiya, poeMota, pofitlo, pointer-to-null, Pok27, poklj, PolterTzi, PoorMansDreams, PopGamer45, portfiend, potato1234x, PotentiallyTom, PotRoastPiggy, Princess-Cheeseballs, ProfanedBane, Prole0, ProPandaBear, ProPeperos, PrPleGoo, ps3moira, Pspritechologist, Psychpsyo, psykana, psykzz, PuceTint, pumkin69, PuroSlavKing, PursuitInAshes, Putnam3145, py01, Pyrovi, qrtDaniil, qrwas, Quantum-cross, quasr-9, quatre, QueerNB, QuietlyWhisper, qwerltaz, Radezolid, RadioMull, Radosvik, Radrark, Rainbeon, Rainfey, RainyGale, Raitononai, Ramlik, RamZ, randy10122, Rane, Ranger6012, Rapidgame7, ravage123321, rbertoche, RedBookcase, Redfire1331, Redict, RedlineTriad, redmushie, RednoWCirabrab, Redrover1760, redspyy, ReeZer2, RemberBM, RemieRichards, RemTim, rene-descartes2021, Renlou, retequizzle, rewafflution, rhailrake, rhsvenson, rich-dunne, RieBi, riggleprime, RIKELOLDABOSS, rinary1, Rinkashikachi, riolume, rlebell33, RobbyTheFish, robinthedragon, robinthegirlthing, Rockdtben, Rohesie, rok-povsic, rokudara-sen, rolfero, RomanNovo, roryflowers, rosieposieeee, Roudenn, router, ruddygreat, rumaks-xyz, RumiTiger, Ruzihm, rwrv, S1rFl0, S1ss3l, Saakra, SabreML, Sadie-silly, saga3152, saintmuntzer, salarua, Salex08, sam, samgithubaccount, Samuka-C, SaphireLattice, SapphicOverload, sarahon, sativaleanne, SaveliyM360, sBasalto, ScalyChimp, ScarKy0, ScholarNZL, schrodinger71, scrato, Scribbles0, scrivoy, scruq445, scuffedjays, ScumbagDog, SeamLesss, Segonist, semensponge, sephtasm, ser1-1y, Serkket, sewerpig, SG6732, sh18rw, Shaddap1, ShadeAware, ShadowCommander, shadowtheprotogen546, shaeone, shampunj, shariathotpatrol, SharkSnake98, Shegare, shepardtothestars, shibechef, Siginanto, signalsender, SignalWalker, siigiil, silicon14wastaken, Silverfur-underscore, Simyon264, sirdragooon, Sirionaut, SirWarock, Sk1tch, SkaldetSkaeg, Skarletto, skeeka-dev, skrybl, Skybailey-dev, skye, Skyedra, SlamBamActionman, slarticodefast, Slava0135, sleepyyapril, slimmslamm, Slyfox333, Smugman, SnappingOpossum, snebl, snicket, sniperchance, Snowni, snowsignal, SolidSyn, SolidusSnek, solstar2, SomegnihT, SonarZeBat, SonicHDC, SoulFN, SoulSloth, Soundwavesghost, soupkilove, southbridge-fur, sowelipililimute, Soydium, SpaceLizard24, SpaceLizardSky, SpaceManiac, SpaceRox1244, SpaceyLady, Spangs04, spanky-spanky, Sparlight, spartak, SpartanKadence, spderman3333, SpeltIncorrectyl, Spessmann, SphiraI, SplinterGP, spoogemonster, sporekto, sporkyz, ssdaniel24, stalengd, stanberytrask, Stanislav4ix, StanTheCarpenter, starbuckss14, Stealthbomber16, steel, Steffo99, stellar-novas, stewie523, stomf, Stop-Signs, stopbreaking, stopka-html, StrawberryMoses, Stray-Pyramid, strO0pwafel, Strol20, StStevens, Subversionary, sunbear-dev, SuperGDPWYL, superjj18, Supernorn, SurrealShibe, SweetAplle, SweptWasTaken, SyaoranFox, Sybil, SYNCHRONIC, Synthestra, Szunti, t, Tainakov, takemysoult, taonewt, tap, TaralGit, Taran, taserthefox, taurie, Tayrtahn, tday93, teamaki, TeenSarlacc, TekuNut, telavivgamers, telyonok, temm1ie, TemporalOroboros, tentekal, terezi4real, Terraspark4941, texcruize, Tezzaide, TGODiamond, TGRCdev, tgrkzus, thanosdegraf, ThatGuyUSA, ThatOneGoblin25, thatrandomcanadianguy, TheArturZh, TheBlueYowie, thecopbennet, TheCze, TheDarkElites, thedraccx, TheEmber, theexetron, TheFlyingSentry, thefoty, TheGrimbeeper, TheIntoxicatedCat, thekilk, themias, theomund, TheProNoob678, TherapyGoth, ThereDrD0, TheSecondLord, TheShuEd, thetolbean, thevinter, TheWaffleJesus, Thinbug0, ThunderBear2006, timothyteakettle, TimrodDX, timurjavid, tin-man-tim, TiniestShark, Titian3, tk-a369, tkdrg, tmtmtl30, ToastEnjoyer, Toby222, TokenStyle, Tollhouse, Toly65, tom-leys, tomasalves8, Tomeno, Tonydatguy, topy, tornado-technology, TornadoTechnology, tosatur, TotallyLemon, ToxicSonicFan04, Tr1bute, travis-g-reid, treytipton, TriviaSolari, trixxedbit, TrixxedHeart, tropicalhibi, truepaintgit, Truoizys, Tryded, TsjipTsjip, tuchila-adi-bogdan, Tunguso4ka, TurboTrackerss14, TVK-04, tyashley, Tyler-IN, TytosB, Tyzemol, UbaserB, Uberration, ubis1, UBlueberry, uhbg, UKNOWH, UltimateJester, Unbelievable-Salmon, underscorex5, UnicornOnLSD, Unisol, Unkn0wnGh0st333, unusualcrow, UpAndLeaves, Uriende, UristMcDorf, user424242420, Utmanarn, Vaaankas, valentfingerov, valquaint, VanderslootAssgiraffe, Varen, Vasilis, VasilisThePikachu, veliebm, Velken, VelonacepsCalyxEggs, veprolet, VerinSenpai, veritable-calamity, Veritius, Vermidia, vero5123, verslebas, vexerot, viceemargo, VigersRay, violet754, Visne, vitopigno, vitusveit, vlad, vlados1408, VMSolidus, vmzd, VoidMeticulous, voidnull000, volotomite, volundr-, Voomra, Vordenburg, vorkathbruh, Vortebo, vulppine, wachte1, wafehling, walksanatora, Warentan, WarMechanic, Watermelon914, weaversam8, wertanchik, whateverusername0, whatston3, widgetbeck, Will-Oliver-Br, Willhelm53, WilliamECrew, willicassi, Winkarst-cpu, wirdal, wixoaGit, WlarusFromDaSpace, Wolfkey-SomeoneElseTookMyUsername, Worldwaker, wrexbe, wtcwr68, xeri7, xkreksx, xprospero, xRiriq, xsainteer, YanehCheck, yathxyz, Ygg01, YotaXP, youarereadingthis, YoungThugSS14, Yousifb26, youtissoum, yunii, YuriyKiss, yuriykiss, zach-hill, Zadeon, Zalycon, zamp, Zandario, Zap527, Zealith-Gamer, zekins3366, ZelteHonor, zero, ZeroDiamond, ZeWaka, zHonys, zionnBE, ZNixian, Zokkie, ZoldorfTheWizard, zonespace27, Zylofan, Zymem, zzylex From 00d4c4f8feb638ecb303a0964b7fa5552b99b5c8 Mon Sep 17 00:00:00 2001 From: KeTuFaisPiKiNut <85769816+ketufaispikinut@users.noreply.github.com> Date: Sun, 26 Apr 2026 12:58:20 -0400 Subject: [PATCH 44/65] Changeling voice mimicry (#43675) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * working yay * fixed the thing I had removed * there it works * i know my coding I hope * Update Resources/Textures/Interface/Actions/changeling2.rsi/meta.json Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> * Update Content.Server/VoiceMask/VoiceMaskSystem.cs Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> * Update Content.Server/VoiceMask/VoiceMaskSystem.cs Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> * Update Content.Server/VoiceMask/VoiceMaskSystem.cs Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> * Update Content.Server/VoiceMask/VoiceMaskSystem.cs Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> * Apply suggestions from code review oh god you can just do batches oh my god Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> * Update changeling-catalog.ftl new line at EOF * Update changeling.yml same * Update changeling.yml line * Update StoreSystem.Ui.cs * Update StoreSystem.Ui.cs * Update StoreSystem.Ui.cs just reverted it to master * Apply suggestions from code review Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> * Update VoiceMaskSystem.cs there ya go skar * fixed the bug, yay * clean * GITHUB, DO YOUR THING * [DataField] is in the air? WRONG. * minor spelling mistake * all is well all is well sometimes * minor fix * apathy * it works * VIVE LA RÉVOLUTION * minor spelling mistake *dies* * why the fuck are high-rez vest making tests fail * stuff * NEWLINENEWLINENEWLINE * Update Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Content.Server/VoiceMask/VoiceMaskSystem.cs Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --------- Co-authored-by: nomdéraisonnablementlong Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Co-authored-by: ScarKy0 Co-authored-by: beck-thompson Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- .../VoiceMask/VoiceMaskBoundUserInterface.cs | 2 +- .../VoiceMaskNameChangeWindow.xaml.cs | 6 +- Content.Server/VoiceMask/VoiceMaskSystem.cs | 98 ++++++++++++++++-- .../SharedSubdermalImplantSystem.Relays.cs | 8 +- .../Inventory/InventorySystem.Relay.cs | 1 + Content.Shared/Store/SharedStoreSystem.cs | 8 +- .../Systems/TriggerOnMobstateChangeSystem.cs | 10 +- .../VoiceMask/SharedVoiceMaskSystem.cs | 21 +++- .../VoiceMask/VoiceMaskComponent.cs | 19 +++- .../Locale/en-US/changeling/changeling.ftl | 3 + .../Locale/en-US/store/changeling-catalog.ftl | 3 + Resources/Prototypes/Actions/changeling.yml | 14 +++ .../Prototypes/Catalog/changeling_catalog.yml | 14 +++ .../Entities/Mobs/Player/changeling.yml | 11 ++ .../Actions/changeling2.rsi/meta.json | 5 +- .../Actions/changeling2.rsi/mimicry.png | Bin 0 -> 1294 bytes 16 files changed, 194 insertions(+), 29 deletions(-) create mode 100644 Resources/Textures/Interface/Actions/changeling2.rsi/mimicry.png diff --git a/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs b/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs index b2b374cac5..c3cfa8edec 100644 --- a/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs +++ b/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs @@ -52,7 +52,7 @@ public sealed class VoiceMaskBoundUserInterface : BoundUserInterface return; } - _window.UpdateState(cast.Name, cast.Verb, cast.Active, cast.AccentHide); + _window.UpdateState(cast.Name, cast.Verb, cast.Active, cast.AccentHide, cast.TitleText); } protected override void Dispose(bool disposing) diff --git a/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs b/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs index a5e7036283..9f614a4cb3 100644 --- a/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs +++ b/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs @@ -18,11 +18,9 @@ public sealed partial class VoiceMaskNameChangeWindow : FancyWindow private List<(string, string)> _verbs = new(); private string? _verb; - public VoiceMaskNameChangeWindow() { RobustXamlLoader.Load(this); - NameSelectorSet.OnPressed += _ => { OnNameChange?.Invoke(NameSelector.Text); @@ -69,13 +67,13 @@ public sealed partial class VoiceMaskNameChangeWindow : FancyWindow SpeechVerbSelector.SelectId(id); } - public void UpdateState(string name, string? verb, bool active, bool accentHide) + public void UpdateState(string name, string? verb, bool active, bool accentHide, LocId titleText) { NameSelector.Text = name; _verb = verb; ToggleButton.Pressed = active; ToggleAccentButton.Pressed = accentHide; - + Title = Loc.GetString(titleText); for (int id = 0; id < SpeechVerbSelector.ItemCount; id++) { if (string.Equals(verb, SpeechVerbSelector.GetItemMetadata(id))) diff --git a/Content.Server/VoiceMask/VoiceMaskSystem.cs b/Content.Server/VoiceMask/VoiceMaskSystem.cs index a67bfb8b66..58088bbec2 100644 --- a/Content.Server/VoiceMask/VoiceMaskSystem.cs +++ b/Content.Server/VoiceMask/VoiceMaskSystem.cs @@ -31,15 +31,40 @@ public sealed partial class VoiceMaskSystem : EntitySystem [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly IdentitySystem _identity = default!; + /// + /// The name of the client-side type that represents the user interface window. + /// Used for innate voice masks, which need to be able to create their own UIs. + /// + private const string UiGeneratedName = "VoiceMaskBoundUserInterface"; + // CCVar. private int _maxNameLength; public override void Initialize() { base.Initialize(); + + // These events should fire in the order Innate -> Implant -> Inventory + // Transform speaker name events SubscribeLocalEvent>(OnTransformSpeakerNameInventory); SubscribeLocalEvent>(OnTransformSpeakerNameImplant); + SubscribeLocalEvent(OnInnateTransformSpeakerName); + + // See identity attempt events SubscribeLocalEvent>(OnSeeIdentityAttemptEvent); + SubscribeLocalEvent(OnInnateSeeIdentityAttemptEvent); + + // Transform speech events + SubscribeLocalEvent>(OnTransformSpeechInventory, before: [typeof(AccentSystem)]); + SubscribeLocalEvent>(OnTransformSpeechImplant, before: [typeof(AccentSystem)]); + SubscribeLocalEvent(OnTransformSpeech, before: [typeof(AccentSystem)]); + + // Voice mask transform things + SubscribeLocalEvent>((ent, ref ev) => OnVoiceMaskToggledEvent(ent, ref ev.Args)); + SubscribeLocalEvent>((ent, ref ev) => OnVoiceMaskToggledEvent(ent, ref ev.Args)); + SubscribeLocalEvent(OnVoiceMaskToggledEvent); + + // Other events SubscribeLocalEvent(OnImplantImplantedEvent); SubscribeLocalEvent(OnImplantRemovedEventEvent); SubscribeLocalEvent(OnLockToggled); @@ -49,13 +74,45 @@ public sealed partial class VoiceMaskSystem : EntitySystem SubscribeLocalEvent(OnAccentToggle); SubscribeLocalEvent(OnEquip); SubscribeLocalEvent(OpenUI); - SubscribeLocalEvent(OnTransformSpeech, before: [typeof(AccentSystem)]); - SubscribeLocalEvent>(OnTransformSpeechInventory, before: [typeof(AccentSystem)]); - SubscribeLocalEvent>(OnTransformSpeechImplant, before: [typeof(AccentSystem)]); + SubscribeLocalEvent(OnMapInit); Subs.CVar(_cfgManager, CCVars.MaxNameLength, value => _maxNameLength = value, true); } + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + if (!ent.Comp.IsInnate) + return; + + // all masks should be inactive on creation + ent.Comp.Active = false; + + _actions.AddAction(ent, ent.Comp.Action); + _uiSystem.SetUi((ent, null), VoiceMaskUIKey.Key, new InterfaceData(UiGeneratedName)); + _identity.QueueIdentityUpdate(ent.Owner); + } + + /// + /// Toggles this mask off it it isn't the mask turned on + /// + private void OnVoiceMaskToggledEvent(Entity ent, ref VoiceMaskToggledEvent args) + { + // we only toggle when the other mask turns on + if (!args.Active) + return; + + // we don't want the entity turned on to be turned off, and there isn't any work to do if it already inactive + if (ent.Owner == args.Mask || !ent.Comp.Active) + return; + + // turn it off + ent.Comp.Active = false; + + // update the + UpdateUI(ent); + _identity.QueueIdentityUpdate(args.Source); + } + /// /// Hides accent if the voice mask is on and the option to block accents is on /// @@ -77,7 +134,12 @@ public sealed partial class VoiceMaskSystem : EntitySystem private void OnTransformSpeechImplant(Entity entity, ref ImplantRelayEvent args) { - TransformSpeech(entity, args.Event); + TransformSpeech(entity, args.Args); + } + + private void OnInnateTransformSpeakerName(Entity ent, ref TransformSpeakerNameEvent args) + { + TransformVoice(ent, args); } private void OnTransformSpeakerNameInventory(Entity entity, ref InventoryRelayedEvent args) @@ -87,7 +149,15 @@ public sealed partial class VoiceMaskSystem : EntitySystem private void OnTransformSpeakerNameImplant(Entity entity, ref ImplantRelayEvent args) { - TransformVoice(entity, args.Event); + TransformVoice(entity, args.Args); + } + + private void OnInnateSeeIdentityAttemptEvent(Entity entity, ref SeeIdentityAttemptEvent args) + { + if (!entity.Comp.OverrideIdentity || !entity.Comp.Active || !entity.Comp.IsInnate) + return; + + args.NameOverride = GetCurrentVoiceName(entity); } private void OnSeeIdentityAttemptEvent(Entity entity, ref ImplantRelayEvent args) @@ -95,11 +165,12 @@ public sealed partial class VoiceMaskSystem : EntitySystem if (!entity.Comp.OverrideIdentity || !entity.Comp.Active) return; - args.Event.NameOverride = GetCurrentVoiceName(entity); + args.Args.NameOverride = GetCurrentVoiceName(entity); } private void OnImplantImplantedEvent(Entity entity, ref ImplantImplantedEvent ev) { + entity.Comp.Active = false; _identity.QueueIdentityUpdate(ev.Implanted); } @@ -139,7 +210,10 @@ public sealed partial class VoiceMaskSystem : EntitySystem } var nameUpdatedEvent = new VoiceMaskNameUpdatedEvent(entity, entity.Comp.VoiceMaskName, message.Name); - RaiseLocalEvent(message.Actor, ref nameUpdatedEvent); + if (entity.Comp.IsInnate) + RaiseLocalEvent(entity.Owner, ref nameUpdatedEvent); + else + RaiseLocalEvent(message.Actor, ref nameUpdatedEvent); entity.Comp.VoiceMaskName = message.Name; _adminLogger.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(message.Actor):player} set voice of {ToPrettyString(entity):mask}: {entity.Comp.VoiceMaskName}"); @@ -154,14 +228,20 @@ public sealed partial class VoiceMaskSystem : EntitySystem _popupSystem.PopupEntity(Loc.GetString("voice-mask-popup-toggle"), entity, args.Actor); entity.Comp.Active = !entity.Comp.Active; + var ev = new VoiceMaskToggledEvent(entity.Owner, args.Actor, entity.Comp.Active); + RaiseLocalEvent(entity.Owner, ev); + // Update identity because of possible name override _identity.QueueIdentityUpdate(args.Actor); + + UpdateUI(entity); } private void OnAccentToggle(Entity entity, ref VoiceMaskAccentToggleMessage args) { _popupSystem.PopupEntity(Loc.GetString("voice-mask-popup-accent-toggle"), entity, args.Actor); entity.Comp.AccentHide = !entity.Comp.AccentHide; + UpdateUI(entity); } #endregion @@ -171,6 +251,7 @@ public sealed partial class VoiceMaskSystem : EntitySystem if (_lock.IsLocked(uid)) return; + component.Active = false; _actions.AddAction(args.Wearer, ref component.ActionEntity, component.Action, uid); } @@ -191,7 +272,7 @@ public sealed partial class VoiceMaskSystem : EntitySystem private void UpdateUI(Entity entity) { if (_uiSystem.HasUi(entity, VoiceMaskUIKey.Key)) - _uiSystem.SetUiState(entity.Owner, VoiceMaskUIKey.Key, new VoiceMaskBuiState(GetCurrentVoiceName(entity), entity.Comp.VoiceMaskSpeechVerb, entity.Comp.Active, entity.Comp.AccentHide)); + _uiSystem.SetUiState(entity.Owner, VoiceMaskUIKey.Key, new VoiceMaskBuiState(GetCurrentVoiceName(entity), entity.Comp.VoiceMaskSpeechVerb, entity.Comp.Active, entity.Comp.AccentHide, entity.Comp.TitleText)); } #endregion @@ -211,3 +292,4 @@ public sealed partial class VoiceMaskSystem : EntitySystem } #endregion } + diff --git a/Content.Shared/Implants/SharedSubdermalImplantSystem.Relays.cs b/Content.Shared/Implants/SharedSubdermalImplantSystem.Relays.cs index 59e2d1baa1..b92369ab44 100644 --- a/Content.Shared/Implants/SharedSubdermalImplantSystem.Relays.cs +++ b/Content.Shared/Implants/SharedSubdermalImplantSystem.Relays.cs @@ -4,6 +4,7 @@ using Content.Shared.Implants.Components; using Content.Shared.Interaction.Events; using Content.Shared.Mobs; using Content.Shared.Store; +using Content.Shared.VoiceMask; namespace Content.Shared.Implants; @@ -16,6 +17,7 @@ public abstract partial class SharedSubdermalImplantSystem SubscribeLocalEvent(RelayToImplantEvent); SubscribeLocalEvent(RelayToImplantEvent); SubscribeLocalEvent(RelayToImplantEvent); + SubscribeLocalEvent(RelayToImplantEvent); // Ref relays, for when you need to write to the event! SubscribeLocalEvent(RefRelayToImplantEvent); @@ -57,7 +59,7 @@ public abstract partial class SharedSubdermalImplantSystem RaiseLocalEvent(implant, relayEv); } - args = relayEv.Event; + args = relayEv.Args; } } @@ -66,13 +68,13 @@ public abstract partial class SharedSubdermalImplantSystem /// public sealed class ImplantRelayEvent where T : notnull { - public T Event; + public T Args; public readonly EntityUid ImplantedEntity; public ImplantRelayEvent(T ev, EntityUid implantedEntity) { - Event = ev; + Args = ev; ImplantedEntity = implantedEntity; } } diff --git a/Content.Shared/Inventory/InventorySystem.Relay.cs b/Content.Shared/Inventory/InventorySystem.Relay.cs index 8101c19eab..4b2cc098f5 100644 --- a/Content.Shared/Inventory/InventorySystem.Relay.cs +++ b/Content.Shared/Inventory/InventorySystem.Relay.cs @@ -59,6 +59,7 @@ public partial class InventorySystem SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); + SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); diff --git a/Content.Shared/Store/SharedStoreSystem.cs b/Content.Shared/Store/SharedStoreSystem.cs index 315d70d52a..980c27016c 100644 --- a/Content.Shared/Store/SharedStoreSystem.cs +++ b/Content.Shared/Store/SharedStoreSystem.cs @@ -35,9 +35,9 @@ public abstract partial class SharedStoreSystem : EntitySystem SubscribeLocalEvent(OnGetStore); SubscribeLocalEvent>((x, ref y) => { - var ev = y.Event; + var ev = y.Args; OnGetStore(x, ref ev); - y.Event = ev; + y.Args = ev; }); SubscribeLocalEvent>(OnImplantInsertAttempt); SubscribeLocalEvent(OnIntrinsicStoreAction); @@ -56,7 +56,7 @@ public abstract partial class SharedStoreSystem : EntitySystem private void OnImplantInsertAttempt(Entity implant, ref ImplantRelayEvent args) { - var ev = args.Event; + var ev = args.Args; // Only allow insertion if the person implanted is doing the action. if (ev.User == ev.Target) @@ -64,7 +64,7 @@ public abstract partial class SharedStoreSystem : EntitySystem else ev.Cancel(); - args.Event = ev; + args.Args = ev; } private void OnAfterInteract(EntityUid uid, CurrencyComponent component, AfterInteractEvent args) diff --git a/Content.Shared/Trigger/Systems/TriggerOnMobstateChangeSystem.cs b/Content.Shared/Trigger/Systems/TriggerOnMobstateChangeSystem.cs index 3afd03f41a..3d53e161d9 100644 --- a/Content.Shared/Trigger/Systems/TriggerOnMobstateChangeSystem.cs +++ b/Content.Shared/Trigger/Systems/TriggerOnMobstateChangeSystem.cs @@ -31,10 +31,10 @@ public sealed partial class TriggerOnMobstateChangeSystem : TriggerOnXSystem private void OnMobStateRelay(EntityUid uid, TriggerOnMobstateChangeComponent component, ImplantRelayEvent args) { - if (!component.MobState.Contains(args.Event.NewMobState)) + if (!component.MobState.Contains(args.Args.NewMobState)) return; - Trigger.Trigger(uid, component.TargetMobstateEntity ? args.ImplantedEntity : args.Event.Origin, component.KeyOut); + Trigger.Trigger(uid, component.TargetMobstateEntity ? args.ImplantedEntity : args.Args.Origin, component.KeyOut); } /// @@ -56,13 +56,13 @@ public sealed partial class TriggerOnMobstateChangeSystem : TriggerOnXSystem private void OnSuicideRelay(EntityUid uid, TriggerOnMobstateChangeComponent component, ImplantRelayEvent args) { - if (args.Event.Handled) + if (args.Args.Handled) return; if (!component.PreventSuicide) return; - _popup.PopupClient(Loc.GetString("suicide-prevented"), args.Event.Victim); - args.Event.Handled = true; + _popup.PopupClient(Loc.GetString("suicide-prevented"), args.Args.Victim); + args.Args.Handled = true; } } diff --git a/Content.Shared/VoiceMask/SharedVoiceMaskSystem.cs b/Content.Shared/VoiceMask/SharedVoiceMaskSystem.cs index 9d586a5af8..50edcfe207 100644 --- a/Content.Shared/VoiceMask/SharedVoiceMaskSystem.cs +++ b/Content.Shared/VoiceMask/SharedVoiceMaskSystem.cs @@ -1,3 +1,4 @@ +using Content.Shared.Inventory; using Robust.Shared.Serialization; namespace Content.Shared.VoiceMask; @@ -15,13 +16,15 @@ public sealed class VoiceMaskBuiState : BoundUserInterfaceState public readonly string? Verb; public readonly bool Active; public readonly bool AccentHide; + public readonly LocId TitleText; - public VoiceMaskBuiState(string name, string? verb, bool active, bool accentHide) + public VoiceMaskBuiState(string name, string? verb, bool active, bool accentHide, LocId titleText) { Name = name; Verb = verb; Active = active; AccentHide = accentHide; + TitleText = titleText; } } @@ -61,3 +64,19 @@ public sealed class VoiceMaskToggleMessage : BoundUserInterfaceMessage; /// [Serializable, NetSerializable] public sealed class VoiceMaskAccentToggleMessage : BoundUserInterfaceMessage; + +/// +/// Fired when a voice mask is turned on. +/// +/// The voice mask that was turned on +/// The entity that owns the voice mask +/// The new value of the voice mask +public sealed class VoiceMaskToggledEvent(EntityUid mask, EntityUid source, bool active) : IInventoryRelayEvent +{ + public EntityUid Mask = mask; + public EntityUid Source = source; + + public bool Active = active; + + SlotFlags IInventoryRelayEvent.TargetSlots => SlotFlags.WITHOUT_POCKET; +} diff --git a/Content.Shared/VoiceMask/VoiceMaskComponent.cs b/Content.Shared/VoiceMask/VoiceMaskComponent.cs index b53a615094..39e07c8e31 100644 --- a/Content.Shared/VoiceMask/VoiceMaskComponent.cs +++ b/Content.Shared/VoiceMask/VoiceMaskComponent.cs @@ -4,8 +4,9 @@ using Robust.Shared.Prototypes; namespace Content.Shared.VoiceMask; /// -/// This component is for voice mask items! Adding this component to clothing will give the the voice mask UI +/// This component is for voice mask items & voice-masking entities! Adding this component to clothing will give the voice mask UI /// and allow the wearer to change their voice and verb at will. +/// Having this on an entity while the IsInnate field is true will give it an innate voice masking ability. /// /// /// DO NOT use this if you do not want the interface. @@ -48,7 +49,7 @@ public sealed partial class VoiceMaskComponent : Component /// If user's voice is getting changed when they speak. /// [DataField] - public bool Active = true; + public bool Active = false; /// /// If user's accent is getting hidden when they speak. @@ -61,5 +62,19 @@ public sealed partial class VoiceMaskComponent : Component /// [DataField] public bool ChangeIDName = false; + + /// + /// Whether the voice mask is innate to the entity. + /// When added to an entity while this field is set to true, the entity itself will gain the action & UI necessary to change its voice. + /// When this field is set to false, then the entity with this component will be a provider (either through implanting or through wearing) of the voice masking abilities for another entity. + /// + [DataField] + public bool IsInnate = false; + + /// + /// Is used as the title text in the UI. + /// + [DataField] + public LocId TitleText = "voice-mask-name-change-window"; } diff --git a/Resources/Locale/en-US/changeling/changeling.ftl b/Resources/Locale/en-US/changeling/changeling.ftl index 6aa167d5c6..5ad430528c 100644 --- a/Resources/Locale/en-US/changeling/changeling.ftl +++ b/Resources/Locale/en-US/changeling/changeling.ftl @@ -32,5 +32,8 @@ changeling-transform-bui-drop-identity-entity = Drop {$entity} changeling-transform-bui-drop-identity-entity-popup = You dropped {$entity} from your memory. changeling-transform-bui-drop-identity-cannot-drop = You cannot drop your current identity. +# voice mimicry +changeling-voice-mimic-window-title = Voice Mimicry + # other changeling-paused-map-name = Changeling identity storage map diff --git a/Resources/Locale/en-US/store/changeling-catalog.ftl b/Resources/Locale/en-US/store/changeling-catalog.ftl index 07dee0aa33..6ee4f75f21 100644 --- a/Resources/Locale/en-US/store/changeling-catalog.ftl +++ b/Resources/Locale/en-US/store/changeling-catalog.ftl @@ -3,3 +3,6 @@ changeling-catalog-arm-blade-desc = Transform your arm into a terrifying flesh b changeling-catalog-flesh-clothing-name = Flesh Clothing changeling-catalog-flesh-clothing-desc = Your body's surface will adapt to mirror the clothing of any person you are transforming into. However, these clothing items are non-functional and will make you easy to identify as a changeling if someone tries to remove them. Can be toggled. + +changeling-catalog-voice-mimic-name = Voice Mimicry +changeling-catalog-voice-mimic-desc = Change your vocal coords at will to imitate existing (and imaginary) crew members. Perfect for luring in prey. diff --git a/Resources/Prototypes/Actions/changeling.yml b/Resources/Prototypes/Actions/changeling.yml index 6382f4c837..a3175d63b2 100644 --- a/Resources/Prototypes/Actions/changeling.yml +++ b/Resources/Prototypes/Actions/changeling.yml @@ -48,3 +48,17 @@ id: ActionChangelingStore name: DNA Store description: Opens the ability store. + +- type: entity + parent: BaseAction + id: ActionChangelingVoiceMimic + name: Voice Mimicry + description: Model your vocal cords to imitate the voice of someone else. + components: + - type: Action + itemIconStyle: BigAction + icon: + sprite: Interface/Actions/changeling2.rsi + state: mimicry + - type: InstantAction + event: !type:VoiceMaskSetNameEvent diff --git a/Resources/Prototypes/Catalog/changeling_catalog.yml b/Resources/Prototypes/Catalog/changeling_catalog.yml index 57b0addaa6..941ab21536 100644 --- a/Resources/Prototypes/Catalog/changeling_catalog.yml +++ b/Resources/Prototypes/Catalog/changeling_catalog.yml @@ -27,3 +27,17 @@ - !type:ListingLimitedStockCondition stock: 1 productComponents: ChangelingFleshClothingAbilityStoreDummy + +- type: listing + id: ChangelingVoiceMimic + name: changeling-catalog-voice-mimic-name + description: changeling-catalog-voice-mimic-desc + icon: { sprite: /Textures/Interface/Actions/changeling2.rsi, state: mimicry} + cost: + ChangelingDNA: 10 # TODO: Balance this once we have DNA from devour. It's currently cheap for testing purposes. + categories: + - ChangelingAbilities + conditions: + - !type:ListingLimitedStockCondition + stock: 1 + productComponents: ChangelingVoiceMimicDummy diff --git a/Resources/Prototypes/Entities/Mobs/Player/changeling.yml b/Resources/Prototypes/Entities/Mobs/Player/changeling.yml index dcddf77e1f..7deb62238b 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/changeling.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/changeling.yml @@ -34,3 +34,14 @@ belt: ChangelingFleshClothingBelt back: ChangelingFleshClothingBack +- type: entity # dummy prototype for the store listing + id: ChangelingVoiceMimicDummy + categories: [ HideSpawnMenu ] + components: + - type: VoiceMask + action: ActionChangelingVoiceMimic + isInnate: true + changeIDName: false + # this is set to false as to not mess with a changeling's ability to disguise. + accentHide: false + titleText: changeling-voice-mimic-window-title \ No newline at end of file diff --git a/Resources/Textures/Interface/Actions/changeling2.rsi/meta.json b/Resources/Textures/Interface/Actions/changeling2.rsi/meta.json index a9c507fe65..a25bf6b528 100644 --- a/Resources/Textures/Interface/Actions/changeling2.rsi/meta.json +++ b/Resources/Textures/Interface/Actions/changeling2.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Made by ketufaispikinut from a sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 (scientist suit), a sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 (hydro suit) and the changeling ability border/background sprites created by TiniestShark.", + "copyright": "Made by ketufaispikinut from a sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 (scientist suit), a sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 (hydro suit) and the changeling ability border/background sprites created by TiniestShark. Mimicry by ketufaispikinut, based on TiniestShark's textures.", "size": { "x": 32, "y": 32 @@ -12,6 +12,9 @@ }, { "name": "flesh_clothing_alt" + }, + { + "name": "mimicry" } ] } diff --git a/Resources/Textures/Interface/Actions/changeling2.rsi/mimicry.png b/Resources/Textures/Interface/Actions/changeling2.rsi/mimicry.png new file mode 100644 index 0000000000000000000000000000000000000000..4fd4c439bbce97a2e633b86f41bc10ff4b5304c5 GIT binary patch literal 1294 zcmV+p1@ZccP)Px($Vo&&R9Ji^- zP^3t=B9*LyF2t>rV6hu1MW`Dgi;8tI1RDq?NfSaaAv5wOsnN;!oF+uyWX8ptd*{rZ zH`CGsk9+Sq=brPQbMHO(U5g6c8XhheoNWN2#Wvo*chBM}=+^LXS@m~bI0``QKvc`~ zj|;>OMENW8GaucZwg4tZ2FvY?gC9){d7pH|sLx+A+Fc>IC3b|4#r4&Nh}xqndPcb(yb5-^Ft? zjHe#d83Gs^Itjprl>{KOvCdDw-4E53bH-B-IQ_~S`2SV`TDOLW%ahqGJ&_1ESC{G7 zzmF?}{al}(YijUW=*nO}P|fQ2!h&T_X0x2>>e5P|UN{Fp)Uox~=k3;v<)^66+kGN{ z>(g^OtK$m`7Jxm}eGog@L0>!$1e@df^c;m^Nq<1i*pxM+FkpT0xIR6$yS|O*W+*t@ zdTqm^Y?OtkiQJ^gY*zPe6}eg$8GRzRL!nq=prR~!G6PY^W}pE`8IYo$NCZ`LY^Xig zb?FLAVTGsKL~cjRB)~*&hXJa~CqY0^knBbkug}}nk-rT(!T}+t!dE(Su97FIW=8HA zRTXO>sU0ejDhElSHz3-iF&;4VdMo`#8`d@%3aK&#NFa?ET zNvE%u+Q?0w*_!&v3NQ%YOVMH*4usckX|xfqS2)0s$$k=;G4zyA2Z9Sm9YeLzWNPOt zt?ZjJ$;XhZ<-^-0^;~dat@(Zx!2BP(9Pey{Rak0o0dJRNWukPjB6uqeKpe{KL@AFmwKz+w^$(u!GjaAjpWXd2G+m8SD8W7nc%fKg z;_P|6Tn-2_;RKI`PQ3K27MRp5N^`lI(dQ%Y;68dpYI76y2(reG9n){SHQ(nPJ$M zn)l|(5vCSrYjkhUr)qRR?(Z)j+S}9Pt$q9WdT!48AN=iJJ`A(6ZvX%Q07*qoM6N<$ Ef~})p&Hw-a literal 0 HcmV?d00001 From 609488b80f3665af30f9fe2f12247c9f145e1ede Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 26 Apr 2026 17:14:55 +0000 Subject: [PATCH 45/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 464422b795..7ca5ed401f 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: TheGrimbeeper - changes: - - message: Artifact instantly teleporting themselves fixed. - type: Fix - id: 9158 - time: '2025-10-26T10:36:06.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/41049 - author: psykana changes: - message: Toggle internals now uses jetpack only if there's no proper gas tank @@ -4070,3 +4063,10 @@ id: 9669 time: '2026-04-25T09:51:50.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/43720 +- author: ketufaispikinut + changes: + - message: The voice mask and identity implant now start disabled. + type: Tweak + id: 9670 + time: '2026-04-26T17:13:42.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/43675 From 03a40855bea67b931623bf11b11ebc773141dff9 Mon Sep 17 00:00:00 2001 From: Samuka <47865393+Samuka-C@users.noreply.github.com> Date: Sun, 26 Apr 2026 17:08:34 -0300 Subject: [PATCH 46/65] Anchor only on station component (#43716) * shared stuff * server stuff * locale stuff * use the comp for the method call * pass transform comp * use query instead of GetStations * return bool inside the while loop * empty commit * Update Content.Shared/Station/SharedStationSystem.cs --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- .../Construction/AnchorOnlyOnStationSystem.cs | 39 +++++++++++++++++++ .../AnchorOnlyOnStationComponent.cs | 23 +++++++++++ .../Components/AnchorableComponent.cs | 8 +++- .../EntitySystems/AnchorableSystem.cs | 30 +++++++++++++- Content.Shared/Station/SharedStationSystem.cs | 23 +++++++++++ .../en-US/anchorable/anchorable-component.ftl | 2 + 6 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 Content.Server/Construction/AnchorOnlyOnStationSystem.cs create mode 100644 Content.Shared/Construction/Components/AnchorOnlyOnStationComponent.cs diff --git a/Content.Server/Construction/AnchorOnlyOnStationSystem.cs b/Content.Server/Construction/AnchorOnlyOnStationSystem.cs new file mode 100644 index 0000000000..53a2245835 --- /dev/null +++ b/Content.Server/Construction/AnchorOnlyOnStationSystem.cs @@ -0,0 +1,39 @@ +using System.Linq; +using Content.Server.Station.Systems; +using Content.Shared.Construction.Components; +using Robust.Server.GameObjects; + +namespace Content.Server.Construction; + +public sealed class AnchorOnlyOnStationSystem : EntitySystem +{ + [Dependency] private readonly StationSystem _stationSystem = null!; + [Dependency] private readonly TransformSystem _transform = null!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnGridSplit); + } + + private void OnGridSplit(ref GridSplitEvent args) + { + var allGrids = args.NewGrids.ToList(); + + var query = AllEntityQuery(); + while (query.MoveNext(out var ent, out var anchorOnlyOnStationComp, out var entXform)) + { + if (entXform.GridUid == null) + continue; + + if (!allGrids.Contains(entXform.GridUid.Value)) + continue; + + if (_stationSystem.IsOnStation(ent, anchorOnlyOnStationComp.OnlyCountLargestGrid)) + continue; + + _transform.Unanchor(ent, entXform); + } + } +} diff --git a/Content.Shared/Construction/Components/AnchorOnlyOnStationComponent.cs b/Content.Shared/Construction/Components/AnchorOnlyOnStationComponent.cs new file mode 100644 index 0000000000..38fcaa636e --- /dev/null +++ b/Content.Shared/Construction/Components/AnchorOnlyOnStationComponent.cs @@ -0,0 +1,23 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Construction.Components; + +/// +/// If a entity has this component it can only be anchored to the station +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class AnchorOnlyOnStationComponent : Component +{ + /// + /// Pop up message when you try to anchor the entity on any grid that isn't the station grid + /// + [DataField] + public LocId PopupMessageAnchorFail = "anchorable-fail-not-on-station"; + + /// + /// If true, it will only be able to be anchored on the largest grid of a station. + /// If false, it will only be able to anchored on any grid of a station. + /// + [DataField] + public bool OnlyCountLargestGrid = true; +} diff --git a/Content.Shared/Construction/Components/AnchorableComponent.cs b/Content.Shared/Construction/Components/AnchorableComponent.cs index e17a49937a..eccd17289c 100644 --- a/Content.Shared/Construction/Components/AnchorableComponent.cs +++ b/Content.Shared/Construction/Components/AnchorableComponent.cs @@ -39,6 +39,11 @@ namespace Content.Shared.Construction.Components public EntityUid User { get; } public EntityUid Tool { get; } + /// + /// This is shown to the player after the entity fails to anchor or unanchor as a popup + /// + public string? FailMessage; + /// /// Extra delay to add to the do_after. /// Add to this, don't replace it. @@ -46,10 +51,11 @@ namespace Content.Shared.Construction.Components /// public float Delay { get; set; } = 0f; - protected BaseAnchoredAttemptEvent(EntityUid user, EntityUid tool) + protected BaseAnchoredAttemptEvent(EntityUid user, EntityUid tool, string? failMessage = null) { User = user; Tool = tool; + FailMessage = failMessage; } } diff --git a/Content.Shared/Construction/EntitySystems/AnchorableSystem.cs b/Content.Shared/Construction/EntitySystems/AnchorableSystem.cs index 495dddfe69..8892c0f6eb 100644 --- a/Content.Shared/Construction/EntitySystems/AnchorableSystem.cs +++ b/Content.Shared/Construction/EntitySystems/AnchorableSystem.cs @@ -10,6 +10,7 @@ using Content.Shared.Interaction; using Content.Shared.Movement.Pulling.Components; using Content.Shared.Movement.Pulling.Systems; using Content.Shared.Popups; +using Content.Shared.Station; using Content.Shared.Tools.Components; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -29,6 +30,7 @@ public sealed partial class AnchorableSystem : EntitySystem [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly PullingSystem _pulling = default!; [Dependency] private readonly SharedMapSystem _map = default!; + [Dependency] private readonly SharedStationSystem _stationSystem = null!; [Dependency] private readonly SharedToolSystem _tool = default!; [Dependency] private readonly SharedTransformSystem _transformSystem = default!; [Dependency] private readonly TagSystem _tagSystem = default!; @@ -49,6 +51,8 @@ public sealed partial class AnchorableSystem : EntitySystem SubscribeLocalEvent(OnAnchoredExamine); SubscribeLocalEvent(OnAnchorStartup); SubscribeLocalEvent(OnAnchorStateChange); + + SubscribeLocalEvent(OnAnchorOnStation); } private void OnAnchorStartup(EntityUid uid, AnchorableComponent comp, ComponentStartup args) @@ -56,6 +60,15 @@ public sealed partial class AnchorableSystem : EntitySystem _appearance.SetData(uid, AnchorVisuals.Anchored, Transform(uid).Anchored); } + private void OnAnchorOnStation(Entity ent, ref AnchorAttemptEvent args) + { + if (_stationSystem.IsOnStation(ent, ent.Comp.OnlyCountLargestGrid)) + return; + + args.FailMessage = Loc.GetString(ent.Comp.PopupMessageAnchorFail); + args.Cancel(); + } + private void OnAnchorStateChange(EntityUid uid, AnchorableComponent comp, AnchorStateChangedEvent args) { _appearance.SetData(uid, AnchorVisuals.Anchored, args.Anchored); @@ -76,8 +89,12 @@ public sealed partial class AnchorableSystem : EntitySystem if (!Resolve(usingUid, ref usingTool)) return; - if (!Valid(uid, userUid, usingUid, false)) + if (!Valid(uid, userUid, usingUid, false, out var failMessage)) + { + if (failMessage != null) + _popup.PopupClient(failMessage, uid, userUid); return; + } // Log unanchor attempt (server only) _adminLogger.Add(LogType.Anchor, LogImpact.Low, $"{ToPrettyString(userUid):user} is trying to unanchor {ToPrettyString(uid):entity} from {transform.Coordinates:targetlocation}"); @@ -227,8 +244,12 @@ public sealed partial class AnchorableSystem : EntitySystem if (!Resolve(usingUid, ref usingTool)) return; - if (!Valid(uid, userUid, usingUid, true, anchorable, usingTool)) + if (!Valid(uid, userUid, usingUid, true, out var failMessage, anchorable, usingTool)) + { + if (failMessage != null) + _popup.PopupClient(Loc.GetString(failMessage), uid, userUid); return; + } // Log anchor attempt (server only) _adminLogger.Add(LogType.Anchor, LogImpact.Low, $"{ToPrettyString(userUid):user} is trying to anchor {ToPrettyString(uid):entity} to {transform.Coordinates:targetlocation}"); @@ -250,9 +271,12 @@ public sealed partial class AnchorableSystem : EntitySystem EntityUid userUid, EntityUid usingUid, bool anchoring, + out string? failMessage, AnchorableComponent? anchorable = null, ToolComponent? usingTool = null) { + failMessage = null; + if (!Resolve(uid, ref anchorable)) return false; @@ -276,6 +300,8 @@ public sealed partial class AnchorableSystem : EntitySystem anchorable.Delay += attempt.Delay; + failMessage = attempt.FailMessage; + return !attempt.Cancelled; } diff --git a/Content.Shared/Station/SharedStationSystem.cs b/Content.Shared/Station/SharedStationSystem.cs index 13726ac2e1..4fee0f7ad5 100644 --- a/Content.Shared/Station/SharedStationSystem.cs +++ b/Content.Shared/Station/SharedStationSystem.cs @@ -175,4 +175,27 @@ public abstract partial class SharedStationSystem : EntitySystem return null; } + + /// + /// Returns true if a entity's parent is the station, and false if the entity is not on the station + /// + /// The entity to check if is on a grid + /// If true, only the largest grid of each station will count, so if the entity is on + /// the ATS or a escape pod, it will return false + public bool IsOnStation(EntityUid entity, bool onlyCountLargestGrid = true) + { + var entityParent = Transform(entity).ParentUid; + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var stationDataComp)) + { + if (onlyCountLargestGrid && GetLargestGrid(uid) == entityParent) + return true; + + if (!onlyCountLargestGrid && stationDataComp.Grids.Contains(entityParent)) + return true; + } + + return false; + } } diff --git a/Resources/Locale/en-US/anchorable/anchorable-component.ftl b/Resources/Locale/en-US/anchorable/anchorable-component.ftl index fdac0aa741..602d88f595 100644 --- a/Resources/Locale/en-US/anchorable/anchorable-component.ftl +++ b/Resources/Locale/en-US/anchorable/anchorable-component.ftl @@ -1,3 +1,5 @@ anchorable-anchored = Anchored anchorable-unanchored = Unanchored anchorable-occupied = Tile occupied + +anchorable-fail-not-on-station = This can only be anchored on a station! From d611cf32190b2f76cc8b93db2b9cb17fa22d8f20 Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Sun, 26 Apr 2026 17:40:45 -0700 Subject: [PATCH 47/65] Fix DummyNonAntag not being ignored during AllPresetStartTest (#43757) * GRAAAAAAAAAAAAAAAH * cleanup * two more instances * safsaffsa * fix foolboxes? * cleanup game preset * API --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- .../GameRules/AllGamePresetsStartTest.cs | 2 + .../GameTicking/GameTicker.CVars.cs | 1 + .../GameTicking/GameTicker.GamePreset.cs | 6 +- .../GameTicking/GameTicker.GameRule.cs | 35 +++++++++++ .../RoundstartStationVariationRuleSystem.cs | 2 +- .../GameTicking/Rules/SecretRuleSystem.cs | 3 + .../GameTicking/Rules/SubGamemodesSystem.cs | 3 + .../StationEvents/EventManagerSystem.cs | 3 + .../Catalog/Fills/Items/toolboxes.yml | 62 +++++++++---------- 9 files changed, 80 insertions(+), 37 deletions(-) diff --git a/Content.IntegrationTests/Tests/GameRules/AllGamePresetsStartTest.cs b/Content.IntegrationTests/Tests/GameRules/AllGamePresetsStartTest.cs index 2c8cad5603..ebd47e8af3 100644 --- a/Content.IntegrationTests/Tests/GameRules/AllGamePresetsStartTest.cs +++ b/Content.IntegrationTests/Tests/GameRules/AllGamePresetsStartTest.cs @@ -169,7 +169,9 @@ public sealed class AllGamePresetsStartTest : GameTest Assert.That(entMan.Count(), Is.GreaterThan(0)); Assert.That(entMan.Count(), Is.EqualTo(1)); + // Clear game preset and return to lobby await Pair.WaitCommand("golobby"); + ticker.SetGamePreset((GamePresetPrototype) null); await Pair.RunUntilSynced(); void AssertAntagInitialized(AntagSpecifierPrototype antag, ICommonSession session) { diff --git a/Content.Server/GameTicking/GameTicker.CVars.cs b/Content.Server/GameTicking/GameTicker.CVars.cs index bb68459740..c247c66471 100644 --- a/Content.Server/GameTicking/GameTicker.CVars.cs +++ b/Content.Server/GameTicking/GameTicker.CVars.cs @@ -76,6 +76,7 @@ namespace Content.Server.GameTicking #if EXCEPTION_TOLERANCE Subs.CVar(_cfg, CCVars.RoundStartFailShutdownCount, value => RoundStartFailShutdownCount = value, true); #endif + Subs.CVar(_cfg, CCVars.GameTickerIgnoredPresets, value => _ignoredRules = value.Split(",")); } } } diff --git a/Content.Server/GameTicking/GameTicker.GamePreset.cs b/Content.Server/GameTicking/GameTicker.GamePreset.cs index d49287e539..4b28075ea8 100644 --- a/Content.Server/GameTicking/GameTicker.GamePreset.cs +++ b/Content.Server/GameTicking/GameTicker.GamePreset.cs @@ -16,8 +16,6 @@ public sealed partial class GameTicker { public const float PresetFailedCooldownIncrease = 30f; - public static readonly EntProtoId DummyGameRule = "DummyNonAntag"; - /// /// The selected preset that will be used at the start of the next round. /// @@ -203,11 +201,9 @@ public sealed partial class GameTicker return false; CurrentPreset = Preset; - var ignored = _cfg.GetCVar(CCVars.GameTickerIgnoredPresets).Split(","); foreach (var rule in Preset.Rules) { - if (!ignored.Contains(rule)) - AddGameRule(rule); + AddFilteredGameRule(rule); } return true; diff --git a/Content.Server/GameTicking/GameTicker.GameRule.cs b/Content.Server/GameTicking/GameTicker.GameRule.cs index e34a4ca718..80749fc727 100644 --- a/Content.Server/GameTicking/GameTicker.GameRule.cs +++ b/Content.Server/GameTicking/GameTicker.GameRule.cs @@ -2,6 +2,7 @@ using System.Linq; using Content.Server.Administration; using Content.Server.GameTicking.Rules.Components; using Content.Shared.Administration; +using Content.Shared.CCVar; using Content.Shared.Database; using Content.Shared.GameTicking.Components; using Content.Shared.Prototypes; @@ -15,8 +16,19 @@ namespace Content.Server.GameTicking; public sealed partial class GameTicker { + /// + /// Designated game rule that spawns a fake antagonist to discourage metagaming. + /// + public static readonly EntProtoId DummyGameRule = "DummyNonAntag"; + [ViewVariables] private readonly List<(TimeSpan, string)> _allPreviousGameRules = new(); + /// + /// List of ignored game rules, these rules won't be spawned by normal means. + /// This list is populated by + /// + [ViewVariables] private string[] _ignoredRules = []; + [Dependency] private readonly EntityWhitelistSystem _whitelist = null!; /// @@ -99,6 +111,29 @@ public sealed partial class GameTicker return ruleEntity; } + /// + /// Tries to add a gamerule to the current round, but ignores any + /// + /// Game rule entity that we are trying to spawn + /// The entityUid of the spawned game rule, if it wasn't ignored. + public EntityUid? AddFilteredGameRule(EntProtoId gameRule) + { + if (IsIgnored(gameRule)) + return null; + + return AddGameRule(gameRule); + } + + /// + /// Checks if this GameRule should be ignored before a spawning attempt. + /// + /// GameRule we are trying to validate + /// True if the gamerule should be ignored and not spawned. + public bool IsIgnored(EntProtoId gameRule) + { + return _ignoredRules.Contains(gameRule); + } + /// /// Game rules can be 'started' separately from being added. 'Starting' them usually /// happens at round start while they can be added and removed before then. diff --git a/Content.Server/GameTicking/Rules/RoundstartStationVariationRuleSystem.cs b/Content.Server/GameTicking/Rules/RoundstartStationVariationRuleSystem.cs index 66f0d1f22c..a41267d7d7 100644 --- a/Content.Server/GameTicking/Rules/RoundstartStationVariationRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RoundstartStationVariationRuleSystem.cs @@ -26,7 +26,7 @@ public sealed class RoundstartStationVariationRuleSystem : GameRuleSystem foreach (var rule in preset.Rules) { + if (GameTicker.IsIgnored(rule)) + continue; + EntityUid ruleEnt; // if we're pre-round (i.e. will only be added) diff --git a/Content.Server/GameTicking/Rules/SubGamemodesSystem.cs b/Content.Server/GameTicking/Rules/SubGamemodesSystem.cs index 4fe3827ce5..5684b51847 100644 --- a/Content.Server/GameTicking/Rules/SubGamemodesSystem.cs +++ b/Content.Server/GameTicking/Rules/SubGamemodesSystem.cs @@ -11,6 +11,9 @@ public sealed class SubGamemodesSystem : GameRuleSystem var picked = EntitySpawnCollection.GetSpawns(comp.Rules, RobustRandom); foreach (var id in picked) { + if (GameTicker.IsIgnored(id)) + continue; + Log.Info($"Starting gamerule {id} as a subgamemode of {ToPrettyString(uid):rule}"); GameTicker.AddGameRule(id); } diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index f0324eeb9d..525f8c0012 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -163,6 +163,9 @@ public sealed class EventManagerSystem : EntitySystem foreach (var eventid in selectedEvents) { + if (GameTicker.IsIgnored(eventid)) + continue; + if (!_prototype.Resolve(eventid, out var eventproto)) { Log.Warning("An event ID has no prototype index!"); diff --git a/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml b/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml index 4d0a25c6db..a1b5f6d8c8 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml @@ -172,6 +172,37 @@ id: FoolboxTable table: !type:AllSelector children: + - !type:GroupSelector # Fun clothing + prob: 0.75 + children: + - !type:NestedSelector + tableId: ClownOtherJobTable + weight: 6 + - id: SprayFlowerPin + - id: ClothingHeadHatMagician + - id: ClothingHeadSafari + - id: ClothingHeadHatPirate + - id: ClothingHeadHatWizardFake + - id: ClothingHeadHatCowboyRed + - id: ClothingHeadHatBowlerHat + - id: ClothingHeadHatWitch + - id: ClothingOuterCoatExpensive + - id: ClothingOuterGhostSheet + - id: ClothingOuterHospitalGown + - id: ClothingShoesBling + weight: 0.5 + - id: ClothingOuterCoatSpaceAsshole + weight: 0.5 + - !type:NestedSelector + tableId: AllPartyHatsTable + - !type:NestedSelector + tableId: InsulsTable + - !type:GroupSelector # ~1/115 + weight: 0.175 + children: + - id: ClothingHeadHatCatEars + - id: ClothingHeadHatFancyCrown + - id: ClothingHeadHatChameleon - !type:GroupSelector # Offensive clown items children: - !type:NestedSelector @@ -209,37 +240,6 @@ - id: FoodBanana - id: FoodPieBananaCream weight: 0.75 - - !type:GroupSelector # Fun clothing - prob: 0.75 - children: - - !type:NestedSelector - tableId: ClownOtherJobTable - weight: 6 - - id: SprayFlowerPin - - id: ClothingHeadHatMagician - - id: ClothingHeadSafari - - id: ClothingHeadHatPirate - - id: ClothingHeadHatWizardFake - - id: ClothingHeadHatCowboyRed - - id: ClothingHeadHatBowlerHat - - id: ClothingHeadHatWitch - - id: ClothingOuterCoatExpensive - - id: ClothingOuterGhostSheet - - id: ClothingOuterHospitalGown - - id: ClothingShoesBling - weight: 0.5 - - id: ClothingOuterCoatSpaceAsshole - weight: 0.5 - - !type:NestedSelector - tableId: AllPartyHatsTable - - !type:NestedSelector - tableId: InsulsTable - - !type:GroupSelector # ~1/115 - weight: 0.175 - children: - - id: ClothingHeadHatCatEars - - id: ClothingHeadHatFancyCrown - - id: ClothingHeadHatChameleon - type: entityTable id: ClownOtherJobTable From 552943ee3c4d5e6bdeb90ff2b96203f07a5c98ae Mon Sep 17 00:00:00 2001 From: KeTuFaisPiKiNut <85769816+ketufaispikinut@users.noreply.github.com> Date: Sun, 26 Apr 2026 22:21:38 -0400 Subject: [PATCH 48/65] oh no all hell broke loose ghost roles are broken (#43735) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :3 * mild improvement * let ghosts become antags * MORE!!! --------- Co-authored-by: nomdéraisonnablementlong Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- Content.IntegrationTests/PoolManager.cs | 5 +++++ .../Tests/GameRules/StartEndGameRulesTest.cs | 3 ++- .../Tests/Station/EvacShuttleTest.cs | 2 +- .../AntagSelectionSystem.API.Assignment.cs | 2 +- Content.Server/Antag/AntagSelectionSystem.cs | 18 +++++++++++++----- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/Content.IntegrationTests/PoolManager.cs b/Content.IntegrationTests/PoolManager.cs index 6e0df92ad4..7fd6c4e542 100644 --- a/Content.IntegrationTests/PoolManager.cs +++ b/Content.IntegrationTests/PoolManager.cs @@ -13,6 +13,11 @@ public static partial class PoolManager public static readonly ContentPoolManager Instance = new(); public const string TestMap = "Empty"; + /// + /// Designated load bearing station. Sometimes you need a station for a test. + /// + public const string TestStation = "Saltern"; + /// /// Runs a server, or a client until a condition is true /// diff --git a/Content.IntegrationTests/Tests/GameRules/StartEndGameRulesTest.cs b/Content.IntegrationTests/Tests/GameRules/StartEndGameRulesTest.cs index 1eef1ab0a1..aef2fcf7cd 100644 --- a/Content.IntegrationTests/Tests/GameRules/StartEndGameRulesTest.cs +++ b/Content.IntegrationTests/Tests/GameRules/StartEndGameRulesTest.cs @@ -13,7 +13,8 @@ public sealed class StartEndGameRulesTest : GameTest public override PoolSettings PoolSettings => new PoolSettings { Dirty = true, - DummyTicker = false + DummyTicker = false, + Map = PoolManager.TestStation }; /// diff --git a/Content.IntegrationTests/Tests/Station/EvacShuttleTest.cs b/Content.IntegrationTests/Tests/Station/EvacShuttleTest.cs index 8da97cbab7..e6a098a639 100644 --- a/Content.IntegrationTests/Tests/Station/EvacShuttleTest.cs +++ b/Content.IntegrationTests/Tests/Station/EvacShuttleTest.cs @@ -39,7 +39,7 @@ public sealed class EvacShuttleTest : GameTest pair.Server.CfgMan.SetCVar(CCVars.EmergencyShuttleEnabled, true); pair.Server.CfgMan.SetCVar(CCVars.GameDummyTicker, false); var gameMap = pair.Server.CfgMan.GetCVar(CCVars.GameMap); - pair.Server.CfgMan.SetCVar(CCVars.GameMap, "Saltern"); + pair.Server.CfgMan.SetCVar(CCVars.GameMap, PoolManager.TestStation); await server.WaitPost(() => ticker.RestartRound()); await pair.RunTicksSync(25); diff --git a/Content.Server/Antag/AntagSelectionSystem.API.Assignment.cs b/Content.Server/Antag/AntagSelectionSystem.API.Assignment.cs index aef77fe6a8..1f902941a3 100644 --- a/Content.Server/Antag/AntagSelectionSystem.API.Assignment.cs +++ b/Content.Server/Antag/AntagSelectionSystem.API.Assignment.cs @@ -113,7 +113,7 @@ public sealed partial class AntagSelectionSystem } } - return player.AttachedEntity == null || IsEntityValid(player, def); + return player.AttachedEntity == null || HasComp(player.AttachedEntity) || IsEntityValid(player, def); } /// diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index da21b1f6d5..5479d8e330 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -126,9 +126,19 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem ent, ref TakeGhostRoleEvent args) @@ -767,9 +777,7 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem(mind, out var mindComp) - || mindComp.OwnedEntity != antag) + if (player.GetMind() is not { } mind) mind = _mind.CreateMind(player.UserId, Name(antag)); _mind.TransferTo(mind, antag, ghostCheckOverride: true); From 36d2559cc4f88801cd4d5b2a2a15eeb66a025036 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 27 Apr 2026 02:37:43 +0000 Subject: [PATCH 49/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 7ca5ed401f..713dc6b0d6 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: psykana - changes: - - message: Toggle internals now uses jetpack only if there's no proper gas tank - equipped - type: Tweak - id: 9159 - time: '2025-10-26T15:48:07.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/35068 - author: Huaqas changes: - message: Added a bottle of crazy space lube to the toy box! @@ -4070,3 +4062,10 @@ id: 9670 time: '2026-04-26T17:13:42.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/43675 +- author: ketufaispikinut + changes: + - message: Ghost roles now work again. + type: Fix + id: 9671 + time: '2026-04-27T02:36:33.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/43735 From e5408b2fa9c1f86a08a184a05127d439afa0267f Mon Sep 17 00:00:00 2001 From: Samuka <47865393+Samuka-C@users.noreply.github.com> Date: Mon, 27 Apr 2026 00:05:41 -0300 Subject: [PATCH 50/65] Make Mothership explosive again (#43768) explode --- .../Entities/Mobs/Player/mothershipcore.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Resources/Prototypes/Entities/Mobs/Player/mothershipcore.yml b/Resources/Prototypes/Entities/Mobs/Player/mothershipcore.yml index 7cf26940e9..a6cae6cd96 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/mothershipcore.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/mothershipcore.yml @@ -85,12 +85,11 @@ doAfterDelay: 30 # you can heal the mothership core, but it takes a while - type: DamagedSiliconAccent enableChargeCorruption: false - # TODO: make it explosive again once until issue https://github.com/space-wizards/space-station-14/issues/40606 is fixed - # - type: Explosive - # explosionType: Default - # maxIntensity: 100 - # intensitySlope: 2 - # totalIntensity: 200 + - type: Explosive + explosionType: Default + maxIntensity: 100 + intensitySlope: 2 + totalIntensity: 200 - type: SurveillanceCameraSpeaker - type: SurveillanceCameraMonitor - type: RoboticsConsole From 229e70fa20ee5bd8188f3672d064728fa8d63ebb Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 27 Apr 2026 03:22:13 +0000 Subject: [PATCH 51/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 713dc6b0d6..0491fcbe13 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Huaqas - changes: - - message: Added a bottle of crazy space lube to the toy box! - type: Add - id: 9160 - time: '2025-10-26T18:37:26.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/36292 - author: ThatGuyUSA changes: - message: .50 uranium pellets use their intended sprite. @@ -4069,3 +4062,10 @@ id: 9671 time: '2026-04-27T02:36:33.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/43735 +- author: Samuka + changes: + - message: The mothership core explodes when destroyed once again! + type: Fix + id: 9672 + time: '2026-04-27T03:21:05.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/43768 From b3bcebc07febb4c63e7e0e07b666a9e3de5c30bc Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Mon, 27 Apr 2026 01:35:12 -0700 Subject: [PATCH 52/65] Fix prototypes which lacked Injurable and add a test for Damageable Prototypes that can't take Damage. (#43767) * test * first line of fixes * fixes * review * fix test fail before I merge * fix for snails godo --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- .../Tests/Damageable/DamageAllPrototypes.cs | 60 +++++++++++++++++++ .../Entities/Clothing/Head/hats.yml | 1 + .../Entities/Mobs/Player/silicon.yml | 2 + .../Objects/Devices/chameleon_projector.yml | 1 + .../Prototypes/Entities/Objects/Fun/darts.yml | 1 + .../Entities/Objects/Misc/candles.yml | 1 + .../Entities/Objects/Misc/ice_crust.yml | 1 + .../Entities/Objects/Misc/kudzu.yml | 2 + .../Entities/Objects/Misc/paper.yml | 2 + .../Xenoarchaeology/xenoartifacts.yml | 1 + .../Structures/Decoration/flesh_blockers.yml | 1 + .../Structures/Furniture/rollerbeds.yml | 2 + .../Structures/Specific/Anomaly/anomalies.yml | 1 - .../Entities/Structures/Storage/glass_box.yml | 2 + .../Entities/Structures/spider_web.yml | 1 + 15 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 Content.IntegrationTests/Tests/Damageable/DamageAllPrototypes.cs diff --git a/Content.IntegrationTests/Tests/Damageable/DamageAllPrototypes.cs b/Content.IntegrationTests/Tests/Damageable/DamageAllPrototypes.cs new file mode 100644 index 0000000000..fceec8e6fa --- /dev/null +++ b/Content.IntegrationTests/Tests/Damageable/DamageAllPrototypes.cs @@ -0,0 +1,60 @@ +using System.Numerics; +using System.Runtime.CompilerServices; +using Content.IntegrationTests.Fixtures; +using Content.IntegrationTests.Fixtures.Attributes; +using Content.IntegrationTests.Utility; +using Content.Shared.Damage; +using Content.Shared.Damage.Components; +using Content.Shared.Damage.Prototypes; +using Content.Shared.Damage.Systems; +using Content.Shared.FixedPoint; +using Robust.Shared.Map; + +namespace Content.IntegrationTests.Tests.Damageable; + +[TestFixture] +[TestOf(typeof(DamageableComponent))] +[TestOf(typeof(DamageableSystem))] +public sealed class DamageAllPrototypesTest : GameTest +{ + [SidedDependency(Side.Server)] private readonly DamageableSystem _damageableSystem = default!; + + private static string[] _damageables = GameDataScrounger.EntitiesWithComponent("Damageable"); + + [Test] + [TestOf(typeof(DamageableSystem))] + [TestCaseSource(nameof(_damageables))] + [Description("Ensures all Entity Prototypes with damageable can be damaged.")] + public async Task TestDamageableComponents(string damageable) + { + var map = await Pair.CreateTestMap(); + + var entity = await SpawnAtPosition(damageable, map.GridCoords); + + // Intentionally cannot take damage, ignore it. + if (SEntMan.HasComponent(entity)) + return; + + var canBeDamaged = false; + + foreach (var type in SProtoMan.EnumeratePrototypes()) + { + if (!_damageableSystem.CanBeDamagedBy(entity, type)) + continue; + + canBeDamaged = true; + + await Server.WaitPost(() => + { + var damage = new DamageSpecifier(type, FixedPoint2.Epsilon); + var previousDamage = _damageableSystem.GetTotalDamage(entity); + _damageableSystem.ChangeDamage(entity, damage, ignoreResistances: true); + Assert.That(_damageableSystem.GetTotalDamage(entity) == FixedPoint2.Epsilon + previousDamage); + _damageableSystem.ClearAllDamage(entity); + }); + } + + // Ensure that this entity can actually be damaged. + Assert.That(canBeDamaged); + } +} diff --git a/Resources/Prototypes/Entities/Clothing/Head/hats.yml b/Resources/Prototypes/Entities/Clothing/Head/hats.yml index af513936da..db7c3c5b68 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hats.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hats.yml @@ -1451,6 +1451,7 @@ Heat: 1 - type: Damageable damageModifierSet: Wood + - type: Injurable - type: Appearance - type: FireVisuals sprite: Effects/fire.rsi diff --git a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml index 7a6e51cb48..ebad756c93 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml @@ -201,6 +201,7 @@ container: station_ai_mind_slot - type: Damageable damageModifierSet: StrongMetallic + - type: Injurable - type: Repairable doAfterDelay: 10 allowSelfRepair: false @@ -385,6 +386,7 @@ density: 200 - type: Damageable damageModifierSet: StrongMetallic + - type: Injurable - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Devices/chameleon_projector.yml b/Resources/Prototypes/Entities/Objects/Devices/chameleon_projector.yml index e69b092afa..57502f1219 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/chameleon_projector.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/chameleon_projector.yml @@ -87,6 +87,7 @@ - type: InteractionOutline - type: Clickable - type: Damageable + - type: Injurable - type: ChameleonDisguise # actions diff --git a/Resources/Prototypes/Entities/Objects/Fun/darts.yml b/Resources/Prototypes/Entities/Objects/Fun/darts.yml index 6eebd41731..f46569580e 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/darts.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/darts.yml @@ -159,6 +159,7 @@ - type: InteractionOutline - type: Physics - type: Damageable + - type: Injurable - type: DamageRandomPopup popups: - darts-popup-bullseye diff --git a/Resources/Prototypes/Entities/Objects/Misc/candles.yml b/Resources/Prototypes/Entities/Objects/Misc/candles.yml index f3167b1d99..5710d7f11f 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/candles.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/candles.yml @@ -52,6 +52,7 @@ shader: unshaded - type: Damageable damageModifierSet: Wood + - type: Injurable - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml b/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml index 514443f9a1..fd34bdf42b 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml @@ -36,6 +36,7 @@ - MidImpassable - type: Damageable damageModifierSet: Wood + - type: Injurable - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml index 82ba09f0a4..2407b539ec 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml @@ -47,6 +47,7 @@ - MidImpassable - type: Damageable damageModifierSet: Wood + - type: Injurable - type: Destructible thresholds: - trigger: @@ -206,6 +207,7 @@ layer: - MidImpassable - type: Damageable + - type: Injurable - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml index ba2a7b2e3a..54e06a95f7 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml @@ -25,6 +25,7 @@ normalState: fire - type: Damageable damageModifierSet: Wood + - type: Injurable - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities @@ -467,4 +468,5 @@ - !type:EmptyAllContainersBehaviour - !type:DoActsBehavior acts: [ "Destruction" ] + - type: Injurable - type: StationAiWhitelist diff --git a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/xenoartifacts.yml b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/xenoartifacts.yml index 265e93d720..7c4729b949 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/xenoartifacts.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/xenoartifacts.yml @@ -27,6 +27,7 @@ effectsTable: !type:NestedSelector tableId: XenoArtifactEffectsDefaultTable - type: Damageable + - type: Injurable - type: Actions - type: Physics bodyType: KinematicController diff --git a/Resources/Prototypes/Entities/Structures/Decoration/flesh_blockers.yml b/Resources/Prototypes/Entities/Structures/Decoration/flesh_blockers.yml index 496536818f..fd27afc035 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/flesh_blockers.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/flesh_blockers.yml @@ -29,6 +29,7 @@ ajar: "" open: "" - type: Damageable + - type: Injurable - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml b/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml index ce312e6fe6..a9558846c2 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml @@ -37,6 +37,8 @@ mask: - MobMask - type: Damageable + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities diff --git a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml index d8dea2e463..9e828925cc 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml @@ -37,7 +37,6 @@ sprite: Structures/Specific/anomaly.rsi - type: InteractionOutline - type: Clickable - - type: Damageable - type: Appearance - type: AnimationPlayer - type: GuideHelp diff --git a/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml b/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml index 7fce8e81ba..6ec05b7793 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml @@ -177,6 +177,8 @@ - type: Climbable - type: Damageable damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities diff --git a/Resources/Prototypes/Entities/Structures/spider_web.yml b/Resources/Prototypes/Entities/Structures/spider_web.yml index e421c99577..edd8fb9e64 100644 --- a/Resources/Prototypes/Entities/Structures/spider_web.yml +++ b/Resources/Prototypes/Entities/Structures/spider_web.yml @@ -23,6 +23,7 @@ - type: Physics - type: Damageable damageModifierSet: Wood + - type: Injurable - type: Temperature - type: TemperatureDamage heatDamage: From 43858b2861ea8cd978a0272c5b54bc3968e1c99b Mon Sep 17 00:00:00 2001 From: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Date: Mon, 27 Apr 2026 17:36:54 +0200 Subject: [PATCH 53/65] Fix newline in description examine (#43722) yeah --- Content.Shared/Examine/ExamineSystemShared.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Shared/Examine/ExamineSystemShared.cs b/Content.Shared/Examine/ExamineSystemShared.cs index da10e99c62..27b02d8b84 100644 --- a/Content.Shared/Examine/ExamineSystemShared.cs +++ b/Content.Shared/Examine/ExamineSystemShared.cs @@ -268,7 +268,7 @@ namespace Content.Shared.Examine //Add an entity description if one is declared if (!string.IsNullOrEmpty(metadata.EntityDescription)) { - message.PushMarkup(metadata.EntityDescription); + message.AddMarkupOrThrow(metadata.EntityDescription); hasDescription = true; } From 525d6237d62a9714a0075292a91ccb783caccb3c Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 27 Apr 2026 15:54:50 +0000 Subject: [PATCH 54/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 0491fcbe13..ce5cff7f86 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: ThatGuyUSA - changes: - - message: .50 uranium pellets use their intended sprite. - type: Fix - id: 9161 - time: '2025-10-26T18:50:01.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/41068 - author: ArtisticRoomba changes: - message: Examine text for whether an object is currently taking Delta-Pressure @@ -4069,3 +4062,10 @@ id: 9672 time: '2026-04-27T03:21:05.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/43768 +- author: ScarKy0 + changes: + - message: Entity examine text will no longer have an extra line after the description. + type: Fix + id: 9673 + time: '2026-04-27T15:53:41.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/43722 From 6d811db43435c5030555820a6b2be402355e5fc8 Mon Sep 17 00:00:00 2001 From: Pok <113675512+Pok27@users.noreply.github.com> Date: Mon, 27 Apr 2026 19:06:23 +0300 Subject: [PATCH 55/65] Changeling disguise limit (#43779) * Changeling-disguise-limit * Update ChangelingIdentityComponent.cs * review --- .../Changeling/Systems/ChangelingIdentitySystem.cs | 1 + .../Changeling/Systems/ChangelingIdentitySystem.cs | 6 +++++- .../Components/ChangelingIdentityComponent.cs | 11 ++++++++++- .../Changeling/Systems/ChangelingDevourSystem.cs | 7 +++++++ .../Systems/SharedChangelingIdentitySystem.cs | 11 +++++++++++ Resources/Locale/en-US/changeling/changeling.ftl | 1 + 6 files changed, 35 insertions(+), 2 deletions(-) diff --git a/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs b/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs index 270a6a7a84..917eeefc08 100644 --- a/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs +++ b/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs @@ -41,6 +41,7 @@ public sealed class ChangelingIdentitySystem : SharedChangelingIdentitySystem ent.Comp.CurrentIdentity = EnsureEntity(state.CurrentIdentity, ent); ent.Comp.IdentityCloningSettings = state.IdentityCloningSettings; + ent.Comp.MaxStoredDisguises = state.MaxStoredDisguises; UpdateUi(ent); } diff --git a/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs b/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs index 36b681015a..6f7556196c 100644 --- a/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs +++ b/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs @@ -35,6 +35,10 @@ public sealed class ChangelingIdentitySystem : SharedChangelingIdentitySystem var netCurrent = GetNetEntity(current); - args.State = new ChangelingIdentityComponentState(sentIdentities, netCurrent, entity.Comp.IdentityCloningSettings); + args.State = new ChangelingIdentityComponentState( + sentIdentities, + netCurrent, + entity.Comp.IdentityCloningSettings, + entity.Comp.MaxStoredDisguises); } } diff --git a/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs b/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs index f202365740..affec705ab 100644 --- a/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs +++ b/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs @@ -37,6 +37,12 @@ public sealed partial class ChangelingIdentityComponent : Component [DataField] public ProtoId IdentityCloningSettings = "ChangelingCloningSettings"; + /// + /// Maximum number of stored disguises, including the changeling's starting identity. + /// + [DataField] + public int MaxStoredDisguises = 5; + public override bool SendOnlyToOwner => true; } @@ -47,14 +53,17 @@ public sealed class ChangelingIdentityComponentState : ComponentState public NetEntity? CurrentIdentity; public ProtoId IdentityCloningSettings; + public int MaxStoredDisguises; public ChangelingIdentityComponentState(List consumedIdentities, NetEntity? currentIdentity, - ProtoId identityCloningSettings) + ProtoId identityCloningSettings, + int maxStoredDisguises) { ConsumedIdentities = consumedIdentities; CurrentIdentity = currentIdentity; IdentityCloningSettings = identityCloningSettings; + MaxStoredDisguises = maxStoredDisguises; } } diff --git a/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs b/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs index 588eedb6a3..6d07fb9378 100644 --- a/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs +++ b/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs @@ -248,6 +248,13 @@ public sealed class ChangelingDevourSystem : EntitySystem return false; } + if (!HasIdentity(changeling.Owner, victim) && !_changelingIdentitySystem.HasFreeDisguiseSlot(changeling.Owner)) + { + if (showPopup) + _popupSystem.PopupClient(Loc.GetString("changeling-devour-attempt-failed-no-space"), changeling.Owner, changeling.Owner, PopupType.Medium); + return false; + } + return true; } diff --git a/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs b/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs index 60ea667cf7..307c6a2132 100644 --- a/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs +++ b/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs @@ -299,6 +299,17 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem } } + /// + /// Returns whether the changeling has space to store another disguise. + /// + public bool HasFreeDisguiseSlot(Entity ent) + { + if (!Resolve(ent, ref ent.Comp, false)) + return false; + + return ent.Comp.ConsumedIdentities.Count(data => data.Identity != null) < ent.Comp.MaxStoredDisguises; + } + /// /// Create a paused map for storing devoured identities as a clone of the player. /// diff --git a/Resources/Locale/en-US/changeling/changeling.ftl b/Resources/Locale/en-US/changeling/changeling.ftl index 5ad430528c..f3e2a026d0 100644 --- a/Resources/Locale/en-US/changeling/changeling.ftl +++ b/Resources/Locale/en-US/changeling/changeling.ftl @@ -9,6 +9,7 @@ changeling-devour-attempt-failed-devoured-recently = This body is too mangled to changeling-devour-attempt-failed-not-dead = This body yet lives! We cannot consume it alive! changeling-devour-attempt-failed-rotting = This corpse has only rotted biomass. changeling-devour-attempt-failed-protected = This victim's biomass is protected by armor! +changeling-devour-attempt-failed-no-space = We have exceeded the maximum number of disguises! changeling-devour-begin-windup-self = Our uncanny mouth reveals itself with otherworldly hunger. changeling-devour-begin-windup-others = { CAPITALIZE(POSS-ADJ($user)) } uncanny mouth reveals itself with otherworldly hunger. From 754317d013881d69ba709e7080030462f503b647 Mon Sep 17 00:00:00 2001 From: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Date: Mon, 27 Apr 2026 21:50:53 +0200 Subject: [PATCH 56/65] Changeling Biodegrade (#43671) * initial fix ensnaring * jesus fucking christ * fuck * Update changeling.yml * oh my god * yay * vomit acid * i love breaking changes + review * BEGONE! * restraint, remove misc balancing * again * null checks --- .../Inventory/StrippableBoundUserInterface.cs | 8 +- .../ChangelingBiodegradeAbilityComponent.cs | 51 ++++++++++ .../Systems/ChangelingAbilitySystem.cs | 69 +++++++++++++ Content.Shared/Cuffs/SharedCuffableSystem.cs | 5 +- .../Components/EnsnareableComponent.cs | 9 +- .../Components/EnsnaringComponent.cs | 1 + .../Ensnaring/SharedEnsnareableSystem.cs | 93 +++++++++++++----- .../Locale/en-US/changeling/changeling.ftl | 15 ++- .../Locale/en-US/store/changeling-catalog.ftl | 3 + Resources/Prototypes/Actions/changeling.yml | 18 ++++ .../Prototypes/Catalog/changeling_catalog.yml | 17 +++- .../Actions/changeling.rsi/background.png | Bin 0 -> 199 bytes .../Actions/changeling.rsi/frame.png | Bin 0 -> 856 bytes .../Actions/changeling.rsi/meta.json | 8 +- .../Actions/changeling2.rsi/biodegrade.png | Bin 0 -> 1553 bytes .../Actions/changeling2.rsi/meta.json | 5 +- 16 files changed, 257 insertions(+), 45 deletions(-) create mode 100644 Content.Shared/Changeling/Components/ChangelingBiodegradeAbilityComponent.cs create mode 100644 Content.Shared/Changeling/Systems/ChangelingAbilitySystem.cs create mode 100644 Resources/Textures/Interface/Actions/changeling.rsi/background.png create mode 100644 Resources/Textures/Interface/Actions/changeling.rsi/frame.png create mode 100644 Resources/Textures/Interface/Actions/changeling2.rsi/biodegrade.png diff --git a/Content.Client/Inventory/StrippableBoundUserInterface.cs b/Content.Client/Inventory/StrippableBoundUserInterface.cs index f9a6cd46d6..b86d022bcd 100644 --- a/Content.Client/Inventory/StrippableBoundUserInterface.cs +++ b/Content.Client/Inventory/StrippableBoundUserInterface.cs @@ -8,7 +8,7 @@ using Content.Client.UserInterface.Controls; using Content.Client.UserInterface.Systems.Hands.Controls; using Content.Client.Verbs.UI; using Content.Shared.Cuffs; -using Content.Shared.Cuffs.Components; +using Content.Shared.Ensnaring; using Content.Shared.Ensnaring.Components; using Content.Shared.Hands.Components; using Content.Shared.IdentityManagement; @@ -39,6 +39,7 @@ namespace Content.Client.Inventory private readonly InventorySystem _inv; private readonly SharedCuffableSystem _cuffable; private readonly StrippableSystem _strippable; + private readonly SharedEnsnareableSystem _snare; [ViewVariables] private const int ButtonSeparation = 4; @@ -71,6 +72,7 @@ namespace Content.Client.Inventory _inv = EntMan.System(); _cuffable = EntMan.System(); _strippable = EntMan.System(); + _snare = EntMan.System(); _virtualHiddenEntity = EntMan.SpawnEntity(HiddenPocketEntityId, MapCoordinates.Nullspace); } @@ -149,7 +151,7 @@ namespace Content.Client.Inventory } // snare-removal button. This is just the old button before the change to item slots. It is pretty out of place. - if (EntMan.TryGetComponent(Owner, out var snare) && snare.IsEnsnared) + if (EntMan.TryGetComponent(Owner, out var snare) && _snare.IsEnsnared((Owner, snare))) { var button = new Button() { @@ -175,7 +177,7 @@ namespace Content.Client.Inventory // +27 vertically from the window header var horizontalMenuSize = Math.Max(200, Math.Max(_handCount, _inventoryDimensions.X + 1) * (SlotControl.DefaultButtonSize + ButtonSeparation) + 20); var verticalMenuSize = Math.Max(200, (_inventoryDimensions.Y + (_handCount > 0 ? 2 : 1)) * (SlotControl.DefaultButtonSize + ButtonSeparation) + 53); - if (snare?.IsEnsnared == true) + if (_snare.IsEnsnared(Owner)) verticalMenuSize += 20; _strippingMenu.SetSize = new Vector2(horizontalMenuSize, verticalMenuSize); } diff --git a/Content.Shared/Changeling/Components/ChangelingBiodegradeAbilityComponent.cs b/Content.Shared/Changeling/Components/ChangelingBiodegradeAbilityComponent.cs new file mode 100644 index 0000000000..c0c97d5852 --- /dev/null +++ b/Content.Shared/Changeling/Components/ChangelingBiodegradeAbilityComponent.cs @@ -0,0 +1,51 @@ +using Content.Shared.Actions; +using Content.Shared.Chemistry.Components; +using Robust.Shared.Audio; +using Robust.Shared.GameStates; + +namespace Content.Shared.Changeling.Components; + +/// +/// Allows the changeling to spawn dummy chameleon clothing items that will transform with them, +/// mimicing the equipment of the stored disguise. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class ChangelingBiodegradeAbilityComponent : Component +{ + /// + /// How long to stun the puller of the changeling when this action is activated. + /// + [DataField] + public TimeSpan PullerStunDuration = TimeSpan.FromSeconds(3f); + + /// + /// The popup to display over the user when the action is used. + /// Only visible to other players. + /// + [DataField] + public LocId ActivatedPopup = "changeling-biodegrade-used-popup"; + + /// + /// The popup to display over the user when the action is used. + /// Only visible to the user + /// + [DataField] + public LocId ActivatedPopupSelf = "changeling-biodegrade-used-popup-self"; + + /// + /// The sound to play when the ability is successfully used. + /// + [DataField] + public SoundSpecifier ActivatedSound = new SoundPathSpecifier("/Audio/Effects/Fluids/splat.ogg"); + + /// + /// The reagents to spill at the location of the entity when this action is used. + /// + [DataField] + public Solution? SpillSolution = new([new("SulfuricAcid", 30)]); +} + +/// +/// Action event for Biodegrade, raised on the ability when used. +/// +public sealed partial class ChangelingBiodegradeActionEvent : InstantActionEvent; diff --git a/Content.Shared/Changeling/Systems/ChangelingAbilitySystem.cs b/Content.Shared/Changeling/Systems/ChangelingAbilitySystem.cs new file mode 100644 index 0000000000..d7fb5111d2 --- /dev/null +++ b/Content.Shared/Changeling/Systems/ChangelingAbilitySystem.cs @@ -0,0 +1,69 @@ +using System.Linq; +using Content.Shared.Changeling.Components; +using Content.Shared.Cuffs; +using Content.Shared.Ensnaring; +using Content.Shared.Fluids; +using Content.Shared.IdentityManagement; +using Content.Shared.Movement.Pulling.Systems; +using Content.Shared.Popups; +using Content.Shared.Stunnable; +using Robust.Shared.Audio.Systems; + +namespace Content.Shared.Changeling.Systems; + +public sealed partial class ChangelingAbilitySystem : EntitySystem +{ + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly SharedCuffableSystem _cuffable = default!; + [Dependency] private readonly SharedEnsnareableSystem _snare = default!; + [Dependency] private readonly PullingSystem _pulling = default!; + [Dependency] private readonly SharedStunSystem _stun = default!; + [Dependency] private readonly SharedPuddleSystem _puddle = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnBiodegradeAction); + } + + private void OnBiodegradeAction(Entity ent, ref ChangelingBiodegradeActionEvent args) + { + // Nothing can be done :( + if (!_cuffable.IsCuffed(args.Performer) && !_snare.IsEnsnared(args.Performer)) + return; + + if (_pulling.GetPuller(args.Performer) is { } puller) + { + _stun.TryAddParalyzeDuration(puller, ent.Comp.PullerStunDuration); + } + + var toDelete = new List(); + + _cuffable.TryGetAllCuffs(args.Performer, out var cuffs); + foreach (var cuff in cuffs.ToList()) + { + _cuffable.Uncuff(args.Performer, args.Performer, cuff); + toDelete.Add(cuff); + } + + toDelete.AddRange(_snare.ForceFreeAll(args.Performer)); + + args.Handled = true; + + var selfPopup = Loc.TryGetString(ent.Comp.ActivatedPopupSelf, out var self, ("user", Identity.Entity(args.Performer, EntityManager)), ("restraint", toDelete.First())) ? self : null; + var othersPopup = Loc.TryGetString(ent.Comp.ActivatedPopup, out var others, ("user", Identity.Entity(args.Performer, EntityManager)), ("restraint", toDelete.First())) ? others : null; + + _popup.PopupPredicted(selfPopup, othersPopup, args.Performer, args.Performer, PopupType.LargeCaution); + _audio.PlayPredicted(ent.Comp.ActivatedSound, args.Performer, args.Performer); + + foreach (var deleted in toDelete) + { + PredictedQueueDel(deleted); + } + + if (ent.Comp.SpillSolution != null) + _puddle.TrySpillAt(args.Performer, ent.Comp.SpillSolution, out _, false); + } +} diff --git a/Content.Shared/Cuffs/SharedCuffableSystem.cs b/Content.Shared/Cuffs/SharedCuffableSystem.cs index 577b7dfe2c..b44b4c2a8d 100644 --- a/Content.Shared/Cuffs/SharedCuffableSystem.cs +++ b/Content.Shared/Cuffs/SharedCuffableSystem.cs @@ -572,8 +572,11 @@ namespace Content.Shared.Cuffs /// /// The entity to be checked /// when true, return false if the target is only partially cuffed (for things with more than 2 hands) /// - public bool IsCuffed(Entity target, bool requireFullyCuffed = true) + public bool IsCuffed(Entity target, bool requireFullyCuffed = true) { + if (!Resolve(target, ref target.Comp, false)) + return false; + if (!TryComp(target, out var hands)) return false; diff --git a/Content.Shared/Ensnaring/Components/EnsnareableComponent.cs b/Content.Shared/Ensnaring/Components/EnsnareableComponent.cs index 126031dc6b..0f17e271ab 100644 --- a/Content.Shared/Ensnaring/Components/EnsnareableComponent.cs +++ b/Content.Shared/Ensnaring/Components/EnsnareableComponent.cs @@ -8,6 +8,7 @@ namespace Content.Shared.Ensnaring.Components; /// Use this on an entity that you would like to be ensnared by anything that has the /// [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] +[Access(typeof(SharedEnsnareableSystem))] public sealed partial class EnsnareableComponent : Component { /// @@ -22,16 +23,10 @@ public sealed partial class EnsnareableComponent : Component [DataField, AutoNetworkedField] public float SprintSpeed = 1.0f; - /// - /// Is this entity currently ensnared? - /// - [DataField, AutoNetworkedField] - public bool IsEnsnared; - /// /// The container where the entity will be stored /// - public Container Container = default!; + public Container? Container = default!; [DataField] public string? Sprite; diff --git a/Content.Shared/Ensnaring/Components/EnsnaringComponent.cs b/Content.Shared/Ensnaring/Components/EnsnaringComponent.cs index b05ce151d8..d93e7559e2 100644 --- a/Content.Shared/Ensnaring/Components/EnsnaringComponent.cs +++ b/Content.Shared/Ensnaring/Components/EnsnaringComponent.cs @@ -6,6 +6,7 @@ namespace Content.Shared.Ensnaring.Components; /// Use this on something you want to use to ensnare an entity with /// [RegisterComponent, NetworkedComponent] +[Access(typeof(SharedEnsnareableSystem))] public sealed partial class EnsnaringComponent : Component { /// diff --git a/Content.Shared/Ensnaring/SharedEnsnareableSystem.cs b/Content.Shared/Ensnaring/SharedEnsnareableSystem.cs index a4c736838a..f42b2c2ae3 100644 --- a/Content.Shared/Ensnaring/SharedEnsnareableSystem.cs +++ b/Content.Shared/Ensnaring/SharedEnsnareableSystem.cs @@ -1,5 +1,5 @@ +using System.Linq; using Content.Shared.Alert; -using Content.Shared.CombatMode.Pacification; using Content.Shared.Damage.Components; using Content.Shared.Damage.Systems; using Content.Shared.DoAfter; @@ -61,7 +61,7 @@ public abstract class SharedEnsnareableSystem : EntitySystem private void OnHandleState(EntityUid uid, EnsnareableComponent component, ref AfterAutoHandleStateEvent args) { - RaiseLocalEvent(uid, new EnsnaredChangedEvent(component.IsEnsnared)); + RaiseLocalEvent(uid, new EnsnaredChangedEvent(IsEnsnared(uid))); } private void OnDoAfter(EntityUid uid, EnsnareableComponent component, DoAfterEvent args) @@ -72,7 +72,7 @@ public abstract class SharedEnsnareableSystem : EntitySystem if (args.Handled || !TryComp(args.Args.Used, out var ensnaring)) return; - if (args.Cancelled || !Container.Remove(args.Args.Used.Value, component.Container)) + if (args.Cancelled || component.Container == null || !Container.Remove(args.Args.Used.Value, component.Container)) { if (args.User == args.Target) Popup.PopupPredicted(Loc.GetString("ensnare-component-try-free-fail", ("ensnare", args.Args.Used)), uid, args.User, PopupType.MediumCaution); @@ -82,12 +82,11 @@ public abstract class SharedEnsnareableSystem : EntitySystem return; } - component.IsEnsnared = component.Container.ContainedEntities.Count > 0; + _hands.PickupOrDrop(args.Args.User, args.Args.Used.Value); + Dirty(uid, component); ensnaring.Ensnared = null; - _hands.PickupOrDrop(args.Args.User, args.Args.Used.Value); - if (args.User == args.Target) Popup.PopupPredicted(Loc.GetString("ensnare-component-try-free-complete", ("ensnare", args.Args.Used)), uid, args.User, PopupType.Medium); else if (args.Target != null) @@ -107,7 +106,7 @@ public abstract class SharedEnsnareableSystem : EntitySystem _speedModifier.RefreshMovementSpeedModifiers(uid); - var ev = new EnsnaredChangedEvent(component.IsEnsnared); + var ev = new EnsnaredChangedEvent(IsEnsnared(uid)); RaiseLocalEvent(uid, ev); } @@ -118,7 +117,7 @@ public abstract class SharedEnsnareableSystem : EntitySystem _speedModifier.RefreshMovementSpeedModifiers(uid); - var ev = new EnsnaredChangedEvent(component.IsEnsnared); + var ev = new EnsnaredChangedEvent(IsEnsnared(uid)); RaiseLocalEvent(uid, ev); } @@ -129,13 +128,13 @@ public abstract class SharedEnsnareableSystem : EntitySystem private void UpdateAppearance(EntityUid uid, EnsnareableComponent component, AppearanceComponent? appearance = null) { - Appearance.SetData(uid, EnsnareableVisuals.IsEnsnared, component.IsEnsnared, appearance); + Appearance.SetData(uid, EnsnareableVisuals.IsEnsnared, IsEnsnared(uid), appearance); } private void MovementSpeedModify(EntityUid uid, EnsnareableComponent component, RefreshMovementSpeedModifiersEvent args) { - if (!component.IsEnsnared) + if (!IsEnsnared(uid)) return; args.ModifySpeed(component.WalkSpeed, component.SprintSpeed); @@ -176,6 +175,9 @@ public abstract class SharedEnsnareableSystem : EntitySystem private void OnStripEnsnareMessage(EntityUid uid, EnsnareableComponent component, StrippingEnsnareButtonPressed args) { + if (component.Container == null) + return; + foreach (var entity in component.Container.ContainedEntities) { if (!TryComp(entity, out var ensnaring)) @@ -188,7 +190,7 @@ public abstract class SharedEnsnareableSystem : EntitySystem private void OnRemoveEnsnareAlert(Entity ent, ref RemoveEnsnareAlertEvent args) { - if (args.Handled) + if (args.Handled || ent.Comp.Container == null) return; foreach (var ensnare in ent.Comp.Container.ContainedEntities) @@ -209,8 +211,8 @@ public abstract class SharedEnsnareableSystem : EntitySystem if (!TryComp(component.Ensnared, out var ensnared)) return; - if (ensnared.IsEnsnared) - ForceFree(uid, component); + if (IsEnsnared((component.Ensnared.Value, ensnared))) + ForceFree((uid, component)); } private void AttemptStepTrigger(EntityUid uid, EnsnaringComponent component, ref StepTriggerAttemptEvent args) @@ -243,7 +245,7 @@ public abstract class SharedEnsnareableSystem : EntitySystem public bool TryEnsnare(EntityUid target, EntityUid ensnare, EnsnaringComponent component) { //Don't do anything if they don't have the ensnareable component. - if (!TryComp(target, out var ensnareable)) + if (!TryComp(target, out var ensnareable) || ensnareable.Container == null) return false; var numEnsnares = ensnareable.Container.ContainedEntities.Count; @@ -261,7 +263,6 @@ public abstract class SharedEnsnareableSystem : EntitySystem } component.Ensnared = target; - ensnareable.IsEnsnared = true; Dirty(target, ensnareable); UpdateAlert(target, ensnareable); @@ -273,24 +274,64 @@ public abstract class SharedEnsnareableSystem : EntitySystem /// /// Used to force free someone for things like if the is removed /// - public void ForceFree(EntityUid ensnare, EnsnaringComponent component) + public void ForceFree(Entity entity) { - if (component.Ensnared == null) + if (!Resolve(entity, ref entity.Comp, false)) return; - if (!TryComp(component.Ensnared, out var ensnareable)) + if (!TryComp(entity.Comp.Ensnared, out var ensnareable) || ensnareable.Container == null) return; - var target = component.Ensnared.Value; + var target = entity.Comp.Ensnared.Value; - Container.Remove(ensnare, ensnareable.Container, force: true); - ensnareable.IsEnsnared = ensnareable.Container.ContainedEntities.Count > 0; - Dirty(component.Ensnared.Value, ensnareable); - component.Ensnared = null; + Container.Remove(entity.Owner, ensnareable.Container, force: true); + + Dirty(entity.Comp.Ensnared.Value, ensnareable); + entity.Comp.Ensnared = null; UpdateAlert(target, ensnareable); - var ev = new EnsnareRemoveEvent(component.WalkSpeed, component.SprintSpeed); - RaiseLocalEvent(ensnare, ev); + var ev = new EnsnareRemoveEvent(entity.Comp.WalkSpeed, entity.Comp.SprintSpeed); + RaiseLocalEvent(target, ev); + } + + /// + /// Removes all ensnares from an entity. + /// + /// The entity to remove snares from. + /// The list of removed snares. + public List ForceFreeAll(Entity entity) + { + if (!Resolve(entity, ref entity.Comp, false)) + return new List(); + + if (entity.Comp.Container == null) + return new List(); + + List snares = new(); + + foreach (var snare in entity.Comp.Container.ContainedEntities.ToList()) + { + ForceFree(snare); + snares.Add(snare); + } + + return snares; + } + + /// + /// Checks whether an entity is currently being ensnared. + /// + /// The entity to check. + /// True if ensnared, otherwise False. + public bool IsEnsnared(Entity entity) + { + if (!Resolve(entity, ref entity.Comp, false)) + return false; + + if (entity.Comp.Container == null) + return false; + + return entity.Comp.Container.ContainedEntities.Count > 0; } /// @@ -299,7 +340,7 @@ public abstract class SharedEnsnareableSystem : EntitySystem /// The entity that has been affected by a snare public void UpdateAlert(EntityUid target, EnsnareableComponent component) { - if (!component.IsEnsnared) + if (!IsEnsnared(target)) _alerts.ClearAlert(target, component.EnsnaredAlert); else _alerts.ShowAlert(target, component.EnsnaredAlert); diff --git a/Resources/Locale/en-US/changeling/changeling.ftl b/Resources/Locale/en-US/changeling/changeling.ftl index f3e2a026d0..4a851d6fa7 100644 --- a/Resources/Locale/en-US/changeling/changeling.ftl +++ b/Resources/Locale/en-US/changeling/changeling.ftl @@ -5,7 +5,6 @@ roles-antag-changeling-objective = A intelligent predator that assumes the ident # devour changeling-devour-attempt-failed-cannot-devour = We cannot devour this! changeling-devour-attempt-failed-already-devoured = We already consumed this body! -changeling-devour-attempt-failed-devoured-recently = This body is too mangled to devour! changeling-devour-attempt-failed-not-dead = This body yet lives! We cannot consume it alive! changeling-devour-attempt-failed-rotting = This corpse has only rotted biomass. changeling-devour-attempt-failed-protected = This victim's biomass is protected by armor! @@ -21,10 +20,6 @@ changeling-devour-consume-complete-others = { CAPITALIZE(POSS-ADJ($user)) } unca # transformation changeling-transform-attempt-self = Our bones snap, muscles tear, one flesh becomes another. changeling-transform-attempt-others = { CAPITALIZE(POSS-ADJ($user)) } bones snap, muscles tear, body shifts into another. -changeling-flesh-clothing-removed-popop = {CAPITALIZE(THE($item))} falls apart into fleshy remains! -changeling-flesh-clothing-examine-wearer = [color=crimson]This item is a camouflaged part of your body. It will disappear if you unequip it![/color] -changeling-flesh-clothing-alert-name = Flesh Clothing Ability -changeling-flesh-clothing-alert-desc = Whether clothing transformation is enabled. Click to toggle. # transformation BUI changeling-transform-bui-select-entity = {$entity} @@ -36,5 +31,15 @@ changeling-transform-bui-drop-identity-cannot-drop = You cannot drop your curren # voice mimicry changeling-voice-mimic-window-title = Voice Mimicry +# flesh clothing +changeling-flesh-clothing-removed-popop = {CAPITALIZE(THE($item))} falls apart into fleshy remains! +changeling-flesh-clothing-examine-wearer = [color=crimson]This item is a camouflaged part of your body. It will disappear if you unequip it![/color] +changeling-flesh-clothing-alert-name = Flesh Clothing Ability +changeling-flesh-clothing-alert-desc = Whether clothing transformation is enabled. Click to toggle. + +# biodegrade +changeling-biodegrade-used-popup = {CAPITALIZE(THE($user))} vomits acid over {POSS-ADJ($user)} {$restraint}! +changeling-biodegrade-used-popup-self = We vomit acid over our {$restraint}! + # other changeling-paused-map-name = Changeling identity storage map diff --git a/Resources/Locale/en-US/store/changeling-catalog.ftl b/Resources/Locale/en-US/store/changeling-catalog.ftl index 6ee4f75f21..893f2a84af 100644 --- a/Resources/Locale/en-US/store/changeling-catalog.ftl +++ b/Resources/Locale/en-US/store/changeling-catalog.ftl @@ -6,3 +6,6 @@ changeling-catalog-flesh-clothing-desc = Your body's surface will adapt to mirro changeling-catalog-voice-mimic-name = Voice Mimicry changeling-catalog-voice-mimic-desc = Change your vocal coords at will to imitate existing (and imaginary) crew members. Perfect for luring in prey. + +changeling-catalog-biodegrade-name = Biodegrade +changeling-catalog-biodegrade-desc = You learn to utilize acid glands within your body to vomit acid over constraints, setting yourself free. diff --git a/Resources/Prototypes/Actions/changeling.yml b/Resources/Prototypes/Actions/changeling.yml index a3175d63b2..c3cd19e5ec 100644 --- a/Resources/Prototypes/Actions/changeling.yml +++ b/Resources/Prototypes/Actions/changeling.yml @@ -20,6 +20,24 @@ retractSounds: collection: gib # Placeholder +- type: entity + parent: BaseAction + id: ActionChangelingBiodegrade + name: Biodegrade + description: Vomit acid over your restraints, setting yourself free. + components: + - type: Action + useDelay: 60 # TODO: Short cooldown but chemical cost + raiseOnAction: true + itemIconStyle: BigAction + checkCanInteract: false + icon: + sprite: Interface/Actions/changeling2.rsi + state: biodegrade + - type: InstantAction + event: !type:ChangelingBiodegradeActionEvent + - type: ChangelingBiodegradeAbility + - type: entity id: ActionChangelingDevour name: "[color=red]Devour[/color]" diff --git a/Resources/Prototypes/Catalog/changeling_catalog.yml b/Resources/Prototypes/Catalog/changeling_catalog.yml index 941ab21536..1a6790bc07 100644 --- a/Resources/Prototypes/Catalog/changeling_catalog.yml +++ b/Resources/Prototypes/Catalog/changeling_catalog.yml @@ -34,10 +34,25 @@ description: changeling-catalog-voice-mimic-desc icon: { sprite: /Textures/Interface/Actions/changeling2.rsi, state: mimicry} cost: - ChangelingDNA: 10 # TODO: Balance this once we have DNA from devour. It's currently cheap for testing purposes. + ChangelingDNA: 10 categories: - ChangelingAbilities conditions: - !type:ListingLimitedStockCondition stock: 1 productComponents: ChangelingVoiceMimicDummy + +- type: listing + id: ChangelingBiodegrade + name: changeling-catalog-biodegrade-name + description: changeling-catalog-biodegrade-desc + icon: { sprite: /Textures/Interface/Actions/changeling2.rsi, state: biodegrade } + applyToMob: true + cost: + ChangelingDNA: 10 + categories: + - ChangelingAbilities + conditions: + - !type:ListingLimitedStockCondition + stock: 1 + productAction: ActionChangelingBiodegrade diff --git a/Resources/Textures/Interface/Actions/changeling.rsi/background.png b/Resources/Textures/Interface/Actions/changeling.rsi/background.png new file mode 100644 index 0000000000000000000000000000000000000000..d754168d9129dba8758fc534f41f32042f5076f9 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}jh-%!ArY;~ z2@!_V{k8+jRnc$Z$;7$NJxrEqnli>gx)gRfJ9iFnU5rl12EdJ<<@ r7w-gfn=ZyUd=+pwueLbh1~Wrde!jc&t~(7t$1r%h`njxgN@xNAG?Grk literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Actions/changeling.rsi/frame.png b/Resources/Textures/Interface/Actions/changeling.rsi/frame.png new file mode 100644 index 0000000000000000000000000000000000000000..f13df2bec83b2d1f6b10f66c60891c8695db569e GIT binary patch literal 856 zcmV-e1E>6nP)Px&5=lfsR9J<@mrZLEQ51%sJ7z@G(5C39HIN2GE%l?gDJ}{cFbfxM#A3ybh0=xe z4-{M#{0AmaE#liOlDLwK%yRi#z zeBzfYD_cC}7%>t@IsrH?-vdyK)DhZ^dee9=C$#0-Wt%aP?o$9I(FK5AD)MM??w28( zNcX9c*?Dp6Ouv#}Hxv|8sg%mNE=kj5JeLze;a~mmZ=e;|ULDWngpqMwE+0MW3r!CV zsO`7^J4R;bg*HqZYxF1DF}e=WZCQYKI9g$S5Z#vLXOH0&>r@?^TBPo~sMW~0uD>?4 zcGtKn2L8;G~9e>3M{>S&CKxF&Zc4IQw;#)>ixUISz94-`eJD0cB$yEy)^8w zLL&!=f2-iEt?*!QRPAUb1c*Es9901J((}+ryDf{CZk}wZ=!L*p3%?YD7YZYrU*LWD z6$L4Ia_w5nTe2WWw`E}@j&%BksJgn^a&o6!Zte*iZk~plCuy2wT(@b~`=6LfrIb@H zGcq?Pf)khsj%4vz45w1@4#{t>Xx+>P@v}YK$pX}*^b`Q-w=A4WrAeS5rC+mk%f2zd zvPD)8snA?oHfLBo79(n!WLHB=rBmO|ybRI+0000gCE literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Actions/changeling.rsi/meta.json b/Resources/Textures/Interface/Actions/changeling.rsi/meta.json index 20c9ed1720..1ba0cdb19d 100644 --- a/Resources/Textures/Interface/Actions/changeling.rsi/meta.json +++ b/Resources/Textures/Interface/Actions/changeling.rsi/meta.json @@ -1,12 +1,18 @@ { "version": 1, "license": "CC0-1.0", - "copyright": "Created by TiniestShark (github)", + "copyright": "Created by TiniestShark (github).", "size": { "x": 32, "y": 32 }, "states": [ + { + "name": "background" + }, + { + "name": "frame" + }, { "name": "transform" }, diff --git a/Resources/Textures/Interface/Actions/changeling2.rsi/biodegrade.png b/Resources/Textures/Interface/Actions/changeling2.rsi/biodegrade.png new file mode 100644 index 0000000000000000000000000000000000000000..caa6e76e9ca5fb0dfa1685808d7cc4efd9258044 GIT binary patch literal 1553 zcmV+s2JZQZP)Px)%Sl8*R9JcYBu*%C;=&F2ZgoxTUo$T11kHp{CY|gj51)K&$cq z0UJVm;ei+oiAf_5#8-nA0uLynrqM(~6=N;7RZ0qNrE95lQ!d%th4Qg%mx^%PULS_J zd-sFd!aupm+?hFZ&iv@v15_p^gIJ8q4MF=4OQ{;CNM)Dck?d3j*Mt?Xt#W zcN4g0ySSO1)yO~xtZ@T*zlZ`r8nUm#@T5seeuHk;Ni-z_OIg>nHo zF)}oovSWMypkWB*GiRU;Ua=JS4G(896>+#JoWB5oV&et?33U`j(kO+FhWq)Xb|dkK zMt$prjD-O9RjdFYsw@IPiw^Pg<+EAm+GXlnFYwxu7cuT94OEU-Rhg%BoyATkN5lOT z%*bJ9c^L;gdL~`)aj>(z3`nwC-`lIGr*xflKA%O~2Q}-7M>JfjV@iuA#wMn0z`>3l zZax@iYoLVs-d+X3QBgPt$D#sCys^?Y^vb z8vs3D9RUObo9dS0&R6*SKxj$^NY(+=Qm>Z;qeO;A@h`}o^z2t}*-qQB!vJimTWa-p z^($O&>!YYL$o00qN6Jga7CW8Doa2DhxSkBLSj=jl>Aa6SU*SyWeFj=WB*rEfXbDlf zyOi49rCEhQBg4mf>yE(!|&VWwqOAJ9e11V~1I|c4G#mKYjVPCD+w2h-^Lw(d&0o z#x&i)ov-lvJH=L?jDidU6_57mDa!I@t7L;~ELR*s zdhV9gg-$l&Eq~c+r=zGc2oJr!t6w4DGYI(Ly6WKfuLn{L)O3Teo~$)erwXFLq!*pl zTebs9&o6%XFT*h1*tI1lBX=RJJDFHApV2-YfZS4_{=7Vu67e38m zr&H7dDJ&{mvib!A0XjQ7Eu|ihhm|W=5)Ow`l-ffp(Gr5nAYjmSX`BtO&P3A<&UB7j zVGAM=Nd{B^&r{E&P#*{cXliOA8jX^3^|CN<;S$_#H-SI^9!5tt477w8c_BcaYbF3) zmr|7jEMK*r`a}CgF>2hg*YwZzGOlOl@i{|b%iHG+B^ODLj&uy44>QmbLeq^5C`+}Iz96ZetZ=1Ag8jH+cM||OY7XsJBDaSreD;+TB>>|KmsoxF zwjGm|>X+Uu%32Gw=#V9^035D;-vs#R`_CwtkwdV$hT`I4%K;^%Zwz<*X7x?=;v$We z7m^%b5dU0n_9GDaej~-jBAdxDY-(!a-ubpi()u`1J5B&`iE&PI$a-V zsNO*Q)-6CVp^C@C0^(P?t%2!aI>vsy<_#j(uF*O?jC=$s`<5-U-gbkA!8)IhJ%6-L z+mQdmfmIbG41@a4vuq8N0D=L<{v`9e-9%zB;Urm}S9Zv2yd95{$u<`tVHm;yfC{gd zi0#q|f{`!!`>hu(*dMTD%$1K+0RP;iQW;^^nA?rZ>7@PEEs=<%5q4A*&dE?BFOm{c zu5!g1+C$wbbC3Snnlg7+S(!O^eBAoKos+|-Jw3{Ql79P$nBL1@00000NkvXXu0mjf DEO6SX literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Actions/changeling2.rsi/meta.json b/Resources/Textures/Interface/Actions/changeling2.rsi/meta.json index a25bf6b528..3a9cf0c5af 100644 --- a/Resources/Textures/Interface/Actions/changeling2.rsi/meta.json +++ b/Resources/Textures/Interface/Actions/changeling2.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Made by ketufaispikinut from a sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 (scientist suit), a sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 (hydro suit) and the changeling ability border/background sprites created by TiniestShark. Mimicry by ketufaispikinut, based on TiniestShark's textures.", + "copyright": "Made by ketufaispikinut from a sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 (scientist suit), a sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 (hydro suit) and the changeling ability border/background sprites created by TiniestShark. Biodegrade and Mimicry by ketufaispikinut, based on TiniestShark's textures.", "size": { "x": 32, "y": 32 @@ -15,6 +15,9 @@ }, { "name": "mimicry" + }, + { + "name": "biodegrade" } ] } From e8f4975f46ba1ff4c495c0a4e073ea9bed63618e Mon Sep 17 00:00:00 2001 From: Pok <113675512+Pok27@users.noreply.github.com> Date: Mon, 27 Apr 2026 23:10:39 +0300 Subject: [PATCH 57/65] Changeling gaining DNA (#43759) * changeling-gain-DNA * review * Return IsUniqueDevour * oops * Update SharedChangelingIdentitySystem.cs * Store data in ChangelingIdentityData + fixes List of changes: - Whether an identity granted devour is now tracked in ChangelingIdentityData - Made devoured shutdown cleanup again - Made server set the mind to null if it never found one, instead of being invalid Fixes: - Fixed name being networked as empty if original was deleted --------- Co-authored-by: ScarKy0 --- .../Systems/ChangelingIdentitySystem.cs | 1 + .../Systems/ChangelingIdentitySystem.cs | 3 +- .../Components/ChangelingDevourComponent.cs | 21 ++++-- .../Components/ChangelingDevouredComponent.cs | 10 +-- .../Components/ChangelingIdentityComponent.cs | 9 +++ .../Components/RecentlyDevouredComponent.cs | 9 +++ .../Systems/ChangelingDevourSystem.cs | 70 ++++++++++++------- .../Systems/SharedChangelingIdentitySystem.cs | 45 +++++++----- 8 files changed, 111 insertions(+), 57 deletions(-) create mode 100644 Content.Shared/Changeling/Components/RecentlyDevouredComponent.cs diff --git a/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs b/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs index 917eeefc08..1dbf2ad920 100644 --- a/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs +++ b/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs @@ -33,6 +33,7 @@ public sealed class ChangelingIdentitySystem : SharedChangelingIdentitySystem OriginalJob = identity.OriginalJob, OriginalName = identity.OriginalName, Starting = identity.Starting, + GrantedDna = identity.GrantedDna, }; ent.Comp.ConsumedIdentities.Add(data); diff --git a/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs b/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs index 6f7556196c..2d2eb04348 100644 --- a/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs +++ b/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs @@ -24,8 +24,9 @@ public sealed class ChangelingIdentitySystem : SharedChangelingIdentitySystem Identity = GetNetEntity(identity.Identity), Original = GetNetEntity(identity.Original), OriginalJob = identity.OriginalJob, - OriginalName = identity.Original != null ? Name(identity.Original.Value) : string.Empty, + OriginalName = identity.OriginalName, Starting = identity.Starting, + GrantedDna = identity.GrantedDna, }; sentIdentities.Add(netData); diff --git a/Content.Shared/Changeling/Components/ChangelingDevourComponent.cs b/Content.Shared/Changeling/Components/ChangelingDevourComponent.cs index 1f8b3c81d3..425d64f4a9 100644 --- a/Content.Shared/Changeling/Components/ChangelingDevourComponent.cs +++ b/Content.Shared/Changeling/Components/ChangelingDevourComponent.cs @@ -1,6 +1,8 @@ using Content.Shared.Changeling.Systems; using Content.Shared.Damage; using Content.Shared.Damage.Prototypes; +using Content.Shared.FixedPoint; +using Content.Shared.Store; using Content.Shared.Whitelist; using Robust.Shared.Audio; using Robust.Shared.GameStates; @@ -125,6 +127,15 @@ public sealed partial class ChangelingDevourComponent : Component [DataField, AutoNetworkedField] public float DevourPreventionPercentageThreshold = 0.1f; + /// + /// DNA awarded for successfully devouring a new identity. + /// + [DataField, AutoNetworkedField] + public Dictionary DevourDnaReward = new() + { + { "ChangelingDNA", 10 } + }; + public override bool SendOnlyToOwner => true; } @@ -134,9 +145,10 @@ public sealed partial class ChangelingDevourComponent : Component /// The changeling devouring this entity. /// The entity that was devoured. /// Whether the changeling is going to be given the target's identity after devouring. -/// Whether this entity was eaten by the changeling before. +/// Whether the changeling has never had the identity of this target before. +/// Whether this devour has granted the changeling Dna. [ByRefEvent] -public record struct ChangelingDevouredEvent(EntityUid Changeling, EntityUid Devoured, bool ObtainedIdentity, bool Unique); +public record struct ChangelingDevouredEvent(EntityUid Changeling, EntityUid Devoured, bool ObtainedIdentity, bool Unique, bool GrantedDna); /// /// Event raised on an entity when devoured by a changeling. @@ -144,6 +156,7 @@ public record struct ChangelingDevouredEvent(EntityUid Changeling, EntityUid Dev /// The changeling devouring this entity. /// The entity that was devoured. /// Whether the changeling is going to be given the target's identity after devouring. -/// Whether this entity was eaten by the changeling before. +/// Whether the changeling has never had the identity of this target before. +/// Whether this devour has granted the changeling Dna. [ByRefEvent] -public record struct ChangelingGotDevouredEvent(EntityUid Changeling, EntityUid Devoured, bool ObtainedIdentity, bool Unique); +public record struct ChangelingGotDevouredEvent(EntityUid Changeling, EntityUid Devoured, bool ObtainedIdentity, bool Unique, bool GrantedDna); diff --git a/Content.Shared/Changeling/Components/ChangelingDevouredComponent.cs b/Content.Shared/Changeling/Components/ChangelingDevouredComponent.cs index f25489fe1f..7e7fa94b14 100644 --- a/Content.Shared/Changeling/Components/ChangelingDevouredComponent.cs +++ b/Content.Shared/Changeling/Components/ChangelingDevouredComponent.cs @@ -4,18 +4,12 @@ namespace Content.Shared.Changeling.Components; /// /// Component used for marking entities devoured by a changeling. -/// Used to prevent granting the identity several times. +/// Used to track which changelings have an identity of this entity. +/// Used for cleanup purposes. /// [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class ChangelingDevouredComponent : Component { - /// - /// Whether this entity has been devoured recently. - /// Gets set back to False when the entity with this component becomes again. - /// - [DataField, AutoNetworkedField] - public bool Recent; - /// /// HashSet of all changelings that have devoured this entity. /// diff --git a/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs b/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs index affec705ab..dcb65d5641 100644 --- a/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs +++ b/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs @@ -112,6 +112,12 @@ public sealed partial class ChangelingIdentityData [DataField] public bool Starting = false; + /// + /// Whether this identity has granted DNA after devour. + /// + [DataField] + public bool GrantedDna = false; + /// /// Convert to a string representation. This if for logging & debugging. This is not localized and should not be /// shown to players. @@ -143,4 +149,7 @@ public sealed partial class ChangelingNetworkedIdentityData [DataField] public bool Starting; + + [DataField] + public bool GrantedDna; } diff --git a/Content.Shared/Changeling/Components/RecentlyDevouredComponent.cs b/Content.Shared/Changeling/Components/RecentlyDevouredComponent.cs new file mode 100644 index 0000000000..a48565ee54 --- /dev/null +++ b/Content.Shared/Changeling/Components/RecentlyDevouredComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Changeling.Components; + +/// +/// Marker component for entities that were devoured recently and cannot be devoured again until revived. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class RecentlyDevouredComponent : Component; diff --git a/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs b/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs index 6d07fb9378..63aad8b4d6 100644 --- a/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs +++ b/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs @@ -4,6 +4,7 @@ using Content.Shared.Administration.Logs; using Content.Shared.Armor; using Content.Shared.Atmos.Rotting; using Content.Shared.Changeling.Components; +using Content.Shared.Store; using Content.Shared.Damage.Systems; using Content.Shared.Database; using Content.Shared.DoAfter; @@ -12,6 +13,7 @@ using Content.Shared.IdentityManagement; using Content.Shared.Inventory; using Content.Shared.Mobs.Systems; using Content.Shared.Popups; +using Content.Shared.Store.Components; using Content.Shared.Whitelist; using Robust.Shared.Audio.Systems; using Robust.Shared.Network; @@ -20,16 +22,17 @@ namespace Content.Shared.Changeling.Systems; public sealed class ChangelingDevourSystem : EntitySystem { + [Dependency] private readonly DamageableSystem _damageable = default!; + [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedChangelingIdentitySystem _changelingIdentitySystem = default!; [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; [Dependency] private readonly SharedPopupSystem _popupSystem = default!; - [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; - [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; - [Dependency] private readonly DamageableSystem _damageable = default!; - [Dependency] private readonly MobStateSystem _mobState = default!; - [Dependency] private readonly SharedChangelingIdentitySystem _changelingIdentitySystem = default!; - [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly SharedStoreSystem _store = default!; public override void Initialize() { @@ -167,17 +170,24 @@ public sealed class ChangelingDevourSystem : EntitySystem _adminLogger.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(ent.Owner):player} successfully devoured {ToPrettyString(target):player}'s identity"); - // If this entity has never been devoured before, it counts as unique. - var unique = !_changelingIdentitySystem.TryGetDataFromOriginal(ent.Owner, target, out _); + // A unique identity is separate from whether we have actually devoured this target before. + var uniqueIdentity = IsUniqueDevour(ent.Owner, target); + var willGrantDna = WillDevourGrantDna(ent.Owner, target); // Even if not unique, target is supposed to give us an identity if it is not currently in our identity list. var becomesIdentity = !HasIdentity(ent.Owner, target); - var ev = new ChangelingDevouredEvent(ent.Owner, target, becomesIdentity, unique); + var ev = new ChangelingDevouredEvent(ent.Owner, target, becomesIdentity, uniqueIdentity, willGrantDna); RaiseLocalEvent(ent, ref ev, true); // We broadcast the event to allow relevant objectives to update. - var devouredEv = new ChangelingGotDevouredEvent(ent.Owner, target, becomesIdentity, unique); + var devouredEv = new ChangelingGotDevouredEvent(ent.Owner, target, becomesIdentity, uniqueIdentity, willGrantDna); RaiseLocalEvent(target, ref devouredEv); // Don't broadcast this one, all neccessary data is in the previous event already. Just use that one if a broadcast is needed. + + EnsureComp(target); + + // Grants the DNA reward associated with a successful unique devour. + if (willGrantDna && TryComp(ent, out var store)) + _store.TryAddCurrency(ent.Comp.DevourDnaReward, ent.Owner, store); } /// @@ -191,17 +201,6 @@ public sealed class ChangelingDevourSystem : EntitySystem return changeling.Comp.ConsumedIdentities.FirstOrDefault(data => data.Original == devoured && data.Identity != null) != null; } - /// - /// Has this entity been devoured by a changeling already before getting revived? - /// - public bool WasDevouredRecently(Entity entity) - { - if (!Resolve(entity, ref entity.Comp, false)) - return false; - - return entity.Comp.Recent; - } - /// /// Can the given changeling devour the given victim? /// @@ -220,7 +219,7 @@ public sealed class ChangelingDevourSystem : EntitySystem return false; } - if (WasDevouredRecently(victim)) + if (HasComp(victim)) { if (showPopup) _popupSystem.PopupClient(Loc.GetString("changeling-devour-attempt-failed-devoured-recently"), changeling.Owner, changeling.Owner, PopupType.Medium); @@ -282,16 +281,35 @@ public sealed class ChangelingDevourSystem : EntitySystem } /// - /// Checks whether this changeling has devoured the target entity at any point before. + /// Checks whether devouring this target has never been devoured by the changeling before. /// /// The changeling. /// The target entity. - /// True if target was previously devoured, False otherwise. + /// True if the target was never devoured before, otherwise False. public bool IsUniqueDevour(Entity ent, EntityUid devoured) { if (!Resolve(ent, ref ent.Comp, false)) return false; - return _changelingIdentitySystem.TryGetDataFromOriginal(ent, devoured, out _); + return !_changelingIdentitySystem.TryGetDataFromOriginal(ent, devoured, out _); + } + + /// + /// Checks whether devouring this entity will grant DNA to the changeling. + /// + /// The changeling. + /// The target entity. + /// True if this target entity has granted the changeling DNA before, False otherwise. + public bool WillDevourGrantDna(Entity ent, EntityUid devoured) + { + if (!Resolve(ent, ref ent.Comp, false)) + return false; + + // This target was never devoured, so obviously it can grant us DNA. + if (!_changelingIdentitySystem.TryGetDataFromOriginal(ent, devoured, out var data)) + return true; + + // If the entity was Devoured, it means it already granted DNA, so we return False. + return !data.GrantedDna; } } diff --git a/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs b/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs index 307c6a2132..a6c1379a7a 100644 --- a/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs +++ b/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs @@ -37,23 +37,21 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem SubscribeLocalEvent(OnStoredRemove); SubscribeLocalEvent(OnDevouredShutdown); - SubscribeLocalEvent(OnDevouredMobState); + SubscribeLocalEvent(OnRecentlyDevouredMobState); } private void OnDevouredEntity(Entity ent, ref ChangelingDevouredEvent args) { - // We're not supposed to be given an identity. - if (!args.ObtainedIdentity) - return; + if (args.ObtainedIdentity) + { + CloneToPausedMap(ent, args.Devoured); + AddDevouredReference(ent, args.Devoured); + } - CloneToPausedMap(ent, args.Devoured); - - // We add a reference to ourselves to prevent repeated identity gain. - var targetDevoured = EnsureComp(args.Devoured); - targetDevoured.DevouredBy.Add(ent.Owner); - targetDevoured.Recent = true; - Dirty(args.Devoured, targetDevoured); - Dirty(ent); + if (args.GrantedDna && TryGetDataFromOriginal(ent.AsNullable(), args.Devoured, out var data)) + { + data.GrantedDna = true; + } } private void OnPlayerAttached(Entity ent, ref PlayerAttachedEvent args) @@ -75,6 +73,7 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem return; data.Starting = true; + data.GrantedDna = true; // I have no idea how you're supposed to ever get DNA from yourself, but just in case. ent.Comp.CurrentIdentity = data.Identity; } @@ -100,14 +99,13 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem } } - private void OnDevouredMobState(Entity ent, ref MobStateChangedEvent args) + private void OnRecentlyDevouredMobState(Entity ent, ref MobStateChangedEvent args) { - // Once we are revived the body is no longer "recent". + // Once we are revived the body is no longer recently devoured. if (args.NewMobState != MobState.Alive) return; - ent.Comp.Recent = false; - Dirty(ent); + RemCompDeferred(ent); } private void OnStoredRemove(Entity ent, ref ComponentRemove args) @@ -222,6 +220,17 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem return clone; } + /// + /// Marks that the changeling has successfully devoured the target. + /// + public void AddDevouredReference(Entity ent, EntityUid target) + { + var targetDevoured = EnsureComp(target); + targetDevoured.DevouredBy.Add(ent.Owner); + + Dirty(target, targetDevoured); + } + /// /// Drop a stored identity from the changeling's storage. /// @@ -348,10 +357,10 @@ public abstract class SharedChangelingIdentitySystem : EntitySystem { data.Identity = identity; data.Original = original; - data.OriginalName = Name(identity); + data.OriginalName = Name(original); var foundMind = _mind.TryGetMind(original, out var mindId, out _); - data.OriginalMind = mindId; + data.OriginalMind = foundMind ? mindId : null; if (foundMind) { From cc2b117175851fc40ae424f219299dd65db5de35 Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Tue, 28 Apr 2026 09:31:52 -0400 Subject: [PATCH 58/65] Fix mapping autosaves (#39587) Fix autosaves while mapping --- Content.Server/Mapping/MappingSystem.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Content.Server/Mapping/MappingSystem.cs b/Content.Server/Mapping/MappingSystem.cs index bc086a7aca..f9b41ecece 100644 --- a/Content.Server/Mapping/MappingSystem.cs +++ b/Content.Server/Mapping/MappingSystem.cs @@ -73,10 +73,10 @@ public sealed class MappingSystem : EntitySystem } _currentlyAutosaving[uid] = (CalculateNextTime(), name); - var saveDir = Path.Combine(_cfg.GetCVar(CCVars.AutosaveDirectory), name).Replace(Path.DirectorySeparatorChar, '/'); - _resMan.UserData.CreateDir(new ResPath(saveDir).ToRootedPath()); + var saveDir = new ResPath(Path.Combine(_cfg.GetCVar(CCVars.AutosaveDirectory), name).Replace(Path.DirectorySeparatorChar, '/')); + _resMan.UserData.CreateDir(saveDir.ToRootedPath()); - var path = new ResPath(Path.Combine(saveDir, $"{DateTime.Now:yyyy-M-dd_HH.mm.ss}-AUTO.yml")); + var path = saveDir / new ResPath($"{DateTime.Now:yyyy-M-dd_HH.mm.ss}-AUTO.yml"); Log.Info($"Autosaving map {name} ({uid}) to {path}. Next save in {ReadableTimeLeft(uid)} seconds."); if (HasComp(uid)) From 93de34cc53af416b1c7b5464880dcdd81815115c Mon Sep 17 00:00:00 2001 From: GR1231 <200696955+GR1231@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:52:19 +0200 Subject: [PATCH 59/65] Make cyborgs magnetize items (#39970) * Make borgs magnetize ore * nullable SlotFlags * add hand check * fix and cleanup * description edit --- .../Storage/Components/MagnetPickupComponent.cs | 11 +++++++---- .../Storage/EntitySystems/MagnetPickupSystem.cs | 17 +++++++++++++---- .../Objects/Specific/Robotics/borg_modules.yml | 2 +- .../Objects/Specific/Salvage/ore_bag.yml | 5 ++++- .../Specific/Salvage/ore_bag_holding.yml | 11 +++++++++++ 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/Content.Shared/Storage/Components/MagnetPickupComponent.cs b/Content.Shared/Storage/Components/MagnetPickupComponent.cs index 72a9c81077..7d9dfe6d51 100644 --- a/Content.Shared/Storage/Components/MagnetPickupComponent.cs +++ b/Content.Shared/Storage/Components/MagnetPickupComponent.cs @@ -11,7 +11,7 @@ namespace Content.Shared.Storage.Components; [AutoGenerateComponentPause] public sealed partial class MagnetPickupComponent : Component { - [ViewVariables(VVAccess.ReadWrite), DataField("nextScan")] + [DataField] [AutoPausedField] [AutoNetworkedField] public TimeSpan NextScan = TimeSpan.Zero; @@ -19,9 +19,12 @@ public sealed partial class MagnetPickupComponent : Component /// /// What container slot the magnet needs to be in to work. /// - [ViewVariables(VVAccess.ReadWrite), DataField("slotFlags")] - public SlotFlags SlotFlags = SlotFlags.BELT; + [DataField] + public SlotFlags? SlotFlags = Inventory.SlotFlags.BELT; - [ViewVariables(VVAccess.ReadWrite), DataField("range")] + [DataField] + public bool RequireActiveHand = false; + + [DataField] public float Range = 1f; } diff --git a/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs b/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs index 6d33fac51f..6f64002cc4 100644 --- a/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs +++ b/Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs @@ -1,3 +1,4 @@ +using Content.Shared.Hands.EntitySystems; using Content.Shared.Inventory; using Content.Shared.Storage.Components; using Content.Shared.Whitelist; @@ -17,6 +18,7 @@ public sealed class MagnetPickupSystem : EntitySystem [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedStorageSystem _storage = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; + [Dependency] private readonly SharedHandsSystem _hands = default!; [Dependency] private readonly EntityQuery _physicsQuery = default!; @@ -48,17 +50,24 @@ public sealed class MagnetPickupSystem : EntitySystem comp.NextScan += ScanDelay; Dirty(uid, comp); - if (!_inventory.TryGetContainingSlot((uid, xform, meta), out var slotDef)) + var parentUid = xform.ParentUid; + + if (comp.RequireActiveHand && (!_hands.TryGetActiveItem(parentUid, out var activeItem) || activeItem != uid)) continue; - if ((slotDef.SlotFlags & comp.SlotFlags) == 0x0) - continue; + if (comp.SlotFlags != null) + { + if (!_inventory.TryGetContainingSlot((uid, xform, meta), out var slotDef)) + continue; + + if ((slotDef.SlotFlags & comp.SlotFlags) == 0x0) + continue; + } // No space if (!_storage.HasSpace((uid, storage))) continue; - var parentUid = xform.ParentUid; var playedSound = false; var finalCoords = xform.Coordinates; var moverCoords = _transform.GetMoverCoordinates(uid, xform); diff --git a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml index 64311dcde6..8ebbb170a9 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml @@ -649,7 +649,7 @@ - item: MiningDrillDiamond - item: Shovel - item: AdvancedMineralScannerUnpowered - - item: OreBagOfHolding + - item: BorgOreBagOfHolding - type: BorgModuleIcon icon: { sprite: Interface/Actions/actions_borg.rsi, state: adv-mining-module } diff --git a/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml b/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml index 87643773db..dbaa50b912 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag.yml @@ -31,8 +31,11 @@ parent: OreBag id: BorgOreBag name: integrated ore bag - description: A large ore bag built into the frame of a mining cyborg. + description: A large ore bag built into the frame of a mining cyborg. Magnetises any nearby ores when held. components: + - type: MagnetPickup + slotFlags: null + requireActiveHand: true - type: Storage grid: - 0,0,9,5 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag_holding.yml b/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag_holding.yml index e8c7fa37dd..c69de6db99 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag_holding.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Salvage/ore_bag_holding.yml @@ -14,3 +14,14 @@ - type: Storage grid: - 0,0,19,9 + +- type: entity + parent: OreBagOfHolding + id: BorgOreBagOfHolding + name: integrated ore bag of holding + description: A very large ore bag built into the frame of a rich mining cyborg. Magnetises any nearby ores when held. + components: + - type: MagnetPickup + slotFlags: null + range: 2 + requireActiveHand: true From eab71ebe1cd587a20c39c8115c3bbbe21d7dd90c Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 28 Apr 2026 15:21:56 +0000 Subject: [PATCH 60/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index ce5cff7f86..379adcb626 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,4 @@ Entries: -- author: ArtisticRoomba - changes: - - message: Examine text for whether an object is currently taking Delta-Pressure - damage is predicted, so you no longer have to wait for it to pop into place, - it just shows up instantly. - type: Tweak - id: 9162 - time: '2025-10-27T11:12:17.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/41135 - author: lzk228 changes: - message: Water cup spills when worn @@ -4069,3 +4060,10 @@ id: 9673 time: '2026-04-27T15:53:41.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/43722 +- author: GR1231 + changes: + - message: Salvage cyborgs can now magnetize ore with integrated ore bags. + type: Add + id: 9674 + time: '2026-04-28T15:20:44.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/39970 From dc384024ac4480f7eb11adb63d06277ccbc5d440 Mon Sep 17 00:00:00 2001 From: Jessica M Date: Tue, 28 Apr 2026 08:09:20 -0700 Subject: [PATCH 61/65] Fix loot not spawning on VGRoid (#39269) * Ignore reserved tiles if we're pulling from a NestedSelector so normal items can spawn on reserved tiles. * Make VGRoid item spawns per dungeon, so they don't only spawn inside one dungeon * add a IgnoreReserved field instead --------- Co-authored-by: Jessica M --- .../Procedural/DungeonJob/DungeonJob.EntityTableDunGen.cs | 3 ++- .../Procedural/DungeonLayers/EntityTableDunGen.cs | 6 ++++++ Resources/Prototypes/Procedural/vgroid.yml | 8 ++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Content.Server/Procedural/DungeonJob/DungeonJob.EntityTableDunGen.cs b/Content.Server/Procedural/DungeonJob/DungeonJob.EntityTableDunGen.cs index 6483448240..92d51e2770 100644 --- a/Content.Server/Procedural/DungeonJob/DungeonJob.EntityTableDunGen.cs +++ b/Content.Server/Procedural/DungeonJob/DungeonJob.EntityTableDunGen.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Content.Server.Ghost.Roles.Components; using Content.Server.NPC.Systems; using Content.Shared.EntityTable; +using Content.Shared.EntityTable.EntitySelectors; using Content.Shared.Physics; using Content.Shared.Procedural; using Content.Shared.Procedural.DungeonLayers; @@ -36,7 +37,7 @@ public sealed partial class DungeonJob if (!ValidateResume()) return; - if (reservedTiles.Contains(tile)) + if (reservedTiles.Contains(tile) && !gen.IgnoreReserved) continue; if (!_anchorable.TileFree((_gridUid, _grid), diff --git a/Content.Shared/Procedural/DungeonLayers/EntityTableDunGen.cs b/Content.Shared/Procedural/DungeonLayers/EntityTableDunGen.cs index 9f19909569..c5ba9a12ca 100644 --- a/Content.Shared/Procedural/DungeonLayers/EntityTableDunGen.cs +++ b/Content.Shared/Procedural/DungeonLayers/EntityTableDunGen.cs @@ -24,4 +24,10 @@ public sealed partial class EntityTableDunGen : IDunGenLayer /// [DataField] public bool PerDungeon; + + /// + /// Should the spawner ignore reserved tiles. + /// + [DataField] + public bool IgnoreReserved; } diff --git a/Resources/Prototypes/Procedural/vgroid.yml b/Resources/Prototypes/Procedural/vgroid.yml index 7cc40dbb8f..d182a7bdae 100644 --- a/Resources/Prototypes/Procedural/vgroid.yml +++ b/Resources/Prototypes/Procedural/vgroid.yml @@ -155,21 +155,29 @@ - !type:EntityTableDunGen minCount: 25 maxCount: 40 + perDungeon: true + ignoreReserved: true table: !type:NestedSelector tableId: SalvageScrapSpawnerCommon - !type:EntityTableDunGen minCount: 30 maxCount: 40 + perDungeon: true + ignoreReserved: true table: !type:NestedSelector tableId: SalvageScrapSpawnerValuable - !type:EntityTableDunGen minCount: 30 maxCount: 45 + perDungeon: true + ignoreReserved: true table: !type:NestedSelector tableId: SalvageTreasureSpawnerCommon - !type:EntityTableDunGen minCount: 30 maxCount: 45 + perDungeon: true + ignoreReserved: true table: !type:NestedSelector tableId: SalvageTreasureSpawnerValuable - !type:MobsDunGen From 9e541fbcb34468e7e73f2cd15a8194b19cab568c Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 28 Apr 2026 15:39:02 +0000 Subject: [PATCH 62/65] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 379adcb626..3b7e3ebe17 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: lzk228 - changes: - - message: Water cup spills when worn - type: Tweak - id: 9163 - time: '2025-10-27T18:56:16.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/41148 - author: Princess-Cheeseballs changes: - message: Wizard is now only a midround spawn. @@ -4067,3 +4060,10 @@ id: 9674 time: '2026-04-28T15:20:44.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/39970 +- author: jessicamaybe + changes: + - message: Loot now spawns on the VGRoid again. + type: Fix + id: 9675 + time: '2026-04-28T15:37:53.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/39269 From 807ea698604dbcc2a6dc359098bcce8488b4b701 Mon Sep 17 00:00:00 2001 From: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Date: Tue, 28 Apr 2026 20:24:15 +0200 Subject: [PATCH 63/65] Changeling move when transforming (#43795) * I love microbalance * Update Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- .../Changeling/Components/ChangelingTransformComponent.cs | 2 +- .../Changeling/Systems/ChangelingTransformSystem.cs | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Content.Shared/Changeling/Components/ChangelingTransformComponent.cs b/Content.Shared/Changeling/Components/ChangelingTransformComponent.cs index 7b465ea3b2..3a52744911 100644 --- a/Content.Shared/Changeling/Components/ChangelingTransformComponent.cs +++ b/Content.Shared/Changeling/Components/ChangelingTransformComponent.cs @@ -30,7 +30,7 @@ public sealed partial class ChangelingTransformComponent : Component /// Time it takes to Transform /// [DataField, AutoNetworkedField] - public TimeSpan TransformWindup = TimeSpan.FromSeconds(5); + public TimeSpan TransformWindup = TimeSpan.FromSeconds(4f); /// /// The noise used when attempting to transform diff --git a/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs b/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs index 28eb55110e..74e13ff2e9 100644 --- a/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs +++ b/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs @@ -156,8 +156,6 @@ public sealed partial class ChangelingTransformSystem : EntitySystem ent, target: targetIdentity) { - BreakOnMove = true, - BreakOnWeightlessMove = true, DuplicateCondition = DuplicateConditions.None, RequireCanInteract = false, DistanceThreshold = null, @@ -168,10 +166,14 @@ public sealed partial class ChangelingTransformSystem : EntitySystem ref ChangelingTransformDoAfterEvent args) { args.Handled = true; - ent.Comp.CurrentTransformSound = _audio.Stop(ent.Comp.CurrentTransformSound); if (args.Cancelled) + { + // Only stop the sound if we finish transforming successfully. + ent.Comp.CurrentTransformSound = _audio.Stop(ent.Comp.CurrentTransformSound); return; + } + ent.Comp.CurrentTransformSound = null; if (!_prototype.Resolve(ent.Comp.TransformCloningSettings, out var settings)) return; From 4d7a8e6e2896434d24f45f31290f136c541e47b3 Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Tue, 28 Apr 2026 12:22:12 -0700 Subject: [PATCH 64/65] Correctly Size Milk Cartons (#43787) change parents Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- .../Consumable/Drinks/drinks-cartons.yml | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml index d655517df9..67eebea932 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [ DrinkBaseMaterialCardboard, SolutionNormal, DrinkBase, DrinkBaseOpenable, DrinkVisualsOpenable, DrinkBaseEmptyTrash ] + parent: [ DrinkBaseMaterialCardboard, SolutionSmall, DrinkBase, DrinkBaseOpenable, DrinkVisualsOpenable, DrinkBaseEmptyTrash ] id: DrinkCartonBase components: - type: Openable @@ -21,16 +21,16 @@ - type: entity abstract: true - parent: [SolutionSmall, DrinkCartonBase ] - id: DrinkCartonSmallBase + parent: [SolutionNormal, DrinkCartonBase ] + id: DrinkCartonNormalBase components: - type: Item - size: Small + size: Normal - type: entity abstract: true - parent: DrinkCartonSmallBase - id: DrinkCartonSmallBaseFull + parent: DrinkCartonNormalBase + id: DrinkCartonNormalBaseFull suffix: Full components: - type: Tag @@ -63,7 +63,7 @@ # Small carton - type: entity - parent: [DrinkBaseMaterialPlastic, DrinkCartonSmallBase] + parent: [DrinkBaseMaterialPlastic, DrinkCartonBase] id: DrinkCartonLime name: lime juice description: Sweet-sour goodness. @@ -85,7 +85,7 @@ tags: [ ] - type: entity - parent: DrinkCartonSmallBase + parent: DrinkCartonBase id: DrinkCartonOrange name: orange juice description: Full of vitamins and deliciousness! @@ -107,7 +107,7 @@ tags: [ ] - type: entity - parent: DrinkCartonSmallBase + parent: DrinkCartonBase id: DrinkCartonTomato name: tomato juice description: Well, at least it LOOKS like tomato juice. You can't tell with all that redness. @@ -129,7 +129,7 @@ tags: [] - type: entity - parent: DrinkCartonSmallBaseFull + parent: DrinkCartonBaseFull id: DrinkCoconutWaterCarton name: coconut water description: It's the inside of the coconut that counts. @@ -143,7 +143,7 @@ sprite: Objects/Consumable/Drinks/coconutwater.rsi - type: entity - parent: DrinkCartonSmallBase + parent: DrinkCartonBase id: DrinkCartonCream name: milk cream description: It's cream. Made from milk. What else did you think you'd find in there? @@ -165,7 +165,7 @@ tags: [ ] - type: entity - parent: [DrinkBaseMaterialPlastic, DrinkCartonSmallBaseFull] + parent: [DrinkBaseMaterialPlastic, DrinkCartonBaseFull] id: DrinkJuiceLemonCarton name: lemon juice description: First it's sour, then it's still sour. @@ -179,7 +179,7 @@ sprite: Objects/Consumable/Drinks/lemonjuice.rsi - type: entity - parent: DrinkCartonSmallBaseFull + parent: DrinkCartonBaseFull id: DrinkJuicePineappleCarton name: pineapple juice description: Tastes like a tropical vacation far from space. @@ -195,7 +195,7 @@ # Normal sized cartons - type: entity - parent: [DrinkBaseMaterialPlastic, DrinkCartonBase] # Looks like a plastic jug, fight me + parent: [DrinkBaseMaterialPlastic, DrinkCartonNormalBase] # Looks like a plastic jug, fight me id: DrinkCartonMilk name: milk description: An opaque white liquid produced by the mammary glands of mammals. @@ -217,7 +217,7 @@ tags: [ ] - type: entity - parent: DrinkCartonBase + parent: DrinkCartonNormalBase id: DrinkCartonSoyMilk name: soy milk description: White and nutritious soy goodness! @@ -239,7 +239,7 @@ tags: [ ] - type: entity - parent: [DrinkBaseMaterialPlastic, DrinkCartonBase] + parent: [DrinkBaseMaterialPlastic, DrinkCartonNormalBase] id: DrinkCartonOatMilk name: oat milk description: It's oat milk. Tan and nutritious goodness! From 510e9e613908460f04099f715736fa249894f639 Mon Sep 17 00:00:00 2001 From: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Date: Tue, 28 Apr 2026 21:25:17 +0200 Subject: [PATCH 65/65] Changeling store initial balance (#43796) * yeah * whipped out my calculator for this one --- Resources/Locale/en-US/store/categories.ftl | 5 +++++ .../Prototypes/Catalog/changeling_catalog.yml | 16 ++++++++-------- .../Entities/Mobs/Player/changeling.yml | 6 +++--- Resources/Prototypes/Roles/Antags/changeling.yml | 6 ++++-- Resources/Prototypes/Store/categories.yml | 12 ++++++++++-- Resources/Prototypes/Store/presets.yml | 4 +++- 6 files changed, 33 insertions(+), 16 deletions(-) diff --git a/Resources/Locale/en-US/store/categories.ftl b/Resources/Locale/en-US/store/categories.ftl index 9ecf4f91d2..58dc49e8e1 100644 --- a/Resources/Locale/en-US/store/categories.ftl +++ b/Resources/Locale/en-US/store/categories.ftl @@ -27,3 +27,8 @@ store-caregory-spellbook-events = Event Spells # Nukie Delivery store-category-nukie-delivery = Offers + +# Changeling +store-category-combat = Combat +store-category-utility = Utility +store-category-stealth = Stealth diff --git a/Resources/Prototypes/Catalog/changeling_catalog.yml b/Resources/Prototypes/Catalog/changeling_catalog.yml index 1a6790bc07..c15fbde62c 100644 --- a/Resources/Prototypes/Catalog/changeling_catalog.yml +++ b/Resources/Prototypes/Catalog/changeling_catalog.yml @@ -6,9 +6,9 @@ description: changeling-catalog-arm-blade-desc applyToMob: true cost: - ChangelingDNA: 25 + ChangelingDNA: 30 categories: - - ChangelingAbilities + - ChangelingStoreCombat conditions: - !type:ListingLimitedStockCondition stock: 1 @@ -20,9 +20,9 @@ description: changeling-catalog-flesh-clothing-desc icon: { sprite: /Textures/Interface/Actions/changeling2.rsi, state: flesh_clothing } cost: - ChangelingDNA: 10 + ChangelingDNA: 20 categories: - - ChangelingAbilities + - ChangelingStoreStealth conditions: - !type:ListingLimitedStockCondition stock: 1 @@ -34,9 +34,9 @@ description: changeling-catalog-voice-mimic-desc icon: { sprite: /Textures/Interface/Actions/changeling2.rsi, state: mimicry} cost: - ChangelingDNA: 10 + ChangelingDNA: 20 categories: - - ChangelingAbilities + - ChangelingStoreUtility conditions: - !type:ListingLimitedStockCondition stock: 1 @@ -49,9 +49,9 @@ icon: { sprite: /Textures/Interface/Actions/changeling2.rsi, state: biodegrade } applyToMob: true cost: - ChangelingDNA: 10 + ChangelingDNA: 20 categories: - - ChangelingAbilities + - ChangelingStoreUtility conditions: - !type:ListingLimitedStockCondition stock: 1 diff --git a/Resources/Prototypes/Entities/Mobs/Player/changeling.yml b/Resources/Prototypes/Entities/Mobs/Player/changeling.yml index 7deb62238b..8ece41546e 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/changeling.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/changeling.yml @@ -12,7 +12,7 @@ - ActionChangelingStore - type: Store balance: - ChangelingDNA: 50 + ChangelingDNA: 60 - type: entity # dummy prototype for the store listing id: ChangelingFleshClothingAbilityStoreDummy @@ -42,6 +42,6 @@ action: ActionChangelingVoiceMimic isInnate: true changeIDName: false - # this is set to false as to not mess with a changeling's ability to disguise. + # this is set to false as to not mess with a changeling's ability to disguise. accentHide: false - titleText: changeling-voice-mimic-window-title \ No newline at end of file + titleText: changeling-voice-mimic-window-title diff --git a/Resources/Prototypes/Roles/Antags/changeling.yml b/Resources/Prototypes/Roles/Antags/changeling.yml index bef0fb71d1..76df0c6069 100644 --- a/Resources/Prototypes/Roles/Antags/changeling.yml +++ b/Resources/Prototypes/Roles/Antags/changeling.yml @@ -23,10 +23,12 @@ - type: Store name: store-preset-name-changeling categories: - - ChangelingAbilities + - ChangelingStoreCombat + - ChangelingStoreStealth + - ChangelingStoreUtility currencyWhitelist: - ChangelingDNA balance: - ChangelingDNA: 50 + ChangelingDNA: 60 mindRoles: - MindRoleChangeling diff --git a/Resources/Prototypes/Store/categories.yml b/Resources/Prototypes/Store/categories.yml index a4c339d0e7..8580c1c5b2 100644 --- a/Resources/Prototypes/Store/categories.yml +++ b/Resources/Prototypes/Store/categories.yml @@ -113,8 +113,16 @@ #changeling #todo: add actual categories when changeling design/abilities are fleshed out - type: storeCategory - id: ChangelingAbilities - name: store-category-abilities + id: ChangelingStoreCombat + name: store-category-combat + +- type: storeCategory + id: ChangelingStoreUtility + name: store-category-utility + +- type: storeCategory + id: ChangelingStoreStealth + name: store-category-stealth - type: storeCategory id: DiscountedItems diff --git a/Resources/Prototypes/Store/presets.yml b/Resources/Prototypes/Store/presets.yml index d4c1245c55..4744124012 100644 --- a/Resources/Prototypes/Store/presets.yml +++ b/Resources/Prototypes/Store/presets.yml @@ -48,7 +48,9 @@ - type: Store name: store-preset-name-changeling categories: - - ChangelingAbilities + - ChangelingStoreCombat + - ChangelingStoreStealth + - ChangelingStoreUtility currencyWhitelist: - ChangelingDNA