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
return;
}
- args.Handled = true;
-
var action = args.Action;
var user = args.User;
-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;
[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;
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);
+
+ // 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 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);
+ // 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)
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;
sprite: Objects/Magic/Eldritch/eldritch_actions.rsi
state: voidblink
- type: TargetAction
- checkCanAccess: false
+ accessMask:
+ - Opaque
repeat: false
range: 16
- type: EntityTargetAction