private bool TryCombiningRooms(RoomComposite composite, RCObj RCOrig, RCObj RCNew, int[] indsOrig) { foreach (int indA in indsOrig) { Direction dirA = RCOrig.connections[indA].side; Direction dirN = (Direction)(((int)dirA + 2) % 4); int[] indsN = RCNew.GetRandomConnections(dirN); foreach (int indN in indsN) { if (indA == -1 || indN == -1) // should be unneccesary { continue; } bool didAdd = composite.Add(RCOrig, indA, RCNew, indN); if (didAdd) { return(true); } } } return(false); }
private bool AddRoomRandom(RoomComposite composite, RCObj RCOrig, FlowNode nodeNew) { RoomData roomNew; RCObj RCNew; // try adding first 2 rooms together for (int i = 0; i < MAX_TRIES; i++) { roomNew = GetRoom(nodeNew); RCNew = new RCObj(roomNew); bool didAdd = TryCombiningRooms(composite, RCOrig, RCNew, RCOrig.GetAvailableConnections()); if (didAdd) { if (!AddNode(nodeNew, RCNew)) { return(false); // couldn't generate complex hallway } return(true); } } return(false); }
private bool CheckOverlappingCyclesHelper(List <List <FlowNode> > cycles, out bool properlyGenerated) { properlyGenerated = true; foreach (List <FlowNode> cycle in cycles) { if (DoesCycleContain(addedCycles, cycle)) { continue; } foreach (FlowNode currentNode in addedNodes.Keys) { if (cycle.Contains(currentNode)) { while (cycle[0] != currentNode) // cycle until currentNode is in the front { cycle.Add(cycle[0]); cycle.RemoveAt(0); } RoomComposite rc = AddCycleToComposite(dungeonComposite, addedNodes[currentNode], cycle); if (rc == null) { properlyGenerated = false; return(false); } else { addedCycles.Add(cycle); properlyGenerated = true; return(true); } } } } return(false); }
private bool TryGenerating(List <List <FlowNode> > cycles) { addedCycles = new List <List <FlowNode> >(); addedNodes = new Dictionary <FlowNode, RCObj>(); remainingNodes = new List <FlowNode>(); foreach (FlowNode node in currentFlow.verticies) { remainingNodes.Add(node.Copy()); } dungeonComposite = null; bool didGen = true; if (cycles.Count > 0) { // TODO: progress cycle a random amount if (Constants.doRandom) { int n = Random.Range(0, cycles.Count); for (int i = 0; i < n; i++) { cycles[0].Add(cycles[0][0]); } cycles[0].RemoveRange(0, n); } FlowNode nodeInit = cycles[0][0]; RoomData roomInit = GetRoom(nodeInit); RCObj RCInit = new RCObj(roomInit); dungeonComposite = new RoomComposite(RCInit); AddNode(nodeInit, RCInit); dungeonComposite = AddCycleToComposite(dungeonComposite, RCInit, cycles[0]); if (dungeonComposite == null) { return(false); } addedCycles.Add(cycles[0]); didGen = CheckOverlappingCycles(cycles); if (!didGen) { return(false); } } else { FlowNode maxNode = remainingNodes[0]; foreach (FlowNode node in remainingNodes) { if (node.neighbors.Count > maxNode.neighbors.Count) { maxNode = node; } } RoomData roomInit = GetRoom(maxNode); RCObj RCInit = new RCObj(roomInit); dungeonComposite = new RoomComposite(RCInit); didGen = AddNode(maxNode, RCInit); if (!didGen) { return(false); } } //Debug.Log(remainingNodes.Count + " remaining!"); int limitCount = 0; while (remainingNodes.Count > 0 && limitCount < 1000000) { limitCount++; List <FlowNode> frontierNodes = new List <FlowNode>(); foreach (FlowNode node in addedNodes.Keys) { foreach (FlowNode adj in node.neighbors) { if (remainingNodes.Contains(adj)) { frontierNodes.Add(adj); } } } FlowNode maxNode = remainingNodes[0]; foreach (FlowNode node in frontierNodes) { if (node.neighbors.Count > maxNode.neighbors.Count) { maxNode = node; } } FlowNode origNode = null; foreach (FlowNode node in addedNodes.Keys) { if (node.neighbors.Contains(maxNode)) { origNode = node; } } didGen = AddRoomRandom(dungeonComposite, addedNodes[origNode], maxNode); if (!didGen) { return(false); } if (addedCycles.Count < cycles.Count) { didGen = CheckOverlappingCycles(cycles); if (!didGen) { return(false); } } } if (dungeonComposite == null || limitCount > 1000000) { return(false); } return(true); }
private RoomComposite AddCycleToComposite(RoomComposite composite, RCObj RCA, List <FlowNode> cycle) { FlowNode nodeN = cycle[1]; RoomData roomN = null; RCObj RCN = null; bool didAdd = false; if (!addedNodes.ContainsKey(cycle[1])) { // try adding first 2 rooms together for (int i = 0; i < MAX_TRIES; i++) { roomN = GetRoom(nodeN); RCN = new RCObj(roomN); didAdd = TryCombiningRooms(composite, RCA, RCN, RCA.GetAvailableConnections()); if (didAdd) { if (!AddNode(nodeN, RCN)) { return(null); // couldn't generate complex hallway } break; } } // failed to place first two rooms if (!didAdd) { return(null); } } else { RCN = addedNodes[nodeN]; } // place rest of rooms for (int n = 2; n < cycle.Count; n++) { didAdd = false; FlowNode nodeM = cycle[n]; if (!addedNodes.ContainsKey(nodeM)) { int[] indsN; // get furthest dir if (n < (cycle.Count + 1) / 2) { indsN = RCN.GetFurthestConnection(RCA, 3); } else // get closest dir { indsN = RCN.GetClosestConnections(RCA, 3); } if (indsN[0] == -1) { continue; } for (int i = 0; i < MAX_TRIES; i++) { RoomData roomM = GetRoom(nodeM); RCObj RCM = new RCObj(roomM); didAdd = TryCombiningRooms(composite, RCN, RCM, indsN); if (didAdd) { if (!AddNode(nodeM, RCM)) { return(null); // couldn't generate complex hallway } RCN = RCM; break; } } if (!didAdd) { return(null); // restart composite } } else { // already added RCN = addedNodes[nodeM]; } } //if (!composite.TryGenerateComplexHallway(RCN, RCA)) // return null; // couldnt do the last hallway :( // succeeded //Debug.Log("Rooms added successfully!"); return(composite); }
public void PlaceComposite(RoomComposite composite, int x, int y, GameObject dungeonContainer = null) { if (dungeonContainer == null) { dungeonContainer = GameObject.Find("DungeonContainer"); // maybe do a new GameObject() here } Awake(); // delete later Vector3Int offset = composite.basePos + new Vector3Int(x, y, 0); foreach (RCObj rco in composite.rooms) { // placing room GameObject roomGameObj = PlaceRoom(rco.roomData, offset.x + rco.pos.x, offset.y + rco.pos.y, dungeonContainer); Room room = roomGameObj.GetComponent <Room>(); // special cases if (rco.roomData.roomType == RoomType.entrance) { List <Direction> sides = new List <Direction>(); foreach (RCConnection connection in rco.connections) { if (connection.isAvailable) { sides.Add(connection.side); } } Direction dir; if (sides.Count == 0) { Debug.LogError("No sides to spawn entrance in!"); dir = 0; } else { dir = sides[Random.Range(0, sides.Count)]; dir = (Direction)((int)dir % 4); } room.SpawnEnterance(dir); } else if (rco.roomData.roomType == RoomType.exit) { Direction dir = 0; foreach (RCConnection connection in rco.connections) { if (!connection.isAvailable) { dir = connection.side; break; } } dir = (Direction)(((int)dir + 2) % 4); room.SpawnExit(dir); } // filling unused walls with doors for (int doorInd = 0; doorInd < rco.connections.Count; doorInd++) { UpdateDoorWallCheck(room.doors[doorInd], rco.connections[doorInd], offset + rco.pos); } } // placing hallway foreach (HallwayObj h in composite.hallways) { PlaceHallway(h, offset); } }