diff --git a/src/data/move.ts b/src/data/move.ts index e6ca754e5af..7d89a4144eb 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -5858,6 +5858,9 @@ export class RemoveTypeAttr extends MoveEffectAttr { const userTypes = user.getTypes(true); const modifiedTypes = userTypes.filter(type => type !== this.removedType); + if (modifiedTypes.length === 0) { + modifiedTypes.push(Type.UNKNOWN); + } user.summonData.types = modifiedTypes; user.updateInfo(); @@ -5880,7 +5883,11 @@ export class CopyTypeAttr extends MoveEffectAttr { return false; } - user.summonData.types = target.getTypes(true); + const targetTypes = target.getTypes(true); + if (targetTypes.includes(Type.UNKNOWN) && targetTypes.indexOf(Type.UNKNOWN) > -1) { + targetTypes[targetTypes.indexOf(Type.UNKNOWN)] = Type.NORMAL; + } + user.summonData.types = targetTypes; user.updateInfo(); user.scene.queueMessage(i18next.t("moveTriggers:copyType", { pokemonName: getPokemonNameWithAffix(user), targetPokemonName: getPokemonNameWithAffix(target) })); diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index ff096add798..546d96462c2 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1244,11 +1244,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } - // the type added to Pokemon from moves like Forest's Curse or Trick Or Treat - if (this.summonData && this.summonData.addedType && !types.includes(this.summonData.addedType)) { - types.push(this.summonData.addedType); - } - // this.scene potentially can be undefined for a fainted pokemon in doubles // use optional chaining to avoid runtime errors @@ -1263,6 +1258,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } + // the type added to Pokemon from moves like Forest's Curse or Trick Or Treat + if (this.summonData && this.summonData.addedType && !types.includes(this.summonData.addedType)) { + types.push(this.summonData.addedType); + } + // If both types are the same (can happen in weird custom typing scenarios), reduce to single type if (types.length > 1 && types[0] === types[1]) { types.splice(0, 1); diff --git a/src/test/moves/reflect_type.test.ts b/src/test/moves/reflect_type.test.ts index 90a138c8bed..17f1eb112b7 100644 --- a/src/test/moves/reflect_type.test.ts +++ b/src/test/moves/reflect_type.test.ts @@ -1,6 +1,7 @@ import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import { Type } from "#app/data/type"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -22,21 +23,37 @@ describe("Moves - Reflect Type", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([ Moves.SPLASH ]) .ability(Abilities.BALL_FETCH) .battleType("single") .disableCrits() - .enemySpecies(Species.MAGIKARP) - .enemyAbility(Abilities.BALL_FETCH) - .enemyMoveset(Moves.SPLASH); + .enemyAbility(Abilities.BALL_FETCH); }); - it("should do X", async () => { + it("If a typeless Pokemon has additionally been affected by Forest's Curse or Trick-or-Treat, however, Reflect Type will cause the user to become a Normal type with an added Grass or Ghost type respectively", async () => { + game.override + .moveset([ Moves.FORESTS_CURSE, Moves.REFLECT_TYPE ]) + .startingLevel(60) + .enemySpecies(Species.CHARMANDER) + .enemyMoveset([ Moves.BURN_UP, Moves.SPLASH ]); await game.classicMode.startBattle([ Species.FEEBAS ]); - game.move.select(Moves.SPLASH); - await game.phaseInterceptor.to("BerryPhase"); + const playerPokemon = game.scene.getPlayerPokemon(); + const enemyPokemon = game.scene.getEnemyPokemon(); - expect(true).toBe(true); + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.BURN_UP); + await game.toNextTurn(); + + game.move.select(Moves.FORESTS_CURSE); + await game.forceEnemyMove(Moves.SPLASH); + await game.toNextTurn(); + expect(enemyPokemon?.getTypes().includes(Type.UNKNOWN)).toBe(true); + expect(enemyPokemon?.getTypes().includes(Type.GRASS)).toBe(true); + + game.move.select(Moves.REFLECT_TYPE); + await game.forceEnemyMove(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon?.getTypes()[0]).toBe(Type.NORMAL); + expect(playerPokemon?.getTypes().includes(Type.GRASS)).toBe(true); }); });