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)
{
// 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;
}
var entitySteering = steeringRequest as EntityTargetSteeringRequest;
if (entitySteering != null && entitySteering.Target.Deleted)
{
controller.VelocityDir = Vector2.Zero;
return SteeringStatus.NoPath;
}
if (_pauseManager.IsGridPaused(entity.Transform.GridID))
{
controller.VelocityDir = Vector2.Zero;
@@ -320,9 +328,9 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering
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 (steeringRequest is EntityTargetSteeringRequest entitySteeringRequest)
if (entitySteering != null)
{
_entityTargetPosition[entity] = entitySteeringRequest.TargetGrid;
_entityTargetPosition[entity] = entitySteering.TargetGrid;
}
// 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
// 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
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
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
RequestPath(entity, steeringRequest);
}
ignoredCollision.Add(entitySteer.Target);
ignoredCollision.Add(entitySteering.Target);
}
HandleStuck(entity);