Fix AI steering throw (#1872)

Entity steering wasn't properly checking if the target was deleted.

Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
This commit is contained in:
metalgearsloth
2020-08-23 20:42:59 +10:00
committed by GitHub
parent b9196d0a10
commit 0b4ca168d4

View File

@@ -249,11 +249,19 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering
private SteeringStatus Steer(IEntity entity, IAiSteeringRequest steeringRequest, float frameTime) private SteeringStatus Steer(IEntity entity, IAiSteeringRequest steeringRequest, float frameTime)
{ {
// Main optimisation to be done below is the redundant calls and adding more variables // Main optimisation to be done below is the redundant calls and adding more variables
if (!entity.TryGetComponent(out AiControllerComponent controller) || !ActionBlockerSystem.CanMove(entity)) if (entity.Deleted || !entity.TryGetComponent(out AiControllerComponent controller) || !ActionBlockerSystem.CanMove(entity))
{ {
return SteeringStatus.NoPath; return SteeringStatus.NoPath;
} }
var entitySteering = steeringRequest as EntityTargetSteeringRequest;
if (entitySteering != null && entitySteering.Target.Deleted)
{
controller.VelocityDir = Vector2.Zero;
return SteeringStatus.NoPath;
}
if (_pauseManager.IsGridPaused(entity.Transform.GridID)) if (_pauseManager.IsGridPaused(entity.Transform.GridID))
{ {
controller.VelocityDir = Vector2.Zero; controller.VelocityDir = Vector2.Zero;
@@ -320,9 +328,9 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering
UpdatePath(entity, path); UpdatePath(entity, path);
// If we're targeting entity get a fixed tile; if they move from it then re-path (at least til we get a better solution) // If we're targeting entity get a fixed tile; if they move from it then re-path (at least til we get a better solution)
if (steeringRequest is EntityTargetSteeringRequest entitySteeringRequest) if (entitySteering != null)
{ {
_entityTargetPosition[entity] = entitySteeringRequest.TargetGrid; _entityTargetPosition[entity] = entitySteering.TargetGrid;
} }
// Move next tick // Move next tick
@@ -342,22 +350,17 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering
// Check if the target entity has moved - If so then re-path // Check if the target entity has moved - If so then re-path
// TODO: Patch the path from the target's position back towards us, stopping if it ever intersects the current path // TODO: Patch the path from the target's position back towards us, stopping if it ever intersects the current path
// Probably need a separate "PatchPath" job // Probably need a separate "PatchPath" job
if (steeringRequest is EntityTargetSteeringRequest entitySteer) if (entitySteering != null)
{ {
if (entitySteer.Target.Deleted)
{
controller.VelocityDir = Vector2.Zero;
return SteeringStatus.NoPath;
}
// Check if target's moved too far // Check if target's moved too far
if (_entityTargetPosition.TryGetValue(entity, out var targetGrid) && (entitySteer.TargetGrid.Position - targetGrid.Position).Length >= entitySteer.TargetMaxMove) if (_entityTargetPosition.TryGetValue(entity, out var targetGrid) &&
(entitySteering.TargetGrid.Position - targetGrid.Position).Length >= entitySteering.TargetMaxMove)
{ {
// We'll just repath and keep following the existing one until we get a new one // We'll just repath and keep following the existing one until we get a new one
RequestPath(entity, steeringRequest); RequestPath(entity, steeringRequest);
} }
ignoredCollision.Add(entitySteer.Target); ignoredCollision.Add(entitySteering.Target);
} }
HandleStuck(entity); HandleStuck(entity);