Пример #1
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);
        }
Пример #2
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);
        }
Пример #3
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);
        }
Пример #4
0
        private void ComputeConnectivityIdToRoomIndexMap(
            UnionFind <RoomIndex> roomUnion,
            Dictionary <int, List <RoomIndex> > connectivityIdToRoomIndexMap)
        {
            IList <RoomIndex> roomIndices = GetRoomIndexList();

            foreach (RoomIndex roomIndex in roomIndices)
            {
                RoomLayout       room           = GetRoomByIndex(roomIndex);
                int              connectivityId = room.connectivity_id;
                List <RoomIndex> connectedRooms = null;

                if (connectivityIdToRoomIndexMap.TryGetValue(connectivityId, out connectedRooms))
                {
                    connectedRooms.Add(roomIndex);
                }
                else
                {
                    connectedRooms = new List <RoomIndex>();
                    connectedRooms.Add(roomIndex);

                    connectivityIdToRoomIndexMap.Add(connectivityId, connectedRooms);
                }
            }
        }
Пример #5
0
        public RoomLayout TryGetRoomByIndex(RoomIndex roomIndex)
        {
            RoomLayout room       = null;
            int        roomXIndex = roomIndex.X;
            int        roomYIndex = roomIndex.Y;
            int        roomZIndex = roomIndex.Z;

            if (roomXIndex >= 0 && roomXIndex < m_roomGrid.GetLength(0) &&
                roomYIndex >= 0 && roomYIndex < m_roomGrid.GetLength(1) &&
                roomZIndex >= 0 && roomZIndex < m_roomGrid.GetLength(2))
            {
                room = m_roomGrid[roomXIndex, roomYIndex, roomZIndex];
            }

            return(room);
        }
Пример #6
0
        public void ApplyLayout(
            DungeonLayout layout)
        {
            // Copy over all the rooms in the layout into the world
            for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid);
                 iterator.Valid;
                 iterator.Next())
            {
                DungeonLayout.RoomIndex roomIndex = iterator.Current;
                RoomLayout   room         = layout.GetRoomByIndex(roomIndex);
                RoomTemplate roomTemplate = layout.LayoutRoomTemplateSet.GetTemplateByName(room.static_room_data.room_template_name);

                room.runtime_nav_mesh = new NavMesh(room.room_key, roomTemplate.NavMeshTemplate);

                m_rooms.Add(room.room_key, room);
            }
        }
Пример #7
0
        public IList <RoomIndex> GetRoomIndexListForFloor(int z_index)
        {
            List <RoomIndex> indices = new List <RoomIndex>();

            for (int y_index = 0; y_index < m_roomGrid.GetLength(1); y_index++)
            {
                for (int x_index = 0; x_index < m_roomGrid.GetLength(0); x_index++)
                {
                    RoomLayout room = m_roomGrid[x_index, y_index, z_index];

                    if (room != null)
                    {
                        indices.Add(new RoomIndex(x_index, y_index, z_index));
                    }
                }
            }

            return(indices);
        }
Пример #8
0
        private void RemoveRoomFromGrid(RoomIndex roomIndex)
        {
            RoomLayout room = GetRoomByIndex(roomIndex);

            // Neighbor on the +x side
            if (room.RoomHasPortalOnSide(MathConstants.eSignedDirection.positive_x))
            {
                RoomLayout posXRoom = GetRoomByIndex(roomIndex.Offset(1, 0, 0));

                // No more room on the -x side
                posXRoom.RoomFlagPortalOnSide(MathConstants.eSignedDirection.negative_x, false);
            }

            // Neighbor on the -x side
            if (room.RoomHasPortalOnSide(MathConstants.eSignedDirection.negative_x))
            {
                RoomLayout negXRoom = GetRoomByIndex(roomIndex.Offset(-1, 0, 0));

                // No more room on the +x side
                negXRoom.RoomFlagPortalOnSide(MathConstants.eSignedDirection.positive_x, false);
            }

            // Neighbor on the +y side
            if (room.RoomHasPortalOnSide(MathConstants.eSignedDirection.positive_y))
            {
                RoomLayout posYRoom = GetRoomByIndex(roomIndex.Offset(0, 1, 0));

                // No more room on the -y side
                posYRoom.RoomFlagPortalOnSide(MathConstants.eSignedDirection.negative_y, false);
            }

            // Neighbor on the -y side
            if (room.RoomHasPortalOnSide(MathConstants.eSignedDirection.negative_y))
            {
                RoomLayout negYRoom = GetRoomByIndex(roomIndex.Offset(0, -1, 0));

                // No more room on the +y side
                negYRoom.RoomFlagPortalOnSide(MathConstants.eSignedDirection.positive_y, false);
            }

            // Stomp this room
            m_roomGrid[roomIndex.X, roomIndex.Y, roomIndex.Z] = null;
        }
Пример #9
0
        private bool CanRemoveRoomFromGrid(RoomIndex roomIndex)
        {
            RoomLayout room          = GetRoomByIndex(roomIndex);
            bool       canRemoveRoom = true;

            // Can't remove this room if it contains stairs
            // Or we are neighboring a room that contains stairs
            if (!room.RoomHasStairs)
            {
                RoomKey roomKey = GetRoomKeyForRoomIndex(roomIndex);

                // Can't remove the origin room because that's where the player is spawned in a new game
                canRemoveRoom = !(roomKey.x == 0 && roomKey.y == 0 && roomKey.z == 0);

                if (canRemoveRoom && room.RoomHasPortalOnSide(MathConstants.eSignedDirection.positive_x))
                {
                    canRemoveRoom &= !GetRoomByIndex(roomIndex.Offset(1, 0, 0)).RoomHasStairs;
                }

                if (canRemoveRoom && room.RoomHasPortalOnSide(MathConstants.eSignedDirection.negative_x))
                {
                    canRemoveRoom &= !GetRoomByIndex(roomIndex.Offset(-1, 0, 0)).RoomHasStairs;
                }

                if (canRemoveRoom && room.RoomHasPortalOnSide(MathConstants.eSignedDirection.positive_y))
                {
                    canRemoveRoom &= !GetRoomByIndex(roomIndex.Offset(0, 1, 0)).RoomHasStairs;
                }

                if (canRemoveRoom && room.RoomHasPortalOnSide(MathConstants.eSignedDirection.negative_y))
                {
                    canRemoveRoom &= !GetRoomByIndex(roomIndex.Offset(0, -1, 0)).RoomHasStairs;
                }
            }
            else
            {
                canRemoveRoom = false;
            }

            return(canRemoveRoom);
        }
Пример #10
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;
                }
            }
        }
Пример #11
0
        private Portal CreateTeleporterPortal(
            Random rng,
            RoomIndex roomIndex)
        {
            Portal                portal              = null;
            RoomLayout            room                = GetRoomByIndex(roomIndex);
            RoomTemplate          roomTemplate        = m_roomTemplateSet.GetTemplateByName(room.static_room_data.room_template_name);
            List <PortalTemplate> teleporterTemplates =
                roomTemplate.PortalTemplates.Where(t => t.PortalType == ePortalType.teleporter).ToList();

            if (teleporterTemplates.Count > 0)
            {
                RoomKey        roomKey        = GetRoomKeyForRoomIndex(roomIndex);
                PortalTemplate portalTemplate = teleporterTemplates[rng.Next(teleporterTemplates.Count)];

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

                // 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;

                // Add the new portal to the room
                room.portals.Add(portal);
            }

            return(portal);
        }
Пример #12
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);
        }
Пример #13
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);
                        }
                    }
                }
            }
        }
Пример #14
0
        private void ComputeRoomConnectivity(UnionFind <RoomIndex> roomUnion)
        {
            IList <RoomIndex> roomIndices = GetRoomIndexList();

            roomUnion = new UnionFind <RoomIndex>();

            // Add all of the rooms into the union
            foreach (RoomIndex roomIndex in roomIndices)
            {
                roomUnion.AddElement(roomIndex);
            }

            // Start connecting to our neighbors
            foreach (RoomIndex roomIndex in roomIndices)
            {
                RoomLayout room = GetRoomByIndex(roomIndex);

                // Union with the neighbor on the +x side
                if (room.RoomHasPortalOnSide(MathConstants.eSignedDirection.positive_x))
                {
                    roomUnion.Union(roomIndex, roomIndex.Offset(1, 0, 0));
                }

                // Union with the neighbor on the -x side
                if (room.RoomHasPortalOnSide(MathConstants.eSignedDirection.negative_x))
                {
                    roomUnion.Union(roomIndex, roomIndex.Offset(-1, 0, 0));
                }

                // Union with the neighbor on the +y side
                if (room.RoomHasPortalOnSide(MathConstants.eSignedDirection.positive_y))
                {
                    roomUnion.Union(roomIndex, roomIndex.Offset(0, 1, 0));
                }

                // Union with the neighbor on the -y side
                if (room.RoomHasPortalOnSide(MathConstants.eSignedDirection.negative_y))
                {
                    roomUnion.Union(roomIndex, roomIndex.Offset(0, -1, 0));
                }

                // Union with the neighbor on the +z side
                if (room.RoomHasPortalOnSide(MathConstants.eSignedDirection.positive_z))
                {
                    roomUnion.Union(roomIndex, roomIndex.Offset(0, 0, 1));
                }

                // Union with the neighbor on the -z side
                if (room.RoomHasPortalOnSide(MathConstants.eSignedDirection.negative_z))
                {
                    roomUnion.Union(roomIndex, roomIndex.Offset(0, 0, -1));
                }
            }

            // Store the final connectivity id on the room
            foreach (RoomIndex roomIndex in roomIndices)
            {
                RoomLayout room = GetRoomByIndex(roomIndex);

                room.connectivity_id = roomUnion.FindRootIndex(roomIndex);
            }
        }
Пример #15
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);
        }