Shuttle drone improvements (#16931)

This commit is contained in:
metalgearsloth
2023-05-31 11:13:02 +10:00
committed by GitHub
parent 53d4e408aa
commit 57858f802f
35 changed files with 335 additions and 278 deletions

View File

@@ -53,7 +53,7 @@ public static class PoolManager
(CCVars.NPCMaxUpdates.Name, "999999"),
(CVars.ThreadParallelCount.Name, "1"),
(CCVars.GameRoleTimers.Name, "false"),
(CCVars.CargoShuttles.Name, "false"),
(CCVars.GridFill.Name, "false"),
(CCVars.ArrivalsShuttles.Name, "false"),
(CCVars.EmergencyShuttleEnabled.Name, "false"),
(CCVars.ProcgenPreload.Name, "false"),

View File

@@ -63,8 +63,6 @@ public sealed class CargoTest
var entManager = server.ResolveDependency<IEntityManager>();
var mapManager = server.ResolveDependency<IMapManager>();
var protoManager = server.ResolveDependency<IPrototypeManager>();
var cfg = server.ResolveDependency<IConfigurationManager>();
await server.WaitPost(() => cfg.SetCVar(CCVars.DisableGridFill, true));
await server.WaitAssertion(() =>
{
@@ -106,7 +104,6 @@ public sealed class CargoTest
mapManager.DeleteMap(mapId);
});
await server.WaitPost(() => cfg.SetCVar(CCVars.DisableGridFill, false));
await pairTracker.CleanReturnAsync();
}

View File

@@ -27,15 +27,12 @@ namespace Content.IntegrationTests.Tests
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, Destructive = true});
var server = pairTracker.Pair.Server;
IEntityManager entityMan = null;
var cfg = server.ResolveDependency<IConfigurationManager>();
await server.WaitPost(() => cfg.SetCVar(CCVars.DisableGridFill, true));
var entityMan = server.ResolveDependency<IEntityManager>();
var mapManager = server.ResolveDependency<IMapManager>();
var prototypeMan = server.ResolveDependency<IPrototypeManager>();
await server.WaitPost(() =>
{
entityMan = IoCManager.Resolve<IEntityManager>();
var mapManager = IoCManager.Resolve<IMapManager>();
var prototypeMan = IoCManager.Resolve<IPrototypeManager>();
var protoIds = prototypeMan
.EnumeratePrototypes<EntityPrototype>()
.Where(p=>!p.Abstract)
@@ -65,7 +62,6 @@ namespace Content.IntegrationTests.Tests
Assert.That(entityMan.EntityCount, Is.Zero);
});
await server.WaitPost(() => cfg.SetCVar(CCVars.DisableGridFill, false));
await pairTracker.CleanReturnAsync();
}
@@ -75,16 +71,13 @@ namespace Content.IntegrationTests.Tests
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, Destructive = true});
var server = pairTracker.Pair.Server;
var map = await PoolManager.CreateTestMap(pairTracker);
IEntityManager entityMan = null;
var cfg = server.ResolveDependency<IConfigurationManager>();
await server.WaitPost(() => cfg.SetCVar(CCVars.DisableGridFill, true));
var entityMan = server.ResolveDependency<IEntityManager>();
var prototypeMan = server.ResolveDependency<IPrototypeManager>();
await server.WaitPost(() =>
{
entityMan = IoCManager.Resolve<IEntityManager>();
var prototypeMan = IoCManager.Resolve<IPrototypeManager>();
var protoIds = prototypeMan
.EnumeratePrototypes<EntityPrototype>()
.Where(p=>!p.Abstract)
@@ -109,7 +102,6 @@ namespace Content.IntegrationTests.Tests
Assert.That(entityMan.EntityCount, Is.Zero);
});
await server.WaitPost(() => cfg.SetCVar(CCVars.DisableGridFill, false));
await pairTracker.CleanReturnAsync();
}
@@ -129,7 +121,6 @@ namespace Content.IntegrationTests.Tests
var mapManager = server.ResolveDependency<IMapManager>();
var sEntMan = server.ResolveDependency<IEntityManager>();
await server.WaitPost(() => cfg.SetCVar(CCVars.DisableGridFill, true));
Assert.That(cfg.GetCVar(CVars.NetPVS), Is.False);
var protoIds = prototypeMan
@@ -178,7 +169,6 @@ namespace Content.IntegrationTests.Tests
Assert.That(sEntMan.EntityCount, Is.Zero);
});
await server.WaitPost(() => cfg.SetCVar(CCVars.DisableGridFill, false));
await pairTracker.CleanReturnAsync();
}

View File

@@ -27,7 +27,7 @@ public sealed class StartEndGameRulesTest
await server.WaitIdleAsync();
var gameTicker = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<GameTicker>();
var cfg = server.ResolveDependency<IConfigurationManager>();
Assert.That(cfg.GetCVar(CCVars.DisableGridFill), Is.False);
Assert.That(cfg.GetCVar(CCVars.GridFill), Is.False);
await server.WaitAssertion(() =>
{

View File

@@ -58,7 +58,7 @@ namespace Content.IntegrationTests.Tests
var mapLoader = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<MapLoaderSystem>();
var mapManager = server.ResolveDependency<IMapManager>();
var cfg = server.ResolveDependency<IConfigurationManager>();
Assert.That(cfg.GetCVar(CCVars.DisableGridFill), Is.False);
Assert.That(cfg.GetCVar(CCVars.GridFill), Is.False);
await server.WaitPost(() =>
{
@@ -188,7 +188,7 @@ namespace Content.IntegrationTests.Tests
var shuttleSystem = entManager.EntitySysManager.GetEntitySystem<ShuttleSystem>();
var xformQuery = entManager.GetEntityQuery<TransformComponent>();
var cfg = server.ResolveDependency<IConfigurationManager>();
Assert.That(cfg.GetCVar(CCVars.DisableGridFill), Is.False);
Assert.That(cfg.GetCVar(CCVars.GridFill), Is.False);
await server.WaitPost(() =>
{
@@ -352,7 +352,7 @@ namespace Content.IntegrationTests.Tests
var mapLoader = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<MapLoaderSystem>();
var mapManager = server.ResolveDependency<IMapManager>();
var cfg = server.ResolveDependency<IConfigurationManager>();
Assert.That(cfg.GetCVar(CCVars.DisableGridFill), Is.False);
Assert.That(cfg.GetCVar(CCVars.GridFill), Is.False);
await server.WaitPost(() =>
{

View File

@@ -29,7 +29,7 @@ namespace Content.IntegrationTests.Tests
var xformSystem = sEntities.EntitySysManager.GetEntitySystem<SharedTransformSystem>();
var resManager = server.ResolveDependency<IResourceManager>();
var cfg = server.ResolveDependency<IConfigurationManager>();
Assert.That(cfg.GetCVar(CCVars.DisableGridFill), Is.False);
Assert.That(cfg.GetCVar(CCVars.GridFill), Is.False);
await server.WaitAssertion(() =>
{

View File

@@ -28,7 +28,7 @@ namespace Content.IntegrationTests.Tests
var mapLoader = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<MapLoaderSystem>();
var mapManager = server.ResolveDependency<IMapManager>();
var cfg = server.ResolveDependency<IConfigurationManager>();
Assert.That(cfg.GetCVar(CCVars.DisableGridFill), Is.False);
Assert.That(cfg.GetCVar(CCVars.GridFill), Is.False);
await server.WaitPost(() =>
{
@@ -97,7 +97,7 @@ namespace Content.IntegrationTests.Tests
MapId mapId = default;
var cfg = server.ResolveDependency<IConfigurationManager>();
Assert.That(cfg.GetCVar(CCVars.DisableGridFill), Is.False);
Assert.That(cfg.GetCVar(CCVars.GridFill), Is.False);
// Load bagel.yml as uninitialized map, and save it to ensure it's up to date.
server.Post(() =>
@@ -178,7 +178,7 @@ namespace Content.IntegrationTests.Tests
var mapManager = server.ResolveDependency<IMapManager>();
var userData = server.ResolveDependency<IResourceManager>().UserData;
var cfg = server.ResolveDependency<IConfigurationManager>();
Assert.That(cfg.GetCVar(CCVars.DisableGridFill), Is.False);
Assert.That(cfg.GetCVar(CCVars.GridFill), Is.False);
MapId mapId = default;
const string fileA = "/load tick load a.yml";

View File

@@ -1,15 +0,0 @@
using Content.Server.Shuttles.Components;
namespace Content.Server.Cargo.Components;
/// <summary>
/// Lets you remotely control the cargo shuttle.
/// </summary>
[RegisterComponent]
public sealed class CargoPilotConsoleComponent : Component
{
/// <summary>
/// <see cref="ShuttleConsoleComponent"/> that we're proxied into.
/// </summary>
public EntityUid? Entity;
}

View File

@@ -24,9 +24,7 @@ public sealed class StationCargoOrderDatabaseComponent : Component
/// </summary>
public int NumOrdersCreated;
[DataField("cargoShuttleProto", customTypeSerializer:typeof(PrototypeIdSerializer<CargoShuttlePrototype>))]
public string? CargoShuttleProto = "CargoShuttle";
// TODO: Can probably dump this
/// <summary>
/// The cargo shuttle assigned to this station.
/// </summary>

View File

@@ -1,5 +1,6 @@
using System.Linq;
using Content.Server.Cargo.Components;
using Content.Server.Shuttle.Components;
using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Events;
using Content.Server.UserInterface;
@@ -30,35 +31,21 @@ namespace Content.Server.Cargo.Systems;
public sealed partial class CargoSystem
{
/*
* Handles cargo shuttle mechanics, including cargo shuttle consoles.
* Handles cargo shuttle mechanics.
*/
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly MapLoaderSystem _map = default!;
[Dependency] private readonly PricingSystem _pricing = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly ShuttleConsoleSystem _console = default!;
[Dependency] private readonly StackSystem _stack = default!;
public MapId? CargoMap { get; private set; }
private int _index;
/// <summary>
/// Whether cargo shuttles are enabled at all. Mainly used to disable cargo shuttle loading for performance reasons locally.
/// </summary>
private bool _enabled;
private void InitializeShuttle()
{
_enabled = _configManager.GetCVar(CCVars.CargoShuttles);
// Don't want to immediately call this as shuttles will get setup in the natural course of things.
_configManager.OnValueChanged(CCVars.CargoShuttles, SetCargoShuttleEnabled);
SubscribeLocalEvent<CargoShuttleComponent, FTLStartedEvent>(OnCargoFTLStarted);
SubscribeLocalEvent<CargoShuttleComponent, FTLCompletedEvent>(OnCargoFTLCompleted);
SubscribeLocalEvent<CargoShuttleComponent, FTLTagEvent>(OnCargoFTLTag);
@@ -69,12 +56,6 @@ public sealed partial class CargoSystem
SubscribeLocalEvent<CargoPalletConsoleComponent, CargoPalletAppraiseMessage>(OnPalletAppraise);
SubscribeLocalEvent<CargoPalletConsoleComponent, BoundUIOpenedEvent>(OnPalletUIOpen);
SubscribeLocalEvent<CargoPilotConsoleComponent, ConsoleShuttleEvent>(OnCargoGetConsole);
SubscribeLocalEvent<CargoPilotConsoleComponent, AfterActivatableUIOpenEvent>(OnCargoPilotConsoleOpen);
SubscribeLocalEvent<CargoPilotConsoleComponent, BoundUIClosedEvent>(OnCargoPilotConsoleClose);
SubscribeLocalEvent<StationCargoOrderDatabaseComponent, ComponentStartup>(OnCargoOrderStartup);
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
}
@@ -88,90 +69,20 @@ public sealed partial class CargoSystem
args.Tag = "DockCargo";
}
private void ShutdownShuttle()
{
_configManager.UnsubValueChanged(CCVars.CargoShuttles, SetCargoShuttleEnabled);
}
private void SetCargoShuttleEnabled(bool value)
{
if (_enabled == value)
return;
_enabled = value;
if (value)
{
Setup();
var query = AllEntityQuery<StationCargoOrderDatabaseComponent>();
while (query.MoveNext(out var stationUid, out var station))
{
AddShuttle(stationUid, station);
}
}
else
{
CleanupShuttle();
}
}
#region Cargo Pilot Console
private void OnCargoPilotConsoleOpen(EntityUid uid, CargoPilotConsoleComponent component, AfterActivatableUIOpenEvent args)
{
component.Entity = GetShuttleConsole(uid);
}
private void OnCargoPilotConsoleClose(EntityUid uid, CargoPilotConsoleComponent component, BoundUIClosedEvent args)
{
component.Entity = null;
}
private void OnCargoGetConsole(EntityUid uid, CargoPilotConsoleComponent component, ref ConsoleShuttleEvent args)
{
args.Console = GetShuttleConsole(uid);
}
private EntityUid? GetShuttleConsole(EntityUid uid)
{
var stationUid = _station.GetOwningStation(uid);
if (!TryComp<StationCargoOrderDatabaseComponent>(stationUid, out var orderDatabase) ||
!TryComp<CargoShuttleComponent>(orderDatabase.Shuttle, out var shuttle))
{
return null;
}
return GetShuttleConsole(orderDatabase.Shuttle.Value, shuttle);
}
#endregion
#region Console
private void UpdateCargoShuttleConsoles(CargoShuttleComponent component)
private void UpdateCargoShuttleConsoles(EntityUid shuttleUid, CargoShuttleComponent component)
{
// Update pilot consoles that are already open.
var pilotConsoleQuery = AllEntityQuery<CargoPilotConsoleComponent>();
while (pilotConsoleQuery.MoveNext(out var uid, out var console))
{
var stationUid = _station.GetOwningStation(uid);
if (stationUid == null || stationUid != component.Station)
continue;
console.Entity = GetShuttleConsole(stationUid.Value);
}
_console.RefreshDroneConsoles();
// Update order consoles.
var shuttleConsoleQuery = AllEntityQuery<CargoShuttleConsoleComponent>();
while (shuttleConsoleQuery.MoveNext(out var uid, out var console))
while (shuttleConsoleQuery.MoveNext(out var uid, out _))
{
var stationUid = _station.GetOwningStation(uid);
if (stationUid != component.Station)
if (stationUid != shuttleUid)
continue;
UpdateShuttleState(uid, stationUid);
@@ -245,21 +156,6 @@ public sealed partial class CargoSystem
#region Shuttle
public EntityUid? GetShuttleConsole(EntityUid uid, CargoShuttleComponent component)
{
var query = AllEntityQuery<ShuttleConsoleComponent, TransformComponent>();
while (query.MoveNext(out var cUid, out var comp, out var xform))
{
if (xform.ParentUid != uid)
continue;
return cUid;
}
return null;
}
/// <summary>
/// Returns the orders that can fit on the cargo shuttle.
/// </summary>
@@ -331,50 +227,6 @@ public sealed partial class CargoSystem
#region Station
private void OnCargoOrderStartup(EntityUid uid, StationCargoOrderDatabaseComponent component, ComponentStartup args)
{
if (!_enabled)
return;
// Stations get created first but if any are added at runtime then do this.
AddShuttle(uid, component);
}
private void AddShuttle(EntityUid stationUid, StationCargoOrderDatabaseComponent component)
{
Setup();
if (CargoMap == null ||
component.Shuttle != null ||
component.CargoShuttleProto == null)
{
return;
}
var prototype = _protoMan.Index<CargoShuttlePrototype>(component.CargoShuttleProto);
var possibleNames = _protoMan.Index<DatasetPrototype>(prototype.NameDataset).Values;
var name = _random.Pick(possibleNames);
if (!_map.TryLoad(CargoMap.Value, prototype.Path.ToString(), out var gridList))
{
_sawmill.Error($"Could not load the cargo shuttle!");
return;
}
var shuttleUid = gridList[0];
var xform = Transform(shuttleUid);
MetaData(shuttleUid).EntityName = name;
// TODO: Something better like a bounds check.
_transform.SetLocalPosition(xform, xform.LocalPosition + 100 * _index);
var comp = EnsureComp<CargoShuttleComponent>(shuttleUid);
comp.Station = stationUid;
component.Shuttle = shuttleUid;
UpdateCargoShuttleConsoles(comp);
_index++;
_sawmill.Info($"Added cargo shuttle to {ToPrettyString(shuttleUid)}");
}
private void SellPallets(EntityUid gridUid, out double amount)
{
GetPalletGoods(gridUid, out var toSell, out amount);
@@ -480,7 +332,7 @@ public sealed partial class CargoSystem
private void OnCargoFTLStarted(EntityUid uid, CargoShuttleComponent component, ref FTLStartedEvent args)
{
var stationUid = component.Station;
var stationUid = _station.GetOwningStation(uid);
// Called
if (CargoMap == null ||
@@ -492,7 +344,7 @@ public sealed partial class CargoSystem
AddCargoContents(uid, component, orderDatabase);
UpdateOrders(orderDatabase);
UpdateCargoShuttleConsoles(component);
UpdateCargoShuttleConsoles(uid, component);
}
private void OnCargoFTLCompleted(EntityUid uid, CargoShuttleComponent component, ref FTLCompletedEvent args)
@@ -502,7 +354,7 @@ public sealed partial class CargoSystem
if (xform.MapID != CargoMap)
return;
var stationUid = component.Station;
var stationUid = _station.GetOwningStation(uid);
if (TryComp<StationBankAccountComponent>(stationUid, out var bank))
{
@@ -515,10 +367,11 @@ public sealed partial class CargoSystem
private void OnRoundRestart(RoundRestartCleanupEvent ev)
{
CleanupShuttle();
CleanupCargoShuttle();
SetupCargoShuttle();
}
private void CleanupShuttle()
private void CleanupCargoShuttle()
{
if (CargoMap == null || !_mapManager.MapExists(CargoMap.Value))
{
@@ -535,7 +388,9 @@ public sealed partial class CargoSystem
while (query.MoveNext(out var uid, out var comp))
{
if (TryComp<StationCargoOrderDatabaseComponent>(comp.Station, out var station))
var stationUid = _station.GetOwningStation(uid);
if (TryComp<StationCargoOrderDatabaseComponent>(uid, out var station))
{
station.Shuttle = null;
}
@@ -543,9 +398,9 @@ public sealed partial class CargoSystem
}
}
private void Setup()
private void SetupCargoShuttle()
{
if (!_enabled || CargoMap != null && _mapManager.MapExists(CargoMap.Value))
if (CargoMap != null && _mapManager.MapExists(CargoMap.Value))
{
return;
}
@@ -564,13 +419,6 @@ public sealed partial class CargoSystem
MetaData(mapUid).EntityName = $"Trading post {_random.Next(1000):000}";
var query = AllEntityQuery<StationCargoOrderDatabaseComponent>();
while (query.MoveNext(out var uid, out var comp))
{
AddShuttle(uid, comp);
}
_console.RefreshShuttleConsoles();
}
}

View File

@@ -27,8 +27,7 @@ public sealed partial class CargoSystem : SharedCargoSystem
public override void Shutdown()
{
base.Shutdown();
ShutdownShuttle();
CleanupShuttle();
CleanupCargoShuttle();
}
public override void Update(float frameTime)
@@ -39,19 +38,21 @@ public sealed partial class CargoSystem : SharedCargoSystem
}
[PublicAPI]
public void UpdateBankAccount(StationBankAccountComponent component, int balanceAdded)
public void UpdateBankAccount(EntityUid uid, StationBankAccountComponent component, int balanceAdded)
{
component.Balance += balanceAdded;
// TODO: Code bad
foreach (var comp in EntityQuery<CargoOrderConsoleComponent>())
{
if (!_uiSystem.IsUiOpen(comp.Owner, CargoConsoleUiKey.Orders)) continue;
var query = EntityQueryEnumerator<CargoOrderConsoleComponent>();
var station = _station.GetOwningStation(comp.Owner);
if (station != component.Owner)
while (query.MoveNext(out var oUid, out var oComp))
{
if (!_uiSystem.IsUiOpen(oUid, CargoConsoleUiKey.Orders))
continue;
UpdateOrderState(comp, station);
var station = _station.GetOwningStation(oUid);
if (station != uid)
continue;
UpdateOrderState(oComp, station);
}
}
}

View File

@@ -1,4 +1,5 @@
using Content.Server.Cargo.Components;
using Content.Server.Shuttle.Components;
using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Systems;
using Content.Shared.Movement.Components;
@@ -254,7 +255,7 @@ namespace Content.Server.Physics.Controllers
var consoleEnt = pilot.Console?.Owner;
// TODO: This is terrible. Just make a new mover and also make it remote piloting + device networks
if (TryComp<CargoPilotConsoleComponent>(consoleEnt, out var cargoConsole))
if (TryComp<DroneConsoleComponent>(consoleEnt, out var cargoConsole))
{
consoleEnt = cargoConsole.Entity;
}

View File

@@ -0,0 +1,10 @@
namespace Content.Server.Salvage.Expeditions;
/// <summary>
/// Added to salvage shuttle. Used for drone control.
/// </summary>
[RegisterComponent]
public sealed class SalvageShuttleComponent : Component
{
}

View File

@@ -0,0 +1,21 @@
using Content.Server.Shuttles.Components;
using Robust.Shared.Prototypes;
namespace Content.Server.Shuttle.Components;
// Primo shitcode
/// <summary>
/// Lets you remotely control a shuttle.
/// </summary>
[RegisterComponent]
public sealed class DroneConsoleComponent : Component
{
[DataField("components", required: true)]
public ComponentRegistry Components = default!;
/// <summary>
/// <see cref="ShuttleConsoleComponent"/> that we're proxied into.
/// </summary>
[DataField("entity")]
public EntityUid? Entity;
}

View File

@@ -0,0 +1,13 @@
using Content.Server.Shuttles.Systems;
using Robust.Shared.Utility;
namespace Content.Server.Shuttles.Components;
/// <summary>
/// Similar to <see cref="GridFillComponent"/> except spawns the grid near to the station.
/// </summary>
[RegisterComponent, Access(typeof(ShuttleSystem))]
public sealed class GridSpawnComponent : Component
{
[DataField("paths", required: true)] public List<ResPath> Paths = new();
}

View File

@@ -8,5 +8,8 @@ namespace Content.Server.Shuttles.Events;
[ByRefEvent]
public struct ConsoleShuttleEvent
{
/// <summary>
/// Console that we proxy into.
/// </summary>
public EntityUid? Console;
}

View File

@@ -0,0 +1,75 @@
using Content.Server.Shuttle.Components;
using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Events;
using Content.Server.Station.Components;
using Content.Server.UserInterface;
namespace Content.Server.Shuttles.Systems;
public sealed partial class ShuttleConsoleSystem
{
/// <summary>
/// Refreshes all drone console entities.
/// </summary>
public void RefreshDroneConsoles()
{
var query = AllEntityQuery<DroneConsoleComponent>();
while (query.MoveNext(out var uid, out var comp))
{
comp.Entity = GetShuttleConsole(uid, comp);
}
}
private void OnDronePilotConsoleOpen(EntityUid uid, DroneConsoleComponent component, AfterActivatableUIOpenEvent args)
{
component.Entity = GetShuttleConsole(uid);
}
private void OnDronePilotConsoleClose(EntityUid uid, DroneConsoleComponent component, BoundUIClosedEvent args)
{
component.Entity = null;
}
private void OnCargoGetConsole(EntityUid uid, DroneConsoleComponent component, ref ConsoleShuttleEvent args)
{
args.Console = GetShuttleConsole(uid, component);
}
/// <summary>
/// Gets the relevant shuttle console to proxy from the drone console.
/// </summary>
private EntityUid? GetShuttleConsole(EntityUid uid, DroneConsoleComponent? component = null)
{
if (!Resolve(uid, ref component))
return null;
var stationUid = _station.GetOwningStation(uid);
if (stationUid == null)
return null;
// I know this sucks but needs device linking or something idunno
var query = AllEntityQuery<ShuttleConsoleComponent, TransformComponent>();
while (query.MoveNext(out var cUid, out _, out var xform))
{
if (xform.GridUid == null ||
!TryComp<StationMemberComponent>(xform.GridUid, out var member) ||
member.Station != stationUid)
{
continue;
}
foreach (var compType in component.Components.Values)
{
if (!HasComp(xform.GridUid, compType.Component.GetType()))
continue;
return cUid;
}
}
return null;
}
}

View File

@@ -1,7 +1,9 @@
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.Shuttle.Components;
using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Events;
using Content.Server.Station.Systems;
using Content.Server.UserInterface;
using Content.Shared.ActionBlocker;
using Content.Shared.Alert;
@@ -21,13 +23,14 @@ using Robust.Shared.Utility;
namespace Content.Server.Shuttles.Systems;
public sealed class ShuttleConsoleSystem : SharedShuttleConsoleSystem
public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
[Dependency] private readonly AlertsSystem _alertsSystem = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly ShuttleSystem _shuttle = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly TagSystem _tags = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!;
@@ -42,6 +45,10 @@ public sealed class ShuttleConsoleSystem : SharedShuttleConsoleSystem
SubscribeLocalEvent<ShuttleConsoleComponent, ShuttleConsoleFTLRequestMessage>(OnDestinationMessage);
SubscribeLocalEvent<ShuttleConsoleComponent, BoundUIClosedEvent>(OnConsoleUIClose);
SubscribeLocalEvent<DroneConsoleComponent, ConsoleShuttleEvent>(OnCargoGetConsole);
SubscribeLocalEvent<DroneConsoleComponent, AfterActivatableUIOpenEvent>(OnDronePilotConsoleOpen);
SubscribeLocalEvent<DroneConsoleComponent, BoundUIClosedEvent>(OnDronePilotConsoleClose);
SubscribeLocalEvent<DockEvent>(OnDock);
SubscribeLocalEvent<UndockEvent>(OnUndock);

View File

@@ -1,5 +1,7 @@
using Content.Server.Shuttles.Components;
using Content.Server.Station.Components;
using Content.Server.Station.Events;
using Content.Shared.Cargo.Components;
using Content.Shared.CCVar;
namespace Content.Server.Shuttles.Systems;
@@ -8,11 +10,88 @@ public sealed partial class ShuttleSystem
{
private void InitializeGridFills()
{
SubscribeLocalEvent<GridSpawnComponent, StationPostInitEvent>(OnGridSpawnPostInit);
SubscribeLocalEvent<GridFillComponent, MapInitEvent>(OnGridFillMapInit);
_cfg.OnValueChanged(CCVars.GridFill, OnGridFillChange);
}
private void ShutdownGridFills()
{
_cfg.UnsubValueChanged(CCVars.GridFill, OnGridFillChange);
}
private void OnGridFillChange(bool obj)
{
// If you're doing this on live then god help you,
if (obj)
{
var query = AllEntityQuery<GridSpawnComponent>();
while (query.MoveNext(out var uid, out var comp))
{
GridSpawns(uid, comp);
}
}
}
private void OnGridSpawnPostInit(EntityUid uid, GridSpawnComponent component, ref StationPostInitEvent args)
{
GridSpawns(uid, component);
}
private void GridSpawns(EntityUid uid, GridSpawnComponent component)
{
if (!_cfg.GetCVar(CCVars.GridFill))
return;
if (!TryComp<StationDataComponent>(uid, out var data))
{
return;
}
var targetGrid = _station.GetLargestGrid(data);
if (targetGrid == null)
return;
// Spawn on a dummy map and try to FTL if possible, otherwise dump it.
var mapId = _mapManager.CreateMap();
var valid = true;
foreach (var path in component.Paths)
{
if (_loader.TryLoad(mapId, path.ToString(), out var ent) && ent.Count == 1)
{
if (TryComp<ShuttleComponent>(ent[0], out var shuttle))
{
TryFTLProximity(ent[0], shuttle, targetGrid.Value);
_station.AddGridToStation(uid, ent[0]);
}
else
{
valid = false;
}
}
else
{
valid = false;
}
if (!valid)
{
_sawmill.Error($"Error loading gridspawn for {ToPrettyString(uid)} / {path}");
}
}
_mapManager.DeleteMap(mapId);
}
private void OnGridFillMapInit(EntityUid uid, GridFillComponent component, MapInitEvent args)
{
if (!_cfg.GetCVar(CCVars.GridFill))
return;
if (!TryComp<DockingComponent>(uid, out var dock) ||
!TryComp<TransformComponent>(uid, out var xform) ||
xform.GridUid == null)
@@ -20,9 +99,6 @@ public sealed partial class ShuttleSystem
return;
}
if (_cfg.GetCVar(CCVars.DisableGridFill))
return;
// Spawn on a dummy map and try to dock if possible, otherwise dump it.
var mapId = _mapManager.CreateMap();
var valid = false;

View File

@@ -67,6 +67,13 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem
SubscribeLocalEvent<FixturesComponent, GridFixtureChangeEvent>(OnGridFixtureChange);
}
public override void Shutdown()
{
base.Shutdown();
ShutdownGridFills();
}
public override void Update(float frameTime)
{
base.Update(frameTime);

View File

@@ -0,0 +1,7 @@
namespace Content.Server.Station.Events;
/// <summary>
/// Raised directed on a station after it has been initialized.
/// </summary>
[ByRefEvent]
public readonly record struct StationPostInitEvent;

View File

@@ -2,6 +2,7 @@ using System.Linq;
using Content.Server.Chat.Systems;
using Content.Server.GameTicking;
using Content.Server.Station.Components;
using Content.Server.Station.Events;
using Content.Shared.CCVar;
using Content.Shared.Station;
using JetBrains.Annotations;
@@ -304,6 +305,9 @@ public sealed class StationSystem : EntitySystem
AddGridToStation(station, grid, null, data, name);
}
var ev = new StationPostInitEvent();
RaiseLocalEvent(station, ref ev);
return station;
}

View File

@@ -1096,17 +1096,11 @@ namespace Content.Shared.CCVar
public static readonly CVarDef<bool> ArrivalsReturns =
CVarDef.Create("shuttle.arrivals_returns", false, CVar.SERVERONLY);
/// <summary>
/// Whether cargo shuttles are enabled.
/// </summary>
public static readonly CVarDef<bool> CargoShuttles =
CVarDef.Create("shuttle.cargo", true, CVar.SERVERONLY);
/// <summary>
/// Whether to automatically spawn escape shuttles.
/// </summary>
public static readonly CVarDef<bool> DisableGridFill =
CVarDef.Create("shuttle.disable_grid_fill", false, CVar.SERVERONLY);
public static readonly CVarDef<bool> GridFill =
CVarDef.Create("shuttle.grid_fill", true, CVar.SERVERONLY);
/*
* Emergency

View File

@@ -1,4 +1,4 @@
using Robust.Shared.Map;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -7,15 +7,9 @@ namespace Content.Shared.Cargo.Components;
/// <summary>
/// Present on cargo shuttles to provide metadata such as preventing spam calling.
/// </summary>
[RegisterComponent, Access(typeof(SharedCargoSystem))]
[RegisterComponent, NetworkedComponent, Access(typeof(SharedCargoSystem))]
public sealed class CargoShuttleComponent : Component
{
/// <summary>
/// The assigned station for this cargo shuttle.
/// </summary>
[DataField("station")]
public EntityUid? Station;
/// <summary>
/// The paper-type prototype to spawn with the order information.
/// </summary>

View File

@@ -1,20 +0,0 @@
using Content.Shared.Dataset;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Utility;
namespace Content.Shared.Cargo.Prototypes;
[Prototype("cargoShuttle")]
public sealed class CargoShuttlePrototype : IPrototype
{
[ViewVariables]
[IdDataField]
public string ID { get; } = default!;
[DataField("path")]
public ResPath Path = default!;
[DataField("nameDataset", customTypeSerializer:typeof(PrototypeIdSerializer<DatasetPrototype>))]
public string NameDataset = "CargoShuttleNames";
}

View File

@@ -17,8 +17,7 @@ expedition_cooldown = 30.0
expedition_failed_cooldown = 30.0
[shuttle]
# Wastes startup time
grid_fill = false
auto_call_time = 0
cargo = false
emergency = false
arrivals = false

View File

@@ -14,6 +14,7 @@ entities:
- uid: 173
components:
- type: MetaData
name: Cargo shuttle
- pos: 2.2710133,-2.4148211
parent: invalid
type: Transform
@@ -37,10 +38,10 @@ entities:
fixedRotation: False
bodyType: Dynamic
type: Physics
- gravityShakeSound: !type:SoundPathSpecifier
path: /Audio/Effects/alert.ogg
type: Gravity
- type: CargoShuttle
- chunkCollection:
version: 2
nodes:

View File

@@ -37,7 +37,7 @@ entities:
fixedRotation: False
bodyType: Dynamic
type: Physics
- type: SalvageShuttle
- gravityShakeSound: !type:SoundPathSpecifier
path: /Audio/Effects/alert.ogg
type: Gravity

View File

@@ -19,6 +19,7 @@
- id: CargoRequestComputerCircuitboard
- id: CargoShuttleComputerCircuitboard
- id: CargoShuttleConsoleCircuitboard
- id: SalvageShuttleConsoleCircuitboard
- id: CigPackGreen
prob: 0.50
- id: DoorRemoteCargo
@@ -59,7 +60,7 @@
- id: WeaponAntiqueLaser
- id: JetpackCaptainFilled
- id: MedalCase
- type: entity
id: LockerCaptainFilled
suffix: Filled

View File

@@ -1,5 +1,5 @@
- type: dataset
id: CargoShuttleNames
id: ShuttleNames
values:
- A Shuttle Will Not Occur
- Big Money Shuttle
@@ -8,4 +8,4 @@
- Shootel
- Shuttle McShuttleface
- ShuttleShuttle
- Urist McShuttle
- Urist McShuttle

View File

@@ -103,12 +103,21 @@
- type: entity
parent: BaseComputerCircuitboard
id: CargoShuttleConsoleCircuitboard
name: supply shuttle console board
name: cargo shuttle console board
description: A computer printed circuit board for a cargo shuttle console.
components:
- type: ComputerBoard
prototype: ComputerShuttleCargo
- type: entity
parent: BaseComputerCircuitboard
id: SalvageShuttleConsoleCircuitboard
name: salvage shuttle console board
description: A computer printed circuit board for a salvage shuttle console.
components:
- type: ComputerBoard
prototype: ComputerShuttleSalvage
- type: entity
parent: BaseComputerCircuitboard
id: SurveillanceCameraMonitorCircuitboard

View File

@@ -31,6 +31,15 @@
components:
- type: StationArrivals
- type: entity
id: BaseStationShuttles
abstract: true
components:
- type: GridSpawn
paths:
- /Maps/Shuttles/cargo.yml
- /Maps/Shuttles/mining.yml
- type: entity
id: BaseStationCentcomm
abstract: true

View File

@@ -14,6 +14,7 @@
- BaseStationJobsSpawning
- BaseStationRecords
- BaseStationArrivals
- BaseStationShuttles
- BaseStationCentcomm
- BaseStationEvacuation
- BaseStationAlertLevels

View File

@@ -129,7 +129,9 @@
state: shuttle
- map: ["computerLayerKeys"]
state: generic_keys
- type: CargoPilotConsole
- type: DroneConsole
components:
- type: CargoShuttle
- type: RadarConsole
maxRange: 256
- type: PointLight
@@ -139,6 +141,34 @@
- type: Computer
board: CargoShuttleConsoleCircuitboard
- type: entity
parent: BaseComputerShuttle
id: ComputerShuttleSalvage
name: salvage shuttle console
description: Used to pilot the salvage shuttle.
components:
- type: Sprite
layers:
- map: ["computerLayerBody"]
state: computer
- map: ["computerLayerKeyboard"]
state: generic_keyboard
- map: ["computerLayerScreen"]
state: shuttle
- map: ["computerLayerKeys"]
state: generic_keys
- type: DroneConsole
components:
- type: SalvageShuttle
- type: RadarConsole
maxRange: 256
- type: PointLight
radius: 1.5
energy: 1.6
color: "#c94242"
- type: Computer
board: SalvageShuttleConsoleCircuitboard
- type: entity
parent: BaseComputer
id: ComputerIFF

View File

@@ -1,4 +0,0 @@
# Cargo
- type: cargoShuttle
id: CargoShuttle
path: /Maps/Shuttles/cargo.yml