示例#1
0
        public override void Perform(MobUpdateContext context)
        {
            NavMesh navMesh   = context.moveRequest.Room.runtime_nav_mesh;
            float   max_range = 5.0f; // Compute max range from mob type

            uint[] navCells = navMesh.ComputeNavCellsInRadius(context.mob.Position, max_range, false);
            Random rng      = context.mob.AIState.behavior_data.GetMobRandomNumberGenerator();

            RNGUtilities.DeterministicKnuthShuffle(rng, navCells);
            Point3d targetPosition = new Point3d(context.mob.Position);

            // Pick the first random nav cell in range that we have line of sight to
            foreach (uint navCellIndex in navCells)
            {
                Point3d testTarget = navMesh.ComputeNavCellCenter(navCellIndex);
                bool    canSee     = navMesh.PointCanSeeOtherPoint(context.mob.Position, testTarget);

                if (canSee)
                {
                    targetPosition = testTarget;
                    break;
                }
            }

            // Compute the side effect of actually moving the mob on the update context
            context.MoveMob(targetPosition);
            context.MobPostDialog("Soo bored...");
        }
示例#2
0
        private void RandomlyRemoveRooms(
            Random rng)
        {
            int originalRoomCount = m_roomGrid.GetLength(0) * m_roomGrid.GetLength(1) * m_roomGrid.GetLength(2);
            int roomCount         = originalRoomCount;

            // Determine the minimum number of rooms we allow for this level
            Range <float> roomDensityRange = m_worldTemplate.DungeonRoomDensity;
            float         roomDensity      = RNGUtilities.RandomFloat(rng, roomDensityRange.Min, roomDensityRange.Max);
            int           minRoomCount     = (int)(Math.Ceiling((float)originalRoomCount * roomDensity));

            // Generate a randomized list of rooms
            IList <RoomIndex> randomRoomIndices = GetRoomIndexList();

            RNGUtilities.DeterministicKnuthShuffle(rng, randomRoomIndices);

            // Randomly remove rooms one at time until we can't remove any more
            foreach (RoomIndex roomIndex in randomRoomIndices)
            {
                if (CanRemoveRoomFromGrid(roomIndex))
                {
                    RemoveRoomFromGrid(roomIndex);

                    roomCount--;

                    if (roomCount <= minRoomCount)
                    {
                        break;
                    }
                }
            }
        }
        private string GenerateNewSessionKey()
        {
            // Generate a random 128-bit string
            string newSessionKey = RNGUtilities.CreateNonDeterministicRandomBase64String(SESSION_KEY_BITS);

            // Make sure this is actually a new key
            while (m_sessions.ContainsKey(newSessionKey))
            {
                newSessionKey = RNGUtilities.CreateNonDeterministicRandomBase64String(SESSION_KEY_BITS);
            }

            return(newSessionKey);
        }
示例#4
0
        public static MobSpawner CreateMobSpawner(RoomKey roomKey, MobSpawnerTemplate template, MobSpawnTableSet spawnTableSet, Random rng)
        {
            MobSpawner newMobSpawner = new MobSpawner();

            newMobSpawner.m_room_key              = new RoomKey(roomKey);
            newMobSpawner.m_mob_spawner_id        = -1; // spawner ID not set until this gets saved into the DB
            newMobSpawner.m_position              = new Point3d(template.Position);
            newMobSpawner.m_remaining_spawn_count = RNGUtilities.RandomInt(rng, 0, template.MaxSpawnCount);
            newMobSpawner.m_random_seed           = rng.Next();
            newMobSpawner.m_spawn_table           = spawnTableSet.GetMobSpawnTableByName(template.SpawnTableName);

            return(newMobSpawner);
        }
示例#5
0
        public static int CreateGame(
            AsyncRPGDataContext context,
            int account_id,
            string game_name,
            GameConstants.eDungeonSize dungeonSize,
            GameConstants.eDungeonDifficulty dungeonDifficulty,
            bool irc_enabled,
            string irc_server,
            int irc_port,
            bool irc_encryption_enabled)
        {
            int new_game_id = -1;

            // Create a random 256-bit (32 byte) encryption key for encrypting chat
            string irc_encryption_key = RNGUtilities.CreateNonDeterministicRandomBase64String(256);

            Debug.Assert(irc_encryption_key.Length == 44);

            if (irc_server.Length == 0)
            {
                irc_server = IrcConstants.DEFAULT_IRC_SERVER;
            }

            if (irc_port < IrcConstants.LOWEST_VALID_IRC_PORT || irc_port > IrcConstants.HIGHEST_VALID_IRC_PORT)
            {
                irc_port = IrcConstants.DEFAULT_IRC_PORT;
            }

            {
                Games newGame = new Games
                {
                    OwnerAccountID      = account_id,
                    Name                = game_name,
                    DungeonSize         = (int)dungeonSize,
                    DungeonDifficulty   = (int)dungeonDifficulty,
                    IrcEnabed           = irc_enabled,
                    IrcServer           = irc_server,
                    IrcPort             = irc_port,
                    IrcEncryptionKey    = irc_encryption_key,
                    IrcEncryptionEnabed = irc_encryption_enabled
                };

                context.Games.InsertOnSubmit(newGame);
                context.SubmitChanges();

                new_game_id = newGame.GameID;
            }

            return(new_game_id);
        }
示例#6
0
        private bool ChooseMobSpawners(
            RequestCache requestCache,
            out string result_code)
        {
            bool success           = true;
            int  desiredSpawnCount = m_max_spawn_count - m_current_spawn_count;

            result_code = SuccessMessages.GENERAL_SUCCESS;

            // Compute a list of all the occupied nav cells
            List <int> occupiedNavCells =
                requestCache.GetMobs(m_room.room_key).Select(m => m_room.runtime_nav_mesh.ComputeNavRefAtPoint(m.Position).NavCellIndex).ToList();

            // Only use mob spawners that have a non zero remaining spawn count
            // and don't have a mob currently standing over stop of it.
            List <MobSpawner> availableMobSpawners =
                (from s in m_room.mobSpawners
                 where s.RemainingSpawnCount > 0 &&
                 !occupiedNavCells.Contains(m_room.runtime_nav_mesh.ComputeNavRefAtPoint(s.Position).NavCellIndex)
                 select s).ToList <MobSpawner>();

            // Shuffle the list and pick the top N spawners (where N is based on difficulty)
            if (availableMobSpawners.Count > 0)
            {
                RNGUtilities.DeterministicKnuthShuffle(m_room.random_seed, availableMobSpawners);

                for (int spawnerIndex = 0;
                     spawnerIndex < availableMobSpawners.Count && spawnerIndex < desiredSpawnCount;
                     spawnerIndex++)
                {
                    m_chosenMobSpawners.Add(availableMobSpawners[spawnerIndex]);
                }
            }

            return(success);
        }
示例#7
0
        private int CreateFullyConnectedRoomGrid(
            Random rng)
        {
            int lateralRoomCount = m_worldTemplate.DungeonLateralRoomCount;
            int floorCount       = m_worldTemplate.DungeonFloorCount;
            int totalRoomCount   = lateralRoomCount * lateralRoomCount * floorCount;

            m_roomGrid   = new RoomLayout[lateralRoomCount, lateralRoomCount, floorCount];
            m_minRoomKey = new RoomKey(m_gameId, -lateralRoomCount / 2, -lateralRoomCount / 2, 0);

            // Fully connect the rooms on each floor, but leave each floor unconnected initially
            for (RoomIndexIterator iterator = new RoomIndexIterator(m_roomGrid, RoomIndexIterator.eIterationType.allRooms);
                 iterator.Valid;
                 iterator.Next())
            {
                RoomIndex roomIndex = iterator.Current;

                RoomKey roomKey =
                    new RoomKey(
                        m_gameId,
                        roomIndex.X - lateralRoomCount / 2,
                        roomIndex.Y - lateralRoomCount / 2,
                        roomIndex.Z);
                RoomLayout room = new RoomLayout(roomKey);

                if (roomIndex.X > 0)
                {
                    room.RoomFlagPortalOnSide(MathConstants.eSignedDirection.negative_x, true);
                }

                if (roomIndex.X < lateralRoomCount - 1)
                {
                    room.RoomFlagPortalOnSide(MathConstants.eSignedDirection.positive_x, true);
                }

                if (roomIndex.Y > 0)
                {
                    room.RoomFlagPortalOnSide(MathConstants.eSignedDirection.negative_y, true);
                }

                if (roomIndex.Y < lateralRoomCount - 1)
                {
                    room.RoomFlagPortalOnSide(MathConstants.eSignedDirection.positive_y, true);
                }

                m_roomGrid[roomIndex.X, roomIndex.Y, roomIndex.Z] = room;
            }

            // Randomly add stairs connecting each floor
            for (int z_index = 0; z_index < floorCount - 1; z_index++)
            {
                Range <int>       stairsRange       = m_worldTemplate.StairsPerFloor;
                IList <RoomIndex> randomRoomIndices = GetRoomIndexListForFloor(z_index);
                int desiredStairsCount = RNGUtilities.RandomInt(rng, stairsRange.Min, stairsRange.Max);
                int currentStairsCount = 0;

                RNGUtilities.DeterministicKnuthShuffle(rng, randomRoomIndices);

                foreach (RoomIndex roomIndex in randomRoomIndices)
                {
                    Room room      = m_roomGrid[roomIndex.X, roomIndex.Y, roomIndex.Z];
                    Room roomAbove = m_roomGrid[roomIndex.X, roomIndex.Y, roomIndex.Z + 1];

                    // Only consider rooms of the configuration X+X-Y+Y- to add stairs to
                    // because we only have rooms with stairs for the templates
                    // X+X-Y+Y-Z+ and X+X-Y+Y-Z-
                    // We do this so that we can get away with 18 room templates rather than 64
                    if (room.RoomHasAllPossibleDoors && !room.RoomHasStairs)
                    {
                        room.RoomFlagPortalOnSide(MathConstants.eSignedDirection.positive_z, true);
                        roomAbove.RoomFlagPortalOnSide(MathConstants.eSignedDirection.negative_z, true);
                        ++currentStairsCount;
                    }

                    if (currentStairsCount >= desiredStairsCount)
                    {
                        break;
                    }
                }
            }

            return(totalRoomCount);
        }
示例#8
0
        public static Portal CreatePortal(Room room, MathConstants.eSignedDirection roomSide)
        {
            Portal newPortal = new Portal();

            newPortal.portal_id        = -1; // portal ID not set until this portal gets saved into the DB
            newPortal.target_portal_id = -1;
            newPortal.room_side        = roomSide;
            newPortal.room_x           = room.room_key.x;
            newPortal.room_y           = room.room_key.y;
            newPortal.room_z           = room.room_key.z;

            switch (roomSide)
            {
            case MathConstants.eSignedDirection.positive_x:
            {
                Point3d p1 = WorldConstants.ROOM_BOUNDS.Max;
                Point3d p0 = p1 - Vector3d.I * WorldConstants.PORTAL_WIDTH - Vector3d.J * WorldConstants.ROOM_Y_SIZE;

                newPortal.bounding_box = new AABB3d(p0, p1);
            }
            break;

            case MathConstants.eSignedDirection.negative_x:
            {
                Point3d p0 = WorldConstants.ROOM_BOUNDS.Min;
                Point3d p1 = p0 + Vector3d.I * WorldConstants.PORTAL_WIDTH + Vector3d.J * WorldConstants.ROOM_Y_SIZE;

                newPortal.bounding_box = new AABB3d(p0, p1);
            }
            break;

            case MathConstants.eSignedDirection.positive_y:
            {
                Point3d p1 = WorldConstants.ROOM_BOUNDS.Max;
                Point3d p0 = p1 - Vector3d.I * WorldConstants.ROOM_X_SIZE - Vector3d.J * WorldConstants.PORTAL_WIDTH;

                newPortal.bounding_box = new AABB3d(p0, p1);
            }
            break;

            case MathConstants.eSignedDirection.negative_y:
            {
                Point3d p0 = WorldConstants.ROOM_BOUNDS.Min;
                Point3d p1 = p0 + Vector3d.I * WorldConstants.ROOM_X_SIZE + Vector3d.J * WorldConstants.PORTAL_WIDTH;

                newPortal.bounding_box = new AABB3d(p0, p1);
            }
            break;

            case MathConstants.eSignedDirection.positive_z:
            case MathConstants.eSignedDirection.negative_z:
            {
                int     column = RNGUtilities.RandomInt(WorldConstants.ROOM_X_TILES / 3, 2 * WorldConstants.ROOM_X_TILES / 3);
                int     row    = RNGUtilities.RandomInt(WorldConstants.ROOM_Y_TILES / 3, 2 * WorldConstants.ROOM_Y_TILES / 3);
                Point3d p0     = WorldConstants.GetTilePosition(column, row);
                Point3d p1     = p0 + Vector3d.I * WorldConstants.ROOM_TILE_SIZE + Vector3d.J * WorldConstants.ROOM_TILE_SIZE;

                newPortal.bounding_box = new AABB3d(p0, p1);
            }
            break;
            }

            return(newPortal);
        }