fix cargo teleporter (#27255)

* fix cargo teleporter

* don't delete orders

* basado
This commit is contained in:
Nemanja
2024-04-23 08:07:12 -04:00
committed by GitHub
parent 8117131c91
commit 1bfc63c546
8 changed files with 133 additions and 37 deletions

View File

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

View File

@@ -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)

View File

@@ -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)
{

View File

@@ -69,7 +69,7 @@ public sealed class CargoGiftsRule : StationEventSystem<CargoGiftsRuleComponent>
Loc.GetString(component.Description),
Loc.GetString(component.Dest),
cargoDb,
stationData!
(station.Value, stationData)
))
{
break;

View File

@@ -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)

View File

@@ -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.

View File

@@ -47,3 +47,5 @@
board: CargoTelepadMachineCircuitboard
- type: Appearance
- type: CollideOnAnchor
- type: NameIdentifier
group: CargoTelepads

View File

@@ -37,3 +37,9 @@
id: Bounty
minValue: 0
maxValue: 999
- type: nameIdentifierGroup
id: CargoTelepads
prefix: TELE
minValue: 0
maxValue: 999