mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-24 00:09:31 +02:00
Merge branch 'beta' into dev/phaseInterceptor-cleanup
This commit is contained in:
commit
f4197c7489
@ -17,7 +17,12 @@ If you have the motivation and experience with Typescript/Javascript (or are wil
|
||||
2. Run `npm run start:dev` to locally run the project in `localhost:8000`
|
||||
|
||||
#### Linting
|
||||
We're using ESLint as our common linter and formatter. It will run automatically during the pre-commit hook but if you would like to manually run it, use the `npm run eslint` script.
|
||||
We're using ESLint as our common linter and formatter. It will run automatically during the pre-commit hook but if you would like to manually run it, use the `npm run eslint` script. To view the complete rules, check out the [eslint.config.js](./eslint.config.js) file.
|
||||
|
||||
### 📚 Documentation
|
||||
You can find the auto-generated documentation [here](https://pagefaultgames.github.io/pokerogue/main/index.html).
|
||||
For information on enemy AI, check out the [enemy-ai.md](./docs/enemy-ai.md) file.
|
||||
For detailed guidelines on documenting your code, refer to the [comments.md](./docs/comments.md) file.
|
||||
|
||||
### ❔ FAQ
|
||||
|
||||
|
@ -853,14 +853,14 @@
|
||||
"spriteSourceSize": { "x": 7, "y": 2, "w": 27, "h": 26 },
|
||||
"sourceSize": { "w": 40, "h": 30 }
|
||||
},
|
||||
"981_2.png": {
|
||||
"981_2": {
|
||||
"frame": { "x": 108, "y": 87, "w": 23, "h": 30 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 9, "y": 0, "w": 23, "h": 30 },
|
||||
"sourceSize": { "w": 40, "h": 30 }
|
||||
},
|
||||
"981_3.png": {
|
||||
"981_3": {
|
||||
"frame": { "x": 246, "y": 86, "w": 23, "h": 30 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
|
@ -1,57 +1,57 @@
|
||||
import Phaser from "phaser";
|
||||
import UI from "./ui/ui";
|
||||
import Pokemon, { EnemyPokemon, PlayerPokemon } from "./field/pokemon";
|
||||
import PokemonSpecies, { allSpecies, getPokemonSpecies, PokemonSpeciesFilter } from "./data/pokemon-species";
|
||||
import UI from "#app/ui/ui";
|
||||
import Pokemon, { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon";
|
||||
import PokemonSpecies, { allSpecies, getPokemonSpecies, PokemonSpeciesFilter } from "#app/data/pokemon-species";
|
||||
import { Constructor, isNullOrUndefined, randSeedInt } from "#app/utils";
|
||||
import * as Utils from "./utils";
|
||||
import * as Utils from "#app/utils";
|
||||
import { ConsumableModifier, ConsumablePokemonModifier, DoubleBattleChanceBoosterModifier, ExpBalanceModifier, ExpShareModifier, FusePokemonModifier, HealingBoosterModifier, Modifier, ModifierBar, ModifierPredicate, MultipleParticipantExpBonusModifier, overrideHeldItems, overrideModifiers, PersistentModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, TerastallizeModifier, TurnHeldItemTransferModifier } from "./modifier/modifier";
|
||||
import { PokeballType } from "./data/pokeball";
|
||||
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "./data/battle-anims";
|
||||
import { Phase } from "./phase";
|
||||
import { initGameSpeed } from "./system/game-speed";
|
||||
import { Arena, ArenaBase } from "./field/arena";
|
||||
import { GameData } from "./system/game-data";
|
||||
import { addTextObject, getTextColor, TextStyle } from "./ui/text";
|
||||
import { allMoves } from "./data/move";
|
||||
import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getModifierType, getPartyLuckValue, ModifierPoolType, modifierTypes, PokemonHeldItemModifierType } from "./modifier/modifier-type";
|
||||
import AbilityBar from "./ui/ability-bar";
|
||||
import { allAbilities, applyAbAttrs, applyPostBattleInitAbAttrs, BlockItemTheftAbAttr, ChangeMovePriorityAbAttr, DoubleBattleChanceAbAttr, PostBattleInitAbAttr } from "./data/ability";
|
||||
import Battle, { BattleType, FixedBattleConfig } from "./battle";
|
||||
import { GameMode, GameModes, getGameMode } from "./game-mode";
|
||||
import FieldSpritePipeline from "./pipelines/field-sprite";
|
||||
import SpritePipeline from "./pipelines/sprite";
|
||||
import PartyExpBar from "./ui/party-exp-bar";
|
||||
import { trainerConfigs, TrainerSlot } from "./data/trainer-config";
|
||||
import Trainer, { TrainerVariant } from "./field/trainer";
|
||||
import TrainerData from "./system/trainer-data";
|
||||
import { PokeballType } from "#app/data/pokeball";
|
||||
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "#app/data/battle-anims";
|
||||
import { Phase } from "#app/phase";
|
||||
import { initGameSpeed } from "#app/system/game-speed";
|
||||
import { Arena, ArenaBase } from "#app/field/arena";
|
||||
import { GameData } from "#app/system/game-data";
|
||||
import { addTextObject, getTextColor, TextStyle } from "#app/ui/text";
|
||||
import { allMoves } from "#app/data/move";
|
||||
import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getModifierType, getPartyLuckValue, ModifierPoolType, modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||
import AbilityBar from "#app/ui/ability-bar";
|
||||
import { allAbilities, applyAbAttrs, applyPostBattleInitAbAttrs, BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, PostBattleInitAbAttr } from "#app/data/ability";
|
||||
import Battle, { BattleType, FixedBattleConfig } from "#app/battle";
|
||||
import { GameMode, GameModes, getGameMode } from "#app/game-mode";
|
||||
import FieldSpritePipeline from "#app/pipelines/field-sprite";
|
||||
import SpritePipeline from "#app/pipelines/sprite";
|
||||
import PartyExpBar from "#app/ui/party-exp-bar";
|
||||
import { trainerConfigs, TrainerSlot } from "#app/data/trainer-config";
|
||||
import Trainer, { TrainerVariant } from "#app/field/trainer";
|
||||
import TrainerData from "#app/system/trainer-data";
|
||||
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
||||
import { pokemonPrevolutions } from "./data/balance/pokemon-evolutions";
|
||||
import PokeballTray from "./ui/pokeball-tray";
|
||||
import InvertPostFX from "./pipelines/invert";
|
||||
import { Achv, achvs, ModifierAchv, MoneyAchv } from "./system/achv";
|
||||
import { Voucher, vouchers } from "./system/voucher";
|
||||
import { Gender } from "./data/gender";
|
||||
import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
||||
import PokeballTray from "#app/ui/pokeball-tray";
|
||||
import InvertPostFX from "#app/pipelines/invert";
|
||||
import { Achv, achvs, ModifierAchv, MoneyAchv } from "#app/system/achv";
|
||||
import { Voucher, vouchers } from "#app/system/voucher";
|
||||
import { Gender } from "#app/data/gender";
|
||||
import UIPlugin from "phaser3-rex-plugins/templates/ui/ui-plugin";
|
||||
import { addUiThemeOverrides } from "./ui/ui-theme";
|
||||
import PokemonData from "./system/pokemon-data";
|
||||
import { Nature } from "./data/nature";
|
||||
import { FormChangeItem, pokemonFormChanges, SpeciesFormChange, SpeciesFormChangeManualTrigger, SpeciesFormChangeTimeOfDayTrigger, SpeciesFormChangeTrigger } from "./data/pokemon-forms";
|
||||
import { FormChangePhase } from "./phases/form-change-phase";
|
||||
import { getTypeRgb } from "./data/type";
|
||||
import PokemonSpriteSparkleHandler from "./field/pokemon-sprite-sparkle-handler";
|
||||
import CharSprite from "./ui/char-sprite";
|
||||
import DamageNumberHandler from "./field/damage-number-handler";
|
||||
import PokemonInfoContainer from "./ui/pokemon-info-container";
|
||||
import { biomeDepths, getBiomeName } from "./data/balance/biomes";
|
||||
import { SceneBase } from "./scene-base";
|
||||
import CandyBar from "./ui/candy-bar";
|
||||
import { Variant, variantData } from "./data/variant";
|
||||
import { addUiThemeOverrides } from "#app/ui/ui-theme";
|
||||
import PokemonData from "#app/system/pokemon-data";
|
||||
import { Nature } from "#app/data/nature";
|
||||
import { FormChangeItem, pokemonFormChanges, SpeciesFormChange, SpeciesFormChangeManualTrigger, SpeciesFormChangeTimeOfDayTrigger, SpeciesFormChangeTrigger } from "#app/data/pokemon-forms";
|
||||
import { FormChangePhase } from "#app/phases/form-change-phase";
|
||||
import { getTypeRgb } from "#app/data/type";
|
||||
import PokemonSpriteSparkleHandler from "#app/field/pokemon-sprite-sparkle-handler";
|
||||
import CharSprite from "#app/ui/char-sprite";
|
||||
import DamageNumberHandler from "#app/field/damage-number-handler";
|
||||
import PokemonInfoContainer from "#app/ui/pokemon-info-container";
|
||||
import { biomeDepths, getBiomeName } from "#app/data/balance/biomes";
|
||||
import { SceneBase } from "#app/scene-base";
|
||||
import CandyBar from "#app/ui/candy-bar";
|
||||
import { Variant, variantData } from "#app/data/variant";
|
||||
import { Localizable } from "#app/interfaces/locales";
|
||||
import Overrides from "#app/overrides";
|
||||
import { InputsController } from "./inputs-controller";
|
||||
import { UiInputs } from "./ui-inputs";
|
||||
import { NewArenaEvent } from "./events/battle-scene";
|
||||
import { ArenaFlyout } from "./ui/arena-flyout";
|
||||
import { InputsController } from "#app/inputs-controller";
|
||||
import { UiInputs } from "#app/ui-inputs";
|
||||
import { NewArenaEvent } from "#app/events/battle-scene";
|
||||
import { ArenaFlyout } from "#app/ui/arena-flyout";
|
||||
import { EaseType } from "#enums/ease-type";
|
||||
import { BattleSpec } from "#enums/battle-spec";
|
||||
import { BattleStyle } from "#enums/battle-style";
|
||||
@ -66,27 +66,27 @@ import { TimedEventManager } from "#app/timed-event-manager";
|
||||
import { PokemonAnimType } from "#enums/pokemon-anim-type";
|
||||
import i18next from "i18next";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { battleSpecDialogue } from "./data/dialogue";
|
||||
import { LoadingScene } from "./loading-scene";
|
||||
import { LevelCapPhase } from "./phases/level-cap-phase";
|
||||
import { LoginPhase } from "./phases/login-phase";
|
||||
import { MessagePhase } from "./phases/message-phase";
|
||||
import { MovePhase } from "./phases/move-phase";
|
||||
import { NewBiomeEncounterPhase } from "./phases/new-biome-encounter-phase";
|
||||
import { NextEncounterPhase } from "./phases/next-encounter-phase";
|
||||
import { PokemonAnimPhase } from "./phases/pokemon-anim-phase";
|
||||
import { QuietFormChangePhase } from "./phases/quiet-form-change-phase";
|
||||
import { ReturnPhase } from "./phases/return-phase";
|
||||
import { SelectBiomePhase } from "./phases/select-biome-phase";
|
||||
import { ShowTrainerPhase } from "./phases/show-trainer-phase";
|
||||
import { SummonPhase } from "./phases/summon-phase";
|
||||
import { SwitchPhase } from "./phases/switch-phase";
|
||||
import { TitlePhase } from "./phases/title-phase";
|
||||
import { ToggleDoublePositionPhase } from "./phases/toggle-double-position-phase";
|
||||
import { TurnInitPhase } from "./phases/turn-init-phase";
|
||||
import { ShopCursorTarget } from "./enums/shop-cursor-target";
|
||||
import MysteryEncounter from "./data/mystery-encounters/mystery-encounter";
|
||||
import { allMysteryEncounters, ANTI_VARIANCE_WEIGHT_MODIFIER, AVERAGE_ENCOUNTERS_PER_RUN_TARGET, BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT, MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT, mysteryEncountersByBiome, WEIGHT_INCREMENT_ON_SPAWN_MISS } from "./data/mystery-encounters/mystery-encounters";
|
||||
import { battleSpecDialogue } from "#app/data/dialogue";
|
||||
import { LoadingScene } from "#app/loading-scene";
|
||||
import { LevelCapPhase } from "#app/phases/level-cap-phase";
|
||||
import { LoginPhase } from "#app/phases/login-phase";
|
||||
import { MessagePhase } from "#app/phases/message-phase";
|
||||
import { MovePhase } from "#app/phases/move-phase";
|
||||
import { NewBiomeEncounterPhase } from "#app/phases/new-biome-encounter-phase";
|
||||
import { NextEncounterPhase } from "#app/phases/next-encounter-phase";
|
||||
import { PokemonAnimPhase } from "#app/phases/pokemon-anim-phase";
|
||||
import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase";
|
||||
import { ReturnPhase } from "#app/phases/return-phase";
|
||||
import { SelectBiomePhase } from "#app/phases/select-biome-phase";
|
||||
import { ShowTrainerPhase } from "#app/phases/show-trainer-phase";
|
||||
import { SummonPhase } from "#app/phases/summon-phase";
|
||||
import { SwitchPhase } from "#app/phases/switch-phase";
|
||||
import { TitlePhase } from "#app/phases/title-phase";
|
||||
import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase";
|
||||
import { TurnInitPhase } from "#app/phases/turn-init-phase";
|
||||
import { ShopCursorTarget } from "#app/enums/shop-cursor-target";
|
||||
import MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { allMysteryEncounters, ANTI_VARIANCE_WEIGHT_MODIFIER, AVERAGE_ENCOUNTERS_PER_RUN_TARGET, BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT, MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT, mysteryEncountersByBiome, WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters";
|
||||
import { MysteryEncounterSaveData } from "#app/data/mystery-encounters/mystery-encounter-save-data";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
@ -94,7 +94,7 @@ import HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||
import { ExpPhase } from "#app/phases/exp-phase";
|
||||
import { ShowPartyExpBarPhase } from "#app/phases/show-party-exp-bar-phase";
|
||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||
import { ExpGainsSpeed } from "./enums/exp-gains-speed";
|
||||
import { ExpGainsSpeed } from "#enums/exp-gains-speed";
|
||||
|
||||
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
|
||||
|
||||
@ -2359,17 +2359,6 @@ export default class BattleScene extends SceneBase {
|
||||
return false;
|
||||
}
|
||||
|
||||
pushMovePhase(movePhase: MovePhase, priorityOverride?: integer): void {
|
||||
const movePriority = new Utils.IntegerHolder(priorityOverride !== undefined ? priorityOverride : movePhase.move.getMove().priority);
|
||||
applyAbAttrs(ChangeMovePriorityAbAttr, movePhase.pokemon, null, false, movePhase.move.getMove(), movePriority);
|
||||
const lowerPriorityPhase = this.phaseQueue.find(p => p instanceof MovePhase && p.move.getMove().priority < movePriority.value);
|
||||
if (lowerPriorityPhase) {
|
||||
this.phaseQueue.splice(this.phaseQueue.indexOf(lowerPriorityPhase), 0, movePhase);
|
||||
} else {
|
||||
this.pushPhase(movePhase);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to add the input phase to index before target phase in the phaseQueue, else simply calls unshiftPhase()
|
||||
* @param phase {@linkcode Phase} the phase to be added
|
||||
|
@ -1107,12 +1107,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.QUILLADIN,
|
||||
Species.CHESNAUGHT,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.BUNNELBY,
|
||||
Species.DIGGERSBY,
|
||||
Species.FLETCHLING,
|
||||
@ -2878,12 +2873,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.DELPHOX,
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.BUNNELBY,
|
||||
Species.DIGGERSBY,
|
||||
Species.FLETCHLING,
|
||||
@ -3910,7 +3900,6 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.YAMPER,
|
||||
Species.BOLTUND,
|
||||
Species.ZAMAZENTA,
|
||||
Species.URSHIFU,
|
||||
Species.ZARUDE,
|
||||
Species.GLASTRIER,
|
||||
Species.WYRDEER,
|
||||
@ -3940,6 +3929,10 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.ALOLA_NINETALES,
|
||||
Species.ALOLA_PERSIAN,
|
||||
Species.ALOLA_GOLEM,
|
||||
[
|
||||
Species.URSHIFU,
|
||||
"single-strike",
|
||||
],
|
||||
Species.HISUI_GROWLITHE,
|
||||
Species.HISUI_ARCANINE,
|
||||
Species.HISUI_TYPHLOSION,
|
||||
@ -6987,14 +6980,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -8301,7 +8287,6 @@ export const tmSpecies: TmSpecies = {
|
||||
[
|
||||
Species.WORMADAM,
|
||||
"sandy",
|
||||
"trash",
|
||||
],
|
||||
Species.ALOLA_SANDSHREW,
|
||||
Species.ALOLA_SANDSLASH,
|
||||
@ -8612,12 +8597,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.CHESNAUGHT,
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.BUNNELBY,
|
||||
Species.DIGGERSBY,
|
||||
Species.LITLEO,
|
||||
@ -9406,14 +9386,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -9766,14 +9739,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.DELPHOX,
|
||||
Species.VIVILLON,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.ESPURR,
|
||||
Species.MEOWSTIC,
|
||||
@ -11147,14 +11113,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -13657,12 +13616,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.DELPHOX,
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.FLETCHLING,
|
||||
Species.FLETCHINDER,
|
||||
Species.TALONFLAME,
|
||||
@ -15326,14 +15280,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -16934,14 +16881,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -18483,14 +18423,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -20250,14 +20183,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -21583,12 +21509,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.DELPHOX,
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.BUNNELBY,
|
||||
Species.DIGGERSBY,
|
||||
Species.LITLEO,
|
||||
@ -22516,7 +22437,6 @@ export const tmSpecies: TmSpecies = {
|
||||
[
|
||||
Species.WORMADAM,
|
||||
"sandy",
|
||||
"trash",
|
||||
],
|
||||
Species.ALOLA_DIGLETT,
|
||||
Species.ALOLA_DUGTRIO,
|
||||
@ -22691,14 +22611,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.CHESNAUGHT,
|
||||
Species.VIVILLON,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -23402,12 +23315,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.DELPHOX,
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.BUNNELBY,
|
||||
Species.DIGGERSBY,
|
||||
Species.FLETCHLING,
|
||||
@ -24134,12 +24042,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.KELDEO,
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.PANCHAM,
|
||||
Species.PANGORO,
|
||||
Species.HONEDGE,
|
||||
@ -24842,14 +24745,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -25712,14 +25608,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -26695,14 +26584,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -27845,14 +27727,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -28911,14 +28786,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -29514,14 +29382,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.DELPHOX,
|
||||
Species.VIVILLON,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.ESPURR,
|
||||
Species.MEOWSTIC,
|
||||
@ -31408,14 +31269,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -32327,14 +32181,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -33037,14 +32884,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -33471,7 +33311,6 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.ARCTOVISH,
|
||||
Species.ZACIAN,
|
||||
Species.ZAMAZENTA,
|
||||
Species.URSHIFU,
|
||||
Species.ZARUDE,
|
||||
Species.REGIDRAGO,
|
||||
Species.GLASTRIER,
|
||||
@ -33522,6 +33361,10 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.ALOLA_MUK,
|
||||
Species.GALAR_MEOWTH,
|
||||
Species.GALAR_STUNFISK,
|
||||
[
|
||||
Species.URSHIFU,
|
||||
"single-strike",
|
||||
],
|
||||
[
|
||||
Species.CALYREX,
|
||||
"ice",
|
||||
@ -36644,14 +36487,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -37389,14 +37225,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.BUNNELBY,
|
||||
Species.DIGGERSBY,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -38266,23 +38095,11 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.DELPHOX,
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -39323,12 +39140,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.CHESPIN,
|
||||
Species.QUILLADIN,
|
||||
Species.CHESNAUGHT,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.BUNNELBY,
|
||||
Species.DIGGERSBY,
|
||||
Species.SKIDDO,
|
||||
@ -40356,7 +40168,10 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.FENNEKIN,
|
||||
Species.BRAIXEN,
|
||||
Species.DELPHOX,
|
||||
[
|
||||
Species.MEOWSTIC,
|
||||
"male",
|
||||
],
|
||||
Species.KLEFKI,
|
||||
Species.PHANTUMP,
|
||||
Species.TREVENANT,
|
||||
@ -41805,7 +41620,6 @@ export const tmSpecies: TmSpecies = {
|
||||
[
|
||||
Species.WORMADAM,
|
||||
"sandy",
|
||||
"trash",
|
||||
],
|
||||
Species.ALOLA_SANDSHREW,
|
||||
Species.ALOLA_SANDSLASH,
|
||||
@ -43701,12 +43515,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.DELPHOX,
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.BUNNELBY,
|
||||
Species.DIGGERSBY,
|
||||
Species.SKIDDO,
|
||||
@ -44160,14 +43969,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.QUILLADIN,
|
||||
Species.CHESNAUGHT,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -44377,14 +44179,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.DELPHOX,
|
||||
Species.VIVILLON,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.ESPURR,
|
||||
Species.MEOWSTIC,
|
||||
@ -45256,6 +45051,10 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.IRON_CROWN,
|
||||
Species.TERAPAGOS,
|
||||
Species.ALOLA_EXEGGUTOR,
|
||||
[
|
||||
Species.INDEEDEE,
|
||||
"male",
|
||||
],
|
||||
],
|
||||
[Moves.GYRO_BALL]: [
|
||||
Species.SQUIRTLE,
|
||||
@ -47501,12 +47300,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.ACCELGOR,
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.SKRELP,
|
||||
Species.DRAGALGE,
|
||||
Species.MAREANIE,
|
||||
@ -48143,7 +47937,6 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.RUNERIGUS,
|
||||
Species.MORPEKO,
|
||||
Species.DURALUDON,
|
||||
Species.URSHIFU,
|
||||
Species.ZARUDE,
|
||||
Species.SPECTRIER,
|
||||
Species.OVERQWIL,
|
||||
@ -48179,6 +47972,10 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.GALAR_WEEZING,
|
||||
Species.GALAR_MOLTRES,
|
||||
Species.GALAR_YAMASK,
|
||||
[
|
||||
Species.URSHIFU,
|
||||
"single-strike",
|
||||
],
|
||||
[
|
||||
Species.CALYREX,
|
||||
"shadow",
|
||||
@ -48456,14 +48253,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.QUILLADIN,
|
||||
Species.CHESNAUGHT,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -49622,7 +49412,10 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.TORTERRA,
|
||||
Species.BUDEW,
|
||||
Species.ROSERADE,
|
||||
[
|
||||
Species.WORMADAM,
|
||||
"plant",
|
||||
],
|
||||
Species.MOTHIM,
|
||||
Species.CHERUBI,
|
||||
Species.CHERRIM,
|
||||
@ -49698,14 +49491,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.CHESNAUGHT,
|
||||
Species.VIVILLON,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -52635,7 +52421,10 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.TORTERRA,
|
||||
Species.BUDEW,
|
||||
Species.ROSERADE,
|
||||
[
|
||||
Species.WORMADAM,
|
||||
"plant",
|
||||
],
|
||||
Species.SNOVER,
|
||||
Species.ABOMASNOW,
|
||||
Species.TANGROWTH,
|
||||
@ -53751,7 +53540,10 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.BIBAREL,
|
||||
Species.BUDEW,
|
||||
Species.ROSERADE,
|
||||
[
|
||||
Species.WORMADAM,
|
||||
"plant",
|
||||
],
|
||||
Species.PACHIRISU,
|
||||
Species.CHERUBI,
|
||||
Species.CHERRIM,
|
||||
@ -53863,14 +53655,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.BUNNELBY,
|
||||
Species.DIGGERSBY,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -55590,12 +55375,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.CHESPIN,
|
||||
Species.QUILLADIN,
|
||||
Species.CHESNAUGHT,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.PANCHAM,
|
||||
Species.PANGORO,
|
||||
Species.HELIOPTILE,
|
||||
@ -55877,7 +55657,6 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.MR_RIME,
|
||||
Species.MORPEKO,
|
||||
Species.DURALUDON,
|
||||
Species.URSHIFU,
|
||||
Species.SPECTRIER,
|
||||
Species.MEOWSCARADA,
|
||||
Species.SQUAWKABILLY,
|
||||
@ -55918,6 +55697,10 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.GALAR_MOLTRES,
|
||||
Species.GALAR_SLOWKING,
|
||||
Species.GALAR_STUNFISK,
|
||||
[
|
||||
Species.URSHIFU,
|
||||
"single-strike",
|
||||
],
|
||||
[
|
||||
Species.CALYREX,
|
||||
"shadow",
|
||||
@ -56577,14 +56360,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -57019,14 +56795,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.PANCHAM,
|
||||
Species.PANGORO,
|
||||
@ -57354,14 +57123,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.BRAIXEN,
|
||||
Species.DELPHOX,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.ESPURR,
|
||||
Species.MEOWSTIC,
|
||||
@ -58997,7 +58759,6 @@ export const tmSpecies: TmSpecies = {
|
||||
[
|
||||
Species.WORMADAM,
|
||||
"sandy",
|
||||
"trash",
|
||||
],
|
||||
Species.ALOLA_SANDSHREW,
|
||||
Species.ALOLA_SANDSLASH,
|
||||
@ -60070,7 +59831,6 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.DURALUDON,
|
||||
Species.ZACIAN,
|
||||
Species.ZAMAZENTA,
|
||||
Species.URSHIFU,
|
||||
Species.ZARUDE,
|
||||
Species.GLASTRIER,
|
||||
Species.SPECTRIER,
|
||||
@ -60116,6 +59876,10 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.HISUI_ZOROARK,
|
||||
Species.HISUI_BRAVIARY,
|
||||
Species.BLOODMOON_URSALUNA,
|
||||
[
|
||||
Species.URSHIFU,
|
||||
"single-strike",
|
||||
],
|
||||
],
|
||||
[Moves.PHANTOM_FORCE]: [
|
||||
Species.HAUNTER,
|
||||
@ -60446,14 +60210,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.QUILLADIN,
|
||||
Species.CHESNAUGHT,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -60529,16 +60286,12 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.WHIMSICOTT,
|
||||
Species.ALOMOMOLA,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
[
|
||||
Species.MEOWSTIC,
|
||||
"male",
|
||||
],
|
||||
Species.SPRITZEE,
|
||||
Species.AROMATISSE,
|
||||
Species.SYLVEON,
|
||||
@ -61402,14 +61155,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -61899,14 +61645,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.MELOETTA,
|
||||
Species.DELPHOX,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SPRITZEE,
|
||||
Species.AROMATISSE,
|
||||
@ -62617,7 +62356,6 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.SIRFETCHD,
|
||||
Species.FALINKS,
|
||||
Species.PINCURCHIN,
|
||||
Species.URSHIFU,
|
||||
Species.ZARUDE,
|
||||
Species.GLASTRIER,
|
||||
Species.TAROUNTULA,
|
||||
@ -62647,6 +62385,10 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.GALAR_ZAPDOS,
|
||||
Species.GALAR_CORSOLA,
|
||||
Species.GALAR_LINOONE,
|
||||
[
|
||||
Species.URSHIFU,
|
||||
"single-strike",
|
||||
],
|
||||
[
|
||||
Species.CALYREX,
|
||||
"ice",
|
||||
@ -63541,12 +63283,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.KELDEO,
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.INKAY,
|
||||
Species.MALAMAR,
|
||||
Species.BINACLE,
|
||||
@ -64755,7 +64492,6 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.OBSTAGOON,
|
||||
Species.PERRSERKER,
|
||||
Species.MORPEKO,
|
||||
Species.URSHIFU,
|
||||
Species.ZARUDE,
|
||||
Species.GLASTRIER,
|
||||
Species.SPECTRIER,
|
||||
@ -64803,6 +64539,10 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.GALAR_LINOONE,
|
||||
Species.GALAR_DARMANITAN,
|
||||
Species.GALAR_STUNFISK,
|
||||
[
|
||||
Species.URSHIFU,
|
||||
"single-strike",
|
||||
],
|
||||
[
|
||||
Species.CALYREX,
|
||||
"ice",
|
||||
@ -65933,12 +65673,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.DELPHOX,
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.BUNNELBY,
|
||||
Species.DIGGERSBY,
|
||||
Species.FLETCHLING,
|
||||
@ -65950,14 +65685,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
[
|
||||
Species.FLOETTE,
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"blue",
|
||||
"white",
|
||||
],
|
||||
Species.FLORGES,
|
||||
Species.SKIDDO,
|
||||
Species.GOGOAT,
|
||||
@ -66291,6 +66019,13 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.MUNKIDORI,
|
||||
Species.FEZANDIPITI,
|
||||
Species.OGERPON,
|
||||
Species.ARCHALUDON,
|
||||
Species.HYDRAPPLE,
|
||||
Species.GOUGING_FIRE,
|
||||
Species.RAGING_BOLT,
|
||||
Species.IRON_BOULDER,
|
||||
Species.IRON_CROWN,
|
||||
Species.PECHARUNT,
|
||||
Species.GALAR_MEOWTH,
|
||||
Species.GALAR_SLOWPOKE,
|
||||
Species.GALAR_SLOWBRO,
|
||||
@ -66429,16 +66164,8 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.PIPLUP,
|
||||
Species.PRINPLUP,
|
||||
Species.EMPOLEON,
|
||||
[
|
||||
Species.SHELLOS,
|
||||
"east",
|
||||
"west",
|
||||
],
|
||||
[
|
||||
Species.GASTRODON,
|
||||
"east",
|
||||
"west",
|
||||
],
|
||||
Species.MISMAGIUS,
|
||||
Species.HAPPINY,
|
||||
Species.SNOVER,
|
||||
@ -66456,25 +66183,11 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.CUBCHOO,
|
||||
Species.BEARTIC,
|
||||
Species.CRYOGONAL,
|
||||
[
|
||||
Species.TORNADUS,
|
||||
"incarnate",
|
||||
"therian",
|
||||
],
|
||||
[
|
||||
Species.KYUREM,
|
||||
"",
|
||||
"black",
|
||||
"white",
|
||||
],
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.SKRELP,
|
||||
Species.DRAGALGE,
|
||||
Species.BERGMITE,
|
||||
@ -66482,11 +66195,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.DIANCIE,
|
||||
Species.PRIMARINA,
|
||||
Species.CRABOMINABLE,
|
||||
[
|
||||
Species.MAGEARNA,
|
||||
"",
|
||||
"original",
|
||||
],
|
||||
Species.INTELEON,
|
||||
Species.FROSMOTH,
|
||||
Species.EISCUE,
|
||||
@ -66779,12 +66488,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.CHESNAUGHT,
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.LITLEO,
|
||||
Species.PYROAR,
|
||||
Species.FLABEBE,
|
||||
@ -67007,23 +66711,14 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.WEAVILE,
|
||||
Species.GLACEON,
|
||||
Species.FROSLASS,
|
||||
[
|
||||
Species.PALKIA,
|
||||
"",
|
||||
"origin",
|
||||
],
|
||||
Species.PHIONE,
|
||||
Species.MANAPHY,
|
||||
Species.ARCEUS,
|
||||
Species.OSHAWOTT,
|
||||
Species.DEWOTT,
|
||||
Species.SAMUROTT,
|
||||
[
|
||||
Species.BASCULIN,
|
||||
"red-striped",
|
||||
"blue-striped",
|
||||
"white-striped",
|
||||
],
|
||||
Species.MINCCINO,
|
||||
Species.CINCCINO,
|
||||
Species.DUCKLETT,
|
||||
@ -67036,12 +66731,7 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.KELDEO,
|
||||
Species.FROAKIE,
|
||||
Species.FROGADIER,
|
||||
[
|
||||
Species.GRENINJA,
|
||||
"",
|
||||
"battle-bond",
|
||||
"ash",
|
||||
],
|
||||
Species.FLABEBE,
|
||||
Species.FLOETTE,
|
||||
Species.FLORGES,
|
||||
@ -67304,6 +66994,10 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.FEZANDIPITI,
|
||||
Species.ALOLA_RAICHU,
|
||||
Species.ETERNAL_FLOETTE,
|
||||
[
|
||||
Species.INDEEDEE,
|
||||
"female",
|
||||
],
|
||||
],
|
||||
[Moves.TEMPER_FLARE]: [
|
||||
Species.CHARMANDER,
|
||||
|
@ -392,16 +392,16 @@ export class Arena {
|
||||
return true;
|
||||
}
|
||||
|
||||
isMoveWeatherCancelled(user: Pokemon, move: Move) {
|
||||
return this.weather && !this.weather.isEffectSuppressed(this.scene) && this.weather.isMoveWeatherCancelled(user, move);
|
||||
public isMoveWeatherCancelled(user: Pokemon, move: Move): boolean {
|
||||
return !!this.weather && !this.weather.isEffectSuppressed(this.scene) && this.weather.isMoveWeatherCancelled(user, move);
|
||||
}
|
||||
|
||||
isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move) {
|
||||
return this.terrain && this.terrain.isMoveTerrainCancelled(user, targets, move);
|
||||
public isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move): boolean {
|
||||
return !!this.terrain && this.terrain.isMoveTerrainCancelled(user, targets, move);
|
||||
}
|
||||
|
||||
getTerrainType() : TerrainType {
|
||||
return this.terrain?.terrainType || TerrainType.NONE;
|
||||
public getTerrainType(): TerrainType {
|
||||
return this.terrain?.terrainType ?? TerrainType.NONE;
|
||||
}
|
||||
|
||||
getAttackTypeMultiplier(attackType: Type, grounded: boolean): number {
|
||||
|
@ -5027,8 +5027,12 @@ export class PokemonBattleSummonData {
|
||||
export class PokemonTurnData {
|
||||
public flinched: boolean = false;
|
||||
public acted: boolean = false;
|
||||
public hitCount: number;
|
||||
public hitsLeft: number;
|
||||
public hitCount: number = 0;
|
||||
/**
|
||||
* - `-1` = Calculate how many hits are left
|
||||
* - `0` = Move is finished
|
||||
*/
|
||||
public hitsLeft: number = -1;
|
||||
public damageDealt: number = 0;
|
||||
public currDamageDealt: number = 0;
|
||||
public damageTaken: number = 0;
|
||||
@ -5114,7 +5118,7 @@ export class PokemonMove {
|
||||
* @param {boolean} ignoreRestrictionTags If `true`, skips the check for move restriction tags (see {@link MoveRestrictionBattlerTag})
|
||||
* @returns `true` if the move can be selected and used by the Pokemon, otherwise `false`.
|
||||
*/
|
||||
isUsable(pokemon: Pokemon, ignorePp?: boolean, ignoreRestrictionTags?: boolean): boolean {
|
||||
isUsable(pokemon: Pokemon, ignorePp: boolean = false, ignoreRestrictionTags: boolean = false): boolean {
|
||||
if (this.moveId && !ignoreRestrictionTags && pokemon.isMoveRestricted(this.moveId)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
* resolve the move's total hit count. This block combines the
|
||||
* effects of the move itself, Parental Bond, and Multi-Lens to do so.
|
||||
*/
|
||||
if (user.turnData.hitsLeft === undefined) {
|
||||
if (user.turnData.hitsLeft === -1) {
|
||||
const hitCount = new Utils.IntegerHolder(1);
|
||||
// Assume single target for multi hit
|
||||
applyMoveAttrs(MultiHitAttr, user, this.getTarget() ?? null, move, hitCount);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { applyAbAttrs, applyPostMoveUsedAbAttrs, applyPreAttackAbAttrs, BlockRedirectAbAttr, IncreasePpAbAttr, PokemonTypeChangeAbAttr, PostMoveUsedAbAttr, RedirectMoveAbAttr } from "#app/data/ability";
|
||||
import { CommonAnim } from "#app/data/battle-anims";
|
||||
import { BattlerTagLapseType, CenterOfAttentionTag } from "#app/data/battler-tags";
|
||||
@ -15,236 +15,149 @@ import { StatusEffect } from "#app/enums/status-effect";
|
||||
import { MoveUsedEvent } from "#app/events/battle-scene";
|
||||
import Pokemon, { MoveResult, PokemonMove, TurnMove } from "#app/field/pokemon";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { BattlePhase } from "#app/phases/battle-phase";
|
||||
import { CommonAnimPhase } from "#app/phases/common-anim-phase";
|
||||
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
||||
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
||||
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
||||
import * as Utils from "#app/utils";
|
||||
import i18next from "i18next";
|
||||
import { BattlePhase } from "./battle-phase";
|
||||
import { CommonAnimPhase } from "./common-anim-phase";
|
||||
import { MoveEffectPhase } from "./move-effect-phase";
|
||||
import { MoveEndPhase } from "./move-end-phase";
|
||||
import { ShowAbilityPhase } from "./show-ability-phase";
|
||||
|
||||
export class MovePhase extends BattlePhase {
|
||||
public pokemon: Pokemon;
|
||||
public move: PokemonMove;
|
||||
public targets: BattlerIndex[];
|
||||
protected _pokemon: Pokemon;
|
||||
protected _move: PokemonMove;
|
||||
protected _targets: BattlerIndex[];
|
||||
protected followUp: boolean;
|
||||
protected ignorePp: boolean;
|
||||
protected failed: boolean;
|
||||
protected cancelled: boolean;
|
||||
protected failed: boolean = false;
|
||||
protected cancelled: boolean = false;
|
||||
|
||||
constructor(scene: BattleScene, pokemon: Pokemon, targets: BattlerIndex[], move: PokemonMove, followUp?: boolean, ignorePp?: boolean) {
|
||||
public get pokemon(): Pokemon {
|
||||
return this._pokemon;
|
||||
}
|
||||
|
||||
protected set pokemon(pokemon: Pokemon) {
|
||||
this._pokemon = pokemon;
|
||||
}
|
||||
|
||||
public get move(): PokemonMove {
|
||||
return this._move;
|
||||
}
|
||||
|
||||
protected set move(move: PokemonMove) {
|
||||
this._move = move;
|
||||
}
|
||||
|
||||
public get targets(): BattlerIndex[] {
|
||||
return this._targets;
|
||||
}
|
||||
|
||||
protected set targets(targets: BattlerIndex[]) {
|
||||
this._targets = targets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param followUp Indicates that the move being uses is a "follow-up" - for example, a move being used by Metronome or Dancer.
|
||||
* Follow-ups bypass a few failure conditions, including flinches, sleep/paralysis/freeze and volatile status checks, etc.
|
||||
*/
|
||||
constructor(scene: BattleScene, pokemon: Pokemon, targets: BattlerIndex[], move: PokemonMove, followUp: boolean = false, ignorePp: boolean = false) {
|
||||
super(scene);
|
||||
|
||||
this.pokemon = pokemon;
|
||||
this.targets = targets;
|
||||
this.move = move;
|
||||
this.followUp = followUp ?? false;
|
||||
this.ignorePp = ignorePp ?? false;
|
||||
this.failed = false;
|
||||
this.cancelled = false;
|
||||
this.followUp = followUp;
|
||||
this.ignorePp = ignorePp;
|
||||
}
|
||||
|
||||
canMove(ignoreDisableTags?: boolean): boolean {
|
||||
/**
|
||||
* Checks if the pokemon is active, if the move is usable, and that the move is targetting something.
|
||||
* @param ignoreDisableTags `true` to not check if the move is disabled
|
||||
* @returns `true` if all the checks pass
|
||||
*/
|
||||
public canMove(ignoreDisableTags: boolean = false): boolean {
|
||||
return this.pokemon.isActive(true) && this.move.isUsable(this.pokemon, this.ignorePp, ignoreDisableTags) && !!this.targets.length;
|
||||
}
|
||||
|
||||
/**Signifies the current move should fail but still use PP */
|
||||
fail(): void {
|
||||
public fail(): void {
|
||||
this.failed = true;
|
||||
}
|
||||
|
||||
/**Signifies the current move should cancel and retain PP */
|
||||
cancel(): void {
|
||||
public cancel(): void {
|
||||
this.cancelled = true;
|
||||
}
|
||||
|
||||
start() {
|
||||
public start() {
|
||||
super.start();
|
||||
|
||||
console.log(Moves[this.move.moveId]);
|
||||
|
||||
// Check if move is unusable (e.g. because it's out of PP due to a mid-turn Spite).
|
||||
if (!this.canMove(true)) {
|
||||
if (this.pokemon.isActive(true) && this.move.ppUsed >= this.move.getMovePp()) { // if the move PP was reduced from Spite or otherwise, the move fails
|
||||
if (this.pokemon.isActive(true) && this.move.ppUsed >= this.move.getMovePp()) {
|
||||
this.fail();
|
||||
this.showMoveText();
|
||||
this.showFailedText();
|
||||
}
|
||||
|
||||
return this.end();
|
||||
}
|
||||
|
||||
this.pokemon.turnData.acted = true;
|
||||
|
||||
// Reset hit-related turn data when starting follow-up moves (e.g. Metronomed moves, Dancer repeats)
|
||||
if (this.followUp) {
|
||||
this.pokemon.turnData.hitsLeft = -1;
|
||||
this.pokemon.turnData.hitCount = 0;
|
||||
}
|
||||
|
||||
// Check move to see if arena.ignoreAbilities should be true.
|
||||
if (!this.followUp) {
|
||||
if (this.move.getMove().checkFlag(MoveFlags.IGNORE_ABILITIES, this.pokemon, null)) {
|
||||
this.scene.arena.setIgnoreAbilities(true, this.pokemon.getBattlerIndex());
|
||||
}
|
||||
} else {
|
||||
this.pokemon.turnData.hitsLeft = 0; // TODO: is `0` correct?
|
||||
this.pokemon.turnData.hitCount = 0; // TODO: is `0` correct?
|
||||
}
|
||||
|
||||
// Move redirection abilities (ie. Storm Drain) only support single target moves
|
||||
const moveTarget = this.targets.length === 1
|
||||
? new Utils.IntegerHolder(this.targets[0])
|
||||
: null;
|
||||
if (moveTarget) {
|
||||
const oldTarget = moveTarget.value;
|
||||
this.scene.getField(true).filter(p => p !== this.pokemon).forEach(p => applyAbAttrs(RedirectMoveAbAttr, p, null, false, this.move.moveId, moveTarget));
|
||||
this.pokemon.getOpponents().forEach(p => {
|
||||
const redirectTag = p.getTag(CenterOfAttentionTag) as CenterOfAttentionTag;
|
||||
if (redirectTag && (!redirectTag.powder || (!this.pokemon.isOfType(Type.GRASS) && !this.pokemon.hasAbility(Abilities.OVERCOAT)))) {
|
||||
moveTarget.value = p.getBattlerIndex();
|
||||
}
|
||||
});
|
||||
//Check if this move is immune to being redirected, and restore its target to the intended target if it is.
|
||||
if ((this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr) || this.move.getMove().hasAttr(BypassRedirectAttr))) {
|
||||
//If an ability prevented this move from being redirected, display its ability pop up.
|
||||
if ((this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr) && !this.move.getMove().hasAttr(BypassRedirectAttr)) && oldTarget !== moveTarget.value) {
|
||||
this.scene.unshiftPhase(new ShowAbilityPhase(this.scene, this.pokemon.getBattlerIndex(), this.pokemon.getPassiveAbility().hasAttr(BlockRedirectAbAttr)));
|
||||
}
|
||||
moveTarget.value = oldTarget;
|
||||
}
|
||||
this.targets[0] = moveTarget.value;
|
||||
}
|
||||
this.resolveRedirectTarget();
|
||||
|
||||
// Check for counterattack moves to switch target
|
||||
if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) {
|
||||
if (this.pokemon.turnData.attacksReceived.length) {
|
||||
const attack = this.pokemon.turnData.attacksReceived[0];
|
||||
this.targets[0] = attack.sourceBattlerIndex;
|
||||
this.resolveCounterAttackTarget();
|
||||
|
||||
// account for metal burst and comeuppance hitting remaining targets in double battles
|
||||
// counterattack will redirect to remaining ally if original attacker faints
|
||||
if (this.scene.currentBattle.double && this.move.getMove().hasFlag(MoveFlags.REDIRECT_COUNTER)) {
|
||||
if (this.scene.getField()[this.targets[0]].hp === 0) {
|
||||
const opposingField = this.pokemon.isPlayer() ? this.scene.getEnemyField() : this.scene.getPlayerField();
|
||||
//@ts-ignore
|
||||
this.targets[0] = opposingField.find(p => p.hp > 0)?.getBattlerIndex(); //TODO: fix ts-ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.targets[0] === BattlerIndex.ATTACKER) {
|
||||
this.fail(); // Marks the move as failed for later in doMove
|
||||
this.showMoveText();
|
||||
this.showFailedText();
|
||||
}
|
||||
}
|
||||
this.resolvePreMoveStatusEffects();
|
||||
|
||||
const targets = this.scene.getField(true).filter(p => {
|
||||
if (this.targets.indexOf(p.getBattlerIndex()) > -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
this.lapsePreMoveAndMoveTags();
|
||||
|
||||
const doMove = () => {
|
||||
this.pokemon.turnData.acted = true; // Record that the move was attempted, even if it fails
|
||||
this.resolveFinalPreMoveCancellationChecks();
|
||||
|
||||
this.pokemon.lapseTags(BattlerTagLapseType.PRE_MOVE);
|
||||
|
||||
let ppUsed = 1;
|
||||
// Filter all opponents to include only those this move is targeting
|
||||
const targetedOpponents = this.pokemon.getOpponents().filter(o => this.targets.includes(o.getBattlerIndex()));
|
||||
for (const opponent of targetedOpponents) {
|
||||
if (this.move.ppUsed + ppUsed >= this.move.getMovePp()) { // If we're already at max PP usage, stop checking
|
||||
break;
|
||||
}
|
||||
if (opponent.hasAbilityWithAttr(IncreasePpAbAttr)) { // Accounting for abilities like Pressure
|
||||
ppUsed++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.followUp && this.canMove() && !this.cancelled) {
|
||||
this.pokemon.lapseTags(BattlerTagLapseType.MOVE);
|
||||
}
|
||||
|
||||
const moveQueue = this.pokemon.getMoveQueue();
|
||||
if (this.cancelled || this.failed) {
|
||||
if (this.failed) {
|
||||
this.move.usePp(ppUsed); // Only use PP if the move failed
|
||||
this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), this.move.ppUsed));
|
||||
this.handlePreMoveFailures();
|
||||
} else {
|
||||
this.useMove();
|
||||
}
|
||||
|
||||
// Record a failed move so Abilities like Truant don't trigger next turn and soft-lock
|
||||
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
|
||||
|
||||
this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT); // Remove any tags from moves like Fly/Dive/etc.
|
||||
this.pokemon.lapseTags(BattlerTagLapseType.AFTER_MOVE);
|
||||
moveQueue.shift(); // Remove the second turn of charge moves
|
||||
return this.end();
|
||||
this.end();
|
||||
}
|
||||
|
||||
this.scene.triggerPokemonFormChange(this.pokemon, SpeciesFormChangePreMoveTrigger);
|
||||
/** Check for cancellation edge cases - no targets remaining, or {@linkcode Moves.NONE} is in the queue */
|
||||
protected resolveFinalPreMoveCancellationChecks() {
|
||||
const targets = this.getActiveTargetPokemon();
|
||||
const moveQueue = this.pokemon.getMoveQueue();
|
||||
|
||||
if (this.move.moveId) {
|
||||
this.showMoveText();
|
||||
}
|
||||
|
||||
// This should only happen when there are no valid targets left on the field
|
||||
if ((moveQueue.length && moveQueue[0].move === Moves.NONE) || !targets.length) {
|
||||
if (targets.length === 0 || (moveQueue.length && moveQueue[0].move === Moves.NONE)) {
|
||||
this.showFailedText();
|
||||
this.cancel();
|
||||
|
||||
// Record a failed move so Abilities like Truant don't trigger next turn and soft-lock
|
||||
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
|
||||
|
||||
this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT); // Remove any tags from moves like Fly/Dive/etc.
|
||||
this.pokemon.lapseTags(BattlerTagLapseType.AFTER_MOVE);
|
||||
|
||||
moveQueue.shift();
|
||||
return this.end();
|
||||
this.cancelled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!moveQueue.length || !moveQueue.shift()?.ignorePP) && !this.ignorePp) { // using .shift here clears out two turn moves once they've been used
|
||||
this.move.usePp(ppUsed);
|
||||
this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), this.move.ppUsed));
|
||||
}
|
||||
|
||||
if (!allMoves[this.move.moveId].hasAttr(CopyMoveAttr)) {
|
||||
this.scene.currentBattle.lastMove = this.move.moveId;
|
||||
}
|
||||
|
||||
// Assume conditions affecting targets only apply to moves with a single target
|
||||
let success = this.move.getMove().applyConditions(this.pokemon, targets[0], this.move.getMove());
|
||||
const cancelled = new Utils.BooleanHolder(false);
|
||||
let failedText = this.move.getMove().getFailedText(this.pokemon, targets[0], this.move.getMove(), cancelled);
|
||||
if (success && this.scene.arena.isMoveWeatherCancelled(this.pokemon, this.move.getMove())) {
|
||||
success = false;
|
||||
} else if (success && this.scene.arena.isMoveTerrainCancelled(this.pokemon, this.targets, this.move.getMove())) {
|
||||
success = false;
|
||||
if (failedText === null) {
|
||||
failedText = getTerrainBlockMessage(targets[0], this.scene.arena.terrain?.terrainType!); // TODO: is this bang correct?
|
||||
}
|
||||
public getActiveTargetPokemon() {
|
||||
return this.scene.getField(true).filter(p => this.targets.includes(p.getBattlerIndex()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger pokemon type change before playing the move animation
|
||||
* Will still change the user's type when using Roar, Whirlwind, Trick-or-Treat, and Forest's Curse,
|
||||
* regardless of whether the move successfully executes or not.
|
||||
* Handles {@link StatusEffect.SLEEP Sleep}/{@link StatusEffect.PARALYSIS Paralysis}/{@link StatusEffect.FREEZE Freeze} rolls and side effects.
|
||||
*/
|
||||
if (success || [ Moves.ROAR, Moves.WHIRLWIND, Moves.TRICK_OR_TREAT, Moves.FORESTS_CURSE ].includes(this.move.moveId)) {
|
||||
applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, this.move.getMove());
|
||||
}
|
||||
|
||||
if (success) {
|
||||
this.scene.unshiftPhase(this.getEffectPhase());
|
||||
} else {
|
||||
this.pokemon.pushMoveHistory({ move: this.move.moveId, targets: this.targets, result: MoveResult.FAIL, virtual: this.move.virtual });
|
||||
if (!cancelled.value) {
|
||||
this.showFailedText(failedText);
|
||||
}
|
||||
}
|
||||
// Checks if Dancer ability is triggered
|
||||
if (this.move.getMove().hasFlag(MoveFlags.DANCE_MOVE) && !this.followUp) {
|
||||
// Pokemon with Dancer can be on either side of the battle so we check in both cases
|
||||
this.scene.getPlayerField().forEach(pokemon => {
|
||||
applyPostMoveUsedAbAttrs(PostMoveUsedAbAttr, pokemon, this.move, this.pokemon, this.targets);
|
||||
});
|
||||
this.scene.getEnemyField().forEach(pokemon => {
|
||||
applyPostMoveUsedAbAttrs(PostMoveUsedAbAttr, pokemon, this.move, this.pokemon, this.targets);
|
||||
});
|
||||
}
|
||||
this.end();
|
||||
};
|
||||
|
||||
protected resolvePreMoveStatusEffects() {
|
||||
if (!this.followUp && this.pokemon.status && !this.pokemon.status.isPostTurn()) {
|
||||
this.pokemon.status.incrementTurn();
|
||||
let activated = false;
|
||||
@ -273,25 +186,257 @@ export class MovePhase extends BattlePhase {
|
||||
if (activated) {
|
||||
this.scene.queueMessage(getStatusEffectActivationText(this.pokemon.status.effect, getPokemonNameWithAffix(this.pokemon)));
|
||||
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, this.pokemon.getBattlerIndex(), undefined, CommonAnim.POISON + (this.pokemon.status.effect - 1)));
|
||||
doMove();
|
||||
} else {
|
||||
if (healed) {
|
||||
} else if (healed) {
|
||||
this.scene.queueMessage(getStatusEffectHealText(this.pokemon.status.effect, getPokemonNameWithAffix(this.pokemon)));
|
||||
this.pokemon.resetStatus();
|
||||
this.pokemon.updateInfo();
|
||||
}
|
||||
doMove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lapse {@linkcode BattlerTagLapseType.PRE_MOVE PRE_MOVE} tags that trigger before a move is used, regardless of whether or not it failed.
|
||||
* Also lapse {@linkcode BattlerTagLapseType.MOVE MOVE} tags if the move should be successful.
|
||||
*/
|
||||
protected lapsePreMoveAndMoveTags() {
|
||||
this.pokemon.lapseTags(BattlerTagLapseType.PRE_MOVE);
|
||||
|
||||
// TODO: does this intentionally happen before the no targets/Moves.NONE on queue cancellation case is checked?
|
||||
if (!this.followUp && this.canMove() && !this.cancelled) {
|
||||
this.pokemon.lapseTags(BattlerTagLapseType.MOVE);
|
||||
}
|
||||
}
|
||||
|
||||
protected useMove() {
|
||||
const targets = this.getActiveTargetPokemon();
|
||||
const moveQueue = this.pokemon.getMoveQueue();
|
||||
|
||||
// form changes happen even before we know that the move wll execute.
|
||||
this.scene.triggerPokemonFormChange(this.pokemon, SpeciesFormChangePreMoveTrigger);
|
||||
|
||||
this.showMoveText();
|
||||
|
||||
// TODO: Clean up implementation of two-turn moves.
|
||||
if (moveQueue.length > 0) { // Using .shift here clears out two turn moves once they've been used
|
||||
this.ignorePp = moveQueue.shift()?.ignorePP ?? false;
|
||||
}
|
||||
|
||||
// "commit" to using the move, deducting PP.
|
||||
if (!this.ignorePp) {
|
||||
const ppUsed = 1 + this.getPpIncreaseFromPressure(targets);
|
||||
|
||||
this.move.usePp(ppUsed);
|
||||
this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), ppUsed));
|
||||
}
|
||||
|
||||
// Update the battle's "last move" pointer, unless we're currently mimicking a move.
|
||||
if (!allMoves[this.move.moveId].hasAttr(CopyMoveAttr)) {
|
||||
this.scene.currentBattle.lastMove = this.move.moveId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the move is successful (meaning that its damage/effects can be attempted)
|
||||
* by checking that all of the following are true:
|
||||
* - Conditional attributes of the move are all met
|
||||
* - The target's `ForceSwitchOutImmunityAbAttr` is not triggered (see {@linkcode Move.prototype.applyConditions})
|
||||
* - Weather does not block the move
|
||||
* - Terrain does not block the move
|
||||
*
|
||||
* TODO: These steps are straightforward, but the implementation below is extremely convoluted.
|
||||
*/
|
||||
|
||||
const move = this.move.getMove();
|
||||
|
||||
/**
|
||||
* Move conditions assume the move has a single target
|
||||
* TODO: is this sustainable?
|
||||
*/
|
||||
const passesConditions = move.applyConditions(this.pokemon, targets[0], move);
|
||||
const failedDueToWeather: boolean = this.scene.arena.isMoveWeatherCancelled(this.pokemon, move);
|
||||
const failedDueToTerrain: boolean = this.scene.arena.isMoveTerrainCancelled(this.pokemon, this.targets, move);
|
||||
|
||||
const success = passesConditions && !failedDueToWeather && !failedDueToTerrain;
|
||||
|
||||
/**
|
||||
* If the move has not failed, trigger ability-based user type changes and then execute it.
|
||||
*
|
||||
* Notably, Roar, Whirlwind, Trick-or-Treat, and Forest's Curse will trigger these type changes even
|
||||
* if the move fails.
|
||||
*/
|
||||
if (success) {
|
||||
applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, this.move.getMove());
|
||||
this.scene.unshiftPhase(new MoveEffectPhase(this.scene, this.pokemon.getBattlerIndex(), this.targets, this.move));
|
||||
|
||||
} else {
|
||||
doMove();
|
||||
if ([ Moves.ROAR, Moves.WHIRLWIND, Moves.TRICK_OR_TREAT, Moves.FORESTS_CURSE ].includes(this.move.moveId)) {
|
||||
applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, this.move.getMove());
|
||||
}
|
||||
|
||||
this.pokemon.pushMoveHistory({ move: this.move.moveId, targets: this.targets, result: MoveResult.FAIL, virtual: this.move.virtual });
|
||||
|
||||
let failedText: string | undefined;
|
||||
const failureMessage = move.getFailedText(this.pokemon, targets[0], move, new Utils.BooleanHolder(false));
|
||||
|
||||
if (failureMessage) {
|
||||
failedText = failureMessage;
|
||||
} else if (failedDueToTerrain) {
|
||||
failedText = getTerrainBlockMessage(this.pokemon, this.scene.arena.getTerrainType());
|
||||
}
|
||||
|
||||
this.showFailedText(failedText);
|
||||
}
|
||||
|
||||
// Handle Dancer, which triggers immediately after a move is used (rather than waiting on `this.end()`).
|
||||
// Note that the `!this.followUp` check here prevents an infinite Dancer loop.
|
||||
if (this.move.getMove().hasFlag(MoveFlags.DANCE_MOVE) && !this.followUp) {
|
||||
this.scene.getField(true).forEach(pokemon => {
|
||||
applyPostMoveUsedAbAttrs(PostMoveUsedAbAttr, pokemon, this.move, this.pokemon, this.targets);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getEffectPhase(): MoveEffectPhase {
|
||||
return new MoveEffectPhase(this.scene, this.pokemon.getBattlerIndex(), this.targets, this.move);
|
||||
/**
|
||||
* Queues a {@linkcode MoveEndPhase} if the move wasn't a {@linkcode followUp} and {@linkcode canMove()} returns `true`,
|
||||
* then ends the phase.
|
||||
*/
|
||||
public end() {
|
||||
if (!this.followUp && this.canMove()) {
|
||||
this.scene.unshiftPhase(new MoveEndPhase(this.scene, this.pokemon.getBattlerIndex()));
|
||||
}
|
||||
|
||||
super.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies PP increasing abilities (currently only {@link Abilities.PRESSURE Pressure}) if they exist on the target pokemon.
|
||||
* Note that targets must include only active pokemon.
|
||||
*
|
||||
* TODO: This hardcodes the PP increase at 1 per opponent, rather than deferring to the ability.
|
||||
*/
|
||||
public getPpIncreaseFromPressure(targets: Pokemon[]) {
|
||||
const foesWithPressure = this.pokemon.getOpponents().filter(o => targets.includes(o) && o.isActive(true) && o.hasAbilityWithAttr(IncreasePpAbAttr));
|
||||
return foesWithPressure.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies `this.targets` in place, based upon:
|
||||
* - Move redirection abilities, effects, etc.
|
||||
* - Counterattacks, which pass a special value into the `targets` constructor param (`[`{@linkcode BattlerIndex.ATTACKER}`]`).
|
||||
*/
|
||||
protected resolveRedirectTarget() {
|
||||
if (this.targets.length === 1) {
|
||||
const currentTarget = this.targets[0];
|
||||
const redirectTarget = new Utils.NumberHolder(currentTarget);
|
||||
|
||||
// check move redirection abilities of every pokemon *except* the user.
|
||||
this.scene.getField(true).filter(p => p !== this.pokemon).forEach(p => applyAbAttrs(RedirectMoveAbAttr, p, null, false, this.move.moveId, redirectTarget));
|
||||
|
||||
// check for center-of-attention tags (note that this will override redirect abilities)
|
||||
this.pokemon.getOpponents().forEach(p => {
|
||||
const redirectTag = p.getTag(CenterOfAttentionTag) as CenterOfAttentionTag;
|
||||
|
||||
// TODO: don't hardcode this interaction.
|
||||
// Handle interaction between the rage powder center-of-attention tag and moves used by grass types/overcoat-havers (which are immune to RP's redirect)
|
||||
if (redirectTag && (!redirectTag.powder || (!this.pokemon.isOfType(Type.GRASS) && !this.pokemon.hasAbility(Abilities.OVERCOAT)))) {
|
||||
redirectTarget.value = p.getBattlerIndex();
|
||||
}
|
||||
});
|
||||
|
||||
if (currentTarget !== redirectTarget.value) {
|
||||
if (this.move.getMove().hasAttr(BypassRedirectAttr)) {
|
||||
redirectTarget.value = currentTarget;
|
||||
|
||||
} else if (this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr)) {
|
||||
redirectTarget.value = currentTarget;
|
||||
this.scene.unshiftPhase(new ShowAbilityPhase(this.scene, this.pokemon.getBattlerIndex(), this.pokemon.getPassiveAbility().hasAttr(BlockRedirectAbAttr)));
|
||||
}
|
||||
|
||||
this.targets[0] = redirectTarget.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Counter-attacking moves pass in `[`{@linkcode BattlerIndex.ATTACKER}`]` into the constructor's `targets` param.
|
||||
* This function modifies `this.targets` to reflect the actual battler index of the user's last
|
||||
* attacker.
|
||||
*
|
||||
* If there is no last attacker, or they are no longer on the field, a message is displayed and the
|
||||
* move is marked for failure.
|
||||
*/
|
||||
protected resolveCounterAttackTarget() {
|
||||
if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) {
|
||||
if (this.pokemon.turnData.attacksReceived.length) {
|
||||
const attacker = this.pokemon.scene.getPokemonById(this.pokemon.turnData.attacksReceived[0].sourceId);
|
||||
|
||||
if (attacker?.isActive(true)) {
|
||||
this.targets[0] = attacker.getBattlerIndex();
|
||||
}
|
||||
|
||||
// account for metal burst and comeuppance hitting remaining targets in double battles
|
||||
// counterattack will redirect to remaining ally if original attacker faints
|
||||
if (this.scene.currentBattle.double && this.move.getMove().hasFlag(MoveFlags.REDIRECT_COUNTER)) {
|
||||
if (this.scene.getField()[this.targets[0]].hp === 0) {
|
||||
const opposingField = this.pokemon.isPlayer() ? this.scene.getEnemyField() : this.scene.getPlayerField();
|
||||
this.targets[0] = opposingField.find(p => p.hp > 0)?.getBattlerIndex() ?? BattlerIndex.ATTACKER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.targets[0] === BattlerIndex.ATTACKER) {
|
||||
this.fail();
|
||||
this.showMoveText();
|
||||
this.showFailedText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the case where the move was cancelled or failed:
|
||||
* - Uses PP if the move failed (not cancelled) and should use PP (failed moves are not affected by {@link Abilities.PRESSURE Pressure})
|
||||
* - Records a cancelled OR failed move in move history, so abilities like {@link Abilities.TRUANT Truant} don't trigger on the
|
||||
* next turn and soft-lock.
|
||||
* - Lapses `MOVE_EFFECT` tags:
|
||||
* - Semi-invulnerable battler tags (Fly/Dive/etc.) are intended to lapse on move effects, but also need
|
||||
* to lapse on move failure/cancellation.
|
||||
*
|
||||
* TODO: ...this seems weird.
|
||||
* - Lapses `AFTER_MOVE` tags:
|
||||
* - This handles the effects of {@link Moves.SUBSTITUTE Substitute}
|
||||
* - Removes the second turn of charge moves
|
||||
*
|
||||
* TODO: handle charge moves more gracefully
|
||||
*/
|
||||
protected handlePreMoveFailures() {
|
||||
if (this.cancelled || this.failed) {
|
||||
if (this.failed) {
|
||||
const ppUsed = this.ignorePp ? 0 : 1;
|
||||
|
||||
if (ppUsed) {
|
||||
this.move.usePp();
|
||||
}
|
||||
|
||||
this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), ppUsed));
|
||||
}
|
||||
|
||||
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
|
||||
|
||||
this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT);
|
||||
this.pokemon.lapseTags(BattlerTagLapseType.AFTER_MOVE);
|
||||
|
||||
this.pokemon.getMoveQueue().shift();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the move's usage text to the player, unless it's a charge turn (ie: {@link Moves.SOLAR_BEAM Solar Beam}),
|
||||
* the pokemon is on a recharge turn (ie: {@link Moves.HYPER_BEAM Hyper Beam}), or a 2-turn move was interrupted (ie: {@link Moves.FLY Fly}).
|
||||
*/
|
||||
protected showMoveText(): void {
|
||||
if (this.move.moveId === Moves.NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
showMoveText(): void {
|
||||
if (this.move.getMove().hasAttr(ChargeAttr)) {
|
||||
const lastMove = this.pokemon.getLastXMoves() as TurnMove[];
|
||||
if (!lastMove.length || lastMove[0].move !== this.move.getMove().id || lastMove[0].result !== MoveResult.OTHER) {
|
||||
@ -311,18 +456,10 @@ export class MovePhase extends BattlePhase {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(this.pokemon),
|
||||
moveName: this.move.getName()
|
||||
}), 500);
|
||||
applyMoveAttrs(PreMoveMessageAttr, this.pokemon, this.pokemon.getOpponents().find(() => true)!, this.move.getMove()); //TODO: is the bang correct here?
|
||||
applyMoveAttrs(PreMoveMessageAttr, this.pokemon, this.pokemon.getOpponents()[0], this.move.getMove());
|
||||
}
|
||||
|
||||
showFailedText(failedText: string | null = null): void {
|
||||
this.scene.queueMessage(failedText || i18next.t("battle:attackFailed"));
|
||||
}
|
||||
|
||||
end() {
|
||||
if (!this.followUp && this.canMove()) {
|
||||
this.scene.unshiftPhase(new MoveEndPhase(this.scene, this.pokemon.getBattlerIndex()));
|
||||
}
|
||||
|
||||
super.end();
|
||||
protected showFailedText(failedText?: string): void {
|
||||
this.scene.queueMessage(failedText ?? i18next.t("battle:attackFailed"));
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import { Moves } from "#app/enums/moves";
|
||||
import { Biome } from "#app/enums/biome";
|
||||
import { Mode } from "#app/ui/ui";
|
||||
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
||||
import { Species } from "#enums/species";
|
||||
|
||||
//const TIMEOUT = 20 * 1000;
|
||||
|
||||
@ -53,12 +54,11 @@ describe("Shop modifications", async () => {
|
||||
|
||||
game.override
|
||||
.startingWave(9)
|
||||
.startingBiome(Biome.ICE_CAVE) // Will lead to Snowy Forest with randomly generated weather
|
||||
.startingBiome(Biome.ICE_CAVE)
|
||||
.battleType("single")
|
||||
.startingLevel(100) // Avoid levelling up
|
||||
.enemyLevel(1000) // Avoid opponent dying before game.doKillOpponents()
|
||||
.disableTrainerWaves()
|
||||
.moveset([ Moves.KOWTOW_CLEAVE ])
|
||||
.moveset([ Moves.SPLASH ])
|
||||
.enemyMoveset(Moves.SPLASH);
|
||||
game.modifiers
|
||||
.addCheck("EVIOLITE")
|
||||
@ -71,9 +71,8 @@ describe("Shop modifications", async () => {
|
||||
});
|
||||
|
||||
it("should not have Eviolite and Mini Black Hole available in Classic if not unlocked", async () => {
|
||||
await game.classicMode.startBattle();
|
||||
game.move.select(Moves.KOWTOW_CLEAVE);
|
||||
await game.phaseInterceptor.to("DamagePhase");
|
||||
await game.classicMode.startBattle([ Species.BULBASAUR ]);
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.doKillOpponents();
|
||||
await game.phaseInterceptor.to("BattleEndPhase");
|
||||
game.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => {
|
||||
@ -86,8 +85,7 @@ describe("Shop modifications", async () => {
|
||||
|
||||
it("should have Eviolite and Mini Black Hole available in Daily", async () => {
|
||||
await game.dailyMode.startBattle();
|
||||
game.move.select(Moves.KOWTOW_CLEAVE);
|
||||
await game.phaseInterceptor.to("DamagePhase");
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.doKillOpponents();
|
||||
await game.phaseInterceptor.to("BattleEndPhase");
|
||||
game.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => {
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
import { allMoves } from "#app/data/move";
|
||||
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
||||
import { MoveResult } from "#app/field/pokemon";
|
||||
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, it, expect, vi } from "vitest";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
describe("Moves - Whirlwind", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
@ -40,14 +39,11 @@ describe("Moves - Whirlwind", () => {
|
||||
await game.classicMode.startBattle([ Species.STARAPTOR ]);
|
||||
|
||||
const staraptor = game.scene.getPlayerPokemon()!;
|
||||
const whirlwind = allMoves[Moves.WHIRLWIND];
|
||||
vi.spyOn(whirlwind, "getFailedText");
|
||||
|
||||
game.move.select(move);
|
||||
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(staraptor.findTag((t) => t.tagType === BattlerTagType.FLYING)).toBeDefined();
|
||||
expect(whirlwind.getFailedText).toHaveBeenCalledOnce();
|
||||
expect(game.scene.getEnemyPokemon()!.getLastXMoves(1)[0].result).toBe(MoveResult.MISS);
|
||||
});
|
||||
});
|
||||
|
@ -44,15 +44,13 @@ describe("Reload", () => {
|
||||
.startingWave(10)
|
||||
.battleType("single")
|
||||
.startingLevel(100) // Avoid levelling up
|
||||
.enemyLevel(1000) // Avoid opponent dying before game.doKillOpponents()
|
||||
.disableTrainerWaves()
|
||||
.moveset([ Moves.KOWTOW_CLEAVE ])
|
||||
.moveset([ Moves.SPLASH ])
|
||||
.enemyMoveset(Moves.SPLASH);
|
||||
await game.dailyMode.startBattle();
|
||||
|
||||
// Transition from Wave 10 to Wave 11 in order to trigger biome switch
|
||||
game.move.select(Moves.KOWTOW_CLEAVE);
|
||||
await game.phaseInterceptor.to("DamagePhase");
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.doKillOpponents();
|
||||
game.onNextPrompt("SelectBiomePhase", Mode.OPTION_SELECT, () => {
|
||||
(game.scene.time as MockClock).overrideDelay = null;
|
||||
@ -79,15 +77,13 @@ describe("Reload", () => {
|
||||
.startingBiome(Biome.ICE_CAVE) // Will lead to Snowy Forest with randomly generated weather
|
||||
.battleType("single")
|
||||
.startingLevel(100) // Avoid levelling up
|
||||
.enemyLevel(1000) // Avoid opponent dying before game.doKillOpponents()
|
||||
.disableTrainerWaves()
|
||||
.moveset([ Moves.KOWTOW_CLEAVE ])
|
||||
.moveset([ Moves.SPLASH ])
|
||||
.enemyMoveset(Moves.SPLASH);
|
||||
await game.classicMode.startBattle(); // Apparently daily mode would override the biome
|
||||
|
||||
// Transition from Wave 10 to Wave 11 in order to trigger biome switch
|
||||
game.move.select(Moves.KOWTOW_CLEAVE);
|
||||
await game.phaseInterceptor.to("DamagePhase");
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.doKillOpponents();
|
||||
await game.toNextWave();
|
||||
expect(game.phaseInterceptor.log).toContain("NewBiomeEncounterPhase");
|
||||
|
Loading…
Reference in New Issue
Block a user