diff --git a/Content.Server/Chemistry/Components/RehydratableComponent.cs b/Content.Server/Chemistry/Components/RehydratableComponent.cs
index 413ecc358c..68ffa2aa17 100644
--- a/Content.Server/Chemistry/Components/RehydratableComponent.cs
+++ b/Content.Server/Chemistry/Components/RehydratableComponent.cs
@@ -1,18 +1,39 @@
-namespace Content.Server.Chemistry.Components
+using Content.Server.Chemistry.EntitySystems;
+using Content.Shared.Chemistry.Reagent;
+using Content.Shared.FixedPoint;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+
+namespace Content.Server.Chemistry.Components;
+
+///
+/// Basically, monkey cubes.
+/// But specifically, this component deletes the entity and spawns in a new entity when the entity is exposed to a certain amount of a given reagent.
+///
+[RegisterComponent, Access(typeof(RehydratableSystem))]
+public sealed class RehydratableComponent : Component
{
///
- /// Basically, monkey cubes.
- /// But specifically, this component deletes the entity and spawns in a new entity when the entity is exposed to a given reagent.
+ /// The reagent that must be present to count as hydrated.
///
- [RegisterComponent]
- public sealed class RehydratableComponent : Component
- {
- [DataField("catalyst")]
- internal string CatalystPrototype = "Water";
+ [DataField("catalyst", customTypeSerializer: typeof(PrototypeIdSerializer)), ViewVariables(VVAccess.ReadWrite)]
+ public string CatalystPrototype = "Water";
- [DataField("target")]
- internal string? TargetPrototype = default!;
+ ///
+ /// The minimum amount of catalyst that must be present to be hydrated.
+ ///
+ [DataField("catalystMinimum"), ViewVariables(VVAccess.ReadWrite)]
+ public FixedPoint2 CatalystMinimum = FixedPoint2.Zero;
- internal bool Expanding;
- }
+ ///
+ /// The entity to create when hydrated.
+ ///
+ [DataField("target", customTypeSerializer: typeof(PrototypeIdSerializer)), ViewVariables(VVAccess.ReadWrite)]
+ public string? TargetPrototype = default!;
}
+
+///
+/// Raised on the rehydrated entity with target being the new entity it became.
+///
+[ByRefEvent]
+public readonly record struct GotRehydratedEvent(EntityUid Target);
diff --git a/Content.Server/Chemistry/EntitySystems/RehydratableSystem.cs b/Content.Server/Chemistry/EntitySystems/RehydratableSystem.cs
index 409d0188af..c4531bfa5f 100644
--- a/Content.Server/Chemistry/EntitySystems/RehydratableSystem.cs
+++ b/Content.Server/Chemistry/EntitySystems/RehydratableSystem.cs
@@ -1,47 +1,42 @@
-using Content.Server.Chemistry.Components;
-using Content.Server.Popups;
+using Content.Server.Chemistry.Components;
using Content.Shared.FixedPoint;
-using JetBrains.Annotations;
+using Content.Shared.Popups;
-namespace Content.Server.Chemistry.EntitySystems
+namespace Content.Server.Chemistry.EntitySystems;
+
+public sealed class RehydratableSystem : EntitySystem
{
- [UsedImplicitly]
- public sealed class RehydratableSystem : EntitySystem
+ [Dependency] private readonly SharedPopupSystem _popups = default!;
+ [Dependency] private readonly SolutionContainerSystem _solutions = default!;
+
+ public override void Initialize()
{
- [Dependency] private readonly SolutionContainerSystem _solutionsSystem = default!;
- public override void Initialize()
+ base.Initialize();
+
+ SubscribeLocalEvent(OnSolutionChange);
+ }
+
+ private void OnSolutionChange(EntityUid uid, RehydratableComponent comp, SolutionChangedEvent args)
+ {
+ var quantity = _solutions.GetReagentQuantity(uid, comp.CatalystPrototype);
+ if (quantity != FixedPoint2.Zero && quantity >= comp.CatalystMinimum)
{
- base.Initialize();
-
- SubscribeLocalEvent(OnSolutionChange);
- }
-
- private void OnSolutionChange(EntityUid uid, RehydratableComponent component, SolutionChangedEvent args)
- {
- if (_solutionsSystem.GetReagentQuantity(uid, component.CatalystPrototype) > FixedPoint2.Zero)
- {
- Expand(component, component.Owner);
- }
- }
-
- // Try not to make this public if you can help it.
- private void Expand(RehydratableComponent component, EntityUid owner)
- {
- if (component.Expanding)
- {
- return;
- }
-
- component.Expanding = true;
- owner.PopupMessageEveryone(Loc.GetString("rehydratable-component-expands-message", ("owner", owner)));
- if (!string.IsNullOrEmpty(component.TargetPrototype))
- {
- var ent = EntityManager.SpawnEntity(component.TargetPrototype,
- EntityManager.GetComponent(owner).Coordinates);
- EntityManager.GetComponent(ent).AttachToGridOrMap();
- }
-
- EntityManager.QueueDeleteEntity((EntityUid) owner);
+ Expand(uid, comp);
}
}
+
+ // Try not to make this public if you can help it.
+ private void Expand(EntityUid uid, RehydratableComponent comp)
+ {
+ _popups.PopupEntity(Loc.GetString("rehydratable-component-expands-message", ("owner", uid)), uid);
+
+ var target = Spawn(comp.TargetPrototype, Transform(uid).Coordinates);
+ Transform(target).AttachToGridOrMap();
+ var ev = new GotRehydratedEvent(target);
+ RaiseLocalEvent(uid, ref ev);
+
+ // prevent double hydration while queued
+ RemComp(uid);
+ QueueDel(uid);
+ }
}