diff --git a/public/images/items/leaders_crest.png b/public/images/items/leaders_crest.png new file mode 100644 index 00000000000..45cf1656374 Binary files /dev/null and b/public/images/items/leaders_crest.png differ diff --git a/public/images/items/moon_flute.png b/public/images/items/moon_flute.png new file mode 100644 index 00000000000..4237a9b29ad Binary files /dev/null and b/public/images/items/moon_flute.png differ diff --git a/public/images/items/sun_flute.png b/public/images/items/sun_flute.png new file mode 100644 index 00000000000..b7cbcdf5569 Binary files /dev/null and b/public/images/items/sun_flute.png differ diff --git a/src/data/mystery-encounters/encounters/lost-at-sea-encounter.ts b/src/data/mystery-encounters/encounters/lost-at-sea-encounter.ts index 0f0538d7542..16568d8cb7d 100644 --- a/src/data/mystery-encounters/encounters/lost-at-sea-encounter.ts +++ b/src/data/mystery-encounters/encounters/lost-at-sea-encounter.ts @@ -10,6 +10,7 @@ import { applyDamageToPokemon } from "#app/data/mystery-encounters/utils/encount import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; +import {PokemonMove} from "#app/field/pokemon"; const OPTION_1_REQUIRED_MOVE = Moves.SURF; const OPTION_2_REQUIRED_MOVE = Moves.FLY; @@ -44,8 +45,8 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with const encounter = scene.currentBattle.mysteryEncounter!; encounter.setDialogueToken("damagePercentage", String(DAMAGE_PERCENTAGE)); - encounter.setDialogueToken("option1RequiredMove", Moves[OPTION_1_REQUIRED_MOVE]); - encounter.setDialogueToken("option2RequiredMove", Moves[OPTION_2_REQUIRED_MOVE]); + encounter.setDialogueToken("option1RequiredMove", new PokemonMove(OPTION_1_REQUIRED_MOVE).getName()); + encounter.setDialogueToken("option2RequiredMove", new PokemonMove(OPTION_2_REQUIRED_MOVE).getName()); return true; }) diff --git a/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts b/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts index 230f5242a36..71a44bd6852 100644 --- a/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts +++ b/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts @@ -87,6 +87,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = ); const e4Template = trainerPartyTemplates.ELITE_FOUR; const brutalConfig = trainerConfigs[brutalTrainerType].clone(); + brutalConfig.title = trainerConfigs[brutalTrainerType].title; brutalConfig.setPartyTemplates(e4Template); // @ts-ignore brutalConfig.partyTemplateFunc = null; // Overrides gym leader party template func diff --git a/src/data/pokemon-evolutions.ts b/src/data/pokemon-evolutions.ts index 6479d620182..f9602d1386a 100644 --- a/src/data/pokemon-evolutions.ts +++ b/src/data/pokemon-evolutions.ts @@ -17,7 +17,8 @@ export enum SpeciesWildEvolutionDelay { SHORT, MEDIUM, LONG, - VERY_LONG + VERY_LONG, + NEVER } export enum EvolutionItem { @@ -39,19 +40,34 @@ export enum EvolutionItem { TART_APPLE, STRAWBERRY_SWEET, UNREMARKABLE_TEACUP, - - CHIPPED_POT = 51, - BLACK_AUGURITE, + UPGRADE, + DUBIOUS_DISC, + DRAGON_SCALE, + PRISM_SCALE, + RAZOR_CLAW, + RAZOR_FANG, + REAPER_CLOTH, + ELECTIRIZER, + MAGMARIZER, + PROTECTOR, + SACHET, + WHIPPED_DREAM, + SYRUPY_APPLE, + CHIPPED_POT, GALARICA_CUFF, GALARICA_WREATH, - PEAT_BLOCK, AUSPICIOUS_ARMOR, MALICIOUS_ARMOR, MASTERPIECE_TEACUP, + SUN_FLUTE, + MOON_FLUTE, + + BLACK_AUGURITE = 51, + PEAT_BLOCK, METAL_ALLOY, SCROLL_OF_DARKNESS, SCROLL_OF_WATERS, - SYRUPY_APPLE + LEADERS_CREST } /** @@ -222,7 +238,7 @@ export const pokemonEvolutions: PokemonEvolutions = { ], [Species.SLOWPOKE]: [ new SpeciesEvolution(Species.SLOWBRO, 37, null, null), - new SpeciesEvolution(Species.SLOWKING, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /* King's Rock */), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.SLOWKING, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.MAGNEMITE]: [ new SpeciesEvolution(Species.MAGNETON, 30, null, null) @@ -249,8 +265,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.ELECTRODE, 30, null, null) ], [Species.CUBONE]: [ - new SpeciesEvolution(Species.ALOLA_MAROWAK, 28, null, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ISLAND || p.scene.arena.biomeType === Biome.BEACH), SpeciesWildEvolutionDelay.MEDIUM), - new SpeciesEvolution(Species.MAROWAK, 28, null, null) + new SpeciesEvolution(Species.ALOLA_MAROWAK, 28, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), + new SpeciesEvolution(Species.MAROWAK, 28, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) ], [Species.TYROGUE]: [ new SpeciesEvolution(Species.HITMONLEE, 20, null, new SpeciesEvolutionCondition(p => p.stats[Stat.ATK] > p.stats[Stat.DEF])), @@ -258,8 +274,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.HITMONTOP, 20, null, new SpeciesEvolutionCondition(p => p.stats[Stat.ATK] === p.stats[Stat.DEF])) ], [Species.KOFFING]: [ - new SpeciesEvolution(Species.GALAR_WEEZING, 35, null, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.METROPOLIS || p.scene.arena.biomeType === Biome.SLUM), SpeciesWildEvolutionDelay.MEDIUM), - new SpeciesEvolution(Species.WEEZING, 35, null, null) + new SpeciesEvolution(Species.GALAR_WEEZING, 35, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), + new SpeciesEvolution(Species.WEEZING, 35, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) ], [Species.RHYHORN]: [ new SpeciesEvolution(Species.RHYDON, 42, null, null) @@ -304,7 +320,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.QUILAVA, 14, null, null) ], [Species.QUILAVA]: [ - new SpeciesEvolution(Species.HISUI_TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), + new SpeciesEvolution(Species.HISUI_TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), new SpeciesEvolution(Species.TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) ], [Species.TOTODILE]: [ @@ -652,7 +668,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.DEWOTT, 17, null, null) ], [Species.DEWOTT]: [ - new SpeciesEvolution(Species.HISUI_SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), + new SpeciesEvolution(Species.HISUI_SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), new SpeciesEvolution(Species.SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) ], [Species.PATRAT]: [ @@ -800,10 +816,10 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.BISHARP, 52, null, null) ], [Species.BISHARP]: [ - new SpeciesEvolution(Species.KINGAMBIT, 64, null, null) + new SpeciesEvolution(Species.KINGAMBIT, 1, EvolutionItem.LEADERS_CREST, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.RUFFLET]: [ - new SpeciesEvolution(Species.HISUI_BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), + new SpeciesEvolution(Species.HISUI_BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), new SpeciesEvolution(Species.BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) ], [Species.VULLABY]: [ @@ -883,20 +899,20 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.CLAWITZER, 37, null, null) ], [Species.TYRUNT]: [ - new SpeciesEvolution(Species.TYRANTRUM, 39, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.TYRANTRUM, 39, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) ], [Species.AMAURA]: [ - new SpeciesEvolution(Species.AURORUS, 39, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) + new SpeciesEvolution(Species.AURORUS, 39, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) ], [Species.GOOMY]: [ - new SpeciesEvolution(Species.HISUI_SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), + new SpeciesEvolution(Species.HISUI_SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), new SpeciesEvolution(Species.SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) ], [Species.SLIGGOO]: [ new SpeciesEvolution(Species.GOODRA, 50, null, new SpeciesEvolutionCondition(p => [ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ].indexOf(p.scene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.LONG) ], [Species.BERGMITE]: [ - new SpeciesEvolution(Species.HISUI_AVALUGG, 37, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), + new SpeciesEvolution(Species.HISUI_AVALUGG, 37, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), new SpeciesEvolution(Species.AVALUGG, 37, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) ], [Species.NOIBAT]: [ @@ -906,7 +922,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.DARTRIX, 17, null, null) ], [Species.DARTRIX]: [ - new SpeciesEvolution(Species.HISUI_DECIDUEYE, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), + new SpeciesEvolution(Species.HISUI_DECIDUEYE, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), new SpeciesEvolution(Species.DECIDUEYE, 34, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) ], [Species.LITTEN]: [ @@ -928,7 +944,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.TOUCANNON, 28, null, null) ], [Species.YUNGOOS]: [ - new SpeciesEvolution(Species.GUMSHOOS, 20, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.GUMSHOOS, 20, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) ], [Species.GRUBBIN]: [ new SpeciesEvolution(Species.CHARJABUG, 20, null, null) @@ -946,7 +962,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.ARAQUANID, 22, null, null) ], [Species.FOMANTIS]: [ - new SpeciesEvolution(Species.LURANTIS, 34, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.LURANTIS, 34, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) ], [Species.MORELULL]: [ new SpeciesEvolution(Species.SHIINOTIC, 24, null, null) @@ -973,17 +989,17 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.KOMMO_O, 45, null, null) ], [Species.COSMOG]: [ - new SpeciesEvolution(Species.COSMOEM, 43, null, null) + new SpeciesEvolution(Species.COSMOEM, 23, null, null) ], [Species.COSMOEM]: [ - new SpeciesEvolution(Species.SOLGALEO, 53, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)), - new SpeciesEvolution(Species.LUNALA, 53, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) + new SpeciesEvolution(Species.SOLGALEO, 53, EvolutionItem.SUN_FLUTE, null, SpeciesWildEvolutionDelay.VERY_LONG), + new SpeciesEvolution(Species.LUNALA, 53, EvolutionItem.MOON_FLUTE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.MELTAN]: [ new SpeciesEvolution(Species.MELMETAL, 48, null, null) ], [Species.ALOLA_RATTATA]: [ - new SpeciesEvolution(Species.ALOLA_RATICATE, 20, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) + new SpeciesEvolution(Species.ALOLA_RATICATE, 20, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) ], [Species.ALOLA_DIGLETT]: [ new SpeciesEvolution(Species.ALOLA_DUGTRIO, 26, null, null) @@ -1090,7 +1106,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.GALAR_RAPIDASH, 40, null, null) ], [Species.GALAR_FARFETCHD]: [ - new SpeciesEvolution(Species.SIRFETCHD, 30, null, null) + new SpeciesEvolution(Species.SIRFETCHD, 30, null, null, SpeciesWildEvolutionDelay.LONG) ], [Species.GALAR_SLOWPOKE]: [ new SpeciesEvolution(Species.GALAR_SLOWBRO, 1, EvolutionItem.GALARICA_CUFF, null, SpeciesWildEvolutionDelay.VERY_LONG), @@ -1106,7 +1122,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.GALAR_LINOONE, 20, null, null) ], [Species.GALAR_LINOONE]: [ - new SpeciesEvolution(Species.OBSTAGOON, 35, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) + new SpeciesEvolution(Species.OBSTAGOON, 35, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) ], [Species.GALAR_YAMASK]: [ new SpeciesEvolution(Species.RUNERIGUS, 34, null, null) @@ -1214,7 +1230,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.GLIMMORA, 35, null, null) ], [Species.GREAVARD]: [ - new SpeciesEvolution(Species.HOUNDSTONE, 30, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) + new SpeciesEvolution(Species.HOUNDSTONE, 30, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) ], [Species.FRIGIBAX]: [ new SpeciesEvolution(Species.ARCTIBAX, 35, null, null) @@ -1226,8 +1242,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.CLODSIRE, 20, null, null) ], [Species.PIKACHU]: [ - new SpeciesFormEvolution(Species.ALOLA_RAICHU, "", "", 1, EvolutionItem.THUNDER_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ISLAND || p.scene.arena.biomeType === Biome.BEACH), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.ALOLA_RAICHU, "partner", "", 1, EvolutionItem.THUNDER_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ISLAND || p.scene.arena.biomeType === Biome.BEACH), SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ALOLA_RAICHU, "", "", 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ALOLA_RAICHU, "partner", "", 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.RAICHU, "", "", 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.RAICHU, "partner", "", 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG) ], @@ -1255,7 +1271,7 @@ export const pokemonEvolutions: PokemonEvolutions = { ], [Species.POLIWHIRL]: [ new SpeciesEvolution(Species.POLIWRATH, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG), - new SpeciesEvolution(Species.POLITOED, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /* King's Rock */), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.POLITOED, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.WEEPINBELL]: [ new SpeciesEvolution(Species.VICTREEBEL, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG) @@ -1267,7 +1283,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.CLOYSTER, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.EXEGGCUTE]: [ - new SpeciesEvolution(Species.ALOLA_EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ISLAND || p.scene.arena.biomeType === Biome.BEACH), SpeciesWildEvolutionDelay.LONG), + new SpeciesEvolution(Species.ALOLA_EXEGGUTOR, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.TANGELA]: [ @@ -1280,12 +1296,12 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.EEVEE]: [ - new SpeciesFormEvolution(Species.SYLVEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(70, p => !!p.getMoveset().find(m => m?.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.SYLVEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(70, p => !!p.getMoveset().find(m => m?.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.ESPEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(70, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.ESPEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(70, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.UMBREON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(70, p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.UMBREON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(70, p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.SYLVEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => !!p.getMoveset().find(m => m?.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.SYLVEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => !!p.getMoveset().find(m => m?.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ESPEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ESPEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.UMBREON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.UMBREON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.VAPOREON, "", "", 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.VAPOREON, "partner", "", 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.JOLTEON, "", "", 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG), @@ -1329,10 +1345,10 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.DUDUNSPARCE, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.HYPER_DRILL).length > 0), SpeciesWildEvolutionDelay.LONG) ], [Species.GLIGAR]: [ - new SpeciesEvolution(Species.GLISCOR, 1, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor fang at night*/), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.GLISCOR, 1, EvolutionItem.RAZOR_FANG, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor fang at night*/), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.SNEASEL]: [ - new SpeciesEvolution(Species.WEAVILE, 1, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor claw at night*/), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.WEAVILE, 1, EvolutionItem.RAZOR_CLAW, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor claw at night*/), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.URSARING]: [ new SpeciesEvolution(Species.URSALUNA, 1, EvolutionItem.PEAT_BLOCK, null, SpeciesWildEvolutionDelay.VERY_LONG) //Ursaring does not evolve into Bloodmoon Ursaluna @@ -1362,8 +1378,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.SUDOWOODO, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.MIME_JR]: [ - new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0 && (p.scene.arena.biomeType === Biome.ICE_CAVE || p.scene.arena.biomeType === Biome.SNOWY_FOREST)), SpeciesWildEvolutionDelay.MEDIUM), - new SpeciesEvolution(Species.MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0), SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0 && (p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), SpeciesWildEvolutionDelay.MEDIUM), + new SpeciesEvolution(Species.MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0 && (p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.PANSAGE]: [ new SpeciesEvolution(Species.SIMISAGE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG) @@ -1381,8 +1397,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.WHIMSICOTT, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.PETILIL]: [ - new SpeciesEvolution(Species.HISUI_LILLIGANT, 1, EvolutionItem.SUN_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.VERY_LONG), - new SpeciesEvolution(Species.LILLIGANT, 1, EvolutionItem.SUN_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.HISUI_LILLIGANT, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.LONG), + new SpeciesEvolution(Species.LILLIGANT, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.BASCULIN]: [ new SpeciesFormEvolution(Species.BASCULEGION, "white-striped", "female", 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE), SpeciesWildEvolutionDelay.VERY_LONG), @@ -1435,7 +1451,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.APPLETUN, 1, EvolutionItem.SWEET_APPLE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.CLOBBOPUS]: [ - new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.TAUNT).length > 0), SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.TAUNT).length > 0)/*Once Taunt is implemented, change evo level to 1 and delay to LONG*/) ], [Species.SINISTEA]: [ new SpeciesFormEvolution(Species.POLTEAGEIST, "phony", "phony", 1, EvolutionItem.CRACKED_POT, null, SpeciesWildEvolutionDelay.LONG), @@ -1472,7 +1488,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.OVERQWIL, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.BARB_BARRAGE).length > 0), SpeciesWildEvolutionDelay.LONG) ], [Species.HISUI_SNEASEL]: [ - new SpeciesEvolution(Species.SNEASLER, 1, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY /* Razor claw at day*/), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.SNEASLER, 1, EvolutionItem.RAZOR_CLAW, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY /* Razor claw at day*/), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.CHARCADET]: [ new SpeciesEvolution(Species.ARMAROUGE, 1, EvolutionItem.AUSPICIOUS_ARMOR, null, SpeciesWildEvolutionDelay.LONG), @@ -1512,10 +1528,10 @@ export const pokemonEvolutions: PokemonEvolutions = { SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.RHYDON]: [ - new SpeciesEvolution(Species.RHYPERIOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /* Protector */), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.RHYPERIOR, 1, EvolutionItem.PROTECTOR, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.SEADRA]: [ - new SpeciesEvolution(Species.KINGDRA, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /* Dragon scale*/), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.KINGDRA, 1, EvolutionItem.DRAGON_SCALE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.SCYTHER]: [ new SpeciesEvolution(Species.SCIZOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition( @@ -1524,22 +1540,22 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.KLEAVOR, 1, EvolutionItem.BLACK_AUGURITE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.ELECTABUZZ]: [ - new SpeciesEvolution(Species.ELECTIVIRE, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /* Electirizer*/), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.ELECTIVIRE, 1, EvolutionItem.ELECTIRIZER, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.MAGMAR]: [ - new SpeciesEvolution(Species.MAGMORTAR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /* Magmarizer*/), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.MAGMORTAR, 1, EvolutionItem.MAGMARIZER, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.PORYGON]: [ - new SpeciesEvolution(Species.PORYGON2, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /*Upgrade*/), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.PORYGON2, 1, EvolutionItem.UPGRADE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.PORYGON2]: [ - new SpeciesEvolution(Species.PORYGON_Z, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /* Dubious disc*/), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.PORYGON_Z, 1, EvolutionItem.DUBIOUS_DISC, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.FEEBAS]: [ - new SpeciesEvolution(Species.MILOTIC, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /* Prism scale*/), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.MILOTIC, 1, EvolutionItem.PRISM_SCALE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.DUSCLOPS]: [ - new SpeciesEvolution(Species.DUSKNOIR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /* Reaper cloth*/), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.DUSKNOIR, 1, EvolutionItem.REAPER_CLOTH, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.CLAMPERL]: [ new SpeciesEvolution(Species.HUNTAIL, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE /* Deep Sea Tooth */), SpeciesWildEvolutionDelay.VERY_LONG), @@ -1558,10 +1574,10 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.ACCELGOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => !!p.scene.gameData.dexData[Species.KARRABLAST].caughtAttr), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.SPRITZEE]: [ - new SpeciesEvolution(Species.AROMATISSE, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /*Sachet*/), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.AROMATISSE, 1, EvolutionItem.SACHET, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.SWIRLIX]: [ - new SpeciesEvolution(Species.SLURPUFF, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /*Whipped Dream*/), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.SLURPUFF, 1, EvolutionItem.WHIPPED_DREAM, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.PHANTUMP]: [ new SpeciesEvolution(Species.TREVENANT, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG) @@ -1576,7 +1592,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.ANNIHILAPE, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.RAGE_FIST).length > 0), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.GOLBAT]: [ - new SpeciesEvolution(Species.CROBAT, 1, null, new SpeciesFriendshipEvolutionCondition(110), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.CROBAT, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.CHANSEY]: [ new SpeciesEvolution(Species.BLISSEY, 1, null, new SpeciesFriendshipEvolutionCondition(200), SpeciesWildEvolutionDelay.LONG) @@ -1610,29 +1626,29 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.CHANSEY, 1, null, new SpeciesFriendshipEvolutionCondition(160), SpeciesWildEvolutionDelay.SHORT) ], [Species.MUNCHLAX]: [ - new SpeciesEvolution(Species.SNORLAX, 1, null, new SpeciesFriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.SNORLAX, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG) ], [Species.RIOLU]: [ - new SpeciesEvolution(Species.LUCARIO, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.LUCARIO, 1, null, new SpeciesFriendshipEvolutionCondition(120, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG) ], [Species.WOOBAT]: [ - new SpeciesEvolution(Species.SWOOBAT, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(Species.SWOOBAT, 1, null, new SpeciesFriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.SWADLOON]: [ - new SpeciesEvolution(Species.LEAVANNY, 1, null, new SpeciesFriendshipEvolutionCondition(110), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.LEAVANNY, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG) ], [Species.TYPE_NULL]: [ - new SpeciesEvolution(Species.SILVALLY, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.SILVALLY, 1, null, new SpeciesFriendshipEvolutionCondition(100), SpeciesWildEvolutionDelay.LONG) ], [Species.ALOLA_MEOWTH]: [ - new SpeciesEvolution(Species.ALOLA_PERSIAN, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.ALOLA_PERSIAN, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG) ], [Species.SNOM]: [ new SpeciesEvolution(Species.FROSMOTH, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.GIMMIGHOUL]: [ - new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.VERY_LONG), - new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 ), SpeciesWildEvolutionDelay.VERY_LONG), + new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 ), SpeciesWildEvolutionDelay.VERY_LONG) ] }; diff --git a/src/data/pokemon-level-moves.ts b/src/data/pokemon-level-moves.ts index 93bd57ae32c..b56bab724be 100644 --- a/src/data/pokemon-level-moves.ts +++ b/src/data/pokemon-level-moves.ts @@ -1609,6 +1609,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 12, Moves.DRAGON_BREATH ], [ 16, Moves.CURSE ], [ 20, Moves.ROCK_SLIDE ], + [ 22, Moves.GYRO_BALL ], //Custom, from USUM [ 24, Moves.SCREECH ], [ 28, Moves.SAND_TOMB ], [ 32, Moves.STEALTH_ROCK ], @@ -2121,7 +2122,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 20, Moves.DOUBLE_HIT ], [ 24, Moves.SLASH ], [ 28, Moves.FOCUS_ENERGY ], - [ 30, Moves.STEEL_WING ], + [ 30, Moves.STEEL_WING ], //Custom [ 32, Moves.AGILITY ], [ 36, Moves.AIR_SLASH ], [ 40, Moves.X_SCISSOR ], @@ -7549,14 +7550,15 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.POUND ], [ 1, Moves.COPYCAT ], [ 1, Moves.BARRIER ], + [ 1, Moves.TICKLE ], //USUM [ 4, Moves.BATON_PASS ], [ 8, Moves.ENCORE ], [ 12, Moves.CONFUSION ], - [ 16, Moves.ROLE_PLAY ], + [ 16, Moves.MIMIC ], //Custom, swapped with Role Play to be closer to USUM [ 20, Moves.PROTECT ], [ 24, Moves.RECYCLE ], [ 28, Moves.PSYBEAM ], - [ 32, Moves.MIMIC ], + [ 32, Moves.ROLE_PLAY ], //Custom, swapped with Mimic [ 36, Moves.LIGHT_SCREEN ], [ 36, Moves.REFLECT ], [ 36, Moves.SAFEGUARD ], diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index 0323c6d43c4..8b96e3cefb8 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -255,7 +255,9 @@ export class TrainerConfig { name = i18next.t("trainerNames:rival"); } } + this.name = name; + return this; } @@ -899,6 +901,20 @@ export class TrainerConfig { return this; } + /** + * Sets a localized name for the trainer. This should only be used for trainers that dont use a "initFor" function and are considered "named" trainers + * @param name - The name of the trainer. + * @returns {TrainerConfig} The updated TrainerConfig instance. + */ + setLocalizedName(name: string): TrainerConfig { + // Check if the internationalization (i18n) system is initialized. + if (!getIsInitialized()) { + initI18n(); + } + this.name = i18next.t(`trainerNames:${name.toLowerCase()}`); + return this; + } + /** * Retrieves the title for the trainer based on the provided trainer slot and variant. * @param {TrainerSlot} trainerSlot - The slot to determine which title to use. Defaults to TrainerSlot.NONE. @@ -2270,21 +2286,22 @@ export const trainerConfigs: TrainerConfigs = { } p.pokeball = PokeballType.MASTER_BALL; })), - [TrainerType.VICTOR]: new TrainerConfig(++t).setName("Victor").setTitle("The Winstrates") + [TrainerType.VICTOR]: new TrainerConfig(++t).setTitle("The Winstrates").setLocalizedName("Victor") .setMoneyMultiplier(1) // The Winstrate trainers have total money multiplier of 6 .setPartyTemplates(trainerPartyTemplates.ONE_AVG_ONE_STRONG), - [TrainerType.VICTORIA]: new TrainerConfig(++t).setName("Victoria").setTitle("The Winstrates") + [TrainerType.VICTORIA]: new TrainerConfig(++t).setTitle("The Winstrates").setLocalizedName("Victoria") .setMoneyMultiplier(1) .setPartyTemplates(trainerPartyTemplates.ONE_AVG_ONE_STRONG), - [TrainerType.VIVI]: new TrainerConfig(++t).setName("Vivi").setTitle("The Winstrates") + [TrainerType.VIVI]: new TrainerConfig(++t).setTitle("The Winstrates").setLocalizedName("Vivi") .setMoneyMultiplier(1) .setPartyTemplates(trainerPartyTemplates.TWO_AVG_ONE_STRONG), - [TrainerType.VICKY]: new TrainerConfig(++t).setName("Vicky").setTitle("The Winstrates") + [TrainerType.VICKY]: new TrainerConfig(++t).setTitle("The Winstrates").setLocalizedName("Vicky") .setMoneyMultiplier(1) .setPartyTemplates(trainerPartyTemplates.ONE_AVG), - [TrainerType.VITO]: new TrainerConfig(++t).setName("Vito").setTitle("The Winstrates") + [TrainerType.VITO]: new TrainerConfig(++t).setTitle("The Winstrates").setLocalizedName("Vito") .setMoneyMultiplier(2) .setPartyTemplates(new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(2, PartyMemberStrength.STRONG))), [TrainerType.BUG_TYPE_SUPERFAN]: new TrainerConfig(++t).setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.ACE_TRAINER) .setPartyTemplates(new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE)) }; + diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 8ca7e2ab015..c94acb6f859 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -10,7 +10,7 @@ import * as Utils from "../utils"; import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from "../data/type"; import { getLevelTotalExp } from "../data/exp"; import { Stat, type PermanentStat, type BattleStat, type EffectiveStat, PERMANENT_STATS, BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat"; -import { DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, BaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempStatStageBoosterModifier, TempCritBoosterModifier, StatBoosterModifier, CritBoosterModifier, TerastallizeModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonIncrementingStatModifier } from "../modifier/modifier"; +import { DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, BaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempStatStageBoosterModifier, TempCritBoosterModifier, StatBoosterModifier, CritBoosterModifier, TerastallizeModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonIncrementingStatModifier, EvoTrackerModifier } from "../modifier/modifier"; import { PokeballType } from "../data/pokeball"; import { Gender } from "../data/gender"; import { initMoveAnim, loadMoveAnimAssets } from "../data/battle-anims"; @@ -99,6 +99,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public pauseEvolutions: boolean; public pokerus: boolean; public switchOutStatus: boolean; + public evoCounter: integer; public fusionSpecies: PokemonSpecies | null; public fusionFormIndex: integer; @@ -195,6 +196,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.metSpecies = dataSource.metSpecies ?? (this.metBiome !== -1 ? this.species.speciesId : this.species.getRootSpeciesId(true)); this.pauseEvolutions = dataSource.pauseEvolutions; this.pokerus = !!dataSource.pokerus; + this.evoCounter = dataSource.evoCounter ?? 0; this.fusionSpecies = dataSource.fusionSpecies instanceof PokemonSpecies ? dataSource.fusionSpecies : dataSource.fusionSpecies ? getPokemonSpecies(dataSource.fusionSpecies) : null; this.fusionFormIndex = dataSource.fusionFormIndex; this.fusionAbilityIndex = dataSource.fusionAbilityIndex; @@ -592,8 +594,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { // Resetting properties should not be shown on the field this.setVisible(false); - // Reset field position - this.setFieldPosition(FieldPosition.CENTER); + // Remove the offset from having a Substitute active if (this.isOffsetBySubstitute()) { this.x -= this.getSubstituteOffset()[0]; this.y -= this.getSubstituteOffset()[1]; @@ -2621,10 +2622,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return result; } - if (isCritical) { - this.scene.queueMessage(i18next.t("battle:hitResultCriticalHit")); - } - // In case of fatal damage, this tag would have gotten cleared before we could lapse it. const destinyTag = this.getTag(BattlerTagType.DESTINY_BOND); @@ -2667,6 +2664,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } + if (isCritical) { + this.scene.queueMessage(i18next.t("battle:hitResultCriticalHit")); + } + // want to include is.Fainted() in case multi hit move ends early, still want to render message if (source.turnData.hitsLeft === 1 || this.isFainted()) { switch (result) { @@ -4049,6 +4050,12 @@ export class PlayerPokemon extends Pokemon { this.updateInfo(true).then(() => resolve()); }); }; + if (preEvolution.speciesId === Species.GIMMIGHOUL) { + const evotracker = this.getHeldItems().filter(m => m instanceof EvoTrackerModifier)[0] ?? null; + if (evotracker) { + this.scene.removeModifier(evotracker); + } + } if (!this.scene.gameMode.isDaily || this.metBiome > -1) { this.scene.gameData.updateSpeciesDexIvs(this.species.speciesId, this.ivs); this.scene.gameData.setPokemonSeen(this, false); diff --git a/src/locales/en/modifier-type.json b/src/locales/en/modifier-type.json index b57073325dc..c362b3f30d4 100644 --- a/src/locales/en/modifier-type.json +++ b/src/locales/en/modifier-type.json @@ -240,6 +240,8 @@ "TOXIC_ORB": { "name": "Toxic Orb", "description": "It's a bizarre orb that exudes toxins when touched and will badly poison the holder during battle." }, "FLAME_ORB": { "name": "Flame Orb", "description": "It's a bizarre orb that gives off heat when touched and will affect the holder with a burn during battle." }, + "EVOLUTION_TRACKER_GIMMIGHOUL": { "name": "Treasures", "description": "This Pokémon loves treasure! Keep collecting treasure and something might happen!"}, + "BATON": { "name": "Baton", "description": "Allows passing along effects when switching Pokémon, which also bypasses traps." }, "SHINY_CHARM": { "name": "Shiny Charm", "description": "Dramatically increases the chance of a wild Pokémon being Shiny." }, @@ -330,6 +332,21 @@ "TART_APPLE": "Tart Apple", "STRAWBERRY_SWEET": "Strawberry Sweet", "UNREMARKABLE_TEACUP": "Unremarkable Teacup", + "UPGRADE": "Upgrade", + "DUBIOUS_DISC": "Dubious Disc", + "DRAGON_SCALE": "Dragon Scale", + "PRISM_SCALE": "Prism Scale", + "RAZOR_CLAW": "Razor Claw", + "RAZOR_FANG": "Razor Fang", + "REAPER_CLOTH": "Reaper Cloth", + "ELECTIRIZER": "Electirizer", + "MAGMARIZER": "Magmarizer", + "PROTECTOR": "Protector", + "SACHET": "Sachet", + "WHIPPED_DREAM": "Whipped Dream", + "LEADERS_CREST": "Leader's Crest", + "SUN_FLUTE": "Sun Flute", + "MOON_FLUTE": "Moon Flute", "CHIPPED_POT": "Chipped Pot", "BLACK_AUGURITE": "Black Augurite", diff --git a/src/locales/en/party-ui-handler.json b/src/locales/en/party-ui-handler.json index 338bdfaec80..8e6e8046c7e 100644 --- a/src/locales/en/party-ui-handler.json +++ b/src/locales/en/party-ui-handler.json @@ -13,6 +13,7 @@ "ALL": "All", "PASS_BATON": "Pass Baton", "UNPAUSE_EVOLUTION": "Unpause Evolution", + "PAUSE_EVOLUTION": "Pause Evolution", "REVIVE": "Revive", "RENAME": "Rename", "SELECT": "Select", @@ -24,6 +25,7 @@ "tooManyItems": "{{pokemonName}} has too many\nof this item!", "anyEffect": "It won't have any effect.", "unpausedEvolutions": "Evolutions have been unpaused for {{pokemonName}}.", + "pausedEvolutions": "Evolutions have been paused for {{pokemonName}}.", "unspliceConfirmation": "Do you really want to unsplice {{fusionName}}\nfrom {{pokemonName}}? {{fusionName}} will be lost.", "wasReverted": "{{fusionName}} was reverted to {{pokemonName}}.", "releaseConfirmation": "Do you really want to release {{pokemonName}}?", diff --git a/src/locales/es/menu.json b/src/locales/es/menu.json index ef1ae93dd82..a35025819fa 100644 --- a/src/locales/es/menu.json +++ b/src/locales/es/menu.json @@ -51,7 +51,7 @@ "renamePokemon": "Renombrar Pokémon.", "rename": "Renombrar", "nickname": "Apodo", - "errorServerDown": "¡Ups! Ha habido un problema al contactar con el servidor.\n\nPuedes mantener esta ventana abierta, el juego se reconectará automáticamente.", + "errorServerDown": "¡Ups! Ha habido un problema al contactar con el servidor.\n\nPuedes mantener esta ventana abierta,\nel juego se reconectará automáticamente.", "noSaves": "No tienes ninguna partida guardada registrada!", "tooManySaves": "¡Tienes demasiadas partidas guardadas registradas!" } diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 3703605d74e..a23a9c5ece2 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -1109,11 +1109,11 @@ class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator { } const evolutionItemPool = [ - party.filter(p => pokemonEvolutions.hasOwnProperty(p.species.speciesId)).map(p => { + party.filter(p => pokemonEvolutions.hasOwnProperty(p.species.speciesId) && (!p.pauseEvolutions || p.species.speciesId === Species.SLOWPOKE || p.species.speciesId === Species.EEVEE)).map(p => { const evolutions = pokemonEvolutions[p.species.speciesId]; return evolutions.filter(e => e.item !== EvolutionItem.NONE && (e.evoFormKey === null || (e.preFormKey || "") === p.getFormKey()) && (!e.condition || e.condition.predicate(p))); }).flat(), - party.filter(p => p.isFusion() && p.fusionSpecies && pokemonEvolutions.hasOwnProperty(p.fusionSpecies.speciesId)).map(p => { + party.filter(p => p.isFusion() && p.fusionSpecies && pokemonEvolutions.hasOwnProperty(p.fusionSpecies.speciesId) && (!p.pauseEvolutions || p.fusionSpecies.speciesId === Species.SLOWPOKE || p.fusionSpecies.speciesId === Species.EEVEE)).map(p => { const evolutions = pokemonEvolutions[p.fusionSpecies!.speciesId]; return evolutions.filter(e => e.item !== EvolutionItem.NONE && (e.evoFormKey === null || (e.preFormKey || "") === p.getFusionFormKey()) && (!e.condition || e.condition.predicate(p))); }).flat() @@ -1372,6 +1372,8 @@ export const modifierTypes = { FORM_CHANGE_ITEM: () => new FormChangeItemModifierTypeGenerator(false), RARE_FORM_CHANGE_ITEM: () => new FormChangeItemModifierTypeGenerator(true), + EVOLUTION_TRACKER_GIMMIGHOUL: () => new PokemonHeldItemModifierType("modifierType:ModifierType.EVOLUTION_TRACKER_GIMMIGHOUL", "relic_gold", (type, _args) => new Modifiers.EvoTrackerModifier(type, (_args[0] as Pokemon).id, Species.GIMMIGHOUL, 10)), + MEGA_BRACELET: () => new ModifierType("modifierType:ModifierType.MEGA_BRACELET", "mega_bracelet", (type, _args) => new Modifiers.MegaEvolutionAccessModifier(type)), DYNAMAX_BAND: () => new ModifierType("modifierType:ModifierType.DYNAMAX_BAND", "dynamax_band", (type, _args) => new Modifiers.GigantamaxAccessModifier(type)), TERA_ORB: () => new ModifierType("modifierType:ModifierType.TERA_ORB", "tera_orb", (type, _args) => new Modifiers.TerastallizeAccessModifier(type)), diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 6614ef38253..0c4d2a63802 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -840,6 +840,41 @@ export class BaseStatModifier extends PokemonHeldItemModifier { } } +export class EvoTrackerModifier extends PokemonHeldItemModifier { + protected species: Species; + protected required: integer; + readonly isTransferrable: boolean = false; + + constructor(type: ModifierType, pokemonId: integer, species: Species, required: integer, stackCount?: integer) { + super(type, pokemonId, stackCount); + this.species = species; + this.required = required; + } + + matchType(modifier: Modifier): boolean { + if (modifier instanceof EvoTrackerModifier) { + return (modifier as EvoTrackerModifier).species === this.species; + } + return false; + } + + clone(): PersistentModifier { + return new EvoTrackerModifier(this.type, this.pokemonId, this.species, this.stackCount); + } + + getArgs(): any[] { + return super.getArgs().concat(this.species); + } + + apply(args: any[]): boolean { + return true; + } + + getMaxHeldItemCount(_pokemon: Pokemon): integer { + return this.required; + } +} + /** * Currently used by Shuckle Juice item */ @@ -1272,7 +1307,7 @@ export class SpeciesCritBoosterModifier extends CritBoosterModifier { * Applies Specific Type item boosts (e.g., Magnet) */ export class AttackTypeBoosterModifier extends PokemonHeldItemModifier { - private moveType: Type; + public moveType: Type; private boostMultiplier: number; constructor(type: ModifierType, pokemonId: integer, moveType: Type, boostPercent: number, stackCount?: integer) { @@ -2372,6 +2407,15 @@ export class MoneyRewardModifier extends ConsumableModifier { scene.addMoney(moneyAmount.value); + scene.getParty().map(p => { + if (p.species?.speciesId === Species.GIMMIGHOUL || p.fusionSpecies?.speciesId === Species.GIMMIGHOUL) { + p.evoCounter++; + const modifierType: ModifierType = modifierTypes.EVOLUTION_TRACKER_GIMMIGHOUL(); + const modifier = modifierType!.newModifier(p); + scene.addModifier(modifier); + } + }); + return true; } } diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index ffd9d45b4bd..c3199166e84 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -102,7 +102,7 @@ export class MoveEffectPhase extends PokemonPhase { * (and not random target) and failed the hit check against its target (MISS), log the move * as FAILed or MISSed (depending on the conditions above) and end this phase. */ - if (!hasActiveTargets || (!move.hasAttr(VariableTargetAttr) && !move.isMultiTarget() && !targetHitChecks[this.targets[0]])) { + if (!hasActiveTargets || (!move.hasAttr(VariableTargetAttr) && !move.isMultiTarget() && !targetHitChecks[this.targets[0]] && !targets[0].getTag(ProtectedTag))) { this.stopMultiHit(); if (hasActiveTargets) { this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: this.getTarget()? getPokemonNameWithAffix(this.getTarget()!) : "" })); @@ -125,20 +125,6 @@ export class MoveEffectPhase extends PokemonPhase { /** Has the move successfully hit a target (for damage) yet? */ let hasHit: boolean = false; for (const target of targets) { - /** - * If the move missed a target, stop all future hits against that target - * and move on to the next target (if there is one). - */ - if (!targetHitChecks[target.getBattlerIndex()]) { - this.stopMultiHit(target); - this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: getPokemonNameWithAffix(target) })); - if (moveHistoryEntry.result === MoveResult.PENDING) { - moveHistoryEntry.result = MoveResult.MISS; - } - user.pushMoveHistory(moveHistoryEntry); - applyMoveAttrs(MissEffectAttr, user, null, move); - continue; - } /** The {@linkcode ArenaTagSide} to which the target belongs */ const targetSide = target.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; @@ -156,6 +142,21 @@ export class MoveEffectPhase extends PokemonPhase { && (hasConditionalProtectApplied.value || (!target.findTags(t => t instanceof DamageProtectedTag).length && target.findTags(t => t instanceof ProtectedTag).find(t => target.lapseTag(t.tagType))) || (this.move.getMove().category !== MoveCategory.STATUS && target.findTags(t => t instanceof DamageProtectedTag).find(t => target.lapseTag(t.tagType)))); + /** + * If the move missed a target, stop all future hits against that target + * and move on to the next target (if there is one). + */ + if (!isProtected && !targetHitChecks[target.getBattlerIndex()]) { + this.stopMultiHit(target); + this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: getPokemonNameWithAffix(target) })); + if (moveHistoryEntry.result === MoveResult.PENDING) { + moveHistoryEntry.result = MoveResult.MISS; + } + user.pushMoveHistory(moveHistoryEntry); + applyMoveAttrs(MissEffectAttr, user, null, move); + continue; + } + /** Does this phase represent the invoked move's first strike? */ const firstHit = (user.turnData.hitsLeft === user.turnData.hitCount); diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 92bfc627ddb..5e6c0d93c8c 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -44,6 +44,7 @@ export default class PokemonData { public pauseEvolutions: boolean; public pokerus: boolean; public usedTMs: Moves[]; + public evoCounter: integer; public fusionSpecies: Species; public fusionFormIndex: integer; @@ -95,6 +96,8 @@ export default class PokemonData { } this.pokerus = !!source.pokerus; + this.evoCounter = source.evoCounter ?? 0; + this.fusionSpecies = sourcePokemon ? sourcePokemon.fusionSpecies?.speciesId : source.fusionSpecies; this.fusionFormIndex = source.fusionFormIndex; this.fusionAbilityIndex = source.fusionAbilityIndex; diff --git a/src/test/moves/baneful_bunker.test.ts b/src/test/moves/baneful_bunker.test.ts new file mode 100644 index 00000000000..c4a3036565c --- /dev/null +++ b/src/test/moves/baneful_bunker.test.ts @@ -0,0 +1,93 @@ +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; +import GameManager from "../utils/gameManager"; +import { Species } from "#enums/species"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { BattlerIndex } from "#app/battle"; +import { StatusEffect } from "#app/enums/status-effect"; + +const TIMEOUT = 20 * 1000; + +describe("Moves - Baneful Bunker", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + + game.override.battleType("single"); + + game.override.moveset(Moves.SLASH); + + game.override.enemySpecies(Species.SNORLAX); + game.override.enemyAbility(Abilities.INSOMNIA); + game.override.enemyMoveset(Moves.BANEFUL_BUNKER); + + game.override.startingLevel(100); + game.override.enemyLevel(100); + }); + test( + "should protect the user and poison attackers that make contact", + async () => { + await game.classicMode.startBattle([Species.CHARIZARD]); + + const leadPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.SLASH); + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.phaseInterceptor.to("BerryPhase", false); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + expect(leadPokemon.status?.effect === StatusEffect.POISON).toBeTruthy(); + }, TIMEOUT + ); + test( + "should protect the user and poison attackers that make contact, regardless of accuracy checks", + async () => { + await game.classicMode.startBattle([Species.CHARIZARD]); + + const leadPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.SLASH); + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + await game.move.forceMiss(); + await game.phaseInterceptor.to("BerryPhase", false); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + expect(leadPokemon.status?.effect === StatusEffect.POISON).toBeTruthy(); + }, TIMEOUT + ); + + test( + "should not poison attackers that don't make contact", + async () => { + game.override.moveset(Moves.FLASH_CANNON); + await game.classicMode.startBattle([Species.CHARIZARD]); + + const leadPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.FLASH_CANNON); + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + await game.move.forceMiss(); + await game.phaseInterceptor.to("BerryPhase", false); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + expect(leadPokemon.status?.effect === StatusEffect.POISON).toBeFalsy(); + }, TIMEOUT + ); +}); diff --git a/src/test/moves/obstruct.test.ts b/src/test/moves/obstruct.test.ts index 539b11090de..eb12daa785d 100644 --- a/src/test/moves/obstruct.test.ts +++ b/src/test/moves/obstruct.test.ts @@ -43,6 +43,23 @@ describe("Moves - Obstruct", () => { expect(enemy.getStatStage(Stat.DEF)).toBe(-2); }, TIMEOUT); + it("bypasses accuracy checks when applying protection and defense reduction", async () => { + game.override.enemyMoveset(Array(4).fill(Moves.ICE_PUNCH)); + await game.classicMode.startBattle(); + + game.move.select(Moves.OBSTRUCT); + await game.phaseInterceptor.to("MoveEffectPhase"); + await game.move.forceMiss(); + + const player = game.scene.getPlayerPokemon()!; + const enemy = game.scene.getEnemyPokemon()!; + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(player.isFullHp()).toBe(true); + expect(enemy.getStatStage(Stat.DEF)).toBe(-2); + }, TIMEOUT + ); + it("protects from non-contact damaging moves and doesn't lower the opponent's defense by 2 stages", async () => { game.override.enemyMoveset(Array(4).fill(Moves.WATER_GUN)); await game.classicMode.startBattle(); diff --git a/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts b/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts index 5d43172f6c0..82670e32daa 100644 --- a/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts @@ -3,7 +3,6 @@ import * as MysteryEncounters from "#app/data/mystery-encounters/mystery-encount import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { getPokemonSpecies } from "#app/data/pokemon-species"; import { Biome } from "#app/enums/biome"; -import { Moves } from "#app/enums/moves"; import { MysteryEncounterType } from "#app/enums/mystery-encounter-type"; import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; @@ -16,6 +15,7 @@ import BattleScene from "#app/battle-scene"; import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; import { PartyExpPhase } from "#app/phases/party-exp-phase"; + const namespace = "mysteryEncounter:lostAtSea"; /** Blastoise for surf. Pidgeot for fly. Abra for none. */ const defaultParty = [Species.BLASTOISE, Species.PIDGEOT, Species.ABRA]; @@ -102,8 +102,8 @@ describe("Lost at Sea - Mystery Encounter", () => { const onInitResult = onInit!(scene); expect(LostAtSeaEncounter.dialogueTokens?.damagePercentage).toBe("25"); - expect(LostAtSeaEncounter.dialogueTokens?.option1RequiredMove).toBe(Moves[Moves.SURF]); - expect(LostAtSeaEncounter.dialogueTokens?.option2RequiredMove).toBe(Moves[Moves.FLY]); + expect(LostAtSeaEncounter.dialogueTokens?.option1RequiredMove).toBe("Surf"); + expect(LostAtSeaEncounter.dialogueTokens?.option2RequiredMove).toBe("Fly"); expect(onInitResult).toBe(true); }); diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index aafcdc9bb34..a793dad6a73 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -467,8 +467,8 @@ export default class PartyUiHandler extends MessageUiHandler { } else if (option === PartyOption.UNPAUSE_EVOLUTION) { this.clearOptions(); ui.playSelect(); - pokemon.pauseEvolutions = false; - this.showText(i18next.t("partyUiHandler:unpausedEvolutions", { pokemonName: getPokemonNameWithAffix(pokemon) }), undefined, () => this.showText("", 0), null, true); + pokemon.pauseEvolutions = !pokemon.pauseEvolutions; + this.showText(i18next.t(pokemon.pauseEvolutions? "partyUiHandler:pausedEvolutions" : "partyUiHandler:unpausedEvolutions", { pokemonName: getPokemonNameWithAffix(pokemon) }), undefined, () => this.showText("", 0), null, true); } else if (option === PartyOption.UNSPLICE) { this.clearOptions(); ui.playSelect(); @@ -889,7 +889,7 @@ export default class PartyUiHandler extends MessageUiHandler { this.options.push(PartyOption.SUMMARY); this.options.push(PartyOption.RENAME); - if (pokemon.pauseEvolutions && (pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) || (pokemon.isFusion() && pokemon.fusionSpecies && pokemonEvolutions.hasOwnProperty(pokemon.fusionSpecies.speciesId)))) { + if ((pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) || (pokemon.isFusion() && pokemon.fusionSpecies && pokemonEvolutions.hasOwnProperty(pokemon.fusionSpecies.speciesId)))) { this.options.push(PartyOption.UNPAUSE_EVOLUTION); } @@ -976,6 +976,8 @@ export default class PartyUiHandler extends MessageUiHandler { if (formChangeItemModifiers && option >= PartyOption.FORM_CHANGE_ITEM) { const modifier = formChangeItemModifiers[option - PartyOption.FORM_CHANGE_ITEM]; optionName = `${modifier.active ? i18next.t("partyUiHandler:DEACTIVATE") : i18next.t("partyUiHandler:ACTIVATE")} ${modifier.type.name}`; + } else if (option === PartyOption.UNPAUSE_EVOLUTION) { + optionName = `${pokemon.pauseEvolutions ? i18next.t("partyUiHandler:UNPAUSE_EVOLUTION") : i18next.t("partyUiHandler:PAUSE_EVOLUTION")}`; } else { if (this.localizedOptions.includes(option)) { optionName = i18next.t(`partyUiHandler:${PartyOption[option]}`);