Exemple #1
0
        private static Vector2D?FindClosestPosition(Vector2D position)
        {
            var physicsSpace   = ServerWorldService.GetPhysicsSpace();
            var collisionGroup = CollisionGroup.Default;

            if (IsValidPosition(
                    // round position
                    position.ToVector2Ushort().ToVector2D()))
            {
                // can teleport right there
                return(position);
            }

            // check nearby tiles
            var tile = ServerWorldService.GetTile(position.ToVector2Ushort());

            foreach (var neighborTile in tile.EightNeighborTiles)
            {
                if (!neighborTile.IsValidTile)
                {
                    continue;
                }

                var neighborTilePosition = neighborTile.Position.ToVector2D();
                if (IsValidPosition(neighborTilePosition))
                {
                    return(neighborTilePosition);
                }
            }

            return(null);

            // Local function for checking if the position is valid.
            bool IsValidPosition(Vector2D pos)
            {
                using var objectsNearby = physicsSpace.TestRectangle(
                          // include some padding, otherwise the check will include border-objects
                          position: pos + (0.01, 0.01),
                          size: (0.98, 0.98),
                          collisionGroup: collisionGroup,
                          sendDebugEvent: false);
                if (objectsNearby.Count > 0)
                {
                    return(false);
                }

                var posTile = Server.World.GetTile(pos.ToVector2Ushort());

                return(ServerCharacterSpawnHelper.IsValidSpawnTile(posTile,
                                                                   checkNeighborTiles: false));
            }
        }
        private static Vector2D FindClosestPosition(Vector2D position)
        {
            var physicsSpace   = ServerWorldService.GetPhysicsSpace();
            var collisionGroup = CollisionGroup.GetDefault();

            if (IsValidPosition(
                    // round position
                    position.ToVector2Ushort().ToVector2D()))
            {
                // can teleport right there
                return(position);
            }

            // check nearby tiles
            var tile = ServerWorldService.GetTile(position.ToVector2Ushort());

            foreach (var neighborTile in tile.EightNeighborTiles)
            {
                if (!neighborTile.IsValidTile)
                {
                    continue;
                }

                var neighborTilePosition = neighborTile.Position.ToVector2D();
                if (IsValidPosition(neighborTilePosition))
                {
                    return(neighborTilePosition);
                }
            }

            throw new Exception("No empty position available nearby.");

            // Local function for checking if the position is valid.
            bool IsValidPosition(Vector2D pos)
            {
                using (var objectsNearby = physicsSpace.TestRectangle(
                           // include some padding, otherwise the check will include border-objects
                           position: pos + (0.01, 0.01),
                           size: (0.98, 0.98),
                           collisionGroup: collisionGroup,
                           sendDebugEvent: false))
                {
                    return(objectsNearby.Count == 0);
                }
            }
        }
        public static bool IsPositionValidForCharacterSpawn(
            Vector2D position,
            bool isPlayer)
        {
            if (!IsValidSpawnPosition(position))
            {
                return(false);
            }

            var physicsSpace = ServerWorldService.GetPhysicsSpace();

            foreach (var t in physicsSpace.TestCircle(position,
                                                      SpawnNoPlayerBuiltStructuresRadius,
                                                      CollisionGroups.Default,
                                                      sendDebugEvent: false).EnumerateAndDispose())
            {
                if (t.PhysicsBody.AssociatedWorldObject?.ProtoWorldObject is IProtoObjectStructure)
                {
                    // some structure nearby
                    return(false);
                }
            }

            if (isPlayer)
            {
                // check if mobs nearby
                foreach (var t in physicsSpace.TestCircle(position,
                                                          SpawnPlayerNoMobsRadius,
                                                          CollisionGroups.Default,
                                                          sendDebugEvent: false).EnumerateAndDispose())
                {
                    if (t.PhysicsBody.AssociatedWorldObject is ICharacter otherCharacter &&
                        otherCharacter.IsNpc)
                    {
                        // mobs nearby
                        return(false);
                    }
                }
            }
            else // a mob
            {
                // check if players nearby
                foreach (var t in physicsSpace.TestCircle(position,
                                                          SpawnMobNoPlayersRadius,
                                                          CollisionGroups.Default,
                                                          sendDebugEvent: false).EnumerateAndDispose())
                {
                    if (t.PhysicsBody.AssociatedWorldObject is ICharacter otherCharacter &&
                        !otherCharacter.IsNpc)
                    {
                        // players nearby
                        return(false);
                    }
                }
            }

            // check if any physics object nearby
            using (var objectsNearby = physicsSpace.TestCircle(position,
                                                               SpawnNoPhysicsObjectsRadius,
                                                               CollisionGroups.Default,
                                                               sendDebugEvent: false))
            {
                if (objectsNearby.Count > 0)
                {
                    // some physical object nearby
                    return(false);
                }
            }

            return(true);
        }
Exemple #4
0
        public static bool IsPositionValidForCharacterSpawn(
            Vector2D position,
            bool isPlayer)
        {
            var tile = ServerWorldService.GetTile(position.ToVector2Ushort());

            if (!IsValidTile(tile) ||
                tile.EightNeighborTiles.Any(t => !IsValidTile(t)))
            {
                // cliff/slope or water nearby
                return(false);
            }

            var physicsSpace = ServerWorldService.GetPhysicsSpace();

            using (var objectsNearby = physicsSpace.TestCircle(
                       position,
                       SpawnNoPlayerBuiltStructuresRadius,
                       CollisionGroups.Default,
                       sendDebugEvent: false))
            {
                if (objectsNearby.Any(
                        t => t.PhysicsBody.AssociatedWorldObject?.ProtoWorldObject is IProtoObjectStructure))
                {
                    // some structure nearby
                    return(false);
                }
            }

            if (isPlayer)
            {
                // check if mobs nearby
                using (var mobsNearby = physicsSpace.TestCircle(
                           position,
                           SpawnPlayerNoMobsRadius,
                           CollisionGroups.Default,
                           sendDebugEvent: false))
                {
                    if (mobsNearby.Any(
                            t => t.PhysicsBody.AssociatedWorldObject is ICharacter otherCharacter &&
                            otherCharacter.IsNpc))
                    {
                        // mobs nearby
                        return(false);
                    }
                }
            }
            else
            {
                // check if mobs nearby
                using (var mobsNearby = physicsSpace.TestCircle(
                           position,
                           SpawnMobNoPlayersRadius,
                           CollisionGroups.Default,
                           sendDebugEvent: false))
                {
                    if (mobsNearby.Any(
                            t => t.PhysicsBody.AssociatedWorldObject is ICharacter otherCharacter &&
                            !otherCharacter.IsNpc))
                    {
                        // players nearby
                        return(false);
                    }
                }
            }

            // check if any physics object nearby
            using (var objectsNearby = physicsSpace.TestCircle(
                       position,
                       SpawnNoPhysicsObjectsRadius,
                       CollisionGroups.Default,
                       sendDebugEvent: false))
            {
                if (objectsNearby.Count > 0)
                {
                    // some physical object nearby
                    return(false);
                }
            }

            return(true);
        }