private IEnumerable <RoomPrototype> GetPossibleRoomsForConnection(RoomPrototypeConnection baseConnection, DungeonNode nextStructureElement) { var baseRoom = baseConnection.ParentRoomPrototype; foreach (var newRoom in GetRandomOrderedRooms(nextStructureElement)) { IEnumerable <RoomConnector> possibleNextConnections = newRoom .GetConnections() .Where(x => x.size.Equals(baseConnection.ParentConnection.size) && x.type == baseConnection.ParentConnection.type) .ToList().Shuffle(_random); foreach (var nextRoomConnection in possibleNextConnections) { var nextRoomConnectionTransform = nextRoomConnection.transform; var selectedConnectionTransform = baseConnection.ParentConnection.transform; GetNewRoomPosAndRot(baseRoom.GlobalPosition, baseRoom.Rotation, selectedConnectionTransform, nextRoomConnectionTransform, out var newRoomPosition, out var rotationDiff); var nextRoomWrapper = new RoomPrototype(nextStructureElement, newRoom, newRoomPosition, rotationDiff); if (!TryAddRoomToVirtualSpace(nextRoomWrapper, baseRoom)) { continue; } nextRoomWrapper.ConnectToParent(nextRoomConnection, baseConnection); yield return(nextRoomWrapper); } } }
private bool BuildPrototypeRoomRecur(RoomPrototype room) { #if TAURUS_DEBUG_LOG Debug.Log($"Room {room.RoomResource} is built"); #endif DungeonNode actualGraphElement = room.ActualGraphElement; if (actualGraphElement.IsEndNode) { return(true); } var subElements = actualGraphElement.SubElements.Where(sub => GetGenMetaData(sub.MetaData).NodeRequired).ToList(); if (room.ChildRoomConnections.Count < actualGraphElement.ChildNodes.Count()) { throw new Exception($"Room {room.RoomResource.name} has {room.ChildRoomConnections.Count} connections, yet the graph element {actualGraphElement.Style} requires {actualGraphElement.ChildNodes.Count()}"); } for (int connectionsToMake = subElements.Count; connectionsToMake > 0; connectionsToMake--) { IList <RoomPrototypeConnection> availableConnections = room.ChildRoomConnections .Where(x => x.State == PrototypeConnectionState.FREE) .ToList() .Shuffle(_random); DungeonNode nextStructureElement = subElements[connectionsToMake - 1]; bool failed = availableConnections.Count < connectionsToMake; RoomPrototypeConnection successfulConnection = null; if (!failed) { foreach (var selectedConnection in availableConnections) { if (GetPossibleRoomsForConnection(selectedConnection, nextStructureElement).Any(BuildPrototypeRoomRecur)) { successfulConnection = selectedConnection; break; } } if (successfulConnection == null) { failed = true; } } // building cannot be successful if (failed) { #if TAURUS_DEBUG_LOG Debug.LogWarning($"Failed to make room {room} of element {actualGraphElement.Style}"); #endif RemoveRoomAndChildrenRecur(room); room.ParentRoomConnection?.ClearChild(); _stepBackCounter.StepBack(); return(false); } else { availableConnections.Remove(successfulConnection); } } return(true); }