private void GenerateMapNodeListCore(MapNode currentNode, List<MapNode> nodeList) { if (nodeList.Contains(currentNode)) return; nodeList.Add(currentNode); foreach (MapNode n in currentNode.Neighbors) GenerateMapNodeListCore(n, nodeList); }
internal void PrintMapGraph(MapNode current, int indent) { if (current.Scratch == 3) return; current.Scratch = 3; StringBuilder tabString = new StringBuilder(); tabString.Append('\t', indent); System.Console.Out.WriteLine(tabString + current.Type.ToString() + " " + current.UniqueID.ToString()); foreach (MapNode n in current.Neighbors) PrintMapGraph(n, indent + 1); }
internal MapNode GenerateMapGraph() { MapNode graphHead = new MapNode(MapNodeType.Entrance); Queue<MapNode> nodesToHandle = new Queue<MapNode>(); nodesToHandle.Enqueue(graphHead); while (nodesToHandle.Count > 0) { MapNode currentNode = nodesToHandle.Dequeue(); for (int i = 0; i < NumberOfNeighborsToGenerate(currentNode.Type); ++i) { MapNodeType nodeTypeToGenerate = m_stitchRatio.GetNewNode(currentNode.Type); AddNeighborsToNode(currentNode, nodeTypeToGenerate, nodesToHandle); } } ClearMapNodeScratch(graphHead); StripEmptyHallWays(graphHead); return graphHead; }
private void StripEmptyHallWays(MapNode graphHead) { bool anyRemoved; do { anyRemoved = false; List<MapNode> nodeList = GenerateMapNodeList(graphHead); foreach (MapNode n in nodeList) { if (n.Type == MapNodeType.Hall) { MapNode neightborOne = n.Neighbors[0]; MapNode neightborTwo = n.Neighbors[1]; if (neightborOne.Type == MapNodeType.None) { neightborTwo.RemoveNeighbor(n); neightborTwo.AddNeighbor(new MapNode(MapNodeType.None)); anyRemoved = true; } else if (neightborTwo.Type == MapNodeType.None) { neightborOne.RemoveNeighbor(n); neightborOne.AddNeighbor(new MapNode(MapNodeType.None)); anyRemoved = true; } } } } while (anyRemoved); }
public void ClearMapNodeScratch(MapNode graphHead) { foreach (MapNode n in GenerateMapNodeList(graphHead)) n.Scratch = 0; }
private List<MapNode> GenerateMapNodeList(MapNode headNode) { List<MapNode> nodeList = new List<MapNode>(); GenerateMapNodeListCore(headNode, nodeList); return nodeList; }
private static void AddNeighborsToNode(MapNode parent, MapNodeType type, Queue<MapNode> nodeQueue) { MapNode neightbor = new MapNode(type); parent.AddNeighbor(neightbor); neightbor.AddNeighbor(parent); nodeQueue.Enqueue(neightbor); }
private void WalkNeighbors(MapNode currentNode, MapChunk currentChunk, Map map, Point upperLeft, ParenthoodChain parentChain) { while (currentNode.Neighbors.Count > 0) { MapNode nextNode = currentNode.Neighbors[0]; nextNode.RemoveNeighbor(currentNode); currentNode.RemoveNeighbor(nextNode); Point seam = currentChunk.Seams[0]; currentChunk.Seams.Remove(seam); GenerateMapFromGraph(nextNode, map, seam + upperLeft, parentChain); } }
// Returns true if placed, false if we walled off seam private bool PlaceMapNode(MapNode current, MapChunk mapChunk, Map map, Point seam, ParenthoodChain parentChain) { Point placedUpperLeftCorner = mapChunk.PlaceChunkOnMap(map, seam, m_level); if (placedUpperLeftCorner == Point.Invalid) { map.SetTerrainAt(seam, TerrainType.Wall); return false; } else { PossiblyUpdateLargestSmallestPoint(placedUpperLeftCorner, mapChunk); map.SetTerrainAt(seam, TerrainType.Floor); parentChain.Push(mapChunk, placedUpperLeftCorner, seam); WalkNeighbors(current, mapChunk, map, placedUpperLeftCorner, parentChain); parentChain.Pop(); return true; } }
private void GenerateMapFromGraph(MapNode current, Map map, Point seam, ParenthoodChain parentChain) { if (current.Generated) return; current.Generated = true; bool placed = false; switch (current.Type) { case MapNodeType.Entrance: { placed = true; MapChunk entranceChunk = GetRandomChunkFromList(m_entrances); // We need to place entrace so it's at our expected location Point randomCenter = new Point(m_random.getInt(100, 150), m_random.getInt(100, 150)); Point entraceUpperLeftCorner = randomCenter - entranceChunk.PlayerPosition; parentChain.Push(entranceChunk, entraceUpperLeftCorner, Point.Invalid); entranceChunk.PlaceChunkOnMapAtPosition(map, entraceUpperLeftCorner, m_random); PossiblyUpdateLargestSmallestPoint(entraceUpperLeftCorner, entranceChunk); map.AddMapItem(MapObjectFactory.Instance.CreateMapObject("StairsUp", entranceChunk.PlayerPosition + entraceUpperLeftCorner)); if (current.Neighbors.Count != entranceChunk.Seams.Count) throw new InvalidOperationException("Number of neighbors should equal number of seams."); WalkNeighbors(current, entranceChunk, map, entraceUpperLeftCorner, parentChain); parentChain.Pop(); break; } case MapNodeType.Hall: { for (int i = 0; i < 10; i++) { placed = PlaceMapNode(current, GetRandomChunkFromList(m_halls), map, seam, parentChain); if (placed) break; } break; } case MapNodeType.None: { // If we have nothing, see if we have any orphan nodes to try to place if (m_unplacedDueToSpace.Count > 0) { // Grab the first unplaced node, and try again. MapNode treeToGraphOn = m_unplacedDueToSpace.Dequeue(); treeToGraphOn.Generated = false; GenerateMapFromGraph(treeToGraphOn, map, seam, parentChain); } else { map.SetTerrainAt(seam, TerrainType.Wall); if (current.Neighbors.Count != 0) throw new InvalidOperationException("None Node types should only have no neighbors"); } placed = true; break; } case MapNodeType.MainRoom: { placed = PlaceMapNode(current, GetRandomChunkFromList(m_mainRooms), map, seam, parentChain); break; } case MapNodeType.TreasureRoom: { placed = PlaceMapNode(current, GetRandomChunkFromList(m_treasureRooms), map, seam, parentChain); break; } case MapNodeType.SideRoom: { placed = PlaceMapNode(current, GetRandomChunkFromList(m_sideRooms), map, seam, parentChain); break; } case MapNodeType.NoneGivenYet: default: throw new InvalidOperationException("Trying to generate MapNode from invalid node."); } if (!placed) { UnplacePossibleHallwayToNowhere(map, parentChain); m_unplacedDueToSpace.Enqueue(current); } }
internal void RemoveNeighbor(MapNode neighbor) { Neighbors.Remove(neighbor); }
internal void AddNeighbor(MapNode neighbor) { Neighbors.Add(neighbor); }