]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
fix cargo teleporter (#27255)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Tue, 23 Apr 2024 12:07:12 +0000 (08:07 -0400)
committerGitHub <noreply@github.com>
Tue, 23 Apr 2024 12:07:12 +0000 (22:07 +1000)
* fix cargo teleporter

* don't delete orders

* basado

Content.Server/Cargo/Components/StationCargoOrderDatabaseComponent.cs
Content.Server/Cargo/Systems/CargoSystem.Orders.cs
Content.Server/Cargo/Systems/CargoSystem.Telepad.cs
Content.Server/StationEvents/Events/CargoGiftsRule.cs
Content.Shared/Cargo/CargoOrderData.cs
Content.Shared/Cargo/Components/SharedCargoTelepadComponent.cs
Resources/Prototypes/Entities/Structures/cargo_telepad.yml
Resources/Prototypes/name_identifier_groups.yml

index c30db08bbe5fa73c415a68a0caef938ee9aea852..2e3b2c211573937589d8e4d1fd8b2ae2461de92f 100644 (file)
@@ -1,4 +1,6 @@
+using Content.Server.Station.Components;
 using Content.Shared.Cargo;
+using Content.Shared.Cargo.Components;
 using Content.Shared.Cargo.Prototypes;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -38,3 +40,17 @@ public sealed partial class StationCargoOrderDatabaseComponent : Component
     [DataField]
     public EntProtoId PrinterOutput = "PaperCargoInvoice";
 }
+
+/// <summary>
+/// Event broadcast before a cargo order is fulfilled, allowing alternate systems to fulfill the order.
+/// </summary>
+[ByRefEvent]
+public record struct FulfillCargoOrderEvent(Entity<StationDataComponent> Station, CargoOrderData Order, Entity<CargoOrderConsoleComponent> OrderConsole)
+{
+    public Entity<CargoOrderConsoleComponent> OrderConsole = OrderConsole;
+    public Entity<StationDataComponent> Station = Station;
+    public CargoOrderData Order = Order;
+
+    public EntityUid? FulfillmentEntity;
+    public bool Handled = false;
+}
index 7a81e1a4241f1399cb5a990c2fee22dbaef06584..13a1d3d565bb1e711e3bc3d6e10067d7069f3ae5 100644 (file)
@@ -170,13 +170,20 @@ namespace Content.Server.Cargo.Systems
                 return;
             }
 
-            var tradeDestination = TryFulfillOrder(stationData, order, orderDatabase);
+            var ev = new FulfillCargoOrderEvent((station.Value, stationData), order, (uid, component));
+            RaiseLocalEvent(ref ev);
+            ev.FulfillmentEntity ??= station.Value;
 
-            if (tradeDestination == null)
+            if (!ev.Handled)
             {
-                ConsolePopup(args.Session, Loc.GetString("cargo-console-unfulfilled"));
-                PlayDenySound(uid, component);
-                return;
+                ev.FulfillmentEntity = TryFulfillOrder((station.Value, stationData), order, orderDatabase);
+
+                if (ev.FulfillmentEntity == null)
+                {
+                    ConsolePopup(args.Session, Loc.GetString("cargo-console-unfulfilled"));
+                    PlayDenySound(uid, component);
+                    return;
+                }
             }
 
             _idCardSystem.TryFindIdCard(player, out var idCard);
@@ -186,14 +193,14 @@ namespace Content.Server.Cargo.Systems
 
             var approverName = idCard.Comp?.FullName ?? Loc.GetString("access-reader-unknown-id");
             var approverJob = idCard.Comp?.JobTitle ?? Loc.GetString("access-reader-unknown-id");
-            var message = Loc.GetString("cargo-console-unlock-approved-order-broadcast", 
+            var message = Loc.GetString("cargo-console-unlock-approved-order-broadcast",
                 ("productName", Loc.GetString(order.ProductName)),
                 ("orderAmount", order.OrderQuantity),
                 ("approverName", approverName),
                 ("approverJob", approverJob),
                 ("cost", cost));
             _radio.SendRadioMessage(uid, message, component.AnnouncementChannel, uid, escapeMarkup: false);
-            ConsolePopup(args.Session, Loc.GetString("cargo-console-trade-station", ("destination", MetaData(tradeDestination.Value).EntityName)));
+            ConsolePopup(args.Session, Loc.GetString("cargo-console-trade-station", ("destination", MetaData(ev.FulfillmentEntity.Value).EntityName)));
 
             // Log order approval
             _adminLogger.Add(LogType.Action, LogImpact.Low,
@@ -201,10 +208,10 @@ namespace Content.Server.Cargo.Systems
 
             orderDatabase.Orders.Remove(order);
             DeductFunds(bank, cost);
-            UpdateOrders(station.Value, orderDatabase);
+            UpdateOrders(station.Value);
         }
 
-        private EntityUid? TryFulfillOrder(StationDataComponent stationData, CargoOrderData order, StationCargoOrderDatabaseComponent orderDatabase)
+        private EntityUid? TryFulfillOrder(Entity<StationDataComponent> stationData, CargoOrderData order, StationCargoOrderDatabaseComponent orderDatabase)
         {
             // No slots at the trade station
             _listEnts.Clear();
@@ -357,7 +364,7 @@ namespace Content.Server.Cargo.Systems
         /// Updates all of the cargo-related consoles for a particular station.
         /// This should be called whenever orders change.
         /// </summary>
-        private void UpdateOrders(EntityUid dbUid, StationCargoOrderDatabaseComponent _)
+        private void UpdateOrders(EntityUid dbUid)
         {
             // Order added so all consoles need updating.
             var orderQuery = AllEntityQuery<CargoOrderConsoleComponent>();
@@ -392,7 +399,7 @@ namespace Content.Server.Cargo.Systems
             string description,
             string dest,
             StationCargoOrderDatabaseComponent component,
-            StationDataComponent stationData
+            Entity<StationDataComponent> stationData
         )
         {
             DebugTools.Assert(_protoMan.HasIndex<EntityPrototype>(spawnId));
@@ -414,7 +421,7 @@ namespace Content.Server.Cargo.Systems
         private bool TryAddOrder(EntityUid dbUid, CargoOrderData data, StationCargoOrderDatabaseComponent component)
         {
             component.Orders.Add(data);
-            UpdateOrders(dbUid, component);
+            UpdateOrders(dbUid);
             return true;
         }
 
@@ -432,7 +439,7 @@ namespace Content.Server.Cargo.Systems
             {
                 orderDB.Orders.RemoveAt(sequenceIdx);
             }
-            UpdateOrders(dbUid, orderDB);
+            UpdateOrders(dbUid);
         }
 
         public void ClearOrders(StationCargoOrderDatabaseComponent component)
index 42aabf2578ef1a673b893b134383d07e4a20abfb..f83ec1a5123b6e875d673b527445e6d3cee52e21 100644 (file)
@@ -1,9 +1,13 @@
+using System.Linq;
 using Content.Server.Cargo.Components;
 using Content.Server.Power.Components;
+using Content.Server.Power.EntitySystems;
+using Content.Server.Station.Components;
 using Content.Shared.Cargo;
 using Content.Shared.Cargo.Components;
 using Content.Shared.DeviceLinking;
 using Robust.Shared.Audio;
+using Robust.Shared.Random;
 using Robust.Shared.Utility;
 
 namespace Content.Server.Cargo.Systems;
@@ -13,10 +17,44 @@ public sealed partial class CargoSystem
     private void InitializeTelepad()
     {
         SubscribeLocalEvent<CargoTelepadComponent, ComponentInit>(OnInit);
+        SubscribeLocalEvent<CargoTelepadComponent, ComponentShutdown>(OnShutdown);
         SubscribeLocalEvent<CargoTelepadComponent, PowerChangedEvent>(OnTelepadPowerChange);
         // Shouldn't need re-anchored event
         SubscribeLocalEvent<CargoTelepadComponent, AnchorStateChangedEvent>(OnTelepadAnchorChange);
+        SubscribeLocalEvent<FulfillCargoOrderEvent>(OnTelepadFulfillCargoOrder);
     }
+
+    private void OnTelepadFulfillCargoOrder(ref FulfillCargoOrderEvent args)
+    {
+        var query = EntityQueryEnumerator<CargoTelepadComponent, TransformComponent>();
+        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;
+
+            // todo cannot be fucking asked to figure out device linking rn but this shouldn't just default to the first port.
+            if (!TryComp<DeviceLinkSinkComponent>(uid, out var sinkComponent) ||
+                sinkComponent.LinkedSources.FirstOrNull() is not { } console ||
+                console != args.OrderConsole.Owner)
+                continue;
+
+            for (var i = 0; i < args.Order.OrderQuantity; i++)
+            {
+                tele.CurrentOrders.Add(args.Order);
+            }
+            tele.Accumulator = tele.Delay;
+            args.Handled = true;
+            args.FulfillmentEntity = uid;
+            return;
+        }
+    }
+
     private void UpdateTelepad(float frameTime)
     {
         var query = EntityQueryEnumerator<CargoTelepadComponent>();
@@ -33,14 +71,6 @@ public sealed partial class CargoSystem
                 continue;
             }
 
-            if (!TryComp<DeviceLinkSinkComponent>(uid, out var sinkComponent) ||
-                sinkComponent.LinkedSources.FirstOrNull() is not { } console ||
-                !HasComp<CargoOrderConsoleComponent>(console))
-            {
-                comp.Accumulator = comp.Delay;
-                continue;
-            }
-
             comp.Accumulator -= frameTime;
 
             // Uhh listen teleporting takes time and I just want the 1 float.
@@ -51,21 +81,22 @@ public sealed partial class CargoSystem
                 continue;
             }
 
-            var station = _station.GetOwningStation(console);
-
-            if (!TryComp<StationCargoOrderDatabaseComponent>(station, out var orderDatabase) ||
-                orderDatabase.Orders.Count == 0)
+            if (comp.CurrentOrders.Count == 0)
             {
                 comp.Accumulator += comp.Delay;
                 continue;
             }
 
             var xform = Transform(uid);
-            if (FulfillNextOrder(orderDatabase, xform.Coordinates, comp.PrinterOutput))
+            var currentOrder = comp.CurrentOrders.First();
+            if (FulfillOrder(currentOrder, xform.Coordinates, comp.PrinterOutput))
             {
                 _audio.PlayPvs(_audio.GetSound(comp.TeleportSound), uid, AudioParams.Default.WithVolume(-8f));
-                UpdateOrders(station.Value, orderDatabase);
 
+                if (_station.GetOwningStation(uid) is { } station)
+                    UpdateOrders(station);
+
+                comp.CurrentOrders.Remove(currentOrder);
                 comp.CurrentState = CargoTelepadState.Teleporting;
                 _appearance.SetData(uid, CargoTelepadVisuals.State, CargoTelepadState.Teleporting, appearance);
             }
@@ -79,6 +110,29 @@ public sealed partial class CargoSystem
         _linker.EnsureSinkPorts(uid, telepad.ReceiverPort);
     }
 
+    private void OnShutdown(Entity<CargoTelepadComponent> ent, ref ComponentShutdown args)
+    {
+        if (ent.Comp.CurrentOrders.Count == 0)
+            return;
+
+        if (_station.GetStations().Count == 0)
+            return;
+
+        if (_station.GetOwningStation(ent) is not { } station)
+        {
+            station = _random.Pick(_station.GetStations().Where(HasComp<StationCargoOrderDatabaseComponent>).ToList());
+        }
+
+        if (!TryComp<StationCargoOrderDatabaseComponent>(station, out var db) ||
+            !TryComp<StationDataComponent>(station, out var data))
+            return;
+
+        foreach (var order in ent.Comp.CurrentOrders)
+        {
+            TryFulfillOrder((station, data), order, db);
+        }
+    }
+
     private void SetEnabled(EntityUid uid, CargoTelepadComponent component, ApcPowerReceiverComponent? receiver = null,
         TransformComponent? xform = null)
     {
index 194786fca7a254d5fff9335e742de012e61e8280..0c8c9b6dc5598f2a7b40a6a215989386b2b60cfd 100644 (file)
@@ -69,7 +69,7 @@ public sealed class CargoGiftsRule : StationEventSystem<CargoGiftsRuleComponent>
                     Loc.GetString(component.Description),
                     Loc.GetString(component.Dest),
                     cargoDb,
-                    stationData!
+                    (station.Value, stationData)
             ))
             {
                 break;
index 831010cedd76409ca069bcef2c278edbdcabb8ca..ce05d92236208de879f973ef6d0536ad60072513 100644 (file)
@@ -1,47 +1,55 @@
 using Robust.Shared.Serialization;
-using Content.Shared.Access.Components;
 using System.Text;
 namespace Content.Shared.Cargo
 {
-    [NetSerializable, Serializable]
-    public sealed class CargoOrderData
+    [DataDefinition, NetSerializable, Serializable]
+    public sealed partial class CargoOrderData
     {
         /// <summary>
         /// Price when the order was added.
         /// </summary>
+        [DataField]
         public int Price;
 
         /// <summary>
         /// A unique (arbitrary) ID which identifies this order.
         /// </summary>
-        public readonly int OrderId;
+        [DataField]
+        public int OrderId { get; private set; }
 
         /// <summary>
         /// Prototype Id for the item to be created
         /// </summary>
-        public readonly string ProductId;
+        [DataField]
+        public string ProductId { get; private set; }
 
         /// <summary>
         /// Prototype Name
         /// </summary>
-        public readonly string ProductName;
+        [DataField]
+        public string ProductName { get; private set; }
 
         /// <summary>
         /// The number of items in the order. Not readonly, as it might change
         /// due to caps on the amount of orders that can be placed.
         /// </summary>
+        [DataField]
         public int OrderQuantity;
 
         /// <summary>
         /// How many instances of this order that we've already dispatched
         /// </summary>
+        [DataField]
         public int NumDispatched = 0;
 
-        public readonly string Requester;
+        [DataField]
+        public string Requester { get; private set; }
         // public String RequesterRank; // TODO Figure out how to get Character ID card data
         // public int RequesterId;
-        public readonly string Reason;
+        [DataField]
+        public string Reason { get; private set; }
         public  bool Approved => Approver is not null;
+        [DataField]
         public string? Approver;
 
         public CargoOrderData(int orderId, string productId, string productName, int price, int amount, string requester, string reason)
index 911ea41cca5bddbbf2e53087553944714f3d0031..5bc393476831964d3a22d121808df43bcc4b263c 100644 (file)
@@ -12,11 +12,14 @@ namespace Content.Shared.Cargo.Components;
 [RegisterComponent, NetworkedComponent, Access(typeof(SharedCargoSystem))]
 public sealed partial class CargoTelepadComponent : Component
 {
+    [DataField]
+    public List<CargoOrderData> CurrentOrders = new();
+
     /// <summary>
     /// The actual amount of time it takes to teleport from the telepad
     /// </summary>
     [DataField("delay"), ViewVariables(VVAccess.ReadWrite)]
-    public float Delay = 10f;
+    public float Delay = 5f;
 
     /// <summary>
     /// How much time we've accumulated until next teleport.
index d395235a533117d04c918ce22bc2dc8ff6d8f866..9dc9f77cffc57c1a32cb89491a3cd912cf5158f0 100644 (file)
@@ -47,3 +47,5 @@
     board: CargoTelepadMachineCircuitboard
   - type: Appearance
   - type: CollideOnAnchor
+  - type: NameIdentifier
+    group: CargoTelepads
index 82c2f3bce9a4b69f6b9f71d619db4b5098c9430d..4823e31f55d059029f54fd1583c1ad73b60b541a 100644 (file)
@@ -37,3 +37,9 @@
   id: Bounty
   minValue: 0
   maxValue: 999
+
+- type: nameIdentifierGroup
+  id: CargoTelepads
+  prefix: TELE
+  minValue: 0
+  maxValue: 999