Add trade stations (#23863)
* puters * Start on fulfillment * weh * Smol update * FTL sound fixes or smth iunno * Add consoles * More tweaks * Make it unanchorable * final wehs * weh * Fix 1 test * Shrimply bump the distance * cat
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||||
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
|
||||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||||
SetSize="300 150"
|
SetSize="300 150"
|
||||||
MinSize="300 150">
|
MinSize="300 150"
|
||||||
<BoxContainer Orientation="Vertical">
|
Title="{Loc 'cargo-pallet-console-menu-title'}">
|
||||||
|
<BoxContainer Orientation="Vertical" Margin="5">
|
||||||
<BoxContainer Orientation="Horizontal">
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc 'cargo-pallet-menu-appraisal-label'}"
|
<Label Text="{Loc 'cargo-pallet-menu-appraisal-label'}"
|
||||||
StyleClasses="LabelKeyText" />
|
StyleClasses="LabelKeyText" />
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ public sealed partial class CargoPalletMenu : FancyWindow
|
|||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
SellButton.OnPressed += OnSellPressed;
|
SellButton.OnPressed += OnSellPressed;
|
||||||
AppraiseButton.OnPressed += OnAppraisePressed;
|
AppraiseButton.OnPressed += OnAppraisePressed;
|
||||||
Title = Loc.GetString("cargo-pallet-console-menu-title");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetAppraisal(int amount)
|
public void SetAppraisal(int amount)
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ namespace Content.IntegrationTests.Tests.Destructible
|
|||||||
Assert.That(spawnEntitiesBehavior.Spawn.Values.Single(), Is.EqualTo(new MinMax { Min = 1, Max = 1 }));
|
Assert.That(spawnEntitiesBehavior.Spawn.Values.Single(), Is.EqualTo(new MinMax { Min = 1, Max = 1 }));
|
||||||
});
|
});
|
||||||
|
|
||||||
var entitiesInRange = sEntityManager.System<EntityLookupSystem>().GetEntitiesInRange(coordinates, 2);
|
var entitiesInRange = sEntityManager.System<EntityLookupSystem>().GetEntitiesInRange(coordinates, 3, LookupFlags.All | LookupFlags.Approximate);
|
||||||
var found = false;
|
var found = false;
|
||||||
|
|
||||||
foreach (var entity in entitiesInRange)
|
foreach (var entity in entitiesInRange)
|
||||||
@@ -86,7 +86,7 @@ namespace Content.IntegrationTests.Tests.Destructible
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.That(found, Is.True);
|
Assert.That(found, Is.True, $"Unable to find {SpawnedEntityId} nearby for destructible test; found {entitiesInRange.Count} entities.");
|
||||||
});
|
});
|
||||||
await pair.CleanReturnAsync();
|
await pair.CleanReturnAsync();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
using Content.Shared.Cargo.Prototypes;
|
using Content.Shared.Cargo.Prototypes;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
namespace Content.Server.Cargo.Components;
|
namespace Content.Server.Cargo.Components;
|
||||||
@@ -30,4 +31,10 @@ public sealed partial class StationCargoOrderDatabaseComponent : Component
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("shuttle")]
|
[DataField("shuttle")]
|
||||||
public EntityUid? Shuttle;
|
public EntityUid? Shuttle;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The paper-type prototype to spawn with the order information.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public EntProtoId PrinterOutput = "PaperCargoInvoice";
|
||||||
}
|
}
|
||||||
|
|||||||
10
Content.Server/Cargo/Components/TradeStationComponent.cs
Normal file
10
Content.Server/Cargo/Components/TradeStationComponent.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Content.Server.Cargo.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Target for approved orders to spawn at.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed partial class TradeStationComponent : Component
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
using Content.Server.Cargo.Components;
|
using Content.Server.Cargo.Components;
|
||||||
using Content.Server.Labels.Components;
|
using Content.Server.Labels.Components;
|
||||||
using Content.Server.Paper;
|
using Content.Server.Paper;
|
||||||
|
using Content.Server.Station.Components;
|
||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
using Content.Shared.Cargo.BUI;
|
using Content.Shared.Cargo.BUI;
|
||||||
using Content.Shared.Cargo.Events;
|
using Content.Shared.Cargo.Events;
|
||||||
@@ -10,6 +11,7 @@ using Content.Shared.Database;
|
|||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.Cargo.Systems
|
namespace Content.Server.Cargo.Systems
|
||||||
@@ -87,10 +89,12 @@ namespace Content.Server.Cargo.Systems
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bankAccount = GetBankAccount(uid, component);
|
var station = _station.GetOwningStation(uid);
|
||||||
|
|
||||||
// No station to deduct from.
|
// No station to deduct from.
|
||||||
if (!TryGetOrderDatabase(uid, out var dbUid, out var orderDatabase, component) || bankAccount == null)
|
if (!TryComp(station, out StationBankAccountComponent? bank) ||
|
||||||
|
!TryComp(station, out StationDataComponent? stationData) ||
|
||||||
|
!TryGetOrderDatabase(station, out var orderDatabase))
|
||||||
{
|
{
|
||||||
ConsolePopup(args.Session, Loc.GetString("cargo-console-station-not-found"));
|
ConsolePopup(args.Session, Loc.GetString("cargo-console-station-not-found"));
|
||||||
PlayDenySound(uid, component);
|
PlayDenySound(uid, component);
|
||||||
@@ -136,32 +140,82 @@ namespace Content.Server.Cargo.Systems
|
|||||||
var cost = order.Price * order.OrderQuantity;
|
var cost = order.Price * order.OrderQuantity;
|
||||||
|
|
||||||
// Not enough balance
|
// Not enough balance
|
||||||
if (cost > bankAccount.Balance)
|
if (cost > bank.Balance)
|
||||||
{
|
{
|
||||||
ConsolePopup(args.Session, Loc.GetString("cargo-console-insufficient-funds", ("cost", cost)));
|
ConsolePopup(args.Session, Loc.GetString("cargo-console-insufficient-funds", ("cost", cost)));
|
||||||
PlayDenySound(uid, component);
|
PlayDenySound(uid, component);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No slots at the trade station
|
||||||
|
_listEnts.Clear();
|
||||||
|
GetTradeStations(stationData, ref _listEnts);
|
||||||
|
EntityUid? tradeDestination = null;
|
||||||
|
|
||||||
|
// Try to fulfill from any station where possible, if the pad is not occupied.
|
||||||
|
foreach (var trade in _listEnts)
|
||||||
|
{
|
||||||
|
var tradePads = GetCargoPallets(trade);
|
||||||
|
_random.Shuffle(tradePads);
|
||||||
|
|
||||||
|
var freePads = GetFreeCargoPallets(trade, tradePads);
|
||||||
|
|
||||||
|
foreach (var pad in freePads)
|
||||||
|
{
|
||||||
|
var coordinates = new EntityCoordinates(trade, pad.Transform.LocalPosition);
|
||||||
|
|
||||||
|
if (FulfillOrder(order, coordinates, orderDatabase.PrinterOutput))
|
||||||
|
{
|
||||||
|
tradeDestination = trade;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tradeDestination != null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tradeDestination == null)
|
||||||
|
{
|
||||||
|
ConsolePopup(args.Session, Loc.GetString("cargo-console-unfulfilled"));
|
||||||
|
PlayDenySound(uid, component);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_idCardSystem.TryFindIdCard(player, out var idCard);
|
_idCardSystem.TryFindIdCard(player, out var idCard);
|
||||||
// ReSharper disable once ConditionalAccessQualifierIsNonNullableAccordingToAPIContract
|
// ReSharper disable once ConditionalAccessQualifierIsNonNullableAccordingToAPIContract
|
||||||
order.SetApproverData(idCard.Comp?.FullName, idCard.Comp?.JobTitle);
|
order.SetApproverData(idCard.Comp?.FullName, idCard.Comp?.JobTitle);
|
||||||
_audio.PlayPvs(_audio.GetSound(component.ConfirmSound), uid);
|
_audio.PlayPvs(component.ConfirmSound, uid);
|
||||||
|
|
||||||
|
ConsolePopup(args.Session, Loc.GetString("cargo-console-trade-station", ("destination", MetaData(tradeDestination.Value).EntityName)));
|
||||||
|
|
||||||
// Log order approval
|
// Log order approval
|
||||||
_adminLogger.Add(LogType.Action, LogImpact.Low,
|
_adminLogger.Add(LogType.Action, LogImpact.Low,
|
||||||
$"{ToPrettyString(player):user} approved order [orderId:{order.OrderId}, quantity:{order.OrderQuantity}, product:{order.ProductId}, requester:{order.Requester}, reason:{order.Reason}] with balance at {bankAccount.Balance}");
|
$"{ToPrettyString(player):user} approved order [orderId:{order.OrderId}, quantity:{order.OrderQuantity}, product:{order.ProductId}, requester:{order.Requester}, reason:{order.Reason}] with balance at {bank.Balance}");
|
||||||
|
|
||||||
DeductFunds(bankAccount, cost);
|
DeductFunds(bank, cost);
|
||||||
UpdateOrders(dbUid!.Value, orderDatabase);
|
UpdateOrders(station.Value, orderDatabase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetTradeStations(StationDataComponent data, ref List<EntityUid> ents)
|
||||||
|
{
|
||||||
|
foreach (var gridUid in data.Grids)
|
||||||
|
{
|
||||||
|
if (!_tradeQuery.HasComponent(gridUid))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ents.Add(gridUid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRemoveOrderMessage(EntityUid uid, CargoOrderConsoleComponent component, CargoConsoleRemoveOrderMessage args)
|
private void OnRemoveOrderMessage(EntityUid uid, CargoOrderConsoleComponent component, CargoConsoleRemoveOrderMessage args)
|
||||||
{
|
{
|
||||||
if (!TryGetOrderDatabase(uid, out var dbUid, out var orderDatabase, component))
|
var station = _station.GetOwningStation(uid);
|
||||||
|
|
||||||
|
if (!TryGetOrderDatabase(station, out var orderDatabase))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RemoveOrder(dbUid!.Value, args.OrderId, orderDatabase);
|
RemoveOrder(station.Value, args.OrderId, orderDatabase);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAddOrderMessage(EntityUid uid, CargoOrderConsoleComponent component, CargoConsoleAddOrderMessage args)
|
private void OnAddOrderMessage(EntityUid uid, CargoOrderConsoleComponent component, CargoConsoleAddOrderMessage args)
|
||||||
@@ -172,11 +226,9 @@ namespace Content.Server.Cargo.Systems
|
|||||||
if (args.Amount <= 0)
|
if (args.Amount <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var bank = GetBankAccount(uid, component);
|
var stationUid = _station.GetOwningStation(uid);
|
||||||
if (bank == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!TryGetOrderDatabase(uid, out var dbUid, out var orderDatabase, component))
|
if (!TryGetOrderDatabase(stationUid, out var orderDatabase))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!_protoMan.TryIndex<CargoProductPrototype>(args.CargoProductId, out var product))
|
if (!_protoMan.TryIndex<CargoProductPrototype>(args.CargoProductId, out var product))
|
||||||
@@ -187,7 +239,7 @@ namespace Content.Server.Cargo.Systems
|
|||||||
|
|
||||||
var data = GetOrderData(args, product, GenerateOrderId(orderDatabase));
|
var data = GetOrderData(args, product, GenerateOrderId(orderDatabase));
|
||||||
|
|
||||||
if (!TryAddOrder(dbUid!.Value, data, orderDatabase))
|
if (!TryAddOrder(stationUid.Value, data, orderDatabase))
|
||||||
{
|
{
|
||||||
PlayDenySound(uid, component);
|
PlayDenySound(uid, component);
|
||||||
return;
|
return;
|
||||||
@@ -336,10 +388,10 @@ namespace Content.Server.Cargo.Systems
|
|||||||
|
|
||||||
public void ClearOrders(StationCargoOrderDatabaseComponent component)
|
public void ClearOrders(StationCargoOrderDatabaseComponent component)
|
||||||
{
|
{
|
||||||
if (component.Orders.Count == 0) return;
|
if (component.Orders.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
component.Orders.Clear();
|
component.Orders.Clear();
|
||||||
Dirty(component);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool PopFrontOrder(StationCargoOrderDatabaseComponent orderDB, [NotNullWhen(true)] out CargoOrderData? orderOut)
|
private static bool PopFrontOrder(StationCargoOrderDatabaseComponent orderDB, [NotNullWhen(true)] out CargoOrderData? orderOut)
|
||||||
@@ -362,16 +414,27 @@ namespace Content.Server.Cargo.Systems
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool FulfillOrder(StationCargoOrderDatabaseComponent orderDB, EntityCoordinates whereToPutIt,
|
/// <summary>
|
||||||
string? paperPrototypeToPrint)
|
/// Tries to fulfill the next outstanding order.
|
||||||
|
/// </summary>
|
||||||
|
private bool FulfillNextOrder(StationCargoOrderDatabaseComponent orderDB, EntityCoordinates spawn, string? paperProto)
|
||||||
{
|
{
|
||||||
if (PopFrontOrder(orderDB, out var order))
|
if (!PopFrontOrder(orderDB, out var order))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return FulfillOrder(order, spawn, paperProto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fulfills the specified cargo order and spawns paper attached to it.
|
||||||
|
/// </summary>
|
||||||
|
private bool FulfillOrder(CargoOrderData order, EntityCoordinates spawn, string? paperProto)
|
||||||
{
|
{
|
||||||
// Create the item itself
|
// Create the item itself
|
||||||
var item = Spawn(order.ProductId, whereToPutIt);
|
var item = Spawn(order.ProductId, spawn);
|
||||||
|
|
||||||
// Create a sheet of paper to write the order details on
|
// Create a sheet of paper to write the order details on
|
||||||
var printed = EntityManager.SpawnEntity(paperPrototypeToPrint, whereToPutIt);
|
var printed = EntityManager.SpawnEntity(paperProto, spawn);
|
||||||
if (TryComp<PaperComponent>(printed, out var paper))
|
if (TryComp<PaperComponent>(printed, out var paper))
|
||||||
{
|
{
|
||||||
// fill in the order data
|
// fill in the order data
|
||||||
@@ -395,31 +458,19 @@ namespace Content.Server.Cargo.Systems
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeductFunds(StationBankAccountComponent component, int amount)
|
private void DeductFunds(StationBankAccountComponent component, int amount)
|
||||||
{
|
{
|
||||||
component.Balance = Math.Max(0, component.Balance - amount);
|
component.Balance = Math.Max(0, component.Balance - amount);
|
||||||
Dirty(component);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Station
|
#region Station
|
||||||
|
|
||||||
private StationBankAccountComponent? GetBankAccount(EntityUid uid, CargoOrderConsoleComponent _)
|
private bool TryGetOrderDatabase([NotNullWhen(true)] EntityUid? stationUid, [MaybeNullWhen(false)] out StationCargoOrderDatabaseComponent dbComp)
|
||||||
{
|
{
|
||||||
var station = _station.GetOwningStation(uid);
|
return TryComp(stationUid, out dbComp);
|
||||||
|
|
||||||
TryComp<StationBankAccountComponent>(station, out var bankComponent);
|
|
||||||
return bankComponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool TryGetOrderDatabase(EntityUid uid, [MaybeNullWhen(false)] out EntityUid? dbUid, [MaybeNullWhen(false)] out StationCargoOrderDatabaseComponent dbComp, CargoOrderConsoleComponent _)
|
|
||||||
{
|
|
||||||
dbUid = _station.GetOwningStation(uid);
|
|
||||||
return TryComp(dbUid, out dbComp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -1,39 +1,27 @@
|
|||||||
using System.Linq;
|
|
||||||
using Content.Server.Cargo.Components;
|
using Content.Server.Cargo.Components;
|
||||||
using Content.Server.GameTicking.Events;
|
|
||||||
using Content.Server.Shuttles.Components;
|
|
||||||
using Content.Server.Shuttles.Events;
|
|
||||||
using Content.Shared.Stacks;
|
using Content.Shared.Stacks;
|
||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
using Content.Shared.Cargo.BUI;
|
using Content.Shared.Cargo.BUI;
|
||||||
using Content.Shared.Cargo.Components;
|
using Content.Shared.Cargo.Components;
|
||||||
using Content.Shared.Cargo.Events;
|
using Content.Shared.Cargo.Events;
|
||||||
using Content.Shared.CCVar;
|
|
||||||
using Content.Shared.GameTicking;
|
using Content.Shared.GameTicking;
|
||||||
using Content.Shared.Whitelist;
|
|
||||||
using Robust.Server.GameObjects;
|
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Audio;
|
||||||
using Content.Shared.Coordinates;
|
|
||||||
using Content.Shared.Mobs;
|
|
||||||
using Content.Shared.Mobs.Components;
|
|
||||||
|
|
||||||
namespace Content.Server.Cargo.Systems;
|
namespace Content.Server.Cargo.Systems;
|
||||||
|
|
||||||
public sealed partial class CargoSystem
|
public sealed partial class CargoSystem
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Handles cargo shuttle mechanics.
|
* Handles cargo shuttle / trade mechanics.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public MapId? CargoMap { get; private set; }
|
private static readonly SoundPathSpecifier ApproveSound = new("/Audio/Effects/Cargo/ping.ogg");
|
||||||
|
|
||||||
private void InitializeShuttle()
|
private void InitializeShuttle()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<CargoShuttleComponent, FTLStartedEvent>(OnCargoFTLStarted);
|
SubscribeLocalEvent<TradeStationComponent, GridSplitEvent>(OnTradeSplit);
|
||||||
SubscribeLocalEvent<CargoShuttleComponent, FTLCompletedEvent>(OnCargoFTLCompleted);
|
|
||||||
SubscribeLocalEvent<CargoShuttleComponent, FTLTagEvent>(OnCargoFTLTag);
|
|
||||||
|
|
||||||
SubscribeLocalEvent<CargoShuttleConsoleComponent, ComponentStartup>(OnCargoShuttleConsoleStartup);
|
SubscribeLocalEvent<CargoShuttleConsoleComponent, ComponentStartup>(OnCargoShuttleConsoleStartup);
|
||||||
|
|
||||||
@@ -42,32 +30,6 @@ public sealed partial class CargoSystem
|
|||||||
SubscribeLocalEvent<CargoPalletConsoleComponent, BoundUIOpenedEvent>(OnPalletUIOpen);
|
SubscribeLocalEvent<CargoPalletConsoleComponent, BoundUIOpenedEvent>(OnPalletUIOpen);
|
||||||
|
|
||||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
|
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
|
||||||
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStart);
|
|
||||||
|
|
||||||
_cfgManager.OnValueChanged(CCVars.GridFill, SetGridFill);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShutdownShuttle()
|
|
||||||
{
|
|
||||||
_cfgManager.UnsubValueChanged(CCVars.GridFill, SetGridFill);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetGridFill(bool obj)
|
|
||||||
{
|
|
||||||
if (obj)
|
|
||||||
{
|
|
||||||
SetupCargoShuttle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnCargoFTLTag(EntityUid uid, CargoShuttleComponent component, ref FTLTagEvent args)
|
|
||||||
{
|
|
||||||
if (args.Handled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Just saves mappers forgetting.
|
|
||||||
args.Handled = true;
|
|
||||||
args.Tag = "DockCargo";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Console
|
#region Console
|
||||||
@@ -156,6 +118,15 @@ public sealed partial class CargoSystem
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
private void OnTradeSplit(EntityUid uid, TradeStationComponent component, ref GridSplitEvent args)
|
||||||
|
{
|
||||||
|
// If the trade station gets bombed it's still a trade station.
|
||||||
|
foreach (var gridUid in args.NewGrids)
|
||||||
|
{
|
||||||
|
EnsureComp<TradeStationComponent>(gridUid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region Shuttle
|
#region Shuttle
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -206,9 +177,9 @@ public sealed partial class CargoSystem
|
|||||||
return space;
|
return space;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<(EntityUid Entity, CargoPalletComponent Component)> GetCargoPallets(EntityUid gridUid)
|
private List<(EntityUid Entity, CargoPalletComponent Component, TransformComponent PalletXform)> GetCargoPallets(EntityUid gridUid)
|
||||||
{
|
{
|
||||||
var pads = new List<(EntityUid, CargoPalletComponent)>();
|
_pads.Clear();
|
||||||
var query = AllEntityQuery<CargoPalletComponent, TransformComponent>();
|
var query = AllEntityQuery<CargoPalletComponent, TransformComponent>();
|
||||||
|
|
||||||
while (query.MoveNext(out var uid, out var comp, out var compXform))
|
while (query.MoveNext(out var uid, out var comp, out var compXform))
|
||||||
@@ -219,23 +190,43 @@ public sealed partial class CargoSystem
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pads.Add((uid, comp));
|
_pads.Add((uid, comp, compXform));
|
||||||
}
|
}
|
||||||
|
|
||||||
return pads;
|
return _pads;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<(EntityUid Entity, CargoPalletComponent Component, TransformComponent Transform)>
|
||||||
|
GetFreeCargoPallets(EntityUid gridUid,
|
||||||
|
List<(EntityUid Entity, CargoPalletComponent Component, TransformComponent Transform)> pallets)
|
||||||
|
{
|
||||||
|
_setEnts.Clear();
|
||||||
|
|
||||||
|
foreach (var pallet in pallets)
|
||||||
|
{
|
||||||
|
var aabb = _lookup.GetAABBNoContainer(pallet.Entity, pallet.Transform.LocalPosition, pallet.Transform.LocalRotation);
|
||||||
|
|
||||||
|
if (_lookup.AnyLocalEntitiesIntersecting(gridUid, aabb, LookupFlags.Dynamic))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
yield return pallet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Station
|
#region Station
|
||||||
|
|
||||||
private void SellPallets(EntityUid gridUid, EntityUid? station, out double amount)
|
private bool SellPallets(EntityUid gridUid, EntityUid? station, out double amount)
|
||||||
{
|
{
|
||||||
station ??= _station.GetOwningStation(gridUid);
|
station ??= _station.GetOwningStation(gridUid);
|
||||||
GetPalletGoods(gridUid, out var toSell, out amount);
|
GetPalletGoods(gridUid, out var toSell, out amount);
|
||||||
|
|
||||||
Log.Debug($"Cargo sold {toSell.Count} entities for {amount}");
|
Log.Debug($"Cargo sold {toSell.Count} entities for {amount}");
|
||||||
|
|
||||||
|
if (toSell.Count == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (station != null)
|
if (station != null)
|
||||||
{
|
{
|
||||||
var ev = new EntitySoldEvent(station.Value, toSell);
|
var ev = new EntitySoldEvent(station.Value, toSell);
|
||||||
@@ -246,6 +237,8 @@ public sealed partial class CargoSystem
|
|||||||
{
|
{
|
||||||
Del(ent);
|
Del(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GetPalletGoods(EntityUid gridUid, out HashSet<EntityUid> toSell, out double amount)
|
private void GetPalletGoods(EntityUid gridUid, out HashSet<EntityUid> toSell, out double amount)
|
||||||
@@ -253,10 +246,15 @@ public sealed partial class CargoSystem
|
|||||||
amount = 0;
|
amount = 0;
|
||||||
toSell = new HashSet<EntityUid>();
|
toSell = new HashSet<EntityUid>();
|
||||||
|
|
||||||
foreach (var (palletUid, _) in GetCargoPallets(gridUid))
|
foreach (var (palletUid, _, _) in GetCargoPallets(gridUid))
|
||||||
{
|
{
|
||||||
// Containers should already get the sell price of their children so can skip those.
|
// Containers should already get the sell price of their children so can skip those.
|
||||||
foreach (var ent in _lookup.GetEntitiesIntersecting(palletUid, LookupFlags.Dynamic | LookupFlags.Sundries | LookupFlags.Approximate))
|
_setEnts.Clear();
|
||||||
|
|
||||||
|
_lookup.GetEntitiesIntersecting(palletUid, _setEnts,
|
||||||
|
LookupFlags.Dynamic | LookupFlags.Sundries);
|
||||||
|
|
||||||
|
foreach (var ent in _setEnts)
|
||||||
{
|
{
|
||||||
// Dont sell:
|
// Dont sell:
|
||||||
// - anything already being sold
|
// - anything already being sold
|
||||||
@@ -304,21 +302,6 @@ public sealed partial class CargoSystem
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddCargoContents(EntityUid shuttleUid, CargoShuttleComponent shuttle, StationCargoOrderDatabaseComponent orderDatabase)
|
|
||||||
{
|
|
||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
|
|
||||||
var pads = GetCargoPallets(shuttleUid);
|
|
||||||
while (pads.Count > 0)
|
|
||||||
{
|
|
||||||
var coordinates = new EntityCoordinates(shuttleUid, xformQuery.GetComponent(_random.PickAndTake(pads).Entity).LocalPosition);
|
|
||||||
if (!FulfillOrder(orderDatabase, coordinates, shuttle.PrinterOutput))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnPalletSale(EntityUid uid, CargoPalletConsoleComponent component, CargoPalletSellMessage args)
|
private void OnPalletSale(EntityUid uid, CargoPalletConsoleComponent component, CargoPalletSellMessage args)
|
||||||
{
|
{
|
||||||
var player = args.Session.AttachedEntity;
|
var player = args.Session.AttachedEntity;
|
||||||
@@ -327,114 +310,29 @@ public sealed partial class CargoSystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var bui = _uiSystem.GetUi(uid, CargoPalletConsoleUiKey.Sale);
|
var bui = _uiSystem.GetUi(uid, CargoPalletConsoleUiKey.Sale);
|
||||||
if (Transform(uid).GridUid is not EntityUid gridUid)
|
var xform = Transform(uid);
|
||||||
|
|
||||||
|
if (xform.GridUid is not EntityUid gridUid)
|
||||||
{
|
{
|
||||||
_uiSystem.SetUiState(bui,
|
_uiSystem.SetUiState(bui,
|
||||||
new CargoPalletConsoleInterfaceState(0, 0, false));
|
new CargoPalletConsoleInterfaceState(0, 0, false));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SellPallets(gridUid, null, out var price);
|
if (!SellPallets(gridUid, null, out var price))
|
||||||
|
return;
|
||||||
|
|
||||||
var stackPrototype = _protoMan.Index<StackPrototype>(component.CashType);
|
var stackPrototype = _protoMan.Index<StackPrototype>(component.CashType);
|
||||||
_stack.Spawn((int) price, stackPrototype, uid.ToCoordinates());
|
_stack.Spawn((int) price, stackPrototype, xform.Coordinates);
|
||||||
|
_audio.PlayPvs(ApproveSound, uid);
|
||||||
UpdatePalletConsoleInterface(uid);
|
UpdatePalletConsoleInterface(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCargoFTLStarted(EntityUid uid, CargoShuttleComponent component, ref FTLStartedEvent args)
|
|
||||||
{
|
|
||||||
var stationUid = _station.GetOwningStation(uid);
|
|
||||||
|
|
||||||
// Called
|
|
||||||
if (CargoMap == null ||
|
|
||||||
args.FromMapUid != _mapManager.GetMapEntityId(CargoMap.Value) ||
|
|
||||||
!TryComp<StationCargoOrderDatabaseComponent>(stationUid, out var orderDatabase))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddCargoContents(uid, component, orderDatabase);
|
|
||||||
UpdateOrders(stationUid!.Value, orderDatabase);
|
|
||||||
UpdateCargoShuttleConsoles(uid, component);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnCargoFTLCompleted(EntityUid uid, CargoShuttleComponent component, ref FTLCompletedEvent args)
|
|
||||||
{
|
|
||||||
var xform = Transform(uid);
|
|
||||||
// Recalled
|
|
||||||
if (xform.MapID != CargoMap)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var stationUid = _station.GetOwningStation(uid);
|
|
||||||
|
|
||||||
if (TryComp<StationBankAccountComponent>(stationUid, out var bank))
|
|
||||||
{
|
|
||||||
SellPallets(uid, stationUid, out var amount);
|
|
||||||
bank.Balance += (int) amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void OnRoundRestart(RoundRestartCleanupEvent ev)
|
private void OnRoundRestart(RoundRestartCleanupEvent ev)
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
CleanupCargoShuttle();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnRoundStart(RoundStartingEvent ev)
|
|
||||||
{
|
|
||||||
if (_cfgManager.GetCVar(CCVars.GridFill))
|
|
||||||
SetupCargoShuttle();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CleanupCargoShuttle()
|
|
||||||
{
|
|
||||||
if (CargoMap == null || !_mapManager.MapExists(CargoMap.Value))
|
|
||||||
{
|
|
||||||
CargoMap = null;
|
|
||||||
DebugTools.Assert(!EntityQuery<CargoShuttleComponent>().Any());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_mapManager.DeleteMap(CargoMap.Value);
|
|
||||||
CargoMap = null;
|
|
||||||
|
|
||||||
// Shuttle may not have been in the cargo dimension (e.g. on the station map) so need to delete.
|
|
||||||
var query = AllEntityQuery<CargoShuttleComponent>();
|
|
||||||
|
|
||||||
while (query.MoveNext(out var uid, out var _))
|
|
||||||
{
|
|
||||||
if (TryComp<StationCargoOrderDatabaseComponent>(uid, out var station))
|
|
||||||
{
|
|
||||||
station.Shuttle = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
QueueDel(uid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetupCargoShuttle()
|
|
||||||
{
|
|
||||||
if (CargoMap != null && _mapManager.MapExists(CargoMap.Value))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// It gets mapinit which is okay... buuutt we still want it paused to avoid power draining.
|
|
||||||
CargoMap = _mapManager.CreateMap();
|
|
||||||
var mapUid = _mapManager.GetMapEntityId(CargoMap.Value);
|
|
||||||
var ftl = EnsureComp<FTLDestinationComponent>(_mapManager.GetMapEntityId(CargoMap.Value));
|
|
||||||
ftl.Whitelist = new EntityWhitelist()
|
|
||||||
{
|
|
||||||
Components = new[]
|
|
||||||
{
|
|
||||||
_factory.GetComponentName(typeof(CargoShuttleComponent))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
_metaSystem.SetEntityName(mapUid, $"Trading post {_random.Next(1000):000}");
|
|
||||||
|
|
||||||
_console.RefreshShuttleConsoles();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ public sealed partial class CargoSystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
var xform = Transform(uid);
|
var xform = Transform(uid);
|
||||||
if (FulfillOrder(orderDatabase, xform.Coordinates, comp.PrinterOutput))
|
if (FulfillNextOrder(orderDatabase, 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);
|
UpdateOrders(station.Value, orderDatabase);
|
||||||
|
|
||||||
comp.CurrentState = CargoTelepadState.Teleporting;
|
comp.CurrentState = CargoTelepadState.Teleporting;
|
||||||
_appearance.SetData(uid, CargoTelepadVisuals.State, CargoTelepadState.Teleporting, appearance);
|
_appearance.SetData(uid, CargoTelepadVisuals.State, CargoTelepadState.Teleporting, appearance);
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ using Content.Shared.Mobs.Components;
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
using Robust.Shared.Configuration;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
@@ -25,9 +23,6 @@ namespace Content.Server.Cargo.Systems;
|
|||||||
public sealed partial class CargoSystem : SharedCargoSystem
|
public sealed partial class CargoSystem : SharedCargoSystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IGameTiming _timing = default!;
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
[Dependency] private readonly IComponentFactory _factory = default!;
|
|
||||||
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
|
|
||||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
|
||||||
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||||
@@ -41,6 +36,7 @@ public sealed partial class CargoSystem : SharedCargoSystem
|
|||||||
[Dependency] private readonly PricingSystem _pricing = default!;
|
[Dependency] private readonly PricingSystem _pricing = default!;
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
|
[Dependency] private readonly SharedTransformSystem _xformSystem = default!;
|
||||||
[Dependency] private readonly ShuttleConsoleSystem _console = default!;
|
[Dependency] private readonly ShuttleConsoleSystem _console = default!;
|
||||||
[Dependency] private readonly StackSystem _stack = default!;
|
[Dependency] private readonly StackSystem _stack = default!;
|
||||||
[Dependency] private readonly StationSystem _station = default!;
|
[Dependency] private readonly StationSystem _station = default!;
|
||||||
@@ -50,6 +46,11 @@ public sealed partial class CargoSystem : SharedCargoSystem
|
|||||||
private EntityQuery<TransformComponent> _xformQuery;
|
private EntityQuery<TransformComponent> _xformQuery;
|
||||||
private EntityQuery<CargoSellBlacklistComponent> _blacklistQuery;
|
private EntityQuery<CargoSellBlacklistComponent> _blacklistQuery;
|
||||||
private EntityQuery<MobStateComponent> _mobQuery;
|
private EntityQuery<MobStateComponent> _mobQuery;
|
||||||
|
private EntityQuery<TradeStationComponent> _tradeQuery;
|
||||||
|
|
||||||
|
private HashSet<EntityUid> _setEnts = new();
|
||||||
|
private List<EntityUid> _listEnts = new();
|
||||||
|
private List<(EntityUid, CargoPalletComponent, TransformComponent)> _pads = new();
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -58,6 +59,7 @@ public sealed partial class CargoSystem : SharedCargoSystem
|
|||||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
_xformQuery = GetEntityQuery<TransformComponent>();
|
||||||
_blacklistQuery = GetEntityQuery<CargoSellBlacklistComponent>();
|
_blacklistQuery = GetEntityQuery<CargoSellBlacklistComponent>();
|
||||||
_mobQuery = GetEntityQuery<MobStateComponent>();
|
_mobQuery = GetEntityQuery<MobStateComponent>();
|
||||||
|
_tradeQuery = GetEntityQuery<TradeStationComponent>();
|
||||||
|
|
||||||
InitializeConsole();
|
InitializeConsole();
|
||||||
InitializeShuttle();
|
InitializeShuttle();
|
||||||
@@ -65,13 +67,6 @@ public sealed partial class CargoSystem : SharedCargoSystem
|
|||||||
InitializeBounty();
|
InitializeBounty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
base.Shutdown();
|
|
||||||
ShutdownShuttle();
|
|
||||||
CleanupCargoShuttle();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
{
|
{
|
||||||
base.Update(frameTime);
|
base.Update(frameTime);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.Shuttles.Systems;
|
using Content.Server.Shuttles.Systems;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.Shuttles.Components;
|
namespace Content.Server.Shuttles.Components;
|
||||||
@@ -23,6 +24,11 @@ public record struct GridSpawnGroup
|
|||||||
public int MinCount = 1;
|
public int MinCount = 1;
|
||||||
public int MaxCount = 1;
|
public int MaxCount = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Components to be added to any spawned grids.
|
||||||
|
/// </summary>
|
||||||
|
public ComponentRegistry AddComponents = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hide the IFF label of the grid.
|
/// Hide the IFF label of the grid.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -235,6 +235,12 @@ public sealed partial class ShuttleSystem
|
|||||||
component.State = FTLState.Starting;
|
component.State = FTLState.Starting;
|
||||||
var audio = _audio.PlayPvs(_startupSound, uid);
|
var audio = _audio.PlayPvs(_startupSound, uid);
|
||||||
audio.Value.Component.Flags |= AudioFlags.GridAudio;
|
audio.Value.Component.Flags |= AudioFlags.GridAudio;
|
||||||
|
|
||||||
|
if (_physicsQuery.TryGetComponent(uid, out var gridPhysics))
|
||||||
|
{
|
||||||
|
_transform.SetLocalPosition(audio.Value.Entity, gridPhysics.LocalCenter);
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure the map is setup before we leave to avoid pop-in (e.g. parallax).
|
// Make sure the map is setup before we leave to avoid pop-in (e.g. parallax).
|
||||||
SetupHyperspace();
|
SetupHyperspace();
|
||||||
return true;
|
return true;
|
||||||
@@ -260,6 +266,7 @@ public sealed partial class ShuttleSystem
|
|||||||
{
|
{
|
||||||
// Startup time has elapsed and in hyperspace.
|
// Startup time has elapsed and in hyperspace.
|
||||||
case FTLState.Starting:
|
case FTLState.Starting:
|
||||||
|
{
|
||||||
DoTheDinosaur(xform);
|
DoTheDinosaur(xform);
|
||||||
|
|
||||||
comp.State = FTLState.Travelling;
|
comp.State = FTLState.Travelling;
|
||||||
@@ -268,7 +275,8 @@ public sealed partial class ShuttleSystem
|
|||||||
var fromRotation = _transform.GetWorldRotation(xform);
|
var fromRotation = _transform.GetWorldRotation(xform);
|
||||||
|
|
||||||
var width = Comp<MapGridComponent>(uid).LocalAABB.Width;
|
var width = Comp<MapGridComponent>(uid).LocalAABB.Width;
|
||||||
xform.Coordinates = new EntityCoordinates(_mapManager.GetMapEntityId(_hyperSpaceMap!.Value), new Vector2(_index + width / 2f, 0f));
|
xform.Coordinates = new EntityCoordinates(_mapManager.GetMapEntityId(_hyperSpaceMap!.Value),
|
||||||
|
new Vector2(_index + width / 2f, 0f));
|
||||||
xform.LocalRotation = Angle.Zero;
|
xform.LocalRotation = Angle.Zero;
|
||||||
_index += width + Buffer;
|
_index += width + Buffer;
|
||||||
comp.Accumulator += comp.TravelTime - DefaultArrivalTime;
|
comp.Accumulator += comp.TravelTime - DefaultArrivalTime;
|
||||||
@@ -285,7 +293,9 @@ public sealed partial class ShuttleSystem
|
|||||||
|
|
||||||
SetDockBolts(uid, true);
|
SetDockBolts(uid, true);
|
||||||
_console.RefreshShuttleConsoles(uid);
|
_console.RefreshShuttleConsoles(uid);
|
||||||
var target = comp.TargetUid != null ? new EntityCoordinates(comp.TargetUid.Value, Vector2.Zero) : comp.TargetCoordinates;
|
var target = comp.TargetUid != null
|
||||||
|
? new EntityCoordinates(comp.TargetUid.Value, Vector2.Zero)
|
||||||
|
: comp.TargetCoordinates;
|
||||||
|
|
||||||
var ev = new FTLStartedEvent(uid, target, fromMapUid, fromMatrix, fromRotation);
|
var ev = new FTLStartedEvent(uid, target, fromMapUid, fromMatrix, fromRotation);
|
||||||
RaiseLocalEvent(uid, ref ev, true);
|
RaiseLocalEvent(uid, ref ev, true);
|
||||||
@@ -293,8 +303,15 @@ public sealed partial class ShuttleSystem
|
|||||||
var wowdio = _audio.PlayPvs(comp.TravelSound, uid);
|
var wowdio = _audio.PlayPvs(comp.TravelSound, uid);
|
||||||
comp.TravelStream = wowdio?.Entity;
|
comp.TravelStream = wowdio?.Entity;
|
||||||
if (wowdio?.Component != null)
|
if (wowdio?.Component != null)
|
||||||
|
{
|
||||||
wowdio.Value.Component.Flags |= AudioFlags.GridAudio;
|
wowdio.Value.Component.Flags |= AudioFlags.GridAudio;
|
||||||
|
|
||||||
|
if (_physicsQuery.TryGetComponent(uid, out var gridPhysics))
|
||||||
|
{
|
||||||
|
_transform.SetLocalPosition(wowdio.Value.Entity, gridPhysics.LocalCenter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
// Arriving, play effects
|
// Arriving, play effects
|
||||||
case FTLState.Travelling:
|
case FTLState.Travelling:
|
||||||
@@ -313,6 +330,7 @@ public sealed partial class ShuttleSystem
|
|||||||
break;
|
break;
|
||||||
// Arrived
|
// Arrived
|
||||||
case FTLState.Arriving:
|
case FTLState.Arriving:
|
||||||
|
{
|
||||||
DoTheDinosaur(xform);
|
DoTheDinosaur(xform);
|
||||||
SetDockBolts(uid, false);
|
SetDockBolts(uid, false);
|
||||||
SetDocks(uid, true);
|
SetDocks(uid, true);
|
||||||
@@ -383,6 +401,12 @@ public sealed partial class ShuttleSystem
|
|||||||
comp.TravelStream = _audio.Stop(comp.TravelStream);
|
comp.TravelStream = _audio.Stop(comp.TravelStream);
|
||||||
var audio = _audio.PlayPvs(_arrivalSound, uid);
|
var audio = _audio.PlayPvs(_arrivalSound, uid);
|
||||||
audio.Value.Component.Flags |= AudioFlags.GridAudio;
|
audio.Value.Component.Flags |= AudioFlags.GridAudio;
|
||||||
|
// TODO: Shitcode til engine fix
|
||||||
|
|
||||||
|
if (_physicsQuery.TryGetComponent(uid, out var gridPhysics))
|
||||||
|
{
|
||||||
|
_transform.SetLocalPosition(audio.Value.Entity, gridPhysics.LocalCenter);
|
||||||
|
}
|
||||||
|
|
||||||
if (TryComp<FTLDestinationComponent>(uid, out var dest))
|
if (TryComp<FTLDestinationComponent>(uid, out var dest))
|
||||||
{
|
{
|
||||||
@@ -397,6 +421,7 @@ public sealed partial class ShuttleSystem
|
|||||||
|
|
||||||
var ftlEvent = new FTLCompletedEvent(uid, _mapManager.GetMapEntityId(mapId));
|
var ftlEvent = new FTLCompletedEvent(uid, _mapManager.GetMapEntityId(mapId));
|
||||||
RaiseLocalEvent(uid, ref ftlEvent, true);
|
RaiseLocalEvent(uid, ref ftlEvent, true);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FTLState.Cooldown:
|
case FTLState.Cooldown:
|
||||||
RemComp<FTLComponent>(uid);
|
RemComp<FTLComponent>(uid);
|
||||||
@@ -711,6 +736,9 @@ public sealed partial class ShuttleSystem
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
var aabb = fixture.Shape.ComputeAABB(transform, 0);
|
var aabb = fixture.Shape.ComputeAABB(transform, 0);
|
||||||
|
|
||||||
|
// Shift it slightly
|
||||||
|
aabb = aabb.Translated(-grid.TileSizeHalfVector);
|
||||||
// Create a small border around it.
|
// Create a small border around it.
|
||||||
aabb = aabb.Enlarged(0.2f);
|
aabb = aabb.Enlarged(0.2f);
|
||||||
aabbs.Add(aabb);
|
aabbs.Add(aabb);
|
||||||
|
|||||||
@@ -156,6 +156,17 @@ public sealed partial class ShuttleSystem
|
|||||||
var name = path.FilenameWithoutExtension;
|
var name = path.FilenameWithoutExtension;
|
||||||
_metadata.SetEntityName(ent[0], name);
|
_metadata.SetEntityName(ent[0], name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var compReg in group.AddComponents.Values)
|
||||||
|
{
|
||||||
|
var compType = compReg.Component.GetType();
|
||||||
|
|
||||||
|
if (HasComp(ent[0], compType))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var comp = _factory.GetComponent(compType);
|
||||||
|
AddComp(ent[0], comp, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace Content.Server.Shuttles.Systems;
|
|||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public sealed partial class ShuttleSystem : SharedShuttleSystem
|
public sealed partial class ShuttleSystem : SharedShuttleSystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IComponentFactory _factory = default!;
|
||||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
@@ -39,7 +40,6 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem
|
|||||||
[Dependency] private readonly MapLoaderSystem _loader = default!;
|
[Dependency] private readonly MapLoaderSystem _loader = default!;
|
||||||
[Dependency] private readonly MetaDataSystem _metadata = default!;
|
[Dependency] private readonly MetaDataSystem _metadata = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
[Dependency] private readonly SharedMapSystem _maps = default!;
|
|
||||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||||
[Dependency] private readonly ShuttleConsoleSystem _console = default!;
|
[Dependency] private readonly ShuttleConsoleSystem _console = default!;
|
||||||
|
|||||||
@@ -10,10 +10,7 @@ namespace Content.Shared.Cargo.Components;
|
|||||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedCargoSystem))]
|
[RegisterComponent, NetworkedComponent, Access(typeof(SharedCargoSystem))]
|
||||||
public sealed partial class CargoShuttleComponent : Component
|
public sealed partial class CargoShuttleComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
/*
|
||||||
/// The paper-type prototype to spawn with the order information.
|
* Still needed for drone console for now.
|
||||||
/// </summary>
|
*/
|
||||||
[DataField("printerOutput", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
|
||||||
public string PrinterOutput = "PaperCargoInvoice";
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ cargo-console-invalid-product = Invalid product ID
|
|||||||
cargo-console-too-many = Too many approved orders
|
cargo-console-too-many = Too many approved orders
|
||||||
cargo-console-snip-snip = Order trimmed to capacity
|
cargo-console-snip-snip = Order trimmed to capacity
|
||||||
cargo-console-insufficient-funds = Insufficient funds (require {$cost})
|
cargo-console-insufficient-funds = Insufficient funds (require {$cost})
|
||||||
|
cargo-console-unfulfilled = No room to fulfill order
|
||||||
|
cargo-console-trade-station = Sent to {$destination}
|
||||||
|
|
||||||
cargo-console-paper-print-name = Order #{$orderNumber}
|
cargo-console-paper-print-name = Order #{$orderNumber}
|
||||||
cargo-console-paper-print-text =
|
cargo-console-paper-print-text =
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -46,9 +46,16 @@
|
|||||||
path: /Maps/Shuttles/cargo.yml
|
path: /Maps/Shuttles/cargo.yml
|
||||||
- type: GridSpawn
|
- type: GridSpawn
|
||||||
groups:
|
groups:
|
||||||
|
trade:
|
||||||
|
addComponents:
|
||||||
|
- type: ProtectedGrid
|
||||||
|
- type: TradeStation
|
||||||
|
paths:
|
||||||
|
- /Maps/Shuttles/trading_outpost.yml
|
||||||
mining:
|
mining:
|
||||||
paths:
|
paths:
|
||||||
- /Maps/Shuttles/mining.yml
|
- /Maps/Shuttles/mining.yml
|
||||||
|
# Spawn last
|
||||||
ruins:
|
ruins:
|
||||||
hide: true
|
hide: true
|
||||||
nameGrid: true
|
nameGrid: true
|
||||||
|
|||||||
Reference in New Issue
Block a user