コード例 #1
0
 private static List <ICommonSession> PasInRange(IEnumerable <ICommonSession> players, MapCoordinates position, float range)
 {
     return(players.Where(x =>
                          x.AttachedEntity != null &&
                          position.InRange(x.AttachedEntity.Transform.MapPosition, range))
            .ToList());
 }
コード例 #2
0
        /// <summary>
        ///     Checks that these coordinates are within a certain distance without any
        ///     entity that matches the collision mask obstructing them.
        ///     If the <paramref name="range"/> is zero or negative,
        ///     this method will only check if nothing obstructs the two sets
        ///     of coordinates.
        /// </summary>
        /// <param name="origin">Set of coordinates to use.</param>
        /// <param name="other">Other set of coordinates to use.</param>
        /// <param name="range">
        ///     Maximum distance between the two sets of coordinates.
        /// </param>
        /// <param name="collisionMask">The mask to check for collisions.</param>
        /// <param name="predicate">
        ///     A predicate to check whether to ignore an entity or not.
        ///     If it returns true, it will be ignored.
        /// </param>
        /// <param name="ignoreInsideBlocker">
        ///     If true and <see cref="origin"/> or <see cref="other"/> are inside
        ///     the obstruction, ignores the obstruction and considers the interaction
        ///     unobstructed.
        ///     Therefore, setting this to true makes this check more permissive,
        ///     such as allowing an interaction to occur inside something impassable
        ///     (like a wall). The default, false, makes the check more restrictive.
        /// </param>
        /// <returns>
        ///     True if the two points are within a given range without being obstructed.
        /// </returns>
        public bool InRangeUnobstructed(
            MapCoordinates origin,
            MapCoordinates other,
            float range = InteractionRange,
            CollisionGroup collisionMask = CollisionGroup.Impassable,
            Ignored?predicate            = null,
            bool ignoreInsideBlocker     = false)
        {
            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 CollisionRay(origin.Position, dir.Normalized, (int)collisionMask);
            var rayResults = _sharedBroadphaseSystem.IntersectRayWithPredicate(origin.MapId, ray, dir.Length, predicate.Invoke, false).ToList();

            if (rayResults.Count == 0)
            {
                return(true);
            }

            // TODO: Wot? This should just be in the predicate.
            if (!ignoreInsideBlocker)
            {
                return(false);
            }

            foreach (var result in rayResults)
            {
                if (!result.HitEntity.TryGetComponent(out IPhysBody? p))
                {
                    continue;
                }

                var bBox = p.GetWorldAABB();

                if (bBox.Contains(origin.Position) || bBox.Contains(other.Position))
                {
                    continue;
                }

                return(false);
            }

            return(true);
        }
コード例 #3
0
        public static bool InRangeUnOccluded(MapCoordinates origin, MapCoordinates other, float range, Ignored?predicate, bool ignoreInsideBlocker = true)
        {
            var occluderSystem = Get <OccluderSystem>();

            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();

            if (rayResults.Count == 0)
            {
                return(true);
            }

            if (!ignoreInsideBlocker)
            {
                return(false);
            }

            foreach (var result in rayResults)
            {
                if (!result.HitEntity.TryGetComponent(out OccluderComponent? o))
                {
                    continue;
                }

                var bBox = o.BoundingBox.Translated(o.Owner.Transform.WorldPosition);

                if (bBox.Contains(origin.Position) || bBox.Contains(other.Position))
                {
                    continue;
                }

                return(false);
            }

            return(true);
        }
コード例 #4
0
 /// <summary>
 ///     Gets all players inside of a circle.
 /// </summary>
 /// <param name="worldPos">Position of the circle in world-space.</param>
 /// <param name="range">Radius of the circle in world units.</param>
 /// <returns></returns>
 public List <IPlayerSession> GetPlayersInRange(MapCoordinates worldPos, int range)
 {
     _sessionsLock.EnterReadLock();
     //TODO: This needs to be moved to the PVS system.
     try
     {
         return
             (_sessions.Values.Where(x =>
                                     x.AttachedEntity != null && worldPos.InRange(x.AttachedEntity.Transform.MapPosition, range))
              .Cast <IPlayerSession>()
              .ToList());
     }
     finally
     {
         _sessionsLock.ExitReadLock();
     }
 }
コード例 #5
0
        /// <summary>
        ///     Checks that these coordinates are within a certain distance without any
        ///     entity that matches the collision mask obstructing them.
        ///     If the <paramref name="range"/> is zero or negative,
        ///     this method will only check if nothing obstructs the two sets
        ///     of coordinates.
        /// </summary>
        /// <param name="origin">Set of coordinates to use.</param>
        /// <param name="other">Other set of coordinates to use.</param>
        /// <param name="range">
        ///     Maximum distance between the two sets of coordinates.
        /// </param>
        /// <param name="collisionMask">The mask to check for collisions.</param>
        /// <param name="predicate">
        ///     A predicate to check whether to ignore an entity or not.
        ///     If it returns true, it will be ignored.
        /// </param>
        /// <param name="ignoreInsideBlocker">
        ///     If true and <see cref="origin"/> or <see cref="other"/> are inside
        ///     the obstruction, ignores the obstruction and considers the interaction
        ///     unobstructed.
        ///     Therefore, setting this to true makes this check more permissive,
        ///     such as allowing an interaction to occur inside something impassable
        ///     (like a wall). The default, false, makes the check more restrictive.
        /// </param>
        /// <returns>
        ///     True if the two points are within a given range without being obstructed.
        /// </returns>
        public bool InRangeUnobstructed(
            MapCoordinates origin,
            MapCoordinates other,
            float range = InteractionRange,
            CollisionGroup collisionMask = CollisionGroup.Impassable,
            Ignored predicate            = null,
            bool ignoreInsideBlocker     = false)
        {
            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 CollisionRay(origin.Position, dir.Normalized, (int)collisionMask);
            var rayResults = _physicsManager.IntersectRayWithPredicate(origin.MapId, ray, dir.Length, predicate.Invoke, false).ToList();

            if (rayResults.Count == 0)
            {
                return(true);
            }

            if (!ignoreInsideBlocker)
            {
                return(false);
            }

            if (rayResults.Count <= 0)
            {
                return(false);
            }

            return((rayResults[0].HitPos - other.Position).Length < 1f);
        }
コード例 #6
0
        public static bool InRangeUnOccluded(MapCoordinates origin, MapCoordinates other, float range, Ignored predicate, bool ignoreInsideBlocker = true)
        {
            var occluderSystem = Get <OccluderSystem>();

            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();

            if (rayResults.Count == 0)
            {
                return(true);
            }

            if (!ignoreInsideBlocker)
            {
                return(false);
            }

            if (rayResults.Count <= 0)
            {
                return(false);
            }

            return((rayResults[0].HitPos - other.Position).Length < 1f);
        }
コード例 #7
0
        /// <summary>
        ///     Checks that these coordinates are within a certain distance without any
        ///     entity that matches the collision mask obstructing them.
        ///     If the <paramref name="range"/> is zero or negative,
        ///     this method will only check if nothing obstructs the two sets of coordinates..
        /// </summary>
        /// <param name="coords">Set of coordinates to use.</param>
        /// <param name="otherCoords">Other set of coordinates to use.</param>
        /// <param name="range">maximum distance between the two sets of coordinates.</param>
        /// <param name="collisionMask">the mask to check for collisions</param>
        /// <param name="predicate">A predicate to check whether to ignore an entity or not. If it returns true, it will be ignored.</param>
        /// <param name="ignoreInsideBlocker">if true and the coordinates are inside the obstruction, ignores the obstruction and
        /// considers the interaction unobstructed. Therefore, setting this to true makes this check more permissive, such
        /// as allowing an interaction to occur inside something impassable (like a wall). The default, false,
        /// makes the check more restrictive.</param>
        /// <returns>True if the two points are within a given range without being obstructed.</returns>
        public bool InRangeUnobstructed(MapCoordinates coords, MapCoordinates otherCoords, float range = InteractionRange,
                                        int collisionMask = (int)CollisionGroup.Impassable, Func <IEntity, bool> predicate = null, bool ignoreInsideBlocker = false)
        {
            if (!coords.InRange(otherCoords, range))
            {
                return(false);
            }

            var dir = otherCoords.Position - coords.Position;

            if (dir.LengthSquared.Equals(0f))
            {
                return(true);
            }
            if (range > 0f && !(dir.LengthSquared <= range * range))
            {
                return(false);
            }

            var ray        = new CollisionRay(coords.Position, dir.Normalized, collisionMask);
            var rayResults = _physicsManager.IntersectRayWithPredicate(coords.MapId, ray, dir.Length, predicate, returnOnFirstHit: false).ToList();

            return(rayResults.Count == 0 || (ignoreInsideBlocker && rayResults.Count > 0 && (rayResults[0].HitPos - otherCoords.Position).Length < 1f));
        }