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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user