From 8409f39b8dd029b83916d1fb15d29b5d97b00142 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Fri, 13 Sep 2024 03:49:28 -0700 Subject: [PATCH] [Misc] Allow Meloetta's starting form to be selected (#4192) * Allow Meloetta's starting form to be selected * Meloetta won't change forms during a monotype challenge Also removes reversion to Aria form when arena resets --- src/data/pokemon-forms.ts | 16 ++++-- src/data/pokemon-species.ts | 2 +- src/test/moves/relic_song.test.ts | 81 +++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 src/test/moves/relic_song.test.ts diff --git a/src/data/pokemon-forms.ts b/src/data/pokemon-forms.ts index 20703cebe81..4fc833939e4 100644 --- a/src/data/pokemon-forms.ts +++ b/src/data/pokemon-forms.ts @@ -12,6 +12,7 @@ import { TimeOfDay } from "#enums/time-of-day"; import { getPokemonNameWithAffix } from "#app/messages"; import i18next from "i18next"; import { WeatherType } from "./weather"; +import { Challenges } from "#app/enums/challenges"; export enum FormChangeItem { NONE, @@ -345,6 +346,16 @@ export class SpeciesFormChangePostMoveTrigger extends SpeciesFormChangeMoveTrigg } } +export class MeloettaFormChangePostMoveTrigger extends SpeciesFormChangePostMoveTrigger { + override canChange(pokemon: Pokemon): boolean { + if (pokemon.scene.gameMode.hasChallenge(Challenges.SINGLE_TYPE)) { + return false; + } else { + return super.canChange(pokemon); + } + } +} + export class SpeciesDefaultFormMatchTrigger extends SpeciesFormChangeTrigger { private formKey: string; @@ -759,9 +770,8 @@ export const pokemonFormChanges: PokemonFormChanges = { new SpeciesFormChange(Species.KELDEO, "resolute", "ordinary", new SpeciesFormChangeMoveLearnedTrigger(Moves.SECRET_SWORD, false)) ], [Species.MELOETTA]: [ - new SpeciesFormChange(Species.MELOETTA, "aria", "pirouette", new SpeciesFormChangePostMoveTrigger(Moves.RELIC_SONG), true), - new SpeciesFormChange(Species.MELOETTA, "pirouette", "aria", new SpeciesFormChangePostMoveTrigger(Moves.RELIC_SONG), true), - new SpeciesFormChange(Species.MELOETTA, "pirouette", "aria", new SpeciesFormChangeActiveTrigger(false), true) + new SpeciesFormChange(Species.MELOETTA, "aria", "pirouette", new MeloettaFormChangePostMoveTrigger(Moves.RELIC_SONG), true), + new SpeciesFormChange(Species.MELOETTA, "pirouette", "aria", new MeloettaFormChangePostMoveTrigger(Moves.RELIC_SONG), true) ], [Species.GENESECT]: [ new SpeciesFormChange(Species.GENESECT, "", "shock", new SpeciesFormChangeItemTrigger(FormChangeItem.SHOCK_DRIVE)), diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 3645cb03c60..aa85c29f551 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -1893,7 +1893,7 @@ export function initSpecies() { ), new PokemonSpecies(Species.MELOETTA, 5, false, false, true, "Melody Pokémon", Type.NORMAL, Type.PSYCHIC, 0.6, 6.5, Abilities.SERENE_GRACE, Abilities.NONE, Abilities.NONE, 600, 100, 77, 77, 128, 128, 90, 3, 100, 270, GrowthRate.SLOW, null, false, true, new PokemonForm("Aria Forme", "aria", Type.NORMAL, Type.PSYCHIC, 0.6, 6.5, Abilities.SERENE_GRACE, Abilities.NONE, Abilities.NONE, 600, 100, 77, 77, 128, 128, 90, 3, 100, 270, false, null, true), - new PokemonForm("Pirouette Forme", "pirouette", Type.NORMAL, Type.FIGHTING, 0.6, 6.5, Abilities.SERENE_GRACE, Abilities.NONE, Abilities.NONE, 600, 100, 128, 90, 77, 77, 128, 3, 100, 270), + new PokemonForm("Pirouette Forme", "pirouette", Type.NORMAL, Type.FIGHTING, 0.6, 6.5, Abilities.SERENE_GRACE, Abilities.NONE, Abilities.NONE, 600, 100, 128, 90, 77, 77, 128, 3, 100, 270, false, null, true), ), new PokemonSpecies(Species.GENESECT, 5, false, false, true, "Paleozoic Pokémon", Type.BUG, Type.STEEL, 1.5, 82.5, Abilities.DOWNLOAD, Abilities.NONE, Abilities.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300, GrowthRate.SLOW, null, false, true, new PokemonForm("Normal", "", Type.BUG, Type.STEEL, 1.5, 82.5, Abilities.DOWNLOAD, Abilities.NONE, Abilities.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300, false, null, true), diff --git a/src/test/moves/relic_song.test.ts b/src/test/moves/relic_song.test.ts new file mode 100644 index 00000000000..373d88f0434 --- /dev/null +++ b/src/test/moves/relic_song.test.ts @@ -0,0 +1,81 @@ +import { Type } from "#app/data/type"; +import { Challenges } from "#app/enums/challenges"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Relic Song", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + const TIMEOUT = 20 * 1000; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([Moves.RELIC_SONG, Moves.SPLASH]) + .battleType("single") + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH) + .enemySpecies(Species.MAGIKARP) + .enemyLevel(100); + }); + + it("swaps Meloetta's form between Aria and Pirouette", async () => { + await game.classicMode.startBattle([Species.MELOETTA]); + + const meloetta = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.RELIC_SONG); + await game.toNextTurn(); + + expect(meloetta.formIndex).toBe(1); + + game.move.select(Moves.RELIC_SONG); + await game.phaseInterceptor.to("BerryPhase"); + + expect(meloetta.formIndex).toBe(0); + }, TIMEOUT); + + it("doesn't swap Meloetta's form during a mono-type challenge", async () => { + game.challengeMode.addChallenge(Challenges.SINGLE_TYPE, Type.PSYCHIC + 1, 0); + await game.challengeMode.startBattle([Species.MELOETTA]); + + const meloetta = game.scene.getPlayerPokemon()!; + + expect(meloetta.formIndex).toBe(0); + + game.move.select(Moves.RELIC_SONG); + await game.phaseInterceptor.to("BerryPhase"); + await game.toNextTurn(); + + expect(meloetta.formIndex).toBe(0); + }, TIMEOUT); + + it("doesn't swap Meloetta's form during biome change (arena reset)", async () => { + game.override + .starterForms({[Species.MELOETTA]: 1}) + .startingWave(10); + await game.classicMode.startBattle([Species.MELOETTA]); + + const meloetta = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.SPLASH); + await game.doKillOpponents(); + await game.toNextWave(); + + expect(meloetta.formIndex).toBe(1); + }, TIMEOUT); +});