Shooting NPCs and more (#18042)

* Add pirate shooting

* Shooting working

* Basics working

* Refactor time

* More conversion

* Update primitives

* Update yml

* weh

* Building again

* Draft

* weh

* b

* Start shutdown

* Starting to take form

* Code side done

* is it worky

* Fix prototypes

* stuff

* Shitty working

* Juke events working

* Even more cleanup

* RTX

* Fix interaction combat mode and compquery

* GetAmmoCount relays

* Fix rotation speed

* Juke fixes

* fixes

* weh

* The collision avoidance never ends

* Fixes

* Pause support

* framework

* lazy

* Fix idling

* Fix drip

* goobed

* Fix takeover shutdown bug

* Merge fixes

* shitter

* Fix carpos
This commit is contained in:
metalgearsloth
2023-08-02 10:48:56 +10:00
committed by GitHub
parent 018e465fad
commit c31c848afd
103 changed files with 2089 additions and 810 deletions

View File

@@ -11,7 +11,7 @@ namespace Content.Server.NPC.HTN.PrimitiveTasks.Operators;
/// <summary>
/// Moves an NPC to the specified target key. Hands the actual steering off to NPCSystem.Steering
/// </summary>
public sealed class MoveToOperator : HTNOperator
public sealed class MoveToOperator : HTNOperator, IHtnConditionalShutdown
{
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
@@ -19,6 +19,12 @@ public sealed class MoveToOperator : HTNOperator
private PathfindingSystem _pathfind = default!;
private SharedTransformSystem _transform = default!;
/// <summary>
/// When to shut the task down.
/// </summary>
[DataField("shutdownState")]
public HTNPlanState ShutdownState { get; } = HTNPlanState.TaskFinished;
/// <summary>
/// Should we assume the MovementTarget is reachable during planning or should we pathfind to it?
/// </summary>
@@ -35,7 +41,7 @@ public sealed class MoveToOperator : HTNOperator
/// Target Coordinates to move to. This gets removed after execution.
/// </summary>
[DataField("targetKey")]
public string TargetKey = "MovementTarget";
public string TargetKey = "TargetCoordinates";
/// <summary>
/// Where the pathfinding result will be stored (if applicable). This gets removed after execution.
@@ -49,6 +55,12 @@ public sealed class MoveToOperator : HTNOperator
[DataField("rangeKey")]
public string RangeKey = "MovementRange";
/// <summary>
/// Do we only need to move into line of sight.
/// </summary>
[DataField("stopOnLineOfSight")]
public bool StopOnLineOfSight;
private const string MovementCancelToken = "MovementCancelToken";
public override void Initialize(IEntitySystemManager sysManager)
@@ -132,6 +144,7 @@ public sealed class MoveToOperator : HTNOperator
// Re-use the path we may have if applicable.
var comp = _steering.Register(uid, targetCoordinates);
comp.ArriveOnLineOfSight = StopOnLineOfSight;
if (blackboard.TryGetValue<float>(RangeKey, out var range, _entManager))
{
@@ -150,10 +163,30 @@ public sealed class MoveToOperator : HTNOperator
}
}
public override void Shutdown(NPCBlackboard blackboard, HTNOperatorStatus status)
public override HTNOperatorStatus Update(NPCBlackboard blackboard, float frameTime)
{
base.Shutdown(blackboard, status);
var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);
if (!_entManager.TryGetComponent<NPCSteeringComponent>(owner, out var steering))
return HTNOperatorStatus.Failed;
// Just keep moving in the background and let the other tasks handle it.
if (ShutdownState == HTNPlanState.PlanFinished && steering.Status == SteeringStatus.Moving)
{
return HTNOperatorStatus.Finished;
}
return steering.Status switch
{
SteeringStatus.InRange => HTNOperatorStatus.Finished,
SteeringStatus.NoPath => HTNOperatorStatus.Failed,
SteeringStatus.Moving => HTNOperatorStatus.Continuing,
_ => throw new ArgumentOutOfRangeException()
};
}
public void ConditionalShutdown(NPCBlackboard blackboard)
{
// Cleanup the blackboard and remove steering.
if (blackboard.TryGetValue<CancellationTokenSource>(MovementCancelToken, out var cancelToken, _entManager))
{
@@ -171,20 +204,4 @@ public sealed class MoveToOperator : HTNOperator
_steering.Unregister(blackboard.GetValue<EntityUid>(NPCBlackboard.Owner));
}
public override HTNOperatorStatus Update(NPCBlackboard blackboard, float frameTime)
{
var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);
if (!_entManager.TryGetComponent<NPCSteeringComponent>(owner, out var steering))
return HTNOperatorStatus.Failed;
return steering.Status switch
{
SteeringStatus.InRange => HTNOperatorStatus.Finished,
SteeringStatus.NoPath => HTNOperatorStatus.Failed,
SteeringStatus.Moving => HTNOperatorStatus.Continuing,
_ => throw new ArgumentOutOfRangeException()
};
}
}