Allow cargo request computers to send orders to the primary account (#37943)

This commit is contained in:
pathetic meowmeow
2025-06-09 11:11:19 -04:00
committed by GitHub
parent b1ab5bd059
commit 3d40bebbef
6 changed files with 92 additions and 20 deletions

View 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;
}
}
}

View 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");
}
}
}

View 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,17 +470,32 @@ 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;
}
return amount;
}

View 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

View 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>

View File

@@ -931,7 +931,7 @@
account: Engineering
announcementChannel: Engineering
removeLimitAccess: [ "ChiefEngineer" ]
slipPrinter: true
mode: SendToPrimary
- type: ActiveRadio
channels:
- Engineering
@@ -964,7 +964,7 @@
account: Medical
announcementChannel: Medical
removeLimitAccess: [ "ChiefMedicalOfficer" ]
slipPrinter: true
mode: SendToPrimary
- type: ActiveRadio
channels:
- Medical
@@ -997,7 +997,7 @@
account: Science
announcementChannel: Science
removeLimitAccess: [ "ResearchDirector" ]
slipPrinter: true
mode: SendToPrimary
- type: ActiveRadio
channels:
- Science
@@ -1030,7 +1030,7 @@
account: Security
announcementChannel: Security
removeLimitAccess: [ "HeadOfSecurity" ]
slipPrinter: true
mode: SendToPrimary
- type: ActiveRadio
channels:
- Security
@@ -1063,7 +1063,7 @@
account: Service
announcementChannel: Service
removeLimitAccess: [ "HeadOfPersonnel" ]
slipPrinter: true
mode: SendToPrimary
- type: ActiveRadio
channels:
- Service