// assumes origRoom is already in rooms public bool Add(RCObj origRoom, int origConnectionIndex, RCObj newRoom, int newConnectionIndex) { if (!rooms.Contains(origRoom) || !origRoom.connections[origConnectionIndex].isAvailable || !newRoom.connections[newConnectionIndex].isAvailable) { Debug.LogWarning("Something went wrong when adding a room to composite!"); } Direction dirOut = origRoom.connections[origConnectionIndex].side; Vector3Int nearestPos = origRoom.pos + origRoom.connections[origConnectionIndex].pos - newRoom.connections[newConnectionIndex].pos + MIN_HALLWAY * DirectionUtil.Convert(dirOut); HallwayObj hallway = new HallwayObj(origRoom, newRoom, origRoom.connections[origConnectionIndex], newRoom.connections[newConnectionIndex], true); for (int i = 0; i < MAX_HALLWAY; i++) { if (Constants.doRandom) { if (Random.Range(0, 1f) < 0.3f) { continue; } } newRoom.pos = nearestPos + (i * DirectionUtil.Convert(dirOut)); if (CanAddRoom(newRoom)) { if (TryGenerateSimpleHallway(hallway)) { hallway.roomA.connectedObjects.Add(hallway.roomB); hallway.roomB.connectedObjects.Add(hallway.roomA); rooms.Add(newRoom); origRoom.connections[origConnectionIndex].isAvailable = false; newRoom.connections[newConnectionIndex].isAvailable = false; AddRoomToGrid(newRoom); AddHalwayToGrid(hallway); UpdateDoorAvailability(); return(true); } } } return(false); }
private void PlaceHallway(HallwayObj hallway, Vector3Int offset) { foreach (Vector3Int p in hallway.path) { PlaceHallwayWalls(offset + p); } foreach (Vector3Int p in hallway.path) { for (int r = -1; r <= 1; r++) { for (int c = -1; c <= 1; c++) { ClearWallAddFloor(offset + p + new Vector3Int(c, r, 0)); } } } }
public bool TryGenerateComplexHallway(RCObj RCA, RCObj RCB) { int[] lastRoomInds = RCB.GetClosestConnections(RCA, 2); int[] firstRoomInds = RCA.GetClosestConnections(RCB, 2); if (lastRoomInds[0] == -1 || firstRoomInds[0] == -1) // no available connections, restart composite { return(false); } for (int lastInd = 0; lastInd < 2; lastInd++) { if (lastRoomInds[lastInd] == -1) { continue; } for (int firstInd = 0; firstInd < 2; firstInd++) { if (firstRoomInds[firstInd] == -1) { continue; } HallwayObj complexHallway = new HallwayObj(RCA, RCB, RCA.connections[firstRoomInds[firstInd]], RCB.connections[lastRoomInds[lastInd]], false); if (TryGenerateComplexHallwayHelper(complexHallway)) { AddHalwayToGrid(complexHallway); complexHallway.connectionA.isAvailable = false; complexHallway.connectionB.isAvailable = false; UpdateDoorAvailability(); RCA.connectedObjects.Add(RCB); RCB.connectedObjects.Add(RCA); return(true); } } } return(false); }
private bool TryGenerateSimpleHallway(HallwayObj hallway) { Vector3Int start = basePos + hallway.roomA.pos + hallway.connectionA.pos; Vector3Int end = basePos + hallway.roomB.pos + hallway.connectionB.pos; if (start.x != end.x && start.y != end.y) { Debug.LogWarning("Simple hallway couldn't be made because points aren't in a line!"); return(false); } List <Vector3Int> path = new List <Vector3Int>(); Vector3Int dir = DirectionUtil.Convert(hallway.connectionA.side); Vector3Int pos = start + dir; Vector3Int posP = pos + DirectionUtil.Convert(DirectionUtil.PrevDir(hallway.connectionA.side)); Vector3Int posN = pos + DirectionUtil.Convert(DirectionUtil.NextDir(hallway.connectionA.side)); int lim = 0; while (pos != end && lim < SIMPLE_HALLWAY_LIMIT) { if (grid[MID + pos.x, MID + pos.y] || grid[MID + posP.x, MID + posP.y] || grid[MID + posN.x, MID + posN.y]) { return(false); } path.Add(pos - basePos); pos += dir; posP += dir; posN += dir; lim += 1; } if (lim >= SIMPLE_HALLWAY_LIMIT) { Debug.LogWarning("Exceeded limit on simple path gen!"); return(false); } hallway.path = path; return(true); }
private void AddHalwayToGrid(HallwayObj hallway) { hallways.Add(hallway); for (int i = 1; i < hallway.path.Count - 1; i++) { Vector3Int pos = hallway.path[i] + basePos + new Vector3Int(MID, MID, 0); for (int x = -2; x <= 2; x++) { for (int y = -2; y <= 2; y++) { grid[pos.x + x, pos.y + y] = true; } } } // need to check more than just one spot foreach (Vector3Int p in hallway.path) { grid[MID + basePos.x + p.x, MID + basePos.y + p.y] = true; } }
private bool TryGenerateComplexHallwayHelper(HallwayObj hallway) { Vector3Int rawStart = basePos + hallway.roomA.pos + hallway.connectionA.pos; Vector3Int rawEnd = basePos + hallway.roomB.pos + hallway.connectionB.pos; Direction startDir = hallway.connectionA.side; Direction endDir = hallway.connectionB.side; Vector3Int start = rawStart + DirectionUtil.Convert(startDir); Vector3Int end = rawEnd + DirectionUtil.Convert(endDir); List <Vector3Int> path = new List <Vector3Int>(); int lim = 0; // nodes expanded // pos, dir Queue <System.Tuple <Vector3Int, Direction> > frontier = new Queue <System.Tuple <Vector3Int, Direction> >(); Dictionary <Vector3Int, Vector3Int> child2parent = new Dictionary <Vector3Int, Vector3Int>(); frontier.Enqueue(new System.Tuple <Vector3Int, Direction>(start, startDir)); child2parent[start] = start; bool foundPath = false; // BFS -- add direction first // note: this should be an A* search but i don't want to implement a priority queue while (frontier.Count > 0 && lim < COMPLEX_HALLWAY_LIMIT) { System.Tuple <Vector3Int, Direction> node = frontier.Dequeue(); Vector3Int pos = node.Item1; Direction dir = node.Item2; lim += 1; // go through neighbors in order of: dir => dir + 1 => dir - 1 // check // not in dictionary // is legal spot (check new tiles on grid) // if (grid[MID + pos.x, MID + pos.y]) Direction nextDir = dir; if (ComplexHallwayHelperHelper(pos, nextDir, end, child2parent, frontier)) { foundPath = true; break; } nextDir = DirectionUtil.NextDir(dir); if (ComplexHallwayHelperHelper(pos, nextDir, end, child2parent, frontier)) { foundPath = true; break; } nextDir = DirectionUtil.PrevDir(dir); if (ComplexHallwayHelperHelper(pos, nextDir, end, child2parent, frontier)) { foundPath = true; break; } } //if (lim >= COMPLEX_HALLWAY_LIMIT) // Debug.LogWarning("Exceeded limit on complex path gen!"); if (!foundPath) { return(false); } //Debug.Log("Succeeded in generating complex hallway!"); Vector3Int p = end; path.Add(p - basePos); while (p != start) { p = child2parent[p]; path.Add(p - basePos); } hallway.path = path; return(true); }