fix cargo teleporter (#27255)
* fix cargo teleporter * don't delete orders * basado
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -193,7 +200,7 @@ namespace Content.Server.Cargo.Systems
|
||||
("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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -69,7 +69,7 @@ public sealed class CargoGiftsRule : StationEventSystem<CargoGiftsRuleComponent>
|
||||
Loc.GetString(component.Description),
|
||||
Loc.GetString(component.Dest),
|
||||
cargoDb,
|
||||
stationData!
|
||||
(station.Value, stationData)
|
||||
))
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -47,3 +47,5 @@
|
||||
board: CargoTelepadMachineCircuitboard
|
||||
- type: Appearance
|
||||
- type: CollideOnAnchor
|
||||
- type: NameIdentifier
|
||||
group: CargoTelepads
|
||||
|
||||
@@ -37,3 +37,9 @@
|
||||
id: Bounty
|
||||
minValue: 0
|
||||
maxValue: 999
|
||||
|
||||
- type: nameIdentifierGroup
|
||||
id: CargoTelepads
|
||||
prefix: TELE
|
||||
minValue: 0
|
||||
maxValue: 999
|
||||
|
||||
Reference in New Issue
Block a user