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); +});