// we can't draw a straight corridor so let's do an L shape public void connectWith_L_ShapedHall(Node currentNode, int[][] dungeon) { int meetX, meetY; Node tempL, tempR; bool isRight; // L R L R // R L R L // T= FS F= TS if (currentNode.leftChild.roomRect.Left < currentNode.rightChild.roomRect.Left) { if (currentNode.leftChild.roomRect.Top < currentNode.rightChild.roomRect.Top) { isRight = true; // L above and left R tempL = currentNode.leftChild; tempR = currentNode.rightChild; } else { isRight = false; // L below and left R tempL = currentNode.rightChild; tempR = currentNode.leftChild; } } else { if (currentNode.leftChild.roomRect.Top < currentNode.rightChild.roomRect.Top) { isRight = false; // L above and right R tempL = currentNode.leftChild; tempR = currentNode.rightChild; } else { isRight = true; // L below and right R tempL = currentNode.rightChild; tempR = currentNode.leftChild; } } if (currentNode.split_dir == "vert") // down { if (!isRight) { // up and left // _____ // | | // | L | // |___| // _____ | // | | | // | R |___|X // |___| meetX = Meta.random.Next(Math.Max(tempR.roomRect.Right + 1, tempL.roomRect.Left), tempL.roomRect.Right); meetY = Meta.random.Next(Math.Max(tempL.roomRect.Bottom + 1, tempR.roomRect.Top + 1), tempR.roomRect.Bottom); dungeon[meetX][meetY] = 1; // go up int a = 1; bool hit = false; while (!hit) { if (dungeon[meetX][meetY - a] != 1) { dungeon[meetX][meetY - a] = 1; a++; } else hit = true; } // go left a = 1; hit = false; while (!hit) { if (dungeon[meetX - a][meetY] != 1) { dungeon[meetX - a][meetY] = 1; a++; } else hit = true; } } else { // up and right // _____ // | | // | L | // |___| // | _____ // | | | // X|____| R | // |___| meetX = Meta.random.Next(tempL.roomRect.Left + 1, Math.Min(tempL.roomRect.Right, tempR.roomRect.Left - 1)); meetY = Meta.random.Next(Math.Max(tempL.roomRect.Bottom + 1, tempR.roomRect.Top + 1), tempR.roomRect.Bottom); dungeon[meetX][meetY] = 1; // go up int a = 1; bool hit = false; while (!hit) { if (dungeon[meetX][meetY - a] != 1) { dungeon[meetX][meetY - a] = 1; a++; } else hit = true; } // go right a = 1; hit = false; while (!hit) { if (dungeon[meetX + a][meetY] != 1) { dungeon[meetX + a][meetY] = 1; a++; } else hit = true; } } } else // up { if (!isRight) { // down and right // _____ // X____| | // | | L | // | |___| // __|__ // | | // | R | // |___| meetX = Meta.random.Next(tempR.roomRect.Left + 1, Math.Min(tempR.roomRect.Right - 1, tempL.roomRect.Left)); meetY = Meta.random.Next(tempL.roomRect.Top + 1, tempL.roomRect.Bottom); dungeon[meetX][meetY] = 1; // go down int a = 1; bool hit = false; while (!hit) { if (dungeon[meetX][meetY + a] != 1) { dungeon[meetX][meetY + a] = 1; a++; } else hit = true; } // go right a = 1; hit = false; while (!hit) { if (dungeon[meetX + a][meetY] != 1) { dungeon[meetX + a][meetY] = 1; a++; } else hit = true; } } else { // down and left // _____ // | |____X // | L | | // |___| | // __|__ // | | // | R | // |___| meetX = Meta.random.Next(tempR.roomRect.Left + 1, tempR.roomRect.Right); meetY = Meta.random.Next(tempL.roomRect.Top + 1, Math.Min(tempL.roomRect.Bottom - 1, tempR.roomRect.Top)); dungeon[meetX][meetY] = 1; // go down int a = 1; bool hit = false; while (!hit) { if (dungeon[meetX][meetY + a] != 1) { dungeon[meetX][meetY + a] = 1; a++; } else hit = true; } // go left a = 1; hit = false; while (!hit) { if (dungeon[meetX - a][meetY] != 1) { dungeon[meetX - a][meetY] = 1; a++; } else hit = true; } } } }
public void split(int[][] dungeon) { // try to favor one way if ratio is way out of whack if (Rect.Width / Rect.Height > max_partition_ratio) { split_dir = "vert"; } else if (Rect.Height / Rect.Width > max_partition_ratio) { split_dir = "horiz"; } else split_dir = (Meta.random.Next(2) == 1) ? "vert" : "horiz"; // split the node if (split_dir == "vert") { // get split position splitPos = Rect.Left + (int)(HomogenizedRandomValue() * Rect.Width); // create kiddos leftChild = new Node(Rect.Left, Rect.Top, splitPos - Rect.Left, Rect.Height); rightChild = new Node(splitPos + 1, Rect.Top, Rect.Left + Rect.Width - splitPos - 1, Rect.Height); // if not too small, split if (leftChild.shouldSplit(leftChild.Rect.Width)) leftChild.split(dungeon); if (rightChild.shouldSplit(rightChild.Rect.Width)) rightChild.split(dungeon); } else // horiz split { splitPos = Rect.Top + (int)(HomogenizedRandomValue() * Rect.Height); leftChild = new Node(Rect.Left, Rect.Top, Rect.Width, splitPos - Rect.Top); rightChild = new Node(Rect.Left, splitPos + 1, Rect.Width, Rect.Top + Rect.Height - splitPos - 1); if (leftChild.shouldSplit(leftChild.Rect.Height)) leftChild.split(dungeon); if (rightChild.shouldSplit(rightChild.Rect.Height)) rightChild.split(dungeon); } }
public int[][] createDungeon() { torchList = new List<Entity>(); roomList = new List<Rectangle>(); manager = new EntityManager(); // initialize size of dungeon array and sets everything to unvisited (0) floor = new int[dwidth][]; for (int a = 0; a < floor.Length; a++) { floor[a] = new int[dheight]; } for (int x = 0; x < floor.Length; x++) { for (int y = 0; y < floor[x].Length; y++) { floor[x][y] = 0; } } // start with single node then recursively split into areas until done Node wholeDungeon = new Node(1, 1, dwidth - 2, dheight - 2); wholeDungeon.split(floor); // now add rooms roomList = wholeDungeon.addRooms(floor); // now connect the rooms wholeDungeon.connectRooms(floor); // now draw walls paintWalls(); // now add doors addDoors(); // now add torches addTorches(); // now add stairs up and down addStairs(); // add mobs addMobs(); return floor; }