Evac shuttle (#8931)
Co-authored-by: metalgearsloth <metalgearsloth@gmail.com>
This commit is contained in:
@@ -8,14 +8,11 @@ using Robust.Shared.Prototypes;
|
||||
namespace Content.Server.AI.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(IMobMoverComponent))]
|
||||
[Virtual]
|
||||
public class AiControllerComponent : Component, IMobMoverComponent, IMoverComponent
|
||||
public class AiControllerComponent : Component
|
||||
{
|
||||
[DataField("logic")] private float _visionRadius = 8.0f;
|
||||
|
||||
public bool CanMove { get; set; } = true;
|
||||
|
||||
// TODO: Need to ECS a lot more of the AI first before we can ECS this
|
||||
/// <summary>
|
||||
/// Whether the AI is actively iterated.
|
||||
@@ -46,59 +43,6 @@ namespace Content.Server.AI.Components
|
||||
set => _visionRadius = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
// This component requires a physics component.
|
||||
Owner.EnsureComponent<PhysicsComponent>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Movement speed (m/s) that the entity walks, after modifiers
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public float CurrentWalkSpeed
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IoCManager.Resolve<IEntityManager>().TryGetComponent(Owner, out MovementSpeedModifierComponent? component))
|
||||
{
|
||||
return component.CurrentWalkSpeed;
|
||||
}
|
||||
|
||||
return MovementSpeedModifierComponent.DefaultBaseWalkSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Movement speed (m/s) that the entity walks, after modifiers
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public float CurrentSprintSpeed
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IoCManager.Resolve<IEntityManager>().TryGetComponent(Owner, out MovementSpeedModifierComponent? component))
|
||||
{
|
||||
return component.CurrentSprintSpeed;
|
||||
}
|
||||
|
||||
return MovementSpeedModifierComponent.DefaultBaseSprintSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
public Angle LastGridAngle { get => Angle.Zero; set {} }
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float PushStrength { get; set; } = IMobMoverComponent.PushStrengthDefault;
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float GrabRange { get; set; } = IMobMoverComponent.GrabRangeDefault;
|
||||
|
||||
/// <summary>
|
||||
/// Is the entity Sprinting (running)?
|
||||
/// </summary>
|
||||
@@ -111,17 +55,6 @@ namespace Content.Server.AI.Components
|
||||
[ViewVariables]
|
||||
public Vector2 VelocityDir { get; set; }
|
||||
|
||||
(Vector2 walking, Vector2 sprinting) IMoverComponent.VelocityDir =>
|
||||
Sprinting ? (Vector2.Zero, VelocityDir) : (VelocityDir, Vector2.Zero);
|
||||
|
||||
public EntityCoordinates LastPosition { get; set; }
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float StepSoundDistance { get; set; }
|
||||
|
||||
public void SetVelocityDirection(Direction direction, ushort subTick, bool enabled) { }
|
||||
public void SetSprinting(ushort subTick, bool walking) { }
|
||||
|
||||
public virtual void Update(float frameTime) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,10 @@ using Content.Server.CPUJob.JobQueues;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.Doors.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.AI.Steering
|
||||
@@ -17,6 +19,7 @@ namespace Content.Server.AI.Steering
|
||||
public sealed class AiSteeringSystem : EntitySystem
|
||||
{
|
||||
// http://www.red3d.com/cwr/papers/1999/gdc99steer.html for a steering overview
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly PathfindingSystem _pathfindingSystem = default!;
|
||||
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
|
||||
@@ -120,9 +123,9 @@ namespace Content.Server.AI.Steering
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
public void Unregister(EntityUid entity)
|
||||
{
|
||||
if (EntityManager.TryGetComponent(entity, out AiControllerComponent? controller))
|
||||
if (EntityManager.TryGetComponent(entity, out SharedPlayerInputMoverComponent? controller))
|
||||
{
|
||||
controller.VelocityDir = Vector2.Zero;
|
||||
controller.CurTickSprintMovement = Vector2.Zero;
|
||||
}
|
||||
|
||||
if (_pathfindingRequests.TryGetValue(entity, out var request))
|
||||
@@ -228,6 +231,13 @@ namespace Content.Server.AI.Steering
|
||||
_listIndex = (_listIndex + 1) % _agentLists.Count;
|
||||
}
|
||||
|
||||
private void SetDirection(SharedPlayerInputMoverComponent component, Vector2 value)
|
||||
{
|
||||
component.CurTickSprintMovement = value;
|
||||
component._lastInputTick = _timing.CurTick;
|
||||
component._lastInputSubTick = ushort.MaxValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Go through each steerer and combine their vectors
|
||||
/// </summary>
|
||||
@@ -240,7 +250,7 @@ namespace Content.Server.AI.Steering
|
||||
{
|
||||
// Main optimisation to be done below is the redundant calls and adding more variables
|
||||
if (Deleted(entity) ||
|
||||
!EntityManager.TryGetComponent(entity, out AiControllerComponent? controller) ||
|
||||
!EntityManager.TryGetComponent(entity, out SharedPlayerInputMoverComponent? controller) ||
|
||||
!controller.CanMove ||
|
||||
!TryComp(entity, out TransformComponent? xform) ||
|
||||
xform.GridUid == null)
|
||||
@@ -252,13 +262,13 @@ namespace Content.Server.AI.Steering
|
||||
|
||||
if (entitySteering != null && (!EntityManager.EntityExists(entitySteering.Target) ? EntityLifeStage.Deleted : EntityManager.GetComponent<MetaDataComponent>(entitySteering.Target).EntityLifeStage) >= EntityLifeStage.Deleted)
|
||||
{
|
||||
controller.VelocityDir = Vector2.Zero;
|
||||
controller.CurTickSprintMovement = Vector2.Zero;
|
||||
return SteeringStatus.NoPath;
|
||||
}
|
||||
|
||||
if (_mapManager.IsGridPaused(xform.GridUid.Value))
|
||||
{
|
||||
controller.VelocityDir = Vector2.Zero;
|
||||
SetDirection(controller, Vector2.Zero);
|
||||
return SteeringStatus.Pending;
|
||||
}
|
||||
|
||||
@@ -266,7 +276,7 @@ namespace Content.Server.AI.Steering
|
||||
// Check if we can even arrive -> Currently only samegrid movement supported
|
||||
if (xform.GridUid != steeringRequest.TargetGrid.GetGridUid(EntityManager))
|
||||
{
|
||||
controller.VelocityDir = Vector2.Zero;
|
||||
SetDirection(controller, Vector2.Zero);
|
||||
return SteeringStatus.NoPath;
|
||||
}
|
||||
|
||||
@@ -280,7 +290,7 @@ namespace Content.Server.AI.Steering
|
||||
_interactionSystem.InRangeUnobstructed(entity, steeringRequest.TargetMap, steeringRequest.ArrivalDistance, popup: true))
|
||||
{
|
||||
// TODO: Need cruder LOS checks for ranged weaps
|
||||
controller.VelocityDir = Vector2.Zero;
|
||||
SetDirection(controller, Vector2.Zero);
|
||||
return SteeringStatus.Arrived;
|
||||
}
|
||||
|
||||
@@ -291,7 +301,7 @@ namespace Content.Server.AI.Steering
|
||||
// If we're really close don't swiggity swoogity back and forth and just wait for the interaction check maybe?
|
||||
if (steeringRequest.TimeUntilInteractionCheck > 0.0f && targetDistance <= 0.1f)
|
||||
{
|
||||
controller.VelocityDir = Vector2.Zero;
|
||||
SetDirection(controller, Vector2.Zero);
|
||||
return SteeringStatus.Moving;
|
||||
}
|
||||
|
||||
@@ -305,7 +315,7 @@ namespace Content.Server.AI.Steering
|
||||
break;
|
||||
// Currently nothing should be cancelling these except external factors
|
||||
case TaskCanceledException _:
|
||||
controller.VelocityDir = Vector2.Zero;
|
||||
SetDirection(controller, Vector2.Zero);
|
||||
return SteeringStatus.NoPath;
|
||||
default:
|
||||
throw pathRequest.Job.Exception;
|
||||
@@ -314,7 +324,7 @@ namespace Content.Server.AI.Steering
|
||||
var path = _pathfindingRequests[entity].Job.Result;
|
||||
if (path == null || path.Count == 0)
|
||||
{
|
||||
controller.VelocityDir = Vector2.Zero;
|
||||
SetDirection(controller, Vector2.Zero);
|
||||
return SteeringStatus.NoPath;
|
||||
}
|
||||
|
||||
@@ -335,7 +345,7 @@ namespace Content.Server.AI.Steering
|
||||
// If the route's empty we could be close and may not need a re-path so we won't check if it is
|
||||
if (!_paths.ContainsKey(entity) && !_pathfindingRequests.ContainsKey(entity) && targetDistance > 1.5f)
|
||||
{
|
||||
controller.VelocityDir = Vector2.Zero;
|
||||
SetDirection(controller, Vector2.Zero);
|
||||
RequestPath(entity, steeringRequest);
|
||||
return SteeringStatus.Pending;
|
||||
}
|
||||
@@ -365,14 +375,14 @@ namespace Content.Server.AI.Steering
|
||||
var nextGrid = NextGrid(entity, steeringRequest);
|
||||
if (!nextGrid.HasValue)
|
||||
{
|
||||
controller.VelocityDir = Vector2.Zero;
|
||||
SetDirection(controller, Vector2.Zero);
|
||||
return SteeringStatus.NoPath;
|
||||
}
|
||||
|
||||
// Validate that we can even get to the next grid (could probably just check if we can use nextTile if we're not near the target grid)
|
||||
if (!_pathfindingSystem.CanTraverse(entity, nextGrid.Value))
|
||||
{
|
||||
controller.VelocityDir = Vector2.Zero;
|
||||
SetDirection(controller, Vector2.Zero);
|
||||
return SteeringStatus.NoPath;
|
||||
}
|
||||
|
||||
@@ -392,7 +402,7 @@ namespace Content.Server.AI.Steering
|
||||
|
||||
// Move towards it
|
||||
DebugTools.Assert(movementVector != new Vector2(float.NaN, float.NaN));
|
||||
controller.VelocityDir = movementVector.Normalized;
|
||||
SetDirection(controller, movementVector.Normalized);
|
||||
return SteeringStatus.Moving;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Content.Server.AI.Utility.AiLogic
|
||||
// TODO: Need to split out the IMover stuff for NPC to a generic one that can be used for hoomans as well.
|
||||
[RegisterComponent]
|
||||
[ComponentProtoName("UtilityAI")]
|
||||
[ComponentReference(typeof(AiControllerComponent)), ComponentReference(typeof(IMoverComponent))]
|
||||
[ComponentReference(typeof(AiControllerComponent))]
|
||||
public sealed class UtilityAi : AiControllerComponent
|
||||
{
|
||||
// TODO: Look at having ParallelOperators (probably no more than that as then you'd have a full-blown BT)
|
||||
|
||||
Reference in New Issue
Block a user