file-scoped namespaces

This commit is contained in:
vulppine
2022-08-23 10:55:46 -07:00
parent df25715ed3
commit b3a4ef9997
20 changed files with 2503 additions and 2525 deletions

View File

@@ -8,10 +8,10 @@ using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.Atmos.Monitor
namespace Content.Client.Atmos.Monitor;
public sealed class AtmosMonitorVisualizer : AppearanceVisualizer
{
public sealed class AtmosMonitorVisualizer : AppearanceVisualizer
{
[Dependency] IEntityManager _entityManager = default!;
[DataField("layerMap")]
private string _layerMap { get; } = string.Empty;
@@ -66,5 +66,4 @@ namespace Content.Client.Atmos.Monitor
if (_alarmStates.TryGetValue(alarmType, out var state))
sprite.LayerSetState(layer, new RSI.StateId(state));
}
}
}

View File

@@ -6,10 +6,10 @@ using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
namespace Content.Client.Atmos.Monitor.UI
namespace Content.Client.Atmos.Monitor.UI;
public sealed class AirAlarmBoundUserInterface : BoundUserInterface
{
public sealed class AirAlarmBoundUserInterface : BoundUserInterface
{
private AirAlarmWindow? _window;
public AirAlarmBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
@@ -76,5 +76,4 @@ namespace Content.Client.Atmos.Monitor.UI
if (disposing) _window?.Dispose();
}
}
}

View File

@@ -13,11 +13,11 @@ using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Localization;
namespace Content.Client.Atmos.Monitor.UI
namespace Content.Client.Atmos.Monitor.UI;
[GenerateTypedNameReferences]
public sealed partial class AirAlarmWindow : DefaultWindow
{
[GenerateTypedNameReferences]
public sealed partial class AirAlarmWindow : DefaultWindow
{
public event Action<string, IAtmosDeviceData>? AtmosDeviceDataChanged;
public event Action<string, AtmosMonitorThresholdType, AtmosAlarmThreshold, Gas?>? AtmosAlarmThresholdChanged;
public event Action<AirAlarmMode>? AirAlarmModeChanged;
@@ -148,5 +148,4 @@ namespace Content.Client.Atmos.Monitor.UI
break;
}
}
}
}

View File

@@ -8,11 +8,11 @@ using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Localization;
namespace Content.Client.Atmos.Monitor.UI.Widgets
namespace Content.Client.Atmos.Monitor.UI.Widgets;
[GenerateTypedNameReferences]
public sealed partial class PumpControl : BoxContainer
{
[GenerateTypedNameReferences]
public sealed partial class PumpControl : BoxContainer
{
private GasVentPumpData _data;
private string _address;
@@ -99,5 +99,4 @@ namespace Content.Client.Atmos.Monitor.UI.Widgets
_data.InternalPressureBound = data.InternalPressureBound;
_internalBound.Value = _data.InternalPressureBound;
}
}
}

View File

@@ -11,11 +11,11 @@ using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Localization;
namespace Content.Client.Atmos.Monitor.UI.Widgets
namespace Content.Client.Atmos.Monitor.UI.Widgets;
[GenerateTypedNameReferences]
public sealed partial class ScrubberControl : BoxContainer
{
[GenerateTypedNameReferences]
public sealed partial class ScrubberControl : BoxContainer
{
private GasVentScrubberData _data;
private string _address;
@@ -119,5 +119,4 @@ namespace Content.Client.Atmos.Monitor.UI.Widgets
if (!intersect.Contains(value))
_gasControls[value].Pressed = false;
}
}
}

View File

@@ -11,11 +11,11 @@ using Robust.Shared.Localization;
// holy FUCK
// this technically works because some of this you can *not* do in XAML but holy FUCK
namespace Content.Client.Atmos.Monitor.UI.Widgets
namespace Content.Client.Atmos.Monitor.UI.Widgets;
[GenerateTypedNameReferences]
public sealed partial class ThresholdControl : BoxContainer
{
[GenerateTypedNameReferences]
public sealed partial class ThresholdControl : BoxContainer
{
private AtmosAlarmThreshold _threshold;
private AtmosMonitorThresholdType _type;
private Gas? _gas;
@@ -292,5 +292,4 @@ namespace Content.Client.Atmos.Monitor.UI.Widgets
private bool ValidateThreshold(float value) => (_value != null) && (value >= 0);
}
}
}

View File

@@ -3,11 +3,11 @@ using Content.Shared.Atmos.Monitor.Components;
using Content.Shared.Atmos.Piping.Unary.Components;
using Robust.Shared.Network;
namespace Content.Server.Atmos.Monitor.Components
namespace Content.Server.Atmos.Monitor.Components;
[RegisterComponent]
public sealed class AirAlarmComponent : Component
{
[RegisterComponent]
public sealed class AirAlarmComponent : Component
{
[ViewVariables] public AirAlarmMode CurrentMode { get; set; } = AirAlarmMode.Filtering;
// Remember to null this afterwards.
@@ -23,5 +23,4 @@ namespace Content.Server.Atmos.Monitor.Components
public HashSet<NetUserId> ActivePlayers = new();
public bool CanSync = true;
}
}

View File

@@ -3,32 +3,31 @@ using Content.Shared.Tag;
using Robust.Shared.Audio;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;
namespace Content.Server.Atmos.Monitor.Components
{
// AtmosAlarmables are entities that can be alarmed
// by a linked AtmosMonitor (alarmer?) if a threshold
// is passed in some way. The intended use is to
// do something in case something dangerous happens,
// e.g., activate firelocks in case a temperature
// threshold is reached
//
// It goes:
//
// AtmosMonitor -> AtmosDeviceUpdateEvent
// -> Threshold calculation
// -> AtmosAlarmEvent
// -> Everything linked to that monitor (targetted)
namespace Content.Server.Atmos.Monitor.Components;
// AtmosAlarmables are entities that can be alarmed
// by a linked AtmosMonitor (alarmer?) if a threshold
// is passed in some way. The intended use is to
// do something in case something dangerous happens,
// e.g., activate firelocks in case a temperature
// threshold is reached
//
// It goes:
//
// AtmosMonitor -> AtmosDeviceUpdateEvent
// -> Threshold calculation
// -> AtmosAlarmEvent
// -> Everything linked to that monitor (targetted)
/// <summary>
/// A component to add to device network devices if you want them to be alarmed
/// by an atmospheric alarmer. This will store every single alert received, and
/// calculate the highest alert based on the alerts received. Equally, if you
/// link other alarmables to this, it will store the alerts from them to
/// calculate the highest network alert.
/// </summary>
[RegisterComponent]
public sealed class AtmosAlarmableComponent : Component
{
/// <summary>
/// A component to add to device network devices if you want them to be alarmed
/// by an atmospheric alarmer. This will store every single alert received, and
/// calculate the highest alert based on the alerts received. Equally, if you
/// link other alarmables to this, it will store the alerts from them to
/// calculate the highest network alert.
/// </summary>
[RegisterComponent]
public sealed class AtmosAlarmableComponent : Component
{
[ViewVariables]
public readonly Dictionary<string, AtmosMonitorAlarmType> NetworkAlarmStates = new();
@@ -58,5 +57,4 @@ namespace Content.Server.Atmos.Monitor.Components
/// </summary>
[DataField("receiveOnly")]
public bool ReceiveOnly { get; }
}
}

View File

@@ -3,11 +3,11 @@ using Content.Shared.Atmos.Monitor;
using Robust.Shared.Audio;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Atmos.Monitor.Components
namespace Content.Server.Atmos.Monitor.Components;
[RegisterComponent]
public sealed class AtmosMonitorComponent : Component
{
[RegisterComponent]
public sealed class AtmosMonitorComponent : Component
{
// Whether this monitor can send alarms,
// or recieve atmos command events.
//
@@ -66,5 +66,4 @@ namespace Content.Server.Atmos.Monitor.Components
/// to these devices.
/// </summary>
[ViewVariables] public HashSet<string> RegisteredDevices = new();
}
}

View File

@@ -1,7 +1,6 @@
namespace Content.Server.Atmos.Monitor.Components
namespace Content.Server.Atmos.Monitor.Components;
[RegisterComponent]
public sealed class FireAlarmComponent : Component
{
[RegisterComponent]
public sealed class FireAlarmComponent : Component
{
}
}

View File

@@ -5,14 +5,14 @@ using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor.Components;
using Content.Shared.Atmos.Piping.Unary.Components;
namespace Content.Server.Atmos.Monitor
namespace Content.Server.Atmos.Monitor;
/// <summary>
/// This is an interface that air alarm modes use
/// in order to execute the defined modes.
/// </summary>
public interface IAirAlarmMode
{
/// <summary>
/// This is an interface that air alarm modes use
/// in order to execute the defined modes.
/// </summary>
public interface IAirAlarmMode
{
// This is executed the moment the mode
// is set. This is to ensure that 'dumb'
// modes such as Filter/Panic are immediately
@@ -23,20 +23,20 @@ namespace Content.Server.Atmos.Monitor
/// are immediately set.
/// </summary>
public void Execute(EntityUid uid);
}
}
// IAirAlarmModeUpdate
//
// This is an interface that AirAlarmSystem uses
// in order to 'update' air alarm modes so that
// modes like Replace can be implemented.
/// <summary>
/// An interface that AirAlarmSystem uses
/// in order to update air alarm modes that
/// need updating (e.g., Replace)
/// </summary>
public interface IAirAlarmModeUpdate
{
// IAirAlarmModeUpdate
//
// This is an interface that AirAlarmSystem uses
// in order to 'update' air alarm modes so that
// modes like Replace can be implemented.
/// <summary>
/// An interface that AirAlarmSystem uses
/// in order to update air alarm modes that
/// need updating (e.g., Replace)
/// </summary>
public interface IAirAlarmModeUpdate
{
/// <summary>
/// This is checked by AirAlarmSystem when
/// a mode is updated. This should be set
@@ -51,10 +51,10 @@ namespace Content.Server.Atmos.Monitor
/// be where all the logic goes.
/// </summary>
public void Update(EntityUid uid);
}
}
public sealed class AirAlarmModeFactory
{
public sealed class AirAlarmModeFactory
{
private static IAirAlarmMode _filterMode = new AirAlarmFilterMode();
private static IAirAlarmMode _fillMode = new AirAlarmFillMode();
private static IAirAlarmMode _panicMode = new AirAlarmPanicMode();
@@ -71,11 +71,11 @@ namespace Content.Server.Atmos.Monitor
AirAlarmMode.Replace => new AirAlarmReplaceMode(),
_ => null
};
}
}
// like a tiny little EntitySystem
public abstract class AirAlarmModeExecutor : IAirAlarmMode
{
// like a tiny little EntitySystem
public abstract class AirAlarmModeExecutor : IAirAlarmMode
{
[Dependency] public readonly IEntityManager EntityManager = default!;
public readonly DeviceNetworkSystem DeviceNetworkSystem;
public readonly AirAlarmSystem AirAlarmSystem;
@@ -89,10 +89,10 @@ namespace Content.Server.Atmos.Monitor
DeviceNetworkSystem = EntitySystem.Get<DeviceNetworkSystem>();
AirAlarmSystem = EntitySystem.Get<AirAlarmSystem>();
}
}
}
public sealed class AirAlarmNoneMode : AirAlarmModeExecutor
{
public sealed class AirAlarmNoneMode : AirAlarmModeExecutor
{
public override void Execute(EntityUid uid)
{
if (!EntityManager.TryGetComponent(uid, out AirAlarmComponent? alarm))
@@ -110,10 +110,10 @@ namespace Content.Server.Atmos.Monitor
AirAlarmSystem.SetData(uid, addr, device);
}
}
}
}
public sealed class AirAlarmFilterMode : AirAlarmModeExecutor
{
public sealed class AirAlarmFilterMode : AirAlarmModeExecutor
{
public override void Execute(EntityUid uid)
{
if (!EntityManager.TryGetComponent(uid, out AirAlarmComponent? alarm))
@@ -129,10 +129,10 @@ namespace Content.Server.Atmos.Monitor
AirAlarmSystem.SetData(uid, addr, GasVentScrubberData.FilterModePreset);
}
}
}
}
public sealed class AirAlarmPanicMode : AirAlarmModeExecutor
{
public sealed class AirAlarmPanicMode : AirAlarmModeExecutor
{
public override void Execute(EntityUid uid)
{
if (!EntityManager.TryGetComponent(uid, out AirAlarmComponent? alarm))
@@ -148,10 +148,10 @@ namespace Content.Server.Atmos.Monitor
AirAlarmSystem.SetData(uid, addr, GasVentScrubberData.PanicModePreset);
}
}
}
}
public sealed class AirAlarmFillMode : AirAlarmModeExecutor
{
public sealed class AirAlarmFillMode : AirAlarmModeExecutor
{
public override void Execute(EntityUid uid)
{
if (!EntityManager.TryGetComponent(uid, out AirAlarmComponent? alarm))
@@ -167,10 +167,10 @@ namespace Content.Server.Atmos.Monitor
AirAlarmSystem.SetData(uid, addr, GasVentScrubberData.FillModePreset);
}
}
}
}
public sealed class AirAlarmReplaceMode : AirAlarmModeExecutor, IAirAlarmModeUpdate
{
public sealed class AirAlarmReplaceMode : AirAlarmModeExecutor, IAirAlarmModeUpdate
{
private AirAlarmComponent? _alarm;
private float _lastPressure = Atmospherics.OneAtmosphere;
@@ -210,5 +210,4 @@ namespace Content.Server.Atmos.Monitor
AirAlarmSystem.SetData(uid, addr, GasVentScrubberData.ReplaceModePreset);
}
}
}
}

View File

@@ -18,19 +18,19 @@ using Content.Shared.Interaction;
using Robust.Server.GameObjects;
using Robust.Shared.Player;
namespace Content.Server.Atmos.Monitor.Systems
namespace Content.Server.Atmos.Monitor.Systems;
// AirAlarm system - specific for atmos devices, rather than
// atmos monitors.
//
// oh boy, message passing!
//
// Commands should always be sent into packet's Command
// data key. In response, a packet will be transmitted
// with the response type as its command, and the
// response data in its data key.
public sealed class AirAlarmSystem : EntitySystem
{
// AirAlarm system - specific for atmos devices, rather than
// atmos monitors.
//
// oh boy, message passing!
//
// Commands should always be sent into packet's Command
// data key. In response, a packet will be transmitted
// with the response type as its command, and the
// response data in its data key.
public sealed class AirAlarmSystem : EntitySystem
{
[Dependency] private readonly DeviceNetworkSystem _deviceNet = default!;
[Dependency] private readonly AtmosDeviceNetworkSystem _atmosDevNetSystem = default!;
[Dependency] private readonly AtmosAlarmableSystem _atmosAlarmable = default!;
@@ -530,5 +530,4 @@ namespace Content.Server.Atmos.Monitor.Systems
}
#endregion
}
}

View File

@@ -11,10 +11,10 @@ using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Utility;
namespace Content.Server.Atmos.Monitor.Systems
namespace Content.Server.Atmos.Monitor.Systems;
public sealed class AtmosAlarmableSystem : EntitySystem
{
public sealed class AtmosAlarmableSystem : EntitySystem
{
[Dependency] private readonly AppearanceSystem _appearance = default!;
[Dependency] private readonly AudioSystem _audioSystem = default!;
[Dependency] private readonly DeviceNetworkSystem _deviceNet = default!;
@@ -293,15 +293,14 @@ namespace Content.Server.Atmos.Monitor.Systems
{
_appearance.SetData(uid, AtmosMonitorVisuals.AlarmType, alarm);
}
}
}
public sealed class AtmosAlarmEvent : EntityEventArgs
{
public sealed class AtmosAlarmEvent : EntityEventArgs
{
public AtmosMonitorAlarmType AlarmType { get; }
public AtmosAlarmEvent(AtmosMonitorAlarmType netMax)
{
AlarmType = netMax;
}
}
}

View File

@@ -16,14 +16,14 @@ using Robust.Shared.Audio;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
namespace Content.Server.Atmos.Monitor.Systems
namespace Content.Server.Atmos.Monitor.Systems;
// AtmosMonitorSystem. Grabs all the AtmosAlarmables connected
// to it via local APC net, and starts sending updates of the
// current atmosphere. Monitors fire (which always triggers as
// a danger), and atmos (which triggers based on set thresholds).
public sealed class AtmosMonitorSystem : EntitySystem
{
// AtmosMonitorSystem. Grabs all the AtmosAlarmables connected
// to it via local APC net, and starts sending updates of the
// current atmosphere. Monitors fire (which always triggers as
// a danger), and atmos (which triggers based on set thresholds).
public sealed class AtmosMonitorSystem : EntitySystem
{
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private readonly AtmosDeviceSystem _atmosDeviceSystem = default!;
[Dependency] private readonly DeviceNetworkSystem _deviceNetSystem = default!;
@@ -33,8 +33,6 @@ namespace Content.Server.Atmos.Monitor.Systems
public const string AtmosMonitorSetThresholdCmd = "atmos_monitor_set_threshold";
// Packet data
public const string AlertTypes = "atmos_monitor_alert_types";
public const string AtmosMonitorThresholdData = "atmos_monitor_threshold_data";
public const string AtmosMonitorThresholdDataType = "atmos_monitor_threshold_type";
@@ -379,5 +377,4 @@ namespace Content.Server.Atmos.Monitor.Systems
}
}
}
}

View File

@@ -9,10 +9,10 @@ using Content.Shared.Interaction;
using Content.Shared.Emag.Systems;
using Robust.Server.GameObjects;
namespace Content.Server.Atmos.Monitor.Systems
namespace Content.Server.Atmos.Monitor.Systems;
public sealed class FireAlarmSystem : EntitySystem
{
public sealed class FireAlarmSystem : EntitySystem
{
[Dependency] private readonly AtmosDeviceNetworkSystem _atmosDevNet = default!;
[Dependency] private readonly AtmosAlarmableSystem _atmosAlarmable = default!;
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
@@ -65,5 +65,4 @@ namespace Content.Server.Atmos.Monitor.Systems
}
}
}
}
}

View File

@@ -0,0 +1,270 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.Atmos.Monitor;
// mostly based around floats and percentages, no literals
// except for the range boundaries
[Prototype("alarmThreshold")]
[Serializable, NetSerializable]
public sealed class AtmosAlarmThreshold : IPrototype, ISerializationHooks
{
[IdDataFieldAttribute]
public string ID { get; } = default!;
[ViewVariables]
[DataField("ignore")]
public bool Ignore = false;
// zero bounds are not allowed - just
// set the bound to null if you want
// to disable it
[ViewVariables]
[DataField("upperBound")]
public float? UpperBound { get; private set; }
[ViewVariables]
[DataField("lowerBound")]
public float? LowerBound { get; private set; }
// upper warning percentage
// must always cause UpperWarningBound
// to be smaller
[ViewVariables]
[DataField("upperWarnAround")]
public float? UpperWarningPercentage { get; private set; }
// lower warning percentage
// must always cause LowerWarningBound
// to be larger
[ViewVariables]
[DataField("lowerWarnAround")]
public float? LowerWarningPercentage { get; private set; }
[ViewVariables]
public float? UpperWarningBound
{
get => CalculateWarningBound(AtmosMonitorThresholdBound.Upper);
}
[ViewVariables]
public float? LowerWarningBound
{
get => CalculateWarningBound(AtmosMonitorThresholdBound.Lower);
}
public AtmosAlarmThreshold()
{}
public AtmosAlarmThreshold(AtmosAlarmThreshold other)
{
Ignore = other.Ignore;
UpperBound = other.UpperBound;
LowerBound = other.LowerBound;
UpperWarningPercentage = other.UpperWarningPercentage;
LowerWarningPercentage = other.LowerWarningPercentage;
}
void ISerializationHooks.AfterDeserialization()
{
if (UpperBound <= LowerBound)
UpperBound = null;
if (LowerBound >= UpperBound)
LowerBound = null;
if (UpperWarningPercentage != null)
TrySetWarningBound(AtmosMonitorThresholdBound.Upper, UpperBound * UpperWarningPercentage);
if (LowerWarningPercentage != null)
TrySetWarningBound(AtmosMonitorThresholdBound.Lower, LowerBound * LowerWarningPercentage);
}
// utility function to check a threshold against some calculated value
public bool CheckThreshold(float value, out AtmosMonitorAlarmType state)
{
state = AtmosMonitorAlarmType.Normal;
if (Ignore) return false;
if (value >= UpperBound || value <= LowerBound)
{
state = AtmosMonitorAlarmType.Danger;
return true;
}
if (value >= UpperWarningBound || value <= LowerWarningBound)
{
state = AtmosMonitorAlarmType.Warning;
return true;
}
return true;
}
// set the primary bound, takes a hard value
public bool TrySetPrimaryBound(AtmosMonitorThresholdBound bound, float? input)
{
if (input == null)
{
switch (bound)
{
case AtmosMonitorThresholdBound.Upper:
UpperBound = null;
break;
case AtmosMonitorThresholdBound.Lower:
LowerBound = null;
break;
}
return true;
}
float value = (float) input;
if (value <= 0f || float.IsNaN(value))
return false;
(float target, int compare)? targetValue = null;
switch (bound)
{
case AtmosMonitorThresholdBound.Upper:
if (float.IsPositiveInfinity(value))
return false;
if (LowerBound != null)
targetValue = ((float) LowerBound, -1);
break;
case AtmosMonitorThresholdBound.Lower:
if (float.IsNegativeInfinity(value))
return false;
if (UpperBound != null)
targetValue = ((float) UpperBound, 1);
break;
}
bool isValid = true;
if (targetValue != null)
{
var result = targetValue.Value.target.CompareTo(value);
isValid = targetValue.Value.compare == result;
}
if (isValid)
{
switch (bound)
{
case AtmosMonitorThresholdBound.Upper:
UpperBound = value;
return true;
case AtmosMonitorThresholdBound.Lower:
LowerBound = value;
return true;
}
}
return false;
}
// set the warning bound, takes a hard value
//
// this will always set the percentage and
// the raw value at the same time
public bool TrySetWarningBound(AtmosMonitorThresholdBound bound, float? input)
{
if (input == null)
{
switch (bound)
{
case AtmosMonitorThresholdBound.Upper:
UpperWarningPercentage = null;
break;
case AtmosMonitorThresholdBound.Lower:
LowerWarningPercentage = null;
break;
}
return true;
}
switch (bound)
{
case AtmosMonitorThresholdBound.Upper:
if (UpperBound == null)
return false;
float upperWarning = (float) (input / UpperBound);
float upperTestValue = (upperWarning * (float) UpperBound);
if (upperWarning > 1f
|| upperTestValue < LowerWarningBound
|| upperTestValue < LowerBound)
return false;
UpperWarningPercentage = upperWarning;
return true;
case AtmosMonitorThresholdBound.Lower:
if (LowerBound == null)
return false;
float lowerWarning = (float) (input / LowerBound);
float testValue = (lowerWarning * (float) LowerBound);
if (lowerWarning < 1f
|| testValue > UpperWarningBound
|| testValue > UpperBound)
return false;
LowerWarningPercentage = lowerWarning;
return true;
}
return false;
}
public float? CalculateWarningBound(AtmosMonitorThresholdBound bound)
{
float? value = null;
switch (bound)
{
case AtmosMonitorThresholdBound.Upper:
if (UpperBound == null || UpperWarningPercentage == null)
break;
value = UpperBound * UpperWarningPercentage;
break;
case AtmosMonitorThresholdBound.Lower:
if (LowerBound == null || LowerWarningPercentage == null)
break;
value = LowerBound * LowerWarningPercentage;
break;
}
return value;
}
}
public enum AtmosMonitorThresholdBound
{
Upper,
Lower
}
// not really used in the prototype but in code,
// to differentiate between the different
// fields you can find this prototype in
public enum AtmosMonitorThresholdType
{
Temperature,
Pressure,
Gas
}
[Serializable, NetSerializable]
public enum AtmosMonitorVisuals : byte
{
Offset,
AlarmType,
}

View File

@@ -1,271 +0,0 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.Atmos.Monitor
{
// mostly based around floats and percentages, no literals
// except for the range boundaries
[Prototype("alarmThreshold")]
[Serializable, NetSerializable]
public sealed class AtmosAlarmThreshold : IPrototype, ISerializationHooks
{
[IdDataFieldAttribute]
public string ID { get; } = default!;
[ViewVariables]
[DataField("ignore")]
public bool Ignore = false;
// zero bounds are not allowed - just
// set the bound to null if you want
// to disable it
[ViewVariables]
[DataField("upperBound")]
public float? UpperBound { get; private set; }
[ViewVariables]
[DataField("lowerBound")]
public float? LowerBound { get; private set; }
// upper warning percentage
// must always cause UpperWarningBound
// to be smaller
[ViewVariables]
[DataField("upperWarnAround")]
public float? UpperWarningPercentage { get; private set; }
// lower warning percentage
// must always cause LowerWarningBound
// to be larger
[ViewVariables]
[DataField("lowerWarnAround")]
public float? LowerWarningPercentage { get; private set; }
[ViewVariables]
public float? UpperWarningBound
{
get => CalculateWarningBound(AtmosMonitorThresholdBound.Upper);
}
[ViewVariables]
public float? LowerWarningBound
{
get => CalculateWarningBound(AtmosMonitorThresholdBound.Lower);
}
public AtmosAlarmThreshold()
{}
public AtmosAlarmThreshold(AtmosAlarmThreshold other)
{
Ignore = other.Ignore;
UpperBound = other.UpperBound;
LowerBound = other.LowerBound;
UpperWarningPercentage = other.UpperWarningPercentage;
LowerWarningPercentage = other.LowerWarningPercentage;
}
void ISerializationHooks.AfterDeserialization()
{
if (UpperBound <= LowerBound)
UpperBound = null;
if (LowerBound >= UpperBound)
LowerBound = null;
if (UpperWarningPercentage != null)
TrySetWarningBound(AtmosMonitorThresholdBound.Upper, UpperBound * UpperWarningPercentage);
if (LowerWarningPercentage != null)
TrySetWarningBound(AtmosMonitorThresholdBound.Lower, LowerBound * LowerWarningPercentage);
}
// utility function to check a threshold against some calculated value
public bool CheckThreshold(float value, out AtmosMonitorAlarmType state)
{
state = AtmosMonitorAlarmType.Normal;
if (Ignore) return false;
if (value >= UpperBound || value <= LowerBound)
{
state = AtmosMonitorAlarmType.Danger;
return true;
}
if (value >= UpperWarningBound || value <= LowerWarningBound)
{
state = AtmosMonitorAlarmType.Warning;
return true;
}
return true;
}
// set the primary bound, takes a hard value
public bool TrySetPrimaryBound(AtmosMonitorThresholdBound bound, float? input)
{
if (input == null)
{
switch (bound)
{
case AtmosMonitorThresholdBound.Upper:
UpperBound = null;
break;
case AtmosMonitorThresholdBound.Lower:
LowerBound = null;
break;
}
return true;
}
float value = (float) input;
if (value <= 0f || float.IsNaN(value))
return false;
(float target, int compare)? targetValue = null;
switch (bound)
{
case AtmosMonitorThresholdBound.Upper:
if (float.IsPositiveInfinity(value))
return false;
if (LowerBound != null)
targetValue = ((float) LowerBound, -1);
break;
case AtmosMonitorThresholdBound.Lower:
if (float.IsNegativeInfinity(value))
return false;
if (UpperBound != null)
targetValue = ((float) UpperBound, 1);
break;
}
bool isValid = true;
if (targetValue != null)
{
var result = targetValue.Value.target.CompareTo(value);
isValid = targetValue.Value.compare == result;
}
if (isValid)
{
switch (bound)
{
case AtmosMonitorThresholdBound.Upper:
UpperBound = value;
return true;
case AtmosMonitorThresholdBound.Lower:
LowerBound = value;
return true;
}
}
return false;
}
// set the warning bound, takes a hard value
//
// this will always set the percentage and
// the raw value at the same time
public bool TrySetWarningBound(AtmosMonitorThresholdBound bound, float? input)
{
if (input == null)
{
switch (bound)
{
case AtmosMonitorThresholdBound.Upper:
UpperWarningPercentage = null;
break;
case AtmosMonitorThresholdBound.Lower:
LowerWarningPercentage = null;
break;
}
return true;
}
switch (bound)
{
case AtmosMonitorThresholdBound.Upper:
if (UpperBound == null)
return false;
float upperWarning = (float) (input / UpperBound);
float upperTestValue = (upperWarning * (float) UpperBound);
if (upperWarning > 1f
|| upperTestValue < LowerWarningBound
|| upperTestValue < LowerBound)
return false;
UpperWarningPercentage = upperWarning;
return true;
case AtmosMonitorThresholdBound.Lower:
if (LowerBound == null)
return false;
float lowerWarning = (float) (input / LowerBound);
float testValue = (lowerWarning * (float) LowerBound);
if (lowerWarning < 1f
|| testValue > UpperWarningBound
|| testValue > UpperBound)
return false;
LowerWarningPercentage = lowerWarning;
return true;
}
return false;
}
public float? CalculateWarningBound(AtmosMonitorThresholdBound bound)
{
float? value = null;
switch (bound)
{
case AtmosMonitorThresholdBound.Upper:
if (UpperBound == null || UpperWarningPercentage == null)
break;
value = UpperBound * UpperWarningPercentage;
break;
case AtmosMonitorThresholdBound.Lower:
if (LowerBound == null || LowerWarningPercentage == null)
break;
value = LowerBound * LowerWarningPercentage;
break;
}
return value;
}
}
public enum AtmosMonitorThresholdBound
{
Upper,
Lower
}
// not really used in the prototype but in code,
// to differentiate between the different
// fields you can find this prototype in
public enum AtmosMonitorThresholdType
{
Temperature,
Pressure,
Gas
}
[Serializable, NetSerializable]
public enum AtmosMonitorVisuals : byte
{
Offset,
AlarmType,
}
}

View File

@@ -1,13 +1,12 @@
using Robust.Shared.Serialization;
namespace Content.Shared.Atmos.Monitor
namespace Content.Shared.Atmos.Monitor;
[Serializable, NetSerializable]
public enum AtmosMonitorAlarmType : sbyte
{
[Serializable, NetSerializable]
public enum AtmosMonitorAlarmType : sbyte
{
Normal = 0,
Warning = 1,
Danger = 2, // 1 << 1 is the exact same thing and we're not really doing **bitmasking** are we?
Emagged = 3,
}
}

View File

@@ -1,42 +1,42 @@
using Robust.Shared.Serialization;
namespace Content.Shared.Atmos.Monitor.Components
{
[Serializable, NetSerializable]
public enum SharedAirAlarmInterfaceKey
{
Key
}
namespace Content.Shared.Atmos.Monitor.Components;
[Serializable, NetSerializable]
public enum AirAlarmMode
{
[Serializable, NetSerializable]
public enum SharedAirAlarmInterfaceKey
{
Key
}
[Serializable, NetSerializable]
public enum AirAlarmMode
{
None,
Filtering,
Fill,
Panic,
Replace
}
}
[Serializable, NetSerializable]
public enum AirAlarmWireStatus
{
[Serializable, NetSerializable]
public enum AirAlarmWireStatus
{
Power,
Access,
Panic,
DeviceSync
}
}
public interface IAtmosDeviceData
{
public interface IAtmosDeviceData
{
public bool Enabled { get; set; }
public bool Dirty { get; set; }
public bool IgnoreAlarms { get; set; }
}
}
[Serializable, NetSerializable]
public sealed class AirAlarmUIState : BoundUserInterfaceState
{
[Serializable, NetSerializable]
public sealed class AirAlarmUIState : BoundUserInterfaceState
{
public AirAlarmUIState(string address, int deviceCount, float pressureAverage, float temperatureAverage, Dictionary<string, IAtmosDeviceData> deviceData, AirAlarmMode mode, AirAlarmTab tab, AtmosMonitorAlarmType alarmType)
{
Address = address;
@@ -63,37 +63,37 @@ namespace Content.Shared.Atmos.Monitor.Components
public AirAlarmMode Mode { get; }
public AirAlarmTab Tab { get; }
public AtmosMonitorAlarmType AlarmType { get; }
}
}
[Serializable, NetSerializable]
public sealed class AirAlarmTabSetMessage : BoundUserInterfaceMessage
{
[Serializable, NetSerializable]
public sealed class AirAlarmTabSetMessage : BoundUserInterfaceMessage
{
public AirAlarmTabSetMessage(AirAlarmTab tab)
{
Tab = tab;
}
public AirAlarmTab Tab { get; }
}
}
[Serializable, NetSerializable]
public sealed class AirAlarmResyncAllDevicesMessage : BoundUserInterfaceMessage
{}
[Serializable, NetSerializable]
public sealed class AirAlarmResyncAllDevicesMessage : BoundUserInterfaceMessage
{}
[Serializable, NetSerializable]
public sealed class AirAlarmUpdateAlarmModeMessage : BoundUserInterfaceMessage
{
[Serializable, NetSerializable]
public sealed class AirAlarmUpdateAlarmModeMessage : BoundUserInterfaceMessage
{
public AirAlarmMode Mode { get; }
public AirAlarmUpdateAlarmModeMessage(AirAlarmMode mode)
{
Mode = mode;
}
}
}
[Serializable, NetSerializable]
public sealed class AirAlarmUpdateDeviceDataMessage : BoundUserInterfaceMessage
{
[Serializable, NetSerializable]
public sealed class AirAlarmUpdateDeviceDataMessage : BoundUserInterfaceMessage
{
public string Address { get; }
public IAtmosDeviceData Data { get; }
@@ -102,11 +102,11 @@ namespace Content.Shared.Atmos.Monitor.Components
Address = addr;
Data = data;
}
}
}
[Serializable, NetSerializable]
public sealed class AirAlarmUpdateAlarmThresholdMessage : BoundUserInterfaceMessage
{
[Serializable, NetSerializable]
public sealed class AirAlarmUpdateAlarmThresholdMessage : BoundUserInterfaceMessage
{
public string Address { get; }
public AtmosAlarmThreshold Threshold { get; }
public AtmosMonitorThresholdType Type { get; }
@@ -119,13 +119,12 @@ namespace Content.Shared.Atmos.Monitor.Components
Type = type;
Gas = gas;
}
}
}
public enum AirAlarmTab
{
public enum AirAlarmTab
{
Vent,
Scrubber,
Sensors,
Settings
}
}

View File

@@ -1,11 +1,10 @@
using Robust.Shared.Serialization;
namespace Content.Shared.Atmos.Monitor.Components
namespace Content.Shared.Atmos.Monitor.Components;
[Serializable, NetSerializable]
public enum FireAlarmWireStatus
{
[Serializable, NetSerializable]
public enum FireAlarmWireStatus
{
Power,
Alarm
}
}