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;
|
||||||
|
using Content.Shared.Cargo.Components;
|
||||||
using Content.Shared.Cargo.Prototypes;
|
using Content.Shared.Cargo.Prototypes;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
@@ -38,3 +40,17 @@ public sealed partial class StationCargoOrderDatabaseComponent : Component
|
|||||||
[DataField]
|
[DataField]
|
||||||
public EntProtoId PrinterOutput = "PaperCargoInvoice";
|
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,14 +170,21 @@ namespace Content.Server.Cargo.Systems
|
|||||||
return;
|
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)
|
||||||
|
{
|
||||||
|
ev.FulfillmentEntity = TryFulfillOrder((station.Value, stationData), order, orderDatabase);
|
||||||
|
|
||||||
|
if (ev.FulfillmentEntity == null)
|
||||||
{
|
{
|
||||||
ConsolePopup(args.Session, Loc.GetString("cargo-console-unfulfilled"));
|
ConsolePopup(args.Session, Loc.GetString("cargo-console-unfulfilled"));
|
||||||
PlayDenySound(uid, component);
|
PlayDenySound(uid, component);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_idCardSystem.TryFindIdCard(player, out var idCard);
|
_idCardSystem.TryFindIdCard(player, out var idCard);
|
||||||
// ReSharper disable once ConditionalAccessQualifierIsNonNullableAccordingToAPIContract
|
// ReSharper disable once ConditionalAccessQualifierIsNonNullableAccordingToAPIContract
|
||||||
@@ -193,7 +200,7 @@ namespace Content.Server.Cargo.Systems
|
|||||||
("approverJob", approverJob),
|
("approverJob", approverJob),
|
||||||
("cost", cost));
|
("cost", cost));
|
||||||
_radio.SendRadioMessage(uid, message, component.AnnouncementChannel, uid, escapeMarkup: false);
|
_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
|
// Log order approval
|
||||||
_adminLogger.Add(LogType.Action, LogImpact.Low,
|
_adminLogger.Add(LogType.Action, LogImpact.Low,
|
||||||
@@ -201,10 +208,10 @@ namespace Content.Server.Cargo.Systems
|
|||||||
|
|
||||||
orderDatabase.Orders.Remove(order);
|
orderDatabase.Orders.Remove(order);
|
||||||
DeductFunds(bank, cost);
|
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
|
// No slots at the trade station
|
||||||
_listEnts.Clear();
|
_listEnts.Clear();
|
||||||
@@ -357,7 +364,7 @@ namespace Content.Server.Cargo.Systems
|
|||||||
/// Updates all of the cargo-related consoles for a particular station.
|
/// Updates all of the cargo-related consoles for a particular station.
|
||||||
/// This should be called whenever orders change.
|
/// This should be called whenever orders change.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void UpdateOrders(EntityUid dbUid, StationCargoOrderDatabaseComponent _)
|
private void UpdateOrders(EntityUid dbUid)
|
||||||
{
|
{
|
||||||
// Order added so all consoles need updating.
|
// Order added so all consoles need updating.
|
||||||
var orderQuery = AllEntityQuery<CargoOrderConsoleComponent>();
|
var orderQuery = AllEntityQuery<CargoOrderConsoleComponent>();
|
||||||
@@ -392,7 +399,7 @@ namespace Content.Server.Cargo.Systems
|
|||||||
string description,
|
string description,
|
||||||
string dest,
|
string dest,
|
||||||
StationCargoOrderDatabaseComponent component,
|
StationCargoOrderDatabaseComponent component,
|
||||||
StationDataComponent stationData
|
Entity<StationDataComponent> stationData
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
DebugTools.Assert(_protoMan.HasIndex<EntityPrototype>(spawnId));
|
DebugTools.Assert(_protoMan.HasIndex<EntityPrototype>(spawnId));
|
||||||
@@ -414,7 +421,7 @@ namespace Content.Server.Cargo.Systems
|
|||||||
private bool TryAddOrder(EntityUid dbUid, CargoOrderData data, StationCargoOrderDatabaseComponent component)
|
private bool TryAddOrder(EntityUid dbUid, CargoOrderData data, StationCargoOrderDatabaseComponent component)
|
||||||
{
|
{
|
||||||
component.Orders.Add(data);
|
component.Orders.Add(data);
|
||||||
UpdateOrders(dbUid, component);
|
UpdateOrders(dbUid);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,7 +439,7 @@ namespace Content.Server.Cargo.Systems
|
|||||||
{
|
{
|
||||||
orderDB.Orders.RemoveAt(sequenceIdx);
|
orderDB.Orders.RemoveAt(sequenceIdx);
|
||||||
}
|
}
|
||||||
UpdateOrders(dbUid, orderDB);
|
UpdateOrders(dbUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearOrders(StationCargoOrderDatabaseComponent component)
|
public void ClearOrders(StationCargoOrderDatabaseComponent component)
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
|
using System.Linq;
|
||||||
using Content.Server.Cargo.Components;
|
using Content.Server.Cargo.Components;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
|
using Content.Server.Power.EntitySystems;
|
||||||
|
using Content.Server.Station.Components;
|
||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
using Content.Shared.Cargo.Components;
|
using Content.Shared.Cargo.Components;
|
||||||
using Content.Shared.DeviceLinking;
|
using Content.Shared.DeviceLinking;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.Cargo.Systems;
|
namespace Content.Server.Cargo.Systems;
|
||||||
@@ -13,10 +17,44 @@ public sealed partial class CargoSystem
|
|||||||
private void InitializeTelepad()
|
private void InitializeTelepad()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<CargoTelepadComponent, ComponentInit>(OnInit);
|
SubscribeLocalEvent<CargoTelepadComponent, ComponentInit>(OnInit);
|
||||||
|
SubscribeLocalEvent<CargoTelepadComponent, ComponentShutdown>(OnShutdown);
|
||||||
SubscribeLocalEvent<CargoTelepadComponent, PowerChangedEvent>(OnTelepadPowerChange);
|
SubscribeLocalEvent<CargoTelepadComponent, PowerChangedEvent>(OnTelepadPowerChange);
|
||||||
// Shouldn't need re-anchored event
|
// Shouldn't need re-anchored event
|
||||||
SubscribeLocalEvent<CargoTelepadComponent, AnchorStateChangedEvent>(OnTelepadAnchorChange);
|
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)
|
private void UpdateTelepad(float frameTime)
|
||||||
{
|
{
|
||||||
var query = EntityQueryEnumerator<CargoTelepadComponent>();
|
var query = EntityQueryEnumerator<CargoTelepadComponent>();
|
||||||
@@ -33,14 +71,6 @@ public sealed partial class CargoSystem
|
|||||||
continue;
|
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;
|
comp.Accumulator -= frameTime;
|
||||||
|
|
||||||
// Uhh listen teleporting takes time and I just want the 1 float.
|
// Uhh listen teleporting takes time and I just want the 1 float.
|
||||||
@@ -51,21 +81,22 @@ public sealed partial class CargoSystem
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var station = _station.GetOwningStation(console);
|
if (comp.CurrentOrders.Count == 0)
|
||||||
|
|
||||||
if (!TryComp<StationCargoOrderDatabaseComponent>(station, out var orderDatabase) ||
|
|
||||||
orderDatabase.Orders.Count == 0)
|
|
||||||
{
|
{
|
||||||
comp.Accumulator += comp.Delay;
|
comp.Accumulator += comp.Delay;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var xform = Transform(uid);
|
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));
|
_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;
|
comp.CurrentState = CargoTelepadState.Teleporting;
|
||||||
_appearance.SetData(uid, CargoTelepadVisuals.State, CargoTelepadState.Teleporting, appearance);
|
_appearance.SetData(uid, CargoTelepadVisuals.State, CargoTelepadState.Teleporting, appearance);
|
||||||
}
|
}
|
||||||
@@ -79,6 +110,29 @@ public sealed partial class CargoSystem
|
|||||||
_linker.EnsureSinkPorts(uid, telepad.ReceiverPort);
|
_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,
|
private void SetEnabled(EntityUid uid, CargoTelepadComponent component, ApcPowerReceiverComponent? receiver = null,
|
||||||
TransformComponent? xform = null)
|
TransformComponent? xform = null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public sealed class CargoGiftsRule : StationEventSystem<CargoGiftsRuleComponent>
|
|||||||
Loc.GetString(component.Description),
|
Loc.GetString(component.Description),
|
||||||
Loc.GetString(component.Dest),
|
Loc.GetString(component.Dest),
|
||||||
cargoDb,
|
cargoDb,
|
||||||
stationData!
|
(station.Value, stationData)
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,47 +1,55 @@
|
|||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Content.Shared.Access.Components;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
namespace Content.Shared.Cargo
|
namespace Content.Shared.Cargo
|
||||||
{
|
{
|
||||||
[NetSerializable, Serializable]
|
[DataDefinition, NetSerializable, Serializable]
|
||||||
public sealed class CargoOrderData
|
public sealed partial class CargoOrderData
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Price when the order was added.
|
/// Price when the order was added.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
public int Price;
|
public int Price;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A unique (arbitrary) ID which identifies this order.
|
/// A unique (arbitrary) ID which identifies this order.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly int OrderId;
|
[DataField]
|
||||||
|
public int OrderId { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prototype Id for the item to be created
|
/// Prototype Id for the item to be created
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly string ProductId;
|
[DataField]
|
||||||
|
public string ProductId { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prototype Name
|
/// Prototype Name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly string ProductName;
|
[DataField]
|
||||||
|
public string ProductName { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of items in the order. Not readonly, as it might change
|
/// 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.
|
/// due to caps on the amount of orders that can be placed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
public int OrderQuantity;
|
public int OrderQuantity;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How many instances of this order that we've already dispatched
|
/// How many instances of this order that we've already dispatched
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
public int NumDispatched = 0;
|
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 String RequesterRank; // TODO Figure out how to get Character ID card data
|
||||||
// public int RequesterId;
|
// public int RequesterId;
|
||||||
public readonly string Reason;
|
[DataField]
|
||||||
|
public string Reason { get; private set; }
|
||||||
public bool Approved => Approver is not null;
|
public bool Approved => Approver is not null;
|
||||||
|
[DataField]
|
||||||
public string? Approver;
|
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)
|
||||||
|
|||||||
@@ -12,11 +12,14 @@ namespace Content.Shared.Cargo.Components;
|
|||||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedCargoSystem))]
|
[RegisterComponent, NetworkedComponent, Access(typeof(SharedCargoSystem))]
|
||||||
public sealed partial class CargoTelepadComponent : Component
|
public sealed partial class CargoTelepadComponent : Component
|
||||||
{
|
{
|
||||||
|
[DataField]
|
||||||
|
public List<CargoOrderData> CurrentOrders = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The actual amount of time it takes to teleport from the telepad
|
/// The actual amount of time it takes to teleport from the telepad
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("delay"), ViewVariables(VVAccess.ReadWrite)]
|
[DataField("delay"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
public float Delay = 10f;
|
public float Delay = 5f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How much time we've accumulated until next teleport.
|
/// How much time we've accumulated until next teleport.
|
||||||
|
|||||||
@@ -47,3 +47,5 @@
|
|||||||
board: CargoTelepadMachineCircuitboard
|
board: CargoTelepadMachineCircuitboard
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
- type: CollideOnAnchor
|
- type: CollideOnAnchor
|
||||||
|
- type: NameIdentifier
|
||||||
|
group: CargoTelepads
|
||||||
|
|||||||
@@ -37,3 +37,9 @@
|
|||||||
id: Bounty
|
id: Bounty
|
||||||
minValue: 0
|
minValue: 0
|
||||||
maxValue: 999
|
maxValue: 999
|
||||||
|
|
||||||
|
- type: nameIdentifierGroup
|
||||||
|
id: CargoTelepads
|
||||||
|
prefix: TELE
|
||||||
|
minValue: 0
|
||||||
|
maxValue: 999
|
||||||
|
|||||||
Reference in New Issue
Block a user