/* * Method for placing random rooms * Randomly picks entrance and primary exit * If !willCollide(), is placed * If any unused doors remain, stores them in unusedDoors queue * @param origin: vector3 position that tracks where an object is spawned. * @param room: room to be placed * */ private void placeMultiDoorRoom(Prefab room, Door door) { door.decrement(); //door has been consumed now int numDoors = room.numDoors(); //number of doors IN THIS ROOM ONLY int doorsToQueue = numDoors - 1; //number of open doors int entInt = (int)Random.Range(0, numDoors - 1); //pick an entrance from room Quaternion[] exits = new Quaternion[doorsToQueue]; int[] distribute = split(door.getNum(), doorsToQueue); Vector3 center = door.getPos() + (CELL_SIZE * door.getFace()); //move spawn point from door to center of next room Transform placedRoom = Instantiate(room.getTransform(), center, Quaternion.identity) as Transform; //spawn the room in normal orientation currentRoomsPlaced += 1; Vector3 entrance = room.getDoor(entInt) * placedRoom.forward; //get vector pointing at the door we want to connect with the connecting door placedRoom.forward = Quaternion.FromToRotation(entrance, -door.getFace()) * placedRoom.forward; //rotate transform so that proper door is lined up. placedRoom.transform.localScale = new Vector3(scale, 1, scale); placeLight(center); //Debug.Log("Center for this room will be " + center); if (placedRoom.up != Vector3.up) //ensures everything is upright (some bug somewhere is flipping random rooms upsidedown) { placedRoom.up = Quaternion.FromToRotation(placedRoom.up, Vector3.up) * placedRoom.up; } //Debug.Log("There are " + (doorsToQueue) + " doors to add"); for (int i = 1; i < numDoors; i++) { exits[mod(i, doorsToQueue)] = room.getDoor(mod(entInt + i, numDoors)); } for (int i = 0; i < doorsToQueue; i++) { int doorSplit = distribute[0]; //this door's share of the rooms Vector3 facing = exits[i] * placedRoom.forward; //gets a door that is NOT the entrance Vector3 position = center + (facing * CELL_SIZE); unusedDoors.Enqueue(new Door(position, facing, doorSplit)); // Debug.Log("Added door at position " + position + " that is facing " + facing + " to queue"); } }
private void spawnDungeon() { bool stairwayPlaced = false; int lostRooms = 0; //when a door path collides, the number of rooms on that path are stored and put onto another branch spawnStart(); Door lastDoor = new Door(Vector3.right*CELL_SIZE, Vector3.right, 1); int countdown = maxRooms; while (unusedDoors.Count != 0) { Door door = (Door) unusedDoors.Dequeue(); lastDoor = door; door.addNum(lostRooms); lostRooms = 0; Vector3 position = door.getPos() + (door.getFace() * CELL_SIZE); if (!willCollide(position) && currentRoomsPlaced < maxRooms) //if the next prefab would clip inside an already existing thing, then it stops. { if (door.getNum() == 1) { Prefab room = WeightedRandomizer.From(deadends).TakeOne(); placeDeadEndRoom(room, door); countdown--; } else if (door.getNum() < 1) //just seal with door so we stay true to the actual room limit { Transform placedRoom = Instantiate(closed_door, door.getPos(), Quaternion.identity) as Transform; placedRoom.transform.localScale = new Vector3(scale, 1, scale); placedRoom.rotation = Quaternion.FromToRotation(placedRoom.forward, door.getFace()); if (placedRoom.up != Vector3.up) //ensures everything is upright (some bug somewhere is flipping random rooms upsidedown) { placedRoom.up = Quaternion.FromToRotation(placedRoom.up, Vector3.up) * placedRoom.up; } } else { Prefab room = WeightedRandomizer.From(branches).TakeOne(); placeMultiDoorRoom(room, door); countdown--; } } else { door.decrement(); lostRooms += door.getNum(); Transform placedRoom = null; if (stairwayPlaced || currentRoomsPlaced < maxRooms/2) { placedRoom = Instantiate(closed_door, door.getPos(), Quaternion.identity) as Transform; } else { placedRoom = Instantiate(Stairway, door.getPos(), Quaternion.identity) as Transform; stairwayPlaced = true; } placedRoom.transform.localScale = new Vector3(scale, 1, scale); placedRoom.rotation = Quaternion.FromToRotation(placedRoom.forward, door.getFace()); if (placedRoom.up != Vector3.up) //ensures everything is upright (some bug somewhere is flipping random rooms upsidedown) { placedRoom.up = Quaternion.FromToRotation(placedRoom.up, Vector3.up) * placedRoom.up; } } } if (!stairwayPlaced) { Transform placedRoom = Instantiate(Stairway, lastDoor.getPos(), Quaternion.identity) as Transform; stairwayPlaced = true; placedRoom.transform.localScale = new Vector3(scale, 1, scale); placedRoom.rotation = Quaternion.FromToRotation(placedRoom.forward, lastDoor.getFace()); if (placedRoom.up != Vector3.up) //ensures everything is upright (some bug somewhere is flipping random rooms upsidedown) { placedRoom.up = Quaternion.FromToRotation(placedRoom.up, Vector3.up) * placedRoom.up; } } }
/* * places rooms and hallways that end the path * @param origin: vector3 position that tracks where an object is spawned * @param room: room to be placed */ private void placeDeadEndRoom(Prefab room, Door door) { Vector3 center = door.getPos() + CELL_SIZE * door.getFace(); Transform placedRoom = Instantiate(room.getTransform(), center, Quaternion.identity) as Transform; //spawn the room currentRoomsPlaced += 1; placedRoom.transform.localScale = new Vector3(scale, 1, scale); Vector3 entrance = room.getDoor(0) * placedRoom.forward; placedRoom.forward = Quaternion.FromToRotation(entrance, -door.getFace()) * placedRoom.forward; if (placedRoom.up != Vector3.up) //ensures everything is upright (some bug somewhere is flipping random rooms upsidedown) { placedRoom.up = Quaternion.FromToRotation(placedRoom.up, Vector3.up) * placedRoom.up; } placeLight(center); }