Пример #1
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;
        }
Пример #2
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);
        }
Пример #3
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);
                        }
                    }
                }
            }
        }