diff --git a/Content.Server/Singularity/Components/RadiationCollectorComponent.cs b/Content.Server/Singularity/Components/RadiationCollectorComponent.cs
index e958c7dab7..649514ed42 100644
--- a/Content.Server/Singularity/Components/RadiationCollectorComponent.cs
+++ b/Content.Server/Singularity/Components/RadiationCollectorComponent.cs
@@ -1,90 +1,87 @@
using Content.Server.Singularity.EntitySystems;
using Content.Shared.Atmos;
-using Content.Shared.Atmos.Prototypes;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-namespace Content.Server.Singularity.Components
+namespace Content.Server.Singularity.Components;
+
+///
+/// Generates electricity from radiation.
+///
+[RegisterComponent]
+[Access(typeof(RadiationCollectorSystem))]
+public sealed partial class RadiationCollectorComponent : Component
{
///
- /// Generates electricity from radiation.
+ /// How much joules will collector generate for each rad.
///
- [RegisterComponent]
- [Access(typeof(RadiationCollectorSystem))]
- public sealed partial class RadiationCollectorComponent : Component
- {
- ///
- /// How much joules will collector generate for each rad.
- ///
- [DataField("chargeModifier")]
- [ViewVariables(VVAccess.ReadWrite)]
- public float ChargeModifier = 30000f;
-
- ///
- /// Cooldown time between users interaction.
- ///
- [DataField("cooldown")]
- [ViewVariables(VVAccess.ReadWrite)]
- public TimeSpan Cooldown = TimeSpan.FromSeconds(0.81f);
-
- ///
- /// Was machine activated by user?
- ///
- [ViewVariables(VVAccess.ReadOnly)]
- public bool Enabled;
-
- ///
- /// Timestamp when machine can be deactivated again.
- ///
- public TimeSpan CoolDownEnd;
-
- ///
- /// List of gases that will react to the radiation passing through the collector
- ///
- [DataField("radiationReactiveGases")]
- [ViewVariables(VVAccess.ReadWrite)]
- public List? RadiationReactiveGases;
- }
+ [DataField("chargeModifier")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public float ChargeModifier = 30000f;
///
- /// Describes how a gas reacts to the collected radiation
+ /// Cooldown time between users interaction.
///
- [DataDefinition]
- public sealed partial class RadiationReactiveGas
- {
- ///
- /// The reactant gas
- ///
- [DataField("reactantPrototype", required: true)]
- public Gas Reactant = Gas.Plasma;
+ [DataField("cooldown")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public TimeSpan Cooldown = TimeSpan.FromSeconds(0.81f);
- ///
- /// Multipier for the amount of power produced by the radiation collector when using this gas
- ///
- [DataField("powerGenerationEfficiency")]
- public float PowerGenerationEfficiency = 1f;
+ ///
+ /// Was machine activated by user?
+ ///
+ [ViewVariables(VVAccess.ReadOnly)]
+ public bool Enabled;
- ///
- /// Controls the rate (molar percentage per rad) at which the reactant breaks down when exposed to radiation
- ///
- /// ///
- /// Set to zero if the reactant does not deplete
- ///
- [DataField("reactantBreakdownRate")]
- public float ReactantBreakdownRate = 1f;
+ ///
+ /// Timestamp when machine can be deactivated again.
+ ///
+ public TimeSpan CoolDownEnd;
- ///
- /// A byproduct gas that is generated when the reactant breaks down
- ///
- ///
- /// Leave null if the reactant no byproduct gas is to be formed
- ///
- [DataField("byproductPrototype")]
- public Gas? Byproduct = null;
-
- ///
- /// The molar ratio of the byproduct gas generated from the reactant gas
- ///
- [DataField("molarRatio")]
- public float MolarRatio = 1f;
- }
+ ///
+ /// List of gases that will react to the radiation passing through the collector
+ ///
+ [DataField("radiationReactiveGases")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public List? RadiationReactiveGases;
+}
+
+///
+/// Describes how a gas reacts to the collected radiation
+///
+[DataDefinition]
+public sealed partial class RadiationReactiveGas
+{
+ ///
+ /// The reactant gas
+ ///
+ [DataField("reactantPrototype", required: true)]
+ public Gas Reactant = Gas.Plasma;
+
+ ///
+ /// Multipier for the amount of power produced by the radiation collector when using this gas
+ ///
+ [DataField("powerGenerationEfficiency")]
+ public float PowerGenerationEfficiency = 1f;
+
+ ///
+ /// Controls the rate (molar percentage per rad) at which the reactant breaks down when exposed to radiation
+ ///
+ /// ///
+ /// Set to zero if the reactant does not deplete
+ ///
+ [DataField("reactantBreakdownRate")]
+ public float ReactantBreakdownRate = 1f;
+
+ ///
+ /// A byproduct gas that is generated when the reactant breaks down
+ ///
+ ///
+ /// Leave null if the reactant no byproduct gas is to be formed
+ ///
+ [DataField("byproductPrototype")]
+ public Gas? Byproduct = null;
+
+ ///
+ /// The molar ratio of the byproduct gas generated from the reactant gas
+ ///
+ [DataField("molarRatio")]
+ public float MolarRatio = 1f;
}
diff --git a/Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs b/Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs
index 8fa05386e2..19d9b98f4a 100644
--- a/Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs
+++ b/Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs
@@ -11,151 +11,150 @@ using Content.Shared.Examine;
using Content.Server.Atmos;
using System.Diagnostics.CodeAnalysis;
-namespace Content.Server.Singularity.EntitySystems
+namespace Content.Server.Singularity.EntitySystems;
+
+public sealed class RadiationCollectorSystem : EntitySystem
{
- public sealed class RadiationCollectorSystem : EntitySystem
+ [Dependency] private readonly IGameTiming _gameTiming = default!;
+ [Dependency] private readonly PopupSystem _popupSystem = default!;
+ [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
+ [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
+
+ public override void Initialize()
{
- [Dependency] private readonly IGameTiming _gameTiming = default!;
- [Dependency] private readonly PopupSystem _popupSystem = default!;
- [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
- [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
+ base.Initialize();
+ SubscribeLocalEvent(OnInteractHand);
+ SubscribeLocalEvent(OnRadiation);
+ SubscribeLocalEvent(OnExamined);
+ SubscribeLocalEvent(OnAnalyzed);
+ }
- public override void Initialize()
+ private bool TryGetLoadedGasTank(EntityUid uid, [NotNullWhen(true)] out GasTankComponent? gasTankComponent)
+ {
+ gasTankComponent = null;
+ var container = _containerSystem.EnsureContainer(uid, "GasTank");
+
+ if (container.ContainedEntity == null)
+ return false;
+
+ if (!EntityManager.TryGetComponent(container.ContainedEntity, out gasTankComponent))
+ return false;
+
+ return true;
+ }
+
+ private void OnInteractHand(EntityUid uid, RadiationCollectorComponent component, InteractHandEvent args)
+ {
+ var curTime = _gameTiming.CurTime;
+
+ if (curTime < component.CoolDownEnd)
+ return;
+
+ ToggleCollector(uid, args.User, component);
+ component.CoolDownEnd = curTime + component.Cooldown;
+ }
+
+ private void OnRadiation(EntityUid uid, RadiationCollectorComponent component, OnIrradiatedEvent args)
+ {
+ if (!component.Enabled || component.RadiationReactiveGases == null)
+ return;
+
+ if (!TryGetLoadedGasTank(uid, out var gasTankComponent))
+ return;
+
+ var charge = 0f;
+
+ foreach (var gas in component.RadiationReactiveGases)
{
- base.Initialize();
- SubscribeLocalEvent(OnInteractHand);
- SubscribeLocalEvent(OnRadiation);
- SubscribeLocalEvent(OnExamined);
- SubscribeLocalEvent(OnAnalyzed);
- }
+ float reactantMol = gasTankComponent.Air.GetMoles(gas.Reactant);
+ float delta = args.TotalRads * reactantMol * gas.ReactantBreakdownRate;
- private bool TryGetLoadedGasTank(EntityUid uid, [NotNullWhen(true)] out GasTankComponent? gasTankComponent)
- {
- gasTankComponent = null;
- var container = _containerSystem.EnsureContainer(uid, "GasTank");
+ // We need to offset the huge power gains possible when using very cold gases
+ // (they allow you to have a much higher molar concentrations of gas in the tank).
+ // Hence power output is modified using the Michaelis-Menten equation,
+ // it will heavily penalise the power output of low temperature reactions:
+ // 300K = 100% power output, 73K = 49% power output, 1K = 1% power output
+ float temperatureMod = 1.5f * gasTankComponent.Air.Temperature / (150f + gasTankComponent.Air.Temperature);
+ charge += args.TotalRads * reactantMol * component.ChargeModifier * gas.PowerGenerationEfficiency * temperatureMod;
- if (container.ContainedEntity == null)
- return false;
-
- if (!EntityManager.TryGetComponent(container.ContainedEntity, out gasTankComponent))
- return false;
-
- return true;
- }
-
- private void OnInteractHand(EntityUid uid, RadiationCollectorComponent component, InteractHandEvent args)
- {
- var curTime = _gameTiming.CurTime;
-
- if (curTime < component.CoolDownEnd)
- return;
-
- ToggleCollector(uid, args.User, component);
- component.CoolDownEnd = curTime + component.Cooldown;
- }
-
- private void OnRadiation(EntityUid uid, RadiationCollectorComponent component, OnIrradiatedEvent args)
- {
- if (!component.Enabled || component.RadiationReactiveGases == null)
- return;
-
- if (!TryGetLoadedGasTank(uid, out var gasTankComponent))
- return;
-
- var charge = 0f;
-
- foreach (var gas in component.RadiationReactiveGases)
+ if (delta > 0)
{
- float reactantMol = gasTankComponent.Air.GetMoles(gas.Reactant);
- float delta = args.TotalRads * reactantMol * gas.ReactantBreakdownRate;
-
- // We need to offset the huge power gains possible when using very cold gases
- // (they allow you to have a much higher molar concentrations of gas in the tank).
- // Hence power output is modified using the Michaelis-Menten equation,
- // it will heavily penalise the power output of low temperature reactions:
- // 300K = 100% power output, 73K = 49% power output, 1K = 1% power output
- float temperatureMod = 1.5f * gasTankComponent.Air.Temperature / (150f + gasTankComponent.Air.Temperature);
- charge += args.TotalRads * reactantMol * component.ChargeModifier * gas.PowerGenerationEfficiency * temperatureMod;
-
- if (delta > 0)
- {
- gasTankComponent.Air.AdjustMoles(gas.Reactant, -Math.Min(delta, reactantMol));
- }
-
- if (gas.Byproduct != null)
- {
- gasTankComponent.Air.AdjustMoles((int) gas.Byproduct, delta * gas.MolarRatio);
- }
+ gasTankComponent.Air.AdjustMoles(gas.Reactant, -Math.Min(delta, reactantMol));
}
- // No idea if this is even vaguely accurate to the previous logic.
- // The maths is copied from that logic even though it works differently.
- // But the previous logic would also make the radiation collectors never ever stop providing energy.
- // And since frameTime was used there, I'm assuming that this is what the intent was.
- // This still won't stop things being potentially hilariously unbalanced though.
- if (TryComp(uid, out var batteryComponent))
+ if (gas.Byproduct != null)
{
- batteryComponent.CurrentCharge += charge;
+ gasTankComponent.Air.AdjustMoles((int) gas.Byproduct, delta * gas.MolarRatio);
}
}
- private void OnExamined(EntityUid uid, RadiationCollectorComponent component, ExaminedEvent args)
+ // No idea if this is even vaguely accurate to the previous logic.
+ // The maths is copied from that logic even though it works differently.
+ // But the previous logic would also make the radiation collectors never ever stop providing energy.
+ // And since frameTime was used there, I'm assuming that this is what the intent was.
+ // This still won't stop things being potentially hilariously unbalanced though.
+ if (TryComp(uid, out var batteryComponent))
{
- if (!TryGetLoadedGasTank(uid, out var gasTankComponent))
- {
- args.PushMarkup(Loc.GetString("power-radiation-collector-gas-tank-missing"));
- return;
- }
-
- args.PushMarkup(Loc.GetString("power-radiation-collector-gas-tank-present"));
-
- if (gasTankComponent.IsLowPressure)
- {
- args.PushMarkup(Loc.GetString("power-radiation-collector-gas-tank-low-pressure"));
- }
- }
-
- private void OnAnalyzed(EntityUid uid, RadiationCollectorComponent component, GasAnalyzerScanEvent args)
- {
- if (!TryGetLoadedGasTank(uid, out var gasTankComponent))
- return;
-
- args.GasMixtures = new Dictionary { { Name(uid), gasTankComponent.Air } };
- }
-
- public void ToggleCollector(EntityUid uid, EntityUid? user = null, RadiationCollectorComponent? component = null)
- {
- if (!Resolve(uid, ref component))
- return;
-
- SetCollectorEnabled(uid, !component.Enabled, user, component);
- }
-
- public void SetCollectorEnabled(EntityUid uid, bool enabled, EntityUid? user = null, RadiationCollectorComponent? component = null)
- {
- if (!Resolve(uid, ref component))
- return;
-
- component.Enabled = enabled;
-
- // Show message to the player
- if (user != null)
- {
- var msg = component.Enabled ? "radiation-collector-component-use-on" : "radiation-collector-component-use-off";
- _popupSystem.PopupEntity(Loc.GetString(msg), uid);
- }
-
- // Update appearance
- UpdateAppearance(uid, component);
- }
-
- private void UpdateAppearance(EntityUid uid, RadiationCollectorComponent? component, AppearanceComponent? appearance = null)
- {
- if (!Resolve(uid, ref component, ref appearance))
- return;
-
- var state = component.Enabled ? RadiationCollectorVisualState.Active : RadiationCollectorVisualState.Deactive;
- _appearance.SetData(uid, RadiationCollectorVisuals.VisualState, state, appearance);
+ batteryComponent.CurrentCharge += charge;
}
}
+
+ private void OnExamined(EntityUid uid, RadiationCollectorComponent component, ExaminedEvent args)
+ {
+ if (!TryGetLoadedGasTank(uid, out var gasTankComponent))
+ {
+ args.PushMarkup(Loc.GetString("power-radiation-collector-gas-tank-missing"));
+ return;
+ }
+
+ args.PushMarkup(Loc.GetString("power-radiation-collector-gas-tank-present"));
+
+ if (gasTankComponent.IsLowPressure)
+ {
+ args.PushMarkup(Loc.GetString("power-radiation-collector-gas-tank-low-pressure"));
+ }
+ }
+
+ private void OnAnalyzed(EntityUid uid, RadiationCollectorComponent component, GasAnalyzerScanEvent args)
+ {
+ if (!TryGetLoadedGasTank(uid, out var gasTankComponent))
+ return;
+
+ args.GasMixtures = new Dictionary { { Name(uid), gasTankComponent.Air } };
+ }
+
+ public void ToggleCollector(EntityUid uid, EntityUid? user = null, RadiationCollectorComponent? component = null)
+ {
+ if (!Resolve(uid, ref component))
+ return;
+
+ SetCollectorEnabled(uid, !component.Enabled, user, component);
+ }
+
+ public void SetCollectorEnabled(EntityUid uid, bool enabled, EntityUid? user = null, RadiationCollectorComponent? component = null)
+ {
+ if (!Resolve(uid, ref component))
+ return;
+
+ component.Enabled = enabled;
+
+ // Show message to the player
+ if (user != null)
+ {
+ var msg = component.Enabled ? "radiation-collector-component-use-on" : "radiation-collector-component-use-off";
+ _popupSystem.PopupEntity(Loc.GetString(msg), uid);
+ }
+
+ // Update appearance
+ UpdateAppearance(uid, component);
+ }
+
+ private void UpdateAppearance(EntityUid uid, RadiationCollectorComponent? component, AppearanceComponent? appearance = null)
+ {
+ if (!Resolve(uid, ref component, ref appearance))
+ return;
+
+ var state = component.Enabled ? RadiationCollectorVisualState.Active : RadiationCollectorVisualState.Deactive;
+ _appearance.SetData(uid, RadiationCollectorVisuals.VisualState, state, appearance);
+ }
}