using Robust.Shared.Audio; using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Shared.Disposal.Components; [NetworkedComponent] public abstract class SharedDisposalUnitComponent : Component { public const string ContainerId = "disposals"; /// /// Sounds played upon the unit flushing. /// [ViewVariables(VVAccess.ReadWrite), DataField("soundFlush")] public SoundSpecifier? FlushSound = new SoundPathSpecifier("/Audio/Machines/disposalflush.ogg"); /// /// State for this disposals unit. /// [DataField("state")] public DisposalsPressureState State; // TODO: Just make this use vaulting. /// /// We'll track whatever just left disposals so we know what collision we need to ignore until they stop intersecting our BB. /// [ViewVariables, DataField("recentlyEjected")] public readonly List RecentlyEjected = new(); /// /// Next time the disposal unit will be pressurized. /// [DataField("nextPressurized", customTypeSerializer:typeof(TimeOffsetSerializer))] public TimeSpan NextPressurized = TimeSpan.Zero; /// /// How long it takes to flush a disposals unit manually. /// [DataField("flushTime")] public TimeSpan ManualFlushTime = TimeSpan.FromSeconds(2); /// /// How long it takes from the start of a flush animation to return the sprite to normal. /// [DataField("flushDelay")] public TimeSpan FlushDelay = TimeSpan.FromSeconds(3); [DataField("mobsCanEnter")] public bool MobsCanEnter = true; /// /// Removes the pressure requirement for flushing. /// [DataField("disablePressure"), ViewVariables(VVAccess.ReadWrite)] public bool DisablePressure = false; /// /// Last time that an entity tried to exit this disposal unit. /// [ViewVariables] public TimeSpan LastExitAttempt; [DataField("autoEngageEnabled")] public bool AutomaticEngage = true; [ViewVariables(VVAccess.ReadWrite)] [DataField("autoEngageTime")] public TimeSpan AutomaticEngageTime = TimeSpan.FromSeconds(30); /// /// Delay from trying to enter disposals ourselves. /// [ViewVariables(VVAccess.ReadWrite)] [DataField("entryDelay")] public float EntryDelay = 0.5f; /// /// Delay from trying to shove someone else into disposals. /// [ViewVariables(VVAccess.ReadWrite)] public float DraggedEntryDelay = 0.5f; /// /// Container of entities inside this disposal unit. /// [ViewVariables] public Container Container = default!; // TODO: Network power shit instead fam. [ViewVariables, DataField("powered")] public bool Powered; /// /// Was the disposals unit engaged for a manual flush. /// [ViewVariables(VVAccess.ReadWrite), DataField("engaged")] public bool Engaged; /// /// Next time this unit will flush. Is the lesser of and /// [ViewVariables, DataField("nextFlush", customTypeSerializer:typeof(TimeOffsetSerializer))] public TimeSpan? NextFlush; [Serializable, NetSerializable] public enum Visuals : byte { VisualState, Handle, Light } [Serializable, NetSerializable] public enum VisualState : byte { UnAnchored, Anchored, Flushing, Charging } [Serializable, NetSerializable] public enum HandleState : byte { Normal, Engaged } [Serializable, NetSerializable] [Flags] public enum LightStates : byte { Off = 0, Charging = 1 << 0, Full = 1 << 1, Ready = 1 << 2 } [Serializable, NetSerializable] public enum UiButton : byte { Eject, Engage, Power } [Serializable, NetSerializable] public sealed class DisposalUnitBoundUserInterfaceState : BoundUserInterfaceState, IEquatable { public readonly string UnitName; public readonly string UnitState; public readonly TimeSpan FullPressureTime; public readonly bool Powered; public readonly bool Engaged; public DisposalUnitBoundUserInterfaceState(string unitName, string unitState, TimeSpan fullPressureTime, bool powered, bool engaged) { UnitName = unitName; UnitState = unitState; FullPressureTime = fullPressureTime; Powered = powered; Engaged = engaged; } public bool Equals(DisposalUnitBoundUserInterfaceState? other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return UnitName == other.UnitName && UnitState == other.UnitState && Powered == other.Powered && Engaged == other.Engaged && FullPressureTime.Equals(other.FullPressureTime); } } /// /// Message data sent from client to server when a disposal unit ui button is pressed. /// [Serializable, NetSerializable] public sealed class UiButtonPressedMessage : BoundUserInterfaceMessage { public readonly UiButton Button; public UiButtonPressedMessage(UiButton button) { Button = button; } } [Serializable, NetSerializable] public enum DisposalUnitUiKey : byte { Key } } [Serializable, NetSerializable] public enum DisposalsPressureState : byte { Ready, /// /// Has been flushed recently within FlushDelay. /// Flushed, /// /// FlushDelay has elapsed and now we're transitioning back to Ready. /// Pressurizing }