Enable nullability in Content.Server (#3685)
This commit is contained in:
@@ -12,7 +12,6 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -40,7 +39,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
|
||||
private PathfindingSystem _pathfindingSystem;
|
||||
private PathfindingSystem _pathfindingSystem = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Queued region updates
|
||||
@@ -180,7 +179,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
||||
var targetNode = _pathfindingSystem.GetNode(targetTile);
|
||||
|
||||
var collisionMask = 0;
|
||||
if (entity.TryGetComponent(out IPhysBody physics))
|
||||
if (entity.TryGetComponent(out IPhysBody? physics))
|
||||
{
|
||||
collisionMask = physics.CollisionMask;
|
||||
}
|
||||
@@ -229,7 +228,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
||||
var reachableArgs = ReachableArgs.GetArgs(entity);
|
||||
var reachableRegions = GetReachableRegions(reachableArgs, targetRegion);
|
||||
|
||||
return reachableRegions.Contains(entityRegion);
|
||||
return entityRegion != null && reachableRegions.Contains(entityRegion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -238,7 +237,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
||||
/// <param name="reachableArgs"></param>
|
||||
/// <param name="region"></param>
|
||||
/// <returns></returns>
|
||||
public HashSet<PathfindingRegion> GetReachableRegions(ReachableArgs reachableArgs, PathfindingRegion region)
|
||||
public HashSet<PathfindingRegion> GetReachableRegions(ReachableArgs reachableArgs, PathfindingRegion? region)
|
||||
{
|
||||
// if we're on a node that's not tracked at all atm then region will be null
|
||||
if (region == null)
|
||||
@@ -276,7 +275,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
||||
/// <returns></returns>
|
||||
private ReachableArgs GetCachedArgs(ReachableArgs accessibleArgs)
|
||||
{
|
||||
ReachableArgs foundArgs = null;
|
||||
ReachableArgs? foundArgs = null;
|
||||
|
||||
foreach (var (cachedAccessible, _) in _cachedAccessible)
|
||||
{
|
||||
@@ -422,7 +421,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
public PathfindingRegion GetRegion(IEntity entity)
|
||||
public PathfindingRegion? GetRegion(IEntity entity)
|
||||
{
|
||||
var entityTile = _mapManager.GetGrid(entity.Transform.GridID).GetTileRef(entity.Transform.Coordinates);
|
||||
var entityNode = _pathfindingSystem.GetNode(entityTile);
|
||||
@@ -434,7 +433,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
/// <returns></returns>
|
||||
public PathfindingRegion GetRegion(PathfindingNode node)
|
||||
public PathfindingRegion? GetRegion(PathfindingNode node)
|
||||
{
|
||||
// Not sure on the best way to optimise this
|
||||
// On the one hand, just storing each node's region is faster buuutttt muh memory
|
||||
@@ -469,7 +468,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
||||
/// <param name="x">This is already calculated in advance so may as well re-use it</param>
|
||||
/// <param name="y">This is already calculated in advance so may as well re-use it</param>
|
||||
/// <returns></returns>
|
||||
private PathfindingRegion CalculateNode(
|
||||
private PathfindingRegion? CalculateNode(
|
||||
PathfindingNode node,
|
||||
Dictionary<PathfindingNode, PathfindingRegion> existingRegions,
|
||||
HashSet<PathfindingRegion> chunkRegions,
|
||||
@@ -499,8 +498,8 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
||||
// Otherwise, make our own region.
|
||||
var leftNeighbor = x > 0 ? parentChunk.Nodes[x - 1, y] : null;
|
||||
var bottomNeighbor = y > 0 ? parentChunk.Nodes[x, y - 1] : null;
|
||||
PathfindingRegion leftRegion;
|
||||
PathfindingRegion bottomRegion;
|
||||
PathfindingRegion? leftRegion;
|
||||
PathfindingRegion? bottomRegion;
|
||||
|
||||
// We'll check if our left or down neighbors are already in a region and join them
|
||||
|
||||
@@ -562,7 +561,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="target"></param>
|
||||
private void MergeInto(PathfindingRegion source, PathfindingRegion target, Dictionary<PathfindingNode, PathfindingRegion> existingRegions = null)
|
||||
private void MergeInto(PathfindingRegion source, PathfindingRegion target, Dictionary<PathfindingNode, PathfindingRegion>? existingRegions = null)
|
||||
{
|
||||
DebugTools.AssertNotNull(source);
|
||||
DebugTools.AssertNotNull(target);
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
||||
}
|
||||
|
||||
// HashSet wasn't working correctly so uhh we got this.
|
||||
public bool Equals(PathfindingRegion other)
|
||||
public bool Equals(PathfindingRegion? other)
|
||||
{
|
||||
if (other == null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
||||
@@ -12,11 +12,11 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Pathfinders
|
||||
public class AStarPathfindingJob : Job<Queue<TileRef>>
|
||||
{
|
||||
#if DEBUG
|
||||
public static event Action<SharedAiDebug.AStarRouteDebug> DebugRoute;
|
||||
public static event Action<SharedAiDebug.AStarRouteDebug>? DebugRoute;
|
||||
#endif
|
||||
|
||||
private readonly PathfindingNode _startNode;
|
||||
private PathfindingNode _endNode;
|
||||
private readonly PathfindingNode? _startNode;
|
||||
private PathfindingNode? _endNode;
|
||||
private readonly PathfindingArgs _pathfindingArgs;
|
||||
|
||||
public AStarPathfindingJob(
|
||||
@@ -31,7 +31,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Pathfinders
|
||||
_pathfindingArgs = pathfindingArgs;
|
||||
}
|
||||
|
||||
protected override async Task<Queue<TileRef>> Process()
|
||||
protected override async Task<Queue<TileRef>?> Process()
|
||||
{
|
||||
if (_startNode == null ||
|
||||
_endNode == null ||
|
||||
@@ -50,7 +50,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Pathfinders
|
||||
var costSoFar = new Dictionary<PathfindingNode, float>();
|
||||
var cameFrom = new Dictionary<PathfindingNode, PathfindingNode>();
|
||||
|
||||
PathfindingNode currentNode = null;
|
||||
PathfindingNode? currentNode = null;
|
||||
frontier.Add((0.0f, _startNode));
|
||||
costSoFar[_startNode] = 0.0f;
|
||||
var routeFound = false;
|
||||
@@ -121,7 +121,9 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Pathfinders
|
||||
return null;
|
||||
}
|
||||
|
||||
var route = PathfindingHelpers.ReconstructPath(cameFrom, currentNode);
|
||||
DebugTools.AssertNotNull(currentNode);
|
||||
|
||||
var route = PathfindingHelpers.ReconstructPath(cameFrom, currentNode!);
|
||||
|
||||
if (route.Count == 1)
|
||||
{
|
||||
|
||||
@@ -16,11 +16,11 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Pathfinders
|
||||
// Some of this is probably fugly due to other structural changes in pathfinding so it could do with optimisation
|
||||
// Realistically it's probably not getting used given it doesn't support tile costs which can be very useful
|
||||
#if DEBUG
|
||||
public static event Action<SharedAiDebug.JpsRouteDebug> DebugRoute;
|
||||
public static event Action<SharedAiDebug.JpsRouteDebug>? DebugRoute;
|
||||
#endif
|
||||
|
||||
private readonly PathfindingNode _startNode;
|
||||
private PathfindingNode _endNode;
|
||||
private readonly PathfindingNode? _startNode;
|
||||
private PathfindingNode? _endNode;
|
||||
private readonly PathfindingArgs _pathfindingArgs;
|
||||
|
||||
public JpsPathfindingJob(double maxTime,
|
||||
@@ -34,7 +34,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Pathfinders
|
||||
_pathfindingArgs = pathfindingArgs;
|
||||
}
|
||||
|
||||
protected override async Task<Queue<TileRef>> Process()
|
||||
protected override async Task<Queue<TileRef>?> Process()
|
||||
{
|
||||
// VERY similar to A*; main difference is with the neighbor tiles you look for jump nodes instead
|
||||
if (_startNode == null ||
|
||||
@@ -58,7 +58,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Pathfinders
|
||||
var jumpNodes = new HashSet<PathfindingNode>();
|
||||
#endif
|
||||
|
||||
PathfindingNode currentNode = null;
|
||||
PathfindingNode? currentNode = null;
|
||||
openTiles.Add((0, _startNode));
|
||||
gScores[_startNode] = 0.0f;
|
||||
var routeFound = false;
|
||||
@@ -123,7 +123,10 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Pathfinders
|
||||
return null;
|
||||
}
|
||||
|
||||
var route = PathfindingHelpers.ReconstructJumpPath(cameFrom, currentNode);
|
||||
DebugTools.AssertNotNull(currentNode);
|
||||
|
||||
var route = PathfindingHelpers.ReconstructJumpPath(cameFrom, currentNode!);
|
||||
|
||||
if (route.Count == 1)
|
||||
{
|
||||
return null;
|
||||
@@ -153,14 +156,14 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Pathfinders
|
||||
return route;
|
||||
}
|
||||
|
||||
private PathfindingNode GetJumpPoint(PathfindingNode currentNode, Direction direction, PathfindingNode endNode)
|
||||
private PathfindingNode? GetJumpPoint(PathfindingNode currentNode, Direction direction, PathfindingNode endNode)
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
while (count < 1000)
|
||||
{
|
||||
count++;
|
||||
PathfindingNode nextNode = null;
|
||||
PathfindingNode? nextNode = null;
|
||||
foreach (var node in currentNode.GetNeighbors())
|
||||
{
|
||||
if (PathfindingHelpers.RelativeDirection(node, currentNode) == direction)
|
||||
@@ -285,10 +288,10 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Pathfinders
|
||||
// I tried just casting direction ints and offsets to make it smaller but brain no worky.
|
||||
// From NorthEast we check (Closed / Open) S - SE, W - NW
|
||||
|
||||
PathfindingNode openNeighborOne = null;
|
||||
PathfindingNode closedNeighborOne = null;
|
||||
PathfindingNode openNeighborTwo = null;
|
||||
PathfindingNode closedNeighborTwo = null;
|
||||
PathfindingNode? openNeighborOne = null;
|
||||
PathfindingNode? closedNeighborOne = null;
|
||||
PathfindingNode? openNeighborTwo = null;
|
||||
PathfindingNode? closedNeighborTwo = null;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
@@ -400,10 +403,10 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Pathfinders
|
||||
/// </summary>
|
||||
private bool IsCardinalJumpPoint(Direction direction, PathfindingNode currentNode)
|
||||
{
|
||||
PathfindingNode openNeighborOne = null;
|
||||
PathfindingNode closedNeighborOne = null;
|
||||
PathfindingNode openNeighborTwo = null;
|
||||
PathfindingNode closedNeighborTwo = null;
|
||||
PathfindingNode? openNeighborOne = null;
|
||||
PathfindingNode? closedNeighborOne = null;
|
||||
PathfindingNode? openNeighborTwo = null;
|
||||
PathfindingNode? closedNeighborTwo = null;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
|
||||
@@ -177,12 +177,9 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
return _nodes[chunkX, chunkY];
|
||||
}
|
||||
|
||||
private void CreateNode(TileRef tile, PathfindingChunk parent = null)
|
||||
private void CreateNode(TileRef tile, PathfindingChunk? parent = null)
|
||||
{
|
||||
if (parent == null)
|
||||
{
|
||||
parent = this;
|
||||
}
|
||||
parent ??= this;
|
||||
|
||||
var node = new PathfindingNode(parent, tile);
|
||||
var offsetX = tile.X - Indices.X;
|
||||
|
||||
@@ -36,10 +36,10 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
// Given there's different collision layers stored for each node in the graph it's probably not worth it to cache this
|
||||
// Also this will help with corner-cutting
|
||||
|
||||
PathfindingNode northNeighbor = null;
|
||||
PathfindingNode southNeighbor = null;
|
||||
PathfindingNode eastNeighbor = null;
|
||||
PathfindingNode westNeighbor = null;
|
||||
PathfindingNode? northNeighbor = null;
|
||||
PathfindingNode? southNeighbor = null;
|
||||
PathfindingNode? eastNeighbor = null;
|
||||
PathfindingNode? westNeighbor = null;
|
||||
foreach (var neighbor in currentNode.GetNeighbors())
|
||||
{
|
||||
if (neighbor.TileRef.X == currentNode.TileRef.X &&
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
/// <returns></returns>
|
||||
public IEnumerable<PathfindingNode> GetNeighbors()
|
||||
{
|
||||
List<PathfindingChunk> neighborChunks = null;
|
||||
List<PathfindingChunk>? neighborChunks = null;
|
||||
if (ParentChunk.OnEdge(this))
|
||||
{
|
||||
neighborChunks = ParentChunk.RelevantChunks(this).ToList();
|
||||
@@ -80,7 +80,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
{
|
||||
DebugTools.AssertNotNull(neighborChunks);
|
||||
// Get the relevant chunk and then get the node on it
|
||||
foreach (var neighbor in neighborChunks)
|
||||
foreach (var neighbor in neighborChunks!)
|
||||
{
|
||||
// A lot of edge transitions are going to have a single neighboring chunk
|
||||
// (given > 1 only affects corners)
|
||||
@@ -96,7 +96,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
}
|
||||
}
|
||||
|
||||
public PathfindingNode GetNeighbor(Direction direction)
|
||||
public PathfindingNode? GetNeighbor(Direction direction)
|
||||
{
|
||||
var chunkXOffset = TileRef.X - ParentChunk.Indices.X;
|
||||
var chunkYOffset = TileRef.Y - ParentChunk.Indices.Y;
|
||||
@@ -266,7 +266,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
// TODO: Check for powered I think (also need an event for when it's depowered
|
||||
// AccessReader calls this whenever opening / closing but it can seem to get called multiple times
|
||||
// Which may or may not be intended?
|
||||
if (entity.TryGetComponent(out AccessReader accessReader) && !_accessReaders.ContainsKey(entity))
|
||||
if (entity.TryGetComponent(out AccessReader? accessReader) && !_accessReaders.ContainsKey(entity))
|
||||
{
|
||||
_accessReaders.Add(entity, accessReader);
|
||||
ParentChunk.Dirty();
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
}
|
||||
}
|
||||
|
||||
private void QueueGridChange(object sender, GridChangedEventArgs eventArgs)
|
||||
private void QueueGridChange(object? sender, GridChangedEventArgs eventArgs)
|
||||
{
|
||||
foreach (var (position, _) in eventArgs.Modified)
|
||||
{
|
||||
@@ -245,7 +245,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
}
|
||||
}
|
||||
|
||||
private void QueueTileChange(object sender, TileChangedEventArgs eventArgs)
|
||||
private void QueueTileChange(object? sender, TileChangedEventArgs eventArgs)
|
||||
{
|
||||
_tileUpdateQueue.Enqueue(eventArgs.NewTile);
|
||||
}
|
||||
@@ -264,7 +264,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
{
|
||||
if (entity.Deleted ||
|
||||
_lastKnownPositions.ContainsKey(entity) ||
|
||||
!entity.TryGetComponent(out IPhysBody physics) ||
|
||||
!entity.TryGetComponent(out IPhysBody? physics) ||
|
||||
!PathfindingNode.IsRelevant(entity, physics))
|
||||
{
|
||||
return;
|
||||
@@ -303,7 +303,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
{
|
||||
// If we've moved to space or the likes then remove us.
|
||||
if (moveEvent.Sender.Deleted ||
|
||||
!moveEvent.Sender.TryGetComponent(out IPhysBody physics) ||
|
||||
!moveEvent.Sender.TryGetComponent(out IPhysBody? physics) ||
|
||||
!PathfindingNode.IsRelevant(moveEvent.Sender, physics) ||
|
||||
moveEvent.NewPosition.GetGridId(EntityManager) == GridId.Invalid)
|
||||
{
|
||||
@@ -368,7 +368,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
|
||||
|
||||
public bool CanTraverse(IEntity entity, PathfindingNode node)
|
||||
{
|
||||
if (entity.TryGetComponent(out IPhysBody physics) &&
|
||||
if (entity.TryGetComponent(out IPhysBody? physics) &&
|
||||
(physics.CollisionMask & node.BlockedCollisionMask) != 0)
|
||||
{
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user