public static EmptyGrid ProcessMap(EmptyGrid map, BinarySpacePartitioningSettings settings)
    {
        // Random Generator
        Random.State initialState = Random.state;
        if (settings.useFixedSeed)
        {
            Random.InitState(settings.seed.GetHashCode());
        }
        else
        {
            Random.InitState(Time.time.ToString().GetHashCode());
        }

        // Set root
        BSPLeaf root = new BSPLeaf(0, 0, map.width - 1, map.height - 1);

        // Space Partition
        root.Split(ref settings);

        // Get terminal leaves
        List <BSPLeaf> list = new List <BSPLeaf>();

        root.GetLeaves(ref list);

        List <Vector2> midpoints = new List <Vector2>();

        // Recursive Division
        if (settings.useOnlyRecursiveDivision)
        {
            // Fill initial
            for (int y = 0; y < map.height; y++)
            {
                for (int x = 0; x < map.width; x++)
                {
                    map.values[x, y] = Cell.CreateCell(CellType.Floor);
                }
            }
            DrawBSPRoom(ref map.values, ref midpoints, ref settings, root);
        }
        else
        {
            // Room placement on map
            foreach (BSPLeaf leaf in list)
            {
                DrawRectangularRoom(ref map.values, ref midpoints, ref settings, leaf);
            }
        }

        if (settings.hasCleanup)
        {
            CleanUpRoomPlacement(ref map.values, ref map.width, ref map.height);
        }

        Random.state = initialState;

        return(map);
    }
Esempio n. 2
0
 private bool CanSplit(int spaceSize, bool isVertical, ref BinarySpacePartitioningSettings settings)
 {
     if (isVertical)
     {
         return((spaceSize > (settings.minSpaceSizeVertical * settings.minSpaceSizeToSplitMiltiplier)) || (Random.value < settings.chanceToStopSpaceSplitting));
     }
     else
     {
         return((spaceSize > (settings.minSpaceSizeHorizontal * settings.minSpaceSizeToSplitMiltiplier)) || (Random.value < settings.chanceToStopSpaceSplitting));
     }
 }
    private static void DrawBSPRoom(ref Cell[,] map, ref List <Vector2> midpoints, ref BinarySpacePartitioningSettings settings, BSPLeaf leaf, CellType roomWallsCell = CellType.Wall, CellType roomFloorCell = CellType.Floor)
    {
        if (leaf.Left != null && leaf.Right != null)
        {
            if (leaf.splitOrientationIsVertical)
            {
                int passageAt       = Random.Range(leaf.Left.bounds.zMin, leaf.Left.bounds.zMin + leaf.Left.SizeZ + 1);
                int divideCellIndex = leaf.Left.bounds.xMin + leaf.Left.SizeX;

                for (int z = leaf.bounds.zMin; z <= leaf.bounds.zMin + leaf.SizeZ; z++)
                {
                    if (passageAt != z)
                    {
                        map[divideCellIndex, z] = Cell.CreateCell(roomWallsCell);
                    }
                    else
                    {
                        map[divideCellIndex, z] = Cell.CreateCell(roomFloorCell);
                    }
                }
            }
            else
            {
                int passageAt       = Random.Range(leaf.Left.bounds.xMin, leaf.Left.bounds.xMin + leaf.Left.SizeX + 1);
                int divideCellIndex = leaf.Left.bounds.zMin + leaf.Left.SizeZ;

                while (passageAt == divideCellIndex)
                {
                    passageAt = Random.Range(leaf.Left.bounds.xMin, leaf.Left.bounds.xMin + leaf.Left.SizeX + 1);
                }

                for (int x = leaf.bounds.xMin; x <= leaf.bounds.xMin + leaf.SizeX; x++)
                {
                    if (passageAt != x)
                    {
                        map[x, divideCellIndex] = Cell.CreateCell(roomWallsCell);
                    }
                    else
                    {
                        map[x, divideCellIndex] = Cell.CreateCell(roomFloorCell);
                    }
                }
            }

            DrawBSPRoom(ref map, ref midpoints, ref settings, leaf.Left, roomWallsCell, roomFloorCell);
            DrawBSPRoom(ref map, ref midpoints, ref settings, leaf.Right, roomWallsCell, roomFloorCell);
        }
        else
        {
            return;
        }
    }
Esempio n. 4
0
    private bool AbleToSplit(ref BinarySpacePartitioningSettings settings)
    {
        bool canSplitVertical   = (SizeX >= settings.minSpaceSizeVertical);
        bool canSplitHorizontal = (SizeZ >= settings.minSpaceSizeHorizontal);

        if (!(canSplitVertical || canSplitHorizontal))
        {
            return(false);
        }
        else
        {
            if (canSplitVertical && canSplitHorizontal)
            {
                if (SizeX / SizeZ > settings.widthHeightRatioToSplitNotRandom) //width > height
                {
                    splitOrientationIsVertical = true;
                }
                else if (SizeZ / SizeX > settings.widthHeightRatioToSplitNotRandom)
                {
                    splitOrientationIsVertical = false;
                }
                else
                {
                    splitOrientationIsVertical = (Random.value < 0.5f);
                }
            }
            else if (canSplitVertical)
            {
                splitOrientationIsVertical = true;
            }
            else
            {
                splitOrientationIsVertical = false;
            }

            return(true);
        }
    }
Esempio n. 5
0
    public void Split(ref BinarySpacePartitioningSettings settings)
    {
        if (!AbleToSplit(ref settings))
        {
            return;
        }

        int whereToSplit;

        if (splitOrientationIsVertical)
        {
            if (settings.canShareSingleWall)
            {
                whereToSplit = Random.Range(0 + settings.minSplitSizeVertical - 1, SizeX - settings.minSplitSizeVertical + 1);
                Left         = new BSPLeaf(bounds.xMin, bounds.zMin, whereToSplit, SizeZ);
                Right        = new BSPLeaf(bounds.xMin + whereToSplit, bounds.zMin, SizeX - whereToSplit, SizeZ);
                if (CanSplit(whereToSplit, true, ref settings))
                {
                    Left.Split(ref settings);
                }
                if (CanSplit(SizeX - whereToSplit, true, ref settings))
                {
                    Right.Split(ref settings);
                }
            }
            else
            {
                whereToSplit = Random.Range(0 + settings.minSplitSizeVertical - 1, SizeX - settings.minSplitSizeVertical + 1);
                Left         = new BSPLeaf(bounds.xMin, bounds.zMin, whereToSplit, SizeZ);
                Right        = new BSPLeaf(bounds.xMin + whereToSplit + 1, bounds.zMin, SizeX - whereToSplit - 1, SizeZ);
                if (CanSplit(whereToSplit, true, ref settings))
                {
                    Left.Split(ref settings);
                }
                if (CanSplit(SizeX - whereToSplit - 1, true, ref settings))
                {
                    Right.Split(ref settings);
                }
            }
        }
        else
        {
            if (settings.canShareSingleWall)
            {
                whereToSplit = Random.Range(0 + settings.minSplitSizeHorizontal - 1, SizeZ - settings.minSplitSizeHorizontal + 1);
                Left         = new BSPLeaf(bounds.xMin, bounds.zMin, SizeX, whereToSplit);
                Right        = new BSPLeaf(bounds.xMin, bounds.zMin + whereToSplit, SizeX, SizeZ - whereToSplit);
                if (CanSplit(whereToSplit, false, ref settings))
                {
                    Left.Split(ref settings);
                }
                if (CanSplit(SizeZ - whereToSplit, false, ref settings))
                {
                    Right.Split(ref settings);
                }
            }
            else
            {
                whereToSplit = Random.Range(0 + settings.minSplitSizeHorizontal - 1, SizeZ - settings.minSplitSizeHorizontal + 1);
                Left         = new BSPLeaf(bounds.xMin, bounds.zMin, SizeX, whereToSplit);
                Right        = new BSPLeaf(bounds.xMin, bounds.zMin + whereToSplit + 1, SizeX, SizeZ - whereToSplit - 1);
                if (CanSplit(whereToSplit, false, ref settings))
                {
                    Left.Split(ref settings);
                }
                if (CanSplit(SizeZ - whereToSplit - 1, false, ref settings))
                {
                    Right.Split(ref settings);
                }
            }
        }
    }
    public static TileMapSettings PreprocessMap(TileMapSettings mapSettings, BinarySpacePartitioningSettings settings)
    {
        if (settings.roomsMinHeight < 3)
        {
            settings.roomsMinHeight = 3;
        }
        if (settings.roomsMinWidth < 3)
        {
            settings.roomsMinWidth = 3;
        }

        if (settings.useRoomsMaxSizeValues)
        {
            if (settings.roomsMaxHeight < settings.roomsMinHeight)
            {
                settings.roomsMaxHeight = settings.roomsMinHeight;
            }
            if (settings.roomsMaxWidth < settings.roomsMinWidth)
            {
                settings.roomsMaxWidth = settings.roomsMinWidth;
            }

            settings.roomsMinHeight = settings.roomsMaxHeight;
            settings.roomsMinWidth  = settings.roomsMaxWidth;

            if (settings.minSplitSizeHorizontal < settings.roomsMaxHeight)
            {
                settings.minSplitSizeHorizontal = settings.roomsMaxHeight;
            }
            if (settings.minSplitSizeVertical < settings.roomsMaxWidth)
            {
                settings.minSplitSizeVertical = settings.roomsMaxWidth;
            }

            if (settings.minSpaceSizeHorizontal < settings.minSplitSizeHorizontal * 2 - 1)
            {
                settings.minSpaceSizeHorizontal = settings.minSplitSizeHorizontal * 2 - 1;
            }
            if (settings.minSpaceSizeVertical < settings.minSplitSizeVertical * 2 - 1)
            {
                settings.minSpaceSizeVertical = settings.minSplitSizeVertical * 2 - 1;
            }

            if (mapSettings.mapHeight < settings.minSpaceSizeHorizontal)
            {
                mapSettings.mapHeight = settings.minSpaceSizeHorizontal;
            }
            if (mapSettings.mapWidth < settings.minSpaceSizeVertical)
            {
                mapSettings.mapWidth = settings.minSpaceSizeVertical;
            }
        }
        else
        {
            if (settings.minSplitSizeHorizontal < settings.roomsMinHeight)
            {
                settings.minSplitSizeHorizontal = settings.roomsMinHeight;
            }
            if (settings.minSplitSizeVertical < settings.roomsMinWidth)
            {
                settings.minSplitSizeVertical = settings.roomsMinWidth;
            }

            if (settings.minSpaceSizeHorizontal < settings.minSplitSizeHorizontal * 2 - 1)
            {
                settings.minSpaceSizeHorizontal = settings.minSplitSizeHorizontal * 2 - 1;
            }
            if (settings.minSpaceSizeVertical < settings.minSplitSizeVertical * 2 - 1)
            {
                settings.minSpaceSizeVertical = settings.minSplitSizeVertical * 2 - 1;
            }

            if (mapSettings.mapHeight < settings.minSpaceSizeHorizontal)
            {
                mapSettings.mapHeight = settings.minSpaceSizeHorizontal;
            }
            if (mapSettings.mapWidth < settings.minSpaceSizeVertical)
            {
                mapSettings.mapWidth = settings.minSpaceSizeVertical;
            }
        }

        return(mapSettings);
    }
    private static void DrawRectangularRoom(ref Cell[,] map, ref List <Vector2> midpoints, ref BinarySpacePartitioningSettings settings, BSPLeaf leaf, CellType roomWallsCell = CellType.Wall, CellType roomFloorCell = CellType.Floor)
    {
        int roomsMinWidth  = settings.roomsMinWidth - 1;
        int roomsMinHeight = settings.roomsMinHeight - 1;

        int roomWidth;
        int roomHeight;

        if (settings.useRoomsMaxSizeValues)
        {
            roomWidth  = Random.Range(roomsMinWidth, settings.roomsMaxWidth);
            roomHeight = Random.Range(roomsMinHeight, settings.roomsMaxHeight);
        }
        else
        {
            roomWidth  = Random.Range(roomsMinWidth, leaf.SizeX + 1);
            roomHeight = Random.Range(roomsMinHeight, leaf.SizeZ + 1);
        }

        int xOffset = Random.Range(0, leaf.SizeX - roomWidth);
        int zOffset = Random.Range(0, leaf.SizeZ - roomHeight);

        for (int z = leaf.bounds.zMin + zOffset + 1; z < leaf.bounds.zMin + zOffset + roomHeight; z++)
        {
            for (int x = leaf.bounds.xMin + xOffset + 1; x < leaf.bounds.xMin + xOffset + roomWidth; x++)
            {
                map[x, z] = Cell.CreateCell(roomFloorCell);
            }
        }
        for (int x = leaf.bounds.xMin + xOffset; x <= leaf.bounds.xMin + xOffset + roomWidth; x++)
        {
            map[x, leaf.bounds.zMin + zOffset] = Cell.CreateCell(roomWallsCell);
            map[x, leaf.bounds.zMin + zOffset + roomHeight] = Cell.CreateCell(roomWallsCell);
        }
        for (int z = leaf.bounds.zMin + zOffset; z <= leaf.bounds.zMin + zOffset + roomHeight; z++)
        {
            map[leaf.bounds.xMin + xOffset, z]             = Cell.CreateCell(roomWallsCell);
            map[leaf.bounds.xMin + xOffset + roomWidth, z] = Cell.CreateCell(roomWallsCell);
        }

        midpoints.Add(new Vector2(leaf.bounds.xMin + xOffset + roomWidth / 2, leaf.bounds.zMin + zOffset + roomHeight / 2));
    }