Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ordering Shuttles #34

Merged
merged 5 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions Content.Client/Cargo/UI/CargoConsoleMenu.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
using static Robust.Client.UserInterface.Controls.BaseButton;

namespace Content.Client.Cargo.UI
Expand Down Expand Up @@ -147,15 +148,31 @@ public void PopulateOrders(IEnumerable<CargoOrderData> orders)
Orders.DisposeAllChildren();
Requests.DisposeAllChildren();

var error = _spriteSystem.Frame0(_protoManager.Index<EntityPrototype>("Error"));

foreach (var order in orders)
{
var product = _protoManager.Index<EntityPrototype>(order.ProductId);
var productName = product.Name;

var productName = String.Empty;
var texture = error;
if (_protoManager.TryIndex<EntityPrototype>(order.ProductId ?? String.Empty, out var product))
{
productName = product.Name;
texture = _spriteSystem.Frame0(product);
}
else
{
if (order.IconOverride != SpriteSpecifier.Invalid)
texture = _spriteSystem.Frame0(order.IconOverride);

if (order.ProductName != null)
productName = order.ProductName;
}

var row = new CargoOrderRow
{
Order = order,
Icon = { Texture = _spriteSystem.Frame0(product) },
Icon = { Texture = texture },
ProductName =
{
Text = Loc.GetString(
Expand Down
2 changes: 1 addition & 1 deletion Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void SetOrders(SpriteSystem sprites, IPrototypeManager protoManager, List

foreach (var order in orders)
{
var product = protoManager.Index<EntityPrototype>(order.ProductId);
var product = protoManager.Index<EntityPrototype>(order.ProductId ?? String.Empty);
var productName = product.Name;

var row = new CargoOrderRow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ await server.WaitAssertion(() =>
// purchaseable entity with a StorageFill.
foreach (var proto in prototypeManager.EnumeratePrototypes<CargoProductPrototype>())
{
if (restockStores.ContainsKey(proto.Product))
if (proto.Product != null && restockStores.ContainsKey(proto.Product))
{
foreach (var entry in restockStores[proto.Product])
restocks.Remove(entry);
Expand Down
126 changes: 117 additions & 9 deletions Content.Server/Cargo/Systems/CargoSystem.Orders.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Cargo.Components;
using Content.Server.Labels.Components;
using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Systems;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Shared.Cargo;
using Content.Shared.Cargo.BUI;
using Content.Shared.Cargo.Components;
Expand All @@ -10,15 +13,27 @@
using Content.Shared.Database;
using Content.Shared.Interaction;
using Content.Shared.Paper;
using Robust.Server.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;

namespace Content.Server.Cargo.Systems
{
sealed class Shuttle
{
public EntityUid ShuttleUid { get; set; }
public TimeSpan ShuttleTime { get; set; }
public EntityUid StationUid { get; set; }
}
public sealed partial class CargoSystem
{
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
[Dependency] private readonly MapLoaderSystem _mapLoader = default!;
[Dependency] private readonly ShuttleSystem _shuttleSystem = default!;
[Dependency] private readonly StationSystem _stationSystem = default!;
[Dependency] private readonly IMapManager _mapManager = default!;

/// <summary>
/// How much time to wait (in seconds) before increasing bank accounts balance.
Expand All @@ -30,6 +45,10 @@ public sealed partial class CargoSystem
/// </summary>
private float _timer;

private List<Shuttle> Shuttles = new();

private const int FTLDelay = 5;

private void InitializeConsole()
{
SubscribeLocalEvent<CargoOrderConsoleComponent, CargoConsoleAddOrderMessage>(OnAddOrderMessage);
Expand Down Expand Up @@ -132,8 +151,10 @@ private void OnApproveOrderMessage(EntityUid uid, CargoOrderConsoleComponent com
return;
}

bool hasProductId = _protoMan.HasIndex<EntityPrototype>(order.ProductId ?? String.Empty);

// Invalid order
if (!_protoMan.HasIndex<EntityPrototype>(order.ProductId))
if (!hasProductId && order.Shuttle == null)
{
ConsolePopup(args.Actor, Loc.GetString("cargo-console-invalid-product"));
PlayDenySound(uid, component);
Expand All @@ -144,7 +165,7 @@ private void OnApproveOrderMessage(EntityUid uid, CargoOrderConsoleComponent com
var capacity = orderDatabase.Capacity;

// Too many orders, avoid them getting spammed in the UI.
if (amount >= capacity)
if (amount >= capacity && hasProductId)
{
ConsolePopup(args.Actor, Loc.GetString("cargo-console-too-many"));
PlayDenySound(uid, component);
Expand Down Expand Up @@ -231,7 +252,7 @@ private void OnApproveOrderMessage(EntityUid uid, CargoOrderConsoleComponent com
{
var coordinates = new EntityCoordinates(trade, pad.Transform.LocalPosition);

if (FulfillOrder(order, coordinates, orderDatabase.PrinterOutput))
if (FulfillOrder(order, coordinates, trade, orderDatabase.PrinterOutput))
{
tradeDestination = trade;
order.NumDispatched++;
Expand Down Expand Up @@ -352,7 +373,11 @@ private void PlayDenySound(EntityUid uid, CargoOrderConsoleComponent component)

private static CargoOrderData GetOrderData(CargoConsoleAddOrderMessage args, CargoProductPrototype cargoProduct, int id)
{
return new CargoOrderData(id, cargoProduct.Product, cargoProduct.Name, cargoProduct.Cost, args.Amount, args.Requester, args.Reason);
SpriteSpecifier icon = SpriteSpecifier.Invalid;
if (cargoProduct.Shuttle != null)
icon = cargoProduct.Icon;

return new CargoOrderData(id, cargoProduct.Product ?? String.Empty, cargoProduct.Name, cargoProduct.Cost, args.Amount, args.Requester, args.Reason, cargoProduct.Shuttle, icon);
}

public static int GetOutstandingOrderCount(StationCargoOrderDatabaseComponent component)
Expand Down Expand Up @@ -483,18 +508,31 @@ private static bool PopFrontOrder(StationCargoOrderDatabaseComponent orderDB, [N
/// <summary>
/// Tries to fulfill the next outstanding order.
/// </summary>
private bool FulfillNextOrder(StationCargoOrderDatabaseComponent orderDB, EntityCoordinates spawn, string? paperProto)
private bool FulfillNextOrder(StationCargoOrderDatabaseComponent orderDB, EntityCoordinates spawn, EntityUid station, string? paperProto)
{
if (!PopFrontOrder(orderDB, out var order))
return false;

return FulfillOrder(order, spawn, paperProto);
return FulfillOrder(order, spawn, station, paperProto);
}

/// <summary>
/// Fulfills the specified cargo order and spawns paper attached to it.
/// </summary>
private bool FulfillOrder(CargoOrderData order, EntityCoordinates spawn, string? paperProto)
private bool FulfillOrder(CargoOrderData order, EntityCoordinates spawn, EntityUid? station, string? paperProto)
{
bool completed = false;

if (order.ProductId != String.Empty)
completed = completed || FulfillProduct(order, spawn, paperProto);

if (order.Shuttle != null && station != null)
completed = completed || FulfillShuttle(order, spawn, station.Value);

return completed;
}

private bool FulfillProduct(CargoOrderData order, EntityCoordinates spawn, string? paperProto)
{
// Create the item itself
var item = Spawn(order.ProductId, spawn);
Expand All @@ -521,13 +559,83 @@ private bool FulfillOrder(CargoOrderData order, EntityCoordinates spawn, string?

// attempt to attach the label to the item
if (TryComp<PaperLabelComponent>(item, out var label))
{
_slots.TryInsert(item, label.LabelSlot, printed, null);
{ _slots.TryInsert(item, label.LabelSlot, printed, null);
}
}

return true;
}

private bool FulfillShuttle(CargoOrderData order, EntityCoordinates coords, EntityUid station)
{
if (order.Shuttle == null)
return false;

var path = order.Shuttle.ToString();

if (path == null)
return false;

_mapSystem.CreateMap(out var pausedMap);
_mapManager.SetMapPaused(pausedMap, true);

if (!_mapLoader.TryLoad(pausedMap, path, out var loadedShuttles)
|| loadedShuttles.Count != 1)
{
_mapManager.DeleteMap(pausedMap);
return false;
}

var delay = _timing.CurTime + TimeSpan.FromSeconds(FTLDelay);

Shuttles.Add(new Shuttle
{
ShuttleUid = loadedShuttles[0],
ShuttleTime = delay,
StationUid = station
});

return true;
}

private void UpdateOrderedShuttles()
{
List<Shuttle> shuttlesToRemove = new();

foreach (var i in Shuttles)
{
if (_timing.CurTime < i.ShuttleTime)
continue;

var shuttle = i.ShuttleUid;
var station = i.StationUid;

MapId shuttleMap;

if (EntityManager.TryGetComponent<TransformComponent>(shuttle, out var shuttlexForm))
{
shuttleMap = shuttlexForm.MapID;
}
else
{
shuttleMap = _transformSystem.GetMapId(_transformSystem.ToCoordinates(shuttle, _transformSystem.GetMapCoordinates(shuttle)));
}

if (!_shuttleSystem.TryFTLProximity(shuttle, station))
{
EntityManager.DeleteEntity(shuttle);
}

_mapManager.DeleteMap(shuttleMap);
shuttlesToRemove.Add(i);
}

foreach (var x in shuttlesToRemove)
{
Shuttles.Remove(x);
}

shuttlesToRemove.Clear();
}

private void DeductFunds(StationBankAccountComponent component, int amount)
Expand Down
2 changes: 1 addition & 1 deletion Content.Server/Cargo/Systems/CargoSystem.Shuttle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private List<CargoOrderData> GetProjectedOrders(
// 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);
order.ProductId ?? String.Empty, order.ProductName, order.Price, spaceRemaining, order.Requester, order.Reason, order.Shuttle, order.IconOverride);
orders.Add(reducedOrder);
}
else
Expand Down
2 changes: 1 addition & 1 deletion Content.Server/Cargo/Systems/CargoSystem.Telepad.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ private void UpdateTelepad(float frameTime)

var xform = Transform(uid);
var currentOrder = comp.CurrentOrders.First();
if (FulfillOrder(currentOrder, xform.Coordinates, comp.PrinterOutput))
if (FulfillOrder(currentOrder, xform.Coordinates, _station.GetOwningStation(uid), comp.PrinterOutput))
{
_audio.PlayPvs(_audio.GetSound(comp.TeleportSound), uid, AudioParams.Default.WithVolume(-8f));

Expand Down
1 change: 1 addition & 0 deletions Content.Server/Cargo/Systems/CargoSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public override void Update(float frameTime)
UpdateConsole(frameTime);
UpdateTelepad(frameTime);
UpdateBounty();
UpdateOrderedShuttles();
}

[PublicAPI]
Expand Down
2 changes: 1 addition & 1 deletion Content.Server/StationEvents/Events/CargoGiftsRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ protected override void ActiveTick(EntityUid uid, CargoGiftsRuleComponent compon

if (!_cargoSystem.AddAndApproveOrder(
station!.Value,
product.Product,
product.Product ?? String.Empty,
product.Name,
product.Cost,
qty,
Expand Down
16 changes: 14 additions & 2 deletions Content.Shared/Cargo/CargoOrderData.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
using System.Text;
namespace Content.Shared.Cargo
{
Expand All @@ -21,7 +22,16 @@ public sealed partial class CargoOrderData
/// Prototype Id for the item to be created
/// </summary>
[DataField]
public string ProductId { get; private set; }
public string? ProductId { get; private set; }

/// <summary>
/// Prototype Id for the item to be created
/// </summary>
[DataField]
public ResPath? Shuttle { get; private set; }

[DataField]
public SpriteSpecifier IconOverride { get; private set; } = SpriteSpecifier.Invalid;

/// <summary>
/// Prototype Name
Expand Down Expand Up @@ -52,7 +62,7 @@ public sealed partial class CargoOrderData
[DataField]
public string? Approver;

public CargoOrderData(int orderId, string productId, string productName, int price, int amount, string requester, string reason)
public CargoOrderData(int orderId, string productId, string productName, int price, int amount, string requester, string reason, ResPath? shuttle = null, SpriteSpecifier? iconOverride = null)
{
OrderId = orderId;
ProductId = productId;
Expand All @@ -61,6 +71,8 @@ public CargoOrderData(int orderId, string productId, string productName, int pri
OrderQuantity = amount;
Requester = requester;
Reason = reason;
Shuttle = shuttle;
IconOverride = iconOverride ?? SpriteSpecifier.Invalid;
}

public void SetApproverData(string? fullName, string? jobTitle)
Expand Down
8 changes: 7 additions & 1 deletion Content.Shared/Cargo/Prototypes/CargoProductPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,13 @@ public string Description
/// The entity prototype ID of the product.
/// </summary>
[DataField]
public EntProtoId Product { get; private set; } = string.Empty;
public EntProtoId? Product;

/// <summary>
/// The path to the shuttle that will get ftl
/// </summary>
[DataField]
public ResPath? Shuttle;

/// <summary>
/// The point cost of the product.
Expand Down
Loading
Loading