NPC steering tweaks (#26351)
- Fix the free node check considering the whole tile and not the poly. - Clear maps on direction resets. - More robust arrival checks for pathfinding nodes.
This commit is contained in:
@@ -58,7 +58,7 @@ public sealed partial class NPCSteeringSystem
|
||||
|
||||
// TODO: Ideally for "FreeSpace" we check all entities on the tile and build flags dynamically (pathfinder refactor in future).
|
||||
var ents = _entSetPool.Get();
|
||||
_lookup.GetLocalEntitiesIntersecting(node.GraphUid, node.ChunkOrigin, ents, flags: LookupFlags.Static);
|
||||
_lookup.GetLocalEntitiesIntersecting(node.GraphUid, node.Box.Enlarged(-0.04f), ents, flags: LookupFlags.Static);
|
||||
var result = true;
|
||||
|
||||
if (ents.Count > 0)
|
||||
@@ -158,28 +158,6 @@ public sealed partial class NPCSteeringSystem
|
||||
}
|
||||
}
|
||||
|
||||
// Need to be pretty close if it's just a node to make sure LOS for door bashes or the likes.
|
||||
float arrivalDistance;
|
||||
|
||||
if (targetCoordinates.Equals(steering.Coordinates))
|
||||
{
|
||||
// What's our tolerance for arrival.
|
||||
// If it's a pathfinding node it might be different to the destination.
|
||||
arrivalDistance = steering.Range;
|
||||
}
|
||||
// If next node is a free tile then get within its bounds.
|
||||
// This is to avoid popping it too early
|
||||
else if (steering.CurrentPath.TryPeek(out var node) && IsFreeSpace(uid, steering, node))
|
||||
{
|
||||
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.
|
||||
else
|
||||
{
|
||||
arrivalDistance = SharedInteractionSystem.InteractionRange - 0.05f;
|
||||
}
|
||||
|
||||
// Check if mapids match.
|
||||
var targetMap = targetCoordinates.ToMap(EntityManager, _transform);
|
||||
var ourMap = ourCoordinates.ToMap(EntityManager, _transform);
|
||||
@@ -192,8 +170,30 @@ public sealed partial class NPCSteeringSystem
|
||||
|
||||
var direction = targetMap.Position - ourMap.Position;
|
||||
|
||||
// Need to be pretty close if it's just a node to make sure LOS for door bashes or the likes.
|
||||
bool arrived;
|
||||
|
||||
if (targetCoordinates.Equals(steering.Coordinates))
|
||||
{
|
||||
// What's our tolerance for arrival.
|
||||
// If it's a pathfinding node it might be different to the destination.
|
||||
arrived = direction.Length() <= steering.Range;
|
||||
}
|
||||
// If next node is a free tile then get within its bounds.
|
||||
// This is to avoid popping it too early
|
||||
else if (steering.CurrentPath.TryPeek(out var node) && IsFreeSpace(uid, steering, node))
|
||||
{
|
||||
arrived = node.Box.Contains(ourCoordinates.Position);
|
||||
}
|
||||
// Try getting into blocked range I guess?
|
||||
// TODO: Consider melee range or the likes.
|
||||
else
|
||||
{
|
||||
arrived = direction.Length() <= SharedInteractionSystem.InteractionRange - 0.05f;
|
||||
}
|
||||
|
||||
// Are we in range
|
||||
if (direction.Length() <= arrivalDistance)
|
||||
if (arrived)
|
||||
{
|
||||
// Node needs some kind of special handling like access or smashing.
|
||||
if (steering.CurrentPath.TryPeek(out var node) && !IsFreeSpace(uid, steering, node))
|
||||
|
||||
Reference in New Issue
Block a user