-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;
+
+/// <summary>
+/// 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.
+/// </summary>
+[RegisterComponent, Access(typeof(RehydratableSystem))]
+public sealed class RehydratableComponent : Component
{
/// <summary>
- /// 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.
/// </summary>
- [RegisterComponent]
- public sealed class RehydratableComponent : Component
- {
- [DataField("catalyst")]
- internal string CatalystPrototype = "Water";
+ [DataField("catalyst", customTypeSerializer: typeof(PrototypeIdSerializer<ReagentPrototype>)), ViewVariables(VVAccess.ReadWrite)]
+ public string CatalystPrototype = "Water";
- [DataField("target")]
- internal string? TargetPrototype = default!;
+ /// <summary>
+ /// The minimum amount of catalyst that must be present to be hydrated.
+ /// </summary>
+ [DataField("catalystMinimum"), ViewVariables(VVAccess.ReadWrite)]
+ public FixedPoint2 CatalystMinimum = FixedPoint2.Zero;
- internal bool Expanding;
- }
+ /// <summary>
+ /// The entity to create when hydrated.
+ /// </summary>
+ [DataField("target", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>)), ViewVariables(VVAccess.ReadWrite)]
+ public string? TargetPrototype = default!;
}
+
+/// <summary>
+/// Raised on the rehydrated entity with target being the new entity it became.
+/// </summary>
+[ByRefEvent]
+public readonly record struct GotRehydratedEvent(EntityUid Target);
-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();
+ base.Initialize();
- SubscribeLocalEvent<RehydratableComponent, SolutionChangedEvent>(OnSolutionChange);
- }
+ SubscribeLocalEvent<RehydratableComponent, SolutionChangedEvent>(OnSolutionChange);
+ }
- private void OnSolutionChange(EntityUid uid, RehydratableComponent component, SolutionChangedEvent args)
+ private void OnSolutionChange(EntityUid uid, RehydratableComponent comp, SolutionChangedEvent args)
+ {
+ var quantity = _solutions.GetReagentQuantity(uid, comp.CatalystPrototype);
+ if (quantity != FixedPoint2.Zero && quantity >= comp.CatalystMinimum)
{
- if (_solutionsSystem.GetReagentQuantity(uid, component.CatalystPrototype) > FixedPoint2.Zero)
- {
- Expand(component, component.Owner);
- }
+ Expand(uid, comp);
}
+ }
- // 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<TransformComponent>(owner).Coordinates);
- EntityManager.GetComponent<TransformComponent>(ent).AttachToGridOrMap();
- }
-
- EntityManager.QueueDeleteEntity((EntityUid) owner);
- }
+ // 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<RehydratableComponent>(uid);
+ QueueDel(uid);
}
}