diff --git a/public/images/ui/ball_window.png b/public/images/ui/ball_window.png new file mode 100644 index 00000000000..e5945888cc6 Binary files /dev/null and b/public/images/ui/ball_window.png differ diff --git a/src/battle-phase.ts b/src/battle-phase.ts index 1a5154609cd..986bfeb28ba 100644 --- a/src/battle-phase.ts +++ b/src/battle-phase.ts @@ -360,8 +360,10 @@ export class CommandPhase extends BattlePhase { } break; case Command.BALL: - this.scene.unshiftPhase(new AttemptCapturePhase(this.scene, PokeballType.POKEBALL)); - success = true; + if (cursor < 4) { + this.scene.unshiftPhase(new AttemptCapturePhase(this.scene, cursor as PokeballType)); + success = true; + } break; case Command.POKEMON: this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, cursor, true)); @@ -762,6 +764,8 @@ export class AttemptCapturePhase extends BattlePhase { start() { super.start(); + this.scene.pokeballCounts[this.pokeballType]--; + const pokemon = this.scene.getEnemyPokemon(); this.originalY = pokemon.y; diff --git a/src/battle-scene.ts b/src/battle-scene.ts index b23de5767b0..9bbef0bfae8 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -5,7 +5,7 @@ import { BattlePhase, EncounterPhase, SummonPhase, CommandPhase, NextEncounterPh import { PlayerPokemon, EnemyPokemon } from './pokemon'; import PokemonSpecies, { allSpecies, getPokemonSpecies } from './pokemon-species'; import * as Utils from './utils'; -import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonModifier, ExpBoosterModifier, ExpBoosterModifierType } from './modifier'; +import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonModifier} from './modifier'; import { PokeballType } from './pokeball'; import { Species } from './species'; import { initAutoPlay } from './auto-play'; @@ -30,7 +30,7 @@ export default class BattleScene extends Phaser.Scene { public arena: BiomeArena; public trainer: Phaser.GameObjects.Sprite; public currentBattle: Battle; - public pokeballCounts = Object.fromEntries(Utils.getEnumValues(PokeballType).map(t => [ t, 0 ])); + public pokeballCounts = Object.fromEntries(Utils.getEnumValues(PokeballType).filter(p => p <= PokeballType.MASTER_BALL).map(t => [ t, 0 ])); private party: PlayerPokemon[]; private modifierBar: ModifierBar; private modifiers: Modifier[]; @@ -107,6 +107,7 @@ export default class BattleScene extends Phaser.Scene { this.loadAtlas('overlay_hp', 'ui'); this.loadImage('overlay_exp', 'ui'); this.loadImage('level_up_stats', 'ui'); + this.loadImage('ball_window', 'ui'); this.loadImage('boolean_window', 'ui'); this.loadImage('party_bg', 'ui'); @@ -271,6 +272,8 @@ export default class BattleScene extends Phaser.Scene { Promise.all(loadPokemonAssets).then(() => { if (this.auto) initAutoPlay.apply(this, [ this.autoSpeed ]); + + this.pokeballCounts[PokeballType.POKEBALL] += 5; this.newBattle(); diff --git a/src/modifier.ts b/src/modifier.ts index 9ae12f0cb1e..07b3e495ffa 100644 --- a/src/modifier.ts +++ b/src/modifier.ts @@ -122,8 +122,8 @@ class AddPokeballModifier extends ConsumableModifier { } apply(args: any[]): boolean { - (args[0] as BattleScene).pokeballCounts[this.pokeballType] += this.count; - console.log((args[0] as BattleScene).pokeballCounts); + const pokeballCounts = (args[0] as BattleScene).pokeballCounts; + pokeballCounts[this.pokeballType] = Math.min(pokeballCounts[this.pokeballType] + this.count, 99); return true; } diff --git a/src/ui/ball-ui-handler.ts b/src/ui/ball-ui-handler.ts new file mode 100644 index 00000000000..128f92fbeed --- /dev/null +++ b/src/ui/ball-ui-handler.ts @@ -0,0 +1,123 @@ +import { CommandPhase } from "../battle-phase"; +import BattleScene from "../battle-scene"; +import { getPokeballName, PokeballType } from "../pokeball"; +import { addTextObject, TextStyle } from "../text"; +import { Command } from "./command-ui-handler"; +import { Mode } from "./ui"; +import UiHandler from "./uiHandler"; + +export default class BallUiHandler extends UiHandler { + private pokeballSelectContainer: Phaser.GameObjects.Container; + private pokeballSelectBg: Phaser.GameObjects.Image; + private countsText: Phaser.GameObjects.Text; + + private cursorObj: Phaser.GameObjects.Image; + + constructor(scene: BattleScene) { + super(scene, Mode.BALL); + } + + setup() { + const ui = this.getUi(); + + this.pokeballSelectContainer = this.scene.add.container((this.scene.game.canvas.width / 6) - 115, -49); + this.pokeballSelectContainer.setVisible(false); + ui.add(this.pokeballSelectContainer); + + this.pokeballSelectBg = this.scene.add.image(0, 0, 'ball_window'); + this.pokeballSelectBg.setOrigin(0, 1); + this.pokeballSelectContainer.add(this.pokeballSelectBg); + + let optionsTextContent = ''; + + for (let pb = 0; pb < Object.keys(this.scene.pokeballCounts).length; pb++) + optionsTextContent += `${getPokeballName(pb)}\n`; + optionsTextContent += 'CANCEL'; + const optionsText = addTextObject(this.scene, 0, 0, optionsTextContent, TextStyle.WINDOW, { align: 'right', maxLines: 6 }); + optionsText.setOrigin(0, 0); + optionsText.setPositionRelative(this.pokeballSelectBg, 42, 9); + optionsText.setLineSpacing(12); + this.pokeballSelectContainer.add(optionsText); + + this.countsText = addTextObject(this.scene, 0, 0, '', TextStyle.WINDOW, { maxLines: 5 }); + this.countsText.setPositionRelative(this.pokeballSelectBg, 18, 9); + this.countsText.setLineSpacing(12); + this.pokeballSelectContainer.add(this.countsText); + + this.setCursor(0); + } + + show(args: any[]) { + super.show(args); + + this.updateCounts(); + this.pokeballSelectContainer.setVisible(true); + this.setCursor(this.cursor); + } + + processInput(keyCode: integer) { + const keyCodes = Phaser.Input.Keyboard.KeyCodes; + const ui = this.getUi(); + + let success = false; + + const pokeballTypeCount = Object.keys(this.scene.pokeballCounts).length; + + if (keyCode === keyCodes.Z || keyCode === keyCodes.X) { + success = true; + if (keyCode === keyCodes.Z && this.cursor < pokeballTypeCount) { + if (this.scene.pokeballCounts[this.cursor]) { + (this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.BALL, this.cursor); + this.scene.ui.setMode(Mode.COMMAND); + this.scene.ui.setMode(Mode.MESSAGE); + success = true; + } else + ui.playError(); + } else { + ui.setMode(Mode.COMMAND); + success = true; + } + } else { + switch (keyCode) { + case keyCodes.UP: + success = this.setCursor(this.cursor ? this.cursor - 1 : pokeballTypeCount); + break; + case keyCodes.DOWN: + success = this.setCursor(this.cursor < pokeballTypeCount ? this.cursor + 1 : 0); + break; + } + } + + if (success) + ui.playSelect(); + } + + updateCounts() { + this.countsText.setText(Object.values(this.scene.pokeballCounts).map(c => `x${c}`).join('\n')); + } + + setCursor(cursor: integer): boolean { + const ret = super.setCursor(cursor); + + if (!this.cursorObj) { + this.cursorObj = this.scene.add.image(0, 0, 'cursor'); + this.pokeballSelectContainer.add(this.cursorObj); + } + + this.cursorObj.setPositionRelative(this.pokeballSelectBg, 12, 17 + 16 * this.cursor); + + return ret; + } + + clear() { + super.clear(); + this.pokeballSelectContainer.setVisible(false); + this.eraseCursor(); + } + + eraseCursor() { + if (this.cursorObj) + this.cursorObj.destroy(); + this.cursorObj = null; + } +} \ No newline at end of file diff --git a/src/ui/command-ui-handler.ts b/src/ui/command-ui-handler.ts index b98e74e8b76..99585bb1c1f 100644 --- a/src/ui/command-ui-handler.ts +++ b/src/ui/command-ui-handler.ts @@ -61,7 +61,7 @@ export default class CommandUiHandler extends UiHandler { success = true; break; case 1: - (this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.BALL, this.cursor); + ui.setModeWithoutClear(Mode.BALL); success = true; break; case 2: diff --git a/src/ui/switch-check-ui-handler.ts b/src/ui/switch-check-ui-handler.ts index 335fb23a5f0..33dabb4a897 100644 --- a/src/ui/switch-check-ui-handler.ts +++ b/src/ui/switch-check-ui-handler.ts @@ -34,7 +34,7 @@ export default class SwitchCheckUiHandler extends AwaitableUiHandler { switchCheckText.setLineSpacing(12); switchCheckContainer.add(switchCheckText); - this.setCursor(0) + this.setCursor(0); } show(args: any[]) { diff --git a/src/ui/ui.ts b/src/ui/ui.ts index 81221fcb259..469eaf211e7 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -7,11 +7,13 @@ import FightUiHandler from './fight-ui-handler'; import MessageUiHandler from './message-ui-handler'; import SwitchCheckUiHandler from './switch-check-ui-handler'; import ModifierSelectUiHandler from './modifier-select-ui-handler'; +import BallUiHandler from './ball-ui-handler'; export enum Mode { MESSAGE = 0, COMMAND, FIGHT, + BALL, SWITCH_CHECK, MODIFIER_SELECT, PARTY @@ -29,6 +31,7 @@ export default class UI extends Phaser.GameObjects.Container { new BattleMessageUiHandler(scene), new CommandUiHandler(scene), new FightUiHandler(scene), + new BallUiHandler(scene), new SwitchCheckUiHandler(scene), new ModifierSelectUiHandler(scene), new PartyUiHandler(scene)