Fix Centcomm (#16772)

This commit is contained in:
metalgearsloth
2023-05-24 21:28:44 +10:00
committed by GitHub
parent b1596c9f18
commit af5eaec932
9 changed files with 232 additions and 130 deletions

View File

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