public Map GenerateMap(int extraConnections) { LogFile.Log.LogEntry(String.Format("Generating BSP dungeon")); baseMap = new Map(width, height); //Make a BSP tree for the rooms rootNode = new MapNode(0, 0, width, height); rootNode.Split(); //Draw a room in each BSP leaf rootNode.DrawRoomAtLeaf(baseMap); //debug //Screen.Instance.DrawMapDebug(baseMap); //Draw connecting corridors rootNode.DrawCorridorConnectingChildren(baseMap); //Add any extra connecting corridors as specified for (int i = 0; i < extraConnections; i++) { rootNode.AddRandomConnection(baseMap); } //Add doors where single corridors terminate into rooms AddDoors(); //Turn corridors into normal squares and surround with walls CorridorsIntoRooms(); //Set which squares are light blocking //Now done during creation //SetLightBlocking(baseMap); //Set the PC start location in a random room baseMap.PCStartLocation = rootNode.RandomRoomPoint(); return(baseMap); }
public Map GenerateMap(int extraConnections) { LogFile.Log.LogEntry(String.Format("Generating BSP dungeon")); baseMap = new Map(width, height); //Make a BSP tree for the rooms rootNode = new MapNode(0, 0, width, height); rootNode.Split(); //Draw a room in each BSP leaf rootNode.DrawRoomAtLeaf(baseMap); //debug //Screen.Instance.DrawMapDebug(baseMap); //Draw connecting corridors rootNode.DrawCorridorConnectingChildren(baseMap); //Add any extra connecting corridors as specified for (int i = 0; i < extraConnections; i++) { rootNode.AddRandomConnection(baseMap); } //Add doors where single corridors terminate into rooms AddDoors(); //Turn corridors into normal squares and surround with walls CorridorsIntoRooms(); //Set which squares are light blocking //Now done during creation //SetLightBlocking(baseMap); //Set the PC start location in a random room baseMap.PCStartLocation = rootNode.RandomRoomPoint(); return baseMap; }
public Map GenerateMap(int extraConnections) { LogFile.Log.LogEntry(String.Format("Generating BSP dungeon")); do { baseMap = new Map(width, height); connectivityGraph = new ConnectivityMap(); //BSP is always connected baseMap.GuaranteedConnected = true; //Make a BSP tree for the rooms rootNode = new MapNode(this, 0, 0, width, height); rootNode.Split(); //Draw a room in each BSP leaf rootNode.DrawRoomAtLeaf(baseMap); //debug //Screen.Instance.DrawMapDebug(baseMap); //Draw connecting corridors rootNode.DrawCorridorConnectingChildren(baseMap); //Add any extra connecting corridors as specified for (int i = 0; i < extraConnections; i++) { rootNode.AddRandomConnection(baseMap); } //Add doors where single corridors terminate into rooms AddDoorsGraph(); //Turn corridors into normal squares and surround with walls CorridorsIntoRooms(); //Work out where the staircases will be //We just want 2 places that aren't too close to each other. The map is guaranteed connected double RequiredStairDistance = (width * 0.5); double stairDistance; do { upStaircase = RandomWalkablePoint(); downStaircase = RandomWalkablePoint(); stairDistance = Math.Sqrt(Math.Pow(upStaircase.x - downStaircase.x, 2) + Math.Pow(upStaircase.y - downStaircase.y, 2)); } while (stairDistance < RequiredStairDistance); //Set which squares are light blocking //Now done during creation //SetLightBlocking(baseMap); //Set the PC start location in a random room baseMap.PCStartLocation = AddEntryRoomForPlayer(); } while (baseMap.PCStartLocation == null); //Fake a start room PointInRoom randomRoom = RandomPointInRoom(); //baseMap.PCStartLocation = randomRoom.GetPointInRoomOnly(); baseMap.PCStartRoomId = randomRoom.RoomId; //Build the map model for the graph, based on the PC's true starting position (useful for locking doors) graphModel = new MapModel(connectivityGraph, baseMap.PCStartRoomId); //Save out the graph GraphvizExport.OutputUndirectedGraph(connectivityGraph.RoomConnectionGraph, "bsptree-base"); //Save out a copy of the graph with no cycles GraphvizExport.OutputUndirectedGraph(graphModel.GraphNoCycles.mapNoCycles, "bsptree-nocycles"); return baseMap.Clone(); }
public void Split() { Random rand = MapGeneratorBSP.rand; split = SplitType.Vertical; //Long thin areas are more likely to be split widthways and vice versa if(rand.Next(width + height) < width) { split = SplitType.Horizontal; } if (split == SplitType.Horizontal) { //Small chance that we don't recurse any further int chanceNoSplitHoriz = mustSplitSize - (width / minBSPSquareWidth); if (rand.Next(noSplitChance) < chanceNoSplitHoriz) { childLeft = null; childRight = null; return; } int minSplit = (int)(width * minimumSplit); int maxSplit = (int)(width * maximumSplit); actualSplit = minSplit + rand.Next(maxSplit - minSplit + 1); //Define the two child areas, make objects and then recursively split them if (actualSplit < minBSPSquareWidth) { childLeft = null; } else { childLeft = new MapNode(parentGenerator, x, y, actualSplit, height); childLeft.Split(); } if (width - actualSplit < minBSPSquareWidth) { childRight = null; } else { childRight = new MapNode(parentGenerator, x + actualSplit, y, width - actualSplit, height); childRight.Split(); } } else { //SplitType.Vertical //Small chance that we don't recurse any further int chanceNoSplitVert = mustSplitSize - (height / minBSPSquareHeight); if (rand.Next(noSplitChance) < chanceNoSplitVert) { childLeft = null; childRight = null; } int minSplit = (int)(height * minimumSplit); int maxSplit = (int)(height * maximumSplit); actualSplit = minSplit + rand.Next(maxSplit - minSplit + 1); //Define the two child areas, make objects and then recursively split them if (actualSplit < minBSPSquareHeight) { childLeft = null; } else { childLeft = new MapNode(parentGenerator, x, y, width, actualSplit); childLeft.Split(); } if (height - actualSplit < minBSPSquareHeight) { childRight = null; } else { childRight = new MapNode(parentGenerator, x, y + actualSplit, width, height - actualSplit); childRight.Split(); } } }
public void Split() { Random rand = MapGeneratorBSP.rand; split = SplitType.Vertical; //Long thin areas are more likely to be split widthways and vice versa if (rand.Next(width + height) < width) { split = SplitType.Horizontal; } if (split == SplitType.Horizontal) { //Small chance that we don't recurse any further int chanceNoSplitHoriz = mustSplitSize - (width / minBSPSquareWidth); if (rand.Next(noSplitChance) < chanceNoSplitHoriz) { childLeft = null; childRight = null; return; } int minSplit = (int)(width * minimumSplit); int maxSplit = (int)(width * maximumSplit); actualSplit = minSplit + rand.Next(maxSplit - minSplit + 1); //Define the two child areas, make objects and then recursively split them if (actualSplit < minBSPSquareWidth) { childLeft = null; } else { childLeft = new MapNode(x, y, actualSplit, height); childLeft.Split(); } if (width - actualSplit < minBSPSquareWidth) { childRight = null; } else { childRight = new MapNode(x + actualSplit, y, width - actualSplit, height); childRight.Split(); } } else { //SplitType.Vertical //Small chance that we don't recurse any further int chanceNoSplitVert = mustSplitSize - (height / minBSPSquareHeight); if (rand.Next(noSplitChance) < chanceNoSplitVert) { childLeft = null; childRight = null; } int minSplit = (int)(height * minimumSplit); int maxSplit = (int)(height * maximumSplit); actualSplit = minSplit + rand.Next(maxSplit - minSplit + 1); //Define the two child areas, make objects and then recursively split them if (actualSplit < minBSPSquareHeight) { childLeft = null; } else { childLeft = new MapNode(x, y, width, actualSplit); childLeft.Split(); } if (height - actualSplit < minBSPSquareHeight) { childRight = null; } else { childRight = new MapNode(x, y + actualSplit, width, height - actualSplit); childRight.Split(); } } }
public Map GenerateMap(int extraConnections) { LogFile.Log.LogEntry(String.Format("Generating BSPCave dungeon")); baseMap = new Map(width, height); //BSP is always connected baseMap.GuaranteedConnected = true; //Make a BSP tree for the rooms rootNode = new MapNode(this, 0, 0, width, height); rootNode.Split(); //Draw a room in each BSP leaf rootNode.DrawRoomAtLeaf(baseMap); //debug //Screen.Instance.DrawMapDebug(baseMap); //Draw connecting corridors rootNode.DrawCorridorConnectingChildren(baseMap); //Add any extra connecting corridors as specified for (int i = 0; i < extraConnections; i++) { rootNode.AddRandomConnection(baseMap); } //Add doors where single corridors terminate into rooms AddDoors(); //Turn corridors into normal squares and surround with walls CorridorsIntoRooms(); //Now fill all void with walls //Fill the map with walls for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (baseMap.mapSquares[i, j].Terrain == MapTerrain.Void) { baseMap.mapSquares[i, j].Terrain = MapTerrain.Wall; } } } //Work out where the staircases will be //We just want 2 places that aren't too close to each other. The map is guaranteed connected double RequiredStairDistance = (width * 0.5); double stairDistance; do { upStaircase = RandomWalkablePoint(); downStaircase = RandomWalkablePoint(); stairDistance = Math.Sqrt(Math.Pow(upStaircase.x - downStaircase.x, 2) + Math.Pow(upStaircase.y - downStaircase.y, 2)); } while (stairDistance < RequiredStairDistance); //Set which squares are light blocking //Now done during creation //SetLightBlocking(baseMap); //Set the PC start location in a random room baseMap.PCStartLocation = rootNode.RandomRoomPoint().GetPointInRoomOnly(); //Now we use the cave algorithm to eat the map //Instead of setting this Empty like in cave, set them to Corridor temporarily (so the algo knows where it's been) DiggingChance = 22; //Start digging from a random point int noDiggingPoints = 6 + Game.Random.Next(2); for (int i = 0; i < noDiggingPoints; i++) { int x = Game.Random.Next(width); int y = Game.Random.Next(height); //Don't dig right to the edge if (x == 0) { x = 1; } if (x == width - 1) { x = width - 2; } if (y == 0) { y = 1; } if (y == height - 1) { y = height - 2; } Dig(x, y); } //Turn the corridors into empty for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (baseMap.mapSquares[i, j].Terrain == MapTerrain.Corridor) { baseMap.mapSquares[i, j].Terrain = MapTerrain.Empty; } } } //Do a final pass to convert Wall into something more exciting if (wallType.Count > 0) { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (baseMap.mapSquares[i, j].Terrain == MapTerrain.Wall) { baseMap.mapSquares[i, j].Terrain = wallType[rand.Next(wallType.Count)]; } } } } return(baseMap.Clone()); }
public Map GenerateMap(int extraConnections) { LogFile.Log.LogEntry(String.Format("Generating BSPCave dungeon")); baseMap = new Map(width, height); //BSP is always connected baseMap.GuaranteedConnected = true; //Make a BSP tree for the rooms rootNode = new MapNode(this, 0, 0, width, height); rootNode.Split(); //Draw a room in each BSP leaf rootNode.DrawRoomAtLeaf(baseMap); //debug //Screen.Instance.DrawMapDebug(baseMap); //Draw connecting corridors rootNode.DrawCorridorConnectingChildren(baseMap); //Add any extra connecting corridors as specified for (int i = 0; i < extraConnections; i++) { rootNode.AddRandomConnection(baseMap); } //Add doors where single corridors terminate into rooms AddDoors(); //Turn corridors into normal squares and surround with walls CorridorsIntoRooms(); //Now fill all void with walls //Fill the map with walls for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (baseMap.mapSquares[i, j].Terrain == MapTerrain.Void) { baseMap.mapSquares[i, j].Terrain = MapTerrain.Wall; } } } //Work out where the staircases will be //We just want 2 places that aren't too close to each other. The map is guaranteed connected double RequiredStairDistance = (width * 0.5); double stairDistance; do { upStaircase = RandomWalkablePoint(); downStaircase = RandomWalkablePoint(); stairDistance = Math.Sqrt(Math.Pow(upStaircase.x - downStaircase.x, 2) + Math.Pow(upStaircase.y - downStaircase.y, 2)); } while (stairDistance < RequiredStairDistance); //Set which squares are light blocking //Now done during creation //SetLightBlocking(baseMap); //Set the PC start location in a random room baseMap.PCStartLocation = rootNode.RandomRoomPoint().GetPointInRoomOnly(); //Now we use the cave algorithm to eat the map //Instead of setting this Empty like in cave, set them to Corridor temporarily (so the algo knows where it's been) DiggingChance = 22; //Start digging from a random point int noDiggingPoints = 6 + Game.Random.Next(2); for (int i = 0; i < noDiggingPoints; i++) { int x = Game.Random.Next(width); int y = Game.Random.Next(height); //Don't dig right to the edge if (x == 0) x = 1; if (x == width - 1) x = width - 2; if (y == 0) y = 1; if (y == height - 1) y = height - 2; Dig(x, y); } //Turn the corridors into empty for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (baseMap.mapSquares[i, j].Terrain == MapTerrain.Corridor) { baseMap.mapSquares[i, j].Terrain = MapTerrain.Empty; } } } //Do a final pass to convert Wall into something more exciting if (wallType.Count > 0) { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (baseMap.mapSquares[i, j].Terrain == MapTerrain.Wall) { baseMap.mapSquares[i, j].Terrain = wallType[rand.Next(wallType.Count)]; } } } } return baseMap.Clone(); }