Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Content.Server.Communications;
using Content.Server.DeviceNetwork.Systems;
using Content.Server.GameTicking.Events;
using Content.Server._HL.Cleanup;
using Content.Server.Pinpointer;
using Content.Server.Popups;
using Content.Server.RoundEnd;
Expand Down Expand Up @@ -81,6 +82,8 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
private EntityUid? _singletonColcommMap;
private EntityUid? _singletonColcommGrid;
private EntityUid? _singletonColcommShuttle;
private TimeSpan _nextColcommValidation;
private static readonly TimeSpan ColcommValidationInterval = TimeSpan.FromSeconds(30);

public override void Initialize()
{
Expand Down Expand Up @@ -165,6 +168,72 @@ public override void Update(float frameTime)
{
base.Update(frameTime);
UpdateEmergencyConsole(frameTime);
ValidateColcommState();
}

private void ValidateColcommState()
{
if (_timing.CurTime < _nextColcommValidation)
return;

_nextColcommValidation = _timing.CurTime + ColcommValidationInterval;

var singletonValid = _singletonColcommMap != null && _singletonColcommGrid != null
&& Exists(_singletonColcommMap.Value) && Exists(_singletonColcommGrid.Value);
var needsRespawn = false;

var query = AllEntityQuery<StationColcommComponent>();
while (query.MoveNext(out var _, out var colcomm))
{
if (colcomm.Entity != null && Exists(colcomm.Entity.Value))
{
EnsureComp<CleanupProtectedGridComponent>(colcomm.Entity.Value);

if (TryComp(colcomm.Entity.Value, out TransformComponent? xform) && xform.MapUid != null)
colcomm.MapEntity = xform.MapUid;

if (!singletonValid)
{
_singletonColcommGrid = colcomm.Entity;
_singletonColcommMap = colcomm.MapEntity;
singletonValid = _singletonColcommMap != null && _singletonColcommGrid != null
&& Exists(_singletonColcommMap.Value) && Exists(_singletonColcommGrid.Value);
}

continue;
}

if (singletonValid)
{
colcomm.Entity = _singletonColcommGrid;
colcomm.MapEntity = _singletonColcommMap;
continue;
}

colcomm.Entity = null;
colcomm.MapEntity = null;
needsRespawn = true;
}

if (needsRespawn)
RespawnColcommViaSpawnPath();
}

private void RespawnColcommViaSpawnPath()
{
_singletonColcommMap = null;
_singletonColcommGrid = null;
_singletonColcommShuttle = null;

var query = AllEntityQuery<StationColcommComponent>();
while (query.MoveNext(out var _, out var colcomm))
{
colcomm.Entity = null;
colcomm.MapEntity = null;
}

// Reuse the normal startup flow to restore ColComm + shuttle consistently.
SetupEmergencyShuttle();
}

/// <summary>
Expand Down Expand Up @@ -516,6 +585,7 @@ private void AddColcomm(EntityUid station, StationColcommComponent component)
{
component.MapEntity = _singletonColcommMap;
component.Entity = _singletonColcommGrid;
EnsureComp<CleanupProtectedGridComponent>(_singletonColcommGrid.Value);
return;
}

Expand Down Expand Up @@ -544,6 +614,7 @@ private void AddColcomm(EntityUid station, StationColcommComponent component)
component.Entity = grid;
_singletonColcommMap = map;
_singletonColcommGrid = grid;
EnsureComp<CleanupProtectedGridComponent>(grid.Value);
_metaData.SetEntityName(map, Loc.GetString("map-name-Colcomm"));
_shuttle.TryAddFTLDestination(mapId, true, out _);
Log.Info($"Created Colcomm grid {ToPrettyString(grid)} on map {ToPrettyString(map)} for station {ToPrettyString(station)}");
Expand Down Expand Up @@ -618,6 +689,7 @@ private void AddEmergencyShuttle(Entity<StationEmergencyShuttleComponent?, Stati
ent.Comp1.EmergencyShuttle = shuttle;
_singletonColcommShuttle = shuttle; // Store singleton
EnsureComp<ProtectedGridComponent>(shuttle.Value);
EnsureComp<CleanupProtectedGridComponent>(shuttle.Value);
EnsureComp<PreventPilotComponent>(shuttle.Value);
EnsureComp<EmergencyShuttleComponent>(shuttle.Value);

Expand Down
4 changes: 4 additions & 0 deletions Content.Server/Trash/TrashCleanupSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ private bool ShouldProtectGrid(EntityUid gridUid)
if (HasComp<StationMemberComponent>(gridUid))
return true;

// A grid with a world loader is an active world-loading anchor and should never be trash-cleaned.
if (HasComp<WorldLoaderComponent>(gridUid))
return true;

// Protect grids with important components that indicate they shouldn't be deleted
if (HasComp<WorldControllerComponent>(gridUid) || HasComp<CleanupProtectedGridComponent>(gridUid))
return true;
Expand Down
1 change: 1 addition & 0 deletions Resources/Maps/colcomm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ entities:
- type: GridPathfinding
- type: BecomesStation
id: Colcomm
- type: CleanupProtectedGrid
- type: Gravity
gravityShakeSound: !type:SoundPathSpecifier
path: /Audio/Effects/alert.ogg
Expand Down
Loading