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)); }
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>())); } }