From 3940abbeafb015d988eb99d3ba60f4a79f41552f Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Thu, 24 Jul 2025 20:56:11 -0400 Subject: [PATCH 01/76] [Dev] test:silent now passes --silent='passed-only' to Vitest (#6131) * [Dev] test:silent now passes --silent='passed-only' to Vitest * Update test shard to actually use `test-silent` * Removed obselete `project` flag --- .github/workflows/test-shard-template.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-shard-template.yml b/.github/workflows/test-shard-template.yml index b154166f81b..124004f380f 100644 --- a/.github/workflows/test-shard-template.yml +++ b/.github/workflows/test-shard-template.yml @@ -44,4 +44,4 @@ jobs: run: pnpm i - name: Run tests - run: pnpm exec vitest --project ${{ inputs.project }} --no-isolate --shard=${{ inputs.shard }}/${{ inputs.totalShards }} ${{ !runner.debug && '--silent' || '' }} + run: pnpm test:silent --shard=${{ inputs.shard }}/${{ inputs.totalShards }} diff --git a/package.json b/package.json index 85c95bcae3f..9bba5e56f89 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "test": "vitest run --no-isolate", "test:cov": "vitest run --coverage --no-isolate", "test:watch": "vitest watch --coverage --no-isolate", - "test:silent": "vitest run --silent --no-isolate", + "test:silent": "vitest run --silent='passed-only' --no-isolate", "test:create": "node scripts/create-test/create-test.js", "typecheck": "tsc --noEmit", "eslint": "eslint --fix .", From 6211fbd4719c8fc3cab76b01790e67872b004baf Mon Sep 17 00:00:00 2001 From: Acelynn Zhang <102631387+acelynnzhang@users.noreply.github.com> Date: Thu, 24 Jul 2025 20:05:14 -0500 Subject: [PATCH 02/76] [Bug] Unblock priority spread under Psychic Terrain (#6136) Unblock priority spread under Psychic Terrain Co-authored-by: Acelynn Zhang --- src/data/moves/move-utils.ts | 22 +++++++++++ src/data/terrain.ts | 21 +++++++---- test/arena/psychic-terrain.test.ts | 59 ++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 test/arena/psychic-terrain.test.ts diff --git a/src/data/moves/move-utils.ts b/src/data/moves/move-utils.ts index a0baf7ff9b7..241144599e5 100644 --- a/src/data/moves/move-utils.ts +++ b/src/data/moves/move-utils.ts @@ -27,6 +27,28 @@ export function isFieldTargeted(move: Move): boolean { return false; } +/** + * Determine whether a move is a spread move. + * + * @param move - The {@linkcode Move} to check + * @returns Whether {@linkcode move} is spread-targeted. + * @remarks + * Examples include: + * - Moves targeting all adjacent Pokemon (like Surf) + * - Moves targeting all adjacent enemies (like Air Cutter) + */ + +export function isSpreadMove(move: Move): boolean { + switch (move.moveTarget) { + case MoveTarget.ALL_ENEMIES: + case MoveTarget.ALL_NEAR_ENEMIES: + case MoveTarget.ALL_OTHERS: + case MoveTarget.ALL_NEAR_OTHERS: + return true; + } + return false; +} + export function getMoveTargets(user: Pokemon, move: MoveId, replaceTarget?: MoveTarget): MoveTargetSet { const variableTarget = new NumberHolder(0); user.getOpponents(false).forEach(p => applyMoveAttrs("VariableTargetAttr", user, p, allMoves[move], variableTarget)); diff --git a/src/data/terrain.ts b/src/data/terrain.ts index f5382b1c3ec..7906450d0ea 100644 --- a/src/data/terrain.ts +++ b/src/data/terrain.ts @@ -3,6 +3,7 @@ import type { BattlerIndex } from "#enums/battler-index"; import { PokemonType } from "#enums/pokemon-type"; import type { Pokemon } from "#field/pokemon"; import type { Move } from "#moves/move"; +import { isFieldTargeted, isSpreadMove } from "#moves/move-utils"; import i18next from "i18next"; export enum TerrainType { @@ -60,13 +61,19 @@ export class Terrain { isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move): boolean { switch (this.terrainType) { case TerrainType.PSYCHIC: - if (!move.hasAttr("ProtectAttr")) { - // Cancels move if the move has positive priority and targets a Pokemon grounded on the Psychic Terrain - return ( - move.getPriority(user) > 0 && - user.getOpponents(true).some(o => targets.includes(o.getBattlerIndex()) && o.isGrounded()) - ); - } + // Cf https://bulbapedia.bulbagarden.net/wiki/Psychic_Terrain_(move)#Generation_VII + // Psychic terrain will only cancel a move if it: + return ( + // ... is neither spread nor field-targeted, + !isFieldTargeted(move) && + !isSpreadMove(move) && + // .. has positive final priority, + move.getPriority(user) > 0 && + // ...and is targeting at least 1 grounded opponent + user + .getOpponents(true) + .some(o => targets.includes(o.getBattlerIndex()) && o.isGrounded()) + ); } return false; diff --git a/test/arena/psychic-terrain.test.ts b/test/arena/psychic-terrain.test.ts new file mode 100644 index 00000000000..82232cd8d05 --- /dev/null +++ b/test/arena/psychic-terrain.test.ts @@ -0,0 +1,59 @@ +import { AbilityId } from "#enums/ability-id"; +import { MoveId } from "#enums/move-id"; +import { SpeciesId } from "#enums/species-id"; +import { StatusEffect } from "#enums/status-effect"; +import { WeatherType } from "#enums/weather-type"; +import { GameManager } from "#test/test-utils/game-manager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Arena - Psychic Terrain", () => { + 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 + .battleStyle("single") + .criticalHits(false) + .enemyLevel(1) + .enemySpecies(SpeciesId.SHUCKLE) + .enemyAbility(AbilityId.STURDY) + .enemyMoveset(MoveId.SPLASH) + .moveset([MoveId.PSYCHIC_TERRAIN, MoveId.RAIN_DANCE, MoveId.DARK_VOID]) + .ability(AbilityId.NO_GUARD); + }); + + it("Dark Void with Prankster is not blocked", async () => { + await game.classicMode.startBattle([SpeciesId.MAGIKARP]); + + game.move.select(MoveId.PSYCHIC_TERRAIN); + await game.toNextTurn(); + + game.move.select(MoveId.DARK_VOID); + await game.toEndOfTurn(); + + expect(game.scene.getEnemyPokemon()!.status?.effect).toBe(StatusEffect.SLEEP); + }); + + it("Rain Dance with Prankster is not blocked", async () => { + await game.classicMode.startBattle([SpeciesId.MAGIKARP]); + + game.move.select(MoveId.PSYCHIC_TERRAIN); + await game.toNextTurn(); + + game.move.select(MoveId.RAIN_DANCE); + await game.toEndOfTurn(); + + expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.RAIN); + }); +}); From 6ad11015f72e0864c048c8dc5281f387c695e935 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Thu, 24 Jul 2025 21:23:13 -0400 Subject: [PATCH 03/76] [Dev] Remove `sanitizeOverrides`, consolidate initialization code into 1 file https://github.com/pagefaultgames/pokerogue/pull/6134 * Removed `sanitizeOverrides` * Moved initialization code to its own file * Hopefully fixed test contamination * Actually listened to people now * fixed the thingy * Run stub setup on init because * Update testFileInitialization.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/balance/biomes.ts | 7 +- src/init/init.ts | 35 +++++++++ src/loading-scene.ts | 38 ++-------- test/test-utils/game-manager.ts | 1 - test/test-utils/helpers/overrides-helper.ts | 14 +--- test/test-utils/test-file-initialization.ts | 78 ++++++++------------- test/vitest.setup.ts | 4 +- vitest.config.ts | 3 + 8 files changed, 80 insertions(+), 100 deletions(-) create mode 100644 src/init/init.ts diff --git a/src/data/balance/biomes.ts b/src/data/balance/biomes.ts index 32195b90e43..f84a518fb65 100644 --- a/src/data/balance/biomes.ts +++ b/src/data/balance/biomes.ts @@ -86,7 +86,7 @@ export enum BiomePoolTier { export const uncatchableSpecies: SpeciesId[] = []; -export interface SpeciesTree { +interface SpeciesTree { [key: number]: SpeciesId[] } @@ -94,11 +94,11 @@ export interface PokemonPools { [key: number]: (SpeciesId | SpeciesTree)[] } -export interface BiomeTierPokemonPools { +interface BiomeTierPokemonPools { [key: number]: PokemonPools } -export interface BiomePokemonPools { +interface BiomePokemonPools { [key: number]: BiomeTierPokemonPools } @@ -2022,7 +2022,6 @@ export const biomeTrainerPools: BiomeTrainerPools = { } }; -// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: init methods are expected to have many lines. export function initBiomes() { const pokemonBiomes = [ [ SpeciesId.BULBASAUR, PokemonType.GRASS, PokemonType.POISON, [ diff --git a/src/init/init.ts b/src/init/init.ts new file mode 100644 index 00000000000..17b991be3a0 --- /dev/null +++ b/src/init/init.ts @@ -0,0 +1,35 @@ +import { initAbilities } from "#abilities/ability"; +import { initBiomes } from "#balance/biomes"; +import { initEggMoves } from "#balance/egg-moves"; +import { initPokemonPrevolutions, initPokemonStarters } from "#balance/pokemon-evolutions"; +import { initChallenges } from "#data/challenge"; +import { initTrainerTypeDialogue } from "#data/dialogue"; +import { initPokemonForms } from "#data/pokemon-forms"; +import { initSpecies } from "#data/pokemon-species"; +import { initModifierPools } from "#modifiers/init-modifier-pools"; +import { initModifierTypes } from "#modifiers/modifier-type"; +import { initMoves } from "#moves/move"; +import { initMysteryEncounters } from "#mystery-encounters/mystery-encounters"; +import { initAchievements } from "#system/achv"; +import { initVouchers } from "#system/voucher"; +import { initStatsKeys } from "#ui/game-stats-ui-handler"; + +/** Initialize the game. */ +export function initializeGame() { + initModifierTypes(); + initModifierPools(); + initAchievements(); + initVouchers(); + initStatsKeys(); + initPokemonPrevolutions(); + initPokemonStarters(); + initBiomes(); + initEggMoves(); + initPokemonForms(); + initTrainerTypeDialogue(); + initSpecies(); + initMoves(); + initAbilities(); + initChallenges(); + initMysteryEncounters(); +} diff --git a/src/loading-scene.ts b/src/loading-scene.ts index eb6883e0c68..706ea01a16a 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -1,29 +1,16 @@ -import { initAbilities } from "#abilities/ability"; import { timedEventManager } from "#app/global-event-manager"; +import { initializeGame } from "#app/init/init"; import { SceneBase } from "#app/scene-base"; import { isMobile } from "#app/touch-controls"; -import { initBiomes } from "#balance/biomes"; -import { initEggMoves } from "#balance/egg-moves"; -import { initPokemonPrevolutions, initPokemonStarters } from "#balance/pokemon-evolutions"; -import { initChallenges } from "#data/challenge"; -import { initTrainerTypeDialogue } from "#data/dialogue"; -import { initPokemonForms } from "#data/pokemon-forms"; -import { initSpecies } from "#data/pokemon-species"; import { BiomeId } from "#enums/biome-id"; import { GachaType } from "#enums/gacha-types"; import { getBiomeHasProps } from "#field/arena"; -import { initModifierPools } from "#modifiers/init-modifier-pools"; -import { initModifierTypes } from "#modifiers/modifier-type"; -import { initMoves } from "#moves/move"; -import { initMysteryEncounters } from "#mystery-encounters/mystery-encounters"; import { CacheBustedLoaderPlugin } from "#plugins/cache-busted-loader-plugin"; -import { initAchievements } from "#system/achv"; -import { initVouchers } from "#system/voucher"; -import { initStatsKeys } from "#ui/game-stats-ui-handler"; import { getWindowVariantSuffix, WindowVariant } from "#ui/ui-theme"; import { hasAllLocalizedSprites, localPing } from "#utils/common"; import { getEnumValues } from "#utils/enums"; import i18next from "i18next"; +import type { GameObjects } from "phaser"; export class LoadingScene extends SceneBase { public static readonly KEY = "loading"; @@ -366,30 +353,12 @@ export class LoadingScene extends SceneBase { this.loadLoadingScreen(); - initModifierTypes(); - initModifierPools(); - - initAchievements(); - initVouchers(); - initStatsKeys(); - initPokemonPrevolutions(); - initPokemonStarters(); - initBiomes(); - initEggMoves(); - initPokemonForms(); - initTrainerTypeDialogue(); - initSpecies(); - initMoves(); - initAbilities(); - initChallenges(); - initMysteryEncounters(); + initializeGame(); } loadLoadingScreen() { const mobile = isMobile(); - const loadingGraphics: any[] = []; - const bg = this.add.image(0, 0, ""); bg.setOrigin(0, 0); bg.setScale(6); @@ -460,6 +429,7 @@ export class LoadingScene extends SceneBase { }); disclaimerDescriptionText.setOrigin(0.5, 0.5); + const loadingGraphics: (GameObjects.Image | GameObjects.Graphics | GameObjects.Text)[] = []; loadingGraphics.push( bg, graphics, diff --git a/test/test-utils/game-manager.ts b/test/test-utils/game-manager.ts index 43d9e256d53..b81b077b2f2 100644 --- a/test/test-utils/game-manager.ts +++ b/test/test-utils/game-manager.ts @@ -124,7 +124,6 @@ export class GameManager { this.reload = new ReloadHelper(this); this.modifiers = new ModifierHelper(this); this.field = new FieldHelper(this); - this.override.sanitizeOverrides(); // Disables Mystery Encounters on all tests (can be overridden at test level) this.override.mysteryEncounterChance(0); diff --git a/test/test-utils/helpers/overrides-helper.ts b/test/test-utils/helpers/overrides-helper.ts index bd2986cc094..d67ceedf891 100644 --- a/test/test-utils/helpers/overrides-helper.ts +++ b/test/test-utils/helpers/overrides-helper.ts @@ -3,7 +3,7 @@ import type { NewArenaEvent } from "#events/battle-scene"; /** biome-ignore-end lint/correctness/noUnusedImports: tsdoc imports */ import type { BattleStyle, RandomTrainerOverride } from "#app/overrides"; -import Overrides, { defaultOverrides } from "#app/overrides"; +import Overrides from "#app/overrides"; import { AbilityId } from "#enums/ability-id"; import type { BattleType } from "#enums/battle-type"; import { BiomeId } from "#enums/biome-id"; @@ -19,7 +19,7 @@ import type { ModifierOverride } from "#modifiers/modifier-type"; import type { Variant } from "#sprites/variant"; import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"; import { coerceArray, shiftCharCodes } from "#utils/common"; -import { expect, vi } from "vitest"; +import { vi } from "vitest"; /** * Helper to handle overrides in tests @@ -667,14 +667,4 @@ export class OverridesHelper extends GameManagerHelper { private log(...params: any[]) { console.log("Overrides:", ...params); } - - public sanitizeOverrides(): void { - for (const key of Object.keys(defaultOverrides)) { - if (Overrides[key] !== defaultOverrides[key]) { - vi.spyOn(Overrides, key as any, "get").mockReturnValue(defaultOverrides[key]); - } - } - expect(Overrides).toEqual(defaultOverrides); - this.log("Sanitizing all overrides!"); - } } diff --git a/test/test-utils/test-file-initialization.ts b/test/test-utils/test-file-initialization.ts index 87318f34ae3..631d3f9146b 100644 --- a/test/test-utils/test-file-initialization.ts +++ b/test/test-utils/test-file-initialization.ts @@ -1,38 +1,46 @@ -import { initAbilities } from "#abilities/ability"; -import { initLoggedInUser } from "#app/account"; import { SESSION_ID_COOKIE_NAME } from "#app/constants"; -import { initBiomes } from "#balance/biomes"; -import { initEggMoves } from "#balance/egg-moves"; -import { initPokemonPrevolutions, initPokemonStarters } from "#balance/pokemon-evolutions"; -import { initPokemonForms } from "#data/pokemon-forms"; -import { initSpecies } from "#data/pokemon-species"; -import { initModifierPools } from "#modifiers/init-modifier-pools"; -import { initModifierTypes } from "#modifiers/modifier-type"; -import { initMoves } from "#moves/move"; -import { initMysteryEncounters } from "#mystery-encounters/mystery-encounters"; +import { initializeGame } from "#app/init/init"; import { initI18n } from "#plugins/i18n"; -import { initAchievements } from "#system/achv"; -import { initVouchers } from "#system/voucher"; import { blobToString } from "#test/test-utils/game-manager-utils"; import { manageListeners } from "#test/test-utils/listeners-manager"; import { MockConsoleLog } from "#test/test-utils/mocks/mock-console-log"; import { mockContext } from "#test/test-utils/mocks/mock-context-canvas"; import { mockLocalStorage } from "#test/test-utils/mocks/mock-local-storage"; import { MockImage } from "#test/test-utils/mocks/mocks-container/mock-image"; -import { initStatsKeys } from "#ui/game-stats-ui-handler"; import { setCookie } from "#utils/cookies"; import Phaser from "phaser"; import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; import InputText from "phaser3-rex-plugins/plugins/inputtext"; let wasInitialized = false; -/** - * An initialization function that is run at the beginning of every test file (via `beforeAll()`). - */ -export function initTestFile() { - // Set the timezone to UTC for tests. - process.env.TZ = "UTC"; +/** + * Run initialization code upon starting a new file, both per-suite and per-instance oncess. + */ +export function initTests(): void { + setupStubs(); + if (!wasInitialized) { + initTestFile(); + wasInitialized = true; + } + + manageListeners(); +} + +/** + * Initialize various values at the beginning of each testing instance. + */ +function initTestFile(): void { + initI18n(); + initializeGame(); +} + +/** + * Setup various stubs for testing. + * @todo Move this into a dedicated stub file instead of running it once per test instance + * @todo Investigate why this resets on new test suite start + */ +function setupStubs(): void { Object.defineProperty(window, "localStorage", { value: mockLocalStorage(), }); @@ -68,9 +76,9 @@ export function initTestFile() { /** * Sets this object's position relative to another object with a given offset - * @param guideObject {@linkcode Phaser.GameObjects.GameObject} to base the position off of - * @param x The relative x position - * @param y The relative y position + * @param guideObject - The {@linkcode Phaser.GameObjects.GameObject} to base the position off of + * @param x - The relative x position + * @param y - The relative y position */ const setPositionRelative = function (guideObject: any, x: number, y: number): any { const offsetX = guideObject.width * (-0.5 + (0.5 - guideObject.originX)); @@ -85,30 +93,6 @@ export function initTestFile() { Phaser.GameObjects.Text.prototype.setPositionRelative = setPositionRelative; Phaser.GameObjects.Rectangle.prototype.setPositionRelative = setPositionRelative; HTMLCanvasElement.prototype.getContext = () => mockContext; - - // Initialize all of these things if and only if they have not been initialized yet - if (!wasInitialized) { - wasInitialized = true; - initI18n(); - initModifierTypes(); - initModifierPools(); - initVouchers(); - initAchievements(); - initStatsKeys(); - initPokemonPrevolutions(); - initBiomes(); - initEggMoves(); - initPokemonForms(); - initSpecies(); - initMoves(); - initAbilities(); - initLoggedInUser(); - initMysteryEncounters(); - // init the pokemon starters for the pokedex - initPokemonStarters(); - } - - manageListeners(); } /** diff --git a/test/vitest.setup.ts b/test/vitest.setup.ts index 70293f20469..be35e18e2e9 100644 --- a/test/vitest.setup.ts +++ b/test/vitest.setup.ts @@ -1,5 +1,5 @@ import "vitest-canvas-mock"; -import { initTestFile } from "#test/test-utils/test-file-initialization"; +import { initTests } from "#test/test-utils/test-file-initialization"; import { afterAll, beforeAll, vi } from "vitest"; /** Set the timezone to UTC for tests. */ @@ -51,7 +51,7 @@ vi.mock("i18next", async importOriginal => { global.testFailed = false; beforeAll(() => { - initTestFile(); + initTests(); }); afterAll(() => { diff --git a/vitest.config.ts b/vitest.config.ts index e9f7a2a438c..e788302857b 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -5,6 +5,9 @@ import { defaultConfig } from "./vite.config"; export default defineProject(({ mode }) => ({ ...defaultConfig, test: { + env: { + TZ: "UTC", + }, testTimeout: 20000, setupFiles: ["./test/font-face.setup.ts", "./test/vitest.setup.ts"], sequence: { From 99545cf3c798c5a7b0f2b25ea0049256eda97e1c Mon Sep 17 00:00:00 2001 From: Madmadness65 <59298170+Madmadness65@users.noreply.github.com> Date: Thu, 24 Jul 2025 20:45:09 -0500 Subject: [PATCH 04/76] [Misc] Sinistea and Poltchageist line alt forms now available (#4989) * Sinistea and Poltchageist line alt forms now available * Unmark Poltchageist line as unobtainable, fix sprite key of alt forms * Correct forms not being marked as starter selectable * Reduce wild chance for Antique/Masterpiece forms Instead of being 1/2 chance to get the Antique or Masterpiece forms, it is now only a 1/16 chance to get them. --------- Co-authored-by: damocleas --- src/battle-scene.ts | 5 +++++ src/data/pokemon-species.ts | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index bb28fb0d5b6..62351c4a833 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1669,6 +1669,11 @@ export class BattleScene extends SceneBase { case SpeciesId.MAUSHOLD: case SpeciesId.DUDUNSPARCE: return !randSeedInt(4) ? 1 : 0; + case SpeciesId.SINISTEA: + case SpeciesId.POLTEAGEIST: + case SpeciesId.POLTCHAGEIST: + case SpeciesId.SINISTCHA: + return !randSeedInt(16) ? 1 : 0; case SpeciesId.PIKACHU: if (this.currentBattle?.battleType === BattleType.TRAINER && this.currentBattle?.waveIndex < 30) { return 0; // Ban Cosplay and Partner Pika from Trainers before wave 30 diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 140b03e6d4c..4e1c01642cb 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -2851,11 +2851,11 @@ export function initSpecies() { new PokemonSpecies(SpeciesId.GRAPPLOCT, 8, false, false, false, "Jujitsu Pokémon", PokemonType.FIGHTING, null, 1.6, 39, AbilityId.LIMBER, AbilityId.NONE, AbilityId.TECHNICIAN, 480, 80, 118, 90, 70, 80, 42, 45, 50, 168, GrowthRate.MEDIUM_SLOW, 50, false), new PokemonSpecies(SpeciesId.SINISTEA, 8, false, false, false, "Black Tea Pokémon", PokemonType.GHOST, null, 0.1, 0.2, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, GrowthRate.MEDIUM_FAST, null, false, false, new PokemonForm("Phony Form", "phony", PokemonType.GHOST, null, 0.1, 0.2, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, "", true), - new PokemonForm("Antique Form", "antique", PokemonType.GHOST, null, 0.1, 0.2, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, "", true, true), + new PokemonForm("Antique Form", "antique", PokemonType.GHOST, null, 0.1, 0.2, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, "", true), ), new PokemonSpecies(SpeciesId.POLTEAGEIST, 8, false, false, false, "Black Tea Pokémon", PokemonType.GHOST, null, 0.2, 0.4, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 508, 60, 65, 65, 134, 114, 70, 60, 50, 178, GrowthRate.MEDIUM_FAST, null, false, false, new PokemonForm("Phony Form", "phony", PokemonType.GHOST, null, 0.2, 0.4, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 508, 60, 65, 65, 134, 114, 70, 60, 50, 178, false, "", true), - new PokemonForm("Antique Form", "antique", PokemonType.GHOST, null, 0.2, 0.4, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 508, 60, 65, 65, 134, 114, 70, 60, 50, 178, false, "", true, true), + new PokemonForm("Antique Form", "antique", PokemonType.GHOST, null, 0.2, 0.4, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 508, 60, 65, 65, 134, 114, 70, 60, 50, 178, false, "", true), ), new PokemonSpecies(SpeciesId.HATENNA, 8, false, false, false, "Calm Pokémon", PokemonType.PSYCHIC, null, 0.4, 3.4, AbilityId.HEALER, AbilityId.ANTICIPATION, AbilityId.MAGIC_BOUNCE, 265, 42, 30, 45, 56, 53, 39, 235, 50, 53, GrowthRate.SLOW, 0, false), new PokemonSpecies(SpeciesId.HATTREM, 8, false, false, false, "Serene Pokémon", PokemonType.PSYCHIC, null, 0.6, 4.8, AbilityId.HEALER, AbilityId.ANTICIPATION, AbilityId.MAGIC_BOUNCE, 370, 57, 40, 65, 86, 73, 49, 120, 50, 130, GrowthRate.SLOW, 0, false), @@ -3109,11 +3109,11 @@ export function initSpecies() { new PokemonSpecies(SpeciesId.DIPPLIN, 9, false, false, false, "Candy Apple Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 0.4, 4.4, AbilityId.SUPERSWEET_SYRUP, AbilityId.GLUTTONY, AbilityId.STICKY_HOLD, 485, 80, 80, 110, 95, 80, 40, 45, 50, 170, GrowthRate.ERRATIC, 50, false), new PokemonSpecies(SpeciesId.POLTCHAGEIST, 9, false, false, false, "Matcha Pokémon", PokemonType.GRASS, PokemonType.GHOST, 0.1, 1.1, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, GrowthRate.SLOW, null, false, false, new PokemonForm("Counterfeit Form", "counterfeit", PokemonType.GRASS, PokemonType.GHOST, 0.1, 1.1, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, null, true), - new PokemonForm("Artisan Form", "artisan", PokemonType.GRASS, PokemonType.GHOST, 0.1, 1.1, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, null, false, true), + new PokemonForm("Artisan Form", "artisan", PokemonType.GRASS, PokemonType.GHOST, 0.1, 1.1, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, "counterfeit", true), ), new PokemonSpecies(SpeciesId.SINISTCHA, 9, false, false, false, "Matcha Pokémon", PokemonType.GRASS, PokemonType.GHOST, 0.2, 2.2, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 508, 71, 60, 106, 121, 80, 70, 60, 50, 178, GrowthRate.SLOW, null, false, false, - new PokemonForm("Unremarkable Form", "unremarkable", PokemonType.GRASS, PokemonType.GHOST, 0.2, 2.2, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 508, 71, 60, 106, 121, 80, 70, 60, 50, 178), - new PokemonForm("Masterpiece Form", "masterpiece", PokemonType.GRASS, PokemonType.GHOST, 0.2, 2.2, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 508, 71, 60, 106, 121, 80, 70, 60, 50, 178, false, null, false, true), + new PokemonForm("Unremarkable Form", "unremarkable", PokemonType.GRASS, PokemonType.GHOST, 0.2, 2.2, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 508, 71, 60, 106, 121, 80, 70, 60, 50, 178, false, null, true), + new PokemonForm("Masterpiece Form", "masterpiece", PokemonType.GRASS, PokemonType.GHOST, 0.2, 2.2, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 508, 71, 60, 106, 121, 80, 70, 60, 50, 178, false, "unremarkable", true), ), new PokemonSpecies(SpeciesId.OKIDOGI, 9, true, false, false, "Retainer Pokémon", PokemonType.POISON, PokemonType.FIGHTING, 1.8, 92.2, AbilityId.TOXIC_CHAIN, AbilityId.NONE, AbilityId.GUARD_DOG, 555, 88, 128, 115, 58, 86, 80, 3, 0, 276, GrowthRate.SLOW, 100, false), new PokemonSpecies(SpeciesId.MUNKIDORI, 9, true, false, false, "Retainer Pokémon", PokemonType.POISON, PokemonType.PSYCHIC, 1, 12.2, AbilityId.TOXIC_CHAIN, AbilityId.NONE, AbilityId.FRISK, 555, 88, 75, 66, 130, 90, 106, 3, 0, 276, GrowthRate.SLOW, 100, false), From fc128a2f4c6e85db15bf1519822f89ba59fe1eac Mon Sep 17 00:00:00 2001 From: Acelynn Zhang <102631387+acelynnzhang@users.noreply.github.com> Date: Fri, 25 Jul 2025 01:16:23 -0500 Subject: [PATCH 05/76] [Bug] Fix when variable move power is called (#6126) * Apply variable power attribute before type boost * Update test/abilities/normal-move-type-change.test.ts Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> * Minor test improvements --------- Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/moves/move.ts | 16 ++++++++----- .../abilities/normal-move-type-change.test.ts | 23 ++++++++++++++++++- test/abilities/normalize.test.ts | 12 ++++++++++ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index 379b474e7e5..779f2d4fc76 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -808,16 +808,14 @@ export abstract class Move implements Localizable { } const power = new NumberHolder(this.power); + + applyMoveAttrs("VariablePowerAttr", source, target, this, power); + const typeChangeMovePowerMultiplier = new NumberHolder(1); const typeChangeHolder = new NumberHolder(this.type); applyAbAttrs("MoveTypeChangeAbAttr", {pokemon: source, opponent: target, move: this, simulated: true, moveType: typeChangeHolder, power: typeChangeMovePowerMultiplier}); - const sourceTeraType = source.getTeraType(); - if (source.isTerastallized && sourceTeraType === this.type && power.value < 60 && this.priority <= 0 && !this.hasAttr("MultiHitAttr") && !globalScene.findModifier(m => m instanceof PokemonMultiHitModifier && m.pokemonId === source.id)) { - power.value = 60; - } - const abAttrParams: PreAttackModifyPowerAbAttrParams = { pokemon: source, opponent: target, @@ -832,6 +830,13 @@ export abstract class Move implements Localizable { applyAbAttrs("AllyMoveCategoryPowerBoostAbAttr", {...abAttrParams, pokemon: ally}); } + // Non-priority, single-hit moves of the user's Tera Type are always a bare minimum of 60 power + + const sourceTeraType = source.getTeraType(); + if (source.isTerastallized && sourceTeraType === this.type && power.value < 60 && this.priority <= 0 && !this.hasAttr("MultiHitAttr") && !globalScene.findModifier(m => m instanceof PokemonMultiHitModifier && m.pokemonId === source.id)) { + power.value = 60; + } + const fieldAuras = new Set( globalScene.getField(true) .map((p) => p.getAbilityAttrs("FieldMoveTypePowerBoostAbAttr").filter(attr => { @@ -855,7 +860,6 @@ export abstract class Move implements Localizable { power.value *= typeBoost.boostValue; } - applyMoveAttrs("VariablePowerAttr", source, target, this, power); if (!this.hasAttr("TypelessAttr")) { globalScene.arena.applyTags(WeakenMoveTypeTag, simulated, typeChangeHolder.value, power); diff --git a/test/abilities/normal-move-type-change.test.ts b/test/abilities/normal-move-type-change.test.ts index 58839bae898..fdf9ef0f9f2 100644 --- a/test/abilities/normal-move-type-change.test.ts +++ b/test/abilities/normal-move-type-change.test.ts @@ -48,7 +48,7 @@ describe.each([ .startingLevel(100) .starterSpecies(SpeciesId.MAGIKARP) .ability(ab) - .moveset([MoveId.TACKLE, MoveId.REVELATION_DANCE, MoveId.FURY_SWIPES]) + .moveset([MoveId.TACKLE, MoveId.REVELATION_DANCE, MoveId.FURY_SWIPES, MoveId.CRUSH_GRIP]) .enemySpecies(SpeciesId.DUSCLOPS) .enemyAbility(AbilityId.BALL_FETCH) .enemyMoveset(MoveId.SPLASH) @@ -75,6 +75,27 @@ describe.each([ expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); }); + // Regression test to ensure proper ordering of effects + it("should still boost variable-power moves", async () => { + await game.classicMode.startBattle([SpeciesId.MAGIKARP]); + + const playerPokemon = game.field.getPlayerPokemon(); + const typeSpy = vi.spyOn(playerPokemon, "getMoveType"); + + const enemyPokemon = game.field.getEnemyPokemon(); + const enemySpy = vi.spyOn(enemyPokemon, "getMoveEffectiveness"); + const powerSpy = vi.spyOn(allMoves[MoveId.CRUSH_GRIP], "calculateBattlePower"); + + game.move.select(MoveId.CRUSH_GRIP); + + await game.toEndOfTurn(); + + expect(typeSpy).toHaveLastReturnedWith(ty); + expect(enemySpy).toHaveReturnedWith(1); + expect(powerSpy).toHaveReturnedWith(144); // 120 * 1.2 + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + }); + // Galvanize specifically would like to check for volt absorb's activation if (ab === AbilityId.GALVANIZE) { it("should cause Normal-type attacks to activate Volt Absorb", async () => { diff --git a/test/abilities/normalize.test.ts b/test/abilities/normalize.test.ts index aeebb2fdbcb..a19a08fdaf0 100644 --- a/test/abilities/normalize.test.ts +++ b/test/abilities/normalize.test.ts @@ -44,6 +44,18 @@ describe("Abilities - Normalize", () => { expect(powerSpy).toHaveLastReturnedWith(toDmgValue(allMoves[MoveId.TACKLE].power * 1.2)); }); + it("should boost variable power moves", async () => { + await game.classicMode.startBattle([SpeciesId.MAGIKARP]); + const magikarp = game.field.getPlayerPokemon(); + magikarp.friendship = 255; + + const powerSpy = vi.spyOn(allMoves[MoveId.RETURN], "calculateBattlePower"); + + game.move.use(MoveId.RETURN); + await game.toEndOfTurn(); + expect(powerSpy).toHaveLastReturnedWith(102 * 1.2); + }); + it("should not apply the old type boost item after changing a move's type", async () => { game.override .startingHeldItems([{ name: "ATTACK_TYPE_BOOSTER", count: 1, type: PokemonType.GRASS }]) From ffa3d1cfe31fb86690035167cdbb6584db7a106f Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Fri, 25 Jul 2025 14:36:21 -0600 Subject: [PATCH 06/76] [UI/UX] [Bug] Fix `ModifierSelectPhase` animation delay (#6121) * Rework promise handling to ensure no races * Add delay to ensure pokeball opening animation can be seen * Remove leftover debug statements. Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Add tween bouncing pokeball to tweens that must complete for promise to resolve * Fix typo in tsdoc Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> --- src/ui/modifier-select-ui-handler.ts | 189 ++++++++++++++++++++------- 1 file changed, 140 insertions(+), 49 deletions(-) diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index 264804eb627..3e3487d4ffb 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -273,12 +273,23 @@ export class ModifierSelectUiHandler extends AwaitableUiHandler { // causing errors if reroll is selected this.awaitingActionInput = false; - // TODO: Replace with `Promise.withResolvers` when possible. - let tweenResolve: () => void; - const tweenPromise = new Promise(resolve => (tweenResolve = resolve)); + const { promise: tweenPromise, resolve: tweenResolve } = Promise.withResolvers(); let i = 0; - // TODO: Rework this bespoke logic for animating the modifier options. + // #region: animation + /** Holds promises that resolve once each reward's *upgrade animation* has finished playing */ + const rewardAnimPromises: Promise[] = []; + /** Holds promises that resolves once *all* animations for a reward have finished playing */ + const rewardAnimAllSettledPromises: Promise[] = []; + + /* + * A counter here is used instead of a loop to "stagger" the apperance of each reward, + * using `sine.easeIn` to speed up the appearance of the rewards as each animation progresses. + * + * The `onComplete` callback for this tween is set to resolve once the upgrade animations + * for each reward has finished playing, allowing for the next set of animations to + * start to appear. + */ globalScene.tweens.addCounter({ ease: "Sine.easeIn", duration: 1250, @@ -288,30 +299,35 @@ export class ModifierSelectUiHandler extends AwaitableUiHandler { const index = Math.floor(value * typeOptions.length); if (index > i && index <= typeOptions.length) { const option = this.options[i]; - option?.show( - Math.floor((1 - value) * 1250) * 0.325 + 2000 * maxUpgradeCount, - -(maxUpgradeCount - typeOptions[i].upgradeCount), - ); + if (option) { + rewardAnimPromises.push( + option.show( + Math.floor((1 - value) * 1250) * 0.325 + 2000 * maxUpgradeCount, + -(maxUpgradeCount - typeOptions[i].upgradeCount), + rewardAnimAllSettledPromises, + ), + ); + } i++; } }, onComplete: () => { - tweenResolve(); + Promise.allSettled(rewardAnimPromises).then(() => tweenResolve()); }, }); - let shopResolve: () => void; - const shopPromise = new Promise(resolve => (shopResolve = resolve)); - tweenPromise.then(() => { - globalScene.time.delayedCall(1000, () => { - for (const shopOption of this.shopOptionsRows.flat()) { - shopOption.show(0, 0); - } - shopResolve(); - }); + /** Holds promises that resolve once each shop item has finished animating */ + const shopAnimPromises: Promise[] = []; + globalScene.time.delayedCall(1000 + maxUpgradeCount * 2000, () => { + for (const shopOption of this.shopOptionsRows.flat()) { + // It is safe to skip awaiting the `show` method here, + // as the promise it returns is also part of the promise appended to `shopAnimPromises`, + // which is awaited later on. + shopOption.show(0, 0, shopAnimPromises, false); + } }); - shopPromise.then(() => { + tweenPromise.then(() => { globalScene.time.delayedCall(500, () => { if (partyHasHeldItem) { this.transferButtonContainer.setAlpha(0); @@ -344,31 +360,39 @@ export class ModifierSelectUiHandler extends AwaitableUiHandler { duration: 250, }); - const updateCursorTarget = () => { - if (globalScene.shopCursorTarget === ShopCursorTarget.CHECK_TEAM) { - this.setRowCursor(0); - this.setCursor(2); - } else if (globalScene.shopCursorTarget === ShopCursorTarget.SHOP && globalScene.gameMode.hasNoShop) { - this.setRowCursor(ShopCursorTarget.REWARDS); - this.setCursor(0); - } else { - this.setRowCursor(globalScene.shopCursorTarget); - this.setCursor(0); - } - }; + // Ensure that the reward animations have completed before allowing input to proceed. + // Required to ensure that the user cannot interact with the UI before the animations + // have completed, (which, among other things, would allow the GameObjects to be destroyed + // before the animations have completed, causing errors). + Promise.allSettled([...shopAnimPromises, ...rewardAnimAllSettledPromises]).then(() => { + const updateCursorTarget = () => { + if (globalScene.shopCursorTarget === ShopCursorTarget.CHECK_TEAM) { + this.setRowCursor(0); + this.setCursor(2); + } else if (globalScene.shopCursorTarget === ShopCursorTarget.SHOP && globalScene.gameMode.hasNoShop) { + this.setRowCursor(ShopCursorTarget.REWARDS); + this.setCursor(0); + } else { + this.setRowCursor(globalScene.shopCursorTarget); + this.setCursor(0); + } + }; - updateCursorTarget(); + updateCursorTarget(); - handleTutorial(Tutorial.Select_Item).then(res => { - if (res) { - updateCursorTarget(); - } - this.awaitingActionInput = true; - this.onActionInput = args[2]; + handleTutorial(Tutorial.Select_Item).then(res => { + if (res) { + updateCursorTarget(); + } + this.awaitingActionInput = true; + this.onActionInput = args[2]; + }); }); }); }); + // #endregion: animation + return true; } @@ -820,14 +844,45 @@ class ModifierOption extends Phaser.GameObjects.Container { } } - show(remainingDuration: number, upgradeCountOffset: number) { - if (!this.modifierTypeOption.cost) { + /** + * Start the tweens responsible for animating the option's appearance + * + * @privateremarks + * This method is unusual. It "returns" (one via the actual return, one by via appending to the `promiseHolder` + * parameter) two promises. The promise returned by the method resolves once the option's appearance animations have + * completed, and is meant to allow callers to synchronize with the completion of the option's appearance animations. + * The promise appended to `promiseHolder` resolves once *all* animations started by this method have completed, + * and should be used by callers to ensure that all animations have completed before proceeding. + * + * @param remainingDuration - The duration in milliseconds that the animation can play for + * @param upgradeCountOffset - The offset to apply to the upgrade count for options whose rarity is being upgraded + * @param promiseHolder - A promise that resolves once all tweens started by this method have completed will be pushed to this array. + * @param isReward - Whether the option being shown is a reward, meaning it should show pokeball and upgrade animations. + * @returns A promise that resolves once the *option's apperance animations* have completed. This promise will resolve _before_ all + * promises that are initiated in this method complete. Instead, the `promiseHolder` array will contain a new promise + * that will resolve once all animations have completed. + * + */ + async show( + remainingDuration: number, + upgradeCountOffset: number, + promiseHolder: Promise[], + isReward = true, + ): Promise { + /** Promises for the pokeball and upgrade animations */ + const animPromises: Promise[] = []; + if (isReward) { + const { promise: bouncePromise, resolve: resolveBounce } = Promise.withResolvers(); globalScene.tweens.add({ targets: this.pb, y: 0, duration: 1250, ease: "Bounce.Out", + onComplete: () => { + resolveBounce(); + }, }); + animPromises.push(bouncePromise); let lastValue = 1; let bounceCount = 0; @@ -857,7 +912,9 @@ class ModifierOption extends Phaser.GameObjects.Container { // TODO: Figure out proper delay between chains and then convert this into a single tween chain // rather than starting multiple tween chains. + for (let u = 0; u < this.modifierTypeOption.upgradeCount; u++) { + const { resolve, promise } = Promise.withResolvers(); globalScene.tweens.chain({ tweens: [ { @@ -883,65 +940,99 @@ class ModifierOption extends Phaser.GameObjects.Container { ease: "Sine.easeOut", onComplete: () => { this.pbTint.setVisible(false); + resolve(); }, }, ], }); + animPromises.push(promise); } } + const finalPromises: Promise[] = []; globalScene.time.delayedCall(remainingDuration + 2000, () => { - if (!globalScene) { - return; - } - - if (!this.modifierTypeOption.cost) { + if (isReward) { this.pb.setTexture("pb", `${this.getPbAtlasKey(0)}_open`); globalScene.playSound("se/pb_rel"); + const { resolve: pbResolve, promise: pbPromise } = Promise.withResolvers(); + globalScene.tweens.add({ targets: this.pb, duration: 500, - delay: 250, ease: "Sine.easeIn", alpha: 0, - onComplete: () => this.pb.destroy(), + onComplete: () => { + Promise.allSettled(animPromises).then(() => this.pb.destroy()); + pbResolve(); + }, }); + finalPromises.push(pbPromise); } + /** Delay for the rest of the tweens to ensure they show after the pokeball animation begins to appear */ + const delay = isReward ? 250 : 0; + + const { resolve: itemResolve, promise: itemPromise } = Promise.withResolvers(); globalScene.tweens.add({ targets: this.itemContainer, + delay, duration: 500, ease: "Elastic.Out", scale: 2, alpha: 1, + onComplete: () => { + itemResolve(); + }, }); - if (!this.modifierTypeOption.cost) { + finalPromises.push(itemPromise); + + if (isReward) { + const { resolve: itemTintResolve, promise: itemTintPromise } = Promise.withResolvers(); globalScene.tweens.add({ targets: this.itemTint, alpha: 0, + delay, duration: 500, ease: "Sine.easeIn", - onComplete: () => this.itemTint.destroy(), + onComplete: () => { + this.itemTint.destroy(); + itemTintResolve(); + }, }); + finalPromises.push(itemTintPromise); } + + const { resolve: itemTextResolve, promise: itemTextPromise } = Promise.withResolvers(); globalScene.tweens.add({ targets: this.itemText, + delay, duration: 500, alpha: 1, y: 25, ease: "Cubic.easeInOut", + onComplete: () => itemTextResolve(), }); + finalPromises.push(itemTextPromise); + if (this.itemCostText) { + const { resolve: itemCostResolve, promise: itemCostPromise } = Promise.withResolvers(); globalScene.tweens.add({ targets: this.itemCostText, + delay, duration: 500, alpha: 1, y: 35, ease: "Cubic.easeInOut", + onComplete: () => itemCostResolve(), }); + finalPromises.push(itemCostPromise); } }); + // The `.then` suppresses the return type for the Promise.allSettled so that it returns void. + promiseHolder.push(Promise.allSettled([...animPromises, ...finalPromises]).then()); + + await Promise.allSettled(animPromises); } getPbAtlasKey(tierOffset = 0) { From 7b7edbb474ef36505bb6229aaa0eead31efda019 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Fri, 25 Jul 2025 16:22:52 -0700 Subject: [PATCH 07/76] [Test] `MoveHelper#changeMoveset` disables moveset overrides (#5915) Also fix Assist tests and add `expect` for max moveset length --- test/moves/assist.test.ts | 5 ++--- test/test-utils/helpers/move-helper.ts | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/test/moves/assist.test.ts b/test/moves/assist.test.ts index 08112d911b1..52467c2ba98 100644 --- a/test/moves/assist.test.ts +++ b/test/moves/assist.test.ts @@ -86,12 +86,11 @@ describe("Moves - Assist", () => { }); it("should apply secondary effects of a move", async () => { - game.override.moveset([MoveId.ASSIST, MoveId.WOOD_HAMMER, MoveId.WOOD_HAMMER, MoveId.WOOD_HAMMER]); await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.SHUCKLE]); const [feebas, shuckle] = game.scene.getPlayerField(); - game.move.changeMoveset(feebas, [MoveId.ASSIST, MoveId.SKETCH, MoveId.PROTECT, MoveId.DRAGON_TAIL]); - game.move.changeMoveset(shuckle, [MoveId.ASSIST, MoveId.SKETCH, MoveId.PROTECT, MoveId.DRAGON_TAIL]); + game.move.changeMoveset(feebas, [MoveId.ASSIST, MoveId.WOOD_HAMMER]); + game.move.changeMoveset(shuckle, [MoveId.ASSIST, MoveId.WOOD_HAMMER]); game.move.select(MoveId.ASSIST, 0); game.move.select(MoveId.ASSIST, 1); diff --git a/test/test-utils/helpers/move-helper.ts b/test/test-utils/helpers/move-helper.ts index fd6a123a5bb..4fa14b573ab 100644 --- a/test/test-utils/helpers/move-helper.ts +++ b/test/test-utils/helpers/move-helper.ts @@ -209,12 +209,27 @@ export class MoveHelper extends GameManagerHelper { /** * Changes a pokemon's moveset to the given move(s). + * * Used when the normal moveset override can't be used (such as when it's necessary to check or update properties of the moveset). + * + * **Note**: Will disable the moveset override matching the pokemon's party. * @param pokemon - The {@linkcode Pokemon} being modified * @param moveset - The {@linkcode MoveId} (single or array) to change the Pokemon's moveset to. */ public changeMoveset(pokemon: Pokemon, moveset: MoveId | MoveId[]): void { + if (pokemon.isPlayer()) { + if (coerceArray(Overrides.MOVESET_OVERRIDE).length > 0) { + vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([]); + console.warn("Player moveset override disabled due to use of `game.move.changeMoveset`!"); + } + } else { + if (coerceArray(Overrides.OPP_MOVESET_OVERRIDE).length > 0) { + vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([]); + console.warn("Enemy moveset override disabled due to use of `game.move.changeMoveset`!"); + } + } moveset = coerceArray(moveset); + expect(moveset.length, "Cannot assign more than 4 moves to a moveset!").toBeLessThanOrEqual(4); pokemon.moveset = []; moveset.forEach(move => { pokemon.moveset.push(new PokemonMove(move)); From ab394db9cf57455b1034694cb285bf80dbce3900 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Fri, 25 Jul 2025 19:39:25 -0400 Subject: [PATCH 08/76] [Refactor] Minor cleanup of `initExpKeys` (#6127) --- src/battle-scene.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 62351c4a833..4c846a019a1 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -699,16 +699,16 @@ export class BattleScene extends SceneBase { if (expSpriteKeys.size > 0) { return; } - this.cachedFetch("./exp-sprites.json") - .then(res => res.json()) - .then(keys => { - if (Array.isArray(keys)) { - for (const key of keys) { - expSpriteKeys.add(key); - } - } - Promise.resolve(); - }); + const res = await this.cachedFetch("./exp-sprites.json"); + const keys = await res.json(); + if (!Array.isArray(keys)) { + throw new Error("EXP Sprites were not array when fetched!"); + } + + // TODO: Optimize this + for (const k of keys) { + expSpriteKeys.add(k); + } } /** From 2e3a7d47e0a5f17c303fd762c7740a589e8fac17 Mon Sep 17 00:00:00 2001 From: Acelynn Zhang <102631387+acelynnzhang@users.noreply.github.com> Date: Fri, 25 Jul 2025 19:55:13 -0400 Subject: [PATCH 09/76] [Bug] Fix Thrash continuing on caught Pokemon (#6144) Fix Thrash continuing on caught Pokemon --- src/phases/attempt-capture-phase.ts | 1 + test/phases/capture-phase.test.ts | 37 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 test/phases/capture-phase.test.ts diff --git a/src/phases/attempt-capture-phase.ts b/src/phases/attempt-capture-phase.ts index 604d4fd8384..fcddd23dd20 100644 --- a/src/phases/attempt-capture-phase.ts +++ b/src/phases/attempt-capture-phase.ts @@ -279,6 +279,7 @@ export class AttemptCapturePhase extends PokemonPhase { globalScene.updateModifiers(true); removePokemon(); if (newPokemon) { + newPokemon.leaveField(true, true, false); newPokemon.loadAssets().then(end); } else { end(); diff --git a/test/phases/capture-phase.test.ts b/test/phases/capture-phase.test.ts new file mode 100644 index 00000000000..45a915ebb55 --- /dev/null +++ b/test/phases/capture-phase.test.ts @@ -0,0 +1,37 @@ +import { AbilityId } from "#enums/ability-id"; +import { MoveId } from "#enums/move-id"; +import { SpeciesId } from "#enums/species-id"; +import { GameManager } from "#test/test-utils/game-manager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it } from "vitest"; + +describe("Capture Phase", () => { + 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 + .ability(AbilityId.BALL_FETCH) + .battleStyle("single") + .criticalHits(false) + .enemySpecies(SpeciesId.MAGIKARP) + .enemyAbility(AbilityId.BALL_FETCH) + .enemyMoveset(MoveId.SPLASH) + .startingLevel(100) + .enemyLevel(100); + }); + + // TODO: write test and enable once the phase's logic has been refactored + it.todo("should reset the captured Pokemon's temporary data"); +}); From 556d588d67618d87d755d081d718cc4e90ef3173 Mon Sep 17 00:00:00 2001 From: damocleas Date: Fri, 25 Jul 2025 21:20:48 -0400 Subject: [PATCH 10/76] [UI/UX] Replace 'Neutral' in the Arena Flyout with 'Field' (#6139) Update arena-flyout.ts for Field > Neutral --- src/ui/arena-flyout.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ui/arena-flyout.ts b/src/ui/arena-flyout.ts index 43cc553d936..970c65c8978 100644 --- a/src/ui/arena-flyout.ts +++ b/src/ui/arena-flyout.ts @@ -86,14 +86,14 @@ export class ArenaFlyout extends Phaser.GameObjects.Container { private flyoutTextHeaderPlayer: Phaser.GameObjects.Text; /** The {@linkcode Phaser.GameObjects.Text} header used to indicate the enemy's effects */ private flyoutTextHeaderEnemy: Phaser.GameObjects.Text; - /** The {@linkcode Phaser.GameObjects.Text} header used to indicate neutral effects */ + /** The {@linkcode Phaser.GameObjects.Text} header used to indicate field effects */ private flyoutTextHeaderField: Phaser.GameObjects.Text; /** The {@linkcode Phaser.GameObjects.Text} used to indicate the player's effects */ private flyoutTextPlayer: Phaser.GameObjects.Text; /** The {@linkcode Phaser.GameObjects.Text} used to indicate the enemy's effects */ private flyoutTextEnemy: Phaser.GameObjects.Text; - /** The {@linkcode Phaser.GameObjects.Text} used to indicate neutral effects */ + /** The {@linkcode Phaser.GameObjects.Text} used to indicate field effects */ private flyoutTextField: Phaser.GameObjects.Text; /** Container for all field effects observed by this object */ @@ -163,7 +163,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container { this.flyoutTextHeaderField = addTextObject( this.flyoutWidth / 2, 5, - i18next.t("arenaFlyout:neutral"), + i18next.t("arenaFlyout:field"), TextStyle.SUMMARY_GREEN, ); this.flyoutTextHeaderField.setFontSize(54); From bb46ba9f6049c2c6a5f3e56807dfeb0e8f21afb4 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Sat, 26 Jul 2025 00:58:15 -0400 Subject: [PATCH 11/76] [Dev] Added typedoc deployments for Beta (#6147) --- .github/workflows/github-pages.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index fff90047df2..1588a15afeb 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -4,6 +4,7 @@ on: push: branches: - main + - beta pull_request: branches: - main From 4f259e2c2f4870a2962fe4608c19d6a521236183 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Fri, 25 Jul 2025 23:30:58 -0600 Subject: [PATCH 12/76] [Misc] Fix import in decrypt-save.js (#6149) --- scripts/decrypt-save.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/decrypt-save.js b/scripts/decrypt-save.js index 219cdb47bed..e50f152f159 100644 --- a/scripts/decrypt-save.js +++ b/scripts/decrypt-save.js @@ -2,7 +2,9 @@ // biome-ignore lint/performance/noNamespaceImport: This is how you import fs from node import * as fs from "node:fs"; -import { AES, enc } from "crypto-js"; +import crypto_js from "crypto-js"; + +const { AES, enc } = crypto_js; const SAVE_KEY = "x0i2O7WRiANTqPmZ"; @@ -144,7 +146,7 @@ function main() { process.exit(0); } - writeToFile(destPath, decrypt); + writeToFile(args[1], decrypt); } main(); From 0ef1a34030289b44b8fe1d705769c9f203756ecf Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sat, 26 Jul 2025 16:07:16 -0600 Subject: [PATCH 13/76] [Refactor][Bug] Illusion no longer overwrites data of original Pokemon https://github.com/pagefaultgames/pokerogue/pull/6140 --- src/@types/illusion-data.ts | 26 ++-- src/data/abilities/ability.ts | 10 +- src/field/pokemon.ts | 251 ++++++++++++++++---------------- src/phases/evolution-phase.ts | 2 +- src/system/pokemon-data.ts | 10 +- src/ui/party-ui-handler.ts | 13 +- src/ui/summary-ui-handler.ts | 23 +-- test/abilities/illusion.test.ts | 4 +- 8 files changed, 164 insertions(+), 175 deletions(-) diff --git a/src/@types/illusion-data.ts b/src/@types/illusion-data.ts index 854c98c8cc9..b152e3fdf59 100644 --- a/src/@types/illusion-data.ts +++ b/src/@types/illusion-data.ts @@ -8,20 +8,14 @@ import type { Variant } from "#sprites/variant"; * Data pertaining to a Pokemon's Illusion. */ export interface IllusionData { - basePokemon: { - /** The actual name of the Pokemon */ - name: string; - /** The actual nickname of the Pokemon */ - nickname: string; - /** Whether the base pokemon is shiny or not */ - shiny: boolean; - /** The shiny variant of the base pokemon */ - variant: Variant; - /** Whether the fusion species of the base pokemon is shiny or not */ - fusionShiny: boolean; - /** The variant of the fusion species of the base pokemon */ - fusionVariant: Variant; - }; + /** The name of pokemon featured in the illusion */ + name: string; + /** The nickname of the pokemon featured in the illusion */ + nickname: string; + /** Whether the pokemon featured in the illusion is shiny or not */ + shiny: boolean; + /** The variant of the pokemon featured in the illusion */ + variant: Variant; /** The species of the illusion */ species: SpeciesId; /** The formIndex of the illusion */ @@ -34,6 +28,10 @@ export interface IllusionData { fusionSpecies?: PokemonSpecies; /** The fusionFormIndex of the illusion */ fusionFormIndex?: number; + /** Whether the fusion species of the pokemon featured in the illusion is shiny or not */ + fusionShiny?: boolean; + /** The variant of the fusion species of the pokemon featured in the illusion */ + fusionVariant?: Variant; /** The fusionGender of the illusion if it's a fusion */ fusionGender?: Gender; /** The level of the illusion (not used currently) */ diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index 62d6974d3a2..0ee1a51a78e 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -15,6 +15,7 @@ import { SpeciesFormChangeAbilityTrigger, SpeciesFormChangeWeatherTrigger } from import { Gender } from "#data/gender"; import { getPokeballName } from "#data/pokeball"; import { pokemonFormChanges } from "#data/pokemon-forms"; +import type { PokemonSpecies } from "#data/pokemon-species"; import { getNonVolatileStatusEffects, getStatusEffectDescriptor, getStatusEffectHealText } from "#data/status-effect"; import { TerrainType } from "#data/terrain"; import type { Weather } from "#data/weather"; @@ -6001,8 +6002,13 @@ export class IllusionPreSummonAbAttr extends PreSummonAbAttr { const party: Pokemon[] = (pokemon.isPlayer() ? globalScene.getPlayerParty() : globalScene.getEnemyParty()).filter( p => p.isAllowedInBattle(), ); - const lastPokemon: Pokemon = party.filter(p => p !== pokemon).at(-1) || pokemon; - pokemon.setIllusion(lastPokemon); + let illusionPokemon: Pokemon | PokemonSpecies; + if (pokemon.hasTrainer()) { + illusionPokemon = party.filter(p => p !== pokemon).at(-1) || pokemon; + } else { + illusionPokemon = globalScene.arena.randomSpecies(globalScene.currentBattle.waveIndex, pokemon.level); + } + pokemon.setIllusion(illusionPokemon); } /** @returns Whether the illusion can be applied. */ diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 32edd721cd9..70bc98cb02e 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -442,10 +442,9 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { * @returns The name to render for this {@linkcode Pokemon}. */ getNameToRender(useIllusion = true) { - const name: string = - !useIllusion && this.summonData.illusion ? this.summonData.illusion.basePokemon.name : this.name; - const nickname: string = - !useIllusion && this.summonData.illusion ? this.summonData.illusion.basePokemon.nickname : this.nickname; + const illusion = this.summonData.illusion; + const name = useIllusion ? (illusion?.name ?? this.name) : this.name; + const nickname: string = useIllusion ? (illusion?.nickname ?? this.nickname) : this.nickname; try { if (nickname) { return decodeURIComponent(escape(atob(nickname))); // TODO: Remove `atob` and `escape`... eventually... @@ -463,7 +462,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { * @returns The {@linkcode PokeballType} that will be shown when this Pokemon is sent out into battle. */ getPokeball(useIllusion = false): PokeballType { - return useIllusion && this.summonData.illusion ? this.summonData.illusion.pokeball : this.pokeball; + return useIllusion ? (this.summonData.illusion?.pokeball ?? this.pokeball) : this.pokeball; } init(): void { @@ -609,24 +608,33 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { } /** - * Generate an illusion of the last pokemon in the party, as other wild pokemon in the area. + * Set this pokemon's illusion to the data of the given pokemon. + * + * @remarks + * When setting the illusion of a wild pokemon, a {@linkcode PokemonSpecies} is generally passed. + * When setting the illusion of a pokemon in this way, the fields required by illusion data + * but missing from `PokemonSpecies` are set as follows + * - `pokeball` and `nickname` are both inherited from this pokemon + * - `shiny` will always be set if this pokemon OR its fusion is shiny + * - `variant` will always be 0 + * - Fields related to fusion will be set to `undefined` or `0` as appropriate + * - The gender is set to be the same as this pokemon, if it is compatible with the provided pokemon. + * - If the provided pokemon can only ever exist as one gender, it is always that gender + * - If this pokemon is genderless but the provided pokemon isn't, then a gender roll is done based on this + * pokemon's ID */ - setIllusion(pokemon: Pokemon): boolean { - if (this.summonData.illusion) { - this.breakIllusion(); - } - if (this.hasTrainer()) { + setIllusion(pokemon: Pokemon | PokemonSpecies): boolean { + this.breakIllusion(); + if (pokemon instanceof Pokemon) { const speciesId = pokemon.species.speciesId; this.summonData.illusion = { - basePokemon: { - name: this.name, - nickname: this.nickname, - shiny: this.shiny, - variant: this.variant, - fusionShiny: this.fusionShiny, - fusionVariant: this.fusionVariant, - }, + name: pokemon.name, + nickname: pokemon.nickname, + shiny: pokemon.shiny, + variant: pokemon.variant, + fusionShiny: pokemon.fusionShiny, + fusionVariant: pokemon.fusionVariant, species: speciesId, formIndex: pokemon.formIndex, gender: pokemon.gender, @@ -636,54 +644,61 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { fusionGender: pokemon.fusionGender, }; - this.name = pokemon.name; - this.nickname = pokemon.nickname; - this.shiny = pokemon.shiny; - this.variant = pokemon.variant; - this.fusionVariant = pokemon.fusionVariant; - this.fusionShiny = pokemon.fusionShiny; - if (this.shiny) { + if (pokemon.shiny || pokemon.fusionShiny) { this.initShinySparkle(); } - this.loadAssets(false, true).then(() => this.playAnim()); - this.updateInfo(); } else { - const randomIllusion: PokemonSpecies = globalScene.arena.randomSpecies( - globalScene.currentBattle.waveIndex, - this.level, - ); - + // Correct the gender in case the illusioned species has a gender incompatible with this pokemon + let gender = this.gender; + switch (pokemon.malePercent) { + case null: + gender = Gender.GENDERLESS; + break; + case 0: + gender = Gender.FEMALE; + break; + case 100: + gender = Gender.MALE; + break; + default: + gender = (this.id % 256) * 0.390625 < pokemon.malePercent ? Gender.MALE : Gender.FEMALE; + } + /* + TODO: Allow setting `variant` to something other than 0, which would require first loading the + assets for the provided species, as its entry would otherwise not + be guaranteed to exist in the `variantData` map. But this would prevent `summonData` from being populated + until the assets are loaded, which would cause issues as this method cannot be easily promisified. + */ this.summonData.illusion = { - basePokemon: { - name: this.name, - nickname: this.nickname, - shiny: this.shiny, - variant: this.variant, - fusionShiny: this.fusionShiny, - fusionVariant: this.fusionVariant, - }, - species: randomIllusion.speciesId, - formIndex: randomIllusion.formIndex, - gender: this.gender, + fusionShiny: false, + fusionVariant: 0, + shiny: this.shiny || this.fusionShiny, + variant: 0, + nickname: this.nickname, + name: pokemon.name, + species: pokemon.speciesId, + formIndex: pokemon.formIndex, + gender, pokeball: this.pokeball, }; - this.name = randomIllusion.name; - this.loadAssets(false, true).then(() => this.playAnim()); + if (this.shiny || this.fusionShiny) { + this.initShinySparkle(); + } } + this.loadAssets(false, true).then(() => this.playAnim()); + this.updateInfo(); return true; } + /** + * Break the illusion of this pokemon, if it has an active illusion. + * @returns Whether an illusion was broken. + */ breakIllusion(): boolean { if (!this.summonData.illusion) { return false; } - this.name = this.summonData.illusion.basePokemon.name; - this.nickname = this.summonData.illusion.basePokemon.nickname; - this.shiny = this.summonData.illusion.basePokemon.shiny; - this.variant = this.summonData.illusion.basePokemon.variant; - this.fusionVariant = this.summonData.illusion.basePokemon.fusionVariant; - this.fusionShiny = this.summonData.illusion.basePokemon.fusionShiny; this.summonData.illusion = null; if (this.isOnField()) { globalScene.playSound("PRSFX- Transform"); @@ -718,8 +733,12 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { // Assets for moves loadPromises.push(loadMoveAnimations(this.getMoveset().map(m => m.getMove().id))); + /** alias for `this.summonData.illusion`; bangs on this are safe when guarded with `useIllusion` being true */ + const illusion = this.summonData.illusion; + useIllusion = useIllusion && !!illusion; + // Load the assets for the species form - const formIndex = useIllusion && this.summonData.illusion ? this.summonData.illusion.formIndex : this.formIndex; + const formIndex = useIllusion ? illusion!.formIndex : this.formIndex; loadPromises.push( this.getSpeciesForm(false, useIllusion).loadAssets( this.getGender(useIllusion) === Gender.FEMALE, @@ -736,16 +755,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { ); } if (this.getFusionSpeciesForm()) { - const fusionFormIndex = - useIllusion && this.summonData.illusion ? this.summonData.illusion.fusionFormIndex : this.fusionFormIndex; - const fusionShiny = - !useIllusion && this.summonData.illusion?.basePokemon - ? this.summonData.illusion.basePokemon.fusionShiny - : this.fusionShiny; - const fusionVariant = - !useIllusion && this.summonData.illusion?.basePokemon - ? this.summonData.illusion.basePokemon.fusionVariant - : this.fusionVariant; + const { fusionFormIndex, fusionShiny, fusionVariant } = useIllusion ? illusion! : this; loadPromises.push( this.getFusionSpeciesForm(false, useIllusion).loadAssets( this.getFusionGender(false, useIllusion) === Gender.FEMALE, @@ -933,8 +943,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { return this.getSpeciesForm(ignoreOverride, false).getSpriteKey( this.getGender(ignoreOverride) === Gender.FEMALE, this.formIndex, - this.summonData.illusion?.basePokemon.shiny ?? this.shiny, - this.summonData.illusion?.basePokemon.variant ?? this.variant, + this.isShiny(false), + this.getVariant(false), ); } @@ -977,11 +987,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { } getIconAtlasKey(ignoreOverride = false, useIllusion = true): string { - // TODO: confirm the correct behavior here (is it intentional that the check fails if `illusion.formIndex` is `0`?) - const formIndex = - useIllusion && this.summonData.illusion?.formIndex ? this.summonData.illusion.formIndex : this.formIndex; - const variant = - !useIllusion && this.summonData.illusion ? this.summonData.illusion.basePokemon.variant : this.variant; + const illusion = this.summonData.illusion; + const { formIndex, variant } = useIllusion && illusion ? illusion : this; return this.getSpeciesForm(ignoreOverride, useIllusion).getIconAtlasKey( formIndex, this.isBaseShiny(useIllusion), @@ -990,15 +997,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { } getFusionIconAtlasKey(ignoreOverride = false, useIllusion = true): string { - // TODO: confirm the correct behavior here (is it intentional that the check fails if `illusion.fusionFormIndex` is `0`?) - const fusionFormIndex = - useIllusion && this.summonData.illusion?.fusionFormIndex - ? this.summonData.illusion.fusionFormIndex - : this.fusionFormIndex; - const fusionVariant = - !useIllusion && this.summonData.illusion - ? this.summonData.illusion.basePokemon.fusionVariant - : this.fusionVariant; + const illusion = this.summonData.illusion; + const { fusionFormIndex, fusionVariant } = useIllusion && illusion ? illusion : this; return this.getFusionSpeciesForm(ignoreOverride, useIllusion).getIconAtlasKey( fusionFormIndex, this.isFusionShiny(), @@ -1006,11 +1006,9 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { ); } - getIconId(ignoreOverride?: boolean, useIllusion = true): string { - const formIndex = - useIllusion && this.summonData.illusion?.formIndex ? this.summonData.illusion?.formIndex : this.formIndex; - const variant = - !useIllusion && !!this.summonData.illusion ? this.summonData.illusion?.basePokemon.variant : this.variant; + getIconId(ignoreOverride?: boolean, useIllusion = false): string { + const illusion = this.summonData.illusion; + const { formIndex, variant } = useIllusion && illusion ? illusion : this; return this.getSpeciesForm(ignoreOverride, useIllusion).getIconId( this.getGender(ignoreOverride, useIllusion) === Gender.FEMALE, formIndex, @@ -1020,14 +1018,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { } getFusionIconId(ignoreOverride?: boolean, useIllusion = true): string { - const fusionFormIndex = - useIllusion && this.summonData.illusion?.fusionFormIndex - ? this.summonData.illusion?.fusionFormIndex - : this.fusionFormIndex; - const fusionVariant = - !useIllusion && !!this.summonData.illusion - ? this.summonData.illusion?.basePokemon.fusionVariant - : this.fusionVariant; + const illusion = this.summonData.illusion; + const { fusionFormIndex, fusionVariant } = useIllusion && illusion ? illusion : this; return this.getFusionSpeciesForm(ignoreOverride, useIllusion).getIconId( this.getFusionGender(ignoreOverride, useIllusion) === Gender.FEMALE, fusionFormIndex, @@ -1702,29 +1694,23 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { * @returns Whether this Pokemon is shiny */ isShiny(useIllusion = false): boolean { - if (!useIllusion && this.summonData.illusion) { - return ( - this.summonData.illusion.basePokemon?.shiny || - (this.summonData.illusion.fusionSpecies && this.summonData.illusion.basePokemon?.fusionShiny) || - false - ); + if (useIllusion) { + const illusion = this.summonData.illusion; + return illusion?.shiny || (!!illusion?.fusionSpecies && !!illusion.fusionShiny); } return this.shiny || (this.isFusion(useIllusion) && this.fusionShiny); } isBaseShiny(useIllusion = false) { - if (!useIllusion && this.summonData.illusion) { - return !!this.summonData.illusion.basePokemon?.shiny; - } - return this.shiny; + return useIllusion ? (this.summonData.illusion?.shiny ?? this.shiny) : this.shiny; } isFusionShiny(useIllusion = false) { - if (!useIllusion && this.summonData.illusion) { - return !!this.summonData.illusion.basePokemon?.fusionShiny; + if (!this.isFusion(useIllusion)) { + return false; } - return this.isFusion(useIllusion) && this.fusionShiny; + return useIllusion ? (this.summonData.illusion?.fusionShiny ?? this.fusionShiny) : this.fusionShiny; } /** @@ -1733,39 +1719,48 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { * @returns Whether this pokemon's base and fusion counterparts are both shiny. */ isDoubleShiny(useIllusion = false): boolean { - if (!useIllusion && this.summonData.illusion?.basePokemon) { - return ( - this.isFusion(false) && - this.summonData.illusion.basePokemon.shiny && - this.summonData.illusion.basePokemon.fusionShiny - ); - } - - return this.isFusion(useIllusion) && this.shiny && this.fusionShiny; + return this.isFusion(useIllusion) && this.isBaseShiny(useIllusion) && this.isFusionShiny(useIllusion); } /** * Return this Pokemon's {@linkcode Variant | shiny variant}. + * If a fusion, returns the maximum of the two variants. * Only meaningful if this pokemon is actually shiny. * @param useIllusion - Whether to consider this pokemon's illusion if present; default `false` * @returns The shiny variant of this Pokemon. */ getVariant(useIllusion = false): Variant { - if (!useIllusion && this.summonData.illusion) { - return !this.isFusion(false) - ? this.summonData.illusion.basePokemon!.variant - : (Math.max(this.variant, this.fusionVariant) as Variant); + const illusion = this.summonData.illusion; + const baseVariant = useIllusion ? (illusion?.variant ?? this.variant) : this.variant; + if (!this.isFusion(useIllusion)) { + return baseVariant; } - - return !this.isFusion(true) ? this.variant : (Math.max(this.variant, this.fusionVariant) as Variant); + const fusionVariant = useIllusion ? (illusion?.fusionVariant ?? this.fusionVariant) : this.fusionVariant; + return Math.max(baseVariant, fusionVariant) as Variant; } - // TODO: Clarify how this differs from `getVariant` - getBaseVariant(doubleShiny: boolean): Variant { - if (doubleShiny) { - return this.summonData.illusion?.basePokemon?.variant ?? this.variant; + /** + * Return the base pokemon's variant. Equivalent to {@linkcode getVariant} if this pokemon is not a fusion. + * @returns The shiny variant of this Pokemon's base species. + */ + getBaseVariant(useIllusion = false): Variant { + const illusion = this.summonData.illusion; + return useIllusion && illusion ? (illusion.variant ?? this.variant) : this.variant; + } + + /** + * Return the fused pokemon's variant. + * + * @remarks + * Always returns `0` if the pokemon is not a fusion. + * @returns The shiny variant of this pokemon's fusion species. + */ + getFusionVariant(useIllusion = false): Variant { + if (!this.isFusion(useIllusion)) { + return 0; } - return this.getVariant(); + const illusion = this.summonData.illusion; + return illusion ? (illusion.fusionVariant ?? this.fusionVariant) : this.fusionVariant; } /** @@ -1782,7 +1777,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { * @returns Whether this Pokemon is currently fused with another species. */ isFusion(useIllusion = false): boolean { - return useIllusion && this.summonData.illusion ? !!this.summonData.illusion.fusionSpecies : !!this.fusionSpecies; + return useIllusion ? !!this.summonData.illusion?.fusionSpecies : !!this.fusionSpecies; } /** @@ -1792,9 +1787,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { * @see {@linkcode getNameToRender} - gets this Pokemon's display name. */ getName(useIllusion = false): string { - return !useIllusion && this.summonData.illusion?.basePokemon - ? this.summonData.illusion.basePokemon.name - : this.name; + return useIllusion ? (this.summonData.illusion?.name ?? this.name) : this.name; } /** diff --git a/src/phases/evolution-phase.ts b/src/phases/evolution-phase.ts index f8bee8371f2..cad79455af3 100644 --- a/src/phases/evolution-phase.ts +++ b/src/phases/evolution-phase.ts @@ -135,7 +135,7 @@ export class EvolutionPhase extends Phase { sprite .setPipelineData("ignoreTimeTint", true) - .setPipelineData("spriteKey", pokemon.getSpriteKey()) + .setPipelineData("spriteKey", spriteKey) .setPipelineData("shiny", pokemon.shiny) .setPipelineData("variant", pokemon.variant); diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 9cea08bfb13..69c1539d944 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -88,12 +88,12 @@ export class PokemonData { this.id = source.id; this.player = sourcePokemon?.isPlayer() ?? source.player; this.species = sourcePokemon?.species.speciesId ?? source.species; - this.nickname = sourcePokemon?.summonData.illusion?.basePokemon.nickname ?? source.nickname; + this.nickname = source.nickname; this.formIndex = Math.max(Math.min(source.formIndex, getPokemonSpecies(this.species).forms.length - 1), 0); this.abilityIndex = source.abilityIndex; this.passive = source.passive; - this.shiny = sourcePokemon?.summonData.illusion?.basePokemon.shiny ?? source.shiny; - this.variant = sourcePokemon?.summonData.illusion?.basePokemon.variant ?? source.variant; + this.shiny = source.shiny; + this.variant = source.variant; this.pokeball = source.pokeball ?? PokeballType.POKEBALL; this.level = source.level; this.exp = source.exp; @@ -134,8 +134,8 @@ export class PokemonData { this.fusionSpecies = sourcePokemon?.fusionSpecies?.speciesId ?? source.fusionSpecies; this.fusionFormIndex = source.fusionFormIndex; this.fusionAbilityIndex = source.fusionAbilityIndex; - this.fusionShiny = sourcePokemon?.summonData.illusion?.basePokemon.fusionShiny ?? source.fusionShiny; - this.fusionVariant = sourcePokemon?.summonData.illusion?.basePokemon.fusionVariant ?? source.fusionVariant; + this.fusionShiny = source.fusionShiny; + this.fusionVariant = source.fusionVariant; this.fusionGender = source.fusionGender; this.fusionLuck = source.fusionLuck ?? (source.fusionShiny ? source.fusionVariant + 1 : 0); this.fusionTeraType = (source.fusionTeraType ?? 0) as PokemonType; diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index ce5f60813c7..956e4c52e39 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -1791,17 +1791,16 @@ class PartySlot extends Phaser.GameObjects.Container { const shinyStar = globalScene.add.image(0, 0, `shiny_star_small${doubleShiny ? "_1" : ""}`); shinyStar.setOrigin(0, 0); shinyStar.setPositionRelative(this.slotName, -9, 3); - shinyStar.setTint(getVariantTint(this.pokemon.getBaseVariant(doubleShiny))); + shinyStar.setTint(getVariantTint(this.pokemon.getBaseVariant())); slotInfoContainer.add(shinyStar); if (doubleShiny) { - const fusionShinyStar = globalScene.add.image(0, 0, "shiny_star_small_2"); - fusionShinyStar.setOrigin(0, 0); - fusionShinyStar.setPosition(shinyStar.x, shinyStar.y); - fusionShinyStar.setTint( - getVariantTint(this.pokemon.summonData.illusion?.basePokemon.fusionVariant ?? this.pokemon.fusionVariant), - ); + const fusionShinyStar = globalScene.add + .image(0, 0, "shiny_star_small_2") + .setOrigin(0) + .setPosition(shinyStar.x, shinyStar.y) + .setTint(getVariantTint(this.pokemon.fusionVariant)); slotInfoContainer.add(fusionShinyStar); } diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index b4df4612546..770bb1d9d29 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -354,18 +354,13 @@ export class SummaryUiHandler extends UiHandler { } catch (err: unknown) { console.error(`Failed to play animation for ${spriteKey}`, err); } - this.pokemonSprite.setPipelineData("teraColor", getTypeRgb(this.pokemon.getTeraType())); - this.pokemonSprite.setPipelineData("isTerastallized", this.pokemon.isTerastallized); - this.pokemonSprite.setPipelineData("ignoreTimeTint", true); - this.pokemonSprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey()); - this.pokemonSprite.setPipelineData( - "shiny", - this.pokemon.summonData.illusion?.basePokemon.shiny ?? this.pokemon.shiny, - ); - this.pokemonSprite.setPipelineData( - "variant", - this.pokemon.summonData.illusion?.basePokemon.variant ?? this.pokemon.variant, - ); + this.pokemonSprite + .setPipelineData("teraColor", getTypeRgb(this.pokemon.getTeraType())) + .setPipelineData("isTerastallized", this.pokemon.isTerastallized) + .setPipelineData("ignoreTimeTint", true) + .setPipelineData("spriteKey", this.pokemon.getSpriteKey()) + .setPipelineData("shiny", this.pokemon.shiny) + .setPipelineData("variant", this.pokemon.variant); ["spriteColors", "fusionSpriteColors"].map(k => { delete this.pokemonSprite.pipelineData[`${k}Base`]; if (this.pokemon?.summonData.speciesForm) { @@ -463,9 +458,7 @@ export class SummaryUiHandler extends UiHandler { this.fusionShinyIcon.setPosition(this.shinyIcon.x, this.shinyIcon.y); this.fusionShinyIcon.setVisible(doubleShiny); if (isFusion) { - this.fusionShinyIcon.setTint( - getVariantTint(this.pokemon.summonData.illusion?.basePokemon.fusionVariant ?? this.pokemon.fusionVariant), - ); + this.fusionShinyIcon.setTint(getVariantTint(this.pokemon.fusionVariant)); } this.pokeball.setFrame(getPokeballAtlasKey(this.pokemon.pokeball)); diff --git a/test/abilities/illusion.test.ts b/test/abilities/illusion.test.ts index 17a1fa8dd3d..e48cd9e9b78 100644 --- a/test/abilities/illusion.test.ts +++ b/test/abilities/illusion.test.ts @@ -145,8 +145,8 @@ describe("Abilities - Illusion", () => { const zoroark = game.scene.getPlayerPokemon()!; - expect(zoroark.name).equals("Axew"); - expect(zoroark.getNameToRender()).equals("axew nickname"); + expect(zoroark.summonData.illusion?.name).equals("Axew"); + expect(zoroark.getNameToRender(true)).equals("axew nickname"); expect(zoroark.getGender(false, true)).equals(Gender.FEMALE); expect(zoroark.isShiny(true)).equals(true); expect(zoroark.getPokeball(true)).equals(PokeballType.GREAT_BALL); From 08d721642457d47bf9f4d325b44900caf608ca8c Mon Sep 17 00:00:00 2001 From: SmhMyHead <191356399+SmhMyHead@users.noreply.github.com> Date: Sun, 27 Jul 2025 00:34:21 +0200 Subject: [PATCH 14/76] [UI/UX] Added "Hide Username" Setting (#6105) * [UI/UX] Added "Hide Username" Setting * Mask tid with asterisk instead of hiding completely --------- Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> --- src/battle-scene.ts | 1 + src/system/settings/settings.ts | 11 +++++++++++ src/ui/summary-ui-handler.ts | 22 ++++++++++++++++------ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 4c846a019a1..7e9360270ad 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -236,6 +236,7 @@ export class BattleScene extends SceneBase { public enableTouchControls = false; public enableVibration = false; public showBgmBar = true; + public hideUsername = false; /** Determines the selected battle style. */ public battleStyle: BattleStyle = BattleStyle.SWITCH; /** diff --git a/src/system/settings/settings.ts b/src/system/settings/settings.ts index 19d10baedfd..33087f2509e 100644 --- a/src/system/settings/settings.ts +++ b/src/system/settings/settings.ts @@ -171,6 +171,7 @@ export const SettingKeys = { UI_Volume: "UI_SOUND_EFFECTS", Battle_Music: "BATTLE_MUSIC", Show_BGM_Bar: "SHOW_BGM_BAR", + Hide_Username: "HIDE_USERNAME", Move_Touch_Controls: "MOVE_TOUCH_CONTROLS", Shop_Overlay_Opacity: "SHOP_OVERLAY_OPACITY", }; @@ -625,6 +626,13 @@ export const Setting: Array = [ default: 1, type: SettingType.DISPLAY, }, + { + key: SettingKeys.Hide_Username, + label: i18next.t("settings:hideUsername"), + options: OFF_ON, + default: 0, + type: SettingType.DISPLAY, + }, { key: SettingKeys.Master_Volume, label: i18next.t("settings:masterVolume"), @@ -792,6 +800,9 @@ export function setSetting(setting: string, value: number): boolean { case SettingKeys.Show_BGM_Bar: globalScene.showBgmBar = Setting[index].options[value].value === "On"; break; + case SettingKeys.Hide_Username: + globalScene.hideUsername = Setting[index].options[value].value === "On"; + break; case SettingKeys.Candy_Upgrade_Notification: if (globalScene.candyUpgradeNotification === value) { break; diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index 770bb1d9d29..7661dab068e 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -803,24 +803,34 @@ export class SummaryUiHandler extends UiHandler { case Page.PROFILE: { const profileContainer = globalScene.add.container(0, -pageBg.height); pageContainer.add(profileContainer); + const otColor = + globalScene.gameData.gender === PlayerGender.FEMALE ? TextStyle.SUMMARY_PINK : TextStyle.SUMMARY_BLUE; + const usernameReplacement = + globalScene.gameData.gender === PlayerGender.FEMALE + ? i18next.t("trainerNames:player_f") + : i18next.t("trainerNames:player_m"); // TODO: should add field for original trainer name to Pokemon object, to support gift/traded Pokemon from MEs const trainerText = addBBCodeTextObject( 7, 12, - `${i18next.t("pokemonSummary:ot")}/${getBBCodeFrag(loggedInUser?.username || i18next.t("pokemonSummary:unknown"), globalScene.gameData.gender === PlayerGender.FEMALE ? TextStyle.SUMMARY_PINK : TextStyle.SUMMARY_BLUE)}`, + `${i18next.t("pokemonSummary:ot")}/${getBBCodeFrag( + !globalScene.hideUsername + ? loggedInUser?.username || i18next.t("pokemonSummary:unknown") + : usernameReplacement, + otColor, + )}`, TextStyle.SUMMARY_ALT, - ); - trainerText.setOrigin(0, 0); + ).setOrigin(0); profileContainer.add(trainerText); + const idToDisplay = globalScene.hideUsername ? "*****" : globalScene.gameData.trainerId.toString(); const trainerIdText = addTextObject( 141, 12, - `${i18next.t("pokemonSummary:idNo")}${globalScene.gameData.trainerId.toString()}`, + `${i18next.t("pokemonSummary:idNo")}${idToDisplay}`, TextStyle.SUMMARY_ALT, - ); - trainerIdText.setOrigin(0, 0); + ).setOrigin(0); profileContainer.add(trainerIdText); const typeLabel = addTextObject(7, 28, `${i18next.t("pokemonSummary:type")}/`, TextStyle.WINDOW_ALT); From 30a6f4708105cf025474b6ff2a7215d91352953b Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Sat, 26 Jul 2025 19:23:18 -0700 Subject: [PATCH 15/76] [Dev] Add `dist/` to `ls-lint` ignore list --- .ls-lint.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ls-lint.yml b/.ls-lint.yml index 09d626af624..610218f8ed2 100644 --- a/.ls-lint.yml +++ b/.ls-lint.yml @@ -25,3 +25,4 @@ ignore: - .github - .git - public + - dist From a117ff9bc843fd2aae63b68f54f626059bec091f Mon Sep 17 00:00:00 2001 From: damocleas Date: Sat, 26 Jul 2025 22:31:55 -0400 Subject: [PATCH 16/76] [i18n] Update Locales --- public/locales | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales b/public/locales index 362b2c4fcc2..e2fbba17ea7 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit 362b2c4fcc20b31a7be6c2dab537055fbaeb247f +Subproject commit e2fbba17ea7a96068970ea98a8a84ed3e25b6f07 From 2f1cf2fc13c9b9108a04c8bcadb9667e8db8c0e6 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sat, 26 Jul 2025 20:35:39 -0600 Subject: [PATCH 17/76] [Beta] [Bug] Fix shiny display issues (#6154) Fix shininess check --- src/field/pokemon.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 70bc98cb02e..32229d80f37 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1694,12 +1694,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { * @returns Whether this Pokemon is shiny */ isShiny(useIllusion = false): boolean { - if (useIllusion) { - const illusion = this.summonData.illusion; - return illusion?.shiny || (!!illusion?.fusionSpecies && !!illusion.fusionShiny); - } - - return this.shiny || (this.isFusion(useIllusion) && this.fusionShiny); + return this.isBaseShiny(useIllusion) || this.isFusionShiny(useIllusion); } isBaseShiny(useIllusion = false) { From ed8858e07ddb9b23618f52032c3025777d179d77 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sat, 26 Jul 2025 20:58:06 -0600 Subject: [PATCH 18/76] [Bug][Beta] Make bounce delay use fixed int (#6156) Make bounce delay use fixed int --- src/ui/starter-select-ui-handler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 18a3fbc30a3..fcd8167a519 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -1476,7 +1476,7 @@ export class StarterSelectUiHandler extends MessageUiHandler { loop: -1, // Make the initial bounce a little randomly delayed delay: randIntRange(0, 50) * 5, - loopDelay: 1000, + loopDelay: fixedInt(1000), tweens: [ { targets: icon, From 1b8082a177d6cef98a4f9afefbb8d15f3d5859d0 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sun, 27 Jul 2025 11:46:56 -0600 Subject: [PATCH 19/76] [Refactor] Refactor UI text ts (#5946) * Add destroy method to pokemon-sprite-sparkle-handler * Move TextStyle to enums, convert into const object * Cleanup text.ts file * Add necessary explicit types for TextStyle let vars * Fix locales submodule commit * Fix merge issue --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/@types/ui.ts | 10 +++ src/battle-scene.ts | 3 +- .../mystery-encounter-dialogue.ts | 2 +- .../utils/encounter-dialogue-utils.ts | 2 +- src/data/nature.ts | 3 +- src/enums/text-style.ts | 59 +++++++++++++ src/field/damage-number-handler.ts | 3 +- src/field/pokemon-sprite-sparkle-handler.ts | 13 ++- src/modifier/modifier.ts | 3 +- src/phases/end-card-phase.ts | 3 +- src/phases/scan-ivs-phase.ts | 3 +- src/timed-event-manager.ts | 3 +- src/ui/ability-bar.ts | 3 +- src/ui/abstact-option-select-ui-handler.ts | 3 +- src/ui/achv-bar.ts | 3 +- src/ui/achvs-ui-handler.ts | 3 +- src/ui/admin-ui-handler.ts | 2 +- src/ui/arena-flyout.ts | 3 +- src/ui/ball-ui-handler.ts | 3 +- src/ui/base-stats-overlay.ts | 3 +- src/ui/battle-flyout.ts | 3 +- src/ui/battle-info/battle-info.ts | 3 +- src/ui/battle-info/enemy-battle-info.ts | 3 +- src/ui/battle-message-ui-handler.ts | 3 +- src/ui/bgm-bar.ts | 3 +- src/ui/candy-bar.ts | 3 +- src/ui/challenges-select-ui-handler.ts | 3 +- src/ui/command-ui-handler.ts | 3 +- src/ui/daily-run-scoreboard.ts | 3 +- src/ui/dropdown.ts | 3 +- src/ui/egg-counter-container.ts | 3 +- src/ui/egg-gacha-ui-handler.ts | 5 +- src/ui/egg-list-ui-handler.ts | 3 +- src/ui/evolution-scene-handler.ts | 3 +- src/ui/fight-ui-handler.ts | 5 +- src/ui/filter-bar.ts | 3 +- src/ui/filter-text.ts | 3 +- src/ui/form-modal-ui-handler.ts | 3 +- src/ui/game-stats-ui-handler.ts | 3 +- src/ui/loading-modal-ui-handler.ts | 3 +- src/ui/login-form-ui-handler.ts | 3 +- src/ui/menu-ui-handler.ts | 3 +- src/ui/modal-ui-handler.ts | 3 +- src/ui/modifier-select-ui-handler.ts | 3 +- src/ui/move-info-overlay.ts | 3 +- src/ui/mystery-encounter-ui-handler.ts | 3 +- src/ui/party-exp-bar.ts | 3 +- src/ui/party-ui-handler.ts | 3 +- src/ui/pokedex-info-overlay.ts | 3 +- src/ui/pokedex-mon-container.ts | 3 +- src/ui/pokedex-page-ui-handler.ts | 3 +- src/ui/pokedex-ui-handler.ts | 3 +- src/ui/pokemon-hatch-info-container.ts | 3 +- src/ui/pokemon-info-container.ts | 3 +- src/ui/registration-form-ui-handler.ts | 3 +- src/ui/run-history-ui-handler.ts | 3 +- src/ui/run-info-ui-handler.ts | 3 +- src/ui/save-slot-select-ui-handler.ts | 3 +- src/ui/session-reload-modal-ui-handler.ts | 3 +- .../settings/abstract-binding-ui-handler.ts | 3 +- .../abstract-control-settings-ui-handler.ts | 3 +- .../settings/abstract-settings-ui-handler.ts | 3 +- src/ui/settings/gamepad-binding-ui-handler.ts | 3 +- .../settings/keyboard-binding-ui-handler.ts | 3 +- src/ui/settings/navigation-menu.ts | 3 +- .../settings/settings-gamepad-ui-handler.ts | 3 +- .../settings/settings-keyboard-ui-handler.ts | 3 +- src/ui/starter-container.ts | 3 +- src/ui/starter-select-ui-handler.ts | 3 +- src/ui/stats-container.ts | 3 +- src/ui/summary-ui-handler.ts | 3 +- src/ui/text.ts | 82 ++----------------- src/ui/title-ui-handler.ts | 3 +- src/ui/ui-handler.ts | 2 +- src/ui/ui.ts | 3 +- src/ui/unavailable-modal-ui-handler.ts | 3 +- 76 files changed, 230 insertions(+), 150 deletions(-) create mode 100644 src/@types/ui.ts create mode 100644 src/enums/text-style.ts diff --git a/src/@types/ui.ts b/src/@types/ui.ts new file mode 100644 index 00000000000..10dab01c616 --- /dev/null +++ b/src/@types/ui.ts @@ -0,0 +1,10 @@ +import type Phaser from "phaser"; +import type InputText from "phaser3-rex-plugins/plugins/gameobjects/dom/inputtext/InputText"; + +export interface TextStyleOptions { + scale: number; + styleOptions: Phaser.Types.GameObjects.Text.TextStyle | InputText.IConfig; + shadowColor: string; + shadowXpos: number; + shadowYpos: number; +} diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 7e9360270ad..275f129a63a 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -67,6 +67,7 @@ import { PokemonType } from "#enums/pokemon-type"; import { ShopCursorTarget } from "#enums/shop-cursor-target"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; +import { TextStyle } from "#enums/text-style"; import type { TrainerSlot } from "#enums/trainer-slot"; import { TrainerType } from "#enums/trainer-type"; import { TrainerVariant } from "#enums/trainer-variant"; @@ -132,7 +133,7 @@ import { CharSprite } from "#ui/char-sprite"; import { PartyExpBar } from "#ui/party-exp-bar"; import { PokeballTray } from "#ui/pokeball-tray"; import { PokemonInfoContainer } from "#ui/pokemon-info-container"; -import { addTextObject, getTextColor, TextStyle } from "#ui/text"; +import { addTextObject, getTextColor } from "#ui/text"; import { UI } from "#ui/ui"; import { addUiThemeOverrides } from "#ui/ui-theme"; import { diff --git a/src/data/mystery-encounters/mystery-encounter-dialogue.ts b/src/data/mystery-encounters/mystery-encounter-dialogue.ts index 42383940755..385ccb5c246 100644 --- a/src/data/mystery-encounters/mystery-encounter-dialogue.ts +++ b/src/data/mystery-encounters/mystery-encounter-dialogue.ts @@ -1,4 +1,4 @@ -import type { TextStyle } from "#ui/text"; +import type { TextStyle } from "#enums/text-style"; export class TextDisplay { speaker?: string; diff --git a/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts b/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts index 4f4af94a88d..1ae0659b29e 100644 --- a/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts @@ -1,6 +1,6 @@ import { globalScene } from "#app/global-scene"; +import type { TextStyle } from "#enums/text-style"; import { UiTheme } from "#enums/ui-theme"; -import type { TextStyle } from "#ui/text"; import { getTextWithColors } from "#ui/text"; import { isNullOrUndefined } from "#utils/common"; import i18next from "i18next"; diff --git a/src/data/nature.ts b/src/data/nature.ts index 4f4e627daf3..41764ec4276 100644 --- a/src/data/nature.ts +++ b/src/data/nature.ts @@ -1,7 +1,8 @@ import { Nature } from "#enums/nature"; import { EFFECTIVE_STATS, getShortenedStatKey, Stat } from "#enums/stat"; +import { TextStyle } from "#enums/text-style"; import { UiTheme } from "#enums/ui-theme"; -import { getBBCodeFrag, TextStyle } from "#ui/text"; +import { getBBCodeFrag } from "#ui/text"; import { toReadableString } from "#utils/common"; import i18next from "i18next"; diff --git a/src/enums/text-style.ts b/src/enums/text-style.ts new file mode 100644 index 00000000000..964a985cdd6 --- /dev/null +++ b/src/enums/text-style.ts @@ -0,0 +1,59 @@ +export const TextStyle = Object.freeze({ + MESSAGE: 1, + WINDOW: 2, + WINDOW_ALT: 3, + WINDOW_BATTLE_COMMAND: 4, + BATTLE_INFO: 5, + PARTY: 6, + PARTY_RED: 7, + PARTY_CANCEL_BUTTON: 8, + INSTRUCTIONS_TEXT: 9, + MOVE_LABEL: 10, + SUMMARY: 11, + SUMMARY_DEX_NUM: 12, + SUMMARY_DEX_NUM_GOLD: 13, + SUMMARY_ALT: 14, + SUMMARY_HEADER: 15, + SUMMARY_RED: 16, + SUMMARY_BLUE: 17, + SUMMARY_PINK: 18, + SUMMARY_GOLD: 19, + SUMMARY_GRAY: 20, + SUMMARY_GREEN: 21, + SUMMARY_STATS: 22, + SUMMARY_STATS_BLUE: 23, + SUMMARY_STATS_PINK: 24, + SUMMARY_STATS_GOLD: 25, + LUCK_VALUE: 26, + STATS_HEXAGON: 27, + GROWTH_RATE_TYPE: 28, + MONEY: 29, // Money default styling (pale yellow) + MONEY_WINDOW: 30, // Money displayed in Windows (needs different colors based on theme) + HEADER_LABEL: 31, + STATS_LABEL: 32, + STATS_VALUE: 33, + SETTINGS_VALUE: 34, + SETTINGS_LABEL: 35, + SETTINGS_LABEL_NAVBAR: 36, + SETTINGS_SELECTED: 37, + SETTINGS_LOCKED: 38, + EGG_LIST: 39, + EGG_SUMMARY_NAME: 40, + EGG_SUMMARY_DEX: 41, + STARTER_VALUE_LIMIT: 42, + TOOLTIP_TITLE: 43, + TOOLTIP_CONTENT: 44, + FILTER_BAR_MAIN: 45, + MOVE_INFO_CONTENT: 46, + MOVE_PP_FULL: 47, + MOVE_PP_HALF_FULL: 48, + MOVE_PP_NEAR_EMPTY: 49, + MOVE_PP_EMPTY: 50, + SMALLER_WINDOW_ALT: 51, + BGM_BAR: 52, + PERFECT_IV: 53, + ME_OPTION_DEFAULT: 54, // Default style for choices in ME + ME_OPTION_SPECIAL: 55, // Style for choices with special requirements in ME + SHADOW_TEXT: 56 // to obscure unavailable options +}) +export type TextStyle = typeof TextStyle[keyof typeof TextStyle]; \ No newline at end of file diff --git a/src/field/damage-number-handler.ts b/src/field/damage-number-handler.ts index acb279a17a0..1bbacc19566 100644 --- a/src/field/damage-number-handler.ts +++ b/src/field/damage-number-handler.ts @@ -1,9 +1,10 @@ import { globalScene } from "#app/global-scene"; import type { BattlerIndex } from "#enums/battler-index"; import { HitResult } from "#enums/hit-result"; +import { TextStyle } from "#enums/text-style"; import type { Pokemon } from "#field/pokemon"; import type { DamageResult } from "#types/damage-result"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { fixedInt, formatStat } from "#utils/common"; type TextAndShadowArr = [string | null, string | null]; diff --git a/src/field/pokemon-sprite-sparkle-handler.ts b/src/field/pokemon-sprite-sparkle-handler.ts index 725229ce723..bd44dc03330 100644 --- a/src/field/pokemon-sprite-sparkle-handler.ts +++ b/src/field/pokemon-sprite-sparkle-handler.ts @@ -5,10 +5,11 @@ import { coerceArray, fixedInt, randInt } from "#utils/common"; export class PokemonSpriteSparkleHandler { private sprites: Set; + private counterTween?: Phaser.Tweens.Tween; + setup(): void { this.sprites = new Set(); - - globalScene.tweens.addCounter({ + this.counterTween = globalScene.tweens.addCounter({ duration: fixedInt(200), from: 0, to: 1, @@ -78,4 +79,12 @@ export class PokemonSpriteSparkleHandler { this.sprites.delete(s); } } + + destroy(): void { + this.removeAll(); + if (this.counterTween) { + this.counterTween.destroy(); + this.counterTween = undefined; + } + } } diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index f8c35b3e8f9..f6a9ed48847 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -23,6 +23,7 @@ import type { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { BATTLE_STATS, type PermanentStat, Stat, TEMP_BATTLE_STATS, type TempBattleStat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; +import { TextStyle } from "#enums/text-style"; import type { PlayerPokemon, Pokemon } from "#field/pokemon"; import type { DoubleBattleChanceBoosterModifierType, @@ -40,7 +41,7 @@ import type { } from "#modifiers/modifier-type"; import type { VoucherType } from "#system/voucher"; import type { ModifierInstanceMap, ModifierString } from "#types/modifier-types"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { BooleanHolder, hslToHex, isNullOrUndefined, NumberHolder, randSeedFloat, toDmgValue } from "#utils/common"; import { getModifierType } from "#utils/modifier-utils"; import i18next from "i18next"; diff --git a/src/phases/end-card-phase.ts b/src/phases/end-card-phase.ts index 5c3f6e1bf9b..b9b383db13d 100644 --- a/src/phases/end-card-phase.ts +++ b/src/phases/end-card-phase.ts @@ -1,7 +1,8 @@ import { globalScene } from "#app/global-scene"; import { Phase } from "#app/phase"; import { PlayerGender } from "#enums/player-gender"; -import { addTextObject, TextStyle } from "#ui/text"; +import { TextStyle } from "#enums/text-style"; +import { addTextObject } from "#ui/text"; import i18next from "i18next"; export class EndCardPhase extends Phase { diff --git a/src/phases/scan-ivs-phase.ts b/src/phases/scan-ivs-phase.ts index e0865feb7ca..eebee28bfbb 100644 --- a/src/phases/scan-ivs-phase.ts +++ b/src/phases/scan-ivs-phase.ts @@ -2,9 +2,10 @@ import { globalScene } from "#app/global-scene"; import { getPokemonNameWithAffix } from "#app/messages"; import type { BattlerIndex } from "#enums/battler-index"; import { PERMANENT_STATS, Stat } from "#enums/stat"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import { PokemonPhase } from "#phases/pokemon-phase"; -import { getTextColor, TextStyle } from "#ui/text"; +import { getTextColor } from "#ui/text"; import i18next from "i18next"; export class ScanIvsPhase extends PokemonPhase { diff --git a/src/timed-event-manager.ts b/src/timed-event-manager.ts index 02cb7fe8e0d..9877f298404 100644 --- a/src/timed-event-manager.ts +++ b/src/timed-event-manager.ts @@ -5,8 +5,9 @@ import { Challenges } from "#enums/challenges"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; +import { TextStyle } from "#enums/text-style"; import { WeatherType } from "#enums/weather-type"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import type { nil } from "#utils/common"; import { isNullOrUndefined } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/ability-bar.ts b/src/ui/ability-bar.ts index 79a68e9dce7..4b868d4e66c 100644 --- a/src/ui/ability-bar.ts +++ b/src/ui/ability-bar.ts @@ -1,5 +1,6 @@ import { globalScene } from "#app/global-scene"; -import { addTextObject, TextStyle } from "#ui/text"; +import { TextStyle } from "#enums/text-style"; +import { addTextObject } from "#ui/text"; import i18next from "i18next"; const barWidth = 118; diff --git a/src/ui/abstact-option-select-ui-handler.ts b/src/ui/abstact-option-select-ui-handler.ts index d93ad8b7665..2fb0159b6ef 100644 --- a/src/ui/abstact-option-select-ui-handler.ts +++ b/src/ui/abstact-option-select-ui-handler.ts @@ -1,7 +1,8 @@ import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; -import { addBBCodeTextObject, getTextColor, getTextStyleOptions, TextStyle } from "#ui/text"; +import { addBBCodeTextObject, getTextColor, getTextStyleOptions } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; import { fixedInt, rgbHexToRgba } from "#utils/common"; diff --git a/src/ui/achv-bar.ts b/src/ui/achv-bar.ts index 8e0f2a9404b..bb1ef95c9de 100644 --- a/src/ui/achv-bar.ts +++ b/src/ui/achv-bar.ts @@ -1,8 +1,9 @@ import { globalScene } from "#app/global-scene"; import type { PlayerGender } from "#enums/player-gender"; +import { TextStyle } from "#enums/text-style"; import { Achv, getAchievementDescription } from "#system/achv"; import { Voucher } from "#system/voucher"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; export class AchvBar extends Phaser.GameObjects.Container { private defaultWidth: number; diff --git a/src/ui/achvs-ui-handler.ts b/src/ui/achvs-ui-handler.ts index 6b247f6da96..01fd1d45a61 100644 --- a/src/ui/achvs-ui-handler.ts +++ b/src/ui/achvs-ui-handler.ts @@ -1,6 +1,7 @@ import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; import { PlayerGender } from "#enums/player-gender"; +import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; import type { Achv } from "#system/achv"; import { achvs, getAchievementDescription } from "#system/achv"; @@ -9,7 +10,7 @@ import type { Voucher } from "#system/voucher"; import { getVoucherTypeIcon, getVoucherTypeName, vouchers } from "#system/voucher"; import { MessageUiHandler } from "#ui/message-ui-handler"; import { ScrollBar } from "#ui/scroll-bar"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import i18next from "i18next"; diff --git a/src/ui/admin-ui-handler.ts b/src/ui/admin-ui-handler.ts index 3d0a1153127..f136aeb5008 100644 --- a/src/ui/admin-ui-handler.ts +++ b/src/ui/admin-ui-handler.ts @@ -1,11 +1,11 @@ import { pokerogueApi } from "#api/pokerogue-api"; import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import type { InputFieldConfig } from "#ui/form-modal-ui-handler"; import { FormModalUiHandler } from "#ui/form-modal-ui-handler"; import type { ModalConfig } from "#ui/modal-ui-handler"; -import { TextStyle } from "#ui/text"; import { formatText } from "#utils/common"; type AdminUiHandlerService = "discord" | "google"; diff --git a/src/ui/arena-flyout.ts b/src/ui/arena-flyout.ts index 970c65c8978..9a674719202 100644 --- a/src/ui/arena-flyout.ts +++ b/src/ui/arena-flyout.ts @@ -3,6 +3,7 @@ import { ArenaTrapTag } from "#data/arena-tag"; import { TerrainType } from "#data/terrain"; import { ArenaTagSide } from "#enums/arena-tag-side"; import { ArenaTagType } from "#enums/arena-tag-type"; +import { TextStyle } from "#enums/text-style"; import { WeatherType } from "#enums/weather-type"; import type { ArenaEvent } from "#events/arena"; import { @@ -14,7 +15,7 @@ import { } from "#events/arena"; import type { TurnEndEvent } from "#events/battle-scene"; import { BattleSceneEventType } from "#events/battle-scene"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { TimeOfDayWidget } from "#ui/time-of-day-widget"; import { addWindow, WindowVariant } from "#ui/ui-theme"; import { fixedInt, formatText, toCamelCaseString } from "#utils/common"; diff --git a/src/ui/ball-ui-handler.ts b/src/ui/ball-ui-handler.ts index bde340e3cf7..67beb0eba84 100644 --- a/src/ui/ball-ui-handler.ts +++ b/src/ui/ball-ui-handler.ts @@ -2,9 +2,10 @@ import { globalScene } from "#app/global-scene"; import { getPokeballName } from "#data/pokeball"; import { Button } from "#enums/buttons"; import { Command } from "#enums/command"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import type { CommandPhase } from "#phases/command-phase"; -import { addTextObject, getTextStyleOptions, TextStyle } from "#ui/text"; +import { addTextObject, getTextStyleOptions } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; import i18next from "i18next"; diff --git a/src/ui/base-stats-overlay.ts b/src/ui/base-stats-overlay.ts index 888b87a8d11..e3ba472475a 100644 --- a/src/ui/base-stats-overlay.ts +++ b/src/ui/base-stats-overlay.ts @@ -1,6 +1,7 @@ import type { InfoToggle } from "#app/battle-scene"; import { globalScene } from "#app/global-scene"; -import { addTextObject, TextStyle } from "#ui/text"; +import { TextStyle } from "#enums/text-style"; +import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { fixedInt } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/battle-flyout.ts b/src/ui/battle-flyout.ts index 083dc7bbf19..0a67dc9ad37 100644 --- a/src/ui/battle-flyout.ts +++ b/src/ui/battle-flyout.ts @@ -2,12 +2,13 @@ import { globalScene } from "#app/global-scene"; import { getPokemonNameWithAffix } from "#app/messages"; import { BerryType } from "#enums/berry-type"; import { MoveId } from "#enums/move-id"; +import { TextStyle } from "#enums/text-style"; import { UiTheme } from "#enums/ui-theme"; import type { BerryUsedEvent, MoveUsedEvent } from "#events/battle-scene"; import { BattleSceneEventType } from "#events/battle-scene"; import type { EnemyPokemon, Pokemon } from "#field/pokemon"; import type { Move } from "#moves/move"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { fixedInt } from "#utils/common"; /** Container for info about a {@linkcode Move} */ diff --git a/src/ui/battle-info/battle-info.ts b/src/ui/battle-info/battle-info.ts index 4a2a6d1804d..0aedfbdf5e7 100644 --- a/src/ui/battle-info/battle-info.ts +++ b/src/ui/battle-info/battle-info.ts @@ -4,9 +4,10 @@ import { getTypeRgb } from "#data/type"; import { PokemonType } from "#enums/pokemon-type"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; +import { TextStyle } from "#enums/text-style"; import type { Pokemon } from "#field/pokemon"; import { getVariantTint } from "#sprites/variant"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { fixedInt, getLocalizedSpriteKey, getShinyDescriptor } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/battle-info/enemy-battle-info.ts b/src/ui/battle-info/enemy-battle-info.ts index 5799fb476ef..d426a49df5c 100644 --- a/src/ui/battle-info/enemy-battle-info.ts +++ b/src/ui/battle-info/enemy-battle-info.ts @@ -1,10 +1,11 @@ import { globalScene } from "#app/global-scene"; import { Stat } from "#enums/stat"; +import { TextStyle } from "#enums/text-style"; import type { EnemyPokemon } from "#field/pokemon"; import { BattleFlyout } from "#ui/battle-flyout"; import type { BattleInfoParamList } from "#ui/battle-info"; import { BattleInfo } from "#ui/battle-info"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { addWindow, WindowVariant } from "#ui/ui-theme"; import i18next from "i18next"; import type { GameObjects } from "phaser"; diff --git a/src/ui/battle-message-ui-handler.ts b/src/ui/battle-message-ui-handler.ts index bd524f0bb43..b58897b9022 100644 --- a/src/ui/battle-message-ui-handler.ts +++ b/src/ui/battle-message-ui-handler.ts @@ -1,9 +1,10 @@ import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; import { getStatKey, PERMANENT_STATS } from "#enums/stat"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import { MessageUiHandler } from "#ui/message-ui-handler"; -import { addBBCodeTextObject, addTextObject, getTextColor, TextStyle } from "#ui/text"; +import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import i18next from "i18next"; import type BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; diff --git a/src/ui/bgm-bar.ts b/src/ui/bgm-bar.ts index d8b6bbe8b8a..fb50e444aa5 100644 --- a/src/ui/bgm-bar.ts +++ b/src/ui/bgm-bar.ts @@ -1,5 +1,6 @@ import { globalScene } from "#app/global-scene"; -import { addTextObject, TextStyle } from "#ui/text"; +import { TextStyle } from "#enums/text-style"; +import { addTextObject } from "#ui/text"; import { formatText } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/candy-bar.ts b/src/ui/candy-bar.ts index ea3500d6c4c..239b963227b 100644 --- a/src/ui/candy-bar.ts +++ b/src/ui/candy-bar.ts @@ -1,7 +1,8 @@ import { globalScene } from "#app/global-scene"; import { starterColors } from "#app/global-vars/starter-colors"; import type { SpeciesId } from "#enums/species-id"; -import { addTextObject, TextStyle } from "#ui/text"; +import { TextStyle } from "#enums/text-style"; +import { addTextObject } from "#ui/text"; import { rgbHexToRgba } from "#utils/common"; import { argbFromRgba } from "@material/material-color-utilities"; diff --git a/src/ui/challenges-select-ui-handler.ts b/src/ui/challenges-select-ui-handler.ts index a827cddc9a7..4f205d59de8 100644 --- a/src/ui/challenges-select-ui-handler.ts +++ b/src/ui/challenges-select-ui-handler.ts @@ -3,8 +3,9 @@ import type { Challenge } from "#data/challenge"; import { Button } from "#enums/buttons"; import { Challenges } from "#enums/challenges"; import { Color, ShadowColor } from "#enums/color"; +import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; import { getLocalizedSpriteKey } from "#utils/common"; diff --git a/src/ui/command-ui-handler.ts b/src/ui/command-ui-handler.ts index 2e4acfb7c42..41ff559062a 100644 --- a/src/ui/command-ui-handler.ts +++ b/src/ui/command-ui-handler.ts @@ -5,11 +5,12 @@ import { Button } from "#enums/buttons"; import { Command } from "#enums/command"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import { TerastallizeAccessModifier } from "#modifiers/modifier"; import type { CommandPhase } from "#phases/command-phase"; import { PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import i18next from "i18next"; diff --git a/src/ui/daily-run-scoreboard.ts b/src/ui/daily-run-scoreboard.ts index dcd45b40390..9391d02859c 100644 --- a/src/ui/daily-run-scoreboard.ts +++ b/src/ui/daily-run-scoreboard.ts @@ -1,6 +1,7 @@ import { pokerogueApi } from "#api/pokerogue-api"; import { globalScene } from "#app/global-scene"; -import { addTextObject, TextStyle } from "#ui/text"; +import { TextStyle } from "#enums/text-style"; +import { addTextObject } from "#ui/text"; import { addWindow, WindowVariant } from "#ui/ui-theme"; import { executeIf } from "#utils/common"; import { getEnumKeys } from "#utils/enums"; diff --git a/src/ui/dropdown.ts b/src/ui/dropdown.ts index 2a100ddbe59..c13d1ab6482 100644 --- a/src/ui/dropdown.ts +++ b/src/ui/dropdown.ts @@ -1,6 +1,7 @@ import { globalScene } from "#app/global-scene"; +import { TextStyle } from "#enums/text-style"; import { ScrollBar } from "#ui/scroll-bar"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { addWindow, WindowVariant } from "#ui/ui-theme"; import i18next from "i18next"; diff --git a/src/ui/egg-counter-container.ts b/src/ui/egg-counter-container.ts index ff536228fde..da394e73b28 100644 --- a/src/ui/egg-counter-container.ts +++ b/src/ui/egg-counter-container.ts @@ -1,8 +1,9 @@ import { globalScene } from "#app/global-scene"; +import { TextStyle } from "#enums/text-style"; import type { EggCountChangedEvent } from "#events/egg"; import { EggEventType } from "#events/egg"; import type { EggHatchSceneHandler } from "#ui/egg-hatch-scene-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; /** diff --git a/src/ui/egg-gacha-ui-handler.ts b/src/ui/egg-gacha-ui-handler.ts index 19d1efa75dd..5dcf05e2606 100644 --- a/src/ui/egg-gacha-ui-handler.ts +++ b/src/ui/egg-gacha-ui-handler.ts @@ -6,10 +6,11 @@ import { Egg, getLegendaryGachaSpeciesForTimestamp } from "#data/egg"; import { Button } from "#enums/buttons"; import { EggTier } from "#enums/egg-type"; import { GachaType } from "#enums/gacha-types"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import { getVoucherTypeIcon, VoucherType } from "#system/voucher"; import { MessageUiHandler } from "#ui/message-ui-handler"; -import { addTextObject, getEggTierTextTint, getTextStyleOptions, TextStyle } from "#ui/text"; +import { addTextObject, getEggTierTextTint, getTextStyleOptions } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { fixedInt, randSeedShuffle } from "#utils/common"; import { getEnumValues } from "#utils/enums"; @@ -74,7 +75,7 @@ export class EggGachaUiHandler extends MessageUiHandler { const gachaInfoContainer = globalScene.add.container(160, 46); const currentLanguage = i18next.resolvedLanguage ?? "en"; - let gachaTextStyle = TextStyle.WINDOW_ALT; + let gachaTextStyle: TextStyle = TextStyle.WINDOW_ALT; let gachaX = 4; let gachaY = 0; let pokemonIconX = -20; diff --git a/src/ui/egg-list-ui-handler.ts b/src/ui/egg-list-ui-handler.ts index 94d6889ed48..42f969b9d38 100644 --- a/src/ui/egg-list-ui-handler.ts +++ b/src/ui/egg-list-ui-handler.ts @@ -1,11 +1,12 @@ import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import { MessageUiHandler } from "#ui/message-ui-handler"; import { PokemonIconAnimHandler, PokemonIconAnimMode } from "#ui/pokemon-icon-anim-handler"; import { ScrollBar } from "#ui/scroll-bar"; import { ScrollableGridUiHandler } from "#ui/scrollable-grid-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import i18next from "i18next"; diff --git a/src/ui/evolution-scene-handler.ts b/src/ui/evolution-scene-handler.ts index 5ad4fc6fdf5..c22cf31faaa 100644 --- a/src/ui/evolution-scene-handler.ts +++ b/src/ui/evolution-scene-handler.ts @@ -1,8 +1,9 @@ import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import { MessageUiHandler } from "#ui/message-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; export class EvolutionSceneHandler extends MessageUiHandler { public evolutionContainer: Phaser.GameObjects.Container; diff --git a/src/ui/fight-ui-handler.ts b/src/ui/fight-ui-handler.ts index 286199b99e2..42f8cba5df4 100644 --- a/src/ui/fight-ui-handler.ts +++ b/src/ui/fight-ui-handler.ts @@ -7,12 +7,13 @@ import { Command } from "#enums/command"; import { MoveCategory } from "#enums/move-category"; import { MoveUseMode } from "#enums/move-use-mode"; import { PokemonType } from "#enums/pokemon-type"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import type { EnemyPokemon, Pokemon } from "#field/pokemon"; import type { PokemonMove } from "#moves/pokemon-move"; import type { CommandPhase } from "#phases/command-phase"; import { MoveInfoOverlay } from "#ui/move-info-overlay"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { fixedInt, getLocalizedSpriteKey, padInt } from "#utils/common"; import i18next from "i18next"; @@ -284,7 +285,7 @@ export class FightUiHandler extends UiHandler implements InfoToggle { const ppColorStyle = FightUiHandler.ppRatioToColor(pp / maxPP); - //** Changes the text color and shadow according to the determined TextStyle */ + // Changes the text color and shadow according to the determined TextStyle this.ppText.setColor(this.getTextColor(ppColorStyle, false)).setShadowColor(this.getTextColor(ppColorStyle, true)); this.moveInfoOverlay.show(pokemonMove.getMove()); diff --git a/src/ui/filter-bar.ts b/src/ui/filter-bar.ts index 3961ae3415c..ea227655a97 100644 --- a/src/ui/filter-bar.ts +++ b/src/ui/filter-bar.ts @@ -1,10 +1,11 @@ import { globalScene } from "#app/global-scene"; import type { DropDownColumn } from "#enums/drop-down-column"; +import { TextStyle } from "#enums/text-style"; import type { UiTheme } from "#enums/ui-theme"; import type { DropDown } from "#ui/dropdown"; import { DropDownType } from "#ui/dropdown"; import type { StarterContainer } from "#ui/starter-container"; -import { addTextObject, getTextColor, TextStyle } from "#ui/text"; +import { addTextObject, getTextColor } from "#ui/text"; import { addWindow, WindowVariant } from "#ui/ui-theme"; export class FilterBar extends Phaser.GameObjects.Container { diff --git a/src/ui/filter-text.ts b/src/ui/filter-text.ts index 4a9012e44fc..ff7119dd778 100644 --- a/src/ui/filter-text.ts +++ b/src/ui/filter-text.ts @@ -1,9 +1,10 @@ import { globalScene } from "#app/global-scene"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import type { UiTheme } from "#enums/ui-theme"; import type { AwaitableUiHandler } from "#ui/awaitable-ui-handler"; import type { StarterContainer } from "#ui/starter-container"; -import { addTextObject, getTextColor, TextStyle } from "#ui/text"; +import { addTextObject, getTextColor } from "#ui/text"; import type { UI } from "#ui/ui"; import { addWindow, WindowVariant } from "#ui/ui-theme"; import i18next from "i18next"; diff --git a/src/ui/form-modal-ui-handler.ts b/src/ui/form-modal-ui-handler.ts index 35965b09b80..7ae545a7292 100644 --- a/src/ui/form-modal-ui-handler.ts +++ b/src/ui/form-modal-ui-handler.ts @@ -1,9 +1,10 @@ import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; +import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; import type { ModalConfig } from "#ui/modal-ui-handler"; import { ModalUiHandler } from "#ui/modal-ui-handler"; -import { addTextInputObject, addTextObject, TextStyle } from "#ui/text"; +import { addTextInputObject, addTextObject } from "#ui/text"; import { addWindow, WindowVariant } from "#ui/ui-theme"; import { fixedInt } from "#utils/common"; import type InputText from "phaser3-rex-plugins/plugins/inputtext"; diff --git a/src/ui/game-stats-ui-handler.ts b/src/ui/game-stats-ui-handler.ts index 759792b122f..fa5cd0a989a 100644 --- a/src/ui/game-stats-ui-handler.ts +++ b/src/ui/game-stats-ui-handler.ts @@ -2,9 +2,10 @@ import { globalScene } from "#app/global-scene"; import { speciesStarterCosts } from "#balance/starters"; import { Button } from "#enums/buttons"; import { DexAttr } from "#enums/dex-attr"; +import { TextStyle } from "#enums/text-style"; import { UiTheme } from "#enums/ui-theme"; import type { GameData } from "#system/game-data"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; import { formatFancyLargeNumber, getPlayTimeString, toReadableString } from "#utils/common"; diff --git a/src/ui/loading-modal-ui-handler.ts b/src/ui/loading-modal-ui-handler.ts index 585d70d51db..de00d911c47 100644 --- a/src/ui/loading-modal-ui-handler.ts +++ b/src/ui/loading-modal-ui-handler.ts @@ -1,6 +1,7 @@ +import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; import { ModalUiHandler } from "#ui/modal-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import i18next from "i18next"; export class LoadingModalUiHandler extends ModalUiHandler { diff --git a/src/ui/login-form-ui-handler.ts b/src/ui/login-form-ui-handler.ts index 417a9031bf7..524eaeece86 100644 --- a/src/ui/login-form-ui-handler.ts +++ b/src/ui/login-form-ui-handler.ts @@ -1,11 +1,12 @@ import { pokerogueApi } from "#api/pokerogue-api"; import { globalScene } from "#app/global-scene"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler"; import type { InputFieldConfig } from "#ui/form-modal-ui-handler"; import { FormModalUiHandler } from "#ui/form-modal-ui-handler"; import type { ModalConfig } from "#ui/modal-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { fixedInt } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/menu-ui-handler.ts b/src/ui/menu-ui-handler.ts index 4e45dfedcb3..fa65cccab2f 100644 --- a/src/ui/menu-ui-handler.ts +++ b/src/ui/menu-ui-handler.ts @@ -5,13 +5,14 @@ import { bypassLogin } from "#app/global-vars/bypass-login"; import { handleTutorial, Tutorial } from "#app/tutorial"; import { Button } from "#enums/buttons"; import { GameDataType } from "#enums/game-data-type"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstact-option-select-ui-handler"; import { AdminMode, getAdminModeName } from "#ui/admin-ui-handler"; import type { AwaitableUiHandler } from "#ui/awaitable-ui-handler"; import { BgmBar } from "#ui/bgm-bar"; import { MessageUiHandler } from "#ui/message-ui-handler"; -import { addTextObject, getTextStyleOptions, TextStyle } from "#ui/text"; +import { addTextObject, getTextStyleOptions } from "#ui/text"; import { addWindow, WindowVariant } from "#ui/ui-theme"; import { fixedInt, isLocal, sessionIdKey } from "#utils/common"; import { getCookie } from "#utils/cookies"; diff --git a/src/ui/modal-ui-handler.ts b/src/ui/modal-ui-handler.ts index 844f7f43930..c93b713831e 100644 --- a/src/ui/modal-ui-handler.ts +++ b/src/ui/modal-ui-handler.ts @@ -1,7 +1,8 @@ import { globalScene } from "#app/global-scene"; import type { Button } from "#enums/buttons"; +import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { addWindow, WindowVariant } from "#ui/ui-theme"; diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index 3e3487d4ffb..50d88738d32 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -6,13 +6,14 @@ import { getPokeballAtlasKey } from "#data/pokeball"; import { Button } from "#enums/buttons"; import type { PokeballType } from "#enums/pokeball"; import { ShopCursorTarget } from "#enums/shop-cursor-target"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import { HealShopCostModifier, LockModifierTiersModifier, PokemonHeldItemModifier } from "#modifiers/modifier"; import type { ModifierTypeOption } from "#modifiers/modifier-type"; import { getPlayerShopModifierTypeOptionsForWave, TmModifierType } from "#modifiers/modifier-type"; import { AwaitableUiHandler } from "#ui/awaitable-ui-handler"; import { MoveInfoOverlay } from "#ui/move-info-overlay"; -import { addTextObject, getModifierTierTextTint, getTextColor, getTextStyleOptions, TextStyle } from "#ui/text"; +import { addTextObject, getModifierTierTextTint, getTextColor, getTextStyleOptions } from "#ui/text"; import { formatMoney, NumberHolder } from "#utils/common"; import i18next from "i18next"; import Phaser from "phaser"; diff --git a/src/ui/move-info-overlay.ts b/src/ui/move-info-overlay.ts index 7720354a5b3..f8632eb244e 100644 --- a/src/ui/move-info-overlay.ts +++ b/src/ui/move-info-overlay.ts @@ -2,8 +2,9 @@ import type { InfoToggle } from "#app/battle-scene"; import { globalScene } from "#app/global-scene"; import { MoveCategory } from "#enums/move-category"; import { PokemonType } from "#enums/pokemon-type"; +import { TextStyle } from "#enums/text-style"; import type { Move } from "#moves/move"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { fixedInt, getLocalizedSpriteKey } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/mystery-encounter-ui-handler.ts b/src/ui/mystery-encounter-ui-handler.ts index 37f0efb50e4..b6bc464855c 100644 --- a/src/ui/mystery-encounter-ui-handler.ts +++ b/src/ui/mystery-encounter-ui-handler.ts @@ -3,13 +3,14 @@ import { getPokeballAtlasKey } from "#data/pokeball"; import { Button } from "#enums/buttons"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import { getEncounterText } from "#mystery-encounters/encounter-dialogue-utils"; import type { OptionSelectSettings } from "#mystery-encounters/encounter-phase-utils"; import type { MysteryEncounterOption } from "#mystery-encounters/mystery-encounter-option"; import type { MysteryEncounterPhase } from "#phases/mystery-encounter-phases"; import { PartyUiMode } from "#ui/party-ui-handler"; -import { addBBCodeTextObject, getBBCodeFrag, TextStyle } from "#ui/text"; +import { addBBCodeTextObject, getBBCodeFrag } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { addWindow, WindowVariant } from "#ui/ui-theme"; import { fixedInt, isNullOrUndefined } from "#utils/common"; diff --git a/src/ui/party-exp-bar.ts b/src/ui/party-exp-bar.ts index 0d6ec936a92..952a1f8227a 100644 --- a/src/ui/party-exp-bar.ts +++ b/src/ui/party-exp-bar.ts @@ -1,6 +1,7 @@ import { globalScene } from "#app/global-scene"; +import { TextStyle } from "#enums/text-style"; import type { Pokemon } from "#field/pokemon"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import i18next from "i18next"; export class PartyExpBar extends Phaser.GameObjects.Container { diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 956e4c52e39..2b29a564f9f 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -13,6 +13,7 @@ import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import type { PlayerPokemon, Pokemon } from "#field/pokemon"; import type { PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#modifiers/modifier"; @@ -23,7 +24,7 @@ import type { TurnMove } from "#types/turn-move"; import { MessageUiHandler } from "#ui/message-ui-handler"; import { MoveInfoOverlay } from "#ui/move-info-overlay"; import { PokemonIconAnimHandler, PokemonIconAnimMode } from "#ui/pokemon-icon-anim-handler"; -import { addBBCodeTextObject, addTextObject, getTextColor, TextStyle } from "#ui/text"; +import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { BooleanHolder, getLocalizedSpriteKey, randInt, toReadableString } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/pokedex-info-overlay.ts b/src/ui/pokedex-info-overlay.ts index 6d3b8f1009f..0f2f5fa3dde 100644 --- a/src/ui/pokedex-info-overlay.ts +++ b/src/ui/pokedex-info-overlay.ts @@ -1,6 +1,7 @@ import type { InfoToggle } from "#app/battle-scene"; import { globalScene } from "#app/global-scene"; -import { addTextObject, TextStyle } from "#ui/text"; +import { TextStyle } from "#enums/text-style"; +import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { fixedInt } from "#utils/common"; diff --git a/src/ui/pokedex-mon-container.ts b/src/ui/pokedex-mon-container.ts index 73799870e6b..cfb8555e6c9 100644 --- a/src/ui/pokedex-mon-container.ts +++ b/src/ui/pokedex-mon-container.ts @@ -1,7 +1,8 @@ import { globalScene } from "#app/global-scene"; import type { PokemonSpecies } from "#data/pokemon-species"; +import { TextStyle } from "#enums/text-style"; import type { Variant } from "#sprites/variant"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { isNullOrUndefined } from "#utils/common"; interface SpeciesDetails { diff --git a/src/ui/pokedex-page-ui-handler.ts b/src/ui/pokedex-page-ui-handler.ts index ff96aa55772..b3eb8de0f50 100644 --- a/src/ui/pokedex-page-ui-handler.ts +++ b/src/ui/pokedex-page-ui-handler.ts @@ -38,6 +38,7 @@ import type { Nature } from "#enums/nature"; import { Passive as PassiveAttr } from "#enums/passive"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; +import { TextStyle } from "#enums/text-style"; import { TimeOfDay } from "#enums/time-of-day"; import { UiMode } from "#enums/ui-mode"; import type { Variant } from "#sprites/variant"; @@ -51,7 +52,7 @@ import { MessageUiHandler } from "#ui/message-ui-handler"; import { MoveInfoOverlay } from "#ui/move-info-overlay"; import { PokedexInfoOverlay } from "#ui/pokedex-info-overlay"; import { StatsContainer } from "#ui/stats-container"; -import { addBBCodeTextObject, addTextObject, getTextColor, getTextStyleOptions, TextStyle } from "#ui/text"; +import { addBBCodeTextObject, addTextObject, getTextColor, getTextStyleOptions } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { BooleanHolder, diff --git a/src/ui/pokedex-ui-handler.ts b/src/ui/pokedex-ui-handler.ts index c2f595cb190..5d49e867b59 100644 --- a/src/ui/pokedex-ui-handler.ts +++ b/src/ui/pokedex-ui-handler.ts @@ -26,6 +26,7 @@ import type { Nature } from "#enums/nature"; import { Passive as PassiveAttr } from "#enums/passive"; import { PokemonType } from "#enums/pokemon-type"; import type { SpeciesId } from "#enums/species-id"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import type { Variant } from "#sprites/variant"; import { getVariantIcon, getVariantTint } from "#sprites/variant"; @@ -40,7 +41,7 @@ import { MessageUiHandler } from "#ui/message-ui-handler"; import { PokedexMonContainer } from "#ui/pokedex-mon-container"; import { PokemonIconAnimHandler, PokemonIconAnimMode } from "#ui/pokemon-icon-anim-handler"; import { ScrollBar } from "#ui/scroll-bar"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { BooleanHolder, fixedInt, getLocalizedSpriteKey, padInt, randIntRange, rgbHexToRgba } from "#utils/common"; import type { StarterPreferences } from "#utils/data"; diff --git a/src/ui/pokemon-hatch-info-container.ts b/src/ui/pokemon-hatch-info-container.ts index 8bcd62316cd..9c223adf837 100644 --- a/src/ui/pokemon-hatch-info-container.ts +++ b/src/ui/pokemon-hatch-info-container.ts @@ -8,9 +8,10 @@ import { Gender } from "#data/gender"; import { getPokemonSpeciesForm } from "#data/pokemon-species"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; +import { TextStyle } from "#enums/text-style"; import type { PlayerPokemon } from "#field/pokemon"; import { PokemonInfoContainer } from "#ui/pokemon-info-container"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { padInt, rgbHexToRgba } from "#utils/common"; import { argbFromRgba } from "@material/material-color-utilities"; diff --git a/src/ui/pokemon-info-container.ts b/src/ui/pokemon-info-container.ts index c95f412c834..3b2349348a8 100644 --- a/src/ui/pokemon-info-container.ts +++ b/src/ui/pokemon-info-container.ts @@ -3,13 +3,14 @@ import { Gender, getGenderColor, getGenderSymbol } from "#data/gender"; import { getNatureName } from "#data/nature"; import { DexAttr } from "#enums/dex-attr"; import { PokemonType } from "#enums/pokemon-type"; +import { TextStyle } from "#enums/text-style"; import type { Pokemon } from "#field/pokemon"; import { getVariantTint } from "#sprites/variant"; import type { StarterDataEntry } from "#system/game-data"; import type { DexEntry } from "#types/dex-data"; import { ConfirmUiHandler } from "#ui/confirm-ui-handler"; import { StatsContainer } from "#ui/stats-container"; -import { addBBCodeTextObject, addTextObject, getTextColor, TextStyle } from "#ui/text"; +import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { fixedInt, getShinyDescriptor } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/registration-form-ui-handler.ts b/src/ui/registration-form-ui-handler.ts index 2466603af71..60f8d1d987f 100644 --- a/src/ui/registration-form-ui-handler.ts +++ b/src/ui/registration-form-ui-handler.ts @@ -1,10 +1,11 @@ import { pokerogueApi } from "#api/pokerogue-api"; import { globalScene } from "#app/global-scene"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import type { InputFieldConfig } from "#ui/form-modal-ui-handler"; import { FormModalUiHandler } from "#ui/form-modal-ui-handler"; import type { ModalConfig } from "#ui/modal-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import i18next from "i18next"; interface LanguageSetting { diff --git a/src/ui/run-history-ui-handler.ts b/src/ui/run-history-ui-handler.ts index f810468aea1..00aa47ae65d 100644 --- a/src/ui/run-history-ui-handler.ts +++ b/src/ui/run-history-ui-handler.ts @@ -3,13 +3,14 @@ import { BattleType } from "#enums/battle-type"; import { Button } from "#enums/buttons"; import { GameModes } from "#enums/game-modes"; import { PlayerGender } from "#enums/player-gender"; +import { TextStyle } from "#enums/text-style"; import { TrainerVariant } from "#enums/trainer-variant"; import { UiMode } from "#enums/ui-mode"; import type { RunEntry } from "#system/game-data"; import type { PokemonData } from "#system/pokemon-data"; import { MessageUiHandler } from "#ui/message-ui-handler"; import { RunDisplayMode } from "#ui/run-info-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { fixedInt, formatLargeNumber } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/run-info-ui-handler.ts b/src/ui/run-info-ui-handler.ts index 29f95c4e4c8..465e48a45ad 100644 --- a/src/ui/run-info-ui-handler.ts +++ b/src/ui/run-info-ui-handler.ts @@ -12,6 +12,7 @@ import type { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { PlayerGender } from "#enums/player-gender"; import { PokemonType } from "#enums/pokemon-type"; import type { SpeciesId } from "#enums/species-id"; +import { TextStyle } from "#enums/text-style"; import { TrainerVariant } from "#enums/trainer-variant"; import { UiMode } from "#enums/ui-mode"; // biome-ignore lint/performance/noNamespaceImport: See `src/system/game-data.ts` @@ -21,7 +22,7 @@ import { getVariantTint } from "#sprites/variant"; import type { SessionSaveData } from "#system/game-data"; import type { PokemonData } from "#system/pokemon-data"; import { SettingKeyboard } from "#system/settings-keyboard"; -import { addBBCodeTextObject, addTextObject, getTextColor, TextStyle } from "#ui/text"; +import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; import { formatFancyLargeNumber, formatLargeNumber, formatMoney, getPlayTimeString } from "#utils/common"; diff --git a/src/ui/save-slot-select-ui-handler.ts b/src/ui/save-slot-select-ui-handler.ts index bcbe60265cd..9da34e672f1 100644 --- a/src/ui/save-slot-select-ui-handler.ts +++ b/src/ui/save-slot-select-ui-handler.ts @@ -1,6 +1,7 @@ import { GameMode } from "#app/game-mode"; import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; // biome-ignore lint/performance/noNamespaceImport: See `src/system/game-data.ts` import * as Modifier from "#modifiers/modifier"; @@ -8,7 +9,7 @@ import type { SessionSaveData } from "#system/game-data"; import type { PokemonData } from "#system/pokemon-data"; import { MessageUiHandler } from "#ui/message-ui-handler"; import { RunDisplayMode } from "#ui/run-info-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { fixedInt, formatLargeNumber, getPlayTimeString, isNullOrUndefined } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/session-reload-modal-ui-handler.ts b/src/ui/session-reload-modal-ui-handler.ts index ab1197324a6..1f5a205f990 100644 --- a/src/ui/session-reload-modal-ui-handler.ts +++ b/src/ui/session-reload-modal-ui-handler.ts @@ -1,7 +1,8 @@ +import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; import type { ModalConfig } from "#ui/modal-ui-handler"; import { ModalUiHandler } from "#ui/modal-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; export class SessionReloadModalUiHandler extends ModalUiHandler { constructor(mode: UiMode | null = null) { diff --git a/src/ui/settings/abstract-binding-ui-handler.ts b/src/ui/settings/abstract-binding-ui-handler.ts index 7004af8c4ed..eb68456a69d 100644 --- a/src/ui/settings/abstract-binding-ui-handler.ts +++ b/src/ui/settings/abstract-binding-ui-handler.ts @@ -1,8 +1,9 @@ import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; +import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; import { NavigationManager } from "#ui/navigation-menu"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; import i18next from "i18next"; diff --git a/src/ui/settings/abstract-control-settings-ui-handler.ts b/src/ui/settings/abstract-control-settings-ui-handler.ts index 64786849abc..8f7de42e4db 100644 --- a/src/ui/settings/abstract-control-settings-ui-handler.ts +++ b/src/ui/settings/abstract-control-settings-ui-handler.ts @@ -2,11 +2,12 @@ import { globalScene } from "#app/global-scene"; import type { InterfaceConfig } from "#app/inputs-controller"; import { Button } from "#enums/buttons"; import type { Device } from "#enums/devices"; +import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; import { getIconWithSettingName } from "#inputs/config-handler"; import { NavigationManager, NavigationMenu } from "#ui/navigation-menu"; import { ScrollBar } from "#ui/scroll-bar"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; import i18next from "i18next"; diff --git a/src/ui/settings/abstract-settings-ui-handler.ts b/src/ui/settings/abstract-settings-ui-handler.ts index 9e56ae80b14..81d733220fc 100644 --- a/src/ui/settings/abstract-settings-ui-handler.ts +++ b/src/ui/settings/abstract-settings-ui-handler.ts @@ -1,5 +1,6 @@ import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import type { SettingType } from "#system/settings"; import { Setting, SettingKeys } from "#system/settings"; @@ -7,7 +8,7 @@ import type { InputsIcons } from "#ui/abstract-control-settings-ui-handler"; import { MessageUiHandler } from "#ui/message-ui-handler"; import { NavigationManager, NavigationMenu } from "#ui/navigation-menu"; import { ScrollBar } from "#ui/scroll-bar"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import i18next from "i18next"; diff --git a/src/ui/settings/gamepad-binding-ui-handler.ts b/src/ui/settings/gamepad-binding-ui-handler.ts index e97fc56d7c0..53d606b6f84 100644 --- a/src/ui/settings/gamepad-binding-ui-handler.ts +++ b/src/ui/settings/gamepad-binding-ui-handler.ts @@ -1,9 +1,10 @@ import { globalScene } from "#app/global-scene"; import { Device } from "#enums/devices"; +import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; import { getIconWithSettingName, getKeyWithKeycode } from "#inputs/config-handler"; import { AbstractBindingUiHandler } from "#ui/abstract-binding-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import i18next from "i18next"; export class GamepadBindingUiHandler extends AbstractBindingUiHandler { diff --git a/src/ui/settings/keyboard-binding-ui-handler.ts b/src/ui/settings/keyboard-binding-ui-handler.ts index e43184795d1..b339ac16188 100644 --- a/src/ui/settings/keyboard-binding-ui-handler.ts +++ b/src/ui/settings/keyboard-binding-ui-handler.ts @@ -1,9 +1,10 @@ import { globalScene } from "#app/global-scene"; import { Device } from "#enums/devices"; +import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; import { getKeyWithKeycode } from "#inputs/config-handler"; import { AbstractBindingUiHandler } from "#ui/abstract-binding-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import i18next from "i18next"; export class KeyboardBindingUiHandler extends AbstractBindingUiHandler { diff --git a/src/ui/settings/navigation-menu.ts b/src/ui/settings/navigation-menu.ts index 1303c32d3a5..2f3aa50f7f3 100644 --- a/src/ui/settings/navigation-menu.ts +++ b/src/ui/settings/navigation-menu.ts @@ -1,8 +1,9 @@ import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import type { InputsIcons } from "#ui/abstract-control-settings-ui-handler"; -import { addTextObject, setTextStyle, TextStyle } from "#ui/text"; +import { addTextObject, setTextStyle } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import i18next from "i18next"; diff --git a/src/ui/settings/settings-gamepad-ui-handler.ts b/src/ui/settings/settings-gamepad-ui-handler.ts index ea2e18a2ce6..57a70411f4c 100644 --- a/src/ui/settings/settings-gamepad-ui-handler.ts +++ b/src/ui/settings/settings-gamepad-ui-handler.ts @@ -1,6 +1,7 @@ import { globalScene } from "#app/global-scene"; import type { InterfaceConfig } from "#app/inputs-controller"; import { Device } from "#enums/devices"; +import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; import pad_dualshock from "#inputs/pad-dualshock"; import pad_unlicensedSNES from "#inputs/pad-unlicensed-snes"; @@ -13,7 +14,7 @@ import { settingGamepadOptions, } from "#system/settings-gamepad"; import { AbstractControlSettingsUiHandler } from "#ui/abstract-control-settings-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { truncateString } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/settings/settings-keyboard-ui-handler.ts b/src/ui/settings/settings-keyboard-ui-handler.ts index 2c2e0dbd7cd..ad4bf47f673 100644 --- a/src/ui/settings/settings-keyboard-ui-handler.ts +++ b/src/ui/settings/settings-keyboard-ui-handler.ts @@ -1,6 +1,7 @@ import { globalScene } from "#app/global-scene"; import type { InterfaceConfig } from "#app/inputs-controller"; import { Device } from "#enums/devices"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import cfg_keyboard_qwerty from "#inputs/cfg-keyboard-qwerty"; import { deleteBind } from "#inputs/config-handler"; @@ -13,7 +14,7 @@ import { } from "#system/settings-keyboard"; import { AbstractControlSettingsUiHandler } from "#ui/abstract-control-settings-ui-handler"; import { NavigationManager } from "#ui/navigation-menu"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { reverseValueToKeySetting, truncateString } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/starter-container.ts b/src/ui/starter-container.ts index 4c174dc5955..f81ac8e5bfb 100644 --- a/src/ui/starter-container.ts +++ b/src/ui/starter-container.ts @@ -1,6 +1,7 @@ import { globalScene } from "#app/global-scene"; import type { PokemonSpecies } from "#data/pokemon-species"; -import { addTextObject, TextStyle } from "#ui/text"; +import { TextStyle } from "#enums/text-style"; +import { addTextObject } from "#ui/text"; export class StarterContainer extends Phaser.GameObjects.Container { public species: PokemonSpecies; diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index fcd8167a519..82e19d857c5 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -39,6 +39,7 @@ import type { Nature } from "#enums/nature"; import { Passive as PassiveAttr } from "#enums/passive"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import type { CandyUpgradeNotificationChangedEvent } from "#events/battle-scene"; import { BattleSceneEventType } from "#events/battle-scene"; @@ -57,7 +58,7 @@ import { PokemonIconAnimHandler, PokemonIconAnimMode } from "#ui/pokemon-icon-an import { ScrollBar } from "#ui/scroll-bar"; import { StarterContainer } from "#ui/starter-container"; import { StatsContainer } from "#ui/stats-container"; -import { addBBCodeTextObject, addTextObject, TextStyle } from "#ui/text"; +import { addBBCodeTextObject, addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { BooleanHolder, diff --git a/src/ui/stats-container.ts b/src/ui/stats-container.ts index 6b89e80b80a..e9af5eed3e3 100644 --- a/src/ui/stats-container.ts +++ b/src/ui/stats-container.ts @@ -1,6 +1,7 @@ import { globalScene } from "#app/global-scene"; import { getStatKey, PERMANENT_STATS } from "#enums/stat"; -import { addBBCodeTextObject, addTextObject, getTextColor, TextStyle } from "#ui/text"; +import { TextStyle } from "#enums/text-style"; +import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text"; import i18next from "i18next"; import type BBCodeText from "phaser3-rex-plugins/plugins/gameobjects/tagtext/bbcodetext/BBCodeText"; diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index 7661dab068e..c5c714f0b34 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -16,6 +16,7 @@ import { PlayerGender } from "#enums/player-gender"; import { PokemonType } from "#enums/pokemon-type"; import { getStatKey, PERMANENT_STATS, Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import type { PlayerPokemon } from "#field/pokemon"; import { modifierSortFunc, PokemonHeldItemModifier } from "#modifiers/modifier"; @@ -24,7 +25,7 @@ import type { PokemonMove } from "#moves/pokemon-move"; import type { Variant } from "#sprites/variant"; import { getVariantTint } from "#sprites/variant"; import { achvs } from "#system/achv"; -import { addBBCodeTextObject, addTextObject, getBBCodeFrag, TextStyle } from "#ui/text"; +import { addBBCodeTextObject, addTextObject, getBBCodeFrag } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { fixedInt, diff --git a/src/ui/text.ts b/src/ui/text.ts index b2a1894c85c..8aa50983874 100644 --- a/src/ui/text.ts +++ b/src/ui/text.ts @@ -1,79 +1,14 @@ import { globalScene } from "#app/global-scene"; import { EggTier } from "#enums/egg-type"; import { ModifierTier } from "#enums/modifier-tier"; +import { TextStyle } from "#enums/text-style"; import { UiTheme } from "#enums/ui-theme"; import i18next from "#plugins/i18n"; +import type { TextStyleOptions } from "#types/ui"; import type Phaser from "phaser"; import BBCodeText from "phaser3-rex-plugins/plugins/gameobjects/tagtext/bbcodetext/BBCodeText"; import type InputText from "phaser3-rex-plugins/plugins/inputtext"; -export enum TextStyle { - MESSAGE, - WINDOW, - WINDOW_ALT, - WINDOW_BATTLE_COMMAND, - BATTLE_INFO, - PARTY, - PARTY_RED, - PARTY_CANCEL_BUTTON, - INSTRUCTIONS_TEXT, - MOVE_LABEL, - SUMMARY, - SUMMARY_DEX_NUM, - SUMMARY_DEX_NUM_GOLD, - SUMMARY_ALT, - SUMMARY_HEADER, - SUMMARY_RED, - SUMMARY_BLUE, - SUMMARY_PINK, - SUMMARY_GOLD, - SUMMARY_GRAY, - SUMMARY_GREEN, - SUMMARY_STATS, - SUMMARY_STATS_BLUE, - SUMMARY_STATS_PINK, - SUMMARY_STATS_GOLD, - LUCK_VALUE, - STATS_HEXAGON, - GROWTH_RATE_TYPE, - MONEY, // Money default styling (pale yellow) - MONEY_WINDOW, // Money displayed in Windows (needs different colors based on theme) - HEADER_LABEL, - STATS_LABEL, - STATS_VALUE, - SETTINGS_VALUE, - SETTINGS_LABEL, - SETTINGS_LABEL_NAVBAR, - SETTINGS_SELECTED, - SETTINGS_LOCKED, - EGG_LIST, - EGG_SUMMARY_NAME, - EGG_SUMMARY_DEX, - STARTER_VALUE_LIMIT, - TOOLTIP_TITLE, - TOOLTIP_CONTENT, - FILTER_BAR_MAIN, - MOVE_INFO_CONTENT, - MOVE_PP_FULL, - MOVE_PP_HALF_FULL, - MOVE_PP_NEAR_EMPTY, - MOVE_PP_EMPTY, - SMALLER_WINDOW_ALT, - BGM_BAR, - PERFECT_IV, - ME_OPTION_DEFAULT, // Default style for choices in ME - ME_OPTION_SPECIAL, // Style for choices with special requirements in ME - SHADOW_TEXT, // To obscure unavailable options -} - -export interface TextStyleOptions { - scale: number; - styleOptions: Phaser.Types.GameObjects.Text.TextStyle | InputText.IConfig; - shadowColor: string; - shadowXpos: number; - shadowYpos: number; -} - export function addTextObject( x: number, y: number, @@ -87,9 +22,10 @@ export function addTextObject( extraStyleOptions, ); - const ret = globalScene.add.text(x, y, content, styleOptions); - ret.setScale(scale); - ret.setShadow(shadowXpos, shadowYpos, shadowColor); + const ret = globalScene.add + .text(x, y, content, styleOptions) + .setScale(scale) + .setShadow(shadowXpos, shadowYpos, shadowColor); if (!(styleOptions as Phaser.Types.GameObjects.Text.TextStyle).lineSpacing) { ret.setLineSpacing(scale * 30); } @@ -107,8 +43,7 @@ export function setTextStyle( globalScene.uiTheme, extraStyleOptions, ); - obj.setScale(scale); - obj.setShadow(shadowXpos, shadowYpos, shadowColor); + obj.setScale(scale).setShadow(shadowXpos, shadowYpos, shadowColor); if (!(styleOptions as Phaser.Types.GameObjects.Text.TextStyle).lineSpacing) { obj.setLineSpacing(scale * 30); } @@ -133,8 +68,7 @@ export function addBBCodeTextObject( const ret = new BBCodeText(globalScene, x, y, content, styleOptions as BBCodeText.TextStyle); globalScene.add.existing(ret); - ret.setScale(scale); - ret.setShadow(shadowXpos, shadowYpos, shadowColor); + ret.setScale(scale).setShadow(shadowXpos, shadowYpos, shadowColor); if (!(styleOptions as BBCodeText.TextStyle).lineSpacing) { ret.setLineSpacing(scale * 60); } diff --git a/src/ui/title-ui-handler.ts b/src/ui/title-ui-handler.ts index b7c37538a3e..66cb69f6a26 100644 --- a/src/ui/title-ui-handler.ts +++ b/src/ui/title-ui-handler.ts @@ -5,10 +5,11 @@ import { TimedEventDisplay } from "#app/timed-event-manager"; import { getSplashMessages } from "#data/splash-messages"; import { PlayerGender } from "#enums/player-gender"; import type { SpeciesId } from "#enums/species-id"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import { version } from "#package.json"; import { OptionSelectUiHandler } from "#ui/option-select-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { fixedInt, randInt, randItem } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import i18next from "i18next"; diff --git a/src/ui/ui-handler.ts b/src/ui/ui-handler.ts index c7b25c90205..7dde6b22dcd 100644 --- a/src/ui/ui-handler.ts +++ b/src/ui/ui-handler.ts @@ -1,7 +1,7 @@ import { globalScene } from "#app/global-scene"; import type { Button } from "#enums/buttons"; +import type { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; -import type { TextStyle } from "#ui/text"; import { getTextColor } from "#ui/text"; /** diff --git a/src/ui/ui.ts b/src/ui/ui.ts index e9798e6350d..4c8f0613122 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -2,6 +2,7 @@ import { globalScene } from "#app/global-scene"; import type { Button } from "#enums/buttons"; import { Device } from "#enums/devices"; import { PlayerGender } from "#enums/player-gender"; +import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import { AchvBar } from "#ui/achv-bar"; import { AchvsUiHandler } from "#ui/achvs-ui-handler"; @@ -51,7 +52,7 @@ import { StarterSelectUiHandler } from "#ui/starter-select-ui-handler"; import { SummaryUiHandler } from "#ui/summary-ui-handler"; import { TargetSelectUiHandler } from "#ui/target-select-ui-handler"; import { TestDialogueUiHandler } from "#ui/test-dialogue-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { TitleUiHandler } from "#ui/title-ui-handler"; import type { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; diff --git a/src/ui/unavailable-modal-ui-handler.ts b/src/ui/unavailable-modal-ui-handler.ts index 420a47664a7..5c3dc513473 100644 --- a/src/ui/unavailable-modal-ui-handler.ts +++ b/src/ui/unavailable-modal-ui-handler.ts @@ -1,9 +1,10 @@ import { updateUserInfo } from "#app/account"; import { globalScene } from "#app/global-scene"; +import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; import type { ModalConfig } from "#ui/modal-ui-handler"; import { ModalUiHandler } from "#ui/modal-ui-handler"; -import { addTextObject, TextStyle } from "#ui/text"; +import { addTextObject } from "#ui/text"; import { sessionIdKey } from "#utils/common"; import { removeCookie } from "#utils/cookies"; import i18next from "i18next"; From f3854abc166bf4ec4137a26864b4726cc0290066 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Sun, 27 Jul 2025 16:16:04 -0400 Subject: [PATCH 20/76] [Test] Added custom equality matchers (#6157) * Added rudimentary test matchers for `toEqualArrayUnsorted` and `toHaveTypes` Might port the rest at a later date * Actually run the effing setup matchers file + fixed ls lint to not be angy * added dev dep * Update .ls-lint.yml * Update .ls-lint.yml --------- Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Co-authored-by: Amani H. <109637146+xsn34kzx@users.noreply.github.com> --- .ls-lint.yml | 4 +- package.json | 1 + pnpm-lock.yaml | 3 + test/@types/vitest.d.ts | 26 ++++++++ test/matchers.setup.ts | 14 ++++ .../matchers/to-equal-array-unsorted.ts | 43 +++++++++++++ test/test-utils/matchers/to-have-types.ts | 64 +++++++++++++++++++ vitest.config.ts | 2 +- 8 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 test/@types/vitest.d.ts create mode 100644 test/matchers.setup.ts create mode 100644 test/test-utils/matchers/to-equal-array-unsorted.ts create mode 100644 test/test-utils/matchers/to-have-types.ts diff --git a/.ls-lint.yml b/.ls-lint.yml index 610218f8ed2..22f08f72938 100644 --- a/.ls-lint.yml +++ b/.ls-lint.yml @@ -11,14 +11,14 @@ _cfg: &cfg ls: <<: *cfg - src: + src: &src <<: *cfg .dir: kebab-case | regex:@types .js: exists:0 src/system/version-migration/versions: .ts: snake_case <<: *cfg - + test: *src ignore: - node_modules - .vscode diff --git a/package.json b/package.json index 9bba5e56f89..02d063389b7 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "@types/jsdom": "^21.1.7", "@types/node": "^22.16.3", "@vitest/coverage-istanbul": "^3.2.4", + "@vitest/expect": "^3.2.4", "chalk": "^5.4.1", "dependency-cruiser": "^16.10.4", "inquirer": "^12.7.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e77bf065fd5..86a7bb904a1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,6 +57,9 @@ importers: '@vitest/coverage-istanbul': specifier: ^3.2.4 version: 3.2.4(vitest@3.2.4(@types/node@22.16.3)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.3)(typescript@5.8.3))(yaml@2.8.0)) + '@vitest/expect': + specifier: ^3.2.4 + version: 3.2.4 chalk: specifier: ^5.4.1 version: 5.4.1 diff --git a/test/@types/vitest.d.ts b/test/@types/vitest.d.ts new file mode 100644 index 00000000000..3a0a0fec9cf --- /dev/null +++ b/test/@types/vitest.d.ts @@ -0,0 +1,26 @@ +import type { Pokemon } from "#field/pokemon"; +import type { PokemonType } from "#enums/pokemon-type"; +import type { expect } from "vitest"; +import { toHaveTypesOptions } from "#test/test-utils/matchers/to-have-types"; + +declare module "vitest" { + interface Assertion { + /** + * Matcher to check if an array contains EXACTLY the given items (in any order). + * + * Different from {@linkcode expect.arrayContaining} as the latter only requires the array contain + * _at least_ the listed items. + * + * @param expected - The expected contents of the array, in any order. + * @see {@linkcode expect.arrayContaining} + */ + toEqualArrayUnsorted(expected: E[]): void; + /** + * Matcher to check if a {@linkcode Pokemon}'s current typing includes the given types. + * + * @param expected - The expected types (in any order). + * @param options - The options passed to the matcher. + */ + toHaveTypes(expected: PokemonType[], options?: toHaveTypesOptions): void; + } +} \ No newline at end of file diff --git a/test/matchers.setup.ts b/test/matchers.setup.ts new file mode 100644 index 00000000000..7fd5fcb463e --- /dev/null +++ b/test/matchers.setup.ts @@ -0,0 +1,14 @@ +import { toEqualArrayUnsorted } from "#test/test-utils/matchers/to-equal-array-unsorted"; +import { toHaveTypes } from "#test/test-utils/matchers/to-have-types"; +import { expect } from "vitest"; + +/** + * @module + * Setup file for custom matchers. + * Make sure to define the call signatures in `test/@types/vitest.d.ts` too! + */ + +expect.extend({ + toEqualArrayUnsorted, + toHaveTypes, +}); diff --git a/test/test-utils/matchers/to-equal-array-unsorted.ts b/test/test-utils/matchers/to-equal-array-unsorted.ts new file mode 100644 index 00000000000..0627623bbd9 --- /dev/null +++ b/test/test-utils/matchers/to-equal-array-unsorted.ts @@ -0,0 +1,43 @@ +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +/** + * Matcher to check if an array contains exactly the given items, disregarding order. + * @param received - The object to check. Should be an array of elements. + * @returns The result of the matching + */ +export function toEqualArrayUnsorted(this: MatcherState, received: unknown, expected: unknown): SyncExpectationResult { + if (!Array.isArray(received)) { + return { + pass: this.isNot, + message: () => `Expected an array, but got ${this.utils.stringify(received)}!`, + }; + } + + if (!Array.isArray(expected)) { + return { + pass: this.isNot, + message: () => `Expected to recieve an array, but got ${this.utils.stringify(expected)}!`, + }; + } + + if (received.length !== expected.length) { + return { + pass: this.isNot, + message: () => `Expected to recieve array of length ${received.length}, but got ${expected.length}!`, + actual: received, + expected, + }; + } + + const gotSorted = received.slice().sort(); + const wantSorted = expected.slice().sort(); + const pass = this.equals(gotSorted, wantSorted, [...this.customTesters, this.utils.iterableEquality]); + + return { + pass: this.isNot !== pass, + message: () => + `Expected ${this.utils.stringify(received)} to exactly equal ${this.utils.stringify(expected)} without order!`, + actual: gotSorted, + expected: wantSorted, + }; +} diff --git a/test/test-utils/matchers/to-have-types.ts b/test/test-utils/matchers/to-have-types.ts new file mode 100644 index 00000000000..d09f4fc5f76 --- /dev/null +++ b/test/test-utils/matchers/to-have-types.ts @@ -0,0 +1,64 @@ +import { PokemonType } from "#enums/pokemon-type"; +import { Pokemon } from "#field/pokemon"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +export interface toHaveTypesOptions { + /** + * Whether to enforce exact matches (`true`) or superset matches (`false`). + * @defaultValue `true` + */ + exact?: boolean; + /** + * Optional arguments to pass to {@linkcode Pokemon.getTypes}. + */ + args?: Parameters<(typeof Pokemon.prototype)["getTypes"]>; +} + +/** + * Matcher to check if an array contains exactly the given items, disregarding order. + * @param received - The object to check. Should be an array of one or more {@linkcode PokemonType}s. + * @param options - The {@linkcode toHaveTypesOptions | options} for this matcher + * @returns The result of the matching + */ +export function toHaveTypes( + this: MatcherState, + received: unknown, + expected: unknown, + options: toHaveTypesOptions = {}, +): SyncExpectationResult { + if (!(received instanceof Pokemon)) { + return { + pass: this.isNot, + message: () => `Expected a Pokemon, but got ${this.utils.stringify(received)}!`, + }; + } + + if (!Array.isArray(expected) || expected.length === 0) { + return { + pass: this.isNot, + message: () => `Expected to recieve an array with length >=1, but got ${this.utils.stringify(expected)}!`, + }; + } + + if (!expected.every((t): t is PokemonType => t in PokemonType)) { + return { + pass: this.isNot, + message: () => `Expected to recieve array of PokemonTypes but got ${this.utils.stringify(expected)}!`, + }; + } + + const gotSorted = pkmnTypeToStr(received.getTypes(...(options.args ?? []))); + const wantSorted = pkmnTypeToStr(expected.slice()); + const pass = this.equals(gotSorted, wantSorted, [...this.customTesters, this.utils.iterableEquality]); + + return { + pass: this.isNot !== pass, + message: () => `Expected ${received.name} to have types ${this.utils.stringify(wantSorted)}, but got ${gotSorted}!`, + actual: gotSorted, + expected: wantSorted, + }; +} + +function pkmnTypeToStr(p: PokemonType[]): string[] { + return p.sort().map(type => PokemonType[type]); +} diff --git a/vitest.config.ts b/vitest.config.ts index e788302857b..65c5427e591 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -9,7 +9,7 @@ export default defineProject(({ mode }) => ({ TZ: "UTC", }, testTimeout: 20000, - setupFiles: ["./test/font-face.setup.ts", "./test/vitest.setup.ts"], + setupFiles: ["./test/font-face.setup.ts", "./test/vitest.setup.ts", "./test/matchers.setup.ts"], sequence: { sequencer: MySequencer, }, From 7cb2c560abbba0b5c8dad79ef3bc349ccbfc4a55 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Sun, 27 Jul 2025 13:32:47 -0700 Subject: [PATCH 21/76] [Misc] Fix import in `vitest.d.ts` --- test/@types/vitest.d.ts | 2 +- test/matchers.setup.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/test/@types/vitest.d.ts b/test/@types/vitest.d.ts index 3a0a0fec9cf..58b36580727 100644 --- a/test/@types/vitest.d.ts +++ b/test/@types/vitest.d.ts @@ -1,7 +1,7 @@ import type { Pokemon } from "#field/pokemon"; import type { PokemonType } from "#enums/pokemon-type"; import type { expect } from "vitest"; -import { toHaveTypesOptions } from "#test/test-utils/matchers/to-have-types"; +import type { toHaveTypesOptions } from "#test/test-utils/matchers/to-have-types"; declare module "vitest" { interface Assertion { diff --git a/test/matchers.setup.ts b/test/matchers.setup.ts index 7fd5fcb463e..03d9dd342e4 100644 --- a/test/matchers.setup.ts +++ b/test/matchers.setup.ts @@ -2,8 +2,7 @@ import { toEqualArrayUnsorted } from "#test/test-utils/matchers/to-equal-array-u import { toHaveTypes } from "#test/test-utils/matchers/to-have-types"; import { expect } from "vitest"; -/** - * @module +/* * Setup file for custom matchers. * Make sure to define the call signatures in `test/@types/vitest.d.ts` too! */ From 29d9bb6e7b554fa21403144f0c80b865c3af67c4 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Sun, 27 Jul 2025 16:42:57 -0400 Subject: [PATCH 22/76] [Dev] Turned on `checkJs` in TSConfig; fixed script type errors (#6115) --- biome.jsonc | 7 ++++--- scripts/create-test/create-test.js | 24 +++++++++++++----------- tsconfig.json | 1 + 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/biome.jsonc b/biome.jsonc index d4cb67d33a6..470885a543d 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -177,9 +177,10 @@ } }, - // Overrides to prevent unused import removal inside `overrides.ts` and enums files (for TSDoc linkcodes) + // Overrides to prevent unused import removal inside `overrides.ts` and enums files (for TSDoc linkcodes), + // as well as in all TS files in `scripts/` (which are assumed to be boilerplate templates). { - "includes": ["**/src/overrides.ts", "**/src/enums/**/*"], + "includes": ["**/src/overrides.ts", "**/src/enums/**/*", "**/scripts/**/*.ts"], "linter": { "rules": { "correctness": { @@ -189,7 +190,7 @@ } }, { - "includes": ["**/src/overrides.ts"], + "includes": ["**/src/overrides.ts", "**/scripts/**/*.ts"], "linter": { "rules": { "style": { diff --git a/scripts/create-test/create-test.js b/scripts/create-test/create-test.js index f24aac548fc..c0f27f8891e 100644 --- a/scripts/create-test/create-test.js +++ b/scripts/create-test/create-test.js @@ -44,20 +44,22 @@ function getTestFolderPath(...folders) { * @returns {Promise<{selectedOption: {label: string, dir: string}}>} the selected type */ async function promptTestType() { - const typeAnswer = await inquirer.prompt([ - { - type: "list", - name: "selectedOption", - message: "What type of test would you like to create?", - choices: [...choices.map(choice => ({ name: choice.label, value: choice })), "EXIT"], - }, - ]); + const typeAnswer = await inquirer + .prompt([ + { + type: "list", + name: "selectedOption", + message: "What type of test would you like to create?", + choices: [...choices.map(choice => ({ name: choice.label, value: choice })), { name: "EXIT", value: "N/A" }], + }, + ]) + .then(ans => ans.selectedOption); - if (typeAnswer.selectedOption === "EXIT") { + if (typeAnswer.name === "EXIT") { console.log("Exiting..."); - return process.exit(); + return process.exit(0); } - if (!choices.some(choice => choice.dir === typeAnswer.selectedOption.dir)) { + if (!choices.some(choice => choice.dir === typeAnswer.dir)) { console.error(`Please provide a valid type: (${choices.map(choice => choice.label).join(", ")})!`); return await promptTestType(); } diff --git a/tsconfig.json b/tsconfig.json index 8c53625ce55..1e067dcff03 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,7 @@ "esModuleInterop": true, "strictNullChecks": true, "sourceMap": false, + "checkJs": true, "strict": false, // TODO: Enable this eventually "rootDir": ".", "baseUrl": "./src", From 19730f9cf0345ed54e13c606bca8313c2d1aa0de Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Sun, 27 Jul 2025 16:59:03 -0400 Subject: [PATCH 23/76] [Misc] Moved + cleaned up string manipulation functions (#6112) * Added string utility package to replace util functions * Changed string manipulation functions fully over to `change-case` * Fixed missing comma in package.json trailing commas when :( * fixed lockfile * Hopefully re-added all the string utils * fixed package json * Fixed remaining cases of regex + code dupliation * Fixed more bugs and errors * Moved around functions and hopefully fixed the regex issues * Minor renaming * Fixed incorrect casing on setting strings pascal snake case :skull: * ran biome --- src/data/balance/egg-moves.ts | 4 +- src/data/battle-anims.ts | 15 +- src/data/challenge.ts | 99 +++------- src/data/dialogue.ts | 4 +- src/data/moves/move.ts | 5 +- .../mystery-encounters/mystery-encounter.ts | 3 +- src/data/nature.ts | 4 +- src/data/pokemon-species.ts | 21 +- src/data/trainer-names.ts | 4 +- src/data/trainers/trainer-config.ts | 14 +- src/field/trainer.ts | 7 +- src/plugins/i18n.ts | 8 +- src/system/game-data.ts | 4 +- src/ui/admin-ui-handler.ts | 6 +- src/ui/arena-flyout.ts | 7 +- src/ui/bgm-bar.ts | 4 +- src/ui/game-stats-ui-handler.ts | 9 +- src/ui/party-ui-handler.ts | 5 +- src/ui/pokedex-page-ui-handler.ts | 12 +- .../abstract-control-settings-ui-handler.ts | 14 +- .../settings/settings-keyboard-ui-handler.ts | 5 +- src/ui/starter-select-ui-handler.ts | 4 +- src/ui/summary-ui-handler.ts | 6 +- src/utils/common.ts | 105 +--------- src/utils/strings.ts | 179 ++++++++++++++++++ test/setting-menu/helpers/in-game-manip.ts | 14 +- test/setting-menu/helpers/menu-manip.ts | 1 + test/test-utils/helpers/move-helper.ts | 15 +- test/utils/strings.test.ts | 47 +++++ 29 files changed, 342 insertions(+), 283 deletions(-) create mode 100644 src/utils/strings.ts create mode 100644 test/utils/strings.test.ts diff --git a/src/data/balance/egg-moves.ts b/src/data/balance/egg-moves.ts index f5026abe2ef..3475fe4fdea 100644 --- a/src/data/balance/egg-moves.ts +++ b/src/data/balance/egg-moves.ts @@ -1,8 +1,8 @@ import { allMoves } from "#data/data-lists"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { toReadableString } from "#utils/common"; import { getEnumKeys, getEnumValues } from "#utils/enums"; +import { toTitleCase } from "#utils/strings"; export const speciesEggMoves = { [SpeciesId.BULBASAUR]: [ MoveId.SAPPY_SEED, MoveId.MALIGNANT_CHAIN, MoveId.EARTH_POWER, MoveId.MATCHA_GOTCHA ], @@ -617,7 +617,7 @@ function parseEggMoves(content: string): void { } if (eggMoves.every(m => m === MoveId.NONE)) { - console.warn(`Species ${toReadableString(SpeciesId[species])} could not be parsed, excluding from output...`) + console.warn(`Species ${toTitleCase(SpeciesId[species])} could not be parsed, excluding from output...`) } else { output += `[SpeciesId.${SpeciesId[species]}]: [ ${eggMoves.map(m => `MoveId.${MoveId[m]}`).join(", ")} ],\n`; } diff --git a/src/data/battle-anims.ts b/src/data/battle-anims.ts index 0dc8bf4850c..55a3cc4e916 100644 --- a/src/data/battle-anims.ts +++ b/src/data/battle-anims.ts @@ -7,8 +7,9 @@ import { AnimBlendType, AnimFocus, AnimFrameTarget, ChargeAnim, CommonAnim } fro import { MoveFlags } from "#enums/move-flags"; import { MoveId } from "#enums/move-id"; import type { Pokemon } from "#field/pokemon"; -import { animationFileName, coerceArray, getFrameMs, isNullOrUndefined, type nil } from "#utils/common"; +import { coerceArray, getFrameMs, isNullOrUndefined, type nil } from "#utils/common"; import { getEnumKeys, getEnumValues } from "#utils/enums"; +import { toKebabCase } from "#utils/strings"; import Phaser from "phaser"; export class AnimConfig { @@ -412,7 +413,7 @@ export function initCommonAnims(): Promise { const commonAnimId = commonAnimIds[ca]; commonAnimFetches.push( globalScene - .cachedFetch(`./battle-anims/common-${commonAnimNames[ca].toLowerCase().replace(/_/g, "-")}.json`) + .cachedFetch(`./battle-anims/common-${toKebabCase(commonAnimNames[ca])}.json`) .then(response => response.json()) .then(cas => commonAnims.set(commonAnimId, new AnimConfig(cas))), ); @@ -450,7 +451,7 @@ export function initMoveAnim(move: MoveId): Promise { const fetchAnimAndResolve = (move: MoveId) => { globalScene - .cachedFetch(`./battle-anims/${animationFileName(move)}.json`) + .cachedFetch(`./battle-anims/${toKebabCase(MoveId[move])}.json`) .then(response => { const contentType = response.headers.get("content-type"); if (!response.ok || contentType?.indexOf("application/json") === -1) { @@ -506,7 +507,7 @@ function useDefaultAnim(move: MoveId, defaultMoveAnim: MoveId) { * @remarks use {@linkcode useDefaultAnim} to use a default animation */ function logMissingMoveAnim(move: MoveId, ...optionalParams: any[]) { - const moveName = animationFileName(move); + const moveName = toKebabCase(MoveId[move]); console.warn(`Could not load animation file for move '${moveName}'`, ...optionalParams); } @@ -524,7 +525,7 @@ export async function initEncounterAnims(encounterAnim: EncounterAnim | Encounte } encounterAnimFetches.push( globalScene - .cachedFetch(`./battle-anims/encounter-${encounterAnimNames[anim].toLowerCase().replace(/_/g, "-")}.json`) + .cachedFetch(`./battle-anims/encounter-${toKebabCase(encounterAnimNames[anim])}.json`) .then(response => response.json()) .then(cas => encounterAnims.set(anim, new AnimConfig(cas))), ); @@ -548,7 +549,7 @@ export function initMoveChargeAnim(chargeAnim: ChargeAnim): Promise { } else { chargeAnims.set(chargeAnim, null); globalScene - .cachedFetch(`./battle-anims/${ChargeAnim[chargeAnim].toLowerCase().replace(/_/g, "-")}.json`) + .cachedFetch(`./battle-anims/${toKebabCase(ChargeAnim[chargeAnim])}.json`) .then(response => response.json()) .then(ca => { if (Array.isArray(ca)) { @@ -1405,7 +1406,9 @@ export async function populateAnims() { const chargeAnimIds = getEnumValues(ChargeAnim); const commonNamePattern = /name: (?:Common:)?(Opp )?(.*)/; const moveNameToId = {}; + // Exclude MoveId.NONE; for (const move of getEnumValues(MoveId).slice(1)) { + // KARATE_CHOP => KARATECHOP const moveName = MoveId[move].toUpperCase().replace(/_/g, ""); moveNameToId[moveName] = move; } diff --git a/src/data/challenge.ts b/src/data/challenge.ts index 938ee482d01..db4ec931bc2 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -27,6 +27,7 @@ import type { DexAttrProps, GameData } from "#system/game-data"; import { BooleanHolder, type NumberHolder, randSeedItem } from "#utils/common"; import { deepCopy } from "#utils/data"; import { getPokemonSpecies } from "#utils/pokemon-utils"; +import { toCamelCase, toSnakeCase } from "#utils/strings"; import i18next from "i18next"; /** A constant for the default max cost of the starting party before a run */ @@ -67,14 +68,11 @@ export abstract class Challenge { } /** - * Gets the localisation key for the challenge - * @returns {@link string} The i18n key for this challenge + * Gets the localization key for the challenge + * @returns The i18n key for this challenge as camel case. */ geti18nKey(): string { - return Challenges[this.id] - .split("_") - .map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase())) - .join(""); + return toCamelCase(Challenges[this.id]); } /** @@ -105,23 +103,22 @@ export abstract class Challenge { } /** - * Returns the textual representation of a challenge's current value. - * @param overrideValue {@link number} The value to check for. If undefined, gets the current value. - * @returns {@link string} The localised name for the current value. + * Return the textual representation of a challenge's current value. + * @param overrideValue - The value to check for; default {@linkcode this.value} + * @returns The localised text for the current value. */ - getValue(overrideValue?: number): string { - const value = overrideValue ?? this.value; - return i18next.t(`challenges:${this.geti18nKey()}.value.${value}`); + getValue(overrideValue: number = this.value): string { + return i18next.t(`challenges:${this.geti18nKey()}.value.${overrideValue}`); } /** - * Returns the description of a challenge's current value. - * @param overrideValue {@link number} The value to check for. If undefined, gets the current value. - * @returns {@link string} The localised description for the current value. + * Return the description of a challenge's current value. + * @param overrideValue - The value to check for; default {@linkcode this.value} + * @returns The localised description for the current value. */ - getDescription(overrideValue?: number): string { - const value = overrideValue ?? this.value; - return `${i18next.t([`challenges:${this.geti18nKey()}.desc.${value}`, `challenges:${this.geti18nKey()}.desc`])}`; + // TODO: Do we need an override value here? it's currently unused + getDescription(overrideValue: number = this.value): string { + return `${i18next.t([`challenges:${this.geti18nKey()}.desc.${overrideValue}`, `challenges:${this.geti18nKey()}.desc`])}`; } /** @@ -579,31 +576,19 @@ export class SingleGenerationChallenge extends Challenge { return this.value > 0 ? 1 : 0; } - /** - * Returns the textual representation of a challenge's current value. - * @param {value} overrideValue The value to check for. If undefined, gets the current value. - * @returns {string} The localised name for the current value. - */ - getValue(overrideValue?: number): string { - const value = overrideValue ?? this.value; - if (value === 0) { + getValue(overrideValue: number = this.value): string { + if (overrideValue === 0) { return i18next.t("settings:off"); } - return i18next.t(`starterSelectUiHandler:gen${value}`); + return i18next.t(`starterSelectUiHandler:gen${overrideValue}`); } - /** - * Returns the description of a challenge's current value. - * @param {value} overrideValue The value to check for. If undefined, gets the current value. - * @returns {string} The localised description for the current value. - */ - getDescription(overrideValue?: number): string { - const value = overrideValue ?? this.value; - if (value === 0) { + getDescription(overrideValue: number = this.value): string { + if (overrideValue === 0) { return i18next.t("challenges:singleGeneration.desc_default"); } return i18next.t("challenges:singleGeneration.desc", { - gen: i18next.t(`challenges:singleGeneration.gen_${value}`), + gen: i18next.t(`challenges:singleGeneration.gen_${overrideValue}`), }); } @@ -671,29 +656,13 @@ export class SingleTypeChallenge extends Challenge { return this.value > 0 ? 1 : 0; } - /** - * Returns the textual representation of a challenge's current value. - * @param {value} overrideValue The value to check for. If undefined, gets the current value. - * @returns {string} The localised name for the current value. - */ - getValue(overrideValue?: number): string { - if (overrideValue === undefined) { - overrideValue = this.value; - } - return PokemonType[this.value - 1].toLowerCase(); + getValue(overrideValue: number = this.value): string { + return toSnakeCase(PokemonType[overrideValue - 1]); } - /** - * Returns the description of a challenge's current value. - * @param {value} overrideValue The value to check for. If undefined, gets the current value. - * @returns {string} The localised description for the current value. - */ - getDescription(overrideValue?: number): string { - if (overrideValue === undefined) { - overrideValue = this.value; - } - const type = i18next.t(`pokemonInfo:Type.${PokemonType[this.value - 1]}`); - const typeColor = `[color=${TypeColor[PokemonType[this.value - 1]]}][shadow=${TypeShadow[PokemonType[this.value - 1]]}]${type}[/shadow][/color]`; + getDescription(overrideValue: number = this.value): string { + const type = i18next.t(`pokemonInfo:Type.${PokemonType[overrideValue - 1]}`); + const typeColor = `[color=${TypeColor[PokemonType[overrideValue - 1]]}][shadow=${TypeShadow[PokemonType[this.value - 1]]}]${type}[/shadow][/color]`; const defaultDesc = i18next.t("challenges:singleType.desc_default"); const typeDesc = i18next.t("challenges:singleType.desc", { type: typeColor, @@ -832,13 +801,7 @@ export class LowerStarterMaxCostChallenge extends Challenge { super(Challenges.LOWER_MAX_STARTER_COST, 9); } - /** - * @override - */ - getValue(overrideValue?: number): string { - if (overrideValue === undefined) { - overrideValue = this.value; - } + getValue(overrideValue: number = this.value): string { return (DEFAULT_PARTY_MAX_COST - overrideValue).toString(); } @@ -866,13 +829,7 @@ export class LowerStarterPointsChallenge extends Challenge { super(Challenges.LOWER_STARTER_POINTS, 9); } - /** - * @override - */ - getValue(overrideValue?: number): string { - if (overrideValue === undefined) { - overrideValue = this.value; - } + getValue(overrideValue: number = this.value): string { return (DEFAULT_PARTY_MAX_COST - overrideValue).toString(); } diff --git a/src/data/dialogue.ts b/src/data/dialogue.ts index 406e72ee82b..361d005e83b 100644 --- a/src/data/dialogue.ts +++ b/src/data/dialogue.ts @@ -1,6 +1,7 @@ import { BattleSpec } from "#enums/battle-spec"; import { TrainerType } from "#enums/trainer-type"; import { trainerConfigs } from "#trainers/trainer-config"; +import { capitalizeFirstLetter } from "#utils/strings"; export interface TrainerTypeMessages { encounter?: string | string[]; @@ -1755,8 +1756,7 @@ export function initTrainerTypeDialogue(): void { trainerConfigs[trainerType][`${messageType}Messages`] = messages[0][messageType]; } if (messages.length > 1) { - trainerConfigs[trainerType][`female${messageType.slice(0, 1).toUpperCase()}${messageType.slice(1)}Messages`] = - messages[1][messageType]; + trainerConfigs[trainerType][`female${capitalizeFirstLetter(messageType)}Messages`] = messages[1][messageType]; } } else { trainerConfigs[trainerType][`${messageType}Messages`] = messages[messageType]; diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index 779f2d4fc76..965ab23a692 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -87,8 +87,9 @@ import type { AttackMoveResult } from "#types/attack-move-result"; import type { Localizable } from "#types/locales"; import type { ChargingMove, MoveAttrMap, MoveAttrString, MoveClassMap, MoveKindString } from "#types/move-types"; import type { TurnMove } from "#types/turn-move"; -import { BooleanHolder, type Constructor, isNullOrUndefined, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue, toReadableString } from "#utils/common"; +import { BooleanHolder, type Constructor, isNullOrUndefined, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common"; import { getEnumValues } from "#utils/enums"; +import { toTitleCase } from "#utils/strings"; import i18next from "i18next"; /** @@ -8137,7 +8138,7 @@ export class ResistLastMoveTypeAttr extends MoveEffectAttr { } const type = validTypes[user.randBattleSeedInt(validTypes.length)]; user.summonData.types = [ type ]; - globalScene.phaseManager.queueMessage(i18next.t("battle:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), type: toReadableString(PokemonType[type]) })); + globalScene.phaseManager.queueMessage(i18next.t("battle:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), type: toTitleCase(PokemonType[type]) })); user.updateInfo(); return true; diff --git a/src/data/mystery-encounters/mystery-encounter.ts b/src/data/mystery-encounters/mystery-encounter.ts index a2ca2b20ce7..47dfe58cace 100644 --- a/src/data/mystery-encounters/mystery-encounter.ts +++ b/src/data/mystery-encounters/mystery-encounter.ts @@ -25,7 +25,8 @@ import { StatusEffectRequirement, WaveRangeRequirement, } from "#mystery-encounters/mystery-encounter-requirements"; -import { capitalizeFirstLetter, coerceArray, isNullOrUndefined, randSeedInt } from "#utils/common"; +import { coerceArray, isNullOrUndefined, randSeedInt } from "#utils/common"; +import { capitalizeFirstLetter } from "#utils/strings"; export interface EncounterStartOfBattleEffect { sourcePokemon?: Pokemon; diff --git a/src/data/nature.ts b/src/data/nature.ts index 41764ec4276..b085faebb80 100644 --- a/src/data/nature.ts +++ b/src/data/nature.ts @@ -3,7 +3,7 @@ import { EFFECTIVE_STATS, getShortenedStatKey, Stat } from "#enums/stat"; import { TextStyle } from "#enums/text-style"; import { UiTheme } from "#enums/ui-theme"; import { getBBCodeFrag } from "#ui/text"; -import { toReadableString } from "#utils/common"; +import { toTitleCase } from "#utils/strings"; import i18next from "i18next"; export function getNatureName( @@ -13,7 +13,7 @@ export function getNatureName( ignoreBBCode = false, uiTheme: UiTheme = UiTheme.DEFAULT, ): string { - let ret = toReadableString(Nature[nature]); + let ret = toTitleCase(Nature[nature]); //Translating nature if (i18next.exists(`nature:${ret}`)) { ret = i18next.t(`nature:${ret}` as any); diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 4e1c01642cb..dfaa6425ef1 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -29,15 +29,9 @@ import type { Variant, VariantSet } from "#sprites/variant"; import { populateVariantColorCache, variantColorCache, variantData } from "#sprites/variant"; import type { StarterMoveset } from "#system/game-data"; import type { Localizable } from "#types/locales"; -import { - capitalizeString, - isNullOrUndefined, - randSeedFloat, - randSeedGauss, - randSeedInt, - randSeedItem, -} from "#utils/common"; +import { isNullOrUndefined, randSeedFloat, randSeedGauss, randSeedInt, randSeedItem } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; +import { toCamelCase, toPascalCase } from "#utils/strings"; import { argbFromRgba, QuantizerCelebi, rgbaFromArgb } from "@material/material-color-utilities"; import i18next from "i18next"; @@ -91,6 +85,7 @@ export function getPokemonSpeciesForm(species: SpeciesId, formIndex: number): Po return retSpecies; } +// TODO: Clean this up and seriously review alternate means of fusion naming export function getFusedSpeciesName(speciesAName: string, speciesBName: string): string { const fragAPattern = /([a-z]{2}.*?[aeiou(?:y$)\-']+)(.*?)$/i; const fragBPattern = /([a-z]{2}.*?[aeiou(?:y$)\-'])(.*?)$/i; @@ -904,14 +899,14 @@ export class PokemonSpecies extends PokemonSpeciesForm implements Localizable { * @returns the pokemon-form locale key for the single form name ("Alolan Form", "Eternal Flower" etc) */ getFormNameToDisplay(formIndex = 0, append = false): string { - const formKey = this.forms?.[formIndex!]?.formKey; - const formText = capitalizeString(formKey, "-", false, false) || ""; - const speciesName = capitalizeString(SpeciesId[this.speciesId], "_", true, false); + const formKey = this.forms[formIndex]?.formKey ?? ""; + const formText = toPascalCase(formKey); + const speciesName = toCamelCase(SpeciesId[this.speciesId]); let ret = ""; const region = this.getRegion(); if (this.speciesId === SpeciesId.ARCEUS) { - ret = i18next.t(`pokemonInfo:Type.${formText?.toUpperCase()}`); + ret = i18next.t(`pokemonInfo:Type.${formText.toUpperCase()}`); } else if ( [ SpeciesFormKey.MEGA, @@ -937,7 +932,7 @@ export class PokemonSpecies extends PokemonSpeciesForm implements Localizable { if (i18next.exists(i18key)) { ret = i18next.t(i18key); } else { - const rootSpeciesName = capitalizeString(SpeciesId[this.getRootSpeciesId()], "_", true, false); + const rootSpeciesName = toCamelCase(SpeciesId[this.getRootSpeciesId()]); const i18RootKey = `pokemonForm:${rootSpeciesName}${formText}`; ret = i18next.exists(i18RootKey) ? i18next.t(i18RootKey) : formText; } diff --git a/src/data/trainer-names.ts b/src/data/trainer-names.ts index 6b882d1ddc1..8eafd9f6404 100644 --- a/src/data/trainer-names.ts +++ b/src/data/trainer-names.ts @@ -1,12 +1,12 @@ import { TrainerType } from "#enums/trainer-type"; -import { toReadableString } from "#utils/common"; +import { toPascalSnakeCase } from "#utils/strings"; class TrainerNameConfig { public urls: string[]; public femaleUrls: string[] | null; constructor(type: TrainerType, ...urls: string[]) { - this.urls = urls.length ? urls : [toReadableString(TrainerType[type]).replace(/ /g, "_")]; + this.urls = urls.length ? urls : [toPascalSnakeCase(TrainerType[type])]; } hasGenderVariant(...femaleUrls: string[]): TrainerNameConfig { diff --git a/src/data/trainers/trainer-config.ts b/src/data/trainers/trainer-config.ts index 4e88399bec3..6b3fcf70f80 100644 --- a/src/data/trainers/trainer-config.ts +++ b/src/data/trainers/trainer-config.ts @@ -41,15 +41,9 @@ import type { TrainerConfigs, TrainerTierPools, } from "#types/trainer-funcs"; -import { - coerceArray, - isNullOrUndefined, - randSeedInt, - randSeedIntRange, - randSeedItem, - toReadableString, -} from "#utils/common"; +import { coerceArray, isNullOrUndefined, randSeedInt, randSeedIntRange, randSeedItem } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; +import { toSnakeCase, toTitleCase } from "#utils/strings"; import i18next from "i18next"; /** Minimum BST for Pokemon generated onto the Elite Four's teams */ @@ -140,7 +134,7 @@ export class TrainerConfig { constructor(trainerType: TrainerType, allowLegendaries?: boolean) { this.trainerType = trainerType; this.trainerAI = new TrainerAI(); - this.name = toReadableString(TrainerType[this.getDerivedType()]); + this.name = toTitleCase(TrainerType[this.getDerivedType()]); this.battleBgm = "battle_trainer"; this.mixedBattleBgm = "battle_trainer"; this.victoryBgm = "victory_trainer"; @@ -734,7 +728,7 @@ export class TrainerConfig { } // Localize the trainer's name by converting it to lowercase and replacing spaces with underscores. - const nameForCall = this.name.toLowerCase().replace(/\s/g, "_"); + const nameForCall = toSnakeCase(this.name); this.name = i18next.t(`trainerNames:${nameForCall}`); // Set the title to "elite_four". (this is the key in the i18n file) diff --git a/src/field/trainer.ts b/src/field/trainer.ts index 7186cc4e928..a8af298e1cf 100644 --- a/src/field/trainer.ts +++ b/src/field/trainer.ts @@ -23,6 +23,7 @@ import { } from "#trainers/trainer-party-template"; import { randSeedInt, randSeedItem, randSeedWeightedItem } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; +import { toSnakeCase } from "#utils/strings"; import i18next from "i18next"; export class Trainer extends Phaser.GameObjects.Container { @@ -170,7 +171,7 @@ export class Trainer extends Phaser.GameObjects.Container { const evilTeamTitles = ["grunt"]; if (this.name === "" && evilTeamTitles.some(t => name.toLocaleLowerCase().includes(t))) { // This is a evil team grunt so we localize it by only using the "name" as the title - title = i18next.t(`trainerClasses:${name.toLowerCase().replace(/\s/g, "_")}`); + title = i18next.t(`trainerClasses:${toSnakeCase(name)}`); console.log("Localized grunt name: " + title); // Since grunts are not named we can just return the title return title; @@ -187,7 +188,7 @@ export class Trainer extends Phaser.GameObjects.Container { } // Get the localized trainer class name from the i18n file and set it as the title. // This is used for trainer class names, not titles like "Elite Four, Champion, etc." - title = i18next.t(`trainerClasses:${name.toLowerCase().replace(/\s/g, "_")}`); + title = i18next.t(`trainerClasses:${toSnakeCase(name)}`); } // If no specific trainer slot is set. @@ -208,7 +209,7 @@ export class Trainer extends Phaser.GameObjects.Container { if (this.config.titleDouble && this.variant === TrainerVariant.DOUBLE && !this.config.doubleOnly) { title = this.config.titleDouble; - name = i18next.t(`trainerNames:${this.config.nameDouble.toLowerCase().replace(/\s/g, "_")}`); + name = i18next.t(`trainerNames:${toSnakeCase(this.config.nameDouble)}`); } console.log(title ? `${title} ${name}` : name); diff --git a/src/plugins/i18n.ts b/src/plugins/i18n.ts index 4ee4aa730fb..89946b2691b 100644 --- a/src/plugins/i18n.ts +++ b/src/plugins/i18n.ts @@ -1,5 +1,5 @@ import pkg from "#package.json"; -import { camelCaseToKebabCase } from "#utils/common"; +import { toKebabCase } from "#utils/strings"; import i18next from "i18next"; import LanguageDetector from "i18next-browser-languagedetector"; import HttpBackend from "i18next-http-backend"; @@ -194,14 +194,16 @@ export async function initI18n(): Promise { ], backend: { loadPath(lng: string, [ns]: string[]) { + // Use namespace maps where required let fileName: string; if (namespaceMap[ns]) { fileName = namespaceMap[ns]; } else if (ns.startsWith("mysteryEncounters/")) { - fileName = camelCaseToKebabCase(ns + "Dialogue"); + fileName = toKebabCase(ns + "-dialogue"); // mystery-encounters/a-trainers-test-dialogue } else { - fileName = camelCaseToKebabCase(ns); + fileName = toKebabCase(ns); } + // ex: "./locales/en/move-anims" return `./locales/${lng}/${fileName}.json?v=${pkg.version}`; }, }, diff --git a/src/system/game-data.ts b/src/system/game-data.ts index c52a5155fb4..b148ed4e2ba 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -1454,11 +1454,10 @@ export class GameData { reader.onload = (_ => { return e => { - let dataName: string; + let dataName = GameDataType[dataType].toLowerCase(); let dataStr = AES.decrypt(e.target?.result?.toString()!, saveKey).toString(enc.Utf8); // TODO: is this bang correct? let valid = false; try { - dataName = GameDataType[dataType].toLowerCase(); switch (dataType) { case GameDataType.SYSTEM: { dataStr = this.convertSystemDataStr(dataStr); @@ -1493,7 +1492,6 @@ export class GameData { const displayError = (error: string) => globalScene.ui.showText(error, null, () => globalScene.ui.showText("", 0), fixedInt(1500)); - dataName = dataName!; // tell TS compiler that dataName is defined! if (!valid) { return globalScene.ui.showText( diff --git a/src/ui/admin-ui-handler.ts b/src/ui/admin-ui-handler.ts index f136aeb5008..e577368363d 100644 --- a/src/ui/admin-ui-handler.ts +++ b/src/ui/admin-ui-handler.ts @@ -6,7 +6,7 @@ import { UiMode } from "#enums/ui-mode"; import type { InputFieldConfig } from "#ui/form-modal-ui-handler"; import { FormModalUiHandler } from "#ui/form-modal-ui-handler"; import type { ModalConfig } from "#ui/modal-ui-handler"; -import { formatText } from "#utils/common"; +import { toTitleCase } from "#utils/strings"; type AdminUiHandlerService = "discord" | "google"; type AdminUiHandlerServiceMode = "Link" | "Unlink"; @@ -21,9 +21,9 @@ export class AdminUiHandler extends FormModalUiHandler { private readonly httpUserNotFoundErrorCode: number = 404; private readonly ERR_REQUIRED_FIELD = (field: string) => { if (field === "username") { - return `${formatText(field)} is required`; + return `${toTitleCase(field)} is required`; } - return `${formatText(field)} Id is required`; + return `${toTitleCase(field)} Id is required`; }; // returns a string saying whether a username has been successfully linked/unlinked to discord/google private readonly SUCCESS_SERVICE_MODE = (service: string, mode: string) => { diff --git a/src/ui/arena-flyout.ts b/src/ui/arena-flyout.ts index 9a674719202..d2a45646690 100644 --- a/src/ui/arena-flyout.ts +++ b/src/ui/arena-flyout.ts @@ -18,7 +18,8 @@ import { BattleSceneEventType } from "#events/battle-scene"; import { addTextObject } from "#ui/text"; import { TimeOfDayWidget } from "#ui/time-of-day-widget"; import { addWindow, WindowVariant } from "#ui/ui-theme"; -import { fixedInt, formatText, toCamelCaseString } from "#utils/common"; +import { fixedInt } from "#utils/common"; +import { toCamelCase, toTitleCase } from "#utils/strings"; import type { ParseKeys } from "i18next"; import i18next from "i18next"; @@ -49,10 +50,10 @@ export function getFieldEffectText(arenaTagType: string): string { if (!arenaTagType || arenaTagType === ArenaTagType.NONE) { return arenaTagType; } - const effectName = toCamelCaseString(arenaTagType); + const effectName = toCamelCase(arenaTagType); const i18nKey = `arenaFlyout:${effectName}` as ParseKeys; const resultName = i18next.t(i18nKey); - return !resultName || resultName === i18nKey ? formatText(arenaTagType) : resultName; + return !resultName || resultName === i18nKey ? toTitleCase(arenaTagType) : resultName; } export class ArenaFlyout extends Phaser.GameObjects.Container { diff --git a/src/ui/bgm-bar.ts b/src/ui/bgm-bar.ts index fb50e444aa5..e2c6925ec30 100644 --- a/src/ui/bgm-bar.ts +++ b/src/ui/bgm-bar.ts @@ -1,7 +1,7 @@ import { globalScene } from "#app/global-scene"; import { TextStyle } from "#enums/text-style"; import { addTextObject } from "#ui/text"; -import { formatText } from "#utils/common"; +import { toTitleCase } from "#utils/strings"; import i18next from "i18next"; const hiddenX = -150; @@ -101,7 +101,7 @@ export class BgmBar extends Phaser.GameObjects.Container { getRealBgmName(bgmName: string): string { return i18next.t([`bgmName:${bgmName}`, "bgmName:missing_entries"], { - name: formatText(bgmName), + name: toTitleCase(bgmName), }); } } diff --git a/src/ui/game-stats-ui-handler.ts b/src/ui/game-stats-ui-handler.ts index fa5cd0a989a..ed66230bed7 100644 --- a/src/ui/game-stats-ui-handler.ts +++ b/src/ui/game-stats-ui-handler.ts @@ -8,7 +8,8 @@ import type { GameData } from "#system/game-data"; import { addTextObject } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; -import { formatFancyLargeNumber, getPlayTimeString, toReadableString } from "#utils/common"; +import { formatFancyLargeNumber, getPlayTimeString } from "#utils/common"; +import { toTitleCase } from "#utils/strings"; import i18next from "i18next"; import Phaser from "phaser"; @@ -502,11 +503,9 @@ export function initStatsKeys() { sourceFunc: gameData => gameData.gameStats[key].toString(), }; } - if (!(displayStats[key] as DisplayStat).label_key) { + if (!displayStats[key].label_key) { const splittableKey = key.replace(/([a-z]{2,})([A-Z]{1}(?:[^A-Z]|$))/g, "$1_$2"); - (displayStats[key] as DisplayStat).label_key = toReadableString( - `${splittableKey[0].toUpperCase()}${splittableKey.slice(1)}`, - ); + displayStats[key].label_key = toTitleCase(splittableKey); } } } diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 2b29a564f9f..915cc76fd73 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -26,7 +26,8 @@ import { MoveInfoOverlay } from "#ui/move-info-overlay"; import { PokemonIconAnimHandler, PokemonIconAnimMode } from "#ui/pokemon-icon-anim-handler"; import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; -import { BooleanHolder, getLocalizedSpriteKey, randInt, toReadableString } from "#utils/common"; +import { BooleanHolder, getLocalizedSpriteKey, randInt } from "#utils/common"; +import { toTitleCase } from "#utils/strings"; import i18next from "i18next"; import type BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; @@ -1409,7 +1410,7 @@ export class PartyUiHandler extends MessageUiHandler { if (this.localizedOptions.includes(option)) { optionName = i18next.t(`partyUiHandler:${PartyOption[option]}`); } else { - optionName = toReadableString(PartyOption[option]); + optionName = toTitleCase(PartyOption[option]); } } break; diff --git a/src/ui/pokedex-page-ui-handler.ts b/src/ui/pokedex-page-ui-handler.ts index b3eb8de0f50..49ce5b64d9f 100644 --- a/src/ui/pokedex-page-ui-handler.ts +++ b/src/ui/pokedex-page-ui-handler.ts @@ -54,16 +54,10 @@ import { PokedexInfoOverlay } from "#ui/pokedex-info-overlay"; import { StatsContainer } from "#ui/stats-container"; import { addBBCodeTextObject, addTextObject, getTextColor, getTextStyleOptions } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; -import { - BooleanHolder, - getLocalizedSpriteKey, - isNullOrUndefined, - padInt, - rgbHexToRgba, - toReadableString, -} from "#utils/common"; +import { BooleanHolder, getLocalizedSpriteKey, isNullOrUndefined, padInt, rgbHexToRgba } from "#utils/common"; import { getEnumValues } from "#utils/enums"; import { getPokemonSpecies } from "#utils/pokemon-utils"; +import { toTitleCase } from "#utils/strings"; import { argbFromRgba } from "@material/material-color-utilities"; import i18next from "i18next"; import type BBCodeText from "phaser3-rex-plugins/plugins/gameobjects/tagtext/bbcodetext/BBCodeText"; @@ -2620,7 +2614,7 @@ export class PokedexPageUiHandler extends MessageUiHandler { // Setting growth rate text if (isFormCaught) { - let growthReadable = toReadableString(GrowthRate[species.growthRate]); + let growthReadable = toTitleCase(GrowthRate[species.growthRate]); const growthAux = growthReadable.replace(" ", "_"); if (i18next.exists("growth:" + growthAux)) { growthReadable = i18next.t(("growth:" + growthAux) as any); diff --git a/src/ui/settings/abstract-control-settings-ui-handler.ts b/src/ui/settings/abstract-control-settings-ui-handler.ts index 8f7de42e4db..ee9e990ee2a 100644 --- a/src/ui/settings/abstract-control-settings-ui-handler.ts +++ b/src/ui/settings/abstract-control-settings-ui-handler.ts @@ -10,6 +10,7 @@ import { ScrollBar } from "#ui/scroll-bar"; import { addTextObject } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; +import { toCamelCase } from "#utils/strings"; import i18next from "i18next"; export interface InputsIcons { @@ -88,12 +89,6 @@ export abstract class AbstractControlSettingsUiHandler extends UiHandler { return settings; } - private camelize(string: string): string { - return string - .replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => (index === 0 ? word.toLowerCase() : word.toUpperCase())) - .replace(/\s+/g, ""); - } - /** * Setup UI elements. */ @@ -210,14 +205,15 @@ export abstract class AbstractControlSettingsUiHandler extends UiHandler { settingFiltered.forEach((setting, s) => { // Convert the setting key from format 'Key_Name' to 'Key name' for display. - const settingName = setting.replace(/_/g, " "); + // TODO: IDK if this can be followed by both an underscore and a space, so leaving it as a regex matching both for now + const i18nKey = toCamelCase(setting.replace(/Alt(_| )/, "")); // Create and add a text object for the setting name to the scene. const isLock = this.settingBlacklisted.includes(this.setting[setting]); const labelStyle = isLock ? TextStyle.SETTINGS_LOCKED : TextStyle.SETTINGS_LABEL; + const isAlt = setting.includes("Alt"); let labelText: string; - const i18nKey = this.camelize(settingName.replace("Alt ", "")); - if (settingName.toLowerCase().includes("alt")) { + if (isAlt) { labelText = `${i18next.t(`settings:${i18nKey}`)}${i18next.t("settings:alt")}`; } else { labelText = i18next.t(`settings:${i18nKey}`); diff --git a/src/ui/settings/settings-keyboard-ui-handler.ts b/src/ui/settings/settings-keyboard-ui-handler.ts index ad4bf47f673..295a71abe36 100644 --- a/src/ui/settings/settings-keyboard-ui-handler.ts +++ b/src/ui/settings/settings-keyboard-ui-handler.ts @@ -15,7 +15,8 @@ import { import { AbstractControlSettingsUiHandler } from "#ui/abstract-control-settings-ui-handler"; import { NavigationManager } from "#ui/navigation-menu"; import { addTextObject } from "#ui/text"; -import { reverseValueToKeySetting, truncateString } from "#utils/common"; +import { truncateString } from "#utils/common"; +import { toPascalSnakeCase } from "#utils/strings"; import i18next from "i18next"; /** @@ -101,7 +102,7 @@ export class SettingsKeyboardUiHandler extends AbstractControlSettingsUiHandler } const cursor = this.cursor + this.scrollCursor; // Calculate the absolute cursor position. const selection = this.settingLabels[cursor].text; - const key = reverseValueToKeySetting(selection); + const key = toPascalSnakeCase(selection); const settingName = SettingKeyboard[key]; const activeConfig = this.getActiveConfig(); const success = deleteBind(this.getActiveConfig(), settingName); diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 82e19d857c5..e8f9b5e1c38 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -69,10 +69,10 @@ import { padInt, randIntRange, rgbHexToRgba, - toReadableString, } from "#utils/common"; import type { StarterPreferences } from "#utils/data"; import { loadStarterPreferences, saveStarterPreferences } from "#utils/data"; +import { toTitleCase } from "#utils/strings"; import { argbFromRgba } from "@material/material-color-utilities"; import i18next from "i18next"; import type { GameObjects } from "phaser"; @@ -3527,7 +3527,7 @@ export class StarterSelectUiHandler extends MessageUiHandler { this.pokemonLuckLabelText.setVisible(this.pokemonLuckText.visible); //Growth translate - let growthReadable = toReadableString(GrowthRate[species.growthRate]); + let growthReadable = toTitleCase(GrowthRate[species.growthRate]); const growthAux = growthReadable.replace(" ", "_"); if (i18next.exists("growth:" + growthAux)) { growthReadable = i18next.t(("growth:" + growthAux) as any); diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index c5c714f0b34..b51bdfdb157 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -35,9 +35,9 @@ import { isNullOrUndefined, padInt, rgbHexToRgba, - toReadableString, } from "#utils/common"; import { getEnumValues } from "#utils/enums"; +import { toTitleCase } from "#utils/strings"; import { argbFromRgba } from "@material/material-color-utilities"; import i18next from "i18next"; @@ -962,8 +962,8 @@ export class SummaryUiHandler extends UiHandler { this.passiveContainer?.descriptionText?.setVisible(false); const closeFragment = getBBCodeFrag("", TextStyle.WINDOW_ALT); - const rawNature = toReadableString(Nature[this.pokemon?.getNature()!]); // TODO: is this bang correct? - const nature = `${getBBCodeFrag(toReadableString(getNatureName(this.pokemon?.getNature()!)), TextStyle.SUMMARY_RED)}${closeFragment}`; // TODO: is this bang correct? + const rawNature = toTitleCase(Nature[this.pokemon?.getNature()!]); // TODO: is this bang correct? + const nature = `${getBBCodeFrag(toTitleCase(getNatureName(this.pokemon?.getNature()!)), TextStyle.SUMMARY_RED)}${closeFragment}`; // TODO: is this bang correct? const memoString = i18next.t("pokemonSummary:memoString", { metFragment: i18next.t( diff --git a/src/utils/common.ts b/src/utils/common.ts index e9ba3acb5e5..66a74ed2c33 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -1,6 +1,5 @@ import { pokerogueApi } from "#api/pokerogue-api"; import { MoneyFormat } from "#enums/money-format"; -import { MoveId } from "#enums/move-id"; import type { Variant } from "#sprites/variant"; import i18next from "i18next"; @@ -10,19 +9,6 @@ export const MissingTextureKey = "__MISSING"; // TODO: Draft tests for these utility functions // TODO: Break up this file -/** - * Convert a `snake_case` string in any capitalization (such as one from an enum reverse mapping) - * into a readable `Title Case` version. - * @param str - The snake case string to be converted. - * @returns The result of converting `str` into title case. - */ -export function toReadableString(str: string): string { - return str - .replace(/_/g, " ") - .split(" ") - .map(s => capitalizeFirstLetter(s.toLowerCase())) - .join(" "); -} export function randomString(length: number, seeded = false) { const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; @@ -278,7 +264,7 @@ export function formatMoney(format: MoneyFormat, amount: number) { } export function formatStat(stat: number, forHp = false): string { - return formatLargeNumber(stat, forHp ? 100000 : 1000000); + return formatLargeNumber(stat, forHp ? 100_000 : 1_000_000); } export function executeIf(condition: boolean, promiseFunc: () => Promise): Promise { @@ -359,31 +345,6 @@ export function fixedInt(value: number): number { return new FixedInt(value) as unknown as number; } -/** - * Formats a string to title case - * @param unformattedText Text to be formatted - * @returns the formatted string - */ -export function formatText(unformattedText: string): string { - const text = unformattedText.split("_"); - for (let i = 0; i < text.length; i++) { - text[i] = text[i].charAt(0).toUpperCase() + text[i].substring(1).toLowerCase(); - } - - return text.join(" "); -} - -export function toCamelCaseString(unformattedText: string): string { - if (!unformattedText) { - return ""; - } - return unformattedText - .split(/[_ ]/) - .filter(f => f) - .map((f, i) => (i ? `${f[0].toUpperCase()}${f.slice(1).toLowerCase()}` : f.toLowerCase())) - .join(""); -} - export function rgbToHsv(r: number, g: number, b: number) { const v = Math.max(r, g, b); const c = v - Math.min(r, g, b); @@ -510,41 +471,6 @@ export function truncateString(str: string, maxLength = 10) { return str; } -/** - * Convert a space-separated string into a capitalized and underscored string. - * @param input - The string to be converted. - * @returns The converted string with words capitalized and separated by underscores. - */ -export function reverseValueToKeySetting(input: string) { - // Split the input string into an array of words - const words = input.split(" "); - // Capitalize the first letter of each word and convert the rest to lowercase - const capitalizedWords = words.map((word: string) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()); - // Join the capitalized words with underscores and return the result - return capitalizedWords.join("_"); -} - -/** - * Capitalize a string. - * @param str - The string to be capitalized. - * @param sep - The separator between the words of the string. - * @param lowerFirstChar - Whether the first character of the string should be lowercase or not. - * @param returnWithSpaces - Whether the returned string should have spaces between the words or not. - * @returns The capitalized string. - */ -export function capitalizeString(str: string, sep: string, lowerFirstChar = true, returnWithSpaces = false) { - if (str) { - const splitedStr = str.toLowerCase().split(sep); - - for (let i = +lowerFirstChar; i < splitedStr?.length; i++) { - splitedStr[i] = splitedStr[i].charAt(0).toUpperCase() + splitedStr[i].substring(1); - } - - return returnWithSpaces ? splitedStr.join(" ") : splitedStr.join(""); - } - return null; -} - /** * Report whether a given value is nullish (`null`/`undefined`). * @param val - The value whose nullishness is being checked @@ -554,15 +480,6 @@ export function isNullOrUndefined(val: any): val is null | undefined { return val === null || val === undefined; } -/** - * Capitalize the first letter of a string. - * @param str - The string whose first letter is being capitalized - * @return The original string with its first letter capitalized - */ -export function capitalizeFirstLetter(str: string) { - return str.charAt(0).toUpperCase() + str.slice(1); -} - /** * This function is used in the context of a Pokémon battle game to calculate the actual integer damage value from a float result. * Many damage calculation formulas involve various parameters and result in float values. @@ -597,26 +514,6 @@ export function isBetween(num: number, min: number, max: number): boolean { return min <= num && num <= max; } -/** - * Helper method to return the animation filename for a given move - * - * @param move the move for which the animation filename is needed - */ -export function animationFileName(move: MoveId): string { - return MoveId[move].toLowerCase().replace(/_/g, "-"); -} - -/** - * Transforms a camelCase string into a kebab-case string - * @param str The camelCase string - * @returns A kebab-case string - * - * @source {@link https://stackoverflow.com/a/67243723/} - */ -export function camelCaseToKebabCase(str: string): string { - return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, (s, o) => (o ? "-" : "") + s.toLowerCase()); -} - /** Get the localized shiny descriptor for the provided variant * @param variant - The variant to get the shiny descriptor for * @returns The localized shiny descriptor diff --git a/src/utils/strings.ts b/src/utils/strings.ts new file mode 100644 index 00000000000..dfa3d7c887f --- /dev/null +++ b/src/utils/strings.ts @@ -0,0 +1,179 @@ +// TODO: Standardize file and path casing to remove the need for all these different casing methods + +// #region Split string code + +// Regexps involved with splitting words in various case formats. +// Sourced from https://www.npmjs.com/package/change-case (with slight tweaking here and there) + +/** Regex to split at word boundaries.*/ +const SPLIT_LOWER_UPPER_RE = /([\p{Ll}\d])(\p{Lu})/gu; +/** Regex to split around single-letter uppercase words.*/ +const SPLIT_UPPER_UPPER_RE = /(\p{Lu})([\p{Lu}][\p{Ll}])/gu; +/** Regexp involved with stripping non-word delimiters from the result. */ +const DELIM_STRIP_REGEXP = /[-_ ]+/giu; +// The replacement value for splits. +const SPLIT_REPLACE_VALUE = "$1\0$2"; + +/** + * Split any cased string into an array of its constituent words. + * @param string - The string to be split + * @returns The new string, delimited at each instance of one or more spaces, underscores, hyphens + * or lower-to-upper boundaries. + * @remarks + * **DO NOT USE THIS FUNCTION!** + * Exported only to allow for testing. + * @todo Consider tests into [in-source testing](https://vitest.dev/guide/in-source.html) and converting this to unexported + */ +export function splitWords(value: string): string[] { + let result = value.trim(); + result = result.replace(SPLIT_LOWER_UPPER_RE, SPLIT_REPLACE_VALUE).replace(SPLIT_UPPER_UPPER_RE, SPLIT_REPLACE_VALUE); + result = result.replace(DELIM_STRIP_REGEXP, "\0"); + + // Trim the delimiter from around the output string + return trimFromStartAndEnd(result, "\0").split(/\0/g); +} + +/** + * Helper function to remove one or more sequences of characters from either end of a string. + * @param str - The string to replace + * @param charToTrim - The string to remove + * @returns The result of removing all instances of {@linkcode charsToTrim} from either end of {@linkcode str}. + */ +function trimFromStartAndEnd(str: string, charToTrim: string): string { + let start = 0; + let end = str.length; + const blockLength = charToTrim.length; + + while (str.startsWith(charToTrim, start)) { + start += blockLength; + } + if (start - end === blockLength) { + // Occurs if the ENTIRE string is made up of charToTrim (at which point we return nothing) + return ""; + } + while (str.endsWith(charToTrim, end)) { + end -= blockLength; + } + return str.slice(start, end); +} + +// #endregion Split String code + +/** + * Capitalize the first letter of a string. + * @param str - The string whose first letter is to be capitalized + * @return The original string with its first letter capitalized. + * @example + * ```ts + * console.log(capitalizeFirstLetter("consectetur adipiscing elit")); // returns "Consectetur adipiscing elit" + * ``` + */ +export function capitalizeFirstLetter(str: string) { + return str.charAt(0).toUpperCase() + str.slice(1); +} + +/** + * Helper method to convert a string into `Title Case` (such as one used for console logs). + * @param str - The string being converted + * @returns The result of converting `str` into title case. + * @example + * ```ts + * console.log(toTitleCase("lorem ipsum dolor sit amet")); // returns "Lorem Ipsum Dolor Sit Amet" + * ``` + */ +export function toTitleCase(str: string): string { + return splitWords(str) + .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) + .join(" "); +} + +/** + * Helper method to convert a string into `camelCase` (such as one used for i18n keys). + * @param str - The string being converted + * @returns The result of converting `str` into camel case. + * @example + * ```ts + * console.log(toCamelCase("BIG_ANGRY_TRAINER")); // returns "bigAngryTrainer" + * ``` + */ +export function toCamelCase(str: string) { + return splitWords(str) + .map((word, index) => (index === 0 ? word.toLowerCase() : capitalizeFirstLetter(word))) + .join(""); +} + +/** + * Helper method to convert a string into `PascalCase`. + * @param str - The string being converted + * @returns The result of converting `str` into pascal case. + * @example + * ```ts + * console.log(toPascalCase("hi how was your day")); // returns "HiHowWasYourDay" + * ``` + * @remarks + */ +export function toPascalCase(str: string) { + return splitWords(str) + .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) + .join(""); +} + +/** + * Helper method to convert a string into `kebab-case` (such as one used for filenames). + * @param str - The string being converted + * @returns The result of converting `str` into kebab case. + * @example + * ```ts + * console.log(toKebabCase("not_kebab-caSe String")); // returns "not-kebab-case-string" + * ``` + */ +export function toKebabCase(str: string): string { + return splitWords(str) + .map(word => word.toLowerCase()) + .join("-"); +} + +/** + * Helper method to convert a string into `snake_case` (such as one used for filenames). + * @param str - The string being converted + * @returns The result of converting `str` into snake case. + * @example + * ```ts + * console.log(toSnakeCase("not-in snake_CaSe")); // returns "not_in_snake_case" + * ``` + */ +export function toSnakeCase(str: string) { + return splitWords(str) + .map(word => word.toLowerCase()) + .join("_"); +} + +/** + * Helper method to convert a string into `UPPER_SNAKE_CASE`. + * @param str - The string being converted + * @returns The result of converting `str` into upper snake case. + * @example + * ```ts + * console.log(toUpperSnakeCase("apples bananas_oranGes-PearS")); // returns "APPLES_BANANAS_ORANGES_PEARS" + * ``` + */ +export function toUpperSnakeCase(str: string) { + return splitWords(str) + .map(word => word.toUpperCase()) + .join("_"); +} + +/** + * Helper method to convert a string into `Pascal_Snake_Case`. + * @param str - The string being converted + * @returns The result of converting `str` into pascal snake case. + * @example + * ```ts + * console.log(toPascalSnakeCase("apples-bananas_oranGes Pears")); // returns "Apples_Bananas_Oranges_Pears" + * ``` + */ +export function toPascalSnakeCase(str: string) { + return splitWords(str) + .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) + .join("_"); +} diff --git a/test/setting-menu/helpers/in-game-manip.ts b/test/setting-menu/helpers/in-game-manip.ts index acc119b2cc2..2f4350bab5c 100644 --- a/test/setting-menu/helpers/in-game-manip.ts +++ b/test/setting-menu/helpers/in-game-manip.ts @@ -1,5 +1,6 @@ import { getIconForLatestInput, getSettingNameWithKeycode } from "#inputs/config-handler"; import { SettingKeyboard } from "#system/settings-keyboard"; +import { toPascalSnakeCase } from "#utils/strings"; import { expect } from "vitest"; export class InGameManip { @@ -56,22 +57,11 @@ export class InGameManip { return this; } - normalizeSettingNameString(input) { - // Convert the input string to lower case - const lowerCasedInput = input.toLowerCase(); - - // Replace underscores with spaces, capitalize the first letter of each word, and join them back with underscores - const words = lowerCasedInput.split("_").map(word => word.charAt(0).toUpperCase() + word.slice(1)); - const result = words.join("_"); - - return result; - } - weShouldTriggerTheButton(settingName) { if (!settingName.includes("Button_")) { settingName = "Button_" + settingName; } - this.settingName = SettingKeyboard[this.normalizeSettingNameString(settingName)]; + this.settingName = SettingKeyboard[toPascalSnakeCase(settingName)]; expect(getSettingNameWithKeycode(this.config, this.keycode)).toEqual(this.settingName); return this; } diff --git a/test/setting-menu/helpers/menu-manip.ts b/test/setting-menu/helpers/menu-manip.ts index 29e096608f1..276fef2f973 100644 --- a/test/setting-menu/helpers/menu-manip.ts +++ b/test/setting-menu/helpers/menu-manip.ts @@ -29,6 +29,7 @@ export class MenuManip { this.specialCaseIcon = null; } + // TODO: Review this convertNameToButtonString(input) { // Check if the input starts with "Alt_Button" if (input.startsWith("Alt_Button")) { diff --git a/test/test-utils/helpers/move-helper.ts b/test/test-utils/helpers/move-helper.ts index 4fa14b573ab..15605edf31d 100644 --- a/test/test-utils/helpers/move-helper.ts +++ b/test/test-utils/helpers/move-helper.ts @@ -12,7 +12,8 @@ import type { CommandPhase } from "#phases/command-phase"; import type { EnemyCommandPhase } from "#phases/enemy-command-phase"; import { MoveEffectPhase } from "#phases/move-effect-phase"; import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"; -import { coerceArray, toReadableString } from "#utils/common"; +import { coerceArray } from "#utils/common"; +import { toTitleCase } from "#utils/strings"; import type { MockInstance } from "vitest"; import { expect, vi } from "vitest"; @@ -66,12 +67,12 @@ export class MoveHelper extends GameManagerHelper { const movePosition = this.getMovePosition(pkmIndex, move); if (movePosition === -1) { expect.fail( - `MoveHelper.select called with move '${toReadableString(MoveId[move])}' not in moveset!` + - `\nBattler Index: ${toReadableString(BattlerIndex[pkmIndex])}` + + `MoveHelper.select called with move '${toTitleCase(MoveId[move])}' not in moveset!` + + `\nBattler Index: ${toTitleCase(BattlerIndex[pkmIndex])}` + `\nMoveset: [${this.game.scene .getPlayerParty() [pkmIndex].getMoveset() - .map(pm => toReadableString(MoveId[pm.moveId])) + .map(pm => toTitleCase(MoveId[pm.moveId])) .join(", ")}]`, ); } @@ -110,12 +111,12 @@ export class MoveHelper extends GameManagerHelper { const movePosition = this.getMovePosition(pkmIndex, move); if (movePosition === -1) { expect.fail( - `MoveHelper.selectWithTera called with move '${toReadableString(MoveId[move])}' not in moveset!` + - `\nBattler Index: ${toReadableString(BattlerIndex[pkmIndex])}` + + `MoveHelper.selectWithTera called with move '${toTitleCase(MoveId[move])}' not in moveset!` + + `\nBattler Index: ${toTitleCase(BattlerIndex[pkmIndex])}` + `\nMoveset: [${this.game.scene .getPlayerParty() [pkmIndex].getMoveset() - .map(pm => toReadableString(MoveId[pm.moveId])) + .map(pm => toTitleCase(MoveId[pm.moveId])) .join(", ")}]`, ); } diff --git a/test/utils/strings.test.ts b/test/utils/strings.test.ts new file mode 100644 index 00000000000..3d6eb235ba8 --- /dev/null +++ b/test/utils/strings.test.ts @@ -0,0 +1,47 @@ +import { splitWords } from "#utils/strings"; +import { describe, expect, it } from "vitest"; + +interface testCase { + input: string; + words: string[]; +} + +const testCases: testCase[] = [ + { + input: "Lorem ipsum dolor sit amet", + words: ["Lorem", "ipsum", "dolor", "sit", "amet"], + }, + { + input: "consectetur-adipiscing-elit", + words: ["consectetur", "adipiscing", "elit"], + }, + { + input: "sed_do_eiusmod_tempor_incididunt_ut_labore", + words: ["sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore"], + }, + { + input: "Et Dolore Magna Aliqua", + words: ["Et", "Dolore", "Magna", "Aliqua"], + }, + { + input: "BIG_ANGRY_TRAINER", + words: ["BIG", "ANGRY", "TRAINER"], + }, + { + input: "ApplesBananasOrangesAndAPear", + words: ["Apples", "Bananas", "Oranges", "And", "A", "Pear"], + }, + { + input: "mysteryEncounters/anOfferYouCantRefuse", + words: ["mystery", "Encounters/an", "Offer", "You", "Cant", "Refuse"], + }, +]; + +describe("Utils - Casing -", () => { + describe("splitWords", () => { + it.each(testCases)("should split a string into its constituent words - $input", ({ input, words }) => { + const ret = splitWords(input); + expect(ret).toEqual(words); + }); + }); +}); From c0e755c3c3344a0d9f703cf6b78b5e267d4d8e95 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sun, 27 Jul 2025 19:01:44 -0600 Subject: [PATCH 24/76] [Refactor] Prevent serialization of full species in pokemon summon data https://github.com/pagefaultgames/pokerogue/pull/6145 * Prevent serialization of entire species form in pokemon summon data * Apply suggestions from code review Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Apply Kev's suggestions from code review Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --------- Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/@types/type-helpers.ts | 11 +++ src/data/pokemon/pokemon-data.ts | 132 ++++++++++++++++++++++++++++++- 2 files changed, 141 insertions(+), 2 deletions(-) diff --git a/src/@types/type-helpers.ts b/src/@types/type-helpers.ts index 3a5c88e3f15..b3e5b1cfc07 100644 --- a/src/@types/type-helpers.ts +++ b/src/@types/type-helpers.ts @@ -75,3 +75,14 @@ export type NonFunctionPropertiesRecursive = { }; export type AbstractConstructor = abstract new (...args: any[]) => T; + +/** + * Type helper that iterates through the fields of the type and coerces any `null` properties to `undefined` (including in union types). + * + * @remarks + * This is primarily useful when an object with nullable properties wants to be serialized and have its `null` + * properties coerced to `undefined`. + */ +export type CoerceNullPropertiesToUndefined = { + [K in keyof T]: null extends T[K] ? Exclude | undefined : T[K]; +}; diff --git a/src/data/pokemon/pokemon-data.ts b/src/data/pokemon/pokemon-data.ts index 6ae86bed5e7..a2a0138a17a 100644 --- a/src/data/pokemon/pokemon-data.ts +++ b/src/data/pokemon/pokemon-data.ts @@ -1,18 +1,29 @@ import { type BattlerTag, loadBattlerTag } from "#data/battler-tags"; +import { allSpecies } from "#data/data-lists"; import type { Gender } from "#data/gender"; import { PokemonMove } from "#data/moves/pokemon-move"; -import type { PokemonSpeciesForm } from "#data/pokemon-species"; +import { getPokemonSpeciesForm, type PokemonSpeciesForm } from "#data/pokemon-species"; import type { TypeDamageMultiplier } from "#data/type"; import type { AbilityId } from "#enums/ability-id"; import type { BerryType } from "#enums/berry-type"; import type { MoveId } from "#enums/move-id"; import type { Nature } from "#enums/nature"; import type { PokemonType } from "#enums/pokemon-type"; +import type { SpeciesId } from "#enums/species-id"; import type { AttackMoveResult } from "#types/attack-move-result"; import type { IllusionData } from "#types/illusion-data"; import type { TurnMove } from "#types/turn-move"; +import type { CoerceNullPropertiesToUndefined } from "#types/type-helpers"; import { isNullOrUndefined } from "#utils/common"; +/** + * The type that {@linkcode PokemonSpeciesForm} is converted to when an object containing it serializes it. + */ +type SerializedSpeciesForm = { + id: SpeciesId; + formIdx: number; +}; + /** * Permanent data that can customize a Pokemon in non-standard ways from its Species. * Includes abilities, nature, changed types, etc. @@ -41,9 +52,59 @@ export class CustomPokemonData { } } +/** + * Deserialize a pokemon species form from an object containing `id` and `formIdx` properties. + * @param value - The value to deserialize + * @returns The `PokemonSpeciesForm` or `null` if the fields could not be properly discerned + */ +function deserializePokemonSpeciesForm(value: SerializedSpeciesForm | PokemonSpeciesForm): PokemonSpeciesForm | null { + // @ts-expect-error: We may be deserializing a PokemonSpeciesForm, but we catch later on + let { id, formIdx } = value; + + if (isNullOrUndefined(id) || isNullOrUndefined(formIdx)) { + // @ts-expect-error: Typescript doesn't know that in block, `value` must be a PokemonSpeciesForm + id = value.speciesId; + // @ts-expect-error: Same as above (plus we are accessing a protected property) + formIdx = value._formIndex; + } + // If for some reason either of these fields are null/undefined, we cannot reconstruct the species form + if (isNullOrUndefined(id) || isNullOrUndefined(formIdx)) { + return null; + } + return getPokemonSpeciesForm(id, formIdx); +} + +interface SerializedIllusionData extends Omit { + /** The id of the illusioned fusion species, or `undefined` if not a fusion */ + fusionSpecies?: SpeciesId; +} + +interface SerializedPokemonSummonData { + statStages: number[]; + moveQueue: TurnMove[]; + tags: BattlerTag[]; + abilitySuppressed: boolean; + speciesForm?: SerializedSpeciesForm; + fusionSpeciesForm?: SerializedSpeciesForm; + ability?: AbilityId; + passiveAbility?: AbilityId; + gender?: Gender; + fusionGender?: Gender; + stats: number[]; + moveset?: PokemonMove[]; + types: PokemonType[]; + addedType?: PokemonType; + illusion?: SerializedIllusionData; + illusionBroken: boolean; + berriesEatenLast: BerryType[]; + moveHistory: TurnMove[]; +} + /** * Persistent in-battle data for a {@linkcode Pokemon}. * Resets on switch or new battle. + * + * @sealed */ export class PokemonSummonData { /** [Atk, Def, SpAtk, SpDef, Spd, Acc, Eva] */ @@ -86,7 +147,7 @@ export class PokemonSummonData { */ public moveHistory: TurnMove[] = []; - constructor(source?: PokemonSummonData | Partial) { + constructor(source?: PokemonSummonData | SerializedPokemonSummonData) { if (isNullOrUndefined(source)) { return; } @@ -97,6 +158,30 @@ export class PokemonSummonData { continue; } + if (key === "speciesForm" || key === "fusionSpeciesForm") { + this[key] = deserializePokemonSpeciesForm(value); + } + + if (key === "illusion" && typeof value === "object") { + // Make a copy so as not to mutate provided value + const illusionData = { + ...value, + }; + if (!isNullOrUndefined(illusionData.fusionSpecies)) { + switch (typeof illusionData.fusionSpecies) { + case "object": + illusionData.fusionSpecies = allSpecies[illusionData.fusionSpecies.speciesId]; + break; + case "number": + illusionData.fusionSpecies = allSpecies[illusionData.fusionSpecies]; + break; + default: + illusionData.fusionSpecies = undefined; + } + } + this[key] = illusionData as IllusionData; + } + if (key === "moveset") { this.moveset = value?.map((m: any) => PokemonMove.loadMove(m)); continue; @@ -110,6 +195,49 @@ export class PokemonSummonData { this[key] = value; } } + + /** + * Serialize this PokemonSummonData to JSON, converting {@linkcode PokemonSpeciesForm} and {@linkcode IllusionData.fusionSpecies} + * into simpler types instead of serializing all of their fields. + * + * @remarks + * - `IllusionData.fusionSpecies` is serialized as just the species ID + * - `PokemonSpeciesForm` and `PokemonSpeciesForm.fusionSpeciesForm` are converted into {@linkcode SerializedSpeciesForm} objects + */ + public toJSON(): SerializedPokemonSummonData { + // Pokemon species forms are never saved, only the species ID. + const illusion = this.illusion; + const speciesForm = this.speciesForm; + const fusionSpeciesForm = this.fusionSpeciesForm; + const illusionSpeciesForm = illusion?.fusionSpecies; + const t = { + // the "as omit" is required to avoid TS resolving the overwritten properties to "never" + // We coerce null to undefined in the type, as the for loop below replaces `null` with `undefined` + ...(this as Omit< + CoerceNullPropertiesToUndefined, + "speciesForm" | "fusionSpeciesForm" | "illusion" + >), + speciesForm: isNullOrUndefined(speciesForm) + ? undefined + : { id: speciesForm.speciesId, formIdx: speciesForm.formIndex }, + fusionSpeciesForm: isNullOrUndefined(fusionSpeciesForm) + ? undefined + : { id: fusionSpeciesForm.speciesId, formIdx: fusionSpeciesForm.formIndex }, + illusion: isNullOrUndefined(illusion) + ? undefined + : { + ...(this.illusion as Omit), + fusionSpecies: illusionSpeciesForm?.speciesId, + }, + }; + // Replace `null` with `undefined`, as `undefined` never gets serialized + for (const [key, value] of Object.entries(t)) { + if (value === null) { + t[key] = undefined; + } + } + return t; + } } // TODO: Merge this inside `summmonData` but exclude from save if/when a save data serializer is added From 343407832962d4e8c007663fb82d429f48392eda Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Sun, 27 Jul 2025 18:03:34 -0700 Subject: [PATCH 25/76] [Docs] Add `@module` modifier tag to `tsdoc.json` --- tsdoc.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tsdoc.json b/tsdoc.json index b4cbc9a62a5..689f7a96c5c 100644 --- a/tsdoc.json +++ b/tsdoc.json @@ -9,6 +9,10 @@ { "tagName": "@linkcode", "syntaxKind": "inline" + }, + { + "tagName": "@module", + "syntaxKind": "modifier" } ] } From 157b662f9ed719f8ef35ab13792ae7ec448f1e5c Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Sun, 27 Jul 2025 23:17:46 -0400 Subject: [PATCH 26/76] [Bug] Fix camel case bug in `strings.ts` (#6161) --- src/utils/strings.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils/strings.ts b/src/utils/strings.ts index dfa3d7c887f..bf5e5c6473f 100644 --- a/src/utils/strings.ts +++ b/src/utils/strings.ts @@ -98,7 +98,9 @@ export function toTitleCase(str: string): string { */ export function toCamelCase(str: string) { return splitWords(str) - .map((word, index) => (index === 0 ? word.toLowerCase() : capitalizeFirstLetter(word))) + .map((word, index) => + index === 0 ? word.toLowerCase() : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(), + ) .join(""); } From 462b423cb8e903d150bd1d665254a97af9843b61 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Sun, 27 Jul 2025 21:20:02 -0700 Subject: [PATCH 27/76] [Dev] Change `target` to `ES2023` in `tsconfig.json` (#6160) --- src/field/pokemon.ts | 5 ++--- src/field/trainer.ts | 1 - src/modifier/modifier.ts | 20 ++++++++++---------- tsconfig.json | 8 ++++---- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 32229d80f37..fd04c007e1b 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -213,7 +213,6 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { * TODO: Stop treating this like a unique ID and stop treating 0 as no pokemon */ public id: number; - public name: string; public nickname: string; public species: PokemonSpecies; public formIndex: number; @@ -5664,7 +5663,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { } export class PlayerPokemon extends Pokemon { - protected battleInfo: PlayerBattleInfo; + protected declare battleInfo: PlayerBattleInfo; public compatibleTms: MoveId[]; constructor( @@ -6193,7 +6192,7 @@ export class PlayerPokemon extends Pokemon { } export class EnemyPokemon extends Pokemon { - protected battleInfo: EnemyBattleInfo; + protected declare battleInfo: EnemyBattleInfo; public trainerSlot: TrainerSlot; public aiType: AiType; public bossSegments: number; diff --git a/src/field/trainer.ts b/src/field/trainer.ts index a8af298e1cf..584c9310932 100644 --- a/src/field/trainer.ts +++ b/src/field/trainer.ts @@ -30,7 +30,6 @@ export class Trainer extends Phaser.GameObjects.Container { public config: TrainerConfig; public variant: TrainerVariant; public partyTemplateIndex: number; - public name: string; public partnerName: string; public nameKey: string; public partnerNameKey: string | undefined; diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index f6a9ed48847..b31bee7fc69 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -462,7 +462,7 @@ export abstract class LapsingPersistentModifier extends PersistentModifier { * @see {@linkcode apply} */ export class DoubleBattleChanceBoosterModifier extends LapsingPersistentModifier { - public override type: DoubleBattleChanceBoosterModifierType; + public declare type: DoubleBattleChanceBoosterModifierType; match(modifier: Modifier): boolean { return modifier instanceof DoubleBattleChanceBoosterModifier && modifier.getMaxBattles() === this.getMaxBattles(); @@ -936,7 +936,7 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier { * Currently used by Shuckle Juice item */ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { - public override type: PokemonBaseStatTotalModifierType; + public declare type: PokemonBaseStatTotalModifierType; public isTransferable = false; public statModifier: 10 | -15; @@ -2074,7 +2074,7 @@ export abstract class ConsumablePokemonModifier extends ConsumableModifier { } export class TerrastalizeModifier extends ConsumablePokemonModifier { - public override type: TerastallizeModifierType; + public declare type: TerastallizeModifierType; public teraType: PokemonType; constructor(type: TerastallizeModifierType, pokemonId: number, teraType: PokemonType) { @@ -2318,7 +2318,7 @@ export class PokemonLevelIncrementModifier extends ConsumablePokemonModifier { } export class TmModifier extends ConsumablePokemonModifier { - public override type: TmModifierType; + public declare type: TmModifierType; /** * Applies {@linkcode TmModifier} @@ -2365,7 +2365,7 @@ export class RememberMoveModifier extends ConsumablePokemonModifier { } export class EvolutionItemModifier extends ConsumablePokemonModifier { - public override type: EvolutionItemModifierType; + public declare type: EvolutionItemModifierType; /** * Applies {@linkcode EvolutionItemModifier} * @param playerPokemon The {@linkcode PlayerPokemon} that should evolve via item @@ -2530,7 +2530,7 @@ export class ExpBoosterModifier extends PersistentModifier { } export class PokemonExpBoosterModifier extends PokemonHeldItemModifier { - public override type: PokemonExpBoosterModifierType; + public declare type: PokemonExpBoosterModifierType; private boostMultiplier: number; @@ -2627,7 +2627,7 @@ export class ExpBalanceModifier extends PersistentModifier { } export class PokemonFriendshipBoosterModifier extends PokemonHeldItemModifier { - public override type: PokemonFriendshipBoosterModifierType; + public declare type: PokemonFriendshipBoosterModifierType; matchType(modifier: Modifier): boolean { return modifier instanceof PokemonFriendshipBoosterModifier; @@ -2684,7 +2684,7 @@ export class PokemonNatureWeightModifier extends PokemonHeldItemModifier { } export class PokemonMoveAccuracyBoosterModifier extends PokemonHeldItemModifier { - public override type: PokemonMoveAccuracyBoosterModifierType; + public declare type: PokemonMoveAccuracyBoosterModifierType; private accuracyAmount: number; constructor(type: PokemonMoveAccuracyBoosterModifierType, pokemonId: number, accuracy: number, stackCount?: number) { @@ -2736,7 +2736,7 @@ export class PokemonMoveAccuracyBoosterModifier extends PokemonHeldItemModifier } export class PokemonMultiHitModifier extends PokemonHeldItemModifier { - public override type: PokemonMultiHitModifierType; + public declare type: PokemonMultiHitModifierType; matchType(modifier: Modifier): boolean { return modifier instanceof PokemonMultiHitModifier; @@ -2817,7 +2817,7 @@ export class PokemonMultiHitModifier extends PokemonHeldItemModifier { } export class PokemonFormChangeItemModifier extends PokemonHeldItemModifier { - public override type: FormChangeItemModifierType; + public declare type: FormChangeItemModifierType; public formChangeItem: FormChangeItem; public active: boolean; public isTransferable = false; diff --git a/tsconfig.json b/tsconfig.json index 1e067dcff03..9aa06829789 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,11 +1,11 @@ { "compilerOptions": { - "target": "ES2020", - "module": "ES2020", + "target": "ES2023", + "module": "ES2022", // Modifying this option requires all values to be set manually because the defaults get overridden - // Values other than "ES2024.Promise" taken from https://github.com/microsoft/TypeScript/blob/main/src/lib/es2020.full.d.ts + // Values other than "ES2024.Promise" taken from https://github.com/microsoft/TypeScript/blob/main/src/lib/es2023.full.d.ts "lib": [ - "ES2020", + "ES2023", "ES2024.Promise", "DOM", "DOM.AsyncIterable", From 0935d817e9ab9261a7a736be249e7d5f168ec4e8 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sun, 25 May 2025 17:26:37 -0500 Subject: [PATCH 28/76] breakup fight and ball commands into their own methods --- src/phases/command-phase.ts | 418 +++++++++++++++++++----------------- 1 file changed, 222 insertions(+), 196 deletions(-) diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index 14674037fbe..92c01aa4b85 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -148,206 +148,232 @@ export class CommandPhase extends FieldPhase { } /** - * TODO: Remove `args` and clean this thing up - * Code will need to be copied over from pkty except replacing the `virtual` and `ignorePP` args with a corresponding `MoveUseMode`. + * + * @param user - The pokemon using the move + * @param cursor - */ - handleCommand(command: Command, cursor: number, ...args: any[]): boolean { + private queueFightErrorMessage(user: PlayerPokemon, cursor: number) { + const move = user.getMoveset()[cursor]; + globalScene.ui.setMode(UiMode.MESSAGE); + + // Decides between a Disabled, Not Implemented, or No PP translation message + const errorMessage = user.isMoveRestricted(move.moveId, user) + ? user.getRestrictingTag(move.moveId, user)!.selectionDeniedText(user, move.moveId) + : move.getName().endsWith(" (N)") + ? "battle:moveNotImplemented" + : "battle:moveNoPP"; + const moveName = move.getName().replace(" (N)", ""); // Trims off the indicator + + globalScene.ui.showText( + i18next.t(errorMessage, { moveName: moveName }), + null, + () => { + globalScene.ui.clearText(); + globalScene.ui.setMode(UiMode.FIGHT, this.fieldIndex); + }, + null, + true, + ); + } + + /** Helper method for {@linkcode handleFightCommand} that returns the moveID for the phase + * based on the move passed in or the cursor. + * + * Does not check if the move is usable or not, that should be handled by the caller. + */ + private comptueMoveId(playerPokemon: PlayerPokemon, cursor: number, move?: TurnMove): MoveId { + return move?.move ?? (cursor > -1 ? playerPokemon.getMoveset()[cursor]?.moveId : MoveId.NONE); + } + + /** + * Handle fight logic + * @param command - The command to handle (FIGHT or TERA) + * @param cursor - The index that the cursor is placed on, or -1 if no move can be selected. + * @param args - Any additional arguments to pass to the command + */ + private handleFightCommand( + command: Command.FIGHT | Command.TERA, + cursor: number, + useMode: MoveUseMode = MoveUseMode.NORMAL, + move?: TurnMove, + ): boolean { + const playerPokemon = globalScene.getPlayerField()[this.fieldIndex]; + const ignorePP = isIgnorePP(useMode); + + /** Whether or not to display an error message instead of attempting to initiate the command selection process */ + let canUse = cursor !== -1 || !playerPokemon.trySelectMove(cursor, ignorePP); + + const useStruggle = canUse + ? false + : cursor > -1 && !playerPokemon.getMoveset().some(m => m.isUsable(playerPokemon)); + + canUse = canUse || useStruggle; + + if (!canUse) { + this.queueFightErrorMessage(playerPokemon, cursor); + return false; + } + + const moveId = useStruggle ? MoveId.STRUGGLE : this.comptueMoveId(playerPokemon, cursor, move); + + const turnCommand: TurnCommand = { + command: Command.FIGHT, + cursor: cursor, + move: { move: moveId, targets: [], useMode }, + args: [useMode, move], + }; + const preTurnCommand: TurnCommand = { + command: command, + targets: [this.fieldIndex], + skip: command === Command.FIGHT, + }; + + const moveTargets: MoveTargetSet = + move === undefined + ? getMoveTargets(playerPokemon, moveId) + : { + targets: move.targets, + multiple: move.targets.length > 1, + }; + + if (!moveId) { + turnCommand.targets = [this.fieldIndex]; + } + + console.log(moveTargets, getPokemonNameWithAffix(playerPokemon)); + + if (moveTargets.multiple) { + globalScene.phaseManager.unshiftNew("SelectTargetPhase", this.fieldIndex); + } + + if (turnCommand.move && (moveTargets.targets.length <= 1 || moveTargets.multiple)) { + turnCommand.move.targets = moveTargets.targets; + } else if ( + turnCommand.move && + playerPokemon.getTag(BattlerTagType.CHARGING) && + playerPokemon.getMoveQueue().length >= 1 + ) { + turnCommand.move.targets = playerPokemon.getMoveQueue()[0].targets; + } else { + globalScene.phaseManager.unshiftNew("SelectTargetPhase", this.fieldIndex); + } + + globalScene.currentBattle.preTurnCommands[this.fieldIndex] = preTurnCommand; + globalScene.currentBattle.turnCommands[this.fieldIndex] = turnCommand; + + return true; + } + + private queueShowText(key: string) { + globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); + globalScene.ui.setMode(UiMode.MESSAGE); + + globalScene.ui.showText( + i18next.t(key), + null, + () => { + globalScene.ui.showText("", 0); + globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); + }, + null, + true, + ); + } + + /** + * Helper method for {@linkcode handleBallCommand} that checks if the pokeball can be thrown. + * + * The pokeball may not be thrown if: + * - It is a trainer battle + * - The biome is {@linkcode Biome.END} and it is not classic mode + * - The biome is {@linkcode Biome.END} and the fresh start challenge is active + * - The biome is {@linkcode Biome.END} and the player has not either caught the target before or caught all but one starter + * - The player is in a mystery encounter that disallows catching the pokemon + * @returns Whether a pokeball can be thrown + * + */ + private checkCanUseBall(): boolean { + if ( + globalScene.arena.biomeType === BiomeId.END && + (!globalScene.gameMode.isClassic || + globalScene.gameMode.isFreshStartChallenge() || + (globalScene + .getEnemyField() + .some(p => p.isActive() && !globalScene.gameData.dexData[p.species.speciesId].caughtAttr) && + globalScene.gameData.getStarterCount(d => !!d.caughtAttr) < Object.keys(speciesStarterCosts).length - 1)) + ) { + this.queueShowText("battle:noPokeballForce"); + } else if (globalScene.currentBattle.battleType === BattleType.TRAINER) { + this.queueShowText("battle:noPokeballTrainer"); + } else if ( + globalScene.currentBattle.isBattleMysteryEncounter() && + !globalScene.currentBattle.mysteryEncounter!.catchAllowed + ) { + this.queueShowText("battle:noPokeballMysteryEncounter"); + } else { + return true; + } + + return false; + } + + /** + * Helper method for {@linkcode handleCommand} that handles the logic when the selected command is to use a pokeball. + * + * @param cursor - The index of the pokeball to use + * @returns Whether the command was successfully initiated + */ + handleBallCommand(cursor: number): boolean { + const targets = globalScene + .getEnemyField() + .filter(p => p.isActive(true)) + .map(p => p.getBattlerIndex()); + if (targets.length > 1) { + this.queueShowText("battle:noPokeballMulti"); + return false; + } + + if (!this.checkCanUseBall()) { + return false; + } + + if (cursor < 5) { + const targetPokemon = globalScene.getEnemyPokemon(); + if ( + targetPokemon?.isBoss() && + targetPokemon?.bossSegmentIndex >= 1 && + // TODO: Decouple this hardcoded exception for wonder guard and just check the target... + !targetPokemon?.hasAbility(AbilityId.WONDER_GUARD, false, true) && + cursor < PokeballType.MASTER_BALL + ) { + this.queueShowText("battle:noPokeballStrong"); + return false; + } + + globalScene.currentBattle.turnCommands[this.fieldIndex] = { + command: Command.BALL, + cursor: cursor, + }; + globalScene.currentBattle.turnCommands[this.fieldIndex]!.targets = targets; + if (this.fieldIndex) { + globalScene.currentBattle.turnCommands[this.fieldIndex - 1]!.skip = true; + } + return true; + } + + return false; + } + + handleCommand(command: Command, cursor: number, useMode: MoveUseMode = MoveUseMode.NORMAL, move?: TurnMove): boolean { const playerPokemon = globalScene.getPlayerField()[this.fieldIndex]; let success = false; switch (command) { - // TODO: We don't need 2 args for this - moveUseMode is carried over from queuedMove case Command.TERA: - case Command.FIGHT: { - let useStruggle = false; - const turnMove: TurnMove | undefined = args.length === 2 ? (args[1] as TurnMove) : undefined; - if ( - cursor === -1 || - playerPokemon.trySelectMove(cursor, isIgnorePP(args[0] as MoveUseMode)) || - (useStruggle = cursor > -1 && !playerPokemon.getMoveset().filter(m => m.isUsable(playerPokemon)).length) - ) { - let moveId: MoveId; - if (useStruggle) { - moveId = MoveId.STRUGGLE; - } else if (turnMove !== undefined) { - moveId = turnMove.move; - } else if (cursor > -1) { - moveId = playerPokemon.getMoveset()[cursor].moveId; - } else { - moveId = MoveId.NONE; - } - - const turnCommand: TurnCommand = { - command: Command.FIGHT, - cursor: cursor, - move: { move: moveId, targets: [], useMode: args[0] }, - args: args, - }; - const preTurnCommand: TurnCommand = { - command: command, - targets: [this.fieldIndex], - skip: command === Command.FIGHT, - }; - const moveTargets: MoveTargetSet = - turnMove === undefined - ? getMoveTargets(playerPokemon, moveId) - : { - targets: turnMove.targets, - multiple: turnMove.targets.length > 1, - }; - if (!moveId) { - turnCommand.targets = [this.fieldIndex]; - } - console.log(moveTargets, getPokemonNameWithAffix(playerPokemon)); - if (moveTargets.targets.length > 1 && moveTargets.multiple) { - globalScene.phaseManager.unshiftNew("SelectTargetPhase", this.fieldIndex); - } - if (turnCommand.move && (moveTargets.targets.length <= 1 || moveTargets.multiple)) { - turnCommand.move.targets = moveTargets.targets; - } else if ( - turnCommand.move && - playerPokemon.getTag(BattlerTagType.CHARGING) && - playerPokemon.getMoveQueue().length >= 1 - ) { - turnCommand.move.targets = playerPokemon.getMoveQueue()[0].targets; - } else { - globalScene.phaseManager.unshiftNew("SelectTargetPhase", this.fieldIndex); - } - globalScene.currentBattle.preTurnCommands[this.fieldIndex] = preTurnCommand; - globalScene.currentBattle.turnCommands[this.fieldIndex] = turnCommand; - success = true; - } else if (cursor < playerPokemon.getMoveset().length) { - const move = playerPokemon.getMoveset()[cursor]; - globalScene.ui.setMode(UiMode.MESSAGE); - - // Decides between a Disabled, Not Implemented, or No PP translation message - const errorMessage = playerPokemon.isMoveRestricted(move.moveId, playerPokemon) - ? playerPokemon - .getRestrictingTag(move.moveId, playerPokemon)! - .selectionDeniedText(playerPokemon, move.moveId) - : move.getName().endsWith(" (N)") - ? "battle:moveNotImplemented" - : "battle:moveNoPP"; - const moveName = move.getName().replace(" (N)", ""); // Trims off the indicator - - globalScene.ui.showText( - i18next.t(errorMessage, { moveName: moveName }), - null, - () => { - globalScene.ui.clearText(); - globalScene.ui.setMode(UiMode.FIGHT, this.fieldIndex); - }, - null, - true, - ); - } - break; - } - case Command.BALL: { - const notInDex = - globalScene - .getEnemyField() - .filter(p => p.isActive(true)) - .some(p => !globalScene.gameData.dexData[p.species.speciesId].caughtAttr) && - globalScene.gameData.getStarterCount(d => !!d.caughtAttr) < Object.keys(speciesStarterCosts).length - 1; - if ( - globalScene.arena.biomeType === BiomeId.END && - (!globalScene.gameMode.isClassic || globalScene.gameMode.isFreshStartChallenge() || notInDex) - ) { - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - globalScene.ui.setMode(UiMode.MESSAGE); - globalScene.ui.showText( - i18next.t("battle:noPokeballForce"), - null, - () => { - globalScene.ui.showText("", 0); - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - }, - null, - true, - ); - } else if (globalScene.currentBattle.battleType === BattleType.TRAINER) { - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - globalScene.ui.setMode(UiMode.MESSAGE); - globalScene.ui.showText( - i18next.t("battle:noPokeballTrainer"), - null, - () => { - globalScene.ui.showText("", 0); - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - }, - null, - true, - ); - } else if ( - globalScene.currentBattle.isBattleMysteryEncounter() && - !globalScene.currentBattle.mysteryEncounter!.catchAllowed - ) { - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - globalScene.ui.setMode(UiMode.MESSAGE); - globalScene.ui.showText( - i18next.t("battle:noPokeballMysteryEncounter"), - null, - () => { - globalScene.ui.showText("", 0); - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - }, - null, - true, - ); - } else { - const targets = globalScene - .getEnemyField() - .filter(p => p.isActive(true)) - .map(p => p.getBattlerIndex()); - if (targets.length > 1) { - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - globalScene.ui.setMode(UiMode.MESSAGE); - globalScene.ui.showText( - i18next.t("battle:noPokeballMulti"), - null, - () => { - globalScene.ui.showText("", 0); - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - }, - null, - true, - ); - } else if (cursor < 5) { - const targetPokemon = globalScene.getEnemyField().find(p => p.isActive(true)); - if ( - targetPokemon?.isBoss() && - targetPokemon?.bossSegmentIndex >= 1 && - !targetPokemon?.hasAbility(AbilityId.WONDER_GUARD, false, true) && - cursor < PokeballType.MASTER_BALL - ) { - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - globalScene.ui.setMode(UiMode.MESSAGE); - globalScene.ui.showText( - i18next.t("battle:noPokeballStrong"), - null, - () => { - globalScene.ui.showText("", 0); - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - }, - null, - true, - ); - } else { - globalScene.currentBattle.turnCommands[this.fieldIndex] = { - command: Command.BALL, - cursor: cursor, - }; - globalScene.currentBattle.turnCommands[this.fieldIndex]!.targets = targets; - if (this.fieldIndex) { - globalScene.currentBattle.turnCommands[this.fieldIndex - 1]!.skip = true; - } - success = true; - } - } - } - break; - } + case Command.FIGHT: + return this.handleFightCommand(command, cursor, useMode, move); + case Command.BALL: + return this.handleBallCommand(cursor); case Command.POKEMON: case Command.RUN: { const isSwitch = command === Command.POKEMON; @@ -388,11 +414,11 @@ export class CommandPhase extends FieldPhase { true, ); } else { - const batonPass = isSwitch && (args[0] as boolean); + const batonPass = isSwitch && useMode; const trappedAbMessages: string[] = []; if (batonPass || !playerPokemon.isTrapped(trappedAbMessages)) { currentBattle.turnCommands[this.fieldIndex] = isSwitch - ? { command: Command.POKEMON, cursor: cursor, args: args } + ? { command: Command.POKEMON, cursor: cursor } : { command: Command.RUN }; success = true; if (!isSwitch && this.fieldIndex) { From 22b9a19ba65950c909328b057a8d002007cdc462 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 26 May 2025 11:46:53 -0500 Subject: [PATCH 29/76] Breakup run and pokemon commands --- src/phases/command-phase.ts | 274 +++++++++++++++++++++--------------- 1 file changed, 158 insertions(+), 116 deletions(-) diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index 92c01aa4b85..a37721ac912 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -20,15 +20,19 @@ import { UiMode } from "#enums/ui-mode"; import type { PlayerPokemon } from "#field/pokemon"; import type { MoveTargetSet } from "#moves/move"; import { getMoveTargets } from "#moves/move-utils"; -import { FieldPhase } from "#phases/field-phase"; import type { TurnMove } from "#types/turn-move"; -import { isNullOrUndefined } from "#utils/common"; import i18next from "i18next"; +import { FieldPhase } from "./field-phase"; export class CommandPhase extends FieldPhase { public readonly phaseName = "CommandPhase"; protected fieldIndex: number; + /** + * Whether the command phase is handling a switch command + */ + private isSwitch = false; + constructor(fieldIndex: number) { super(); @@ -150,7 +154,7 @@ export class CommandPhase extends FieldPhase { /** * * @param user - The pokemon using the move - * @param cursor - + * @param cursor - The index of the move in the moveset */ private queueFightErrorMessage(user: PlayerPokemon, cursor: number) { const move = user.getMoveset()[cursor]; @@ -264,6 +268,11 @@ export class CommandPhase extends FieldPhase { return true; } + /** + * Set the mode in preparation to show the text, and then show the text. + * Only works for parameterless i18next keys. + * @param key - The i18next key for the text to show + */ private queueShowText(key: string) { globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); globalScene.ui.setMode(UiMode.MESSAGE); @@ -323,7 +332,7 @@ export class CommandPhase extends FieldPhase { * @param cursor - The index of the pokeball to use * @returns Whether the command was successfully initiated */ - handleBallCommand(cursor: number): boolean { + private handleBallCommand(cursor: number): boolean { const targets = globalScene .getEnemyField() .filter(p => p.isActive(true)) @@ -364,125 +373,158 @@ export class CommandPhase extends FieldPhase { return false; } - handleCommand(command: Command, cursor: number, useMode: MoveUseMode = MoveUseMode.NORMAL, move?: TurnMove): boolean { + /** + * Common helper method to handle the logic for effects that prevent the pokemon from leaving the field + * due to trapping abilities or effects. + * + * This method queues the proper messages in the case of trapping abilities or effects + * + * @returns Whether the pokemon is currently trapped + */ + private handleTrap(): boolean { const playerPokemon = globalScene.getPlayerField()[this.fieldIndex]; + const trappedAbMessages: string[] = []; + const isSwitch = this.isSwitch; + if (!playerPokemon.isTrapped(trappedAbMessages)) { + return false; + } + if (trappedAbMessages.length > 0) { + if (isSwitch) { + globalScene.ui.setMode(UiMode.MESSAGE); + } + globalScene.ui.showText( + trappedAbMessages[0], + null, + () => { + globalScene.ui.showText("", 0); + if (isSwitch) { + globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); + } + }, + null, + true, + ); + } else { + const trapTag = playerPokemon.getTag(TrappedTag); + const fairyLockTag = globalScene.arena.getTagOnSide(ArenaTagType.FAIRY_LOCK, ArenaTagSide.PLAYER); + + if (!isSwitch) { + globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); + globalScene.ui.setMode(UiMode.MESSAGE); + } + if (trapTag) { + this.showNoEscapeText(trapTag, false); + } else if (fairyLockTag) { + this.showNoEscapeText(fairyLockTag, false); + } + } + + return true; + } + + /** + * Common helper method that attempts to have the pokemon leave the field. + * Checks for trapping abilities and effects. + * + * @param cursor - The index of the option that the cursor is on + * @param isBatonSwitch - Whether the switch command is switching via the Baton item + * @returns whether the pokemon is able to leave the field, indicating the command phase should end + */ + private tryLeaveField(cursor?: number, isBatonSwitch = false): boolean { + const currentBattle = globalScene.currentBattle; + + if (isBatonSwitch && !this.handleTrap()) { + currentBattle.turnCommands[this.fieldIndex] = { + command: this.isSwitch ? Command.POKEMON : Command.RUN, + cursor: cursor, + }; + if (!this.isSwitch && this.fieldIndex) { + currentBattle.turnCommands[this.fieldIndex - 1]!.skip = true; + } + return true; + } + + return false; + } + + private handleRunCommand(): boolean { + const { currentBattle, arena } = globalScene; + const mysteryEncounterFleeAllowed = currentBattle.mysteryEncounter?.fleeAllowed ?? true; + if (arena.biomeType === BiomeId.END || !mysteryEncounterFleeAllowed) { + this.queueShowText("battle:noEscapeForce"); + return false; + } + if ( + currentBattle.battleType === BattleType.TRAINER || + currentBattle.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE + ) { + this.queueShowText("battle:noEscapeTrainer"); + return false; + } + + const success = this.tryLeaveField(); + + return success; + } + + /** + * Show a message indicating that the pokemon cannot escape, and then return to the command phase. + */ + private showNoEscapeText(tag: any, isSwitch: boolean): void { + globalScene.ui.showText( + i18next.t("battle:noEscapePokemon", { + pokemonName: + tag.sourceId && globalScene.getPokemonById(tag.sourceId) + ? getPokemonNameWithAffix(globalScene.getPokemonById(tag.sourceId)!) + : "", + moveName: tag.getMoveName(), + escapeVerb: i18next.t(isSwitch ? "battle:escapeVerbSwitch" : "battle:escapeVerbFlee"), + }), + null, + () => { + globalScene.ui.showText("", 0); + if (!isSwitch) { + globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); + } + }, + null, + true, + ); + } + + // Overloads for handleCommand to provide a more specific type signature for the different options + handleCommand(command: Command.FIGHT | Command.TERA, cursor: number, useMode?: MoveUseMode, move?: TurnMove): boolean; + handleCommand(command: Command.BALL, cursor: number): boolean; + handleCommand(command: Command.POKEMON, cursor: number, useBaton: boolean): boolean; + handleCommand(command: Command.RUN, cursor: number): boolean; + handleCommand(command: Command, cursor: number, useMode?: boolean | MoveUseMode, move?: TurnMove): boolean; + + /** + * Process the command phase logic based on the selected command + * + * @param command - The kind of command to handle + * @param cursor - The index of option that the cursor is on, or -1 if no option is selected + * @param useMode - The mode to use for the move, if applicable. For switches, a boolean that specifies whether the switch is a Baton switch. + * @param move - For {@linkcode Command.FIGHT}, the move to use + */ + handleCommand(command: Command, cursor: number, useMode: boolean | MoveUseMode = false, move?: TurnMove): boolean { let success = false; switch (command) { case Command.TERA: case Command.FIGHT: - return this.handleFightCommand(command, cursor, useMode, move); - case Command.BALL: - return this.handleBallCommand(cursor); - case Command.POKEMON: - case Command.RUN: { - const isSwitch = command === Command.POKEMON; - const { currentBattle, arena } = globalScene; - const mysteryEncounterFleeAllowed = currentBattle.mysteryEncounter?.fleeAllowed; - if ( - !isSwitch && - (arena.biomeType === BiomeId.END || - (!isNullOrUndefined(mysteryEncounterFleeAllowed) && !mysteryEncounterFleeAllowed)) - ) { - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - globalScene.ui.setMode(UiMode.MESSAGE); - globalScene.ui.showText( - i18next.t("battle:noEscapeForce"), - null, - () => { - globalScene.ui.showText("", 0); - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - }, - null, - true, - ); - } else if ( - !isSwitch && - (currentBattle.battleType === BattleType.TRAINER || - currentBattle.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE) - ) { - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - globalScene.ui.setMode(UiMode.MESSAGE); - globalScene.ui.showText( - i18next.t("battle:noEscapeTrainer"), - null, - () => { - globalScene.ui.showText("", 0); - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - }, - null, - true, - ); - } else { - const batonPass = isSwitch && useMode; - const trappedAbMessages: string[] = []; - if (batonPass || !playerPokemon.isTrapped(trappedAbMessages)) { - currentBattle.turnCommands[this.fieldIndex] = isSwitch - ? { command: Command.POKEMON, cursor: cursor } - : { command: Command.RUN }; - success = true; - if (!isSwitch && this.fieldIndex) { - currentBattle.turnCommands[this.fieldIndex - 1]!.skip = true; - } - } else if (trappedAbMessages.length > 0) { - if (!isSwitch) { - globalScene.ui.setMode(UiMode.MESSAGE); - } - globalScene.ui.showText( - trappedAbMessages[0], - null, - () => { - globalScene.ui.showText("", 0); - if (!isSwitch) { - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - } - }, - null, - true, - ); - } else { - const trapTag = playerPokemon.getTag(TrappedTag); - const fairyLockTag = globalScene.arena.getTagOnSide(ArenaTagType.FAIRY_LOCK, ArenaTagSide.PLAYER); - - if (!trapTag && !fairyLockTag) { - i18next.t(`battle:noEscape${isSwitch ? "Switch" : "Flee"}`); - break; - } - if (!isSwitch) { - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - globalScene.ui.setMode(UiMode.MESSAGE); - } - const showNoEscapeText = (tag: any) => { - globalScene.ui.showText( - i18next.t("battle:noEscapePokemon", { - pokemonName: - tag.sourceId && globalScene.getPokemonById(tag.sourceId) - ? getPokemonNameWithAffix(globalScene.getPokemonById(tag.sourceId)!) - : "", - moveName: tag.getMoveName(), - escapeVerb: isSwitch ? i18next.t("battle:escapeVerbSwitch") : i18next.t("battle:escapeVerbFlee"), - }), - null, - () => { - globalScene.ui.showText("", 0); - if (!isSwitch) { - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - } - }, - null, - true, - ); - }; - - if (trapTag) { - showNoEscapeText(trapTag); - } else if (fairyLockTag) { - showNoEscapeText(fairyLockTag); - } - } - } + success = this.handleFightCommand(command, cursor, typeof useMode === "boolean" ? undefined : useMode, move); break; - } + case Command.BALL: + success = this.handleBallCommand(cursor); + break; + case Command.POKEMON: + this.isSwitch = true; + success = this.tryLeaveField(cursor, typeof useMode === "boolean" ? useMode : undefined); + this.isSwitch = false; + break; + case Command.RUN: + success = this.handleRunCommand(); } if (success) { From 958eb005665637223b22a41371a95b09d379dce8 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 26 May 2025 15:56:14 -0500 Subject: [PATCH 30/76] Breakup commandPhase#start Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> --- src/phases/command-phase.ts | 205 ++++++++++++++++++++++-------------- 1 file changed, 125 insertions(+), 80 deletions(-) diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index a37721ac912..943eca87e5a 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -1,14 +1,13 @@ import type { TurnCommand } from "#app/battle"; +import { BattlerTagType } from "#app/enums/battler-tag-type"; import { globalScene } from "#app/global-scene"; import { getPokemonNameWithAffix } from "#app/messages"; import { speciesStarterCosts } from "#balance/starters"; -import type { EncoreTag } from "#data/battler-tags"; import { TrappedTag } from "#data/battler-tags"; import { AbilityId } from "#enums/ability-id"; import { ArenaTagSide } from "#enums/arena-tag-side"; import { ArenaTagType } from "#enums/arena-tag-type"; import { BattleType } from "#enums/battle-type"; -import { BattlerTagType } from "#enums/battler-tag-type"; import { BiomeId } from "#enums/biome-id"; import { Command } from "#enums/command"; import { FieldPosition } from "#enums/field-position"; @@ -39,11 +38,13 @@ export class CommandPhase extends FieldPhase { this.fieldIndex = fieldIndex; } - start() { - super.start(); - - globalScene.updateGameInfo(); - + /** + * Resets the cursor to the position of {@linkcode Command.FIGHT} if any of the following are true + * - The setting to remember the last action is not enabled + * - This is the first turn of a mystery encounter, trainer battle, or the END biome + * - The cursor is currently on the POKEMON command + */ + private resetCursorIfNeeded() { const commandUiHandler = globalScene.ui.handlers[UiMode.COMMAND]; // If one of these conditions is true, we always reset the cursor to Command.FIGHT @@ -52,33 +53,42 @@ export class CommandPhase extends FieldPhase { globalScene.currentBattle.battleType === BattleType.TRAINER || globalScene.arena.biomeType === BiomeId.END; - if (commandUiHandler) { - if ( - (globalScene.currentBattle.turn === 1 && (!globalScene.commandCursorMemory || cursorResetEvent)) || - commandUiHandler.getCursor() === Command.POKEMON - ) { - commandUiHandler.setCursor(Command.FIGHT); - } else { - commandUiHandler.setCursor(commandUiHandler.getCursor()); - } + if ( + (commandUiHandler && + globalScene.currentBattle.turn === 1 && + (!globalScene.commandCursorMemory || cursorResetEvent)) || + commandUiHandler.getCursor() === Command.POKEMON + ) { + commandUiHandler.setCursor(Command.FIGHT); + } + } + + /** + * Submethod of {@linkcode start} that validates field index logic for nonzero field indices. + * Must only be called if the field index is nonzero. + */ + private handleFieldIndexLogic() { + // If we somehow are attempting to check the right pokemon but there's only one pokemon out + // Switch back to the center pokemon. This can happen rarely in double battles with mid turn switching + // TODO: Prevent this from happening in the first place + if (globalScene.getPlayerField().filter(p => p.isActive()).length === 1) { + this.fieldIndex = FieldPosition.CENTER; + return; } - if (this.fieldIndex) { - // If we somehow are attempting to check the right pokemon but there's only one pokemon out - // Switch back to the center pokemon. This can happen rarely in double battles with mid turn switching - if (globalScene.getPlayerField().filter(p => p.isActive()).length === 1) { - this.fieldIndex = FieldPosition.CENTER; - } else { - const allyCommand = globalScene.currentBattle.turnCommands[this.fieldIndex - 1]; - if (allyCommand?.command === Command.BALL || allyCommand?.command === Command.RUN) { - globalScene.currentBattle.turnCommands[this.fieldIndex] = { - command: allyCommand?.command, - skip: true, - }; - } - } + const allyCommand = globalScene.currentBattle.turnCommands[this.fieldIndex - 1]; + if (allyCommand?.command === Command.BALL || allyCommand?.command === Command.RUN) { + globalScene.currentBattle.turnCommands[this.fieldIndex] = { + command: allyCommand?.command, + skip: true, + }; } + } + /** Submethod of {@linkcode start} that sets the turn command to skip if this pokemon is commanding its ally + * via {@linkcode Abilities.COMMANDER}. + */ + private checkCommander() { // If the Pokemon has applied Commander's effects to its ally, skip this command if ( globalScene.currentBattle?.double && @@ -90,64 +100,99 @@ export class CommandPhase extends FieldPhase { skip: true, }; } + } - // Checks if the Pokemon is under the effects of Encore. If so, Encore can end early if the encored move has no more PP. - const encoreTag = this.getPokemon().getTag(BattlerTagType.ENCORE) as EncoreTag | undefined; - if (encoreTag) { - this.getPokemon().lapseTag(BattlerTagType.ENCORE); + /** + * Clear out all unusable moves in front of the currently acting pokemon's move queue. + * TODO: Refactor move queue handling to ensure that this method is not necessary. + */ + private clearUnusuableMoves() { + const playerPokemon = this.getPokemon(); + const moveQueue = playerPokemon.getMoveQueue(); + if (moveQueue.length === 0) { + return; } + let entriesToDelete = 0; + const moveset = playerPokemon.getMoveset(); + for (const queuedMove of moveQueue) { + const movesetQueuedMove = moveset.find(m => m.moveId === queuedMove.move); + if ( + queuedMove.move !== MoveId.NONE && + !isVirtual(queuedMove.useMode) && + !movesetQueuedMove?.isUsable(playerPokemon, isIgnorePP(queuedMove.useMode)) + ) { + entriesToDelete++; + } else { + break; + } + } + if (entriesToDelete) { + moveQueue.splice(0, entriesToDelete); + } + } + + /** + * Attempt to execute the first usable move in this Pokemon's move queue + * @returns Whether a queued move was successfully set to be executed. + */ + private tryExecuteQueuedMove(): boolean { + this.clearUnusuableMoves(); + const playerPokemon = globalScene.getPlayerField()[this.fieldIndex]; + const moveQueue = playerPokemon.getMoveQueue(); + + if (moveQueue.length === 0) { + return false; + } + + const queuedMove = moveQueue[0]; + if (queuedMove.move === MoveId.NONE) { + this.handleCommand(Command.FIGHT, -1); + return true; + } + const moveIndex = playerPokemon.getMoveset().findIndex(m => m.moveId === queuedMove.move); + if (!isVirtual(queuedMove.useMode) && moveIndex === -1) { + globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); + } else { + this.handleCommand(Command.FIGHT, moveIndex, queuedMove.useMode, queuedMove); + } + + return true; + } + + start() { + super.start(); + + globalScene.updateGameInfo(); + this.resetCursorIfNeeded(); + + if (this.fieldIndex) { + this.handleFieldIndexLogic(); + } + + this.checkCommander(); + + const playerPokemon = this.getPokemon(); + + // Note: It is OK to call this if the target is not under the effect of encore; it will simply do nothing. + playerPokemon.lapseTag(BattlerTagType.ENCORE); + if (globalScene.currentBattle.turnCommands[this.fieldIndex]?.skip) { return this.end(); } - const playerPokemon = globalScene.getPlayerField()[this.fieldIndex]; - - const moveQueue = playerPokemon.getMoveQueue(); - - while ( - moveQueue.length && - moveQueue[0] && - moveQueue[0].move && - !isVirtual(moveQueue[0].useMode) && - (!playerPokemon.getMoveset().find(m => m.moveId === moveQueue[0].move) || - !playerPokemon - .getMoveset() - [playerPokemon.getMoveset().findIndex(m => m.moveId === moveQueue[0].move)].isUsable( - playerPokemon, - isIgnorePP(moveQueue[0].useMode), - )) - ) { - moveQueue.shift(); + if (this.tryExecuteQueuedMove()) { + return; } - // TODO: Refactor this. I did a few simple find/replace matches but this is just ABHORRENTLY structured - if (moveQueue.length > 0) { - const queuedMove = moveQueue[0]; - if (!queuedMove.move) { - this.handleCommand(Command.FIGHT, -1, MoveUseMode.NORMAL); - } else { - const moveIndex = playerPokemon.getMoveset().findIndex(m => m.moveId === queuedMove.move); - if ( - (moveIndex > -1 && - playerPokemon.getMoveset()[moveIndex].isUsable(playerPokemon, isIgnorePP(queuedMove.useMode))) || - isVirtual(queuedMove.useMode) - ) { - this.handleCommand(Command.FIGHT, moveIndex, queuedMove.useMode, queuedMove); - } else { - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - } - } + if ( + globalScene.currentBattle.isBattleMysteryEncounter() && + globalScene.currentBattle.mysteryEncounter?.skipToFightInput + ) { + globalScene.ui.clearText(); + globalScene.ui.setMode(UiMode.FIGHT, this.fieldIndex); } else { - if ( - globalScene.currentBattle.isBattleMysteryEncounter() && - globalScene.currentBattle.mysteryEncounter?.skipToFightInput - ) { - globalScene.ui.clearText(); - globalScene.ui.setMode(UiMode.FIGHT, this.fieldIndex); - } else { - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - } + globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); } } @@ -201,7 +246,7 @@ export class CommandPhase extends FieldPhase { useMode: MoveUseMode = MoveUseMode.NORMAL, move?: TurnMove, ): boolean { - const playerPokemon = globalScene.getPlayerField()[this.fieldIndex]; + const playerPokemon = this.getPokemon(); const ignorePP = isIgnorePP(useMode); /** Whether or not to display an error message instead of attempting to initiate the command selection process */ @@ -382,7 +427,7 @@ export class CommandPhase extends FieldPhase { * @returns Whether the pokemon is currently trapped */ private handleTrap(): boolean { - const playerPokemon = globalScene.getPlayerField()[this.fieldIndex]; + const playerPokemon = this.getPokemon(); const trappedAbMessages: string[] = []; const isSwitch = this.isSwitch; if (!playerPokemon.isTrapped(trappedAbMessages)) { From 22d2b4a43665543ae386a3ca88df2834482912eb Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 26 May 2025 16:41:58 -0500 Subject: [PATCH 31/76] Minor touchups --- src/phases/command-phase.ts | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index 943eca87e5a..34ca7bb71e5 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -249,8 +249,7 @@ export class CommandPhase extends FieldPhase { const playerPokemon = this.getPokemon(); const ignorePP = isIgnorePP(useMode); - /** Whether or not to display an error message instead of attempting to initiate the command selection process */ - let canUse = cursor !== -1 || !playerPokemon.trySelectMove(cursor, ignorePP); + let canUse = cursor === -1 || playerPokemon.trySelectMove(cursor, ignorePP); const useStruggle = canUse ? false @@ -291,7 +290,7 @@ export class CommandPhase extends FieldPhase { console.log(moveTargets, getPokemonNameWithAffix(playerPokemon)); - if (moveTargets.multiple) { + if (moveTargets.targets.length > 1 && moveTargets.multiple) { globalScene.phaseManager.unshiftNew("SelectTargetPhase", this.fieldIndex); } @@ -419,7 +418,7 @@ export class CommandPhase extends FieldPhase { } /** - * Common helper method to handle the logic for effects that prevent the pokemon from leaving the field + * Helper method to handle the logic for effects that prevent the pokemon from leaving the field * due to trapping abilities or effects. * * This method queues the proper messages in the case of trapping abilities or effects @@ -478,11 +477,16 @@ export class CommandPhase extends FieldPhase { private tryLeaveField(cursor?: number, isBatonSwitch = false): boolean { const currentBattle = globalScene.currentBattle; - if (isBatonSwitch && !this.handleTrap()) { - currentBattle.turnCommands[this.fieldIndex] = { - command: this.isSwitch ? Command.POKEMON : Command.RUN, - cursor: cursor, - }; + if (isBatonSwitch || !this.handleTrap()) { + currentBattle.turnCommands[this.fieldIndex] = this.isSwitch + ? { + command: Command.POKEMON, + cursor: cursor, + args: [isBatonSwitch], + } + : { + command: Command.RUN, + }; if (!this.isSwitch && this.fieldIndex) { currentBattle.turnCommands[this.fieldIndex - 1]!.skip = true; } @@ -537,7 +541,7 @@ export class CommandPhase extends FieldPhase { ); } - // Overloads for handleCommand to provide a more specific type signature for the different options + // Overloads for handleCommand to provide a more specific signature for the different options handleCommand(command: Command.FIGHT | Command.TERA, cursor: number, useMode?: MoveUseMode, move?: TurnMove): boolean; handleCommand(command: Command.BALL, cursor: number): boolean; handleCommand(command: Command.POKEMON, cursor: number, useBaton: boolean): boolean; From 9218d35938d11813d53a44c48a1fe181cce0a105 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 26 May 2025 16:49:00 -0500 Subject: [PATCH 32/76] Add overload for handle command --- src/phases/command-phase.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index 34ca7bb71e5..c9a83096359 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -249,6 +249,7 @@ export class CommandPhase extends FieldPhase { const playerPokemon = this.getPokemon(); const ignorePP = isIgnorePP(useMode); + let canUse = cursor === -1 || playerPokemon.trySelectMove(cursor, ignorePP); let canUse = cursor === -1 || playerPokemon.trySelectMove(cursor, ignorePP); const useStruggle = canUse From adb5900497fcc1a6d6afeb892e84e508c6b899f8 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 26 May 2025 20:40:48 -0500 Subject: [PATCH 33/76] Fix improperly named computeMoveId method --- src/phases/command-phase.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index c9a83096359..024e54f8065 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -230,7 +230,7 @@ export class CommandPhase extends FieldPhase { * * Does not check if the move is usable or not, that should be handled by the caller. */ - private comptueMoveId(playerPokemon: PlayerPokemon, cursor: number, move?: TurnMove): MoveId { + private computeMoveId(playerPokemon: PlayerPokemon, cursor: number, move?: TurnMove): MoveId { return move?.move ?? (cursor > -1 ? playerPokemon.getMoveset()[cursor]?.moveId : MoveId.NONE); } @@ -263,7 +263,7 @@ export class CommandPhase extends FieldPhase { return false; } - const moveId = useStruggle ? MoveId.STRUGGLE : this.comptueMoveId(playerPokemon, cursor, move); + const moveId = useStruggle ? MoveId.STRUGGLE : this.computeMoveId(playerPokemon, cursor, move); const turnCommand: TurnCommand = { command: Command.FIGHT, From e1e7287919513d9017b8e17f142e34d3cd103ef5 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 26 May 2025 23:13:46 -0500 Subject: [PATCH 34/76] Improve `canUse` computation --- src/phases/command-phase.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index 024e54f8065..85b919148e3 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -252,13 +252,12 @@ export class CommandPhase extends FieldPhase { let canUse = cursor === -1 || playerPokemon.trySelectMove(cursor, ignorePP); let canUse = cursor === -1 || playerPokemon.trySelectMove(cursor, ignorePP); + // Ternary here ensures we don't compute struggle conditions unless necessary const useStruggle = canUse ? false : cursor > -1 && !playerPokemon.getMoveset().some(m => m.isUsable(playerPokemon)); - canUse = canUse || useStruggle; - - if (!canUse) { + if (!canUse && !useStruggle) { this.queueFightErrorMessage(playerPokemon, cursor); return false; } From 1df3ac096254d0dd3587d9c26a986212d24dcf60 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 26 May 2025 23:18:04 -0500 Subject: [PATCH 35/76] Explicitly check against Moves.NONE Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> --- src/phases/command-phase.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index 85b919148e3..a8ea0abe5c2 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -284,7 +284,7 @@ export class CommandPhase extends FieldPhase { multiple: move.targets.length > 1, }; - if (!moveId) { + if (moveId === Moves.NONE) { turnCommand.targets = [this.fieldIndex]; } From 26cbf2db8c1d6a3f1485ad53f2b007ba40c39187 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Fri, 6 Jun 2025 10:41:34 -0500 Subject: [PATCH 36/76] Update with Bertie's comments Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> --- src/phases/command-phase.ts | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index a8ea0abe5c2..ce83c25d314 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -225,7 +225,8 @@ export class CommandPhase extends FieldPhase { ); } - /** Helper method for {@linkcode handleFightCommand} that returns the moveID for the phase + /** + * Helper method for {@linkcode handleFightCommand} that returns the moveID for the phase * based on the move passed in or the cursor. * * Does not check if the move is usable or not, that should be handled by the caller. @@ -235,10 +236,16 @@ export class CommandPhase extends FieldPhase { } /** - * Handle fight logic + * Process the logic for executing a fight-related command + * + * @remarks + * - Validates whether the move can be used, using struggle if not + * - Constructs the turn command and inserts it into the battle's turn commands + * * @param command - The command to handle (FIGHT or TERA) * @param cursor - The index that the cursor is placed on, or -1 if no move can be selected. - * @param args - Any additional arguments to pass to the command + * @param ignorePP - Whether to ignore PP when checking if the move can be used. + * @param move - The move to force the command to use, if any. */ private handleFightCommand( command: Command.FIGHT | Command.TERA, @@ -249,7 +256,6 @@ export class CommandPhase extends FieldPhase { const playerPokemon = this.getPokemon(); const ignorePP = isIgnorePP(useMode); - let canUse = cursor === -1 || playerPokemon.trySelectMove(cursor, ignorePP); let canUse = cursor === -1 || playerPokemon.trySelectMove(cursor, ignorePP); // Ternary here ensures we don't compute struggle conditions unless necessary @@ -257,7 +263,9 @@ export class CommandPhase extends FieldPhase { ? false : cursor > -1 && !playerPokemon.getMoveset().some(m => m.isUsable(playerPokemon)); - if (!canUse && !useStruggle) { + canUse ||= useStruggle; + + if (!canUse) { this.queueFightErrorMessage(playerPokemon, cursor); return false; } @@ -284,7 +292,7 @@ export class CommandPhase extends FieldPhase { multiple: move.targets.length > 1, }; - if (moveId === Moves.NONE) { + if (moveId === MoveId.NONE) { turnCommand.targets = [this.fieldIndex]; } From c0a42985bffbab5369bf797b3adb9246fa653819 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Tue, 15 Jul 2025 22:12:19 -0700 Subject: [PATCH 37/76] Fix imports --- src/phases/command-phase.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index ce83c25d314..d44681ab12c 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -1,5 +1,4 @@ import type { TurnCommand } from "#app/battle"; -import { BattlerTagType } from "#app/enums/battler-tag-type"; import { globalScene } from "#app/global-scene"; import { getPokemonNameWithAffix } from "#app/messages"; import { speciesStarterCosts } from "#balance/starters"; @@ -8,6 +7,7 @@ import { AbilityId } from "#enums/ability-id"; import { ArenaTagSide } from "#enums/arena-tag-side"; import { ArenaTagType } from "#enums/arena-tag-type"; import { BattleType } from "#enums/battle-type"; +import { BattlerTagType } from "#enums/battler-tag-type"; import { BiomeId } from "#enums/biome-id"; import { Command } from "#enums/command"; import { FieldPosition } from "#enums/field-position"; @@ -19,9 +19,9 @@ import { UiMode } from "#enums/ui-mode"; import type { PlayerPokemon } from "#field/pokemon"; import type { MoveTargetSet } from "#moves/move"; import { getMoveTargets } from "#moves/move-utils"; +import { FieldPhase } from "#phases/field-phase"; import type { TurnMove } from "#types/turn-move"; import i18next from "i18next"; -import { FieldPhase } from "./field-phase"; export class CommandPhase extends FieldPhase { public readonly phaseName = "CommandPhase"; From ed915dcb58c85a9c511b80dba329b65bdde609be Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Wed, 23 Jul 2025 21:15:23 -0600 Subject: [PATCH 38/76] Apply kev's suggestions from code review Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/phases/command-phase.ts | 115 +++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 46 deletions(-) diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index d44681ab12c..44b365146d9 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -44,19 +44,21 @@ export class CommandPhase extends FieldPhase { * - This is the first turn of a mystery encounter, trainer battle, or the END biome * - The cursor is currently on the POKEMON command */ - private resetCursorIfNeeded() { + private resetCursorIfNeeded(): void { const commandUiHandler = globalScene.ui.handlers[UiMode.COMMAND]; + const { arena, commandCursorMemory, currentBattle } = globalScene; + const { battleType, turn } = currentBattle; + const { biomeType } = arena; // If one of these conditions is true, we always reset the cursor to Command.FIGHT const cursorResetEvent = - globalScene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER || - globalScene.currentBattle.battleType === BattleType.TRAINER || - globalScene.arena.biomeType === BiomeId.END; + battleType === BattleType.MYSTERY_ENCOUNTER || battleType === BattleType.TRAINER || biomeType === BiomeId.END; + if (!commandUiHandler) { + return; + } if ( - (commandUiHandler && - globalScene.currentBattle.turn === 1 && - (!globalScene.commandCursorMemory || cursorResetEvent)) || + (turn === 1 && (!commandCursorMemory || cursorResetEvent)) || commandUiHandler.getCursor() === Command.POKEMON ) { commandUiHandler.setCursor(Command.FIGHT); @@ -67,7 +69,7 @@ export class CommandPhase extends FieldPhase { * Submethod of {@linkcode start} that validates field index logic for nonzero field indices. * Must only be called if the field index is nonzero. */ - private handleFieldIndexLogic() { + private handleFieldIndexLogic(): void { // If we somehow are attempting to check the right pokemon but there's only one pokemon out // Switch back to the center pokemon. This can happen rarely in double battles with mid turn switching // TODO: Prevent this from happening in the first place @@ -85,10 +87,11 @@ export class CommandPhase extends FieldPhase { } } - /** Submethod of {@linkcode start} that sets the turn command to skip if this pokemon is commanding its ally - * via {@linkcode Abilities.COMMANDER}. + /** + * Submethod of {@linkcode start} that sets the turn command to skip if this pokemon + * is commanding its ally via {@linkcode AbilityId.COMMANDER}. */ - private checkCommander() { + private checkCommander(): void { // If the Pokemon has applied Commander's effects to its ally, skip this command if ( globalScene.currentBattle?.double && @@ -104,9 +107,10 @@ export class CommandPhase extends FieldPhase { /** * Clear out all unusable moves in front of the currently acting pokemon's move queue. + * * TODO: Refactor move queue handling to ensure that this method is not necessary. */ - private clearUnusuableMoves() { + private clearUnusuableMoves(): void { const playerPokemon = this.getPokemon(); const moveQueue = playerPokemon.getMoveQueue(); if (moveQueue.length === 0) { @@ -160,7 +164,7 @@ export class CommandPhase extends FieldPhase { return true; } - start() { + public override start(): void { super.start(); globalScene.updateGameInfo(); @@ -178,7 +182,8 @@ export class CommandPhase extends FieldPhase { playerPokemon.lapseTag(BattlerTagType.ENCORE); if (globalScene.currentBattle.turnCommands[this.fieldIndex]?.skip) { - return this.end(); + this.end(); + return; } if (this.tryExecuteQueuedMove()) { @@ -197,7 +202,8 @@ export class CommandPhase extends FieldPhase { } /** - * + * Submethod of {@linkcode handleFightCommand} responsible for queuing the appropriate + * error message when a move cannot be used. * @param user - The pokemon using the move * @param cursor - The index of the move in the moveset */ @@ -231,7 +237,7 @@ export class CommandPhase extends FieldPhase { * * Does not check if the move is usable or not, that should be handled by the caller. */ - private computeMoveId(playerPokemon: PlayerPokemon, cursor: number, move?: TurnMove): MoveId { + private computeMoveId(playerPokemon: PlayerPokemon, cursor: number, move: TurnMove | undefined): MoveId { return move?.move ?? (cursor > -1 ? playerPokemon.getMoveset()[cursor]?.moveId : MoveId.NONE); } @@ -274,12 +280,12 @@ export class CommandPhase extends FieldPhase { const turnCommand: TurnCommand = { command: Command.FIGHT, - cursor: cursor, + cursor, move: { move: moveId, targets: [], useMode }, args: [useMode, move], }; const preTurnCommand: TurnCommand = { - command: command, + command, targets: [this.fieldIndex], skip: command === Command.FIGHT, }; @@ -296,7 +302,14 @@ export class CommandPhase extends FieldPhase { turnCommand.targets = [this.fieldIndex]; } - console.log(moveTargets, getPokemonNameWithAffix(playerPokemon)); + console.log( + "Move:", + MoveId[moveId], + "Move targets:", + moveTargets, + "\nPlayer Pokemon:", + getPokemonNameWithAffix(playerPokemon), + ); if (moveTargets.targets.length > 1 && moveTargets.multiple) { globalScene.phaseManager.unshiftNew("SelectTargetPhase", this.fieldIndex); @@ -325,7 +338,7 @@ export class CommandPhase extends FieldPhase { * Only works for parameterless i18next keys. * @param key - The i18next key for the text to show */ - private queueShowText(key: string) { + private queueShowText(key: string): void { globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); globalScene.ui.setMode(UiMode.MESSAGE); @@ -344,32 +357,35 @@ export class CommandPhase extends FieldPhase { /** * Helper method for {@linkcode handleBallCommand} that checks if the pokeball can be thrown. * - * The pokeball may not be thrown if: + * The pokeball may not be thrown if any of the following are true: * - It is a trainer battle - * - The biome is {@linkcode Biome.END} and it is not classic mode - * - The biome is {@linkcode Biome.END} and the fresh start challenge is active - * - The biome is {@linkcode Biome.END} and the player has not either caught the target before or caught all but one starter + * - The player is in the {@linkcode BiomeId.END | End} biome and + * - it is not classic mode; or + * - the fresh start challenge is active; or + * - the player has not caught the target before and the player is still missing more than one starter * - The player is in a mystery encounter that disallows catching the pokemon * @returns Whether a pokeball can be thrown - * */ private checkCanUseBall(): boolean { + const { arena, currentBattle, gameData, gameMode } = globalScene; + const { battleType } = currentBattle; + const { biomeType } = arena; + const { isClassic } = gameMode; + const { dexData } = gameData; + + const someUncaughtSpeciesOnField = globalScene + .getEnemyField() + .some(p => p.isActive() && !dexData[p.species.speciesId].caughtAttr); + const missingMultipleStarters = + gameData.getStarterCount(d => !!d.caughtAttr) < Object.keys(speciesStarterCosts).length - 1; if ( - globalScene.arena.biomeType === BiomeId.END && - (!globalScene.gameMode.isClassic || - globalScene.gameMode.isFreshStartChallenge() || - (globalScene - .getEnemyField() - .some(p => p.isActive() && !globalScene.gameData.dexData[p.species.speciesId].caughtAttr) && - globalScene.gameData.getStarterCount(d => !!d.caughtAttr) < Object.keys(speciesStarterCosts).length - 1)) + biomeType === BiomeId.END && + (!isClassic || gameMode.isFreshStartChallenge() || (someUncaughtSpeciesOnField && missingMultipleStarters)) ) { this.queueShowText("battle:noPokeballForce"); - } else if (globalScene.currentBattle.battleType === BattleType.TRAINER) { + } else if (battleType === BattleType.TRAINER) { this.queueShowText("battle:noPokeballTrainer"); - } else if ( - globalScene.currentBattle.isBattleMysteryEncounter() && - !globalScene.currentBattle.mysteryEncounter!.catchAllowed - ) { + } else if (currentBattle.isBattleMysteryEncounter() && !currentBattle.mysteryEncounter!.catchAllowed) { this.queueShowText("battle:noPokeballMysteryEncounter"); } else { return true; @@ -398,7 +414,8 @@ export class CommandPhase extends FieldPhase { return false; } - if (cursor < 5) { + const numBallTypes = 5; + if (cursor < numBallTypes) { const targetPokemon = globalScene.getEnemyPokemon(); if ( targetPokemon?.isBoss() && @@ -489,7 +506,7 @@ export class CommandPhase extends FieldPhase { currentBattle.turnCommands[this.fieldIndex] = this.isSwitch ? { command: Command.POKEMON, - cursor: cursor, + cursor, args: [isBatonSwitch], } : { @@ -550,12 +567,6 @@ export class CommandPhase extends FieldPhase { } // Overloads for handleCommand to provide a more specific signature for the different options - handleCommand(command: Command.FIGHT | Command.TERA, cursor: number, useMode?: MoveUseMode, move?: TurnMove): boolean; - handleCommand(command: Command.BALL, cursor: number): boolean; - handleCommand(command: Command.POKEMON, cursor: number, useBaton: boolean): boolean; - handleCommand(command: Command.RUN, cursor: number): boolean; - handleCommand(command: Command, cursor: number, useMode?: boolean | MoveUseMode, move?: TurnMove): boolean; - /** * Process the command phase logic based on the selected command * @@ -563,8 +574,20 @@ export class CommandPhase extends FieldPhase { * @param cursor - The index of option that the cursor is on, or -1 if no option is selected * @param useMode - The mode to use for the move, if applicable. For switches, a boolean that specifies whether the switch is a Baton switch. * @param move - For {@linkcode Command.FIGHT}, the move to use + * @returns Whether the command was successful */ - handleCommand(command: Command, cursor: number, useMode: boolean | MoveUseMode = false, move?: TurnMove): boolean { + handleCommand(command: Command.FIGHT | Command.TERA, cursor: number, useMode?: MoveUseMode, move?: TurnMove): boolean; + handleCommand(command: Command.BALL, cursor: number): boolean; + handleCommand(command: Command.POKEMON, cursor: number, useBaton: boolean): boolean; + handleCommand(command: Command.RUN, cursor: number): boolean; + handleCommand(command: Command, cursor: number, useMode?: boolean | MoveUseMode, move?: TurnMove): boolean; + + public handleCommand( + command: Command, + cursor: number, + useMode: boolean | MoveUseMode = false, + move?: TurnMove, + ): boolean { let success = false; switch (command) { From 0c82b3f514d2624ea1d36e39b5a749f385fa3013 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Thu, 24 Jul 2025 15:14:24 -0600 Subject: [PATCH 39/76] Improve documentation Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> --- src/phases/command-phase.ts | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index 44b365146d9..016d4ff5d3b 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -107,9 +107,8 @@ export class CommandPhase extends FieldPhase { /** * Clear out all unusable moves in front of the currently acting pokemon's move queue. - * - * TODO: Refactor move queue handling to ensure that this method is not necessary. */ + // TODO: Refactor move queue handling to ensure that this method is not necessary. private clearUnusuableMoves(): void { const playerPokemon = this.getPokemon(); const moveQueue = playerPokemon.getMoveQueue(); @@ -355,8 +354,10 @@ export class CommandPhase extends FieldPhase { } /** - * Helper method for {@linkcode handleBallCommand} that checks if the pokeball can be thrown. + * Helper method for {@linkcode handleBallCommand} that checks if a pokeball can be thrown + * and displays the appropriate error message. * + * @remarks * The pokeball may not be thrown if any of the following are true: * - It is a trainer battle * - The player is in the {@linkcode BiomeId.END | End} biome and @@ -443,10 +444,10 @@ export class CommandPhase extends FieldPhase { } /** - * Helper method to handle the logic for effects that prevent the pokemon from leaving the field + * Submethod of {@linkcode tryLeaveField} to handle the logic for effects that prevent the pokemon from leaving the field * due to trapping abilities or effects. * - * This method queues the proper messages in the case of trapping abilities or effects + * This method queues the proper messages in the case of trapping abilities or effects. * * @returns Whether the pokemon is currently trapped */ @@ -496,8 +497,7 @@ export class CommandPhase extends FieldPhase { * Checks for trapping abilities and effects. * * @param cursor - The index of the option that the cursor is on - * @param isBatonSwitch - Whether the switch command is switching via the Baton item - * @returns whether the pokemon is able to leave the field, indicating the command phase should end + * @returns Whether the pokemon is able to leave the field, indicating the command phase should end */ private tryLeaveField(cursor?: number, isBatonSwitch = false): boolean { const currentBattle = globalScene.currentBattle; @@ -521,6 +521,19 @@ export class CommandPhase extends FieldPhase { return false; } + /** + * Helper method for {@linkcode handleCommand} that handles the logic when the selected command is RUN. + * + * @remarks + * Checks if the player is allowed to flee, and if not, queues the appropriate message. + * + * The player cannot flee if: + * - The player is in the {@linkcode BiomeId.END | End} biome + * - The player is in a trainer battle + * - The player is in a mystery encounter that disallows fleeing + * - The player's pokemon is trapped by an ability or effect + * @returns Whether the pokemon is able to leave the field, indicating the command phase should end + */ private handleRunCommand(): boolean { const { currentBattle, arena } = globalScene; const mysteryEncounterFleeAllowed = currentBattle.mysteryEncounter?.fleeAllowed ?? true; From 903fad89d9e4d25fd4665958b3cc99efab718db5 Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Mon, 28 Jul 2025 01:46:11 -0400 Subject: [PATCH 40/76] [Balance][Challenge] Added expanded Fresh Start options (#6162) --- src/data/challenge.ts | 35 ++++++++++++++++++++++++++--------- src/system/achv.ts | 2 +- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/data/challenge.ts b/src/data/challenge.ts index db4ec931bc2..aaa82a7d20f 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -4,6 +4,7 @@ import { defaultStarterSpecies } from "#app/constants"; import { globalScene } from "#app/global-scene"; import { pokemonEvolutions } from "#balance/pokemon-evolutions"; import { speciesStarterCosts } from "#balance/starters"; +import { getEggTierForSpecies } from "#data/egg"; import { pokemonFormChanges } from "#data/pokemon-forms"; import type { PokemonSpecies } from "#data/pokemon-species"; import { getPokemonSpeciesForm } from "#data/pokemon-species"; @@ -11,6 +12,7 @@ import { BattleType } from "#enums/battle-type"; import { ChallengeType } from "#enums/challenge-type"; import { Challenges } from "#enums/challenges"; import { TypeColor, TypeShadow } from "#enums/color"; +import { EggTier } from "#enums/egg-type"; import { ClassicFixedBossWaves } from "#enums/fixed-boss-waves"; import { ModifierTier } from "#enums/modifier-tier"; import type { MoveId } from "#enums/move-id"; @@ -683,11 +685,14 @@ export class SingleTypeChallenge extends Challenge { */ export class FreshStartChallenge extends Challenge { constructor() { - super(Challenges.FRESH_START, 1); + super(Challenges.FRESH_START, 3); } applyStarterChoice(pokemon: PokemonSpecies, valid: BooleanHolder): boolean { - if (!defaultStarterSpecies.includes(pokemon.speciesId)) { + if ( + (this.value === 1 && !defaultStarterSpecies.includes(pokemon.speciesId)) || + (this.value === 2 && getEggTierForSpecies(pokemon) >= EggTier.EPIC) + ) { valid.value = false; return true; } @@ -695,15 +700,12 @@ export class FreshStartChallenge extends Challenge { } applyStarterCost(species: SpeciesId, cost: NumberHolder): boolean { - if (defaultStarterSpecies.includes(species)) { - cost.value = speciesStarterCosts[species]; - return true; - } - return false; + cost.value = speciesStarterCosts[species]; + return true; } applyStarterModify(pokemon: Pokemon): boolean { - pokemon.abilityIndex = 0; // Always base ability, not hidden ability + pokemon.abilityIndex = pokemon.abilityIndex % 2; // Always base ability, if you set it to hidden it wraps to first ability pokemon.passive = false; // Passive isn't unlocked pokemon.nature = Nature.HARDY; // Neutral nature pokemon.moveset = pokemon.species @@ -715,7 +717,22 @@ export class FreshStartChallenge extends Challenge { pokemon.luck = 0; // No luck pokemon.shiny = false; // Not shiny pokemon.variant = 0; // Not shiny - pokemon.formIndex = 0; // Froakie should be base form + if (pokemon.species.speciesId === SpeciesId.ZYGARDE && pokemon.formIndex >= 2) { + pokemon.formIndex -= 2; // Sets 10%-PC to 10%-AB and 50%-PC to 50%-AB + } else if ( + pokemon.formIndex > 0 && + [ + SpeciesId.PIKACHU, + SpeciesId.EEVEE, + SpeciesId.PICHU, + SpeciesId.ROTOM, + SpeciesId.MELOETTA, + SpeciesId.FROAKIE, + SpeciesId.ROCKRUFF, + ].includes(pokemon.species.speciesId) + ) { + pokemon.formIndex = 0; // These mons are set to form 0 because they're meant to be unlocks or mid-run form changes + } pokemon.ivs = [15, 15, 15, 15, 15, 15]; // Default IVs of 15 for all stats (Updated to 15 from 10 in 1.2.0) pokemon.teraType = pokemon.species.type1; // Always primary tera type return true; diff --git a/src/system/achv.ts b/src/system/achv.ts index abe6f264d20..69eade02e35 100644 --- a/src/system/achv.ts +++ b/src/system/achv.ts @@ -890,7 +890,7 @@ export const achvs = { 100, c => c instanceof FreshStartChallenge && - c.value > 0 && + c.value === 1 && !globalScene.gameMode.challenges.some( c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0, ), From c92b895946825d1a552224810629927296614d12 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Mon, 28 Jul 2025 14:43:36 -0400 Subject: [PATCH 41/76] [Dev] Add `workflow-dispatch` trigger to tests github workflow (#6152) Add `workflow-dispatch` trigger to github workflow Co-authored-by: damocleas --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d3dd23eb379..764a35ace60 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,6 +11,7 @@ on: - beta merge_group: types: [checks_requested] + workflow_dispatch: jobs: check-path-change-filter: From 48db9491c6a61eb871b7dc591c427a44a824b277 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Mon, 28 Jul 2025 14:51:43 -0400 Subject: [PATCH 42/76] [Test] Add support for custom boilerplates to `create-test.js` (#6158) * Added support for custom boilerplates to test:create script * Added support for custom boilerplates to create-test.js * Fixed syntax error * Update create-test.js Co-authored-by: Amani H. <109637146+xsn34kzx@users.noreply.github.com> * Fix pluralization error in `create-test.js` --------- Co-authored-by: Amani H. <109637146+xsn34kzx@users.noreply.github.com> --- .../default.ts} | 0 scripts/create-test/create-test.js | 107 +++++++++++------- 2 files changed, 63 insertions(+), 44 deletions(-) rename scripts/create-test/{test-boilerplate.ts => boilerplates/default.ts} (100%) diff --git a/scripts/create-test/test-boilerplate.ts b/scripts/create-test/boilerplates/default.ts similarity index 100% rename from scripts/create-test/test-boilerplate.ts rename to scripts/create-test/boilerplates/default.ts diff --git a/scripts/create-test/create-test.js b/scripts/create-test/create-test.js index c0f27f8891e..765993959d1 100644 --- a/scripts/create-test/create-test.js +++ b/scripts/create-test/create-test.js @@ -17,15 +17,20 @@ const version = "2.0.1"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const projectRoot = path.join(__dirname, "..", ".."); -const boilerplateFilePath = path.join(__dirname, "test-boilerplate.ts"); -const choices = [ - { label: "Move", dir: "moves" }, - { label: "Ability", dir: "abilities" }, - { label: "Item", dir: "items" }, - { label: "Mystery Encounter", dir: "mystery-encounter/encounters" }, - { label: "Utils", dir: "utils" }, - { label: "UI", dir: "ui" }, -]; + +const choices = /** @type {const} */ (["Move", "Ability", "Item", "Reward", "Mystery Encounter", "Utils", "UI"]); +/** @typedef {choices[number]} choiceType */ + +/** @satisfies {{[k in choiceType]: string}} */ +const choicesToDirs = /** @type {const} */ ({ + Move: "moves", + Ability: "abilities", + Item: "items", + Reward: "rewards", + "Mystery Encounter": "mystery-encounter/encounters", + Utils: "utils", + UI: "ui", +}); //#endregion //#region Functions @@ -41,48 +46,47 @@ function getTestFolderPath(...folders) { /** * Prompts the user to select a type via list. - * @returns {Promise<{selectedOption: {label: string, dir: string}}>} the selected type + * @returns {Promise} the selected type */ async function promptTestType() { - const typeAnswer = await inquirer + /** @type {choiceType | "EXIT"} */ + const choice = await inquirer .prompt([ { type: "list", name: "selectedOption", message: "What type of test would you like to create?", - choices: [...choices.map(choice => ({ name: choice.label, value: choice })), { name: "EXIT", value: "N/A" }], + choices: [...choices, "EXIT"], }, ]) - .then(ans => ans.selectedOption); + .then(ta => ta.selectedOption); - if (typeAnswer.name === "EXIT") { + if (choice === "EXIT") { console.log("Exiting..."); return process.exit(0); } - if (!choices.some(choice => choice.dir === typeAnswer.dir)) { - console.error(`Please provide a valid type: (${choices.map(choice => choice.label).join(", ")})!`); - return await promptTestType(); - } - return typeAnswer; + return choice; } /** * Prompts the user to provide a file name. - * @param {string} selectedType - * @returns {Promise<{userInput: string}>} the selected file name + * @param {choiceType} selectedType The chosen string (used to display console logs) + * @returns {Promise} the selected file name */ async function promptFileName(selectedType) { - /** @type {{userInput: string}} */ - const fileNameAnswer = await inquirer.prompt([ - { - type: "input", - name: "userInput", - message: `Please provide the name of the ${selectedType}:`, - }, - ]); + /** @type {string} */ + const fileNameAnswer = await inquirer + .prompt([ + { + type: "input", + name: "userInput", + message: `Please provide the name of the ${selectedType}.`, + }, + ]) + .then(fa => fa.userInput); - if (!fileNameAnswer.userInput || fileNameAnswer.userInput.trim().length === 0) { + if (fileNameAnswer.trim().length === 0) { console.error("Please provide a valid file name!"); return await promptFileName(selectedType); } @@ -90,51 +94,66 @@ async function promptFileName(selectedType) { return fileNameAnswer; } +/** + * Obtain the path to the boilerplate file based on the current option. + * @param {choiceType} choiceType The choice selected + * @returns {string} The path to the boilerplate file + */ +function getBoilerplatePath(choiceType) { + switch (choiceType) { + // case "Reward": + // return path.join(__dirname, "boilerplates/reward.ts"); + default: + return path.join(__dirname, "boilerplates/default.ts"); + } +} + /** * Runs the interactive test:create "CLI" * @returns {Promise} */ async function runInteractive() { - console.group(chalk.grey(`Create Test - v${version}\n`)); + console.group(chalk.grey(`🧪 Create Test - v${version}\n`)); try { - const typeAnswer = await promptTestType(); - const fileNameAnswer = await promptFileName(typeAnswer.selectedOption.label); + const choice = await promptTestType(); + const fileNameAnswer = await promptFileName(choice); - const type = typeAnswer.selectedOption; // Convert fileName from snake_case or camelCase to kebab-case - const fileName = fileNameAnswer.userInput + const fileName = fileNameAnswer .replace(/_+/g, "-") // Convert snake_case (underscore) to kebab-case (dashes) .replace(/([a-z])([A-Z])/g, "$1-$2") // Convert camelCase to kebab-case .replace(/\s+/g, "-") // Replace spaces with dashes .toLowerCase(); // Ensure all lowercase - // Format the description for the test case + // Format the description for the test case in Title Case const formattedName = fileName.replace(/-/g, " ").replace(/\b\w/g, char => char.toUpperCase()); + const description = `${choice} - ${formattedName}`; + // Determine the directory based on the type - const dir = getTestFolderPath(type.dir); - const description = `${type.label} - ${formattedName}`; + const localDir = choicesToDirs[choice]; + const absoluteDir = getTestFolderPath(localDir); // Define the content template - const content = fs.readFileSync(boilerplateFilePath, "utf8").replace("{{description}}", description); + const content = fs.readFileSync(getBoilerplatePath(choice), "utf8").replace("{{description}}", description); // Ensure the directory exists - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true }); + if (!fs.existsSync(absoluteDir)) { + fs.mkdirSync(absoluteDir, { recursive: true }); } // Create the file with the given name - const filePath = path.join(dir, `${fileName}.test.ts`); + const filePath = path.join(absoluteDir, `${fileName}.test.ts`); if (fs.existsSync(filePath)) { - console.error(chalk.red.bold(`\n✗ File "${fileName}.test.ts" already exists!\n`)); + console.error(chalk.red.bold(`✗ File "${fileName}.test.ts" already exists!\n`)); process.exit(1); } // Write the template content to the file fs.writeFileSync(filePath, content, "utf8"); - console.log(chalk.green.bold(`\n✔ File created at: test/${type.dir}/${fileName}.test.ts\n`)); + console.log(chalk.green.bold(`✔ File created at: test/${localDir}/${fileName}.test.ts\n`)); console.groupEnd(); } catch (err) { console.error(chalk.red("✗ Error: ", err.message)); From 0517d5704aa63f09a92002ba06e4f95e0c8939d2 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 28 Jul 2025 20:13:10 -0600 Subject: [PATCH 43/76] [Refactor] Mark nickname in pokemon as optional (#6168) Mark nickname in pokemon as optional --- src/@types/illusion-data.ts | 2 +- src/field/pokemon.ts | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/@types/illusion-data.ts b/src/@types/illusion-data.ts index b152e3fdf59..5bf86d23ac2 100644 --- a/src/@types/illusion-data.ts +++ b/src/@types/illusion-data.ts @@ -11,7 +11,7 @@ export interface IllusionData { /** The name of pokemon featured in the illusion */ name: string; /** The nickname of the pokemon featured in the illusion */ - nickname: string; + nickname?: string; /** Whether the pokemon featured in the illusion is shiny or not */ shiny: boolean; /** The variant of the pokemon featured in the illusion */ diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index fd04c007e1b..7aecc0c8e75 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -213,7 +213,11 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { * TODO: Stop treating this like a unique ID and stop treating 0 as no pokemon */ public id: number; - public nickname: string; + /** + * The Pokemon's current nickname, or `undefined` if it currently lacks one. + * If omitted, references to this should refer to the default name for this Pokemon's species. + */ + public nickname?: string; public species: PokemonSpecies; public formIndex: number; public abilityIndex: number; @@ -443,7 +447,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { getNameToRender(useIllusion = true) { const illusion = this.summonData.illusion; const name = useIllusion ? (illusion?.name ?? this.name) : this.name; - const nickname: string = useIllusion ? (illusion?.nickname ?? this.nickname) : this.nickname; + const nickname: string | undefined = useIllusion ? illusion?.nickname : this.nickname; try { if (nickname) { return decodeURIComponent(escape(atob(nickname))); // TODO: Remove `atob` and `escape`... eventually... From 9f74bfff943190e365b6900dc6bb9211f711ac62 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Tue, 29 Jul 2025 08:59:41 -0700 Subject: [PATCH 44/76] [Dev] Update Vite from 6.3.5 to 7.0.6 (#6163) --- package.json | 8 +- pnpm-lock.yaml | 918 ++++++++++++++++++++++--------------------------- 2 files changed, 418 insertions(+), 508 deletions(-) diff --git a/package.json b/package.json index 02d063389b7..71a8b1ae334 100644 --- a/package.json +++ b/package.json @@ -30,19 +30,19 @@ "@biomejs/biome": "2.0.0", "@ls-lint/ls-lint": "2.3.1", "@types/jsdom": "^21.1.7", - "@types/node": "^22.16.3", + "@types/node": "^22.16.5", "@vitest/coverage-istanbul": "^3.2.4", "@vitest/expect": "^3.2.4", "chalk": "^5.4.1", "dependency-cruiser": "^16.10.4", - "inquirer": "^12.7.0", + "inquirer": "^12.8.2", "jsdom": "^26.1.0", "lefthook": "^1.12.2", "msw": "^2.10.4", "phaser3spectorjs": "^0.0.8", - "typedoc": "^0.28.7", + "typedoc": "^0.28.8", "typescript": "^5.8.3", - "vite": "^6.3.5", + "vite": "^7.0.6", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.2.4", "vitest-canvas-mock": "^0.3.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 86a7bb904a1..900be6fd76e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -52,11 +52,11 @@ importers: specifier: ^21.1.7 version: 21.1.7 '@types/node': - specifier: ^22.16.3 - version: 22.16.3 + specifier: ^22.16.5 + version: 22.16.5 '@vitest/coverage-istanbul': specifier: ^3.2.4 - version: 3.2.4(vitest@3.2.4(@types/node@22.16.3)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.3)(typescript@5.8.3))(yaml@2.8.0)) + version: 3.2.4(vitest@3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.0)) '@vitest/expect': specifier: ^3.2.4 version: 3.2.4 @@ -67,8 +67,8 @@ importers: specifier: ^16.10.4 version: 16.10.4 inquirer: - specifier: ^12.7.0 - version: 12.7.0(@types/node@22.16.3) + specifier: ^12.8.2 + version: 12.8.2(@types/node@22.16.5) jsdom: specifier: ^26.1.0 version: 26.1.0 @@ -77,28 +77,28 @@ importers: version: 1.12.2 msw: specifier: ^2.10.4 - version: 2.10.4(@types/node@22.16.3)(typescript@5.8.3) + version: 2.10.4(@types/node@22.16.5)(typescript@5.8.3) phaser3spectorjs: specifier: ^0.0.8 version: 0.0.8 typedoc: - specifier: ^0.28.7 - version: 0.28.7(typescript@5.8.3) + specifier: ^0.28.8 + version: 0.28.8(typescript@5.8.3) typescript: specifier: ^5.8.3 version: 5.8.3 vite: - specifier: ^6.3.5 - version: 6.3.5(@types/node@22.16.3)(yaml@2.8.0) + specifier: ^7.0.6 + version: 7.0.6(@types/node@22.16.5)(yaml@2.8.0) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.16.3)(yaml@2.8.0)) + version: 5.1.4(typescript@5.8.3)(vite@7.0.6(@types/node@22.16.5)(yaml@2.8.0)) vitest: specifier: ^3.2.4 - version: 3.2.4(@types/node@22.16.3)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.3)(typescript@5.8.3))(yaml@2.8.0) + version: 3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.0) vitest-canvas-mock: specifier: ^0.3.3 - version: 0.3.3(vitest@3.2.4(@types/node@22.16.3)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.3)(typescript@5.8.3))(yaml@2.8.0)) + version: 0.3.3(vitest@3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.0)) packages: @@ -155,8 +155,8 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.27.6': - resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} + '@babel/helpers@7.28.2': + resolution: {integrity: sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==} engines: {node: '>=6.9.0'} '@babel/parser@7.28.0': @@ -164,8 +164,8 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/runtime@7.27.6': - resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} + '@babel/runtime@7.28.2': + resolution: {integrity: sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==} engines: {node: '>=6.9.0'} '@babel/template@7.27.2': @@ -176,8 +176,8 @@ packages: resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.1': - resolution: {integrity: sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==} + '@babel/types@7.28.2': + resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} engines: {node: '>=6.9.0'} '@biomejs/biome@2.0.0': @@ -270,167 +270,167 @@ packages: resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} engines: {node: '>=18'} - '@esbuild/aix-ppc64@0.25.6': - resolution: {integrity: sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==} + '@esbuild/aix-ppc64@0.25.8': + resolution: {integrity: sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.6': - resolution: {integrity: sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==} + '@esbuild/android-arm64@0.25.8': + resolution: {integrity: sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.6': - resolution: {integrity: sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==} + '@esbuild/android-arm@0.25.8': + resolution: {integrity: sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.6': - resolution: {integrity: sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==} + '@esbuild/android-x64@0.25.8': + resolution: {integrity: sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.6': - resolution: {integrity: sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==} + '@esbuild/darwin-arm64@0.25.8': + resolution: {integrity: sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.6': - resolution: {integrity: sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==} + '@esbuild/darwin-x64@0.25.8': + resolution: {integrity: sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.6': - resolution: {integrity: sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==} + '@esbuild/freebsd-arm64@0.25.8': + resolution: {integrity: sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.6': - resolution: {integrity: sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==} + '@esbuild/freebsd-x64@0.25.8': + resolution: {integrity: sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.6': - resolution: {integrity: sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==} + '@esbuild/linux-arm64@0.25.8': + resolution: {integrity: sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.6': - resolution: {integrity: sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==} + '@esbuild/linux-arm@0.25.8': + resolution: {integrity: sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.6': - resolution: {integrity: sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==} + '@esbuild/linux-ia32@0.25.8': + resolution: {integrity: sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.6': - resolution: {integrity: sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==} + '@esbuild/linux-loong64@0.25.8': + resolution: {integrity: sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.6': - resolution: {integrity: sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==} + '@esbuild/linux-mips64el@0.25.8': + resolution: {integrity: sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.6': - resolution: {integrity: sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==} + '@esbuild/linux-ppc64@0.25.8': + resolution: {integrity: sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.6': - resolution: {integrity: sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==} + '@esbuild/linux-riscv64@0.25.8': + resolution: {integrity: sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.6': - resolution: {integrity: sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==} + '@esbuild/linux-s390x@0.25.8': + resolution: {integrity: sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.6': - resolution: {integrity: sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==} + '@esbuild/linux-x64@0.25.8': + resolution: {integrity: sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.6': - resolution: {integrity: sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==} + '@esbuild/netbsd-arm64@0.25.8': + resolution: {integrity: sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.6': - resolution: {integrity: sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==} + '@esbuild/netbsd-x64@0.25.8': + resolution: {integrity: sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.6': - resolution: {integrity: sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==} + '@esbuild/openbsd-arm64@0.25.8': + resolution: {integrity: sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.6': - resolution: {integrity: sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==} + '@esbuild/openbsd-x64@0.25.8': + resolution: {integrity: sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.6': - resolution: {integrity: sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA==} + '@esbuild/openharmony-arm64@0.25.8': + resolution: {integrity: sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.25.6': - resolution: {integrity: sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==} + '@esbuild/sunos-x64@0.25.8': + resolution: {integrity: sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.6': - resolution: {integrity: sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==} + '@esbuild/win32-arm64@0.25.8': + resolution: {integrity: sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.6': - resolution: {integrity: sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==} + '@esbuild/win32-ia32@0.25.8': + resolution: {integrity: sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.6': - resolution: {integrity: sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==} + '@esbuild/win32-x64@0.25.8': + resolution: {integrity: sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@gerrit0/mini-shiki@3.7.0': - resolution: {integrity: sha512-7iY9wg4FWXmeoFJpUL2u+tsmh0d0jcEJHAIzVxl3TG4KL493JNnisdLAILZ77zcD+z3J0keEXZ+lFzUgzQzPDg==} + '@gerrit0/mini-shiki@3.8.1': + resolution: {integrity: sha512-HVZW+8pxoOExr5ZMPK15U79jQAZTO/S6i5byQyyZGjtNj+qaYd82cizTncwFzTQgiLo8uUBym6vh+/1tfJklTw==} - '@inquirer/checkbox@4.1.9': - resolution: {integrity: sha512-DBJBkzI5Wx4jFaYm221LHvAhpKYkhVS0k9plqHwaHhofGNxvYB7J3Bz8w+bFJ05zaMb0sZNHo4KdmENQFlNTuQ==} + '@inquirer/checkbox@4.2.0': + resolution: {integrity: sha512-fdSw07FLJEU5vbpOPzXo5c6xmMGDzbZE2+niuDHX5N6mc6V0Ebso/q3xiHra4D73+PMsC8MJmcaZKuAAoaQsSA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -438,8 +438,8 @@ packages: '@types/node': optional: true - '@inquirer/confirm@5.1.13': - resolution: {integrity: sha512-EkCtvp67ICIVVzjsquUiVSd+V5HRGOGQfsqA4E4vMWhYnB7InUL0pa0TIWt1i+OfP16Gkds8CdIu6yGZwOM1Yw==} + '@inquirer/confirm@5.1.14': + resolution: {integrity: sha512-5yR4IBfe0kXe59r1YCTG8WXkUbl7Z35HK87Sw+WUyGD8wNUx7JvY7laahzeytyE1oLn74bQnL7hstctQxisQ8Q==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -447,8 +447,8 @@ packages: '@types/node': optional: true - '@inquirer/core@10.1.14': - resolution: {integrity: sha512-Ma+ZpOJPewtIYl6HZHZckeX1STvDnHTCB2GVINNUlSEn2Am6LddWwfPkIGY0IUFVjUUrr/93XlBwTK6mfLjf0A==} + '@inquirer/core@10.1.15': + resolution: {integrity: sha512-8xrp836RZvKkpNbVvgWUlxjT4CraKk2q+I3Ksy+seI2zkcE+y6wNs1BVhgcv8VyImFecUhdQrYLdW32pAjwBdA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -456,8 +456,8 @@ packages: '@types/node': optional: true - '@inquirer/editor@4.2.14': - resolution: {integrity: sha512-yd2qtLl4QIIax9DTMZ1ZN2pFrrj+yL3kgIWxm34SS6uwCr0sIhsNyudUjAo5q3TqI03xx4SEBkUJqZuAInp9uA==} + '@inquirer/editor@4.2.15': + resolution: {integrity: sha512-wst31XT8DnGOSS4nNJDIklGKnf+8shuauVrWzgKegWUe28zfCftcWZ2vktGdzJgcylWSS2SrDnYUb6alZcwnCQ==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -465,8 +465,8 @@ packages: '@types/node': optional: true - '@inquirer/expand@4.0.16': - resolution: {integrity: sha512-oiDqafWzMtofeJyyGkb1CTPaxUkjIcSxePHHQCfif8t3HV9pHcw1Kgdw3/uGpDvaFfeTluwQtWiqzPVjAqS3zA==} + '@inquirer/expand@4.0.17': + resolution: {integrity: sha512-PSqy9VmJx/VbE3CT453yOfNa+PykpKg/0SYP7odez1/NWBGuDXgPhp4AeGYYKjhLn5lUUavVS/JbeYMPdH50Mw==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -474,12 +474,12 @@ packages: '@types/node': optional: true - '@inquirer/figures@1.0.12': - resolution: {integrity: sha512-MJttijd8rMFcKJC8NYmprWr6hD3r9Gd9qUC0XwPNwoEPWSMVJwA2MlXxF+nhZZNMY+HXsWa+o7KY2emWYIn0jQ==} + '@inquirer/figures@1.0.13': + resolution: {integrity: sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==} engines: {node: '>=18'} - '@inquirer/input@4.2.0': - resolution: {integrity: sha512-opqpHPB1NjAmDISi3uvZOTrjEEU5CWVu/HBkDby8t93+6UxYX0Z7Ps0Ltjm5sZiEbWenjubwUkivAEYQmy9xHw==} + '@inquirer/input@4.2.1': + resolution: {integrity: sha512-tVC+O1rBl0lJpoUZv4xY+WGWY8V5b0zxU1XDsMsIHYregdh7bN5X5QnIONNBAl0K765FYlAfNHS2Bhn7SSOVow==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -487,8 +487,8 @@ packages: '@types/node': optional: true - '@inquirer/number@3.0.16': - resolution: {integrity: sha512-kMrXAaKGavBEoBYUCgualbwA9jWUx2TjMA46ek+pEKy38+LFpL9QHlTd8PO2kWPUgI/KB+qi02o4y2rwXbzr3Q==} + '@inquirer/number@3.0.17': + resolution: {integrity: sha512-GcvGHkyIgfZgVnnimURdOueMk0CztycfC8NZTiIY9arIAkeOgt6zG57G+7vC59Jns3UX27LMkPKnKWAOF5xEYg==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -496,8 +496,8 @@ packages: '@types/node': optional: true - '@inquirer/password@4.0.16': - resolution: {integrity: sha512-g8BVNBj5Zeb5/Y3cSN+hDUL7CsIFDIuVxb9EPty3lkxBaYpjL5BNRKSYOF9yOLe+JOcKFd+TSVeADQ4iSY7rbg==} + '@inquirer/password@4.0.17': + resolution: {integrity: sha512-DJolTnNeZ00E1+1TW+8614F7rOJJCM4y4BAGQ3Gq6kQIG+OJ4zr3GLjIjVVJCbKsk2jmkmv6v2kQuN/vriHdZA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -505,8 +505,8 @@ packages: '@types/node': optional: true - '@inquirer/prompts@7.6.0': - resolution: {integrity: sha512-jAhL7tyMxB3Gfwn4HIJ0yuJ5pvcB5maYUcouGcgd/ub79f9MqZ+aVnBtuFf+VC2GTkCBF+R+eo7Vi63w5VZlzw==} + '@inquirer/prompts@7.7.1': + resolution: {integrity: sha512-XDxPrEWeWUBy8scAXzXuFY45r/q49R0g72bUzgQXZ1DY/xEFX+ESDMkTQolcb5jRBzaNJX2W8XQl6krMNDTjaA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -514,8 +514,8 @@ packages: '@types/node': optional: true - '@inquirer/rawlist@4.1.4': - resolution: {integrity: sha512-5GGvxVpXXMmfZNtvWw4IsHpR7RzqAR624xtkPd1NxxlV5M+pShMqzL4oRddRkg8rVEOK9fKdJp1jjVML2Lr7TQ==} + '@inquirer/rawlist@4.1.5': + resolution: {integrity: sha512-R5qMyGJqtDdi4Ht521iAkNqyB6p2UPuZUbMifakg1sWtu24gc2Z8CJuw8rP081OckNDMgtDCuLe42Q2Kr3BolA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -523,8 +523,8 @@ packages: '@types/node': optional: true - '@inquirer/search@3.0.16': - resolution: {integrity: sha512-POCmXo+j97kTGU6aeRjsPyuCpQQfKcMXdeTMw708ZMtWrj5aykZvlUxH4Qgz3+Y1L/cAVZsSpA+UgZCu2GMOMg==} + '@inquirer/search@3.0.17': + resolution: {integrity: sha512-CuBU4BAGFqRYors4TNCYzy9X3DpKtgIW4Boi0WNkm4Ei1hvY9acxKdBdyqzqBCEe4YxSdaQQsasJlFlUJNgojw==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -532,8 +532,8 @@ packages: '@types/node': optional: true - '@inquirer/select@4.2.4': - resolution: {integrity: sha512-unTppUcTjmnbl/q+h8XeQDhAqIOmwWYWNyiiP2e3orXrg6tOaa5DHXja9PChCSbChOsktyKgOieRZFnajzxoBg==} + '@inquirer/select@4.3.1': + resolution: {integrity: sha512-Gfl/5sqOF5vS/LIrSndFgOh7jgoe0UXEizDqahFRkq5aJBLegZ6WjuMh/hVEJwlFQjyLq1z9fRtvUMkb7jM1LA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -541,8 +541,8 @@ packages: '@types/node': optional: true - '@inquirer/type@3.0.7': - resolution: {integrity: sha512-PfunHQcjwnju84L+ycmcMKB/pTPIngjUJvfnRhKY6FKPuYXlM4aQCb/nIdTFR6BEhMjFvngzvng/vBAJMZpLSA==} + '@inquirer/type@3.0.8': + resolution: {integrity: sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -580,8 +580,8 @@ packages: '@material/material-color-utilities@0.2.7': resolution: {integrity: sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==} - '@mswjs/interceptors@0.39.2': - resolution: {integrity: sha512-RuzCup9Ct91Y7V79xwCb146RaBRHZ7NBbrIUySumd1rpKqHL5OonaqrGIbug5hNwP/fRyxFMA6ISgw4FTtYFYg==} + '@mswjs/interceptors@0.39.4': + resolution: {integrity: sha512-B82DbrGVCIBrNEfRJbqUFB0eNz0wVzqbenEpmbE71XLVU4yKZbDnRBuxz+7udc/uM7LDWDD4sRJ5tISzHf2QkQ==} engines: {node: '>=18'} '@open-draft/deferred-promise@2.2.0': @@ -593,161 +593,121 @@ packages: '@open-draft/until@2.1.0': resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@oxlint/darwin-arm64@1.6.0': - resolution: {integrity: sha512-m3wyqBh1TOHjpr/dXeIZY7OoX+MQazb+bMHQdDtwUvefrafUx+5YHRvulYh1sZSQ449nQ3nk3qj5qj535vZRjg==} - cpu: [arm64] - os: [darwin] - - '@oxlint/darwin-x64@1.6.0': - resolution: {integrity: sha512-75fJfF/9xNypr7cnOYoZBhfmG1yP7ex3pUOeYGakmtZRffO9z1i1quLYhjZsmaDXsAIZ3drMhenYHMmFKS3SRg==} - cpu: [x64] - os: [darwin] - - '@oxlint/linux-arm64-gnu@1.6.0': - resolution: {integrity: sha512-YhXGf0FXa72bEt4F7eTVKx5X3zWpbAOPnaA/dZ6/g8tGhw1m9IFjrabVHFjzcx3dQny4MgA59EhyElkDvpUe8A==} - cpu: [arm64] - os: [linux] - - '@oxlint/linux-arm64-musl@1.6.0': - resolution: {integrity: sha512-T3JDhx8mjGjvh5INsPZJrlKHmZsecgDYvtvussKRdkc1Nnn7WC+jH9sh5qlmYvwzvmetlPVNezAoNvmGO9vtMg==} - cpu: [arm64] - os: [linux] - - '@oxlint/linux-x64-gnu@1.6.0': - resolution: {integrity: sha512-Dx7ghtAl8aXBdqofJpi338At6lkeCtTfoinTYQXd9/TEJx+f+zCGNlQO6nJz3ydJBX48FDuOFKkNC+lUlWrd8w==} - cpu: [x64] - os: [linux] - - '@oxlint/linux-x64-musl@1.6.0': - resolution: {integrity: sha512-7KvMGdWmAZtAtg6IjoEJHKxTXdAcrHnUnqfgs0JpXst7trquV2mxBeRZusQXwxpu4HCSomKMvJfsp1qKaqSFDg==} - cpu: [x64] - os: [linux] - - '@oxlint/win32-arm64@1.6.0': - resolution: {integrity: sha512-iSGC9RwX+dl7o5KFr5aH7Gq3nFbkq/3Gda6mxNPMvNkWrgXdIyiINxpyD8hJu566M+QSv1wEAu934BZotFDyoQ==} - cpu: [arm64] - os: [win32] - - '@oxlint/win32-x64@1.6.0': - resolution: {integrity: sha512-jOj3L/gfLc0IwgOTkZMiZ5c673i/hbAmidlaylT0gE6H18hln9HxPgp5GCf4E4y6mwEJlW8QC5hQi221+9otdA==} - cpu: [x64] - os: [win32] - '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@rollup/rollup-android-arm-eabi@4.45.0': - resolution: {integrity: sha512-2o/FgACbji4tW1dzXOqAV15Eu7DdgbKsF2QKcxfG4xbh5iwU7yr5RRP5/U+0asQliSYv5M4o7BevlGIoSL0LXg==} + '@rollup/rollup-android-arm-eabi@4.46.1': + resolution: {integrity: sha512-oENme6QxtLCqjChRUUo3S6X8hjCXnWmJWnedD7VbGML5GUtaOtAyx+fEEXnBXVf0CBZApMQU0Idwi0FmyxzQhw==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.45.0': - resolution: {integrity: sha512-PSZ0SvMOjEAxwZeTx32eI/j5xSYtDCRxGu5k9zvzoY77xUNssZM+WV6HYBLROpY5CkXsbQjvz40fBb7WPwDqtQ==} + '@rollup/rollup-android-arm64@4.46.1': + resolution: {integrity: sha512-OikvNT3qYTl9+4qQ9Bpn6+XHM+ogtFadRLuT2EXiFQMiNkXFLQfNVppi5o28wvYdHL2s3fM0D/MZJ8UkNFZWsw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.45.0': - resolution: {integrity: sha512-BA4yPIPssPB2aRAWzmqzQ3y2/KotkLyZukVB7j3psK/U3nVJdceo6qr9pLM2xN6iRP/wKfxEbOb1yrlZH6sYZg==} + '@rollup/rollup-darwin-arm64@4.46.1': + resolution: {integrity: sha512-EFYNNGij2WllnzljQDQnlFTXzSJw87cpAs4TVBAWLdkvic5Uh5tISrIL6NRcxoh/b2EFBG/TK8hgRrGx94zD4A==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.45.0': - resolution: {integrity: sha512-Pr2o0lvTwsiG4HCr43Zy9xXrHspyMvsvEw4FwKYqhli4FuLE5FjcZzuQ4cfPe0iUFCvSQG6lACI0xj74FDZKRA==} + '@rollup/rollup-darwin-x64@4.46.1': + resolution: {integrity: sha512-ZaNH06O1KeTug9WI2+GRBE5Ujt9kZw4a1+OIwnBHal92I8PxSsl5KpsrPvthRynkhMck4XPdvY0z26Cym/b7oA==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.45.0': - resolution: {integrity: sha512-lYE8LkE5h4a/+6VnnLiL14zWMPnx6wNbDG23GcYFpRW1V9hYWHAw9lBZ6ZUIrOaoK7NliF1sdwYGiVmziUF4vA==} + '@rollup/rollup-freebsd-arm64@4.46.1': + resolution: {integrity: sha512-n4SLVebZP8uUlJ2r04+g2U/xFeiQlw09Me5UFqny8HGbARl503LNH5CqFTb5U5jNxTouhRjai6qPT0CR5c/Iig==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.45.0': - resolution: {integrity: sha512-PVQWZK9sbzpvqC9Q0GlehNNSVHR+4m7+wET+7FgSnKG3ci5nAMgGmr9mGBXzAuE5SvguCKJ6mHL6vq1JaJ/gvw==} + '@rollup/rollup-freebsd-x64@4.46.1': + resolution: {integrity: sha512-8vu9c02F16heTqpvo3yeiu7Vi1REDEC/yES/dIfq3tSXe6mLndiwvYr3AAvd1tMNUqE9yeGYa5w7PRbI5QUV+w==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.45.0': - resolution: {integrity: sha512-hLrmRl53prCcD+YXTfNvXd776HTxNh8wPAMllusQ+amcQmtgo3V5i/nkhPN6FakW+QVLoUUr2AsbtIRPFU3xIA==} + '@rollup/rollup-linux-arm-gnueabihf@4.46.1': + resolution: {integrity: sha512-K4ncpWl7sQuyp6rWiGUvb6Q18ba8mzM0rjWJ5JgYKlIXAau1db7hZnR0ldJvqKWWJDxqzSLwGUhA4jp+KqgDtQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.45.0': - resolution: {integrity: sha512-XBKGSYcrkdiRRjl+8XvrUR3AosXU0NvF7VuqMsm7s5nRy+nt58ZMB19Jdp1RdqewLcaYnpk8zeVs/4MlLZEJxw==} + '@rollup/rollup-linux-arm-musleabihf@4.46.1': + resolution: {integrity: sha512-YykPnXsjUjmXE6j6k2QBBGAn1YsJUix7pYaPLK3RVE0bQL2jfdbfykPxfF8AgBlqtYbfEnYHmLXNa6QETjdOjQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.45.0': - resolution: {integrity: sha512-fRvZZPUiBz7NztBE/2QnCS5AtqLVhXmUOPj9IHlfGEXkapgImf4W9+FSkL8cWqoAjozyUzqFmSc4zh2ooaeF6g==} + '@rollup/rollup-linux-arm64-gnu@4.46.1': + resolution: {integrity: sha512-kKvqBGbZ8i9pCGW3a1FH3HNIVg49dXXTsChGFsHGXQaVJPLA4f/O+XmTxfklhccxdF5FefUn2hvkoGJH0ScWOA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.45.0': - resolution: {integrity: sha512-Btv2WRZOcUGi8XU80XwIvzTg4U6+l6D0V6sZTrZx214nrwxw5nAi8hysaXj/mctyClWgesyuxbeLylCBNauimg==} + '@rollup/rollup-linux-arm64-musl@4.46.1': + resolution: {integrity: sha512-zzX5nTw1N1plmqC9RGC9vZHFuiM7ZP7oSWQGqpbmfjK7p947D518cVK1/MQudsBdcD84t6k70WNczJOct6+hdg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.45.0': - resolution: {integrity: sha512-Li0emNnwtUZdLwHjQPBxn4VWztcrw/h7mgLyHiEI5Z0MhpeFGlzaiBHpSNVOMB/xucjXTTcO+dhv469Djr16KA==} + '@rollup/rollup-linux-loongarch64-gnu@4.46.1': + resolution: {integrity: sha512-O8CwgSBo6ewPpktFfSDgB6SJN9XDcPSvuwxfejiddbIC/hn9Tg6Ai0f0eYDf3XvB/+PIWzOQL+7+TZoB8p9Yuw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.45.0': - resolution: {integrity: sha512-sB8+pfkYx2kvpDCfd63d5ScYT0Fz1LO6jIb2zLZvmK9ob2D8DeVqrmBDE0iDK8KlBVmsTNzrjr3G1xV4eUZhSw==} + '@rollup/rollup-linux-ppc64-gnu@4.46.1': + resolution: {integrity: sha512-JnCfFVEKeq6G3h3z8e60kAp8Rd7QVnWCtPm7cxx+5OtP80g/3nmPtfdCXbVl063e3KsRnGSKDHUQMydmzc/wBA==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.45.0': - resolution: {integrity: sha512-5GQ6PFhh7E6jQm70p1aW05G2cap5zMOvO0se5JMecHeAdj5ZhWEHbJ4hiKpfi1nnnEdTauDXxPgXae/mqjow9w==} + '@rollup/rollup-linux-riscv64-gnu@4.46.1': + resolution: {integrity: sha512-dVxuDqS237eQXkbYzQQfdf/njgeNw6LZuVyEdUaWwRpKHhsLI+y4H/NJV8xJGU19vnOJCVwaBFgr936FHOnJsQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.45.0': - resolution: {integrity: sha512-N/euLsBd1rekWcuduakTo/dJw6U6sBP3eUq+RXM9RNfPuWTvG2w/WObDkIvJ2KChy6oxZmOSC08Ak2OJA0UiAA==} + '@rollup/rollup-linux-riscv64-musl@4.46.1': + resolution: {integrity: sha512-CvvgNl2hrZrTR9jXK1ye0Go0HQRT6ohQdDfWR47/KFKiLd5oN5T14jRdUVGF4tnsN8y9oSfMOqH6RuHh+ck8+w==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.45.0': - resolution: {integrity: sha512-2l9sA7d7QdikL0xQwNMO3xURBUNEWyHVHfAsHsUdq+E/pgLTUcCE+gih5PCdmyHmfTDeXUWVhqL0WZzg0nua3g==} + '@rollup/rollup-linux-s390x-gnu@4.46.1': + resolution: {integrity: sha512-x7ANt2VOg2565oGHJ6rIuuAon+A8sfe1IeUx25IKqi49OjSr/K3awoNqr9gCwGEJo9OuXlOn+H2p1VJKx1psxA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.45.0': - resolution: {integrity: sha512-XZdD3fEEQcwG2KrJDdEQu7NrHonPxxaV0/w2HpvINBdcqebz1aL+0vM2WFJq4DeiAVT6F5SUQas65HY5JDqoPw==} + '@rollup/rollup-linux-x64-gnu@4.46.1': + resolution: {integrity: sha512-9OADZYryz/7E8/qt0vnaHQgmia2Y0wrjSSn1V/uL+zw/i7NUhxbX4cHXdEQ7dnJgzYDS81d8+tf6nbIdRFZQoQ==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.45.0': - resolution: {integrity: sha512-7ayfgvtmmWgKWBkCGg5+xTQ0r5V1owVm67zTrsEY1008L5ro7mCyGYORomARt/OquB9KY7LpxVBZes+oSniAAQ==} + '@rollup/rollup-linux-x64-musl@4.46.1': + resolution: {integrity: sha512-NuvSCbXEKY+NGWHyivzbjSVJi68Xfq1VnIvGmsuXs6TCtveeoDRKutI5vf2ntmNnVq64Q4zInet0UDQ+yMB6tA==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.45.0': - resolution: {integrity: sha512-B+IJgcBnE2bm93jEW5kHisqvPITs4ddLOROAcOc/diBgrEiQJJ6Qcjby75rFSmH5eMGrqJryUgJDhrfj942apQ==} + '@rollup/rollup-win32-arm64-msvc@4.46.1': + resolution: {integrity: sha512-mWz+6FSRb82xuUMMV1X3NGiaPFqbLN9aIueHleTZCc46cJvwTlvIh7reQLk4p97dv0nddyewBhwzryBHH7wtPw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.45.0': - resolution: {integrity: sha512-+CXwwG66g0/FpWOnP/v1HnrGVSOygK/osUbu3wPRy8ECXjoYKjRAyfxYpDQOfghC5qPJYLPH0oN4MCOjwgdMug==} + '@rollup/rollup-win32-ia32-msvc@4.46.1': + resolution: {integrity: sha512-7Thzy9TMXDw9AU4f4vsLNBxh7/VOKuXi73VH3d/kHGr0tZ3x/ewgL9uC7ojUKmH1/zvmZe2tLapYcZllk3SO8Q==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.45.0': - resolution: {integrity: sha512-SRf1cytG7wqcHVLrBc9VtPK4pU5wxiB/lNIkNmW2ApKXIg+RpqwHfsaEK+e7eH4A1BpI6BX/aBWXxZCIrJg3uA==} + '@rollup/rollup-win32-x64-msvc@4.46.1': + resolution: {integrity: sha512-7GVB4luhFmGUNXXJhH2jJwZCFB3pIOixv2E3s17GQHBFUOQaISlt7aGcQgqvCaDSxTZJUzlK/QJ1FN8S94MrzQ==} cpu: [x64] os: [win32] - '@shikijs/engine-oniguruma@3.7.0': - resolution: {integrity: sha512-5BxcD6LjVWsGu4xyaBC5bu8LdNgPCVBnAkWTtOCs/CZxcB22L8rcoWfv7Hh/3WooVjBZmFtyxhgvkQFedPGnFw==} + '@shikijs/engine-oniguruma@3.8.1': + resolution: {integrity: sha512-KGQJZHlNY7c656qPFEQpIoqOuC4LrxjyNndRdzk5WKB/Ie87+NJCF1xo9KkOUxwxylk7rT6nhlZyTGTC4fCe1g==} - '@shikijs/langs@3.7.0': - resolution: {integrity: sha512-1zYtdfXLr9xDKLTGy5kb7O0zDQsxXiIsw1iIBcNOO8Yi5/Y1qDbJ+0VsFoqTlzdmneO8Ij35g7QKF8kcLyznCQ==} + '@shikijs/langs@3.8.1': + resolution: {integrity: sha512-TjOFg2Wp1w07oKnXjs0AUMb4kJvujML+fJ1C5cmEj45lhjbUXtziT1x2bPQb9Db6kmPhkG5NI2tgYW1/DzhUuQ==} - '@shikijs/themes@3.7.0': - resolution: {integrity: sha512-VJx8497iZPy5zLiiCTSIaOChIcKQwR0FebwE9S3rcN0+J/GTWwQ1v/bqhTbpbY3zybPKeO8wdammqkpXc4NVjQ==} + '@shikijs/themes@3.8.1': + resolution: {integrity: sha512-Vu3t3BBLifc0GB0UPg2Pox1naTemrrvyZv2lkiSw3QayVV60me1ujFQwPZGgUTmwXl1yhCPW8Lieesm0CYruLQ==} - '@shikijs/types@3.7.0': - resolution: {integrity: sha512-MGaLeaRlSWpnP0XSAum3kP3a8vtcTsITqoEPYdt3lQG3YCdQH4DnEhodkYcNMcU0uW0RffhoD1O3e0vG5eSBBg==} + '@shikijs/types@3.8.1': + resolution: {integrity: sha512-5C39Q8/8r1I26suLh+5TPk1DTrbY/kn3IdWA5HdizR0FhlhD05zx5nKCqhzSfDHH3p4S0ZefxWd77DLV+8FhGg==} '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} @@ -770,8 +730,8 @@ packages: '@types/jsdom@21.1.7': resolution: {integrity: sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==} - '@types/node@22.16.3': - resolution: {integrity: sha512-sr4Xz74KOUeYadexo1r8imhRtlVXcs+j3XK3TcoiYk7B1t3YRVJgtaD3cwX73NYb71pmVuMLNRhJ9XKdoDB74g==} + '@types/node@22.16.5': + resolution: {integrity: sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==} '@types/statuses@2.0.6': resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} @@ -1008,8 +968,8 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - electron-to-chromium@1.5.182: - resolution: {integrity: sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA==} + electron-to-chromium@1.5.191: + resolution: {integrity: sha512-xcwe9ELcuxYLUFqZZxL19Z6HVKcvNkIwhbHUz7L3us6u12yR+7uY89dSl570f/IqNthx8dAw3tojG7i4Ni4tDA==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1044,8 +1004,8 @@ packages: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} - esbuild@0.25.6: - resolution: {integrity: sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==} + esbuild@0.25.8: + resolution: {integrity: sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==} engines: {node: '>=18'} hasBin: true @@ -1229,8 +1189,8 @@ packages: resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - inquirer@12.7.0: - resolution: {integrity: sha512-KKFRc++IONSyE2UYw9CJ1V0IWx5yQKomwB+pp3cWomWs+v2+ZsG11G2OVfAjFS6WWCppKw+RfKmpqGfSzD5QBQ==} + inquirer@12.8.2: + resolution: {integrity: sha512-oBDL9f4+cDambZVJdfJu2M5JQfvaug9lbo6fKDlFV40i8t3FGA1Db67ov5Hp5DInG4zmXhHWTSnlXBntnJ7GMA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -1408,8 +1368,8 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - loupe@3.1.4: - resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} + loupe@3.2.0: + resolution: {integrity: sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==} lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -1501,8 +1461,8 @@ packages: node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - nwsapi@2.2.20: - resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} + nwsapi@2.2.21: + resolution: {integrity: sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==} object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} @@ -1518,11 +1478,6 @@ packages: outvariant@1.4.3: resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} - oxlint@1.6.0: - resolution: {integrity: sha512-jtaD65PqzIa1udvSxxscTKBxYKuZoFXyKGLiU1Qjo1ulq3uv/fQDtoV1yey1FrQZrQjACGPi1Widsy1TucC7Jg==} - engines: {node: '>=8.*'} - hasBin: true - package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} @@ -1568,19 +1523,14 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} - prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} - engines: {node: '>=14'} - hasBin: true - process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -1629,16 +1579,16 @@ packages: engines: {node: '>= 0.4'} hasBin: true - rollup@4.45.0: - resolution: {integrity: sha512-WLjEcJRIo7i3WDDgOIJqVI2d+lAC3EwvOGy+Xfq6hs+GQuAA4Di/H72xmXkOhrIWFg2PFYSKZYfH0f4vfKXN4A==} + rollup@4.46.1: + resolution: {integrity: sha512-33xGNBsDJAkzt0PvninskHlWnTIPgDtTwhg0U38CUoNP/7H6wI2Cz6dUeoNPbjdTdsYTGuiFFASuUOWovH0SyQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true rrweb-cssom@0.8.0: resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} - run-async@4.0.4: - resolution: {integrity: sha512-2cgeRHnV11lSXBEhq7sN7a5UVjTKm9JTb9x8ApIT//16D7QL96AgnNeWSGoB4gIHc0iYw/Ha0Z+waBaCYZVNhg==} + run-async@4.0.5: + resolution: {integrity: sha512-oN9GTgxUNDBumHTTDmQ8dep6VIJbgj9S3dPP+9XylVLIK4xB9XTXtKWROd5pnhdXR9k0EgO1JRcNh0T+Ny2FsA==} engines: {node: '>=0.12.0'} rxjs@7.8.2: @@ -1833,8 +1783,8 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - typedoc@0.28.7: - resolution: {integrity: sha512-lpz0Oxl6aidFkmS90VQDQjk/Qf2iw0IUvFqirdONBdj7jPSN9mGXhy66BcGNDxx5ZMyKKiBVAREvPEzT6Uxipw==} + typedoc@0.28.8: + resolution: {integrity: sha512-16GfLopc8icHfdvqZDqdGBoS2AieIRP2rpf9mU+MgN+gGLyEQvAO0QgOa6NJ5QNmQi0LFrDY9in4F2fUNKgJKA==} engines: {node: '>= 18', pnpm: '>= 10'} hasBin: true peerDependencies: @@ -1880,19 +1830,19 @@ packages: vite: optional: true - vite@6.3.5: - resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + vite@7.0.6: + resolution: {integrity: sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@types/node': ^20.19.0 || >=22.12.0 jiti: '>=1.21.0' - less: '*' + less: ^4.0.0 lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 yaml: ^2.4.2 @@ -2082,11 +2032,11 @@ snapshots: '@babel/generator': 7.28.0 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) - '@babel/helpers': 7.27.6 + '@babel/helpers': 7.28.2 '@babel/parser': 7.28.0 '@babel/template': 7.27.2 '@babel/traverse': 7.28.0 - '@babel/types': 7.28.1 + '@babel/types': 7.28.2 convert-source-map: 2.0.0 debug: 4.4.1 gensync: 1.0.0-beta.2 @@ -2098,7 +2048,7 @@ snapshots: '@babel/generator@7.28.0': dependencies: '@babel/parser': 7.28.0 - '@babel/types': 7.28.1 + '@babel/types': 7.28.2 '@jridgewell/gen-mapping': 0.3.12 '@jridgewell/trace-mapping': 0.3.29 jsesc: 3.1.0 @@ -2116,7 +2066,7 @@ snapshots: '@babel/helper-module-imports@7.27.1': dependencies: '@babel/traverse': 7.28.0 - '@babel/types': 7.28.1 + '@babel/types': 7.28.2 transitivePeerDependencies: - supports-color @@ -2135,22 +2085,22 @@ snapshots: '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.27.6': + '@babel/helpers@7.28.2': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.1 + '@babel/types': 7.28.2 '@babel/parser@7.28.0': dependencies: - '@babel/types': 7.28.1 + '@babel/types': 7.28.2 - '@babel/runtime@7.27.6': {} + '@babel/runtime@7.28.2': {} '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 '@babel/parser': 7.28.0 - '@babel/types': 7.28.1 + '@babel/types': 7.28.2 '@babel/traverse@7.28.0': dependencies: @@ -2159,12 +2109,12 @@ snapshots: '@babel/helper-globals': 7.28.0 '@babel/parser': 7.28.0 '@babel/template': 7.27.2 - '@babel/types': 7.28.1 + '@babel/types': 7.28.2 debug: 4.4.1 transitivePeerDependencies: - supports-color - '@babel/types@7.28.1': + '@babel/types@7.28.2': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 @@ -2237,113 +2187,113 @@ snapshots: '@csstools/css-tokenizer@3.0.4': {} - '@esbuild/aix-ppc64@0.25.6': + '@esbuild/aix-ppc64@0.25.8': optional: true - '@esbuild/android-arm64@0.25.6': + '@esbuild/android-arm64@0.25.8': optional: true - '@esbuild/android-arm@0.25.6': + '@esbuild/android-arm@0.25.8': optional: true - '@esbuild/android-x64@0.25.6': + '@esbuild/android-x64@0.25.8': optional: true - '@esbuild/darwin-arm64@0.25.6': + '@esbuild/darwin-arm64@0.25.8': optional: true - '@esbuild/darwin-x64@0.25.6': + '@esbuild/darwin-x64@0.25.8': optional: true - '@esbuild/freebsd-arm64@0.25.6': + '@esbuild/freebsd-arm64@0.25.8': optional: true - '@esbuild/freebsd-x64@0.25.6': + '@esbuild/freebsd-x64@0.25.8': optional: true - '@esbuild/linux-arm64@0.25.6': + '@esbuild/linux-arm64@0.25.8': optional: true - '@esbuild/linux-arm@0.25.6': + '@esbuild/linux-arm@0.25.8': optional: true - '@esbuild/linux-ia32@0.25.6': + '@esbuild/linux-ia32@0.25.8': optional: true - '@esbuild/linux-loong64@0.25.6': + '@esbuild/linux-loong64@0.25.8': optional: true - '@esbuild/linux-mips64el@0.25.6': + '@esbuild/linux-mips64el@0.25.8': optional: true - '@esbuild/linux-ppc64@0.25.6': + '@esbuild/linux-ppc64@0.25.8': optional: true - '@esbuild/linux-riscv64@0.25.6': + '@esbuild/linux-riscv64@0.25.8': optional: true - '@esbuild/linux-s390x@0.25.6': + '@esbuild/linux-s390x@0.25.8': optional: true - '@esbuild/linux-x64@0.25.6': + '@esbuild/linux-x64@0.25.8': optional: true - '@esbuild/netbsd-arm64@0.25.6': + '@esbuild/netbsd-arm64@0.25.8': optional: true - '@esbuild/netbsd-x64@0.25.6': + '@esbuild/netbsd-x64@0.25.8': optional: true - '@esbuild/openbsd-arm64@0.25.6': + '@esbuild/openbsd-arm64@0.25.8': optional: true - '@esbuild/openbsd-x64@0.25.6': + '@esbuild/openbsd-x64@0.25.8': optional: true - '@esbuild/openharmony-arm64@0.25.6': + '@esbuild/openharmony-arm64@0.25.8': optional: true - '@esbuild/sunos-x64@0.25.6': + '@esbuild/sunos-x64@0.25.8': optional: true - '@esbuild/win32-arm64@0.25.6': + '@esbuild/win32-arm64@0.25.8': optional: true - '@esbuild/win32-ia32@0.25.6': + '@esbuild/win32-ia32@0.25.8': optional: true - '@esbuild/win32-x64@0.25.6': + '@esbuild/win32-x64@0.25.8': optional: true - '@gerrit0/mini-shiki@3.7.0': + '@gerrit0/mini-shiki@3.8.1': dependencies: - '@shikijs/engine-oniguruma': 3.7.0 - '@shikijs/langs': 3.7.0 - '@shikijs/themes': 3.7.0 - '@shikijs/types': 3.7.0 + '@shikijs/engine-oniguruma': 3.8.1 + '@shikijs/langs': 3.8.1 + '@shikijs/themes': 3.8.1 + '@shikijs/types': 3.8.1 '@shikijs/vscode-textmate': 10.0.2 - '@inquirer/checkbox@4.1.9(@types/node@22.16.3)': + '@inquirer/checkbox@4.2.0(@types/node@22.16.5)': dependencies: - '@inquirer/core': 10.1.14(@types/node@22.16.3) - '@inquirer/figures': 1.0.12 - '@inquirer/type': 3.0.7(@types/node@22.16.3) + '@inquirer/core': 10.1.15(@types/node@22.16.5) + '@inquirer/figures': 1.0.13 + '@inquirer/type': 3.0.8(@types/node@22.16.5) ansi-escapes: 4.3.2 yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 - '@inquirer/confirm@5.1.13(@types/node@22.16.3)': + '@inquirer/confirm@5.1.14(@types/node@22.16.5)': dependencies: - '@inquirer/core': 10.1.14(@types/node@22.16.3) - '@inquirer/type': 3.0.7(@types/node@22.16.3) + '@inquirer/core': 10.1.15(@types/node@22.16.5) + '@inquirer/type': 3.0.8(@types/node@22.16.5) optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 - '@inquirer/core@10.1.14(@types/node@22.16.3)': + '@inquirer/core@10.1.15(@types/node@22.16.5)': dependencies: - '@inquirer/figures': 1.0.12 - '@inquirer/type': 3.0.7(@types/node@22.16.3) + '@inquirer/figures': 1.0.13 + '@inquirer/type': 3.0.8(@types/node@22.16.5) ansi-escapes: 4.3.2 cli-width: 4.1.0 mute-stream: 2.0.0 @@ -2351,93 +2301,93 @@ snapshots: wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 - '@inquirer/editor@4.2.14(@types/node@22.16.3)': + '@inquirer/editor@4.2.15(@types/node@22.16.5)': dependencies: - '@inquirer/core': 10.1.14(@types/node@22.16.3) - '@inquirer/type': 3.0.7(@types/node@22.16.3) + '@inquirer/core': 10.1.15(@types/node@22.16.5) + '@inquirer/type': 3.0.8(@types/node@22.16.5) external-editor: 3.1.0 optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 - '@inquirer/expand@4.0.16(@types/node@22.16.3)': + '@inquirer/expand@4.0.17(@types/node@22.16.5)': dependencies: - '@inquirer/core': 10.1.14(@types/node@22.16.3) - '@inquirer/type': 3.0.7(@types/node@22.16.3) + '@inquirer/core': 10.1.15(@types/node@22.16.5) + '@inquirer/type': 3.0.8(@types/node@22.16.5) yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 - '@inquirer/figures@1.0.12': {} + '@inquirer/figures@1.0.13': {} - '@inquirer/input@4.2.0(@types/node@22.16.3)': + '@inquirer/input@4.2.1(@types/node@22.16.5)': dependencies: - '@inquirer/core': 10.1.14(@types/node@22.16.3) - '@inquirer/type': 3.0.7(@types/node@22.16.3) + '@inquirer/core': 10.1.15(@types/node@22.16.5) + '@inquirer/type': 3.0.8(@types/node@22.16.5) optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 - '@inquirer/number@3.0.16(@types/node@22.16.3)': + '@inquirer/number@3.0.17(@types/node@22.16.5)': dependencies: - '@inquirer/core': 10.1.14(@types/node@22.16.3) - '@inquirer/type': 3.0.7(@types/node@22.16.3) + '@inquirer/core': 10.1.15(@types/node@22.16.5) + '@inquirer/type': 3.0.8(@types/node@22.16.5) optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 - '@inquirer/password@4.0.16(@types/node@22.16.3)': + '@inquirer/password@4.0.17(@types/node@22.16.5)': dependencies: - '@inquirer/core': 10.1.14(@types/node@22.16.3) - '@inquirer/type': 3.0.7(@types/node@22.16.3) + '@inquirer/core': 10.1.15(@types/node@22.16.5) + '@inquirer/type': 3.0.8(@types/node@22.16.5) ansi-escapes: 4.3.2 optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 - '@inquirer/prompts@7.6.0(@types/node@22.16.3)': + '@inquirer/prompts@7.7.1(@types/node@22.16.5)': dependencies: - '@inquirer/checkbox': 4.1.9(@types/node@22.16.3) - '@inquirer/confirm': 5.1.13(@types/node@22.16.3) - '@inquirer/editor': 4.2.14(@types/node@22.16.3) - '@inquirer/expand': 4.0.16(@types/node@22.16.3) - '@inquirer/input': 4.2.0(@types/node@22.16.3) - '@inquirer/number': 3.0.16(@types/node@22.16.3) - '@inquirer/password': 4.0.16(@types/node@22.16.3) - '@inquirer/rawlist': 4.1.4(@types/node@22.16.3) - '@inquirer/search': 3.0.16(@types/node@22.16.3) - '@inquirer/select': 4.2.4(@types/node@22.16.3) + '@inquirer/checkbox': 4.2.0(@types/node@22.16.5) + '@inquirer/confirm': 5.1.14(@types/node@22.16.5) + '@inquirer/editor': 4.2.15(@types/node@22.16.5) + '@inquirer/expand': 4.0.17(@types/node@22.16.5) + '@inquirer/input': 4.2.1(@types/node@22.16.5) + '@inquirer/number': 3.0.17(@types/node@22.16.5) + '@inquirer/password': 4.0.17(@types/node@22.16.5) + '@inquirer/rawlist': 4.1.5(@types/node@22.16.5) + '@inquirer/search': 3.0.17(@types/node@22.16.5) + '@inquirer/select': 4.3.1(@types/node@22.16.5) optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 - '@inquirer/rawlist@4.1.4(@types/node@22.16.3)': + '@inquirer/rawlist@4.1.5(@types/node@22.16.5)': dependencies: - '@inquirer/core': 10.1.14(@types/node@22.16.3) - '@inquirer/type': 3.0.7(@types/node@22.16.3) + '@inquirer/core': 10.1.15(@types/node@22.16.5) + '@inquirer/type': 3.0.8(@types/node@22.16.5) yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 - '@inquirer/search@3.0.16(@types/node@22.16.3)': + '@inquirer/search@3.0.17(@types/node@22.16.5)': dependencies: - '@inquirer/core': 10.1.14(@types/node@22.16.3) - '@inquirer/figures': 1.0.12 - '@inquirer/type': 3.0.7(@types/node@22.16.3) + '@inquirer/core': 10.1.15(@types/node@22.16.5) + '@inquirer/figures': 1.0.13 + '@inquirer/type': 3.0.8(@types/node@22.16.5) yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 - '@inquirer/select@4.2.4(@types/node@22.16.3)': + '@inquirer/select@4.3.1(@types/node@22.16.5)': dependencies: - '@inquirer/core': 10.1.14(@types/node@22.16.3) - '@inquirer/figures': 1.0.12 - '@inquirer/type': 3.0.7(@types/node@22.16.3) + '@inquirer/core': 10.1.15(@types/node@22.16.5) + '@inquirer/figures': 1.0.13 + '@inquirer/type': 3.0.8(@types/node@22.16.5) ansi-escapes: 4.3.2 yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 - '@inquirer/type@3.0.7(@types/node@22.16.3)': + '@inquirer/type@3.0.8(@types/node@22.16.5)': optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 '@isaacs/cliui@8.0.2': dependencies: @@ -2468,7 +2418,7 @@ snapshots: '@material/material-color-utilities@0.2.7': {} - '@mswjs/interceptors@0.39.2': + '@mswjs/interceptors@0.39.4': dependencies: '@open-draft/deferred-promise': 2.2.0 '@open-draft/logger': 0.3.0 @@ -2486,107 +2436,83 @@ snapshots: '@open-draft/until@2.1.0': {} - '@oxlint/darwin-arm64@1.6.0': - optional: true - - '@oxlint/darwin-x64@1.6.0': - optional: true - - '@oxlint/linux-arm64-gnu@1.6.0': - optional: true - - '@oxlint/linux-arm64-musl@1.6.0': - optional: true - - '@oxlint/linux-x64-gnu@1.6.0': - optional: true - - '@oxlint/linux-x64-musl@1.6.0': - optional: true - - '@oxlint/win32-arm64@1.6.0': - optional: true - - '@oxlint/win32-x64@1.6.0': - optional: true - '@pkgjs/parseargs@0.11.0': optional: true - '@rollup/rollup-android-arm-eabi@4.45.0': + '@rollup/rollup-android-arm-eabi@4.46.1': optional: true - '@rollup/rollup-android-arm64@4.45.0': + '@rollup/rollup-android-arm64@4.46.1': optional: true - '@rollup/rollup-darwin-arm64@4.45.0': + '@rollup/rollup-darwin-arm64@4.46.1': optional: true - '@rollup/rollup-darwin-x64@4.45.0': + '@rollup/rollup-darwin-x64@4.46.1': optional: true - '@rollup/rollup-freebsd-arm64@4.45.0': + '@rollup/rollup-freebsd-arm64@4.46.1': optional: true - '@rollup/rollup-freebsd-x64@4.45.0': + '@rollup/rollup-freebsd-x64@4.46.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.45.0': + '@rollup/rollup-linux-arm-gnueabihf@4.46.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.45.0': + '@rollup/rollup-linux-arm-musleabihf@4.46.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.45.0': + '@rollup/rollup-linux-arm64-gnu@4.46.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.45.0': + '@rollup/rollup-linux-arm64-musl@4.46.1': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.45.0': + '@rollup/rollup-linux-loongarch64-gnu@4.46.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.45.0': + '@rollup/rollup-linux-ppc64-gnu@4.46.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.45.0': + '@rollup/rollup-linux-riscv64-gnu@4.46.1': optional: true - '@rollup/rollup-linux-riscv64-musl@4.45.0': + '@rollup/rollup-linux-riscv64-musl@4.46.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.45.0': + '@rollup/rollup-linux-s390x-gnu@4.46.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.45.0': + '@rollup/rollup-linux-x64-gnu@4.46.1': optional: true - '@rollup/rollup-linux-x64-musl@4.45.0': + '@rollup/rollup-linux-x64-musl@4.46.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.45.0': + '@rollup/rollup-win32-arm64-msvc@4.46.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.45.0': + '@rollup/rollup-win32-ia32-msvc@4.46.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.45.0': + '@rollup/rollup-win32-x64-msvc@4.46.1': optional: true - '@shikijs/engine-oniguruma@3.7.0': + '@shikijs/engine-oniguruma@3.8.1': dependencies: - '@shikijs/types': 3.7.0 + '@shikijs/types': 3.8.1 '@shikijs/vscode-textmate': 10.0.2 - '@shikijs/langs@3.7.0': + '@shikijs/langs@3.8.1': dependencies: - '@shikijs/types': 3.7.0 + '@shikijs/types': 3.8.1 - '@shikijs/themes@3.7.0': + '@shikijs/themes@3.8.1': dependencies: - '@shikijs/types': 3.7.0 + '@shikijs/types': 3.8.1 - '@shikijs/types@3.7.0': + '@shikijs/types@3.8.1': dependencies: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 @@ -2609,11 +2535,11 @@ snapshots: '@types/jsdom@21.1.7': dependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 '@types/tough-cookie': 4.0.5 parse5: 7.3.0 - '@types/node@22.16.3': + '@types/node@22.16.5': dependencies: undici-types: 6.21.0 @@ -2623,7 +2549,7 @@ snapshots: '@types/unist@3.0.3': {} - '@vitest/coverage-istanbul@3.2.4(vitest@3.2.4(@types/node@22.16.3)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.3)(typescript@5.8.3))(yaml@2.8.0))': + '@vitest/coverage-istanbul@3.2.4(vitest@3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.0))': dependencies: '@istanbuljs/schema': 0.1.3 debug: 4.4.1 @@ -2635,7 +2561,7 @@ snapshots: magicast: 0.3.5 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/node@22.16.3)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.3)(typescript@5.8.3))(yaml@2.8.0) + vitest: 3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.0) transitivePeerDependencies: - supports-color @@ -2647,14 +2573,14 @@ snapshots: chai: 5.2.1 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(msw@2.10.4(@types/node@22.16.3)(typescript@5.8.3))(vite@6.3.5(@types/node@22.16.3)(yaml@2.8.0))': + '@vitest/mocker@3.2.4(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(vite@7.0.6(@types/node@22.16.5)(yaml@2.8.0))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - msw: 2.10.4(@types/node@22.16.3)(typescript@5.8.3) - vite: 6.3.5(@types/node@22.16.3)(yaml@2.8.0) + msw: 2.10.4(@types/node@22.16.5)(typescript@5.8.3) + vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.0) '@vitest/pretty-format@3.2.4': dependencies: @@ -2679,7 +2605,7 @@ snapshots: '@vitest/utils@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - loupe: 3.1.4 + loupe: 3.2.0 tinyrainbow: 2.0.0 acorn-jsx-walk@2.0.0: {} @@ -2734,7 +2660,7 @@ snapshots: browserslist@4.25.1: dependencies: caniuse-lite: 1.0.30001727 - electron-to-chromium: 1.5.182 + electron-to-chromium: 1.5.191 node-releases: 2.0.19 update-browserslist-db: 1.1.3(browserslist@4.25.1) @@ -2764,7 +2690,7 @@ snapshots: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.1.4 + loupe: 3.2.0 pathval: 2.0.1 chalk@4.1.2: @@ -2863,7 +2789,7 @@ snapshots: json5: 2.2.3 memoize: 10.1.0 picocolors: 1.1.1 - picomatch: 4.0.2 + picomatch: 4.0.3 prompts: 2.4.2 rechoir: 0.8.0 safe-regex: 2.1.1 @@ -2880,7 +2806,7 @@ snapshots: eastasianwidth@0.2.0: {} - electron-to-chromium@1.5.182: {} + electron-to-chromium@1.5.191: {} emoji-regex@8.0.0: {} @@ -2905,34 +2831,34 @@ snapshots: dependencies: es-errors: 1.3.0 - esbuild@0.25.6: + esbuild@0.25.8: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.6 - '@esbuild/android-arm': 0.25.6 - '@esbuild/android-arm64': 0.25.6 - '@esbuild/android-x64': 0.25.6 - '@esbuild/darwin-arm64': 0.25.6 - '@esbuild/darwin-x64': 0.25.6 - '@esbuild/freebsd-arm64': 0.25.6 - '@esbuild/freebsd-x64': 0.25.6 - '@esbuild/linux-arm': 0.25.6 - '@esbuild/linux-arm64': 0.25.6 - '@esbuild/linux-ia32': 0.25.6 - '@esbuild/linux-loong64': 0.25.6 - '@esbuild/linux-mips64el': 0.25.6 - '@esbuild/linux-ppc64': 0.25.6 - '@esbuild/linux-riscv64': 0.25.6 - '@esbuild/linux-s390x': 0.25.6 - '@esbuild/linux-x64': 0.25.6 - '@esbuild/netbsd-arm64': 0.25.6 - '@esbuild/netbsd-x64': 0.25.6 - '@esbuild/openbsd-arm64': 0.25.6 - '@esbuild/openbsd-x64': 0.25.6 - '@esbuild/openharmony-arm64': 0.25.6 - '@esbuild/sunos-x64': 0.25.6 - '@esbuild/win32-arm64': 0.25.6 - '@esbuild/win32-ia32': 0.25.6 - '@esbuild/win32-x64': 0.25.6 + '@esbuild/aix-ppc64': 0.25.8 + '@esbuild/android-arm': 0.25.8 + '@esbuild/android-arm64': 0.25.8 + '@esbuild/android-x64': 0.25.8 + '@esbuild/darwin-arm64': 0.25.8 + '@esbuild/darwin-x64': 0.25.8 + '@esbuild/freebsd-arm64': 0.25.8 + '@esbuild/freebsd-x64': 0.25.8 + '@esbuild/linux-arm': 0.25.8 + '@esbuild/linux-arm64': 0.25.8 + '@esbuild/linux-ia32': 0.25.8 + '@esbuild/linux-loong64': 0.25.8 + '@esbuild/linux-mips64el': 0.25.8 + '@esbuild/linux-ppc64': 0.25.8 + '@esbuild/linux-riscv64': 0.25.8 + '@esbuild/linux-s390x': 0.25.8 + '@esbuild/linux-x64': 0.25.8 + '@esbuild/netbsd-arm64': 0.25.8 + '@esbuild/netbsd-x64': 0.25.8 + '@esbuild/openbsd-arm64': 0.25.8 + '@esbuild/openbsd-x64': 0.25.8 + '@esbuild/openharmony-arm64': 0.25.8 + '@esbuild/sunos-x64': 0.25.8 + '@esbuild/win32-arm64': 0.25.8 + '@esbuild/win32-ia32': 0.25.8 + '@esbuild/win32-x64': 0.25.8 escalade@3.2.0: {} @@ -2958,9 +2884,9 @@ snapshots: fast-uri@3.0.6: {} - fdir@6.4.6(picomatch@4.0.2): + fdir@6.4.6(picomatch@4.0.3): optionalDependencies: - picomatch: 4.0.2 + picomatch: 4.0.3 foreground-child@3.3.1: dependencies: @@ -3063,7 +2989,7 @@ snapshots: i18next-browser-languagedetector@8.2.0: dependencies: - '@babel/runtime': 7.27.6 + '@babel/runtime': 7.28.2 i18next-http-backend@2.7.3: dependencies: @@ -3083,11 +3009,11 @@ snapshots: i18next@22.5.1: dependencies: - '@babel/runtime': 7.27.6 + '@babel/runtime': 7.28.2 i18next@24.2.3(typescript@5.8.3): dependencies: - '@babel/runtime': 7.27.6 + '@babel/runtime': 7.28.2 optionalDependencies: typescript: 5.8.3 @@ -3107,17 +3033,17 @@ snapshots: ini@4.1.1: {} - inquirer@12.7.0(@types/node@22.16.3): + inquirer@12.8.2(@types/node@22.16.5): dependencies: - '@inquirer/core': 10.1.14(@types/node@22.16.3) - '@inquirer/prompts': 7.6.0(@types/node@22.16.3) - '@inquirer/type': 3.0.7(@types/node@22.16.3) + '@inquirer/core': 10.1.15(@types/node@22.16.5) + '@inquirer/prompts': 7.7.1(@types/node@22.16.5) + '@inquirer/type': 3.0.8(@types/node@22.16.5) ansi-escapes: 4.3.2 mute-stream: 2.0.0 - run-async: 4.0.4 + run-async: 4.0.5 rxjs: 7.8.2 optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 interpret@3.1.1: {} @@ -3203,7 +3129,7 @@ snapshots: http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.20 + nwsapi: 2.2.21 parse5: 7.3.0 rrweb-cssom: 0.8.0 saxes: 6.0.0 @@ -3299,7 +3225,7 @@ snapshots: lodash@4.17.21: {} - loupe@3.1.4: {} + loupe@3.2.0: {} lru-cache@10.4.3: {} @@ -3316,7 +3242,7 @@ snapshots: magicast@0.3.5: dependencies: '@babel/parser': 7.28.0 - '@babel/types': 7.28.1 + '@babel/types': 7.28.2 source-map-js: 1.2.1 make-dir@4.0.0: @@ -3356,13 +3282,13 @@ snapshots: ms@2.1.3: {} - msw@2.10.4(@types/node@22.16.3)(typescript@5.8.3): + msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3): dependencies: '@bundled-es-modules/cookie': 2.0.1 '@bundled-es-modules/statuses': 1.0.1 '@bundled-es-modules/tough-cookie': 0.1.6 - '@inquirer/confirm': 5.1.13(@types/node@22.16.3) - '@mswjs/interceptors': 0.39.2 + '@inquirer/confirm': 5.1.14(@types/node@22.16.5) + '@mswjs/interceptors': 0.39.4 '@open-draft/deferred-promise': 2.2.0 '@open-draft/until': 2.1.0 '@types/cookie': 0.6.0 @@ -3393,7 +3319,7 @@ snapshots: node-releases@2.0.19: {} - nwsapi@2.2.20: {} + nwsapi@2.2.21: {} object-keys@1.1.1: {} @@ -3403,17 +3329,6 @@ snapshots: outvariant@1.4.3: {} - oxlint@1.6.0: - optionalDependencies: - '@oxlint/darwin-arm64': 1.6.0 - '@oxlint/darwin-x64': 1.6.0 - '@oxlint/linux-arm64-gnu': 1.6.0 - '@oxlint/linux-arm64-musl': 1.6.0 - '@oxlint/linux-x64-gnu': 1.6.0 - '@oxlint/linux-x64-musl': 1.6.0 - '@oxlint/win32-arm64': 1.6.0 - '@oxlint/win32-x64': 1.6.0 - package-json-from-dist@1.0.1: {} pako@1.0.11: {} @@ -3462,7 +3377,7 @@ snapshots: picocolors@1.1.1: {} - picomatch@4.0.2: {} + picomatch@4.0.3: {} postcss@8.5.6: dependencies: @@ -3470,8 +3385,6 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - prettier@3.6.2: {} - process-nextick-args@2.0.1: {} prompts@2.4.2: @@ -3517,38 +3430,35 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - rollup@4.45.0: + rollup@4.46.1: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.45.0 - '@rollup/rollup-android-arm64': 4.45.0 - '@rollup/rollup-darwin-arm64': 4.45.0 - '@rollup/rollup-darwin-x64': 4.45.0 - '@rollup/rollup-freebsd-arm64': 4.45.0 - '@rollup/rollup-freebsd-x64': 4.45.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.45.0 - '@rollup/rollup-linux-arm-musleabihf': 4.45.0 - '@rollup/rollup-linux-arm64-gnu': 4.45.0 - '@rollup/rollup-linux-arm64-musl': 4.45.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.45.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.45.0 - '@rollup/rollup-linux-riscv64-gnu': 4.45.0 - '@rollup/rollup-linux-riscv64-musl': 4.45.0 - '@rollup/rollup-linux-s390x-gnu': 4.45.0 - '@rollup/rollup-linux-x64-gnu': 4.45.0 - '@rollup/rollup-linux-x64-musl': 4.45.0 - '@rollup/rollup-win32-arm64-msvc': 4.45.0 - '@rollup/rollup-win32-ia32-msvc': 4.45.0 - '@rollup/rollup-win32-x64-msvc': 4.45.0 + '@rollup/rollup-android-arm-eabi': 4.46.1 + '@rollup/rollup-android-arm64': 4.46.1 + '@rollup/rollup-darwin-arm64': 4.46.1 + '@rollup/rollup-darwin-x64': 4.46.1 + '@rollup/rollup-freebsd-arm64': 4.46.1 + '@rollup/rollup-freebsd-x64': 4.46.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.46.1 + '@rollup/rollup-linux-arm-musleabihf': 4.46.1 + '@rollup/rollup-linux-arm64-gnu': 4.46.1 + '@rollup/rollup-linux-arm64-musl': 4.46.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.46.1 + '@rollup/rollup-linux-ppc64-gnu': 4.46.1 + '@rollup/rollup-linux-riscv64-gnu': 4.46.1 + '@rollup/rollup-linux-riscv64-musl': 4.46.1 + '@rollup/rollup-linux-s390x-gnu': 4.46.1 + '@rollup/rollup-linux-x64-gnu': 4.46.1 + '@rollup/rollup-linux-x64-musl': 4.46.1 + '@rollup/rollup-win32-arm64-msvc': 4.46.1 + '@rollup/rollup-win32-ia32-msvc': 4.46.1 + '@rollup/rollup-win32-x64-msvc': 4.46.1 fsevents: 2.3.3 rrweb-cssom@0.8.0: {} - run-async@4.0.4: - dependencies: - oxlint: 1.6.0 - prettier: 3.6.2 + run-async@4.0.5: {} rxjs@7.8.2: dependencies: @@ -3657,8 +3567,8 @@ snapshots: tinyglobby@0.2.14: dependencies: - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 + fdir: 6.4.6(picomatch@4.0.3) + picomatch: 4.0.3 tinypool@1.1.1: {} @@ -3716,9 +3626,9 @@ snapshots: type-fest@4.41.0: {} - typedoc@0.28.7(typescript@5.8.3): + typedoc@0.28.8(typescript@5.8.3): dependencies: - '@gerrit0/mini-shiki': 3.7.0 + '@gerrit0/mini-shiki': 3.8.1 lunr: 2.3.9 markdown-it: 14.1.0 minimatch: 9.0.5 @@ -3746,13 +3656,13 @@ snapshots: util-deprecate@1.0.2: {} - vite-node@3.2.4(@types/node@22.16.3)(yaml@2.8.0): + vite-node@3.2.4(@types/node@22.16.5)(yaml@2.8.0): dependencies: cac: 6.7.14 debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@22.16.3)(yaml@2.8.0) + vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -3767,40 +3677,40 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.16.3)(yaml@2.8.0)): + vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@7.0.6(@types/node@22.16.5)(yaml@2.8.0)): dependencies: debug: 4.4.1 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.8.3) optionalDependencies: - vite: 6.3.5(@types/node@22.16.3)(yaml@2.8.0) + vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.0) transitivePeerDependencies: - supports-color - typescript - vite@6.3.5(@types/node@22.16.3)(yaml@2.8.0): + vite@7.0.6(@types/node@22.16.5)(yaml@2.8.0): dependencies: - esbuild: 0.25.6 - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 + esbuild: 0.25.8 + fdir: 6.4.6(picomatch@4.0.3) + picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.45.0 + rollup: 4.46.1 tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 fsevents: 2.3.3 yaml: 2.8.0 - vitest-canvas-mock@0.3.3(vitest@3.2.4(@types/node@22.16.3)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.3)(typescript@5.8.3))(yaml@2.8.0)): + vitest-canvas-mock@0.3.3(vitest@3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.0)): dependencies: jest-canvas-mock: 2.5.2 - vitest: 3.2.4(@types/node@22.16.3)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.3)(typescript@5.8.3))(yaml@2.8.0) + vitest: 3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.0) - vitest@3.2.4(@types/node@22.16.3)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.3)(typescript@5.8.3))(yaml@2.8.0): + vitest@3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(msw@2.10.4(@types/node@22.16.3)(typescript@5.8.3))(vite@6.3.5(@types/node@22.16.3)(yaml@2.8.0)) + '@vitest/mocker': 3.2.4(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(vite@7.0.6(@types/node@22.16.5)(yaml@2.8.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -3811,18 +3721,18 @@ snapshots: expect-type: 1.2.2 magic-string: 0.30.17 pathe: 2.0.3 - picomatch: 4.0.2 + picomatch: 4.0.3 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 tinyglobby: 0.2.14 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@22.16.3)(yaml@2.8.0) - vite-node: 3.2.4(@types/node@22.16.3)(yaml@2.8.0) + vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.0) + vite-node: 3.2.4(@types/node@22.16.5)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.16.3 + '@types/node': 22.16.5 jsdom: 26.1.0 transitivePeerDependencies: - jiti From b1561ce741f1a9b3c93bd09e7e6bd353bb083a3a Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Tue, 29 Jul 2025 16:15:17 -0400 Subject: [PATCH 45/76] [ME] [Bug] Disable trades in GTS ME with only 1 valid party member https://github.com/pagefaultgames/pokerogue/pull/6167 --- .../encounters/global-trade-system-encounter.ts | 7 +++++-- .../encounters/global-trade-system-encounter.test.ts | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts index b914927123a..347092fe0b4 100644 --- a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts +++ b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts @@ -39,6 +39,7 @@ import { addPokemonDataToDexAndValidateAchievements } from "#mystery-encounters/ import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter"; import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter"; import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option"; +import { PartySizeRequirement } from "#mystery-encounters/mystery-encounter-requirements"; import { PokemonData } from "#system/pokemon-data"; import { MusicPreference } from "#system/settings"; import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler"; @@ -151,7 +152,8 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil return true; }) .withOption( - MysteryEncounterOptionBuilder.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT) + MysteryEncounterOptionBuilder.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) + .withSceneRequirement(new PartySizeRequirement([2, 6], true)) // Requires 2 valid party members .withHasDexProgress(true) .withDialogue({ buttonLabel: `${namespace}:option.1.label`, @@ -257,7 +259,8 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil .build(), ) .withOption( - MysteryEncounterOptionBuilder.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT) + MysteryEncounterOptionBuilder.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) + .withSceneRequirement(new PartySizeRequirement([2, 6], true)) // Requires 2 valid party members .withHasDexProgress(true) .withDialogue({ buttonLabel: `${namespace}:option.2.label`, diff --git a/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts b/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts index 2ac55dabe1c..867a33f6ab6 100644 --- a/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts +++ b/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts @@ -93,7 +93,7 @@ describe("Global Trade System - Mystery Encounter", () => { describe("Option 1 - Check Trade Offers", () => { it("should have the correct properties", () => { const option = GlobalTradeSystemEncounter.options[0]; - expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT); expect(option.dialogue).toBeDefined(); expect(option.dialogue).toStrictEqual({ buttonLabel: `${namespace}:option.1.label`, @@ -154,7 +154,7 @@ describe("Global Trade System - Mystery Encounter", () => { describe("Option 2 - Wonder Trade", () => { it("should have the correct properties", () => { const option = GlobalTradeSystemEncounter.options[1]; - expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT); expect(option.dialogue).toBeDefined(); expect(option.dialogue).toStrictEqual({ buttonLabel: `${namespace}:option.2.label`, From 32faab05d5605e28042eba992422d33fdfccdcd1 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Tue, 29 Jul 2025 15:47:24 -0600 Subject: [PATCH 46/76] [Refactor] Minor refactor of battler tags (#6129) * Minor refactor battler tags * Improve documentation * Update type when loading in pokemon-data constructor for battler tags * Fix issues in tsdoc comments with Wlowscha's suggestions Co-authored-by: Wlowscha <54003515+Wlowscha@users.noreply.github.com> * Apply bertie's suggestions from code review Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> * Remove unnecessary as const from tagType * Remove missed `as const` * Apply kev's suggestions from code review Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update src/data/battler-tags.ts Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> * Update src/data/battler-tags.ts Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> --------- Co-authored-by: Wlowscha <54003515+Wlowscha@users.noreply.github.com> Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/@types/battler-tags.ts | 119 +++++ src/data/battler-tags.ts | 881 ++++++++++++++++++------------- src/data/moves/move.ts | 2 +- src/data/pokemon/pokemon-data.ts | 11 +- src/enums/battler-tag-type.ts | 1 - 5 files changed, 643 insertions(+), 371 deletions(-) create mode 100644 src/@types/battler-tags.ts diff --git a/src/@types/battler-tags.ts b/src/@types/battler-tags.ts new file mode 100644 index 00000000000..d1ff93e0400 --- /dev/null +++ b/src/@types/battler-tags.ts @@ -0,0 +1,119 @@ +// biome-ignore-start lint/correctness/noUnusedImports: Used in a TSDoc comment +import type { AbilityBattlerTag, BattlerTagTypeMap, SerializableBattlerTag, TypeBoostTag } from "#data/battler-tags"; +import type { AbilityId } from "#enums/ability-id"; +// biome-ignore-end lint/correctness/noUnusedImports: end +import type { BattlerTagType } from "#enums/battler-tag-type"; + +/** + * Subset of {@linkcode BattlerTagType}s that restrict the use of moves. + */ +export type MoveRestrictionBattlerTagType = + | BattlerTagType.THROAT_CHOPPED + | BattlerTagType.TORMENT + | BattlerTagType.TAUNT + | BattlerTagType.IMPRISON + | BattlerTagType.HEAL_BLOCK + | BattlerTagType.ENCORE + | BattlerTagType.DISABLED + | BattlerTagType.GORILLA_TACTICS; + +/** + * Subset of {@linkcode BattlerTagType}s that block damage from moves. + */ +export type FormBlockDamageBattlerTagType = BattlerTagType.ICE_FACE | BattlerTagType.DISGUISE; + +/** + * Subset of {@linkcode BattlerTagType}s that are related to trapping effects. + */ +export type TrappingBattlerTagType = + | BattlerTagType.BIND + | BattlerTagType.WRAP + | BattlerTagType.FIRE_SPIN + | BattlerTagType.WHIRLPOOL + | BattlerTagType.CLAMP + | BattlerTagType.SAND_TOMB + | BattlerTagType.MAGMA_STORM + | BattlerTagType.SNAP_TRAP + | BattlerTagType.THUNDER_CAGE + | BattlerTagType.INFESTATION + | BattlerTagType.INGRAIN + | BattlerTagType.OCTOLOCK + | BattlerTagType.NO_RETREAT; + +/** + * Subset of {@linkcode BattlerTagType}s that are related to protection effects. + */ +export type ProtectionBattlerTagType = BattlerTagType.PROTECTED | BattlerTagType.SPIKY_SHIELD | DamageProtectedTagType; +/** + * Subset of {@linkcode BattlerTagType}s related to protection effects that block damage but not status moves. + */ +export type DamageProtectedTagType = ContactSetStatusProtectedTagType | ContactStatStageChangeProtectedTagType; + +/** + * Subset of {@linkcode BattlerTagType}s related to protection effects that set a status effect on the attacker. + */ +export type ContactSetStatusProtectedTagType = BattlerTagType.BANEFUL_BUNKER | BattlerTagType.BURNING_BULWARK; + +/** + * Subset of {@linkcode BattlerTagType}s related to protection effects that change stat stages of the attacker. + */ +export type ContactStatStageChangeProtectedTagType = + | BattlerTagType.KINGS_SHIELD + | BattlerTagType.SILK_TRAP + | BattlerTagType.OBSTRUCT; + +/** Subset of {@linkcode BattlerTagType}s that provide the Endure effect */ +export type EndureTagType = BattlerTagType.ENDURE_TOKEN | BattlerTagType.ENDURING; + +/** + * Subset of {@linkcode BattlerTagType}s that are related to semi-invulnerable states. + */ +export type SemiInvulnerableTagType = + | BattlerTagType.FLYING + | BattlerTagType.UNDERGROUND + | BattlerTagType.UNDERWATER + | BattlerTagType.HIDDEN; + +/** + * Subset of {@linkcode BattlerTagType}s corresponding to {@linkcode AbilityBattlerTag}s + * + * @remarks + * ⚠️ {@linkcode AbilityId.FLASH_FIRE | Flash Fire}'s {@linkcode BattlerTagType.FIRE_BOOST} is not included as it + * subclasses {@linkcode TypeBoostTag} and not `AbilityBattlerTag`. + */ +export type AbilityBattlerTagType = + | BattlerTagType.PROTOSYNTHESIS + | BattlerTagType.QUARK_DRIVE + | BattlerTagType.UNBURDEN + | BattlerTagType.SLOW_START + | BattlerTagType.TRUANT; + +/** + * Subset of {@linkcode BattlerTagType}s related to abilities that boost the highest stat. + */ +export type HighestStatBoostTagType = + | BattlerTagType.QUARK_DRIVE // formatting + | BattlerTagType.PROTOSYNTHESIS; +/** + * Subset of {@linkcode BattlerTagType}s that are able to persist between turns and should therefore be serialized + */ +export type SerializableBattlerTagType = keyof { + [K in keyof BattlerTagTypeMap as BattlerTagTypeMap[K] extends SerializableBattlerTag + ? K + : never]: BattlerTagTypeMap[K]; +}; + +/** + * Subset of {@linkcode BattlerTagType}s that are not able to persist across waves and should therefore not be serialized + */ +export type NonSerializableBattlerTagType = Exclude; + +/** + * Dummy, typescript-only declaration to ensure that + * {@linkcode BattlerTagTypeMap} has an entry for all `BattlerTagType`s. + * + * If a battler tag is missing from the map, Typescript will throw an error on this statement. + * + * ⚠️ Does not actually exist at runtime, so it must not be used! + */ +declare const EnsureAllBattlerTagTypesAreMapped: BattlerTagTypeMap[BattlerTagType] & never; diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index c8ddfe32f0b..79c14f860b6 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -8,6 +8,7 @@ import { SpeciesFormChangeAbilityTrigger } from "#data/form-change-triggers"; import { getStatusEffectHealText } from "#data/status-effect"; import { TerrainType } from "#data/terrain"; import { AbilityId } from "#enums/ability-id"; +import type { BattlerIndex } from "#enums/battler-index"; import { BattlerTagLapseType } from "#enums/battler-tag-lapse-type"; import { BattlerTagType } from "#enums/battler-tag-type"; import { HitResult } from "#enums/hit-result"; @@ -31,41 +32,107 @@ import type { MoveEffectPhase } from "#phases/move-effect-phase"; import type { MovePhase } from "#phases/move-phase"; import type { StatStageChangeCallback } from "#phases/stat-stage-change-phase"; import i18next from "#plugins/i18n"; +import type { + AbilityBattlerTagType, + ContactSetStatusProtectedTagType, + ContactStatStageChangeProtectedTagType, + DamageProtectedTagType, + EndureTagType, + HighestStatBoostTagType, + MoveRestrictionBattlerTagType, + ProtectionBattlerTagType, + SemiInvulnerableTagType, + TrappingBattlerTagType, +} from "#types/battler-tags"; +import type { Mutable, NonFunctionProperties } from "#types/type-helpers"; import { BooleanHolder, coerceArray, getFrameMs, isNullOrUndefined, NumberHolder, toDmgValue } from "#utils/common"; +/* +@module +BattlerTags are used to represent semi-persistent effects that can be attached to a Pokemon. +Note that before serialization, a new tag object is created, and then `loadTag` is called on the +tag with the object that was serialized. + +This means it is straightforward to avoid serializing fields. +Fields that are not set in the constructor and not set in `loadTag` will thus not be serialized. + +Any battler tag that can persist across sessions must extend SerializableBattlerTag in its class definition signature. +Only tags that persist across waves (meaning their effect can last >1 turn) should be considered +serializable. + +Serializable battler tags have strict requirements for their fields. +Properties that are not necessary to reconstruct the tag must not be serialized. This can be avoided +by using a private property. If access to the property is needed outside of the class, then +a getter (and potentially, a setter) should be used instead. + +If a property that is intended to be private must be serialized, then it should instead +be declared as a public readonly propety. Then, in the `loadTag` method (or any method inside the class that needs to adjust the property) +use `(this as Mutable).propertyName = value;` +These rules ensure that Typescript is aware of the shape of the serialized version of the class. +*/ + +/** Interface containing the serializable fields of BattlerTag */ +interface BaseBattlerTag { + /** The tag's remaining duration */ + turnCount: number; + /** The {@linkcode MoveId} that created this tag, or `undefined` if not set by a move */ + sourceMove?: MoveId; + /** The {@linkcode Pokemon.id | PID} of the Pokemon that added this tag, or `undefined` if not set by a pokemon */ + sourceId?: number; +} + /** * A {@linkcode BattlerTag} represents a semi-persistent effect that can be attached to a {@linkcode Pokemon}. * Tags can trigger various effects throughout a turn, and are cleared on switching out * or through their respective {@linkcode BattlerTag.lapse | lapse} methods. */ -export class BattlerTag { - public tagType: BattlerTagType; - public lapseTypes: BattlerTagLapseType[]; +export class BattlerTag implements BaseBattlerTag { + public readonly tagType: BattlerTagType; + public turnCount: number; - public sourceMove: MoveId; + public sourceMove?: MoveId; public sourceId?: number; - public isBatonPassable: boolean; + + //#region non-serializable fields + // Fields that should never be serialized, as they must not change after instantiation + #isBatonPassable = false; + public get isBatonPassable(): boolean { + return this.#isBatonPassable; + } + + #lapseTypes: readonly [BattlerTagLapseType, ...BattlerTagLapseType[]]; + public get lapseTypes(): readonly BattlerTagLapseType[] { + return this.#lapseTypes; + } + //#endregion non-serializable fields constructor( tagType: BattlerTagType, - lapseType: BattlerTagLapseType | BattlerTagLapseType[], + lapseType: BattlerTagLapseType | [BattlerTagLapseType, ...BattlerTagLapseType[]], turnCount: number, sourceMove?: MoveId, sourceId?: number, isBatonPassable = false, ) { this.tagType = tagType; - this.lapseTypes = coerceArray(lapseType); + this.#lapseTypes = coerceArray(lapseType); this.turnCount = turnCount; - this.sourceMove = sourceMove!; // TODO: is this bang correct? + // We intentionally don't want to set source move to `MoveId.NONE` here, so a raw boolean comparison is OK. + if (sourceMove) { + this.sourceMove = sourceMove; + } this.sourceId = sourceId; - this.isBatonPassable = isBatonPassable; + this.#isBatonPassable = isBatonPassable; } canAdd(_pokemon: Pokemon): boolean { return true; } + /** + * Apply effects that occur when the tag is added to a {@linkcode Pokemon} + * @param _pokemon - The {@linkcode Pokemon} the tag was added to + */ onAdd(_pokemon: Pokemon): void {} onRemove(_pokemon: Pokemon): void {} @@ -99,9 +166,9 @@ export class BattlerTag { /** * Load the data for a given {@linkcode BattlerTag} or JSON representation thereof. * Should be inherited from by any battler tag with custom attributes. - * @param source The battler tag to load + * @param source - An object containing the fields needed to reconstruct this tag. */ - loadTag(source: BattlerTag | any): void { + loadTag(source: BaseBattlerTag): void { this.turnCount = source.turnCount; this.sourceMove = source.sourceMove; this.sourceId = source.sourceId; @@ -116,12 +183,9 @@ export class BattlerTag { } } -export interface WeatherBattlerTag { - weatherTypes: WeatherType[]; -} - -export interface TerrainBattlerTag { - terrainTypes: TerrainType[]; +export abstract class SerializableBattlerTag extends BattlerTag { + /** Nonexistent, dummy field to allow typescript to distinguish this class from `BattlerTag` */ + private declare __SerializableBattlerTag: never; } /** @@ -132,8 +196,8 @@ export interface TerrainBattlerTag { * match a condition. A restricted move gets cancelled before it is used. * Players and enemies should not be allowed to select restricted moves. */ -export abstract class MoveRestrictionBattlerTag extends BattlerTag { - /** @override */ +export abstract class MoveRestrictionBattlerTag extends SerializableBattlerTag { + public declare readonly tagType: MoveRestrictionBattlerTagType; override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { if (lapseType === BattlerTagLapseType.PRE_MOVE) { // Cancel the affected pokemon's selected move @@ -154,32 +218,32 @@ export abstract class MoveRestrictionBattlerTag extends BattlerTag { } /** - * Gets whether this tag is restricting a move. + * Determine whether a move's usage is restricted by this tag * - * @param move - {@linkcode MoveId} ID to check restriction for. + * @param move - The {@linkcode MoveId} being checked * @param user - The {@linkcode Pokemon} involved * @returns `true` if the move is restricted by this tag, otherwise `false`. */ public abstract isMoveRestricted(move: MoveId, user?: Pokemon): boolean; /** - * Checks if this tag is restricting a move based on a user's decisions during the target selection phase + * Check if this tag is restricting a move based on a user's decisions during the target selection phase * - * @param {MoveId} _move {@linkcode MoveId} move ID to check restriction for - * @param {Pokemon} _user {@linkcode Pokemon} the user of the above move - * @param {Pokemon} _target {@linkcode Pokemon} the target of the above move - * @returns {boolean} `false` unless overridden by the child tag + * @param _move - {@linkcode MoveId} to check restriction for + * @param _user - The user of the move + * @param _target - The pokemon targeted by the move + * @returns Whether the move is restricted by this tag */ isMoveTargetRestricted(_move: MoveId, _user: Pokemon, _target: Pokemon): boolean { return false; } /** - * Gets the text to display when the player attempts to select a move that is restricted by this tag. + * Get the text to display when the player attempts to select a move that is restricted by this tag. * - * @param {Pokemon} pokemon {@linkcode Pokemon} for which the player is attempting to select the restricted move - * @param {MoveId} move {@linkcode MoveId} ID of the move that is having its selection denied - * @returns {string} text to display when the player attempts to select the restricted move + * @param pokemon - The pokemon for which the player is attempting to select the restricted move + * @param move - The {@linkcode MoveId | ID} of the Move that is having its selection denied + * @returns The text to display when the player attempts to select the restricted move */ abstract selectionDeniedText(pokemon: Pokemon, move: MoveId): string; @@ -188,9 +252,9 @@ export abstract class MoveRestrictionBattlerTag extends BattlerTag { * Because restriction effects also prevent selection of the move, this situation can only arise if a * pokemon first selects a move, then gets outsped by a pokemon using a move that restricts the selected move. * - * @param {Pokemon} _pokemon {@linkcode Pokemon} attempting to use the restricted move - * @param {MoveId} _move {@linkcode MoveId} ID of the move being interrupted - * @returns {string} text to display when the move is interrupted + * @param _pokemon - The pokemon attempting to use the restricted move + * @param _move - The {@linkcode MoveId | ID} of the move being interrupted + * @returns The text to display when the move is interrupted */ interruptedText(_pokemon: Pokemon, _move: MoveId): string { return ""; @@ -200,9 +264,10 @@ export abstract class MoveRestrictionBattlerTag extends BattlerTag { /** * Tag representing the "Throat Chop" effect. Pokemon with this tag cannot use sound-based moves. * @see {@link https://bulbapedia.bulbagarden.net/wiki/Throat_Chop_(move) | Throat Chop} - * @extends MoveRestrictionBattlerTag + * @sealed */ export class ThroatChoppedTag extends MoveRestrictionBattlerTag { + public override readonly tagType = BattlerTagType.THROAT_CHOPPED; constructor() { super( BattlerTagType.THROAT_CHOPPED, @@ -213,10 +278,9 @@ export class ThroatChoppedTag extends MoveRestrictionBattlerTag { } /** - * Checks if a {@linkcode MoveId | move} is restricted by Throat Chop. - * @override - * @param {MoveId} move the {@linkcode MoveId | move} to check for sound-based restriction - * @returns true if the move is sound-based + * Check if a move is restricted by Throat Chop. + * @param move - The {@linkcode MoveId | ID } of the move to check for sound-based restriction + * @returns Whether the move is sound based */ override isMoveRestricted(move: MoveId): boolean { return allMoves[move].hasFlag(MoveFlags.SOUND_BASED); @@ -224,10 +288,9 @@ export class ThroatChoppedTag extends MoveRestrictionBattlerTag { /** * Shows a message when the player attempts to select a move that is restricted by Throat Chop. - * @override - * @param {Pokemon} _pokemon the {@linkcode Pokemon} that is attempting to select the restricted move - * @param {MoveId} move the {@linkcode MoveId | move} that is being restricted - * @returns the message to display when the player attempts to select the restricted move + * @param _pokemon - The {@linkcode Pokemon} that is attempting to select the restricted move + * @param move - The {@linkcode MoveId | move} that is being restricted + * @returns The message to display when the player attempts to select the restricted move */ override selectionDeniedText(_pokemon: Pokemon, move: MoveId): string { return i18next.t("battle:moveCannotBeSelected", { @@ -237,10 +300,9 @@ export class ThroatChoppedTag extends MoveRestrictionBattlerTag { /** * Shows a message when a move is interrupted by Throat Chop. - * @override - * @param {Pokemon} pokemon the interrupted {@linkcode Pokemon} - * @param {MoveId} _move the {@linkcode MoveId | move} that was interrupted - * @returns the message to display when the move is interrupted + * @param pokemon - The interrupted {@linkcode Pokemon} + * @param _move - The {@linkcode MoveId | ID } of the move that was interrupted + * @returns The message to display when the move is interrupted */ override interruptedText(pokemon: Pokemon, _move: MoveId): string { return i18next.t("battle:throatChopInterruptedMove", { @@ -252,10 +314,13 @@ export class ThroatChoppedTag extends MoveRestrictionBattlerTag { /** * Tag representing the "disabling" effect performed by {@linkcode MoveId.DISABLE} and {@linkcode AbilityId.CURSED_BODY}. * When the tag is added, the last-used move of the tag holder is set as the disabled move. + * + * @sealed */ export class DisabledTag extends MoveRestrictionBattlerTag { + public override readonly tagType = BattlerTagType.DISABLED; /** The move being disabled. Gets set when {@linkcode onAdd} is called for this tag. */ - private moveId: MoveId = MoveId.NONE; + public readonly moveId: MoveId = MoveId.NONE; constructor(sourceId: number) { super( @@ -267,14 +332,11 @@ export class DisabledTag extends MoveRestrictionBattlerTag { ); } - /** @override */ override isMoveRestricted(move: MoveId): boolean { return move === this.moveId; } /** - * @override - * * Attempt to disable the target's last move by setting this tag's {@linkcode moveId} * and showing a message. */ @@ -287,7 +349,7 @@ export class DisabledTag extends MoveRestrictionBattlerTag { } super.onAdd(pokemon); - this.moveId = move.move; + (this as Mutable).moveId = move.move; globalScene.phaseManager.queueMessage( i18next.t("battlerTags:disabledOnAdd", { @@ -297,7 +359,6 @@ export class DisabledTag extends MoveRestrictionBattlerTag { ); } - /** @override */ override onRemove(pokemon: Pokemon): void { super.onRemove(pokemon); @@ -309,16 +370,14 @@ export class DisabledTag extends MoveRestrictionBattlerTag { ); } - /** @override */ override selectionDeniedText(_pokemon: Pokemon, move: MoveId): string { return i18next.t("battle:moveDisabled", { moveName: allMoves[move].name }); } /** - * @override - * @param {Pokemon} pokemon {@linkcode Pokemon} attempting to use the restricted move - * @param {MoveId} move {@linkcode MoveId} ID of the move being interrupted - * @returns {string} text to display when the move is interrupted + * @param pokemon - {@linkcode Pokemon} attempting to use the restricted move + * @param move - {@linkcode MoveId | ID} of the move being interrupted + * @returns The text to display when the move is interrupted */ override interruptedText(pokemon: Pokemon, move: MoveId): string { return i18next.t("battle:disableInterruptedMove", { @@ -327,18 +386,21 @@ export class DisabledTag extends MoveRestrictionBattlerTag { }); } - /** @override */ - override loadTag(source: BattlerTag | any): void { + override loadTag(source: NonFunctionProperties): void { super.loadTag(source); - this.moveId = source.moveId; + (this as Mutable).moveId = source.moveId; } } /** * Tag used by Gorilla Tactics to restrict the user to using only one move. + * + * @sealed */ export class GorillaTacticsTag extends MoveRestrictionBattlerTag { - private moveId = MoveId.NONE; + public override readonly tagType = BattlerTagType.GORILLA_TACTICS; + /** ID of the move that the user is locked into using*/ + public readonly moveId: MoveId = MoveId.NONE; constructor() { super(BattlerTagType.GORILLA_TACTICS, BattlerTagLapseType.CUSTOM, 0); @@ -367,18 +429,17 @@ export class GorillaTacticsTag extends MoveRestrictionBattlerTag { super.onAdd(pokemon); // Bang is justified as tag is not added if prior move doesn't exist - this.moveId = pokemon.getLastNonVirtualMove()!.move; + (this as Mutable).moveId = pokemon.getLastNonVirtualMove()!.move; pokemon.setStat(Stat.ATK, pokemon.getStat(Stat.ATK, false) * 1.5, false); } /** * Loads the Gorilla Tactics Battler Tag along with its unique class variable moveId - * @override - * @param source Gorilla Tactics' {@linkcode BattlerTag} information + * @param source - Object containing the fields needed to reconstruct this tag. */ - public override loadTag(source: BattlerTag | any): void { + override loadTag(source: NonFunctionProperties): void { super.loadTag(source); - this.moveId = source.moveId; + (this as Mutable).moveId = source.moveId; } /** @@ -397,7 +458,8 @@ export class GorillaTacticsTag extends MoveRestrictionBattlerTag { /** * BattlerTag that represents the "recharge" effects of moves like Hyper Beam. */ -export class RechargingTag extends BattlerTag { +export class RechargingTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.RECHARGING; constructor(sourceMove: MoveId) { super(BattlerTagType.RECHARGING, [BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.TURN_END], 2, sourceMove); } @@ -430,6 +492,8 @@ export class RechargingTag extends BattlerTag { * @see {@link https://bulbapedia.bulbagarden.net/wiki/Beak_Blast_(move) | Beak Blast} */ export class BeakBlastChargingTag extends BattlerTag { + public override readonly tagType = BattlerTagType.BEAK_BLAST_CHARGING; + public declare readonly sourceMove: MoveId.BEAK_BLAST; constructor() { super( BattlerTagType.BEAK_BLAST_CHARGING, @@ -454,8 +518,8 @@ export class BeakBlastChargingTag extends BattlerTag { /** * Inflicts `BURN` status on attackers that make contact, and causes this tag * to be removed after the source makes a move (or the turn ends, whichever comes first) - * @param pokemon {@linkcode Pokemon} the owner of this tag - * @param lapseType {@linkcode BattlerTagLapseType} the type of functionality invoked in battle + * @param pokemon - The owner of this tag + * @param lapseType - The type of functionality invoked in battle * @returns `true` if invoked with the `AFTER_HIT` lapse type */ lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { @@ -498,8 +562,8 @@ export class ShellTrapTag extends BattlerTag { /** * "Activates" the shell trap, causing the tag owner to move next. - * @param pokemon {@linkcode Pokemon} the owner of this tag - * @param lapseType {@linkcode BattlerTagLapseType} the type of functionality invoked in battle + * @param pokemon - The owner of this tag + * @param lapseType - The type of functionality invoked in battle * @returns `true` if invoked with the `AFTER_HIT` lapse type */ lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { @@ -529,7 +593,8 @@ export class ShellTrapTag extends BattlerTag { } } -export class TrappedTag extends BattlerTag { +export class TrappedTag extends SerializableBattlerTag { + public declare readonly tagType: TrappingBattlerTagType; constructor( tagType: BattlerTagType, lapseType: BattlerTagLapseType, @@ -546,13 +611,13 @@ export class TrappedTag extends BattlerTag { console.warn(`Failed to get source Pokemon for TrappedTag canAdd; id: ${this.sourceId}`); return false; } - - const move = allMoves[this.sourceMove]; + if (this.sourceMove && allMoves[this.sourceMove]?.hitsSubstitute(source, pokemon)) { + return false; + } const isGhost = pokemon.isOfType(PokemonType.GHOST); const isTrapped = pokemon.getTag(TrappedTag); - const hasSubstitute = move.hitsSubstitute(source, pokemon); - return !isTrapped && !isGhost && !hasSubstitute; + return !isTrapped && !isGhost; } onAdd(pokemon: Pokemon): void { @@ -591,9 +656,9 @@ export class TrappedTag extends BattlerTag { * BattlerTag implementing No Retreat's trapping effect. * This is treated separately from other trapping effects to prevent * Ghost-type Pokemon from being able to reuse the move. - * @extends TrappedTag */ class NoRetreatTag extends TrappedTag { + public override readonly tagType = BattlerTagType.NO_RETREAT; constructor(sourceId: number) { super(BattlerTagType.NO_RETREAT, BattlerTagLapseType.CUSTOM, 0, MoveId.NO_RETREAT, sourceId); } @@ -608,6 +673,7 @@ class NoRetreatTag extends TrappedTag { * BattlerTag that represents the {@link https://bulbapedia.bulbagarden.net/wiki/Flinch Flinch} status condition */ export class FlinchedTag extends BattlerTag { + public override readonly tagType = BattlerTagType.FLINCHED; constructor(sourceMove: MoveId) { super(BattlerTagType.FLINCHED, [BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.TURN_END], 1, sourceMove); } @@ -639,6 +705,7 @@ export class FlinchedTag extends BattlerTag { } export class InterruptedTag extends BattlerTag { + public override readonly tagType = BattlerTagType.INTERRUPTED; constructor(sourceMove: MoveId) { super(BattlerTagType.INTERRUPTED, BattlerTagLapseType.PRE_MOVE, 0, sourceMove); } @@ -668,7 +735,8 @@ export class InterruptedTag extends BattlerTag { /** * BattlerTag that represents the {@link https://bulbapedia.bulbagarden.net/wiki/Confusion_(status_condition) Confusion} status condition */ -export class ConfusedTag extends BattlerTag { +export class ConfusedTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.CONFUSED; constructor(turnCount: number, sourceMove: MoveId) { super(BattlerTagType.CONFUSED, BattlerTagLapseType.MOVE, turnCount, sourceMove, undefined, true); } @@ -752,10 +820,10 @@ export class ConfusedTag extends BattlerTag { /** * Tag applied to the {@linkcode Move.DESTINY_BOND} user. - * @extends BattlerTag * @see {@linkcode apply} */ -export class DestinyBondTag extends BattlerTag { +export class DestinyBondTag extends SerializableBattlerTag { + public readonly tagType = BattlerTagType.DESTINY_BOND; constructor(sourceMove: MoveId, sourceId: number) { super(BattlerTagType.DESTINY_BOND, BattlerTagLapseType.PRE_MOVE, 1, sourceMove, sourceId, true); } @@ -765,9 +833,9 @@ export class DestinyBondTag extends BattlerTag { * or after receiving fatal damage. When the damage is fatal, * the attacking Pokemon is taken down as well, unless it's a boss. * - * @param {Pokemon} pokemon Pokemon that is attacking the Destiny Bond user. - * @param {BattlerTagLapseType} lapseType CUSTOM or PRE_MOVE - * @returns false if the tag source fainted or one turn has passed since the application + * @param pokemon - The Pokemon that is attacking the Destiny Bond user. + * @param lapseType - CUSTOM or PRE_MOVE + * @returns `false` if the tag source fainted or one turn has passed since the application */ lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { if (lapseType !== BattlerTagLapseType.CUSTOM) { @@ -811,7 +879,9 @@ export class DestinyBondTag extends BattlerTag { } } -export class InfatuatedTag extends BattlerTag { +// Technically serializable as in a double battle, a pokemon could be infatuated by its ally +export class InfatuatedTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.INFATUATED; constructor(sourceMove: number, sourceId: number) { super(BattlerTagType.INFATUATED, BattlerTagLapseType.MOVE, 1, sourceMove, sourceId); } @@ -901,8 +971,9 @@ export class InfatuatedTag extends BattlerTag { } } -export class SeedTag extends BattlerTag { - private sourceIndex: number; +export class SeedTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.SEEDED; + public readonly sourceIndex: BattlerIndex; constructor(sourceId: number) { super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, MoveId.LEECH_SEED, sourceId, true); @@ -910,11 +981,11 @@ export class SeedTag extends BattlerTag { /** * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag + * @param source - An object containing the fields needed to reconstruct this tag. */ - loadTag(source: BattlerTag | any): void { + override loadTag(source: NonFunctionProperties): void { super.loadTag(source); - this.sourceIndex = source.sourceIndex; + (this as Mutable).sourceIndex = source.sourceIndex; } canAdd(pokemon: Pokemon): boolean { @@ -935,7 +1006,7 @@ export class SeedTag extends BattlerTag { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), }), ); - this.sourceIndex = source.getBattlerIndex(); + (this as Mutable).sourceIndex = source.getBattlerIndex(); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { @@ -990,9 +1061,10 @@ export class SeedTag extends BattlerTag { /** * BattlerTag representing the effects of {@link https://bulbapedia.bulbagarden.net/wiki/Powder_(move) | Powder}. * When the afflicted Pokemon uses a Fire-type move, the move is cancelled, and the - * Pokemon takes damage equal to 1/4 of it's maximum HP (rounded down). + * Pokemon takes damage equal to 1/4 of its maximum HP (rounded down). */ export class PowderTag extends BattlerTag { + public override readonly tagType = BattlerTagType.POWDER; constructor() { super(BattlerTagType.POWDER, [BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.TURN_END], 1); } @@ -1051,7 +1123,7 @@ export class PowderTag extends BattlerTag { } } -export class NightmareTag extends BattlerTag { +export class NightmareTag extends SerializableBattlerTag { constructor() { super(BattlerTagType.NIGHTMARE, BattlerTagLapseType.TURN_END, 1, MoveId.NIGHTMARE); } @@ -1104,7 +1176,7 @@ export class NightmareTag extends BattlerTag { } } -export class FrenzyTag extends BattlerTag { +export class FrenzyTag extends SerializableBattlerTag { constructor(turnCount: number, sourceMove: MoveId, sourceId: number) { super(BattlerTagType.FRENZY, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); } @@ -1124,6 +1196,8 @@ export class FrenzyTag extends BattlerTag { * Encore forces the target Pokemon to use its most-recent move for 3 turns. */ export class EncoreTag extends MoveRestrictionBattlerTag { + public override readonly tagType = BattlerTagType.ENCORE; + /** The ID of the move the user is locked into using */ public moveId: MoveId; constructor(sourceId: number) { @@ -1136,12 +1210,12 @@ export class EncoreTag extends MoveRestrictionBattlerTag { ); } - loadTag(source: BattlerTag | any): void { + override loadTag(source: NonFunctionProperties): void { super.loadTag(source); - this.moveId = source.moveId as MoveId; + this.moveId = source.moveId; } - canAdd(pokemon: Pokemon): boolean { + override canAdd(pokemon: Pokemon): boolean { const lastMove = pokemon.getLastNonVirtualMove(); if (!lastMove) { return false; @@ -1156,10 +1230,7 @@ export class EncoreTag extends MoveRestrictionBattlerTag { return true; } - onAdd(pokemon: Pokemon): void { - // TODO: shouldn't this be `onAdd`? - super.onRemove(pokemon); - + override onAdd(pokemon: Pokemon): void { globalScene.phaseManager.queueMessage( i18next.t("battlerTags:encoreOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), @@ -1199,7 +1270,7 @@ export class EncoreTag extends MoveRestrictionBattlerTag { /** * Checks if the move matches the moveId stored within the tag and returns a boolean value - * @param move {@linkcode MoveId} the move selected + * @param move - The ID of the move selected * @param user N/A * @returns `true` if the move does not match with the moveId stored and as a result, restricted */ @@ -1223,6 +1294,7 @@ export class EncoreTag extends MoveRestrictionBattlerTag { } export class HelpingHandTag extends BattlerTag { + public override readonly tagType = BattlerTagType.HELPING_HAND; constructor(sourceId: number) { super(BattlerTagType.HELPING_HAND, BattlerTagLapseType.TURN_END, 1, MoveId.HELPING_HAND, sourceId); } @@ -1245,16 +1317,16 @@ export class HelpingHandTag extends BattlerTag { /** * Applies the Ingrain tag to a pokemon - * @extends TrappedTag */ export class IngrainTag extends TrappedTag { + public override readonly tagType = BattlerTagType.INGRAIN; constructor(sourceId: number) { super(BattlerTagType.INGRAIN, BattlerTagLapseType.TURN_END, 1, MoveId.INGRAIN, sourceId); } /** * Check if the Ingrain tag can be added to the pokemon - * @param pokemon {@linkcode Pokemon} The pokemon to check if the tag can be added to + * @param pokemon - The pokemon to check if the tag can be added to * @returns boolean True if the tag can be added, false otherwise */ canAdd(pokemon: Pokemon): boolean { @@ -1295,6 +1367,7 @@ export class IngrainTag extends TrappedTag { * end of each turn. */ export class OctolockTag extends TrappedTag { + public override readonly tagType = BattlerTagType.OCTOLOCK; constructor(sourceId: number) { super(BattlerTagType.OCTOLOCK, BattlerTagLapseType.TURN_END, 1, MoveId.OCTOLOCK, sourceId); } @@ -1317,7 +1390,8 @@ export class OctolockTag extends TrappedTag { } } -export class AquaRingTag extends BattlerTag { +export class AquaRingTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.AQUA_RING; constructor() { super(BattlerTagType.AQUA_RING, BattlerTagLapseType.TURN_END, 1, MoveId.AQUA_RING, undefined, true); } @@ -1353,7 +1427,8 @@ export class AquaRingTag extends BattlerTag { } /** Tag used to allow moves that interact with {@link MoveId.MINIMIZE} to function */ -export class MinimizeTag extends BattlerTag { +export class MinimizeTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.MINIMIZED; constructor() { super(BattlerTagType.MINIMIZED, BattlerTagLapseType.TURN_END, 1, MoveId.MINIMIZE); } @@ -1371,7 +1446,8 @@ export class MinimizeTag extends BattlerTag { } } -export class DrowsyTag extends BattlerTag { +export class DrowsyTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.DROWSY; constructor() { super(BattlerTagType.DROWSY, BattlerTagLapseType.TURN_END, 2, MoveId.YAWN); } @@ -1405,7 +1481,9 @@ export class DrowsyTag extends BattlerTag { } export abstract class DamagingTrapTag extends TrappedTag { - private commonAnim: CommonAnim; + public declare readonly tagType: TrappingBattlerTagType; + /** The animation to play during the damage sequence */ + #commonAnim: CommonAnim; constructor( tagType: BattlerTagType, @@ -1416,16 +1494,7 @@ export abstract class DamagingTrapTag extends TrappedTag { ) { super(tagType, BattlerTagLapseType.TURN_END, turnCount, sourceMove, sourceId); - this.commonAnim = commonAnim; - } - - /** - * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag - */ - loadTag(source: BattlerTag | any): void { - super.loadTag(source); - this.commonAnim = source.commonAnim as CommonAnim; + this.#commonAnim = commonAnim; } canAdd(pokemon: Pokemon): boolean { @@ -1443,7 +1512,7 @@ export abstract class DamagingTrapTag extends TrappedTag { moveName: this.getMoveName(), }), ); - phaseManager.unshiftNew("CommonAnimPhase", pokemon.getBattlerIndex(), undefined, this.commonAnim); + phaseManager.unshiftNew("CommonAnimPhase", pokemon.getBattlerIndex(), undefined, this.#commonAnim); const cancelled = new BooleanHolder(false); applyAbAttrs("BlockNonDirectDamageAbAttr", { pokemon, cancelled }); @@ -1459,6 +1528,7 @@ export abstract class DamagingTrapTag extends TrappedTag { // TODO: Condense all these tags into 1 singular tag with a modified message func export class BindTag extends DamagingTrapTag { + public override readonly tagType = BattlerTagType.BIND; constructor(turnCount: number, sourceId: number) { super(BattlerTagType.BIND, CommonAnim.BIND, turnCount, MoveId.BIND, sourceId); } @@ -1479,6 +1549,7 @@ export class BindTag extends DamagingTrapTag { } export class WrapTag extends DamagingTrapTag { + public override readonly tagType = BattlerTagType.WRAP; constructor(turnCount: number, sourceId: number) { super(BattlerTagType.WRAP, CommonAnim.WRAP, turnCount, MoveId.WRAP, sourceId); } @@ -1507,18 +1578,21 @@ export abstract class VortexTrapTag extends DamagingTrapTag { } export class FireSpinTag extends VortexTrapTag { + public override readonly tagType = BattlerTagType.FIRE_SPIN; constructor(turnCount: number, sourceId: number) { super(BattlerTagType.FIRE_SPIN, CommonAnim.FIRE_SPIN, turnCount, MoveId.FIRE_SPIN, sourceId); } } export class WhirlpoolTag extends VortexTrapTag { + public override readonly tagType = BattlerTagType.WHIRLPOOL; constructor(turnCount: number, sourceId: number) { super(BattlerTagType.WHIRLPOOL, CommonAnim.WHIRLPOOL, turnCount, MoveId.WHIRLPOOL, sourceId); } } export class ClampTag extends DamagingTrapTag { + public override readonly tagType = BattlerTagType.CLAMP; constructor(turnCount: number, sourceId: number) { super(BattlerTagType.CLAMP, CommonAnim.CLAMP, turnCount, MoveId.CLAMP, sourceId); } @@ -1538,6 +1612,7 @@ export class ClampTag extends DamagingTrapTag { } export class SandTombTag extends DamagingTrapTag { + public override readonly tagType = BattlerTagType.SAND_TOMB; constructor(turnCount: number, sourceId: number) { super(BattlerTagType.SAND_TOMB, CommonAnim.SAND_TOMB, turnCount, MoveId.SAND_TOMB, sourceId); } @@ -1551,6 +1626,7 @@ export class SandTombTag extends DamagingTrapTag { } export class MagmaStormTag extends DamagingTrapTag { + public override readonly tagType = BattlerTagType.MAGMA_STORM; constructor(turnCount: number, sourceId: number) { super(BattlerTagType.MAGMA_STORM, CommonAnim.MAGMA_STORM, turnCount, MoveId.MAGMA_STORM, sourceId); } @@ -1563,6 +1639,7 @@ export class MagmaStormTag extends DamagingTrapTag { } export class SnapTrapTag extends DamagingTrapTag { + public override readonly tagType = BattlerTagType.SNAP_TRAP; constructor(turnCount: number, sourceId: number) { super(BattlerTagType.SNAP_TRAP, CommonAnim.SNAP_TRAP, turnCount, MoveId.SNAP_TRAP, sourceId); } @@ -1575,6 +1652,7 @@ export class SnapTrapTag extends DamagingTrapTag { } export class ThunderCageTag extends DamagingTrapTag { + public override readonly tagType = BattlerTagType.THUNDER_CAGE; constructor(turnCount: number, sourceId: number) { super(BattlerTagType.THUNDER_CAGE, CommonAnim.THUNDER_CAGE, turnCount, MoveId.THUNDER_CAGE, sourceId); } @@ -1594,6 +1672,7 @@ export class ThunderCageTag extends DamagingTrapTag { } export class InfestationTag extends DamagingTrapTag { + public override readonly tagType = BattlerTagType.INFESTATION; constructor(turnCount: number, sourceId: number) { super(BattlerTagType.INFESTATION, CommonAnim.INFESTATION, turnCount, MoveId.INFESTATION, sourceId); } @@ -1613,7 +1692,8 @@ export class InfestationTag extends DamagingTrapTag { } export class ProtectedTag extends BattlerTag { - constructor(sourceMove: MoveId, tagType: BattlerTagType = BattlerTagType.PROTECTED) { + public declare readonly tagType: ProtectionBattlerTagType; + constructor(sourceMove: MoveId, tagType: ProtectionBattlerTagType = BattlerTagType.PROTECTED) { super(tagType, BattlerTagLapseType.TURN_END, 0, sourceMove); } @@ -1649,14 +1729,13 @@ export class ProtectedTag extends BattlerTag { } /** Class for `BattlerTag`s that apply some effect when hit by a contact move */ -export class ContactProtectedTag extends ProtectedTag { +export abstract class ContactProtectedTag extends ProtectedTag { /** * Function to call when a contact move hits the pokemon with this tag. * @param _attacker - The pokemon using the contact move * @param _user - The pokemon that is being attacked and has the tag - * @param _move - The move used by the attacker */ - onContact(_attacker: Pokemon, _user: Pokemon) {} + abstract onContact(_attacker: Pokemon, _user: Pokemon): void; /** * Lapse the tag and apply `onContact` if the move makes contact and @@ -1686,22 +1765,16 @@ export class ContactProtectedTag extends ProtectedTag { /** * `BattlerTag` class for moves that block damaging moves damage the enemy if the enemy's move makes contact * Used by {@linkcode MoveId.SPIKY_SHIELD} + * + * @sealed */ export class ContactDamageProtectedTag extends ContactProtectedTag { - private damageRatio: number; + public override readonly tagType = BattlerTagType.SPIKY_SHIELD; + #damageRatio: number; constructor(sourceMove: MoveId, damageRatio: number) { super(sourceMove, BattlerTagType.SPIKY_SHIELD); - this.damageRatio = damageRatio; - } - - /** - * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag - */ - loadTag(source: BattlerTag | any): void { - super.loadTag(source); - this.damageRatio = source.damageRatio; + this.#damageRatio = damageRatio; } /** @@ -1713,7 +1786,7 @@ export class ContactDamageProtectedTag extends ContactProtectedTag { const cancelled = new BooleanHolder(false); applyAbAttrs("BlockNonDirectDamageAbAttr", { pokemon: user, cancelled }); if (!cancelled.value) { - attacker.damageAndUpdate(toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), { + attacker.damageAndUpdate(toDmgValue(attacker.getMaxHp() * (1 / this.#damageRatio)), { result: HitResult.INDIRECT, }); } @@ -1721,20 +1794,22 @@ export class ContactDamageProtectedTag extends ContactProtectedTag { } /** Base class for `BattlerTag`s that block damaging moves but not status moves */ -export class DamageProtectedTag extends ContactProtectedTag {} +export abstract class DamageProtectedTag extends ContactProtectedTag { + public declare readonly tagType: DamageProtectedTagType; +} export class ContactSetStatusProtectedTag extends DamageProtectedTag { + public declare readonly tagType: ContactSetStatusProtectedTagType; + /** The status effect applied to attackers */ + #statusEffect: StatusEffect; /** - * @param sourceMove The move that caused the tag to be applied - * @param tagType The type of the tag - * @param statusEffect The status effect to apply to the attacker + * @param sourceMove - The move that caused the tag to be applied + * @param tagType - The type of the tag + * @param statusEffect - The status effect applied to attackers */ - constructor( - sourceMove: MoveId, - tagType: BattlerTagType, - private statusEffect: StatusEffect, - ) { + constructor(sourceMove: MoveId, tagType: ContactSetStatusProtectedTagType, statusEffect: StatusEffect) { super(sourceMove, tagType); + this.#statusEffect = statusEffect; } /** @@ -1743,7 +1818,7 @@ export class ContactSetStatusProtectedTag extends DamageProtectedTag { * @param user - The pokemon that is being attacked and has the tag */ override onContact(attacker: Pokemon, user: Pokemon): void { - attacker.trySetStatus(this.statusEffect, true, user); + attacker.trySetStatus(this.#statusEffect, true, user); } } @@ -1752,24 +1827,15 @@ export class ContactSetStatusProtectedTag extends DamageProtectedTag { * Used by {@linkcode MoveId.KINGS_SHIELD}, {@linkcode MoveId.OBSTRUCT}, {@linkcode MoveId.SILK_TRAP} */ export class ContactStatStageChangeProtectedTag extends DamageProtectedTag { - private stat: BattleStat; - private levels: number; + public declare readonly tagType: ContactStatStageChangeProtectedTagType; + #stat: BattleStat; + #levels: number; - constructor(sourceMove: MoveId, tagType: BattlerTagType, stat: BattleStat, levels: number) { + constructor(sourceMove: MoveId, tagType: ContactStatStageChangeProtectedTagType, stat: BattleStat, levels: number) { super(sourceMove, tagType); - this.stat = stat; - this.levels = levels; - } - - /** - * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag - */ - override loadTag(source: BattlerTag | any): void { - super.loadTag(source); - this.stat = source.stat; - this.levels = source.levels; + this.#stat = stat; + this.#levels = levels; } /** @@ -1782,19 +1848,19 @@ export class ContactStatStageChangeProtectedTag extends DamageProtectedTag { "StatStageChangePhase", attacker.getBattlerIndex(), false, - [this.stat], - this.levels, + [this.#stat], + this.#levels, ); } } /** * `BattlerTag` class for effects that cause the affected Pokemon to survive lethal attacks at 1 HP. - * Used for {@link https://bulbapedia.bulbagarden.net/wiki/Endure_(move) | Endure} and - * Endure Tokens. + * Used for {@link https://bulbapedia.bulbagarden.net/wiki/Endure_(move) | Endure} and endure tokens. */ export class EnduringTag extends BattlerTag { - constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, sourceMove: MoveId) { + public declare readonly tagType: EndureTagType; + constructor(tagType: EndureTagType, lapseType: BattlerTagLapseType, sourceMove: MoveId) { super(tagType, lapseType, 0, sourceMove); } @@ -1823,6 +1889,7 @@ export class EnduringTag extends BattlerTag { } export class SturdyTag extends BattlerTag { + public override readonly tagType = BattlerTagType.STURDY; constructor(sourceMove: MoveId) { super(BattlerTagType.STURDY, BattlerTagLapseType.TURN_END, 0, sourceMove); } @@ -1841,7 +1908,8 @@ export class SturdyTag extends BattlerTag { } } -export class PerishSongTag extends BattlerTag { +export class PerishSongTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.PERISH_SONG; constructor(turnCount: number) { super(BattlerTagType.PERISH_SONG, BattlerTagLapseType.TURN_END, turnCount, MoveId.PERISH_SONG, undefined, true); } @@ -1873,6 +1941,7 @@ export class PerishSongTag extends BattlerTag { * @see {@link https://bulbapedia.bulbagarden.net/wiki/Center_of_attention | Center of Attention} */ export class CenterOfAttentionTag extends BattlerTag { + public override readonly tagType = BattlerTagType.CENTER_OF_ATTENTION; public powder: boolean; constructor(sourceMove: MoveId) { @@ -1899,30 +1968,26 @@ export class CenterOfAttentionTag extends BattlerTag { } } -export class AbilityBattlerTag extends BattlerTag { - public ability: AbilityId; - - constructor(tagType: BattlerTagType, ability: AbilityId, lapseType: BattlerTagLapseType, turnCount: number) { - super(tagType, lapseType, turnCount); - - this.ability = ability; +export class AbilityBattlerTag extends SerializableBattlerTag { + public declare readonly tagType: AbilityBattlerTagType; + #ability: AbilityId; + /** The ability that the tag corresponds to */ + public get ability(): AbilityId { + return this.#ability; } - /** - * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag - */ - loadTag(source: BattlerTag | any): void { - super.loadTag(source); - this.ability = source.ability as AbilityId; + constructor(tagType: AbilityBattlerTagType, ability: AbilityId, lapseType: BattlerTagLapseType, turnCount: number) { + super(tagType, lapseType, turnCount); + + this.#ability = ability; } } /** * Tag used by Unburden to double speed - * @extends AbilityBattlerTag */ export class UnburdenTag extends AbilityBattlerTag { + public override readonly tagType = BattlerTagType.UNBURDEN; constructor() { super(BattlerTagType.UNBURDEN, AbilityId.UNBURDEN, BattlerTagLapseType.CUSTOM, 1); } @@ -1935,6 +2000,7 @@ export class UnburdenTag extends AbilityBattlerTag { } export class TruantTag extends AbilityBattlerTag { + public override readonly tagType = BattlerTagType.TRUANT; constructor() { super(BattlerTagType.TRUANT, AbilityId.TRUANT, BattlerTagLapseType.MOVE, 1); } @@ -1969,6 +2035,7 @@ export class TruantTag extends AbilityBattlerTag { } export class SlowStartTag extends AbilityBattlerTag { + public override readonly tagType = BattlerTagType.SLOW_START; constructor() { super(BattlerTagType.SLOW_START, AbilityId.SLOW_START, BattlerTagLapseType.TURN_END, 5); } @@ -2006,18 +2073,19 @@ export class SlowStartTag extends AbilityBattlerTag { } export class HighestStatBoostTag extends AbilityBattlerTag { + public declare readonly tagType: HighestStatBoostTagType; public stat: Stat; public multiplier: number; - constructor(tagType: BattlerTagType, ability: AbilityId) { + constructor(tagType: HighestStatBoostTagType, ability: AbilityId) { super(tagType, ability, BattlerTagLapseType.CUSTOM, 1); } /** * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag + * @param source - An object containing the fields needed to reconstruct this tag. */ - loadTag(source: BattlerTag | any): void { + loadTag(source: NonFunctionProperties): void { super.loadTag(source); this.stat = source.stat as Stat; this.multiplier = source.multiplier; @@ -2065,43 +2133,32 @@ export class HighestStatBoostTag extends AbilityBattlerTag { } } -export class WeatherHighestStatBoostTag extends HighestStatBoostTag implements WeatherBattlerTag { - public weatherTypes: WeatherType[]; - - constructor(tagType: BattlerTagType, ability: AbilityId, ...weatherTypes: WeatherType[]) { - super(tagType, ability); - this.weatherTypes = weatherTypes; +export class WeatherHighestStatBoostTag extends HighestStatBoostTag { + #weatherTypes: WeatherType[]; + public get weatherTypes(): WeatherType[] { + return this.#weatherTypes; } - /** - * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag - */ - loadTag(source: BattlerTag | any): void { - super.loadTag(source); - this.weatherTypes = source.weatherTypes.map(w => w as WeatherType); + constructor(tagType: HighestStatBoostTagType, ability: AbilityId, ...weatherTypes: WeatherType[]) { + super(tagType, ability); + this.#weatherTypes = weatherTypes; } } -export class TerrainHighestStatBoostTag extends HighestStatBoostTag implements TerrainBattlerTag { - public terrainTypes: TerrainType[]; - - constructor(tagType: BattlerTagType, ability: AbilityId, ...terrainTypes: TerrainType[]) { - super(tagType, ability); - this.terrainTypes = terrainTypes; +export class TerrainHighestStatBoostTag extends HighestStatBoostTag { + #terrainTypes: TerrainType[]; + public get terrainTypes(): TerrainType[] { + return this.#terrainTypes; } - /** - * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag - */ - loadTag(source: BattlerTag | any): void { - super.loadTag(source); - this.terrainTypes = source.terrainTypes.map(w => w as TerrainType); + constructor(tagType: HighestStatBoostTagType, ability: AbilityId, ...terrainTypes: TerrainType[]) { + super(tagType, ability); + this.#terrainTypes = terrainTypes; } } -export class SemiInvulnerableTag extends BattlerTag { +export class SemiInvulnerableTag extends SerializableBattlerTag { + public declare readonly tagType: SemiInvulnerableTagType; constructor(tagType: BattlerTagType, turnCount: number, sourceMove: MoveId) { super(tagType, BattlerTagLapseType.MOVE_EFFECT, turnCount, sourceMove); } @@ -2121,22 +2178,16 @@ export class SemiInvulnerableTag extends BattlerTag { } } -export class TypeImmuneTag extends BattlerTag { - public immuneType: PokemonType; +export class TypeImmuneTag extends SerializableBattlerTag { + #immuneType: PokemonType; + public get immuneType(): PokemonType { + return this.#immuneType; + } constructor(tagType: BattlerTagType, sourceMove: MoveId, immuneType: PokemonType, length = 1) { super(tagType, BattlerTagLapseType.TURN_END, length, sourceMove, undefined, true); - this.immuneType = immuneType; - } - - /** - * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag - */ - loadTag(source: BattlerTag | any): void { - super.loadTag(source); - this.immuneType = source.immuneType as PokemonType; + this.#immuneType = immuneType; } } @@ -2174,10 +2225,20 @@ export class FloatingTag extends TypeImmuneTag { } } -export class TypeBoostTag extends BattlerTag { - public boostedType: PokemonType; - public boostValue: number; - public oneUse: boolean; +export class TypeBoostTag extends SerializableBattlerTag { + #boostedType: PokemonType; + #boostValue: number; + #oneUse: boolean; + + public get boostedType(): PokemonType { + return this.#boostedType; + } + public get boostValue(): number { + return this.#boostValue; + } + public get oneUse(): boolean { + return this.#oneUse; + } constructor( tagType: BattlerTagType, @@ -2188,20 +2249,9 @@ export class TypeBoostTag extends BattlerTag { ) { super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove); - this.boostedType = boostedType; - this.boostValue = boostValue; - this.oneUse = oneUse; - } - - /** - * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag - */ - loadTag(source: BattlerTag | any): void { - super.loadTag(source); - this.boostedType = source.boostedType as PokemonType; - this.boostValue = source.boostValue; - this.oneUse = source.oneUse; + this.#boostedType = boostedType; + this.#boostValue = boostValue; + this.#oneUse = oneUse; } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { @@ -2224,7 +2274,7 @@ export class TypeBoostTag extends BattlerTag { } } -export class CritBoostTag extends BattlerTag { +export class CritBoostTag extends SerializableBattlerTag { constructor(tagType: BattlerTagType, sourceMove: MoveId) { super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove, undefined, true); } @@ -2256,7 +2306,6 @@ export class CritBoostTag extends BattlerTag { /** * Tag for the effects of Dragon Cheer, which boosts the critical hit ratio of the user's allies. - * @extends {CritBoostTag} */ export class DragonCheerTag extends CritBoostTag { /** The types of the user's ally when the tag is added */ @@ -2273,22 +2322,12 @@ export class DragonCheerTag extends CritBoostTag { } } -export class SaltCuredTag extends BattlerTag { - private sourceIndex: number; - +export class SaltCuredTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.SALT_CURED; constructor(sourceId: number) { super(BattlerTagType.SALT_CURED, BattlerTagLapseType.TURN_END, 1, MoveId.SALT_CURE, sourceId); } - /** - * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag - */ - loadTag(source: BattlerTag | any): void { - super.loadTag(source); - this.sourceIndex = source.sourceIndex; - } - onAdd(pokemon: Pokemon): void { const source = this.getSourcePokemon(); if (!source) { @@ -2302,7 +2341,6 @@ export class SaltCuredTag extends BattlerTag { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), }), ); - this.sourceIndex = source.getBattlerIndex(); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { @@ -2338,22 +2376,11 @@ export class SaltCuredTag extends BattlerTag { } } -export class CursedTag extends BattlerTag { - private sourceIndex: number; - +export class CursedTag extends SerializableBattlerTag { constructor(sourceId: number) { super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, MoveId.CURSE, sourceId, true); } - /** - * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag - */ - loadTag(source: BattlerTag | any): void { - super.loadTag(source); - this.sourceIndex = source.sourceIndex; - } - onAdd(pokemon: Pokemon): void { const source = this.getSourcePokemon(); if (!source) { @@ -2362,7 +2389,6 @@ export class CursedTag extends BattlerTag { } super.onAdd(pokemon); - this.sourceIndex = source.getBattlerIndex(); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { @@ -2392,10 +2418,11 @@ export class CursedTag extends BattlerTag { return ret; } } + /** * Battler tag for attacks that remove a type post use. */ -export class RemovedTypeTag extends BattlerTag { +export class RemovedTypeTag extends SerializableBattlerTag { constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, sourceMove: MoveId) { super(tagType, lapseType, 1, sourceMove); } @@ -2405,7 +2432,7 @@ export class RemovedTypeTag extends BattlerTag { * Battler tag for effects that ground the source, allowing Ground-type moves to hit them. * @description `IGNORE_FLYING`: Persistent grounding effects (i.e. from Smack Down and Thousand Waves) */ -export class GroundedTag extends BattlerTag { +export class GroundedTag extends SerializableBattlerTag { constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, sourceMove: MoveId) { super(tagType, lapseType, 1, sourceMove); } @@ -2478,15 +2505,16 @@ export class RoostedTag extends BattlerTag { } /** Common attributes of form change abilities that block damage */ -export class FormBlockDamageTag extends BattlerTag { - constructor(tagType: BattlerTagType) { +export class FormBlockDamageTag extends SerializableBattlerTag { + public declare readonly tagType: BattlerTagType.ICE_FACE | BattlerTagType.DISGUISE; + constructor(tagType: BattlerTagType.ICE_FACE | BattlerTagType.DISGUISE) { super(tagType, BattlerTagLapseType.CUSTOM, 1); } /** * Determines if the tag can be added to the Pokémon. - * @param {Pokemon} pokemon The Pokémon to which the tag might be added. - * @returns {boolean} True if the tag can be added, false otherwise. + * @param pokemon - The Pokémon to which the tag might be added. + * @returns `true` if the tag can be added, `false` otherwise. */ canAdd(pokemon: Pokemon): boolean { return pokemon.formIndex === 0; @@ -2508,7 +2536,7 @@ export class FormBlockDamageTag extends BattlerTag { /** * Removes the tag from the Pokémon. * Triggers a form change when the tag is removed. - * @param {Pokemon} pokemon The Pokémon from which the tag is removed. + * @param pokemon - The Pokémon from which the tag is removed. */ onRemove(pokemon: Pokemon): void { super.onRemove(pokemon); @@ -2516,12 +2544,14 @@ export class FormBlockDamageTag extends BattlerTag { globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger); } } + /** Provides the additional weather-based effects of the Ice Face ability */ export class IceFaceBlockDamageTag extends FormBlockDamageTag { + public override readonly tagType = BattlerTagType.ICE_FACE; /** * Determines if the tag can be added to the Pokémon. - * @param {Pokemon} pokemon The Pokémon to which the tag might be added. - * @returns {boolean} True if the tag can be added, false otherwise. + * @param pokemon - The Pokémon to which the tag might be added. + * @returns `true` if the tag can be added, `false` otherwise. */ canAdd(pokemon: Pokemon): boolean { const weatherType = globalScene.arena.weather?.weatherType; @@ -2535,20 +2565,17 @@ export class IceFaceBlockDamageTag extends FormBlockDamageTag { * Battler tag indicating a Tatsugiri with {@link https://bulbapedia.bulbagarden.net/wiki/Commander_(Ability) | Commander} * has entered the tagged Pokemon's mouth. */ -export class CommandedTag extends BattlerTag { - private _tatsugiriFormKey: string; +export class CommandedTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.COMMANDED; + public readonly tatsugiriFormKey: string; constructor(sourceId: number) { super(BattlerTagType.COMMANDED, BattlerTagLapseType.CUSTOM, 0, MoveId.NONE, sourceId); } - public get tatsugiriFormKey(): string { - return this._tatsugiriFormKey; - } - /** Caches the Tatsugiri's form key and sharply boosts the tagged Pokemon's stats */ override onAdd(pokemon: Pokemon): void { - this._tatsugiriFormKey = this.getSourcePokemon()?.getFormKey() ?? "curly"; + (this as Mutable).tatsugiriFormKey = this.getSourcePokemon()?.getFormKey() ?? "curly"; globalScene.phaseManager.unshiftNew( "StatStageChangePhase", pokemon.getBattlerIndex(), @@ -2565,9 +2592,9 @@ export class CommandedTag extends BattlerTag { } } - override loadTag(source: BattlerTag | any): void { + override loadTag(source: NonFunctionProperties): void { super.loadTag(source); - this._tatsugiriFormKey = source._tatsugiriFormKey; + (this as Mutable).tatsugiriFormKey = source.tatsugiriFormKey; } } @@ -2581,7 +2608,8 @@ export class CommandedTag extends BattlerTag { * - Removing stacks decreases DEF and SPDEF, independently, by one stage for each stack that successfully changed * the stat when added. */ -export class StockpilingTag extends BattlerTag { +export class StockpilingTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.STOCKPILING; public stockpiledCount = 0; public statChangeCounts: { [Stat.DEF]: number; [Stat.SPDEF]: number } = { [Stat.DEF]: 0, @@ -2604,7 +2632,7 @@ export class StockpilingTag extends BattlerTag { } }; - loadTag(source: BattlerTag | any): void { + override loadTag(source: NonFunctionProperties): void { super.loadTag(source); this.stockpiledCount = source.stockpiledCount || 0; this.statChangeCounts = { @@ -2687,10 +2715,10 @@ export class StockpilingTag extends BattlerTag { /** * Battler tag for Gulp Missile used by Cramorant. - * @extends BattlerTag */ -export class GulpMissileTag extends BattlerTag { - constructor(tagType: BattlerTagType, sourceMove: MoveId) { +export class GulpMissileTag extends SerializableBattlerTag { + public declare readonly tagType: BattlerTagType.GULP_MISSILE_ARROKUDA | BattlerTagType.GULP_MISSILE_PIKACHU; + constructor(tagType: BattlerTagType.GULP_MISSILE_ARROKUDA | BattlerTagType.GULP_MISSILE_PIKACHU, sourceMove: MoveId) { super(tagType, BattlerTagLapseType.HIT, 0, sourceMove); } @@ -2729,11 +2757,12 @@ export class GulpMissileTag extends BattlerTag { /** * Gulp Missile's initial form changes are triggered by using Surf and Dive. - * @param {Pokemon} pokemon The Pokemon with Gulp Missile ability. + * @param pokemon - The Pokemon with Gulp Missile ability. * @returns Whether the BattlerTag can be added. */ canAdd(pokemon: Pokemon): boolean { - const isSurfOrDive = [MoveId.SURF, MoveId.DIVE].includes(this.sourceMove); + // Bang here is OK as if sourceMove was undefined, this would just evaluate to false + const isSurfOrDive = [MoveId.SURF, MoveId.DIVE].includes(this.sourceMove!); const isNormalForm = pokemon.formIndex === 0 && !pokemon.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA) && @@ -2755,52 +2784,46 @@ export class GulpMissileTag extends BattlerTag { } /** - * Tag that makes the target drop all of it type immunities + * Tag that makes the target drop the immunities granted by a particular type * and all accuracy checks ignore its evasiveness stat. * * Applied by moves: {@linkcode MoveId.ODOR_SLEUTH | Odor Sleuth}, * {@linkcode MoveId.MIRACLE_EYE | Miracle Eye} and {@linkcode MoveId.FORESIGHT | Foresight}. * - * @extends BattlerTag * @see {@linkcode ignoreImmunity} */ -export class ExposedTag extends BattlerTag { - private defenderType: PokemonType; - private allowedTypes: PokemonType[]; +export class ExposedTag extends SerializableBattlerTag { + public declare readonly tagType: BattlerTagType.IGNORE_DARK | BattlerTagType.IGNORE_GHOST; + #defenderType: PokemonType; + #allowedTypes: readonly PokemonType[]; - constructor(tagType: BattlerTagType, sourceMove: MoveId, defenderType: PokemonType, allowedTypes: PokemonType[]) { + constructor( + tagType: BattlerTagType.IGNORE_DARK | BattlerTagType.IGNORE_GHOST, + sourceMove: MoveId, + defenderType: PokemonType, + allowedTypes: PokemonType[], + ) { super(tagType, BattlerTagLapseType.CUSTOM, 1, sourceMove); - this.defenderType = defenderType; - this.allowedTypes = allowedTypes; + this.#defenderType = defenderType; + this.#allowedTypes = allowedTypes; } /** - * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag - */ - loadTag(source: BattlerTag | any): void { - super.loadTag(source); - this.defenderType = source.defenderType as PokemonType; - this.allowedTypes = source.allowedTypes as PokemonType[]; - } - - /** - * @param types {@linkcode PokemonType} of the defending Pokemon - * @param moveType {@linkcode PokemonType} of the move targetting it + * @param type - The defending type to check against + * @param moveType - The pokemon type of the move being used * @returns `true` if the move should be allowed to target the defender. */ ignoreImmunity(type: PokemonType, moveType: PokemonType): boolean { - return type === this.defenderType && this.allowedTypes.includes(moveType); + return type === this.#defenderType && this.#allowedTypes.includes(moveType); } } /** * Tag that prevents HP recovery from held items and move effects. It also blocks the usage of recovery moves. * Applied by moves: {@linkcode MoveId.HEAL_BLOCK | Heal Block (5 turns)}, {@linkcode MoveId.PSYCHIC_NOISE | Psychic Noise (2 turns)} - * - * @extends MoveRestrictionBattlerTag */ export class HealBlockTag extends MoveRestrictionBattlerTag { + public override readonly tagType = BattlerTagType.HEAL_BLOCK; constructor(turnCount: number, sourceMove: MoveId) { super( BattlerTagType.HEAL_BLOCK, @@ -2818,7 +2841,7 @@ export class HealBlockTag extends MoveRestrictionBattlerTag { /** * Checks if a move is disabled under Heal Block - * @param {MoveId} move {@linkcode MoveId} the move ID + * @param move - {@linkcode MoveId | ID} of the move being used * @returns `true` if the move has a TRIAGE_MOVE flag and is a status move */ override isMoveRestricted(move: MoveId): boolean { @@ -2828,9 +2851,9 @@ export class HealBlockTag extends MoveRestrictionBattlerTag { /** * Checks if a move is disabled under Heal Block because of its choice of target * Implemented b/c of Pollen Puff - * @param {MoveId} move {@linkcode MoveId} the move ID - * @param {Pokemon} user {@linkcode Pokemon} the move user - * @param {Pokemon} target {@linkcode Pokemon} the target of the move + * @param move - {@linkcode MoveId | ID} of the move being used + * @param user - The pokemon using the move + * @param target - The target of the move * @returns `true` if the move cannot be used because the target is an ally */ override isMoveTargetRestricted(move: MoveId, user: Pokemon, target: Pokemon) { @@ -2851,10 +2874,9 @@ export class HealBlockTag extends MoveRestrictionBattlerTag { } /** - * @override - * @param {Pokemon} pokemon {@linkcode Pokemon} attempting to use the restricted move - * @param {MoveId} move {@linkcode MoveId} ID of the move being interrupted - * @returns {string} text to display when the move is interrupted + * @param pokemon - {@linkcode Pokemon} attempting to use the restricted move + * @param move - {@linkcode MoveId | ID} of the move being interrupted + * @returns Text to display when the move is interrupted */ override interruptedText(pokemon: Pokemon, move: MoveId): string { return i18next.t("battle:moveDisabledHealBlock", { @@ -2880,17 +2902,17 @@ export class HealBlockTag extends MoveRestrictionBattlerTag { /** * Tag that doubles the type effectiveness of Fire-type moves. - * @extends BattlerTag */ -export class TarShotTag extends BattlerTag { +export class TarShotTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.TAR_SHOT; constructor() { super(BattlerTagType.TAR_SHOT, BattlerTagLapseType.CUSTOM, 0); } /** * If the Pokemon is terastallized, the tag cannot be added. - * @param {Pokemon} pokemon the {@linkcode Pokemon} to which the tag is added - * @returns whether the tag is applied + * @param pokemon - The pokemon to check + * @returns Whether the tag can be added */ override canAdd(pokemon: Pokemon): boolean { return !pokemon.isTerastallized; @@ -2910,6 +2932,7 @@ export class TarShotTag extends BattlerTag { * While this tag is in effect, the afflicted Pokemon's moves are changed to Electric type. */ export class ElectrifiedTag extends BattlerTag { + public override readonly tagType = BattlerTagType.ELECTRIFIED; constructor() { super(BattlerTagType.ELECTRIFIED, BattlerTagLapseType.TURN_END, 1, MoveId.ELECTRIFY); } @@ -2928,7 +2951,8 @@ export class ElectrifiedTag extends BattlerTag { * Battler Tag that keeps track of how many times the user has Autotomized * Each count of Autotomization reduces the weight by 100kg */ -export class AutotomizedTag extends BattlerTag { +export class AutotomizedTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.AUTOTOMIZED; public autotomizeCount = 0; constructor(sourceMove: MoveId = MoveId.AUTOTOMIZE) { super(BattlerTagType.AUTOTOMIZED, BattlerTagLapseType.CUSTOM, 1, sourceMove); @@ -2954,20 +2978,45 @@ export class AutotomizedTag extends BattlerTag { onOverlap(pokemon: Pokemon): void { this.onAdd(pokemon); } + + loadTag(source: NonFunctionProperties): void { + super.loadTag(source); + this.autotomizeCount = source.autotomizeCount; + } } /** * Tag implementing the {@link https://bulbapedia.bulbagarden.net/wiki/Substitute_(doll)#Effect | Substitute Doll} effect, * for use with the moves Substitute and Shed Tail. Pokemon with this tag deflect most forms of received attack damage * onto the tag. This tag also grants immunity to most Status moves and several move effects. + * + * @sealed */ -export class SubstituteTag extends BattlerTag { +export class SubstituteTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.SUBSTITUTE; /** The substitute's remaining HP. If HP is depleted, the Substitute fades. */ public hp: number; + + //#region non-serializable properties /** A reference to the sprite representing the Substitute doll */ - public sprite: Phaser.GameObjects.Sprite; + #sprite: Phaser.GameObjects.Sprite; + /** A reference to the sprite representing the Substitute doll */ + public get sprite(): Phaser.GameObjects.Sprite { + return this.#sprite; + } + public set sprite(value: Phaser.GameObjects.Sprite) { + this.#sprite = value; + } /** Is the source Pokemon "in focus," i.e. is it fully visible on the field? */ - public sourceInFocus: boolean; + #sourceInFocus: boolean; + /** Is the source Pokemon "in focus," i.e. is it fully visible on the field? */ + public get sourceInFocus(): boolean { + return this.#sourceInFocus; + } + public set sourceInFocus(value: boolean) { + this.#sourceInFocus = value; + } + //#endregion non-serializable properties constructor(sourceMove: MoveId, sourceId: number) { super( @@ -3078,9 +3127,9 @@ export class SubstituteTag extends BattlerTag { /** * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag + * @param source - An object containing the necessary properties to load the tag */ - loadTag(source: BattlerTag | any): void { + override loadTag(source: NonFunctionProperties): void { super.loadTag(source); this.hp = source.hp; } @@ -3093,6 +3142,7 @@ export class SubstituteTag extends BattlerTag { * Currently used only in MysteryEncounters to provide start of fight stat buffs. */ export class MysteryEncounterPostSummonTag extends BattlerTag { + public override readonly tagType = BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON; constructor() { super(BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON, BattlerTagLapseType.CUSTOM, 1); } @@ -3126,15 +3176,11 @@ export class MysteryEncounterPostSummonTag extends BattlerTag { * Torment does not interrupt the move if the move is performed consecutively in the same turn and right after Torment is applied */ export class TormentTag extends MoveRestrictionBattlerTag { + public override readonly tagType = BattlerTagType.TORMENT; constructor(sourceId: number) { super(BattlerTagType.TORMENT, BattlerTagLapseType.AFTER_MOVE, 1, MoveId.TORMENT, sourceId); } - /** - * Adds the battler tag to the target Pokemon and defines the private class variable 'target' - * 'Target' is used to track the Pokemon's current status - * @param {Pokemon} pokemon the Pokemon tormented - */ override onAdd(pokemon: Pokemon) { super.onAdd(pokemon); globalScene.phaseManager.queueMessage( @@ -3147,7 +3193,7 @@ export class TormentTag extends MoveRestrictionBattlerTag { /** * Torment only ends when the affected Pokemon leaves the battle field - * @param {Pokemon} pokemon the Pokemon under the effects of Torment + * @param pokemon - The Pokemon under the effects of Torment * @param _tagType * @returns `true` if still present | `false` if not */ @@ -3156,8 +3202,8 @@ export class TormentTag extends MoveRestrictionBattlerTag { } /** - * This checks if the current move used is identical to the last used move with a {@linkcode MoveResult} of `SUCCESS`/`MISS` - * @param {MoveId} move the move under investigation + * Check if the current move used is identical to the last used move with a {@linkcode MoveResult} of `SUCCESS`/`MISS` + * @param move - The move under investigation * @returns `true` if there is valid consecutive usage | `false` if the moves are different from each other */ public override isMoveRestricted(move: MoveId, user: Pokemon): boolean { @@ -3189,6 +3235,7 @@ export class TormentTag extends MoveRestrictionBattlerTag { * The tag is removed after 4 turns. */ export class TauntTag extends MoveRestrictionBattlerTag { + public override readonly tagType = BattlerTagType.TAUNT; constructor() { super(BattlerTagType.TAUNT, [BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE], 4, MoveId.TAUNT); } @@ -3214,8 +3261,8 @@ export class TauntTag extends MoveRestrictionBattlerTag { } /** - * Checks if a move is a status move and determines its restriction status on that basis - * @param {MoveId} move the move under investigation + * Check if a move is a status move and determines its restriction status on that basis + * @param move - The move under investigation * @returns `true` if the move is a status move */ override isMoveRestricted(move: MoveId): boolean { @@ -3243,6 +3290,7 @@ export class TauntTag extends MoveRestrictionBattlerTag { * The tag is only removed when the source-user is removed from the field. */ export class ImprisonTag extends MoveRestrictionBattlerTag { + public override readonly tagType = BattlerTagType.IMPRISON; constructor(sourceId: number) { super( BattlerTagType.IMPRISON, @@ -3255,8 +3303,7 @@ export class ImprisonTag extends MoveRestrictionBattlerTag { /** * Checks if the source of Imprison is still active - * @override - * @param pokemon The pokemon this tag is attached to + * @param pokemon - The pokemon this tag is attached to * @returns `true` if the source is still active */ public override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { @@ -3273,8 +3320,7 @@ export class ImprisonTag extends MoveRestrictionBattlerTag { /** * Checks if the source of the tag has the parameter move in its moveset and that the source is still active - * @override - * @param {MoveId} move the move under investigation + * @param move - The move under investigation * @returns `false` if either condition is not met */ public override isMoveRestricted(move: MoveId, _user: Pokemon): boolean { @@ -3306,7 +3352,8 @@ export class ImprisonTag extends MoveRestrictionBattlerTag { * For three turns, starting from the turn of hit, at the end of each turn, the target Pokemon's speed will decrease by 1. * The tag can also expire by taking the target Pokemon off the field, or the Pokemon that originally used the move. */ -export class SyrupBombTag extends BattlerTag { +export class SyrupBombTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.SYRUP_BOMB; constructor(sourceId: number) { super(BattlerTagType.SYRUP_BOMB, BattlerTagLapseType.TURN_END, 3, MoveId.SYRUP_BOMB, sourceId); } @@ -3368,7 +3415,8 @@ export class SyrupBombTag extends BattlerTag { * The effects of Telekinesis can be baton passed to a teammate. * @see {@link https://bulbapedia.bulbagarden.net/wiki/Telekinesis_(move) | MoveId.TELEKINESIS} */ -export class TelekinesisTag extends BattlerTag { +export class TelekinesisTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.TELEKINESIS; constructor(sourceMove: MoveId) { super( BattlerTagType.TELEKINESIS, @@ -3391,9 +3439,9 @@ export class TelekinesisTag extends BattlerTag { /** * Tag that swaps the user's base ATK stat with its base DEF stat. - * @extends BattlerTag */ -export class PowerTrickTag extends BattlerTag { +export class PowerTrickTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.POWER_TRICK; constructor(sourceMove: MoveId, sourceId: number) { super(BattlerTagType.POWER_TRICK, BattlerTagLapseType.CUSTOM, 0, sourceMove, sourceId, true); } @@ -3418,7 +3466,7 @@ export class PowerTrickTag extends BattlerTag { /** * Removes the Power Trick tag and reverts any stat changes if the tag is already applied. - * @param {Pokemon} pokemon The {@linkcode Pokemon} that already has the Power Trick tag. + * @param pokemon - The {@linkcode Pokemon} that already has the Power Trick tag. */ onOverlap(pokemon: Pokemon): void { pokemon.removeTag(this.tagType); @@ -3426,7 +3474,7 @@ export class PowerTrickTag extends BattlerTag { /** * Swaps the user's base ATK stat with its base DEF stat. - * @param {Pokemon} pokemon The {@linkcode Pokemon} whose stats will be swapped. + * @param pokemon - The {@linkcode Pokemon} whose stats will be swapped. */ swapStat(pokemon: Pokemon): void { const temp = pokemon.getStat(Stat.ATK, false); @@ -3440,7 +3488,8 @@ export class PowerTrickTag extends BattlerTag { * If this tag is active when the bearer faints from an opponent's move, the tag reduces that move's PP to 0. * Otherwise, it lapses when the bearer makes another move. */ -export class GrudgeTag extends BattlerTag { +export class GrudgeTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.GRUDGE; constructor() { super(BattlerTagType.GRUDGE, [BattlerTagLapseType.CUSTOM, BattlerTagLapseType.PRE_MOVE], 1, MoveId.GRUDGE); } @@ -3458,7 +3507,7 @@ export class GrudgeTag extends BattlerTag { * Activates Grudge's special effect on the attacking Pokemon and lapses the tag. * @param pokemon * @param lapseType - * @param sourcePokemon {@linkcode Pokemon} the source of the move that fainted the tag's bearer + * @param sourcePokemon - The source of the move that fainted the tag's bearer * @returns `false` if Grudge activates its effect or lapses */ override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType, sourcePokemon?: Pokemon): boolean { @@ -3486,6 +3535,7 @@ export class GrudgeTag extends BattlerTag { * Tag used to heal the user of Psycho Shift of its status effect if Psycho Shift succeeds in transferring its status effect to the target Pokemon */ export class PsychoShiftTag extends BattlerTag { + public override readonly tagType = BattlerTagType.PSYCHO_SHIFT; constructor() { super(BattlerTagType.PSYCHO_SHIFT, BattlerTagLapseType.AFTER_MOVE, 1, MoveId.PSYCHO_SHIFT); } @@ -3510,6 +3560,7 @@ export class PsychoShiftTag extends BattlerTag { * Tag associated with the move Magic Coat. */ export class MagicCoatTag extends BattlerTag { + public override readonly tagType = BattlerTagType.MAGIC_COAT; constructor() { super(BattlerTagType.MAGIC_COAT, BattlerTagLapseType.TURN_END, 1, MoveId.MAGIC_COAT); } @@ -3729,19 +3780,18 @@ export function getBattlerTag( return new PsychoShiftTag(); case BattlerTagType.MAGIC_COAT: return new MagicCoatTag(); - case BattlerTagType.NONE: - default: - return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); } } /** * When given a battler tag or json representing one, creates an actual BattlerTag object with the same data. - * @param {BattlerTag | any} source A battler tag - * @return {BattlerTag} The valid battler tag + * @param source - An object containing the data necessary to reconstruct the BattlerTag. + * @returns The valid battler tag */ -export function loadBattlerTag(source: BattlerTag | any): BattlerTag { - const tag = getBattlerTag(source.tagType, source.turnCount, source.sourceMove, source.sourceId); +export function loadBattlerTag(source: SerializableBattlerTag): BattlerTag { + // TODO: Remove this bang by fixing the signature of `getBattlerTag` + // to allow undefined sourceIds and sourceMoves (with appropriate fallback for tags that require it) + const tag = getBattlerTag(source.tagType, source.turnCount, source.sourceMove!, source.sourceId!); tag.loadTag(source); return tag; } @@ -3749,8 +3799,8 @@ export function loadBattlerTag(source: BattlerTag | any): BattlerTag { /** * Helper function to verify that the current phase is a MoveEffectPhase and provide quick access to commonly used fields * - * @param _pokemon {@linkcode Pokemon} The Pokémon used to access the current phase - * @returns null if current phase is not MoveEffectPhase, otherwise Object containing the {@linkcode MoveEffectPhase}, and its + * @param _pokemon - The Pokémon used to access the current phase (unused) + * @returns `null` if current phase is not MoveEffectPhase, otherwise Object containing the {@linkcode MoveEffectPhase}, and its * corresponding {@linkcode Move} and user {@linkcode Pokemon} */ function getMoveEffectPhaseData(_pokemon: Pokemon): { phase: MoveEffectPhase; attacker: Pokemon; move: Move } | null { @@ -3764,3 +3814,104 @@ function getMoveEffectPhaseData(_pokemon: Pokemon): { phase: MoveEffectPhase; at } return null; } + +/** + * Map from {@linkcode BattlerTagType} to the corresponding {@linkcode BattlerTag} class. + */ +export type BattlerTagTypeMap = { + [BattlerTagType.RECHARGING]: RechargingTag; + [BattlerTagType.SHELL_TRAP]: ShellTrapTag; + [BattlerTagType.FLINCHED]: FlinchedTag; + [BattlerTagType.INTERRUPTED]: InterruptedTag; + [BattlerTagType.CONFUSED]: ConfusedTag; + [BattlerTagType.INFATUATED]: InfatuatedTag; + [BattlerTagType.SEEDED]: SeedTag; + [BattlerTagType.POWDER]: PowderTag; + [BattlerTagType.NIGHTMARE]: NightmareTag; + [BattlerTagType.FRENZY]: FrenzyTag; + [BattlerTagType.CHARGING]: BattlerTag; + [BattlerTagType.ENCORE]: EncoreTag; + [BattlerTagType.HELPING_HAND]: HelpingHandTag; + [BattlerTagType.INGRAIN]: IngrainTag; + [BattlerTagType.AQUA_RING]: AquaRingTag; + [BattlerTagType.DROWSY]: DrowsyTag; + [BattlerTagType.TRAPPED]: TrappedTag; + [BattlerTagType.NO_RETREAT]: NoRetreatTag; + [BattlerTagType.BIND]: BindTag; + [BattlerTagType.WRAP]: WrapTag; + [BattlerTagType.FIRE_SPIN]: FireSpinTag; + [BattlerTagType.WHIRLPOOL]: WhirlpoolTag; + [BattlerTagType.CLAMP]: ClampTag; + [BattlerTagType.SAND_TOMB]: SandTombTag; + [BattlerTagType.MAGMA_STORM]: MagmaStormTag; + [BattlerTagType.SNAP_TRAP]: SnapTrapTag; + [BattlerTagType.THUNDER_CAGE]: ThunderCageTag; + [BattlerTagType.INFESTATION]: InfestationTag; + [BattlerTagType.PROTECTED]: ProtectedTag; + [BattlerTagType.SPIKY_SHIELD]: ContactDamageProtectedTag; + [BattlerTagType.KINGS_SHIELD]: ContactStatStageChangeProtectedTag; + [BattlerTagType.OBSTRUCT]: ContactStatStageChangeProtectedTag; + [BattlerTagType.SILK_TRAP]: ContactStatStageChangeProtectedTag; + [BattlerTagType.BANEFUL_BUNKER]: ContactSetStatusProtectedTag; + [BattlerTagType.BURNING_BULWARK]: ContactSetStatusProtectedTag; + [BattlerTagType.ENDURING]: EnduringTag; + [BattlerTagType.ENDURE_TOKEN]: EnduringTag; + [BattlerTagType.STURDY]: SturdyTag; + [BattlerTagType.PERISH_SONG]: PerishSongTag; + [BattlerTagType.CENTER_OF_ATTENTION]: CenterOfAttentionTag; + [BattlerTagType.TRUANT]: TruantTag; + [BattlerTagType.SLOW_START]: SlowStartTag; + [BattlerTagType.PROTOSYNTHESIS]: WeatherHighestStatBoostTag; + [BattlerTagType.QUARK_DRIVE]: TerrainHighestStatBoostTag; + [BattlerTagType.FLYING]: SemiInvulnerableTag; + [BattlerTagType.UNDERGROUND]: SemiInvulnerableTag; + [BattlerTagType.UNDERWATER]: SemiInvulnerableTag; + [BattlerTagType.HIDDEN]: SemiInvulnerableTag; + [BattlerTagType.FIRE_BOOST]: TypeBoostTag; + [BattlerTagType.CRIT_BOOST]: CritBoostTag; + [BattlerTagType.DRAGON_CHEER]: DragonCheerTag; + [BattlerTagType.ALWAYS_CRIT]: BattlerTag; + [BattlerTagType.IGNORE_ACCURACY]: BattlerTag; + [BattlerTagType.ALWAYS_GET_HIT]: BattlerTag; + [BattlerTagType.RECEIVE_DOUBLE_DAMAGE]: BattlerTag; + [BattlerTagType.BYPASS_SLEEP]: BattlerTag; + [BattlerTagType.IGNORE_FLYING]: GroundedTag; + [BattlerTagType.ROOSTED]: RoostedTag; + [BattlerTagType.BURNED_UP]: RemovedTypeTag; + [BattlerTagType.DOUBLE_SHOCKED]: RemovedTypeTag; + [BattlerTagType.SALT_CURED]: SaltCuredTag; + [BattlerTagType.CURSED]: CursedTag; + [BattlerTagType.CHARGED]: TypeBoostTag; + [BattlerTagType.FLOATING]: FloatingTag; + [BattlerTagType.MINIMIZED]: MinimizeTag; + [BattlerTagType.DESTINY_BOND]: DestinyBondTag; + [BattlerTagType.ICE_FACE]: IceFaceBlockDamageTag; + [BattlerTagType.DISGUISE]: FormBlockDamageTag; + [BattlerTagType.COMMANDED]: CommandedTag; + [BattlerTagType.STOCKPILING]: StockpilingTag; + [BattlerTagType.OCTOLOCK]: OctolockTag; + [BattlerTagType.DISABLED]: DisabledTag; + [BattlerTagType.IGNORE_GHOST]: ExposedTag; + [BattlerTagType.IGNORE_DARK]: ExposedTag; + [BattlerTagType.GULP_MISSILE_ARROKUDA]: GulpMissileTag; + [BattlerTagType.GULP_MISSILE_PIKACHU]: GulpMissileTag; + [BattlerTagType.BEAK_BLAST_CHARGING]: BeakBlastChargingTag; + [BattlerTagType.TAR_SHOT]: TarShotTag; + [BattlerTagType.ELECTRIFIED]: ElectrifiedTag; + [BattlerTagType.THROAT_CHOPPED]: ThroatChoppedTag; + [BattlerTagType.GORILLA_TACTICS]: GorillaTacticsTag; + [BattlerTagType.UNBURDEN]: UnburdenTag; + [BattlerTagType.SUBSTITUTE]: SubstituteTag; + [BattlerTagType.AUTOTOMIZED]: AutotomizedTag; + [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON]: MysteryEncounterPostSummonTag; + [BattlerTagType.HEAL_BLOCK]: HealBlockTag; + [BattlerTagType.TORMENT]: TormentTag; + [BattlerTagType.TAUNT]: TauntTag; + [BattlerTagType.IMPRISON]: ImprisonTag; + [BattlerTagType.SYRUP_BOMB]: SyrupBombTag; + [BattlerTagType.TELEKINESIS]: TelekinesisTag; + [BattlerTagType.POWER_TRICK]: PowerTrickTag; + [BattlerTagType.GRUDGE]: GrudgeTag; + [BattlerTagType.PSYCHO_SHIFT]: PsychoShiftTag; + [BattlerTagType.MAGIC_COAT]: MagicCoatTag; +}; diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index 965ab23a692..e6673f31826 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -10800,7 +10800,7 @@ export function initMoves() { new SelfStatusMove(MoveId.NO_RETREAT, PokemonType.FIGHTING, -1, 5, -1, 0, 8) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 1, true) .attr(AddBattlerTagAttr, BattlerTagType.NO_RETREAT, true, false) - .condition((user, target, move) => user.getTag(TrappedTag)?.sourceMove !== MoveId.NO_RETREAT), // fails if the user is currently trapped by No Retreat + .condition((user, target, move) => user.getTag(TrappedTag)?.tagType !== BattlerTagType.NO_RETREAT), // fails if the user is currently trapped by No Retreat new StatusMove(MoveId.TAR_SHOT, PokemonType.ROCK, 100, 15, -1, 0, 8) .attr(StatStageChangeAttr, [ Stat.SPD ], -1) .attr(AddBattlerTagAttr, BattlerTagType.TAR_SHOT, false) diff --git a/src/data/pokemon/pokemon-data.ts b/src/data/pokemon/pokemon-data.ts index a2a0138a17a..972d7627bcd 100644 --- a/src/data/pokemon/pokemon-data.ts +++ b/src/data/pokemon/pokemon-data.ts @@ -1,4 +1,5 @@ -import { type BattlerTag, loadBattlerTag } from "#data/battler-tags"; +import type { BattlerTag } from "#data/battler-tags"; +import { loadBattlerTag, SerializableBattlerTag } from "#data/battler-tags"; import { allSpecies } from "#data/data-lists"; import type { Gender } from "#data/gender"; import { PokemonMove } from "#data/moves/pokemon-move"; @@ -187,9 +188,11 @@ export class PokemonSummonData { continue; } - if (key === "tags") { - // load battler tags - this.tags = value.map((t: BattlerTag) => loadBattlerTag(t)); + if (key === "tags" && Array.isArray(value)) { + // load battler tags, discarding any that are not serializable + this.tags = value + .map((t: SerializableBattlerTag) => loadBattlerTag(t)) + .filter((t): t is SerializableBattlerTag => t instanceof SerializableBattlerTag); continue; } this[key] = value; diff --git a/src/enums/battler-tag-type.ts b/src/enums/battler-tag-type.ts index 719b08c5b81..6d9d2dd4a92 100644 --- a/src/enums/battler-tag-type.ts +++ b/src/enums/battler-tag-type.ts @@ -1,5 +1,4 @@ export enum BattlerTagType { - NONE = "NONE", RECHARGING = "RECHARGING", FLINCHED = "FLINCHED", INTERRUPTED = "INTERRUPTED", From ede2a947cacb07700515dfb941230b781f57f659 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Tue, 29 Jul 2025 15:31:44 -0700 Subject: [PATCH 47/76] [Docs] Adjust `@module` doc comment in `battler-tags.ts` Note that currently Typedoc is not parsing `@module` docs, but this comment adjustment would be required if and when it gets fixed --- src/data/battler-tags.ts | 46 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 79c14f860b6..9dfd43eccb3 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -47,29 +47,29 @@ import type { import type { Mutable, NonFunctionProperties } from "#types/type-helpers"; import { BooleanHolder, coerceArray, getFrameMs, isNullOrUndefined, NumberHolder, toDmgValue } from "#utils/common"; -/* -@module -BattlerTags are used to represent semi-persistent effects that can be attached to a Pokemon. -Note that before serialization, a new tag object is created, and then `loadTag` is called on the -tag with the object that was serialized. - -This means it is straightforward to avoid serializing fields. -Fields that are not set in the constructor and not set in `loadTag` will thus not be serialized. - -Any battler tag that can persist across sessions must extend SerializableBattlerTag in its class definition signature. -Only tags that persist across waves (meaning their effect can last >1 turn) should be considered -serializable. - -Serializable battler tags have strict requirements for their fields. -Properties that are not necessary to reconstruct the tag must not be serialized. This can be avoided -by using a private property. If access to the property is needed outside of the class, then -a getter (and potentially, a setter) should be used instead. - -If a property that is intended to be private must be serialized, then it should instead -be declared as a public readonly propety. Then, in the `loadTag` method (or any method inside the class that needs to adjust the property) -use `(this as Mutable).propertyName = value;` -These rules ensure that Typescript is aware of the shape of the serialized version of the class. -*/ +/** + * @module + * BattlerTags are used to represent semi-persistent effects that can be attached to a Pokemon. + * Note that before serialization, a new tag object is created, and then `loadTag` is called on the + * tag with the object that was serialized. + * + * This means it is straightforward to avoid serializing fields. + * Fields that are not set in the constructor and not set in `loadTag` will thus not be serialized. + * + * Any battler tag that can persist across sessions must extend SerializableBattlerTag in its class definition signature. + * Only tags that persist across waves (meaning their effect can last >1 turn) should be considered + * serializable. + * + * Serializable battler tags have strict requirements for their fields. + * Properties that are not necessary to reconstruct the tag must not be serialized. This can be avoided + * by using a private property. If access to the property is needed outside of the class, then + * a getter (and potentially, a setter) should be used instead. + * + * If a property that is intended to be private must be serialized, then it should instead + * be declared as a public readonly propety. Then, in the `loadTag` method (or any method inside the class that needs to adjust the property) + * use `(this as Mutable).propertyName = value;` + * These rules ensure that Typescript is aware of the shape of the serialized version of the class. + */ /** Interface containing the serializable fields of BattlerTag */ interface BaseBattlerTag { From 10b9cfcdb0b30db35e452117b3ca25f6f26da2f2 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Tue, 29 Jul 2025 15:50:57 -0700 Subject: [PATCH 48/76] [Balance] End of turn triggers won't occur when you end a biome (#6169) * [Balance] End of turn triggers won't occur when you end a biome * Add tests * Move phase manipulation logic into `PhaseManager` * Rename "biome end" to "interlude" * Rename `TurnEndPhase#endOfBiome` to `upcomingInterlude` --------- Co-authored-by: Wlowscha <54003515+Wlowscha@users.noreply.github.com> --- src/phase-manager.ts | 13 +++++ src/phases/check-interlude-phase.ts | 18 +++++++ src/phases/turn-end-phase.ts | 8 ++- src/phases/turn-start-phase.ts | 9 ++-- test/phases/check-biome-end-phase.test.ts | 62 +++++++++++++++++++++++ 5 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 src/phases/check-interlude-phase.ts create mode 100644 test/phases/check-biome-end-phase.test.ts diff --git a/src/phase-manager.ts b/src/phase-manager.ts index 73ea373904f..c56afe446ed 100644 --- a/src/phase-manager.ts +++ b/src/phase-manager.ts @@ -9,6 +9,7 @@ import { AttemptCapturePhase } from "#phases/attempt-capture-phase"; import { AttemptRunPhase } from "#phases/attempt-run-phase"; import { BattleEndPhase } from "#phases/battle-end-phase"; import { BerryPhase } from "#phases/berry-phase"; +import { CheckInterludePhase } from "#phases/check-interlude-phase"; import { CheckStatusEffectPhase } from "#phases/check-status-effect-phase"; import { CheckSwitchPhase } from "#phases/check-switch-phase"; import { CommandPhase } from "#phases/command-phase"; @@ -121,6 +122,7 @@ const PHASES = Object.freeze({ AttemptRunPhase, BattleEndPhase, BerryPhase, + CheckInterludePhase, CheckStatusEffectPhase, CheckSwitchPhase, CommandPhase, @@ -665,4 +667,15 @@ export class PhaseManager { ): void { this.startDynamicPhase(this.create(phase, ...args)); } + + /** Prevents end of turn effects from triggering when transitioning to a new biome on a X0 wave */ + public onInterlude(): void { + const phasesToRemove = ["WeatherEffectPhase", "BerryPhase", "CheckStatusEffectPhase"]; + this.phaseQueue = this.phaseQueue.filter(p => !phasesToRemove.includes(p.phaseName)); + + const turnEndPhase = this.findPhase(p => p.phaseName === "TurnEndPhase"); + if (turnEndPhase) { + turnEndPhase.upcomingInterlude = true; + } + } } diff --git a/src/phases/check-interlude-phase.ts b/src/phases/check-interlude-phase.ts new file mode 100644 index 00000000000..1589f74f058 --- /dev/null +++ b/src/phases/check-interlude-phase.ts @@ -0,0 +1,18 @@ +import { globalScene } from "#app/global-scene"; +import { Phase } from "#app/phase"; + +export class CheckInterludePhase extends Phase { + public override readonly phaseName = "CheckInterludePhase"; + + public override start(): void { + super.start(); + const { phaseManager } = globalScene; + const { waveIndex } = globalScene.currentBattle; + + if (waveIndex % 10 === 0 && globalScene.getEnemyParty().every(p => p.isFainted())) { + phaseManager.onInterlude(); + } + + this.end(); + } +} diff --git a/src/phases/turn-end-phase.ts b/src/phases/turn-end-phase.ts index ce3b2958c23..463f26e73a2 100644 --- a/src/phases/turn-end-phase.ts +++ b/src/phases/turn-end-phase.ts @@ -18,6 +18,8 @@ import i18next from "i18next"; export class TurnEndPhase extends FieldPhase { public readonly phaseName = "TurnEndPhase"; + public upcomingInterlude = false; + start() { super.start(); @@ -59,9 +61,11 @@ export class TurnEndPhase extends FieldPhase { pokemon.tempSummonData.waveTurnCount++; }; - this.executeForAll(handlePokemon); + if (!this.upcomingInterlude) { + this.executeForAll(handlePokemon); - globalScene.arena.lapseTags(); + globalScene.arena.lapseTags(); + } if (globalScene.arena.weather && !globalScene.arena.weather.lapse()) { globalScene.arena.trySetWeather(WeatherType.NONE); diff --git a/src/phases/turn-start-phase.ts b/src/phases/turn-start-phase.ts index 0fc126801ec..9fdac65bb10 100644 --- a/src/phases/turn-start-phase.ts +++ b/src/phases/turn-start-phase.ts @@ -218,6 +218,7 @@ export class TurnStartPhase extends FieldPhase { break; } } + phaseManager.pushNew("CheckInterludePhase"); phaseManager.pushNew("WeatherEffectPhase"); phaseManager.pushNew("BerryPhase"); @@ -227,10 +228,10 @@ export class TurnStartPhase extends FieldPhase { phaseManager.pushNew("TurnEndPhase"); - /** - * this.end() will call shiftPhase(), which dumps everything from PrependQueue (aka everything that is unshifted()) to the front - * of the queue and dequeues to start the next phase - * this is important since stuff like SwitchSummon, AttemptRun, AttemptCapture Phases break the "flow" and should take precedence + /* + * `this.end()` will call `PhaseManager#shiftPhase()`, which dumps everything from `phaseQueuePrepend` + * (aka everything that is queued via `unshift()`) to the front of the queue and dequeues to start the next phase. + * This is important since stuff like `SwitchSummonPhase`, `AttemptRunPhase`, and `AttemptCapturePhase` break the "flow" and should take precedence */ this.end(); } diff --git a/test/phases/check-biome-end-phase.test.ts b/test/phases/check-biome-end-phase.test.ts new file mode 100644 index 00000000000..06957af9011 --- /dev/null +++ b/test/phases/check-biome-end-phase.test.ts @@ -0,0 +1,62 @@ +import { AbilityId } from "#enums/ability-id"; +import { BerryType } from "#enums/berry-type"; +import { MoveId } from "#enums/move-id"; +import { SpeciesId } from "#enums/species-id"; +import { WeatherType } from "#enums/weather-type"; +import { GameManager } from "#test/test-utils/game-manager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Check Biome End Phase", () => { + 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 + .enemySpecies(SpeciesId.MAGIKARP) + .enemyMoveset(MoveId.SPLASH) + .enemyAbility(AbilityId.BALL_FETCH) + .ability(AbilityId.BALL_FETCH) + .startingLevel(100); + }); + + it("should not trigger end of turn effects when defeating the final pokemon of a biome in classic", async () => { + game.override + .startingWave(10) + .weather(WeatherType.SANDSTORM) + .startingHeldItems([{ name: "BERRY", type: BerryType.SITRUS }]); + await game.classicMode.startBattle([SpeciesId.FEEBAS]); + + const player = game.field.getPlayerPokemon(); + + player.hp = 1; + + game.move.use(MoveId.EXTREME_SPEED); + await game.toEndOfTurn(); + + expect(player.hp).toBe(1); + }); + + it("should not prevent end of turn effects when transitioning waves within a biome", async () => { + game.override.weather(WeatherType.SANDSTORM); + await game.classicMode.startBattle([SpeciesId.FEEBAS]); + + const player = game.field.getPlayerPokemon(); + + game.move.use(MoveId.EXTREME_SPEED); + await game.toEndOfTurn(); + + expect(player.hp).toBeLessThan(player.getMaxHp()); + }); +}); From 6ae2bd70cfbe6d97cae4941d4d27fa61403c36a0 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Tue, 29 Jul 2025 20:02:30 -0700 Subject: [PATCH 49/76] [Test] Add missing single battle override to `CheckInterludePhase` test --- ...k-biome-end-phase.test.ts => check-interlude-phase.test.ts} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename test/phases/{check-biome-end-phase.test.ts => check-interlude-phase.test.ts} (97%) diff --git a/test/phases/check-biome-end-phase.test.ts b/test/phases/check-interlude-phase.test.ts similarity index 97% rename from test/phases/check-biome-end-phase.test.ts rename to test/phases/check-interlude-phase.test.ts index 06957af9011..d5413d1db35 100644 --- a/test/phases/check-biome-end-phase.test.ts +++ b/test/phases/check-interlude-phase.test.ts @@ -28,7 +28,8 @@ describe("Check Biome End Phase", () => { .enemyMoveset(MoveId.SPLASH) .enemyAbility(AbilityId.BALL_FETCH) .ability(AbilityId.BALL_FETCH) - .startingLevel(100); + .startingLevel(100) + .battleStyle("single"); }); it("should not trigger end of turn effects when defeating the final pokemon of a biome in classic", async () => { From 17eeceb4f348b87582986f77a6129874cb3ad53d Mon Sep 17 00:00:00 2001 From: fabske0 <192151969+fabske0@users.noreply.github.com> Date: Wed, 30 Jul 2025 19:58:10 +0200 Subject: [PATCH 50/76] [UI/UX] Fix button and input field overlaps (#6013) * [Fix] Fix button overlap * [Fix] Fix input field overlaps * use getWidth to determine if label should be shortened --------- Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Co-authored-by: damocleas --- src/ui/form-modal-ui-handler.ts | 20 ++++++++++++---- src/ui/modal-ui-handler.ts | 19 +++++++++++---- src/ui/pokedex-scan-ui-handler.ts | 7 ++++-- src/ui/registration-form-ui-handler.ts | 32 +++----------------------- 4 files changed, 38 insertions(+), 40 deletions(-) diff --git a/src/ui/form-modal-ui-handler.ts b/src/ui/form-modal-ui-handler.ts index 7ae545a7292..203d98a86c7 100644 --- a/src/ui/form-modal-ui-handler.ts +++ b/src/ui/form-modal-ui-handler.ts @@ -72,6 +72,10 @@ export abstract class FormModalUiHandler extends ModalUiHandler { (hasTitle ? 31 : 5) + 20 * (config.length - 1) + 16 + this.getButtonTopMargin(), "", TextStyle.TOOLTIP_CONTENT, + { + fontSize: "42px", + wordWrap: { width: 850 }, + }, ); this.errorMessage.setColor(this.getTextColor(TextStyle.SUMMARY_PINK)); this.errorMessage.setShadowColor(this.getTextColor(TextStyle.SUMMARY_PINK, true)); @@ -84,20 +88,28 @@ export abstract class FormModalUiHandler extends ModalUiHandler { this.inputs = []; this.formLabels = []; fieldsConfig.forEach((config, f) => { - const label = addTextObject(10, (hasTitle ? 31 : 5) + 20 * f, config.label, TextStyle.TOOLTIP_CONTENT); + // The Pokédex Scan Window uses width `300` instead of `160` like the other forms + // Therefore, the label does not need to be shortened + const label = addTextObject( + 10, + (hasTitle ? 31 : 5) + 20 * f, + config.label.length > 25 && this.getWidth() < 200 ? config.label.slice(0, 20) + "..." : config.label, + TextStyle.TOOLTIP_CONTENT, + ); label.name = "formLabel" + f; this.formLabels.push(label); this.modalContainer.add(this.formLabels[this.formLabels.length - 1]); - const inputContainer = globalScene.add.container(70, (hasTitle ? 28 : 2) + 20 * f); + const inputWidth = label.width < 320 ? 80 : 80 - (label.width - 320) / 5.5; + const inputContainer = globalScene.add.container(70 + (80 - inputWidth), (hasTitle ? 28 : 2) + 20 * f); inputContainer.setVisible(false); - const inputBg = addWindow(0, 0, 80, 16, false, false, 0, 0, WindowVariant.XTHIN); + const inputBg = addWindow(0, 0, inputWidth, 16, false, false, 0, 0, WindowVariant.XTHIN); const isPassword = config?.isPassword; const isReadOnly = config?.isReadOnly; - const input = addTextInputObject(4, -2, 440, 116, TextStyle.TOOLTIP_CONTENT, { + const input = addTextInputObject(4, -2, inputWidth * 5.5, 116, TextStyle.TOOLTIP_CONTENT, { type: isPassword ? "password" : "text", maxLength: isPassword ? 64 : 20, readOnly: isReadOnly, diff --git a/src/ui/modal-ui-handler.ts b/src/ui/modal-ui-handler.ts index c93b713831e..228d80968b9 100644 --- a/src/ui/modal-ui-handler.ts +++ b/src/ui/modal-ui-handler.ts @@ -152,7 +152,12 @@ export abstract class ModalUiHandler extends UiHandler { updateContainer(config?: ModalConfig): void { const [marginTop, marginRight, marginBottom, marginLeft] = this.getMargin(config); - const [width, height] = [this.getWidth(config), this.getHeight(config)]; + /** + * If the total amount of characters for the 2 buttons exceeds ~30 characters, + * the width in `registration-form-ui-handler.ts` and `login-form-ui-handler.ts` needs to be increased. + */ + const width = this.getWidth(config); + const height = this.getHeight(config); this.modalContainer.setPosition( (globalScene.game.canvas.width / 6 - (width + (marginRight - marginLeft))) / 2, (-globalScene.game.canvas.height / 6 - (height + (marginBottom - marginTop))) / 2, @@ -166,10 +171,14 @@ export abstract class ModalUiHandler extends UiHandler { this.titleText.setX(width / 2); this.titleText.setVisible(!!title); - for (let b = 0; b < this.buttonContainers.length; b++) { - const sliceWidth = width / (this.buttonContainers.length + 1); - - this.buttonContainers[b].setPosition(sliceWidth * (b + 1), this.modalBg.height - (this.buttonBgs[b].height + 8)); + if (this.buttonContainers.length > 0) { + const spacing = 12; + const totalWidth = this.buttonBgs.reduce((sum, bg) => sum + bg.width, 0) + spacing * (this.buttonBgs.length - 1); + let x = (this.modalBg.width - totalWidth) / 2; + this.buttonContainers.forEach((container, i) => { + container.setPosition(x + this.buttonBgs[i].width / 2, this.modalBg.height - (this.buttonBgs[i].height + 8)); + x += this.buttonBgs[i].width + spacing; + }); } } diff --git a/src/ui/pokedex-scan-ui-handler.ts b/src/ui/pokedex-scan-ui-handler.ts index bcf869f6f39..ab3258a03de 100644 --- a/src/ui/pokedex-scan-ui-handler.ts +++ b/src/ui/pokedex-scan-ui-handler.ts @@ -158,8 +158,11 @@ export class PokedexScanUiHandler extends FormModalUiHandler { if (super.show(args)) { const config = args[0] as ModalConfig; - this.inputs[0].resize(1150, 116); - this.inputContainers[0].list[0].width = 200; + const label = this.formLabels[0]; + + const inputWidth = label.width < 420 ? 200 : 200 - (label.width - 420) / 5.75; + this.inputs[0].resize(inputWidth * 5.75, 116); + this.inputContainers[0].list[0].width = inputWidth; if (args[1] && typeof (args[1] as PlayerPokemon).getNameToRender === "function") { this.inputs[0].text = (args[1] as PlayerPokemon).getNameToRender(); } else { diff --git a/src/ui/registration-form-ui-handler.ts b/src/ui/registration-form-ui-handler.ts index 60f8d1d987f..2c8080d534d 100644 --- a/src/ui/registration-form-ui-handler.ts +++ b/src/ui/registration-form-ui-handler.ts @@ -8,19 +8,6 @@ import type { ModalConfig } from "#ui/modal-ui-handler"; import { addTextObject } from "#ui/text"; import i18next from "i18next"; -interface LanguageSetting { - inputFieldFontSize?: string; - warningMessageFontSize?: string; - errorMessageFontSize?: string; -} - -const languageSettings: { [key: string]: LanguageSetting } = { - "es-ES": { - inputFieldFontSize: "50px", - errorMessageFontSize: "40px", - }, -}; - export class RegistrationFormUiHandler extends FormModalUiHandler { getModalTitle(_config?: ModalConfig): string { return i18next.t("menu:register"); @@ -35,7 +22,7 @@ export class RegistrationFormUiHandler extends FormModalUiHandler { } getButtonTopMargin(): number { - return 8; + return 12; } getButtonLabels(_config?: ModalConfig): string[] { @@ -76,18 +63,9 @@ export class RegistrationFormUiHandler extends FormModalUiHandler { setup(): void { super.setup(); - this.modalContainer.list.forEach((child: Phaser.GameObjects.GameObject) => { - if (child instanceof Phaser.GameObjects.Text && child !== this.titleText) { - const inputFieldFontSize = languageSettings[i18next.resolvedLanguage!]?.inputFieldFontSize; - if (inputFieldFontSize) { - child.setFontSize(inputFieldFontSize); - } - } - }); - - const warningMessageFontSize = languageSettings[i18next.resolvedLanguage!]?.warningMessageFontSize ?? "42px"; const label = addTextObject(10, 87, i18next.t("menu:registrationAgeWarning"), TextStyle.TOOLTIP_CONTENT, { - fontSize: warningMessageFontSize, + fontSize: "42px", + wordWrap: { width: 850 }, }); this.modalContainer.add(label); @@ -107,10 +85,6 @@ export class RegistrationFormUiHandler extends FormModalUiHandler { const onFail = error => { globalScene.ui.setMode(UiMode.REGISTRATION_FORM, Object.assign(config, { errorMessage: error?.trim() })); globalScene.ui.playError(); - const errorMessageFontSize = languageSettings[i18next.resolvedLanguage!]?.errorMessageFontSize; - if (errorMessageFontSize) { - this.errorMessage.setFontSize(errorMessageFontSize); - } }; if (!this.inputs[0].text) { return onFail(i18next.t("menu:emptyUsername")); From 1ae69a4183bca6deffbf0a2356a6b47477670d1b Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Wed, 30 Jul 2025 21:17:17 -0400 Subject: [PATCH 51/76] [Dev] Moved type helpers to separate directory; (#6123) * [Dev] Moved type helpers to separate directory; renamed `EnumValues` to `ObjectValues` and enforced usage * Update tsconfig.json Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Fixed import issue * Updated documentation slightly --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: Dean <69436131+emdeann@users.noreply.github.com> --- src/@types/arena-tags.ts | 2 +- src/@types/{ => helpers}/enum-types.ts | 10 ++--- src/@types/{ => helpers}/type-helpers.ts | 18 +++++--- src/@types/modifier-types.ts | 3 +- src/@types/phase-types.ts | 3 +- src/enums/ability-attr.ts | 4 +- src/enums/dex-attr.ts | 4 +- src/enums/gacha-types.ts | 4 +- src/enums/hit-check-result.ts | 4 +- src/utils/enums.ts | 6 +-- test/types/enum-types.test-d.ts | 53 +++++++++++++++--------- tsconfig.json | 2 +- 12 files changed, 70 insertions(+), 43 deletions(-) rename src/@types/{ => helpers}/enum-types.ts (68%) rename src/@types/{ => helpers}/type-helpers.ts (81%) diff --git a/src/@types/arena-tags.ts b/src/@types/arena-tags.ts index ab4339b2fef..9ccccb1df5c 100644 --- a/src/@types/arena-tags.ts +++ b/src/@types/arena-tags.ts @@ -1,6 +1,6 @@ import type { ArenaTagTypeMap } from "#data/arena-tag"; import type { ArenaTagType } from "#enums/arena-tag-type"; -import type { NonFunctionProperties } from "./type-helpers"; +import type { NonFunctionProperties } from "#types/type-helpers"; /** Subset of {@linkcode ArenaTagType}s that apply some negative effect to pokemon that switch in ({@link https://bulbapedia.bulbagarden.net/wiki/List_of_moves_that_cause_entry_hazards#List_of_traps | entry hazards} and Imprison. */ export type ArenaTrapTagType = diff --git a/src/@types/enum-types.ts b/src/@types/helpers/enum-types.ts similarity index 68% rename from src/@types/enum-types.ts rename to src/@types/helpers/enum-types.ts index 84df0a96505..2461f900c6b 100644 --- a/src/@types/enum-types.ts +++ b/src/@types/helpers/enum-types.ts @@ -1,18 +1,14 @@ +import type { ObjectValues } from "#types/type-helpers"; + /** Union type accepting any TS Enum or `const object`, with or without reverse mapping. */ export type EnumOrObject = Record; -/** - * Utility type to extract the enum values from a `const object`, - * or convert an `enum` interface produced by `typeof Enum` into the union type representing its values. - */ -export type EnumValues = E[keyof E]; - /** * Generic type constraint representing a TS numeric enum with reverse mappings. * @example * TSNumericEnum */ -export type TSNumericEnum = number extends EnumValues ? T : never; +export type TSNumericEnum = number extends ObjectValues ? T : never; /** Generic type constraint representing a non reverse-mapped TS enum or `const object`. */ export type NormalEnum = Exclude>; diff --git a/src/@types/type-helpers.ts b/src/@types/helpers/type-helpers.ts similarity index 81% rename from src/@types/type-helpers.ts rename to src/@types/helpers/type-helpers.ts index b3e5b1cfc07..37f97fcf08c 100644 --- a/src/@types/type-helpers.ts +++ b/src/@types/helpers/type-helpers.ts @@ -6,8 +6,6 @@ import type { AbAttr } from "#abilities/ability"; // biome-ignore-end lint/correctness/noUnusedImports: Used in a tsdoc comment -import type { EnumValues } from "#types/enum-types"; - /** * Exactly matches the type of the argument, preventing adding additional properties. * @@ -37,16 +35,25 @@ export type Mutable = { }; /** - * Type helper to obtain the keys associated with a given value inside a `const object`. + * Type helper to obtain the keys associated with a given value inside an object. * @typeParam O - The type of the object * @typeParam V - The type of one of O's values */ -export type InferKeys, V extends EnumValues> = { +export type InferKeys> = { [K in keyof O]: O[K] extends V ? K : never; }[keyof O]; /** - * Type helper that matches any `Function` type. Equivalent to `Function`, but will not raise a warning from Biome. + * Utility type to obtain the values of a given object. \ + * Functions similar to `keyof E`, except producing the values instead of the keys. + * @remarks + * This can be used to convert an `enum` interface produced by `typeof Enum` into the union type representing its members. + */ +export type ObjectValues = E[keyof E]; + +/** + * Type helper that matches any `Function` type. + * Equivalent to `Function`, but will not raise a warning from Biome. */ export type AnyFn = (...args: any[]) => any; @@ -65,6 +72,7 @@ export type NonFunctionProperties = { /** * Type helper to extract out non-function properties from a type, recursively applying to nested properties. + * This can be used to mimic the effects of JSON serialization and de-serialization on a given type. */ export type NonFunctionPropertiesRecursive = { [K in keyof Class as Class[K] extends AnyFn ? never : K]: Class[K] extends Array diff --git a/src/@types/modifier-types.ts b/src/@types/modifier-types.ts index 28b39d1a151..13a84a984e2 100644 --- a/src/@types/modifier-types.ts +++ b/src/@types/modifier-types.ts @@ -3,6 +3,7 @@ import type { Pokemon } from "#field/pokemon"; import type { ModifierConstructorMap } from "#modifiers/modifier"; import type { ModifierType, WeightedModifierType } from "#modifiers/modifier-type"; +import type { ObjectValues } from "#types/type-helpers"; export type ModifierTypeFunc = () => ModifierType; export type WeightedModifierTypeWeightFunc = (party: Pokemon[], rerollCount?: number) => number; @@ -19,7 +20,7 @@ export type ModifierInstanceMap = { /** * Union type of all modifier constructors. */ -export type ModifierClass = ModifierConstructorMap[keyof ModifierConstructorMap]; +export type ModifierClass = ObjectValues; /** * Union type of all modifier names as strings. diff --git a/src/@types/phase-types.ts b/src/@types/phase-types.ts index 1d68c7921dd..91673053747 100644 --- a/src/@types/phase-types.ts +++ b/src/@types/phase-types.ts @@ -1,4 +1,5 @@ import type { PhaseConstructorMap } from "#app/phase-manager"; +import type { ObjectValues } from "#types/type-helpers"; // Intentionally export the types of everything in phase-manager, as this file is meant to be // the centralized place for type definitions for the phase system. @@ -17,7 +18,7 @@ export type PhaseMap = { /** * Union type of all phase constructors. */ -export type PhaseClass = PhaseConstructorMap[keyof PhaseConstructorMap]; +export type PhaseClass = ObjectValues; /** * Union type of all phase names as strings. diff --git a/src/enums/ability-attr.ts b/src/enums/ability-attr.ts index 5f7d107f2d1..a3b9511ad02 100644 --- a/src/enums/ability-attr.ts +++ b/src/enums/ability-attr.ts @@ -1,3 +1,5 @@ +import type { ObjectValues } from "#types/type-helpers"; + /** * Not to be confused with an Ability Attribute. * This is an object literal storing the slot that an ability can occupy. @@ -8,4 +10,4 @@ export const AbilityAttr = Object.freeze({ ABILITY_HIDDEN: 4, }); -export type AbilityAttr = typeof AbilityAttr[keyof typeof AbilityAttr]; \ No newline at end of file +export type AbilityAttr = ObjectValues; \ No newline at end of file diff --git a/src/enums/dex-attr.ts b/src/enums/dex-attr.ts index ee5ceb43ef2..1a98167b4a1 100644 --- a/src/enums/dex-attr.ts +++ b/src/enums/dex-attr.ts @@ -1,3 +1,5 @@ +import type { ObjectValues } from "#types/type-helpers"; + export const DexAttr = Object.freeze({ NON_SHINY: 1n, SHINY: 2n, @@ -8,4 +10,4 @@ export const DexAttr = Object.freeze({ VARIANT_3: 64n, DEFAULT_FORM: 128n, }); -export type DexAttr = typeof DexAttr[keyof typeof DexAttr]; +export type DexAttr = ObjectValues; diff --git a/src/enums/gacha-types.ts b/src/enums/gacha-types.ts index cd0bc67eae0..08f147b27b1 100644 --- a/src/enums/gacha-types.ts +++ b/src/enums/gacha-types.ts @@ -1,7 +1,9 @@ +import type { ObjectValues } from "#types/type-helpers"; + export const GachaType = Object.freeze({ MOVE: 0, LEGENDARY: 1, SHINY: 2 }); -export type GachaType = typeof GachaType[keyof typeof GachaType]; +export type GachaType = ObjectValues; diff --git a/src/enums/hit-check-result.ts b/src/enums/hit-check-result.ts index cf8a2b17194..0866050341e 100644 --- a/src/enums/hit-check-result.ts +++ b/src/enums/hit-check-result.ts @@ -1,3 +1,5 @@ +import type { ObjectValues } from "#types/type-helpers"; + /** The result of a hit check calculation */ export const HitCheckResult = { /** Hit checks haven't been evaluated yet in this pass */ @@ -20,4 +22,4 @@ export const HitCheckResult = { ERROR: 8, } as const; -export type HitCheckResult = typeof HitCheckResult[keyof typeof HitCheckResult]; +export type HitCheckResult = ObjectValues; diff --git a/src/utils/enums.ts b/src/utils/enums.ts index 98cb4272ee9..25ee864794c 100644 --- a/src/utils/enums.ts +++ b/src/utils/enums.ts @@ -1,5 +1,5 @@ -import type { EnumOrObject, EnumValues, NormalEnum, TSNumericEnum } from "#app/@types/enum-types"; -import type { InferKeys } from "#app/@types/type-helpers"; +import type { EnumOrObject, NormalEnum, TSNumericEnum } from "#types/enum-types"; +import type { InferKeys, ObjectValues } from "#types/type-helpers"; /** * Return the string keys of an Enum object, excluding reverse-mapped numbers. @@ -61,7 +61,7 @@ export function getEnumValues(enumType: TSNumericEnum * If multiple keys map to the same value, the first one (in insertion order) will be retrieved, * but the return type will be the union of ALL their corresponding keys. */ -export function enumValueToKey>( +export function enumValueToKey>( object: NormalEnum, val: V, ): InferKeys { diff --git a/test/types/enum-types.test-d.ts b/test/types/enum-types.test-d.ts index 396c479e85a..3d03098c2ad 100644 --- a/test/types/enum-types.test-d.ts +++ b/test/types/enum-types.test-d.ts @@ -1,5 +1,6 @@ -import type { EnumOrObject, EnumValues, NormalEnum, TSNumericEnum } from "#app/@types/enum-types"; import type { enumValueToKey, getEnumKeys, getEnumValues } from "#app/utils/enums"; +import type { EnumOrObject, NormalEnum, TSNumericEnum } from "#types/enum-types"; +import type { ObjectValues } from "#types/type-helpers"; import { describe, expectTypeOf, it } from "vitest"; enum testEnumNum { @@ -16,21 +17,33 @@ const testObjNum = { testON1: 1, testON2: 2 } as const; const testObjString = { testOS1: "apple", testOS2: "banana" } as const; -describe("Enum Type Helpers", () => { - describe("EnumValues", () => { - it("should go from enum object type to value type", () => { - expectTypeOf>().toEqualTypeOf(); - expectTypeOf>().branded.toEqualTypeOf<1 | 2>(); +interface testObject { + key_1: "1"; + key_2: "2"; + key_3: "3"; +} - expectTypeOf>().toEqualTypeOf(); - expectTypeOf>().toEqualTypeOf(); - expectTypeOf>().toMatchTypeOf<"apple" | "banana">(); +describe("Enum Type Helpers", () => { + describe("ObjectValues", () => { + it("should produce a union of an object's values", () => { + expectTypeOf>().toEqualTypeOf<"1" | "2" | "3">(); + }); + + it("should go from enum object type to value type", () => { + expectTypeOf>().toEqualTypeOf(); + expectTypeOf>().branded.toEqualTypeOf<1 | 2>(); + + expectTypeOf>().toEqualTypeOf(); + expectTypeOf>().toEqualTypeOf< + testEnumString.testS1 | testEnumString.testS2 + >(); + + expectTypeOf>().toExtend<"apple" | "banana">(); }); it("should produce union of const object values as type", () => { - expectTypeOf>().toEqualTypeOf<1 | 2>(); - - expectTypeOf>().toEqualTypeOf<"apple" | "banana">(); + expectTypeOf>().toEqualTypeOf<1 | 2>(); + expectTypeOf>().toEqualTypeOf<"apple" | "banana">(); }); }); @@ -38,7 +51,6 @@ describe("Enum Type Helpers", () => { it("should match numeric enums", () => { expectTypeOf>().toEqualTypeOf(); }); - it("should not match string enums or const objects", () => { expectTypeOf>().toBeNever(); expectTypeOf>().toBeNever(); @@ -59,19 +71,19 @@ describe("Enum Type Helpers", () => { describe("EnumOrObject", () => { it("should match any enum or const object", () => { - expectTypeOf().toMatchTypeOf(); - expectTypeOf().toMatchTypeOf(); - expectTypeOf().toMatchTypeOf(); - expectTypeOf().toMatchTypeOf(); + expectTypeOf().toExtend(); + expectTypeOf().toExtend(); + expectTypeOf().toExtend(); + expectTypeOf().toExtend(); }); it("should not match an enum value union w/o typeof", () => { - expectTypeOf().not.toMatchTypeOf(); - expectTypeOf().not.toMatchTypeOf(); + expectTypeOf().not.toExtend(); + expectTypeOf().not.toExtend(); }); it("should be equivalent to `TSNumericEnum | NormalEnum`", () => { - expectTypeOf().branded.toEqualTypeOf | NormalEnum>(); + expectTypeOf().toEqualTypeOf | NormalEnum>(); }); }); }); @@ -80,6 +92,7 @@ describe("Enum Functions", () => { describe("getEnumKeys", () => { it("should retrieve keys of numeric enum", () => { expectTypeOf>().returns.toEqualTypeOf<("testN1" | "testN2")[]>(); + expectTypeOf>().returns.toEqualTypeOf<("testON1" | "testON2")[]>(); }); }); diff --git a/tsconfig.json b/tsconfig.json index 9aa06829789..dcbf7456df8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -49,7 +49,7 @@ "./system/*.ts" ], "#trainers/*": ["./data/trainers/*.ts"], - "#types/*": ["./@types/*.ts", "./typings/phaser/*.ts"], + "#types/*": ["./@types/helpers/*.ts", "./@types/*.ts", "./typings/phaser/*.ts"], "#ui/*": ["./ui/battle-info/*.ts", "./ui/settings/*.ts", "./ui/*.ts"], "#utils/*": ["./utils/*.ts"], "#data/*": ["./data/pokemon-forms/*.ts", "./data/pokemon/*.ts", "./data/*.ts"], From 9475505cd221d87cf3774bae4a1830d1201b4ffa Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Wed, 30 Jul 2025 20:59:14 -0600 Subject: [PATCH 52/76] [Misc] Improve type signatures of serialized arena/battler tags (#6180) * Improve type signatures of serialized arena/battler tags * Minor adjustments to tsdocs from code review Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> --------- Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> --- src/@types/arena-tags.ts | 9 ++-- src/@types/battler-tags.ts | 9 ++++ src/data/arena-tag.ts | 90 ++++++++++++++++++++++++-------------- src/data/battler-tags.ts | 45 +++++++++++++++---- 4 files changed, 105 insertions(+), 48 deletions(-) diff --git a/src/@types/arena-tags.ts b/src/@types/arena-tags.ts index 9ccccb1df5c..cfdce4350da 100644 --- a/src/@types/arena-tags.ts +++ b/src/@types/arena-tags.ts @@ -1,6 +1,5 @@ import type { ArenaTagTypeMap } from "#data/arena-tag"; import type { ArenaTagType } from "#enums/arena-tag-type"; -import type { NonFunctionProperties } from "#types/type-helpers"; /** Subset of {@linkcode ArenaTagType}s that apply some negative effect to pokemon that switch in ({@link https://bulbapedia.bulbagarden.net/wiki/List_of_moves_that_cause_entry_hazards#List_of_traps | entry hazards} and Imprison. */ export type ArenaTrapTagType = @@ -30,13 +29,13 @@ export type NonSerializableArenaTagType = ArenaTagType.NONE | TurnProtectArenaTa export type SerializableArenaTagType = Exclude; /** - * Type-safe representation of the serializable data of an ArenaTag + * Type-safe representation of an arbitrary, serialized Arena Tag */ -export type ArenaTagTypeData = NonFunctionProperties< +export type ArenaTagTypeData = Parameters< ArenaTagTypeMap[keyof { [K in keyof ArenaTagTypeMap as K extends SerializableArenaTagType ? K : never]: ArenaTagTypeMap[K]; - }] ->; + }]["loadTag"] +>[0]; /** Dummy, typescript-only declaration to ensure that * {@linkcode ArenaTagTypeMap} has a map for all ArenaTagTypes. diff --git a/src/@types/battler-tags.ts b/src/@types/battler-tags.ts index d1ff93e0400..0057280e4e5 100644 --- a/src/@types/battler-tags.ts +++ b/src/@types/battler-tags.ts @@ -108,6 +108,15 @@ export type SerializableBattlerTagType = keyof { */ export type NonSerializableBattlerTagType = Exclude; +/** + * Type-safe representation of an arbitrary, serialized Battler Tag + */ +export type BattlerTagTypeData = Parameters< + BattlerTagTypeMap[keyof { + [K in keyof BattlerTagTypeMap as K extends SerializableBattlerTagType ? K : never]: BattlerTagTypeMap[K]; + }]["loadTag"] +>[0]; + /** * Dummy, typescript-only declaration to ensure that * {@linkcode BattlerTagTypeMap} has an entry for all `BattlerTagType`s. diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index 2c4c8a04282..b24fd17e0e3 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -26,38 +26,58 @@ import type { ArenaTrapTagType, SerializableArenaTagType, } from "#types/arena-tags"; -import type { Mutable, NonFunctionProperties } from "#types/type-helpers"; +import type { Mutable } from "#types/type-helpers"; import { BooleanHolder, isNullOrUndefined, NumberHolder, toDmgValue } from "#utils/common"; import i18next from "i18next"; -/* -ArenaTags are are meant for effects that are tied to the arena (as opposed to a specific pokemon). -Examples include (but are not limited to) -- Cross-turn effects that persist even if the user/target switches out, such as Wish, Future Sight, and Happy Hour -- Effects that are applied to a specific side of the field, such as Crafty Shield, Reflect, and Spikes -- Field-Effects, like Gravity and Trick Room - -Any arena tag that persists across turns *must* extend from `SerializableArenaTag` in the class definition signature. - -Serializable ArenaTags have strict rules for their fields. -These rules ensure that only the data necessary to reconstruct the tag is serialized, and that the -session loader is able to deserialize saved tags correctly. - -If the data is static (i.e. it is always the same for all instances of the class, such as the -type that is weakened by Mud Sport/Water Sport), then it must not be defined as a field, and must -instead be defined as a getter. -A static property is also acceptable, though static properties are less ergonomic with inheritance. - -If the data is mutable (i.e. it can change over the course of the tag's lifetime), then it *must* -be defined as a field, and it must be set in the `loadTag` method. -Such fields cannot be marked as `private/protected`, as if they were, typescript would omit them from -types that are based off of the class, namely, `ArenaTagTypeData`. It is preferrable to trade the -type-safety of private/protected fields for the type safety when deserializing arena tags from save data. - -For data that is mutable only within a turn (e.g. SuppressAbilitiesTag's beingRemoved field), -where it does not make sense to be serialized, the field should use ES2020's private field syntax (a `#` prepended to the field name). -If the field should be accessible outside of the class, then a public getter should be used. -*/ +/** + * @module + * ArenaTags are are meant for effects that are tied to the arena (as opposed to a specific pokemon). + * Examples include (but are not limited to) + * - Cross-turn effects that persist even if the user/target switches out, such as Wish, Future Sight, and Happy Hour + * - Effects that are applied to a specific side of the field, such as Crafty Shield, Reflect, and Spikes + * - Field-Effects, like Gravity and Trick Room + * + * Any arena tag that persists across turns *must* extend from `SerializableArenaTag` in the class definition signature. + * + * Serializable ArenaTags have strict rules for their fields. + * These rules ensure that only the data necessary to reconstruct the tag is serialized, and that the + * session loader is able to deserialize saved tags correctly. + * + * If the data is static (i.e. it is always the same for all instances of the class, such as the + * type that is weakened by Mud Sport/Water Sport), then it must not be defined as a field, and must + * instead be defined as a getter. + * A static property is also acceptable, though static properties are less ergonomic with inheritance. + * + * If the data is mutable (i.e. it can change over the course of the tag's lifetime), then it *must* + * be defined as a field, and it must be set in the `loadTag` method. + * Such fields cannot be marked as `private`/`protected`; if they were, Typescript would omit them from + * types that are based off of the class, namely, `ArenaTagTypeData`. It is preferrable to trade the + * type-safety of private/protected fields for the type safety when deserializing arena tags from save data. + * + * For data that is mutable only within a turn (e.g. SuppressAbilitiesTag's beingRemoved field), + * where it does not make sense to be serialized, the field should use ES2020's + * [private field syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_elements#private_fields). + * If the field should be accessible outside of the class, then a public getter should be used. + * + * If any new serializable fields *are* added, then the class *must* override the + * `loadTag` method to set the new fields. Its signature *must* match the example below, + * ``` + * class ExampleTag extends SerializableArenaTag { + * // Example, if we add 2 new fields that should be serialized: + * public a: string; + * public b: number; + * // Then we must also define a loadTag method with one of the following signatures + * public override loadTag(source: BaseArenaTag & Pick(source: BaseArenaTag & Pick): void; + * public override loadTag(source: NonFunctionProperties): void; + * } + * ``` + * Notes + * - If the class has any subclasses, then the second form of `loadTag` *must* be used. + * - The third form *must not* be used if the class has any getters, as typescript would expect such fields to be + * present in `source`. + */ /** Interface containing the serializable fields of ArenaTagData. */ interface BaseArenaTag { @@ -141,9 +161,9 @@ export abstract class ArenaTag implements BaseArenaTag { /** * When given a arena tag or json representing one, load the data for it. * This is meant to be inherited from by any arena tag with custom attributes - * @param source - The {@linkcode BaseArenaTag} being loaded + * @param source - The arena tag being loaded */ - loadTag(source: BaseArenaTag): void { + loadTag(source: BaseArenaTag & Pick): void { this.turnCount = source.turnCount; this.sourceMove = source.sourceMove; this.sourceId = source.sourceId; @@ -646,7 +666,9 @@ class WishTag extends SerializableArenaTag { } } - override loadTag(source: NonFunctionProperties): void { + public override loadTag( + source: BaseArenaTag & Pick, + ): void { super.loadTag(source); (this as Mutable).battlerIndex = source.battlerIndex; (this as Mutable).healHp = source.healHp; @@ -813,7 +835,7 @@ export abstract class ArenaTrapTag extends SerializableArenaTag { : Phaser.Math.Linear(0, 1 / Math.pow(2, this.layers), Math.min(pokemon.getHpRatio(), 0.5) * 2); } - loadTag(source: NonFunctionProperties): void { + public loadTag(source: BaseArenaTag & Pick): void { super.loadTag(source); this.layers = source.layers; this.maxLayers = source.maxLayers; @@ -1581,7 +1603,7 @@ export class SuppressAbilitiesTag extends SerializableArenaTag { this.#beingRemoved = false; } - public override loadTag(source: NonFunctionProperties): void { + public override loadTag(source: BaseArenaTag & Pick): void { super.loadTag(source); (this as Mutable).sourceCount = source.sourceCount; } diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 9dfd43eccb3..e21065c184f 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -69,6 +69,24 @@ import { BooleanHolder, coerceArray, getFrameMs, isNullOrUndefined, NumberHolder * be declared as a public readonly propety. Then, in the `loadTag` method (or any method inside the class that needs to adjust the property) * use `(this as Mutable).propertyName = value;` * These rules ensure that Typescript is aware of the shape of the serialized version of the class. + * + * If any new serializable fields *are* added, then the class *must* override the + * `loadTag` method to set the new fields. Its signature *must* match the example below: + * ``` + * class ExampleTag extends SerializableBattlerTag { + * // Example, if we add 2 new fields that should be serialized: + * public a: string; + * public b: number; + * // Then we must also define a loadTag method with one of the following signatures + * public override loadTag(source: BaseBattlerTag & Pick(source: BaseBattlerTag & Pick): void; + * public override loadTag(source: NonFunctionProperties): void; + * } + * ``` + * Notes + * - If the class has any subclasses, then the second form of `loadTag` *must* be used. + * - The third form *must not* be used if the class has any getters, as typescript would expect such fields to be + * present in `source`. */ /** Interface containing the serializable fields of BattlerTag */ @@ -168,7 +186,7 @@ export class BattlerTag implements BaseBattlerTag { * Should be inherited from by any battler tag with custom attributes. * @param source - An object containing the fields needed to reconstruct this tag. */ - loadTag(source: BaseBattlerTag): void { + public loadTag(source: BaseBattlerTag & Pick): void { this.turnCount = source.turnCount; this.sourceMove = source.sourceMove; this.sourceId = source.sourceId; @@ -386,7 +404,7 @@ export class DisabledTag extends MoveRestrictionBattlerTag { }); } - override loadTag(source: NonFunctionProperties): void { + public override loadTag(source: BaseBattlerTag & Pick): void { super.loadTag(source); (this as Mutable).moveId = source.moveId; } @@ -437,7 +455,7 @@ export class GorillaTacticsTag extends MoveRestrictionBattlerTag { * Loads the Gorilla Tactics Battler Tag along with its unique class variable moveId * @param source - Object containing the fields needed to reconstruct this tag. */ - override loadTag(source: NonFunctionProperties): void { + public override loadTag(source: BaseBattlerTag & Pick): void { super.loadTag(source); (this as Mutable).moveId = source.moveId; } @@ -971,6 +989,12 @@ export class InfatuatedTag extends SerializableBattlerTag { } } +/** + * Battler tag for the "Seeded" effect applied by {@linkcode MoveId.LEECH_SEED | Leech Seed} and + * {@linkcode MoveId.SAPPY_SEED | Sappy Seed} + * + * @sealed + */ export class SeedTag extends SerializableBattlerTag { public override readonly tagType = BattlerTagType.SEEDED; public readonly sourceIndex: BattlerIndex; @@ -983,7 +1007,7 @@ export class SeedTag extends SerializableBattlerTag { * When given a battler tag or json representing one, load the data for it. * @param source - An object containing the fields needed to reconstruct this tag. */ - override loadTag(source: NonFunctionProperties): void { + public override loadTag(source: BaseBattlerTag & Pick): void { super.loadTag(source); (this as Mutable).sourceIndex = source.sourceIndex; } @@ -1194,6 +1218,7 @@ export class FrenzyTag extends SerializableBattlerTag { /** * Applies the effects of {@linkcode MoveId.ENCORE} onto the target Pokemon. * Encore forces the target Pokemon to use its most-recent move for 3 turns. + * @sealed */ export class EncoreTag extends MoveRestrictionBattlerTag { public override readonly tagType = BattlerTagType.ENCORE; @@ -1210,7 +1235,7 @@ export class EncoreTag extends MoveRestrictionBattlerTag { ); } - override loadTag(source: NonFunctionProperties): void { + public override loadTag(source: NonFunctionProperties): void { super.loadTag(source); this.moveId = source.moveId; } @@ -2085,7 +2110,7 @@ export class HighestStatBoostTag extends AbilityBattlerTag { * When given a battler tag or json representing one, load the data for it. * @param source - An object containing the fields needed to reconstruct this tag. */ - loadTag(source: NonFunctionProperties): void { + public override loadTag(source: BaseBattlerTag & Pick): void { super.loadTag(source); this.stat = source.stat as Stat; this.multiplier = source.multiplier; @@ -2564,6 +2589,7 @@ export class IceFaceBlockDamageTag extends FormBlockDamageTag { /** * Battler tag indicating a Tatsugiri with {@link https://bulbapedia.bulbagarden.net/wiki/Commander_(Ability) | Commander} * has entered the tagged Pokemon's mouth. + * @sealed */ export class CommandedTag extends SerializableBattlerTag { public override readonly tagType = BattlerTagType.COMMANDED; @@ -2607,6 +2633,7 @@ export class CommandedTag extends SerializableBattlerTag { * - Stat changes on removal of (all) stacks. * - Removing stacks decreases DEF and SPDEF, independently, by one stage for each stack that successfully changed * the stat when added. + * @sealed */ export class StockpilingTag extends SerializableBattlerTag { public override readonly tagType = BattlerTagType.STOCKPILING; @@ -2632,7 +2659,7 @@ export class StockpilingTag extends SerializableBattlerTag { } }; - override loadTag(source: NonFunctionProperties): void { + public override loadTag(source: NonFunctionProperties): void { super.loadTag(source); this.stockpiledCount = source.stockpiledCount || 0; this.statChangeCounts = { @@ -2979,7 +3006,7 @@ export class AutotomizedTag extends SerializableBattlerTag { this.onAdd(pokemon); } - loadTag(source: NonFunctionProperties): void { + public override loadTag(source: NonFunctionProperties): void { super.loadTag(source); this.autotomizeCount = source.autotomizeCount; } @@ -3129,7 +3156,7 @@ export class SubstituteTag extends SerializableBattlerTag { * When given a battler tag or json representing one, load the data for it. * @param source - An object containing the necessary properties to load the tag */ - override loadTag(source: NonFunctionProperties): void { + public override loadTag(source: BaseBattlerTag & Pick): void { super.loadTag(source); this.hp = source.hp; } From 12acaa959048e0604fe3529a3be2ba0f53bf8184 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Wed, 30 Jul 2025 23:55:52 -0400 Subject: [PATCH 53/76] [Balance] Updated SF/Triage interactions for moves (#6179) * Fixed move flags * Disabled order up interactionn with sheer force * Update src/data/moves/move.ts * Removed order up test that no longer applies shouldn't have been there in the first place --- src/data/moves/move.ts | 24 ++++++++++++------------ src/enums/move-flags.ts | 14 +++++++++----- test/moves/order-up.test.ts | 19 ------------------- 3 files changed, 21 insertions(+), 36 deletions(-) diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index e6673f31826..8557768bc03 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -423,9 +423,8 @@ export abstract class Move implements Localizable { /** * Sets the {@linkcode MoveFlags.MAKES_CONTACT} flag for the calling Move - * @param setFlag Default `true`, set to `false` if the move doesn't make contact - * @see {@linkcode AbilityId.STATIC} - * @returns The {@linkcode Move} that called this function + * @param setFlag - Whether the move should make contact; default `true` + * @returns `this` */ makesContact(setFlag: boolean = true): this { this.setFlag(MoveFlags.MAKES_CONTACT, setFlag); @@ -3576,8 +3575,7 @@ export class CutHpStatStageBoostAttr extends StatStageChangeAttr { /** * Attribute implementing the stat boosting effect of {@link https://bulbapedia.bulbagarden.net/wiki/Order_Up_(move) | Order Up}. * If the user has a Pokemon with {@link https://bulbapedia.bulbagarden.net/wiki/Commander_(Ability) | Commander} in their mouth, - * one of the user's stats are increased by 1 stage, depending on the "commanding" Pokemon's form. This effect does not respect - * effect chance, but Order Up itself may be boosted by Sheer Force. + * one of the user's stats are increased by 1 stage, depending on the "commanding" Pokemon's form. */ export class OrderUpStatBoostAttr extends MoveEffectAttr { constructor() { @@ -9228,7 +9226,7 @@ export function initMoves() { new SelfStatusMove(MoveId.STOCKPILE, PokemonType.NORMAL, -1, 20, -1, 0, 3) .condition(user => (user.getTag(StockpilingTag)?.stockpiledCount ?? 0) < 3) .attr(AddBattlerTagAttr, BattlerTagType.STOCKPILING, true), - new AttackMove(MoveId.SPIT_UP, PokemonType.NORMAL, MoveCategory.SPECIAL, -1, -1, 10, -1, 0, 3) + new AttackMove(MoveId.SPIT_UP, PokemonType.NORMAL, MoveCategory.SPECIAL, -1, 100, 10, -1, 0, 3) .condition(hasStockpileStacksCondition) .attr(SpitUpPowerAttr, 100) .attr(RemoveBattlerTagAttr, [ BattlerTagType.STOCKPILING ], true), @@ -9471,7 +9469,7 @@ export function initMoves() { new AttackMove(MoveId.SAND_TOMB, PokemonType.GROUND, MoveCategory.PHYSICAL, 35, 85, 15, -1, 0, 3) .attr(TrapAttr, BattlerTagType.SAND_TOMB) .makesContact(false), - new AttackMove(MoveId.SHEER_COLD, PokemonType.ICE, MoveCategory.SPECIAL, 200, 20, 5, -1, 0, 3) + new AttackMove(MoveId.SHEER_COLD, PokemonType.ICE, MoveCategory.SPECIAL, 200, 30, 5, -1, 0, 3) .attr(IceNoEffectTypeAttr) .attr(OneHitKOAttr) .attr(SheerColdAccuracyAttr), @@ -10393,7 +10391,7 @@ export function initMoves() { .attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.FLOATING, BattlerTagType.TELEKINESIS ]) .makesContact(false) .target(MoveTarget.ALL_NEAR_ENEMIES), - new AttackMove(MoveId.THOUSAND_WAVES, PokemonType.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6) + new AttackMove(MoveId.THOUSAND_WAVES, PokemonType.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, 100, 0, 6) .attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, false, 1, 1, true) .makesContact(false) .target(MoveTarget.ALL_NEAR_ENEMIES), @@ -10928,7 +10926,8 @@ export function initMoves() { new StatusMove(MoveId.LIFE_DEW, PokemonType.WATER, -1, 10, -1, 0, 8) .attr(HealAttr, 0.25, true, false) .target(MoveTarget.USER_AND_ALLIES) - .ignoresProtect(), + .ignoresProtect() + .triageMove(), new SelfStatusMove(MoveId.OBSTRUCT, PokemonType.DARK, 100, 10, -1, 4, 8) .attr(ProtectAttr, BattlerTagType.OBSTRUCT) .condition(failIfLastCondition), @@ -11006,7 +11005,8 @@ export function initMoves() { new StatusMove(MoveId.JUNGLE_HEALING, PokemonType.GRASS, -1, 10, -1, 0, 8) .attr(HealAttr, 0.25, true, false) .attr(HealStatusEffectAttr, false, getNonVolatileStatusEffects()) - .target(MoveTarget.USER_AND_ALLIES), + .target(MoveTarget.USER_AND_ALLIES) + .triageMove(), new AttackMove(MoveId.WICKED_BLOW, PokemonType.DARK, MoveCategory.PHYSICAL, 75, 100, 5, -1, 0, 8) .attr(CritOnlyAttr) .punchingMove(), @@ -11234,7 +11234,7 @@ export function initMoves() { .makesContact(false), new AttackMove(MoveId.LUMINA_CRASH, PokemonType.PSYCHIC, MoveCategory.SPECIAL, 80, 100, 10, 100, 0, 9) .attr(StatStageChangeAttr, [ Stat.SPDEF ], -2), - new AttackMove(MoveId.ORDER_UP, PokemonType.DRAGON, MoveCategory.PHYSICAL, 80, 100, 10, 100, 0, 9) + new AttackMove(MoveId.ORDER_UP, PokemonType.DRAGON, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 9) .attr(OrderUpStatBoostAttr) .makesContact(false), new AttackMove(MoveId.JET_PUNCH, PokemonType.WATER, MoveCategory.PHYSICAL, 60, 100, 15, -1, 1, 9) @@ -11417,7 +11417,7 @@ export function initMoves() { .attr(IvyCudgelTypeAttr) .attr(HighCritAttr) .makesContact(false), - new ChargingAttackMove(MoveId.ELECTRO_SHOT, PokemonType.ELECTRIC, MoveCategory.SPECIAL, 130, 100, 10, 100, 0, 9) + new ChargingAttackMove(MoveId.ELECTRO_SHOT, PokemonType.ELECTRIC, MoveCategory.SPECIAL, 130, 100, 10, -1, 0, 9) .chargeText(i18next.t("moveTriggers:absorbedElectricity", { pokemonName: "{USER}" })) .chargeAttr(StatStageChangeAttr, [ Stat.SPATK ], 1, true) .chargeAttr(WeatherInstantChargeAttr, [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ]), diff --git a/src/enums/move-flags.ts b/src/enums/move-flags.ts index 06de265df09..6cdc1e5f8cc 100644 --- a/src/enums/move-flags.ts +++ b/src/enums/move-flags.ts @@ -4,15 +4,19 @@ */ export enum MoveFlags { NONE = 0, + /** + * Whether the move makes contact. + * Set by default on all contact moves, and unset by default on all special moves. + */ MAKES_CONTACT = 1 << 0, IGNORE_PROTECT = 1 << 1, /** * Sound-based moves have the following effects: - * - Pokemon with the {@linkcode AbilityId.SOUNDPROOF Soundproof Ability} are unaffected by other Pokemon's sound-based moves. - * - Pokemon affected by {@linkcode MoveId.THROAT_CHOP Throat Chop} cannot use sound-based moves for two turns. - * - Sound-based moves used by a Pokemon with {@linkcode AbilityId.LIQUID_VOICE Liquid Voice} become Water-type moves. - * - Sound-based moves used by a Pokemon with {@linkcode AbilityId.PUNK_ROCK Punk Rock} are boosted by 30%. Pokemon with Punk Rock also take half damage from sound-based moves. - * - All sound-based moves (except Howl) can hit Pokemon behind an active {@linkcode MoveId.SUBSTITUTE Substitute}. + * - Pokemon with the {@linkcode AbilityId.SOUNDPROOF | Soundproof} Ability are unaffected by other Pokemon's sound-based moves. + * - Pokemon affected by {@linkcode MoveId.THROAT_CHOP | Throat Chop} cannot use sound-based moves for two turns. + * - Sound-based moves used by a Pokemon with {@linkcode AbilityId.LIQUID_VOICE | Liquid Voice} become Water-type moves. + * - Sound-based moves used by a Pokemon with {@linkcode AbilityId.PUNK_ROCK | Punk Rock} are boosted by 30%. Pokemon with Punk Rock also take half damage from sound-based moves. + * - All sound-based moves (except Howl) can hit Pokemon behind an active {@linkcode MoveId.SUBSTITUTE | Substitute}. * * cf https://bulbapedia.bulbagarden.net/wiki/Sound-based_move */ diff --git a/test/moves/order-up.test.ts b/test/moves/order-up.test.ts index 2e77d4b2fa7..2da7cc5daf8 100644 --- a/test/moves/order-up.test.ts +++ b/test/moves/order-up.test.ts @@ -65,23 +65,4 @@ describe("Moves - Order Up", () => { affectedStats.forEach(st => expect(dondozo.getStatStage(st)).toBe(st === stat ? 3 : 2)); }, ); - - it("should be boosted by Sheer Force while still applying a stat boost", async () => { - game.override.passiveAbility(AbilityId.SHEER_FORCE).starterForms({ [SpeciesId.TATSUGIRI]: 0 }); - - await game.classicMode.startBattle([SpeciesId.TATSUGIRI, SpeciesId.DONDOZO]); - - const [tatsugiri, dondozo] = game.scene.getPlayerField(); - - expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); - expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); - - game.move.select(MoveId.ORDER_UP, 1, BattlerIndex.ENEMY); - expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy(); - - await game.phaseInterceptor.to("BerryPhase", false); - - expect(dondozo.waveData.abilitiesApplied.has(AbilityId.SHEER_FORCE)).toBeTruthy(); - expect(dondozo.getStatStage(Stat.ATK)).toBe(3); - }); }); From f7b87f3d1e330f4fa20c85fc116f5021b4ce60ab Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Thu, 31 Jul 2025 00:43:06 -0400 Subject: [PATCH 54/76] [Move Bug] Fully implemented Future Sight, Doom Desire; fixed Wish Double battle oversight (#5862) * Mostly implemented Future Sight/Doom Desire * Fixed a few docs * Fixed com * Update magic_guard.test.ts * Update documentation * Update documentation on arena-tag.ts * Update arena-tag.ts docs * Update arena-tag.ts * Update turn-end-phase.ts * Update move.ts documentation * Fixed tpyo * Update move.ts documentation * Add assorted TODO test cases * Refactored FS to use a positional tag manager * Added strong typing to the manager, finished save load stufff * Fixed locales + tests * Fixed tests and documentation * sh Fixed tests for good * Fixed MEP * Reverted overrides changse * Fixed issues with merging * Fixed locales update & heal block test * Fixed wish tests * Fixed test typo * Fixed wish test flaking out due to speed ties * Fixed tests fr fr * actually fixed tests bc i'm stupid * Fixed tests for real * Remove locales update * Update arena-tag.ts Co-authored-by: Dean <69436131+emdeann@users.noreply.github.com> * Update move.ts Co-authored-by: Dean <69436131+emdeann@users.noreply.github.com> * Update arena-tag.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Applied review suggestions and added a _wee_ bit more docs * fixed wish condition * Applied kev's reviews * Minor nits * Minor formatting change in `heal-block.test.ts` --------- Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Co-authored-by: Dean <69436131+emdeann@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/@types/arena-tags.ts | 3 - src/data/arena-tag.ts | 128 +----- src/data/moves/move.ts | 134 ++++-- .../positional-tags/load-positional-tag.ts | 70 ++++ .../positional-tags/positional-tag-manager.ts | 55 +++ src/data/positional-tags/positional-tag.ts | 174 ++++++++ src/enums/arena-tag-type.ts | 3 - src/enums/move-use-mode.ts | 79 ++-- src/enums/positional-tag-type.ts | 10 + src/field/arena.ts | 51 ++- src/phase-manager.ts | 2 + src/phases/move-effect-phase.ts | 33 +- src/phases/move-phase.ts | 17 - src/phases/positional-tag-phase.ts | 21 + src/phases/turn-start-phase.ts | 4 + src/system/arena-data.ts | 7 + src/system/game-data.ts | 5 + test/moves/delayed-attack.test.ts | 389 ++++++++++++++++++ test/moves/future-sight.test.ts | 45 -- test/moves/heal-block.test.ts | 26 +- test/moves/wish.test.ts | 183 ++++++++ test/test-utils/helpers/field-helper.ts | 12 +- test/test-utils/helpers/move-helper.ts | 12 +- test/test-utils/phase-interceptor.ts | 2 + test/types/positional-tags.test-d.ts | 29 ++ 25 files changed, 1175 insertions(+), 319 deletions(-) create mode 100644 src/data/positional-tags/load-positional-tag.ts create mode 100644 src/data/positional-tags/positional-tag-manager.ts create mode 100644 src/data/positional-tags/positional-tag.ts create mode 100644 src/enums/positional-tag-type.ts create mode 100644 src/phases/positional-tag-phase.ts create mode 100644 test/moves/delayed-attack.test.ts delete mode 100644 test/moves/future-sight.test.ts create mode 100644 test/moves/wish.test.ts create mode 100644 test/types/positional-tags.test-d.ts diff --git a/src/@types/arena-tags.ts b/src/@types/arena-tags.ts index cfdce4350da..afcc8a0f924 100644 --- a/src/@types/arena-tags.ts +++ b/src/@types/arena-tags.ts @@ -9,9 +9,6 @@ export type ArenaTrapTagType = | ArenaTagType.STEALTH_ROCK | ArenaTagType.IMPRISON; -/** Subset of {@linkcode ArenaTagType}s that are considered delayed attacks */ -export type ArenaDelayedAttackTagType = ArenaTagType.FUTURE_SIGHT | ArenaTagType.DOOM_DESIRE; - /** Subset of {@linkcode ArenaTagType}s that create {@link https://bulbapedia.bulbagarden.net/wiki/Category:Screen-creating_moves | screens}. */ export type ArenaScreenTagType = ArenaTagType.REFLECT | ArenaTagType.LIGHT_SCREEN | ArenaTagType.AURORA_VEIL; diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index b24fd17e0e3..9f2a5e09667 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -1,3 +1,7 @@ +/** biome-ignore-start lint/correctness/noUnusedImports: TSDoc imports */ +import type { BattlerTag } from "#app/data/battler-tags"; +/** biome-ignore-end lint/correctness/noUnusedImports: TSDoc imports */ + import { applyAbAttrs, applyOnGainAbAttrs, applyOnLoseAbAttrs } from "#abilities/apply-ab-attrs"; import { globalScene } from "#app/global-scene"; import { getPokemonNameWithAffix } from "#app/messages"; @@ -6,35 +10,32 @@ import { allMoves } from "#data/data-lists"; import { AbilityId } from "#enums/ability-id"; import { ArenaTagSide } from "#enums/arena-tag-side"; import { ArenaTagType } from "#enums/arena-tag-type"; -import type { BattlerIndex } from "#enums/battler-index"; import { BattlerTagType } from "#enums/battler-tag-type"; import { HitResult } from "#enums/hit-result"; import { CommonAnim } from "#enums/move-anims-common"; import { MoveCategory } from "#enums/move-category"; import { MoveId } from "#enums/move-id"; import { MoveTarget } from "#enums/move-target"; -import { MoveUseMode } from "#enums/move-use-mode"; import { PokemonType } from "#enums/pokemon-type"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; import type { Arena } from "#field/arena"; import type { Pokemon } from "#field/pokemon"; import type { - ArenaDelayedAttackTagType, ArenaScreenTagType, ArenaTagTypeData, ArenaTrapTagType, SerializableArenaTagType, } from "#types/arena-tags"; import type { Mutable } from "#types/type-helpers"; -import { BooleanHolder, isNullOrUndefined, NumberHolder, toDmgValue } from "#utils/common"; +import { BooleanHolder, NumberHolder, toDmgValue } from "#utils/common"; import i18next from "i18next"; /** * @module * ArenaTags are are meant for effects that are tied to the arena (as opposed to a specific pokemon). * Examples include (but are not limited to) - * - Cross-turn effects that persist even if the user/target switches out, such as Wish, Future Sight, and Happy Hour + * - Cross-turn effects that persist even if the user/target switches out, such as Happy Hour * - Effects that are applied to a specific side of the field, such as Crafty Shield, Reflect, and Spikes * - Field-Effects, like Gravity and Trick Room * @@ -624,58 +625,6 @@ export class NoCritTag extends SerializableArenaTag { } } -/** - * Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Wish_(move) | Wish}. - * Heals the Pokémon in the user's position the turn after Wish is used. - */ -class WishTag extends SerializableArenaTag { - // The following fields are meant to be inwardly mutable, but outwardly immutable. - readonly battlerIndex: BattlerIndex; - readonly healHp: number; - readonly sourceName: string; - // End inwardly mutable fields - - public readonly tagType = ArenaTagType.WISH; - - constructor(turnCount: number, sourceId: number | undefined, side: ArenaTagSide) { - super(turnCount, MoveId.WISH, sourceId, side); - } - - onAdd(_arena: Arena): void { - const source = this.getSourcePokemon(); - if (!source) { - console.warn(`Failed to get source Pokemon for WishTag on add message; id: ${this.sourceId}`); - return; - } - - (this as Mutable).sourceName = getPokemonNameWithAffix(source); - (this as Mutable).healHp = toDmgValue(source.getMaxHp() / 2); - (this as Mutable).battlerIndex = source.getBattlerIndex(); - } - - onRemove(_arena: Arena): void { - const target = globalScene.getField()[this.battlerIndex]; - if (target?.isActive(true)) { - globalScene.phaseManager.queueMessage( - // TODO: Rename key as it triggers on activation - i18next.t("arenaTag:wishTagOnAdd", { - pokemonNameWithAffix: this.sourceName, - }), - ); - globalScene.phaseManager.unshiftNew("PokemonHealPhase", target.getBattlerIndex(), this.healHp, null, true, false); - } - } - - public override loadTag( - source: BaseArenaTag & Pick, - ): void { - super.loadTag(source); - (this as Mutable).battlerIndex = source.battlerIndex; - (this as Mutable).healHp = source.healHp; - (this as Mutable).sourceName = source.sourceName; - } -} - /** * Abstract class to implement weakened moves of a specific type. */ @@ -1148,48 +1097,6 @@ class StickyWebTag extends ArenaTrapTag { } } -/** - * Arena Tag class for delayed attacks, such as {@linkcode MoveId.FUTURE_SIGHT} or {@linkcode MoveId.DOOM_DESIRE}. - * Delays the attack's effect by a set amount of turns, usually 3 (including the turn the move is used), - * and deals damage after the turn count is reached. - */ -export class DelayedAttackTag extends SerializableArenaTag { - public targetIndex: BattlerIndex; - public readonly tagType: ArenaDelayedAttackTagType; - - constructor( - tagType: ArenaTagType.DOOM_DESIRE | ArenaTagType.FUTURE_SIGHT, - sourceMove: MoveId | undefined, - sourceId: number | undefined, - targetIndex: BattlerIndex, - side: ArenaTagSide = ArenaTagSide.BOTH, - ) { - super(3, sourceMove, sourceId, side); - this.tagType = tagType; - this.targetIndex = targetIndex; - this.side = side; - } - - lapse(arena: Arena): boolean { - const ret = super.lapse(arena); - - if (!ret) { - // TODO: This should not add to move history (for Spite) - globalScene.phaseManager.unshiftNew( - "MoveEffectPhase", - this.sourceId!, - [this.targetIndex], - allMoves[this.sourceMove!], - MoveUseMode.FOLLOW_UP, - ); // TODO: are those bangs correct? - } - - return ret; - } - - onRemove(_arena: Arena): void {} -} - /** * Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Trick_Room_(move) Trick Room}. * Reverses the Speed stats for all Pokémon on the field as long as this arena tag is up, @@ -1685,7 +1592,6 @@ export function getArenaTag( turnCount: number, sourceMove: MoveId | undefined, sourceId: number | undefined, - targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH, ): ArenaTag | null { switch (tagType) { @@ -1711,14 +1617,6 @@ export function getArenaTag( return new SpikesTag(sourceId, side); case ArenaTagType.TOXIC_SPIKES: return new ToxicSpikesTag(sourceId, side); - case ArenaTagType.FUTURE_SIGHT: - case ArenaTagType.DOOM_DESIRE: - if (isNullOrUndefined(targetIndex)) { - return null; // If missing target index, no tag is created - } - return new DelayedAttackTag(tagType, sourceMove, sourceId, targetIndex, side); - case ArenaTagType.WISH: - return new WishTag(turnCount, sourceId, side); case ArenaTagType.STEALTH_ROCK: return new StealthRockTag(sourceId, side); case ArenaTagType.STICKY_WEB: @@ -1761,16 +1659,9 @@ export function getArenaTag( * @param source - An arena tag * @returns The valid arena tag */ -export function loadArenaTag(source: (ArenaTag | ArenaTagTypeData) & { targetIndex?: BattlerIndex }): ArenaTag { +export function loadArenaTag(source: ArenaTag | ArenaTagTypeData): ArenaTag { const tag = - getArenaTag( - source.tagType, - source.turnCount, - source.sourceMove, - source.sourceId, - source.targetIndex, - source.side, - ) ?? new NoneTag(); + getArenaTag(source.tagType, source.turnCount, source.sourceMove, source.sourceId, source.side) ?? new NoneTag(); tag.loadTag(source); return tag; } @@ -1787,9 +1678,6 @@ export type ArenaTagTypeMap = { [ArenaTagType.CRAFTY_SHIELD]: CraftyShieldTag; [ArenaTagType.NO_CRIT]: NoCritTag; [ArenaTagType.TOXIC_SPIKES]: ToxicSpikesTag; - [ArenaTagType.FUTURE_SIGHT]: DelayedAttackTag; - [ArenaTagType.DOOM_DESIRE]: DelayedAttackTag; - [ArenaTagType.WISH]: WishTag; [ArenaTagType.STEALTH_ROCK]: StealthRockTag; [ArenaTagType.STICKY_WEB]: StickyWebTag; [ArenaTagType.TRICK_ROOM]: TrickRoomTag; diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index 8557768bc03..bde5f2977d8 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -25,6 +25,7 @@ import { getBerryEffectFunc } from "#data/berry"; import { applyChallenges } from "#data/challenge"; import { allAbilities, allMoves } from "#data/data-lists"; import { SpeciesFormChangeRevertWeatherFormTrigger } from "#data/form-change-triggers"; +import { DelayedAttackTag } from "#data/positional-tags/positional-tag"; import { getNonVolatileStatusEffects, getStatusEffectHealText, @@ -54,6 +55,7 @@ import { MoveFlags } from "#enums/move-flags"; import { MoveTarget } from "#enums/move-target"; import { MultiHitType } from "#enums/multi-hit-type"; import { PokemonType } from "#enums/pokemon-type"; +import { PositionalTagType } from "#enums/positional-tag-type"; import { SpeciesId } from "#enums/species-id"; import { BATTLE_STATS, @@ -3122,54 +3124,110 @@ export class OverrideMoveEffectAttr extends MoveAttr { * Its sole purpose is to ensure that typescript is able to properly narrow when the `is` method is called. */ declare private _: never; - override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + /** + * Apply the move attribute to override other effects of this move. + * @param user - The {@linkcode Pokemon} using the move + * @param target - The {@linkcode Pokemon} targeted by the move + * @param move - The {@linkcode Move} being used + * @param args - + * `[0]`: A {@linkcode BooleanHolder} containing whether move effects were successfully overridden; should be set to `true` on success \ + * `[1]`: The {@linkcode MoveUseMode} dictating how this move was used. + * @returns `true` if the move effect was successfully overridden. + */ + public override apply(_user: Pokemon, _target: Pokemon, _move: Move, _args: [overridden: BooleanHolder, useMode: MoveUseMode]): boolean { return true; } } +/** Abstract class for moves that add {@linkcode PositionalTag}s to the field. */ +abstract class AddPositionalTagAttr extends OverrideMoveEffectAttr { + protected abstract readonly tagType: PositionalTagType; + + public override getCondition(): MoveConditionFunc { + // Check the arena if another similar positional tag is active and affecting the same slot + return (_user, target, move) => globalScene.arena.positionalTagManager.canAddTag(this.tagType, target.getBattlerIndex()) + } +} + /** - * Attack Move that doesn't hit the turn it is played and doesn't allow for multiple - * uses on the same target. Examples are Future Sight or Doom Desire. - * @extends OverrideMoveEffectAttr - * @param tagType The {@linkcode ArenaTagType} that will be placed on the field when the move is used - * @param chargeAnim The {@linkcode ChargeAnim | Charging Animation} used for the move - * @param chargeText The text to display when the move is used + * Attribute to implement delayed attacks, such as {@linkcode MoveId.FUTURE_SIGHT} or {@linkcode MoveId.DOOM_DESIRE}. + * Delays the attack's effect with a {@linkcode DelayedAttackTag}, + * activating against the given slot after the given turn count has elapsed. */ export class DelayedAttackAttr extends OverrideMoveEffectAttr { - public tagType: ArenaTagType; public chargeAnim: ChargeAnim; private chargeText: string; - constructor(tagType: ArenaTagType, chargeAnim: ChargeAnim, chargeText: string) { + /** + * @param chargeAnim - The {@linkcode ChargeAnim | charging animation} used for the move's charging phase. + * @param chargeKey - The `i18next` locales **key** to show when the delayed attack is used. + * In the displayed text, `{{pokemonName}}` will be populated with the user's name. + */ + constructor(chargeAnim: ChargeAnim, chargeKey: string) { super(); - this.tagType = tagType; this.chargeAnim = chargeAnim; - this.chargeText = chargeText; + this.chargeText = chargeKey; } - apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - // Edge case for the move applied on a pokemon that has fainted - if (!target) { - return true; + public override apply(user: Pokemon, target: Pokemon, move: Move, args: [overridden: BooleanHolder, useMode: MoveUseMode]): boolean { + const useMode = args[1]; + if (useMode === MoveUseMode.DELAYED_ATTACK) { + // don't trigger if already queueing an indirect attack + return false; } - const overridden = args[0] as BooleanHolder; - const virtual = args[1] as boolean; + const overridden = args[0]; + overridden.value = true; - if (!virtual) { - overridden.value = true; - globalScene.phaseManager.unshiftNew("MoveAnimPhase", new MoveChargeAnim(this.chargeAnim, move.id, user)); - globalScene.phaseManager.queueMessage(this.chargeText.replace("{TARGET}", getPokemonNameWithAffix(target)).replace("{USER}", getPokemonNameWithAffix(user))); - user.pushMoveHistory({ move: move.id, targets: [ target.getBattlerIndex() ], result: MoveResult.OTHER, useMode: MoveUseMode.NORMAL }); - const side = target.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; - globalScene.arena.addTag(this.tagType, 3, move.id, user.id, side, false, target.getBattlerIndex()); - } else { - globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:tookMoveAttack", { pokemonName: getPokemonNameWithAffix(globalScene.getPokemonById(target.id) ?? undefined), moveName: move.name })); - } + // Display the move animation to foresee an attack + globalScene.phaseManager.unshiftNew("MoveAnimPhase", new MoveChargeAnim(this.chargeAnim, move.id, user)); + globalScene.phaseManager.queueMessage( + i18next.t( + this.chargeText, + { pokemonName: getPokemonNameWithAffix(user) } + ) + ) + user.pushMoveHistory({move: move.id, targets: [target.getBattlerIndex()], result: MoveResult.OTHER, useMode, turn: globalScene.currentBattle.turn}) + user.pushMoveHistory({move: move.id, targets: [target.getBattlerIndex()], result: MoveResult.OTHER, useMode, turn: globalScene.currentBattle.turn}) + // Queue up an attack on the given slot. + globalScene.arena.positionalTagManager.addTag({ + tagType: PositionalTagType.DELAYED_ATTACK, + sourceId: user.id, + targetIndex: target.getBattlerIndex(), + sourceMove: move.id, + turnCount: 3 + }) return true; } + + public override getCondition(): MoveConditionFunc { + // Check the arena if another similar attack is active and affecting the same slot + return (_user, target) => globalScene.arena.positionalTagManager.canAddTag(PositionalTagType.DELAYED_ATTACK, target.getBattlerIndex()) + } +} + +/** + * Attribute to queue a {@linkcode WishTag} to activate in 2 turns. + * The tag whill heal + */ +export class WishAttr extends MoveEffectAttr { + public override apply(user: Pokemon, target: Pokemon, _move: Move): boolean { + globalScene.arena.positionalTagManager.addTag({ + tagType: PositionalTagType.WISH, + healHp: toDmgValue(user.getMaxHp() / 2), + targetIndex: target.getBattlerIndex(), + turnCount: 2, + pokemonName: getPokemonNameWithAffix(user), + }); + return true; + } + + public override getCondition(): MoveConditionFunc { + // Check the arena if another wish is active and affecting the same slot + return (_user, target) => globalScene.arena.positionalTagManager.canAddTag(PositionalTagType.WISH, target.getBattlerIndex()) + } } /** @@ -3187,8 +3245,8 @@ export class AwaitCombinedPledgeAttr extends OverrideMoveEffectAttr { * @param user the {@linkcode Pokemon} using this move * @param target n/a * @param move the {@linkcode Move} being used - * @param args - * - [0] a {@linkcode BooleanHolder} indicating whether the move's base + * @param args - + * `[0]`: A {@linkcode BooleanHolder} indicating whether the move's base * effects should be overridden this turn. * @returns `true` if base move effects were overridden; `false` otherwise */ @@ -9203,9 +9261,12 @@ export function initMoves() { .attr(StatStageChangeAttr, [ Stat.SPDEF ], -1) .ballBombMove(), new AttackMove(MoveId.FUTURE_SIGHT, PokemonType.PSYCHIC, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 2) - .partial() // cannot be used on multiple Pokemon on the same side in a double battle, hits immediately when called by Metronome/etc, should not apply abilities or held items if user is off the field + .attr(DelayedAttackAttr, ChargeAnim.FUTURE_SIGHT_CHARGING, "moveTriggers:foresawAnAttack") .ignoresProtect() - .attr(DelayedAttackAttr, ArenaTagType.FUTURE_SIGHT, ChargeAnim.FUTURE_SIGHT_CHARGING, i18next.t("moveTriggers:foresawAnAttack", { pokemonName: "{USER}" })), + /* + * Should not apply abilities or held items if user is off the field + */ + .edgeCase(), new AttackMove(MoveId.ROCK_SMASH, PokemonType.FIGHTING, MoveCategory.PHYSICAL, 40, 100, 15, 50, 0, 2) .attr(StatStageChangeAttr, [ Stat.DEF ], -1), new AttackMove(MoveId.WHIRLPOOL, PokemonType.WATER, MoveCategory.SPECIAL, 35, 85, 15, -1, 0, 2) @@ -9291,8 +9352,8 @@ export function initMoves() { .ignoresSubstitute() .attr(AbilityCopyAttr), new SelfStatusMove(MoveId.WISH, PokemonType.NORMAL, -1, 10, -1, 0, 3) - .triageMove() - .attr(AddArenaTagAttr, ArenaTagType.WISH, 2, true), + .attr(WishAttr) + .triageMove(), new SelfStatusMove(MoveId.ASSIST, PokemonType.NORMAL, -1, 20, -1, 0, 3) .attr(RandomMovesetMoveAttr, invalidAssistMoves, true), new SelfStatusMove(MoveId.INGRAIN, PokemonType.GRASS, -1, 20, -1, 0, 3) @@ -9541,9 +9602,12 @@ export function initMoves() { .attr(ConfuseAttr) .pulseMove(), new AttackMove(MoveId.DOOM_DESIRE, PokemonType.STEEL, MoveCategory.SPECIAL, 140, 100, 5, -1, 0, 3) - .partial() // cannot be used on multiple Pokemon on the same side in a double battle, hits immediately when called by Metronome/etc, should not apply abilities or held items if user is off the field + .attr(DelayedAttackAttr, ChargeAnim.DOOM_DESIRE_CHARGING, "moveTriggers:choseDoomDesireAsDestiny") .ignoresProtect() - .attr(DelayedAttackAttr, ArenaTagType.DOOM_DESIRE, ChargeAnim.DOOM_DESIRE_CHARGING, i18next.t("moveTriggers:choseDoomDesireAsDestiny", { pokemonName: "{USER}" })), + /* + * Should not apply abilities or held items if user is off the field + */ + .edgeCase(), new AttackMove(MoveId.PSYCHO_BOOST, PokemonType.PSYCHIC, MoveCategory.SPECIAL, 140, 90, 5, -1, 0, 3) .attr(StatStageChangeAttr, [ Stat.SPATK ], -2, true), new SelfStatusMove(MoveId.ROOST, PokemonType.FLYING, -1, 5, -1, 0, 4) diff --git a/src/data/positional-tags/load-positional-tag.ts b/src/data/positional-tags/load-positional-tag.ts new file mode 100644 index 00000000000..ef3609d93e7 --- /dev/null +++ b/src/data/positional-tags/load-positional-tag.ts @@ -0,0 +1,70 @@ +import { DelayedAttackTag, type PositionalTag, WishTag } from "#data/positional-tags/positional-tag"; +import { PositionalTagType } from "#enums/positional-tag-type"; +import type { ObjectValues } from "#types/type-helpers"; +import type { Constructor } from "#utils/common"; + +/** + * Load the attributes of a {@linkcode PositionalTag}. + * @param tagType - The {@linkcode PositionalTagType} to create + * @param args - The arguments needed to instantize the given tag + * @returns The newly created tag. + * @remarks + * This function does not perform any checking if the added tag is valid. + */ +export function loadPositionalTag({ + tagType, + ...args +}: serializedPosTagMap[T]): posTagInstanceMap[T]; +/** + * Load the attributes of a {@linkcode PositionalTag}. + * @param tag - The {@linkcode SerializedPositionalTag} to instantiate + * @returns The newly created tag. + * @remarks + * This function does not perform any checking if the added tag is valid. + */ +export function loadPositionalTag(tag: SerializedPositionalTag): PositionalTag; +export function loadPositionalTag({ + tagType, + ...rest +}: serializedPosTagMap[T]): posTagInstanceMap[T] { + // Note: We need 2 type assertions here: + // 1 because TS doesn't narrow the type of TagClass correctly based on `T`. + // It converts it into `new (DelayedAttackTag | WishTag) => DelayedAttackTag & WishTag` + const tagClass = posTagConstructorMap[tagType] as new (args: posTagParamMap[T]) => posTagInstanceMap[T]; + // 2 because TS doesn't narrow the type of `rest` correctly + // (from `Omit into `posTagParamMap[T]`) + return new tagClass(rest as unknown as posTagParamMap[T]); +} + +/** Const object mapping tag types to their constructors. */ +const posTagConstructorMap = Object.freeze({ + [PositionalTagType.DELAYED_ATTACK]: DelayedAttackTag, + [PositionalTagType.WISH]: WishTag, +}) satisfies { + // NB: This `satisfies` block ensures that all tag types have corresponding entries in the map. + [k in PositionalTagType]: Constructor; +}; + +/** Type mapping positional tag types to their constructors. */ +type posTagMap = typeof posTagConstructorMap; + +/** Type mapping all positional tag types to their instances. */ +type posTagInstanceMap = { + [k in PositionalTagType]: InstanceType; +}; + +/** Type mapping all positional tag types to their constructors' parameters. */ +type posTagParamMap = { + [k in PositionalTagType]: ConstructorParameters[0]; +}; + +/** + * Type mapping all positional tag types to their constructors' parameters, alongside the `tagType` selector. + * Equivalent to their serialized representations. + */ +export type serializedPosTagMap = { + [k in PositionalTagType]: posTagParamMap[k] & { tagType: k }; +}; + +/** Union type containing all serialized {@linkcode PositionalTag}s. */ +export type SerializedPositionalTag = ObjectValues; diff --git a/src/data/positional-tags/positional-tag-manager.ts b/src/data/positional-tags/positional-tag-manager.ts new file mode 100644 index 00000000000..7bf4d4995c6 --- /dev/null +++ b/src/data/positional-tags/positional-tag-manager.ts @@ -0,0 +1,55 @@ +import { loadPositionalTag } from "#data/positional-tags/load-positional-tag"; +import type { PositionalTag } from "#data/positional-tags/positional-tag"; +import type { BattlerIndex } from "#enums/battler-index"; +import type { PositionalTagType } from "#enums/positional-tag-type"; + +/** A manager for the {@linkcode PositionalTag}s in the arena. */ +export class PositionalTagManager { + /** + * Array containing all pending unactivated {@linkcode PositionalTag}s, + * sorted by order of creation (oldest first). + */ + public tags: PositionalTag[] = []; + + /** + * Add a new {@linkcode PositionalTag} to the arena. + * @remarks + * This function does not perform any checking if the added tag is valid. + */ + public addTag(tag: Parameters>[0]): void { + this.tags.push(loadPositionalTag(tag)); + } + + /** + * Check whether a new {@linkcode PositionalTag} can be added to the battlefield. + * @param tagType - The {@linkcode PositionalTagType} being created + * @param targetIndex - The {@linkcode BattlerIndex} being targeted + * @returns Whether the tag can be added. + */ + public canAddTag(tagType: PositionalTagType, targetIndex: BattlerIndex): boolean { + return !this.tags.some(t => t.tagType === tagType && t.targetIndex === targetIndex); + } + + /** + * Decrement turn counts of and trigger all pending {@linkcode PositionalTag}s on field. + * @remarks + * If multiple tags trigger simultaneously, they will activate in order of **initial creation**, regardless of current speed order. + * (Source: [Smogon]()) + */ + public activateAllTags(): void { + const leftoverTags: PositionalTag[] = []; + for (const tag of this.tags) { + // Check for silent removal, immediately removing invalid tags. + if (--tag.turnCount > 0) { + // tag still cooking + leftoverTags.push(tag); + continue; + } + + if (tag.shouldTrigger()) { + tag.trigger(); + } + } + this.tags = leftoverTags; + } +} diff --git a/src/data/positional-tags/positional-tag.ts b/src/data/positional-tags/positional-tag.ts new file mode 100644 index 00000000000..77ca6f0e9eb --- /dev/null +++ b/src/data/positional-tags/positional-tag.ts @@ -0,0 +1,174 @@ +import { globalScene } from "#app/global-scene"; +import { getPokemonNameWithAffix } from "#app/messages"; +// biome-ignore-start lint/correctness/noUnusedImports: TSDoc +import type { ArenaTag } from "#data/arena-tag"; +// biome-ignore-end lint/correctness/noUnusedImports: TSDoc +import { allMoves } from "#data/data-lists"; +import type { BattlerIndex } from "#enums/battler-index"; +import type { MoveId } from "#enums/move-id"; +import { MoveUseMode } from "#enums/move-use-mode"; +import { PositionalTagType } from "#enums/positional-tag-type"; +import type { Pokemon } from "#field/pokemon"; +import i18next from "i18next"; + +/** + * Baseline arguments used to construct all {@linkcode PositionalTag}s, + * the contents of which are serialized and used to construct new tags. \ + * Does not contain the `tagType` parameter (which is used to select the proper class constructor during tag loading). + * @privateRemarks + * All {@linkcode PositionalTag}s are intended to implement a sub-interface of this containing their respective parameters, + * and should refrain from adding extra serializable fields not contained in said interface. + * This ensures that all tags truly "become" their respective interfaces when converted to and from JSON. + */ +export interface PositionalTagBaseArgs { + /** + * The number of turns remaining until this tag's activation. \ + * Decremented by 1 at the end of each turn until reaching 0, at which point it will + * {@linkcode PositionalTag.trigger | trigger} the tag's effects and be removed. + */ + turnCount: number; + /** + * The {@linkcode BattlerIndex} targeted by this effect. + */ + targetIndex: BattlerIndex; +} + +/** + * A {@linkcode PositionalTag} is a variant of an {@linkcode ArenaTag} that targets a single *slot* of the battlefield. + * Each tag can last one or more turns, triggering various effects on removal. + * Multiple tags of the same kind can stack with one another, provided they are affecting different targets. + */ +export abstract class PositionalTag implements PositionalTagBaseArgs { + /** This tag's {@linkcode PositionalTagType | type} */ + public abstract readonly tagType: PositionalTagType; + // These arguments have to be public to implement the interface, but are functionally private + // outside this and the tag manager. + // Left undocumented to inherit doc comments from the interface + public turnCount: number; + public readonly targetIndex: BattlerIndex; + + constructor({ turnCount, targetIndex }: PositionalTagBaseArgs) { + this.turnCount = turnCount; + this.targetIndex = targetIndex; + } + + /** Trigger this tag's effects prior to removal. */ + public abstract trigger(): void; + + /** + * Check whether this tag should be allowed to {@linkcode trigger} and activate its effects + * upon its duration elapsing. + * @returns Whether this tag should be allowed to trigger prior to being removed. + */ + public abstract shouldTrigger(): boolean; + + /** + * Get the {@linkcode Pokemon} currently targeted by this tag. + * @returns The {@linkcode Pokemon} located in this tag's target position, or `undefined` if none exist in it. + */ + protected getTarget(): Pokemon | undefined { + return globalScene.getField()[this.targetIndex]; + } +} + +/** Interface containing additional properties used to construct a {@linkcode DelayedAttackTag}. */ +interface DelayedAttackArgs extends PositionalTagBaseArgs { + /** + * The {@linkcode Pokemon.id | PID} of the {@linkcode Pokemon} having created this effect. + */ + sourceId: number; + /** The {@linkcode MoveId} that created this attack. */ + sourceMove: MoveId; +} + +/** + * Tag to manage execution of delayed attacks, such as {@linkcode MoveId.FUTURE_SIGHT} or {@linkcode MoveId.DOOM_DESIRE}. \ + * Delayed attacks do nothing for the first several turns after use (including the turn the move is used), + * triggering against a certain slot after the turn count has elapsed. + */ +export class DelayedAttackTag extends PositionalTag implements DelayedAttackArgs { + public override readonly tagType = PositionalTagType.DELAYED_ATTACK; + public readonly sourceMove: MoveId; + public readonly sourceId: number; + + constructor({ sourceId, turnCount, targetIndex, sourceMove }: DelayedAttackArgs) { + super({ turnCount, targetIndex }); + this.sourceId = sourceId; + this.sourceMove = sourceMove; + } + + public override trigger(): void { + // Bangs are justified as the `shouldTrigger` method will queue the tag for removal + // if the source or target no longer exist + const source = globalScene.getPokemonById(this.sourceId)!; + const target = this.getTarget()!; + + source.turnData.extraTurns++; + globalScene.phaseManager.queueMessage( + i18next.t("moveTriggers:tookMoveAttack", { + pokemonName: getPokemonNameWithAffix(target), + moveName: allMoves[this.sourceMove].name, + }), + ); + + globalScene.phaseManager.unshiftNew( + "MoveEffectPhase", + this.sourceId, // TODO: Find an alternate method of passing the source pokemon without a source ID + [this.targetIndex], + allMoves[this.sourceMove], + MoveUseMode.DELAYED_ATTACK, + ); + } + + public override shouldTrigger(): boolean { + const source = globalScene.getPokemonById(this.sourceId); + const target = this.getTarget(); + // Silently disappear if either source or target are missing or happen to be the same pokemon + // (i.e. targeting oneself) + // We also need to check for fainted targets as they don't technically leave the field until _after_ the turn ends + return !!source && !!target && source !== target && !target.isFainted(); + } +} + +/** Interface containing arguments used to construct a {@linkcode WishTag}. */ +interface WishArgs extends PositionalTagBaseArgs { + /** The amount of {@linkcode Stat.HP | HP} to heal; set to 50% of the user's max HP during move usage. */ + healHp: number; + /** The name of the {@linkcode Pokemon} having created the tag. */ + pokemonName: string; +} + +/** + * Tag to implement {@linkcode MoveId.WISH | Wish}. + */ +export class WishTag extends PositionalTag implements WishArgs { + public override readonly tagType = PositionalTagType.WISH; + + public readonly pokemonName: string; + public readonly healHp: number; + + constructor({ turnCount, targetIndex, healHp, pokemonName }: WishArgs) { + super({ turnCount, targetIndex }); + this.healHp = healHp; + this.pokemonName = pokemonName; + } + + public override trigger(): void { + // TODO: Rename this locales key - wish shows a message on REMOVAL, not addition + globalScene.phaseManager.queueMessage( + i18next.t("arenaTag:wishTagOnAdd", { + pokemonNameWithAffix: this.pokemonName, + }), + ); + + globalScene.phaseManager.unshiftNew("PokemonHealPhase", this.targetIndex, this.healHp, null, true, false); + } + + public override shouldTrigger(): boolean { + // Disappear if no target or target is fainted. + // The source need not exist at the time of activation (since all we need is a simple message) + // TODO: Verify whether Wish shows a message if the Pokemon it would affect is KO'd on the turn of activation + const target = this.getTarget(); + return !!target && !target.isFainted(); + } +} diff --git a/src/enums/arena-tag-type.ts b/src/enums/arena-tag-type.ts index 214826993b3..7f9364395c0 100644 --- a/src/enums/arena-tag-type.ts +++ b/src/enums/arena-tag-type.ts @@ -15,9 +15,6 @@ export enum ArenaTagType { SPIKES = "SPIKES", TOXIC_SPIKES = "TOXIC_SPIKES", MIST = "MIST", - FUTURE_SIGHT = "FUTURE_SIGHT", - DOOM_DESIRE = "DOOM_DESIRE", - WISH = "WISH", STEALTH_ROCK = "STEALTH_ROCK", STICKY_WEB = "STICKY_WEB", TRICK_ROOM = "TRICK_ROOM", diff --git a/src/enums/move-use-mode.ts b/src/enums/move-use-mode.ts index 1bb9d6374b7..13ea5248853 100644 --- a/src/enums/move-use-mode.ts +++ b/src/enums/move-use-mode.ts @@ -1,5 +1,7 @@ import type { PostDancingMoveAbAttr } from "#abilities/ability"; +import type { DelayedAttackAttr } from "#app/@types/move-types"; import type { BattlerTagLapseType } from "#enums/battler-tag-lapse-type"; +import type { ObjectValues } from "#types/type-helpers"; /** * Enum representing all the possible means through which a given move can be executed. @@ -59,11 +61,20 @@ export const MoveUseMode = { * and retain the same copy prevention as {@linkcode MoveUseMode.FOLLOW_UP}, but additionally * **cannot be reflected by other reflecting effects**. */ - REFLECTED: 5 - // TODO: Add use type TRANSPARENT for Future Sight and Doom Desire to prevent move history pushing + REFLECTED: 5, + /** + * This "move" was created by a transparent effect that **does not count as using a move**, + * such as {@linkcode DelayedAttackAttr | Future Sight/Doom Desire}. + * + * In addition to inheriting the cancellation ignores and copy prevention from {@linkcode MoveUseMode.REFLECTED}, + * transparent moves are ignored by **all forms of move usage checks** due to **not pushing to move history**. + * @todo Consider other means of implementing FS/DD than this - we currently only use it + * to prevent pushing to move history and avoid re-delaying the attack portion + */ + DELAYED_ATTACK: 6 } as const; -export type MoveUseMode = (typeof MoveUseMode)[keyof typeof MoveUseMode]; +export type MoveUseMode = ObjectValues; // # HELPER FUNCTIONS // Please update the markdown tables if any new `MoveUseMode`s get added. @@ -75,13 +86,14 @@ export type MoveUseMode = (typeof MoveUseMode)[keyof typeof MoveUseMode]; * @remarks * This function is equivalent to the following truth table: * - * | Use Type | Returns | - * |------------------------------------|---------| - * | {@linkcode MoveUseMode.NORMAL} | `false` | - * | {@linkcode MoveUseMode.IGNORE_PP} | `false` | - * | {@linkcode MoveUseMode.INDIRECT} | `true` | - * | {@linkcode MoveUseMode.FOLLOW_UP} | `true` | - * | {@linkcode MoveUseMode.REFLECTED} | `true` | + * | Use Type | Returns | + * |----------------------------------------|---------| + * | {@linkcode MoveUseMode.NORMAL} | `false` | + * | {@linkcode MoveUseMode.IGNORE_PP} | `false` | + * | {@linkcode MoveUseMode.INDIRECT} | `true` | + * | {@linkcode MoveUseMode.FOLLOW_UP} | `true` | + * | {@linkcode MoveUseMode.REFLECTED} | `true` | + * | {@linkcode MoveUseMode.DELAYED_ATTACK} | `true` | */ export function isVirtual(useMode: MoveUseMode): boolean { return useMode >= MoveUseMode.INDIRECT @@ -95,13 +107,14 @@ export function isVirtual(useMode: MoveUseMode): boolean { * @remarks * This function is equivalent to the following truth table: * - * | Use Type | Returns | - * |------------------------------------|---------| - * | {@linkcode MoveUseMode.NORMAL} | `false` | - * | {@linkcode MoveUseMode.IGNORE_PP} | `false` | - * | {@linkcode MoveUseMode.INDIRECT} | `false` | - * | {@linkcode MoveUseMode.FOLLOW_UP} | `true` | - * | {@linkcode MoveUseMode.REFLECTED} | `true` | + * | Use Type | Returns | + * |----------------------------------------|---------| + * | {@linkcode MoveUseMode.NORMAL} | `false` | + * | {@linkcode MoveUseMode.IGNORE_PP} | `false` | + * | {@linkcode MoveUseMode.INDIRECT} | `false` | + * | {@linkcode MoveUseMode.FOLLOW_UP} | `true` | + * | {@linkcode MoveUseMode.REFLECTED} | `true` | + * | {@linkcode MoveUseMode.DELAYED_ATTACK} | `true` | */ export function isIgnoreStatus(useMode: MoveUseMode): boolean { return useMode >= MoveUseMode.FOLLOW_UP; @@ -115,13 +128,14 @@ export function isIgnoreStatus(useMode: MoveUseMode): boolean { * @remarks * This function is equivalent to the following truth table: * - * | Use Type | Returns | - * |------------------------------------|---------| - * | {@linkcode MoveUseMode.NORMAL} | `false` | - * | {@linkcode MoveUseMode.IGNORE_PP} | `true` | - * | {@linkcode MoveUseMode.INDIRECT} | `true` | - * | {@linkcode MoveUseMode.FOLLOW_UP} | `true` | - * | {@linkcode MoveUseMode.REFLECTED} | `true` | + * | Use Type | Returns | + * |----------------------------------------|---------| + * | {@linkcode MoveUseMode.NORMAL} | `false` | + * | {@linkcode MoveUseMode.IGNORE_PP} | `true` | + * | {@linkcode MoveUseMode.INDIRECT} | `true` | + * | {@linkcode MoveUseMode.FOLLOW_UP} | `true` | + * | {@linkcode MoveUseMode.REFLECTED} | `true` | + * | {@linkcode MoveUseMode.DELAYED_ATTACK} | `true` | */ export function isIgnorePP(useMode: MoveUseMode): boolean { return useMode >= MoveUseMode.IGNORE_PP; @@ -136,14 +150,15 @@ export function isIgnorePP(useMode: MoveUseMode): boolean { * @remarks * This function is equivalent to the following truth table: * - * | Use Type | Returns | - * |------------------------------------|---------| - * | {@linkcode MoveUseMode.NORMAL} | `false` | - * | {@linkcode MoveUseMode.IGNORE_PP} | `false` | - * | {@linkcode MoveUseMode.INDIRECT} | `false` | - * | {@linkcode MoveUseMode.FOLLOW_UP} | `false` | - * | {@linkcode MoveUseMode.REFLECTED} | `true` | + * | Use Type | Returns | + * |----------------------------------------|---------| + * | {@linkcode MoveUseMode.NORMAL} | `false` | + * | {@linkcode MoveUseMode.IGNORE_PP} | `false` | + * | {@linkcode MoveUseMode.INDIRECT} | `false` | + * | {@linkcode MoveUseMode.FOLLOW_UP} | `false` | + * | {@linkcode MoveUseMode.REFLECTED} | `true` | + * | {@linkcode MoveUseMode.DELAYED_ATTACK} | `false` | */ export function isReflected(useMode: MoveUseMode): boolean { return useMode === MoveUseMode.REFLECTED; -} +} \ No newline at end of file diff --git a/src/enums/positional-tag-type.ts b/src/enums/positional-tag-type.ts new file mode 100644 index 00000000000..254503d0de6 --- /dev/null +++ b/src/enums/positional-tag-type.ts @@ -0,0 +1,10 @@ +/** + * Enum representing all positional tag types. + * @privateRemarks + * When adding new tag types, please update `positionalTagConstructorMap` in `src/data/positionalTags` + * with the new tag type. + */ +export enum PositionalTagType { + DELAYED_ATTACK = "DELAYED_ATTACK", + WISH = "WISH", +} diff --git a/src/field/arena.ts b/src/field/arena.ts index 8f27ddb22e9..484450cc5df 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -1,3 +1,7 @@ +// biome-ignore-start lint/correctness/noUnusedImports: TSDoc imports +import type { PositionalTag } from "#data/positional-tags/positional-tag"; +// biome-ignore-end lint/correctness/noUnusedImports: TSDoc imports + import { applyAbAttrs } from "#abilities/apply-ab-attrs"; import { globalScene } from "#app/global-scene"; import Overrides from "#app/overrides"; @@ -7,6 +11,7 @@ import type { ArenaTag } from "#data/arena-tag"; import { ArenaTrapTag, getArenaTag } from "#data/arena-tag"; import { SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "#data/form-change-triggers"; import type { PokemonSpecies } from "#data/pokemon-species"; +import { PositionalTagManager } from "#data/positional-tags/positional-tag-manager"; import { getTerrainClearMessage, getTerrainStartMessage, Terrain, TerrainType } from "#data/terrain"; import { getLegendaryWeatherContinuesMessage, @@ -38,7 +43,14 @@ export class Arena { public biomeType: BiomeId; public weather: Weather | null; public terrain: Terrain | null; - public tags: ArenaTag[]; + /** All currently-active {@linkcode ArenaTag}s on both sides of the field. */ + public tags: ArenaTag[] = []; + /** + * All currently-active {@linkcode PositionalTag}s on both sides of the field, + * sorted by tag type. + */ + public positionalTagManager: PositionalTagManager = new PositionalTagManager(); + public bgm: string; public ignoreAbilities: boolean; public ignoringEffectSource: BattlerIndex | null; @@ -58,7 +70,6 @@ export class Arena { constructor(biome: BiomeId, bgm: string, playerFaints = 0) { this.biomeType = biome; - this.tags = []; this.bgm = bgm; this.trainerPool = biomeTrainerPools[biome]; this.updatePoolsForTimeOfDay(); @@ -676,15 +687,15 @@ export class Arena { } /** - * Adds a new tag to the arena - * @param tagType {@linkcode ArenaTagType} the tag being added - * @param turnCount How many turns the tag lasts - * @param sourceMove {@linkcode MoveId} the move the tag came from, or `undefined` if not from a move - * @param sourceId The ID of the pokemon in play the tag came from (see {@linkcode BattleScene.getPokemonById}) - * @param side {@linkcode ArenaTagSide} which side(s) the tag applies to - * @param quiet If a message should be queued on screen to announce the tag being added - * @param targetIndex The {@linkcode BattlerIndex} of the target pokemon - * @returns `false` if there already exists a tag of this type in the Arena + * Add a new {@linkcode ArenaTag} to the arena, triggering overlap effects on existing tags as applicable. + * @param tagType - The {@linkcode ArenaTagType} of the tag to add. + * @param turnCount - The number of turns the newly-added tag should last. + * @param sourceId - The {@linkcode Pokemon.id | PID} of the Pokemon creating the tag. + * @param sourceMove - The {@linkcode MoveId} of the move creating the tag, or `undefined` if not from a move. + * @param side - The {@linkcode ArenaTagSide}(s) to which the tag should apply; default `ArenaTagSide.BOTH`. + * @param quiet - Whether to suppress messages produced by tag addition; default `false`. + * @returns `true` if the tag was successfully added without overlapping. + // TODO: Do we need the return value here? literally nothing uses it */ addTag( tagType: ArenaTagType, @@ -693,7 +704,6 @@ export class Arena { sourceId: number, side: ArenaTagSide = ArenaTagSide.BOTH, quiet = false, - targetIndex?: BattlerIndex, ): boolean { const existingTag = this.getTagOnSide(tagType, side); if (existingTag) { @@ -708,7 +718,7 @@ export class Arena { } // creates a new tag object - const newTag = getArenaTag(tagType, turnCount || 0, sourceMove, sourceId, targetIndex, side); + const newTag = getArenaTag(tagType, turnCount || 0, sourceMove, sourceId, side); if (newTag) { newTag.onAdd(this, quiet); this.tags.push(newTag); @@ -724,10 +734,19 @@ export class Arena { } /** - * Attempts to get a tag from the Arena via {@linkcode getTagOnSide} that applies to both sides - * @param tagType The {@linkcode ArenaTagType} or {@linkcode ArenaTag} to get - * @returns either the {@linkcode ArenaTag}, or `undefined` if it isn't there + * Attempt to get a tag from the Arena via {@linkcode getTagOnSide} that applies to both sides + * @param tagType - The {@linkcode ArenaTagType} to retrieve + * @returns The existing {@linkcode ArenaTag}, or `undefined` if not present. + * @overload */ + getTag(tagType: ArenaTagType): ArenaTag | undefined; + /** + * Attempt to get a tag from the Arena via {@linkcode getTagOnSide} that applies to both sides + * @param tagType - The constructor of the {@linkcode ArenaTag} to retrieve + * @returns The existing {@linkcode ArenaTag}, or `undefined` if not present. + * @overload + */ + getTag(tagType: Constructor | AbstractConstructor): T | undefined; getTag(tagType: ArenaTagType | Constructor | AbstractConstructor): ArenaTag | undefined { return this.getTagOnSide(tagType, ArenaTagSide.BOTH); } diff --git a/src/phase-manager.ts b/src/phase-manager.ts index c56afe446ed..37edeae7e42 100644 --- a/src/phase-manager.ts +++ b/src/phase-manager.ts @@ -61,6 +61,7 @@ import { PartyHealPhase } from "#phases/party-heal-phase"; import { PokemonAnimPhase } from "#phases/pokemon-anim-phase"; import { PokemonHealPhase } from "#phases/pokemon-heal-phase"; import { PokemonTransformPhase } from "#phases/pokemon-transform-phase"; +import { PositionalTagPhase } from "#phases/positional-tag-phase"; import { PostGameOverPhase } from "#phases/post-game-over-phase"; import { PostSummonPhase } from "#phases/post-summon-phase"; import { PostTurnStatusEffectPhase } from "#phases/post-turn-status-effect-phase"; @@ -172,6 +173,7 @@ const PHASES = Object.freeze({ PokemonAnimPhase, PokemonHealPhase, PokemonTransformPhase, + PositionalTagPhase, PostGameOverPhase, PostSummonPhase, PostTurnStatusEffectPhase, diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index b1cb9e48d51..c57e0f6cead 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -19,7 +19,7 @@ import { MoveFlags } from "#enums/move-flags"; import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { MoveTarget } from "#enums/move-target"; -import { isReflected, isVirtual, MoveUseMode } from "#enums/move-use-mode"; +import { isReflected, MoveUseMode } from "#enums/move-use-mode"; import { PokemonType } from "#enums/pokemon-type"; import type { Pokemon } from "#field/pokemon"; import { @@ -244,43 +244,19 @@ export class MoveEffectPhase extends PokemonPhase { globalScene.currentBattle.lastPlayerInvolved = this.fieldIndex; } - const isDelayedAttack = this.move.hasAttr("DelayedAttackAttr"); - /** If the user was somehow removed from the field and it's not a delayed attack, end this phase */ - if (!user.isOnField()) { - if (!isDelayedAttack) { - super.end(); - return; - } - if (!user.scene) { - /* - * This happens if the Pokemon that used the delayed attack gets caught and released - * on the turn the attack would have triggered. Having access to the global scene - * in the future may solve this entirely, so for now we just cancel the hit - */ - super.end(); - return; - } - } + const move = this.move; /** * Does an effect from this move override other effects on this turn? * e.g. Charging moves (Fly, etc.) on their first turn of use. */ const overridden = new BooleanHolder(false); - const move = this.move; // Apply effects to override a move effect. // Assuming single target here works as this is (currently) // only used for Future Sight, calling and Pledge moves. // TODO: change if any other move effect overrides are introduced - applyMoveAttrs( - "OverrideMoveEffectAttr", - user, - this.getFirstTarget() ?? null, - move, - overridden, - isVirtual(this.useMode), - ); + applyMoveAttrs("OverrideMoveEffectAttr", user, this.getFirstTarget() ?? null, move, overridden, this.useMode); // If other effects were overriden, stop this phase before they can be applied if (overridden.value) { @@ -355,7 +331,7 @@ export class MoveEffectPhase extends PokemonPhase { */ private postAnimCallback(user: Pokemon, targets: Pokemon[]) { // Add to the move history entry - if (this.firstHit) { + if (this.firstHit && this.useMode !== MoveUseMode.DELAYED_ATTACK) { user.pushMoveHistory(this.moveHistoryEntry); applyAbAttrs("ExecutedMoveAbAttr", { pokemon: user }); } @@ -663,6 +639,7 @@ export class MoveEffectPhase extends PokemonPhase { /** @returns The {@linkcode Pokemon} using this phase's invoked move */ public getUserPokemon(): Pokemon | null { + // TODO: Make this purely a battler index if (this.battlerIndex > BattlerIndex.ENEMY_2) { return globalScene.getPokemonById(this.battlerIndex); } diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index 82bb6b153ef..cd7c7a8f48f 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -2,14 +2,12 @@ import { applyAbAttrs } from "#abilities/apply-ab-attrs"; import { globalScene } from "#app/global-scene"; import { getPokemonNameWithAffix } from "#app/messages"; import Overrides from "#app/overrides"; -import type { DelayedAttackTag } from "#data/arena-tag"; import { CenterOfAttentionTag } from "#data/battler-tags"; import { SpeciesFormChangePreMoveTrigger } from "#data/form-change-triggers"; import { getStatusEffectActivationText, getStatusEffectHealText } from "#data/status-effect"; import { getTerrainBlockMessage } from "#data/terrain"; import { getWeatherBlockMessage } from "#data/weather"; import { AbilityId } from "#enums/ability-id"; -import { ArenaTagType } from "#enums/arena-tag-type"; import { BattlerIndex } from "#enums/battler-index"; import { BattlerTagLapseType } from "#enums/battler-tag-lapse-type"; import { BattlerTagType } from "#enums/battler-tag-type"; @@ -297,21 +295,6 @@ export class MovePhase extends BattlePhase { // form changes happen even before we know that the move wll execute. globalScene.triggerPokemonFormChange(this.pokemon, SpeciesFormChangePreMoveTrigger); - // Check the player side arena if another delayed attack is active and hitting the same slot. - if (move.hasAttr("DelayedAttackAttr")) { - const currentTargetIndex = targets[0].getBattlerIndex(); - const delayedAttackHittingSameSlot = globalScene.arena.tags.some( - tag => - (tag.tagType === ArenaTagType.FUTURE_SIGHT || tag.tagType === ArenaTagType.DOOM_DESIRE) && - (tag as DelayedAttackTag).targetIndex === currentTargetIndex, - ); - - if (delayedAttackHittingSameSlot) { - this.failMove(true); - return; - } - } - // Check if the move has any attributes that can interrupt its own use **before** displaying text. // TODO: This should not rely on direct return values let failed = move.getAttrs("PreUseInterruptAttr").some(attr => attr.apply(this.pokemon, targets[0], move)); diff --git a/src/phases/positional-tag-phase.ts b/src/phases/positional-tag-phase.ts new file mode 100644 index 00000000000..dec572273c5 --- /dev/null +++ b/src/phases/positional-tag-phase.ts @@ -0,0 +1,21 @@ +// biome-ignore-start lint/correctness/noUnusedImports: TSDocs +import type { PositionalTag } from "#data/positional-tags/positional-tag"; +import type { TurnEndPhase } from "#phases/turn-end-phase"; +// biome-ignore-end lint/correctness/noUnusedImports: TSDocs + +import { globalScene } from "#app/global-scene"; +import { Phase } from "#app/phase"; + +/** + * Phase to trigger all pending post-turn {@linkcode PositionalTag}s. + * Occurs before {@linkcode TurnEndPhase} to allow for proper electrify timing. + */ +export class PositionalTagPhase extends Phase { + public readonly phaseName = "PositionalTagPhase"; + + public override start(): void { + globalScene.arena.positionalTagManager.activateAllTags(); + super.end(); + return; + } +} diff --git a/src/phases/turn-start-phase.ts b/src/phases/turn-start-phase.ts index 9fdac65bb10..9c53a333ed0 100644 --- a/src/phases/turn-start-phase.ts +++ b/src/phases/turn-start-phase.ts @@ -220,12 +220,16 @@ export class TurnStartPhase extends FieldPhase { } phaseManager.pushNew("CheckInterludePhase"); + // TODO: Re-order these phases to be consistent with mainline turn order: + // https://www.smogon.com/forums/threads/sword-shield-battle-mechanics-research.3655528/page-64#post-9244179 + phaseManager.pushNew("WeatherEffectPhase"); phaseManager.pushNew("BerryPhase"); /** Add a new phase to check who should be taking status damage */ phaseManager.pushNew("CheckStatusEffectPhase", moveOrder); + phaseManager.pushNew("PositionalTagPhase"); phaseManager.pushNew("TurnEndPhase"); /* diff --git a/src/system/arena-data.ts b/src/system/arena-data.ts index c0ad4a25024..b2a04f96a55 100644 --- a/src/system/arena-data.ts +++ b/src/system/arena-data.ts @@ -1,5 +1,6 @@ import type { ArenaTag } from "#data/arena-tag"; import { loadArenaTag, SerializableArenaTag } from "#data/arena-tag"; +import type { SerializedPositionalTag } from "#data/positional-tags/load-positional-tag"; import { Terrain } from "#data/terrain"; import { Weather } from "#data/weather"; import type { BiomeId } from "#enums/biome-id"; @@ -12,6 +13,7 @@ export interface SerializedArenaData { weather: NonFunctionProperties | null; terrain: NonFunctionProperties | null; tags?: ArenaTagTypeData[]; + positionalTags: SerializedPositionalTag[]; playerTerasUsed?: number; } @@ -20,6 +22,7 @@ export class ArenaData { public weather: Weather | null; public terrain: Terrain | null; public tags: ArenaTag[]; + public positionalTags: SerializedPositionalTag[] = []; public playerTerasUsed: number; constructor(source: Arena | SerializedArenaData) { @@ -37,11 +40,15 @@ export class ArenaData { this.biome = source.biomeType; this.weather = source.weather; this.terrain = source.terrain; + // The assertion here is ok - we ensure that all tags are inside the `posTagConstructorMap` map, + // and that all `PositionalTags` will become their respective interfaces when serialized and de-serialized. + this.positionalTags = (source.positionalTagManager.tags as unknown as SerializedPositionalTag[]) ?? []; return; } this.biome = source.biome; this.weather = source.weather ? new Weather(source.weather.weatherType, source.weather.turnsLeft) : null; this.terrain = source.terrain ? new Terrain(source.terrain.terrainType, source.terrain.turnsLeft) : null; + this.positionalTags = source.positionalTags ?? []; } } diff --git a/src/system/game-data.ts b/src/system/game-data.ts index b148ed4e2ba..d899afa19ef 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -16,6 +16,7 @@ import { allMoves, allSpecies } from "#data/data-lists"; import type { Egg } from "#data/egg"; import { pokemonFormChanges } from "#data/pokemon-forms"; import type { PokemonSpecies } from "#data/pokemon-species"; +import { loadPositionalTag } from "#data/positional-tags/load-positional-tag"; import { TerrainType } from "#data/terrain"; import { AbilityAttr } from "#enums/ability-attr"; import { BattleType } from "#enums/battle-type"; @@ -1096,6 +1097,10 @@ export class GameData { } } + globalScene.arena.positionalTagManager.tags = sessionData.arena.positionalTags.map(tag => + loadPositionalTag(tag), + ); + if (globalScene.modifiers.length) { console.warn("Existing modifiers not cleared on session load, deleting..."); globalScene.modifiers = []; diff --git a/test/moves/delayed-attack.test.ts b/test/moves/delayed-attack.test.ts new file mode 100644 index 00000000000..e8cf2871626 --- /dev/null +++ b/test/moves/delayed-attack.test.ts @@ -0,0 +1,389 @@ +import { getPokemonNameWithAffix } from "#app/messages"; +import { AttackTypeBoosterModifier } from "#app/modifier/modifier"; +import { allMoves } from "#data/data-lists"; +import { AbilityId } from "#enums/ability-id"; +import { BattleType } from "#enums/battle-type"; +import { BattlerIndex } from "#enums/battler-index"; +import { MoveId } from "#enums/move-id"; +import { MoveResult } from "#enums/move-result"; +import { PokemonType } from "#enums/pokemon-type"; +import { PositionalTagType } from "#enums/positional-tag-type"; +import { SpeciesId } from "#enums/species-id"; +import { Stat } from "#enums/stat"; +import { GameManager } from "#test/test-utils/game-manager"; +import i18next from "i18next"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Moves - Delayed Attacks", () => { + 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 + .ability(AbilityId.NO_GUARD) + .battleStyle("single") + .enemySpecies(SpeciesId.MAGIKARP) + .enemyAbility(AbilityId.STURDY) + .enemyMoveset(MoveId.SPLASH); + }); + + /** + * Wait until a number of turns have passed. + * @param numTurns - Number of turns to pass. + * @param toEndOfTurn - Whether to advance to the `TurnEndPhase` (`true`) or the `PositionalTagPhase` (`false`); + * default `true` + * @returns A Promise that resolves once the specified number of turns has elapsed + * and the specified phase has been reached. + */ + async function passTurns(numTurns: number, toEndOfTurn = true): Promise { + for (let i = 0; i < numTurns; i++) { + game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER); + if (game.scene.getPlayerField()[1]?.isActive()) { + game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER_2); + } + await game.move.forceEnemyMove(MoveId.SPLASH); + if (game.scene.getEnemyField()[1]?.isActive()) { + await game.move.forceEnemyMove(MoveId.SPLASH); + } + await game.phaseInterceptor.to("PositionalTagPhase"); + } + if (toEndOfTurn) { + await game.toEndOfTurn(); + } + } + + /** + * Expect that future sight is active with the specified number of attacks. + * @param numAttacks - The number of delayed attacks that should be queued; default `1` + */ + function expectFutureSightActive(numAttacks = 1) { + const delayedAttacks = game.scene.arena.positionalTagManager["tags"].filter( + t => t.tagType === PositionalTagType.DELAYED_ATTACK, + ); + expect(delayedAttacks).toHaveLength(numAttacks); + } + + it.each<{ name: string; move: MoveId }>([ + { name: "Future Sight", move: MoveId.FUTURE_SIGHT }, + { name: "Doom Desire", move: MoveId.DOOM_DESIRE }, + ])("$name should show message and strike 2 turns after use, ignoring player/enemy switches", async ({ move }) => { + game.override.battleType(BattleType.TRAINER); + await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MILOTIC]); + + game.move.use(move); + await game.toNextTurn(); + + expectFutureSightActive(); + + game.doSwitchPokemon(1); + game.forceEnemyToSwitch(); + await game.toNextTurn(); + + await passTurns(1); + + expectFutureSightActive(0); + const enemy = game.field.getEnemyPokemon(); + expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); + expect(game.textInterceptor.logs).toContain( + i18next.t("moveTriggers:tookMoveAttack", { + pokemonName: getPokemonNameWithAffix(enemy), + moveName: allMoves[move].name, + }), + ); + }); + + it("should fail (preserving prior instances) when used against the same target", async () => { + await game.classicMode.startBattle([SpeciesId.BRONZONG]); + + game.move.use(MoveId.FUTURE_SIGHT); + await game.toNextTurn(); + + expectFutureSightActive(); + const bronzong = game.field.getPlayerPokemon(); + expect(bronzong.getLastXMoves()[0].result).toBe(MoveResult.OTHER); + + game.move.use(MoveId.FUTURE_SIGHT); + await game.toNextTurn(); + + expectFutureSightActive(); + expect(bronzong.getLastXMoves()[0].result).toBe(MoveResult.FAIL); + }); + + it("should still be delayed when called by other moves", async () => { + await game.classicMode.startBattle([SpeciesId.BRONZONG]); + + game.move.use(MoveId.METRONOME); + game.move.forceMetronomeMove(MoveId.FUTURE_SIGHT); + await game.toNextTurn(); + + expectFutureSightActive(); + const enemy = game.field.getEnemyPokemon(); + expect(enemy.hp).toBe(enemy.getMaxHp()); + + await passTurns(2); + + expectFutureSightActive(0); + expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); + }); + + it("should work when used against different targets in doubles", async () => { + game.override.battleStyle("double"); + await game.classicMode.startBattle([SpeciesId.MAGIKARP, SpeciesId.FEEBAS]); + + const [karp, feebas, enemy1, enemy2] = game.scene.getField(); + + game.move.use(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER, BattlerIndex.ENEMY); + game.move.use(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2); + await game.toEndOfTurn(); + + expectFutureSightActive(2); + expect(enemy1.hp).toBe(enemy1.getMaxHp()); + expect(enemy2.hp).toBe(enemy2.getMaxHp()); + expect(karp.getLastXMoves()[0].result).toBe(MoveResult.OTHER); + expect(feebas.getLastXMoves()[0].result).toBe(MoveResult.OTHER); + + await passTurns(2); + + expect(enemy1.hp).toBeLessThan(enemy1.getMaxHp()); + expect(enemy2.hp).toBeLessThan(enemy2.getMaxHp()); + }); + + it("should trigger multiple pending attacks in order of creation, even if that order changes later on", async () => { + game.override.battleStyle("double"); + await game.classicMode.startBattle([SpeciesId.MAGIKARP, SpeciesId.FEEBAS]); + + const [alomomola, blissey] = game.scene.getField(); + + const oldOrder = game.field.getSpeedOrder(); + + game.move.use(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER, BattlerIndex.ENEMY); + game.move.use(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2); + await game.move.forceEnemyMove(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER); + await game.move.forceEnemyMove(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER_2); + // Ensure that the moves are used deterministically in speed order (for speed ties) + await game.setTurnOrder(oldOrder.map(p => p.getBattlerIndex())); + await game.toNextTurn(); + + expectFutureSightActive(4); + + // Lower speed to change turn order + alomomola.setStatStage(Stat.SPD, 6); + blissey.setStatStage(Stat.SPD, -6); + + const newOrder = game.field.getSpeedOrder(); + expect(newOrder).not.toEqual(oldOrder); + + await passTurns(2, false); + + // All attacks have concluded at this point, unshifting new `MoveEffectPhase`s to the queue. + expectFutureSightActive(0); + + const MEPs = game.scene.phaseManager.phaseQueue.filter(p => p.is("MoveEffectPhase")); + expect(MEPs).toHaveLength(4); + expect(MEPs.map(mep => mep.getPokemon())).toEqual(oldOrder); + }); + + it("should vanish silently if it would otherwise hit the user", async () => { + game.override.battleStyle("double"); + await game.classicMode.startBattle([SpeciesId.MAGIKARP, SpeciesId.FEEBAS, SpeciesId.MILOTIC]); + + const [karp, feebas, milotic] = game.scene.getPlayerParty(); + + game.move.use(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2); + game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER_2); + await game.toNextTurn(); + + expectFutureSightActive(1); + + // Milotic / Feebas // Karp + game.doSwitchPokemon(2); + game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER_2); + await game.toNextTurn(); + + expect(game.scene.getPlayerParty()).toEqual([milotic, feebas, karp]); + + // Milotic / Karp // Feebas + game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER); + game.doSwitchPokemon(2); + + await passTurns(1); + + expect(game.scene.getPlayerParty()).toEqual([milotic, karp, feebas]); + + expect(karp.hp).toBe(karp.getMaxHp()); + expect(feebas.hp).toBe(feebas.getMaxHp()); + expect(game.textInterceptor.logs).not.toContain( + i18next.t("moveTriggers:tookMoveAttack", { + pokemonName: getPokemonNameWithAffix(karp), + moveName: allMoves[MoveId.FUTURE_SIGHT].name, + }), + ); + }); + + it("should redirect normally if target is fainted when move is used", async () => { + game.override.battleStyle("double"); + await game.classicMode.startBattle([SpeciesId.MAGIKARP]); + + const [enemy1, enemy2] = game.scene.getEnemyField(); + + game.move.use(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2); + await game.killPokemon(enemy2); + await game.toNextTurn(); + + expect(enemy2.isFainted()).toBe(true); + expectFutureSightActive(); + + const attack = game.scene.arena.positionalTagManager.tags.find( + t => t.tagType === PositionalTagType.DELAYED_ATTACK, + )!; + expect(attack).toBeDefined(); + expect(attack.targetIndex).toBe(enemy1.getBattlerIndex()); + + await passTurns(2); + + expect(enemy1.hp).toBeLessThan(enemy1.getMaxHp()); + expect(game.textInterceptor.logs).toContain( + i18next.t("moveTriggers:tookMoveAttack", { + pokemonName: getPokemonNameWithAffix(enemy1), + moveName: allMoves[MoveId.FUTURE_SIGHT].name, + }), + ); + }); + + it("should vanish silently if slot is vacant when attack lands", async () => { + game.override.battleStyle("double"); + await game.classicMode.startBattle([SpeciesId.MAGIKARP]); + + const [enemy1, enemy2] = game.scene.getEnemyField(); + + game.move.use(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2); + await game.toNextTurn(); + + expectFutureSightActive(1); + + game.move.use(MoveId.SPLASH); + await game.killPokemon(enemy2); + await game.toNextTurn(); + + game.move.use(MoveId.SPLASH); + await game.toNextTurn(); + + expectFutureSightActive(0); + expect(enemy1.hp).toBe(enemy1.getMaxHp()); + expect(game.textInterceptor.logs).not.toContain( + i18next.t("moveTriggers:tookMoveAttack", { + pokemonName: getPokemonNameWithAffix(enemy1), + moveName: allMoves[MoveId.FUTURE_SIGHT].name, + }), + ); + }); + + it("should consider type changes at moment of execution while ignoring redirection", async () => { + game.override.battleStyle("double"); + await game.classicMode.startBattle([SpeciesId.MAGIKARP]); + + // fake left enemy having lightning rod + const [enemy1, enemy2] = game.scene.getEnemyField(); + game.field.mockAbility(enemy1, AbilityId.LIGHTNING_ROD); + + game.move.use(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2); + await game.toNextTurn(); + + expectFutureSightActive(1); + + game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER); + await game.toNextTurn(); + + game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER); + await game.move.forceEnemyMove(MoveId.ELECTRIFY, BattlerIndex.PLAYER); + await game.phaseInterceptor.to("PositionalTagPhase"); + await game.phaseInterceptor.to("MoveEffectPhase", false); + + // Wait until all normal attacks have triggered, then check pending MEP + const karp = game.field.getPlayerPokemon(); + const typeMock = vi.spyOn(karp, "getMoveType"); + + await game.toEndOfTurn(); + + expect(enemy1.hp).toBe(enemy1.getMaxHp()); + expect(enemy2.hp).toBeLessThan(enemy2.getMaxHp()); + expect(game.textInterceptor.logs).toContain( + i18next.t("moveTriggers:tookMoveAttack", { + pokemonName: getPokemonNameWithAffix(enemy2), + moveName: allMoves[MoveId.FUTURE_SIGHT].name, + }), + ); + expect(typeMock).toHaveLastReturnedWith(PokemonType.ELECTRIC); + }); + + // TODO: this is not implemented + it.todo("should not apply Shell Bell recovery, even if user is on field"); + + // TODO: Enable once code is added to MEP to do this + it.todo("should not apply the user's abilities when dealing damage if the user is inactive", async () => { + game.override.ability(AbilityId.NORMALIZE).enemySpecies(SpeciesId.LUNALA); + await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MILOTIC]); + + game.move.use(MoveId.DOOM_DESIRE); + await game.toNextTurn(); + + expectFutureSightActive(); + + await passTurns(1); + + game.doSwitchPokemon(1); + const typeMock = vi.spyOn(game.field.getPlayerPokemon(), "getMoveType"); + const powerMock = vi.spyOn(allMoves[MoveId.DOOM_DESIRE], "calculateBattlePower"); + + await game.toNextTurn(); + + // Player Normalize was not applied due to being off field + const enemy = game.field.getEnemyPokemon(); + expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); + expect(game.textInterceptor.logs).toContain( + i18next.t("moveTriggers:tookMoveAttack", { + pokemonName: getPokemonNameWithAffix(enemy), + moveName: allMoves[MoveId.DOOM_DESIRE].name, + }), + ); + expect(typeMock).toHaveLastReturnedWith(PokemonType.STEEL); + expect(powerMock).toHaveLastReturnedWith(150); + }); + + it.todo("should not apply the user's held items when dealing damage if the user is inactive", async () => { + game.override.startingHeldItems([{ name: "ATTACK_TYPE_BOOSTER", count: 99, type: PokemonType.PSYCHIC }]); + await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MILOTIC]); + + game.move.use(MoveId.FUTURE_SIGHT); + await game.toNextTurn(); + + expectFutureSightActive(); + + await passTurns(1); + + game.doSwitchPokemon(1); + + const powerMock = vi.spyOn(allMoves[MoveId.FUTURE_SIGHT], "calculateBattlePower"); + const typeBoostSpy = vi.spyOn(AttackTypeBoosterModifier.prototype, "apply"); + + await game.toNextTurn(); + + expect(powerMock).toHaveLastReturnedWith(120); + expect(typeBoostSpy).not.toHaveBeenCalled(); + }); + + // TODO: Implement and move to a power spot's test file + it.todo("Should activate ally's power spot when switched in during single battles"); +}); diff --git a/test/moves/future-sight.test.ts b/test/moves/future-sight.test.ts deleted file mode 100644 index 53e93412570..00000000000 --- a/test/moves/future-sight.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { AbilityId } from "#enums/ability-id"; -import { MoveId } from "#enums/move-id"; -import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/test-utils/game-manager"; -import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - -describe("Moves - Future Sight", () => { - 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 - .startingLevel(50) - .moveset([MoveId.FUTURE_SIGHT, MoveId.SPLASH]) - .battleStyle("single") - .enemySpecies(SpeciesId.MAGIKARP) - .enemyAbility(AbilityId.STURDY) - .enemyMoveset(MoveId.SPLASH); - }); - - it("hits 2 turns after use, ignores user switch out", async () => { - await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MILOTIC]); - - game.move.select(MoveId.FUTURE_SIGHT); - await game.toNextTurn(); - game.doSwitchPokemon(1); - await game.toNextTurn(); - game.move.select(MoveId.SPLASH); - await game.toNextTurn(); - - expect(game.scene.getEnemyPokemon()!.isFullHp()).toBe(false); - }); -}); diff --git a/test/moves/heal-block.test.ts b/test/moves/heal-block.test.ts index 4e4a9355467..fc814fda4bc 100644 --- a/test/moves/heal-block.test.ts +++ b/test/moves/heal-block.test.ts @@ -1,9 +1,8 @@ import { AbilityId } from "#enums/ability-id"; -import { ArenaTagSide } from "#enums/arena-tag-side"; -import { ArenaTagType } from "#enums/arena-tag-type"; import { BattlerIndex } from "#enums/battler-index"; import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; +import { PositionalTagType } from "#enums/positional-tag-type"; import { SpeciesId } from "#enums/species-id"; import { WeatherType } from "#enums/weather-type"; import { GameManager } from "#test/test-utils/game-manager"; @@ -68,22 +67,25 @@ describe("Moves - Heal Block", () => { expect(enemy.isFullHp()).toBe(false); }); - it("should stop delayed heals, such as from Wish", async () => { + it("should prevent Wish from restoring HP", async () => { await game.classicMode.startBattle([SpeciesId.CHARIZARD]); - const player = game.scene.getPlayerPokemon()!; + const player = game.field.getPlayerPokemon()!; - player.damageAndUpdate(player.getMaxHp() - 1); + player.hp = 1; - game.move.select(MoveId.WISH); - await game.phaseInterceptor.to("TurnEndPhase"); + game.move.use(MoveId.WISH); + await game.toNextTurn(); - expect(game.scene.arena.getTagOnSide(ArenaTagType.WISH, ArenaTagSide.PLAYER)).toBeDefined(); - while (game.scene.arena.getTagOnSide(ArenaTagType.WISH, ArenaTagSide.PLAYER)) { - game.move.select(MoveId.SPLASH); - await game.phaseInterceptor.to("TurnEndPhase"); - } + expect(game.scene.arena.positionalTagManager.tags.filter(t => t.tagType === PositionalTagType.WISH)) // + .toHaveLength(1); + game.move.use(MoveId.SPLASH); + await game.toNextTurn(); + + // wish triggered, but did NOT heal the player + expect(game.scene.arena.positionalTagManager.tags.filter(t => t.tagType === PositionalTagType.WISH)) // + .toHaveLength(0); expect(player.hp).toBe(1); }); diff --git a/test/moves/wish.test.ts b/test/moves/wish.test.ts new file mode 100644 index 00000000000..147c598106b --- /dev/null +++ b/test/moves/wish.test.ts @@ -0,0 +1,183 @@ +import { getPokemonNameWithAffix } from "#app/messages"; +import { AbilityId } from "#enums/ability-id"; +import { BattlerIndex } from "#enums/battler-index"; +import { MoveId } from "#enums/move-id"; +import { MoveResult } from "#enums/move-result"; +import { PositionalTagType } from "#enums/positional-tag-type"; +import { SpeciesId } from "#enums/species-id"; +import { Stat } from "#enums/stat"; +import { GameManager } from "#test/test-utils/game-manager"; +import { toDmgValue } from "#utils/common"; +import i18next from "i18next"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Move - Wish", () => { + 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 + .ability(AbilityId.BALL_FETCH) + .battleStyle("single") + .criticalHits(false) + .enemySpecies(SpeciesId.MAGIKARP) + .enemyAbility(AbilityId.BALL_FETCH) + .enemyMoveset(MoveId.SPLASH) + .startingLevel(100) + .enemyLevel(100); + }); + + /** + * Expect that wish is active with the specified number of attacks. + * @param numAttacks - The number of wish instances that should be queued; default `1` + */ + function expectWishActive(numAttacks = 1) { + const wishes = game.scene.arena.positionalTagManager["tags"].filter(t => t.tagType === PositionalTagType.WISH); + expect(wishes).toHaveLength(numAttacks); + } + + it("should heal the Pokemon in the current slot for 50% of the user's maximum HP", async () => { + await game.classicMode.startBattle([SpeciesId.ALOMOMOLA, SpeciesId.BLISSEY]); + + const [alomomola, blissey] = game.scene.getPlayerParty(); + alomomola.hp = 1; + blissey.hp = 1; + + game.move.use(MoveId.WISH); + await game.toNextTurn(); + + expectWishActive(); + + game.doSwitchPokemon(1); + await game.toEndOfTurn(); + + expectWishActive(0); + expect(game.textInterceptor.logs).toContain( + i18next.t("arenaTag:wishTagOnAdd", { + pokemonNameWithAffix: getPokemonNameWithAffix(alomomola), + }), + ); + expect(alomomola.hp).toBe(1); + expect(blissey.hp).toBe(toDmgValue(alomomola.getMaxHp() / 2) + 1); + }); + + it("should work if the user has full HP, but not if it already has an active Wish", async () => { + await game.classicMode.startBattle([SpeciesId.ALOMOMOLA, SpeciesId.BLISSEY]); + + const alomomola = game.field.getPlayerPokemon(); + alomomola.hp = 1; + + game.move.use(MoveId.WISH); + await game.toNextTurn(); + + expectWishActive(); + + game.move.use(MoveId.WISH); + await game.toEndOfTurn(); + + expect(alomomola.hp).toBe(toDmgValue(alomomola.getMaxHp() / 2) + 1); + expect(alomomola.getLastXMoves()[0].result).toBe(MoveResult.FAIL); + }); + + it("should function independently of Future Sight", async () => { + await game.classicMode.startBattle([SpeciesId.ALOMOMOLA, SpeciesId.BLISSEY]); + + const [alomomola, blissey] = game.scene.getPlayerParty(); + alomomola.hp = 1; + blissey.hp = 1; + + game.move.use(MoveId.WISH); + await game.move.forceEnemyMove(MoveId.FUTURE_SIGHT); + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.toNextTurn(); + + expectWishActive(1); + }); + + it("should work in double battles and trigger in order of creation", async () => { + game.override.battleStyle("double"); + await game.classicMode.startBattle([SpeciesId.ALOMOMOLA, SpeciesId.BLISSEY]); + + const [alomomola, blissey, karp1, karp2] = game.scene.getField(); + alomomola.hp = 1; + blissey.hp = 1; + + vi.spyOn(karp1, "getNameToRender").mockReturnValue("Karp 1"); + vi.spyOn(karp2, "getNameToRender").mockReturnValue("Karp 2"); + + const oldOrder = game.field.getSpeedOrder(); + + game.move.use(MoveId.WISH, BattlerIndex.PLAYER); + game.move.use(MoveId.WISH, BattlerIndex.PLAYER_2); + await game.move.forceEnemyMove(MoveId.WISH); + await game.move.forceEnemyMove(MoveId.WISH); + // Ensure that the wishes are used deterministically in speed order (for speed ties) + await game.setTurnOrder(oldOrder.map(p => p.getBattlerIndex())); + await game.toNextTurn(); + + expectWishActive(4); + + // Lower speed to change turn order + alomomola.setStatStage(Stat.SPD, 6); + blissey.setStatStage(Stat.SPD, -6); + + const newOrder = game.field.getSpeedOrder(); + expect(newOrder).not.toEqual(oldOrder); + + game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER); + game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER_2); + await game.phaseInterceptor.to("PositionalTagPhase"); + + // all wishes have activated and added healing phases + expectWishActive(0); + + const healPhases = game.scene.phaseManager.phaseQueue.filter(p => p.is("PokemonHealPhase")); + expect(healPhases).toHaveLength(4); + expect.soft(healPhases.map(php => php.getPokemon())).toEqual(oldOrder); + + await game.toEndOfTurn(); + + expect(alomomola.hp).toBe(toDmgValue(alomomola.getMaxHp() / 2) + 1); + expect(blissey.hp).toBe(toDmgValue(blissey.getMaxHp() / 2) + 1); + }); + + it("should vanish and not play message if slot is empty", async () => { + game.override.battleStyle("double"); + await game.classicMode.startBattle([SpeciesId.ALOMOMOLA, SpeciesId.BLISSEY]); + + const [alomomola, blissey] = game.scene.getPlayerParty(); + alomomola.hp = 1; + blissey.hp = 1; + + game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER); + game.move.use(MoveId.WISH, BattlerIndex.PLAYER_2); + await game.toNextTurn(); + + expectWishActive(); + + game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER); + game.move.use(MoveId.MEMENTO, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2); + await game.toEndOfTurn(); + + // Wish went away without doing anything + expectWishActive(0); + expect(game.textInterceptor.logs).not.toContain( + i18next.t("arenaTag:wishTagOnAdd", { + pokemonNameWithAffix: getPokemonNameWithAffix(blissey), + }), + ); + expect(alomomola.hp).toBe(1); + }); +}); diff --git a/test/test-utils/helpers/field-helper.ts b/test/test-utils/helpers/field-helper.ts index 35ca853d049..2d8fd8ee701 100644 --- a/test/test-utils/helpers/field-helper.ts +++ b/test/test-utils/helpers/field-helper.ts @@ -5,7 +5,6 @@ import type { globalScene } from "#app/global-scene"; import type { Ability } from "#abilities/ability"; import { allAbilities } from "#data/data-lists"; import type { AbilityId } from "#enums/ability-id"; -import type { BattlerIndex } from "#enums/battler-index"; import type { PokemonType } from "#enums/pokemon-type"; import { Stat } from "#enums/stat"; import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon"; @@ -45,18 +44,21 @@ export class FieldHelper extends GameManagerHelper { } /** - * @returns The {@linkcode BattlerIndex | indexes} of Pokemon on the field in order of decreasing Speed. + * Helper function to return all on-field {@linkcode Pokemon} in speed order (fastest first). + * @returns An array containing all {@linkcode Pokemon} on the field in order of descending Speed. * Speed ties are returned in increasing order of index. * * @remarks * This does not account for Trick Room as it does not modify the _speed_ of Pokemon on the field, * only their turn order. */ - public getSpeedOrder(): BattlerIndex[] { + public getSpeedOrder(): Pokemon[] { return this.game.scene .getField(true) - .sort((pA, pB) => pB.getEffectiveStat(Stat.SPD) - pA.getEffectiveStat(Stat.SPD)) - .map(p => p.getBattlerIndex()); + .sort( + (pA, pB) => + pB.getEffectiveStat(Stat.SPD) - pA.getEffectiveStat(Stat.SPD) || pA.getBattlerIndex() - pB.getBattlerIndex(), + ); } /** diff --git a/test/test-utils/helpers/move-helper.ts b/test/test-utils/helpers/move-helper.ts index 15605edf31d..041df916cbf 100644 --- a/test/test-utils/helpers/move-helper.ts +++ b/test/test-utils/helpers/move-helper.ts @@ -325,10 +325,16 @@ export class MoveHelper extends GameManagerHelper { } /** - * Force the move used by Metronome to be a specific move. - * @param move - The move to force metronome to use - * @param once - If `true`, uses {@linkcode MockInstance#mockReturnValueOnce} when mocking, else uses {@linkcode MockInstance#mockReturnValue}. + * Force the next move(s) used by Metronome to be a specific move. \ + * Triggers during the next upcoming {@linkcode MoveEffectPhase} that Metronome is used. + * @param move - The move to force Metronome to call + * @param once - If `true`, mocks the return value exactly once; default `false` * @returns The spy that for Metronome that was mocked (Usually unneeded). + * @example + * ```ts + * game.move.use(MoveId.METRONOME); + * game.move.forceMetronomeMove(MoveId.FUTURE_SIGHT); // Can be in any order + * ``` */ public forceMetronomeMove(move: MoveId, once = false): MockInstance { const spy = vi.spyOn(allMoves[MoveId.METRONOME].getAttrs("RandomMoveAttr")[0], "getMoveOverride"); diff --git a/test/test-utils/phase-interceptor.ts b/test/test-utils/phase-interceptor.ts index e0675a722f9..50de7e9f047 100644 --- a/test/test-utils/phase-interceptor.ts +++ b/test/test-utils/phase-interceptor.ts @@ -37,6 +37,7 @@ import { NextEncounterPhase } from "#phases/next-encounter-phase"; import { PartyExpPhase } from "#phases/party-exp-phase"; import { PartyHealPhase } from "#phases/party-heal-phase"; import { PokemonTransformPhase } from "#phases/pokemon-transform-phase"; +import { PositionalTagPhase } from "#phases/positional-tag-phase"; import { PostGameOverPhase } from "#phases/post-game-over-phase"; import { PostSummonPhase } from "#phases/post-summon-phase"; import { QuietFormChangePhase } from "#phases/quiet-form-change-phase"; @@ -142,6 +143,7 @@ export class PhaseInterceptor { [LevelCapPhase, this.startPhase], [AttemptRunPhase, this.startPhase], [SelectBiomePhase, this.startPhase], + [PositionalTagPhase, this.startPhase], [PokemonTransformPhase, this.startPhase], [MysteryEncounterPhase, this.startPhase], [MysteryEncounterOptionSelectedPhase, this.startPhase], diff --git a/test/types/positional-tags.test-d.ts b/test/types/positional-tags.test-d.ts new file mode 100644 index 00000000000..a75cc291764 --- /dev/null +++ b/test/types/positional-tags.test-d.ts @@ -0,0 +1,29 @@ +import type { SerializedPositionalTag, serializedPosTagMap } from "#data/positional-tags/load-positional-tag"; +import type { DelayedAttackTag, WishTag } from "#data/positional-tags/positional-tag"; +import type { PositionalTagType } from "#enums/positional-tag-type"; +import type { Mutable, NonFunctionPropertiesRecursive } from "#types/type-helpers"; +import { describe, expectTypeOf, it } from "vitest"; + +// Needed to get around properties being readonly in certain classes +type NonFunctionMutable = Mutable>; + +describe("serializedPositionalTagMap", () => { + it("should contain representations of each tag's serialized form", () => { + expectTypeOf().branded.toEqualTypeOf< + NonFunctionMutable + >(); + expectTypeOf().branded.toEqualTypeOf>(); + }); +}); + +describe("SerializedPositionalTag", () => { + it("should accept a union of all serialized tag forms", () => { + expectTypeOf().branded.toEqualTypeOf< + NonFunctionMutable | NonFunctionMutable + >(); + }); + it("should accept a union of all unserialized tag forms", () => { + expectTypeOf().toExtend(); + expectTypeOf().toExtend(); + }); +}); From 8b304adf1400af77fc40ff6030e905eab82d069a Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Thu, 31 Jul 2025 02:27:54 -0400 Subject: [PATCH 55/76] [Refactor] Added `PhaseManager.toTitleScreen` (#6114) * Added `toTitlePhase`; documented phase manager * Documented phase methods * Fixed syntax errors + updated signature * Reverted all the goodies * Fixed missing shift phase call GHAG * Reverted change --- src/battle-scene.ts | 7 ++----- src/enums/dynamic-phase-type.ts | 3 ++- src/phase-manager.ts | 15 +++++++++++++++ src/phases/select-starter-phase.ts | 7 ++++--- src/phases/title-phase.ts | 11 ++++++----- src/ui/challenges-select-ui-handler.ts | 3 +-- src/ui/starter-select-ui-handler.ts | 16 +++++++++------- test/test-utils/game-manager.ts | 5 +---- 8 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 275f129a63a..9af954c3852 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -657,9 +657,7 @@ export class BattleScene extends SceneBase { ).then(() => loadMoveAnimAssets(defaultMoves, true)), this.initStarterColors(), ]).then(() => { - this.phaseManager.pushNew("LoginPhase"); - this.phaseManager.pushNew("TitlePhase"); - + this.phaseManager.toTitleScreen(true); this.phaseManager.shiftPhase(); }); } @@ -1269,13 +1267,12 @@ export class BattleScene extends SceneBase { duration: 250, ease: "Sine.easeInOut", onComplete: () => { - this.phaseManager.clearPhaseQueue(); - this.ui.freeUIData(); this.uiContainer.remove(this.ui, true); this.uiContainer.destroy(); this.children.removeAll(true); this.game.domContainer.innerHTML = ""; + // TODO: `launchBattle` calls `reset(false, false, true)` this.launchBattle(); }, }); diff --git a/src/enums/dynamic-phase-type.ts b/src/enums/dynamic-phase-type.ts index a34ac371668..b9ea6bf197d 100644 --- a/src/enums/dynamic-phase-type.ts +++ b/src/enums/dynamic-phase-type.ts @@ -1,6 +1,7 @@ /** - * Enum representation of the phase types held by implementations of {@linkcode PhasePriorityQueue} + * Enum representation of the phase types held by implementations of {@linkcode PhasePriorityQueue}. */ +// TODO: We currently assume these are in order export enum DynamicPhaseType { POST_SUMMON } diff --git a/src/phase-manager.ts b/src/phase-manager.ts index 37edeae7e42..850f0c564ea 100644 --- a/src/phase-manager.ts +++ b/src/phase-manager.ts @@ -244,6 +244,21 @@ export class PhaseManager { this.dynamicPhaseTypes = [PostSummonPhase]; } + /** + * Clear all previously set phases, then add a new {@linkcode TitlePhase} to transition to the title screen. + * @param addLogin - Whether to add a new {@linkcode LoginPhase} before the {@linkcode TitlePhase} + * (but reset everything else). + * Default `false` + */ + public toTitleScreen(addLogin = false): void { + this.clearAllPhases(); + + if (addLogin) { + this.unshiftNew("LoginPhase"); + } + this.unshiftNew("TitlePhase"); + } + /* Phase Functions */ getCurrentPhase(): Phase | null { return this.currentPhase; diff --git a/src/phases/select-starter-phase.ts b/src/phases/select-starter-phase.ts index af056ebb4ee..6456bacd0e3 100644 --- a/src/phases/select-starter-phase.ts +++ b/src/phases/select-starter-phase.ts @@ -24,10 +24,11 @@ export class SelectStarterPhase extends Phase { globalScene.ui.setMode(UiMode.STARTER_SELECT, (starters: Starter[]) => { globalScene.ui.clearText(); globalScene.ui.setMode(UiMode.SAVE_SLOT, SaveSlotUiMode.SAVE, (slotId: number) => { + // If clicking cancel, back out to title screen if (slotId === -1) { - globalScene.phaseManager.clearPhaseQueue(); - globalScene.phaseManager.pushNew("TitlePhase"); - return this.end(); + globalScene.phaseManager.toTitleScreen(); + this.end(); + return; } globalScene.sessionSlotId = slotId; this.initBattle(starters); diff --git a/src/phases/title-phase.ts b/src/phases/title-phase.ts index 38e3ff3a017..6f0493f707d 100644 --- a/src/phases/title-phase.ts +++ b/src/phases/title-phase.ts @@ -114,11 +114,11 @@ export class TitlePhase extends Phase { }); } } + // Cancel button = back to title options.push({ label: i18next.t("menu:cancel"), handler: () => { - globalScene.phaseManager.clearPhaseQueue(); - globalScene.phaseManager.pushNew("TitlePhase"); + globalScene.phaseManager.toTitleScreen(); super.end(); return true; }, @@ -191,11 +191,12 @@ export class TitlePhase extends Phase { initDailyRun(): void { globalScene.ui.clearText(); globalScene.ui.setMode(UiMode.SAVE_SLOT, SaveSlotUiMode.SAVE, (slotId: number) => { - globalScene.phaseManager.clearPhaseQueue(); if (slotId === -1) { - globalScene.phaseManager.pushNew("TitlePhase"); - return super.end(); + globalScene.phaseManager.toTitleScreen(); + super.end(); + return; } + globalScene.phaseManager.clearPhaseQueue(); globalScene.sessionSlotId = slotId; const generateDaily = (seed: string) => { diff --git a/src/ui/challenges-select-ui-handler.ts b/src/ui/challenges-select-ui-handler.ts index 4f205d59de8..4a7ab7641a3 100644 --- a/src/ui/challenges-select-ui-handler.ts +++ b/src/ui/challenges-select-ui-handler.ts @@ -382,8 +382,7 @@ export class GameChallengesUiHandler extends UiHandler { this.cursorObj?.setVisible(true); this.updateChallengeArrows(this.startCursor.visible); } else { - globalScene.phaseManager.clearPhaseQueue(); - globalScene.phaseManager.pushNew("TitlePhase"); + globalScene.phaseManager.toTitleScreen(); globalScene.phaseManager.getCurrentPhase()?.end(); } success = true; diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index e8f9b5e1c38..974f24e706f 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -4303,7 +4303,10 @@ export class StarterSelectUiHandler extends MessageUiHandler { return true; } - tryExit(): boolean { + /** + * Attempt to back out of the starter selection screen into the appropriate parent modal + */ + tryExit(): void { this.blockInput = true; const ui = this.getUi(); @@ -4317,12 +4320,13 @@ export class StarterSelectUiHandler extends MessageUiHandler { UiMode.CONFIRM, () => { ui.setMode(UiMode.STARTER_SELECT); - globalScene.phaseManager.clearPhaseQueue(); - if (globalScene.gameMode.isChallenge) { + // Non-challenge modes go directly back to title, while challenge modes go to the selection screen. + if (!globalScene.gameMode.isChallenge) { + globalScene.phaseManager.toTitleScreen(); + } else { + globalScene.phaseManager.clearPhaseQueue(); globalScene.phaseManager.pushNew("SelectChallengePhase"); globalScene.phaseManager.pushNew("EncounterPhase"); - } else { - globalScene.phaseManager.pushNew("TitlePhase"); } this.clearText(); globalScene.phaseManager.getCurrentPhase()?.end(); @@ -4333,8 +4337,6 @@ export class StarterSelectUiHandler extends MessageUiHandler { 19, ); }); - - return true; } tryStart(manualTrigger = false): boolean { diff --git a/test/test-utils/game-manager.ts b/test/test-utils/game-manager.ts index b81b077b2f2..23a2e6240f8 100644 --- a/test/test-utils/game-manager.ts +++ b/test/test-utils/game-manager.ts @@ -103,12 +103,9 @@ export class GameManager { if (!firstTimeScene) { this.scene.reset(false, true); (this.scene.ui.handlers[UiMode.STARTER_SELECT] as StarterSelectUiHandler).clearStarterPreferences(); - this.scene.phaseManager.clearAllPhases(); // Must be run after phase interceptor has been initialized. - - this.scene.phaseManager.pushNew("LoginPhase"); - this.scene.phaseManager.pushNew("TitlePhase"); + this.scene.phaseManager.toTitleScreen(true); this.scene.phaseManager.shiftPhase(); this.gameWrapper.scene = this.scene; From 75ececd942a439660b4670bef1b16388183c9cf1 Mon Sep 17 00:00:00 2001 From: Tiago Rodrigues Date: Thu, 31 Jul 2025 21:14:51 +0100 Subject: [PATCH 56/76] [UI/UX] Implement Discard Button (#5985) * [feature]Implemented needed parts for discard function from issue #4780: -TryDiscardFunction in battlescene; -Created a party discard mode button; -Updated Transfer button in modifier-select-ui-handler to Manage items; -Created tests for the discard function in test/ui; -Added images for the new discard and transfer buttons to loading-scene; -Created placeholder messages for discard feature in party-ui-handler; Co-authored-by: Tiago Rodrigues * [Fix] Updated icon for dynamic messaging * [Fix] Corrected legacy mode icons and adjusted double-battle button location * [Fix]Adjusted button positioning and mapping after review. Mapping requires debugging. * [Fix] Fixed visible pokeball in legacy mode and key mapping * [Fix] Background fixes,manage menu is the only one affected by changes now * Implement i18n keys * [Fix] implemented most code optimizations and callbacks to the modified locales folder * [Fix] Implemented 3 suggestions * [Fix]improved/corrected test structure Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * [Fix] added functionality test for the discard button * [Fix] added necessary comment Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> * [Fix] Implemented suggested changes in test/discard text prompt * [Fix] Implemented UI suggestions and removed discard text confirmation * [Fix] added missing imports * Fix imports in test file * [Fix] Implemented suggested cursor behavior and reworked test code * [Fix] Corrected failed test * [Fix] atempting to fix the test timeout issue * [Fix] Undoing latest attempt * [Fix] Implemented suggestions to fix broken tests * Reviews * [Fix] replaced icon images * [Fix] Updated jsons to match new icons and removed pokeball icon from legacy mode * Optimized new images * [Fix] Fixed referenced bug and added similar confirmation box to release * [Fix] Updated tests to handle the corfirmation box * [Fix] Added back the accidentally removed changes * [Fix]updated incorrect import path * [fix] add description for the manageItemMode function Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> * Update src/ui/party-ui-handler.ts Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> * [Fix] corrected formating issue --------- Co-authored-by: Mikhail Shueb Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> Co-authored-by: damocleas Co-authored-by: Bertie690 Co-authored-by: Adri1 --- .../ui/legacy/party_bg_double_manage.png | Bin 0 -> 431 bytes public/images/ui/legacy/party_discard.json | 62 ++++ public/images/ui/legacy/party_discard.png | Bin 0 -> 346 bytes public/images/ui/legacy/party_transfer.json | 62 ++++ public/images/ui/legacy/party_transfer.png | Bin 0 -> 366 bytes public/images/ui/party_bg_double_manage.png | Bin 0 -> 837 bytes public/images/ui/party_discard.json | 62 ++++ public/images/ui/party_discard.png | Bin 0 -> 386 bytes public/images/ui/party_transfer.json | 62 ++++ public/images/ui/party_transfer.png | Bin 0 -> 403 bytes src/battle-scene.ts | 17 + src/loading-scene.ts | 3 + src/ui/modifier-select-ui-handler.ts | 6 +- src/ui/party-ui-handler.ts | 305 ++++++++++++++++-- test/ui/item-manage-button.test.ts | 172 ++++++++++ 15 files changed, 726 insertions(+), 25 deletions(-) create mode 100644 public/images/ui/legacy/party_bg_double_manage.png create mode 100644 public/images/ui/legacy/party_discard.json create mode 100644 public/images/ui/legacy/party_discard.png create mode 100644 public/images/ui/legacy/party_transfer.json create mode 100644 public/images/ui/legacy/party_transfer.png create mode 100644 public/images/ui/party_bg_double_manage.png create mode 100644 public/images/ui/party_discard.json create mode 100644 public/images/ui/party_discard.png create mode 100644 public/images/ui/party_transfer.json create mode 100644 public/images/ui/party_transfer.png create mode 100644 test/ui/item-manage-button.test.ts diff --git a/public/images/ui/legacy/party_bg_double_manage.png b/public/images/ui/legacy/party_bg_double_manage.png new file mode 100644 index 0000000000000000000000000000000000000000..2bf2d63c3154c6f6f28101d351899c3170753130 GIT binary patch literal 431 zcmeAS@N?(olHy`uVBq!ia0y~yU~~Yox3Dk+N%2!Jlz@~_fKQ04hetv}1VhIRjSU+j zPF$#X@S?*b=ny|pd4#8nV@O3@Qh?Nxge#3I4T0=^RsoU+_T9bh!o!*nOL7kyWVeXD&{?48nhv#qhU|MW}uTI4_ tb@7<(Q=06hADPGYS`}PrT+GM95V7FIR?(B*mcSTb@O1TaS?83{1OS1sq`m+E literal 0 HcmV?d00001 diff --git a/public/images/ui/legacy/party_discard.json b/public/images/ui/legacy/party_discard.json new file mode 100644 index 00000000000..4aa563fcd77 --- /dev/null +++ b/public/images/ui/legacy/party_discard.json @@ -0,0 +1,62 @@ +{ + "textures": [ + { + "image": "party_discard.png", + "format": "RGBA8888", + "size": { + "w": 75, + "h": 50 + }, + "scale": 1, + "frames": [ + { + "filename": "normal", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 75, + "h": 25 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 75, + "h": 25 + }, + "frame": { + "x": 0, + "y": 0, + "w": 75, + "h": 25 + } + }, + { + "filename": "selected", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 75, + "h": 25 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 75, + "h": 25 + }, + "frame": { + "x": 0, + "y": 25, + "w": 75, + "h": 25 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:17219773dfffd6b1204d988fea3f9462:1127ad21d64bc7ebb9df4fc28f3d2d39:7ad46e8fb4648c3d3d84a746ecb371ea$" + } +} diff --git a/public/images/ui/legacy/party_discard.png b/public/images/ui/legacy/party_discard.png new file mode 100644 index 0000000000000000000000000000000000000000..d95ba6960152815beb50ca60c39624525d694622 GIT binary patch literal 346 zcmeAS@N?(olHy`uVBq!ia0vp^-au@`!VDyz`C4B9QqloFA+A8$!y};}V#8FQiUkE9 zHYIM^X>WfdsNzR~LDCoZOrSJlNswPKgTu2MX+X|fPZ!6KinzU#4f&c4cwAo|li0!N z`ifD)!ZFa2L8w~$Da+bTX$cQ*94)kYcANRpdH?^X|CPCBO^^|EO7zp1yW4ctrpRjc zQ)NDt{1(%VI3<25T?>5Gd&aH)Mew%AXYQ%$2`_uoHU+ohq^|Dx4vhH4J>gKncQ{K+tVk|IB z724qAnzQW6tTWdNUW5aU)>P328Jz|*T0HT7@CILy(FTnWqsw001%s0{{R3=1n`$0000RP)t-s0000A z@3s)BmOz1{NJwB+u+wl@u%K}8_;4_OM|0i)0004WQchCyU5JW2wSOhr_$$dZtx}vE^;i17J2$gm1XP1}TRL<_xFEf|S-UaT88-{D)nHBM> zyNiWAR)NJ~NzmwA*Ch+>Noz&eHS4(2xpckPO6RpZ8ANN*I>_^&HA|a&N8@eCgVHea zLSXM`OP)KB8hB~8m3kX%Rex>n#R_a{+8{O!T}braXmtty1&CM>u;8nBhb%m^B3}J< zv9Qk}usAFU8lA_nC!xJ)tqB{Gjw_ve(|WCRj?Kv=T8q{|+9s`8+SWQ6Z$qAxhLLsx zTSwc|)_~N&OS7%i+gPjqYg;Q;U{lj3v1#Z+qW4CtOZYE9!~);?0S@8G#sK zXvnGQD=I1~X&Gy3Y8qHL8X6j!7`R%Pcv@OoIypIcx<-0=c?AUpMMXs=CnrzLKDC#D zf$5;9i(^Q|t+#jY_FXm*V7uV(LZIoi*n_|Gr*=1mX#HZIY_hF*-|VcX-S6aX-aR4b z-~MsV;q}*lzIxvL@%Lk9g$4#jCKi?g?E{DB&*cA}{6{Nofhv!Hf`bD$quZInb0v>W z&F@(!OexZOE|b6K*|EjW2YxCoziM1Q{j{V+>RZVOuj}4FL>rb@{NY~rU2@NZA88G$ za*W4zz2ASKB8M$v+3$wHSqy({1VAqKXrj*2Iu>gZoA447&556?_@df#&x#TwlC3ZC(0c! zoO5{LrTteu@(cBDAKm$(Hq1;XRZF7W@O3re@0pMlI)k#!bfcYRAmHajDjDvbhR^|6J zf1UJ7n)$=Q3Wk`kJ}e6!DK)%ezRDhT2o&5PW8E9xaqrg8;q3qA@qUNfE-Q!HCFM*j z`oDa7eu&{K{}uZSLTo@~4zNJroIdyK#C1#aeKyxFSq-%JZQM`(+9krKm$rWC&D{Ob zkKxb%Uk>+;=B(ylvpC=9wRgqmeTK3OWnbBWwq39|aQzCqS>*ii;MxU}X`IYJ2Lya> z$o)R?p4^77c9(v!r~UTGw_&z^q0Afb-3*)}BEC$#=6(z6hHaarm~z&*?K-t+cQE(P zNco6^Go4SHUgGPWa|#qj7cMtUI>Yao`a^Fe&wZ7t4_7ZS+T*EpSR5##vyx{%P-O8E vqnZgJZQmzx0ps1;^JrdI2NayB`y{-Z-FxlHe76_C{J`Mp>gTe~DWM4f{^n*n literal 0 HcmV?d00001 diff --git a/public/images/ui/party_discard.json b/public/images/ui/party_discard.json new file mode 100644 index 00000000000..4aa563fcd77 --- /dev/null +++ b/public/images/ui/party_discard.json @@ -0,0 +1,62 @@ +{ + "textures": [ + { + "image": "party_discard.png", + "format": "RGBA8888", + "size": { + "w": 75, + "h": 50 + }, + "scale": 1, + "frames": [ + { + "filename": "normal", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 75, + "h": 25 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 75, + "h": 25 + }, + "frame": { + "x": 0, + "y": 0, + "w": 75, + "h": 25 + } + }, + { + "filename": "selected", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 75, + "h": 25 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 75, + "h": 25 + }, + "frame": { + "x": 0, + "y": 25, + "w": 75, + "h": 25 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:17219773dfffd6b1204d988fea3f9462:1127ad21d64bc7ebb9df4fc28f3d2d39:7ad46e8fb4648c3d3d84a746ecb371ea$" + } +} diff --git a/public/images/ui/party_discard.png b/public/images/ui/party_discard.png new file mode 100644 index 0000000000000000000000000000000000000000..e56c845eadccfb9462418fa7c67996915e793d40 GIT binary patch literal 386 zcmV-|0e$|7P)001%s0{{R3=1n`$0000dP)t-s00008 zT8s#cwILxXIXO~hR)TYLgn2wkoSdz#&epjR*P_;X9!G-PkFWl(aN~a zFF_a-4bh4KT17)NUIEbpP&7oFSmRBRZJD%h&YE%!Bjp;x;s3ULrb(k4f~td}+4jx4 gy~bOxUY7Ar|BwSDE^sg}CjbBd07*qoM6N<$f{o9q?EnA( literal 0 HcmV?d00001 diff --git a/public/images/ui/party_transfer.json b/public/images/ui/party_transfer.json new file mode 100644 index 00000000000..7cfcf5ccc30 --- /dev/null +++ b/public/images/ui/party_transfer.json @@ -0,0 +1,62 @@ +{ + "textures": [ + { + "image": "party_transfer.png", + "format": "RGBA8888", + "size": { + "w": 75, + "h": 50 + }, + "scale": 1, + "frames": [ + { + "filename": "normal", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 75, + "h": 25 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 75, + "h": 25 + }, + "frame": { + "x": 0, + "y": 0, + "w": 75, + "h": 25 + } + }, + { + "filename": "selected", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 75, + "h": 25 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 75, + "h": 25 + }, + "frame": { + "x": 0, + "y": 25, + "w": 75, + "h": 25 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:17219773dfffd6b1204d988fea3f9462:1127ad21d64bc7ebb9df4fc28f3d2d39:7ad46e8fb4648c3d3d84a746ecb371ea$" + } +} diff --git a/public/images/ui/party_transfer.png b/public/images/ui/party_transfer.png new file mode 100644 index 0000000000000000000000000000000000000000..45815a156b5a97589eee9d390fcf242f16862a39 GIT binary patch literal 403 zcmV;E0c`$>P)001%s0{{R3=1n`$0000dP)t-s00008 zT8s#cwF#x63h%ZMsg@xjDJ5}qIXO~ubA+6nt*y@1|NsB4BSDG)0004WQchC>zWWkSeKMRky!inK$sX415(GDDK{9D=5T9(R{oRhE$v-rtT}O`=&f~C?S{shz zNohPBcxJJq1GG^W)PyS_6trt!4C5gOYdceaK}hZ;0?8}6-VpFJrMr+t2@YGWKR zCuJPzyDvAyyKnyOMV!R@vb^sUtRxFqzmF(*QHzpE%cJ;YPHp{KCMI)eNP8w8E#8xK zE44f>la11tmR6 0) { + return true; + } + + return this.removeModifier(itemModifier); + } canTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, transferQuantity = 1): boolean { const mod = itemModifier.clone() as PokemonHeldItemModifier; diff --git a/src/loading-scene.ts b/src/loading-scene.ts index 706ea01a16a..c5b0263e785 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -119,6 +119,7 @@ export class LoadingScene extends SceneBase { this.loadImage("party_bg", "ui"); this.loadImage("party_bg_double", "ui"); + this.loadImage("party_bg_double_manage", "ui"); this.loadAtlas("party_slot_main", "ui"); this.loadAtlas("party_slot", "ui"); this.loadImage("party_slot_overlay_lv", "ui"); @@ -126,6 +127,8 @@ export class LoadingScene extends SceneBase { this.loadAtlas("party_slot_hp_overlay", "ui"); this.loadAtlas("party_pb", "ui"); this.loadAtlas("party_cancel", "ui"); + this.loadAtlas("party_discard", "ui"); + this.loadAtlas("party_transfer", "ui"); this.loadImage("summary_bg", "ui"); this.loadImage("summary_overlay_shiny", "ui"); diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index 50d88738d32..16eecf6993d 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -69,7 +69,7 @@ export class ModifierSelectUiHandler extends AwaitableUiHandler { if (context) { context.font = styleOptions.fontSize + "px " + styleOptions.fontFamily; - this.transferButtonWidth = context.measureText(i18next.t("modifierSelectUiHandler:transfer")).width; + this.transferButtonWidth = context.measureText(i18next.t("modifierSelectUiHandler:manageItems")).width; this.checkButtonWidth = context.measureText(i18next.t("modifierSelectUiHandler:checkTeam")).width; } @@ -81,7 +81,7 @@ export class ModifierSelectUiHandler extends AwaitableUiHandler { this.transferButtonContainer.setVisible(false); ui.add(this.transferButtonContainer); - const transferButtonText = addTextObject(-4, -2, i18next.t("modifierSelectUiHandler:transfer"), TextStyle.PARTY); + const transferButtonText = addTextObject(-4, -2, i18next.t("modifierSelectUiHandler:manageItems"), TextStyle.PARTY); transferButtonText.setName("text-transfer-btn"); transferButtonText.setOrigin(1, 0); this.transferButtonContainer.add(transferButtonText); @@ -601,7 +601,7 @@ export class ModifierSelectUiHandler extends AwaitableUiHandler { (globalScene.game.canvas.width - this.transferButtonWidth - this.checkButtonWidth) / 6 - 30, OPTION_BUTTON_YPOSITION + 4, ); - ui.showText(i18next.t("modifierSelectUiHandler:transferDesc")); + ui.showText(i18next.t("modifierSelectUiHandler:manageItemsDesc")); } else if (cursor === 2) { this.cursorObj.setPosition( (globalScene.game.canvas.width - this.checkButtonWidth) / 6 - 10, diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 915cc76fd73..b259316f6fa 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -103,6 +103,11 @@ export enum PartyUiMode { * This is generally used in for Mystery Encounter or special effects that require the player to select a Pokemon */ SELECT, + /** + * Indicates that the party UI is open to select a party member from which items will be discarded. + * This type of selection can be cancelled. + */ + DISCARD, } export enum PartyOption { @@ -121,6 +126,7 @@ export enum PartyOption { RELEASE, RENAME, SELECT, + DISCARD, SCROLL_UP = 1000, SCROLL_DOWN = 1001, FORM_CHANGE_ITEM = 2000, @@ -155,6 +161,7 @@ export class PartyUiHandler extends MessageUiHandler { private partySlotsContainer: Phaser.GameObjects.Container; private partySlots: PartySlot[]; private partyCancelButton: PartyCancelButton; + private partyDiscardModeButton: PartyDiscardModeButton; private partyMessageBox: Phaser.GameObjects.NineSlice; private moveInfoOverlay: MoveInfoOverlay; @@ -180,6 +187,8 @@ export class PartyUiHandler extends MessageUiHandler { private transferAll: boolean; private lastCursor = 0; + private lastLeftPokemonCursor = 0; + private lastRightPokemonCursor = 0; private selectCallback: PartySelectCallback | PartyModifierTransferSelectCallback | null; private selectFilter: PokemonSelectFilter | PokemonModifierTransferSelectFilter; private moveSelectFilter: PokemonMoveSelectFilter; @@ -308,6 +317,12 @@ export class PartyUiHandler extends MessageUiHandler { this.iconAnimHandler = new PokemonIconAnimHandler(); this.iconAnimHandler.setup(); + const partyDiscardModeButton = new PartyDiscardModeButton(60, -globalScene.game.canvas.height / 15 - 1, this); + + partyContainer.add(partyDiscardModeButton); + + this.partyDiscardModeButton = partyDiscardModeButton; + // prepare move overlay. in case it appears to be too big, set the overlayScale to .5 const overlayScale = 1; this.moveInfoOverlay = new MoveInfoOverlay({ @@ -349,8 +364,18 @@ export class PartyUiHandler extends MessageUiHandler { this.showMovePp = args.length > 6 && args[6]; this.partyContainer.setVisible(true); - this.partyBg.setTexture(`party_bg${globalScene.currentBattle.double ? "_double" : ""}`); + if (this.isItemManageMode()) { + this.partyBg.setTexture(`party_bg${globalScene.currentBattle.double ? "_double_manage" : ""}`); + } else { + this.partyBg.setTexture(`party_bg${globalScene.currentBattle.double ? "_double" : ""}`); + } + this.populatePartySlots(); + // If we are currently transferring items, set the icon to its proper state and reveal the button. + if (this.isItemManageMode()) { + this.partyDiscardModeButton.toggleIcon(this.partyUiMode as PartyUiMode.MODIFIER_TRANSFER | PartyUiMode.DISCARD); + } + this.showPartyText(); this.setCursor(0); return true; @@ -595,7 +620,7 @@ export class PartyUiHandler extends MessageUiHandler { const option = this.options[this.optionsCursor]; if (button === Button.LEFT) { /** Decrease quantity for the current item and update UI */ - if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { + if (this.isItemManageMode()) { this.transferQuantities[option] = this.transferQuantities[option] === 1 ? this.transferQuantitiesMax[option] @@ -609,7 +634,7 @@ export class PartyUiHandler extends MessageUiHandler { if (button === Button.RIGHT) { /** Increase quantity for the current item and update UI */ - if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { + if (this.isItemManageMode()) { this.transferQuantities[option] = this.transferQuantities[option] === this.transferQuantitiesMax[option] ? 1 @@ -639,6 +664,45 @@ export class PartyUiHandler extends MessageUiHandler { return success; } + private processDiscardMenuInput(pokemon: PlayerPokemon) { + const ui = this.getUi(); + const option = this.options[this.optionsCursor]; + this.clearOptions(); + + this.blockInput = true; + this.showText(i18next.t("partyUiHandler:discardConfirmation"), null, () => { + this.blockInput = false; + ui.setModeWithoutClear( + UiMode.CONFIRM, + () => { + ui.setMode(UiMode.PARTY); + this.doDiscard(option, pokemon); + }, + () => { + ui.setMode(UiMode.PARTY); + this.showPartyText(); + }, + ); + }); + + return true; + } + + private doDiscard(option: PartyOption, pokemon: PlayerPokemon) { + const itemModifiers = this.getTransferrableItemsFromPokemon(pokemon); + this.clearOptions(); + + if (option === PartyOption.ALL) { + // Discard all currently held items + for (let i = 0; i < itemModifiers.length; i++) { + globalScene.tryDiscardHeldItemModifier(itemModifiers[i], this.transferQuantities[i]); + } + } else { + // Discard the currently selected item + globalScene.tryDiscardHeldItemModifier(itemModifiers[option], this.transferQuantities[option]); + } + } + private moveOptionCursor(button: Button.UP | Button.DOWN): boolean { if (button === Button.UP) { return this.setCursor(this.optionsCursor ? this.optionsCursor - 1 : this.options.length - 1); @@ -725,6 +789,10 @@ export class PartyUiHandler extends MessageUiHandler { return this.processModifierTransferModeInput(pokemon); } + if (this.partyUiMode === PartyUiMode.DISCARD) { + return this.processDiscardMenuInput(pokemon); + } + // options specific to the mode (moves) if (this.partyUiMode === PartyUiMode.REMEMBER_MOVE_MODIFIER) { return this.processRememberMoveModeInput(pokemon); @@ -864,7 +932,7 @@ export class PartyUiHandler extends MessageUiHandler { } if (button === Button.LEFT || button === Button.RIGHT) { - if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { + if (this.isItemManageMode()) { return this.processModifierTransferModeLeftRightInput(button); } } @@ -919,10 +987,22 @@ export class PartyUiHandler extends MessageUiHandler { return !(this.partyUiMode === PartyUiMode.FAINT_SWITCH || this.partyUiMode === PartyUiMode.REVIVAL_BLESSING); } + /** + * Return whether this UI handler is responsible for managing items. + * Used to ensure proper placement of mode toggle buttons in the UI, etc. + * @returns Whether the current handler is responsible for managing items. + */ + private isItemManageMode(): boolean { + return this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER || this.partyUiMode === PartyUiMode.DISCARD; + } + private processPartyActionInput(): boolean { const ui = this.getUi(); if (this.cursor < 6) { - if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && !this.transferMode) { + if ( + (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && !this.transferMode) || + this.partyUiMode === PartyUiMode.DISCARD + ) { /** Initialize item quantities for the selected Pokemon */ const itemModifiers = globalScene.findModifiers( m => @@ -936,6 +1016,25 @@ export class PartyUiHandler extends MessageUiHandler { this.showOptions(); ui.playSelect(); } + + // Toggle item transfer mode to discard items or vice versa + if (this.cursor === 7) { + switch (this.partyUiMode) { + case PartyUiMode.DISCARD: + this.partyUiMode = PartyUiMode.MODIFIER_TRANSFER; + break; + case PartyUiMode.MODIFIER_TRANSFER: + this.partyUiMode = PartyUiMode.DISCARD; + break; + default: + ui.playError(); + return false; + } + this.partyDiscardModeButton.toggleIcon(this.partyUiMode); + ui.playSelect(); + return true; + } + // Pressing return button if (this.cursor === 6) { if (!this.allowCancel()) { @@ -956,6 +1055,7 @@ export class PartyUiHandler extends MessageUiHandler { this.clearTransfer(); ui.playSelect(); } else if (this.allowCancel()) { + this.partyDiscardModeButton.clear(); if (this.selectCallback) { const selectCallback = this.selectCallback; this.selectCallback = null; @@ -974,30 +1074,74 @@ export class PartyUiHandler extends MessageUiHandler { const slotCount = this.partySlots.length; const battlerCount = globalScene.currentBattle.getBattlerCount(); + if (this.lastCursor < battlerCount) { + this.lastLeftPokemonCursor = this.lastCursor; + } + if (this.lastCursor >= battlerCount && this.lastCursor < 6) { + this.lastRightPokemonCursor = this.lastCursor; + } + let success = false; switch (button) { + // Item manage mode adds an extra 8th "toggle mode" button to the UI, located *below* both active party members. + // The following logic serves to ensure its menu behaviour matches its in-game position, + // being selected when scrolling up from the first inactive party member or down from the last active one. case Button.UP: + if (this.isItemManageMode()) { + if (this.cursor === 1) { + success = this.setCursor(globalScene.currentBattle.double ? 0 : 7); + break; + } + if (this.cursor === 2) { + success = this.setCursor(globalScene.currentBattle.double ? 7 : 1); + break; + } + if (this.cursor === 6) { + success = this.setCursor(slotCount <= globalScene.currentBattle.getBattlerCount() ? 7 : slotCount - 1); + break; + } + if (this.cursor === 7) { + success = this.setCursor(globalScene.currentBattle.double && slotCount > 1 ? 1 : 0); + break; + } + } success = this.setCursor(this.cursor ? (this.cursor < 6 ? this.cursor - 1 : slotCount - 1) : 6); break; case Button.DOWN: + if (this.isItemManageMode()) { + if (this.cursor === 0) { + success = this.setCursor(globalScene.currentBattle.double && slotCount > 1 ? 1 : 7); + break; + } + if (this.cursor === 1) { + success = this.setCursor(globalScene.currentBattle.double ? 7 : slotCount > 2 ? 2 : 6); + break; + } + if (this.cursor === 7) { + success = this.setCursor( + slotCount > globalScene.currentBattle.getBattlerCount() ? globalScene.currentBattle.getBattlerCount() : 6, + ); + break; + } + } success = this.setCursor(this.cursor < 6 ? (this.cursor < slotCount - 1 ? this.cursor + 1 : 6) : 0); break; case Button.LEFT: - if (this.cursor >= battlerCount && this.cursor <= 6) { - success = this.setCursor(0); + if (this.cursor === 6) { + success = this.setCursor(this.isItemManageMode() ? 7 : this.lastLeftPokemonCursor); + } + if (this.cursor >= battlerCount && this.cursor < 6) { + success = this.setCursor(this.lastLeftPokemonCursor); } break; case Button.RIGHT: - if (slotCount === battlerCount) { + // Scrolling right from item transfer button or with no backup party members goes to cancel + if (this.cursor === 7 || slotCount <= battlerCount) { success = this.setCursor(6); break; } - if (battlerCount >= 2 && slotCount > battlerCount && this.getCursor() === 0 && this.lastCursor === 1) { - success = this.setCursor(2); - break; - } - if (slotCount > battlerCount && this.cursor < battlerCount) { - success = this.setCursor(this.lastCursor < 6 ? this.lastCursor || battlerCount : battlerCount); + if (this.cursor < battlerCount) { + success = this.setCursor(this.lastRightPokemonCursor || battlerCount); break; } } @@ -1044,11 +1188,15 @@ export class PartyUiHandler extends MessageUiHandler { this.partySlots[this.lastCursor].deselect(); } else if (this.lastCursor === 6) { this.partyCancelButton.deselect(); + } else if (this.lastCursor === 7) { + this.partyDiscardModeButton.deselect(); } if (cursor < 6) { this.partySlots[cursor].select(); } else if (cursor === 6) { this.partyCancelButton.select(); + } else if (cursor === 7) { + this.partyDiscardModeButton.select(); } } return changed; @@ -1143,14 +1291,16 @@ export class PartyUiHandler extends MessageUiHandler { optionsMessage = i18next.t("partyUiHandler:selectAnotherPokemonToSplice"); } break; + case PartyUiMode.DISCARD: + optionsMessage = i18next.t("partyUiHandler:changeQuantityDiscard"); } this.showText(optionsMessage, 0); this.updateOptions(); - /** When an item is being selected for transfer, the message box is taller as the message occupies two lines */ - if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { + /** When an item is being selected for transfer or discard, the message box is taller as the message occupies two lines */ + if (this.isItemManageMode()) { this.partyMessageBox.setSize(262 - Math.max(this.optionsBg.displayWidth - 56, 0), 42); } else { this.partyMessageBox.setSize(262 - Math.max(this.optionsBg.displayWidth - 56, 0), 30); @@ -1159,6 +1309,20 @@ export class PartyUiHandler extends MessageUiHandler { this.setCursor(0); } + showPartyText() { + switch (this.partyUiMode) { + case PartyUiMode.MODIFIER_TRANSFER: + this.showText(i18next.t("partyUiHandler:partyTransfer")); + break; + case PartyUiMode.DISCARD: + this.showText(i18next.t("partyUiHandler:partyDiscard")); + break; + default: + this.showText("", 0); + break; + } + } + private allowBatonModifierSwitch(): boolean { return !!( this.partyUiMode !== PartyUiMode.FAINT_SWITCH && @@ -1276,6 +1440,9 @@ export class PartyUiHandler extends MessageUiHandler { this.addCommonOptions(pokemon); } break; + case PartyUiMode.DISCARD: + this.updateOptionsWithModifierTransferMode(pokemon); + break; // TODO: This still needs to be broken up. // It could use a rework differentiating different kind of switches // to treat baton passing separately from switching on faint. @@ -1381,7 +1548,8 @@ export class PartyUiHandler extends MessageUiHandler { optionName = "↓"; } else if ( (this.partyUiMode !== PartyUiMode.REMEMBER_MOVE_MODIFIER && - (this.partyUiMode !== PartyUiMode.MODIFIER_TRANSFER || this.transferMode)) || + (this.partyUiMode !== PartyUiMode.MODIFIER_TRANSFER || this.transferMode) && + this.partyUiMode !== PartyUiMode.DISCARD) || option === PartyOption.CANCEL ) { switch (option) { @@ -1444,7 +1612,7 @@ export class PartyUiHandler extends MessageUiHandler { const itemModifiers = this.getItemModifiers(pokemon); const itemModifier = itemModifiers[option]; if ( - this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && + this.isItemManageMode() && this.transferQuantitiesMax[option] > 1 && !this.transferMode && itemModifier !== undefined && @@ -1474,7 +1642,6 @@ export class PartyUiHandler extends MessageUiHandler { optionText.x = 15 - this.optionsBg.width; } } - startTransfer(): void { this.transferMode = true; this.transferCursor = this.cursor; @@ -1608,7 +1775,7 @@ export class PartyUiHandler extends MessageUiHandler { this.eraseOptionsCursor(); this.partyMessageBox.setSize(262, 30); - this.showText("", 0); + this.showPartyText(); } eraseOptionsCursor() { @@ -1663,7 +1830,9 @@ class PartySlot extends Phaser.GameObjects.Container { ? -184 + (globalScene.currentBattle.double ? -40 : 0) + (28 + (globalScene.currentBattle.double ? 8 : 0)) * slotIndex - : -124 + (globalScene.currentBattle.double ? -8 : 0) + slotIndex * 64, + : partyUiMode === PartyUiMode.MODIFIER_TRANSFER + ? -124 + (globalScene.currentBattle.double ? -20 : 0) + slotIndex * 55 + : -124 + (globalScene.currentBattle.double ? -8 : 0) + slotIndex * 64, ); this.slotIndex = slotIndex; @@ -1918,7 +2087,6 @@ class PartySlot extends Phaser.GameObjects.Container { class PartyCancelButton extends Phaser.GameObjects.Container { private selected: boolean; - private partyCancelBg: Phaser.GameObjects.Sprite; private partyCancelPb: Phaser.GameObjects.Sprite; @@ -1965,3 +2133,96 @@ class PartyCancelButton extends Phaser.GameObjects.Container { this.partyCancelPb.setFrame("party_pb"); } } + +class PartyDiscardModeButton extends Phaser.GameObjects.Container { + private selected: boolean; + private transferIcon: Phaser.GameObjects.Sprite; + private discardIcon: Phaser.GameObjects.Sprite; + private textBox: Phaser.GameObjects.Text; + private party: PartyUiHandler; + + constructor(x: number, y: number, party: PartyUiHandler) { + super(globalScene, x, y); + + this.setup(party); + } + + setup(party: PartyUiHandler) { + this.transferIcon = globalScene.add.sprite(0, 0, "party_transfer"); + this.discardIcon = globalScene.add.sprite(0, 0, "party_discard"); + this.textBox = addTextObject(-8, -7, i18next.t("partyUiHandler:TRANSFER"), TextStyle.PARTY); + this.party = party; + + this.add(this.transferIcon); + this.add(this.discardIcon); + this.add(this.textBox); + + this.clear(); + } + + select() { + if (this.selected) { + return; + } + + this.selected = true; + + this.party.showText(i18next.t("partyUiHandler:changeMode")); + + this.transferIcon.setFrame("selected"); + this.discardIcon.setFrame("selected"); + } + + deselect() { + if (!this.selected) { + return; + } + + this.selected = false; + this.party.showPartyText(); + + this.transferIcon.setFrame("normal"); + this.discardIcon.setFrame("normal"); + } + + /** + * If the current mode deals with transferring items, toggle the discard items button's name and assets. + * @param partyMode - The current {@linkcode PartyUiMode} + * @remarks + * This will also reveal the button if it is currently hidden. + */ + public toggleIcon(partyMode: PartyUiMode.MODIFIER_TRANSFER | PartyUiMode.DISCARD): void { + this.setActive(true).setVisible(true); + switch (partyMode) { + case PartyUiMode.MODIFIER_TRANSFER: + this.transferIcon.setVisible(true); + this.discardIcon.setVisible(false); + this.textBox.setVisible(true); + this.textBox.setText(i18next.t("partyUiHandler:TRANSFER")); + this.setPosition( + globalScene.currentBattle.double ? 64 : 60, + globalScene.currentBattle.double ? -48 : -globalScene.game.canvas.height / 15 - 1, + ); + this.transferIcon.displayWidth = this.textBox.text.length * 9 + 3; + break; + case PartyUiMode.DISCARD: + this.transferIcon.setVisible(false); + this.discardIcon.setVisible(true); + this.textBox.setVisible(true); + this.textBox.setText(i18next.t("partyUiHandler:DISCARD")); + this.setPosition( + globalScene.currentBattle.double ? 64 : 60, + globalScene.currentBattle.double ? -48 : -globalScene.game.canvas.height / 15 - 1, + ); + this.discardIcon.displayWidth = this.textBox.text.length * 9 + 3; + break; + } + } + + clear() { + this.setActive(false).setVisible(false); + this.transferIcon.setVisible(false); + this.discardIcon.setVisible(false); + this.textBox.setVisible(false); + } +} diff --git a/test/ui/item-manage-button.test.ts b/test/ui/item-manage-button.test.ts new file mode 100644 index 00000000000..a7ea76918a5 --- /dev/null +++ b/test/ui/item-manage-button.test.ts @@ -0,0 +1,172 @@ +import { BerryType } from "#enums/berry-type"; +import { Button } from "#enums/buttons"; +import { MoveId } from "#enums/move-id"; +import { SpeciesId } from "#enums/species-id"; +import { UiMode } from "#enums/ui-mode"; +import type { Pokemon } from "#field/pokemon"; +import { GameManager } from "#test/test-utils/game-manager"; +import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; +import type { PartyUiHandler } from "#ui/party-ui-handler"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("UI - Transfer Items", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(async () => { + game = new GameManager(phaserGame); + game.override + .battleStyle("single") + .startingLevel(100) + .startingHeldItems([ + { name: "BERRY", count: 1, type: BerryType.SITRUS }, + { name: "BERRY", count: 2, type: BerryType.APICOT }, + { name: "BERRY", count: 2, type: BerryType.LUM }, + ]) + .enemySpecies(SpeciesId.MAGIKARP) + .enemyMoveset(MoveId.SPLASH); + + await game.classicMode.startBattle([SpeciesId.RAYQUAZA, SpeciesId.RAYQUAZA, SpeciesId.RAYQUAZA]); + + game.move.use(MoveId.DRAGON_CLAW); + + await game.phaseInterceptor.to("SelectModifierPhase"); + }); + + it("manage button exists in the proper screen", async () => { + let handlerLength: Phaser.GameObjects.GameObject[] | undefined; + + await new Promise(resolve => { + //select manage items menu + game.onNextPrompt("SelectModifierPhase", UiMode.MODIFIER_SELECT, async () => { + await new Promise(r => setTimeout(r, 100)); + const handler = game.scene.ui.getHandler() as ModifierSelectUiHandler; + + handler.processInput(Button.DOWN); + handler.setCursor(1); + handler.processInput(Button.ACTION); + }); + + game.onNextPrompt("SelectModifierPhase", UiMode.PARTY, async () => { + await new Promise(r => setTimeout(r, 100)); + const handler = game.scene.ui.getHandler() as PartyUiHandler; + + handler.processInput(Button.DOWN); + handler.processInput(Button.ACTION); + handlerLength = handler.optionsContainer.list; + + handler.processInput(Button.CANCEL); + + resolve(); + }); + }); + + expect(handlerLength).toHaveLength(0); // should select manage button, which has no menu + }); + + it("manage button doesn't exist in the other screens", async () => { + let handlerLength: Phaser.GameObjects.GameObject[] | undefined; + + await new Promise(resolve => { + game.onNextPrompt("SelectModifierPhase", UiMode.MODIFIER_SELECT, async () => { + await new Promise(r => setTimeout(r, 100)); + const handler = game.scene.ui.getHandler() as ModifierSelectUiHandler; + + handler.processInput(Button.DOWN); + handler.setCursor(2); + handler.processInput(Button.ACTION); + }); + + game.onNextPrompt("SelectModifierPhase", UiMode.PARTY, async () => { + await new Promise(r => setTimeout(r, 100)); + const handler = game.scene.ui.getHandler() as PartyUiHandler; + + handler.processInput(Button.DOWN); + handler.processInput(Button.ACTION); + handlerLength = handler.optionsContainer.list; + + handler.processInput(Button.CANCEL); + handler.processInput(Button.CANCEL); + + resolve(); + }); + }); + + expect(handlerLength).toHaveLength(6); // should select 2nd pokemon (length is 5 options + image) + }); + + // Test that the manage button actually discards items, needs proofreading + it("should discard items when button is selected", async () => { + let pokemon: Pokemon | undefined; + + await new Promise(resolve => { + game.onNextPrompt("SelectModifierPhase", UiMode.MODIFIER_SELECT, async () => { + await new Promise(r => setTimeout(r, 100)); + const handler = game.scene.ui.getHandler() as ModifierSelectUiHandler; + + handler.processInput(Button.DOWN); + handler.setCursor(1); + handler.processInput(Button.ACTION); + }); + game.onNextPrompt("SelectModifierPhase", UiMode.PARTY, async () => { + await new Promise(r => setTimeout(r, 100)); + const handler = game.scene.ui.getHandler() as PartyUiHandler; + + // Enter discard mode and select first party member + handler.setCursor(7); + handler.processInput(Button.ACTION); + handler.setCursor(0); + handler.processInput(Button.ACTION); + pokemon = game.field.getPlayerPokemon(); + + resolve(); + }); + }); + + expect(pokemon).toBeDefined(); + if (pokemon) { + expect(pokemon.getHeldItems()).toHaveLength(3); + expect(pokemon.getHeldItems().map(h => h.stackCount)).toEqual([1, 2, 2]); + } + + await new Promise(resolve => { + game.onNextPrompt("SelectModifierPhase", UiMode.PARTY, async () => { + await new Promise(r => setTimeout(r, 100)); + const handler = game.scene.ui.getHandler() as PartyUiHandler; + handler.processInput(Button.ACTION); + resolve(); + }); + }); + + await new Promise(resolve => { + game.onNextPrompt("SelectModifierPhase", UiMode.PARTY, async () => { + await new Promise(r => setTimeout(r, 100)); + const handler = game.scene.ui.getHandler() as PartyUiHandler; + handler.processInput(Button.ACTION); + + pokemon = game.field.getPlayerPokemon(); + + handler.processInput(Button.CANCEL); + resolve(); + }); + }); + + expect(pokemon).toBeDefined(); + if (pokemon) { + // Sitrus berry was discarded, leaving 2 stacks of 2 berries behind + expect(pokemon.getHeldItems()).toHaveLength(2); + expect(pokemon.getHeldItems().map(h => h.stackCount)).toEqual([2, 2]); + } + }); +}); From 901f6a6812d77e0ae0bfc5883f690dd62b47d047 Mon Sep 17 00:00:00 2001 From: Acelynn Zhang <102631387+acelynnzhang@users.noreply.github.com> Date: Thu, 31 Jul 2025 16:18:11 -0400 Subject: [PATCH 57/76] [Bug] Fix Truant behavior (#6171) --- src/data/battler-tags.ts | 2 +- test/abilities/truant.test.ts | 72 +++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 test/abilities/truant.test.ts diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index e21065c184f..f3cfe4e7d99 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2038,7 +2038,7 @@ export class TruantTag extends AbilityBattlerTag { const lastMove = pokemon.getLastXMoves()[0]; - if (!lastMove) { + if (!lastMove || lastMove.move === MoveId.NONE) { // Don't interrupt move if last move was `Moves.NONE` OR no prior move was found return true; } diff --git a/test/abilities/truant.test.ts b/test/abilities/truant.test.ts new file mode 100644 index 00000000000..0d71cd393b0 --- /dev/null +++ b/test/abilities/truant.test.ts @@ -0,0 +1,72 @@ +import { getPokemonNameWithAffix } from "#app/messages"; +import { AbilityId } from "#enums/ability-id"; +import { MoveId } from "#enums/move-id"; +import { MoveResult } from "#enums/move-result"; +import { SpeciesId } from "#enums/species-id"; +import { GameManager } from "#test/test-utils/game-manager"; +import i18next from "i18next"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Ability - Truant", () => { + 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 + .battleStyle("single") + .criticalHits(false) + .moveset([MoveId.SPLASH, MoveId.TACKLE]) + .ability(AbilityId.TRUANT) + .enemySpecies(SpeciesId.MAGIKARP) + .enemyAbility(AbilityId.BALL_FETCH) + .enemyMoveset(MoveId.SPLASH); + }); + + it("should loaf around and prevent using moves every other turn", async () => { + await game.classicMode.startBattle([SpeciesId.FEEBAS]); + + const player = game.field.getPlayerPokemon(); + const enemy = game.field.getEnemyPokemon(); + + // Turn 1: Splash succeeds + game.move.select(MoveId.SPLASH); + await game.toNextTurn(); + + expect(player.getLastXMoves(1)[0]).toEqual( + expect.objectContaining({ move: MoveId.SPLASH, result: MoveResult.SUCCESS }), + ); + + // Turn 2: Truant activates, cancelling tackle and displaying message + game.move.select(MoveId.TACKLE); + await game.toNextTurn(); + + expect(player.getLastXMoves(1)[0]).toEqual(expect.objectContaining({ move: MoveId.NONE, result: MoveResult.FAIL })); + expect(enemy.hp).toBe(enemy.getMaxHp()); + expect(game.textInterceptor.logs).toContain( + i18next.t("battlerTags:truantLapse", { + pokemonNameWithAffix: getPokemonNameWithAffix(player), + }), + ); + + // Turn 3: Truant didn't activate, tackle worked + game.move.select(MoveId.TACKLE); + await game.toNextTurn(); + + expect(player.getLastXMoves(1)[0]).toEqual( + expect.objectContaining({ move: MoveId.TACKLE, result: MoveResult.SUCCESS }), + ); + expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); + }); +}); From c3b6e9e6b515120cd452ffc092717e22b7ca175b Mon Sep 17 00:00:00 2001 From: damocleas Date: Thu, 31 Jul 2025 17:07:48 -0400 Subject: [PATCH 58/76] Update locales --- public/locales | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales b/public/locales index e2fbba17ea7..5784dda3ac3 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit e2fbba17ea7a96068970ea98a8a84ed3e25b6f07 +Subproject commit 5784dda3ac3aff7f84878888ce8f6ed5443bfd88 From 12433b78e5d11af423276f7bc6a5af6234de4582 Mon Sep 17 00:00:00 2001 From: Lugiad Date: Fri, 1 Aug 2025 00:13:05 +0200 Subject: [PATCH 59/76] [i18n] Add Tagalog language support (#6170) --- public/images/statuses_tl.json | 188 ++++++++ public/images/statuses_tl.png | Bin 0 -> 419 bytes public/images/types_tl.json | 440 ++++++++++++++++++ public/images/types_tl.png | Bin 0 -> 1861 bytes public/locales | 2 +- src/plugins/i18n.ts | 5 +- src/system/settings/settings.ts | 4 + .../settings/settings-display-ui-handler.ts | 6 + src/ui/starter-select-ui-handler.ts | 4 + src/utils/common.ts | 1 + 10 files changed, 647 insertions(+), 3 deletions(-) create mode 100644 public/images/statuses_tl.json create mode 100644 public/images/statuses_tl.png create mode 100644 public/images/types_tl.json create mode 100644 public/images/types_tl.png diff --git a/public/images/statuses_tl.json b/public/images/statuses_tl.json new file mode 100644 index 00000000000..094b0188d69 --- /dev/null +++ b/public/images/statuses_tl.json @@ -0,0 +1,188 @@ +{ + "textures": [ + { + "image": "statuses_tl.png", + "format": "RGBA8888", + "size": { + "w": 22, + "h": 64 + }, + "scale": 1, + "frames": [ + { + "filename": "pokerus", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 22, + "h": 8 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 22, + "h": 8 + }, + "frame": { + "x": 0, + "y": 0, + "w": 22, + "h": 8 + } + }, + { + "filename": "burn", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 20, + "h": 8 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 20, + "h": 8 + }, + "frame": { + "x": 0, + "y": 8, + "w": 20, + "h": 8 + } + }, + { + "filename": "faint", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 20, + "h": 8 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 20, + "h": 8 + }, + "frame": { + "x": 0, + "y": 16, + "w": 20, + "h": 8 + } + }, + { + "filename": "freeze", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 20, + "h": 8 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 20, + "h": 8 + }, + "frame": { + "x": 0, + "y": 24, + "w": 20, + "h": 8 + } + }, + { + "filename": "paralysis", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 20, + "h": 8 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 20, + "h": 8 + }, + "frame": { + "x": 0, + "y": 32, + "w": 20, + "h": 8 + } + }, + { + "filename": "poison", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 20, + "h": 8 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 20, + "h": 8 + }, + "frame": { + "x": 0, + "y": 40, + "w": 20, + "h": 8 + } + }, + { + "filename": "sleep", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 20, + "h": 8 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 20, + "h": 8 + }, + "frame": { + "x": 0, + "y": 48, + "w": 20, + "h": 8 + } + }, + { + "filename": "toxic", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 20, + "h": 8 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 20, + "h": 8 + }, + "frame": { + "x": 0, + "y": 56, + "w": 20, + "h": 8 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:37686e85605d17b806f22d43081c1139:70535ffee63ba61b3397d8470c2c8982:e6649238c018d3630e55681417c698ca$" + } +} diff --git a/public/images/statuses_tl.png b/public/images/statuses_tl.png new file mode 100644 index 0000000000000000000000000000000000000000..9f24c6a0810ebd6ca4ecbc752e77f3ec43243352 GIT binary patch literal 419 zcmV;U0bKrxP)==ukM|a8Nin zUPJ%@00eYWPE!B?006U-W|{y10T@X{K~#8Nt<&3%!!QU0P|{BB?Oy)>XLlHZ&|-O? z77^o|xPexx+5R!aE(Jiy3b+%Xj0#nYQ;qgTfCQL zafK2f0dh0#$wV#g)>xQK^Mo53x0k48NVYV23+eOq)#CLeyMieJv6KQ@%*&1 zc+zq{psja{H5E#zKyFk5IS_=#cjI^f_s%l$&{Dk42ejj}#SsdC0B9HPz^sMvH^=9p zT`{kI`WX3`4>ofVQ12wp0KoSh%Enl@*`= z#hX}t{ql925BM0r&Vx+71Q&}ke{ZqmViJnwBiH%j#A3B%w3d?re*h(mIE1ye$|wK; N002ovPDHLkV1kAS!6N_w literal 0 HcmV?d00001 diff --git a/public/images/types_tl.json b/public/images/types_tl.json new file mode 100644 index 00000000000..2706c6f49f3 --- /dev/null +++ b/public/images/types_tl.json @@ -0,0 +1,440 @@ +{ + "textures": [ + { + "image": "types_tl.png", + "format": "RGBA8888", + "size": { + "w": 32, + "h": 280 + }, + "scale": 1, + "frames": [ + { + "filename": "unknown", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + } + }, + { + "filename": "bug", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 14, + "w": 32, + "h": 14 + } + }, + { + "filename": "dark", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 28, + "w": 32, + "h": 14 + } + }, + { + "filename": "dragon", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 42, + "w": 32, + "h": 14 + } + }, + { + "filename": "electric", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 56, + "w": 32, + "h": 14 + } + }, + { + "filename": "fairy", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 70, + "w": 32, + "h": 14 + } + }, + { + "filename": "fighting", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 84, + "w": 32, + "h": 14 + } + }, + { + "filename": "fire", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 98, + "w": 32, + "h": 14 + } + }, + { + "filename": "flying", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 112, + "w": 32, + "h": 14 + } + }, + { + "filename": "ghost", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 126, + "w": 32, + "h": 14 + } + }, + { + "filename": "grass", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 140, + "w": 32, + "h": 14 + } + }, + { + "filename": "ground", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 154, + "w": 32, + "h": 14 + } + }, + { + "filename": "ice", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 168, + "w": 32, + "h": 14 + } + }, + { + "filename": "normal", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 182, + "w": 32, + "h": 14 + } + }, + { + "filename": "poison", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 196, + "w": 32, + "h": 14 + } + }, + { + "filename": "psychic", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 210, + "w": 32, + "h": 14 + } + }, + { + "filename": "rock", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 224, + "w": 32, + "h": 14 + } + }, + { + "filename": "steel", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 238, + "w": 32, + "h": 14 + } + }, + { + "filename": "water", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 252, + "w": 32, + "h": 14 + } + }, + { + "filename": "stellar", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 266, + "w": 32, + "h": 14 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:f14cf47d9a8f1d40c8e03aa6ba00fff3:6fc4227b57a95d429a1faad4280f7ec8:5961efbfbf4c56b8745347e7a663a32f$" + } +} diff --git a/public/images/types_tl.png b/public/images/types_tl.png new file mode 100644 index 0000000000000000000000000000000000000000..b9fdceba7da236067f326c6ae0411d21ecc3aca6 GIT binary patch literal 1861 zcmV-L2fFx)P)w(#bTLPPF?g0TJzF&)W;aGAIh_AGV0S+vJ3(AuL^4fDElo&gWl5En=CyV`H^s7$9UM5@tAf zXfp?BNC0zCdw3yLdq{hG&Qg3B7=fm~gQZ%LLCcg-i=3_ZrBXSqrIfCEJG%e2y`@^c z!T-L{sLQ$k%;5jcUA@h+O4#N9<<_9+;Q#5mjP5u}?o}!8L3!_R@9&lW^z+{JL&|9_&Ef3f1>&ZhtW|NsBSF=(KWb6QHX@AnA+000DZQchC<00029lV+L#00qrS zL_t(|Uc8T4Zp1JQLy4Ia%3Ee_d;e3EQDO*g1@^BG6l22=F$_EJ z?G(5z?pX06tFX(bu$AHmzFvhwg+tYglL*_qBK?D(%@g1LeuZC?y~5c%oVg7_fue?r*X5*;aT1UVdHqv4afmw?wAuLy9LSD@IiV(Quc+FP~!iq1) z%R}K0Ftjj$Ap!7~@ccva220|CRpuz0Yc5iuGUmgCz|CTvix75sy~0TThsYw(h$|u? zxU)|#)av0Z2|nI_&{UEwux5ir$@|wkLwHc4G?+ zig8MPS%4RY2L>>#0Nky(f3v!SVMQQ%nw5_1LXCi&I?Y#IIf2~iXLV%(+G)E2!6=~j zKR}(JuP`SncqZck^iD6aJ_&fCd!Pf|3c$A&_n%hZU|2nXh{84-=emXXsh zphc4_7C0=&>X(12zI;N6P*7pr$LtP+TW zzTzB%4{HIa1z^era9RMq@_OQ5fFrU(tDGJH+jN$OoG!o%hX)Seu=?S9jFB4(VIaC` zD5z@eEv=gpbe^Cg$Oo3MW}c^8JsC;)*M0uKfdG65l+Cfvp})o>5o{#beGmyIBJyU!{C0bI;6y~PT@xEa?SuKz01D1$&&`XtCQ6$q*ZWr+%P z+wQPjCc>41l0%K>w#APfXQ#qdMB4=gGDF=v$|zLTVlr7ws;Vl>*=*Lf7zMRd!Np%{~g5QHxY$a-t%-rTob~bzRE`&F;ShLE)A900000NkvXXu0mjf9426$ literal 0 HcmV?d00001 diff --git a/public/locales b/public/locales index 5784dda3ac3..7898c0018a7 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit 5784dda3ac3aff7f84878888ce8f6ed5443bfd88 +Subproject commit 7898c0018a70601a6ead76c9dd497ff966cc2e2a diff --git a/src/plugins/i18n.ts b/src/plugins/i18n.ts index 89946b2691b..62fc73a10a3 100644 --- a/src/plugins/i18n.ts +++ b/src/plugins/i18n.ts @@ -79,13 +79,13 @@ const fonts: Array = [ face: new FontFace("emerald", "url(./fonts/pokemon-bw.ttf)", { unicodeRange: rangesByLanguage.japanese, }), - only: ["en", "es", "fr", "it", "de", "pt", "ko", "ja", "ca", "da", "tr", "ro", "ru"], + only: ["en", "es", "fr", "it", "de", "pt", "ko", "ja", "ca", "da", "tr", "ro", "ru", "tl"], }, { face: new FontFace("pkmnems", "url(./fonts/pokemon-bw.ttf)", { unicodeRange: rangesByLanguage.japanese, }), - only: ["en", "es", "fr", "it", "de", "pt", "ko", "ja", "ca", "da", "tr", "ro", "ru"], + only: ["en", "es", "fr", "it", "de", "pt", "ko", "ja", "ca", "da", "tr", "ro", "ru", "tl"], }, ]; @@ -191,6 +191,7 @@ export async function initI18n(): Promise { "tr", "ro", "ru", + "tl", ], backend: { loadPath(lng: string, [ns]: string[]) { diff --git a/src/system/settings/settings.ts b/src/system/settings/settings.ts index 33087f2509e..32d9e0ee2be 100644 --- a/src/system/settings/settings.ts +++ b/src/system/settings/settings.ts @@ -981,6 +981,10 @@ export function setSetting(setting: string, value: number): boolean { label: "Română (Needs Help)", handler: () => changeLocaleHandler("ro"), }, + { + label: "Tagalog (Needs Help)", + handler: () => changeLocaleHandler("tl"), + }, { label: i18next.t("settings:back"), handler: () => cancelHandler(), diff --git a/src/ui/settings/settings-display-ui-handler.ts b/src/ui/settings/settings-display-ui-handler.ts index 3c261d6ddab..1a0481b8e8d 100644 --- a/src/ui/settings/settings-display-ui-handler.ts +++ b/src/ui/settings/settings-display-ui-handler.ts @@ -117,6 +117,12 @@ export class SettingsDisplayUiHandler extends AbstractSettingsUiHandler { label: "Română (Needs Help)", }; break; + case "tl": + this.settings[languageIndex].options[0] = { + value: "Tagalog", + label: "Tagalog (Needs Help)", + }; + break; default: this.settings[languageIndex].options[0] = { value: "English", diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 974f24e706f..6929d6f818d 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -176,6 +176,10 @@ const languageSettings: { [key: string]: LanguageSetting } = { starterInfoYOffset: 0.5, starterInfoXPos: 26, }, + tl: { + starterInfoTextSize: "56px", + instructionTextSize: "38px", + }, }; const valueReductionMax = 2; diff --git a/src/utils/common.ts b/src/utils/common.ts index 66a74ed2c33..1c75dac93b4 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -436,6 +436,7 @@ export function hasAllLocalizedSprites(lang?: string): boolean { case "ja": case "ca": case "ru": + case "tl": return true; default: return false; From 6204a6fdcb18f6a78d7a72511eb4e28841a71ac4 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Thu, 31 Jul 2025 17:44:03 -0600 Subject: [PATCH 60/76] [Bug] [Beta] Fix serializable battler tags (#6183) Fix serializable battler tags --- src/data/arena-tag.ts | 5 ++++- src/data/battler-tags.ts | 8 ++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index 9f2a5e09667..34477d737b4 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -1659,7 +1659,10 @@ export function getArenaTag( * @param source - An arena tag * @returns The valid arena tag */ -export function loadArenaTag(source: ArenaTag | ArenaTagTypeData): ArenaTag { +export function loadArenaTag(source: ArenaTag | ArenaTagTypeData | { tagType: ArenaTagType.NONE }): ArenaTag { + if (source.tagType === ArenaTagType.NONE) { + return new NoneTag(); + } const tag = getArenaTag(source.tagType, source.turnCount, source.sourceMove, source.sourceId, source.side) ?? new NoneTag(); tag.loadTag(source); diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index f3cfe4e7d99..a1ed535e1d1 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -201,7 +201,7 @@ export class BattlerTag implements BaseBattlerTag { } } -export abstract class SerializableBattlerTag extends BattlerTag { +export class SerializableBattlerTag extends BattlerTag { /** Nonexistent, dummy field to allow typescript to distinguish this class from `BattlerTag` */ private declare __SerializableBattlerTag: never; } @@ -3641,7 +3641,7 @@ export function getBattlerTag( case BattlerTagType.FRENZY: return new FrenzyTag(turnCount, sourceMove, sourceId); case BattlerTagType.CHARGING: - return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, 1, sourceMove, sourceId); + return new SerializableBattlerTag(tagType, BattlerTagLapseType.CUSTOM, 1, sourceMove, sourceId); case BattlerTagType.ENCORE: return new EncoreTag(sourceId); case BattlerTagType.HELPING_HAND: @@ -3726,10 +3726,10 @@ export function getBattlerTag( return new DragonCheerTag(); case BattlerTagType.ALWAYS_CRIT: case BattlerTagType.IGNORE_ACCURACY: - return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, 2, sourceMove); + return new SerializableBattlerTag(tagType, BattlerTagLapseType.TURN_END, 2, sourceMove); case BattlerTagType.ALWAYS_GET_HIT: case BattlerTagType.RECEIVE_DOUBLE_DAMAGE: - return new BattlerTag(tagType, BattlerTagLapseType.PRE_MOVE, 1, sourceMove); + return new SerializableBattlerTag(tagType, BattlerTagLapseType.PRE_MOVE, 1, sourceMove); case BattlerTagType.BYPASS_SLEEP: return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, turnCount, sourceMove); case BattlerTagType.IGNORE_FLYING: From 4dd6eb4e954d58735a7009eac959eb6349ae5a31 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Thu, 31 Jul 2025 17:57:53 -0600 Subject: [PATCH 61/76] [Misc] [Beta] Fix serializable battler tags (#6184) Fix serializable battler tags --- src/data/battler-tags.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index a1ed535e1d1..8805d671f8e 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -3856,7 +3856,7 @@ export type BattlerTagTypeMap = { [BattlerTagType.POWDER]: PowderTag; [BattlerTagType.NIGHTMARE]: NightmareTag; [BattlerTagType.FRENZY]: FrenzyTag; - [BattlerTagType.CHARGING]: BattlerTag; + [BattlerTagType.CHARGING]: SerializableBattlerTag; [BattlerTagType.ENCORE]: EncoreTag; [BattlerTagType.HELPING_HAND]: HelpingHandTag; [BattlerTagType.INGRAIN]: IngrainTag; @@ -3897,10 +3897,10 @@ export type BattlerTagTypeMap = { [BattlerTagType.FIRE_BOOST]: TypeBoostTag; [BattlerTagType.CRIT_BOOST]: CritBoostTag; [BattlerTagType.DRAGON_CHEER]: DragonCheerTag; - [BattlerTagType.ALWAYS_CRIT]: BattlerTag; - [BattlerTagType.IGNORE_ACCURACY]: BattlerTag; - [BattlerTagType.ALWAYS_GET_HIT]: BattlerTag; - [BattlerTagType.RECEIVE_DOUBLE_DAMAGE]: BattlerTag; + [BattlerTagType.ALWAYS_CRIT]: SerializableBattlerTag; + [BattlerTagType.IGNORE_ACCURACY]: SerializableBattlerTag; + [BattlerTagType.ALWAYS_GET_HIT]: SerializableBattlerTag; + [BattlerTagType.RECEIVE_DOUBLE_DAMAGE]: SerializableBattlerTag; [BattlerTagType.BYPASS_SLEEP]: BattlerTag; [BattlerTagType.IGNORE_FLYING]: GroundedTag; [BattlerTagType.ROOSTED]: RoostedTag; From 8ef2fadce45c3891bd7d32e91003cb7cbd220458 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Thu, 31 Jul 2025 19:08:41 -0600 Subject: [PATCH 62/76] [Misc] Disallow using NonFunctionProperties in loadTag methods (#6185) Disallow using NonFunctionProperties in loadTag methods --- src/data/arena-tag.ts | 3 --- src/data/battler-tags.ts | 16 +++++++--------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index 34477d737b4..15c2cde1d58 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -71,13 +71,10 @@ import i18next from "i18next"; * // Then we must also define a loadTag method with one of the following signatures * public override loadTag(source: BaseArenaTag & Pick(source: BaseArenaTag & Pick): void; - * public override loadTag(source: NonFunctionProperties): void; * } * ``` * Notes * - If the class has any subclasses, then the second form of `loadTag` *must* be used. - * - The third form *must not* be used if the class has any getters, as typescript would expect such fields to be - * present in `source`. */ /** Interface containing the serializable fields of ArenaTagData. */ diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 8805d671f8e..edeff293aa0 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -44,7 +44,7 @@ import type { SemiInvulnerableTagType, TrappingBattlerTagType, } from "#types/battler-tags"; -import type { Mutable, NonFunctionProperties } from "#types/type-helpers"; +import type { Mutable } from "#types/type-helpers"; import { BooleanHolder, coerceArray, getFrameMs, isNullOrUndefined, NumberHolder, toDmgValue } from "#utils/common"; /** @@ -80,13 +80,10 @@ import { BooleanHolder, coerceArray, getFrameMs, isNullOrUndefined, NumberHolder * // Then we must also define a loadTag method with one of the following signatures * public override loadTag(source: BaseBattlerTag & Pick(source: BaseBattlerTag & Pick): void; - * public override loadTag(source: NonFunctionProperties): void; * } * ``` * Notes * - If the class has any subclasses, then the second form of `loadTag` *must* be used. - * - The third form *must not* be used if the class has any getters, as typescript would expect such fields to be - * present in `source`. */ /** Interface containing the serializable fields of BattlerTag */ @@ -419,7 +416,6 @@ export class GorillaTacticsTag extends MoveRestrictionBattlerTag { public override readonly tagType = BattlerTagType.GORILLA_TACTICS; /** ID of the move that the user is locked into using*/ public readonly moveId: MoveId = MoveId.NONE; - constructor() { super(BattlerTagType.GORILLA_TACTICS, BattlerTagLapseType.CUSTOM, 0); } @@ -1235,7 +1231,7 @@ export class EncoreTag extends MoveRestrictionBattlerTag { ); } - public override loadTag(source: NonFunctionProperties): void { + public override loadTag(source: BaseBattlerTag & Pick): void { super.loadTag(source); this.moveId = source.moveId; } @@ -2618,7 +2614,7 @@ export class CommandedTag extends SerializableBattlerTag { } } - override loadTag(source: NonFunctionProperties): void { + override loadTag(source: BaseBattlerTag & Pick): void { super.loadTag(source); (this as Mutable).tatsugiriFormKey = source.tatsugiriFormKey; } @@ -2659,7 +2655,9 @@ export class StockpilingTag extends SerializableBattlerTag { } }; - public override loadTag(source: NonFunctionProperties): void { + public override loadTag( + source: BaseBattlerTag & Pick, + ): void { super.loadTag(source); this.stockpiledCount = source.stockpiledCount || 0; this.statChangeCounts = { @@ -3006,7 +3004,7 @@ export class AutotomizedTag extends SerializableBattlerTag { this.onAdd(pokemon); } - public override loadTag(source: NonFunctionProperties): void { + public override loadTag(source: BaseBattlerTag & Pick): void { super.loadTag(source); this.autotomizeCount = source.autotomizeCount; } From f54890001c895123842b81d53232711327208d82 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Thu, 31 Jul 2025 19:06:38 -0700 Subject: [PATCH 63/76] [Dev] `pnpm biome` will now only display errors by default (#6187) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 71a8b1ae334..d3494da677c 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "typecheck": "tsc --noEmit", "eslint": "eslint --fix .", "eslint-ci": "eslint .", - "biome": "biome check --write --changed --no-errors-on-unmatched", + "biome": "biome check --write --changed --no-errors-on-unmatched --diagnostic-level=error", "biome-ci": "biome ci --diagnostic-level=error --reporter=github --no-errors-on-unmatched", "docs": "typedoc", "depcruise": "depcruise src test", From 1c59b67d7e4be525104fd3382fbb35b608a1f005 Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Fri, 1 Aug 2025 13:08:28 -0400 Subject: [PATCH 64/76] [Sprite] Move Clauncher, Clawitzer, Skiddo, Fomantis, Lurantis animations to consistent (#6177) * Move Clauncher, Clawitzer, Skiddo out of exp * Move Fomantis, Lurantis out of exp --- public/exp-sprites.json | 42 - public/images/pokemon/672.json | 518 +++- public/images/pokemon/672.png | Bin 645 -> 3337 bytes public/images/pokemon/692.json | 774 +++++ public/images/pokemon/693.json | 941 +++++- public/images/pokemon/693.png | Bin 1088 -> 25840 bytes public/images/pokemon/753.json | 2559 +++++++++++++++- public/images/pokemon/753.png | Bin 476 -> 2090 bytes public/images/pokemon/754.json | 1106 ++++++- public/images/pokemon/754.png | Bin 789 -> 3754 bytes public/images/pokemon/back/672.json | 518 +++- public/images/pokemon/back/672.png | Bin 599 -> 3350 bytes public/images/pokemon/back/692.json | 774 +++++ public/images/pokemon/back/693.json | 941 +++++- public/images/pokemon/back/693.png | Bin 982 -> 21703 bytes public/images/pokemon/back/753.json | 2561 +++++++++++++++- public/images/pokemon/back/753.png | Bin 441 -> 2062 bytes public/images/pokemon/back/754.json | 1085 ++++++- public/images/pokemon/back/754.png | Bin 689 -> 3640 bytes public/images/pokemon/back/shiny/672.json | 518 +++- public/images/pokemon/back/shiny/672.png | Bin 599 -> 3349 bytes public/images/pokemon/back/shiny/692.json | 833 +++++- public/images/pokemon/back/shiny/692.png | Bin 478 -> 2025 bytes public/images/pokemon/back/shiny/693.json | 941 +++++- public/images/pokemon/back/shiny/693.png | Bin 1029 -> 21707 bytes public/images/pokemon/back/shiny/753.json | 2561 +++++++++++++++- public/images/pokemon/back/shiny/753.png | Bin 441 -> 2061 bytes public/images/pokemon/back/shiny/754.json | 1106 ++++++- public/images/pokemon/back/shiny/754.png | Bin 690 -> 3640 bytes public/images/pokemon/exp/672.json | 479 --- public/images/pokemon/exp/672.png | Bin 3333 -> 0 bytes public/images/pokemon/exp/692.json | 794 ----- public/images/pokemon/exp/692.png | Bin 2580 -> 0 bytes public/images/pokemon/exp/693.json | 902 ------ public/images/pokemon/exp/693.png | Bin 25840 -> 0 bytes public/images/pokemon/exp/753.json | 2582 ----------------- public/images/pokemon/exp/753.png | Bin 2090 -> 0 bytes public/images/pokemon/exp/754.json | 1133 -------- public/images/pokemon/exp/754.png | Bin 3754 -> 0 bytes public/images/pokemon/exp/back/672.json | 479 --- public/images/pokemon/exp/back/672.png | Bin 3350 -> 0 bytes public/images/pokemon/exp/back/692.json | 794 ----- public/images/pokemon/exp/back/692.png | Bin 2025 -> 0 bytes public/images/pokemon/exp/back/693.json | 902 ------ public/images/pokemon/exp/back/693.png | Bin 21703 -> 0 bytes public/images/pokemon/exp/back/753.json | 2582 ----------------- public/images/pokemon/exp/back/753.png | Bin 2062 -> 0 bytes public/images/pokemon/exp/back/754.json | 1112 ------- public/images/pokemon/exp/back/754.png | Bin 3640 -> 0 bytes public/images/pokemon/exp/back/shiny/672.json | 479 --- public/images/pokemon/exp/back/shiny/672.png | Bin 3349 -> 0 bytes public/images/pokemon/exp/back/shiny/692.json | 794 ----- public/images/pokemon/exp/back/shiny/692.png | Bin 2025 -> 0 bytes public/images/pokemon/exp/back/shiny/693.json | 902 ------ public/images/pokemon/exp/back/shiny/693.png | Bin 21707 -> 0 bytes public/images/pokemon/exp/back/shiny/753.json | 2582 ----------------- public/images/pokemon/exp/back/shiny/753.png | Bin 2061 -> 0 bytes public/images/pokemon/exp/back/shiny/754.json | 1133 -------- public/images/pokemon/exp/back/shiny/754.png | Bin 3640 -> 0 bytes public/images/pokemon/exp/shiny/672.json | 479 --- public/images/pokemon/exp/shiny/672.png | Bin 3333 -> 0 bytes public/images/pokemon/exp/shiny/692.json | 794 ----- public/images/pokemon/exp/shiny/692.png | Bin 2580 -> 0 bytes public/images/pokemon/exp/shiny/693.json | 902 ------ public/images/pokemon/exp/shiny/693.png | Bin 25899 -> 0 bytes public/images/pokemon/exp/shiny/753.json | 2582 ----------------- public/images/pokemon/exp/shiny/753.png | Bin 2090 -> 0 bytes public/images/pokemon/exp/shiny/754.json | 1133 -------- public/images/pokemon/exp/shiny/754.png | Bin 3754 -> 0 bytes public/images/pokemon/shiny/672.json | 518 +++- public/images/pokemon/shiny/672.png | Bin 645 -> 3337 bytes public/images/pokemon/shiny/692.json | 833 +++++- public/images/pokemon/shiny/692.png | Bin 509 -> 2580 bytes public/images/pokemon/shiny/693.json | 941 +++++- public/images/pokemon/shiny/693.png | Bin 1144 -> 25899 bytes public/images/pokemon/shiny/753.json | 2559 +++++++++++++++- public/images/pokemon/shiny/753.png | Bin 471 -> 2090 bytes public/images/pokemon/shiny/754.json | 1106 ++++++- public/images/pokemon/shiny/754.png | Bin 812 -> 3754 bytes public/images/pokemon/variant/672.json | 15 + public/images/pokemon/variant/672_3.json | 41 - public/images/pokemon/variant/672_3.png | Bin 672 -> 0 bytes .../pokemon/variant/_exp_masterlist.json | 10 - .../images/pokemon/variant/_masterlist.json | 4 +- public/images/pokemon/variant/back/753.json | 28 +- .../pokemon/variant/{exp => back}/754.json | 0 public/images/pokemon/variant/back/754_2.json | 41 - public/images/pokemon/variant/back/754_2.png | Bin 703 -> 0 bytes public/images/pokemon/variant/back/754_3.json | 41 - public/images/pokemon/variant/back/754_3.png | Bin 700 -> 0 bytes public/images/pokemon/variant/exp/672.json | 32 - public/images/pokemon/variant/exp/692.json | 26 - public/images/pokemon/variant/exp/693.json | 30 - public/images/pokemon/variant/exp/753.json | 32 - public/images/pokemon/variant/exp/754_2.json | 1133 -------- public/images/pokemon/variant/exp/754_2.png | Bin 4040 -> 0 bytes public/images/pokemon/variant/exp/754_3.json | 1133 -------- public/images/pokemon/variant/exp/754_3.png | Bin 4040 -> 0 bytes .../images/pokemon/variant/exp/back/672.json | 32 - .../images/pokemon/variant/exp/back/692.json | 28 - .../images/pokemon/variant/exp/back/693.json | 28 - .../images/pokemon/variant/exp/back/753.json | 26 - .../images/pokemon/variant/exp/back/754.json | 14 - .../pokemon/variant/exp/back/754_2.json | 1112 ------- .../images/pokemon/variant/exp/back/754_2.png | Bin 3646 -> 0 bytes .../pokemon/variant/exp/back/754_3.json | 1112 ------- .../images/pokemon/variant/exp/back/754_3.png | Bin 3725 -> 0 bytes 107 files changed, 23263 insertions(+), 28929 deletions(-) delete mode 100644 public/images/pokemon/exp/672.json delete mode 100644 public/images/pokemon/exp/672.png delete mode 100644 public/images/pokemon/exp/692.json delete mode 100644 public/images/pokemon/exp/692.png delete mode 100644 public/images/pokemon/exp/693.json delete mode 100644 public/images/pokemon/exp/693.png delete mode 100644 public/images/pokemon/exp/753.json delete mode 100644 public/images/pokemon/exp/753.png delete mode 100644 public/images/pokemon/exp/754.json delete mode 100644 public/images/pokemon/exp/754.png delete mode 100644 public/images/pokemon/exp/back/672.json delete mode 100644 public/images/pokemon/exp/back/672.png delete mode 100644 public/images/pokemon/exp/back/692.json delete mode 100644 public/images/pokemon/exp/back/692.png delete mode 100644 public/images/pokemon/exp/back/693.json delete mode 100644 public/images/pokemon/exp/back/693.png delete mode 100644 public/images/pokemon/exp/back/753.json delete mode 100644 public/images/pokemon/exp/back/753.png delete mode 100644 public/images/pokemon/exp/back/754.json delete mode 100644 public/images/pokemon/exp/back/754.png delete mode 100644 public/images/pokemon/exp/back/shiny/672.json delete mode 100644 public/images/pokemon/exp/back/shiny/672.png delete mode 100644 public/images/pokemon/exp/back/shiny/692.json delete mode 100644 public/images/pokemon/exp/back/shiny/692.png delete mode 100644 public/images/pokemon/exp/back/shiny/693.json delete mode 100644 public/images/pokemon/exp/back/shiny/693.png delete mode 100644 public/images/pokemon/exp/back/shiny/753.json delete mode 100644 public/images/pokemon/exp/back/shiny/753.png delete mode 100644 public/images/pokemon/exp/back/shiny/754.json delete mode 100644 public/images/pokemon/exp/back/shiny/754.png delete mode 100644 public/images/pokemon/exp/shiny/672.json delete mode 100644 public/images/pokemon/exp/shiny/672.png delete mode 100644 public/images/pokemon/exp/shiny/692.json delete mode 100644 public/images/pokemon/exp/shiny/692.png delete mode 100644 public/images/pokemon/exp/shiny/693.json delete mode 100644 public/images/pokemon/exp/shiny/693.png delete mode 100644 public/images/pokemon/exp/shiny/753.json delete mode 100644 public/images/pokemon/exp/shiny/753.png delete mode 100644 public/images/pokemon/exp/shiny/754.json delete mode 100644 public/images/pokemon/exp/shiny/754.png delete mode 100644 public/images/pokemon/variant/672_3.json delete mode 100644 public/images/pokemon/variant/672_3.png rename public/images/pokemon/variant/{exp => back}/754.json (100%) delete mode 100644 public/images/pokemon/variant/back/754_2.json delete mode 100644 public/images/pokemon/variant/back/754_2.png delete mode 100644 public/images/pokemon/variant/back/754_3.json delete mode 100644 public/images/pokemon/variant/back/754_3.png delete mode 100644 public/images/pokemon/variant/exp/672.json delete mode 100644 public/images/pokemon/variant/exp/692.json delete mode 100644 public/images/pokemon/variant/exp/693.json delete mode 100644 public/images/pokemon/variant/exp/753.json delete mode 100644 public/images/pokemon/variant/exp/754_2.json delete mode 100644 public/images/pokemon/variant/exp/754_2.png delete mode 100644 public/images/pokemon/variant/exp/754_3.json delete mode 100644 public/images/pokemon/variant/exp/754_3.png delete mode 100644 public/images/pokemon/variant/exp/back/672.json delete mode 100644 public/images/pokemon/variant/exp/back/692.json delete mode 100644 public/images/pokemon/variant/exp/back/693.json delete mode 100644 public/images/pokemon/variant/exp/back/753.json delete mode 100644 public/images/pokemon/variant/exp/back/754.json delete mode 100644 public/images/pokemon/variant/exp/back/754_2.json delete mode 100644 public/images/pokemon/variant/exp/back/754_2.png delete mode 100644 public/images/pokemon/variant/exp/back/754_3.json delete mode 100644 public/images/pokemon/variant/exp/back/754_3.png diff --git a/public/exp-sprites.json b/public/exp-sprites.json index 7430bcf4dba..1903a6c7804 100644 --- a/public/exp-sprites.json +++ b/public/exp-sprites.json @@ -333,8 +333,6 @@ "671-yellow", "6713", "6713", - "672", - "672", "6724", "6724", "673", @@ -377,10 +375,6 @@ "690", "691", "691", - "692", - "692", - "693", - "693", "695", "695", "696", @@ -503,10 +497,6 @@ "751", "752", "752", - "753", - "753", - "754", - "754", "755", "755", "756", @@ -1459,8 +1449,6 @@ "671b-yellow", "6713b", "6713b", - "672b", - "672b", "6724b", "6724b", "673b", @@ -1503,10 +1491,6 @@ "690b", "691b", "691b", - "692b", - "692b", - "693b", - "693b", "695b", "695b", "696b", @@ -1629,10 +1613,6 @@ "751b", "752b", "752b", - "753b", - "753b", - "754b", - "754b", "755b", "755b", "756b", @@ -2585,8 +2565,6 @@ "671sb-yellow", "6713sb", "6713sb", - "672sb", - "672sb", "6724sb", "6724sb", "673sb", @@ -2629,10 +2607,6 @@ "690sb", "691sb", "691sb", - "692sb", - "692sb", - "693sb", - "693sb", "695sb", "695sb", "696sb", @@ -2755,10 +2729,6 @@ "751sb", "752sb", "752sb", - "753sb", - "753sb", - "754sb", - "754sb", "755sb", "755sb", "756sb", @@ -3716,8 +3686,6 @@ "671s-yellow", "6713s", "6713s", - "672s", - "672s", "6724s", "6724s", "673s", @@ -3760,10 +3728,6 @@ "690s", "691s", "691s", - "692s", - "692s", - "693s", - "693s", "695s", "695s", "696s", @@ -3886,10 +3850,6 @@ "751s", "752s", "752s", - "753s", - "753s", - "754s", - "754s", "755s", "755s", "756s", @@ -4625,8 +4585,6 @@ "730", "747", "748", - "753", - "754", "755", "756", "761", diff --git a/public/images/pokemon/672.json b/public/images/pokemon/672.json index eabec185e7a..f337bef7d29 100644 --- a/public/images/pokemon/672.json +++ b/public/images/pokemon/672.json @@ -1,41 +1,479 @@ -{ - "textures": [ - { - "image": "672.png", - "format": "RGBA8888", - "size": { - "w": 50, - "h": 50 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 42, - "h": 50 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 42, - "h": 50 - }, - "frame": { - "x": 0, - "y": 0, - "w": 42, - "h": 50 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:a5389856891adb93e4e47b311ec032fc:ff2b44df2ba78f8e713e7ecfbd8a40e8:2e4767b7cd134fc0ab1bb6e9eee82bc7$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0002.png", + "frame": { "x": 127, "y": 50, "w": 42, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 42, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0004.png", + "frame": { "x": 43, "y": 53, "w": 43, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 43, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0005.png", + "frame": { "x": 124, "y": 148, "w": 43, "h": 45 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 13, "w": 43, "h": 45 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0006.png", + "frame": { "x": 0, "y": 102, "w": 42, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 42, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0007.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0008.png", + "frame": { "x": 127, "y": 99, "w": 41, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 41, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0009.png", + "frame": { "x": 128, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0010.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0011.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0012.png", + "frame": { "x": 127, "y": 50, "w": 42, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 42, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0013.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0014.png", + "frame": { "x": 43, "y": 53, "w": 43, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 43, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0015.png", + "frame": { "x": 124, "y": 148, "w": 43, "h": 45 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 13, "w": 43, "h": 45 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0016.png", + "frame": { "x": 0, "y": 102, "w": 42, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 42, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0017.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0018.png", + "frame": { "x": 127, "y": 99, "w": 41, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 41, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0019.png", + "frame": { "x": 128, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0020.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0021.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0022.png", + "frame": { "x": 127, "y": 50, "w": 42, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 42, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0023.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0024.png", + "frame": { "x": 43, "y": 53, "w": 43, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 43, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0025.png", + "frame": { "x": 124, "y": 148, "w": 43, "h": 45 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 13, "w": 43, "h": 45 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0026.png", + "frame": { "x": 0, "y": 102, "w": 42, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 42, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0027.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0028.png", + "frame": { "x": 127, "y": 99, "w": 41, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 41, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0029.png", + "frame": { "x": 128, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0030.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0031.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0032.png", + "frame": { "x": 127, "y": 50, "w": 42, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 42, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0033.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0034.png", + "frame": { "x": 43, "y": 53, "w": 43, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 43, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0035.png", + "frame": { "x": 124, "y": 148, "w": 43, "h": 45 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 13, "w": 43, "h": 45 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0036.png", + "frame": { "x": 0, "y": 102, "w": 42, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 42, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0037.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0038.png", + "frame": { "x": 127, "y": 99, "w": 41, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 41, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0039.png", + "frame": { "x": 128, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0040.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0041.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0042.png", + "frame": { "x": 43, "y": 0, "w": 43, "h": 53 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 4, "w": 43, "h": 53 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0043.png", + "frame": { "x": 0, "y": 0, "w": 43, "h": 54 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 0, "w": 43, "h": 54 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0044.png", + "frame": { "x": 42, "y": 100, "w": 41, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 9, "w": 41, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0045.png", + "frame": { "x": 86, "y": 50, "w": 41, "h": 51 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 7, "w": 41, "h": 51 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0046.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0047.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0048.png", + "frame": { "x": 43, "y": 0, "w": 43, "h": 53 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 4, "w": 43, "h": 53 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0049.png", + "frame": { "x": 0, "y": 0, "w": 43, "h": 54 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 0, "w": 43, "h": 54 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0050.png", + "frame": { "x": 83, "y": 101, "w": 41, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 9, "w": 41, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0051.png", + "frame": { "x": 86, "y": 50, "w": 41, "h": 51 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 7, "w": 41, "h": 51 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0052.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.11-x64", + "image": "672.png", + "format": "I8", + "size": { "w": 170, "h": 193 }, + "scale": "1" + } } diff --git a/public/images/pokemon/672.png b/public/images/pokemon/672.png index 2fdd68acd32510bbb57ccc654cc8ae07082560ef..ff319db5822189e38382ff2966380a614293dc6f 100644 GIT binary patch literal 3337 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 diff --git a/public/images/pokemon/692.json b/public/images/pokemon/692.json index 125642a01f1..86b535260ae 100644 --- a/public/images/pokemon/692.json +++ b/public/images/pokemon/692.json @@ -7,6 +7,780 @@ "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, "sourceSize": { "w": 63, "h": 35 }, "duration": 50 + }, + { + "filename": "0002.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0003.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0004.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0005.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0006.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0007.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0008.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0009.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0010.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0011.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0012.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0013.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0014.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0015.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0016.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0017.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0018.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0019.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0020.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0021.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0022.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0023.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0024.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0025.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0026.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0027.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0028.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0029.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0030.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0031.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0032.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0033.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0034.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0035.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0036.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0037.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0038.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0039.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0040.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0041.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0042.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0043.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0044.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0045.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0046.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0047.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0048.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0049.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0050.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0051.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0052.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0053.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0054.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0055.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0056.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0057.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0058.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0059.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0060.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0061.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0062.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0063.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0064.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0065.png", + "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0066.png", + "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0067.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0068.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0069.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0070.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0071.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0072.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0073.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0074.png", + "frame": { "x": 1, "y": 71, "w": 57, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0075.png", + "frame": { "x": 1, "y": 71, "w": 57, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0076.png", + "frame": { "x": 117, "y": 72, "w": 59, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 2, "w": 59, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0077.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0078.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0079.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0080.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0081.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0082.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0083.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0084.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0085.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0086.png", + "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0087.png", + "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 } ], "meta": { diff --git a/public/images/pokemon/693.json b/public/images/pokemon/693.json index 5e35ec822d2..c8f7763de1d 100644 --- a/public/images/pokemon/693.json +++ b/public/images/pokemon/693.json @@ -1,41 +1,902 @@ -{ - "textures": [ - { - "image": "693.png", - "format": "RGBA8888", - "size": { - "w": 87, - "h": 87 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 87, - "h": 78 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 87, - "h": 78 - }, - "frame": { - "x": 0, - "y": 0, - "w": 87, - "h": 78 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:56529e9f35f7fe73552976d184900c50:cf9846d335c4b48dea98b7f53c4caa05:9c1f9147e693c05eb4655590e9099679$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 208, "y": 78, "w": 95, "h": 76 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 2, "w": 95, "h": 76 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0002.png", + "frame": { "x": 416, "y": 214, "w": 91, "h": 76 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 1, "w": 91, "h": 76 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0003.png", + "frame": { "x": 405, "y": 145, "w": 103, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 103, "h": 69 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0004.png", + "frame": { "x": 207, "y": 344, "w": 105, "h": 62 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 17, "w": 105, "h": 62 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0005.png", + "frame": { "x": 507, "y": 285, "w": 105, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 18, "w": 105, "h": 63 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0006.png", + "frame": { "x": 412, "y": 1, "w": 104, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 13, "w": 104, "h": 71 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0007.png", + "frame": { "x": 1, "y": 145, "w": 99, "h": 72 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 14, "w": 99, "h": 72 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0008.png", + "frame": { "x": 1, "y": 76, "w": 105, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 21, "w": 105, "h": 69 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0009.png", + "frame": { "x": 507, "y": 219, "w": 104, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 24, "w": 104, "h": 66 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0010.png", + "frame": { "x": 1, "y": 283, "w": 102, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 23, "w": 102, "h": 66 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0011.png", + "frame": { "x": 207, "y": 1, "w": 99, "h": 77 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 10, "w": 99, "h": 77 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0012.png", + "frame": { "x": 517, "y": 74, "w": 93, "h": 78 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 7, "w": 93, "h": 78 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0013.png", + "frame": { "x": 106, "y": 78, "w": 102, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 12, "w": 102, "h": 71 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0014.png", + "frame": { "x": 421, "y": 348, "w": 102, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 19, "w": 102, "h": 63 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0015.png", + "frame": { "x": 312, "y": 354, "w": 100, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 18, "w": 100, "h": 61 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0016.png", + "frame": { "x": 208, "y": 78, "w": 95, "h": 76 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 2, "w": 95, "h": 76 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0017.png", + "frame": { "x": 416, "y": 214, "w": 91, "h": 76 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 1, "w": 91, "h": 76 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0018.png", + "frame": { "x": 405, "y": 145, "w": 103, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 103, "h": 69 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0019.png", + "frame": { "x": 207, "y": 344, "w": 105, "h": 62 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 17, "w": 105, "h": 62 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0020.png", + "frame": { "x": 507, "y": 285, "w": 105, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 18, "w": 105, "h": 63 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0021.png", + "frame": { "x": 412, "y": 1, "w": 104, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 13, "w": 104, "h": 71 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0022.png", + "frame": { "x": 1, "y": 145, "w": 99, "h": 72 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 14, "w": 99, "h": 72 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0023.png", + "frame": { "x": 1, "y": 76, "w": 105, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 21, "w": 105, "h": 69 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0024.png", + "frame": { "x": 507, "y": 219, "w": 104, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 24, "w": 104, "h": 66 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0025.png", + "frame": { "x": 1, "y": 283, "w": 102, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 23, "w": 102, "h": 66 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0026.png", + "frame": { "x": 207, "y": 1, "w": 99, "h": 77 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 10, "w": 99, "h": 77 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0027.png", + "frame": { "x": 517, "y": 74, "w": 93, "h": 78 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 7, "w": 93, "h": 78 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0028.png", + "frame": { "x": 106, "y": 78, "w": 102, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 12, "w": 102, "h": 71 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0029.png", + "frame": { "x": 421, "y": 348, "w": 102, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 19, "w": 102, "h": 63 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0030.png", + "frame": { "x": 312, "y": 354, "w": 100, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 18, "w": 100, "h": 61 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0031.png", + "frame": { "x": 208, "y": 78, "w": 95, "h": 76 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 2, "w": 95, "h": 76 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0032.png", + "frame": { "x": 416, "y": 214, "w": 91, "h": 76 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 1, "w": 91, "h": 76 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0033.png", + "frame": { "x": 405, "y": 145, "w": 103, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 103, "h": 69 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0034.png", + "frame": { "x": 207, "y": 344, "w": 105, "h": 62 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 17, "w": 105, "h": 62 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0035.png", + "frame": { "x": 507, "y": 285, "w": 105, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 18, "w": 105, "h": 63 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0036.png", + "frame": { "x": 412, "y": 1, "w": 104, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 13, "w": 104, "h": 71 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0037.png", + "frame": { "x": 1, "y": 145, "w": 99, "h": 72 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 14, "w": 99, "h": 72 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0038.png", + "frame": { "x": 1, "y": 76, "w": 105, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 21, "w": 105, "h": 69 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0039.png", + "frame": { "x": 507, "y": 219, "w": 104, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 24, "w": 104, "h": 66 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0040.png", + "frame": { "x": 1, "y": 283, "w": 102, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 23, "w": 102, "h": 66 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0041.png", + "frame": { "x": 207, "y": 1, "w": 99, "h": 77 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 10, "w": 99, "h": 77 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0042.png", + "frame": { "x": 517, "y": 74, "w": 93, "h": 78 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 7, "w": 93, "h": 78 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0043.png", + "frame": { "x": 106, "y": 78, "w": 102, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 12, "w": 102, "h": 71 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0044.png", + "frame": { "x": 421, "y": 348, "w": 102, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 19, "w": 102, "h": 63 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0045.png", + "frame": { "x": 312, "y": 354, "w": 100, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 18, "w": 100, "h": 61 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0046.png", + "frame": { "x": 208, "y": 78, "w": 95, "h": 76 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 2, "w": 95, "h": 76 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0047.png", + "frame": { "x": 416, "y": 214, "w": 91, "h": 76 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 1, "w": 91, "h": 76 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0048.png", + "frame": { "x": 405, "y": 145, "w": 103, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 103, "h": 69 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0049.png", + "frame": { "x": 207, "y": 344, "w": 105, "h": 62 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 17, "w": 105, "h": 62 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0050.png", + "frame": { "x": 507, "y": 285, "w": 105, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 18, "w": 105, "h": 63 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0051.png", + "frame": { "x": 412, "y": 1, "w": 104, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 13, "w": 104, "h": 71 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0052.png", + "frame": { "x": 1, "y": 145, "w": 99, "h": 72 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 14, "w": 99, "h": 72 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0053.png", + "frame": { "x": 1, "y": 76, "w": 105, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 21, "w": 105, "h": 69 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0054.png", + "frame": { "x": 507, "y": 219, "w": 104, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 24, "w": 104, "h": 66 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0055.png", + "frame": { "x": 1, "y": 283, "w": 102, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 23, "w": 102, "h": 66 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0056.png", + "frame": { "x": 207, "y": 1, "w": 99, "h": 77 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 10, "w": 99, "h": 77 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0057.png", + "frame": { "x": 517, "y": 74, "w": 93, "h": 78 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 7, "w": 93, "h": 78 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0058.png", + "frame": { "x": 106, "y": 78, "w": 102, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 12, "w": 102, "h": 71 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0059.png", + "frame": { "x": 421, "y": 348, "w": 102, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 19, "w": 102, "h": 63 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0060.png", + "frame": { "x": 312, "y": 354, "w": 100, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 18, "w": 100, "h": 61 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0061.png", + "frame": { "x": 208, "y": 78, "w": 95, "h": 76 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 2, "w": 95, "h": 76 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0062.png", + "frame": { "x": 416, "y": 214, "w": 91, "h": 76 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 1, "w": 91, "h": 76 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0063.png", + "frame": { "x": 405, "y": 145, "w": 103, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 103, "h": 69 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0064.png", + "frame": { "x": 207, "y": 344, "w": 105, "h": 62 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 17, "w": 105, "h": 62 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0065.png", + "frame": { "x": 507, "y": 285, "w": 105, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 18, "w": 105, "h": 63 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0066.png", + "frame": { "x": 412, "y": 1, "w": 104, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 13, "w": 104, "h": 71 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0067.png", + "frame": { "x": 1, "y": 145, "w": 99, "h": 72 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 14, "w": 99, "h": 72 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0068.png", + "frame": { "x": 1, "y": 76, "w": 105, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 21, "w": 105, "h": 69 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0069.png", + "frame": { "x": 507, "y": 219, "w": 104, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 24, "w": 104, "h": 66 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0070.png", + "frame": { "x": 1, "y": 283, "w": 102, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 23, "w": 102, "h": 66 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0071.png", + "frame": { "x": 207, "y": 1, "w": 99, "h": 77 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 10, "w": 99, "h": 77 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0072.png", + "frame": { "x": 517, "y": 74, "w": 93, "h": 78 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 7, "w": 93, "h": 78 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0073.png", + "frame": { "x": 106, "y": 78, "w": 102, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 12, "w": 102, "h": 71 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0074.png", + "frame": { "x": 421, "y": 348, "w": 102, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 19, "w": 102, "h": 63 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0075.png", + "frame": { "x": 312, "y": 354, "w": 100, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 18, "w": 100, "h": 61 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0076.png", + "frame": { "x": 208, "y": 78, "w": 95, "h": 76 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 2, "w": 95, "h": 76 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0077.png", + "frame": { "x": 303, "y": 140, "w": 102, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 5, "w": 102, "h": 70 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0078.png", + "frame": { "x": 523, "y": 348, "w": 102, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 13, "y": 11, "w": 102, "h": 63 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0079.png", + "frame": { "x": 318, "y": 290, "w": 103, "h": 64 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 15, "y": 7, "w": 103, "h": 64 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0080.png", + "frame": { "x": 105, "y": 1, "w": 102, "h": 75 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 0, "w": 102, "h": 75 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0081.png", + "frame": { "x": 306, "y": 72, "w": 108, "h": 68 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 14, "w": 108, "h": 68 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0082.png", + "frame": { "x": 108, "y": 276, "w": 105, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 14, "w": 105, "h": 65 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0083.png", + "frame": { "x": 1, "y": 1, "w": 104, "h": 74 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 8, "w": 104, "h": 74 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0084.png", + "frame": { "x": 203, "y": 210, "w": 106, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 13, "w": 106, "h": 66 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0085.png", + "frame": { "x": 508, "y": 152, "w": 106, "h": 67 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 15, "w": 106, "h": 67 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0086.png", + "frame": { "x": 414, "y": 74, "w": 103, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 8, "w": 103, "h": 71 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0087.png", + "frame": { "x": 306, "y": 72, "w": 108, "h": 68 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 14, "w": 108, "h": 68 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0088.png", + "frame": { "x": 108, "y": 276, "w": 105, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 14, "w": 105, "h": 65 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0089.png", + "frame": { "x": 1, "y": 1, "w": 104, "h": 74 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 8, "w": 104, "h": 74 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0090.png", + "frame": { "x": 203, "y": 210, "w": 106, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 13, "w": 106, "h": 66 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0091.png", + "frame": { "x": 309, "y": 214, "w": 107, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 14, "w": 107, "h": 65 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0092.png", + "frame": { "x": 306, "y": 1, "w": 106, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 9, "w": 106, "h": 70 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0093.png", + "frame": { "x": 1, "y": 218, "w": 107, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 14, "w": 107, "h": 65 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0094.png", + "frame": { "x": 213, "y": 279, "w": 105, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 14, "w": 105, "h": 65 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0095.png", + "frame": { "x": 103, "y": 341, "w": 104, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 15, "w": 104, "h": 63 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0096.png", + "frame": { "x": 516, "y": 1, "w": 101, "h": 73 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 5, "w": 101, "h": 73 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0097.png", + "frame": { "x": 100, "y": 149, "w": 103, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 103, "h": 69 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0098.png", + "frame": { "x": 1, "y": 349, "w": 102, "h": 62 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 16, "w": 102, "h": 62 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + }, + { + "filename": "0099.png", + "frame": { "x": 103, "y": 404, "w": 100, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 16, "w": 100, "h": 61 }, + "sourceSize": { "w": 118, "h": 90 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.12-x64", + "image": "693.png", + "format": "I8", + "size": { "w": 626, "h": 466 }, + "scale": "1" + } } diff --git a/public/images/pokemon/693.png b/public/images/pokemon/693.png index 848c881311acdc85f6eb12840a8e3f60be8256a4..28f3bd88282bc4d4972b347c0308bf6d9e16d016 100644 GIT binary patch literal 25840 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 U6<`(rIRF3v07*qoM6N<$f?TKLMgRZ+ literal 476 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 literal 789 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 literal 982 zcmV;{11bE8P))P0004WQchCl3Yzmpxr_C#V&TAw?3 zNgScJB}nMe({LNlwCmX;-R?)gabFOby`uen8^IFYx5wLd0D893_iO~`U|6y1wEaz+ z<-Toczi!w{v+Y-QrbDU74SS*2cC6AKB`)`OrZ@H+m$bdwAE15N>4grK_Eo#kwXJhU z6DMA=K1U~eE{T)${0Gwx`S_FYJe}^*q=9;23KbsBzD6h0MsGzgIP2GKn49U^_8tWn z{Spnoipr+^h+4mvwFeq|O>?(Yg}Jbs0YpGAZF?|1UMY$6#*V$BrR>t`{=5y^+Uttg z10Rmw{&m~NMzkmLm}jQxWW|+^`*uU8PibyFU!An$Y#ojRI!|}~y2agIV4jOz(%u%^ zmnm5mt44QIiBJV%G(6i~y2#tq0RS$na5-JZSlK<=uj#$Ii0=xV)6R)kY46Z$`PFMi z@%8kCQgx0lE$iecAAU)^JJs`6uqr)c)Q;zpIm1C9o$G>C5rC>pROi;D>F!%+VepqEOKS&+|LRlQ%wE=iK33 z6rHH33RA;upS?^fb$b?^)X+bEP0<#8(HT6 zz+2fQy}olZv)JcGQYJw~^Q!02x%OG=efs(v(txtLbFaUsd#7ah8>f%jN#$?4w(Q#F zI!pr>UJ=k#sqbWB1C9_SiBL{Q4GJ0x0000DNk~Le0001t0001t1Oos709@`|4FCWDDv>23 zf6P*5*^Qd``1t?7%ILFK$^ZZW0d!JMQvg8b*k%9#2a-udK~#8N&6z=K8&?#C=hc+D zyP3+P9@w|U`qKf(~+OKMq+~qCfXgzf}Jln5m z404yZOonUD;dnB>07069+@=1>aNQA;@dRs0Q;=LfUr&bM_!T*R?%4Y^Zsi*6p<|?8 zocN?ENG|^vT{EuM;McJrcX`dYbasYj@p0K=wePsjh}6`iwk927EVVUhT3%r;e+})W zY2c#@QW$J~9H1NQfE=Rct{vJ#H+cdw9Hr%)O9%>ig2G&3E)DEiBi1!59VfcR2H}e9 z(%8K?J@2by{WUSllQdSju8ARdZmzg4jonixeWiL>(^q=wT&W!Gk;>tMx#GHZXiw#r znXVB^FR8vXi{B``V6HeW4ejMpe`-U>43;vL$gGDtlz72hVJ?l?lNr>+=m;sZL`qm3 z#m1Ik=_}l&F?(18zpm6~v9HS7ku0w;*ADH)agyam3BZ`SV30=?ZgcaBox;tD3zyj*DWks<{JguP~Pe_Xg;cH7^SotTl_^}vf2on^L{TA4E_@n2kSL}3w}}#SU&Nru%~Z8VNOZD+$$?Dd z2xS5~ha5=Ey^$&>7nYT()Hu1&%6TZ|TkAfAnoPZ*<+-f>`?I;c%!MOqrSN{Bq%*G>*?RLCDp@XaUJ5vksIDre`-wb+1rKAft-~R zERd(Kp$2}`{gr?tqGMgit+$l9nazpmY+BqIDZo9Q_4ZD0um+EK9qZz5WsEaeT9liEd&^-JZK4a#MGZrHNGPNy={RCs)H;V2Z3t38x04Si z7)u_cFBlg!4DC()DvAvKHu9n2XhSv6YwVVq)Sgd?uNugw9)va`pJothCm%j#j1a{V z&9I4l_;3(vCm%km*m;R4mT1x@^5J7+KbDAMi6(9!A3hv}f7;214+o)k^5MflXcO}B z8bPR?eE4t>Y9}8)9E3I@9~urq?c~FUgHQ|kG|l#=^0ROGTlA9d4vR`Yo>dEI!Hd#3i$|7e+?6y&VIN)ooXln9C!sabEsKD zMTLCYraK$VgQjV1Ve1Fw(jitEXN3jz=YM%9@C6qI3{s| z2^?MXf3lMjCb1f`$8wBdL=cpGLp2mLdjZQaf-xjgViFC-#wDWg91)Bq5ldf{!Ppr0 z5})N9f&tgcl< z0TghatDNCgIO=FrK}a$3;RF*} zyvcfXAe7}S#|TD%XDEr)SP+uzMTirOc%$(q0ZL*#Rr?~u31-{i%{vQUG(r7~5F;2- z5Z=^*5U_@mb4Y~Lg4NJs8^KgeRv|L&?DgeLox;{;=C&d|Q710kdz zmScRQYrr2eNF$GGhBW z1Orle9W8!_haI3KUc*5sUznF2Od5ju98_l}d**%U+Wl2RzSbZ#Fd$^fr+nG*wk*MX z2|N?erach1z$MbfqAmj=ox1{wHI`t+6nrS|%%EoJ&DjWb@NEdi22nzlnqz_(qX24VC!9{}*{6t1D#>cM;;O~7kzMyshA-{X<*S_5ZwS0$1 i)^emaA{gO)?EDRxN>)KQH0uWd0000-iBL{Q4GJ0x0000DNk~Le0000j0000j2m=5B01di zcXO*+ms_8jnVOk$h*7{0u816AF=E`(mKJ^77|U;k!)AJkpI8zs;7iZ=T~CWcN*_AG zM6*A28fXB;I>B)QfDXy(Rdl1wDOJqsJL8Qb{dW`{neclu7p;aaNZ7Cc2gbaB|- z-a^n4kspipz5+itwoi%3H+z#qerf_cOfT%0HZ7djMtp7RTCFs_i|b0t-=VE*b?X8-^I diff --git a/public/images/pokemon/back/754.json b/public/images/pokemon/back/754.json index 125ebed161c..86abaac1814 100644 --- a/public/images/pokemon/back/754.json +++ b/public/images/pokemon/back/754.json @@ -4,29 +4,1100 @@ "image": "754.png", "format": "RGBA8888", "size": { - "w": 68, - "h": 68 + "w": 222, + "h": 222 }, "scale": 1, "frames": [ { - "filename": "0001.png", + "filename": "0036.png", "rotated": false, "trimmed": false, "sourceSize": { - "w": 36, + "w": 92, "h": 68 }, "spriteSourceSize": { "x": 0, "y": 0, - "w": 36, + "w": 92, "h": 68 }, "frame": { "x": 0, "y": 0, - "w": 36, + "w": 92, + "h": 68 + } + }, + { + "filename": "0037.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 92, + "y": 0, + "w": 92, + "h": 68 + } + }, + { + "filename": "0039.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 92, + "y": 0, + "w": 92, + "h": 68 + } + }, + { + "filename": "0041.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 92, + "y": 0, + "w": 92, + "h": 68 + } + }, + { + "filename": "0043.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 92, + "y": 0, + "w": 92, + "h": 68 + } + }, + { + "filename": "0045.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 92, + "y": 0, + "w": 92, + "h": 68 + } + }, + { + "filename": "0046.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 92, + "y": 0, + "w": 92, + "h": 68 + } + }, + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0022.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0023.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0029.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0030.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0052.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0038.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 0, + "y": 68, + "w": 92, + "h": 68 + } + }, + { + "filename": "0042.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 0, + "y": 68, + "w": 92, + "h": 68 + } + }, + { + "filename": "0040.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 0, + "y": 136, + "w": 92, + "h": 68 + } + }, + { + "filename": "0044.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 0, + "y": 136, + "w": 92, + "h": 68 + } + }, + { + "filename": "0035.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 2, + "y": 0, + "w": 88, + "h": 68 + }, + "frame": { + "x": 92, + "y": 68, + "w": 88, + "h": 68 + } + }, + { + "filename": "0047.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 2, + "y": 0, + "w": 88, + "h": 68 + }, + "frame": { + "x": 92, + "y": 68, + "w": 88, + "h": 68 + } + }, + { + "filename": "0034.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 40, + "h": 68 + }, + "frame": { + "x": 180, + "y": 68, + "w": 40, + "h": 68 + } + }, + { + "filename": "0048.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 40, + "h": 68 + }, + "frame": { + "x": 180, + "y": 68, + "w": 40, + "h": 68 + } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 39, + "h": 68 + }, + "frame": { + "x": 92, + "y": 136, + "w": 39, + "h": 68 + } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 39, + "h": 68 + }, + "frame": { + "x": 92, + "y": 136, + "w": 39, + "h": 68 + } + }, + { + "filename": "0019.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 39, + "h": 68 + }, + "frame": { + "x": 92, + "y": 136, + "w": 39, + "h": 68 + } + }, + { + "filename": "0026.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 39, + "h": 68 + }, + "frame": { + "x": 92, + "y": 136, + "w": 39, + "h": 68 + } + }, + { + "filename": "0033.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 39, + "h": 68 + }, + "frame": { + "x": 92, + "y": 136, + "w": 39, + "h": 68 + } + }, + { + "filename": "0049.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 39, + "h": 68 + }, + "frame": { + "x": 92, + "y": 136, + "w": 39, + "h": 68 + } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0017.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0021.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0024.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0028.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0031.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0051.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0018.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0020.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0025.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0027.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0032.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0050.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, "h": 68 } } @@ -36,6 +1107,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:2774f1d6c293a696177c371795e6ba38:d35951afed6391313aa94000563ae143:f7cb0e9bb3adbe899317e6e2e306035d$" + "smartupdate": "$TexturePacker:SmartUpdate:3adad944aac48ad53efa41f8c9916d1c:ea15b954875ad08814f50cbbf849c1b3:f7cb0e9bb3adbe899317e6e2e306035d$" } } diff --git a/public/images/pokemon/back/754.png b/public/images/pokemon/back/754.png index ec44dc6326687a0e77c233c354284913bd32a6ac..66bd6a1b9758f405bbc4754bcad9fa3c6e1db256 100644 GIT binary patch delta 3613 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 delta 639 zcmV-_0)YLv9I*uVJL^@GB2*(boPD(Z)szow$GSwB~R=U<# zT+bFPwF~5zW7bXt57L~5x%C)?L(KdLuwf3NiCuJA5OR8Q*C+OCZgg9CBlxBd_%DiEc-gOni#pNLIq zlH7fqC=n^{&PGWh(hZRVLv$#S zyA7WGY=}g*o#}f_0x{-Dq>d5|;vZ7Q2)yoz+Pon0C2}VKXsReAK3JP~V%FxLhG zF}T}+k^Ctc$S#>An8-O#Y#>IAB}I5ONwy1{j1r04006@T0{{R3_kjoM0000jP)t-s0000G z5D-viBu!0CWL#63E=m7Pd6|PQf~GpO5?-+-KkYYw&@m9KPAzfav!YTCn6cSkoJL(a_X?76dl&wvgV zwh!n0=gc{ywSF_swoGQ3k{gFm^jBqnXAhWAJ`hZ(4>Fs|P28_9q`3H~)c*A*Vye_8 znSJ{%FkFu+`(}D^t*+%J?wjfL{>8`XM{;@FznHF**(k;ZwpONfKVBjOyY{hl{Fp$|+Z+_{Lxf(KI0(~y;&o~1U<)9vTN0_{C zs$s)GL4lb4yl&o{g3rVW6)aws^<&1y&gWtJps8;k2km8)8o(k#b;_n(4o*R^T)uf6 zw38cS%aS9-?PF~hX(#5((!||928y(baV|fdwvrp`T5@3Clx~q$u4roKTh{HeU%JR! zAIizMpIU~zut5WhWStTMIs1OFm0XwiCYQ@zD+YTuHuy(< z3W9a{MQ$b6|M4#N(IRCac=M`h-oBlOXV_(bR;^?cSFb+5$O4~Tq|?sLk6*oN-mWMW z_VV`2=Mx@0#nr!mc<9M6*DT^(JI*;CjmLxExl|S`ZkmR?-*Mr4$K&z0539R_Yw2_M zOs-i(x`;z3SdFXSt~k{?cgBBz)x2JP>HSY;;?N6L!`{P}ga1mOyJvFEA}`kZ&ki%u zos4ufJg});O}{!Gf4g{CtteZJvx0U!(vzyXTC7%|eXbhWT(z3JHtbc!RklYyt*a}W z%7R5Tp>kZdsET7LDm~GZy?CH8yIgYF-0EOuirFc;`uHjn{n1E|s^NoO*l+JwW*I7H zv6vgdaV4`IJt4)Sw^;aGa@kycV2YvAhPpqJS^x5QG%zG}DkLaHailNx zRrX956Ds?%H{aww(=PXDVTuu2_xqZ*Lf%SOmn!p(wS5?Airk@W3g}+yA^CJcae62r zcXDKlQJPHcT^5Q;r$BP~#tKum&+h6=5>%7oNcA;!7IP=swO;Pt&kc;%~5-QaoH2MbnfG3iprLdt6i9Q^Jx>LayKP%TH~mmi#%xovw zXl(_fxk5GhSy|^L`Ac$Qg%s+u&&o5SN?+^T5_2iAmU%gw&GLNENcf4Pq|l{YuS|h? zu4eVX31+?fI-}gPAXk))6iqYhDN&Zz$=%7#uezN1m2Kccb{e%7T+B0ZU-u~YHRbwM zW=8aEAqD-(TW-2jtJ>64dqKA{2a@0kef`uUm-+Y)S7E11&PlFOLaKZwgRQIsS@1-h zzsq_LCmF8tZ{`#86I^byn;C4y2MQM4{o(sS@Pq{YD!e}y7hEbq6XF>a=6bnMx(NXcr!X&fcxjR)Vi4T<j3kUD!Px)s6qL>+ulbJU8VF;o5x3+|0gX9>e6w5~a^*AYQLV{SumZ6Gvt z_Db}L<*5zB)#?Li#n3oxgJ)>bwI{Z(iwQNi@Mj4O(U{x7*9QK4X=(3hCL?=d(GZP& z8{pc&4u5k;Q@In1hG>j!a9g$qesf1dZA8Hc8nchD4ZNH0X#DuV5O0z4hryMD6LcpQ z4e=H!e=On3L1}+t!4PkG%Y1DBo$bfAjA)E)ko+CMg8sy!AsS;Fu(LPj#G)Y@CvFJx zQ1A$p;=Co)J+>iJgZ8Bl7MMa~!X-obirWB}J_3~@XzYE8d;#T)1}=TT5RC($GITpX zX$h8TK}2H~M7qsqohA?NXuzUqOiJFzFskxd-D%t%O-vBcI7zq7si+%!M^nxsYLJ|Q z@`Y)0b2gvL&QB3RNKVu3oe@1V{JnS))#GIJqab|=!dpIIXqb#p9tdVeaMM_(s|XAw zpxi2XL65ggS008yG!EsYWYrW35?whM0(OZ*xfgr~EpiSAL%=R6C>P2JvLOs9^)x6? zWIV44hMolFID32oe=3yY?74^T3H*srjrlA~X&mat#nTGQC z>=}d+Gt*Fxvj-3kFf$3|@!7Lr0Z-s)4CU$Bdm3WQ1cUeL=^;5{xLO)o%^xE00`Jw)*^6rIU#v&fK?Gj#y*f5~`@rm9tgA_H zwfgFo@x3}Sd-uTXU##`z(PEBj@%L(+y?~%5nBc zL*wBSpd4q9G&Gh^fO4EY(hwJzg!07f@d+FaX*4$b1P!I3JTdz;4W*$RXP=;SaqVM&I@*@rYlf)x4$hQ`?g4S`^k zp_8-kMer)c(8<}85`{{@s}w`WXCK9@G(*Q{4|w$?hQ`^a@hZ*GII09*r5QRsD#Yb9 zLVK5zFsc+TqtB~3mm&y;QKfJheSQt+A_&G&#c>&ZyoP^bgi%FtIq6gCgLO$5RRWjO zz7Dv+0GGjs5SBK?W%ThH7Q*61A}*(WDt8c8r_>Oa(HBzPa+%sS;xhV}>f&#VDO}!h zKH?enG1Voh8gZHNLm8fNKBhVVa4^JWeh4L=@jhk&0C0HjMqG9eq3&gsd>kfb6bAr~ zuhSte?-cGK)V-{dkHdtG3jrKKIK*X#fA%5N@{A%MQ?QM55QfH&haoN#*%+Sek1E46 zl`=k0!7k217#cqwhPW)cmM6QH7El%Wn1X#AK^Pi89)`F~ik2rGpcV(@V+yu$2NuH6 z`0;QHmmN%;Uo}HmL=bTq@UKr> zwqXciXo$;5ynoZ$RSgh^7Q=BiM0000jP)t-s0000G z5D-mGO;BbeWL#5%raGA}NtuH#v!RZ(2$)^p7#ZKlFb>nEeZg;$cFt zW*`^+Ifwa4FlcChe#(!<8PyaxL-bu;yK*-onoQQr5pO&i(c~a3=#-Kr zSr&cR?*^6hhNb9Ce>&{nuPw=54HOZ1d1xU!0$aG3WH4)_9Naaa`(uhr@xF^#z^}L99O(bz3N__!R*2KS0 z3%%KJFsqtu)(q~IZ)CG;$iV22v;1n2ff43E3|a(c-;002ovPDHLkV1nij2?+oI diff --git a/public/images/pokemon/back/shiny/692.json b/public/images/pokemon/back/shiny/692.json index 2dec26a2616..801710c4861 100644 --- a/public/images/pokemon/back/shiny/692.json +++ b/public/images/pokemon/back/shiny/692.json @@ -1,41 +1,794 @@ -{ - "textures": [ - { - "image": "692.png", - "format": "RGBA8888", - "size": { - "w": 56, - "h": 56 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 56, - "h": 35 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 56, - "h": 35 - }, - "frame": { - "x": 0, - "y": 0, - "w": 56, - "h": 35 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:8b2c775abfa9b635f2149e201570e6ff:f327a0cd8d92fa087869ded83baa8e41:2880def858c84cd859bedf13b0b49a33$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0002.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0003.png", + "frame": { "x": 1, "y": 36, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0004.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0005.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0006.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0007.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0008.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0009.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0010.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0011.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0012.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0013.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0014.png", + "frame": { "x": 1, "y": 36, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0015.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0016.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0017.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0018.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0019.png", + "frame": { "x": 1, "y": 36, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0020.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0021.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0022.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0023.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0024.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0025.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0026.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0027.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0028.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0029.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0030.png", + "frame": { "x": 1, "y": 36, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0031.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0032.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0033.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0034.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0035.png", + "frame": { "x": 1, "y": 36, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0036.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0037.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0038.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0039.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0040.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0041.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0042.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0043.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0044.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0045.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0046.png", + "frame": { "x": 1, "y": 36, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0047.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0048.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0049.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0050.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0051.png", + "frame": { "x": 1, "y": 36, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0052.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0053.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0054.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0055.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0056.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0057.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0058.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0059.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0060.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0061.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0062.png", + "frame": { "x": 1, "y": 36, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0063.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0064.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0065.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0066.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0067.png", + "frame": { "x": 59, "y": 37, "w": 57, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 1, "w": 57, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0068.png", + "frame": { "x": 59, "y": 37, "w": 57, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 1, "w": 57, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0069.png", + "frame": { "x": 1, "y": 72, "w": 58, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 58, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0070.png", + "frame": { "x": 1, "y": 72, "w": 58, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 58, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0071.png", + "frame": { "x": 1, "y": 72, "w": 58, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 58, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0072.png", + "frame": { "x": 1, "y": 72, "w": 58, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 58, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0073.png", + "frame": { "x": 1, "y": 72, "w": 58, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 58, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0074.png", + "frame": { "x": 60, "y": 72, "w": 58, "h": 31 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 4, "w": 58, "h": 31 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0075.png", + "frame": { "x": 119, "y": 72, "w": 56, "h": 31 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 4, "w": 56, "h": 31 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0076.png", + "frame": { "x": 60, "y": 72, "w": 58, "h": 31 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 4, "w": 58, "h": 31 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0077.png", + "frame": { "x": 1, "y": 72, "w": 58, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 58, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0078.png", + "frame": { "x": 1, "y": 72, "w": 58, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 58, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0079.png", + "frame": { "x": 1, "y": 72, "w": 58, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 58, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0080.png", + "frame": { "x": 1, "y": 72, "w": 58, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 58, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0081.png", + "frame": { "x": 1, "y": 72, "w": 58, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 58, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0082.png", + "frame": { "x": 1, "y": 72, "w": 58, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 58, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0083.png", + "frame": { "x": 1, "y": 72, "w": 58, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 58, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0084.png", + "frame": { "x": 59, "y": 37, "w": 57, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 1, "w": 57, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0085.png", + "frame": { "x": 59, "y": 37, "w": 57, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 1, "w": 57, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0086.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0087.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.12-x64", + "image": "692.png", + "format": "I8", + "size": { "w": 181, "h": 106 }, + "scale": "1" + } } diff --git a/public/images/pokemon/back/shiny/692.png b/public/images/pokemon/back/shiny/692.png index 7459aabd207d6e05e7d533fe0daf144a7e619cd7..dfad01dd44659d0f5ce9c3a42fdc114c166f3250 100644 GIT binary patch literal 2025 zcmV0000aP)t-s0000G z5D+3*bHBg8`1treoXkwa|BOg6zhXoGgIP^YP5-Hku?;U90000CbW%=J0RR90|NsC0 z|NsC03B*t)000MQNklJ;g3Ofgf_qtjKfw!4963&$U${)0YkQtk(->(R_h>q3jr7KXAYVdy7!~76; zhMIV>YTKmWc5Z|k#hySz=FSUE54DNC%%I`*T8-!n8aK0k!kIbnTF?oM{Wd_2D?82^ z3h}mW$8kuoM>tH>2z?u7jOes20ghwe_wziT3kNvEah<5GnuE&4YS3`F>lcV+pI^6Q zfIn?d@Z4@`%@pdZ)`?Z4;Rqjd)#umOc!U5&xPw@=NUsj65vxPParmFk3Cf0TgE;AM z=7j;NUOiMH7K47h4(AWpw(Yzf04}IMF*VD7lq1Sb-s*Z*8RmaisT!mg8R3TQ6?%}C!1`l~Jc(mV9 z4cbo*nyT}5fPH(ay3q?*=q414C-zIkRlflwvSwvvG?DlMds`aq%Sue@00??ZH&R@_|Gr6*ZH^{NU#keJcy(kKi$hAuZ^ zfd?0~W6`uk`fp)b5Nc22;-bonccfQ@rk-v=q!v0B3(=&F&WjvZ^MeBv1dC-Kem((% zOCzraRxf}(URwej0s85oBeCMY`7r}=m~)sbgJ#RV>Q3CyEscl86_EbJ;&*2rA@=9d zFH7h=qu3%Xx}01zreIdDeZ%FujG=>LM|2(^Wg2`rSKQ6_sDip19dx`SwB^uHe<$x^ zv|;C|r;46Cev7(%vrZ-sKT1m+d#!0T70TFY6Y6Ee&xA4)v>Ej_mz|>#1F@a9!K;m6 zn8*nxXlKbwHe!h3rsnKnXnw2L2v$8|*Q;qeyjJY8vZu(Ra4FNPA@AXgO=+?PH<8_=!YAFe$m zk`>};wZGt`F~MCxF+&^Rt?TZbFj>jOx$HXJIKS?56*FywcdolISxH|2ST?jV!F_gS zrH$y$vlk{SkX^!9^;W_Sj0wg8g`GB|8@peatl*!Kwu=eI0fn75qIPSX?R< zOot$^Pg`_wp1hE11ar6Aa78W|l=n`O?^Ns`S>Y2euHb7JsnH6_(zYnRleTPpheMx6 zm6Sp)**nmcXY>m6*4t#Ll{*9AOgV*GvJ8dFY>Q^d$hP9kj+vIY&BS-tN`_E4y1PbE z*+s8#l_PF5P~TlA8G-Wmx=&S8y;N;Z_fnZ$BN>7ECJSw=kzT4c=Ubst%`BgwO)!gm-gg)YpG<=LR*XQ z@#dz{YZJE_PJ!>vN(N^Oy^wUal4l_+y_~eozlf(n?N#R1XoaS z;Ii9xTQ{(J3EEs)-_+H0kCIhJa0PYIdIH{fqDAw1J+!&8zLPr}EbLS`CmAGzuZKo( z_M`lXH&s*5zMk~B&7AcOk(Ti?-yP6OWZl85BOuNQX7V8N>atY@FhcUQjQ z*quSl++}gu;TKg+9+LNm5xd3h5I{wL`|N7$(OhcTMne(n~00000NkvXX Hu0mjfmxbn~ literal 478 zcmV<40U`d0P)WS^uew*M9dZ00001bW%=J06^y0W&i*I zXh}ptRCr$P&aqCzFc1b{`we^wZIVt=2Oc1icmUu9GIXblk-B;5N!`4Vh>fl8#?nY; z@50M*=QNNahmol_IEp^~zkcz3vgn`a$@_wzIEtH+pQ-5MpHTw&Fdd!l6-gQ56Va-e z-mA5qMDX5gN=MB((sdN2bF5vWBA8i<9(-paC~b;djHpEWqJQDScbK~d5i}L(rwgPp zXxawnJD=0C(^&HZA!e=F_<$d$i>-%_alWAf>h+&LQOKPmG;MOn@9Q`!{d*W=Y!$FU z(jmI=-s}S|Z+pa@Cmg1BS&N7;BuS5>sf=cXcpRpBE<-b`m(Sn09i}#n04t~nse{ji zVBce)-h$NFqX7t*(l1x8QdIoI2#N}Y1ZWu{oz;MbkbB@f)Y+`r0@S#sm=TiE7H53R zEC4D_F$$oXq+AA+`Q8fI1Aj>~TUF&bx>rJ~5%LUBJxbtrNQw9{PM;G0de^(&7l6;I UI}(g#6#xJL07*qoM6N<$f|E1W4gdfE diff --git a/public/images/pokemon/back/shiny/693.json b/public/images/pokemon/back/shiny/693.json index 6c1d41485e9..6358a8908f6 100644 --- a/public/images/pokemon/back/shiny/693.json +++ b/public/images/pokemon/back/shiny/693.json @@ -1,41 +1,902 @@ -{ - "textures": [ - { - "image": "693.png", - "format": "RGBA8888", - "size": { - "w": 90, - "h": 90 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 90, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 90, - "h": 70 - }, - "frame": { - "x": 0, - "y": 0, - "w": 90, - "h": 70 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:e4bbb1dc7d71678d99aa6c088ee2dda6:9e2c014adc4489792adb3203513e62b4:9c1f9147e693c05eb4655590e9099679$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0002.png", + "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0003.png", + "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0004.png", + "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0005.png", + "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0006.png", + "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0007.png", + "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0008.png", + "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0009.png", + "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0010.png", + "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0011.png", + "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0012.png", + "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0013.png", + "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0014.png", + "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0015.png", + "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0016.png", + "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0017.png", + "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0018.png", + "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0019.png", + "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0020.png", + "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0021.png", + "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0022.png", + "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0023.png", + "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0024.png", + "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0025.png", + "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0026.png", + "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0027.png", + "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0028.png", + "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0029.png", + "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0030.png", + "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0031.png", + "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0032.png", + "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0033.png", + "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0034.png", + "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0035.png", + "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0036.png", + "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0037.png", + "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0038.png", + "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0039.png", + "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0040.png", + "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0041.png", + "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0042.png", + "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0043.png", + "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0044.png", + "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0045.png", + "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0046.png", + "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0047.png", + "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0048.png", + "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0049.png", + "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0050.png", + "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0051.png", + "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0052.png", + "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0053.png", + "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0054.png", + "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0055.png", + "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0056.png", + "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0057.png", + "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0058.png", + "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0059.png", + "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0060.png", + "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0061.png", + "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0062.png", + "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0063.png", + "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0064.png", + "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0065.png", + "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0066.png", + "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0067.png", + "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0068.png", + "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0069.png", + "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0070.png", + "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0071.png", + "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0072.png", + "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0073.png", + "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0074.png", + "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0075.png", + "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0076.png", + "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0077.png", + "frame": { "x": 565, "y": 196, "w": 90, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 6, "w": 90, "h": 65 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0078.png", + "frame": { "x": 278, "y": 266, "w": 90, "h": 59 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 10, "w": 90, "h": 59 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0079.png", + "frame": { "x": 189, "y": 199, "w": 95, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 8, "w": 95, "h": 61 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0080.png", + "frame": { "x": 193, "y": 1, "w": 98, "h": 68 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 3, "w": 98, "h": 68 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0081.png", + "frame": { "x": 1, "y": 71, "w": 94, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 65 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0082.png", + "frame": { "x": 469, "y": 196, "w": 96, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 12, "w": 96, "h": 61 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0083.png", + "frame": { "x": 1, "y": 1, "w": 98, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 13, "y": 5, "w": 98, "h": 70 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0084.png", + "frame": { "x": 1, "y": 136, "w": 94, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 10, "w": 94, "h": 63 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0085.png", + "frame": { "x": 95, "y": 72, "w": 96, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 15, "y": 12, "w": 96, "h": 63 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0086.png", + "frame": { "x": 381, "y": 1, "w": 97, "h": 67 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 6, "w": 97, "h": 67 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0087.png", + "frame": { "x": 1, "y": 71, "w": 94, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 65 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0088.png", + "frame": { "x": 469, "y": 196, "w": 96, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 12, "w": 96, "h": 61 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0089.png", + "frame": { "x": 1, "y": 1, "w": 98, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 13, "y": 5, "w": 98, "h": 70 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0090.png", + "frame": { "x": 191, "y": 136, "w": 94, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 10, "w": 94, "h": 63 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0091.png", + "frame": { "x": 95, "y": 135, "w": 96, "h": 62 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 11, "w": 96, "h": 62 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0092.png", + "frame": { "x": 572, "y": 67, "w": 99, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 7, "w": 99, "h": 65 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0093.png", + "frame": { "x": 284, "y": 205, "w": 95, "h": 61 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 11, "w": 95, "h": 61 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0094.png", + "frame": { "x": 1, "y": 199, "w": 91, "h": 60 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 18, "y": 12, "w": 91, "h": 60 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0095.png", + "frame": { "x": 1, "y": 259, "w": 95, "h": 60 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 15, "y": 12, "w": 95, "h": 60 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0096.png", + "frame": { "x": 193, "y": 69, "w": 95, "h": 67 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 15, "y": 5, "w": 95, "h": 67 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0097.png", + "frame": { "x": 285, "y": 141, "w": 92, "h": 64 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 18, "y": 8, "w": 92, "h": 64 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0098.png", + "frame": { "x": 96, "y": 318, "w": 89, "h": 58 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 22, "y": 14, "w": 89, "h": 58 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + }, + { + "filename": "0099.png", + "frame": { "x": 564, "y": 261, "w": 92, "h": 58 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 19, "y": 14, "w": 92, "h": 58 }, + "sourceSize": { "w": 111, "h": 83 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.12-x64", + "image": "693.png", + "format": "I8", + "size": { "w": 672, "h": 377 }, + "scale": "1" + } } diff --git a/public/images/pokemon/back/shiny/693.png b/public/images/pokemon/back/shiny/693.png index 47715b534bdd4894f6270acef17d166dd5950a85..6884c2e28c7cc0a973f46300b758328f9b60c0f1 100644 GIT binary patch literal 21707 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 diff --git a/public/images/pokemon/back/shiny/753.json b/public/images/pokemon/back/shiny/753.json index 70c1091b725..f1d1bc11bb0 100644 --- a/public/images/pokemon/back/shiny/753.json +++ b/public/images/pokemon/back/shiny/753.json @@ -4,29 +4,2570 @@ "image": "753.png", "format": "RGBA8888", "size": { - "w": 45, - "h": 45 + "w": 140, + "h": 140 }, "scale": 1, "frames": [ { - "filename": "0001.png", + "filename": "0019.png", "rotated": false, - "trimmed": false, + "trimmed": true, "sourceSize": { - "w": 28, - "h": 45 + "w": 31, + "h": 53 }, "spriteSourceSize": { "x": 0, - "y": 0, - "w": 28, - "h": 45 + "y": 5, + "w": 31, + "h": 47 }, "frame": { "x": 0, "y": 0, + "w": 31, + "h": 47 + } + }, + { + "filename": "0020.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 31, + "h": 47 + } + }, + { + "filename": "0027.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 31, + "h": 47 + } + }, + { + "filename": "0028.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 31, + "h": 47 + } + }, + { + "filename": "0053.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 31, + "h": 47 + } + }, + { + "filename": "0054.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 31, + "h": 47 + } + }, + { + "filename": "0061.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 31, + "h": 47 + } + }, + { + "filename": "0062.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 31, + "h": 47 + } + }, + { + "filename": "0087.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 31, + "h": 47 + } + }, + { + "filename": "0088.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 31, + "h": 47 + } + }, + { + "filename": "0095.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 31, + "h": 47 + } + }, + { + "filename": "0096.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 31, + "h": 47 + } + }, + { + "filename": "0021.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 47, + "w": 31, + "h": 47 + } + }, + { + "filename": "0022.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 47, + "w": 31, + "h": 47 + } + }, + { + "filename": "0025.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 47, + "w": 31, + "h": 47 + } + }, + { + "filename": "0026.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 47, + "w": 31, + "h": 47 + } + }, + { + "filename": "0055.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 47, + "w": 31, + "h": 47 + } + }, + { + "filename": "0056.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 47, + "w": 31, + "h": 47 + } + }, + { + "filename": "0059.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 47, + "w": 31, + "h": 47 + } + }, + { + "filename": "0060.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 47, + "w": 31, + "h": 47 + } + }, + { + "filename": "0089.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 47, + "w": 31, + "h": 47 + } + }, + { + "filename": "0090.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 47, + "w": 31, + "h": 47 + } + }, + { + "filename": "0093.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 47, + "w": 31, + "h": 47 + } + }, + { + "filename": "0094.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 31, + "h": 47 + }, + "frame": { + "x": 0, + "y": 47, + "w": 31, + "h": 47 + } + }, + { + "filename": "0023.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 31, + "h": 46 + }, + "frame": { + "x": 0, + "y": 94, + "w": 31, + "h": 46 + } + }, + { + "filename": "0024.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 31, + "h": 46 + }, + "frame": { + "x": 0, + "y": 94, + "w": 31, + "h": 46 + } + }, + { + "filename": "0057.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 31, + "h": 46 + }, + "frame": { + "x": 0, + "y": 94, + "w": 31, + "h": 46 + } + }, + { + "filename": "0058.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 31, + "h": 46 + }, + "frame": { + "x": 0, + "y": 94, + "w": 31, + "h": 46 + } + }, + { + "filename": "0091.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 31, + "h": 46 + }, + "frame": { + "x": 0, + "y": 94, + "w": 31, + "h": 46 + } + }, + { + "filename": "0092.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 31, + "h": 46 + }, + "frame": { + "x": 0, + "y": 94, + "w": 31, + "h": 46 + } + }, + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0017.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0018.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0029.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0030.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0031.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0032.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0033.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0034.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0035.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0036.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0047.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0048.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0049.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0050.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0051.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0052.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0063.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0064.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0065.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0066.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0067.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0068.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0069.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0070.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0081.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0082.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0083.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0084.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0085.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0086.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0097.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0098.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0099.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0100.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0101.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0102.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0110.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0111.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0112.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0120.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0121.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0122.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 47, + "w": 30, + "h": 47 + } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 47, + "w": 30, + "h": 47 + } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 47, + "w": 30, + "h": 47 + } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 47, + "w": 30, + "h": 47 + } + }, + { + "filename": "0037.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 47, + "w": 30, + "h": 47 + } + }, + { + "filename": "0038.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 47, + "w": 30, + "h": 47 + } + }, + { + "filename": "0045.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 47, + "w": 30, + "h": 47 + } + }, + { + "filename": "0046.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 47, + "w": 30, + "h": 47 + } + }, + { + "filename": "0071.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 47, + "w": 30, + "h": 47 + } + }, + { + "filename": "0072.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 47, + "w": 30, + "h": 47 + } + }, + { + "filename": "0079.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 47, + "w": 30, + "h": 47 + } + }, + { + "filename": "0080.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 31, + "y": 47, + "w": 30, + "h": 47 + } + }, + { + "filename": "0109.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 7, + "w": 30, + "h": 46 + }, + "frame": { + "x": 31, + "y": 94, + "w": 30, + "h": 46 + } + }, + { + "filename": "0119.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 7, + "w": 30, + "h": 46 + }, + "frame": { + "x": 31, + "y": 94, + "w": 30, + "h": 46 + } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 30, + "h": 47 + }, + "frame": { + "x": 61, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 30, + "h": 47 + }, + "frame": { + "x": 61, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 30, + "h": 47 + }, + "frame": { + "x": 61, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 30, + "h": 47 + }, + "frame": { + "x": 61, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0039.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 30, + "h": 47 + }, + "frame": { + "x": 61, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0040.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 30, + "h": 47 + }, + "frame": { + "x": 61, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0043.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 30, + "h": 47 + }, + "frame": { + "x": 61, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0044.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 30, + "h": 47 + }, + "frame": { + "x": 61, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0073.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 30, + "h": 47 + }, + "frame": { + "x": 61, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0074.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 30, + "h": 47 + }, + "frame": { + "x": 61, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0077.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 30, + "h": 47 + }, + "frame": { + "x": 61, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0078.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 30, + "h": 47 + }, + "frame": { + "x": 61, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0103.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 2, + "w": 29, + "h": 47 + }, + "frame": { + "x": 91, + "y": 0, + "w": 29, + "h": 47 + } + }, + { + "filename": "0104.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 2, + "w": 29, + "h": 47 + }, + "frame": { + "x": 91, + "y": 0, + "w": 29, + "h": 47 + } + }, + { + "filename": "0113.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 2, + "w": 29, + "h": 47 + }, + "frame": { + "x": 91, + "y": 0, + "w": 29, + "h": 47 + } + }, + { + "filename": "0114.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 2, + "w": 29, + "h": 47 + }, + "frame": { + "x": 91, + "y": 0, + "w": 29, + "h": 47 + } + }, + { + "filename": "0107.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 4, + "w": 29, + "h": 47 + }, + "frame": { + "x": 61, + "y": 47, + "w": 29, + "h": 47 + } + }, + { + "filename": "0108.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 4, + "w": 29, + "h": 47 + }, + "frame": { + "x": 61, + "y": 47, + "w": 29, + "h": 47 + } + }, + { + "filename": "0117.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 4, + "w": 29, + "h": 47 + }, + "frame": { + "x": 61, + "y": 47, + "w": 29, + "h": 47 + } + }, + { + "filename": "0118.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 4, + "w": 29, + "h": 47 + }, + "frame": { + "x": 61, + "y": 47, + "w": 29, + "h": 47 + } + }, + { + "filename": "0105.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 0, "w": 28, + "h": 46 + }, + "frame": { + "x": 61, + "y": 94, + "w": 28, + "h": 46 + } + }, + { + "filename": "0106.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 0, + "w": 28, + "h": 46 + }, + "frame": { + "x": 61, + "y": 94, + "w": 28, + "h": 46 + } + }, + { + "filename": "0115.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 0, + "w": 28, + "h": 46 + }, + "frame": { + "x": 61, + "y": 94, + "w": 28, + "h": 46 + } + }, + { + "filename": "0116.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 1, + "y": 0, + "w": 28, + "h": 46 + }, + "frame": { + "x": 61, + "y": 94, + "w": 28, + "h": 46 + } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 8, + "w": 29, + "h": 45 + }, + "frame": { + "x": 89, + "y": 94, + "w": 29, + "h": 45 + } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 8, + "w": 29, + "h": 45 + }, + "frame": { + "x": 89, + "y": 94, + "w": 29, + "h": 45 + } + }, + { + "filename": "0041.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 8, + "w": 29, + "h": 45 + }, + "frame": { + "x": 89, + "y": 94, + "w": 29, + "h": 45 + } + }, + { + "filename": "0042.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 8, + "w": 29, + "h": 45 + }, + "frame": { + "x": 89, + "y": 94, + "w": 29, + "h": 45 + } + }, + { + "filename": "0075.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 8, + "w": 29, + "h": 45 + }, + "frame": { + "x": 89, + "y": 94, + "w": 29, + "h": 45 + } + }, + { + "filename": "0076.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 31, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 8, + "w": 29, + "h": 45 + }, + "frame": { + "x": 89, + "y": 94, + "w": 29, "h": 45 } } @@ -36,6 +2577,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:f2829e1ebd212cc5203393968a2efd5f:dd79bfe2b6a61007ace9092be7975ffe:16c1874bc814253ca78e52a99a340ff7$" + "smartupdate": "$TexturePacker:SmartUpdate:b6d27dc4e44833805071498f628d15c3:7ab61edae9d3eecb963334bb47dd5aa7:16c1874bc814253ca78e52a99a340ff7$" } } diff --git a/public/images/pokemon/back/shiny/753.png b/public/images/pokemon/back/shiny/753.png index aadcbe3fa04508f4a2949cc97e86a058b1027008..14f23fc6bb90dfa52bcfab1a181053d58bc48518 100644 GIT binary patch delta 2054 zcmV+h2>JK91C020 ze|niczrVlCy>R&W`2X;xcn<2A00001bW%=J06^y0W&i*Okx4{BRCr#^nL%sZRuqNx zYFtWJQpZutcw-cU3#KrxQZe-qAhuw-v?=W-t7PCILN_r3vkeHs>re193?mxqQB!jluD2a{An{4;tLsHP}PP zNWD1oNmGzq{xP~{TCc&cV?plnnrZ3mjm_etvc+oOah(yVsYz{3I>uOPYtpp5f5KcE z+Dp^GM-`+n*!n0yH`oI?M$KJ2w1;l;1Y|f#%Q=@26!HNIbA`DyuxE`}*KBm0=o%Y@ zE3Qjp_u}+?s800P#3&!6vC4H#48e1A#dT@yo_a7;YJfFErI*f?%F&*v94?qEu4{+( zRQ@v4HA3knHI!!Y8-*9l700Eaf4y8vZ3vmcQl=7_4N!*?FPJOLr7?RlgPIr}A!U|G z35%21*b*##g}XFn4{PApmD(&0RarZc^$d5wURt`CGk4JJRO*b16p&N>3~X`Zw)J^<%NR4DsX0e+_SHH757$?MmlB zE=ma&$kW$Q13&8SLckHxvo7SSEoE+Db7H=j7q>x@EZp{>ZL9fZ2chff(J zM6pCOZX+K)9E7^bhtDQ4>AhJ#Qy`S9T&)ImONv%4+%@c9_>*@9sHubS=2=Yv70 zc__C%`EU^WF!JFb^hce1j$6ow59JQ)jB?gZK5ZbxbH2kxT{ThU#e*98Xeo({I{r~$ z?hF_uQ@JIde?!QD1SL0I1hTaTbKj1DQKYiu^AuX^Tog#zRzr(xiEv}d2Z1IVRJcfj zY^{lrb<_yh2H*yO#?%xc-VYi1G=B}&WDnO~Aa8WdNdh?}pBfkSZ(3^>@Y%QW25KOr zf#w8rD?k>kA@Yg6wi-mH+h;cqkzjPqd>>E;$!A_8e;)y=WrEYi50|HN4JCjBub^fL zHEXD-kx$q37o%k`w@~8ueep~G1Zo%;wU2lOL=yNFpegz%Hb>;sISgw8;Rl}>`D{-x zUc_>YV3^(ZAjET=U?Q-)9)u{z35Hl;N|HSYu^b~9VuQ-Mv*)uMBNze`RzrJCGlJom z#0e&Fe{{pkPD+@>YRn$XF@h06Q1T7cP|WNFEXN4OkVuJ1G!&bbh{AJ3FqTA!zAA&U zDefgc%Q*xCu9Yd_6@4|%5D>-5F@gz)`R0g6WBbox4^hL(@s}M1@&ULmUWF24!-f|j zmtX`?zNgd&z>1S1d%j*GkRE}B7Tc0f5!Ft+9l?W-mb zLi%Aj#y7eK{4s+x@~DQ$hu&_KmeCFg2DSv}L&q5aAOHMaLxw znVcmU&!R^tu~m!juhD$rd`k!+paKIze>I@Va;jM(i0l|Fxi0>c>~p}8SaYjEDBRST z7a>b9AeGnC;&*u10ZQUE9E9?fdD+3FA(+oW^%inq-iI#TUnS&g4MHOWLY92WmmP1% z63mytGx1_R0C5dmB3&%%GZ50b3y@f22}aDphvMD>YS!Mutr5xV$r7G~3<%+iSkS$n zA&0U`FrtTafv19?;15Fj;AL+CJY^nSGzh^@WCUY;{Hg%{-dE!bY6lSV`zLz>%07*qoM6N<$f_ZDV-~a#s delta 421 zcmV;W0b2fz5V->-iBL{Q4GJ0x0000DNk~Le0000j0000j2m=5B01dv=-?684@Ki~zoO@4cqpo(` zOBv~6!@K7q8N)!!xFySoIOcbagI1jTEhKbSe>ttNG(g93;IQ)mq$QCgraIF-ln?r* zhdu`Hq^Ssp{;9m z&GpFF9cue2MOS^idefozO$OJXX||=fJOs#@r>$tYD-iJ%Sis)Ub?wC;fJzj3#7xe0 P00000NkvXXu0mjfr3Jw4 diff --git a/public/images/pokemon/back/shiny/754.json b/public/images/pokemon/back/shiny/754.json index 10165ba4b4a..8b1a3d44a4d 100644 --- a/public/images/pokemon/back/shiny/754.json +++ b/public/images/pokemon/back/shiny/754.json @@ -4,29 +4,1121 @@ "image": "754.png", "format": "RGBA8888", "size": { - "w": 68, - "h": 68 + "w": 222, + "h": 222 }, "scale": 1, "frames": [ { - "filename": "0001.png", + "filename": "0036.png", "rotated": false, "trimmed": false, "sourceSize": { - "w": 36, + "w": 92, "h": 68 }, "spriteSourceSize": { "x": 0, "y": 0, - "w": 36, + "w": 92, "h": 68 }, "frame": { "x": 0, "y": 0, - "w": 36, + "w": 92, + "h": 68 + } + }, + { + "filename": "0037.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 92, + "y": 0, + "w": 92, + "h": 68 + } + }, + { + "filename": "0039.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 92, + "y": 0, + "w": 92, + "h": 68 + } + }, + { + "filename": "0041.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 92, + "y": 0, + "w": 92, + "h": 68 + } + }, + { + "filename": "0043.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 92, + "y": 0, + "w": 92, + "h": 68 + } + }, + { + "filename": "0045.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 92, + "y": 0, + "w": 92, + "h": 68 + } + }, + { + "filename": "0046.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 92, + "y": 0, + "w": 92, + "h": 68 + } + }, + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0022.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0023.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0029.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0030.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0052.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0053.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 184, + "y": 0, + "w": 38, + "h": 68 + } + }, + { + "filename": "0038.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 0, + "y": 68, + "w": 92, + "h": 68 + } + }, + { + "filename": "0042.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 0, + "y": 68, + "w": 92, + "h": 68 + } + }, + { + "filename": "0040.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 0, + "y": 136, + "w": 92, + "h": 68 + } + }, + { + "filename": "0044.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 92, + "h": 68 + }, + "frame": { + "x": 0, + "y": 136, + "w": 92, + "h": 68 + } + }, + { + "filename": "0035.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 2, + "y": 0, + "w": 88, + "h": 68 + }, + "frame": { + "x": 92, + "y": 68, + "w": 88, + "h": 68 + } + }, + { + "filename": "0047.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 2, + "y": 0, + "w": 88, + "h": 68 + }, + "frame": { + "x": 92, + "y": 68, + "w": 88, + "h": 68 + } + }, + { + "filename": "0034.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 40, + "h": 68 + }, + "frame": { + "x": 180, + "y": 68, + "w": 40, + "h": 68 + } + }, + { + "filename": "0048.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 40, + "h": 68 + }, + "frame": { + "x": 180, + "y": 68, + "w": 40, + "h": 68 + } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 39, + "h": 68 + }, + "frame": { + "x": 92, + "y": 136, + "w": 39, + "h": 68 + } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 39, + "h": 68 + }, + "frame": { + "x": 92, + "y": 136, + "w": 39, + "h": 68 + } + }, + { + "filename": "0019.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 39, + "h": 68 + }, + "frame": { + "x": 92, + "y": 136, + "w": 39, + "h": 68 + } + }, + { + "filename": "0026.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 39, + "h": 68 + }, + "frame": { + "x": 92, + "y": 136, + "w": 39, + "h": 68 + } + }, + { + "filename": "0033.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 39, + "h": 68 + }, + "frame": { + "x": 92, + "y": 136, + "w": 39, + "h": 68 + } + }, + { + "filename": "0049.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 39, + "h": 68 + }, + "frame": { + "x": 92, + "y": 136, + "w": 39, + "h": 68 + } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0017.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0021.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0024.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0028.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0031.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0051.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 131, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0018.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0020.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0025.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0027.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0032.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, + "h": 68 + } + }, + { + "filename": "0050.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 92, + "h": 68 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 38, + "h": 68 + }, + "frame": { + "x": 169, + "y": 136, + "w": 38, "h": 68 } } @@ -36,6 +1128,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:fb4a59b5a68751679b02829509901f6d:d3641a5857a0273c94152df891d4cf5c:f7cb0e9bb3adbe899317e6e2e306035d$" + "smartupdate": "$TexturePacker:SmartUpdate:7651b73927071f2814265b66582a8d13:a2d1ef3cf0c2458640f77c2fbcc821a0:f7cb0e9bb3adbe899317e6e2e306035d$" } } diff --git a/public/images/pokemon/back/shiny/754.png b/public/images/pokemon/back/shiny/754.png index 47a582ff7883f33d7326488abffb40e3af06501a..1f7346ed822ae7a5f5d53874880134a108d990c8 100644 GIT binary patch delta 3613 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 delta 640 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 P00000NkvXXu0mjfca=Sz diff --git a/public/images/pokemon/exp/692.json b/public/images/pokemon/exp/692.json deleted file mode 100644 index 86b535260ae..00000000000 --- a/public/images/pokemon/exp/692.json +++ /dev/null @@ -1,794 +0,0 @@ -{ "frames": [ - { - "filename": "0001.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0002.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0003.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0004.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0005.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0006.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0007.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0008.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0009.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0010.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0011.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0012.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0013.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0014.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0015.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0016.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0017.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0018.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0019.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0020.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0021.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0022.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0023.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0024.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0025.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0026.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0027.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0028.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0029.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0030.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0031.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0032.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0033.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0034.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0035.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0036.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0037.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0038.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0039.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0040.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0041.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0042.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0043.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0044.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0045.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0046.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0047.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0048.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0049.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0050.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0051.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0052.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0053.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0054.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0055.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0056.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0057.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0058.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0059.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0060.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0061.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0062.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0063.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0064.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0065.png", - "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0066.png", - "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0067.png", - "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0068.png", - "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0069.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0070.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0071.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0072.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0073.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0074.png", - "frame": { "x": 1, "y": 71, "w": 57, "h": 33 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 33 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0075.png", - "frame": { "x": 1, "y": 71, "w": 57, "h": 33 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 33 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0076.png", - "frame": { "x": 117, "y": 72, "w": 59, "h": 33 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 59, "h": 33 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0077.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0078.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0079.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0080.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0081.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0082.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0083.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0084.png", - "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0085.png", - "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0086.png", - "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0087.png", - "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - } - ], - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.12-x64", - "image": "692.png", - "format": "I8", - "size": { "w": 239, "h": 106 }, - "scale": "1" - } -} diff --git a/public/images/pokemon/exp/692.png b/public/images/pokemon/exp/692.png deleted file mode 100644 index daa9db0a203be7bfe9b81f0f8ac9199b1f7ef65b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2580 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 U6<`(rIRF3v07*qoM6N<$f?TKLMgRZ+ diff --git a/public/images/pokemon/exp/754.json b/public/images/pokemon/exp/754.json deleted file mode 100644 index 64490baa49f..00000000000 --- a/public/images/pokemon/exp/754.json +++ /dev/null @@ -1,1133 +0,0 @@ -{ - "textures": [ - { - "image": "754.png", - "format": "RGBA8888", - "size": { - "w": 234, - "h": 234 - }, - "scale": 1, - "frames": [ - { - "filename": "0036.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 0, - "y": 68, - "w": 93, - "h": 68 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 0, - "y": 68, - "w": 93, - "h": 68 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 68, - "w": 93, - "h": 68 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 85, - "h": 68 - }, - "frame": { - "x": 0, - "y": 136, - "w": 85, - "h": 68 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 85, - "h": 68 - }, - "frame": { - "x": 0, - "y": 136, - "w": 85, - "h": 68 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 133, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 133, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 133, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 133, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 133, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 133, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 181, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 181, - "y": 136, - "w": 48, - "h": 68 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:f79fcee4451cea6aad915f561b31bf78:95fdb55190edb6ce0d5847a4e46b4d5c:f7cb0e9bb3adbe899317e6e2e306035d$" - } -} diff --git a/public/images/pokemon/exp/754.png b/public/images/pokemon/exp/754.png deleted file mode 100644 index f6410e02a1137c8c8ec3cc4103ddd52c1cbacafa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3754 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 diff --git a/public/images/pokemon/exp/back/672.json b/public/images/pokemon/exp/back/672.json deleted file mode 100644 index f877b9abc2e..00000000000 --- a/public/images/pokemon/exp/back/672.json +++ /dev/null @@ -1,479 +0,0 @@ -{ "frames": [ - { - "filename": "0001.png", - "frame": { "x": 120, "y": 0, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0002.png", - "frame": { "x": 118, "y": 97, "w": 40, "h": 49 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 9, "w": 40, "h": 49 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0003.png", - "frame": { "x": 41, "y": 98, "w": 40, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 10, "w": 40, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0004.png", - "frame": { "x": 78, "y": 0, "w": 42, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 10, "w": 42, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0005.png", - "frame": { "x": 118, "y": 50, "w": 42, "h": 47 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 11, "w": 42, "h": 47 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0006.png", - "frame": { "x": 0, "y": 56, "w": 41, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 10, "w": 41, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0007.png", - "frame": { "x": 0, "y": 104, "w": 40, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 10, "w": 40, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0008.png", - "frame": { "x": 40, "y": 146, "w": 39, "h": 49 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 9, "w": 39, "h": 49 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0009.png", - "frame": { "x": 78, "y": 48, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0010.png", - "frame": { "x": 120, "y": 0, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0011.png", - "frame": { "x": 120, "y": 0, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0012.png", - "frame": { "x": 118, "y": 97, "w": 40, "h": 49 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 9, "w": 40, "h": 49 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0013.png", - "frame": { "x": 41, "y": 98, "w": 40, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 10, "w": 40, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0014.png", - "frame": { "x": 78, "y": 0, "w": 42, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 10, "w": 42, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0015.png", - "frame": { "x": 118, "y": 50, "w": 42, "h": 47 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 11, "w": 42, "h": 47 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0016.png", - "frame": { "x": 0, "y": 56, "w": 41, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 10, "w": 41, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0017.png", - "frame": { "x": 0, "y": 104, "w": 40, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 10, "w": 40, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0018.png", - "frame": { "x": 40, "y": 146, "w": 39, "h": 49 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 9, "w": 39, "h": 49 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0019.png", - "frame": { "x": 78, "y": 48, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0020.png", - "frame": { "x": 120, "y": 0, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0021.png", - "frame": { "x": 120, "y": 0, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0022.png", - "frame": { "x": 118, "y": 97, "w": 40, "h": 49 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 9, "w": 40, "h": 49 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0023.png", - "frame": { "x": 41, "y": 98, "w": 40, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 10, "w": 40, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0024.png", - "frame": { "x": 78, "y": 0, "w": 42, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 10, "w": 42, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0025.png", - "frame": { "x": 118, "y": 50, "w": 42, "h": 47 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 11, "w": 42, "h": 47 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0026.png", - "frame": { "x": 0, "y": 56, "w": 41, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 10, "w": 41, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0027.png", - "frame": { "x": 0, "y": 104, "w": 40, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 10, "w": 40, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0028.png", - "frame": { "x": 40, "y": 146, "w": 39, "h": 49 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 9, "w": 39, "h": 49 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0029.png", - "frame": { "x": 78, "y": 48, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0030.png", - "frame": { "x": 120, "y": 0, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0031.png", - "frame": { "x": 120, "y": 0, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0032.png", - "frame": { "x": 118, "y": 97, "w": 40, "h": 49 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 9, "w": 40, "h": 49 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0033.png", - "frame": { "x": 41, "y": 98, "w": 40, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 10, "w": 40, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0034.png", - "frame": { "x": 78, "y": 0, "w": 42, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 10, "w": 42, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0035.png", - "frame": { "x": 118, "y": 50, "w": 42, "h": 47 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 11, "w": 42, "h": 47 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0036.png", - "frame": { "x": 0, "y": 56, "w": 41, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 10, "w": 41, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0037.png", - "frame": { "x": 0, "y": 104, "w": 40, "h": 48 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 10, "w": 40, "h": 48 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0038.png", - "frame": { "x": 40, "y": 146, "w": 39, "h": 49 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 9, "w": 39, "h": 49 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0039.png", - "frame": { "x": 78, "y": 48, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0040.png", - "frame": { "x": 120, "y": 0, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0041.png", - "frame": { "x": 120, "y": 0, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0042.png", - "frame": { "x": 39, "y": 0, "w": 39, "h": 53 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 5, "w": 39, "h": 53 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0043.png", - "frame": { "x": 0, "y": 0, "w": 39, "h": 56 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 0, "w": 39, "h": 56 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0044.png", - "frame": { "x": 79, "y": 146, "w": 40, "h": 47 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 9, "w": 40, "h": 47 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0045.png", - "frame": { "x": 119, "y": 146, "w": 38, "h": 49 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 8, "w": 38, "h": 49 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0046.png", - "frame": { "x": 120, "y": 0, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0047.png", - "frame": { "x": 120, "y": 0, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0048.png", - "frame": { "x": 39, "y": 0, "w": 39, "h": 53 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 5, "w": 39, "h": 53 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0049.png", - "frame": { "x": 0, "y": 0, "w": 39, "h": 56 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 0, "w": 39, "h": 56 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0050.png", - "frame": { "x": 79, "y": 146, "w": 40, "h": 47 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 9, "w": 40, "h": 47 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0051.png", - "frame": { "x": 119, "y": 146, "w": 38, "h": 49 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 8, "w": 38, "h": 49 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - }, - { - "filename": "0052.png", - "frame": { "x": 120, "y": 0, "w": 40, "h": 50 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 8, "w": 40, "h": 50 }, - "sourceSize": { "w": 44, "h": 58 }, - "duration": 100 - } - ], - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.11-x64", - "image": "672.png", - "format": "I8", - "size": { "w": 160, "h": 195 }, - "scale": "1" - } -} diff --git a/public/images/pokemon/exp/back/672.png b/public/images/pokemon/exp/back/672.png deleted file mode 100644 index 2201da3b627868ded81f15570ebc12d6a7921c9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3350 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 Hu0mjfP_*US diff --git a/public/images/pokemon/exp/back/693.json b/public/images/pokemon/exp/back/693.json deleted file mode 100644 index 6358a8908f6..00000000000 --- a/public/images/pokemon/exp/back/693.json +++ /dev/null @@ -1,902 +0,0 @@ -{ "frames": [ - { - "filename": "0001.png", - "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0002.png", - "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0003.png", - "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0004.png", - "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0005.png", - "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0006.png", - "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0007.png", - "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0008.png", - "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0009.png", - "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0010.png", - "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0011.png", - "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0012.png", - "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0013.png", - "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0014.png", - "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0015.png", - "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0016.png", - "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0017.png", - "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0018.png", - "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0019.png", - "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0020.png", - "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0021.png", - "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0022.png", - "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0023.png", - "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0024.png", - "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0025.png", - "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0026.png", - "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0027.png", - "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0028.png", - "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0029.png", - "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0030.png", - "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0031.png", - "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0032.png", - "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0033.png", - "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0034.png", - "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0035.png", - "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0036.png", - "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0037.png", - "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0038.png", - "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0039.png", - "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0040.png", - "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0041.png", - "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0042.png", - "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0043.png", - "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0044.png", - "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0045.png", - "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0046.png", - "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0047.png", - "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0048.png", - "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0049.png", - "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0050.png", - "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0051.png", - "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0052.png", - "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0053.png", - "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0054.png", - "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0055.png", - "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0056.png", - "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0057.png", - "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0058.png", - "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0059.png", - "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0060.png", - "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0061.png", - "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0062.png", - "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0063.png", - "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0064.png", - "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0065.png", - "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0066.png", - "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0067.png", - "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0068.png", - "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0069.png", - "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0070.png", - "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0071.png", - "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0072.png", - "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0073.png", - "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0074.png", - "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0075.png", - "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0076.png", - "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0077.png", - "frame": { "x": 565, "y": 196, "w": 90, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 6, "w": 90, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0078.png", - "frame": { "x": 278, "y": 266, "w": 90, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 10, "w": 90, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0079.png", - "frame": { "x": 189, "y": 199, "w": 95, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 8, "w": 95, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0080.png", - "frame": { "x": 193, "y": 1, "w": 98, "h": 68 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 3, "w": 98, "h": 68 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0081.png", - "frame": { "x": 1, "y": 71, "w": 94, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0082.png", - "frame": { "x": 469, "y": 196, "w": 96, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 12, "w": 96, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0083.png", - "frame": { "x": 1, "y": 1, "w": 98, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 5, "w": 98, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0084.png", - "frame": { "x": 1, "y": 136, "w": 94, "h": 63 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 10, "w": 94, "h": 63 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0085.png", - "frame": { "x": 95, "y": 72, "w": 96, "h": 63 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 12, "w": 96, "h": 63 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0086.png", - "frame": { "x": 381, "y": 1, "w": 97, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 97, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0087.png", - "frame": { "x": 1, "y": 71, "w": 94, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0088.png", - "frame": { "x": 469, "y": 196, "w": 96, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 12, "w": 96, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0089.png", - "frame": { "x": 1, "y": 1, "w": 98, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 5, "w": 98, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0090.png", - "frame": { "x": 191, "y": 136, "w": 94, "h": 63 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 10, "w": 94, "h": 63 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0091.png", - "frame": { "x": 95, "y": 135, "w": 96, "h": 62 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 96, "h": 62 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0092.png", - "frame": { "x": 572, "y": 67, "w": 99, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 99, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0093.png", - "frame": { "x": 284, "y": 205, "w": 95, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 11, "w": 95, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0094.png", - "frame": { "x": 1, "y": 199, "w": 91, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 12, "w": 91, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0095.png", - "frame": { "x": 1, "y": 259, "w": 95, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 12, "w": 95, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0096.png", - "frame": { "x": 193, "y": 69, "w": 95, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 5, "w": 95, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0097.png", - "frame": { "x": 285, "y": 141, "w": 92, "h": 64 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 8, "w": 92, "h": 64 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0098.png", - "frame": { "x": 96, "y": 318, "w": 89, "h": 58 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 22, "y": 14, "w": 89, "h": 58 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0099.png", - "frame": { "x": 564, "y": 261, "w": 92, "h": 58 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 19, "y": 14, "w": 92, "h": 58 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - } - ], - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.12-x64", - "image": "693.png", - "format": "I8", - "size": { "w": 672, "h": 377 }, - "scale": "1" - } -} diff --git a/public/images/pokemon/exp/back/693.png b/public/images/pokemon/exp/back/693.png deleted file mode 100644 index 1ff5db69b60d4ceee2ee140b113c2591b6d2292f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21703 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 diff --git a/public/images/pokemon/exp/back/753.json b/public/images/pokemon/exp/back/753.json deleted file mode 100644 index dbd9fd7d635..00000000000 --- a/public/images/pokemon/exp/back/753.json +++ /dev/null @@ -1,2582 +0,0 @@ -{ - "textures": [ - { - "image": "753.png", - "format": "RGBA8888", - "size": { - "w": 140, - "h": 140 - }, - "scale": 1, - "frames": [ - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 0, - "w": 31, - "h": 47 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 0, - "w": 31, - "h": 47 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 0, - "w": 31, - "h": 47 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 0, - "w": 31, - "h": 47 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 0, - "w": 31, - "h": 47 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 0, - "w": 31, - "h": 47 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 0, - "w": 31, - "h": 47 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 0, - "w": 31, - "h": 47 - } - }, - { - "filename": "0087.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 0, - "w": 31, - "h": 47 - } - }, - { - "filename": "0088.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 0, - "w": 31, - "h": 47 - } - }, - { - "filename": "0095.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 0, - "w": 31, - "h": 47 - } - }, - { - "filename": "0096.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 0, - "w": 31, - "h": 47 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 47, - "w": 31, - "h": 47 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 47, - "w": 31, - "h": 47 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 47, - "w": 31, - "h": 47 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 47, - "w": 31, - "h": 47 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 47, - "w": 31, - "h": 47 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 47, - "w": 31, - "h": 47 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 47, - "w": 31, - "h": 47 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 47, - "w": 31, - "h": 47 - } - }, - { - "filename": "0089.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 47, - "w": 31, - "h": 47 - } - }, - { - "filename": "0090.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 47, - "w": 31, - "h": 47 - } - }, - { - "filename": "0093.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 47, - "w": 31, - "h": 47 - } - }, - { - "filename": "0094.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 31, - "h": 47 - }, - "frame": { - "x": 0, - "y": 47, - "w": 31, - "h": 47 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 7, - "w": 31, - "h": 46 - }, - "frame": { - "x": 0, - "y": 94, - "w": 31, - "h": 46 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 7, - "w": 31, - "h": 46 - }, - "frame": { - "x": 0, - "y": 94, - "w": 31, - "h": 46 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 7, - "w": 31, - "h": 46 - }, - "frame": { - "x": 0, - "y": 94, - "w": 31, - "h": 46 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 7, - "w": 31, - "h": 46 - }, - "frame": { - "x": 0, - "y": 94, - "w": 31, - "h": 46 - } - }, - { - "filename": "0091.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 7, - "w": 31, - "h": 46 - }, - "frame": { - "x": 0, - "y": 94, - "w": 31, - "h": 46 - } - }, - { - "filename": "0092.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 7, - "w": 31, - "h": 46 - }, - "frame": { - "x": 0, - "y": 94, - "w": 31, - "h": 46 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0081.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0082.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0083.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0084.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0085.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0086.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0097.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0098.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0099.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0100.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0101.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0102.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0110.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0111.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0112.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0120.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0121.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0122.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 47, - "w": 30, - "h": 47 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 47, - "w": 30, - "h": 47 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 47, - "w": 30, - "h": 47 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 47, - "w": 30, - "h": 47 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 47, - "w": 30, - "h": 47 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 47, - "w": 30, - "h": 47 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 47, - "w": 30, - "h": 47 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 47, - "w": 30, - "h": 47 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 47, - "w": 30, - "h": 47 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 47, - "w": 30, - "h": 47 - } - }, - { - "filename": "0079.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 47, - "w": 30, - "h": 47 - } - }, - { - "filename": "0080.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 30, - "h": 47 - }, - "frame": { - "x": 31, - "y": 47, - "w": 30, - "h": 47 - } - }, - { - "filename": "0109.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 7, - "w": 30, - "h": 46 - }, - "frame": { - "x": 31, - "y": 94, - "w": 30, - "h": 46 - } - }, - { - "filename": "0119.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 7, - "w": 30, - "h": 46 - }, - "frame": { - "x": 31, - "y": 94, - "w": 30, - "h": 46 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 30, - "h": 47 - }, - "frame": { - "x": 61, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 30, - "h": 47 - }, - "frame": { - "x": 61, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 30, - "h": 47 - }, - "frame": { - "x": 61, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 30, - "h": 47 - }, - "frame": { - "x": 61, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 30, - "h": 47 - }, - "frame": { - "x": 61, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 30, - "h": 47 - }, - "frame": { - "x": 61, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 30, - "h": 47 - }, - "frame": { - "x": 61, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 30, - "h": 47 - }, - "frame": { - "x": 61, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0073.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 30, - "h": 47 - }, - "frame": { - "x": 61, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0074.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 30, - "h": 47 - }, - "frame": { - "x": 61, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0077.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 30, - "h": 47 - }, - "frame": { - "x": 61, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0078.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 30, - "h": 47 - }, - "frame": { - "x": 61, - "y": 0, - "w": 30, - "h": 47 - } - }, - { - "filename": "0103.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 29, - "h": 47 - }, - "frame": { - "x": 91, - "y": 0, - "w": 29, - "h": 47 - } - }, - { - "filename": "0104.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 29, - "h": 47 - }, - "frame": { - "x": 91, - "y": 0, - "w": 29, - "h": 47 - } - }, - { - "filename": "0113.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 29, - "h": 47 - }, - "frame": { - "x": 91, - "y": 0, - "w": 29, - "h": 47 - } - }, - { - "filename": "0114.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 29, - "h": 47 - }, - "frame": { - "x": 91, - "y": 0, - "w": 29, - "h": 47 - } - }, - { - "filename": "0107.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 4, - "w": 29, - "h": 47 - }, - "frame": { - "x": 61, - "y": 47, - "w": 29, - "h": 47 - } - }, - { - "filename": "0108.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 4, - "w": 29, - "h": 47 - }, - "frame": { - "x": 61, - "y": 47, - "w": 29, - "h": 47 - } - }, - { - "filename": "0117.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 4, - "w": 29, - "h": 47 - }, - "frame": { - "x": 61, - "y": 47, - "w": 29, - "h": 47 - } - }, - { - "filename": "0118.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 4, - "w": 29, - "h": 47 - }, - "frame": { - "x": 61, - "y": 47, - "w": 29, - "h": 47 - } - }, - { - "filename": "0105.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 28, - "h": 46 - }, - "frame": { - "x": 61, - "y": 94, - "w": 28, - "h": 46 - } - }, - { - "filename": "0106.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 28, - "h": 46 - }, - "frame": { - "x": 61, - "y": 94, - "w": 28, - "h": 46 - } - }, - { - "filename": "0115.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 28, - "h": 46 - }, - "frame": { - "x": 61, - "y": 94, - "w": 28, - "h": 46 - } - }, - { - "filename": "0116.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 28, - "h": 46 - }, - "frame": { - "x": 61, - "y": 94, - "w": 28, - "h": 46 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 8, - "w": 29, - "h": 45 - }, - "frame": { - "x": 89, - "y": 94, - "w": 29, - "h": 45 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 8, - "w": 29, - "h": 45 - }, - "frame": { - "x": 89, - "y": 94, - "w": 29, - "h": 45 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 8, - "w": 29, - "h": 45 - }, - "frame": { - "x": 89, - "y": 94, - "w": 29, - "h": 45 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 8, - "w": 29, - "h": 45 - }, - "frame": { - "x": 89, - "y": 94, - "w": 29, - "h": 45 - } - }, - { - "filename": "0075.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 8, - "w": 29, - "h": 45 - }, - "frame": { - "x": 89, - "y": 94, - "w": 29, - "h": 45 - } - }, - { - "filename": "0076.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 31, - "h": 53 - }, - "spriteSourceSize": { - "x": 0, - "y": 8, - "w": 29, - "h": 45 - }, - "frame": { - "x": 89, - "y": 94, - "w": 29, - "h": 45 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:4209223453e7dabb3758c23bb26a3f91:234fdcf4efd83f52e8b51f13ec19a55c:16c1874bc814253ca78e52a99a340ff7$" - } -} diff --git a/public/images/pokemon/exp/back/753.png b/public/images/pokemon/exp/back/753.png deleted file mode 100644 index aa1fb7067451bf45a6cfae43f0a9e2f6a945ab38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2062 zcmV+p2=VucP)JXlcKcfHOe9zrV~9o5Q*1+|kDH z@w|U`qKf(~+OKMq+~qCfXgzf}Jln5m404yZOonUD;dnB>07069+@=1>aNQA;@dRs0 zQ;=LfUr&bM_!T*R?%4Y^Zsi*6p<|?8ocN?ENG|^vT{EuM;McJrcX`dYbasYj@p0K= zwePsjh}6`iwk927EVVUhT3%r;4eh0A;G+ss7;JqUpd0Lf9HQo~9oj=Tc>*#VrRAJU z2nu7nYT()Hu1&%6TZ|TkAfAnoPZ* z<+-f>`?I;c%!MOqrSN{Bq%*G>*?RLCDp@X zaUJ5vksIDrYE16g+l9`7oRtzRkf*Pq27c82m4G9nV_nFtx0Jb=&57x3THF~az&)My z_D*lG29J0h>*8)@j5AnV>6{mUoNI|Ax=_=Fnk5`SZC%`@G0yIF7acQQe_aNzJTadN zlse|B8yQ3<)9@(}5?b5VQCVHItn3(iFiLwiUl zq$lY(VqDZZhZb!JQb4zp4<{H)9;7cA7c~s+P5df~4E;9pq2XvlHP378mYUR_Pl>M@ z$fq8JHX@&95NanMK4pv$#S+c1iG28Q5NanMKC9Syi71w6(kAlZV`D#-h+>H*ZXh2% z9E94*hYts#cJkrFL1+{5@fty>oqYIk5NanMJ{*KLAs-qJLha^0ROGTlA9d4vR`Yo>dEI!Hd#3i$|74HKNs zez-oJYA695cm*|cs98cqg?!qkI~&Y{sf7~1>x=DBSE0mMzve~AB^Ut|aGtB2;Z->5TM&YnlVb!EqRf_vzZjCiB*CIL!fJXQN5#0h5G z;LSS=Uo=7eix49iQ4rqLfe^5UlXFOf)PmK}VjIC!OjfhK0eTQ@#UDj5#3hXcgR+TW zcK=CDJJ19#Yin!{94E&KMjVk@144g#EXN3D=ggQ?!$2rvIYux7q2Q>v|L&?DgeLox z;{;=C&d|Q710kdzmScRQYrr2eNF$GGheA)4~EWvyUJQL5RJrK9RCDO&BE(0N*y8?+dmSDsbd?@bBpl0dK+!~R*9?juN z$bb;O2<`p?Ih5-JBRWVIcq#}A{vf0eUUz1|Q|7@%gAn{gMli<5uL|JreKo$Ib^sy2 sd+gV~-2}CKhey_Oq&6ZL;eG7<4Vg+-K{zz)2LJ#707*qoM6N<$f^$j7lK=n! diff --git a/public/images/pokemon/exp/back/754.json b/public/images/pokemon/exp/back/754.json deleted file mode 100644 index 86abaac1814..00000000000 --- a/public/images/pokemon/exp/back/754.json +++ /dev/null @@ -1,1112 +0,0 @@ -{ - "textures": [ - { - "image": "754.png", - "format": "RGBA8888", - "size": { - "w": 222, - "h": 222 - }, - "scale": 1, - "frames": [ - { - "filename": "0036.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 68, - "w": 92, - "h": 68 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 68, - "w": 92, - "h": 68 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 136, - "w": 92, - "h": 68 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 136, - "w": 92, - "h": 68 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 88, - "h": 68 - }, - "frame": { - "x": 92, - "y": 68, - "w": 88, - "h": 68 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 88, - "h": 68 - }, - "frame": { - "x": 92, - "y": 68, - "w": 88, - "h": 68 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 40, - "h": 68 - }, - "frame": { - "x": 180, - "y": 68, - "w": 40, - "h": 68 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 40, - "h": 68 - }, - "frame": { - "x": 180, - "y": 68, - "w": 40, - "h": 68 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:3adad944aac48ad53efa41f8c9916d1c:ea15b954875ad08814f50cbbf849c1b3:f7cb0e9bb3adbe899317e6e2e306035d$" - } -} diff --git a/public/images/pokemon/exp/back/754.png b/public/images/pokemon/exp/back/754.png deleted file mode 100644 index 66bd6a1b9758f405bbc4754bcad9fa3c6e1db256..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3640 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 Hu0mjfmxbn~ diff --git a/public/images/pokemon/exp/back/shiny/693.json b/public/images/pokemon/exp/back/shiny/693.json deleted file mode 100644 index 6358a8908f6..00000000000 --- a/public/images/pokemon/exp/back/shiny/693.json +++ /dev/null @@ -1,902 +0,0 @@ -{ "frames": [ - { - "filename": "0001.png", - "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0002.png", - "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0003.png", - "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0004.png", - "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0005.png", - "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0006.png", - "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0007.png", - "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0008.png", - "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0009.png", - "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0010.png", - "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0011.png", - "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0012.png", - "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0013.png", - "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0014.png", - "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0015.png", - "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0016.png", - "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0017.png", - "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0018.png", - "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0019.png", - "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0020.png", - "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0021.png", - "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0022.png", - "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0023.png", - "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0024.png", - "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0025.png", - "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0026.png", - "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0027.png", - "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0028.png", - "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0029.png", - "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0030.png", - "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0031.png", - "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0032.png", - "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0033.png", - "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0034.png", - "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0035.png", - "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0036.png", - "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0037.png", - "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0038.png", - "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0039.png", - "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0040.png", - "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0041.png", - "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0042.png", - "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0043.png", - "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0044.png", - "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0045.png", - "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0046.png", - "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0047.png", - "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0048.png", - "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0049.png", - "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0050.png", - "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0051.png", - "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0052.png", - "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0053.png", - "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0054.png", - "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0055.png", - "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0056.png", - "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0057.png", - "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0058.png", - "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0059.png", - "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0060.png", - "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0061.png", - "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0062.png", - "frame": { "x": 472, "y": 70, "w": 88, "h": 72 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 0, "w": 88, "h": 72 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0063.png", - "frame": { "x": 378, "y": 138, "w": 91, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 8, "w": 91, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0064.png", - "frame": { "x": 187, "y": 260, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0065.png", - "frame": { "x": 379, "y": 257, "w": 95, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 16, "w": 95, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0066.png", - "frame": { "x": 572, "y": 1, "w": 98, "h": 66 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 98, "h": 66 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0067.png", - "frame": { "x": 478, "y": 1, "w": 94, "h": 69 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 11, "w": 94, "h": 69 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0068.png", - "frame": { "x": 560, "y": 132, "w": 93, "h": 64 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 19, "w": 93, "h": 64 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0069.png", - "frame": { "x": 474, "y": 257, "w": 90, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 22, "w": 90, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0070.png", - "frame": { "x": 95, "y": 197, "w": 94, "h": 62 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 21, "w": 94, "h": 62 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0071.png", - "frame": { "x": 99, "y": 1, "w": 94, "h": 71 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 71 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0072.png", - "frame": { "x": 291, "y": 1, "w": 90, "h": 73 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 6, "w": 90, "h": 73 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0073.png", - "frame": { "x": 288, "y": 74, "w": 90, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 21, "y": 11, "w": 90, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0074.png", - "frame": { "x": 368, "y": 317, "w": 88, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 23, "y": 17, "w": 88, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0075.png", - "frame": { "x": 96, "y": 259, "w": 91, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 15, "w": 91, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0076.png", - "frame": { "x": 381, "y": 68, "w": 91, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 20, "y": 3, "w": 91, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0077.png", - "frame": { "x": 565, "y": 196, "w": 90, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 6, "w": 90, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0078.png", - "frame": { "x": 278, "y": 266, "w": 90, "h": 59 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 10, "w": 90, "h": 59 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0079.png", - "frame": { "x": 189, "y": 199, "w": 95, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 8, "w": 95, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0080.png", - "frame": { "x": 193, "y": 1, "w": 98, "h": 68 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 3, "w": 98, "h": 68 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0081.png", - "frame": { "x": 1, "y": 71, "w": 94, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0082.png", - "frame": { "x": 469, "y": 196, "w": 96, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 12, "w": 96, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0083.png", - "frame": { "x": 1, "y": 1, "w": 98, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 5, "w": 98, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0084.png", - "frame": { "x": 1, "y": 136, "w": 94, "h": 63 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 10, "w": 94, "h": 63 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0085.png", - "frame": { "x": 95, "y": 72, "w": 96, "h": 63 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 12, "w": 96, "h": 63 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0086.png", - "frame": { "x": 381, "y": 1, "w": 97, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 97, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0087.png", - "frame": { "x": 1, "y": 71, "w": 94, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 17, "y": 10, "w": 94, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0088.png", - "frame": { "x": 469, "y": 196, "w": 96, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 12, "w": 96, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0089.png", - "frame": { "x": 1, "y": 1, "w": 98, "h": 70 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 5, "w": 98, "h": 70 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0090.png", - "frame": { "x": 191, "y": 136, "w": 94, "h": 63 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 10, "w": 94, "h": 63 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0091.png", - "frame": { "x": 95, "y": 135, "w": 96, "h": 62 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 96, "h": 62 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0092.png", - "frame": { "x": 572, "y": 67, "w": 99, "h": 65 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 99, "h": 65 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0093.png", - "frame": { "x": 284, "y": 205, "w": 95, "h": 61 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 11, "w": 95, "h": 61 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0094.png", - "frame": { "x": 1, "y": 199, "w": 91, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 12, "w": 91, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0095.png", - "frame": { "x": 1, "y": 259, "w": 95, "h": 60 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 12, "w": 95, "h": 60 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0096.png", - "frame": { "x": 193, "y": 69, "w": 95, "h": 67 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 5, "w": 95, "h": 67 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0097.png", - "frame": { "x": 285, "y": 141, "w": 92, "h": 64 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 18, "y": 8, "w": 92, "h": 64 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0098.png", - "frame": { "x": 96, "y": 318, "w": 89, "h": 58 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 22, "y": 14, "w": 89, "h": 58 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - }, - { - "filename": "0099.png", - "frame": { "x": 564, "y": 261, "w": 92, "h": 58 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 19, "y": 14, "w": 92, "h": 58 }, - "sourceSize": { "w": 111, "h": 83 }, - "duration": 100 - } - ], - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.12-x64", - "image": "693.png", - "format": "I8", - "size": { "w": 672, "h": 377 }, - "scale": "1" - } -} diff --git a/public/images/pokemon/exp/back/shiny/693.png b/public/images/pokemon/exp/back/shiny/693.png deleted file mode 100644 index 6884c2e28c7cc0a973f46300b758328f9b60c0f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21707 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 diff --git a/public/images/pokemon/exp/back/shiny/754.json b/public/images/pokemon/exp/back/shiny/754.json deleted file mode 100644 index 8b1a3d44a4d..00000000000 --- a/public/images/pokemon/exp/back/shiny/754.json +++ /dev/null @@ -1,1133 +0,0 @@ -{ - "textures": [ - { - "image": "754.png", - "format": "RGBA8888", - "size": { - "w": 222, - "h": 222 - }, - "scale": 1, - "frames": [ - { - "filename": "0036.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 68, - "w": 92, - "h": 68 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 68, - "w": 92, - "h": 68 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 136, - "w": 92, - "h": 68 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 136, - "w": 92, - "h": 68 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 88, - "h": 68 - }, - "frame": { - "x": 92, - "y": 68, - "w": 88, - "h": 68 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 88, - "h": 68 - }, - "frame": { - "x": 92, - "y": 68, - "w": 88, - "h": 68 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 40, - "h": 68 - }, - "frame": { - "x": 180, - "y": 68, - "w": 40, - "h": 68 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 40, - "h": 68 - }, - "frame": { - "x": 180, - "y": 68, - "w": 40, - "h": 68 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:7651b73927071f2814265b66582a8d13:a2d1ef3cf0c2458640f77c2fbcc821a0:f7cb0e9bb3adbe899317e6e2e306035d$" - } -} diff --git a/public/images/pokemon/exp/back/shiny/754.png b/public/images/pokemon/exp/back/shiny/754.png deleted file mode 100644 index 1f7346ed822ae7a5f5d53874880134a108d990c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3640 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 P00000NkvXXu0mjf3{pa$ diff --git a/public/images/pokemon/exp/shiny/692.json b/public/images/pokemon/exp/shiny/692.json deleted file mode 100644 index 86b535260ae..00000000000 --- a/public/images/pokemon/exp/shiny/692.json +++ /dev/null @@ -1,794 +0,0 @@ -{ "frames": [ - { - "filename": "0001.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0002.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0003.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0004.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0005.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0006.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0007.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0008.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0009.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0010.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0011.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0012.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0013.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0014.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0015.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0016.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0017.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0018.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0019.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0020.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0021.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0022.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0023.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0024.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0025.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0026.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0027.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0028.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0029.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0030.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0031.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0032.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0033.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0034.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0035.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0036.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0037.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0038.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0039.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0040.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0041.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0042.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0043.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0044.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0045.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0046.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0047.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0048.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0049.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0050.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0051.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0052.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0053.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0054.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0055.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0056.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0057.png", - "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0058.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0059.png", - "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0060.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0061.png", - "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0062.png", - "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0063.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0064.png", - "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0065.png", - "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0066.png", - "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0067.png", - "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0068.png", - "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0069.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0070.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0071.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0072.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0073.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0074.png", - "frame": { "x": 1, "y": 71, "w": 57, "h": 33 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 33 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0075.png", - "frame": { "x": 1, "y": 71, "w": 57, "h": 33 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 33 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0076.png", - "frame": { "x": 117, "y": 72, "w": 59, "h": 33 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 59, "h": 33 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0077.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0078.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0079.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0080.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0081.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0082.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0083.png", - "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0084.png", - "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0085.png", - "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0086.png", - "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - }, - { - "filename": "0087.png", - "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, - "sourceSize": { "w": 63, "h": 35 }, - "duration": 50 - } - ], - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.12-x64", - "image": "692.png", - "format": "I8", - "size": { "w": 239, "h": 106 }, - "scale": "1" - } -} diff --git a/public/images/pokemon/exp/shiny/692.png b/public/images/pokemon/exp/shiny/692.png deleted file mode 100644 index 86f8cf51e927f901f82eebd19c51b559b8bb1977..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2580 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 U@SQEz%m4rY07*qoM6N<$f@D_Uga7~l diff --git a/public/images/pokemon/exp/shiny/754.json b/public/images/pokemon/exp/shiny/754.json deleted file mode 100644 index 18bb597aa75..00000000000 --- a/public/images/pokemon/exp/shiny/754.json +++ /dev/null @@ -1,1133 +0,0 @@ -{ - "textures": [ - { - "image": "754.png", - "format": "RGBA8888", - "size": { - "w": 234, - "h": 234 - }, - "scale": 1, - "frames": [ - { - "filename": "0036.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 0, - "w": 93, - "h": 68 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 0, - "w": 48, - "h": 68 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 0, - "y": 68, - "w": 93, - "h": 68 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 0, - "y": 68, - "w": 93, - "h": 68 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 93, - "h": 68 - }, - "frame": { - "x": 93, - "y": 68, - "w": 93, - "h": 68 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 186, - "y": 68, - "w": 48, - "h": 68 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 85, - "h": 68 - }, - "frame": { - "x": 0, - "y": 136, - "w": 85, - "h": 68 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 85, - "h": 68 - }, - "frame": { - "x": 0, - "y": 136, - "w": 85, - "h": 68 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 85, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 133, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 133, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 133, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 133, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 133, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 133, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 181, - "y": 136, - "w": 48, - "h": 68 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 93, - "h": 68 - }, - "spriteSourceSize": { - "x": 23, - "y": 0, - "w": 48, - "h": 68 - }, - "frame": { - "x": 181, - "y": 136, - "w": 48, - "h": 68 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:05bdd50d4b0041ca84c3293ee7fdf36e:adfe2b6fb11cad37f71416b628cb08c7:f7cb0e9bb3adbe899317e6e2e306035d$" - } -} diff --git a/public/images/pokemon/exp/shiny/754.png b/public/images/pokemon/exp/shiny/754.png deleted file mode 100644 index b1d4806163aa503f2e6f9d32ee7174ecb103bebe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3754 zcmZ{nc{~&T>k$Ch0*kV=qDmMc_$NLJ@LWXDc+`jFM3N-A{5@(aRWt?<}0 zx~k$z}U%{lq3Dl_PVn>-HiG`{+`)kB`0$T#&>&o{g7MZoUg~%f-PRW zKYp%G_4%1uzaJh{#Oqx0;qCY)?sM11AB#Fa_-nBW66^f+(1oAdc7*4HE+t;?CAg9= zLUn%e_xWH_ySo?dJ8zmC3kp>G?otf!DpT~zrQIw9j|$Ym;YUP82xq-6z(=y;2ftxM zWheuvJdcow<=hbBlDBkdhOy3RKt$? zVK`OF8D-@=@YlaKE~f|6+-dB-d2bq#^{3f1KMj+j*(?tZ$sEX4S*kM|e* zVSCVy`%)AIo-j#|^ua9n{ko4<7{^GePKxu@e8U`zeEXW3GGk zDG(WPA&LgE+(?30tu41zp?I;SlEUv5ddE^rO4g{1DOuE=iyhBu0U`8M@nPE+_5tw4 zNT)G?ai7E#L`s$)J|Rdw0n+^BljTZ(?guk9Bs13Dx5$J!YVoggr!x(HDZV~!RPnNF zD@*5_%0K6SB(>i^(otR@Iqw2&&ub?jnn&5BYH94S3Cb@)%Va# zvhm3okwNDBj_7+&KR$ZB45xs(90m;dK6@@m+3r!Qf^}?P9mfyXpK$cpYSU!Z(%ryB z<_Z=s=#81eBQ9*()%{ATd1DD}y{{s>CezURn(%%8HZVE0J{k>sxA5u#CGzc>_O$QgdxzaW{^`9YcXL>CTA7BoFY z3s_w|@)6g%XEr%*ZOnEnOXMzmEGg&U=ob!Lz&u^`%8a=67S;8Zj^l_;k*K%fI&lT3 z4I=}8suUAj8|?Jqx)DjBV?Q7P@v&Y)MkYE&Hrgq=_E@2Cm0+8wN1;%J&;9w+%LhH& zRCL4D&b_gmy*GdQ=$0{AeXf7=Vby-r`$OKXzJ|}ISy$-7{>TIN1*_=evxznD9--Zz zMNI~4sH)ncB~B6}4>KABmmp zB2lEIRT4(P6Bx6-+54rrOZ9WElyiy~20?($1`_2fK@>-+ff+F&n5{aGa0#9# zdCt499b6Ru{$tY=w(jqC_wb)a?HToR&cPN;CDQ4eOh}pYq(rbCQ>j7*kBlF;l4VjK z^P!~8Y;NEuQuK4g?KkQC!yan~X?sI_c1)R6Tdn4i!KN?Z*I(C`FGS8@i!?$-n4>N| z3{rG5B8+i(=sxmxZ483xo<>|GMW^o$xeX0~Elc~&7O>rOb+<_RDL@24ZZbW18apB> zZ9$^+uqUcXn_b08a{op!sc>-7vn#DJ%+Wxu1}Qo~C6dGP9r{HFhg@YyS8p$1Z)DdJ zlPvSz8t_U3T(cNUcNpQWcQ1=(I9Ek1^HLD-q|p-f1vfu%?INcv23T!u^c5*D41WL%Qeo4jlj*MwAoNqDRQ`;`s=>ymlQ1p4l7CTfC{)d9%9C|D3$70)U<@Fq8E~~Xm%FNUnTwJB+9c0tx-Q@l0WQw zhiJLQYy{(-QxTyyfU6labE#bw%}Uy^@I^7wohFvBI3l9?Gn+Loddkl?f}vJz6v4RG zCz6@~^z3P=mK;Bj^9hW0y*mJw6GzzhY}n8ZqHR4ED3uYV^&=$Am<`I5Z z^&%-c6vs~^MO*eI^nsUp*hiT88k}kDj$>K|^0ST#^H+*%ocmgnf&6%2iRvTnnCVxt zxE)N2Lvf4}k;_j#I#Ba!dB3KftVxx>!=!>c3Y6&5UG_nT%yJZZQ)rXyk7{|f*9V$a z{dqFc;lMvJnr;QH!sWXl_xA=V|AB^rBY^*b!iU&Oe?T?;`hP$d77ddAGi{c6{Evha z>n^U`C2dUt-C%1rraJhVLhsc`wNU3%;1uj=$X>AddZUv+AC{uAopZGonT7SF^Hc3D zN))3!??w!BseXlNu3!5{X0}15O~M7Wc2(`{S`O08F~NNfwq`*o@}p*PaC9WRclz9P zqHZVOak{`|iC&|;wd&KiPr6V_k`!eZl$rcwf8Z$hr2L_{!dy?XCs( zUxw3njbI;(saKci$9i9?>sqXeEt+U_aMio;68fRo5pQBb|$6Rve!Ehzx1i(-dTW)Cv+3@U`tN) zroXdR5UXrF$C4Wf2&8|wjsL=Kzt@}$0)w5+2MO{bhE zE_6_qx?*;Hv8Hk!kKa6*yeeo^!9k@%*6s)#o7txvH`2B#E);VO6;R+Y##Mpk3`a!> zpaBg)@9LBl zQsKgx7^xiGF>=Mavxjj`l+3E3#W51f-u5wq)Wz5>qz`&~#+b!GqkU)KKSiH2RS z_Rxj5DmQz4QXKNo+_0_C9o42& lxbnmwGX4KHMcR3in&F2nj@{eZ*!@WYtYCKLBvY@%{{sbcX(Ipt diff --git a/public/images/pokemon/shiny/672.json b/public/images/pokemon/shiny/672.json index dfd98acaf6b..f337bef7d29 100644 --- a/public/images/pokemon/shiny/672.json +++ b/public/images/pokemon/shiny/672.json @@ -1,41 +1,479 @@ -{ - "textures": [ - { - "image": "672.png", - "format": "RGBA8888", - "size": { - "w": 50, - "h": 50 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 42, - "h": 50 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 42, - "h": 50 - }, - "frame": { - "x": 0, - "y": 0, - "w": 42, - "h": 50 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:b346b616fb3566e3bb64cdd6b14c5d59:fb0b72a9ea01a28cfcf7731d5cf359af:2e4767b7cd134fc0ab1bb6e9eee82bc7$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0002.png", + "frame": { "x": 127, "y": 50, "w": 42, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 42, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0004.png", + "frame": { "x": 43, "y": 53, "w": 43, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 43, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0005.png", + "frame": { "x": 124, "y": 148, "w": 43, "h": 45 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 13, "w": 43, "h": 45 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0006.png", + "frame": { "x": 0, "y": 102, "w": 42, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 42, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0007.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0008.png", + "frame": { "x": 127, "y": 99, "w": 41, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 41, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0009.png", + "frame": { "x": 128, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0010.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0011.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0012.png", + "frame": { "x": 127, "y": 50, "w": 42, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 42, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0013.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0014.png", + "frame": { "x": 43, "y": 53, "w": 43, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 43, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0015.png", + "frame": { "x": 124, "y": 148, "w": 43, "h": 45 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 13, "w": 43, "h": 45 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0016.png", + "frame": { "x": 0, "y": 102, "w": 42, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 42, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0017.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0018.png", + "frame": { "x": 127, "y": 99, "w": 41, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 41, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0019.png", + "frame": { "x": 128, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0020.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0021.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0022.png", + "frame": { "x": 127, "y": 50, "w": 42, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 42, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0023.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0024.png", + "frame": { "x": 43, "y": 53, "w": 43, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 43, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0025.png", + "frame": { "x": 124, "y": 148, "w": 43, "h": 45 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 13, "w": 43, "h": 45 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0026.png", + "frame": { "x": 0, "y": 102, "w": 42, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 42, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0027.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0028.png", + "frame": { "x": 127, "y": 99, "w": 41, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 41, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0029.png", + "frame": { "x": 128, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0030.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0031.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0032.png", + "frame": { "x": 127, "y": 50, "w": 42, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 42, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0033.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0034.png", + "frame": { "x": 43, "y": 53, "w": 43, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 43, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0035.png", + "frame": { "x": 124, "y": 148, "w": 43, "h": 45 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 13, "w": 43, "h": 45 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0036.png", + "frame": { "x": 0, "y": 102, "w": 42, "h": 47 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 11, "w": 42, "h": 47 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0037.png", + "frame": { "x": 0, "y": 54, "w": 42, "h": 48 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 10, "w": 42, "h": 48 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0038.png", + "frame": { "x": 127, "y": 99, "w": 41, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 9, "w": 41, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0039.png", + "frame": { "x": 128, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0040.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0041.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0042.png", + "frame": { "x": 43, "y": 0, "w": 43, "h": 53 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 4, "w": 43, "h": 53 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0043.png", + "frame": { "x": 0, "y": 0, "w": 43, "h": 54 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 0, "w": 43, "h": 54 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0044.png", + "frame": { "x": 42, "y": 100, "w": 41, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 9, "w": 41, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0045.png", + "frame": { "x": 86, "y": 50, "w": 41, "h": 51 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 7, "w": 41, "h": 51 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0046.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0047.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0048.png", + "frame": { "x": 43, "y": 0, "w": 43, "h": 53 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 4, "w": 43, "h": 53 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0049.png", + "frame": { "x": 0, "y": 0, "w": 43, "h": 54 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 0, "w": 43, "h": 54 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0050.png", + "frame": { "x": 83, "y": 101, "w": 41, "h": 49 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 9, "w": 41, "h": 49 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0051.png", + "frame": { "x": 86, "y": 50, "w": 41, "h": 51 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 7, "w": 41, "h": 51 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + }, + { + "filename": "0052.png", + "frame": { "x": 86, "y": 0, "w": 42, "h": 50 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 8, "w": 42, "h": 50 }, + "sourceSize": { "w": 44, "h": 58 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.11-x64", + "image": "672.png", + "format": "I8", + "size": { "w": 170, "h": 193 }, + "scale": "1" + } } diff --git a/public/images/pokemon/shiny/672.png b/public/images/pokemon/shiny/672.png index b25ec4f08d3793635a101a729d9ba37669dde734..8602e7a026b66294dd20c1094f6e47cef215331a 100644 GIT binary patch literal 3337 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 diff --git a/public/images/pokemon/shiny/692.json b/public/images/pokemon/shiny/692.json index fc36cdb3337..86b535260ae 100644 --- a/public/images/pokemon/shiny/692.json +++ b/public/images/pokemon/shiny/692.json @@ -1,41 +1,794 @@ -{ - "textures": [ - { - "image": "692.png", - "format": "RGBA8888", - "size": { - "w": 56, - "h": 56 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 56, - "h": 35 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 56, - "h": 35 - }, - "frame": { - "x": 0, - "y": 0, - "w": 56, - "h": 35 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:19c1aa023d08bc22ccccf8bfeaa199e7:b92ea755c18e1ed1e6d509334c6f592e:2880def858c84cd859bedf13b0b49a33$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0002.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0003.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0004.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0005.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0006.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0007.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0008.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0009.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0010.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0011.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0012.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0013.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0014.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0015.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0016.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0017.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0018.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0019.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0020.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0021.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0022.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0023.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0024.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0025.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0026.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0027.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0028.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0029.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0030.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0031.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0032.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0033.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0034.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0035.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0036.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0037.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0038.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0039.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0040.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0041.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0042.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0043.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0044.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0045.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0046.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0047.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0048.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0049.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0050.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0051.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0052.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0053.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0054.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0055.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0056.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0057.png", + "frame": { "x": 121, "y": 1, "w": 59, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 59, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0058.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0059.png", + "frame": { "x": 1, "y": 36, "w": 58, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 1, "w": 58, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0060.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0061.png", + "frame": { "x": 181, "y": 1, "w": 57, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 0, "w": 57, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0062.png", + "frame": { "x": 60, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0063.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0064.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0065.png", + "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0066.png", + "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0067.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0068.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0069.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0070.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0071.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0072.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0073.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0074.png", + "frame": { "x": 1, "y": 71, "w": 57, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0075.png", + "frame": { "x": 1, "y": 71, "w": 57, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0076.png", + "frame": { "x": 117, "y": 72, "w": 59, "h": 33 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 2, "w": 59, "h": 33 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0077.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0078.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0079.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0080.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0081.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0082.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0083.png", + "frame": { "x": 1, "y": 1, "w": 60, "h": 34 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 1, "w": 60, "h": 34 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0084.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0085.png", + "frame": { "x": 62, "y": 1, "w": 58, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 58, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0086.png", + "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + }, + { + "filename": "0087.png", + "frame": { "x": 178, "y": 37, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.12-x64", + "image": "692.png", + "format": "I8", + "size": { "w": 239, "h": 106 }, + "scale": "1" + } } diff --git a/public/images/pokemon/shiny/692.png b/public/images/pokemon/shiny/692.png index 8dc8ee90534866c392bd1d25bf699b5ce1f1c4b9..86f8cf51e927f901f82eebd19c51b559b8bb1977 100644 GIT binary patch literal 2580 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 KMNUMnLSTZ}Z5|Z> diff --git a/public/images/pokemon/shiny/753.json b/public/images/pokemon/shiny/753.json index 964519cb949..5b20ef749a0 100644 --- a/public/images/pokemon/shiny/753.json +++ b/public/images/pokemon/shiny/753.json @@ -4,30 +4,2571 @@ "image": "753.png", "format": "RGBA8888", "size": { - "w": 45, - "h": 45 + "w": 137, + "h": 137 }, "scale": 1, "frames": [ { "filename": "0001.png", "rotated": false, - "trimmed": false, + "trimmed": true, "sourceSize": { - "w": 28, - "h": 45 + "w": 30, + "h": 52 }, "spriteSourceSize": { "x": 0, - "y": 0, - "w": 28, - "h": 45 + "y": 5, + "w": 30, + "h": 47 }, "frame": { "x": 0, "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0017.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0018.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0029.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0030.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0031.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0032.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0033.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0034.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0035.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0036.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0047.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0048.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0049.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0050.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0051.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0052.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0063.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0064.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0065.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0066.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0067.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0068.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0069.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0070.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0081.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0082.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0083.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0084.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0085.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0086.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0097.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0098.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0099.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0100.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0101.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0102.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0110.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0111.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0112.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0120.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0121.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0122.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 5, + "w": 30, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 30, + "h": 47 + } + }, + { + "filename": "0103.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 2, "w": 28, + "h": 47 + }, + "frame": { + "x": 30, + "y": 0, + "w": 28, + "h": 47 + } + }, + { + "filename": "0104.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 2, + "w": 28, + "h": 47 + }, + "frame": { + "x": 30, + "y": 0, + "w": 28, + "h": 47 + } + }, + { + "filename": "0113.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 2, + "w": 28, + "h": 47 + }, + "frame": { + "x": 30, + "y": 0, + "w": 28, + "h": 47 + } + }, + { + "filename": "0114.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 2, + "w": 28, + "h": 47 + }, + "frame": { + "x": 30, + "y": 0, + "w": 28, + "h": 47 + } + }, + { + "filename": "0107.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 4, + "w": 28, + "h": 47 + }, + "frame": { + "x": 58, + "y": 0, + "w": 28, + "h": 47 + } + }, + { + "filename": "0108.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 4, + "w": 28, + "h": 47 + }, + "frame": { + "x": 58, + "y": 0, + "w": 28, + "h": 47 + } + }, + { + "filename": "0117.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 4, + "w": 28, + "h": 47 + }, + "frame": { + "x": 58, + "y": 0, + "w": 28, + "h": 47 + } + }, + { + "filename": "0118.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 4, + "w": 28, + "h": 47 + }, + "frame": { + "x": 58, + "y": 0, + "w": 28, + "h": 47 + } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 0, + "w": 29, + "h": 46 + } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 0, + "w": 29, + "h": 46 + } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 0, + "w": 29, + "h": 46 + } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 0, + "w": 29, + "h": 46 + } + }, + { + "filename": "0037.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 0, + "w": 29, + "h": 46 + } + }, + { + "filename": "0038.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 0, + "w": 29, + "h": 46 + } + }, + { + "filename": "0045.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 0, + "w": 29, + "h": 46 + } + }, + { + "filename": "0046.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 0, + "w": 29, + "h": 46 + } + }, + { + "filename": "0071.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 0, + "w": 29, + "h": 46 + } + }, + { + "filename": "0072.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 0, + "w": 29, + "h": 46 + } + }, + { + "filename": "0079.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 0, + "w": 29, + "h": 46 + } + }, + { + "filename": "0080.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 1, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 0, + "w": 29, + "h": 46 + } + }, + { + "filename": "0019.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 46, + "w": 29, + "h": 46 + } + }, + { + "filename": "0020.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 46, + "w": 29, + "h": 46 + } + }, + { + "filename": "0027.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 46, + "w": 29, + "h": 46 + } + }, + { + "filename": "0028.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 46, + "w": 29, + "h": 46 + } + }, + { + "filename": "0053.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 46, + "w": 29, + "h": 46 + } + }, + { + "filename": "0054.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 46, + "w": 29, + "h": 46 + } + }, + { + "filename": "0061.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 46, + "w": 29, + "h": 46 + } + }, + { + "filename": "0062.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 46, + "w": 29, + "h": 46 + } + }, + { + "filename": "0087.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 46, + "w": 29, + "h": 46 + } + }, + { + "filename": "0088.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 46, + "w": 29, + "h": 46 + } + }, + { + "filename": "0095.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 46, + "w": 29, + "h": 46 + } + }, + { + "filename": "0096.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 6, + "w": 29, + "h": 46 + }, + "frame": { + "x": 86, + "y": 46, + "w": 29, + "h": 46 + } + }, + { + "filename": "0021.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, "h": 45 + }, + "frame": { + "x": 0, + "y": 47, + "w": 30, + "h": 45 + } + }, + { + "filename": "0022.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, + "h": 45 + }, + "frame": { + "x": 0, + "y": 47, + "w": 30, + "h": 45 + } + }, + { + "filename": "0025.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, + "h": 45 + }, + "frame": { + "x": 0, + "y": 47, + "w": 30, + "h": 45 + } + }, + { + "filename": "0026.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, + "h": 45 + }, + "frame": { + "x": 0, + "y": 47, + "w": 30, + "h": 45 + } + }, + { + "filename": "0055.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, + "h": 45 + }, + "frame": { + "x": 0, + "y": 47, + "w": 30, + "h": 45 + } + }, + { + "filename": "0056.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, + "h": 45 + }, + "frame": { + "x": 0, + "y": 47, + "w": 30, + "h": 45 + } + }, + { + "filename": "0059.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, + "h": 45 + }, + "frame": { + "x": 0, + "y": 47, + "w": 30, + "h": 45 + } + }, + { + "filename": "0060.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, + "h": 45 + }, + "frame": { + "x": 0, + "y": 47, + "w": 30, + "h": 45 + } + }, + { + "filename": "0089.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, + "h": 45 + }, + "frame": { + "x": 0, + "y": 47, + "w": 30, + "h": 45 + } + }, + { + "filename": "0090.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, + "h": 45 + }, + "frame": { + "x": 0, + "y": 47, + "w": 30, + "h": 45 + } + }, + { + "filename": "0093.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, + "h": 45 + }, + "frame": { + "x": 0, + "y": 47, + "w": 30, + "h": 45 + } + }, + { + "filename": "0094.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, + "h": 45 + }, + "frame": { + "x": 0, + "y": 47, + "w": 30, + "h": 45 + } + }, + { + "filename": "0105.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 0, + "w": 27, + "h": 46 + }, + "frame": { + "x": 30, + "y": 47, + "w": 27, + "h": 46 + } + }, + { + "filename": "0106.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 0, + "w": 27, + "h": 46 + }, + "frame": { + "x": 30, + "y": 47, + "w": 27, + "h": 46 + } + }, + { + "filename": "0115.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 0, + "w": 27, + "h": 46 + }, + "frame": { + "x": 30, + "y": 47, + "w": 27, + "h": 46 + } + }, + { + "filename": "0116.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 0, + "w": 27, + "h": 46 + }, + "frame": { + "x": 30, + "y": 47, + "w": 27, + "h": 46 + } + }, + { + "filename": "0109.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, + "h": 45 + }, + "frame": { + "x": 0, + "y": 92, + "w": 30, + "h": 45 + } + }, + { + "filename": "0119.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 7, + "w": 30, + "h": 45 + }, + "frame": { + "x": 0, + "y": 92, + "w": 30, + "h": 45 + } + }, + { + "filename": "0023.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 8, + "w": 29, + "h": 44 + }, + "frame": { + "x": 57, + "y": 47, + "w": 29, + "h": 44 + } + }, + { + "filename": "0024.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 8, + "w": 29, + "h": 44 + }, + "frame": { + "x": 57, + "y": 47, + "w": 29, + "h": 44 + } + }, + { + "filename": "0057.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 8, + "w": 29, + "h": 44 + }, + "frame": { + "x": 57, + "y": 47, + "w": 29, + "h": 44 + } + }, + { + "filename": "0058.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 8, + "w": 29, + "h": 44 + }, + "frame": { + "x": 57, + "y": 47, + "w": 29, + "h": 44 + } + }, + { + "filename": "0091.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 8, + "w": 29, + "h": 44 + }, + "frame": { + "x": 57, + "y": 47, + "w": 29, + "h": 44 + } + }, + { + "filename": "0092.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 0, + "y": 8, + "w": 29, + "h": 44 + }, + "frame": { + "x": 57, + "y": 47, + "w": 29, + "h": 44 + } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 57, + "y": 91, + "w": 28, + "h": 44 + } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 57, + "y": 91, + "w": 28, + "h": 44 + } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 57, + "y": 91, + "w": 28, + "h": 44 + } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 57, + "y": 91, + "w": 28, + "h": 44 + } + }, + { + "filename": "0039.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 57, + "y": 91, + "w": 28, + "h": 44 + } + }, + { + "filename": "0040.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 57, + "y": 91, + "w": 28, + "h": 44 + } + }, + { + "filename": "0043.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 57, + "y": 91, + "w": 28, + "h": 44 + } + }, + { + "filename": "0044.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 57, + "y": 91, + "w": 28, + "h": 44 + } + }, + { + "filename": "0073.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 57, + "y": 91, + "w": 28, + "h": 44 + } + }, + { + "filename": "0074.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 57, + "y": 91, + "w": 28, + "h": 44 + } + }, + { + "filename": "0077.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 57, + "y": 91, + "w": 28, + "h": 44 + } + }, + { + "filename": "0078.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 57, + "y": 91, + "w": 28, + "h": 44 + } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 85, + "y": 92, + "w": 28, + "h": 44 + } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 85, + "y": 92, + "w": 28, + "h": 44 + } + }, + { + "filename": "0041.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 85, + "y": 92, + "w": 28, + "h": 44 + } + }, + { + "filename": "0042.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 85, + "y": 92, + "w": 28, + "h": 44 + } + }, + { + "filename": "0075.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 85, + "y": 92, + "w": 28, + "h": 44 + } + }, + { + "filename": "0076.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 30, + "h": 52 + }, + "spriteSourceSize": { + "x": 2, + "y": 8, + "w": 28, + "h": 44 + }, + "frame": { + "x": 85, + "y": 92, + "w": 28, + "h": 44 } } ] @@ -36,6 +2577,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:0dfeaaa8dc9e984b8345da123854713a:ca6cbb0693924b86228f2fe9ab294ec9:16c1874bc814253ca78e52a99a340ff7$" + "smartupdate": "$TexturePacker:SmartUpdate:0a066207f4eaa63438f1b44ba24dbced:1c3824600c00c692fd9dab4dbe03a2ed:16c1874bc814253ca78e52a99a340ff7$" } } diff --git a/public/images/pokemon/shiny/753.png b/public/images/pokemon/shiny/753.png index e13412f2a4f3bceaace7423bcdf472f49eb8ab1d..12f0f7a090f25a4f94d78f930a5487b7512ad024 100644 GIT binary patch delta 2042 zcmVOSH8jNmbK+zRH4ZEg)i}ErAO% zbK8FRe0m`fYC$NhCVrL_$9z4gNCa9Pa&|mX0)H&8gPJ1H>X5FdY)JKyBIM$JX$$OuJ?@iF1e!=0TtV)i&s8w2pAg6= zLL*NpHIU@07`7iiCS?QLciowe%nnXk|)S)Q)mrlj*Zr$S(qorBsUApLU4W;~=8? z6OAcCV@|1QAj$U^9mkjU*~%0fT1=@GHQ)ax_Hk{Rrt*WADF&#We<_usMvmi!aGFxV zY2Qmw`61&H_n*qmUTNeSODT%tUF>{RoTjhTDC6PPwQv_>(6dW(B%i>B>SL{Tfr`QFilSzc z_xnk7yB1rM>q#-^f2PVLOFD;lp+(=5RE-q{QRsLX`aE8**Xxnq%b&+T?>UK!$9^!D ztF%Lm)v^{}UPVzm3FYlXHm!T1R5FwmFQwMF7`0t|q@smYKj_>~l%}*CaWPiQ<-)r( z2B4K{YvaaE;w>bJM4Le6NnA$aD^WHQ5$!isQ4}ScsIr`*e^QKTq-ocGarXR}sZWH) zv^@FSu`Lr4hgSPv9Mb@kNX}n%L0r*tj&T*;1vv*??r@HA70m@X2VCxg83SCUc0tYo zm*dVcu0np!0hgN?%oyM*1_>|=+RK$r>bxS-1#!hD+smEKo{M6eAm`X+=~N&{2Uh_m z$T_65SdBZ~e_REa8cc%8(MUJvIrIY_$T`wQVMf8I=3cI1njo%7A4Bxj6lWV}*e1w1 z4z=!ylLk6`Tm_gQ=QtmkSvhZoA+)&)FhS0t8fUTyiG!;k6XYDpSr|E^;tat@Gk^(l z4&A7Nj=3wz(_lC@=SaVErI9p(;N&XM1Ubk4YA+y;e_i_gRObyj$7!rjyD$z>6={N;<1{LZUB)4*Qkh)1BKuTh z2UWQie^X2@T%j#?8at>8_5jXt1ICMUxT#8jp8d_FKpEsRhLV9Cr?B)v72!!AWi*tb z8A)zPCq`B9d$E8jiQtHevw|xOV?{_d-*yV^k2}n=CQq@;IH8I}8H$l_^a?^Um7t>m zRqn#WKPsHyBrjhZcQKrpLn9=ifikkC#1&`7e@HF_%1FFL8oBQzBn&UKQHEq044fo7 zqN0p!y!!UVK3s}zl#wl$rvNAK?I(sZiX_6gY5N5ugOIdQ2HmQH+>;qjL>W7dc$aHs zJdje#XTpUSd`N|X00Bi~Ue;Y6S8@OT|E&OiL ze+F6@OWEcX04>-J{Q;2C;1#H^tw$Ld%5d2y__|@KF${EZn&7r@XSIqd4;RRF85?|D#JB_FxKnGQwCvVD&zNN zC}uRwF_ZV<>Fo6jdQf-t#r2w=%t~IUq7G9ZBZC8Hxa=3_@M4Ue?|0M^gs*<%C}^R}joATYRj?y!DpsX!fVJz1q{izlNqV8oUBG{PmvxeI1#~Xz+?w!=Lr2i*w5- z*HshFWq2C?%9z2ue=MUhm(kc^e@)Y*j~R52Wwhopnp?f2H9ytg?VmcwG8%IkZ6k^A z_UCO|=p4&v%w;%&Tmu8em_gc>#IcOkQ}dz@e3ZZuB@H|j0|VFWLP#(sj%BQ?YeFPZ z2Qj#SM<{N5;Nkq5KILY5Mj*!ZY9oY)dxRoB6Z9l`#O3(v{xwX{u31wDP|pZObjtR1 z9y2&Dv~j(B2!RbQc>4V$+t;~=l^!`>^5!1PC{E5lLeaR;EM-s4%SJ!%&nqP19~n{j Y18D*Q@SQEz%m4rY07*qoM6N<$g8!J$?EnA( delta 410 zcmV;L0cHNG5Z41CiBL{Q4GJ0x0000DNk~Le0000j0000j2m=5B01d|OwlvFq7Ol;de0wuP^Kz!}5ebJ-Py*_Xm zHx3JUXrJGumx{kjFBB&tQA9dAnvUb3y*}4bzh&z~v5cC)qCOnmcrHp*d%?lnCu71bH*hFrXv&4i+Et(^b07*qoM6N<$ Eg8inv3jhEB diff --git a/public/images/pokemon/shiny/754.json b/public/images/pokemon/shiny/754.json index ecb5b8a6779..18bb597aa75 100644 --- a/public/images/pokemon/shiny/754.json +++ b/public/images/pokemon/shiny/754.json @@ -4,29 +4,1121 @@ "image": "754.png", "format": "RGBA8888", "size": { - "w": 68, - "h": 68 + "w": 234, + "h": 234 }, "scale": 1, "frames": [ { - "filename": "0001.png", + "filename": "0036.png", "rotated": false, "trimmed": false, "sourceSize": { - "w": 46, + "w": 93, "h": 68 }, "spriteSourceSize": { "x": 0, "y": 0, - "w": 46, + "w": 93, "h": 68 }, "frame": { "x": 0, "y": 0, - "w": 46, + "w": 93, + "h": 68 + } + }, + { + "filename": "0040.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 93, + "h": 68 + }, + "frame": { + "x": 0, + "y": 0, + "w": 93, + "h": 68 + } + }, + { + "filename": "0044.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 93, + "h": 68 + }, + "frame": { + "x": 0, + "y": 0, + "w": 93, + "h": 68 + } + }, + { + "filename": "0037.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 93, + "h": 68 + }, + "frame": { + "x": 93, + "y": 0, + "w": 93, + "h": 68 + } + }, + { + "filename": "0039.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 93, + "h": 68 + }, + "frame": { + "x": 93, + "y": 0, + "w": 93, + "h": 68 + } + }, + { + "filename": "0041.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 93, + "h": 68 + }, + "frame": { + "x": 93, + "y": 0, + "w": 93, + "h": 68 + } + }, + { + "filename": "0043.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 93, + "h": 68 + }, + "frame": { + "x": 93, + "y": 0, + "w": 93, + "h": 68 + } + }, + { + "filename": "0045.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 93, + "h": 68 + }, + "frame": { + "x": 93, + "y": 0, + "w": 93, + "h": 68 + } + }, + { + "filename": "0046.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 93, + "h": 68 + }, + "frame": { + "x": 93, + "y": 0, + "w": 93, + "h": 68 + } + }, + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 0, + "w": 48, + "h": 68 + } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 0, + "w": 48, + "h": 68 + } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 0, + "w": 48, + "h": 68 + } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 0, + "w": 48, + "h": 68 + } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 0, + "w": 48, + "h": 68 + } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 0, + "w": 48, + "h": 68 + } + }, + { + "filename": "0022.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 0, + "w": 48, + "h": 68 + } + }, + { + "filename": "0023.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 0, + "w": 48, + "h": 68 + } + }, + { + "filename": "0029.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 0, + "w": 48, + "h": 68 + } + }, + { + "filename": "0030.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 0, + "w": 48, + "h": 68 + } + }, + { + "filename": "0038.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 93, + "h": 68 + }, + "frame": { + "x": 0, + "y": 68, + "w": 93, + "h": 68 + } + }, + { + "filename": "0042.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 93, + "h": 68 + }, + "frame": { + "x": 0, + "y": 68, + "w": 93, + "h": 68 + } + }, + { + "filename": "0047.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 93, + "h": 68 + }, + "frame": { + "x": 93, + "y": 68, + "w": 93, + "h": 68 + } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 68, + "w": 48, + "h": 68 + } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 68, + "w": 48, + "h": 68 + } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 68, + "w": 48, + "h": 68 + } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 68, + "w": 48, + "h": 68 + } + }, + { + "filename": "0017.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 68, + "w": 48, + "h": 68 + } + }, + { + "filename": "0021.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 68, + "w": 48, + "h": 68 + } + }, + { + "filename": "0024.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 68, + "w": 48, + "h": 68 + } + }, + { + "filename": "0028.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 68, + "w": 48, + "h": 68 + } + }, + { + "filename": "0031.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 68, + "w": 48, + "h": 68 + } + }, + { + "filename": "0052.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 68, + "w": 48, + "h": 68 + } + }, + { + "filename": "0053.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 186, + "y": 68, + "w": 48, + "h": 68 + } + }, + { + "filename": "0035.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 4, + "y": 0, + "w": 85, + "h": 68 + }, + "frame": { + "x": 0, + "y": 136, + "w": 85, + "h": 68 + } + }, + { + "filename": "0048.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 4, + "y": 0, + "w": 85, + "h": 68 + }, + "frame": { + "x": 0, + "y": 136, + "w": 85, + "h": 68 + } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 85, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 85, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 85, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 85, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0018.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 85, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0020.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 85, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0025.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 85, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0027.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 85, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0032.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 85, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0051.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 85, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 133, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 133, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0019.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 133, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0026.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 133, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0033.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 133, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0050.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 133, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0034.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 181, + "y": 136, + "w": 48, + "h": 68 + } + }, + { + "filename": "0049.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 93, + "h": 68 + }, + "spriteSourceSize": { + "x": 23, + "y": 0, + "w": 48, + "h": 68 + }, + "frame": { + "x": 181, + "y": 136, + "w": 48, "h": 68 } } @@ -36,6 +1128,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:f4866096a7f384feda7689540b5499f2:1c5d416a85ea018909e59a1eb9c84c3a:f7cb0e9bb3adbe899317e6e2e306035d$" + "smartupdate": "$TexturePacker:SmartUpdate:05bdd50d4b0041ca84c3293ee7fdf36e:adfe2b6fb11cad37f71416b628cb08c7:f7cb0e9bb3adbe899317e6e2e306035d$" } } diff --git a/public/images/pokemon/shiny/754.png b/public/images/pokemon/shiny/754.png index f50262ab10ed86de88ba36b22827ed93d058280d..b1d4806163aa503f2e6f9d32ee7174ecb103bebe 100644 GIT binary patch delta 3725 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 diff --git a/public/images/pokemon/variant/exp/back/672.json b/public/images/pokemon/variant/exp/back/672.json deleted file mode 100644 index c118d603d57..00000000000 --- a/public/images/pokemon/variant/exp/back/672.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "1": { - "3d3128": "69112a", - "67615b": "9e2c3d", - "615140": "89431b", - "7e6d5a": "b3743e", - "554538": "642509", - "efeded": "f8e2b7", - "beb8b6": "e3a378", - "0e5d58": "8c6859", - "09a77c": "f8f0e2", - "0d8374": "d2af94", - "c16a3f": "321512", - "c6b379": "552d30", - "a8905c": "4b2525" - }, - "2": { - "3d3128": "161526", - "67615b": "2d2b40", - "615140": "4c7a68", - "7e6d5a": "72b692", - "554538": "305a4f", - "efeded": "ffeffe", - "beb8b6": "d4b3d7", - "0e5d58": "363e6c", - "09a77c": "96d5e3", - "0d8374": "6885b6", - "c16a3f": "612c6b", - "c6b379": "9f5f9b", - "a8905c": "854d87" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/692.json b/public/images/pokemon/variant/exp/back/692.json deleted file mode 100644 index d4c85f37c9d..00000000000 --- a/public/images/pokemon/variant/exp/back/692.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "1": { - "337380": "783a1d", - "b3b3b3": "c8ba6d", - "595959": "c85b5b", - "61daf2": "e1ac53", - "cc9c3d": "53be53", - "404040": "7d182d", - "ffc44c": "a9f076", - "b2f2ff": "fada7f", - "47a1b3": "af6a37", - "101010": "070707", - "735822": "20734c" - }, - "2": { - "337380": "5f3c23", - "b3b3b3": "68a7aa", - "595959": "88cd56", - "61daf2": "e1d6b6", - "cc9c3d": "7743be", - "404040": "1c873e", - "ffc44c": "a36feb", - "b2f2ff": "faf8d7", - "47a1b3": "968144", - "101010": "070707", - "735822": "371c72" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/693.json b/public/images/pokemon/variant/exp/back/693.json deleted file mode 100644 index 3187a81e0c0..00000000000 --- a/public/images/pokemon/variant/exp/back/693.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "1": { - "224b73": "552813", - "4595e5": "aa6839", - "23a2c8": "c87a23", - "262626": "230808", - "cc9c3d": "1b3c17", - "404040": "3c171b", - "5f5f5f": "6e2e3b", - "61daf2": "f2bd61", - "3674b3": "7d3e21", - "ffc44c": "426e2e", - "735822": "08230e" - }, - "2": { - "224b73": "5f463a", - "4595e5": "c8b493", - "23a2c8": "beb099", - "262626": "295a1c", - "cc9c3d": "6259af", - "404040": "2a8c53", - "5f5f5f": "51c85d", - "61daf2": "f0eadb", - "3674b3": "9b8265", - "ffc44c": "a39afa", - "735822": "36235f" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/753.json b/public/images/pokemon/variant/exp/back/753.json deleted file mode 100644 index 26e48f43509..00000000000 --- a/public/images/pokemon/variant/exp/back/753.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "1": { - "234028": "2e1643", - "5ba668": "4e2c62", - "468050": "3e2253", - "315945": "0e2616", - "549977": "1b3822", - "69bf94": "27452c", - "d98d9a": "a55c36", - "ffbfca": "b47145", - "803340": "682c16", - "cc5266": "a55c36" - }, - "2": { - "234028": "531034", - "5ba668": "ce54b0", - "468050": "9b2d76", - "315945": "441342", - "549977": "5a215a", - "69bf94": "6e3472", - "d98d9a": "263b83", - "ffbfca": "3454a5", - "803340": "0b1d4e", - "cc5266": "263b83" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/754.json b/public/images/pokemon/variant/exp/back/754.json deleted file mode 100644 index 5fb99ea57c9..00000000000 --- a/public/images/pokemon/variant/exp/back/754.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "1": { - "803340": "82180e", - "ff667f": "c95623", - "cc5266": "ac351f", - "ffbfca": "f48b49", - "d98d9a": "c95623", - "315945": "122a1a", - "69bf94": "314e36", - "bfbfbf": "c9d6b7", - "737373": "859970", - "f8f8f8": "eff7e2" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/754_2.json b/public/images/pokemon/variant/exp/back/754_2.json deleted file mode 100644 index f32f0133f99..00000000000 --- a/public/images/pokemon/variant/exp/back/754_2.json +++ /dev/null @@ -1,1112 +0,0 @@ -{ - "textures": [ - { - "image": "754_2.png", - "format": "RGBA8888", - "size": { - "w": 222, - "h": 222 - }, - "scale": 1, - "frames": [ - { - "filename": "0036.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 92, - "y": 0, - "w": 92, - "h": 68 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 184, - "y": 0, - "w": 38, - "h": 68 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 68, - "w": 92, - "h": 68 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 68, - "w": 92, - "h": 68 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 136, - "w": 92, - "h": 68 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 92, - "h": 68 - }, - "frame": { - "x": 0, - "y": 136, - "w": 92, - "h": 68 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 88, - "h": 68 - }, - "frame": { - "x": 92, - "y": 68, - "w": 88, - "h": 68 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 88, - "h": 68 - }, - "frame": { - "x": 92, - "y": 68, - "w": 88, - "h": 68 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 40, - "h": 68 - }, - "frame": { - "x": 180, - "y": 68, - "w": 40, - "h": 68 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 40, - "h": 68 - }, - "frame": { - "x": 180, - "y": 68, - "w": 40, - "h": 68 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 39, - "h": 68 - }, - "frame": { - "x": 92, - "y": 136, - "w": 39, - "h": 68 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 131, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 92, - "h": 68 - }, - "spriteSourceSize": { - "x": 25, - "y": 0, - "w": 38, - "h": 68 - }, - "frame": { - "x": 169, - "y": 136, - "w": 38, - "h": 68 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:3adad944aac48ad53efa41f8c9916d1c:ea15b954875ad08814f50cbbf849c1b3:f7cb0e9bb3adbe899317e6e2e306035d$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/754_2.png b/public/images/pokemon/variant/exp/back/754_2.png deleted file mode 100644 index 85eadd7428f1f47714ab694948233ca6260f4d25..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3646 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 aqf9^bo)+t5(&1;3?Uu2nQLTYX)c*kQPkuK5 From e50ebaa815912b618d83158c66e7d59e6daa9105 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Fri, 1 Aug 2025 12:51:11 -0600 Subject: [PATCH 65/76] [Misc] Fix missing types in battler tags and remove DragonCheerTag (#6188) * Fix missing types in battler tags * Fix issues with dragon cheer --- src/@types/battler-tags.ts | 9 +++++ src/data/battler-tags.ts | 82 ++++++++++++++++++++++++-------------- src/field/pokemon.ts | 4 +- 3 files changed, 63 insertions(+), 32 deletions(-) diff --git a/src/@types/battler-tags.ts b/src/@types/battler-tags.ts index 0057280e4e5..211eb25113d 100644 --- a/src/@types/battler-tags.ts +++ b/src/@types/battler-tags.ts @@ -88,6 +88,15 @@ export type AbilityBattlerTagType = | BattlerTagType.SLOW_START | BattlerTagType.TRUANT; +/** Subset of {@linkcode BattlerTagType}s that provide type boosts */ +export type TypeBoostTagType = BattlerTagType.FIRE_BOOST | BattlerTagType.CHARGED; + +/** Subset of {@linkcode BattlerTagType}s that boost the user's critical stage */ +export type CritStageBoostTagType = BattlerTagType.CRIT_BOOST | BattlerTagType.DRAGON_CHEER; + +/** Subset of {@linkcode BattlerTagType}s that remove one of the users' types */ +export type RemovedTypeTagType = BattlerTagType.DOUBLE_SHOCKED | BattlerTagType.BURNED_UP; + /** * Subset of {@linkcode BattlerTagType}s related to abilities that boost the highest stat. */ diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index edeff293aa0..59b040ca9d8 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -34,15 +34,19 @@ import type { StatStageChangeCallback } from "#phases/stat-stage-change-phase"; import i18next from "#plugins/i18n"; import type { AbilityBattlerTagType, + BattlerTagTypeData, ContactSetStatusProtectedTagType, ContactStatStageChangeProtectedTagType, + CritStageBoostTagType, DamageProtectedTagType, EndureTagType, HighestStatBoostTagType, MoveRestrictionBattlerTagType, ProtectionBattlerTagType, + RemovedTypeTagType, SemiInvulnerableTagType, TrappingBattlerTagType, + TypeBoostTagType, } from "#types/battler-tags"; import type { Mutable } from "#types/type-helpers"; import { BooleanHolder, coerceArray, getFrameMs, isNullOrUndefined, NumberHolder, toDmgValue } from "#utils/common"; @@ -203,6 +207,19 @@ export class SerializableBattlerTag extends BattlerTag { private declare __SerializableBattlerTag: never; } +/** + * Interface for a generic serializable battler tag, i.e. one that does not have a + * dedicated subclass. + * + * @remarks + * Used to ensure type safety when serializing battler tags, + * allowing typescript to properly infer the type of the tag. + * @see BattlerTagTypeMap + */ +interface GenericSerializableBattlerTag extends SerializableBattlerTag { + tagType: T; +} + /** * Base class for tags that restrict the usage of moves. This effect is generally referred to as "disabling" a move * in-game (not to be confused with {@linkcode MoveId.DISABLE}). @@ -560,6 +577,7 @@ export class BeakBlastChargingTag extends BattlerTag { * @see {@link https://bulbapedia.bulbagarden.net/wiki/Shell_Trap_(move) | Shell Trap} */ export class ShellTrapTag extends BattlerTag { + public override readonly tagType = BattlerTagType.SHELL_TRAP; public activated = false; constructor() { @@ -1144,6 +1162,7 @@ export class PowderTag extends BattlerTag { } export class NightmareTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.NIGHTMARE; constructor() { super(BattlerTagType.NIGHTMARE, BattlerTagLapseType.TURN_END, 1, MoveId.NIGHTMARE); } @@ -1197,6 +1216,7 @@ export class NightmareTag extends SerializableBattlerTag { } export class FrenzyTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.FRENZY; constructor(turnCount: number, sourceMove: MoveId, sourceId: number) { super(BattlerTagType.FRENZY, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); } @@ -2199,7 +2219,7 @@ export class SemiInvulnerableTag extends SerializableBattlerTag { } } -export class TypeImmuneTag extends SerializableBattlerTag { +export abstract class TypeImmuneTag extends SerializableBattlerTag { #immuneType: PokemonType; public get immuneType(): PokemonType { return this.#immuneType; @@ -2218,6 +2238,7 @@ export class TypeImmuneTag extends SerializableBattlerTag { * @see {@link https://bulbapedia.bulbagarden.net/wiki/Telekinesis_(move) | MoveId.TELEKINESIS} */ export class FloatingTag extends TypeImmuneTag { + public override readonly tagType = BattlerTagType.FLOATING; constructor(tagType: BattlerTagType, sourceMove: MoveId, turnCount: number) { super(tagType, sourceMove, PokemonType.GROUND, turnCount); } @@ -2247,6 +2268,7 @@ export class FloatingTag extends TypeImmuneTag { } export class TypeBoostTag extends SerializableBattlerTag { + public declare readonly tagType: TypeBoostTagType; #boostedType: PokemonType; #boostValue: number; #oneUse: boolean; @@ -2296,13 +2318,24 @@ export class TypeBoostTag extends SerializableBattlerTag { } export class CritBoostTag extends SerializableBattlerTag { - constructor(tagType: BattlerTagType, sourceMove: MoveId) { + public declare readonly tagType: CritStageBoostTagType; + /** The number of stages boosted by this tag */ + public readonly critStages: number; + + constructor(tagType: CritStageBoostTagType, sourceMove: MoveId) { super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove, undefined, true); } onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); + // Dragon cheer adds +2 crit stages if the pokemon is a Dragon type when the tag is added + if (this.tagType === BattlerTagType.DRAGON_CHEER && pokemon.getTypes(true).includes(PokemonType.DRAGON)) { + (this as Mutable).critStages = 2; + } else { + (this as Mutable).critStages = 1; + } + globalScene.phaseManager.queueMessage( i18next.t("battlerTags:critBoostOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), @@ -2323,23 +2356,12 @@ export class CritBoostTag extends SerializableBattlerTag { }), ); } -} -/** - * Tag for the effects of Dragon Cheer, which boosts the critical hit ratio of the user's allies. - */ -export class DragonCheerTag extends CritBoostTag { - /** The types of the user's ally when the tag is added */ - public typesOnAdd: PokemonType[]; - - constructor() { - super(BattlerTagType.CRIT_BOOST, MoveId.DRAGON_CHEER); - } - - onAdd(pokemon: Pokemon): void { - super.onAdd(pokemon); - - this.typesOnAdd = pokemon.getTypes(true); + public override loadTag(source: BaseBattlerTag & Pick): void { + super.loadTag(source); + // TODO: Remove the nullish coalescing once Zod Schemas come in + // For now, this is kept for backwards compatibility with older save files + (this as Mutable).critStages = source.critStages ?? 1; } } @@ -2398,6 +2420,7 @@ export class SaltCuredTag extends SerializableBattlerTag { } export class CursedTag extends SerializableBattlerTag { + public override readonly tagType = BattlerTagType.CURSED; constructor(sourceId: number) { super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, MoveId.CURSE, sourceId, true); } @@ -2444,7 +2467,8 @@ export class CursedTag extends SerializableBattlerTag { * Battler tag for attacks that remove a type post use. */ export class RemovedTypeTag extends SerializableBattlerTag { - constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, sourceMove: MoveId) { + public declare readonly tagType: RemovedTypeTagType; + constructor(tagType: RemovedTypeTagType, lapseType: BattlerTagLapseType, sourceMove: MoveId) { super(tagType, lapseType, 1, sourceMove); } } @@ -2454,7 +2478,8 @@ export class RemovedTypeTag extends SerializableBattlerTag { * @description `IGNORE_FLYING`: Persistent grounding effects (i.e. from Smack Down and Thousand Waves) */ export class GroundedTag extends SerializableBattlerTag { - constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, sourceMove: MoveId) { + public override readonly tagType = BattlerTagType.IGNORE_FLYING; + constructor(tagType: BattlerTagType.IGNORE_FLYING, lapseType: BattlerTagLapseType, sourceMove: MoveId) { super(tagType, lapseType, 1, sourceMove); } } @@ -3719,9 +3744,8 @@ export function getBattlerTag( case BattlerTagType.FIRE_BOOST: return new TypeBoostTag(tagType, sourceMove, PokemonType.FIRE, 1.5, false); case BattlerTagType.CRIT_BOOST: - return new CritBoostTag(tagType, sourceMove); case BattlerTagType.DRAGON_CHEER: - return new DragonCheerTag(); + return new CritBoostTag(tagType, sourceMove); case BattlerTagType.ALWAYS_CRIT: case BattlerTagType.IGNORE_ACCURACY: return new SerializableBattlerTag(tagType, BattlerTagLapseType.TURN_END, 2, sourceMove); @@ -3813,7 +3837,7 @@ export function getBattlerTag( * @param source - An object containing the data necessary to reconstruct the BattlerTag. * @returns The valid battler tag */ -export function loadBattlerTag(source: SerializableBattlerTag): BattlerTag { +export function loadBattlerTag(source: BattlerTag | BattlerTagTypeData): BattlerTag { // TODO: Remove this bang by fixing the signature of `getBattlerTag` // to allow undefined sourceIds and sourceMoves (with appropriate fallback for tags that require it) const tag = getBattlerTag(source.tagType, source.turnCount, source.sourceMove!, source.sourceId!); @@ -3854,7 +3878,7 @@ export type BattlerTagTypeMap = { [BattlerTagType.POWDER]: PowderTag; [BattlerTagType.NIGHTMARE]: NightmareTag; [BattlerTagType.FRENZY]: FrenzyTag; - [BattlerTagType.CHARGING]: SerializableBattlerTag; + [BattlerTagType.CHARGING]: GenericSerializableBattlerTag; [BattlerTagType.ENCORE]: EncoreTag; [BattlerTagType.HELPING_HAND]: HelpingHandTag; [BattlerTagType.INGRAIN]: IngrainTag; @@ -3894,11 +3918,11 @@ export type BattlerTagTypeMap = { [BattlerTagType.HIDDEN]: SemiInvulnerableTag; [BattlerTagType.FIRE_BOOST]: TypeBoostTag; [BattlerTagType.CRIT_BOOST]: CritBoostTag; - [BattlerTagType.DRAGON_CHEER]: DragonCheerTag; - [BattlerTagType.ALWAYS_CRIT]: SerializableBattlerTag; - [BattlerTagType.IGNORE_ACCURACY]: SerializableBattlerTag; - [BattlerTagType.ALWAYS_GET_HIT]: SerializableBattlerTag; - [BattlerTagType.RECEIVE_DOUBLE_DAMAGE]: SerializableBattlerTag; + [BattlerTagType.DRAGON_CHEER]: CritBoostTag; + [BattlerTagType.ALWAYS_CRIT]: GenericSerializableBattlerTag; + [BattlerTagType.IGNORE_ACCURACY]: GenericSerializableBattlerTag; + [BattlerTagType.ALWAYS_GET_HIT]: GenericSerializableBattlerTag; + [BattlerTagType.RECEIVE_DOUBLE_DAMAGE]: GenericSerializableBattlerTag; [BattlerTagType.BYPASS_SLEEP]: BattlerTag; [BattlerTagType.IGNORE_FLYING]: GroundedTag; [BattlerTagType.ROOSTED]: RoostedTag; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 7aecc0c8e75..7cb6f30c99e 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -25,7 +25,6 @@ import { AutotomizedTag, BattlerTag, CritBoostTag, - DragonCheerTag, EncoreTag, ExposedTag, GroundedTag, @@ -1390,8 +1389,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { const critBoostTag = source.getTag(CritBoostTag); if (critBoostTag) { // Dragon cheer only gives +1 crit stage to non-dragon types - critStage.value += - critBoostTag instanceof DragonCheerTag && !critBoostTag.typesOnAdd.includes(PokemonType.DRAGON) ? 1 : 2; + critStage.value += critBoostTag.critStages; } console.log(`crit stage: +${critStage.value}`); From c6ca35c4abee6149ab041696f879585c1feb9742 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Fri, 1 Aug 2025 12:59:53 -0600 Subject: [PATCH 66/76] [Misc] Set default for crit stage battler tag (#6192) Set default for crit stage --- src/data/battler-tags.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 59b040ca9d8..2e06b213e28 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2320,7 +2320,7 @@ export class TypeBoostTag extends SerializableBattlerTag { export class CritBoostTag extends SerializableBattlerTag { public declare readonly tagType: CritStageBoostTagType; /** The number of stages boosted by this tag */ - public readonly critStages: number; + public readonly critStages: number = 1; constructor(tagType: CritStageBoostTagType, sourceMove: MoveId) { super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove, undefined, true); From 93525b5803cf0891c709ada4210b5c03cd79278b Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Fri, 1 Aug 2025 13:38:43 -0600 Subject: [PATCH 67/76] [Bug] [Beta] Remove setting currentPhase to null in clearAllPhases (#6193) Remove setting currentPhase to null in clearAllPhases --- src/phase-manager.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/phase-manager.ts b/src/phase-manager.ts index 850f0c564ea..aa01a0ffc10 100644 --- a/src/phase-manager.ts +++ b/src/phase-manager.ts @@ -322,7 +322,6 @@ export class PhaseManager { queue.splice(0, queue.length); } this.dynamicPhaseQueues.forEach(queue => queue.clear()); - this.currentPhase = null; this.standbyPhase = null; this.clearPhaseQueueSplice(); } From 97ddcb711b5cf46a150a5e0366e620070e4071d6 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Sat, 2 Aug 2025 15:40:30 -0400 Subject: [PATCH 68/76] [Test] `game.move.use` overrides summon data moveset if present (#6174) * [Test] Update `game.move.use` to override summon data moveset if present * ran biome & fixed errors --- test/test-utils/helpers/move-helper.ts | 30 +++++++++++++++----------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/test/test-utils/helpers/move-helper.ts b/test/test-utils/helpers/move-helper.ts index 041df916cbf..6a01e4110da 100644 --- a/test/test-utils/helpers/move-helper.ts +++ b/test/test-utils/helpers/move-helper.ts @@ -143,7 +143,7 @@ export class MoveHelper extends GameManagerHelper { } } - /** Helper function to get the index of the selected move in the selected part member's moveset. */ + /** Helper function to get the index of the selected move in the selected party member's moveset. */ private getMovePosition(pokemonIndex: BattlerIndex.PLAYER | BattlerIndex.PLAYER_2, move: MoveId): number { const playerPokemon = this.game.scene.getPlayerField()[pokemonIndex]; const moveset = playerPokemon.getMoveset(); @@ -153,17 +153,18 @@ export class MoveHelper extends GameManagerHelper { } /** - * Modifies a player pokemon's moveset to contain only the selected move and then + * Modifies a player pokemon's moveset to contain only the selected move, and then * selects it to be used during the next {@linkcode CommandPhase}. * - * Warning: Will disable the player moveset override if it is enabled! + * **Warning**: Will disable the player moveset override if it is enabled, as well as any mid-battle moveset changes! * - * Note: If you need to check for changes in the player's moveset as part of the test, it may be - * best to use {@linkcode changeMoveset} and {@linkcode select} instead. - * @param moveId - the move to use - * @param pkmIndex - The {@linkcode BattlerIndex} of the player Pokemon using the move. Relevant for double battles only and defaults to {@linkcode BattlerIndex.PLAYER} if not specified. - * @param targetIndex - The {@linkcode BattlerIndex} of the Pokemon to target for single-target moves; should be omitted for multi-target moves. - * @param useTera - If `true`, the Pokemon will attempt to Terastallize even without a Tera Orb; default `false`. + * @param moveId - The {@linkcode MoveId} to use + * @param pkmIndex - The {@linkcode BattlerIndex} of the player Pokemon using the move. Relevant for double battles only and defaults to {@linkcode BattlerIndex.PLAYER} if not specified + * @param targetIndex - The {@linkcode BattlerIndex} of the Pokemon to target for single-target moves; should be omitted for multi-target moves + * @param useTera - If `true`, the Pokemon will attempt to Terastallize even without a Tera Orb; default `false` + * @remarks + * If you need to check for changes in the player's moveset as part of the test, it may be + * better to use {@linkcode changeMoveset} and {@linkcode select} instead. */ public use( moveId: MoveId, @@ -176,8 +177,11 @@ export class MoveHelper extends GameManagerHelper { console.warn("Warning: `MoveHelper.use` overwriting player pokemon moveset and disabling moveset override!"); } + // Clear out both the normal and temporary movesets before setting the move. const pokemon = this.game.scene.getPlayerField()[pkmIndex]; - pokemon.moveset = [new PokemonMove(moveId)]; + pokemon.moveset.splice(0); + pokemon.summonData.moveset?.splice(0); + pokemon.setMove(0, moveId); if (useTera) { this.selectWithTera(moveId, pkmIndex, targetIndex); @@ -211,7 +215,7 @@ export class MoveHelper extends GameManagerHelper { /** * Changes a pokemon's moveset to the given move(s). * - * Used when the normal moveset override can't be used (such as when it's necessary to check or update properties of the moveset). + * Useful when normal moveset overrides can't be used (such as when it's necessary to check or update properties of the moveset). * * **Note**: Will disable the moveset override matching the pokemon's party. * @param pokemon - The {@linkcode Pokemon} being modified @@ -232,8 +236,8 @@ export class MoveHelper extends GameManagerHelper { moveset = coerceArray(moveset); expect(moveset.length, "Cannot assign more than 4 moves to a moveset!").toBeLessThanOrEqual(4); pokemon.moveset = []; - moveset.forEach(move => { - pokemon.moveset.push(new PokemonMove(move)); + moveset.forEach((move, i) => { + pokemon.setMove(i, move); }); const movesetStr = moveset.map(moveId => MoveId[moveId]).join(", "); console.log(`Pokemon ${pokemon.species.name}'s moveset manually set to ${movesetStr} (=[${moveset.join(", ")}])!`); From 1f5e0898182d763617dcc3d3882b20235a8f683e Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Sat, 2 Aug 2025 16:48:51 -0400 Subject: [PATCH 69/76] [Beta] Remove non-Legend Fresh Start option, fix starting movesets https://github.com/pagefaultgames/pokerogue/pull/6196 * Remove non-Legend fresh start option, fix starting movesets * Move updateInfo call * Fix relearns counting for starter moves * Reduce array allocations and function calls --- src/data/challenge.ts | 27 ++++++++++++++------------- src/phases/select-starter-phase.ts | 6 +++++- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/data/challenge.ts b/src/data/challenge.ts index aaa82a7d20f..fd6528bb3bc 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -4,7 +4,6 @@ import { defaultStarterSpecies } from "#app/constants"; import { globalScene } from "#app/global-scene"; import { pokemonEvolutions } from "#balance/pokemon-evolutions"; import { speciesStarterCosts } from "#balance/starters"; -import { getEggTierForSpecies } from "#data/egg"; import { pokemonFormChanges } from "#data/pokemon-forms"; import type { PokemonSpecies } from "#data/pokemon-species"; import { getPokemonSpeciesForm } from "#data/pokemon-species"; @@ -12,7 +11,6 @@ import { BattleType } from "#enums/battle-type"; import { ChallengeType } from "#enums/challenge-type"; import { Challenges } from "#enums/challenges"; import { TypeColor, TypeShadow } from "#enums/color"; -import { EggTier } from "#enums/egg-type"; import { ClassicFixedBossWaves } from "#enums/fixed-boss-waves"; import { ModifierTier } from "#enums/modifier-tier"; import type { MoveId } from "#enums/move-id"; @@ -26,7 +24,7 @@ import type { Pokemon } from "#field/pokemon"; import { Trainer } from "#field/trainer"; import { PokemonMove } from "#moves/pokemon-move"; import type { DexAttrProps, GameData } from "#system/game-data"; -import { BooleanHolder, type NumberHolder, randSeedItem } from "#utils/common"; +import { BooleanHolder, isBetween, type NumberHolder, randSeedItem } from "#utils/common"; import { deepCopy } from "#utils/data"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import { toCamelCase, toSnakeCase } from "#utils/strings"; @@ -685,14 +683,11 @@ export class SingleTypeChallenge extends Challenge { */ export class FreshStartChallenge extends Challenge { constructor() { - super(Challenges.FRESH_START, 3); + super(Challenges.FRESH_START, 2); } applyStarterChoice(pokemon: PokemonSpecies, valid: BooleanHolder): boolean { - if ( - (this.value === 1 && !defaultStarterSpecies.includes(pokemon.speciesId)) || - (this.value === 2 && getEggTierForSpecies(pokemon) >= EggTier.EPIC) - ) { + if (this.value === 1 && !defaultStarterSpecies.includes(pokemon.speciesId)) { valid.value = false; return true; } @@ -708,12 +703,18 @@ export class FreshStartChallenge extends Challenge { pokemon.abilityIndex = pokemon.abilityIndex % 2; // Always base ability, if you set it to hidden it wraps to first ability pokemon.passive = false; // Passive isn't unlocked pokemon.nature = Nature.HARDY; // Neutral nature - pokemon.moveset = pokemon.species + let validMoves = pokemon.species .getLevelMoves() - .filter(m => m[0] <= 5) - .map(lm => lm[1]) - .slice(0, 4) - .map(m => new PokemonMove(m)); // No egg moves + .filter(m => isBetween(m[0], 1, 5)) + .map(lm => lm[1]); + // Filter egg moves out of the moveset + pokemon.moveset = pokemon.moveset.filter(pm => validMoves.includes(pm.moveId)); + if (pokemon.moveset.length < 4) { + // If there's empty slots fill with remaining valid moves + const existingMoveIds = pokemon.moveset.map(pm => pm.moveId); + validMoves = validMoves.filter(m => !existingMoveIds.includes(m)); + pokemon.moveset = pokemon.moveset.concat(validMoves.map(m => new PokemonMove(m))).slice(0, 4); + } pokemon.luck = 0; // No luck pokemon.shiny = false; // Not shiny pokemon.variant = 0; // Not shiny diff --git a/src/phases/select-starter-phase.ts b/src/phases/select-starter-phase.ts index 6456bacd0e3..d6bd252c77d 100644 --- a/src/phases/select-starter-phase.ts +++ b/src/phases/select-starter-phase.ts @@ -99,8 +99,12 @@ export class SelectStarterPhase extends Phase { starterPokemon.generateFusionSpecies(true); } starterPokemon.setVisible(false); - applyChallenges(ChallengeType.STARTER_MODIFY, starterPokemon); + const chalApplied = applyChallenges(ChallengeType.STARTER_MODIFY, starterPokemon); party.push(starterPokemon); + if (chalApplied) { + // If any challenges modified the starter, it should update + loadPokemonAssets.push(starterPokemon.updateInfo()); + } loadPokemonAssets.push(starterPokemon.loadAssets()); }); overrideModifiers(); From 957a3e5c24879c0df3ebca645529e01ff847f7df Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Sat, 2 Aug 2025 17:29:35 -0400 Subject: [PATCH 70/76] [Misc] Move asset initialization from `preload` to `launchBattle` https://github.com/pagefaultgames/pokerogue/pull/6109 * Move asset initialization into `preload` instead of `launchBattle` * Fix init problems; remove unused `waitUntil` util function * Fixed missing `clearAllPhases` call --- src/battle-scene.ts | 36 +++++++------ test/misc.test.ts | 29 ----------- test/test-utils/game-manager-utils.ts | 11 ---- test/test-utils/game-manager.ts | 73 ++++++++++++++++----------- 4 files changed, 60 insertions(+), 89 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 1864de2c6f4..e5a63285ecc 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -380,9 +380,21 @@ export class BattleScene extends SceneBase { }; } - populateAnims(); + /** + * These moves serve as fallback animations for other moves without loaded animations, and + * must be loaded prior to game start. + */ + const defaultMoves = [MoveId.TACKLE, MoveId.TAIL_WHIP, MoveId.FOCUS_ENERGY, MoveId.STRUGGLE]; - await this.initVariantData(); + await Promise.all([ + populateAnims(), + this.initVariantData(), + initCommonAnims().then(() => loadCommonAnimAssets(true)), + Promise.all(defaultMoves.map(m => initMoveAnim(m))).then(() => loadMoveAnimAssets(defaultMoves, true)), + this.initStarterColors(), + ]).catch(reason => { + throw new Error(`Unexpected error during BattleScene preLoad!\nReason: ${reason}`); + }); } create() { @@ -584,8 +596,6 @@ export class BattleScene extends SceneBase { this.party = []; - const loadPokemonAssets = []; - this.arenaPlayer = new ArenaBase(true); this.arenaPlayer.setName("arena-player"); this.arenaPlayerTransition = new ArenaBase(true); @@ -640,26 +650,14 @@ export class BattleScene extends SceneBase { this.reset(false, false, true); + // Initialize UI-related aspects and then start the login phase. const ui = new UI(); this.uiContainer.add(ui); - this.ui = ui; - ui.setup(); - const defaultMoves = [MoveId.TACKLE, MoveId.TAIL_WHIP, MoveId.FOCUS_ENERGY, MoveId.STRUGGLE]; - - Promise.all([ - Promise.all(loadPokemonAssets), - initCommonAnims().then(() => loadCommonAnimAssets(true)), - Promise.all( - [MoveId.TACKLE, MoveId.TAIL_WHIP, MoveId.FOCUS_ENERGY, MoveId.STRUGGLE].map(m => initMoveAnim(m)), - ).then(() => loadMoveAnimAssets(defaultMoves, true)), - this.initStarterColors(), - ]).then(() => { - this.phaseManager.toTitleScreen(true); - this.phaseManager.shiftPhase(); - }); + this.phaseManager.toTitleScreen(true); + this.phaseManager.shiftPhase(); } initSession(): void { diff --git a/test/misc.test.ts b/test/misc.test.ts index 96407b78470..a77ac1f5c91 100644 --- a/test/misc.test.ts +++ b/test/misc.test.ts @@ -1,5 +1,4 @@ import { GameManager } from "#test/test-utils/game-manager"; -import { waitUntil } from "#test/test-utils/game-manager-utils"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; @@ -36,19 +35,6 @@ describe("Test misc", () => { expect(spy).toHaveBeenCalled(); }); - // it.skip("test apifetch mock async", async () => { - // const spy = vi.fn(); - // await apiFetch("https://localhost:8080/account/info").then(response => { - // expect(response.status).toBe(200); - // expect(response.ok).toBe(true); - // return response.json(); - // }).then(data => { - // spy(); // Call the spy function - // expect(data).toEqual({ "username": "greenlamp", "lastSessionSlot": 0 }); - // }); - // expect(spy).toHaveBeenCalled(); - // }); - it("test fetch mock sync", async () => { const response = await fetch("https://localhost:8080/account/info"); const data = await response.json(); @@ -62,19 +48,4 @@ describe("Test misc", () => { const data = await game.scene.cachedFetch("./battle-anims/splishy-splash.json"); expect(data).toBeDefined(); }); - - it("testing wait phase queue", async () => { - const fakeScene = { - phaseQueue: [1, 2, 3], // Initially not empty - }; - setTimeout(() => { - fakeScene.phaseQueue = []; - }, 500); - const spy = vi.fn(); - await waitUntil(() => fakeScene.phaseQueue.length === 0).then(result => { - expect(result).toBe(true); - spy(); // Call the spy function - }); - expect(spy).toHaveBeenCalled(); - }); }); diff --git a/test/test-utils/game-manager-utils.ts b/test/test-utils/game-manager-utils.ts index db758cfe64d..7bb8ea57469 100644 --- a/test/test-utils/game-manager-utils.ts +++ b/test/test-utils/game-manager-utils.ts @@ -87,17 +87,6 @@ function getTestRunStarters(seed: string, species?: SpeciesId[]): Starter[] { return starters; } -export function waitUntil(truth): Promise { - return new Promise(resolve => { - const interval = setInterval(() => { - if (truth()) { - clearInterval(interval); - resolve(true); - } - }, 1000); - }); -} - /** * Useful for populating party, wave index, etc. without having to spin up and run through an entire EncounterPhase */ diff --git a/test/test-utils/game-manager.ts b/test/test-utils/game-manager.ts index 23a2e6240f8..f952557bb69 100644 --- a/test/test-utils/game-manager.ts +++ b/test/test-utils/game-manager.ts @@ -31,7 +31,7 @@ import { TurnEndPhase } from "#phases/turn-end-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; import { TurnStartPhase } from "#phases/turn-start-phase"; import { ErrorInterceptor } from "#test/test-utils/error-interceptor"; -import { generateStarter, waitUntil } from "#test/test-utils/game-manager-utils"; +import { generateStarter } from "#test/test-utils/game-manager-utils"; import { GameWrapper } from "#test/test-utils/game-wrapper"; import { ChallengeModeHelper } from "#test/test-utils/helpers/challenge-mode-helper"; import { ClassicModeHelper } from "#test/test-utils/helpers/classic-mode-helper"; @@ -85,30 +85,22 @@ export class GameManager { constructor(phaserGame: Phaser.Game, bypassLogin = true) { localStorage.clear(); ErrorInterceptor.getInstance().clear(); - BattleScene.prototype.randBattleSeedInt = (range, min = 0) => min + range - 1; // This simulates a max roll + // Simulate max rolls on RNG functions + // TODO: Create helpers for disabling/enabling battle RNG + BattleScene.prototype.randBattleSeedInt = (range, min = 0) => min + range - 1; this.gameWrapper = new GameWrapper(phaserGame, bypassLogin); - let firstTimeScene = false; + // TODO: Figure out a way to optimize and re-use the same game manager for each test + // Re-use an existing `globalScene` if present, or else create a new scene from scratch. if (globalScene) { this.scene = globalScene; + this.phaseInterceptor = new PhaseInterceptor(this.scene); + this.resetScene(); } else { this.scene = new BattleScene(); + this.phaseInterceptor = new PhaseInterceptor(this.scene); this.gameWrapper.setScene(this.scene); - firstTimeScene = true; - } - - this.phaseInterceptor = new PhaseInterceptor(this.scene); - - if (!firstTimeScene) { - this.scene.reset(false, true); - (this.scene.ui.handlers[UiMode.STARTER_SELECT] as StarterSelectUiHandler).clearStarterPreferences(); - - // Must be run after phase interceptor has been initialized. - this.scene.phaseManager.toTitleScreen(true); - this.scene.phaseManager.shiftPhase(); - - this.gameWrapper.scene = this.scene; } this.textInterceptor = new TextInterceptor(this.scene); @@ -122,10 +114,30 @@ export class GameManager { this.modifiers = new ModifierHelper(this); this.field = new FieldHelper(this); + this.initDefaultOverrides(); + + // TODO: remove `any` assertion + global.fetch = vi.fn(MockFetch) as any; + } + + /** Reset a prior `BattleScene` instance to the proper initial state. */ + private resetScene(): void { + this.scene.reset(false, true); + (this.scene.ui.handlers[UiMode.STARTER_SELECT] as StarterSelectUiHandler).clearStarterPreferences(); + + this.gameWrapper.scene = this.scene; + + this.scene.phaseManager.toTitleScreen(true); + this.scene.phaseManager.shiftPhase(); + } + + /** + * Initialize various default overrides for starting tests, typically to alleviate randomness. + */ + // TODO: This should not be here + private initDefaultOverrides(): void { // Disables Mystery Encounters on all tests (can be overridden at test level) this.override.mysteryEncounterChance(0); - - global.fetch = vi.fn(MockFetch) as any; } /** @@ -141,15 +153,13 @@ export class GameManager { * @param mode - The mode to wait for. * @returns A promise that resolves when the mode is set. */ - waitMode(mode: UiMode): Promise { - return new Promise(async resolve => { - await waitUntil(() => this.scene.ui?.getMode() === mode); - return resolve(); - }); + // TODO: This is unused + async waitMode(mode: UiMode): Promise { + await vi.waitUntil(() => this.scene.ui?.getMode() === mode); } /** - * Ends the current phase. + * End the currently running phase immediately. */ endPhase() { this.scene.phaseManager.getCurrentPhase()?.end(); @@ -283,11 +293,14 @@ export class GameManager { .getPokemon() .getMoveset() [movePosition].getMove(); - if (!move.isMultiTarget()) { - handler.setCursor(targetIndex !== undefined ? targetIndex : BattlerIndex.ENEMY); - } - if (move.isMultiTarget() && targetIndex !== undefined) { - expect.fail(`targetIndex was passed to selectMove() but move ("${move.name}") is not targetted`); + + // Multi target attacks do not select a target + if (move.isMultiTarget()) { + if (targetIndex !== undefined) { + expect.fail(`targetIndex was passed to selectMove() but move ("${move.name}") is not targeted`); + } + } else { + handler.setCursor(targetIndex ?? BattlerIndex.ENEMY); } handler.processInput(Button.ACTION); }, From acb1f4184b2d6c4f5b3a2ecb7a5c3dffbd57e5da Mon Sep 17 00:00:00 2001 From: Blitzy <118096277+Blitz425@users.noreply.github.com> Date: Sat, 2 Aug 2025 17:05:07 -0500 Subject: [PATCH 71/76] [Balance] Adjust Cosmog / Cosmoem Evolutions, Lower Buneary Friendship requirements (#6198) * Lower Buneary Friendship Requirement and Change Cosmog method * Update biomes.ts - Cosmog/Cosmoem wild evo levels * fix ? * fixed now * Update Cosmog Evolution + Biome Levels --------- Co-authored-by: damocleas --- src/data/balance/biomes.ts | 4 ++-- src/data/balance/pokemon-evolutions.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/data/balance/biomes.ts b/src/data/balance/biomes.ts index f84a518fb65..1298e80c362 100644 --- a/src/data/balance/biomes.ts +++ b/src/data/balance/biomes.ts @@ -1291,11 +1291,11 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.ALL]: [ { 1: [ SpeciesId.BELDUM ], 20: [ SpeciesId.METANG ], 45: [ SpeciesId.METAGROSS ] }, SpeciesId.SIGILYPH, { 1: [ SpeciesId.SOLOSIS ], 32: [ SpeciesId.DUOSION ], 41: [ SpeciesId.REUNICLUS ] } ] }, [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ SpeciesId.PORYGON ], 30: [ SpeciesId.PORYGON2 ] } ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ SpeciesId.COSMOG ], 23: [ SpeciesId.COSMOEM ] }, SpeciesId.CELESTEELA ] }, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ SpeciesId.COSMOG ], 60: [ SpeciesId.COSMOEM ] }, SpeciesId.CELESTEELA ] }, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [ SpeciesId.SOLROCK ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [ SpeciesId.LUNATONE ], [TimeOfDay.ALL]: [ SpeciesId.CLEFABLE, SpeciesId.BRONZONG, SpeciesId.MUSHARNA, SpeciesId.REUNICLUS, SpeciesId.MINIOR ] }, [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.METAGROSS, SpeciesId.PORYGON_Z ] }, [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.CELESTEELA ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [ SpeciesId.SOLGALEO ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [ SpeciesId.LUNALA ], [TimeOfDay.ALL]: [ SpeciesId.RAYQUAZA, SpeciesId.NECROZMA ] } + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [ { 1: [ SpeciesId.COSMOG ], 60: [ SpeciesId.COSMOEM ], 80: [ SpeciesId.SOLGALEO ] } ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [ { 1: [ SpeciesId.COSMOG ], 60: [ SpeciesId.COSMOEM ], 80: [ SpeciesId.LUNALA ] } ], [TimeOfDay.ALL]: [ SpeciesId.RAYQUAZA, SpeciesId.NECROZMA ] } }, [BiomeId.CONSTRUCTION_SITE]: { [BiomePoolTier.COMMON]: { diff --git a/src/data/balance/pokemon-evolutions.ts b/src/data/balance/pokemon-evolutions.ts index c632889326d..5183146ffc1 100644 --- a/src/data/balance/pokemon-evolutions.ts +++ b/src/data/balance/pokemon-evolutions.ts @@ -1191,11 +1191,11 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(SpeciesId.KOMMO_O, 45, null, null) ], [SpeciesId.COSMOG]: [ - new SpeciesEvolution(SpeciesId.COSMOEM, 23, null, null) + new SpeciesEvolution(SpeciesId.COSMOEM, 1, null, {key: EvoCondKey.FRIENDSHIP, value: 40}, SpeciesWildEvolutionDelay.VERY_LONG) ], [SpeciesId.COSMOEM]: [ - new SpeciesEvolution(SpeciesId.SOLGALEO, 1, EvolutionItem.SUN_FLUTE, null, SpeciesWildEvolutionDelay.VERY_LONG), - new SpeciesEvolution(SpeciesId.LUNALA, 1, EvolutionItem.MOON_FLUTE, null, SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(SpeciesId.SOLGALEO, 23, EvolutionItem.SUN_FLUTE, null, SpeciesWildEvolutionDelay.VERY_LONG), + new SpeciesEvolution(SpeciesId.LUNALA, 23, EvolutionItem.MOON_FLUTE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [SpeciesId.MELTAN]: [ new SpeciesEvolution(SpeciesId.MELMETAL, 48, null, null) @@ -1824,7 +1824,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(SpeciesId.ROSELIA, 1, null, [{key: EvoCondKey.FRIENDSHIP, value: 70}, {key: EvoCondKey.TIME, time: [TimeOfDay.DAWN, TimeOfDay.DAY]}], SpeciesWildEvolutionDelay.SHORT) ], [SpeciesId.BUNEARY]: [ - new SpeciesEvolution(SpeciesId.LOPUNNY, 1, null, {key: EvoCondKey.FRIENDSHIP, value: 70}, SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(SpeciesId.LOPUNNY, 1, null, {key: EvoCondKey.FRIENDSHIP, value: 50}, SpeciesWildEvolutionDelay.MEDIUM) ], [SpeciesId.CHINGLING]: [ new SpeciesEvolution(SpeciesId.CHIMECHO, 1, null, [{key: EvoCondKey.FRIENDSHIP, value: 90}, {key: EvoCondKey.TIME, time: [TimeOfDay.DUSK, TimeOfDay.NIGHT]}], SpeciesWildEvolutionDelay.MEDIUM) From 5ed9e152abf3dc2dbe04f98ccb72aed889648fd3 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Sat, 2 Aug 2025 18:35:06 -0400 Subject: [PATCH 72/76] [Test] Port over + augment remaining test matchers from pkty (#6159) * Partially ported over pkty matchers (WIP) * Cleaned up some more matchers * Fiexd up matchers * Fixed up remaining matchers * Removed the word "matcher" from the pkty matcher functions If we want them back we can always undo this commit and convert the other custom ones * Added wip spite test * Added `toHaveUsedPP` matcher * Fixed up docs and tests * Fixed spite test * Ran biome * Apply Biome * Reverted biome breaking i18next * Update src/typings/i18next.d.ts comment * Fixed log message to not be overly verbose * Added option to check for all PP used in pp matcher + cleaned up grudge tests * Fixed up tests * Fixed tests and such * Fix various TSDocs + missing TSDoc imports --- biome.jsonc | 3 +- global.d.ts | 10 +- src/@types/helpers/type-helpers.ts | 9 + src/data/battler-tags.ts | 1 + src/typings/i18next.d.ts | 1 + src/typings/phaser/index.d.ts | 42 ++-- src/vite.env.d.ts | 18 +- test/@types/vitest.d.ts | 135 +++++++++++-- test/matchers.setup.ts | 26 +++ test/moves/grudge.test.ts | 71 ++++--- test/moves/spite.test.ts | 126 ++++++++++++ .../matchers/to-equal-array-unsorted.ts | 46 +++-- .../matchers/to-have-ability-applied.ts | 43 ++++ .../matchers/to-have-battler-tag.ts | 43 ++++ .../matchers/to-have-effective-stat.ts | 66 +++++++ test/test-utils/matchers/to-have-fainted.ts | 35 ++++ test/test-utils/matchers/to-have-full-hp.ts | 35 ++++ test/test-utils/matchers/to-have-hp.ts | 35 ++++ .../test-utils/matchers/to-have-stat-stage.ts | 53 +++++ .../matchers/to-have-status-effect.ts | 83 ++++++++ .../matchers/to-have-taken-damage.ts | 46 +++++ test/test-utils/matchers/to-have-terrain.ts | 62 ++++++ test/test-utils/matchers/to-have-types.ts | 55 +++--- test/test-utils/matchers/to-have-used-move.ts | 70 +++++++ test/test-utils/matchers/to-have-used-pp.ts | 77 ++++++++ test/test-utils/matchers/to-have-weather.ts | 62 ++++++ test/test-utils/string-utils.ts | 183 ++++++++++++++++++ test/test-utils/test-utils.ts | 53 +++++ test/types/type-helpers.test-d.ts | 38 ++++ 29 files changed, 1395 insertions(+), 132 deletions(-) create mode 100644 test/moves/spite.test.ts create mode 100644 test/test-utils/matchers/to-have-ability-applied.ts create mode 100644 test/test-utils/matchers/to-have-battler-tag.ts create mode 100644 test/test-utils/matchers/to-have-effective-stat.ts create mode 100644 test/test-utils/matchers/to-have-fainted.ts create mode 100644 test/test-utils/matchers/to-have-full-hp.ts create mode 100644 test/test-utils/matchers/to-have-hp.ts create mode 100644 test/test-utils/matchers/to-have-stat-stage.ts create mode 100644 test/test-utils/matchers/to-have-status-effect.ts create mode 100644 test/test-utils/matchers/to-have-taken-damage.ts create mode 100644 test/test-utils/matchers/to-have-terrain.ts create mode 100644 test/test-utils/matchers/to-have-used-move.ts create mode 100644 test/test-utils/matchers/to-have-used-pp.ts create mode 100644 test/test-utils/matchers/to-have-weather.ts create mode 100644 test/test-utils/string-utils.ts create mode 100644 test/types/type-helpers.test-d.ts diff --git a/biome.jsonc b/biome.jsonc index 470885a543d..d2f7c711dc9 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -19,7 +19,6 @@ // and having to verify whether each individual file is ignored "includes": [ "**", - "!**/*.d.ts", "!**/dist/**/*", "!**/build/**/*", "!**/coverage/**/*", @@ -180,7 +179,7 @@ // Overrides to prevent unused import removal inside `overrides.ts` and enums files (for TSDoc linkcodes), // as well as in all TS files in `scripts/` (which are assumed to be boilerplate templates). { - "includes": ["**/src/overrides.ts", "**/src/enums/**/*", "**/scripts/**/*.ts"], + "includes": ["**/src/overrides.ts", "**/src/enums/**/*", "**/scripts/**/*.ts", "**/*.d.ts"], "linter": { "rules": { "correctness": { diff --git a/global.d.ts b/global.d.ts index 27e96a4d8b5..8b79d966e3c 100644 --- a/global.d.ts +++ b/global.d.ts @@ -1,7 +1,6 @@ +import type { AnyFn } from "#types/type-helpers"; import type { SetupServerApi } from "msw/node"; -export {}; - declare global { /** * Only used in testing. @@ -11,4 +10,11 @@ declare global { * To set up your own server in a test see `game-data.test.ts` */ var server: SetupServerApi; + + // Overloads for `Function.apply` and `Function.call` to add type safety on matching argument types + interface Function { + apply(this: T, thisArg: ThisParameterType, argArray: Parameters): ReturnType; + + call(this: T, thisArg: ThisParameterType, ...argArray: Parameters): ReturnType; + } } diff --git a/src/@types/helpers/type-helpers.ts b/src/@types/helpers/type-helpers.ts index 37f97fcf08c..7ad20b88956 100644 --- a/src/@types/helpers/type-helpers.ts +++ b/src/@types/helpers/type-helpers.ts @@ -94,3 +94,12 @@ export type AbstractConstructor = abstract new (...args: any[]) => T; export type CoerceNullPropertiesToUndefined = { [K in keyof T]: null extends T[K] ? Exclude | undefined : T[K]; }; + +/** + * Type helper to mark all properties in `T` as optional, while still mandating that at least 1 + * of its properties be present. + * + * Distinct from {@linkcode Partial} as this requires at least 1 property to _not_ be undefined. + * @typeParam T - The type to render partial + */ +export type AtLeastOne = Partial & ObjectValues<{ [K in keyof T]: Pick, K> }>; diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 2e06b213e28..2f540f5e1b9 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -3560,6 +3560,7 @@ export class GrudgeTag extends SerializableBattlerTag { * @param sourcePokemon - The source of the move that fainted the tag's bearer * @returns `false` if Grudge activates its effect or lapses */ + // TODO: Confirm whether this should interact with copying moves override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType, sourcePokemon?: Pokemon): boolean { if (lapseType === BattlerTagLapseType.CUSTOM && sourcePokemon) { if (sourcePokemon.isActive() && pokemon.isOpponent(sourcePokemon)) { diff --git a/src/typings/i18next.d.ts b/src/typings/i18next.d.ts index 0eaa1e6ff0f..1e1695f6b9a 100644 --- a/src/typings/i18next.d.ts +++ b/src/typings/i18next.d.ts @@ -3,6 +3,7 @@ import type { TOptions } from "i18next"; // Module declared to make referencing keys in the localization files type-safe. declare module "i18next" { interface TFunction { + // biome-ignore lint/style/useShorthandFunctionType: This needs to be an interface due to interface merging (key: string | string[], options?: TOptions & Record): string; } } diff --git a/src/typings/phaser/index.d.ts b/src/typings/phaser/index.d.ts index 26fbcff75bd..caddaedfc59 100644 --- a/src/typings/phaser/index.d.ts +++ b/src/typings/phaser/index.d.ts @@ -1,7 +1,7 @@ import "phaser"; declare module "phaser" { - namespace GameObjects { + namespace GameObjects { interface GameObject { width: number; @@ -16,45 +16,45 @@ declare module "phaser" { y: number; } - interface Container { + interface Container { /** * Sets this object's position relative to another object with a given offset */ - setPositionRelative(guideObject: any, x: number, y: number): this; - } - interface Sprite { + setPositionRelative(guideObject: any, x: number, y: number): this; + } + interface Sprite { /** * Sets this object's position relative to another object with a given offset */ - setPositionRelative(guideObject: any, x: number, y: number): this; - } - interface Image { + setPositionRelative(guideObject: any, x: number, y: number): this; + } + interface Image { /** * Sets this object's position relative to another object with a given offset */ - setPositionRelative(guideObject: any, x: number, y: number): this; - } - interface NineSlice { + setPositionRelative(guideObject: any, x: number, y: number): this; + } + interface NineSlice { /** * Sets this object's position relative to another object with a given offset */ - setPositionRelative(guideObject: any, x: number, y: number): this; - } - interface Text { + setPositionRelative(guideObject: any, x: number, y: number): this; + } + interface Text { /** * Sets this object's position relative to another object with a given offset */ - setPositionRelative(guideObject: any, x: number, y: number): this; - } - interface Rectangle { + setPositionRelative(guideObject: any, x: number, y: number): this; + } + interface Rectangle { /** * Sets this object's position relative to another object with a given offset */ - setPositionRelative(guideObject: any, x: number, y: number): this; - } - } + setPositionRelative(guideObject: any, x: number, y: number): this; + } + } - namespace Input { + namespace Input { namespace Gamepad { interface GamepadPlugin { /** diff --git a/src/vite.env.d.ts b/src/vite.env.d.ts index a2acc658a10..68159908730 100644 --- a/src/vite.env.d.ts +++ b/src/vite.env.d.ts @@ -1,16 +1,16 @@ /// interface ImportMetaEnv { - readonly VITE_PORT?: string; - readonly VITE_BYPASS_LOGIN?: string; - readonly VITE_BYPASS_TUTORIAL?: string; - readonly VITE_API_BASE_URL?: string; - readonly VITE_SERVER_URL?: string; - readonly VITE_DISCORD_CLIENT_ID?: string; - readonly VITE_GOOGLE_CLIENT_ID?: string; - readonly VITE_I18N_DEBUG?: string; + readonly VITE_PORT?: string; + readonly VITE_BYPASS_LOGIN?: string; + readonly VITE_BYPASS_TUTORIAL?: string; + readonly VITE_API_BASE_URL?: string; + readonly VITE_SERVER_URL?: string; + readonly VITE_DISCORD_CLIENT_ID?: string; + readonly VITE_GOOGLE_CLIENT_ID?: string; + readonly VITE_I18N_DEBUG?: string; } interface ImportMeta { - readonly env: ImportMetaEnv + readonly env: ImportMetaEnv; } diff --git a/test/@types/vitest.d.ts b/test/@types/vitest.d.ts index 58b36580727..7b756c45a57 100644 --- a/test/@types/vitest.d.ts +++ b/test/@types/vitest.d.ts @@ -1,26 +1,139 @@ -import type { Pokemon } from "#field/pokemon"; +import type { TerrainType } from "#app/data/terrain"; +import type { AbilityId } from "#enums/ability-id"; +import type { BattlerTagType } from "#enums/battler-tag-type"; +import type { MoveId } from "#enums/move-id"; import type { PokemonType } from "#enums/pokemon-type"; -import type { expect } from "vitest"; +import type { BattleStat, EffectiveStat, Stat } from "#enums/stat"; +import type { StatusEffect } from "#enums/status-effect"; +import type { WeatherType } from "#enums/weather-type"; +import type { Pokemon } from "#field/pokemon"; +import type { ToHaveEffectiveStatMatcherOptions } from "#test/test-utils/matchers/to-have-effective-stat"; +import type { expectedStatusType } from "#test/test-utils/matchers/to-have-status-effect"; import type { toHaveTypesOptions } from "#test/test-utils/matchers/to-have-types"; +import type { TurnMove } from "#types/turn-move"; +import type { AtLeastOne } from "#types/type-helpers"; +import type { expect } from "vitest"; +import type Overrides from "#app/overrides"; +import type { PokemonMove } from "#moves/pokemon-move"; declare module "vitest" { interface Assertion { /** - * Matcher to check if an array contains EXACTLY the given items (in any order). + * Check whether an array contains EXACTLY the given items (in any order). * - * Different from {@linkcode expect.arrayContaining} as the latter only requires the array contain - * _at least_ the listed items. + * Different from {@linkcode expect.arrayContaining} as the latter only checks for subset equality + * (as opposed to full equality). * - * @param expected - The expected contents of the array, in any order. + * @param expected - The expected contents of the array, in any order * @see {@linkcode expect.arrayContaining} */ toEqualArrayUnsorted(expected: E[]): void; + /** - * Matcher to check if a {@linkcode Pokemon}'s current typing includes the given types. + * Check whether a {@linkcode Pokemon}'s current typing includes the given types. * - * @param expected - The expected types (in any order). - * @param options - The options passed to the matcher. + * @param expected - The expected types (in any order) + * @param options - The options passed to the matcher */ - toHaveTypes(expected: PokemonType[], options?: toHaveTypesOptions): void; + toHaveTypes(expected: [PokemonType, ...PokemonType[]], options?: toHaveTypesOptions): void; + + /** + * Matcher to check the contents of a {@linkcode Pokemon}'s move history. + * + * @param expectedValue - The expected value; can be a {@linkcode MoveId} or a partially filled {@linkcode TurnMove} + * containing the desired properties to check + * @param index - The index of the move history entry to check, in order from most recent to least recent. + * Default `0` (last used move) + * @see {@linkcode Pokemon.getLastXMoves} + */ + toHaveUsedMove(expected: MoveId | AtLeastOne, index?: number): void; + + /** + * Check whether a {@linkcode Pokemon}'s effective stat is as expected + * (checked after all stat value modifications). + * + * @param stat - The {@linkcode EffectiveStat} to check + * @param expectedValue - The expected value of {@linkcode stat} + * @param options - (Optional) The {@linkcode ToHaveEffectiveStatMatcherOptions} + * @remarks + * If you want to check the stat **before** modifiers are applied, use {@linkcode Pokemon.getStat} instead. + */ + toHaveEffectiveStat(stat: EffectiveStat, expectedValue: number, options?: ToHaveEffectiveStatMatcherOptions): void; + + /** + * Check whether a {@linkcode Pokemon} has taken a specific amount of damage. + * @param expectedDamageTaken - The expected amount of damage taken + * @param roundDown - Whether to round down {@linkcode expectedDamageTaken} with {@linkcode toDmgValue}; default `true` + */ + toHaveTakenDamage(expectedDamageTaken: number, roundDown?: boolean): void; + + /** + * Check whether the current {@linkcode WeatherType} is as expected. + * @param expectedWeatherType - The expected {@linkcode WeatherType} + */ + toHaveWeather(expectedWeatherType: WeatherType): void; + + /** + * Check whether the current {@linkcode TerrainType} is as expected. + * @param expectedTerrainType - The expected {@linkcode TerrainType} + */ + toHaveTerrain(expectedTerrainType: TerrainType): void; + + /** + * Check whether a {@linkcode Pokemon} is at full HP. + */ + toHaveFullHp(): void; + + /** + * Check whether a {@linkcode Pokemon} has a specific {@linkcode StatusEffect | non-volatile status effect}. + * @param expectedStatusEffect - The {@linkcode StatusEffect} the Pokemon is expected to have, + * or a partially filled {@linkcode Status} containing the desired properties + */ + toHaveStatusEffect(expectedStatusEffect: expectedStatusType): void; + + /** + * Check whether a {@linkcode Pokemon} has a specific {@linkcode Stat} stage. + * @param stat - The {@linkcode BattleStat} to check + * @param expectedStage - The expected stat stage value of {@linkcode stat} + */ + toHaveStatStage(stat: BattleStat, expectedStage: number): void; + + /** + * Check whether a {@linkcode Pokemon} has a specific {@linkcode BattlerTagType}. + * @param expectedBattlerTagType - The expected {@linkcode BattlerTagType} + */ + toHaveBattlerTag(expectedBattlerTagType: BattlerTagType): void; + + /** + * Check whether a {@linkcode Pokemon} has applied a specific {@linkcode AbilityId}. + * @param expectedAbilityId - The expected {@linkcode AbilityId} + */ + toHaveAbilityApplied(expectedAbilityId: AbilityId): void; + + /** + * Check whether a {@linkcode Pokemon} has a specific amount of {@linkcode Stat.HP | HP}. + * @param expectedHp - The expected amount of {@linkcode Stat.HP | HP} to have + */ + toHaveHp(expectedHp: number): void; + + /** + * Check whether a {@linkcode Pokemon} is currently fainted (as determined by {@linkcode Pokemon.isFainted}). + * @remarks + * When checking whether an enemy wild Pokemon is fainted, one must reference it in a variable _before_ the fainting effect occurs + * as otherwise the Pokemon will be GC'ed and rendered `undefined`. + */ + toHaveFainted(): void; + + /** + * Check whether a {@linkcode Pokemon} has consumed the given amount of PP for one of its moves. + * @param expectedValue - The {@linkcode MoveId} of the {@linkcode PokemonMove} that should have consumed PP + * @param ppUsed - The numerical amount of PP that should have been consumed, + * or `all` to indicate the move should be _out_ of PP + * @remarks + * If the Pokemon's moveset has been set via {@linkcode Overrides.MOVESET_OVERRIDE}/{@linkcode Overrides.OPP_MOVESET_OVERRIDE}, + * does not contain {@linkcode expectedMove} + * or contains the desired move more than once, this will fail the test. + */ + toHaveUsedPP(expectedMove: MoveId, ppUsed: number | "all"): void; } -} \ No newline at end of file +} diff --git a/test/matchers.setup.ts b/test/matchers.setup.ts index 03d9dd342e4..03b29302916 100644 --- a/test/matchers.setup.ts +++ b/test/matchers.setup.ts @@ -1,5 +1,18 @@ import { toEqualArrayUnsorted } from "#test/test-utils/matchers/to-equal-array-unsorted"; +import { toHaveAbilityApplied } from "#test/test-utils/matchers/to-have-ability-applied"; +import { toHaveBattlerTag } from "#test/test-utils/matchers/to-have-battler-tag"; +import { toHaveEffectiveStat } from "#test/test-utils/matchers/to-have-effective-stat"; +import { toHaveFainted } from "#test/test-utils/matchers/to-have-fainted"; +import { toHaveFullHp } from "#test/test-utils/matchers/to-have-full-hp"; +import { toHaveHp } from "#test/test-utils/matchers/to-have-hp"; +import { toHaveStatStage } from "#test/test-utils/matchers/to-have-stat-stage"; +import { toHaveStatusEffect } from "#test/test-utils/matchers/to-have-status-effect"; +import { toHaveTakenDamage } from "#test/test-utils/matchers/to-have-taken-damage"; +import { toHaveTerrain } from "#test/test-utils/matchers/to-have-terrain"; import { toHaveTypes } from "#test/test-utils/matchers/to-have-types"; +import { toHaveUsedMove } from "#test/test-utils/matchers/to-have-used-move"; +import { toHaveUsedPP } from "#test/test-utils/matchers/to-have-used-pp"; +import { toHaveWeather } from "#test/test-utils/matchers/to-have-weather"; import { expect } from "vitest"; /* @@ -10,4 +23,17 @@ import { expect } from "vitest"; expect.extend({ toEqualArrayUnsorted, toHaveTypes, + toHaveUsedMove, + toHaveEffectiveStat, + toHaveTakenDamage, + toHaveWeather, + toHaveTerrain, + toHaveFullHp, + toHaveStatusEffect, + toHaveStatStage, + toHaveBattlerTag, + toHaveAbilityApplied, + toHaveHp, + toHaveFainted, + toHaveUsedPP, }); diff --git a/test/moves/grudge.test.ts b/test/moves/grudge.test.ts index 6f5df077d9f..d9e2f4f8320 100644 --- a/test/moves/grudge.test.ts +++ b/test/moves/grudge.test.ts @@ -2,6 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; +import { WeatherType } from "#enums/weather-type"; import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -23,68 +24,64 @@ describe("Moves - Grudge", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([MoveId.EMBER, MoveId.SPLASH]) .ability(AbilityId.BALL_FETCH) .battleStyle("single") .criticalHits(false) - .enemySpecies(SpeciesId.SHEDINJA) - .enemyAbility(AbilityId.WONDER_GUARD) - .enemyMoveset([MoveId.GRUDGE, MoveId.SPLASH]); + .enemySpecies(SpeciesId.RATTATA) + .startingLevel(100) + .enemyAbility(AbilityId.NO_GUARD); }); - it("should reduce the PP of the Pokemon's move to 0 when the user has fainted", async () => { + it("should reduce the PP of an attack that faints the user to 0", async () => { await game.classicMode.startBattle([SpeciesId.FEEBAS]); - const playerPokemon = game.scene.getPlayerPokemon(); - game.move.select(MoveId.EMBER); - await game.move.selectEnemyMove(MoveId.GRUDGE); + const feebas = game.field.getPlayerPokemon(); + const ratatta = game.field.getEnemyPokemon(); + + game.move.use(MoveId.GUILLOTINE); + await game.move.forceEnemyMove(MoveId.GRUDGE); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); - await game.phaseInterceptor.to("BerryPhase"); + await game.phaseInterceptor.to("FaintPhase"); - const playerMove = playerPokemon?.getMoveset().find(m => m.moveId === MoveId.EMBER); - - expect(playerMove?.getPpRatio()).toBe(0); + // Ratatta should have fainted and consumed all of Guillotine's PP + expect(ratatta).toHaveFainted(); + expect(feebas).toHaveUsedPP(MoveId.GUILLOTINE, "all"); }); it("should remain in effect until the user's next move", async () => { await game.classicMode.startBattle([SpeciesId.FEEBAS]); - const playerPokemon = game.scene.getPlayerPokemon(); - game.move.select(MoveId.SPLASH); - await game.move.selectEnemyMove(MoveId.GRUDGE); + const feebas = game.field.getPlayerPokemon(); + const ratatta = game.field.getEnemyPokemon(); + + game.move.use(MoveId.SPLASH); + await game.move.forceEnemyMove(MoveId.GRUDGE); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.toNextTurn(); - game.move.select(MoveId.EMBER); - await game.move.selectEnemyMove(MoveId.SPLASH); + game.move.use(MoveId.GUILLOTINE); + await game.move.forceEnemyMove(MoveId.SPLASH); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); - await game.phaseInterceptor.to("BerryPhase"); + await game.toEndOfTurn(); - const playerMove = playerPokemon?.getMoveset().find(m => m.moveId === MoveId.EMBER); - - expect(playerMove?.getPpRatio()).toBe(0); + expect(ratatta).toHaveFainted(); + expect(feebas).toHaveUsedPP(MoveId.GUILLOTINE, "all"); }); - it("should not reduce the opponent's PP if the user dies to weather/indirect damage", async () => { + it("should not reduce PP if the user dies to weather/indirect damage", async () => { // Opponent will be reduced to 1 HP by False Swipe, then faint to Sandstorm - game.override - .moveset([MoveId.FALSE_SWIPE]) - .startingLevel(100) - .ability(AbilityId.SAND_STREAM) - .enemySpecies(SpeciesId.RATTATA); - await game.classicMode.startBattle([SpeciesId.GEODUDE]); + game.override.weather(WeatherType.SANDSTORM); + await game.classicMode.startBattle([SpeciesId.FEEBAS]); - const enemyPokemon = game.scene.getEnemyPokemon(); - const playerPokemon = game.scene.getPlayerPokemon(); + const feebas = game.field.getPlayerPokemon(); + const ratatta = game.field.getEnemyPokemon(); - game.move.select(MoveId.FALSE_SWIPE); - await game.move.selectEnemyMove(MoveId.GRUDGE); + game.move.use(MoveId.FALSE_SWIPE); + await game.move.forceEnemyMove(MoveId.GRUDGE); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); - await game.phaseInterceptor.to("BerryPhase"); + await game.toEndOfTurn(); - expect(enemyPokemon?.isFainted()).toBe(true); - - const playerMove = playerPokemon?.getMoveset().find(m => m.moveId === MoveId.FALSE_SWIPE); - expect(playerMove?.getPpRatio()).toBeGreaterThan(0); + expect(ratatta).toHaveFainted(); + expect(feebas).toHaveUsedPP(MoveId.FALSE_SWIPE, 1); }); }); diff --git a/test/moves/spite.test.ts b/test/moves/spite.test.ts new file mode 100644 index 00000000000..56c1be76198 --- /dev/null +++ b/test/moves/spite.test.ts @@ -0,0 +1,126 @@ +import { AbilityId } from "#enums/ability-id"; +import { BattlerIndex } from "#enums/battler-index"; +import { MoveId } from "#enums/move-id"; +import { MoveResult } from "#enums/move-result"; +import { MoveUseMode } from "#enums/move-use-mode"; +import { SpeciesId } from "#enums/species-id"; +import { GameManager } from "#test/test-utils/game-manager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Spite", () => { + 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 + .ability(AbilityId.BALL_FETCH) + .battleStyle("single") + .criticalHits(false) + .enemySpecies(SpeciesId.MAGIKARP) + .enemyAbility(AbilityId.BALL_FETCH) + .startingLevel(100) + .enemyLevel(100); + }); + + it("should reduce the PP of the target's last used move by 4", async () => { + await game.classicMode.startBattle([SpeciesId.FEEBAS]); + + const karp = game.field.getEnemyPokemon(); + game.move.changeMoveset(karp, [MoveId.SPLASH, MoveId.TACKLE]); + + game.move.use(MoveId.SPITE); + await game.move.selectEnemyMove(MoveId.TACKLE); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.toNextTurn(); + + expect(karp).toHaveUsedPP(MoveId.TACKLE, 1); + + game.move.use(MoveId.SPITE); + await game.move.selectEnemyMove(MoveId.SPLASH); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.toEndOfTurn(); + + expect(karp).toHaveUsedPP(MoveId.TACKLE, 4 + 1); + }); + + it("should fail if the target has not used a move", async () => { + await game.classicMode.startBattle([SpeciesId.FEEBAS]); + + const karp = game.field.getEnemyPokemon(); + game.move.changeMoveset(karp, [MoveId.SPLASH, MoveId.TACKLE]); + + game.move.use(MoveId.SPITE); + await game.move.selectEnemyMove(MoveId.TACKLE); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.toEndOfTurn(); + + const feebas = game.field.getPlayerPokemon(); + expect(feebas).toHaveUsedMove({ move: MoveId.SPITE, result: MoveResult.FAIL }); + }); + + it("should fail if the target's last used move is out of PP", async () => { + await game.classicMode.startBattle([SpeciesId.FEEBAS]); + + const karp = game.field.getEnemyPokemon(); + game.move.changeMoveset(karp, [MoveId.TACKLE]); + karp.moveset[0].ppUsed = 0; + + game.move.use(MoveId.SPITE); + await game.move.selectEnemyMove(MoveId.TACKLE); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.toEndOfTurn(); + + const feebas = game.field.getPlayerPokemon(); + expect(feebas).toHaveUsedMove({ move: MoveId.SPITE, result: MoveResult.FAIL }); + }); + + it("should fail if the target's last used move is not in their moveset", async () => { + await game.classicMode.startBattle([SpeciesId.FEEBAS]); + + const karp = game.field.getEnemyPokemon(); + game.move.changeMoveset(karp, [MoveId.TACKLE]); + // Fake magikarp having used Splash the turn prior + karp.pushMoveHistory({ move: MoveId.SPLASH, targets: [BattlerIndex.ENEMY], useMode: MoveUseMode.NORMAL }); + + game.move.use(MoveId.SPITE); + await game.move.selectEnemyMove(MoveId.TACKLE); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.toEndOfTurn(); + + const feebas = game.field.getPlayerPokemon(); + expect(feebas).toHaveUsedMove({ move: MoveId.SPITE, result: MoveResult.FAIL }); + }); + + it("should ignore virtual and Dancer-induced moves", async () => { + game.override.battleStyle("double").enemyAbility(AbilityId.DANCER); + game.move.forceMetronomeMove(MoveId.SPLASH); + await game.classicMode.startBattle([SpeciesId.FEEBAS]); + + const [karp1, karp2] = game.scene.getEnemyField(); + game.move.changeMoveset(karp1, [MoveId.SPLASH, MoveId.METRONOME, MoveId.SWORDS_DANCE]); + game.move.changeMoveset(karp2, [MoveId.SWORDS_DANCE, MoveId.TACKLE]); + + game.move.use(MoveId.SPITE); + await game.move.selectEnemyMove(MoveId.METRONOME); + await game.move.selectEnemyMove(MoveId.SWORDS_DANCE); + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER]); + await game.toEndOfTurn(); + + // Spite ignored virtual splash and swords dance, instead only docking from metronome + expect(karp1).toHaveUsedPP(MoveId.SPLASH, 0); + expect(karp1).toHaveUsedPP(MoveId.SWORDS_DANCE, 0); + expect(karp1).toHaveUsedPP(MoveId.METRONOME, 5); + }); +}); diff --git a/test/test-utils/matchers/to-equal-array-unsorted.ts b/test/test-utils/matchers/to-equal-array-unsorted.ts index 0627623bbd9..846ea9e7779 100644 --- a/test/test-utils/matchers/to-equal-array-unsorted.ts +++ b/test/test-utils/matchers/to-equal-array-unsorted.ts @@ -1,43 +1,47 @@ +import { getOnelineDiffStr } from "#test/test-utils/string-utils"; import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; /** - * Matcher to check if an array contains exactly the given items, disregarding order. - * @param received - The object to check. Should be an array of elements. - * @returns The result of the matching + * Matcher that checks if an array contains exactly the given items, disregarding order. + * @param received - The received value. Should be an array of elements + * @param expected - The array to check equality with + * @returns Whether the matcher passed */ -export function toEqualArrayUnsorted(this: MatcherState, received: unknown, expected: unknown): SyncExpectationResult { +export function toEqualArrayUnsorted( + this: MatcherState, + received: unknown, + expected: unknown[], +): SyncExpectationResult { if (!Array.isArray(received)) { return { - pass: this.isNot, + pass: false, message: () => `Expected an array, but got ${this.utils.stringify(received)}!`, }; } - if (!Array.isArray(expected)) { - return { - pass: this.isNot, - message: () => `Expected to recieve an array, but got ${this.utils.stringify(expected)}!`, - }; - } - if (received.length !== expected.length) { return { - pass: this.isNot, - message: () => `Expected to recieve array of length ${received.length}, but got ${expected.length}!`, + pass: false, + message: () => `Expected to receive array of length ${received.length}, but got ${expected.length} instead!`, actual: received, expected, }; } - const gotSorted = received.slice().sort(); - const wantSorted = expected.slice().sort(); - const pass = this.equals(gotSorted, wantSorted, [...this.customTesters, this.utils.iterableEquality]); + const actualSorted = received.slice().sort(); + const expectedSorted = expected.slice().sort(); + const pass = this.equals(actualSorted, expectedSorted, [...this.customTesters, this.utils.iterableEquality]); + + const actualStr = getOnelineDiffStr.call(this, actualSorted); + const expectedStr = getOnelineDiffStr.call(this, expectedSorted); return { - pass: this.isNot !== pass, + pass, message: () => - `Expected ${this.utils.stringify(received)} to exactly equal ${this.utils.stringify(expected)} without order!`, - actual: gotSorted, - expected: wantSorted, + pass + ? `Expected ${actualStr} to NOT exactly equal ${expectedStr} without order, but it did!` + : `Expected ${actualStr} to exactly equal ${expectedStr} without order, but it didn't!`, + expected: expectedSorted, + actual: actualSorted, }; } diff --git a/test/test-utils/matchers/to-have-ability-applied.ts b/test/test-utils/matchers/to-have-ability-applied.ts new file mode 100644 index 00000000000..a3921e6371c --- /dev/null +++ b/test/test-utils/matchers/to-have-ability-applied.ts @@ -0,0 +1,43 @@ +/* biome-ignore-start lint/correctness/noUnusedImports: tsdoc imports */ +import type { Pokemon } from "#field/pokemon"; +/* biome-ignore-end lint/correctness/noUnusedImports: tsdoc imports */ + +import { getPokemonNameWithAffix } from "#app/messages"; +import { AbilityId } from "#enums/ability-id"; +import { getEnumStr } from "#test/test-utils/string-utils"; +import { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +/** + * Matcher that checks if a {@linkcode Pokemon} has applied a specific {@linkcode AbilityId}. + * @param received - The object to check. Should be a {@linkcode Pokemon} + * @param expectedAbility - The {@linkcode AbilityId} to check for + * @returns Whether the matcher passed + */ +export function toHaveAbilityApplied( + this: MatcherState, + received: unknown, + expectedAbilityId: AbilityId, +): SyncExpectationResult { + if (!isPokemonInstance(received)) { + return { + pass: false, + message: () => `Expected to recieve a Pokemon, but got ${receivedStr(received)}!`, + }; + } + + const pass = received.waveData.abilitiesApplied.has(expectedAbilityId); + + const pkmName = getPokemonNameWithAffix(received); + const expectedAbilityStr = getEnumStr(AbilityId, expectedAbilityId); + + return { + pass, + message: () => + pass + ? `Expected ${pkmName} to NOT have applied ${expectedAbilityStr}, but it did!` + : `Expected ${pkmName} to have applied ${expectedAbilityStr}, but it didn't!`, + expected: expectedAbilityId, + actual: received.waveData.abilitiesApplied, + }; +} diff --git a/test/test-utils/matchers/to-have-battler-tag.ts b/test/test-utils/matchers/to-have-battler-tag.ts new file mode 100644 index 00000000000..af405d7da39 --- /dev/null +++ b/test/test-utils/matchers/to-have-battler-tag.ts @@ -0,0 +1,43 @@ +/* biome-ignore-start lint/correctness/noUnusedImports: tsdoc imports */ +import type { Pokemon } from "#field/pokemon"; +/* biome-ignore-end lint/correctness/noUnusedImports: tsdoc imports */ + +import { getPokemonNameWithAffix } from "#app/messages"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { getEnumStr } from "#test/test-utils/string-utils"; +import { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +/** + * Matcher that checks if a {@linkcode Pokemon} has a specific {@linkcode BattlerTagType}. + * @param received - The object to check. Should be a {@linkcode Pokemon} + * @param expectedBattlerTagType - The {@linkcode BattlerTagType} to check for + * @returns Whether the matcher passed + */ +export function toHaveBattlerTag( + this: MatcherState, + received: unknown, + expectedBattlerTagType: BattlerTagType, +): SyncExpectationResult { + if (!isPokemonInstance(received)) { + return { + pass: this.isNot, + message: () => `Expected to receive a Pokémon, but got ${receivedStr(received)}!`, + }; + } + + const pass = !!received.getTag(expectedBattlerTagType); + const pkmName = getPokemonNameWithAffix(received); + // "BattlerTagType.SEEDED (=1)" + const expectedTagStr = getEnumStr(BattlerTagType, expectedBattlerTagType, { prefix: "BattlerTagType." }); + + return { + pass, + message: () => + pass + ? `Expected ${pkmName} to NOT have ${expectedTagStr}, but it did!` + : `Expected ${pkmName} to have ${expectedTagStr}, but it didn't!`, + expected: expectedBattlerTagType, + actual: received.summonData.tags.map(t => t.tagType), + }; +} diff --git a/test/test-utils/matchers/to-have-effective-stat.ts b/test/test-utils/matchers/to-have-effective-stat.ts new file mode 100644 index 00000000000..bc10a646c02 --- /dev/null +++ b/test/test-utils/matchers/to-have-effective-stat.ts @@ -0,0 +1,66 @@ +import { getPokemonNameWithAffix } from "#app/messages"; +import type { EffectiveStat } from "#enums/stat"; +import type { Pokemon } from "#field/pokemon"; +import type { Move } from "#moves/move"; +import { getStatName } from "#test/test-utils/string-utils"; +import { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +export interface ToHaveEffectiveStatMatcherOptions { + /** + * The target {@linkcode Pokemon} + * @see {@linkcode Pokemon.getEffectiveStat} + */ + enemy?: Pokemon; + /** + * The {@linkcode Move} being used + * @see {@linkcode Pokemon.getEffectiveStat} + */ + move?: Move; + /** + * Whether a critical hit occurred or not + * @see {@linkcode Pokemon.getEffectiveStat} + * @defaultValue `false` + */ + isCritical?: boolean; +} + +/** + * Matcher that checks if a {@linkcode Pokemon}'s effective stat equals a certain value. + * @param received - The object to check. Should be a {@linkcode Pokemon} + * @param stat - The {@linkcode EffectiveStat} to check + * @param expectedValue - The expected value of the {@linkcode stat} + * @param options - The {@linkcode ToHaveEffectiveStatMatcherOptions} + * @returns Whether the matcher passed + */ +export function toHaveEffectiveStat( + this: MatcherState, + received: unknown, + stat: EffectiveStat, + expectedValue: number, + { enemy, move, isCritical = false }: ToHaveEffectiveStatMatcherOptions = {}, +): SyncExpectationResult { + if (!isPokemonInstance(received)) { + return { + pass: false, + message: () => `Expected to receive a Pokémon, but got ${receivedStr(received)}!`, + }; + } + + // TODO: Change once getEffectiveStat is refactored to take an object literal + const actualValue = received.getEffectiveStat(stat, enemy, move, undefined, undefined, undefined, isCritical); + const pass = actualValue === expectedValue; + + const pkmName = getPokemonNameWithAffix(received); + const statName = getStatName(stat); + + return { + pass, + message: () => + pass + ? `Expected ${pkmName} to NOT have ${expectedValue} ${statName}, but it did!` + : `Expected ${pkmName} to have ${expectedValue} ${statName}, but got ${actualValue} instead!`, + expected: expectedValue, + actual: actualValue, + }; +} diff --git a/test/test-utils/matchers/to-have-fainted.ts b/test/test-utils/matchers/to-have-fainted.ts new file mode 100644 index 00000000000..73ca96a31b5 --- /dev/null +++ b/test/test-utils/matchers/to-have-fainted.ts @@ -0,0 +1,35 @@ +import { getPokemonNameWithAffix } from "#app/messages"; +// biome-ignore lint/correctness/noUnusedImports: TSDoc +import type { Pokemon } from "#field/pokemon"; +import { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +/** + * Matcher that checks if a {@linkcode Pokemon} has fainted. + * @param received - The object to check. Should be a {@linkcode Pokemon} + * @returns Whether the matcher passed + */ +export function toHaveFainted(this: MatcherState, received: unknown): SyncExpectationResult { + if (!isPokemonInstance(received)) { + return { + pass: false, + message: () => `Expected to receive a Pokémon, but got ${receivedStr(received)}!`, + }; + } + + const pass = received.isFainted(); + + const hp = received.hp; + const maxHp = received.getMaxHp(); + const pkmName = getPokemonNameWithAffix(received); + + return { + pass, + message: () => + pass + ? `Expected ${pkmName} to NOT have fainted, but it did!` + : `Expected ${pkmName} to have fainted, but it didn't! (${hp}/${maxHp} HP)`, + expected: 0, + actual: hp, + }; +} diff --git a/test/test-utils/matchers/to-have-full-hp.ts b/test/test-utils/matchers/to-have-full-hp.ts new file mode 100644 index 00000000000..3d7c8f9458d --- /dev/null +++ b/test/test-utils/matchers/to-have-full-hp.ts @@ -0,0 +1,35 @@ +import { getPokemonNameWithAffix } from "#app/messages"; +// biome-ignore lint/correctness/noUnusedImports: TSDoc +import type { Pokemon } from "#field/pokemon"; +import { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +/** + * Matcher that checks if a {@linkcode Pokemon} is at full hp. + * @param received - The object to check. Should be a {@linkcode Pokemon}. + * @returns Whether the matcher passed + */ +export function toHaveFullHp(this: MatcherState, received: unknown): SyncExpectationResult { + if (!isPokemonInstance(received)) { + return { + pass: false, + message: () => `Expected to receive a Pokémon, but got ${receivedStr(received)}!`, + }; + } + + const pass = received.isFullHp(); + + const hp = received.hp; + const maxHp = received.getMaxHp(); + const pkmName = getPokemonNameWithAffix(received); + + return { + pass, + message: () => + pass + ? `Expected ${pkmName} to NOT have full hp, but it did!` + : `Expected ${pkmName} to have full hp, but it didn't! (${hp}/${maxHp} HP)`, + expected: maxHp, + actual: hp, + }; +} diff --git a/test/test-utils/matchers/to-have-hp.ts b/test/test-utils/matchers/to-have-hp.ts new file mode 100644 index 00000000000..20d171b23ce --- /dev/null +++ b/test/test-utils/matchers/to-have-hp.ts @@ -0,0 +1,35 @@ +import { getPokemonNameWithAffix } from "#app/messages"; +// biome-ignore lint/correctness/noUnusedImports: TSDoc +import type { Pokemon } from "#field/pokemon"; +import { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +/** + * Matcher that checks if a Pokemon has a specific amount of HP. + * @param received - The object to check. Should be a {@linkcode Pokemon}. + * @param expectedHp - The expected amount of HP the {@linkcode Pokemon} has + * @returns Whether the matcher passed + */ +export function toHaveHp(this: MatcherState, received: unknown, expectedHp: number): SyncExpectationResult { + if (!isPokemonInstance(received)) { + return { + pass: false, + message: () => `Expected to receive a Pokémon, but got ${receivedStr(received)}!`, + }; + } + + const actualHp = received.hp; + const pass = actualHp === expectedHp; + + const pkmName = getPokemonNameWithAffix(received); + + return { + pass, + message: () => + pass + ? `Expected ${pkmName} to NOT have ${expectedHp} HP, but it did!` + : `Expected ${pkmName} to have ${expectedHp} HP, but got ${actualHp} HP instead!`, + expected: expectedHp, + actual: actualHp, + }; +} diff --git a/test/test-utils/matchers/to-have-stat-stage.ts b/test/test-utils/matchers/to-have-stat-stage.ts new file mode 100644 index 00000000000..feecd650bef --- /dev/null +++ b/test/test-utils/matchers/to-have-stat-stage.ts @@ -0,0 +1,53 @@ +/** biome-ignore-start lint/correctness/noUnusedImports: TSDoc imports */ +import type { Pokemon } from "#field/pokemon"; +/** biome-ignore-end lint/correctness/noUnusedImports: TSDoc imports */ + +import { getPokemonNameWithAffix } from "#app/messages"; +import type { BattleStat } from "#enums/stat"; +import { getStatName } from "#test/test-utils/string-utils"; +import { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +/** + * Matcher that checks if a Pokemon has a specific {@linkcode BattleStat | Stat} stage. + * @param received - The object to check. Should be a {@linkcode Pokemon}. + * @param stat - The {@linkcode BattleStat | Stat} to check + * @param expectedStage - The expected numerical value of {@linkcode stat}; should be within the range `[-6, 6]` + * @returns Whether the matcher passed + */ +export function toHaveStatStage( + this: MatcherState, + received: unknown, + stat: BattleStat, + expectedStage: number, +): SyncExpectationResult { + if (!isPokemonInstance(received)) { + return { + pass: false, + message: () => `Expected to receive a Pokémon, but got ${receivedStr(received)}!`, + }; + } + + if (expectedStage < -6 || expectedStage > 6) { + return { + pass: false, + message: () => `Expected ${expectedStage} to be within the range [-6, 6]!`, + }; + } + + const actualStage = received.getStatStage(stat); + const pass = actualStage === expectedStage; + + const pkmName = getPokemonNameWithAffix(received); + const statName = getStatName(stat); + + return { + pass, + message: () => + pass + ? `Expected ${pkmName}'s ${statName} stat stage to NOT be ${expectedStage}, but it was!` + : `Expected ${pkmName}'s ${statName} stat stage to be ${expectedStage}, but got ${actualStage} instead!`, + expected: expectedStage, + actual: actualStage, + }; +} diff --git a/test/test-utils/matchers/to-have-status-effect.ts b/test/test-utils/matchers/to-have-status-effect.ts new file mode 100644 index 00000000000..a46800632f3 --- /dev/null +++ b/test/test-utils/matchers/to-have-status-effect.ts @@ -0,0 +1,83 @@ +/* biome-ignore-start lint/correctness/noUnusedImports: tsdoc imports */ +import type { Status } from "#data/status-effect"; +import type { Pokemon } from "#field/pokemon"; +/* biome-ignore-end lint/correctness/noUnusedImports: tsdoc imports */ + +import { getPokemonNameWithAffix } from "#app/messages"; +import { StatusEffect } from "#enums/status-effect"; +import { getEnumStr, getOnelineDiffStr } from "#test/test-utils/string-utils"; +import { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +export type expectedStatusType = + | StatusEffect + | { effect: StatusEffect.TOXIC; toxicTurnCount: number } + | { effect: StatusEffect.SLEEP; sleepTurnsRemaining: number }; + +/** + * Matcher that checks if a Pokemon's {@linkcode StatusEffect} is as expected + * @param received - The actual value received. Should be a {@linkcode Pokemon} + * @param expectedStatus - The {@linkcode StatusEffect} the Pokemon is expected to have, + * or a partially filled {@linkcode Status} containing the desired properties + * @returns Whether the matcher passed + */ +export function toHaveStatusEffect( + this: MatcherState, + received: unknown, + expectedStatus: expectedStatusType, +): SyncExpectationResult { + if (!isPokemonInstance(received)) { + return { + pass: false, + message: () => `Expected to receive a Pokémon, but got ${receivedStr(received)}!`, + }; + } + + const pkmName = getPokemonNameWithAffix(received); + const actualEffect = received.status?.effect ?? StatusEffect.NONE; + + // Check exclusively effect equality first, coercing non-matching status effects to numbers. + if (actualEffect !== (expectedStatus as Exclude)?.effect) { + // This is actually 100% safe as `expectedStatus?.effect` will evaluate to `undefined` if a StatusEffect was passed, + // which will never match actualEffect by definition + expectedStatus = (expectedStatus as Exclude).effect; + } + + if (typeof expectedStatus === "number") { + const pass = this.equals(actualEffect, expectedStatus, [...this.customTesters, this.utils.iterableEquality]); + + const actualStr = getEnumStr(StatusEffect, actualEffect, { prefix: "StatusEffect." }); + const expectedStr = getEnumStr(StatusEffect, expectedStatus, { prefix: "StatusEffect." }); + + return { + pass, + message: () => + pass + ? `Expected ${pkmName} to NOT have ${expectedStr}, but it did!` + : `Expected ${pkmName} to have status effect ${expectedStr}, but got ${actualStr} instead!`, + expected: expectedStatus, + actual: actualEffect, + }; + } + + // Check for equality of all fields (for toxic turn count/etc) + const actualStatus = received.status; + const pass = this.equals(received, expectedStatus, [ + ...this.customTesters, + this.utils.subsetEquality, + this.utils.iterableEquality, + ]); + + const expectedStr = getOnelineDiffStr.call(this, expectedStatus); + const actualStr = getOnelineDiffStr.call(this, actualStatus); + + return { + pass, + message: () => + pass + ? `Expected ${pkmName}'s status to NOT match ${expectedStr}, but it did!` + : `Expected ${pkmName}'s status to match ${expectedStr}, but got ${actualStr} instead!`, + expected: expectedStatus, + actual: actualStatus, + }; +} diff --git a/test/test-utils/matchers/to-have-taken-damage.ts b/test/test-utils/matchers/to-have-taken-damage.ts new file mode 100644 index 00000000000..77c60ae836a --- /dev/null +++ b/test/test-utils/matchers/to-have-taken-damage.ts @@ -0,0 +1,46 @@ +/** biome-ignore-start lint/correctness/noUnusedImports: TSDoc imports */ +import type { Pokemon } from "#field/pokemon"; +/** biome-ignore-end lint/correctness/noUnusedImports: TSDoc imports */ + +import { getPokemonNameWithAffix } from "#app/messages"; +import { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils"; +import { toDmgValue } from "#utils/common"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +/** + * Matcher that checks if a Pokemon has taken a specific amount of damage. + * Unless specified, will run the expected damage value through {@linkcode toDmgValue} + * to round it down and make it a minimum of 1. + * @param received - The object to check. Should be a {@linkcode Pokemon}. + * @param expectedDamageTaken - The expected amount of damage the {@linkcode Pokemon} has taken + * @param roundDown - Whether to round down {@linkcode expectedDamageTaken} with {@linkcode toDmgValue}; default `true` + * @returns Whether the matcher passed + */ +export function toHaveTakenDamage( + this: MatcherState, + received: unknown, + expectedDamageTaken: number, + roundDown = true, +): SyncExpectationResult { + if (!isPokemonInstance(received)) { + return { + pass: false, + message: () => `Expected to receive a Pokémon, but got ${receivedStr(received)}!`, + }; + } + + const expectedDmgValue = roundDown ? toDmgValue(expectedDamageTaken) : expectedDamageTaken; + const actualDmgValue = received.getInverseHp(); + const pass = actualDmgValue === expectedDmgValue; + const pkmName = getPokemonNameWithAffix(received); + + return { + pass, + message: () => + pass + ? `Expected ${pkmName} to NOT have taken ${expectedDmgValue} damage, but it did!` + : `Expected ${pkmName} to have taken ${expectedDmgValue} damage, but got ${actualDmgValue} instead!`, + expected: expectedDmgValue, + actual: actualDmgValue, + }; +} diff --git a/test/test-utils/matchers/to-have-terrain.ts b/test/test-utils/matchers/to-have-terrain.ts new file mode 100644 index 00000000000..292c32abafc --- /dev/null +++ b/test/test-utils/matchers/to-have-terrain.ts @@ -0,0 +1,62 @@ +/** biome-ignore-start lint/correctness/noUnusedImports: TSDoc imports */ +import type { GameManager } from "#test/test-utils/game-manager"; +/** biome-ignore-end lint/correctness/noUnusedImports: TSDoc imports */ + +import { TerrainType } from "#app/data/terrain"; +import { getEnumStr } from "#test/test-utils/string-utils"; +import { isGameManagerInstance, receivedStr } from "#test/test-utils/test-utils"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +/** + * Matcher that checks if the {@linkcode TerrainType} is as expected + * @param received - The object to check. Should be an instance of {@linkcode GameManager}. + * @param expectedTerrainType - The expected {@linkcode TerrainType}, or {@linkcode TerrainType.NONE} if no terrain should be active + * @returns Whether the matcher passed + */ +export function toHaveTerrain( + this: MatcherState, + received: unknown, + expectedTerrainType: TerrainType, +): SyncExpectationResult { + if (!isGameManagerInstance(received)) { + return { + pass: false, + message: () => `Expected GameManager, but got ${receivedStr(received)}!`, + }; + } + + if (!received.scene?.arena) { + return { + pass: false, + message: () => `Expected GameManager.${received.scene ? "scene" : "scene.arena"} to be defined!`, + }; + } + + const actual = received.scene.arena.getTerrainType(); + const pass = actual === expectedTerrainType; + const actualStr = toTerrainStr(actual); + const expectedStr = toTerrainStr(expectedTerrainType); + + return { + pass, + message: () => + pass + ? `Expected Arena to NOT have ${expectedStr} active, but it did!` + : `Expected Arena to have ${expectedStr} active, but got ${actualStr} instead!`, + expected: expectedTerrainType, + actual, + }; +} + +/** + * Get a human readable string of the current {@linkcode TerrainType}. + * @param terrainType - The {@linkcode TerrainType} to transform + * @returns A human readable string + */ +function toTerrainStr(terrainType: TerrainType) { + if (terrainType === TerrainType.NONE) { + return "no terrain"; + } + // "Electric Terrain (=2)" + return getEnumStr(TerrainType, terrainType, { casing: "Title", suffix: " Terrain" }); +} diff --git a/test/test-utils/matchers/to-have-types.ts b/test/test-utils/matchers/to-have-types.ts index d09f4fc5f76..3f16f740583 100644 --- a/test/test-utils/matchers/to-have-types.ts +++ b/test/test-utils/matchers/to-have-types.ts @@ -1,6 +1,9 @@ +import { getPokemonNameWithAffix } from "#app/messages"; import { PokemonType } from "#enums/pokemon-type"; -import { Pokemon } from "#field/pokemon"; +import type { Pokemon } from "#field/pokemon"; +import { stringifyEnumArray } from "#test/test-utils/string-utils"; import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; +import { isPokemonInstance, receivedStr } from "../test-utils"; export interface toHaveTypesOptions { /** @@ -15,7 +18,7 @@ export interface toHaveTypesOptions { } /** - * Matcher to check if an array contains exactly the given items, disregarding order. + * Matcher that checks if an array contains exactly the given items, disregarding order. * @param received - The object to check. Should be an array of one or more {@linkcode PokemonType}s. * @param options - The {@linkcode toHaveTypesOptions | options} for this matcher * @returns The result of the matching @@ -23,42 +26,36 @@ export interface toHaveTypesOptions { export function toHaveTypes( this: MatcherState, received: unknown, - expected: unknown, + expected: [PokemonType, ...PokemonType[]], options: toHaveTypesOptions = {}, ): SyncExpectationResult { - if (!(received instanceof Pokemon)) { + if (!isPokemonInstance(received)) { return { - pass: this.isNot, - message: () => `Expected a Pokemon, but got ${this.utils.stringify(received)}!`, + pass: false, + message: () => `Expected to recieve a Pokémon, but got ${receivedStr(received)}!`, }; } - if (!Array.isArray(expected) || expected.length === 0) { - return { - pass: this.isNot, - message: () => `Expected to recieve an array with length >=1, but got ${this.utils.stringify(expected)}!`, - }; - } + const actualTypes = received.getTypes(...(options.args ?? [])).sort(); + const expectedTypes = expected.slice().sort(); - if (!expected.every((t): t is PokemonType => t in PokemonType)) { - return { - pass: this.isNot, - message: () => `Expected to recieve array of PokemonTypes but got ${this.utils.stringify(expected)}!`, - }; - } + // Exact matches do not care about subset equality + const matchers = options.exact + ? [...this.customTesters, this.utils.iterableEquality] + : [...this.customTesters, this.utils.subsetEquality, this.utils.iterableEquality]; + const pass = this.equals(actualTypes, expectedTypes, matchers); - const gotSorted = pkmnTypeToStr(received.getTypes(...(options.args ?? []))); - const wantSorted = pkmnTypeToStr(expected.slice()); - const pass = this.equals(gotSorted, wantSorted, [...this.customTesters, this.utils.iterableEquality]); + const actualStr = stringifyEnumArray(PokemonType, actualTypes); + const expectedStr = stringifyEnumArray(PokemonType, expectedTypes); + const pkmName = getPokemonNameWithAffix(received); return { - pass: this.isNot !== pass, - message: () => `Expected ${received.name} to have types ${this.utils.stringify(wantSorted)}, but got ${gotSorted}!`, - actual: gotSorted, - expected: wantSorted, + pass, + message: () => + pass + ? `Expected ${pkmName} to NOT have types ${expectedStr}, but it did!` + : `Expected ${pkmName} to have types ${expectedStr}, but got ${actualStr} instead!`, + expected: expectedTypes, + actual: actualTypes, }; } - -function pkmnTypeToStr(p: PokemonType[]): string[] { - return p.sort().map(type => PokemonType[type]); -} diff --git a/test/test-utils/matchers/to-have-used-move.ts b/test/test-utils/matchers/to-have-used-move.ts new file mode 100644 index 00000000000..ef90e4dbad9 --- /dev/null +++ b/test/test-utils/matchers/to-have-used-move.ts @@ -0,0 +1,70 @@ +/** biome-ignore-start lint/correctness/noUnusedImports: TSDoc imports */ +import type { Pokemon } from "#field/pokemon"; +/** biome-ignore-end lint/correctness/noUnusedImports: TSDoc imports */ + +import { getPokemonNameWithAffix } from "#app/messages"; +import type { MoveId } from "#enums/move-id"; +import { getOnelineDiffStr, getOrdinal } from "#test/test-utils/string-utils"; +import { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils"; +import type { TurnMove } from "#types/turn-move"; +import type { AtLeastOne } from "#types/type-helpers"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +/** + * Matcher to check the contents of a {@linkcode Pokemon}'s move history. + * @param received - The actual value received. Should be a {@linkcode Pokemon} + * @param expectedValue - The {@linkcode MoveId} the Pokemon is expected to have used, + * or a partially filled {@linkcode TurnMove} containing the desired properties to check + * @param index - The index of the move history entry to check, in order from most recent to least recent. + * Default `0` (last used move) + * @returns Whether the matcher passed + */ +export function toHaveUsedMove( + this: MatcherState, + received: unknown, + expectedResult: MoveId | AtLeastOne, + index = 0, +): SyncExpectationResult { + if (!isPokemonInstance(received)) { + return { + pass: false, + message: () => `Expected to receive a Pokémon, but got ${receivedStr(received)}!`, + }; + } + + const move: TurnMove | undefined = received.getLastXMoves(-1)[index]; + const pkmName = getPokemonNameWithAffix(received); + + if (move === undefined) { + return { + pass: false, + message: () => `Expected ${pkmName} to have used ${index + 1} moves, but it didn't!`, + actual: received.getLastXMoves(-1), + }; + } + + // Coerce to a `TurnMove` + if (typeof expectedResult === "number") { + expectedResult = { move: expectedResult }; + } + + const moveIndexStr = index === 0 ? "last move" : `${getOrdinal(index)} most recent move`; + + const pass = this.equals(move, expectedResult, [ + ...this.customTesters, + this.utils.subsetEquality, + this.utils.iterableEquality, + ]); + + const expectedStr = getOnelineDiffStr.call(this, expectedResult); + return { + pass, + message: () => + pass + ? `Expected ${pkmName}'s ${moveIndexStr} to NOT match ${expectedStr}, but it did!` + : // Replace newlines with spaces to preserve one-line ness + `Expected ${pkmName}'s ${moveIndexStr} to match ${expectedStr}, but it didn't!`, + expected: expectedResult, + actual: move, + }; +} diff --git a/test/test-utils/matchers/to-have-used-pp.ts b/test/test-utils/matchers/to-have-used-pp.ts new file mode 100644 index 00000000000..3b606a535bc --- /dev/null +++ b/test/test-utils/matchers/to-have-used-pp.ts @@ -0,0 +1,77 @@ +// biome-ignore-start lint/correctness/noUnusedImports: TSDoc imports +import type { Pokemon } from "#field/pokemon"; +// biome-ignore-end lint/correctness/noUnusedImports: TSDoc imports + +import { getPokemonNameWithAffix } from "#app/messages"; +import Overrides from "#app/overrides"; +import { MoveId } from "#enums/move-id"; +import { getEnumStr } from "#test/test-utils/string-utils"; +import { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils"; +import { coerceArray } from "#utils/common"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +/** + * Matcher to check the amount of PP consumed by a {@linkcode Pokemon}. + * @param received - The actual value received. Should be a {@linkcode Pokemon} + * @param expectedValue - The {@linkcode MoveId} that should have consumed PP + * @param ppUsed - The numerical amount of PP that should have been consumed, + * or `all` to indicate the move should be _out_ of PP + * @returns Whether the matcher passed + * @remarks + * If the same move appears in the Pokemon's moveset multiple times, this will fail the test! + */ +export function toHaveUsedPP( + this: MatcherState, + received: unknown, + expectedMove: MoveId, + ppUsed: number | "all", +): SyncExpectationResult { + if (!isPokemonInstance(received)) { + return { + pass: false, + message: () => `Expected to receive a Pokémon, but got ${receivedStr(received)}!`, + }; + } + + const override = received.isPlayer() ? Overrides.MOVESET_OVERRIDE : Overrides.OPP_MOVESET_OVERRIDE; + if (coerceArray(override).length > 0) { + return { + pass: false, + message: () => + `Cannot test for PP consumption with ${received.isPlayer() ? "player" : "enemy"} moveset overrides active!`, + }; + } + + const pkmName = getPokemonNameWithAffix(received); + const moveStr = getEnumStr(MoveId, expectedMove); + + const movesetMoves = received.getMoveset().filter(pm => pm.moveId === expectedMove); + if (movesetMoves.length !== 1) { + return { + pass: false, + message: () => + `Expected MoveId.${moveStr} to appear in ${pkmName}'s moveset exactly once, but got ${movesetMoves.length} times!`, + expected: expectedMove, + actual: received.getMoveset(), + }; + } + + const move = movesetMoves[0]; // will be the only move in the array + + let ppStr: string = ppUsed.toString(); + if (typeof ppUsed === "string") { + ppStr = "all its"; + ppUsed = move.getMovePp(); + } + const pass = move.ppUsed === ppUsed; + + return { + pass, + message: () => + pass + ? `Expected ${pkmName}'s ${moveStr} to NOT have used ${ppStr} PP, but it did!` + : `Expected ${pkmName}'s ${moveStr} to have used ${ppStr} PP, but got ${move.ppUsed} instead!`, + expected: ppUsed, + actual: move.ppUsed, + }; +} diff --git a/test/test-utils/matchers/to-have-weather.ts b/test/test-utils/matchers/to-have-weather.ts new file mode 100644 index 00000000000..49433b2137b --- /dev/null +++ b/test/test-utils/matchers/to-have-weather.ts @@ -0,0 +1,62 @@ +/** biome-ignore-start lint/correctness/noUnusedImports: TSDoc imports */ +import type { GameManager } from "#test/test-utils/game-manager"; +/** biome-ignore-end lint/correctness/noUnusedImports: TSDoc imports */ + +import { WeatherType } from "#enums/weather-type"; +import { isGameManagerInstance, receivedStr } from "#test/test-utils/test-utils"; +import { toTitleCase } from "#utils/strings"; +import type { MatcherState, SyncExpectationResult } from "@vitest/expect"; + +/** + * Matcher that checks if the {@linkcode WeatherType} is as expected + * @param received - The object to check. Expects an instance of {@linkcode GameManager}. + * @param expectedWeatherType - The expected {@linkcode WeatherType} + * @returns Whether the matcher passed + */ +export function toHaveWeather( + this: MatcherState, + received: unknown, + expectedWeatherType: WeatherType, +): SyncExpectationResult { + if (!isGameManagerInstance(received)) { + return { + pass: false, + message: () => `Expected GameManager, but got ${receivedStr(received)}!`, + }; + } + + if (!received.scene?.arena) { + return { + pass: false, + message: () => `Expected GameManager.${received.scene ? "scene" : "scene.arena"} to be defined!`, + }; + } + + const actual = received.scene.arena.getWeatherType(); + const pass = actual === expectedWeatherType; + const actualStr = toWeatherStr(actual); + const expectedStr = toWeatherStr(expectedWeatherType); + + return { + pass, + message: () => + pass + ? `Expected Arena to NOT have ${expectedStr} weather active, but it did!` + : `Expected Arena to have ${expectedStr} weather active, but got ${actualStr} instead!`, + expected: expectedWeatherType, + actual, + }; +} + +/** + * Get a human readable representation of the current {@linkcode WeatherType}. + * @param weatherType - The {@linkcode WeatherType} to transform + * @returns A human readable string + */ +function toWeatherStr(weatherType: WeatherType) { + if (weatherType === WeatherType.NONE) { + return "no weather"; + } + + return toTitleCase(WeatherType[weatherType]); +} diff --git a/test/test-utils/string-utils.ts b/test/test-utils/string-utils.ts new file mode 100644 index 00000000000..bd3dd7c2fa9 --- /dev/null +++ b/test/test-utils/string-utils.ts @@ -0,0 +1,183 @@ +import { getStatKey, type Stat } from "#enums/stat"; +import type { EnumOrObject, NormalEnum, TSNumericEnum } from "#types/enum-types"; +import type { ObjectValues } from "#types/type-helpers"; +import { enumValueToKey } from "#utils/enums"; +import { toTitleCase } from "#utils/strings"; +import type { MatcherState } from "@vitest/expect"; +import i18next from "i18next"; + +type Casing = "Preserve" | "Title"; + +interface getEnumStrOptions { + /** + * A string denoting the casing method to use. + * @defaultValue "Preserve" + */ + casing?: Casing; + /** + * If present, will be prepended to the beginning of the enum string. + */ + prefix?: string; + /** + * If present, will be added to the end of the enum string. + */ + suffix?: string; +} + +/** + * Return the name of an enum member or const object value, alongside its corresponding value. + * @param obj - The {@linkcode EnumOrObject} to source reverse mappings from + * @param enums - One of {@linkcode obj}'s values + * @param casing - A string denoting the casing method to use; default `Preserve` + * @param prefix - An optional string to be prepended to the enum's string representation + * @param suffix - An optional string to be appended to the enum's string representation + * @returns The stringified representation of `val` as dictated by the options. + * @example + * ```ts + * enum fakeEnum { + * ONE: 1, + * TWO: 2, + * THREE: 3, + * } + * getEnumStr(fakeEnum, fakeEnum.ONE); // Output: "ONE (=1)" + * getEnumStr(fakeEnum, fakeEnum.TWO, {casing: "Title", prefix: "fakeEnum.", suffix: "!!!"}); // Output: "fakeEnum.TWO!!! (=2)" + * ``` + */ +export function getEnumStr( + obj: E, + val: ObjectValues, + { casing = "Preserve", prefix = "", suffix = "" }: getEnumStrOptions = {}, +): string { + let casingFunc: ((s: string) => string) | undefined; + switch (casing) { + case "Preserve": + break; + case "Title": + casingFunc = toTitleCase; + break; + } + + let stringPart = + obj[val] !== undefined + ? // TS reverse mapped enum + (obj[val] as string) + : // Normal enum/`const object` + (enumValueToKey(obj as NormalEnum, val) as string); + + if (casingFunc) { + stringPart = casingFunc(stringPart); + } + + return `${prefix}${stringPart}${suffix} (=${val})`; +} + +/** + * Convert an array of enums or `const object`s into a readable string version. + * @param obj - The {@linkcode EnumOrObject} to source reverse mappings from + * @param enums - An array of {@linkcode obj}'s values + * @returns The stringified representation of `enums`. + * @example + * ```ts + * enum fakeEnum { + * ONE: 1, + * TWO: 2, + * THREE: 3, + * } + * console.log(stringifyEnumArray(fakeEnum, [fakeEnum.ONE, fakeEnum.TWO, fakeEnum.THREE])); // Output: "[ONE, TWO, THREE] (=[1, 2, 3])" + * ``` + */ +export function stringifyEnumArray(obj: E, enums: E[keyof E][]): string { + if (obj.length === 0) { + return "[]"; + } + + const vals = enums.slice(); + /** An array of string names */ + let names: string[]; + + if (obj[enums[0]] !== undefined) { + // Reverse mapping exists - `obj` is a `TSNumericEnum` and its reverse mapped counterparts are strings + names = enums.map(e => (obj as TSNumericEnum)[e] as string); + } else { + // No reverse mapping exists means `obj` is a `NormalEnum`. + // NB: This (while ugly) should be more ergonomic than doing a repeated lookup for large `const object`s + // as the `enums` array should be significantly shorter than the corresponding enum type. + names = []; + for (const [k, v] of Object.entries(obj as NormalEnum)) { + if (names.length === enums.length) { + // No more names to get + break; + } + // Find all matches for the given enum, assigning their keys to the names array + findIndices(enums, v).forEach(matchIndex => { + names[matchIndex] = k; + }); + } + } + return `[${names.join(", ")}] (=[${vals.join(", ")}])`; +} + +/** + * Return the indices of all occurrences of a value in an array. + * @param arr - The array to search + * @param searchElement - The value to locate in the array + * @param fromIndex - The array index at which to begin the search. If fromIndex is omitted, the + * search starts at index 0 + */ +function findIndices(arr: T[], searchElement: T, fromIndex = 0): number[] { + const indices: number[] = []; + const arrSliced = arr.slice(fromIndex); + for (const [index, value] of arrSliced.entries()) { + if (value === searchElement) { + indices.push(index); + } + } + return indices; +} + +/** + * Convert a number into an English ordinal + * @param num - The number to convert into an ordinal + * @returns The ordinal representation of {@linkcode num}. + * @example + * ```ts + * console.log(getOrdinal(1)); // Output: "1st" + * console.log(getOrdinal(12)); // Output: "12th" + * console.log(getOrdinal(24)); // Output: "24th" + * ``` + */ +export function getOrdinal(num: number): string { + const tens = num % 10; + const hundreds = num % 100; + if (tens === 1 && hundreds !== 11) { + return num + "st"; + } + if (tens === 2 && hundreds !== 12) { + return num + "nd"; + } + if (tens === 3 && hundreds !== 13) { + return num + "rd"; + } + return num + "th"; +} + +/** + * Get the localized name of a {@linkcode Stat}. + * @param s - The {@linkcode Stat} to check + * @returns - The proper name for s, retrieved from the translations. + */ +export function getStatName(s: Stat): string { + return i18next.t(getStatKey(s)); +} + +/** + * Convert an object into a oneline diff to be shown in an error message. + * @param obj - The object to return the oneline diff of + * @returns The updated diff + */ +export function getOnelineDiffStr(this: MatcherState, obj: unknown): string { + return this.utils + .stringify(obj, undefined, { maxLength: 35, indent: 0, printBasicPrototype: false }) + .replace(/\n/g, " ") // Replace newlines with spaces + .replace(/,(\s*)}$/g, "$1}"); +} diff --git a/test/test-utils/test-utils.ts b/test/test-utils/test-utils.ts index 40e4bbe8775..b9e73c3e9da 100644 --- a/test/test-utils/test-utils.ts +++ b/test/test-utils/test-utils.ts @@ -1,3 +1,5 @@ +import { Pokemon } from "#field/pokemon"; +import type { GameManager } from "#test/test-utils/game-manager"; import i18next, { type ParseKeys } from "i18next"; import { vi } from "vitest"; @@ -29,3 +31,54 @@ export function arrayOfRange(start: number, end: number) { export function getApiBaseUrl() { return import.meta.env.VITE_SERVER_URL ?? "http://localhost:8001"; } + +type TypeOfResult = "undefined" | "object" | "boolean" | "number" | "bigint" | "string" | "symbol" | "function"; + +/** + * Helper to determine the actual type of the received object as human readable string + * @param received - The received object + * @returns A human readable string of the received object (type) + */ +export function receivedStr(received: unknown, expectedType: TypeOfResult = "object"): string { + if (received === null) { + return "null"; + } + if (received === undefined) { + return "undefined"; + } + if (typeof received !== expectedType) { + return typeof received; + } + if (expectedType === "object") { + return received.constructor.name; + } + + return "unknown"; +} + +/** + * Helper to check if the received object is an {@linkcode object} + * @param received - The object to check + * @returns Whether the object is an {@linkcode object}. + */ +function isObject(received: unknown): received is object { + return received !== null && typeof received === "object"; +} + +/** + * Helper function to check if a given object is a {@linkcode Pokemon}. + * @param received - The object to check + * @return Whether `received` is a {@linkcode Pokemon} instance. + */ +export function isPokemonInstance(received: unknown): received is Pokemon { + return isObject(received) && received instanceof Pokemon; +} + +/** + * Checks if an object is a {@linkcode GameManager} instance + * @param received - The object to check + * @returns Whether the object is a {@linkcode GameManager} instance. + */ +export function isGameManagerInstance(received: unknown): received is GameManager { + return isObject(received) && (received as GameManager).constructor.name === "GameManager"; +} diff --git a/test/types/type-helpers.test-d.ts b/test/types/type-helpers.test-d.ts new file mode 100644 index 00000000000..29f957890fc --- /dev/null +++ b/test/types/type-helpers.test-d.ts @@ -0,0 +1,38 @@ +import type { AtLeastOne } from "#types/type-helpers"; +import { describe, it } from "node:test"; +import { expectTypeOf } from "vitest"; + +type fakeObj = { + foo: number; + bar: string; + baz: number | string; +}; + +type optionalObj = { + foo: number; + bar: string; + baz?: number | string; +}; + +describe("AtLeastOne", () => { + it("should accept an object with at least 1 of its defined parameters", () => { + expectTypeOf<{ foo: number }>().toExtend>(); + expectTypeOf<{ bar: string }>().toExtend>(); + expectTypeOf<{ baz: number | string }>().toExtend>(); + }); + + it("should convert to a partial intersection with the union of all individual single properties", () => { + expectTypeOf>().branded.toEqualTypeOf< + Partial & ({ foo: number } | { bar: string } | { baz: number | string }) + >(); + }); + + it("should treat optional properties as required", () => { + expectTypeOf>().branded.toEqualTypeOf>(); + }); + + it("should not accept empty objects, even if optional properties are present", () => { + expectTypeOf>().not.toExtend>(); + expectTypeOf>().not.toExtend>(); + }); +}); From 491df80b66fe3aa2eceb94d4ed417b0a451a3578 Mon Sep 17 00:00:00 2001 From: Blitzy <118096277+Blitz425@users.noreply.github.com> Date: Sat, 2 Aug 2025 20:08:50 -0500 Subject: [PATCH 73/76] [Beta] Further Cosmog Evolution Readjustments (#6203) Update pokemon-evolutions.ts --- src/data/balance/pokemon-evolutions.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data/balance/pokemon-evolutions.ts b/src/data/balance/pokemon-evolutions.ts index 5183146ffc1..ab535682e86 100644 --- a/src/data/balance/pokemon-evolutions.ts +++ b/src/data/balance/pokemon-evolutions.ts @@ -1191,11 +1191,11 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(SpeciesId.KOMMO_O, 45, null, null) ], [SpeciesId.COSMOG]: [ - new SpeciesEvolution(SpeciesId.COSMOEM, 1, null, {key: EvoCondKey.FRIENDSHIP, value: 40}, SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(SpeciesId.COSMOEM, 1, null, {key: EvoCondKey.FRIENDSHIP, value: 43}, SpeciesWildEvolutionDelay.VERY_LONG) ], [SpeciesId.COSMOEM]: [ - new SpeciesEvolution(SpeciesId.SOLGALEO, 23, EvolutionItem.SUN_FLUTE, null, SpeciesWildEvolutionDelay.VERY_LONG), - new SpeciesEvolution(SpeciesId.LUNALA, 23, EvolutionItem.MOON_FLUTE, null, SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(SpeciesId.SOLGALEO, 13, EvolutionItem.SUN_FLUTE, null, SpeciesWildEvolutionDelay.VERY_LONG), + new SpeciesEvolution(SpeciesId.LUNALA, 13, EvolutionItem.MOON_FLUTE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [SpeciesId.MELTAN]: [ new SpeciesEvolution(SpeciesId.MELMETAL, 48, null, null) From e8ab79ebed6ee32e33c25cfbdb5b0e5deb444939 Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Sat, 2 Aug 2025 22:35:06 -0400 Subject: [PATCH 74/76] [Dev] Move various functions out of `pokemon-species.ts` (#6155) `initSpecies` moved to its own file, other functions moved to `pokemon-utils.ts` --- src/data/balance/pokemon-species.ts | 1784 ++++++++++++++++ src/data/challenge.ts | 3 +- src/data/daily-run.ts | 4 +- src/data/pokemon-species.ts | 1888 +---------------- src/data/pokemon/pokemon-data.ts | 3 +- src/field/pokemon.ts | 4 +- src/init/init.ts | 2 +- src/system/pokemon-data.ts | 3 +- .../version-migration/versions/v1_7_0.ts | 3 +- src/ui/pokedex-page-ui-handler.ts | 4 +- src/ui/pokedex-ui-handler.ts | 3 +- src/ui/pokemon-hatch-info-container.ts | 2 +- src/ui/starter-select-ui-handler.ts | 2 +- src/utils/pokemon-utils.ts | 106 +- test/test-utils/game-manager-utils.ts | 3 +- 15 files changed, 1910 insertions(+), 1904 deletions(-) create mode 100644 src/data/balance/pokemon-species.ts diff --git a/src/data/balance/pokemon-species.ts b/src/data/balance/pokemon-species.ts new file mode 100644 index 00000000000..5e9d352f437 --- /dev/null +++ b/src/data/balance/pokemon-species.ts @@ -0,0 +1,1784 @@ +import { allSpecies } from "#data/data-lists"; +import { GrowthRate } from "#data/exp"; +import { PokemonForm, PokemonSpecies } from "#data/pokemon-species"; +import { AbilityId } from "#enums/ability-id"; +import { PokemonType } from "#enums/pokemon-type"; +import { SpeciesFormKey } from "#enums/species-form-key"; +import { SpeciesId } from "#enums/species-id"; + +// biome-ignore format: manually formatted +export function initSpecies() { + allSpecies.push( + new PokemonSpecies(SpeciesId.BULBASAUR, 1, false, false, false, "Seed Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.7, 6.9, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CHLOROPHYLL, 318, 45, 49, 49, 65, 65, 45, 45, 50, 64, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.IVYSAUR, 1, false, false, false, "Seed Pokémon", PokemonType.GRASS, PokemonType.POISON, 1, 13, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CHLOROPHYLL, 405, 60, 62, 63, 80, 80, 60, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.VENUSAUR, 1, false, false, false, "Seed Pokémon", PokemonType.GRASS, PokemonType.POISON, 2, 100, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, GrowthRate.MEDIUM_SLOW, 87.5, true, true, + new PokemonForm("Normal", "", PokemonType.GRASS, PokemonType.POISON, 2, 100, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, true, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.GRASS, PokemonType.POISON, 2.4, 155.5, AbilityId.THICK_FAT, AbilityId.THICK_FAT, AbilityId.THICK_FAT, 625, 80, 100, 123, 122, 120, 80, 45, 50, 263, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GRASS, PokemonType.POISON, 24, 999.9, AbilityId.EFFECT_SPORE, AbilityId.NONE, AbilityId.EFFECT_SPORE, 625, 120, 122, 90, 108, 105, 80, 45, 50, 263, true) + ), + new PokemonSpecies(SpeciesId.CHARMANDER, 1, false, false, false, "Lizard Pokémon", PokemonType.FIRE, null, 0.6, 8.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SOLAR_POWER, 309, 39, 52, 43, 60, 50, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.CHARMELEON, 1, false, false, false, "Flame Pokémon", PokemonType.FIRE, null, 1.1, 19, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SOLAR_POWER, 405, 58, 64, 58, 80, 65, 80, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.CHARIZARD, 1, false, false, false, "Flame Pokémon", PokemonType.FIRE, PokemonType.FLYING, 1.7, 90.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SOLAR_POWER, 534, 78, 84, 78, 109, 85, 100, 45, 50, 267, GrowthRate.MEDIUM_SLOW, 87.5, false, true, + new PokemonForm("Normal", "", PokemonType.FIRE, PokemonType.FLYING, 1.7, 90.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SOLAR_POWER, 534, 78, 84, 78, 109, 85, 100, 45, 50, 267, false, null, true), + new PokemonForm("Mega X", SpeciesFormKey.MEGA_X, PokemonType.FIRE, PokemonType.DRAGON, 1.7, 110.5, AbilityId.TOUGH_CLAWS, AbilityId.NONE, AbilityId.TOUGH_CLAWS, 634, 78, 130, 111, 130, 85, 100, 45, 50, 267), + new PokemonForm("Mega Y", SpeciesFormKey.MEGA_Y, PokemonType.FIRE, PokemonType.FLYING, 1.7, 100.5, AbilityId.DROUGHT, AbilityId.NONE, AbilityId.DROUGHT, 634, 78, 104, 78, 159, 115, 100, 45, 50, 267), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIRE, PokemonType.FLYING, 28, 999.9, AbilityId.BERSERK, AbilityId.NONE, AbilityId.BERSERK, 634, 118, 99, 88, 134, 95, 100, 45, 50, 267) + ), + new PokemonSpecies(SpeciesId.SQUIRTLE, 1, false, false, false, "Tiny Turtle Pokémon", PokemonType.WATER, null, 0.5, 9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.RAIN_DISH, 314, 44, 48, 65, 50, 64, 43, 45, 50, 63, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.WARTORTLE, 1, false, false, false, "Turtle Pokémon", PokemonType.WATER, null, 1, 22.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.RAIN_DISH, 405, 59, 63, 80, 65, 80, 58, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.BLASTOISE, 1, false, false, false, "Shellfish Pokémon", PokemonType.WATER, null, 1.6, 85.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, + new PokemonForm("Normal", "", PokemonType.WATER, null, 1.6, 85.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.WATER, null, 1.6, 101.1, AbilityId.MEGA_LAUNCHER, AbilityId.NONE, AbilityId.MEGA_LAUNCHER, 630, 79, 103, 120, 135, 115, 78, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, PokemonType.STEEL, 25, 999.9, AbilityId.SHELL_ARMOR, AbilityId.NONE, AbilityId.SHELL_ARMOR, 630, 119, 108, 125, 105, 110, 63, 45, 50, 265) + ), + new PokemonSpecies(SpeciesId.CATERPIE, 1, false, false, false, "Worm Pokémon", PokemonType.BUG, null, 0.3, 2.9, AbilityId.SHIELD_DUST, AbilityId.NONE, AbilityId.RUN_AWAY, 195, 45, 30, 35, 20, 20, 45, 255, 50, 39, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.METAPOD, 1, false, false, false, "Cocoon Pokémon", PokemonType.BUG, null, 0.7, 9.9, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.SHED_SKIN, 205, 50, 20, 55, 25, 25, 30, 120, 50, 72, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BUTTERFREE, 1, false, false, false, "Butterfly Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.1, 32, AbilityId.COMPOUND_EYES, AbilityId.NONE, AbilityId.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, GrowthRate.MEDIUM_FAST, 50, true, true, + new PokemonForm("Normal", "", PokemonType.BUG, PokemonType.FLYING, 1.1, 32, AbilityId.COMPOUND_EYES, AbilityId.NONE, AbilityId.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, true, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.BUG, PokemonType.FLYING, 17, 999.9, AbilityId.COMPOUND_EYES, AbilityId.NONE, AbilityId.COMPOUND_EYES, 495, 80, 40, 75, 120, 95, 85, 45, 50, 198, true) + ), + new PokemonSpecies(SpeciesId.WEEDLE, 1, false, false, false, "Hairy Bug Pokémon", PokemonType.BUG, PokemonType.POISON, 0.3, 3.2, AbilityId.SHIELD_DUST, AbilityId.NONE, AbilityId.RUN_AWAY, 195, 40, 35, 30, 20, 20, 50, 255, 70, 39, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.KAKUNA, 1, false, false, false, "Cocoon Pokémon", PokemonType.BUG, PokemonType.POISON, 0.6, 10, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.SHED_SKIN, 205, 45, 25, 50, 25, 25, 35, 120, 70, 72, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BEEDRILL, 1, false, false, false, "Poison Bee Pokémon", PokemonType.BUG, PokemonType.POISON, 1, 29.5, AbilityId.SWARM, AbilityId.NONE, AbilityId.SNIPER, 395, 65, 90, 40, 45, 80, 75, 45, 70, 198, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.BUG, PokemonType.POISON, 1, 29.5, AbilityId.SWARM, AbilityId.NONE, AbilityId.SNIPER, 395, 65, 90, 40, 45, 80, 75, 45, 70, 198, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.BUG, PokemonType.POISON, 1.4, 40.5, AbilityId.ADAPTABILITY, AbilityId.NONE, AbilityId.ADAPTABILITY, 495, 65, 150, 40, 15, 80, 145, 45, 70, 198) + ), + new PokemonSpecies(SpeciesId.PIDGEY, 1, false, false, false, "Tiny Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 1.8, AbilityId.KEEN_EYE, AbilityId.TANGLED_FEET, AbilityId.BIG_PECKS, 251, 40, 45, 40, 35, 35, 56, 255, 70, 50, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.PIDGEOTTO, 1, false, false, false, "Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.1, 30, AbilityId.KEEN_EYE, AbilityId.TANGLED_FEET, AbilityId.BIG_PECKS, 349, 63, 60, 55, 50, 50, 71, 120, 70, 122, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.PIDGEOT, 1, false, false, false, "Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.5, 39.5, AbilityId.KEEN_EYE, AbilityId.TANGLED_FEET, AbilityId.BIG_PECKS, 479, 83, 80, 75, 70, 70, 101, 45, 70, 240, GrowthRate.MEDIUM_SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.NORMAL, PokemonType.FLYING, 1.5, 39.5, AbilityId.KEEN_EYE, AbilityId.TANGLED_FEET, AbilityId.BIG_PECKS, 479, 83, 80, 75, 70, 70, 101, 45, 70, 240, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.NORMAL, PokemonType.FLYING, 2.2, 50.5, AbilityId.NO_GUARD, AbilityId.NO_GUARD, AbilityId.NO_GUARD, 579, 83, 80, 80, 135, 80, 121, 45, 70, 240) + ), + new PokemonSpecies(SpeciesId.RATTATA, 1, false, false, false, "Mouse Pokémon", PokemonType.NORMAL, null, 0.3, 3.5, AbilityId.RUN_AWAY, AbilityId.GUTS, AbilityId.HUSTLE, 253, 30, 56, 35, 25, 35, 72, 255, 70, 51, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.RATICATE, 1, false, false, false, "Mouse Pokémon", PokemonType.NORMAL, null, 0.7, 18.5, AbilityId.RUN_AWAY, AbilityId.GUTS, AbilityId.HUSTLE, 413, 55, 81, 60, 50, 70, 97, 127, 70, 145, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.SPEAROW, 1, false, false, false, "Tiny Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 2, AbilityId.KEEN_EYE, AbilityId.NONE, AbilityId.SNIPER, 262, 40, 60, 30, 31, 31, 70, 255, 70, 52, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.FEAROW, 1, false, false, false, "Beak Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.2, 38, AbilityId.KEEN_EYE, AbilityId.NONE, AbilityId.SNIPER, 442, 65, 90, 65, 61, 61, 100, 90, 70, 155, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.EKANS, 1, false, false, false, "Snake Pokémon", PokemonType.POISON, null, 2, 6.9, AbilityId.INTIMIDATE, AbilityId.SHED_SKIN, AbilityId.UNNERVE, 288, 35, 60, 44, 40, 54, 55, 255, 70, 58, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ARBOK, 1, false, false, false, "Cobra Pokémon", PokemonType.POISON, null, 3.5, 65, AbilityId.INTIMIDATE, AbilityId.SHED_SKIN, AbilityId.UNNERVE, 448, 60, 95, 69, 65, 79, 80, 90, 70, 157, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PIKACHU, 1, false, false, false, "Mouse Pokémon", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 320, 35, 55, 40, 50, 50, 90, 190, 50, 112, GrowthRate.MEDIUM_FAST, 50, true, true, + new PokemonForm("Normal", "", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 320, 35, 55, 40, 50, 50, 90, 190, 50, 112, true, null, true), + new PokemonForm("Partner", "partner", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), + new PokemonForm("Cosplay", "cosplay", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom + new PokemonForm("Cool Cosplay", "cool-cosplay", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom + new PokemonForm("Beauty Cosplay", "beauty-cosplay", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom + new PokemonForm("Cute Cosplay", "cute-cosplay", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom + new PokemonForm("Smart Cosplay", "smart-cosplay", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom + new PokemonForm("Tough Cosplay", "tough-cosplay", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.ELECTRIC, null, 21, 999.9, AbilityId.LIGHTNING_ROD, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 530, 125, 95, 60, 90, 70, 90, 190, 50, 112) + ), + new PokemonSpecies(SpeciesId.RAICHU, 1, false, false, false, "Mouse Pokémon", PokemonType.ELECTRIC, null, 0.8, 30, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 485, 60, 90, 55, 90, 80, 110, 75, 50, 243, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.SANDSHREW, 1, false, false, false, "Mouse Pokémon", PokemonType.GROUND, null, 0.6, 12, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.SAND_RUSH, 300, 50, 75, 85, 20, 30, 40, 255, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SANDSLASH, 1, false, false, false, "Mouse Pokémon", PokemonType.GROUND, null, 1, 29.5, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.SAND_RUSH, 450, 75, 100, 110, 45, 55, 65, 90, 50, 158, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.NIDORAN_F, 1, false, false, false, "Poison Pin Pokémon", PokemonType.POISON, null, 0.4, 7, AbilityId.POISON_POINT, AbilityId.RIVALRY, AbilityId.HUSTLE, 275, 55, 47, 52, 40, 40, 41, 235, 50, 55, GrowthRate.MEDIUM_SLOW, 0, false), + new PokemonSpecies(SpeciesId.NIDORINA, 1, false, false, false, "Poison Pin Pokémon", PokemonType.POISON, null, 0.8, 20, AbilityId.POISON_POINT, AbilityId.RIVALRY, AbilityId.HUSTLE, 365, 70, 62, 67, 55, 55, 56, 120, 50, 128, GrowthRate.MEDIUM_SLOW, 0, false), + new PokemonSpecies(SpeciesId.NIDOQUEEN, 1, false, false, false, "Drill Pokémon", PokemonType.POISON, PokemonType.GROUND, 1.3, 60, AbilityId.POISON_POINT, AbilityId.RIVALRY, AbilityId.SHEER_FORCE, 505, 90, 92, 87, 75, 85, 76, 45, 50, 253, GrowthRate.MEDIUM_SLOW, 0, false), + new PokemonSpecies(SpeciesId.NIDORAN_M, 1, false, false, false, "Poison Pin Pokémon", PokemonType.POISON, null, 0.5, 9, AbilityId.POISON_POINT, AbilityId.RIVALRY, AbilityId.HUSTLE, 273, 46, 57, 40, 40, 40, 50, 235, 50, 55, GrowthRate.MEDIUM_SLOW, 100, false), + new PokemonSpecies(SpeciesId.NIDORINO, 1, false, false, false, "Poison Pin Pokémon", PokemonType.POISON, null, 0.9, 19.5, AbilityId.POISON_POINT, AbilityId.RIVALRY, AbilityId.HUSTLE, 365, 61, 72, 57, 55, 55, 65, 120, 50, 128, GrowthRate.MEDIUM_SLOW, 100, false), + new PokemonSpecies(SpeciesId.NIDOKING, 1, false, false, false, "Drill Pokémon", PokemonType.POISON, PokemonType.GROUND, 1.4, 62, AbilityId.POISON_POINT, AbilityId.RIVALRY, AbilityId.SHEER_FORCE, 505, 81, 102, 77, 85, 75, 85, 45, 50, 253, GrowthRate.MEDIUM_SLOW, 100, false), + new PokemonSpecies(SpeciesId.CLEFAIRY, 1, false, false, false, "Fairy Pokémon", PokemonType.FAIRY, null, 0.6, 7.5, AbilityId.CUTE_CHARM, AbilityId.MAGIC_GUARD, AbilityId.FRIEND_GUARD, 323, 70, 45, 48, 60, 65, 35, 150, 140, 113, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.CLEFABLE, 1, false, false, false, "Fairy Pokémon", PokemonType.FAIRY, null, 1.3, 40, AbilityId.CUTE_CHARM, AbilityId.MAGIC_GUARD, AbilityId.UNAWARE, 483, 95, 70, 73, 95, 90, 60, 25, 140, 242, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.VULPIX, 1, false, false, false, "Fox Pokémon", PokemonType.FIRE, null, 0.6, 9.9, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.DROUGHT, 299, 38, 41, 40, 50, 65, 65, 190, 50, 60, GrowthRate.MEDIUM_FAST, 25, false), + new PokemonSpecies(SpeciesId.NINETALES, 1, false, false, false, "Fox Pokémon", PokemonType.FIRE, null, 1.1, 19.9, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.DROUGHT, 505, 73, 76, 75, 81, 100, 100, 75, 50, 177, GrowthRate.MEDIUM_FAST, 25, false), + new PokemonSpecies(SpeciesId.JIGGLYPUFF, 1, false, false, false, "Balloon Pokémon", PokemonType.NORMAL, PokemonType.FAIRY, 0.5, 5.5, AbilityId.CUTE_CHARM, AbilityId.COMPETITIVE, AbilityId.FRIEND_GUARD, 270, 115, 45, 20, 45, 25, 20, 170, 50, 95, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.WIGGLYTUFF, 1, false, false, false, "Balloon Pokémon", PokemonType.NORMAL, PokemonType.FAIRY, 1, 12, AbilityId.CUTE_CHARM, AbilityId.COMPETITIVE, AbilityId.FRISK, 435, 140, 70, 45, 85, 50, 45, 50, 50, 218, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.ZUBAT, 1, false, false, false, "Bat Pokémon", PokemonType.POISON, PokemonType.FLYING, 0.8, 7.5, AbilityId.INNER_FOCUS, AbilityId.NONE, AbilityId.INFILTRATOR, 245, 40, 45, 35, 30, 40, 55, 255, 50, 49, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.GOLBAT, 1, false, false, false, "Bat Pokémon", PokemonType.POISON, PokemonType.FLYING, 1.6, 55, AbilityId.INNER_FOCUS, AbilityId.NONE, AbilityId.INFILTRATOR, 455, 75, 80, 70, 65, 75, 90, 90, 50, 159, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.ODDISH, 1, false, false, false, "Weed Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.5, 5.4, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.RUN_AWAY, 320, 45, 50, 55, 75, 65, 30, 255, 50, 64, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.GLOOM, 1, false, false, false, "Weed Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.8, 8.6, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.STENCH, 395, 60, 65, 70, 85, 75, 40, 120, 50, 138, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.VILEPLUME, 1, false, false, false, "Flower Pokémon", PokemonType.GRASS, PokemonType.POISON, 1.2, 18.6, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.EFFECT_SPORE, 490, 75, 80, 85, 110, 90, 50, 45, 50, 245, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.PARAS, 1, false, false, false, "Mushroom Pokémon", PokemonType.BUG, PokemonType.GRASS, 0.3, 5.4, AbilityId.EFFECT_SPORE, AbilityId.DRY_SKIN, AbilityId.DAMP, 285, 35, 70, 55, 45, 55, 25, 190, 70, 57, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PARASECT, 1, false, false, false, "Mushroom Pokémon", PokemonType.BUG, PokemonType.GRASS, 1, 29.5, AbilityId.EFFECT_SPORE, AbilityId.DRY_SKIN, AbilityId.DAMP, 405, 60, 95, 80, 60, 80, 30, 75, 70, 142, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.VENONAT, 1, false, false, false, "Insect Pokémon", PokemonType.BUG, PokemonType.POISON, 1, 30, AbilityId.COMPOUND_EYES, AbilityId.TINTED_LENS, AbilityId.RUN_AWAY, 305, 60, 55, 50, 40, 55, 45, 190, 70, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.VENOMOTH, 1, false, false, false, "Poison Moth Pokémon", PokemonType.BUG, PokemonType.POISON, 1.5, 12.5, AbilityId.SHIELD_DUST, AbilityId.TINTED_LENS, AbilityId.WONDER_SKIN, 450, 70, 65, 60, 90, 75, 90, 75, 70, 158, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DIGLETT, 1, false, false, false, "Mole Pokémon", PokemonType.GROUND, null, 0.2, 0.8, AbilityId.SAND_VEIL, AbilityId.ARENA_TRAP, AbilityId.SAND_FORCE, 265, 10, 55, 25, 35, 45, 95, 255, 50, 53, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DUGTRIO, 1, false, false, false, "Mole Pokémon", PokemonType.GROUND, null, 0.7, 33.3, AbilityId.SAND_VEIL, AbilityId.ARENA_TRAP, AbilityId.SAND_FORCE, 425, 35, 100, 50, 50, 70, 120, 50, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MEOWTH, 1, false, false, false, "Scratch Cat Pokémon", PokemonType.NORMAL, null, 0.4, 4.2, AbilityId.PICKUP, AbilityId.TECHNICIAN, AbilityId.UNNERVE, 290, 40, 45, 35, 40, 40, 90, 255, 50, 58, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.NORMAL, null, 0.4, 4.2, AbilityId.PICKUP, AbilityId.TECHNICIAN, AbilityId.UNNERVE, 290, 40, 45, 35, 40, 40, 90, 255, 50, 58, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.NORMAL, null, 33, 999.9, AbilityId.TECHNICIAN, AbilityId.TECHNICIAN, AbilityId.TECHNICIAN, 540, 115, 110, 65, 65, 70, 115, 255, 50, 58) + ), + new PokemonSpecies(SpeciesId.PERSIAN, 1, false, false, false, "Classy Cat Pokémon", PokemonType.NORMAL, null, 1, 32, AbilityId.LIMBER, AbilityId.TECHNICIAN, AbilityId.UNNERVE, 440, 65, 70, 60, 65, 65, 115, 90, 50, 154, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PSYDUCK, 1, false, false, false, "Duck Pokémon", PokemonType.WATER, null, 0.8, 19.6, AbilityId.DAMP, AbilityId.CLOUD_NINE, AbilityId.SWIFT_SWIM, 320, 50, 52, 48, 65, 50, 55, 190, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GOLDUCK, 1, false, false, false, "Duck Pokémon", PokemonType.WATER, null, 1.7, 76.6, AbilityId.DAMP, AbilityId.CLOUD_NINE, AbilityId.SWIFT_SWIM, 500, 80, 82, 78, 95, 80, 85, 75, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MANKEY, 1, false, false, false, "Pig Monkey Pokémon", PokemonType.FIGHTING, null, 0.5, 28, AbilityId.VITAL_SPIRIT, AbilityId.ANGER_POINT, AbilityId.DEFIANT, 305, 40, 80, 35, 35, 45, 70, 190, 70, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PRIMEAPE, 1, false, false, false, "Pig Monkey Pokémon", PokemonType.FIGHTING, null, 1, 32, AbilityId.VITAL_SPIRIT, AbilityId.ANGER_POINT, AbilityId.DEFIANT, 455, 65, 105, 60, 60, 70, 95, 75, 70, 159, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GROWLITHE, 1, false, false, false, "Puppy Pokémon", PokemonType.FIRE, null, 0.7, 19, AbilityId.INTIMIDATE, AbilityId.FLASH_FIRE, AbilityId.JUSTIFIED, 350, 55, 70, 45, 70, 50, 60, 190, 50, 70, GrowthRate.SLOW, 75, false), + new PokemonSpecies(SpeciesId.ARCANINE, 1, false, false, false, "Legendary Pokémon", PokemonType.FIRE, null, 1.9, 155, AbilityId.INTIMIDATE, AbilityId.FLASH_FIRE, AbilityId.JUSTIFIED, 555, 90, 110, 80, 100, 80, 95, 75, 50, 194, GrowthRate.SLOW, 75, false), + new PokemonSpecies(SpeciesId.POLIWAG, 1, false, false, false, "Tadpole Pokémon", PokemonType.WATER, null, 0.6, 12.4, AbilityId.WATER_ABSORB, AbilityId.DAMP, AbilityId.SWIFT_SWIM, 300, 40, 50, 40, 40, 40, 90, 255, 50, 60, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.POLIWHIRL, 1, false, false, false, "Tadpole Pokémon", PokemonType.WATER, null, 1, 20, AbilityId.WATER_ABSORB, AbilityId.DAMP, AbilityId.SWIFT_SWIM, 385, 65, 65, 65, 50, 50, 90, 120, 50, 135, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.POLIWRATH, 1, false, false, false, "Tadpole Pokémon", PokemonType.WATER, PokemonType.FIGHTING, 1.3, 54, AbilityId.WATER_ABSORB, AbilityId.DAMP, AbilityId.SWIFT_SWIM, 510, 90, 95, 95, 70, 90, 70, 45, 50, 255, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.ABRA, 1, false, false, false, "Psi Pokémon", PokemonType.PSYCHIC, null, 0.9, 19.5, AbilityId.SYNCHRONIZE, AbilityId.INNER_FOCUS, AbilityId.MAGIC_GUARD, 310, 25, 20, 15, 105, 55, 90, 200, 50, 62, GrowthRate.MEDIUM_SLOW, 75, false), + new PokemonSpecies(SpeciesId.KADABRA, 1, false, false, false, "Psi Pokémon", PokemonType.PSYCHIC, null, 1.3, 56.5, AbilityId.SYNCHRONIZE, AbilityId.INNER_FOCUS, AbilityId.MAGIC_GUARD, 400, 40, 35, 30, 120, 70, 105, 100, 50, 140, GrowthRate.MEDIUM_SLOW, 75, true), + new PokemonSpecies(SpeciesId.ALAKAZAM, 1, false, false, false, "Psi Pokémon", PokemonType.PSYCHIC, null, 1.5, 48, AbilityId.SYNCHRONIZE, AbilityId.INNER_FOCUS, AbilityId.MAGIC_GUARD, 500, 55, 50, 45, 135, 95, 120, 50, 50, 250, GrowthRate.MEDIUM_SLOW, 75, true, true, + new PokemonForm("Normal", "", PokemonType.PSYCHIC, null, 1.5, 48, AbilityId.SYNCHRONIZE, AbilityId.INNER_FOCUS, AbilityId.MAGIC_GUARD, 500, 55, 50, 45, 135, 95, 120, 50, 50, 250, true, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.PSYCHIC, null, 1.2, 48, AbilityId.TRACE, AbilityId.TRACE, AbilityId.TRACE, 600, 55, 50, 65, 175, 105, 150, 50, 50, 250, true) + ), + new PokemonSpecies(SpeciesId.MACHOP, 1, false, false, false, "Superpower Pokémon", PokemonType.FIGHTING, null, 0.8, 19.5, AbilityId.GUTS, AbilityId.NO_GUARD, AbilityId.STEADFAST, 305, 70, 80, 50, 35, 35, 35, 180, 50, 61, GrowthRate.MEDIUM_SLOW, 75, false), + new PokemonSpecies(SpeciesId.MACHOKE, 1, false, false, false, "Superpower Pokémon", PokemonType.FIGHTING, null, 1.5, 70.5, AbilityId.GUTS, AbilityId.NO_GUARD, AbilityId.STEADFAST, 405, 80, 100, 70, 50, 60, 45, 90, 50, 142, GrowthRate.MEDIUM_SLOW, 75, false), + new PokemonSpecies(SpeciesId.MACHAMP, 1, false, false, false, "Superpower Pokémon", PokemonType.FIGHTING, null, 1.6, 130, AbilityId.GUTS, AbilityId.NO_GUARD, AbilityId.STEADFAST, 505, 90, 130, 80, 65, 85, 55, 45, 50, 253, GrowthRate.MEDIUM_SLOW, 75, false, true, + new PokemonForm("Normal", "", PokemonType.FIGHTING, null, 1.6, 130, AbilityId.GUTS, AbilityId.NO_GUARD, AbilityId.STEADFAST, 505, 90, 130, 80, 65, 85, 55, 45, 50, 253, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIGHTING, null, 25, 999.9, AbilityId.GUTS, AbilityId.GUTS, AbilityId.GUTS, 605, 120, 170, 85, 75, 90, 65, 45, 50, 253) + ), + new PokemonSpecies(SpeciesId.BELLSPROUT, 1, false, false, false, "Flower Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.7, 4, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.GLUTTONY, 300, 50, 75, 35, 70, 30, 40, 255, 70, 60, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.WEEPINBELL, 1, false, false, false, "Flycatcher Pokémon", PokemonType.GRASS, PokemonType.POISON, 1, 6.4, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.GLUTTONY, 390, 65, 90, 50, 85, 45, 55, 120, 70, 137, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.VICTREEBEL, 1, false, false, false, "Flycatcher Pokémon", PokemonType.GRASS, PokemonType.POISON, 1.7, 15.5, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.GLUTTONY, 490, 80, 105, 65, 100, 70, 70, 45, 70, 245, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.TENTACOOL, 1, false, false, false, "Jellyfish Pokémon", PokemonType.WATER, PokemonType.POISON, 0.9, 45.5, AbilityId.CLEAR_BODY, AbilityId.LIQUID_OOZE, AbilityId.RAIN_DISH, 335, 40, 40, 35, 50, 100, 70, 190, 50, 67, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.TENTACRUEL, 1, false, false, false, "Jellyfish Pokémon", PokemonType.WATER, PokemonType.POISON, 1.6, 55, AbilityId.CLEAR_BODY, AbilityId.LIQUID_OOZE, AbilityId.RAIN_DISH, 515, 80, 70, 65, 80, 120, 100, 60, 50, 180, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.GEODUDE, 1, false, false, false, "Rock Pokémon", PokemonType.ROCK, PokemonType.GROUND, 0.4, 20, AbilityId.ROCK_HEAD, AbilityId.STURDY, AbilityId.SAND_VEIL, 300, 40, 80, 100, 30, 30, 20, 255, 70, 60, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.GRAVELER, 1, false, false, false, "Rock Pokémon", PokemonType.ROCK, PokemonType.GROUND, 1, 105, AbilityId.ROCK_HEAD, AbilityId.STURDY, AbilityId.SAND_VEIL, 390, 55, 95, 115, 45, 45, 35, 120, 70, 137, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.GOLEM, 1, false, false, false, "Megaton Pokémon", PokemonType.ROCK, PokemonType.GROUND, 1.4, 300, AbilityId.ROCK_HEAD, AbilityId.STURDY, AbilityId.SAND_VEIL, 495, 80, 120, 130, 55, 65, 45, 45, 70, 248, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.PONYTA, 1, false, false, false, "Fire Horse Pokémon", PokemonType.FIRE, null, 1, 30, AbilityId.RUN_AWAY, AbilityId.FLASH_FIRE, AbilityId.FLAME_BODY, 410, 50, 85, 55, 65, 65, 90, 190, 50, 82, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.RAPIDASH, 1, false, false, false, "Fire Horse Pokémon", PokemonType.FIRE, null, 1.7, 95, AbilityId.RUN_AWAY, AbilityId.FLASH_FIRE, AbilityId.FLAME_BODY, 500, 65, 100, 70, 80, 80, 105, 60, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SLOWPOKE, 1, false, false, false, "Dopey Pokémon", PokemonType.WATER, PokemonType.PSYCHIC, 1.2, 36, AbilityId.OBLIVIOUS, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 315, 90, 65, 65, 40, 40, 15, 190, 50, 63, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SLOWBRO, 1, false, false, false, "Hermit Crab Pokémon", PokemonType.WATER, PokemonType.PSYCHIC, 1.6, 78.5, AbilityId.OBLIVIOUS, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 490, 95, 75, 110, 100, 80, 30, 75, 50, 172, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.PSYCHIC, 1.6, 78.5, AbilityId.OBLIVIOUS, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 490, 95, 75, 110, 100, 80, 30, 75, 50, 172, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.WATER, PokemonType.PSYCHIC, 2, 120, AbilityId.SHELL_ARMOR, AbilityId.SHELL_ARMOR, AbilityId.SHELL_ARMOR, 590, 95, 75, 180, 130, 80, 30, 75, 50, 172) + ), + new PokemonSpecies(SpeciesId.MAGNEMITE, 1, false, false, false, "Magnet Pokémon", PokemonType.ELECTRIC, PokemonType.STEEL, 0.3, 6, AbilityId.MAGNET_PULL, AbilityId.STURDY, AbilityId.ANALYTIC, 325, 25, 35, 70, 95, 55, 45, 190, 50, 65, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.MAGNETON, 1, false, false, false, "Magnet Pokémon", PokemonType.ELECTRIC, PokemonType.STEEL, 1, 60, AbilityId.MAGNET_PULL, AbilityId.STURDY, AbilityId.ANALYTIC, 465, 50, 60, 95, 120, 70, 70, 60, 50, 163, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.FARFETCHD, 1, false, false, false, "Wild Duck Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.8, 15, AbilityId.KEEN_EYE, AbilityId.INNER_FOCUS, AbilityId.DEFIANT, 377, 52, 90, 55, 58, 62, 60, 45, 50, 132, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DODUO, 1, false, false, false, "Twin Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.4, 39.2, AbilityId.RUN_AWAY, AbilityId.EARLY_BIRD, AbilityId.TANGLED_FEET, 310, 35, 85, 45, 35, 35, 75, 190, 70, 62, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.DODRIO, 1, false, false, false, "Triple Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.8, 85.2, AbilityId.RUN_AWAY, AbilityId.EARLY_BIRD, AbilityId.TANGLED_FEET, 470, 60, 110, 70, 60, 60, 110, 45, 70, 165, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.SEEL, 1, false, false, false, "Sea Lion Pokémon", PokemonType.WATER, null, 1.1, 90, AbilityId.THICK_FAT, AbilityId.HYDRATION, AbilityId.ICE_BODY, 325, 65, 45, 55, 45, 70, 45, 190, 70, 65, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DEWGONG, 1, false, false, false, "Sea Lion Pokémon", PokemonType.WATER, PokemonType.ICE, 1.7, 120, AbilityId.THICK_FAT, AbilityId.HYDRATION, AbilityId.ICE_BODY, 475, 90, 70, 80, 70, 95, 70, 75, 70, 166, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GRIMER, 1, false, false, false, "Sludge Pokémon", PokemonType.POISON, null, 0.9, 30, AbilityId.STENCH, AbilityId.STICKY_HOLD, AbilityId.POISON_TOUCH, 325, 80, 80, 50, 40, 50, 25, 190, 70, 65, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MUK, 1, false, false, false, "Sludge Pokémon", PokemonType.POISON, null, 1.2, 30, AbilityId.STENCH, AbilityId.STICKY_HOLD, AbilityId.POISON_TOUCH, 500, 105, 105, 75, 65, 100, 50, 75, 70, 175, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SHELLDER, 1, false, false, false, "Bivalve Pokémon", PokemonType.WATER, null, 0.3, 4, AbilityId.SHELL_ARMOR, AbilityId.SKILL_LINK, AbilityId.OVERCOAT, 305, 30, 65, 100, 45, 25, 40, 190, 50, 61, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.CLOYSTER, 1, false, false, false, "Bivalve Pokémon", PokemonType.WATER, PokemonType.ICE, 1.5, 132.5, AbilityId.SHELL_ARMOR, AbilityId.SKILL_LINK, AbilityId.OVERCOAT, 525, 50, 95, 180, 85, 45, 70, 60, 50, 184, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.GASTLY, 1, false, false, false, "Gas Pokémon", PokemonType.GHOST, PokemonType.POISON, 1.3, 0.1, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 310, 30, 35, 30, 100, 35, 80, 190, 50, 62, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.HAUNTER, 1, false, false, false, "Gas Pokémon", PokemonType.GHOST, PokemonType.POISON, 1.6, 0.1, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 405, 45, 50, 45, 115, 55, 95, 90, 50, 142, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.GENGAR, 1, false, false, false, "Shadow Pokémon", PokemonType.GHOST, PokemonType.POISON, 1.5, 40.5, AbilityId.CURSED_BODY, AbilityId.NONE, AbilityId.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, GrowthRate.MEDIUM_SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.GHOST, PokemonType.POISON, 1.5, 40.5, AbilityId.CURSED_BODY, AbilityId.NONE, AbilityId.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.GHOST, PokemonType.POISON, 1.4, 40.5, AbilityId.SHADOW_TAG, AbilityId.NONE, AbilityId.NONE, 600, 60, 65, 80, 170, 95, 130, 45, 50, 250), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GHOST, PokemonType.POISON, 20, 999.9, AbilityId.CURSED_BODY, AbilityId.NONE, AbilityId.NONE, 600, 140, 65, 70, 140, 85, 100, 45, 50, 250) + ), + new PokemonSpecies(SpeciesId.ONIX, 1, false, false, false, "Rock Snake Pokémon", PokemonType.ROCK, PokemonType.GROUND, 8.8, 210, AbilityId.ROCK_HEAD, AbilityId.STURDY, AbilityId.WEAK_ARMOR, 385, 35, 45, 160, 30, 45, 70, 45, 50, 77, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DROWZEE, 1, false, false, false, "Hypnosis Pokémon", PokemonType.PSYCHIC, null, 1, 32.4, AbilityId.INSOMNIA, AbilityId.FOREWARN, AbilityId.INNER_FOCUS, 328, 60, 48, 45, 43, 90, 42, 190, 70, 66, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.HYPNO, 1, false, false, false, "Hypnosis Pokémon", PokemonType.PSYCHIC, null, 1.6, 75.6, AbilityId.INSOMNIA, AbilityId.FOREWARN, AbilityId.INNER_FOCUS, 483, 85, 73, 70, 73, 115, 67, 75, 70, 169, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.KRABBY, 1, false, false, false, "River Crab Pokémon", PokemonType.WATER, null, 0.4, 6.5, AbilityId.HYPER_CUTTER, AbilityId.SHELL_ARMOR, AbilityId.SHEER_FORCE, 325, 30, 105, 90, 25, 25, 50, 225, 50, 65, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.KINGLER, 1, false, false, false, "Pincer Pokémon", PokemonType.WATER, null, 1.3, 60, AbilityId.HYPER_CUTTER, AbilityId.SHELL_ARMOR, AbilityId.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.WATER, null, 1.3, 60, AbilityId.HYPER_CUTTER, AbilityId.SHELL_ARMOR, AbilityId.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, null, 19, 999.9, AbilityId.TOUGH_CLAWS, AbilityId.TOUGH_CLAWS, AbilityId.TOUGH_CLAWS, 575, 92, 145, 140, 60, 65, 73, 60, 50, 166) + ), + new PokemonSpecies(SpeciesId.VOLTORB, 1, false, false, false, "Ball Pokémon", PokemonType.ELECTRIC, null, 0.5, 10.4, AbilityId.SOUNDPROOF, AbilityId.STATIC, AbilityId.AFTERMATH, 330, 40, 30, 50, 55, 55, 100, 190, 70, 66, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.ELECTRODE, 1, false, false, false, "Ball Pokémon", PokemonType.ELECTRIC, null, 1.2, 66.6, AbilityId.SOUNDPROOF, AbilityId.STATIC, AbilityId.AFTERMATH, 490, 60, 50, 70, 80, 80, 150, 60, 70, 172, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.EXEGGCUTE, 1, false, false, false, "Egg Pokémon", PokemonType.GRASS, PokemonType.PSYCHIC, 0.4, 2.5, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.HARVEST, 325, 60, 40, 80, 60, 45, 40, 90, 50, 65, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.EXEGGUTOR, 1, false, false, false, "Coconut Pokémon", PokemonType.GRASS, PokemonType.PSYCHIC, 2, 120, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.HARVEST, 530, 95, 95, 85, 125, 75, 55, 45, 50, 186, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.CUBONE, 1, false, false, false, "Lonely Pokémon", PokemonType.GROUND, null, 0.4, 6.5, AbilityId.ROCK_HEAD, AbilityId.LIGHTNING_ROD, AbilityId.BATTLE_ARMOR, 320, 50, 50, 95, 40, 50, 35, 190, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MAROWAK, 1, false, false, false, "Bone Keeper Pokémon", PokemonType.GROUND, null, 1, 45, AbilityId.ROCK_HEAD, AbilityId.LIGHTNING_ROD, AbilityId.BATTLE_ARMOR, 425, 60, 80, 110, 50, 80, 45, 75, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.HITMONLEE, 1, false, false, false, "Kicking Pokémon", PokemonType.FIGHTING, null, 1.5, 49.8, AbilityId.LIMBER, AbilityId.RECKLESS, AbilityId.UNBURDEN, 455, 50, 120, 53, 35, 110, 87, 45, 50, 159, GrowthRate.MEDIUM_FAST, 100, false), + new PokemonSpecies(SpeciesId.HITMONCHAN, 1, false, false, false, "Punching Pokémon", PokemonType.FIGHTING, null, 1.4, 50.2, AbilityId.KEEN_EYE, AbilityId.IRON_FIST, AbilityId.INNER_FOCUS, 455, 50, 105, 79, 35, 110, 76, 45, 50, 159, GrowthRate.MEDIUM_FAST, 100, false), + new PokemonSpecies(SpeciesId.LICKITUNG, 1, false, false, false, "Licking Pokémon", PokemonType.NORMAL, null, 1.2, 65.5, AbilityId.OWN_TEMPO, AbilityId.OBLIVIOUS, AbilityId.CLOUD_NINE, 385, 90, 55, 75, 60, 75, 30, 45, 50, 77, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.KOFFING, 1, false, false, false, "Poison Gas Pokémon", PokemonType.POISON, null, 0.6, 1, AbilityId.LEVITATE, AbilityId.NEUTRALIZING_GAS, AbilityId.STENCH, 340, 40, 65, 95, 60, 45, 35, 190, 50, 68, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.WEEZING, 1, false, false, false, "Poison Gas Pokémon", PokemonType.POISON, null, 1.2, 9.5, AbilityId.LEVITATE, AbilityId.NEUTRALIZING_GAS, AbilityId.STENCH, 490, 65, 90, 120, 85, 70, 60, 60, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.RHYHORN, 1, false, false, false, "Spikes Pokémon", PokemonType.GROUND, PokemonType.ROCK, 1, 115, AbilityId.LIGHTNING_ROD, AbilityId.ROCK_HEAD, AbilityId.RECKLESS, 345, 80, 85, 95, 30, 30, 25, 120, 50, 69, GrowthRate.SLOW, 50, true), + new PokemonSpecies(SpeciesId.RHYDON, 1, false, false, false, "Drill Pokémon", PokemonType.GROUND, PokemonType.ROCK, 1.9, 120, AbilityId.LIGHTNING_ROD, AbilityId.ROCK_HEAD, AbilityId.RECKLESS, 485, 105, 130, 120, 45, 45, 40, 60, 50, 170, GrowthRate.SLOW, 50, true), + new PokemonSpecies(SpeciesId.CHANSEY, 1, false, false, false, "Egg Pokémon", PokemonType.NORMAL, null, 1.1, 34.6, AbilityId.NATURAL_CURE, AbilityId.SERENE_GRACE, AbilityId.HEALER, 450, 250, 5, 5, 35, 105, 50, 30, 140, 395, GrowthRate.FAST, 0, false), + new PokemonSpecies(SpeciesId.TANGELA, 1, false, false, false, "Vine Pokémon", PokemonType.GRASS, null, 1, 35, AbilityId.CHLOROPHYLL, AbilityId.LEAF_GUARD, AbilityId.REGENERATOR, 435, 65, 55, 115, 100, 40, 60, 45, 50, 87, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.KANGASKHAN, 1, false, false, false, "Parent Pokémon", PokemonType.NORMAL, null, 2.2, 80, AbilityId.EARLY_BIRD, AbilityId.SCRAPPY, AbilityId.INNER_FOCUS, 490, 105, 95, 80, 40, 80, 90, 45, 50, 172, GrowthRate.MEDIUM_FAST, 0, false, true, + new PokemonForm("Normal", "", PokemonType.NORMAL, null, 2.2, 80, AbilityId.EARLY_BIRD, AbilityId.SCRAPPY, AbilityId.INNER_FOCUS, 490, 105, 95, 80, 40, 80, 90, 45, 50, 172, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.NORMAL, null, 2.2, 100, AbilityId.PARENTAL_BOND, AbilityId.PARENTAL_BOND, AbilityId.PARENTAL_BOND, 590, 105, 125, 100, 60, 100, 100, 45, 50, 172) + ), + new PokemonSpecies(SpeciesId.HORSEA, 1, false, false, false, "Dragon Pokémon", PokemonType.WATER, null, 0.4, 8, AbilityId.SWIFT_SWIM, AbilityId.SNIPER, AbilityId.DAMP, 295, 30, 40, 70, 70, 25, 60, 225, 50, 59, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SEADRA, 1, false, false, false, "Dragon Pokémon", PokemonType.WATER, null, 1.2, 25, AbilityId.POISON_POINT, AbilityId.SNIPER, AbilityId.DAMP, 440, 55, 65, 95, 95, 45, 85, 75, 50, 154, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GOLDEEN, 1, false, false, false, "Goldfish Pokémon", PokemonType.WATER, null, 0.6, 15, AbilityId.SWIFT_SWIM, AbilityId.WATER_VEIL, AbilityId.LIGHTNING_ROD, 320, 45, 67, 60, 35, 50, 63, 225, 50, 64, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.SEAKING, 1, false, false, false, "Goldfish Pokémon", PokemonType.WATER, null, 1.3, 39, AbilityId.SWIFT_SWIM, AbilityId.WATER_VEIL, AbilityId.LIGHTNING_ROD, 450, 80, 92, 65, 65, 80, 68, 60, 50, 158, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.STARYU, 1, false, false, false, "Star Shape Pokémon", PokemonType.WATER, null, 0.8, 34.5, AbilityId.ILLUMINATE, AbilityId.NATURAL_CURE, AbilityId.ANALYTIC, 340, 30, 45, 55, 70, 55, 85, 225, 50, 68, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.STARMIE, 1, false, false, false, "Mysterious Pokémon", PokemonType.WATER, PokemonType.PSYCHIC, 1.1, 80, AbilityId.ILLUMINATE, AbilityId.NATURAL_CURE, AbilityId.ANALYTIC, 520, 60, 75, 85, 100, 85, 115, 60, 50, 182, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.MR_MIME, 1, false, false, false, "Barrier Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 1.3, 54.5, AbilityId.SOUNDPROOF, AbilityId.FILTER, AbilityId.TECHNICIAN, 460, 40, 45, 65, 100, 120, 90, 45, 50, 161, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SCYTHER, 1, false, false, false, "Mantis Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.5, 56, AbilityId.SWARM, AbilityId.TECHNICIAN, AbilityId.STEADFAST, 500, 70, 110, 80, 55, 80, 105, 45, 50, 100, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.JYNX, 1, false, false, false, "Human Shape Pokémon", PokemonType.ICE, PokemonType.PSYCHIC, 1.4, 40.6, AbilityId.OBLIVIOUS, AbilityId.FOREWARN, AbilityId.DRY_SKIN, 455, 65, 50, 35, 115, 95, 95, 45, 50, 159, GrowthRate.MEDIUM_FAST, 0, false), + new PokemonSpecies(SpeciesId.ELECTABUZZ, 1, false, false, false, "Electric Pokémon", PokemonType.ELECTRIC, null, 1.1, 30, AbilityId.STATIC, AbilityId.NONE, AbilityId.VITAL_SPIRIT, 490, 65, 83, 57, 95, 85, 105, 45, 50, 172, GrowthRate.MEDIUM_FAST, 75, false), + new PokemonSpecies(SpeciesId.MAGMAR, 1, false, false, false, "Spitfire Pokémon", PokemonType.FIRE, null, 1.3, 44.5, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.VITAL_SPIRIT, 495, 65, 95, 57, 100, 85, 93, 45, 50, 173, GrowthRate.MEDIUM_FAST, 75, false), + new PokemonSpecies(SpeciesId.PINSIR, 1, false, false, false, "Stag Beetle Pokémon", PokemonType.BUG, null, 1.5, 55, AbilityId.HYPER_CUTTER, AbilityId.MOLD_BREAKER, AbilityId.MOXIE, 500, 65, 125, 100, 55, 70, 85, 45, 50, 175, GrowthRate.SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.BUG, null, 1.5, 55, AbilityId.HYPER_CUTTER, AbilityId.MOLD_BREAKER, AbilityId.MOXIE, 500, 65, 125, 100, 55, 70, 85, 45, 50, 175, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.BUG, PokemonType.FLYING, 1.7, 59, AbilityId.AERILATE, AbilityId.AERILATE, AbilityId.AERILATE, 600, 65, 155, 120, 65, 90, 105, 45, 50, 175) + ), + new PokemonSpecies(SpeciesId.TAUROS, 1, false, false, false, "Wild Bull Pokémon", PokemonType.NORMAL, null, 1.4, 88.4, AbilityId.INTIMIDATE, AbilityId.ANGER_POINT, AbilityId.SHEER_FORCE, 490, 75, 100, 95, 40, 70, 110, 45, 50, 172, GrowthRate.SLOW, 100, false), + new PokemonSpecies(SpeciesId.MAGIKARP, 1, false, false, false, "Fish Pokémon", PokemonType.WATER, null, 0.9, 10, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.RATTLED, 200, 20, 10, 55, 15, 20, 80, 255, 50, 40, GrowthRate.SLOW, 50, true), + new PokemonSpecies(SpeciesId.GYARADOS, 1, false, false, false, "Atrocious Pokémon", PokemonType.WATER, PokemonType.FLYING, 6.5, 235, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.MOXIE, 540, 95, 125, 79, 60, 100, 81, 45, 50, 189, GrowthRate.SLOW, 50, true, true, + new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.FLYING, 6.5, 235, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.MOXIE, 540, 95, 125, 79, 60, 100, 81, 45, 50, 189, true, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.WATER, PokemonType.DARK, 6.5, 305, AbilityId.MOLD_BREAKER, AbilityId.MOLD_BREAKER, AbilityId.MOLD_BREAKER, 640, 95, 155, 109, 70, 130, 81, 45, 50, 189, true) + ), + new PokemonSpecies(SpeciesId.LAPRAS, 1, false, false, false, "Transport Pokémon", PokemonType.WATER, PokemonType.ICE, 2.5, 220, AbilityId.WATER_ABSORB, AbilityId.SHELL_ARMOR, AbilityId.HYDRATION, 535, 130, 85, 80, 85, 95, 60, 45, 50, 187, GrowthRate.SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.ICE, 2.5, 220, AbilityId.WATER_ABSORB, AbilityId.SHELL_ARMOR, AbilityId.HYDRATION, 535, 130, 85, 80, 85, 95, 60, 45, 50, 187, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, PokemonType.ICE, 24, 999.9, AbilityId.SHIELD_DUST, AbilityId.SHIELD_DUST, AbilityId.SHIELD_DUST, 635, 170, 97, 85, 107, 111, 65, 45, 50, 187) + ), + new PokemonSpecies(SpeciesId.DITTO, 1, false, false, false, "Transform Pokémon", PokemonType.NORMAL, null, 0.3, 4, AbilityId.LIMBER, AbilityId.NONE, AbilityId.IMPOSTER, 288, 48, 48, 48, 48, 48, 48, 35, 50, 101, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.EEVEE, 1, false, false, false, "Evolution Pokémon", PokemonType.NORMAL, null, 0.3, 6.5, AbilityId.RUN_AWAY, AbilityId.ADAPTABILITY, AbilityId.ANTICIPATION, 325, 55, 55, 50, 45, 65, 55, 45, 50, 65, GrowthRate.MEDIUM_FAST, 87.5, false, true, + new PokemonForm("Normal", "", PokemonType.NORMAL, null, 0.3, 6.5, AbilityId.RUN_AWAY, AbilityId.ADAPTABILITY, AbilityId.ANTICIPATION, 325, 55, 55, 50, 45, 65, 55, 45, 50, 65, false, null, true), + new PokemonForm("Partner", "partner", PokemonType.NORMAL, null, 0.3, 6.5, AbilityId.RUN_AWAY, AbilityId.ADAPTABILITY, AbilityId.ANTICIPATION, 435, 65, 75, 70, 65, 85, 75, 45, 50, 65, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.NORMAL, null, 18, 999.9, AbilityId.PROTEAN, AbilityId.PROTEAN, AbilityId.PROTEAN, 535, 110, 95, 70, 90, 85, 85, 45, 50, 65) + ), + new PokemonSpecies(SpeciesId.VAPOREON, 1, false, false, false, "Bubble Jet Pokémon", PokemonType.WATER, null, 1, 29, AbilityId.WATER_ABSORB, AbilityId.NONE, AbilityId.HYDRATION, 525, 130, 65, 60, 110, 95, 65, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.JOLTEON, 1, false, false, false, "Lightning Pokémon", PokemonType.ELECTRIC, null, 0.8, 24.5, AbilityId.VOLT_ABSORB, AbilityId.NONE, AbilityId.QUICK_FEET, 525, 65, 65, 60, 110, 95, 130, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.FLAREON, 1, false, false, false, "Flame Pokémon", PokemonType.FIRE, null, 0.9, 25, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.GUTS, 525, 65, 130, 60, 95, 110, 65, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.PORYGON, 1, false, false, false, "Virtual Pokémon", PokemonType.NORMAL, null, 0.8, 36.5, AbilityId.TRACE, AbilityId.DOWNLOAD, AbilityId.ANALYTIC, 395, 65, 60, 70, 85, 75, 40, 45, 50, 79, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.OMANYTE, 1, false, false, false, "Spiral Pokémon", PokemonType.ROCK, PokemonType.WATER, 0.4, 7.5, AbilityId.SWIFT_SWIM, AbilityId.SHELL_ARMOR, AbilityId.WEAK_ARMOR, 355, 35, 40, 100, 90, 55, 35, 45, 50, 71, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.OMASTAR, 1, false, false, false, "Spiral Pokémon", PokemonType.ROCK, PokemonType.WATER, 1, 35, AbilityId.SWIFT_SWIM, AbilityId.SHELL_ARMOR, AbilityId.WEAK_ARMOR, 495, 70, 60, 125, 115, 70, 55, 45, 50, 173, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.KABUTO, 1, false, false, false, "Shellfish Pokémon", PokemonType.ROCK, PokemonType.WATER, 0.5, 11.5, AbilityId.SWIFT_SWIM, AbilityId.BATTLE_ARMOR, AbilityId.WEAK_ARMOR, 355, 30, 80, 90, 55, 45, 55, 45, 50, 71, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.KABUTOPS, 1, false, false, false, "Shellfish Pokémon", PokemonType.ROCK, PokemonType.WATER, 1.3, 40.5, AbilityId.SWIFT_SWIM, AbilityId.BATTLE_ARMOR, AbilityId.WEAK_ARMOR, 495, 60, 115, 105, 65, 70, 80, 45, 50, 173, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.AERODACTYL, 1, false, false, false, "Fossil Pokémon", PokemonType.ROCK, PokemonType.FLYING, 1.8, 59, AbilityId.ROCK_HEAD, AbilityId.PRESSURE, AbilityId.UNNERVE, 515, 80, 105, 65, 60, 75, 130, 45, 50, 180, GrowthRate.SLOW, 87.5, false, true, + new PokemonForm("Normal", "", PokemonType.ROCK, PokemonType.FLYING, 1.8, 59, AbilityId.ROCK_HEAD, AbilityId.PRESSURE, AbilityId.UNNERVE, 515, 80, 105, 65, 60, 75, 130, 45, 50, 180, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.ROCK, PokemonType.FLYING, 2.1, 79, AbilityId.TOUGH_CLAWS, AbilityId.TOUGH_CLAWS, AbilityId.TOUGH_CLAWS, 615, 80, 135, 85, 70, 95, 150, 45, 50, 180) + ), + new PokemonSpecies(SpeciesId.SNORLAX, 1, false, false, false, "Sleeping Pokémon", PokemonType.NORMAL, null, 2.1, 460, AbilityId.IMMUNITY, AbilityId.THICK_FAT, AbilityId.GLUTTONY, 540, 160, 110, 65, 65, 110, 30, 25, 50, 189, GrowthRate.SLOW, 87.5, false, true, + new PokemonForm("Normal", "", PokemonType.NORMAL, null, 2.1, 460, AbilityId.IMMUNITY, AbilityId.THICK_FAT, AbilityId.GLUTTONY, 540, 160, 110, 65, 65, 110, 30, 25, 50, 189, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.NORMAL, null, 35, 999.9, AbilityId.HARVEST, AbilityId.HARVEST, AbilityId.HARVEST, 640, 210, 135, 70, 90, 115, 20, 25, 50, 189) + ), + new PokemonSpecies(SpeciesId.ARTICUNO, 1, true, false, false, "Freeze Pokémon", PokemonType.ICE, PokemonType.FLYING, 1.7, 55.4, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.SNOW_CLOAK, 580, 90, 85, 100, 95, 125, 85, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.ZAPDOS, 1, true, false, false, "Electric Pokémon", PokemonType.ELECTRIC, PokemonType.FLYING, 1.6, 52.6, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.STATIC, 580, 90, 90, 85, 125, 90, 100, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.MOLTRES, 1, true, false, false, "Flame Pokémon", PokemonType.FIRE, PokemonType.FLYING, 2, 60, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.FLAME_BODY, 580, 90, 100, 90, 125, 85, 90, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.DRATINI, 1, false, false, false, "Dragon Pokémon", PokemonType.DRAGON, null, 1.8, 3.3, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.MARVEL_SCALE, 300, 41, 64, 45, 50, 50, 50, 45, 35, 60, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.DRAGONAIR, 1, false, false, false, "Dragon Pokémon", PokemonType.DRAGON, null, 4, 16.5, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.MARVEL_SCALE, 420, 61, 84, 65, 70, 70, 70, 45, 35, 147, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.DRAGONITE, 1, false, false, false, "Dragon Pokémon", PokemonType.DRAGON, PokemonType.FLYING, 2.2, 210, AbilityId.INNER_FOCUS, AbilityId.NONE, AbilityId.MULTISCALE, 600, 91, 134, 95, 100, 100, 80, 45, 35, 300, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.MEWTWO, 1, false, true, false, "Genetic Pokémon", PokemonType.PSYCHIC, null, 2, 122, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.UNNERVE, 680, 106, 110, 90, 154, 90, 130, 3, 0, 340, GrowthRate.SLOW, null, false, true, + new PokemonForm("Normal", "", PokemonType.PSYCHIC, null, 2, 122, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.UNNERVE, 680, 106, 110, 90, 154, 90, 130, 3, 0, 340, false, null, true), + new PokemonForm("Mega X", SpeciesFormKey.MEGA_X, PokemonType.PSYCHIC, PokemonType.FIGHTING, 2.3, 127, AbilityId.STEADFAST, AbilityId.NONE, AbilityId.STEADFAST, 780, 106, 190, 100, 154, 100, 130, 3, 0, 340), + new PokemonForm("Mega Y", SpeciesFormKey.MEGA_Y, PokemonType.PSYCHIC, null, 1.5, 33, AbilityId.INSOMNIA, AbilityId.NONE, AbilityId.INSOMNIA, 780, 106, 150, 70, 194, 120, 140, 3, 0, 340) + ), + new PokemonSpecies(SpeciesId.MEW, 1, false, false, true, "New Species Pokémon", PokemonType.PSYCHIC, null, 0.4, 4, AbilityId.SYNCHRONIZE, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 45, 100, 300, GrowthRate.MEDIUM_SLOW, null, false), + new PokemonSpecies(SpeciesId.CHIKORITA, 2, false, false, false, "Leaf Pokémon", PokemonType.GRASS, null, 0.9, 6.4, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.LEAF_GUARD, 318, 45, 49, 65, 49, 65, 45, 45, 70, 64, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.BAYLEEF, 2, false, false, false, "Leaf Pokémon", PokemonType.GRASS, null, 1.2, 15.8, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.LEAF_GUARD, 405, 60, 62, 80, 63, 80, 60, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.MEGANIUM, 2, false, false, false, "Herb Pokémon", PokemonType.GRASS, null, 1.8, 100.5, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.LEAF_GUARD, 525, 80, 82, 100, 83, 100, 80, 45, 70, 263, GrowthRate.MEDIUM_SLOW, 87.5, true), + new PokemonSpecies(SpeciesId.CYNDAQUIL, 2, false, false, false, "Fire Mouse Pokémon", PokemonType.FIRE, null, 0.5, 7.9, AbilityId.BLAZE, AbilityId.NONE, AbilityId.FLASH_FIRE, 309, 39, 52, 43, 60, 50, 65, 45, 70, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.QUILAVA, 2, false, false, false, "Volcano Pokémon", PokemonType.FIRE, null, 0.9, 19, AbilityId.BLAZE, AbilityId.NONE, AbilityId.FLASH_FIRE, 405, 58, 64, 58, 80, 65, 80, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.TYPHLOSION, 2, false, false, false, "Volcano Pokémon", PokemonType.FIRE, null, 1.7, 79.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.FLASH_FIRE, 534, 78, 84, 78, 109, 85, 100, 45, 70, 267, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.TOTODILE, 2, false, false, false, "Big Jaw Pokémon", PokemonType.WATER, null, 0.6, 9.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHEER_FORCE, 314, 50, 65, 64, 44, 48, 43, 45, 70, 63, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.CROCONAW, 2, false, false, false, "Big Jaw Pokémon", PokemonType.WATER, null, 1.1, 25, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHEER_FORCE, 405, 65, 80, 80, 59, 63, 58, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.FERALIGATR, 2, false, false, false, "Big Jaw Pokémon", PokemonType.WATER, null, 2.3, 88.8, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHEER_FORCE, 530, 85, 105, 100, 79, 83, 78, 45, 70, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.SENTRET, 2, false, false, false, "Scout Pokémon", PokemonType.NORMAL, null, 0.8, 6, AbilityId.RUN_AWAY, AbilityId.KEEN_EYE, AbilityId.FRISK, 215, 35, 46, 34, 35, 45, 20, 255, 70, 43, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.FURRET, 2, false, false, false, "Long Body Pokémon", PokemonType.NORMAL, null, 1.8, 32.5, AbilityId.RUN_AWAY, AbilityId.KEEN_EYE, AbilityId.FRISK, 415, 85, 76, 64, 45, 55, 90, 90, 70, 145, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.HOOTHOOT, 2, false, false, false, "Owl Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.7, 21.2, AbilityId.INSOMNIA, AbilityId.KEEN_EYE, AbilityId.TINTED_LENS, 262, 60, 30, 30, 36, 56, 50, 255, 50, 52, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.NOCTOWL, 2, false, false, false, "Owl Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.6, 40.8, AbilityId.INSOMNIA, AbilityId.KEEN_EYE, AbilityId.TINTED_LENS, 452, 100, 50, 50, 86, 96, 70, 90, 50, 158, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.LEDYBA, 2, false, false, false, "Five Star Pokémon", PokemonType.BUG, PokemonType.FLYING, 1, 10.8, AbilityId.SWARM, AbilityId.EARLY_BIRD, AbilityId.RATTLED, 265, 40, 20, 30, 40, 80, 55, 255, 70, 53, GrowthRate.FAST, 50, true), + new PokemonSpecies(SpeciesId.LEDIAN, 2, false, false, false, "Five Star Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.4, 35.6, AbilityId.SWARM, AbilityId.EARLY_BIRD, AbilityId.IRON_FIST, 390, 55, 35, 50, 55, 110, 85, 90, 70, 137, GrowthRate.FAST, 50, true), + new PokemonSpecies(SpeciesId.SPINARAK, 2, false, false, false, "String Spit Pokémon", PokemonType.BUG, PokemonType.POISON, 0.5, 8.5, AbilityId.SWARM, AbilityId.INSOMNIA, AbilityId.SNIPER, 250, 40, 60, 40, 40, 40, 30, 255, 70, 50, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.ARIADOS, 2, false, false, false, "Long Leg Pokémon", PokemonType.BUG, PokemonType.POISON, 1.1, 33.5, AbilityId.SWARM, AbilityId.INSOMNIA, AbilityId.SNIPER, 400, 70, 90, 70, 60, 70, 40, 90, 70, 140, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.CROBAT, 2, false, false, false, "Bat Pokémon", PokemonType.POISON, PokemonType.FLYING, 1.8, 75, AbilityId.INNER_FOCUS, AbilityId.NONE, AbilityId.INFILTRATOR, 535, 85, 90, 80, 70, 80, 130, 90, 50, 268, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CHINCHOU, 2, false, false, false, "Angler Pokémon", PokemonType.WATER, PokemonType.ELECTRIC, 0.5, 12, AbilityId.VOLT_ABSORB, AbilityId.ILLUMINATE, AbilityId.WATER_ABSORB, 330, 75, 38, 38, 56, 56, 67, 190, 50, 66, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.LANTURN, 2, false, false, false, "Light Pokémon", PokemonType.WATER, PokemonType.ELECTRIC, 1.2, 22.5, AbilityId.VOLT_ABSORB, AbilityId.ILLUMINATE, AbilityId.WATER_ABSORB, 460, 125, 58, 58, 76, 76, 67, 75, 50, 161, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.PICHU, 2, false, false, false, "Tiny Mouse Pokémon", PokemonType.ELECTRIC, null, 0.3, 2, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 205, 20, 40, 15, 35, 35, 60, 190, 70, 41, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Normal", "", PokemonType.ELECTRIC, null, 1.4, 2, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 205, 20, 40, 15, 35, 35, 60, 190, 70, 41, false, null, true), + new PokemonForm("Spiky-Eared", "spiky", PokemonType.ELECTRIC, null, 1.4, 2, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 205, 20, 40, 15, 35, 35, 60, 190, 70, 41, false, null, true) + ), + new PokemonSpecies(SpeciesId.CLEFFA, 2, false, false, false, "Star Shape Pokémon", PokemonType.FAIRY, null, 0.3, 3, AbilityId.CUTE_CHARM, AbilityId.MAGIC_GUARD, AbilityId.FRIEND_GUARD, 218, 50, 25, 28, 45, 55, 15, 150, 140, 44, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.IGGLYBUFF, 2, false, false, false, "Balloon Pokémon", PokemonType.NORMAL, PokemonType.FAIRY, 0.3, 1, AbilityId.CUTE_CHARM, AbilityId.COMPETITIVE, AbilityId.FRIEND_GUARD, 210, 90, 30, 15, 40, 20, 15, 170, 50, 42, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.TOGEPI, 2, false, false, false, "Spike Ball Pokémon", PokemonType.FAIRY, null, 0.3, 1.5, AbilityId.HUSTLE, AbilityId.SERENE_GRACE, AbilityId.SUPER_LUCK, 245, 35, 20, 65, 40, 65, 20, 190, 50, 49, GrowthRate.FAST, 87.5, false), + new PokemonSpecies(SpeciesId.TOGETIC, 2, false, false, false, "Happiness Pokémon", PokemonType.FAIRY, PokemonType.FLYING, 0.6, 3.2, AbilityId.HUSTLE, AbilityId.SERENE_GRACE, AbilityId.SUPER_LUCK, 405, 55, 40, 85, 80, 105, 40, 75, 50, 142, GrowthRate.FAST, 87.5, false), + new PokemonSpecies(SpeciesId.NATU, 2, false, false, false, "Tiny Bird Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 0.2, 2, AbilityId.SYNCHRONIZE, AbilityId.EARLY_BIRD, AbilityId.MAGIC_BOUNCE, 320, 40, 50, 45, 70, 45, 70, 190, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.XATU, 2, false, false, false, "Mystic Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 1.5, 15, AbilityId.SYNCHRONIZE, AbilityId.EARLY_BIRD, AbilityId.MAGIC_BOUNCE, 470, 65, 75, 70, 95, 70, 95, 75, 50, 165, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.MAREEP, 2, false, false, false, "Wool Pokémon", PokemonType.ELECTRIC, null, 0.6, 7.8, AbilityId.STATIC, AbilityId.NONE, AbilityId.PLUS, 280, 55, 40, 40, 65, 45, 35, 235, 70, 56, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.FLAAFFY, 2, false, false, false, "Wool Pokémon", PokemonType.ELECTRIC, null, 0.8, 13.3, AbilityId.STATIC, AbilityId.NONE, AbilityId.PLUS, 365, 70, 55, 55, 80, 60, 45, 120, 70, 128, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.AMPHAROS, 2, false, false, false, "Light Pokémon", PokemonType.ELECTRIC, null, 1.4, 61.5, AbilityId.STATIC, AbilityId.NONE, AbilityId.PLUS, 510, 90, 75, 85, 115, 90, 55, 45, 70, 255, GrowthRate.MEDIUM_SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.ELECTRIC, null, 1.4, 61.5, AbilityId.STATIC, AbilityId.NONE, AbilityId.PLUS, 510, 90, 75, 85, 115, 90, 55, 45, 70, 255, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.ELECTRIC, PokemonType.DRAGON, 1.4, 61.5, AbilityId.MOLD_BREAKER, AbilityId.NONE, AbilityId.MOLD_BREAKER, 610, 90, 95, 105, 165, 110, 45, 45, 70, 255) + ), + new PokemonSpecies(SpeciesId.BELLOSSOM, 2, false, false, false, "Flower Pokémon", PokemonType.GRASS, null, 0.4, 5.8, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.HEALER, 490, 75, 80, 95, 90, 100, 50, 45, 50, 245, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.MARILL, 2, false, false, false, "Aqua Mouse Pokémon", PokemonType.WATER, PokemonType.FAIRY, 0.4, 8.5, AbilityId.THICK_FAT, AbilityId.HUGE_POWER, AbilityId.SAP_SIPPER, 250, 70, 20, 50, 20, 50, 40, 190, 50, 88, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.AZUMARILL, 2, false, false, false, "Aqua Rabbit Pokémon", PokemonType.WATER, PokemonType.FAIRY, 0.8, 28.5, AbilityId.THICK_FAT, AbilityId.HUGE_POWER, AbilityId.SAP_SIPPER, 420, 100, 50, 80, 60, 80, 50, 75, 50, 210, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.SUDOWOODO, 2, false, false, false, "Imitation Pokémon", PokemonType.ROCK, null, 1.2, 38, AbilityId.STURDY, AbilityId.ROCK_HEAD, AbilityId.RATTLED, 410, 70, 100, 115, 30, 65, 30, 65, 50, 144, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.POLITOED, 2, false, false, false, "Frog Pokémon", PokemonType.WATER, null, 1.1, 33.9, AbilityId.WATER_ABSORB, AbilityId.DAMP, AbilityId.DRIZZLE, 500, 90, 75, 75, 90, 100, 70, 45, 50, 250, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.HOPPIP, 2, false, false, false, "Cottonweed Pokémon", PokemonType.GRASS, PokemonType.FLYING, 0.4, 0.5, AbilityId.CHLOROPHYLL, AbilityId.LEAF_GUARD, AbilityId.INFILTRATOR, 250, 35, 35, 40, 35, 55, 50, 255, 70, 50, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SKIPLOOM, 2, false, false, false, "Cottonweed Pokémon", PokemonType.GRASS, PokemonType.FLYING, 0.6, 1, AbilityId.CHLOROPHYLL, AbilityId.LEAF_GUARD, AbilityId.INFILTRATOR, 340, 55, 45, 50, 45, 65, 80, 120, 70, 119, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.JUMPLUFF, 2, false, false, false, "Cottonweed Pokémon", PokemonType.GRASS, PokemonType.FLYING, 0.8, 3, AbilityId.CHLOROPHYLL, AbilityId.LEAF_GUARD, AbilityId.INFILTRATOR, 460, 75, 55, 70, 55, 95, 110, 45, 70, 230, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.AIPOM, 2, false, false, false, "Long Tail Pokémon", PokemonType.NORMAL, null, 0.8, 11.5, AbilityId.RUN_AWAY, AbilityId.PICKUP, AbilityId.SKILL_LINK, 360, 55, 70, 55, 40, 55, 85, 45, 70, 72, GrowthRate.FAST, 50, true), + new PokemonSpecies(SpeciesId.SUNKERN, 2, false, false, false, "Seed Pokémon", PokemonType.GRASS, null, 0.3, 1.8, AbilityId.CHLOROPHYLL, AbilityId.SOLAR_POWER, AbilityId.EARLY_BIRD, 180, 30, 30, 30, 30, 30, 30, 235, 70, 36, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SUNFLORA, 2, false, false, false, "Sun Pokémon", PokemonType.GRASS, null, 0.8, 8.5, AbilityId.CHLOROPHYLL, AbilityId.SOLAR_POWER, AbilityId.EARLY_BIRD, 425, 75, 75, 55, 105, 85, 30, 120, 70, 149, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.YANMA, 2, false, false, false, "Clear Wing Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.2, 38, AbilityId.SPEED_BOOST, AbilityId.COMPOUND_EYES, AbilityId.FRISK, 390, 65, 65, 45, 75, 45, 95, 75, 70, 78, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.WOOPER, 2, false, false, false, "Water Fish Pokémon", PokemonType.WATER, PokemonType.GROUND, 0.4, 8.5, AbilityId.DAMP, AbilityId.WATER_ABSORB, AbilityId.UNAWARE, 210, 55, 45, 45, 25, 25, 15, 255, 50, 42, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.QUAGSIRE, 2, false, false, false, "Water Fish Pokémon", PokemonType.WATER, PokemonType.GROUND, 1.4, 75, AbilityId.DAMP, AbilityId.WATER_ABSORB, AbilityId.UNAWARE, 430, 95, 85, 85, 65, 65, 35, 90, 50, 151, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.ESPEON, 2, false, false, false, "Sun Pokémon", PokemonType.PSYCHIC, null, 0.9, 26.5, AbilityId.SYNCHRONIZE, AbilityId.NONE, AbilityId.MAGIC_BOUNCE, 525, 65, 65, 60, 130, 95, 110, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.UMBREON, 2, false, false, false, "Moonlight Pokémon", PokemonType.DARK, null, 1, 27, AbilityId.SYNCHRONIZE, AbilityId.NONE, AbilityId.INNER_FOCUS, 525, 95, 65, 110, 60, 130, 65, 45, 35, 184, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.MURKROW, 2, false, false, false, "Darkness Pokémon", PokemonType.DARK, PokemonType.FLYING, 0.5, 2.1, AbilityId.INSOMNIA, AbilityId.SUPER_LUCK, AbilityId.PRANKSTER, 405, 60, 85, 42, 85, 42, 91, 30, 35, 81, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.SLOWKING, 2, false, false, false, "Royal Pokémon", PokemonType.WATER, PokemonType.PSYCHIC, 2, 79.5, AbilityId.OBLIVIOUS, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 490, 95, 75, 80, 100, 110, 30, 70, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MISDREAVUS, 2, false, false, false, "Screech Pokémon", PokemonType.GHOST, null, 0.7, 1, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 435, 60, 60, 60, 85, 85, 85, 45, 35, 87, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.UNOWN, 2, false, false, false, "Symbol Pokémon", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, GrowthRate.MEDIUM_FAST, null, false, false, + new PokemonForm("A", "a", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("B", "b", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("C", "c", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("D", "d", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("E", "e", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("F", "f", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("G", "g", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("H", "h", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("I", "i", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("J", "j", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("K", "k", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("L", "l", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("M", "m", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("N", "n", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("O", "o", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("P", "p", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("Q", "q", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("R", "r", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("S", "s", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("T", "t", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("U", "u", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("V", "v", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("W", "w", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("X", "x", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("Y", "y", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("Z", "z", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("!", "exclamation", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), + new PokemonForm("?", "question", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true) + ), + new PokemonSpecies(SpeciesId.WOBBUFFET, 2, false, false, false, "Patient Pokémon", PokemonType.PSYCHIC, null, 1.3, 28.5, AbilityId.SHADOW_TAG, AbilityId.NONE, AbilityId.TELEPATHY, 405, 190, 33, 58, 33, 58, 33, 45, 50, 142, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.GIRAFARIG, 2, false, false, false, "Long Neck Pokémon", PokemonType.NORMAL, PokemonType.PSYCHIC, 1.5, 41.5, AbilityId.INNER_FOCUS, AbilityId.EARLY_BIRD, AbilityId.SAP_SIPPER, 455, 70, 80, 65, 90, 65, 85, 60, 70, 159, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.PINECO, 2, false, false, false, "Bagworm Pokémon", PokemonType.BUG, null, 0.6, 7.2, AbilityId.STURDY, AbilityId.NONE, AbilityId.OVERCOAT, 290, 50, 65, 90, 35, 35, 15, 190, 70, 58, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.FORRETRESS, 2, false, false, false, "Bagworm Pokémon", PokemonType.BUG, PokemonType.STEEL, 1.2, 125.8, AbilityId.STURDY, AbilityId.NONE, AbilityId.OVERCOAT, 465, 75, 90, 140, 60, 60, 40, 75, 70, 163, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DUNSPARCE, 2, false, false, false, "Land Snake Pokémon", PokemonType.NORMAL, null, 1.5, 14, AbilityId.SERENE_GRACE, AbilityId.RUN_AWAY, AbilityId.RATTLED, 415, 100, 70, 70, 65, 65, 45, 190, 50, 145, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GLIGAR, 2, false, false, false, "Fly Scorpion Pokémon", PokemonType.GROUND, PokemonType.FLYING, 1.1, 64.8, AbilityId.HYPER_CUTTER, AbilityId.SAND_VEIL, AbilityId.IMMUNITY, 430, 65, 75, 105, 35, 65, 85, 60, 70, 86, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.STEELIX, 2, false, false, false, "Iron Snake Pokémon", PokemonType.STEEL, PokemonType.GROUND, 9.2, 400, AbilityId.ROCK_HEAD, AbilityId.STURDY, AbilityId.SHEER_FORCE, 510, 75, 85, 200, 55, 65, 30, 25, 50, 179, GrowthRate.MEDIUM_FAST, 50, true, true, + new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.GROUND, 9.2, 400, AbilityId.ROCK_HEAD, AbilityId.STURDY, AbilityId.SHEER_FORCE, 510, 75, 85, 200, 55, 65, 30, 25, 50, 179, true, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.STEEL, PokemonType.GROUND, 10.5, 740, AbilityId.SAND_FORCE, AbilityId.SAND_FORCE, AbilityId.SAND_FORCE, 610, 75, 125, 230, 55, 95, 30, 25, 50, 179, true) + ), + new PokemonSpecies(SpeciesId.SNUBBULL, 2, false, false, false, "Fairy Pokémon", PokemonType.FAIRY, null, 0.6, 7.8, AbilityId.INTIMIDATE, AbilityId.RUN_AWAY, AbilityId.RATTLED, 300, 60, 80, 50, 40, 40, 30, 190, 70, 60, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.GRANBULL, 2, false, false, false, "Fairy Pokémon", PokemonType.FAIRY, null, 1.4, 48.7, AbilityId.INTIMIDATE, AbilityId.QUICK_FEET, AbilityId.RATTLED, 450, 90, 120, 75, 60, 60, 45, 75, 70, 158, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.QWILFISH, 2, false, false, false, "Balloon Pokémon", PokemonType.WATER, PokemonType.POISON, 0.5, 3.9, AbilityId.POISON_POINT, AbilityId.SWIFT_SWIM, AbilityId.INTIMIDATE, 440, 65, 95, 85, 55, 55, 85, 45, 50, 88, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SCIZOR, 2, false, false, false, "Pincer Pokémon", PokemonType.BUG, PokemonType.STEEL, 1.8, 118, AbilityId.SWARM, AbilityId.TECHNICIAN, AbilityId.LIGHT_METAL, 500, 70, 130, 100, 55, 80, 65, 25, 50, 175, GrowthRate.MEDIUM_FAST, 50, true, true, + new PokemonForm("Normal", "", PokemonType.BUG, PokemonType.STEEL, 1.8, 118, AbilityId.SWARM, AbilityId.TECHNICIAN, AbilityId.LIGHT_METAL, 500, 70, 130, 100, 55, 80, 65, 25, 50, 175, true, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.BUG, PokemonType.STEEL, 2, 125, AbilityId.TECHNICIAN, AbilityId.TECHNICIAN, AbilityId.TECHNICIAN, 600, 70, 150, 140, 65, 100, 75, 25, 50, 175, true) + ), + new PokemonSpecies(SpeciesId.SHUCKLE, 2, false, false, false, "Mold Pokémon", PokemonType.BUG, PokemonType.ROCK, 0.6, 20.5, AbilityId.STURDY, AbilityId.GLUTTONY, AbilityId.CONTRARY, 505, 20, 10, 230, 10, 230, 5, 190, 50, 177, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.HERACROSS, 2, false, false, false, "Single Horn Pokémon", PokemonType.BUG, PokemonType.FIGHTING, 1.5, 54, AbilityId.SWARM, AbilityId.GUTS, AbilityId.MOXIE, 500, 80, 125, 75, 40, 95, 85, 45, 50, 175, GrowthRate.SLOW, 50, true, true, + new PokemonForm("Normal", "", PokemonType.BUG, PokemonType.FIGHTING, 1.5, 54, AbilityId.SWARM, AbilityId.GUTS, AbilityId.MOXIE, 500, 80, 125, 75, 40, 95, 85, 45, 50, 175, true, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.BUG, PokemonType.FIGHTING, 1.7, 62.5, AbilityId.SKILL_LINK, AbilityId.SKILL_LINK, AbilityId.SKILL_LINK, 600, 80, 185, 115, 40, 105, 75, 45, 50, 175, true) + ), + new PokemonSpecies(SpeciesId.SNEASEL, 2, false, false, false, "Sharp Claw Pokémon", PokemonType.DARK, PokemonType.ICE, 0.9, 28, AbilityId.INNER_FOCUS, AbilityId.KEEN_EYE, AbilityId.PICKPOCKET, 430, 55, 95, 55, 35, 75, 115, 60, 35, 86, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.TEDDIURSA, 2, false, false, false, "Little Bear Pokémon", PokemonType.NORMAL, null, 0.6, 8.8, AbilityId.PICKUP, AbilityId.QUICK_FEET, AbilityId.HONEY_GATHER, 330, 60, 80, 50, 50, 50, 40, 120, 70, 66, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.URSARING, 2, false, false, false, "Hibernator Pokémon", PokemonType.NORMAL, null, 1.8, 125.8, AbilityId.GUTS, AbilityId.QUICK_FEET, AbilityId.UNNERVE, 500, 90, 130, 75, 75, 75, 55, 60, 70, 175, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.SLUGMA, 2, false, false, false, "Lava Pokémon", PokemonType.FIRE, null, 0.7, 35, AbilityId.MAGMA_ARMOR, AbilityId.FLAME_BODY, AbilityId.WEAK_ARMOR, 250, 40, 40, 40, 70, 40, 20, 190, 70, 50, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MAGCARGO, 2, false, false, false, "Lava Pokémon", PokemonType.FIRE, PokemonType.ROCK, 0.8, 55, AbilityId.MAGMA_ARMOR, AbilityId.FLAME_BODY, AbilityId.WEAK_ARMOR, 430, 60, 50, 120, 90, 80, 30, 75, 70, 151, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SWINUB, 2, false, false, false, "Pig Pokémon", PokemonType.ICE, PokemonType.GROUND, 0.4, 6.5, AbilityId.OBLIVIOUS, AbilityId.SNOW_CLOAK, AbilityId.THICK_FAT, 250, 50, 50, 40, 30, 30, 50, 225, 50, 50, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.PILOSWINE, 2, false, false, false, "Swine Pokémon", PokemonType.ICE, PokemonType.GROUND, 1.1, 55.8, AbilityId.OBLIVIOUS, AbilityId.SNOW_CLOAK, AbilityId.THICK_FAT, 450, 100, 100, 80, 60, 60, 50, 75, 50, 158, GrowthRate.SLOW, 50, true), + new PokemonSpecies(SpeciesId.CORSOLA, 2, false, false, false, "Coral Pokémon", PokemonType.WATER, PokemonType.ROCK, 0.6, 5, AbilityId.HUSTLE, AbilityId.NATURAL_CURE, AbilityId.REGENERATOR, 410, 65, 55, 95, 65, 95, 35, 60, 50, 144, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.REMORAID, 2, false, false, false, "Jet Pokémon", PokemonType.WATER, null, 0.6, 12, AbilityId.HUSTLE, AbilityId.SNIPER, AbilityId.MOODY, 300, 35, 65, 35, 65, 35, 65, 190, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.OCTILLERY, 2, false, false, false, "Jet Pokémon", PokemonType.WATER, null, 0.9, 28.5, AbilityId.SUCTION_CUPS, AbilityId.SNIPER, AbilityId.MOODY, 480, 75, 105, 75, 105, 75, 45, 75, 50, 168, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.DELIBIRD, 2, false, false, false, "Delivery Pokémon", PokemonType.ICE, PokemonType.FLYING, 0.9, 16, AbilityId.VITAL_SPIRIT, AbilityId.HUSTLE, AbilityId.INSOMNIA, 330, 45, 55, 45, 65, 45, 75, 45, 50, 116, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.MANTINE, 2, false, false, false, "Kite Pokémon", PokemonType.WATER, PokemonType.FLYING, 2.1, 220, AbilityId.SWIFT_SWIM, AbilityId.WATER_ABSORB, AbilityId.WATER_VEIL, 485, 85, 40, 70, 80, 140, 70, 25, 50, 170, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.SKARMORY, 2, false, false, false, "Armor Bird Pokémon", PokemonType.STEEL, PokemonType.FLYING, 1.7, 50.5, AbilityId.KEEN_EYE, AbilityId.STURDY, AbilityId.WEAK_ARMOR, 465, 65, 80, 140, 40, 70, 70, 25, 50, 163, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.HOUNDOUR, 2, false, false, false, "Dark Pokémon", PokemonType.DARK, PokemonType.FIRE, 0.6, 10.8, AbilityId.EARLY_BIRD, AbilityId.FLASH_FIRE, AbilityId.UNNERVE, 330, 45, 60, 30, 80, 50, 65, 120, 35, 66, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.HOUNDOOM, 2, false, false, false, "Dark Pokémon", PokemonType.DARK, PokemonType.FIRE, 1.4, 35, AbilityId.EARLY_BIRD, AbilityId.FLASH_FIRE, AbilityId.UNNERVE, 500, 75, 90, 50, 110, 80, 95, 45, 35, 175, GrowthRate.SLOW, 50, true, true, + new PokemonForm("Normal", "", PokemonType.DARK, PokemonType.FIRE, 1.4, 35, AbilityId.EARLY_BIRD, AbilityId.FLASH_FIRE, AbilityId.UNNERVE, 500, 75, 90, 50, 110, 80, 95, 45, 35, 175, true, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DARK, PokemonType.FIRE, 1.9, 49.5, AbilityId.SOLAR_POWER, AbilityId.SOLAR_POWER, AbilityId.SOLAR_POWER, 600, 75, 90, 90, 140, 90, 115, 45, 35, 175, true) + ), + new PokemonSpecies(SpeciesId.KINGDRA, 2, false, false, false, "Dragon Pokémon", PokemonType.WATER, PokemonType.DRAGON, 1.8, 152, AbilityId.SWIFT_SWIM, AbilityId.SNIPER, AbilityId.DAMP, 540, 75, 95, 95, 95, 95, 85, 45, 50, 270, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PHANPY, 2, false, false, false, "Long Nose Pokémon", PokemonType.GROUND, null, 0.5, 33.5, AbilityId.PICKUP, AbilityId.NONE, AbilityId.SAND_VEIL, 330, 90, 60, 60, 40, 40, 40, 120, 70, 66, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DONPHAN, 2, false, false, false, "Armor Pokémon", PokemonType.GROUND, null, 1.1, 120, AbilityId.STURDY, AbilityId.NONE, AbilityId.SAND_VEIL, 500, 90, 120, 120, 60, 60, 50, 60, 70, 175, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.PORYGON2, 2, false, false, false, "Virtual Pokémon", PokemonType.NORMAL, null, 0.6, 32.5, AbilityId.TRACE, AbilityId.DOWNLOAD, AbilityId.ANALYTIC, 515, 85, 80, 90, 105, 95, 60, 45, 50, 180, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.STANTLER, 2, false, false, false, "Big Horn Pokémon", PokemonType.NORMAL, null, 1.4, 71.2, AbilityId.INTIMIDATE, AbilityId.FRISK, AbilityId.SAP_SIPPER, 465, 73, 95, 62, 85, 65, 85, 45, 70, 163, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.SMEARGLE, 2, false, false, false, "Painter Pokémon", PokemonType.NORMAL, null, 1.2, 58, AbilityId.OWN_TEMPO, AbilityId.TECHNICIAN, AbilityId.MOODY, 250, 55, 20, 35, 20, 45, 75, 45, 70, 88, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.TYROGUE, 2, false, false, false, "Scuffle Pokémon", PokemonType.FIGHTING, null, 0.7, 21, AbilityId.GUTS, AbilityId.STEADFAST, AbilityId.VITAL_SPIRIT, 210, 35, 35, 35, 35, 35, 35, 75, 50, 42, GrowthRate.MEDIUM_FAST, 100, false), + new PokemonSpecies(SpeciesId.HITMONTOP, 2, false, false, false, "Handstand Pokémon", PokemonType.FIGHTING, null, 1.4, 48, AbilityId.INTIMIDATE, AbilityId.TECHNICIAN, AbilityId.STEADFAST, 455, 50, 95, 95, 35, 110, 70, 45, 50, 159, GrowthRate.MEDIUM_FAST, 100, false), + new PokemonSpecies(SpeciesId.SMOOCHUM, 2, false, false, false, "Kiss Pokémon", PokemonType.ICE, PokemonType.PSYCHIC, 0.4, 6, AbilityId.OBLIVIOUS, AbilityId.FOREWARN, AbilityId.HYDRATION, 305, 45, 30, 15, 85, 65, 65, 45, 50, 61, GrowthRate.MEDIUM_FAST, 0, false), + new PokemonSpecies(SpeciesId.ELEKID, 2, false, false, false, "Electric Pokémon", PokemonType.ELECTRIC, null, 0.6, 23.5, AbilityId.STATIC, AbilityId.NONE, AbilityId.VITAL_SPIRIT, 360, 45, 63, 37, 65, 55, 95, 45, 50, 72, GrowthRate.MEDIUM_FAST, 75, false), + new PokemonSpecies(SpeciesId.MAGBY, 2, false, false, false, "Live Coal Pokémon", PokemonType.FIRE, null, 0.7, 21.4, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.VITAL_SPIRIT, 365, 45, 75, 37, 70, 55, 83, 45, 50, 73, GrowthRate.MEDIUM_FAST, 75, false), + new PokemonSpecies(SpeciesId.MILTANK, 2, false, false, false, "Milk Cow Pokémon", PokemonType.NORMAL, null, 1.2, 75.5, AbilityId.THICK_FAT, AbilityId.SCRAPPY, AbilityId.SAP_SIPPER, 490, 95, 80, 105, 40, 70, 100, 45, 50, 172, GrowthRate.SLOW, 0, false), + new PokemonSpecies(SpeciesId.BLISSEY, 2, false, false, false, "Happiness Pokémon", PokemonType.NORMAL, null, 1.5, 46.8, AbilityId.NATURAL_CURE, AbilityId.SERENE_GRACE, AbilityId.HEALER, 540, 255, 10, 10, 75, 135, 55, 30, 140, 608, GrowthRate.FAST, 0, false), + new PokemonSpecies(SpeciesId.RAIKOU, 2, true, false, false, "Thunder Pokémon", PokemonType.ELECTRIC, null, 1.9, 178, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.INNER_FOCUS, 580, 90, 85, 75, 115, 100, 115, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.ENTEI, 2, true, false, false, "Volcano Pokémon", PokemonType.FIRE, null, 2.1, 198, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.INNER_FOCUS, 580, 115, 115, 85, 90, 75, 100, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.SUICUNE, 2, true, false, false, "Aurora Pokémon", PokemonType.WATER, null, 2, 187, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.INNER_FOCUS, 580, 100, 75, 115, 90, 115, 85, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.LARVITAR, 2, false, false, false, "Rock Skin Pokémon", PokemonType.ROCK, PokemonType.GROUND, 0.6, 72, AbilityId.GUTS, AbilityId.NONE, AbilityId.SAND_VEIL, 300, 50, 64, 50, 45, 50, 41, 45, 35, 60, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.PUPITAR, 2, false, false, false, "Hard Shell Pokémon", PokemonType.ROCK, PokemonType.GROUND, 1.2, 152, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.SHED_SKIN, 410, 70, 84, 70, 65, 70, 51, 45, 35, 144, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.TYRANITAR, 2, false, false, false, "Armor Pokémon", PokemonType.ROCK, PokemonType.DARK, 2, 202, AbilityId.SAND_STREAM, AbilityId.NONE, AbilityId.UNNERVE, 600, 100, 134, 110, 95, 100, 61, 45, 35, 300, GrowthRate.SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.ROCK, PokemonType.DARK, 2, 202, AbilityId.SAND_STREAM, AbilityId.NONE, AbilityId.UNNERVE, 600, 100, 134, 110, 95, 100, 61, 45, 35, 300, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.ROCK, PokemonType.DARK, 2.5, 255, AbilityId.SAND_STREAM, AbilityId.NONE, AbilityId.SAND_STREAM, 700, 100, 164, 150, 95, 120, 71, 45, 35, 300) + ), + new PokemonSpecies(SpeciesId.LUGIA, 2, false, true, false, "Diving Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 5.2, 216, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.MULTISCALE, 680, 106, 90, 130, 90, 154, 110, 3, 0, 340, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.HO_OH, 2, false, true, false, "Rainbow Pokémon", PokemonType.FIRE, PokemonType.FLYING, 3.8, 199, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.REGENERATOR, 680, 106, 130, 90, 110, 154, 90, 3, 0, 340, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.CELEBI, 2, false, false, true, "Time Travel Pokémon", PokemonType.PSYCHIC, PokemonType.GRASS, 0.6, 5, AbilityId.NATURAL_CURE, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 45, 100, 300, GrowthRate.MEDIUM_SLOW, null, false), + new PokemonSpecies(SpeciesId.TREECKO, 3, false, false, false, "Wood Gecko Pokémon", PokemonType.GRASS, null, 0.5, 5, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.UNBURDEN, 310, 40, 45, 35, 65, 55, 70, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.GROVYLE, 3, false, false, false, "Wood Gecko Pokémon", PokemonType.GRASS, null, 0.9, 21.6, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.UNBURDEN, 405, 50, 65, 45, 85, 65, 95, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.SCEPTILE, 3, false, false, false, "Forest Pokémon", PokemonType.GRASS, null, 1.7, 52.2, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.UNBURDEN, 530, 70, 85, 65, 105, 85, 120, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, + new PokemonForm("Normal", "", PokemonType.GRASS, null, 1.7, 52.2, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.UNBURDEN, 530, 70, 85, 65, 105, 85, 120, 45, 50, 265, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.GRASS, PokemonType.DRAGON, 1.9, 55.2, AbilityId.LIGHTNING_ROD, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 630, 70, 110, 75, 145, 85, 145, 45, 50, 265) + ), + new PokemonSpecies(SpeciesId.TORCHIC, 3, false, false, false, "Chick Pokémon", PokemonType.FIRE, null, 0.4, 2.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SPEED_BOOST, 310, 45, 60, 40, 70, 50, 45, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, true), + new PokemonSpecies(SpeciesId.COMBUSKEN, 3, false, false, false, "Young Fowl Pokémon", PokemonType.FIRE, PokemonType.FIGHTING, 0.9, 19.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SPEED_BOOST, 405, 60, 85, 60, 85, 60, 55, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, true), + new PokemonSpecies(SpeciesId.BLAZIKEN, 3, false, false, false, "Blaze Pokémon", PokemonType.FIRE, PokemonType.FIGHTING, 1.9, 52, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SPEED_BOOST, 530, 80, 120, 70, 110, 70, 80, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, true, true, + new PokemonForm("Normal", "", PokemonType.FIRE, PokemonType.FIGHTING, 1.9, 52, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SPEED_BOOST, 530, 80, 120, 70, 110, 70, 80, 45, 50, 265, true, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.FIRE, PokemonType.FIGHTING, 1.9, 52, AbilityId.SPEED_BOOST, AbilityId.NONE, AbilityId.SPEED_BOOST, 630, 80, 160, 80, 130, 80, 100, 45, 50, 265, true) + ), + new PokemonSpecies(SpeciesId.MUDKIP, 3, false, false, false, "Mud Fish Pokémon", PokemonType.WATER, null, 0.4, 7.6, AbilityId.TORRENT, AbilityId.NONE, AbilityId.DAMP, 310, 50, 70, 50, 50, 50, 40, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.MARSHTOMP, 3, false, false, false, "Mud Fish Pokémon", PokemonType.WATER, PokemonType.GROUND, 0.7, 28, AbilityId.TORRENT, AbilityId.NONE, AbilityId.DAMP, 405, 70, 85, 70, 60, 70, 50, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.SWAMPERT, 3, false, false, false, "Mud Fish Pokémon", PokemonType.WATER, PokemonType.GROUND, 1.5, 81.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.DAMP, 535, 100, 110, 90, 85, 90, 60, 45, 50, 268, GrowthRate.MEDIUM_SLOW, 87.5, false, true, + new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.GROUND, 1.5, 81.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.DAMP, 535, 100, 110, 90, 85, 90, 60, 45, 50, 268, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.WATER, PokemonType.GROUND, 1.9, 102, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.SWIFT_SWIM, 635, 100, 150, 110, 95, 110, 70, 45, 50, 268) + ), + new PokemonSpecies(SpeciesId.POOCHYENA, 3, false, false, false, "Bite Pokémon", PokemonType.DARK, null, 0.5, 13.6, AbilityId.RUN_AWAY, AbilityId.QUICK_FEET, AbilityId.RATTLED, 220, 35, 55, 35, 30, 30, 35, 255, 70, 56, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MIGHTYENA, 3, false, false, false, "Bite Pokémon", PokemonType.DARK, null, 1, 37, AbilityId.INTIMIDATE, AbilityId.QUICK_FEET, AbilityId.MOXIE, 420, 70, 90, 70, 60, 60, 70, 127, 70, 147, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ZIGZAGOON, 3, false, false, false, "Tiny Raccoon Pokémon", PokemonType.NORMAL, null, 0.4, 17.5, AbilityId.PICKUP, AbilityId.GLUTTONY, AbilityId.QUICK_FEET, 240, 38, 30, 41, 30, 41, 60, 255, 50, 56, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.LINOONE, 3, false, false, false, "Rushing Pokémon", PokemonType.NORMAL, null, 0.5, 32.5, AbilityId.PICKUP, AbilityId.GLUTTONY, AbilityId.QUICK_FEET, 420, 78, 70, 61, 50, 61, 100, 90, 50, 147, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.WURMPLE, 3, false, false, false, "Worm Pokémon", PokemonType.BUG, null, 0.3, 3.6, AbilityId.SHIELD_DUST, AbilityId.NONE, AbilityId.RUN_AWAY, 195, 45, 45, 35, 20, 30, 20, 255, 70, 56, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SILCOON, 3, false, false, false, "Cocoon Pokémon", PokemonType.BUG, null, 0.6, 10, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.SHED_SKIN, 205, 50, 35, 55, 25, 25, 15, 120, 70, 72, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BEAUTIFLY, 3, false, false, false, "Butterfly Pokémon", PokemonType.BUG, PokemonType.FLYING, 1, 28.4, AbilityId.SWARM, AbilityId.NONE, AbilityId.RIVALRY, 395, 60, 70, 50, 100, 50, 65, 45, 70, 198, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.CASCOON, 3, false, false, false, "Cocoon Pokémon", PokemonType.BUG, null, 0.7, 11.5, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.SHED_SKIN, 205, 50, 35, 55, 25, 25, 15, 120, 70, 72, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DUSTOX, 3, false, false, false, "Poison Moth Pokémon", PokemonType.BUG, PokemonType.POISON, 1.2, 31.6, AbilityId.SHIELD_DUST, AbilityId.NONE, AbilityId.COMPOUND_EYES, 385, 60, 50, 70, 50, 90, 65, 45, 70, 193, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.LOTAD, 3, false, false, false, "Water Weed Pokémon", PokemonType.WATER, PokemonType.GRASS, 0.5, 2.6, AbilityId.SWIFT_SWIM, AbilityId.RAIN_DISH, AbilityId.OWN_TEMPO, 220, 40, 30, 30, 40, 50, 30, 255, 50, 44, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.LOMBRE, 3, false, false, false, "Jolly Pokémon", PokemonType.WATER, PokemonType.GRASS, 1.2, 32.5, AbilityId.SWIFT_SWIM, AbilityId.RAIN_DISH, AbilityId.OWN_TEMPO, 340, 60, 50, 50, 60, 70, 50, 120, 50, 119, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.LUDICOLO, 3, false, false, false, "Carefree Pokémon", PokemonType.WATER, PokemonType.GRASS, 1.5, 55, AbilityId.SWIFT_SWIM, AbilityId.RAIN_DISH, AbilityId.OWN_TEMPO, 480, 80, 70, 70, 90, 100, 70, 45, 50, 240, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.SEEDOT, 3, false, false, false, "Acorn Pokémon", PokemonType.GRASS, null, 0.5, 4, AbilityId.CHLOROPHYLL, AbilityId.EARLY_BIRD, AbilityId.PICKPOCKET, 220, 40, 40, 50, 30, 30, 30, 255, 50, 44, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.NUZLEAF, 3, false, false, false, "Wily Pokémon", PokemonType.GRASS, PokemonType.DARK, 1, 28, AbilityId.CHLOROPHYLL, AbilityId.EARLY_BIRD, AbilityId.PICKPOCKET, 340, 70, 70, 40, 60, 40, 60, 120, 50, 119, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.SHIFTRY, 3, false, false, false, "Wicked Pokémon", PokemonType.GRASS, PokemonType.DARK, 1.3, 59.6, AbilityId.CHLOROPHYLL, AbilityId.WIND_RIDER, AbilityId.PICKPOCKET, 480, 90, 100, 60, 90, 60, 80, 45, 50, 240, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.TAILLOW, 3, false, false, false, "Tiny Swallow Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 2.3, AbilityId.GUTS, AbilityId.NONE, AbilityId.SCRAPPY, 270, 40, 55, 30, 30, 30, 85, 200, 70, 54, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SWELLOW, 3, false, false, false, "Swallow Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.7, 19.8, AbilityId.GUTS, AbilityId.NONE, AbilityId.SCRAPPY, 455, 60, 85, 60, 75, 50, 125, 45, 70, 159, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.WINGULL, 3, false, false, false, "Seagull Pokémon", PokemonType.WATER, PokemonType.FLYING, 0.6, 9.5, AbilityId.KEEN_EYE, AbilityId.HYDRATION, AbilityId.RAIN_DISH, 270, 40, 30, 30, 55, 30, 85, 190, 50, 54, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PELIPPER, 3, false, false, false, "Water Bird Pokémon", PokemonType.WATER, PokemonType.FLYING, 1.2, 28, AbilityId.KEEN_EYE, AbilityId.DRIZZLE, AbilityId.RAIN_DISH, 440, 60, 50, 100, 95, 70, 65, 45, 50, 154, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.RALTS, 3, false, false, false, "Feeling Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 0.4, 6.6, AbilityId.SYNCHRONIZE, AbilityId.TRACE, AbilityId.TELEPATHY, 198, 28, 25, 25, 45, 35, 40, 235, 35, 40, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.KIRLIA, 3, false, false, false, "Emotion Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 0.8, 20.2, AbilityId.SYNCHRONIZE, AbilityId.TRACE, AbilityId.TELEPATHY, 278, 38, 35, 35, 65, 55, 50, 120, 35, 97, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.GARDEVOIR, 3, false, false, false, "Embrace Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 1.6, 48.4, AbilityId.SYNCHRONIZE, AbilityId.TRACE, AbilityId.TELEPATHY, 518, 68, 65, 65, 125, 115, 80, 45, 35, 259, GrowthRate.SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.PSYCHIC, PokemonType.FAIRY, 1.6, 48.4, AbilityId.SYNCHRONIZE, AbilityId.TRACE, AbilityId.TELEPATHY, 518, 68, 65, 65, 125, 115, 80, 45, 35, 259, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.PSYCHIC, PokemonType.FAIRY, 1.6, 48.4, AbilityId.PIXILATE, AbilityId.PIXILATE, AbilityId.PIXILATE, 618, 68, 85, 65, 165, 135, 100, 45, 35, 259) + ), + new PokemonSpecies(SpeciesId.SURSKIT, 3, false, false, false, "Pond Skater Pokémon", PokemonType.BUG, PokemonType.WATER, 0.5, 1.7, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.RAIN_DISH, 269, 40, 30, 32, 50, 52, 65, 200, 70, 54, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MASQUERAIN, 3, false, false, false, "Eyeball Pokémon", PokemonType.BUG, PokemonType.FLYING, 0.8, 3.6, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.UNNERVE, 454, 70, 60, 62, 100, 82, 80, 75, 70, 159, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SHROOMISH, 3, false, false, false, "Mushroom Pokémon", PokemonType.GRASS, null, 0.4, 4.5, AbilityId.EFFECT_SPORE, AbilityId.POISON_HEAL, AbilityId.QUICK_FEET, 295, 60, 40, 60, 40, 60, 35, 255, 70, 59, GrowthRate.FLUCTUATING, 50, false), + new PokemonSpecies(SpeciesId.BRELOOM, 3, false, false, false, "Mushroom Pokémon", PokemonType.GRASS, PokemonType.FIGHTING, 1.2, 39.2, AbilityId.EFFECT_SPORE, AbilityId.POISON_HEAL, AbilityId.TECHNICIAN, 460, 60, 130, 80, 60, 60, 70, 90, 70, 161, GrowthRate.FLUCTUATING, 50, false), + new PokemonSpecies(SpeciesId.SLAKOTH, 3, false, false, false, "Slacker Pokémon", PokemonType.NORMAL, null, 0.8, 24, AbilityId.TRUANT, AbilityId.NONE, AbilityId.STALL, 280, 60, 60, 60, 35, 35, 30, 255, 70, 56, GrowthRate.SLOW, 50, false), //Custom Hidden + new PokemonSpecies(SpeciesId.VIGOROTH, 3, false, false, false, "Wild Monkey Pokémon", PokemonType.NORMAL, null, 1.4, 46.5, AbilityId.VITAL_SPIRIT, AbilityId.NONE, AbilityId.INSOMNIA, 440, 80, 80, 80, 55, 55, 90, 120, 70, 154, GrowthRate.SLOW, 50, false), //Custom Hidden + new PokemonSpecies(SpeciesId.SLAKING, 3, false, false, false, "Lazy Pokémon", PokemonType.NORMAL, null, 2, 130.5, AbilityId.TRUANT, AbilityId.NONE, AbilityId.STALL, 670, 150, 160, 100, 95, 65, 100, 45, 70, 285, GrowthRate.SLOW, 50, false), //Custom Hidden + new PokemonSpecies(SpeciesId.NINCADA, 3, false, false, false, "Trainee Pokémon", PokemonType.BUG, PokemonType.GROUND, 0.5, 5.5, AbilityId.COMPOUND_EYES, AbilityId.NONE, AbilityId.RUN_AWAY, 266, 31, 45, 90, 30, 30, 40, 255, 50, 53, GrowthRate.ERRATIC, 50, false), + new PokemonSpecies(SpeciesId.NINJASK, 3, false, false, false, "Ninja Pokémon", PokemonType.BUG, PokemonType.FLYING, 0.8, 12, AbilityId.SPEED_BOOST, AbilityId.NONE, AbilityId.INFILTRATOR, 456, 61, 90, 45, 50, 50, 160, 120, 50, 160, GrowthRate.ERRATIC, 50, false), + new PokemonSpecies(SpeciesId.SHEDINJA, 3, false, false, false, "Shed Pokémon", PokemonType.BUG, PokemonType.GHOST, 0.8, 1.2, AbilityId.WONDER_GUARD, AbilityId.NONE, AbilityId.NONE, 236, 1, 90, 45, 30, 30, 40, 45, 50, 83, GrowthRate.ERRATIC, null, false), + new PokemonSpecies(SpeciesId.WHISMUR, 3, false, false, false, "Whisper Pokémon", PokemonType.NORMAL, null, 0.6, 16.3, AbilityId.SOUNDPROOF, AbilityId.NONE, AbilityId.RATTLED, 240, 64, 51, 23, 51, 23, 28, 190, 50, 48, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.LOUDRED, 3, false, false, false, "Big Voice Pokémon", PokemonType.NORMAL, null, 1, 40.5, AbilityId.SOUNDPROOF, AbilityId.NONE, AbilityId.SCRAPPY, 360, 84, 71, 43, 71, 43, 48, 120, 50, 126, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.EXPLOUD, 3, false, false, false, "Loud Noise Pokémon", PokemonType.NORMAL, null, 1.5, 84, AbilityId.SOUNDPROOF, AbilityId.NONE, AbilityId.SCRAPPY, 490, 104, 91, 63, 91, 73, 68, 45, 50, 245, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.MAKUHITA, 3, false, false, false, "Guts Pokémon", PokemonType.FIGHTING, null, 1, 86.4, AbilityId.THICK_FAT, AbilityId.GUTS, AbilityId.SHEER_FORCE, 237, 72, 60, 30, 20, 30, 25, 180, 70, 47, GrowthRate.FLUCTUATING, 75, false), + new PokemonSpecies(SpeciesId.HARIYAMA, 3, false, false, false, "Arm Thrust Pokémon", PokemonType.FIGHTING, null, 2.3, 253.8, AbilityId.THICK_FAT, AbilityId.GUTS, AbilityId.SHEER_FORCE, 474, 144, 120, 60, 40, 60, 50, 200, 70, 166, GrowthRate.FLUCTUATING, 75, false), + new PokemonSpecies(SpeciesId.AZURILL, 3, false, false, false, "Polka Dot Pokémon", PokemonType.NORMAL, PokemonType.FAIRY, 0.2, 2, AbilityId.THICK_FAT, AbilityId.HUGE_POWER, AbilityId.SAP_SIPPER, 190, 50, 20, 40, 20, 40, 20, 150, 50, 38, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.NOSEPASS, 3, false, false, false, "Compass Pokémon", PokemonType.ROCK, null, 1, 97, AbilityId.STURDY, AbilityId.MAGNET_PULL, AbilityId.SAND_FORCE, 375, 30, 45, 135, 45, 90, 30, 255, 70, 75, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SKITTY, 3, false, false, false, "Kitten Pokémon", PokemonType.NORMAL, null, 0.6, 11, AbilityId.CUTE_CHARM, AbilityId.NORMALIZE, AbilityId.WONDER_SKIN, 260, 50, 45, 45, 35, 35, 50, 255, 70, 52, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.DELCATTY, 3, false, false, false, "Prim Pokémon", PokemonType.NORMAL, null, 1.1, 32.6, AbilityId.CUTE_CHARM, AbilityId.NORMALIZE, AbilityId.WONDER_SKIN, 400, 70, 65, 65, 55, 55, 90, 60, 70, 140, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.SABLEYE, 3, false, false, false, "Darkness Pokémon", PokemonType.DARK, PokemonType.GHOST, 0.5, 11, AbilityId.KEEN_EYE, AbilityId.STALL, AbilityId.PRANKSTER, 380, 50, 75, 75, 65, 65, 50, 45, 35, 133, GrowthRate.MEDIUM_SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.DARK, PokemonType.GHOST, 0.5, 11, AbilityId.KEEN_EYE, AbilityId.STALL, AbilityId.PRANKSTER, 380, 50, 75, 75, 65, 65, 50, 45, 35, 133, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DARK, PokemonType.GHOST, 0.5, 161, AbilityId.MAGIC_BOUNCE, AbilityId.MAGIC_BOUNCE, AbilityId.MAGIC_BOUNCE, 480, 50, 85, 125, 85, 115, 20, 45, 35, 133) + ), + new PokemonSpecies(SpeciesId.MAWILE, 3, false, false, false, "Deceiver Pokémon", PokemonType.STEEL, PokemonType.FAIRY, 0.6, 11.5, AbilityId.HYPER_CUTTER, AbilityId.INTIMIDATE, AbilityId.SHEER_FORCE, 380, 50, 85, 85, 55, 55, 50, 45, 50, 133, GrowthRate.FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.FAIRY, 0.6, 11.5, AbilityId.HYPER_CUTTER, AbilityId.INTIMIDATE, AbilityId.SHEER_FORCE, 380, 50, 85, 85, 55, 55, 50, 45, 50, 133, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.STEEL, PokemonType.FAIRY, 1, 23.5, AbilityId.HUGE_POWER, AbilityId.HUGE_POWER, AbilityId.HUGE_POWER, 480, 50, 105, 125, 55, 95, 50, 45, 50, 133) + ), + new PokemonSpecies(SpeciesId.ARON, 3, false, false, false, "Iron Armor Pokémon", PokemonType.STEEL, PokemonType.ROCK, 0.4, 60, AbilityId.STURDY, AbilityId.ROCK_HEAD, AbilityId.HEAVY_METAL, 330, 50, 70, 100, 40, 40, 30, 180, 35, 66, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.LAIRON, 3, false, false, false, "Iron Armor Pokémon", PokemonType.STEEL, PokemonType.ROCK, 0.9, 120, AbilityId.STURDY, AbilityId.ROCK_HEAD, AbilityId.HEAVY_METAL, 430, 60, 90, 140, 50, 50, 40, 90, 35, 151, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.AGGRON, 3, false, false, false, "Iron Armor Pokémon", PokemonType.STEEL, PokemonType.ROCK, 2.1, 360, AbilityId.STURDY, AbilityId.ROCK_HEAD, AbilityId.HEAVY_METAL, 530, 70, 110, 180, 60, 60, 50, 45, 35, 265, GrowthRate.SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.ROCK, 2.1, 360, AbilityId.STURDY, AbilityId.ROCK_HEAD, AbilityId.HEAVY_METAL, 530, 70, 110, 180, 60, 60, 50, 45, 35, 265, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.STEEL, null, 2.2, 395, AbilityId.FILTER, AbilityId.FILTER, AbilityId.FILTER, 630, 70, 140, 230, 60, 80, 50, 45, 35, 265) + ), + new PokemonSpecies(SpeciesId.MEDITITE, 3, false, false, false, "Meditate Pokémon", PokemonType.FIGHTING, PokemonType.PSYCHIC, 0.6, 11.2, AbilityId.PURE_POWER, AbilityId.NONE, AbilityId.TELEPATHY, 280, 30, 40, 55, 40, 55, 60, 180, 70, 56, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.MEDICHAM, 3, false, false, false, "Meditate Pokémon", PokemonType.FIGHTING, PokemonType.PSYCHIC, 1.3, 31.5, AbilityId.PURE_POWER, AbilityId.NONE, AbilityId.TELEPATHY, 410, 60, 60, 75, 60, 75, 80, 90, 70, 144, GrowthRate.MEDIUM_FAST, 50, true, true, + new PokemonForm("Normal", "", PokemonType.FIGHTING, PokemonType.PSYCHIC, 1.3, 31.5, AbilityId.PURE_POWER, AbilityId.NONE, AbilityId.TELEPATHY, 410, 60, 60, 75, 60, 75, 80, 90, 70, 144, true, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.FIGHTING, PokemonType.PSYCHIC, 1.3, 31.5, AbilityId.PURE_POWER, AbilityId.NONE, AbilityId.PURE_POWER, 510, 60, 100, 85, 80, 85, 100, 90, 70, 144, true) + ), + new PokemonSpecies(SpeciesId.ELECTRIKE, 3, false, false, false, "Lightning Pokémon", PokemonType.ELECTRIC, null, 0.6, 15.2, AbilityId.STATIC, AbilityId.LIGHTNING_ROD, AbilityId.MINUS, 295, 40, 45, 40, 65, 40, 65, 120, 50, 59, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.MANECTRIC, 3, false, false, false, "Discharge Pokémon", PokemonType.ELECTRIC, null, 1.5, 40.2, AbilityId.STATIC, AbilityId.LIGHTNING_ROD, AbilityId.MINUS, 475, 70, 75, 60, 105, 60, 105, 45, 50, 166, GrowthRate.SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.ELECTRIC, null, 1.5, 40.2, AbilityId.STATIC, AbilityId.LIGHTNING_ROD, AbilityId.MINUS, 475, 70, 75, 60, 105, 60, 105, 45, 50, 166, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.ELECTRIC, null, 1.8, 44, AbilityId.INTIMIDATE, AbilityId.INTIMIDATE, AbilityId.INTIMIDATE, 575, 70, 75, 80, 135, 80, 135, 45, 50, 166) + ), + new PokemonSpecies(SpeciesId.PLUSLE, 3, false, false, false, "Cheering Pokémon", PokemonType.ELECTRIC, null, 0.4, 4.2, AbilityId.PLUS, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 405, 60, 50, 40, 85, 75, 95, 200, 70, 142, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MINUN, 3, false, false, false, "Cheering Pokémon", PokemonType.ELECTRIC, null, 0.4, 4.2, AbilityId.MINUS, AbilityId.NONE, AbilityId.VOLT_ABSORB, 405, 60, 40, 50, 75, 85, 95, 200, 70, 142, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.VOLBEAT, 3, false, false, false, "Firefly Pokémon", PokemonType.BUG, null, 0.7, 17.7, AbilityId.ILLUMINATE, AbilityId.SWARM, AbilityId.PRANKSTER, 430, 65, 73, 75, 47, 85, 85, 150, 70, 151, GrowthRate.ERRATIC, 100, false), + new PokemonSpecies(SpeciesId.ILLUMISE, 3, false, false, false, "Firefly Pokémon", PokemonType.BUG, null, 0.6, 17.7, AbilityId.OBLIVIOUS, AbilityId.TINTED_LENS, AbilityId.PRANKSTER, 430, 65, 47, 75, 73, 85, 85, 150, 70, 151, GrowthRate.FLUCTUATING, 0, false), + new PokemonSpecies(SpeciesId.ROSELIA, 3, false, false, false, "Thorn Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.3, 2, AbilityId.NATURAL_CURE, AbilityId.POISON_POINT, AbilityId.LEAF_GUARD, 400, 50, 60, 45, 100, 80, 65, 150, 50, 140, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.GULPIN, 3, false, false, false, "Stomach Pokémon", PokemonType.POISON, null, 0.4, 10.3, AbilityId.LIQUID_OOZE, AbilityId.STICKY_HOLD, AbilityId.GLUTTONY, 302, 70, 43, 53, 43, 53, 40, 225, 70, 60, GrowthRate.FLUCTUATING, 50, true), + new PokemonSpecies(SpeciesId.SWALOT, 3, false, false, false, "Poison Bag Pokémon", PokemonType.POISON, null, 1.7, 80, AbilityId.LIQUID_OOZE, AbilityId.STICKY_HOLD, AbilityId.GLUTTONY, 467, 100, 73, 83, 73, 83, 55, 75, 70, 163, GrowthRate.FLUCTUATING, 50, true), + new PokemonSpecies(SpeciesId.CARVANHA, 3, false, false, false, "Savage Pokémon", PokemonType.WATER, PokemonType.DARK, 0.8, 20.8, AbilityId.ROUGH_SKIN, AbilityId.NONE, AbilityId.SPEED_BOOST, 305, 45, 90, 20, 65, 20, 65, 225, 35, 61, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.SHARPEDO, 3, false, false, false, "Brutal Pokémon", PokemonType.WATER, PokemonType.DARK, 1.8, 88.8, AbilityId.ROUGH_SKIN, AbilityId.NONE, AbilityId.SPEED_BOOST, 460, 70, 120, 40, 95, 40, 95, 60, 35, 161, GrowthRate.SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.DARK, 1.8, 88.8, AbilityId.ROUGH_SKIN, AbilityId.NONE, AbilityId.SPEED_BOOST, 460, 70, 120, 40, 95, 40, 95, 60, 35, 161, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.WATER, PokemonType.DARK, 2.5, 130.3, AbilityId.STRONG_JAW, AbilityId.NONE, AbilityId.STRONG_JAW, 560, 70, 140, 70, 110, 65, 105, 60, 35, 161) + ), + new PokemonSpecies(SpeciesId.WAILMER, 3, false, false, false, "Ball Whale Pokémon", PokemonType.WATER, null, 2, 130, AbilityId.WATER_VEIL, AbilityId.OBLIVIOUS, AbilityId.PRESSURE, 400, 130, 70, 35, 70, 35, 60, 125, 50, 80, GrowthRate.FLUCTUATING, 50, false), + new PokemonSpecies(SpeciesId.WAILORD, 3, false, false, false, "Float Whale Pokémon", PokemonType.WATER, null, 14.5, 398, AbilityId.WATER_VEIL, AbilityId.OBLIVIOUS, AbilityId.PRESSURE, 500, 170, 90, 45, 90, 45, 60, 60, 50, 175, GrowthRate.FLUCTUATING, 50, false), + new PokemonSpecies(SpeciesId.NUMEL, 3, false, false, false, "Numb Pokémon", PokemonType.FIRE, PokemonType.GROUND, 0.7, 24, AbilityId.OBLIVIOUS, AbilityId.SIMPLE, AbilityId.OWN_TEMPO, 305, 60, 60, 40, 65, 45, 35, 255, 70, 61, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.CAMERUPT, 3, false, false, false, "Eruption Pokémon", PokemonType.FIRE, PokemonType.GROUND, 1.9, 220, AbilityId.MAGMA_ARMOR, AbilityId.SOLID_ROCK, AbilityId.ANGER_POINT, 460, 70, 100, 70, 105, 75, 40, 150, 70, 161, GrowthRate.MEDIUM_FAST, 50, true, true, + new PokemonForm("Normal", "", PokemonType.FIRE, PokemonType.GROUND, 1.9, 220, AbilityId.MAGMA_ARMOR, AbilityId.SOLID_ROCK, AbilityId.ANGER_POINT, 460, 70, 100, 70, 105, 75, 40, 150, 70, 161, true, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.FIRE, PokemonType.GROUND, 2.5, 320.5, AbilityId.SHEER_FORCE, AbilityId.SHEER_FORCE, AbilityId.SHEER_FORCE, 560, 70, 120, 100, 145, 105, 20, 150, 70, 161) + ), + new PokemonSpecies(SpeciesId.TORKOAL, 3, false, false, false, "Coal Pokémon", PokemonType.FIRE, null, 0.5, 80.4, AbilityId.WHITE_SMOKE, AbilityId.DROUGHT, AbilityId.SHELL_ARMOR, 470, 70, 85, 140, 85, 70, 20, 90, 50, 165, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SPOINK, 3, false, false, false, "Bounce Pokémon", PokemonType.PSYCHIC, null, 0.7, 30.6, AbilityId.THICK_FAT, AbilityId.OWN_TEMPO, AbilityId.GLUTTONY, 330, 60, 25, 35, 70, 80, 60, 255, 70, 66, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.GRUMPIG, 3, false, false, false, "Manipulate Pokémon", PokemonType.PSYCHIC, null, 0.9, 71.5, AbilityId.THICK_FAT, AbilityId.OWN_TEMPO, AbilityId.GLUTTONY, 470, 80, 45, 65, 90, 110, 80, 60, 70, 165, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.SPINDA, 3, false, false, false, "Spot Panda Pokémon", PokemonType.NORMAL, null, 1.1, 5, AbilityId.OWN_TEMPO, AbilityId.TANGLED_FEET, AbilityId.CONTRARY, 360, 60, 60, 60, 60, 60, 60, 255, 70, 126, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.TRAPINCH, 3, false, false, false, "Ant Pit Pokémon", PokemonType.GROUND, null, 0.7, 15, AbilityId.HYPER_CUTTER, AbilityId.ARENA_TRAP, AbilityId.SHEER_FORCE, 290, 45, 100, 45, 45, 45, 10, 255, 50, 58, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.VIBRAVA, 3, false, false, false, "Vibration Pokémon", PokemonType.GROUND, PokemonType.DRAGON, 1.1, 15.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 340, 50, 70, 50, 50, 50, 70, 120, 50, 119, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.FLYGON, 3, false, false, false, "Mystic Pokémon", PokemonType.GROUND, PokemonType.DRAGON, 2, 82, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 520, 80, 100, 80, 80, 80, 100, 45, 50, 260, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.CACNEA, 3, false, false, false, "Cactus Pokémon", PokemonType.GRASS, null, 0.4, 51.3, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.WATER_ABSORB, 335, 50, 85, 40, 85, 40, 35, 190, 35, 67, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.CACTURNE, 3, false, false, false, "Scarecrow Pokémon", PokemonType.GRASS, PokemonType.DARK, 1.3, 77.4, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.WATER_ABSORB, 475, 70, 115, 60, 115, 60, 55, 60, 35, 166, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.SWABLU, 3, false, false, false, "Cotton Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.4, 1.2, AbilityId.NATURAL_CURE, AbilityId.NONE, AbilityId.CLOUD_NINE, 310, 45, 40, 60, 40, 75, 50, 255, 50, 62, GrowthRate.ERRATIC, 50, false), + new PokemonSpecies(SpeciesId.ALTARIA, 3, false, false, false, "Humming Pokémon", PokemonType.DRAGON, PokemonType.FLYING, 1.1, 20.6, AbilityId.NATURAL_CURE, AbilityId.NONE, AbilityId.CLOUD_NINE, 490, 75, 70, 90, 70, 105, 80, 45, 50, 172, GrowthRate.ERRATIC, 50, false, true, + new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.FLYING, 1.1, 20.6, AbilityId.NATURAL_CURE, AbilityId.NONE, AbilityId.CLOUD_NINE, 490, 75, 70, 90, 70, 105, 80, 45, 50, 172, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.FAIRY, 1.5, 20.6, AbilityId.PIXILATE, AbilityId.NONE, AbilityId.PIXILATE, 590, 75, 110, 110, 110, 105, 80, 45, 50, 172) + ), + new PokemonSpecies(SpeciesId.ZANGOOSE, 3, false, false, false, "Cat Ferret Pokémon", PokemonType.NORMAL, null, 1.3, 40.3, AbilityId.IMMUNITY, AbilityId.NONE, AbilityId.TOXIC_BOOST, 458, 73, 115, 60, 60, 60, 90, 90, 70, 160, GrowthRate.ERRATIC, 50, false), + new PokemonSpecies(SpeciesId.SEVIPER, 3, false, false, false, "Fang Snake Pokémon", PokemonType.POISON, null, 2.7, 52.5, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.INFILTRATOR, 458, 73, 100, 60, 100, 60, 65, 90, 70, 160, GrowthRate.FLUCTUATING, 50, false), + new PokemonSpecies(SpeciesId.LUNATONE, 3, false, false, false, "Meteorite Pokémon", PokemonType.ROCK, PokemonType.PSYCHIC, 1, 168, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 460, 90, 55, 65, 95, 85, 70, 45, 50, 161, GrowthRate.FAST, null, false), + new PokemonSpecies(SpeciesId.SOLROCK, 3, false, false, false, "Meteorite Pokémon", PokemonType.ROCK, PokemonType.PSYCHIC, 1.2, 154, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 460, 90, 95, 85, 55, 65, 70, 45, 50, 161, GrowthRate.FAST, null, false), + new PokemonSpecies(SpeciesId.BARBOACH, 3, false, false, false, "Whiskers Pokémon", PokemonType.WATER, PokemonType.GROUND, 0.4, 1.9, AbilityId.OBLIVIOUS, AbilityId.ANTICIPATION, AbilityId.HYDRATION, 288, 50, 48, 43, 46, 41, 60, 190, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.WHISCASH, 3, false, false, false, "Whiskers Pokémon", PokemonType.WATER, PokemonType.GROUND, 0.9, 23.6, AbilityId.OBLIVIOUS, AbilityId.ANTICIPATION, AbilityId.HYDRATION, 468, 110, 78, 73, 76, 71, 60, 75, 50, 164, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CORPHISH, 3, false, false, false, "Ruffian Pokémon", PokemonType.WATER, null, 0.6, 11.5, AbilityId.HYPER_CUTTER, AbilityId.SHELL_ARMOR, AbilityId.ADAPTABILITY, 308, 43, 80, 65, 50, 35, 35, 205, 50, 62, GrowthRate.FLUCTUATING, 50, false), + new PokemonSpecies(SpeciesId.CRAWDAUNT, 3, false, false, false, "Rogue Pokémon", PokemonType.WATER, PokemonType.DARK, 1.1, 32.8, AbilityId.HYPER_CUTTER, AbilityId.SHELL_ARMOR, AbilityId.ADAPTABILITY, 468, 63, 120, 85, 90, 55, 55, 155, 50, 164, GrowthRate.FLUCTUATING, 50, false), + new PokemonSpecies(SpeciesId.BALTOY, 3, false, false, false, "Clay Doll Pokémon", PokemonType.GROUND, PokemonType.PSYCHIC, 0.5, 21.5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 300, 40, 40, 55, 40, 70, 55, 255, 50, 60, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.CLAYDOL, 3, false, false, false, "Clay Doll Pokémon", PokemonType.GROUND, PokemonType.PSYCHIC, 1.5, 108, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 500, 60, 70, 105, 70, 120, 75, 90, 50, 175, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.LILEEP, 3, false, false, false, "Sea Lily Pokémon", PokemonType.ROCK, PokemonType.GRASS, 1, 23.8, AbilityId.SUCTION_CUPS, AbilityId.NONE, AbilityId.STORM_DRAIN, 355, 66, 41, 77, 61, 87, 23, 45, 50, 71, GrowthRate.ERRATIC, 87.5, false), + new PokemonSpecies(SpeciesId.CRADILY, 3, false, false, false, "Barnacle Pokémon", PokemonType.ROCK, PokemonType.GRASS, 1.5, 60.4, AbilityId.SUCTION_CUPS, AbilityId.NONE, AbilityId.STORM_DRAIN, 495, 86, 81, 97, 81, 107, 43, 45, 50, 173, GrowthRate.ERRATIC, 87.5, false), + new PokemonSpecies(SpeciesId.ANORITH, 3, false, false, false, "Old Shrimp Pokémon", PokemonType.ROCK, PokemonType.BUG, 0.7, 12.5, AbilityId.BATTLE_ARMOR, AbilityId.NONE, AbilityId.SWIFT_SWIM, 355, 45, 95, 50, 40, 50, 75, 45, 50, 71, GrowthRate.ERRATIC, 87.5, false), + new PokemonSpecies(SpeciesId.ARMALDO, 3, false, false, false, "Plate Pokémon", PokemonType.ROCK, PokemonType.BUG, 1.5, 68.2, AbilityId.BATTLE_ARMOR, AbilityId.NONE, AbilityId.SWIFT_SWIM, 495, 75, 125, 100, 70, 80, 45, 45, 50, 173, GrowthRate.ERRATIC, 87.5, false), + new PokemonSpecies(SpeciesId.FEEBAS, 3, false, false, false, "Fish Pokémon", PokemonType.WATER, null, 0.6, 7.4, AbilityId.SWIFT_SWIM, AbilityId.OBLIVIOUS, AbilityId.ADAPTABILITY, 200, 20, 15, 20, 10, 55, 80, 255, 50, 40, GrowthRate.ERRATIC, 50, false), + new PokemonSpecies(SpeciesId.MILOTIC, 3, false, false, false, "Tender Pokémon", PokemonType.WATER, null, 6.2, 162, AbilityId.MARVEL_SCALE, AbilityId.COMPETITIVE, AbilityId.CUTE_CHARM, 540, 95, 60, 79, 100, 125, 81, 60, 50, 189, GrowthRate.ERRATIC, 50, true), + new PokemonSpecies(SpeciesId.CASTFORM, 3, false, false, false, "Weather Pokémon", PokemonType.NORMAL, null, 0.3, 0.8, AbilityId.FORECAST, AbilityId.NONE, AbilityId.NONE, 420, 70, 70, 70, 70, 70, 70, 45, 70, 147, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal Form", "", PokemonType.NORMAL, null, 0.3, 0.8, AbilityId.FORECAST, AbilityId.NONE, AbilityId.NONE, 420, 70, 70, 70, 70, 70, 70, 45, 70, 147, false, null, true), + new PokemonForm("Sunny Form", "sunny", PokemonType.FIRE, null, 0.3, 0.8, AbilityId.FORECAST, AbilityId.NONE, AbilityId.NONE, 420, 70, 70, 70, 70, 70, 70, 45, 70, 147), + new PokemonForm("Rainy Form", "rainy", PokemonType.WATER, null, 0.3, 0.8, AbilityId.FORECAST, AbilityId.NONE, AbilityId.NONE, 420, 70, 70, 70, 70, 70, 70, 45, 70, 147), + new PokemonForm("Snowy Form", "snowy", PokemonType.ICE, null, 0.3, 0.8, AbilityId.FORECAST, AbilityId.NONE, AbilityId.NONE, 420, 70, 70, 70, 70, 70, 70, 45, 70, 147) + ), + new PokemonSpecies(SpeciesId.KECLEON, 3, false, false, false, "Color Swap Pokémon", PokemonType.NORMAL, null, 1, 22, AbilityId.COLOR_CHANGE, AbilityId.NONE, AbilityId.PROTEAN, 440, 60, 90, 70, 60, 120, 40, 200, 70, 154, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SHUPPET, 3, false, false, false, "Puppet Pokémon", PokemonType.GHOST, null, 0.6, 2.3, AbilityId.INSOMNIA, AbilityId.FRISK, AbilityId.CURSED_BODY, 295, 44, 75, 35, 63, 33, 45, 225, 35, 59, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.BANETTE, 3, false, false, false, "Marionette Pokémon", PokemonType.GHOST, null, 1.1, 12.5, AbilityId.INSOMNIA, AbilityId.FRISK, AbilityId.CURSED_BODY, 455, 64, 115, 65, 83, 63, 65, 45, 35, 159, GrowthRate.FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.GHOST, null, 1.1, 12.5, AbilityId.INSOMNIA, AbilityId.FRISK, AbilityId.CURSED_BODY, 455, 64, 115, 65, 83, 63, 65, 45, 35, 159, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.GHOST, null, 1.2, 13, AbilityId.PRANKSTER, AbilityId.PRANKSTER, AbilityId.PRANKSTER, 555, 64, 165, 75, 93, 83, 75, 45, 35, 159) + ), + new PokemonSpecies(SpeciesId.DUSKULL, 3, false, false, false, "Requiem Pokémon", PokemonType.GHOST, null, 0.8, 15, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.FRISK, 295, 20, 40, 90, 30, 90, 25, 190, 35, 59, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.DUSCLOPS, 3, false, false, false, "Beckon Pokémon", PokemonType.GHOST, null, 1.6, 30.6, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.FRISK, 455, 40, 70, 130, 60, 130, 25, 90, 35, 159, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.TROPIUS, 3, false, false, false, "Fruit Pokémon", PokemonType.GRASS, PokemonType.FLYING, 2, 100, AbilityId.CHLOROPHYLL, AbilityId.SOLAR_POWER, AbilityId.HARVEST, 460, 99, 68, 83, 72, 87, 51, 200, 70, 161, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.CHIMECHO, 3, false, false, false, "Wind Chime Pokémon", PokemonType.PSYCHIC, null, 0.6, 1, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 455, 75, 50, 80, 95, 90, 65, 45, 70, 159, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.ABSOL, 3, false, false, false, "Disaster Pokémon", PokemonType.DARK, null, 1.2, 47, AbilityId.PRESSURE, AbilityId.SUPER_LUCK, AbilityId.JUSTIFIED, 465, 65, 130, 60, 75, 60, 75, 30, 35, 163, GrowthRate.MEDIUM_SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.DARK, null, 1.2, 47, AbilityId.PRESSURE, AbilityId.SUPER_LUCK, AbilityId.JUSTIFIED, 465, 65, 130, 60, 75, 60, 75, 30, 35, 163, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DARK, null, 1.2, 49, AbilityId.MAGIC_BOUNCE, AbilityId.MAGIC_BOUNCE, AbilityId.MAGIC_BOUNCE, 565, 65, 150, 60, 115, 60, 115, 30, 35, 163) + ), + new PokemonSpecies(SpeciesId.WYNAUT, 3, false, false, false, "Bright Pokémon", PokemonType.PSYCHIC, null, 0.6, 14, AbilityId.SHADOW_TAG, AbilityId.NONE, AbilityId.TELEPATHY, 260, 95, 23, 48, 23, 48, 23, 125, 50, 52, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SNORUNT, 3, false, false, false, "Snow Hat Pokémon", PokemonType.ICE, null, 0.7, 16.8, AbilityId.INNER_FOCUS, AbilityId.ICE_BODY, AbilityId.MOODY, 300, 50, 50, 50, 50, 50, 50, 190, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GLALIE, 3, false, false, false, "Face Pokémon", PokemonType.ICE, null, 1.5, 256.5, AbilityId.INNER_FOCUS, AbilityId.ICE_BODY, AbilityId.MOODY, 480, 80, 80, 80, 80, 80, 80, 75, 50, 168, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.ICE, null, 1.5, 256.5, AbilityId.INNER_FOCUS, AbilityId.ICE_BODY, AbilityId.MOODY, 480, 80, 80, 80, 80, 80, 80, 75, 50, 168, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.ICE, null, 2.1, 350.2, AbilityId.REFRIGERATE, AbilityId.REFRIGERATE, AbilityId.REFRIGERATE, 580, 80, 120, 80, 120, 80, 100, 75, 50, 168) + ), + new PokemonSpecies(SpeciesId.SPHEAL, 3, false, false, false, "Clap Pokémon", PokemonType.ICE, PokemonType.WATER, 0.8, 39.5, AbilityId.THICK_FAT, AbilityId.ICE_BODY, AbilityId.OBLIVIOUS, 290, 70, 40, 50, 55, 50, 25, 255, 50, 58, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SEALEO, 3, false, false, false, "Ball Roll Pokémon", PokemonType.ICE, PokemonType.WATER, 1.1, 87.6, AbilityId.THICK_FAT, AbilityId.ICE_BODY, AbilityId.OBLIVIOUS, 410, 90, 60, 70, 75, 70, 45, 120, 50, 144, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.WALREIN, 3, false, false, false, "Ice Break Pokémon", PokemonType.ICE, PokemonType.WATER, 1.4, 150.6, AbilityId.THICK_FAT, AbilityId.ICE_BODY, AbilityId.OBLIVIOUS, 530, 110, 80, 90, 95, 90, 65, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.CLAMPERL, 3, false, false, false, "Bivalve Pokémon", PokemonType.WATER, null, 0.4, 52.5, AbilityId.SHELL_ARMOR, AbilityId.NONE, AbilityId.RATTLED, 345, 35, 64, 85, 74, 55, 32, 255, 70, 69, GrowthRate.ERRATIC, 50, false), + new PokemonSpecies(SpeciesId.HUNTAIL, 3, false, false, false, "Deep Sea Pokémon", PokemonType.WATER, null, 1.7, 27, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.WATER_VEIL, 485, 55, 104, 105, 94, 75, 52, 60, 70, 170, GrowthRate.ERRATIC, 50, false), + new PokemonSpecies(SpeciesId.GOREBYSS, 3, false, false, false, "South Sea Pokémon", PokemonType.WATER, null, 1.8, 22.6, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.HYDRATION, 485, 55, 84, 105, 114, 75, 52, 60, 70, 170, GrowthRate.ERRATIC, 50, false), + new PokemonSpecies(SpeciesId.RELICANTH, 3, false, false, false, "Longevity Pokémon", PokemonType.WATER, PokemonType.ROCK, 1, 23.4, AbilityId.SWIFT_SWIM, AbilityId.ROCK_HEAD, AbilityId.STURDY, 485, 100, 90, 130, 45, 65, 55, 25, 50, 170, GrowthRate.SLOW, 87.5, true), + new PokemonSpecies(SpeciesId.LUVDISC, 3, false, false, false, "Rendezvous Pokémon", PokemonType.WATER, null, 0.6, 8.7, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.HYDRATION, 330, 43, 30, 55, 40, 65, 97, 225, 70, 116, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.BAGON, 3, false, false, false, "Rock Head Pokémon", PokemonType.DRAGON, null, 0.6, 42.1, AbilityId.ROCK_HEAD, AbilityId.NONE, AbilityId.SHEER_FORCE, 300, 45, 75, 60, 40, 30, 50, 45, 35, 60, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.SHELGON, 3, false, false, false, "Endurance Pokémon", PokemonType.DRAGON, null, 1.1, 110.5, AbilityId.ROCK_HEAD, AbilityId.NONE, AbilityId.OVERCOAT, 420, 65, 95, 100, 60, 50, 50, 45, 35, 147, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.SALAMENCE, 3, false, false, false, "Dragon Pokémon", PokemonType.DRAGON, PokemonType.FLYING, 1.5, 102.6, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.MOXIE, 600, 95, 135, 80, 110, 80, 100, 45, 35, 300, GrowthRate.SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.FLYING, 1.5, 102.6, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.MOXIE, 600, 95, 135, 80, 110, 80, 100, 45, 35, 300, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.FLYING, 1.8, 112.6, AbilityId.AERILATE, AbilityId.NONE, AbilityId.AERILATE, 700, 95, 145, 130, 120, 90, 120, 45, 35, 300) + ), + new PokemonSpecies(SpeciesId.BELDUM, 3, false, false, false, "Iron Ball Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 0.6, 95.2, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.LIGHT_METAL, 300, 40, 55, 80, 35, 60, 30, 45, 35, 60, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Frigibax + new PokemonSpecies(SpeciesId.METANG, 3, false, false, false, "Iron Claw Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 1.2, 202.5, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.LIGHT_METAL, 420, 60, 75, 100, 55, 80, 50, 25, 35, 147, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Arctibax + new PokemonSpecies(SpeciesId.METAGROSS, 3, false, false, false, "Iron Leg Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 1.6, 550, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.LIGHT_METAL, 600, 80, 135, 130, 95, 90, 70, 10, 35, 300, GrowthRate.SLOW, null, false, true, //Custom Catchrate, matching Baxcalibur + new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.PSYCHIC, 1.6, 550, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.LIGHT_METAL, 600, 80, 135, 130, 95, 90, 70, 3, 35, 300, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.STEEL, PokemonType.PSYCHIC, 2.5, 942.9, AbilityId.TOUGH_CLAWS, AbilityId.NONE, AbilityId.TOUGH_CLAWS, 700, 80, 145, 150, 105, 110, 110, 3, 35, 300) + ), + new PokemonSpecies(SpeciesId.REGIROCK, 3, true, false, false, "Rock Peak Pokémon", PokemonType.ROCK, null, 1.7, 230, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.STURDY, 580, 80, 100, 200, 50, 100, 50, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.REGICE, 3, true, false, false, "Iceberg Pokémon", PokemonType.ICE, null, 1.8, 175, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.ICE_BODY, 580, 80, 50, 100, 100, 200, 50, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.REGISTEEL, 3, true, false, false, "Iron Pokémon", PokemonType.STEEL, null, 1.9, 205, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.LIGHT_METAL, 580, 80, 75, 150, 75, 150, 50, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.LATIAS, 3, true, false, false, "Eon Pokémon", PokemonType.DRAGON, PokemonType.PSYCHIC, 1.4, 40, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 600, 80, 80, 90, 110, 130, 110, 3, 90, 300, GrowthRate.SLOW, 0, false, true, + new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.PSYCHIC, 1.4, 40, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 600, 80, 80, 90, 110, 130, 110, 3, 90, 300, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.PSYCHIC, 1.8, 52, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 700, 80, 100, 120, 140, 150, 110, 3, 90, 300) + ), + new PokemonSpecies(SpeciesId.LATIOS, 3, true, false, false, "Eon Pokémon", PokemonType.DRAGON, PokemonType.PSYCHIC, 2, 60, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 600, 80, 90, 80, 130, 110, 110, 3, 90, 300, GrowthRate.SLOW, 100, false, true, + new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.PSYCHIC, 2, 60, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 600, 80, 90, 80, 130, 110, 110, 3, 90, 300, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.PSYCHIC, 2.3, 70, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 700, 80, 130, 100, 160, 120, 110, 3, 90, 300) + ), + new PokemonSpecies(SpeciesId.KYOGRE, 3, false, true, false, "Sea Basin Pokémon", PokemonType.WATER, null, 4.5, 352, AbilityId.DRIZZLE, AbilityId.NONE, AbilityId.NONE, 670, 100, 100, 90, 150, 140, 90, 3, 0, 335, GrowthRate.SLOW, null, false, true, + new PokemonForm("Normal", "", PokemonType.WATER, null, 4.5, 352, AbilityId.DRIZZLE, AbilityId.NONE, AbilityId.NONE, 670, 100, 100, 90, 150, 140, 90, 3, 0, 335, false, null, true), + new PokemonForm("Primal", "primal", PokemonType.WATER, null, 9.8, 430, AbilityId.PRIMORDIAL_SEA, AbilityId.NONE, AbilityId.NONE, 770, 100, 150, 90, 180, 160, 90, 3, 0, 335) + ), + new PokemonSpecies(SpeciesId.GROUDON, 3, false, true, false, "Continent Pokémon", PokemonType.GROUND, null, 3.5, 950, AbilityId.DROUGHT, AbilityId.NONE, AbilityId.NONE, 670, 100, 150, 140, 100, 90, 90, 3, 0, 335, GrowthRate.SLOW, null, false, true, + new PokemonForm("Normal", "", PokemonType.GROUND, null, 3.5, 950, AbilityId.DROUGHT, AbilityId.NONE, AbilityId.NONE, 670, 100, 150, 140, 100, 90, 90, 3, 0, 335, false, null, true), + new PokemonForm("Primal", "primal", PokemonType.GROUND, PokemonType.FIRE, 5, 999.7, AbilityId.DESOLATE_LAND, AbilityId.NONE, AbilityId.NONE, 770, 100, 180, 160, 150, 90, 90, 3, 0, 335) + ), + new PokemonSpecies(SpeciesId.RAYQUAZA, 3, false, true, false, "Sky High Pokémon", PokemonType.DRAGON, PokemonType.FLYING, 7, 206.5, AbilityId.AIR_LOCK, AbilityId.NONE, AbilityId.NONE, 680, 105, 150, 90, 150, 90, 95, 3, 0, 340, GrowthRate.SLOW, null, false, true, + new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.FLYING, 7, 206.5, AbilityId.AIR_LOCK, AbilityId.NONE, AbilityId.NONE, 680, 105, 150, 90, 150, 90, 95, 3, 0, 340, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.FLYING, 10.8, 392, AbilityId.DELTA_STREAM, AbilityId.NONE, AbilityId.NONE, 780, 105, 180, 100, 180, 100, 115, 3, 0, 340) + ), + new PokemonSpecies(SpeciesId.JIRACHI, 3, false, false, true, "Wish Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 0.3, 1.1, AbilityId.SERENE_GRACE, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 3, 100, 300, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.DEOXYS, 3, false, false, true, "DNA Pokémon", PokemonType.PSYCHIC, null, 1.7, 60.8, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 600, 50, 150, 50, 150, 50, 150, 3, 0, 300, GrowthRate.SLOW, null, false, true, + new PokemonForm("Normal Forme", "normal", PokemonType.PSYCHIC, null, 1.7, 60.8, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 600, 50, 150, 50, 150, 50, 150, 3, 0, 300, false, "", true), + new PokemonForm("Attack Forme", "attack", PokemonType.PSYCHIC, null, 1.7, 60.8, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 600, 50, 180, 20, 180, 20, 150, 3, 0, 300), + new PokemonForm("Defense Forme", "defense", PokemonType.PSYCHIC, null, 1.7, 60.8, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 600, 50, 70, 160, 70, 160, 90, 3, 0, 300), + new PokemonForm("Speed Forme", "speed", PokemonType.PSYCHIC, null, 1.7, 60.8, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 600, 50, 95, 90, 95, 90, 180, 3, 0, 300) + ), + new PokemonSpecies(SpeciesId.TURTWIG, 4, false, false, false, "Tiny Leaf Pokémon", PokemonType.GRASS, null, 0.4, 10.2, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.SHELL_ARMOR, 318, 55, 68, 64, 45, 55, 31, 45, 70, 64, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.GROTLE, 4, false, false, false, "Grove Pokémon", PokemonType.GRASS, null, 1.1, 97, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.SHELL_ARMOR, 405, 75, 89, 85, 55, 65, 36, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.TORTERRA, 4, false, false, false, "Continent Pokémon", PokemonType.GRASS, PokemonType.GROUND, 2.2, 310, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.SHELL_ARMOR, 525, 95, 109, 105, 75, 85, 56, 45, 70, 263, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.CHIMCHAR, 4, false, false, false, "Chimp Pokémon", PokemonType.FIRE, null, 0.5, 6.2, AbilityId.BLAZE, AbilityId.NONE, AbilityId.IRON_FIST, 309, 44, 58, 44, 58, 44, 61, 45, 70, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.MONFERNO, 4, false, false, false, "Playful Pokémon", PokemonType.FIRE, PokemonType.FIGHTING, 0.9, 22, AbilityId.BLAZE, AbilityId.NONE, AbilityId.IRON_FIST, 405, 64, 78, 52, 78, 52, 81, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.INFERNAPE, 4, false, false, false, "Flame Pokémon", PokemonType.FIRE, PokemonType.FIGHTING, 1.2, 55, AbilityId.BLAZE, AbilityId.NONE, AbilityId.IRON_FIST, 534, 76, 104, 71, 104, 71, 108, 45, 70, 267, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.PIPLUP, 4, false, false, false, "Penguin Pokémon", PokemonType.WATER, null, 0.4, 5.2, AbilityId.TORRENT, AbilityId.NONE, AbilityId.COMPETITIVE, 314, 53, 51, 53, 61, 56, 40, 45, 70, 63, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.PRINPLUP, 4, false, false, false, "Penguin Pokémon", PokemonType.WATER, null, 0.8, 23, AbilityId.TORRENT, AbilityId.NONE, AbilityId.COMPETITIVE, 405, 64, 66, 68, 81, 76, 50, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.EMPOLEON, 4, false, false, false, "Emperor Pokémon", PokemonType.WATER, PokemonType.STEEL, 1.7, 84.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.COMPETITIVE, 530, 84, 86, 88, 111, 101, 60, 45, 70, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.STARLY, 4, false, false, false, "Starling Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 2, AbilityId.KEEN_EYE, AbilityId.NONE, AbilityId.RECKLESS, 245, 40, 55, 30, 30, 30, 60, 255, 70, 49, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.STARAVIA, 4, false, false, false, "Starling Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 15.5, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.RECKLESS, 340, 55, 75, 50, 40, 40, 80, 120, 70, 119, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.STARAPTOR, 4, false, false, false, "Predator Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.2, 24.9, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.RECKLESS, 485, 85, 120, 70, 50, 60, 100, 45, 70, 243, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.BIDOOF, 4, false, false, false, "Plump Mouse Pokémon", PokemonType.NORMAL, null, 0.5, 20, AbilityId.SIMPLE, AbilityId.UNAWARE, AbilityId.MOODY, 250, 59, 45, 40, 35, 40, 31, 255, 70, 50, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.BIBAREL, 4, false, false, false, "Beaver Pokémon", PokemonType.NORMAL, PokemonType.WATER, 1, 31.5, AbilityId.SIMPLE, AbilityId.UNAWARE, AbilityId.MOODY, 410, 79, 85, 60, 55, 60, 71, 127, 70, 144, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.KRICKETOT, 4, false, false, false, "Cricket Pokémon", PokemonType.BUG, null, 0.3, 2.2, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.RUN_AWAY, 194, 37, 25, 41, 25, 41, 25, 255, 70, 39, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.KRICKETUNE, 4, false, false, false, "Cricket Pokémon", PokemonType.BUG, null, 1, 25.5, AbilityId.SWARM, AbilityId.NONE, AbilityId.TECHNICIAN, 384, 77, 85, 51, 55, 51, 65, 45, 70, 134, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.SHINX, 4, false, false, false, "Flash Pokémon", PokemonType.ELECTRIC, null, 0.5, 9.5, AbilityId.RIVALRY, AbilityId.INTIMIDATE, AbilityId.GUTS, 263, 45, 65, 34, 40, 34, 45, 235, 50, 53, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.LUXIO, 4, false, false, false, "Spark Pokémon", PokemonType.ELECTRIC, null, 0.9, 30.5, AbilityId.RIVALRY, AbilityId.INTIMIDATE, AbilityId.GUTS, 363, 60, 85, 49, 60, 49, 60, 120, 100, 127, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.LUXRAY, 4, false, false, false, "Gleam Eyes Pokémon", PokemonType.ELECTRIC, null, 1.4, 42, AbilityId.RIVALRY, AbilityId.INTIMIDATE, AbilityId.GUTS, 523, 80, 120, 79, 95, 79, 70, 45, 50, 262, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.BUDEW, 4, false, false, false, "Bud Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.2, 1.2, AbilityId.NATURAL_CURE, AbilityId.POISON_POINT, AbilityId.LEAF_GUARD, 280, 40, 30, 35, 50, 70, 55, 255, 50, 56, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.ROSERADE, 4, false, false, false, "Bouquet Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.9, 14.5, AbilityId.NATURAL_CURE, AbilityId.POISON_POINT, AbilityId.TECHNICIAN, 515, 60, 70, 65, 125, 105, 90, 75, 50, 258, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.CRANIDOS, 4, false, false, false, "Head Butt Pokémon", PokemonType.ROCK, null, 0.9, 31.5, AbilityId.MOLD_BREAKER, AbilityId.NONE, AbilityId.SHEER_FORCE, 350, 67, 125, 40, 30, 30, 58, 45, 70, 70, GrowthRate.ERRATIC, 87.5, false), + new PokemonSpecies(SpeciesId.RAMPARDOS, 4, false, false, false, "Head Butt Pokémon", PokemonType.ROCK, null, 1.6, 102.5, AbilityId.MOLD_BREAKER, AbilityId.NONE, AbilityId.SHEER_FORCE, 495, 97, 165, 60, 65, 50, 58, 45, 70, 173, GrowthRate.ERRATIC, 87.5, false), + new PokemonSpecies(SpeciesId.SHIELDON, 4, false, false, false, "Shield Pokémon", PokemonType.ROCK, PokemonType.STEEL, 0.5, 57, AbilityId.STURDY, AbilityId.NONE, AbilityId.SOUNDPROOF, 350, 30, 42, 118, 42, 88, 30, 45, 70, 70, GrowthRate.ERRATIC, 87.5, false), + new PokemonSpecies(SpeciesId.BASTIODON, 4, false, false, false, "Shield Pokémon", PokemonType.ROCK, PokemonType.STEEL, 1.3, 149.5, AbilityId.STURDY, AbilityId.NONE, AbilityId.SOUNDPROOF, 495, 60, 52, 168, 47, 138, 30, 45, 70, 173, GrowthRate.ERRATIC, 87.5, false), + new PokemonSpecies(SpeciesId.BURMY, 4, false, false, false, "Bagworm Pokémon", PokemonType.BUG, null, 0.2, 3.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.OVERCOAT, 224, 40, 29, 45, 29, 45, 36, 120, 70, 45, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Plant Cloak", "plant", PokemonType.BUG, null, 0.2, 3.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.OVERCOAT, 224, 40, 29, 45, 29, 45, 36, 120, 70, 45, false, null, true), + new PokemonForm("Sandy Cloak", "sandy", PokemonType.BUG, null, 0.2, 3.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.OVERCOAT, 224, 40, 29, 45, 29, 45, 36, 120, 70, 45, false, null, true), + new PokemonForm("Trash Cloak", "trash", PokemonType.BUG, null, 0.2, 3.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.OVERCOAT, 224, 40, 29, 45, 29, 45, 36, 120, 70, 45, false, null, true) + ), + new PokemonSpecies(SpeciesId.WORMADAM, 4, false, false, false, "Bagworm Pokémon", PokemonType.BUG, PokemonType.GRASS, 0.5, 6.5, AbilityId.ANTICIPATION, AbilityId.NONE, AbilityId.OVERCOAT, 424, 60, 59, 85, 79, 105, 36, 45, 70, 148, GrowthRate.MEDIUM_FAST, 0, false, false, + new PokemonForm("Plant Cloak", "plant", PokemonType.BUG, PokemonType.GRASS, 0.5, 6.5, AbilityId.ANTICIPATION, AbilityId.NONE, AbilityId.OVERCOAT, 424, 60, 59, 85, 79, 105, 36, 45, 70, 148, false, null, true), + new PokemonForm("Sandy Cloak", "sandy", PokemonType.BUG, PokemonType.GROUND, 0.5, 6.5, AbilityId.ANTICIPATION, AbilityId.NONE, AbilityId.OVERCOAT, 424, 60, 79, 105, 59, 85, 36, 45, 70, 148, false, null, true), + new PokemonForm("Trash Cloak", "trash", PokemonType.BUG, PokemonType.STEEL, 0.5, 6.5, AbilityId.ANTICIPATION, AbilityId.NONE, AbilityId.OVERCOAT, 424, 60, 69, 95, 69, 95, 36, 45, 70, 148, false, null, true) + ), + new PokemonSpecies(SpeciesId.MOTHIM, 4, false, false, false, "Moth Pokémon", PokemonType.BUG, PokemonType.FLYING, 0.9, 23.3, AbilityId.SWARM, AbilityId.NONE, AbilityId.TINTED_LENS, 424, 70, 94, 50, 94, 50, 66, 45, 70, 148, GrowthRate.MEDIUM_FAST, 100, false), + new PokemonSpecies(SpeciesId.COMBEE, 4, false, false, false, "Tiny Bee Pokémon", PokemonType.BUG, PokemonType.FLYING, 0.3, 5.5, AbilityId.HONEY_GATHER, AbilityId.NONE, AbilityId.HUSTLE, 244, 30, 30, 42, 30, 42, 70, 120, 50, 49, GrowthRate.MEDIUM_SLOW, 87.5, true), + new PokemonSpecies(SpeciesId.VESPIQUEN, 4, false, false, false, "Beehive Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.2, 38.5, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.UNNERVE, 474, 70, 80, 102, 80, 102, 40, 45, 50, 166, GrowthRate.MEDIUM_SLOW, 0, false), + new PokemonSpecies(SpeciesId.PACHIRISU, 4, false, false, false, "EleSquirrel Pokémon", PokemonType.ELECTRIC, null, 0.4, 3.9, AbilityId.RUN_AWAY, AbilityId.PICKUP, AbilityId.VOLT_ABSORB, 405, 60, 45, 70, 45, 90, 95, 200, 100, 142, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.BUIZEL, 4, false, false, false, "Sea Weasel Pokémon", PokemonType.WATER, null, 0.7, 29.5, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.WATER_VEIL, 330, 55, 65, 35, 60, 30, 85, 190, 70, 66, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.FLOATZEL, 4, false, false, false, "Sea Weasel Pokémon", PokemonType.WATER, null, 1.1, 33.5, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.WATER_VEIL, 495, 85, 105, 55, 85, 50, 115, 75, 70, 173, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.CHERUBI, 4, false, false, false, "Cherry Pokémon", PokemonType.GRASS, null, 0.4, 3.3, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.NONE, 275, 45, 35, 45, 62, 53, 35, 190, 50, 55, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CHERRIM, 4, false, false, false, "Blossom Pokémon", PokemonType.GRASS, null, 0.5, 9.3, AbilityId.FLOWER_GIFT, AbilityId.NONE, AbilityId.NONE, 450, 70, 60, 70, 87, 78, 85, 75, 50, 158, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Overcast Form", "overcast", PokemonType.GRASS, null, 0.5, 9.3, AbilityId.FLOWER_GIFT, AbilityId.NONE, AbilityId.NONE, 450, 70, 60, 70, 87, 78, 85, 75, 50, 158, false, null, true), + new PokemonForm("Sunshine Form", "sunshine", PokemonType.GRASS, null, 0.5, 9.3, AbilityId.FLOWER_GIFT, AbilityId.NONE, AbilityId.NONE, 450, 70, 60, 70, 87, 78, 85, 75, 50, 158) + ), + new PokemonSpecies(SpeciesId.SHELLOS, 4, false, false, false, "Sea Slug Pokémon", PokemonType.WATER, null, 0.3, 6.3, AbilityId.STICKY_HOLD, AbilityId.STORM_DRAIN, AbilityId.SAND_FORCE, 325, 76, 48, 48, 57, 62, 34, 190, 50, 65, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("East Sea", "east", PokemonType.WATER, null, 0.3, 6.3, AbilityId.STICKY_HOLD, AbilityId.STORM_DRAIN, AbilityId.SAND_FORCE, 325, 76, 48, 48, 57, 62, 34, 190, 50, 65, false, null, true), + new PokemonForm("West Sea", "west", PokemonType.WATER, null, 0.3, 6.3, AbilityId.STICKY_HOLD, AbilityId.STORM_DRAIN, AbilityId.SAND_FORCE, 325, 76, 48, 48, 57, 62, 34, 190, 50, 65, false, null, true) + ), + new PokemonSpecies(SpeciesId.GASTRODON, 4, false, false, false, "Sea Slug Pokémon", PokemonType.WATER, PokemonType.GROUND, 0.9, 29.9, AbilityId.STICKY_HOLD, AbilityId.STORM_DRAIN, AbilityId.SAND_FORCE, 475, 111, 83, 68, 92, 82, 39, 75, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("East Sea", "east", PokemonType.WATER, PokemonType.GROUND, 0.9, 29.9, AbilityId.STICKY_HOLD, AbilityId.STORM_DRAIN, AbilityId.SAND_FORCE, 475, 111, 83, 68, 92, 82, 39, 75, 50, 166, false, null, true), + new PokemonForm("West Sea", "west", PokemonType.WATER, PokemonType.GROUND, 0.9, 29.9, AbilityId.STICKY_HOLD, AbilityId.STORM_DRAIN, AbilityId.SAND_FORCE, 475, 111, 83, 68, 92, 82, 39, 75, 50, 166, false, null, true) + ), + new PokemonSpecies(SpeciesId.AMBIPOM, 4, false, false, false, "Long Tail Pokémon", PokemonType.NORMAL, null, 1.2, 20.3, AbilityId.TECHNICIAN, AbilityId.PICKUP, AbilityId.SKILL_LINK, 482, 75, 100, 66, 60, 66, 115, 45, 100, 169, GrowthRate.FAST, 50, true), + new PokemonSpecies(SpeciesId.DRIFLOON, 4, false, false, false, "Balloon Pokémon", PokemonType.GHOST, PokemonType.FLYING, 0.4, 1.2, AbilityId.AFTERMATH, AbilityId.UNBURDEN, AbilityId.FLARE_BOOST, 348, 90, 50, 34, 60, 44, 70, 125, 50, 70, GrowthRate.FLUCTUATING, 50, false), + new PokemonSpecies(SpeciesId.DRIFBLIM, 4, false, false, false, "Blimp Pokémon", PokemonType.GHOST, PokemonType.FLYING, 1.2, 15, AbilityId.AFTERMATH, AbilityId.UNBURDEN, AbilityId.FLARE_BOOST, 498, 150, 80, 44, 90, 54, 80, 60, 50, 174, GrowthRate.FLUCTUATING, 50, false), + new PokemonSpecies(SpeciesId.BUNEARY, 4, false, false, false, "Rabbit Pokémon", PokemonType.NORMAL, null, 0.4, 5.5, AbilityId.RUN_AWAY, AbilityId.KLUTZ, AbilityId.LIMBER, 350, 55, 66, 44, 44, 56, 85, 190, 0, 70, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.LOPUNNY, 4, false, false, false, "Rabbit Pokémon", PokemonType.NORMAL, null, 1.2, 33.3, AbilityId.CUTE_CHARM, AbilityId.KLUTZ, AbilityId.LIMBER, 480, 65, 76, 84, 54, 96, 105, 60, 140, 168, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.NORMAL, null, 1.2, 33.3, AbilityId.CUTE_CHARM, AbilityId.KLUTZ, AbilityId.LIMBER, 480, 65, 76, 84, 54, 96, 105, 60, 140, 168, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.NORMAL, PokemonType.FIGHTING, 1.3, 28.3, AbilityId.SCRAPPY, AbilityId.SCRAPPY, AbilityId.SCRAPPY, 580, 65, 136, 94, 54, 96, 135, 60, 140, 168) + ), + new PokemonSpecies(SpeciesId.MISMAGIUS, 4, false, false, false, "Magical Pokémon", PokemonType.GHOST, null, 0.9, 4.4, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 495, 60, 60, 60, 105, 105, 105, 45, 35, 173, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.HONCHKROW, 4, false, false, false, "Big Boss Pokémon", PokemonType.DARK, PokemonType.FLYING, 0.9, 27.3, AbilityId.INSOMNIA, AbilityId.SUPER_LUCK, AbilityId.MOXIE, 505, 100, 125, 52, 105, 52, 71, 30, 35, 177, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.GLAMEOW, 4, false, false, false, "Catty Pokémon", PokemonType.NORMAL, null, 0.5, 3.9, AbilityId.LIMBER, AbilityId.OWN_TEMPO, AbilityId.KEEN_EYE, 310, 49, 55, 42, 42, 37, 85, 190, 70, 62, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.PURUGLY, 4, false, false, false, "Tiger Cat Pokémon", PokemonType.NORMAL, null, 1, 43.8, AbilityId.THICK_FAT, AbilityId.OWN_TEMPO, AbilityId.DEFIANT, 452, 71, 82, 64, 64, 59, 112, 75, 70, 158, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.CHINGLING, 4, false, false, false, "Bell Pokémon", PokemonType.PSYCHIC, null, 0.2, 0.6, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 285, 45, 30, 50, 65, 50, 45, 120, 70, 57, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.STUNKY, 4, false, false, false, "Skunk Pokémon", PokemonType.POISON, PokemonType.DARK, 0.4, 19.2, AbilityId.STENCH, AbilityId.AFTERMATH, AbilityId.KEEN_EYE, 329, 63, 63, 47, 41, 41, 74, 225, 50, 66, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SKUNTANK, 4, false, false, false, "Skunk Pokémon", PokemonType.POISON, PokemonType.DARK, 1, 38, AbilityId.STENCH, AbilityId.AFTERMATH, AbilityId.KEEN_EYE, 479, 103, 93, 67, 71, 61, 84, 60, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BRONZOR, 4, false, false, false, "Bronze Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 0.5, 60.5, AbilityId.LEVITATE, AbilityId.HEATPROOF, AbilityId.HEAVY_METAL, 300, 57, 24, 86, 24, 86, 23, 255, 50, 60, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.BRONZONG, 4, false, false, false, "Bronze Bell Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 1.3, 187, AbilityId.LEVITATE, AbilityId.HEATPROOF, AbilityId.HEAVY_METAL, 500, 67, 89, 116, 79, 116, 33, 90, 50, 175, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.BONSLY, 4, false, false, false, "Bonsai Pokémon", PokemonType.ROCK, null, 0.5, 15, AbilityId.STURDY, AbilityId.ROCK_HEAD, AbilityId.RATTLED, 290, 50, 80, 95, 10, 45, 10, 255, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MIME_JR, 4, false, false, false, "Mime Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 0.6, 13, AbilityId.SOUNDPROOF, AbilityId.FILTER, AbilityId.TECHNICIAN, 310, 20, 25, 45, 70, 90, 60, 145, 50, 62, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.HAPPINY, 4, false, false, false, "Playhouse Pokémon", PokemonType.NORMAL, null, 0.6, 24.4, AbilityId.NATURAL_CURE, AbilityId.SERENE_GRACE, AbilityId.FRIEND_GUARD, 220, 100, 5, 5, 15, 65, 30, 130, 140, 110, GrowthRate.FAST, 0, false), + new PokemonSpecies(SpeciesId.CHATOT, 4, false, false, false, "Music Note Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.5, 1.9, AbilityId.KEEN_EYE, AbilityId.TANGLED_FEET, AbilityId.BIG_PECKS, 411, 76, 65, 45, 92, 42, 91, 30, 35, 144, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SPIRITOMB, 4, false, false, false, "Forbidden Pokémon", PokemonType.GHOST, PokemonType.DARK, 1, 108, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.INFILTRATOR, 485, 50, 92, 108, 92, 108, 35, 100, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GIBLE, 4, false, false, false, "Land Shark Pokémon", PokemonType.DRAGON, PokemonType.GROUND, 0.7, 20.5, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.ROUGH_SKIN, 300, 58, 70, 45, 40, 45, 42, 45, 50, 60, GrowthRate.SLOW, 50, true), + new PokemonSpecies(SpeciesId.GABITE, 4, false, false, false, "Cave Pokémon", PokemonType.DRAGON, PokemonType.GROUND, 1.4, 56, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.ROUGH_SKIN, 410, 68, 90, 65, 50, 55, 82, 45, 50, 144, GrowthRate.SLOW, 50, true), + new PokemonSpecies(SpeciesId.GARCHOMP, 4, false, false, false, "Mach Pokémon", PokemonType.DRAGON, PokemonType.GROUND, 1.9, 95, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.ROUGH_SKIN, 600, 108, 130, 95, 80, 85, 102, 45, 50, 300, GrowthRate.SLOW, 50, true, true, + new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.GROUND, 1.9, 95, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.ROUGH_SKIN, 600, 108, 130, 95, 80, 85, 102, 45, 50, 300, true, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.GROUND, 1.9, 95, AbilityId.SAND_FORCE, AbilityId.NONE, AbilityId.SAND_FORCE, 700, 108, 170, 115, 120, 95, 92, 45, 50, 300, true) + ), + new PokemonSpecies(SpeciesId.MUNCHLAX, 4, false, false, false, "Big Eater Pokémon", PokemonType.NORMAL, null, 0.6, 105, AbilityId.PICKUP, AbilityId.THICK_FAT, AbilityId.GLUTTONY, 390, 135, 85, 40, 40, 85, 5, 50, 50, 78, GrowthRate.SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.RIOLU, 4, false, false, false, "Emanation Pokémon", PokemonType.FIGHTING, null, 0.7, 20.2, AbilityId.STEADFAST, AbilityId.INNER_FOCUS, AbilityId.PRANKSTER, 285, 40, 70, 40, 35, 40, 60, 75, 50, 57, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.LUCARIO, 4, false, false, false, "Aura Pokémon", PokemonType.FIGHTING, PokemonType.STEEL, 1.2, 54, AbilityId.STEADFAST, AbilityId.INNER_FOCUS, AbilityId.JUSTIFIED, 525, 70, 110, 70, 115, 70, 90, 45, 50, 184, GrowthRate.MEDIUM_SLOW, 87.5, false, true, + new PokemonForm("Normal", "", PokemonType.FIGHTING, PokemonType.STEEL, 1.2, 54, AbilityId.STEADFAST, AbilityId.INNER_FOCUS, AbilityId.JUSTIFIED, 525, 70, 110, 70, 115, 70, 90, 45, 50, 184, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.FIGHTING, PokemonType.STEEL, 1.3, 57.5, AbilityId.ADAPTABILITY, AbilityId.ADAPTABILITY, AbilityId.ADAPTABILITY, 625, 70, 145, 88, 140, 70, 112, 45, 50, 184) + ), + new PokemonSpecies(SpeciesId.HIPPOPOTAS, 4, false, false, false, "Hippo Pokémon", PokemonType.GROUND, null, 0.8, 49.5, AbilityId.SAND_STREAM, AbilityId.NONE, AbilityId.SAND_FORCE, 330, 68, 72, 78, 38, 42, 32, 140, 50, 66, GrowthRate.SLOW, 50, true), + new PokemonSpecies(SpeciesId.HIPPOWDON, 4, false, false, false, "Heavyweight Pokémon", PokemonType.GROUND, null, 2, 300, AbilityId.SAND_STREAM, AbilityId.NONE, AbilityId.SAND_FORCE, 525, 108, 112, 118, 68, 72, 47, 60, 50, 184, GrowthRate.SLOW, 50, true), + new PokemonSpecies(SpeciesId.SKORUPI, 4, false, false, false, "Scorpion Pokémon", PokemonType.POISON, PokemonType.BUG, 0.8, 12, AbilityId.BATTLE_ARMOR, AbilityId.SNIPER, AbilityId.KEEN_EYE, 330, 40, 50, 90, 30, 55, 65, 120, 50, 66, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.DRAPION, 4, false, false, false, "Ogre Scorpion Pokémon", PokemonType.POISON, PokemonType.DARK, 1.3, 61.5, AbilityId.BATTLE_ARMOR, AbilityId.SNIPER, AbilityId.KEEN_EYE, 500, 70, 90, 110, 60, 75, 95, 45, 50, 175, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.CROAGUNK, 4, false, false, false, "Toxic Mouth Pokémon", PokemonType.POISON, PokemonType.FIGHTING, 0.7, 23, AbilityId.ANTICIPATION, AbilityId.DRY_SKIN, AbilityId.POISON_TOUCH, 300, 48, 61, 40, 61, 40, 50, 140, 100, 60, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.TOXICROAK, 4, false, false, false, "Toxic Mouth Pokémon", PokemonType.POISON, PokemonType.FIGHTING, 1.3, 44.4, AbilityId.ANTICIPATION, AbilityId.DRY_SKIN, AbilityId.POISON_TOUCH, 490, 83, 106, 65, 86, 65, 85, 75, 50, 172, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.CARNIVINE, 4, false, false, false, "Bug Catcher Pokémon", PokemonType.GRASS, null, 1.4, 27, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 454, 74, 100, 72, 90, 72, 46, 200, 70, 159, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.FINNEON, 4, false, false, false, "Wing Fish Pokémon", PokemonType.WATER, null, 0.4, 7, AbilityId.SWIFT_SWIM, AbilityId.STORM_DRAIN, AbilityId.WATER_VEIL, 330, 49, 49, 56, 49, 61, 66, 190, 70, 66, GrowthRate.ERRATIC, 50, true), + new PokemonSpecies(SpeciesId.LUMINEON, 4, false, false, false, "Neon Pokémon", PokemonType.WATER, null, 1.2, 24, AbilityId.SWIFT_SWIM, AbilityId.STORM_DRAIN, AbilityId.WATER_VEIL, 460, 69, 69, 76, 69, 86, 91, 75, 70, 161, GrowthRate.ERRATIC, 50, true), + new PokemonSpecies(SpeciesId.MANTYKE, 4, false, false, false, "Kite Pokémon", PokemonType.WATER, PokemonType.FLYING, 1, 65, AbilityId.SWIFT_SWIM, AbilityId.WATER_ABSORB, AbilityId.WATER_VEIL, 345, 45, 20, 50, 60, 120, 50, 25, 50, 69, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.SNOVER, 4, false, false, false, "Frost Tree Pokémon", PokemonType.GRASS, PokemonType.ICE, 1, 50.5, AbilityId.SNOW_WARNING, AbilityId.NONE, AbilityId.SOUNDPROOF, 334, 60, 62, 50, 62, 60, 40, 120, 50, 67, GrowthRate.SLOW, 50, true), + new PokemonSpecies(SpeciesId.ABOMASNOW, 4, false, false, false, "Frost Tree Pokémon", PokemonType.GRASS, PokemonType.ICE, 2.2, 135.5, AbilityId.SNOW_WARNING, AbilityId.NONE, AbilityId.SOUNDPROOF, 494, 90, 92, 75, 92, 85, 60, 60, 50, 173, GrowthRate.SLOW, 50, true, true, + new PokemonForm("Normal", "", PokemonType.GRASS, PokemonType.ICE, 2.2, 135.5, AbilityId.SNOW_WARNING, AbilityId.NONE, AbilityId.SOUNDPROOF, 494, 90, 92, 75, 92, 85, 60, 60, 50, 173, true, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.GRASS, PokemonType.ICE, 2.7, 185, AbilityId.SNOW_WARNING, AbilityId.NONE, AbilityId.SNOW_WARNING, 594, 90, 132, 105, 132, 105, 30, 60, 50, 173, true) + ), + new PokemonSpecies(SpeciesId.WEAVILE, 4, false, false, false, "Sharp Claw Pokémon", PokemonType.DARK, PokemonType.ICE, 1.1, 34, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.PICKPOCKET, 510, 70, 120, 65, 45, 85, 125, 45, 35, 179, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.MAGNEZONE, 4, false, false, false, "Magnet Area Pokémon", PokemonType.ELECTRIC, PokemonType.STEEL, 1.2, 180, AbilityId.MAGNET_PULL, AbilityId.STURDY, AbilityId.ANALYTIC, 535, 70, 70, 115, 130, 90, 60, 30, 50, 268, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.LICKILICKY, 4, false, false, false, "Licking Pokémon", PokemonType.NORMAL, null, 1.7, 140, AbilityId.OWN_TEMPO, AbilityId.OBLIVIOUS, AbilityId.CLOUD_NINE, 515, 110, 85, 95, 80, 95, 50, 30, 50, 180, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.RHYPERIOR, 4, false, false, false, "Drill Pokémon", PokemonType.GROUND, PokemonType.ROCK, 2.4, 282.8, AbilityId.LIGHTNING_ROD, AbilityId.SOLID_ROCK, AbilityId.RECKLESS, 535, 115, 140, 130, 55, 55, 40, 30, 50, 268, GrowthRate.SLOW, 50, true), + new PokemonSpecies(SpeciesId.TANGROWTH, 4, false, false, false, "Vine Pokémon", PokemonType.GRASS, null, 2, 128.6, AbilityId.CHLOROPHYLL, AbilityId.LEAF_GUARD, AbilityId.REGENERATOR, 535, 100, 100, 125, 110, 50, 50, 30, 50, 187, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.ELECTIVIRE, 4, false, false, false, "Thunderbolt Pokémon", PokemonType.ELECTRIC, null, 1.8, 138.6, AbilityId.MOTOR_DRIVE, AbilityId.NONE, AbilityId.VITAL_SPIRIT, 540, 75, 123, 67, 95, 85, 95, 30, 50, 270, GrowthRate.MEDIUM_FAST, 75, false), + new PokemonSpecies(SpeciesId.MAGMORTAR, 4, false, false, false, "Blast Pokémon", PokemonType.FIRE, null, 1.6, 68, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.VITAL_SPIRIT, 540, 75, 95, 67, 125, 95, 83, 30, 50, 270, GrowthRate.MEDIUM_FAST, 75, false), + new PokemonSpecies(SpeciesId.TOGEKISS, 4, false, false, false, "Jubilee Pokémon", PokemonType.FAIRY, PokemonType.FLYING, 1.5, 38, AbilityId.HUSTLE, AbilityId.SERENE_GRACE, AbilityId.SUPER_LUCK, 545, 85, 50, 95, 120, 115, 80, 30, 50, 273, GrowthRate.FAST, 87.5, false), + new PokemonSpecies(SpeciesId.YANMEGA, 4, false, false, false, "Ogre Darner Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.9, 51.5, AbilityId.SPEED_BOOST, AbilityId.TINTED_LENS, AbilityId.FRISK, 515, 86, 76, 86, 116, 56, 95, 30, 70, 180, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.LEAFEON, 4, false, false, false, "Verdant Pokémon", PokemonType.GRASS, null, 1, 25.5, AbilityId.LEAF_GUARD, AbilityId.NONE, AbilityId.CHLOROPHYLL, 525, 65, 110, 130, 60, 65, 95, 45, 35, 184, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.GLACEON, 4, false, false, false, "Fresh Snow Pokémon", PokemonType.ICE, null, 0.8, 25.9, AbilityId.SNOW_CLOAK, AbilityId.NONE, AbilityId.ICE_BODY, 525, 65, 60, 110, 130, 95, 65, 45, 35, 184, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.GLISCOR, 4, false, false, false, "Fang Scorpion Pokémon", PokemonType.GROUND, PokemonType.FLYING, 2, 42.5, AbilityId.HYPER_CUTTER, AbilityId.SAND_VEIL, AbilityId.POISON_HEAL, 510, 75, 95, 125, 45, 75, 95, 30, 70, 179, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.MAMOSWINE, 4, false, false, false, "Twin Tusk Pokémon", PokemonType.ICE, PokemonType.GROUND, 2.5, 291, AbilityId.OBLIVIOUS, AbilityId.SNOW_CLOAK, AbilityId.THICK_FAT, 530, 110, 130, 80, 70, 60, 80, 50, 50, 265, GrowthRate.SLOW, 50, true), + new PokemonSpecies(SpeciesId.PORYGON_Z, 4, false, false, false, "Virtual Pokémon", PokemonType.NORMAL, null, 0.9, 34, AbilityId.ADAPTABILITY, AbilityId.DOWNLOAD, AbilityId.ANALYTIC, 535, 85, 80, 70, 135, 75, 90, 30, 50, 268, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.GALLADE, 4, false, false, false, "Blade Pokémon", PokemonType.PSYCHIC, PokemonType.FIGHTING, 1.6, 52, AbilityId.STEADFAST, AbilityId.SHARPNESS, AbilityId.JUSTIFIED, 518, 68, 125, 65, 65, 115, 80, 45, 35, 259, GrowthRate.SLOW, 100, false, true, + new PokemonForm("Normal", "", PokemonType.PSYCHIC, PokemonType.FIGHTING, 1.6, 52, AbilityId.STEADFAST, AbilityId.SHARPNESS, AbilityId.JUSTIFIED, 518, 68, 125, 65, 65, 115, 80, 45, 35, 259, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.PSYCHIC, PokemonType.FIGHTING, 1.6, 56.4, AbilityId.INNER_FOCUS, AbilityId.INNER_FOCUS, AbilityId.INNER_FOCUS, 618, 68, 165, 95, 65, 115, 110, 45, 35, 259) + ), + new PokemonSpecies(SpeciesId.PROBOPASS, 4, false, false, false, "Compass Pokémon", PokemonType.ROCK, PokemonType.STEEL, 1.4, 340, AbilityId.STURDY, AbilityId.MAGNET_PULL, AbilityId.SAND_FORCE, 525, 60, 55, 145, 75, 150, 40, 60, 70, 184, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DUSKNOIR, 4, false, false, false, "Gripper Pokémon", PokemonType.GHOST, null, 2.2, 106.6, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.FRISK, 525, 45, 100, 135, 65, 135, 45, 45, 35, 263, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.FROSLASS, 4, false, false, false, "Snow Land Pokémon", PokemonType.ICE, PokemonType.GHOST, 1.3, 26.6, AbilityId.SNOW_CLOAK, AbilityId.NONE, AbilityId.CURSED_BODY, 480, 70, 80, 70, 80, 70, 110, 75, 50, 168, GrowthRate.MEDIUM_FAST, 0, false), + new PokemonSpecies(SpeciesId.ROTOM, 4, false, false, false, "Plasma Pokémon", PokemonType.ELECTRIC, PokemonType.GHOST, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 440, 50, 50, 77, 95, 77, 91, 45, 50, 154, GrowthRate.MEDIUM_FAST, null, false, false, + new PokemonForm("Normal", "", PokemonType.ELECTRIC, PokemonType.GHOST, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 440, 50, 50, 77, 95, 77, 91, 45, 50, 154, false, null, true), + new PokemonForm("Heat", "heat", PokemonType.ELECTRIC, PokemonType.FIRE, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 520, 50, 65, 107, 105, 107, 86, 45, 50, 182, false, null, true), + new PokemonForm("Wash", "wash", PokemonType.ELECTRIC, PokemonType.WATER, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 520, 50, 65, 107, 105, 107, 86, 45, 50, 182, false, null, true), + new PokemonForm("Frost", "frost", PokemonType.ELECTRIC, PokemonType.ICE, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 520, 50, 65, 107, 105, 107, 86, 45, 50, 182, false, null, true), + new PokemonForm("Fan", "fan", PokemonType.ELECTRIC, PokemonType.FLYING, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 520, 50, 65, 107, 105, 107, 86, 45, 50, 182, false, null, true), + new PokemonForm("Mow", "mow", PokemonType.ELECTRIC, PokemonType.GRASS, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 520, 50, 65, 107, 105, 107, 86, 45, 50, 182, false, null, true) + ), + new PokemonSpecies(SpeciesId.UXIE, 4, true, false, false, "Knowledge Pokémon", PokemonType.PSYCHIC, null, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 580, 75, 75, 130, 75, 130, 95, 3, 140, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.MESPRIT, 4, true, false, false, "Emotion Pokémon", PokemonType.PSYCHIC, null, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 580, 80, 105, 105, 105, 105, 80, 3, 140, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.AZELF, 4, true, false, false, "Willpower Pokémon", PokemonType.PSYCHIC, null, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 580, 75, 125, 70, 125, 70, 115, 3, 140, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.DIALGA, 4, false, true, false, "Temporal Pokémon", PokemonType.STEEL, PokemonType.DRAGON, 5.4, 683, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 100, 120, 120, 150, 100, 90, 3, 0, 340, GrowthRate.SLOW, null, false, false, + new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.DRAGON, 5.4, 683, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 100, 120, 120, 150, 100, 90, 3, 0, 340, false, null, true), + new PokemonForm("Origin Forme", "origin", PokemonType.STEEL, PokemonType.DRAGON, 7, 848.7, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 100, 100, 120, 150, 120, 90, 3, 0, 340) + ), + new PokemonSpecies(SpeciesId.PALKIA, 4, false, true, false, "Spatial Pokémon", PokemonType.WATER, PokemonType.DRAGON, 4.2, 336, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 90, 120, 100, 150, 120, 100, 3, 0, 340, GrowthRate.SLOW, null, false, false, + new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.DRAGON, 4.2, 336, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 90, 120, 100, 150, 120, 100, 3, 0, 340, false, null, true), + new PokemonForm("Origin Forme", "origin", PokemonType.WATER, PokemonType.DRAGON, 6.3, 659, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 90, 100, 100, 150, 120, 120, 3, 0, 340) + ), + new PokemonSpecies(SpeciesId.HEATRAN, 4, true, false, false, "Lava Dome Pokémon", PokemonType.FIRE, PokemonType.STEEL, 1.7, 430, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.FLAME_BODY, 600, 91, 90, 106, 130, 106, 77, 3, 100, 300, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.REGIGIGAS, 4, true, false, false, "Colossal Pokémon", PokemonType.NORMAL, null, 3.7, 420, AbilityId.SLOW_START, AbilityId.NONE, AbilityId.NORMALIZE, 670, 110, 160, 110, 80, 110, 100, 3, 0, 335, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.GIRATINA, 4, false, true, false, "Renegade Pokémon", PokemonType.GHOST, PokemonType.DRAGON, 4.5, 750, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 150, 100, 120, 100, 120, 90, 3, 0, 340, GrowthRate.SLOW, null, false, true, + new PokemonForm("Altered Forme", "altered", PokemonType.GHOST, PokemonType.DRAGON, 4.5, 750, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 150, 100, 120, 100, 120, 90, 3, 0, 340, false, null, true), + new PokemonForm("Origin Forme", "origin", PokemonType.GHOST, PokemonType.DRAGON, 6.9, 650, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.LEVITATE, 680, 150, 120, 100, 120, 100, 90, 3, 0, 340) + ), + new PokemonSpecies(SpeciesId.CRESSELIA, 4, true, false, false, "Lunar Pokémon", PokemonType.PSYCHIC, null, 1.5, 85.6, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 580, 120, 70, 110, 75, 120, 85, 3, 100, 300, GrowthRate.SLOW, 0, false), + new PokemonSpecies(SpeciesId.PHIONE, 4, false, false, true, "Sea Drifter Pokémon", PokemonType.WATER, null, 0.4, 3.1, AbilityId.HYDRATION, AbilityId.NONE, AbilityId.NONE, 480, 80, 80, 80, 80, 80, 80, 30, 70, 240, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.MANAPHY, 4, false, false, true, "Seafaring Pokémon", PokemonType.WATER, null, 0.3, 1.4, AbilityId.HYDRATION, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 3, 70, 300, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.DARKRAI, 4, false, false, true, "Pitch-Black Pokémon", PokemonType.DARK, null, 1.5, 50.5, AbilityId.BAD_DREAMS, AbilityId.NONE, AbilityId.NONE, 600, 70, 90, 90, 135, 90, 125, 3, 0, 300, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.SHAYMIN, 4, false, false, true, "Gratitude Pokémon", PokemonType.GRASS, null, 0.2, 2.1, AbilityId.NATURAL_CURE, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 45, 100, 300, GrowthRate.MEDIUM_SLOW, null, false, true, + new PokemonForm("Land Forme", "land", PokemonType.GRASS, null, 0.2, 2.1, AbilityId.NATURAL_CURE, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 45, 100, 300, false, null, true), + new PokemonForm("Sky Forme", "sky", PokemonType.GRASS, PokemonType.FLYING, 0.4, 5.2, AbilityId.SERENE_GRACE, AbilityId.NONE, AbilityId.NONE, 600, 100, 103, 75, 120, 75, 127, 45, 100, 300) + ), + new PokemonSpecies(SpeciesId.ARCEUS, 4, false, false, true, "Alpha Pokémon", PokemonType.NORMAL, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360, GrowthRate.SLOW, null, false, true, + new PokemonForm("Normal", "normal", PokemonType.NORMAL, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360, false, null, true), + new PokemonForm("Fighting", "fighting", PokemonType.FIGHTING, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Flying", "flying", PokemonType.FLYING, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Poison", "poison", PokemonType.POISON, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Ground", "ground", PokemonType.GROUND, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Rock", "rock", PokemonType.ROCK, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Bug", "bug", PokemonType.BUG, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Ghost", "ghost", PokemonType.GHOST, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Steel", "steel", PokemonType.STEEL, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Fire", "fire", PokemonType.FIRE, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Water", "water", PokemonType.WATER, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Grass", "grass", PokemonType.GRASS, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Electric", "electric", PokemonType.ELECTRIC, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Psychic", "psychic", PokemonType.PSYCHIC, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Ice", "ice", PokemonType.ICE, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Dragon", "dragon", PokemonType.DRAGON, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Dark", "dark", PokemonType.DARK, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("Fairy", "fairy", PokemonType.FAIRY, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), + new PokemonForm("???", "unknown", PokemonType.UNKNOWN, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360, false, null, false, true) + ), + new PokemonSpecies(SpeciesId.VICTINI, 5, false, false, true, "Victory Pokémon", PokemonType.PSYCHIC, PokemonType.FIRE, 0.4, 4, AbilityId.VICTORY_STAR, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 3, 100, 300, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.SNIVY, 5, false, false, false, "Grass Snake Pokémon", PokemonType.GRASS, null, 0.6, 8.1, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CONTRARY, 308, 45, 45, 55, 45, 55, 63, 45, 70, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.SERVINE, 5, false, false, false, "Grass Snake Pokémon", PokemonType.GRASS, null, 0.8, 16, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CONTRARY, 413, 60, 60, 75, 60, 75, 83, 45, 70, 145, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.SERPERIOR, 5, false, false, false, "Regal Pokémon", PokemonType.GRASS, null, 3.3, 63, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CONTRARY, 528, 75, 75, 95, 75, 95, 113, 45, 70, 264, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.TEPIG, 5, false, false, false, "Fire Pig Pokémon", PokemonType.FIRE, null, 0.5, 9.9, AbilityId.BLAZE, AbilityId.NONE, AbilityId.THICK_FAT, 308, 65, 63, 45, 45, 45, 45, 45, 70, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.PIGNITE, 5, false, false, false, "Fire Pig Pokémon", PokemonType.FIRE, PokemonType.FIGHTING, 1, 55.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.THICK_FAT, 418, 90, 93, 55, 70, 55, 55, 45, 70, 146, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.EMBOAR, 5, false, false, false, "Mega Fire Pig Pokémon", PokemonType.FIRE, PokemonType.FIGHTING, 1.6, 150, AbilityId.BLAZE, AbilityId.NONE, AbilityId.RECKLESS, 528, 110, 123, 65, 100, 65, 65, 45, 70, 264, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.OSHAWOTT, 5, false, false, false, "Sea Otter Pokémon", PokemonType.WATER, null, 0.5, 5.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHELL_ARMOR, 308, 55, 55, 45, 63, 45, 45, 45, 70, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.DEWOTT, 5, false, false, false, "Discipline Pokémon", PokemonType.WATER, null, 0.8, 24.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHELL_ARMOR, 413, 75, 75, 60, 83, 60, 60, 45, 70, 145, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.SAMUROTT, 5, false, false, false, "Formidable Pokémon", PokemonType.WATER, null, 1.5, 94.6, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHELL_ARMOR, 528, 95, 100, 85, 108, 70, 70, 45, 70, 264, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.PATRAT, 5, false, false, false, "Scout Pokémon", PokemonType.NORMAL, null, 0.5, 11.6, AbilityId.RUN_AWAY, AbilityId.KEEN_EYE, AbilityId.ANALYTIC, 255, 45, 55, 39, 35, 39, 42, 255, 70, 51, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.WATCHOG, 5, false, false, false, "Lookout Pokémon", PokemonType.NORMAL, null, 1.1, 27, AbilityId.ILLUMINATE, AbilityId.KEEN_EYE, AbilityId.ANALYTIC, 420, 60, 85, 69, 60, 69, 77, 255, 70, 147, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.LILLIPUP, 5, false, false, false, "Puppy Pokémon", PokemonType.NORMAL, null, 0.4, 4.1, AbilityId.VITAL_SPIRIT, AbilityId.PICKUP, AbilityId.RUN_AWAY, 275, 45, 60, 45, 25, 45, 55, 255, 50, 55, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.HERDIER, 5, false, false, false, "Loyal Dog Pokémon", PokemonType.NORMAL, null, 0.9, 14.7, AbilityId.INTIMIDATE, AbilityId.SAND_RUSH, AbilityId.SCRAPPY, 370, 65, 80, 65, 35, 65, 60, 120, 50, 130, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.STOUTLAND, 5, false, false, false, "Big-Hearted Pokémon", PokemonType.NORMAL, null, 1.2, 61, AbilityId.INTIMIDATE, AbilityId.SAND_RUSH, AbilityId.SCRAPPY, 500, 85, 110, 90, 45, 90, 80, 45, 50, 250, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.PURRLOIN, 5, false, false, false, "Devious Pokémon", PokemonType.DARK, null, 0.4, 10.1, AbilityId.LIMBER, AbilityId.UNBURDEN, AbilityId.PRANKSTER, 281, 41, 50, 37, 50, 37, 66, 255, 50, 56, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.LIEPARD, 5, false, false, false, "Cruel Pokémon", PokemonType.DARK, null, 1.1, 37.5, AbilityId.LIMBER, AbilityId.UNBURDEN, AbilityId.PRANKSTER, 446, 64, 88, 50, 88, 50, 106, 90, 50, 156, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PANSAGE, 5, false, false, false, "Grass Monkey Pokémon", PokemonType.GRASS, null, 0.6, 10.5, AbilityId.GLUTTONY, AbilityId.NONE, AbilityId.OVERGROW, 316, 50, 53, 48, 53, 48, 64, 190, 70, 63, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.SIMISAGE, 5, false, false, false, "Thorn Monkey Pokémon", PokemonType.GRASS, null, 1.1, 30.5, AbilityId.GLUTTONY, AbilityId.NONE, AbilityId.OVERGROW, 498, 75, 98, 63, 98, 63, 101, 75, 70, 174, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.PANSEAR, 5, false, false, false, "High Temp Pokémon", PokemonType.FIRE, null, 0.6, 11, AbilityId.GLUTTONY, AbilityId.NONE, AbilityId.BLAZE, 316, 50, 53, 48, 53, 48, 64, 190, 70, 63, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.SIMISEAR, 5, false, false, false, "Ember Pokémon", PokemonType.FIRE, null, 1, 28, AbilityId.GLUTTONY, AbilityId.NONE, AbilityId.BLAZE, 498, 75, 98, 63, 98, 63, 101, 75, 70, 174, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.PANPOUR, 5, false, false, false, "Spray Pokémon", PokemonType.WATER, null, 0.6, 13.5, AbilityId.GLUTTONY, AbilityId.NONE, AbilityId.TORRENT, 316, 50, 53, 48, 53, 48, 64, 190, 70, 63, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.SIMIPOUR, 5, false, false, false, "Geyser Pokémon", PokemonType.WATER, null, 1, 29, AbilityId.GLUTTONY, AbilityId.NONE, AbilityId.TORRENT, 498, 75, 98, 63, 98, 63, 101, 75, 70, 174, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.MUNNA, 5, false, false, false, "Dream Eater Pokémon", PokemonType.PSYCHIC, null, 0.6, 23.3, AbilityId.FOREWARN, AbilityId.SYNCHRONIZE, AbilityId.TELEPATHY, 292, 76, 25, 45, 67, 55, 24, 190, 50, 58, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.MUSHARNA, 5, false, false, false, "Drowsing Pokémon", PokemonType.PSYCHIC, null, 1.1, 60.5, AbilityId.FOREWARN, AbilityId.SYNCHRONIZE, AbilityId.TELEPATHY, 487, 116, 55, 85, 107, 95, 29, 75, 50, 170, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.PIDOVE, 5, false, false, false, "Tiny Pigeon Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 2.1, AbilityId.BIG_PECKS, AbilityId.SUPER_LUCK, AbilityId.RIVALRY, 264, 50, 55, 50, 36, 30, 43, 255, 50, 53, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.TRANQUILL, 5, false, false, false, "Wild Pigeon Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 15, AbilityId.BIG_PECKS, AbilityId.SUPER_LUCK, AbilityId.RIVALRY, 358, 62, 77, 62, 50, 42, 65, 120, 50, 125, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.UNFEZANT, 5, false, false, false, "Proud Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.2, 29, AbilityId.BIG_PECKS, AbilityId.SUPER_LUCK, AbilityId.RIVALRY, 488, 80, 115, 80, 65, 55, 93, 45, 50, 244, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.BLITZLE, 5, false, false, false, "Electrified Pokémon", PokemonType.ELECTRIC, null, 0.8, 29.8, AbilityId.LIGHTNING_ROD, AbilityId.MOTOR_DRIVE, AbilityId.SAP_SIPPER, 295, 45, 60, 32, 50, 32, 76, 190, 70, 59, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ZEBSTRIKA, 5, false, false, false, "Thunderbolt Pokémon", PokemonType.ELECTRIC, null, 1.6, 79.5, AbilityId.LIGHTNING_ROD, AbilityId.MOTOR_DRIVE, AbilityId.SAP_SIPPER, 497, 75, 100, 63, 80, 63, 116, 75, 70, 174, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ROGGENROLA, 5, false, false, false, "Mantle Pokémon", PokemonType.ROCK, null, 0.4, 18, AbilityId.STURDY, AbilityId.WEAK_ARMOR, AbilityId.SAND_FORCE, 280, 55, 75, 85, 25, 25, 15, 255, 50, 56, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.BOLDORE, 5, false, false, false, "Ore Pokémon", PokemonType.ROCK, null, 0.9, 102, AbilityId.STURDY, AbilityId.WEAK_ARMOR, AbilityId.SAND_FORCE, 390, 70, 105, 105, 50, 40, 20, 120, 50, 137, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.GIGALITH, 5, false, false, false, "Compressed Pokémon", PokemonType.ROCK, null, 1.7, 260, AbilityId.STURDY, AbilityId.SAND_STREAM, AbilityId.SAND_FORCE, 515, 85, 135, 130, 60, 80, 25, 45, 50, 258, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.WOOBAT, 5, false, false, false, "Bat Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 0.4, 2.1, AbilityId.UNAWARE, AbilityId.KLUTZ, AbilityId.SIMPLE, 323, 65, 45, 43, 55, 43, 72, 190, 50, 65, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SWOOBAT, 5, false, false, false, "Courting Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 0.9, 10.5, AbilityId.UNAWARE, AbilityId.KLUTZ, AbilityId.SIMPLE, 425, 67, 57, 55, 77, 55, 114, 45, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DRILBUR, 5, false, false, false, "Mole Pokémon", PokemonType.GROUND, null, 0.3, 8.5, AbilityId.SAND_RUSH, AbilityId.SAND_FORCE, AbilityId.MOLD_BREAKER, 328, 60, 85, 40, 30, 45, 68, 120, 50, 66, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.EXCADRILL, 5, false, false, false, "Subterrene Pokémon", PokemonType.GROUND, PokemonType.STEEL, 0.7, 40.4, AbilityId.SAND_RUSH, AbilityId.SAND_FORCE, AbilityId.MOLD_BREAKER, 508, 110, 135, 60, 50, 65, 88, 60, 50, 178, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.AUDINO, 5, false, false, false, "Hearing Pokémon", PokemonType.NORMAL, null, 1.1, 31, AbilityId.HEALER, AbilityId.REGENERATOR, AbilityId.KLUTZ, 445, 103, 60, 86, 60, 86, 50, 255, 50, 390, GrowthRate.FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.NORMAL, null, 1.1, 31, AbilityId.HEALER, AbilityId.REGENERATOR, AbilityId.KLUTZ, 445, 103, 60, 86, 60, 86, 50, 255, 50, 390, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.NORMAL, PokemonType.FAIRY, 1.5, 32, AbilityId.REGENERATOR, AbilityId.REGENERATOR, AbilityId.REGENERATOR, 545, 103, 60, 126, 80, 126, 50, 255, 50, 390) + ), + new PokemonSpecies(SpeciesId.TIMBURR, 5, false, false, false, "Muscular Pokémon", PokemonType.FIGHTING, null, 0.6, 12.5, AbilityId.GUTS, AbilityId.SHEER_FORCE, AbilityId.IRON_FIST, 305, 75, 80, 55, 25, 35, 35, 180, 70, 61, GrowthRate.MEDIUM_SLOW, 75, false), + new PokemonSpecies(SpeciesId.GURDURR, 5, false, false, false, "Muscular Pokémon", PokemonType.FIGHTING, null, 1.2, 40, AbilityId.GUTS, AbilityId.SHEER_FORCE, AbilityId.IRON_FIST, 405, 85, 105, 85, 40, 50, 40, 90, 50, 142, GrowthRate.MEDIUM_SLOW, 75, false), + new PokemonSpecies(SpeciesId.CONKELDURR, 5, false, false, false, "Muscular Pokémon", PokemonType.FIGHTING, null, 1.4, 87, AbilityId.GUTS, AbilityId.SHEER_FORCE, AbilityId.IRON_FIST, 505, 105, 140, 95, 55, 65, 45, 45, 50, 253, GrowthRate.MEDIUM_SLOW, 75, false), + new PokemonSpecies(SpeciesId.TYMPOLE, 5, false, false, false, "Tadpole Pokémon", PokemonType.WATER, null, 0.5, 4.5, AbilityId.SWIFT_SWIM, AbilityId.HYDRATION, AbilityId.WATER_ABSORB, 294, 50, 50, 40, 50, 40, 64, 255, 50, 59, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.PALPITOAD, 5, false, false, false, "Vibration Pokémon", PokemonType.WATER, PokemonType.GROUND, 0.8, 17, AbilityId.SWIFT_SWIM, AbilityId.HYDRATION, AbilityId.WATER_ABSORB, 384, 75, 65, 55, 65, 55, 69, 120, 50, 134, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SEISMITOAD, 5, false, false, false, "Vibration Pokémon", PokemonType.WATER, PokemonType.GROUND, 1.5, 62, AbilityId.SWIFT_SWIM, AbilityId.POISON_TOUCH, AbilityId.WATER_ABSORB, 509, 105, 95, 75, 85, 75, 74, 45, 50, 255, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.THROH, 5, false, false, false, "Judo Pokémon", PokemonType.FIGHTING, null, 1.3, 55.5, AbilityId.GUTS, AbilityId.INNER_FOCUS, AbilityId.MOLD_BREAKER, 465, 120, 100, 85, 30, 85, 45, 45, 50, 163, GrowthRate.MEDIUM_FAST, 100, false), + new PokemonSpecies(SpeciesId.SAWK, 5, false, false, false, "Karate Pokémon", PokemonType.FIGHTING, null, 1.4, 51, AbilityId.STURDY, AbilityId.INNER_FOCUS, AbilityId.MOLD_BREAKER, 465, 75, 125, 75, 30, 75, 85, 45, 50, 163, GrowthRate.MEDIUM_FAST, 100, false), + new PokemonSpecies(SpeciesId.SEWADDLE, 5, false, false, false, "Sewing Pokémon", PokemonType.BUG, PokemonType.GRASS, 0.3, 2.5, AbilityId.SWARM, AbilityId.CHLOROPHYLL, AbilityId.OVERCOAT, 310, 45, 53, 70, 40, 60, 42, 255, 70, 62, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SWADLOON, 5, false, false, false, "Leaf-Wrapped Pokémon", PokemonType.BUG, PokemonType.GRASS, 0.5, 7.3, AbilityId.LEAF_GUARD, AbilityId.CHLOROPHYLL, AbilityId.OVERCOAT, 380, 55, 63, 90, 50, 80, 42, 120, 70, 133, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.LEAVANNY, 5, false, false, false, "Nurturing Pokémon", PokemonType.BUG, PokemonType.GRASS, 1.2, 20.5, AbilityId.SWARM, AbilityId.CHLOROPHYLL, AbilityId.OVERCOAT, 500, 75, 103, 80, 70, 80, 92, 45, 70, 250, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.VENIPEDE, 5, false, false, false, "Centipede Pokémon", PokemonType.BUG, PokemonType.POISON, 0.4, 5.3, AbilityId.POISON_POINT, AbilityId.SWARM, AbilityId.SPEED_BOOST, 260, 30, 45, 59, 30, 39, 57, 255, 50, 52, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.WHIRLIPEDE, 5, false, false, false, "Curlipede Pokémon", PokemonType.BUG, PokemonType.POISON, 1.2, 58.5, AbilityId.POISON_POINT, AbilityId.SWARM, AbilityId.SPEED_BOOST, 360, 40, 55, 99, 40, 79, 47, 120, 50, 126, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SCOLIPEDE, 5, false, false, false, "Megapede Pokémon", PokemonType.BUG, PokemonType.POISON, 2.5, 200.5, AbilityId.POISON_POINT, AbilityId.SWARM, AbilityId.SPEED_BOOST, 485, 60, 100, 89, 55, 69, 112, 45, 50, 243, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.COTTONEE, 5, false, false, false, "Cotton Puff Pokémon", PokemonType.GRASS, PokemonType.FAIRY, 0.3, 0.6, AbilityId.PRANKSTER, AbilityId.INFILTRATOR, AbilityId.CHLOROPHYLL, 280, 40, 27, 60, 37, 50, 66, 190, 50, 56, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.WHIMSICOTT, 5, false, false, false, "Windveiled Pokémon", PokemonType.GRASS, PokemonType.FAIRY, 0.7, 6.6, AbilityId.PRANKSTER, AbilityId.INFILTRATOR, AbilityId.CHLOROPHYLL, 480, 60, 67, 85, 77, 75, 116, 75, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PETILIL, 5, false, false, false, "Bulb Pokémon", PokemonType.GRASS, null, 0.5, 6.6, AbilityId.CHLOROPHYLL, AbilityId.OWN_TEMPO, AbilityId.LEAF_GUARD, 280, 45, 35, 50, 70, 50, 30, 190, 50, 56, GrowthRate.MEDIUM_FAST, 0, false), + new PokemonSpecies(SpeciesId.LILLIGANT, 5, false, false, false, "Flowering Pokémon", PokemonType.GRASS, null, 1.1, 16.3, AbilityId.CHLOROPHYLL, AbilityId.OWN_TEMPO, AbilityId.LEAF_GUARD, 480, 70, 60, 75, 110, 75, 90, 75, 50, 168, GrowthRate.MEDIUM_FAST, 0, false), + new PokemonSpecies(SpeciesId.BASCULIN, 5, false, false, false, "Hostile Pokémon", PokemonType.WATER, null, 1, 18, AbilityId.RECKLESS, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 190, 50, 161, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Red-Striped Form", "red-striped", PokemonType.WATER, null, 1, 18, AbilityId.RECKLESS, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 190, 50, 161, false, null, true), + new PokemonForm("Blue-Striped Form", "blue-striped", PokemonType.WATER, null, 1, 18, AbilityId.ROCK_HEAD, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 190, 50, 161, false, null, true), + new PokemonForm("White-Striped Form", "white-striped", PokemonType.WATER, null, 1, 18, AbilityId.RATTLED, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 190, 50, 161, false, null, true) + ), + new PokemonSpecies(SpeciesId.SANDILE, 5, false, false, false, "Desert Croc Pokémon", PokemonType.GROUND, PokemonType.DARK, 0.7, 15.2, AbilityId.INTIMIDATE, AbilityId.MOXIE, AbilityId.ANGER_POINT, 292, 50, 72, 35, 35, 35, 65, 180, 50, 58, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.KROKOROK, 5, false, false, false, "Desert Croc Pokémon", PokemonType.GROUND, PokemonType.DARK, 1, 33.4, AbilityId.INTIMIDATE, AbilityId.MOXIE, AbilityId.ANGER_POINT, 351, 60, 82, 45, 45, 45, 74, 90, 50, 123, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.KROOKODILE, 5, false, false, false, "Intimidation Pokémon", PokemonType.GROUND, PokemonType.DARK, 1.5, 96.3, AbilityId.INTIMIDATE, AbilityId.MOXIE, AbilityId.ANGER_POINT, 519, 95, 117, 80, 65, 70, 92, 45, 50, 260, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.DARUMAKA, 5, false, false, false, "Zen Charm Pokémon", PokemonType.FIRE, null, 0.6, 37.5, AbilityId.HUSTLE, AbilityId.NONE, AbilityId.INNER_FOCUS, 315, 70, 90, 45, 15, 45, 50, 120, 50, 63, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.DARMANITAN, 5, false, false, false, "Blazing Pokémon", PokemonType.FIRE, null, 1.3, 92.9, AbilityId.SHEER_FORCE, AbilityId.NONE, AbilityId.ZEN_MODE, 480, 105, 140, 55, 30, 55, 95, 60, 50, 168, GrowthRate.MEDIUM_SLOW, 50, false, true, + new PokemonForm("Standard Mode", "", PokemonType.FIRE, null, 1.3, 92.9, AbilityId.SHEER_FORCE, AbilityId.NONE, AbilityId.ZEN_MODE, 480, 105, 140, 55, 30, 55, 95, 60, 50, 168, false, null, true), + new PokemonForm("Zen Mode", "zen", PokemonType.FIRE, PokemonType.PSYCHIC, 1.3, 92.9, AbilityId.SHEER_FORCE, AbilityId.NONE, AbilityId.ZEN_MODE, 540, 105, 30, 105, 140, 105, 55, 60, 50, 189) + ), + new PokemonSpecies(SpeciesId.MARACTUS, 5, false, false, false, "Cactus Pokémon", PokemonType.GRASS, null, 1, 28, AbilityId.WATER_ABSORB, AbilityId.CHLOROPHYLL, AbilityId.STORM_DRAIN, 461, 75, 86, 67, 106, 67, 60, 255, 50, 161, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DWEBBLE, 5, false, false, false, "Rock Inn Pokémon", PokemonType.BUG, PokemonType.ROCK, 0.3, 14.5, AbilityId.STURDY, AbilityId.SHELL_ARMOR, AbilityId.WEAK_ARMOR, 325, 50, 65, 85, 35, 35, 55, 190, 50, 65, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CRUSTLE, 5, false, false, false, "Stone Home Pokémon", PokemonType.BUG, PokemonType.ROCK, 1.4, 200, AbilityId.STURDY, AbilityId.SHELL_ARMOR, AbilityId.WEAK_ARMOR, 485, 70, 105, 125, 65, 75, 45, 75, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SCRAGGY, 5, false, false, false, "Shedding Pokémon", PokemonType.DARK, PokemonType.FIGHTING, 0.6, 11.8, AbilityId.SHED_SKIN, AbilityId.MOXIE, AbilityId.INTIMIDATE, 348, 50, 75, 70, 35, 70, 48, 180, 35, 70, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SCRAFTY, 5, false, false, false, "Hoodlum Pokémon", PokemonType.DARK, PokemonType.FIGHTING, 1.1, 30, AbilityId.SHED_SKIN, AbilityId.MOXIE, AbilityId.INTIMIDATE, 488, 65, 90, 115, 45, 115, 58, 90, 50, 171, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SIGILYPH, 5, false, false, false, "Avianoid Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 1.4, 14, AbilityId.WONDER_SKIN, AbilityId.MAGIC_GUARD, AbilityId.TINTED_LENS, 490, 72, 58, 80, 103, 80, 97, 45, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.YAMASK, 5, false, false, false, "Spirit Pokémon", PokemonType.GHOST, null, 0.5, 1.5, AbilityId.MUMMY, AbilityId.NONE, AbilityId.NONE, 303, 38, 30, 85, 55, 65, 30, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.COFAGRIGUS, 5, false, false, false, "Coffin Pokémon", PokemonType.GHOST, null, 1.7, 76.5, AbilityId.MUMMY, AbilityId.NONE, AbilityId.NONE, 483, 58, 50, 145, 95, 105, 30, 90, 50, 169, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.TIRTOUGA, 5, false, false, false, "Prototurtle Pokémon", PokemonType.WATER, PokemonType.ROCK, 0.7, 16.5, AbilityId.SOLID_ROCK, AbilityId.STURDY, AbilityId.SWIFT_SWIM, 355, 54, 78, 103, 53, 45, 22, 45, 50, 71, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.CARRACOSTA, 5, false, false, false, "Prototurtle Pokémon", PokemonType.WATER, PokemonType.ROCK, 1.2, 81, AbilityId.SOLID_ROCK, AbilityId.STURDY, AbilityId.SWIFT_SWIM, 495, 74, 108, 133, 83, 65, 32, 45, 50, 173, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.ARCHEN, 5, false, false, false, "First Bird Pokémon", PokemonType.ROCK, PokemonType.FLYING, 0.5, 9.5, AbilityId.DEFEATIST, AbilityId.NONE, AbilityId.WIMP_OUT, 401, 55, 112, 45, 74, 45, 70, 45, 50, 71, GrowthRate.MEDIUM_FAST, 87.5, false), //Custom Hidden + new PokemonSpecies(SpeciesId.ARCHEOPS, 5, false, false, false, "First Bird Pokémon", PokemonType.ROCK, PokemonType.FLYING, 1.4, 32, AbilityId.DEFEATIST, AbilityId.NONE, AbilityId.EMERGENCY_EXIT, 567, 75, 140, 65, 112, 65, 110, 45, 50, 177, GrowthRate.MEDIUM_FAST, 87.5, false), //Custom Hidden + new PokemonSpecies(SpeciesId.TRUBBISH, 5, false, false, false, "Trash Bag Pokémon", PokemonType.POISON, null, 0.6, 31, AbilityId.STENCH, AbilityId.STICKY_HOLD, AbilityId.AFTERMATH, 329, 50, 50, 62, 40, 62, 65, 190, 50, 66, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GARBODOR, 5, false, false, false, "Trash Heap Pokémon", PokemonType.POISON, null, 1.9, 107.3, AbilityId.STENCH, AbilityId.WEAK_ARMOR, AbilityId.AFTERMATH, 474, 80, 95, 82, 60, 82, 75, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.POISON, null, 1.9, 107.3, AbilityId.STENCH, AbilityId.WEAK_ARMOR, AbilityId.AFTERMATH, 474, 80, 95, 82, 60, 82, 75, 60, 50, 166, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.POISON, PokemonType.STEEL, 21, 999.9, AbilityId.TOXIC_DEBRIS, AbilityId.TOXIC_DEBRIS, AbilityId.TOXIC_DEBRIS, 574, 115, 121, 102, 81, 102, 53, 60, 50, 166) + ), + new PokemonSpecies(SpeciesId.ZORUA, 5, false, false, false, "Tricky Fox Pokémon", PokemonType.DARK, null, 0.7, 12.5, AbilityId.ILLUSION, AbilityId.NONE, AbilityId.NONE, 330, 40, 65, 40, 80, 40, 65, 75, 50, 66, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.ZOROARK, 5, false, false, false, "Illusion Fox Pokémon", PokemonType.DARK, null, 1.6, 81.1, AbilityId.ILLUSION, AbilityId.NONE, AbilityId.NONE, 510, 60, 105, 60, 120, 60, 105, 45, 50, 179, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.MINCCINO, 5, false, false, false, "Chinchilla Pokémon", PokemonType.NORMAL, null, 0.4, 5.8, AbilityId.CUTE_CHARM, AbilityId.TECHNICIAN, AbilityId.SKILL_LINK, 300, 55, 50, 40, 40, 40, 75, 255, 50, 60, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.CINCCINO, 5, false, false, false, "Scarf Pokémon", PokemonType.NORMAL, null, 0.5, 7.5, AbilityId.CUTE_CHARM, AbilityId.TECHNICIAN, AbilityId.SKILL_LINK, 470, 75, 95, 60, 65, 60, 115, 60, 50, 165, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.GOTHITA, 5, false, false, false, "Fixation Pokémon", PokemonType.PSYCHIC, null, 0.4, 5.8, AbilityId.FRISK, AbilityId.COMPETITIVE, AbilityId.SHADOW_TAG, 290, 45, 30, 50, 55, 65, 45, 200, 50, 58, GrowthRate.MEDIUM_SLOW, 25, false), + new PokemonSpecies(SpeciesId.GOTHORITA, 5, false, false, false, "Manipulate Pokémon", PokemonType.PSYCHIC, null, 0.7, 18, AbilityId.FRISK, AbilityId.COMPETITIVE, AbilityId.SHADOW_TAG, 390, 60, 45, 70, 75, 85, 55, 100, 50, 137, GrowthRate.MEDIUM_SLOW, 25, false), + new PokemonSpecies(SpeciesId.GOTHITELLE, 5, false, false, false, "Astral Body Pokémon", PokemonType.PSYCHIC, null, 1.5, 44, AbilityId.FRISK, AbilityId.COMPETITIVE, AbilityId.SHADOW_TAG, 490, 70, 55, 95, 95, 110, 65, 50, 50, 245, GrowthRate.MEDIUM_SLOW, 25, false), + new PokemonSpecies(SpeciesId.SOLOSIS, 5, false, false, false, "Cell Pokémon", PokemonType.PSYCHIC, null, 0.3, 1, AbilityId.OVERCOAT, AbilityId.MAGIC_GUARD, AbilityId.REGENERATOR, 290, 45, 30, 40, 105, 50, 20, 200, 50, 58, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.DUOSION, 5, false, false, false, "Mitosis Pokémon", PokemonType.PSYCHIC, null, 0.6, 8, AbilityId.OVERCOAT, AbilityId.MAGIC_GUARD, AbilityId.REGENERATOR, 370, 65, 40, 50, 125, 60, 30, 100, 50, 130, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.REUNICLUS, 5, false, false, false, "Multiplying Pokémon", PokemonType.PSYCHIC, null, 1, 20.1, AbilityId.OVERCOAT, AbilityId.MAGIC_GUARD, AbilityId.REGENERATOR, 490, 110, 65, 75, 125, 85, 30, 50, 50, 245, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.DUCKLETT, 5, false, false, false, "Water Bird Pokémon", PokemonType.WATER, PokemonType.FLYING, 0.5, 5.5, AbilityId.KEEN_EYE, AbilityId.BIG_PECKS, AbilityId.HYDRATION, 305, 62, 44, 50, 44, 50, 55, 190, 70, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SWANNA, 5, false, false, false, "White Bird Pokémon", PokemonType.WATER, PokemonType.FLYING, 1.3, 24.2, AbilityId.KEEN_EYE, AbilityId.BIG_PECKS, AbilityId.HYDRATION, 473, 75, 87, 63, 87, 63, 98, 45, 70, 166, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.VANILLITE, 5, false, false, false, "Fresh Snow Pokémon", PokemonType.ICE, null, 0.4, 5.7, AbilityId.ICE_BODY, AbilityId.SNOW_CLOAK, AbilityId.WEAK_ARMOR, 305, 36, 50, 50, 65, 60, 44, 255, 50, 61, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.VANILLISH, 5, false, false, false, "Icy Snow Pokémon", PokemonType.ICE, null, 1.1, 41, AbilityId.ICE_BODY, AbilityId.SNOW_CLOAK, AbilityId.WEAK_ARMOR, 395, 51, 65, 65, 80, 75, 59, 120, 50, 138, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.VANILLUXE, 5, false, false, false, "Snowstorm Pokémon", PokemonType.ICE, null, 1.3, 57.5, AbilityId.ICE_BODY, AbilityId.SNOW_WARNING, AbilityId.WEAK_ARMOR, 535, 71, 95, 85, 110, 95, 79, 45, 50, 268, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.DEERLING, 5, false, false, false, "Season Pokémon", PokemonType.NORMAL, PokemonType.GRASS, 0.6, 19.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 335, 60, 60, 50, 40, 50, 75, 190, 70, 67, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Spring Form", "spring", PokemonType.NORMAL, PokemonType.GRASS, 0.6, 19.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 335, 60, 60, 50, 40, 50, 75, 190, 70, 67, false, null, true), + new PokemonForm("Summer Form", "summer", PokemonType.NORMAL, PokemonType.GRASS, 0.6, 19.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 335, 60, 60, 50, 40, 50, 75, 190, 70, 67, false, null, true), + new PokemonForm("Autumn Form", "autumn", PokemonType.NORMAL, PokemonType.GRASS, 0.6, 19.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 335, 60, 60, 50, 40, 50, 75, 190, 70, 67, false, null, true), + new PokemonForm("Winter Form", "winter", PokemonType.NORMAL, PokemonType.GRASS, 0.6, 19.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 335, 60, 60, 50, 40, 50, 75, 190, 70, 67, false, null, true) + ), + new PokemonSpecies(SpeciesId.SAWSBUCK, 5, false, false, false, "Season Pokémon", PokemonType.NORMAL, PokemonType.GRASS, 1.9, 92.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 475, 80, 100, 70, 60, 70, 95, 75, 70, 166, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Spring Form", "spring", PokemonType.NORMAL, PokemonType.GRASS, 1.9, 92.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 475, 80, 100, 70, 60, 70, 95, 75, 70, 166, false, null, true), + new PokemonForm("Summer Form", "summer", PokemonType.NORMAL, PokemonType.GRASS, 1.9, 92.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 475, 80, 100, 70, 60, 70, 95, 75, 70, 166, false, null, true), + new PokemonForm("Autumn Form", "autumn", PokemonType.NORMAL, PokemonType.GRASS, 1.9, 92.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 475, 80, 100, 70, 60, 70, 95, 75, 70, 166, false, null, true), + new PokemonForm("Winter Form", "winter", PokemonType.NORMAL, PokemonType.GRASS, 1.9, 92.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 475, 80, 100, 70, 60, 70, 95, 75, 70, 166, false, null, true) + ), + new PokemonSpecies(SpeciesId.EMOLGA, 5, false, false, false, "Sky Squirrel Pokémon", PokemonType.ELECTRIC, PokemonType.FLYING, 0.4, 5, AbilityId.STATIC, AbilityId.NONE, AbilityId.MOTOR_DRIVE, 428, 55, 75, 60, 75, 60, 103, 200, 50, 150, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.KARRABLAST, 5, false, false, false, "Clamping Pokémon", PokemonType.BUG, null, 0.5, 5.9, AbilityId.SWARM, AbilityId.SHED_SKIN, AbilityId.NO_GUARD, 315, 50, 75, 45, 40, 45, 60, 200, 50, 63, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ESCAVALIER, 5, false, false, false, "Cavalry Pokémon", PokemonType.BUG, PokemonType.STEEL, 1, 33, AbilityId.SWARM, AbilityId.SHELL_ARMOR, AbilityId.OVERCOAT, 495, 70, 135, 105, 60, 105, 20, 75, 50, 173, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.FOONGUS, 5, false, false, false, "Mushroom Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.2, 1, AbilityId.EFFECT_SPORE, AbilityId.NONE, AbilityId.REGENERATOR, 294, 69, 55, 45, 55, 55, 15, 190, 50, 59, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.AMOONGUSS, 5, false, false, false, "Mushroom Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.6, 10.5, AbilityId.EFFECT_SPORE, AbilityId.NONE, AbilityId.REGENERATOR, 464, 114, 85, 70, 85, 80, 30, 75, 50, 162, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.FRILLISH, 5, false, false, false, "Floating Pokémon", PokemonType.WATER, PokemonType.GHOST, 1.2, 33, AbilityId.WATER_ABSORB, AbilityId.CURSED_BODY, AbilityId.DAMP, 335, 55, 40, 50, 65, 85, 40, 190, 50, 67, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.JELLICENT, 5, false, false, false, "Floating Pokémon", PokemonType.WATER, PokemonType.GHOST, 2.2, 135, AbilityId.WATER_ABSORB, AbilityId.CURSED_BODY, AbilityId.DAMP, 480, 100, 60, 70, 85, 105, 60, 60, 50, 168, GrowthRate.MEDIUM_FAST, 50, true), + new PokemonSpecies(SpeciesId.ALOMOMOLA, 5, false, false, false, "Caring Pokémon", PokemonType.WATER, null, 1.2, 31.6, AbilityId.HEALER, AbilityId.HYDRATION, AbilityId.REGENERATOR, 470, 165, 75, 80, 40, 45, 65, 75, 70, 165, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.JOLTIK, 5, false, false, false, "Attaching Pokémon", PokemonType.BUG, PokemonType.ELECTRIC, 0.1, 0.6, AbilityId.COMPOUND_EYES, AbilityId.UNNERVE, AbilityId.SWARM, 319, 50, 47, 50, 57, 50, 65, 190, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GALVANTULA, 5, false, false, false, "EleSpider Pokémon", PokemonType.BUG, PokemonType.ELECTRIC, 0.8, 14.3, AbilityId.COMPOUND_EYES, AbilityId.UNNERVE, AbilityId.SWARM, 472, 70, 77, 60, 97, 60, 108, 75, 50, 165, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.FERROSEED, 5, false, false, false, "Thorn Seed Pokémon", PokemonType.GRASS, PokemonType.STEEL, 0.6, 18.8, AbilityId.IRON_BARBS, AbilityId.NONE, AbilityId.ANTICIPATION, 305, 44, 50, 91, 24, 86, 10, 255, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.FERROTHORN, 5, false, false, false, "Thorn Pod Pokémon", PokemonType.GRASS, PokemonType.STEEL, 1, 110, AbilityId.IRON_BARBS, AbilityId.NONE, AbilityId.ANTICIPATION, 489, 74, 94, 131, 54, 116, 20, 90, 50, 171, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.KLINK, 5, false, false, false, "Gear Pokémon", PokemonType.STEEL, null, 0.3, 21, AbilityId.PLUS, AbilityId.MINUS, AbilityId.CLEAR_BODY, 300, 40, 55, 70, 45, 60, 30, 130, 50, 60, GrowthRate.MEDIUM_SLOW, null, false), + new PokemonSpecies(SpeciesId.KLANG, 5, false, false, false, "Gear Pokémon", PokemonType.STEEL, null, 0.6, 51, AbilityId.PLUS, AbilityId.MINUS, AbilityId.CLEAR_BODY, 440, 60, 80, 95, 70, 85, 50, 60, 50, 154, GrowthRate.MEDIUM_SLOW, null, false), + new PokemonSpecies(SpeciesId.KLINKLANG, 5, false, false, false, "Gear Pokémon", PokemonType.STEEL, null, 0.6, 81, AbilityId.PLUS, AbilityId.MINUS, AbilityId.CLEAR_BODY, 520, 60, 100, 115, 70, 85, 90, 30, 50, 260, GrowthRate.MEDIUM_SLOW, null, false), + new PokemonSpecies(SpeciesId.TYNAMO, 5, false, false, false, "EleFish Pokémon", PokemonType.ELECTRIC, null, 0.2, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 275, 35, 55, 40, 45, 40, 60, 190, 70, 55, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.EELEKTRIK, 5, false, false, false, "EleFish Pokémon", PokemonType.ELECTRIC, null, 1.2, 22, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 405, 65, 85, 70, 75, 70, 40, 60, 70, 142, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.EELEKTROSS, 5, false, false, false, "EleFish Pokémon", PokemonType.ELECTRIC, null, 2.1, 80.5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 515, 85, 115, 80, 105, 80, 50, 30, 70, 258, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.ELGYEM, 5, false, false, false, "Cerebral Pokémon", PokemonType.PSYCHIC, null, 0.5, 9, AbilityId.TELEPATHY, AbilityId.SYNCHRONIZE, AbilityId.ANALYTIC, 335, 55, 55, 55, 85, 55, 30, 255, 50, 67, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BEHEEYEM, 5, false, false, false, "Cerebral Pokémon", PokemonType.PSYCHIC, null, 1, 34.5, AbilityId.TELEPATHY, AbilityId.SYNCHRONIZE, AbilityId.ANALYTIC, 485, 75, 75, 75, 125, 95, 40, 90, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.LITWICK, 5, false, false, false, "Candle Pokémon", PokemonType.GHOST, PokemonType.FIRE, 0.3, 3.1, AbilityId.FLASH_FIRE, AbilityId.FLAME_BODY, AbilityId.INFILTRATOR, 275, 50, 30, 55, 65, 55, 20, 190, 50, 55, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.LAMPENT, 5, false, false, false, "Lamp Pokémon", PokemonType.GHOST, PokemonType.FIRE, 0.6, 13, AbilityId.FLASH_FIRE, AbilityId.FLAME_BODY, AbilityId.INFILTRATOR, 370, 60, 40, 60, 95, 60, 55, 90, 50, 130, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.CHANDELURE, 5, false, false, false, "Luring Pokémon", PokemonType.GHOST, PokemonType.FIRE, 1, 34.3, AbilityId.FLASH_FIRE, AbilityId.FLAME_BODY, AbilityId.INFILTRATOR, 520, 60, 55, 90, 145, 90, 80, 45, 50, 260, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.AXEW, 5, false, false, false, "Tusk Pokémon", PokemonType.DRAGON, null, 0.6, 18, AbilityId.RIVALRY, AbilityId.MOLD_BREAKER, AbilityId.UNNERVE, 320, 46, 87, 60, 30, 40, 57, 75, 35, 64, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.FRAXURE, 5, false, false, false, "Axe Jaw Pokémon", PokemonType.DRAGON, null, 1, 36, AbilityId.RIVALRY, AbilityId.MOLD_BREAKER, AbilityId.UNNERVE, 410, 66, 117, 70, 40, 50, 67, 60, 35, 144, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.HAXORUS, 5, false, false, false, "Axe Jaw Pokémon", PokemonType.DRAGON, null, 1.8, 105.5, AbilityId.RIVALRY, AbilityId.MOLD_BREAKER, AbilityId.UNNERVE, 540, 76, 147, 90, 60, 70, 97, 45, 35, 270, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.CUBCHOO, 5, false, false, false, "Chill Pokémon", PokemonType.ICE, null, 0.5, 8.5, AbilityId.SNOW_CLOAK, AbilityId.SLUSH_RUSH, AbilityId.RATTLED, 305, 55, 70, 40, 60, 40, 40, 120, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BEARTIC, 5, false, false, false, "Freezing Pokémon", PokemonType.ICE, null, 2.6, 260, AbilityId.SNOW_CLOAK, AbilityId.SLUSH_RUSH, AbilityId.SWIFT_SWIM, 505, 95, 130, 80, 70, 80, 50, 60, 50, 177, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CRYOGONAL, 5, false, false, false, "Crystallizing Pokémon", PokemonType.ICE, null, 1.1, 148, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 515, 80, 50, 50, 95, 135, 105, 25, 50, 180, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.SHELMET, 5, false, false, false, "Snail Pokémon", PokemonType.BUG, null, 0.4, 7.7, AbilityId.HYDRATION, AbilityId.SHELL_ARMOR, AbilityId.OVERCOAT, 305, 50, 40, 85, 40, 65, 25, 200, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ACCELGOR, 5, false, false, false, "Shell Out Pokémon", PokemonType.BUG, null, 0.8, 25.3, AbilityId.HYDRATION, AbilityId.STICKY_HOLD, AbilityId.UNBURDEN, 495, 80, 70, 40, 100, 60, 145, 75, 50, 173, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.STUNFISK, 5, false, false, false, "Trap Pokémon", PokemonType.GROUND, PokemonType.ELECTRIC, 0.7, 11, AbilityId.STATIC, AbilityId.LIMBER, AbilityId.SAND_VEIL, 471, 109, 66, 84, 81, 99, 32, 75, 70, 165, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MIENFOO, 5, false, false, false, "Martial Arts Pokémon", PokemonType.FIGHTING, null, 0.9, 20, AbilityId.INNER_FOCUS, AbilityId.REGENERATOR, AbilityId.RECKLESS, 350, 45, 85, 50, 55, 50, 65, 180, 50, 70, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.MIENSHAO, 5, false, false, false, "Martial Arts Pokémon", PokemonType.FIGHTING, null, 1.4, 35.5, AbilityId.INNER_FOCUS, AbilityId.REGENERATOR, AbilityId.RECKLESS, 510, 65, 125, 60, 95, 60, 105, 45, 50, 179, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.DRUDDIGON, 5, false, false, false, "Cave Pokémon", PokemonType.DRAGON, null, 1.6, 139, AbilityId.ROUGH_SKIN, AbilityId.SHEER_FORCE, AbilityId.MOLD_BREAKER, 485, 77, 120, 90, 60, 90, 48, 45, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GOLETT, 5, false, false, false, "Automaton Pokémon", PokemonType.GROUND, PokemonType.GHOST, 1, 92, AbilityId.IRON_FIST, AbilityId.KLUTZ, AbilityId.NO_GUARD, 303, 59, 74, 50, 35, 50, 35, 190, 50, 61, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.GOLURK, 5, false, false, false, "Automaton Pokémon", PokemonType.GROUND, PokemonType.GHOST, 2.8, 330, AbilityId.IRON_FIST, AbilityId.KLUTZ, AbilityId.NO_GUARD, 483, 89, 124, 80, 55, 80, 55, 90, 50, 169, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.PAWNIARD, 5, false, false, false, "Sharp Blade Pokémon", PokemonType.DARK, PokemonType.STEEL, 0.5, 10.2, AbilityId.DEFIANT, AbilityId.INNER_FOCUS, AbilityId.PRESSURE, 340, 45, 85, 70, 40, 40, 60, 120, 35, 68, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BISHARP, 5, false, false, false, "Sword Blade Pokémon", PokemonType.DARK, PokemonType.STEEL, 1.6, 70, AbilityId.DEFIANT, AbilityId.INNER_FOCUS, AbilityId.PRESSURE, 490, 65, 125, 100, 60, 70, 70, 45, 35, 172, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BOUFFALANT, 5, false, false, false, "Bash Buffalo Pokémon", PokemonType.NORMAL, null, 1.6, 94.6, AbilityId.RECKLESS, AbilityId.SAP_SIPPER, AbilityId.SOUNDPROOF, 490, 95, 110, 95, 40, 95, 55, 45, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.RUFFLET, 5, false, false, false, "Eaglet Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.5, 10.5, AbilityId.KEEN_EYE, AbilityId.SHEER_FORCE, AbilityId.HUSTLE, 350, 70, 83, 50, 37, 50, 60, 190, 50, 70, GrowthRate.SLOW, 100, false), + new PokemonSpecies(SpeciesId.BRAVIARY, 5, false, false, false, "Valiant Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.5, 41, AbilityId.KEEN_EYE, AbilityId.SHEER_FORCE, AbilityId.DEFIANT, 510, 100, 123, 75, 57, 75, 80, 60, 50, 179, GrowthRate.SLOW, 100, false), + new PokemonSpecies(SpeciesId.VULLABY, 5, false, false, false, "Diapered Pokémon", PokemonType.DARK, PokemonType.FLYING, 0.5, 9, AbilityId.BIG_PECKS, AbilityId.OVERCOAT, AbilityId.WEAK_ARMOR, 370, 70, 55, 75, 45, 65, 60, 190, 35, 74, GrowthRate.SLOW, 0, false), + new PokemonSpecies(SpeciesId.MANDIBUZZ, 5, false, false, false, "Bone Vulture Pokémon", PokemonType.DARK, PokemonType.FLYING, 1.2, 39.5, AbilityId.BIG_PECKS, AbilityId.OVERCOAT, AbilityId.WEAK_ARMOR, 510, 110, 65, 105, 55, 95, 80, 60, 35, 179, GrowthRate.SLOW, 0, false), + new PokemonSpecies(SpeciesId.HEATMOR, 5, false, false, false, "Anteater Pokémon", PokemonType.FIRE, null, 1.4, 58, AbilityId.GLUTTONY, AbilityId.FLASH_FIRE, AbilityId.WHITE_SMOKE, 484, 85, 97, 66, 105, 66, 65, 90, 50, 169, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DURANT, 5, false, false, false, "Iron Ant Pokémon", PokemonType.BUG, PokemonType.STEEL, 0.3, 33, AbilityId.SWARM, AbilityId.HUSTLE, AbilityId.TRUANT, 484, 58, 109, 112, 48, 48, 109, 90, 50, 169, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DEINO, 5, false, false, false, "Irate Pokémon", PokemonType.DARK, PokemonType.DRAGON, 0.8, 17.3, AbilityId.HUSTLE, AbilityId.NONE, AbilityId.NONE, 300, 52, 65, 50, 45, 50, 38, 45, 35, 60, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.ZWEILOUS, 5, false, false, false, "Hostile Pokémon", PokemonType.DARK, PokemonType.DRAGON, 1.4, 50, AbilityId.HUSTLE, AbilityId.NONE, AbilityId.NONE, 420, 72, 85, 70, 65, 70, 58, 45, 35, 147, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.HYDREIGON, 5, false, false, false, "Brutal Pokémon", PokemonType.DARK, PokemonType.DRAGON, 1.8, 160, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 600, 92, 105, 90, 125, 90, 98, 45, 35, 300, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.LARVESTA, 5, false, false, false, "Torch Pokémon", PokemonType.BUG, PokemonType.FIRE, 1.1, 28.8, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.SWARM, 360, 55, 85, 55, 50, 55, 60, 45, 50, 72, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.VOLCARONA, 5, false, false, false, "Sun Pokémon", PokemonType.BUG, PokemonType.FIRE, 1.6, 46, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.SWARM, 550, 85, 60, 65, 135, 105, 100, 15, 50, 275, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.COBALION, 5, true, false, false, "Iron Will Pokémon", PokemonType.STEEL, PokemonType.FIGHTING, 2.1, 250, AbilityId.JUSTIFIED, AbilityId.NONE, AbilityId.NONE, 580, 91, 90, 129, 90, 72, 108, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.TERRAKION, 5, true, false, false, "Cavern Pokémon", PokemonType.ROCK, PokemonType.FIGHTING, 1.9, 260, AbilityId.JUSTIFIED, AbilityId.NONE, AbilityId.NONE, 580, 91, 129, 90, 72, 90, 108, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.VIRIZION, 5, true, false, false, "Grassland Pokémon", PokemonType.GRASS, PokemonType.FIGHTING, 2, 200, AbilityId.JUSTIFIED, AbilityId.NONE, AbilityId.NONE, 580, 91, 90, 72, 90, 129, 108, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.TORNADUS, 5, true, false, false, "Cyclone Pokémon", PokemonType.FLYING, null, 1.5, 63, AbilityId.PRANKSTER, AbilityId.NONE, AbilityId.DEFIANT, 580, 79, 115, 70, 125, 80, 111, 3, 90, 290, GrowthRate.SLOW, 100, false, true, + new PokemonForm("Incarnate Forme", "incarnate", PokemonType.FLYING, null, 1.5, 63, AbilityId.PRANKSTER, AbilityId.NONE, AbilityId.DEFIANT, 580, 79, 115, 70, 125, 80, 111, 3, 90, 290, false, null, true), + new PokemonForm("Therian Forme", "therian", PokemonType.FLYING, null, 1.4, 63, AbilityId.REGENERATOR, AbilityId.NONE, AbilityId.REGENERATOR, 580, 79, 100, 80, 110, 90, 121, 3, 90, 290) + ), + new PokemonSpecies(SpeciesId.THUNDURUS, 5, true, false, false, "Bolt Strike Pokémon", PokemonType.ELECTRIC, PokemonType.FLYING, 1.5, 61, AbilityId.PRANKSTER, AbilityId.NONE, AbilityId.DEFIANT, 580, 79, 115, 70, 125, 80, 111, 3, 90, 290, GrowthRate.SLOW, 100, false, true, + new PokemonForm("Incarnate Forme", "incarnate", PokemonType.ELECTRIC, PokemonType.FLYING, 1.5, 61, AbilityId.PRANKSTER, AbilityId.NONE, AbilityId.DEFIANT, 580, 79, 115, 70, 125, 80, 111, 3, 90, 290, false, null, true), + new PokemonForm("Therian Forme", "therian", PokemonType.ELECTRIC, PokemonType.FLYING, 3, 61, AbilityId.VOLT_ABSORB, AbilityId.NONE, AbilityId.VOLT_ABSORB, 580, 79, 105, 70, 145, 80, 101, 3, 90, 290) + ), + new PokemonSpecies(SpeciesId.RESHIRAM, 5, false, true, false, "Vast White Pokémon", PokemonType.DRAGON, PokemonType.FIRE, 3.2, 330, AbilityId.TURBOBLAZE, AbilityId.NONE, AbilityId.NONE, 680, 100, 120, 100, 150, 120, 90, 3, 0, 340, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.ZEKROM, 5, false, true, false, "Deep Black Pokémon", PokemonType.DRAGON, PokemonType.ELECTRIC, 2.9, 345, AbilityId.TERAVOLT, AbilityId.NONE, AbilityId.NONE, 680, 100, 150, 120, 120, 100, 90, 3, 0, 340, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.LANDORUS, 5, true, false, false, "Abundance Pokémon", PokemonType.GROUND, PokemonType.FLYING, 1.5, 68, AbilityId.SAND_FORCE, AbilityId.NONE, AbilityId.SHEER_FORCE, 600, 89, 125, 90, 115, 80, 101, 3, 90, 300, GrowthRate.SLOW, 100, false, true, + new PokemonForm("Incarnate Forme", "incarnate", PokemonType.GROUND, PokemonType.FLYING, 1.5, 68, AbilityId.SAND_FORCE, AbilityId.NONE, AbilityId.SHEER_FORCE, 600, 89, 125, 90, 115, 80, 101, 3, 90, 300, false, null, true), + new PokemonForm("Therian Forme", "therian", PokemonType.GROUND, PokemonType.FLYING, 1.3, 68, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.INTIMIDATE, 600, 89, 145, 90, 105, 80, 91, 3, 90, 300) + ), + new PokemonSpecies(SpeciesId.KYUREM, 5, false, true, false, "Boundary Pokémon", PokemonType.DRAGON, PokemonType.ICE, 3, 325, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 660, 125, 130, 90, 130, 90, 95, 3, 0, 330, GrowthRate.SLOW, null, false, true, + new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.ICE, 3, 325, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 660, 125, 130, 90, 130, 90, 95, 3, 0, 330, false, null, true), + new PokemonForm("Black", "black", PokemonType.DRAGON, PokemonType.ICE, 3.3, 325, AbilityId.TERAVOLT, AbilityId.NONE, AbilityId.NONE, 700, 125, 170, 100, 120, 90, 95, 3, 0, 350), + new PokemonForm("White", "white", PokemonType.DRAGON, PokemonType.ICE, 3.6, 325, AbilityId.TURBOBLAZE, AbilityId.NONE, AbilityId.NONE, 700, 125, 120, 90, 170, 100, 95, 3, 0, 350) + ), + new PokemonSpecies(SpeciesId.KELDEO, 5, false, false, true, "Colt Pokémon", PokemonType.WATER, PokemonType.FIGHTING, 1.4, 48.5, AbilityId.JUSTIFIED, AbilityId.NONE, AbilityId.NONE, 580, 91, 72, 90, 129, 90, 108, 3, 35, 290, GrowthRate.SLOW, null, false, true, + new PokemonForm("Ordinary Form", "ordinary", PokemonType.WATER, PokemonType.FIGHTING, 1.4, 48.5, AbilityId.JUSTIFIED, AbilityId.NONE, AbilityId.NONE, 580, 91, 72, 90, 129, 90, 108, 3, 35, 290, false, null, true), + new PokemonForm("Resolute", "resolute", PokemonType.WATER, PokemonType.FIGHTING, 1.4, 48.5, AbilityId.JUSTIFIED, AbilityId.NONE, AbilityId.NONE, 580, 91, 72, 90, 129, 90, 108, 3, 35, 290) + ), + new PokemonSpecies(SpeciesId.MELOETTA, 5, false, false, true, "Melody Pokémon", PokemonType.NORMAL, PokemonType.PSYCHIC, 0.6, 6.5, AbilityId.SERENE_GRACE, AbilityId.NONE, AbilityId.NONE, 600, 100, 77, 77, 128, 128, 90, 3, 100, 300, GrowthRate.SLOW, null, false, true, + new PokemonForm("Aria Forme", "aria", PokemonType.NORMAL, PokemonType.PSYCHIC, 0.6, 6.5, AbilityId.SERENE_GRACE, AbilityId.NONE, AbilityId.NONE, 600, 100, 77, 77, 128, 128, 90, 3, 100, 300, false, null, true), + new PokemonForm("Pirouette Forme", "pirouette", PokemonType.NORMAL, PokemonType.FIGHTING, 0.6, 6.5, AbilityId.SERENE_GRACE, AbilityId.NONE, AbilityId.NONE, 600, 100, 128, 90, 77, 77, 128, 3, 100, 300, false, null, true) + ), + new PokemonSpecies(SpeciesId.GENESECT, 5, false, false, true, "Paleozoic Pokémon", PokemonType.BUG, PokemonType.STEEL, 1.5, 82.5, AbilityId.DOWNLOAD, AbilityId.NONE, AbilityId.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300, GrowthRate.SLOW, null, false, true, + new PokemonForm("Normal", "", PokemonType.BUG, PokemonType.STEEL, 1.5, 82.5, AbilityId.DOWNLOAD, AbilityId.NONE, AbilityId.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300, false, null, true), + new PokemonForm("Shock Drive", "shock", PokemonType.BUG, PokemonType.STEEL, 1.5, 82.5, AbilityId.DOWNLOAD, AbilityId.NONE, AbilityId.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300), + new PokemonForm("Burn Drive", "burn", PokemonType.BUG, PokemonType.STEEL, 1.5, 82.5, AbilityId.DOWNLOAD, AbilityId.NONE, AbilityId.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300), + new PokemonForm("Chill Drive", "chill", PokemonType.BUG, PokemonType.STEEL, 1.5, 82.5, AbilityId.DOWNLOAD, AbilityId.NONE, AbilityId.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300), + new PokemonForm("Douse Drive", "douse", PokemonType.BUG, PokemonType.STEEL, 1.5, 82.5, AbilityId.DOWNLOAD, AbilityId.NONE, AbilityId.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300) + ), + new PokemonSpecies(SpeciesId.CHESPIN, 6, false, false, false, "Spiny Nut Pokémon", PokemonType.GRASS, null, 0.4, 9, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.BULLETPROOF, 313, 56, 61, 65, 48, 45, 38, 45, 70, 63, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.QUILLADIN, 6, false, false, false, "Spiny Armor Pokémon", PokemonType.GRASS, null, 0.7, 29, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.BULLETPROOF, 405, 61, 78, 95, 56, 58, 57, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.CHESNAUGHT, 6, false, false, false, "Spiny Armor Pokémon", PokemonType.GRASS, PokemonType.FIGHTING, 1.6, 90, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.BULLETPROOF, 530, 88, 107, 122, 74, 75, 64, 45, 70, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.FENNEKIN, 6, false, false, false, "Fox Pokémon", PokemonType.FIRE, null, 0.4, 9.4, AbilityId.BLAZE, AbilityId.NONE, AbilityId.MAGICIAN, 307, 40, 45, 40, 62, 60, 60, 45, 70, 61, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.BRAIXEN, 6, false, false, false, "Fox Pokémon", PokemonType.FIRE, null, 1, 14.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.MAGICIAN, 409, 59, 59, 58, 90, 70, 73, 45, 70, 143, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.DELPHOX, 6, false, false, false, "Fox Pokémon", PokemonType.FIRE, PokemonType.PSYCHIC, 1.5, 39, AbilityId.BLAZE, AbilityId.NONE, AbilityId.MAGICIAN, 534, 75, 69, 72, 114, 100, 104, 45, 70, 267, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.FROAKIE, 6, false, false, false, "Bubble Frog Pokémon", PokemonType.WATER, null, 0.3, 7, AbilityId.TORRENT, AbilityId.NONE, AbilityId.PROTEAN, 314, 41, 56, 40, 62, 44, 71, 45, 70, 63, GrowthRate.MEDIUM_SLOW, 87.5, false, false, + new PokemonForm("Normal", "", PokemonType.WATER, null, 0.3, 7, AbilityId.TORRENT, AbilityId.NONE, AbilityId.PROTEAN, 314, 41, 56, 40, 62, 44, 71, 45, 70, 63, false, null, true), + new PokemonForm("Battle Bond", "battle-bond", PokemonType.WATER, null, 0.3, 7, AbilityId.TORRENT, AbilityId.NONE, AbilityId.TORRENT, 314, 41, 56, 40, 62, 44, 71, 45, 70, 63, false, "", true) + ), + new PokemonSpecies(SpeciesId.FROGADIER, 6, false, false, false, "Bubble Frog Pokémon", PokemonType.WATER, null, 0.6, 10.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.PROTEAN, 405, 54, 63, 52, 83, 56, 97, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false, false, + new PokemonForm("Normal", "", PokemonType.WATER, null, 0.6, 10.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.PROTEAN, 405, 54, 63, 52, 83, 56, 97, 45, 70, 142, false, null, true), + new PokemonForm("Battle Bond", "battle-bond", PokemonType.WATER, null, 0.6, 10.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.NONE, 405, 54, 63, 52, 83, 56, 97, 45, 70, 142, false, "", true) + ), + new PokemonSpecies(SpeciesId.GRENINJA, 6, false, false, false, "Ninja Pokémon", PokemonType.WATER, PokemonType.DARK, 1.5, 40, AbilityId.TORRENT, AbilityId.NONE, AbilityId.PROTEAN, 530, 72, 95, 67, 103, 71, 122, 45, 70, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, false, + new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.DARK, 1.5, 40, AbilityId.TORRENT, AbilityId.NONE, AbilityId.PROTEAN, 530, 72, 95, 67, 103, 71, 122, 45, 70, 265, false, null, true), + new PokemonForm("Battle Bond", "battle-bond", PokemonType.WATER, PokemonType.DARK, 1.5, 40, AbilityId.BATTLE_BOND, AbilityId.NONE, AbilityId.BATTLE_BOND, 530, 72, 95, 67, 103, 71, 122, 45, 70, 265, false, "", true), + new PokemonForm("Ash", "ash", PokemonType.WATER, PokemonType.DARK, 1.5, 40, AbilityId.BATTLE_BOND, AbilityId.NONE, AbilityId.NONE, 640, 72, 145, 67, 153, 71, 132, 45, 70, 265) + ), + new PokemonSpecies(SpeciesId.BUNNELBY, 6, false, false, false, "Digging Pokémon", PokemonType.NORMAL, null, 0.4, 5, AbilityId.PICKUP, AbilityId.CHEEK_POUCH, AbilityId.HUGE_POWER, 237, 38, 36, 38, 32, 36, 57, 255, 50, 47, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DIGGERSBY, 6, false, false, false, "Digging Pokémon", PokemonType.NORMAL, PokemonType.GROUND, 1, 42.4, AbilityId.PICKUP, AbilityId.CHEEK_POUCH, AbilityId.HUGE_POWER, 423, 85, 56, 77, 50, 77, 78, 127, 50, 148, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.FLETCHLING, 6, false, false, false, "Tiny Robin Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 1.7, AbilityId.BIG_PECKS, AbilityId.NONE, AbilityId.GALE_WINGS, 278, 45, 50, 43, 40, 38, 62, 255, 50, 56, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.FLETCHINDER, 6, false, false, false, "Ember Pokémon", PokemonType.FIRE, PokemonType.FLYING, 0.7, 16, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.GALE_WINGS, 382, 62, 73, 55, 56, 52, 84, 120, 50, 134, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.TALONFLAME, 6, false, false, false, "Scorching Pokémon", PokemonType.FIRE, PokemonType.FLYING, 1.2, 24.5, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.GALE_WINGS, 499, 78, 81, 71, 74, 69, 126, 45, 50, 175, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SCATTERBUG, 6, false, false, false, "Scatterdust Pokémon", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Meadow Pattern", "meadow", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Icy Snow Pattern", "icy-snow", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Polar Pattern", "polar", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Tundra Pattern", "tundra", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Continental Pattern", "continental", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Garden Pattern", "garden", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Elegant Pattern", "elegant", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Modern Pattern", "modern", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Marine Pattern", "marine", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Archipelago Pattern", "archipelago", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("High Plains Pattern", "high-plains", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Sandstorm Pattern", "sandstorm", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("River Pattern", "river", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Monsoon Pattern", "monsoon", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Savanna Pattern", "savanna", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Sun Pattern", "sun", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Ocean Pattern", "ocean", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Jungle Pattern", "jungle", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Fancy Pattern", "fancy", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), + new PokemonForm("Poké Ball Pattern", "poke-ball", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true) + ), + new PokemonSpecies(SpeciesId.SPEWPA, 6, false, false, false, "Scatterdust Pokémon", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.SHED_SKIN, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Meadow Pattern", "meadow", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Icy Snow Pattern", "icy-snow", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Polar Pattern", "polar", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Tundra Pattern", "tundra", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Continental Pattern", "continental", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Garden Pattern", "garden", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Elegant Pattern", "elegant", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Modern Pattern", "modern", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Marine Pattern", "marine", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Archipelago Pattern", "archipelago", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("High Plains Pattern", "high-plains", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Sandstorm Pattern", "sandstorm", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("River Pattern", "river", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Monsoon Pattern", "monsoon", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Savanna Pattern", "savanna", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Sun Pattern", "sun", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Ocean Pattern", "ocean", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Jungle Pattern", "jungle", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Fancy Pattern", "fancy", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), + new PokemonForm("Poké Ball Pattern", "poke-ball", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true) + ), + new PokemonSpecies(SpeciesId.VIVILLON, 6, false, false, false, "Scale Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Meadow Pattern", "meadow", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Icy Snow Pattern", "icy-snow", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Polar Pattern", "polar", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Tundra Pattern", "tundra", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Continental Pattern", "continental", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Garden Pattern", "garden", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Elegant Pattern", "elegant", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Modern Pattern", "modern", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Marine Pattern", "marine", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Archipelago Pattern", "archipelago", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("High Plains Pattern", "high-plains", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Sandstorm Pattern", "sandstorm", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("River Pattern", "river", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Monsoon Pattern", "monsoon", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Savanna Pattern", "savanna", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Sun Pattern", "sun", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Ocean Pattern", "ocean", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Jungle Pattern", "jungle", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Fancy Pattern", "fancy", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), + new PokemonForm("Poké Ball Pattern", "poke-ball", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true) + ), + new PokemonSpecies(SpeciesId.LITLEO, 6, false, false, false, "Lion Cub Pokémon", PokemonType.FIRE, PokemonType.NORMAL, 0.6, 13.5, AbilityId.RIVALRY, AbilityId.UNNERVE, AbilityId.MOXIE, 369, 62, 50, 58, 73, 54, 72, 220, 70, 74, GrowthRate.MEDIUM_SLOW, 12.5, false), + new PokemonSpecies(SpeciesId.PYROAR, 6, false, false, false, "Royal Pokémon", PokemonType.FIRE, PokemonType.NORMAL, 1.5, 81.5, AbilityId.RIVALRY, AbilityId.UNNERVE, AbilityId.MOXIE, 507, 86, 68, 72, 109, 66, 106, 65, 70, 177, GrowthRate.MEDIUM_SLOW, 12.5, true), + new PokemonSpecies(SpeciesId.FLABEBE, 6, false, false, false, "Single Bloom Pokémon", PokemonType.FAIRY, null, 0.1, 0.1, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 303, 44, 38, 39, 61, 79, 42, 225, 70, 61, GrowthRate.MEDIUM_FAST, 0, false, false, + new PokemonForm("Red Flower", "red", PokemonType.FAIRY, null, 0.1, 0.1, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 303, 44, 38, 39, 61, 79, 42, 225, 70, 61, false, null, true), + new PokemonForm("Yellow Flower", "yellow", PokemonType.FAIRY, null, 0.1, 0.1, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 303, 44, 38, 39, 61, 79, 42, 225, 70, 61, false, null, true), + new PokemonForm("Orange Flower", "orange", PokemonType.FAIRY, null, 0.1, 0.1, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 303, 44, 38, 39, 61, 79, 42, 225, 70, 61, false, null, true), + new PokemonForm("Blue Flower", "blue", PokemonType.FAIRY, null, 0.1, 0.1, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 303, 44, 38, 39, 61, 79, 42, 225, 70, 61, false, null, true), + new PokemonForm("White Flower", "white", PokemonType.FAIRY, null, 0.1, 0.1, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 303, 44, 38, 39, 61, 79, 42, 225, 70, 61, false, null, true) + ), + new PokemonSpecies(SpeciesId.FLOETTE, 6, false, false, false, "Single Bloom Pokémon", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 371, 54, 45, 47, 75, 98, 52, 120, 70, 130, GrowthRate.MEDIUM_FAST, 0, false, false, + new PokemonForm("Red Flower", "red", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 371, 54, 45, 47, 75, 98, 52, 120, 70, 130, false, null, true), + new PokemonForm("Yellow Flower", "yellow", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 371, 54, 45, 47, 75, 98, 52, 120, 70, 130, false, null, true), + new PokemonForm("Orange Flower", "orange", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 371, 54, 45, 47, 75, 98, 52, 120, 70, 130, false, null, true), + new PokemonForm("Blue Flower", "blue", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 371, 54, 45, 47, 75, 98, 52, 120, 70, 130, false, null, true), + new PokemonForm("White Flower", "white", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 371, 54, 45, 47, 75, 98, 52, 120, 70, 130, false, null, true) + ), + new PokemonSpecies(SpeciesId.FLORGES, 6, false, false, false, "Garden Pokémon", PokemonType.FAIRY, null, 1.1, 10, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 552, 78, 65, 68, 112, 154, 75, 45, 70, 276, GrowthRate.MEDIUM_FAST, 0, false, false, + new PokemonForm("Red Flower", "red", PokemonType.FAIRY, null, 1.1, 10, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 552, 78, 65, 68, 112, 154, 75, 45, 70, 276, false, null, true), + new PokemonForm("Yellow Flower", "yellow", PokemonType.FAIRY, null, 1.1, 10, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 552, 78, 65, 68, 112, 154, 75, 45, 70, 276, false, null, true), + new PokemonForm("Orange Flower", "orange", PokemonType.FAIRY, null, 1.1, 10, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 552, 78, 65, 68, 112, 154, 75, 45, 70, 276, false, null, true), + new PokemonForm("Blue Flower", "blue", PokemonType.FAIRY, null, 1.1, 10, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 552, 78, 65, 68, 112, 154, 75, 45, 70, 276, false, null, true), + new PokemonForm("White Flower", "white", PokemonType.FAIRY, null, 1.1, 10, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 552, 78, 65, 68, 112, 154, 75, 45, 70, 276, false, null, true) + ), + new PokemonSpecies(SpeciesId.SKIDDO, 6, false, false, false, "Mount Pokémon", PokemonType.GRASS, null, 0.9, 31, AbilityId.SAP_SIPPER, AbilityId.NONE, AbilityId.GRASS_PELT, 350, 66, 65, 48, 62, 57, 52, 200, 70, 70, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GOGOAT, 6, false, false, false, "Mount Pokémon", PokemonType.GRASS, null, 1.7, 91, AbilityId.SAP_SIPPER, AbilityId.NONE, AbilityId.GRASS_PELT, 531, 123, 100, 62, 97, 81, 68, 45, 70, 186, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PANCHAM, 6, false, false, false, "Playful Pokémon", PokemonType.FIGHTING, null, 0.6, 8, AbilityId.IRON_FIST, AbilityId.MOLD_BREAKER, AbilityId.SCRAPPY, 348, 67, 82, 62, 46, 48, 43, 220, 50, 70, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PANGORO, 6, false, false, false, "Daunting Pokémon", PokemonType.FIGHTING, PokemonType.DARK, 2.1, 136, AbilityId.IRON_FIST, AbilityId.MOLD_BREAKER, AbilityId.SCRAPPY, 495, 95, 124, 78, 69, 71, 58, 65, 50, 173, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.FURFROU, 6, false, false, false, "Poodle Pokémon", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Natural Form", "", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), + new PokemonForm("Heart Trim", "heart", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), + new PokemonForm("Star Trim", "star", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), + new PokemonForm("Diamond Trim", "diamond", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), + new PokemonForm("Debutante Trim", "debutante", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), + new PokemonForm("Matron Trim", "matron", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), + new PokemonForm("Dandy Trim", "dandy", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), + new PokemonForm("La Reine Trim", "la-reine", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), + new PokemonForm("Kabuki Trim", "kabuki", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), + new PokemonForm("Pharaoh Trim", "pharaoh", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true) + ), + new PokemonSpecies(SpeciesId.ESPURR, 6, false, false, false, "Restraint Pokémon", PokemonType.PSYCHIC, null, 0.3, 3.5, AbilityId.KEEN_EYE, AbilityId.INFILTRATOR, AbilityId.OWN_TEMPO, 355, 62, 48, 54, 63, 60, 68, 190, 50, 71, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MEOWSTIC, 6, false, false, false, "Constraint Pokémon", PokemonType.PSYCHIC, null, 0.6, 8.5, AbilityId.KEEN_EYE, AbilityId.INFILTRATOR, AbilityId.PRANKSTER, 466, 74, 48, 76, 83, 81, 104, 75, 50, 163, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Male", "male", PokemonType.PSYCHIC, null, 0.6, 8.5, AbilityId.KEEN_EYE, AbilityId.INFILTRATOR, AbilityId.PRANKSTER, 466, 74, 48, 76, 83, 81, 104, 75, 50, 163, false, "", true), + new PokemonForm("Female", "female", PokemonType.PSYCHIC, null, 0.6, 8.5, AbilityId.KEEN_EYE, AbilityId.INFILTRATOR, AbilityId.COMPETITIVE, 466, 74, 48, 76, 83, 81, 104, 75, 50, 163, false, null, true) + ), + new PokemonSpecies(SpeciesId.HONEDGE, 6, false, false, false, "Sword Pokémon", PokemonType.STEEL, PokemonType.GHOST, 0.8, 2, AbilityId.NO_GUARD, AbilityId.NONE, AbilityId.NONE, 325, 45, 80, 100, 35, 37, 28, 180, 50, 65, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DOUBLADE, 6, false, false, false, "Sword Pokémon", PokemonType.STEEL, PokemonType.GHOST, 0.8, 4.5, AbilityId.NO_GUARD, AbilityId.NONE, AbilityId.NONE, 448, 59, 110, 150, 45, 49, 35, 90, 50, 157, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.AEGISLASH, 6, false, false, false, "Royal Sword Pokémon", PokemonType.STEEL, PokemonType.GHOST, 1.7, 53, AbilityId.STANCE_CHANGE, AbilityId.NONE, AbilityId.NONE, 500, 60, 50, 140, 50, 140, 60, 45, 50, 250, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Shield Forme", "shield", PokemonType.STEEL, PokemonType.GHOST, 1.7, 53, AbilityId.STANCE_CHANGE, AbilityId.NONE, AbilityId.NONE, 500, 60, 50, 140, 50, 140, 60, 45, 50, 250, false, "", true), + new PokemonForm("Blade Forme", "blade", PokemonType.STEEL, PokemonType.GHOST, 1.7, 53, AbilityId.STANCE_CHANGE, AbilityId.NONE, AbilityId.NONE, 500, 60, 140, 50, 140, 50, 60, 45, 50, 250) + ), + new PokemonSpecies(SpeciesId.SPRITZEE, 6, false, false, false, "Perfume Pokémon", PokemonType.FAIRY, null, 0.2, 0.5, AbilityId.HEALER, AbilityId.NONE, AbilityId.AROMA_VEIL, 341, 78, 52, 60, 63, 65, 23, 200, 50, 68, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.AROMATISSE, 6, false, false, false, "Fragrance Pokémon", PokemonType.FAIRY, null, 0.8, 15.5, AbilityId.HEALER, AbilityId.NONE, AbilityId.AROMA_VEIL, 462, 101, 72, 72, 99, 89, 29, 140, 50, 162, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SWIRLIX, 6, false, false, false, "Cotton Candy Pokémon", PokemonType.FAIRY, null, 0.4, 3.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.UNBURDEN, 341, 62, 48, 66, 59, 57, 49, 200, 50, 68, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SLURPUFF, 6, false, false, false, "Meringue Pokémon", PokemonType.FAIRY, null, 0.8, 5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.UNBURDEN, 480, 82, 80, 86, 85, 75, 72, 140, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.INKAY, 6, false, false, false, "Revolving Pokémon", PokemonType.DARK, PokemonType.PSYCHIC, 0.4, 3.5, AbilityId.CONTRARY, AbilityId.SUCTION_CUPS, AbilityId.INFILTRATOR, 288, 53, 54, 53, 37, 46, 45, 190, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MALAMAR, 6, false, false, false, "Overturning Pokémon", PokemonType.DARK, PokemonType.PSYCHIC, 1.5, 47, AbilityId.CONTRARY, AbilityId.SUCTION_CUPS, AbilityId.INFILTRATOR, 482, 86, 92, 88, 68, 75, 73, 80, 50, 169, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BINACLE, 6, false, false, false, "Two-Handed Pokémon", PokemonType.ROCK, PokemonType.WATER, 0.5, 31, AbilityId.TOUGH_CLAWS, AbilityId.SNIPER, AbilityId.PICKPOCKET, 306, 42, 52, 67, 39, 56, 50, 120, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BARBARACLE, 6, false, false, false, "Collective Pokémon", PokemonType.ROCK, PokemonType.WATER, 1.3, 96, AbilityId.TOUGH_CLAWS, AbilityId.SNIPER, AbilityId.PICKPOCKET, 500, 72, 105, 115, 54, 86, 68, 45, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SKRELP, 6, false, false, false, "Mock Kelp Pokémon", PokemonType.POISON, PokemonType.WATER, 0.5, 7.3, AbilityId.POISON_POINT, AbilityId.POISON_TOUCH, AbilityId.ADAPTABILITY, 320, 50, 60, 60, 60, 60, 30, 225, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DRAGALGE, 6, false, false, false, "Mock Kelp Pokémon", PokemonType.POISON, PokemonType.DRAGON, 1.8, 81.5, AbilityId.POISON_POINT, AbilityId.POISON_TOUCH, AbilityId.ADAPTABILITY, 494, 65, 75, 90, 97, 123, 44, 55, 50, 173, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CLAUNCHER, 6, false, false, false, "Water Gun Pokémon", PokemonType.WATER, null, 0.5, 8.3, AbilityId.MEGA_LAUNCHER, AbilityId.NONE, AbilityId.NONE, 330, 50, 53, 62, 58, 63, 44, 225, 50, 66, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.CLAWITZER, 6, false, false, false, "Howitzer Pokémon", PokemonType.WATER, null, 1.3, 35.3, AbilityId.MEGA_LAUNCHER, AbilityId.NONE, AbilityId.NONE, 500, 71, 73, 88, 120, 89, 59, 55, 50, 100, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.HELIOPTILE, 6, false, false, false, "Generator Pokémon", PokemonType.ELECTRIC, PokemonType.NORMAL, 0.5, 6, AbilityId.DRY_SKIN, AbilityId.SAND_VEIL, AbilityId.SOLAR_POWER, 289, 44, 38, 33, 61, 43, 70, 190, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.HELIOLISK, 6, false, false, false, "Generator Pokémon", PokemonType.ELECTRIC, PokemonType.NORMAL, 1, 21, AbilityId.DRY_SKIN, AbilityId.SAND_VEIL, AbilityId.SOLAR_POWER, 481, 62, 55, 52, 109, 94, 109, 75, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.TYRUNT, 6, false, false, false, "Royal Heir Pokémon", PokemonType.ROCK, PokemonType.DRAGON, 0.8, 26, AbilityId.STRONG_JAW, AbilityId.NONE, AbilityId.STURDY, 362, 58, 89, 77, 45, 45, 48, 45, 50, 72, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.TYRANTRUM, 6, false, false, false, "Despot Pokémon", PokemonType.ROCK, PokemonType.DRAGON, 2.5, 270, AbilityId.STRONG_JAW, AbilityId.NONE, AbilityId.ROCK_HEAD, 521, 82, 121, 119, 69, 59, 71, 45, 50, 182, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.AMAURA, 6, false, false, false, "Tundra Pokémon", PokemonType.ROCK, PokemonType.ICE, 1.3, 25.2, AbilityId.REFRIGERATE, AbilityId.NONE, AbilityId.SNOW_WARNING, 362, 77, 59, 50, 67, 63, 46, 45, 50, 72, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.AURORUS, 6, false, false, false, "Tundra Pokémon", PokemonType.ROCK, PokemonType.ICE, 2.7, 225, AbilityId.REFRIGERATE, AbilityId.NONE, AbilityId.SNOW_WARNING, 521, 123, 77, 72, 99, 92, 58, 45, 50, 104, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.SYLVEON, 6, false, false, false, "Intertwining Pokémon", PokemonType.FAIRY, null, 1, 23.5, AbilityId.CUTE_CHARM, AbilityId.NONE, AbilityId.PIXILATE, 525, 95, 65, 65, 110, 130, 60, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.HAWLUCHA, 6, false, false, false, "Wrestling Pokémon", PokemonType.FIGHTING, PokemonType.FLYING, 0.8, 21.5, AbilityId.LIMBER, AbilityId.UNBURDEN, AbilityId.MOLD_BREAKER, 500, 78, 92, 75, 74, 63, 118, 100, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DEDENNE, 6, false, false, false, "Antenna Pokémon", PokemonType.ELECTRIC, PokemonType.FAIRY, 0.2, 2.2, AbilityId.CHEEK_POUCH, AbilityId.PICKUP, AbilityId.PLUS, 431, 67, 58, 57, 81, 67, 101, 180, 50, 151, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CARBINK, 6, false, false, false, "Jewel Pokémon", PokemonType.ROCK, PokemonType.FAIRY, 0.3, 5.7, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.STURDY, 500, 50, 50, 150, 50, 150, 50, 60, 50, 100, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.GOOMY, 6, false, false, false, "Soft Tissue Pokémon", PokemonType.DRAGON, null, 0.3, 2.8, AbilityId.SAP_SIPPER, AbilityId.HYDRATION, AbilityId.GOOEY, 300, 45, 50, 35, 55, 75, 40, 45, 35, 60, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.SLIGGOO, 6, false, false, false, "Soft Tissue Pokémon", PokemonType.DRAGON, null, 0.8, 17.5, AbilityId.SAP_SIPPER, AbilityId.HYDRATION, AbilityId.GOOEY, 452, 68, 75, 53, 83, 113, 60, 45, 35, 158, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.GOODRA, 6, false, false, false, "Dragon Pokémon", PokemonType.DRAGON, null, 2, 150.5, AbilityId.SAP_SIPPER, AbilityId.HYDRATION, AbilityId.GOOEY, 600, 90, 100, 70, 110, 150, 80, 45, 35, 300, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.KLEFKI, 6, false, false, false, "Key Ring Pokémon", PokemonType.STEEL, PokemonType.FAIRY, 0.2, 3, AbilityId.PRANKSTER, AbilityId.NONE, AbilityId.MAGICIAN, 470, 57, 80, 91, 80, 87, 75, 75, 50, 165, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.PHANTUMP, 6, false, false, false, "Stump Pokémon", PokemonType.GHOST, PokemonType.GRASS, 0.4, 7, AbilityId.NATURAL_CURE, AbilityId.FRISK, AbilityId.HARVEST, 309, 43, 70, 48, 50, 60, 38, 120, 50, 62, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.TREVENANT, 6, false, false, false, "Elder Tree Pokémon", PokemonType.GHOST, PokemonType.GRASS, 1.5, 71, AbilityId.NATURAL_CURE, AbilityId.FRISK, AbilityId.HARVEST, 474, 85, 110, 76, 65, 82, 56, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PUMPKABOO, 6, false, false, false, "Pumpkin Pokémon", PokemonType.GHOST, PokemonType.GRASS, 0.4, 5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 335, 49, 66, 70, 44, 55, 51, 120, 50, 67, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Average Size", "", PokemonType.GHOST, PokemonType.GRASS, 0.4, 5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 335, 49, 66, 70, 44, 55, 51, 120, 50, 67, false, null, true), + new PokemonForm("Small Size", "small", PokemonType.GHOST, PokemonType.GRASS, 0.3, 3.5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 335, 44, 66, 70, 44, 55, 56, 120, 50, 67, false, "", true), + new PokemonForm("Large Size", "large", PokemonType.GHOST, PokemonType.GRASS, 0.5, 7.5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 335, 54, 66, 70, 44, 55, 46, 120, 50, 67, false, "", true), + new PokemonForm("Super Size", "super", PokemonType.GHOST, PokemonType.GRASS, 0.8, 15, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 335, 59, 66, 70, 44, 55, 41, 120, 50, 67, false, "", true) + ), + new PokemonSpecies(SpeciesId.GOURGEIST, 6, false, false, false, "Pumpkin Pokémon", PokemonType.GHOST, PokemonType.GRASS, 0.9, 12.5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 494, 65, 90, 122, 58, 75, 84, 60, 50, 173, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Average Size", "", PokemonType.GHOST, PokemonType.GRASS, 0.9, 12.5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 494, 65, 90, 122, 58, 75, 84, 60, 50, 173, false, null, true), + new PokemonForm("Small Size", "small", PokemonType.GHOST, PokemonType.GRASS, 0.7, 9.5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 494, 55, 85, 122, 58, 75, 99, 60, 50, 173, false, "", true), + new PokemonForm("Large Size", "large", PokemonType.GHOST, PokemonType.GRASS, 1.1, 14, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 494, 75, 95, 122, 58, 75, 69, 60, 50, 173, false, "", true), + new PokemonForm("Super Size", "super", PokemonType.GHOST, PokemonType.GRASS, 1.7, 39, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 494, 85, 100, 122, 58, 75, 54, 60, 50, 173, false, "", true) + ), + new PokemonSpecies(SpeciesId.BERGMITE, 6, false, false, false, "Ice Chunk Pokémon", PokemonType.ICE, null, 1, 99.5, AbilityId.OWN_TEMPO, AbilityId.ICE_BODY, AbilityId.STURDY, 304, 55, 69, 85, 32, 35, 28, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.AVALUGG, 6, false, false, false, "Iceberg Pokémon", PokemonType.ICE, null, 2, 505, AbilityId.OWN_TEMPO, AbilityId.ICE_BODY, AbilityId.STURDY, 514, 95, 117, 184, 44, 46, 28, 55, 50, 180, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.NOIBAT, 6, false, false, false, "Sound Wave Pokémon", PokemonType.FLYING, PokemonType.DRAGON, 0.5, 8, AbilityId.FRISK, AbilityId.INFILTRATOR, AbilityId.TELEPATHY, 245, 40, 30, 35, 45, 40, 55, 190, 50, 49, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.NOIVERN, 6, false, false, false, "Sound Wave Pokémon", PokemonType.FLYING, PokemonType.DRAGON, 1.5, 85, AbilityId.FRISK, AbilityId.INFILTRATOR, AbilityId.TELEPATHY, 535, 85, 70, 80, 97, 80, 123, 45, 50, 187, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.XERNEAS, 6, false, true, false, "Life Pokémon", PokemonType.FAIRY, null, 3, 215, AbilityId.FAIRY_AURA, AbilityId.NONE, AbilityId.NONE, 680, 126, 131, 95, 131, 98, 99, 45, 0, 340, GrowthRate.SLOW, null, false, true, + new PokemonForm("Neutral Mode", "neutral", PokemonType.FAIRY, null, 3, 215, AbilityId.FAIRY_AURA, AbilityId.NONE, AbilityId.NONE, 680, 126, 131, 95, 131, 98, 99, 45, 0, 340, false, null, true), + new PokemonForm("Active Mode", "active", PokemonType.FAIRY, null, 3, 215, AbilityId.FAIRY_AURA, AbilityId.NONE, AbilityId.NONE, 680, 126, 131, 95, 131, 98, 99, 45, 0, 340) + ), + new PokemonSpecies(SpeciesId.YVELTAL, 6, false, true, false, "Destruction Pokémon", PokemonType.DARK, PokemonType.FLYING, 5.8, 203, AbilityId.DARK_AURA, AbilityId.NONE, AbilityId.NONE, 680, 126, 131, 95, 131, 98, 99, 45, 0, 340, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.ZYGARDE, 6, false, true, false, "Order Pokémon", PokemonType.DRAGON, PokemonType.GROUND, 5, 305, AbilityId.AURA_BREAK, AbilityId.NONE, AbilityId.NONE, 600, 108, 100, 121, 81, 95, 95, 3, 0, 300, GrowthRate.SLOW, null, false, false, + new PokemonForm("50% Forme", "50", PokemonType.DRAGON, PokemonType.GROUND, 5, 305, AbilityId.AURA_BREAK, AbilityId.NONE, AbilityId.NONE, 600, 108, 100, 121, 81, 95, 95, 3, 0, 300, false, "", true), + new PokemonForm("10% Forme", "10", PokemonType.DRAGON, PokemonType.GROUND, 1.2, 33.5, AbilityId.AURA_BREAK, AbilityId.NONE, AbilityId.NONE, 486, 54, 100, 71, 61, 85, 115, 3, 0, 243, false, null, true), + new PokemonForm("50% Forme Power Construct", "50-pc", PokemonType.DRAGON, PokemonType.GROUND, 5, 305, AbilityId.POWER_CONSTRUCT, AbilityId.NONE, AbilityId.NONE, 600, 108, 100, 121, 81, 95, 95, 3, 0, 300, false, "", true), + new PokemonForm("10% Forme Power Construct", "10-pc", PokemonType.DRAGON, PokemonType.GROUND, 1.2, 33.5, AbilityId.POWER_CONSTRUCT, AbilityId.NONE, AbilityId.NONE, 486, 54, 100, 71, 61, 85, 115, 3, 0, 243, false, "10", true), + new PokemonForm("Complete Forme (50% PC)", "complete", PokemonType.DRAGON, PokemonType.GROUND, 4.5, 610, AbilityId.POWER_CONSTRUCT, AbilityId.NONE, AbilityId.NONE, 708, 216, 100, 121, 91, 95, 85, 3, 0, 354), + new PokemonForm("Complete Forme (10% PC)", "10-complete", PokemonType.DRAGON, PokemonType.GROUND, 4.5, 610, AbilityId.POWER_CONSTRUCT, AbilityId.NONE, AbilityId.NONE, 708, 216, 100, 121, 91, 95, 85, 3, 0, 354, false, "complete") + ), + new PokemonSpecies(SpeciesId.DIANCIE, 6, false, false, true, "Jewel Pokémon", PokemonType.ROCK, PokemonType.FAIRY, 0.7, 8.8, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.NONE, 600, 50, 100, 150, 100, 150, 50, 3, 50, 300, GrowthRate.SLOW, null, false, true, + new PokemonForm("Normal", "", PokemonType.ROCK, PokemonType.FAIRY, 0.7, 8.8, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.NONE, 600, 50, 100, 150, 100, 150, 50, 3, 50, 300, false, null, true), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.ROCK, PokemonType.FAIRY, 1.1, 27.8, AbilityId.MAGIC_BOUNCE, AbilityId.NONE, AbilityId.NONE, 700, 50, 160, 110, 160, 110, 110, 3, 50, 300) + ), + new PokemonSpecies(SpeciesId.HOOPA, 6, false, false, true, "Mischief Pokémon", PokemonType.PSYCHIC, PokemonType.GHOST, 0.5, 9, AbilityId.MAGICIAN, AbilityId.NONE, AbilityId.NONE, 600, 80, 110, 60, 150, 130, 70, 3, 100, 300, GrowthRate.SLOW, null, false, false, + new PokemonForm("Hoopa Confined", "", PokemonType.PSYCHIC, PokemonType.GHOST, 0.5, 9, AbilityId.MAGICIAN, AbilityId.NONE, AbilityId.NONE, 600, 80, 110, 60, 150, 130, 70, 3, 100, 300, false, null, true), + new PokemonForm("Hoopa Unbound", "unbound", PokemonType.PSYCHIC, PokemonType.DARK, 6.5, 490, AbilityId.MAGICIAN, AbilityId.NONE, AbilityId.NONE, 680, 80, 160, 60, 170, 130, 80, 3, 100, 340) + ), + new PokemonSpecies(SpeciesId.VOLCANION, 6, false, false, true, "Steam Pokémon", PokemonType.FIRE, PokemonType.WATER, 1.7, 195, AbilityId.WATER_ABSORB, AbilityId.NONE, AbilityId.NONE, 600, 80, 110, 120, 130, 90, 70, 3, 100, 300, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.ROWLET, 7, false, false, false, "Grass Quill Pokémon", PokemonType.GRASS, PokemonType.FLYING, 0.3, 1.5, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.LONG_REACH, 320, 68, 55, 55, 50, 50, 42, 45, 50, 64, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.DARTRIX, 7, false, false, false, "Blade Quill Pokémon", PokemonType.GRASS, PokemonType.FLYING, 0.7, 16, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.LONG_REACH, 420, 78, 75, 75, 70, 70, 52, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.DECIDUEYE, 7, false, false, false, "Arrow Quill Pokémon", PokemonType.GRASS, PokemonType.GHOST, 1.6, 36.6, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.LONG_REACH, 530, 78, 107, 75, 100, 100, 70, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.LITTEN, 7, false, false, false, "Fire Cat Pokémon", PokemonType.FIRE, null, 0.4, 4.3, AbilityId.BLAZE, AbilityId.NONE, AbilityId.INTIMIDATE, 320, 45, 65, 40, 60, 40, 70, 45, 50, 64, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.TORRACAT, 7, false, false, false, "Fire Cat Pokémon", PokemonType.FIRE, null, 0.7, 25, AbilityId.BLAZE, AbilityId.NONE, AbilityId.INTIMIDATE, 420, 65, 85, 50, 80, 50, 90, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.INCINEROAR, 7, false, false, false, "Heel Pokémon", PokemonType.FIRE, PokemonType.DARK, 1.8, 83, AbilityId.BLAZE, AbilityId.NONE, AbilityId.INTIMIDATE, 530, 95, 115, 90, 80, 90, 60, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.POPPLIO, 7, false, false, false, "Sea Lion Pokémon", PokemonType.WATER, null, 0.4, 7.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.LIQUID_VOICE, 320, 50, 54, 54, 66, 56, 40, 45, 50, 64, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.BRIONNE, 7, false, false, false, "Pop Star Pokémon", PokemonType.WATER, null, 0.6, 17.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.LIQUID_VOICE, 420, 60, 69, 69, 91, 81, 50, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.PRIMARINA, 7, false, false, false, "Soloist Pokémon", PokemonType.WATER, PokemonType.FAIRY, 1.8, 44, AbilityId.TORRENT, AbilityId.NONE, AbilityId.LIQUID_VOICE, 530, 80, 74, 74, 126, 116, 60, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.PIKIPEK, 7, false, false, false, "Woodpecker Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 1.2, AbilityId.KEEN_EYE, AbilityId.SKILL_LINK, AbilityId.PICKUP, 265, 35, 75, 30, 30, 30, 65, 255, 70, 53, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.TRUMBEAK, 7, false, false, false, "Bugle Beak Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 14.8, AbilityId.KEEN_EYE, AbilityId.SKILL_LINK, AbilityId.PICKUP, 355, 55, 85, 50, 40, 50, 75, 120, 70, 124, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.TOUCANNON, 7, false, false, false, "Cannon Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.1, 26, AbilityId.KEEN_EYE, AbilityId.SKILL_LINK, AbilityId.SHEER_FORCE, 485, 80, 120, 75, 75, 75, 60, 45, 70, 243, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.YUNGOOS, 7, false, false, false, "Loitering Pokémon", PokemonType.NORMAL, null, 0.4, 6, AbilityId.STAKEOUT, AbilityId.STRONG_JAW, AbilityId.ADAPTABILITY, 253, 48, 70, 30, 30, 30, 45, 255, 70, 51, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GUMSHOOS, 7, false, false, false, "Stakeout Pokémon", PokemonType.NORMAL, null, 0.7, 14.2, AbilityId.STAKEOUT, AbilityId.STRONG_JAW, AbilityId.ADAPTABILITY, 418, 88, 110, 60, 55, 60, 45, 127, 70, 146, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GRUBBIN, 7, false, false, false, "Larva Pokémon", PokemonType.BUG, null, 0.4, 4.4, AbilityId.SWARM, AbilityId.NONE, AbilityId.NONE, 300, 47, 62, 45, 55, 45, 46, 255, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CHARJABUG, 7, false, false, false, "Battery Pokémon", PokemonType.BUG, PokemonType.ELECTRIC, 0.5, 10.5, AbilityId.BATTERY, AbilityId.NONE, AbilityId.NONE, 400, 57, 82, 95, 55, 75, 36, 120, 50, 140, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.VIKAVOLT, 7, false, false, false, "Stag Beetle Pokémon", PokemonType.BUG, PokemonType.ELECTRIC, 1.5, 45, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 500, 77, 70, 90, 145, 75, 43, 45, 50, 250, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CRABRAWLER, 7, false, false, false, "Boxing Pokémon", PokemonType.FIGHTING, null, 0.6, 7, AbilityId.HYPER_CUTTER, AbilityId.IRON_FIST, AbilityId.ANGER_POINT, 338, 47, 82, 57, 42, 47, 63, 225, 70, 68, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CRABOMINABLE, 7, false, false, false, "Woolly Crab Pokémon", PokemonType.FIGHTING, PokemonType.ICE, 1.7, 180, AbilityId.HYPER_CUTTER, AbilityId.IRON_FIST, AbilityId.ANGER_POINT, 478, 97, 132, 77, 62, 67, 43, 60, 70, 167, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ORICORIO, 7, false, false, false, "Dancing Pokémon", PokemonType.FIRE, PokemonType.FLYING, 0.6, 3.4, AbilityId.DANCER, AbilityId.NONE, AbilityId.NONE, 476, 75, 70, 70, 98, 70, 93, 45, 70, 167, GrowthRate.MEDIUM_FAST, 25, false, false, + new PokemonForm("Baile Style", "baile", PokemonType.FIRE, PokemonType.FLYING, 0.6, 3.4, AbilityId.DANCER, AbilityId.NONE, AbilityId.NONE, 476, 75, 70, 70, 98, 70, 93, 45, 70, 167, false, "", true), + new PokemonForm("Pom-Pom Style", "pompom", PokemonType.ELECTRIC, PokemonType.FLYING, 0.6, 3.4, AbilityId.DANCER, AbilityId.NONE, AbilityId.NONE, 476, 75, 70, 70, 98, 70, 93, 45, 70, 167, false, null, true), + new PokemonForm("Pau Style", "pau", PokemonType.PSYCHIC, PokemonType.FLYING, 0.6, 3.4, AbilityId.DANCER, AbilityId.NONE, AbilityId.NONE, 476, 75, 70, 70, 98, 70, 93, 45, 70, 167, false, null, true), + new PokemonForm("Sensu Style", "sensu", PokemonType.GHOST, PokemonType.FLYING, 0.6, 3.4, AbilityId.DANCER, AbilityId.NONE, AbilityId.NONE, 476, 75, 70, 70, 98, 70, 93, 45, 70, 167, false, null, true) + ), + new PokemonSpecies(SpeciesId.CUTIEFLY, 7, false, false, false, "Bee Fly Pokémon", PokemonType.BUG, PokemonType.FAIRY, 0.1, 0.2, AbilityId.HONEY_GATHER, AbilityId.SHIELD_DUST, AbilityId.SWEET_VEIL, 304, 40, 45, 40, 55, 40, 84, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.RIBOMBEE, 7, false, false, false, "Bee Fly Pokémon", PokemonType.BUG, PokemonType.FAIRY, 0.2, 0.5, AbilityId.HONEY_GATHER, AbilityId.SHIELD_DUST, AbilityId.SWEET_VEIL, 464, 60, 55, 60, 95, 70, 124, 75, 50, 162, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ROCKRUFF, 7, false, false, false, "Puppy Pokémon", PokemonType.ROCK, null, 0.5, 9.2, AbilityId.KEEN_EYE, AbilityId.VITAL_SPIRIT, AbilityId.STEADFAST, 280, 45, 65, 40, 30, 40, 60, 190, 50, 56, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Normal", "", PokemonType.ROCK, null, 0.5, 9.2, AbilityId.KEEN_EYE, AbilityId.VITAL_SPIRIT, AbilityId.STEADFAST, 280, 45, 65, 40, 30, 40, 60, 190, 50, 56, false, null, true), + new PokemonForm("Own Tempo", "own-tempo", PokemonType.ROCK, null, 0.5, 9.2, AbilityId.OWN_TEMPO, AbilityId.NONE, AbilityId.OWN_TEMPO, 280, 45, 65, 40, 30, 40, 60, 190, 50, 56, false, "", true) + ), + new PokemonSpecies(SpeciesId.LYCANROC, 7, false, false, false, "Wolf Pokémon", PokemonType.ROCK, null, 0.8, 25, AbilityId.KEEN_EYE, AbilityId.SAND_RUSH, AbilityId.STEADFAST, 487, 75, 115, 65, 55, 65, 112, 90, 50, 170, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Midday Form", "midday", PokemonType.ROCK, null, 0.8, 25, AbilityId.KEEN_EYE, AbilityId.SAND_RUSH, AbilityId.STEADFAST, 487, 75, 115, 65, 55, 65, 112, 90, 50, 170, false, "", true), + new PokemonForm("Midnight Form", "midnight", PokemonType.ROCK, null, 1.1, 25, AbilityId.KEEN_EYE, AbilityId.VITAL_SPIRIT, AbilityId.NO_GUARD, 487, 85, 115, 75, 55, 75, 82, 90, 50, 170, false, null, true), + new PokemonForm("Dusk Form", "dusk", PokemonType.ROCK, null, 0.8, 25, AbilityId.TOUGH_CLAWS, AbilityId.TOUGH_CLAWS, AbilityId.TOUGH_CLAWS, 487, 75, 117, 65, 55, 65, 110, 90, 50, 170, false, null, true) + ), + new PokemonSpecies(SpeciesId.WISHIWASHI, 7, false, false, false, "Small Fry Pokémon", PokemonType.WATER, null, 0.2, 0.3, AbilityId.SCHOOLING, AbilityId.NONE, AbilityId.NONE, 175, 45, 20, 20, 25, 25, 40, 60, 50, 61, GrowthRate.FAST, 50, false, false, + new PokemonForm("Solo Form", "", PokemonType.WATER, null, 0.2, 0.3, AbilityId.SCHOOLING, AbilityId.NONE, AbilityId.NONE, 175, 45, 20, 20, 25, 25, 40, 60, 50, 61, false, null, true), + new PokemonForm("School", "school", PokemonType.WATER, null, 8.2, 78.6, AbilityId.SCHOOLING, AbilityId.NONE, AbilityId.NONE, 620, 45, 140, 130, 140, 135, 30, 60, 50, 217) + ), + new PokemonSpecies(SpeciesId.MAREANIE, 7, false, false, false, "Brutal Star Pokémon", PokemonType.POISON, PokemonType.WATER, 0.4, 8, AbilityId.MERCILESS, AbilityId.LIMBER, AbilityId.REGENERATOR, 305, 50, 53, 62, 43, 52, 45, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.TOXAPEX, 7, false, false, false, "Brutal Star Pokémon", PokemonType.POISON, PokemonType.WATER, 0.7, 14.5, AbilityId.MERCILESS, AbilityId.LIMBER, AbilityId.REGENERATOR, 495, 50, 63, 152, 53, 142, 35, 75, 50, 173, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MUDBRAY, 7, false, false, false, "Donkey Pokémon", PokemonType.GROUND, null, 1, 110, AbilityId.OWN_TEMPO, AbilityId.STAMINA, AbilityId.INNER_FOCUS, 385, 70, 100, 70, 45, 55, 45, 190, 50, 77, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MUDSDALE, 7, false, false, false, "Draft Horse Pokémon", PokemonType.GROUND, null, 2.5, 920, AbilityId.OWN_TEMPO, AbilityId.STAMINA, AbilityId.INNER_FOCUS, 500, 100, 125, 100, 55, 85, 35, 60, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DEWPIDER, 7, false, false, false, "Water Bubble Pokémon", PokemonType.WATER, PokemonType.BUG, 0.3, 4, AbilityId.WATER_BUBBLE, AbilityId.NONE, AbilityId.WATER_ABSORB, 269, 38, 40, 52, 40, 72, 27, 200, 50, 54, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ARAQUANID, 7, false, false, false, "Water Bubble Pokémon", PokemonType.WATER, PokemonType.BUG, 1.8, 82, AbilityId.WATER_BUBBLE, AbilityId.NONE, AbilityId.WATER_ABSORB, 454, 68, 70, 92, 50, 132, 42, 100, 50, 159, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.FOMANTIS, 7, false, false, false, "Sickle Grass Pokémon", PokemonType.GRASS, null, 0.3, 1.5, AbilityId.LEAF_GUARD, AbilityId.NONE, AbilityId.CONTRARY, 250, 40, 55, 35, 50, 35, 35, 190, 50, 50, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.LURANTIS, 7, false, false, false, "Bloom Sickle Pokémon", PokemonType.GRASS, null, 0.9, 18.5, AbilityId.LEAF_GUARD, AbilityId.NONE, AbilityId.CONTRARY, 480, 70, 105, 90, 80, 90, 45, 75, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MORELULL, 7, false, false, false, "Illuminating Pokémon", PokemonType.GRASS, PokemonType.FAIRY, 0.2, 1.5, AbilityId.ILLUMINATE, AbilityId.EFFECT_SPORE, AbilityId.RAIN_DISH, 285, 40, 35, 55, 65, 75, 15, 190, 50, 57, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SHIINOTIC, 7, false, false, false, "Illuminating Pokémon", PokemonType.GRASS, PokemonType.FAIRY, 1, 11.5, AbilityId.ILLUMINATE, AbilityId.EFFECT_SPORE, AbilityId.RAIN_DISH, 405, 60, 45, 80, 90, 100, 30, 75, 50, 142, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SALANDIT, 7, false, false, false, "Toxic Lizard Pokémon", PokemonType.POISON, PokemonType.FIRE, 0.6, 4.8, AbilityId.CORROSION, AbilityId.NONE, AbilityId.OBLIVIOUS, 320, 48, 44, 40, 71, 40, 77, 120, 50, 64, GrowthRate.MEDIUM_FAST, 87.5, false), + new PokemonSpecies(SpeciesId.SALAZZLE, 7, false, false, false, "Toxic Lizard Pokémon", PokemonType.POISON, PokemonType.FIRE, 1.2, 22.2, AbilityId.CORROSION, AbilityId.NONE, AbilityId.OBLIVIOUS, 480, 68, 64, 60, 111, 60, 117, 45, 50, 168, GrowthRate.MEDIUM_FAST, 0, false), + new PokemonSpecies(SpeciesId.STUFFUL, 7, false, false, false, "Flailing Pokémon", PokemonType.NORMAL, PokemonType.FIGHTING, 0.5, 6.8, AbilityId.FLUFFY, AbilityId.KLUTZ, AbilityId.CUTE_CHARM, 340, 70, 75, 50, 45, 50, 50, 140, 50, 68, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BEWEAR, 7, false, false, false, "Strong Arm Pokémon", PokemonType.NORMAL, PokemonType.FIGHTING, 2.1, 135, AbilityId.FLUFFY, AbilityId.KLUTZ, AbilityId.UNNERVE, 500, 120, 125, 80, 55, 60, 60, 70, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BOUNSWEET, 7, false, false, false, "Fruit Pokémon", PokemonType.GRASS, null, 0.3, 3.2, AbilityId.LEAF_GUARD, AbilityId.OBLIVIOUS, AbilityId.SWEET_VEIL, 210, 42, 30, 38, 30, 38, 32, 235, 50, 42, GrowthRate.MEDIUM_SLOW, 0, false), + new PokemonSpecies(SpeciesId.STEENEE, 7, false, false, false, "Fruit Pokémon", PokemonType.GRASS, null, 0.7, 8.2, AbilityId.LEAF_GUARD, AbilityId.OBLIVIOUS, AbilityId.SWEET_VEIL, 290, 52, 40, 48, 40, 48, 62, 120, 50, 102, GrowthRate.MEDIUM_SLOW, 0, false), + new PokemonSpecies(SpeciesId.TSAREENA, 7, false, false, false, "Fruit Pokémon", PokemonType.GRASS, null, 1.2, 21.4, AbilityId.LEAF_GUARD, AbilityId.QUEENLY_MAJESTY, AbilityId.SWEET_VEIL, 510, 72, 120, 98, 50, 98, 72, 45, 50, 255, GrowthRate.MEDIUM_SLOW, 0, false), + new PokemonSpecies(SpeciesId.COMFEY, 7, false, false, false, "Posy Picker Pokémon", PokemonType.FAIRY, null, 0.1, 0.3, AbilityId.FLOWER_VEIL, AbilityId.TRIAGE, AbilityId.NATURAL_CURE, 485, 51, 52, 90, 82, 110, 100, 60, 50, 170, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.ORANGURU, 7, false, false, false, "Sage Pokémon", PokemonType.NORMAL, PokemonType.PSYCHIC, 1.5, 76, AbilityId.INNER_FOCUS, AbilityId.TELEPATHY, AbilityId.SYMBIOSIS, 490, 90, 60, 80, 90, 110, 60, 45, 50, 172, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.PASSIMIAN, 7, false, false, false, "Teamwork Pokémon", PokemonType.FIGHTING, null, 2, 82.8, AbilityId.RECEIVER, AbilityId.NONE, AbilityId.DEFIANT, 490, 100, 120, 90, 40, 60, 80, 45, 50, 172, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.WIMPOD, 7, false, false, false, "Turn Tail Pokémon", PokemonType.BUG, PokemonType.WATER, 0.5, 12, AbilityId.WIMP_OUT, AbilityId.NONE, AbilityId.RUN_AWAY, 230, 25, 35, 40, 20, 30, 80, 90, 50, 46, GrowthRate.MEDIUM_FAST, 50, false), //Custom Hidden + new PokemonSpecies(SpeciesId.GOLISOPOD, 7, false, false, false, "Hard Scale Pokémon", PokemonType.BUG, PokemonType.WATER, 2, 108, AbilityId.EMERGENCY_EXIT, AbilityId.NONE, AbilityId.ANTICIPATION, 530, 75, 125, 140, 60, 90, 40, 45, 50, 186, GrowthRate.MEDIUM_FAST, 50, false), //Custom Hidden + new PokemonSpecies(SpeciesId.SANDYGAST, 7, false, false, false, "Sand Heap Pokémon", PokemonType.GHOST, PokemonType.GROUND, 0.5, 70, AbilityId.WATER_COMPACTION, AbilityId.NONE, AbilityId.SAND_VEIL, 320, 55, 55, 80, 70, 45, 15, 140, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PALOSSAND, 7, false, false, false, "Sand Castle Pokémon", PokemonType.GHOST, PokemonType.GROUND, 1.3, 250, AbilityId.WATER_COMPACTION, AbilityId.NONE, AbilityId.SAND_VEIL, 480, 85, 75, 110, 100, 75, 35, 60, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PYUKUMUKU, 7, false, false, false, "Sea Cucumber Pokémon", PokemonType.WATER, null, 0.3, 1.2, AbilityId.INNARDS_OUT, AbilityId.NONE, AbilityId.UNAWARE, 410, 55, 60, 130, 30, 130, 5, 60, 50, 144, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.TYPE_NULL, 7, true, false, false, "Synthetic Pokémon", PokemonType.NORMAL, null, 1.9, 120.5, AbilityId.BATTLE_ARMOR, AbilityId.NONE, AbilityId.NONE, 534, 95, 95, 95, 95, 95, 59, 3, 0, 107, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.SILVALLY, 7, true, false, false, "Synthetic Pokémon", PokemonType.NORMAL, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285, GrowthRate.SLOW, null, false, false, + new PokemonForm("Type: Normal", "normal", PokemonType.NORMAL, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285, false, "", true), + new PokemonForm("Type: Fighting", "fighting", PokemonType.FIGHTING, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Flying", "flying", PokemonType.FLYING, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Poison", "poison", PokemonType.POISON, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Ground", "ground", PokemonType.GROUND, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Rock", "rock", PokemonType.ROCK, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Bug", "bug", PokemonType.BUG, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Ghost", "ghost", PokemonType.GHOST, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Steel", "steel", PokemonType.STEEL, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Fire", "fire", PokemonType.FIRE, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Water", "water", PokemonType.WATER, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Grass", "grass", PokemonType.GRASS, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Electric", "electric", PokemonType.ELECTRIC, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Psychic", "psychic", PokemonType.PSYCHIC, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Ice", "ice", PokemonType.ICE, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Dragon", "dragon", PokemonType.DRAGON, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Dark", "dark", PokemonType.DARK, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), + new PokemonForm("Type: Fairy", "fairy", PokemonType.FAIRY, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285) + ), + new PokemonSpecies(SpeciesId.MINIOR, 7, false, false, false, "Meteor Pokémon", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, GrowthRate.MEDIUM_SLOW, null, false, false, + new PokemonForm("Red Meteor Form", "red-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), + new PokemonForm("Orange Meteor Form", "orange-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), + new PokemonForm("Yellow Meteor Form", "yellow-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), + new PokemonForm("Green Meteor Form", "green-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), + new PokemonForm("Blue Meteor Form", "blue-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), + new PokemonForm("Indigo Meteor Form", "indigo-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), + new PokemonForm("Violet Meteor Form", "violet-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), + new PokemonForm("Red Core Form", "red", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true), + new PokemonForm("Orange Core Form", "orange", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true), + new PokemonForm("Yellow Core Form", "yellow", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true), + new PokemonForm("Green Core Form", "green", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true), + new PokemonForm("Blue Core Form", "blue", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true), + new PokemonForm("Indigo Core Form", "indigo", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true), + new PokemonForm("Violet Core Form", "violet", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true) + ), + new PokemonSpecies(SpeciesId.KOMALA, 7, false, false, false, "Drowsing Pokémon", PokemonType.NORMAL, null, 0.4, 19.9, AbilityId.COMATOSE, AbilityId.NONE, AbilityId.NONE, 480, 65, 115, 65, 75, 95, 65, 45, 70, 168, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.TURTONATOR, 7, false, false, false, "Blast Turtle Pokémon", PokemonType.FIRE, PokemonType.DRAGON, 2, 212, AbilityId.SHELL_ARMOR, AbilityId.NONE, AbilityId.NONE, 485, 60, 78, 135, 91, 85, 36, 70, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.TOGEDEMARU, 7, false, false, false, "Roly-Poly Pokémon", PokemonType.ELECTRIC, PokemonType.STEEL, 0.3, 3.3, AbilityId.IRON_BARBS, AbilityId.LIGHTNING_ROD, AbilityId.STURDY, 435, 65, 98, 63, 40, 73, 96, 180, 50, 152, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MIMIKYU, 7, false, false, false, "Disguise Pokémon", PokemonType.GHOST, PokemonType.FAIRY, 0.2, 0.7, AbilityId.DISGUISE, AbilityId.NONE, AbilityId.NONE, 476, 55, 90, 80, 50, 105, 96, 45, 50, 167, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Disguised Form", "disguised", PokemonType.GHOST, PokemonType.FAIRY, 0.2, 0.7, AbilityId.DISGUISE, AbilityId.NONE, AbilityId.NONE, 476, 55, 90, 80, 50, 105, 96, 45, 50, 167, false, null, true), + new PokemonForm("Busted Form", "busted", PokemonType.GHOST, PokemonType.FAIRY, 0.2, 0.7, AbilityId.DISGUISE, AbilityId.NONE, AbilityId.NONE, 476, 55, 90, 80, 50, 105, 96, 45, 50, 167) + ), + new PokemonSpecies(SpeciesId.BRUXISH, 7, false, false, false, "Gnash Teeth Pokémon", PokemonType.WATER, PokemonType.PSYCHIC, 0.9, 19, AbilityId.DAZZLING, AbilityId.STRONG_JAW, AbilityId.WONDER_SKIN, 475, 68, 105, 70, 70, 70, 92, 80, 70, 166, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DRAMPA, 7, false, false, false, "Placid Pokémon", PokemonType.NORMAL, PokemonType.DRAGON, 3, 185, AbilityId.BERSERK, AbilityId.SAP_SIPPER, AbilityId.CLOUD_NINE, 485, 78, 60, 85, 135, 91, 36, 70, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DHELMISE, 7, false, false, false, "Sea Creeper Pokémon", PokemonType.GHOST, PokemonType.GRASS, 3.9, 210, AbilityId.STEELWORKER, AbilityId.NONE, AbilityId.NONE, 517, 70, 131, 100, 86, 90, 40, 25, 50, 181, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.JANGMO_O, 7, false, false, false, "Scaly Pokémon", PokemonType.DRAGON, null, 0.6, 29.7, AbilityId.BULLETPROOF, AbilityId.SOUNDPROOF, AbilityId.OVERCOAT, 300, 45, 55, 65, 45, 45, 45, 45, 50, 60, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.HAKAMO_O, 7, false, false, false, "Scaly Pokémon", PokemonType.DRAGON, PokemonType.FIGHTING, 1.2, 47, AbilityId.BULLETPROOF, AbilityId.SOUNDPROOF, AbilityId.OVERCOAT, 420, 55, 75, 90, 65, 70, 65, 45, 50, 147, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.KOMMO_O, 7, false, false, false, "Scaly Pokémon", PokemonType.DRAGON, PokemonType.FIGHTING, 1.6, 78.2, AbilityId.BULLETPROOF, AbilityId.SOUNDPROOF, AbilityId.OVERCOAT, 600, 75, 110, 125, 100, 105, 85, 45, 50, 300, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.TAPU_KOKO, 7, true, false, false, "Land Spirit Pokémon", PokemonType.ELECTRIC, PokemonType.FAIRY, 1.8, 20.5, AbilityId.ELECTRIC_SURGE, AbilityId.NONE, AbilityId.TELEPATHY, 570, 70, 115, 85, 95, 75, 130, 3, 50, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.TAPU_LELE, 7, true, false, false, "Land Spirit Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 1.2, 18.6, AbilityId.PSYCHIC_SURGE, AbilityId.NONE, AbilityId.TELEPATHY, 570, 70, 85, 75, 130, 115, 95, 3, 50, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.TAPU_BULU, 7, true, false, false, "Land Spirit Pokémon", PokemonType.GRASS, PokemonType.FAIRY, 1.9, 45.5, AbilityId.GRASSY_SURGE, AbilityId.NONE, AbilityId.TELEPATHY, 570, 70, 130, 115, 85, 95, 75, 3, 50, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.TAPU_FINI, 7, true, false, false, "Land Spirit Pokémon", PokemonType.WATER, PokemonType.FAIRY, 1.3, 21.2, AbilityId.MISTY_SURGE, AbilityId.NONE, AbilityId.TELEPATHY, 570, 70, 75, 115, 95, 130, 85, 3, 50, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.COSMOG, 7, true, false, false, "Nebula Pokémon", PokemonType.PSYCHIC, null, 0.2, 0.1, AbilityId.UNAWARE, AbilityId.NONE, AbilityId.NONE, 200, 43, 29, 31, 29, 31, 37, 3, 0, 40, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.COSMOEM, 7, true, false, false, "Protostar Pokémon", PokemonType.PSYCHIC, null, 0.1, 999.9, AbilityId.STURDY, AbilityId.NONE, AbilityId.NONE, 400, 43, 29, 131, 29, 131, 37, 3, 0, 140, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.SOLGALEO, 7, false, true, false, "Sunne Pokémon", PokemonType.PSYCHIC, PokemonType.STEEL, 3.4, 230, AbilityId.FULL_METAL_BODY, AbilityId.NONE, AbilityId.NONE, 680, 137, 137, 107, 113, 89, 97, 3, 0, 340, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.LUNALA, 7, false, true, false, "Moone Pokémon", PokemonType.PSYCHIC, PokemonType.GHOST, 4, 120, AbilityId.SHADOW_SHIELD, AbilityId.NONE, AbilityId.NONE, 680, 137, 113, 89, 137, 107, 97, 3, 0, 340, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.NIHILEGO, 7, true, false, false, "Parasite Pokémon", PokemonType.ROCK, PokemonType.POISON, 1.2, 55.5, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 109, 53, 47, 127, 131, 103, 45, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.BUZZWOLE, 7, true, false, false, "Swollen Pokémon", PokemonType.BUG, PokemonType.FIGHTING, 2.4, 333.6, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 107, 139, 139, 53, 53, 79, 45, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.PHEROMOSA, 7, true, false, false, "Lissome Pokémon", PokemonType.BUG, PokemonType.FIGHTING, 1.8, 25, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 71, 137, 37, 137, 37, 151, 45, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.XURKITREE, 7, true, false, false, "Glowing Pokémon", PokemonType.ELECTRIC, null, 3.8, 100, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 83, 89, 71, 173, 71, 83, 45, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.CELESTEELA, 7, true, false, false, "Launch Pokémon", PokemonType.STEEL, PokemonType.FLYING, 9.2, 999.9, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 97, 101, 103, 107, 101, 61, 45, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.KARTANA, 7, true, false, false, "Drawn Sword Pokémon", PokemonType.GRASS, PokemonType.STEEL, 0.3, 0.1, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 59, 181, 131, 59, 31, 109, 45, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.GUZZLORD, 7, true, false, false, "Junkivore Pokémon", PokemonType.DARK, PokemonType.DRAGON, 5.5, 888, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 223, 101, 53, 97, 53, 43, 45, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.NECROZMA, 7, false, true, false, "Prism Pokémon", PokemonType.PSYCHIC, null, 2.4, 230, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 600, 97, 107, 101, 127, 89, 79, 3, 0, 300, GrowthRate.SLOW, null, false, false, + new PokemonForm("Normal", "", PokemonType.PSYCHIC, null, 2.4, 230, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 600, 97, 107, 101, 127, 89, 79, 3, 0, 300, false, null, true), + new PokemonForm("Dusk Mane", "dusk-mane", PokemonType.PSYCHIC, PokemonType.STEEL, 3.8, 460, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 680, 97, 157, 127, 113, 109, 77, 3, 0, 340), + new PokemonForm("Dawn Wings", "dawn-wings", PokemonType.PSYCHIC, PokemonType.GHOST, 4.2, 350, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 680, 97, 113, 109, 157, 127, 77, 3, 0, 340), + new PokemonForm("Ultra", "ultra", PokemonType.PSYCHIC, PokemonType.DRAGON, 7.5, 230, AbilityId.NEUROFORCE, AbilityId.NONE, AbilityId.NONE, 754, 97, 167, 97, 167, 97, 129, 3, 0, 377) + ), + new PokemonSpecies(SpeciesId.MAGEARNA, 7, false, false, true, "Artificial Pokémon", PokemonType.STEEL, PokemonType.FAIRY, 1, 80.5, AbilityId.SOUL_HEART, AbilityId.NONE, AbilityId.NONE, 600, 80, 95, 115, 130, 115, 65, 3, 0, 300, GrowthRate.SLOW, null, false, false, + new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.FAIRY, 1, 80.5, AbilityId.SOUL_HEART, AbilityId.NONE, AbilityId.NONE, 600, 80, 95, 115, 130, 115, 65, 3, 0, 300, false, null, true), + new PokemonForm("Original", "original", PokemonType.STEEL, PokemonType.FAIRY, 1, 80.5, AbilityId.SOUL_HEART, AbilityId.NONE, AbilityId.NONE, 600, 80, 95, 115, 130, 115, 65, 3, 0, 300, false, null, true) + ), + new PokemonSpecies(SpeciesId.MARSHADOW, 7, false, false, true, "Gloomdweller Pokémon", PokemonType.FIGHTING, PokemonType.GHOST, 0.7, 22.2, AbilityId.TECHNICIAN, AbilityId.NONE, AbilityId.NONE, 600, 90, 125, 80, 90, 90, 125, 3, 0, 300, GrowthRate.SLOW, null, false, true, + new PokemonForm("Normal", "", PokemonType.FIGHTING, PokemonType.GHOST, 0.7, 22.2, AbilityId.TECHNICIAN, AbilityId.NONE, AbilityId.NONE, 600, 90, 125, 80, 90, 90, 125, 3, 0, 300, false, null, true), + new PokemonForm("Zenith", "zenith", PokemonType.FIGHTING, PokemonType.GHOST, 0.7, 22.2, AbilityId.TECHNICIAN, AbilityId.NONE, AbilityId.NONE, 600, 90, 125, 80, 90, 90, 125, 3, 0, 300, false, null, false, true) + ), + new PokemonSpecies(SpeciesId.POIPOLE, 7, true, false, false, "Poison Pin Pokémon", PokemonType.POISON, null, 0.6, 1.8, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 420, 67, 73, 67, 73, 67, 73, 45, 0, 210, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.NAGANADEL, 7, true, false, false, "Poison Pin Pokémon", PokemonType.POISON, PokemonType.DRAGON, 3.6, 150, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 540, 73, 73, 73, 127, 73, 121, 45, 0, 270, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.STAKATAKA, 7, true, false, false, "Rampart Pokémon", PokemonType.ROCK, PokemonType.STEEL, 5.5, 820, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 61, 131, 211, 53, 101, 13, 30, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.BLACEPHALON, 7, true, false, false, "Fireworks Pokémon", PokemonType.FIRE, PokemonType.GHOST, 1.8, 13, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 53, 127, 53, 151, 79, 107, 30, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.ZERAORA, 7, false, false, true, "Thunderclap Pokémon", PokemonType.ELECTRIC, null, 1.5, 44.5, AbilityId.VOLT_ABSORB, AbilityId.NONE, AbilityId.NONE, 600, 88, 112, 75, 102, 80, 143, 3, 0, 300, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.MELTAN, 7, false, false, true, "Hex Nut Pokémon", PokemonType.STEEL, null, 0.2, 8, AbilityId.MAGNET_PULL, AbilityId.NONE, AbilityId.NONE, 300, 46, 65, 65, 55, 35, 34, 3, 0, 150, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.MELMETAL, 7, false, false, true, "Hex Nut Pokémon", PokemonType.STEEL, null, 2.5, 800, AbilityId.IRON_FIST, AbilityId.NONE, AbilityId.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, GrowthRate.SLOW, null, false, true, + new PokemonForm("Normal", "", PokemonType.STEEL, null, 2.5, 800, AbilityId.IRON_FIST, AbilityId.NONE, AbilityId.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.STEEL, null, 25, 999.9, AbilityId.IRON_FIST, AbilityId.NONE, AbilityId.NONE, 700, 170, 158, 158, 95, 75, 44, 3, 0, 300) + ), + new PokemonSpecies(SpeciesId.GROOKEY, 8, false, false, false, "Chimp Pokémon", PokemonType.GRASS, null, 0.3, 5, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.GRASSY_SURGE, 310, 50, 65, 50, 40, 40, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.THWACKEY, 8, false, false, false, "Beat Pokémon", PokemonType.GRASS, null, 0.7, 14, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.GRASSY_SURGE, 420, 70, 85, 70, 55, 60, 80, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.RILLABOOM, 8, false, false, false, "Drummer Pokémon", PokemonType.GRASS, null, 2.1, 90, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, + new PokemonForm("Normal", "", PokemonType.GRASS, null, 2.1, 90, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GRASS, null, 28, 999.9, AbilityId.GRASSY_SURGE, AbilityId.NONE, AbilityId.GRASSY_SURGE, 630, 125, 140, 105, 90, 85, 85, 45, 50, 265) + ), + new PokemonSpecies(SpeciesId.SCORBUNNY, 8, false, false, false, "Rabbit Pokémon", PokemonType.FIRE, null, 0.3, 4.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.LIBERO, 310, 50, 71, 40, 40, 40, 69, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.RABOOT, 8, false, false, false, "Rabbit Pokémon", PokemonType.FIRE, null, 0.6, 9, AbilityId.BLAZE, AbilityId.NONE, AbilityId.LIBERO, 420, 65, 86, 60, 55, 60, 94, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.CINDERACE, 8, false, false, false, "Striker Pokémon", PokemonType.FIRE, null, 1.4, 33, AbilityId.BLAZE, AbilityId.NONE, AbilityId.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, + new PokemonForm("Normal", "", PokemonType.FIRE, null, 1.4, 33, AbilityId.BLAZE, AbilityId.NONE, AbilityId.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIRE, null, 27, 999.9, AbilityId.LIBERO, AbilityId.NONE, AbilityId.LIBERO, 630, 100, 141, 80, 95, 80, 134, 45, 50, 265) + ), + new PokemonSpecies(SpeciesId.SOBBLE, 8, false, false, false, "Water Lizard Pokémon", PokemonType.WATER, null, 0.3, 4, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SNIPER, 310, 50, 40, 40, 70, 40, 70, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.DRIZZILE, 8, false, false, false, "Water Lizard Pokémon", PokemonType.WATER, null, 0.7, 11.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SNIPER, 420, 65, 60, 55, 95, 55, 90, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.INTELEON, 8, false, false, false, "Secret Agent Pokémon", PokemonType.WATER, null, 1.9, 45.2, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, + new PokemonForm("Normal", "", PokemonType.WATER, null, 1.9, 45.2, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, null, 40, 999.9, AbilityId.SNIPER, AbilityId.NONE, AbilityId.SNIPER, 630, 95, 117, 67, 147, 67, 137, 45, 50, 265) + ), + new PokemonSpecies(SpeciesId.SKWOVET, 8, false, false, false, "Cheeky Pokémon", PokemonType.NORMAL, null, 0.3, 2.5, AbilityId.CHEEK_POUCH, AbilityId.NONE, AbilityId.GLUTTONY, 275, 70, 55, 55, 35, 35, 25, 255, 50, 55, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GREEDENT, 8, false, false, false, "Greedy Pokémon", PokemonType.NORMAL, null, 0.6, 6, AbilityId.CHEEK_POUCH, AbilityId.NONE, AbilityId.GLUTTONY, 460, 120, 95, 95, 55, 75, 20, 90, 50, 161, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ROOKIDEE, 8, false, false, false, "Tiny Bird Pokémon", PokemonType.FLYING, null, 0.2, 1.8, AbilityId.KEEN_EYE, AbilityId.UNNERVE, AbilityId.BIG_PECKS, 245, 38, 47, 35, 33, 35, 57, 255, 50, 49, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.CORVISQUIRE, 8, false, false, false, "Raven Pokémon", PokemonType.FLYING, null, 0.8, 16, AbilityId.KEEN_EYE, AbilityId.UNNERVE, AbilityId.BIG_PECKS, 365, 68, 67, 55, 43, 55, 77, 120, 50, 128, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.CORVIKNIGHT, 8, false, false, false, "Raven Pokémon", PokemonType.FLYING, PokemonType.STEEL, 2.2, 75, AbilityId.PRESSURE, AbilityId.UNNERVE, AbilityId.MIRROR_ARMOR, 495, 98, 87, 105, 53, 85, 67, 45, 50, 248, GrowthRate.MEDIUM_SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.FLYING, PokemonType.STEEL, 2.2, 75, AbilityId.PRESSURE, AbilityId.UNNERVE, AbilityId.MIRROR_ARMOR, 495, 98, 87, 105, 53, 85, 67, 45, 50, 248, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FLYING, PokemonType.STEEL, 14, 999.9, AbilityId.MIRROR_ARMOR, AbilityId.MIRROR_ARMOR, AbilityId.MIRROR_ARMOR, 595, 118, 112, 135, 63, 90, 77, 45, 50, 248) + ), + new PokemonSpecies(SpeciesId.BLIPBUG, 8, false, false, false, "Larva Pokémon", PokemonType.BUG, null, 0.4, 8, AbilityId.SWARM, AbilityId.COMPOUND_EYES, AbilityId.TELEPATHY, 180, 25, 20, 20, 25, 45, 45, 255, 50, 36, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DOTTLER, 8, false, false, false, "Radome Pokémon", PokemonType.BUG, PokemonType.PSYCHIC, 0.4, 19.5, AbilityId.SWARM, AbilityId.COMPOUND_EYES, AbilityId.TELEPATHY, 335, 50, 35, 80, 50, 90, 30, 120, 50, 117, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ORBEETLE, 8, false, false, false, "Seven Spot Pokémon", PokemonType.BUG, PokemonType.PSYCHIC, 0.4, 40.8, AbilityId.SWARM, AbilityId.FRISK, AbilityId.TELEPATHY, 505, 60, 45, 110, 80, 120, 90, 45, 50, 253, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.BUG, PokemonType.PSYCHIC, 0.4, 40.8, AbilityId.SWARM, AbilityId.FRISK, AbilityId.TELEPATHY, 505, 60, 45, 110, 80, 120, 90, 45, 50, 253, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.BUG, PokemonType.PSYCHIC, 14, 999.9, AbilityId.TRACE, AbilityId.TRACE, AbilityId.TRACE, 605, 75, 50, 140, 100, 150, 90, 45, 50, 253) + ), + new PokemonSpecies(SpeciesId.NICKIT, 8, false, false, false, "Fox Pokémon", PokemonType.DARK, null, 0.6, 8.9, AbilityId.RUN_AWAY, AbilityId.UNBURDEN, AbilityId.STAKEOUT, 245, 40, 28, 28, 47, 52, 50, 255, 50, 49, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.THIEVUL, 8, false, false, false, "Fox Pokémon", PokemonType.DARK, null, 1.2, 19.9, AbilityId.RUN_AWAY, AbilityId.UNBURDEN, AbilityId.STAKEOUT, 455, 70, 58, 58, 87, 92, 90, 127, 50, 159, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.GOSSIFLEUR, 8, false, false, false, "Flowering Pokémon", PokemonType.GRASS, null, 0.4, 2.2, AbilityId.COTTON_DOWN, AbilityId.REGENERATOR, AbilityId.EFFECT_SPORE, 250, 40, 40, 60, 40, 60, 10, 190, 50, 50, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ELDEGOSS, 8, false, false, false, "Cotton Bloom Pokémon", PokemonType.GRASS, null, 0.5, 2.5, AbilityId.COTTON_DOWN, AbilityId.REGENERATOR, AbilityId.EFFECT_SPORE, 460, 60, 50, 90, 80, 120, 60, 75, 50, 161, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.WOOLOO, 8, false, false, false, "Sheep Pokémon", PokemonType.NORMAL, null, 0.6, 6, AbilityId.FLUFFY, AbilityId.RUN_AWAY, AbilityId.BULLETPROOF, 270, 42, 40, 55, 40, 45, 48, 255, 50, 122, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DUBWOOL, 8, false, false, false, "Sheep Pokémon", PokemonType.NORMAL, null, 1.3, 43, AbilityId.FLUFFY, AbilityId.STEADFAST, AbilityId.BULLETPROOF, 490, 72, 80, 100, 60, 90, 88, 127, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CHEWTLE, 8, false, false, false, "Snapping Pokémon", PokemonType.WATER, null, 0.3, 8.5, AbilityId.STRONG_JAW, AbilityId.SHELL_ARMOR, AbilityId.SWIFT_SWIM, 284, 50, 64, 50, 38, 38, 44, 255, 50, 57, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DREDNAW, 8, false, false, false, "Bite Pokémon", PokemonType.WATER, PokemonType.ROCK, 1, 115.5, AbilityId.STRONG_JAW, AbilityId.SHELL_ARMOR, AbilityId.SWIFT_SWIM, 485, 90, 115, 90, 48, 68, 74, 75, 50, 170, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.ROCK, 1, 115.5, AbilityId.STRONG_JAW, AbilityId.SHELL_ARMOR, AbilityId.SWIFT_SWIM, 485, 90, 115, 90, 48, 68, 74, 75, 50, 170, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, PokemonType.ROCK, 24, 999.9, AbilityId.STRONG_JAW, AbilityId.STRONG_JAW, AbilityId.STRONG_JAW, 585, 115, 137, 115, 61, 83, 74, 75, 50, 170) + ), + new PokemonSpecies(SpeciesId.YAMPER, 8, false, false, false, "Puppy Pokémon", PokemonType.ELECTRIC, null, 0.3, 13.5, AbilityId.BALL_FETCH, AbilityId.NONE, AbilityId.RATTLED, 270, 59, 45, 50, 40, 50, 26, 255, 50, 54, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.BOLTUND, 8, false, false, false, "Dog Pokémon", PokemonType.ELECTRIC, null, 1, 34, AbilityId.STRONG_JAW, AbilityId.NONE, AbilityId.COMPETITIVE, 490, 69, 90, 60, 90, 60, 121, 45, 50, 172, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.ROLYCOLY, 8, false, false, false, "Coal Pokémon", PokemonType.ROCK, null, 0.3, 12, AbilityId.STEAM_ENGINE, AbilityId.HEATPROOF, AbilityId.FLASH_FIRE, 240, 30, 40, 50, 40, 50, 30, 255, 50, 48, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.CARKOL, 8, false, false, false, "Coal Pokémon", PokemonType.ROCK, PokemonType.FIRE, 1.1, 78, AbilityId.STEAM_ENGINE, AbilityId.FLAME_BODY, AbilityId.FLASH_FIRE, 410, 80, 60, 90, 60, 70, 50, 120, 50, 144, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.COALOSSAL, 8, false, false, false, "Coal Pokémon", PokemonType.ROCK, PokemonType.FIRE, 2.8, 310.5, AbilityId.STEAM_ENGINE, AbilityId.FLAME_BODY, AbilityId.FLASH_FIRE, 510, 110, 80, 120, 80, 90, 30, 45, 50, 255, GrowthRate.MEDIUM_SLOW, 50, false, true, + new PokemonForm("Normal", "", PokemonType.ROCK, PokemonType.FIRE, 2.8, 310.5, AbilityId.STEAM_ENGINE, AbilityId.FLAME_BODY, AbilityId.FLASH_FIRE, 510, 110, 80, 120, 80, 90, 30, 45, 50, 255, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.ROCK, PokemonType.FIRE, 42, 999.9, AbilityId.STEAM_ENGINE, AbilityId.STEAM_ENGINE, AbilityId.STEAM_ENGINE, 610, 140, 100, 132, 95, 100, 43, 45, 50, 255) + ), + new PokemonSpecies(SpeciesId.APPLIN, 8, false, false, false, "Apple Core Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 0.2, 0.5, AbilityId.RIPEN, AbilityId.GLUTTONY, AbilityId.BULLETPROOF, 260, 40, 40, 80, 40, 40, 20, 255, 50, 52, GrowthRate.ERRATIC, 50, false), + new PokemonSpecies(SpeciesId.FLAPPLE, 8, false, false, false, "Apple Wing Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 0.3, 1, AbilityId.RIPEN, AbilityId.GLUTTONY, AbilityId.HUSTLE, 485, 70, 110, 80, 95, 60, 70, 45, 50, 170, GrowthRate.ERRATIC, 50, false, true, + new PokemonForm("Normal", "", PokemonType.GRASS, PokemonType.DRAGON, 0.3, 1, AbilityId.RIPEN, AbilityId.GLUTTONY, AbilityId.HUSTLE, 485, 70, 110, 80, 95, 60, 70, 45, 50, 170, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GRASS, PokemonType.DRAGON, 24, 999.9, AbilityId.HUSTLE, AbilityId.HUSTLE, AbilityId.HUSTLE, 585, 100, 125, 90, 105, 70, 95, 45, 50, 170) + ), + new PokemonSpecies(SpeciesId.APPLETUN, 8, false, false, false, "Apple Nectar Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 0.4, 13, AbilityId.RIPEN, AbilityId.GLUTTONY, AbilityId.THICK_FAT, 485, 110, 85, 80, 100, 80, 30, 45, 50, 170, GrowthRate.ERRATIC, 50, false, true, + new PokemonForm("Normal", "", PokemonType.GRASS, PokemonType.DRAGON, 0.4, 13, AbilityId.RIPEN, AbilityId.GLUTTONY, AbilityId.THICK_FAT, 485, 110, 85, 80, 100, 80, 30, 45, 50, 170, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GRASS, PokemonType.DRAGON, 24, 999.9, AbilityId.THICK_FAT, AbilityId.THICK_FAT, AbilityId.THICK_FAT, 585, 150, 100, 95, 115, 95, 30, 45, 50, 170) + ), + new PokemonSpecies(SpeciesId.SILICOBRA, 8, false, false, false, "Sand Snake Pokémon", PokemonType.GROUND, null, 2.2, 7.6, AbilityId.SAND_SPIT, AbilityId.SHED_SKIN, AbilityId.SAND_VEIL, 315, 52, 57, 75, 35, 50, 46, 255, 50, 63, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SANDACONDA, 8, false, false, false, "Sand Snake Pokémon", PokemonType.GROUND, null, 3.8, 65.5, AbilityId.SAND_SPIT, AbilityId.SHED_SKIN, AbilityId.SAND_VEIL, 510, 72, 107, 125, 65, 70, 71, 120, 50, 179, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.GROUND, null, 3.8, 65.5, AbilityId.SAND_SPIT, AbilityId.SHED_SKIN, AbilityId.SAND_VEIL, 510, 72, 107, 125, 65, 70, 71, 120, 50, 179, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GROUND, null, 22, 999.9, AbilityId.SAND_SPIT, AbilityId.SAND_SPIT, AbilityId.SAND_SPIT, 610, 102, 137, 140, 70, 80, 81, 120, 50, 179) + ), + new PokemonSpecies(SpeciesId.CRAMORANT, 8, false, false, false, "Gulp Pokémon", PokemonType.FLYING, PokemonType.WATER, 0.8, 18, AbilityId.GULP_MISSILE, AbilityId.NONE, AbilityId.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Normal", "", PokemonType.FLYING, PokemonType.WATER, 0.8, 18, AbilityId.GULP_MISSILE, AbilityId.NONE, AbilityId.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166, false, null, true), + new PokemonForm("Gulping Form", "gulping", PokemonType.FLYING, PokemonType.WATER, 0.8, 18, AbilityId.GULP_MISSILE, AbilityId.NONE, AbilityId.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166), + new PokemonForm("Gorging Form", "gorging", PokemonType.FLYING, PokemonType.WATER, 0.8, 18, AbilityId.GULP_MISSILE, AbilityId.NONE, AbilityId.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166) + ), + new PokemonSpecies(SpeciesId.ARROKUDA, 8, false, false, false, "Rush Pokémon", PokemonType.WATER, null, 0.5, 1, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.PROPELLER_TAIL, 280, 41, 63, 40, 40, 30, 66, 255, 50, 56, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.BARRASKEWDA, 8, false, false, false, "Skewer Pokémon", PokemonType.WATER, null, 1.3, 30, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.PROPELLER_TAIL, 490, 61, 123, 60, 60, 50, 136, 60, 50, 172, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.TOXEL, 8, false, false, false, "Baby Pokémon", PokemonType.ELECTRIC, PokemonType.POISON, 0.4, 11, AbilityId.RATTLED, AbilityId.STATIC, AbilityId.KLUTZ, 242, 40, 38, 35, 54, 35, 40, 75, 50, 48, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.TOXTRICITY, 8, false, false, false, "Punk Pokémon", PokemonType.ELECTRIC, PokemonType.POISON, 1.6, 40, AbilityId.PUNK_ROCK, AbilityId.PLUS, AbilityId.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, GrowthRate.MEDIUM_SLOW, 50, false, true, + new PokemonForm("Amped Form", "amped", PokemonType.ELECTRIC, PokemonType.POISON, 1.6, 40, AbilityId.PUNK_ROCK, AbilityId.PLUS, AbilityId.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, false, "", true), + new PokemonForm("Low-Key Form", "lowkey", PokemonType.ELECTRIC, PokemonType.POISON, 1.6, 40, AbilityId.PUNK_ROCK, AbilityId.MINUS, AbilityId.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, false, "lowkey", true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.ELECTRIC, PokemonType.POISON, 24, 999.9, AbilityId.PUNK_ROCK, AbilityId.PUNK_ROCK, AbilityId.PUNK_ROCK, 602, 114, 105, 82, 137, 82, 82, 45, 50, 176) + ), + new PokemonSpecies(SpeciesId.SIZZLIPEDE, 8, false, false, false, "Radiator Pokémon", PokemonType.FIRE, PokemonType.BUG, 0.7, 1, AbilityId.FLASH_FIRE, AbilityId.WHITE_SMOKE, AbilityId.FLAME_BODY, 305, 50, 65, 45, 50, 50, 45, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CENTISKORCH, 8, false, false, false, "Radiator Pokémon", PokemonType.FIRE, PokemonType.BUG, 3, 120, AbilityId.FLASH_FIRE, AbilityId.WHITE_SMOKE, AbilityId.FLAME_BODY, 525, 100, 115, 65, 90, 90, 65, 75, 50, 184, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.FIRE, PokemonType.BUG, 3, 120, AbilityId.FLASH_FIRE, AbilityId.WHITE_SMOKE, AbilityId.FLAME_BODY, 525, 100, 115, 65, 90, 90, 65, 75, 50, 184, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIRE, PokemonType.BUG, 75, 999.9, AbilityId.FLASH_FIRE, AbilityId.FLASH_FIRE, AbilityId.FLASH_FIRE, 625, 130, 125, 75, 94, 100, 101, 75, 50, 184) + ), + new PokemonSpecies(SpeciesId.CLOBBOPUS, 8, false, false, false, "Tantrum Pokémon", PokemonType.FIGHTING, null, 0.6, 4, AbilityId.LIMBER, AbilityId.NONE, AbilityId.TECHNICIAN, 310, 50, 68, 60, 50, 50, 32, 180, 50, 62, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.GRAPPLOCT, 8, false, false, false, "Jujitsu Pokémon", PokemonType.FIGHTING, null, 1.6, 39, AbilityId.LIMBER, AbilityId.NONE, AbilityId.TECHNICIAN, 480, 80, 118, 90, 70, 80, 42, 45, 50, 168, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SINISTEA, 8, false, false, false, "Black Tea Pokémon", PokemonType.GHOST, null, 0.1, 0.2, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, GrowthRate.MEDIUM_FAST, null, false, false, + new PokemonForm("Phony Form", "phony", PokemonType.GHOST, null, 0.1, 0.2, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, "", true), + new PokemonForm("Antique Form", "antique", PokemonType.GHOST, null, 0.1, 0.2, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, "", true) + ), + new PokemonSpecies(SpeciesId.POLTEAGEIST, 8, false, false, false, "Black Tea Pokémon", PokemonType.GHOST, null, 0.2, 0.4, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 508, 60, 65, 65, 134, 114, 70, 60, 50, 178, GrowthRate.MEDIUM_FAST, null, false, false, + new PokemonForm("Phony Form", "phony", PokemonType.GHOST, null, 0.2, 0.4, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 508, 60, 65, 65, 134, 114, 70, 60, 50, 178, false, "", true), + new PokemonForm("Antique Form", "antique", PokemonType.GHOST, null, 0.2, 0.4, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 508, 60, 65, 65, 134, 114, 70, 60, 50, 178, false, "", true) + ), + new PokemonSpecies(SpeciesId.HATENNA, 8, false, false, false, "Calm Pokémon", PokemonType.PSYCHIC, null, 0.4, 3.4, AbilityId.HEALER, AbilityId.ANTICIPATION, AbilityId.MAGIC_BOUNCE, 265, 42, 30, 45, 56, 53, 39, 235, 50, 53, GrowthRate.SLOW, 0, false), + new PokemonSpecies(SpeciesId.HATTREM, 8, false, false, false, "Serene Pokémon", PokemonType.PSYCHIC, null, 0.6, 4.8, AbilityId.HEALER, AbilityId.ANTICIPATION, AbilityId.MAGIC_BOUNCE, 370, 57, 40, 65, 86, 73, 49, 120, 50, 130, GrowthRate.SLOW, 0, false), + new PokemonSpecies(SpeciesId.HATTERENE, 8, false, false, false, "Silent Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 2.1, 5.1, AbilityId.HEALER, AbilityId.ANTICIPATION, AbilityId.MAGIC_BOUNCE, 510, 57, 90, 95, 136, 103, 29, 45, 50, 255, GrowthRate.SLOW, 0, false, true, + new PokemonForm("Normal", "", PokemonType.PSYCHIC, PokemonType.FAIRY, 2.1, 5.1, AbilityId.HEALER, AbilityId.ANTICIPATION, AbilityId.MAGIC_BOUNCE, 510, 57, 90, 95, 136, 103, 29, 45, 50, 255, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.PSYCHIC, PokemonType.FAIRY, 26, 999.9, AbilityId.MAGIC_BOUNCE, AbilityId.MAGIC_BOUNCE, AbilityId.MAGIC_BOUNCE, 610, 87, 100, 110, 146, 118, 49, 45, 50, 255) + ), + new PokemonSpecies(SpeciesId.IMPIDIMP, 8, false, false, false, "Wily Pokémon", PokemonType.DARK, PokemonType.FAIRY, 0.4, 5.5, AbilityId.PRANKSTER, AbilityId.FRISK, AbilityId.PICKPOCKET, 265, 45, 45, 30, 55, 40, 50, 255, 50, 53, GrowthRate.MEDIUM_FAST, 100, false), + new PokemonSpecies(SpeciesId.MORGREM, 8, false, false, false, "Devious Pokémon", PokemonType.DARK, PokemonType.FAIRY, 0.8, 12.5, AbilityId.PRANKSTER, AbilityId.FRISK, AbilityId.PICKPOCKET, 370, 65, 60, 45, 75, 55, 70, 120, 50, 130, GrowthRate.MEDIUM_FAST, 100, false), + new PokemonSpecies(SpeciesId.GRIMMSNARL, 8, false, false, false, "Bulk Up Pokémon", PokemonType.DARK, PokemonType.FAIRY, 1.5, 61, AbilityId.PRANKSTER, AbilityId.FRISK, AbilityId.PICKPOCKET, 510, 95, 120, 65, 95, 75, 60, 45, 50, 255, GrowthRate.MEDIUM_FAST, 100, false, true, + new PokemonForm("Normal", "", PokemonType.DARK, PokemonType.FAIRY, 1.5, 61, AbilityId.PRANKSTER, AbilityId.FRISK, AbilityId.PICKPOCKET, 510, 95, 120, 65, 95, 75, 60, 45, 50, 255, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.DARK, PokemonType.FAIRY, 32, 999.9, AbilityId.PRANKSTER, AbilityId.PRANKSTER, AbilityId.PRANKSTER, 610, 130, 138, 75, 110, 92, 65, 45, 50, 255) + ), + new PokemonSpecies(SpeciesId.OBSTAGOON, 8, false, false, false, "Blocking Pokémon", PokemonType.DARK, PokemonType.NORMAL, 1.6, 46, AbilityId.RECKLESS, AbilityId.GUTS, AbilityId.DEFIANT, 520, 93, 90, 101, 60, 81, 95, 45, 50, 260, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PERRSERKER, 8, false, false, false, "Viking Pokémon", PokemonType.STEEL, null, 0.8, 28, AbilityId.BATTLE_ARMOR, AbilityId.TOUGH_CLAWS, AbilityId.STEELY_SPIRIT, 440, 70, 110, 100, 50, 60, 50, 90, 50, 154, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CURSOLA, 8, false, false, false, "Coral Pokémon", PokemonType.GHOST, null, 1, 0.4, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.PERISH_BODY, 510, 60, 95, 50, 145, 130, 30, 30, 50, 179, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.SIRFETCHD, 8, false, false, false, "Wild Duck Pokémon", PokemonType.FIGHTING, null, 0.8, 117, AbilityId.STEADFAST, AbilityId.NONE, AbilityId.SCRAPPY, 507, 62, 135, 95, 68, 82, 65, 45, 50, 177, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MR_RIME, 8, false, false, false, "Comedian Pokémon", PokemonType.ICE, PokemonType.PSYCHIC, 1.5, 58.2, AbilityId.TANGLED_FEET, AbilityId.SCREEN_CLEANER, AbilityId.ICE_BODY, 520, 80, 85, 75, 110, 100, 70, 45, 50, 182, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.RUNERIGUS, 8, false, false, false, "Grudge Pokémon", PokemonType.GROUND, PokemonType.GHOST, 1.6, 66.6, AbilityId.WANDERING_SPIRIT, AbilityId.NONE, AbilityId.NONE, 483, 58, 95, 145, 50, 105, 30, 90, 50, 169, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.MILCERY, 8, false, false, false, "Cream Pokémon", PokemonType.FAIRY, null, 0.2, 0.3, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 270, 45, 40, 40, 50, 61, 34, 200, 50, 54, GrowthRate.MEDIUM_FAST, 0, false), + new PokemonSpecies(SpeciesId.ALCREMIE, 8, false, false, false, "Cream Pokémon", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, GrowthRate.MEDIUM_FAST, 0, false, true, + new PokemonForm("Vanilla Cream", "vanilla-cream", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, "", true), + new PokemonForm("Ruby Cream", "ruby-cream", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), + new PokemonForm("Matcha Cream", "matcha-cream", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), + new PokemonForm("Mint Cream", "mint-cream", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), + new PokemonForm("Lemon Cream", "lemon-cream", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), + new PokemonForm("Salted Cream", "salted-cream", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), + new PokemonForm("Ruby Swirl", "ruby-swirl", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), + new PokemonForm("Caramel Swirl", "caramel-swirl", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), + new PokemonForm("Rainbow Swirl", "rainbow-swirl", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FAIRY, null, 30, 999.9, AbilityId.MISTY_SURGE, AbilityId.NONE, AbilityId.MISTY_SURGE, 595, 105, 70, 85, 130, 141, 64, 100, 50, 173) + ), + new PokemonSpecies(SpeciesId.FALINKS, 8, false, false, false, "Formation Pokémon", PokemonType.FIGHTING, null, 3, 62, AbilityId.BATTLE_ARMOR, AbilityId.NONE, AbilityId.DEFIANT, 470, 65, 100, 100, 70, 60, 75, 45, 50, 165, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.PINCURCHIN, 8, false, false, false, "Sea Urchin Pokémon", PokemonType.ELECTRIC, null, 0.3, 1, AbilityId.LIGHTNING_ROD, AbilityId.NONE, AbilityId.ELECTRIC_SURGE, 435, 48, 101, 95, 91, 85, 15, 75, 50, 152, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SNOM, 8, false, false, false, "Worm Pokémon", PokemonType.ICE, PokemonType.BUG, 0.3, 3.8, AbilityId.SHIELD_DUST, AbilityId.NONE, AbilityId.ICE_SCALES, 185, 30, 25, 35, 45, 30, 20, 190, 50, 37, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.FROSMOTH, 8, false, false, false, "Frost Moth Pokémon", PokemonType.ICE, PokemonType.BUG, 1.3, 42, AbilityId.SHIELD_DUST, AbilityId.NONE, AbilityId.ICE_SCALES, 475, 70, 65, 60, 125, 90, 65, 75, 50, 166, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.STONJOURNER, 8, false, false, false, "Big Rock Pokémon", PokemonType.ROCK, null, 2.5, 520, AbilityId.POWER_SPOT, AbilityId.NONE, AbilityId.NONE, 470, 100, 125, 135, 20, 20, 70, 60, 50, 165, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.EISCUE, 8, false, false, false, "Penguin Pokémon", PokemonType.ICE, null, 1.4, 89, AbilityId.ICE_FACE, AbilityId.NONE, AbilityId.NONE, 470, 75, 80, 110, 65, 90, 50, 60, 50, 165, GrowthRate.SLOW, 50, false, false, + new PokemonForm("Ice Face", "", PokemonType.ICE, null, 1.4, 89, AbilityId.ICE_FACE, AbilityId.NONE, AbilityId.NONE, 470, 75, 80, 110, 65, 90, 50, 60, 50, 165, false, null, true), + new PokemonForm("No Ice", "no-ice", PokemonType.ICE, null, 1.4, 89, AbilityId.ICE_FACE, AbilityId.NONE, AbilityId.NONE, 470, 75, 80, 70, 65, 50, 130, 60, 50, 165) + ), + new PokemonSpecies(SpeciesId.INDEEDEE, 8, false, false, false, "Emotion Pokémon", PokemonType.PSYCHIC, PokemonType.NORMAL, 0.9, 28, AbilityId.INNER_FOCUS, AbilityId.SYNCHRONIZE, AbilityId.PSYCHIC_SURGE, 475, 60, 65, 55, 105, 95, 95, 30, 140, 166, GrowthRate.FAST, 50, false, false, + new PokemonForm("Male", "male", PokemonType.PSYCHIC, PokemonType.NORMAL, 0.9, 28, AbilityId.INNER_FOCUS, AbilityId.SYNCHRONIZE, AbilityId.PSYCHIC_SURGE, 475, 60, 65, 55, 105, 95, 95, 30, 140, 166, false, "", true), + new PokemonForm("Female", "female", PokemonType.PSYCHIC, PokemonType.NORMAL, 0.9, 28, AbilityId.OWN_TEMPO, AbilityId.SYNCHRONIZE, AbilityId.PSYCHIC_SURGE, 475, 70, 55, 65, 95, 105, 85, 30, 140, 166, false, null, true) + ), + new PokemonSpecies(SpeciesId.MORPEKO, 8, false, false, false, "Two-Sided Pokémon", PokemonType.ELECTRIC, PokemonType.DARK, 0.3, 3, AbilityId.HUNGER_SWITCH, AbilityId.NONE, AbilityId.NONE, 436, 58, 95, 58, 70, 58, 97, 180, 50, 153, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Full Belly Mode", "full-belly", PokemonType.ELECTRIC, PokemonType.DARK, 0.3, 3, AbilityId.HUNGER_SWITCH, AbilityId.NONE, AbilityId.NONE, 436, 58, 95, 58, 70, 58, 97, 180, 50, 153, false, "", true), + new PokemonForm("Hangry Mode", "hangry", PokemonType.ELECTRIC, PokemonType.DARK, 0.3, 3, AbilityId.HUNGER_SWITCH, AbilityId.NONE, AbilityId.NONE, 436, 58, 95, 58, 70, 58, 97, 180, 50, 153) + ), + new PokemonSpecies(SpeciesId.CUFANT, 8, false, false, false, "Copperderm Pokémon", PokemonType.STEEL, null, 1.2, 100, AbilityId.SHEER_FORCE, AbilityId.NONE, AbilityId.HEAVY_METAL, 330, 72, 80, 49, 40, 49, 40, 190, 50, 66, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.COPPERAJAH, 8, false, false, false, "Copperderm Pokémon", PokemonType.STEEL, null, 3, 650, AbilityId.SHEER_FORCE, AbilityId.NONE, AbilityId.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.STEEL, null, 3, 650, AbilityId.SHEER_FORCE, AbilityId.NONE, AbilityId.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.STEEL, PokemonType.GROUND, 23, 999.9, AbilityId.MOLD_BREAKER, AbilityId.NONE, AbilityId.MOLD_BREAKER, 600, 177, 155, 79, 90, 79, 20, 90, 50, 175) + ), + new PokemonSpecies(SpeciesId.DRACOZOLT, 8, false, false, false, "Fossil Pokémon", PokemonType.ELECTRIC, PokemonType.DRAGON, 1.8, 190, AbilityId.VOLT_ABSORB, AbilityId.HUSTLE, AbilityId.SAND_RUSH, 505, 90, 100, 90, 80, 70, 75, 45, 50, 177, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.ARCTOZOLT, 8, false, false, false, "Fossil Pokémon", PokemonType.ELECTRIC, PokemonType.ICE, 2.3, 150, AbilityId.VOLT_ABSORB, AbilityId.STATIC, AbilityId.SLUSH_RUSH, 505, 90, 100, 90, 90, 80, 55, 45, 50, 177, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.DRACOVISH, 8, false, false, false, "Fossil Pokémon", PokemonType.WATER, PokemonType.DRAGON, 2.3, 215, AbilityId.WATER_ABSORB, AbilityId.STRONG_JAW, AbilityId.SAND_RUSH, 505, 90, 90, 100, 70, 80, 75, 45, 50, 177, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.ARCTOVISH, 8, false, false, false, "Fossil Pokémon", PokemonType.WATER, PokemonType.ICE, 2, 175, AbilityId.WATER_ABSORB, AbilityId.ICE_BODY, AbilityId.SLUSH_RUSH, 505, 90, 90, 100, 80, 90, 55, 45, 50, 177, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.DURALUDON, 8, false, false, false, "Alloy Pokémon", PokemonType.STEEL, PokemonType.DRAGON, 1.8, 40, AbilityId.LIGHT_METAL, AbilityId.HEAVY_METAL, AbilityId.STALWART, 535, 70, 95, 115, 120, 50, 85, 45, 50, 187, GrowthRate.MEDIUM_FAST, 50, false, true, + new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.DRAGON, 1.8, 40, AbilityId.LIGHT_METAL, AbilityId.HEAVY_METAL, AbilityId.STALWART, 535, 70, 95, 115, 120, 50, 85, 45, 50, 187, false, null, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.STEEL, PokemonType.DRAGON, 43, 999.9, AbilityId.LIGHTNING_ROD, AbilityId.LIGHTNING_ROD, AbilityId.LIGHTNING_ROD, 635, 100, 110, 120, 175, 60, 70, 45, 50, 187) + ), + new PokemonSpecies(SpeciesId.DREEPY, 8, false, false, false, "Lingering Pokémon", PokemonType.DRAGON, PokemonType.GHOST, 0.5, 2, AbilityId.CLEAR_BODY, AbilityId.INFILTRATOR, AbilityId.CURSED_BODY, 270, 28, 60, 30, 40, 30, 82, 45, 50, 54, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.DRAKLOAK, 8, false, false, false, "Caretaker Pokémon", PokemonType.DRAGON, PokemonType.GHOST, 1.4, 11, AbilityId.CLEAR_BODY, AbilityId.INFILTRATOR, AbilityId.CURSED_BODY, 410, 68, 80, 50, 60, 50, 102, 45, 50, 144, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.DRAGAPULT, 8, false, false, false, "Stealth Pokémon", PokemonType.DRAGON, PokemonType.GHOST, 3, 50, AbilityId.CLEAR_BODY, AbilityId.INFILTRATOR, AbilityId.CURSED_BODY, 600, 88, 120, 75, 100, 75, 142, 45, 50, 300, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.ZACIAN, 8, false, true, false, "Warrior Pokémon", PokemonType.FAIRY, null, 2.8, 110, AbilityId.INTREPID_SWORD, AbilityId.NONE, AbilityId.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, GrowthRate.SLOW, null, false, false, + new PokemonForm("Hero of Many Battles", "hero-of-many-battles", PokemonType.FAIRY, null, 2.8, 110, AbilityId.INTREPID_SWORD, AbilityId.NONE, AbilityId.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, false, "", true), + new PokemonForm("Crowned", "crowned", PokemonType.FAIRY, PokemonType.STEEL, 2.8, 355, AbilityId.INTREPID_SWORD, AbilityId.NONE, AbilityId.NONE, 700, 92, 150, 115, 80, 115, 148, 10, 0, 360) + ), + new PokemonSpecies(SpeciesId.ZAMAZENTA, 8, false, true, false, "Warrior Pokémon", PokemonType.FIGHTING, null, 2.9, 210, AbilityId.DAUNTLESS_SHIELD, AbilityId.NONE, AbilityId.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, GrowthRate.SLOW, null, false, false, + new PokemonForm("Hero of Many Battles", "hero-of-many-battles", PokemonType.FIGHTING, null, 2.9, 210, AbilityId.DAUNTLESS_SHIELD, AbilityId.NONE, AbilityId.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, false, "", true), + new PokemonForm("Crowned", "crowned", PokemonType.FIGHTING, PokemonType.STEEL, 2.9, 785, AbilityId.DAUNTLESS_SHIELD, AbilityId.NONE, AbilityId.NONE, 700, 92, 120, 140, 80, 140, 128, 10, 0, 360) + ), + new PokemonSpecies(SpeciesId.ETERNATUS, 8, false, true, false, "Gigantic Pokémon", PokemonType.POISON, PokemonType.DRAGON, 20, 950, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 690, 140, 85, 95, 145, 95, 130, 255, 0, 345, GrowthRate.SLOW, null, false, true, + new PokemonForm("Normal", "", PokemonType.POISON, PokemonType.DRAGON, 20, 950, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 690, 140, 85, 95, 145, 95, 130, 255, 0, 345, false, null, true), + new PokemonForm("E-Max", "eternamax", PokemonType.POISON, PokemonType.DRAGON, 100, 999.9, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 1125, 255, 115, 250, 125, 250, 130, 255, 0, 345) + ), + new PokemonSpecies(SpeciesId.KUBFU, 8, true, false, false, "Wushu Pokémon", PokemonType.FIGHTING, null, 0.6, 12, AbilityId.INNER_FOCUS, AbilityId.NONE, AbilityId.NONE, 385, 60, 90, 60, 53, 50, 72, 3, 50, 77, GrowthRate.SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.URSHIFU, 8, true, false, false, "Wushu Pokémon", PokemonType.FIGHTING, PokemonType.DARK, 1.9, 105, AbilityId.UNSEEN_FIST, AbilityId.NONE, AbilityId.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, GrowthRate.SLOW, 87.5, false, true, + new PokemonForm("Single Strike Style", "single-strike", PokemonType.FIGHTING, PokemonType.DARK, 1.9, 105, AbilityId.UNSEEN_FIST, AbilityId.NONE, AbilityId.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, false, "", true), + new PokemonForm("Rapid Strike Style", "rapid-strike", PokemonType.FIGHTING, PokemonType.WATER, 1.9, 105, AbilityId.UNSEEN_FIST, AbilityId.NONE, AbilityId.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, false, null, true), + new PokemonForm("G-Max Single Strike Style", SpeciesFormKey.GIGANTAMAX_SINGLE, PokemonType.FIGHTING, PokemonType.DARK, 29, 999.9, AbilityId.UNSEEN_FIST, AbilityId.NONE, AbilityId.NONE, 650, 125, 145, 115, 83, 70, 112, 3, 50, 275), + new PokemonForm("G-Max Rapid Strike Style", SpeciesFormKey.GIGANTAMAX_RAPID, PokemonType.FIGHTING, PokemonType.WATER, 26, 999.9, AbilityId.UNSEEN_FIST, AbilityId.NONE, AbilityId.NONE, 650, 125, 145, 115, 83, 70, 112, 3, 50, 275) + ), + new PokemonSpecies(SpeciesId.ZARUDE, 8, false, false, true, "Rogue Monkey Pokémon", PokemonType.DARK, PokemonType.GRASS, 1.8, 70, AbilityId.LEAF_GUARD, AbilityId.NONE, AbilityId.NONE, 600, 105, 120, 105, 70, 95, 105, 3, 0, 300, GrowthRate.SLOW, null, false, false, + new PokemonForm("Normal", "", PokemonType.DARK, PokemonType.GRASS, 1.8, 70, AbilityId.LEAF_GUARD, AbilityId.NONE, AbilityId.NONE, 600, 105, 120, 105, 70, 95, 105, 3, 0, 300, false, null, true), + new PokemonForm("Dada", "dada", PokemonType.DARK, PokemonType.GRASS, 1.8, 70, AbilityId.LEAF_GUARD, AbilityId.NONE, AbilityId.NONE, 600, 105, 120, 105, 70, 95, 105, 3, 0, 300, false, null, true) + ), + new PokemonSpecies(SpeciesId.REGIELEKI, 8, true, false, false, "Electron Pokémon", PokemonType.ELECTRIC, null, 1.2, 145, AbilityId.TRANSISTOR, AbilityId.NONE, AbilityId.NONE, 580, 80, 100, 50, 100, 50, 200, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.REGIDRAGO, 8, true, false, false, "Dragon Orb Pokémon", PokemonType.DRAGON, null, 2.1, 200, AbilityId.DRAGONS_MAW, AbilityId.NONE, AbilityId.NONE, 580, 200, 100, 50, 100, 50, 80, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.GLASTRIER, 8, true, false, false, "Wild Horse Pokémon", PokemonType.ICE, null, 2.2, 800, AbilityId.CHILLING_NEIGH, AbilityId.NONE, AbilityId.NONE, 580, 100, 145, 130, 65, 110, 30, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.SPECTRIER, 8, true, false, false, "Swift Horse Pokémon", PokemonType.GHOST, null, 2, 44.5, AbilityId.GRIM_NEIGH, AbilityId.NONE, AbilityId.NONE, 580, 100, 65, 60, 145, 80, 130, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.CALYREX, 8, false, true, false, "King Pokémon", PokemonType.PSYCHIC, PokemonType.GRASS, 1.1, 7.7, AbilityId.UNNERVE, AbilityId.NONE, AbilityId.NONE, 500, 100, 80, 80, 80, 80, 80, 3, 100, 250, GrowthRate.SLOW, null, false, true, + new PokemonForm("Normal", "", PokemonType.PSYCHIC, PokemonType.GRASS, 1.1, 7.7, AbilityId.UNNERVE, AbilityId.NONE, AbilityId.NONE, 500, 100, 80, 80, 80, 80, 80, 3, 100, 250, false, null, true), + new PokemonForm("Ice", "ice", PokemonType.PSYCHIC, PokemonType.ICE, 2.4, 809.1, AbilityId.AS_ONE_GLASTRIER, AbilityId.NONE, AbilityId.NONE, 680, 100, 165, 150, 85, 130, 50, 3, 100, 340), + new PokemonForm("Shadow", "shadow", PokemonType.PSYCHIC, PokemonType.GHOST, 2.4, 53.6, AbilityId.AS_ONE_SPECTRIER, AbilityId.NONE, AbilityId.NONE, 680, 100, 85, 80, 165, 100, 150, 3, 100, 340) + ), + new PokemonSpecies(SpeciesId.WYRDEER, 8, false, false, false, "Big Horn Pokémon", PokemonType.NORMAL, PokemonType.PSYCHIC, 1.8, 95.1, AbilityId.INTIMIDATE, AbilityId.FRISK, AbilityId.SAP_SIPPER, 525, 103, 105, 72, 105, 75, 65, 45, 50, 263, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.KLEAVOR, 8, false, false, false, "Axe Pokémon", PokemonType.BUG, PokemonType.ROCK, 1.8, 89, AbilityId.SWARM, AbilityId.SHEER_FORCE, AbilityId.SHARPNESS, 500, 70, 135, 95, 45, 70, 85, 15, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.URSALUNA, 8, false, false, false, "Peat Pokémon", PokemonType.GROUND, PokemonType.NORMAL, 2.4, 290, AbilityId.GUTS, AbilityId.BULLETPROOF, AbilityId.UNNERVE, 550, 130, 140, 105, 45, 80, 50, 20, 50, 275, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BASCULEGION, 8, false, false, false, "Big Fish Pokémon", PokemonType.WATER, PokemonType.GHOST, 3, 110, AbilityId.SWIFT_SWIM, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 530, 120, 112, 65, 80, 75, 78, 45, 50, 265, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Male", "male", PokemonType.WATER, PokemonType.GHOST, 3, 110, AbilityId.SWIFT_SWIM, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 530, 120, 112, 65, 80, 75, 78, 45, 50, 265, false, "", true), + new PokemonForm("Female", "female", PokemonType.WATER, PokemonType.GHOST, 3, 110, AbilityId.SWIFT_SWIM, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 530, 120, 92, 65, 100, 75, 78, 45, 50, 265, false, null, true) + ), + new PokemonSpecies(SpeciesId.SNEASLER, 8, false, false, false, "Free Climb Pokémon", PokemonType.FIGHTING, PokemonType.POISON, 1.3, 43, AbilityId.PRESSURE, AbilityId.UNBURDEN, AbilityId.POISON_TOUCH, 510, 80, 130, 60, 40, 80, 120, 20, 50, 102, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.OVERQWIL, 8, false, false, false, "Pin Cluster Pokémon", PokemonType.DARK, PokemonType.POISON, 2.5, 60.5, AbilityId.POISON_POINT, AbilityId.SWIFT_SWIM, AbilityId.INTIMIDATE, 510, 85, 115, 95, 65, 65, 85, 45, 50, 179, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ENAMORUS, 8, true, false, false, "Love-Hate Pokémon", PokemonType.FAIRY, PokemonType.FLYING, 1.6, 48, AbilityId.CUTE_CHARM, AbilityId.NONE, AbilityId.CONTRARY, 580, 74, 115, 70, 135, 80, 106, 3, 50, 116, GrowthRate.SLOW, 0, false, true, + new PokemonForm("Incarnate Forme", "incarnate", PokemonType.FAIRY, PokemonType.FLYING, 1.6, 48, AbilityId.CUTE_CHARM, AbilityId.NONE, AbilityId.CONTRARY, 580, 74, 115, 70, 135, 80, 106, 3, 50, 116, false, null, true), + new PokemonForm("Therian Forme", "therian", PokemonType.FAIRY, PokemonType.FLYING, 1.6, 48, AbilityId.OVERCOAT, AbilityId.NONE, AbilityId.OVERCOAT, 580, 74, 115, 110, 135, 100, 46, 3, 50, 116) + ), + new PokemonSpecies(SpeciesId.SPRIGATITO, 9, false, false, false, "Grass Cat Pokémon", PokemonType.GRASS, null, 0.4, 4.1, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.PROTEAN, 310, 40, 61, 54, 45, 45, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.FLORAGATO, 9, false, false, false, "Grass Cat Pokémon", PokemonType.GRASS, null, 0.9, 12.2, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.PROTEAN, 410, 61, 80, 63, 60, 63, 83, 45, 50, 144, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.MEOWSCARADA, 9, false, false, false, "Magician Pokémon", PokemonType.GRASS, PokemonType.DARK, 1.5, 31.2, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.PROTEAN, 530, 76, 110, 70, 81, 70, 123, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.FUECOCO, 9, false, false, false, "Fire Croc Pokémon", PokemonType.FIRE, null, 0.4, 9.8, AbilityId.BLAZE, AbilityId.NONE, AbilityId.UNAWARE, 310, 67, 45, 59, 63, 40, 36, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.CROCALOR, 9, false, false, false, "Fire Croc Pokémon", PokemonType.FIRE, null, 1, 30.7, AbilityId.BLAZE, AbilityId.NONE, AbilityId.UNAWARE, 411, 81, 55, 78, 90, 58, 49, 45, 50, 144, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.SKELEDIRGE, 9, false, false, false, "Singer Pokémon", PokemonType.FIRE, PokemonType.GHOST, 1.6, 326.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.UNAWARE, 530, 104, 75, 100, 110, 75, 66, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.QUAXLY, 9, false, false, false, "Duckling Pokémon", PokemonType.WATER, null, 0.5, 6.1, AbilityId.TORRENT, AbilityId.NONE, AbilityId.MOXIE, 310, 55, 65, 45, 50, 45, 50, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.QUAXWELL, 9, false, false, false, "Practicing Pokémon", PokemonType.WATER, null, 1.2, 21.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.MOXIE, 410, 70, 85, 65, 65, 60, 65, 45, 50, 144, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.QUAQUAVAL, 9, false, false, false, "Dancer Pokémon", PokemonType.WATER, PokemonType.FIGHTING, 1.8, 61.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.MOXIE, 530, 85, 120, 80, 85, 75, 85, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.LECHONK, 9, false, false, false, "Hog Pokémon", PokemonType.NORMAL, null, 0.5, 10.2, AbilityId.AROMA_VEIL, AbilityId.GLUTTONY, AbilityId.THICK_FAT, 254, 54, 45, 40, 35, 45, 35, 255, 50, 51, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.OINKOLOGNE, 9, false, false, false, "Hog Pokémon", PokemonType.NORMAL, null, 1, 120, AbilityId.LINGERING_AROMA, AbilityId.GLUTTONY, AbilityId.THICK_FAT, 489, 110, 100, 75, 59, 80, 65, 100, 50, 171, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Male", "male", PokemonType.NORMAL, null, 1, 120, AbilityId.LINGERING_AROMA, AbilityId.GLUTTONY, AbilityId.THICK_FAT, 489, 110, 100, 75, 59, 80, 65, 100, 50, 171, false, "", true), + new PokemonForm("Female", "female", PokemonType.NORMAL, null, 1, 120, AbilityId.AROMA_VEIL, AbilityId.GLUTTONY, AbilityId.THICK_FAT, 489, 115, 90, 70, 59, 90, 65, 100, 50, 171, false, null, true) + ), + new PokemonSpecies(SpeciesId.TAROUNTULA, 9, false, false, false, "String Ball Pokémon", PokemonType.BUG, null, 0.3, 4, AbilityId.INSOMNIA, AbilityId.NONE, AbilityId.STAKEOUT, 210, 35, 41, 45, 29, 40, 20, 255, 50, 42, GrowthRate.ERRATIC, 50, false), + new PokemonSpecies(SpeciesId.SPIDOPS, 9, false, false, false, "Trap Pokémon", PokemonType.BUG, null, 1, 16.5, AbilityId.INSOMNIA, AbilityId.NONE, AbilityId.STAKEOUT, 404, 60, 79, 92, 52, 86, 35, 120, 50, 141, GrowthRate.ERRATIC, 50, false), + new PokemonSpecies(SpeciesId.NYMBLE, 9, false, false, false, "Grasshopper Pokémon", PokemonType.BUG, null, 0.2, 1, AbilityId.SWARM, AbilityId.NONE, AbilityId.TINTED_LENS, 210, 33, 46, 40, 21, 25, 45, 190, 20, 42, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.LOKIX, 9, false, false, false, "Grasshopper Pokémon", PokemonType.BUG, PokemonType.DARK, 1, 17.5, AbilityId.SWARM, AbilityId.NONE, AbilityId.TINTED_LENS, 450, 71, 102, 78, 52, 55, 92, 30, 0, 158, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PAWMI, 9, false, false, false, "Mouse Pokémon", PokemonType.ELECTRIC, null, 0.3, 2.5, AbilityId.STATIC, AbilityId.NATURAL_CURE, AbilityId.IRON_FIST, 240, 45, 50, 20, 40, 25, 60, 190, 50, 48, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PAWMO, 9, false, false, false, "Mouse Pokémon", PokemonType.ELECTRIC, PokemonType.FIGHTING, 0.4, 6.5, AbilityId.VOLT_ABSORB, AbilityId.NATURAL_CURE, AbilityId.IRON_FIST, 350, 60, 75, 40, 50, 40, 85, 80, 50, 123, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.PAWMOT, 9, false, false, false, "Hands-On Pokémon", PokemonType.ELECTRIC, PokemonType.FIGHTING, 0.9, 41, AbilityId.VOLT_ABSORB, AbilityId.NATURAL_CURE, AbilityId.IRON_FIST, 490, 70, 115, 70, 70, 60, 105, 45, 50, 245, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.TANDEMAUS, 9, false, false, false, "Couple Pokémon", PokemonType.NORMAL, null, 0.3, 1.8, AbilityId.RUN_AWAY, AbilityId.PICKUP, AbilityId.OWN_TEMPO, 305, 50, 50, 45, 40, 45, 75, 150, 50, 61, GrowthRate.FAST, null, false), + new PokemonSpecies(SpeciesId.MAUSHOLD, 9, false, false, false, "Family Pokémon", PokemonType.NORMAL, null, 0.3, 2.3, AbilityId.FRIEND_GUARD, AbilityId.CHEEK_POUCH, AbilityId.TECHNICIAN, 470, 74, 75, 70, 65, 75, 111, 75, 50, 165, GrowthRate.FAST, null, false, false, + new PokemonForm("Family of Four", "four", PokemonType.NORMAL, null, 0.3, 2.8, AbilityId.FRIEND_GUARD, AbilityId.CHEEK_POUCH, AbilityId.TECHNICIAN, 470, 74, 75, 70, 65, 75, 111, 75, 50, 165), + new PokemonForm("Family of Three", "three", PokemonType.NORMAL, null, 0.3, 2.3, AbilityId.FRIEND_GUARD, AbilityId.CHEEK_POUCH, AbilityId.TECHNICIAN, 470, 74, 75, 70, 65, 75, 111, 75, 50, 165) + ), + new PokemonSpecies(SpeciesId.FIDOUGH, 9, false, false, false, "Puppy Pokémon", PokemonType.FAIRY, null, 0.3, 10.9, AbilityId.OWN_TEMPO, AbilityId.NONE, AbilityId.KLUTZ, 312, 37, 55, 70, 30, 55, 65, 190, 50, 62, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.DACHSBUN, 9, false, false, false, "Dog Pokémon", PokemonType.FAIRY, null, 0.5, 14.9, AbilityId.WELL_BAKED_BODY, AbilityId.NONE, AbilityId.AROMA_VEIL, 477, 57, 80, 115, 50, 80, 95, 90, 50, 167, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SMOLIV, 9, false, false, false, "Olive Pokémon", PokemonType.GRASS, PokemonType.NORMAL, 0.3, 6.5, AbilityId.EARLY_BIRD, AbilityId.NONE, AbilityId.HARVEST, 260, 41, 35, 45, 58, 51, 30, 255, 50, 52, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.DOLLIV, 9, false, false, false, "Olive Pokémon", PokemonType.GRASS, PokemonType.NORMAL, 0.6, 11.9, AbilityId.EARLY_BIRD, AbilityId.NONE, AbilityId.HARVEST, 354, 52, 53, 60, 78, 78, 33, 120, 50, 124, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.ARBOLIVA, 9, false, false, false, "Olive Pokémon", PokemonType.GRASS, PokemonType.NORMAL, 1.4, 48.2, AbilityId.SEED_SOWER, AbilityId.NONE, AbilityId.HARVEST, 510, 78, 69, 90, 125, 109, 39, 45, 50, 255, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SQUAWKABILLY, 9, false, false, false, "Parrot Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 2.4, AbilityId.INTIMIDATE, AbilityId.HUSTLE, AbilityId.GUTS, 417, 82, 96, 51, 45, 51, 92, 190, 50, 146, GrowthRate.ERRATIC, 50, false, false, + new PokemonForm("Green Plumage", "green-plumage", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 2.4, AbilityId.INTIMIDATE, AbilityId.HUSTLE, AbilityId.GUTS, 417, 82, 96, 51, 45, 51, 92, 190, 50, 146, false, null, true), + new PokemonForm("Blue Plumage", "blue-plumage", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 2.4, AbilityId.INTIMIDATE, AbilityId.HUSTLE, AbilityId.GUTS, 417, 82, 96, 51, 45, 51, 92, 190, 50, 146, false, null, true), + new PokemonForm("Yellow Plumage", "yellow-plumage", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 2.4, AbilityId.INTIMIDATE, AbilityId.HUSTLE, AbilityId.SHEER_FORCE, 417, 82, 96, 51, 45, 51, 92, 190, 50, 146, false, null, true), + new PokemonForm("White Plumage", "white-plumage", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 2.4, AbilityId.INTIMIDATE, AbilityId.HUSTLE, AbilityId.SHEER_FORCE, 417, 82, 96, 51, 45, 51, 92, 190, 50, 146, false, null, true) + ), + new PokemonSpecies(SpeciesId.NACLI, 9, false, false, false, "Rock Salt Pokémon", PokemonType.ROCK, null, 0.4, 16, AbilityId.PURIFYING_SALT, AbilityId.STURDY, AbilityId.CLEAR_BODY, 280, 55, 55, 75, 35, 35, 25, 255, 50, 56, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.NACLSTACK, 9, false, false, false, "Rock Salt Pokémon", PokemonType.ROCK, null, 0.6, 105, AbilityId.PURIFYING_SALT, AbilityId.STURDY, AbilityId.CLEAR_BODY, 355, 60, 60, 100, 35, 65, 35, 120, 50, 124, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.GARGANACL, 9, false, false, false, "Rock Salt Pokémon", PokemonType.ROCK, null, 2.3, 240, AbilityId.PURIFYING_SALT, AbilityId.STURDY, AbilityId.CLEAR_BODY, 500, 100, 100, 130, 45, 90, 35, 45, 50, 250, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.CHARCADET, 9, false, false, false, "Fire Child Pokémon", PokemonType.FIRE, null, 0.6, 10.5, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.FLAME_BODY, 255, 40, 50, 40, 50, 40, 35, 90, 50, 51, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.ARMAROUGE, 9, false, false, false, "Fire Warrior Pokémon", PokemonType.FIRE, PokemonType.PSYCHIC, 1.5, 85, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.WEAK_ARMOR, 525, 85, 60, 100, 125, 80, 75, 25, 20, 263, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.CERULEDGE, 9, false, false, false, "Fire Blades Pokémon", PokemonType.FIRE, PokemonType.GHOST, 1.6, 62, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.WEAK_ARMOR, 525, 75, 125, 80, 60, 100, 85, 25, 20, 263, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.TADBULB, 9, false, false, false, "EleTadpole Pokémon", PokemonType.ELECTRIC, null, 0.3, 0.4, AbilityId.OWN_TEMPO, AbilityId.STATIC, AbilityId.DAMP, 272, 61, 31, 41, 59, 35, 45, 190, 50, 54, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BELLIBOLT, 9, false, false, false, "EleFrog Pokémon", PokemonType.ELECTRIC, null, 1.2, 113, AbilityId.ELECTROMORPHOSIS, AbilityId.STATIC, AbilityId.DAMP, 495, 109, 64, 91, 103, 83, 45, 50, 50, 173, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.WATTREL, 9, false, false, false, "Storm Petrel Pokémon", PokemonType.ELECTRIC, PokemonType.FLYING, 0.4, 3.6, AbilityId.WIND_POWER, AbilityId.VOLT_ABSORB, AbilityId.COMPETITIVE, 280, 40, 40, 35, 55, 40, 70, 180, 50, 56, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.KILOWATTREL, 9, false, false, false, "Frigatebird Pokémon", PokemonType.ELECTRIC, PokemonType.FLYING, 1.4, 38.6, AbilityId.WIND_POWER, AbilityId.VOLT_ABSORB, AbilityId.COMPETITIVE, 490, 70, 70, 60, 105, 60, 125, 90, 50, 172, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.MASCHIFF, 9, false, false, false, "Rascal Pokémon", PokemonType.DARK, null, 0.5, 16, AbilityId.INTIMIDATE, AbilityId.RUN_AWAY, AbilityId.STAKEOUT, 340, 60, 78, 60, 40, 51, 51, 150, 50, 68, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.MABOSSTIFF, 9, false, false, false, "Boss Pokémon", PokemonType.DARK, null, 1.1, 61, AbilityId.INTIMIDATE, AbilityId.GUARD_DOG, AbilityId.STAKEOUT, 505, 80, 120, 90, 60, 70, 85, 75, 50, 177, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.SHROODLE, 9, false, false, false, "Toxic Mouse Pokémon", PokemonType.POISON, PokemonType.NORMAL, 0.2, 0.7, AbilityId.UNBURDEN, AbilityId.PICKPOCKET, AbilityId.PRANKSTER, 290, 40, 65, 35, 40, 35, 75, 190, 50, 58, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.GRAFAIAI, 9, false, false, false, "Toxic Monkey Pokémon", PokemonType.POISON, PokemonType.NORMAL, 0.7, 27.2, AbilityId.UNBURDEN, AbilityId.POISON_TOUCH, AbilityId.PRANKSTER, 485, 63, 95, 65, 80, 72, 110, 90, 50, 170, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.BRAMBLIN, 9, false, false, false, "Tumbleweed Pokémon", PokemonType.GRASS, PokemonType.GHOST, 0.6, 0.6, AbilityId.WIND_RIDER, AbilityId.NONE, AbilityId.INFILTRATOR, 275, 40, 65, 30, 45, 35, 60, 190, 50, 55, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BRAMBLEGHAST, 9, false, false, false, "Tumbleweed Pokémon", PokemonType.GRASS, PokemonType.GHOST, 1.2, 6, AbilityId.WIND_RIDER, AbilityId.NONE, AbilityId.INFILTRATOR, 480, 55, 115, 70, 80, 70, 90, 45, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.TOEDSCOOL, 9, false, false, false, "Woodear Pokémon", PokemonType.GROUND, PokemonType.GRASS, 0.9, 33, AbilityId.MYCELIUM_MIGHT, AbilityId.NONE, AbilityId.NONE, 335, 40, 40, 35, 50, 100, 70, 190, 50, 67, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.TOEDSCRUEL, 9, false, false, false, "Woodear Pokémon", PokemonType.GROUND, PokemonType.GRASS, 1.9, 58, AbilityId.MYCELIUM_MIGHT, AbilityId.NONE, AbilityId.NONE, 515, 80, 70, 65, 80, 120, 100, 90, 50, 180, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.KLAWF, 9, false, false, false, "Ambush Pokémon", PokemonType.ROCK, null, 1.3, 79, AbilityId.ANGER_SHELL, AbilityId.SHELL_ARMOR, AbilityId.REGENERATOR, 450, 70, 100, 115, 35, 55, 75, 120, 50, 158, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CAPSAKID, 9, false, false, false, "Spicy Pepper Pokémon", PokemonType.GRASS, null, 0.3, 3, AbilityId.CHLOROPHYLL, AbilityId.INSOMNIA, AbilityId.KLUTZ, 304, 50, 62, 40, 62, 40, 50, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.SCOVILLAIN, 9, false, false, false, "Spicy Pepper Pokémon", PokemonType.GRASS, PokemonType.FIRE, 0.9, 15, AbilityId.CHLOROPHYLL, AbilityId.INSOMNIA, AbilityId.MOODY, 486, 65, 108, 65, 108, 65, 75, 75, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.RELLOR, 9, false, false, false, "Rolling Pokémon", PokemonType.BUG, null, 0.2, 1, AbilityId.COMPOUND_EYES, AbilityId.NONE, AbilityId.SHED_SKIN, 270, 41, 50, 60, 31, 58, 30, 190, 50, 54, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.RABSCA, 9, false, false, false, "Rolling Pokémon", PokemonType.BUG, PokemonType.PSYCHIC, 0.3, 3.5, AbilityId.SYNCHRONIZE, AbilityId.NONE, AbilityId.TELEPATHY, 470, 75, 50, 85, 115, 100, 45, 45, 50, 165, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.FLITTLE, 9, false, false, false, "Frill Pokémon", PokemonType.PSYCHIC, null, 0.2, 1.5, AbilityId.ANTICIPATION, AbilityId.FRISK, AbilityId.SPEED_BOOST, 255, 30, 35, 30, 55, 30, 75, 120, 50, 51, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.ESPATHRA, 9, false, false, false, "Ostrich Pokémon", PokemonType.PSYCHIC, null, 1.9, 90, AbilityId.OPPORTUNIST, AbilityId.FRISK, AbilityId.SPEED_BOOST, 481, 95, 60, 60, 101, 60, 105, 60, 50, 168, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.TINKATINK, 9, false, false, false, "Metalsmith Pokémon", PokemonType.FAIRY, PokemonType.STEEL, 0.4, 8.9, AbilityId.MOLD_BREAKER, AbilityId.OWN_TEMPO, AbilityId.PICKPOCKET, 297, 50, 45, 45, 35, 64, 58, 190, 50, 59, GrowthRate.MEDIUM_SLOW, 0, false), + new PokemonSpecies(SpeciesId.TINKATUFF, 9, false, false, false, "Hammer Pokémon", PokemonType.FAIRY, PokemonType.STEEL, 0.7, 59.1, AbilityId.MOLD_BREAKER, AbilityId.OWN_TEMPO, AbilityId.PICKPOCKET, 380, 65, 55, 55, 45, 82, 78, 90, 50, 133, GrowthRate.MEDIUM_SLOW, 0, false), + new PokemonSpecies(SpeciesId.TINKATON, 9, false, false, false, "Hammer Pokémon", PokemonType.FAIRY, PokemonType.STEEL, 0.7, 112.8, AbilityId.MOLD_BREAKER, AbilityId.OWN_TEMPO, AbilityId.PICKPOCKET, 506, 85, 75, 77, 70, 105, 94, 45, 50, 253, GrowthRate.MEDIUM_SLOW, 0, false), + new PokemonSpecies(SpeciesId.WIGLETT, 9, false, false, false, "Garden Eel Pokémon", PokemonType.WATER, null, 1.2, 1.8, AbilityId.GOOEY, AbilityId.RATTLED, AbilityId.SAND_VEIL, 245, 10, 55, 25, 35, 25, 95, 255, 50, 49, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.WUGTRIO, 9, false, false, false, "Garden Eel Pokémon", PokemonType.WATER, null, 1.2, 5.4, AbilityId.GOOEY, AbilityId.RATTLED, AbilityId.SAND_VEIL, 425, 35, 100, 50, 50, 70, 120, 50, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BOMBIRDIER, 9, false, false, false, "Item Drop Pokémon", PokemonType.FLYING, PokemonType.DARK, 1.5, 42.9, AbilityId.BIG_PECKS, AbilityId.KEEN_EYE, AbilityId.ROCKY_PAYLOAD, 485, 70, 103, 85, 60, 85, 82, 25, 50, 243, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.FINIZEN, 9, false, false, false, "Dolphin Pokémon", PokemonType.WATER, null, 1.3, 60.2, AbilityId.WATER_VEIL, AbilityId.NONE, AbilityId.NONE, 315, 70, 45, 40, 45, 40, 75, 200, 50, 63, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.PALAFIN, 9, false, false, false, "Dolphin Pokémon", PokemonType.WATER, null, 1.3, 60.2, AbilityId.ZERO_TO_HERO, AbilityId.NONE, AbilityId.NONE, 457, 100, 70, 72, 53, 62, 100, 45, 50, 160, GrowthRate.SLOW, 50, false, true, + new PokemonForm("Zero Form", "zero", PokemonType.WATER, null, 1.3, 60.2, AbilityId.ZERO_TO_HERO, AbilityId.NONE, AbilityId.ZERO_TO_HERO, 457, 100, 70, 72, 53, 62, 100, 45, 50, 160, false, null, true), + new PokemonForm("Hero Form", "hero", PokemonType.WATER, null, 1.8, 97.4, AbilityId.ZERO_TO_HERO, AbilityId.NONE, AbilityId.ZERO_TO_HERO, 650, 100, 160, 97, 106, 87, 100, 45, 50, 160) + ), + new PokemonSpecies(SpeciesId.VAROOM, 9, false, false, false, "Single-Cyl Pokémon", PokemonType.STEEL, PokemonType.POISON, 1, 35, AbilityId.OVERCOAT, AbilityId.NONE, AbilityId.SLOW_START, 300, 45, 70, 63, 30, 45, 47, 190, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.REVAVROOM, 9, false, false, false, "Multi-Cyl Pokémon", PokemonType.STEEL, PokemonType.POISON, 1.8, 120, AbilityId.OVERCOAT, AbilityId.NONE, AbilityId.FILTER, 500, 80, 119, 90, 54, 67, 90, 75, 50, 175, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.POISON, 1.8, 120, AbilityId.OVERCOAT, AbilityId.NONE, AbilityId.FILTER, 500, 80, 119, 90, 54, 67, 90, 75, 50, 175, false, null, true), + new PokemonForm("Segin Starmobile", "segin-starmobile", PokemonType.STEEL, PokemonType.DARK, 1.8, 240, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.INTIMIDATE, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175, false, null, false, true), + new PokemonForm("Schedar Starmobile", "schedar-starmobile", PokemonType.STEEL, PokemonType.FIRE, 1.8, 240, AbilityId.SPEED_BOOST, AbilityId.NONE, AbilityId.SPEED_BOOST, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175, false, null, false, true), + new PokemonForm("Navi Starmobile", "navi-starmobile", PokemonType.STEEL, PokemonType.POISON, 1.8, 240, AbilityId.TOXIC_DEBRIS, AbilityId.NONE, AbilityId.TOXIC_DEBRIS, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175, false, null, false, true), + new PokemonForm("Ruchbah Starmobile", "ruchbah-starmobile", PokemonType.STEEL, PokemonType.FAIRY, 1.8, 240, AbilityId.MISTY_SURGE, AbilityId.NONE, AbilityId.MISTY_SURGE, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175, false, null, false, true), + new PokemonForm("Caph Starmobile", "caph-starmobile", PokemonType.STEEL, PokemonType.FIGHTING, 1.8, 240, AbilityId.STAMINA, AbilityId.NONE, AbilityId.STAMINA, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175, false, null, false, true) + ), + new PokemonSpecies(SpeciesId.CYCLIZAR, 9, false, false, false, "Mount Pokémon", PokemonType.DRAGON, PokemonType.NORMAL, 1.6, 63, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.REGENERATOR, 501, 70, 95, 65, 85, 65, 121, 190, 50, 175, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.ORTHWORM, 9, false, false, false, "Earthworm Pokémon", PokemonType.STEEL, null, 2.5, 310, AbilityId.EARTH_EATER, AbilityId.NONE, AbilityId.SAND_VEIL, 480, 70, 85, 145, 60, 55, 65, 25, 50, 240, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.GLIMMET, 9, false, false, false, "Ore Pokémon", PokemonType.ROCK, PokemonType.POISON, 0.7, 8, AbilityId.TOXIC_DEBRIS, AbilityId.NONE, AbilityId.CORROSION, 350, 48, 35, 42, 105, 60, 60, 70, 50, 70, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.GLIMMORA, 9, false, false, false, "Ore Pokémon", PokemonType.ROCK, PokemonType.POISON, 1.5, 45, AbilityId.TOXIC_DEBRIS, AbilityId.NONE, AbilityId.CORROSION, 525, 83, 55, 90, 130, 81, 86, 25, 50, 184, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.GREAVARD, 9, false, false, false, "Ghost Dog Pokémon", PokemonType.GHOST, null, 0.6, 35, AbilityId.PICKUP, AbilityId.NONE, AbilityId.FLUFFY, 290, 50, 61, 60, 30, 55, 34, 120, 50, 58, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.HOUNDSTONE, 9, false, false, false, "Ghost Dog Pokémon", PokemonType.GHOST, null, 2, 15, AbilityId.SAND_RUSH, AbilityId.NONE, AbilityId.FLUFFY, 488, 72, 101, 100, 50, 97, 68, 60, 50, 171, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.FLAMIGO, 9, false, false, false, "Synchronize Pokémon", PokemonType.FLYING, PokemonType.FIGHTING, 1.6, 37, AbilityId.SCRAPPY, AbilityId.TANGLED_FEET, AbilityId.COSTAR, 500, 82, 115, 74, 75, 64, 90, 100, 50, 175, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.CETODDLE, 9, false, false, false, "Terra Whale Pokémon", PokemonType.ICE, null, 1.2, 45, AbilityId.THICK_FAT, AbilityId.SNOW_CLOAK, AbilityId.SHEER_FORCE, 334, 108, 68, 45, 30, 40, 43, 150, 50, 67, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.CETITAN, 9, false, false, false, "Terra Whale Pokémon", PokemonType.ICE, null, 4.5, 700, AbilityId.THICK_FAT, AbilityId.SLUSH_RUSH, AbilityId.SHEER_FORCE, 521, 170, 113, 65, 45, 55, 73, 50, 50, 182, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.VELUZA, 9, false, false, false, "Jettison Pokémon", PokemonType.WATER, PokemonType.PSYCHIC, 2.5, 90, AbilityId.MOLD_BREAKER, AbilityId.NONE, AbilityId.SHARPNESS, 478, 90, 102, 73, 78, 65, 70, 100, 50, 167, GrowthRate.FAST, 50, false), + new PokemonSpecies(SpeciesId.DONDOZO, 9, false, false, false, "Big Catfish Pokémon", PokemonType.WATER, null, 12, 220, AbilityId.UNAWARE, AbilityId.OBLIVIOUS, AbilityId.WATER_VEIL, 530, 150, 100, 115, 65, 65, 35, 25, 50, 265, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.TATSUGIRI, 9, false, false, false, "Mimicry Pokémon", PokemonType.DRAGON, PokemonType.WATER, 0.3, 8, AbilityId.COMMANDER, AbilityId.NONE, AbilityId.STORM_DRAIN, 475, 68, 50, 60, 120, 95, 82, 100, 50, 166, GrowthRate.MEDIUM_SLOW, 50, false, false, + new PokemonForm("Curly Form", "curly", PokemonType.DRAGON, PokemonType.WATER, 0.3, 8, AbilityId.COMMANDER, AbilityId.NONE, AbilityId.STORM_DRAIN, 475, 68, 50, 60, 120, 95, 82, 100, 50, 166, false, null, true), + new PokemonForm("Droopy Form", "droopy", PokemonType.DRAGON, PokemonType.WATER, 0.3, 8, AbilityId.COMMANDER, AbilityId.NONE, AbilityId.STORM_DRAIN, 475, 68, 50, 60, 120, 95, 82, 100, 50, 166, false, null, true), + new PokemonForm("Stretchy Form", "stretchy", PokemonType.DRAGON, PokemonType.WATER, 0.3, 8, AbilityId.COMMANDER, AbilityId.NONE, AbilityId.STORM_DRAIN, 475, 68, 50, 60, 120, 95, 82, 100, 50, 166, false, null, true) + ), + new PokemonSpecies(SpeciesId.ANNIHILAPE, 9, false, false, false, "Rage Monkey Pokémon", PokemonType.FIGHTING, PokemonType.GHOST, 1.2, 56, AbilityId.VITAL_SPIRIT, AbilityId.INNER_FOCUS, AbilityId.DEFIANT, 535, 110, 115, 80, 50, 90, 90, 45, 50, 268, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.CLODSIRE, 9, false, false, false, "Spiny Fish Pokémon", PokemonType.POISON, PokemonType.GROUND, 1.8, 223, AbilityId.POISON_POINT, AbilityId.WATER_ABSORB, AbilityId.UNAWARE, 430, 130, 75, 60, 45, 100, 20, 90, 50, 151, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.FARIGIRAF, 9, false, false, false, "Long Neck Pokémon", PokemonType.NORMAL, PokemonType.PSYCHIC, 3.2, 160, AbilityId.CUD_CHEW, AbilityId.ARMOR_TAIL, AbilityId.SAP_SIPPER, 520, 120, 90, 70, 110, 70, 60, 45, 50, 260, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.DUDUNSPARCE, 9, false, false, false, "Land Snake Pokémon", PokemonType.NORMAL, null, 3.6, 39.2, AbilityId.SERENE_GRACE, AbilityId.RUN_AWAY, AbilityId.RATTLED, 520, 125, 100, 80, 85, 75, 55, 45, 50, 182, GrowthRate.MEDIUM_FAST, 50, false, false, + new PokemonForm("Two-Segment Form", "two-segment", PokemonType.NORMAL, null, 3.6, 39.2, AbilityId.SERENE_GRACE, AbilityId.RUN_AWAY, AbilityId.RATTLED, 520, 125, 100, 80, 85, 75, 55, 45, 50, 182, false, ""), + new PokemonForm("Three-Segment Form", "three-segment", PokemonType.NORMAL, null, 4.5, 47.4, AbilityId.SERENE_GRACE, AbilityId.RUN_AWAY, AbilityId.RATTLED, 520, 125, 100, 80, 85, 75, 55, 45, 50, 182) + ), + new PokemonSpecies(SpeciesId.KINGAMBIT, 9, false, false, false, "Big Blade Pokémon", PokemonType.DARK, PokemonType.STEEL, 2, 120, AbilityId.DEFIANT, AbilityId.SUPREME_OVERLORD, AbilityId.PRESSURE, 550, 100, 135, 120, 60, 85, 50, 25, 50, 275, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GREAT_TUSK, 9, false, false, false, "Paradox Pokémon", PokemonType.GROUND, PokemonType.FIGHTING, 2.2, 320, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 570, 115, 131, 131, 53, 53, 87, 30, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.SCREAM_TAIL, 9, false, false, false, "Paradox Pokémon", PokemonType.FAIRY, PokemonType.PSYCHIC, 1.2, 8, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 570, 115, 65, 99, 65, 115, 111, 50, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.BRUTE_BONNET, 9, false, false, false, "Paradox Pokémon", PokemonType.GRASS, PokemonType.DARK, 1.2, 21, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 570, 111, 127, 99, 79, 99, 55, 50, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.FLUTTER_MANE, 9, false, false, false, "Paradox Pokémon", PokemonType.GHOST, PokemonType.FAIRY, 1.4, 4, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 570, 55, 55, 55, 135, 135, 135, 30, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.SLITHER_WING, 9, false, false, false, "Paradox Pokémon", PokemonType.BUG, PokemonType.FIGHTING, 3.2, 92, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 570, 85, 135, 79, 85, 105, 81, 30, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.SANDY_SHOCKS, 9, false, false, false, "Paradox Pokémon", PokemonType.ELECTRIC, PokemonType.GROUND, 2.3, 60, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 570, 85, 81, 97, 121, 85, 101, 30, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.IRON_TREADS, 9, false, false, false, "Paradox Pokémon", PokemonType.GROUND, PokemonType.STEEL, 0.9, 240, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 570, 90, 112, 120, 72, 70, 106, 30, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.IRON_BUNDLE, 9, false, false, false, "Paradox Pokémon", PokemonType.ICE, PokemonType.WATER, 0.6, 11, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 570, 56, 80, 114, 124, 60, 136, 50, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.IRON_HANDS, 9, false, false, false, "Paradox Pokémon", PokemonType.FIGHTING, PokemonType.ELECTRIC, 1.8, 380.7, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 570, 154, 140, 108, 50, 68, 50, 50, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.IRON_JUGULIS, 9, false, false, false, "Paradox Pokémon", PokemonType.DARK, PokemonType.FLYING, 1.3, 111, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 570, 94, 80, 86, 122, 80, 108, 30, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.IRON_MOTH, 9, false, false, false, "Paradox Pokémon", PokemonType.FIRE, PokemonType.POISON, 1.2, 36, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 570, 80, 70, 60, 140, 110, 110, 30, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.IRON_THORNS, 9, false, false, false, "Paradox Pokémon", PokemonType.ROCK, PokemonType.ELECTRIC, 1.6, 303, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 570, 100, 134, 110, 70, 84, 72, 30, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.FRIGIBAX, 9, false, false, false, "Ice Fin Pokémon", PokemonType.DRAGON, PokemonType.ICE, 0.5, 17, AbilityId.THERMAL_EXCHANGE, AbilityId.NONE, AbilityId.ICE_BODY, 320, 65, 75, 45, 35, 45, 55, 45, 50, 64, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.ARCTIBAX, 9, false, false, false, "Ice Fin Pokémon", PokemonType.DRAGON, PokemonType.ICE, 0.8, 30, AbilityId.THERMAL_EXCHANGE, AbilityId.NONE, AbilityId.ICE_BODY, 423, 90, 95, 66, 45, 65, 62, 25, 50, 148, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.BAXCALIBUR, 9, false, false, false, "Ice Dragon Pokémon", PokemonType.DRAGON, PokemonType.ICE, 2.1, 210, AbilityId.THERMAL_EXCHANGE, AbilityId.NONE, AbilityId.ICE_BODY, 600, 115, 145, 92, 75, 86, 87, 10, 50, 300, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.GIMMIGHOUL, 9, false, false, false, "Coin Chest Pokémon", PokemonType.GHOST, null, 0.3, 5, AbilityId.RATTLED, AbilityId.NONE, AbilityId.NONE, 300, 45, 30, 70, 75, 70, 10, 45, 50, 60, GrowthRate.SLOW, null, false, false, + new PokemonForm("Chest Form", "chest", PokemonType.GHOST, null, 0.3, 5, AbilityId.RATTLED, AbilityId.NONE, AbilityId.NONE, 300, 45, 30, 70, 75, 70, 10, 45, 50, 60, false, "", true), + new PokemonForm("Roaming Form", "roaming", PokemonType.GHOST, null, 0.1, 1, AbilityId.RUN_AWAY, AbilityId.NONE, AbilityId.NONE, 300, 45, 30, 25, 75, 45, 80, 45, 50, 60, false, null, true) + ), + new PokemonSpecies(SpeciesId.GHOLDENGO, 9, false, false, false, "Coin Entity Pokémon", PokemonType.STEEL, PokemonType.GHOST, 1.2, 30, AbilityId.GOOD_AS_GOLD, AbilityId.NONE, AbilityId.NONE, 550, 87, 60, 95, 133, 91, 84, 45, 50, 275, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.WO_CHIEN, 9, true, false, false, "Ruinous Pokémon", PokemonType.DARK, PokemonType.GRASS, 1.5, 74.2, AbilityId.TABLETS_OF_RUIN, AbilityId.NONE, AbilityId.NONE, 570, 85, 85, 100, 95, 135, 70, 6, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.CHIEN_PAO, 9, true, false, false, "Ruinous Pokémon", PokemonType.DARK, PokemonType.ICE, 1.9, 152.2, AbilityId.SWORD_OF_RUIN, AbilityId.NONE, AbilityId.NONE, 570, 80, 120, 80, 90, 65, 135, 6, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.TING_LU, 9, true, false, false, "Ruinous Pokémon", PokemonType.DARK, PokemonType.GROUND, 2.7, 699.7, AbilityId.VESSEL_OF_RUIN, AbilityId.NONE, AbilityId.NONE, 570, 155, 110, 125, 55, 80, 45, 6, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.CHI_YU, 9, true, false, false, "Ruinous Pokémon", PokemonType.DARK, PokemonType.FIRE, 0.4, 4.9, AbilityId.BEADS_OF_RUIN, AbilityId.NONE, AbilityId.NONE, 570, 55, 80, 80, 135, 120, 100, 6, 0, 285, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.ROARING_MOON, 9, false, false, false, "Paradox Pokémon", PokemonType.DRAGON, PokemonType.DARK, 2, 380, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 590, 105, 139, 71, 55, 101, 119, 10, 0, 295, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.IRON_VALIANT, 9, false, false, false, "Paradox Pokémon", PokemonType.FAIRY, PokemonType.FIGHTING, 1.4, 35, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 590, 74, 130, 90, 120, 60, 116, 10, 0, 295, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.KORAIDON, 9, false, true, false, "Paradox Pokémon", PokemonType.FIGHTING, PokemonType.DRAGON, 2.5, 303, AbilityId.ORICHALCUM_PULSE, AbilityId.NONE, AbilityId.NONE, 670, 100, 135, 115, 85, 100, 135, 3, 0, 335, GrowthRate.SLOW, null, false, false, + new PokemonForm("Apex Build", "apex-build", PokemonType.FIGHTING, PokemonType.DRAGON, 2.5, 303, AbilityId.ORICHALCUM_PULSE, AbilityId.NONE, AbilityId.NONE, 670, 100, 135, 115, 85, 100, 135, 3, 0, 335, false, null, true) + ), + new PokemonSpecies(SpeciesId.MIRAIDON, 9, false, true, false, "Paradox Pokémon", PokemonType.ELECTRIC, PokemonType.DRAGON, 3.5, 240, AbilityId.HADRON_ENGINE, AbilityId.NONE, AbilityId.NONE, 670, 100, 85, 100, 135, 115, 135, 3, 0, 335, GrowthRate.SLOW, null, false, false, + new PokemonForm("Ultimate Mode", "ultimate-mode", PokemonType.ELECTRIC, PokemonType.DRAGON, 3.5, 240, AbilityId.HADRON_ENGINE, AbilityId.NONE, AbilityId.NONE, 670, 100, 85, 100, 135, 115, 135, 3, 0, 335, false, null, true) + ), + new PokemonSpecies(SpeciesId.WALKING_WAKE, 9, false, false, false, "Paradox Pokémon", PokemonType.WATER, PokemonType.DRAGON, 3.5, 280, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 590, 99, 83, 91, 125, 83, 109, 10, 0, 295, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Gouging Fire and Raging Bolt + new PokemonSpecies(SpeciesId.IRON_LEAVES, 9, false, false, false, "Paradox Pokémon", PokemonType.GRASS, PokemonType.PSYCHIC, 1.5, 125, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 590, 90, 130, 88, 70, 108, 104, 10, 0, 295, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Iron Boulder and Iron Crown + new PokemonSpecies(SpeciesId.DIPPLIN, 9, false, false, false, "Candy Apple Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 0.4, 4.4, AbilityId.SUPERSWEET_SYRUP, AbilityId.GLUTTONY, AbilityId.STICKY_HOLD, 485, 80, 80, 110, 95, 80, 40, 45, 50, 170, GrowthRate.ERRATIC, 50, false), + new PokemonSpecies(SpeciesId.POLTCHAGEIST, 9, false, false, false, "Matcha Pokémon", PokemonType.GRASS, PokemonType.GHOST, 0.1, 1.1, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, GrowthRate.SLOW, null, false, false, + new PokemonForm("Counterfeit Form", "counterfeit", PokemonType.GRASS, PokemonType.GHOST, 0.1, 1.1, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, null, true), + new PokemonForm("Artisan Form", "artisan", PokemonType.GRASS, PokemonType.GHOST, 0.1, 1.1, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, "counterfeit", true) + ), + new PokemonSpecies(SpeciesId.SINISTCHA, 9, false, false, false, "Matcha Pokémon", PokemonType.GRASS, PokemonType.GHOST, 0.2, 2.2, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 508, 71, 60, 106, 121, 80, 70, 60, 50, 178, GrowthRate.SLOW, null, false, false, + new PokemonForm("Unremarkable Form", "unremarkable", PokemonType.GRASS, PokemonType.GHOST, 0.2, 2.2, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 508, 71, 60, 106, 121, 80, 70, 60, 50, 178, false, null, true), + new PokemonForm("Masterpiece Form", "masterpiece", PokemonType.GRASS, PokemonType.GHOST, 0.2, 2.2, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 508, 71, 60, 106, 121, 80, 70, 60, 50, 178, false, "unremarkable", true) + ), + new PokemonSpecies(SpeciesId.OKIDOGI, 9, true, false, false, "Retainer Pokémon", PokemonType.POISON, PokemonType.FIGHTING, 1.8, 92.2, AbilityId.TOXIC_CHAIN, AbilityId.NONE, AbilityId.GUARD_DOG, 555, 88, 128, 115, 58, 86, 80, 3, 0, 276, GrowthRate.SLOW, 100, false), + new PokemonSpecies(SpeciesId.MUNKIDORI, 9, true, false, false, "Retainer Pokémon", PokemonType.POISON, PokemonType.PSYCHIC, 1, 12.2, AbilityId.TOXIC_CHAIN, AbilityId.NONE, AbilityId.FRISK, 555, 88, 75, 66, 130, 90, 106, 3, 0, 276, GrowthRate.SLOW, 100, false), + new PokemonSpecies(SpeciesId.FEZANDIPITI, 9, true, false, false, "Retainer Pokémon", PokemonType.POISON, PokemonType.FAIRY, 1.4, 30.1, AbilityId.TOXIC_CHAIN, AbilityId.NONE, AbilityId.TECHNICIAN, 555, 88, 91, 82, 70, 125, 99, 3, 0, 276, GrowthRate.SLOW, 100, false), + new PokemonSpecies(SpeciesId.OGERPON, 9, true, false, false, "Mask Pokémon", PokemonType.GRASS, null, 1.2, 39.8, AbilityId.DEFIANT, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275, GrowthRate.SLOW, 0, false, false, + new PokemonForm("Teal Mask", "teal-mask", PokemonType.GRASS, null, 1.2, 39.8, AbilityId.DEFIANT, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275, false, null, true), + new PokemonForm("Wellspring Mask", "wellspring-mask", PokemonType.GRASS, PokemonType.WATER, 1.2, 39.8, AbilityId.WATER_ABSORB, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275), + new PokemonForm("Hearthflame Mask", "hearthflame-mask", PokemonType.GRASS, PokemonType.FIRE, 1.2, 39.8, AbilityId.MOLD_BREAKER, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275), + new PokemonForm("Cornerstone Mask", "cornerstone-mask", PokemonType.GRASS, PokemonType.ROCK, 1.2, 39.8, AbilityId.STURDY, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275), + new PokemonForm("Teal Mask Terastallized", "teal-mask-tera", PokemonType.GRASS, null, 1.2, 39.8, AbilityId.EMBODY_ASPECT_TEAL, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275), + new PokemonForm("Wellspring Mask Terastallized", "wellspring-mask-tera", PokemonType.GRASS, PokemonType.WATER, 1.2, 39.8, AbilityId.EMBODY_ASPECT_WELLSPRING, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275), + new PokemonForm("Hearthflame Mask Terastallized", "hearthflame-mask-tera", PokemonType.GRASS, PokemonType.FIRE, 1.2, 39.8, AbilityId.EMBODY_ASPECT_HEARTHFLAME, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275), + new PokemonForm("Cornerstone Mask Terastallized", "cornerstone-mask-tera", PokemonType.GRASS, PokemonType.ROCK, 1.2, 39.8, AbilityId.EMBODY_ASPECT_CORNERSTONE, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275) + ), + new PokemonSpecies(SpeciesId.ARCHALUDON, 9, false, false, false, "Alloy Pokémon", PokemonType.STEEL, PokemonType.DRAGON, 2, 60, AbilityId.STAMINA, AbilityId.STURDY, AbilityId.STALWART, 600, 90, 105, 130, 125, 65, 85, 10, 50, 300, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.HYDRAPPLE, 9, false, false, false, "Apple Hydra Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 1.8, 93, AbilityId.SUPERSWEET_SYRUP, AbilityId.REGENERATOR, AbilityId.STICKY_HOLD, 540, 106, 80, 110, 120, 80, 44, 10, 50, 270, GrowthRate.ERRATIC, 50, false), + new PokemonSpecies(SpeciesId.GOUGING_FIRE, 9, false, false, false, "Paradox Pokémon", PokemonType.FIRE, PokemonType.DRAGON, 3.5, 590, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 590, 105, 115, 121, 65, 93, 91, 10, 0, 295, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.RAGING_BOLT, 9, false, false, false, "Paradox Pokémon", PokemonType.ELECTRIC, PokemonType.DRAGON, 5.2, 480, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 590, 125, 73, 91, 137, 89, 75, 10, 0, 295, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.IRON_BOULDER, 9, false, false, false, "Paradox Pokémon", PokemonType.ROCK, PokemonType.PSYCHIC, 1.5, 162.5, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 590, 90, 120, 80, 68, 108, 124, 10, 0, 295, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.IRON_CROWN, 9, false, false, false, "Paradox Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 1.6, 156, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 590, 90, 72, 100, 122, 108, 98, 10, 0, 295, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.TERAPAGOS, 9, false, true, false, "Tera Pokémon", PokemonType.NORMAL, null, 0.2, 6.5, AbilityId.TERA_SHIFT, AbilityId.NONE, AbilityId.NONE, 450, 90, 65, 85, 65, 85, 60, 5, 50, 90, GrowthRate.SLOW, 50, false, false, + new PokemonForm("Normal Form", "", PokemonType.NORMAL, null, 0.2, 6.5, AbilityId.TERA_SHIFT, AbilityId.NONE, AbilityId.NONE, 450, 90, 65, 85, 65, 85, 60, 5, 50, 90, false, null, true), + new PokemonForm("Terastal Form", "terastal", PokemonType.NORMAL, null, 0.3, 16, AbilityId.TERA_SHELL, AbilityId.NONE, AbilityId.NONE, 600, 95, 95, 110, 105, 110, 85, 5, 50, 120), + new PokemonForm("Stellar Form", "stellar", PokemonType.NORMAL, null, 1.7, 77, AbilityId.TERAFORM_ZERO, AbilityId.NONE, AbilityId.NONE, 700, 160, 105, 110, 130, 110, 85, 5, 50, 140) + ), + new PokemonSpecies(SpeciesId.PECHARUNT, 9, false, false, true, "Subjugation Pokémon", PokemonType.POISON, PokemonType.GHOST, 0.3, 0.3, AbilityId.POISON_PUPPETEER, AbilityId.NONE, AbilityId.NONE, 600, 88, 88, 160, 88, 88, 88, 3, 0, 300, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.ALOLA_RATTATA, 7, false, false, false, "Mouse Pokémon", PokemonType.DARK, PokemonType.NORMAL, 0.3, 3.8, AbilityId.GLUTTONY, AbilityId.HUSTLE, AbilityId.THICK_FAT, 253, 30, 56, 35, 25, 35, 72, 255, 70, 51, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_RATICATE, 7, false, false, false, "Mouse Pokémon", PokemonType.DARK, PokemonType.NORMAL, 0.7, 25.5, AbilityId.GLUTTONY, AbilityId.HUSTLE, AbilityId.THICK_FAT, 413, 75, 71, 70, 40, 80, 77, 127, 70, 145, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_RAICHU, 7, false, false, false, "Mouse Pokémon", PokemonType.ELECTRIC, PokemonType.PSYCHIC, 0.7, 21, AbilityId.SURGE_SURFER, AbilityId.NONE, AbilityId.NONE, 485, 60, 85, 50, 95, 85, 110, 75, 50, 243, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_SANDSHREW, 7, false, false, false, "Mouse Pokémon", PokemonType.ICE, PokemonType.STEEL, 0.7, 40, AbilityId.SNOW_CLOAK, AbilityId.NONE, AbilityId.SLUSH_RUSH, 300, 50, 75, 90, 10, 35, 40, 255, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_SANDSLASH, 7, false, false, false, "Mouse Pokémon", PokemonType.ICE, PokemonType.STEEL, 1.2, 55, AbilityId.SNOW_CLOAK, AbilityId.NONE, AbilityId.SLUSH_RUSH, 450, 75, 100, 120, 25, 65, 65, 90, 50, 158, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_VULPIX, 7, false, false, false, "Fox Pokémon", PokemonType.ICE, null, 0.6, 9.9, AbilityId.SNOW_CLOAK, AbilityId.NONE, AbilityId.SNOW_WARNING, 299, 38, 41, 40, 50, 65, 65, 190, 50, 60, GrowthRate.MEDIUM_FAST, 25, false), + new PokemonSpecies(SpeciesId.ALOLA_NINETALES, 7, false, false, false, "Fox Pokémon", PokemonType.ICE, PokemonType.FAIRY, 1.1, 19.9, AbilityId.SNOW_CLOAK, AbilityId.NONE, AbilityId.SNOW_WARNING, 505, 73, 67, 75, 81, 100, 109, 75, 50, 177, GrowthRate.MEDIUM_FAST, 25, false), + new PokemonSpecies(SpeciesId.ALOLA_DIGLETT, 7, false, false, false, "Mole Pokémon", PokemonType.GROUND, PokemonType.STEEL, 0.2, 1, AbilityId.SAND_VEIL, AbilityId.TANGLING_HAIR, AbilityId.SAND_FORCE, 265, 10, 55, 30, 35, 45, 90, 255, 50, 53, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_DUGTRIO, 7, false, false, false, "Mole Pokémon", PokemonType.GROUND, PokemonType.STEEL, 0.7, 66.6, AbilityId.SAND_VEIL, AbilityId.TANGLING_HAIR, AbilityId.SAND_FORCE, 425, 35, 100, 60, 50, 70, 110, 50, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_MEOWTH, 7, false, false, false, "Scratch Cat Pokémon", PokemonType.DARK, null, 0.4, 4.2, AbilityId.PICKUP, AbilityId.TECHNICIAN, AbilityId.RATTLED, 290, 40, 35, 35, 50, 40, 90, 255, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_PERSIAN, 7, false, false, false, "Classy Cat Pokémon", PokemonType.DARK, null, 1.1, 33, AbilityId.FUR_COAT, AbilityId.TECHNICIAN, AbilityId.RATTLED, 440, 65, 60, 60, 75, 65, 115, 90, 50, 154, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_GEODUDE, 7, false, false, false, "Rock Pokémon", PokemonType.ROCK, PokemonType.ELECTRIC, 0.4, 20.3, AbilityId.MAGNET_PULL, AbilityId.STURDY, AbilityId.GALVANIZE, 300, 40, 80, 100, 30, 30, 20, 255, 70, 60, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_GRAVELER, 7, false, false, false, "Rock Pokémon", PokemonType.ROCK, PokemonType.ELECTRIC, 1, 110, AbilityId.MAGNET_PULL, AbilityId.STURDY, AbilityId.GALVANIZE, 390, 55, 95, 115, 45, 45, 35, 120, 70, 137, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_GOLEM, 7, false, false, false, "Megaton Pokémon", PokemonType.ROCK, PokemonType.ELECTRIC, 1.7, 316, AbilityId.MAGNET_PULL, AbilityId.STURDY, AbilityId.GALVANIZE, 495, 80, 120, 130, 55, 65, 45, 45, 70, 223, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_GRIMER, 7, false, false, false, "Sludge Pokémon", PokemonType.POISON, PokemonType.DARK, 0.7, 42, AbilityId.POISON_TOUCH, AbilityId.GLUTTONY, AbilityId.POWER_OF_ALCHEMY, 325, 80, 80, 50, 40, 50, 25, 190, 70, 65, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_MUK, 7, false, false, false, "Sludge Pokémon", PokemonType.POISON, PokemonType.DARK, 1, 52, AbilityId.POISON_TOUCH, AbilityId.GLUTTONY, AbilityId.POWER_OF_ALCHEMY, 500, 105, 105, 75, 65, 100, 50, 75, 70, 175, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_EXEGGUTOR, 7, false, false, false, "Coconut Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 10.9, 415.6, AbilityId.FRISK, AbilityId.NONE, AbilityId.HARVEST, 530, 95, 105, 85, 125, 75, 45, 45, 50, 186, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.ALOLA_MAROWAK, 7, false, false, false, "Bone Keeper Pokémon", PokemonType.FIRE, PokemonType.GHOST, 1, 34, AbilityId.CURSED_BODY, AbilityId.LIGHTNING_ROD, AbilityId.ROCK_HEAD, 425, 60, 80, 110, 50, 80, 45, 75, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.ETERNAL_FLOETTE, 6, true, false, false, "Single Bloom Pokémon", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 551, 74, 65, 67, 125, 128, 92, 120, 70, 243, GrowthRate.MEDIUM_FAST, 0, false), //Marked as Sub-Legend, for casing purposes + new PokemonSpecies(SpeciesId.GALAR_MEOWTH, 8, false, false, false, "Scratch Cat Pokémon", PokemonType.STEEL, null, 0.4, 7.5, AbilityId.PICKUP, AbilityId.TOUGH_CLAWS, AbilityId.UNNERVE, 290, 50, 65, 55, 40, 40, 40, 255, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GALAR_PONYTA, 8, false, false, false, "Fire Horse Pokémon", PokemonType.PSYCHIC, null, 0.8, 24, AbilityId.RUN_AWAY, AbilityId.PASTEL_VEIL, AbilityId.ANTICIPATION, 410, 50, 85, 55, 65, 65, 90, 190, 50, 82, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GALAR_RAPIDASH, 8, false, false, false, "Fire Horse Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 1.7, 80, AbilityId.RUN_AWAY, AbilityId.PASTEL_VEIL, AbilityId.ANTICIPATION, 500, 65, 100, 70, 80, 80, 105, 60, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GALAR_SLOWPOKE, 8, false, false, false, "Dopey Pokémon", PokemonType.PSYCHIC, null, 1.2, 36, AbilityId.GLUTTONY, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 315, 90, 65, 65, 40, 40, 15, 190, 50, 63, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GALAR_SLOWBRO, 8, false, false, false, "Hermit Crab Pokémon", PokemonType.POISON, PokemonType.PSYCHIC, 1.6, 70.5, AbilityId.QUICK_DRAW, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 490, 95, 100, 95, 100, 70, 30, 75, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GALAR_FARFETCHD, 8, false, false, false, "Wild Duck Pokémon", PokemonType.FIGHTING, null, 0.8, 42, AbilityId.STEADFAST, AbilityId.NONE, AbilityId.SCRAPPY, 377, 52, 95, 55, 58, 62, 55, 45, 50, 132, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GALAR_WEEZING, 8, false, false, false, "Poison Gas Pokémon", PokemonType.POISON, PokemonType.FAIRY, 3, 16, AbilityId.LEVITATE, AbilityId.NEUTRALIZING_GAS, AbilityId.MISTY_SURGE, 490, 65, 90, 120, 85, 70, 60, 60, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GALAR_MR_MIME, 8, false, false, false, "Barrier Pokémon", PokemonType.ICE, PokemonType.PSYCHIC, 1.4, 56.8, AbilityId.VITAL_SPIRIT, AbilityId.SCREEN_CLEANER, AbilityId.ICE_BODY, 460, 50, 65, 65, 90, 90, 100, 45, 50, 161, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GALAR_ARTICUNO, 8, true, false, false, "Freeze Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 1.7, 50.9, AbilityId.COMPETITIVE, AbilityId.NONE, AbilityId.NONE, 580, 90, 85, 85, 125, 100, 95, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.GALAR_ZAPDOS, 8, true, false, false, "Electric Pokémon", PokemonType.FIGHTING, PokemonType.FLYING, 1.6, 58.2, AbilityId.DEFIANT, AbilityId.NONE, AbilityId.NONE, 580, 90, 125, 90, 85, 90, 100, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.GALAR_MOLTRES, 8, true, false, false, "Flame Pokémon", PokemonType.DARK, PokemonType.FLYING, 2, 66, AbilityId.BERSERK, AbilityId.NONE, AbilityId.NONE, 580, 90, 85, 90, 100, 125, 90, 3, 35, 290, GrowthRate.SLOW, null, false), + new PokemonSpecies(SpeciesId.GALAR_SLOWKING, 8, false, false, false, "Royal Pokémon", PokemonType.POISON, PokemonType.PSYCHIC, 1.8, 79.5, AbilityId.CURIOUS_MEDICINE, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 490, 95, 65, 80, 110, 110, 30, 70, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GALAR_CORSOLA, 8, false, false, false, "Coral Pokémon", PokemonType.GHOST, null, 0.6, 0.5, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 410, 60, 55, 100, 65, 100, 30, 60, 50, 144, GrowthRate.FAST, 25, false), + new PokemonSpecies(SpeciesId.GALAR_ZIGZAGOON, 8, false, false, false, "Tiny Raccoon Pokémon", PokemonType.DARK, PokemonType.NORMAL, 0.4, 17.5, AbilityId.PICKUP, AbilityId.GLUTTONY, AbilityId.QUICK_FEET, 240, 38, 30, 41, 30, 41, 60, 255, 50, 56, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GALAR_LINOONE, 8, false, false, false, "Rushing Pokémon", PokemonType.DARK, PokemonType.NORMAL, 0.5, 32.5, AbilityId.PICKUP, AbilityId.GLUTTONY, AbilityId.QUICK_FEET, 420, 78, 70, 61, 50, 61, 100, 90, 50, 147, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GALAR_DARUMAKA, 8, false, false, false, "Zen Charm Pokémon", PokemonType.ICE, null, 0.7, 40, AbilityId.HUSTLE, AbilityId.NONE, AbilityId.INNER_FOCUS, 315, 70, 90, 45, 15, 45, 50, 120, 50, 63, GrowthRate.MEDIUM_SLOW, 50, false), + new PokemonSpecies(SpeciesId.GALAR_DARMANITAN, 8, false, false, false, "Blazing Pokémon", PokemonType.ICE, null, 1.7, 120, AbilityId.GORILLA_TACTICS, AbilityId.NONE, AbilityId.ZEN_MODE, 480, 105, 140, 55, 30, 55, 95, 60, 50, 168, GrowthRate.MEDIUM_SLOW, 50, false, true, + new PokemonForm("Standard Mode", "", PokemonType.ICE, null, 1.7, 120, AbilityId.GORILLA_TACTICS, AbilityId.NONE, AbilityId.ZEN_MODE, 480, 105, 140, 55, 30, 55, 95, 60, 50, 168, false, null, true), + new PokemonForm("Zen Mode", "zen", PokemonType.ICE, PokemonType.FIRE, 1.7, 120, AbilityId.GORILLA_TACTICS, AbilityId.NONE, AbilityId.ZEN_MODE, 540, 105, 160, 55, 30, 55, 135, 60, 50, 189) + ), + new PokemonSpecies(SpeciesId.GALAR_YAMASK, 8, false, false, false, "Spirit Pokémon", PokemonType.GROUND, PokemonType.GHOST, 0.5, 1.5, AbilityId.WANDERING_SPIRIT, AbilityId.NONE, AbilityId.NONE, 303, 38, 55, 85, 30, 65, 30, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.GALAR_STUNFISK, 8, false, false, false, "Trap Pokémon", PokemonType.GROUND, PokemonType.STEEL, 0.7, 20.5, AbilityId.MIMICRY, AbilityId.NONE, AbilityId.NONE, 471, 109, 81, 99, 66, 84, 32, 75, 70, 165, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.HISUI_GROWLITHE, 8, false, false, false, "Puppy Pokémon", PokemonType.FIRE, PokemonType.ROCK, 0.8, 22.7, AbilityId.INTIMIDATE, AbilityId.FLASH_FIRE, AbilityId.ROCK_HEAD, 350, 60, 75, 45, 65, 50, 55, 190, 50, 70, GrowthRate.SLOW, 75, false), + new PokemonSpecies(SpeciesId.HISUI_ARCANINE, 8, false, false, false, "Legendary Pokémon", PokemonType.FIRE, PokemonType.ROCK, 2, 168, AbilityId.INTIMIDATE, AbilityId.FLASH_FIRE, AbilityId.ROCK_HEAD, 555, 95, 115, 80, 95, 80, 90, 85, 50, 194, GrowthRate.SLOW, 75, false), + new PokemonSpecies(SpeciesId.HISUI_VOLTORB, 8, false, false, false, "Ball Pokémon", PokemonType.ELECTRIC, PokemonType.GRASS, 0.5, 13, AbilityId.SOUNDPROOF, AbilityId.STATIC, AbilityId.AFTERMATH, 330, 40, 30, 50, 55, 55, 100, 190, 80, 66, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.HISUI_ELECTRODE, 8, false, false, false, "Ball Pokémon", PokemonType.ELECTRIC, PokemonType.GRASS, 1.2, 81, AbilityId.SOUNDPROOF, AbilityId.STATIC, AbilityId.AFTERMATH, 490, 60, 50, 70, 80, 80, 150, 60, 70, 172, GrowthRate.MEDIUM_FAST, null, false), + new PokemonSpecies(SpeciesId.HISUI_TYPHLOSION, 8, false, false, false, "Volcano Pokémon", PokemonType.FIRE, PokemonType.GHOST, 1.6, 69.8, AbilityId.BLAZE, AbilityId.NONE, AbilityId.FRISK, 534, 73, 84, 78, 119, 85, 95, 45, 70, 240, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.HISUI_QWILFISH, 8, false, false, false, "Balloon Pokémon", PokemonType.DARK, PokemonType.POISON, 0.5, 3.9, AbilityId.POISON_POINT, AbilityId.SWIFT_SWIM, AbilityId.INTIMIDATE, 440, 65, 95, 85, 55, 55, 85, 45, 50, 88, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.HISUI_SNEASEL, 8, false, false, false, "Sharp Claw Pokémon", PokemonType.FIGHTING, PokemonType.POISON, 0.9, 27, AbilityId.INNER_FOCUS, AbilityId.KEEN_EYE, AbilityId.PICKPOCKET, 430, 55, 95, 55, 35, 75, 115, 60, 35, 86, GrowthRate.MEDIUM_SLOW, 50, true), + new PokemonSpecies(SpeciesId.HISUI_SAMUROTT, 8, false, false, false, "Formidable Pokémon", PokemonType.WATER, PokemonType.DARK, 1.5, 58.2, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHARPNESS, 528, 90, 108, 80, 100, 65, 85, 45, 80, 238, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.HISUI_LILLIGANT, 8, false, false, false, "Flowering Pokémon", PokemonType.GRASS, PokemonType.FIGHTING, 1.2, 19.2, AbilityId.CHLOROPHYLL, AbilityId.HUSTLE, AbilityId.LEAF_GUARD, 480, 70, 105, 75, 50, 75, 105, 75, 50, 168, GrowthRate.MEDIUM_FAST, 0, false), + new PokemonSpecies(SpeciesId.HISUI_ZORUA, 8, false, false, false, "Tricky Fox Pokémon", PokemonType.NORMAL, PokemonType.GHOST, 0.7, 12.5, AbilityId.ILLUSION, AbilityId.NONE, AbilityId.NONE, 330, 35, 60, 40, 85, 40, 70, 75, 50, 66, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.HISUI_ZOROARK, 8, false, false, false, "Illusion Fox Pokémon", PokemonType.NORMAL, PokemonType.GHOST, 1.6, 83, AbilityId.ILLUSION, AbilityId.NONE, AbilityId.NONE, 510, 55, 100, 60, 125, 60, 110, 45, 50, 179, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.HISUI_BRAVIARY, 8, false, false, false, "Valiant Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 1.7, 43.4, AbilityId.KEEN_EYE, AbilityId.SHEER_FORCE, AbilityId.TINTED_LENS, 510, 110, 83, 70, 112, 70, 65, 60, 50, 179, GrowthRate.SLOW, 100, false), + new PokemonSpecies(SpeciesId.HISUI_SLIGGOO, 8, false, false, false, "Soft Tissue Pokémon", PokemonType.STEEL, PokemonType.DRAGON, 0.7, 68.5, AbilityId.SAP_SIPPER, AbilityId.SHELL_ARMOR, AbilityId.GOOEY, 452, 58, 75, 83, 83, 113, 40, 45, 35, 158, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.HISUI_GOODRA, 8, false, false, false, "Dragon Pokémon", PokemonType.STEEL, PokemonType.DRAGON, 1.7, 334.1, AbilityId.SAP_SIPPER, AbilityId.SHELL_ARMOR, AbilityId.GOOEY, 600, 80, 100, 100, 110, 150, 60, 45, 35, 270, GrowthRate.SLOW, 50, false), + new PokemonSpecies(SpeciesId.HISUI_AVALUGG, 8, false, false, false, "Iceberg Pokémon", PokemonType.ICE, PokemonType.ROCK, 1.4, 262.4, AbilityId.STRONG_JAW, AbilityId.ICE_BODY, AbilityId.STURDY, 514, 95, 127, 184, 34, 36, 38, 55, 50, 180, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.HISUI_DECIDUEYE, 8, false, false, false, "Arrow Quill Pokémon", PokemonType.GRASS, PokemonType.FIGHTING, 1.6, 37, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.SCRAPPY, 530, 88, 112, 80, 95, 95, 60, 45, 50, 239, GrowthRate.MEDIUM_SLOW, 87.5, false), + new PokemonSpecies(SpeciesId.PALDEA_TAUROS, 9, false, false, false, "Wild Bull Pokémon", PokemonType.FIGHTING, null, 1.4, 115, AbilityId.INTIMIDATE, AbilityId.ANGER_POINT, AbilityId.CUD_CHEW, 490, 75, 110, 105, 30, 70, 100, 45, 50, 172, GrowthRate.SLOW, 100, false, false, + new PokemonForm("Combat Breed", "combat", PokemonType.FIGHTING, null, 1.4, 115, AbilityId.INTIMIDATE, AbilityId.ANGER_POINT, AbilityId.CUD_CHEW, 490, 75, 110, 105, 30, 70, 100, 45, 50, 172, false, "", true), + new PokemonForm("Blaze Breed", "blaze", PokemonType.FIGHTING, PokemonType.FIRE, 1.4, 85, AbilityId.INTIMIDATE, AbilityId.ANGER_POINT, AbilityId.CUD_CHEW, 490, 75, 110, 105, 30, 70, 100, 45, 50, 172, false, null, true), + new PokemonForm("Aqua Breed", "aqua", PokemonType.FIGHTING, PokemonType.WATER, 1.4, 110, AbilityId.INTIMIDATE, AbilityId.ANGER_POINT, AbilityId.CUD_CHEW, 490, 75, 110, 105, 30, 70, 100, 45, 50, 172, false, null, true) + ), + new PokemonSpecies(SpeciesId.PALDEA_WOOPER, 9, false, false, false, "Water Fish Pokémon", PokemonType.POISON, PokemonType.GROUND, 0.4, 11, AbilityId.POISON_POINT, AbilityId.WATER_ABSORB, AbilityId.UNAWARE, 210, 55, 45, 45, 25, 25, 15, 255, 50, 42, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(SpeciesId.BLOODMOON_URSALUNA, 9, true, false, false, "Peat Pokémon", PokemonType.GROUND, PokemonType.NORMAL, 2.7, 333, AbilityId.MINDS_EYE, AbilityId.NONE, AbilityId.NONE, 555, 113, 70, 120, 135, 65, 52, 75, 50, 278, GrowthRate.MEDIUM_FAST, 50, false) + ); +} diff --git a/src/data/challenge.ts b/src/data/challenge.ts index fd6528bb3bc..1a1a3774f8f 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -6,7 +6,6 @@ import { pokemonEvolutions } from "#balance/pokemon-evolutions"; import { speciesStarterCosts } from "#balance/starters"; import { pokemonFormChanges } from "#data/pokemon-forms"; import type { PokemonSpecies } from "#data/pokemon-species"; -import { getPokemonSpeciesForm } from "#data/pokemon-species"; import { BattleType } from "#enums/battle-type"; import { ChallengeType } from "#enums/challenge-type"; import { Challenges } from "#enums/challenges"; @@ -26,7 +25,7 @@ import { PokemonMove } from "#moves/pokemon-move"; import type { DexAttrProps, GameData } from "#system/game-data"; import { BooleanHolder, isBetween, type NumberHolder, randSeedItem } from "#utils/common"; import { deepCopy } from "#utils/data"; -import { getPokemonSpecies } from "#utils/pokemon-utils"; +import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; import { toCamelCase, toSnakeCase } from "#utils/strings"; import i18next from "i18next"; diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index 9a6f560933a..b5fb0aa8c07 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -2,7 +2,7 @@ import { pokerogueApi } from "#api/pokerogue-api"; import { globalScene } from "#app/global-scene"; import { speciesStarterCosts } from "#balance/starters"; import type { PokemonSpeciesForm } from "#data/pokemon-species"; -import { getPokemonSpeciesForm, PokemonSpecies } from "#data/pokemon-species"; +import { PokemonSpecies } from "#data/pokemon-species"; import { BiomeId } from "#enums/biome-id"; import { PartyMemberStrength } from "#enums/party-member-strength"; import type { SpeciesId } from "#enums/species-id"; @@ -10,7 +10,7 @@ import { PlayerPokemon } from "#field/pokemon"; import type { Starter } from "#ui/starter-select-ui-handler"; import { randSeedGauss, randSeedInt, randSeedItem } from "#utils/common"; import { getEnumValues } from "#utils/enums"; -import { getPokemonSpecies } from "#utils/pokemon-utils"; +import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; export interface DailyRunConfig { seed: number; diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index dfaa6425ef1..7bfe02d9086 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -12,14 +12,13 @@ import { pokemonFormLevelMoves as pokemonSpeciesFormLevelMoves, pokemonSpeciesLevelMoves, } from "#balance/pokemon-level-moves"; -import { POKERUS_STARTER_COUNT, speciesStarterCosts } from "#balance/starters"; -import { allSpecies } from "#data/data-lists"; -import { GrowthRate } from "#data/exp"; +import { speciesStarterCosts } from "#balance/starters"; +import type { GrowthRate } from "#data/exp"; import { Gender } from "#data/gender"; import { AbilityId } from "#enums/ability-id"; import { DexAttr } from "#enums/dex-attr"; import { PartyMemberStrength } from "#enums/party-member-strength"; -import { PokemonType } from "#enums/pokemon-type"; +import type { PokemonType } from "#enums/pokemon-type"; import { SpeciesFormKey } from "#enums/species-form-key"; import { SpeciesId } from "#enums/species-id"; import type { Stat } from "#enums/stat"; @@ -29,7 +28,7 @@ import type { Variant, VariantSet } from "#sprites/variant"; import { populateVariantColorCache, variantColorCache, variantData } from "#sprites/variant"; import type { StarterMoveset } from "#system/game-data"; import type { Localizable } from "#types/locales"; -import { isNullOrUndefined, randSeedFloat, randSeedGauss, randSeedInt, randSeedItem } from "#utils/common"; +import { isNullOrUndefined, randSeedFloat, randSeedGauss, randSeedInt } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import { toCamelCase, toPascalCase } from "#utils/strings"; import { argbFromRgba, QuantizerCelebi, rgbaFromArgb } from "@material/material-color-utilities"; @@ -74,84 +73,6 @@ export const normalForm: SpeciesId[] = [ SpeciesId.CALYREX, ]; -export function getPokemonSpeciesForm(species: SpeciesId, formIndex: number): PokemonSpeciesForm { - const retSpecies: PokemonSpecies = - species >= 2000 - ? allSpecies.find(s => s.speciesId === species)! // TODO: is the bang correct? - : allSpecies[species - 1]; - if (formIndex < retSpecies.forms?.length) { - return retSpecies.forms[formIndex]; - } - return retSpecies; -} - -// TODO: Clean this up and seriously review alternate means of fusion naming -export function getFusedSpeciesName(speciesAName: string, speciesBName: string): string { - const fragAPattern = /([a-z]{2}.*?[aeiou(?:y$)\-']+)(.*?)$/i; - const fragBPattern = /([a-z]{2}.*?[aeiou(?:y$)\-'])(.*?)$/i; - - const [speciesAPrefixMatch, speciesBPrefixMatch] = [speciesAName, speciesBName].map(n => /^(?:[^ ]+) /.exec(n)); - const [speciesAPrefix, speciesBPrefix] = [speciesAPrefixMatch, speciesBPrefixMatch].map(m => (m ? m[0] : "")); - - if (speciesAPrefix) { - speciesAName = speciesAName.slice(speciesAPrefix.length); - } - if (speciesBPrefix) { - speciesBName = speciesBName.slice(speciesBPrefix.length); - } - - const [speciesASuffixMatch, speciesBSuffixMatch] = [speciesAName, speciesBName].map(n => / (?:[^ ]+)$/.exec(n)); - const [speciesASuffix, speciesBSuffix] = [speciesASuffixMatch, speciesBSuffixMatch].map(m => (m ? m[0] : "")); - - if (speciesASuffix) { - speciesAName = speciesAName.slice(0, -speciesASuffix.length); - } - if (speciesBSuffix) { - speciesBName = speciesBName.slice(0, -speciesBSuffix.length); - } - - const splitNameA = speciesAName.split(/ /g); - const splitNameB = speciesBName.split(/ /g); - - const fragAMatch = fragAPattern.exec(speciesAName); - const fragBMatch = fragBPattern.exec(speciesBName); - - let fragA: string; - let fragB: string; - - fragA = splitNameA.length === 1 ? (fragAMatch ? fragAMatch[1] : speciesAName) : splitNameA[splitNameA.length - 1]; - - if (splitNameB.length === 1) { - if (fragBMatch) { - const lastCharA = fragA.slice(fragA.length - 1); - const prevCharB = fragBMatch[1].slice(fragBMatch.length - 1); - fragB = (/[-']/.test(prevCharB) ? prevCharB : "") + fragBMatch[2] || prevCharB; - if (lastCharA === fragB[0]) { - if (/[aiu]/.test(lastCharA)) { - fragB = fragB.slice(1); - } else { - const newCharMatch = new RegExp(`[^${lastCharA}]`).exec(fragB); - if (newCharMatch?.index !== undefined && newCharMatch.index > 0) { - fragB = fragB.slice(newCharMatch.index); - } - } - } - } else { - fragB = speciesBName; - } - } else { - fragB = splitNameB[splitNameB.length - 1]; - } - - if (splitNameA.length > 1) { - fragA = `${splitNameA.slice(0, splitNameA.length - 1).join(" ")} ${fragA}`; - } - - fragB = `${fragB.slice(0, 1).toLowerCase()}${fragB.slice(1)}`; - - return `${speciesAPrefix || speciesBPrefix}${fragA}${fragB}${speciesBSuffix || speciesASuffix}`; -} - export type PokemonSpeciesFilter = (species: PokemonSpecies) => boolean; export abstract class PokemonSpeciesForm { @@ -1400,1804 +1321,3 @@ export class PokemonForm extends PokemonSpeciesForm { return this.formSpriteKey !== null ? this.formSpriteKey : this.formKey; } } - -/** - * Method to get the daily list of starters with Pokerus. - * @returns A list of starters with Pokerus - */ -export function getPokerusStarters(): PokemonSpecies[] { - const pokerusStarters: PokemonSpecies[] = []; - const date = new Date(); - date.setUTCHours(0, 0, 0, 0); - globalScene.executeWithSeedOffset( - () => { - while (pokerusStarters.length < POKERUS_STARTER_COUNT) { - const randomSpeciesId = Number.parseInt(randSeedItem(Object.keys(speciesStarterCosts)), 10); - const species = getPokemonSpecies(randomSpeciesId); - if (!pokerusStarters.includes(species)) { - pokerusStarters.push(species); - } - } - }, - 0, - date.getTime().toString(), - ); - return pokerusStarters; -} - -// biome-ignore format: manually formatted -export function initSpecies() { - allSpecies.push( - new PokemonSpecies(SpeciesId.BULBASAUR, 1, false, false, false, "Seed Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.7, 6.9, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CHLOROPHYLL, 318, 45, 49, 49, 65, 65, 45, 45, 50, 64, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.IVYSAUR, 1, false, false, false, "Seed Pokémon", PokemonType.GRASS, PokemonType.POISON, 1, 13, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CHLOROPHYLL, 405, 60, 62, 63, 80, 80, 60, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.VENUSAUR, 1, false, false, false, "Seed Pokémon", PokemonType.GRASS, PokemonType.POISON, 2, 100, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, GrowthRate.MEDIUM_SLOW, 87.5, true, true, - new PokemonForm("Normal", "", PokemonType.GRASS, PokemonType.POISON, 2, 100, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, true, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.GRASS, PokemonType.POISON, 2.4, 155.5, AbilityId.THICK_FAT, AbilityId.THICK_FAT, AbilityId.THICK_FAT, 625, 80, 100, 123, 122, 120, 80, 45, 50, 263, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GRASS, PokemonType.POISON, 24, 999.9, AbilityId.EFFECT_SPORE, AbilityId.NONE, AbilityId.EFFECT_SPORE, 625, 120, 122, 90, 108, 105, 80, 45, 50, 263, true), - ), - new PokemonSpecies(SpeciesId.CHARMANDER, 1, false, false, false, "Lizard Pokémon", PokemonType.FIRE, null, 0.6, 8.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SOLAR_POWER, 309, 39, 52, 43, 60, 50, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.CHARMELEON, 1, false, false, false, "Flame Pokémon", PokemonType.FIRE, null, 1.1, 19, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SOLAR_POWER, 405, 58, 64, 58, 80, 65, 80, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.CHARIZARD, 1, false, false, false, "Flame Pokémon", PokemonType.FIRE, PokemonType.FLYING, 1.7, 90.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SOLAR_POWER, 534, 78, 84, 78, 109, 85, 100, 45, 50, 267, GrowthRate.MEDIUM_SLOW, 87.5, false, true, - new PokemonForm("Normal", "", PokemonType.FIRE, PokemonType.FLYING, 1.7, 90.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SOLAR_POWER, 534, 78, 84, 78, 109, 85, 100, 45, 50, 267, false, null, true), - new PokemonForm("Mega X", SpeciesFormKey.MEGA_X, PokemonType.FIRE, PokemonType.DRAGON, 1.7, 110.5, AbilityId.TOUGH_CLAWS, AbilityId.NONE, AbilityId.TOUGH_CLAWS, 634, 78, 130, 111, 130, 85, 100, 45, 50, 267), - new PokemonForm("Mega Y", SpeciesFormKey.MEGA_Y, PokemonType.FIRE, PokemonType.FLYING, 1.7, 100.5, AbilityId.DROUGHT, AbilityId.NONE, AbilityId.DROUGHT, 634, 78, 104, 78, 159, 115, 100, 45, 50, 267), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIRE, PokemonType.FLYING, 28, 999.9, AbilityId.BERSERK, AbilityId.NONE, AbilityId.BERSERK, 634, 118, 99, 88, 134, 95, 100, 45, 50, 267), - ), - new PokemonSpecies(SpeciesId.SQUIRTLE, 1, false, false, false, "Tiny Turtle Pokémon", PokemonType.WATER, null, 0.5, 9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.RAIN_DISH, 314, 44, 48, 65, 50, 64, 43, 45, 50, 63, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.WARTORTLE, 1, false, false, false, "Turtle Pokémon", PokemonType.WATER, null, 1, 22.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.RAIN_DISH, 405, 59, 63, 80, 65, 80, 58, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.BLASTOISE, 1, false, false, false, "Shellfish Pokémon", PokemonType.WATER, null, 1.6, 85.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, - new PokemonForm("Normal", "", PokemonType.WATER, null, 1.6, 85.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.WATER, null, 1.6, 101.1, AbilityId.MEGA_LAUNCHER, AbilityId.NONE, AbilityId.MEGA_LAUNCHER, 630, 79, 103, 120, 135, 115, 78, 45, 50, 265), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, PokemonType.STEEL, 25, 999.9, AbilityId.SHELL_ARMOR, AbilityId.NONE, AbilityId.SHELL_ARMOR, 630, 119, 108, 125, 105, 110, 63, 45, 50, 265), - ), - new PokemonSpecies(SpeciesId.CATERPIE, 1, false, false, false, "Worm Pokémon", PokemonType.BUG, null, 0.3, 2.9, AbilityId.SHIELD_DUST, AbilityId.NONE, AbilityId.RUN_AWAY, 195, 45, 30, 35, 20, 20, 45, 255, 50, 39, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.METAPOD, 1, false, false, false, "Cocoon Pokémon", PokemonType.BUG, null, 0.7, 9.9, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.SHED_SKIN, 205, 50, 20, 55, 25, 25, 30, 120, 50, 72, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BUTTERFREE, 1, false, false, false, "Butterfly Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.1, 32, AbilityId.COMPOUND_EYES, AbilityId.NONE, AbilityId.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, GrowthRate.MEDIUM_FAST, 50, true, true, - new PokemonForm("Normal", "", PokemonType.BUG, PokemonType.FLYING, 1.1, 32, AbilityId.COMPOUND_EYES, AbilityId.NONE, AbilityId.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, true, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.BUG, PokemonType.FLYING, 17, 999.9, AbilityId.COMPOUND_EYES, AbilityId.NONE, AbilityId.COMPOUND_EYES, 495, 80, 40, 75, 120, 95, 85, 45, 50, 198, true), - ), - new PokemonSpecies(SpeciesId.WEEDLE, 1, false, false, false, "Hairy Bug Pokémon", PokemonType.BUG, PokemonType.POISON, 0.3, 3.2, AbilityId.SHIELD_DUST, AbilityId.NONE, AbilityId.RUN_AWAY, 195, 40, 35, 30, 20, 20, 50, 255, 70, 39, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.KAKUNA, 1, false, false, false, "Cocoon Pokémon", PokemonType.BUG, PokemonType.POISON, 0.6, 10, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.SHED_SKIN, 205, 45, 25, 50, 25, 25, 35, 120, 70, 72, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BEEDRILL, 1, false, false, false, "Poison Bee Pokémon", PokemonType.BUG, PokemonType.POISON, 1, 29.5, AbilityId.SWARM, AbilityId.NONE, AbilityId.SNIPER, 395, 65, 90, 40, 45, 80, 75, 45, 70, 198, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.BUG, PokemonType.POISON, 1, 29.5, AbilityId.SWARM, AbilityId.NONE, AbilityId.SNIPER, 395, 65, 90, 40, 45, 80, 75, 45, 70, 198, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.BUG, PokemonType.POISON, 1.4, 40.5, AbilityId.ADAPTABILITY, AbilityId.NONE, AbilityId.ADAPTABILITY, 495, 65, 150, 40, 15, 80, 145, 45, 70, 198), - ), - new PokemonSpecies(SpeciesId.PIDGEY, 1, false, false, false, "Tiny Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 1.8, AbilityId.KEEN_EYE, AbilityId.TANGLED_FEET, AbilityId.BIG_PECKS, 251, 40, 45, 40, 35, 35, 56, 255, 70, 50, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.PIDGEOTTO, 1, false, false, false, "Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.1, 30, AbilityId.KEEN_EYE, AbilityId.TANGLED_FEET, AbilityId.BIG_PECKS, 349, 63, 60, 55, 50, 50, 71, 120, 70, 122, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.PIDGEOT, 1, false, false, false, "Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.5, 39.5, AbilityId.KEEN_EYE, AbilityId.TANGLED_FEET, AbilityId.BIG_PECKS, 479, 83, 80, 75, 70, 70, 101, 45, 70, 240, GrowthRate.MEDIUM_SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.NORMAL, PokemonType.FLYING, 1.5, 39.5, AbilityId.KEEN_EYE, AbilityId.TANGLED_FEET, AbilityId.BIG_PECKS, 479, 83, 80, 75, 70, 70, 101, 45, 70, 240, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.NORMAL, PokemonType.FLYING, 2.2, 50.5, AbilityId.NO_GUARD, AbilityId.NO_GUARD, AbilityId.NO_GUARD, 579, 83, 80, 80, 135, 80, 121, 45, 70, 240), - ), - new PokemonSpecies(SpeciesId.RATTATA, 1, false, false, false, "Mouse Pokémon", PokemonType.NORMAL, null, 0.3, 3.5, AbilityId.RUN_AWAY, AbilityId.GUTS, AbilityId.HUSTLE, 253, 30, 56, 35, 25, 35, 72, 255, 70, 51, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.RATICATE, 1, false, false, false, "Mouse Pokémon", PokemonType.NORMAL, null, 0.7, 18.5, AbilityId.RUN_AWAY, AbilityId.GUTS, AbilityId.HUSTLE, 413, 55, 81, 60, 50, 70, 97, 127, 70, 145, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.SPEAROW, 1, false, false, false, "Tiny Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 2, AbilityId.KEEN_EYE, AbilityId.NONE, AbilityId.SNIPER, 262, 40, 60, 30, 31, 31, 70, 255, 70, 52, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.FEAROW, 1, false, false, false, "Beak Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.2, 38, AbilityId.KEEN_EYE, AbilityId.NONE, AbilityId.SNIPER, 442, 65, 90, 65, 61, 61, 100, 90, 70, 155, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.EKANS, 1, false, false, false, "Snake Pokémon", PokemonType.POISON, null, 2, 6.9, AbilityId.INTIMIDATE, AbilityId.SHED_SKIN, AbilityId.UNNERVE, 288, 35, 60, 44, 40, 54, 55, 255, 70, 58, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ARBOK, 1, false, false, false, "Cobra Pokémon", PokemonType.POISON, null, 3.5, 65, AbilityId.INTIMIDATE, AbilityId.SHED_SKIN, AbilityId.UNNERVE, 448, 60, 95, 69, 65, 79, 80, 90, 70, 157, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PIKACHU, 1, false, false, false, "Mouse Pokémon", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 320, 35, 55, 40, 50, 50, 90, 190, 50, 112, GrowthRate.MEDIUM_FAST, 50, true, true, - new PokemonForm("Normal", "", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 320, 35, 55, 40, 50, 50, 90, 190, 50, 112, true, null, true), - new PokemonForm("Partner", "partner", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), - new PokemonForm("Cosplay", "cosplay", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom - new PokemonForm("Cool Cosplay", "cool-cosplay", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom - new PokemonForm("Beauty Cosplay", "beauty-cosplay", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom - new PokemonForm("Cute Cosplay", "cute-cosplay", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom - new PokemonForm("Smart Cosplay", "smart-cosplay", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom - new PokemonForm("Tough Cosplay", "tough-cosplay", PokemonType.ELECTRIC, null, 0.4, 6, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.ELECTRIC, null, 21, 999.9, AbilityId.LIGHTNING_ROD, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 530, 125, 95, 60, 90, 70, 90, 190, 50, 112), //+100 BST from Partner Form - ), - new PokemonSpecies(SpeciesId.RAICHU, 1, false, false, false, "Mouse Pokémon", PokemonType.ELECTRIC, null, 0.8, 30, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 485, 60, 90, 55, 90, 80, 110, 75, 50, 243, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.SANDSHREW, 1, false, false, false, "Mouse Pokémon", PokemonType.GROUND, null, 0.6, 12, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.SAND_RUSH, 300, 50, 75, 85, 20, 30, 40, 255, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SANDSLASH, 1, false, false, false, "Mouse Pokémon", PokemonType.GROUND, null, 1, 29.5, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.SAND_RUSH, 450, 75, 100, 110, 45, 55, 65, 90, 50, 158, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.NIDORAN_F, 1, false, false, false, "Poison Pin Pokémon", PokemonType.POISON, null, 0.4, 7, AbilityId.POISON_POINT, AbilityId.RIVALRY, AbilityId.HUSTLE, 275, 55, 47, 52, 40, 40, 41, 235, 50, 55, GrowthRate.MEDIUM_SLOW, 0, false), - new PokemonSpecies(SpeciesId.NIDORINA, 1, false, false, false, "Poison Pin Pokémon", PokemonType.POISON, null, 0.8, 20, AbilityId.POISON_POINT, AbilityId.RIVALRY, AbilityId.HUSTLE, 365, 70, 62, 67, 55, 55, 56, 120, 50, 128, GrowthRate.MEDIUM_SLOW, 0, false), - new PokemonSpecies(SpeciesId.NIDOQUEEN, 1, false, false, false, "Drill Pokémon", PokemonType.POISON, PokemonType.GROUND, 1.3, 60, AbilityId.POISON_POINT, AbilityId.RIVALRY, AbilityId.SHEER_FORCE, 505, 90, 92, 87, 75, 85, 76, 45, 50, 253, GrowthRate.MEDIUM_SLOW, 0, false), - new PokemonSpecies(SpeciesId.NIDORAN_M, 1, false, false, false, "Poison Pin Pokémon", PokemonType.POISON, null, 0.5, 9, AbilityId.POISON_POINT, AbilityId.RIVALRY, AbilityId.HUSTLE, 273, 46, 57, 40, 40, 40, 50, 235, 50, 55, GrowthRate.MEDIUM_SLOW, 100, false), - new PokemonSpecies(SpeciesId.NIDORINO, 1, false, false, false, "Poison Pin Pokémon", PokemonType.POISON, null, 0.9, 19.5, AbilityId.POISON_POINT, AbilityId.RIVALRY, AbilityId.HUSTLE, 365, 61, 72, 57, 55, 55, 65, 120, 50, 128, GrowthRate.MEDIUM_SLOW, 100, false), - new PokemonSpecies(SpeciesId.NIDOKING, 1, false, false, false, "Drill Pokémon", PokemonType.POISON, PokemonType.GROUND, 1.4, 62, AbilityId.POISON_POINT, AbilityId.RIVALRY, AbilityId.SHEER_FORCE, 505, 81, 102, 77, 85, 75, 85, 45, 50, 253, GrowthRate.MEDIUM_SLOW, 100, false), - new PokemonSpecies(SpeciesId.CLEFAIRY, 1, false, false, false, "Fairy Pokémon", PokemonType.FAIRY, null, 0.6, 7.5, AbilityId.CUTE_CHARM, AbilityId.MAGIC_GUARD, AbilityId.FRIEND_GUARD, 323, 70, 45, 48, 60, 65, 35, 150, 140, 113, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.CLEFABLE, 1, false, false, false, "Fairy Pokémon", PokemonType.FAIRY, null, 1.3, 40, AbilityId.CUTE_CHARM, AbilityId.MAGIC_GUARD, AbilityId.UNAWARE, 483, 95, 70, 73, 95, 90, 60, 25, 140, 242, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.VULPIX, 1, false, false, false, "Fox Pokémon", PokemonType.FIRE, null, 0.6, 9.9, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.DROUGHT, 299, 38, 41, 40, 50, 65, 65, 190, 50, 60, GrowthRate.MEDIUM_FAST, 25, false), - new PokemonSpecies(SpeciesId.NINETALES, 1, false, false, false, "Fox Pokémon", PokemonType.FIRE, null, 1.1, 19.9, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.DROUGHT, 505, 73, 76, 75, 81, 100, 100, 75, 50, 177, GrowthRate.MEDIUM_FAST, 25, false), - new PokemonSpecies(SpeciesId.JIGGLYPUFF, 1, false, false, false, "Balloon Pokémon", PokemonType.NORMAL, PokemonType.FAIRY, 0.5, 5.5, AbilityId.CUTE_CHARM, AbilityId.COMPETITIVE, AbilityId.FRIEND_GUARD, 270, 115, 45, 20, 45, 25, 20, 170, 50, 95, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.WIGGLYTUFF, 1, false, false, false, "Balloon Pokémon", PokemonType.NORMAL, PokemonType.FAIRY, 1, 12, AbilityId.CUTE_CHARM, AbilityId.COMPETITIVE, AbilityId.FRISK, 435, 140, 70, 45, 85, 50, 45, 50, 50, 218, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.ZUBAT, 1, false, false, false, "Bat Pokémon", PokemonType.POISON, PokemonType.FLYING, 0.8, 7.5, AbilityId.INNER_FOCUS, AbilityId.NONE, AbilityId.INFILTRATOR, 245, 40, 45, 35, 30, 40, 55, 255, 50, 49, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.GOLBAT, 1, false, false, false, "Bat Pokémon", PokemonType.POISON, PokemonType.FLYING, 1.6, 55, AbilityId.INNER_FOCUS, AbilityId.NONE, AbilityId.INFILTRATOR, 455, 75, 80, 70, 65, 75, 90, 90, 50, 159, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.ODDISH, 1, false, false, false, "Weed Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.5, 5.4, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.RUN_AWAY, 320, 45, 50, 55, 75, 65, 30, 255, 50, 64, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.GLOOM, 1, false, false, false, "Weed Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.8, 8.6, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.STENCH, 395, 60, 65, 70, 85, 75, 40, 120, 50, 138, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.VILEPLUME, 1, false, false, false, "Flower Pokémon", PokemonType.GRASS, PokemonType.POISON, 1.2, 18.6, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.EFFECT_SPORE, 490, 75, 80, 85, 110, 90, 50, 45, 50, 245, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.PARAS, 1, false, false, false, "Mushroom Pokémon", PokemonType.BUG, PokemonType.GRASS, 0.3, 5.4, AbilityId.EFFECT_SPORE, AbilityId.DRY_SKIN, AbilityId.DAMP, 285, 35, 70, 55, 45, 55, 25, 190, 70, 57, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PARASECT, 1, false, false, false, "Mushroom Pokémon", PokemonType.BUG, PokemonType.GRASS, 1, 29.5, AbilityId.EFFECT_SPORE, AbilityId.DRY_SKIN, AbilityId.DAMP, 405, 60, 95, 80, 60, 80, 30, 75, 70, 142, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.VENONAT, 1, false, false, false, "Insect Pokémon", PokemonType.BUG, PokemonType.POISON, 1, 30, AbilityId.COMPOUND_EYES, AbilityId.TINTED_LENS, AbilityId.RUN_AWAY, 305, 60, 55, 50, 40, 55, 45, 190, 70, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.VENOMOTH, 1, false, false, false, "Poison Moth Pokémon", PokemonType.BUG, PokemonType.POISON, 1.5, 12.5, AbilityId.SHIELD_DUST, AbilityId.TINTED_LENS, AbilityId.WONDER_SKIN, 450, 70, 65, 60, 90, 75, 90, 75, 70, 158, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DIGLETT, 1, false, false, false, "Mole Pokémon", PokemonType.GROUND, null, 0.2, 0.8, AbilityId.SAND_VEIL, AbilityId.ARENA_TRAP, AbilityId.SAND_FORCE, 265, 10, 55, 25, 35, 45, 95, 255, 50, 53, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DUGTRIO, 1, false, false, false, "Mole Pokémon", PokemonType.GROUND, null, 0.7, 33.3, AbilityId.SAND_VEIL, AbilityId.ARENA_TRAP, AbilityId.SAND_FORCE, 425, 35, 100, 50, 50, 70, 120, 50, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MEOWTH, 1, false, false, false, "Scratch Cat Pokémon", PokemonType.NORMAL, null, 0.4, 4.2, AbilityId.PICKUP, AbilityId.TECHNICIAN, AbilityId.UNNERVE, 290, 40, 45, 35, 40, 40, 90, 255, 50, 58, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.NORMAL, null, 0.4, 4.2, AbilityId.PICKUP, AbilityId.TECHNICIAN, AbilityId.UNNERVE, 290, 40, 45, 35, 40, 40, 90, 255, 50, 58, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.NORMAL, null, 33, 999.9, AbilityId.TECHNICIAN, AbilityId.TECHNICIAN, AbilityId.TECHNICIAN, 540, 115, 110, 65, 65, 70, 115, 255, 50, 58), //+100 BST from Persian - ), - new PokemonSpecies(SpeciesId.PERSIAN, 1, false, false, false, "Classy Cat Pokémon", PokemonType.NORMAL, null, 1, 32, AbilityId.LIMBER, AbilityId.TECHNICIAN, AbilityId.UNNERVE, 440, 65, 70, 60, 65, 65, 115, 90, 50, 154, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PSYDUCK, 1, false, false, false, "Duck Pokémon", PokemonType.WATER, null, 0.8, 19.6, AbilityId.DAMP, AbilityId.CLOUD_NINE, AbilityId.SWIFT_SWIM, 320, 50, 52, 48, 65, 50, 55, 190, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GOLDUCK, 1, false, false, false, "Duck Pokémon", PokemonType.WATER, null, 1.7, 76.6, AbilityId.DAMP, AbilityId.CLOUD_NINE, AbilityId.SWIFT_SWIM, 500, 80, 82, 78, 95, 80, 85, 75, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MANKEY, 1, false, false, false, "Pig Monkey Pokémon", PokemonType.FIGHTING, null, 0.5, 28, AbilityId.VITAL_SPIRIT, AbilityId.ANGER_POINT, AbilityId.DEFIANT, 305, 40, 80, 35, 35, 45, 70, 190, 70, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PRIMEAPE, 1, false, false, false, "Pig Monkey Pokémon", PokemonType.FIGHTING, null, 1, 32, AbilityId.VITAL_SPIRIT, AbilityId.ANGER_POINT, AbilityId.DEFIANT, 455, 65, 105, 60, 60, 70, 95, 75, 70, 159, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GROWLITHE, 1, false, false, false, "Puppy Pokémon", PokemonType.FIRE, null, 0.7, 19, AbilityId.INTIMIDATE, AbilityId.FLASH_FIRE, AbilityId.JUSTIFIED, 350, 55, 70, 45, 70, 50, 60, 190, 50, 70, GrowthRate.SLOW, 75, false), - new PokemonSpecies(SpeciesId.ARCANINE, 1, false, false, false, "Legendary Pokémon", PokemonType.FIRE, null, 1.9, 155, AbilityId.INTIMIDATE, AbilityId.FLASH_FIRE, AbilityId.JUSTIFIED, 555, 90, 110, 80, 100, 80, 95, 75, 50, 194, GrowthRate.SLOW, 75, false), - new PokemonSpecies(SpeciesId.POLIWAG, 1, false, false, false, "Tadpole Pokémon", PokemonType.WATER, null, 0.6, 12.4, AbilityId.WATER_ABSORB, AbilityId.DAMP, AbilityId.SWIFT_SWIM, 300, 40, 50, 40, 40, 40, 90, 255, 50, 60, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.POLIWHIRL, 1, false, false, false, "Tadpole Pokémon", PokemonType.WATER, null, 1, 20, AbilityId.WATER_ABSORB, AbilityId.DAMP, AbilityId.SWIFT_SWIM, 385, 65, 65, 65, 50, 50, 90, 120, 50, 135, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.POLIWRATH, 1, false, false, false, "Tadpole Pokémon", PokemonType.WATER, PokemonType.FIGHTING, 1.3, 54, AbilityId.WATER_ABSORB, AbilityId.DAMP, AbilityId.SWIFT_SWIM, 510, 90, 95, 95, 70, 90, 70, 45, 50, 255, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.ABRA, 1, false, false, false, "Psi Pokémon", PokemonType.PSYCHIC, null, 0.9, 19.5, AbilityId.SYNCHRONIZE, AbilityId.INNER_FOCUS, AbilityId.MAGIC_GUARD, 310, 25, 20, 15, 105, 55, 90, 200, 50, 62, GrowthRate.MEDIUM_SLOW, 75, false), - new PokemonSpecies(SpeciesId.KADABRA, 1, false, false, false, "Psi Pokémon", PokemonType.PSYCHIC, null, 1.3, 56.5, AbilityId.SYNCHRONIZE, AbilityId.INNER_FOCUS, AbilityId.MAGIC_GUARD, 400, 40, 35, 30, 120, 70, 105, 100, 50, 140, GrowthRate.MEDIUM_SLOW, 75, true), - new PokemonSpecies(SpeciesId.ALAKAZAM, 1, false, false, false, "Psi Pokémon", PokemonType.PSYCHIC, null, 1.5, 48, AbilityId.SYNCHRONIZE, AbilityId.INNER_FOCUS, AbilityId.MAGIC_GUARD, 500, 55, 50, 45, 135, 95, 120, 50, 50, 250, GrowthRate.MEDIUM_SLOW, 75, true, true, - new PokemonForm("Normal", "", PokemonType.PSYCHIC, null, 1.5, 48, AbilityId.SYNCHRONIZE, AbilityId.INNER_FOCUS, AbilityId.MAGIC_GUARD, 500, 55, 50, 45, 135, 95, 120, 50, 50, 250, true, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.PSYCHIC, null, 1.2, 48, AbilityId.TRACE, AbilityId.TRACE, AbilityId.TRACE, 600, 55, 50, 65, 175, 105, 150, 50, 50, 250, true), - ), - new PokemonSpecies(SpeciesId.MACHOP, 1, false, false, false, "Superpower Pokémon", PokemonType.FIGHTING, null, 0.8, 19.5, AbilityId.GUTS, AbilityId.NO_GUARD, AbilityId.STEADFAST, 305, 70, 80, 50, 35, 35, 35, 180, 50, 61, GrowthRate.MEDIUM_SLOW, 75, false), - new PokemonSpecies(SpeciesId.MACHOKE, 1, false, false, false, "Superpower Pokémon", PokemonType.FIGHTING, null, 1.5, 70.5, AbilityId.GUTS, AbilityId.NO_GUARD, AbilityId.STEADFAST, 405, 80, 100, 70, 50, 60, 45, 90, 50, 142, GrowthRate.MEDIUM_SLOW, 75, false), - new PokemonSpecies(SpeciesId.MACHAMP, 1, false, false, false, "Superpower Pokémon", PokemonType.FIGHTING, null, 1.6, 130, AbilityId.GUTS, AbilityId.NO_GUARD, AbilityId.STEADFAST, 505, 90, 130, 80, 65, 85, 55, 45, 50, 253, GrowthRate.MEDIUM_SLOW, 75, false, true, - new PokemonForm("Normal", "", PokemonType.FIGHTING, null, 1.6, 130, AbilityId.GUTS, AbilityId.NO_GUARD, AbilityId.STEADFAST, 505, 90, 130, 80, 65, 85, 55, 45, 50, 253, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIGHTING, null, 25, 999.9, AbilityId.GUTS, AbilityId.GUTS, AbilityId.GUTS, 605, 120, 170, 85, 75, 90, 65, 45, 50, 253), - ), - new PokemonSpecies(SpeciesId.BELLSPROUT, 1, false, false, false, "Flower Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.7, 4, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.GLUTTONY, 300, 50, 75, 35, 70, 30, 40, 255, 70, 60, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.WEEPINBELL, 1, false, false, false, "Flycatcher Pokémon", PokemonType.GRASS, PokemonType.POISON, 1, 6.4, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.GLUTTONY, 390, 65, 90, 50, 85, 45, 55, 120, 70, 137, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.VICTREEBEL, 1, false, false, false, "Flycatcher Pokémon", PokemonType.GRASS, PokemonType.POISON, 1.7, 15.5, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.GLUTTONY, 490, 80, 105, 65, 100, 70, 70, 45, 70, 245, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.TENTACOOL, 1, false, false, false, "Jellyfish Pokémon", PokemonType.WATER, PokemonType.POISON, 0.9, 45.5, AbilityId.CLEAR_BODY, AbilityId.LIQUID_OOZE, AbilityId.RAIN_DISH, 335, 40, 40, 35, 50, 100, 70, 190, 50, 67, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.TENTACRUEL, 1, false, false, false, "Jellyfish Pokémon", PokemonType.WATER, PokemonType.POISON, 1.6, 55, AbilityId.CLEAR_BODY, AbilityId.LIQUID_OOZE, AbilityId.RAIN_DISH, 515, 80, 70, 65, 80, 120, 100, 60, 50, 180, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.GEODUDE, 1, false, false, false, "Rock Pokémon", PokemonType.ROCK, PokemonType.GROUND, 0.4, 20, AbilityId.ROCK_HEAD, AbilityId.STURDY, AbilityId.SAND_VEIL, 300, 40, 80, 100, 30, 30, 20, 255, 70, 60, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.GRAVELER, 1, false, false, false, "Rock Pokémon", PokemonType.ROCK, PokemonType.GROUND, 1, 105, AbilityId.ROCK_HEAD, AbilityId.STURDY, AbilityId.SAND_VEIL, 390, 55, 95, 115, 45, 45, 35, 120, 70, 137, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.GOLEM, 1, false, false, false, "Megaton Pokémon", PokemonType.ROCK, PokemonType.GROUND, 1.4, 300, AbilityId.ROCK_HEAD, AbilityId.STURDY, AbilityId.SAND_VEIL, 495, 80, 120, 130, 55, 65, 45, 45, 70, 248, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.PONYTA, 1, false, false, false, "Fire Horse Pokémon", PokemonType.FIRE, null, 1, 30, AbilityId.RUN_AWAY, AbilityId.FLASH_FIRE, AbilityId.FLAME_BODY, 410, 50, 85, 55, 65, 65, 90, 190, 50, 82, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.RAPIDASH, 1, false, false, false, "Fire Horse Pokémon", PokemonType.FIRE, null, 1.7, 95, AbilityId.RUN_AWAY, AbilityId.FLASH_FIRE, AbilityId.FLAME_BODY, 500, 65, 100, 70, 80, 80, 105, 60, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SLOWPOKE, 1, false, false, false, "Dopey Pokémon", PokemonType.WATER, PokemonType.PSYCHIC, 1.2, 36, AbilityId.OBLIVIOUS, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 315, 90, 65, 65, 40, 40, 15, 190, 50, 63, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SLOWBRO, 1, false, false, false, "Hermit Crab Pokémon", PokemonType.WATER, PokemonType.PSYCHIC, 1.6, 78.5, AbilityId.OBLIVIOUS, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 490, 95, 75, 110, 100, 80, 30, 75, 50, 172, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.PSYCHIC, 1.6, 78.5, AbilityId.OBLIVIOUS, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 490, 95, 75, 110, 100, 80, 30, 75, 50, 172, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.WATER, PokemonType.PSYCHIC, 2, 120, AbilityId.SHELL_ARMOR, AbilityId.SHELL_ARMOR, AbilityId.SHELL_ARMOR, 590, 95, 75, 180, 130, 80, 30, 75, 50, 172), - ), - new PokemonSpecies(SpeciesId.MAGNEMITE, 1, false, false, false, "Magnet Pokémon", PokemonType.ELECTRIC, PokemonType.STEEL, 0.3, 6, AbilityId.MAGNET_PULL, AbilityId.STURDY, AbilityId.ANALYTIC, 325, 25, 35, 70, 95, 55, 45, 190, 50, 65, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.MAGNETON, 1, false, false, false, "Magnet Pokémon", PokemonType.ELECTRIC, PokemonType.STEEL, 1, 60, AbilityId.MAGNET_PULL, AbilityId.STURDY, AbilityId.ANALYTIC, 465, 50, 60, 95, 120, 70, 70, 60, 50, 163, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.FARFETCHD, 1, false, false, false, "Wild Duck Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.8, 15, AbilityId.KEEN_EYE, AbilityId.INNER_FOCUS, AbilityId.DEFIANT, 377, 52, 90, 55, 58, 62, 60, 45, 50, 132, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DODUO, 1, false, false, false, "Twin Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.4, 39.2, AbilityId.RUN_AWAY, AbilityId.EARLY_BIRD, AbilityId.TANGLED_FEET, 310, 35, 85, 45, 35, 35, 75, 190, 70, 62, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.DODRIO, 1, false, false, false, "Triple Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.8, 85.2, AbilityId.RUN_AWAY, AbilityId.EARLY_BIRD, AbilityId.TANGLED_FEET, 470, 60, 110, 70, 60, 60, 110, 45, 70, 165, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.SEEL, 1, false, false, false, "Sea Lion Pokémon", PokemonType.WATER, null, 1.1, 90, AbilityId.THICK_FAT, AbilityId.HYDRATION, AbilityId.ICE_BODY, 325, 65, 45, 55, 45, 70, 45, 190, 70, 65, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DEWGONG, 1, false, false, false, "Sea Lion Pokémon", PokemonType.WATER, PokemonType.ICE, 1.7, 120, AbilityId.THICK_FAT, AbilityId.HYDRATION, AbilityId.ICE_BODY, 475, 90, 70, 80, 70, 95, 70, 75, 70, 166, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GRIMER, 1, false, false, false, "Sludge Pokémon", PokemonType.POISON, null, 0.9, 30, AbilityId.STENCH, AbilityId.STICKY_HOLD, AbilityId.POISON_TOUCH, 325, 80, 80, 50, 40, 50, 25, 190, 70, 65, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MUK, 1, false, false, false, "Sludge Pokémon", PokemonType.POISON, null, 1.2, 30, AbilityId.STENCH, AbilityId.STICKY_HOLD, AbilityId.POISON_TOUCH, 500, 105, 105, 75, 65, 100, 50, 75, 70, 175, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SHELLDER, 1, false, false, false, "Bivalve Pokémon", PokemonType.WATER, null, 0.3, 4, AbilityId.SHELL_ARMOR, AbilityId.SKILL_LINK, AbilityId.OVERCOAT, 305, 30, 65, 100, 45, 25, 40, 190, 50, 61, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.CLOYSTER, 1, false, false, false, "Bivalve Pokémon", PokemonType.WATER, PokemonType.ICE, 1.5, 132.5, AbilityId.SHELL_ARMOR, AbilityId.SKILL_LINK, AbilityId.OVERCOAT, 525, 50, 95, 180, 85, 45, 70, 60, 50, 184, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.GASTLY, 1, false, false, false, "Gas Pokémon", PokemonType.GHOST, PokemonType.POISON, 1.3, 0.1, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 310, 30, 35, 30, 100, 35, 80, 190, 50, 62, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.HAUNTER, 1, false, false, false, "Gas Pokémon", PokemonType.GHOST, PokemonType.POISON, 1.6, 0.1, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 405, 45, 50, 45, 115, 55, 95, 90, 50, 142, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.GENGAR, 1, false, false, false, "Shadow Pokémon", PokemonType.GHOST, PokemonType.POISON, 1.5, 40.5, AbilityId.CURSED_BODY, AbilityId.NONE, AbilityId.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, GrowthRate.MEDIUM_SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.GHOST, PokemonType.POISON, 1.5, 40.5, AbilityId.CURSED_BODY, AbilityId.NONE, AbilityId.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.GHOST, PokemonType.POISON, 1.4, 40.5, AbilityId.SHADOW_TAG, AbilityId.NONE, AbilityId.NONE, 600, 60, 65, 80, 170, 95, 130, 45, 50, 250), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GHOST, PokemonType.POISON, 20, 999.9, AbilityId.CURSED_BODY, AbilityId.NONE, AbilityId.NONE, 600, 140, 65, 70, 140, 85, 100, 45, 50, 250), - ), - new PokemonSpecies(SpeciesId.ONIX, 1, false, false, false, "Rock Snake Pokémon", PokemonType.ROCK, PokemonType.GROUND, 8.8, 210, AbilityId.ROCK_HEAD, AbilityId.STURDY, AbilityId.WEAK_ARMOR, 385, 35, 45, 160, 30, 45, 70, 45, 50, 77, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DROWZEE, 1, false, false, false, "Hypnosis Pokémon", PokemonType.PSYCHIC, null, 1, 32.4, AbilityId.INSOMNIA, AbilityId.FOREWARN, AbilityId.INNER_FOCUS, 328, 60, 48, 45, 43, 90, 42, 190, 70, 66, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.HYPNO, 1, false, false, false, "Hypnosis Pokémon", PokemonType.PSYCHIC, null, 1.6, 75.6, AbilityId.INSOMNIA, AbilityId.FOREWARN, AbilityId.INNER_FOCUS, 483, 85, 73, 70, 73, 115, 67, 75, 70, 169, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.KRABBY, 1, false, false, false, "River Crab Pokémon", PokemonType.WATER, null, 0.4, 6.5, AbilityId.HYPER_CUTTER, AbilityId.SHELL_ARMOR, AbilityId.SHEER_FORCE, 325, 30, 105, 90, 25, 25, 50, 225, 50, 65, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.KINGLER, 1, false, false, false, "Pincer Pokémon", PokemonType.WATER, null, 1.3, 60, AbilityId.HYPER_CUTTER, AbilityId.SHELL_ARMOR, AbilityId.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.WATER, null, 1.3, 60, AbilityId.HYPER_CUTTER, AbilityId.SHELL_ARMOR, AbilityId.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, null, 19, 999.9, AbilityId.TOUGH_CLAWS, AbilityId.TOUGH_CLAWS, AbilityId.TOUGH_CLAWS, 575, 92, 145, 140, 60, 65, 73, 60, 50, 166), - ), - new PokemonSpecies(SpeciesId.VOLTORB, 1, false, false, false, "Ball Pokémon", PokemonType.ELECTRIC, null, 0.5, 10.4, AbilityId.SOUNDPROOF, AbilityId.STATIC, AbilityId.AFTERMATH, 330, 40, 30, 50, 55, 55, 100, 190, 70, 66, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.ELECTRODE, 1, false, false, false, "Ball Pokémon", PokemonType.ELECTRIC, null, 1.2, 66.6, AbilityId.SOUNDPROOF, AbilityId.STATIC, AbilityId.AFTERMATH, 490, 60, 50, 70, 80, 80, 150, 60, 70, 172, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.EXEGGCUTE, 1, false, false, false, "Egg Pokémon", PokemonType.GRASS, PokemonType.PSYCHIC, 0.4, 2.5, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.HARVEST, 325, 60, 40, 80, 60, 45, 40, 90, 50, 65, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.EXEGGUTOR, 1, false, false, false, "Coconut Pokémon", PokemonType.GRASS, PokemonType.PSYCHIC, 2, 120, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.HARVEST, 530, 95, 95, 85, 125, 75, 55, 45, 50, 186, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.CUBONE, 1, false, false, false, "Lonely Pokémon", PokemonType.GROUND, null, 0.4, 6.5, AbilityId.ROCK_HEAD, AbilityId.LIGHTNING_ROD, AbilityId.BATTLE_ARMOR, 320, 50, 50, 95, 40, 50, 35, 190, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MAROWAK, 1, false, false, false, "Bone Keeper Pokémon", PokemonType.GROUND, null, 1, 45, AbilityId.ROCK_HEAD, AbilityId.LIGHTNING_ROD, AbilityId.BATTLE_ARMOR, 425, 60, 80, 110, 50, 80, 45, 75, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.HITMONLEE, 1, false, false, false, "Kicking Pokémon", PokemonType.FIGHTING, null, 1.5, 49.8, AbilityId.LIMBER, AbilityId.RECKLESS, AbilityId.UNBURDEN, 455, 50, 120, 53, 35, 110, 87, 45, 50, 159, GrowthRate.MEDIUM_FAST, 100, false), - new PokemonSpecies(SpeciesId.HITMONCHAN, 1, false, false, false, "Punching Pokémon", PokemonType.FIGHTING, null, 1.4, 50.2, AbilityId.KEEN_EYE, AbilityId.IRON_FIST, AbilityId.INNER_FOCUS, 455, 50, 105, 79, 35, 110, 76, 45, 50, 159, GrowthRate.MEDIUM_FAST, 100, false), - new PokemonSpecies(SpeciesId.LICKITUNG, 1, false, false, false, "Licking Pokémon", PokemonType.NORMAL, null, 1.2, 65.5, AbilityId.OWN_TEMPO, AbilityId.OBLIVIOUS, AbilityId.CLOUD_NINE, 385, 90, 55, 75, 60, 75, 30, 45, 50, 77, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.KOFFING, 1, false, false, false, "Poison Gas Pokémon", PokemonType.POISON, null, 0.6, 1, AbilityId.LEVITATE, AbilityId.NEUTRALIZING_GAS, AbilityId.STENCH, 340, 40, 65, 95, 60, 45, 35, 190, 50, 68, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.WEEZING, 1, false, false, false, "Poison Gas Pokémon", PokemonType.POISON, null, 1.2, 9.5, AbilityId.LEVITATE, AbilityId.NEUTRALIZING_GAS, AbilityId.STENCH, 490, 65, 90, 120, 85, 70, 60, 60, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.RHYHORN, 1, false, false, false, "Spikes Pokémon", PokemonType.GROUND, PokemonType.ROCK, 1, 115, AbilityId.LIGHTNING_ROD, AbilityId.ROCK_HEAD, AbilityId.RECKLESS, 345, 80, 85, 95, 30, 30, 25, 120, 50, 69, GrowthRate.SLOW, 50, true), - new PokemonSpecies(SpeciesId.RHYDON, 1, false, false, false, "Drill Pokémon", PokemonType.GROUND, PokemonType.ROCK, 1.9, 120, AbilityId.LIGHTNING_ROD, AbilityId.ROCK_HEAD, AbilityId.RECKLESS, 485, 105, 130, 120, 45, 45, 40, 60, 50, 170, GrowthRate.SLOW, 50, true), - new PokemonSpecies(SpeciesId.CHANSEY, 1, false, false, false, "Egg Pokémon", PokemonType.NORMAL, null, 1.1, 34.6, AbilityId.NATURAL_CURE, AbilityId.SERENE_GRACE, AbilityId.HEALER, 450, 250, 5, 5, 35, 105, 50, 30, 140, 395, GrowthRate.FAST, 0, false), - new PokemonSpecies(SpeciesId.TANGELA, 1, false, false, false, "Vine Pokémon", PokemonType.GRASS, null, 1, 35, AbilityId.CHLOROPHYLL, AbilityId.LEAF_GUARD, AbilityId.REGENERATOR, 435, 65, 55, 115, 100, 40, 60, 45, 50, 87, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.KANGASKHAN, 1, false, false, false, "Parent Pokémon", PokemonType.NORMAL, null, 2.2, 80, AbilityId.EARLY_BIRD, AbilityId.SCRAPPY, AbilityId.INNER_FOCUS, 490, 105, 95, 80, 40, 80, 90, 45, 50, 172, GrowthRate.MEDIUM_FAST, 0, false, true, - new PokemonForm("Normal", "", PokemonType.NORMAL, null, 2.2, 80, AbilityId.EARLY_BIRD, AbilityId.SCRAPPY, AbilityId.INNER_FOCUS, 490, 105, 95, 80, 40, 80, 90, 45, 50, 172, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.NORMAL, null, 2.2, 100, AbilityId.PARENTAL_BOND, AbilityId.PARENTAL_BOND, AbilityId.PARENTAL_BOND, 590, 105, 125, 100, 60, 100, 100, 45, 50, 172), - ), - new PokemonSpecies(SpeciesId.HORSEA, 1, false, false, false, "Dragon Pokémon", PokemonType.WATER, null, 0.4, 8, AbilityId.SWIFT_SWIM, AbilityId.SNIPER, AbilityId.DAMP, 295, 30, 40, 70, 70, 25, 60, 225, 50, 59, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SEADRA, 1, false, false, false, "Dragon Pokémon", PokemonType.WATER, null, 1.2, 25, AbilityId.POISON_POINT, AbilityId.SNIPER, AbilityId.DAMP, 440, 55, 65, 95, 95, 45, 85, 75, 50, 154, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GOLDEEN, 1, false, false, false, "Goldfish Pokémon", PokemonType.WATER, null, 0.6, 15, AbilityId.SWIFT_SWIM, AbilityId.WATER_VEIL, AbilityId.LIGHTNING_ROD, 320, 45, 67, 60, 35, 50, 63, 225, 50, 64, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.SEAKING, 1, false, false, false, "Goldfish Pokémon", PokemonType.WATER, null, 1.3, 39, AbilityId.SWIFT_SWIM, AbilityId.WATER_VEIL, AbilityId.LIGHTNING_ROD, 450, 80, 92, 65, 65, 80, 68, 60, 50, 158, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.STARYU, 1, false, false, false, "Star Shape Pokémon", PokemonType.WATER, null, 0.8, 34.5, AbilityId.ILLUMINATE, AbilityId.NATURAL_CURE, AbilityId.ANALYTIC, 340, 30, 45, 55, 70, 55, 85, 225, 50, 68, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.STARMIE, 1, false, false, false, "Mysterious Pokémon", PokemonType.WATER, PokemonType.PSYCHIC, 1.1, 80, AbilityId.ILLUMINATE, AbilityId.NATURAL_CURE, AbilityId.ANALYTIC, 520, 60, 75, 85, 100, 85, 115, 60, 50, 182, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.MR_MIME, 1, false, false, false, "Barrier Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 1.3, 54.5, AbilityId.SOUNDPROOF, AbilityId.FILTER, AbilityId.TECHNICIAN, 460, 40, 45, 65, 100, 120, 90, 45, 50, 161, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SCYTHER, 1, false, false, false, "Mantis Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.5, 56, AbilityId.SWARM, AbilityId.TECHNICIAN, AbilityId.STEADFAST, 500, 70, 110, 80, 55, 80, 105, 45, 50, 100, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.JYNX, 1, false, false, false, "Human Shape Pokémon", PokemonType.ICE, PokemonType.PSYCHIC, 1.4, 40.6, AbilityId.OBLIVIOUS, AbilityId.FOREWARN, AbilityId.DRY_SKIN, 455, 65, 50, 35, 115, 95, 95, 45, 50, 159, GrowthRate.MEDIUM_FAST, 0, false), - new PokemonSpecies(SpeciesId.ELECTABUZZ, 1, false, false, false, "Electric Pokémon", PokemonType.ELECTRIC, null, 1.1, 30, AbilityId.STATIC, AbilityId.NONE, AbilityId.VITAL_SPIRIT, 490, 65, 83, 57, 95, 85, 105, 45, 50, 172, GrowthRate.MEDIUM_FAST, 75, false), - new PokemonSpecies(SpeciesId.MAGMAR, 1, false, false, false, "Spitfire Pokémon", PokemonType.FIRE, null, 1.3, 44.5, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.VITAL_SPIRIT, 495, 65, 95, 57, 100, 85, 93, 45, 50, 173, GrowthRate.MEDIUM_FAST, 75, false), - new PokemonSpecies(SpeciesId.PINSIR, 1, false, false, false, "Stag Beetle Pokémon", PokemonType.BUG, null, 1.5, 55, AbilityId.HYPER_CUTTER, AbilityId.MOLD_BREAKER, AbilityId.MOXIE, 500, 65, 125, 100, 55, 70, 85, 45, 50, 175, GrowthRate.SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.BUG, null, 1.5, 55, AbilityId.HYPER_CUTTER, AbilityId.MOLD_BREAKER, AbilityId.MOXIE, 500, 65, 125, 100, 55, 70, 85, 45, 50, 175, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.BUG, PokemonType.FLYING, 1.7, 59, AbilityId.AERILATE, AbilityId.AERILATE, AbilityId.AERILATE, 600, 65, 155, 120, 65, 90, 105, 45, 50, 175), - ), - new PokemonSpecies(SpeciesId.TAUROS, 1, false, false, false, "Wild Bull Pokémon", PokemonType.NORMAL, null, 1.4, 88.4, AbilityId.INTIMIDATE, AbilityId.ANGER_POINT, AbilityId.SHEER_FORCE, 490, 75, 100, 95, 40, 70, 110, 45, 50, 172, GrowthRate.SLOW, 100, false), - new PokemonSpecies(SpeciesId.MAGIKARP, 1, false, false, false, "Fish Pokémon", PokemonType.WATER, null, 0.9, 10, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.RATTLED, 200, 20, 10, 55, 15, 20, 80, 255, 50, 40, GrowthRate.SLOW, 50, true), - new PokemonSpecies(SpeciesId.GYARADOS, 1, false, false, false, "Atrocious Pokémon", PokemonType.WATER, PokemonType.FLYING, 6.5, 235, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.MOXIE, 540, 95, 125, 79, 60, 100, 81, 45, 50, 189, GrowthRate.SLOW, 50, true, true, - new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.FLYING, 6.5, 235, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.MOXIE, 540, 95, 125, 79, 60, 100, 81, 45, 50, 189, true, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.WATER, PokemonType.DARK, 6.5, 305, AbilityId.MOLD_BREAKER, AbilityId.MOLD_BREAKER, AbilityId.MOLD_BREAKER, 640, 95, 155, 109, 70, 130, 81, 45, 50, 189, true), - ), - new PokemonSpecies(SpeciesId.LAPRAS, 1, false, false, false, "Transport Pokémon", PokemonType.WATER, PokemonType.ICE, 2.5, 220, AbilityId.WATER_ABSORB, AbilityId.SHELL_ARMOR, AbilityId.HYDRATION, 535, 130, 85, 80, 85, 95, 60, 45, 50, 187, GrowthRate.SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.ICE, 2.5, 220, AbilityId.WATER_ABSORB, AbilityId.SHELL_ARMOR, AbilityId.HYDRATION, 535, 130, 85, 80, 85, 95, 60, 45, 50, 187, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, PokemonType.ICE, 24, 999.9, AbilityId.SHIELD_DUST, AbilityId.SHIELD_DUST, AbilityId.SHIELD_DUST, 635, 170, 97, 85, 107, 111, 65, 45, 50, 187), - ), - new PokemonSpecies(SpeciesId.DITTO, 1, false, false, false, "Transform Pokémon", PokemonType.NORMAL, null, 0.3, 4, AbilityId.LIMBER, AbilityId.NONE, AbilityId.IMPOSTER, 288, 48, 48, 48, 48, 48, 48, 35, 50, 101, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.EEVEE, 1, false, false, false, "Evolution Pokémon", PokemonType.NORMAL, null, 0.3, 6.5, AbilityId.RUN_AWAY, AbilityId.ADAPTABILITY, AbilityId.ANTICIPATION, 325, 55, 55, 50, 45, 65, 55, 45, 50, 65, GrowthRate.MEDIUM_FAST, 87.5, false, true, - new PokemonForm("Normal", "", PokemonType.NORMAL, null, 0.3, 6.5, AbilityId.RUN_AWAY, AbilityId.ADAPTABILITY, AbilityId.ANTICIPATION, 325, 55, 55, 50, 45, 65, 55, 45, 50, 65, false, null, true), - new PokemonForm("Partner", "partner", PokemonType.NORMAL, null, 0.3, 6.5, AbilityId.RUN_AWAY, AbilityId.ADAPTABILITY, AbilityId.ANTICIPATION, 435, 65, 75, 70, 65, 85, 75, 45, 50, 65, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.NORMAL, null, 18, 999.9, AbilityId.PROTEAN, AbilityId.PROTEAN, AbilityId.PROTEAN, 535, 110, 95, 70, 90, 85, 85, 45, 50, 65), //+100 BST from Partner Form - ), - new PokemonSpecies(SpeciesId.VAPOREON, 1, false, false, false, "Bubble Jet Pokémon", PokemonType.WATER, null, 1, 29, AbilityId.WATER_ABSORB, AbilityId.NONE, AbilityId.HYDRATION, 525, 130, 65, 60, 110, 95, 65, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.JOLTEON, 1, false, false, false, "Lightning Pokémon", PokemonType.ELECTRIC, null, 0.8, 24.5, AbilityId.VOLT_ABSORB, AbilityId.NONE, AbilityId.QUICK_FEET, 525, 65, 65, 60, 110, 95, 130, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.FLAREON, 1, false, false, false, "Flame Pokémon", PokemonType.FIRE, null, 0.9, 25, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.GUTS, 525, 65, 130, 60, 95, 110, 65, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.PORYGON, 1, false, false, false, "Virtual Pokémon", PokemonType.NORMAL, null, 0.8, 36.5, AbilityId.TRACE, AbilityId.DOWNLOAD, AbilityId.ANALYTIC, 395, 65, 60, 70, 85, 75, 40, 45, 50, 79, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.OMANYTE, 1, false, false, false, "Spiral Pokémon", PokemonType.ROCK, PokemonType.WATER, 0.4, 7.5, AbilityId.SWIFT_SWIM, AbilityId.SHELL_ARMOR, AbilityId.WEAK_ARMOR, 355, 35, 40, 100, 90, 55, 35, 45, 50, 71, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.OMASTAR, 1, false, false, false, "Spiral Pokémon", PokemonType.ROCK, PokemonType.WATER, 1, 35, AbilityId.SWIFT_SWIM, AbilityId.SHELL_ARMOR, AbilityId.WEAK_ARMOR, 495, 70, 60, 125, 115, 70, 55, 45, 50, 173, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.KABUTO, 1, false, false, false, "Shellfish Pokémon", PokemonType.ROCK, PokemonType.WATER, 0.5, 11.5, AbilityId.SWIFT_SWIM, AbilityId.BATTLE_ARMOR, AbilityId.WEAK_ARMOR, 355, 30, 80, 90, 55, 45, 55, 45, 50, 71, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.KABUTOPS, 1, false, false, false, "Shellfish Pokémon", PokemonType.ROCK, PokemonType.WATER, 1.3, 40.5, AbilityId.SWIFT_SWIM, AbilityId.BATTLE_ARMOR, AbilityId.WEAK_ARMOR, 495, 60, 115, 105, 65, 70, 80, 45, 50, 173, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.AERODACTYL, 1, false, false, false, "Fossil Pokémon", PokemonType.ROCK, PokemonType.FLYING, 1.8, 59, AbilityId.ROCK_HEAD, AbilityId.PRESSURE, AbilityId.UNNERVE, 515, 80, 105, 65, 60, 75, 130, 45, 50, 180, GrowthRate.SLOW, 87.5, false, true, - new PokemonForm("Normal", "", PokemonType.ROCK, PokemonType.FLYING, 1.8, 59, AbilityId.ROCK_HEAD, AbilityId.PRESSURE, AbilityId.UNNERVE, 515, 80, 105, 65, 60, 75, 130, 45, 50, 180, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.ROCK, PokemonType.FLYING, 2.1, 79, AbilityId.TOUGH_CLAWS, AbilityId.TOUGH_CLAWS, AbilityId.TOUGH_CLAWS, 615, 80, 135, 85, 70, 95, 150, 45, 50, 180), - ), - new PokemonSpecies(SpeciesId.SNORLAX, 1, false, false, false, "Sleeping Pokémon", PokemonType.NORMAL, null, 2.1, 460, AbilityId.IMMUNITY, AbilityId.THICK_FAT, AbilityId.GLUTTONY, 540, 160, 110, 65, 65, 110, 30, 25, 50, 189, GrowthRate.SLOW, 87.5, false, true, - new PokemonForm("Normal", "", PokemonType.NORMAL, null, 2.1, 460, AbilityId.IMMUNITY, AbilityId.THICK_FAT, AbilityId.GLUTTONY, 540, 160, 110, 65, 65, 110, 30, 25, 50, 189, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.NORMAL, null, 35, 999.9, AbilityId.HARVEST, AbilityId.HARVEST, AbilityId.HARVEST, 640, 210, 135, 70, 90, 115, 20, 25, 50, 189), - ), - new PokemonSpecies(SpeciesId.ARTICUNO, 1, true, false, false, "Freeze Pokémon", PokemonType.ICE, PokemonType.FLYING, 1.7, 55.4, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.SNOW_CLOAK, 580, 90, 85, 100, 95, 125, 85, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.ZAPDOS, 1, true, false, false, "Electric Pokémon", PokemonType.ELECTRIC, PokemonType.FLYING, 1.6, 52.6, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.STATIC, 580, 90, 90, 85, 125, 90, 100, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.MOLTRES, 1, true, false, false, "Flame Pokémon", PokemonType.FIRE, PokemonType.FLYING, 2, 60, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.FLAME_BODY, 580, 90, 100, 90, 125, 85, 90, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.DRATINI, 1, false, false, false, "Dragon Pokémon", PokemonType.DRAGON, null, 1.8, 3.3, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.MARVEL_SCALE, 300, 41, 64, 45, 50, 50, 50, 45, 35, 60, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.DRAGONAIR, 1, false, false, false, "Dragon Pokémon", PokemonType.DRAGON, null, 4, 16.5, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.MARVEL_SCALE, 420, 61, 84, 65, 70, 70, 70, 45, 35, 147, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.DRAGONITE, 1, false, false, false, "Dragon Pokémon", PokemonType.DRAGON, PokemonType.FLYING, 2.2, 210, AbilityId.INNER_FOCUS, AbilityId.NONE, AbilityId.MULTISCALE, 600, 91, 134, 95, 100, 100, 80, 45, 35, 300, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.MEWTWO, 1, false, true, false, "Genetic Pokémon", PokemonType.PSYCHIC, null, 2, 122, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.UNNERVE, 680, 106, 110, 90, 154, 90, 130, 3, 0, 340, GrowthRate.SLOW, null, false, true, - new PokemonForm("Normal", "", PokemonType.PSYCHIC, null, 2, 122, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.UNNERVE, 680, 106, 110, 90, 154, 90, 130, 3, 0, 340, false, null, true), - new PokemonForm("Mega X", SpeciesFormKey.MEGA_X, PokemonType.PSYCHIC, PokemonType.FIGHTING, 2.3, 127, AbilityId.STEADFAST, AbilityId.NONE, AbilityId.STEADFAST, 780, 106, 190, 100, 154, 100, 130, 3, 0, 340), - new PokemonForm("Mega Y", SpeciesFormKey.MEGA_Y, PokemonType.PSYCHIC, null, 1.5, 33, AbilityId.INSOMNIA, AbilityId.NONE, AbilityId.INSOMNIA, 780, 106, 150, 70, 194, 120, 140, 3, 0, 340), - ), - new PokemonSpecies(SpeciesId.MEW, 1, false, false, true, "New Species Pokémon", PokemonType.PSYCHIC, null, 0.4, 4, AbilityId.SYNCHRONIZE, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 45, 100, 300, GrowthRate.MEDIUM_SLOW, null, false), - new PokemonSpecies(SpeciesId.CHIKORITA, 2, false, false, false, "Leaf Pokémon", PokemonType.GRASS, null, 0.9, 6.4, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.LEAF_GUARD, 318, 45, 49, 65, 49, 65, 45, 45, 70, 64, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.BAYLEEF, 2, false, false, false, "Leaf Pokémon", PokemonType.GRASS, null, 1.2, 15.8, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.LEAF_GUARD, 405, 60, 62, 80, 63, 80, 60, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.MEGANIUM, 2, false, false, false, "Herb Pokémon", PokemonType.GRASS, null, 1.8, 100.5, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.LEAF_GUARD, 525, 80, 82, 100, 83, 100, 80, 45, 70, 263, GrowthRate.MEDIUM_SLOW, 87.5, true), - new PokemonSpecies(SpeciesId.CYNDAQUIL, 2, false, false, false, "Fire Mouse Pokémon", PokemonType.FIRE, null, 0.5, 7.9, AbilityId.BLAZE, AbilityId.NONE, AbilityId.FLASH_FIRE, 309, 39, 52, 43, 60, 50, 65, 45, 70, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.QUILAVA, 2, false, false, false, "Volcano Pokémon", PokemonType.FIRE, null, 0.9, 19, AbilityId.BLAZE, AbilityId.NONE, AbilityId.FLASH_FIRE, 405, 58, 64, 58, 80, 65, 80, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.TYPHLOSION, 2, false, false, false, "Volcano Pokémon", PokemonType.FIRE, null, 1.7, 79.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.FLASH_FIRE, 534, 78, 84, 78, 109, 85, 100, 45, 70, 267, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.TOTODILE, 2, false, false, false, "Big Jaw Pokémon", PokemonType.WATER, null, 0.6, 9.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHEER_FORCE, 314, 50, 65, 64, 44, 48, 43, 45, 70, 63, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.CROCONAW, 2, false, false, false, "Big Jaw Pokémon", PokemonType.WATER, null, 1.1, 25, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHEER_FORCE, 405, 65, 80, 80, 59, 63, 58, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.FERALIGATR, 2, false, false, false, "Big Jaw Pokémon", PokemonType.WATER, null, 2.3, 88.8, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHEER_FORCE, 530, 85, 105, 100, 79, 83, 78, 45, 70, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.SENTRET, 2, false, false, false, "Scout Pokémon", PokemonType.NORMAL, null, 0.8, 6, AbilityId.RUN_AWAY, AbilityId.KEEN_EYE, AbilityId.FRISK, 215, 35, 46, 34, 35, 45, 20, 255, 70, 43, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.FURRET, 2, false, false, false, "Long Body Pokémon", PokemonType.NORMAL, null, 1.8, 32.5, AbilityId.RUN_AWAY, AbilityId.KEEN_EYE, AbilityId.FRISK, 415, 85, 76, 64, 45, 55, 90, 90, 70, 145, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.HOOTHOOT, 2, false, false, false, "Owl Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.7, 21.2, AbilityId.INSOMNIA, AbilityId.KEEN_EYE, AbilityId.TINTED_LENS, 262, 60, 30, 30, 36, 56, 50, 255, 50, 52, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.NOCTOWL, 2, false, false, false, "Owl Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.6, 40.8, AbilityId.INSOMNIA, AbilityId.KEEN_EYE, AbilityId.TINTED_LENS, 452, 100, 50, 50, 86, 96, 70, 90, 50, 158, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.LEDYBA, 2, false, false, false, "Five Star Pokémon", PokemonType.BUG, PokemonType.FLYING, 1, 10.8, AbilityId.SWARM, AbilityId.EARLY_BIRD, AbilityId.RATTLED, 265, 40, 20, 30, 40, 80, 55, 255, 70, 53, GrowthRate.FAST, 50, true), - new PokemonSpecies(SpeciesId.LEDIAN, 2, false, false, false, "Five Star Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.4, 35.6, AbilityId.SWARM, AbilityId.EARLY_BIRD, AbilityId.IRON_FIST, 390, 55, 35, 50, 55, 110, 85, 90, 70, 137, GrowthRate.FAST, 50, true), - new PokemonSpecies(SpeciesId.SPINARAK, 2, false, false, false, "String Spit Pokémon", PokemonType.BUG, PokemonType.POISON, 0.5, 8.5, AbilityId.SWARM, AbilityId.INSOMNIA, AbilityId.SNIPER, 250, 40, 60, 40, 40, 40, 30, 255, 70, 50, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.ARIADOS, 2, false, false, false, "Long Leg Pokémon", PokemonType.BUG, PokemonType.POISON, 1.1, 33.5, AbilityId.SWARM, AbilityId.INSOMNIA, AbilityId.SNIPER, 400, 70, 90, 70, 60, 70, 40, 90, 70, 140, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.CROBAT, 2, false, false, false, "Bat Pokémon", PokemonType.POISON, PokemonType.FLYING, 1.8, 75, AbilityId.INNER_FOCUS, AbilityId.NONE, AbilityId.INFILTRATOR, 535, 85, 90, 80, 70, 80, 130, 90, 50, 268, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CHINCHOU, 2, false, false, false, "Angler Pokémon", PokemonType.WATER, PokemonType.ELECTRIC, 0.5, 12, AbilityId.VOLT_ABSORB, AbilityId.ILLUMINATE, AbilityId.WATER_ABSORB, 330, 75, 38, 38, 56, 56, 67, 190, 50, 66, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.LANTURN, 2, false, false, false, "Light Pokémon", PokemonType.WATER, PokemonType.ELECTRIC, 1.2, 22.5, AbilityId.VOLT_ABSORB, AbilityId.ILLUMINATE, AbilityId.WATER_ABSORB, 460, 125, 58, 58, 76, 76, 67, 75, 50, 161, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.PICHU, 2, false, false, false, "Tiny Mouse Pokémon", PokemonType.ELECTRIC, null, 0.3, 2, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 205, 20, 40, 15, 35, 35, 60, 190, 70, 41, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Normal", "", PokemonType.ELECTRIC, null, 1.4, 2, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 205, 20, 40, 15, 35, 35, 60, 190, 70, 41, false, null, true), - new PokemonForm("Spiky-Eared", "spiky", PokemonType.ELECTRIC, null, 1.4, 2, AbilityId.STATIC, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 205, 20, 40, 15, 35, 35, 60, 190, 70, 41, false, null, true), - ), - new PokemonSpecies(SpeciesId.CLEFFA, 2, false, false, false, "Star Shape Pokémon", PokemonType.FAIRY, null, 0.3, 3, AbilityId.CUTE_CHARM, AbilityId.MAGIC_GUARD, AbilityId.FRIEND_GUARD, 218, 50, 25, 28, 45, 55, 15, 150, 140, 44, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.IGGLYBUFF, 2, false, false, false, "Balloon Pokémon", PokemonType.NORMAL, PokemonType.FAIRY, 0.3, 1, AbilityId.CUTE_CHARM, AbilityId.COMPETITIVE, AbilityId.FRIEND_GUARD, 210, 90, 30, 15, 40, 20, 15, 170, 50, 42, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.TOGEPI, 2, false, false, false, "Spike Ball Pokémon", PokemonType.FAIRY, null, 0.3, 1.5, AbilityId.HUSTLE, AbilityId.SERENE_GRACE, AbilityId.SUPER_LUCK, 245, 35, 20, 65, 40, 65, 20, 190, 50, 49, GrowthRate.FAST, 87.5, false), - new PokemonSpecies(SpeciesId.TOGETIC, 2, false, false, false, "Happiness Pokémon", PokemonType.FAIRY, PokemonType.FLYING, 0.6, 3.2, AbilityId.HUSTLE, AbilityId.SERENE_GRACE, AbilityId.SUPER_LUCK, 405, 55, 40, 85, 80, 105, 40, 75, 50, 142, GrowthRate.FAST, 87.5, false), - new PokemonSpecies(SpeciesId.NATU, 2, false, false, false, "Tiny Bird Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 0.2, 2, AbilityId.SYNCHRONIZE, AbilityId.EARLY_BIRD, AbilityId.MAGIC_BOUNCE, 320, 40, 50, 45, 70, 45, 70, 190, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.XATU, 2, false, false, false, "Mystic Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 1.5, 15, AbilityId.SYNCHRONIZE, AbilityId.EARLY_BIRD, AbilityId.MAGIC_BOUNCE, 470, 65, 75, 70, 95, 70, 95, 75, 50, 165, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.MAREEP, 2, false, false, false, "Wool Pokémon", PokemonType.ELECTRIC, null, 0.6, 7.8, AbilityId.STATIC, AbilityId.NONE, AbilityId.PLUS, 280, 55, 40, 40, 65, 45, 35, 235, 70, 56, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.FLAAFFY, 2, false, false, false, "Wool Pokémon", PokemonType.ELECTRIC, null, 0.8, 13.3, AbilityId.STATIC, AbilityId.NONE, AbilityId.PLUS, 365, 70, 55, 55, 80, 60, 45, 120, 70, 128, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.AMPHAROS, 2, false, false, false, "Light Pokémon", PokemonType.ELECTRIC, null, 1.4, 61.5, AbilityId.STATIC, AbilityId.NONE, AbilityId.PLUS, 510, 90, 75, 85, 115, 90, 55, 45, 70, 255, GrowthRate.MEDIUM_SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.ELECTRIC, null, 1.4, 61.5, AbilityId.STATIC, AbilityId.NONE, AbilityId.PLUS, 510, 90, 75, 85, 115, 90, 55, 45, 70, 255, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.ELECTRIC, PokemonType.DRAGON, 1.4, 61.5, AbilityId.MOLD_BREAKER, AbilityId.NONE, AbilityId.MOLD_BREAKER, 610, 90, 95, 105, 165, 110, 45, 45, 70, 255), - ), - new PokemonSpecies(SpeciesId.BELLOSSOM, 2, false, false, false, "Flower Pokémon", PokemonType.GRASS, null, 0.4, 5.8, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.HEALER, 490, 75, 80, 95, 90, 100, 50, 45, 50, 245, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.MARILL, 2, false, false, false, "Aqua Mouse Pokémon", PokemonType.WATER, PokemonType.FAIRY, 0.4, 8.5, AbilityId.THICK_FAT, AbilityId.HUGE_POWER, AbilityId.SAP_SIPPER, 250, 70, 20, 50, 20, 50, 40, 190, 50, 88, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.AZUMARILL, 2, false, false, false, "Aqua Rabbit Pokémon", PokemonType.WATER, PokemonType.FAIRY, 0.8, 28.5, AbilityId.THICK_FAT, AbilityId.HUGE_POWER, AbilityId.SAP_SIPPER, 420, 100, 50, 80, 60, 80, 50, 75, 50, 210, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.SUDOWOODO, 2, false, false, false, "Imitation Pokémon", PokemonType.ROCK, null, 1.2, 38, AbilityId.STURDY, AbilityId.ROCK_HEAD, AbilityId.RATTLED, 410, 70, 100, 115, 30, 65, 30, 65, 50, 144, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.POLITOED, 2, false, false, false, "Frog Pokémon", PokemonType.WATER, null, 1.1, 33.9, AbilityId.WATER_ABSORB, AbilityId.DAMP, AbilityId.DRIZZLE, 500, 90, 75, 75, 90, 100, 70, 45, 50, 250, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.HOPPIP, 2, false, false, false, "Cottonweed Pokémon", PokemonType.GRASS, PokemonType.FLYING, 0.4, 0.5, AbilityId.CHLOROPHYLL, AbilityId.LEAF_GUARD, AbilityId.INFILTRATOR, 250, 35, 35, 40, 35, 55, 50, 255, 70, 50, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SKIPLOOM, 2, false, false, false, "Cottonweed Pokémon", PokemonType.GRASS, PokemonType.FLYING, 0.6, 1, AbilityId.CHLOROPHYLL, AbilityId.LEAF_GUARD, AbilityId.INFILTRATOR, 340, 55, 45, 50, 45, 65, 80, 120, 70, 119, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.JUMPLUFF, 2, false, false, false, "Cottonweed Pokémon", PokemonType.GRASS, PokemonType.FLYING, 0.8, 3, AbilityId.CHLOROPHYLL, AbilityId.LEAF_GUARD, AbilityId.INFILTRATOR, 460, 75, 55, 70, 55, 95, 110, 45, 70, 230, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.AIPOM, 2, false, false, false, "Long Tail Pokémon", PokemonType.NORMAL, null, 0.8, 11.5, AbilityId.RUN_AWAY, AbilityId.PICKUP, AbilityId.SKILL_LINK, 360, 55, 70, 55, 40, 55, 85, 45, 70, 72, GrowthRate.FAST, 50, true), - new PokemonSpecies(SpeciesId.SUNKERN, 2, false, false, false, "Seed Pokémon", PokemonType.GRASS, null, 0.3, 1.8, AbilityId.CHLOROPHYLL, AbilityId.SOLAR_POWER, AbilityId.EARLY_BIRD, 180, 30, 30, 30, 30, 30, 30, 235, 70, 36, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SUNFLORA, 2, false, false, false, "Sun Pokémon", PokemonType.GRASS, null, 0.8, 8.5, AbilityId.CHLOROPHYLL, AbilityId.SOLAR_POWER, AbilityId.EARLY_BIRD, 425, 75, 75, 55, 105, 85, 30, 120, 70, 149, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.YANMA, 2, false, false, false, "Clear Wing Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.2, 38, AbilityId.SPEED_BOOST, AbilityId.COMPOUND_EYES, AbilityId.FRISK, 390, 65, 65, 45, 75, 45, 95, 75, 70, 78, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.WOOPER, 2, false, false, false, "Water Fish Pokémon", PokemonType.WATER, PokemonType.GROUND, 0.4, 8.5, AbilityId.DAMP, AbilityId.WATER_ABSORB, AbilityId.UNAWARE, 210, 55, 45, 45, 25, 25, 15, 255, 50, 42, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.QUAGSIRE, 2, false, false, false, "Water Fish Pokémon", PokemonType.WATER, PokemonType.GROUND, 1.4, 75, AbilityId.DAMP, AbilityId.WATER_ABSORB, AbilityId.UNAWARE, 430, 95, 85, 85, 65, 65, 35, 90, 50, 151, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.ESPEON, 2, false, false, false, "Sun Pokémon", PokemonType.PSYCHIC, null, 0.9, 26.5, AbilityId.SYNCHRONIZE, AbilityId.NONE, AbilityId.MAGIC_BOUNCE, 525, 65, 65, 60, 130, 95, 110, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.UMBREON, 2, false, false, false, "Moonlight Pokémon", PokemonType.DARK, null, 1, 27, AbilityId.SYNCHRONIZE, AbilityId.NONE, AbilityId.INNER_FOCUS, 525, 95, 65, 110, 60, 130, 65, 45, 35, 184, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.MURKROW, 2, false, false, false, "Darkness Pokémon", PokemonType.DARK, PokemonType.FLYING, 0.5, 2.1, AbilityId.INSOMNIA, AbilityId.SUPER_LUCK, AbilityId.PRANKSTER, 405, 60, 85, 42, 85, 42, 91, 30, 35, 81, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.SLOWKING, 2, false, false, false, "Royal Pokémon", PokemonType.WATER, PokemonType.PSYCHIC, 2, 79.5, AbilityId.OBLIVIOUS, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 490, 95, 75, 80, 100, 110, 30, 70, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MISDREAVUS, 2, false, false, false, "Screech Pokémon", PokemonType.GHOST, null, 0.7, 1, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 435, 60, 60, 60, 85, 85, 85, 45, 35, 87, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.UNOWN, 2, false, false, false, "Symbol Pokémon", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, GrowthRate.MEDIUM_FAST, null, false, false, - new PokemonForm("A", "a", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("B", "b", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("C", "c", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("D", "d", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("E", "e", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("F", "f", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("G", "g", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("H", "h", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("I", "i", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("J", "j", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("K", "k", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("L", "l", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("M", "m", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("N", "n", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("O", "o", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("P", "p", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("Q", "q", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("R", "r", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("S", "s", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("T", "t", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("U", "u", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("V", "v", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("W", "w", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("X", "x", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("Y", "y", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("Z", "z", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("!", "exclamation", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - new PokemonForm("?", "question", PokemonType.PSYCHIC, null, 0.5, 5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 336, 48, 72, 48, 72, 48, 48, 225, 70, 118, false, null, true), - ), - new PokemonSpecies(SpeciesId.WOBBUFFET, 2, false, false, false, "Patient Pokémon", PokemonType.PSYCHIC, null, 1.3, 28.5, AbilityId.SHADOW_TAG, AbilityId.NONE, AbilityId.TELEPATHY, 405, 190, 33, 58, 33, 58, 33, 45, 50, 142, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.GIRAFARIG, 2, false, false, false, "Long Neck Pokémon", PokemonType.NORMAL, PokemonType.PSYCHIC, 1.5, 41.5, AbilityId.INNER_FOCUS, AbilityId.EARLY_BIRD, AbilityId.SAP_SIPPER, 455, 70, 80, 65, 90, 65, 85, 60, 70, 159, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.PINECO, 2, false, false, false, "Bagworm Pokémon", PokemonType.BUG, null, 0.6, 7.2, AbilityId.STURDY, AbilityId.NONE, AbilityId.OVERCOAT, 290, 50, 65, 90, 35, 35, 15, 190, 70, 58, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.FORRETRESS, 2, false, false, false, "Bagworm Pokémon", PokemonType.BUG, PokemonType.STEEL, 1.2, 125.8, AbilityId.STURDY, AbilityId.NONE, AbilityId.OVERCOAT, 465, 75, 90, 140, 60, 60, 40, 75, 70, 163, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DUNSPARCE, 2, false, false, false, "Land Snake Pokémon", PokemonType.NORMAL, null, 1.5, 14, AbilityId.SERENE_GRACE, AbilityId.RUN_AWAY, AbilityId.RATTLED, 415, 100, 70, 70, 65, 65, 45, 190, 50, 145, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GLIGAR, 2, false, false, false, "Fly Scorpion Pokémon", PokemonType.GROUND, PokemonType.FLYING, 1.1, 64.8, AbilityId.HYPER_CUTTER, AbilityId.SAND_VEIL, AbilityId.IMMUNITY, 430, 65, 75, 105, 35, 65, 85, 60, 70, 86, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.STEELIX, 2, false, false, false, "Iron Snake Pokémon", PokemonType.STEEL, PokemonType.GROUND, 9.2, 400, AbilityId.ROCK_HEAD, AbilityId.STURDY, AbilityId.SHEER_FORCE, 510, 75, 85, 200, 55, 65, 30, 25, 50, 179, GrowthRate.MEDIUM_FAST, 50, true, true, - new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.GROUND, 9.2, 400, AbilityId.ROCK_HEAD, AbilityId.STURDY, AbilityId.SHEER_FORCE, 510, 75, 85, 200, 55, 65, 30, 25, 50, 179, true, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.STEEL, PokemonType.GROUND, 10.5, 740, AbilityId.SAND_FORCE, AbilityId.SAND_FORCE, AbilityId.SAND_FORCE, 610, 75, 125, 230, 55, 95, 30, 25, 50, 179, true), - ), - new PokemonSpecies(SpeciesId.SNUBBULL, 2, false, false, false, "Fairy Pokémon", PokemonType.FAIRY, null, 0.6, 7.8, AbilityId.INTIMIDATE, AbilityId.RUN_AWAY, AbilityId.RATTLED, 300, 60, 80, 50, 40, 40, 30, 190, 70, 60, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.GRANBULL, 2, false, false, false, "Fairy Pokémon", PokemonType.FAIRY, null, 1.4, 48.7, AbilityId.INTIMIDATE, AbilityId.QUICK_FEET, AbilityId.RATTLED, 450, 90, 120, 75, 60, 60, 45, 75, 70, 158, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.QWILFISH, 2, false, false, false, "Balloon Pokémon", PokemonType.WATER, PokemonType.POISON, 0.5, 3.9, AbilityId.POISON_POINT, AbilityId.SWIFT_SWIM, AbilityId.INTIMIDATE, 440, 65, 95, 85, 55, 55, 85, 45, 50, 88, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SCIZOR, 2, false, false, false, "Pincer Pokémon", PokemonType.BUG, PokemonType.STEEL, 1.8, 118, AbilityId.SWARM, AbilityId.TECHNICIAN, AbilityId.LIGHT_METAL, 500, 70, 130, 100, 55, 80, 65, 25, 50, 175, GrowthRate.MEDIUM_FAST, 50, true, true, - new PokemonForm("Normal", "", PokemonType.BUG, PokemonType.STEEL, 1.8, 118, AbilityId.SWARM, AbilityId.TECHNICIAN, AbilityId.LIGHT_METAL, 500, 70, 130, 100, 55, 80, 65, 25, 50, 175, true, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.BUG, PokemonType.STEEL, 2, 125, AbilityId.TECHNICIAN, AbilityId.TECHNICIAN, AbilityId.TECHNICIAN, 600, 70, 150, 140, 65, 100, 75, 25, 50, 175, true), - ), - new PokemonSpecies(SpeciesId.SHUCKLE, 2, false, false, false, "Mold Pokémon", PokemonType.BUG, PokemonType.ROCK, 0.6, 20.5, AbilityId.STURDY, AbilityId.GLUTTONY, AbilityId.CONTRARY, 505, 20, 10, 230, 10, 230, 5, 190, 50, 177, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.HERACROSS, 2, false, false, false, "Single Horn Pokémon", PokemonType.BUG, PokemonType.FIGHTING, 1.5, 54, AbilityId.SWARM, AbilityId.GUTS, AbilityId.MOXIE, 500, 80, 125, 75, 40, 95, 85, 45, 50, 175, GrowthRate.SLOW, 50, true, true, - new PokemonForm("Normal", "", PokemonType.BUG, PokemonType.FIGHTING, 1.5, 54, AbilityId.SWARM, AbilityId.GUTS, AbilityId.MOXIE, 500, 80, 125, 75, 40, 95, 85, 45, 50, 175, true, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.BUG, PokemonType.FIGHTING, 1.7, 62.5, AbilityId.SKILL_LINK, AbilityId.SKILL_LINK, AbilityId.SKILL_LINK, 600, 80, 185, 115, 40, 105, 75, 45, 50, 175, true), - ), - new PokemonSpecies(SpeciesId.SNEASEL, 2, false, false, false, "Sharp Claw Pokémon", PokemonType.DARK, PokemonType.ICE, 0.9, 28, AbilityId.INNER_FOCUS, AbilityId.KEEN_EYE, AbilityId.PICKPOCKET, 430, 55, 95, 55, 35, 75, 115, 60, 35, 86, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.TEDDIURSA, 2, false, false, false, "Little Bear Pokémon", PokemonType.NORMAL, null, 0.6, 8.8, AbilityId.PICKUP, AbilityId.QUICK_FEET, AbilityId.HONEY_GATHER, 330, 60, 80, 50, 50, 50, 40, 120, 70, 66, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.URSARING, 2, false, false, false, "Hibernator Pokémon", PokemonType.NORMAL, null, 1.8, 125.8, AbilityId.GUTS, AbilityId.QUICK_FEET, AbilityId.UNNERVE, 500, 90, 130, 75, 75, 75, 55, 60, 70, 175, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.SLUGMA, 2, false, false, false, "Lava Pokémon", PokemonType.FIRE, null, 0.7, 35, AbilityId.MAGMA_ARMOR, AbilityId.FLAME_BODY, AbilityId.WEAK_ARMOR, 250, 40, 40, 40, 70, 40, 20, 190, 70, 50, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MAGCARGO, 2, false, false, false, "Lava Pokémon", PokemonType.FIRE, PokemonType.ROCK, 0.8, 55, AbilityId.MAGMA_ARMOR, AbilityId.FLAME_BODY, AbilityId.WEAK_ARMOR, 430, 60, 50, 120, 90, 80, 30, 75, 70, 151, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SWINUB, 2, false, false, false, "Pig Pokémon", PokemonType.ICE, PokemonType.GROUND, 0.4, 6.5, AbilityId.OBLIVIOUS, AbilityId.SNOW_CLOAK, AbilityId.THICK_FAT, 250, 50, 50, 40, 30, 30, 50, 225, 50, 50, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.PILOSWINE, 2, false, false, false, "Swine Pokémon", PokemonType.ICE, PokemonType.GROUND, 1.1, 55.8, AbilityId.OBLIVIOUS, AbilityId.SNOW_CLOAK, AbilityId.THICK_FAT, 450, 100, 100, 80, 60, 60, 50, 75, 50, 158, GrowthRate.SLOW, 50, true), - new PokemonSpecies(SpeciesId.CORSOLA, 2, false, false, false, "Coral Pokémon", PokemonType.WATER, PokemonType.ROCK, 0.6, 5, AbilityId.HUSTLE, AbilityId.NATURAL_CURE, AbilityId.REGENERATOR, 410, 65, 55, 95, 65, 95, 35, 60, 50, 144, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.REMORAID, 2, false, false, false, "Jet Pokémon", PokemonType.WATER, null, 0.6, 12, AbilityId.HUSTLE, AbilityId.SNIPER, AbilityId.MOODY, 300, 35, 65, 35, 65, 35, 65, 190, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.OCTILLERY, 2, false, false, false, "Jet Pokémon", PokemonType.WATER, null, 0.9, 28.5, AbilityId.SUCTION_CUPS, AbilityId.SNIPER, AbilityId.MOODY, 480, 75, 105, 75, 105, 75, 45, 75, 50, 168, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.DELIBIRD, 2, false, false, false, "Delivery Pokémon", PokemonType.ICE, PokemonType.FLYING, 0.9, 16, AbilityId.VITAL_SPIRIT, AbilityId.HUSTLE, AbilityId.INSOMNIA, 330, 45, 55, 45, 65, 45, 75, 45, 50, 116, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.MANTINE, 2, false, false, false, "Kite Pokémon", PokemonType.WATER, PokemonType.FLYING, 2.1, 220, AbilityId.SWIFT_SWIM, AbilityId.WATER_ABSORB, AbilityId.WATER_VEIL, 485, 85, 40, 70, 80, 140, 70, 25, 50, 170, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.SKARMORY, 2, false, false, false, "Armor Bird Pokémon", PokemonType.STEEL, PokemonType.FLYING, 1.7, 50.5, AbilityId.KEEN_EYE, AbilityId.STURDY, AbilityId.WEAK_ARMOR, 465, 65, 80, 140, 40, 70, 70, 25, 50, 163, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.HOUNDOUR, 2, false, false, false, "Dark Pokémon", PokemonType.DARK, PokemonType.FIRE, 0.6, 10.8, AbilityId.EARLY_BIRD, AbilityId.FLASH_FIRE, AbilityId.UNNERVE, 330, 45, 60, 30, 80, 50, 65, 120, 35, 66, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.HOUNDOOM, 2, false, false, false, "Dark Pokémon", PokemonType.DARK, PokemonType.FIRE, 1.4, 35, AbilityId.EARLY_BIRD, AbilityId.FLASH_FIRE, AbilityId.UNNERVE, 500, 75, 90, 50, 110, 80, 95, 45, 35, 175, GrowthRate.SLOW, 50, true, true, - new PokemonForm("Normal", "", PokemonType.DARK, PokemonType.FIRE, 1.4, 35, AbilityId.EARLY_BIRD, AbilityId.FLASH_FIRE, AbilityId.UNNERVE, 500, 75, 90, 50, 110, 80, 95, 45, 35, 175, true, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DARK, PokemonType.FIRE, 1.9, 49.5, AbilityId.SOLAR_POWER, AbilityId.SOLAR_POWER, AbilityId.SOLAR_POWER, 600, 75, 90, 90, 140, 90, 115, 45, 35, 175, true), - ), - new PokemonSpecies(SpeciesId.KINGDRA, 2, false, false, false, "Dragon Pokémon", PokemonType.WATER, PokemonType.DRAGON, 1.8, 152, AbilityId.SWIFT_SWIM, AbilityId.SNIPER, AbilityId.DAMP, 540, 75, 95, 95, 95, 95, 85, 45, 50, 270, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PHANPY, 2, false, false, false, "Long Nose Pokémon", PokemonType.GROUND, null, 0.5, 33.5, AbilityId.PICKUP, AbilityId.NONE, AbilityId.SAND_VEIL, 330, 90, 60, 60, 40, 40, 40, 120, 70, 66, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DONPHAN, 2, false, false, false, "Armor Pokémon", PokemonType.GROUND, null, 1.1, 120, AbilityId.STURDY, AbilityId.NONE, AbilityId.SAND_VEIL, 500, 90, 120, 120, 60, 60, 50, 60, 70, 175, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.PORYGON2, 2, false, false, false, "Virtual Pokémon", PokemonType.NORMAL, null, 0.6, 32.5, AbilityId.TRACE, AbilityId.DOWNLOAD, AbilityId.ANALYTIC, 515, 85, 80, 90, 105, 95, 60, 45, 50, 180, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.STANTLER, 2, false, false, false, "Big Horn Pokémon", PokemonType.NORMAL, null, 1.4, 71.2, AbilityId.INTIMIDATE, AbilityId.FRISK, AbilityId.SAP_SIPPER, 465, 73, 95, 62, 85, 65, 85, 45, 70, 163, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.SMEARGLE, 2, false, false, false, "Painter Pokémon", PokemonType.NORMAL, null, 1.2, 58, AbilityId.OWN_TEMPO, AbilityId.TECHNICIAN, AbilityId.MOODY, 250, 55, 20, 35, 20, 45, 75, 45, 70, 88, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.TYROGUE, 2, false, false, false, "Scuffle Pokémon", PokemonType.FIGHTING, null, 0.7, 21, AbilityId.GUTS, AbilityId.STEADFAST, AbilityId.VITAL_SPIRIT, 210, 35, 35, 35, 35, 35, 35, 75, 50, 42, GrowthRate.MEDIUM_FAST, 100, false), - new PokemonSpecies(SpeciesId.HITMONTOP, 2, false, false, false, "Handstand Pokémon", PokemonType.FIGHTING, null, 1.4, 48, AbilityId.INTIMIDATE, AbilityId.TECHNICIAN, AbilityId.STEADFAST, 455, 50, 95, 95, 35, 110, 70, 45, 50, 159, GrowthRate.MEDIUM_FAST, 100, false), - new PokemonSpecies(SpeciesId.SMOOCHUM, 2, false, false, false, "Kiss Pokémon", PokemonType.ICE, PokemonType.PSYCHIC, 0.4, 6, AbilityId.OBLIVIOUS, AbilityId.FOREWARN, AbilityId.HYDRATION, 305, 45, 30, 15, 85, 65, 65, 45, 50, 61, GrowthRate.MEDIUM_FAST, 0, false), - new PokemonSpecies(SpeciesId.ELEKID, 2, false, false, false, "Electric Pokémon", PokemonType.ELECTRIC, null, 0.6, 23.5, AbilityId.STATIC, AbilityId.NONE, AbilityId.VITAL_SPIRIT, 360, 45, 63, 37, 65, 55, 95, 45, 50, 72, GrowthRate.MEDIUM_FAST, 75, false), - new PokemonSpecies(SpeciesId.MAGBY, 2, false, false, false, "Live Coal Pokémon", PokemonType.FIRE, null, 0.7, 21.4, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.VITAL_SPIRIT, 365, 45, 75, 37, 70, 55, 83, 45, 50, 73, GrowthRate.MEDIUM_FAST, 75, false), - new PokemonSpecies(SpeciesId.MILTANK, 2, false, false, false, "Milk Cow Pokémon", PokemonType.NORMAL, null, 1.2, 75.5, AbilityId.THICK_FAT, AbilityId.SCRAPPY, AbilityId.SAP_SIPPER, 490, 95, 80, 105, 40, 70, 100, 45, 50, 172, GrowthRate.SLOW, 0, false), - new PokemonSpecies(SpeciesId.BLISSEY, 2, false, false, false, "Happiness Pokémon", PokemonType.NORMAL, null, 1.5, 46.8, AbilityId.NATURAL_CURE, AbilityId.SERENE_GRACE, AbilityId.HEALER, 540, 255, 10, 10, 75, 135, 55, 30, 140, 608, GrowthRate.FAST, 0, false), - new PokemonSpecies(SpeciesId.RAIKOU, 2, true, false, false, "Thunder Pokémon", PokemonType.ELECTRIC, null, 1.9, 178, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.INNER_FOCUS, 580, 90, 85, 75, 115, 100, 115, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.ENTEI, 2, true, false, false, "Volcano Pokémon", PokemonType.FIRE, null, 2.1, 198, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.INNER_FOCUS, 580, 115, 115, 85, 90, 75, 100, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.SUICUNE, 2, true, false, false, "Aurora Pokémon", PokemonType.WATER, null, 2, 187, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.INNER_FOCUS, 580, 100, 75, 115, 90, 115, 85, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.LARVITAR, 2, false, false, false, "Rock Skin Pokémon", PokemonType.ROCK, PokemonType.GROUND, 0.6, 72, AbilityId.GUTS, AbilityId.NONE, AbilityId.SAND_VEIL, 300, 50, 64, 50, 45, 50, 41, 45, 35, 60, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.PUPITAR, 2, false, false, false, "Hard Shell Pokémon", PokemonType.ROCK, PokemonType.GROUND, 1.2, 152, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.SHED_SKIN, 410, 70, 84, 70, 65, 70, 51, 45, 35, 144, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.TYRANITAR, 2, false, false, false, "Armor Pokémon", PokemonType.ROCK, PokemonType.DARK, 2, 202, AbilityId.SAND_STREAM, AbilityId.NONE, AbilityId.UNNERVE, 600, 100, 134, 110, 95, 100, 61, 45, 35, 300, GrowthRate.SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.ROCK, PokemonType.DARK, 2, 202, AbilityId.SAND_STREAM, AbilityId.NONE, AbilityId.UNNERVE, 600, 100, 134, 110, 95, 100, 61, 45, 35, 300, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.ROCK, PokemonType.DARK, 2.5, 255, AbilityId.SAND_STREAM, AbilityId.NONE, AbilityId.SAND_STREAM, 700, 100, 164, 150, 95, 120, 71, 45, 35, 300), - ), - new PokemonSpecies(SpeciesId.LUGIA, 2, false, true, false, "Diving Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 5.2, 216, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.MULTISCALE, 680, 106, 90, 130, 90, 154, 110, 3, 0, 340, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.HO_OH, 2, false, true, false, "Rainbow Pokémon", PokemonType.FIRE, PokemonType.FLYING, 3.8, 199, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.REGENERATOR, 680, 106, 130, 90, 110, 154, 90, 3, 0, 340, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.CELEBI, 2, false, false, true, "Time Travel Pokémon", PokemonType.PSYCHIC, PokemonType.GRASS, 0.6, 5, AbilityId.NATURAL_CURE, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 45, 100, 300, GrowthRate.MEDIUM_SLOW, null, false), - new PokemonSpecies(SpeciesId.TREECKO, 3, false, false, false, "Wood Gecko Pokémon", PokemonType.GRASS, null, 0.5, 5, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.UNBURDEN, 310, 40, 45, 35, 65, 55, 70, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.GROVYLE, 3, false, false, false, "Wood Gecko Pokémon", PokemonType.GRASS, null, 0.9, 21.6, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.UNBURDEN, 405, 50, 65, 45, 85, 65, 95, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.SCEPTILE, 3, false, false, false, "Forest Pokémon", PokemonType.GRASS, null, 1.7, 52.2, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.UNBURDEN, 530, 70, 85, 65, 105, 85, 120, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, - new PokemonForm("Normal", "", PokemonType.GRASS, null, 1.7, 52.2, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.UNBURDEN, 530, 70, 85, 65, 105, 85, 120, 45, 50, 265, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.GRASS, PokemonType.DRAGON, 1.9, 55.2, AbilityId.LIGHTNING_ROD, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 630, 70, 110, 75, 145, 85, 145, 45, 50, 265), - ), - new PokemonSpecies(SpeciesId.TORCHIC, 3, false, false, false, "Chick Pokémon", PokemonType.FIRE, null, 0.4, 2.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SPEED_BOOST, 310, 45, 60, 40, 70, 50, 45, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, true), - new PokemonSpecies(SpeciesId.COMBUSKEN, 3, false, false, false, "Young Fowl Pokémon", PokemonType.FIRE, PokemonType.FIGHTING, 0.9, 19.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SPEED_BOOST, 405, 60, 85, 60, 85, 60, 55, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, true), - new PokemonSpecies(SpeciesId.BLAZIKEN, 3, false, false, false, "Blaze Pokémon", PokemonType.FIRE, PokemonType.FIGHTING, 1.9, 52, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SPEED_BOOST, 530, 80, 120, 70, 110, 70, 80, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, true, true, - new PokemonForm("Normal", "", PokemonType.FIRE, PokemonType.FIGHTING, 1.9, 52, AbilityId.BLAZE, AbilityId.NONE, AbilityId.SPEED_BOOST, 530, 80, 120, 70, 110, 70, 80, 45, 50, 265, true, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.FIRE, PokemonType.FIGHTING, 1.9, 52, AbilityId.SPEED_BOOST, AbilityId.NONE, AbilityId.SPEED_BOOST, 630, 80, 160, 80, 130, 80, 100, 45, 50, 265, true), - ), - new PokemonSpecies(SpeciesId.MUDKIP, 3, false, false, false, "Mud Fish Pokémon", PokemonType.WATER, null, 0.4, 7.6, AbilityId.TORRENT, AbilityId.NONE, AbilityId.DAMP, 310, 50, 70, 50, 50, 50, 40, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.MARSHTOMP, 3, false, false, false, "Mud Fish Pokémon", PokemonType.WATER, PokemonType.GROUND, 0.7, 28, AbilityId.TORRENT, AbilityId.NONE, AbilityId.DAMP, 405, 70, 85, 70, 60, 70, 50, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.SWAMPERT, 3, false, false, false, "Mud Fish Pokémon", PokemonType.WATER, PokemonType.GROUND, 1.5, 81.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.DAMP, 535, 100, 110, 90, 85, 90, 60, 45, 50, 268, GrowthRate.MEDIUM_SLOW, 87.5, false, true, - new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.GROUND, 1.5, 81.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.DAMP, 535, 100, 110, 90, 85, 90, 60, 45, 50, 268, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.WATER, PokemonType.GROUND, 1.9, 102, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.SWIFT_SWIM, 635, 100, 150, 110, 95, 110, 70, 45, 50, 268), - ), - new PokemonSpecies(SpeciesId.POOCHYENA, 3, false, false, false, "Bite Pokémon", PokemonType.DARK, null, 0.5, 13.6, AbilityId.RUN_AWAY, AbilityId.QUICK_FEET, AbilityId.RATTLED, 220, 35, 55, 35, 30, 30, 35, 255, 70, 56, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MIGHTYENA, 3, false, false, false, "Bite Pokémon", PokemonType.DARK, null, 1, 37, AbilityId.INTIMIDATE, AbilityId.QUICK_FEET, AbilityId.MOXIE, 420, 70, 90, 70, 60, 60, 70, 127, 70, 147, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ZIGZAGOON, 3, false, false, false, "Tiny Raccoon Pokémon", PokemonType.NORMAL, null, 0.4, 17.5, AbilityId.PICKUP, AbilityId.GLUTTONY, AbilityId.QUICK_FEET, 240, 38, 30, 41, 30, 41, 60, 255, 50, 56, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.LINOONE, 3, false, false, false, "Rushing Pokémon", PokemonType.NORMAL, null, 0.5, 32.5, AbilityId.PICKUP, AbilityId.GLUTTONY, AbilityId.QUICK_FEET, 420, 78, 70, 61, 50, 61, 100, 90, 50, 147, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.WURMPLE, 3, false, false, false, "Worm Pokémon", PokemonType.BUG, null, 0.3, 3.6, AbilityId.SHIELD_DUST, AbilityId.NONE, AbilityId.RUN_AWAY, 195, 45, 45, 35, 20, 30, 20, 255, 70, 56, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SILCOON, 3, false, false, false, "Cocoon Pokémon", PokemonType.BUG, null, 0.6, 10, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.SHED_SKIN, 205, 50, 35, 55, 25, 25, 15, 120, 70, 72, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BEAUTIFLY, 3, false, false, false, "Butterfly Pokémon", PokemonType.BUG, PokemonType.FLYING, 1, 28.4, AbilityId.SWARM, AbilityId.NONE, AbilityId.RIVALRY, 395, 60, 70, 50, 100, 50, 65, 45, 70, 198, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.CASCOON, 3, false, false, false, "Cocoon Pokémon", PokemonType.BUG, null, 0.7, 11.5, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.SHED_SKIN, 205, 50, 35, 55, 25, 25, 15, 120, 70, 72, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DUSTOX, 3, false, false, false, "Poison Moth Pokémon", PokemonType.BUG, PokemonType.POISON, 1.2, 31.6, AbilityId.SHIELD_DUST, AbilityId.NONE, AbilityId.COMPOUND_EYES, 385, 60, 50, 70, 50, 90, 65, 45, 70, 193, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.LOTAD, 3, false, false, false, "Water Weed Pokémon", PokemonType.WATER, PokemonType.GRASS, 0.5, 2.6, AbilityId.SWIFT_SWIM, AbilityId.RAIN_DISH, AbilityId.OWN_TEMPO, 220, 40, 30, 30, 40, 50, 30, 255, 50, 44, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.LOMBRE, 3, false, false, false, "Jolly Pokémon", PokemonType.WATER, PokemonType.GRASS, 1.2, 32.5, AbilityId.SWIFT_SWIM, AbilityId.RAIN_DISH, AbilityId.OWN_TEMPO, 340, 60, 50, 50, 60, 70, 50, 120, 50, 119, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.LUDICOLO, 3, false, false, false, "Carefree Pokémon", PokemonType.WATER, PokemonType.GRASS, 1.5, 55, AbilityId.SWIFT_SWIM, AbilityId.RAIN_DISH, AbilityId.OWN_TEMPO, 480, 80, 70, 70, 90, 100, 70, 45, 50, 240, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.SEEDOT, 3, false, false, false, "Acorn Pokémon", PokemonType.GRASS, null, 0.5, 4, AbilityId.CHLOROPHYLL, AbilityId.EARLY_BIRD, AbilityId.PICKPOCKET, 220, 40, 40, 50, 30, 30, 30, 255, 50, 44, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.NUZLEAF, 3, false, false, false, "Wily Pokémon", PokemonType.GRASS, PokemonType.DARK, 1, 28, AbilityId.CHLOROPHYLL, AbilityId.EARLY_BIRD, AbilityId.PICKPOCKET, 340, 70, 70, 40, 60, 40, 60, 120, 50, 119, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.SHIFTRY, 3, false, false, false, "Wicked Pokémon", PokemonType.GRASS, PokemonType.DARK, 1.3, 59.6, AbilityId.CHLOROPHYLL, AbilityId.WIND_RIDER, AbilityId.PICKPOCKET, 480, 90, 100, 60, 90, 60, 80, 45, 50, 240, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.TAILLOW, 3, false, false, false, "Tiny Swallow Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 2.3, AbilityId.GUTS, AbilityId.NONE, AbilityId.SCRAPPY, 270, 40, 55, 30, 30, 30, 85, 200, 70, 54, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SWELLOW, 3, false, false, false, "Swallow Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.7, 19.8, AbilityId.GUTS, AbilityId.NONE, AbilityId.SCRAPPY, 455, 60, 85, 60, 75, 50, 125, 45, 70, 159, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.WINGULL, 3, false, false, false, "Seagull Pokémon", PokemonType.WATER, PokemonType.FLYING, 0.6, 9.5, AbilityId.KEEN_EYE, AbilityId.HYDRATION, AbilityId.RAIN_DISH, 270, 40, 30, 30, 55, 30, 85, 190, 50, 54, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PELIPPER, 3, false, false, false, "Water Bird Pokémon", PokemonType.WATER, PokemonType.FLYING, 1.2, 28, AbilityId.KEEN_EYE, AbilityId.DRIZZLE, AbilityId.RAIN_DISH, 440, 60, 50, 100, 95, 70, 65, 45, 50, 154, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.RALTS, 3, false, false, false, "Feeling Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 0.4, 6.6, AbilityId.SYNCHRONIZE, AbilityId.TRACE, AbilityId.TELEPATHY, 198, 28, 25, 25, 45, 35, 40, 235, 35, 40, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.KIRLIA, 3, false, false, false, "Emotion Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 0.8, 20.2, AbilityId.SYNCHRONIZE, AbilityId.TRACE, AbilityId.TELEPATHY, 278, 38, 35, 35, 65, 55, 50, 120, 35, 97, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.GARDEVOIR, 3, false, false, false, "Embrace Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 1.6, 48.4, AbilityId.SYNCHRONIZE, AbilityId.TRACE, AbilityId.TELEPATHY, 518, 68, 65, 65, 125, 115, 80, 45, 35, 259, GrowthRate.SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.PSYCHIC, PokemonType.FAIRY, 1.6, 48.4, AbilityId.SYNCHRONIZE, AbilityId.TRACE, AbilityId.TELEPATHY, 518, 68, 65, 65, 125, 115, 80, 45, 35, 259, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.PSYCHIC, PokemonType.FAIRY, 1.6, 48.4, AbilityId.PIXILATE, AbilityId.PIXILATE, AbilityId.PIXILATE, 618, 68, 85, 65, 165, 135, 100, 45, 35, 259), - ), - new PokemonSpecies(SpeciesId.SURSKIT, 3, false, false, false, "Pond Skater Pokémon", PokemonType.BUG, PokemonType.WATER, 0.5, 1.7, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.RAIN_DISH, 269, 40, 30, 32, 50, 52, 65, 200, 70, 54, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MASQUERAIN, 3, false, false, false, "Eyeball Pokémon", PokemonType.BUG, PokemonType.FLYING, 0.8, 3.6, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.UNNERVE, 454, 70, 60, 62, 100, 82, 80, 75, 70, 159, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SHROOMISH, 3, false, false, false, "Mushroom Pokémon", PokemonType.GRASS, null, 0.4, 4.5, AbilityId.EFFECT_SPORE, AbilityId.POISON_HEAL, AbilityId.QUICK_FEET, 295, 60, 40, 60, 40, 60, 35, 255, 70, 59, GrowthRate.FLUCTUATING, 50, false), - new PokemonSpecies(SpeciesId.BRELOOM, 3, false, false, false, "Mushroom Pokémon", PokemonType.GRASS, PokemonType.FIGHTING, 1.2, 39.2, AbilityId.EFFECT_SPORE, AbilityId.POISON_HEAL, AbilityId.TECHNICIAN, 460, 60, 130, 80, 60, 60, 70, 90, 70, 161, GrowthRate.FLUCTUATING, 50, false), - new PokemonSpecies(SpeciesId.SLAKOTH, 3, false, false, false, "Slacker Pokémon", PokemonType.NORMAL, null, 0.8, 24, AbilityId.TRUANT, AbilityId.NONE, AbilityId.STALL, 280, 60, 60, 60, 35, 35, 30, 255, 70, 56, GrowthRate.SLOW, 50, false), //Custom Hidden - new PokemonSpecies(SpeciesId.VIGOROTH, 3, false, false, false, "Wild Monkey Pokémon", PokemonType.NORMAL, null, 1.4, 46.5, AbilityId.VITAL_SPIRIT, AbilityId.NONE, AbilityId.INSOMNIA, 440, 80, 80, 80, 55, 55, 90, 120, 70, 154, GrowthRate.SLOW, 50, false), //Custom Hidden - new PokemonSpecies(SpeciesId.SLAKING, 3, false, false, false, "Lazy Pokémon", PokemonType.NORMAL, null, 2, 130.5, AbilityId.TRUANT, AbilityId.NONE, AbilityId.STALL, 670, 150, 160, 100, 95, 65, 100, 45, 70, 285, GrowthRate.SLOW, 50, false), //Custom Hidden - new PokemonSpecies(SpeciesId.NINCADA, 3, false, false, false, "Trainee Pokémon", PokemonType.BUG, PokemonType.GROUND, 0.5, 5.5, AbilityId.COMPOUND_EYES, AbilityId.NONE, AbilityId.RUN_AWAY, 266, 31, 45, 90, 30, 30, 40, 255, 50, 53, GrowthRate.ERRATIC, 50, false), - new PokemonSpecies(SpeciesId.NINJASK, 3, false, false, false, "Ninja Pokémon", PokemonType.BUG, PokemonType.FLYING, 0.8, 12, AbilityId.SPEED_BOOST, AbilityId.NONE, AbilityId.INFILTRATOR, 456, 61, 90, 45, 50, 50, 160, 120, 50, 160, GrowthRate.ERRATIC, 50, false), - new PokemonSpecies(SpeciesId.SHEDINJA, 3, false, false, false, "Shed Pokémon", PokemonType.BUG, PokemonType.GHOST, 0.8, 1.2, AbilityId.WONDER_GUARD, AbilityId.NONE, AbilityId.NONE, 236, 1, 90, 45, 30, 30, 40, 45, 50, 83, GrowthRate.ERRATIC, null, false), - new PokemonSpecies(SpeciesId.WHISMUR, 3, false, false, false, "Whisper Pokémon", PokemonType.NORMAL, null, 0.6, 16.3, AbilityId.SOUNDPROOF, AbilityId.NONE, AbilityId.RATTLED, 240, 64, 51, 23, 51, 23, 28, 190, 50, 48, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.LOUDRED, 3, false, false, false, "Big Voice Pokémon", PokemonType.NORMAL, null, 1, 40.5, AbilityId.SOUNDPROOF, AbilityId.NONE, AbilityId.SCRAPPY, 360, 84, 71, 43, 71, 43, 48, 120, 50, 126, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.EXPLOUD, 3, false, false, false, "Loud Noise Pokémon", PokemonType.NORMAL, null, 1.5, 84, AbilityId.SOUNDPROOF, AbilityId.NONE, AbilityId.SCRAPPY, 490, 104, 91, 63, 91, 73, 68, 45, 50, 245, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.MAKUHITA, 3, false, false, false, "Guts Pokémon", PokemonType.FIGHTING, null, 1, 86.4, AbilityId.THICK_FAT, AbilityId.GUTS, AbilityId.SHEER_FORCE, 237, 72, 60, 30, 20, 30, 25, 180, 70, 47, GrowthRate.FLUCTUATING, 75, false), - new PokemonSpecies(SpeciesId.HARIYAMA, 3, false, false, false, "Arm Thrust Pokémon", PokemonType.FIGHTING, null, 2.3, 253.8, AbilityId.THICK_FAT, AbilityId.GUTS, AbilityId.SHEER_FORCE, 474, 144, 120, 60, 40, 60, 50, 200, 70, 166, GrowthRate.FLUCTUATING, 75, false), - new PokemonSpecies(SpeciesId.AZURILL, 3, false, false, false, "Polka Dot Pokémon", PokemonType.NORMAL, PokemonType.FAIRY, 0.2, 2, AbilityId.THICK_FAT, AbilityId.HUGE_POWER, AbilityId.SAP_SIPPER, 190, 50, 20, 40, 20, 40, 20, 150, 50, 38, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.NOSEPASS, 3, false, false, false, "Compass Pokémon", PokemonType.ROCK, null, 1, 97, AbilityId.STURDY, AbilityId.MAGNET_PULL, AbilityId.SAND_FORCE, 375, 30, 45, 135, 45, 90, 30, 255, 70, 75, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SKITTY, 3, false, false, false, "Kitten Pokémon", PokemonType.NORMAL, null, 0.6, 11, AbilityId.CUTE_CHARM, AbilityId.NORMALIZE, AbilityId.WONDER_SKIN, 260, 50, 45, 45, 35, 35, 50, 255, 70, 52, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.DELCATTY, 3, false, false, false, "Prim Pokémon", PokemonType.NORMAL, null, 1.1, 32.6, AbilityId.CUTE_CHARM, AbilityId.NORMALIZE, AbilityId.WONDER_SKIN, 400, 70, 65, 65, 55, 55, 90, 60, 70, 140, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.SABLEYE, 3, false, false, false, "Darkness Pokémon", PokemonType.DARK, PokemonType.GHOST, 0.5, 11, AbilityId.KEEN_EYE, AbilityId.STALL, AbilityId.PRANKSTER, 380, 50, 75, 75, 65, 65, 50, 45, 35, 133, GrowthRate.MEDIUM_SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.DARK, PokemonType.GHOST, 0.5, 11, AbilityId.KEEN_EYE, AbilityId.STALL, AbilityId.PRANKSTER, 380, 50, 75, 75, 65, 65, 50, 45, 35, 133, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DARK, PokemonType.GHOST, 0.5, 161, AbilityId.MAGIC_BOUNCE, AbilityId.MAGIC_BOUNCE, AbilityId.MAGIC_BOUNCE, 480, 50, 85, 125, 85, 115, 20, 45, 35, 133), - ), - new PokemonSpecies(SpeciesId.MAWILE, 3, false, false, false, "Deceiver Pokémon", PokemonType.STEEL, PokemonType.FAIRY, 0.6, 11.5, AbilityId.HYPER_CUTTER, AbilityId.INTIMIDATE, AbilityId.SHEER_FORCE, 380, 50, 85, 85, 55, 55, 50, 45, 50, 133, GrowthRate.FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.FAIRY, 0.6, 11.5, AbilityId.HYPER_CUTTER, AbilityId.INTIMIDATE, AbilityId.SHEER_FORCE, 380, 50, 85, 85, 55, 55, 50, 45, 50, 133, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.STEEL, PokemonType.FAIRY, 1, 23.5, AbilityId.HUGE_POWER, AbilityId.HUGE_POWER, AbilityId.HUGE_POWER, 480, 50, 105, 125, 55, 95, 50, 45, 50, 133), - ), - new PokemonSpecies(SpeciesId.ARON, 3, false, false, false, "Iron Armor Pokémon", PokemonType.STEEL, PokemonType.ROCK, 0.4, 60, AbilityId.STURDY, AbilityId.ROCK_HEAD, AbilityId.HEAVY_METAL, 330, 50, 70, 100, 40, 40, 30, 180, 35, 66, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.LAIRON, 3, false, false, false, "Iron Armor Pokémon", PokemonType.STEEL, PokemonType.ROCK, 0.9, 120, AbilityId.STURDY, AbilityId.ROCK_HEAD, AbilityId.HEAVY_METAL, 430, 60, 90, 140, 50, 50, 40, 90, 35, 151, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.AGGRON, 3, false, false, false, "Iron Armor Pokémon", PokemonType.STEEL, PokemonType.ROCK, 2.1, 360, AbilityId.STURDY, AbilityId.ROCK_HEAD, AbilityId.HEAVY_METAL, 530, 70, 110, 180, 60, 60, 50, 45, 35, 265, GrowthRate.SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.ROCK, 2.1, 360, AbilityId.STURDY, AbilityId.ROCK_HEAD, AbilityId.HEAVY_METAL, 530, 70, 110, 180, 60, 60, 50, 45, 35, 265, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.STEEL, null, 2.2, 395, AbilityId.FILTER, AbilityId.FILTER, AbilityId.FILTER, 630, 70, 140, 230, 60, 80, 50, 45, 35, 265), - ), - new PokemonSpecies(SpeciesId.MEDITITE, 3, false, false, false, "Meditate Pokémon", PokemonType.FIGHTING, PokemonType.PSYCHIC, 0.6, 11.2, AbilityId.PURE_POWER, AbilityId.NONE, AbilityId.TELEPATHY, 280, 30, 40, 55, 40, 55, 60, 180, 70, 56, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.MEDICHAM, 3, false, false, false, "Meditate Pokémon", PokemonType.FIGHTING, PokemonType.PSYCHIC, 1.3, 31.5, AbilityId.PURE_POWER, AbilityId.NONE, AbilityId.TELEPATHY, 410, 60, 60, 75, 60, 75, 80, 90, 70, 144, GrowthRate.MEDIUM_FAST, 50, true, true, - new PokemonForm("Normal", "", PokemonType.FIGHTING, PokemonType.PSYCHIC, 1.3, 31.5, AbilityId.PURE_POWER, AbilityId.NONE, AbilityId.TELEPATHY, 410, 60, 60, 75, 60, 75, 80, 90, 70, 144, true, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.FIGHTING, PokemonType.PSYCHIC, 1.3, 31.5, AbilityId.PURE_POWER, AbilityId.NONE, AbilityId.PURE_POWER, 510, 60, 100, 85, 80, 85, 100, 90, 70, 144, true), - ), - new PokemonSpecies(SpeciesId.ELECTRIKE, 3, false, false, false, "Lightning Pokémon", PokemonType.ELECTRIC, null, 0.6, 15.2, AbilityId.STATIC, AbilityId.LIGHTNING_ROD, AbilityId.MINUS, 295, 40, 45, 40, 65, 40, 65, 120, 50, 59, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.MANECTRIC, 3, false, false, false, "Discharge Pokémon", PokemonType.ELECTRIC, null, 1.5, 40.2, AbilityId.STATIC, AbilityId.LIGHTNING_ROD, AbilityId.MINUS, 475, 70, 75, 60, 105, 60, 105, 45, 50, 166, GrowthRate.SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.ELECTRIC, null, 1.5, 40.2, AbilityId.STATIC, AbilityId.LIGHTNING_ROD, AbilityId.MINUS, 475, 70, 75, 60, 105, 60, 105, 45, 50, 166, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.ELECTRIC, null, 1.8, 44, AbilityId.INTIMIDATE, AbilityId.INTIMIDATE, AbilityId.INTIMIDATE, 575, 70, 75, 80, 135, 80, 135, 45, 50, 166), - ), - new PokemonSpecies(SpeciesId.PLUSLE, 3, false, false, false, "Cheering Pokémon", PokemonType.ELECTRIC, null, 0.4, 4.2, AbilityId.PLUS, AbilityId.NONE, AbilityId.LIGHTNING_ROD, 405, 60, 50, 40, 85, 75, 95, 200, 70, 142, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MINUN, 3, false, false, false, "Cheering Pokémon", PokemonType.ELECTRIC, null, 0.4, 4.2, AbilityId.MINUS, AbilityId.NONE, AbilityId.VOLT_ABSORB, 405, 60, 40, 50, 75, 85, 95, 200, 70, 142, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.VOLBEAT, 3, false, false, false, "Firefly Pokémon", PokemonType.BUG, null, 0.7, 17.7, AbilityId.ILLUMINATE, AbilityId.SWARM, AbilityId.PRANKSTER, 430, 65, 73, 75, 47, 85, 85, 150, 70, 151, GrowthRate.ERRATIC, 100, false), - new PokemonSpecies(SpeciesId.ILLUMISE, 3, false, false, false, "Firefly Pokémon", PokemonType.BUG, null, 0.6, 17.7, AbilityId.OBLIVIOUS, AbilityId.TINTED_LENS, AbilityId.PRANKSTER, 430, 65, 47, 75, 73, 85, 85, 150, 70, 151, GrowthRate.FLUCTUATING, 0, false), - new PokemonSpecies(SpeciesId.ROSELIA, 3, false, false, false, "Thorn Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.3, 2, AbilityId.NATURAL_CURE, AbilityId.POISON_POINT, AbilityId.LEAF_GUARD, 400, 50, 60, 45, 100, 80, 65, 150, 50, 140, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.GULPIN, 3, false, false, false, "Stomach Pokémon", PokemonType.POISON, null, 0.4, 10.3, AbilityId.LIQUID_OOZE, AbilityId.STICKY_HOLD, AbilityId.GLUTTONY, 302, 70, 43, 53, 43, 53, 40, 225, 70, 60, GrowthRate.FLUCTUATING, 50, true), - new PokemonSpecies(SpeciesId.SWALOT, 3, false, false, false, "Poison Bag Pokémon", PokemonType.POISON, null, 1.7, 80, AbilityId.LIQUID_OOZE, AbilityId.STICKY_HOLD, AbilityId.GLUTTONY, 467, 100, 73, 83, 73, 83, 55, 75, 70, 163, GrowthRate.FLUCTUATING, 50, true), - new PokemonSpecies(SpeciesId.CARVANHA, 3, false, false, false, "Savage Pokémon", PokemonType.WATER, PokemonType.DARK, 0.8, 20.8, AbilityId.ROUGH_SKIN, AbilityId.NONE, AbilityId.SPEED_BOOST, 305, 45, 90, 20, 65, 20, 65, 225, 35, 61, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.SHARPEDO, 3, false, false, false, "Brutal Pokémon", PokemonType.WATER, PokemonType.DARK, 1.8, 88.8, AbilityId.ROUGH_SKIN, AbilityId.NONE, AbilityId.SPEED_BOOST, 460, 70, 120, 40, 95, 40, 95, 60, 35, 161, GrowthRate.SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.DARK, 1.8, 88.8, AbilityId.ROUGH_SKIN, AbilityId.NONE, AbilityId.SPEED_BOOST, 460, 70, 120, 40, 95, 40, 95, 60, 35, 161, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.WATER, PokemonType.DARK, 2.5, 130.3, AbilityId.STRONG_JAW, AbilityId.NONE, AbilityId.STRONG_JAW, 560, 70, 140, 70, 110, 65, 105, 60, 35, 161), - ), - new PokemonSpecies(SpeciesId.WAILMER, 3, false, false, false, "Ball Whale Pokémon", PokemonType.WATER, null, 2, 130, AbilityId.WATER_VEIL, AbilityId.OBLIVIOUS, AbilityId.PRESSURE, 400, 130, 70, 35, 70, 35, 60, 125, 50, 80, GrowthRate.FLUCTUATING, 50, false), - new PokemonSpecies(SpeciesId.WAILORD, 3, false, false, false, "Float Whale Pokémon", PokemonType.WATER, null, 14.5, 398, AbilityId.WATER_VEIL, AbilityId.OBLIVIOUS, AbilityId.PRESSURE, 500, 170, 90, 45, 90, 45, 60, 60, 50, 175, GrowthRate.FLUCTUATING, 50, false), - new PokemonSpecies(SpeciesId.NUMEL, 3, false, false, false, "Numb Pokémon", PokemonType.FIRE, PokemonType.GROUND, 0.7, 24, AbilityId.OBLIVIOUS, AbilityId.SIMPLE, AbilityId.OWN_TEMPO, 305, 60, 60, 40, 65, 45, 35, 255, 70, 61, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.CAMERUPT, 3, false, false, false, "Eruption Pokémon", PokemonType.FIRE, PokemonType.GROUND, 1.9, 220, AbilityId.MAGMA_ARMOR, AbilityId.SOLID_ROCK, AbilityId.ANGER_POINT, 460, 70, 100, 70, 105, 75, 40, 150, 70, 161, GrowthRate.MEDIUM_FAST, 50, true, true, - new PokemonForm("Normal", "", PokemonType.FIRE, PokemonType.GROUND, 1.9, 220, AbilityId.MAGMA_ARMOR, AbilityId.SOLID_ROCK, AbilityId.ANGER_POINT, 460, 70, 100, 70, 105, 75, 40, 150, 70, 161, true, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.FIRE, PokemonType.GROUND, 2.5, 320.5, AbilityId.SHEER_FORCE, AbilityId.SHEER_FORCE, AbilityId.SHEER_FORCE, 560, 70, 120, 100, 145, 105, 20, 150, 70, 161), - ), - new PokemonSpecies(SpeciesId.TORKOAL, 3, false, false, false, "Coal Pokémon", PokemonType.FIRE, null, 0.5, 80.4, AbilityId.WHITE_SMOKE, AbilityId.DROUGHT, AbilityId.SHELL_ARMOR, 470, 70, 85, 140, 85, 70, 20, 90, 50, 165, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SPOINK, 3, false, false, false, "Bounce Pokémon", PokemonType.PSYCHIC, null, 0.7, 30.6, AbilityId.THICK_FAT, AbilityId.OWN_TEMPO, AbilityId.GLUTTONY, 330, 60, 25, 35, 70, 80, 60, 255, 70, 66, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.GRUMPIG, 3, false, false, false, "Manipulate Pokémon", PokemonType.PSYCHIC, null, 0.9, 71.5, AbilityId.THICK_FAT, AbilityId.OWN_TEMPO, AbilityId.GLUTTONY, 470, 80, 45, 65, 90, 110, 80, 60, 70, 165, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.SPINDA, 3, false, false, false, "Spot Panda Pokémon", PokemonType.NORMAL, null, 1.1, 5, AbilityId.OWN_TEMPO, AbilityId.TANGLED_FEET, AbilityId.CONTRARY, 360, 60, 60, 60, 60, 60, 60, 255, 70, 126, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.TRAPINCH, 3, false, false, false, "Ant Pit Pokémon", PokemonType.GROUND, null, 0.7, 15, AbilityId.HYPER_CUTTER, AbilityId.ARENA_TRAP, AbilityId.SHEER_FORCE, 290, 45, 100, 45, 45, 45, 10, 255, 50, 58, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.VIBRAVA, 3, false, false, false, "Vibration Pokémon", PokemonType.GROUND, PokemonType.DRAGON, 1.1, 15.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 340, 50, 70, 50, 50, 50, 70, 120, 50, 119, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.FLYGON, 3, false, false, false, "Mystic Pokémon", PokemonType.GROUND, PokemonType.DRAGON, 2, 82, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 520, 80, 100, 80, 80, 80, 100, 45, 50, 260, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.CACNEA, 3, false, false, false, "Cactus Pokémon", PokemonType.GRASS, null, 0.4, 51.3, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.WATER_ABSORB, 335, 50, 85, 40, 85, 40, 35, 190, 35, 67, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.CACTURNE, 3, false, false, false, "Scarecrow Pokémon", PokemonType.GRASS, PokemonType.DARK, 1.3, 77.4, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.WATER_ABSORB, 475, 70, 115, 60, 115, 60, 55, 60, 35, 166, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.SWABLU, 3, false, false, false, "Cotton Bird Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.4, 1.2, AbilityId.NATURAL_CURE, AbilityId.NONE, AbilityId.CLOUD_NINE, 310, 45, 40, 60, 40, 75, 50, 255, 50, 62, GrowthRate.ERRATIC, 50, false), - new PokemonSpecies(SpeciesId.ALTARIA, 3, false, false, false, "Humming Pokémon", PokemonType.DRAGON, PokemonType.FLYING, 1.1, 20.6, AbilityId.NATURAL_CURE, AbilityId.NONE, AbilityId.CLOUD_NINE, 490, 75, 70, 90, 70, 105, 80, 45, 50, 172, GrowthRate.ERRATIC, 50, false, true, - new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.FLYING, 1.1, 20.6, AbilityId.NATURAL_CURE, AbilityId.NONE, AbilityId.CLOUD_NINE, 490, 75, 70, 90, 70, 105, 80, 45, 50, 172, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.FAIRY, 1.5, 20.6, AbilityId.PIXILATE, AbilityId.NONE, AbilityId.PIXILATE, 590, 75, 110, 110, 110, 105, 80, 45, 50, 172), - ), - new PokemonSpecies(SpeciesId.ZANGOOSE, 3, false, false, false, "Cat Ferret Pokémon", PokemonType.NORMAL, null, 1.3, 40.3, AbilityId.IMMUNITY, AbilityId.NONE, AbilityId.TOXIC_BOOST, 458, 73, 115, 60, 60, 60, 90, 90, 70, 160, GrowthRate.ERRATIC, 50, false), - new PokemonSpecies(SpeciesId.SEVIPER, 3, false, false, false, "Fang Snake Pokémon", PokemonType.POISON, null, 2.7, 52.5, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.INFILTRATOR, 458, 73, 100, 60, 100, 60, 65, 90, 70, 160, GrowthRate.FLUCTUATING, 50, false), - new PokemonSpecies(SpeciesId.LUNATONE, 3, false, false, false, "Meteorite Pokémon", PokemonType.ROCK, PokemonType.PSYCHIC, 1, 168, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 460, 90, 55, 65, 95, 85, 70, 45, 50, 161, GrowthRate.FAST, null, false), - new PokemonSpecies(SpeciesId.SOLROCK, 3, false, false, false, "Meteorite Pokémon", PokemonType.ROCK, PokemonType.PSYCHIC, 1.2, 154, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 460, 90, 95, 85, 55, 65, 70, 45, 50, 161, GrowthRate.FAST, null, false), - new PokemonSpecies(SpeciesId.BARBOACH, 3, false, false, false, "Whiskers Pokémon", PokemonType.WATER, PokemonType.GROUND, 0.4, 1.9, AbilityId.OBLIVIOUS, AbilityId.ANTICIPATION, AbilityId.HYDRATION, 288, 50, 48, 43, 46, 41, 60, 190, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.WHISCASH, 3, false, false, false, "Whiskers Pokémon", PokemonType.WATER, PokemonType.GROUND, 0.9, 23.6, AbilityId.OBLIVIOUS, AbilityId.ANTICIPATION, AbilityId.HYDRATION, 468, 110, 78, 73, 76, 71, 60, 75, 50, 164, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CORPHISH, 3, false, false, false, "Ruffian Pokémon", PokemonType.WATER, null, 0.6, 11.5, AbilityId.HYPER_CUTTER, AbilityId.SHELL_ARMOR, AbilityId.ADAPTABILITY, 308, 43, 80, 65, 50, 35, 35, 205, 50, 62, GrowthRate.FLUCTUATING, 50, false), - new PokemonSpecies(SpeciesId.CRAWDAUNT, 3, false, false, false, "Rogue Pokémon", PokemonType.WATER, PokemonType.DARK, 1.1, 32.8, AbilityId.HYPER_CUTTER, AbilityId.SHELL_ARMOR, AbilityId.ADAPTABILITY, 468, 63, 120, 85, 90, 55, 55, 155, 50, 164, GrowthRate.FLUCTUATING, 50, false), - new PokemonSpecies(SpeciesId.BALTOY, 3, false, false, false, "Clay Doll Pokémon", PokemonType.GROUND, PokemonType.PSYCHIC, 0.5, 21.5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 300, 40, 40, 55, 40, 70, 55, 255, 50, 60, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.CLAYDOL, 3, false, false, false, "Clay Doll Pokémon", PokemonType.GROUND, PokemonType.PSYCHIC, 1.5, 108, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 500, 60, 70, 105, 70, 120, 75, 90, 50, 175, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.LILEEP, 3, false, false, false, "Sea Lily Pokémon", PokemonType.ROCK, PokemonType.GRASS, 1, 23.8, AbilityId.SUCTION_CUPS, AbilityId.NONE, AbilityId.STORM_DRAIN, 355, 66, 41, 77, 61, 87, 23, 45, 50, 71, GrowthRate.ERRATIC, 87.5, false), - new PokemonSpecies(SpeciesId.CRADILY, 3, false, false, false, "Barnacle Pokémon", PokemonType.ROCK, PokemonType.GRASS, 1.5, 60.4, AbilityId.SUCTION_CUPS, AbilityId.NONE, AbilityId.STORM_DRAIN, 495, 86, 81, 97, 81, 107, 43, 45, 50, 173, GrowthRate.ERRATIC, 87.5, false), - new PokemonSpecies(SpeciesId.ANORITH, 3, false, false, false, "Old Shrimp Pokémon", PokemonType.ROCK, PokemonType.BUG, 0.7, 12.5, AbilityId.BATTLE_ARMOR, AbilityId.NONE, AbilityId.SWIFT_SWIM, 355, 45, 95, 50, 40, 50, 75, 45, 50, 71, GrowthRate.ERRATIC, 87.5, false), - new PokemonSpecies(SpeciesId.ARMALDO, 3, false, false, false, "Plate Pokémon", PokemonType.ROCK, PokemonType.BUG, 1.5, 68.2, AbilityId.BATTLE_ARMOR, AbilityId.NONE, AbilityId.SWIFT_SWIM, 495, 75, 125, 100, 70, 80, 45, 45, 50, 173, GrowthRate.ERRATIC, 87.5, false), - new PokemonSpecies(SpeciesId.FEEBAS, 3, false, false, false, "Fish Pokémon", PokemonType.WATER, null, 0.6, 7.4, AbilityId.SWIFT_SWIM, AbilityId.OBLIVIOUS, AbilityId.ADAPTABILITY, 200, 20, 15, 20, 10, 55, 80, 255, 50, 40, GrowthRate.ERRATIC, 50, false), - new PokemonSpecies(SpeciesId.MILOTIC, 3, false, false, false, "Tender Pokémon", PokemonType.WATER, null, 6.2, 162, AbilityId.MARVEL_SCALE, AbilityId.COMPETITIVE, AbilityId.CUTE_CHARM, 540, 95, 60, 79, 100, 125, 81, 60, 50, 189, GrowthRate.ERRATIC, 50, true), - new PokemonSpecies(SpeciesId.CASTFORM, 3, false, false, false, "Weather Pokémon", PokemonType.NORMAL, null, 0.3, 0.8, AbilityId.FORECAST, AbilityId.NONE, AbilityId.NONE, 420, 70, 70, 70, 70, 70, 70, 45, 70, 147, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal Form", "", PokemonType.NORMAL, null, 0.3, 0.8, AbilityId.FORECAST, AbilityId.NONE, AbilityId.NONE, 420, 70, 70, 70, 70, 70, 70, 45, 70, 147, false, null, true), - new PokemonForm("Sunny Form", "sunny", PokemonType.FIRE, null, 0.3, 0.8, AbilityId.FORECAST, AbilityId.NONE, AbilityId.NONE, 420, 70, 70, 70, 70, 70, 70, 45, 70, 147), - new PokemonForm("Rainy Form", "rainy", PokemonType.WATER, null, 0.3, 0.8, AbilityId.FORECAST, AbilityId.NONE, AbilityId.NONE, 420, 70, 70, 70, 70, 70, 70, 45, 70, 147), - new PokemonForm("Snowy Form", "snowy", PokemonType.ICE, null, 0.3, 0.8, AbilityId.FORECAST, AbilityId.NONE, AbilityId.NONE, 420, 70, 70, 70, 70, 70, 70, 45, 70, 147), - ), - new PokemonSpecies(SpeciesId.KECLEON, 3, false, false, false, "Color Swap Pokémon", PokemonType.NORMAL, null, 1, 22, AbilityId.COLOR_CHANGE, AbilityId.NONE, AbilityId.PROTEAN, 440, 60, 90, 70, 60, 120, 40, 200, 70, 154, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SHUPPET, 3, false, false, false, "Puppet Pokémon", PokemonType.GHOST, null, 0.6, 2.3, AbilityId.INSOMNIA, AbilityId.FRISK, AbilityId.CURSED_BODY, 295, 44, 75, 35, 63, 33, 45, 225, 35, 59, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.BANETTE, 3, false, false, false, "Marionette Pokémon", PokemonType.GHOST, null, 1.1, 12.5, AbilityId.INSOMNIA, AbilityId.FRISK, AbilityId.CURSED_BODY, 455, 64, 115, 65, 83, 63, 65, 45, 35, 159, GrowthRate.FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.GHOST, null, 1.1, 12.5, AbilityId.INSOMNIA, AbilityId.FRISK, AbilityId.CURSED_BODY, 455, 64, 115, 65, 83, 63, 65, 45, 35, 159, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.GHOST, null, 1.2, 13, AbilityId.PRANKSTER, AbilityId.PRANKSTER, AbilityId.PRANKSTER, 555, 64, 165, 75, 93, 83, 75, 45, 35, 159), - ), - new PokemonSpecies(SpeciesId.DUSKULL, 3, false, false, false, "Requiem Pokémon", PokemonType.GHOST, null, 0.8, 15, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.FRISK, 295, 20, 40, 90, 30, 90, 25, 190, 35, 59, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.DUSCLOPS, 3, false, false, false, "Beckon Pokémon", PokemonType.GHOST, null, 1.6, 30.6, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.FRISK, 455, 40, 70, 130, 60, 130, 25, 90, 35, 159, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.TROPIUS, 3, false, false, false, "Fruit Pokémon", PokemonType.GRASS, PokemonType.FLYING, 2, 100, AbilityId.CHLOROPHYLL, AbilityId.SOLAR_POWER, AbilityId.HARVEST, 460, 99, 68, 83, 72, 87, 51, 200, 70, 161, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.CHIMECHO, 3, false, false, false, "Wind Chime Pokémon", PokemonType.PSYCHIC, null, 0.6, 1, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 455, 75, 50, 80, 95, 90, 65, 45, 70, 159, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.ABSOL, 3, false, false, false, "Disaster Pokémon", PokemonType.DARK, null, 1.2, 47, AbilityId.PRESSURE, AbilityId.SUPER_LUCK, AbilityId.JUSTIFIED, 465, 65, 130, 60, 75, 60, 75, 30, 35, 163, GrowthRate.MEDIUM_SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.DARK, null, 1.2, 47, AbilityId.PRESSURE, AbilityId.SUPER_LUCK, AbilityId.JUSTIFIED, 465, 65, 130, 60, 75, 60, 75, 30, 35, 163, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DARK, null, 1.2, 49, AbilityId.MAGIC_BOUNCE, AbilityId.MAGIC_BOUNCE, AbilityId.MAGIC_BOUNCE, 565, 65, 150, 60, 115, 60, 115, 30, 35, 163), - ), - new PokemonSpecies(SpeciesId.WYNAUT, 3, false, false, false, "Bright Pokémon", PokemonType.PSYCHIC, null, 0.6, 14, AbilityId.SHADOW_TAG, AbilityId.NONE, AbilityId.TELEPATHY, 260, 95, 23, 48, 23, 48, 23, 125, 50, 52, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SNORUNT, 3, false, false, false, "Snow Hat Pokémon", PokemonType.ICE, null, 0.7, 16.8, AbilityId.INNER_FOCUS, AbilityId.ICE_BODY, AbilityId.MOODY, 300, 50, 50, 50, 50, 50, 50, 190, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GLALIE, 3, false, false, false, "Face Pokémon", PokemonType.ICE, null, 1.5, 256.5, AbilityId.INNER_FOCUS, AbilityId.ICE_BODY, AbilityId.MOODY, 480, 80, 80, 80, 80, 80, 80, 75, 50, 168, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.ICE, null, 1.5, 256.5, AbilityId.INNER_FOCUS, AbilityId.ICE_BODY, AbilityId.MOODY, 480, 80, 80, 80, 80, 80, 80, 75, 50, 168, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.ICE, null, 2.1, 350.2, AbilityId.REFRIGERATE, AbilityId.REFRIGERATE, AbilityId.REFRIGERATE, 580, 80, 120, 80, 120, 80, 100, 75, 50, 168), - ), - new PokemonSpecies(SpeciesId.SPHEAL, 3, false, false, false, "Clap Pokémon", PokemonType.ICE, PokemonType.WATER, 0.8, 39.5, AbilityId.THICK_FAT, AbilityId.ICE_BODY, AbilityId.OBLIVIOUS, 290, 70, 40, 50, 55, 50, 25, 255, 50, 58, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SEALEO, 3, false, false, false, "Ball Roll Pokémon", PokemonType.ICE, PokemonType.WATER, 1.1, 87.6, AbilityId.THICK_FAT, AbilityId.ICE_BODY, AbilityId.OBLIVIOUS, 410, 90, 60, 70, 75, 70, 45, 120, 50, 144, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.WALREIN, 3, false, false, false, "Ice Break Pokémon", PokemonType.ICE, PokemonType.WATER, 1.4, 150.6, AbilityId.THICK_FAT, AbilityId.ICE_BODY, AbilityId.OBLIVIOUS, 530, 110, 80, 90, 95, 90, 65, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.CLAMPERL, 3, false, false, false, "Bivalve Pokémon", PokemonType.WATER, null, 0.4, 52.5, AbilityId.SHELL_ARMOR, AbilityId.NONE, AbilityId.RATTLED, 345, 35, 64, 85, 74, 55, 32, 255, 70, 69, GrowthRate.ERRATIC, 50, false), - new PokemonSpecies(SpeciesId.HUNTAIL, 3, false, false, false, "Deep Sea Pokémon", PokemonType.WATER, null, 1.7, 27, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.WATER_VEIL, 485, 55, 104, 105, 94, 75, 52, 60, 70, 170, GrowthRate.ERRATIC, 50, false), - new PokemonSpecies(SpeciesId.GOREBYSS, 3, false, false, false, "South Sea Pokémon", PokemonType.WATER, null, 1.8, 22.6, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.HYDRATION, 485, 55, 84, 105, 114, 75, 52, 60, 70, 170, GrowthRate.ERRATIC, 50, false), - new PokemonSpecies(SpeciesId.RELICANTH, 3, false, false, false, "Longevity Pokémon", PokemonType.WATER, PokemonType.ROCK, 1, 23.4, AbilityId.SWIFT_SWIM, AbilityId.ROCK_HEAD, AbilityId.STURDY, 485, 100, 90, 130, 45, 65, 55, 25, 50, 170, GrowthRate.SLOW, 87.5, true), - new PokemonSpecies(SpeciesId.LUVDISC, 3, false, false, false, "Rendezvous Pokémon", PokemonType.WATER, null, 0.6, 8.7, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.HYDRATION, 330, 43, 30, 55, 40, 65, 97, 225, 70, 116, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.BAGON, 3, false, false, false, "Rock Head Pokémon", PokemonType.DRAGON, null, 0.6, 42.1, AbilityId.ROCK_HEAD, AbilityId.NONE, AbilityId.SHEER_FORCE, 300, 45, 75, 60, 40, 30, 50, 45, 35, 60, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.SHELGON, 3, false, false, false, "Endurance Pokémon", PokemonType.DRAGON, null, 1.1, 110.5, AbilityId.ROCK_HEAD, AbilityId.NONE, AbilityId.OVERCOAT, 420, 65, 95, 100, 60, 50, 50, 45, 35, 147, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.SALAMENCE, 3, false, false, false, "Dragon Pokémon", PokemonType.DRAGON, PokemonType.FLYING, 1.5, 102.6, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.MOXIE, 600, 95, 135, 80, 110, 80, 100, 45, 35, 300, GrowthRate.SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.FLYING, 1.5, 102.6, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.MOXIE, 600, 95, 135, 80, 110, 80, 100, 45, 35, 300, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.FLYING, 1.8, 112.6, AbilityId.AERILATE, AbilityId.NONE, AbilityId.AERILATE, 700, 95, 145, 130, 120, 90, 120, 45, 35, 300), - ), - new PokemonSpecies(SpeciesId.BELDUM, 3, false, false, false, "Iron Ball Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 0.6, 95.2, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.LIGHT_METAL, 300, 40, 55, 80, 35, 60, 30, 45, 35, 60, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Frigibax - new PokemonSpecies(SpeciesId.METANG, 3, false, false, false, "Iron Claw Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 1.2, 202.5, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.LIGHT_METAL, 420, 60, 75, 100, 55, 80, 50, 25, 35, 147, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Arctibax - new PokemonSpecies(SpeciesId.METAGROSS, 3, false, false, false, "Iron Leg Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 1.6, 550, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.LIGHT_METAL, 600, 80, 135, 130, 95, 90, 70, 10, 35, 300, GrowthRate.SLOW, null, false, true, //Custom Catchrate, matching Baxcalibur - new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.PSYCHIC, 1.6, 550, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.LIGHT_METAL, 600, 80, 135, 130, 95, 90, 70, 3, 35, 300, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.STEEL, PokemonType.PSYCHIC, 2.5, 942.9, AbilityId.TOUGH_CLAWS, AbilityId.NONE, AbilityId.TOUGH_CLAWS, 700, 80, 145, 150, 105, 110, 110, 3, 35, 300), - ), - new PokemonSpecies(SpeciesId.REGIROCK, 3, true, false, false, "Rock Peak Pokémon", PokemonType.ROCK, null, 1.7, 230, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.STURDY, 580, 80, 100, 200, 50, 100, 50, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.REGICE, 3, true, false, false, "Iceberg Pokémon", PokemonType.ICE, null, 1.8, 175, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.ICE_BODY, 580, 80, 50, 100, 100, 200, 50, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.REGISTEEL, 3, true, false, false, "Iron Pokémon", PokemonType.STEEL, null, 1.9, 205, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.LIGHT_METAL, 580, 80, 75, 150, 75, 150, 50, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.LATIAS, 3, true, false, false, "Eon Pokémon", PokemonType.DRAGON, PokemonType.PSYCHIC, 1.4, 40, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 600, 80, 80, 90, 110, 130, 110, 3, 90, 300, GrowthRate.SLOW, 0, false, true, - new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.PSYCHIC, 1.4, 40, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 600, 80, 80, 90, 110, 130, 110, 3, 90, 300, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.PSYCHIC, 1.8, 52, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 700, 80, 100, 120, 140, 150, 110, 3, 90, 300), - ), - new PokemonSpecies(SpeciesId.LATIOS, 3, true, false, false, "Eon Pokémon", PokemonType.DRAGON, PokemonType.PSYCHIC, 2, 60, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 600, 80, 90, 80, 130, 110, 110, 3, 90, 300, GrowthRate.SLOW, 100, false, true, - new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.PSYCHIC, 2, 60, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 600, 80, 90, 80, 130, 110, 110, 3, 90, 300, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.PSYCHIC, 2.3, 70, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 700, 80, 130, 100, 160, 120, 110, 3, 90, 300), - ), - new PokemonSpecies(SpeciesId.KYOGRE, 3, false, true, false, "Sea Basin Pokémon", PokemonType.WATER, null, 4.5, 352, AbilityId.DRIZZLE, AbilityId.NONE, AbilityId.NONE, 670, 100, 100, 90, 150, 140, 90, 3, 0, 335, GrowthRate.SLOW, null, false, true, - new PokemonForm("Normal", "", PokemonType.WATER, null, 4.5, 352, AbilityId.DRIZZLE, AbilityId.NONE, AbilityId.NONE, 670, 100, 100, 90, 150, 140, 90, 3, 0, 335, false, null, true), - new PokemonForm("Primal", "primal", PokemonType.WATER, null, 9.8, 430, AbilityId.PRIMORDIAL_SEA, AbilityId.NONE, AbilityId.NONE, 770, 100, 150, 90, 180, 160, 90, 3, 0, 335), - ), - new PokemonSpecies(SpeciesId.GROUDON, 3, false, true, false, "Continent Pokémon", PokemonType.GROUND, null, 3.5, 950, AbilityId.DROUGHT, AbilityId.NONE, AbilityId.NONE, 670, 100, 150, 140, 100, 90, 90, 3, 0, 335, GrowthRate.SLOW, null, false, true, - new PokemonForm("Normal", "", PokemonType.GROUND, null, 3.5, 950, AbilityId.DROUGHT, AbilityId.NONE, AbilityId.NONE, 670, 100, 150, 140, 100, 90, 90, 3, 0, 335, false, null, true), - new PokemonForm("Primal", "primal", PokemonType.GROUND, PokemonType.FIRE, 5, 999.7, AbilityId.DESOLATE_LAND, AbilityId.NONE, AbilityId.NONE, 770, 100, 180, 160, 150, 90, 90, 3, 0, 335), - ), - new PokemonSpecies(SpeciesId.RAYQUAZA, 3, false, true, false, "Sky High Pokémon", PokemonType.DRAGON, PokemonType.FLYING, 7, 206.5, AbilityId.AIR_LOCK, AbilityId.NONE, AbilityId.NONE, 680, 105, 150, 90, 150, 90, 95, 3, 0, 340, GrowthRate.SLOW, null, false, true, - new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.FLYING, 7, 206.5, AbilityId.AIR_LOCK, AbilityId.NONE, AbilityId.NONE, 680, 105, 150, 90, 150, 90, 95, 3, 0, 340, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.FLYING, 10.8, 392, AbilityId.DELTA_STREAM, AbilityId.NONE, AbilityId.NONE, 780, 105, 180, 100, 180, 100, 115, 3, 0, 340), - ), - new PokemonSpecies(SpeciesId.JIRACHI, 3, false, false, true, "Wish Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 0.3, 1.1, AbilityId.SERENE_GRACE, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 3, 100, 300, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.DEOXYS, 3, false, false, true, "DNA Pokémon", PokemonType.PSYCHIC, null, 1.7, 60.8, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 600, 50, 150, 50, 150, 50, 150, 3, 0, 300, GrowthRate.SLOW, null, false, true, - new PokemonForm("Normal Forme", "normal", PokemonType.PSYCHIC, null, 1.7, 60.8, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 600, 50, 150, 50, 150, 50, 150, 3, 0, 300, false, "", true), - new PokemonForm("Attack Forme", "attack", PokemonType.PSYCHIC, null, 1.7, 60.8, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 600, 50, 180, 20, 180, 20, 150, 3, 0, 300), - new PokemonForm("Defense Forme", "defense", PokemonType.PSYCHIC, null, 1.7, 60.8, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 600, 50, 70, 160, 70, 160, 90, 3, 0, 300), - new PokemonForm("Speed Forme", "speed", PokemonType.PSYCHIC, null, 1.7, 60.8, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 600, 50, 95, 90, 95, 90, 180, 3, 0, 300), - ), - new PokemonSpecies(SpeciesId.TURTWIG, 4, false, false, false, "Tiny Leaf Pokémon", PokemonType.GRASS, null, 0.4, 10.2, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.SHELL_ARMOR, 318, 55, 68, 64, 45, 55, 31, 45, 70, 64, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.GROTLE, 4, false, false, false, "Grove Pokémon", PokemonType.GRASS, null, 1.1, 97, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.SHELL_ARMOR, 405, 75, 89, 85, 55, 65, 36, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.TORTERRA, 4, false, false, false, "Continent Pokémon", PokemonType.GRASS, PokemonType.GROUND, 2.2, 310, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.SHELL_ARMOR, 525, 95, 109, 105, 75, 85, 56, 45, 70, 263, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.CHIMCHAR, 4, false, false, false, "Chimp Pokémon", PokemonType.FIRE, null, 0.5, 6.2, AbilityId.BLAZE, AbilityId.NONE, AbilityId.IRON_FIST, 309, 44, 58, 44, 58, 44, 61, 45, 70, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.MONFERNO, 4, false, false, false, "Playful Pokémon", PokemonType.FIRE, PokemonType.FIGHTING, 0.9, 22, AbilityId.BLAZE, AbilityId.NONE, AbilityId.IRON_FIST, 405, 64, 78, 52, 78, 52, 81, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.INFERNAPE, 4, false, false, false, "Flame Pokémon", PokemonType.FIRE, PokemonType.FIGHTING, 1.2, 55, AbilityId.BLAZE, AbilityId.NONE, AbilityId.IRON_FIST, 534, 76, 104, 71, 104, 71, 108, 45, 70, 267, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.PIPLUP, 4, false, false, false, "Penguin Pokémon", PokemonType.WATER, null, 0.4, 5.2, AbilityId.TORRENT, AbilityId.NONE, AbilityId.COMPETITIVE, 314, 53, 51, 53, 61, 56, 40, 45, 70, 63, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.PRINPLUP, 4, false, false, false, "Penguin Pokémon", PokemonType.WATER, null, 0.8, 23, AbilityId.TORRENT, AbilityId.NONE, AbilityId.COMPETITIVE, 405, 64, 66, 68, 81, 76, 50, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.EMPOLEON, 4, false, false, false, "Emperor Pokémon", PokemonType.WATER, PokemonType.STEEL, 1.7, 84.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.COMPETITIVE, 530, 84, 86, 88, 111, 101, 60, 45, 70, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.STARLY, 4, false, false, false, "Starling Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 2, AbilityId.KEEN_EYE, AbilityId.NONE, AbilityId.RECKLESS, 245, 40, 55, 30, 30, 30, 60, 255, 70, 49, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.STARAVIA, 4, false, false, false, "Starling Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 15.5, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.RECKLESS, 340, 55, 75, 50, 40, 40, 80, 120, 70, 119, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.STARAPTOR, 4, false, false, false, "Predator Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.2, 24.9, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.RECKLESS, 485, 85, 120, 70, 50, 60, 100, 45, 70, 243, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.BIDOOF, 4, false, false, false, "Plump Mouse Pokémon", PokemonType.NORMAL, null, 0.5, 20, AbilityId.SIMPLE, AbilityId.UNAWARE, AbilityId.MOODY, 250, 59, 45, 40, 35, 40, 31, 255, 70, 50, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.BIBAREL, 4, false, false, false, "Beaver Pokémon", PokemonType.NORMAL, PokemonType.WATER, 1, 31.5, AbilityId.SIMPLE, AbilityId.UNAWARE, AbilityId.MOODY, 410, 79, 85, 60, 55, 60, 71, 127, 70, 144, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.KRICKETOT, 4, false, false, false, "Cricket Pokémon", PokemonType.BUG, null, 0.3, 2.2, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.RUN_AWAY, 194, 37, 25, 41, 25, 41, 25, 255, 70, 39, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.KRICKETUNE, 4, false, false, false, "Cricket Pokémon", PokemonType.BUG, null, 1, 25.5, AbilityId.SWARM, AbilityId.NONE, AbilityId.TECHNICIAN, 384, 77, 85, 51, 55, 51, 65, 45, 70, 134, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.SHINX, 4, false, false, false, "Flash Pokémon", PokemonType.ELECTRIC, null, 0.5, 9.5, AbilityId.RIVALRY, AbilityId.INTIMIDATE, AbilityId.GUTS, 263, 45, 65, 34, 40, 34, 45, 235, 50, 53, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.LUXIO, 4, false, false, false, "Spark Pokémon", PokemonType.ELECTRIC, null, 0.9, 30.5, AbilityId.RIVALRY, AbilityId.INTIMIDATE, AbilityId.GUTS, 363, 60, 85, 49, 60, 49, 60, 120, 100, 127, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.LUXRAY, 4, false, false, false, "Gleam Eyes Pokémon", PokemonType.ELECTRIC, null, 1.4, 42, AbilityId.RIVALRY, AbilityId.INTIMIDATE, AbilityId.GUTS, 523, 80, 120, 79, 95, 79, 70, 45, 50, 262, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.BUDEW, 4, false, false, false, "Bud Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.2, 1.2, AbilityId.NATURAL_CURE, AbilityId.POISON_POINT, AbilityId.LEAF_GUARD, 280, 40, 30, 35, 50, 70, 55, 255, 50, 56, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.ROSERADE, 4, false, false, false, "Bouquet Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.9, 14.5, AbilityId.NATURAL_CURE, AbilityId.POISON_POINT, AbilityId.TECHNICIAN, 515, 60, 70, 65, 125, 105, 90, 75, 50, 258, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.CRANIDOS, 4, false, false, false, "Head Butt Pokémon", PokemonType.ROCK, null, 0.9, 31.5, AbilityId.MOLD_BREAKER, AbilityId.NONE, AbilityId.SHEER_FORCE, 350, 67, 125, 40, 30, 30, 58, 45, 70, 70, GrowthRate.ERRATIC, 87.5, false), - new PokemonSpecies(SpeciesId.RAMPARDOS, 4, false, false, false, "Head Butt Pokémon", PokemonType.ROCK, null, 1.6, 102.5, AbilityId.MOLD_BREAKER, AbilityId.NONE, AbilityId.SHEER_FORCE, 495, 97, 165, 60, 65, 50, 58, 45, 70, 173, GrowthRate.ERRATIC, 87.5, false), - new PokemonSpecies(SpeciesId.SHIELDON, 4, false, false, false, "Shield Pokémon", PokemonType.ROCK, PokemonType.STEEL, 0.5, 57, AbilityId.STURDY, AbilityId.NONE, AbilityId.SOUNDPROOF, 350, 30, 42, 118, 42, 88, 30, 45, 70, 70, GrowthRate.ERRATIC, 87.5, false), - new PokemonSpecies(SpeciesId.BASTIODON, 4, false, false, false, "Shield Pokémon", PokemonType.ROCK, PokemonType.STEEL, 1.3, 149.5, AbilityId.STURDY, AbilityId.NONE, AbilityId.SOUNDPROOF, 495, 60, 52, 168, 47, 138, 30, 45, 70, 173, GrowthRate.ERRATIC, 87.5, false), - new PokemonSpecies(SpeciesId.BURMY, 4, false, false, false, "Bagworm Pokémon", PokemonType.BUG, null, 0.2, 3.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.OVERCOAT, 224, 40, 29, 45, 29, 45, 36, 120, 70, 45, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Plant Cloak", "plant", PokemonType.BUG, null, 0.2, 3.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.OVERCOAT, 224, 40, 29, 45, 29, 45, 36, 120, 70, 45, false, null, true), - new PokemonForm("Sandy Cloak", "sandy", PokemonType.BUG, null, 0.2, 3.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.OVERCOAT, 224, 40, 29, 45, 29, 45, 36, 120, 70, 45, false, null, true), - new PokemonForm("Trash Cloak", "trash", PokemonType.BUG, null, 0.2, 3.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.OVERCOAT, 224, 40, 29, 45, 29, 45, 36, 120, 70, 45, false, null, true), - ), - new PokemonSpecies(SpeciesId.WORMADAM, 4, false, false, false, "Bagworm Pokémon", PokemonType.BUG, PokemonType.GRASS, 0.5, 6.5, AbilityId.ANTICIPATION, AbilityId.NONE, AbilityId.OVERCOAT, 424, 60, 59, 85, 79, 105, 36, 45, 70, 148, GrowthRate.MEDIUM_FAST, 0, false, false, - new PokemonForm("Plant Cloak", "plant", PokemonType.BUG, PokemonType.GRASS, 0.5, 6.5, AbilityId.ANTICIPATION, AbilityId.NONE, AbilityId.OVERCOAT, 424, 60, 59, 85, 79, 105, 36, 45, 70, 148, false, null, true), - new PokemonForm("Sandy Cloak", "sandy", PokemonType.BUG, PokemonType.GROUND, 0.5, 6.5, AbilityId.ANTICIPATION, AbilityId.NONE, AbilityId.OVERCOAT, 424, 60, 79, 105, 59, 85, 36, 45, 70, 148, false, null, true), - new PokemonForm("Trash Cloak", "trash", PokemonType.BUG, PokemonType.STEEL, 0.5, 6.5, AbilityId.ANTICIPATION, AbilityId.NONE, AbilityId.OVERCOAT, 424, 60, 69, 95, 69, 95, 36, 45, 70, 148, false, null, true), - ), - new PokemonSpecies(SpeciesId.MOTHIM, 4, false, false, false, "Moth Pokémon", PokemonType.BUG, PokemonType.FLYING, 0.9, 23.3, AbilityId.SWARM, AbilityId.NONE, AbilityId.TINTED_LENS, 424, 70, 94, 50, 94, 50, 66, 45, 70, 148, GrowthRate.MEDIUM_FAST, 100, false), - new PokemonSpecies(SpeciesId.COMBEE, 4, false, false, false, "Tiny Bee Pokémon", PokemonType.BUG, PokemonType.FLYING, 0.3, 5.5, AbilityId.HONEY_GATHER, AbilityId.NONE, AbilityId.HUSTLE, 244, 30, 30, 42, 30, 42, 70, 120, 50, 49, GrowthRate.MEDIUM_SLOW, 87.5, true), - new PokemonSpecies(SpeciesId.VESPIQUEN, 4, false, false, false, "Beehive Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.2, 38.5, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.UNNERVE, 474, 70, 80, 102, 80, 102, 40, 45, 50, 166, GrowthRate.MEDIUM_SLOW, 0, false), - new PokemonSpecies(SpeciesId.PACHIRISU, 4, false, false, false, "EleSquirrel Pokémon", PokemonType.ELECTRIC, null, 0.4, 3.9, AbilityId.RUN_AWAY, AbilityId.PICKUP, AbilityId.VOLT_ABSORB, 405, 60, 45, 70, 45, 90, 95, 200, 100, 142, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.BUIZEL, 4, false, false, false, "Sea Weasel Pokémon", PokemonType.WATER, null, 0.7, 29.5, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.WATER_VEIL, 330, 55, 65, 35, 60, 30, 85, 190, 70, 66, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.FLOATZEL, 4, false, false, false, "Sea Weasel Pokémon", PokemonType.WATER, null, 1.1, 33.5, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.WATER_VEIL, 495, 85, 105, 55, 85, 50, 115, 75, 70, 173, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.CHERUBI, 4, false, false, false, "Cherry Pokémon", PokemonType.GRASS, null, 0.4, 3.3, AbilityId.CHLOROPHYLL, AbilityId.NONE, AbilityId.NONE, 275, 45, 35, 45, 62, 53, 35, 190, 50, 55, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CHERRIM, 4, false, false, false, "Blossom Pokémon", PokemonType.GRASS, null, 0.5, 9.3, AbilityId.FLOWER_GIFT, AbilityId.NONE, AbilityId.NONE, 450, 70, 60, 70, 87, 78, 85, 75, 50, 158, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Overcast Form", "overcast", PokemonType.GRASS, null, 0.5, 9.3, AbilityId.FLOWER_GIFT, AbilityId.NONE, AbilityId.NONE, 450, 70, 60, 70, 87, 78, 85, 75, 50, 158, false, null, true), - new PokemonForm("Sunshine Form", "sunshine", PokemonType.GRASS, null, 0.5, 9.3, AbilityId.FLOWER_GIFT, AbilityId.NONE, AbilityId.NONE, 450, 70, 60, 70, 87, 78, 85, 75, 50, 158), - ), - new PokemonSpecies(SpeciesId.SHELLOS, 4, false, false, false, "Sea Slug Pokémon", PokemonType.WATER, null, 0.3, 6.3, AbilityId.STICKY_HOLD, AbilityId.STORM_DRAIN, AbilityId.SAND_FORCE, 325, 76, 48, 48, 57, 62, 34, 190, 50, 65, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("East Sea", "east", PokemonType.WATER, null, 0.3, 6.3, AbilityId.STICKY_HOLD, AbilityId.STORM_DRAIN, AbilityId.SAND_FORCE, 325, 76, 48, 48, 57, 62, 34, 190, 50, 65, false, null, true), - new PokemonForm("West Sea", "west", PokemonType.WATER, null, 0.3, 6.3, AbilityId.STICKY_HOLD, AbilityId.STORM_DRAIN, AbilityId.SAND_FORCE, 325, 76, 48, 48, 57, 62, 34, 190, 50, 65, false, null, true), - ), - new PokemonSpecies(SpeciesId.GASTRODON, 4, false, false, false, "Sea Slug Pokémon", PokemonType.WATER, PokemonType.GROUND, 0.9, 29.9, AbilityId.STICKY_HOLD, AbilityId.STORM_DRAIN, AbilityId.SAND_FORCE, 475, 111, 83, 68, 92, 82, 39, 75, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("East Sea", "east", PokemonType.WATER, PokemonType.GROUND, 0.9, 29.9, AbilityId.STICKY_HOLD, AbilityId.STORM_DRAIN, AbilityId.SAND_FORCE, 475, 111, 83, 68, 92, 82, 39, 75, 50, 166, false, null, true), - new PokemonForm("West Sea", "west", PokemonType.WATER, PokemonType.GROUND, 0.9, 29.9, AbilityId.STICKY_HOLD, AbilityId.STORM_DRAIN, AbilityId.SAND_FORCE, 475, 111, 83, 68, 92, 82, 39, 75, 50, 166, false, null, true), - ), - new PokemonSpecies(SpeciesId.AMBIPOM, 4, false, false, false, "Long Tail Pokémon", PokemonType.NORMAL, null, 1.2, 20.3, AbilityId.TECHNICIAN, AbilityId.PICKUP, AbilityId.SKILL_LINK, 482, 75, 100, 66, 60, 66, 115, 45, 100, 169, GrowthRate.FAST, 50, true), - new PokemonSpecies(SpeciesId.DRIFLOON, 4, false, false, false, "Balloon Pokémon", PokemonType.GHOST, PokemonType.FLYING, 0.4, 1.2, AbilityId.AFTERMATH, AbilityId.UNBURDEN, AbilityId.FLARE_BOOST, 348, 90, 50, 34, 60, 44, 70, 125, 50, 70, GrowthRate.FLUCTUATING, 50, false), - new PokemonSpecies(SpeciesId.DRIFBLIM, 4, false, false, false, "Blimp Pokémon", PokemonType.GHOST, PokemonType.FLYING, 1.2, 15, AbilityId.AFTERMATH, AbilityId.UNBURDEN, AbilityId.FLARE_BOOST, 498, 150, 80, 44, 90, 54, 80, 60, 50, 174, GrowthRate.FLUCTUATING, 50, false), - new PokemonSpecies(SpeciesId.BUNEARY, 4, false, false, false, "Rabbit Pokémon", PokemonType.NORMAL, null, 0.4, 5.5, AbilityId.RUN_AWAY, AbilityId.KLUTZ, AbilityId.LIMBER, 350, 55, 66, 44, 44, 56, 85, 190, 0, 70, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.LOPUNNY, 4, false, false, false, "Rabbit Pokémon", PokemonType.NORMAL, null, 1.2, 33.3, AbilityId.CUTE_CHARM, AbilityId.KLUTZ, AbilityId.LIMBER, 480, 65, 76, 84, 54, 96, 105, 60, 140, 168, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.NORMAL, null, 1.2, 33.3, AbilityId.CUTE_CHARM, AbilityId.KLUTZ, AbilityId.LIMBER, 480, 65, 76, 84, 54, 96, 105, 60, 140, 168, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.NORMAL, PokemonType.FIGHTING, 1.3, 28.3, AbilityId.SCRAPPY, AbilityId.SCRAPPY, AbilityId.SCRAPPY, 580, 65, 136, 94, 54, 96, 135, 60, 140, 168), - ), - new PokemonSpecies(SpeciesId.MISMAGIUS, 4, false, false, false, "Magical Pokémon", PokemonType.GHOST, null, 0.9, 4.4, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 495, 60, 60, 60, 105, 105, 105, 45, 35, 173, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.HONCHKROW, 4, false, false, false, "Big Boss Pokémon", PokemonType.DARK, PokemonType.FLYING, 0.9, 27.3, AbilityId.INSOMNIA, AbilityId.SUPER_LUCK, AbilityId.MOXIE, 505, 100, 125, 52, 105, 52, 71, 30, 35, 177, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.GLAMEOW, 4, false, false, false, "Catty Pokémon", PokemonType.NORMAL, null, 0.5, 3.9, AbilityId.LIMBER, AbilityId.OWN_TEMPO, AbilityId.KEEN_EYE, 310, 49, 55, 42, 42, 37, 85, 190, 70, 62, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.PURUGLY, 4, false, false, false, "Tiger Cat Pokémon", PokemonType.NORMAL, null, 1, 43.8, AbilityId.THICK_FAT, AbilityId.OWN_TEMPO, AbilityId.DEFIANT, 452, 71, 82, 64, 64, 59, 112, 75, 70, 158, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.CHINGLING, 4, false, false, false, "Bell Pokémon", PokemonType.PSYCHIC, null, 0.2, 0.6, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 285, 45, 30, 50, 65, 50, 45, 120, 70, 57, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.STUNKY, 4, false, false, false, "Skunk Pokémon", PokemonType.POISON, PokemonType.DARK, 0.4, 19.2, AbilityId.STENCH, AbilityId.AFTERMATH, AbilityId.KEEN_EYE, 329, 63, 63, 47, 41, 41, 74, 225, 50, 66, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SKUNTANK, 4, false, false, false, "Skunk Pokémon", PokemonType.POISON, PokemonType.DARK, 1, 38, AbilityId.STENCH, AbilityId.AFTERMATH, AbilityId.KEEN_EYE, 479, 103, 93, 67, 71, 61, 84, 60, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BRONZOR, 4, false, false, false, "Bronze Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 0.5, 60.5, AbilityId.LEVITATE, AbilityId.HEATPROOF, AbilityId.HEAVY_METAL, 300, 57, 24, 86, 24, 86, 23, 255, 50, 60, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.BRONZONG, 4, false, false, false, "Bronze Bell Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 1.3, 187, AbilityId.LEVITATE, AbilityId.HEATPROOF, AbilityId.HEAVY_METAL, 500, 67, 89, 116, 79, 116, 33, 90, 50, 175, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.BONSLY, 4, false, false, false, "Bonsai Pokémon", PokemonType.ROCK, null, 0.5, 15, AbilityId.STURDY, AbilityId.ROCK_HEAD, AbilityId.RATTLED, 290, 50, 80, 95, 10, 45, 10, 255, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MIME_JR, 4, false, false, false, "Mime Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 0.6, 13, AbilityId.SOUNDPROOF, AbilityId.FILTER, AbilityId.TECHNICIAN, 310, 20, 25, 45, 70, 90, 60, 145, 50, 62, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.HAPPINY, 4, false, false, false, "Playhouse Pokémon", PokemonType.NORMAL, null, 0.6, 24.4, AbilityId.NATURAL_CURE, AbilityId.SERENE_GRACE, AbilityId.FRIEND_GUARD, 220, 100, 5, 5, 15, 65, 30, 130, 140, 110, GrowthRate.FAST, 0, false), - new PokemonSpecies(SpeciesId.CHATOT, 4, false, false, false, "Music Note Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.5, 1.9, AbilityId.KEEN_EYE, AbilityId.TANGLED_FEET, AbilityId.BIG_PECKS, 411, 76, 65, 45, 92, 42, 91, 30, 35, 144, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SPIRITOMB, 4, false, false, false, "Forbidden Pokémon", PokemonType.GHOST, PokemonType.DARK, 1, 108, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.INFILTRATOR, 485, 50, 92, 108, 92, 108, 35, 100, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GIBLE, 4, false, false, false, "Land Shark Pokémon", PokemonType.DRAGON, PokemonType.GROUND, 0.7, 20.5, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.ROUGH_SKIN, 300, 58, 70, 45, 40, 45, 42, 45, 50, 60, GrowthRate.SLOW, 50, true), - new PokemonSpecies(SpeciesId.GABITE, 4, false, false, false, "Cave Pokémon", PokemonType.DRAGON, PokemonType.GROUND, 1.4, 56, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.ROUGH_SKIN, 410, 68, 90, 65, 50, 55, 82, 45, 50, 144, GrowthRate.SLOW, 50, true), - new PokemonSpecies(SpeciesId.GARCHOMP, 4, false, false, false, "Mach Pokémon", PokemonType.DRAGON, PokemonType.GROUND, 1.9, 95, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.ROUGH_SKIN, 600, 108, 130, 95, 80, 85, 102, 45, 50, 300, GrowthRate.SLOW, 50, true, true, - new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.GROUND, 1.9, 95, AbilityId.SAND_VEIL, AbilityId.NONE, AbilityId.ROUGH_SKIN, 600, 108, 130, 95, 80, 85, 102, 45, 50, 300, true, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.GROUND, 1.9, 95, AbilityId.SAND_FORCE, AbilityId.NONE, AbilityId.SAND_FORCE, 700, 108, 170, 115, 120, 95, 92, 45, 50, 300, true), - ), - new PokemonSpecies(SpeciesId.MUNCHLAX, 4, false, false, false, "Big Eater Pokémon", PokemonType.NORMAL, null, 0.6, 105, AbilityId.PICKUP, AbilityId.THICK_FAT, AbilityId.GLUTTONY, 390, 135, 85, 40, 40, 85, 5, 50, 50, 78, GrowthRate.SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.RIOLU, 4, false, false, false, "Emanation Pokémon", PokemonType.FIGHTING, null, 0.7, 20.2, AbilityId.STEADFAST, AbilityId.INNER_FOCUS, AbilityId.PRANKSTER, 285, 40, 70, 40, 35, 40, 60, 75, 50, 57, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.LUCARIO, 4, false, false, false, "Aura Pokémon", PokemonType.FIGHTING, PokemonType.STEEL, 1.2, 54, AbilityId.STEADFAST, AbilityId.INNER_FOCUS, AbilityId.JUSTIFIED, 525, 70, 110, 70, 115, 70, 90, 45, 50, 184, GrowthRate.MEDIUM_SLOW, 87.5, false, true, - new PokemonForm("Normal", "", PokemonType.FIGHTING, PokemonType.STEEL, 1.2, 54, AbilityId.STEADFAST, AbilityId.INNER_FOCUS, AbilityId.JUSTIFIED, 525, 70, 110, 70, 115, 70, 90, 45, 50, 184, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.FIGHTING, PokemonType.STEEL, 1.3, 57.5, AbilityId.ADAPTABILITY, AbilityId.ADAPTABILITY, AbilityId.ADAPTABILITY, 625, 70, 145, 88, 140, 70, 112, 45, 50, 184), - ), - new PokemonSpecies(SpeciesId.HIPPOPOTAS, 4, false, false, false, "Hippo Pokémon", PokemonType.GROUND, null, 0.8, 49.5, AbilityId.SAND_STREAM, AbilityId.NONE, AbilityId.SAND_FORCE, 330, 68, 72, 78, 38, 42, 32, 140, 50, 66, GrowthRate.SLOW, 50, true), - new PokemonSpecies(SpeciesId.HIPPOWDON, 4, false, false, false, "Heavyweight Pokémon", PokemonType.GROUND, null, 2, 300, AbilityId.SAND_STREAM, AbilityId.NONE, AbilityId.SAND_FORCE, 525, 108, 112, 118, 68, 72, 47, 60, 50, 184, GrowthRate.SLOW, 50, true), - new PokemonSpecies(SpeciesId.SKORUPI, 4, false, false, false, "Scorpion Pokémon", PokemonType.POISON, PokemonType.BUG, 0.8, 12, AbilityId.BATTLE_ARMOR, AbilityId.SNIPER, AbilityId.KEEN_EYE, 330, 40, 50, 90, 30, 55, 65, 120, 50, 66, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.DRAPION, 4, false, false, false, "Ogre Scorpion Pokémon", PokemonType.POISON, PokemonType.DARK, 1.3, 61.5, AbilityId.BATTLE_ARMOR, AbilityId.SNIPER, AbilityId.KEEN_EYE, 500, 70, 90, 110, 60, 75, 95, 45, 50, 175, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.CROAGUNK, 4, false, false, false, "Toxic Mouth Pokémon", PokemonType.POISON, PokemonType.FIGHTING, 0.7, 23, AbilityId.ANTICIPATION, AbilityId.DRY_SKIN, AbilityId.POISON_TOUCH, 300, 48, 61, 40, 61, 40, 50, 140, 100, 60, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.TOXICROAK, 4, false, false, false, "Toxic Mouth Pokémon", PokemonType.POISON, PokemonType.FIGHTING, 1.3, 44.4, AbilityId.ANTICIPATION, AbilityId.DRY_SKIN, AbilityId.POISON_TOUCH, 490, 83, 106, 65, 86, 65, 85, 75, 50, 172, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.CARNIVINE, 4, false, false, false, "Bug Catcher Pokémon", PokemonType.GRASS, null, 1.4, 27, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 454, 74, 100, 72, 90, 72, 46, 200, 70, 159, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.FINNEON, 4, false, false, false, "Wing Fish Pokémon", PokemonType.WATER, null, 0.4, 7, AbilityId.SWIFT_SWIM, AbilityId.STORM_DRAIN, AbilityId.WATER_VEIL, 330, 49, 49, 56, 49, 61, 66, 190, 70, 66, GrowthRate.ERRATIC, 50, true), - new PokemonSpecies(SpeciesId.LUMINEON, 4, false, false, false, "Neon Pokémon", PokemonType.WATER, null, 1.2, 24, AbilityId.SWIFT_SWIM, AbilityId.STORM_DRAIN, AbilityId.WATER_VEIL, 460, 69, 69, 76, 69, 86, 91, 75, 70, 161, GrowthRate.ERRATIC, 50, true), - new PokemonSpecies(SpeciesId.MANTYKE, 4, false, false, false, "Kite Pokémon", PokemonType.WATER, PokemonType.FLYING, 1, 65, AbilityId.SWIFT_SWIM, AbilityId.WATER_ABSORB, AbilityId.WATER_VEIL, 345, 45, 20, 50, 60, 120, 50, 25, 50, 69, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.SNOVER, 4, false, false, false, "Frost Tree Pokémon", PokemonType.GRASS, PokemonType.ICE, 1, 50.5, AbilityId.SNOW_WARNING, AbilityId.NONE, AbilityId.SOUNDPROOF, 334, 60, 62, 50, 62, 60, 40, 120, 50, 67, GrowthRate.SLOW, 50, true), - new PokemonSpecies(SpeciesId.ABOMASNOW, 4, false, false, false, "Frost Tree Pokémon", PokemonType.GRASS, PokemonType.ICE, 2.2, 135.5, AbilityId.SNOW_WARNING, AbilityId.NONE, AbilityId.SOUNDPROOF, 494, 90, 92, 75, 92, 85, 60, 60, 50, 173, GrowthRate.SLOW, 50, true, true, - new PokemonForm("Normal", "", PokemonType.GRASS, PokemonType.ICE, 2.2, 135.5, AbilityId.SNOW_WARNING, AbilityId.NONE, AbilityId.SOUNDPROOF, 494, 90, 92, 75, 92, 85, 60, 60, 50, 173, true, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.GRASS, PokemonType.ICE, 2.7, 185, AbilityId.SNOW_WARNING, AbilityId.NONE, AbilityId.SNOW_WARNING, 594, 90, 132, 105, 132, 105, 30, 60, 50, 173, true), - ), - new PokemonSpecies(SpeciesId.WEAVILE, 4, false, false, false, "Sharp Claw Pokémon", PokemonType.DARK, PokemonType.ICE, 1.1, 34, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.PICKPOCKET, 510, 70, 120, 65, 45, 85, 125, 45, 35, 179, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.MAGNEZONE, 4, false, false, false, "Magnet Area Pokémon", PokemonType.ELECTRIC, PokemonType.STEEL, 1.2, 180, AbilityId.MAGNET_PULL, AbilityId.STURDY, AbilityId.ANALYTIC, 535, 70, 70, 115, 130, 90, 60, 30, 50, 268, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.LICKILICKY, 4, false, false, false, "Licking Pokémon", PokemonType.NORMAL, null, 1.7, 140, AbilityId.OWN_TEMPO, AbilityId.OBLIVIOUS, AbilityId.CLOUD_NINE, 515, 110, 85, 95, 80, 95, 50, 30, 50, 180, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.RHYPERIOR, 4, false, false, false, "Drill Pokémon", PokemonType.GROUND, PokemonType.ROCK, 2.4, 282.8, AbilityId.LIGHTNING_ROD, AbilityId.SOLID_ROCK, AbilityId.RECKLESS, 535, 115, 140, 130, 55, 55, 40, 30, 50, 268, GrowthRate.SLOW, 50, true), - new PokemonSpecies(SpeciesId.TANGROWTH, 4, false, false, false, "Vine Pokémon", PokemonType.GRASS, null, 2, 128.6, AbilityId.CHLOROPHYLL, AbilityId.LEAF_GUARD, AbilityId.REGENERATOR, 535, 100, 100, 125, 110, 50, 50, 30, 50, 187, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.ELECTIVIRE, 4, false, false, false, "Thunderbolt Pokémon", PokemonType.ELECTRIC, null, 1.8, 138.6, AbilityId.MOTOR_DRIVE, AbilityId.NONE, AbilityId.VITAL_SPIRIT, 540, 75, 123, 67, 95, 85, 95, 30, 50, 270, GrowthRate.MEDIUM_FAST, 75, false), - new PokemonSpecies(SpeciesId.MAGMORTAR, 4, false, false, false, "Blast Pokémon", PokemonType.FIRE, null, 1.6, 68, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.VITAL_SPIRIT, 540, 75, 95, 67, 125, 95, 83, 30, 50, 270, GrowthRate.MEDIUM_FAST, 75, false), - new PokemonSpecies(SpeciesId.TOGEKISS, 4, false, false, false, "Jubilee Pokémon", PokemonType.FAIRY, PokemonType.FLYING, 1.5, 38, AbilityId.HUSTLE, AbilityId.SERENE_GRACE, AbilityId.SUPER_LUCK, 545, 85, 50, 95, 120, 115, 80, 30, 50, 273, GrowthRate.FAST, 87.5, false), - new PokemonSpecies(SpeciesId.YANMEGA, 4, false, false, false, "Ogre Darner Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.9, 51.5, AbilityId.SPEED_BOOST, AbilityId.TINTED_LENS, AbilityId.FRISK, 515, 86, 76, 86, 116, 56, 95, 30, 70, 180, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.LEAFEON, 4, false, false, false, "Verdant Pokémon", PokemonType.GRASS, null, 1, 25.5, AbilityId.LEAF_GUARD, AbilityId.NONE, AbilityId.CHLOROPHYLL, 525, 65, 110, 130, 60, 65, 95, 45, 35, 184, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.GLACEON, 4, false, false, false, "Fresh Snow Pokémon", PokemonType.ICE, null, 0.8, 25.9, AbilityId.SNOW_CLOAK, AbilityId.NONE, AbilityId.ICE_BODY, 525, 65, 60, 110, 130, 95, 65, 45, 35, 184, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.GLISCOR, 4, false, false, false, "Fang Scorpion Pokémon", PokemonType.GROUND, PokemonType.FLYING, 2, 42.5, AbilityId.HYPER_CUTTER, AbilityId.SAND_VEIL, AbilityId.POISON_HEAL, 510, 75, 95, 125, 45, 75, 95, 30, 70, 179, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.MAMOSWINE, 4, false, false, false, "Twin Tusk Pokémon", PokemonType.ICE, PokemonType.GROUND, 2.5, 291, AbilityId.OBLIVIOUS, AbilityId.SNOW_CLOAK, AbilityId.THICK_FAT, 530, 110, 130, 80, 70, 60, 80, 50, 50, 265, GrowthRate.SLOW, 50, true), - new PokemonSpecies(SpeciesId.PORYGON_Z, 4, false, false, false, "Virtual Pokémon", PokemonType.NORMAL, null, 0.9, 34, AbilityId.ADAPTABILITY, AbilityId.DOWNLOAD, AbilityId.ANALYTIC, 535, 85, 80, 70, 135, 75, 90, 30, 50, 268, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.GALLADE, 4, false, false, false, "Blade Pokémon", PokemonType.PSYCHIC, PokemonType.FIGHTING, 1.6, 52, AbilityId.STEADFAST, AbilityId.SHARPNESS, AbilityId.JUSTIFIED, 518, 68, 125, 65, 65, 115, 80, 45, 35, 259, GrowthRate.SLOW, 100, false, true, - new PokemonForm("Normal", "", PokemonType.PSYCHIC, PokemonType.FIGHTING, 1.6, 52, AbilityId.STEADFAST, AbilityId.SHARPNESS, AbilityId.JUSTIFIED, 518, 68, 125, 65, 65, 115, 80, 45, 35, 259, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.PSYCHIC, PokemonType.FIGHTING, 1.6, 56.4, AbilityId.INNER_FOCUS, AbilityId.INNER_FOCUS, AbilityId.INNER_FOCUS, 618, 68, 165, 95, 65, 115, 110, 45, 35, 259), - ), - new PokemonSpecies(SpeciesId.PROBOPASS, 4, false, false, false, "Compass Pokémon", PokemonType.ROCK, PokemonType.STEEL, 1.4, 340, AbilityId.STURDY, AbilityId.MAGNET_PULL, AbilityId.SAND_FORCE, 525, 60, 55, 145, 75, 150, 40, 60, 70, 184, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DUSKNOIR, 4, false, false, false, "Gripper Pokémon", PokemonType.GHOST, null, 2.2, 106.6, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.FRISK, 525, 45, 100, 135, 65, 135, 45, 45, 35, 263, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.FROSLASS, 4, false, false, false, "Snow Land Pokémon", PokemonType.ICE, PokemonType.GHOST, 1.3, 26.6, AbilityId.SNOW_CLOAK, AbilityId.NONE, AbilityId.CURSED_BODY, 480, 70, 80, 70, 80, 70, 110, 75, 50, 168, GrowthRate.MEDIUM_FAST, 0, false), - new PokemonSpecies(SpeciesId.ROTOM, 4, false, false, false, "Plasma Pokémon", PokemonType.ELECTRIC, PokemonType.GHOST, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 440, 50, 50, 77, 95, 77, 91, 45, 50, 154, GrowthRate.MEDIUM_FAST, null, false, false, - new PokemonForm("Normal", "", PokemonType.ELECTRIC, PokemonType.GHOST, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 440, 50, 50, 77, 95, 77, 91, 45, 50, 154, false, null, true), - new PokemonForm("Heat", "heat", PokemonType.ELECTRIC, PokemonType.FIRE, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 520, 50, 65, 107, 105, 107, 86, 45, 50, 182, false, null, true), - new PokemonForm("Wash", "wash", PokemonType.ELECTRIC, PokemonType.WATER, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 520, 50, 65, 107, 105, 107, 86, 45, 50, 182, false, null, true), - new PokemonForm("Frost", "frost", PokemonType.ELECTRIC, PokemonType.ICE, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 520, 50, 65, 107, 105, 107, 86, 45, 50, 182, false, null, true), - new PokemonForm("Fan", "fan", PokemonType.ELECTRIC, PokemonType.FLYING, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 520, 50, 65, 107, 105, 107, 86, 45, 50, 182, false, null, true), - new PokemonForm("Mow", "mow", PokemonType.ELECTRIC, PokemonType.GRASS, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 520, 50, 65, 107, 105, 107, 86, 45, 50, 182, false, null, true), - ), - new PokemonSpecies(SpeciesId.UXIE, 4, true, false, false, "Knowledge Pokémon", PokemonType.PSYCHIC, null, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 580, 75, 75, 130, 75, 130, 95, 3, 140, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.MESPRIT, 4, true, false, false, "Emotion Pokémon", PokemonType.PSYCHIC, null, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 580, 80, 105, 105, 105, 105, 80, 3, 140, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.AZELF, 4, true, false, false, "Willpower Pokémon", PokemonType.PSYCHIC, null, 0.3, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 580, 75, 125, 70, 125, 70, 115, 3, 140, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.DIALGA, 4, false, true, false, "Temporal Pokémon", PokemonType.STEEL, PokemonType.DRAGON, 5.4, 683, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 100, 120, 120, 150, 100, 90, 3, 0, 340, GrowthRate.SLOW, null, false, false, - new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.DRAGON, 5.4, 683, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 100, 120, 120, 150, 100, 90, 3, 0, 340, false, null, true), - new PokemonForm("Origin Forme", "origin", PokemonType.STEEL, PokemonType.DRAGON, 7, 848.7, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 100, 100, 120, 150, 120, 90, 3, 0, 340), - ), - new PokemonSpecies(SpeciesId.PALKIA, 4, false, true, false, "Spatial Pokémon", PokemonType.WATER, PokemonType.DRAGON, 4.2, 336, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 90, 120, 100, 150, 120, 100, 3, 0, 340, GrowthRate.SLOW, null, false, false, - new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.DRAGON, 4.2, 336, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 90, 120, 100, 150, 120, 100, 3, 0, 340, false, null, true), - new PokemonForm("Origin Forme", "origin", PokemonType.WATER, PokemonType.DRAGON, 6.3, 659, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 90, 100, 100, 150, 120, 120, 3, 0, 340), - ), - new PokemonSpecies(SpeciesId.HEATRAN, 4, true, false, false, "Lava Dome Pokémon", PokemonType.FIRE, PokemonType.STEEL, 1.7, 430, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.FLAME_BODY, 600, 91, 90, 106, 130, 106, 77, 3, 100, 300, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.REGIGIGAS, 4, true, false, false, "Colossal Pokémon", PokemonType.NORMAL, null, 3.7, 420, AbilityId.SLOW_START, AbilityId.NONE, AbilityId.NORMALIZE, 670, 110, 160, 110, 80, 110, 100, 3, 0, 335, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.GIRATINA, 4, false, true, false, "Renegade Pokémon", PokemonType.GHOST, PokemonType.DRAGON, 4.5, 750, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 150, 100, 120, 100, 120, 90, 3, 0, 340, GrowthRate.SLOW, null, false, true, - new PokemonForm("Altered Forme", "altered", PokemonType.GHOST, PokemonType.DRAGON, 4.5, 750, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.TELEPATHY, 680, 150, 100, 120, 100, 120, 90, 3, 0, 340, false, null, true), - new PokemonForm("Origin Forme", "origin", PokemonType.GHOST, PokemonType.DRAGON, 6.9, 650, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.LEVITATE, 680, 150, 120, 100, 120, 100, 90, 3, 0, 340), - ), - new PokemonSpecies(SpeciesId.CRESSELIA, 4, true, false, false, "Lunar Pokémon", PokemonType.PSYCHIC, null, 1.5, 85.6, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 580, 120, 70, 110, 75, 120, 85, 3, 100, 300, GrowthRate.SLOW, 0, false), - new PokemonSpecies(SpeciesId.PHIONE, 4, false, false, true, "Sea Drifter Pokémon", PokemonType.WATER, null, 0.4, 3.1, AbilityId.HYDRATION, AbilityId.NONE, AbilityId.NONE, 480, 80, 80, 80, 80, 80, 80, 30, 70, 240, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.MANAPHY, 4, false, false, true, "Seafaring Pokémon", PokemonType.WATER, null, 0.3, 1.4, AbilityId.HYDRATION, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 3, 70, 300, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.DARKRAI, 4, false, false, true, "Pitch-Black Pokémon", PokemonType.DARK, null, 1.5, 50.5, AbilityId.BAD_DREAMS, AbilityId.NONE, AbilityId.NONE, 600, 70, 90, 90, 135, 90, 125, 3, 0, 300, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.SHAYMIN, 4, false, false, true, "Gratitude Pokémon", PokemonType.GRASS, null, 0.2, 2.1, AbilityId.NATURAL_CURE, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 45, 100, 300, GrowthRate.MEDIUM_SLOW, null, false, true, - new PokemonForm("Land Forme", "land", PokemonType.GRASS, null, 0.2, 2.1, AbilityId.NATURAL_CURE, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 45, 100, 300, false, null, true), - new PokemonForm("Sky Forme", "sky", PokemonType.GRASS, PokemonType.FLYING, 0.4, 5.2, AbilityId.SERENE_GRACE, AbilityId.NONE, AbilityId.NONE, 600, 100, 103, 75, 120, 75, 127, 45, 100, 300), - ), - new PokemonSpecies(SpeciesId.ARCEUS, 4, false, false, true, "Alpha Pokémon", PokemonType.NORMAL, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360, GrowthRate.SLOW, null, false, true, - new PokemonForm("Normal", "normal", PokemonType.NORMAL, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360, false, null, true), - new PokemonForm("Fighting", "fighting", PokemonType.FIGHTING, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Flying", "flying", PokemonType.FLYING, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Poison", "poison", PokemonType.POISON, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Ground", "ground", PokemonType.GROUND, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Rock", "rock", PokemonType.ROCK, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Bug", "bug", PokemonType.BUG, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Ghost", "ghost", PokemonType.GHOST, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Steel", "steel", PokemonType.STEEL, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Fire", "fire", PokemonType.FIRE, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Water", "water", PokemonType.WATER, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Grass", "grass", PokemonType.GRASS, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Electric", "electric", PokemonType.ELECTRIC, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Psychic", "psychic", PokemonType.PSYCHIC, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Ice", "ice", PokemonType.ICE, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Dragon", "dragon", PokemonType.DRAGON, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Dark", "dark", PokemonType.DARK, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("Fairy", "fairy", PokemonType.FAIRY, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360), - new PokemonForm("???", "unknown", PokemonType.UNKNOWN, null, 3.2, 320, AbilityId.MULTITYPE, AbilityId.NONE, AbilityId.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 360, false, null, false, true), - ), - new PokemonSpecies(SpeciesId.VICTINI, 5, false, false, true, "Victory Pokémon", PokemonType.PSYCHIC, PokemonType.FIRE, 0.4, 4, AbilityId.VICTORY_STAR, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 3, 100, 300, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.SNIVY, 5, false, false, false, "Grass Snake Pokémon", PokemonType.GRASS, null, 0.6, 8.1, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CONTRARY, 308, 45, 45, 55, 45, 55, 63, 45, 70, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.SERVINE, 5, false, false, false, "Grass Snake Pokémon", PokemonType.GRASS, null, 0.8, 16, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CONTRARY, 413, 60, 60, 75, 60, 75, 83, 45, 70, 145, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.SERPERIOR, 5, false, false, false, "Regal Pokémon", PokemonType.GRASS, null, 3.3, 63, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.CONTRARY, 528, 75, 75, 95, 75, 95, 113, 45, 70, 264, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.TEPIG, 5, false, false, false, "Fire Pig Pokémon", PokemonType.FIRE, null, 0.5, 9.9, AbilityId.BLAZE, AbilityId.NONE, AbilityId.THICK_FAT, 308, 65, 63, 45, 45, 45, 45, 45, 70, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.PIGNITE, 5, false, false, false, "Fire Pig Pokémon", PokemonType.FIRE, PokemonType.FIGHTING, 1, 55.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.THICK_FAT, 418, 90, 93, 55, 70, 55, 55, 45, 70, 146, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.EMBOAR, 5, false, false, false, "Mega Fire Pig Pokémon", PokemonType.FIRE, PokemonType.FIGHTING, 1.6, 150, AbilityId.BLAZE, AbilityId.NONE, AbilityId.RECKLESS, 528, 110, 123, 65, 100, 65, 65, 45, 70, 264, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.OSHAWOTT, 5, false, false, false, "Sea Otter Pokémon", PokemonType.WATER, null, 0.5, 5.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHELL_ARMOR, 308, 55, 55, 45, 63, 45, 45, 45, 70, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.DEWOTT, 5, false, false, false, "Discipline Pokémon", PokemonType.WATER, null, 0.8, 24.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHELL_ARMOR, 413, 75, 75, 60, 83, 60, 60, 45, 70, 145, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.SAMUROTT, 5, false, false, false, "Formidable Pokémon", PokemonType.WATER, null, 1.5, 94.6, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHELL_ARMOR, 528, 95, 100, 85, 108, 70, 70, 45, 70, 264, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.PATRAT, 5, false, false, false, "Scout Pokémon", PokemonType.NORMAL, null, 0.5, 11.6, AbilityId.RUN_AWAY, AbilityId.KEEN_EYE, AbilityId.ANALYTIC, 255, 45, 55, 39, 35, 39, 42, 255, 70, 51, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.WATCHOG, 5, false, false, false, "Lookout Pokémon", PokemonType.NORMAL, null, 1.1, 27, AbilityId.ILLUMINATE, AbilityId.KEEN_EYE, AbilityId.ANALYTIC, 420, 60, 85, 69, 60, 69, 77, 255, 70, 147, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.LILLIPUP, 5, false, false, false, "Puppy Pokémon", PokemonType.NORMAL, null, 0.4, 4.1, AbilityId.VITAL_SPIRIT, AbilityId.PICKUP, AbilityId.RUN_AWAY, 275, 45, 60, 45, 25, 45, 55, 255, 50, 55, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.HERDIER, 5, false, false, false, "Loyal Dog Pokémon", PokemonType.NORMAL, null, 0.9, 14.7, AbilityId.INTIMIDATE, AbilityId.SAND_RUSH, AbilityId.SCRAPPY, 370, 65, 80, 65, 35, 65, 60, 120, 50, 130, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.STOUTLAND, 5, false, false, false, "Big-Hearted Pokémon", PokemonType.NORMAL, null, 1.2, 61, AbilityId.INTIMIDATE, AbilityId.SAND_RUSH, AbilityId.SCRAPPY, 500, 85, 110, 90, 45, 90, 80, 45, 50, 250, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.PURRLOIN, 5, false, false, false, "Devious Pokémon", PokemonType.DARK, null, 0.4, 10.1, AbilityId.LIMBER, AbilityId.UNBURDEN, AbilityId.PRANKSTER, 281, 41, 50, 37, 50, 37, 66, 255, 50, 56, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.LIEPARD, 5, false, false, false, "Cruel Pokémon", PokemonType.DARK, null, 1.1, 37.5, AbilityId.LIMBER, AbilityId.UNBURDEN, AbilityId.PRANKSTER, 446, 64, 88, 50, 88, 50, 106, 90, 50, 156, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PANSAGE, 5, false, false, false, "Grass Monkey Pokémon", PokemonType.GRASS, null, 0.6, 10.5, AbilityId.GLUTTONY, AbilityId.NONE, AbilityId.OVERGROW, 316, 50, 53, 48, 53, 48, 64, 190, 70, 63, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.SIMISAGE, 5, false, false, false, "Thorn Monkey Pokémon", PokemonType.GRASS, null, 1.1, 30.5, AbilityId.GLUTTONY, AbilityId.NONE, AbilityId.OVERGROW, 498, 75, 98, 63, 98, 63, 101, 75, 70, 174, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.PANSEAR, 5, false, false, false, "High Temp Pokémon", PokemonType.FIRE, null, 0.6, 11, AbilityId.GLUTTONY, AbilityId.NONE, AbilityId.BLAZE, 316, 50, 53, 48, 53, 48, 64, 190, 70, 63, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.SIMISEAR, 5, false, false, false, "Ember Pokémon", PokemonType.FIRE, null, 1, 28, AbilityId.GLUTTONY, AbilityId.NONE, AbilityId.BLAZE, 498, 75, 98, 63, 98, 63, 101, 75, 70, 174, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.PANPOUR, 5, false, false, false, "Spray Pokémon", PokemonType.WATER, null, 0.6, 13.5, AbilityId.GLUTTONY, AbilityId.NONE, AbilityId.TORRENT, 316, 50, 53, 48, 53, 48, 64, 190, 70, 63, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.SIMIPOUR, 5, false, false, false, "Geyser Pokémon", PokemonType.WATER, null, 1, 29, AbilityId.GLUTTONY, AbilityId.NONE, AbilityId.TORRENT, 498, 75, 98, 63, 98, 63, 101, 75, 70, 174, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.MUNNA, 5, false, false, false, "Dream Eater Pokémon", PokemonType.PSYCHIC, null, 0.6, 23.3, AbilityId.FOREWARN, AbilityId.SYNCHRONIZE, AbilityId.TELEPATHY, 292, 76, 25, 45, 67, 55, 24, 190, 50, 58, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.MUSHARNA, 5, false, false, false, "Drowsing Pokémon", PokemonType.PSYCHIC, null, 1.1, 60.5, AbilityId.FOREWARN, AbilityId.SYNCHRONIZE, AbilityId.TELEPATHY, 487, 116, 55, 85, 107, 95, 29, 75, 50, 170, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.PIDOVE, 5, false, false, false, "Tiny Pigeon Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 2.1, AbilityId.BIG_PECKS, AbilityId.SUPER_LUCK, AbilityId.RIVALRY, 264, 50, 55, 50, 36, 30, 43, 255, 50, 53, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.TRANQUILL, 5, false, false, false, "Wild Pigeon Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 15, AbilityId.BIG_PECKS, AbilityId.SUPER_LUCK, AbilityId.RIVALRY, 358, 62, 77, 62, 50, 42, 65, 120, 50, 125, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.UNFEZANT, 5, false, false, false, "Proud Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.2, 29, AbilityId.BIG_PECKS, AbilityId.SUPER_LUCK, AbilityId.RIVALRY, 488, 80, 115, 80, 65, 55, 93, 45, 50, 244, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.BLITZLE, 5, false, false, false, "Electrified Pokémon", PokemonType.ELECTRIC, null, 0.8, 29.8, AbilityId.LIGHTNING_ROD, AbilityId.MOTOR_DRIVE, AbilityId.SAP_SIPPER, 295, 45, 60, 32, 50, 32, 76, 190, 70, 59, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ZEBSTRIKA, 5, false, false, false, "Thunderbolt Pokémon", PokemonType.ELECTRIC, null, 1.6, 79.5, AbilityId.LIGHTNING_ROD, AbilityId.MOTOR_DRIVE, AbilityId.SAP_SIPPER, 497, 75, 100, 63, 80, 63, 116, 75, 70, 174, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ROGGENROLA, 5, false, false, false, "Mantle Pokémon", PokemonType.ROCK, null, 0.4, 18, AbilityId.STURDY, AbilityId.WEAK_ARMOR, AbilityId.SAND_FORCE, 280, 55, 75, 85, 25, 25, 15, 255, 50, 56, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.BOLDORE, 5, false, false, false, "Ore Pokémon", PokemonType.ROCK, null, 0.9, 102, AbilityId.STURDY, AbilityId.WEAK_ARMOR, AbilityId.SAND_FORCE, 390, 70, 105, 105, 50, 40, 20, 120, 50, 137, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.GIGALITH, 5, false, false, false, "Compressed Pokémon", PokemonType.ROCK, null, 1.7, 260, AbilityId.STURDY, AbilityId.SAND_STREAM, AbilityId.SAND_FORCE, 515, 85, 135, 130, 60, 80, 25, 45, 50, 258, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.WOOBAT, 5, false, false, false, "Bat Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 0.4, 2.1, AbilityId.UNAWARE, AbilityId.KLUTZ, AbilityId.SIMPLE, 323, 65, 45, 43, 55, 43, 72, 190, 50, 65, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SWOOBAT, 5, false, false, false, "Courting Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 0.9, 10.5, AbilityId.UNAWARE, AbilityId.KLUTZ, AbilityId.SIMPLE, 425, 67, 57, 55, 77, 55, 114, 45, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DRILBUR, 5, false, false, false, "Mole Pokémon", PokemonType.GROUND, null, 0.3, 8.5, AbilityId.SAND_RUSH, AbilityId.SAND_FORCE, AbilityId.MOLD_BREAKER, 328, 60, 85, 40, 30, 45, 68, 120, 50, 66, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.EXCADRILL, 5, false, false, false, "Subterrene Pokémon", PokemonType.GROUND, PokemonType.STEEL, 0.7, 40.4, AbilityId.SAND_RUSH, AbilityId.SAND_FORCE, AbilityId.MOLD_BREAKER, 508, 110, 135, 60, 50, 65, 88, 60, 50, 178, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.AUDINO, 5, false, false, false, "Hearing Pokémon", PokemonType.NORMAL, null, 1.1, 31, AbilityId.HEALER, AbilityId.REGENERATOR, AbilityId.KLUTZ, 445, 103, 60, 86, 60, 86, 50, 255, 50, 390, GrowthRate.FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.NORMAL, null, 1.1, 31, AbilityId.HEALER, AbilityId.REGENERATOR, AbilityId.KLUTZ, 445, 103, 60, 86, 60, 86, 50, 255, 50, 390, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.NORMAL, PokemonType.FAIRY, 1.5, 32, AbilityId.REGENERATOR, AbilityId.REGENERATOR, AbilityId.REGENERATOR, 545, 103, 60, 126, 80, 126, 50, 255, 50, 390), //Custom Ability, base form Hidden Ability - ), - new PokemonSpecies(SpeciesId.TIMBURR, 5, false, false, false, "Muscular Pokémon", PokemonType.FIGHTING, null, 0.6, 12.5, AbilityId.GUTS, AbilityId.SHEER_FORCE, AbilityId.IRON_FIST, 305, 75, 80, 55, 25, 35, 35, 180, 70, 61, GrowthRate.MEDIUM_SLOW, 75, false), - new PokemonSpecies(SpeciesId.GURDURR, 5, false, false, false, "Muscular Pokémon", PokemonType.FIGHTING, null, 1.2, 40, AbilityId.GUTS, AbilityId.SHEER_FORCE, AbilityId.IRON_FIST, 405, 85, 105, 85, 40, 50, 40, 90, 50, 142, GrowthRate.MEDIUM_SLOW, 75, false), - new PokemonSpecies(SpeciesId.CONKELDURR, 5, false, false, false, "Muscular Pokémon", PokemonType.FIGHTING, null, 1.4, 87, AbilityId.GUTS, AbilityId.SHEER_FORCE, AbilityId.IRON_FIST, 505, 105, 140, 95, 55, 65, 45, 45, 50, 253, GrowthRate.MEDIUM_SLOW, 75, false), - new PokemonSpecies(SpeciesId.TYMPOLE, 5, false, false, false, "Tadpole Pokémon", PokemonType.WATER, null, 0.5, 4.5, AbilityId.SWIFT_SWIM, AbilityId.HYDRATION, AbilityId.WATER_ABSORB, 294, 50, 50, 40, 50, 40, 64, 255, 50, 59, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.PALPITOAD, 5, false, false, false, "Vibration Pokémon", PokemonType.WATER, PokemonType.GROUND, 0.8, 17, AbilityId.SWIFT_SWIM, AbilityId.HYDRATION, AbilityId.WATER_ABSORB, 384, 75, 65, 55, 65, 55, 69, 120, 50, 134, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SEISMITOAD, 5, false, false, false, "Vibration Pokémon", PokemonType.WATER, PokemonType.GROUND, 1.5, 62, AbilityId.SWIFT_SWIM, AbilityId.POISON_TOUCH, AbilityId.WATER_ABSORB, 509, 105, 95, 75, 85, 75, 74, 45, 50, 255, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.THROH, 5, false, false, false, "Judo Pokémon", PokemonType.FIGHTING, null, 1.3, 55.5, AbilityId.GUTS, AbilityId.INNER_FOCUS, AbilityId.MOLD_BREAKER, 465, 120, 100, 85, 30, 85, 45, 45, 50, 163, GrowthRate.MEDIUM_FAST, 100, false), - new PokemonSpecies(SpeciesId.SAWK, 5, false, false, false, "Karate Pokémon", PokemonType.FIGHTING, null, 1.4, 51, AbilityId.STURDY, AbilityId.INNER_FOCUS, AbilityId.MOLD_BREAKER, 465, 75, 125, 75, 30, 75, 85, 45, 50, 163, GrowthRate.MEDIUM_FAST, 100, false), - new PokemonSpecies(SpeciesId.SEWADDLE, 5, false, false, false, "Sewing Pokémon", PokemonType.BUG, PokemonType.GRASS, 0.3, 2.5, AbilityId.SWARM, AbilityId.CHLOROPHYLL, AbilityId.OVERCOAT, 310, 45, 53, 70, 40, 60, 42, 255, 70, 62, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SWADLOON, 5, false, false, false, "Leaf-Wrapped Pokémon", PokemonType.BUG, PokemonType.GRASS, 0.5, 7.3, AbilityId.LEAF_GUARD, AbilityId.CHLOROPHYLL, AbilityId.OVERCOAT, 380, 55, 63, 90, 50, 80, 42, 120, 70, 133, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.LEAVANNY, 5, false, false, false, "Nurturing Pokémon", PokemonType.BUG, PokemonType.GRASS, 1.2, 20.5, AbilityId.SWARM, AbilityId.CHLOROPHYLL, AbilityId.OVERCOAT, 500, 75, 103, 80, 70, 80, 92, 45, 70, 250, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.VENIPEDE, 5, false, false, false, "Centipede Pokémon", PokemonType.BUG, PokemonType.POISON, 0.4, 5.3, AbilityId.POISON_POINT, AbilityId.SWARM, AbilityId.SPEED_BOOST, 260, 30, 45, 59, 30, 39, 57, 255, 50, 52, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.WHIRLIPEDE, 5, false, false, false, "Curlipede Pokémon", PokemonType.BUG, PokemonType.POISON, 1.2, 58.5, AbilityId.POISON_POINT, AbilityId.SWARM, AbilityId.SPEED_BOOST, 360, 40, 55, 99, 40, 79, 47, 120, 50, 126, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SCOLIPEDE, 5, false, false, false, "Megapede Pokémon", PokemonType.BUG, PokemonType.POISON, 2.5, 200.5, AbilityId.POISON_POINT, AbilityId.SWARM, AbilityId.SPEED_BOOST, 485, 60, 100, 89, 55, 69, 112, 45, 50, 243, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.COTTONEE, 5, false, false, false, "Cotton Puff Pokémon", PokemonType.GRASS, PokemonType.FAIRY, 0.3, 0.6, AbilityId.PRANKSTER, AbilityId.INFILTRATOR, AbilityId.CHLOROPHYLL, 280, 40, 27, 60, 37, 50, 66, 190, 50, 56, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.WHIMSICOTT, 5, false, false, false, "Windveiled Pokémon", PokemonType.GRASS, PokemonType.FAIRY, 0.7, 6.6, AbilityId.PRANKSTER, AbilityId.INFILTRATOR, AbilityId.CHLOROPHYLL, 480, 60, 67, 85, 77, 75, 116, 75, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PETILIL, 5, false, false, false, "Bulb Pokémon", PokemonType.GRASS, null, 0.5, 6.6, AbilityId.CHLOROPHYLL, AbilityId.OWN_TEMPO, AbilityId.LEAF_GUARD, 280, 45, 35, 50, 70, 50, 30, 190, 50, 56, GrowthRate.MEDIUM_FAST, 0, false), - new PokemonSpecies(SpeciesId.LILLIGANT, 5, false, false, false, "Flowering Pokémon", PokemonType.GRASS, null, 1.1, 16.3, AbilityId.CHLOROPHYLL, AbilityId.OWN_TEMPO, AbilityId.LEAF_GUARD, 480, 70, 60, 75, 110, 75, 90, 75, 50, 168, GrowthRate.MEDIUM_FAST, 0, false), - new PokemonSpecies(SpeciesId.BASCULIN, 5, false, false, false, "Hostile Pokémon", PokemonType.WATER, null, 1, 18, AbilityId.RECKLESS, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 190, 50, 161, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Red-Striped Form", "red-striped", PokemonType.WATER, null, 1, 18, AbilityId.RECKLESS, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 190, 50, 161, false, null, true), - new PokemonForm("Blue-Striped Form", "blue-striped", PokemonType.WATER, null, 1, 18, AbilityId.ROCK_HEAD, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 190, 50, 161, false, null, true), - new PokemonForm("White-Striped Form", "white-striped", PokemonType.WATER, null, 1, 18, AbilityId.RATTLED, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 190, 50, 161, false, null, true), - ), - new PokemonSpecies(SpeciesId.SANDILE, 5, false, false, false, "Desert Croc Pokémon", PokemonType.GROUND, PokemonType.DARK, 0.7, 15.2, AbilityId.INTIMIDATE, AbilityId.MOXIE, AbilityId.ANGER_POINT, 292, 50, 72, 35, 35, 35, 65, 180, 50, 58, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.KROKOROK, 5, false, false, false, "Desert Croc Pokémon", PokemonType.GROUND, PokemonType.DARK, 1, 33.4, AbilityId.INTIMIDATE, AbilityId.MOXIE, AbilityId.ANGER_POINT, 351, 60, 82, 45, 45, 45, 74, 90, 50, 123, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.KROOKODILE, 5, false, false, false, "Intimidation Pokémon", PokemonType.GROUND, PokemonType.DARK, 1.5, 96.3, AbilityId.INTIMIDATE, AbilityId.MOXIE, AbilityId.ANGER_POINT, 519, 95, 117, 80, 65, 70, 92, 45, 50, 260, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.DARUMAKA, 5, false, false, false, "Zen Charm Pokémon", PokemonType.FIRE, null, 0.6, 37.5, AbilityId.HUSTLE, AbilityId.NONE, AbilityId.INNER_FOCUS, 315, 70, 90, 45, 15, 45, 50, 120, 50, 63, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.DARMANITAN, 5, false, false, false, "Blazing Pokémon", PokemonType.FIRE, null, 1.3, 92.9, AbilityId.SHEER_FORCE, AbilityId.NONE, AbilityId.ZEN_MODE, 480, 105, 140, 55, 30, 55, 95, 60, 50, 168, GrowthRate.MEDIUM_SLOW, 50, false, true, - new PokemonForm("Standard Mode", "", PokemonType.FIRE, null, 1.3, 92.9, AbilityId.SHEER_FORCE, AbilityId.NONE, AbilityId.ZEN_MODE, 480, 105, 140, 55, 30, 55, 95, 60, 50, 168, false, null, true), - new PokemonForm("Zen Mode", "zen", PokemonType.FIRE, PokemonType.PSYCHIC, 1.3, 92.9, AbilityId.SHEER_FORCE, AbilityId.NONE, AbilityId.ZEN_MODE, 540, 105, 30, 105, 140, 105, 55, 60, 50, 189), - ), - new PokemonSpecies(SpeciesId.MARACTUS, 5, false, false, false, "Cactus Pokémon", PokemonType.GRASS, null, 1, 28, AbilityId.WATER_ABSORB, AbilityId.CHLOROPHYLL, AbilityId.STORM_DRAIN, 461, 75, 86, 67, 106, 67, 60, 255, 50, 161, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DWEBBLE, 5, false, false, false, "Rock Inn Pokémon", PokemonType.BUG, PokemonType.ROCK, 0.3, 14.5, AbilityId.STURDY, AbilityId.SHELL_ARMOR, AbilityId.WEAK_ARMOR, 325, 50, 65, 85, 35, 35, 55, 190, 50, 65, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CRUSTLE, 5, false, false, false, "Stone Home Pokémon", PokemonType.BUG, PokemonType.ROCK, 1.4, 200, AbilityId.STURDY, AbilityId.SHELL_ARMOR, AbilityId.WEAK_ARMOR, 485, 70, 105, 125, 65, 75, 45, 75, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SCRAGGY, 5, false, false, false, "Shedding Pokémon", PokemonType.DARK, PokemonType.FIGHTING, 0.6, 11.8, AbilityId.SHED_SKIN, AbilityId.MOXIE, AbilityId.INTIMIDATE, 348, 50, 75, 70, 35, 70, 48, 180, 35, 70, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SCRAFTY, 5, false, false, false, "Hoodlum Pokémon", PokemonType.DARK, PokemonType.FIGHTING, 1.1, 30, AbilityId.SHED_SKIN, AbilityId.MOXIE, AbilityId.INTIMIDATE, 488, 65, 90, 115, 45, 115, 58, 90, 50, 171, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SIGILYPH, 5, false, false, false, "Avianoid Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 1.4, 14, AbilityId.WONDER_SKIN, AbilityId.MAGIC_GUARD, AbilityId.TINTED_LENS, 490, 72, 58, 80, 103, 80, 97, 45, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.YAMASK, 5, false, false, false, "Spirit Pokémon", PokemonType.GHOST, null, 0.5, 1.5, AbilityId.MUMMY, AbilityId.NONE, AbilityId.NONE, 303, 38, 30, 85, 55, 65, 30, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.COFAGRIGUS, 5, false, false, false, "Coffin Pokémon", PokemonType.GHOST, null, 1.7, 76.5, AbilityId.MUMMY, AbilityId.NONE, AbilityId.NONE, 483, 58, 50, 145, 95, 105, 30, 90, 50, 169, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.TIRTOUGA, 5, false, false, false, "Prototurtle Pokémon", PokemonType.WATER, PokemonType.ROCK, 0.7, 16.5, AbilityId.SOLID_ROCK, AbilityId.STURDY, AbilityId.SWIFT_SWIM, 355, 54, 78, 103, 53, 45, 22, 45, 50, 71, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.CARRACOSTA, 5, false, false, false, "Prototurtle Pokémon", PokemonType.WATER, PokemonType.ROCK, 1.2, 81, AbilityId.SOLID_ROCK, AbilityId.STURDY, AbilityId.SWIFT_SWIM, 495, 74, 108, 133, 83, 65, 32, 45, 50, 173, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.ARCHEN, 5, false, false, false, "First Bird Pokémon", PokemonType.ROCK, PokemonType.FLYING, 0.5, 9.5, AbilityId.DEFEATIST, AbilityId.NONE, AbilityId.WIMP_OUT, 401, 55, 112, 45, 74, 45, 70, 45, 50, 71, GrowthRate.MEDIUM_FAST, 87.5, false), //Custom Hidden - new PokemonSpecies(SpeciesId.ARCHEOPS, 5, false, false, false, "First Bird Pokémon", PokemonType.ROCK, PokemonType.FLYING, 1.4, 32, AbilityId.DEFEATIST, AbilityId.NONE, AbilityId.EMERGENCY_EXIT, 567, 75, 140, 65, 112, 65, 110, 45, 50, 177, GrowthRate.MEDIUM_FAST, 87.5, false), //Custom Hidden - new PokemonSpecies(SpeciesId.TRUBBISH, 5, false, false, false, "Trash Bag Pokémon", PokemonType.POISON, null, 0.6, 31, AbilityId.STENCH, AbilityId.STICKY_HOLD, AbilityId.AFTERMATH, 329, 50, 50, 62, 40, 62, 65, 190, 50, 66, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GARBODOR, 5, false, false, false, "Trash Heap Pokémon", PokemonType.POISON, null, 1.9, 107.3, AbilityId.STENCH, AbilityId.WEAK_ARMOR, AbilityId.AFTERMATH, 474, 80, 95, 82, 60, 82, 75, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.POISON, null, 1.9, 107.3, AbilityId.STENCH, AbilityId.WEAK_ARMOR, AbilityId.AFTERMATH, 474, 80, 95, 82, 60, 82, 75, 60, 50, 166, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.POISON, PokemonType.STEEL, 21, 999.9, AbilityId.TOXIC_DEBRIS, AbilityId.TOXIC_DEBRIS, AbilityId.TOXIC_DEBRIS, 574, 115, 121, 102, 81, 102, 53, 60, 50, 166), - ), - new PokemonSpecies(SpeciesId.ZORUA, 5, false, false, false, "Tricky Fox Pokémon", PokemonType.DARK, null, 0.7, 12.5, AbilityId.ILLUSION, AbilityId.NONE, AbilityId.NONE, 330, 40, 65, 40, 80, 40, 65, 75, 50, 66, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.ZOROARK, 5, false, false, false, "Illusion Fox Pokémon", PokemonType.DARK, null, 1.6, 81.1, AbilityId.ILLUSION, AbilityId.NONE, AbilityId.NONE, 510, 60, 105, 60, 120, 60, 105, 45, 50, 179, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.MINCCINO, 5, false, false, false, "Chinchilla Pokémon", PokemonType.NORMAL, null, 0.4, 5.8, AbilityId.CUTE_CHARM, AbilityId.TECHNICIAN, AbilityId.SKILL_LINK, 300, 55, 50, 40, 40, 40, 75, 255, 50, 60, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.CINCCINO, 5, false, false, false, "Scarf Pokémon", PokemonType.NORMAL, null, 0.5, 7.5, AbilityId.CUTE_CHARM, AbilityId.TECHNICIAN, AbilityId.SKILL_LINK, 470, 75, 95, 60, 65, 60, 115, 60, 50, 165, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.GOTHITA, 5, false, false, false, "Fixation Pokémon", PokemonType.PSYCHIC, null, 0.4, 5.8, AbilityId.FRISK, AbilityId.COMPETITIVE, AbilityId.SHADOW_TAG, 290, 45, 30, 50, 55, 65, 45, 200, 50, 58, GrowthRate.MEDIUM_SLOW, 25, false), - new PokemonSpecies(SpeciesId.GOTHORITA, 5, false, false, false, "Manipulate Pokémon", PokemonType.PSYCHIC, null, 0.7, 18, AbilityId.FRISK, AbilityId.COMPETITIVE, AbilityId.SHADOW_TAG, 390, 60, 45, 70, 75, 85, 55, 100, 50, 137, GrowthRate.MEDIUM_SLOW, 25, false), - new PokemonSpecies(SpeciesId.GOTHITELLE, 5, false, false, false, "Astral Body Pokémon", PokemonType.PSYCHIC, null, 1.5, 44, AbilityId.FRISK, AbilityId.COMPETITIVE, AbilityId.SHADOW_TAG, 490, 70, 55, 95, 95, 110, 65, 50, 50, 245, GrowthRate.MEDIUM_SLOW, 25, false), - new PokemonSpecies(SpeciesId.SOLOSIS, 5, false, false, false, "Cell Pokémon", PokemonType.PSYCHIC, null, 0.3, 1, AbilityId.OVERCOAT, AbilityId.MAGIC_GUARD, AbilityId.REGENERATOR, 290, 45, 30, 40, 105, 50, 20, 200, 50, 58, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.DUOSION, 5, false, false, false, "Mitosis Pokémon", PokemonType.PSYCHIC, null, 0.6, 8, AbilityId.OVERCOAT, AbilityId.MAGIC_GUARD, AbilityId.REGENERATOR, 370, 65, 40, 50, 125, 60, 30, 100, 50, 130, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.REUNICLUS, 5, false, false, false, "Multiplying Pokémon", PokemonType.PSYCHIC, null, 1, 20.1, AbilityId.OVERCOAT, AbilityId.MAGIC_GUARD, AbilityId.REGENERATOR, 490, 110, 65, 75, 125, 85, 30, 50, 50, 245, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.DUCKLETT, 5, false, false, false, "Water Bird Pokémon", PokemonType.WATER, PokemonType.FLYING, 0.5, 5.5, AbilityId.KEEN_EYE, AbilityId.BIG_PECKS, AbilityId.HYDRATION, 305, 62, 44, 50, 44, 50, 55, 190, 70, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SWANNA, 5, false, false, false, "White Bird Pokémon", PokemonType.WATER, PokemonType.FLYING, 1.3, 24.2, AbilityId.KEEN_EYE, AbilityId.BIG_PECKS, AbilityId.HYDRATION, 473, 75, 87, 63, 87, 63, 98, 45, 70, 166, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.VANILLITE, 5, false, false, false, "Fresh Snow Pokémon", PokemonType.ICE, null, 0.4, 5.7, AbilityId.ICE_BODY, AbilityId.SNOW_CLOAK, AbilityId.WEAK_ARMOR, 305, 36, 50, 50, 65, 60, 44, 255, 50, 61, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.VANILLISH, 5, false, false, false, "Icy Snow Pokémon", PokemonType.ICE, null, 1.1, 41, AbilityId.ICE_BODY, AbilityId.SNOW_CLOAK, AbilityId.WEAK_ARMOR, 395, 51, 65, 65, 80, 75, 59, 120, 50, 138, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.VANILLUXE, 5, false, false, false, "Snowstorm Pokémon", PokemonType.ICE, null, 1.3, 57.5, AbilityId.ICE_BODY, AbilityId.SNOW_WARNING, AbilityId.WEAK_ARMOR, 535, 71, 95, 85, 110, 95, 79, 45, 50, 268, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.DEERLING, 5, false, false, false, "Season Pokémon", PokemonType.NORMAL, PokemonType.GRASS, 0.6, 19.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 335, 60, 60, 50, 40, 50, 75, 190, 70, 67, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Spring Form", "spring", PokemonType.NORMAL, PokemonType.GRASS, 0.6, 19.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 335, 60, 60, 50, 40, 50, 75, 190, 70, 67, false, null, true), - new PokemonForm("Summer Form", "summer", PokemonType.NORMAL, PokemonType.GRASS, 0.6, 19.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 335, 60, 60, 50, 40, 50, 75, 190, 70, 67, false, null, true), - new PokemonForm("Autumn Form", "autumn", PokemonType.NORMAL, PokemonType.GRASS, 0.6, 19.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 335, 60, 60, 50, 40, 50, 75, 190, 70, 67, false, null, true), - new PokemonForm("Winter Form", "winter", PokemonType.NORMAL, PokemonType.GRASS, 0.6, 19.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 335, 60, 60, 50, 40, 50, 75, 190, 70, 67, false, null, true), - ), - new PokemonSpecies(SpeciesId.SAWSBUCK, 5, false, false, false, "Season Pokémon", PokemonType.NORMAL, PokemonType.GRASS, 1.9, 92.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 475, 80, 100, 70, 60, 70, 95, 75, 70, 166, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Spring Form", "spring", PokemonType.NORMAL, PokemonType.GRASS, 1.9, 92.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 475, 80, 100, 70, 60, 70, 95, 75, 70, 166, false, null, true), - new PokemonForm("Summer Form", "summer", PokemonType.NORMAL, PokemonType.GRASS, 1.9, 92.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 475, 80, 100, 70, 60, 70, 95, 75, 70, 166, false, null, true), - new PokemonForm("Autumn Form", "autumn", PokemonType.NORMAL, PokemonType.GRASS, 1.9, 92.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 475, 80, 100, 70, 60, 70, 95, 75, 70, 166, false, null, true), - new PokemonForm("Winter Form", "winter", PokemonType.NORMAL, PokemonType.GRASS, 1.9, 92.5, AbilityId.CHLOROPHYLL, AbilityId.SAP_SIPPER, AbilityId.SERENE_GRACE, 475, 80, 100, 70, 60, 70, 95, 75, 70, 166, false, null, true), - ), - new PokemonSpecies(SpeciesId.EMOLGA, 5, false, false, false, "Sky Squirrel Pokémon", PokemonType.ELECTRIC, PokemonType.FLYING, 0.4, 5, AbilityId.STATIC, AbilityId.NONE, AbilityId.MOTOR_DRIVE, 428, 55, 75, 60, 75, 60, 103, 200, 50, 150, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.KARRABLAST, 5, false, false, false, "Clamping Pokémon", PokemonType.BUG, null, 0.5, 5.9, AbilityId.SWARM, AbilityId.SHED_SKIN, AbilityId.NO_GUARD, 315, 50, 75, 45, 40, 45, 60, 200, 50, 63, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ESCAVALIER, 5, false, false, false, "Cavalry Pokémon", PokemonType.BUG, PokemonType.STEEL, 1, 33, AbilityId.SWARM, AbilityId.SHELL_ARMOR, AbilityId.OVERCOAT, 495, 70, 135, 105, 60, 105, 20, 75, 50, 173, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.FOONGUS, 5, false, false, false, "Mushroom Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.2, 1, AbilityId.EFFECT_SPORE, AbilityId.NONE, AbilityId.REGENERATOR, 294, 69, 55, 45, 55, 55, 15, 190, 50, 59, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.AMOONGUSS, 5, false, false, false, "Mushroom Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.6, 10.5, AbilityId.EFFECT_SPORE, AbilityId.NONE, AbilityId.REGENERATOR, 464, 114, 85, 70, 85, 80, 30, 75, 50, 162, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.FRILLISH, 5, false, false, false, "Floating Pokémon", PokemonType.WATER, PokemonType.GHOST, 1.2, 33, AbilityId.WATER_ABSORB, AbilityId.CURSED_BODY, AbilityId.DAMP, 335, 55, 40, 50, 65, 85, 40, 190, 50, 67, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.JELLICENT, 5, false, false, false, "Floating Pokémon", PokemonType.WATER, PokemonType.GHOST, 2.2, 135, AbilityId.WATER_ABSORB, AbilityId.CURSED_BODY, AbilityId.DAMP, 480, 100, 60, 70, 85, 105, 60, 60, 50, 168, GrowthRate.MEDIUM_FAST, 50, true), - new PokemonSpecies(SpeciesId.ALOMOMOLA, 5, false, false, false, "Caring Pokémon", PokemonType.WATER, null, 1.2, 31.6, AbilityId.HEALER, AbilityId.HYDRATION, AbilityId.REGENERATOR, 470, 165, 75, 80, 40, 45, 65, 75, 70, 165, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.JOLTIK, 5, false, false, false, "Attaching Pokémon", PokemonType.BUG, PokemonType.ELECTRIC, 0.1, 0.6, AbilityId.COMPOUND_EYES, AbilityId.UNNERVE, AbilityId.SWARM, 319, 50, 47, 50, 57, 50, 65, 190, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GALVANTULA, 5, false, false, false, "EleSpider Pokémon", PokemonType.BUG, PokemonType.ELECTRIC, 0.8, 14.3, AbilityId.COMPOUND_EYES, AbilityId.UNNERVE, AbilityId.SWARM, 472, 70, 77, 60, 97, 60, 108, 75, 50, 165, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.FERROSEED, 5, false, false, false, "Thorn Seed Pokémon", PokemonType.GRASS, PokemonType.STEEL, 0.6, 18.8, AbilityId.IRON_BARBS, AbilityId.NONE, AbilityId.ANTICIPATION, 305, 44, 50, 91, 24, 86, 10, 255, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.FERROTHORN, 5, false, false, false, "Thorn Pod Pokémon", PokemonType.GRASS, PokemonType.STEEL, 1, 110, AbilityId.IRON_BARBS, AbilityId.NONE, AbilityId.ANTICIPATION, 489, 74, 94, 131, 54, 116, 20, 90, 50, 171, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.KLINK, 5, false, false, false, "Gear Pokémon", PokemonType.STEEL, null, 0.3, 21, AbilityId.PLUS, AbilityId.MINUS, AbilityId.CLEAR_BODY, 300, 40, 55, 70, 45, 60, 30, 130, 50, 60, GrowthRate.MEDIUM_SLOW, null, false), - new PokemonSpecies(SpeciesId.KLANG, 5, false, false, false, "Gear Pokémon", PokemonType.STEEL, null, 0.6, 51, AbilityId.PLUS, AbilityId.MINUS, AbilityId.CLEAR_BODY, 440, 60, 80, 95, 70, 85, 50, 60, 50, 154, GrowthRate.MEDIUM_SLOW, null, false), - new PokemonSpecies(SpeciesId.KLINKLANG, 5, false, false, false, "Gear Pokémon", PokemonType.STEEL, null, 0.6, 81, AbilityId.PLUS, AbilityId.MINUS, AbilityId.CLEAR_BODY, 520, 60, 100, 115, 70, 85, 90, 30, 50, 260, GrowthRate.MEDIUM_SLOW, null, false), - new PokemonSpecies(SpeciesId.TYNAMO, 5, false, false, false, "EleFish Pokémon", PokemonType.ELECTRIC, null, 0.2, 0.3, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 275, 35, 55, 40, 45, 40, 60, 190, 70, 55, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.EELEKTRIK, 5, false, false, false, "EleFish Pokémon", PokemonType.ELECTRIC, null, 1.2, 22, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 405, 65, 85, 70, 75, 70, 40, 60, 70, 142, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.EELEKTROSS, 5, false, false, false, "EleFish Pokémon", PokemonType.ELECTRIC, null, 2.1, 80.5, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 515, 85, 115, 80, 105, 80, 50, 30, 70, 258, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.ELGYEM, 5, false, false, false, "Cerebral Pokémon", PokemonType.PSYCHIC, null, 0.5, 9, AbilityId.TELEPATHY, AbilityId.SYNCHRONIZE, AbilityId.ANALYTIC, 335, 55, 55, 55, 85, 55, 30, 255, 50, 67, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BEHEEYEM, 5, false, false, false, "Cerebral Pokémon", PokemonType.PSYCHIC, null, 1, 34.5, AbilityId.TELEPATHY, AbilityId.SYNCHRONIZE, AbilityId.ANALYTIC, 485, 75, 75, 75, 125, 95, 40, 90, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.LITWICK, 5, false, false, false, "Candle Pokémon", PokemonType.GHOST, PokemonType.FIRE, 0.3, 3.1, AbilityId.FLASH_FIRE, AbilityId.FLAME_BODY, AbilityId.INFILTRATOR, 275, 50, 30, 55, 65, 55, 20, 190, 50, 55, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.LAMPENT, 5, false, false, false, "Lamp Pokémon", PokemonType.GHOST, PokemonType.FIRE, 0.6, 13, AbilityId.FLASH_FIRE, AbilityId.FLAME_BODY, AbilityId.INFILTRATOR, 370, 60, 40, 60, 95, 60, 55, 90, 50, 130, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.CHANDELURE, 5, false, false, false, "Luring Pokémon", PokemonType.GHOST, PokemonType.FIRE, 1, 34.3, AbilityId.FLASH_FIRE, AbilityId.FLAME_BODY, AbilityId.INFILTRATOR, 520, 60, 55, 90, 145, 90, 80, 45, 50, 260, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.AXEW, 5, false, false, false, "Tusk Pokémon", PokemonType.DRAGON, null, 0.6, 18, AbilityId.RIVALRY, AbilityId.MOLD_BREAKER, AbilityId.UNNERVE, 320, 46, 87, 60, 30, 40, 57, 75, 35, 64, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.FRAXURE, 5, false, false, false, "Axe Jaw Pokémon", PokemonType.DRAGON, null, 1, 36, AbilityId.RIVALRY, AbilityId.MOLD_BREAKER, AbilityId.UNNERVE, 410, 66, 117, 70, 40, 50, 67, 60, 35, 144, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.HAXORUS, 5, false, false, false, "Axe Jaw Pokémon", PokemonType.DRAGON, null, 1.8, 105.5, AbilityId.RIVALRY, AbilityId.MOLD_BREAKER, AbilityId.UNNERVE, 540, 76, 147, 90, 60, 70, 97, 45, 35, 270, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.CUBCHOO, 5, false, false, false, "Chill Pokémon", PokemonType.ICE, null, 0.5, 8.5, AbilityId.SNOW_CLOAK, AbilityId.SLUSH_RUSH, AbilityId.RATTLED, 305, 55, 70, 40, 60, 40, 40, 120, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BEARTIC, 5, false, false, false, "Freezing Pokémon", PokemonType.ICE, null, 2.6, 260, AbilityId.SNOW_CLOAK, AbilityId.SLUSH_RUSH, AbilityId.SWIFT_SWIM, 505, 95, 130, 80, 70, 80, 50, 60, 50, 177, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CRYOGONAL, 5, false, false, false, "Crystallizing Pokémon", PokemonType.ICE, null, 1.1, 148, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 515, 80, 50, 50, 95, 135, 105, 25, 50, 180, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.SHELMET, 5, false, false, false, "Snail Pokémon", PokemonType.BUG, null, 0.4, 7.7, AbilityId.HYDRATION, AbilityId.SHELL_ARMOR, AbilityId.OVERCOAT, 305, 50, 40, 85, 40, 65, 25, 200, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ACCELGOR, 5, false, false, false, "Shell Out Pokémon", PokemonType.BUG, null, 0.8, 25.3, AbilityId.HYDRATION, AbilityId.STICKY_HOLD, AbilityId.UNBURDEN, 495, 80, 70, 40, 100, 60, 145, 75, 50, 173, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.STUNFISK, 5, false, false, false, "Trap Pokémon", PokemonType.GROUND, PokemonType.ELECTRIC, 0.7, 11, AbilityId.STATIC, AbilityId.LIMBER, AbilityId.SAND_VEIL, 471, 109, 66, 84, 81, 99, 32, 75, 70, 165, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MIENFOO, 5, false, false, false, "Martial Arts Pokémon", PokemonType.FIGHTING, null, 0.9, 20, AbilityId.INNER_FOCUS, AbilityId.REGENERATOR, AbilityId.RECKLESS, 350, 45, 85, 50, 55, 50, 65, 180, 50, 70, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.MIENSHAO, 5, false, false, false, "Martial Arts Pokémon", PokemonType.FIGHTING, null, 1.4, 35.5, AbilityId.INNER_FOCUS, AbilityId.REGENERATOR, AbilityId.RECKLESS, 510, 65, 125, 60, 95, 60, 105, 45, 50, 179, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.DRUDDIGON, 5, false, false, false, "Cave Pokémon", PokemonType.DRAGON, null, 1.6, 139, AbilityId.ROUGH_SKIN, AbilityId.SHEER_FORCE, AbilityId.MOLD_BREAKER, 485, 77, 120, 90, 60, 90, 48, 45, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GOLETT, 5, false, false, false, "Automaton Pokémon", PokemonType.GROUND, PokemonType.GHOST, 1, 92, AbilityId.IRON_FIST, AbilityId.KLUTZ, AbilityId.NO_GUARD, 303, 59, 74, 50, 35, 50, 35, 190, 50, 61, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.GOLURK, 5, false, false, false, "Automaton Pokémon", PokemonType.GROUND, PokemonType.GHOST, 2.8, 330, AbilityId.IRON_FIST, AbilityId.KLUTZ, AbilityId.NO_GUARD, 483, 89, 124, 80, 55, 80, 55, 90, 50, 169, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.PAWNIARD, 5, false, false, false, "Sharp Blade Pokémon", PokemonType.DARK, PokemonType.STEEL, 0.5, 10.2, AbilityId.DEFIANT, AbilityId.INNER_FOCUS, AbilityId.PRESSURE, 340, 45, 85, 70, 40, 40, 60, 120, 35, 68, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BISHARP, 5, false, false, false, "Sword Blade Pokémon", PokemonType.DARK, PokemonType.STEEL, 1.6, 70, AbilityId.DEFIANT, AbilityId.INNER_FOCUS, AbilityId.PRESSURE, 490, 65, 125, 100, 60, 70, 70, 45, 35, 172, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BOUFFALANT, 5, false, false, false, "Bash Buffalo Pokémon", PokemonType.NORMAL, null, 1.6, 94.6, AbilityId.RECKLESS, AbilityId.SAP_SIPPER, AbilityId.SOUNDPROOF, 490, 95, 110, 95, 40, 95, 55, 45, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.RUFFLET, 5, false, false, false, "Eaglet Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.5, 10.5, AbilityId.KEEN_EYE, AbilityId.SHEER_FORCE, AbilityId.HUSTLE, 350, 70, 83, 50, 37, 50, 60, 190, 50, 70, GrowthRate.SLOW, 100, false), - new PokemonSpecies(SpeciesId.BRAVIARY, 5, false, false, false, "Valiant Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.5, 41, AbilityId.KEEN_EYE, AbilityId.SHEER_FORCE, AbilityId.DEFIANT, 510, 100, 123, 75, 57, 75, 80, 60, 50, 179, GrowthRate.SLOW, 100, false), - new PokemonSpecies(SpeciesId.VULLABY, 5, false, false, false, "Diapered Pokémon", PokemonType.DARK, PokemonType.FLYING, 0.5, 9, AbilityId.BIG_PECKS, AbilityId.OVERCOAT, AbilityId.WEAK_ARMOR, 370, 70, 55, 75, 45, 65, 60, 190, 35, 74, GrowthRate.SLOW, 0, false), - new PokemonSpecies(SpeciesId.MANDIBUZZ, 5, false, false, false, "Bone Vulture Pokémon", PokemonType.DARK, PokemonType.FLYING, 1.2, 39.5, AbilityId.BIG_PECKS, AbilityId.OVERCOAT, AbilityId.WEAK_ARMOR, 510, 110, 65, 105, 55, 95, 80, 60, 35, 179, GrowthRate.SLOW, 0, false), - new PokemonSpecies(SpeciesId.HEATMOR, 5, false, false, false, "Anteater Pokémon", PokemonType.FIRE, null, 1.4, 58, AbilityId.GLUTTONY, AbilityId.FLASH_FIRE, AbilityId.WHITE_SMOKE, 484, 85, 97, 66, 105, 66, 65, 90, 50, 169, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DURANT, 5, false, false, false, "Iron Ant Pokémon", PokemonType.BUG, PokemonType.STEEL, 0.3, 33, AbilityId.SWARM, AbilityId.HUSTLE, AbilityId.TRUANT, 484, 58, 109, 112, 48, 48, 109, 90, 50, 169, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DEINO, 5, false, false, false, "Irate Pokémon", PokemonType.DARK, PokemonType.DRAGON, 0.8, 17.3, AbilityId.HUSTLE, AbilityId.NONE, AbilityId.NONE, 300, 52, 65, 50, 45, 50, 38, 45, 35, 60, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.ZWEILOUS, 5, false, false, false, "Hostile Pokémon", PokemonType.DARK, PokemonType.DRAGON, 1.4, 50, AbilityId.HUSTLE, AbilityId.NONE, AbilityId.NONE, 420, 72, 85, 70, 65, 70, 58, 45, 35, 147, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.HYDREIGON, 5, false, false, false, "Brutal Pokémon", PokemonType.DARK, PokemonType.DRAGON, 1.8, 160, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 600, 92, 105, 90, 125, 90, 98, 45, 35, 300, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.LARVESTA, 5, false, false, false, "Torch Pokémon", PokemonType.BUG, PokemonType.FIRE, 1.1, 28.8, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.SWARM, 360, 55, 85, 55, 50, 55, 60, 45, 50, 72, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.VOLCARONA, 5, false, false, false, "Sun Pokémon", PokemonType.BUG, PokemonType.FIRE, 1.6, 46, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.SWARM, 550, 85, 60, 65, 135, 105, 100, 15, 50, 275, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.COBALION, 5, true, false, false, "Iron Will Pokémon", PokemonType.STEEL, PokemonType.FIGHTING, 2.1, 250, AbilityId.JUSTIFIED, AbilityId.NONE, AbilityId.NONE, 580, 91, 90, 129, 90, 72, 108, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.TERRAKION, 5, true, false, false, "Cavern Pokémon", PokemonType.ROCK, PokemonType.FIGHTING, 1.9, 260, AbilityId.JUSTIFIED, AbilityId.NONE, AbilityId.NONE, 580, 91, 129, 90, 72, 90, 108, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.VIRIZION, 5, true, false, false, "Grassland Pokémon", PokemonType.GRASS, PokemonType.FIGHTING, 2, 200, AbilityId.JUSTIFIED, AbilityId.NONE, AbilityId.NONE, 580, 91, 90, 72, 90, 129, 108, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.TORNADUS, 5, true, false, false, "Cyclone Pokémon", PokemonType.FLYING, null, 1.5, 63, AbilityId.PRANKSTER, AbilityId.NONE, AbilityId.DEFIANT, 580, 79, 115, 70, 125, 80, 111, 3, 90, 290, GrowthRate.SLOW, 100, false, true, - new PokemonForm("Incarnate Forme", "incarnate", PokemonType.FLYING, null, 1.5, 63, AbilityId.PRANKSTER, AbilityId.NONE, AbilityId.DEFIANT, 580, 79, 115, 70, 125, 80, 111, 3, 90, 290, false, null, true), - new PokemonForm("Therian Forme", "therian", PokemonType.FLYING, null, 1.4, 63, AbilityId.REGENERATOR, AbilityId.NONE, AbilityId.REGENERATOR, 580, 79, 100, 80, 110, 90, 121, 3, 90, 290), - ), - new PokemonSpecies(SpeciesId.THUNDURUS, 5, true, false, false, "Bolt Strike Pokémon", PokemonType.ELECTRIC, PokemonType.FLYING, 1.5, 61, AbilityId.PRANKSTER, AbilityId.NONE, AbilityId.DEFIANT, 580, 79, 115, 70, 125, 80, 111, 3, 90, 290, GrowthRate.SLOW, 100, false, true, - new PokemonForm("Incarnate Forme", "incarnate", PokemonType.ELECTRIC, PokemonType.FLYING, 1.5, 61, AbilityId.PRANKSTER, AbilityId.NONE, AbilityId.DEFIANT, 580, 79, 115, 70, 125, 80, 111, 3, 90, 290, false, null, true), - new PokemonForm("Therian Forme", "therian", PokemonType.ELECTRIC, PokemonType.FLYING, 3, 61, AbilityId.VOLT_ABSORB, AbilityId.NONE, AbilityId.VOLT_ABSORB, 580, 79, 105, 70, 145, 80, 101, 3, 90, 290), - ), - new PokemonSpecies(SpeciesId.RESHIRAM, 5, false, true, false, "Vast White Pokémon", PokemonType.DRAGON, PokemonType.FIRE, 3.2, 330, AbilityId.TURBOBLAZE, AbilityId.NONE, AbilityId.NONE, 680, 100, 120, 100, 150, 120, 90, 3, 0, 340, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.ZEKROM, 5, false, true, false, "Deep Black Pokémon", PokemonType.DRAGON, PokemonType.ELECTRIC, 2.9, 345, AbilityId.TERAVOLT, AbilityId.NONE, AbilityId.NONE, 680, 100, 150, 120, 120, 100, 90, 3, 0, 340, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.LANDORUS, 5, true, false, false, "Abundance Pokémon", PokemonType.GROUND, PokemonType.FLYING, 1.5, 68, AbilityId.SAND_FORCE, AbilityId.NONE, AbilityId.SHEER_FORCE, 600, 89, 125, 90, 115, 80, 101, 3, 90, 300, GrowthRate.SLOW, 100, false, true, - new PokemonForm("Incarnate Forme", "incarnate", PokemonType.GROUND, PokemonType.FLYING, 1.5, 68, AbilityId.SAND_FORCE, AbilityId.NONE, AbilityId.SHEER_FORCE, 600, 89, 125, 90, 115, 80, 101, 3, 90, 300, false, null, true), - new PokemonForm("Therian Forme", "therian", PokemonType.GROUND, PokemonType.FLYING, 1.3, 68, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.INTIMIDATE, 600, 89, 145, 90, 105, 80, 91, 3, 90, 300), - ), - new PokemonSpecies(SpeciesId.KYUREM, 5, false, true, false, "Boundary Pokémon", PokemonType.DRAGON, PokemonType.ICE, 3, 325, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 660, 125, 130, 90, 130, 90, 95, 3, 0, 330, GrowthRate.SLOW, null, false, true, - new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.ICE, 3, 325, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 660, 125, 130, 90, 130, 90, 95, 3, 0, 330, false, null, true), - new PokemonForm("Black", "black", PokemonType.DRAGON, PokemonType.ICE, 3.3, 325, AbilityId.TERAVOLT, AbilityId.NONE, AbilityId.NONE, 700, 125, 170, 100, 120, 90, 95, 3, 0, 350), - new PokemonForm("White", "white", PokemonType.DRAGON, PokemonType.ICE, 3.6, 325, AbilityId.TURBOBLAZE, AbilityId.NONE, AbilityId.NONE, 700, 125, 120, 90, 170, 100, 95, 3, 0, 350), - ), - new PokemonSpecies(SpeciesId.KELDEO, 5, false, false, true, "Colt Pokémon", PokemonType.WATER, PokemonType.FIGHTING, 1.4, 48.5, AbilityId.JUSTIFIED, AbilityId.NONE, AbilityId.NONE, 580, 91, 72, 90, 129, 90, 108, 3, 35, 290, GrowthRate.SLOW, null, false, true, - new PokemonForm("Ordinary Form", "ordinary", PokemonType.WATER, PokemonType.FIGHTING, 1.4, 48.5, AbilityId.JUSTIFIED, AbilityId.NONE, AbilityId.NONE, 580, 91, 72, 90, 129, 90, 108, 3, 35, 290, false, null, true), - new PokemonForm("Resolute", "resolute", PokemonType.WATER, PokemonType.FIGHTING, 1.4, 48.5, AbilityId.JUSTIFIED, AbilityId.NONE, AbilityId.NONE, 580, 91, 72, 90, 129, 90, 108, 3, 35, 290), - ), - new PokemonSpecies(SpeciesId.MELOETTA, 5, false, false, true, "Melody Pokémon", PokemonType.NORMAL, PokemonType.PSYCHIC, 0.6, 6.5, AbilityId.SERENE_GRACE, AbilityId.NONE, AbilityId.NONE, 600, 100, 77, 77, 128, 128, 90, 3, 100, 300, GrowthRate.SLOW, null, false, true, - new PokemonForm("Aria Forme", "aria", PokemonType.NORMAL, PokemonType.PSYCHIC, 0.6, 6.5, AbilityId.SERENE_GRACE, AbilityId.NONE, AbilityId.NONE, 600, 100, 77, 77, 128, 128, 90, 3, 100, 300, false, null, true), - new PokemonForm("Pirouette Forme", "pirouette", PokemonType.NORMAL, PokemonType.FIGHTING, 0.6, 6.5, AbilityId.SERENE_GRACE, AbilityId.NONE, AbilityId.NONE, 600, 100, 128, 90, 77, 77, 128, 3, 100, 300, false, null, true), - ), - new PokemonSpecies(SpeciesId.GENESECT, 5, false, false, true, "Paleozoic Pokémon", PokemonType.BUG, PokemonType.STEEL, 1.5, 82.5, AbilityId.DOWNLOAD, AbilityId.NONE, AbilityId.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300, GrowthRate.SLOW, null, false, true, - new PokemonForm("Normal", "", PokemonType.BUG, PokemonType.STEEL, 1.5, 82.5, AbilityId.DOWNLOAD, AbilityId.NONE, AbilityId.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300, false, null, true), - new PokemonForm("Shock Drive", "shock", PokemonType.BUG, PokemonType.STEEL, 1.5, 82.5, AbilityId.DOWNLOAD, AbilityId.NONE, AbilityId.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300), - new PokemonForm("Burn Drive", "burn", PokemonType.BUG, PokemonType.STEEL, 1.5, 82.5, AbilityId.DOWNLOAD, AbilityId.NONE, AbilityId.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300), - new PokemonForm("Chill Drive", "chill", PokemonType.BUG, PokemonType.STEEL, 1.5, 82.5, AbilityId.DOWNLOAD, AbilityId.NONE, AbilityId.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300), - new PokemonForm("Douse Drive", "douse", PokemonType.BUG, PokemonType.STEEL, 1.5, 82.5, AbilityId.DOWNLOAD, AbilityId.NONE, AbilityId.NONE, 600, 71, 120, 95, 120, 95, 99, 3, 0, 300), - ), - new PokemonSpecies(SpeciesId.CHESPIN, 6, false, false, false, "Spiny Nut Pokémon", PokemonType.GRASS, null, 0.4, 9, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.BULLETPROOF, 313, 56, 61, 65, 48, 45, 38, 45, 70, 63, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.QUILLADIN, 6, false, false, false, "Spiny Armor Pokémon", PokemonType.GRASS, null, 0.7, 29, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.BULLETPROOF, 405, 61, 78, 95, 56, 58, 57, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.CHESNAUGHT, 6, false, false, false, "Spiny Armor Pokémon", PokemonType.GRASS, PokemonType.FIGHTING, 1.6, 90, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.BULLETPROOF, 530, 88, 107, 122, 74, 75, 64, 45, 70, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.FENNEKIN, 6, false, false, false, "Fox Pokémon", PokemonType.FIRE, null, 0.4, 9.4, AbilityId.BLAZE, AbilityId.NONE, AbilityId.MAGICIAN, 307, 40, 45, 40, 62, 60, 60, 45, 70, 61, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.BRAIXEN, 6, false, false, false, "Fox Pokémon", PokemonType.FIRE, null, 1, 14.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.MAGICIAN, 409, 59, 59, 58, 90, 70, 73, 45, 70, 143, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.DELPHOX, 6, false, false, false, "Fox Pokémon", PokemonType.FIRE, PokemonType.PSYCHIC, 1.5, 39, AbilityId.BLAZE, AbilityId.NONE, AbilityId.MAGICIAN, 534, 75, 69, 72, 114, 100, 104, 45, 70, 267, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.FROAKIE, 6, false, false, false, "Bubble Frog Pokémon", PokemonType.WATER, null, 0.3, 7, AbilityId.TORRENT, AbilityId.NONE, AbilityId.PROTEAN, 314, 41, 56, 40, 62, 44, 71, 45, 70, 63, GrowthRate.MEDIUM_SLOW, 87.5, false, false, - new PokemonForm("Normal", "", PokemonType.WATER, null, 0.3, 7, AbilityId.TORRENT, AbilityId.NONE, AbilityId.PROTEAN, 314, 41, 56, 40, 62, 44, 71, 45, 70, 63, false, null, true), - new PokemonForm("Battle Bond", "battle-bond", PokemonType.WATER, null, 0.3, 7, AbilityId.TORRENT, AbilityId.NONE, AbilityId.TORRENT, 314, 41, 56, 40, 62, 44, 71, 45, 70, 63, false, "", true), - ), - new PokemonSpecies(SpeciesId.FROGADIER, 6, false, false, false, "Bubble Frog Pokémon", PokemonType.WATER, null, 0.6, 10.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.PROTEAN, 405, 54, 63, 52, 83, 56, 97, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false, false, - new PokemonForm("Normal", "", PokemonType.WATER, null, 0.6, 10.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.PROTEAN, 405, 54, 63, 52, 83, 56, 97, 45, 70, 142, false, null, true), - new PokemonForm("Battle Bond", "battle-bond", PokemonType.WATER, null, 0.6, 10.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.NONE, 405, 54, 63, 52, 83, 56, 97, 45, 70, 142, false, "", true), - ), - new PokemonSpecies(SpeciesId.GRENINJA, 6, false, false, false, "Ninja Pokémon", PokemonType.WATER, PokemonType.DARK, 1.5, 40, AbilityId.TORRENT, AbilityId.NONE, AbilityId.PROTEAN, 530, 72, 95, 67, 103, 71, 122, 45, 70, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, false, - new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.DARK, 1.5, 40, AbilityId.TORRENT, AbilityId.NONE, AbilityId.PROTEAN, 530, 72, 95, 67, 103, 71, 122, 45, 70, 265, false, null, true), - new PokemonForm("Battle Bond", "battle-bond", PokemonType.WATER, PokemonType.DARK, 1.5, 40, AbilityId.BATTLE_BOND, AbilityId.NONE, AbilityId.BATTLE_BOND, 530, 72, 95, 67, 103, 71, 122, 45, 70, 265, false, "", true), - new PokemonForm("Ash", "ash", PokemonType.WATER, PokemonType.DARK, 1.5, 40, AbilityId.BATTLE_BOND, AbilityId.NONE, AbilityId.NONE, 640, 72, 145, 67, 153, 71, 132, 45, 70, 265), - ), - new PokemonSpecies(SpeciesId.BUNNELBY, 6, false, false, false, "Digging Pokémon", PokemonType.NORMAL, null, 0.4, 5, AbilityId.PICKUP, AbilityId.CHEEK_POUCH, AbilityId.HUGE_POWER, 237, 38, 36, 38, 32, 36, 57, 255, 50, 47, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DIGGERSBY, 6, false, false, false, "Digging Pokémon", PokemonType.NORMAL, PokemonType.GROUND, 1, 42.4, AbilityId.PICKUP, AbilityId.CHEEK_POUCH, AbilityId.HUGE_POWER, 423, 85, 56, 77, 50, 77, 78, 127, 50, 148, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.FLETCHLING, 6, false, false, false, "Tiny Robin Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 1.7, AbilityId.BIG_PECKS, AbilityId.NONE, AbilityId.GALE_WINGS, 278, 45, 50, 43, 40, 38, 62, 255, 50, 56, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.FLETCHINDER, 6, false, false, false, "Ember Pokémon", PokemonType.FIRE, PokemonType.FLYING, 0.7, 16, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.GALE_WINGS, 382, 62, 73, 55, 56, 52, 84, 120, 50, 134, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.TALONFLAME, 6, false, false, false, "Scorching Pokémon", PokemonType.FIRE, PokemonType.FLYING, 1.2, 24.5, AbilityId.FLAME_BODY, AbilityId.NONE, AbilityId.GALE_WINGS, 499, 78, 81, 71, 74, 69, 126, 45, 50, 175, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SCATTERBUG, 6, false, false, false, "Scatterdust Pokémon", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Meadow Pattern", "meadow", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Icy Snow Pattern", "icy-snow", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Polar Pattern", "polar", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Tundra Pattern", "tundra", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Continental Pattern", "continental", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Garden Pattern", "garden", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Elegant Pattern", "elegant", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Modern Pattern", "modern", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Marine Pattern", "marine", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Archipelago Pattern", "archipelago", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("High Plains Pattern", "high-plains", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Sandstorm Pattern", "sandstorm", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("River Pattern", "river", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Monsoon Pattern", "monsoon", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Savanna Pattern", "savanna", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Sun Pattern", "sun", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Ocean Pattern", "ocean", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Jungle Pattern", "jungle", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Fancy Pattern", "fancy", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - new PokemonForm("Poké Ball Pattern", "poke-ball", PokemonType.BUG, null, 0.3, 2.5, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 200, 38, 35, 40, 27, 25, 35, 255, 70, 40, false, "", true), - ), - new PokemonSpecies(SpeciesId.SPEWPA, 6, false, false, false, "Scatterdust Pokémon", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.SHED_SKIN, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Meadow Pattern", "meadow", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Icy Snow Pattern", "icy-snow", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Polar Pattern", "polar", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Tundra Pattern", "tundra", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Continental Pattern", "continental", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Garden Pattern", "garden", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Elegant Pattern", "elegant", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Modern Pattern", "modern", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Marine Pattern", "marine", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Archipelago Pattern", "archipelago", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("High Plains Pattern", "high-plains", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Sandstorm Pattern", "sandstorm", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("River Pattern", "river", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Monsoon Pattern", "monsoon", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Savanna Pattern", "savanna", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Sun Pattern", "sun", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Ocean Pattern", "ocean", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Jungle Pattern", "jungle", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Fancy Pattern", "fancy", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - new PokemonForm("Poké Ball Pattern", "poke-ball", PokemonType.BUG, null, 0.3, 8.4, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.FRIEND_GUARD, 213, 45, 22, 60, 27, 30, 29, 120, 70, 75, false, "", true), - ), - new PokemonSpecies(SpeciesId.VIVILLON, 6, false, false, false, "Scale Pokémon", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Meadow Pattern", "meadow", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Icy Snow Pattern", "icy-snow", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Polar Pattern", "polar", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Tundra Pattern", "tundra", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Continental Pattern", "continental", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Garden Pattern", "garden", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Elegant Pattern", "elegant", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Modern Pattern", "modern", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Marine Pattern", "marine", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Archipelago Pattern", "archipelago", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("High Plains Pattern", "high-plains", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Sandstorm Pattern", "sandstorm", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("River Pattern", "river", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Monsoon Pattern", "monsoon", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Savanna Pattern", "savanna", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Sun Pattern", "sun", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Ocean Pattern", "ocean", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Jungle Pattern", "jungle", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Fancy Pattern", "fancy", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - new PokemonForm("Poké Ball Pattern", "poke-ball", PokemonType.BUG, PokemonType.FLYING, 1.2, 17, AbilityId.SHIELD_DUST, AbilityId.COMPOUND_EYES, AbilityId.FRIEND_GUARD, 411, 80, 52, 50, 90, 50, 89, 45, 70, 206, false, null, true), - ), - new PokemonSpecies(SpeciesId.LITLEO, 6, false, false, false, "Lion Cub Pokémon", PokemonType.FIRE, PokemonType.NORMAL, 0.6, 13.5, AbilityId.RIVALRY, AbilityId.UNNERVE, AbilityId.MOXIE, 369, 62, 50, 58, 73, 54, 72, 220, 70, 74, GrowthRate.MEDIUM_SLOW, 12.5, false), - new PokemonSpecies(SpeciesId.PYROAR, 6, false, false, false, "Royal Pokémon", PokemonType.FIRE, PokemonType.NORMAL, 1.5, 81.5, AbilityId.RIVALRY, AbilityId.UNNERVE, AbilityId.MOXIE, 507, 86, 68, 72, 109, 66, 106, 65, 70, 177, GrowthRate.MEDIUM_SLOW, 12.5, true), - new PokemonSpecies(SpeciesId.FLABEBE, 6, false, false, false, "Single Bloom Pokémon", PokemonType.FAIRY, null, 0.1, 0.1, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 303, 44, 38, 39, 61, 79, 42, 225, 70, 61, GrowthRate.MEDIUM_FAST, 0, false, false, - new PokemonForm("Red Flower", "red", PokemonType.FAIRY, null, 0.1, 0.1, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 303, 44, 38, 39, 61, 79, 42, 225, 70, 61, false, null, true), - new PokemonForm("Yellow Flower", "yellow", PokemonType.FAIRY, null, 0.1, 0.1, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 303, 44, 38, 39, 61, 79, 42, 225, 70, 61, false, null, true), - new PokemonForm("Orange Flower", "orange", PokemonType.FAIRY, null, 0.1, 0.1, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 303, 44, 38, 39, 61, 79, 42, 225, 70, 61, false, null, true), - new PokemonForm("Blue Flower", "blue", PokemonType.FAIRY, null, 0.1, 0.1, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 303, 44, 38, 39, 61, 79, 42, 225, 70, 61, false, null, true), - new PokemonForm("White Flower", "white", PokemonType.FAIRY, null, 0.1, 0.1, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 303, 44, 38, 39, 61, 79, 42, 225, 70, 61, false, null, true), - ), - new PokemonSpecies(SpeciesId.FLOETTE, 6, false, false, false, "Single Bloom Pokémon", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 371, 54, 45, 47, 75, 98, 52, 120, 70, 130, GrowthRate.MEDIUM_FAST, 0, false, false, - new PokemonForm("Red Flower", "red", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 371, 54, 45, 47, 75, 98, 52, 120, 70, 130, false, null, true), - new PokemonForm("Yellow Flower", "yellow", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 371, 54, 45, 47, 75, 98, 52, 120, 70, 130, false, null, true), - new PokemonForm("Orange Flower", "orange", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 371, 54, 45, 47, 75, 98, 52, 120, 70, 130, false, null, true), - new PokemonForm("Blue Flower", "blue", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 371, 54, 45, 47, 75, 98, 52, 120, 70, 130, false, null, true), - new PokemonForm("White Flower", "white", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 371, 54, 45, 47, 75, 98, 52, 120, 70, 130, false, null, true), - ), - new PokemonSpecies(SpeciesId.FLORGES, 6, false, false, false, "Garden Pokémon", PokemonType.FAIRY, null, 1.1, 10, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 552, 78, 65, 68, 112, 154, 75, 45, 70, 276, GrowthRate.MEDIUM_FAST, 0, false, false, - new PokemonForm("Red Flower", "red", PokemonType.FAIRY, null, 1.1, 10, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 552, 78, 65, 68, 112, 154, 75, 45, 70, 276, false, null, true), - new PokemonForm("Yellow Flower", "yellow", PokemonType.FAIRY, null, 1.1, 10, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 552, 78, 65, 68, 112, 154, 75, 45, 70, 276, false, null, true), - new PokemonForm("Orange Flower", "orange", PokemonType.FAIRY, null, 1.1, 10, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 552, 78, 65, 68, 112, 154, 75, 45, 70, 276, false, null, true), - new PokemonForm("Blue Flower", "blue", PokemonType.FAIRY, null, 1.1, 10, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 552, 78, 65, 68, 112, 154, 75, 45, 70, 276, false, null, true), - new PokemonForm("White Flower", "white", PokemonType.FAIRY, null, 1.1, 10, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 552, 78, 65, 68, 112, 154, 75, 45, 70, 276, false, null, true), - ), - new PokemonSpecies(SpeciesId.SKIDDO, 6, false, false, false, "Mount Pokémon", PokemonType.GRASS, null, 0.9, 31, AbilityId.SAP_SIPPER, AbilityId.NONE, AbilityId.GRASS_PELT, 350, 66, 65, 48, 62, 57, 52, 200, 70, 70, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GOGOAT, 6, false, false, false, "Mount Pokémon", PokemonType.GRASS, null, 1.7, 91, AbilityId.SAP_SIPPER, AbilityId.NONE, AbilityId.GRASS_PELT, 531, 123, 100, 62, 97, 81, 68, 45, 70, 186, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PANCHAM, 6, false, false, false, "Playful Pokémon", PokemonType.FIGHTING, null, 0.6, 8, AbilityId.IRON_FIST, AbilityId.MOLD_BREAKER, AbilityId.SCRAPPY, 348, 67, 82, 62, 46, 48, 43, 220, 50, 70, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PANGORO, 6, false, false, false, "Daunting Pokémon", PokemonType.FIGHTING, PokemonType.DARK, 2.1, 136, AbilityId.IRON_FIST, AbilityId.MOLD_BREAKER, AbilityId.SCRAPPY, 495, 95, 124, 78, 69, 71, 58, 65, 50, 173, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.FURFROU, 6, false, false, false, "Poodle Pokémon", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Natural Form", "", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), - new PokemonForm("Heart Trim", "heart", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), - new PokemonForm("Star Trim", "star", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), - new PokemonForm("Diamond Trim", "diamond", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), - new PokemonForm("Debutante Trim", "debutante", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), - new PokemonForm("Matron Trim", "matron", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), - new PokemonForm("Dandy Trim", "dandy", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), - new PokemonForm("La Reine Trim", "la-reine", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), - new PokemonForm("Kabuki Trim", "kabuki", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), - new PokemonForm("Pharaoh Trim", "pharaoh", PokemonType.NORMAL, null, 1.2, 28, AbilityId.FUR_COAT, AbilityId.NONE, AbilityId.NONE, 472, 75, 80, 60, 65, 90, 102, 160, 70, 165, false, null, true), - ), - new PokemonSpecies(SpeciesId.ESPURR, 6, false, false, false, "Restraint Pokémon", PokemonType.PSYCHIC, null, 0.3, 3.5, AbilityId.KEEN_EYE, AbilityId.INFILTRATOR, AbilityId.OWN_TEMPO, 355, 62, 48, 54, 63, 60, 68, 190, 50, 71, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MEOWSTIC, 6, false, false, false, "Constraint Pokémon", PokemonType.PSYCHIC, null, 0.6, 8.5, AbilityId.KEEN_EYE, AbilityId.INFILTRATOR, AbilityId.PRANKSTER, 466, 74, 48, 76, 83, 81, 104, 75, 50, 163, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Male", "male", PokemonType.PSYCHIC, null, 0.6, 8.5, AbilityId.KEEN_EYE, AbilityId.INFILTRATOR, AbilityId.PRANKSTER, 466, 74, 48, 76, 83, 81, 104, 75, 50, 163, false, "", true), - new PokemonForm("Female", "female", PokemonType.PSYCHIC, null, 0.6, 8.5, AbilityId.KEEN_EYE, AbilityId.INFILTRATOR, AbilityId.COMPETITIVE, 466, 74, 48, 76, 83, 81, 104, 75, 50, 163, false, null, true), - ), - new PokemonSpecies(SpeciesId.HONEDGE, 6, false, false, false, "Sword Pokémon", PokemonType.STEEL, PokemonType.GHOST, 0.8, 2, AbilityId.NO_GUARD, AbilityId.NONE, AbilityId.NONE, 325, 45, 80, 100, 35, 37, 28, 180, 50, 65, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DOUBLADE, 6, false, false, false, "Sword Pokémon", PokemonType.STEEL, PokemonType.GHOST, 0.8, 4.5, AbilityId.NO_GUARD, AbilityId.NONE, AbilityId.NONE, 448, 59, 110, 150, 45, 49, 35, 90, 50, 157, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.AEGISLASH, 6, false, false, false, "Royal Sword Pokémon", PokemonType.STEEL, PokemonType.GHOST, 1.7, 53, AbilityId.STANCE_CHANGE, AbilityId.NONE, AbilityId.NONE, 500, 60, 50, 140, 50, 140, 60, 45, 50, 250, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Shield Forme", "shield", PokemonType.STEEL, PokemonType.GHOST, 1.7, 53, AbilityId.STANCE_CHANGE, AbilityId.NONE, AbilityId.NONE, 500, 60, 50, 140, 50, 140, 60, 45, 50, 250, false, "", true), - new PokemonForm("Blade Forme", "blade", PokemonType.STEEL, PokemonType.GHOST, 1.7, 53, AbilityId.STANCE_CHANGE, AbilityId.NONE, AbilityId.NONE, 500, 60, 140, 50, 140, 50, 60, 45, 50, 250), - ), - new PokemonSpecies(SpeciesId.SPRITZEE, 6, false, false, false, "Perfume Pokémon", PokemonType.FAIRY, null, 0.2, 0.5, AbilityId.HEALER, AbilityId.NONE, AbilityId.AROMA_VEIL, 341, 78, 52, 60, 63, 65, 23, 200, 50, 68, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.AROMATISSE, 6, false, false, false, "Fragrance Pokémon", PokemonType.FAIRY, null, 0.8, 15.5, AbilityId.HEALER, AbilityId.NONE, AbilityId.AROMA_VEIL, 462, 101, 72, 72, 99, 89, 29, 140, 50, 162, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SWIRLIX, 6, false, false, false, "Cotton Candy Pokémon", PokemonType.FAIRY, null, 0.4, 3.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.UNBURDEN, 341, 62, 48, 66, 59, 57, 49, 200, 50, 68, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SLURPUFF, 6, false, false, false, "Meringue Pokémon", PokemonType.FAIRY, null, 0.8, 5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.UNBURDEN, 480, 82, 80, 86, 85, 75, 72, 140, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.INKAY, 6, false, false, false, "Revolving Pokémon", PokemonType.DARK, PokemonType.PSYCHIC, 0.4, 3.5, AbilityId.CONTRARY, AbilityId.SUCTION_CUPS, AbilityId.INFILTRATOR, 288, 53, 54, 53, 37, 46, 45, 190, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MALAMAR, 6, false, false, false, "Overturning Pokémon", PokemonType.DARK, PokemonType.PSYCHIC, 1.5, 47, AbilityId.CONTRARY, AbilityId.SUCTION_CUPS, AbilityId.INFILTRATOR, 482, 86, 92, 88, 68, 75, 73, 80, 50, 169, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BINACLE, 6, false, false, false, "Two-Handed Pokémon", PokemonType.ROCK, PokemonType.WATER, 0.5, 31, AbilityId.TOUGH_CLAWS, AbilityId.SNIPER, AbilityId.PICKPOCKET, 306, 42, 52, 67, 39, 56, 50, 120, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BARBARACLE, 6, false, false, false, "Collective Pokémon", PokemonType.ROCK, PokemonType.WATER, 1.3, 96, AbilityId.TOUGH_CLAWS, AbilityId.SNIPER, AbilityId.PICKPOCKET, 500, 72, 105, 115, 54, 86, 68, 45, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SKRELP, 6, false, false, false, "Mock Kelp Pokémon", PokemonType.POISON, PokemonType.WATER, 0.5, 7.3, AbilityId.POISON_POINT, AbilityId.POISON_TOUCH, AbilityId.ADAPTABILITY, 320, 50, 60, 60, 60, 60, 30, 225, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DRAGALGE, 6, false, false, false, "Mock Kelp Pokémon", PokemonType.POISON, PokemonType.DRAGON, 1.8, 81.5, AbilityId.POISON_POINT, AbilityId.POISON_TOUCH, AbilityId.ADAPTABILITY, 494, 65, 75, 90, 97, 123, 44, 55, 50, 173, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CLAUNCHER, 6, false, false, false, "Water Gun Pokémon", PokemonType.WATER, null, 0.5, 8.3, AbilityId.MEGA_LAUNCHER, AbilityId.NONE, AbilityId.NONE, 330, 50, 53, 62, 58, 63, 44, 225, 50, 66, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.CLAWITZER, 6, false, false, false, "Howitzer Pokémon", PokemonType.WATER, null, 1.3, 35.3, AbilityId.MEGA_LAUNCHER, AbilityId.NONE, AbilityId.NONE, 500, 71, 73, 88, 120, 89, 59, 55, 50, 100, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.HELIOPTILE, 6, false, false, false, "Generator Pokémon", PokemonType.ELECTRIC, PokemonType.NORMAL, 0.5, 6, AbilityId.DRY_SKIN, AbilityId.SAND_VEIL, AbilityId.SOLAR_POWER, 289, 44, 38, 33, 61, 43, 70, 190, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.HELIOLISK, 6, false, false, false, "Generator Pokémon", PokemonType.ELECTRIC, PokemonType.NORMAL, 1, 21, AbilityId.DRY_SKIN, AbilityId.SAND_VEIL, AbilityId.SOLAR_POWER, 481, 62, 55, 52, 109, 94, 109, 75, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.TYRUNT, 6, false, false, false, "Royal Heir Pokémon", PokemonType.ROCK, PokemonType.DRAGON, 0.8, 26, AbilityId.STRONG_JAW, AbilityId.NONE, AbilityId.STURDY, 362, 58, 89, 77, 45, 45, 48, 45, 50, 72, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.TYRANTRUM, 6, false, false, false, "Despot Pokémon", PokemonType.ROCK, PokemonType.DRAGON, 2.5, 270, AbilityId.STRONG_JAW, AbilityId.NONE, AbilityId.ROCK_HEAD, 521, 82, 121, 119, 69, 59, 71, 45, 50, 182, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.AMAURA, 6, false, false, false, "Tundra Pokémon", PokemonType.ROCK, PokemonType.ICE, 1.3, 25.2, AbilityId.REFRIGERATE, AbilityId.NONE, AbilityId.SNOW_WARNING, 362, 77, 59, 50, 67, 63, 46, 45, 50, 72, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.AURORUS, 6, false, false, false, "Tundra Pokémon", PokemonType.ROCK, PokemonType.ICE, 2.7, 225, AbilityId.REFRIGERATE, AbilityId.NONE, AbilityId.SNOW_WARNING, 521, 123, 77, 72, 99, 92, 58, 45, 50, 104, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.SYLVEON, 6, false, false, false, "Intertwining Pokémon", PokemonType.FAIRY, null, 1, 23.5, AbilityId.CUTE_CHARM, AbilityId.NONE, AbilityId.PIXILATE, 525, 95, 65, 65, 110, 130, 60, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.HAWLUCHA, 6, false, false, false, "Wrestling Pokémon", PokemonType.FIGHTING, PokemonType.FLYING, 0.8, 21.5, AbilityId.LIMBER, AbilityId.UNBURDEN, AbilityId.MOLD_BREAKER, 500, 78, 92, 75, 74, 63, 118, 100, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DEDENNE, 6, false, false, false, "Antenna Pokémon", PokemonType.ELECTRIC, PokemonType.FAIRY, 0.2, 2.2, AbilityId.CHEEK_POUCH, AbilityId.PICKUP, AbilityId.PLUS, 431, 67, 58, 57, 81, 67, 101, 180, 50, 151, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CARBINK, 6, false, false, false, "Jewel Pokémon", PokemonType.ROCK, PokemonType.FAIRY, 0.3, 5.7, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.STURDY, 500, 50, 50, 150, 50, 150, 50, 60, 50, 100, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.GOOMY, 6, false, false, false, "Soft Tissue Pokémon", PokemonType.DRAGON, null, 0.3, 2.8, AbilityId.SAP_SIPPER, AbilityId.HYDRATION, AbilityId.GOOEY, 300, 45, 50, 35, 55, 75, 40, 45, 35, 60, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.SLIGGOO, 6, false, false, false, "Soft Tissue Pokémon", PokemonType.DRAGON, null, 0.8, 17.5, AbilityId.SAP_SIPPER, AbilityId.HYDRATION, AbilityId.GOOEY, 452, 68, 75, 53, 83, 113, 60, 45, 35, 158, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.GOODRA, 6, false, false, false, "Dragon Pokémon", PokemonType.DRAGON, null, 2, 150.5, AbilityId.SAP_SIPPER, AbilityId.HYDRATION, AbilityId.GOOEY, 600, 90, 100, 70, 110, 150, 80, 45, 35, 300, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.KLEFKI, 6, false, false, false, "Key Ring Pokémon", PokemonType.STEEL, PokemonType.FAIRY, 0.2, 3, AbilityId.PRANKSTER, AbilityId.NONE, AbilityId.MAGICIAN, 470, 57, 80, 91, 80, 87, 75, 75, 50, 165, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.PHANTUMP, 6, false, false, false, "Stump Pokémon", PokemonType.GHOST, PokemonType.GRASS, 0.4, 7, AbilityId.NATURAL_CURE, AbilityId.FRISK, AbilityId.HARVEST, 309, 43, 70, 48, 50, 60, 38, 120, 50, 62, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.TREVENANT, 6, false, false, false, "Elder Tree Pokémon", PokemonType.GHOST, PokemonType.GRASS, 1.5, 71, AbilityId.NATURAL_CURE, AbilityId.FRISK, AbilityId.HARVEST, 474, 85, 110, 76, 65, 82, 56, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PUMPKABOO, 6, false, false, false, "Pumpkin Pokémon", PokemonType.GHOST, PokemonType.GRASS, 0.4, 5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 335, 49, 66, 70, 44, 55, 51, 120, 50, 67, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Average Size", "", PokemonType.GHOST, PokemonType.GRASS, 0.4, 5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 335, 49, 66, 70, 44, 55, 51, 120, 50, 67, false, null, true), - new PokemonForm("Small Size", "small", PokemonType.GHOST, PokemonType.GRASS, 0.3, 3.5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 335, 44, 66, 70, 44, 55, 56, 120, 50, 67, false, "", true), - new PokemonForm("Large Size", "large", PokemonType.GHOST, PokemonType.GRASS, 0.5, 7.5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 335, 54, 66, 70, 44, 55, 46, 120, 50, 67, false, "", true), - new PokemonForm("Super Size", "super", PokemonType.GHOST, PokemonType.GRASS, 0.8, 15, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 335, 59, 66, 70, 44, 55, 41, 120, 50, 67, false, "", true), - ), - new PokemonSpecies(SpeciesId.GOURGEIST, 6, false, false, false, "Pumpkin Pokémon", PokemonType.GHOST, PokemonType.GRASS, 0.9, 12.5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 494, 65, 90, 122, 58, 75, 84, 60, 50, 173, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Average Size", "", PokemonType.GHOST, PokemonType.GRASS, 0.9, 12.5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 494, 65, 90, 122, 58, 75, 84, 60, 50, 173, false, null, true), - new PokemonForm("Small Size", "small", PokemonType.GHOST, PokemonType.GRASS, 0.7, 9.5, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 494, 55, 85, 122, 58, 75, 99, 60, 50, 173, false, "", true), - new PokemonForm("Large Size", "large", PokemonType.GHOST, PokemonType.GRASS, 1.1, 14, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 494, 75, 95, 122, 58, 75, 69, 60, 50, 173, false, "", true), - new PokemonForm("Super Size", "super", PokemonType.GHOST, PokemonType.GRASS, 1.7, 39, AbilityId.PICKUP, AbilityId.FRISK, AbilityId.INSOMNIA, 494, 85, 100, 122, 58, 75, 54, 60, 50, 173, false, "", true), - ), - new PokemonSpecies(SpeciesId.BERGMITE, 6, false, false, false, "Ice Chunk Pokémon", PokemonType.ICE, null, 1, 99.5, AbilityId.OWN_TEMPO, AbilityId.ICE_BODY, AbilityId.STURDY, 304, 55, 69, 85, 32, 35, 28, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.AVALUGG, 6, false, false, false, "Iceberg Pokémon", PokemonType.ICE, null, 2, 505, AbilityId.OWN_TEMPO, AbilityId.ICE_BODY, AbilityId.STURDY, 514, 95, 117, 184, 44, 46, 28, 55, 50, 180, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.NOIBAT, 6, false, false, false, "Sound Wave Pokémon", PokemonType.FLYING, PokemonType.DRAGON, 0.5, 8, AbilityId.FRISK, AbilityId.INFILTRATOR, AbilityId.TELEPATHY, 245, 40, 30, 35, 45, 40, 55, 190, 50, 49, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.NOIVERN, 6, false, false, false, "Sound Wave Pokémon", PokemonType.FLYING, PokemonType.DRAGON, 1.5, 85, AbilityId.FRISK, AbilityId.INFILTRATOR, AbilityId.TELEPATHY, 535, 85, 70, 80, 97, 80, 123, 45, 50, 187, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.XERNEAS, 6, false, true, false, "Life Pokémon", PokemonType.FAIRY, null, 3, 215, AbilityId.FAIRY_AURA, AbilityId.NONE, AbilityId.NONE, 680, 126, 131, 95, 131, 98, 99, 45, 0, 340, GrowthRate.SLOW, null, false, true, - new PokemonForm("Neutral Mode", "neutral", PokemonType.FAIRY, null, 3, 215, AbilityId.FAIRY_AURA, AbilityId.NONE, AbilityId.NONE, 680, 126, 131, 95, 131, 98, 99, 45, 0, 340, false, null, true), - new PokemonForm("Active Mode", "active", PokemonType.FAIRY, null, 3, 215, AbilityId.FAIRY_AURA, AbilityId.NONE, AbilityId.NONE, 680, 126, 131, 95, 131, 98, 99, 45, 0, 340) - ), - new PokemonSpecies(SpeciesId.YVELTAL, 6, false, true, false, "Destruction Pokémon", PokemonType.DARK, PokemonType.FLYING, 5.8, 203, AbilityId.DARK_AURA, AbilityId.NONE, AbilityId.NONE, 680, 126, 131, 95, 131, 98, 99, 45, 0, 340, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.ZYGARDE, 6, false, true, false, "Order Pokémon", PokemonType.DRAGON, PokemonType.GROUND, 5, 305, AbilityId.AURA_BREAK, AbilityId.NONE, AbilityId.NONE, 600, 108, 100, 121, 81, 95, 95, 3, 0, 300, GrowthRate.SLOW, null, false, false, - new PokemonForm("50% Forme", "50", PokemonType.DRAGON, PokemonType.GROUND, 5, 305, AbilityId.AURA_BREAK, AbilityId.NONE, AbilityId.NONE, 600, 108, 100, 121, 81, 95, 95, 3, 0, 300, false, "", true), - new PokemonForm("10% Forme", "10", PokemonType.DRAGON, PokemonType.GROUND, 1.2, 33.5, AbilityId.AURA_BREAK, AbilityId.NONE, AbilityId.NONE, 486, 54, 100, 71, 61, 85, 115, 3, 0, 243, false, null, true), - new PokemonForm("50% Forme Power Construct", "50-pc", PokemonType.DRAGON, PokemonType.GROUND, 5, 305, AbilityId.POWER_CONSTRUCT, AbilityId.NONE, AbilityId.NONE, 600, 108, 100, 121, 81, 95, 95, 3, 0, 300, false, "", true), - new PokemonForm("10% Forme Power Construct", "10-pc", PokemonType.DRAGON, PokemonType.GROUND, 1.2, 33.5, AbilityId.POWER_CONSTRUCT, AbilityId.NONE, AbilityId.NONE, 486, 54, 100, 71, 61, 85, 115, 3, 0, 243, false, "10", true), - new PokemonForm("Complete Forme (50% PC)", "complete", PokemonType.DRAGON, PokemonType.GROUND, 4.5, 610, AbilityId.POWER_CONSTRUCT, AbilityId.NONE, AbilityId.NONE, 708, 216, 100, 121, 91, 95, 85, 3, 0, 354), - new PokemonForm("Complete Forme (10% PC)", "10-complete", PokemonType.DRAGON, PokemonType.GROUND, 4.5, 610, AbilityId.POWER_CONSTRUCT, AbilityId.NONE, AbilityId.NONE, 708, 216, 100, 121, 91, 95, 85, 3, 0, 354, false, "complete"), - ), - new PokemonSpecies(SpeciesId.DIANCIE, 6, false, false, true, "Jewel Pokémon", PokemonType.ROCK, PokemonType.FAIRY, 0.7, 8.8, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.NONE, 600, 50, 100, 150, 100, 150, 50, 3, 50, 300, GrowthRate.SLOW, null, false, true, - new PokemonForm("Normal", "", PokemonType.ROCK, PokemonType.FAIRY, 0.7, 8.8, AbilityId.CLEAR_BODY, AbilityId.NONE, AbilityId.NONE, 600, 50, 100, 150, 100, 150, 50, 3, 50, 300, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.ROCK, PokemonType.FAIRY, 1.1, 27.8, AbilityId.MAGIC_BOUNCE, AbilityId.NONE, AbilityId.NONE, 700, 50, 160, 110, 160, 110, 110, 3, 50, 300), - ), - new PokemonSpecies(SpeciesId.HOOPA, 6, false, false, true, "Mischief Pokémon", PokemonType.PSYCHIC, PokemonType.GHOST, 0.5, 9, AbilityId.MAGICIAN, AbilityId.NONE, AbilityId.NONE, 600, 80, 110, 60, 150, 130, 70, 3, 100, 300, GrowthRate.SLOW, null, false, false, - new PokemonForm("Hoopa Confined", "", PokemonType.PSYCHIC, PokemonType.GHOST, 0.5, 9, AbilityId.MAGICIAN, AbilityId.NONE, AbilityId.NONE, 600, 80, 110, 60, 150, 130, 70, 3, 100, 300, false, null, true), - new PokemonForm("Hoopa Unbound", "unbound", PokemonType.PSYCHIC, PokemonType.DARK, 6.5, 490, AbilityId.MAGICIAN, AbilityId.NONE, AbilityId.NONE, 680, 80, 160, 60, 170, 130, 80, 3, 100, 340), - ), - new PokemonSpecies(SpeciesId.VOLCANION, 6, false, false, true, "Steam Pokémon", PokemonType.FIRE, PokemonType.WATER, 1.7, 195, AbilityId.WATER_ABSORB, AbilityId.NONE, AbilityId.NONE, 600, 80, 110, 120, 130, 90, 70, 3, 100, 300, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.ROWLET, 7, false, false, false, "Grass Quill Pokémon", PokemonType.GRASS, PokemonType.FLYING, 0.3, 1.5, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.LONG_REACH, 320, 68, 55, 55, 50, 50, 42, 45, 50, 64, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.DARTRIX, 7, false, false, false, "Blade Quill Pokémon", PokemonType.GRASS, PokemonType.FLYING, 0.7, 16, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.LONG_REACH, 420, 78, 75, 75, 70, 70, 52, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.DECIDUEYE, 7, false, false, false, "Arrow Quill Pokémon", PokemonType.GRASS, PokemonType.GHOST, 1.6, 36.6, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.LONG_REACH, 530, 78, 107, 75, 100, 100, 70, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.LITTEN, 7, false, false, false, "Fire Cat Pokémon", PokemonType.FIRE, null, 0.4, 4.3, AbilityId.BLAZE, AbilityId.NONE, AbilityId.INTIMIDATE, 320, 45, 65, 40, 60, 40, 70, 45, 50, 64, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.TORRACAT, 7, false, false, false, "Fire Cat Pokémon", PokemonType.FIRE, null, 0.7, 25, AbilityId.BLAZE, AbilityId.NONE, AbilityId.INTIMIDATE, 420, 65, 85, 50, 80, 50, 90, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.INCINEROAR, 7, false, false, false, "Heel Pokémon", PokemonType.FIRE, PokemonType.DARK, 1.8, 83, AbilityId.BLAZE, AbilityId.NONE, AbilityId.INTIMIDATE, 530, 95, 115, 90, 80, 90, 60, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.POPPLIO, 7, false, false, false, "Sea Lion Pokémon", PokemonType.WATER, null, 0.4, 7.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.LIQUID_VOICE, 320, 50, 54, 54, 66, 56, 40, 45, 50, 64, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.BRIONNE, 7, false, false, false, "Pop Star Pokémon", PokemonType.WATER, null, 0.6, 17.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.LIQUID_VOICE, 420, 60, 69, 69, 91, 81, 50, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.PRIMARINA, 7, false, false, false, "Soloist Pokémon", PokemonType.WATER, PokemonType.FAIRY, 1.8, 44, AbilityId.TORRENT, AbilityId.NONE, AbilityId.LIQUID_VOICE, 530, 80, 74, 74, 126, 116, 60, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.PIKIPEK, 7, false, false, false, "Woodpecker Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.3, 1.2, AbilityId.KEEN_EYE, AbilityId.SKILL_LINK, AbilityId.PICKUP, 265, 35, 75, 30, 30, 30, 65, 255, 70, 53, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.TRUMBEAK, 7, false, false, false, "Bugle Beak Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 14.8, AbilityId.KEEN_EYE, AbilityId.SKILL_LINK, AbilityId.PICKUP, 355, 55, 85, 50, 40, 50, 75, 120, 70, 124, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.TOUCANNON, 7, false, false, false, "Cannon Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 1.1, 26, AbilityId.KEEN_EYE, AbilityId.SKILL_LINK, AbilityId.SHEER_FORCE, 485, 80, 120, 75, 75, 75, 60, 45, 70, 243, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.YUNGOOS, 7, false, false, false, "Loitering Pokémon", PokemonType.NORMAL, null, 0.4, 6, AbilityId.STAKEOUT, AbilityId.STRONG_JAW, AbilityId.ADAPTABILITY, 253, 48, 70, 30, 30, 30, 45, 255, 70, 51, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GUMSHOOS, 7, false, false, false, "Stakeout Pokémon", PokemonType.NORMAL, null, 0.7, 14.2, AbilityId.STAKEOUT, AbilityId.STRONG_JAW, AbilityId.ADAPTABILITY, 418, 88, 110, 60, 55, 60, 45, 127, 70, 146, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GRUBBIN, 7, false, false, false, "Larva Pokémon", PokemonType.BUG, null, 0.4, 4.4, AbilityId.SWARM, AbilityId.NONE, AbilityId.NONE, 300, 47, 62, 45, 55, 45, 46, 255, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CHARJABUG, 7, false, false, false, "Battery Pokémon", PokemonType.BUG, PokemonType.ELECTRIC, 0.5, 10.5, AbilityId.BATTERY, AbilityId.NONE, AbilityId.NONE, 400, 57, 82, 95, 55, 75, 36, 120, 50, 140, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.VIKAVOLT, 7, false, false, false, "Stag Beetle Pokémon", PokemonType.BUG, PokemonType.ELECTRIC, 1.5, 45, AbilityId.LEVITATE, AbilityId.NONE, AbilityId.NONE, 500, 77, 70, 90, 145, 75, 43, 45, 50, 250, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CRABRAWLER, 7, false, false, false, "Boxing Pokémon", PokemonType.FIGHTING, null, 0.6, 7, AbilityId.HYPER_CUTTER, AbilityId.IRON_FIST, AbilityId.ANGER_POINT, 338, 47, 82, 57, 42, 47, 63, 225, 70, 68, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CRABOMINABLE, 7, false, false, false, "Woolly Crab Pokémon", PokemonType.FIGHTING, PokemonType.ICE, 1.7, 180, AbilityId.HYPER_CUTTER, AbilityId.IRON_FIST, AbilityId.ANGER_POINT, 478, 97, 132, 77, 62, 67, 43, 60, 70, 167, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ORICORIO, 7, false, false, false, "Dancing Pokémon", PokemonType.FIRE, PokemonType.FLYING, 0.6, 3.4, AbilityId.DANCER, AbilityId.NONE, AbilityId.NONE, 476, 75, 70, 70, 98, 70, 93, 45, 70, 167, GrowthRate.MEDIUM_FAST, 25, false, false, - new PokemonForm("Baile Style", "baile", PokemonType.FIRE, PokemonType.FLYING, 0.6, 3.4, AbilityId.DANCER, AbilityId.NONE, AbilityId.NONE, 476, 75, 70, 70, 98, 70, 93, 45, 70, 167, false, "", true), - new PokemonForm("Pom-Pom Style", "pompom", PokemonType.ELECTRIC, PokemonType.FLYING, 0.6, 3.4, AbilityId.DANCER, AbilityId.NONE, AbilityId.NONE, 476, 75, 70, 70, 98, 70, 93, 45, 70, 167, false, null, true), - new PokemonForm("Pau Style", "pau", PokemonType.PSYCHIC, PokemonType.FLYING, 0.6, 3.4, AbilityId.DANCER, AbilityId.NONE, AbilityId.NONE, 476, 75, 70, 70, 98, 70, 93, 45, 70, 167, false, null, true), - new PokemonForm("Sensu Style", "sensu", PokemonType.GHOST, PokemonType.FLYING, 0.6, 3.4, AbilityId.DANCER, AbilityId.NONE, AbilityId.NONE, 476, 75, 70, 70, 98, 70, 93, 45, 70, 167, false, null, true), - ), - new PokemonSpecies(SpeciesId.CUTIEFLY, 7, false, false, false, "Bee Fly Pokémon", PokemonType.BUG, PokemonType.FAIRY, 0.1, 0.2, AbilityId.HONEY_GATHER, AbilityId.SHIELD_DUST, AbilityId.SWEET_VEIL, 304, 40, 45, 40, 55, 40, 84, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.RIBOMBEE, 7, false, false, false, "Bee Fly Pokémon", PokemonType.BUG, PokemonType.FAIRY, 0.2, 0.5, AbilityId.HONEY_GATHER, AbilityId.SHIELD_DUST, AbilityId.SWEET_VEIL, 464, 60, 55, 60, 95, 70, 124, 75, 50, 162, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ROCKRUFF, 7, false, false, false, "Puppy Pokémon", PokemonType.ROCK, null, 0.5, 9.2, AbilityId.KEEN_EYE, AbilityId.VITAL_SPIRIT, AbilityId.STEADFAST, 280, 45, 65, 40, 30, 40, 60, 190, 50, 56, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Normal", "", PokemonType.ROCK, null, 0.5, 9.2, AbilityId.KEEN_EYE, AbilityId.VITAL_SPIRIT, AbilityId.STEADFAST, 280, 45, 65, 40, 30, 40, 60, 190, 50, 56, false, null, true), - new PokemonForm("Own Tempo", "own-tempo", PokemonType.ROCK, null, 0.5, 9.2, AbilityId.OWN_TEMPO, AbilityId.NONE, AbilityId.OWN_TEMPO, 280, 45, 65, 40, 30, 40, 60, 190, 50, 56, false, "", true), - ), - new PokemonSpecies(SpeciesId.LYCANROC, 7, false, false, false, "Wolf Pokémon", PokemonType.ROCK, null, 0.8, 25, AbilityId.KEEN_EYE, AbilityId.SAND_RUSH, AbilityId.STEADFAST, 487, 75, 115, 65, 55, 65, 112, 90, 50, 170, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Midday Form", "midday", PokemonType.ROCK, null, 0.8, 25, AbilityId.KEEN_EYE, AbilityId.SAND_RUSH, AbilityId.STEADFAST, 487, 75, 115, 65, 55, 65, 112, 90, 50, 170, false, "", true), - new PokemonForm("Midnight Form", "midnight", PokemonType.ROCK, null, 1.1, 25, AbilityId.KEEN_EYE, AbilityId.VITAL_SPIRIT, AbilityId.NO_GUARD, 487, 85, 115, 75, 55, 75, 82, 90, 50, 170, false, null, true), - new PokemonForm("Dusk Form", "dusk", PokemonType.ROCK, null, 0.8, 25, AbilityId.TOUGH_CLAWS, AbilityId.TOUGH_CLAWS, AbilityId.TOUGH_CLAWS, 487, 75, 117, 65, 55, 65, 110, 90, 50, 170, false, null, true), - ), - new PokemonSpecies(SpeciesId.WISHIWASHI, 7, false, false, false, "Small Fry Pokémon", PokemonType.WATER, null, 0.2, 0.3, AbilityId.SCHOOLING, AbilityId.NONE, AbilityId.NONE, 175, 45, 20, 20, 25, 25, 40, 60, 50, 61, GrowthRate.FAST, 50, false, false, - new PokemonForm("Solo Form", "", PokemonType.WATER, null, 0.2, 0.3, AbilityId.SCHOOLING, AbilityId.NONE, AbilityId.NONE, 175, 45, 20, 20, 25, 25, 40, 60, 50, 61, false, null, true), - new PokemonForm("School", "school", PokemonType.WATER, null, 8.2, 78.6, AbilityId.SCHOOLING, AbilityId.NONE, AbilityId.NONE, 620, 45, 140, 130, 140, 135, 30, 60, 50, 217), - ), - new PokemonSpecies(SpeciesId.MAREANIE, 7, false, false, false, "Brutal Star Pokémon", PokemonType.POISON, PokemonType.WATER, 0.4, 8, AbilityId.MERCILESS, AbilityId.LIMBER, AbilityId.REGENERATOR, 305, 50, 53, 62, 43, 52, 45, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.TOXAPEX, 7, false, false, false, "Brutal Star Pokémon", PokemonType.POISON, PokemonType.WATER, 0.7, 14.5, AbilityId.MERCILESS, AbilityId.LIMBER, AbilityId.REGENERATOR, 495, 50, 63, 152, 53, 142, 35, 75, 50, 173, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MUDBRAY, 7, false, false, false, "Donkey Pokémon", PokemonType.GROUND, null, 1, 110, AbilityId.OWN_TEMPO, AbilityId.STAMINA, AbilityId.INNER_FOCUS, 385, 70, 100, 70, 45, 55, 45, 190, 50, 77, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MUDSDALE, 7, false, false, false, "Draft Horse Pokémon", PokemonType.GROUND, null, 2.5, 920, AbilityId.OWN_TEMPO, AbilityId.STAMINA, AbilityId.INNER_FOCUS, 500, 100, 125, 100, 55, 85, 35, 60, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DEWPIDER, 7, false, false, false, "Water Bubble Pokémon", PokemonType.WATER, PokemonType.BUG, 0.3, 4, AbilityId.WATER_BUBBLE, AbilityId.NONE, AbilityId.WATER_ABSORB, 269, 38, 40, 52, 40, 72, 27, 200, 50, 54, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ARAQUANID, 7, false, false, false, "Water Bubble Pokémon", PokemonType.WATER, PokemonType.BUG, 1.8, 82, AbilityId.WATER_BUBBLE, AbilityId.NONE, AbilityId.WATER_ABSORB, 454, 68, 70, 92, 50, 132, 42, 100, 50, 159, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.FOMANTIS, 7, false, false, false, "Sickle Grass Pokémon", PokemonType.GRASS, null, 0.3, 1.5, AbilityId.LEAF_GUARD, AbilityId.NONE, AbilityId.CONTRARY, 250, 40, 55, 35, 50, 35, 35, 190, 50, 50, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.LURANTIS, 7, false, false, false, "Bloom Sickle Pokémon", PokemonType.GRASS, null, 0.9, 18.5, AbilityId.LEAF_GUARD, AbilityId.NONE, AbilityId.CONTRARY, 480, 70, 105, 90, 80, 90, 45, 75, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MORELULL, 7, false, false, false, "Illuminating Pokémon", PokemonType.GRASS, PokemonType.FAIRY, 0.2, 1.5, AbilityId.ILLUMINATE, AbilityId.EFFECT_SPORE, AbilityId.RAIN_DISH, 285, 40, 35, 55, 65, 75, 15, 190, 50, 57, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SHIINOTIC, 7, false, false, false, "Illuminating Pokémon", PokemonType.GRASS, PokemonType.FAIRY, 1, 11.5, AbilityId.ILLUMINATE, AbilityId.EFFECT_SPORE, AbilityId.RAIN_DISH, 405, 60, 45, 80, 90, 100, 30, 75, 50, 142, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SALANDIT, 7, false, false, false, "Toxic Lizard Pokémon", PokemonType.POISON, PokemonType.FIRE, 0.6, 4.8, AbilityId.CORROSION, AbilityId.NONE, AbilityId.OBLIVIOUS, 320, 48, 44, 40, 71, 40, 77, 120, 50, 64, GrowthRate.MEDIUM_FAST, 87.5, false), - new PokemonSpecies(SpeciesId.SALAZZLE, 7, false, false, false, "Toxic Lizard Pokémon", PokemonType.POISON, PokemonType.FIRE, 1.2, 22.2, AbilityId.CORROSION, AbilityId.NONE, AbilityId.OBLIVIOUS, 480, 68, 64, 60, 111, 60, 117, 45, 50, 168, GrowthRate.MEDIUM_FAST, 0, false), - new PokemonSpecies(SpeciesId.STUFFUL, 7, false, false, false, "Flailing Pokémon", PokemonType.NORMAL, PokemonType.FIGHTING, 0.5, 6.8, AbilityId.FLUFFY, AbilityId.KLUTZ, AbilityId.CUTE_CHARM, 340, 70, 75, 50, 45, 50, 50, 140, 50, 68, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BEWEAR, 7, false, false, false, "Strong Arm Pokémon", PokemonType.NORMAL, PokemonType.FIGHTING, 2.1, 135, AbilityId.FLUFFY, AbilityId.KLUTZ, AbilityId.UNNERVE, 500, 120, 125, 80, 55, 60, 60, 70, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BOUNSWEET, 7, false, false, false, "Fruit Pokémon", PokemonType.GRASS, null, 0.3, 3.2, AbilityId.LEAF_GUARD, AbilityId.OBLIVIOUS, AbilityId.SWEET_VEIL, 210, 42, 30, 38, 30, 38, 32, 235, 50, 42, GrowthRate.MEDIUM_SLOW, 0, false), - new PokemonSpecies(SpeciesId.STEENEE, 7, false, false, false, "Fruit Pokémon", PokemonType.GRASS, null, 0.7, 8.2, AbilityId.LEAF_GUARD, AbilityId.OBLIVIOUS, AbilityId.SWEET_VEIL, 290, 52, 40, 48, 40, 48, 62, 120, 50, 102, GrowthRate.MEDIUM_SLOW, 0, false), - new PokemonSpecies(SpeciesId.TSAREENA, 7, false, false, false, "Fruit Pokémon", PokemonType.GRASS, null, 1.2, 21.4, AbilityId.LEAF_GUARD, AbilityId.QUEENLY_MAJESTY, AbilityId.SWEET_VEIL, 510, 72, 120, 98, 50, 98, 72, 45, 50, 255, GrowthRate.MEDIUM_SLOW, 0, false), - new PokemonSpecies(SpeciesId.COMFEY, 7, false, false, false, "Posy Picker Pokémon", PokemonType.FAIRY, null, 0.1, 0.3, AbilityId.FLOWER_VEIL, AbilityId.TRIAGE, AbilityId.NATURAL_CURE, 485, 51, 52, 90, 82, 110, 100, 60, 50, 170, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.ORANGURU, 7, false, false, false, "Sage Pokémon", PokemonType.NORMAL, PokemonType.PSYCHIC, 1.5, 76, AbilityId.INNER_FOCUS, AbilityId.TELEPATHY, AbilityId.SYMBIOSIS, 490, 90, 60, 80, 90, 110, 60, 45, 50, 172, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.PASSIMIAN, 7, false, false, false, "Teamwork Pokémon", PokemonType.FIGHTING, null, 2, 82.8, AbilityId.RECEIVER, AbilityId.NONE, AbilityId.DEFIANT, 490, 100, 120, 90, 40, 60, 80, 45, 50, 172, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.WIMPOD, 7, false, false, false, "Turn Tail Pokémon", PokemonType.BUG, PokemonType.WATER, 0.5, 12, AbilityId.WIMP_OUT, AbilityId.NONE, AbilityId.RUN_AWAY, 230, 25, 35, 40, 20, 30, 80, 90, 50, 46, GrowthRate.MEDIUM_FAST, 50, false), //Custom Hidden - new PokemonSpecies(SpeciesId.GOLISOPOD, 7, false, false, false, "Hard Scale Pokémon", PokemonType.BUG, PokemonType.WATER, 2, 108, AbilityId.EMERGENCY_EXIT, AbilityId.NONE, AbilityId.ANTICIPATION, 530, 75, 125, 140, 60, 90, 40, 45, 50, 186, GrowthRate.MEDIUM_FAST, 50, false), //Custom Hidden - new PokemonSpecies(SpeciesId.SANDYGAST, 7, false, false, false, "Sand Heap Pokémon", PokemonType.GHOST, PokemonType.GROUND, 0.5, 70, AbilityId.WATER_COMPACTION, AbilityId.NONE, AbilityId.SAND_VEIL, 320, 55, 55, 80, 70, 45, 15, 140, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PALOSSAND, 7, false, false, false, "Sand Castle Pokémon", PokemonType.GHOST, PokemonType.GROUND, 1.3, 250, AbilityId.WATER_COMPACTION, AbilityId.NONE, AbilityId.SAND_VEIL, 480, 85, 75, 110, 100, 75, 35, 60, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PYUKUMUKU, 7, false, false, false, "Sea Cucumber Pokémon", PokemonType.WATER, null, 0.3, 1.2, AbilityId.INNARDS_OUT, AbilityId.NONE, AbilityId.UNAWARE, 410, 55, 60, 130, 30, 130, 5, 60, 50, 144, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.TYPE_NULL, 7, true, false, false, "Synthetic Pokémon", PokemonType.NORMAL, null, 1.9, 120.5, AbilityId.BATTLE_ARMOR, AbilityId.NONE, AbilityId.NONE, 534, 95, 95, 95, 95, 95, 59, 3, 0, 107, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.SILVALLY, 7, true, false, false, "Synthetic Pokémon", PokemonType.NORMAL, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285, GrowthRate.SLOW, null, false, false, - new PokemonForm("Type: Normal", "normal", PokemonType.NORMAL, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285, false, "", true), - new PokemonForm("Type: Fighting", "fighting", PokemonType.FIGHTING, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Flying", "flying", PokemonType.FLYING, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Poison", "poison", PokemonType.POISON, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Ground", "ground", PokemonType.GROUND, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Rock", "rock", PokemonType.ROCK, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Bug", "bug", PokemonType.BUG, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Ghost", "ghost", PokemonType.GHOST, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Steel", "steel", PokemonType.STEEL, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Fire", "fire", PokemonType.FIRE, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Water", "water", PokemonType.WATER, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Grass", "grass", PokemonType.GRASS, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Electric", "electric", PokemonType.ELECTRIC, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Psychic", "psychic", PokemonType.PSYCHIC, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Ice", "ice", PokemonType.ICE, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Dragon", "dragon", PokemonType.DRAGON, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Dark", "dark", PokemonType.DARK, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - new PokemonForm("Type: Fairy", "fairy", PokemonType.FAIRY, null, 2.3, 100.5, AbilityId.RKS_SYSTEM, AbilityId.NONE, AbilityId.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), - ), - new PokemonSpecies(SpeciesId.MINIOR, 7, false, false, false, "Meteor Pokémon", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, GrowthRate.MEDIUM_SLOW, null, false, false, - new PokemonForm("Red Meteor Form", "red-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), - new PokemonForm("Orange Meteor Form", "orange-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), - new PokemonForm("Yellow Meteor Form", "yellow-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), - new PokemonForm("Green Meteor Form", "green-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), - new PokemonForm("Blue Meteor Form", "blue-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), - new PokemonForm("Indigo Meteor Form", "indigo-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), - new PokemonForm("Violet Meteor Form", "violet-meteor", PokemonType.ROCK, PokemonType.FLYING, 0.3, 40, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, null, true), - new PokemonForm("Red Core Form", "red", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true), - new PokemonForm("Orange Core Form", "orange", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true), - new PokemonForm("Yellow Core Form", "yellow", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true), - new PokemonForm("Green Core Form", "green", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true), - new PokemonForm("Blue Core Form", "blue", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true), - new PokemonForm("Indigo Core Form", "indigo", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true), - new PokemonForm("Violet Core Form", "violet", PokemonType.ROCK, PokemonType.FLYING, 0.3, 0.3, AbilityId.SHIELDS_DOWN, AbilityId.NONE, AbilityId.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 175, false, null, true), - ), - new PokemonSpecies(SpeciesId.KOMALA, 7, false, false, false, "Drowsing Pokémon", PokemonType.NORMAL, null, 0.4, 19.9, AbilityId.COMATOSE, AbilityId.NONE, AbilityId.NONE, 480, 65, 115, 65, 75, 95, 65, 45, 70, 168, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.TURTONATOR, 7, false, false, false, "Blast Turtle Pokémon", PokemonType.FIRE, PokemonType.DRAGON, 2, 212, AbilityId.SHELL_ARMOR, AbilityId.NONE, AbilityId.NONE, 485, 60, 78, 135, 91, 85, 36, 70, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.TOGEDEMARU, 7, false, false, false, "Roly-Poly Pokémon", PokemonType.ELECTRIC, PokemonType.STEEL, 0.3, 3.3, AbilityId.IRON_BARBS, AbilityId.LIGHTNING_ROD, AbilityId.STURDY, 435, 65, 98, 63, 40, 73, 96, 180, 50, 152, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MIMIKYU, 7, false, false, false, "Disguise Pokémon", PokemonType.GHOST, PokemonType.FAIRY, 0.2, 0.7, AbilityId.DISGUISE, AbilityId.NONE, AbilityId.NONE, 476, 55, 90, 80, 50, 105, 96, 45, 50, 167, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Disguised Form", "disguised", PokemonType.GHOST, PokemonType.FAIRY, 0.2, 0.7, AbilityId.DISGUISE, AbilityId.NONE, AbilityId.NONE, 476, 55, 90, 80, 50, 105, 96, 45, 50, 167, false, null, true), - new PokemonForm("Busted Form", "busted", PokemonType.GHOST, PokemonType.FAIRY, 0.2, 0.7, AbilityId.DISGUISE, AbilityId.NONE, AbilityId.NONE, 476, 55, 90, 80, 50, 105, 96, 45, 50, 167), - ), - new PokemonSpecies(SpeciesId.BRUXISH, 7, false, false, false, "Gnash Teeth Pokémon", PokemonType.WATER, PokemonType.PSYCHIC, 0.9, 19, AbilityId.DAZZLING, AbilityId.STRONG_JAW, AbilityId.WONDER_SKIN, 475, 68, 105, 70, 70, 70, 92, 80, 70, 166, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DRAMPA, 7, false, false, false, "Placid Pokémon", PokemonType.NORMAL, PokemonType.DRAGON, 3, 185, AbilityId.BERSERK, AbilityId.SAP_SIPPER, AbilityId.CLOUD_NINE, 485, 78, 60, 85, 135, 91, 36, 70, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DHELMISE, 7, false, false, false, "Sea Creeper Pokémon", PokemonType.GHOST, PokemonType.GRASS, 3.9, 210, AbilityId.STEELWORKER, AbilityId.NONE, AbilityId.NONE, 517, 70, 131, 100, 86, 90, 40, 25, 50, 181, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.JANGMO_O, 7, false, false, false, "Scaly Pokémon", PokemonType.DRAGON, null, 0.6, 29.7, AbilityId.BULLETPROOF, AbilityId.SOUNDPROOF, AbilityId.OVERCOAT, 300, 45, 55, 65, 45, 45, 45, 45, 50, 60, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.HAKAMO_O, 7, false, false, false, "Scaly Pokémon", PokemonType.DRAGON, PokemonType.FIGHTING, 1.2, 47, AbilityId.BULLETPROOF, AbilityId.SOUNDPROOF, AbilityId.OVERCOAT, 420, 55, 75, 90, 65, 70, 65, 45, 50, 147, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.KOMMO_O, 7, false, false, false, "Scaly Pokémon", PokemonType.DRAGON, PokemonType.FIGHTING, 1.6, 78.2, AbilityId.BULLETPROOF, AbilityId.SOUNDPROOF, AbilityId.OVERCOAT, 600, 75, 110, 125, 100, 105, 85, 45, 50, 300, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.TAPU_KOKO, 7, true, false, false, "Land Spirit Pokémon", PokemonType.ELECTRIC, PokemonType.FAIRY, 1.8, 20.5, AbilityId.ELECTRIC_SURGE, AbilityId.NONE, AbilityId.TELEPATHY, 570, 70, 115, 85, 95, 75, 130, 3, 50, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.TAPU_LELE, 7, true, false, false, "Land Spirit Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 1.2, 18.6, AbilityId.PSYCHIC_SURGE, AbilityId.NONE, AbilityId.TELEPATHY, 570, 70, 85, 75, 130, 115, 95, 3, 50, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.TAPU_BULU, 7, true, false, false, "Land Spirit Pokémon", PokemonType.GRASS, PokemonType.FAIRY, 1.9, 45.5, AbilityId.GRASSY_SURGE, AbilityId.NONE, AbilityId.TELEPATHY, 570, 70, 130, 115, 85, 95, 75, 3, 50, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.TAPU_FINI, 7, true, false, false, "Land Spirit Pokémon", PokemonType.WATER, PokemonType.FAIRY, 1.3, 21.2, AbilityId.MISTY_SURGE, AbilityId.NONE, AbilityId.TELEPATHY, 570, 70, 75, 115, 95, 130, 85, 3, 50, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.COSMOG, 7, true, false, false, "Nebula Pokémon", PokemonType.PSYCHIC, null, 0.2, 0.1, AbilityId.UNAWARE, AbilityId.NONE, AbilityId.NONE, 200, 43, 29, 31, 29, 31, 37, 3, 0, 40, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.COSMOEM, 7, true, false, false, "Protostar Pokémon", PokemonType.PSYCHIC, null, 0.1, 999.9, AbilityId.STURDY, AbilityId.NONE, AbilityId.NONE, 400, 43, 29, 131, 29, 131, 37, 3, 0, 140, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.SOLGALEO, 7, false, true, false, "Sunne Pokémon", PokemonType.PSYCHIC, PokemonType.STEEL, 3.4, 230, AbilityId.FULL_METAL_BODY, AbilityId.NONE, AbilityId.NONE, 680, 137, 137, 107, 113, 89, 97, 3, 0, 340, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.LUNALA, 7, false, true, false, "Moone Pokémon", PokemonType.PSYCHIC, PokemonType.GHOST, 4, 120, AbilityId.SHADOW_SHIELD, AbilityId.NONE, AbilityId.NONE, 680, 137, 113, 89, 137, 107, 97, 3, 0, 340, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.NIHILEGO, 7, true, false, false, "Parasite Pokémon", PokemonType.ROCK, PokemonType.POISON, 1.2, 55.5, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 109, 53, 47, 127, 131, 103, 45, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.BUZZWOLE, 7, true, false, false, "Swollen Pokémon", PokemonType.BUG, PokemonType.FIGHTING, 2.4, 333.6, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 107, 139, 139, 53, 53, 79, 45, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.PHEROMOSA, 7, true, false, false, "Lissome Pokémon", PokemonType.BUG, PokemonType.FIGHTING, 1.8, 25, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 71, 137, 37, 137, 37, 151, 45, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.XURKITREE, 7, true, false, false, "Glowing Pokémon", PokemonType.ELECTRIC, null, 3.8, 100, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 83, 89, 71, 173, 71, 83, 45, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.CELESTEELA, 7, true, false, false, "Launch Pokémon", PokemonType.STEEL, PokemonType.FLYING, 9.2, 999.9, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 97, 101, 103, 107, 101, 61, 45, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.KARTANA, 7, true, false, false, "Drawn Sword Pokémon", PokemonType.GRASS, PokemonType.STEEL, 0.3, 0.1, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 59, 181, 131, 59, 31, 109, 45, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.GUZZLORD, 7, true, false, false, "Junkivore Pokémon", PokemonType.DARK, PokemonType.DRAGON, 5.5, 888, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 223, 101, 53, 97, 53, 43, 45, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.NECROZMA, 7, false, true, false, "Prism Pokémon", PokemonType.PSYCHIC, null, 2.4, 230, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 600, 97, 107, 101, 127, 89, 79, 3, 0, 300, GrowthRate.SLOW, null, false, false, - new PokemonForm("Normal", "", PokemonType.PSYCHIC, null, 2.4, 230, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 600, 97, 107, 101, 127, 89, 79, 3, 0, 300, false, null, true), - new PokemonForm("Dusk Mane", "dusk-mane", PokemonType.PSYCHIC, PokemonType.STEEL, 3.8, 460, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 680, 97, 157, 127, 113, 109, 77, 3, 0, 340), - new PokemonForm("Dawn Wings", "dawn-wings", PokemonType.PSYCHIC, PokemonType.GHOST, 4.2, 350, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 680, 97, 113, 109, 157, 127, 77, 3, 0, 340), - new PokemonForm("Ultra", "ultra", PokemonType.PSYCHIC, PokemonType.DRAGON, 7.5, 230, AbilityId.NEUROFORCE, AbilityId.NONE, AbilityId.NONE, 754, 97, 167, 97, 167, 97, 129, 3, 0, 377), - ), - new PokemonSpecies(SpeciesId.MAGEARNA, 7, false, false, true, "Artificial Pokémon", PokemonType.STEEL, PokemonType.FAIRY, 1, 80.5, AbilityId.SOUL_HEART, AbilityId.NONE, AbilityId.NONE, 600, 80, 95, 115, 130, 115, 65, 3, 0, 300, GrowthRate.SLOW, null, false, false, - new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.FAIRY, 1, 80.5, AbilityId.SOUL_HEART, AbilityId.NONE, AbilityId.NONE, 600, 80, 95, 115, 130, 115, 65, 3, 0, 300, false, null, true), - new PokemonForm("Original", "original", PokemonType.STEEL, PokemonType.FAIRY, 1, 80.5, AbilityId.SOUL_HEART, AbilityId.NONE, AbilityId.NONE, 600, 80, 95, 115, 130, 115, 65, 3, 0, 300, false, null, true), - ), - new PokemonSpecies(SpeciesId.MARSHADOW, 7, false, false, true, "Gloomdweller Pokémon", PokemonType.FIGHTING, PokemonType.GHOST, 0.7, 22.2, AbilityId.TECHNICIAN, AbilityId.NONE, AbilityId.NONE, 600, 90, 125, 80, 90, 90, 125, 3, 0, 300, GrowthRate.SLOW, null, false, true, - new PokemonForm("Normal", "", PokemonType.FIGHTING, PokemonType.GHOST, 0.7, 22.2, AbilityId.TECHNICIAN, AbilityId.NONE, AbilityId.NONE, 600, 90, 125, 80, 90, 90, 125, 3, 0, 300, false, null, true), - new PokemonForm("Zenith", "zenith", PokemonType.FIGHTING, PokemonType.GHOST, 0.7, 22.2, AbilityId.TECHNICIAN, AbilityId.NONE, AbilityId.NONE, 600, 90, 125, 80, 90, 90, 125, 3, 0, 300, false, null, false, true) - ), - new PokemonSpecies(SpeciesId.POIPOLE, 7, true, false, false, "Poison Pin Pokémon", PokemonType.POISON, null, 0.6, 1.8, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 420, 67, 73, 67, 73, 67, 73, 45, 0, 210, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.NAGANADEL, 7, true, false, false, "Poison Pin Pokémon", PokemonType.POISON, PokemonType.DRAGON, 3.6, 150, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 540, 73, 73, 73, 127, 73, 121, 45, 0, 270, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.STAKATAKA, 7, true, false, false, "Rampart Pokémon", PokemonType.ROCK, PokemonType.STEEL, 5.5, 820, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 61, 131, 211, 53, 101, 13, 30, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.BLACEPHALON, 7, true, false, false, "Fireworks Pokémon", PokemonType.FIRE, PokemonType.GHOST, 1.8, 13, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 53, 127, 53, 151, 79, 107, 30, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.ZERAORA, 7, false, false, true, "Thunderclap Pokémon", PokemonType.ELECTRIC, null, 1.5, 44.5, AbilityId.VOLT_ABSORB, AbilityId.NONE, AbilityId.NONE, 600, 88, 112, 75, 102, 80, 143, 3, 0, 300, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.MELTAN, 7, false, false, true, "Hex Nut Pokémon", PokemonType.STEEL, null, 0.2, 8, AbilityId.MAGNET_PULL, AbilityId.NONE, AbilityId.NONE, 300, 46, 65, 65, 55, 35, 34, 3, 0, 150, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.MELMETAL, 7, false, false, true, "Hex Nut Pokémon", PokemonType.STEEL, null, 2.5, 800, AbilityId.IRON_FIST, AbilityId.NONE, AbilityId.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, GrowthRate.SLOW, null, false, true, - new PokemonForm("Normal", "", PokemonType.STEEL, null, 2.5, 800, AbilityId.IRON_FIST, AbilityId.NONE, AbilityId.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.STEEL, null, 25, 999.9, AbilityId.IRON_FIST, AbilityId.NONE, AbilityId.NONE, 700, 170, 158, 158, 95, 75, 44, 3, 0, 300), - ), - new PokemonSpecies(SpeciesId.GROOKEY, 8, false, false, false, "Chimp Pokémon", PokemonType.GRASS, null, 0.3, 5, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.GRASSY_SURGE, 310, 50, 65, 50, 40, 40, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.THWACKEY, 8, false, false, false, "Beat Pokémon", PokemonType.GRASS, null, 0.7, 14, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.GRASSY_SURGE, 420, 70, 85, 70, 55, 60, 80, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.RILLABOOM, 8, false, false, false, "Drummer Pokémon", PokemonType.GRASS, null, 2.1, 90, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, - new PokemonForm("Normal", "", PokemonType.GRASS, null, 2.1, 90, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GRASS, null, 28, 999.9, AbilityId.GRASSY_SURGE, AbilityId.NONE, AbilityId.GRASSY_SURGE, 630, 125, 140, 105, 90, 85, 85, 45, 50, 265), - ), - new PokemonSpecies(SpeciesId.SCORBUNNY, 8, false, false, false, "Rabbit Pokémon", PokemonType.FIRE, null, 0.3, 4.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.LIBERO, 310, 50, 71, 40, 40, 40, 69, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.RABOOT, 8, false, false, false, "Rabbit Pokémon", PokemonType.FIRE, null, 0.6, 9, AbilityId.BLAZE, AbilityId.NONE, AbilityId.LIBERO, 420, 65, 86, 60, 55, 60, 94, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.CINDERACE, 8, false, false, false, "Striker Pokémon", PokemonType.FIRE, null, 1.4, 33, AbilityId.BLAZE, AbilityId.NONE, AbilityId.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, - new PokemonForm("Normal", "", PokemonType.FIRE, null, 1.4, 33, AbilityId.BLAZE, AbilityId.NONE, AbilityId.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIRE, null, 27, 999.9, AbilityId.LIBERO, AbilityId.NONE, AbilityId.LIBERO, 630, 100, 141, 80, 95, 80, 134, 45, 50, 265), - ), - new PokemonSpecies(SpeciesId.SOBBLE, 8, false, false, false, "Water Lizard Pokémon", PokemonType.WATER, null, 0.3, 4, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SNIPER, 310, 50, 40, 40, 70, 40, 70, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.DRIZZILE, 8, false, false, false, "Water Lizard Pokémon", PokemonType.WATER, null, 0.7, 11.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SNIPER, 420, 65, 60, 55, 95, 55, 90, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.INTELEON, 8, false, false, false, "Secret Agent Pokémon", PokemonType.WATER, null, 1.9, 45.2, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, - new PokemonForm("Normal", "", PokemonType.WATER, null, 1.9, 45.2, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, null, 40, 999.9, AbilityId.SNIPER, AbilityId.NONE, AbilityId.SNIPER, 630, 95, 117, 67, 147, 67, 137, 45, 50, 265), - ), - new PokemonSpecies(SpeciesId.SKWOVET, 8, false, false, false, "Cheeky Pokémon", PokemonType.NORMAL, null, 0.3, 2.5, AbilityId.CHEEK_POUCH, AbilityId.NONE, AbilityId.GLUTTONY, 275, 70, 55, 55, 35, 35, 25, 255, 50, 55, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GREEDENT, 8, false, false, false, "Greedy Pokémon", PokemonType.NORMAL, null, 0.6, 6, AbilityId.CHEEK_POUCH, AbilityId.NONE, AbilityId.GLUTTONY, 460, 120, 95, 95, 55, 75, 20, 90, 50, 161, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ROOKIDEE, 8, false, false, false, "Tiny Bird Pokémon", PokemonType.FLYING, null, 0.2, 1.8, AbilityId.KEEN_EYE, AbilityId.UNNERVE, AbilityId.BIG_PECKS, 245, 38, 47, 35, 33, 35, 57, 255, 50, 49, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.CORVISQUIRE, 8, false, false, false, "Raven Pokémon", PokemonType.FLYING, null, 0.8, 16, AbilityId.KEEN_EYE, AbilityId.UNNERVE, AbilityId.BIG_PECKS, 365, 68, 67, 55, 43, 55, 77, 120, 50, 128, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.CORVIKNIGHT, 8, false, false, false, "Raven Pokémon", PokemonType.FLYING, PokemonType.STEEL, 2.2, 75, AbilityId.PRESSURE, AbilityId.UNNERVE, AbilityId.MIRROR_ARMOR, 495, 98, 87, 105, 53, 85, 67, 45, 50, 248, GrowthRate.MEDIUM_SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.FLYING, PokemonType.STEEL, 2.2, 75, AbilityId.PRESSURE, AbilityId.UNNERVE, AbilityId.MIRROR_ARMOR, 495, 98, 87, 105, 53, 85, 67, 45, 50, 248, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FLYING, PokemonType.STEEL, 14, 999.9, AbilityId.MIRROR_ARMOR, AbilityId.MIRROR_ARMOR, AbilityId.MIRROR_ARMOR, 595, 118, 112, 135, 63, 90, 77, 45, 50, 248), - ), - new PokemonSpecies(SpeciesId.BLIPBUG, 8, false, false, false, "Larva Pokémon", PokemonType.BUG, null, 0.4, 8, AbilityId.SWARM, AbilityId.COMPOUND_EYES, AbilityId.TELEPATHY, 180, 25, 20, 20, 25, 45, 45, 255, 50, 36, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DOTTLER, 8, false, false, false, "Radome Pokémon", PokemonType.BUG, PokemonType.PSYCHIC, 0.4, 19.5, AbilityId.SWARM, AbilityId.COMPOUND_EYES, AbilityId.TELEPATHY, 335, 50, 35, 80, 50, 90, 30, 120, 50, 117, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ORBEETLE, 8, false, false, false, "Seven Spot Pokémon", PokemonType.BUG, PokemonType.PSYCHIC, 0.4, 40.8, AbilityId.SWARM, AbilityId.FRISK, AbilityId.TELEPATHY, 505, 60, 45, 110, 80, 120, 90, 45, 50, 253, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.BUG, PokemonType.PSYCHIC, 0.4, 40.8, AbilityId.SWARM, AbilityId.FRISK, AbilityId.TELEPATHY, 505, 60, 45, 110, 80, 120, 90, 45, 50, 253, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.BUG, PokemonType.PSYCHIC, 14, 999.9, AbilityId.TRACE, AbilityId.TRACE, AbilityId.TRACE, 605, 75, 50, 140, 100, 150, 90, 45, 50, 253), - ), - new PokemonSpecies(SpeciesId.NICKIT, 8, false, false, false, "Fox Pokémon", PokemonType.DARK, null, 0.6, 8.9, AbilityId.RUN_AWAY, AbilityId.UNBURDEN, AbilityId.STAKEOUT, 245, 40, 28, 28, 47, 52, 50, 255, 50, 49, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.THIEVUL, 8, false, false, false, "Fox Pokémon", PokemonType.DARK, null, 1.2, 19.9, AbilityId.RUN_AWAY, AbilityId.UNBURDEN, AbilityId.STAKEOUT, 455, 70, 58, 58, 87, 92, 90, 127, 50, 159, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.GOSSIFLEUR, 8, false, false, false, "Flowering Pokémon", PokemonType.GRASS, null, 0.4, 2.2, AbilityId.COTTON_DOWN, AbilityId.REGENERATOR, AbilityId.EFFECT_SPORE, 250, 40, 40, 60, 40, 60, 10, 190, 50, 50, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ELDEGOSS, 8, false, false, false, "Cotton Bloom Pokémon", PokemonType.GRASS, null, 0.5, 2.5, AbilityId.COTTON_DOWN, AbilityId.REGENERATOR, AbilityId.EFFECT_SPORE, 460, 60, 50, 90, 80, 120, 60, 75, 50, 161, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.WOOLOO, 8, false, false, false, "Sheep Pokémon", PokemonType.NORMAL, null, 0.6, 6, AbilityId.FLUFFY, AbilityId.RUN_AWAY, AbilityId.BULLETPROOF, 270, 42, 40, 55, 40, 45, 48, 255, 50, 122, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DUBWOOL, 8, false, false, false, "Sheep Pokémon", PokemonType.NORMAL, null, 1.3, 43, AbilityId.FLUFFY, AbilityId.STEADFAST, AbilityId.BULLETPROOF, 490, 72, 80, 100, 60, 90, 88, 127, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CHEWTLE, 8, false, false, false, "Snapping Pokémon", PokemonType.WATER, null, 0.3, 8.5, AbilityId.STRONG_JAW, AbilityId.SHELL_ARMOR, AbilityId.SWIFT_SWIM, 284, 50, 64, 50, 38, 38, 44, 255, 50, 57, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DREDNAW, 8, false, false, false, "Bite Pokémon", PokemonType.WATER, PokemonType.ROCK, 1, 115.5, AbilityId.STRONG_JAW, AbilityId.SHELL_ARMOR, AbilityId.SWIFT_SWIM, 485, 90, 115, 90, 48, 68, 74, 75, 50, 170, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.ROCK, 1, 115.5, AbilityId.STRONG_JAW, AbilityId.SHELL_ARMOR, AbilityId.SWIFT_SWIM, 485, 90, 115, 90, 48, 68, 74, 75, 50, 170, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, PokemonType.ROCK, 24, 999.9, AbilityId.STRONG_JAW, AbilityId.STRONG_JAW, AbilityId.STRONG_JAW, 585, 115, 137, 115, 61, 83, 74, 75, 50, 170), - ), - new PokemonSpecies(SpeciesId.YAMPER, 8, false, false, false, "Puppy Pokémon", PokemonType.ELECTRIC, null, 0.3, 13.5, AbilityId.BALL_FETCH, AbilityId.NONE, AbilityId.RATTLED, 270, 59, 45, 50, 40, 50, 26, 255, 50, 54, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.BOLTUND, 8, false, false, false, "Dog Pokémon", PokemonType.ELECTRIC, null, 1, 34, AbilityId.STRONG_JAW, AbilityId.NONE, AbilityId.COMPETITIVE, 490, 69, 90, 60, 90, 60, 121, 45, 50, 172, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.ROLYCOLY, 8, false, false, false, "Coal Pokémon", PokemonType.ROCK, null, 0.3, 12, AbilityId.STEAM_ENGINE, AbilityId.HEATPROOF, AbilityId.FLASH_FIRE, 240, 30, 40, 50, 40, 50, 30, 255, 50, 48, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.CARKOL, 8, false, false, false, "Coal Pokémon", PokemonType.ROCK, PokemonType.FIRE, 1.1, 78, AbilityId.STEAM_ENGINE, AbilityId.FLAME_BODY, AbilityId.FLASH_FIRE, 410, 80, 60, 90, 60, 70, 50, 120, 50, 144, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.COALOSSAL, 8, false, false, false, "Coal Pokémon", PokemonType.ROCK, PokemonType.FIRE, 2.8, 310.5, AbilityId.STEAM_ENGINE, AbilityId.FLAME_BODY, AbilityId.FLASH_FIRE, 510, 110, 80, 120, 80, 90, 30, 45, 50, 255, GrowthRate.MEDIUM_SLOW, 50, false, true, - new PokemonForm("Normal", "", PokemonType.ROCK, PokemonType.FIRE, 2.8, 310.5, AbilityId.STEAM_ENGINE, AbilityId.FLAME_BODY, AbilityId.FLASH_FIRE, 510, 110, 80, 120, 80, 90, 30, 45, 50, 255, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.ROCK, PokemonType.FIRE, 42, 999.9, AbilityId.STEAM_ENGINE, AbilityId.STEAM_ENGINE, AbilityId.STEAM_ENGINE, 610, 140, 100, 132, 95, 100, 43, 45, 50, 255), - ), - new PokemonSpecies(SpeciesId.APPLIN, 8, false, false, false, "Apple Core Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 0.2, 0.5, AbilityId.RIPEN, AbilityId.GLUTTONY, AbilityId.BULLETPROOF, 260, 40, 40, 80, 40, 40, 20, 255, 50, 52, GrowthRate.ERRATIC, 50, false), - new PokemonSpecies(SpeciesId.FLAPPLE, 8, false, false, false, "Apple Wing Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 0.3, 1, AbilityId.RIPEN, AbilityId.GLUTTONY, AbilityId.HUSTLE, 485, 70, 110, 80, 95, 60, 70, 45, 50, 170, GrowthRate.ERRATIC, 50, false, true, - new PokemonForm("Normal", "", PokemonType.GRASS, PokemonType.DRAGON, 0.3, 1, AbilityId.RIPEN, AbilityId.GLUTTONY, AbilityId.HUSTLE, 485, 70, 110, 80, 95, 60, 70, 45, 50, 170, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GRASS, PokemonType.DRAGON, 24, 999.9, AbilityId.HUSTLE, AbilityId.HUSTLE, AbilityId.HUSTLE, 585, 100, 125, 90, 105, 70, 95, 45, 50, 170), - ), - new PokemonSpecies(SpeciesId.APPLETUN, 8, false, false, false, "Apple Nectar Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 0.4, 13, AbilityId.RIPEN, AbilityId.GLUTTONY, AbilityId.THICK_FAT, 485, 110, 85, 80, 100, 80, 30, 45, 50, 170, GrowthRate.ERRATIC, 50, false, true, - new PokemonForm("Normal", "", PokemonType.GRASS, PokemonType.DRAGON, 0.4, 13, AbilityId.RIPEN, AbilityId.GLUTTONY, AbilityId.THICK_FAT, 485, 110, 85, 80, 100, 80, 30, 45, 50, 170, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GRASS, PokemonType.DRAGON, 24, 999.9, AbilityId.THICK_FAT, AbilityId.THICK_FAT, AbilityId.THICK_FAT, 585, 150, 100, 95, 115, 95, 30, 45, 50, 170), - ), - new PokemonSpecies(SpeciesId.SILICOBRA, 8, false, false, false, "Sand Snake Pokémon", PokemonType.GROUND, null, 2.2, 7.6, AbilityId.SAND_SPIT, AbilityId.SHED_SKIN, AbilityId.SAND_VEIL, 315, 52, 57, 75, 35, 50, 46, 255, 50, 63, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SANDACONDA, 8, false, false, false, "Sand Snake Pokémon", PokemonType.GROUND, null, 3.8, 65.5, AbilityId.SAND_SPIT, AbilityId.SHED_SKIN, AbilityId.SAND_VEIL, 510, 72, 107, 125, 65, 70, 71, 120, 50, 179, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.GROUND, null, 3.8, 65.5, AbilityId.SAND_SPIT, AbilityId.SHED_SKIN, AbilityId.SAND_VEIL, 510, 72, 107, 125, 65, 70, 71, 120, 50, 179, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GROUND, null, 22, 999.9, AbilityId.SAND_SPIT, AbilityId.SAND_SPIT, AbilityId.SAND_SPIT, 610, 102, 137, 140, 70, 80, 81, 120, 50, 179), - ), - new PokemonSpecies(SpeciesId.CRAMORANT, 8, false, false, false, "Gulp Pokémon", PokemonType.FLYING, PokemonType.WATER, 0.8, 18, AbilityId.GULP_MISSILE, AbilityId.NONE, AbilityId.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Normal", "", PokemonType.FLYING, PokemonType.WATER, 0.8, 18, AbilityId.GULP_MISSILE, AbilityId.NONE, AbilityId.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166, false, null, true), - new PokemonForm("Gulping Form", "gulping", PokemonType.FLYING, PokemonType.WATER, 0.8, 18, AbilityId.GULP_MISSILE, AbilityId.NONE, AbilityId.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166), - new PokemonForm("Gorging Form", "gorging", PokemonType.FLYING, PokemonType.WATER, 0.8, 18, AbilityId.GULP_MISSILE, AbilityId.NONE, AbilityId.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166), - ), - new PokemonSpecies(SpeciesId.ARROKUDA, 8, false, false, false, "Rush Pokémon", PokemonType.WATER, null, 0.5, 1, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.PROPELLER_TAIL, 280, 41, 63, 40, 40, 30, 66, 255, 50, 56, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.BARRASKEWDA, 8, false, false, false, "Skewer Pokémon", PokemonType.WATER, null, 1.3, 30, AbilityId.SWIFT_SWIM, AbilityId.NONE, AbilityId.PROPELLER_TAIL, 490, 61, 123, 60, 60, 50, 136, 60, 50, 172, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.TOXEL, 8, false, false, false, "Baby Pokémon", PokemonType.ELECTRIC, PokemonType.POISON, 0.4, 11, AbilityId.RATTLED, AbilityId.STATIC, AbilityId.KLUTZ, 242, 40, 38, 35, 54, 35, 40, 75, 50, 48, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.TOXTRICITY, 8, false, false, false, "Punk Pokémon", PokemonType.ELECTRIC, PokemonType.POISON, 1.6, 40, AbilityId.PUNK_ROCK, AbilityId.PLUS, AbilityId.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, GrowthRate.MEDIUM_SLOW, 50, false, true, - new PokemonForm("Amped Form", "amped", PokemonType.ELECTRIC, PokemonType.POISON, 1.6, 40, AbilityId.PUNK_ROCK, AbilityId.PLUS, AbilityId.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, false, "", true), - new PokemonForm("Low-Key Form", "lowkey", PokemonType.ELECTRIC, PokemonType.POISON, 1.6, 40, AbilityId.PUNK_ROCK, AbilityId.MINUS, AbilityId.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, false, "lowkey", true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.ELECTRIC, PokemonType.POISON, 24, 999.9, AbilityId.PUNK_ROCK, AbilityId.PUNK_ROCK, AbilityId.PUNK_ROCK, 602, 114, 105, 82, 137, 82, 82, 45, 50, 176), - ), - new PokemonSpecies(SpeciesId.SIZZLIPEDE, 8, false, false, false, "Radiator Pokémon", PokemonType.FIRE, PokemonType.BUG, 0.7, 1, AbilityId.FLASH_FIRE, AbilityId.WHITE_SMOKE, AbilityId.FLAME_BODY, 305, 50, 65, 45, 50, 50, 45, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CENTISKORCH, 8, false, false, false, "Radiator Pokémon", PokemonType.FIRE, PokemonType.BUG, 3, 120, AbilityId.FLASH_FIRE, AbilityId.WHITE_SMOKE, AbilityId.FLAME_BODY, 525, 100, 115, 65, 90, 90, 65, 75, 50, 184, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.FIRE, PokemonType.BUG, 3, 120, AbilityId.FLASH_FIRE, AbilityId.WHITE_SMOKE, AbilityId.FLAME_BODY, 525, 100, 115, 65, 90, 90, 65, 75, 50, 184, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIRE, PokemonType.BUG, 75, 999.9, AbilityId.FLASH_FIRE, AbilityId.FLASH_FIRE, AbilityId.FLASH_FIRE, 625, 130, 125, 75, 94, 100, 101, 75, 50, 184), - ), - new PokemonSpecies(SpeciesId.CLOBBOPUS, 8, false, false, false, "Tantrum Pokémon", PokemonType.FIGHTING, null, 0.6, 4, AbilityId.LIMBER, AbilityId.NONE, AbilityId.TECHNICIAN, 310, 50, 68, 60, 50, 50, 32, 180, 50, 62, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.GRAPPLOCT, 8, false, false, false, "Jujitsu Pokémon", PokemonType.FIGHTING, null, 1.6, 39, AbilityId.LIMBER, AbilityId.NONE, AbilityId.TECHNICIAN, 480, 80, 118, 90, 70, 80, 42, 45, 50, 168, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SINISTEA, 8, false, false, false, "Black Tea Pokémon", PokemonType.GHOST, null, 0.1, 0.2, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, GrowthRate.MEDIUM_FAST, null, false, false, - new PokemonForm("Phony Form", "phony", PokemonType.GHOST, null, 0.1, 0.2, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, "", true), - new PokemonForm("Antique Form", "antique", PokemonType.GHOST, null, 0.1, 0.2, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, "", true), - ), - new PokemonSpecies(SpeciesId.POLTEAGEIST, 8, false, false, false, "Black Tea Pokémon", PokemonType.GHOST, null, 0.2, 0.4, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 508, 60, 65, 65, 134, 114, 70, 60, 50, 178, GrowthRate.MEDIUM_FAST, null, false, false, - new PokemonForm("Phony Form", "phony", PokemonType.GHOST, null, 0.2, 0.4, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 508, 60, 65, 65, 134, 114, 70, 60, 50, 178, false, "", true), - new PokemonForm("Antique Form", "antique", PokemonType.GHOST, null, 0.2, 0.4, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 508, 60, 65, 65, 134, 114, 70, 60, 50, 178, false, "", true), - ), - new PokemonSpecies(SpeciesId.HATENNA, 8, false, false, false, "Calm Pokémon", PokemonType.PSYCHIC, null, 0.4, 3.4, AbilityId.HEALER, AbilityId.ANTICIPATION, AbilityId.MAGIC_BOUNCE, 265, 42, 30, 45, 56, 53, 39, 235, 50, 53, GrowthRate.SLOW, 0, false), - new PokemonSpecies(SpeciesId.HATTREM, 8, false, false, false, "Serene Pokémon", PokemonType.PSYCHIC, null, 0.6, 4.8, AbilityId.HEALER, AbilityId.ANTICIPATION, AbilityId.MAGIC_BOUNCE, 370, 57, 40, 65, 86, 73, 49, 120, 50, 130, GrowthRate.SLOW, 0, false), - new PokemonSpecies(SpeciesId.HATTERENE, 8, false, false, false, "Silent Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 2.1, 5.1, AbilityId.HEALER, AbilityId.ANTICIPATION, AbilityId.MAGIC_BOUNCE, 510, 57, 90, 95, 136, 103, 29, 45, 50, 255, GrowthRate.SLOW, 0, false, true, - new PokemonForm("Normal", "", PokemonType.PSYCHIC, PokemonType.FAIRY, 2.1, 5.1, AbilityId.HEALER, AbilityId.ANTICIPATION, AbilityId.MAGIC_BOUNCE, 510, 57, 90, 95, 136, 103, 29, 45, 50, 255, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.PSYCHIC, PokemonType.FAIRY, 26, 999.9, AbilityId.MAGIC_BOUNCE, AbilityId.MAGIC_BOUNCE, AbilityId.MAGIC_BOUNCE, 610, 87, 100, 110, 146, 118, 49, 45, 50, 255), - ), - new PokemonSpecies(SpeciesId.IMPIDIMP, 8, false, false, false, "Wily Pokémon", PokemonType.DARK, PokemonType.FAIRY, 0.4, 5.5, AbilityId.PRANKSTER, AbilityId.FRISK, AbilityId.PICKPOCKET, 265, 45, 45, 30, 55, 40, 50, 255, 50, 53, GrowthRate.MEDIUM_FAST, 100, false), - new PokemonSpecies(SpeciesId.MORGREM, 8, false, false, false, "Devious Pokémon", PokemonType.DARK, PokemonType.FAIRY, 0.8, 12.5, AbilityId.PRANKSTER, AbilityId.FRISK, AbilityId.PICKPOCKET, 370, 65, 60, 45, 75, 55, 70, 120, 50, 130, GrowthRate.MEDIUM_FAST, 100, false), - new PokemonSpecies(SpeciesId.GRIMMSNARL, 8, false, false, false, "Bulk Up Pokémon", PokemonType.DARK, PokemonType.FAIRY, 1.5, 61, AbilityId.PRANKSTER, AbilityId.FRISK, AbilityId.PICKPOCKET, 510, 95, 120, 65, 95, 75, 60, 45, 50, 255, GrowthRate.MEDIUM_FAST, 100, false, true, - new PokemonForm("Normal", "", PokemonType.DARK, PokemonType.FAIRY, 1.5, 61, AbilityId.PRANKSTER, AbilityId.FRISK, AbilityId.PICKPOCKET, 510, 95, 120, 65, 95, 75, 60, 45, 50, 255, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.DARK, PokemonType.FAIRY, 32, 999.9, AbilityId.PRANKSTER, AbilityId.PRANKSTER, AbilityId.PRANKSTER, 610, 130, 138, 75, 110, 92, 65, 45, 50, 255), - ), - new PokemonSpecies(SpeciesId.OBSTAGOON, 8, false, false, false, "Blocking Pokémon", PokemonType.DARK, PokemonType.NORMAL, 1.6, 46, AbilityId.RECKLESS, AbilityId.GUTS, AbilityId.DEFIANT, 520, 93, 90, 101, 60, 81, 95, 45, 50, 260, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PERRSERKER, 8, false, false, false, "Viking Pokémon", PokemonType.STEEL, null, 0.8, 28, AbilityId.BATTLE_ARMOR, AbilityId.TOUGH_CLAWS, AbilityId.STEELY_SPIRIT, 440, 70, 110, 100, 50, 60, 50, 90, 50, 154, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CURSOLA, 8, false, false, false, "Coral Pokémon", PokemonType.GHOST, null, 1, 0.4, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.PERISH_BODY, 510, 60, 95, 50, 145, 130, 30, 30, 50, 179, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.SIRFETCHD, 8, false, false, false, "Wild Duck Pokémon", PokemonType.FIGHTING, null, 0.8, 117, AbilityId.STEADFAST, AbilityId.NONE, AbilityId.SCRAPPY, 507, 62, 135, 95, 68, 82, 65, 45, 50, 177, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MR_RIME, 8, false, false, false, "Comedian Pokémon", PokemonType.ICE, PokemonType.PSYCHIC, 1.5, 58.2, AbilityId.TANGLED_FEET, AbilityId.SCREEN_CLEANER, AbilityId.ICE_BODY, 520, 80, 85, 75, 110, 100, 70, 45, 50, 182, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.RUNERIGUS, 8, false, false, false, "Grudge Pokémon", PokemonType.GROUND, PokemonType.GHOST, 1.6, 66.6, AbilityId.WANDERING_SPIRIT, AbilityId.NONE, AbilityId.NONE, 483, 58, 95, 145, 50, 105, 30, 90, 50, 169, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.MILCERY, 8, false, false, false, "Cream Pokémon", PokemonType.FAIRY, null, 0.2, 0.3, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 270, 45, 40, 40, 50, 61, 34, 200, 50, 54, GrowthRate.MEDIUM_FAST, 0, false), - new PokemonSpecies(SpeciesId.ALCREMIE, 8, false, false, false, "Cream Pokémon", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, GrowthRate.MEDIUM_FAST, 0, false, true, - new PokemonForm("Vanilla Cream", "vanilla-cream", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, "", true), - new PokemonForm("Ruby Cream", "ruby-cream", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), - new PokemonForm("Matcha Cream", "matcha-cream", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), - new PokemonForm("Mint Cream", "mint-cream", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), - new PokemonForm("Lemon Cream", "lemon-cream", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), - new PokemonForm("Salted Cream", "salted-cream", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), - new PokemonForm("Ruby Swirl", "ruby-swirl", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), - new PokemonForm("Caramel Swirl", "caramel-swirl", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), - new PokemonForm("Rainbow Swirl", "rainbow-swirl", PokemonType.FAIRY, null, 0.3, 0.5, AbilityId.SWEET_VEIL, AbilityId.NONE, AbilityId.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FAIRY, null, 30, 999.9, AbilityId.MISTY_SURGE, AbilityId.NONE, AbilityId.MISTY_SURGE, 595, 105, 70, 85, 130, 141, 64, 100, 50, 173), - ), - new PokemonSpecies(SpeciesId.FALINKS, 8, false, false, false, "Formation Pokémon", PokemonType.FIGHTING, null, 3, 62, AbilityId.BATTLE_ARMOR, AbilityId.NONE, AbilityId.DEFIANT, 470, 65, 100, 100, 70, 60, 75, 45, 50, 165, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.PINCURCHIN, 8, false, false, false, "Sea Urchin Pokémon", PokemonType.ELECTRIC, null, 0.3, 1, AbilityId.LIGHTNING_ROD, AbilityId.NONE, AbilityId.ELECTRIC_SURGE, 435, 48, 101, 95, 91, 85, 15, 75, 50, 152, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SNOM, 8, false, false, false, "Worm Pokémon", PokemonType.ICE, PokemonType.BUG, 0.3, 3.8, AbilityId.SHIELD_DUST, AbilityId.NONE, AbilityId.ICE_SCALES, 185, 30, 25, 35, 45, 30, 20, 190, 50, 37, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.FROSMOTH, 8, false, false, false, "Frost Moth Pokémon", PokemonType.ICE, PokemonType.BUG, 1.3, 42, AbilityId.SHIELD_DUST, AbilityId.NONE, AbilityId.ICE_SCALES, 475, 70, 65, 60, 125, 90, 65, 75, 50, 166, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.STONJOURNER, 8, false, false, false, "Big Rock Pokémon", PokemonType.ROCK, null, 2.5, 520, AbilityId.POWER_SPOT, AbilityId.NONE, AbilityId.NONE, 470, 100, 125, 135, 20, 20, 70, 60, 50, 165, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.EISCUE, 8, false, false, false, "Penguin Pokémon", PokemonType.ICE, null, 1.4, 89, AbilityId.ICE_FACE, AbilityId.NONE, AbilityId.NONE, 470, 75, 80, 110, 65, 90, 50, 60, 50, 165, GrowthRate.SLOW, 50, false, false, - new PokemonForm("Ice Face", "", PokemonType.ICE, null, 1.4, 89, AbilityId.ICE_FACE, AbilityId.NONE, AbilityId.NONE, 470, 75, 80, 110, 65, 90, 50, 60, 50, 165, false, null, true), - new PokemonForm("No Ice", "no-ice", PokemonType.ICE, null, 1.4, 89, AbilityId.ICE_FACE, AbilityId.NONE, AbilityId.NONE, 470, 75, 80, 70, 65, 50, 130, 60, 50, 165), - ), - new PokemonSpecies(SpeciesId.INDEEDEE, 8, false, false, false, "Emotion Pokémon", PokemonType.PSYCHIC, PokemonType.NORMAL, 0.9, 28, AbilityId.INNER_FOCUS, AbilityId.SYNCHRONIZE, AbilityId.PSYCHIC_SURGE, 475, 60, 65, 55, 105, 95, 95, 30, 140, 166, GrowthRate.FAST, 50, false, false, - new PokemonForm("Male", "male", PokemonType.PSYCHIC, PokemonType.NORMAL, 0.9, 28, AbilityId.INNER_FOCUS, AbilityId.SYNCHRONIZE, AbilityId.PSYCHIC_SURGE, 475, 60, 65, 55, 105, 95, 95, 30, 140, 166, false, "", true), - new PokemonForm("Female", "female", PokemonType.PSYCHIC, PokemonType.NORMAL, 0.9, 28, AbilityId.OWN_TEMPO, AbilityId.SYNCHRONIZE, AbilityId.PSYCHIC_SURGE, 475, 70, 55, 65, 95, 105, 85, 30, 140, 166, false, null, true), - ), - new PokemonSpecies(SpeciesId.MORPEKO, 8, false, false, false, "Two-Sided Pokémon", PokemonType.ELECTRIC, PokemonType.DARK, 0.3, 3, AbilityId.HUNGER_SWITCH, AbilityId.NONE, AbilityId.NONE, 436, 58, 95, 58, 70, 58, 97, 180, 50, 153, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Full Belly Mode", "full-belly", PokemonType.ELECTRIC, PokemonType.DARK, 0.3, 3, AbilityId.HUNGER_SWITCH, AbilityId.NONE, AbilityId.NONE, 436, 58, 95, 58, 70, 58, 97, 180, 50, 153, false, "", true), - new PokemonForm("Hangry Mode", "hangry", PokemonType.ELECTRIC, PokemonType.DARK, 0.3, 3, AbilityId.HUNGER_SWITCH, AbilityId.NONE, AbilityId.NONE, 436, 58, 95, 58, 70, 58, 97, 180, 50, 153), - ), - new PokemonSpecies(SpeciesId.CUFANT, 8, false, false, false, "Copperderm Pokémon", PokemonType.STEEL, null, 1.2, 100, AbilityId.SHEER_FORCE, AbilityId.NONE, AbilityId.HEAVY_METAL, 330, 72, 80, 49, 40, 49, 40, 190, 50, 66, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.COPPERAJAH, 8, false, false, false, "Copperderm Pokémon", PokemonType.STEEL, null, 3, 650, AbilityId.SHEER_FORCE, AbilityId.NONE, AbilityId.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.STEEL, null, 3, 650, AbilityId.SHEER_FORCE, AbilityId.NONE, AbilityId.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.STEEL, PokemonType.GROUND, 23, 999.9, AbilityId.MOLD_BREAKER, AbilityId.NONE, AbilityId.MOLD_BREAKER, 600, 177, 155, 79, 90, 79, 20, 90, 50, 175), - ), - new PokemonSpecies(SpeciesId.DRACOZOLT, 8, false, false, false, "Fossil Pokémon", PokemonType.ELECTRIC, PokemonType.DRAGON, 1.8, 190, AbilityId.VOLT_ABSORB, AbilityId.HUSTLE, AbilityId.SAND_RUSH, 505, 90, 100, 90, 80, 70, 75, 45, 50, 177, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.ARCTOZOLT, 8, false, false, false, "Fossil Pokémon", PokemonType.ELECTRIC, PokemonType.ICE, 2.3, 150, AbilityId.VOLT_ABSORB, AbilityId.STATIC, AbilityId.SLUSH_RUSH, 505, 90, 100, 90, 90, 80, 55, 45, 50, 177, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.DRACOVISH, 8, false, false, false, "Fossil Pokémon", PokemonType.WATER, PokemonType.DRAGON, 2.3, 215, AbilityId.WATER_ABSORB, AbilityId.STRONG_JAW, AbilityId.SAND_RUSH, 505, 90, 90, 100, 70, 80, 75, 45, 50, 177, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.ARCTOVISH, 8, false, false, false, "Fossil Pokémon", PokemonType.WATER, PokemonType.ICE, 2, 175, AbilityId.WATER_ABSORB, AbilityId.ICE_BODY, AbilityId.SLUSH_RUSH, 505, 90, 90, 100, 80, 90, 55, 45, 50, 177, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.DURALUDON, 8, false, false, false, "Alloy Pokémon", PokemonType.STEEL, PokemonType.DRAGON, 1.8, 40, AbilityId.LIGHT_METAL, AbilityId.HEAVY_METAL, AbilityId.STALWART, 535, 70, 95, 115, 120, 50, 85, 45, 50, 187, GrowthRate.MEDIUM_FAST, 50, false, true, - new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.DRAGON, 1.8, 40, AbilityId.LIGHT_METAL, AbilityId.HEAVY_METAL, AbilityId.STALWART, 535, 70, 95, 115, 120, 50, 85, 45, 50, 187, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.STEEL, PokemonType.DRAGON, 43, 999.9, AbilityId.LIGHTNING_ROD, AbilityId.LIGHTNING_ROD, AbilityId.LIGHTNING_ROD, 635, 100, 110, 120, 175, 60, 70, 45, 50, 187), - ), - new PokemonSpecies(SpeciesId.DREEPY, 8, false, false, false, "Lingering Pokémon", PokemonType.DRAGON, PokemonType.GHOST, 0.5, 2, AbilityId.CLEAR_BODY, AbilityId.INFILTRATOR, AbilityId.CURSED_BODY, 270, 28, 60, 30, 40, 30, 82, 45, 50, 54, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.DRAKLOAK, 8, false, false, false, "Caretaker Pokémon", PokemonType.DRAGON, PokemonType.GHOST, 1.4, 11, AbilityId.CLEAR_BODY, AbilityId.INFILTRATOR, AbilityId.CURSED_BODY, 410, 68, 80, 50, 60, 50, 102, 45, 50, 144, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.DRAGAPULT, 8, false, false, false, "Stealth Pokémon", PokemonType.DRAGON, PokemonType.GHOST, 3, 50, AbilityId.CLEAR_BODY, AbilityId.INFILTRATOR, AbilityId.CURSED_BODY, 600, 88, 120, 75, 100, 75, 142, 45, 50, 300, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.ZACIAN, 8, false, true, false, "Warrior Pokémon", PokemonType.FAIRY, null, 2.8, 110, AbilityId.INTREPID_SWORD, AbilityId.NONE, AbilityId.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, GrowthRate.SLOW, null, false, false, - new PokemonForm("Hero of Many Battles", "hero-of-many-battles", PokemonType.FAIRY, null, 2.8, 110, AbilityId.INTREPID_SWORD, AbilityId.NONE, AbilityId.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, false, "", true), - new PokemonForm("Crowned", "crowned", PokemonType.FAIRY, PokemonType.STEEL, 2.8, 355, AbilityId.INTREPID_SWORD, AbilityId.NONE, AbilityId.NONE, 700, 92, 150, 115, 80, 115, 148, 10, 0, 360), - ), - new PokemonSpecies(SpeciesId.ZAMAZENTA, 8, false, true, false, "Warrior Pokémon", PokemonType.FIGHTING, null, 2.9, 210, AbilityId.DAUNTLESS_SHIELD, AbilityId.NONE, AbilityId.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, GrowthRate.SLOW, null, false, false, - new PokemonForm("Hero of Many Battles", "hero-of-many-battles", PokemonType.FIGHTING, null, 2.9, 210, AbilityId.DAUNTLESS_SHIELD, AbilityId.NONE, AbilityId.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, false, "", true), - new PokemonForm("Crowned", "crowned", PokemonType.FIGHTING, PokemonType.STEEL, 2.9, 785, AbilityId.DAUNTLESS_SHIELD, AbilityId.NONE, AbilityId.NONE, 700, 92, 120, 140, 80, 140, 128, 10, 0, 360), - ), - new PokemonSpecies(SpeciesId.ETERNATUS, 8, false, true, false, "Gigantic Pokémon", PokemonType.POISON, PokemonType.DRAGON, 20, 950, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 690, 140, 85, 95, 145, 95, 130, 255, 0, 345, GrowthRate.SLOW, null, false, true, - new PokemonForm("Normal", "", PokemonType.POISON, PokemonType.DRAGON, 20, 950, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 690, 140, 85, 95, 145, 95, 130, 255, 0, 345, false, null, true), - new PokemonForm("E-Max", "eternamax", PokemonType.POISON, PokemonType.DRAGON, 100, 999.9, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 1125, 255, 115, 250, 125, 250, 130, 255, 0, 345), - ), - new PokemonSpecies(SpeciesId.KUBFU, 8, true, false, false, "Wushu Pokémon", PokemonType.FIGHTING, null, 0.6, 12, AbilityId.INNER_FOCUS, AbilityId.NONE, AbilityId.NONE, 385, 60, 90, 60, 53, 50, 72, 3, 50, 77, GrowthRate.SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.URSHIFU, 8, true, false, false, "Wushu Pokémon", PokemonType.FIGHTING, PokemonType.DARK, 1.9, 105, AbilityId.UNSEEN_FIST, AbilityId.NONE, AbilityId.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, GrowthRate.SLOW, 87.5, false, true, - new PokemonForm("Single Strike Style", "single-strike", PokemonType.FIGHTING, PokemonType.DARK, 1.9, 105, AbilityId.UNSEEN_FIST, AbilityId.NONE, AbilityId.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, false, "", true), - new PokemonForm("Rapid Strike Style", "rapid-strike", PokemonType.FIGHTING, PokemonType.WATER, 1.9, 105, AbilityId.UNSEEN_FIST, AbilityId.NONE, AbilityId.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, false, null, true), - new PokemonForm("G-Max Single Strike Style", SpeciesFormKey.GIGANTAMAX_SINGLE, PokemonType.FIGHTING, PokemonType.DARK, 29, 999.9, AbilityId.UNSEEN_FIST, AbilityId.NONE, AbilityId.NONE, 650, 125, 145, 115, 83, 70, 112, 3, 50, 275), - new PokemonForm("G-Max Rapid Strike Style", SpeciesFormKey.GIGANTAMAX_RAPID, PokemonType.FIGHTING, PokemonType.WATER, 26, 999.9, AbilityId.UNSEEN_FIST, AbilityId.NONE, AbilityId.NONE, 650, 125, 145, 115, 83, 70, 112, 3, 50, 275), - ), - new PokemonSpecies(SpeciesId.ZARUDE, 8, false, false, true, "Rogue Monkey Pokémon", PokemonType.DARK, PokemonType.GRASS, 1.8, 70, AbilityId.LEAF_GUARD, AbilityId.NONE, AbilityId.NONE, 600, 105, 120, 105, 70, 95, 105, 3, 0, 300, GrowthRate.SLOW, null, false, false, - new PokemonForm("Normal", "", PokemonType.DARK, PokemonType.GRASS, 1.8, 70, AbilityId.LEAF_GUARD, AbilityId.NONE, AbilityId.NONE, 600, 105, 120, 105, 70, 95, 105, 3, 0, 300, false, null, true), - new PokemonForm("Dada", "dada", PokemonType.DARK, PokemonType.GRASS, 1.8, 70, AbilityId.LEAF_GUARD, AbilityId.NONE, AbilityId.NONE, 600, 105, 120, 105, 70, 95, 105, 3, 0, 300, false, null, true), - ), - new PokemonSpecies(SpeciesId.REGIELEKI, 8, true, false, false, "Electron Pokémon", PokemonType.ELECTRIC, null, 1.2, 145, AbilityId.TRANSISTOR, AbilityId.NONE, AbilityId.NONE, 580, 80, 100, 50, 100, 50, 200, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.REGIDRAGO, 8, true, false, false, "Dragon Orb Pokémon", PokemonType.DRAGON, null, 2.1, 200, AbilityId.DRAGONS_MAW, AbilityId.NONE, AbilityId.NONE, 580, 200, 100, 50, 100, 50, 80, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.GLASTRIER, 8, true, false, false, "Wild Horse Pokémon", PokemonType.ICE, null, 2.2, 800, AbilityId.CHILLING_NEIGH, AbilityId.NONE, AbilityId.NONE, 580, 100, 145, 130, 65, 110, 30, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.SPECTRIER, 8, true, false, false, "Swift Horse Pokémon", PokemonType.GHOST, null, 2, 44.5, AbilityId.GRIM_NEIGH, AbilityId.NONE, AbilityId.NONE, 580, 100, 65, 60, 145, 80, 130, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.CALYREX, 8, false, true, false, "King Pokémon", PokemonType.PSYCHIC, PokemonType.GRASS, 1.1, 7.7, AbilityId.UNNERVE, AbilityId.NONE, AbilityId.NONE, 500, 100, 80, 80, 80, 80, 80, 3, 100, 250, GrowthRate.SLOW, null, false, true, - new PokemonForm("Normal", "", PokemonType.PSYCHIC, PokemonType.GRASS, 1.1, 7.7, AbilityId.UNNERVE, AbilityId.NONE, AbilityId.NONE, 500, 100, 80, 80, 80, 80, 80, 3, 100, 250, false, null, true), - new PokemonForm("Ice", "ice", PokemonType.PSYCHIC, PokemonType.ICE, 2.4, 809.1, AbilityId.AS_ONE_GLASTRIER, AbilityId.NONE, AbilityId.NONE, 680, 100, 165, 150, 85, 130, 50, 3, 100, 340), - new PokemonForm("Shadow", "shadow", PokemonType.PSYCHIC, PokemonType.GHOST, 2.4, 53.6, AbilityId.AS_ONE_SPECTRIER, AbilityId.NONE, AbilityId.NONE, 680, 100, 85, 80, 165, 100, 150, 3, 100, 340), - ), - new PokemonSpecies(SpeciesId.WYRDEER, 8, false, false, false, "Big Horn Pokémon", PokemonType.NORMAL, PokemonType.PSYCHIC, 1.8, 95.1, AbilityId.INTIMIDATE, AbilityId.FRISK, AbilityId.SAP_SIPPER, 525, 103, 105, 72, 105, 75, 65, 45, 50, 263, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.KLEAVOR, 8, false, false, false, "Axe Pokémon", PokemonType.BUG, PokemonType.ROCK, 1.8, 89, AbilityId.SWARM, AbilityId.SHEER_FORCE, AbilityId.SHARPNESS, 500, 70, 135, 95, 45, 70, 85, 15, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.URSALUNA, 8, false, false, false, "Peat Pokémon", PokemonType.GROUND, PokemonType.NORMAL, 2.4, 290, AbilityId.GUTS, AbilityId.BULLETPROOF, AbilityId.UNNERVE, 550, 130, 140, 105, 45, 80, 50, 20, 50, 275, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BASCULEGION, 8, false, false, false, "Big Fish Pokémon", PokemonType.WATER, PokemonType.GHOST, 3, 110, AbilityId.SWIFT_SWIM, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 530, 120, 112, 65, 80, 75, 78, 45, 50, 265, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Male", "male", PokemonType.WATER, PokemonType.GHOST, 3, 110, AbilityId.SWIFT_SWIM, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 530, 120, 112, 65, 80, 75, 78, 45, 50, 265, false, "", true), - new PokemonForm("Female", "female", PokemonType.WATER, PokemonType.GHOST, 3, 110, AbilityId.SWIFT_SWIM, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 530, 120, 92, 65, 100, 75, 78, 45, 50, 265, false, null, true), - ), - new PokemonSpecies(SpeciesId.SNEASLER, 8, false, false, false, "Free Climb Pokémon", PokemonType.FIGHTING, PokemonType.POISON, 1.3, 43, AbilityId.PRESSURE, AbilityId.UNBURDEN, AbilityId.POISON_TOUCH, 510, 80, 130, 60, 40, 80, 120, 20, 50, 102, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.OVERQWIL, 8, false, false, false, "Pin Cluster Pokémon", PokemonType.DARK, PokemonType.POISON, 2.5, 60.5, AbilityId.POISON_POINT, AbilityId.SWIFT_SWIM, AbilityId.INTIMIDATE, 510, 85, 115, 95, 65, 65, 85, 45, 50, 179, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ENAMORUS, 8, true, false, false, "Love-Hate Pokémon", PokemonType.FAIRY, PokemonType.FLYING, 1.6, 48, AbilityId.CUTE_CHARM, AbilityId.NONE, AbilityId.CONTRARY, 580, 74, 115, 70, 135, 80, 106, 3, 50, 116, GrowthRate.SLOW, 0, false, true, - new PokemonForm("Incarnate Forme", "incarnate", PokemonType.FAIRY, PokemonType.FLYING, 1.6, 48, AbilityId.CUTE_CHARM, AbilityId.NONE, AbilityId.CONTRARY, 580, 74, 115, 70, 135, 80, 106, 3, 50, 116, false, null, true), - new PokemonForm("Therian Forme", "therian", PokemonType.FAIRY, PokemonType.FLYING, 1.6, 48, AbilityId.OVERCOAT, AbilityId.NONE, AbilityId.OVERCOAT, 580, 74, 115, 110, 135, 100, 46, 3, 50, 116), - ), - new PokemonSpecies(SpeciesId.SPRIGATITO, 9, false, false, false, "Grass Cat Pokémon", PokemonType.GRASS, null, 0.4, 4.1, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.PROTEAN, 310, 40, 61, 54, 45, 45, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.FLORAGATO, 9, false, false, false, "Grass Cat Pokémon", PokemonType.GRASS, null, 0.9, 12.2, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.PROTEAN, 410, 61, 80, 63, 60, 63, 83, 45, 50, 144, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.MEOWSCARADA, 9, false, false, false, "Magician Pokémon", PokemonType.GRASS, PokemonType.DARK, 1.5, 31.2, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.PROTEAN, 530, 76, 110, 70, 81, 70, 123, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.FUECOCO, 9, false, false, false, "Fire Croc Pokémon", PokemonType.FIRE, null, 0.4, 9.8, AbilityId.BLAZE, AbilityId.NONE, AbilityId.UNAWARE, 310, 67, 45, 59, 63, 40, 36, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.CROCALOR, 9, false, false, false, "Fire Croc Pokémon", PokemonType.FIRE, null, 1, 30.7, AbilityId.BLAZE, AbilityId.NONE, AbilityId.UNAWARE, 411, 81, 55, 78, 90, 58, 49, 45, 50, 144, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.SKELEDIRGE, 9, false, false, false, "Singer Pokémon", PokemonType.FIRE, PokemonType.GHOST, 1.6, 326.5, AbilityId.BLAZE, AbilityId.NONE, AbilityId.UNAWARE, 530, 104, 75, 100, 110, 75, 66, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.QUAXLY, 9, false, false, false, "Duckling Pokémon", PokemonType.WATER, null, 0.5, 6.1, AbilityId.TORRENT, AbilityId.NONE, AbilityId.MOXIE, 310, 55, 65, 45, 50, 45, 50, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.QUAXWELL, 9, false, false, false, "Practicing Pokémon", PokemonType.WATER, null, 1.2, 21.5, AbilityId.TORRENT, AbilityId.NONE, AbilityId.MOXIE, 410, 70, 85, 65, 65, 60, 65, 45, 50, 144, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.QUAQUAVAL, 9, false, false, false, "Dancer Pokémon", PokemonType.WATER, PokemonType.FIGHTING, 1.8, 61.9, AbilityId.TORRENT, AbilityId.NONE, AbilityId.MOXIE, 530, 85, 120, 80, 85, 75, 85, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.LECHONK, 9, false, false, false, "Hog Pokémon", PokemonType.NORMAL, null, 0.5, 10.2, AbilityId.AROMA_VEIL, AbilityId.GLUTTONY, AbilityId.THICK_FAT, 254, 54, 45, 40, 35, 45, 35, 255, 50, 51, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.OINKOLOGNE, 9, false, false, false, "Hog Pokémon", PokemonType.NORMAL, null, 1, 120, AbilityId.LINGERING_AROMA, AbilityId.GLUTTONY, AbilityId.THICK_FAT, 489, 110, 100, 75, 59, 80, 65, 100, 50, 171, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Male", "male", PokemonType.NORMAL, null, 1, 120, AbilityId.LINGERING_AROMA, AbilityId.GLUTTONY, AbilityId.THICK_FAT, 489, 110, 100, 75, 59, 80, 65, 100, 50, 171, false, "", true), - new PokemonForm("Female", "female", PokemonType.NORMAL, null, 1, 120, AbilityId.AROMA_VEIL, AbilityId.GLUTTONY, AbilityId.THICK_FAT, 489, 115, 90, 70, 59, 90, 65, 100, 50, 171, false, null, true), - ), - new PokemonSpecies(SpeciesId.TAROUNTULA, 9, false, false, false, "String Ball Pokémon", PokemonType.BUG, null, 0.3, 4, AbilityId.INSOMNIA, AbilityId.NONE, AbilityId.STAKEOUT, 210, 35, 41, 45, 29, 40, 20, 255, 50, 42, GrowthRate.ERRATIC, 50, false), - new PokemonSpecies(SpeciesId.SPIDOPS, 9, false, false, false, "Trap Pokémon", PokemonType.BUG, null, 1, 16.5, AbilityId.INSOMNIA, AbilityId.NONE, AbilityId.STAKEOUT, 404, 60, 79, 92, 52, 86, 35, 120, 50, 141, GrowthRate.ERRATIC, 50, false), - new PokemonSpecies(SpeciesId.NYMBLE, 9, false, false, false, "Grasshopper Pokémon", PokemonType.BUG, null, 0.2, 1, AbilityId.SWARM, AbilityId.NONE, AbilityId.TINTED_LENS, 210, 33, 46, 40, 21, 25, 45, 190, 20, 42, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.LOKIX, 9, false, false, false, "Grasshopper Pokémon", PokemonType.BUG, PokemonType.DARK, 1, 17.5, AbilityId.SWARM, AbilityId.NONE, AbilityId.TINTED_LENS, 450, 71, 102, 78, 52, 55, 92, 30, 0, 158, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PAWMI, 9, false, false, false, "Mouse Pokémon", PokemonType.ELECTRIC, null, 0.3, 2.5, AbilityId.STATIC, AbilityId.NATURAL_CURE, AbilityId.IRON_FIST, 240, 45, 50, 20, 40, 25, 60, 190, 50, 48, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PAWMO, 9, false, false, false, "Mouse Pokémon", PokemonType.ELECTRIC, PokemonType.FIGHTING, 0.4, 6.5, AbilityId.VOLT_ABSORB, AbilityId.NATURAL_CURE, AbilityId.IRON_FIST, 350, 60, 75, 40, 50, 40, 85, 80, 50, 123, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.PAWMOT, 9, false, false, false, "Hands-On Pokémon", PokemonType.ELECTRIC, PokemonType.FIGHTING, 0.9, 41, AbilityId.VOLT_ABSORB, AbilityId.NATURAL_CURE, AbilityId.IRON_FIST, 490, 70, 115, 70, 70, 60, 105, 45, 50, 245, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.TANDEMAUS, 9, false, false, false, "Couple Pokémon", PokemonType.NORMAL, null, 0.3, 1.8, AbilityId.RUN_AWAY, AbilityId.PICKUP, AbilityId.OWN_TEMPO, 305, 50, 50, 45, 40, 45, 75, 150, 50, 61, GrowthRate.FAST, null, false), - new PokemonSpecies(SpeciesId.MAUSHOLD, 9, false, false, false, "Family Pokémon", PokemonType.NORMAL, null, 0.3, 2.3, AbilityId.FRIEND_GUARD, AbilityId.CHEEK_POUCH, AbilityId.TECHNICIAN, 470, 74, 75, 70, 65, 75, 111, 75, 50, 165, GrowthRate.FAST, null, false, false, - new PokemonForm("Family of Four", "four", PokemonType.NORMAL, null, 0.3, 2.8, AbilityId.FRIEND_GUARD, AbilityId.CHEEK_POUCH, AbilityId.TECHNICIAN, 470, 74, 75, 70, 65, 75, 111, 75, 50, 165), - new PokemonForm("Family of Three", "three", PokemonType.NORMAL, null, 0.3, 2.3, AbilityId.FRIEND_GUARD, AbilityId.CHEEK_POUCH, AbilityId.TECHNICIAN, 470, 74, 75, 70, 65, 75, 111, 75, 50, 165), - ), - new PokemonSpecies(SpeciesId.FIDOUGH, 9, false, false, false, "Puppy Pokémon", PokemonType.FAIRY, null, 0.3, 10.9, AbilityId.OWN_TEMPO, AbilityId.NONE, AbilityId.KLUTZ, 312, 37, 55, 70, 30, 55, 65, 190, 50, 62, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.DACHSBUN, 9, false, false, false, "Dog Pokémon", PokemonType.FAIRY, null, 0.5, 14.9, AbilityId.WELL_BAKED_BODY, AbilityId.NONE, AbilityId.AROMA_VEIL, 477, 57, 80, 115, 50, 80, 95, 90, 50, 167, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SMOLIV, 9, false, false, false, "Olive Pokémon", PokemonType.GRASS, PokemonType.NORMAL, 0.3, 6.5, AbilityId.EARLY_BIRD, AbilityId.NONE, AbilityId.HARVEST, 260, 41, 35, 45, 58, 51, 30, 255, 50, 52, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.DOLLIV, 9, false, false, false, "Olive Pokémon", PokemonType.GRASS, PokemonType.NORMAL, 0.6, 11.9, AbilityId.EARLY_BIRD, AbilityId.NONE, AbilityId.HARVEST, 354, 52, 53, 60, 78, 78, 33, 120, 50, 124, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.ARBOLIVA, 9, false, false, false, "Olive Pokémon", PokemonType.GRASS, PokemonType.NORMAL, 1.4, 48.2, AbilityId.SEED_SOWER, AbilityId.NONE, AbilityId.HARVEST, 510, 78, 69, 90, 125, 109, 39, 45, 50, 255, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SQUAWKABILLY, 9, false, false, false, "Parrot Pokémon", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 2.4, AbilityId.INTIMIDATE, AbilityId.HUSTLE, AbilityId.GUTS, 417, 82, 96, 51, 45, 51, 92, 190, 50, 146, GrowthRate.ERRATIC, 50, false, false, - new PokemonForm("Green Plumage", "green-plumage", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 2.4, AbilityId.INTIMIDATE, AbilityId.HUSTLE, AbilityId.GUTS, 417, 82, 96, 51, 45, 51, 92, 190, 50, 146, false, null, true), - new PokemonForm("Blue Plumage", "blue-plumage", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 2.4, AbilityId.INTIMIDATE, AbilityId.HUSTLE, AbilityId.GUTS, 417, 82, 96, 51, 45, 51, 92, 190, 50, 146, false, null, true), - new PokemonForm("Yellow Plumage", "yellow-plumage", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 2.4, AbilityId.INTIMIDATE, AbilityId.HUSTLE, AbilityId.SHEER_FORCE, 417, 82, 96, 51, 45, 51, 92, 190, 50, 146, false, null, true), - new PokemonForm("White Plumage", "white-plumage", PokemonType.NORMAL, PokemonType.FLYING, 0.6, 2.4, AbilityId.INTIMIDATE, AbilityId.HUSTLE, AbilityId.SHEER_FORCE, 417, 82, 96, 51, 45, 51, 92, 190, 50, 146, false, null, true), - ), - new PokemonSpecies(SpeciesId.NACLI, 9, false, false, false, "Rock Salt Pokémon", PokemonType.ROCK, null, 0.4, 16, AbilityId.PURIFYING_SALT, AbilityId.STURDY, AbilityId.CLEAR_BODY, 280, 55, 55, 75, 35, 35, 25, 255, 50, 56, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.NACLSTACK, 9, false, false, false, "Rock Salt Pokémon", PokemonType.ROCK, null, 0.6, 105, AbilityId.PURIFYING_SALT, AbilityId.STURDY, AbilityId.CLEAR_BODY, 355, 60, 60, 100, 35, 65, 35, 120, 50, 124, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.GARGANACL, 9, false, false, false, "Rock Salt Pokémon", PokemonType.ROCK, null, 2.3, 240, AbilityId.PURIFYING_SALT, AbilityId.STURDY, AbilityId.CLEAR_BODY, 500, 100, 100, 130, 45, 90, 35, 45, 50, 250, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.CHARCADET, 9, false, false, false, "Fire Child Pokémon", PokemonType.FIRE, null, 0.6, 10.5, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.FLAME_BODY, 255, 40, 50, 40, 50, 40, 35, 90, 50, 51, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.ARMAROUGE, 9, false, false, false, "Fire Warrior Pokémon", PokemonType.FIRE, PokemonType.PSYCHIC, 1.5, 85, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.WEAK_ARMOR, 525, 85, 60, 100, 125, 80, 75, 25, 20, 263, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.CERULEDGE, 9, false, false, false, "Fire Blades Pokémon", PokemonType.FIRE, PokemonType.GHOST, 1.6, 62, AbilityId.FLASH_FIRE, AbilityId.NONE, AbilityId.WEAK_ARMOR, 525, 75, 125, 80, 60, 100, 85, 25, 20, 263, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.TADBULB, 9, false, false, false, "EleTadpole Pokémon", PokemonType.ELECTRIC, null, 0.3, 0.4, AbilityId.OWN_TEMPO, AbilityId.STATIC, AbilityId.DAMP, 272, 61, 31, 41, 59, 35, 45, 190, 50, 54, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BELLIBOLT, 9, false, false, false, "EleFrog Pokémon", PokemonType.ELECTRIC, null, 1.2, 113, AbilityId.ELECTROMORPHOSIS, AbilityId.STATIC, AbilityId.DAMP, 495, 109, 64, 91, 103, 83, 45, 50, 50, 173, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.WATTREL, 9, false, false, false, "Storm Petrel Pokémon", PokemonType.ELECTRIC, PokemonType.FLYING, 0.4, 3.6, AbilityId.WIND_POWER, AbilityId.VOLT_ABSORB, AbilityId.COMPETITIVE, 280, 40, 40, 35, 55, 40, 70, 180, 50, 56, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.KILOWATTREL, 9, false, false, false, "Frigatebird Pokémon", PokemonType.ELECTRIC, PokemonType.FLYING, 1.4, 38.6, AbilityId.WIND_POWER, AbilityId.VOLT_ABSORB, AbilityId.COMPETITIVE, 490, 70, 70, 60, 105, 60, 125, 90, 50, 172, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.MASCHIFF, 9, false, false, false, "Rascal Pokémon", PokemonType.DARK, null, 0.5, 16, AbilityId.INTIMIDATE, AbilityId.RUN_AWAY, AbilityId.STAKEOUT, 340, 60, 78, 60, 40, 51, 51, 150, 50, 68, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.MABOSSTIFF, 9, false, false, false, "Boss Pokémon", PokemonType.DARK, null, 1.1, 61, AbilityId.INTIMIDATE, AbilityId.GUARD_DOG, AbilityId.STAKEOUT, 505, 80, 120, 90, 60, 70, 85, 75, 50, 177, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.SHROODLE, 9, false, false, false, "Toxic Mouse Pokémon", PokemonType.POISON, PokemonType.NORMAL, 0.2, 0.7, AbilityId.UNBURDEN, AbilityId.PICKPOCKET, AbilityId.PRANKSTER, 290, 40, 65, 35, 40, 35, 75, 190, 50, 58, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.GRAFAIAI, 9, false, false, false, "Toxic Monkey Pokémon", PokemonType.POISON, PokemonType.NORMAL, 0.7, 27.2, AbilityId.UNBURDEN, AbilityId.POISON_TOUCH, AbilityId.PRANKSTER, 485, 63, 95, 65, 80, 72, 110, 90, 50, 170, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.BRAMBLIN, 9, false, false, false, "Tumbleweed Pokémon", PokemonType.GRASS, PokemonType.GHOST, 0.6, 0.6, AbilityId.WIND_RIDER, AbilityId.NONE, AbilityId.INFILTRATOR, 275, 40, 65, 30, 45, 35, 60, 190, 50, 55, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BRAMBLEGHAST, 9, false, false, false, "Tumbleweed Pokémon", PokemonType.GRASS, PokemonType.GHOST, 1.2, 6, AbilityId.WIND_RIDER, AbilityId.NONE, AbilityId.INFILTRATOR, 480, 55, 115, 70, 80, 70, 90, 45, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.TOEDSCOOL, 9, false, false, false, "Woodear Pokémon", PokemonType.GROUND, PokemonType.GRASS, 0.9, 33, AbilityId.MYCELIUM_MIGHT, AbilityId.NONE, AbilityId.NONE, 335, 40, 40, 35, 50, 100, 70, 190, 50, 67, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.TOEDSCRUEL, 9, false, false, false, "Woodear Pokémon", PokemonType.GROUND, PokemonType.GRASS, 1.9, 58, AbilityId.MYCELIUM_MIGHT, AbilityId.NONE, AbilityId.NONE, 515, 80, 70, 65, 80, 120, 100, 90, 50, 180, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.KLAWF, 9, false, false, false, "Ambush Pokémon", PokemonType.ROCK, null, 1.3, 79, AbilityId.ANGER_SHELL, AbilityId.SHELL_ARMOR, AbilityId.REGENERATOR, 450, 70, 100, 115, 35, 55, 75, 120, 50, 158, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CAPSAKID, 9, false, false, false, "Spicy Pepper Pokémon", PokemonType.GRASS, null, 0.3, 3, AbilityId.CHLOROPHYLL, AbilityId.INSOMNIA, AbilityId.KLUTZ, 304, 50, 62, 40, 62, 40, 50, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.SCOVILLAIN, 9, false, false, false, "Spicy Pepper Pokémon", PokemonType.GRASS, PokemonType.FIRE, 0.9, 15, AbilityId.CHLOROPHYLL, AbilityId.INSOMNIA, AbilityId.MOODY, 486, 65, 108, 65, 108, 65, 75, 75, 50, 170, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.RELLOR, 9, false, false, false, "Rolling Pokémon", PokemonType.BUG, null, 0.2, 1, AbilityId.COMPOUND_EYES, AbilityId.NONE, AbilityId.SHED_SKIN, 270, 41, 50, 60, 31, 58, 30, 190, 50, 54, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.RABSCA, 9, false, false, false, "Rolling Pokémon", PokemonType.BUG, PokemonType.PSYCHIC, 0.3, 3.5, AbilityId.SYNCHRONIZE, AbilityId.NONE, AbilityId.TELEPATHY, 470, 75, 50, 85, 115, 100, 45, 45, 50, 165, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.FLITTLE, 9, false, false, false, "Frill Pokémon", PokemonType.PSYCHIC, null, 0.2, 1.5, AbilityId.ANTICIPATION, AbilityId.FRISK, AbilityId.SPEED_BOOST, 255, 30, 35, 30, 55, 30, 75, 120, 50, 51, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.ESPATHRA, 9, false, false, false, "Ostrich Pokémon", PokemonType.PSYCHIC, null, 1.9, 90, AbilityId.OPPORTUNIST, AbilityId.FRISK, AbilityId.SPEED_BOOST, 481, 95, 60, 60, 101, 60, 105, 60, 50, 168, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.TINKATINK, 9, false, false, false, "Metalsmith Pokémon", PokemonType.FAIRY, PokemonType.STEEL, 0.4, 8.9, AbilityId.MOLD_BREAKER, AbilityId.OWN_TEMPO, AbilityId.PICKPOCKET, 297, 50, 45, 45, 35, 64, 58, 190, 50, 59, GrowthRate.MEDIUM_SLOW, 0, false), - new PokemonSpecies(SpeciesId.TINKATUFF, 9, false, false, false, "Hammer Pokémon", PokemonType.FAIRY, PokemonType.STEEL, 0.7, 59.1, AbilityId.MOLD_BREAKER, AbilityId.OWN_TEMPO, AbilityId.PICKPOCKET, 380, 65, 55, 55, 45, 82, 78, 90, 50, 133, GrowthRate.MEDIUM_SLOW, 0, false), - new PokemonSpecies(SpeciesId.TINKATON, 9, false, false, false, "Hammer Pokémon", PokemonType.FAIRY, PokemonType.STEEL, 0.7, 112.8, AbilityId.MOLD_BREAKER, AbilityId.OWN_TEMPO, AbilityId.PICKPOCKET, 506, 85, 75, 77, 70, 105, 94, 45, 50, 253, GrowthRate.MEDIUM_SLOW, 0, false), - new PokemonSpecies(SpeciesId.WIGLETT, 9, false, false, false, "Garden Eel Pokémon", PokemonType.WATER, null, 1.2, 1.8, AbilityId.GOOEY, AbilityId.RATTLED, AbilityId.SAND_VEIL, 245, 10, 55, 25, 35, 25, 95, 255, 50, 49, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.WUGTRIO, 9, false, false, false, "Garden Eel Pokémon", PokemonType.WATER, null, 1.2, 5.4, AbilityId.GOOEY, AbilityId.RATTLED, AbilityId.SAND_VEIL, 425, 35, 100, 50, 50, 70, 120, 50, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BOMBIRDIER, 9, false, false, false, "Item Drop Pokémon", PokemonType.FLYING, PokemonType.DARK, 1.5, 42.9, AbilityId.BIG_PECKS, AbilityId.KEEN_EYE, AbilityId.ROCKY_PAYLOAD, 485, 70, 103, 85, 60, 85, 82, 25, 50, 243, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.FINIZEN, 9, false, false, false, "Dolphin Pokémon", PokemonType.WATER, null, 1.3, 60.2, AbilityId.WATER_VEIL, AbilityId.NONE, AbilityId.NONE, 315, 70, 45, 40, 45, 40, 75, 200, 50, 63, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.PALAFIN, 9, false, false, false, "Dolphin Pokémon", PokemonType.WATER, null, 1.3, 60.2, AbilityId.ZERO_TO_HERO, AbilityId.NONE, AbilityId.NONE, 457, 100, 70, 72, 53, 62, 100, 45, 50, 160, GrowthRate.SLOW, 50, false, true, - new PokemonForm("Zero Form", "zero", PokemonType.WATER, null, 1.3, 60.2, AbilityId.ZERO_TO_HERO, AbilityId.NONE, AbilityId.ZERO_TO_HERO, 457, 100, 70, 72, 53, 62, 100, 45, 50, 160, false, null, true), - new PokemonForm("Hero Form", "hero", PokemonType.WATER, null, 1.8, 97.4, AbilityId.ZERO_TO_HERO, AbilityId.NONE, AbilityId.ZERO_TO_HERO, 650, 100, 160, 97, 106, 87, 100, 45, 50, 160), - ), - new PokemonSpecies(SpeciesId.VAROOM, 9, false, false, false, "Single-Cyl Pokémon", PokemonType.STEEL, PokemonType.POISON, 1, 35, AbilityId.OVERCOAT, AbilityId.NONE, AbilityId.SLOW_START, 300, 45, 70, 63, 30, 45, 47, 190, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.REVAVROOM, 9, false, false, false, "Multi-Cyl Pokémon", PokemonType.STEEL, PokemonType.POISON, 1.8, 120, AbilityId.OVERCOAT, AbilityId.NONE, AbilityId.FILTER, 500, 80, 119, 90, 54, 67, 90, 75, 50, 175, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.POISON, 1.8, 120, AbilityId.OVERCOAT, AbilityId.NONE, AbilityId.FILTER, 500, 80, 119, 90, 54, 67, 90, 75, 50, 175, false, null, true), - new PokemonForm("Segin Starmobile", "segin-starmobile", PokemonType.STEEL, PokemonType.DARK, 1.8, 240, AbilityId.INTIMIDATE, AbilityId.NONE, AbilityId.INTIMIDATE, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175, false, null, false, true), - new PokemonForm("Schedar Starmobile", "schedar-starmobile", PokemonType.STEEL, PokemonType.FIRE, 1.8, 240, AbilityId.SPEED_BOOST, AbilityId.NONE, AbilityId.SPEED_BOOST, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175, false, null, false, true), - new PokemonForm("Navi Starmobile", "navi-starmobile", PokemonType.STEEL, PokemonType.POISON, 1.8, 240, AbilityId.TOXIC_DEBRIS, AbilityId.NONE, AbilityId.TOXIC_DEBRIS, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175, false, null, false, true), - new PokemonForm("Ruchbah Starmobile", "ruchbah-starmobile", PokemonType.STEEL, PokemonType.FAIRY, 1.8, 240, AbilityId.MISTY_SURGE, AbilityId.NONE, AbilityId.MISTY_SURGE, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175, false, null, false, true), - new PokemonForm("Caph Starmobile", "caph-starmobile", PokemonType.STEEL, PokemonType.FIGHTING, 1.8, 240, AbilityId.STAMINA, AbilityId.NONE, AbilityId.STAMINA, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175, false, null, false, true), - ), - new PokemonSpecies(SpeciesId.CYCLIZAR, 9, false, false, false, "Mount Pokémon", PokemonType.DRAGON, PokemonType.NORMAL, 1.6, 63, AbilityId.SHED_SKIN, AbilityId.NONE, AbilityId.REGENERATOR, 501, 70, 95, 65, 85, 65, 121, 190, 50, 175, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.ORTHWORM, 9, false, false, false, "Earthworm Pokémon", PokemonType.STEEL, null, 2.5, 310, AbilityId.EARTH_EATER, AbilityId.NONE, AbilityId.SAND_VEIL, 480, 70, 85, 145, 60, 55, 65, 25, 50, 240, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.GLIMMET, 9, false, false, false, "Ore Pokémon", PokemonType.ROCK, PokemonType.POISON, 0.7, 8, AbilityId.TOXIC_DEBRIS, AbilityId.NONE, AbilityId.CORROSION, 350, 48, 35, 42, 105, 60, 60, 70, 50, 70, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.GLIMMORA, 9, false, false, false, "Ore Pokémon", PokemonType.ROCK, PokemonType.POISON, 1.5, 45, AbilityId.TOXIC_DEBRIS, AbilityId.NONE, AbilityId.CORROSION, 525, 83, 55, 90, 130, 81, 86, 25, 50, 184, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.GREAVARD, 9, false, false, false, "Ghost Dog Pokémon", PokemonType.GHOST, null, 0.6, 35, AbilityId.PICKUP, AbilityId.NONE, AbilityId.FLUFFY, 290, 50, 61, 60, 30, 55, 34, 120, 50, 58, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.HOUNDSTONE, 9, false, false, false, "Ghost Dog Pokémon", PokemonType.GHOST, null, 2, 15, AbilityId.SAND_RUSH, AbilityId.NONE, AbilityId.FLUFFY, 488, 72, 101, 100, 50, 97, 68, 60, 50, 171, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.FLAMIGO, 9, false, false, false, "Synchronize Pokémon", PokemonType.FLYING, PokemonType.FIGHTING, 1.6, 37, AbilityId.SCRAPPY, AbilityId.TANGLED_FEET, AbilityId.COSTAR, 500, 82, 115, 74, 75, 64, 90, 100, 50, 175, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.CETODDLE, 9, false, false, false, "Terra Whale Pokémon", PokemonType.ICE, null, 1.2, 45, AbilityId.THICK_FAT, AbilityId.SNOW_CLOAK, AbilityId.SHEER_FORCE, 334, 108, 68, 45, 30, 40, 43, 150, 50, 67, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.CETITAN, 9, false, false, false, "Terra Whale Pokémon", PokemonType.ICE, null, 4.5, 700, AbilityId.THICK_FAT, AbilityId.SLUSH_RUSH, AbilityId.SHEER_FORCE, 521, 170, 113, 65, 45, 55, 73, 50, 50, 182, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.VELUZA, 9, false, false, false, "Jettison Pokémon", PokemonType.WATER, PokemonType.PSYCHIC, 2.5, 90, AbilityId.MOLD_BREAKER, AbilityId.NONE, AbilityId.SHARPNESS, 478, 90, 102, 73, 78, 65, 70, 100, 50, 167, GrowthRate.FAST, 50, false), - new PokemonSpecies(SpeciesId.DONDOZO, 9, false, false, false, "Big Catfish Pokémon", PokemonType.WATER, null, 12, 220, AbilityId.UNAWARE, AbilityId.OBLIVIOUS, AbilityId.WATER_VEIL, 530, 150, 100, 115, 65, 65, 35, 25, 50, 265, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.TATSUGIRI, 9, false, false, false, "Mimicry Pokémon", PokemonType.DRAGON, PokemonType.WATER, 0.3, 8, AbilityId.COMMANDER, AbilityId.NONE, AbilityId.STORM_DRAIN, 475, 68, 50, 60, 120, 95, 82, 100, 50, 166, GrowthRate.MEDIUM_SLOW, 50, false, false, - new PokemonForm("Curly Form", "curly", PokemonType.DRAGON, PokemonType.WATER, 0.3, 8, AbilityId.COMMANDER, AbilityId.NONE, AbilityId.STORM_DRAIN, 475, 68, 50, 60, 120, 95, 82, 100, 50, 166, false, null, true), - new PokemonForm("Droopy Form", "droopy", PokemonType.DRAGON, PokemonType.WATER, 0.3, 8, AbilityId.COMMANDER, AbilityId.NONE, AbilityId.STORM_DRAIN, 475, 68, 50, 60, 120, 95, 82, 100, 50, 166, false, null, true), - new PokemonForm("Stretchy Form", "stretchy", PokemonType.DRAGON, PokemonType.WATER, 0.3, 8, AbilityId.COMMANDER, AbilityId.NONE, AbilityId.STORM_DRAIN, 475, 68, 50, 60, 120, 95, 82, 100, 50, 166, false, null, true), - ), - new PokemonSpecies(SpeciesId.ANNIHILAPE, 9, false, false, false, "Rage Monkey Pokémon", PokemonType.FIGHTING, PokemonType.GHOST, 1.2, 56, AbilityId.VITAL_SPIRIT, AbilityId.INNER_FOCUS, AbilityId.DEFIANT, 535, 110, 115, 80, 50, 90, 90, 45, 50, 268, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.CLODSIRE, 9, false, false, false, "Spiny Fish Pokémon", PokemonType.POISON, PokemonType.GROUND, 1.8, 223, AbilityId.POISON_POINT, AbilityId.WATER_ABSORB, AbilityId.UNAWARE, 430, 130, 75, 60, 45, 100, 20, 90, 50, 151, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.FARIGIRAF, 9, false, false, false, "Long Neck Pokémon", PokemonType.NORMAL, PokemonType.PSYCHIC, 3.2, 160, AbilityId.CUD_CHEW, AbilityId.ARMOR_TAIL, AbilityId.SAP_SIPPER, 520, 120, 90, 70, 110, 70, 60, 45, 50, 260, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.DUDUNSPARCE, 9, false, false, false, "Land Snake Pokémon", PokemonType.NORMAL, null, 3.6, 39.2, AbilityId.SERENE_GRACE, AbilityId.RUN_AWAY, AbilityId.RATTLED, 520, 125, 100, 80, 85, 75, 55, 45, 50, 182, GrowthRate.MEDIUM_FAST, 50, false, false, - new PokemonForm("Two-Segment Form", "two-segment", PokemonType.NORMAL, null, 3.6, 39.2, AbilityId.SERENE_GRACE, AbilityId.RUN_AWAY, AbilityId.RATTLED, 520, 125, 100, 80, 85, 75, 55, 45, 50, 182, false, ""), - new PokemonForm("Three-Segment Form", "three-segment", PokemonType.NORMAL, null, 4.5, 47.4, AbilityId.SERENE_GRACE, AbilityId.RUN_AWAY, AbilityId.RATTLED, 520, 125, 100, 80, 85, 75, 55, 45, 50, 182), - ), - new PokemonSpecies(SpeciesId.KINGAMBIT, 9, false, false, false, "Big Blade Pokémon", PokemonType.DARK, PokemonType.STEEL, 2, 120, AbilityId.DEFIANT, AbilityId.SUPREME_OVERLORD, AbilityId.PRESSURE, 550, 100, 135, 120, 60, 85, 50, 25, 50, 275, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GREAT_TUSK, 9, false, false, false, "Paradox Pokémon", PokemonType.GROUND, PokemonType.FIGHTING, 2.2, 320, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 570, 115, 131, 131, 53, 53, 87, 30, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.SCREAM_TAIL, 9, false, false, false, "Paradox Pokémon", PokemonType.FAIRY, PokemonType.PSYCHIC, 1.2, 8, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 570, 115, 65, 99, 65, 115, 111, 50, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.BRUTE_BONNET, 9, false, false, false, "Paradox Pokémon", PokemonType.GRASS, PokemonType.DARK, 1.2, 21, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 570, 111, 127, 99, 79, 99, 55, 50, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.FLUTTER_MANE, 9, false, false, false, "Paradox Pokémon", PokemonType.GHOST, PokemonType.FAIRY, 1.4, 4, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 570, 55, 55, 55, 135, 135, 135, 30, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.SLITHER_WING, 9, false, false, false, "Paradox Pokémon", PokemonType.BUG, PokemonType.FIGHTING, 3.2, 92, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 570, 85, 135, 79, 85, 105, 81, 30, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.SANDY_SHOCKS, 9, false, false, false, "Paradox Pokémon", PokemonType.ELECTRIC, PokemonType.GROUND, 2.3, 60, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 570, 85, 81, 97, 121, 85, 101, 30, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.IRON_TREADS, 9, false, false, false, "Paradox Pokémon", PokemonType.GROUND, PokemonType.STEEL, 0.9, 240, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 570, 90, 112, 120, 72, 70, 106, 30, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.IRON_BUNDLE, 9, false, false, false, "Paradox Pokémon", PokemonType.ICE, PokemonType.WATER, 0.6, 11, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 570, 56, 80, 114, 124, 60, 136, 50, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.IRON_HANDS, 9, false, false, false, "Paradox Pokémon", PokemonType.FIGHTING, PokemonType.ELECTRIC, 1.8, 380.7, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 570, 154, 140, 108, 50, 68, 50, 50, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.IRON_JUGULIS, 9, false, false, false, "Paradox Pokémon", PokemonType.DARK, PokemonType.FLYING, 1.3, 111, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 570, 94, 80, 86, 122, 80, 108, 30, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.IRON_MOTH, 9, false, false, false, "Paradox Pokémon", PokemonType.FIRE, PokemonType.POISON, 1.2, 36, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 570, 80, 70, 60, 140, 110, 110, 30, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.IRON_THORNS, 9, false, false, false, "Paradox Pokémon", PokemonType.ROCK, PokemonType.ELECTRIC, 1.6, 303, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 570, 100, 134, 110, 70, 84, 72, 30, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.FRIGIBAX, 9, false, false, false, "Ice Fin Pokémon", PokemonType.DRAGON, PokemonType.ICE, 0.5, 17, AbilityId.THERMAL_EXCHANGE, AbilityId.NONE, AbilityId.ICE_BODY, 320, 65, 75, 45, 35, 45, 55, 45, 50, 64, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.ARCTIBAX, 9, false, false, false, "Ice Fin Pokémon", PokemonType.DRAGON, PokemonType.ICE, 0.8, 30, AbilityId.THERMAL_EXCHANGE, AbilityId.NONE, AbilityId.ICE_BODY, 423, 90, 95, 66, 45, 65, 62, 25, 50, 148, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.BAXCALIBUR, 9, false, false, false, "Ice Dragon Pokémon", PokemonType.DRAGON, PokemonType.ICE, 2.1, 210, AbilityId.THERMAL_EXCHANGE, AbilityId.NONE, AbilityId.ICE_BODY, 600, 115, 145, 92, 75, 86, 87, 10, 50, 300, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.GIMMIGHOUL, 9, false, false, false, "Coin Chest Pokémon", PokemonType.GHOST, null, 0.3, 5, AbilityId.RATTLED, AbilityId.NONE, AbilityId.NONE, 300, 45, 30, 70, 75, 70, 10, 45, 50, 60, GrowthRate.SLOW, null, false, false, - new PokemonForm("Chest Form", "chest", PokemonType.GHOST, null, 0.3, 5, AbilityId.RATTLED, AbilityId.NONE, AbilityId.NONE, 300, 45, 30, 70, 75, 70, 10, 45, 50, 60, false, "", true), - new PokemonForm("Roaming Form", "roaming", PokemonType.GHOST, null, 0.1, 1, AbilityId.RUN_AWAY, AbilityId.NONE, AbilityId.NONE, 300, 45, 30, 25, 75, 45, 80, 45, 50, 60, false, null, true), - ), - new PokemonSpecies(SpeciesId.GHOLDENGO, 9, false, false, false, "Coin Entity Pokémon", PokemonType.STEEL, PokemonType.GHOST, 1.2, 30, AbilityId.GOOD_AS_GOLD, AbilityId.NONE, AbilityId.NONE, 550, 87, 60, 95, 133, 91, 84, 45, 50, 275, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.WO_CHIEN, 9, true, false, false, "Ruinous Pokémon", PokemonType.DARK, PokemonType.GRASS, 1.5, 74.2, AbilityId.TABLETS_OF_RUIN, AbilityId.NONE, AbilityId.NONE, 570, 85, 85, 100, 95, 135, 70, 6, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.CHIEN_PAO, 9, true, false, false, "Ruinous Pokémon", PokemonType.DARK, PokemonType.ICE, 1.9, 152.2, AbilityId.SWORD_OF_RUIN, AbilityId.NONE, AbilityId.NONE, 570, 80, 120, 80, 90, 65, 135, 6, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.TING_LU, 9, true, false, false, "Ruinous Pokémon", PokemonType.DARK, PokemonType.GROUND, 2.7, 699.7, AbilityId.VESSEL_OF_RUIN, AbilityId.NONE, AbilityId.NONE, 570, 155, 110, 125, 55, 80, 45, 6, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.CHI_YU, 9, true, false, false, "Ruinous Pokémon", PokemonType.DARK, PokemonType.FIRE, 0.4, 4.9, AbilityId.BEADS_OF_RUIN, AbilityId.NONE, AbilityId.NONE, 570, 55, 80, 80, 135, 120, 100, 6, 0, 285, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.ROARING_MOON, 9, false, false, false, "Paradox Pokémon", PokemonType.DRAGON, PokemonType.DARK, 2, 380, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 590, 105, 139, 71, 55, 101, 119, 10, 0, 295, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.IRON_VALIANT, 9, false, false, false, "Paradox Pokémon", PokemonType.FAIRY, PokemonType.FIGHTING, 1.4, 35, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 590, 74, 130, 90, 120, 60, 116, 10, 0, 295, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.KORAIDON, 9, false, true, false, "Paradox Pokémon", PokemonType.FIGHTING, PokemonType.DRAGON, 2.5, 303, AbilityId.ORICHALCUM_PULSE, AbilityId.NONE, AbilityId.NONE, 670, 100, 135, 115, 85, 100, 135, 3, 0, 335, GrowthRate.SLOW, null, false, false, - new PokemonForm("Apex Build", "apex-build", PokemonType.FIGHTING, PokemonType.DRAGON, 2.5, 303, AbilityId.ORICHALCUM_PULSE, AbilityId.NONE, AbilityId.NONE, 670, 100, 135, 115, 85, 100, 135, 3, 0, 335, false, null, true), - ), - new PokemonSpecies(SpeciesId.MIRAIDON, 9, false, true, false, "Paradox Pokémon", PokemonType.ELECTRIC, PokemonType.DRAGON, 3.5, 240, AbilityId.HADRON_ENGINE, AbilityId.NONE, AbilityId.NONE, 670, 100, 85, 100, 135, 115, 135, 3, 0, 335, GrowthRate.SLOW, null, false, false, - new PokemonForm("Ultimate Mode", "ultimate-mode", PokemonType.ELECTRIC, PokemonType.DRAGON, 3.5, 240, AbilityId.HADRON_ENGINE, AbilityId.NONE, AbilityId.NONE, 670, 100, 85, 100, 135, 115, 135, 3, 0, 335, false, null, true), - ), - new PokemonSpecies(SpeciesId.WALKING_WAKE, 9, false, false, false, "Paradox Pokémon", PokemonType.WATER, PokemonType.DRAGON, 3.5, 280, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 590, 99, 83, 91, 125, 83, 109, 10, 0, 295, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Gouging Fire and Raging Bolt - new PokemonSpecies(SpeciesId.IRON_LEAVES, 9, false, false, false, "Paradox Pokémon", PokemonType.GRASS, PokemonType.PSYCHIC, 1.5, 125, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 590, 90, 130, 88, 70, 108, 104, 10, 0, 295, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Iron Boulder and Iron Crown - new PokemonSpecies(SpeciesId.DIPPLIN, 9, false, false, false, "Candy Apple Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 0.4, 4.4, AbilityId.SUPERSWEET_SYRUP, AbilityId.GLUTTONY, AbilityId.STICKY_HOLD, 485, 80, 80, 110, 95, 80, 40, 45, 50, 170, GrowthRate.ERRATIC, 50, false), - new PokemonSpecies(SpeciesId.POLTCHAGEIST, 9, false, false, false, "Matcha Pokémon", PokemonType.GRASS, PokemonType.GHOST, 0.1, 1.1, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, GrowthRate.SLOW, null, false, false, - new PokemonForm("Counterfeit Form", "counterfeit", PokemonType.GRASS, PokemonType.GHOST, 0.1, 1.1, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, null, true), - new PokemonForm("Artisan Form", "artisan", PokemonType.GRASS, PokemonType.GHOST, 0.1, 1.1, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, "counterfeit", true), - ), - new PokemonSpecies(SpeciesId.SINISTCHA, 9, false, false, false, "Matcha Pokémon", PokemonType.GRASS, PokemonType.GHOST, 0.2, 2.2, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 508, 71, 60, 106, 121, 80, 70, 60, 50, 178, GrowthRate.SLOW, null, false, false, - new PokemonForm("Unremarkable Form", "unremarkable", PokemonType.GRASS, PokemonType.GHOST, 0.2, 2.2, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 508, 71, 60, 106, 121, 80, 70, 60, 50, 178, false, null, true), - new PokemonForm("Masterpiece Form", "masterpiece", PokemonType.GRASS, PokemonType.GHOST, 0.2, 2.2, AbilityId.HOSPITALITY, AbilityId.NONE, AbilityId.HEATPROOF, 508, 71, 60, 106, 121, 80, 70, 60, 50, 178, false, "unremarkable", true), - ), - new PokemonSpecies(SpeciesId.OKIDOGI, 9, true, false, false, "Retainer Pokémon", PokemonType.POISON, PokemonType.FIGHTING, 1.8, 92.2, AbilityId.TOXIC_CHAIN, AbilityId.NONE, AbilityId.GUARD_DOG, 555, 88, 128, 115, 58, 86, 80, 3, 0, 276, GrowthRate.SLOW, 100, false), - new PokemonSpecies(SpeciesId.MUNKIDORI, 9, true, false, false, "Retainer Pokémon", PokemonType.POISON, PokemonType.PSYCHIC, 1, 12.2, AbilityId.TOXIC_CHAIN, AbilityId.NONE, AbilityId.FRISK, 555, 88, 75, 66, 130, 90, 106, 3, 0, 276, GrowthRate.SLOW, 100, false), - new PokemonSpecies(SpeciesId.FEZANDIPITI, 9, true, false, false, "Retainer Pokémon", PokemonType.POISON, PokemonType.FAIRY, 1.4, 30.1, AbilityId.TOXIC_CHAIN, AbilityId.NONE, AbilityId.TECHNICIAN, 555, 88, 91, 82, 70, 125, 99, 3, 0, 276, GrowthRate.SLOW, 100, false), - new PokemonSpecies(SpeciesId.OGERPON, 9, true, false, false, "Mask Pokémon", PokemonType.GRASS, null, 1.2, 39.8, AbilityId.DEFIANT, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275, GrowthRate.SLOW, 0, false, false, - new PokemonForm("Teal Mask", "teal-mask", PokemonType.GRASS, null, 1.2, 39.8, AbilityId.DEFIANT, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275, false, null, true), - new PokemonForm("Wellspring Mask", "wellspring-mask", PokemonType.GRASS, PokemonType.WATER, 1.2, 39.8, AbilityId.WATER_ABSORB, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275), - new PokemonForm("Hearthflame Mask", "hearthflame-mask", PokemonType.GRASS, PokemonType.FIRE, 1.2, 39.8, AbilityId.MOLD_BREAKER, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275), - new PokemonForm("Cornerstone Mask", "cornerstone-mask", PokemonType.GRASS, PokemonType.ROCK, 1.2, 39.8, AbilityId.STURDY, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275), - new PokemonForm("Teal Mask Terastallized", "teal-mask-tera", PokemonType.GRASS, null, 1.2, 39.8, AbilityId.EMBODY_ASPECT_TEAL, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275), - new PokemonForm("Wellspring Mask Terastallized", "wellspring-mask-tera", PokemonType.GRASS, PokemonType.WATER, 1.2, 39.8, AbilityId.EMBODY_ASPECT_WELLSPRING, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275), - new PokemonForm("Hearthflame Mask Terastallized", "hearthflame-mask-tera", PokemonType.GRASS, PokemonType.FIRE, 1.2, 39.8, AbilityId.EMBODY_ASPECT_HEARTHFLAME, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275), - new PokemonForm("Cornerstone Mask Terastallized", "cornerstone-mask-tera", PokemonType.GRASS, PokemonType.ROCK, 1.2, 39.8, AbilityId.EMBODY_ASPECT_CORNERSTONE, AbilityId.NONE, AbilityId.NONE, 550, 80, 120, 84, 60, 96, 110, 5, 50, 275), - ), - new PokemonSpecies(SpeciesId.ARCHALUDON, 9, false, false, false, "Alloy Pokémon", PokemonType.STEEL, PokemonType.DRAGON, 2, 60, AbilityId.STAMINA, AbilityId.STURDY, AbilityId.STALWART, 600, 90, 105, 130, 125, 65, 85, 10, 50, 300, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.HYDRAPPLE, 9, false, false, false, "Apple Hydra Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 1.8, 93, AbilityId.SUPERSWEET_SYRUP, AbilityId.REGENERATOR, AbilityId.STICKY_HOLD, 540, 106, 80, 110, 120, 80, 44, 10, 50, 270, GrowthRate.ERRATIC, 50, false), - new PokemonSpecies(SpeciesId.GOUGING_FIRE, 9, false, false, false, "Paradox Pokémon", PokemonType.FIRE, PokemonType.DRAGON, 3.5, 590, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 590, 105, 115, 121, 65, 93, 91, 10, 0, 295, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.RAGING_BOLT, 9, false, false, false, "Paradox Pokémon", PokemonType.ELECTRIC, PokemonType.DRAGON, 5.2, 480, AbilityId.PROTOSYNTHESIS, AbilityId.NONE, AbilityId.NONE, 590, 125, 73, 91, 137, 89, 75, 10, 0, 295, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.IRON_BOULDER, 9, false, false, false, "Paradox Pokémon", PokemonType.ROCK, PokemonType.PSYCHIC, 1.5, 162.5, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 590, 90, 120, 80, 68, 108, 124, 10, 0, 295, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.IRON_CROWN, 9, false, false, false, "Paradox Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 1.6, 156, AbilityId.QUARK_DRIVE, AbilityId.NONE, AbilityId.NONE, 590, 90, 72, 100, 122, 108, 98, 10, 0, 295, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.TERAPAGOS, 9, false, true, false, "Tera Pokémon", PokemonType.NORMAL, null, 0.2, 6.5, AbilityId.TERA_SHIFT, AbilityId.NONE, AbilityId.NONE, 450, 90, 65, 85, 65, 85, 60, 5, 50, 90, GrowthRate.SLOW, 50, false, false, - new PokemonForm("Normal Form", "", PokemonType.NORMAL, null, 0.2, 6.5, AbilityId.TERA_SHIFT, AbilityId.NONE, AbilityId.NONE, 450, 90, 65, 85, 65, 85, 60, 5, 50, 90, false, null, true), - new PokemonForm("Terastal Form", "terastal", PokemonType.NORMAL, null, 0.3, 16, AbilityId.TERA_SHELL, AbilityId.NONE, AbilityId.NONE, 600, 95, 95, 110, 105, 110, 85, 5, 50, 120), - new PokemonForm("Stellar Form", "stellar", PokemonType.NORMAL, null, 1.7, 77, AbilityId.TERAFORM_ZERO, AbilityId.NONE, AbilityId.NONE, 700, 160, 105, 110, 130, 110, 85, 5, 50, 140), - ), - new PokemonSpecies(SpeciesId.PECHARUNT, 9, false, false, true, "Subjugation Pokémon", PokemonType.POISON, PokemonType.GHOST, 0.3, 0.3, AbilityId.POISON_PUPPETEER, AbilityId.NONE, AbilityId.NONE, 600, 88, 88, 160, 88, 88, 88, 3, 0, 300, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.ALOLA_RATTATA, 7, false, false, false, "Mouse Pokémon", PokemonType.DARK, PokemonType.NORMAL, 0.3, 3.8, AbilityId.GLUTTONY, AbilityId.HUSTLE, AbilityId.THICK_FAT, 253, 30, 56, 35, 25, 35, 72, 255, 70, 51, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_RATICATE, 7, false, false, false, "Mouse Pokémon", PokemonType.DARK, PokemonType.NORMAL, 0.7, 25.5, AbilityId.GLUTTONY, AbilityId.HUSTLE, AbilityId.THICK_FAT, 413, 75, 71, 70, 40, 80, 77, 127, 70, 145, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_RAICHU, 7, false, false, false, "Mouse Pokémon", PokemonType.ELECTRIC, PokemonType.PSYCHIC, 0.7, 21, AbilityId.SURGE_SURFER, AbilityId.NONE, AbilityId.NONE, 485, 60, 85, 50, 95, 85, 110, 75, 50, 243, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_SANDSHREW, 7, false, false, false, "Mouse Pokémon", PokemonType.ICE, PokemonType.STEEL, 0.7, 40, AbilityId.SNOW_CLOAK, AbilityId.NONE, AbilityId.SLUSH_RUSH, 300, 50, 75, 90, 10, 35, 40, 255, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_SANDSLASH, 7, false, false, false, "Mouse Pokémon", PokemonType.ICE, PokemonType.STEEL, 1.2, 55, AbilityId.SNOW_CLOAK, AbilityId.NONE, AbilityId.SLUSH_RUSH, 450, 75, 100, 120, 25, 65, 65, 90, 50, 158, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_VULPIX, 7, false, false, false, "Fox Pokémon", PokemonType.ICE, null, 0.6, 9.9, AbilityId.SNOW_CLOAK, AbilityId.NONE, AbilityId.SNOW_WARNING, 299, 38, 41, 40, 50, 65, 65, 190, 50, 60, GrowthRate.MEDIUM_FAST, 25, false), - new PokemonSpecies(SpeciesId.ALOLA_NINETALES, 7, false, false, false, "Fox Pokémon", PokemonType.ICE, PokemonType.FAIRY, 1.1, 19.9, AbilityId.SNOW_CLOAK, AbilityId.NONE, AbilityId.SNOW_WARNING, 505, 73, 67, 75, 81, 100, 109, 75, 50, 177, GrowthRate.MEDIUM_FAST, 25, false), - new PokemonSpecies(SpeciesId.ALOLA_DIGLETT, 7, false, false, false, "Mole Pokémon", PokemonType.GROUND, PokemonType.STEEL, 0.2, 1, AbilityId.SAND_VEIL, AbilityId.TANGLING_HAIR, AbilityId.SAND_FORCE, 265, 10, 55, 30, 35, 45, 90, 255, 50, 53, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_DUGTRIO, 7, false, false, false, "Mole Pokémon", PokemonType.GROUND, PokemonType.STEEL, 0.7, 66.6, AbilityId.SAND_VEIL, AbilityId.TANGLING_HAIR, AbilityId.SAND_FORCE, 425, 35, 100, 60, 50, 70, 110, 50, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_MEOWTH, 7, false, false, false, "Scratch Cat Pokémon", PokemonType.DARK, null, 0.4, 4.2, AbilityId.PICKUP, AbilityId.TECHNICIAN, AbilityId.RATTLED, 290, 40, 35, 35, 50, 40, 90, 255, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_PERSIAN, 7, false, false, false, "Classy Cat Pokémon", PokemonType.DARK, null, 1.1, 33, AbilityId.FUR_COAT, AbilityId.TECHNICIAN, AbilityId.RATTLED, 440, 65, 60, 60, 75, 65, 115, 90, 50, 154, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_GEODUDE, 7, false, false, false, "Rock Pokémon", PokemonType.ROCK, PokemonType.ELECTRIC, 0.4, 20.3, AbilityId.MAGNET_PULL, AbilityId.STURDY, AbilityId.GALVANIZE, 300, 40, 80, 100, 30, 30, 20, 255, 70, 60, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_GRAVELER, 7, false, false, false, "Rock Pokémon", PokemonType.ROCK, PokemonType.ELECTRIC, 1, 110, AbilityId.MAGNET_PULL, AbilityId.STURDY, AbilityId.GALVANIZE, 390, 55, 95, 115, 45, 45, 35, 120, 70, 137, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_GOLEM, 7, false, false, false, "Megaton Pokémon", PokemonType.ROCK, PokemonType.ELECTRIC, 1.7, 316, AbilityId.MAGNET_PULL, AbilityId.STURDY, AbilityId.GALVANIZE, 495, 80, 120, 130, 55, 65, 45, 45, 70, 223, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_GRIMER, 7, false, false, false, "Sludge Pokémon", PokemonType.POISON, PokemonType.DARK, 0.7, 42, AbilityId.POISON_TOUCH, AbilityId.GLUTTONY, AbilityId.POWER_OF_ALCHEMY, 325, 80, 80, 50, 40, 50, 25, 190, 70, 65, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_MUK, 7, false, false, false, "Sludge Pokémon", PokemonType.POISON, PokemonType.DARK, 1, 52, AbilityId.POISON_TOUCH, AbilityId.GLUTTONY, AbilityId.POWER_OF_ALCHEMY, 500, 105, 105, 75, 65, 100, 50, 75, 70, 175, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_EXEGGUTOR, 7, false, false, false, "Coconut Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 10.9, 415.6, AbilityId.FRISK, AbilityId.NONE, AbilityId.HARVEST, 530, 95, 105, 85, 125, 75, 45, 45, 50, 186, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.ALOLA_MAROWAK, 7, false, false, false, "Bone Keeper Pokémon", PokemonType.FIRE, PokemonType.GHOST, 1, 34, AbilityId.CURSED_BODY, AbilityId.LIGHTNING_ROD, AbilityId.ROCK_HEAD, 425, 60, 80, 110, 50, 80, 45, 75, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.ETERNAL_FLOETTE, 6, true, false, false, "Single Bloom Pokémon", PokemonType.FAIRY, null, 0.2, 0.9, AbilityId.FLOWER_VEIL, AbilityId.NONE, AbilityId.SYMBIOSIS, 551, 74, 65, 67, 125, 128, 92, 120, 70, 243, GrowthRate.MEDIUM_FAST, 0, false), //Marked as Sub-Legend, for casing purposes - new PokemonSpecies(SpeciesId.GALAR_MEOWTH, 8, false, false, false, "Scratch Cat Pokémon", PokemonType.STEEL, null, 0.4, 7.5, AbilityId.PICKUP, AbilityId.TOUGH_CLAWS, AbilityId.UNNERVE, 290, 50, 65, 55, 40, 40, 40, 255, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GALAR_PONYTA, 8, false, false, false, "Fire Horse Pokémon", PokemonType.PSYCHIC, null, 0.8, 24, AbilityId.RUN_AWAY, AbilityId.PASTEL_VEIL, AbilityId.ANTICIPATION, 410, 50, 85, 55, 65, 65, 90, 190, 50, 82, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GALAR_RAPIDASH, 8, false, false, false, "Fire Horse Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 1.7, 80, AbilityId.RUN_AWAY, AbilityId.PASTEL_VEIL, AbilityId.ANTICIPATION, 500, 65, 100, 70, 80, 80, 105, 60, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GALAR_SLOWPOKE, 8, false, false, false, "Dopey Pokémon", PokemonType.PSYCHIC, null, 1.2, 36, AbilityId.GLUTTONY, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 315, 90, 65, 65, 40, 40, 15, 190, 50, 63, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GALAR_SLOWBRO, 8, false, false, false, "Hermit Crab Pokémon", PokemonType.POISON, PokemonType.PSYCHIC, 1.6, 70.5, AbilityId.QUICK_DRAW, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 490, 95, 100, 95, 100, 70, 30, 75, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GALAR_FARFETCHD, 8, false, false, false, "Wild Duck Pokémon", PokemonType.FIGHTING, null, 0.8, 42, AbilityId.STEADFAST, AbilityId.NONE, AbilityId.SCRAPPY, 377, 52, 95, 55, 58, 62, 55, 45, 50, 132, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GALAR_WEEZING, 8, false, false, false, "Poison Gas Pokémon", PokemonType.POISON, PokemonType.FAIRY, 3, 16, AbilityId.LEVITATE, AbilityId.NEUTRALIZING_GAS, AbilityId.MISTY_SURGE, 490, 65, 90, 120, 85, 70, 60, 60, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GALAR_MR_MIME, 8, false, false, false, "Barrier Pokémon", PokemonType.ICE, PokemonType.PSYCHIC, 1.4, 56.8, AbilityId.VITAL_SPIRIT, AbilityId.SCREEN_CLEANER, AbilityId.ICE_BODY, 460, 50, 65, 65, 90, 90, 100, 45, 50, 161, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GALAR_ARTICUNO, 8, true, false, false, "Freeze Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 1.7, 50.9, AbilityId.COMPETITIVE, AbilityId.NONE, AbilityId.NONE, 580, 90, 85, 85, 125, 100, 95, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.GALAR_ZAPDOS, 8, true, false, false, "Electric Pokémon", PokemonType.FIGHTING, PokemonType.FLYING, 1.6, 58.2, AbilityId.DEFIANT, AbilityId.NONE, AbilityId.NONE, 580, 90, 125, 90, 85, 90, 100, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.GALAR_MOLTRES, 8, true, false, false, "Flame Pokémon", PokemonType.DARK, PokemonType.FLYING, 2, 66, AbilityId.BERSERK, AbilityId.NONE, AbilityId.NONE, 580, 90, 85, 90, 100, 125, 90, 3, 35, 290, GrowthRate.SLOW, null, false), - new PokemonSpecies(SpeciesId.GALAR_SLOWKING, 8, false, false, false, "Royal Pokémon", PokemonType.POISON, PokemonType.PSYCHIC, 1.8, 79.5, AbilityId.CURIOUS_MEDICINE, AbilityId.OWN_TEMPO, AbilityId.REGENERATOR, 490, 95, 65, 80, 110, 110, 30, 70, 50, 172, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GALAR_CORSOLA, 8, false, false, false, "Coral Pokémon", PokemonType.GHOST, null, 0.6, 0.5, AbilityId.WEAK_ARMOR, AbilityId.NONE, AbilityId.CURSED_BODY, 410, 60, 55, 100, 65, 100, 30, 60, 50, 144, GrowthRate.FAST, 25, false), - new PokemonSpecies(SpeciesId.GALAR_ZIGZAGOON, 8, false, false, false, "Tiny Raccoon Pokémon", PokemonType.DARK, PokemonType.NORMAL, 0.4, 17.5, AbilityId.PICKUP, AbilityId.GLUTTONY, AbilityId.QUICK_FEET, 240, 38, 30, 41, 30, 41, 60, 255, 50, 56, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GALAR_LINOONE, 8, false, false, false, "Rushing Pokémon", PokemonType.DARK, PokemonType.NORMAL, 0.5, 32.5, AbilityId.PICKUP, AbilityId.GLUTTONY, AbilityId.QUICK_FEET, 420, 78, 70, 61, 50, 61, 100, 90, 50, 147, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GALAR_DARUMAKA, 8, false, false, false, "Zen Charm Pokémon", PokemonType.ICE, null, 0.7, 40, AbilityId.HUSTLE, AbilityId.NONE, AbilityId.INNER_FOCUS, 315, 70, 90, 45, 15, 45, 50, 120, 50, 63, GrowthRate.MEDIUM_SLOW, 50, false), - new PokemonSpecies(SpeciesId.GALAR_DARMANITAN, 8, false, false, false, "Blazing Pokémon", PokemonType.ICE, null, 1.7, 120, AbilityId.GORILLA_TACTICS, AbilityId.NONE, AbilityId.ZEN_MODE, 480, 105, 140, 55, 30, 55, 95, 60, 50, 168, GrowthRate.MEDIUM_SLOW, 50, false, true, - new PokemonForm("Standard Mode", "", PokemonType.ICE, null, 1.7, 120, AbilityId.GORILLA_TACTICS, AbilityId.NONE, AbilityId.ZEN_MODE, 480, 105, 140, 55, 30, 55, 95, 60, 50, 168, false, null, true), - new PokemonForm("Zen Mode", "zen", PokemonType.ICE, PokemonType.FIRE, 1.7, 120, AbilityId.GORILLA_TACTICS, AbilityId.NONE, AbilityId.ZEN_MODE, 540, 105, 160, 55, 30, 55, 135, 60, 50, 189), - ), - new PokemonSpecies(SpeciesId.GALAR_YAMASK, 8, false, false, false, "Spirit Pokémon", PokemonType.GROUND, PokemonType.GHOST, 0.5, 1.5, AbilityId.WANDERING_SPIRIT, AbilityId.NONE, AbilityId.NONE, 303, 38, 55, 85, 30, 65, 30, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.GALAR_STUNFISK, 8, false, false, false, "Trap Pokémon", PokemonType.GROUND, PokemonType.STEEL, 0.7, 20.5, AbilityId.MIMICRY, AbilityId.NONE, AbilityId.NONE, 471, 109, 81, 99, 66, 84, 32, 75, 70, 165, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.HISUI_GROWLITHE, 8, false, false, false, "Puppy Pokémon", PokemonType.FIRE, PokemonType.ROCK, 0.8, 22.7, AbilityId.INTIMIDATE, AbilityId.FLASH_FIRE, AbilityId.ROCK_HEAD, 350, 60, 75, 45, 65, 50, 55, 190, 50, 70, GrowthRate.SLOW, 75, false), - new PokemonSpecies(SpeciesId.HISUI_ARCANINE, 8, false, false, false, "Legendary Pokémon", PokemonType.FIRE, PokemonType.ROCK, 2, 168, AbilityId.INTIMIDATE, AbilityId.FLASH_FIRE, AbilityId.ROCK_HEAD, 555, 95, 115, 80, 95, 80, 90, 85, 50, 194, GrowthRate.SLOW, 75, false), - new PokemonSpecies(SpeciesId.HISUI_VOLTORB, 8, false, false, false, "Ball Pokémon", PokemonType.ELECTRIC, PokemonType.GRASS, 0.5, 13, AbilityId.SOUNDPROOF, AbilityId.STATIC, AbilityId.AFTERMATH, 330, 40, 30, 50, 55, 55, 100, 190, 80, 66, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.HISUI_ELECTRODE, 8, false, false, false, "Ball Pokémon", PokemonType.ELECTRIC, PokemonType.GRASS, 1.2, 81, AbilityId.SOUNDPROOF, AbilityId.STATIC, AbilityId.AFTERMATH, 490, 60, 50, 70, 80, 80, 150, 60, 70, 172, GrowthRate.MEDIUM_FAST, null, false), - new PokemonSpecies(SpeciesId.HISUI_TYPHLOSION, 8, false, false, false, "Volcano Pokémon", PokemonType.FIRE, PokemonType.GHOST, 1.6, 69.8, AbilityId.BLAZE, AbilityId.NONE, AbilityId.FRISK, 534, 73, 84, 78, 119, 85, 95, 45, 70, 240, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.HISUI_QWILFISH, 8, false, false, false, "Balloon Pokémon", PokemonType.DARK, PokemonType.POISON, 0.5, 3.9, AbilityId.POISON_POINT, AbilityId.SWIFT_SWIM, AbilityId.INTIMIDATE, 440, 65, 95, 85, 55, 55, 85, 45, 50, 88, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.HISUI_SNEASEL, 8, false, false, false, "Sharp Claw Pokémon", PokemonType.FIGHTING, PokemonType.POISON, 0.9, 27, AbilityId.INNER_FOCUS, AbilityId.KEEN_EYE, AbilityId.PICKPOCKET, 430, 55, 95, 55, 35, 75, 115, 60, 35, 86, GrowthRate.MEDIUM_SLOW, 50, true), - new PokemonSpecies(SpeciesId.HISUI_SAMUROTT, 8, false, false, false, "Formidable Pokémon", PokemonType.WATER, PokemonType.DARK, 1.5, 58.2, AbilityId.TORRENT, AbilityId.NONE, AbilityId.SHARPNESS, 528, 90, 108, 80, 100, 65, 85, 45, 80, 238, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.HISUI_LILLIGANT, 8, false, false, false, "Flowering Pokémon", PokemonType.GRASS, PokemonType.FIGHTING, 1.2, 19.2, AbilityId.CHLOROPHYLL, AbilityId.HUSTLE, AbilityId.LEAF_GUARD, 480, 70, 105, 75, 50, 75, 105, 75, 50, 168, GrowthRate.MEDIUM_FAST, 0, false), - new PokemonSpecies(SpeciesId.HISUI_ZORUA, 8, false, false, false, "Tricky Fox Pokémon", PokemonType.NORMAL, PokemonType.GHOST, 0.7, 12.5, AbilityId.ILLUSION, AbilityId.NONE, AbilityId.NONE, 330, 35, 60, 40, 85, 40, 70, 75, 50, 66, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.HISUI_ZOROARK, 8, false, false, false, "Illusion Fox Pokémon", PokemonType.NORMAL, PokemonType.GHOST, 1.6, 83, AbilityId.ILLUSION, AbilityId.NONE, AbilityId.NONE, 510, 55, 100, 60, 125, 60, 110, 45, 50, 179, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.HISUI_BRAVIARY, 8, false, false, false, "Valiant Pokémon", PokemonType.PSYCHIC, PokemonType.FLYING, 1.7, 43.4, AbilityId.KEEN_EYE, AbilityId.SHEER_FORCE, AbilityId.TINTED_LENS, 510, 110, 83, 70, 112, 70, 65, 60, 50, 179, GrowthRate.SLOW, 100, false), - new PokemonSpecies(SpeciesId.HISUI_SLIGGOO, 8, false, false, false, "Soft Tissue Pokémon", PokemonType.STEEL, PokemonType.DRAGON, 0.7, 68.5, AbilityId.SAP_SIPPER, AbilityId.SHELL_ARMOR, AbilityId.GOOEY, 452, 58, 75, 83, 83, 113, 40, 45, 35, 158, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.HISUI_GOODRA, 8, false, false, false, "Dragon Pokémon", PokemonType.STEEL, PokemonType.DRAGON, 1.7, 334.1, AbilityId.SAP_SIPPER, AbilityId.SHELL_ARMOR, AbilityId.GOOEY, 600, 80, 100, 100, 110, 150, 60, 45, 35, 270, GrowthRate.SLOW, 50, false), - new PokemonSpecies(SpeciesId.HISUI_AVALUGG, 8, false, false, false, "Iceberg Pokémon", PokemonType.ICE, PokemonType.ROCK, 1.4, 262.4, AbilityId.STRONG_JAW, AbilityId.ICE_BODY, AbilityId.STURDY, 514, 95, 127, 184, 34, 36, 38, 55, 50, 180, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.HISUI_DECIDUEYE, 8, false, false, false, "Arrow Quill Pokémon", PokemonType.GRASS, PokemonType.FIGHTING, 1.6, 37, AbilityId.OVERGROW, AbilityId.NONE, AbilityId.SCRAPPY, 530, 88, 112, 80, 95, 95, 60, 45, 50, 239, GrowthRate.MEDIUM_SLOW, 87.5, false), - new PokemonSpecies(SpeciesId.PALDEA_TAUROS, 9, false, false, false, "Wild Bull Pokémon", PokemonType.FIGHTING, null, 1.4, 115, AbilityId.INTIMIDATE, AbilityId.ANGER_POINT, AbilityId.CUD_CHEW, 490, 75, 110, 105, 30, 70, 100, 45, 50, 172, GrowthRate.SLOW, 100, false, false, - new PokemonForm("Combat Breed", "combat", PokemonType.FIGHTING, null, 1.4, 115, AbilityId.INTIMIDATE, AbilityId.ANGER_POINT, AbilityId.CUD_CHEW, 490, 75, 110, 105, 30, 70, 100, 45, 50, 172, false, "", true), - new PokemonForm("Blaze Breed", "blaze", PokemonType.FIGHTING, PokemonType.FIRE, 1.4, 85, AbilityId.INTIMIDATE, AbilityId.ANGER_POINT, AbilityId.CUD_CHEW, 490, 75, 110, 105, 30, 70, 100, 45, 50, 172, false, null, true), - new PokemonForm("Aqua Breed", "aqua", PokemonType.FIGHTING, PokemonType.WATER, 1.4, 110, AbilityId.INTIMIDATE, AbilityId.ANGER_POINT, AbilityId.CUD_CHEW, 490, 75, 110, 105, 30, 70, 100, 45, 50, 172, false, null, true), - ), - new PokemonSpecies(SpeciesId.PALDEA_WOOPER, 9, false, false, false, "Water Fish Pokémon", PokemonType.POISON, PokemonType.GROUND, 0.4, 11, AbilityId.POISON_POINT, AbilityId.WATER_ABSORB, AbilityId.UNAWARE, 210, 55, 45, 45, 25, 25, 15, 255, 50, 42, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(SpeciesId.BLOODMOON_URSALUNA, 9, true, false, false, "Peat Pokémon", PokemonType.GROUND, PokemonType.NORMAL, 2.7, 333, AbilityId.MINDS_EYE, AbilityId.NONE, AbilityId.NONE, 555, 113, 70, 120, 135, 65, 52, 75, 50, 278, GrowthRate.MEDIUM_FAST, 50, false), //Marked as Sub-Legend, for casing purposes - ); -} diff --git a/src/data/pokemon/pokemon-data.ts b/src/data/pokemon/pokemon-data.ts index 972d7627bcd..0eabb0d354a 100644 --- a/src/data/pokemon/pokemon-data.ts +++ b/src/data/pokemon/pokemon-data.ts @@ -3,7 +3,7 @@ import { loadBattlerTag, SerializableBattlerTag } from "#data/battler-tags"; import { allSpecies } from "#data/data-lists"; import type { Gender } from "#data/gender"; import { PokemonMove } from "#data/moves/pokemon-move"; -import { getPokemonSpeciesForm, type PokemonSpeciesForm } from "#data/pokemon-species"; +import type { PokemonSpeciesForm } from "#data/pokemon-species"; import type { TypeDamageMultiplier } from "#data/type"; import type { AbilityId } from "#enums/ability-id"; import type { BerryType } from "#enums/berry-type"; @@ -16,6 +16,7 @@ import type { IllusionData } from "#types/illusion-data"; import type { TurnMove } from "#types/turn-move"; import type { CoerceNullPropertiesToUndefined } from "#types/type-helpers"; import { isNullOrUndefined } from "#utils/common"; +import { getPokemonSpeciesForm } from "#utils/pokemon-utils"; /** * The type that {@linkcode PokemonSpeciesForm} is converted to when an object containing it serializes it. diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 7cb6f30c99e..fe78994ce93 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -60,7 +60,7 @@ import { } from "#data/pokemon-data"; import type { SpeciesFormChange } from "#data/pokemon-forms"; import type { PokemonSpeciesForm } from "#data/pokemon-species"; -import { getFusedSpeciesName, getPokemonSpeciesForm, PokemonSpecies } from "#data/pokemon-species"; +import { PokemonSpecies } from "#data/pokemon-species"; import { getRandomStatus, getStatusEffectOverlapText, Status } from "#data/status-effect"; import { getTerrainBlockMessage, TerrainType } from "#data/terrain"; import type { TypeDamageMultiplier } from "#data/type"; @@ -168,7 +168,7 @@ import { toDmgValue, } from "#utils/common"; import { getEnumValues } from "#utils/enums"; -import { getPokemonSpecies } from "#utils/pokemon-utils"; +import { getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; import { argbFromRgba, QuantizerCelebi, rgbaFromArgb } from "@material/material-color-utilities"; import i18next from "i18next"; import Phaser from "phaser"; diff --git a/src/init/init.ts b/src/init/init.ts index 17b991be3a0..ba9738e2be8 100644 --- a/src/init/init.ts +++ b/src/init/init.ts @@ -2,10 +2,10 @@ import { initAbilities } from "#abilities/ability"; import { initBiomes } from "#balance/biomes"; import { initEggMoves } from "#balance/egg-moves"; import { initPokemonPrevolutions, initPokemonStarters } from "#balance/pokemon-evolutions"; +import { initSpecies } from "#balance/pokemon-species"; import { initChallenges } from "#data/challenge"; import { initTrainerTypeDialogue } from "#data/dialogue"; import { initPokemonForms } from "#data/pokemon-forms"; -import { initSpecies } from "#data/pokemon-species"; import { initModifierPools } from "#modifiers/init-modifier-pools"; import { initModifierTypes } from "#modifiers/modifier-type"; import { initMoves } from "#moves/move"; diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 69c1539d944..0ddfedeff84 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -1,7 +1,6 @@ import { globalScene } from "#app/global-scene"; import type { Gender } from "#data/gender"; import { CustomPokemonData, PokemonBattleData, PokemonSummonData } from "#data/pokemon-data"; -import { getPokemonSpeciesForm } from "#data/pokemon-species"; import { Status } from "#data/status-effect"; import { BattleType } from "#enums/battle-type"; import type { BiomeId } from "#enums/biome-id"; @@ -14,7 +13,7 @@ import { TrainerSlot } from "#enums/trainer-slot"; import { EnemyPokemon, Pokemon } from "#field/pokemon"; import { PokemonMove } from "#moves/pokemon-move"; import type { Variant } from "#sprites/variant"; -import { getPokemonSpecies } from "#utils/pokemon-utils"; +import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; export class PokemonData { public id: number; diff --git a/src/system/version-migration/versions/v1_7_0.ts b/src/system/version-migration/versions/v1_7_0.ts index 9ba25bcbaac..69c640756ea 100644 --- a/src/system/version-migration/versions/v1_7_0.ts +++ b/src/system/version-migration/versions/v1_7_0.ts @@ -1,11 +1,10 @@ import { globalScene } from "#app/global-scene"; -import { getPokemonSpeciesForm } from "#data/pokemon-species"; import { DexAttr } from "#enums/dex-attr"; import type { SessionSaveData, SystemSaveData } from "#system/game-data"; import type { SessionSaveMigrator } from "#types/session-save-migrator"; import type { SystemSaveMigrator } from "#types/system-save-migrator"; import { isNullOrUndefined } from "#utils/common"; -import { getPokemonSpecies } from "#utils/pokemon-utils"; +import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; /** * If a starter is caught, but the only forms registered as caught are not starterSelectable, diff --git a/src/ui/pokedex-page-ui-handler.ts b/src/ui/pokedex-page-ui-handler.ts index 49ce5b64d9f..227b86c4d4d 100644 --- a/src/ui/pokedex-page-ui-handler.ts +++ b/src/ui/pokedex-page-ui-handler.ts @@ -25,7 +25,7 @@ import { getNatureName } from "#data/nature"; import type { SpeciesFormChange } from "#data/pokemon-forms"; import { pokemonFormChanges } from "#data/pokemon-forms"; import type { PokemonSpecies } from "#data/pokemon-species"; -import { getPokemonSpeciesForm, normalForm } from "#data/pokemon-species"; +import { normalForm } from "#data/pokemon-species"; import { AbilityAttr } from "#enums/ability-attr"; import type { AbilityId } from "#enums/ability-id"; import { BiomeId } from "#enums/biome-id"; @@ -56,7 +56,7 @@ import { addBBCodeTextObject, addTextObject, getTextColor, getTextStyleOptions } import { addWindow } from "#ui/ui-theme"; import { BooleanHolder, getLocalizedSpriteKey, isNullOrUndefined, padInt, rgbHexToRgba } from "#utils/common"; import { getEnumValues } from "#utils/enums"; -import { getPokemonSpecies } from "#utils/pokemon-utils"; +import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; import { toTitleCase } from "#utils/strings"; import { argbFromRgba } from "@material/material-color-utilities"; import i18next from "i18next"; diff --git a/src/ui/pokedex-ui-handler.ts b/src/ui/pokedex-ui-handler.ts index 5d49e867b59..cd1dc312f4d 100644 --- a/src/ui/pokedex-ui-handler.ts +++ b/src/ui/pokedex-ui-handler.ts @@ -15,7 +15,7 @@ import { import { speciesTmMoves } from "#balance/tms"; import { allAbilities, allMoves, allSpecies } from "#data/data-lists"; import type { PokemonForm, PokemonSpecies } from "#data/pokemon-species"; -import { getPokemonSpeciesForm, getPokerusStarters, normalForm } from "#data/pokemon-species"; +import { normalForm } from "#data/pokemon-species"; import { AbilityAttr } from "#enums/ability-attr"; import { AbilityId } from "#enums/ability-id"; import { BiomeId } from "#enums/biome-id"; @@ -46,6 +46,7 @@ import { addWindow } from "#ui/ui-theme"; import { BooleanHolder, fixedInt, getLocalizedSpriteKey, padInt, randIntRange, rgbHexToRgba } from "#utils/common"; import type { StarterPreferences } from "#utils/data"; import { loadStarterPreferences } from "#utils/data"; +import { getPokemonSpeciesForm, getPokerusStarters } from "#utils/pokemon-utils"; import { argbFromRgba } from "@material/material-color-utilities"; import i18next from "i18next"; diff --git a/src/ui/pokemon-hatch-info-container.ts b/src/ui/pokemon-hatch-info-container.ts index 9c223adf837..bb1cc22e9fd 100644 --- a/src/ui/pokemon-hatch-info-container.ts +++ b/src/ui/pokemon-hatch-info-container.ts @@ -5,7 +5,6 @@ import { allMoves } from "#data/data-lists"; import { getEggTierForSpecies } from "#data/egg"; import type { EggHatchData } from "#data/egg-hatch-data"; import { Gender } from "#data/gender"; -import { getPokemonSpeciesForm } from "#data/pokemon-species"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { TextStyle } from "#enums/text-style"; @@ -13,6 +12,7 @@ import type { PlayerPokemon } from "#field/pokemon"; import { PokemonInfoContainer } from "#ui/pokemon-info-container"; import { addTextObject } from "#ui/text"; import { padInt, rgbHexToRgba } from "#utils/common"; +import { getPokemonSpeciesForm } from "#utils/pokemon-utils"; import { argbFromRgba } from "@material/material-color-utilities"; /** diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 6929d6f818d..dac6bc677a2 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -24,7 +24,6 @@ import { Gender, getGenderColor, getGenderSymbol } from "#data/gender"; import { getNatureName } from "#data/nature"; import { pokemonFormChanges } from "#data/pokemon-forms"; import type { PokemonSpecies } from "#data/pokemon-species"; -import { getPokemonSpeciesForm, getPokerusStarters } from "#data/pokemon-species"; import { AbilityAttr } from "#enums/ability-attr"; import { AbilityId } from "#enums/ability-id"; import { Button } from "#enums/buttons"; @@ -72,6 +71,7 @@ import { } from "#utils/common"; import type { StarterPreferences } from "#utils/data"; import { loadStarterPreferences, saveStarterPreferences } from "#utils/data"; +import { getPokemonSpeciesForm, getPokerusStarters } from "#utils/pokemon-utils"; import { toTitleCase } from "#utils/strings"; import { argbFromRgba } from "@material/material-color-utilities"; import i18next from "i18next"; diff --git a/src/utils/pokemon-utils.ts b/src/utils/pokemon-utils.ts index da39cfe11ad..8de0a3bfcf1 100644 --- a/src/utils/pokemon-utils.ts +++ b/src/utils/pokemon-utils.ts @@ -1,6 +1,9 @@ +import { globalScene } from "#app/global-scene"; +import { POKERUS_STARTER_COUNT, speciesStarterCosts } from "#balance/starters"; import { allSpecies } from "#data/data-lists"; -import type { PokemonSpecies } from "#data/pokemon-species"; +import type { PokemonSpecies, PokemonSpeciesForm } from "#data/pokemon-species"; import type { SpeciesId } from "#enums/species-id"; +import { randSeedItem } from "./common"; /** * Gets the {@linkcode PokemonSpecies} object associated with the {@linkcode SpeciesId} enum given @@ -19,3 +22,104 @@ export function getPokemonSpecies(species: SpeciesId | SpeciesId[]): PokemonSpec } return allSpecies[species - 1]; } + +/** + * Method to get the daily list of starters with Pokerus. + * @returns A list of starters with Pokerus + */ +export function getPokerusStarters(): PokemonSpecies[] { + const pokerusStarters: PokemonSpecies[] = []; + const date = new Date(); + date.setUTCHours(0, 0, 0, 0); + globalScene.executeWithSeedOffset( + () => { + while (pokerusStarters.length < POKERUS_STARTER_COUNT) { + const randomSpeciesId = Number.parseInt(randSeedItem(Object.keys(speciesStarterCosts)), 10); + const species = getPokemonSpecies(randomSpeciesId); + if (!pokerusStarters.includes(species)) { + pokerusStarters.push(species); + } + } + }, + 0, + date.getTime().toString(), + ); + return pokerusStarters; +} + +export function getFusedSpeciesName(speciesAName: string, speciesBName: string): string { + const fragAPattern = /([a-z]{2}.*?[aeiou(?:y$)\-']+)(.*?)$/i; + const fragBPattern = /([a-z]{2}.*?[aeiou(?:y$)\-'])(.*?)$/i; + + const [speciesAPrefixMatch, speciesBPrefixMatch] = [speciesAName, speciesBName].map(n => /^(?:[^ ]+) /.exec(n)); + const [speciesAPrefix, speciesBPrefix] = [speciesAPrefixMatch, speciesBPrefixMatch].map(m => (m ? m[0] : "")); + + if (speciesAPrefix) { + speciesAName = speciesAName.slice(speciesAPrefix.length); + } + if (speciesBPrefix) { + speciesBName = speciesBName.slice(speciesBPrefix.length); + } + + const [speciesASuffixMatch, speciesBSuffixMatch] = [speciesAName, speciesBName].map(n => / (?:[^ ]+)$/.exec(n)); + const [speciesASuffix, speciesBSuffix] = [speciesASuffixMatch, speciesBSuffixMatch].map(m => (m ? m[0] : "")); + + if (speciesASuffix) { + speciesAName = speciesAName.slice(0, -speciesASuffix.length); + } + if (speciesBSuffix) { + speciesBName = speciesBName.slice(0, -speciesBSuffix.length); + } + + const splitNameA = speciesAName.split(/ /g); + const splitNameB = speciesBName.split(/ /g); + + const fragAMatch = fragAPattern.exec(speciesAName); + const fragBMatch = fragBPattern.exec(speciesBName); + + let fragA: string; + let fragB: string; + + fragA = splitNameA.length === 1 ? (fragAMatch ? fragAMatch[1] : speciesAName) : splitNameA[splitNameA.length - 1]; + + if (splitNameB.length === 1) { + if (fragBMatch) { + const lastCharA = fragA.slice(fragA.length - 1); + const prevCharB = fragBMatch[1].slice(fragBMatch.length - 1); + fragB = (/[-']/.test(prevCharB) ? prevCharB : "") + fragBMatch[2] || prevCharB; + if (lastCharA === fragB[0]) { + if (/[aiu]/.test(lastCharA)) { + fragB = fragB.slice(1); + } else { + const newCharMatch = new RegExp(`[^${lastCharA}]`).exec(fragB); + if (newCharMatch?.index !== undefined && newCharMatch.index > 0) { + fragB = fragB.slice(newCharMatch.index); + } + } + } + } else { + fragB = speciesBName; + } + } else { + fragB = splitNameB[splitNameB.length - 1]; + } + + if (splitNameA.length > 1) { + fragA = `${splitNameA.slice(0, splitNameA.length - 1).join(" ")} ${fragA}`; + } + + fragB = `${fragB.slice(0, 1).toLowerCase()}${fragB.slice(1)}`; + + return `${speciesAPrefix || speciesBPrefix}${fragA}${fragB}${speciesBSuffix || speciesASuffix}`; +} + +export function getPokemonSpeciesForm(species: SpeciesId, formIndex: number): PokemonSpeciesForm { + const retSpecies: PokemonSpecies = + species >= 2000 + ? allSpecies.find(s => s.speciesId === species)! // TODO: is the bang correct? + : allSpecies[species - 1]; + if (formIndex < retSpecies.forms?.length) { + return retSpecies.forms[formIndex]; + } + return retSpecies; +} diff --git a/test/test-utils/game-manager-utils.ts b/test/test-utils/game-manager-utils.ts index 7bb8ea57469..89e352cdbdc 100644 --- a/test/test-utils/game-manager-utils.ts +++ b/test/test-utils/game-manager-utils.ts @@ -3,7 +3,6 @@ import type { BattleScene } from "#app/battle-scene"; import { getGameMode } from "#app/game-mode"; import { getDailyRunStarters } from "#data/daily-run"; import { Gender } from "#data/gender"; -import { getPokemonSpeciesForm } from "#data/pokemon-species"; import { BattleType } from "#enums/battle-type"; import { GameModes } from "#enums/game-modes"; import type { MoveId } from "#enums/move-id"; @@ -11,7 +10,7 @@ import type { SpeciesId } from "#enums/species-id"; import { PlayerPokemon } from "#field/pokemon"; import type { StarterMoveset } from "#system/game-data"; import type { Starter } from "#ui/starter-select-ui-handler"; -import { getPokemonSpecies } from "#utils/pokemon-utils"; +import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; /** Function to convert Blob to string */ export function blobToString(blob) { From 0bc78cb715df828994710fcd859d70bb518b214b Mon Sep 17 00:00:00 2001 From: "Amani H." <109637146+xsn34kzx@users.noreply.github.com> Date: Sat, 2 Aug 2025 23:05:54 -0400 Subject: [PATCH 75/76] [Balance] Prevent MEs on X1 Waves (#6204) * [Balance] Prevent MEs on X1 Waves * Fix Bug-Type Superfan Encounter Test * Fix Unit Tests --- src/battle-scene.ts | 1 + .../teleporting-hijinks-encounter.ts | 2 +- .../berries-abound-encounter.test.ts | 2 +- .../bug-type-superfan-encounter.test.ts | 12 +++++------ .../teleporting-hijinks-encounter.test.ts | 20 +++++++++---------- .../mystery-encounter.test.ts | 12 +++++++++-- test/phases/mystery-encounter-phase.test.ts | 2 +- 7 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index e5a63285ecc..8c8906be2b0 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -3528,6 +3528,7 @@ export class BattleScene extends SceneBase { this.gameMode.hasMysteryEncounters && battleType === BattleType.WILD && !this.gameMode.isBoss(waveIndex) && + waveIndex % 10 !== 1 && waveIndex < highestMysteryEncounterWave && waveIndex > lowestMysteryEncounterWave ); diff --git a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts index b547064fd66..d77326837cd 100644 --- a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts +++ b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts @@ -59,7 +59,7 @@ export const TeleportingHijinksEncounter: MysteryEncounter = MysteryEncounterBui ) .withEncounterTier(MysteryEncounterTier.COMMON) .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) - .withSceneRequirement(new WaveModulusRequirement([1, 2, 3], 10)) // Must be in first 3 waves after boss wave + .withSceneRequirement(new WaveModulusRequirement([2, 3, 4], 10)) // Must be in first 3 waves after boss wave .withSceneRequirement(new MoneyRequirement(0, MONEY_COST_MULTIPLIER)) // Must be able to pay teleport cost .withAutoHideIntroVisuals(false) .withCatchAllowed(true) diff --git a/test/mystery-encounter/encounters/berries-abound-encounter.test.ts b/test/mystery-encounter/encounters/berries-abound-encounter.test.ts index 3d29c04cab7..25116a89ec5 100644 --- a/test/mystery-encounter/encounters/berries-abound-encounter.test.ts +++ b/test/mystery-encounter/encounters/berries-abound-encounter.test.ts @@ -174,7 +174,7 @@ describe("Berries Abound - Mystery Encounter", () => { }); it("should start battle if fastest pokemon is slower than boss below wave 50", async () => { - game.override.startingWave(41); + game.override.startingWave(42); const encounterTextSpy = vi.spyOn(EncounterDialogueUtils, "showEncounterText"); await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty); diff --git a/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts b/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts index 205bf996815..bed9d48d063 100644 --- a/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts +++ b/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts @@ -253,7 +253,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { }); it("should start battle against the Bug-Type Superfan with wave 70 party template", async () => { - game.override.startingWave(61); + game.override.startingWave(63); await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); await runMysteryEncounterToEnd(game, 1, undefined, true); @@ -268,7 +268,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { }); it("should start battle against the Bug-Type Superfan with wave 100 party template", async () => { - game.override.startingWave(81); + game.override.startingWave(83); await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); await runMysteryEncounterToEnd(game, 1, undefined, true); @@ -284,7 +284,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { }); it("should start battle against the Bug-Type Superfan with wave 120 party template", async () => { - game.override.startingWave(111); + game.override.startingWave(113); await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); await runMysteryEncounterToEnd(game, 1, undefined, true); @@ -302,7 +302,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { }); it("should start battle against the Bug-Type Superfan with wave 140 party template", async () => { - game.override.startingWave(131); + game.override.startingWave(133); await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); await runMysteryEncounterToEnd(game, 1, undefined, true); @@ -320,7 +320,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { }); it("should start battle against the Bug-Type Superfan with wave 160 party template", async () => { - game.override.startingWave(151); + game.override.startingWave(153); await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); await runMysteryEncounterToEnd(game, 1, undefined, true); @@ -338,7 +338,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { }); it("should start battle against the Bug-Type Superfan with wave 180 party template", async () => { - game.override.startingWave(171); + game.override.startingWave(173); await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); await runMysteryEncounterToEnd(game, 1, undefined, true); diff --git a/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts b/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts index 43d497c57bb..ff4f73cfbde 100644 --- a/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts +++ b/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts @@ -79,14 +79,6 @@ describe("Teleporting Hijinks - Mystery Encounter", () => { expect(TeleportingHijinksEncounter.options.length).toBe(3); }); - it("should run in waves that are X1", async () => { - game.override.startingWave(11).mysteryEncounterTier(MysteryEncounterTier.COMMON); - - await game.runToMysteryEncounter(); - - expect(scene.currentBattle?.mysteryEncounter?.encounterType).toBe(MysteryEncounterType.TELEPORTING_HIJINKS); - }); - it("should run in waves that are X2", async () => { game.override.startingWave(32).mysteryEncounterTier(MysteryEncounterTier.COMMON); @@ -103,8 +95,16 @@ describe("Teleporting Hijinks - Mystery Encounter", () => { expect(scene.currentBattle?.mysteryEncounter?.encounterType).toBe(MysteryEncounterType.TELEPORTING_HIJINKS); }); - it("should NOT run in waves that are not X1, X2, or X3", async () => { - game.override.startingWave(54); + it("should run in waves that are X4", async () => { + game.override.startingWave(54).mysteryEncounterTier(MysteryEncounterTier.COMMON); + + await game.runToMysteryEncounter(); + + expect(scene.currentBattle?.mysteryEncounter?.encounterType).toBe(MysteryEncounterType.TELEPORTING_HIJINKS); + }); + + it("should NOT run in waves that are not X2, X3, or X4", async () => { + game.override.startingWave(67); await game.runToMysteryEncounter(); diff --git a/test/mystery-encounter/mystery-encounter.test.ts b/test/mystery-encounter/mystery-encounter.test.ts index 71bc9aec008..ec27f7c6a48 100644 --- a/test/mystery-encounter/mystery-encounter.test.ts +++ b/test/mystery-encounter/mystery-encounter.test.ts @@ -24,7 +24,7 @@ describe("Mystery Encounters", () => { beforeEach(() => { game = new GameManager(phaserGame); scene = game.scene; - game.override.startingWave(11).mysteryEncounterChance(100); + game.override.startingWave(12).mysteryEncounterChance(100); }); it("Spawns a mystery encounter", async () => { @@ -37,12 +37,20 @@ describe("Mystery Encounters", () => { expect(game.scene.phaseManager.getCurrentPhase()!.constructor.name).toBe(MysteryEncounterPhase.name); }); + it("Encounters should not run on X1 waves", async () => { + game.override.startingWave(11); + + await game.runToMysteryEncounter(); + + expect(scene.currentBattle.mysteryEncounter).toBeUndefined(); + }); + it("Encounters should not run below wave 10", async () => { game.override.startingWave(9); await game.runToMysteryEncounter(); - expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.MYSTERIOUS_CHALLENGERS); + expect(scene.currentBattle.mysteryEncounter).toBeUndefined(); }); it("Encounters should not run above wave 180", async () => { diff --git a/test/phases/mystery-encounter-phase.test.ts b/test/phases/mystery-encounter-phase.test.ts index ad71a4151ac..2b6105c7034 100644 --- a/test/phases/mystery-encounter-phase.test.ts +++ b/test/phases/mystery-encounter-phase.test.ts @@ -27,7 +27,7 @@ describe("Mystery Encounter Phases", () => { beforeEach(() => { game = new GameManager(phaserGame); - game.override.startingWave(11).mysteryEncounterChance(100).seed("test"); // Seed guarantees wild encounter to be replaced by ME + game.override.startingWave(12).mysteryEncounterChance(100).seed("test"); // Seed guarantees wild encounter to be replaced by ME }); describe("MysteryEncounterPhase", () => { From 8a2b8889717d68642b2c8c5357551624cac662ae Mon Sep 17 00:00:00 2001 From: Blitzy <118096277+Blitz425@users.noreply.github.com> Date: Sun, 3 Aug 2025 15:53:10 -0500 Subject: [PATCH 76/76] [Balance] Update and Change Breeder Trainer Class Teams (#6200) * Update Breeder Trainer Class * Update trainer-config.ts * Update trainer-config.ts * Update whirlwind.test.ts * Update src/data/trainers/trainer-config.ts Co-authored-by: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> * Adjust Party Templates and move Wynaut * Update trainer-party-template.ts --------- Co-authored-by: damocleas Co-authored-by: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> --- src/data/trainers/trainer-config.ts | 54 +++++++++++++++++++-- src/data/trainers/trainer-party-template.ts | 1 + test/moves/whirlwind.test.ts | 2 +- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/data/trainers/trainer-config.ts b/src/data/trainers/trainer-config.ts index 6b3fcf70f80..5739492f96e 100644 --- a/src/data/trainers/trainer-config.ts +++ b/src/data/trainers/trainer-config.ts @@ -1244,12 +1244,58 @@ export const trainerConfigs: TrainerConfigs = { .setHasDouble("Breeders") .setPartyTemplateFunc(() => getWavePartyTemplate( - trainerPartyTemplates.FOUR_WEAKER, - trainerPartyTemplates.FIVE_WEAKER, - trainerPartyTemplates.SIX_WEAKER, + trainerPartyTemplates.FOUR_WEAK, + trainerPartyTemplates.FIVE_WEAK, + trainerPartyTemplates.SIX_WEAK, ), ) - .setSpeciesFilter(s => s.baseTotal < 450), + .setSpeciesPools({ + [TrainerPoolTier.COMMON]: [ + SpeciesId.PICHU, + SpeciesId.CLEFFA, + SpeciesId.IGGLYBUFF, + SpeciesId.TOGEPI, + SpeciesId.TYROGUE, + SpeciesId.SMOOCHUM, + SpeciesId.AZURILL, + SpeciesId.BUDEW, + SpeciesId.CHINGLING, + SpeciesId.BONSLY, + SpeciesId.MIME_JR, + SpeciesId.HAPPINY, + SpeciesId.MANTYKE, + SpeciesId.TOXEL, + ], + [TrainerPoolTier.UNCOMMON]: [ + SpeciesId.DITTO, + SpeciesId.ELEKID, + SpeciesId.MAGBY, + SpeciesId.WYNAUT, + SpeciesId.MUNCHLAX, + SpeciesId.RIOLU, + SpeciesId.AUDINO, + ], + [TrainerPoolTier.RARE]: [ + SpeciesId.ALOLA_RATTATA, + SpeciesId.ALOLA_SANDSHREW, + SpeciesId.ALOLA_VULPIX, + SpeciesId.ALOLA_DIGLETT, + SpeciesId.ALOLA_MEOWTH, + SpeciesId.GALAR_PONYTA, + ], + [TrainerPoolTier.SUPER_RARE]: [ + SpeciesId.ALOLA_GEODUDE, + SpeciesId.ALOLA_GRIMER, + SpeciesId.GALAR_MEOWTH, + SpeciesId.GALAR_SLOWPOKE, + SpeciesId.GALAR_FARFETCHD, + SpeciesId.HISUI_GROWLITHE, + SpeciesId.HISUI_VOLTORB, + SpeciesId.HISUI_QWILFISH, + SpeciesId.HISUI_SNEASEL, + SpeciesId.HISUI_ZORUA, + ], + }), [TrainerType.CLERK]: new TrainerConfig(++t) .setHasGenders("Clerk Female") .setHasDouble("Colleagues") diff --git a/src/data/trainers/trainer-party-template.ts b/src/data/trainers/trainer-party-template.ts index d4e7fe7a261..0ad3d36dcfa 100644 --- a/src/data/trainers/trainer-party-template.ts +++ b/src/data/trainers/trainer-party-template.ts @@ -144,6 +144,7 @@ export const trainerPartyTemplates = { FIVE_WEAK_BALANCED: new TrainerPartyTemplate(5, PartyMemberStrength.WEAK, false, true), SIX_WEAKER: new TrainerPartyTemplate(6, PartyMemberStrength.WEAKER), SIX_WEAKER_SAME: new TrainerPartyTemplate(6, PartyMemberStrength.WEAKER, true), + SIX_WEAK: new TrainerPartyTemplate(6, PartyMemberStrength.WEAK), SIX_WEAK_SAME: new TrainerPartyTemplate(6, PartyMemberStrength.WEAK, true), SIX_WEAK_BALANCED: new TrainerPartyTemplate(6, PartyMemberStrength.WEAK, false, true), diff --git a/test/moves/whirlwind.test.ts b/test/moves/whirlwind.test.ts index 90bbf722224..2aadb76b019 100644 --- a/test/moves/whirlwind.test.ts +++ b/test/moves/whirlwind.test.ts @@ -206,7 +206,7 @@ describe("Moves - Whirlwind", () => { await game.classicMode.startBattle([SpeciesId.MAGIKARP, SpeciesId.TOTODILE]); // expect the enemy to have at least 4 pokemon, necessary for this check to even work - expect(game.scene.getEnemyParty().length, "enemy must have exactly 4 pokemon").toBe(4); + expect(game.scene.getEnemyParty().length, "enemy must have exactly 4 pokemon").toBeGreaterThanOrEqual(4); const user = game.scene.getPlayerPokemon()!;