fix: fix non-access checking EntityTargetActions (#38731)

This commit is contained in:
Perry Fraser
2025-07-22 15:34:39 -04:00
committed by GitHub
parent f16175a6e3
commit 1ee7dffe6d
5 changed files with 35 additions and 12 deletions

View File

@@ -334,7 +334,12 @@ namespace Content.Client.Actions
private void OnEntityTargetAttempt(Entity<EntityTargetActionComponent> ent, ref ActionTargetAttemptEvent args)
{
if (args.Handled || args.Input.EntityUid is not { Valid: true } entity)
if (args.Handled)
return;
args.Handled = true;
if (args.Input.EntityUid is not { Valid: true } entity)
return;
// let world target component handle it
@@ -345,8 +350,6 @@ namespace Content.Client.Actions
return;
}
args.Handled = true;
var action = args.Action;
var user = args.User;

View File

@@ -1,6 +1,6 @@
using Content.Shared.Actions;
using Content.Shared.Interaction;
using Robust.Shared.GameStates;
using Content.Shared.Interaction;
using Content.Shared.Physics;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared.Actions.Components;
@@ -37,6 +37,16 @@ public sealed partial class TargetActionComponent : Component
[DataField]
public bool CheckCanAccess = true;
/// <summary>
/// The collision group to use to check for accessibility if <see cref="CheckCanAccess" /> is true.
/// </summary>
[DataField]
public CollisionGroup AccessMask = SharedInteractionSystem.InRangeUnobstructedMask;
/// <summary>
/// The allowed range for a target to be. If zero or negative, the range check is skipped,
/// unless <see cref="CheckCanAccess"/> is true.
/// </summary>
[DataField]
public float Range = SharedInteractionSystem.InteractionRange;

View File

@@ -417,13 +417,18 @@ public abstract class SharedActionsSystem : EntitySystem
return comp.CanTargetSelf;
var targetAction = Comp<TargetActionComponent>(uid);
// not using the ValidateBaseTarget logic since its raycast fails if the target is e.g. a wall
if (targetAction.CheckCanAccess)
return _interaction.InRangeAndAccessible(user, target, range: targetAction.Range);
return _interaction.InRangeAndAccessible(user, target, targetAction.Range, targetAction.AccessMask);
// if not just checking pure range, let stored entities be targeted by actions
// if it's out of range it probably isn't stored anyway...
return _interaction.CanAccessViaStorage(user, target);
// Just check normal in range, allowing <= 0 range to mean infinite range.
if (targetAction.Range > 0
&& !_transform.InRange(user, target, targetAction.Range))
return false;
// If checkCanAccess isn't set, we allow targeting things in containers
return _interaction.IsAccessible(user, target);
}
public bool ValidateWorldTarget(EntityUid user, EntityCoordinates target, Entity<WorldTargetActionComponent> ent)

View File

@@ -86,7 +86,11 @@ namespace Content.Shared.Interaction
private EntityQuery<UseDelayComponent> _delayQuery;
private EntityQuery<ActivatableUIComponent> _uiQuery;
private const CollisionGroup InRangeUnobstructedMask = CollisionGroup.Impassable | CollisionGroup.InteractImpassable;
/// <summary>
/// The collision mask used by default for
/// <see cref="InRangeUnobstructed(MapCoordinates,MapCoordinates,float,CollisionGroup,Ignored?,bool)" />
/// </summary>
public const CollisionGroup InRangeUnobstructedMask = CollisionGroup.Impassable | CollisionGroup.InteractImpassable;
public const float InteractionRange = 1.5f;
public const float InteractionRangeSquared = InteractionRange * InteractionRange;

View File

@@ -35,7 +35,8 @@
sprite: Objects/Magic/Eldritch/eldritch_actions.rsi
state: voidblink
- type: TargetAction
checkCanAccess: false
accessMask:
- Opaque
repeat: false
range: 16
- type: EntityTargetAction