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