From cc435284ec174910f7e33810e36c8df6d17240e6 Mon Sep 17 00:00:00 2001
From: Flashfyre <flashfireex@gmail.com>
Date: Fri, 27 Oct 2023 17:43:53 -0400
Subject: [PATCH] Update implementation of Pokeball and run commands

---
 src/battle-phases.ts      | 48 ++++++++++++++++++++++++++++-----------
 src/battle.ts             |  3 +--
 src/ui/ball-ui-handler.ts |  6 ++---
 3 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/src/battle-phases.ts b/src/battle-phases.ts
index 59d5979ac40..b49d4661d0d 100644
--- a/src/battle-phases.ts
+++ b/src/battle-phases.ts
@@ -937,6 +937,15 @@ export class CommandPhase extends FieldPhase {
   start() {
     super.start();
 
+    if (this.fieldIndex) {
+      const allyCommand = this.scene.currentBattle.turnCommands[this.fieldIndex - 1];
+      if (allyCommand.command === Command.BALL || allyCommand.command === Command.RUN)
+        this.scene.currentBattle.turnCommands[this.fieldIndex] = { command: allyCommand.command, skip: true };
+    }
+
+    if (this.scene.currentBattle.turnCommands[this.fieldIndex]?.skip)
+      return this.end();
+
     const playerPokemon = this.scene.getPlayerField()[this.fieldIndex];
 
     const moveQueue = playerPokemon.getMoveQueue();
@@ -1007,15 +1016,26 @@ export class CommandPhase extends FieldPhase {
             this.scene.ui.showText(null, 0);
             this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
           }, null, true);
-        } else if (cursor < 4) {
+        } else {
           const targets = this.scene.getEnemyField().filter(p => p.isActive(true)).map(p => p.getBattlerIndex());
-          this.scene.currentBattle.turnCommands[this.fieldIndex] = { command: Command.BALL, cursor: cursor };
-          this.scene.currentBattle.turnPokeballCounts[cursor as PokeballType]--;
-          if (targets.length > 1)
-            this.scene.unshiftPhase(new SelectTargetPhase(this.scene, this.fieldIndex));
-          else
-            this.scene.currentBattle.turnCommands[this.fieldIndex].targets = targets;
-          success = true;
+          if (targets.length > 1) {
+            this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
+            this.scene.ui.setMode(Mode.MESSAGE);
+            this.scene.ui.showText(`You can only throw a Poké Ball\nwhen there is one Pokémon remaining!`, null, () => {
+              this.scene.ui.showText(null, 0);
+              this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
+            }, null, true);
+          } else if (cursor < 4) {
+            this.scene.currentBattle.turnCommands[this.fieldIndex] = { command: Command.BALL, cursor: cursor };
+            if (targets.length > 1)
+              this.scene.unshiftPhase(new SelectTargetPhase(this.scene, this.fieldIndex));
+            else {
+              this.scene.currentBattle.turnCommands[this.fieldIndex].targets = targets;
+              if (this.fieldIndex)
+                this.scene.currentBattle.turnCommands[this.fieldIndex - 1].skip = true;
+            }
+            success = true;
+          }
         }
         break;
       case Command.POKEMON:
@@ -1039,6 +1059,8 @@ export class CommandPhase extends FieldPhase {
               ? { command: Command.POKEMON, cursor: cursor, args: args }
               : { command: Command.RUN };
             success = true;
+            if (this.fieldIndex)
+              this.scene.currentBattle.turnCommands[this.fieldIndex - 1].skip = true;
           } else if (trapTag) {
             this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
             this.scene.ui.setMode(Mode.MESSAGE);
@@ -1059,9 +1081,6 @@ export class CommandPhase extends FieldPhase {
 
   cancel() {
     if (this.fieldIndex) {
-      const lastCommand = this.scene.currentBattle.turnCommands[0];
-      if (lastCommand.command === Command.BALL)
-        this.scene.currentBattle.turnPokeballCounts[lastCommand.cursor]++;
       this.scene.unshiftPhase(new CommandPhase(this.scene, 0));
       this.scene.unshiftPhase(new CommandPhase(this.scene, 1));
       this.end();
@@ -1117,12 +1136,12 @@ export class SelectTargetPhase extends PokemonPhase {
     this.scene.ui.setMode(Mode.TARGET_SELECT, this.fieldIndex, move, (cursor: integer) => {
       this.scene.ui.setMode(Mode.MESSAGE);
       if (cursor === -1) {
-        if (turnCommand.command === Command.BALL)
-          this.scene.currentBattle.turnPokeballCounts[turnCommand.cursor]++;
         this.scene.currentBattle.turnCommands[this.fieldIndex] = null;
         this.scene.unshiftPhase(new CommandPhase(this.scene, this.fieldIndex));
       } else
         turnCommand.targets = [ cursor ];
+      if (this.scene.currentBattle.turnCommands[this.fieldIndex].command === Command.BALL && this.fieldIndex)
+        this.scene.currentBattle.turnCommands[this.fieldIndex - 1].skip = true;
       this.end();
     });
   }
@@ -1169,6 +1188,9 @@ export class TurnStartPhase extends FieldPhase {
       const pokemon = field[o];
       const turnCommand = this.scene.currentBattle.turnCommands[o];
 
+      if (turnCommand.skip)
+        continue;
+
       switch (turnCommand.command) {
         case Command.FIGHT:
           const queuedMove = turnCommand.move;
diff --git a/src/battle.ts b/src/battle.ts
index c15b9d5cfd8..0e61208423b 100644
--- a/src/battle.ts
+++ b/src/battle.ts
@@ -24,6 +24,7 @@ export interface TurnCommand {
     cursor?: integer;
     move?: QueuedMove;
     targets?: BattlerIndex[];
+    skip?: boolean;
     args?: any[];
 };
 
@@ -42,7 +43,6 @@ export default class Battle {
     public started: boolean;
     public turn: integer;
     public turnCommands: TurnCommands;
-    public turnPokeballCounts: PokeballCounts;
     public playerParticipantIds: Set<integer> = new Set<integer>();
     public escapeAttempts: integer = 0;
     public lastMove: Moves;
@@ -94,7 +94,6 @@ export default class Battle {
     incrementTurn(scene: BattleScene): void {
         this.turn++;
         this.turnCommands = Object.fromEntries(Utils.getEnumValues(BattlerIndex).map(bt => [ bt, null ]));
-        this.turnPokeballCounts = Object.assign({}, scene.pokeballCounts);
     }
 
     addParticipant(playerPokemon: PlayerPokemon): void {
diff --git a/src/ui/ball-ui-handler.ts b/src/ui/ball-ui-handler.ts
index bee1d7b4633..cab77166492 100644
--- a/src/ui/ball-ui-handler.ts
+++ b/src/ui/ball-ui-handler.ts
@@ -60,13 +60,13 @@ export default class BallUiHandler extends UiHandler {
 
     let success = false;
 
-    const pokeballTypeCount = Object.keys(this.scene.currentBattle.turnPokeballCounts).length;
+    const pokeballTypeCount = Object.keys(this.scene.pokeballCounts).length;
 
     if (button === Button.ACTION || button === Button.CANCEL) {
       const commandPhase = this.scene.getCurrentPhase() as CommandPhase;
       success = true;
       if (button === Button.ACTION && this.cursor < pokeballTypeCount) {
-        if (this.scene.currentBattle.turnPokeballCounts[this.cursor]) {
+        if (this.scene.pokeballCounts[this.cursor]) {
           if (commandPhase.handleCommand(Command.BALL, this.cursor)) {
             this.scene.ui.setMode(Mode.COMMAND, commandPhase.getFieldIndex());
             this.scene.ui.setMode(Mode.MESSAGE);
@@ -94,7 +94,7 @@ export default class BallUiHandler extends UiHandler {
   }
 
   updateCounts() {
-    this.countsText.setText(Object.values(this.scene.currentBattle.turnPokeballCounts).map(c => `x${c}`).join('\n'));
+    this.countsText.setText(Object.values(this.scene.pokeballCounts).map(c => `x${c}`).join('\n'));
   }
 
   setCursor(cursor: integer): boolean {