Пример #1
0
    public FilledRegion Apply(FillData data)
    {
        List <Region> spawnAreas = new List <Region>();

        //Get data.
        Generation.BeingFilled = data.BeingFilled;
        int numb   = Generation.NumbPlateaus;
        int width  = Generation.PlateauWidth;
        int space  = Generation.SpaceBetweenPlateaus;
        int border = Generation.Border;

        //Plateau location data.
        int height = (int)Math.Round((PlateauRelativeHeight * data.BeingFilled.Height), 0);

        if (height >= data.BeingFilled.Height)
        {
            height = data.BeingFilled.Height - 1;
        }
        int top = data.BeingFilled.Bottom - height;

        //Add the plateaus.
        Region r;

        for (int i = 0; i < numb; ++i)
        {
            r = new Region(data.BeingFilled.Left + border + (i * (space + width)), top, width - 1, data.BeingFilled.Bottom - top);
            data.FillRegion(true, r);
            spawnAreas.Add(new Region(new Location(r.Left, data.BeingFilled.Top),
                                      r.TopRight.Above));
        }

        //Make room for any holes that the plateaus covered.
        foreach (Location l in data.HolesAlongPerimeter())
        {
            //The hole is covered if it is just under the region and the space right above it is covered.
            if (data.BeingFilled.Touches(l.Above, true, true, false) &&
                data.GetMapAt(l.Above))
            {
                //Make a litle tunnel under the plateau.
                int[]  plateauSides = PlateauSides(l.X, numb, width, space, border, data.BeingFilled.Left, data.BeingFilled.Right);
                Region cleared      = new Region(plateauSides[0], data.BeingFilled.Bottom, width - 1, 0);
                data.FillRegion(false, cleared);
            }
        }

        return(new SteppedHallwayRegion(data.BeingFilled, spawnAreas));
    }
    public FilledRegion Apply(FillData data)
    {
        //Keep track of the spawn areas above the steps, indexed by y coordinate.
        Dictionary <int, Region> platformSpaces = new Dictionary <int, Region>();

        //Get step data.
        int  stepWidth  = (int)Math.Round(StepSizeScale * (data.BeingFilled.Width + 1), 0);
        int  spaceWidth = data.BeingFilled.Width + 1 - stepWidth - stepWidth;
        bool left       = true;

        Location line1, line2;

        for (int y = data.BeingFilled.Bottom - 1; y > data.BeingFilled.Top; y -= Space)
        {
            //Fill the line.
            if (left)
            {
                line1 = new Location(data.BeingFilled.Left, y);
                line2 = new Location(data.BeingFilled.Left + stepWidth - 1, y);

                data.FillLine(true, line1, line2);
                platformSpaces.Add(y, new Region(line1, line2, true));
            }
            else
            {
                line1 = new Location(data.BeingFilled.Left + stepWidth + spaceWidth, y);
                line2 = new Location(data.BeingFilled.Right, y);

                data.FillLine(true, line1, line2);
                platformSpaces.Add(y, new Region(line1, line2, true));
            }

            //Change sides.
            left = !left;
        }

        //Free any holes.
        foreach (Location l in data.HolesAlongPerimeter())
        {
            //If the hole is on the left side and there's a platform in the way:
            if (data.BeingFilled.Touches(l.Right, true, true, false) &&
                data.GetMapAt(l.Right))
            {
                //Remove the left edge of the platform.

                data.SetMapAt(l.Right, false);

                Region r = platformSpaces[l.Y];
                ++r.X;
                --r.Width;
                platformSpaces[l.Y] = r;
            }
            //Otherwise, if the hole is on the right side and there's a platform in the way:
            else if (data.BeingFilled.Touches(l.Left, true, true, false) &&
                     data.GetMapAt(l.Left))
            {
                //Remove the right edge of the platform.

                data.SetMapAt(l.Left, false);

                Region r = platformSpaces[l.Y];
                --r.Width;
                platformSpaces[l.Y] = r;
            }
        }

        return(new AlternatingStepsRegion(data.BeingFilled, platformSpaces.Values));
    }
Пример #3
0
    public void IterateFillPattern()
    {
        //Already done?
        if (iterateFillPatternsRegionCount >= Regions.Count)
        {
            return;
        }

        //Run an iteration.

        FilledRegion temp;
        Region       r = Regions[iterateFillPatternsRegionCount];

        iterateFillPatternsRegionCount++;

        //Pick a random applicable pattern (assuming one exists) and apply it.
        FillPattern p = Settings.MostSuitable(r);

        if (p != null)
        {
            //Clear the space, and apply the pattern.
            FillData.BeingFilled = r;
            FillData.FillRegion(false, r);
            temp = p.Apply(FillData);

            //If the filled region is blank, replace it with a BlankRegion.
            bool blank = true;
            for (int i = temp.Covering.Left; i <= temp.Covering.Right; ++i)
            {
                for (int j = temp.Covering.Top; j <= temp.Covering.Bottom; ++j)
                {
                    if (FillData.GetMapAt(new Location(i, j)))
                    {
                        blank = false;
                        break;
                    }
                }
                if (!blank)
                {
                    break;
                }
            }
            if (blank)
            {
                temp = new BlankRegion(temp.Covering);
            }

            //Now add it.
            FilledRegions.Add(temp);
            Region r2;

            //Make sure the spawn points are all valid.
            foreach (Spawns s in FilledRegions[FilledRegions.Count - 1].PotentialSpawns.Keys)
            {
                for (int i = 0; i < FilledRegions[FilledRegions.Count - 1].PotentialSpawns[s].Count; ++i)
                {
                    r2 = FilledRegions[FilledRegions.Count - 1].PotentialSpawns[s][i];

                    if (r2.Width < 0 || r2.Height < 0)
                    {
                        FilledRegions[FilledRegions.Count - 1].PotentialSpawns[s].RemoveAt(i--);
                    }
                }
            }
        }
        //If no regions fit, add a "NoRegion".
        else
        {
            FilledRegions.Add(new NoRegion(r));
        }
    }
Пример #4
0
    /// <summary>
    /// Gets all continuous left/right Lines from the given level using all the walls in the given column.
    /// The Lines are indexed by all wall bounds that make up part of that indexed Line.
    /// </summary>
    public static void GetVerticalLines(FillData data, WallToLines associations, int col)
    {
        int      startingY, currentY;
        Interval temp;
        ColType  current;
        bool     rightCol = (col == data.Map.GetLength(0) - 1);

        //Do the algorithm for both the left and the right of the column.
        int currentCol;

        for (int dir = -1; dir < 2; dir += 2)
        {
            currentCol = col + dir;
            current    = (currentCol > col ? ColType.Right : ColType.Left);

            //Take care of the edge case where the whole row is a valid line.
            bool colFree = true;
            for (int j = 0; j < data.Map.GetLength(1); ++j)
            {
                if (data.GetMapAt(new Location(currentCol, j)) ||
                    !data.GetMapAt(new Location(col, j)))
                {
                    colFree = false;
                    break;
                }
            }

            //If the whole column is one line, just use that.
            if (colFree)
            {
                //If the level wraps around, use a large line.
                if (data.WrapY)
                {
                    associations.AddReferences(GetBounds(new Line(Orientation.Vertical, new Interval(0, data.Map.GetLength(1) - 1, true, 2), col)),
                                               current,
                                               new Line(Orientation.Vertical, new Interval(-data.Map.GetLength(1), 2.0f * data.Map.GetLength(1), true, 2), (col + currentCol) * 0.5f));
                }
                else
                {
                    associations.AddReferences(GetBounds(new Line(Orientation.Vertical, new Interval(0, data.Map.GetLength(1) - 1, true, 2), col)),
                                               current,
                                               new Line(Orientation.Vertical, new Interval(0, data.Map.GetLength(1) - 1, true, 2), col));
                }
            }

            //Otherwise, go through one wall at a time and build individual collections of Lines.
            else
            {
                //An edge is a whole Line if it spans an unbroken column of walls with no walls covering the edge.

                //Use a counter to run through the whole column in groups of unbroken walls.
                startingY = 0;
                currentY  = 0;
                temp      = null;
                while (startingY < data.Map.GetLength(1))
                {
                    //Get the next valid spot to start from.
                    while ((!data.GetMapAt(new Location(col, startingY)) ||
                            data.GetMapAt(new Location(currentCol, startingY))) &&
                           startingY < data.Map.GetLength(1))
                    {
                        currentY += 1;
                        startingY = currentY;
                    }
                    if (startingY >= data.Map.GetLength(1))
                    {
                        break;
                    }

                    //Keep the counter going as long as the next spot is valid (i.e.
                    //  there is a wall to the side but not in the way).
                    while (data.GetMapAt(new Location(col, currentY + 1)) &&
                           !data.GetMapAt(new Location(currentCol, currentY + 1)) &&
                           currentY < data.Map.GetLength(1))
                    {
                        currentY += 1;
                    }

                    //Now make the line.
                    temp = new Interval(startingY, currentY, true, 2);
                    associations.AddReferences(GetBounds(new Line(Orientation.Vertical, temp, col)),
                                               current,
                                               new Line(Orientation.Vertical, temp, (col + currentCol) * 0.5f));

                    //If this is near the top, wrap it around to the bottom.
                    if (data.WrapY && temp.Start < 2.0f)
                    {
                        associations.AddReferences(GetBounds(new Line(Orientation.Vertical, temp + data.WorldSize.Y, col)),
                                                   current,
                                                   new Line(Orientation.Vertical, temp + data.WorldSize.Y, (col + currentCol) * 0.5f));
                    }

                    //Move to the next spot in the column.
                    startingY = currentY + 1;
                    currentY  = startingY;
                }

                //If the level wraps around in the Y, take the last Line and wrap it around.
                if (temp != null && data.WrapY)
                {
                    associations.AddReferences(GetBounds(new Line(Orientation.Vertical, temp - data.WorldSize.Y, col)),
                                               current,
                                               new Line(Orientation.Vertical, temp - data.WorldSize.Y, (col + currentCol) * 0.5f));
                }
            }
        }
    }
Пример #5
0
    /// <summary>
    /// Gets all continuous top/bottom Lines from the given level using all the walls in the given row.
    /// The Lines are indexed by all wall bounds that make up part of that indexed Line.
    /// </summary>
    public static void GetHorizontalLines(FillData data, WallToLines associations, int row)
    {
        int      startingX, currentX;
        Interval temp;
        ColType  current;
        bool     bottomRow = (row == data.Map.GetLength(1) - 1);

        //Do the algorithm for both above and below the row.
        int currentRow;

        for (int dir = -1; dir < 2; dir += 2)
        {
            currentRow = row + dir;
            current    = (currentRow < row ? ColType.Bottom : ColType.Top);

            //There is one special case: the whole row is a valid line.
            bool rowFree = true;
            for (int i = 0; i < data.Map.GetLength(0); ++i)
            {
                if (data.GetMapAt(new Location(i, currentRow)) ||
                    !data.GetMapAt(new Location(i, row)))
                {
                    rowFree = false;
                    break;
                }
            }

            //If the whole row is one line, just use that.
            if (rowFree)
            {
                //If the level wraps around, use a large line.
                if (data.WrapX)
                {
                    associations.AddReferences(GetBounds(new Line(Orientation.Horizontal, new Interval(0, data.Map.GetLength(0) - 1, true, 2), row)),
                                               current,
                                               new Line(Orientation.Horizontal, new Interval(-data.Map.GetLength(0), 2.0f * data.Map.GetLength(0), true, 2), (row + currentRow) * 0.5f));
                }
                else
                {
                    associations.AddReferences(GetBounds(new Line(Orientation.Horizontal, new Interval(0, data.Map.GetLength(0) - 1, true, 2), row)),
                                               current,
                                               new Line(Orientation.Horizontal, new Interval(0, data.Map.GetLength(0) - 1, true, 2), row));
                }
            }

            //Otherwise, go through one wall at a time and build individual collections of Lines.
            else
            {
                //An edge is a whole Line if it spans an unbroken row of walls with no walls covering the edge.

                //Use a counter to run through the whole row in groups of unbroken rows.
                startingX = 0;
                currentX  = 0;
                temp      = null;
                while (startingX < data.Map.GetLength(0))
                {
                    //Get the next valid spot to start from.
                    while ((!data.GetMapAt(new Location(startingX, row)) ||
                            data.GetMapAt(new Location(startingX, currentRow))) &&
                           startingX < data.Map.GetLength(0))
                    {
                        currentX += 1;
                        startingX = currentX;
                    }
                    if (startingX >= data.Map.GetLength(0))
                    {
                        break;
                    }

                    //Keep the counter going as long as the next spot is valid (i.e.
                    //  there is a wall in this row but not above/underneath).
                    while (data.GetMapAt(new Location(currentX + 1, row)) &&
                           !data.GetMapAt(new Location(currentX + 1, currentRow)) &&
                           currentX < data.Map.GetLength(0))
                    {
                        currentX += 1;
                    }

                    //Now make the line.
                    temp = new Interval(startingX, currentX, true, 2);
                    associations.AddReferences(GetBounds(new Line(Orientation.Horizontal, temp, row)),
                                               current,
                                               new Line(Orientation.Horizontal, temp, (row + currentRow) * 0.5f));

                    //If this is near the left, wrap it around to the right.
                    if (data.WrapX && temp.Start < 2.0f)
                    {
                        associations.AddReferences(GetBounds(new Line(Orientation.Horizontal, temp + data.WorldSize.X, row)),
                                                   current,
                                                   new Line(Orientation.Horizontal, temp + data.WorldSize.X, (row + currentRow) * 0.5f));
                    }

                    //Move to the next spot in the row.
                    startingX = currentX + 1;
                    currentX  = startingX;
                }

                //If the level wraps around in the X, take the last Line and wrap it around.
                if (temp != null && data.WrapX)
                {
                    associations.AddReferences(GetBounds(new Line(Orientation.Horizontal, temp - data.WorldSize.X, row)),
                                               current,
                                               new Line(Orientation.Horizontal, temp - data.WorldSize.X, (row + currentRow) * 0.5f));
                }
            }
        }
    }
    public FilledRegion Apply(FillData data)
    {
        //The spawning areas.
        List <Region> spawningAreas = new List <Region>();

        //Get/set some data.
        Region area = data.BeingFilled;

        PlateauGeneration.BeingFilled = data.BeingFilled;
        //If the corridor is going to be vertical, flip the width and height.
        if (area.Height > area.Width)
        {
            PlateauGeneration.BeingFilled = new Region(area.Y, area.X, area.Height, area.Width);
        }

        int numb        = PlateauGeneration.NumbPlateaus;
        int plateauSize = PlateauGeneration.PlateauWidth;

        int space  = PlateauGeneration.SpaceBetweenPlateaus;
        int border = PlateauGeneration.Border;

        //Plateau size data.
        //"maxSize" is the largest allowable hurdle height.
        int maxSize = PlateauGeneration.BeingFilled.Height - 1;

        if (area.Height > area.Width)
        {
            //Vertical.

            //Add the plateaus.
            int hurdleWidth, plateauExtent;
            for (int i = 0; i < numb; ++i)
            {
                //Get a width within the given random variation.
                hurdleWidth = (int)Math.Round((area.Width + 1) * (HurdleAverageSpaceScale + ((2 * HurdleHeightVariance * (float)GeneratorSettings.R.NextDouble()) - HurdleHeightVariance)), 0);
                //Keep it constrained.
                if (hurdleWidth > maxSize)
                {
                    hurdleWidth = maxSize;
                }
                if (hurdleWidth < 1)
                {
                    hurdleWidth = 1;
                }

                //Get the width of the plateau given the size of a hurdle.
                plateauExtent  = area.Width + 1 - hurdleWidth;
                plateauExtent /= 2;

                //Fill in the plateaus.
                data.FillRegion(true, new Region(area.Left, area.Top + border + (i * (space + plateauSize)), plateauExtent - 1, plateauSize - 1));
                if ((2 * plateauExtent) + hurdleWidth >= area.Width + 1)
                {
                    data.FillRegion(true, new Region(area.Right - plateauExtent + 1, area.Top + border + (i * (space + plateauSize)), plateauExtent - 1, plateauSize - 1));
                }
                else
                {
                    data.FillRegion(true, new Region(area.Right - plateauExtent, area.Top + border + (i * (space + plateauSize)), plateauExtent, plateauSize - 1));
                }
            }

            //Make room for any holes that the plateaus covered.
            foreach (Location l in data.HolesAlongPerimeter())
            {
                //The hole is covered if it is just left/right of the region and the space just right/left of it (respectively) is filled.
                if ((area.Touches(l.Left, true, true, false) && data.GetMapAt(l.Left)) ||
                    (area.Touches(l.Right, true, true, false) && data.GetMapAt(l.Right)))
                {
                    //Make a little tunnel under the plateau.
                    int[]  plateauSides = SteppedHallwayPattern.PlateauSides(l.Y, numb, plateauSize, space, border, area.Top, area.Bottom);
                    Region cleared;
                    if (l.X - 1 == area.Right)
                    {
                        cleared = new Region(data.BeingFilled.Right, plateauSides[0], 0, plateauSize - 1);
                    }
                    else
                    {
                        cleared = new Region(data.BeingFilled.Left, plateauSides[0], 0, plateauSize - 1);
                    }
                    data.FillRegion(false, cleared);
                }
            }
        }
        else
        {
            //Horizontal.

            //Add the plateaus.
            int hurdleHeight, plateauHeight;
            for (int i = 0; i < numb; ++i)
            {
                //Get a height within the given random variation.
                hurdleHeight = (int)Math.Round((area.Height + 1) * (HurdleAverageSpaceScale + ((2 * HurdleHeightVariance * (float)GeneratorSettings.R.NextDouble()) - HurdleHeightVariance)), 0);
                //Keep it constrained.
                if (hurdleHeight > maxSize)
                {
                    hurdleHeight = maxSize;
                }
                if (hurdleHeight < 1)
                {
                    hurdleHeight = 1;
                }

                //Get the height of the plateau given the size of a hurdle.
                plateauHeight  = area.Height + 1 - hurdleHeight;
                plateauHeight /= 2;

                //Fill in the plateaus.
                data.FillRegion(true, new Region(area.Left + border + (i * (space + plateauSize)), area.Top, plateauSize - 1, plateauHeight - 1));
                if ((2 * plateauHeight) + hurdleHeight >= area.Height + 1)
                {
                    data.FillRegion(true, new Region(area.Left + border + (i * (space + plateauSize)), area.Bottom - plateauHeight + 1, plateauSize - 1, plateauHeight - 1));
                    spawningAreas.Add(new Region(area.Left + border + (i * (space + plateauSize)), area.Top + plateauHeight, plateauSize - 1, data.BeingFilled.Height - plateauHeight - plateauHeight - 2));
                }
                else
                {
                    data.FillRegion(true, new Region(area.Left + border + (i * (space + plateauSize)), area.Bottom - plateauHeight, plateauSize - 1, plateauHeight));
                    spawningAreas.Add(new Region(area.Left + border + (i * (space + plateauSize)), area.Top + plateauHeight, plateauSize - 1, data.BeingFilled.Height - plateauHeight - plateauHeight - 1));
                }
            }
        }


        //Make room for any holes that the plateaus covered.
        foreach (Location l in data.HolesAlongPerimeter())
        {
            //Horizontal.
            if (area.Height < area.Width)
            {
                //The hole is covered if it is just below/above the region and the space above/below it (respectively) is filled.
                if ((area.Touches(l.Above, true, true, false) && data.GetMapAt(l.Above)) ||
                    (area.Touches(l.Below, true, true, false) && data.GetMapAt(l.Below)))
                {
                    //Make a little tunnel under the plateau.
                    int[] plateauSides = SteppedHallwayPattern.PlateauSides(l.X, numb, plateauSize, space, border, area.Left, area.Right);

                    Region cleared;
                    if (l.Y - 1 == area.Bottom)
                    {
                        cleared = new Region(plateauSides[0], data.BeingFilled.Bottom, plateauSize - 1, 0);
                    }
                    else
                    {
                        cleared = new Region(plateauSides[0], data.BeingFilled.Top, plateauSize - 1, 0);
                    }

                    data.FillRegion(false, cleared);
                }
            }

            //Vertical.
            else if ((area.Touches(l.Left, true, true, false) && data.GetMapAt(l.Left)) ||
                     (area.Touches(l.Right, true, true, false) && data.GetMapAt(l.Right)))
            {
                //Make a little tunnel under the plateau.
                int[] plateauSides = SteppedHallwayPattern.PlateauSides(l.Y, numb, plateauSize, space, border, area.Top, area.Bottom);

                Region cleared;
                if (l.X - 1 == area.Right)
                {
                    cleared = new Region(data.BeingFilled.Right, plateauSides[0], 0, plateauSize - 1);
                }
                else
                {
                    cleared = new Region(data.BeingFilled.Left, plateauSides[0], 0, plateauSize - 1);
                }

                data.FillRegion(false, cleared);
            }
        }

        //Return the new regions.
        return(new ThickHurdleRegion(data.BeingFilled, spawningAreas));
    }
Пример #7
0
    public FilledRegion Apply(FillData data)
    {
        //Start on either the relative top or bottom of the corridor.
        bool top = MathF.R.NextDouble() > 0.5;

        //Set up the plateau properties.
        bool horizontal = data.BeingFilled.Width > data.BeingFilled.Height;

        if (horizontal)
        {
            Generation.BeingFilled = data.BeingFilled;
        }
        else
        {
            Generation.BeingFilled = new Region(data.BeingFilled.Y,
                                                data.BeingFilled.X,
                                                data.BeingFilled.Height,
                                                data.BeingFilled.Width);
        }

        int spaceBetween = Generation.SpaceBetweenPlateaus;
        int border       = Generation.Border;
        int plateauWidth = Generation.PlateauWidth;
        int numbPlateaus = Generation.NumbPlateaus;

        //Fill the area. Also keep track of the free space above/below plateaus.
        List <Region> freeAreas = new List <Region>();

        for (int i = 0; i < numbPlateaus; ++i)
        {
            if (top)
            {
                if (horizontal)
                {
                    data.FillRegion(true, new Region(data.BeingFilled.Left + border + (i * (spaceBetween + plateauWidth)),
                                                     data.BeingFilled.Top,
                                                     plateauWidth - 1,
                                                     data.BeingFilled.Height - 1));
                    freeAreas.Add(new Region(data.BeingFilled.Left + border + (i * (spaceBetween + plateauWidth)),
                                             data.BeingFilled.Bottom,
                                             plateauWidth - 1, 0));
                }
                else
                {
                    data.FillRegion(true, new Region(data.BeingFilled.Left,
                                                     data.BeingFilled.Top + border + (i * (spaceBetween + plateauWidth)),
                                                     data.BeingFilled.Width - 1,
                                                     plateauWidth - 1));
                    freeAreas.Add(new Region(data.BeingFilled.Left + 1,
                                             data.BeingFilled.Top + border + (i * (spaceBetween + plateauWidth)) - 1,
                                             data.BeingFilled.Width - 2, 0));
                }
            }
            else
            {
                if (horizontal)
                {
                    data.FillRegion(true, new Region(data.BeingFilled.Left + border + (i * (spaceBetween + plateauWidth)),
                                                     data.BeingFilled.Top + 1,
                                                     plateauWidth - 1,
                                                     data.BeingFilled.Height - 1));
                    freeAreas.Add(new Region(data.BeingFilled.Left + border + (i * (spaceBetween + plateauWidth)),
                                             data.BeingFilled.Top,
                                             plateauWidth - 1, 0));
                }
                else
                {
                    data.FillRegion(true, new Region(data.BeingFilled.Left + 1,
                                                     data.BeingFilled.Top + border + (i * (spaceBetween + plateauWidth)),
                                                     data.BeingFilled.Width - 1,
                                                     plateauWidth - 1));
                    freeAreas.Add(new Region(data.BeingFilled.Left + 1,
                                             data.BeingFilled.Top + border + (i * (spaceBetween + plateauWidth)) - 1,
                                             data.BeingFilled.Width - 2, 0));
                }
            }

            top = !top;
        }

        Region area = data.BeingFilled;

        //Make room for any holes that the plateaus covered.
        //TODO: Instead of clearing out the bottom, just clear that column of plateau. Possibly also do this for other plateau patterns?
        foreach (Location l in data.HolesAlongPerimeter())
        {
            //Horizontal.
            if (area.Height < area.Width)
            {
                //The hole is covered if it is just below/above the region and the space above/below it (respectively) is filled.
                if ((area.Touches(l.Above, true, true, false) && data.GetMapAt(l.Above)) ||
                    (area.Touches(l.Below, true, true, false) && data.GetMapAt(l.Below)))
                {
                    //Make a little tunnel under the plateau.
                    int[] plateauSides = SteppedHallwayPattern.PlateauSides(l.X, numbPlateaus, plateauWidth, spaceBetween, border, area.Left, area.Right);

                    Region cleared;
                    if (l.Y - 1 == area.Bottom)
                    {
                        cleared = new Region(plateauSides[0], data.BeingFilled.Bottom, plateauWidth - 1, 0);
                    }
                    else
                    {
                        cleared = new Region(plateauSides[0], data.BeingFilled.Top, plateauWidth - 1, 0);
                    }

                    data.FillRegion(false, cleared);
                }
            }

            //Vertical
            else if ((area.Touches(l.Left, true, true, false) && data.GetMapAt(l.Left)) ||
                     (area.Touches(l.Right, true, true, false) && data.GetMapAt(l.Right)))
            {
                //Make a little tunnel under the plateau.
                int[] plateauSides = SteppedHallwayPattern.PlateauSides(l.Y, numbPlateaus, plateauWidth, spaceBetween, border, area.Top, area.Bottom);

                Region cleared;
                if (l.X - 1 == area.Right)
                {
                    cleared = new Region(data.BeingFilled.Right, plateauSides[0], 0, plateauWidth - 1);
                }
                else
                {
                    cleared = new Region(data.BeingFilled.Left, plateauSides[0], 0, plateauWidth - 1);
                }

                data.FillRegion(false, cleared);
            }
        }

        if (horizontal)
        {
            return(new ZipperRegion(data.BeingFilled, freeAreas));
        }
        else
        {
            return(new ZipperRegion(data.BeingFilled, new List <Region>()));
        }
    }