diff --git a/Content.Server/Anomaly/Components/InjectionAnomalyComponent.cs b/Content.Server/Anomaly/Components/InjectionAnomalyComponent.cs
new file mode 100644
index 0000000000..4a9b5b6b55
--- /dev/null
+++ b/Content.Server/Anomaly/Components/InjectionAnomalyComponent.cs
@@ -0,0 +1,47 @@
+using Content.Server.Anomaly.Effects;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.Anomaly.Components;
+
+///
+/// This component allows the anomaly to inject liquid from the SolutionContainer
+/// into the surrounding entities with the InjectionSolution component
+///
+
+[RegisterComponent, Access(typeof(InjectionAnomalySystem))]
+public sealed partial class InjectionAnomalyComponent : Component
+{
+ ///
+ /// the maximum amount of injection of a substance into an entity per pulsation
+ /// scales with Severity
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float MaxSolutionInjection = 15;
+ ///
+ /// the maximum amount of injection of a substance into an entity in the supercritical phase
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float SuperCriticalSolutionInjection = 50;
+
+ ///
+ /// The maximum radius in which the anomaly injects reagents into the surrounding containers.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float InjectRadius = 3;
+ ///
+ /// The maximum radius in which the anomaly injects reagents into the surrounding containers.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float SuperCriticalInjectRadius = 15;
+
+ ///
+ /// The name of the prototype of the special effect that appears above the entities into which the injection was carried out
+ ///
+ [DataField, ViewVariables(VVAccess.ReadOnly)]
+ public EntProtoId VisualEffectPrototype = "PuddleSparkle";
+ ///
+ /// Solution name that can be drained.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public string Solution { get; set; } = "default";
+}
diff --git a/Content.Server/Anomaly/Components/PuddleCreateAnomalyComponent.cs b/Content.Server/Anomaly/Components/PuddleCreateAnomalyComponent.cs
new file mode 100644
index 0000000000..78c50b3d7e
--- /dev/null
+++ b/Content.Server/Anomaly/Components/PuddleCreateAnomalyComponent.cs
@@ -0,0 +1,29 @@
+using Content.Server.Anomaly.Effects;
+
+namespace Content.Server.Anomaly.Components;
+
+///
+/// This component allows the anomaly to create puddles from the solutionContainer
+///
+[RegisterComponent, Access(typeof(PuddleCreateAnomalySystem))]
+public sealed partial class PuddleCreateAnomalyComponent : Component
+{
+ ///
+ /// The maximum amount of solution that an anomaly can splash out of the storage on the floor during pulsation.
+ /// Scales with Severity.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float MaxPuddleSize = 100;
+
+ ///
+ /// The maximum amount of solution that an anomaly can splash out of the storage on the floor during supercritical event
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float SuperCriticalPuddleSize = 1000;
+
+ ///
+ /// Solution name that can be drained.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public string Solution { get; set; } = "default";
+}
diff --git a/Content.Server/Anomaly/Components/ReagentProducerAnomalyComponent.cs b/Content.Server/Anomaly/Components/ReagentProducerAnomalyComponent.cs
new file mode 100644
index 0000000000..aa860c1713
--- /dev/null
+++ b/Content.Server/Anomaly/Components/ReagentProducerAnomalyComponent.cs
@@ -0,0 +1,94 @@
+using Content.Server.Anomaly.Effects;
+using Content.Shared.Chemistry.Reagent;
+using Robust.Shared.Audio;
+using Robust.Shared.Prototypes;
+using System.Numerics;
+
+namespace Content.Server.Anomaly.Components;
+///
+/// This component allows the anomaly to generate a random type of reagent in the specified SolutionContainer.
+/// With the increasing severity of the anomaly, the type of reagent produced may change.
+/// The higher the severity of the anomaly, the higher the chance of dangerous or useful reagents.
+///
+[RegisterComponent, Access(typeof(ReagentProducerAnomalySystem))]
+public sealed partial class ReagentProducerAnomalyComponent : Component
+{
+ //the addition of the reagent will occur instantly when an anomaly appears,
+ //and there will not be the first three seconds of a white empty anomaly.
+ public float AccumulatedFrametime = 3.0f;
+ ///
+ /// How frequently should this reagent generation update, in seconds?
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float UpdateInterval = 3.0f;
+
+ ///
+ /// The spread of the random weight of the choice of this category, depending on the severity.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public Vector2 WeightSpreadDangerous = new(5.0f, 9.0f);
+ ///
+ /// The spread of the random weight of the choice of this category, depending on the severity.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public Vector2 WeightSpreadFun = new(3.0f, 0.0f);
+ ///
+ /// The spread of the random weight of the choice of this category, depending on the severity.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public Vector2 WeightSpreadUseful = new(1.0f, 1.0f);
+
+ ///
+ /// Category of dangerous reagents for injection. Various toxins and poisons
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public List> DangerousChemicals = new();
+ ///
+ /// Category of useful reagents for injection. Medicine and other things that players WANT to get
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public List> UsefulChemicals = new();
+ ///
+ /// Category of fun reagents for injection. Glue, drugs, beer. Something that will bring fun.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public List> FunChemicals = new();
+
+ ///
+ /// Noise made when anomaly pulse.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public SoundSpecifier ChangeSound = new SoundPathSpecifier("/Audio/Effects/waterswirl.ogg");
+ ///
+ /// The component will repaint the sprites of the object to match the current color of the solution,
+ /// if the RandomSprite component is hung correctly.
+ /// Ideally, this should be put into a separate component, but I suffered for 4 hours,
+ /// and nothing worked out for me. So for now it will be like this.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadOnly)]
+ public bool NeedRecolor = false;
+
+ ///
+ /// the maximum amount of reagent produced per second
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float MaxReagentProducing = 1.5f;
+
+ ///
+ /// how much does the reagent production increase before entering the supercritical state
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float SupercriticalReagentProducingModifier = 100f;
+
+ ///
+ /// The name of the reagent that the anomaly produces.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public ProtoId ProducingReagent = "Water";
+ ///
+ /// Solution name where the substance is generated
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("solution")]
+ public string Solution = "default";
+}
diff --git a/Content.Server/Anomaly/Effects/InjectionAnomalySystem.cs b/Content.Server/Anomaly/Effects/InjectionAnomalySystem.cs
new file mode 100644
index 0000000000..acc0e2f0c3
--- /dev/null
+++ b/Content.Server/Anomaly/Effects/InjectionAnomalySystem.cs
@@ -0,0 +1,67 @@
+using System.Linq;
+using Content.Server.Anomaly.Components;
+using Content.Server.Chemistry.Components.SolutionManager;
+using Content.Server.Chemistry.EntitySystems;
+using Content.Shared.Anomaly.Components;
+
+namespace Content.Server.Anomaly.Effects;
+///
+/// This component allows the anomaly to inject liquid from the SolutionContainer
+/// into the surrounding entities with the InjectionSolution component
+///
+///
+
+///
+public sealed class InjectionAnomalySystem : EntitySystem
+{
+ [Dependency] private readonly EntityLookupSystem _lookup = default!;
+ [Dependency] private readonly SolutionContainerSystem _solutionContainer = default!;
+
+ private EntityQuery _injectableQuery;
+
+ public override void Initialize()
+ {
+ SubscribeLocalEvent(OnPulse);
+ SubscribeLocalEvent(OnSupercritical, before: new[] { typeof(SolutionContainerSystem) });
+
+ _injectableQuery = GetEntityQuery();
+ }
+
+ private void OnPulse(EntityUid uid, InjectionAnomalyComponent component, ref AnomalyPulseEvent args)
+ {
+ PulseScalableEffect(uid, component, component.InjectRadius, component.MaxSolutionInjection * args.Severity);
+ }
+
+ private void OnSupercritical(EntityUid uid, InjectionAnomalyComponent component, ref AnomalySupercriticalEvent args)
+ {
+ PulseScalableEffect(uid, component, component.SuperCriticalInjectRadius, component.SuperCriticalSolutionInjection);
+ }
+
+ private void PulseScalableEffect(EntityUid uid, InjectionAnomalyComponent component, float injectRadius, float maxInject)
+ {
+ if (!_solutionContainer.TryGetSolution(uid, component.Solution, out var sol))
+ return;
+ //We get all the entity in the radius into which the reagent will be injected.
+ var xformQuery = GetEntityQuery();
+ var xform = xformQuery.GetComponent(uid);
+ var allEnts = _lookup.GetComponentsInRange(xform.MapPosition, injectRadius)
+ .Select(x => x.Owner).ToList();
+
+ //for each matching entity found
+ foreach (var ent in allEnts)
+ {
+ if (!_solutionContainer.TryGetInjectableSolution(ent, out var injectable))
+ continue;
+
+ if (_injectableQuery.TryGetComponent(ent, out var injEnt))
+ {
+ var buffer = sol;
+ _solutionContainer.TryTransferSolution(ent, injectable, buffer, maxInject);
+ //Spawn Effect
+ var uidXform = Transform(ent);
+ Spawn(component.VisualEffectPrototype, uidXform.Coordinates);
+ }
+ }
+ }
+
+}
diff --git a/Content.Server/Anomaly/Effects/PuddleCreateAnomalySystem.cs b/Content.Server/Anomaly/Effects/PuddleCreateAnomalySystem.cs
new file mode 100644
index 0000000000..deae38e5c8
--- /dev/null
+++ b/Content.Server/Anomaly/Effects/PuddleCreateAnomalySystem.cs
@@ -0,0 +1,39 @@
+using Content.Server.Anomaly.Components;
+using Content.Server.Chemistry.EntitySystems;
+using Content.Shared.Anomaly.Components;
+using Content.Server.Fluids.EntitySystems;
+
+namespace Content.Server.Anomaly.Effects;
+
+///
+/// This component allows the anomaly to create puddles from SolutionContainer.
+///
+public sealed class PuddleCreateAnomalySystem : EntitySystem
+{
+ [Dependency] private readonly PuddleSystem _puddle = default!;
+ [Dependency] private readonly SolutionContainerSystem _solutionContainer = default!;
+
+ public override void Initialize()
+ {
+ SubscribeLocalEvent(OnPulse);
+ SubscribeLocalEvent(OnSupercritical, before: new[] { typeof(InjectionAnomalySystem) });
+ }
+
+ private void OnPulse(EntityUid uid, PuddleCreateAnomalyComponent component, ref AnomalyPulseEvent args)
+ {
+ if (!_solutionContainer.TryGetSolution(uid, component.Solution, out var sol))
+ return;
+
+ var xform = Transform(uid);
+ var puddleSol = _solutionContainer.SplitSolution(uid, sol, component.MaxPuddleSize * args.Severity);
+ _puddle.TrySplashSpillAt(uid, xform.Coordinates, puddleSol, out _);
+ }
+ private void OnSupercritical(EntityUid uid, PuddleCreateAnomalyComponent component, ref AnomalySupercriticalEvent args)
+ {
+ if (!_solutionContainer.TryGetSolution(uid, component.Solution, out var sol))
+ return;
+ var buffer = sol;
+ var xform = Transform(uid);
+ _puddle.TrySpillAt(xform.Coordinates, buffer, out _);
+ }
+}
diff --git a/Content.Server/Anomaly/Effects/ReagentProducerAnomalySystem.cs b/Content.Server/Anomaly/Effects/ReagentProducerAnomalySystem.cs
new file mode 100644
index 0000000000..fdfff42d7c
--- /dev/null
+++ b/Content.Server/Anomaly/Effects/ReagentProducerAnomalySystem.cs
@@ -0,0 +1,152 @@
+using Content.Server.Anomaly.Components;
+using Content.Server.Chemistry.EntitySystems;
+using Content.Shared.Anomaly.Components;
+using Robust.Shared.Random;
+using Content.Shared.Chemistry.Components;
+using Robust.Shared.Prototypes;
+using Content.Shared.Sprite;
+using Robust.Server.GameObjects;
+
+namespace Content.Server.Anomaly.Effects;
+
+///
+
+public sealed class ReagentProducerAnomalySystem : EntitySystem
+{
+ //The idea is to divide substances into several categories.
+ //The anomaly will choose one of the categories with a given chance based on severity.
+ //Then a random substance will be selected from the selected category.
+ //There are the following categories:
+
+ //Dangerous:
+ //selected most often. A list of substances that are extremely unpleasant for injection.
+
+ //Fun:
+ //Funny things have an increased chance of appearing in an anomaly.
+
+ //Useful:
+ //Those reagents that the players are hunting for. Very low percentage of loss.
+
+ [Dependency] private readonly SolutionContainerSystem _solutionContainer = default!;
+ [Dependency] private readonly IRobustRandom _random = default!;
+ [Dependency] private readonly PointLightSystem _light = default!;
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+ [Dependency] private readonly SharedAudioSystem _audio = default!;
+
+ public const string FallbackReagent = "Water";
+
+ public override void Initialize()
+ {
+ SubscribeLocalEvent(OnPulse);
+ SubscribeLocalEvent(OnMapInit);
+ }
+
+ private void OnPulse(EntityUid uid, ReagentProducerAnomalyComponent component, ref AnomalyPulseEvent args)
+ {
+ if (_random.NextFloat(0.0f, 1.0f) > args.Stability)
+ ChangeReagent(uid, component, args.Severity);
+ }
+
+ private void ChangeReagent(EntityUid uid, ReagentProducerAnomalyComponent component, float severity)
+ {
+ var reagent = GetRandomReagentType(uid, component, severity);
+ component.ProducingReagent = reagent;
+ _audio.PlayPvs(component.ChangeSound, uid);
+ }
+
+ //reagent realtime generation
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var uid, out var component, out var anomaly))
+ {
+ component.AccumulatedFrametime += frameTime;
+
+ if (component.AccumulatedFrametime < component.UpdateInterval)
+ continue;
+
+ if (!_solutionContainer.TryGetSolution(uid, component.Solution, out var producerSol))
+ continue;
+
+ Solution newSol = new();
+ var reagentProducingAmount = anomaly.Stability * component.MaxReagentProducing * component.AccumulatedFrametime;
+ if (anomaly.Severity >= 0.97) reagentProducingAmount *= component.SupercriticalReagentProducingModifier;
+
+ newSol.AddReagent(component.ProducingReagent, reagentProducingAmount);
+ _solutionContainer.TryAddSolution(uid, producerSol, newSol); //TO DO - the container is not fully filled.
+
+ component.AccumulatedFrametime = 0;
+
+ // The component will repaint the sprites of the object to match the current color of the solution,
+ // if the RandomSprite component is hung correctly.
+
+ // Ideally, this should be put into a separate component, but I suffered for 4 hours,
+ // and nothing worked out for me. So for now it will be like this.
+ if (component.NeedRecolor)
+ {
+ var color = producerSol.GetColor(_prototypeManager);
+ _light.SetColor(uid, color);
+ if (TryComp(uid, out var randomSprite))
+ {
+ foreach (var ent in randomSprite.Selected)
+ {
+ var state = randomSprite.Selected[ent.Key];
+ state.Color = color;
+ randomSprite.Selected[ent.Key] = state;
+ }
+ Dirty(uid, randomSprite);
+ }
+ }
+ }
+ }
+
+ private void OnMapInit(EntityUid uid, ReagentProducerAnomalyComponent component, MapInitEvent args)
+ {
+ ChangeReagent(uid, component, 0.1f); //MapInit Reagent 100% change
+ }
+
+ // returns a random reagent based on a system of random weights.
+ // First, the category is selected: The category has a minimum and maximum weight,
+ // the current value depends on severity.
+ // Accordingly, with the strengthening of the anomaly,
+ // the chances of falling out of some categories grow, and some fall.
+ //
+ // After that, a random reagent in the selected category is selected.
+ //
+ // Such a system is made to control the danger and interest of the anomaly more.
+ private string GetRandomReagentType(EntityUid uid, ReagentProducerAnomalyComponent component, float severity)
+ {
+ //Category Weight Randomization
+ var currentWeightDangerous = MathHelper.Lerp(component.WeightSpreadDangerous.X, component.WeightSpreadDangerous.Y, severity);
+ var currentWeightFun = MathHelper.Lerp(component.WeightSpreadFun.X, component.WeightSpreadFun.Y, severity);
+ var currentWeightUseful = MathHelper.Lerp(component.WeightSpreadUseful.X, component.WeightSpreadUseful.Y, severity);
+
+ var sumWeight = currentWeightDangerous + currentWeightFun + currentWeightUseful;
+ var rnd = _random.NextFloat(0f, sumWeight);
+ //Dangerous
+ if (rnd <= currentWeightDangerous && component.DangerousChemicals.Count > 0)
+ {
+ var reagent = _random.Pick(component.DangerousChemicals);
+ return reagent;
+ }
+ else rnd -= currentWeightDangerous;
+ //Fun
+ if (rnd <= currentWeightFun && component.FunChemicals.Count > 0)
+ {
+ var reagent = _random.Pick(component.FunChemicals);
+ return reagent;
+ }
+ else rnd -= currentWeightFun;
+ //Useful
+ if (rnd <= currentWeightUseful && component.UsefulChemicals.Count > 0)
+ {
+ var reagent = _random.Pick(component.UsefulChemicals);
+ return reagent;
+ }
+ //We should never end up here.
+ //Maybe Log Error?
+ return FallbackReagent;
+ }
+}
diff --git a/Resources/Audio/Effects/attributions.yml b/Resources/Audio/Effects/attributions.yml
index f9239f4dab..71a2ae2b53 100644
--- a/Resources/Audio/Effects/attributions.yml
+++ b/Resources/Audio/Effects/attributions.yml
@@ -56,4 +56,9 @@
- files: ["break_stone.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Taken from tgstation"
- source: "https://github.com/tgstation/tgstation/blob/e3a835b96043fad1269ee7b0c3a6cb340a466f3a/sound/effects/break_stone.ogg"
\ No newline at end of file
+ source: "https://github.com/tgstation/tgstation/blob/e3a835b96043fad1269ee7b0c3a6cb340a466f3a/sound/effects/break_stone.ogg"
+
+- files: ["waterswirl.ogg"]
+ license: "CC0-1.0"
+ copyright: "Taken from InspectorJ via freesound.org and mixed from stereo to mono."
+ source: "https://freesound.org/people/InspectorJ/sounds/398703/"
diff --git a/Resources/Audio/Effects/waterswirl.ogg b/Resources/Audio/Effects/waterswirl.ogg
new file mode 100644
index 0000000000..d8c9755a69
Binary files /dev/null and b/Resources/Audio/Effects/waterswirl.ogg differ
diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml
index e1f1e56480..043bf707b4 100644
--- a/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml
+++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml
@@ -17,4 +17,5 @@
- AnomalyBluespace
- AnomalyIce
- AnomalyRock
+ - AnomalyLiquid
chance: 1
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml b/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml
index a49d095535..beed7db43c 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml
@@ -206,3 +206,232 @@
radius: 2
energy: 3
color: "#06DF24"
+
+- type: entity
+ name: Reagent slime
+ id: ReagentSlime
+ suffix: Water
+ parent: MobAdultSlimes
+ description: It consists of a liquid, and it wants to dissolve you in itself.
+ components:
+ - type: NpcFactionMember
+ factions:
+ - SimpleHostile
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/elemental.rsi
+ layers:
+ - map: [ "enum.DamageStateVisualLayers.Base" ]
+ state: alive
+ color: "#75b1f0"
+ - type: PointLight
+ radius: 2.0
+ energy: 3.5
+ color: "#75b1f0" # Edited through the LiquidAnomalySystem
+ - type: MobState
+ allowedStates:
+ - Alive
+ - Dead
+ - type: MobThresholds
+ thresholds:
+ 0: Alive
+ 150: Dead
+ - type: SlowOnDamage
+ speedModifierThresholds:
+ 50: 0.4
+ - type: Bloodstream
+ bloodReagent: Water
+ chemicalMaxVolume: 100
+ - type: StatusEffects
+ allowed:
+ - SlowedDown
+ - Electrocution
+ - type: MeleeWeapon
+ soundHit:
+ collection: AlienClaw
+ animation: WeaponArcBite
+ damage:
+ types:
+ Slash: 15
+ - type: MeleeChemicalInjector
+ solution: bloodstream
+ transferAmount: 5
+ - type: DamageStateVisuals
+ rotate: true
+ states:
+ Alive:
+ Base: alive
+ Dead:
+ Base: dead
+ - type: Tag
+ tags:
+ - FootstepSound
+ - CannotSuicide
+ - DoorBumpOpener
+ - type: NoSlip
+ - type: ZombieImmune
+ - type: ExaminableSolution
+ solution: bloodstream
+ - type: InjectableSolution
+ solution: bloodstream
+ - type: DrainableSolution
+ solution: bloodstream
+
+- type: entity
+ name: Reagent Slime Spawner
+ id: ReagentSlimeSpawner
+ parent: MarkerBase
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Mobs/Aliens/elemental.rsi
+ state: alive
+ - type: RandomSpawner
+ prototypes:
+ - ReagentSlime
+ - ReagentSlimeBeer
+ - ReagentSlimePax
+ - ReagentSlimeNocturine
+ - ReagentSlimeTHC
+ - ReagentSlimeBicaridine
+ - ReagentSlimeToxin
+ - ReagentSlimeNapalm
+ - ReagentSlimeOmnizine
+ chance: 1
+
+- type: entity
+ id: ReagentSlimeBeer
+ parent: ReagentSlime
+ suffix: Beer
+ components:
+ - type: Bloodstream
+ bloodReagent: Beer
+ - type: PointLight
+ color: "#cfa85f"
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/elemental.rsi
+ layers:
+ - map: [ "enum.DamageStateVisualLayers.Base" ]
+ state: alive
+ color: "#cfa85f"
+
+- type: entity
+ id: ReagentSlimePax
+ parent: ReagentSlime
+ suffix: Pax
+ components:
+ - type: Bloodstream
+ bloodReagent: Pax
+ - type: PointLight
+ color: "#AAAAAA"
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/elemental.rsi
+ layers:
+ - map: [ "enum.DamageStateVisualLayers.Base" ]
+ state: alive
+ color: "#AAAAAA"
+
+- type: entity
+ id: ReagentSlimeNocturine
+ parent: ReagentSlime
+ suffix: Nocturine
+ components:
+ - type: Bloodstream
+ bloodReagent: Nocturine
+ - type: PointLight
+ color: "#128e80"
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/elemental.rsi
+ layers:
+ - map: [ "enum.DamageStateVisualLayers.Base" ]
+ state: alive
+ color: "#128e80"
+
+- type: entity
+ id: ReagentSlimeTHC
+ parent: ReagentSlime
+ suffix: THC
+ components:
+ - type: Bloodstream
+ bloodReagent: THC
+ - type: PointLight
+ color: "#808080"
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/elemental.rsi
+ layers:
+ - map: [ "enum.DamageStateVisualLayers.Base" ]
+ state: alive
+ color: "#808080"
+
+- type: entity
+ id: ReagentSlimeBicaridine
+ parent: ReagentSlime
+ suffix: Bicaridine
+ components:
+ - type: Bloodstream
+ bloodReagent: Bicaridine
+ - type: PointLight
+ color: "#ffaa00"
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/elemental.rsi
+ layers:
+ - map: [ "enum.DamageStateVisualLayers.Base" ]
+ state: alive
+ color: "#ffaa00"
+
+- type: entity
+ id: ReagentSlimeToxin
+ parent: ReagentSlime
+ suffix: Toxin
+ components:
+ - type: Bloodstream
+ bloodReagent: Toxin
+ - type: PointLight
+ color: "#cf3600"
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/elemental.rsi
+ layers:
+ - map: [ "enum.DamageStateVisualLayers.Base" ]
+ state: alive
+ color: "#cf3600"
+
+- type: entity
+ id: ReagentSlimeNapalm
+ parent: ReagentSlime
+ suffix: Napalm
+ components:
+ - type: Bloodstream
+ bloodReagent: Napalm
+ - type: PointLight
+ color: "#FA00AF"
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/elemental.rsi
+ layers:
+ - map: [ "enum.DamageStateVisualLayers.Base" ]
+ state: alive
+ color: "#FA00AF"
+
+- type: entity
+ id: ReagentSlimeOmnizine
+ parent: ReagentSlime
+ suffix: Omnizine
+ components:
+ - type: Bloodstream
+ bloodReagent: Omnizine
+ - type: PointLight
+ color: "#fcf7f9"
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/elemental.rsi
+ layers:
+ - map: [ "enum.DamageStateVisualLayers.Base" ]
+ state: alive
+ color: "#fcf7f9"
\ No newline at end of file
diff --git a/Resources/Prototypes/Entities/Structures/Specific/anomalies.yml b/Resources/Prototypes/Entities/Structures/Specific/anomalies.yml
index 16d9365b9f..d227e57ff3 100644
--- a/Resources/Prototypes/Entities/Structures/Specific/anomalies.yml
+++ b/Resources/Prototypes/Entities/Structures/Specific/anomalies.yml
@@ -263,3 +263,109 @@
superCriticalSpawns:
- AsteroidRock
- SpawnMobOreCrab
+
+- type: entity
+ id: AnomalyLiquid
+ parent: BaseAnomaly
+ suffix: Liquid
+ components:
+ - type: Sprite
+ sprite: Structures/Specific/Anomalies/liquid_anom.rsi
+ layers:
+ - state: anom
+ map: ["enum.AnomalyVisualLayers.Base"]
+ - state: pulse
+ map: ["enum.AnomalyVisualLayers.Animated"]
+ visible: false
+ - type: RandomSprite
+ selected: # Initialized layer values. Edited through the ReagentProducerAnomalySystem
+ enum.AnomalyVisualLayers.Base:
+ anom: "#ffffff"
+ enum.AnomalyVisualLayers.Animated:
+ pulse: "#ffffff"
+ - type: PointLight
+ radius: 4.0
+ energy: 3.5
+ color: "#bbbbbb"
+ - type: BadFood
+ - type: Anomaly
+ anomalyContactDamage:
+ types:
+ Slash: 1
+ - type: EntitySpawnAnomaly
+ superCriticalSpawns:
+ - ReagentSlimeSpawner
+ spawns:
+ - PuddleSparkle
+ - type: SolutionContainerManager
+ solutions:
+ anomaly:
+ maxVol: 1500
+ - type: PuddleCreateAnomaly
+ solution: anomaly
+ - type: InjectionAnomaly
+ solution: anomaly
+ - type: ReagentProducerAnomaly
+ solution: anomaly
+ needRecolor: true
+ dangerousChemicals:
+ - UnstableMutagen
+ - Mold
+ - PolytrinicAcid
+ - FerrochromicAcid
+ - FluorosulfuricAcid
+ - SulfuricAcid
+ - HeartbreakerToxin
+ - VentCrud
+ - UncookedAnimalProteins
+ - Thermite
+ - Napalm
+ - Phlogiston
+ - ChlorineTrifluoride
+ - FoamingAgent
+ - BuzzochloricBees
+ - RobustHarvest
+ usefulChemicals:
+ - Cryptobiolin
+ - Dylovene
+ - Arithrazine
+ - Bicaridine
+ - Cryoxadone
+ - Dermaline
+ - Dexalin
+ - DexalinPlus
+ - Epinephrine
+ - Leporazine
+ - Ambuzol
+ - Tricordrazine
+ - Artifexium
+ - Ethylredoxrazine
+ funChemicals:
+ - Desoxyephedrine
+ - Ephedrine
+ - THC
+ - THCOil
+ - SpaceDrugs
+ - Nocturine
+ - MuteToxin
+ - NorepinephricAcid
+ - Pax
+ - Ipecac
+ - Cognizine
+ - Beer
+ - SpaceGlue
+ - CogChamp
+ - Honk
+ - Carpetium
+ - type: Drink
+ solution: anomaly
+ - type: DrainableSolution
+ solution: anomaly
+ - type: DrawableSolution
+ solution: anomaly
+ - type: ExaminableSolution
+ solution: anomaly
+ - type: RefillableSolution
+ solution: anomaly
+ - type: InjectableSolution
+ solution: beaker
diff --git a/Resources/Textures/Mobs/Aliens/elemental.rsi/alive.png b/Resources/Textures/Mobs/Aliens/elemental.rsi/alive.png
new file mode 100644
index 0000000000..c0fbc020b3
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/elemental.rsi/alive.png differ
diff --git a/Resources/Textures/Mobs/Aliens/elemental.rsi/dead.png b/Resources/Textures/Mobs/Aliens/elemental.rsi/dead.png
new file mode 100644
index 0000000000..1363188c39
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/elemental.rsi/dead.png differ
diff --git a/Resources/Textures/Mobs/Aliens/elemental.rsi/meta.json b/Resources/Textures/Mobs/Aliens/elemental.rsi/meta.json
new file mode 100644
index 0000000000..3d3d7f75a8
--- /dev/null
+++ b/Resources/Textures/Mobs/Aliens/elemental.rsi/meta.json
@@ -0,0 +1,44 @@
+{
+ "version": 1,
+ "license": "CC0-1.0",
+ "copyright": "Created by TheShuEd (github) for Space Station 14.",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "dead"
+ },
+ {
+ "name": "alive",
+ "directions": 4,
+ "delays": [
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ],
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ],
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ],
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ]
+ ]
+ }
+ ]
+}
diff --git a/Resources/Textures/Structures/Specific/Anomalies/liquid_anom.rsi/anom.png b/Resources/Textures/Structures/Specific/Anomalies/liquid_anom.rsi/anom.png
new file mode 100644
index 0000000000..f421984c36
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/liquid_anom.rsi/anom.png differ
diff --git a/Resources/Textures/Structures/Specific/Anomalies/liquid_anom.rsi/meta.json b/Resources/Textures/Structures/Specific/Anomalies/liquid_anom.rsi/meta.json
new file mode 100644
index 0000000000..320816f3c5
--- /dev/null
+++ b/Resources/Textures/Structures/Specific/Anomalies/liquid_anom.rsi/meta.json
@@ -0,0 +1,33 @@
+{
+ "version": 1,
+ "license": "CC0-1.0",
+ "copyright": "Created by TheShuEd (github) for ss14",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "anom",
+ "delays": [
+ [
+ 0.18625,
+ 0.18625,
+ 0.18625,
+ 0.18625
+ ]
+ ]
+ },
+ {
+ "name": "pulse",
+ "delays": [
+ [
+ 0.15625,
+ 0.15625,
+ 0.15625,
+ 0.15625
+ ]
+ ]
+ }
+ ]
+}
diff --git a/Resources/Textures/Structures/Specific/Anomalies/liquid_anom.rsi/pulse.png b/Resources/Textures/Structures/Specific/Anomalies/liquid_anom.rsi/pulse.png
new file mode 100644
index 0000000000..3447184fb6
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/liquid_anom.rsi/pulse.png differ