From bd930de04457b5d863a7c2ac7c0b9bf56ea524a4 Mon Sep 17 00:00:00 2001
From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Date: Wed, 9 Feb 2022 07:08:07 +1300
Subject: [PATCH] Allow a range <= 0 in InRangeUnoccluded (#6440)
---
Content.Shared/Examine/ExamineSystemShared.cs | 27 +++++++++++++------
.../Interaction/SharedInteractionSystem.cs | 19 ++++++++-----
2 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/Content.Shared/Examine/ExamineSystemShared.cs b/Content.Shared/Examine/ExamineSystemShared.cs
index 1172875d23..832d2c1f8b 100644
--- a/Content.Shared/Examine/ExamineSystemShared.cs
+++ b/Content.Shared/Examine/ExamineSystemShared.cs
@@ -9,6 +9,7 @@ using JetBrains.Annotations;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
+using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
@@ -33,6 +34,8 @@ namespace Content.Shared.Examine
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
+ public const float MaxRaycastRange = 100;
+
///
/// Examine range to use when the examiner is in critical condition.
///
@@ -114,23 +117,31 @@ namespace Content.Shared.Examine
public static bool InRangeUnOccluded(MapCoordinates origin, MapCoordinates other, float range, Ignored? predicate, bool ignoreInsideBlocker = true)
{
- if (origin.MapId == MapId.Nullspace ||
+ if (other.MapId != origin.MapId ||
other.MapId == MapId.Nullspace) return false;
+ var dir = other.Position - origin.Position;
+ var length = dir.Length;
+
+ // If range specified also check it
+ if (range > 0f && length > range) return false;
+
+ if (MathHelper.CloseTo(length, 0)) return true;
+
+ if (length > MaxRaycastRange)
+ {
+ Logger.Warning("InRangeUnOccluded check performed over extreme range. Limiting CollisionRay size.");
+ length = MaxRaycastRange;
+ }
+
var occluderSystem = Get();
var entMan = IoCManager.Resolve();
- if (!origin.InRange(other, range)) return false;
-
- var dir = other.Position - origin.Position;
-
- if (dir.LengthSquared.Equals(0f)) return true;
- if (range > 0f && !(dir.LengthSquared <= range * range)) return false;
predicate ??= _ => false;
var ray = new Ray(origin.Position, dir.Normalized);
var rayResults = occluderSystem
- .IntersectRayWithPredicate(origin.MapId, ray, dir.Length, predicate.Invoke, false).ToList();
+ .IntersectRayWithPredicate(origin.MapId, ray, length, predicate.Invoke, false).ToList();
if (rayResults.Count == 0) return true;
diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs
index 783d7a7c03..e219effae8 100644
--- a/Content.Shared/Interaction/SharedInteractionSystem.cs
+++ b/Content.Shared/Interaction/SharedInteractionSystem.cs
@@ -49,6 +49,8 @@ namespace Content.Shared.Interaction
public const float InteractionRange = 2;
public const float InteractionRangeSquared = InteractionRange * InteractionRange;
+ public const float MaxRaycastRange = 100;
+
public delegate bool Ignored(EntityUid entity);
public override void Initialize()
@@ -322,19 +324,24 @@ namespace Content.Shared.Interaction
// Have to be on same map regardless.
if (other.MapId != origin.MapId) return false;
- // Uhh this does mean we could raycast infinity distance so may need to limit it.
var dir = other.Position - origin.Position;
- var lengthSquared = dir.LengthSquared;
-
- if (lengthSquared.Equals(0f)) return true;
+ var length = dir.Length;
// If range specified also check it
- if (range > 0f && lengthSquared > range * range) return false;
+ if (range > 0f && length > range) return false;
+
+ if (MathHelper.CloseTo(length, 0)) return true;
predicate ??= _ => false;
+ if (length > MaxRaycastRange)
+ {
+ Logger.Warning("InRangeUnobstructed check performed over extreme range. Limiting CollisionRay size.");
+ length = MaxRaycastRange;
+ }
+
var ray = new CollisionRay(origin.Position, dir.Normalized, (int) collisionMask);
- var rayResults = _sharedBroadphaseSystem.IntersectRayWithPredicate(origin.MapId, ray, dir.Length, predicate.Invoke, false).ToList();
+ var rayResults = _sharedBroadphaseSystem.IntersectRayWithPredicate(origin.MapId, ray, length, predicate.Invoke, false).ToList();
if (rayResults.Count == 0) return true;