void GenerateBranch(out int length, out AP_Room lastRoom) { // out above used to return length and lastRoom of branch to GenerateBranchPaths() for making connections at the end int branchLength = Random.Range(mBranchLength.minimum, mBranchLength.maximum + 1); length = 0; lastRoom = null; for (int i = 0; i < branchLength; i++) { length++; AP_Room newBranchRoom = ExpandRoom(); newBranchRoom.SetRoomType(AP_Room.RoomType.branch); if (i < branchLength - 1) { if (!ExpandBranchDoors(newBranchRoom)) { lastRoom = newBranchRoom; break; } } else { lastRoom = newBranchRoom; } } }
public void MergeRoom(AP_Room r, int id) { Vector2 mergeDir = r.GetUnitPos() - GetUnitPos(); SetOpen(mergeDir); SetID(id); mMergedRooms.Add(r); }
public virtual void Setup(AP_Room r, DD_GenObstacle g, GiveEnemy e) { obstacleGenerator = g; enemyGenerator = e; room = r; rows = r.GetSize() - 3; // -3 accomodates an inset such that objects are generated at least 1 unit away from the room's walls columns = rows; }
public void ConnectRoom(AP_Room r) { Vector2 connectDir = r.GetUnitPos() - GetUnitPos(); if (connectDir.magnitude != 1) { print("Rooms not orthogonally adjacent, connect failed"); return; } ConnectRoom(connectDir); r.ConnectRoom(-connectDir); }
public void MergeRoom(AP_Room r) { Vector2 mergeDir = r.GetUnitPos() - GetUnitPos(); if (mergeDir.magnitude != 1) { print("Rooms not orthogonally adjacent, merge failed"); return; } MergeRoom(r, GetID()); r.MergeRoom(this, GetID()); }
bool ExpandBranchDoors(AP_Room r) { Vector2[] dirs = GetRandomDirections(); // get shuffled array of cardinal directions for (int i = 0; i < 4; i++) { // iterate through array to find first valid direction if (isSpaceAvailable(r, dirs[i])) { AddDoorToFront(r, dirs[i]); return(true); } } return(false); }
AP_Room ExpandRoom() { if (ExpandingDoors.Count > 0) { Door nextDoor = ExpandingDoors[0]; // get most recent door from expanding doors list ExpandingDoors.RemoveAt(0); // removing door from list makes sure it's not used again AP_Room newRoom = CreateRoom(nextDoor.newPos); // place room based on door retrieved AP_Room originRoom = GetRoomAtPos(nextDoor.origin); // get origin of nextDoor, then find that origin room in dungeon rooms originRoom.ConnectRoom(newRoom); // join both rooms with a door edge return(newRoom); } else { print("NO DOORS TO EXPAND FROM"); return(null); } }
protected Vector3 offset = Vector2.zero; // offset of pouplating objects to match big room public override void Setup(AP_Room r, DD_GenObstacle g, GiveEnemy e) { obstacleGenerator = g; enemyGenerator = e; room = r; int newSize = 2 * r.GetSize() - 4; // to get inset from sides of new large room rows = newSize; //r.GetSize () - 3; columns = rows; float offsetMod = r.GetSize() / 2f; Debug.Log("OFFSET MOD FOR LARGE ROOM IS " + offsetMod); offset = new Vector2(offsetMod, offsetMod); if (FindObjectsOfType <AP_BigRoomPopulator> ().Length == 1) { handleBoss = true; } }
AP_Room CreateRoom(Vector2 rPos) { if (isSpaceAvailable(rPos)) { AP_Room newRoom = Instantiate(mDefaultRoom) as AP_Room; newRoom.SetupRoom(rPos, mRoomCount++); // room count used to set the room id, and then increment room count so next set id will be different DungeonRooms.Add(newRoom); return(newRoom); } else { SceneManager.LoadScene(SceneManager.GetActiveScene().name); // Application.LoadLevel (Application.loadedLevelName); print("RELOAD LEVEL - FAILED TO CREATE ROOM"); do { } while(Application.isLoadingLevel); return(null); } }
void GenerateDungeon() { int dungeonSpan = Random.Range(mMainPath.minimum, mMainPath.maximum + 1); int minDist = Mathf.CeilToInt(minMainPathPortion * dungeonSpan); int countToMid = Random.Range(minDist, dungeonSpan - minDist); int countToEnd = dungeonSpan - countToMid; AP_Room startRoom = CreateRoom(Vector2.zero); //create starting room, add it to dungeon rooms list startRoom.SetRoomType(AP_Room.RoomType.start); ExpandMainPathDoors(startRoom); // add doors to start room, then call expand making sure rooms only expand 'away' from start room for (int i = 0; i < countToMid; i++) // builds path between start room and mid room { AP_Room newRoom = ExpandRoom(); newRoom.SetRoomType(AP_Room.RoomType.mainPath); if (i != countToMid - 1) // I only main path to continue expanding until the next room is the middle room { ExpandMainPathDoors(newRoom); } } BuildBigRoom(false); // passing false tells method this is the middle room for (int i = 0; i < countToEnd; i++) // expand main path from mid room to end room { AP_Room newRoom = ExpandRoom(); newRoom.SetRoomType(AP_Room.RoomType.mainPath); if (i != countToEnd - 1) // no more main path when the next room is the end room { ExpandMainPathDoors(newRoom); } } BuildBigRoom(true); // passing true tells method this is the end room GenerateBranchPaths(); // go through dungeon rooms to % change merge some together. // go through mainPath and branch room types for change to convert them to trap rooms }
void ExpandMainPathDoors(AP_Room r) { Vector2[] dirs = GetRandomDirections(); // get shuffled array of cardinal directions for (int i = 0; i < 4; i++) { // iterate through array to find first valid direction if (isSpaceAvailable(r, dirs[i])) // direction doens't already have a room { if (dirs[i] != bannedMainPathDir) // direction isn't banned for main path { AddDoorToFront(r, dirs[i]); for (int j = i; j < 4; j++) { AddDoorToEnd(r, dirs [j]); } break; } else { AddDoorToEnd(r, dirs[i]); // add door at end as potential branch if banned from main path } } } }
void AddDoorToFront(AP_Room r, Vector2 dir) { Door newDoor = CreateDoor(r, dir); ExpandingDoors.Insert(0, newDoor); }
public List <Vector2> GetPathThroughDungeon() { List <Vector2> path = new List <Vector2> (); AP_Room curRoom = DungeonRooms [0]; int curRoomIndex = 0; do { curRoom = DungeonRooms [curRoomIndex]; if (curRoom.GetRoomType() == AP_Room.RoomType.mid) { Vector2 closeEntry = curRoom.GetPosition(); Vector2 farExit = curRoom.GetPosition(); for (int i = 1; i < 4; i++) // increment through the 4 rooms of the mid room to get the room closest and furthest from last room. These will be the entry/exit rooms { Vector2 previousRoomPos = DungeonRooms[curRoomIndex - 1].GetPosition(); float distance = Vector2.Distance(previousRoomPos, DungeonRooms[curRoomIndex + i].GetPosition()); if (distance < Vector2.Distance(previousRoomPos, closeEntry)) { closeEntry = DungeonRooms[curRoomIndex + i].GetPosition(); } else if (distance > Vector2.Distance(previousRoomPos, farExit)) { farExit = DungeonRooms[curRoomIndex + i].GetPosition(); } } path.Add(closeEntry); path.Add(farExit); curRoomIndex += 4; } else if (curRoom.GetRoomType() == AP_Room.RoomType.end) { Vector2 closeEntry = curRoom.GetPosition(); Vector2 centroid = closeEntry; for (int i = 1; i < 4; i++) { centroid += DungeonRooms[curRoomIndex + i].GetPosition(); Vector2 previousRoomPos = DungeonRooms[curRoomIndex - 1].GetPosition(); float distance = Vector2.Distance(previousRoomPos, DungeonRooms[curRoomIndex + i].GetPosition()); if (distance < Vector2.Distance(previousRoomPos, closeEntry)) { closeEntry = DungeonRooms[curRoomIndex + i].GetPosition(); } } centroid /= 4; path.Add(closeEntry); path.Add(centroid); } else // cur room must be a main path room { Vector2 roomPos = curRoom.GetPosition(); path.Add(roomPos); curRoomIndex++; } } while (curRoom.GetRoomType() != AP_Room.RoomType.end); return(path); }
public Door(AP_Room r, Vector2 dir) { origin = r.GetUnitPos(); doorDir = dir; newPos = origin + doorDir; }
bool isSpaceAvailable(AP_Room r, Vector2 dir) { return(isSpaceAvailable(r.GetUnitPos() + dir)); }
Door CreateDoor(AP_Room r, Vector2 dir) { Door newDoor = new Door(r, dir); return(newDoor); }
void BuildBigRoom(bool isEndRoom) { Vector2 origin = DungeonRooms[DungeonRooms.Count - 1].GetUnitPos(); // get unit position of last room in dungeon room list to know the previous room to big room Vector2[] dirs = GetRandomDirections(); Vector2[] sectionOffsets = { Vector2.zero, Vector2.right, new Vector2(1, 1), Vector2.up }; // offsets of four rooms composing the big room with 0,0 as the bottom left room section Vector2[] sectionPositions = new Vector2[4]; bool isValid = true; int curDirIndex = 0; int offset = 0; // stores random offset of big room from origin room offset = (Random.value > 0.5) ? 0 : -1; // for now as big rooms are 2x2, either no offset, or -1 offset are possible int attempts = 0; // used to track attempt iterations to place big room, to use both possible offsets do { isValid = true; Vector2 curDir = dirs[curDirIndex]; if (dirs[curDirIndex] == mNorth) { sectionPositions[0] = origin + curDir + new Vector2(offset, 0); } else if (dirs[curDirIndex] == mEast) { sectionPositions[0] = origin + curDir + new Vector2(0, offset); } else if (dirs[curDirIndex] == mSouth) { sectionPositions[0] = origin + curDir + new Vector2(offset, -1); } else // dir[curDirIndex] must equal mWest { sectionPositions[0] = origin + curDir + new Vector2(-1, offset); } for (int i = 1; i < 4; i++) // using 0,0 as bottom left, setup other section positions { sectionPositions[i] = sectionPositions[0] + sectionOffsets[i]; } // iterate through vector2 array. if all positions are free space, continue for (int r = 0; r < 4; r++) { if (!isSpaceAvailable(sectionPositions[r])) { isValid = false; curDirIndex++; if (attempts == 0) // swap the offset and try again { curDirIndex = 0; attempts = 1; offset = (offset == 0) ? -1 : 0; } } } } while (!isValid && curDirIndex < 4); // repeat trying different positioning of big room until valid position is found if (curDirIndex > 3) //reload level if big room fails to generate in current conditions { SceneManager.LoadScene(SceneManager.GetActiveScene().name); // Application.LoadLevel(Application.loadedLevelName); print("RELOAD LEVEL " + ((isEndRoom) ? "END ROOM" : "MID ROOM") + " FAILED"); // do { // } while(Application.isLoadingLevel); return; // return from this function so no other lines in this function run, this should theoretically be unnecessary? } for (int i = 0; i < 4; i++) // iterate through array again, generating a room at each chosen unit position { AP_Room r = CreateRoom(sectionPositions[i]); r.SetRoomType(((isEndRoom) ? AP_Room.RoomType.end : AP_Room.RoomType.mid)); // consider expanding rooms of big room using add door to end, to enable potential branching from big room } // merge the four created rooms AP_Room[] otherRooms = new AP_Room[3]; for (int i = 0; i < 3; i++) { otherRooms [i] = GetRoomAtPos(sectionPositions [i + 1]); } GetRoomAtPos(sectionPositions [0]).MergeRoom(otherRooms); //GetRoomAtPos (sectionPositions [0]).MergeRoom ( GetRoomAtPos (sectionPositions [1]), // GetRoomAtPos (sectionPositions [2]), // GetRoomAtPos (sectionPositions [3])); /*GetRoomAtPos(sectionPositions[0]).MergeRoom(GetRoomAtPos(sectionPositions[1])); * GetRoomAtPos(sectionPositions[0]).MergeRoom(GetRoomAtPos(sectionPositions[3])); * GetRoomAtPos(sectionPositions[2]).MergeRoom(GetRoomAtPos(sectionPositions[1])); * GetRoomAtPos(sectionPositions[2]).MergeRoom(GetRoomAtPos(sectionPositions[3])); */ AP_Room entryRoom = GetRoomAtPos(origin); AP_Room midRoomNode = GetRoomAtPos(origin + dirs[curDirIndex]); entryRoom.ConnectRoom(midRoomNode); // connect this big room with the last main path room generated if (!isEndRoom) { // choose a valid direction and room for the main path to continue on from int entryDoor = 0; int exitDoor = 0; for (int i = 0; i < 4; i++) { if (Vector2.Distance(origin, sectionPositions[i]) == 1) { entryDoor = i; } } exitDoor = (entryDoor + 2 > 3) ? (entryDoor + 1) % 3 : entryDoor + 2; // print("entry door = " + entryDoor + " exit door = " + exitDoor); for (int i = 0; i < 4; i++) { if (i != exitDoor) { ExpandMainPathDoors(GetRoomAtPos(sectionPositions[i])); } } ExpandMainPathDoors(GetRoomAtPos(sectionPositions[exitDoor])); } }
void GenerateBranchPaths() { ShuffleDoors(); List <AP_Room> branchEndRooms = new List <AP_Room> (); List <int> branchLengths = new List <int> (); int branchCount = Random.Range(mBranches.minimum, mBranches.maximum + 1); // get random number of branches to be created // print ("Branch Count = " + branchCount); for (int i = 0; i < branchCount; i++) { if (ExpandingDoors.Count == 0) // can't branch if there are no available doors { break; } Vector2 pos = ExpandingDoors [0].newPos; // get proposed new room position if (isSpaceAvailable(pos)) { int length; AP_Room lastRoom; GenerateBranch(out length, out lastRoom); // generate branch starting from that door if (length > 0) { branchEndRooms.Add(lastRoom); branchLengths.Add(length); } } else { ExpandingDoors.RemoveAt(0); // remove bad door and decrement i so branch count is preserved i--; } } // for each room in branchEndRooms for (int i = 0; i < branchEndRooms.Count; i++) { // turn the last room in long branches into treasure rooms if (branchLengths[i] > (mBranchLength.minimum + mBranchLength.maximum) / 2) { AP_Room r = branchEndRooms [i]; r.SetRoomType(AP_Room.RoomType.treasure); } } /*for(int i = 0; i < branchEndRooms.Count; i++) * { * AP_Room r = branchEndRooms [i]; * // check to see if end room can connect to another room and isn't already connected to more than one other room * // connect it to another room if possible * Vector2[] dirs = GetRandomDirections(); * int connectionsMade = 0; * for(int j = 0; j < 4; j++) * { * if (!r.IsRoomConnectedInDir(dirs[j]) * && !isSpaceAvailable (r.GetUnitPos () + dirs [j]) * && GetRoomAtPos (r.GetUnitPos () + dirs [j]).GetRoomType () != AP_Room.RoomType.end) * { * // print ("Connect rooms"); * //r.ConnectRoom (GetRoomAtPos (r.GetUnitPos () + dirs[j])); * connectionsMade++; * } * * } * if (connectionsMade == 0 && branchLengths[i] > (mBranchLength.minimum + mBranchLength.maximum) /2) // if no connection was made on last room and length is greater than a certain value * // % chance to change room into treasure room * { * // print ("TREASURE ROOM MADE AT INDEX" + DungeonRooms.IndexOf(r)); * r.SetRoomType(AP_Room.RoomType.treasure); * } * * }*/ }
void Awake() { room = GetComponent <AP_Room> (); }
void AddDoorToEnd(AP_Room r, Vector2 dir) { Door newDoor = CreateDoor(r, dir); ExpandingDoors.Insert(ExpandingDoors.Count, newDoor); }