]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Allow cargo request computers to send orders to the primary account (#37943)
authorpathetic meowmeow <uhhadd@gmail.com>
Mon, 9 Jun 2025 15:11:19 +0000 (11:11 -0400)
committerGitHub <noreply@github.com>
Mon, 9 Jun 2025 15:11:19 +0000 (11:11 -0400)
Content.Client/Cargo/UI/CargoConsoleMenu.xaml.cs
Content.Client/Cargo/UI/CargoOrderRow.xaml.cs
Content.Server/Cargo/Systems/CargoSystem.Orders.cs
Content.Server/StationEvents/Events/CargoGiftsRule.cs
Content.Shared/Cargo/Components/CargoOrderConsoleComponent.cs
Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml

index dfc61c0527183e624217d68397fe5045af05610e..03246cfdfe55db1c59f7810e451de1121adc319e 100644 (file)
@@ -203,6 +203,9 @@ namespace Content.Client.Cargo.UI
         /// </summary>
         public void PopulateOrders(IEnumerable<CargoOrderData> orders)
         {
+            if (!_orderConsoleQuery.TryComp(_owner, out var orderConsole))
+                return;
+
             Requests.DisposeAllChildren();
 
             foreach (var order in orders)
@@ -237,6 +240,7 @@ namespace Content.Client.Cargo.UI
                 row.Cancel.OnPressed += (args) => { OnOrderCanceled?.Invoke(args); };
 
                 // TODO: Disable based on access.
+                row.SetApproveVisible(orderConsole.Mode != CargoOrderConsoleMode.SendToPrimary);
                 row.Approve.OnPressed += (args) => { OnOrderApproved?.Invoke(args); };
                 Requests.AddChild(row);
             }
@@ -290,8 +294,8 @@ namespace Content.Client.Cargo.UI
                                            TransferSpinBox.Value > bankAccount.Accounts[orderConsole.Account] * orderConsole.TransferLimit ||
                                            _timing.CurTime < orderConsole.NextAccountActionTime;
 
-            OrdersSpacer.Visible = !orderConsole.SlipPrinter;
-            Orders.Visible = !orderConsole.SlipPrinter;
+            OrdersSpacer.Visible = orderConsole.Mode != CargoOrderConsoleMode.PrintSlip;
+            Orders.Visible = orderConsole.Mode != CargoOrderConsoleMode.PrintSlip;
         }
     }
 }
index 77abcf4069c5d12a93f5a30bac7c2057fed1e51e..d2a23b5a2e315083e906feb2d0e7b655035b9826 100644 (file)
@@ -14,5 +14,15 @@ namespace Content.Client.Cargo.UI
         {
             RobustXamlLoader.Load(this);
         }
+
+        public void SetApproveVisible(bool visible)
+        {
+            Approve.Visible = visible;
+
+            if (visible)
+                Cancel.AddStyleClass("OpenLeft");
+            else
+                Cancel.RemoveStyleClass("OpenLeft");
+        }
     }
 }
index e6248f177296c54696460f12e46d1ae4018106eb..aecba50dff9a4fc21ca05c6637906e00d122716b 100644 (file)
@@ -100,7 +100,7 @@ namespace Content.Server.Cargo.Systems
             {
                 OnInteractUsingCash(uid, component, ref args);
             }
-            else if (TryComp<CargoSlipComponent>(args.Used, out var slip) && !component.SlipPrinter)
+            else if (TryComp<CargoSlipComponent>(args.Used, out var slip) && component.Mode == CargoOrderConsoleMode.DirectOrder)
             {
                 OnInteractUsingSlip((uid, component), ref args, slip);
             }
@@ -144,7 +144,7 @@ namespace Content.Server.Cargo.Systems
             if (args.Actor is not { Valid: true } player)
                 return;
 
-            if (component.SlipPrinter)
+            if (component.Mode != CargoOrderConsoleMode.DirectOrder)
                 return;
 
             if (!_accessReaderSystem.IsAllowed(player, uid))
@@ -181,7 +181,7 @@ namespace Content.Server.Cargo.Systems
                 return;
             }
 
-            var amount = GetOutstandingOrderCount(orderDatabase, order.Account);
+            var amount = GetOutstandingOrderCount((station.Value, orderDatabase), order.Account);
             var capacity = orderDatabase.Capacity;
 
             // Too many orders, avoid them getting spammed in the UI.
@@ -312,7 +312,7 @@ namespace Content.Server.Cargo.Systems
         {
             var station = _station.GetOwningStation(uid);
 
-            if (component.SlipPrinter)
+            if (component.Mode != CargoOrderConsoleMode.DirectOrder)
                 return;
 
             if (!TryGetOrderDatabase(station, out var orderDatabase))
@@ -367,6 +367,9 @@ namespace Content.Server.Cargo.Systems
             if (!TryGetOrderDatabase(stationUid, out var orderDatabase))
                 return;
 
+            if (!TryComp<StationBankAccountComponent>(stationUid, out var bank))
+                return;
+
             if (!_protoMan.TryIndex<CargoProductPrototype>(args.CargoProductId, out var product))
             {
                 Log.Error($"Tried to add invalid cargo product {args.CargoProductId} as order!");
@@ -376,15 +379,17 @@ namespace Content.Server.Cargo.Systems
             if (!GetAvailableProducts((uid, component)).Contains(args.CargoProductId))
                 return;
 
-            if (component.SlipPrinter)
+            if (component.Mode == CargoOrderConsoleMode.PrintSlip)
             {
                 OnAddOrderMessageSlipPrinter(uid, component, args, product);
                 return;
             }
 
+            var targetAccount = component.Mode == CargoOrderConsoleMode.SendToPrimary ? bank.PrimaryAccount : component.Account;
+
             var data = GetOrderData(args, product, GenerateOrderId(orderDatabase), component.Account);
 
-            if (!TryAddOrder(stationUid.Value, component.Account, data, orderDatabase))
+            if (!TryAddOrder(stationUid.Value, targetAccount, data, orderDatabase))
             {
                 PlayDenySound(uid, component);
                 return;
@@ -419,15 +424,33 @@ namespace Content.Server.Cargo.Systems
                     CargoConsoleUiKey.Orders,
                     new CargoConsoleInterfaceState(
                     MetaData(station.Value).EntityName,
-                    GetOutstandingOrderCount(orderDatabase, console.Account),
+                    GetOutstandingOrderCount((station!.Value, orderDatabase), console.Account),
                     orderDatabase.Capacity,
                     GetNetEntity(station.Value),
-                    orderDatabase.Orders[console.Account],
+                    RelevantOrders((station!.Value, orderDatabase), (consoleUid, console)),
                     GetAvailableProducts((consoleUid, console))
                 ));
             }
         }
 
+        /// <summary>
+        /// Gets orders relevant to this account, i.e. orders on the account directly or orders on behalf of the account in the primary account.
+        /// </summary>
+        private List<CargoOrderData> RelevantOrders(Entity<StationCargoOrderDatabaseComponent> station, Entity<CargoOrderConsoleComponent> console)
+        {
+            if (!TryComp<StationBankAccountComponent>(station, out var bank))
+                return [];
+
+            var ourOrders = station.Comp.Orders[console.Comp.Account];
+
+            if (console.Comp.Account == bank.PrimaryAccount)
+                return ourOrders;
+
+            var otherOrders = station.Comp.Orders[bank.PrimaryAccount].Where(order => order.Account == console.Comp.Account);
+
+            return ourOrders.Concat(otherOrders).ToList();
+        }
+
         private void ConsolePopup(EntityUid actor, string text)
         {
             _popup.PopupCursor(text, actor);
@@ -447,12 +470,27 @@ namespace Content.Server.Cargo.Systems
             return new CargoOrderData(id, cargoProduct.Product, cargoProduct.Name, cargoProduct.Cost, args.Amount, args.Requester, args.Reason, account);
         }
 
-        public static int GetOutstandingOrderCount(StationCargoOrderDatabaseComponent component, ProtoId<CargoAccountPrototype> account)
+        public int GetOutstandingOrderCount(Entity<StationCargoOrderDatabaseComponent> station, ProtoId<CargoAccountPrototype> account)
         {
             var amount = 0;
 
-            foreach (var order in component.Orders[account])
+            if (!TryComp<StationBankAccountComponent>(station, out var bank))
+                return amount;
+
+            foreach (var order in station.Comp.Orders[account])
+            {
+                if (!order.Approved)
+                    continue;
+                amount += order.OrderQuantity - order.NumDispatched;
+            }
+
+            if (account == bank.PrimaryAccount)
+                return amount;
+
+            foreach (var order in station.Comp.Orders[bank.PrimaryAccount])
             {
+                if (order.Account != account)
+                    continue;
                 if (!order.Approved)
                     continue;
                 amount += order.OrderQuantity - order.NumDispatched;
index f8a718a536ccbafa7ca1c45937870a55b1ed6424..91baf2ecad9581852c7ef95ca218437941c602f6 100644 (file)
@@ -53,7 +53,7 @@ public sealed class CargoGiftsRule : StationEventSystem<CargoGiftsRuleComponent>
         }
 
         // Add some presents
-        var outstanding = CargoSystem.GetOutstandingOrderCount(cargoDb, component.Account);
+        var outstanding = _cargoSystem.GetOutstandingOrderCount((station.Value, cargoDb), component.Account);
         while (outstanding < cargoDb.Capacity - component.OrderSpaceToLeave && component.Gifts.Count > 0)
         {
             // I wish there was a nice way to pop this
index e930fbda230963b386ec28d60037881fb7505f7a..1d3aa6fc9e3a47b5e859bebab5935e368c11750e 100644 (file)
@@ -104,10 +104,10 @@ public sealed partial class CargoOrderConsoleComponent : Component
     public static readonly ProtoId<RadioChannelPrototype> BaseAnnouncementChannel = "Supply";
 
     /// <summary>
-    /// If set to true, restricts this console from ordering and has it print slips instead
+    /// The behaviour of the cargo console regarding orders
     /// </summary>
     [DataField]
-    public bool SlipPrinter;
+    public CargoOrderConsoleMode Mode = CargoOrderConsoleMode.DirectOrder;
 
     /// <summary>
     /// The time at which the console will be able to print a slip again.
@@ -146,6 +146,26 @@ public sealed partial class CargoOrderConsoleComponent : Component
     public TimeSpan DenySoundDelay = TimeSpan.FromSeconds(2);
 }
 
+/// <summary>
+/// The behaviour of the cargo order console
+/// </summary>
+[Serializable, NetSerializable]
+public enum CargoOrderConsoleMode : byte
+{
+    /// <summary>
+    /// Place orders directly
+    /// </summary>
+    DirectOrder,
+    /// <summary>
+    /// Print a slip to be inserted into a DirectOrder console
+    /// </summary>
+    PrintSlip,
+    /// <summary>
+    /// Transfers the order to the primary account
+    /// </summary>
+    SendToPrimary,
+}
+
 /// <summary>
 /// Withdraw funds from an account
 /// </summary>
index ca9b5fabba08a213e5ea8dc53c3315dc1384ab54..bc50c4fe3901a52ddcea41838b8cdc5c51697286 100644 (file)
     account: Engineering
     announcementChannel: Engineering
     removeLimitAccess: [ "ChiefEngineer" ]
-    slipPrinter: true
+    mode: SendToPrimary
   - type: ActiveRadio
     channels:
     - Engineering
     account: Medical
     announcementChannel: Medical
     removeLimitAccess: [ "ChiefMedicalOfficer" ]
-    slipPrinter: true
+    mode: SendToPrimary
   - type: ActiveRadio
     channels:
     - Medical
     account: Science
     announcementChannel: Science
     removeLimitAccess: [ "ResearchDirector" ]
-    slipPrinter: true
+    mode: SendToPrimary
   - type: ActiveRadio
     channels:
     - Science
     account: Security
     announcementChannel: Security
     removeLimitAccess: [ "HeadOfSecurity" ]
-    slipPrinter: true
+    mode: SendToPrimary
   - type: ActiveRadio
     channels:
     - Security
     account: Service
     announcementChannel: Service
     removeLimitAccess: [ "HeadOfPersonnel" ]
-    slipPrinter: true
+    mode: SendToPrimary
   - type: ActiveRadio
     channels:
     - Service