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

@@ -77,12 +77,43 @@ public sealed partial class NPCSteeringSystem
{
var ourCoordinates = xform.Coordinates;
var destinationCoordinates = steering.Coordinates;
var inLos = true;
// Check if we're in LOS if that's required.
// TODO: Need something uhh better not sure on the interaction between these.
if (steering.ArriveOnLineOfSight)
{
// TODO: use vision range
inLos = _interaction.InRangeUnobstructed(uid, steering.Coordinates, 10f);
if (inLos)
{
steering.LineOfSightTimer += frameTime;
if (steering.LineOfSightTimer >= steering.LineOfSightTimeRequired)
{
steering.Status = SteeringStatus.InRange;
ResetStuck(steering, ourCoordinates);
return true;
}
}
else
{
steering.LineOfSightTimer = 0f;
}
}
else
{
steering.LineOfSightTimer = 0f;
}
// We've arrived, nothing else matters.
if (xform.Coordinates.TryDistance(EntityManager, destinationCoordinates, out var distance) &&
distance <= steering.Range)
if (xform.Coordinates.TryDistance(EntityManager, destinationCoordinates, out var targetDistance) &&
inLos &&
targetDistance <= steering.Range)
{
steering.Status = SteeringStatus.InRange;
ResetStuck(steering, ourCoordinates);
return true;
}
@@ -117,7 +148,7 @@ public sealed partial class NPCSteeringSystem
// This is to avoid popping it too early
else if (steering.CurrentPath.TryPeek(out var node) && IsFreeSpace(uid, steering, node))
{
arrivalDistance = MathF.Min(node.Box.Width / 2f, node.Box.Height / 2f) - 0.01f;
arrivalDistance = MathF.Max(0.05f, MathF.Min(node.Box.Width / 2f, node.Box.Height / 2f) - 0.05f);
}
// Try getting into blocked range I guess?
// TODO: Consider melee range or the likes.
@@ -172,7 +203,7 @@ public sealed partial class NPCSteeringSystem
steering.Status = SteeringStatus.NoPath;
return false;
case SteeringObstacleStatus.Continuing:
CheckPath(uid, steering, xform, needsPath, distance);
CheckPath(uid, steering, xform, needsPath, targetDistance);
return true;
default:
throw new ArgumentOutOfRangeException();
@@ -205,9 +236,7 @@ public sealed partial class NPCSteeringSystem
}
else
{
// This probably shouldn't happen as we check above but eh.
steering.Status = SteeringStatus.NoPath;
return false;
needsPath = true;
}
}
// Stuck detection
@@ -228,8 +257,13 @@ public sealed partial class NPCSteeringSystem
// B) NPCs still try to move in locked containers (e.g. cow, hamster)
// and I don't want to spam grafana even harder than it gets spammed rn.
Log.Debug($"NPC {ToPrettyString(uid)} found stuck at {ourCoordinates}");
steering.Status = SteeringStatus.NoPath;
return false;
needsPath = true;
if (stuckTime.TotalSeconds > maxStuckTime * 3)
{
steering.Status = SteeringStatus.NoPath;
return false;
}
}
}
else
@@ -237,14 +271,14 @@ public sealed partial class NPCSteeringSystem
ResetStuck(steering, ourCoordinates);
}
// Do we have no more nodes to follow OR has the target moved sufficiently? If so then re-path.
if (!needsPath)
// If not in LOS and no path then get a new one fam.
if (!inLos && steering.CurrentPath.Count == 0)
{
needsPath = steering.CurrentPath.Count == 0 || (steering.CurrentPath.Peek().Data.Flags & PathfindingBreadcrumbFlag.Invalid) != 0x0;
needsPath = true;
}
// TODO: Probably need partial planning support i.e. patch from the last node to where the target moved to.
CheckPath(uid, steering, xform, needsPath, distance);
CheckPath(uid, steering, xform, needsPath, targetDistance);
// If we don't have a path yet then do nothing; this is to avoid stutter-stepping if it turns out there's no path
// available but we assume there was.
@@ -295,8 +329,10 @@ public sealed partial class NPCSteeringSystem
return;
}
if (!needsPath)
if (!needsPath && steering.CurrentPath.Count > 0)
{
needsPath = steering.CurrentPath.Count > 0 && (steering.CurrentPath.Peek().Data.Flags & PathfindingBreadcrumbFlag.Invalid) != 0x0;
// If the target has sufficiently moved.
var lastNode = GetCoordinates(steering.CurrentPath.Last());
@@ -357,10 +393,6 @@ public sealed partial class NPCSteeringSystem
mask = (CollisionGroup) physics.CollisionMask;
}
// If we have to backtrack (for example, we're behind a table and the target is on the other side)
// Then don't consider pruning.
var goal = nodes.Last().Coordinates.ToMap(EntityManager, _transform);
for (var i = 0; i < nodes.Count; i++)
{
var node = nodes[i];
@@ -451,7 +483,9 @@ public sealed partial class NPCSteeringSystem
var xformB = _xformQuery.GetComponent(ent);
if (!_physics.TryGetNearest(uid, ent, out var pointA, out var pointB, out var distance, xform, xformB))
if (!_physics.TryGetNearest(uid, ent,
out var pointA, out var pointB, out var distance,
xform, xformB))
{
continue;
}
@@ -508,8 +542,7 @@ public sealed partial class NPCSteeringSystem
var objectRadius = 0.25f;
var detectionRadius = MathF.Max(0.35f, agentRadius + objectRadius);
var ourVelocity = body.LinearVelocity;
var factionQuery = GetEntityQuery<NpcFactionMemberComponent>();
factionQuery.TryGetComponent(uid, out var ourFaction);
_factionQuery.TryGetComponent(uid, out var ourFaction);
foreach (var ent in _lookup.GetEntitiesInRange(uid, detectionRadius, LookupFlags.Dynamic))
{
@@ -520,7 +553,7 @@ public sealed partial class NPCSteeringSystem
!otherBody.CanCollide ||
(mask & otherBody.CollisionLayer) == 0x0 &&
(layer & otherBody.CollisionMask) == 0x0 ||
!factionQuery.TryGetComponent(ent, out var otherFaction) ||
!_factionQuery.TryGetComponent(ent, out var otherFaction) ||
!_npcFaction.IsEntityFriendly(uid, ent, ourFaction, otherFaction) ||
// Use <= 0 so we ignore stationary friends in case.
Vector2.Dot(otherBody.LinearVelocity, ourVelocity) <= 0f)