await data.Pair.CleanReturnAsync();
}
+ [Test]
+ public async Task TestGhostGridNotTerminating()
+ {
+ var data = await SetupData();
+
+ Assert.DoesNotThrowAsync(async () =>
+ {
+ // Delete the grid
+ await data.Server.WaitPost(() => data.SEntMan.DeleteEntity(data.MapData.Grid.Owner));
+ });
+
+ await data.Pair.RunTicksSync(5);
+
+ await data.Pair.CleanReturnAsync();
+ }
+
}
public EntityCoordinates GetObserverSpawnPoint()
{
_possiblePositions.Clear();
-
- foreach (var (point, transform) in EntityManager.EntityQuery<SpawnPointComponent, TransformComponent>(true))
+ var spawnPointQuery = EntityManager.EntityQueryEnumerator<SpawnPointComponent, TransformComponent>();
+ while (spawnPointQuery.MoveNext(out var uid, out var point, out var transform))
{
- if (point.SpawnType != SpawnPointType.Observer)
+ if (point.SpawnType != SpawnPointType.Observer
+ || TerminatingOrDeleted(uid)
+ || transform.MapUid == null
+ || TerminatingOrDeleted(transform.MapUid.Value))
+ {
continue;
+ }
_possiblePositions.Add(transform.Coordinates);
}
if (_mapManager.MapExists(DefaultMap))
{
- return new EntityCoordinates(_mapManager.GetMapEntityId(DefaultMap), Vector2.Zero);
+ var mapUid = _mapManager.GetMapEntityId(DefaultMap);
+ if (!TerminatingOrDeleted(mapUid))
+ return new EntityCoordinates(mapUid, Vector2.Zero);
}
// Just pick a point at this point I guess.
return SpawnGhost(mind, spawnPosition, canReturn);
}
+ private bool IsValidSpawnPosition(EntityCoordinates? spawnPosition)
+ {
+ if (spawnPosition?.IsValid(EntityManager) != true)
+ return false;
+
+ var mapUid = spawnPosition?.GetMapUid(EntityManager);
+ var gridUid = spawnPosition?.EntityId;
+ // Test if the map is being deleted
+ if (mapUid == null || TerminatingOrDeleted(mapUid.Value))
+ return false;
+ // Test if the grid is being deleted
+ if (gridUid != null && TerminatingOrDeleted(gridUid.Value))
+ return false;
+
+ return true;
+ }
+
public EntityUid? SpawnGhost(Entity<MindComponent?> mind, EntityCoordinates? spawnPosition = null,
bool canReturn = false)
{
if (!Resolve(mind, ref mind.Comp))
return null;
- // Test if the map is being deleted
- var mapUid = spawnPosition?.GetMapUid(EntityManager);
- if (mapUid == null || TerminatingOrDeleted(mapUid.Value))
+ // Test if the map or grid is being deleted
+ if (!IsValidSpawnPosition(spawnPosition))
spawnPosition = null;
+ // If it's bad, look for a valid point to spawn
spawnPosition ??= _ticker.GetObserverSpawnPoint();
- if (!spawnPosition.Value.IsValid(EntityManager))
+ // Make sure the new point is valid too
+ if (!IsValidSpawnPosition(spawnPosition))
{
Log.Warning($"No spawn valid ghost spawn position found for {mind.Comp.CharacterName}"
- + " \"{ToPrettyString(mind)}\"");
+ + $" \"{ToPrettyString(mind)}\"");
_minds.TransferTo(mind.Owner, null, createGhost: false, mind: mind.Comp);
return null;
}