Esempio n. 1
0
    public void ForceTurn(RbyTurn playerTurn, RbyTurn enemyTurn = null, bool speedTieWin = true)
    {
        bool useItem = Items[playerTurn.Move] != null;

        if (useItem)
        {
            if (playerTurn.Target != null)
            {
                UseItem(playerTurn.Move, playerTurn.Target, playerTurn.Target2);
            }
            else
            {
                UseItem(playerTurn.Move, playerTurn.Flags);
            }
        }
        else if ((playerTurn.Flags & Switch) != 0)
        {
            BattleMenu(1, 0);
            ChooseMenuItem(FindPokemon(playerTurn.Move));
            ChooseMenuItem(0);
        }
        else if (EnemyMon.UsingTrappingMove)
        {
            if (CpuRead("wTopMenuItemX") != 0x9 || CpuRead("wCurrentMenuItem") != 0)
            {
                MenuPress(Joypad.Left | Joypad.Up);
            }
        }
        else if (!BattleMon.ThrashingAbout && !BattleMon.Invulnerable)
        {
            if (CurrentMenuType != MenuType.Fight)
            {
                BattleMenu(0, 0);
            }
            int moveIndex = FindBattleMove(playerTurn.Move);

            // Reusing 'ChooseMenuItem' code, because the final AdvanceFrame advances past 'SelectEnemyMove.done',
            // and I don't have a good solution for this problem right now.
            RunUntil("_Joypad", "HandleMenuInput_.getJoypadState");
            var scroll = CalcScroll(moveIndex, CpuRead("wCurrentMenuItem"), CpuRead("wNumMovesMinusOne"), true);
            for (int i = 0; i < scroll.Amount; i++)
            {
                MenuPress(scroll.Input);
            }
            if ((CpuRead("hJoyLast") & (byte)Joypad.A) != 0)
            {
                Press(Joypad.None);
            }
            Inject(Joypad.A);
        }

        if (!(EnemyMon.StoringEnergy | EnemyMon.ChargingUp | EnemyMon.UsingRage | EnemyMon.Frozen | EnemyMon.UsingTrappingMove))
        {
            Hold(Joypad.A, SYM["SelectEnemyMove.done"]);
            A = enemyTurn != null && enemyTurn.Move != "" ? Moves[enemyTurn.Move].Id : 0;
        }

        bool playerFirst;
        int  speedtie = Hold(Joypad.A, SYM["MainInBattleLoop.speedEqual"] + 9, SYM["MainInBattleLoop.enemyMovesFirst"], SYM["MainInBattleLoop.playerMovesFirst"]);

        if (speedtie == SYM["MainInBattleLoop.enemyMovesFirst"])
        {
            playerFirst = false;
        }
        else if (speedtie == SYM["MainInBattleLoop.playerMovesFirst"])
        {
            playerFirst = true;
        }
        else
        {
            A           = speedTieWin ? 0x00 : 0xff;
            playerFirst = speedTieWin;
        }

        if (playerFirst)
        {
            if (!useItem)
            {
                ForceTurnInternal(playerTurn);
            }
            else
            {
                RunUntil(SYM["MainInBattleLoop.playerMovesFirst"] + 6);
            }
            if (enemyTurn != null)
            {
                ForceTurnInternal(enemyTurn);
            }
        }
        else
        {
            Debug.Assert(enemyTurn != null, "No enemy turn was specified even though the opponent moved first!");
            ForceTurnInternal(enemyTurn);
            if (!useItem)
            {
                ForceTurnInternal(playerTurn);
            }
        }

        CurrentMenuType = MenuType.None;

        // Semi-terrible code to get around thrash. TODO: fix
        if (BattleMon.ThrashingAbout)
        {
            if (EnemyMon.HP == 0)
            {
                if (EnemyParty.Where(mon => mon.HP > 0).Count() > 1)
                {
                    ClearTextUntil(Joypad.None, SYM["PlayCry"]);
                }
                else
                {
                    ClearText();
                }
            }
        }
        else if (!BattleMon.Invulnerable)
        {
            ClearText();
        }
    }