public void SetCost(RDGGridNode node, RDGRoom roomFrom, RDGRoom roomTo, RDGGrid grid) { hueristic = Mathf.Abs(x - Mathf.CeilToInt(roomTo.center.x)) + Mathf.Abs(y - Mathf.CeilToInt(roomTo.center.y)); if ((roomFrom != null && grid[x, y] == roomFrom) || (roomTo != null && grid[x, y] == roomTo)) { cost = 0; } else if (grid[x, y] != null) { if (grid[x, y].type == RoomType.CORRIDOR) { cost = 0; } else { cost = int.MaxValue - hueristic; //Subtract the huersitic so that we don't overflow when we call fullCost } } else { cost = parent.cost + 1; if (dir != node.dir) { cost += 2; } } }
IEnumerator GenerateWalls(RDGRoom room) { for (int i = room.x - 1; i <= room.x + room.width; i++) { if (theGrid[i, room.y - 1] == null) { MakeWallAt(i, room.y - 1); theGrid[i, room.y - 1] = room; yield return(null); } if (theGrid[i, room.y + room.height] == null) { MakeWallAt(i, room.y + room.height); theGrid[i, room.y + room.height] = room; yield return(null); } } for (int i = room.y - 1; i <= room.y + room.height; i++) { if (theGrid[room.x - 1, i] == null) { MakeWallAt(room.x - 1, i); theGrid[room.x - 1, i] = room; yield return(null); } if (theGrid[room.x + room.width, i] == null) { MakeWallAt(room.x + room.width, i); theGrid[room.x + room.width, i] = room; yield return(null); } } }
List <RDGGridNode> GetNeighbors(RDGGridNode fromNode, RDGRoom roomFrom = null, RDGRoom roomTo = null) { List <RDGGridNode> neighbors = new List <RDGGridNode>(); RDGGridNode currNode; if (fromNode.x > minX) { currNode = new RDGGridNode(x: fromNode.x - 1, y: fromNode.y, dir: Direction.WEST, parent: fromNode); currNode.SetCost(fromNode, roomFrom, roomTo, this); neighbors.Add(currNode); } if (fromNode.x < maxX) { currNode = new RDGGridNode(x: fromNode.x + 1, y: fromNode.y, dir: Direction.EAST, parent: fromNode); currNode.SetCost(fromNode, roomFrom, roomTo, this); neighbors.Add(currNode); } if (fromNode.y > minY) { currNode = new RDGGridNode(x: fromNode.x, y: fromNode.y - 1, dir: Direction.SOUTH, parent: fromNode); currNode.SetCost(fromNode, roomFrom, roomTo, this); neighbors.Add(currNode); } if (fromNode.y < maxY) { currNode = new RDGGridNode(x: fromNode.x, y: fromNode.y + 1, dir: Direction.NORTH, parent: fromNode); currNode.SetCost(fromNode, roomFrom, roomTo, this); neighbors.Add(currNode); } return(neighbors); }
void MakeRoomFloor(RDGRoom room) { RDGGround ground = Instantiate(floorPrefab, room.centerV3 * squareSize, Quaternion.identity) as RDGGround; ground.Init(new Vector2(room.width, room.height)); ground.transform.parent = geometryParent; }
public void Push(RDGRoom other) { if (Mathf.Abs(center.x - other.center.x) >= Mathf.Abs(center.y - other.center.y)) { if (center.x > other.center.x) { other.x--; } else if (center.x < other.center.x) { other.x++; } } if (Mathf.Abs(center.x - other.center.x) <= Mathf.Abs(center.y - other.center.y)) { if (center.y > other.center.y) { other.y--; } else if (center.y < other.center.y) { other.y++; } } pushed = false; other.pushed = true; }
void AddRoom(RDGGridNode initialNode, RDGGridNode finalNode) { RDGRoom room = new RDGRoom(Mathf.Min(initialNode.x, finalNode.x), Mathf.Min(initialNode.y, finalNode.y), Mathf.Abs(initialNode.x - finalNode.x) + 1, Mathf.Abs(initialNode.y - finalNode.y) + 1); room.type = RoomType.CORRIDOR; theGrid.AddRoom(room); rooms.Add(room); }
public IEnumerator Pathfind(RDGRoom roomFrom, RDGRoom roomTo) { List <RDGGridNode> open = new List <RDGGridNode>(); List <RDGGridNode> closed = new List <RDGGridNode>(); RDGGridNode currNode = new RDGGridNode(x: Mathf.FloorToInt(roomFrom.center.x), y: Mathf.FloorToInt(roomFrom.center.y)); open.Add(currNode); RDGGridNode otherNode; while (open.Count > 0) { currNode = open.OrderBy(x => x.fullCost).ElementAt(0); open.Remove(currNode); //Debug.Log("Testing node: " + currNode.x + ", " + currNode.y); if (currNode.x == Mathf.FloorToInt(roomTo.center.x) && currNode.y == Mathf.FloorToInt(roomTo.center.y)) { lastPath = BuildPath(currNode); yield break; } foreach (var item in GetNeighbors(currNode, roomFrom, roomTo)) { otherNode = open.Find(n => n.x == currNode.x && n.y == currNode.y); if (otherNode != null) { if (otherNode.cost > item.cost) { open.Remove(otherNode); } else { continue; } } otherNode = closed.Find(n => n.x == currNode.x && n.y == currNode.y); if (otherNode != null) { if (otherNode.cost > item.cost) { closed.Remove(otherNode); } else { continue; } } open.Add(item); //yield return null; } closed.Add(currNode); } }
public void AddRoom(RDGRoom room) { for (int x = 0; x < room.width; x++) { for (int y = 0; y < room.height; y++) { this[room.x + x, room.y + y] = room; } } }
/// <summary> /// Creates a minimum spanning tree using the connections that this graph already has. /// </summary> /// <returns>The minimum spanning tree.</returns> public IEnumerator GenerateMinSpanTree(RDGGraph mst) { List <RDGRoom> undiscovered = new List <RDGRoom>(); foreach (var item in graph.Keys) { undiscovered.Add(item); } RDGRoom currFrom = undiscovered[0]; undiscovered.Remove(currFrom); mst.AddRoom(currFrom); RDGRoom currTo; int currMinDist; while (undiscovered.Count > 0) { //Reset vars currTo = currFrom = null; currMinDist = int.MaxValue; //Find the shortest connection to a new room //Check through every room we've discovered foreach (var discoveredRoom in mst.graph.Keys) { //Get its adjency list from the creator object foreach (var room in graph[discoveredRoom]) { //Check if undiscovered if (undiscovered.Contains(room)) { int distance = RDGMath.DistBetweenRooms(discoveredRoom, room); if (currTo == null || distance < currMinDist) { currFrom = discoveredRoom; currTo = room; currMinDist = distance; } } } } //Remove that room from undiscovered and add it to the graph undiscovered.Remove(currTo); mst.AddRoom(currTo); //Connect the room to the graph mst.AddConnection(currFrom, currTo); yield return(null); } }
/// <summary> /// Adds a direct connection between two rooms /// </summary> /// <param name="roomA">Room a.</param> /// <param name="roomB">Room b.</param> public void AddConnection(RDGRoom roomA, RDGRoom roomB) { if (!graph[roomA].Contains(roomB)) { graph[roomA].Add(roomB); } if (!graph[roomB].Contains(roomA)) { graph[roomB].Add(roomA); } }
IEnumerator AddExtraConnections() { int num = Mathf.CeilToInt((graph.connections - minGraph.connections) * percentExtras); RDGRoom roomA = null, roomB = null; for (int i = 0; i < num; i++) { do { graph.GetRandomConnection(ref roomA, ref roomB); }while(minGraph.ContainsConnection(roomA, roomB)); minGraph.AddConnection(roomA, roomB); yield return(null); } }
IEnumerator Generate() { graph = null; minGraph = null; theGrid = null; acting = true; rooms.Clear(); RDGRoom.ResetIDs(); for (int i = 0; i < numRooms; i++) { rooms.Add(MakeRoom()); yield return(null); } while (PushRoomsOut()) { yield return(null); } tris = Triangulate(); graph = new RDGGraph(rooms, tris); minGraph = new RDGGraph(); yield return(StartCoroutine(graph.GenerateMinSpanTree(minGraph))); yield return(StartCoroutine(AddExtraConnections())); BuildGrid(); yield return(StartCoroutine(BuildCorridors())); foreach (var item in rooms) { MakeRoomFloor(item); yield return(null); yield return(StartCoroutine(GenerateWalls(item))); } acting = false; }
/// <summary> /// Checks if this room overlaps another room in both the X and Y dimensions, /// which constitutes a full collision /// </summary> /// <param name="other">Other.</param> public bool Overlaps(RDGRoom other) { return(OverlapDim(x - buffer, x + width, other.x - buffer, other.x + other.width) && OverlapDim(y - buffer, y + height, other.y - buffer, other.y + other.height)); }
public void GetRandomConnection(ref RDGRoom roomA, ref RDGRoom roomB) { roomA = graph.ElementAt(UnityEngine.Random.Range(0, graph.Count)).Key; roomB = graph[roomA].ElementAt(UnityEngine.Random.Range(0, graph[roomA].Count)); }
public bool ContainsConnection(RDGRoom roomA, RDGRoom roomB) { return(graph[roomA].Contains(roomB)); }
/// <summary> /// Gets the manhattan distance between two rooms /// </summary> /// <returns>The between rooms.</returns> /// <param name="roomA">Room a.</param> /// <param name="roomB">Room b.</param> public static int DistBetweenRooms(RDGRoom roomA, RDGRoom roomB) { return((int)(Mathf.Abs(roomA.center.x - roomB.center.x) + Mathf.Abs(roomA.center.y - roomB.center.y))); }
/// <summary> /// Adds a room to this graph /// </summary> /// <param name="room">Room.</param> void AddRoom(RDGRoom room) { graph.Add(room, new List <RDGRoom>()); }