Departmental Economy (#36445)

* Cargo Accounts, Request Consoles, and lock boxes

* Funding Allocation Computer

* final changes

* test fix

* remove dumb code

* ScarKy0 review

* first cour

* second cour

* Update machines.yml

* review

---------

Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>
Co-authored-by: Milon <milonpl.git@proton.me>
This commit is contained in:
Nemanja
2025-04-13 09:22:36 -04:00
committed by GitHub
parent 5f78b72763
commit 12b75beeab
62 changed files with 2106 additions and 331 deletions

View File

@@ -1,13 +1,13 @@
using System.Linq;
using Content.Server.Cargo.Components;
using Content.Shared.Stacks;
using Content.Shared.Cargo;
using Content.Shared.Cargo.BUI;
using Content.Shared.Cargo.Components;
using Content.Shared.Cargo.Events;
using Content.Shared.GameTicking;
using Robust.Shared.Map;
using Robust.Shared.Random;
using Content.Shared.Cargo.Prototypes;
using JetBrains.Annotations;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
namespace Content.Server.Cargo.Systems;
@@ -28,12 +28,11 @@ public sealed partial class CargoSystem
SubscribeLocalEvent<CargoPalletConsoleComponent, CargoPalletSellMessage>(OnPalletSale);
SubscribeLocalEvent<CargoPalletConsoleComponent, CargoPalletAppraiseMessage>(OnPalletAppraise);
SubscribeLocalEvent<CargoPalletConsoleComponent, BoundUIOpenedEvent>(OnPalletUIOpen);
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
}
#region Console
[PublicAPI]
private void UpdateCargoShuttleConsoles(EntityUid shuttleUid, CargoShuttleComponent _)
{
// Update pilot consoles that are already open.
@@ -54,15 +53,18 @@ public sealed partial class CargoSystem
private void UpdatePalletConsoleInterface(EntityUid uid)
{
if (Transform(uid).GridUid is not EntityUid gridUid)
if (Transform(uid).GridUid is not { } gridUid)
{
_uiSystem.SetUiState(uid, CargoPalletConsoleUiKey.Sale,
new CargoPalletConsoleInterfaceState(0, 0, false));
_uiSystem.SetUiState(uid,
CargoPalletConsoleUiKey.Sale,
new CargoPalletConsoleInterfaceState(0, 0, false));
return;
}
GetPalletGoods(gridUid, out var toSell, out var amount);
_uiSystem.SetUiState(uid, CargoPalletConsoleUiKey.Sale,
new CargoPalletConsoleInterfaceState((int) amount, toSell.Count, true));
GetPalletGoods(gridUid, out var toSell, out var goods);
var totalAmount = goods.Sum(t => t.Item3);
_uiSystem.SetUiState(uid,
CargoPalletConsoleUiKey.Sale,
new CargoPalletConsoleInterfaceState((int) totalAmount, toSell.Count, true));
}
private void OnPalletUIOpen(EntityUid uid, CargoPalletConsoleComponent component, BoundUIOpenedEvent args)
@@ -98,11 +100,15 @@ public sealed partial class CargoSystem
var shuttleName = orderDatabase?.Shuttle != null ? MetaData(orderDatabase.Shuttle.Value).EntityName : string.Empty;
if (_uiSystem.HasUi(uid, CargoConsoleUiKey.Shuttle))
_uiSystem.SetUiState(uid, CargoConsoleUiKey.Shuttle, new CargoShuttleConsoleBoundUserInterfaceState(
{
_uiSystem.SetUiState(uid,
CargoConsoleUiKey.Shuttle,
new CargoShuttleConsoleBoundUserInterfaceState(
station != null ? MetaData(station.Value).EntityName : Loc.GetString("cargo-shuttle-console-station-unknown"),
string.IsNullOrEmpty(shuttleName) ? Loc.GetString("cargo-shuttle-console-shuttle-not-found") : shuttleName,
orders
));
}
}
#endregion
@@ -132,9 +138,10 @@ public sealed partial class CargoSystem
return orders;
var spaceRemaining = GetCargoSpace(shuttleUid);
for (var i = 0; i < component.Orders.Count && spaceRemaining > 0; i++)
var allOrders = component.AllOrders.ToList();
for (var i = 0; i < allOrders.Count && spaceRemaining > 0; i++)
{
var order = component.Orders[i];
var order = allOrders[i];
if (order.Approved)
{
var numToShip = order.OrderQuantity - order.NumDispatched;
@@ -142,8 +149,14 @@ public sealed partial class CargoSystem
{
// We won't be able to fit the whole order on, so make one
// which represents the space we do have left:
var reducedOrder = new CargoOrderData(order.OrderId,
order.ProductId, order.ProductName, order.Price, spaceRemaining, order.Requester, order.Reason);
var reducedOrder = new CargoOrderData(
order.OrderId,
order.ProductId,
order.ProductName,
order.Price,
spaceRemaining,
order.Requester,
order.Reason);
orders.Add(reducedOrder);
}
else
@@ -219,16 +232,13 @@ public sealed partial class CargoSystem
#region Station
private bool SellPallets(EntityUid gridUid, out double amount)
private bool SellPallets(EntityUid gridUid, out HashSet<(EntityUid, OverrideSellComponent?, double)> goods)
{
GetPalletGoods(gridUid, out var toSell, out amount);
Log.Debug($"Cargo sold {toSell.Count} entities for {amount}");
GetPalletGoods(gridUid, out var toSell, out goods);
if (toSell.Count == 0)
return false;
var ev = new EntitySoldEvent(toSell);
RaiseLocalEvent(ref ev);
@@ -240,9 +250,9 @@ public sealed partial class CargoSystem
return true;
}
private void GetPalletGoods(EntityUid gridUid, out HashSet<EntityUid> toSell, out double amount)
private void GetPalletGoods(EntityUid gridUid, out HashSet<EntityUid> toSell, out HashSet<(EntityUid, OverrideSellComponent?, double)> goods)
{
amount = 0;
goods = new HashSet<(EntityUid, OverrideSellComponent?, double)>();
toSell = new HashSet<EntityUid>();
foreach (var (palletUid, _, _) in GetCargoPallets(gridUid, BuySellType.Sell))
@@ -250,7 +260,9 @@ public sealed partial class CargoSystem
// Containers should already get the sell price of their children so can skip those.
_setEnts.Clear();
_lookup.GetEntitiesIntersecting(palletUid, _setEnts,
_lookup.GetEntitiesIntersecting(
palletUid,
_setEnts,
LookupFlags.Dynamic | LookupFlags.Sundries);
foreach (var ent in _setEnts)
@@ -273,7 +285,7 @@ public sealed partial class CargoSystem
if (price == 0)
continue;
toSell.Add(ent);
amount += price;
goods.Add((ent, CompOrNull<OverrideSellComponent>(ent), price));
}
}
}
@@ -305,28 +317,49 @@ public sealed partial class CargoSystem
{
var xform = Transform(uid);
if (xform.GridUid is not EntityUid gridUid)
if (_station.GetOwningStation(uid) is not { } station ||
!TryComp<StationBankAccountComponent>(station, out var bankAccount))
{
_uiSystem.SetUiState(uid, CargoPalletConsoleUiKey.Sale,
new CargoPalletConsoleInterfaceState(0, 0, false));
return;
}
if (!SellPallets(gridUid, out var price))
if (xform.GridUid is not { } gridUid)
{
_uiSystem.SetUiState(uid,
CargoPalletConsoleUiKey.Sale,
new CargoPalletConsoleInterfaceState(0, 0, false));
return;
}
if (!SellPallets(gridUid, out var goods))
return;
var stackPrototype = _protoMan.Index<StackPrototype>(component.CashType);
_stack.Spawn((int) price, stackPrototype, xform.Coordinates);
var baseDistribution = CreateAccountDistribution(bankAccount.PrimaryAccount, bankAccount, bankAccount.PrimaryCut);
foreach (var (_, sellComponent, value) in goods)
{
Dictionary<ProtoId<CargoAccountPrototype>, double> distribution;
if (sellComponent != null)
{
distribution = new Dictionary<ProtoId<CargoAccountPrototype>, double>()
{
{ sellComponent.OverrideAccount, bankAccount.PrimaryCut },
{ bankAccount.PrimaryAccount, 1.0 - bankAccount.PrimaryCut },
};
}
else
{
distribution = baseDistribution;
}
UpdateBankAccount((station, bankAccount), (int) Math.Round(value), distribution, false);
}
Dirty(station, bankAccount);
_audio.PlayPvs(ApproveSound, uid);
UpdatePalletConsoleInterface(uid);
}
#endregion
private void OnRoundRestart(RoundRestartCleanupEvent ev)
{
Reset();
}
}
/// <summary>