public void DespawnObject(Vector2 positon)
    {
        s_object obj = ObjectFromWorld(positon);

        if (obj == null)
        {
            return;
        }
        Vector2Int lastpos = VectorPositionFromWorld(obj.transform.position);

        if (obj.GetType() == typeof(o_character))
        {
            character_layer[lastpos.x, lastpos.y] = null;
        }
        else if (obj.GetType() == typeof(o_tile))
        {
            block_layer[lastpos.x, lastpos.y] = null;
        }
        else if (obj.GetType() == typeof(o_item))
        {
            item_layer[lastpos.x, lastpos.y] = null;
        }

        obj.gameObject.SetActive(false);
    }
    public s_object SpawnObject(string typeofobj, Vector2 positon)
    {
        if (objPool[typeofobj] == null)
        {
            print(typeofobj);
            return(null);
        }
        s_object obj = objPool[typeofobj].Peek();
        //if(objPool[typeofobj].Peek())

        Vector2Int cells = VectorPositionFromWorld(positon);

        /*
         * bool check = false;
         *
         * //Compare the 'obj' to what exists on the current position
         * if (obj.GetType() == typeof(o_character))
         *  check = character_layer[cells.x, cells.y] != null;
         * else if (obj.GetType() == typeof(o_tile))
         *  check = block_layer[cells.x, cells.y] != null;
         * else if (obj.GetType() == typeof(o_item))
         *  check = item_layer[cells.x, cells.y] != null;
         *
         * if (check)
         *  return null;
         */

        //Delete the last position from the world
        Vector2Int lastpos = VectorPositionFromWorld(obj.transform.position);

        /*
         * if (obj.GetType() == typeof(o_character))
         *  character_layer[lastpos.x, lastpos.y] = null;
         * else if(obj.GetType() == typeof(o_tile))
         *  block_layer[lastpos.x, lastpos.y] = null;
         * else if (obj.GetType() == typeof(o_item))
         *  item_layer[lastpos.x, lastpos.y] = null;
         */

        if (obj.GetType() == typeof(o_character))
        {
            character_layer[cells.x, cells.y] = (o_character)obj;
        }
        else if (obj.GetType() == typeof(o_tile))
        {
            block_layer[cells.x, cells.y] = (o_tile)obj;
        }
        else if (obj.GetType() == typeof(o_item))
        {
            item_layer[cells.x, cells.y] = (o_item)obj;
        }

        objPool[typeofobj].Dequeue();
        objPool[typeofobj].Enqueue(obj);
        obj.transform.position = SnapToGrid(positon);
        obj.gameObject.SetActive(true);

        return(obj);
    }
    public void DisplayData(s_object otype)
    {
        string datatype = otype.GetType().ToString();

        switch (datatype)
        {
        case "o_door":

            o_door door = (o_door)otype;
            door.location = GUI.TextField(new Rect(50, 60, 80, 20), door.location);
            if (levels.Exists(d => d.name == door.location))
            {
                GUI.Box(new Rect(50, 80, 160, 20), "Position: " + door.teleport_position);
                data_level dat = levels.Find(d => d.name == door.location);
                door.teleport_position.x = (int)GUI.HorizontalSlider(new Rect(50, 100, 90, 20), door.teleport_position.x, dat.size_x, 0);
                door.teleport_position.y = (int)GUI.HorizontalSlider(new Rect(50, 120, 90, 20), door.teleport_position.y, dat.size_y, 0);
                door.teleport_position.z = (int)GUI.HorizontalSlider(new Rect(50, 140, 90, 20), door.teleport_position.z, dat.size_z, 0);

                GUI.Box(new Rect(50, 160, 270, 20), "Requirements: " + door.DOOR_STATE.ToString());

                if (GUI.Button(new Rect(50, 180, 200, 40), "Change requirement +"))
                {
                    door.DOOR_STATE++;
                }
                if (GUI.Button(new Rect(250, 180, 200, 40), "Change requirement -"))
                {
                    door.DOOR_STATE--;
                }

                door.DOOR_STATE = (o_door.DOOR_MODE)Mathf.Clamp((float)door.DOOR_STATE, 0, 2);

                switch (door.DOOR_STATE)
                {
                case o_door.DOOR_MODE.WATERSTONE:

                    door.locked = true;
                    GUI.Box(new Rect(50, 220, 270, 20), "Water stones: " + door.required_waterstones);
                    door.required_waterstones = (int)GUI.HorizontalSlider(new Rect(50, 240, 90, 20), door.required_waterstones, 0, 30);
                    break;

                case o_door.DOOR_MODE.NONE:
                    door.locked = false;
                    break;
                }
            }
            break;

        case "o_block":

            dataobj = null;
            break;
        }

        if (GUI.Button(new Rect(50, 260, 90, 20), "Exit"))
        {
            dataobj = null;
        }
    }
 public bool IsCharacter(Vector3 mousePositon, s_object obj)
 {
     if (obj != null)
     {
         if (obj.GetType() == typeof(o_character))
         {
             return(true);
         }
     }
     return(false);
 }
    private void OnGUI()
    {
        Vector3 mousepos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        switch (TOOLKIT)
        {
        case TOOLKT.BRUSH:

            break;

        case TOOLKT.EDIT:

            if (dataobj == null)
            {
                s_object obj = Grid.GetObjectFromGrid(new Vector3(mousepos.x, mousepos.y, z * Grid.GetNodeLength));
                if (obj == null)
                {
                    break;
                }
                object otype = obj.GetType();

                if (Input.GetMouseButtonDown(0))
                {
                    dataobj = obj;
                }
            }
            else
            {
                DisplayData(dataobj);
            }

            break;
        }

        z_depth        = (int)GUI.VerticalSlider(new Rect(45, 55, 150, 75), z_depth, 0, 10);
        wordsiz_temp.x = (int)GUI.HorizontalSlider(new Rect(32, 23, 150, 23), wordsiz_temp.x, 1, 45);
        wordsiz_temp.y = (int)GUI.VerticalSlider(new Rect(32, 45, 23, 150), wordsiz_temp.y, 1, 45);
        GUI.Label(new Rect(0, 0, 90, 90), "(" + wordsiz_temp.x + ", " + wordsiz_temp.y + ")" + " Z-Fill: " + z_depth);
    }
    private void Update()
    {
        if (PlayerPrefs.GetInt("MonsterMode") == 0)
        {
            if (Players.Count < 10)
            {
                PlayerCount.text = "0" + Players.Count;
            }
            else
            {
                PlayerCount.text = "" + Players.Count;
            }

            if (Enemies.Count < 10)
            {
                EnemyCount.text = "0" + Enemies.Count;
            }
            else
            {
                EnemyCount.text = "" + Enemies.Count;
            }
        }
        else
        {
            if (Players.Count < 10)
            {
                PlayerCount.text = "0" + Enemies.Count;
            }
            else
            {
                PlayerCount.text = "" + Enemies.Count;
            }

            if (Enemies.Count < 10)
            {
                EnemyCount.text = "0" + Players.Count;
            }
            else
            {
                EnemyCount.text = "" + Players.Count;
            }
        }

        Vector3 mousePositon = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        if (player == null)
        {
            pathfcost  = 0;
            stats.text = "Nothing";
        }

        if (GetWinner == VICTORY_DICTATOR.ENEMY)
        {
            s_camera.staticCam.StartCoroutine(s_camera.staticCam.Fade(Color.black, 0.3f));

            game_on = false;
            if (s_camera.staticCam.isfaded)
            {
                UnityEngine.SceneManagement.SceneManager.LoadScene("Title");
            }
        }


        if (game_on)
        {
            switch (STATES)
            {
            case STATEMACHINE.IDLE:

                switch (TURNSTATE)
                {
                case TURNS.PLAYER:
                    if (Input.GetMouseButtonDown(0))
                    {
                        if (CheckForObject(mousePositon))
                        {
                            s_object obj = GetObjectFromWorld(mousePositon);
                            if (IsCharacter(mousePositon, obj))
                            {
                                o_character obselect = obj.GetComponent <o_character>();
                                if (obselect.health > 0)
                                {
                                    if (obselect.playable)
                                    {
                                        pathfcost = 0;
                                        SwitchCharacter((o_character)obj);
                                        CheckCharacterSurroundings(false);
                                    }
                                    player = obselect;
                                    STATES = STATEMACHINE.SELECT_CHAR;
                                }
                            }
                        }
                    }
                    break;

                    #region ENEMY
                case TURNS.ENEMY:

                    if (EnemyQueue.Count > 0)
                    {
                        //print("Chara " + EnemyQueue.Peek());
                        player = EnemyQueue.Peek();
                        //print("pl " + player);
                        STATES = STATEMACHINE.SELECT_CHAR;
                    }
                    else
                    {
                        s_camera.staticCam.StartCoroutine(s_camera.staticCam.Fade(Color.clear, 4));
                        if (s_camera.staticCam.isfaded)
                        {
                            print("Progress END: " + EnemyQueue.Count);
                            EndTurn();
                        }
                    }

                    break;
                    #endregion
                }

                break;

            case STATEMACHINE.SELECT_CHAR:

                switch (TURNSTATE)
                {
                case TURNS.PLAYER:

                    if (player.current_item != null)
                    {
                        stats.text = player.name + "\n" + "Item: " + player.current_item.name;
                    }
                    else
                    {
                        stats.text = player.name;
                    }

                    //actionpoints = "AP: " + player.actionPoints + "/" + player.maxActionPoints;

                    if (CheckForObject(mousePositon))
                    {
                        if (Input.GetMouseButtonDown(0))
                        {
                            CheckCharacterSurroundings(false);
                            s_object obj = GetObjectFromWorld(mousePositon);

                            if (obj != null)
                            {
                                if (obj.GetType() == typeof(o_character))
                                {
                                    o_character chara = obj.GetComponent <o_character>();
                                    if (targets.Contains(chara))
                                    {
                                        if (!chara.playable)
                                        {
                                            targetToAttack = chara;
                                            STATES         = STATEMACHINE.ATTACK_SELECT;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (Input.GetMouseButtonDown(0))
                    {
                        Vector2 mousepos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

                        if (player.MoveCost(mousepos) != -1)
                        {
                            Grid.UnpaintAllNodes();
                            pathfcost = player.MoveCost(mousepos);
                            player.SetDirections(Grid.NodeFromWorld(mousepos));
                            List <o_node> dir = player.directions;

                            foreach (o_node d in dir)
                            {
                                Grid.PaintNode(Grid.NodePositionFromWorld(d), Color.yellow);
                            }
                            STATES = STATEMACHINE.MOVE_TO;
                        }
                    }

                    break;

                    #region ENEMY
                case TURNS.ENEMY:

                    if (player.current_item != null)
                    {
                        UseItem();
                    }

                    /*if (targetToAttack != null)
                     *  if (targetToAttack.health == 0 && !targetToAttack.IsDisappear())
                     *      return;
                     */
                    CheckCharacterSurroundings(true);
                    if (targets.Count == 0)
                    {
                        STATES = STATEMACHINE.MOVE_TO;
                    }
                    else
                    {
                        STATES = STATEMACHINE.ATTACK_SELECT;
                    }
                    break;
                    #endregion
                }

                //Have a cancel button where this player is no longer the focus

                //Attack button where it checks enemies

                break;

            case STATEMACHINE.MOVE_TO:

                switch (TURNSTATE)
                {
                case TURNS.PLAYER:
                    if (Input.GetMouseButtonDown(0))
                    {
                        Vector2 mousepos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                        if (player.playable)
                        {
                            if (player.actionPoints >= pathfcost)
                            {
                                if (Grid.NodeFromWorld(mousepos) == player.directions[player.directions.Count - 1])
                                {
                                    ConfirmMovement();
                                    return;
                                }
                            }
                        }

                        if (player.MoveCost(mousepos) != -1)
                        {
                            Grid.UnpaintAllNodes();
                            pathfcost = player.MoveCost(mousepos);
                            player.SetDirections(Grid.NodeFromWorld(mousepos));
                            List <o_node> dir = player.directions;

                            foreach (o_node d in dir)
                            {
                                Grid.PaintNode(Grid.NodePositionFromWorld(d), Color.yellow);
                            }
                        }
                    }

                    if (Input.GetMouseButtonDown(1))
                    {
                        Grid.UnpaintAllNodes();
                        LooseFocus();
                    }

                    break;

                    #region ENEMY
                case TURNS.ENEMY:

                    int         newcost = int.MaxValue;
                    o_character tar     = null;

                    foreach (o_character e in Players)
                    {
                        //Check around the target and pathfind for each position.
                        HashSet <o_node> aroundChar = Grid.CheckAroundNode(Grid.NodeFromWorld(e.transform.position));

                        int potentialMoveCost = int.MaxValue;
                        e.GetComponent <SpriteRenderer>().color = Color.red;
                        o_node nof = null;

                        foreach (o_node no in aroundChar)
                        {
                            if (!no.walkable)
                            {
                                continue;
                            }

                            int comp = player.MoveCost(no.position);
                            if (comp == -1)
                            {
                                continue;
                            }

                            potentialMoveCost = Mathf.Min(potentialMoveCost, comp);
                            if (potentialMoveCost == comp)
                            {
                                nof = no;
                            }
                        }

                        e.GetComponent <SpriteRenderer>().color = Color.white;
                        if (potentialMoveCost <= player.range)
                        {
                            if (potentialMoveCost <= player.actionPoints)
                            {
                                tar     = e;
                                newcost = Mathf.Min(newcost, potentialMoveCost);
                                if (newcost == potentialMoveCost)
                                {
                                    if (nof != null)
                                    {
                                        player.SetDirections(nof);
                                    }
                                }
                            }
                        }
                        else
                        {
                            continue;
                        }
                        Grid.UnpaintAllNodes();
                    }

                    if (newcost != int.MaxValue)
                    {
                        Grid.UnpaintAllNodes();
                        pathfcost = newcost;
                        if (pathfcost > 0)
                        {
                            ConfirmMovement();
                        }
                        else
                        {
                            NextEnemy();
                        }
                    }
                    else
                    {
                        NextEnemy();
                    }

                    break;
                    #endregion
                }
                //Confirm?
                //Cancecl Move

                break;

            case STATEMACHINE.ATTACK_SELECT:

                switch (TURNSTATE)
                {
                case TURNS.PLAYER:


                    if (targetToAttack != null)
                    {
                        targetToAttack.renderer.color = Color.magenta;
                    }

                    if (Input.GetMouseButtonDown(0))
                    {
                        s_object obj = GetObjectFromWorld(mousePositon);
                        if (obj != targetToAttack)
                        {
                            o_character newtarg = targets.Find(x => obj == x);

                            if (newtarg != null)
                            {
                                targetToAttack.renderer.color = Color.white;
                                targetToAttack = newtarg;
                                return;
                            }
                        }
                    }


                    if (targetToAttack.health > 0 && player.actionPoints >= 2)
                    {
                        if (Input.GetMouseButtonDown(0))
                        {
                            targetToAttack.renderer.color = Color.white;
                            STATES = STATEMACHINE.ATTACK_EXECUTE;
                        }
                    }

                    if (targetToAttack.health <= 0 || player.actionPoints < 2)
                    {
                        targetToAttack.renderer.color = Color.white;
                        LooseFocus();
                    }

                    if (Input.GetMouseButtonDown(1))
                    {
                        if (targetToAttack != null)
                        {
                            targetToAttack.renderer.color = Color.white;
                        }
                        LooseFocus();
                    }
                    break;

                    #region ENEMY
                case TURNS.ENEMY:

                    CheckCharacterSurroundings(true);
                    if (targets.Count > 0)
                    {
                        //The enemy can attack the player again if they have sufficent points
                        if (player.actionPoints >= 2)
                        {
                            targetToAttack = GetTargetWithLowestHealth();

                            if (targetToAttack.health > 0)
                            {
                                if (!isattacking && !IsSkipped)
                                {
                                    StartCoroutine(AttackingAnim());
                                }

                                if (IsSkipped)
                                {
                                    AttackCalculations(targetToAttack);
                                }
                            }
                        }
                        else
                        {
                            NextEnemy();
                        }
                    }
                    else
                    {
                        STATES = STATEMACHINE.SELECT_CHAR;
                    }

                    break;
                    #endregion
                }

                break;

            case STATEMACHINE.ATTACK_EXECUTE:

                if (!isattacking)
                {
                    StartCoroutine(AttackingAnim());
                }
                else if (TURNSTATE == TURNS.PLAYER)
                {
                    STATES = STATEMACHINE.ATTACK_SELECT;
                }

                break;

            case STATEMACHINE.WALK:
                //Call Player enumarator to walk
                //Once done go back to select char

                break;
            }
        }
    }
    public void CheckCharacterSurroundings(bool is_enemy)
    {
        //If an enemy or two appears enable the confirm attack button
        targets.Clear();
        HashSet <o_node> enemynodes = Grid.CheckAroundNode(Grid.NodeFromWorld(player.transform.position));

        foreach (o_node e in enemynodes)
        {
            s_object enemyObject = Grid.ObjectFromWorld(e);

            if (enemyObject == null)
            {
                continue;
            }

            if (enemyObject.GetType() == typeof(o_character))
            {
                o_character enemy = enemyObject.GetComponent <o_character>();

                if (PlayerPrefs.GetInt("MonsterMode") == 0)
                {
                    if (!is_enemy)
                    {
                        if (!Heroes.Contains(enemy.name))
                        {
                            targets.Add(enemy);
                        }
                    }
                    else
                    {
                        if (!Adversaries.Contains(enemy.name))
                        {
                            targets.Add(enemy);
                        }
                    }
                }
                else
                if (PlayerPrefs.GetInt("MonsterMode") == 1)
                {
                    if (!is_enemy)
                    {
                        if (!Adversaries.Contains(enemy.name))
                        {
                            targets.Add(enemy);
                        }
                    }
                    else
                    {
                        if (!Heroes.Contains(enemy.name))
                        {
                            targets.Add(enemy);
                        }
                    }
                }
            }
            else
            {
                continue;
            }
        }
    }
    new void Update()
    {
        if (CheckCollisionInside(this) != null)
        {
            s_object collidedobj = CheckCollisionInside(this);
            if (collidedobj.GetType() == typeof(o_door))
            {
                o_door d = collidedobj.GetComponent <o_door>();
                if (d.CanPass())
                {
                    reqtext = "";
                    if (d.location != "Ending")
                    {
                        saved_number_of_water = water_stones_cap;
                        gman.LoadRoom(d);
                    }
                    else
                    {
                        UnityEngine.SceneManagement.SceneManager.LoadScene("Ending");
                    }
                }
                else
                {
                    reqtext = d.PassReq();
                }
            }
            else
            if (collidedobj.GetType() == typeof(o_block))
            {
                if (collidedobj.name == "Spike")
                {
                    if (!isdying)
                    {
                        water_stones_cap = saved_number_of_water;
                        isgrounded       = false;
                        StartCoroutine(DyingAnim());
                    }
                }
            }
            else
            if (collidedobj.GetType() == typeof(o_item))
            {
                o_item i = collidedobj.GetComponent <o_item>();
                water_stones_cap++;
                grid.DespawnObject(i);
            }
        }
        else
        {
            reqtext = "";
        }
        base.Update();

        ite = "Water stones: " + water_stones_cap;

        gman.txt.text = ite + "\n" + reqtext;

        if (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0)
        {
            anim.SetBool("Walk", true);
        }
        else
        {
            anim.SetBool("Walk", false);
        }

        if (!Input.GetButton("Vertical"))
        {
            anim.SetFloat("Y", 0);
            anim.SetFloat("X", (int)Input.GetAxisRaw("Horizontal"));
            if (Input.GetKey(KeyCode.RightArrow))
            {
                vecloicty.x = speed;
            }
            if (Input.GetKey(KeyCode.LeftArrow))
            {
                vecloicty.x = -speed;
            }
        }
        if (!Input.GetButton("Horizontal"))
        {
            anim.SetFloat("X", 0);
            anim.SetFloat("Y", (int)Input.GetAxisRaw("Vertical"));
            if (Input.GetKey(KeyCode.UpArrow))
            {
                vecloicty.y = speed;
            }
            if (Input.GetKey(KeyCode.DownArrow))
            {
                vecloicty.y = -speed;
            }
        }

        if (isgrounded)
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                vecloicty.z = 5;
            }
        }
    }