Exemplo n.º 1
0
    public enum DamageType { poking, burn };                             ///the types of damage that an entity can take for the purpose of the TakeDamage function

    ///On Start, Entity attempts to bind itself to the Tile underneath it
    ///on fail, Entity destroys itself
    public virtual void Start()
    {
        if (occupyingTile == null)
        {
//            Debug.Log("Checking space beneath this entity at " + transform.position.x + "," + transform.position.y);
            Vector2    topRightLoc = new Vector2(transform.position.x + 0.25f, transform.position.y + 0.25f);
            Vector2    botLeftLoc  = new Vector2(transform.position.x - 0.25f, transform.position.y - 0.25f);
            Collider2D collider    = Physics2D.OverlapArea(topRightLoc, botLeftLoc, TileMonoBehavior.tileLayerMask);
            if (collider != null)
            {
                TileMonoBehavior belowTile = collider.gameObject.GetComponent <TileMonoBehavior>();
                if (belowTile != null)
                {
                    if (!belowTile.ConnectToEntity(this)) //if could not connect entity to a tile, we should garbage collect entity because it can't interract with game at all
                    {
                        Debug.Log("ALERT! Found Tile Layer Object at " + transform.position.x + "," + transform.position.y + " that lacks TileMonoBehavior script!");
                        Destroy(this.gameObject);
                    }
                }
            }
            else
            {
                Debug.Log("Could not find Tile for this entity to stand on, destroying this");
                Destroy(this.gameObject);
            }
        }
    }
    ///populates random dungeon rooms with stuff, including placing player character, stairs, enemies
    void PopulateDungeon()
    {
        ///create dungeon controller that all entities will reference

        Instantiate(dungeonController, new Vector3(), transform.rotation); //places dungeon controller first to take advantage of automatic turn order tracking

        //Instantiate(playerObject, GetRandomRoomFromQueue().getCoords(), transform.rotation); //places player character in a random room

        dungeon_room targetRoom = GetRandomRoomFromQueue(); //pick a random room to place the stairs in

        if (createdRoomsQueue.Count >= 2)                   //if we can have stairs in separate room from Player (if we grab top room, there is another room after for player to go into)
        {
//            Debug.Log("Preventing Stairs appearing in player's room");
            tappedRoomsStack.Push(createdRoomsQueue.Dequeue()); //prevent the stairs from appearing in the same room as the player (we already grabbed the stairs room, now we're just keeping it separate from random rooms list)
        }
        //clear the tile that the stairs occupy
        Vector3 stairsPos   = targetRoom.getRandomTileInRoom(); //grab a random position in the room, TODO: remove that tile, and place the stairs tile in its place
        Vector2 topRightLoc = new Vector2(stairsPos.x + 0.25f, stairsPos.y + 0.25f);
        Vector2 botLeftLoc  = new Vector2(stairsPos.x - 0.25f, stairsPos.y - 0.25f);



        Collider2D collider = Physics2D.OverlapArea(topRightLoc, botLeftLoc, TileMonoBehavior.tileLayerMask);//build a collider at stairs position to see if there is already a tile there

        if (collider != null)
        {
            Destroy(collider.gameObject);
        }
        //place stairs into the dungeon
        Instantiate(stairsTilePrefab, stairsPos, transform.rotation);
        targetRoom = GetRandomRoomFromQueue();

        //playe player into the dungeon
        Vector3 playerPos = targetRoom.getRandomTileInRoom();

        while (playerPos.x == stairsPos.x && playerPos.y == stairsPos.y) //if player directly overlaps stairs, move player someplace else
        {
            playerPos = targetRoom.getRandomTileInRoom();
        }
        Instantiate(playerObject, playerPos, transform.rotation);

        if (tappedRoomsStack.Count > 0) //shift all of the removed elements back onto the queue, preparation for placing in rest of the dungeon
        {
            createdRoomsQueue.Enqueue(tappedRoomsStack.Pop());
        }
        //TODO: insert spectacular monster/item spawning algorithm here!
        int failCount = 0; //used to kill while loop after too many failed cases

        while (numberOfMonsters > 0 && (failCount < 10))
        {
            //pick a tile, any tile...
            TileMonoBehavior tileAtSpawnPos   = null;
            dungeon_room     monsterSpawnRoom = GetRandomRoomFromQueue();
            Vector3          monsterSpawnPos  = monsterSpawnRoom.getRandomTileInRoom();
            //check if tile already occupied
            topRightLoc = new Vector2(monsterSpawnPos.x + 0.25f, monsterSpawnPos.y + 0.25f); //build a collider to fetch the tile there
            botLeftLoc  = new Vector2(monsterSpawnPos.x - 0.25f, monsterSpawnPos.y - 0.25f);
            collider    = Physics2D.OverlapArea(topRightLoc, botLeftLoc, TileMonoBehavior.tileLayerMask);
            if (collider != null) //we find a tile there
            {
                tileAtSpawnPos = collider.gameObject.GetComponent <TileMonoBehavior>();
            }
            if (tileAtSpawnPos != null && !tileAtSpawnPos.IsOccupied()) //if we found a tile and it is not occupied, spawn a monster there
            {
                Debug.Log("Creating monster at " + monsterSpawnPos.x + "," + monsterSpawnPos.y);
                GameObject spawnedEnemy = (GameObject)Instantiate(basicMonster, monsterSpawnPos, transform.rotation); //place a monster there, connect it to the tile
                tileAtSpawnPos.ConnectToEntity(spawnedEnemy.GetComponent <Entity>());
                numberOfMonsters--;
                failCount = 0;
            }
            else
            {
                failCount++;
            }
        }
        if (failCount == 10)
        {
            Debug.Log("Failed to spawn all monsters, remaining monsters: " + numberOfMonsters);
        }
    }