private void TryLinkRooms() { var xdoor = 0; var ydoor = 0; var MaxAttempts = numberRooms * 20; while (!cancellinking) { cancelcounter++; var corridor = FindUnusedDoorinRandomRoom(ref xdoor, ref ydoor); if (corridor != null) { starterRoom = corridor.StartRoom; if (corridor.GrowCorridor(ref xdoor, ref ydoor)) { return; } } if (cancelcounter > MaxAttempts) { cancellinking = true; } } }
// try to grow corridor public bool GrowCorridor(ref int xdoor, ref int ydoor) { var done = false; var x = xdoor; var y = ydoor; var seglen = Atts.R.Next(4) + 3; var iDir = PickDirection(x, y); if (iDir == -1) { return(false); } var xOffset = Atts.OffSetDirX[iDir]; var yOffset = Atts.OffSetDirY[iDir]; while (!done) { x += xOffset; y += yOffset; if (!Atts.IsOnMap(x, y)) { RemoveFailedCorridor(xdoor, ydoor); return(false); } var locType = cmap[x, y].LocationType; if (locType == Atts.LocationType.Empty) { cmap[x, y].LocationType = Atts.LocationType.TempCorridor; if (seglen > 0) { seglen--; } else if (cmap[x, y].GridLine) // Only change direction where { iDir = NewDirection(iDir); xOffset = Atts.OffSetDirX[iDir]; yOffset = Atts.OffSetDirY[iDir]; seglen = Atts.R.Next(4) + 3; } continue; } // hit something - door or Corridor if (locType == Atts.LocationType.Corridor) { var metCorridor = cmap[x, y].Corridor; if (IsNewCorridor(metCorridor)) { MeetANewCorridor(metCorridor); done = true; } else { RemoveFailedCorridor(xdoor, ydoor); return(false); } } if (locType == Atts.LocationType.DoorPoint) { var room = cmap[x, y].aRoom; if (!room.IsSameRoom(StartRoom) && !room.ConnectedRooms.Contains(StartRoom) && room.HasSpareExit()) { EndRoom = room; room.AddExit(this, Atts.FromDir[iDir]); LinkTwoRooms(room, StartRoom); done = true; } else { RemoveFailedCorridor(xdoor, ydoor); return(false); } } /* if (locType == Atts.LocationType.WallPoint) * { * RemoveFailedCorridor(xdoor, ydoor); * return false; * }*/ } // Finalize the TempDoors and TempCorridors if (cmap[xdoor, ydoor].LocationType == Atts.LocationType.TempDoor) { cmap[xdoor, ydoor].LocationType = Atts.LocationType.DoorPoint; } for (var yp = 0; yp < Atts.MaxLocsY; yp++) { for (var xp = 0; xp < Atts.MaxLocsX; xp++) { if (Atts.IsOnMap(xp, yp) && cmap[xp, yp].LocationType == Atts.LocationType.TempCorridor) { cmap[xp, yp].LocationType = Atts.LocationType.Corridor; cmap[xp, yp].Corridor = this; } } } return(true); }
// Height comparison is also done because Top, Left for a rectangular room is different to Top,Left for a circular room // Circular rooms have height 0. public bool IsSameRoom(DungeonRoom other) { return(Top == other.Top && Left == other.Left && Height == other.Height); }
private void LinkTwoRooms(DungeonRoom room1, DungeonRoom room2) { room1.ConnectedRooms.UnionWith(room2.ConnectedRooms); room2.ConnectedRooms.UnionWith(room1.ConnectedRooms); }