private void BuildDungeon(GameEvents.RequestDungeonEvent e) { Debug.LogFormat("Seed: {0}, Theme: {1}", e.Seed, e.Theme); // TODO // will need to load prefabs based on level theme! m_Rng = new System.Random(e.Seed); m_PotentialPathRooms = new Queue <RoomDatum>(); m_MainPathRooms = new List <RoomDatum>(); m_DeadEndRooms = new List <RoomDatum>(); // construct the main path int maxPathLength = 5; m_CurrentRoomCount = 0; m_MainPath = true; RoomDatum startRoom = new RoomDatum(eRoom.Start); ProcessNextRoom(startRoom, null, maxPathLength); // fill out side paths BuildSidePaths(); // place interesting things PlaceObjects(); // notify Vector3 startPosition = startRoom.Room.FloorCenter.position + Vector3.up * 2f; Quaternion startRotation = Quaternion.identity; VSEventManager.Instance.TriggerEvent(new GameEvents.DungeonBuiltEvent(startPosition, startRotation)); }
private RoomDatum DetermineNextRoom(int maxRoomCount) { RoomDatum nextRoom = null; if (m_CurrentRoomCount == maxRoomCount - 1) { if (m_MainPath) { nextRoom = new RoomDatum(eRoom.End); } else { // TODO better way of marking dead end? like an eRoom type? nextRoom = new RoomDatum(eRoom.Sqr_Sm); } } else { float nextRoomChance = (float)m_Rng.NextDouble(); if (nextRoomChance < 0.45f) { nextRoom = new RoomDatum(eRoom.Sqr_Md); } else if (nextRoomChance < 0.75f) { nextRoom = new RoomDatum(eRoom.Rct_Sm); } else { nextRoom = new RoomDatum(eRoom.Sqr_Lg); } } return(nextRoom); }
private void BuildSidePaths() { int maxLength = 4; int minLength = 2; while (m_PotentialPathRooms.Count > 0) { RoomDatum data = m_PotentialPathRooms.Dequeue(); int pathLength = m_Rng.Next(maxLength) + minLength; m_CurrentRoomCount = 0; m_MainPath = false; ProcessNextRoom(data, null, pathLength); } }
private bool DetermineEndOfRoute(RoomDatum roomData, Connector roomEntry) { if (roomData.RoomType == eRoom.Sqr_Sm && !roomEntry.IsOnMainPath) { roomData.SetDeadEnd(); m_DeadEndRooms.Add(roomData); GameObject roomObj = roomData.Room.gameObject; roomObj.name = string.Format("{0} [{1}]", roomObj.name, "Dead End"); return(true); } // check end room if (roomData.RoomType == eRoom.End) { return(true); } return(false); }
private void ProcessNextRoom(RoomDatum roomData, Connector prevHallConnector, int maxRoomCount) { Room room = BuildRoom(roomData, prevHallConnector); Connector entryConnector = room.Connectors[0]; m_CurrentRoomCount += 1; // check for dead ends bool end = DetermineEndOfRoute(roomData, entryConnector); if (end) { return; } int previousSlot = 0; // should probably track the actual last slot to help avoid overlapping Connector randomConnector = room.GetRandomConnector(previousSlot, m_Rng); Hall hall = BuildHall(randomConnector, entryConnector, room, maxRoomCount); RoomDatum nextRoom = DetermineNextRoom(maxRoomCount); ProcessNextRoom(nextRoom, hall.Connectors[1], maxRoomCount); }
private Room BuildRoom(RoomDatum roomData, Connector prevHallConnector) { // spawn the new room bool existingRoom = (roomData.Room != null); Room room = roomData.Room; GameObject roomObj = null; Connector previousConnector = prevHallConnector; if (existingRoom) { room = roomData.Room; roomObj = room.gameObject; previousConnector = roomData.PreviousHallConnector; } else { roomObj = (GameObject)Instantiate(m_RoomPrefabs[(int)roomData.RoomType], null); room = roomObj.GetComponent <Room>(); roomData.SetRoom(room, prevHallConnector); } Connector entryConnector = room.Connectors[0]; if (roomData.RoomType == eRoom.Start) { entryConnector.IsOnMainPath = true; } if (previousConnector != null) { Vector3 position = previousConnector.WorldPosition + room.GetConnectorToCenter(entryConnector); position.y = 0f; // all rooms at 0 height roomObj.transform.position = position; // update connections previousConnector.SetNextSpace(room); entryConnector.IsOnMainPath = previousConnector.IsOnMainPath; // rotate if (!existingRoom) { float angleFromForward = 180f + Utils.SignedAngle(Vector3.forward, previousConnector.Forward); roomObj.transform.RotateAround(previousConnector.WorldPosition, Vector3.up, angleFromForward); } // open the door room.OpenWall(0); } else { // no previous room, likely the start room roomObj.transform.position = Vector3.zero + room.GetConnectorToCenter(entryConnector); } // queue up potential side path rooms if (m_MainPath && roomData.RoomType != eRoom.Start && roomData.RoomType != eRoom.End && !roomData.IsDeadEnd) { m_PotentialPathRooms.Enqueue(roomData); m_MainPathRooms.Add(roomData); } // ugh if (roomData.RoomType == eRoom.Start) { m_StartRoom = roomData.Room; } else if (roomData.RoomType == eRoom.End) { m_EndRoom = roomData.Room; } return(room); }