Example #1
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;
                    }
                }
            }
        }
Example #2
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...");
        }
Example #3
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);
        }
Example #4
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);
        }