public void TagOutRunner(GameObject targetToTagOut)
    {
        PlayerStatus       newBatterStatus        = null;
        GameManager        gameManager            = GameUtils.FetchGameManager();
        DialogBoxManager   dialogBoxManagerScript = GameUtils.FetchDialogBoxManager();
        PlayersTurnManager playersTurnManager     = GameUtils.FetchPlayersTurnManager();


        RunnerBehaviour tagOutRunnerBehaviourScript = PlayerUtils.FetchRunnerBehaviourScript(targetToTagOut);

        int batterCount = gameManager.AttackTeamBatterListClone.Count;

        //test in case there no one left to pick
        if (batterCount > 0)
        {
            GameObject newBatter = gameManager.AttackTeamBatterListClone.First();
            newBatterStatus = PlayerUtils.FetchPlayerStatusScript(newBatter);
            BatterBehaviour newbatterBehaviourScript = PlayerUtils.FetchBatterBehaviourScript(newBatter);
            newbatterBehaviourScript.EquipedBat = tagOutRunnerBehaviourScript.EquipedBat;
            newBatter.SetActive(true);
        }

        dialogBoxManagerScript.DisplayDialogAndTextForGivenAmountOfTime(1f, false, "TAG OUT !!!!!!!");
        tagOutRunnerBehaviourScript.EquipedBat = null;
        gameManager.AttackTeamRunnerList.Remove(targetToTagOut);
        targetToTagOut.SetActive(false);
        playersTurnManager.UpdatePlayerTurnQueue(targetToTagOut);


        int runnersCount = gameManager.AttackTeamRunnerList.Count;

        bool isRunnersAllSafeAndStaying = gameManager.AttackTeamRunnerList.TrueForAll(runner => {
            RunnerBehaviour runnerBehaviour = PlayerUtils.FetchRunnerBehaviourScript(runner);
            return(runnerBehaviour.IsSafe && runnerBehaviour.IsStaying);
        });

        if (runnersCount == 0 && batterCount == 0 || batterCount == 0 && runnersCount > 0 && isRunnersAllSafeAndStaying)
        {
            gameManager.ProcessNextInningHalf();
        }
        else if (runnersCount == 0 && batterCount > 0)
        {
            StartCoroutine(gameManager.WaitAndReinit(dialogBoxManagerScript, newBatterStatus, FieldBall));
        }
        else if (runnersCount > 0)
        {
            if (isRunnersAllSafeAndStaying && batterCount > 0)
            {
                StartCoroutine(gameManager.WaitAndReinit(dialogBoxManagerScript, newBatterStatus, FieldBall));
            }
            else
            {
                playersTurnManager.TurnState      = TurnStateEnum.FIELDER_TURN;
                PlayersTurnManager.IsCommandPhase = true;
            }
        }
    }
    public void CalculatePitcherColliderInterraction(GameObject ballGameObject, BallController ballControllerScript, GenericPlayerBehaviour genericPlayerBehaviourScript)
    {
        int runnersOnFieldCount   = -1;
        List <GameObject> runners = PlayerUtils.GetRunnersOnField();

        runnersOnFieldCount = runners.Count;

        if (runnersOnFieldCount < 1)
        {
            return;
        }

        //Choose the runner who just hit the ball
        GameObject runnerToGetOut = runners.Last();

        bool hasIntercepted = false;
        PlayersTurnManager playersTurnManager = GameUtils.FetchPlayersTurnManager();

        if (ballControllerScript.BallHeight == BallHeightEnum.HIGH || ballControllerScript.BallHeight == BallHeightEnum.LOW)
        {
            GameManager      gameManager            = GameUtils.FetchGameManager();
            DialogBoxManager dialogBoxManagerScript = GameUtils.FetchDialogBoxManager();
            dialogBoxManagerScript.DisplayDialogAndTextForGivenAmountOfTime(1f, false, "TAG OUT !!!!!!!");

            ballControllerScript.Target = null;


            PlayerActionsManager.InterceptBall(ballGameObject, ballControllerScript, genericPlayerBehaviourScript);
            hasIntercepted = true;

            gameManager.AttackTeamRunnerList.Remove(runnerToGetOut);
            runnerToGetOut.SetActive(false);
            playersTurnManager.UpdatePlayerTurnQueue(runnerToGetOut);
            gameManager.AttackTeamBatterListClone.First().SetActive(true);
            RunnerBehaviour runnerBehaviourScript = PlayerUtils.FetchRunnerBehaviourScript(runnerToGetOut);
            BatterBehaviour batterBehaviourScript = PlayerUtils.FetchBatterBehaviourScript(gameManager.AttackTeamBatterListClone.First());
            batterBehaviourScript.EquipedBat = runnerBehaviourScript.EquipedBat;
            runnerBehaviourScript.EquipedBat = null;

            if (runnersOnFieldCount == 1)
            {
                GameData.isPaused = true;
                StartCoroutine(gameManager.WaitAndReinit(dialogBoxManagerScript, PlayerUtils.FetchPlayerStatusScript(gameManager.AttackTeamBatterListClone.First()), FieldBall));
                return;
            }
            else
            {
                GameObject bat = batterBehaviourScript.EquipedBat;
                bat.transform.SetParent(null);
                bat.transform.position = FieldUtils.GetBatCorrectPosition(batterBehaviourScript.transform.position);
                bat.transform.rotation = Quaternion.Euler(0f, 0f, -70f);
                bat.transform.SetParent(gameManager.AttackTeamBatterListClone.First().transform);
                batterBehaviourScript.EquipedBat.SetActive(true);
                TeamUtils.AddPlayerTeamMember(PlayerFieldPositionEnum.BATTER, batterBehaviourScript.gameObject, TeamUtils.GetBaseballPlayerOwner(batterBehaviourScript.gameObject));
            }
        }

        if (runnersOnFieldCount >= 1)
        {
            if (!hasIntercepted)
            {
                PlayerActionsManager.InterceptBall(ballGameObject, ballControllerScript, genericPlayerBehaviourScript);
            }

            PlayerActionsManager playerActionsManager = GameUtils.FetchPlayerActionsManager();
            PlayerAbilities      playerAbilities      = PlayerUtils.FetchPlayerAbilitiesScript(this.gameObject);
            playerAbilities.ReinitAbilities();
            PlayerAbility passPlayerAbility = new PlayerAbility("Pass to fielder", AbilityTypeEnum.BASIC, AbilityCategoryEnum.NORMAL, playerActionsManager.GenericPassAction, this.gameObject, true);
            playerAbilities.AddAbility(passPlayerAbility);
            playersTurnManager.TurnState      = TurnStateEnum.PITCHER_TURN;
            PlayersTurnManager.IsCommandPhase = true;
        }
    }
    public void CalculateRunnerColliderInterraction(BaseEnum baseReached, bool isNextRunnerTurnPossible = false)
    {
        Debug.Log(this.name + " interracted with " + baseReached.ToString());
        this.CurrentBase = baseReached;

        PlayerStatus playerStatusScript = PlayerUtils.FetchPlayerStatusScript(this.gameObject);

        this.EnableMovement = false;

        PlayersTurnManager   playersTurnManager   = GameUtils.FetchPlayersTurnManager();
        TurnAvailabilityEnum turnAvailabilityEnum = TurnAvailabilityEnum.READY;

        switch (baseReached)
        {
        case BaseEnum.HOME_BASE:

            if (baseReached == BaseEnum.HOME_BASE && !this.HasPassedThroughThreeFirstBases())
            {
                Debug.Log("Get on HOME BASE FIRST TIME !!");
                this.NextBase = BaseEnum.FIRST_BASE;
                playersTurnManager.TurnState = TurnStateEnum.STANDBY;
                playersTurnManager.UpdatePlayerTurnAvailability(this.gameObject.name, turnAvailabilityEnum);
            }
            else
            {
                Debug.Log("Get on HOME BASE to mark a point");
                Debug.Log("WIN ONE POINT !!!");
                this.Target   = null;
                this.NextBase = this.CurrentBase;
                playerStatusScript.IsAllowedToMove = false;
                this.HasReachedHomeBase            = true;

                PlayerEnum        playerEnum = playerStatusScript.PlayerOwner;
                TeamsScoreManager teamsScoreManagerScript = GameUtils.FetchTeamsScoreManager();
                teamsScoreManagerScript.IncrementTeamScore(GameData.teamIdEnumMap[playerEnum]);
                this.IsStaying = true;
                IsoRenderer.ReinitializeAnimator();
                GameManager gameManager = GameUtils.FetchGameManager();

                this.gameObject.SetActive(false);
                gameManager.AttackTeamRunnerList.Remove(this.gameObject);
                playersTurnManager.UpdatePlayerTurnQueue(this.gameObject);
                gameManager.AttackTeamRunnerHomeList.Add(this.gameObject);

                int batterCount = gameManager.AttackTeamBatterListClone.Count;
                if (this.EquipedBat != null && batterCount > 0)
                {
                    GameObject      newBatter = gameManager.AttackTeamBatterListClone.First();
                    BatterBehaviour newbatterBehaviourScript = PlayerUtils.FetchBatterBehaviourScript(newBatter);
                    newbatterBehaviourScript.EquipedBat = this.EquipedBat;
                    this.EquipedBat = null;
                    gameManager.EquipBatToPlayer(newBatter);
                }

                int runnersCount = gameManager.AttackTeamRunnerList.Count;

                bool isRunnersAllSafeAndStaying = gameManager.AttackTeamRunnerList.TrueForAll(runner => {
                    RunnerBehaviour runnerBehaviour = PlayerUtils.FetchRunnerBehaviourScript(runner);
                    return(runnerBehaviour.IsSafe && runnerBehaviour.IsStaying);
                });

                if (runnersCount == 0 && batterCount == 0 || batterCount == 0 && runnersCount > 0 && isRunnersAllSafeAndStaying)
                {
                    gameManager.IsStateCheckAllowed = false;
                    gameManager.ProcessNextInningHalf();
                }
                else
                {
                    gameManager.IsStateCheckAllowed = true;
                }
            }

            break;

        case BaseEnum.FIRST_BASE:
            Debug.Log("Get on FIRST BASE");

            this.NextBase            = BaseEnum.SECOND_BASE;
            this.HasReachedFirstBase = true;
            if (this.IsInWalkState)
            {
                this.IsInWalkState   = false;
                turnAvailabilityEnum = TurnAvailabilityEnum.WAITING;
                IsoRenderer.ReinitializeAnimator();
            }

            playersTurnManager.UpdatePlayerTurnAvailability(this.gameObject.name, turnAvailabilityEnum);
            break;

        case BaseEnum.SECOND_BASE:
            Debug.Log("Get on SECOND BASE");
            this.NextBase             = BaseEnum.THIRD_BASE;
            this.HasReachedSecondBase = true;
            playersTurnManager.UpdatePlayerTurnAvailability(this.gameObject.name, turnAvailabilityEnum);
            break;

        case BaseEnum.THIRD_BASE:
            Debug.Log("Get on THIRD BASE");
            this.NextBase            = BaseEnum.HOME_BASE;
            this.HasReachedThirdBase = true;
            playersTurnManager.UpdatePlayerTurnAvailability(this.gameObject.name, turnAvailabilityEnum);
            break;

        default:
            Debug.Log("DO NOT KNOW WHAT HAPPEN");
            break;
        }

        if (isNextRunnerTurnPossible)
        {
            playersTurnManager.TurnState      = TurnStateEnum.RUNNER_TURN;
            PlayersTurnManager.IsCommandPhase = true;
        }
    }