diff --git a/Content.Client/Salvage/SalvageMagnetComponent.cs b/Content.Client/Salvage/SalvageMagnetComponent.cs new file mode 100644 index 0000000000..44b8b9d958 --- /dev/null +++ b/Content.Client/Salvage/SalvageMagnetComponent.cs @@ -0,0 +1,5 @@ +using Content.Shared.Salvage; +using Robust.Shared.GameStates; + +[NetworkedComponent, RegisterComponent] +public sealed class SalvageMagnetComponent : SharedSalvageMagnetComponent {} diff --git a/Content.Server/Salvage/SalvageMagnetComponent.cs b/Content.Server/Salvage/SalvageMagnetComponent.cs index 6ec6339467..a756a1cbdf 100644 --- a/Content.Server/Salvage/SalvageMagnetComponent.cs +++ b/Content.Server/Salvage/SalvageMagnetComponent.cs @@ -1,14 +1,17 @@ using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Content.Shared.Radio; +using Content.Shared.Salvage; +using Robust.Shared.GameStates; namespace Content.Server.Salvage { /// /// A salvage magnet. /// - [RegisterComponent] - public sealed class SalvageMagnetComponent : Component + [NetworkedComponent, RegisterComponent] + [Access(typeof(SalvageSystem))] + public sealed class SalvageMagnetComponent : SharedSalvageMagnetComponent { /// /// Offset relative to magnet used as centre of the placement circle. @@ -49,6 +52,21 @@ namespace Content.Server.Salvage [DataField("salvageChannel", customTypeSerializer: typeof(PrototypeIdSerializer))] public string SalvageChannel = "Supply"; + /// + /// Current how much charge the magnet currently has + /// + public int ChargeRemaining = 5; + + /// + /// How much capacity the magnet can hold + /// + public int ChargeCapacity = 5; + + /// + /// Used as a guard to prevent spamming the appearance system + /// + public int PreviousCharge = 5; + } public record struct MagnetState(MagnetStateType StateType, TimeSpan Until) { diff --git a/Content.Server/Salvage/SalvageSystem.cs b/Content.Server/Salvage/SalvageSystem.cs index ebbd4651a9..1330314b1d 100644 --- a/Content.Server/Salvage/SalvageSystem.cs +++ b/Content.Server/Salvage/SalvageSystem.cs @@ -3,6 +3,7 @@ using Content.Shared.CCVar; using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Popups; +using Content.Shared.Salvage; using Robust.Server.Maps; using Robust.Shared.Configuration; using Robust.Shared.Map; @@ -27,6 +28,7 @@ namespace Content.Server.Salvage [Dependency] private readonly MapLoaderSystem _map = default!; [Dependency] private readonly SharedPopupSystem _popupSystem = default!; [Dependency] private readonly RadioSystem _radioSystem = default!; + [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; private static readonly TimeSpan AttachingTime = TimeSpan.FromSeconds(30); private static readonly TimeSpan HoldTime = TimeSpan.FromMinutes(4); @@ -58,6 +60,42 @@ namespace Content.Server.Salvage } } + private void UpdateAppearance(EntityUid uid, SalvageMagnetComponent? component = null) + { + if (!Resolve(uid, ref component, false)) + return; + + _appearanceSystem.SetData(uid, SalvageMagnetVisuals.ReadyBlinking, component.MagnetState.StateType == MagnetStateType.Attaching); + _appearanceSystem.SetData(uid, SalvageMagnetVisuals.Ready, component.MagnetState.StateType == MagnetStateType.Holding); + _appearanceSystem.SetData(uid, SalvageMagnetVisuals.Unready, component.MagnetState.StateType == MagnetStateType.CoolingDown); + _appearanceSystem.SetData(uid, SalvageMagnetVisuals.UnreadyBlinking, component.MagnetState.StateType == MagnetStateType.Detaching); + } + + private void UpdateChargeStateAppearance(EntityUid uid, TimeSpan currentTime, SalvageMagnetComponent? component = null) + { + if (!Resolve(uid, ref component, false)) + return; + + int timeLeft = (component.MagnetState.Until.Minutes * 60 + component.MagnetState.Until.Seconds) - (currentTime.Minutes * 60 + currentTime.Seconds); + if (component.MagnetState.StateType == MagnetStateType.Inactive) + component.ChargeRemaining = 5; + else if (component.MagnetState.StateType == MagnetStateType.Holding) + { + component.ChargeRemaining = (timeLeft / ((HoldTime.Minutes * 60 + HoldTime.Seconds) / component.ChargeCapacity)) + 1; + } + else if (component.MagnetState.StateType == MagnetStateType.Detaching) + component.ChargeRemaining = 0; + else if (component.MagnetState.StateType == MagnetStateType.CoolingDown) + { + component.ChargeRemaining = component.ChargeCapacity - (timeLeft / ((CooldownTime.Minutes * 60 + CooldownTime.Seconds) / component.ChargeCapacity)) - 1; + } + if (component.PreviousCharge != component.ChargeRemaining) + { + _appearanceSystem.SetData(uid, SalvageMagnetVisuals.ChargeState, component.ChargeRemaining); + component.PreviousCharge = component.ChargeRemaining; + } + } + private void OnGridRemoval(GridRemovalEvent ev) { // If we ever want to give magnets names, and announce them individually, we would need to loop this, before removing it. @@ -146,6 +184,7 @@ namespace Content.Server.Salvage return; args.Handled = true; StartMagnet(component, args.User); + UpdateAppearance(uid, component); } private void StartMagnet(SalvageMagnetComponent component, EntityUid user) @@ -356,6 +395,8 @@ namespace Content.Server.Salvage magnet.MagnetState = MagnetState.Inactive; break; } + UpdateAppearance(magnet.Owner, magnet); + UpdateChargeStateAppearance(magnet.Owner, currentTime, magnet); } public override void Update(float frameTime) @@ -373,8 +414,10 @@ namespace Content.Server.Salvage state.CurrentTime += secondsPassed; var deleteQueue = new RemQueue(); + foreach(var magnet in state.ActiveMagnets) { + UpdateChargeStateAppearance(magnet.Owner, state.CurrentTime, magnet); if (magnet.MagnetState.Until > state.CurrentTime) continue; Transition(magnet, state.CurrentTime); if (magnet.MagnetState.StateType == MagnetStateType.Inactive) diff --git a/Content.Shared/Salvage/SharedSalvageMagnetComponent.cs b/Content.Shared/Salvage/SharedSalvageMagnetComponent.cs new file mode 100644 index 0000000000..fac5870d2d --- /dev/null +++ b/Content.Shared/Salvage/SharedSalvageMagnetComponent.cs @@ -0,0 +1,15 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.Salvage; + +public abstract class SharedSalvageMagnetComponent : Component {} + +[Serializable, NetSerializable] +public enum SalvageMagnetVisuals : byte +{ + ChargeState, + Ready, + ReadyBlinking, + Unready, + UnreadyBlinking +} diff --git a/Resources/Prototypes/Entities/Structures/Machines/salvage.yml b/Resources/Prototypes/Entities/Structures/Machines/salvage.yml index 3d010ac4cb..39887c2243 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/salvage.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/salvage.yml @@ -5,10 +5,52 @@ description: "Pulls in salvage." components: - type: Sprite + netsync: false + sprite: Structures/Machines/salvage.rsi layers: - - sprite: Structures/Machines/salvage.rsi - state: salvage-magnet - # Ideally, there'd be lights indicating power usage and a big red lamp indicating loss + - state: salvage-magnet + - state: salvage-magnet-ready + visible: false + map: [ "ready" ] + - state: salvage-magnet-ready-blinking + visible: false + map: [ "readyBlinking" ] + - state: salvage-magnet-unready + visible: false + map: [ "unready" ] + - state: salvage-magnet-unready-blinking + visible: false + map: [ "unreadyBlinking" ] + - state: salvage-magnet-o4 + map: ["chargeState"] + shader: unshaded + - type: Appearance + - type: GenericVisualizer + visuals: + enum.SalvageMagnetVisuals.ChargeState: + chargeState: + 0: { state: salvage-magnet-o0, shader: "unshaded", visible: false } + 1: { state: salvage-magnet-o0, shader: "unshaded", visible: true } + 2: { state: salvage-magnet-o1, shader: "unshaded", visible: true } + 3: { state: salvage-magnet-o2, shader: "unshaded", visible: true } + 4: { state: salvage-magnet-o3, shader: "unshaded", visible: true } + 5: { state: salvage-magnet-o4, shader: "unshaded", visible: true } + enum.SalvageMagnetVisuals.Ready: + ready: + False: { state: salvage-magnet-ready, visible: false, shader: "unshaded" } + True: { state: salvage-magnet-ready, visible: true, shader: "unshaded" } + enum.SalvageMagnetVisuals.ReadyBlinking: + readyBlinking: + False: { state: salvage-magnet-ready-blinking, visible: false, shader: "unshaded" } + True: { state: salvage-magnet-ready-blinking, visible: true, shader: "unshaded" } + enum.SalvageMagnetVisuals.Unready: + unready: + False: { state: salvage-magnet-unready, visible: false, shader: "unshaded" } + True: { state: salvage-magnet-unready, visible: true, shader: "unshaded" } + enum.SalvageMagnetVisuals.UnreadyBlinking: + unreadyBlinking: + False: { state: salvage-magnet-unready-blinking, visible: false, shader: "unshaded" } + True: { state: salvage-magnet-unready-blinking, visible: true, shader: "unshaded" } - type: Rotatable - type: Transform noRot: false diff --git a/Resources/Textures/Structures/Machines/salvage.rsi/meta.json b/Resources/Textures/Structures/Machines/salvage.rsi/meta.json index 852e539aef..6b62026074 100644 --- a/Resources/Textures/Structures/Machines/salvage.rsi/meta.json +++ b/Resources/Textures/Structures/Machines/salvage.rsi/meta.json @@ -9,8 +9,60 @@ "states": [ { "name": "salvage-magnet", + "directions": 4 + }, + { + "name": "salvage-magnet-o0", "directions": 4, - "commentary": "So presumably the lights would represent the power usage of the magnet, when that's in, and the big red lamp would mean something's being lost." + "commentary": "o0 - 04 represent the amount of time remaining during holding/detaching and cooldown." + }, + { + "name": "salvage-magnet-o1", + "directions": 4 + }, + { + "name": "salvage-magnet-o2", + "directions": 4 + }, + { + "name": "salvage-magnet-o3", + "directions": 4 + }, + { + "name": "salvage-magnet-o4", + "directions": 4 + }, + { + "name": "salvage-magnet-unready", + "directions": 4, + "commentary": "Cooldown state" + }, + { + "name": "salvage-magnet-ready", + "directions": 4, + "commentary": "Holding state" + }, + { + "name": "salvage-magnet-ready-blinking", + "directions": 4, + "delays": [ + [ 0.2, 0.2], + [ 0.2, 0.2], + [ 0.2, 0.2], + [ 0.2, 0.2] + ], + "commentary": "Attaching state" + }, + { + "name": "salvage-magnet-unready-blinking", + "directions": 4, + "delays": [ + [ 0.2, 0.2], + [ 0.2, 0.2], + [ 0.2, 0.2], + [ 0.2, 0.2] + ], + "commentary": "Detaching state" } ] } diff --git a/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o0.png b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o0.png new file mode 100644 index 0000000000..6df11fbe99 Binary files /dev/null and b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o0.png differ diff --git a/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o1.png b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o1.png new file mode 100644 index 0000000000..f6cc385e4c Binary files /dev/null and b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o1.png differ diff --git a/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o2.png b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o2.png new file mode 100644 index 0000000000..ac86dc152d Binary files /dev/null and b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o2.png differ diff --git a/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o3.png b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o3.png new file mode 100644 index 0000000000..6a313591d3 Binary files /dev/null and b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o3.png differ diff --git a/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o4.png b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o4.png new file mode 100644 index 0000000000..5761f5bb75 Binary files /dev/null and b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-o4.png differ diff --git a/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-ready-blinking.png b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-ready-blinking.png new file mode 100644 index 0000000000..ec74a68ba7 Binary files /dev/null and b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-ready-blinking.png differ diff --git a/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-ready.png b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-ready.png new file mode 100644 index 0000000000..084dc7ecf0 Binary files /dev/null and b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-ready.png differ diff --git a/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-unready-blinking.png b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-unready-blinking.png new file mode 100644 index 0000000000..1bc46e2eb3 Binary files /dev/null and b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-unready-blinking.png differ diff --git a/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-unready.png b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-unready.png new file mode 100644 index 0000000000..a20b91edd1 Binary files /dev/null and b/Resources/Textures/Structures/Machines/salvage.rsi/salvage-magnet-unready.png differ