/// <summary>
    /// Return the integer of a random OPEN door from a given room
    /// </summary>
    /// <param name="roomSpawn"></param>
    /// <param name="usedDoors"></param>
    /// <returns></returns>
    private int GetRandomValidDoor(RoomSpawn roomSpawn, List <int> usedDoors)
    {
        List <int> validDoors = new List <int>();

        for (int i = 0; i < roomSpawn.doors.Count; i++)
        {
            bool valid = true;
            for (int j = 0; j < usedDoors.Count; j++)
            {
                if (i == usedDoors[j])
                {
                    valid = false;
                }
            }

            if (valid && roomSpawn.doors[i].doorOpen)
            {
                validDoors.Add(i);
            }
        }

        if (validDoors.Count == 0)
        {
            return(-1);
        }

        return(validDoors[Random.Range(0, validDoors.Count - 1)]);
    }
    /// <summary>
    /// Generate a random room based on {rooms} at a given position
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    private RoomSpawn GenerateRoom(int x, int y)
    {
        RoomSpawn roomSpawn = new RoomSpawn();

        int roomPick = Random.Range(0, rooms.Count);

        GameObject    roomObj   = InstantiateRoom(roomPick);
        RoomDescriber describer = roomObj.GetComponent <RoomDescriber>();

        roomSpawn.type     = roomPick;
        roomSpawn.roomSize = describer.roomSize;
        roomSpawn.location = new Vector2(x, y);
        roomSpawn.obj      = roomObj;

        //add each doorway
        List <DoorDescriber> doors = new List <DoorDescriber>();

        for (int i = 0; i < describer.doorways.Count; i++)
        {
            doors.Add(describer.doorways[i].GetComponent <DoorDescriber>());
            doors[i].location = new Vector2(
                describer.doorways[i].transform.position.x,
                describer.doorways[i].transform.position.y);
            doors[i].doorOpen     = true;
            doors[i].elevatorDoor = false;
        }
        roomSpawn.doors = doors;


        return(roomSpawn);
    }
Exemple #3
0
    // Start is called before the first frame update
    void Start()
    {
        roomSpawn = GameObject.Find("GameMaster").GetComponent <RoomSpawn>();
        int isSpawn = Random.Range(1, 3);

        if (isSpawn == 2 && !roomSpawn.safeIsSpawned)
        {
            Instantiate(roomSpawn.SafeZone, transform.position, Quaternion.Euler(0, -90, 0));
            roomSpawn.safeIsSpawned = true;
        }
    }
    /// <summary>
    /// Checks if the player enters the room.
    /// If the player enters then we spawn ennemies
    /// </summary>
    /// <param name="collision"></param>
    private void OnTriggerEnter2D(Collider2D collision)
    {
        RoomSpawn spawn = GameObject.Find("Grid").GetComponent <RoomSpawn>();

        if (collision.CompareTag("Player"))
        {
            string[] coords = this.name.Split(',');

            if (!roomEntered)
            {
                // spawns ennemies
                spawn.SpawnEnnemies(System.Convert.ToInt32(coords[0]),
                                    System.Convert.ToInt32(coords[1]));

                roomEntered = true;
            }
        }
    }
    /// <summary>
    /// Check to see if a given room {roomCheck} is colliding with any existing rooms {roomSpawns}
    /// </summary>
    /// <param name="roomSpawns"></param>
    /// <param name="roomCheck"></param>
    /// <returns></returns>
    private bool CheckRoomIntersections(List <RoomSpawn> roomSpawns, RoomSpawn roomCheck)
    {
        List <Vector4> sizesCheck = roomCheck.roomSize;

        foreach (RoomSpawn room in roomSpawns)
        {
            List <Vector4> sizes = room.roomSize;
            foreach (Vector4 sizeCheck in sizesCheck)
            {
                foreach (Vector4 size in sizes)
                {
                    bool check = helper.AABBTest(new Vector2(sizeCheck.x + roomCheck.location.x, sizeCheck.y + roomCheck.location.y), new Vector2(sizeCheck.z, sizeCheck.w),
                                                 new Vector2(size.x + room.location.x, size.y + room.location.y), new Vector2(size.z, size.w));
                    if (check)
                    {
                        return(true);
                    }
                }
            }
        }

        return(false);
    }
    Room Spawner(RoomSpawn spawn){
        if(rooms.Count >= maxRooms){
            return null;
        }

        if(CollideRooms(spawn.position.x, spawn.position.y, spawn.width, spawn.height))
            return null;

        Room room = Instantiate(spawn.room, spawn.position, Quaternion.identity) as Room;
        room.transform.parent = transform;
        
        if(spawn.direction == Directions.Up){
            room.doorBottom.linkTo = spawn.parent.doorTop;
            spawn.parent.doorTop.linkTo = room.doorBottom;
        } else if(spawn.direction == Directions.Down) {
            room.doorTop.linkTo = spawn.parent.doorBottom;
            spawn.parent.doorBottom.linkTo = room.doorTop;
        } else if(spawn.direction == Directions.Left) {
            room.doorRight.linkTo = spawn.parent.doorLeft;
            spawn.parent.doorLeft.linkTo = room.doorRight;
        } else if(spawn.direction == Directions.Right) {
            room.doorLeft.linkTo = spawn.parent.doorRight;
            spawn.parent.doorRight.linkTo = room.doorLeft;
        }

        if(rooms.Count == 0)
            room.type = RoomType.Entrance;
            
        rooms.Add(room);
        Generate(room, spawn.direction);
        return room;
    }
 bool AddToQueue(Room last, Vector2 position, RoomList size, Directions direction)
 {
     if(!CollideRooms(position.x, position.y, size.width, size.height)){
         Room room = size.rooms[Random.Range(0, size.rooms.Length-1)];
         RoomSpawn spawn = new RoomSpawn(position, size.width, size.height, room, last, direction);
         queue.Add(spawn);
         return true;
     }
     
     return false;
 }
    /// <summary>
    /// Spawns in elevators to then pass to wave generation
    /// </summary>
    /// <param name="roomSpawns"></param>
    /// <returns></returns>
    private List <GameObject> SpawnElevators(List <RoomSpawn> roomSpawns)
    {
        List <GameObject> elevators = new List <GameObject>();

        foreach (RoomSpawn roomSpawn in roomSpawns)
        {
            for (int i = 0; i < roomSpawn.doors.Count; i++)
            {
                if (roomSpawn.doors[i].doorOpen)
                {
                    Vector2 doorPositionAdjust = GetDoorAdjust(roomSpawn.doors[i]);

                    GameObject elevator = Instantiate(elevatorPrefab, mapTransform);
                    elevator.transform.position = roomSpawn.location;
                    RoomDescriber        roomDescriber = elevator.GetComponent <RoomDescriber>();
                    List <DoorDescriber> doors         = new List <DoorDescriber>();
                    //setup doors
                    foreach (GameObject door in roomDescriber.doorways)
                    {
                        doors.Add(door.GetComponent <DoorDescriber>());
                        doors[doors.Count - 1].location = door.transform.position;
                    }

                    //do thing
                    for (int j = 0; j < doors.Count; j++)
                    {
                        Vector2 elevatorAdjust = GetDoorAdjust(doors[j]);
                        if (IsDoorInverse(doorPositionAdjust, elevatorAdjust))
                        {
                            Vector2 roomMove = MatchDoorRoomAdjust(roomSpawn.location, doors[j].location, roomSpawn.location, roomSpawn.doors[i].location, doorPositionAdjust);

                            //Debug.Log($"doorPosAdjust: {doorPositionAdjust}, roomPos: {roomSpawn.location}, roomDoor {i} location: {roomSpawn.doors[i].location}, elevator position: {elevator.transform.position}, elevator door pos: {doors[j].location}");

                            elevator.transform.position += new Vector3(roomMove.x + roomSpawn.location.x, roomMove.y + roomSpawn.location.y, 0);


                            RoomSpawn elevatorRoom = new RoomSpawn();
                            elevatorRoom.obj      = elevator;
                            elevatorRoom.roomSize = elevator.GetComponent <RoomDescriber>().roomSize;
                            elevatorRoom.location = elevator.transform.position;
                            bool intersecting = CheckRoomIntersections(roomSpawns, elevatorRoom);
                            if (intersecting)
                            {
                                Destroy(elevator);
                                break;
                            }
                            elevators.Add(elevator);
                            roomSpawn.doors[i].elevatorDoor = true;
                        }
                        else
                        {
                            GameObject doorObj = doors[j].gameObject;
                            Instantiate(elevatorWallPrefab, doorObj.transform.position, doorObj.transform.rotation, doorObj.transform.parent);
                            Destroy(doorObj);
                        }
                    }
                }
            }
        }

        return(elevators);
    }
    private List <RoomSpawn> SpawnBossRoom(List <RoomSpawn> roomSpawns, int floor)
    {
        //pick random boss from floor list
        BossRoom bossRoom = floorBosses[floor].bossRooms[Random.Range(0, floorBosses[floor].bossRooms.Count - 1)];

        //setup RoomSpawn for boss room
        RoomSpawn     bossRoomSpawn     = new RoomSpawn();
        RoomDescriber bossRoomDescriber = bossRoom.bossRoom.GetComponent <RoomDescriber>();
        //add doors
        List <DoorDescriber> doors = new List <DoorDescriber>();

        for (int i = 0; i < bossRoomDescriber.doorways.Count; i++)
        {
            doors.Add(bossRoomDescriber.doorways[i].GetComponent <DoorDescriber>());
            doors[i].location = new Vector2(
                bossRoomDescriber.doorways[i].transform.position.x,
                bossRoomDescriber.doorways[i].transform.position.y);
            doors[i].doorOpen     = true;
            doors[i].elevatorDoor = false;
        }

        bossRoomSpawn.roomSize = bossRoomDescriber.roomSize;
        bossRoomSpawn.doors    = doors;

        List <Vector2> bossRoomDoorAdjusts = new List <Vector2>();

        foreach (DoorDescriber door in bossRoomSpawn.doors)
        {
            bossRoomDoorAdjusts.Add(GetDoorAdjust(door));
        }

        List <RoomSpawn> validRooms = new List <RoomSpawn>();

        //find all VALID rooms for this particular boss room
        foreach (RoomSpawn room in roomSpawns)
        {
            foreach (DoorDescriber door in room.doors)
            {
                bool found = false;
                foreach (Vector2 bossRoomAdjust in bossRoomDoorAdjusts)
                {
                    if (IsDoorInverse(GetDoorAdjust(door), bossRoomAdjust))
                    {
                        validRooms.Add(room);
                        break;
                    }
                }
                if (found)
                {
                    break;
                }
            }
        }

        bool       finished    = false;
        int        maxLoops    = Constants.LEVELGEN_BOSS_ROOM_MAX_LOOPS;
        List <int> usableRooms = new List <int>();

        for (int i = 0; i < validRooms.Count; i++)
        {
            usableRooms.Add(i);
        }

        do
        {
            //pick random valid room, then pick random valid door
            int randomPick = Random.Range(0, usableRooms.Count - 1);
            usableRooms.RemoveAt(randomPick);
            if (usableRooms.Count == 0)
            {
                Debug.LogError("Ran out of usable rooms to spawn boss room: Regenerating level");
                GenerateLevel(floor);
                return(null);
            }
            int randomRoom   = usableRooms[randomPick];
            int bossDoorPick = -1;
            int roomDoorPick = -1;
            for (int i = 0; i < validRooms[randomRoom].doors.Count; i++)
            {
                for (int j = 0; j < bossRoomDoorAdjusts.Count; j++)
                {
                    if (IsDoorInverse(GetDoorAdjust(validRooms[randomRoom].doors[i]), bossRoomDoorAdjusts[j]))
                    {
                        bossDoorPick = j;
                        roomDoorPick = i;
                    }
                }
            }

            //spawn boss room
            Vector2 roomMove = MatchDoorRoomAdjust(
                bossRoomSpawn.location,
                bossRoomSpawn.doors[bossDoorPick].location,
                validRooms[randomRoom].location,
                validRooms[randomRoom].doors[roomDoorPick].location,
                GetDoorAdjust(validRooms[randomRoom].doors[roomDoorPick]));

            bossRoomSpawn.location += roomMove;
            if (!CheckRoomIntersections(roomSpawns, bossRoomSpawn))
            {
                GameObject bossRoomObj = Instantiate(bossRoom.bossRoom, mapTransform);
                bossRoomObj.transform.position = bossRoomSpawn.location;
                bossRoomSpawn.obj = bossRoomObj;

                bossRoomSpawn.doors[bossDoorPick].doorOpen          = false;
                validRooms[randomRoom].doors[roomDoorPick].doorOpen = false;

                bossRoomPick = bossRoomSpawn;
                bossPick     = bossRoom.boss;

                roomSpawns.Add(bossRoomSpawn);
                graph.AddNodes(bossRoomSpawn.obj.GetComponent <RoomDescriber>().enemyPathPoints, 0);
                finished = true;
            }
            maxLoops--;
        } while (maxLoops > 0 && !finished && usableRooms.Count > 0);
        if (maxLoops == 0)
        {
            Debug.LogError("Boss room failed to spawn, max iterations passed");
        }
        else if (usableRooms.Count == 0)
        {
            Debug.LogError("Boss room failed to spawn, ran out of rooms to search through");
        }
        Debug.Log($"Generating boss room took {Constants.LEVELGEN_BOSS_ROOM_MAX_LOOPS - maxLoops} iterations");
        return(roomSpawns);
    }