Fix Centcomm (#16772)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using Content.Server.Access.Systems;
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Administration.Managers;
|
||||
@@ -23,7 +23,6 @@ using Robust.Shared.Map;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Shuttles.Systems;
|
||||
|
||||
@@ -54,14 +53,6 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
|
||||
public MapId? CentComMap { get; private set; }
|
||||
public EntityUid? CentComGrid { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used for multiple shuttle spawn offsets.
|
||||
/// </summary>
|
||||
private float _shuttleIndex;
|
||||
|
||||
private const float ShuttleSpawnBuffer = 1f;
|
||||
|
||||
private bool _emergencyShuttleEnabled;
|
||||
@@ -76,14 +67,35 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
||||
_configManager.OnValueChanged(CCVars.EmergencyShuttleEnabled, SetEmergencyShuttleEnabled);
|
||||
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStart);
|
||||
SubscribeLocalEvent<StationEmergencyShuttleComponent, ComponentStartup>(OnStationStartup);
|
||||
SubscribeLocalEvent<StationCentcommComponent, ComponentShutdown>(OnCentcommShutdown);
|
||||
SubscribeLocalEvent<StationCentcommComponent, ComponentInit>(OnCentcommInit);
|
||||
SubscribeNetworkEvent<EmergencyShuttleRequestPositionMessage>(OnShuttleRequestPosition);
|
||||
InitializeEmergencyConsole();
|
||||
}
|
||||
|
||||
private void OnRoundStart(RoundStartingEvent ev)
|
||||
{
|
||||
CleanupEmergencyConsole();
|
||||
_roundEndCancelToken?.Cancel();
|
||||
_roundEndCancelToken = new CancellationTokenSource();
|
||||
}
|
||||
|
||||
private void OnCentcommShutdown(EntityUid uid, StationCentcommComponent component, ComponentShutdown args)
|
||||
{
|
||||
QueueDel(component.Entity);
|
||||
component.Entity = EntityUid.Invalid;
|
||||
|
||||
if (_mapManager.MapExists(component.MapId))
|
||||
_mapManager.DeleteMap(component.MapId);
|
||||
|
||||
component.MapId = MapId.Nullspace;
|
||||
}
|
||||
|
||||
private void SetEmergencyShuttleEnabled(bool value)
|
||||
{
|
||||
if (_emergencyShuttleEnabled == value)
|
||||
return;
|
||||
|
||||
_emergencyShuttleEnabled = value;
|
||||
|
||||
if (value)
|
||||
@@ -96,6 +108,16 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
private void CleanupEmergencyShuttle()
|
||||
{
|
||||
var query = AllEntityQuery<StationCentcommComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out _))
|
||||
{
|
||||
RemCompDeferred<StationCentcommComponent>(uid);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
@@ -146,22 +168,22 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// Calls the emergency shuttle for the station.
|
||||
/// </summary>
|
||||
public void CallEmergencyShuttle(EntityUid? stationUid)
|
||||
public void CallEmergencyShuttle(EntityUid stationUid, StationEmergencyShuttleComponent? stationShuttle = null)
|
||||
{
|
||||
if (!TryComp<StationEmergencyShuttleComponent>(stationUid, out var stationShuttle) ||
|
||||
if (!Resolve(stationUid, ref stationShuttle) ||
|
||||
!TryComp<TransformComponent>(stationShuttle.EmergencyShuttle, out var xform) ||
|
||||
!TryComp<ShuttleComponent>(stationShuttle.EmergencyShuttle, out var shuttle))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var targetGrid = _station.GetLargestGrid(Comp<StationDataComponent>(stationUid.Value));
|
||||
var targetGrid = _station.GetLargestGrid(Comp<StationDataComponent>(stationUid));
|
||||
|
||||
// UHH GOOD LUCK
|
||||
if (targetGrid == null)
|
||||
{
|
||||
_logger.Add(LogType.EmergencyShuttle, LogImpact.High, $"Emergency shuttle {ToPrettyString(stationUid.Value)} unable to dock with station {ToPrettyString(stationUid.Value)}");
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid.Value, Loc.GetString("emergency-shuttle-good-luck"), playDefaultSound: false);
|
||||
_logger.Add(LogType.EmergencyShuttle, LogImpact.High, $"Emergency shuttle {ToPrettyString(stationUid)} unable to dock with station {ToPrettyString(stationUid)}");
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid, Loc.GetString("emergency-shuttle-good-luck"), playDefaultSound: false);
|
||||
// TODO: Need filter extensions or something don't blame me.
|
||||
_audio.PlayGlobal("/Audio/Misc/notice1.ogg", Filter.Broadcast(), true);
|
||||
return;
|
||||
@@ -174,10 +196,10 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
||||
if (TryComp<TransformComponent>(targetGrid.Value, out var targetXform))
|
||||
{
|
||||
var angle = _dock.GetAngle(stationShuttle.EmergencyShuttle.Value, xform, targetGrid.Value, targetXform, xformQuery);
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid.Value, Loc.GetString("emergency-shuttle-docked", ("time", $"{_consoleAccumulator:0}"), ("direction", angle.GetDir())), playDefaultSound: false);
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid, Loc.GetString("emergency-shuttle-docked", ("time", $"{_consoleAccumulator:0}"), ("direction", angle.GetDir())), playDefaultSound: false);
|
||||
}
|
||||
|
||||
_logger.Add(LogType.EmergencyShuttle, LogImpact.High, $"Emergency shuttle {ToPrettyString(stationUid.Value)} docked with stations");
|
||||
_logger.Add(LogType.EmergencyShuttle, LogImpact.High, $"Emergency shuttle {ToPrettyString(stationUid)} docked with stations");
|
||||
// TODO: Need filter extensions or something don't blame me.
|
||||
_audio.PlayGlobal("/Audio/Announcements/shuttle_dock.ogg", Filter.Broadcast(), true);
|
||||
}
|
||||
@@ -186,35 +208,33 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
||||
if (TryComp<TransformComponent>(targetGrid.Value, out var targetXform))
|
||||
{
|
||||
var angle = _dock.GetAngle(stationShuttle.EmergencyShuttle.Value, xform, targetGrid.Value, targetXform, xformQuery);
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid.Value, Loc.GetString("emergency-shuttle-nearby", ("direction", angle.GetDir())), playDefaultSound: false);
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid, Loc.GetString("emergency-shuttle-nearby", ("direction", angle.GetDir())), playDefaultSound: false);
|
||||
}
|
||||
|
||||
_logger.Add(LogType.EmergencyShuttle, LogImpact.High, $"Emergency shuttle {ToPrettyString(stationUid.Value)} unable to find a valid docking port for {ToPrettyString(stationUid.Value)}");
|
||||
_logger.Add(LogType.EmergencyShuttle, LogImpact.High, $"Emergency shuttle {ToPrettyString(stationUid)} unable to find a valid docking port for {ToPrettyString(stationUid)}");
|
||||
// TODO: Need filter extensions or something don't blame me.
|
||||
_audio.PlayGlobal("/Audio/Misc/notice1.ogg", Filter.Broadcast(), true);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStationStartup(EntityUid uid, StationEmergencyShuttleComponent component, ComponentStartup args)
|
||||
private void OnCentcommInit(EntityUid uid, StationCentcommComponent component, ComponentInit args)
|
||||
{
|
||||
AddEmergencyShuttle(component);
|
||||
if (!_emergencyShuttleEnabled)
|
||||
return;
|
||||
|
||||
// Post mapinit? fancy
|
||||
if (TryComp<TransformComponent>(component.Entity, out var xform))
|
||||
{
|
||||
component.MapId = xform.MapID;
|
||||
return;
|
||||
}
|
||||
|
||||
AddCentcomm(component);
|
||||
}
|
||||
|
||||
private void OnRoundStart(RoundStartingEvent ev)
|
||||
private void OnStationStartup(EntityUid uid, StationEmergencyShuttleComponent component, ComponentStartup args)
|
||||
{
|
||||
if (CentComMap != null)
|
||||
_mapManager.DeleteMap(CentComMap.Value);
|
||||
|
||||
// Just in case the grid isn't on the map.
|
||||
DebugTools.Assert(Deleted(CentComGrid));
|
||||
if (CentComGrid != null)
|
||||
Del(CentComGrid.Value);
|
||||
|
||||
CentComGrid = null;
|
||||
CentComMap = null;
|
||||
|
||||
CleanupEmergencyConsole();
|
||||
SetupEmergencyShuttle();
|
||||
AddEmergencyShuttle(uid, component);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -234,14 +254,11 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
||||
_consoleAccumulator = _configManager.GetCVar(CCVars.EmergencyShuttleDockTime);
|
||||
EmergencyShuttleArrived = true;
|
||||
|
||||
if (CentComMap != null)
|
||||
_mapManager.SetMapPaused(CentComMap.Value, false);
|
||||
|
||||
var query = AllEntityQuery<StationDataComponent>();
|
||||
var query = AllEntityQuery<StationEmergencyShuttleComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out var comp))
|
||||
{
|
||||
CallEmergencyShuttle(uid);
|
||||
CallEmergencyShuttle(uid, comp);
|
||||
}
|
||||
|
||||
_commsConsole.UpdateCommsConsoleInterface();
|
||||
@@ -249,80 +266,111 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
||||
|
||||
private void SetupEmergencyShuttle()
|
||||
{
|
||||
if (!_emergencyShuttleEnabled || CentComMap != null && _mapManager.MapExists(CentComMap.Value)) return;
|
||||
if (!_emergencyShuttleEnabled)
|
||||
return;
|
||||
|
||||
CentComMap = _mapManager.CreateMap();
|
||||
_mapManager.SetMapPaused(CentComMap.Value, true);
|
||||
var centcommQuery = AllEntityQuery<StationCentcommComponent>();
|
||||
|
||||
// Load CentCom
|
||||
var centComPath = _configManager.GetCVar(CCVars.CentcommMap);
|
||||
|
||||
if (!string.IsNullOrEmpty(centComPath))
|
||||
while (centcommQuery.MoveNext(out var centcomm))
|
||||
{
|
||||
var centcomm = _map.LoadGrid(CentComMap.Value, "/Maps/centcomm.yml");
|
||||
CentComGrid = centcomm;
|
||||
|
||||
if (CentComGrid != null)
|
||||
_shuttle.AddFTLDestination(CentComGrid.Value, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_sawmill.Info("No CentCom map found, skipping setup.");
|
||||
AddCentcomm(centcomm);
|
||||
}
|
||||
|
||||
foreach (var comp in EntityQuery<StationEmergencyShuttleComponent>(true))
|
||||
var query = AllEntityQuery<StationEmergencyShuttleComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out var comp))
|
||||
{
|
||||
AddEmergencyShuttle(comp);
|
||||
AddEmergencyShuttle(uid, comp);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddEmergencyShuttle(StationEmergencyShuttleComponent component)
|
||||
private void AddCentcomm(StationCentcommComponent component)
|
||||
{
|
||||
// Check for existing centcomms and just point to that
|
||||
var query = AllEntityQuery<StationCentcommComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out var otherComp))
|
||||
{
|
||||
if (otherComp == component)
|
||||
continue;
|
||||
|
||||
component.MapId = otherComp.MapId;
|
||||
component.ShuttleIndex = otherComp.ShuttleIndex;
|
||||
return;
|
||||
}
|
||||
|
||||
var mapId = _mapManager.CreateMap();
|
||||
component.MapId = mapId;
|
||||
|
||||
if (!string.IsNullOrEmpty(component.Map.ToString()))
|
||||
{
|
||||
var ent = _map.LoadGrid(mapId, component.Map.ToString());
|
||||
|
||||
if (ent != null)
|
||||
{
|
||||
component.Entity = ent.Value;
|
||||
_shuttle.AddFTLDestination(ent.Value, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_sawmill.Warning("No CentComm map found, skipping setup.");
|
||||
}
|
||||
}
|
||||
|
||||
public HashSet<MapId> GetCentcommMaps()
|
||||
{
|
||||
var query = AllEntityQuery<StationCentcommComponent>();
|
||||
var maps = new HashSet<MapId>(Count<StationCentcommComponent>());
|
||||
|
||||
while (query.MoveNext(out var comp))
|
||||
{
|
||||
maps.Add(comp.MapId);
|
||||
}
|
||||
|
||||
return maps;
|
||||
}
|
||||
|
||||
private void AddEmergencyShuttle(EntityUid uid, StationEmergencyShuttleComponent component)
|
||||
{
|
||||
if (!_emergencyShuttleEnabled
|
||||
|| CentComMap == null
|
||||
|| component.EmergencyShuttle != null)
|
||||
|| component.EmergencyShuttle != null ||
|
||||
!TryComp<StationCentcommComponent>(uid, out var centcomm))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Load escape shuttle
|
||||
var shuttlePath = component.EmergencyShuttlePath;
|
||||
var shuttle = _map.LoadGrid(CentComMap.Value, shuttlePath.ToString(), new MapLoadOptions()
|
||||
var shuttle = _map.LoadGrid(centcomm.MapId, shuttlePath.ToString(), new MapLoadOptions()
|
||||
{
|
||||
// Should be far enough... right? I'm too lazy to bounds check CentCom rn.
|
||||
Offset = new Vector2(500f + _shuttleIndex, 0f)
|
||||
Offset = new Vector2(500f + centcomm.ShuttleIndex, 0f)
|
||||
});
|
||||
|
||||
if (shuttle == null)
|
||||
{
|
||||
_sawmill.Error($"Unable to spawn emergency shuttle {shuttlePath} for {ToPrettyString(component.Owner)}");
|
||||
_sawmill.Error($"Unable to spawn emergency shuttle {shuttlePath} for {ToPrettyString(uid)}");
|
||||
return;
|
||||
}
|
||||
|
||||
_shuttleIndex += _mapManager.GetGrid(shuttle.Value).LocalAABB.Width + ShuttleSpawnBuffer;
|
||||
centcomm.ShuttleIndex += _mapManager.GetGrid(shuttle.Value).LocalAABB.Width + ShuttleSpawnBuffer;
|
||||
|
||||
// Update indices for all centcomm comps pointing to same map
|
||||
var query = AllEntityQuery<StationCentcommComponent>();
|
||||
|
||||
while (query.MoveNext(out var comp))
|
||||
{
|
||||
if (comp == centcomm || comp.MapId != centcomm.MapId)
|
||||
continue;
|
||||
|
||||
comp.ShuttleIndex = comp.ShuttleIndex;
|
||||
}
|
||||
|
||||
component.EmergencyShuttle = shuttle;
|
||||
EnsureComp<ProtectedGridComponent>(shuttle.Value);
|
||||
}
|
||||
|
||||
private void CleanupEmergencyShuttle()
|
||||
{
|
||||
// If we get cleaned up mid roundend just end it.
|
||||
if (_launchedShuttles)
|
||||
{
|
||||
_roundEnd.EndRound();
|
||||
}
|
||||
|
||||
_shuttleIndex = 0f;
|
||||
|
||||
if (CentComMap == null || !_mapManager.MapExists(CentComMap.Value))
|
||||
{
|
||||
CentComMap = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_mapManager.DeleteMap(CentComMap.Value);
|
||||
}
|
||||
|
||||
private void OnEscapeUnpaused(EntityUid uid, EscapePodComponent component, ref EntityUnpausedEvent args)
|
||||
{
|
||||
if (component.LaunchTime == null)
|
||||
|
||||
Reference in New Issue
Block a user