public ProtoRegion(int id, ProtoRoom[,] MasterRoomList, REGION_TYPE regionType = REGION_TYPE.OVERGROUND) { ID = id; Name = Statics.RandomRegionName(); if (regionType == REGION_TYPE.OVERGROUND) { Color = Statics.RandomColor(); } else if (regionType == REGION_TYPE.UNDERGROUND) { Color = Statics.RandomCaveColor(); } // initialize with a single subregion ProtoSubregions.Add(new ProtoSubregion(0, this, MasterRoomList)); }
public ProtoSubregion(int id, ProtoRegion region, ProtoRoom[,] MasterRoomList) { ID = id; ProtoRegion = region; Color = region.Color; Name = Statics.RandomRegionType(); int RoomCountX = MasterRoomList.GetLength(0); int RoomCountY = MasterRoomList.GetLength(1); // keep track of available adjacent roomss // list for random access; hashset for lookup by coordinates List<ProtoRoom> AvailableAdjacentRooms = new List<ProtoRoom>(); HashSet<PointInt> AvailableAdjacentCoordinates = new HashSet<PointInt>(); // grab random point as starting room int x = Statics.Random.Next(RoomCountX); int y = Statics.Random.Next(RoomCountY); while (!MasterRoomList[x, y].Available) { x = Statics.Random.Next(RoomCountX); y = Statics.Random.Next(RoomCountY); } // create starting room ProtoRoom startingRoom = MasterRoomList[x, y]; ProtoRooms.Add(startingRoom); startingRoom.Available = false; startingRoom.ProtoRegion = region; startingRoom.ProtoSubregion = this; UpdateAdjacentRooms(AvailableAdjacentRooms, AvailableAdjacentCoordinates, startingRoom, MasterRoomList); while (AvailableAdjacentRooms.Count > 0 && ((ProtoRooms.Count < Statics.MinimumRegionSize) || (Statics.Random.Next(100) < Statics.ProbabilityOfExpansion))) { // pick a random room from available neighbor set ProtoRoom randomNeighbor = AvailableAdjacentRooms.RandomListItem(); randomNeighbor.Available = false; randomNeighbor.ProtoRegion = region; randomNeighbor.ProtoSubregion = this; AvailableAdjacentRooms.Remove(randomNeighbor); AvailableAdjacentCoordinates.Remove(randomNeighbor.CoordinatesXY); ProtoRooms.Add(randomNeighbor); // add new room's available neighbors to the available set UpdateAdjacentRooms(AvailableAdjacentRooms, AvailableAdjacentCoordinates, randomNeighbor, MasterRoomList); } }
public static Room FromProtoRoom(Region region, Subregion subregion, ProtoRoom pr) { Room room = new Room(); room.ID = pr.ID; room._coordinatesXY = pr.CoordinatesXY; room._region = region; room._subregion = subregion; // sort room connections List<KeyValuePair<string, Tuple<int, int, int>>> DirectionalRoomConnectionsList = pr.DirectionalRoomConnections.ToList(); DirectionalRoomConnectionsList.Sort((x, y) => Statics.SortRoomConnections(x.Key, y.Key)); Dictionary<string, Tuple<int, int, int>> DirectionalRoomConnectionsDictionary = DirectionalRoomConnectionsList.ToDictionary((x) => x.Key, (x) => x.Value); room.DirectionalRoomConnections = new ReadOnlyDictionary<string, Tuple<int, int, int>>(DirectionalRoomConnectionsDictionary); room.RoomConnections = new ReadOnlyCollection<RoomConnection>(pr.ProtoRoomConnections); room._elevation = pr.Elevation; room._elevationcolor = pr.ElevationColor; return room; }
private void UpdateAdjacentRooms(List<ProtoRoom> AvailableAdjacentRooms, HashSet<PointInt> AvailableAdjacentCoordinates, ProtoRoom protoRoom, ProtoRoom[,] MasterRoomList) { // left if (protoRoom.CoordinatesXY.X > 0) { ProtoRoom neighborLeft = MasterRoomList[protoRoom.CoordinatesXY.X - 1, protoRoom.CoordinatesXY.Y]; if (neighborLeft.Available && !AvailableAdjacentCoordinates.Contains(neighborLeft.CoordinatesXY)) { AvailableAdjacentRooms.Add(neighborLeft); AvailableAdjacentCoordinates.Add(neighborLeft.CoordinatesXY); } } // right if (protoRoom.CoordinatesXY.X < MasterRoomList.GetLength(0) - 1) { ProtoRoom neighborRight = MasterRoomList[protoRoom.CoordinatesXY.X + 1, protoRoom.CoordinatesXY.Y]; if (neighborRight.Available && !AvailableAdjacentCoordinates.Contains(neighborRight.CoordinatesXY)) { AvailableAdjacentRooms.Add(neighborRight); AvailableAdjacentCoordinates.Add(neighborRight.CoordinatesXY); } } // above if (protoRoom.CoordinatesXY.Y > 0) { ProtoRoom neighborAbove = MasterRoomList[protoRoom.CoordinatesXY.X, protoRoom.CoordinatesXY.Y - 1]; if (neighborAbove.Available && !AvailableAdjacentCoordinates.Contains(neighborAbove.CoordinatesXY)) { AvailableAdjacentRooms.Add(neighborAbove); AvailableAdjacentCoordinates.Add(neighborAbove.CoordinatesXY); } } // below if (protoRoom.CoordinatesXY.Y < MasterRoomList.GetLength(1) - 1) { ProtoRoom neighborBelow = MasterRoomList[protoRoom.CoordinatesXY.X, protoRoom.CoordinatesXY.Y + 1]; if (neighborBelow.Available && !AvailableAdjacentCoordinates.Contains(neighborBelow.CoordinatesXY)) { AvailableAdjacentRooms.Add(neighborBelow); AvailableAdjacentCoordinates.Add(neighborBelow.CoordinatesXY); } } }
private bool HasAvailableNeighboringRoom(ProtoRoom[,] MasterRoomList) { int RoomCountX = MasterRoomList.GetLength(0); int RoomCountY = MasterRoomList.GetLength(1); foreach (ProtoRoom room in ProtoRooms) { // check left if (room.CoordinatesXY.X > 0 && MasterRoomList[(int)room.CoordinatesXY.X - 1, (int)room.CoordinatesXY.Y].Available) { return true; } // check right if (room.CoordinatesXY.X < RoomCountX - 1 && MasterRoomList[(int)room.CoordinatesXY.X + 1, (int)room.CoordinatesXY.Y].Available) { return true; } // check up if (room.CoordinatesXY.Y > 0 && MasterRoomList[(int)room.CoordinatesXY.X, (int)room.CoordinatesXY.Y - 1].Available) { return true; } // check down if (room.CoordinatesXY.Y < RoomCountY - 1 && MasterRoomList[(int)room.CoordinatesXY.X, (int)room.CoordinatesXY.Y + 1].Available) { return true; } } return false; }
private void InitializeMasterRoomLists() { // initialize master array of tiles MasterOvergroundRoomList = new ProtoRoom[Width, Height]; MasterUndergroundRoomList = new ProtoRoom[Width, Height]; for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { MasterOvergroundRoomList[x, y] = new ProtoRoom(-1, new PointInt(x, y)); MasterUndergroundRoomList[x, y] = new ProtoRoom(-1, new PointInt(x, y)); } } }
private void DrawPaths(CanvasDrawingSession ds, ProtoRoom[,] roomList, int x, int y, Color color) { float fStrokeWidth = 5; foreach (string DirectionalRoomConnection in roomList[x, y].DirectionalRoomConnections.Keys) { switch (DirectionalRoomConnection) { case "nw": ds.DrawLine((x + 0.5f) * Statics.MapResolution, (y + 0.5f) * Statics.MapResolution, ((x - 1) + 0.5f) * Statics.MapResolution, ((y - 1) + 0.5f) * Statics.MapResolution, color, fStrokeWidth); break; case "n": ds.DrawLine((x + 0.5f) * Statics.MapResolution, (y + 0.5f) * Statics.MapResolution, (x + 0.5f) * Statics.MapResolution, ((y - 1) + 0.5f) * Statics.MapResolution, color, fStrokeWidth); break; case "ne": ds.DrawLine((x + 0.5f) * Statics.MapResolution, (y + 0.5f) * Statics.MapResolution, ((x + 1) + 0.5f) * Statics.MapResolution, ((y - 1) + 0.5f) * Statics.MapResolution, color, fStrokeWidth); break; case "w": ds.DrawLine((x + 0.5f) * Statics.MapResolution, (y + 0.5f) * Statics.MapResolution, ((x - 1) + 0.5f) * Statics.MapResolution, (y + 0.5f) * Statics.MapResolution, color, fStrokeWidth); break; case "o": break; case "e": ds.DrawLine((x + 0.5f) * Statics.MapResolution, (y + 0.5f) * Statics.MapResolution, ((x + 1) + 0.5f) * Statics.MapResolution, (y + 0.5f) * Statics.MapResolution, color, fStrokeWidth); break; case "sw": ds.DrawLine((x + 0.5f) * Statics.MapResolution, (y + 0.5f) * Statics.MapResolution, ((x - 1) + 0.5f) * Statics.MapResolution, ((y + 1) + 0.5f) * Statics.MapResolution, color, fStrokeWidth); break; case "s": ds.DrawLine((x + 0.5f) * Statics.MapResolution, (y + 0.5f) * Statics.MapResolution, (x + 0.5f) * Statics.MapResolution, ((y + 1) + 0.5f) * Statics.MapResolution, color, fStrokeWidth); break; case "se": ds.DrawLine((x + 0.5f) * Statics.MapResolution, (y + 0.5f) * Statics.MapResolution, ((x + 1) + 0.5f) * Statics.MapResolution, ((y + 1) + 0.5f) * Statics.MapResolution, color, fStrokeWidth); break; default: throw new Exception(); } } }
private ProtoRoom AddRoomConnection(ProtoRoom currentRoom, string strDirection, ProtoRoom[,] masterRoomList, bool bForce = false) { Tuple<int, int, int> connectionWorldCoordinates; if (currentRoom.DirectionalRoomConnections.TryGetValue(strDirection, out connectionWorldCoordinates)) { return currentRoom; } string strOppositeDirection = string.Empty; PointInt connectingRoomCoordinates = null; switch (strDirection) { case "nw": strOppositeDirection = "se"; connectingRoomCoordinates = new PointInt(currentRoom.CoordinatesXY.X - 1, currentRoom.CoordinatesXY.Y - 1); break; case "n": strOppositeDirection = "s"; connectingRoomCoordinates = new PointInt(currentRoom.CoordinatesXY.X, currentRoom.CoordinatesXY.Y - 1); break; case "ne": strOppositeDirection = "sw"; connectingRoomCoordinates = new PointInt(currentRoom.CoordinatesXY.X + 1, currentRoom.CoordinatesXY.Y - 1); break; case "w": strOppositeDirection = "e"; connectingRoomCoordinates = new PointInt(currentRoom.CoordinatesXY.X - 1, currentRoom.CoordinatesXY.Y); break; case "e": strOppositeDirection = "w"; connectingRoomCoordinates = new PointInt(currentRoom.CoordinatesXY.X + 1, currentRoom.CoordinatesXY.Y); break; case "sw": strOppositeDirection = "ne"; connectingRoomCoordinates = new PointInt(currentRoom.CoordinatesXY.X - 1, currentRoom.CoordinatesXY.Y + 1); break; case "s": strOppositeDirection = "n"; connectingRoomCoordinates = new PointInt(currentRoom.CoordinatesXY.X, currentRoom.CoordinatesXY.Y + 1); break; case "se": strOppositeDirection = "nw"; connectingRoomCoordinates = new PointInt(currentRoom.CoordinatesXY.X + 1, currentRoom.CoordinatesXY.Y + 1); break; default: throw new Exception(); } if (connectingRoomCoordinates.X < 0) { return currentRoom; } if (connectingRoomCoordinates.X > Width - 1) { return currentRoom; } if (connectingRoomCoordinates.Y < 0) { return currentRoom; } if (connectingRoomCoordinates.Y > Height - 1) { return currentRoom; } ProtoRoom connectingRoom = masterRoomList[connectingRoomCoordinates.X, connectingRoomCoordinates.Y]; if (connectingRoom.Elevation == 0 || connectingRoom.Elevation == 30) { return currentRoom; } if (connectingRoom.HasMaximumConnections && !bForce) { return currentRoom; } Debug.TotalConnectionCount++; currentRoom.DirectionalRoomConnections.Add(strDirection, connectingRoom.WorldCoordinatesAsTuple); connectingRoom.DirectionalRoomConnections.Add(strOppositeDirection, currentRoom.WorldCoordinatesAsTuple); return connectingRoom; }
private void MergeRegions(ProtoRoom[,] MasterRoomList, int nMinimumSize, bool bAddAsSubregions) { for (int i = ProtoRegions.Count - 1; i >= 0; i--) { if (ProtoRegions[i].RoomCount <= nMinimumSize) { // pick random tile and check neighboring tiles for a new region int nMergeRegion = RandomNeighbor(i).ID; // fold ProtoRegions[i] into ProtoRegions[nMergeRegion] MergeRegions(nMergeRegion, i, bAddAsSubregions); // reindex regions, starting at the index where we removed the last one // NOTE: huge savings over reindexing everything every time ReindexRegions(i); } } }