bypass interaction range checks for aghosts (#16955)

This commit is contained in:
Chief-Engineer
2023-06-01 19:50:17 -05:00
committed by GitHub
parent c8e8057c3a
commit 3bebb0d5e7
4 changed files with 23 additions and 4 deletions

View File

@@ -21,6 +21,7 @@ using Content.Shared.Physics;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Pulling; using Content.Shared.Pulling;
using Content.Shared.Pulling.Components; using Content.Shared.Pulling.Components;
using Content.Shared.Tag;
using Content.Shared.Throwing; using Content.Shared.Throwing;
using Content.Shared.Timing; using Content.Shared.Timing;
using Content.Shared.Verbs; using Content.Shared.Verbs;
@@ -66,6 +67,7 @@ namespace Content.Shared.Interaction
[Dependency] private readonly SharedPullingSystem _pullSystem = default!; [Dependency] private readonly SharedPullingSystem _pullSystem = default!;
[Dependency] private readonly InventorySystem _inventory = default!; [Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly TagSystem _tagSystem = default!;
private const CollisionGroup InRangeUnobstructedMask private const CollisionGroup InRangeUnobstructedMask
= CollisionGroup.Impassable | CollisionGroup.InteractImpassable; = CollisionGroup.Impassable | CollisionGroup.InteractImpassable;
@@ -254,7 +256,7 @@ namespace Content.Shared.Interaction
{ {
// This is for Admin/mapping convenience. If ever there are other ghosts that can still interact, this check // This is for Admin/mapping convenience. If ever there are other ghosts that can still interact, this check
// might need to be more selective. // might need to be more selective.
return !HasComp<SharedGhostComponent>(user); return !_tagSystem.HasTag(user, "BypassInteractionRangeChecks");
} }
/// <summary> /// <summary>
@@ -474,6 +476,7 @@ namespace Content.Shared.Interaction
/// A predicate to check whether to ignore an entity or not. /// A predicate to check whether to ignore an entity or not.
/// If it returns true, it will be ignored. /// If it returns true, it will be ignored.
/// </param> /// </param>
/// <param name="checkAccess">Perform range checks</param>
/// <returns> /// <returns>
/// True if the two points are within a given range without being obstructed. /// True if the two points are within a given range without being obstructed.
/// </returns> /// </returns>
@@ -482,12 +485,16 @@ namespace Content.Shared.Interaction
MapCoordinates other, MapCoordinates other,
float range = InteractionRange, float range = InteractionRange,
CollisionGroup collisionMask = InRangeUnobstructedMask, CollisionGroup collisionMask = InRangeUnobstructedMask,
Ignored? predicate = null) Ignored? predicate = null,
bool checkAccess = true)
{ {
// Have to be on same map regardless. // Have to be on same map regardless.
if (other.MapId != origin.MapId) if (other.MapId != origin.MapId)
return false; return false;
if (!checkAccess)
return true;
var dir = other.Position - origin.Position; var dir = other.Position - origin.Position;
var length = dir.Length; var length = dir.Length;
@@ -602,6 +609,11 @@ namespace Content.Shared.Interaction
{ {
return true; return true;
} }
// Entity can bypass range checks.
else if (!ShouldCheckAccess(origin))
{
return true;
}
// Out of range so don't raycast. // Out of range so don't raycast.
else if (distance > range) else if (distance > range)
{ {
@@ -626,7 +638,7 @@ namespace Content.Shared.Interaction
if (inRange) if (inRange)
{ {
var rayPredicate = GetPredicate(originPos, other, targetPos, targetRot, collisionMask, combinedPredicate); var rayPredicate = GetPredicate(originPos, other, targetPos, targetRot, collisionMask, combinedPredicate);
inRange = InRangeUnobstructed(originPos, targetPos, range, collisionMask, rayPredicate); inRange = InRangeUnobstructed(originPos, targetPos, range, collisionMask, rayPredicate, ShouldCheckAccess(origin));
} }
if (!inRange && popup && _gameTiming.IsFirstTimePredicted) if (!inRange && popup && _gameTiming.IsFirstTimePredicted)
@@ -772,7 +784,7 @@ namespace Content.Shared.Interaction
{ {
Ignored combinedPredicate = e => e == origin || (predicate?.Invoke(e) ?? false); Ignored combinedPredicate = e => e == origin || (predicate?.Invoke(e) ?? false);
var originPosition = Transform(origin).MapPosition; var originPosition = Transform(origin).MapPosition;
var inRange = InRangeUnobstructed(originPosition, other, range, collisionMask, combinedPredicate); var inRange = InRangeUnobstructed(originPosition, other, range, collisionMask, combinedPredicate, ShouldCheckAccess(origin));
if (!inRange && popup && _gameTiming.IsFirstTimePredicted) if (!inRange && popup && _gameTiming.IsFirstTimePredicted)
{ {

View File

@@ -10,6 +10,7 @@
- type: Tag - type: Tag
tags: tags:
- CanPilot - CanPilot
- BypassInteractionRangeChecks
- type: Input - type: Input
context: "aghost" context: "aghost"
- type: Ghost - type: Ghost

View File

@@ -60,3 +60,6 @@
baseSprintSpeed: 8 baseSprintSpeed: 8
baseWalkSpeed: 5 baseWalkSpeed: 5
- type: MovementIgnoreGravity - type: MovementIgnoreGravity
- type: Tag
tags:
- BypassInteractionRangeChecks

View File

@@ -73,6 +73,9 @@
- type: Tag - type: Tag
id: BulletFoam id: BulletFoam
- type: Tag
id: BypassInteractionRangeChecks
- type: Tag - type: Tag
id: CableCoil id: CableCoil