private List <RoomNode> GenerateNextRooms(RoomSide side, List <RoomNode> currentRooms, ShouldStillGenerate shouldStillGenerate, int radius) { var oppositeSide = Room.OppositeSide(side); var currRoomNum = 0; var doorsLeft = CountDoorsAtSide(side, currentRooms); var nextRooms = new List <RoomNode>(); while (doorsLeft > 0) { // find a room with <= rooms at opposite of side. RoomNode nextNode = GetRoomWithMaxDoors( oppositeSide, doorsLeft, shouldStillGenerate, radius); nextRooms.Add(nextNode); var nodesToMake = nextNode.GetDoorCount(oppositeSide); Assert.IsTrue(nodesToMake > 0); doorsLeft -= nodesToMake; Assert.IsTrue(doorsLeft >= 0); for (var doorNum = 0; doorNum < nodesToMake; doorNum++) { while (currentRooms[currRoomNum].GetNeighborRooms(side).Count >= currentRooms[currRoomNum].GetDoorCount(side)) { currRoomNum++; } var currentRoomDoorNum = currentRooms[currRoomNum].GetNeighborRooms(side).Count; currentRooms[currRoomNum].GetNeighborRooms(side).Add(nextNode); currentRooms[currRoomNum].GetRoomDoorNums(side).Add(doorNum); nextNode.GetNeighborRooms(oppositeSide).Add(currentRooms[currRoomNum]); nextNode.GetRoomDoorNums(oppositeSide).Add(currentRoomDoorNum); } } return(nextRooms); }
private RoomNode GetRoomWithMaxDoors(RoomSide side, int maxIncomingDoors, ShouldStillGenerate shouldStillGenerate, int madeRoomRadius) { Assert.IsTrue(maxIncomingDoors >= 1); var minOutgoingDoors = shouldStillGenerate.IsDone() ? 0 : 1; // Debug.Log("for side" + side + "make max" + maxIncomingDoors + "," + minOutgoingDoors + "," + maxOutgoingDoors); var maxOutgoingGeneralDoors = shouldStillGenerate.numGenericRooms; List <GameObject> available = new List <GameObject>(); foreach (GameObject roomPrefab in roomPrefabs) { var incomingDoorCount = roomPrefab.GetComponent <Room>().GetDoors(side).Count; var room = roomPrefab.GetComponent <Room>(); if (!(1 <= incomingDoorCount && incomingDoorCount <= maxIncomingDoors)) { continue; } if (shouldStillGenerate.numGenericRooms == 0 && shouldStillGenerate.numWaysDown == 0 && shouldStillGenerate.numSpecialRooms == 1 && room.specialRoomType == shouldStillGenerate.specialRoomType) { // special case: here, we can always finish, no matter how many outgoing doors there are. available.Add(roomPrefab); continue; } var outgoingDoorCount = roomPrefab.GetComponent <Room>().GetDoors(Room.OppositeSide(side)).Count; if (!(minOutgoingDoors <= outgoingDoorCount)) { continue; } if (room.entryPoint != null) { continue; } var isWayDown = room.wayDown != null; if (shouldStillGenerate.numWaysDown > 0 && isWayDown) { available.Add(roomPrefab); } else if (shouldStillGenerate.numSpecialRooms > 0 && room.specialRoomType == shouldStillGenerate.specialRoomType) { available.Add(roomPrefab); } else if (!isWayDown && !room.specialRoom && outgoingDoorCount <= maxOutgoingGeneralDoors) { available.Add(roomPrefab); } } Assert.IsTrue(available.Count > 0, "Not all necessary rooms are available to make " + shouldStillGenerate); var chosenRoomPrefab = available[Random.Range(0, available.Count)]; var madeNode = new RoomNode(this, chosenRoomPrefab, madeRoomRadius); shouldStillGenerate.AddMadeNode(madeNode); return(madeNode); }
public void GenerateMap() { myCurrentStageText.text = "LD" + ((levelCount - currentLevel) * levelStageDepth - currentStage.stageDepth); foreach (RoomNode node in roomNodes) { Destroy(node.roomObject); } roomCount = 0; roomNodes.Clear(); var isInitialStage = (currentLevel == 0 && currentStage.stageDepth == 0); var actualStartRoomPrefab = !isInitialStage ? startRoomPrefab : initialLevelRoomPrefab; var startNode = new RoomNode(this, actualStartRoomPrefab, 0); List <RoomNode> leftmostRooms = new List <RoomNode>(); List <RoomNode> rightmostRooms = new List <RoomNode>(); leftmostRooms.Add(startNode); rightmostRooms.Add(startNode); roomNodes.Add(startNode); var numGenericRooms = levelTargetNumGenericRoomsPerStage[currentLevel]; var needSpecialRooms = currentStage.type != StageNode.StageType.Normal; var shouldStillGenerate = new ShouldStillGenerate(numGenericRooms, currentStage.GetNumWaysDown(), needSpecialRooms ? 1 : 0, currentStage.type); if (isInitialStage) { shouldStillGenerate = new ShouldStillGenerate(0, 0, 0, StageNode.StageType.Normal); } int radius = 1; while (CountDoorsAtSide(RoomSide.Left, leftmostRooms) + CountDoorsAtSide(RoomSide.Left, rightmostRooms) > 0) { if (radius >= shouldStillGenerate.numGenericRooms + 10) { Assert.IsTrue(false); } if (Random.Range(0, 2) == 0) { leftmostRooms = GenerateNextRooms(RoomSide.Left, leftmostRooms, shouldStillGenerate, -radius); rightmostRooms = GenerateNextRooms(RoomSide.Right, rightmostRooms, shouldStillGenerate, radius); } else { rightmostRooms = GenerateNextRooms(RoomSide.Right, rightmostRooms, shouldStillGenerate, radius); leftmostRooms = GenerateNextRooms(RoomSide.Left, leftmostRooms, shouldStillGenerate, -radius); } roomNodes.AddRange(leftmostRooms); roomNodes.AddRange(rightmostRooms); radius++; } Assert.AreEqual(roomCount, roomNodes.Count); foreach (RoomNode node in roomNodes) { node.SetupInstance(); } var sortedRoomNodes = roomNodes.OrderBy(node => node.horizontalPos); var wayDownNum = 0; foreach (var node in sortedRoomNodes) { if (node.roomObject.GetComponent <Room>().wayDown != null) { Debug.Log("will make room" + node.horizontalPos + "the wayDownNum=" + wayDownNum); node.wayDownNum = wayDownNum; wayDownNum++; } } var entryPos = startNode.roomObject.GetComponent <Room>().GetEntryPos(); player.transform.position = new Vector3(entryPos.x, entryPos.y, player.transform.position.z); myPlayer.currentRoomNode = startNode; minimap.RerenderMap(); }