private void SetHeroTarget()
    {
        HeroActionConfirmed();

        HeroMenuAction menuAction = GetHeroMenuAction();

        menuAction.targetIndex    = this._commandSelector.GetChoice();
        menuAction.onBackCallback = this.OnTargetChooseBackCallback;

        HeroMenuAction moveMenuAction = GetPreviousHeroMenuAction();

        ActionBase heroAction = moveMenuAction.currentHeroChoices[moveMenuAction.targetIndex].action;

        switch (heroAction.targetInfo.targetType)
        {
        case TargetType.SINGLE:
            List <FightingEntity> possibleTargets = heroAction.GetAllPossibleActiveTargets(this._field.GetHeroPlayer());
            FightingEntity        target          = possibleTargets[menuAction.targetIndex];
            this._field.GetHeroPlayer().SetQueuedAction(heroAction, new List <int> {
                target.targetId
            });
            break;

        case TargetType.ALL:
            List <int> allEnemies = this._field.GetActiveEnemyObjects().Map((EnemyObject enemy) => enemy.targetId);
            this._field.GetHeroPlayer().SetQueuedAction(heroAction, allEnemies);
            break;

        default:
            break;
        }

        this._field.GetHeroPlayer().PlaySound("confirm"); //TODO: Look towards consolidating use here
        this._heroMenuActions.Push(new HeroMenuAction(MenuState.WAITING));
    }
    private List <HeroActionChoice> GetHeroActionChoices(ActionType type)
    {
        FightingEntity          heroPlayer         = this._field.GetHeroPlayer();
        List <ActionBase>       actions            = this._field.GetHeroPlayer().GetFilteredActions(type);
        List <HeroActionChoice> currentHeroChoices = new List <HeroActionChoice>();

        foreach (ActionBase action in actions)
        {
            currentHeroChoices.Add(new HeroActionChoice(action.name, action));
        }

        if (type == ActionType.BASIC)
        {
            if (_field.GetHeroPlayer().GetFilteredActions(ActionType.MAGIC).Count != 0)
            {
                currentHeroChoices.Insert(1, new HeroActionChoice("Magic", null));
            }
        }

        HeroMenuAction menuAction = GetHeroMenuAction();

        menuAction.targetIndex        = 0;
        menuAction.currentHeroChoices = currentHeroChoices;

        return(currentHeroChoices);
    }
    private void GoBackToLastHeroAction()
    {
        this._playerActionCounter = 0;
        this._heroMenuActions.Pop();
        HeroMenuAction menuAction = GetHeroMenuAction();

        if (menuAction.onBackCallback != null)
        {
            menuAction.onBackCallback();
        }
    }
    public HeroMenuAction GetPreviousHeroMenuAction()
    {
        HeroMenuAction top = GetHeroMenuAction();

        this._heroMenuActions.Pop();

        HeroMenuAction previousHeroAction = GetHeroMenuAction();

        this._heroMenuActions.Push(top);

        return(previousHeroAction);
    }
    private void SetHeroAction()
    {
        HeroMenuAction menuAction = GetHeroMenuAction();

        menuAction.targetIndex    = this._commandSelector.GetChoice();
        menuAction.onBackCallback = this.OnActionChooseBackCallback;

        HeroActionChoice choice = menuAction.currentHeroChoices[menuAction.targetIndex];

        if (choice.choiceName == "Magic" && choice.action == null)
        {
            this._heroMenuActions.Push(new HeroMenuAction(MenuState.MAGIC));
            InitializeCommandCardActionUI(GetHeroActionChoices(ActionType.MAGIC));
        }
        else
        {
            ActionBase heroAction = choice.action;

            if (!heroAction.CheckCost(this._field.GetHeroPlayer()))
            {
                return;
            }

            this._ui.commandCardUI.SetConfirmed();

            if (heroAction.targetInfo.targetTeam != TargetTeam.NONE && heroAction.targetInfo.targetType != TargetType.RANDOM)
            {
                List <FightingEntity> possibleTargets = heroAction.GetAllPossibleActiveTargets(_field.GetHeroPlayer());
                switch (heroAction.targetInfo.targetType)
                {
                case TargetType.SINGLE:
                    this._ui.targetSelectionUI.InitializeTargetSelectionSingle(possibleTargets, 0, this._commandSelector);
                    break;

                case TargetType.ALL:
                    this._commandSelector.Initialize(0, 1, null);     // Only one choice
                    this._ui.targetSelectionUI.InitializeTargetSelectionAll(possibleTargets);
                    break;

                default:
                    Debug.LogError("ERROR: Did not consider target type");
                    break;
                }

                this._heroMenuActions.Push(new HeroMenuAction(MenuState.TARGET));
            }
            else if (heroAction.targetInfo.targetTeam == TargetTeam.NONE)
            {
                HeroActionConfirmed();
                GetHeroMenuAction().onBackCallback = this.OnActionChooseBackCallback;
                this._field.GetHeroPlayer().SetQueuedAction(heroAction, new List <int>());
                CheckExecuteTurn();
                this._field.GetHeroPlayer().PlaySound("confirm"); //TODO: Look towards consolidating use here
                this._heroMenuActions.Push(new HeroMenuAction(MenuState.WAITING));
            }
            else if (heroAction.targetInfo.targetType == TargetType.RANDOM)
            {
                HeroActionConfirmed();
                GetHeroMenuAction().onBackCallback = this.OnActionChooseBackCallback;
                this._field.GetHeroPlayer().SetQueuedAction(heroAction, new List <int> {
                    this._field.GetRandomEnemyObjectIndex()
                });
                CheckExecuteTurn();
                this._field.GetHeroPlayer().PlaySound("confirm"); //TODO: Look towards consolidating use here
                this._heroMenuActions.Push(new HeroMenuAction(MenuState.WAITING));
            }
            else
            {
                Debug.LogError("ERROR: Unexpected target type");
            }
        }
    }
    // Helper Coroutines
    IEnumerator HeroMoveSelection()
    {
        FightingEntity hero = this._field.GetHeroPlayer();

        if (!hero.HasModifier(ModifierAilment.MODIFIER_CANNOT_USE_ACTION))
        {
            this._heroMenuActions.Push(new HeroMenuAction(MenuState.MOVE));
            InitializeCommandCardActionUI(GetHeroActionChoices(ActionType.BASIC));
        }
        else
        {
            this.HeroActionConfirmed();
            this._heroMenuActions.Push(new HeroMenuAction(MenuState.WAITING));
        }

        while (true)
        {
            HeroMenuAction menuAction = this.GetHeroMenuAction();
            MenuState      menuState  = menuAction.menuState;
            switch (menuState)
            {
            case MenuState.MOVE:
                if (Input.GetKeyDown(KeyCode.Z))
                {
                    SetHeroAction();
                }
                break;

            case MenuState.TARGET:
                if (Input.GetKeyDown(KeyCode.Z))
                {
                    SetHeroTarget();
                }
                break;

            case MenuState.MAGIC:
                if (Input.GetKeyDown(KeyCode.Z))
                {
                    SetHeroAction();
                }
                break;

            default:
                break;
            }

            if (_heroMenuActions.Count > 1)
            {
                // Go back a menu
                if (Input.GetKeyDown(KeyCode.X))
                {
                    GoBackToLastHeroAction();
                }
            }

            if (Input.GetKeyDown(KeyCode.L))
            {
                _playerActionCounter = this.maxTimeBeforeAction;
            }

            if (hero.HasSetCommand())
            {
                _playerActionCounter += Time.deltaTime;
            }

            if (this.CheckExecuteTurn())
            {
                break;
            }
            yield return(null);
        }
    }