public override void Generate(VGArea mArea) { // Randomly put solid tiles in the world int solidTilesAmount = (mArea.Width * mArea.Height) / 100 * InitialSolidPercent; for (int i = 0; i < solidTilesAmount; i++) { mArea.GetRandomTile().Set(ValueSolid); } // Iterate generation for (int iteration = 0; iteration < Iterations; iteration++) { // Create a clone of the world's map VGArea areaClone = mArea.Clone(); // Cellar automata rule 4-5 for (int iY = 0; iY < areaClone.Height; iY++) { for (int iX = 0; iX < areaClone.Width; iX++) { if (areaClone.GetTileNeighborsCountByValue(iX, iY, 1, ValueSolid) <= RequiredSolidToStarve) { mArea[iX, iY].Set(ValuePassable); } else if (areaClone.GetTileNeighborsCountByValue(iX, iY, 1, ValueSolid) >= RequiredSolidToSolidify) { mArea[iX, iY].Set(ValueSolid); } } } } }
public override void Generate(VGArea mArea) { // Create a clone of the world's map VGArea areaClone = mArea.Clone(); // Set all solids to walls for (int iY = 0; iY < areaClone.Height; iY++) { for (int iX = 0; iX < areaClone.Width; iX++) { if (areaClone[iX, iY].Value == ValueSolid) { mArea[iX, iY].Set(ValueWall); } } } // Create a clone of the world's map areaClone = mArea.Clone(); // Sets all walls with 9 wall neighbors to solid for (int iY = 0; iY < areaClone.Height; iY++) { for (int iX = 0; iX < areaClone.Width; iX++) { if (areaClone.GetTileNeighborsCountByValue(iX, iY, ValueWall) > 8) { mArea[iX, iY].Set(ValueSolid); } } } }
public void Connect2(VGArea mAreaStart, VGArea mAreaEnd) { VGTile start = mAreaStart.GetRandomBorderTile(); VGTile end = mAreaEnd.GetRandomBorderTile(); start.Set(ValuePath, true); end.Set(ValuePath, true); Path path = PGPathfinder.FindPath(mAreaStart.World.WorldArea, start.Node, end.Node); if (path == null) { return; } List <PGNode> nodes = new List <PGNode>(); for (Path p = path; p != null; p = p.PreviousSteps) { nodes.Add(p.LastStep); } foreach (PGNode node in nodes) { node.Tile.Set(ValuePath); //foreach (VGTile tile in mAreaStart.World.WorldArea.GetTileNeighbors(node.X, node.Y)) if (tile.Value == 0) tile.Set(ValueSolid, false); } }
public static Path FindPath(VGArea mMap, PGNode mStart, PGNode mEnd) { foreach(VGTile tile in mMap.Tiles) tile.Node.Clear(); var closed = new HashSet<PGNode>(); var queue = new PriorityQueue<double, Path>(); queue.Enqueue(0, new Path(mStart)); while (!queue.IsEmpty) { var path = queue.Dequeue(); if (!path.LastStep.Passable || closed.Contains(path.LastStep)) continue; if (path.LastStep.Equals(mEnd)) { return path; } closed.Add(path.LastStep); foreach (PGNode n in mMap.GetTileNodeNeighbors(path.LastStep.Tile.X, path.LastStep.Tile.Y)) { double d = PGUtils.GetNodeDiagonalDistance(path.LastStep, n); var newPath = path.AddStep(n, d); queue.Enqueue(newPath.TotalCost + PGUtils.GetNodeManhattanDistance(n, mEnd), newPath); } } return null; }
public static Path FindPath(VGArea mMap, PGNode mStart, PGNode mEnd) { foreach (VGTile tile in mMap.Tiles) { tile.Node.Clear(); } var closed = new HashSet <PGNode>(); var queue = new PriorityQueue <double, Path>(); queue.Enqueue(0, new Path(mStart)); while (!queue.IsEmpty) { var path = queue.Dequeue(); if (!path.LastStep.Passable || closed.Contains(path.LastStep)) { continue; } if (path.LastStep.Equals(mEnd)) { return(path); } closed.Add(path.LastStep); foreach (PGNode n in mMap.GetTileNodeNeighbors(path.LastStep.Tile.X, path.LastStep.Tile.Y)) { double d = PGUtils.GetNodeDiagonalDistance(path.LastStep, n); var newPath = path.AddStep(n, d); queue.Enqueue(newPath.TotalCost + PGUtils.GetNodeManhattanDistance(n, mEnd), newPath); } } return(null); }
private void Button5Click(object sender, EventArgs e) { VGArea currentArea = new VGArea(World, Convert.ToInt32(textBox21.Text), Convert.ToInt32(textBox22.Text), Convert.ToInt32(textBox23.Text), Convert.ToInt32(textBox24.Text)); VGGOutliner outliner = new VGGOutliner(); outliner.Generate(currentArea); richTextBox1.Text = World.WorldArea.ToString(); }
private void Button3Click(object sender, EventArgs e) { VGArea currentArea = new VGArea(World, Convert.ToInt32(textBox21.Text), Convert.ToInt32(textBox22.Text), Convert.ToInt32(textBox23.Text), Convert.ToInt32(textBox24.Text)); VGGBSPDungeon bsp = new VGGBSPDungeon(4, 3, 1, Convert.ToInt32(textBox8.Text), Convert.ToInt32(textBox11.Text), Convert.ToInt32(textBox9.Text), checkBox1.Checked, checkBox4.Checked, Convert.ToInt32(textBox19.Text), Convert.ToInt32(textBox20.Text), checkBox5.Checked); bsp.Generate(currentArea); richTextBox1.Text = World.WorldArea.ToString(); }
public override void Generate(VGArea mArea) { FinalAreas.Add(mArea.Clone()); for (int i = 0; i < Splits; i++) { FinalAreas = Split(FinalAreas, i % 2 == 0, i == Splits - 1); } List <VGArea> toRemove = FinalAreas.Where(t => VGUtils.GetRandomInt(0, 100) <= RemoveChancePercent).ToList(); foreach (VGArea area in toRemove) { FinalAreas.Remove(area); } if (IsBorder) { foreach (VGArea area in FinalAreas) { foreach (VGTile tile in area.GetBorderTiles()) { tile.Set(ValueSolid, false); } } } if (IsCarved) { foreach (VGArea area in FinalAreas) { for (int iY = 1 + CarveOffset; iY < area.Height - 1 - CarveOffset; iY++) { for (int iX = 1 + CarveOffset; iX < area.Width - 1 - CarveOffset; iX++) { area[iX, iY].Set(ValueRoom); } } } } if (IsConnected) { for (int index = 0; index < FinalAreas.Count - 1; index++) { Connect(FinalAreas[index], FinalAreas[index + 1]); } } mArea.SetBorder(1); }
private void Button4Click(object sender, EventArgs e) { VGArea currentArea = new VGArea(World, Convert.ToInt32(textBox21.Text), Convert.ToInt32(textBox22.Text), Convert.ToInt32(textBox23.Text), Convert.ToInt32(textBox24.Text)); VGGWalker walker = new VGGWalker(0, 1, Convert.ToInt32(textBox10.Text), Convert.ToInt32(textBox14.Text), Convert.ToInt32(textBox13.Text), Convert.ToInt32(textBox12.Text), Convert.ToInt32(textBox15.Text), checkBox2.Checked, checkBox3.Checked, Convert.ToInt32(textBox16.Text), Convert.ToInt32(textBox17.Text), Convert.ToInt32(textBox18.Text)); walker.Generate(currentArea); richTextBox1.Text = World.WorldArea.ToString(); }
public override void Generate(VGArea mArea) { // Create a clone of the world's map VGArea areaClone = mArea.Clone(); // Set all solids to walls for (int iY = 0; iY < areaClone.Height; iY++) for (int iX = 0; iX < areaClone.Width; iX++) if (areaClone[iX, iY].Value == ValueSolid) mArea[iX, iY].Set(ValueWall); // Create a clone of the world's map areaClone = mArea.Clone(); // Sets all walls with 9 wall neighbors to solid for (int iY = 0; iY < areaClone.Height; iY++) for (int iX = 0; iX < areaClone.Width; iX++) if (areaClone.GetTileNeighborsCountByValue(iX, iY, ValueWall) > 8) mArea[iX, iY].Set(ValueSolid); }
private void Button6Click(object sender, EventArgs e) { VGArea currentArea = new VGArea(World, Convert.ToInt32(textBox21.Text), Convert.ToInt32(textBox22.Text), Convert.ToInt32(textBox23.Text), Convert.ToInt32(textBox24.Text)); VGGCave cave = new VGGCave(mIterations: 3, mInitialSolidPercent: 75); VGGBSPDungeon bsp = new VGGBSPDungeon(mSplits: 9, mCarveOffset: 1); VGGOutliner outliner = new VGGOutliner(); cave.Generate(currentArea); bsp.Generate(currentArea); outliner.Generate(currentArea); richTextBox1.Text = World.WorldArea.ToString(); }
private void Button2Click(object sender, EventArgs e) { VGArea currentArea = new VGArea(World, Convert.ToInt32(textBox21.Text), Convert.ToInt32(textBox22.Text), Convert.ToInt32(textBox23.Text), Convert.ToInt32(textBox24.Text)); int coverage = Convert.ToInt32(textBox7.Text); int fc = Convert.ToInt32(textBox4.Text); int wc = Convert.ToInt32(textBox5.Text); int iterations = Convert.ToInt32(textBox6.Text); VGGCave cave = new VGGCave(0, 1, coverage, fc, wc, iterations); cave.Generate(currentArea); richTextBox1.Text = World.WorldArea.ToString(); }
public override void Generate(VGArea mArea) { // Randomly put solid tiles in the world int solidTilesAmount = (mArea.Width*mArea.Height)/100*InitialSolidPercent; for (int i = 0; i < solidTilesAmount; i++) mArea.GetRandomTile().Set(ValueSolid); // Iterate generation for (int iteration = 0; iteration < Iterations; iteration++) { // Create a clone of the world's map VGArea areaClone = mArea.Clone(); // Cellar automata rule 4-5 for (int iY = 0; iY < areaClone.Height; iY++) { for (int iX = 0; iX < areaClone.Width; iX++) { if (areaClone.GetTileNeighborsCountByValue(iX, iY, 1, ValueSolid) <= RequiredSolidToStarve) mArea[iX, iY].Set(ValuePassable); else if (areaClone.GetTileNeighborsCountByValue(iX, iY, 1, ValueSolid) >= RequiredSolidToSolidify) mArea[iX, iY].Set(ValueSolid); } } } }
public abstract void Generate(VGArea mArea);
public override void Generate(VGArea mArea) { for (int i = 0; i < WalkersAmount; i++) { VGTile randomTile = mArea.GetRandomTile(); WalkerPaths.Add(new VGGWalkerPath(randomTile.X, randomTile.Y, WalkerMinimumSteps, WalkerMaximumSteps, WalkerDeathChance, WalkerDirectionChangeChance)); } bool running = true; while (running) { List<VGGWalkerPath> toRemove = new List<VGGWalkerPath>(); running = false; foreach (VGGWalkerPath path in WalkerPaths) { if (mArea.Contains(path.X, path.Y)) { for (int iY = -WalkerRadius; iY < WalkerRadius + 1; iY++) for (int iX = -WalkerRadius; iX < WalkerRadius + 1; iX++) if (mArea.Contains(path.X + iX, path.Y + iY)) mArea[path.X + iX, path.Y + iY].Set(ValuePassable); } else if (IsWrapped) { if (path.X >= mArea.Width) path.X = 0; else if (path.X < 0) path.X = mArea.Width - 1; if (path.Y >= mArea.Height) path.Y = 0; else if (path.Y < 0) path.Y = mArea.Height - 1; } path.Step(); if (path.Alive) running = true; else if (IsRoomCreatedOnDeath) { toRemove.Add(path); int roomWidth = VGUtils.GetRandomInt(RoomMinSize, RoomMaxSize); int roomHeight = VGUtils.GetRandomInt(RoomMinSize, RoomMaxSize); for (int iY = 0; iY < roomHeight; iY++) for (int iX = 0; iX < roomWidth; iX++) if (mArea.Contains(path.X - (roomWidth/2) + iX, path.Y - (roomHeight/2) + iY)) mArea[path.X - (roomWidth/2) + iX, path.Y - (roomHeight/2) + iY].Set(ValuePassable); } } foreach (VGGWalkerPath pathToRemove in toRemove) WalkerPaths.Remove(pathToRemove); } }
public override void Generate(VGArea mArea) { for (int i = 0; i < WalkersAmount; i++) { VGTile randomTile = mArea.GetRandomTile(); WalkerPaths.Add(new VGGWalkerPath(randomTile.X, randomTile.Y, WalkerMinimumSteps, WalkerMaximumSteps, WalkerDeathChance, WalkerDirectionChangeChance)); } bool running = true; while (running) { List <VGGWalkerPath> toRemove = new List <VGGWalkerPath>(); running = false; foreach (VGGWalkerPath path in WalkerPaths) { if (mArea.Contains(path.X, path.Y)) { for (int iY = -WalkerRadius; iY < WalkerRadius + 1; iY++) { for (int iX = -WalkerRadius; iX < WalkerRadius + 1; iX++) { if (mArea.Contains(path.X + iX, path.Y + iY)) { mArea[path.X + iX, path.Y + iY].Set(ValuePassable); } } } } else if (IsWrapped) { if (path.X >= mArea.Width) { path.X = 0; } else if (path.X < 0) { path.X = mArea.Width - 1; } if (path.Y >= mArea.Height) { path.Y = 0; } else if (path.Y < 0) { path.Y = mArea.Height - 1; } } path.Step(); if (path.Alive) { running = true; } else if (IsRoomCreatedOnDeath) { toRemove.Add(path); int roomWidth = VGUtils.GetRandomInt(RoomMinSize, RoomMaxSize); int roomHeight = VGUtils.GetRandomInt(RoomMinSize, RoomMaxSize); for (int iY = 0; iY < roomHeight; iY++) { for (int iX = 0; iX < roomWidth; iX++) { if (mArea.Contains(path.X - (roomWidth / 2) + iX, path.Y - (roomHeight / 2) + iY)) { mArea[path.X - (roomWidth / 2) + iX, path.Y - (roomHeight / 2) + iY].Set(ValuePassable); } } } } } foreach (VGGWalkerPath pathToRemove in toRemove) { WalkerPaths.Remove(pathToRemove); } } }
public void Connect2(VGArea mAreaStart, VGArea mAreaEnd) { VGTile start = mAreaStart.GetRandomBorderTile(); VGTile end = mAreaEnd.GetRandomBorderTile(); start.Set(ValuePath, true); end.Set(ValuePath, true); Path path = PGPathfinder.FindPath(mAreaStart.World.WorldArea, start.Node, end.Node); if (path == null) return; List<PGNode> nodes = new List<PGNode>(); for (Path p = path; p != null; p = p.PreviousSteps) nodes.Add(p.LastStep); foreach (PGNode node in nodes) { node.Tile.Set(ValuePath); //foreach (VGTile tile in mAreaStart.World.WorldArea.GetTileNeighbors(node.X, node.Y)) if (tile.Value == 0) tile.Set(ValueSolid, false); } }
public void Connect(VGArea mAreaStart, VGArea mAreaEnd) { int mStartCX = mAreaStart.XStart + mAreaStart.Width/2; int mStartCY = mAreaStart.YStart + mAreaStart.Height/2; int mEndCX = mAreaEnd.XStart + mAreaEnd.Width/2; int mEndCY = mAreaEnd.YStart + mAreaEnd.Height/2; if (Math.Abs(mEndCX - mStartCX) < Math.Abs(mEndCY - mStartCY)) { if (mStartCX > mEndCX && mStartCY == mEndCY) { mStartCX -= mAreaStart.Width/2; mEndCX += mAreaEnd.Width/2; } if (mStartCX < mEndCX && mStartCY == mEndCY) { mStartCX += mAreaStart.Width/2; mEndCX -= mAreaEnd.Width/2; } } else { if (mStartCY > mEndCY && mStartCX == mEndCX) { mStartCY -= mAreaStart.Height/2; mEndCY += mAreaEnd.Height/2; } if (mStartCY < mEndCY && mStartCX == mEndCX) { mStartCY += mAreaStart.Height/2; mEndCY -= mAreaEnd.Height/2; } } int currentX = mStartCX; int currentY = mStartCY; mAreaStart.World.WorldArea[currentX, currentY].Set(ValuePath); if (Math.Abs(mEndCX - mStartCX) < Math.Abs(mEndCY - mStartCY)) { while (currentX != mEndCX) { if (currentX > mEndCX) currentX--; else currentX++; mAreaStart.World.WorldArea[currentX, currentY].Set(ValuePath); } while (currentY != mEndCY) { if (currentY > mEndCY) currentY--; else currentY++; mAreaStart.World.WorldArea[currentX, currentY].Set(ValuePath); } } else { while (currentY != mEndCY) { if (currentY > mEndCY) currentY--; else currentY++; mAreaStart.World.WorldArea[currentX, currentY].Set(ValuePath); } while (currentX != mEndCX) { if (currentX > mEndCX) currentX--; else currentX++; mAreaStart.World.WorldArea[currentX, currentY].Set(ValuePath); } } }
public void Connect(VGArea mAreaStart, VGArea mAreaEnd) { int mStartCX = mAreaStart.XStart + mAreaStart.Width / 2; int mStartCY = mAreaStart.YStart + mAreaStart.Height / 2; int mEndCX = mAreaEnd.XStart + mAreaEnd.Width / 2; int mEndCY = mAreaEnd.YStart + mAreaEnd.Height / 2; if (Math.Abs(mEndCX - mStartCX) < Math.Abs(mEndCY - mStartCY)) { if (mStartCX > mEndCX && mStartCY == mEndCY) { mStartCX -= mAreaStart.Width / 2; mEndCX += mAreaEnd.Width / 2; } if (mStartCX < mEndCX && mStartCY == mEndCY) { mStartCX += mAreaStart.Width / 2; mEndCX -= mAreaEnd.Width / 2; } } else { if (mStartCY > mEndCY && mStartCX == mEndCX) { mStartCY -= mAreaStart.Height / 2; mEndCY += mAreaEnd.Height / 2; } if (mStartCY < mEndCY && mStartCX == mEndCX) { mStartCY += mAreaStart.Height / 2; mEndCY -= mAreaEnd.Height / 2; } } int currentX = mStartCX; int currentY = mStartCY; mAreaStart.World.WorldArea[currentX, currentY].Set(ValuePath); if (Math.Abs(mEndCX - mStartCX) < Math.Abs(mEndCY - mStartCY)) { while (currentX != mEndCX) { if (currentX > mEndCX) { currentX--; } else { currentX++; } mAreaStart.World.WorldArea[currentX, currentY].Set(ValuePath); } while (currentY != mEndCY) { if (currentY > mEndCY) { currentY--; } else { currentY++; } mAreaStart.World.WorldArea[currentX, currentY].Set(ValuePath); } } else { while (currentY != mEndCY) { if (currentY > mEndCY) { currentY--; } else { currentY++; } mAreaStart.World.WorldArea[currentX, currentY].Set(ValuePath); } while (currentX != mEndCX) { if (currentX > mEndCX) { currentX--; } else { currentX++; } mAreaStart.World.WorldArea[currentX, currentY].Set(ValuePath); } } }
public List <VGArea> Split(List <VGArea> mAreas, bool mHorizontal, bool mApplySplitOffset) { List <VGArea> result = new List <VGArea>(); foreach (VGArea area in mAreas) { int splitX; splitX = (area.XEnd - area.XStart) / 2 > MinimumSplitDistance?VGUtils.Random.Next(area.XStart + ((area.XEnd - area.XStart) / 2) - MinimumSplitDistance, area.XStart + ((area.XEnd - area.XStart) / 2) + MinimumSplitDistance) : VGUtils.Random.Next(area.XStart, area.XEnd); int splitY; splitY = (area.YEnd - area.YStart) / 2 > MinimumSplitDistance?VGUtils.Random.Next(area.YStart + ((area.YEnd - area.YStart) / 2) - MinimumSplitDistance, area.YStart + ((area.YEnd - area.YStart) / 2) + MinimumSplitDistance) : VGUtils.Random.Next(area.YStart, area.YEnd); int offset = 0; if (mApplySplitOffset) { offset = SplitOffset; } VGArea split1, split2; if (mHorizontal) { if ((area.XEnd - SplitOffset) - (area.XStart + SplitOffset) <= SplitOffset) { offset = 0; } if ((splitY - SplitOffset) - (area.YStart + SplitOffset) <= SplitOffset) { offset = 0; } if ((splitY + SplitOffset) - (area.YEnd - SplitOffset) <= SplitOffset) { offset = 0; } split1 = new VGArea(area.World, area.XStart + offset, area.YStart + offset, area.XEnd - offset, splitY - offset); if (area.World.WorldArea.Contains(area.XStart, splitY - 1)) { splitY--; } split2 = new VGArea(area.World, area.XStart + offset, splitY + offset, area.XEnd - offset, area.YEnd - offset); } else { if ((splitX - offset) - (area.XStart + SplitOffset) <= SplitOffset) { offset = 0; } if ((area.XEnd - SplitOffset) - (splitX + SplitOffset) <= SplitOffset) { offset = 0; } if ((area.YEnd - SplitOffset) - (area.YStart + SplitOffset) <= SplitOffset) { offset = 0; } split1 = new VGArea(area.World, area.XStart + offset, area.YStart + offset, splitX - offset, area.YEnd - offset); if (area.World.WorldArea.Contains(splitX - 1, area.YStart)) { splitX--; } split2 = new VGArea(area.World, splitX + offset, area.YStart + offset, area.XEnd - offset, area.YEnd - offset); } result.Add(split1); result.Add(split2); } return(result); }
public override void Generate(VGArea mArea) { FinalAreas.Add(mArea.Clone()); for (int i = 0; i < Splits; i++) FinalAreas = Split(FinalAreas, i%2 == 0, i == Splits - 1); List<VGArea> toRemove = FinalAreas.Where(t => VGUtils.GetRandomInt(0, 100) <= RemoveChancePercent).ToList(); foreach (VGArea area in toRemove) FinalAreas.Remove(area); if (IsBorder) foreach (VGArea area in FinalAreas) foreach(VGTile tile in area.GetBorderTiles()) tile.Set(ValueSolid, false); if (IsCarved) foreach (VGArea area in FinalAreas) for (int iY = 1 + CarveOffset; iY < area.Height - 1 - CarveOffset; iY++) for (int iX = 1 + CarveOffset; iX < area.Width - 1 - CarveOffset; iX++) area[iX, iY].Set(ValueRoom); if (IsConnected) for (int index = 0; index < FinalAreas.Count - 1; index++) Connect(FinalAreas[index], FinalAreas[index + 1]); mArea.SetBorder(1); }
public List<VGArea> Split(List<VGArea> mAreas, bool mHorizontal, bool mApplySplitOffset) { List<VGArea> result = new List<VGArea>(); foreach (VGArea area in mAreas) { int splitX; splitX = (area.XEnd - area.XStart)/2 > MinimumSplitDistance ? VGUtils.Random.Next(area.XStart + ((area.XEnd - area.XStart)/2) - MinimumSplitDistance, area.XStart + ((area.XEnd - area.XStart)/2) + MinimumSplitDistance) : VGUtils.Random.Next(area.XStart, area.XEnd); int splitY; splitY = (area.YEnd - area.YStart)/2 > MinimumSplitDistance ? VGUtils.Random.Next(area.YStart + ((area.YEnd - area.YStart)/2) - MinimumSplitDistance, area.YStart + ((area.YEnd - area.YStart)/2) + MinimumSplitDistance) : VGUtils.Random.Next(area.YStart, area.YEnd); int offset = 0; if (mApplySplitOffset) offset = SplitOffset; VGArea split1, split2; if (mHorizontal) { if ((area.XEnd - SplitOffset) - (area.XStart + SplitOffset) <= SplitOffset) offset = 0; if ((splitY - SplitOffset) - (area.YStart + SplitOffset) <= SplitOffset) offset = 0; if ((splitY + SplitOffset) - (area.YEnd - SplitOffset) <= SplitOffset) offset = 0; split1 = new VGArea(area.World, area.XStart + offset, area.YStart + offset, area.XEnd - offset, splitY - offset); if (area.World.WorldArea.Contains(area.XStart, splitY - 1)) splitY--; split2 = new VGArea(area.World, area.XStart + offset, splitY + offset, area.XEnd - offset, area.YEnd - offset); } else { if ((splitX - offset) - (area.XStart + SplitOffset) <= SplitOffset) offset = 0; if ((area.XEnd - SplitOffset) - (splitX + SplitOffset) <= SplitOffset) offset = 0; if ((area.YEnd - SplitOffset) - (area.YStart + SplitOffset) <= SplitOffset) offset = 0; split1 = new VGArea(area.World, area.XStart + offset, area.YStart + offset, splitX - offset, area.YEnd - offset); if (area.World.WorldArea.Contains(splitX - 1, area.YStart)) splitX--; split2 = new VGArea(area.World, splitX + offset, area.YStart + offset, area.XEnd - offset, area.YEnd - offset); } result.Add(split1); result.Add(split2); } return result; }