diff --git a/Content.Server/Cargo/Systems/CargoSystem.Telepad.cs b/Content.Server/Cargo/Systems/CargoSystem.Telepad.cs index 5a6ecce805..6ab58d88c6 100644 --- a/Content.Server/Cargo/Systems/CargoSystem.Telepad.cs +++ b/Content.Server/Cargo/Systems/CargoSystem.Telepad.cs @@ -1,4 +1,3 @@ -using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Server.Cargo.Components; using Content.Server.Power.Components; @@ -8,131 +7,35 @@ using Content.Shared.Cargo.Components; using Content.Shared.DeviceLinking; using Content.Shared.Power; using Content.Shared.Station.Components; -using Robust.Shared.Audio; using Robust.Shared.Random; namespace Content.Server.Cargo.Systems; public sealed partial class CargoSystem { - private void InitializeTelepad() + [SubscribeLocalEvent] + private void OnInit(Entity ent, ref ComponentInit args) { - SubscribeLocalEvent(OnInit); - SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnTelepadPowerChange); - // Shouldn't need re-anchored event - SubscribeLocalEvent(OnTelepadAnchorChange); - SubscribeLocalEvent(OnTelepadFulfillCargoOrder); + _linker.EnsureSinkPorts(ent.Owner, ent.Comp.ReceiverPort); } - private void OnTelepadFulfillCargoOrder(ref FulfillCargoOrderEvent args) + [SubscribeLocalEvent] + private void OnTelepadPowerChange(Entity ent, ref PowerChangedEvent args) { - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var tele, out var xform)) - { - if (tele.CurrentState != CargoTelepadState.Idle) - continue; - - if (!this.IsPowered(uid, EntityManager)) - continue; - - if (_station.GetOwningStation(uid, xform) != args.Station) - continue; - - if (!IsLinkedToConsole(uid, GetEntity(args.Order.ApprovingConsole))) - continue; - - tele.CurrentOrders.Add(args.Order); - - tele.Accumulator = tele.Delay; - args.Handled = true; - args.FulfillmentEntity = uid; - return; - } + SetEnabled(ent); } - private bool IsLinkedToConsole( - EntityUid uid, - EntityUid? approvingConsole - ) + [SubscribeLocalEvent] + private void OnTelepadAnchorChange(Entity ent, ref AnchorStateChangedEvent args) { - if (approvingConsole is null) - return false; - - if (!TryComp(uid, out var sinkComponent)) - return false; - - return sinkComponent.LinkedSources.Any(ent => ent == approvingConsole.Value); - } - - private void UpdateTelepad(float frameTime) - { - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var comp, out var xform)) - { - // Don't EntityQuery for it as it's not required. - TryComp(uid, out var appearance); - - if (comp.CurrentState == CargoTelepadState.Unpowered) - { - comp.Accumulator = comp.Delay; - continue; - } - - comp.Accumulator -= frameTime; - - // Uhh listen teleporting takes time and I just want the 1 float. - if (comp.Accumulator > 0f) - { - comp.CurrentState = CargoTelepadState.Idle; - _appearance.SetData(uid, CargoTelepadVisuals.State, CargoTelepadState.Idle, appearance); - continue; - } - - if (comp.CurrentOrders.Count == 0) - { - comp.Accumulator += comp.Delay; - continue; - } - - var currentOrder = comp.CurrentOrders.First(); - if (currentOrder.NumDispatched >= currentOrder.OrderQuantity) - { - comp.CurrentOrders.Remove(currentOrder); - } - else if (FulfillOrder(currentOrder, currentOrder.Account, xform.Coordinates, comp.PrinterOutput)) - { - currentOrder.NumDispatched++; - if (currentOrder.NumDispatched >= currentOrder.OrderQuantity) - comp.CurrentOrders.Remove(currentOrder); - - var teleportSound = comp.TeleportSound; - var audioParams = teleportSound?.Params ?? AudioParams.Default; - audioParams = audioParams.AddVolume(-8f); - _audio.PlayPvs(_audio.ResolveSound(comp.TeleportSound), uid, audioParams); - - if (_station.GetOwningStation(uid) is { } station) - UpdateOrders(station); - - comp.CurrentState = CargoTelepadState.Teleporting; - _appearance.SetData(uid, CargoTelepadVisuals.State, CargoTelepadState.Teleporting, appearance); - } - - comp.Accumulator += comp.Delay; - } - } - - private void OnInit(EntityUid uid, CargoTelepadComponent telepad, ComponentInit args) - { - _linker.EnsureSinkPorts(uid, telepad.ReceiverPort); + SetEnabled(ent); } + [SubscribeLocalEvent] private void OnShutdown(Entity ent, ref ComponentShutdown args) { - if (ent.Comp.CurrentOrders.Count == 0) - return; - - if (_station.GetStations().Count == 0) + if (ent.Comp.CurrentOrders.Count == 0 + || _station.GetStations().Count == 0) return; if (_station.GetOwningStation(ent) is not { } station) @@ -140,21 +43,94 @@ public sealed partial class CargoSystem station = _random.Pick(_station.GetStations().Where(x => _orderQuery.HasComp(x.Owner)).ToList()); } - if (!_orderQuery.TryComp(station, out var db) || - !TryComp(station, out var data)) + if (!_orderQuery.TryComp(station, out var orderDatabase) + || !TryComp(station, out var data)) return; foreach (var order in ent.Comp.CurrentOrders) { - TryFulfillOrder((station, data), order.Account, order, db); + TryFulfillOrder((station, data), order.Account, order, orderDatabase); } } - private void SetEnabled(EntityUid uid, CargoTelepadComponent component, ApcPowerReceiverComponent? receiver = null, - TransformComponent? xform = null) + [SubscribeLocalEvent] + private void OnTelepadFulfillCargoOrder(ref FulfillCargoOrderEvent args) + { + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var telepad, out var xform)) + { + if (telepad.CurrentState != CargoTelepadState.Idle + || !this.IsPowered(uid, EntityManager) + || _station.GetOwningStation(uid, xform) != args.Station + || !IsLinkedToConsole(uid, GetEntity(args.Order.ApprovingConsole))) + continue; + + telepad.NextTeleport = Timing.CurTime + telepad.Delay; + telepad.CurrentOrders.Add(args.Order); + args.Handled = true; + args.FulfillmentEntity = uid; + return; + } + } + + private void UpdateTelepad() + { + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var telepad, out var xform)) + { + if (telepad.CurrentState == CargoTelepadState.Unpowered) + continue; + + if (Timing.CurTime < telepad.NextTeleport) + { + telepad.CurrentState = CargoTelepadState.Idle; + _appearance.SetData(uid, CargoTelepadVisuals.State, CargoTelepadState.Idle); + continue; + } + + telepad.NextTeleport = Timing.CurTime + telepad.Delay; + + if (telepad.CurrentOrders.Count == 0) + continue; + + var currentOrder = telepad.CurrentOrders.First(); + if (currentOrder.NumDispatched >= currentOrder.OrderQuantity) + { + telepad.CurrentOrders.Remove(currentOrder); + } + else if (FulfillOrder(currentOrder, currentOrder.Account, xform.Coordinates, telepad.PrinterOutput)) + { + currentOrder.NumDispatched++; + if (currentOrder.NumDispatched >= currentOrder.OrderQuantity) + telepad.CurrentOrders.Remove(currentOrder); + + var teleportSound = telepad.TeleportSound; + var audioParams = teleportSound.Params; + audioParams = audioParams.AddVolume(-8f); + _audio.PlayPvs(_audio.ResolveSound(telepad.TeleportSound), uid, audioParams); + + if (_station.GetOwningStation(uid) is { } station) + UpdateOrders(station); + + telepad.CurrentState = CargoTelepadState.Teleporting; + _appearance.SetData(uid, CargoTelepadVisuals.State, CargoTelepadState.Teleporting); + } + } + } + + private bool IsLinkedToConsole(EntityUid uid, EntityUid? approvingConsole) + { + if (approvingConsole is null + || !TryComp(uid, out var sinkComponent)) + return false; + + return sinkComponent.LinkedSources.Any(ent => ent == approvingConsole.Value); + } + + private void SetEnabled(Entity ent, ApcPowerReceiverComponent? receiver = null, TransformComponent? xform = null) { // False due to AllCompsOneEntity test where they may not have the powerreceiver. - if (!Resolve(uid, ref receiver, ref xform, false)) + if (!Resolve(ent.Owner, ref receiver, ref xform, false)) return; var disabled = !receiver.Powered || !xform.Anchored; @@ -163,20 +139,15 @@ public sealed partial class CargoSystem // Only change to Idle if off // don't overwrite teleporting state if (disabled) - component.CurrentState = CargoTelepadState.Unpowered; - else if (component.CurrentState == CargoTelepadState.Unpowered) - component.CurrentState = CargoTelepadState.Idle; + { + ent.Comp.CurrentState = CargoTelepadState.Unpowered; + } + else if (ent.Comp.CurrentState == CargoTelepadState.Unpowered) + { + ent.Comp.NextTeleport = Timing.CurTime + ent.Comp.Delay; + ent.Comp.CurrentState = CargoTelepadState.Idle; + } - _appearance.SetData(uid, CargoTelepadVisuals.State, component.CurrentState); - } - - private void OnTelepadPowerChange(EntityUid uid, CargoTelepadComponent component, ref PowerChangedEvent args) - { - SetEnabled(uid, component); - } - - private void OnTelepadAnchorChange(EntityUid uid, CargoTelepadComponent component, ref AnchorStateChangedEvent args) - { - SetEnabled(uid, component); + _appearance.SetData(ent.Owner, CargoTelepadVisuals.State, ent.Comp.CurrentState); } } diff --git a/Content.Server/Cargo/Systems/CargoSystem.cs b/Content.Server/Cargo/Systems/CargoSystem.cs index 81aa60905e..0aa4dabbf8 100644 --- a/Content.Server/Cargo/Systems/CargoSystem.cs +++ b/Content.Server/Cargo/Systems/CargoSystem.cs @@ -62,7 +62,6 @@ public sealed partial class CargoSystem : SharedCargoSystem { base.Initialize(); InitializeShuttle(); - InitializeTelepad(); InitializeBounty(); InitializeFunds(); } @@ -71,7 +70,7 @@ public sealed partial class CargoSystem : SharedCargoSystem { base.Update(frameTime); UpdateConsole(); - UpdateTelepad(frameTime); + UpdateTelepad(); UpdateBounty(); } } diff --git a/Content.Shared/Cargo/Components/SharedCargoTelepadComponent.cs b/Content.Shared/Cargo/Components/SharedCargoTelepadComponent.cs index 5533a903be..29eb0693c3 100644 --- a/Content.Shared/Cargo/Components/SharedCargoTelepadComponent.cs +++ b/Content.Shared/Cargo/Components/SharedCargoTelepadComponent.cs @@ -2,29 +2,30 @@ using Content.Shared.DeviceLinking; using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Shared.Cargo.Components; /// /// Handles teleporting in requested cargo after the specified delay. /// -[RegisterComponent, NetworkedComponent, Access(typeof(SharedCargoSystem))] +[RegisterComponent, NetworkedComponent, Access(typeof(SharedCargoSystem)), AutoGenerateComponentPause] public sealed partial class CargoTelepadComponent : Component { [DataField] public List CurrentOrders = new(); /// - /// The actual amount of time it takes to teleport from the telepad + /// The delay between each teleport in seconds /// [DataField] - public float Delay = 5f; + public TimeSpan Delay = TimeSpan.FromSeconds(5); /// - /// How much time we've accumulated until next teleport. + /// The next time the teleporter can teleport. /// - [DataField] - public float Accumulator; + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField] + public TimeSpan NextTeleport; [DataField] public CargoTelepadState CurrentState = CargoTelepadState.Unpowered;