/// <summary>
        ///     Raises an event directed at both the user and the target entity to check whether a user is capable of
        ///     interacting with this entity.
        /// </summary>
        /// <remarks>
        ///     If this is a generic interaction without a target (e.g., stop-drop-and-roll when burning), the target
        ///     may be null. Note that this is checked by <see cref="SharedInteractionSystem"/>. In the majority of
        ///     cases, systems that provide interactions will not need to check this themselves, though they may need to
        ///     check other blockers like <see cref="CanPickup(EntityUid)"/>
        /// </remarks>
        /// <returns></returns>
        public bool CanInteract(EntityUid user, EntityUid?target)
        {
            var ev = new InteractionAttemptEvent(user, target);

            RaiseLocalEvent(user, ev, true);

            if (ev.Cancelled)
            {
                return(false);
            }

            if (target == null)
            {
                return(true);
            }

            var targetEv = new GettingInteractedWithAttemptEvent(user, target);

            RaiseLocalEvent(target.Value, targetEv, true);

            if (!targetEv.Cancelled)
            {
                InteractWithItem(user, target.Value);
            }

            return(!targetEv.Cancelled);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Checks if the user can vault the dragged entity onto the the target
        /// </summary>
        /// <param name="user">The user that wants to vault the entity</param>
        /// <param name="dragged">The entity that is being vaulted</param>
        /// <param name="target">The object that is being vaulted onto</param>
        /// <param name="reason">The reason why it cant be dropped</param>
        /// <returns></returns>
        private bool CanVault(EntityUid user, EntityUid dragged, EntityUid target, out string reason)
        {
            if (!EntitySystem.Get <ActionBlockerSystem>().CanInteract(user, dragged))
            {
                reason = Loc.GetString("comp-climbable-cant-interact");
                return(false);
            }

            // CanInteract() doesn't support checking a second "target" entity.
            // Doing so manually:
            var ev = new GettingInteractedWithAttemptEvent(user, target);

            _entities.EventBus.RaiseLocalEvent(target, ev);
            if (ev.Cancelled)
            {
                reason = Loc.GetString("comp-climbable-cant-interact");
                return(false);
            }

            if (!_entities.HasComponent <ClimbingComponent>(dragged))
            {
                reason = Loc.GetString("comp-climbable-cant-climb");
                return(false);
            }

            bool Ignored(EntityUid entity) => entity == target || entity == user || entity == dragged;

            var sys = EntitySystem.Get <SharedInteractionSystem>();

            if (!sys.InRangeUnobstructed(user, target, Range, predicate: Ignored) ||
                !sys.InRangeUnobstructed(user, dragged, Range, predicate: Ignored))
            {
                reason = Loc.GetString("comp-climbable-cant-reach");
                return(false);
            }

            reason = string.Empty;
            return(true);
        }
 private void OnInteractionAttempt(EntityUid uid, SubFloorHideComponent component, GettingInteractedWithAttemptEvent args)
 {
     // No interactions with entities hidden under floor tiles.
     if (component.BlockInteractions && component.IsUnderCover)
     {
         args.Cancel();
     }
 }