using Content.Server.Cargo.Components; using Content.Server.Construction; using Content.Server.Paper; using Content.Server.Power.Components; using Content.Shared.Cargo; using Content.Shared.Cargo.Components; using Content.Shared.DeviceLinking; using Robust.Shared.Audio; using Robust.Shared.Utility; namespace Content.Server.Cargo.Systems; public sealed partial class CargoSystem { private void InitializeTelepad() { SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnRefreshParts); SubscribeLocalEvent(OnUpgradeExamine); SubscribeLocalEvent(OnTelepadPowerChange); // Shouldn't need re-anchored event SubscribeLocalEvent(OnTelepadAnchorChange); } private void UpdateTelepad(float frameTime) { var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var comp)) { // Don't EntityQuery for it as it's not required. TryComp(uid, out var appearance); if (comp.CurrentState == CargoTelepadState.Unpowered) { comp.CurrentState = CargoTelepadState.Idle; _appearance.SetData(uid, CargoTelepadVisuals.State, CargoTelepadState.Idle, appearance); comp.Accumulator = comp.Delay; continue; } if (!TryComp(uid, out var sinkComponent) || sinkComponent.LinkedSources.FirstOrNull() is not { } console || !HasComp(console)) { 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; } var station = _station.GetOwningStation(console); if (!TryComp(station, out var orderDatabase) || orderDatabase.Orders.Count == 0) { comp.Accumulator += comp.Delay; continue; } var xform = Transform(uid); if (FulfillOrder(orderDatabase, xform.Coordinates, comp.PrinterOutput)) { _audio.PlayPvs(_audio.GetSound(comp.TeleportSound), uid, AudioParams.Default.WithVolume(-8f)); UpdateOrders(station!.Value, orderDatabase); 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); } private void OnRefreshParts(EntityUid uid, CargoTelepadComponent component, RefreshPartsEvent args) { var rating = args.PartRatings[component.MachinePartTeleportDelay] - 1; component.Delay = component.BaseDelay * MathF.Pow(component.PartRatingTeleportDelay, rating); } private void OnUpgradeExamine(EntityUid uid, CargoTelepadComponent component, UpgradeExamineEvent args) { args.AddPercentageUpgrade("cargo-telepad-delay-upgrade", component.Delay / component.BaseDelay); } private void SetEnabled(EntityUid uid, CargoTelepadComponent component, 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)) return; var disabled = !receiver.Powered || !xform.Anchored; // Setting idle state should be handled by Update(); if (disabled) return; TryComp(uid, out var appearance); component.CurrentState = CargoTelepadState.Unpowered; _appearance.SetData(uid, CargoTelepadVisuals.State, CargoTelepadState.Unpowered, appearance); } 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); } }