예제 #1
0
        private bool CreateMobSpawners(
            Random rng,
            out String result)
        {
            bool success = true;

            result = SuccessMessages.GENERAL_SUCCESS;

            for (RoomIndexIterator iterator = new RoomIndexIterator(m_roomGrid);
                 success && iterator.Valid;
                 iterator.Next())
            {
                RoomIndex    roomIndex    = iterator.Current;
                RoomLayout   room         = GetRoomByIndex(roomIndex);
                RoomTemplate roomTemplate = m_roomTemplateSet.GetTemplateByName(room.static_room_data.room_template_name);

                foreach (MobSpawnerTemplate mobSpawnerTemplate in roomTemplate.MobSpawnerTemplates)
                {
                    MobSpawner spawner =
                        MobSpawner.CreateMobSpawner(
                            room.room_key,
                            mobSpawnerTemplate,
                            m_mobSpawnTableSet,
                            rng);

                    // Don't bother adding mob spawners that don't have any spawns left
                    if (spawner.RemainingSpawnCount > 0)
                    {
                        room.mobSpawners.Add(spawner);
                    }
                }
            }

            return(success);
        }
예제 #2
0
        private bool CreateEnergyTanks(
            Random rng,
            out String result)
        {
            bool success = true;

            result = SuccessMessages.GENERAL_SUCCESS;

            for (RoomIndexIterator iterator = new RoomIndexIterator(m_roomGrid);
                 success && iterator.Valid;
                 iterator.Next())
            {
                RoomIndex    roomIndex    = iterator.Current;
                RoomLayout   room         = GetRoomByIndex(roomIndex);
                RoomTemplate roomTemplate = m_roomTemplateSet.GetTemplateByName(room.static_room_data.room_template_name);

                foreach (EnergyTankTemplate energyTankTemplate in roomTemplate.EnergyTankTemplates)
                {
                    //TODO: CreateEnergyTanks - Scale back energy tank distribution based on difficulty
                    EnergyTank energyTank = EnergyTank.CreateEnergyTank(room.room_key, energyTankTemplate);

                    room.energyTanks.Add(energyTank);
                }
            }

            return(success);
        }
예제 #3
0
        private bool SelectRoomTemplates(Random rng, out string result)
        {
            List <RoomTemplate> filteredRoomTemplates = new List <RoomTemplate>();
            bool success = true;

            result = SuccessMessages.GENERAL_SUCCESS;

            for (RoomIndexIterator iterator = new RoomIndexIterator(m_roomGrid);
                 success && iterator.Valid;
                 iterator.Next())
            {
                RoomIndex  roomIndex = iterator.Current;
                RoomLayout room      = GetRoomByIndex(roomIndex);

                filteredRoomTemplates.Clear();
                m_roomTemplateSet.GetTemplatesWithPortalBitmask(room.portalRoomSideBitmask, filteredRoomTemplates);

                if (filteredRoomTemplates.Count > 0)
                {
                    RoomTemplate roomTemplate = filteredRoomTemplates[rng.Next(filteredRoomTemplates.Count)];

                    room.static_room_data.room_template_name = roomTemplate.TemplateName;
                }
                else
                {
                    result  = ErrorMessages.MISSING_ROOM_TEMPLATE;
                    success = false;
                }
            }

            return(success);
        }
예제 #4
0
        private void FilterIsolatedRooms(
            Dictionary <int, List <RoomIndex> > connectivityIdToRoomIndexMap)
        {
            for (RoomIndexIterator iterator = new RoomIndexIterator(m_roomGrid);
                 iterator.Valid;
                 iterator.Next())
            {
                RoomIndex  roomIndex = iterator.Current;
                RoomLayout room      = GetRoomByIndex(roomIndex);

                if (room.RoomIsIsolated)
                {
                    List <RoomIndex> connectedSet = connectivityIdToRoomIndexMap[room.connectivity_id];

                    // Remove the room from the connectivity set
                    connectivityIdToRoomIndexMap.Remove(room.connectivity_id);

                    // Remove the room from the room grid
                    m_roomGrid[roomIndex.X, roomIndex.Y, roomIndex.Z] = null;
                }
            }
        }
예제 #5
0
        private bool CreateNormalPortals(out string result)
        {
            bool success = true;

            result = SuccessMessages.GENERAL_SUCCESS;

            // Create portals in each room
            for (RoomIndexIterator iterator = new RoomIndexIterator(m_roomGrid);
                 iterator.Valid;
                 iterator.Next())
            {
                RoomIndex    roomIndex    = iterator.Current;
                RoomKey      roomKey      = GetRoomKeyForRoomIndex(roomIndex);
                RoomLayout   room         = GetRoomByIndex(roomIndex);
                RoomTemplate roomTemplate = m_roomTemplateSet.GetTemplateByName(room.static_room_data.room_template_name);

                foreach (PortalTemplate portalTemplate in roomTemplate.PortalTemplates)
                {
                    if (portalTemplate.PortalType != ePortalType.teleporter)
                    {
                        Portal portal = new Portal();

                        portal.bounding_box = portalTemplate.BoundingBox;
                        portal.room_side    = portalTemplate.PortalRoomSide;
                        portal.room_x       = roomKey.x;
                        portal.room_y       = roomKey.y;
                        portal.room_z       = roomKey.z;
                        portal.portal_type  = portalTemplate.PortalType;

                        // This is a temp ID for the purpose of portal connection.
                        // A new ID will get assigned when inserting this portal into the DB.
                        portal.portal_id = m_nextPortalId;
                        ++m_nextPortalId;

                        // This get sets in the next pass
                        portal.target_portal_id = -1;

                        room.portals.Add(portal);
                    }
                }
            }

            // Connect neighboring portals
            for (RoomIndexIterator iterator = new RoomIndexIterator(m_roomGrid);
                 success && iterator.Valid;
                 iterator.Next())
            {
                RoomIndex  roomIndex = iterator.Current;
                RoomLayout room      = GetRoomByIndex(roomIndex);

                foreach (Portal portal in room.portals)
                {
                    MathConstants.eSignedDirection opposingRoomSide = RoomKey.GetOpposingRoomSide(portal.room_side);
                    RoomIndex  opposingRoomIndex = roomIndex.GetOpposingRoomIndex(portal.room_side);
                    RoomLayout opposingRoom      = GetRoomByIndex(opposingRoomIndex);
                    Portal     opposingPortal    = opposingRoom.portals.Find(p => p.room_side == opposingRoomSide);

                    if (opposingPortal != null)
                    {
                        portal.target_portal_id         = opposingPortal.portal_id;
                        opposingPortal.target_portal_id = portal.portal_id;
                    }
                    else
                    {
                        result  = ErrorMessages.DUNGEON_LAYOUT_ERROR;
                        success = false;
                        break;
                    }
                }
            }

            return(success);
        }
예제 #6
0
        private void JoinAdjacentDisjointRoomSets(
            Dictionary <int, List <RoomIndex> > connectivityIdToRoomIndexMap)
        {
            // Look for any null room that neighboring at least two disjoint sets of rooms
            for (RoomIndexIterator iterator = new RoomIndexIterator(m_roomGrid, RoomIndexIterator.eIterationType.nullRooms);
                 iterator.Valid;
                 iterator.Next())
            {
                RoomIndex   nullRoomIndex      = iterator.Current;
                RoomIndex[] neighboringIndices = new RoomIndex[4] {
                    nullRoomIndex.Offset(1, 0, 0),
                    nullRoomIndex.Offset(-1, 0, 0),
                    nullRoomIndex.Offset(0, 1, 0),
                    nullRoomIndex.Offset(0, -1, 0)
                };
                MathConstants.eSignedDirection[] neighborSideFlags = new MathConstants.eSignedDirection[4] {
                    MathConstants.eSignedDirection.positive_x,
                    MathConstants.eSignedDirection.negative_x,
                    MathConstants.eSignedDirection.positive_y,
                    MathConstants.eSignedDirection.negative_y
                };

                bool createNewRoom = false;
                TypedFlags <MathConstants.eSignedDirection> nullRoomNeighborFlags = new TypedFlags <MathConstants.eSignedDirection>();
                int lastConnectivityId = -1;

                for (int side_index = 0; side_index < 4; ++side_index)
                {
                    MathConstants.eSignedDirection neighborSide = neighborSideFlags[side_index];
                    RoomIndex neighborRoomIndex = neighboringIndices[side_index];

                    // See if an adjacent room exists on this side
                    RoomLayout neighborRoom = TryGetRoomByIndex(neighborRoomIndex);

                    if (neighborRoom != null)
                    {
                        // Record that a neighboring room was found in this side
                        nullRoomNeighborFlags.Set(neighborSide, true);

                        // See if the neighboring room is actually disjoint from a previous neighbor
                        // we have found on another side (different connectivity_id)
                        int roomConnectivityId = neighborRoom.connectivity_id;

                        if (lastConnectivityId != -1 &&
                            roomConnectivityId != lastConnectivityId)
                        {
                            List <RoomIndex> roomSet     = connectivityIdToRoomIndexMap[roomConnectivityId];
                            List <RoomIndex> lastRoomSet = connectivityIdToRoomIndexMap[lastConnectivityId];

                            // Make the connectivity ids match for rooms in both sets
                            roomSet.ForEach(rIndex => GetRoomByIndex(rIndex).connectivity_id = lastConnectivityId);

                            // Merge the rooms in the set into the previous set
                            lastRoomSet.AddRange(roomSet);

                            // Remove the set
                            connectivityIdToRoomIndexMap.Remove(roomConnectivityId);

                            // Since we have merged two adjacent sets we now need a new room
                            // to bridge the disjoin sets
                            createNewRoom = true;
                        }

                        // Keep track of the last valid connectivity we found for the next iteration
                        lastConnectivityId = neighborRoom.connectivity_id;
                    }
                }

                if (createNewRoom)
                {
                    // Create a new room at the null room index location
                    RoomLayout newRoom = new RoomLayout(GetRoomKeyForRoomIndex(nullRoomIndex));

                    // Record which neighbors the null room has
                    newRoom.portalRoomSideBitmask = nullRoomNeighborFlags;

                    // All neighbors should have the same connectivity id now
                    // so just get the connectivity id from the last valid neighbor
                    newRoom.connectivity_id = lastConnectivityId;

                    // Finally store the new room in the room grid
                    m_roomGrid[nullRoomIndex.X, nullRoomIndex.Y, nullRoomIndex.Z] = newRoom;

                    // Add the new room to the connectivity set it's helping to bridge
                    {
                        List <RoomIndex> lastRoomSet = connectivityIdToRoomIndexMap[lastConnectivityId];

                        lastRoomSet.Add(new RoomIndex(nullRoomIndex));
                    }

                    // Tell all neighboring rooms about the new room adjacent to it
                    for (int side_index = 0; side_index < 4; ++side_index)
                    {
                        MathConstants.eSignedDirection neighborSide = neighborSideFlags[side_index];
                        RoomIndex neighborRoomIndex = neighboringIndices[side_index];

                        // See if an adjacent room exists on this side
                        if (newRoom.portalRoomSideBitmask.Test(neighborSide))
                        {
                            RoomLayout neighborRoom = GetRoomByIndex(neighborRoomIndex);
                            MathConstants.eSignedDirection opposingNeighborSide = RoomKey.GetOpposingRoomSide(neighborSide);

                            neighborRoom.RoomFlagPortalOnSide(opposingNeighborSide, true);
                        }
                    }
                }
            }
        }
예제 #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);
        }