From ef843debee64a1a753d4f5eddfe7487630f893b8 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Wed, 23 Jul 2025 21:06:17 -0600 Subject: [PATCH 01/79] [UI/UX] Allow adjustable column count in stats-ui-handler https://github.com/pagefaultgames/pokerogue/pull/6087 * Make column count modular Co-authored by: ShinigamiHolo <128856544+ShinigamiHolo@users.noreply.github.com> * Make game stats ui handler use phaser method chaining * Adjust max cursor calculation * Make arrowUp start invisible * Add implementations for setFlip methods in MockSprite * Misc cleanup * Address kev's review comments * Address kev's review comments Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * improve clarity of doc comment 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/game-stats-ui-handler.ts | 308 +++++++++++------- .../mocks/mocksContainer/mockSprite.ts | 11 + 2 files changed, 199 insertions(+), 120 deletions(-) diff --git a/src/ui/game-stats-ui-handler.ts b/src/ui/game-stats-ui-handler.ts index f9087ba7dfa..a9de827e258 100644 --- a/src/ui/game-stats-ui-handler.ts +++ b/src/ui/game-stats-ui-handler.ts @@ -2,7 +2,6 @@ import { globalScene } from "#app/global-scene"; import { speciesStarterCosts } from "#balance/starters"; import { Button } from "#enums/buttons"; import { DexAttr } from "#enums/dex-attr"; -import type { UiMode } from "#enums/ui-mode"; import { UiTheme } from "#enums/ui-theme"; import type { GameData } from "#system/game-data"; import { addTextObject, TextStyle } from "#ui/text"; @@ -217,152 +216,207 @@ export class GameStatsUiHandler extends UiHandler { private gameStatsContainer: Phaser.GameObjects.Container; private statsContainer: Phaser.GameObjects.Container; - private statLabels: Phaser.GameObjects.Text[]; - private statValues: Phaser.GameObjects.Text[]; + /** The number of rows enabled per page. */ + private static readonly ROWS_PER_PAGE = 9; + + private statLabels: Phaser.GameObjects.Text[] = []; + private statValues: Phaser.GameObjects.Text[] = []; private arrowUp: Phaser.GameObjects.Sprite; private arrowDown: Phaser.GameObjects.Sprite; - constructor(mode: UiMode | null = null) { - super(mode); - - this.statLabels = []; - this.statValues = []; + /** Whether the UI is single column mode */ + private get singleCol(): boolean { + const resolvedLang = i18next.resolvedLanguage ?? "en"; + // NOTE TO TRANSLATION TEAM: Add more languages that want to display + // in a single-column inside of the `[]` (e.g. `["ru", "fr"]`) + return ["ru"].includes(resolvedLang); } + /** The number of columns used by this menu in the resolved language */ + private get columnCount(): 1 | 2 { + return this.singleCol ? 1 : 2; + } + + // #region Columnar-specific properties + + /** The with of each column in the stats view */ + private get colWidth(): number { + return (globalScene.scaledCanvas.width - 2) / this.columnCount; + } + + /** THe width of a column's background window */ + private get colBgWidth(): number { + return this.colWidth - 2; + } + + /** + * Calculate the `x` position of the stat label based on its index. + * + * @remarks + * Should be used for stat labels (e.g. stat name, not its value). For stat value, use {@linkcode calcTextX}. + * @param index - The index of the stat label + * @returns The `x` position for the stat label + */ + private calcLabelX(index: number): number { + if (this.singleCol || !(index & 1)) { + return 8; + } + return 8 + (index & 1 ? this.colBgWidth : 0); + } + + /** + * Calculate the `y` position of the stat label/text based on its index. + * @param index - The index of the stat label + * @returns The `y` position for the stat label + */ + private calcEntryY(index: number): number { + if (!this.singleCol) { + // Floor division by 2 as we want 1 to go to 0 + index >>= 1; + } + return 28 + index * 16; + } + + /** + * Calculate the `x` position of the stat value based on its index. + * @param index - The index of the stat value + * @returns The calculated `x` position + */ + private calcTextX(index: number): number { + if (this.singleCol || !(index & 1)) { + return this.colBgWidth - 8; + } + return this.colBgWidth * 2 - 8; + } + + /** The number of stats on screen at one time (varies with column count) */ + private get statsPerPage(): number { + return GameStatsUiHandler.ROWS_PER_PAGE * this.columnCount; + } + + // #endregion Columnar-specific properties setup() { const ui = this.getUi(); - this.gameStatsContainer = globalScene.add.container(1, -(globalScene.game.canvas.height / 6) + 1); + /** The scaled width of the global canvas */ + const sWidth = globalScene.scaledCanvas.width; + /** The scaled height of the global canvas */ + const sHeight = globalScene.scaledCanvas.height; + + const gameStatsContainer = globalScene.add.container(1, -sHeight + 1); + this.gameStatsContainer = gameStatsContainer; this.gameStatsContainer.setInteractive( - new Phaser.Geom.Rectangle(0, 0, globalScene.game.canvas.width / 6, globalScene.game.canvas.height / 6), + new Phaser.Geom.Rectangle(0, 0, sWidth, sHeight), Phaser.Geom.Rectangle.Contains, ); - const headerBg = addWindow(0, 0, globalScene.game.canvas.width / 6 - 2, 24); - headerBg.setOrigin(0, 0); + const headerBg = addWindow(0, 0, sWidth - 2, 24).setOrigin(0); - const headerText = addTextObject(0, 0, i18next.t("gameStatsUiHandler:stats"), TextStyle.HEADER_LABEL); - headerText.setOrigin(0, 0); - headerText.setPositionRelative(headerBg, 8, 4); + const headerText = addTextObject(0, 0, i18next.t("gameStatsUiHandler:stats"), TextStyle.HEADER_LABEL) + .setOrigin(0) + .setPositionRelative(headerBg, 8, 4); - const statsBgWidth = (globalScene.game.canvas.width / 6 - 2) / 2; - const [statsBgLeft, statsBgRight] = new Array(2).fill(null).map((_, i) => { - const width = statsBgWidth + 2; - const height = Math.floor(globalScene.game.canvas.height / 6 - headerBg.height - 2); - const statsBg = addWindow( - (statsBgWidth - 2) * i, - headerBg.height, - width, - height, - false, - false, - i > 0 ? -3 : 0, - 1, - ); - statsBg.setOrigin(0, 0); - return statsBg; - }); + this.gameStatsContainer.add([headerBg, headerText]); - this.statsContainer = globalScene.add.container(0, 0); + const colWidth = this.colWidth; - for (let i = 0; i < 18; i++) { - const statLabel = addTextObject( - 8 + (i % 2 === 1 ? statsBgWidth : 0), - 28 + Math.floor(i / 2) * 16, - "", - TextStyle.STATS_LABEL, - ); - statLabel.setOrigin(0, 0); - this.statsContainer.add(statLabel); - this.statLabels.push(statLabel); - - const statValue = addTextObject(statsBgWidth * ((i % 2) + 1) - 8, statLabel.y, "", TextStyle.STATS_VALUE); - statValue.setOrigin(1, 0); - this.statsContainer.add(statValue); - this.statValues.push(statValue); + { + const columnCount = this.columnCount; + const headerHeight = headerBg.height; + const statsBgHeight = Math.floor(globalScene.scaledCanvas.height - headerBg.height - 2); + const maskOffsetX = columnCount === 1 ? 0 : -3; + for (let i = 0; i < columnCount; i++) { + gameStatsContainer.add( + addWindow(i * this.colBgWidth, headerHeight, colWidth, statsBgHeight, false, false, maskOffsetX, 1, undefined) // formatting + .setOrigin(0), + ); + } } - this.gameStatsContainer.add(headerBg); - this.gameStatsContainer.add(headerText); - this.gameStatsContainer.add(statsBgLeft); - this.gameStatsContainer.add(statsBgRight); + const length = this.statsPerPage; + this.statLabels = Array.from({ length }, (_, i) => + addTextObject(this.calcLabelX(i), this.calcEntryY(i), "", TextStyle.STATS_LABEL).setOrigin(0), + ); + + this.statValues = Array.from({ length }, (_, i) => + addTextObject(this.calcTextX(i), this.calcEntryY(i), "", TextStyle.STATS_VALUE).setOrigin(1, 0), + ); + this.statsContainer = globalScene.add.container(0, 0, [...this.statLabels, ...this.statValues]); + this.gameStatsContainer.add(this.statsContainer); // arrows to show that we can scroll through the stats const isLegacyTheme = globalScene.uiTheme === UiTheme.LEGACY; - this.arrowDown = globalScene.add.sprite( - statsBgWidth, - globalScene.game.canvas.height / 6 - (isLegacyTheme ? 9 : 5), - "prompt", - ); - this.gameStatsContainer.add(this.arrowDown); - this.arrowUp = globalScene.add.sprite(statsBgWidth, headerBg.height + (isLegacyTheme ? 7 : 3), "prompt"); - this.arrowUp.flipY = true; - this.gameStatsContainer.add(this.arrowUp); + const arrowX = this.singleCol ? colWidth / 2 : colWidth; + this.arrowDown = globalScene.add.sprite(arrowX, sHeight - (isLegacyTheme ? 9 : 5), "prompt"); + + this.arrowUp = globalScene.add + .sprite(arrowX, headerBg.height + (isLegacyTheme ? 7 : 3), "prompt") // + .setFlipY(true); + + this.gameStatsContainer.add([this.arrowDown, this.arrowUp]); ui.add(this.gameStatsContainer); this.setCursor(0); - this.gameStatsContainer.setVisible(false); } show(args: any[]): boolean { super.show(args); + this.gameStatsContainer.setActive(true).setVisible(true); - this.setCursor(0); - - this.updateStats(); - - this.arrowUp.play("prompt"); - this.arrowDown.play("prompt"); + this.arrowUp.setActive(true).play("prompt").setVisible(false); + this.arrowDown.setActive(true).play("prompt"); + /* `setCursor` handles updating stats if the position is different from before. + When opening this UI, we want to update stats regardless of the prior position. */ + if (!this.setCursor(0)) { + this.updateStats(); + } if (globalScene.uiTheme === UiTheme.LEGACY) { this.arrowUp.setTint(0x484848); this.arrowDown.setTint(0x484848); } - this.updateArrows(); - - this.gameStatsContainer.setVisible(true); - - this.getUi().moveTo(this.gameStatsContainer, this.getUi().length - 1); - - this.getUi().hideTooltip(); + this.getUi() + .moveTo(this.gameStatsContainer, this.getUi().length - 1) + .hideTooltip(); return true; } - updateStats(): void { - const statKeys = Object.keys(displayStats).slice(this.cursor * 2, this.cursor * 2 + 18); + /** + * Update the stat labels and values to reflect the current cursor position. + * + * @remarks + * + * Invokes each stat's {@linkcode DisplayStat.sourceFunc | sourceFunc} to obtain its value. + * Stat labels are shown as `???` if the stat is marked as hidden and its value is zero. + */ + private updateStats(): void { + const perPage = this.statsPerPage; + const columns = this.columnCount; + const statKeys = Object.keys(displayStats).slice(this.cursor * columns, this.cursor * columns + perPage); statKeys.forEach((key, s) => { const stat = displayStats[key] as DisplayStat; - const value = stat.sourceFunc!(globalScene.gameData); // TODO: is this bang correct? + const value = stat.sourceFunc?.(globalScene.gameData) ?? "-"; + const valAsInt = Number.parseInt(value); this.statLabels[s].setText( - !stat.hidden || Number.isNaN(Number.parseInt(value)) || Number.parseInt(value) - ? i18next.t(`gameStatsUiHandler:${stat.label_key}`) - : "???", + !stat.hidden || Number.isNaN(value) || valAsInt ? i18next.t(`gameStatsUiHandler:${stat.label_key}`) : "???", ); this.statValues[s].setText(value); }); - if (statKeys.length < 18) { - for (let s = statKeys.length; s < 18; s++) { - this.statLabels[s].setText(""); - this.statValues[s].setText(""); - } + for (let s = statKeys.length; s < perPage; s++) { + this.statLabels[s].setText(""); + this.statValues[s].setText(""); } } - /** - * Show arrows at the top / bottom of the page if it's possible to scroll in that direction - */ - updateArrows(): void { - const showUpArrow = this.cursor > 0; - this.arrowUp.setVisible(showUpArrow); - - const showDownArrow = this.cursor < Math.ceil((Object.keys(displayStats).length - 18) / 2); - this.arrowDown.setVisible(showDownArrow); + /** The maximum cursor position */ + private get maxCursorPos(): number { + return Math.ceil((Object.keys(displayStats).length - this.statsPerPage) / this.columnCount); } processInput(button: Button): boolean { @@ -370,45 +424,59 @@ export class GameStatsUiHandler extends UiHandler { let success = false; - if (button === Button.CANCEL) { - success = true; - globalScene.ui.revertMode(); - } else { - switch (button) { - case Button.UP: - if (this.cursor) { - success = this.setCursor(this.cursor - 1); - } - break; - case Button.DOWN: - if (this.cursor < Math.ceil((Object.keys(displayStats).length - 18) / 2)) { - success = this.setCursor(this.cursor + 1); - } - break; - } + /** The direction to move the cursor (up/down) */ + let dir: 1 | -1 = 1; + switch (button) { + case Button.CANCEL: + success = true; + globalScene.ui.revertMode(); + break; + // biome-ignore lint/suspicious/noFallthroughSwitchClause: intentional + case Button.UP: + dir = -1; + case Button.DOWN: + success = this.setCursor(this.cursor + dir); } if (success) { ui.playSelect(); + return true; } - return success; + return false; } - setCursor(cursor: number): boolean { - const ret = super.setCursor(cursor); - - if (ret) { - this.updateStats(); - this.updateArrows(); + /** + * Set the cursor to the specified position, if able and update the stats display. + * + * @remarks + * + * If `newCursor` is not between `0` and {@linkcode maxCursorPos}, or if it is the same as {@linkcode newCursor} + * then no updates happen and `false` is returned. + * + * Otherwise, updates the up/down arrow visibility and calls {@linkcode updateStats} + * + * @param newCursor - The position to set the cursor to. + * @returns Whether the cursor successfully moved to a new position + */ + override setCursor(newCursor: number): boolean { + if (newCursor < 0 || newCursor > this.maxCursorPos || this.cursor === newCursor) { + return false; } - return ret; + this.cursor = newCursor; + + this.updateStats(); + // NOTE: Do not toggle the arrows' "active" property here, as this would cause their animations to desync + this.arrowUp.setVisible(this.cursor > 0); + this.arrowDown.setVisible(this.cursor < this.maxCursorPos); + + return true; } clear() { super.clear(); - this.gameStatsContainer.setVisible(false); + this.gameStatsContainer.setVisible(false).setActive(false); } } diff --git a/test/testUtils/mocks/mocksContainer/mockSprite.ts b/test/testUtils/mocks/mocksContainer/mockSprite.ts index bea1db21629..15995a59977 100644 --- a/test/testUtils/mocks/mocksContainer/mockSprite.ts +++ b/test/testUtils/mocks/mocksContainer/mockSprite.ts @@ -154,6 +154,17 @@ export class MockSprite implements MockGameObject { return this; } + setFlipY(flip: boolean): this { + // Sets the vertical flip state of this Game Object. + this.phaserSprite.setFlipY(flip); + return this; + } + + setFlipX(flip: boolean): this { + this.phaserSprite.setFlipX(flip); + return this; + } + setCrop(x: number, y: number, width: number, height: number): this { // Sets the crop size of this Game Object. this.phaserSprite.setCrop(x, y, width, height); From 58876a2086d4b47075ce426f0281323c10c584a3 Mon Sep 17 00:00:00 2001 From: Lugiad <2070109+Adri1@users.noreply.github.com> Date: Thu, 24 Jul 2025 17:48:52 +0200 Subject: [PATCH 02/79] [UI/UX] [Localization] Apply single-column Game Stats to more languages (#6135) Apply sigle-column Game Stats to more languages --- src/ui/game-stats-ui-handler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/game-stats-ui-handler.ts b/src/ui/game-stats-ui-handler.ts index a9de827e258..759792b122f 100644 --- a/src/ui/game-stats-ui-handler.ts +++ b/src/ui/game-stats-ui-handler.ts @@ -230,7 +230,7 @@ export class GameStatsUiHandler extends UiHandler { const resolvedLang = i18next.resolvedLanguage ?? "en"; // NOTE TO TRANSLATION TEAM: Add more languages that want to display // in a single-column inside of the `[]` (e.g. `["ru", "fr"]`) - return ["ru"].includes(resolvedLang); + return ["fr", "es-ES", "es-MX", "it", "ja", "pt-BR", "ru"].includes(resolvedLang); } /** The number of columns used by this menu in the resolved language */ private get columnCount(): 1 | 2 { From 51d4c33de056dad78990b82aedd9f1b527d05d6d Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Thu, 24 Jul 2025 14:38:31 -0600 Subject: [PATCH 03/79] [Misc] Standardize-file-names (#6137) * Standardize filenames to kebab-case Co-authored-by: pymilkmaiden * Move script outside of public folder * Move update_exp_sprites to scripts * Add ls-lint to lint file and directory names * Update lefthook.yml to skip merge / rebase on all pre-commit commands --------- Co-authored-by: pymilkmaiden --- .github/workflows/linting.yml | 5 ++- .ls-lint.yml | 27 ++++++++++++ CONTRIBUTING.md | 4 +- global.d.ts | 2 +- lefthook.yml | 8 ++-- package.json | 1 + pnpm-lock.yaml | 11 +++++ scripts/create-test/test-boilerplate.ts | 2 +- .../update-exp-sprites.ps1 | 0 .../update_source_comments.py | 8 ++-- .../pokerogue-account-api.ts} | 2 +- .../pokerogue-admin-api.ts} | 0 .../pokerogue-api-types.ts} | 0 .../pokerogue-daily-api.ts} | 0 .../pokerogue-save-data-api.ts} | 0 .../pokerogue-session-save-data-api.ts} | 2 +- .../pokerogue-system-save-data-api.ts} | 2 +- ...veMigrator.ts => session-save-migrator.ts} | 0 ...eMigrator.ts => settings-save-migrator.ts} | 0 ...aveMigrator.ts => system-save-migrator.ts} | 0 src/@types/{UserInfo.ts => user-info.ts} | 0 src/account.ts | 2 +- ...board_qwerty.ts => cfg-keyboard-qwerty.ts} | 0 .../{configHandler.ts => config-handler.ts} | 0 .../{pad_dualshock.ts => pad-dualshock.ts} | 0 .../inputs/{pad_generic.ts => pad-generic.ts} | 0 .../inputs/{pad_procon.ts => pad-procon.ts} | 0 ...licensedSNES.ts => pad-unlicensed-snes.ts} | 0 .../inputs/{pad_xbox360.ts => pad-xbox360.ts} | 0 src/data/abilities/ability.ts | 6 +-- src/data/arena-tag.ts | 4 +- src/data/battle-anims.ts | 2 +- src/data/battler-tags.ts | 4 +- src/data/moves/move-utils.ts | 2 +- src/data/moves/move.ts | 10 ++--- .../encounters/clowning-around-encounter.ts | 2 +- .../encounters/field-trip-encounter.ts | 2 +- src/data/pokemon-forms.ts | 2 +- .../{MoveCategory.ts => move-category.ts} | 0 ...ffectTrigger.ts => move-effect-trigger.ts} | 0 src/enums/{MoveFlags.ts => move-flags.ts} | 0 src/enums/{MoveTarget.ts => move-target.ts} | 0 .../{MultiHitType.ts => multi-hit-type.ts} | 0 src/field/pokemon.ts | 6 +-- src/inputs-controller.ts | 14 +++---- src/phases/move-effect-phase.ts | 8 ++-- src/phases/move-phase.ts | 2 +- src/pipelines/field-sprite.ts | 4 +- ...der.frag => field-sprite-frag-shader.frag} | 0 ...ragShader.frag => sprite-frag-shader.frag} | 0 .../{spriteShader.vert => sprite-shader.vert} | 0 src/pipelines/sprite.ts | 4 +- src/plugins/api/pokerogue-account-api.ts | 2 +- src/plugins/api/pokerogue-admin-api.ts | 2 +- src/plugins/api/pokerogue-api.ts | 2 +- src/plugins/api/pokerogue-daily-api.ts | 2 +- src/plugins/api/pokerogue-savedata-api.ts | 2 +- .../api/pokerogue-session-savedata-api.ts | 2 +- .../api/pokerogue-system-savedata-api.ts | 2 +- src/system/game-data.ts | 2 +- .../version-converter.ts} | 16 ++++---- .../versions/v1_0_4.ts | 6 +-- .../versions/v1_10_0.ts | 2 +- .../versions/v1_7_0.ts | 4 +- .../versions/v1_8_3.ts | 2 +- .../versions/v1_9_0.ts | 2 +- src/{@types => typings}/i18next.d.ts | 0 src/ui/fight-ui-handler.ts | 2 +- src/ui/move-info-overlay.ts | 2 +- .../settings/abstract-binding-ui-handler.ts | 2 +- .../abstract-control-settings-ui-handler.ts | 4 +- .../settings/abstract-settings-ui-handler.ts | 2 +- src/ui/settings/gamepad-binding-ui-handler.ts | 2 +- .../settings/keyboard-binding-ui-handler.ts | 2 +- .../{navigationMenu.ts => navigation-menu.ts} | 0 .../settings/settings-gamepad-ui-handler.ts | 6 +-- .../settings/settings-keyboard-ui-handler.ts | 6 +-- src/ui/settings/shiny_icons.json | 41 ------------------- src/ui/summary-ui-handler.ts | 2 +- src/ui/ui.ts | 2 +- ...st.ts => ability-activation-order.test.ts} | 2 +- ...on.test.ts => ability-duplication.test.ts} | 2 +- ..._timing.test.ts => ability-timing.test.ts} | 2 +- test/abilities/analytic.test.ts | 2 +- test/abilities/anger-point.test.ts | 2 +- ...{arena_trap.test.ts => arena-trap.test.ts} | 2 +- ...{aroma_veil.test.ts => aroma-veil.test.ts} | 2 +- ...{aura_break.test.ts => aura-break.test.ts} | 2 +- test/abilities/battery.test.ts | 2 +- ...attle_bond.test.ts => battle-bond.test.ts} | 4 +- ...east_boost.test.ts => beast-boost.test.ts} | 2 +- test/abilities/commander.test.ts | 2 +- test/abilities/competitive.test.ts | 2 +- test/abilities/contrary.test.ts | 2 +- test/abilities/corrosion.test.ts | 2 +- test/abilities/costar.test.ts | 2 +- .../{cud_chew.test.ts => cud-chew.test.ts} | 2 +- test/abilities/dancer.test.ts | 2 +- test/abilities/defiant.test.ts | 2 +- test/abilities/desolate-land.test.ts | 2 +- test/abilities/disguise.test.ts | 2 +- .../{dry_skin.test.ts => dry-skin.test.ts} | 2 +- ...{early_bird.test.ts => early-bird.test.ts} | 2 +- ...{flash_fire.test.ts => flash-fire.test.ts} | 2 +- ...lower_gift.test.ts => flower-gift.test.ts} | 2 +- ...lower_veil.test.ts => flower-veil.test.ts} | 2 +- test/abilities/forecast.test.ts | 2 +- ...end_guard.test.ts => friend-guard.test.ts} | 4 +- ...d_as_gold.test.ts => good-as-gold.test.ts} | 2 +- ...actics.test.ts => gorilla-tactics.test.ts} | 2 +- test/abilities/guard-dog.test.ts | 2 +- ...p_missile.test.ts => gulp-missile.test.ts} | 2 +- test/abilities/harvest.test.ts | 2 +- test/abilities/healer.test.ts | 2 +- test/abilities/heatproof.test.ts | 2 +- ...ey_gather.test.ts => honey-gather.test.ts} | 2 +- test/abilities/hustle.test.ts | 2 +- ...er_cutter.test.ts => hyper-cutter.test.ts} | 2 +- .../{ice_face.test.ts => ice-face.test.ts} | 2 +- test/abilities/illuminate.test.ts | 2 +- test/abilities/illusion.test.ts | 2 +- test/abilities/immunity.test.ts | 2 +- test/abilities/infiltrator.test.ts | 2 +- test/abilities/innards-out.test.ts | 2 +- test/abilities/insomnia.test.ts | 2 +- test/abilities/intimidate.test.ts | 2 +- ...d_sword.test.ts => intrepid-sword.test.ts} | 2 +- test/abilities/lightningrod.test.ts | 2 +- test/abilities/limber.test.ts | 2 +- ...ic_bounce.test.ts => magic-bounce.test.ts} | 2 +- ...agic_guard.test.ts => magic-guard.test.ts} | 2 +- ...agma_armor.test.ts => magma-armor.test.ts} | 2 +- test/abilities/mimicry.test.ts | 2 +- ...ror_armor.test.ts => mirror-armor.test.ts} | 2 +- ...d_breaker.test.ts => mold-breaker.test.ts} | 2 +- test/abilities/moody.test.ts | 2 +- test/abilities/moxie.test.ts | 2 +- test/abilities/mummy.test.ts | 2 +- ...m_might.test.ts => mycelium-might.test.ts} | 2 +- ...g_gas.test.ts => neutralizing-gas.test.ts} | 2 +- .../{no_guard.test.ts => no-guard.test.ts} | 2 +- .../abilities/normal-move-type-change.test.ts | 2 +- test/abilities/normalize.test.ts | 2 +- test/abilities/oblivious.test.ts | 2 +- .../{own_tempo.test.ts => own-tempo.test.ts} | 2 +- ...tal_bond.test.ts => parental-bond.test.ts} | 2 +- ...astel_veil.test.ts => pastel-veil.test.ts} | 2 +- ...erish_body.test.ts => perish-body.test.ts} | 2 +- ...struct.test.ts => power-construct.test.ts} | 2 +- ...{power_spot.test.ts => power-spot.test.ts} | 2 +- test/abilities/protean-libero.test.ts | 2 +- test/abilities/protosynthesis.test.ts | 2 +- ...{quick_draw.test.ts => quick-draw.test.ts} | 2 +- .../{sand_spit.test.ts => sand-spit.test.ts} | 2 +- .../{sand_veil.test.ts => sand-veil.test.ts} | 2 +- ...{sap_sipper.test.ts => sap-sipper.test.ts} | 2 +- test/abilities/schooling.test.ts | 2 +- ...cleaner.test.ts => screen-cleaner.test.ts} | 2 +- ...{seed_sower.test.ts => seed-sower.test.ts} | 2 +- ...ene_grace.test.ts => serene-grace.test.ts} | 2 +- ...heer_force.test.ts => sheer-force.test.ts} | 2 +- test/abilities/shell-armor.test.ts | 2 +- ...hield_dust.test.ts => shield-dust.test.ts} | 2 +- ...elds_down.test.ts => shields-down.test.ts} | 2 +- test/abilities/simple.test.ts | 2 +- ...peed_boost.test.ts => speed-boost.test.ts} | 2 +- test/abilities/stakeout.test.ts | 2 +- test/abilities/stall.test.ts | 2 +- ...y_spirit.test.ts => steely-spirit.test.ts} | 2 +- ...torm_drain.test.ts => storm-drain.test.ts} | 2 +- test/abilities/sturdy.test.ts | 2 +- ...{super_luck.test.ts => super-luck.test.ts} | 2 +- ...rlord.test.ts => supreme-overlord.test.ts} | 2 +- ...{sweet_veil.test.ts => sweet-veil.test.ts} | 2 +- test/abilities/synchronize.test.ts | 2 +- ...{tera_shell.test.ts => tera-shell.test.ts} | 2 +- ...hange.test.ts => thermal-exchange.test.ts} | 2 +- test/abilities/trace.test.ts | 2 +- test/abilities/unburden.test.ts | 2 +- ...nseen_fist.test.ts => unseen-fist.test.ts} | 2 +- ...tory_star.test.ts => victory-star.test.ts} | 2 +- ...al_spirit.test.ts => vital-spirit.test.ts} | 2 +- ...olt_absorb.test.ts => volt-absorb.test.ts} | 2 +- ...pirit.test.ts => wandering-spirit.test.ts} | 2 +- ...er_bubble.test.ts => water-bubble.test.ts} | 2 +- ...{water_veil.test.ts => water-veil.test.ts} | 2 +- .../{wimp_out.test.ts => wimp-out.test.ts} | 2 +- ...{wind_power.test.ts => wind-power.test.ts} | 2 +- ...{wind_rider.test.ts => wind-rider.test.ts} | 2 +- ...onder_skin.test.ts => wonder-skin.test.ts} | 2 +- .../{zen_mode.test.ts => zen-mode.test.ts} | 2 +- ...o_to_hero.test.ts => zero-to-hero.test.ts} | 2 +- test/achievements/achievement.test.ts | 2 +- ..._gravity.test.ts => arena-gravity.test.ts} | 2 +- ...terrain.test.ts => grassy-terrain.test.ts} | 2 +- ...eather_fog.test.ts => weather-fog.test.ts} | 2 +- ...ther_hail.test.ts => weather-hail.test.ts} | 2 +- ...torm.test.ts => weather-sandstorm.test.ts} | 2 +- ...s.test.ts => weather-strong-winds.test.ts} | 2 +- test/battle-scene.test.ts | 2 +- ...lity_swap.test.ts => ability-swap.test.ts} | 2 +- test/battle/battle-order.test.ts | 2 +- test/battle/battle.test.ts | 6 +-- ...ion.test.ts => damage-calculation.test.ts} | 2 +- ...e_battle.test.ts => double-battle.test.ts} | 2 +- ..._battle.test.ts => inverse-battle.test.ts} | 2 +- ..._battle.test.ts => special-battle.test.ts} | 2 +- .../octolock.test.ts | 2 +- .../stockpiling.test.ts | 2 +- .../substitute.test.ts | 2 +- test/boss-pokemon.test.ts | 2 +- ...{daily_mode.test.ts => daily-mode.test.ts} | 2 +- ...ssages.test.ts => splash-messages.test.ts} | 0 ...s_effect.test.ts => status-effect.test.ts} | 4 +- test/eggs/egg.test.ts | 4 +- test/eggs/manaphy-egg.test.ts | 4 +- ...less_boss.test.ts => endless-boss.test.ts} | 2 +- ..._command.test.ts => enemy-command.test.ts} | 4 +- test/escape-calculations.test.ts | 2 +- test/evolution.test.ts | 2 +- test/field/pokemon-id-checks.test.ts | 2 +- test/field/pokemon.test.ts | 2 +- ...{final_boss.test.ts => final-boss.test.ts} | 2 +- .../{fontFace.setup.ts => font-face.setup.ts} | 0 test/game-mode.test.ts | 2 +- test/inputs/inputs.test.ts | 8 ++-- test/internals.test.ts | 2 +- .../{dire_hit.test.ts => dire-hit.test.ts} | 2 +- ...s => double-battle-chance-booster.test.ts} | 2 +- test/items/eviolite.test.ts | 2 +- ...xp_booster.test.ts => exp-booster.test.ts} | 2 +- .../{grip_claw.test.ts => grip-claw.test.ts} | 2 +- test/items/leek.test.ts | 2 +- test/items/leftovers.test.ts | 2 +- ...{light_ball.test.ts => light-ball.test.ts} | 2 +- ...k_capsule.test.ts => lock-capsule.test.ts} | 2 +- ...al_powder.test.ts => metal-powder.test.ts} | 2 +- ...{multi_lens.test.ts => multi-lens.test.ts} | 2 +- ...cal_rock.test.ts => mystical-rock.test.ts} | 2 +- ...ck_powder.test.ts => quick-powder.test.ts} | 2 +- ...iver_seed.test.ts => reviver-seed.test.ts} | 2 +- ...{scope_lens.test.ts => scope-lens.test.ts} | 2 +- ...est.ts => temp-stat-stage-booster.test.ts} | 2 +- ...{thick_club.test.ts => thick-club.test.ts} | 2 +- .../{toxic_orb.test.ts => toxic-orb.test.ts} | 2 +- test/misc.test.ts | 4 +- test/moves/ability-ignore-moves.test.ts | 2 +- .../{after_you.test.ts => after-you.test.ts} | 2 +- ...g_voice.test.ts => alluring-voice.test.ts} | 2 +- test/moves/aromatherapy.test.ts | 2 +- test/moves/assist.test.ts | 2 +- test/moves/astonish.test.ts | 2 +- ...urora_veil.test.ts => aurora-veil.test.ts} | 2 +- test/moves/autotomize.test.ts | 2 +- .../{baddy_bad.test.ts => baddy-bad.test.ts} | 2 +- ..._bunker.test.ts => baneful-bunker.test.ts} | 2 +- ...{baton_pass.test.ts => baton-pass.test.ts} | 2 +- ...{beak_blast.test.ts => beak-blast.test.ts} | 2 +- .../{beat_up.test.ts => beat-up.test.ts} | 2 +- ...{belly_drum.test.ts => belly-drum.test.ts} | 2 +- ...lousy.test.ts => burning-jealousy.test.ts} | 2 +- test/moves/camouflage.test.ts | 2 +- ...ss_edge.test.ts => ceaseless-edge.test.ts} | 2 +- ...ption.test.ts => chilly-reception.test.ts} | 2 +- test/moves/chloroblast.test.ts | 2 +- ...s_soul.test.ts => clangorous-soul.test.ts} | 2 +- test/moves/copycat.test.ts | 2 +- ...y_shield.test.ts => crafty-shield.test.ts} | 2 +- test/moves/defog.test.ts | 2 +- ...tiny_bond.test.ts => destiny-bond.test.ts} | 2 +- ...nd_storm.test.ts => diamond-storm.test.ts} | 2 +- test/moves/dig.test.ts | 2 +- test/moves/disable.test.ts | 2 +- test/moves/dive.test.ts | 2 +- test/moves/doodle.test.ts | 2 +- ...ouble_team.test.ts => double-team.test.ts} | 2 +- ...gon_cheer.test.ts => dragon-cheer.test.ts} | 2 +- ...ragon_rage.test.ts => dragon-rage.test.ts} | 2 +- ...ragon_tail.test.ts => dragon-tail.test.ts} | 2 +- ..._cannon.test.ts => dynamax-cannon.test.ts} | 2 +- test/moves/effectiveness.test.ts | 2 +- test/moves/electrify.test.ts | 2 +- ...ctro_shot.test.ts => electro-shot.test.ts} | 2 +- test/moves/encore.test.ts | 2 +- test/moves/endure.test.ts | 2 +- test/moves/entrainment.test.ts | 2 +- ...{fairy_lock.test.ts => fairy-lock.test.ts} | 2 +- .../{fake_out.test.ts => fake-out.test.ts} | 2 +- ...alse_swipe.test.ts => false-swipe.test.ts} | 2 +- ...l_stinger.test.ts => fell-stinger.test.ts} | 2 +- ...illet_away.test.ts => fillet-away.test.ts} | 2 +- test/moves/first-attack-double-power.test.ts | 2 +- test/moves/fissure.test.ts | 2 +- ...lame_burst.test.ts => flame-burst.test.ts} | 2 +- ...r_shield.test.ts => flower-shield.test.ts} | 2 +- test/moves/fly.test.ts | 2 +- ...ocus_punch.test.ts => focus-punch.test.ts} | 2 +- .../{follow_me.test.ts => follow-me.test.ts} | 2 +- test/moves/foresight.test.ts | 2 +- ...ts_curse.test.ts => forests-curse.test.ts} | 2 +- ...{freeze_dry.test.ts => freeze-dry.test.ts} | 2 +- ...ezy_frost.test.ts => freezy-frost.test.ts} | 2 +- ...usion_bolt.test.ts => fusion-bolt.test.ts} | 2 +- ...bolt.test.ts => fusion-flare-bolt.test.ts} | 2 +- ...ion_flare.test.ts => fusion-flare.test.ts} | 2 +- ...ure_sight.test.ts => future-sight.test.ts} | 2 +- ...astro_acid.test.ts => gastro-acid.test.ts} | 2 +- test/moves/geomancy.test.ts | 2 +- ..._hammer.test.ts => gigaton-hammer.test.ts} | 2 +- ...laive_rush.test.ts => glaive-rush.test.ts} | 2 +- test/moves/growth.test.ts | 2 +- test/moves/grudge.test.ts | 2 +- ...uard_split.test.ts => guard-split.test.ts} | 2 +- ...{guard_swap.test.ts => guard-swap.test.ts} | 2 +- ...{hard_press.test.ts => hard-press.test.ts} | 2 +- test/moves/haze.test.ts | 2 +- .../{heal_bell.test.ts => heal-bell.test.ts} | 2 +- ...{heal_block.test.ts => heal-block.test.ts} | 2 +- ...{heart_swap.test.ts => heart-swap.test.ts} | 2 +- ...{hyper_beam.test.ts => hyper-beam.test.ts} | 2 +- test/moves/imprison.test.ts | 2 +- test/moves/instruct.test.ts | 2 +- .../{jaw_lock.test.ts => jaw-lock.test.ts} | 2 +- .../{lash_out.test.ts => lash-out.test.ts} | 2 +- test/moves/last-resort.test.ts | 2 +- ...respects.test.ts => last-respects.test.ts} | 2 +- ...ht_screen.test.ts => light-screen.test.ts} | 2 +- ...ucky_chant.test.ts => lucky-chant.test.ts} | 2 +- ...lessing.test.ts => lunar-blessing.test.ts} | 2 +- ...unar_dance.test.ts => lunar-dance.test.ts} | 2 +- ...{magic_coat.test.ts => magic-coat.test.ts} | 2 +- ...agnet_rise.test.ts => magnet-rise.test.ts} | 2 +- ...e_it_rain.test.ts => make-it-rain.test.ts} | 2 +- .../{mat_block.test.ts => mat-block.test.ts} | 2 +- ...etal_burst.test.ts => metal-burst.test.ts} | 2 +- test/moves/metronome.test.ts | 2 +- ...iracle_eye.test.ts => miracle-eye.test.ts} | 2 +- ...irror_move.test.ts => mirror-move.test.ts} | 2 +- test/moves/mist.test.ts | 2 +- ...ti_target.test.ts => multi-target.test.ts} | 2 +- test/moves/nightmare.test.ts | 2 +- test/moves/obstruct.test.ts | 2 +- test/moves/octolock.test.ts | 2 +- .../{order_up.test.ts => order-up.test.ts} | 2 +- ...ting_shot.test.ts => parting-shot.test.ts} | 2 +- test/moves/payback.test.ts | 2 +- ...sma_fists.test.ts => plasma-fists.test.ts} | 2 +- ...dge_moves.test.ts => pledge-moves.test.ts} | 2 +- ...ollen_puff.test.ts => pollen-puff.test.ts} | 2 +- test/moves/powder.test.ts | 2 +- ...ower_shift.test.ts => power-shift.test.ts} | 2 +- ...ower_split.test.ts => power-split.test.ts} | 2 +- ...{power_swap.test.ts => power-swap.test.ts} | 2 +- ...ower_trick.test.ts => power-trick.test.ts} | 2 +- test/moves/protect.test.ts | 2 +- ...cho_shift.test.ts => psycho-shift.test.ts} | 2 +- test/moves/purify.test.ts | 2 +- test/moves/quash.test.ts | 2 +- ...uick_guard.test.ts => quick-guard.test.ts} | 2 +- .../{rage_fist.test.ts => rage-fist.test.ts} | 2 +- ...age_powder.test.ts => rage-powder.test.ts} | 2 +- ...lect_type.test.ts => reflect-type.test.ts} | 2 +- test/moves/reflect.test.ts | 2 +- ...{relic_song.test.ts => relic-song.test.ts} | 2 +- test/moves/retaliate.test.ts | 2 +- ...ssing.test.ts => revival-blessing.test.ts} | 2 +- .../{role_play.test.ts => role-play.test.ts} | 2 +- test/moves/rollout.test.ts | 2 +- test/moves/roost.test.ts | 2 +- test/moves/round.test.ts | 2 +- test/moves/safeguard.test.ts | 2 +- ...{scale_shot.test.ts => scale-shot.test.ts} | 2 +- ...ret_power.test.ts => secret-power.test.ts} | 2 +- .../{shed_tail.test.ts => shed-tail.test.ts} | 2 +- ...ide_arm.test.ts => shell-side-arm.test.ts} | 2 +- ...{shell_trap.test.ts => shell-trap.test.ts} | 2 +- ...imple_beam.test.ts => simple-beam.test.ts} | 2 +- test/moves/sketch.test.ts | 2 +- ...{skill_swap.test.ts => skill-swap.test.ts} | 2 +- ...{sleep_talk.test.ts => sleep-talk.test.ts} | 2 +- ...{solar_beam.test.ts => solar-beam.test.ts} | 2 +- ...ly_swirl.test.ts => sparkly-swirl.test.ts} | 2 +- ...l_thief.test.ts => spectral-thief.test.ts} | 2 +- ...{speed_swap.test.ts => speed-swap.test.ts} | 2 +- test/moves/spikes.test.ts | 2 +- .../{spit_up.test.ts => spit-up.test.ts} | 2 +- test/moves/spotlight.test.ts | 2 +- test/moves/steamroller.test.ts | 2 +- test/moves/stockpile.test.ts | 2 +- test/moves/struggle.test.ts | 2 +- test/moves/substitute.test.ts | 2 +- test/moves/swallow.test.ts | 2 +- test/moves/synchronoise.test.ts | 2 +- ...{syrup_bomb.test.ts => syrup-bomb.test.ts} | 2 +- test/moves/tackle.test.ts | 2 +- .../{tail_whip.test.ts => tail-whip.test.ts} | 2 +- test/moves/tailwind.test.ts | 2 +- .../{tar_shot.test.ts => tar-shot.test.ts} | 2 +- test/moves/taunt.test.ts | 2 +- test/moves/telekinesis.test.ts | 2 +- ...{tera_blast.test.ts => tera-blast.test.ts} | 2 +- ...arstorm.test.ts => tera-starstorm.test.ts} | 2 +- ...arrows.test.ts => thousand-arrows.test.ts} | 2 +- ...hroat_chop.test.ts => throat-chop.test.ts} | 2 +- ...nder_wave.test.ts => thunder-wave.test.ts} | 2 +- .../{tidy_up.test.ts => tidy-up.test.ts} | 2 +- test/moves/torment.test.ts | 2 +- ...ic_spikes.test.ts => toxic-spikes.test.ts} | 2 +- test/moves/toxic.test.ts | 2 +- test/moves/transform-imposter.test.ts | 2 +- ...r_treat.test.ts => trick-or-treat.test.ts} | 2 +- ...e_arrows.test.ts => triple-arrows.test.ts} | 2 +- test/moves/{u_turn.test.ts => u-turn.test.ts} | 2 +- ...{upper_hand.test.ts => upper-hand.test.ts} | 2 +- test/moves/whirlwind.test.ts | 2 +- ...{wide_guard.test.ts => wide-guard.test.ts} | 2 +- ...ill_o_wisp.test.ts => will-o-wisp.test.ts} | 2 +- .../mystery-encounter/encounter-test-utils.ts | 2 +- .../a-trainers-test-encounter.test.ts | 4 +- .../absolute-avarice-encounter.test.ts | 2 +- ...an-offer-you-cant-refuse-encounter.test.ts | 4 +- .../berries-abound-encounter.test.ts | 4 +- .../bug-type-superfan-encounter.test.ts | 4 +- .../clowning-around-encounter.test.ts | 4 +- .../dancing-lessons-encounter.test.ts | 2 +- .../encounters/delibirdy-encounter.test.ts | 2 +- .../department-store-sale-encounter.test.ts | 2 +- .../encounters/field-trip-encounter.test.ts | 2 +- .../fiery-fallout-encounter.test.ts | 4 +- .../fight-or-flight-encounter.test.ts | 4 +- .../fun-and-games-encounter.test.ts | 4 +- .../global-trade-system-encounter.test.ts | 2 +- .../encounters/lost-at-sea-encounter.test.ts | 4 +- .../mysterious-challengers-encounter.test.ts | 4 +- .../encounters/part-timer-encounter.test.ts | 2 +- .../encounters/safari-zone.test.ts | 4 +- .../teleporting-hijinks-encounter.test.ts | 4 +- .../the-expert-breeder-encounter.test.ts | 4 +- .../the-pokemon-salesman-encounter.test.ts | 4 +- .../the-strong-stuff-encounter.test.ts | 4 +- .../the-winstrate-challenge-encounter.test.ts | 4 +- .../trash-to-treasure-encounter.test.ts | 4 +- .../uncommon-breed-encounter.test.ts | 4 +- .../encounters/weird-dream-encounter.test.ts | 4 +- .../mystery-encounter-utils.test.ts | 4 +- .../mystery-encounter.test.ts | 2 +- test/phases/form-change-phase.test.ts | 2 +- test/phases/frenzy-move-reset.test.ts | 2 +- test/phases/game-over-phase.test.ts | 2 +- test/phases/learn-move-phase.test.ts | 2 +- test/phases/mystery-encounter-phase.test.ts | 2 +- test/phases/phases.test.ts | 2 +- test/phases/select-modifier-phase.test.ts | 4 +- .../plugins/api/pokerogue-account-api.test.ts | 6 +-- test/plugins/api/pokerogue-admin-api.test.ts | 6 +-- test/plugins/api/pokerogue-api.test.ts | 6 +-- test/plugins/api/pokerogue-daily-api.test.ts | 6 +-- .../api/pokerogue-savedata-api.test.ts | 6 +-- .../pokerogue-session-savedata-api.test.ts | 6 +-- .../api/pokerogue-system-savedata-api.test.ts | 6 +-- test/reload.test.ts | 4 +- .../helpers/in-game-manip.ts} | 2 +- .../helpers/menu-manip.ts} | 2 +- .../rebinding-setting.test.ts} | 8 ++-- ...nSprite.test.ts => pokemon-sprite.test.ts} | 2 +- .../{spritesUtils.ts => sprites-utils.ts} | 0 .../{game_data.test.ts => game-data.test.ts} | 2 +- .../error-interceptor.ts} | 0 .../{testUtils => test-utils}/fakeMobile.html | 0 .../game-manager-utils.ts} | 0 .../game-manager.ts} | 32 +++++++-------- .../game-wrapper.ts} | 16 ++++---- .../helpers/challenge-mode-helper.ts} | 4 +- .../helpers/classic-mode-helper.ts} | 4 +- .../helpers/daily-mode-helper.ts} | 2 +- .../helpers/field-helper.ts | 2 +- .../helpers/game-manager-helper.ts} | 2 +- .../helpers/modifiers-helper.ts} | 2 +- .../helpers/move-helper.ts} | 2 +- .../helpers/overrides-helper.ts} | 2 +- .../helpers/reload-helper.ts} | 4 +- .../helpers/settings-helper.ts} | 2 +- .../inputs-handler.ts} | 6 +-- .../listeners-manager.ts} | 0 .../mocks/mock-clock.ts} | 0 .../mocks/mock-console-log.ts} | 0 .../mocks/mock-context-canvas.ts} | 0 .../mocks/mock-fetch.ts} | 0 .../mocks/mock-game-object-creator.ts} | 4 +- .../mocks/mock-game-object.ts} | 0 .../mocks/mock-loader.ts} | 0 .../mocks/mock-local-storage.ts} | 0 .../mocks/mock-texture-manager.ts} | 24 +++++------ .../mocks/mock-timed-event-manager.ts} | 0 .../mocks/mock-video-game-object.ts} | 2 +- .../mocks-container}/mock-bbcode-text.ts | 2 +- .../mocks/mocks-container/mock-container.ts} | 4 +- .../mocks/mocks-container/mock-graphics.ts} | 2 +- .../mocks/mocks-container/mock-image.ts} | 2 +- .../mocks/mocks-container}/mock-input-text.ts | 2 +- .../mocks/mocks-container/mock-nineslice.ts} | 2 +- .../mocks/mocks-container/mock-polygon.ts} | 2 +- .../mocks/mocks-container/mock-rectangle.ts} | 2 +- .../mocks/mocks-container/mock-sprite.ts} | 2 +- .../mocks/mocks-container/mock-text.ts} | 2 +- .../mocks/mocks-container/mock-texture.ts} | 4 +- .../phase-interceptor.ts} | 2 +- .../saves/data_new.prsv | 0 .../saves/data_pokedex_tests.prsv | 0 .../saves/data_pokedex_tests_v2.prsv | 0 .../saves/everything.prsv | 0 .../test-file-initialization.ts} | 12 +++--- .../testUtils.ts => test-utils/test-utils.ts} | 0 .../text-interceptor.ts} | 0 ...attle_info.test.ts => battle-info.test.ts} | 2 +- test/ui/pokedex.test.ts | 22 +++++----- test/ui/starter-select.test.ts | 20 ++++----- test/ui/transfer-item.test.ts | 2 +- test/ui/type-hints.test.ts | 4 +- test/vitest.setup.ts | 2 +- tsconfig.json | 4 +- vitest.config.ts | 2 +- 522 files changed, 675 insertions(+), 672 deletions(-) create mode 100644 .ls-lint.yml rename update_exp_sprites.ps1 => scripts/update-exp-sprites.ps1 (100%) rename public/update-source-comments.py => scripts/update_source_comments.py (85%) rename src/@types/{PokerogueAccountApi.ts => api/pokerogue-account-api.ts} (85%) rename src/@types/{PokerogueAdminApi.ts => api/pokerogue-admin-api.ts} (100%) rename src/@types/{PokerogueApi.ts => api/pokerogue-api-types.ts} (100%) rename src/@types/{PokerogueDailyApi.ts => api/pokerogue-daily-api.ts} (100%) rename src/@types/{PokerogueSavedataApi.ts => api/pokerogue-save-data-api.ts} (100%) rename src/@types/{PokerogueSessionSavedataApi.ts => api/pokerogue-session-save-data-api.ts} (95%) rename src/@types/{PokerogueSystemSavedataApi.ts => api/pokerogue-system-save-data-api.ts} (88%) rename src/@types/{SessionSaveMigrator.ts => session-save-migrator.ts} (100%) rename src/@types/{SettingsSaveMigrator.ts => settings-save-migrator.ts} (100%) rename src/@types/{SystemSaveMigrator.ts => system-save-migrator.ts} (100%) rename src/@types/{UserInfo.ts => user-info.ts} (100%) rename src/configs/inputs/{cfg_keyboard_qwerty.ts => cfg-keyboard-qwerty.ts} (100%) rename src/configs/inputs/{configHandler.ts => config-handler.ts} (100%) rename src/configs/inputs/{pad_dualshock.ts => pad-dualshock.ts} (100%) rename src/configs/inputs/{pad_generic.ts => pad-generic.ts} (100%) rename src/configs/inputs/{pad_procon.ts => pad-procon.ts} (100%) rename src/configs/inputs/{pad_unlicensedSNES.ts => pad-unlicensed-snes.ts} (100%) rename src/configs/inputs/{pad_xbox360.ts => pad-xbox360.ts} (100%) rename src/enums/{MoveCategory.ts => move-category.ts} (100%) rename src/enums/{MoveEffectTrigger.ts => move-effect-trigger.ts} (100%) rename src/enums/{MoveFlags.ts => move-flags.ts} (100%) rename src/enums/{MoveTarget.ts => move-target.ts} (100%) rename src/enums/{MultiHitType.ts => multi-hit-type.ts} (100%) rename src/pipelines/glsl/{fieldSpriteFragShader.frag => field-sprite-frag-shader.frag} (100%) rename src/pipelines/glsl/{spriteFragShader.frag => sprite-frag-shader.frag} (100%) rename src/pipelines/glsl/{spriteShader.vert => sprite-shader.vert} (100%) rename src/system/{version_migration/version_converter.ts => version-migration/version-converter.ts} (91%) rename src/system/{version_migration => version-migration}/versions/v1_0_4.ts (97%) rename src/system/{version_migration => version-migration}/versions/v1_10_0.ts (96%) rename src/system/{version_migration => version-migration}/versions/v1_7_0.ts (95%) rename src/system/{version_migration => version-migration}/versions/v1_8_3.ts (94%) rename src/system/{version_migration => version-migration}/versions/v1_9_0.ts (95%) rename src/{@types => typings}/i18next.d.ts (100%) rename src/ui/settings/{navigationMenu.ts => navigation-menu.ts} (100%) delete mode 100644 src/ui/settings/shiny_icons.json rename test/abilities/{ability_activation_order.test.ts => ability-activation-order.test.ts} (98%) rename test/abilities/{ability_duplication.test.ts => ability-duplication.test.ts} (96%) rename test/abilities/{ability_timing.test.ts => ability-timing.test.ts} (96%) rename test/abilities/{arena_trap.test.ts => arena-trap.test.ts} (97%) rename test/abilities/{aroma_veil.test.ts => aroma-veil.test.ts} (97%) rename test/abilities/{aura_break.test.ts => aura-break.test.ts} (97%) rename test/abilities/{battle_bond.test.ts => battle-bond.test.ts} (96%) rename test/abilities/{beast_boost.test.ts => beast-boost.test.ts} (98%) rename test/abilities/{cud_chew.test.ts => cud-chew.test.ts} (99%) rename test/abilities/{dry_skin.test.ts => dry-skin.test.ts} (98%) rename test/abilities/{early_bird.test.ts => early-bird.test.ts} (97%) rename test/abilities/{flash_fire.test.ts => flash-fire.test.ts} (98%) rename test/abilities/{flower_gift.test.ts => flower-gift.test.ts} (99%) rename test/abilities/{flower_veil.test.ts => flower-veil.test.ts} (99%) rename test/abilities/{friend_guard.test.ts => friend-guard.test.ts} (97%) rename test/abilities/{good_as_gold.test.ts => good-as-gold.test.ts} (98%) rename test/abilities/{gorilla_tactics.test.ts => gorilla-tactics.test.ts} (98%) rename test/abilities/{gulp_missile.test.ts => gulp-missile.test.ts} (99%) rename test/abilities/{honey_gather.test.ts => honey-gather.test.ts} (97%) rename test/abilities/{hyper_cutter.test.ts => hyper-cutter.test.ts} (96%) rename test/abilities/{ice_face.test.ts => ice-face.test.ts} (99%) rename test/abilities/{intrepid_sword.test.ts => intrepid-sword.test.ts} (95%) rename test/abilities/{magic_bounce.test.ts => magic-bounce.test.ts} (99%) rename test/abilities/{magic_guard.test.ts => magic-guard.test.ts} (99%) rename test/abilities/{magma_armor.test.ts => magma-armor.test.ts} (96%) rename test/abilities/{mirror_armor.test.ts => mirror-armor.test.ts} (99%) rename test/abilities/{mold_breaker.test.ts => mold-breaker.test.ts} (95%) rename test/abilities/{mycelium_might.test.ts => mycelium-might.test.ts} (98%) rename test/abilities/{neutralizing_gas.test.ts => neutralizing-gas.test.ts} (99%) rename test/abilities/{no_guard.test.ts => no-guard.test.ts} (96%) rename test/abilities/{own_tempo.test.ts => own-tempo.test.ts} (96%) rename test/abilities/{parental_bond.test.ts => parental-bond.test.ts} (99%) rename test/abilities/{pastel_veil.test.ts => pastel-veil.test.ts} (97%) rename test/abilities/{perish_body.test.ts => perish-body.test.ts} (98%) rename test/abilities/{power_construct.test.ts => power-construct.test.ts} (97%) rename test/abilities/{power_spot.test.ts => power-spot.test.ts} (97%) rename test/abilities/{quick_draw.test.ts => quick-draw.test.ts} (97%) rename test/abilities/{sand_spit.test.ts => sand-spit.test.ts} (96%) rename test/abilities/{sand_veil.test.ts => sand-veil.test.ts} (97%) rename test/abilities/{sap_sipper.test.ts => sap-sipper.test.ts} (98%) rename test/abilities/{screen_cleaner.test.ts => screen-cleaner.test.ts} (97%) rename test/abilities/{seed_sower.test.ts => seed-sower.test.ts} (96%) rename test/abilities/{serene_grace.test.ts => serene-grace.test.ts} (96%) rename test/abilities/{sheer_force.test.ts => sheer-force.test.ts} (98%) rename test/abilities/{shield_dust.test.ts => shield-dust.test.ts} (97%) rename test/abilities/{shields_down.test.ts => shields-down.test.ts} (99%) rename test/abilities/{speed_boost.test.ts => speed-boost.test.ts} (98%) rename test/abilities/{steely_spirit.test.ts => steely-spirit.test.ts} (98%) rename test/abilities/{storm_drain.test.ts => storm-drain.test.ts} (98%) rename test/abilities/{super_luck.test.ts => super-luck.test.ts} (95%) rename test/abilities/{supreme_overlord.test.ts => supreme-overlord.test.ts} (98%) rename test/abilities/{sweet_veil.test.ts => sweet-veil.test.ts} (97%) rename test/abilities/{tera_shell.test.ts => tera-shell.test.ts} (98%) rename test/abilities/{thermal_exchange.test.ts => thermal-exchange.test.ts} (96%) rename test/abilities/{unseen_fist.test.ts => unseen-fist.test.ts} (98%) rename test/abilities/{victory_star.test.ts => victory-star.test.ts} (96%) rename test/abilities/{vital_spirit.test.ts => vital-spirit.test.ts} (96%) rename test/abilities/{volt_absorb.test.ts => volt-absorb.test.ts} (97%) rename test/abilities/{wandering_spirit.test.ts => wandering-spirit.test.ts} (97%) rename test/abilities/{water_bubble.test.ts => water-bubble.test.ts} (96%) rename test/abilities/{water_veil.test.ts => water-veil.test.ts} (96%) rename test/abilities/{wimp_out.test.ts => wimp-out.test.ts} (99%) rename test/abilities/{wind_power.test.ts => wind-power.test.ts} (98%) rename test/abilities/{wind_rider.test.ts => wind-rider.test.ts} (98%) rename test/abilities/{wonder_skin.test.ts => wonder-skin.test.ts} (97%) rename test/abilities/{zen_mode.test.ts => zen-mode.test.ts} (98%) rename test/abilities/{zero_to_hero.test.ts => zero-to-hero.test.ts} (98%) rename test/arena/{arena_gravity.test.ts => arena-gravity.test.ts} (98%) rename test/arena/{grassy_terrain.test.ts => grassy-terrain.test.ts} (96%) rename test/arena/{weather_fog.test.ts => weather-fog.test.ts} (95%) rename test/arena/{weather_hail.test.ts => weather-hail.test.ts} (97%) rename test/arena/{weather_sandstorm.test.ts => weather-sandstorm.test.ts} (97%) rename test/arena/{weather_strong_winds.test.ts => weather-strong-winds.test.ts} (98%) rename test/battle/{ability_swap.test.ts => ability-swap.test.ts} (97%) rename test/battle/{damage_calculation.test.ts => damage-calculation.test.ts} (98%) rename test/battle/{double_battle.test.ts => double-battle.test.ts} (98%) rename test/battle/{inverse_battle.test.ts => inverse-battle.test.ts} (99%) rename test/battle/{special_battle.test.ts => special-battle.test.ts} (98%) rename test/{battlerTags => battler-tags}/octolock.test.ts (96%) rename test/{battlerTags => battler-tags}/stockpiling.test.ts (99%) rename test/{battlerTags => battler-tags}/substitute.test.ts (99%) rename test/{daily_mode.test.ts => daily-mode.test.ts} (98%) rename test/data/{splash_messages.test.ts => splash-messages.test.ts} (100%) rename test/data/{status_effect.test.ts => status-effect.test.ts} (99%) rename test/{endless_boss.test.ts => endless-boss.test.ts} (98%) rename test/{enemy_command.test.ts => enemy-command.test.ts} (96%) rename test/{final_boss.test.ts => final-boss.test.ts} (98%) rename test/{fontFace.setup.ts => font-face.setup.ts} (100%) rename test/items/{dire_hit.test.ts => dire-hit.test.ts} (98%) rename test/items/{double_battle_chance_booster.test.ts => double-battle-chance-booster.test.ts} (98%) rename test/items/{exp_booster.test.ts => exp-booster.test.ts} (95%) rename test/items/{grip_claw.test.ts => grip-claw.test.ts} (98%) rename test/items/{light_ball.test.ts => light-ball.test.ts} (99%) rename test/items/{lock_capsule.test.ts => lock-capsule.test.ts} (96%) rename test/items/{metal_powder.test.ts => metal-powder.test.ts} (99%) rename test/items/{multi_lens.test.ts => multi-lens.test.ts} (99%) rename test/items/{mystical_rock.test.ts => mystical-rock.test.ts} (96%) rename test/items/{quick_powder.test.ts => quick-powder.test.ts} (99%) rename test/items/{reviver_seed.test.ts => reviver-seed.test.ts} (98%) rename test/items/{scope_lens.test.ts => scope-lens.test.ts} (95%) rename test/items/{temp_stat_stage_booster.test.ts => temp-stat-stage-booster.test.ts} (98%) rename test/items/{thick_club.test.ts => thick-club.test.ts} (99%) rename test/items/{toxic_orb.test.ts => toxic-orb.test.ts} (96%) rename test/moves/{after_you.test.ts => after-you.test.ts} (98%) rename test/moves/{alluring_voice.test.ts => alluring-voice.test.ts} (95%) rename test/moves/{aurora_veil.test.ts => aurora-veil.test.ts} (98%) rename test/moves/{baddy_bad.test.ts => baddy-bad.test.ts} (94%) rename test/moves/{baneful_bunker.test.ts => baneful-bunker.test.ts} (97%) rename test/moves/{baton_pass.test.ts => baton-pass.test.ts} (98%) rename test/moves/{beak_blast.test.ts => beak-blast.test.ts} (98%) rename test/moves/{beat_up.test.ts => beat-up.test.ts} (97%) rename test/moves/{belly_drum.test.ts => belly-drum.test.ts} (98%) rename test/moves/{burning_jealousy.test.ts => burning-jealousy.test.ts} (98%) rename test/moves/{ceaseless_edge.test.ts => ceaseless-edge.test.ts} (98%) rename test/moves/{chilly_reception.test.ts => chilly-reception.test.ts} (98%) rename test/moves/{clangorous_soul.test.ts => clangorous-soul.test.ts} (98%) rename test/moves/{crafty_shield.test.ts => crafty-shield.test.ts} (97%) rename test/moves/{destiny_bond.test.ts => destiny-bond.test.ts} (99%) rename test/moves/{diamond_storm.test.ts => diamond-storm.test.ts} (95%) rename test/moves/{double_team.test.ts => double-team.test.ts} (96%) rename test/moves/{dragon_cheer.test.ts => dragon-cheer.test.ts} (98%) rename test/moves/{dragon_rage.test.ts => dragon-rage.test.ts} (98%) rename test/moves/{dragon_tail.test.ts => dragon-tail.test.ts} (99%) rename test/moves/{dynamax_cannon.test.ts => dynamax-cannon.test.ts} (99%) rename test/moves/{electro_shot.test.ts => electro-shot.test.ts} (98%) rename test/moves/{fairy_lock.test.ts => fairy-lock.test.ts} (99%) rename test/moves/{fake_out.test.ts => fake-out.test.ts} (98%) rename test/moves/{false_swipe.test.ts => false-swipe.test.ts} (96%) rename test/moves/{fell_stinger.test.ts => fell-stinger.test.ts} (99%) rename test/moves/{fillet_away.test.ts => fillet-away.test.ts} (98%) rename test/moves/{flame_burst.test.ts => flame-burst.test.ts} (98%) rename test/moves/{flower_shield.test.ts => flower-shield.test.ts} (98%) rename test/moves/{focus_punch.test.ts => focus-punch.test.ts} (98%) rename test/moves/{follow_me.test.ts => follow-me.test.ts} (98%) rename test/moves/{forests_curse.test.ts => forests-curse.test.ts} (95%) rename test/moves/{freeze_dry.test.ts => freeze-dry.test.ts} (99%) rename test/moves/{freezy_frost.test.ts => freezy-frost.test.ts} (98%) rename test/moves/{fusion_bolt.test.ts => fusion-bolt.test.ts} (95%) rename test/moves/{fusion_flare_bolt.test.ts => fusion-flare-bolt.test.ts} (99%) rename test/moves/{fusion_flare.test.ts => fusion-flare.test.ts} (96%) rename test/moves/{future_sight.test.ts => future-sight.test.ts} (95%) rename test/moves/{gastro_acid.test.ts => gastro-acid.test.ts} (98%) rename test/moves/{gigaton_hammer.test.ts => gigaton-hammer.test.ts} (97%) rename test/moves/{glaive_rush.test.ts => glaive-rush.test.ts} (98%) rename test/moves/{guard_split.test.ts => guard-split.test.ts} (97%) rename test/moves/{guard_swap.test.ts => guard-swap.test.ts} (96%) rename test/moves/{hard_press.test.ts => hard-press.test.ts} (97%) rename test/moves/{heal_bell.test.ts => heal-bell.test.ts} (98%) rename test/moves/{heal_block.test.ts => heal-block.test.ts} (98%) rename test/moves/{heart_swap.test.ts => heart-swap.test.ts} (96%) rename test/moves/{hyper_beam.test.ts => hyper-beam.test.ts} (97%) rename test/moves/{jaw_lock.test.ts => jaw-lock.test.ts} (98%) rename test/moves/{lash_out.test.ts => lash-out.test.ts} (96%) rename test/moves/{last_respects.test.ts => last-respects.test.ts} (99%) rename test/moves/{light_screen.test.ts => light-screen.test.ts} (98%) rename test/moves/{lucky_chant.test.ts => lucky-chant.test.ts} (98%) rename test/moves/{lunar_blessing.test.ts => lunar-blessing.test.ts} (97%) rename test/moves/{lunar_dance.test.ts => lunar-dance.test.ts} (97%) rename test/moves/{magic_coat.test.ts => magic-coat.test.ts} (99%) rename test/moves/{magnet_rise.test.ts => magnet-rise.test.ts} (96%) rename test/moves/{make_it_rain.test.ts => make-it-rain.test.ts} (98%) rename test/moves/{mat_block.test.ts => mat-block.test.ts} (97%) rename test/moves/{metal_burst.test.ts => metal-burst.test.ts} (97%) rename test/moves/{miracle_eye.test.ts => miracle-eye.test.ts} (95%) rename test/moves/{mirror_move.test.ts => mirror-move.test.ts} (97%) rename test/moves/{multi_target.test.ts => multi-target.test.ts} (98%) rename test/moves/{order_up.test.ts => order-up.test.ts} (98%) rename test/moves/{parting_shot.test.ts => parting-shot.test.ts} (99%) rename test/moves/{plasma_fists.test.ts => plasma-fists.test.ts} (98%) rename test/moves/{pledge_moves.test.ts => pledge-moves.test.ts} (99%) rename test/moves/{pollen_puff.test.ts => pollen-puff.test.ts} (97%) rename test/moves/{power_shift.test.ts => power-shift.test.ts} (96%) rename test/moves/{power_split.test.ts => power-split.test.ts} (97%) rename test/moves/{power_swap.test.ts => power-swap.test.ts} (96%) rename test/moves/{power_trick.test.ts => power-trick.test.ts} (98%) rename test/moves/{psycho_shift.test.ts => psycho-shift.test.ts} (96%) rename test/moves/{quick_guard.test.ts => quick-guard.test.ts} (98%) rename test/moves/{rage_fist.test.ts => rage-fist.test.ts} (99%) rename test/moves/{rage_powder.test.ts => rage-powder.test.ts} (97%) rename test/moves/{reflect_type.test.ts => reflect-type.test.ts} (96%) rename test/moves/{relic_song.test.ts => relic-song.test.ts} (97%) rename test/moves/{revival_blessing.test.ts => revival-blessing.test.ts} (98%) rename test/moves/{role_play.test.ts => role-play.test.ts} (96%) rename test/moves/{scale_shot.test.ts => scale-shot.test.ts} (97%) rename test/moves/{secret_power.test.ts => secret-power.test.ts} (98%) rename test/moves/{shed_tail.test.ts => shed-tail.test.ts} (97%) rename test/moves/{shell_side_arm.test.ts => shell-side-arm.test.ts} (97%) rename test/moves/{shell_trap.test.ts => shell-trap.test.ts} (98%) rename test/moves/{simple_beam.test.ts => simple-beam.test.ts} (95%) rename test/moves/{skill_swap.test.ts => skill-swap.test.ts} (96%) rename test/moves/{sleep_talk.test.ts => sleep-talk.test.ts} (97%) rename test/moves/{solar_beam.test.ts => solar-beam.test.ts} (98%) rename test/moves/{sparkly_swirl.test.ts => sparkly-swirl.test.ts} (97%) rename test/moves/{spectral_thief.test.ts => spectral-thief.test.ts} (99%) rename test/moves/{speed_swap.test.ts => speed-swap.test.ts} (96%) rename test/moves/{spit_up.test.ts => spit-up.test.ts} (99%) rename test/moves/{syrup_bomb.test.ts => syrup-bomb.test.ts} (98%) rename test/moves/{tail_whip.test.ts => tail-whip.test.ts} (96%) rename test/moves/{tar_shot.test.ts => tar-shot.test.ts} (98%) rename test/moves/{tera_blast.test.ts => tera-blast.test.ts} (99%) rename test/moves/{tera_starstorm.test.ts => tera-starstorm.test.ts} (98%) rename test/moves/{thousand_arrows.test.ts => thousand-arrows.test.ts} (98%) rename test/moves/{throat_chop.test.ts => throat-chop.test.ts} (96%) rename test/moves/{thunder_wave.test.ts => thunder-wave.test.ts} (98%) rename test/moves/{tidy_up.test.ts => tidy-up.test.ts} (98%) rename test/moves/{toxic_spikes.test.ts => toxic-spikes.test.ts} (98%) rename test/moves/{trick_or_treat.test.ts => trick-or-treat.test.ts} (95%) rename test/moves/{triple_arrows.test.ts => triple-arrows.test.ts} (97%) rename test/moves/{u_turn.test.ts => u-turn.test.ts} (98%) rename test/moves/{upper_hand.test.ts => upper-hand.test.ts} (98%) rename test/moves/{wide_guard.test.ts => wide-guard.test.ts} (97%) rename test/moves/{will_o_wisp.test.ts => will-o-wisp.test.ts} (96%) rename test/{settingMenu/helpers/inGameManip.ts => setting-menu/helpers/in-game-manip.ts} (98%) rename test/{settingMenu/helpers/menuManip.ts => setting-menu/helpers/menu-manip.ts} (99%) rename test/{settingMenu/rebinding_setting.test.ts => setting-menu/rebinding-setting.test.ts} (99%) rename test/sprites/{pokemonSprite.test.ts => pokemon-sprite.test.ts} (99%) rename test/sprites/{spritesUtils.ts => sprites-utils.ts} (100%) rename test/system/{game_data.test.ts => game-data.test.ts} (97%) rename test/{testUtils/errorInterceptor.ts => test-utils/error-interceptor.ts} (100%) rename test/{testUtils => test-utils}/fakeMobile.html (100%) rename test/{testUtils/gameManagerUtils.ts => test-utils/game-manager-utils.ts} (100%) rename test/{testUtils/gameManager.ts => test-utils/game-manager.ts} (94%) rename test/{testUtils/gameWrapper.ts => test-utils/game-wrapper.ts} (92%) rename test/{testUtils/helpers/challengeModeHelper.ts => test-utils/helpers/challenge-mode-helper.ts} (95%) rename test/{testUtils/helpers/classicModeHelper.ts => test-utils/helpers/classic-mode-helper.ts} (96%) rename test/{testUtils/helpers/dailyModeHelper.ts => test-utils/helpers/daily-mode-helper.ts} (96%) rename test/{testUtils => test-utils}/helpers/field-helper.ts (98%) rename test/{testUtils/helpers/gameManagerHelper.ts => test-utils/helpers/game-manager-helper.ts} (75%) rename test/{testUtils/helpers/modifiersHelper.ts => test-utils/helpers/modifiers-helper.ts} (96%) rename test/{testUtils/helpers/moveHelper.ts => test-utils/helpers/move-helper.ts} (99%) rename test/{testUtils/helpers/overridesHelper.ts => test-utils/helpers/overrides-helper.ts} (99%) rename test/{testUtils/helpers/reloadHelper.ts => test-utils/helpers/reload-helper.ts} (95%) rename test/{testUtils/helpers/settingsHelper.ts => test-utils/helpers/settings-helper.ts} (94%) rename test/{testUtils/inputsHandler.ts => test-utils/inputs-handler.ts} (93%) rename test/{testUtils/listenersManager.ts => test-utils/listeners-manager.ts} (100%) rename test/{testUtils/mocks/mockClock.ts => test-utils/mocks/mock-clock.ts} (100%) rename test/{testUtils/mocks/mockConsoleLog.ts => test-utils/mocks/mock-console-log.ts} (100%) rename test/{testUtils/mocks/mockContextCanvas.ts => test-utils/mocks/mock-context-canvas.ts} (100%) rename test/{testUtils/mocks/mockFetch.ts => test-utils/mocks/mock-fetch.ts} (100%) rename test/{testUtils/mocks/mockGameObjectCreator.ts => test-utils/mocks/mock-game-object-creator.ts} (72%) rename test/{testUtils/mocks/mockGameObject.ts => test-utils/mocks/mock-game-object.ts} (100%) rename test/{testUtils/mocks/mockLoader.ts => test-utils/mocks/mock-loader.ts} (100%) rename test/{testUtils/mocks/mockLocalStorage.ts => test-utils/mocks/mock-local-storage.ts} (100%) rename test/{testUtils/mocks/mockTextureManager.ts => test-utils/mocks/mock-texture-manager.ts} (75%) rename test/{testUtils/mocks/mockTimedEventManager.ts => test-utils/mocks/mock-timed-event-manager.ts} (100%) rename test/{testUtils/mocks/mockVideoGameObject.ts => test-utils/mocks/mock-video-game-object.ts} (86%) rename test/{testUtils/mocks/mocksContainer => test-utils/mocks/mocks-container}/mock-bbcode-text.ts (68%) rename test/{testUtils/mocks/mocksContainer/mockContainer.ts => test-utils/mocks/mocks-container/mock-container.ts} (97%) rename test/{testUtils/mocks/mocksContainer/mockGraphics.ts => test-utils/mocks/mocks-container/mock-graphics.ts} (96%) rename test/{testUtils/mocks/mocksContainer/mockImage.ts => test-utils/mocks/mocks-container/mock-image.ts} (75%) rename test/{testUtils/mocks/mocksContainer => test-utils/mocks/mocks-container}/mock-input-text.ts (87%) rename test/{testUtils/mocks/mocksContainer/mockNineslice.ts => test-utils/mocks/mocks-container/mock-nineslice.ts} (85%) rename test/{testUtils/mocks/mocksContainer/mockPolygon.ts => test-utils/mocks/mocks-container/mock-polygon.ts} (64%) rename test/{testUtils/mocks/mocksContainer/mockRectangle.ts => test-utils/mocks/mocks-container/mock-rectangle.ts} (96%) rename test/{testUtils/mocks/mocksContainer/mockSprite.ts => test-utils/mocks/mocks-container/mock-sprite.ts} (98%) rename test/{testUtils/mocks/mocksContainer/mockText.ts => test-utils/mocks/mocks-container/mock-text.ts} (99%) rename test/{testUtils/mocks/mocksContainer/mockTexture.ts => test-utils/mocks/mocks-container/mock-texture.ts} (86%) rename test/{testUtils/phaseInterceptor.ts => test-utils/phase-interceptor.ts} (99%) rename test/{testUtils => test-utils}/saves/data_new.prsv (100%) rename test/{testUtils => test-utils}/saves/data_pokedex_tests.prsv (100%) rename test/{testUtils => test-utils}/saves/data_pokedex_tests_v2.prsv (100%) rename test/{testUtils => test-utils}/saves/everything.prsv (100%) rename test/{testUtils/testFileInitialization.ts => test-utils/test-file-initialization.ts} (90%) rename test/{testUtils/testUtils.ts => test-utils/test-utils.ts} (100%) rename test/{testUtils/TextInterceptor.ts => test-utils/text-interceptor.ts} (100%) rename test/ui/{battle_info.test.ts => battle-info.test.ts} (96%) diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 0b2e4c1a5da..82f5abd23a1 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -41,4 +41,7 @@ jobs: run: pnpm biome-ci - name: Check dependencies with depcruise - run: pnpm depcruise \ No newline at end of file + run: pnpm depcruise + + - name: Lint with ls-lint + run: pnpm ls-lint \ No newline at end of file diff --git a/.ls-lint.yml b/.ls-lint.yml new file mode 100644 index 00000000000..09d626af624 --- /dev/null +++ b/.ls-lint.yml @@ -0,0 +1,27 @@ +# Base settings to use +# Note that the `_cfg` key isn't part of ls-lint's configuration, it's just a YAML anchor for reuse. +_cfg: &cfg + .ps1: kebab-case + .ts: kebab-case + .js: kebab-case + .*.ts: kebab-case + .*.js: kebab-case + .dir: kebab-case + .py: snake_case # python files should always use snake_case + +ls: + <<: *cfg + src: + <<: *cfg + .dir: kebab-case | regex:@types + .js: exists:0 + src/system/version-migration/versions: + .ts: snake_case + <<: *cfg + +ignore: + - node_modules + - .vscode + - .github + - .git + - public diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7092b40b1b6..2d56b868cff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -104,7 +104,7 @@ Most non-trivial changes (*especially bug fixes*) should come along with new tes - Test edge cases. A good strategy is to think of edge cases beforehand and create tests for them using `it.todo`. Once the edge case has been handled, you can remove the `todo` marker. ## 😈 Development Save File -> Some issues may require you to have unlocks on your save file which go beyond normal overrides. For this reason, the repository contains a [save file](../test/testUtils/saves/everything.psrv) with _everything_ unlocked (even ones not legitimately obtainable, like unimplemented variant shinies). +> Some issues may require you to have unlocks on your save file which go beyond normal overrides. For this reason, the repository contains a [save file](../test/test-utils/saves/everything.psrv) with _everything_ unlocked (even ones not legitimately obtainable, like unimplemented variant shinies). 1. Start the game up locally and navigate to `Menu -> Manage Data -> Import Data` -2. Select [everything.prsv](test/testUtils/saves/everything.prsv) (`test/testUtils/saves/everything.prsv`) and confirm. +2. Select [everything.prsv](test/test-utils/saves/everything.prsv) (`test/test-utils/saves/everything.prsv`) and confirm. diff --git a/global.d.ts b/global.d.ts index d2ed6438c0b..27e96a4d8b5 100644 --- a/global.d.ts +++ b/global.d.ts @@ -8,7 +8,7 @@ declare global { * Can technically be undefined/null but for ease of use we are going to assume it is always defined. * Used to load i18n files exclusively. * - * To set up your own server in a test see `game_data.test.ts` + * To set up your own server in a test see `game-data.test.ts` */ var server: SetupServerApi; } diff --git a/lefthook.yml b/lefthook.yml index 40875073fdd..8b5ad2234ed 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -1,11 +1,13 @@ pre-commit: + skip: + - merge + - rebase commands: biome-lint: run: pnpm exec biome check --write --reporter=summary --staged --no-errors-on-unmatched stage_fixed: true - skip: - - merge - - rebase + ls-lint: + run: pnpm exec ls-lint post-merge: commands: diff --git a/package.json b/package.json index 64f2f9786db..85c95bcae3f 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ }, "devDependencies": { "@biomejs/biome": "2.0.0", + "@ls-lint/ls-lint": "2.3.1", "@types/jsdom": "^21.1.7", "@types/node": "^22.16.3", "@vitest/coverage-istanbul": "^3.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9f465c56778..e77bf065fd5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,6 +45,9 @@ importers: '@biomejs/biome': specifier: 2.0.0 version: 2.0.0 + '@ls-lint/ls-lint': + specifier: 2.3.1 + version: 2.3.1 '@types/jsdom': specifier: ^21.1.7 version: 21.1.7 @@ -565,6 +568,12 @@ packages: '@jridgewell/trace-mapping@0.3.29': resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} + '@ls-lint/ls-lint@2.3.1': + resolution: {integrity: sha512-vPe6IDByQnQRTxcAYjTxrmga/tSIui50VBFTB5KIJWY3OOFmxE2VtymjeSEfQfiMbhZV/ZPAqYy2lt8pZFQ0Rw==} + cpu: [x64, arm64, s390x, ppc64le] + os: [darwin, linux, win32] + hasBin: true + '@material/material-color-utilities@0.2.7': resolution: {integrity: sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==} @@ -2452,6 +2461,8 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.4 + '@ls-lint/ls-lint@2.3.1': {} + '@material/material-color-utilities@0.2.7': {} '@mswjs/interceptors@0.39.2': diff --git a/scripts/create-test/test-boilerplate.ts b/scripts/create-test/test-boilerplate.ts index 759f3afaec0..fa914b150c2 100644 --- a/scripts/create-test/test-boilerplate.ts +++ b/scripts/create-test/test-boilerplate.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/update_exp_sprites.ps1 b/scripts/update-exp-sprites.ps1 similarity index 100% rename from update_exp_sprites.ps1 rename to scripts/update-exp-sprites.ps1 diff --git a/public/update-source-comments.py b/scripts/update_source_comments.py similarity index 85% rename from public/update-source-comments.py rename to scripts/update_source_comments.py index 410d1a42566..465285fd4ac 100644 --- a/public/update-source-comments.py +++ b/scripts/update_source_comments.py @@ -2,13 +2,13 @@ import re filenames = [['src/enums/moves.ts', 'move'], ['src/enums/abilities.ts', 'ability'], ['src/enums/species.ts', 'Pokémon']] -commentBlockStart = re.compile('\/\*[^\*].*') # Regex for the start of a comment block -commentBlockEnd = re.compile('.*,\*\/') # Regex for the end of a comment block +commentBlockStart = re.compile(r'\/\*[^\*].*') # Regex for the start of a comment block +commentBlockEnd = re.compile(r'.*,\*\/') # Regex for the end of a comment block -commentExp = re.compile('(?:\/\*\*.*\*\/)') # Regex for a url comment that already existed in the file +commentExp = re.compile(r'(?:\/\*\*.*\*\/)') # Regex for a url comment that already existed in the file enumExp = re.compile('.*,') # Regex for a regular enum line -numberExp = re.compile(' +\= +\d+,') +numberExp = re.compile(r' +\= +\d+,') replaceList = ['ALOLA', 'ETERNAL', 'GALAR', 'HISUI', 'PALDEA', 'BLOODMOON'] diff --git a/src/@types/PokerogueAccountApi.ts b/src/@types/api/pokerogue-account-api.ts similarity index 85% rename from src/@types/PokerogueAccountApi.ts rename to src/@types/api/pokerogue-account-api.ts index 3b3e74ba41d..7bcdc766664 100644 --- a/src/@types/PokerogueAccountApi.ts +++ b/src/@types/api/pokerogue-account-api.ts @@ -1,4 +1,4 @@ -import type { UserInfo } from "#types/UserInfo"; +import type { UserInfo } from "#types/user-info"; export interface AccountInfoResponse extends UserInfo {} diff --git a/src/@types/PokerogueAdminApi.ts b/src/@types/api/pokerogue-admin-api.ts similarity index 100% rename from src/@types/PokerogueAdminApi.ts rename to src/@types/api/pokerogue-admin-api.ts diff --git a/src/@types/PokerogueApi.ts b/src/@types/api/pokerogue-api-types.ts similarity index 100% rename from src/@types/PokerogueApi.ts rename to src/@types/api/pokerogue-api-types.ts diff --git a/src/@types/PokerogueDailyApi.ts b/src/@types/api/pokerogue-daily-api.ts similarity index 100% rename from src/@types/PokerogueDailyApi.ts rename to src/@types/api/pokerogue-daily-api.ts diff --git a/src/@types/PokerogueSavedataApi.ts b/src/@types/api/pokerogue-save-data-api.ts similarity index 100% rename from src/@types/PokerogueSavedataApi.ts rename to src/@types/api/pokerogue-save-data-api.ts diff --git a/src/@types/PokerogueSessionSavedataApi.ts b/src/@types/api/pokerogue-session-save-data-api.ts similarity index 95% rename from src/@types/PokerogueSessionSavedataApi.ts rename to src/@types/api/pokerogue-session-save-data-api.ts index c4650611c4f..bd606ef7e9c 100644 --- a/src/@types/PokerogueSessionSavedataApi.ts +++ b/src/@types/api/pokerogue-session-save-data-api.ts @@ -1,4 +1,4 @@ -export class UpdateSessionSavedataRequest { +export interface UpdateSessionSavedataRequest { slot: number; trainerId: number; secretId: number; diff --git a/src/@types/PokerogueSystemSavedataApi.ts b/src/@types/api/pokerogue-system-save-data-api.ts similarity index 88% rename from src/@types/PokerogueSystemSavedataApi.ts rename to src/@types/api/pokerogue-system-save-data-api.ts index ded22c4c58c..133f9cda506 100644 --- a/src/@types/PokerogueSystemSavedataApi.ts +++ b/src/@types/api/pokerogue-system-save-data-api.ts @@ -4,7 +4,7 @@ export interface GetSystemSavedataRequest { clientSessionId: string; } -export class UpdateSystemSavedataRequest { +export interface UpdateSystemSavedataRequest { clientSessionId: string; trainerId?: number; secretId?: number; diff --git a/src/@types/SessionSaveMigrator.ts b/src/@types/session-save-migrator.ts similarity index 100% rename from src/@types/SessionSaveMigrator.ts rename to src/@types/session-save-migrator.ts diff --git a/src/@types/SettingsSaveMigrator.ts b/src/@types/settings-save-migrator.ts similarity index 100% rename from src/@types/SettingsSaveMigrator.ts rename to src/@types/settings-save-migrator.ts diff --git a/src/@types/SystemSaveMigrator.ts b/src/@types/system-save-migrator.ts similarity index 100% rename from src/@types/SystemSaveMigrator.ts rename to src/@types/system-save-migrator.ts diff --git a/src/@types/UserInfo.ts b/src/@types/user-info.ts similarity index 100% rename from src/@types/UserInfo.ts rename to src/@types/user-info.ts diff --git a/src/account.ts b/src/account.ts index 1bfb756b284..b01691ce940 100644 --- a/src/account.ts +++ b/src/account.ts @@ -1,6 +1,6 @@ import { pokerogueApi } from "#api/pokerogue-api"; import { bypassLogin } from "#app/global-vars/bypass-login"; -import type { UserInfo } from "#types/UserInfo"; +import type { UserInfo } from "#types/user-info"; import { randomString } from "#utils/common"; export let loggedInUser: UserInfo | null = null; diff --git a/src/configs/inputs/cfg_keyboard_qwerty.ts b/src/configs/inputs/cfg-keyboard-qwerty.ts similarity index 100% rename from src/configs/inputs/cfg_keyboard_qwerty.ts rename to src/configs/inputs/cfg-keyboard-qwerty.ts diff --git a/src/configs/inputs/configHandler.ts b/src/configs/inputs/config-handler.ts similarity index 100% rename from src/configs/inputs/configHandler.ts rename to src/configs/inputs/config-handler.ts diff --git a/src/configs/inputs/pad_dualshock.ts b/src/configs/inputs/pad-dualshock.ts similarity index 100% rename from src/configs/inputs/pad_dualshock.ts rename to src/configs/inputs/pad-dualshock.ts diff --git a/src/configs/inputs/pad_generic.ts b/src/configs/inputs/pad-generic.ts similarity index 100% rename from src/configs/inputs/pad_generic.ts rename to src/configs/inputs/pad-generic.ts diff --git a/src/configs/inputs/pad_procon.ts b/src/configs/inputs/pad-procon.ts similarity index 100% rename from src/configs/inputs/pad_procon.ts rename to src/configs/inputs/pad-procon.ts diff --git a/src/configs/inputs/pad_unlicensedSNES.ts b/src/configs/inputs/pad-unlicensed-snes.ts similarity index 100% rename from src/configs/inputs/pad_unlicensedSNES.ts rename to src/configs/inputs/pad-unlicensed-snes.ts diff --git a/src/configs/inputs/pad_xbox360.ts b/src/configs/inputs/pad-xbox360.ts similarity index 100% rename from src/configs/inputs/pad_xbox360.ts rename to src/configs/inputs/pad-xbox360.ts diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index 30f6f6fb8b2..62d6974d3a2 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -28,12 +28,12 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import type { BerryType } from "#enums/berry-type"; import { Command } from "#enums/command"; import { HitResult } from "#enums/hit-result"; -import { MoveCategory } from "#enums/MoveCategory"; -import { MoveFlags } from "#enums/MoveFlags"; -import { MoveTarget } from "#enums/MoveTarget"; import { CommonAnim } from "#enums/move-anims-common"; +import { MoveCategory } from "#enums/move-category"; +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 { MoveUseMode } from "#enums/move-use-mode"; import { PokemonAnimType } from "#enums/pokemon-anim-type"; import { PokemonType } from "#enums/pokemon-type"; diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index 2d49e7011af..2c4c8a04282 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -9,10 +9,10 @@ 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 { MoveCategory } from "#enums/MoveCategory"; -import { MoveTarget } from "#enums/MoveTarget"; 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"; diff --git a/src/data/battle-anims.ts b/src/data/battle-anims.ts index d26f0700f7f..0dc8bf4850c 100644 --- a/src/data/battle-anims.ts +++ b/src/data/battle-anims.ts @@ -3,8 +3,8 @@ import { allMoves } from "#data/data-lists"; import type { BattlerIndex } from "#enums/battler-index"; import { BattlerTagType } from "#enums/battler-tag-type"; import { EncounterAnim } from "#enums/encounter-anims"; -import { MoveFlags } from "#enums/MoveFlags"; import { AnimBlendType, AnimFocus, AnimFrameTarget, ChargeAnim, CommonAnim } from "#enums/move-anims-common"; +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"; diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 060b17e889b..c8ddfe32f0b 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -11,9 +11,9 @@ import { AbilityId } from "#enums/ability-id"; import { BattlerTagLapseType } from "#enums/battler-tag-lapse-type"; import { BattlerTagType } from "#enums/battler-tag-type"; import { HitResult } from "#enums/hit-result"; -import { MoveCategory } from "#enums/MoveCategory"; -import { MoveFlags } from "#enums/MoveFlags"; import { ChargeAnim, CommonAnim } from "#enums/move-anims-common"; +import { MoveCategory } from "#enums/move-category"; +import { MoveFlags } from "#enums/move-flags"; import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { MoveUseMode } from "#enums/move-use-mode"; diff --git a/src/data/moves/move-utils.ts b/src/data/moves/move-utils.ts index 39891f595aa..a0baf7ff9b7 100644 --- a/src/data/moves/move-utils.ts +++ b/src/data/moves/move-utils.ts @@ -1,8 +1,8 @@ import { allMoves } from "#data/data-lists"; import type { BattlerIndex } from "#enums/battler-index"; import { BattlerTagType } from "#enums/battler-tag-type"; -import { MoveTarget } from "#enums/MoveTarget"; import type { MoveId } from "#enums/move-id"; +import { MoveTarget } from "#enums/move-target"; import { PokemonType } from "#enums/pokemon-type"; import type { Pokemon } from "#field/pokemon"; import { applyMoveAttrs } from "#moves/apply-attrs"; diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index d8863016002..379b474e7e5 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -48,11 +48,11 @@ import { ChargeAnim } from "#enums/move-anims-common"; import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { isVirtual, MoveUseMode } from "#enums/move-use-mode"; -import { MoveCategory } from "#enums/MoveCategory"; -import { MoveEffectTrigger } from "#enums/MoveEffectTrigger"; -import { MoveFlags } from "#enums/MoveFlags"; -import { MoveTarget } from "#enums/MoveTarget"; -import { MultiHitType } from "#enums/MultiHitType"; +import { MoveCategory } from "#enums/move-category"; +import { MoveEffectTrigger } from "#enums/move-effect-trigger"; +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 { SpeciesId } from "#enums/species-id"; import { diff --git a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts index 1c3335b859f..1c85cb7595c 100644 --- a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts +++ b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts @@ -8,9 +8,9 @@ import { BattlerIndex } from "#enums/battler-index"; import { BerryType } from "#enums/berry-type"; import { Challenges } from "#enums/challenges"; import { EncounterAnim } from "#enums/encounter-anims"; -import { MoveCategory } from "#enums/MoveCategory"; import { ModifierPoolType } from "#enums/modifier-pool-type"; import { ModifierTier } from "#enums/modifier-tier"; +import { MoveCategory } from "#enums/move-category"; import { MoveId } from "#enums/move-id"; import { MoveUseMode } from "#enums/move-use-mode"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; diff --git a/src/data/mystery-encounters/encounters/field-trip-encounter.ts b/src/data/mystery-encounters/encounters/field-trip-encounter.ts index 84374c87e58..9c655e70b8c 100644 --- a/src/data/mystery-encounters/encounters/field-trip-encounter.ts +++ b/src/data/mystery-encounters/encounters/field-trip-encounter.ts @@ -1,7 +1,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants"; import { globalScene } from "#app/global-scene"; import { modifierTypes } from "#data/data-lists"; -import { MoveCategory } from "#enums/MoveCategory"; +import { MoveCategory } from "#enums/move-category"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; diff --git a/src/data/pokemon-forms.ts b/src/data/pokemon-forms.ts index 6d1db296e55..5a50713c5a9 100644 --- a/src/data/pokemon-forms.ts +++ b/src/data/pokemon-forms.ts @@ -18,7 +18,7 @@ import { } from "#data/form-change-triggers"; import { AbilityId } from "#enums/ability-id"; import { FormChangeItem } from "#enums/form-change-item"; -import { MoveCategory } from "#enums/MoveCategory"; +import { MoveCategory } from "#enums/move-category"; import { MoveId } from "#enums/move-id"; import { SpeciesFormKey } from "#enums/species-form-key"; import { SpeciesId } from "#enums/species-id"; diff --git a/src/enums/MoveCategory.ts b/src/enums/move-category.ts similarity index 100% rename from src/enums/MoveCategory.ts rename to src/enums/move-category.ts diff --git a/src/enums/MoveEffectTrigger.ts b/src/enums/move-effect-trigger.ts similarity index 100% rename from src/enums/MoveEffectTrigger.ts rename to src/enums/move-effect-trigger.ts diff --git a/src/enums/MoveFlags.ts b/src/enums/move-flags.ts similarity index 100% rename from src/enums/MoveFlags.ts rename to src/enums/move-flags.ts diff --git a/src/enums/MoveTarget.ts b/src/enums/move-target.ts similarity index 100% rename from src/enums/MoveTarget.ts rename to src/enums/move-target.ts diff --git a/src/enums/MultiHitType.ts b/src/enums/multi-hit-type.ts similarity index 100% rename from src/enums/MultiHitType.ts rename to src/enums/multi-hit-type.ts diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 01f137b28fd..32edd721cd9 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -82,11 +82,11 @@ import { DexAttr } from "#enums/dex-attr"; import { FieldPosition } from "#enums/field-position"; import { HitResult } from "#enums/hit-result"; import { LearnMoveSituation } from "#enums/learn-move-situation"; -import { MoveCategory } from "#enums/MoveCategory"; -import { MoveFlags } from "#enums/MoveFlags"; -import { MoveTarget } from "#enums/MoveTarget"; import { ModifierTier } from "#enums/modifier-tier"; +import { MoveCategory } from "#enums/move-category"; +import { MoveFlags } from "#enums/move-flags"; import { MoveId } from "#enums/move-id"; +import { MoveTarget } from "#enums/move-target"; import { isIgnorePP, isVirtual, MoveUseMode } from "#enums/move-use-mode"; import { Nature } from "#enums/nature"; import { PokeballType } from "#enums/pokeball"; diff --git a/src/inputs-controller.ts b/src/inputs-controller.ts index 1607e4ee74f..03d2278f26c 100644 --- a/src/inputs-controller.ts +++ b/src/inputs-controller.ts @@ -3,13 +3,13 @@ import { TouchControl } from "#app/touch-controls"; import { Button } from "#enums/buttons"; import { Device } from "#enums/devices"; import { UiMode } from "#enums/ui-mode"; -import cfg_keyboard_qwerty from "#inputs/cfg_keyboard_qwerty"; -import { assign, getButtonWithKeycode, getIconForLatestInput, swap } from "#inputs/configHandler"; -import pad_dualshock from "#inputs/pad_dualshock"; -import pad_generic from "#inputs/pad_generic"; -import pad_procon from "#inputs/pad_procon"; -import pad_unlicensedSNES from "#inputs/pad_unlicensedSNES"; -import pad_xbox360 from "#inputs/pad_xbox360"; +import cfg_keyboard_qwerty from "#inputs/cfg-keyboard-qwerty"; +import { assign, getButtonWithKeycode, getIconForLatestInput, swap } from "#inputs/config-handler"; +import pad_dualshock from "#inputs/pad-dualshock"; +import pad_generic from "#inputs/pad-generic"; +import pad_procon from "#inputs/pad-procon"; +import pad_unlicensedSNES from "#inputs/pad-unlicensed-snes"; +import pad_xbox360 from "#inputs/pad-xbox360"; import type { SettingGamepad } from "#system/settings-gamepad"; import type { SettingKeyboard } from "#system/settings-keyboard"; import { MoveTouchControlsHandler } from "#ui/move-touch-controls-handler"; diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index 4446b2071d0..b1cb9e48d51 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -13,12 +13,12 @@ import { BattlerTagLapseType } from "#enums/battler-tag-lapse-type"; import { BattlerTagType } from "#enums/battler-tag-type"; import { HitCheckResult } from "#enums/hit-check-result"; import { HitResult } from "#enums/hit-result"; -import { MoveCategory } from "#enums/MoveCategory"; -import { MoveEffectTrigger } from "#enums/MoveEffectTrigger"; -import { MoveFlags } from "#enums/MoveFlags"; -import { MoveTarget } from "#enums/MoveTarget"; +import { MoveCategory } from "#enums/move-category"; +import { MoveEffectTrigger } from "#enums/move-effect-trigger"; +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 { PokemonType } from "#enums/pokemon-type"; import type { Pokemon } from "#field/pokemon"; diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index 09a542861be..82bb6b153ef 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -13,8 +13,8 @@ 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"; -import { MoveFlags } from "#enums/MoveFlags"; import { CommonAnim } from "#enums/move-anims-common"; +import { MoveFlags } from "#enums/move-flags"; import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { isIgnorePP, isIgnoreStatus, isReflected, isVirtual, MoveUseMode } from "#enums/move-use-mode"; diff --git a/src/pipelines/field-sprite.ts b/src/pipelines/field-sprite.ts index 647483d1524..b20bacf6a5e 100644 --- a/src/pipelines/field-sprite.ts +++ b/src/pipelines/field-sprite.ts @@ -2,8 +2,8 @@ import { globalScene } from "#app/global-scene"; import { getTerrainColor, TerrainType } from "#data/terrain"; import { getCurrentTime } from "#utils/common"; import Phaser from "phaser"; -import fieldSpriteFragShader from "./glsl/fieldSpriteFragShader.frag?raw"; -import spriteVertShader from "./glsl/spriteShader.vert?raw"; +import fieldSpriteFragShader from "./glsl/field-sprite-frag-shader.frag?raw"; +import spriteVertShader from "./glsl/sprite-shader.vert?raw"; export class FieldSpritePipeline extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline { constructor(game: Phaser.Game, config?: Phaser.Types.Renderer.WebGL.WebGLPipelineConfig) { diff --git a/src/pipelines/glsl/fieldSpriteFragShader.frag b/src/pipelines/glsl/field-sprite-frag-shader.frag similarity index 100% rename from src/pipelines/glsl/fieldSpriteFragShader.frag rename to src/pipelines/glsl/field-sprite-frag-shader.frag diff --git a/src/pipelines/glsl/spriteFragShader.frag b/src/pipelines/glsl/sprite-frag-shader.frag similarity index 100% rename from src/pipelines/glsl/spriteFragShader.frag rename to src/pipelines/glsl/sprite-frag-shader.frag diff --git a/src/pipelines/glsl/spriteShader.vert b/src/pipelines/glsl/sprite-shader.vert similarity index 100% rename from src/pipelines/glsl/spriteShader.vert rename to src/pipelines/glsl/sprite-shader.vert diff --git a/src/pipelines/sprite.ts b/src/pipelines/sprite.ts index 596a761b05f..8d38eda562d 100644 --- a/src/pipelines/sprite.ts +++ b/src/pipelines/sprite.ts @@ -5,8 +5,8 @@ import { Pokemon } from "#field/pokemon"; import { Trainer } from "#field/trainer"; import { variantColorCache } from "#sprites/variant"; import { rgbHexToRgba } from "#utils/common"; -import spriteFragShader from "./glsl/spriteFragShader.frag?raw"; -import spriteVertShader from "./glsl/spriteShader.vert?raw"; +import spriteFragShader from "./glsl/sprite-frag-shader.frag?raw"; +import spriteVertShader from "./glsl/sprite-shader.vert?raw"; export class SpritePipeline extends FieldSpritePipeline { private _tone: number[]; diff --git a/src/plugins/api/pokerogue-account-api.ts b/src/plugins/api/pokerogue-account-api.ts index 56bdc92b9b9..03f522e8dac 100644 --- a/src/plugins/api/pokerogue-account-api.ts +++ b/src/plugins/api/pokerogue-account-api.ts @@ -5,7 +5,7 @@ import type { AccountLoginRequest, AccountLoginResponse, AccountRegisterRequest, -} from "#types/PokerogueAccountApi"; +} from "#types/api/pokerogue-account-api"; import { removeCookie, setCookie } from "#utils/cookies"; /** diff --git a/src/plugins/api/pokerogue-admin-api.ts b/src/plugins/api/pokerogue-admin-api.ts index 4e549c7ff53..7ce4cf8b973 100644 --- a/src/plugins/api/pokerogue-admin-api.ts +++ b/src/plugins/api/pokerogue-admin-api.ts @@ -6,7 +6,7 @@ import type { SearchAccountResponse, UnlinkAccountFromDiscordIdRequest, UnlinkAccountFromGoogledIdRequest, -} from "#types/PokerogueAdminApi"; +} from "#types/api/pokerogue-admin-api"; export class PokerogueAdminApi extends ApiBase { public readonly ERR_USERNAME_NOT_FOUND: string = "Username not found!"; diff --git a/src/plugins/api/pokerogue-api.ts b/src/plugins/api/pokerogue-api.ts index 99600a359a2..ce232685107 100644 --- a/src/plugins/api/pokerogue-api.ts +++ b/src/plugins/api/pokerogue-api.ts @@ -3,7 +3,7 @@ import { PokerogueAccountApi } from "#api/pokerogue-account-api"; import { PokerogueAdminApi } from "#api/pokerogue-admin-api"; import { PokerogueDailyApi } from "#api/pokerogue-daily-api"; import { PokerogueSavedataApi } from "#api/pokerogue-savedata-api"; -import type { TitleStatsResponse } from "#types/PokerogueApi"; +import type { TitleStatsResponse } from "#types/api/pokerogue-api-types"; /** * A wrapper for PokéRogue API requests. diff --git a/src/plugins/api/pokerogue-daily-api.ts b/src/plugins/api/pokerogue-daily-api.ts index 2913c7bd4f2..5ea3846e60e 100644 --- a/src/plugins/api/pokerogue-daily-api.ts +++ b/src/plugins/api/pokerogue-daily-api.ts @@ -1,5 +1,5 @@ import { ApiBase } from "#api/api-base"; -import type { GetDailyRankingsPageCountRequest, GetDailyRankingsRequest } from "#types/PokerogueDailyApi"; +import type { GetDailyRankingsPageCountRequest, GetDailyRankingsRequest } from "#types/api/pokerogue-daily-api"; import type { RankingEntry } from "#ui/daily-run-scoreboard"; /** diff --git a/src/plugins/api/pokerogue-savedata-api.ts b/src/plugins/api/pokerogue-savedata-api.ts index bc77de8060b..f91e7bd027f 100644 --- a/src/plugins/api/pokerogue-savedata-api.ts +++ b/src/plugins/api/pokerogue-savedata-api.ts @@ -2,7 +2,7 @@ import { ApiBase } from "#api/api-base"; import { PokerogueSessionSavedataApi } from "#api/pokerogue-session-savedata-api"; import { PokerogueSystemSavedataApi } from "#api/pokerogue-system-savedata-api"; import { MAX_INT_ATTR_VALUE } from "#app/constants"; -import type { UpdateAllSavedataRequest } from "#types/PokerogueSavedataApi"; +import type { UpdateAllSavedataRequest } from "#types/api/pokerogue-save-data-api"; /** * A wrapper for PokéRogue savedata API requests. diff --git a/src/plugins/api/pokerogue-session-savedata-api.ts b/src/plugins/api/pokerogue-session-savedata-api.ts index a807d4b712c..4ffb0a5d8da 100644 --- a/src/plugins/api/pokerogue-session-savedata-api.ts +++ b/src/plugins/api/pokerogue-session-savedata-api.ts @@ -7,7 +7,7 @@ import type { GetSessionSavedataRequest, NewClearSessionSavedataRequest, UpdateSessionSavedataRequest, -} from "#types/PokerogueSessionSavedataApi"; +} from "#types/api/pokerogue-session-save-data-api"; /** * A wrapper for PokéRogue session savedata API requests. diff --git a/src/plugins/api/pokerogue-system-savedata-api.ts b/src/plugins/api/pokerogue-system-savedata-api.ts index f87aba81ee9..137d4adb18f 100644 --- a/src/plugins/api/pokerogue-system-savedata-api.ts +++ b/src/plugins/api/pokerogue-system-savedata-api.ts @@ -4,7 +4,7 @@ import type { UpdateSystemSavedataRequest, VerifySystemSavedataRequest, VerifySystemSavedataResponse, -} from "#types/PokerogueSystemSavedataApi"; +} from "#types/api/pokerogue-system-save-data-api"; /** * A wrapper for PokéRogue system savedata API requests. diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 4f251b212b1..c52a5155fb4 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -57,7 +57,7 @@ import { applySessionVersionMigration, applySettingsVersionMigration, applySystemVersionMigration, -} from "#system/version_converter"; +} from "#system/version-migration/version-converter"; import { VoucherType, vouchers } from "#system/voucher"; import { trainerConfigs } from "#trainers/trainer-config"; import type { DexData, DexEntry } from "#types/dex-data"; diff --git a/src/system/version_migration/version_converter.ts b/src/system/version-migration/version-converter.ts similarity index 91% rename from src/system/version_migration/version_converter.ts rename to src/system/version-migration/version-converter.ts index c49490da756..6dde611ce84 100644 --- a/src/system/version_migration/version_converter.ts +++ b/src/system/version-migration/version-converter.ts @@ -2,9 +2,9 @@ import { version } from "#package.json"; import type { SessionSaveData, SystemSaveData } from "#system/game-data"; -import type { SessionSaveMigrator } from "#types/SessionSaveMigrator"; -import type { SettingsSaveMigrator } from "#types/SettingsSaveMigrator"; -import type { SystemSaveMigrator } from "#types/SystemSaveMigrator"; +import type { SessionSaveMigrator } from "#types/session-save-migrator"; +import type { SettingsSaveMigrator } from "#types/settings-save-migrator"; +import type { SystemSaveMigrator } from "#types/system-save-migrator"; import { compareVersions } from "compare-versions"; /* @@ -49,11 +49,11 @@ export const settingsMigrators: readonly SettingsSaveMigrator[] = [settingsMigra // Add migrator imports below: // Example: import * as vA_B_C from "#system/vA_B_C"; -import * as v1_0_4 from "#system/v1_0_4"; -import * as v1_7_0 from "#system/v1_7_0"; -import * as v1_8_3 from "#system/v1_8_3"; -import * as v1_9_0 from "#system/v1_9_0"; -import * as v1_10_0 from "#system/v1_10_0"; +import * as v1_0_4 from "#system/version-migration/versions/v1_0_4"; +import * as v1_7_0 from "#system/version-migration/versions/v1_7_0"; +import * as v1_8_3 from "#system/version-migration/versions/v1_8_3"; +import * as v1_9_0 from "#system/version-migration/versions/v1_9_0"; +import * as v1_10_0 from "#system/version-migration/versions/v1_10_0"; /** Current game version */ const LATEST_VERSION = version; diff --git a/src/system/version_migration/versions/v1_0_4.ts b/src/system/version-migration/versions/v1_0_4.ts similarity index 97% rename from src/system/version_migration/versions/v1_0_4.ts rename to src/system/version-migration/versions/v1_0_4.ts index 3523a5b8826..2c50e05d40f 100644 --- a/src/system/version_migration/versions/v1_0_4.ts +++ b/src/system/version-migration/versions/v1_0_4.ts @@ -5,9 +5,9 @@ import { AbilityAttr } from "#enums/ability-attr"; import { DexAttr } from "#enums/dex-attr"; import type { SessionSaveData, SystemSaveData } from "#system/game-data"; import { SettingKeys } from "#system/settings"; -import type { SessionSaveMigrator } from "#types/SessionSaveMigrator"; -import type { SettingsSaveMigrator } from "#types/SettingsSaveMigrator"; -import type { SystemSaveMigrator } from "#types/SystemSaveMigrator"; +import type { SessionSaveMigrator } from "#types/session-save-migrator"; +import type { SettingsSaveMigrator } from "#types/settings-save-migrator"; +import type { SystemSaveMigrator } from "#types/system-save-migrator"; import { isNullOrUndefined } from "#utils/common"; /** diff --git a/src/system/version_migration/versions/v1_10_0.ts b/src/system/version-migration/versions/v1_10_0.ts similarity index 96% rename from src/system/version_migration/versions/v1_10_0.ts rename to src/system/version-migration/versions/v1_10_0.ts index 66436717639..5c13acd4508 100644 --- a/src/system/version_migration/versions/v1_10_0.ts +++ b/src/system/version-migration/versions/v1_10_0.ts @@ -3,7 +3,7 @@ import type { MoveId } from "#enums/move-id"; import type { MoveResult } from "#enums/move-result"; import { MoveUseMode } from "#enums/move-use-mode"; import type { SessionSaveData } from "#system/game-data"; -import type { SessionSaveMigrator } from "#types/SessionSaveMigrator"; +import type { SessionSaveMigrator } from "#types/session-save-migrator"; import type { TurnMove } from "#types/turn-move"; /** Prior signature of `TurnMove`; used to ensure parity */ diff --git a/src/system/version_migration/versions/v1_7_0.ts b/src/system/version-migration/versions/v1_7_0.ts similarity index 95% rename from src/system/version_migration/versions/v1_7_0.ts rename to src/system/version-migration/versions/v1_7_0.ts index 8f757456d0a..9ba25bcbaac 100644 --- a/src/system/version_migration/versions/v1_7_0.ts +++ b/src/system/version-migration/versions/v1_7_0.ts @@ -2,8 +2,8 @@ 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/SessionSaveMigrator"; -import type { SystemSaveMigrator } from "#types/SystemSaveMigrator"; +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"; diff --git a/src/system/version_migration/versions/v1_8_3.ts b/src/system/version-migration/versions/v1_8_3.ts similarity index 94% rename from src/system/version_migration/versions/v1_8_3.ts rename to src/system/version-migration/versions/v1_8_3.ts index e6b5129d9d5..4907b4e5e57 100644 --- a/src/system/version_migration/versions/v1_8_3.ts +++ b/src/system/version-migration/versions/v1_8_3.ts @@ -1,7 +1,7 @@ import { DexAttr } from "#enums/dex-attr"; import { SpeciesId } from "#enums/species-id"; import type { SystemSaveData } from "#system/game-data"; -import type { SystemSaveMigrator } from "#types/SystemSaveMigrator"; +import type { SystemSaveMigrator } from "#types/system-save-migrator"; import { getPokemonSpecies } from "#utils/pokemon-utils"; /** diff --git a/src/system/version_migration/versions/v1_9_0.ts b/src/system/version-migration/versions/v1_9_0.ts similarity index 95% rename from src/system/version_migration/versions/v1_9_0.ts rename to src/system/version-migration/versions/v1_9_0.ts index 80da5f2996b..fb24b9af837 100644 --- a/src/system/version_migration/versions/v1_9_0.ts +++ b/src/system/version-migration/versions/v1_9_0.ts @@ -2,7 +2,7 @@ import { MoveId } from "#enums/move-id"; import { PokemonMove } from "#moves/pokemon-move"; import type { SessionSaveData } from "#system/game-data"; import type { PokemonData } from "#system/pokemon-data"; -import type { SessionSaveMigrator } from "#types/SessionSaveMigrator"; +import type { SessionSaveMigrator } from "#types/session-save-migrator"; /** * Migrate all lingering rage fist data inside `CustomPokemonData`, diff --git a/src/@types/i18next.d.ts b/src/typings/i18next.d.ts similarity index 100% rename from src/@types/i18next.d.ts rename to src/typings/i18next.d.ts diff --git a/src/ui/fight-ui-handler.ts b/src/ui/fight-ui-handler.ts index 9c08991e063..286199b99e2 100644 --- a/src/ui/fight-ui-handler.ts +++ b/src/ui/fight-ui-handler.ts @@ -4,7 +4,7 @@ import { getTypeDamageMultiplierColor } from "#data/type"; import { BattleType } from "#enums/battle-type"; import { Button } from "#enums/buttons"; import { Command } from "#enums/command"; -import { MoveCategory } from "#enums/MoveCategory"; +import { MoveCategory } from "#enums/move-category"; import { MoveUseMode } from "#enums/move-use-mode"; import { PokemonType } from "#enums/pokemon-type"; import { UiMode } from "#enums/ui-mode"; diff --git a/src/ui/move-info-overlay.ts b/src/ui/move-info-overlay.ts index 1747021b7ec..7720354a5b3 100644 --- a/src/ui/move-info-overlay.ts +++ b/src/ui/move-info-overlay.ts @@ -1,6 +1,6 @@ import type { InfoToggle } from "#app/battle-scene"; import { globalScene } from "#app/global-scene"; -import { MoveCategory } from "#enums/MoveCategory"; +import { MoveCategory } from "#enums/move-category"; import { PokemonType } from "#enums/pokemon-type"; import type { Move } from "#moves/move"; import { addTextObject, TextStyle } from "#ui/text"; diff --git a/src/ui/settings/abstract-binding-ui-handler.ts b/src/ui/settings/abstract-binding-ui-handler.ts index aaf3572b489..7004af8c4ed 100644 --- a/src/ui/settings/abstract-binding-ui-handler.ts +++ b/src/ui/settings/abstract-binding-ui-handler.ts @@ -1,7 +1,7 @@ import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; import type { UiMode } from "#enums/ui-mode"; -import { NavigationManager } from "#ui/navigationMenu"; +import { NavigationManager } from "#ui/navigation-menu"; import { addTextObject, TextStyle } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; diff --git a/src/ui/settings/abstract-control-settings-ui-handler.ts b/src/ui/settings/abstract-control-settings-ui-handler.ts index 67cc3ad7c03..64786849abc 100644 --- a/src/ui/settings/abstract-control-settings-ui-handler.ts +++ b/src/ui/settings/abstract-control-settings-ui-handler.ts @@ -3,8 +3,8 @@ import type { InterfaceConfig } from "#app/inputs-controller"; import { Button } from "#enums/buttons"; import type { Device } from "#enums/devices"; import type { UiMode } from "#enums/ui-mode"; -import { getIconWithSettingName } from "#inputs/configHandler"; -import { NavigationManager, NavigationMenu } from "#ui/navigationMenu"; +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 { UiHandler } from "#ui/ui-handler"; diff --git a/src/ui/settings/abstract-settings-ui-handler.ts b/src/ui/settings/abstract-settings-ui-handler.ts index 303ad229ea6..9e56ae80b14 100644 --- a/src/ui/settings/abstract-settings-ui-handler.ts +++ b/src/ui/settings/abstract-settings-ui-handler.ts @@ -5,7 +5,7 @@ import type { SettingType } from "#system/settings"; import { Setting, SettingKeys } from "#system/settings"; import type { InputsIcons } from "#ui/abstract-control-settings-ui-handler"; import { MessageUiHandler } from "#ui/message-ui-handler"; -import { NavigationManager, NavigationMenu } from "#ui/navigationMenu"; +import { NavigationManager, NavigationMenu } from "#ui/navigation-menu"; import { ScrollBar } from "#ui/scroll-bar"; import { addTextObject, TextStyle } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; diff --git a/src/ui/settings/gamepad-binding-ui-handler.ts b/src/ui/settings/gamepad-binding-ui-handler.ts index c514e93ec51..e97fc56d7c0 100644 --- a/src/ui/settings/gamepad-binding-ui-handler.ts +++ b/src/ui/settings/gamepad-binding-ui-handler.ts @@ -1,7 +1,7 @@ import { globalScene } from "#app/global-scene"; import { Device } from "#enums/devices"; import type { UiMode } from "#enums/ui-mode"; -import { getIconWithSettingName, getKeyWithKeycode } from "#inputs/configHandler"; +import { getIconWithSettingName, getKeyWithKeycode } from "#inputs/config-handler"; import { AbstractBindingUiHandler } from "#ui/abstract-binding-ui-handler"; import { addTextObject, TextStyle } from "#ui/text"; import i18next from "i18next"; diff --git a/src/ui/settings/keyboard-binding-ui-handler.ts b/src/ui/settings/keyboard-binding-ui-handler.ts index a789225a8ef..e43184795d1 100644 --- a/src/ui/settings/keyboard-binding-ui-handler.ts +++ b/src/ui/settings/keyboard-binding-ui-handler.ts @@ -1,7 +1,7 @@ import { globalScene } from "#app/global-scene"; import { Device } from "#enums/devices"; import type { UiMode } from "#enums/ui-mode"; -import { getKeyWithKeycode } from "#inputs/configHandler"; +import { getKeyWithKeycode } from "#inputs/config-handler"; import { AbstractBindingUiHandler } from "#ui/abstract-binding-ui-handler"; import { addTextObject, TextStyle } from "#ui/text"; import i18next from "i18next"; diff --git a/src/ui/settings/navigationMenu.ts b/src/ui/settings/navigation-menu.ts similarity index 100% rename from src/ui/settings/navigationMenu.ts rename to src/ui/settings/navigation-menu.ts diff --git a/src/ui/settings/settings-gamepad-ui-handler.ts b/src/ui/settings/settings-gamepad-ui-handler.ts index 63dd4c74618..ea2e18a2ce6 100644 --- a/src/ui/settings/settings-gamepad-ui-handler.ts +++ b/src/ui/settings/settings-gamepad-ui-handler.ts @@ -2,9 +2,9 @@ import { globalScene } from "#app/global-scene"; import type { InterfaceConfig } from "#app/inputs-controller"; import { Device } from "#enums/devices"; import type { UiMode } from "#enums/ui-mode"; -import pad_dualshock from "#inputs/pad_dualshock"; -import pad_unlicensedSNES from "#inputs/pad_unlicensedSNES"; -import pad_xbox360 from "#inputs/pad_xbox360"; +import pad_dualshock from "#inputs/pad-dualshock"; +import pad_unlicensedSNES from "#inputs/pad-unlicensed-snes"; +import pad_xbox360 from "#inputs/pad-xbox360"; import { SettingGamepad, setSettingGamepad, diff --git a/src/ui/settings/settings-keyboard-ui-handler.ts b/src/ui/settings/settings-keyboard-ui-handler.ts index 581e3e938be..2c2e0dbd7cd 100644 --- a/src/ui/settings/settings-keyboard-ui-handler.ts +++ b/src/ui/settings/settings-keyboard-ui-handler.ts @@ -2,8 +2,8 @@ import { globalScene } from "#app/global-scene"; import type { InterfaceConfig } from "#app/inputs-controller"; import { Device } from "#enums/devices"; import { UiMode } from "#enums/ui-mode"; -import cfg_keyboard_qwerty from "#inputs/cfg_keyboard_qwerty"; -import { deleteBind } from "#inputs/configHandler"; +import cfg_keyboard_qwerty from "#inputs/cfg-keyboard-qwerty"; +import { deleteBind } from "#inputs/config-handler"; import { SettingKeyboard, setSettingKeyboard, @@ -12,7 +12,7 @@ import { settingKeyboardOptions, } from "#system/settings-keyboard"; import { AbstractControlSettingsUiHandler } from "#ui/abstract-control-settings-ui-handler"; -import { NavigationManager } from "#ui/navigationMenu"; +import { NavigationManager } from "#ui/navigation-menu"; import { addTextObject, TextStyle } from "#ui/text"; import { reverseValueToKeySetting, truncateString } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/settings/shiny_icons.json b/src/ui/settings/shiny_icons.json deleted file mode 100644 index f40c606ca47..00000000000 --- a/src/ui/settings/shiny_icons.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "textures": [ - { - "image": "shiny_icons.png", - "format": "RGBA8888", - "size": { - "w": 45, - "h": 14 - }, - "scale": 1, - "frames": [ - { - "filename": "0", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 45, - "h": 14 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 15, - "h": 14 - }, - "frame": { - "x": 0, - "y": 0, - "w": 15, - "h": 14 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:a3275c7504a9b35b288265e191b1d14c:420725f3fb73c2cac0ab3bbc0a46f2e1:3a8b8ca0f0e4be067dd46c07b78ee013$" - } -} diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index da0a7f9a40f..b4df4612546 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -10,7 +10,7 @@ import { getNatureName, getNatureStatMultiplier } from "#data/nature"; import { getPokeballAtlasKey } from "#data/pokeball"; import { getTypeRgb } from "#data/type"; import { Button } from "#enums/buttons"; -import { MoveCategory } from "#enums/MoveCategory"; +import { MoveCategory } from "#enums/move-category"; import { Nature } from "#enums/nature"; import { PlayerGender } from "#enums/player-gender"; import { PokemonType } from "#enums/pokemon-type"; diff --git a/src/ui/ui.ts b/src/ui/ui.ts index 394409bcb9d..e9798e6350d 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -29,7 +29,7 @@ import { MenuUiHandler } from "#ui/menu-ui-handler"; import { MessageUiHandler } from "#ui/message-ui-handler"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { MysteryEncounterUiHandler } from "#ui/mystery-encounter-ui-handler"; -import { NavigationManager } from "#ui/navigationMenu"; +import { NavigationManager } from "#ui/navigation-menu"; import { OptionSelectUiHandler } from "#ui/option-select-ui-handler"; import { PartyUiHandler } from "#ui/party-ui-handler"; import { PokedexPageUiHandler } from "#ui/pokedex-page-ui-handler"; diff --git a/test/abilities/ability_activation_order.test.ts b/test/abilities/ability-activation-order.test.ts similarity index 98% rename from test/abilities/ability_activation_order.test.ts rename to test/abilities/ability-activation-order.test.ts index 8344ba6be11..54ff5e8b99a 100644 --- a/test/abilities/ability_activation_order.test.ts +++ b/test/abilities/ability-activation-order.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { WeatherType } from "#enums/weather-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/ability_duplication.test.ts b/test/abilities/ability-duplication.test.ts similarity index 96% rename from test/abilities/ability_duplication.test.ts rename to test/abilities/ability-duplication.test.ts index 0c88b65a00e..da572d94466 100644 --- a/test/abilities/ability_duplication.test.ts +++ b/test/abilities/ability-duplication.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/ability_timing.test.ts b/test/abilities/ability-timing.test.ts similarity index 96% rename from test/abilities/ability_timing.test.ts rename to test/abilities/ability-timing.test.ts index c3e841d8216..f5315d2b80e 100644 --- a/test/abilities/ability_timing.test.ts +++ b/test/abilities/ability-timing.test.ts @@ -5,7 +5,7 @@ import { UiMode } from "#enums/ui-mode"; import { CommandPhase } from "#phases/command-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; import i18next from "#plugins/i18n"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/analytic.test.ts b/test/abilities/analytic.test.ts index 0bacfe6775b..d1b9ba4cbbb 100644 --- a/test/abilities/analytic.test.ts +++ b/test/abilities/analytic.test.ts @@ -2,7 +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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { isBetween, toDmgValue } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/anger-point.test.ts b/test/abilities/anger-point.test.ts index 576062eadeb..84a22449dae 100644 --- a/test/abilities/anger-point.test.ts +++ b/test/abilities/anger-point.test.ts @@ -3,7 +3,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/arena_trap.test.ts b/test/abilities/arena-trap.test.ts similarity index 97% rename from test/abilities/arena_trap.test.ts rename to test/abilities/arena-trap.test.ts index c47cf3cd327..f85fae5b259 100644 --- a/test/abilities/arena_trap.test.ts +++ b/test/abilities/arena-trap.test.ts @@ -2,7 +2,7 @@ import { allAbilities } from "#data/data-lists"; import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/aroma_veil.test.ts b/test/abilities/aroma-veil.test.ts similarity index 97% rename from test/abilities/aroma_veil.test.ts rename to test/abilities/aroma-veil.test.ts index fb08d60c24f..3bdb83203c5 100644 --- a/test/abilities/aroma_veil.test.ts +++ b/test/abilities/aroma-veil.test.ts @@ -5,7 +5,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { PlayerPokemon } from "#field/pokemon"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/aura_break.test.ts b/test/abilities/aura-break.test.ts similarity index 97% rename from test/abilities/aura_break.test.ts rename to test/abilities/aura-break.test.ts index 6f33e3f047f..0fe3a253561 100644 --- a/test/abilities/aura_break.test.ts +++ b/test/abilities/aura-break.test.ts @@ -2,7 +2,7 @@ import { allMoves } from "#data/data-lists"; import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/battery.test.ts b/test/abilities/battery.test.ts index 13ebd52367a..cdb3935c33e 100644 --- a/test/abilities/battery.test.ts +++ b/test/abilities/battery.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { MoveEffectPhase } from "#phases/move-effect-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/battle_bond.test.ts b/test/abilities/battle-bond.test.ts similarity index 96% rename from test/abilities/battle_bond.test.ts rename to test/abilities/battle-bond.test.ts index ef8c2ffed75..c4ffe1e784b 100644 --- a/test/abilities/battle_bond.test.ts +++ b/test/abilities/battle-bond.test.ts @@ -1,11 +1,11 @@ import { allMoves } from "#data/data-lists"; import { Status } from "#data/status-effect"; import { AbilityId } from "#enums/ability-id"; -import { MultiHitType } from "#enums/MultiHitType"; import { MoveId } from "#enums/move-id"; +import { MultiHitType } from "#enums/multi-hit-type"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Abilities - BATTLE BOND", () => { diff --git a/test/abilities/beast_boost.test.ts b/test/abilities/beast-boost.test.ts similarity index 98% rename from test/abilities/beast_boost.test.ts rename to test/abilities/beast-boost.test.ts index 0a49728698b..193de9b7669 100644 --- a/test/abilities/beast_boost.test.ts +++ b/test/abilities/beast-boost.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/commander.test.ts b/test/abilities/commander.test.ts index 8c19ee083c5..d485cab83a2 100644 --- a/test/abilities/commander.test.ts +++ b/test/abilities/commander.test.ts @@ -9,7 +9,7 @@ import type { EffectiveStat } from "#enums/stat"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; import { WeatherType } from "#enums/weather-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/competitive.test.ts b/test/abilities/competitive.test.ts index 7dcc677a74e..1a083705e5c 100644 --- a/test/abilities/competitive.test.ts +++ b/test/abilities/competitive.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/contrary.test.ts b/test/abilities/contrary.test.ts index 7db48dedbfd..df72c25054a 100644 --- a/test/abilities/contrary.test.ts +++ b/test/abilities/contrary.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/corrosion.test.ts b/test/abilities/corrosion.test.ts index 22abc158fc7..490a365394b 100644 --- a/test/abilities/corrosion.test.ts +++ b/test/abilities/corrosion.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/costar.test.ts b/test/abilities/costar.test.ts index c8c0ffd3184..1ca1d06d76f 100644 --- a/test/abilities/costar.test.ts +++ b/test/abilities/costar.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { MessagePhase } from "#phases/message-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/abilities/cud_chew.test.ts b/test/abilities/cud-chew.test.ts similarity index 99% rename from test/abilities/cud_chew.test.ts rename to test/abilities/cud-chew.test.ts index 8fc62b38528..5f15de04cae 100644 --- a/test/abilities/cud_chew.test.ts +++ b/test/abilities/cud-chew.test.ts @@ -7,7 +7,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { Pokemon } from "#field/pokemon"; -import { GameManager } from "#test/testUtils/gameManager"; +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"; diff --git a/test/abilities/dancer.test.ts b/test/abilities/dancer.test.ts index 86b5b68e901..bbf1a368573 100644 --- a/test/abilities/dancer.test.ts +++ b/test/abilities/dancer.test.ts @@ -5,7 +5,7 @@ import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import type { MovePhase } from "#phases/move-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/defiant.test.ts b/test/abilities/defiant.test.ts index 44187429e2b..29c386ff093 100644 --- a/test/abilities/defiant.test.ts +++ b/test/abilities/defiant.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/desolate-land.test.ts b/test/abilities/desolate-land.test.ts index fc066fa8955..c88f7415bb1 100644 --- a/test/abilities/desolate-land.test.ts +++ b/test/abilities/desolate-land.test.ts @@ -6,7 +6,7 @@ import { PokeballType } from "#enums/pokeball"; import { SpeciesId } from "#enums/species-id"; import { WeatherType } from "#enums/weather-type"; import type { CommandPhase } from "#phases/command-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/disguise.test.ts b/test/abilities/disguise.test.ts index 9bd36def8d7..bf271c81e4d 100644 --- a/test/abilities/disguise.test.ts +++ b/test/abilities/disguise.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { toDmgValue } from "#utils/common"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/dry_skin.test.ts b/test/abilities/dry-skin.test.ts similarity index 98% rename from test/abilities/dry_skin.test.ts rename to test/abilities/dry-skin.test.ts index 712d3295e6f..01602150710 100644 --- a/test/abilities/dry_skin.test.ts +++ b/test/abilities/dry-skin.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/early_bird.test.ts b/test/abilities/early-bird.test.ts similarity index 97% rename from test/abilities/early_bird.test.ts rename to test/abilities/early-bird.test.ts index be4a2c802af..97ce02e5e62 100644 --- a/test/abilities/early_bird.test.ts +++ b/test/abilities/early-bird.test.ts @@ -4,7 +4,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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/flash_fire.test.ts b/test/abilities/flash-fire.test.ts similarity index 98% rename from test/abilities/flash_fire.test.ts rename to test/abilities/flash-fire.test.ts index d6085c4e591..d9f0e194d9c 100644 --- a/test/abilities/flash_fire.test.ts +++ b/test/abilities/flash-fire.test.ts @@ -6,7 +6,7 @@ import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { MovePhase } from "#phases/move-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/flower_gift.test.ts b/test/abilities/flower-gift.test.ts similarity index 99% rename from test/abilities/flower_gift.test.ts rename to test/abilities/flower-gift.test.ts index b283729d951..2fc67b098b7 100644 --- a/test/abilities/flower_gift.test.ts +++ b/test/abilities/flower-gift.test.ts @@ -6,7 +6,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { WeatherType } from "#enums/weather-type"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/flower_veil.test.ts b/test/abilities/flower-veil.test.ts similarity index 99% rename from test/abilities/flower_veil.test.ts rename to test/abilities/flower-veil.test.ts index e890ea24fad..46478a3dd9c 100644 --- a/test/abilities/flower_veil.test.ts +++ b/test/abilities/flower-veil.test.ts @@ -6,7 +6,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/forecast.test.ts b/test/abilities/forecast.test.ts index 372e32a27fa..644927186f4 100644 --- a/test/abilities/forecast.test.ts +++ b/test/abilities/forecast.test.ts @@ -9,7 +9,7 @@ import { MovePhase } from "#phases/move-phase"; import { PostSummonPhase } from "#phases/post-summon-phase"; import { QuietFormChangePhase } from "#phases/quiet-form-change-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/friend_guard.test.ts b/test/abilities/friend-guard.test.ts similarity index 97% rename from test/abilities/friend_guard.test.ts rename to test/abilities/friend-guard.test.ts index e26fd5b5f1f..32f4fe06df4 100644 --- a/test/abilities/friend_guard.test.ts +++ b/test/abilities/friend-guard.test.ts @@ -1,10 +1,10 @@ import { allAbilities, allMoves } from "#data/data-lists"; import { AbilityId } from "#enums/ability-id"; import { BattlerIndex } from "#enums/battler-index"; -import { MoveCategory } from "#enums/MoveCategory"; +import { MoveCategory } from "#enums/move-category"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/good_as_gold.test.ts b/test/abilities/good-as-gold.test.ts similarity index 98% rename from test/abilities/good_as_gold.test.ts rename to test/abilities/good-as-gold.test.ts index 956553a96d9..7fc1ad85b53 100644 --- a/test/abilities/good_as_gold.test.ts +++ b/test/abilities/good-as-gold.test.ts @@ -9,7 +9,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; import { WeatherType } from "#enums/weather-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/gorilla_tactics.test.ts b/test/abilities/gorilla-tactics.test.ts similarity index 98% rename from test/abilities/gorilla_tactics.test.ts rename to test/abilities/gorilla-tactics.test.ts index 05714fe77ea..83e6cdb156e 100644 --- a/test/abilities/gorilla_tactics.test.ts +++ b/test/abilities/gorilla-tactics.test.ts @@ -6,7 +6,7 @@ import { MoveUseMode } from "#enums/move-use-mode"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { RandomMoveAttr } from "#moves/move"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/guard-dog.test.ts b/test/abilities/guard-dog.test.ts index aef8f081975..fb06c4c76c3 100644 --- a/test/abilities/guard-dog.test.ts +++ b/test/abilities/guard-dog.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/gulp_missile.test.ts b/test/abilities/gulp-missile.test.ts similarity index 99% rename from test/abilities/gulp_missile.test.ts rename to test/abilities/gulp-missile.test.ts index 69ed6c51ac9..faf30adae33 100644 --- a/test/abilities/gulp_missile.test.ts +++ b/test/abilities/gulp-missile.test.ts @@ -6,7 +6,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; import type { Pokemon } from "#field/pokemon"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/harvest.test.ts b/test/abilities/harvest.test.ts index 244de383b44..d27ee491fed 100644 --- a/test/abilities/harvest.test.ts +++ b/test/abilities/harvest.test.ts @@ -9,7 +9,7 @@ import { WeatherType } from "#enums/weather-type"; import type { Pokemon } from "#field/pokemon"; import { BerryModifier, PreserveBerryModifier } from "#modifiers/modifier"; import type { ModifierOverride } from "#modifiers/modifier-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import type { BooleanHolder } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/healer.test.ts b/test/abilities/healer.test.ts index 8ce8b5bada0..c151836d76d 100644 --- a/test/abilities/healer.test.ts +++ b/test/abilities/healer.test.ts @@ -5,7 +5,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import type { Pokemon } from "#field/pokemon"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { isNullOrUndefined } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/heatproof.test.ts b/test/abilities/heatproof.test.ts index 0d76c1ad40b..63f877a3567 100644 --- a/test/abilities/heatproof.test.ts +++ b/test/abilities/heatproof.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { toDmgValue } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/honey_gather.test.ts b/test/abilities/honey-gather.test.ts similarity index 97% rename from test/abilities/honey_gather.test.ts rename to test/abilities/honey-gather.test.ts index 65c590083f5..8dfd2c189f8 100644 --- a/test/abilities/honey_gather.test.ts +++ b/test/abilities/honey-gather.test.ts @@ -4,7 +4,7 @@ import { Command } from "#enums/command"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { CommandPhase } from "#phases/command-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/hustle.test.ts b/test/abilities/hustle.test.ts index 94045d231d1..74ee01f02ef 100644 --- a/test/abilities/hustle.test.ts +++ b/test/abilities/hustle.test.ts @@ -3,7 +3,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/hyper_cutter.test.ts b/test/abilities/hyper-cutter.test.ts similarity index 96% rename from test/abilities/hyper_cutter.test.ts rename to test/abilities/hyper-cutter.test.ts index 212083b62b6..8a509d026b6 100644 --- a/test/abilities/hyper_cutter.test.ts +++ b/test/abilities/hyper-cutter.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/ice_face.test.ts b/test/abilities/ice-face.test.ts similarity index 99% rename from test/abilities/ice_face.test.ts rename to test/abilities/ice-face.test.ts index a0e2a949672..9b3020b67a7 100644 --- a/test/abilities/ice_face.test.ts +++ b/test/abilities/ice-face.test.ts @@ -8,7 +8,7 @@ import { MoveEndPhase } from "#phases/move-end-phase"; import { QuietFormChangePhase } from "#phases/quiet-form-change-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/illuminate.test.ts b/test/abilities/illuminate.test.ts index 0fb31379542..814b7dc64b7 100644 --- a/test/abilities/illuminate.test.ts +++ b/test/abilities/illuminate.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/illusion.test.ts b/test/abilities/illusion.test.ts index 0624c5e19f4..17a1fa8dd3d 100644 --- a/test/abilities/illusion.test.ts +++ b/test/abilities/illusion.test.ts @@ -3,7 +3,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { PokeballType } from "#enums/pokeball"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/immunity.test.ts b/test/abilities/immunity.test.ts index 6f6fac10bf9..dccee93ac10 100644 --- a/test/abilities/immunity.test.ts +++ b/test/abilities/immunity.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/infiltrator.test.ts b/test/abilities/infiltrator.test.ts index 9f1eed466b9..9f3678850a1 100644 --- a/test/abilities/infiltrator.test.ts +++ b/test/abilities/infiltrator.test.ts @@ -7,7 +7,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/innards-out.test.ts b/test/abilities/innards-out.test.ts index a10465ce1cb..96c07344b11 100644 --- a/test/abilities/innards-out.test.ts +++ b/test/abilities/innards-out.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/insomnia.test.ts b/test/abilities/insomnia.test.ts index 2f683b516eb..679220687b9 100644 --- a/test/abilities/insomnia.test.ts +++ b/test/abilities/insomnia.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/intimidate.test.ts b/test/abilities/intimidate.test.ts index 9ff408aaeb5..3c283e0392b 100644 --- a/test/abilities/intimidate.test.ts +++ b/test/abilities/intimidate.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/intrepid_sword.test.ts b/test/abilities/intrepid-sword.test.ts similarity index 95% rename from test/abilities/intrepid_sword.test.ts rename to test/abilities/intrepid-sword.test.ts index 7465b331791..75a1ab14e82 100644 --- a/test/abilities/intrepid_sword.test.ts +++ b/test/abilities/intrepid-sword.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { CommandPhase } from "#phases/command-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/lightningrod.test.ts b/test/abilities/lightningrod.test.ts index 2d5b6881869..20fcb176055 100644 --- a/test/abilities/lightningrod.test.ts +++ b/test/abilities/lightningrod.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/limber.test.ts b/test/abilities/limber.test.ts index ed140c09fb1..e65a54b545d 100644 --- a/test/abilities/limber.test.ts +++ b/test/abilities/limber.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/magic_bounce.test.ts b/test/abilities/magic-bounce.test.ts similarity index 99% rename from test/abilities/magic_bounce.test.ts rename to test/abilities/magic-bounce.test.ts index 84b4cea8376..3b4185e848f 100644 --- a/test/abilities/magic_bounce.test.ts +++ b/test/abilities/magic-bounce.test.ts @@ -8,7 +8,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Abilities - Magic Bounce", () => { diff --git a/test/abilities/magic_guard.test.ts b/test/abilities/magic-guard.test.ts similarity index 99% rename from test/abilities/magic_guard.test.ts rename to test/abilities/magic-guard.test.ts index 63b22f347fb..e2977420edf 100644 --- a/test/abilities/magic_guard.test.ts +++ b/test/abilities/magic-guard.test.ts @@ -6,7 +6,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { toDmgValue } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/magma_armor.test.ts b/test/abilities/magma-armor.test.ts similarity index 96% rename from test/abilities/magma_armor.test.ts rename to test/abilities/magma-armor.test.ts index cc40ea9f679..2e7176fdf96 100644 --- a/test/abilities/magma_armor.test.ts +++ b/test/abilities/magma-armor.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/mimicry.test.ts b/test/abilities/mimicry.test.ts index f377ab89ffe..c04860d1fcd 100644 --- a/test/abilities/mimicry.test.ts +++ b/test/abilities/mimicry.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/mirror_armor.test.ts b/test/abilities/mirror-armor.test.ts similarity index 99% rename from test/abilities/mirror_armor.test.ts rename to test/abilities/mirror-armor.test.ts index 4d4ee973527..b2f9c9dc8fa 100644 --- a/test/abilities/mirror_armor.test.ts +++ b/test/abilities/mirror-armor.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/mold_breaker.test.ts b/test/abilities/mold-breaker.test.ts similarity index 95% rename from test/abilities/mold_breaker.test.ts rename to test/abilities/mold-breaker.test.ts index c3214cdc224..2af17b625b0 100644 --- a/test/abilities/mold_breaker.test.ts +++ b/test/abilities/mold-breaker.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/moody.test.ts b/test/abilities/moody.test.ts index 150456bc0f7..80879837bce 100644 --- a/test/abilities/moody.test.ts +++ b/test/abilities/moody.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/moxie.test.ts b/test/abilities/moxie.test.ts index 882b4b0df2f..28b90042969 100644 --- a/test/abilities/moxie.test.ts +++ b/test/abilities/moxie.test.ts @@ -6,7 +6,7 @@ import { Stat } from "#enums/stat"; import { EnemyCommandPhase } from "#phases/enemy-command-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; import { VictoryPhase } from "#phases/victory-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/mummy.test.ts b/test/abilities/mummy.test.ts index 6c94fea407b..e3843f9c112 100644 --- a/test/abilities/mummy.test.ts +++ b/test/abilities/mummy.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/mycelium_might.test.ts b/test/abilities/mycelium-might.test.ts similarity index 98% rename from test/abilities/mycelium_might.test.ts rename to test/abilities/mycelium-might.test.ts index fa3ab8e5301..41da6b5c693 100644 --- a/test/abilities/mycelium_might.test.ts +++ b/test/abilities/mycelium-might.test.ts @@ -4,7 +4,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnEndPhase } from "#phases/turn-end-phase"; import { TurnStartPhase } from "#phases/turn-start-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/neutralizing_gas.test.ts b/test/abilities/neutralizing-gas.test.ts similarity index 99% rename from test/abilities/neutralizing_gas.test.ts rename to test/abilities/neutralizing-gas.test.ts index bcc00e4249a..560b7af72e7 100644 --- a/test/abilities/neutralizing_gas.test.ts +++ b/test/abilities/neutralizing-gas.test.ts @@ -8,7 +8,7 @@ import { PokeballType } from "#enums/pokeball"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import type { CommandPhase } from "#phases/command-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/no_guard.test.ts b/test/abilities/no-guard.test.ts similarity index 96% rename from test/abilities/no_guard.test.ts rename to test/abilities/no-guard.test.ts index f6f55ce3b80..9ce12e710e5 100644 --- a/test/abilities/no_guard.test.ts +++ b/test/abilities/no-guard.test.ts @@ -5,7 +5,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { MoveEffectPhase } from "#phases/move-effect-phase"; import { MoveEndPhase } from "#phases/move-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/normal-move-type-change.test.ts b/test/abilities/normal-move-type-change.test.ts index aa673ddde29..58839bae898 100644 --- a/test/abilities/normal-move-type-change.test.ts +++ b/test/abilities/normal-move-type-change.test.ts @@ -5,7 +5,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { toDmgValue } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/normalize.test.ts b/test/abilities/normalize.test.ts index 1128dd1a562..aeebb2fdbcb 100644 --- a/test/abilities/normalize.test.ts +++ b/test/abilities/normalize.test.ts @@ -4,7 +4,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { toDmgValue } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/oblivious.test.ts b/test/abilities/oblivious.test.ts index 8b18fe65455..6b9598903c5 100644 --- a/test/abilities/oblivious.test.ts +++ b/test/abilities/oblivious.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/own_tempo.test.ts b/test/abilities/own-tempo.test.ts similarity index 96% rename from test/abilities/own_tempo.test.ts rename to test/abilities/own-tempo.test.ts index bdb247c4987..c919d9eae53 100644 --- a/test/abilities/own_tempo.test.ts +++ b/test/abilities/own-tempo.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/parental_bond.test.ts b/test/abilities/parental-bond.test.ts similarity index 99% rename from test/abilities/parental_bond.test.ts rename to test/abilities/parental-bond.test.ts index 4937857c8e1..51c15ea32b1 100644 --- a/test/abilities/parental_bond.test.ts +++ b/test/abilities/parental-bond.test.ts @@ -5,7 +5,7 @@ import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { toDmgValue } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/pastel_veil.test.ts b/test/abilities/pastel-veil.test.ts similarity index 97% rename from test/abilities/pastel_veil.test.ts rename to test/abilities/pastel-veil.test.ts index 88f5415524f..c4b368c94d0 100644 --- a/test/abilities/pastel_veil.test.ts +++ b/test/abilities/pastel-veil.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/perish_body.test.ts b/test/abilities/perish-body.test.ts similarity index 98% rename from test/abilities/perish_body.test.ts rename to test/abilities/perish-body.test.ts index 83a862164a1..251d29abe36 100644 --- a/test/abilities/perish_body.test.ts +++ b/test/abilities/perish-body.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/power_construct.test.ts b/test/abilities/power-construct.test.ts similarity index 97% rename from test/abilities/power_construct.test.ts rename to test/abilities/power-construct.test.ts index 0917082d7bd..34e02851daf 100644 --- a/test/abilities/power_construct.test.ts +++ b/test/abilities/power-construct.test.ts @@ -5,7 +5,7 @@ import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { QuietFormChangePhase } from "#phases/quiet-form-change-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; describe("Abilities - POWER CONSTRUCT", () => { diff --git a/test/abilities/power_spot.test.ts b/test/abilities/power-spot.test.ts similarity index 97% rename from test/abilities/power_spot.test.ts rename to test/abilities/power-spot.test.ts index f07ece17245..75d5cd78ae0 100644 --- a/test/abilities/power_spot.test.ts +++ b/test/abilities/power-spot.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { MoveEffectPhase } from "#phases/move-effect-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/protean-libero.test.ts b/test/abilities/protean-libero.test.ts index 35be3fcf63d..305955f5221 100644 --- a/test/abilities/protean-libero.test.ts +++ b/test/abilities/protean-libero.test.ts @@ -8,7 +8,7 @@ import { MoveResult } from "#enums/move-result"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import type { PlayerPokemon } from "#field/pokemon"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/protosynthesis.test.ts b/test/abilities/protosynthesis.test.ts index 5629ea503d7..f4461a562ea 100644 --- a/test/abilities/protosynthesis.test.ts +++ b/test/abilities/protosynthesis.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { Nature } from "#enums/nature"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/quick_draw.test.ts b/test/abilities/quick-draw.test.ts similarity index 97% rename from test/abilities/quick_draw.test.ts rename to test/abilities/quick-draw.test.ts index f881adce5ed..d3914e24268 100644 --- a/test/abilities/quick_draw.test.ts +++ b/test/abilities/quick-draw.test.ts @@ -3,7 +3,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { FaintPhase } from "#phases/faint-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; diff --git a/test/abilities/sand_spit.test.ts b/test/abilities/sand-spit.test.ts similarity index 96% rename from test/abilities/sand_spit.test.ts rename to test/abilities/sand-spit.test.ts index dfd8a342ccc..9cfd94a1857 100644 --- a/test/abilities/sand_spit.test.ts +++ b/test/abilities/sand-spit.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { WeatherType } from "#enums/weather-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/sand_veil.test.ts b/test/abilities/sand-veil.test.ts similarity index 97% rename from test/abilities/sand_veil.test.ts rename to test/abilities/sand-veil.test.ts index 2ad9ef7eaa1..4777a016743 100644 --- a/test/abilities/sand_veil.test.ts +++ b/test/abilities/sand-veil.test.ts @@ -6,7 +6,7 @@ import { Stat } from "#enums/stat"; import { WeatherType } from "#enums/weather-type"; import { MoveEffectPhase } from "#phases/move-effect-phase"; import { MoveEndPhase } from "#phases/move-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import type { StatMultiplierAbAttrParams } from "#types/ability-types"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; diff --git a/test/abilities/sap_sipper.test.ts b/test/abilities/sap-sipper.test.ts similarity index 98% rename from test/abilities/sap_sipper.test.ts rename to test/abilities/sap-sipper.test.ts index a8fe10d7fc5..a1c034ab126 100644 --- a/test/abilities/sap_sipper.test.ts +++ b/test/abilities/sap-sipper.test.ts @@ -8,7 +8,7 @@ import { Stat } from "#enums/stat"; import { RandomMoveAttr } from "#moves/move"; import { MoveEndPhase } from "#phases/move-end-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/schooling.test.ts b/test/abilities/schooling.test.ts index 94bb4cb80f9..fea919c7c5a 100644 --- a/test/abilities/schooling.test.ts +++ b/test/abilities/schooling.test.ts @@ -5,7 +5,7 @@ import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { QuietFormChangePhase } from "#phases/quiet-form-change-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; describe("Abilities - SCHOOLING", () => { diff --git a/test/abilities/screen_cleaner.test.ts b/test/abilities/screen-cleaner.test.ts similarity index 97% rename from test/abilities/screen_cleaner.test.ts rename to test/abilities/screen-cleaner.test.ts index 8b53ab30d49..50a854adeb1 100644 --- a/test/abilities/screen_cleaner.test.ts +++ b/test/abilities/screen-cleaner.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { PostSummonPhase } from "#phases/post-summon-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/seed_sower.test.ts b/test/abilities/seed-sower.test.ts similarity index 96% rename from test/abilities/seed_sower.test.ts rename to test/abilities/seed-sower.test.ts index 8573f0242ea..f31955a0bbb 100644 --- a/test/abilities/seed_sower.test.ts +++ b/test/abilities/seed-sower.test.ts @@ -2,7 +2,7 @@ import { TerrainType } from "#data/terrain"; import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/serene_grace.test.ts b/test/abilities/serene-grace.test.ts similarity index 96% rename from test/abilities/serene_grace.test.ts rename to test/abilities/serene-grace.test.ts index aaa0f26f78b..bbf9cf7555b 100644 --- a/test/abilities/serene_grace.test.ts +++ b/test/abilities/serene-grace.test.ts @@ -3,7 +3,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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/sheer_force.test.ts b/test/abilities/sheer-force.test.ts similarity index 98% rename from test/abilities/sheer_force.test.ts rename to test/abilities/sheer-force.test.ts index 0b0c0c10ccf..0e2ce85bfca 100644 --- a/test/abilities/sheer_force.test.ts +++ b/test/abilities/sheer-force.test.ts @@ -5,7 +5,7 @@ import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/shell-armor.test.ts b/test/abilities/shell-armor.test.ts index e10c3a90444..df0802b25da 100644 --- a/test/abilities/shell-armor.test.ts +++ b/test/abilities/shell-armor.test.ts @@ -4,7 +4,7 @@ import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { Pokemon } from "#field/pokemon"; import type { Move } from "#moves/move"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, type MockInstance, vi } from "vitest"; diff --git a/test/abilities/shield_dust.test.ts b/test/abilities/shield-dust.test.ts similarity index 97% rename from test/abilities/shield_dust.test.ts rename to test/abilities/shield-dust.test.ts index 371c7d9cf29..025b415dbc0 100644 --- a/test/abilities/shield_dust.test.ts +++ b/test/abilities/shield-dust.test.ts @@ -5,7 +5,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { MoveEffectPhase } from "#phases/move-effect-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { NumberHolder } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/shields_down.test.ts b/test/abilities/shields-down.test.ts similarity index 99% rename from test/abilities/shields_down.test.ts rename to test/abilities/shields-down.test.ts index 7678c7d8dac..0323a4afbec 100644 --- a/test/abilities/shields_down.test.ts +++ b/test/abilities/shields-down.test.ts @@ -6,7 +6,7 @@ import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { QuietFormChangePhase } from "#phases/quiet-form-change-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; describe("Abilities - SHIELDS DOWN", () => { diff --git a/test/abilities/simple.test.ts b/test/abilities/simple.test.ts index a709c8696d3..39f1b579a19 100644 --- a/test/abilities/simple.test.ts +++ b/test/abilities/simple.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/speed_boost.test.ts b/test/abilities/speed-boost.test.ts similarity index 98% rename from test/abilities/speed_boost.test.ts rename to test/abilities/speed-boost.test.ts index 975fc8ebecf..ff0beaf74a0 100644 --- a/test/abilities/speed_boost.test.ts +++ b/test/abilities/speed-boost.test.ts @@ -6,7 +6,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { AttemptRunPhase } from "#phases/attempt-run-phase"; import type { CommandPhase } from "#phases/command-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/stakeout.test.ts b/test/abilities/stakeout.test.ts index 85838a52abe..5dafb620274 100644 --- a/test/abilities/stakeout.test.ts +++ b/test/abilities/stakeout.test.ts @@ -2,7 +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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { isBetween } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/stall.test.ts b/test/abilities/stall.test.ts index c012586eea5..71796d376a3 100644 --- a/test/abilities/stall.test.ts +++ b/test/abilities/stall.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { TurnStartPhase } from "#phases/turn-start-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/steely_spirit.test.ts b/test/abilities/steely-spirit.test.ts similarity index 98% rename from test/abilities/steely_spirit.test.ts rename to test/abilities/steely-spirit.test.ts index 0ca7bebe17a..072566fdb96 100644 --- a/test/abilities/steely_spirit.test.ts +++ b/test/abilities/steely-spirit.test.ts @@ -2,7 +2,7 @@ import { allAbilities, allMoves } from "#data/data-lists"; import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/storm_drain.test.ts b/test/abilities/storm-drain.test.ts similarity index 98% rename from test/abilities/storm_drain.test.ts rename to test/abilities/storm-drain.test.ts index 59626546578..bc4d4f15cfa 100644 --- a/test/abilities/storm_drain.test.ts +++ b/test/abilities/storm-drain.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/sturdy.test.ts b/test/abilities/sturdy.test.ts index 0cde40a91da..28d3098a420 100644 --- a/test/abilities/sturdy.test.ts +++ b/test/abilities/sturdy.test.ts @@ -4,7 +4,7 @@ import { SpeciesId } from "#enums/species-id"; import type { EnemyPokemon } from "#field/pokemon"; import { DamageAnimPhase } from "#phases/damage-anim-phase"; import { MoveEndPhase } from "#phases/move-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/abilities/super_luck.test.ts b/test/abilities/super-luck.test.ts similarity index 95% rename from test/abilities/super_luck.test.ts rename to test/abilities/super-luck.test.ts index 954251583f8..a0f5293b036 100644 --- a/test/abilities/super_luck.test.ts +++ b/test/abilities/super-luck.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/supreme_overlord.test.ts b/test/abilities/supreme-overlord.test.ts similarity index 98% rename from test/abilities/supreme_overlord.test.ts rename to test/abilities/supreme-overlord.test.ts index b68153a2cc8..a0f2d9050b3 100644 --- a/test/abilities/supreme_overlord.test.ts +++ b/test/abilities/supreme-overlord.test.ts @@ -5,7 +5,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { Move } from "#moves/move"; import { MoveEffectPhase } from "#phases/move-effect-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/sweet_veil.test.ts b/test/abilities/sweet-veil.test.ts similarity index 97% rename from test/abilities/sweet_veil.test.ts rename to test/abilities/sweet-veil.test.ts index ca98e827c4f..12eeae9f9c5 100644 --- a/test/abilities/sweet_veil.test.ts +++ b/test/abilities/sweet-veil.test.ts @@ -4,7 +4,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/synchronize.test.ts b/test/abilities/synchronize.test.ts index 1874560a166..c95ae1b7828 100644 --- a/test/abilities/synchronize.test.ts +++ b/test/abilities/synchronize.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/tera_shell.test.ts b/test/abilities/tera-shell.test.ts similarity index 98% rename from test/abilities/tera_shell.test.ts rename to test/abilities/tera-shell.test.ts index bd461e3aeba..385fabe1a54 100644 --- a/test/abilities/tera_shell.test.ts +++ b/test/abilities/tera-shell.test.ts @@ -2,7 +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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/thermal_exchange.test.ts b/test/abilities/thermal-exchange.test.ts similarity index 96% rename from test/abilities/thermal_exchange.test.ts rename to test/abilities/thermal-exchange.test.ts index 5e684b982e7..193676ccc18 100644 --- a/test/abilities/thermal_exchange.test.ts +++ b/test/abilities/thermal-exchange.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/trace.test.ts b/test/abilities/trace.test.ts index 7b87b3669b6..4211234a451 100644 --- a/test/abilities/trace.test.ts +++ b/test/abilities/trace.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/unburden.test.ts b/test/abilities/unburden.test.ts index 8d738db9076..686a6c20904 100644 --- a/test/abilities/unburden.test.ts +++ b/test/abilities/unburden.test.ts @@ -9,7 +9,7 @@ import { Stat } from "#enums/stat"; import type { Pokemon } from "#field/pokemon"; import type { ContactHeldItemTransferChanceModifier } from "#modifiers/modifier"; import { StealHeldItemChanceAttr } from "#moves/move"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/unseen_fist.test.ts b/test/abilities/unseen-fist.test.ts similarity index 98% rename from test/abilities/unseen_fist.test.ts rename to test/abilities/unseen-fist.test.ts index c986a112517..01b573fe66c 100644 --- a/test/abilities/unseen_fist.test.ts +++ b/test/abilities/unseen-fist.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { BerryPhase } from "#phases/berry-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/victory_star.test.ts b/test/abilities/victory-star.test.ts similarity index 96% rename from test/abilities/victory_star.test.ts rename to test/abilities/victory-star.test.ts index aff91a7702b..40611f6fbc1 100644 --- a/test/abilities/victory_star.test.ts +++ b/test/abilities/victory-star.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/vital_spirit.test.ts b/test/abilities/vital-spirit.test.ts similarity index 96% rename from test/abilities/vital_spirit.test.ts rename to test/abilities/vital-spirit.test.ts index 7530b2c6c04..e5d80a66a8e 100644 --- a/test/abilities/vital_spirit.test.ts +++ b/test/abilities/vital-spirit.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/volt_absorb.test.ts b/test/abilities/volt-absorb.test.ts similarity index 97% rename from test/abilities/volt_absorb.test.ts rename to test/abilities/volt-absorb.test.ts index 12de6ceff87..921d56f075b 100644 --- a/test/abilities/volt_absorb.test.ts +++ b/test/abilities/volt-absorb.test.ts @@ -5,7 +5,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/wandering_spirit.test.ts b/test/abilities/wandering-spirit.test.ts similarity index 97% rename from test/abilities/wandering_spirit.test.ts rename to test/abilities/wandering-spirit.test.ts index 3d26238e970..63c2550b198 100644 --- a/test/abilities/wandering_spirit.test.ts +++ b/test/abilities/wandering-spirit.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/water_bubble.test.ts b/test/abilities/water-bubble.test.ts similarity index 96% rename from test/abilities/water_bubble.test.ts rename to test/abilities/water-bubble.test.ts index c8d01eb2800..6be1ac51094 100644 --- a/test/abilities/water_bubble.test.ts +++ b/test/abilities/water-bubble.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/water_veil.test.ts b/test/abilities/water-veil.test.ts similarity index 96% rename from test/abilities/water_veil.test.ts rename to test/abilities/water-veil.test.ts index dcfe5b60fe9..0c7068ae209 100644 --- a/test/abilities/water_veil.test.ts +++ b/test/abilities/water-veil.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/wimp_out.test.ts b/test/abilities/wimp-out.test.ts similarity index 99% rename from test/abilities/wimp_out.test.ts rename to test/abilities/wimp-out.test.ts index d6e6908e19b..a1c19a12fd4 100644 --- a/test/abilities/wimp_out.test.ts +++ b/test/abilities/wimp-out.test.ts @@ -9,7 +9,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; import { WeatherType } from "#enums/weather-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { toDmgValue } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/wind_power.test.ts b/test/abilities/wind-power.test.ts similarity index 98% rename from test/abilities/wind_power.test.ts rename to test/abilities/wind-power.test.ts index 255e8fa69be..377a8052e13 100644 --- a/test/abilities/wind_power.test.ts +++ b/test/abilities/wind-power.test.ts @@ -3,7 +3,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/wind_rider.test.ts b/test/abilities/wind-rider.test.ts similarity index 98% rename from test/abilities/wind_rider.test.ts rename to test/abilities/wind-rider.test.ts index e7b55d2ef65..be30acb0f64 100644 --- a/test/abilities/wind_rider.test.ts +++ b/test/abilities/wind-rider.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/wonder_skin.test.ts b/test/abilities/wonder-skin.test.ts similarity index 97% rename from test/abilities/wonder_skin.test.ts rename to test/abilities/wonder-skin.test.ts index f55c303c9e3..8f14bf10101 100644 --- a/test/abilities/wonder_skin.test.ts +++ b/test/abilities/wonder-skin.test.ts @@ -3,7 +3,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { MoveEffectPhase } from "#phases/move-effect-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/abilities/zen_mode.test.ts b/test/abilities/zen-mode.test.ts similarity index 98% rename from test/abilities/zen_mode.test.ts rename to test/abilities/zen-mode.test.ts index 89dc0690ead..24d53bda7b6 100644 --- a/test/abilities/zen_mode.test.ts +++ b/test/abilities/zen-mode.test.ts @@ -3,7 +3,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/abilities/zero_to_hero.test.ts b/test/abilities/zero-to-hero.test.ts similarity index 98% rename from test/abilities/zero_to_hero.test.ts rename to test/abilities/zero-to-hero.test.ts index 84b3ddab60c..cb0fe75d11b 100644 --- a/test/abilities/zero_to_hero.test.ts +++ b/test/abilities/zero-to-hero.test.ts @@ -5,7 +5,7 @@ import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { QuietFormChangePhase } from "#phases/quiet-form-change-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Abilities - ZERO TO HERO", () => { diff --git a/test/achievements/achievement.test.ts b/test/achievements/achievement.test.ts index d736485b25f..9060d6213cc 100644 --- a/test/achievements/achievement.test.ts +++ b/test/achievements/achievement.test.ts @@ -11,7 +11,7 @@ import { MoneyAchv, RibbonAchv, } from "#system/achv"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { NumberHolder } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/arena/arena_gravity.test.ts b/test/arena/arena-gravity.test.ts similarity index 98% rename from test/arena/arena_gravity.test.ts rename to test/arena/arena-gravity.test.ts index d1cee1655a1..b08dcf0c9b0 100644 --- a/test/arena/arena_gravity.test.ts +++ b/test/arena/arena-gravity.test.ts @@ -5,7 +5,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/arena/grassy_terrain.test.ts b/test/arena/grassy-terrain.test.ts similarity index 96% rename from test/arena/grassy_terrain.test.ts rename to test/arena/grassy-terrain.test.ts index 541402123c4..d87498cdd23 100644 --- a/test/arena/grassy_terrain.test.ts +++ b/test/arena/grassy-terrain.test.ts @@ -2,7 +2,7 @@ import { allMoves } from "#data/data-lists"; import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/arena/weather_fog.test.ts b/test/arena/weather-fog.test.ts similarity index 95% rename from test/arena/weather_fog.test.ts rename to test/arena/weather-fog.test.ts index f55a12e3e0f..8dd906d2df3 100644 --- a/test/arena/weather_fog.test.ts +++ b/test/arena/weather-fog.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { WeatherType } from "#enums/weather-type"; import { MoveEffectPhase } from "#phases/move-effect-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/arena/weather_hail.test.ts b/test/arena/weather-hail.test.ts similarity index 97% rename from test/arena/weather_hail.test.ts rename to test/arena/weather-hail.test.ts index c6f27f647fe..b3ff8de3d42 100644 --- a/test/arena/weather_hail.test.ts +++ b/test/arena/weather-hail.test.ts @@ -2,7 +2,7 @@ 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/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/arena/weather_sandstorm.test.ts b/test/arena/weather-sandstorm.test.ts similarity index 97% rename from test/arena/weather_sandstorm.test.ts rename to test/arena/weather-sandstorm.test.ts index a600aeed000..f5cf44458c5 100644 --- a/test/arena/weather_sandstorm.test.ts +++ b/test/arena/weather-sandstorm.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { WeatherType } from "#enums/weather-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/arena/weather_strong_winds.test.ts b/test/arena/weather-strong-winds.test.ts similarity index 98% rename from test/arena/weather_strong_winds.test.ts rename to test/arena/weather-strong-winds.test.ts index b0b1bca8c4c..8d2d1ee0a75 100644 --- a/test/arena/weather_strong_winds.test.ts +++ b/test/arena/weather-strong-winds.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { TurnStartPhase } from "#phases/turn-start-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/battle-scene.test.ts b/test/battle-scene.test.ts index a920c48ea75..0ff4b03a50f 100644 --- a/test/battle-scene.test.ts +++ b/test/battle-scene.test.ts @@ -1,5 +1,5 @@ import { LoadingScene } from "#app/loading-scene"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("BattleScene", () => { diff --git a/test/battle/ability_swap.test.ts b/test/battle/ability-swap.test.ts similarity index 97% rename from test/battle/ability_swap.test.ts rename to test/battle/ability-swap.test.ts index 525c038d011..4ce60e1f0b2 100644 --- a/test/battle/ability_swap.test.ts +++ b/test/battle/ability-swap.test.ts @@ -3,7 +3,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/battle/battle-order.test.ts b/test/battle/battle-order.test.ts index a47da66c4d7..47afb582a5a 100644 --- a/test/battle/battle-order.test.ts +++ b/test/battle/battle-order.test.ts @@ -4,7 +4,7 @@ import { SpeciesId } from "#enums/species-id"; import { EnemyCommandPhase } from "#phases/enemy-command-phase"; import { SelectTargetPhase } from "#phases/select-target-phase"; import { TurnStartPhase } from "#phases/turn-start-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/battle/battle.test.ts b/test/battle/battle.test.ts index 7a2365fb6d8..ff5090e5f8d 100644 --- a/test/battle/battle.test.ts +++ b/test/battle/battle.test.ts @@ -21,8 +21,8 @@ import { SummonPhase } from "#phases/summon-phase"; import { SwitchPhase } from "#phases/switch-phase"; import { TitlePhase } from "#phases/title-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManager } from "#test/testUtils/gameManager"; -import { generateStarter } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { generateStarter } from "#test/test-utils/game-manager-utils"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; @@ -111,7 +111,7 @@ describe("Phase - Battle Phase", () => { }); it("load 100% data file", async () => { - await game.importData("./test/testUtils/saves/everything.prsv"); + await game.importData("./test/test-utils/saves/everything.prsv"); const caughtCount = Object.keys(game.scene.gameData.dexData).filter(key => { const species = game.scene.gameData.dexData[key]; return species.caughtAttr !== 0n; diff --git a/test/battle/damage_calculation.test.ts b/test/battle/damage-calculation.test.ts similarity index 98% rename from test/battle/damage_calculation.test.ts rename to test/battle/damage-calculation.test.ts index fbcefcb0693..ca01830abd0 100644 --- a/test/battle/damage_calculation.test.ts +++ b/test/battle/damage-calculation.test.ts @@ -4,7 +4,7 @@ import { ArenaTagType } from "#enums/arena-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { EnemyPersistentModifier } from "#modifiers/modifier"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/battle/double_battle.test.ts b/test/battle/double-battle.test.ts similarity index 98% rename from test/battle/double_battle.test.ts rename to test/battle/double-battle.test.ts index 7e0aa0f6c69..ad385a1cecf 100644 --- a/test/battle/double_battle.test.ts +++ b/test/battle/double-battle.test.ts @@ -7,7 +7,7 @@ import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { BattleEndPhase } from "#phases/battle-end-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/battle/inverse_battle.test.ts b/test/battle/inverse-battle.test.ts similarity index 99% rename from test/battle/inverse_battle.test.ts rename to test/battle/inverse-battle.test.ts index f9fd8f80a37..9ba2df9bc44 100644 --- a/test/battle/inverse_battle.test.ts +++ b/test/battle/inverse-battle.test.ts @@ -6,7 +6,7 @@ import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/battle/special_battle.test.ts b/test/battle/special-battle.test.ts similarity index 98% rename from test/battle/special_battle.test.ts rename to test/battle/special-battle.test.ts index 36b543b0666..d22931bfea5 100644 --- a/test/battle/special_battle.test.ts +++ b/test/battle/special-battle.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/battlerTags/octolock.test.ts b/test/battler-tags/octolock.test.ts similarity index 96% rename from test/battlerTags/octolock.test.ts rename to test/battler-tags/octolock.test.ts index 5b395a180a2..29024f177cb 100644 --- a/test/battlerTags/octolock.test.ts +++ b/test/battler-tags/octolock.test.ts @@ -3,7 +3,7 @@ import { BattlerTagLapseType } from "#enums/battler-tag-lapse-type"; import { Stat } from "#enums/stat"; import type { Pokemon } from "#field/pokemon"; import { StatStageChangePhase } from "#phases/stat-stage-change-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, describe, expect, it, vi } from "vitest"; describe("BattlerTag - OctolockTag", () => { diff --git a/test/battlerTags/stockpiling.test.ts b/test/battler-tags/stockpiling.test.ts similarity index 99% rename from test/battlerTags/stockpiling.test.ts rename to test/battler-tags/stockpiling.test.ts index 9024b3edb3c..a4bed560687 100644 --- a/test/battlerTags/stockpiling.test.ts +++ b/test/battler-tags/stockpiling.test.ts @@ -4,7 +4,7 @@ import { PokemonSummonData } from "#data/pokemon-data"; import { Stat } from "#enums/stat"; import type { Pokemon } from "#field/pokemon"; import { StatStageChangePhase } from "#phases/stat-stage-change-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; beforeEach(() => { diff --git a/test/battlerTags/substitute.test.ts b/test/battler-tags/substitute.test.ts similarity index 99% rename from test/battlerTags/substitute.test.ts rename to test/battler-tags/substitute.test.ts index 825bebf1a1e..7ae60ad1408 100644 --- a/test/battlerTags/substitute.test.ts +++ b/test/battler-tags/substitute.test.ts @@ -9,7 +9,7 @@ import { MoveResult } from "#enums/move-result"; import { PokemonAnimType } from "#enums/pokemon-anim-type"; import type { Pokemon } from "#field/pokemon"; import type { MoveEffectPhase } from "#phases/move-effect-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import type { TurnMove } from "#types/turn-move"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/boss-pokemon.test.ts b/test/boss-pokemon.test.ts index 06a2f313016..0a7c71c95e7 100644 --- a/test/boss-pokemon.test.ts +++ b/test/boss-pokemon.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { EFFECTIVE_STATS } from "#enums/stat"; import type { EnemyPokemon } from "#field/pokemon"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { toDmgValue } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/daily_mode.test.ts b/test/daily-mode.test.ts similarity index 98% rename from test/daily_mode.test.ts rename to test/daily-mode.test.ts index 0fa7c0dc846..34a8da80478 100644 --- a/test/daily_mode.test.ts +++ b/test/daily-mode.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { MapModifier } from "#modifiers/modifier"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/data/splash_messages.test.ts b/test/data/splash-messages.test.ts similarity index 100% rename from test/data/splash_messages.test.ts rename to test/data/splash-messages.test.ts diff --git a/test/data/status_effect.test.ts b/test/data/status-effect.test.ts similarity index 99% rename from test/data/status_effect.test.ts rename to test/data/status-effect.test.ts index 2ea4dce4147..ebfd9066b3c 100644 --- a/test/data/status_effect.test.ts +++ b/test/data/status-effect.test.ts @@ -11,8 +11,8 @@ 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 { GameManager } from "#test/testUtils/gameManager"; -import { mockI18next } from "#test/testUtils/testUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { mockI18next } from "#test/test-utils/test-utils"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; const pokemonName = "PKM"; diff --git a/test/eggs/egg.test.ts b/test/eggs/egg.test.ts index b27124bd786..8b47e68f402 100644 --- a/test/eggs/egg.test.ts +++ b/test/eggs/egg.test.ts @@ -6,7 +6,7 @@ import { EggTier } from "#enums/egg-type"; import { SpeciesId } from "#enums/species-id"; import { VariantTier } from "#enums/variant-tier"; import { EggData } from "#system/egg-data"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import * as Utils from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; @@ -28,7 +28,7 @@ describe("Egg Generation Tests", () => { }); beforeEach(async () => { - await game.importData("./test/testUtils/saves/everything.prsv"); + await game.importData("./test/test-utils/saves/everything.prsv"); }); it("should return Kyogre for the 10th of June", () => { diff --git a/test/eggs/manaphy-egg.test.ts b/test/eggs/manaphy-egg.test.ts index 319b5a15d7b..484426f1b76 100644 --- a/test/eggs/manaphy-egg.test.ts +++ b/test/eggs/manaphy-egg.test.ts @@ -2,7 +2,7 @@ import { Egg } from "#data/egg"; import { EggSourceType } from "#enums/egg-source-types"; import { EggTier } from "#enums/egg-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; @@ -24,7 +24,7 @@ describe("Manaphy Eggs", () => { }); beforeEach(async () => { - await game.importData("./test/testUtils/saves/everything.prsv"); + await game.importData("./test/test-utils/saves/everything.prsv"); /** * In our tests, we will perform an "RNG sweep" by letting rngSweepProgress diff --git a/test/endless_boss.test.ts b/test/endless-boss.test.ts similarity index 98% rename from test/endless_boss.test.ts rename to test/endless-boss.test.ts index 99c179ceeb6..707d164d4d0 100644 --- a/test/endless_boss.test.ts +++ b/test/endless-boss.test.ts @@ -1,7 +1,7 @@ import { BiomeId } from "#enums/biome-id"; import { GameModes } from "#enums/game-modes"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; const EndlessBossWave = { diff --git a/test/enemy_command.test.ts b/test/enemy-command.test.ts similarity index 96% rename from test/enemy_command.test.ts rename to test/enemy-command.test.ts index 249c819a107..12281179e0d 100644 --- a/test/enemy_command.test.ts +++ b/test/enemy-command.test.ts @@ -2,11 +2,11 @@ import type { BattleScene } from "#app/battle-scene"; import { allMoves } from "#data/data-lists"; import { AbilityId } from "#enums/ability-id"; import { AiType } from "#enums/ai-type"; -import { MoveCategory } from "#enums/MoveCategory"; +import { MoveCategory } from "#enums/move-category"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { EnemyPokemon } from "#field/pokemon"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { randSeedInt } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/escape-calculations.test.ts b/test/escape-calculations.test.ts index 338d2a1dcfc..f1bb955582a 100644 --- a/test/escape-calculations.test.ts +++ b/test/escape-calculations.test.ts @@ -3,7 +3,7 @@ import { Command } from "#enums/command"; import { SpeciesId } from "#enums/species-id"; import { AttemptRunPhase } from "#phases/attempt-run-phase"; import type { CommandPhase } from "#phases/command-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/evolution.test.ts b/test/evolution.test.ts index ffede4d09d6..172a4e5d3aa 100644 --- a/test/evolution.test.ts +++ b/test/evolution.test.ts @@ -2,7 +2,7 @@ import { pokemonEvolutions, SpeciesFormEvolution, SpeciesWildEvolutionDelay } fr import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import * as Utils from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/field/pokemon-id-checks.test.ts b/test/field/pokemon-id-checks.test.ts index 065a1ffeb7e..3a648802a1d 100644 --- a/test/field/pokemon-id-checks.test.ts +++ b/test/field/pokemon-id-checks.test.ts @@ -5,7 +5,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { Pokemon } from "#field/pokemon"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/field/pokemon.test.ts b/test/field/pokemon.test.ts index 8c04dc61b32..baa50556473 100644 --- a/test/field/pokemon.test.ts +++ b/test/field/pokemon.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { PokeballType } from "#enums/pokeball"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Spec - Pokemon", () => { diff --git a/test/final_boss.test.ts b/test/final-boss.test.ts similarity index 98% rename from test/final_boss.test.ts rename to test/final-boss.test.ts index 9dc54490330..2180979899a 100644 --- a/test/final_boss.test.ts +++ b/test/final-boss.test.ts @@ -5,7 +5,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { TurnHeldItemTransferModifier } from "#modifiers/modifier"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; const FinalWave = { diff --git a/test/fontFace.setup.ts b/test/font-face.setup.ts similarity index 100% rename from test/fontFace.setup.ts rename to test/font-face.setup.ts diff --git a/test/game-mode.test.ts b/test/game-mode.test.ts index 52de7e6a705..56af49b3f12 100644 --- a/test/game-mode.test.ts +++ b/test/game-mode.test.ts @@ -1,7 +1,7 @@ import type { GameMode } from "#app/game-mode"; import { getGameMode } from "#app/game-mode"; import { GameModes } from "#enums/game-modes"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import * as Utils from "#utils/common"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/inputs/inputs.test.ts b/test/inputs/inputs.test.ts index ce208d6ce6d..636b2e7a99e 100644 --- a/test/inputs/inputs.test.ts +++ b/test/inputs/inputs.test.ts @@ -1,7 +1,7 @@ -import cfg_keyboard_qwerty from "#inputs/cfg_keyboard_qwerty"; -import pad_xbox360 from "#inputs/pad_xbox360"; -import { GameManager } from "#test/testUtils/gameManager"; -import { InputsHandler } from "#test/testUtils/inputsHandler"; +import cfg_keyboard_qwerty from "#inputs/cfg-keyboard-qwerty"; +import pad_xbox360 from "#inputs/pad-xbox360"; +import { GameManager } from "#test/test-utils/game-manager"; +import { InputsHandler } from "#test/test-utils/inputs-handler"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/internals.test.ts b/test/internals.test.ts index bb3cd89565c..bb33b01c265 100644 --- a/test/internals.test.ts +++ b/test/internals.test.ts @@ -1,6 +1,6 @@ import { AbilityId } from "#enums/ability-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/items/dire_hit.test.ts b/test/items/dire-hit.test.ts similarity index 98% rename from test/items/dire_hit.test.ts rename to test/items/dire-hit.test.ts index 2473dd0038e..fe7fabd3c4c 100644 --- a/test/items/dire_hit.test.ts +++ b/test/items/dire-hit.test.ts @@ -9,7 +9,7 @@ import { CommandPhase } from "#phases/command-phase"; import { NewBattlePhase } from "#phases/new-battle-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/items/double_battle_chance_booster.test.ts b/test/items/double-battle-chance-booster.test.ts similarity index 98% rename from test/items/double_battle_chance_booster.test.ts rename to test/items/double-battle-chance-booster.test.ts index df6a3c6d7de..2c12b34eba3 100644 --- a/test/items/double_battle_chance_booster.test.ts +++ b/test/items/double-battle-chance-booster.test.ts @@ -4,7 +4,7 @@ import { ShopCursorTarget } from "#enums/shop-cursor-target"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { DoubleBattleChanceBoosterModifier } from "#modifiers/modifier"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/items/eviolite.test.ts b/test/items/eviolite.test.ts index 74aff03616c..2e64135d264 100644 --- a/test/items/eviolite.test.ts +++ b/test/items/eviolite.test.ts @@ -1,7 +1,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { StatBoosterModifier } from "#modifiers/modifier"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { NumberHolder, randItem } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/items/exp_booster.test.ts b/test/items/exp-booster.test.ts similarity index 95% rename from test/items/exp_booster.test.ts rename to test/items/exp-booster.test.ts index 6c8c16d08f4..dd2c8eb0c2b 100644 --- a/test/items/exp_booster.test.ts +++ b/test/items/exp-booster.test.ts @@ -1,6 +1,6 @@ import { AbilityId } from "#enums/ability-id"; import { PokemonExpBoosterModifier } from "#modifiers/modifier"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { NumberHolder } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/items/grip_claw.test.ts b/test/items/grip-claw.test.ts similarity index 98% rename from test/items/grip_claw.test.ts rename to test/items/grip-claw.test.ts index 6e25cdf6c08..5ffebd76946 100644 --- a/test/items/grip_claw.test.ts +++ b/test/items/grip-claw.test.ts @@ -5,7 +5,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { Pokemon } from "#field/pokemon"; import type { ContactHeldItemTransferChanceModifier } from "#modifiers/modifier"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/items/leek.test.ts b/test/items/leek.test.ts index 7ee3dff23d6..c38294d07a4 100644 --- a/test/items/leek.test.ts +++ b/test/items/leek.test.ts @@ -1,7 +1,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { randInt } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/items/leftovers.test.ts b/test/items/leftovers.test.ts index 9f2c532ef8b..bed40b1c83a 100644 --- a/test/items/leftovers.test.ts +++ b/test/items/leftovers.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { DamageAnimPhase } from "#phases/damage-anim-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/items/light_ball.test.ts b/test/items/light-ball.test.ts similarity index 99% rename from test/items/light_ball.test.ts rename to test/items/light-ball.test.ts index eebcc81c224..a7f41255ff3 100644 --- a/test/items/light_ball.test.ts +++ b/test/items/light-ball.test.ts @@ -3,7 +3,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { SpeciesStatBoosterModifier } from "#modifiers/modifier"; import i18next from "#plugins/i18n"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { NumberHolder } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/items/lock_capsule.test.ts b/test/items/lock-capsule.test.ts similarity index 96% rename from test/items/lock_capsule.test.ts rename to test/items/lock-capsule.test.ts index e98e6880eb1..01552a4db37 100644 --- a/test/items/lock_capsule.test.ts +++ b/test/items/lock-capsule.test.ts @@ -3,7 +3,7 @@ import { ModifierTier } from "#enums/modifier-tier"; import { MoveId } from "#enums/move-id"; import { UiMode } from "#enums/ui-mode"; import { SelectModifierPhase } from "#phases/select-modifier-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/items/metal_powder.test.ts b/test/items/metal-powder.test.ts similarity index 99% rename from test/items/metal_powder.test.ts rename to test/items/metal-powder.test.ts index 17baa057fd5..4dac8dd39b1 100644 --- a/test/items/metal_powder.test.ts +++ b/test/items/metal-powder.test.ts @@ -3,7 +3,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { SpeciesStatBoosterModifier } from "#modifiers/modifier"; import i18next from "#plugins/i18n"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { NumberHolder } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/items/multi_lens.test.ts b/test/items/multi-lens.test.ts similarity index 99% rename from test/items/multi_lens.test.ts rename to test/items/multi-lens.test.ts index 56d452df9d2..e3cf39e4933 100644 --- a/test/items/multi_lens.test.ts +++ b/test/items/multi-lens.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/items/mystical_rock.test.ts b/test/items/mystical-rock.test.ts similarity index 96% rename from test/items/mystical_rock.test.ts rename to test/items/mystical-rock.test.ts index f1e9bb91ecf..3a29c359582 100644 --- a/test/items/mystical_rock.test.ts +++ b/test/items/mystical-rock.test.ts @@ -2,7 +2,7 @@ import { globalScene } from "#app/global-scene"; import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/items/quick_powder.test.ts b/test/items/quick-powder.test.ts similarity index 99% rename from test/items/quick_powder.test.ts rename to test/items/quick-powder.test.ts index 6c8cb0751c3..2200e8cf96e 100644 --- a/test/items/quick_powder.test.ts +++ b/test/items/quick-powder.test.ts @@ -3,7 +3,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { SpeciesStatBoosterModifier } from "#modifiers/modifier"; import i18next from "#plugins/i18n"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { NumberHolder } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/items/reviver_seed.test.ts b/test/items/reviver-seed.test.ts similarity index 98% rename from test/items/reviver_seed.test.ts rename to test/items/reviver-seed.test.ts index f0929ee0993..268c5497899 100644 --- a/test/items/reviver_seed.test.ts +++ b/test/items/reviver-seed.test.ts @@ -5,7 +5,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { PokemonInstantReviveModifier } from "#modifiers/modifier"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/items/scope_lens.test.ts b/test/items/scope-lens.test.ts similarity index 95% rename from test/items/scope_lens.test.ts rename to test/items/scope-lens.test.ts index 866164629f8..578b0576aaa 100644 --- a/test/items/scope_lens.test.ts +++ b/test/items/scope-lens.test.ts @@ -1,7 +1,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/items/temp_stat_stage_booster.test.ts b/test/items/temp-stat-stage-booster.test.ts similarity index 98% rename from test/items/temp_stat_stage_booster.test.ts rename to test/items/temp-stat-stage-booster.test.ts index 454a469700a..806ff20df6c 100644 --- a/test/items/temp_stat_stage_booster.test.ts +++ b/test/items/temp-stat-stage-booster.test.ts @@ -7,7 +7,7 @@ import { BATTLE_STATS, Stat } from "#enums/stat"; import { UiMode } from "#enums/ui-mode"; import { TempStatStageBoosterModifier } from "#modifiers/modifier"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/items/thick_club.test.ts b/test/items/thick-club.test.ts similarity index 99% rename from test/items/thick_club.test.ts rename to test/items/thick-club.test.ts index 3a993d64a0c..c497cef6338 100644 --- a/test/items/thick_club.test.ts +++ b/test/items/thick-club.test.ts @@ -3,7 +3,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { SpeciesStatBoosterModifier } from "#modifiers/modifier"; import i18next from "#plugins/i18n"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { NumberHolder, randInt } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/items/toxic_orb.test.ts b/test/items/toxic-orb.test.ts similarity index 96% rename from test/items/toxic_orb.test.ts rename to test/items/toxic-orb.test.ts index 0f4acedbfb5..a1888a6aa1d 100644 --- a/test/items/toxic_orb.test.ts +++ b/test/items/toxic-orb.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import i18next from "#plugins/i18n"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/misc.test.ts b/test/misc.test.ts index 5afd8f898c6..96407b78470 100644 --- a/test/misc.test.ts +++ b/test/misc.test.ts @@ -1,5 +1,5 @@ -import { GameManager } from "#test/testUtils/gameManager"; -import { waitUntil } from "#test/testUtils/gameManagerUtils"; +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"; diff --git a/test/moves/ability-ignore-moves.test.ts b/test/moves/ability-ignore-moves.test.ts index 99c5b8f8efe..750d8fe2f20 100644 --- a/test/moves/ability-ignore-moves.test.ts +++ b/test/moves/ability-ignore-moves.test.ts @@ -2,7 +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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/after_you.test.ts b/test/moves/after-you.test.ts similarity index 98% rename from test/moves/after_you.test.ts rename to test/moves/after-you.test.ts index e961342dc36..1625af3dd88 100644 --- a/test/moves/after_you.test.ts +++ b/test/moves/after-you.test.ts @@ -5,7 +5,7 @@ import { MoveResult } from "#enums/move-result"; import { MoveUseMode } from "#enums/move-use-mode"; import { SpeciesId } from "#enums/species-id"; import { MovePhase } from "#phases/move-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/alluring_voice.test.ts b/test/moves/alluring-voice.test.ts similarity index 95% rename from test/moves/alluring_voice.test.ts rename to test/moves/alluring-voice.test.ts index d72d7b4f906..dc01cc1a54e 100644 --- a/test/moves/alluring_voice.test.ts +++ b/test/moves/alluring-voice.test.ts @@ -4,7 +4,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { BerryPhase } from "#phases/berry-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/aromatherapy.test.ts b/test/moves/aromatherapy.test.ts index 39850c4f841..60f9923a2f8 100644 --- a/test/moves/aromatherapy.test.ts +++ b/test/moves/aromatherapy.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/assist.test.ts b/test/moves/assist.test.ts index eff153534dd..08112d911b1 100644 --- a/test/moves/assist.test.ts +++ b/test/moves/assist.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/astonish.test.ts b/test/moves/astonish.test.ts index 7db149c9975..0f7dc526b2d 100644 --- a/test/moves/astonish.test.ts +++ b/test/moves/astonish.test.ts @@ -7,7 +7,7 @@ import { BerryPhase } from "#phases/berry-phase"; import { CommandPhase } from "#phases/command-phase"; import { MoveEndPhase } from "#phases/move-end-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; diff --git a/test/moves/aurora_veil.test.ts b/test/moves/aurora-veil.test.ts similarity index 98% rename from test/moves/aurora_veil.test.ts rename to test/moves/aurora-veil.test.ts index 24e7b1857cc..3c7c86c7fdf 100644 --- a/test/moves/aurora_veil.test.ts +++ b/test/moves/aurora-veil.test.ts @@ -8,7 +8,7 @@ import { SpeciesId } from "#enums/species-id"; import { WeatherType } from "#enums/weather-type"; import type { Pokemon } from "#field/pokemon"; import type { Move } from "#moves/move"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { NumberHolder } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/autotomize.test.ts b/test/moves/autotomize.test.ts index 01021870b88..a8a7309e03e 100644 --- a/test/moves/autotomize.test.ts +++ b/test/moves/autotomize.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/baddy_bad.test.ts b/test/moves/baddy-bad.test.ts similarity index 94% rename from test/moves/baddy_bad.test.ts rename to test/moves/baddy-bad.test.ts index 0af04f0c0c7..5888dd58c31 100644 --- a/test/moves/baddy_bad.test.ts +++ b/test/moves/baddy-bad.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/baneful_bunker.test.ts b/test/moves/baneful-bunker.test.ts similarity index 97% rename from test/moves/baneful_bunker.test.ts rename to test/moves/baneful-bunker.test.ts index 09050dcbb44..da2a8e0418a 100644 --- a/test/moves/baneful_bunker.test.ts +++ b/test/moves/baneful-bunker.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/moves/baton_pass.test.ts b/test/moves/baton-pass.test.ts similarity index 98% rename from test/moves/baton_pass.test.ts rename to test/moves/baton-pass.test.ts index af49ac0db9f..ef1979b223d 100644 --- a/test/moves/baton_pass.test.ts +++ b/test/moves/baton-pass.test.ts @@ -4,7 +4,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/beak_blast.test.ts b/test/moves/beak-blast.test.ts similarity index 98% rename from test/moves/beak_blast.test.ts rename to test/moves/beak-blast.test.ts index 60a6bb75066..71d2d957bed 100644 --- a/test/moves/beak_blast.test.ts +++ b/test/moves/beak-blast.test.ts @@ -6,7 +6,7 @@ import { StatusEffect } from "#enums/status-effect"; import { BerryPhase } from "#phases/berry-phase"; import { MovePhase } from "#phases/move-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/beat_up.test.ts b/test/moves/beat-up.test.ts similarity index 97% rename from test/moves/beat_up.test.ts rename to test/moves/beat-up.test.ts index 8387b6f671b..79d672bd0ed 100644 --- a/test/moves/beat_up.test.ts +++ b/test/moves/beat-up.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { MoveEffectPhase } from "#phases/move-effect-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/belly_drum.test.ts b/test/moves/belly-drum.test.ts similarity index 98% rename from test/moves/belly_drum.test.ts rename to test/moves/belly-drum.test.ts index 9044e10589f..9cbb7adb1ae 100644 --- a/test/moves/belly_drum.test.ts +++ b/test/moves/belly-drum.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { toDmgValue } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/moves/burning_jealousy.test.ts b/test/moves/burning-jealousy.test.ts similarity index 98% rename from test/moves/burning_jealousy.test.ts rename to test/moves/burning-jealousy.test.ts index 9f8dfc29ee4..62f41790582 100644 --- a/test/moves/burning_jealousy.test.ts +++ b/test/moves/burning-jealousy.test.ts @@ -4,7 +4,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/camouflage.test.ts b/test/moves/camouflage.test.ts index 39bf8f6d5b5..badab8ec4a5 100644 --- a/test/moves/camouflage.test.ts +++ b/test/moves/camouflage.test.ts @@ -4,7 +4,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/ceaseless_edge.test.ts b/test/moves/ceaseless-edge.test.ts similarity index 98% rename from test/moves/ceaseless_edge.test.ts rename to test/moves/ceaseless-edge.test.ts index 2d28f4b1a1b..56d7c97ea68 100644 --- a/test/moves/ceaseless_edge.test.ts +++ b/test/moves/ceaseless-edge.test.ts @@ -7,7 +7,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { MoveEffectPhase } from "#phases/move-effect-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; diff --git a/test/moves/chilly_reception.test.ts b/test/moves/chilly-reception.test.ts similarity index 98% rename from test/moves/chilly_reception.test.ts rename to test/moves/chilly-reception.test.ts index f34e61873cc..948b42cb3f2 100644 --- a/test/moves/chilly_reception.test.ts +++ b/test/moves/chilly-reception.test.ts @@ -5,7 +5,7 @@ import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { WeatherType } from "#enums/weather-type"; import { RandomMoveAttr } from "#moves/move"; -import { GameManager } from "#test/testUtils/gameManager"; +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"; diff --git a/test/moves/chloroblast.test.ts b/test/moves/chloroblast.test.ts index c87f79c440a..a6320d2691d 100644 --- a/test/moves/chloroblast.test.ts +++ b/test/moves/chloroblast.test.ts @@ -2,7 +2,7 @@ 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/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/clangorous_soul.test.ts b/test/moves/clangorous-soul.test.ts similarity index 98% rename from test/moves/clangorous_soul.test.ts rename to test/moves/clangorous-soul.test.ts index dc208087bb8..82a0d383f65 100644 --- a/test/moves/clangorous_soul.test.ts +++ b/test/moves/clangorous-soul.test.ts @@ -2,7 +2,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/copycat.test.ts b/test/moves/copycat.test.ts index e6a81cb5627..91e941e2845 100644 --- a/test/moves/copycat.test.ts +++ b/test/moves/copycat.test.ts @@ -5,7 +5,7 @@ import { MoveResult } from "#enums/move-result"; import { MoveUseMode } from "#enums/move-use-mode"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/crafty_shield.test.ts b/test/moves/crafty-shield.test.ts similarity index 97% rename from test/moves/crafty_shield.test.ts rename to test/moves/crafty-shield.test.ts index 98c0dfd7c9a..d0c148c1f41 100644 --- a/test/moves/crafty_shield.test.ts +++ b/test/moves/crafty-shield.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { BerryPhase } from "#phases/berry-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/moves/defog.test.ts b/test/moves/defog.test.ts index 253eac4f22c..820dfaa6bcb 100644 --- a/test/moves/defog.test.ts +++ b/test/moves/defog.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/destiny_bond.test.ts b/test/moves/destiny-bond.test.ts similarity index 99% rename from test/moves/destiny_bond.test.ts rename to test/moves/destiny-bond.test.ts index 29bbfabb09f..48bd29fe662 100644 --- a/test/moves/destiny_bond.test.ts +++ b/test/moves/destiny-bond.test.ts @@ -8,7 +8,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { PokemonInstantReviveModifier } from "#modifiers/modifier"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/diamond_storm.test.ts b/test/moves/diamond-storm.test.ts similarity index 95% rename from test/moves/diamond_storm.test.ts rename to test/moves/diamond-storm.test.ts index 1eb86f94b76..9de7409ca18 100644 --- a/test/moves/diamond_storm.test.ts +++ b/test/moves/diamond-storm.test.ts @@ -3,7 +3,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/dig.test.ts b/test/moves/dig.test.ts index 9d431b78838..2cb8ae05963 100644 --- a/test/moves/dig.test.ts +++ b/test/moves/dig.test.ts @@ -6,7 +6,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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - Dig", () => { diff --git a/test/moves/disable.test.ts b/test/moves/disable.test.ts index f6b1c24ac7d..5543c16fecf 100644 --- a/test/moves/disable.test.ts +++ b/test/moves/disable.test.ts @@ -6,7 +6,7 @@ import { MoveUseMode } from "#enums/move-use-mode"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { RandomMoveAttr } from "#moves/move"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Moves - Disable", () => { diff --git a/test/moves/dive.test.ts b/test/moves/dive.test.ts index c7e4f99f6cb..c34f3dc54dc 100644 --- a/test/moves/dive.test.ts +++ b/test/moves/dive.test.ts @@ -5,7 +5,7 @@ import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { WeatherType } from "#enums/weather-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/doodle.test.ts b/test/moves/doodle.test.ts index 5f4b8ab9b39..c4380720f20 100644 --- a/test/moves/doodle.test.ts +++ b/test/moves/doodle.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/double_team.test.ts b/test/moves/double-team.test.ts similarity index 96% rename from test/moves/double_team.test.ts rename to test/moves/double-team.test.ts index 9cdae33af41..9276a0956e8 100644 --- a/test/moves/double_team.test.ts +++ b/test/moves/double-team.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/dragon_cheer.test.ts b/test/moves/dragon-cheer.test.ts similarity index 98% rename from test/moves/dragon_cheer.test.ts rename to test/moves/dragon-cheer.test.ts index 7d1f35fe2d4..614dd9ab6ab 100644 --- a/test/moves/dragon_cheer.test.ts +++ b/test/moves/dragon-cheer.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/dragon_rage.test.ts b/test/moves/dragon-rage.test.ts similarity index 98% rename from test/moves/dragon_rage.test.ts rename to test/moves/dragon-rage.test.ts index 46e7dfa5a21..1b850ade488 100644 --- a/test/moves/dragon_rage.test.ts +++ b/test/moves/dragon-rage.test.ts @@ -6,7 +6,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import type { EnemyPokemon, PlayerPokemon } from "#field/pokemon"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/dragon_tail.test.ts b/test/moves/dragon-tail.test.ts similarity index 99% rename from test/moves/dragon_tail.test.ts rename to test/moves/dragon-tail.test.ts index c5a77716c56..487647784f7 100644 --- a/test/moves/dragon_tail.test.ts +++ b/test/moves/dragon-tail.test.ts @@ -7,7 +7,7 @@ import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/dynamax_cannon.test.ts b/test/moves/dynamax-cannon.test.ts similarity index 99% rename from test/moves/dynamax_cannon.test.ts rename to test/moves/dynamax-cannon.test.ts index fcbbccd5123..5090a228e23 100644 --- a/test/moves/dynamax_cannon.test.ts +++ b/test/moves/dynamax-cannon.test.ts @@ -5,7 +5,7 @@ import { SpeciesId } from "#enums/species-id"; import type { Move } from "#moves/move"; import { DamageAnimPhase } from "#phases/damage-anim-phase"; import { MoveEffectPhase } from "#phases/move-effect-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/effectiveness.test.ts b/test/moves/effectiveness.test.ts index 58e041fb5c5..0bdef2428a4 100644 --- a/test/moves/effectiveness.test.ts +++ b/test/moves/effectiveness.test.ts @@ -5,7 +5,7 @@ import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { TrainerSlot } from "#enums/trainer-slot"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import Phaser from "phaser"; import { afterEach, beforeAll, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/electrify.test.ts b/test/moves/electrify.test.ts index c3aa925a331..19a2fdfb7a2 100644 --- a/test/moves/electrify.test.ts +++ b/test/moves/electrify.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/electro_shot.test.ts b/test/moves/electro-shot.test.ts similarity index 98% rename from test/moves/electro_shot.test.ts rename to test/moves/electro-shot.test.ts index cb696b162d5..e5031fefb3d 100644 --- a/test/moves/electro_shot.test.ts +++ b/test/moves/electro-shot.test.ts @@ -5,7 +5,7 @@ import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { WeatherType } from "#enums/weather-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/encore.test.ts b/test/moves/encore.test.ts index c20dc194ead..1b0e2ed03f2 100644 --- a/test/moves/encore.test.ts +++ b/test/moves/encore.test.ts @@ -4,7 +4,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/endure.test.ts b/test/moves/endure.test.ts index 717c9d58211..71a16ef4cc1 100644 --- a/test/moves/endure.test.ts +++ b/test/moves/endure.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/entrainment.test.ts b/test/moves/entrainment.test.ts index 9d7da455525..c96cacc8d0b 100644 --- a/test/moves/entrainment.test.ts +++ b/test/moves/entrainment.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/fairy_lock.test.ts b/test/moves/fairy-lock.test.ts similarity index 99% rename from test/moves/fairy_lock.test.ts rename to test/moves/fairy-lock.test.ts index 5f20c39c6f8..eba139fee22 100644 --- a/test/moves/fairy_lock.test.ts +++ b/test/moves/fairy-lock.test.ts @@ -3,7 +3,7 @@ import { ArenaTagSide } from "#enums/arena-tag-side"; import { ArenaTagType } from "#enums/arena-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/fake_out.test.ts b/test/moves/fake-out.test.ts similarity index 98% rename from test/moves/fake_out.test.ts rename to test/moves/fake-out.test.ts index 815de9b9225..8db73681f05 100644 --- a/test/moves/fake_out.test.ts +++ b/test/moves/fake-out.test.ts @@ -1,6 +1,6 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/false_swipe.test.ts b/test/moves/false-swipe.test.ts similarity index 96% rename from test/moves/false_swipe.test.ts rename to test/moves/false-swipe.test.ts index 0aa16ff43e1..30547036e69 100644 --- a/test/moves/false_swipe.test.ts +++ b/test/moves/false-swipe.test.ts @@ -2,7 +2,7 @@ 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/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/fell_stinger.test.ts b/test/moves/fell-stinger.test.ts similarity index 99% rename from test/moves/fell_stinger.test.ts rename to test/moves/fell-stinger.test.ts index c3ea17904af..9f482202c47 100644 --- a/test/moves/fell_stinger.test.ts +++ b/test/moves/fell-stinger.test.ts @@ -5,7 +5,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; import { WeatherType } from "#enums/weather-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/fillet_away.test.ts b/test/moves/fillet-away.test.ts similarity index 98% rename from test/moves/fillet_away.test.ts rename to test/moves/fillet-away.test.ts index 3ba4f5740eb..c4c87e1d00e 100644 --- a/test/moves/fillet_away.test.ts +++ b/test/moves/fillet-away.test.ts @@ -2,7 +2,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { toDmgValue } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/moves/first-attack-double-power.test.ts b/test/moves/first-attack-double-power.test.ts index 7d1d9c4d762..4172f843872 100644 --- a/test/moves/first-attack-double-power.test.ts +++ b/test/moves/first-attack-double-power.test.ts @@ -4,7 +4,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { MoveUseMode } from "#enums/move-use-mode"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/fissure.test.ts b/test/moves/fissure.test.ts index 6fadf867e8a..8a8673811ce 100644 --- a/test/moves/fissure.test.ts +++ b/test/moves/fissure.test.ts @@ -5,7 +5,7 @@ import { Stat } from "#enums/stat"; import type { EnemyPokemon, PlayerPokemon } from "#field/pokemon"; import { DamageAnimPhase } from "#phases/damage-anim-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/flame_burst.test.ts b/test/moves/flame-burst.test.ts similarity index 98% rename from test/moves/flame_burst.test.ts rename to test/moves/flame-burst.test.ts index 76d9a100e37..ce82b46d0fc 100644 --- a/test/moves/flame_burst.test.ts +++ b/test/moves/flame-burst.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { Pokemon } from "#field/pokemon"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/flower_shield.test.ts b/test/moves/flower-shield.test.ts similarity index 98% rename from test/moves/flower_shield.test.ts rename to test/moves/flower-shield.test.ts index 16a1efacf35..425d0443ca7 100644 --- a/test/moves/flower_shield.test.ts +++ b/test/moves/flower-shield.test.ts @@ -6,7 +6,7 @@ import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/fly.test.ts b/test/moves/fly.test.ts index c27db3686b4..3682fce3d0c 100644 --- a/test/moves/fly.test.ts +++ b/test/moves/fly.test.ts @@ -6,7 +6,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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/focus_punch.test.ts b/test/moves/focus-punch.test.ts similarity index 98% rename from test/moves/focus_punch.test.ts rename to test/moves/focus-punch.test.ts index 5123e99c6ff..c67053ef7ec 100644 --- a/test/moves/focus_punch.test.ts +++ b/test/moves/focus-punch.test.ts @@ -6,7 +6,7 @@ import { MessagePhase } from "#phases/message-phase"; import { MoveHeaderPhase } from "#phases/move-header-phase"; import { SwitchSummonPhase } from "#phases/switch-summon-phase"; import { TurnStartPhase } from "#phases/turn-start-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +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"; diff --git a/test/moves/follow_me.test.ts b/test/moves/follow-me.test.ts similarity index 98% rename from test/moves/follow_me.test.ts rename to test/moves/follow-me.test.ts index 891b1844512..2624a1fd267 100644 --- a/test/moves/follow_me.test.ts +++ b/test/moves/follow-me.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/moves/foresight.test.ts b/test/moves/foresight.test.ts index 3163f65dd79..c3b29d8fabb 100644 --- a/test/moves/foresight.test.ts +++ b/test/moves/foresight.test.ts @@ -1,7 +1,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { MoveEffectPhase } from "#phases/move-effect-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/forests_curse.test.ts b/test/moves/forests-curse.test.ts similarity index 95% rename from test/moves/forests_curse.test.ts rename to test/moves/forests-curse.test.ts index 812d3c57217..4467a5c4037 100644 --- a/test/moves/forests_curse.test.ts +++ b/test/moves/forests-curse.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/freeze_dry.test.ts b/test/moves/freeze-dry.test.ts similarity index 99% rename from test/moves/freeze_dry.test.ts rename to test/moves/freeze-dry.test.ts index 5639330db1b..5d84d6be795 100644 --- a/test/moves/freeze_dry.test.ts +++ b/test/moves/freeze-dry.test.ts @@ -4,7 +4,7 @@ import { Challenges } from "#enums/challenges"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/freezy_frost.test.ts b/test/moves/freezy-frost.test.ts similarity index 98% rename from test/moves/freezy_frost.test.ts rename to test/moves/freezy-frost.test.ts index 9cf2f38b286..8a8a47013ca 100644 --- a/test/moves/freezy_frost.test.ts +++ b/test/moves/freezy-frost.test.ts @@ -3,7 +3,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/fusion_bolt.test.ts b/test/moves/fusion-bolt.test.ts similarity index 95% rename from test/moves/fusion_bolt.test.ts rename to test/moves/fusion-bolt.test.ts index ad6810cb412..aa8073c4c1f 100644 --- a/test/moves/fusion_bolt.test.ts +++ b/test/moves/fusion-bolt.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/fusion_flare_bolt.test.ts b/test/moves/fusion-flare-bolt.test.ts similarity index 99% rename from test/moves/fusion_flare_bolt.test.ts rename to test/moves/fusion-flare-bolt.test.ts index 1777eb5e07e..42cc1248325 100644 --- a/test/moves/fusion_flare_bolt.test.ts +++ b/test/moves/fusion-flare-bolt.test.ts @@ -8,7 +8,7 @@ import { DamageAnimPhase } from "#phases/damage-anim-phase"; import { MoveEffectPhase } from "#phases/move-effect-phase"; import { MoveEndPhase } from "#phases/move-end-phase"; import { MovePhase } from "#phases/move-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/fusion_flare.test.ts b/test/moves/fusion-flare.test.ts similarity index 96% rename from test/moves/fusion_flare.test.ts rename to test/moves/fusion-flare.test.ts index d86f784bce4..be8ce4eeec4 100644 --- a/test/moves/fusion_flare.test.ts +++ b/test/moves/fusion-flare.test.ts @@ -2,7 +2,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { TurnStartPhase } from "#phases/turn-start-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/future_sight.test.ts b/test/moves/future-sight.test.ts similarity index 95% rename from test/moves/future_sight.test.ts rename to test/moves/future-sight.test.ts index 96b71b8b0f1..53e93412570 100644 --- a/test/moves/future_sight.test.ts +++ b/test/moves/future-sight.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/gastro_acid.test.ts b/test/moves/gastro-acid.test.ts similarity index 98% rename from test/moves/gastro_acid.test.ts rename to test/moves/gastro-acid.test.ts index 9b8e8f33250..59177528492 100644 --- a/test/moves/gastro_acid.test.ts +++ b/test/moves/gastro-acid.test.ts @@ -4,7 +4,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - Gastro Acid", () => { diff --git a/test/moves/geomancy.test.ts b/test/moves/geomancy.test.ts index 100c4d85637..b01ad756f9b 100644 --- a/test/moves/geomancy.test.ts +++ b/test/moves/geomancy.test.ts @@ -4,7 +4,7 @@ import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import type { EffectiveStat } from "#enums/stat"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/gigaton_hammer.test.ts b/test/moves/gigaton-hammer.test.ts similarity index 97% rename from test/moves/gigaton_hammer.test.ts rename to test/moves/gigaton-hammer.test.ts index 69186886f40..6043f9d7f51 100644 --- a/test/moves/gigaton_hammer.test.ts +++ b/test/moves/gigaton-hammer.test.ts @@ -1,7 +1,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/glaive_rush.test.ts b/test/moves/glaive-rush.test.ts similarity index 98% rename from test/moves/glaive_rush.test.ts rename to test/moves/glaive-rush.test.ts index a09c35604b9..f20abd68500 100644 --- a/test/moves/glaive_rush.test.ts +++ b/test/moves/glaive-rush.test.ts @@ -2,7 +2,7 @@ import { allMoves } from "#data/data-lists"; import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/growth.test.ts b/test/moves/growth.test.ts index 94df21271a1..5737f32d891 100644 --- a/test/moves/growth.test.ts +++ b/test/moves/growth.test.ts @@ -4,7 +4,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { EnemyCommandPhase } from "#phases/enemy-command-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/grudge.test.ts b/test/moves/grudge.test.ts index ff18cd5d6a4..6f5df077d9f 100644 --- a/test/moves/grudge.test.ts +++ b/test/moves/grudge.test.ts @@ -2,7 +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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/guard_split.test.ts b/test/moves/guard-split.test.ts similarity index 97% rename from test/moves/guard_split.test.ts rename to test/moves/guard-split.test.ts index 7972296f6ae..fa5dc162a6c 100644 --- a/test/moves/guard_split.test.ts +++ b/test/moves/guard-split.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/guard_swap.test.ts b/test/moves/guard-swap.test.ts similarity index 96% rename from test/moves/guard_swap.test.ts rename to test/moves/guard-swap.test.ts index eda4349b9f8..e7f8ed1df91 100644 --- a/test/moves/guard_swap.test.ts +++ b/test/moves/guard-swap.test.ts @@ -4,7 +4,7 @@ import { SpeciesId } from "#enums/species-id"; import { BATTLE_STATS, Stat } from "#enums/stat"; import { MoveEndPhase } from "#phases/move-end-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/hard_press.test.ts b/test/moves/hard-press.test.ts similarity index 97% rename from test/moves/hard_press.test.ts rename to test/moves/hard-press.test.ts index f61f5084752..f269373e697 100644 --- a/test/moves/hard_press.test.ts +++ b/test/moves/hard-press.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { Move } from "#moves/move"; import { MoveEffectPhase } from "#phases/move-effect-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/haze.test.ts b/test/moves/haze.test.ts index 990bbc62ae8..179a06fba09 100644 --- a/test/moves/haze.test.ts +++ b/test/moves/haze.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/heal_bell.test.ts b/test/moves/heal-bell.test.ts similarity index 98% rename from test/moves/heal_bell.test.ts rename to test/moves/heal-bell.test.ts index e7f6548713a..8b526601e49 100644 --- a/test/moves/heal_bell.test.ts +++ b/test/moves/heal-bell.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/heal_block.test.ts b/test/moves/heal-block.test.ts similarity index 98% rename from test/moves/heal_block.test.ts rename to test/moves/heal-block.test.ts index 0f3ff0df683..4e4a9355467 100644 --- a/test/moves/heal_block.test.ts +++ b/test/moves/heal-block.test.ts @@ -6,7 +6,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { WeatherType } from "#enums/weather-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/heart_swap.test.ts b/test/moves/heart-swap.test.ts similarity index 96% rename from test/moves/heart_swap.test.ts rename to test/moves/heart-swap.test.ts index c90b13b88ef..e876ec06646 100644 --- a/test/moves/heart_swap.test.ts +++ b/test/moves/heart-swap.test.ts @@ -4,7 +4,7 @@ import { SpeciesId } from "#enums/species-id"; import { BATTLE_STATS } from "#enums/stat"; import { MoveEndPhase } from "#phases/move-end-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/hyper_beam.test.ts b/test/moves/hyper-beam.test.ts similarity index 97% rename from test/moves/hyper_beam.test.ts rename to test/moves/hyper-beam.test.ts index aa3ecfe910b..510dac5f662 100644 --- a/test/moves/hyper_beam.test.ts +++ b/test/moves/hyper-beam.test.ts @@ -5,7 +5,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { BerryPhase } from "#phases/berry-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/imprison.test.ts b/test/moves/imprison.test.ts index 0007c07985c..ed2213bbc7b 100644 --- a/test/moves/imprison.test.ts +++ b/test/moves/imprison.test.ts @@ -3,7 +3,7 @@ import { ArenaTagType } from "#enums/arena-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/instruct.test.ts b/test/moves/instruct.test.ts index c73091a0eea..c34626f5e76 100644 --- a/test/moves/instruct.test.ts +++ b/test/moves/instruct.test.ts @@ -9,7 +9,7 @@ import { Stat } from "#enums/stat"; import type { Pokemon } from "#field/pokemon"; import { RandomMoveAttr } from "#moves/move"; import type { MovePhase } from "#phases/move-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import type { TurnMove } from "#types/turn-move"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/jaw_lock.test.ts b/test/moves/jaw-lock.test.ts similarity index 98% rename from test/moves/jaw_lock.test.ts rename to test/moves/jaw-lock.test.ts index b5e98fbf6d8..919e07ece9a 100644 --- a/test/moves/jaw_lock.test.ts +++ b/test/moves/jaw-lock.test.ts @@ -7,7 +7,7 @@ import { BerryPhase } from "#phases/berry-phase"; import { FaintPhase } from "#phases/faint-phase"; import { MoveEffectPhase } from "#phases/move-effect-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/lash_out.test.ts b/test/moves/lash-out.test.ts similarity index 96% rename from test/moves/lash_out.test.ts rename to test/moves/lash-out.test.ts index b529351e01f..06629997b71 100644 --- a/test/moves/lash_out.test.ts +++ b/test/moves/lash-out.test.ts @@ -3,7 +3,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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/last-resort.test.ts b/test/moves/last-resort.test.ts index 4eaf1ee7f5d..e6f4faacd09 100644 --- a/test/moves/last-resort.test.ts +++ b/test/moves/last-resort.test.ts @@ -4,7 +4,7 @@ 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/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/last_respects.test.ts b/test/moves/last-respects.test.ts similarity index 99% rename from test/moves/last_respects.test.ts rename to test/moves/last-respects.test.ts index e438971125a..9dadb316144 100644 --- a/test/moves/last_respects.test.ts +++ b/test/moves/last-respects.test.ts @@ -5,7 +5,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { Move } from "#moves/move"; import { MoveEffectPhase } from "#phases/move-effect-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/light_screen.test.ts b/test/moves/light-screen.test.ts similarity index 98% rename from test/moves/light_screen.test.ts rename to test/moves/light-screen.test.ts index 5dcdc3c271c..04f7f59f184 100644 --- a/test/moves/light_screen.test.ts +++ b/test/moves/light-screen.test.ts @@ -8,7 +8,7 @@ import { SpeciesId } from "#enums/species-id"; import type { Pokemon } from "#field/pokemon"; import type { Move } from "#moves/move"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { NumberHolder } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/lucky_chant.test.ts b/test/moves/lucky-chant.test.ts similarity index 98% rename from test/moves/lucky_chant.test.ts rename to test/moves/lucky-chant.test.ts index afcdd901382..1128f79b1d2 100644 --- a/test/moves/lucky_chant.test.ts +++ b/test/moves/lucky-chant.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Moves - Lucky Chant", () => { diff --git a/test/moves/lunar_blessing.test.ts b/test/moves/lunar-blessing.test.ts similarity index 97% rename from test/moves/lunar_blessing.test.ts rename to test/moves/lunar-blessing.test.ts index 481156748e3..480c7fb3b31 100644 --- a/test/moves/lunar_blessing.test.ts +++ b/test/moves/lunar-blessing.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/lunar_dance.test.ts b/test/moves/lunar-dance.test.ts similarity index 97% rename from test/moves/lunar_dance.test.ts rename to test/moves/lunar-dance.test.ts index 3fcf953a37c..7386d15079b 100644 --- a/test/moves/lunar_dance.test.ts +++ b/test/moves/lunar-dance.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/magic_coat.test.ts b/test/moves/magic-coat.test.ts similarity index 99% rename from test/moves/magic_coat.test.ts rename to test/moves/magic-coat.test.ts index 4a026ceb84e..2ed09499e95 100644 --- a/test/moves/magic_coat.test.ts +++ b/test/moves/magic-coat.test.ts @@ -9,7 +9,7 @@ import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Moves - Magic Coat", () => { diff --git a/test/moves/magnet_rise.test.ts b/test/moves/magnet-rise.test.ts similarity index 96% rename from test/moves/magnet_rise.test.ts rename to test/moves/magnet-rise.test.ts index da76c178be8..181113b5328 100644 --- a/test/moves/magnet_rise.test.ts +++ b/test/moves/magnet-rise.test.ts @@ -1,6 +1,6 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/make_it_rain.test.ts b/test/moves/make-it-rain.test.ts similarity index 98% rename from test/moves/make_it_rain.test.ts rename to test/moves/make-it-rain.test.ts index 47f1bc89fc1..ab242d0c3a0 100644 --- a/test/moves/make_it_rain.test.ts +++ b/test/moves/make-it-rain.test.ts @@ -4,7 +4,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { MoveEndPhase } from "#phases/move-end-phase"; import { StatStageChangePhase } from "#phases/stat-stage-change-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/mat_block.test.ts b/test/moves/mat-block.test.ts similarity index 97% rename from test/moves/mat_block.test.ts rename to test/moves/mat-block.test.ts index 954e2a8135d..0870a38f062 100644 --- a/test/moves/mat_block.test.ts +++ b/test/moves/mat-block.test.ts @@ -5,7 +5,7 @@ import { Stat } from "#enums/stat"; import { BerryPhase } from "#phases/berry-phase"; import { CommandPhase } from "#phases/command-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/moves/metal_burst.test.ts b/test/moves/metal-burst.test.ts similarity index 97% rename from test/moves/metal_burst.test.ts rename to test/moves/metal-burst.test.ts index c99b4324878..024f12d76af 100644 --- a/test/moves/metal_burst.test.ts +++ b/test/moves/metal-burst.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/metronome.test.ts b/test/moves/metronome.test.ts index 8ca9e63582e..e39d24c81db 100644 --- a/test/moves/metronome.test.ts +++ b/test/moves/metronome.test.ts @@ -9,7 +9,7 @@ import { MoveUseMode } from "#enums/move-use-mode"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import type { RandomMoveAttr } from "#moves/move"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/miracle_eye.test.ts b/test/moves/miracle-eye.test.ts similarity index 95% rename from test/moves/miracle_eye.test.ts rename to test/moves/miracle-eye.test.ts index d77da857068..9ed3824fc28 100644 --- a/test/moves/miracle_eye.test.ts +++ b/test/moves/miracle-eye.test.ts @@ -2,7 +2,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { MoveEffectPhase } from "#phases/move-effect-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/mirror_move.test.ts b/test/moves/mirror-move.test.ts similarity index 97% rename from test/moves/mirror_move.test.ts rename to test/moves/mirror-move.test.ts index 7f833c08bf5..0253932026b 100644 --- a/test/moves/mirror_move.test.ts +++ b/test/moves/mirror-move.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/mist.test.ts b/test/moves/mist.test.ts index b420b234e15..c1a3777e2a5 100644 --- a/test/moves/mist.test.ts +++ b/test/moves/mist.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/multi_target.test.ts b/test/moves/multi-target.test.ts similarity index 98% rename from test/moves/multi_target.test.ts rename to test/moves/multi-target.test.ts index a58fb8d3a6b..53480a6505f 100644 --- a/test/moves/multi_target.test.ts +++ b/test/moves/multi-target.test.ts @@ -2,7 +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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { toDmgValue } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/nightmare.test.ts b/test/moves/nightmare.test.ts index 07579a6790c..7b3772d8b71 100644 --- a/test/moves/nightmare.test.ts +++ b/test/moves/nightmare.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/obstruct.test.ts b/test/moves/obstruct.test.ts index ef589213c74..9abc60be129 100644 --- a/test/moves/obstruct.test.ts +++ b/test/moves/obstruct.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/octolock.test.ts b/test/moves/octolock.test.ts index bf2f8dc5865..09992dd52c7 100644 --- a/test/moves/octolock.test.ts +++ b/test/moves/octolock.test.ts @@ -3,7 +3,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/order_up.test.ts b/test/moves/order-up.test.ts similarity index 98% rename from test/moves/order_up.test.ts rename to test/moves/order-up.test.ts index 2c9702fd6cb..2e77d4b2fa7 100644 --- a/test/moves/order_up.test.ts +++ b/test/moves/order-up.test.ts @@ -6,7 +6,7 @@ import { PokemonAnimType } from "#enums/pokemon-anim-type"; import { SpeciesId } from "#enums/species-id"; import type { EffectiveStat } from "#enums/stat"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/parting_shot.test.ts b/test/moves/parting-shot.test.ts similarity index 99% rename from test/moves/parting_shot.test.ts rename to test/moves/parting-shot.test.ts index 86a14330a3e..7785bdd3a2f 100644 --- a/test/moves/parting_shot.test.ts +++ b/test/moves/parting-shot.test.ts @@ -6,7 +6,7 @@ import { BerryPhase } from "#phases/berry-phase"; import { FaintPhase } from "#phases/faint-phase"; import { MessagePhase } from "#phases/message-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, test } from "vitest"; diff --git a/test/moves/payback.test.ts b/test/moves/payback.test.ts index 20e832288a3..f9692bd480f 100644 --- a/test/moves/payback.test.ts +++ b/test/moves/payback.test.ts @@ -4,7 +4,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { PokeballType } from "#enums/pokeball"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, type MockInstance, vi } from "vitest"; diff --git a/test/moves/plasma_fists.test.ts b/test/moves/plasma-fists.test.ts similarity index 98% rename from test/moves/plasma_fists.test.ts rename to test/moves/plasma-fists.test.ts index 7a5ba77b62d..569fb1d5c0d 100644 --- a/test/moves/plasma_fists.test.ts +++ b/test/moves/plasma-fists.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/pledge_moves.test.ts b/test/moves/pledge-moves.test.ts similarity index 99% rename from test/moves/pledge_moves.test.ts rename to test/moves/pledge-moves.test.ts index bd0c981517c..c67519d417b 100644 --- a/test/moves/pledge_moves.test.ts +++ b/test/moves/pledge-moves.test.ts @@ -7,7 +7,7 @@ import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { toDmgValue } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/pollen_puff.test.ts b/test/moves/pollen-puff.test.ts similarity index 97% rename from test/moves/pollen_puff.test.ts rename to test/moves/pollen-puff.test.ts index d372f72a390..ecd208f777b 100644 --- a/test/moves/pollen_puff.test.ts +++ b/test/moves/pollen-puff.test.ts @@ -2,7 +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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/powder.test.ts b/test/moves/powder.test.ts index 3e60c0d9fec..17f64a95179 100644 --- a/test/moves/powder.test.ts +++ b/test/moves/powder.test.ts @@ -6,7 +6,7 @@ import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { BerryPhase } from "#phases/berry-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/power_shift.test.ts b/test/moves/power-shift.test.ts similarity index 96% rename from test/moves/power_shift.test.ts rename to test/moves/power-shift.test.ts index 069d793a794..adfd1f0aaa9 100644 --- a/test/moves/power_shift.test.ts +++ b/test/moves/power-shift.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/power_split.test.ts b/test/moves/power-split.test.ts similarity index 97% rename from test/moves/power_split.test.ts rename to test/moves/power-split.test.ts index ef6fda419ca..1eaabf6090d 100644 --- a/test/moves/power_split.test.ts +++ b/test/moves/power-split.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/power_swap.test.ts b/test/moves/power-swap.test.ts similarity index 96% rename from test/moves/power_swap.test.ts rename to test/moves/power-swap.test.ts index cdd52fbc524..b25db40e64c 100644 --- a/test/moves/power_swap.test.ts +++ b/test/moves/power-swap.test.ts @@ -4,7 +4,7 @@ import { SpeciesId } from "#enums/species-id"; import { BATTLE_STATS, Stat } from "#enums/stat"; import { MoveEndPhase } from "#phases/move-end-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/power_trick.test.ts b/test/moves/power-trick.test.ts similarity index 98% rename from test/moves/power_trick.test.ts rename to test/moves/power-trick.test.ts index 29a8107d891..3ddd27212e1 100644 --- a/test/moves/power_trick.test.ts +++ b/test/moves/power-trick.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/protect.test.ts b/test/moves/protect.test.ts index 9fd54d44891..7da54f268e0 100644 --- a/test/moves/protect.test.ts +++ b/test/moves/protect.test.ts @@ -7,7 +7,7 @@ import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; diff --git a/test/moves/psycho_shift.test.ts b/test/moves/psycho-shift.test.ts similarity index 96% rename from test/moves/psycho_shift.test.ts rename to test/moves/psycho-shift.test.ts index 6414a91543b..f2e762f1381 100644 --- a/test/moves/psycho_shift.test.ts +++ b/test/moves/psycho-shift.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/purify.test.ts b/test/moves/purify.test.ts index a5d7d86851b..88e0da802a3 100644 --- a/test/moves/purify.test.ts +++ b/test/moves/purify.test.ts @@ -5,7 +5,7 @@ import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import type { EnemyPokemon, PlayerPokemon } from "#field/pokemon"; import { MoveEndPhase } from "#phases/move-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/moves/quash.test.ts b/test/moves/quash.test.ts index 632d37a4e13..91ff5581b9e 100644 --- a/test/moves/quash.test.ts +++ b/test/moves/quash.test.ts @@ -5,7 +5,7 @@ import { MoveResult } from "#enums/move-result"; import { MoveUseMode } from "#enums/move-use-mode"; import { SpeciesId } from "#enums/species-id"; import { WeatherType } from "#enums/weather-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/quick_guard.test.ts b/test/moves/quick-guard.test.ts similarity index 98% rename from test/moves/quick_guard.test.ts rename to test/moves/quick-guard.test.ts index 5e2e1ae1f24..d14eada2445 100644 --- a/test/moves/quick_guard.test.ts +++ b/test/moves/quick-guard.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/moves/rage_fist.test.ts b/test/moves/rage-fist.test.ts similarity index 99% rename from test/moves/rage_fist.test.ts rename to test/moves/rage-fist.test.ts index d7928ddd310..8ed0a71306b 100644 --- a/test/moves/rage_fist.test.ts +++ b/test/moves/rage-fist.test.ts @@ -5,7 +5,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { Move } from "#moves/move"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/rage_powder.test.ts b/test/moves/rage-powder.test.ts similarity index 97% rename from test/moves/rage_powder.test.ts rename to test/moves/rage-powder.test.ts index a0b836f0917..9ae81720e32 100644 --- a/test/moves/rage_powder.test.ts +++ b/test/moves/rage-powder.test.ts @@ -2,7 +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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/moves/reflect_type.test.ts b/test/moves/reflect-type.test.ts similarity index 96% rename from test/moves/reflect_type.test.ts rename to test/moves/reflect-type.test.ts index 499c167bee0..ceaff4019b3 100644 --- a/test/moves/reflect_type.test.ts +++ b/test/moves/reflect-type.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/reflect.test.ts b/test/moves/reflect.test.ts index 47c49ea4d36..228730e9fb6 100644 --- a/test/moves/reflect.test.ts +++ b/test/moves/reflect.test.ts @@ -8,7 +8,7 @@ import { SpeciesId } from "#enums/species-id"; import type { Pokemon } from "#field/pokemon"; import type { Move } from "#moves/move"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { NumberHolder } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/relic_song.test.ts b/test/moves/relic-song.test.ts similarity index 97% rename from test/moves/relic_song.test.ts rename to test/moves/relic-song.test.ts index 36c46769515..62069ac3cd3 100644 --- a/test/moves/relic_song.test.ts +++ b/test/moves/relic-song.test.ts @@ -3,7 +3,7 @@ import { Challenges } from "#enums/challenges"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/retaliate.test.ts b/test/moves/retaliate.test.ts index 3eefbe3ceb6..9e564c52a99 100644 --- a/test/moves/retaliate.test.ts +++ b/test/moves/retaliate.test.ts @@ -2,7 +2,7 @@ import { allMoves } from "#data/data-lists"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { Move } from "#moves/move"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/revival_blessing.test.ts b/test/moves/revival-blessing.test.ts similarity index 98% rename from test/moves/revival_blessing.test.ts rename to test/moves/revival-blessing.test.ts index a9a6bd0fd7d..89a1996fe03 100644 --- a/test/moves/revival_blessing.test.ts +++ b/test/moves/revival-blessing.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { toDmgValue } from "#utils/common"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/role_play.test.ts b/test/moves/role-play.test.ts similarity index 96% rename from test/moves/role_play.test.ts rename to test/moves/role-play.test.ts index dda7f319cd5..af9fc68efa4 100644 --- a/test/moves/role_play.test.ts +++ b/test/moves/role-play.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/rollout.test.ts b/test/moves/rollout.test.ts index eed61f82ab4..c1c66f4ab39 100644 --- a/test/moves/rollout.test.ts +++ b/test/moves/rollout.test.ts @@ -2,7 +2,7 @@ import { allMoves } from "#data/data-lists"; import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/roost.test.ts b/test/moves/roost.test.ts index 30a71721d03..e4ea09e245c 100644 --- a/test/moves/roost.test.ts +++ b/test/moves/roost.test.ts @@ -5,7 +5,7 @@ import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { MoveEffectPhase } from "#phases/move-effect-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/moves/round.test.ts b/test/moves/round.test.ts index a706fd15e9b..517e2202d4d 100644 --- a/test/moves/round.test.ts +++ b/test/moves/round.test.ts @@ -4,7 +4,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { MoveEffectPhase } from "#phases/move-effect-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/safeguard.test.ts b/test/moves/safeguard.test.ts index 2651d8473be..19b56cd759f 100644 --- a/test/moves/safeguard.test.ts +++ b/test/moves/safeguard.test.ts @@ -4,7 +4,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/scale_shot.test.ts b/test/moves/scale-shot.test.ts similarity index 97% rename from test/moves/scale_shot.test.ts rename to test/moves/scale-shot.test.ts index 4e420f6b3ef..7e5c60577ce 100644 --- a/test/moves/scale_shot.test.ts +++ b/test/moves/scale-shot.test.ts @@ -8,7 +8,7 @@ import { DamageAnimPhase } from "#phases/damage-anim-phase"; import { MoveEffectPhase } from "#phases/move-effect-phase"; import { MoveEndPhase } from "#phases/move-end-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/secret_power.test.ts b/test/moves/secret-power.test.ts similarity index 98% rename from test/moves/secret_power.test.ts rename to test/moves/secret-power.test.ts index 8ec69fb276a..16090bebcbe 100644 --- a/test/moves/secret_power.test.ts +++ b/test/moves/secret-power.test.ts @@ -8,7 +8,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/shed_tail.test.ts b/test/moves/shed-tail.test.ts similarity index 97% rename from test/moves/shed_tail.test.ts rename to test/moves/shed-tail.test.ts index 8a837a642c9..ff2b29e846d 100644 --- a/test/moves/shed_tail.test.ts +++ b/test/moves/shed-tail.test.ts @@ -3,7 +3,7 @@ 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/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/shell_side_arm.test.ts b/test/moves/shell-side-arm.test.ts similarity index 97% rename from test/moves/shell_side_arm.test.ts rename to test/moves/shell-side-arm.test.ts index 685cebce4cf..32f37fcc8ac 100644 --- a/test/moves/shell_side_arm.test.ts +++ b/test/moves/shell-side-arm.test.ts @@ -4,7 +4,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { Move, ShellSideArmCategoryAttr } from "#moves/move"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/shell_trap.test.ts b/test/moves/shell-trap.test.ts similarity index 98% rename from test/moves/shell_trap.test.ts rename to test/moves/shell-trap.test.ts index c484d1195aa..d2908278d93 100644 --- a/test/moves/shell_trap.test.ts +++ b/test/moves/shell-trap.test.ts @@ -6,7 +6,7 @@ import { SpeciesId } from "#enums/species-id"; import { BerryPhase } from "#phases/berry-phase"; import { MoveEndPhase } from "#phases/move-end-phase"; import { MovePhase } from "#phases/move-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/simple_beam.test.ts b/test/moves/simple-beam.test.ts similarity index 95% rename from test/moves/simple_beam.test.ts rename to test/moves/simple-beam.test.ts index 106977aea84..f45c19c690e 100644 --- a/test/moves/simple_beam.test.ts +++ b/test/moves/simple-beam.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/sketch.test.ts b/test/moves/sketch.test.ts index 10ad31c35eb..fff9be97e2d 100644 --- a/test/moves/sketch.test.ts +++ b/test/moves/sketch.test.ts @@ -7,7 +7,7 @@ import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { RandomMoveAttr } from "#moves/move"; import { PokemonMove } from "#moves/pokemon-move"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/skill_swap.test.ts b/test/moves/skill-swap.test.ts similarity index 96% rename from test/moves/skill_swap.test.ts rename to test/moves/skill-swap.test.ts index d5ba509b0df..50a0a232f6e 100644 --- a/test/moves/skill_swap.test.ts +++ b/test/moves/skill-swap.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/sleep_talk.test.ts b/test/moves/sleep-talk.test.ts similarity index 97% rename from test/moves/sleep_talk.test.ts rename to test/moves/sleep-talk.test.ts index 972c54463e2..8593f4b4d07 100644 --- a/test/moves/sleep_talk.test.ts +++ b/test/moves/sleep-talk.test.ts @@ -4,7 +4,7 @@ import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/solar_beam.test.ts b/test/moves/solar-beam.test.ts similarity index 98% rename from test/moves/solar_beam.test.ts rename to test/moves/solar-beam.test.ts index 32400abfc0f..f4347493de5 100644 --- a/test/moves/solar_beam.test.ts +++ b/test/moves/solar-beam.test.ts @@ -5,7 +5,7 @@ import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { WeatherType } from "#enums/weather-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/sparkly_swirl.test.ts b/test/moves/sparkly-swirl.test.ts similarity index 97% rename from test/moves/sparkly_swirl.test.ts rename to test/moves/sparkly-swirl.test.ts index d58b6efe990..6e43211ed50 100644 --- a/test/moves/sparkly_swirl.test.ts +++ b/test/moves/sparkly-swirl.test.ts @@ -3,7 +3,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/spectral_thief.test.ts b/test/moves/spectral-thief.test.ts similarity index 99% rename from test/moves/spectral_thief.test.ts rename to test/moves/spectral-thief.test.ts index acb3e22cf6c..dd988ac667a 100644 --- a/test/moves/spectral_thief.test.ts +++ b/test/moves/spectral-thief.test.ts @@ -5,7 +5,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/speed_swap.test.ts b/test/moves/speed-swap.test.ts similarity index 96% rename from test/moves/speed_swap.test.ts rename to test/moves/speed-swap.test.ts index e0c06bfb0f7..b67ad68746a 100644 --- a/test/moves/speed_swap.test.ts +++ b/test/moves/speed-swap.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/spikes.test.ts b/test/moves/spikes.test.ts index 424aecb5c3c..0055945cef9 100644 --- a/test/moves/spikes.test.ts +++ b/test/moves/spikes.test.ts @@ -4,7 +4,7 @@ import { ArenaTagSide } from "#enums/arena-tag-side"; import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/spit_up.test.ts b/test/moves/spit-up.test.ts similarity index 99% rename from test/moves/spit_up.test.ts rename to test/moves/spit-up.test.ts index 03e0cee1e4b..22722cfed2b 100644 --- a/test/moves/spit_up.test.ts +++ b/test/moves/spit-up.test.ts @@ -9,7 +9,7 @@ import { Stat } from "#enums/stat"; import type { Move } from "#moves/move"; import { MovePhase } from "#phases/move-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/spotlight.test.ts b/test/moves/spotlight.test.ts index 4feff5eb719..69510c1d852 100644 --- a/test/moves/spotlight.test.ts +++ b/test/moves/spotlight.test.ts @@ -2,7 +2,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/moves/steamroller.test.ts b/test/moves/steamroller.test.ts index a9da98c1429..2219b95e733 100644 --- a/test/moves/steamroller.test.ts +++ b/test/moves/steamroller.test.ts @@ -4,7 +4,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import type { DamageCalculationResult } from "#types/damage-result"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/stockpile.test.ts b/test/moves/stockpile.test.ts index efc1757738a..5b170c10fcb 100644 --- a/test/moves/stockpile.test.ts +++ b/test/moves/stockpile.test.ts @@ -5,7 +5,7 @@ import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/struggle.test.ts b/test/moves/struggle.test.ts index 2d624f6d338..21c4e204974 100644 --- a/test/moves/struggle.test.ts +++ b/test/moves/struggle.test.ts @@ -1,7 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/substitute.test.ts b/test/moves/substitute.test.ts index 39418fb5b99..15fd770805a 100644 --- a/test/moves/substitute.test.ts +++ b/test/moves/substitute.test.ts @@ -15,7 +15,7 @@ import { StatusEffect } from "#enums/status-effect"; import { UiMode } from "#enums/ui-mode"; import { StealHeldItemChanceAttr } from "#moves/move"; import type { CommandPhase } from "#phases/command-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/swallow.test.ts b/test/moves/swallow.test.ts index 176b00b030c..1ae31517cb6 100644 --- a/test/moves/swallow.test.ts +++ b/test/moves/swallow.test.ts @@ -7,7 +7,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { MovePhase } from "#phases/move-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/synchronoise.test.ts b/test/moves/synchronoise.test.ts index fe4a316a32a..3cfeaf04af9 100644 --- a/test/moves/synchronoise.test.ts +++ b/test/moves/synchronoise.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/syrup_bomb.test.ts b/test/moves/syrup-bomb.test.ts similarity index 98% rename from test/moves/syrup_bomb.test.ts rename to test/moves/syrup-bomb.test.ts index f45070d81a5..3e5bddf1e7b 100644 --- a/test/moves/syrup_bomb.test.ts +++ b/test/moves/syrup-bomb.test.ts @@ -4,7 +4,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/tackle.test.ts b/test/moves/tackle.test.ts index 998afd23f9d..23abd650e55 100644 --- a/test/moves/tackle.test.ts +++ b/test/moves/tackle.test.ts @@ -3,7 +3,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { EnemyCommandPhase } from "#phases/enemy-command-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/tail_whip.test.ts b/test/moves/tail-whip.test.ts similarity index 96% rename from test/moves/tail_whip.test.ts rename to test/moves/tail-whip.test.ts index 272816a88a6..c872b2535e3 100644 --- a/test/moves/tail_whip.test.ts +++ b/test/moves/tail-whip.test.ts @@ -4,7 +4,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { EnemyCommandPhase } from "#phases/enemy-command-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/tailwind.test.ts b/test/moves/tailwind.test.ts index 1c8701de5bc..436c854066f 100644 --- a/test/moves/tailwind.test.ts +++ b/test/moves/tailwind.test.ts @@ -4,7 +4,7 @@ import { ArenaTagType } from "#enums/arena-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/tar_shot.test.ts b/test/moves/tar-shot.test.ts similarity index 98% rename from test/moves/tar_shot.test.ts rename to test/moves/tar-shot.test.ts index c2ae397e43a..719b5e4c7fe 100644 --- a/test/moves/tar_shot.test.ts +++ b/test/moves/tar-shot.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/taunt.test.ts b/test/moves/taunt.test.ts index ba76551708b..f16a019ce2c 100644 --- a/test/moves/taunt.test.ts +++ b/test/moves/taunt.test.ts @@ -3,7 +3,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/telekinesis.test.ts b/test/moves/telekinesis.test.ts index 92d7f8cc885..4c452c24ec6 100644 --- a/test/moves/telekinesis.test.ts +++ b/test/moves/telekinesis.test.ts @@ -5,7 +5,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/tera_blast.test.ts b/test/moves/tera-blast.test.ts similarity index 99% rename from test/moves/tera_blast.test.ts rename to test/moves/tera-blast.test.ts index d6c16c31544..37dd8f53eaf 100644 --- a/test/moves/tera_blast.test.ts +++ b/test/moves/tera-blast.test.ts @@ -6,7 +6,7 @@ import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import type { Move, TeraMoveCategoryAttr } from "#moves/move"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/tera_starstorm.test.ts b/test/moves/tera-starstorm.test.ts similarity index 98% rename from test/moves/tera_starstorm.test.ts rename to test/moves/tera-starstorm.test.ts index a63573b360d..d13ab3fb3b0 100644 --- a/test/moves/tera_starstorm.test.ts +++ b/test/moves/tera-starstorm.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/thousand_arrows.test.ts b/test/moves/thousand-arrows.test.ts similarity index 98% rename from test/moves/thousand_arrows.test.ts rename to test/moves/thousand-arrows.test.ts index 3c7bacfbb2b..e42e92d35d2 100644 --- a/test/moves/thousand_arrows.test.ts +++ b/test/moves/thousand-arrows.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { BerryPhase } from "#phases/berry-phase"; import { MoveEffectPhase } from "#phases/move-effect-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/throat_chop.test.ts b/test/moves/throat-chop.test.ts similarity index 96% rename from test/moves/throat_chop.test.ts rename to test/moves/throat-chop.test.ts index 1a17cb1fba2..f5e6a978e3d 100644 --- a/test/moves/throat_chop.test.ts +++ b/test/moves/throat-chop.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/thunder_wave.test.ts b/test/moves/thunder-wave.test.ts similarity index 98% rename from test/moves/thunder_wave.test.ts rename to test/moves/thunder-wave.test.ts index 06a24e454fa..84408ace7e9 100644 --- a/test/moves/thunder_wave.test.ts +++ b/test/moves/thunder-wave.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import type { EnemyPokemon } from "#field/pokemon"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/tidy_up.test.ts b/test/moves/tidy-up.test.ts similarity index 98% rename from test/moves/tidy_up.test.ts rename to test/moves/tidy-up.test.ts index c96718e2332..8dd74e4ab78 100644 --- a/test/moves/tidy_up.test.ts +++ b/test/moves/tidy-up.test.ts @@ -6,7 +6,7 @@ import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { MoveEndPhase } from "#phases/move-end-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/torment.test.ts b/test/moves/torment.test.ts index 71a4f3cb504..1ed4529fcbd 100644 --- a/test/moves/torment.test.ts +++ b/test/moves/torment.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { TurnEndPhase } from "#phases/turn-end-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/toxic_spikes.test.ts b/test/moves/toxic-spikes.test.ts similarity index 98% rename from test/moves/toxic_spikes.test.ts rename to test/moves/toxic-spikes.test.ts index 69f09ce966a..1315eaa31c3 100644 --- a/test/moves/toxic_spikes.test.ts +++ b/test/moves/toxic-spikes.test.ts @@ -7,7 +7,7 @@ import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import type { SessionSaveData } from "#system/game-data"; import { GameData } from "#system/game-data"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { decrypt, encrypt } from "#utils/data"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/toxic.test.ts b/test/moves/toxic.test.ts index 5aaa4e3e85d..13af6cf48fd 100644 --- a/test/moves/toxic.test.ts +++ b/test/moves/toxic.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/transform-imposter.test.ts b/test/moves/transform-imposter.test.ts index c12542e64e9..b1631130154 100644 --- a/test/moves/transform-imposter.test.ts +++ b/test/moves/transform-imposter.test.ts @@ -12,7 +12,7 @@ import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; import type { EnemyPokemon } from "#field/pokemon"; import { Pokemon } from "#field/pokemon"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, type MockInstance, vi } from "vitest"; diff --git a/test/moves/trick_or_treat.test.ts b/test/moves/trick-or-treat.test.ts similarity index 95% rename from test/moves/trick_or_treat.test.ts rename to test/moves/trick-or-treat.test.ts index 4e563c97ddc..095cda873e0 100644 --- a/test/moves/trick_or_treat.test.ts +++ b/test/moves/trick-or-treat.test.ts @@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/triple_arrows.test.ts b/test/moves/triple-arrows.test.ts similarity index 97% rename from test/moves/triple_arrows.test.ts rename to test/moves/triple-arrows.test.ts index a60c7106a21..2f7c50f8a44 100644 --- a/test/moves/triple_arrows.test.ts +++ b/test/moves/triple-arrows.test.ts @@ -3,7 +3,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import type { FlinchAttr, Move, StatStageChangeAttr } from "#moves/move"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/u_turn.test.ts b/test/moves/u-turn.test.ts similarity index 98% rename from test/moves/u_turn.test.ts rename to test/moves/u-turn.test.ts index cf8b91511ca..fb34490fdf4 100644 --- a/test/moves/u_turn.test.ts +++ b/test/moves/u-turn.test.ts @@ -2,7 +2,7 @@ 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 { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/upper_hand.test.ts b/test/moves/upper-hand.test.ts similarity index 98% rename from test/moves/upper_hand.test.ts rename to test/moves/upper-hand.test.ts index f03a84397f2..91f3a34b9c6 100644 --- a/test/moves/upper_hand.test.ts +++ b/test/moves/upper-hand.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/moves/whirlwind.test.ts b/test/moves/whirlwind.test.ts index 9def19c4668..90bbf722224 100644 --- a/test/moves/whirlwind.test.ts +++ b/test/moves/whirlwind.test.ts @@ -11,7 +11,7 @@ import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { TrainerType } from "#enums/trainer-type"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/moves/wide_guard.test.ts b/test/moves/wide-guard.test.ts similarity index 97% rename from test/moves/wide_guard.test.ts rename to test/moves/wide-guard.test.ts index 7de1faea900..e599829e1b9 100644 --- a/test/moves/wide_guard.test.ts +++ b/test/moves/wide-guard.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { BerryPhase } from "#phases/berry-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; diff --git a/test/moves/will_o_wisp.test.ts b/test/moves/will-o-wisp.test.ts similarity index 96% rename from test/moves/will_o_wisp.test.ts rename to test/moves/will-o-wisp.test.ts index 6f878e1198c..5cb94c4617c 100644 --- a/test/moves/will_o_wisp.test.ts +++ b/test/moves/will-o-wisp.test.ts @@ -3,7 +3,7 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/mystery-encounter/encounter-test-utils.ts b/test/mystery-encounter/encounter-test-utils.ts index 6b6a570d318..784e8ae4950 100644 --- a/test/mystery-encounter/encounter-test-utils.ts +++ b/test/mystery-encounter/encounter-test-utils.ts @@ -13,7 +13,7 @@ import { MysteryEncounterRewardsPhase, } from "#phases/mystery-encounter-phases"; import { VictoryPhase } from "#phases/victory-phase"; -import type { GameManager } from "#test/testUtils/gameManager"; +import type { GameManager } from "#test/test-utils/game-manager"; import type { MessageUiHandler } from "#ui/message-ui-handler"; import type { MysteryEncounterUiHandler } from "#ui/mystery-encounter-ui-handler"; import type { OptionSelectUiHandler } from "#ui/option-select-ui-handler"; diff --git a/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts b/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts index a2832052611..93cf4537c53 100644 --- a/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts +++ b/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts @@ -16,8 +16,8 @@ import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import i18next from "i18next"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts b/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts index 969ac812907..562482dd520 100644 --- a/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts +++ b/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts @@ -17,7 +17,7 @@ import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import i18next from "i18next"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts b/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts index 97326e89a83..d903568785a 100644 --- a/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts +++ b/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts @@ -14,8 +14,8 @@ import * as MysteryEncounters from "#mystery-encounters/mystery-encounters"; import { HUMAN_TRANSITABLE_BIOMES } from "#mystery-encounters/mystery-encounters"; import { SelectModifierPhase } from "#phases/select-modifier-phase"; import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import i18next from "i18next"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/berries-abound-encounter.test.ts b/test/mystery-encounter/encounters/berries-abound-encounter.test.ts index 5af89ebc02c..3d29c04cab7 100644 --- a/test/mystery-encounter/encounters/berries-abound-encounter.test.ts +++ b/test/mystery-encounter/encounters/berries-abound-encounter.test.ts @@ -17,8 +17,8 @@ import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; 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 80f4c00c2a6..205bf996815 100644 --- a/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts +++ b/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts @@ -20,8 +20,8 @@ import { runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/clowning-around-encounter.test.ts b/test/mystery-encounter/encounters/clowning-around-encounter.test.ts index af99834d082..b573701d568 100644 --- a/test/mystery-encounter/encounters/clowning-around-encounter.test.ts +++ b/test/mystery-encounter/encounters/clowning-around-encounter.test.ts @@ -31,8 +31,8 @@ import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import type { OptionSelectUiHandler } from "#ui/option-select-ui-handler"; import type { PartyUiHandler } from "#ui/party-ui-handler"; import { getPokemonSpecies } from "#utils/pokemon-utils"; diff --git a/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts b/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts index 8ef499fe7f4..97d0ce31367 100644 --- a/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts +++ b/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts @@ -20,7 +20,7 @@ import { runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/delibirdy-encounter.test.ts b/test/mystery-encounter/encounters/delibirdy-encounter.test.ts index 0fb6d2d09b8..16c726f1de6 100644 --- a/test/mystery-encounter/encounters/delibirdy-encounter.test.ts +++ b/test/mystery-encounter/encounters/delibirdy-encounter.test.ts @@ -26,7 +26,7 @@ import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/delibirdy"; diff --git a/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts b/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts index 807526d2683..3d84d70b47e 100644 --- a/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts +++ b/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts @@ -11,7 +11,7 @@ import * as MysteryEncounters from "#mystery-encounters/mystery-encounters"; import { CIVILIZATION_ENCOUNTER_BIOMES } from "#mystery-encounters/mystery-encounters"; import { SelectModifierPhase } from "#phases/select-modifier-phase"; import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/field-trip-encounter.test.ts b/test/mystery-encounter/encounters/field-trip-encounter.test.ts index 4390c80d255..8502137cc6e 100644 --- a/test/mystery-encounter/encounters/field-trip-encounter.test.ts +++ b/test/mystery-encounter/encounters/field-trip-encounter.test.ts @@ -11,7 +11,7 @@ import { FieldTripEncounter } from "#mystery-encounters/field-trip-encounter"; import * as MysteryEncounters from "#mystery-encounters/mystery-encounters"; import { SelectModifierPhase } from "#phases/select-modifier-phase"; import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import i18next from "i18next"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts b/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts index 1fb1cbfdbc8..8ec9b4cb345 100644 --- a/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts +++ b/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts @@ -25,8 +25,8 @@ import { runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import i18next from "i18next"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts b/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts index 588c126852f..8149212f00f 100644 --- a/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts +++ b/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts @@ -18,8 +18,8 @@ import { runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts b/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts index 43102cbc80d..b66d0e95ad0 100644 --- a/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts +++ b/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts @@ -21,8 +21,8 @@ import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; 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 2a959df76f2..2ac55dabe1c 100644 --- a/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts +++ b/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts @@ -15,7 +15,7 @@ import * as MysteryEncounters from "#mystery-encounters/mystery-encounters"; import { CIVILIZATION_ENCOUNTER_BIOMES } from "#mystery-encounters/mystery-encounters"; import { SelectModifierPhase } from "#phases/select-modifier-phase"; import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import * as Utils from "#utils/common"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts b/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts index 2186fe43e23..d29f8fe6a82 100644 --- a/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts +++ b/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts @@ -13,8 +13,8 @@ import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import i18next from "i18next"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts b/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts index ee952f3809e..5412f269122 100644 --- a/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts +++ b/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts @@ -18,8 +18,8 @@ import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { TrainerConfig } from "#trainers/trainer-config"; import { TrainerPartyCompoundTemplate, TrainerPartyTemplate } from "#trainers/trainer-party-template"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; diff --git a/test/mystery-encounter/encounters/part-timer-encounter.test.ts b/test/mystery-encounter/encounters/part-timer-encounter.test.ts index 1bbda8b77e0..63eea8bbca2 100644 --- a/test/mystery-encounter/encounters/part-timer-encounter.test.ts +++ b/test/mystery-encounter/encounters/part-timer-encounter.test.ts @@ -15,7 +15,7 @@ import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/partTimer"; diff --git a/test/mystery-encounter/encounters/safari-zone.test.ts b/test/mystery-encounter/encounters/safari-zone.test.ts index 252198139df..ec43dcfb69b 100644 --- a/test/mystery-encounter/encounters/safari-zone.test.ts +++ b/test/mystery-encounter/encounters/safari-zone.test.ts @@ -14,8 +14,8 @@ import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/safariZone"; diff --git a/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts b/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts index 6ecf3162607..43d497c57bb 100644 --- a/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts +++ b/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts @@ -16,8 +16,8 @@ import { runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import i18next from "i18next"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts b/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts index 471a26aa532..4556f7a7f45 100644 --- a/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts +++ b/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts @@ -19,8 +19,8 @@ import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/theExpertPokemonBreeder"; diff --git a/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts b/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts index 81329c5552f..611a103dab2 100644 --- a/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts +++ b/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts @@ -17,8 +17,8 @@ import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/thePokemonSalesman"; diff --git a/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts b/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts index 9a78cd99f93..a314a14485f 100644 --- a/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts +++ b/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts @@ -24,8 +24,8 @@ import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts b/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts index 0541826e569..ae2f9fd79ff 100644 --- a/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts +++ b/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts @@ -21,8 +21,8 @@ import { PartyHealPhase } from "#phases/party-heal-phase"; import { SelectModifierPhase } from "#phases/select-modifier-phase"; import { VictoryPhase } from "#phases/victory-phase"; import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts b/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts index 48b6ce79488..133fbfb10ba 100644 --- a/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts +++ b/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts @@ -27,8 +27,8 @@ import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import * as Utils from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; diff --git a/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts b/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts index a9ebfda496a..24d7960049e 100644 --- a/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts +++ b/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts @@ -24,8 +24,8 @@ import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/encounters/weird-dream-encounter.test.ts b/test/mystery-encounter/encounters/weird-dream-encounter.test.ts index f68818bbfe4..e9fcc9797d1 100644 --- a/test/mystery-encounter/encounters/weird-dream-encounter.test.ts +++ b/test/mystery-encounter/encounters/weird-dream-encounter.test.ts @@ -16,8 +16,8 @@ import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/mystery-encounter-utils.test.ts b/test/mystery-encounter/mystery-encounter-utils.test.ts index 745b11b7e73..adcc3111319 100644 --- a/test/mystery-encounter/mystery-encounter-utils.test.ts +++ b/test/mystery-encounter/mystery-encounter-utils.test.ts @@ -18,8 +18,8 @@ import { } from "#mystery-encounters/encounter-pokemon-utils"; import { MysteryEncounter } from "#mystery-encounters/mystery-encounter"; import { MessagePhase } from "#phases/message-phase"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/mystery-encounter/mystery-encounter.test.ts b/test/mystery-encounter/mystery-encounter.test.ts index c8ac7078788..71bc9aec008 100644 --- a/test/mystery-encounter/mystery-encounter.test.ts +++ b/test/mystery-encounter/mystery-encounter.test.ts @@ -2,7 +2,7 @@ import type { BattleScene } from "#app/battle-scene"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; import { MysteryEncounterPhase } from "#phases/mystery-encounter-phases"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/phases/form-change-phase.test.ts b/test/phases/form-change-phase.test.ts index 4d3af280043..3caf824b252 100644 --- a/test/phases/form-change-phase.test.ts +++ b/test/phases/form-change-phase.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { generateModifierType } from "#mystery-encounters/encounter-phase-utils"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/phases/frenzy-move-reset.test.ts b/test/phases/frenzy-move-reset.test.ts index c922a121526..93406ddd577 100644 --- a/test/phases/frenzy-move-reset.test.ts +++ b/test/phases/frenzy-move-reset.test.ts @@ -4,7 +4,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/phases/game-over-phase.test.ts b/test/phases/game-over-phase.test.ts index d679b812fc0..201eebc5264 100644 --- a/test/phases/game-over-phase.test.ts +++ b/test/phases/game-over-phase.test.ts @@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Unlockables } from "#enums/unlockables"; import { achvs } from "#system/achv"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/phases/learn-move-phase.test.ts b/test/phases/learn-move-phase.test.ts index b7e7175a46c..77902a0d959 100644 --- a/test/phases/learn-move-phase.test.ts +++ b/test/phases/learn-move-phase.test.ts @@ -3,7 +3,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { LearnMovePhase } from "#phases/learn-move-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/phases/mystery-encounter-phase.test.ts b/test/phases/mystery-encounter-phase.test.ts index 3c41028e4b7..ad71a4151ac 100644 --- a/test/phases/mystery-encounter-phase.test.ts +++ b/test/phases/mystery-encounter-phase.test.ts @@ -4,7 +4,7 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { MysteryEncounterOptionSelectedPhase, MysteryEncounterPhase } from "#phases/mystery-encounter-phases"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import type { MessageUiHandler } from "#ui/message-ui-handler"; import type { MysteryEncounterUiHandler } from "#ui/mystery-encounter-ui-handler"; import i18next from "i18next"; diff --git a/test/phases/phases.test.ts b/test/phases/phases.test.ts index daa63fe2adc..27ee4114701 100644 --- a/test/phases/phases.test.ts +++ b/test/phases/phases.test.ts @@ -3,7 +3,7 @@ import { UiMode } from "#enums/ui-mode"; import { LoginPhase } from "#phases/login-phase"; import { TitlePhase } from "#phases/title-phase"; import { UnavailablePhase } from "#phases/unavailable-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/phases/select-modifier-phase.test.ts b/test/phases/select-modifier-phase.test.ts index 565fbe8e439..ae4cebb1866 100644 --- a/test/phases/select-modifier-phase.test.ts +++ b/test/phases/select-modifier-phase.test.ts @@ -10,8 +10,8 @@ import { PlayerPokemon } from "#field/pokemon"; import type { CustomModifierSettings } from "#modifiers/modifier-type"; import { ModifierTypeOption } from "#modifiers/modifier-type"; import { SelectModifierPhase } from "#phases/select-modifier-phase"; -import { GameManager } from "#test/testUtils/gameManager"; -import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; +import { GameManager } from "#test/test-utils/game-manager"; +import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { shiftCharCodes } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; diff --git a/test/plugins/api/pokerogue-account-api.test.ts b/test/plugins/api/pokerogue-account-api.test.ts index 578b6ba041a..b830289c773 100644 --- a/test/plugins/api/pokerogue-account-api.test.ts +++ b/test/plugins/api/pokerogue-account-api.test.ts @@ -1,8 +1,8 @@ import { PokerogueAccountApi } from "#api/pokerogue-account-api"; import { SESSION_ID_COOKIE_NAME } from "#app/constants"; -import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; -import { getApiBaseUrl } from "#test/testUtils/testUtils"; -import type { AccountInfoResponse } from "#types/PokerogueAccountApi"; +import { initServerForApiTests } from "#test/test-utils/test-file-initialization"; +import { getApiBaseUrl } from "#test/test-utils/test-utils"; +import type { AccountInfoResponse } from "#types/api/pokerogue-account-api"; import * as CookieUtils from "#utils/cookies"; import * as cookies from "#utils/cookies"; import { HttpResponse, http } from "msw"; diff --git a/test/plugins/api/pokerogue-admin-api.test.ts b/test/plugins/api/pokerogue-admin-api.test.ts index e36f45801b6..a40fa23698f 100644 --- a/test/plugins/api/pokerogue-admin-api.test.ts +++ b/test/plugins/api/pokerogue-admin-api.test.ts @@ -1,6 +1,6 @@ import { PokerogueAdminApi } from "#api/pokerogue-admin-api"; -import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; -import { getApiBaseUrl } from "#test/testUtils/testUtils"; +import { initServerForApiTests } from "#test/test-utils/test-file-initialization"; +import { getApiBaseUrl } from "#test/test-utils/test-utils"; import type { LinkAccountToDiscordIdRequest, LinkAccountToGoogledIdRequest, @@ -8,7 +8,7 @@ import type { SearchAccountResponse, UnlinkAccountFromDiscordIdRequest, UnlinkAccountFromGoogledIdRequest, -} from "#types/PokerogueAdminApi"; +} from "#types/api/pokerogue-admin-api"; import { HttpResponse, http } from "msw"; import type { SetupServerApi } from "msw/node"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/plugins/api/pokerogue-api.test.ts b/test/plugins/api/pokerogue-api.test.ts index b9ebbe0f685..afd7b3dd608 100644 --- a/test/plugins/api/pokerogue-api.test.ts +++ b/test/plugins/api/pokerogue-api.test.ts @@ -1,7 +1,7 @@ import { pokerogueApi } from "#api/pokerogue-api"; -import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; -import { getApiBaseUrl } from "#test/testUtils/testUtils"; -import type { TitleStatsResponse } from "#types/PokerogueApi"; +import { initServerForApiTests } from "#test/test-utils/test-file-initialization"; +import { getApiBaseUrl } from "#test/test-utils/test-utils"; +import type { TitleStatsResponse } from "#types/api/pokerogue-api-types"; import { HttpResponse, http } from "msw"; import type { SetupServerApi } from "msw/node"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/plugins/api/pokerogue-daily-api.test.ts b/test/plugins/api/pokerogue-daily-api.test.ts index 6399c80781e..ef5dfddada5 100644 --- a/test/plugins/api/pokerogue-daily-api.test.ts +++ b/test/plugins/api/pokerogue-daily-api.test.ts @@ -1,7 +1,7 @@ import { PokerogueDailyApi } from "#api/pokerogue-daily-api"; -import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; -import { getApiBaseUrl } from "#test/testUtils/testUtils"; -import type { GetDailyRankingsPageCountRequest, GetDailyRankingsRequest } from "#types/PokerogueDailyApi"; +import { initServerForApiTests } from "#test/test-utils/test-file-initialization"; +import { getApiBaseUrl } from "#test/test-utils/test-utils"; +import type { GetDailyRankingsPageCountRequest, GetDailyRankingsRequest } from "#types/api/pokerogue-daily-api"; import { type RankingEntry, ScoreboardCategory } from "#ui/daily-run-scoreboard"; import { HttpResponse, http } from "msw"; import type { SetupServerApi } from "msw/node"; diff --git a/test/plugins/api/pokerogue-savedata-api.test.ts b/test/plugins/api/pokerogue-savedata-api.test.ts index d465759bdfc..5dbaf9ff542 100644 --- a/test/plugins/api/pokerogue-savedata-api.test.ts +++ b/test/plugins/api/pokerogue-savedata-api.test.ts @@ -1,7 +1,7 @@ import { PokerogueSavedataApi } from "#api/pokerogue-savedata-api"; -import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; -import { getApiBaseUrl } from "#test/testUtils/testUtils"; -import type { UpdateAllSavedataRequest } from "#types/PokerogueSavedataApi"; +import { initServerForApiTests } from "#test/test-utils/test-file-initialization"; +import { getApiBaseUrl } from "#test/test-utils/test-utils"; +import type { UpdateAllSavedataRequest } from "#types/api/pokerogue-save-data-api"; import { HttpResponse, http } from "msw"; import type { SetupServerApi } from "msw/node"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/plugins/api/pokerogue-session-savedata-api.test.ts b/test/plugins/api/pokerogue-session-savedata-api.test.ts index e95697ab72e..d7ee2703405 100644 --- a/test/plugins/api/pokerogue-session-savedata-api.test.ts +++ b/test/plugins/api/pokerogue-session-savedata-api.test.ts @@ -1,7 +1,7 @@ import { PokerogueSessionSavedataApi } from "#api/pokerogue-session-savedata-api"; import type { SessionSaveData } from "#system/game-data"; -import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; -import { getApiBaseUrl } from "#test/testUtils/testUtils"; +import { initServerForApiTests } from "#test/test-utils/test-file-initialization"; +import { getApiBaseUrl } from "#test/test-utils/test-utils"; import type { ClearSessionSavedataRequest, ClearSessionSavedataResponse, @@ -9,7 +9,7 @@ import type { GetSessionSavedataRequest, NewClearSessionSavedataRequest, UpdateSessionSavedataRequest, -} from "#types/PokerogueSessionSavedataApi"; +} from "#types/api/pokerogue-session-save-data-api"; import { HttpResponse, http } from "msw"; import type { SetupServerApi } from "msw/node"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/plugins/api/pokerogue-system-savedata-api.test.ts b/test/plugins/api/pokerogue-system-savedata-api.test.ts index 0bec6dae16b..d6e4fe18eed 100644 --- a/test/plugins/api/pokerogue-system-savedata-api.test.ts +++ b/test/plugins/api/pokerogue-system-savedata-api.test.ts @@ -1,13 +1,13 @@ import { PokerogueSystemSavedataApi } from "#api/pokerogue-system-savedata-api"; import type { SystemSaveData } from "#system/game-data"; -import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; -import { getApiBaseUrl } from "#test/testUtils/testUtils"; +import { initServerForApiTests } from "#test/test-utils/test-file-initialization"; +import { getApiBaseUrl } from "#test/test-utils/test-utils"; import type { GetSystemSavedataRequest, UpdateSystemSavedataRequest, VerifySystemSavedataRequest, VerifySystemSavedataResponse, -} from "#types/PokerogueSystemSavedataApi"; +} from "#types/api/pokerogue-system-save-data-api"; import { HttpResponse, http } from "msw"; import type { SetupServerApi } from "msw/node"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/reload.test.ts b/test/reload.test.ts index a1cdfcb392a..018a5e334ef 100644 --- a/test/reload.test.ts +++ b/test/reload.test.ts @@ -5,8 +5,8 @@ import { GameModes } from "#enums/game-modes"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; -import { GameManager } from "#test/testUtils/gameManager"; -import type { MockClock } from "#test/testUtils/mocks/mockClock"; +import { GameManager } from "#test/test-utils/game-manager"; +import type { MockClock } from "#test/test-utils/mocks/mock-clock"; import type { OptionSelectUiHandler } from "#ui/option-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/settingMenu/helpers/inGameManip.ts b/test/setting-menu/helpers/in-game-manip.ts similarity index 98% rename from test/settingMenu/helpers/inGameManip.ts rename to test/setting-menu/helpers/in-game-manip.ts index c19c6745300..acc119b2cc2 100644 --- a/test/settingMenu/helpers/inGameManip.ts +++ b/test/setting-menu/helpers/in-game-manip.ts @@ -1,4 +1,4 @@ -import { getIconForLatestInput, getSettingNameWithKeycode } from "#inputs/configHandler"; +import { getIconForLatestInput, getSettingNameWithKeycode } from "#inputs/config-handler"; import { SettingKeyboard } from "#system/settings-keyboard"; import { expect } from "vitest"; diff --git a/test/settingMenu/helpers/menuManip.ts b/test/setting-menu/helpers/menu-manip.ts similarity index 99% rename from test/settingMenu/helpers/menuManip.ts rename to test/setting-menu/helpers/menu-manip.ts index 37c0f823559..29e096608f1 100644 --- a/test/settingMenu/helpers/menuManip.ts +++ b/test/setting-menu/helpers/menu-manip.ts @@ -9,7 +9,7 @@ import { getKeyWithKeycode, getKeyWithSettingName, getSettingNameWithKeycode, -} from "#inputs/configHandler"; +} from "#inputs/config-handler"; import { SettingKeyboard } from "#system/settings-keyboard"; import { expect } from "vitest"; diff --git a/test/settingMenu/rebinding_setting.test.ts b/test/setting-menu/rebinding-setting.test.ts similarity index 99% rename from test/settingMenu/rebinding_setting.test.ts rename to test/setting-menu/rebinding-setting.test.ts index b738861c1ee..6c065a0dd3b 100644 --- a/test/settingMenu/rebinding_setting.test.ts +++ b/test/setting-menu/rebinding-setting.test.ts @@ -1,11 +1,11 @@ import type { InterfaceConfig } from "#app/inputs-controller"; import { Button } from "#enums/buttons"; import { Device } from "#enums/devices"; -import cfg_keyboard_qwerty from "#inputs/cfg_keyboard_qwerty"; -import { getKeyWithKeycode, getKeyWithSettingName } from "#inputs/configHandler"; +import cfg_keyboard_qwerty from "#inputs/cfg-keyboard-qwerty"; +import { getKeyWithKeycode, getKeyWithSettingName } from "#inputs/config-handler"; import { SettingKeyboard } from "#system/settings-keyboard"; -import { InGameManip } from "#test/settingMenu/helpers/inGameManip"; -import { MenuManip } from "#test/settingMenu/helpers/menuManip"; +import { InGameManip } from "#test/setting-menu/helpers/in-game-manip"; +import { MenuManip } from "#test/setting-menu/helpers/menu-manip"; import { deepCopy } from "#utils/data"; import { beforeEach, describe, expect, it } from "vitest"; diff --git a/test/sprites/pokemonSprite.test.ts b/test/sprites/pokemon-sprite.test.ts similarity index 99% rename from test/sprites/pokemonSprite.test.ts rename to test/sprites/pokemon-sprite.test.ts index 019dc51a8e2..bf945636a71 100644 --- a/test/sprites/pokemonSprite.test.ts +++ b/test/sprites/pokemon-sprite.test.ts @@ -1,4 +1,4 @@ -import { getAppRootDir } from "#test/sprites/spritesUtils"; +import { getAppRootDir } from "#test/sprites/sprites-utils"; import fs from "fs"; import path from "path"; import { beforeAll, describe, expect, it } from "vitest"; diff --git a/test/sprites/spritesUtils.ts b/test/sprites/sprites-utils.ts similarity index 100% rename from test/sprites/spritesUtils.ts rename to test/sprites/sprites-utils.ts diff --git a/test/system/game_data.test.ts b/test/system/game-data.test.ts similarity index 97% rename from test/system/game_data.test.ts rename to test/system/game-data.test.ts index 5daed0b2f1b..18775f310b7 100644 --- a/test/system/game_data.test.ts +++ b/test/system/game-data.test.ts @@ -4,7 +4,7 @@ import * as bypassLoginModule from "#app/global-vars/bypass-login"; import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import type { SessionSaveData } from "#system/game-data"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/testUtils/errorInterceptor.ts b/test/test-utils/error-interceptor.ts similarity index 100% rename from test/testUtils/errorInterceptor.ts rename to test/test-utils/error-interceptor.ts diff --git a/test/testUtils/fakeMobile.html b/test/test-utils/fakeMobile.html similarity index 100% rename from test/testUtils/fakeMobile.html rename to test/test-utils/fakeMobile.html diff --git a/test/testUtils/gameManagerUtils.ts b/test/test-utils/game-manager-utils.ts similarity index 100% rename from test/testUtils/gameManagerUtils.ts rename to test/test-utils/game-manager-utils.ts diff --git a/test/testUtils/gameManager.ts b/test/test-utils/game-manager.ts similarity index 94% rename from test/testUtils/gameManager.ts rename to test/test-utils/game-manager.ts index b6d0da49902..43d9e256d53 100644 --- a/test/testUtils/gameManager.ts +++ b/test/test-utils/game-manager.ts @@ -30,22 +30,22 @@ import { TitlePhase } from "#phases/title-phase"; 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/testUtils/errorInterceptor"; -import { generateStarter, waitUntil } from "#test/testUtils/gameManagerUtils"; -import { GameWrapper } from "#test/testUtils/gameWrapper"; -import { ChallengeModeHelper } from "#test/testUtils/helpers/challengeModeHelper"; -import { ClassicModeHelper } from "#test/testUtils/helpers/classicModeHelper"; -import { DailyModeHelper } from "#test/testUtils/helpers/dailyModeHelper"; -import { FieldHelper } from "#test/testUtils/helpers/field-helper"; -import { ModifierHelper } from "#test/testUtils/helpers/modifiersHelper"; -import { MoveHelper } from "#test/testUtils/helpers/moveHelper"; -import { OverridesHelper } from "#test/testUtils/helpers/overridesHelper"; -import { ReloadHelper } from "#test/testUtils/helpers/reloadHelper"; -import { SettingsHelper } from "#test/testUtils/helpers/settingsHelper"; -import type { InputsHandler } from "#test/testUtils/inputsHandler"; -import { MockFetch } from "#test/testUtils/mocks/mockFetch"; -import { PhaseInterceptor } from "#test/testUtils/phaseInterceptor"; -import { TextInterceptor } from "#test/testUtils/TextInterceptor"; +import { ErrorInterceptor } from "#test/test-utils/error-interceptor"; +import { generateStarter, waitUntil } 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"; +import { DailyModeHelper } from "#test/test-utils/helpers/daily-mode-helper"; +import { FieldHelper } from "#test/test-utils/helpers/field-helper"; +import { ModifierHelper } from "#test/test-utils/helpers/modifiers-helper"; +import { MoveHelper } from "#test/test-utils/helpers/move-helper"; +import { OverridesHelper } from "#test/test-utils/helpers/overrides-helper"; +import { ReloadHelper } from "#test/test-utils/helpers/reload-helper"; +import { SettingsHelper } from "#test/test-utils/helpers/settings-helper"; +import type { InputsHandler } from "#test/test-utils/inputs-handler"; +import { MockFetch } from "#test/test-utils/mocks/mock-fetch"; +import { PhaseInterceptor } from "#test/test-utils/phase-interceptor"; +import { TextInterceptor } from "#test/test-utils/text-interceptor"; import type { BallUiHandler } from "#ui/ball-ui-handler"; import type { BattleMessageUiHandler } from "#ui/battle-message-ui-handler"; import type { CommandUiHandler } from "#ui/command-ui-handler"; diff --git a/test/testUtils/gameWrapper.ts b/test/test-utils/game-wrapper.ts similarity index 92% rename from test/testUtils/gameWrapper.ts rename to test/test-utils/game-wrapper.ts index b9665ffe071..1a906bf8492 100644 --- a/test/testUtils/gameWrapper.ts +++ b/test/test-utils/game-wrapper.ts @@ -6,14 +6,14 @@ import * as bypassLoginModule from "#app/global-vars/bypass-login"; import { MoveAnim } from "#data/battle-anims"; import { Pokemon } from "#field/pokemon"; import { version } from "#package.json"; -import { blobToString } from "#test/testUtils/gameManagerUtils"; -import { MockClock } from "#test/testUtils/mocks/mockClock"; -import { MockFetch } from "#test/testUtils/mocks/mockFetch"; -import { MockGameObjectCreator } from "#test/testUtils/mocks/mockGameObjectCreator"; -import { MockLoader } from "#test/testUtils/mocks/mockLoader"; -import { MockContainer } from "#test/testUtils/mocks/mocksContainer/mockContainer"; -import { MockTextureManager } from "#test/testUtils/mocks/mockTextureManager"; -import { MockTimedEventManager } from "#test/testUtils/mocks/mockTimedEventManager"; +import { blobToString } from "#test/test-utils/game-manager-utils"; +import { MockClock } from "#test/test-utils/mocks/mock-clock"; +import { MockFetch } from "#test/test-utils/mocks/mock-fetch"; +import { MockGameObjectCreator } from "#test/test-utils/mocks/mock-game-object-creator"; +import { MockLoader } from "#test/test-utils/mocks/mock-loader"; +import { MockTextureManager } from "#test/test-utils/mocks/mock-texture-manager"; +import { MockTimedEventManager } from "#test/test-utils/mocks/mock-timed-event-manager"; +import { MockContainer } from "#test/test-utils/mocks/mocks-container/mock-container"; import { PokedexMonContainer } from "#ui/pokedex-mon-container"; import { sessionIdKey } from "#utils/common"; import { setCookie } from "#utils/cookies"; diff --git a/test/testUtils/helpers/challengeModeHelper.ts b/test/test-utils/helpers/challenge-mode-helper.ts similarity index 95% rename from test/testUtils/helpers/challengeModeHelper.ts rename to test/test-utils/helpers/challenge-mode-helper.ts index 31b7c062d99..3952685a560 100644 --- a/test/testUtils/helpers/challengeModeHelper.ts +++ b/test/test-utils/helpers/challenge-mode-helper.ts @@ -8,8 +8,8 @@ import { CommandPhase } from "#phases/command-phase"; import { EncounterPhase } from "#phases/encounter-phase"; import { SelectStarterPhase } from "#phases/select-starter-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { generateStarter } from "#test/testUtils/gameManagerUtils"; -import { GameManagerHelper } from "#test/testUtils/helpers/gameManagerHelper"; +import { generateStarter } from "#test/test-utils/game-manager-utils"; +import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"; import { copyChallenge } from "data/challenge"; /** diff --git a/test/testUtils/helpers/classicModeHelper.ts b/test/test-utils/helpers/classic-mode-helper.ts similarity index 96% rename from test/testUtils/helpers/classicModeHelper.ts rename to test/test-utils/helpers/classic-mode-helper.ts index 55b25623b5a..5d73dc07615 100644 --- a/test/testUtils/helpers/classicModeHelper.ts +++ b/test/test-utils/helpers/classic-mode-helper.ts @@ -9,8 +9,8 @@ import { CommandPhase } from "#phases/command-phase"; import { EncounterPhase } from "#phases/encounter-phase"; import { SelectStarterPhase } from "#phases/select-starter-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { generateStarter } from "#test/testUtils/gameManagerUtils"; -import { GameManagerHelper } from "#test/testUtils/helpers/gameManagerHelper"; +import { generateStarter } from "#test/test-utils/game-manager-utils"; +import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"; /** * Helper to handle classic-mode specific operations. diff --git a/test/testUtils/helpers/dailyModeHelper.ts b/test/test-utils/helpers/daily-mode-helper.ts similarity index 96% rename from test/testUtils/helpers/dailyModeHelper.ts rename to test/test-utils/helpers/daily-mode-helper.ts index 214b6e4c5a4..7aa1e699118 100644 --- a/test/testUtils/helpers/dailyModeHelper.ts +++ b/test/test-utils/helpers/daily-mode-helper.ts @@ -6,7 +6,7 @@ import { CommandPhase } from "#phases/command-phase"; import { EncounterPhase } from "#phases/encounter-phase"; import { TitlePhase } from "#phases/title-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; -import { GameManagerHelper } from "#test/testUtils/helpers/gameManagerHelper"; +import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"; import type { SaveSlotSelectUiHandler } from "#ui/save-slot-select-ui-handler"; /** diff --git a/test/testUtils/helpers/field-helper.ts b/test/test-utils/helpers/field-helper.ts similarity index 98% rename from test/testUtils/helpers/field-helper.ts rename to test/test-utils/helpers/field-helper.ts index ca106804b85..35ca853d049 100644 --- a/test/testUtils/helpers/field-helper.ts +++ b/test/test-utils/helpers/field-helper.ts @@ -9,7 +9,7 @@ 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"; -import { GameManagerHelper } from "#test/testUtils/helpers/gameManagerHelper"; +import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"; import { expect, type MockInstance, vi } from "vitest"; /** Helper to manage pokemon */ diff --git a/test/testUtils/helpers/gameManagerHelper.ts b/test/test-utils/helpers/game-manager-helper.ts similarity index 75% rename from test/testUtils/helpers/gameManagerHelper.ts rename to test/test-utils/helpers/game-manager-helper.ts index 6db3819a5cb..eace4d9f5db 100644 --- a/test/testUtils/helpers/gameManagerHelper.ts +++ b/test/test-utils/helpers/game-manager-helper.ts @@ -1,4 +1,4 @@ -import type { GameManager } from "#test/testUtils/gameManager"; +import type { GameManager } from "#test/test-utils/game-manager"; /** * Base class for defining all game helpers. diff --git a/test/testUtils/helpers/modifiersHelper.ts b/test/test-utils/helpers/modifiers-helper.ts similarity index 96% rename from test/testUtils/helpers/modifiersHelper.ts rename to test/test-utils/helpers/modifiers-helper.ts index ff6e78c8a2f..bfda35427fa 100644 --- a/test/testUtils/helpers/modifiersHelper.ts +++ b/test/test-utils/helpers/modifiers-helper.ts @@ -1,6 +1,6 @@ import type { ModifierTypeKeys } from "#modifiers/modifier-type"; import { itemPoolChecks } from "#modifiers/modifier-type"; -import { GameManagerHelper } from "#test/testUtils/helpers/gameManagerHelper"; +import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"; import { expect } from "vitest"; export class ModifierHelper extends GameManagerHelper { diff --git a/test/testUtils/helpers/moveHelper.ts b/test/test-utils/helpers/move-helper.ts similarity index 99% rename from test/testUtils/helpers/moveHelper.ts rename to test/test-utils/helpers/move-helper.ts index 98a1c1664b4..fd6a123a5bb 100644 --- a/test/testUtils/helpers/moveHelper.ts +++ b/test/test-utils/helpers/move-helper.ts @@ -11,7 +11,7 @@ import { PokemonMove } from "#moves/pokemon-move"; 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/testUtils/helpers/gameManagerHelper"; +import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"; import { coerceArray, toReadableString } from "#utils/common"; import type { MockInstance } from "vitest"; import { expect, vi } from "vitest"; diff --git a/test/testUtils/helpers/overridesHelper.ts b/test/test-utils/helpers/overrides-helper.ts similarity index 99% rename from test/testUtils/helpers/overridesHelper.ts rename to test/test-utils/helpers/overrides-helper.ts index 13e3dcc2f09..bd2986cc094 100644 --- a/test/testUtils/helpers/overridesHelper.ts +++ b/test/test-utils/helpers/overrides-helper.ts @@ -17,7 +17,7 @@ import type { Unlockables } from "#enums/unlockables"; import { WeatherType } from "#enums/weather-type"; import type { ModifierOverride } from "#modifiers/modifier-type"; import type { Variant } from "#sprites/variant"; -import { GameManagerHelper } from "#test/testUtils/helpers/gameManagerHelper"; +import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"; import { coerceArray, shiftCharCodes } from "#utils/common"; import { expect, vi } from "vitest"; diff --git a/test/testUtils/helpers/reloadHelper.ts b/test/test-utils/helpers/reload-helper.ts similarity index 95% rename from test/testUtils/helpers/reloadHelper.ts rename to test/test-utils/helpers/reload-helper.ts index bc8adae6f28..a8ed0e21307 100644 --- a/test/testUtils/helpers/reloadHelper.ts +++ b/test/test-utils/helpers/reload-helper.ts @@ -4,8 +4,8 @@ import { CommandPhase } from "#phases/command-phase"; import { TitlePhase } from "#phases/title-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; import type { SessionSaveData } from "#system/game-data"; -import type { GameManager } from "#test/testUtils/gameManager"; -import { GameManagerHelper } from "#test/testUtils/helpers/gameManagerHelper"; +import type { GameManager } from "#test/test-utils/game-manager"; +import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"; import { vi } from "vitest"; /** diff --git a/test/testUtils/helpers/settingsHelper.ts b/test/test-utils/helpers/settings-helper.ts similarity index 94% rename from test/testUtils/helpers/settingsHelper.ts rename to test/test-utils/helpers/settings-helper.ts index 76db93c7de5..a26aa2de33c 100644 --- a/test/testUtils/helpers/settingsHelper.ts +++ b/test/test-utils/helpers/settings-helper.ts @@ -1,7 +1,7 @@ import { BattleStyle } from "#enums/battle-style"; import { ExpGainsSpeed } from "#enums/exp-gains-speed"; import { PlayerGender } from "#enums/player-gender"; -import { GameManagerHelper } from "#test/testUtils/helpers/gameManagerHelper"; +import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"; /** * Helper to handle settings for tests diff --git a/test/testUtils/inputsHandler.ts b/test/test-utils/inputs-handler.ts similarity index 93% rename from test/testUtils/inputsHandler.ts rename to test/test-utils/inputs-handler.ts index 6a0db37c9b6..b8b3224c31d 100644 --- a/test/testUtils/inputsHandler.ts +++ b/test/test-utils/inputs-handler.ts @@ -1,8 +1,8 @@ import type { BattleScene } from "#app/battle-scene"; import type { InputsController } from "#app/inputs-controller"; import { TouchControl } from "#app/touch-controls"; -import pad_xbox360 from "#inputs/pad_xbox360"; -import { holdOn } from "#test/testUtils/gameManagerUtils"; +import pad_xbox360 from "#inputs/pad-xbox360"; +import { holdOn } from "#test/test-utils/game-manager-utils"; import fs from "node:fs"; import { JSDOM } from "jsdom"; import Phaser from "phaser"; @@ -98,7 +98,7 @@ class Fakepad extends Phaser.Input.Gamepad.Gamepad { class FakeMobile { constructor() { - const fakeMobilePage = fs.readFileSync("././test/testUtils/fakeMobile.html", { encoding: "utf8", flag: "r" }); + const fakeMobilePage = fs.readFileSync("././test/test-utils/fakeMobile.html", { encoding: "utf8", flag: "r" }); const dom = new JSDOM(fakeMobilePage); Object.defineProperty(window, "document", { value: dom.window.document, diff --git a/test/testUtils/listenersManager.ts b/test/test-utils/listeners-manager.ts similarity index 100% rename from test/testUtils/listenersManager.ts rename to test/test-utils/listeners-manager.ts diff --git a/test/testUtils/mocks/mockClock.ts b/test/test-utils/mocks/mock-clock.ts similarity index 100% rename from test/testUtils/mocks/mockClock.ts rename to test/test-utils/mocks/mock-clock.ts diff --git a/test/testUtils/mocks/mockConsoleLog.ts b/test/test-utils/mocks/mock-console-log.ts similarity index 100% rename from test/testUtils/mocks/mockConsoleLog.ts rename to test/test-utils/mocks/mock-console-log.ts diff --git a/test/testUtils/mocks/mockContextCanvas.ts b/test/test-utils/mocks/mock-context-canvas.ts similarity index 100% rename from test/testUtils/mocks/mockContextCanvas.ts rename to test/test-utils/mocks/mock-context-canvas.ts diff --git a/test/testUtils/mocks/mockFetch.ts b/test/test-utils/mocks/mock-fetch.ts similarity index 100% rename from test/testUtils/mocks/mockFetch.ts rename to test/test-utils/mocks/mock-fetch.ts diff --git a/test/testUtils/mocks/mockGameObjectCreator.ts b/test/test-utils/mocks/mock-game-object-creator.ts similarity index 72% rename from test/testUtils/mocks/mockGameObjectCreator.ts rename to test/test-utils/mocks/mock-game-object-creator.ts index cfb1051ec2f..3d97f40edab 100644 --- a/test/testUtils/mocks/mockGameObjectCreator.ts +++ b/test/test-utils/mocks/mock-game-object-creator.ts @@ -1,5 +1,5 @@ -import { MockGraphics } from "#test/testUtils/mocks/mocksContainer/mockGraphics"; -import type { MockTextureManager } from "#test/testUtils/mocks/mockTextureManager"; +import type { MockTextureManager } from "#test/test-utils/mocks/mock-texture-manager"; +import { MockGraphics } from "#test/test-utils/mocks/mocks-container/mock-graphics"; export class MockGameObjectCreator { private readonly textureManager: MockTextureManager; diff --git a/test/testUtils/mocks/mockGameObject.ts b/test/test-utils/mocks/mock-game-object.ts similarity index 100% rename from test/testUtils/mocks/mockGameObject.ts rename to test/test-utils/mocks/mock-game-object.ts diff --git a/test/testUtils/mocks/mockLoader.ts b/test/test-utils/mocks/mock-loader.ts similarity index 100% rename from test/testUtils/mocks/mockLoader.ts rename to test/test-utils/mocks/mock-loader.ts diff --git a/test/testUtils/mocks/mockLocalStorage.ts b/test/test-utils/mocks/mock-local-storage.ts similarity index 100% rename from test/testUtils/mocks/mockLocalStorage.ts rename to test/test-utils/mocks/mock-local-storage.ts diff --git a/test/testUtils/mocks/mockTextureManager.ts b/test/test-utils/mocks/mock-texture-manager.ts similarity index 75% rename from test/testUtils/mocks/mockTextureManager.ts rename to test/test-utils/mocks/mock-texture-manager.ts index b61a804bf55..54002ad3cbb 100644 --- a/test/testUtils/mocks/mockTextureManager.ts +++ b/test/test-utils/mocks/mock-texture-manager.ts @@ -1,15 +1,15 @@ -import type { MockGameObject } from "#test/testUtils/mocks/mockGameObject"; -import { MockBBCodeText } from "#test/testUtils/mocks/mocksContainer/mock-bbcode-text"; -import { MockInputText } from "#test/testUtils/mocks/mocksContainer/mock-input-text"; -import { MockContainer } from "#test/testUtils/mocks/mocksContainer/mockContainer"; -import { MockImage } from "#test/testUtils/mocks/mocksContainer/mockImage"; -import { MockNineslice } from "#test/testUtils/mocks/mocksContainer/mockNineslice"; -import { MockPolygon } from "#test/testUtils/mocks/mocksContainer/mockPolygon"; -import { MockRectangle } from "#test/testUtils/mocks/mocksContainer/mockRectangle"; -import { MockSprite } from "#test/testUtils/mocks/mocksContainer/mockSprite"; -import { MockText } from "#test/testUtils/mocks/mocksContainer/mockText"; -import { MockTexture } from "#test/testUtils/mocks/mocksContainer/mockTexture"; -import { MockVideoGameObject } from "#test/testUtils/mocks/mockVideoGameObject"; +import type { MockGameObject } from "#test/test-utils/mocks/mock-game-object"; +import { MockVideoGameObject } from "#test/test-utils/mocks/mock-video-game-object"; +import { MockBBCodeText } from "#test/test-utils/mocks/mocks-container/mock-bbcode-text"; +import { MockContainer } from "#test/test-utils/mocks/mocks-container/mock-container"; +import { MockImage } from "#test/test-utils/mocks/mocks-container/mock-image"; +import { MockInputText } from "#test/test-utils/mocks/mocks-container/mock-input-text"; +import { MockNineslice } from "#test/test-utils/mocks/mocks-container/mock-nineslice"; +import { MockPolygon } from "#test/test-utils/mocks/mocks-container/mock-polygon"; +import { MockRectangle } from "#test/test-utils/mocks/mocks-container/mock-rectangle"; +import { MockSprite } from "#test/test-utils/mocks/mocks-container/mock-sprite"; +import { MockText } from "#test/test-utils/mocks/mocks-container/mock-text"; +import { MockTexture } from "#test/test-utils/mocks/mocks-container/mock-texture"; /** * Stub class for Phaser.Textures.TextureManager diff --git a/test/testUtils/mocks/mockTimedEventManager.ts b/test/test-utils/mocks/mock-timed-event-manager.ts similarity index 100% rename from test/testUtils/mocks/mockTimedEventManager.ts rename to test/test-utils/mocks/mock-timed-event-manager.ts diff --git a/test/testUtils/mocks/mockVideoGameObject.ts b/test/test-utils/mocks/mock-video-game-object.ts similarity index 86% rename from test/testUtils/mocks/mockVideoGameObject.ts rename to test/test-utils/mocks/mock-video-game-object.ts index 40413f6f622..742e3a7d435 100644 --- a/test/testUtils/mocks/mockVideoGameObject.ts +++ b/test/test-utils/mocks/mock-video-game-object.ts @@ -1,4 +1,4 @@ -import type { MockGameObject } from "#test/testUtils/mocks/mockGameObject"; +import type { MockGameObject } from "#test/test-utils/mocks/mock-game-object"; /** Mocks video-related stuff */ export class MockVideoGameObject implements MockGameObject { diff --git a/test/testUtils/mocks/mocksContainer/mock-bbcode-text.ts b/test/test-utils/mocks/mocks-container/mock-bbcode-text.ts similarity index 68% rename from test/testUtils/mocks/mocksContainer/mock-bbcode-text.ts rename to test/test-utils/mocks/mocks-container/mock-bbcode-text.ts index 8df0e01a43e..90b6a54a517 100644 --- a/test/testUtils/mocks/mocksContainer/mock-bbcode-text.ts +++ b/test/test-utils/mocks/mocks-container/mock-bbcode-text.ts @@ -1,4 +1,4 @@ -import { MockText } from "#test/testUtils/mocks/mocksContainer/mockText"; +import { MockText } from "#test/test-utils/mocks/mocks-container/mock-text"; export class MockBBCodeText extends MockText { setMaxLines(_lines: number) {} diff --git a/test/testUtils/mocks/mocksContainer/mockContainer.ts b/test/test-utils/mocks/mocks-container/mock-container.ts similarity index 97% rename from test/testUtils/mocks/mocksContainer/mockContainer.ts rename to test/test-utils/mocks/mocks-container/mock-container.ts index df9aaab5888..dd19dc3259c 100644 --- a/test/testUtils/mocks/mocksContainer/mockContainer.ts +++ b/test/test-utils/mocks/mocks-container/mock-container.ts @@ -1,5 +1,5 @@ -import type { MockGameObject } from "#test/testUtils/mocks/mockGameObject"; -import type { MockTextureManager } from "#test/testUtils/mocks/mockTextureManager"; +import type { MockGameObject } from "#test/test-utils/mocks/mock-game-object"; +import type { MockTextureManager } from "#test/test-utils/mocks/mock-texture-manager"; import { coerceArray } from "#utils/common"; export class MockContainer implements MockGameObject { diff --git a/test/testUtils/mocks/mocksContainer/mockGraphics.ts b/test/test-utils/mocks/mocks-container/mock-graphics.ts similarity index 96% rename from test/testUtils/mocks/mocksContainer/mockGraphics.ts rename to test/test-utils/mocks/mocks-container/mock-graphics.ts index 6558cdf9fb1..1e1dfd38124 100644 --- a/test/testUtils/mocks/mocksContainer/mockGraphics.ts +++ b/test/test-utils/mocks/mocks-container/mock-graphics.ts @@ -1,4 +1,4 @@ -import type { MockGameObject } from "#test/testUtils/mocks/mockGameObject"; +import type { MockGameObject } from "#test/test-utils/mocks/mock-game-object"; export class MockGraphics implements MockGameObject { private scene; diff --git a/test/testUtils/mocks/mocksContainer/mockImage.ts b/test/test-utils/mocks/mocks-container/mock-image.ts similarity index 75% rename from test/testUtils/mocks/mocksContainer/mockImage.ts rename to test/test-utils/mocks/mocks-container/mock-image.ts index 830a22a369c..812e17657ed 100644 --- a/test/testUtils/mocks/mocksContainer/mockImage.ts +++ b/test/test-utils/mocks/mocks-container/mock-image.ts @@ -1,4 +1,4 @@ -import { MockContainer } from "#test/testUtils/mocks/mocksContainer/mockContainer"; +import { MockContainer } from "#test/test-utils/mocks/mocks-container/mock-container"; export class MockImage extends MockContainer { // biome-ignore lint/correctness/noUnusedPrivateClassMembers: this is intentional (?) diff --git a/test/testUtils/mocks/mocksContainer/mock-input-text.ts b/test/test-utils/mocks/mocks-container/mock-input-text.ts similarity index 87% rename from test/testUtils/mocks/mocksContainer/mock-input-text.ts rename to test/test-utils/mocks/mocks-container/mock-input-text.ts index 6826278aa1e..bc5e26fddc5 100644 --- a/test/testUtils/mocks/mocksContainer/mock-input-text.ts +++ b/test/test-utils/mocks/mocks-container/mock-input-text.ts @@ -1,4 +1,4 @@ -import { MockText } from "#test/testUtils/mocks/mocksContainer/mockText"; +import { MockText } from "#test/test-utils/mocks/mocks-container/mock-text"; export class MockInputText extends MockText { public inputType: string; diff --git a/test/testUtils/mocks/mocksContainer/mockNineslice.ts b/test/test-utils/mocks/mocks-container/mock-nineslice.ts similarity index 85% rename from test/testUtils/mocks/mocksContainer/mockNineslice.ts rename to test/test-utils/mocks/mocks-container/mock-nineslice.ts index 11983075cf7..6678a5fca65 100644 --- a/test/testUtils/mocks/mocksContainer/mockNineslice.ts +++ b/test/test-utils/mocks/mocks-container/mock-nineslice.ts @@ -1,4 +1,4 @@ -import { MockContainer } from "#test/testUtils/mocks/mocksContainer/mockContainer"; +import { MockContainer } from "#test/test-utils/mocks/mocks-container/mock-container"; export class MockNineslice extends MockContainer { private texture; diff --git a/test/testUtils/mocks/mocksContainer/mockPolygon.ts b/test/test-utils/mocks/mocks-container/mock-polygon.ts similarity index 64% rename from test/testUtils/mocks/mocksContainer/mockPolygon.ts rename to test/test-utils/mocks/mocks-container/mock-polygon.ts index 2426231193a..7fc13fd7a00 100644 --- a/test/testUtils/mocks/mocksContainer/mockPolygon.ts +++ b/test/test-utils/mocks/mocks-container/mock-polygon.ts @@ -1,4 +1,4 @@ -import { MockContainer } from "#test/testUtils/mocks/mocksContainer/mockContainer"; +import { MockContainer } from "#test/test-utils/mocks/mocks-container/mock-container"; export class MockPolygon extends MockContainer { constructor(textureManager, x, y, _content, _fillColor, _fillAlpha) { diff --git a/test/testUtils/mocks/mocksContainer/mockRectangle.ts b/test/test-utils/mocks/mocks-container/mock-rectangle.ts similarity index 96% rename from test/testUtils/mocks/mocksContainer/mockRectangle.ts rename to test/test-utils/mocks/mocks-container/mock-rectangle.ts index 1e38cd3af44..96c49dec692 100644 --- a/test/testUtils/mocks/mocksContainer/mockRectangle.ts +++ b/test/test-utils/mocks/mocks-container/mock-rectangle.ts @@ -1,4 +1,4 @@ -import type { MockGameObject } from "#test/testUtils/mocks/mockGameObject"; +import type { MockGameObject } from "#test/test-utils/mocks/mock-game-object"; import { coerceArray } from "#utils/common"; export class MockRectangle implements MockGameObject { diff --git a/test/testUtils/mocks/mocksContainer/mockSprite.ts b/test/test-utils/mocks/mocks-container/mock-sprite.ts similarity index 98% rename from test/testUtils/mocks/mocksContainer/mockSprite.ts rename to test/test-utils/mocks/mocks-container/mock-sprite.ts index 15995a59977..d5e11f5c4f9 100644 --- a/test/testUtils/mocks/mocksContainer/mockSprite.ts +++ b/test/test-utils/mocks/mocks-container/mock-sprite.ts @@ -1,4 +1,4 @@ -import type { MockGameObject } from "#test/testUtils/mocks/mockGameObject"; +import type { MockGameObject } from "#test/test-utils/mocks/mock-game-object"; import { coerceArray } from "#utils/common"; import Phaser from "phaser"; diff --git a/test/testUtils/mocks/mocksContainer/mockText.ts b/test/test-utils/mocks/mocks-container/mock-text.ts similarity index 99% rename from test/testUtils/mocks/mocksContainer/mockText.ts rename to test/test-utils/mocks/mocks-container/mock-text.ts index 58ae3650411..ad2fce80972 100644 --- a/test/testUtils/mocks/mocksContainer/mockText.ts +++ b/test/test-utils/mocks/mocks-container/mock-text.ts @@ -1,4 +1,4 @@ -import type { MockGameObject } from "#test/testUtils/mocks/mockGameObject"; +import type { MockGameObject } from "#test/test-utils/mocks/mock-game-object"; import { UI } from "#ui/ui"; export class MockText implements MockGameObject { diff --git a/test/testUtils/mocks/mocksContainer/mockTexture.ts b/test/test-utils/mocks/mocks-container/mock-texture.ts similarity index 86% rename from test/testUtils/mocks/mocksContainer/mockTexture.ts rename to test/test-utils/mocks/mocks-container/mock-texture.ts index af25941094b..3e6b8137676 100644 --- a/test/testUtils/mocks/mocksContainer/mockTexture.ts +++ b/test/test-utils/mocks/mocks-container/mock-texture.ts @@ -1,5 +1,5 @@ -import type { MockGameObject } from "#test/testUtils/mocks/mockGameObject"; -import type { MockTextureManager } from "#test/testUtils/mocks/mockTextureManager"; +import type { MockGameObject } from "#test/test-utils/mocks/mock-game-object"; +import type { MockTextureManager } from "#test/test-utils/mocks/mock-texture-manager"; /** * Stub for Phaser.Textures.Texture object diff --git a/test/testUtils/phaseInterceptor.ts b/test/test-utils/phase-interceptor.ts similarity index 99% rename from test/testUtils/phaseInterceptor.ts rename to test/test-utils/phase-interceptor.ts index cdf151c01af..e0675a722f9 100644 --- a/test/testUtils/phaseInterceptor.ts +++ b/test/test-utils/phase-interceptor.ts @@ -61,7 +61,7 @@ import { TurnStartPhase } from "#phases/turn-start-phase"; import { UnavailablePhase } from "#phases/unavailable-phase"; import { UnlockPhase } from "#phases/unlock-phase"; import { VictoryPhase } from "#phases/victory-phase"; -import { ErrorInterceptor } from "#test/testUtils/errorInterceptor"; +import { ErrorInterceptor } from "#test/test-utils/error-interceptor"; import type { PhaseClass, PhaseString } from "#types/phase-types"; import { UI } from "#ui/ui"; diff --git a/test/testUtils/saves/data_new.prsv b/test/test-utils/saves/data_new.prsv similarity index 100% rename from test/testUtils/saves/data_new.prsv rename to test/test-utils/saves/data_new.prsv diff --git a/test/testUtils/saves/data_pokedex_tests.prsv b/test/test-utils/saves/data_pokedex_tests.prsv similarity index 100% rename from test/testUtils/saves/data_pokedex_tests.prsv rename to test/test-utils/saves/data_pokedex_tests.prsv diff --git a/test/testUtils/saves/data_pokedex_tests_v2.prsv b/test/test-utils/saves/data_pokedex_tests_v2.prsv similarity index 100% rename from test/testUtils/saves/data_pokedex_tests_v2.prsv rename to test/test-utils/saves/data_pokedex_tests_v2.prsv diff --git a/test/testUtils/saves/everything.prsv b/test/test-utils/saves/everything.prsv similarity index 100% rename from test/testUtils/saves/everything.prsv rename to test/test-utils/saves/everything.prsv diff --git a/test/testUtils/testFileInitialization.ts b/test/test-utils/test-file-initialization.ts similarity index 90% rename from test/testUtils/testFileInitialization.ts rename to test/test-utils/test-file-initialization.ts index 98b49159d98..87318f34ae3 100644 --- a/test/testUtils/testFileInitialization.ts +++ b/test/test-utils/test-file-initialization.ts @@ -13,12 +13,12 @@ import { initMysteryEncounters } from "#mystery-encounters/mystery-encounters"; import { initI18n } from "#plugins/i18n"; import { initAchievements } from "#system/achv"; import { initVouchers } from "#system/voucher"; -import { blobToString } from "#test/testUtils/gameManagerUtils"; -import { manageListeners } from "#test/testUtils/listenersManager"; -import { MockConsoleLog } from "#test/testUtils/mocks/mockConsoleLog"; -import { mockContext } from "#test/testUtils/mocks/mockContextCanvas"; -import { mockLocalStorage } from "#test/testUtils/mocks/mockLocalStorage"; -import { MockImage } from "#test/testUtils/mocks/mocksContainer/mockImage"; +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"; diff --git a/test/testUtils/testUtils.ts b/test/test-utils/test-utils.ts similarity index 100% rename from test/testUtils/testUtils.ts rename to test/test-utils/test-utils.ts diff --git a/test/testUtils/TextInterceptor.ts b/test/test-utils/text-interceptor.ts similarity index 100% rename from test/testUtils/TextInterceptor.ts rename to test/test-utils/text-interceptor.ts diff --git a/test/ui/battle_info.test.ts b/test/ui/battle-info.test.ts similarity index 96% rename from test/ui/battle_info.test.ts rename to test/ui/battle-info.test.ts index afc456c6430..8bdd61e05b0 100644 --- a/test/ui/battle_info.test.ts +++ b/test/ui/battle-info.test.ts @@ -3,7 +3,7 @@ import { ExpGainsSpeed } from "#enums/exp-gains-speed"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { ExpPhase } from "#phases/exp-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/ui/pokedex.test.ts b/test/ui/pokedex.test.ts index 1d81f19052c..217c1f09a3b 100644 --- a/test/ui/pokedex.test.ts +++ b/test/ui/pokedex.test.ts @@ -7,7 +7,7 @@ import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import type { StarterAttributes } from "#system/game-data"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { FilterTextRow } from "#ui/filter-text"; import { PokedexPageUiHandler } from "#ui/pokedex-page-ui-handler"; import { PokedexUiHandler } from "#ui/pokedex-ui-handler"; @@ -193,7 +193,7 @@ describe("UI - Pokedex", () => { ***************************/ it("should filter to show only the pokemon with an ability when filtering by ability", async () => { - // await game.importData("test/testUtils/saves/everything.prsv"); + // await game.importData("test/test-utils/saves/everything.prsv"); const pokedexHandler = await runToOpenPokedex(); // Get name of overgrow @@ -301,7 +301,7 @@ describe("UI - Pokedex", () => { it("filtering for unlockable cost reduction only shows species with sufficient candies", async () => { // load the save file - await game.importData("./test/testUtils/saves/data_pokedex_tests.prsv"); + await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv"); const pokedexHandler = await runToOpenPokedex(); // @ts-expect-error - `filterBar` is private @@ -330,7 +330,7 @@ describe("UI - Pokedex", () => { }); it("filtering by passive unlocked only shows species that have their passive", async () => { - await game.importData("./test/testUtils/saves/data_pokedex_tests.prsv"); + await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv"); const pokedexHandler = await runToOpenPokedex(); // @ts-expect-error - `filterBar` is private @@ -347,7 +347,7 @@ describe("UI - Pokedex", () => { }); it("filtering for pokemon that can unlock passive shows only species with sufficient candies", async () => { - await game.importData("./test/testUtils/saves/data_pokedex_tests.prsv"); + await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv"); const pokedexHandler = await runToOpenPokedex(); // @ts-expect-error - `filterBar` is private @@ -375,7 +375,7 @@ describe("UI - Pokedex", () => { }); it("filtering for pokemon that have any cost reduction shows only the species that have unlocked a cost reduction", async () => { - await game.importData("./test/testUtils/saves/data_pokedex_tests.prsv"); + await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv"); const pokedexHandler = await runToOpenPokedex(); const expectedPokemon = new Set([SpeciesId.TREECKO, SpeciesId.CYNDAQUIL, SpeciesId.TOTODILE]); @@ -394,7 +394,7 @@ describe("UI - Pokedex", () => { }); it("filtering for pokemon that have a single cost reduction shows only the species that have unlocked a single cost reduction", async () => { - await game.importData("./test/testUtils/saves/data_pokedex_tests.prsv"); + await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv"); const pokedexHandler = await runToOpenPokedex(); const expectedPokemon = new Set([SpeciesId.CYNDAQUIL, SpeciesId.TOTODILE]); @@ -414,7 +414,7 @@ describe("UI - Pokedex", () => { }); it("filtering for pokemon that have two cost reductions sorts only shows the species that have unlocked both cost reductions", async () => { - await game.importData("./test/testUtils/saves/data_pokedex_tests.prsv"); + await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv"); const pokedexHandler = await runToOpenPokedex(); // @ts-expect-error - `filterBar` is private @@ -433,7 +433,7 @@ describe("UI - Pokedex", () => { }); it("filtering by shiny status shows the caught pokemon with the selected shiny tier", async () => { - await game.importData("./test/testUtils/saves/data_pokedex_tests.prsv"); + await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv"); const pokedexHandler = await runToOpenPokedex(); // @ts-expect-error - `filterBar` is private const filter = pokedexHandler.filterBar.getFilter(DropDownColumn.CAUGHT); @@ -513,7 +513,7 @@ describe("UI - Pokedex", () => { ****************************/ it("should show caught battle form as caught", async () => { - await game.importData("./test/testUtils/saves/data_pokedex_tests_v2.prsv"); + await game.importData("./test/test-utils/saves/data_pokedex_tests_v2.prsv"); const pageHandler = await runToPokedexPage(getPokemonSpecies(SpeciesId.VENUSAUR), { form: 1 }); // @ts-expect-error - `species` is private @@ -528,7 +528,7 @@ describe("UI - Pokedex", () => { //TODO: check tint of the sprite it("should show uncaught battle form as seen", async () => { - await game.importData("./test/testUtils/saves/data_pokedex_tests_v2.prsv"); + await game.importData("./test/test-utils/saves/data_pokedex_tests_v2.prsv"); const pageHandler = await runToPokedexPage(getPokemonSpecies(SpeciesId.VENUSAUR), { form: 2 }); // @ts-expect-error - `species` is private diff --git a/test/ui/starter-select.test.ts b/test/ui/starter-select.test.ts index 63abc99174e..a8c6284cf3f 100644 --- a/test/ui/starter-select.test.ts +++ b/test/ui/starter-select.test.ts @@ -9,7 +9,7 @@ import { UiMode } from "#enums/ui-mode"; import { EncounterPhase } from "#phases/encounter-phase"; import { SelectStarterPhase } from "#phases/select-starter-phase"; import type { TitlePhase } from "#phases/title-phase"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler"; import type { OptionSelectUiHandler } from "#ui/option-select-ui-handler"; import type { SaveSlotSelectUiHandler } from "#ui/save-slot-select-ui-handler"; @@ -37,7 +37,7 @@ describe("UI - Starter select", () => { }); it("Bulbasaur - shiny - variant 2 male", async () => { - await game.importData("./test/testUtils/saves/everything.prsv"); + await game.importData("./test/test-utils/saves/everything.prsv"); const caughtCount = Object.keys(game.scene.gameData.dexData).filter(key => { const species = game.scene.gameData.dexData[key]; return species.caughtAttr !== 0n; @@ -97,7 +97,7 @@ describe("UI - Starter select", () => { }); it("Bulbasaur - shiny - variant 2 female hardy overgrow", async () => { - await game.importData("./test/testUtils/saves/everything.prsv"); + await game.importData("./test/test-utils/saves/everything.prsv"); const caughtCount = Object.keys(game.scene.gameData.dexData).filter(key => { const species = game.scene.gameData.dexData[key]; return species.caughtAttr !== 0n; @@ -159,7 +159,7 @@ describe("UI - Starter select", () => { }); it("Bulbasaur - shiny - variant 2 female lonely chlorophyl", async () => { - await game.importData("./test/testUtils/saves/everything.prsv"); + await game.importData("./test/test-utils/saves/everything.prsv"); const caughtCount = Object.keys(game.scene.gameData.dexData).filter(key => { const species = game.scene.gameData.dexData[key]; return species.caughtAttr !== 0n; @@ -224,7 +224,7 @@ describe("UI - Starter select", () => { }); it("Bulbasaur - shiny - variant 2 female", async () => { - await game.importData("./test/testUtils/saves/everything.prsv"); + await game.importData("./test/test-utils/saves/everything.prsv"); const caughtCount = Object.keys(game.scene.gameData.dexData).filter(key => { const species = game.scene.gameData.dexData[key]; return species.caughtAttr !== 0n; @@ -285,7 +285,7 @@ describe("UI - Starter select", () => { }); it("Bulbasaur - not shiny", async () => { - await game.importData("./test/testUtils/saves/everything.prsv"); + await game.importData("./test/test-utils/saves/everything.prsv"); const caughtCount = Object.keys(game.scene.gameData.dexData).filter(key => { const species = game.scene.gameData.dexData[key]; return species.caughtAttr !== 0n; @@ -345,7 +345,7 @@ describe("UI - Starter select", () => { }); it("Bulbasaur - shiny - variant 1", async () => { - await game.importData("./test/testUtils/saves/everything.prsv"); + await game.importData("./test/test-utils/saves/everything.prsv"); const caughtCount = Object.keys(game.scene.gameData.dexData).filter(key => { const species = game.scene.gameData.dexData[key]; return species.caughtAttr !== 0n; @@ -407,7 +407,7 @@ describe("UI - Starter select", () => { }); it("Bulbasaur - shiny - variant 0", async () => { - await game.importData("./test/testUtils/saves/everything.prsv"); + await game.importData("./test/test-utils/saves/everything.prsv"); const caughtCount = Object.keys(game.scene.gameData.dexData).filter(key => { const species = game.scene.gameData.dexData[key]; return species.caughtAttr !== 0n; @@ -468,7 +468,7 @@ describe("UI - Starter select", () => { }); it("Check if first pokemon in party is caterpie from gen 1 and 1rd row, 3rd column", async () => { - await game.importData("./test/testUtils/saves/everything.prsv"); + await game.importData("./test/test-utils/saves/everything.prsv"); const caughtCount = Object.keys(game.scene.gameData.dexData).filter(key => { const species = game.scene.gameData.dexData[key]; return species.caughtAttr !== 0n; @@ -532,7 +532,7 @@ describe("UI - Starter select", () => { }); it("Check if first pokemon in party is nidoran_m from gen 1 and 2nd row, 4th column (cursor (9+4)-1)", async () => { - await game.importData("./test/testUtils/saves/everything.prsv"); + await game.importData("./test/test-utils/saves/everything.prsv"); const caughtCount = Object.keys(game.scene.gameData.dexData).filter(key => { const species = game.scene.gameData.dexData[key]; return species.caughtAttr !== 0n; diff --git a/test/ui/transfer-item.test.ts b/test/ui/transfer-item.test.ts index f2b0a4f7d35..0d101b5b4ef 100644 --- a/test/ui/transfer-item.test.ts +++ b/test/ui/transfer-item.test.ts @@ -3,7 +3,7 @@ import { Button } from "#enums/buttons"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; -import { GameManager } from "#test/testUtils/gameManager"; +import { GameManager } from "#test/test-utils/game-manager"; import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler"; import Phaser from "phaser"; diff --git a/test/ui/type-hints.test.ts b/test/ui/type-hints.test.ts index 8359c50c35d..f1f27322a64 100644 --- a/test/ui/type-hints.test.ts +++ b/test/ui/type-hints.test.ts @@ -3,8 +3,8 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { CommandPhase } from "#phases/command-phase"; -import { GameManager } from "#test/testUtils/gameManager"; -import type { MockText } from "#test/testUtils/mocks/mocksContainer/mockText"; +import { GameManager } from "#test/test-utils/game-manager"; +import type { MockText } from "#test/test-utils/mocks/mocks-container/mock-text"; import { FightUiHandler } from "#ui/fight-ui-handler"; import i18next from "i18next"; import Phaser from "phaser"; diff --git a/test/vitest.setup.ts b/test/vitest.setup.ts index 6cf20219408..70293f20469 100644 --- a/test/vitest.setup.ts +++ b/test/vitest.setup.ts @@ -1,5 +1,5 @@ import "vitest-canvas-mock"; -import { initTestFile } from "#test/testUtils/testFileInitialization"; +import { initTestFile } from "#test/test-utils/test-file-initialization"; import { afterAll, beforeAll, vi } from "vitest"; /** Set the timezone to UTC for tests. */ diff --git a/tsconfig.json b/tsconfig.json index b7ef84869e5..8c53625ce55 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -43,8 +43,8 @@ "#sprites/*": ["./sprites/*.ts"], "#system/*": [ "./system/settings/*.ts", - "./system/version_migration/versions/*.ts", - "./system/version_migration/*.ts", + "./system/version-migration/versions/*.ts", + "./system/version-migration/*.ts", "./system/*.ts" ], "#trainers/*": ["./data/trainers/*.ts"], diff --git a/vitest.config.ts b/vitest.config.ts index 3900bc7b047..e9f7a2a438c 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -6,7 +6,7 @@ export default defineProject(({ mode }) => ({ ...defaultConfig, test: { testTimeout: 20000, - setupFiles: ["./test/fontFace.setup.ts", "./test/vitest.setup.ts"], + setupFiles: ["./test/font-face.setup.ts", "./test/vitest.setup.ts"], sequence: { sequencer: MySequencer, }, 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 04/79] [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 05/79] [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 06/79] [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 07/79] [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 08/79] [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 09/79] [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 10/79] [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 11/79] [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 12/79] [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 13/79] [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 14/79] [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 15/79] [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 16/79] [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 17/79] [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 18/79] [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 19/79] [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 20/79] [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 21/79] [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 22/79] [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 23/79] [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 24/79] [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 25/79] [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 26/79] [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 27/79] [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 28/79] [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 29/79] [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 30/79] [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 31/79] 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 32/79] 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 33/79] 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 34/79] 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 35/79] 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 36/79] 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 37/79] 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 38/79] 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 39/79] 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 40/79] 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 41/79] 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 42/79] 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 43/79] [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 44/79] [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 45/79] [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 46/79] [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 47/79] [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 48/79] [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 49/79] [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 50/79] [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 51/79] [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 52/79] [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 53/79] [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 54/79] [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 55/79] [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 56/79] [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 57/79] [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 58/79] [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 59/79] [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 60/79] [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 61/79] 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 62/79] [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 63/79] [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 64/79] [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 65/79] [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 66/79] [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 67/79] [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 zcmV)kK%l>gP)0000gP)t-s0000G z5D+FNCUaOKB1>~XKtNw#U(B36|HMrH$XPaYvm>I&MU~}Y+VZ7$Ul9NR00DGTPE!Ct z=GbNc0AzGYL_t(|UhI}JZrm^sMMYZ&;0FTGaJMSmx`^w5)k3*L)TlO%095NrI*E#f z&XHoFLuE%Km#RpP0H+EoH4pRo=g&~pzdHX9z(xccI8p?Vd;|DMD8uKh<+4!VAwp3R zrm!1h_z)KnpfU%%6Lvc+8^A>ffPE)`#aLwxAF^QfG+u@s240)kh@h@kWq^o`1q3A1 zI0L{Oz6=XAlAluZMMVJkp%#weE0b&lEFi2Y95N0}B2z>+odXazNBNkF3OMez;*B zcIFP)zlj*ejB)Ly4>>h}he~G^$}NSm+9xRkKekvYk7Ujv`4q(wlfZ);J}FiKwL?3>V<{^VsG5rU`i)xefJU5TG%epNCU0&QV1%s8=@>uC-BM8rov&ObBLAg>RAH zin++Gi+ApMS^wOfn=%dc475IB7!wm?kf`#BzXD zPkPo!RWPaP)V;oQ8_>)uVQmk%XoH&N0yJ|$;;;Y)yx@1M8L5FhG8{FU;Xti`rh9x% zp#}FGwZW9@f4R>S5m`@VMn*+SIWjlgXbkWW5#M}%MOM`(8ofVj<$lM?q1I1bn_;zM z!A6eMNNym|4ep4E0Bm3n3O!l-5(}JUAdVyFgIym|e8cYl0+aBbVbLYwv~mf~a{IQl z=!-I&LDkUrv~u$<_i1#~Ld5A51#r8Z`Do`|3mhIRi)hX6#mRMq@11x9O+8C0S7pX?OGu#=iMQ@eRnd^F~MRx);Hx;F`96#EZtL~VXHW`+SBd&Rr?e92pa3D3{ zS(0blU+i=8b<2&DNaZ^F`%t1OW948NvKy2zW95dOCn!Ssn4tAh9D!>d_R=(pgnfoX z5}Id$B=I}@Aj)aL%C&uJ=-sB>0l)Va5qmsC=)-tvLtziiN|?_QbmPJ9Z&T_|@$-baR8yzC-jd(hf(gylG^TE zVt6Uc5>D0OE{gZk{|qY@3KzH4!W@pu^Y~9txE9;EcQf3^O5{H&AzW=8vm6J-OMh2B z+VD~_A^pMWrhlH+S}xB%L9nhQkn;V*J`G&emQ>EYnIOPJ=u6xTdBJuPi89J@qDMDq zm2kQBLh(27am{fD7cw zaDnzmOEs_S@6(`7Ih3R2@$m5>ZKF{^1|4%cR14F}g~{Pj__?>a;CWsg?--NeV?^Ot zxjq?fPbqiX^DO09d1`<$F4GmXt;+FSnNswMAMNL!cgOQqR^meGmHQmaCyP$1+%!=Q z1MaK%!A{Nek}?VApR~o8vS|DV3#U}j$|Yga3z|_Bg*Q;QolxXM{5%<&j=G%$KWgJ< z=1}gB<6~ zU6s43=J~k5r&FP~vU7V%x$~@Yw8Uen+~N4NHy)vMaTGybxFMxRV>8DjcRPwUQEj;y zdm5qc=O3^-?olPue(HHeu7keKbMa)uqju7}2!1qr6NNibD2hBaVQ)BJQ!#NEwJDH3 zM%{|nx6TiiIx{YmbEq{shsV4blsg!IiE5MF#c3|} z15Q@~1>J3w%~YEv8=vPV8>Y&QdgC!p*D4UM5wPH#f;f<(5Q;n0Ny4HB3paRqs5KN9 zU>+m_DR+wNdJ}OoV}v+MH=HP^_97Q%KdKya4M&^ca5?hOPm5efC1M`h*|l<~Bwc}7 zgEJ#5Hyub(B&_S>2dkHtEMpic;oQna?O;4Q8{>$;+)U1Z!bvID8xPc8!r7haF{dl( zr;pH2Tf7^ip*M0dCE_DJ+n0uNl!lMlO<6e(B$(BqN{j#ZW@dRRh}_CO3^vAtvvJTH zM=h|vvdE>MfQ*!*isBl{j*y9PBj(&I#O!l;HXe*GdgC|YiP35u=Odg(!hvKHF3COE z>E-1Cot6C6mQxFb1sFONT{faCLFetieHeHkF za<}C3#HHcNTEb{9a_x`qo7hjuq`Y#sF2-uM(NeTD5E{oxvAO6=+=O}K-;i#wxBy>KZPQn(~}+C98P=05h+CQE3tBN&VZINin4SMk!|xhEXT z4bf&gkOrbeQ8@}{FRvbu6bblk4DVxFR~wa+1_M-XW3X^%T52*-Ax@h~cr$1-BDG1m zfpB*+T#DFF3!bZ7n@q=3leLeQaJm8h8+;iz2VTU=>6R>e`Wof~X&_341cwn>7-Oy0 z^xKQRe?LivL#dq9dNiVC-8y}+oG(PpHAv7=@1vu((-0^3(R=x-ta8bb#ZS%2$jjH- zlp)l!jh3W0;1aiXmL9~EzFE1OfF6nwj{2Q*@`mX^$|`5+V=~L**yABkIU4(k8d3Wp zsj#&%7)0@{Z&r3f!xicf1n=D+CIDz~oKUnjRsN;DC_l9;$9}M6^HUx$nQReot|9qc zn5fYE#{tcD_Dvj#soV%a*#{$Bzn@~|IFO!ucZ$DJ!-G;cFOQYWN}-fnm%<%|tw+@S z#SdwY!Ai`^@n}fp4t&3j5iS?jRBDr-Zl6BzLXmGSaxFI*g=#aVpJvlTGic&upe9pk zE~KLT$9QA#70R#@A93M(A*f-viGIovPDbIubRc=lq5HvxXBq&HeSDGkU$t`4 zJrZH-;l@_H9mHBWqbB>iu;{NoO|;QHsdj*~#7pCq)C>5SCrc!>sl{OB*iSit%+V0_ zML#oH)b6Pz4&u1^JU$MKVjgWs?o_#DQf_Bwl!PDRkeiJxw5pAJ0F z{tKOsnv9i`4|nGjU2briUt)btP{ZI;*@GnY)89@7k{4%`7sH6IjQTxTGPLOfPUK6HjoV@)|$`n2Y`RM zf+zQQc_72c@Hij;_jr|+Yi`BSZ+`t~0NYFQ#TFDO_qg-8vr9&8W%O_>e)OwIO6!Nx=9_qH=g|m4xGR+t#qs?a z`DrS54{d()>oF<^>;%~eYBwqOB#YGkB(kb3tIcdkKji>2ACv#s-+i1;c7)2cc6PRY zgG+=~beEQRP#EF~(uNS;c zTvf4hf2GtWxmB>DjZ_<8sn`hsBZzX(fj^0$hg*-vzxvmm(J8vzY5eoAt;*43@>eI5 zMId@_c5u3rRun~DR?diUGD?&U2a>Ts5ER{T5Rh^Qi%<3P4!5>2jCRs6IzJK?<@l$C z8<<1Jub0N7cX~8Ok#h4|?cG#4^d5Xf;4Meqzo*K%BIw~8wHeB%OX zZZ0|-pZ>X6xyKz9;d@#+9Z0RsXj4x1Z^lnp7uP!IJ^pGM;Px8AvNUT-uSpNJkdKg#IetlpC@jXp_ugN}2uupB)+=SpOC@Li@A zG&V*koTzzYn{pje+h3&|L<2wtQY*Um{I0ezOy2EiH_a?>88gEFRixZJHA*A`e;f7U zV%&qdv(d6;4)h$19dd$+o4)P^7b7tjM}q-x#h!cCrEKhvh{>ExF(CelEf^UlUSn{xiH-$ASF@)n}VTkaMpH!qzh^Hs(*l1^Z- z4!XbJKTisj+gIZ$&)yvOf{}P<{QRSVj&PfD7(v?SdOea(cxP!=5EkL+(PqC)-NPmJ zaQ3-Ru_^iec``#eI1n62_}}rU$1<2bhOep~FK;f|96#?Cne3;+@#r;4x%l4b$2j+Y zEtmsXICi?;>ly~@bFaq{UX**%2m%=QE=FVYhBqT}Q@t{CyzTRB*@s)JeQ!Me_ur#F z!lqmwGJ#a9eP?IcsvJGk)k)QRO`k%b1$yZPdud(;$V~nE7Am)lTJP)pXW|$3;c3R^ z2k3N|8b2PB5Bv+yV%A7s)<}R_9b|-KK3z8Qsr@nW!yQqj_~X5ThHbu+S7lR!ej`bnNKf;FM;!D<>mJ zPe@KD=FY}ncJ0ARPRGLW!|kbPjW&NQl`|uJm6JCIQf&@jBa=lzG4?0%-AoQd8b&xr zyvbhb8g&o6m7Pset}FmzZUGiN9IqGI$fDdXOd`Dby4Ltq?nSzs9W7xvVng(Bg8#JX zDS>h$P2M6GNVVGg-i7oBQ@F>t>vNAd-r0<|Lll8=8;-FO z$I(h0dP4RO79;9^IMvq$DK{6X!&FVBlxh04__ z!oi^TU}$(=v2yi&Go6Zts8LOM$X;4PyBn=YpmMaI(k3W&O)3YrgL|%wdupuO0^9{D zh*ox5J}%N7;VgCZAn`JE6r* zUBa!z(G3W{%P!}3(VeYW<{(k5wJEmYrOvT20Ng7(Pbm`=8Ke4dc}py~$Md%7=n_)5uX+Mz zOpO*NaO*BEX+Tof;gV2AATO;pj9Dv>4PbY@f^sLd{))!f~Mf|5>^IWwVd4!&IJ0tPYECDdhkNfNw_~S69vxGpv7codFIu=za>R zU`AKHUwRsmN9NZrN5L1YoRia9LH8l5CsN=Pw&UATrkwYURe{Eaa&$EV5+;D<499@-kRB=YI^C1=~k}697mi_nwC>; zuBvjJn(Nnr>zyjNq-lDD+hm*jvKo z?i6XoTG-aegxiG!Y3f#Por($y=-G;j`z|Ous=v|A(IQRdfLabG9a+b!J9l_1!i-gN zKqqFBIjtnKTe(2;vYSCy-^kH7lykBA8P)H`7bZF7=HG?=Jr!1V+-Q=5ugkFGae{*I ztnZ0(oYr$9V1lFea{)^j4(uo@#(4`E)jtDY_$n3Q?~-Ttzwmij{BJy)o&-x2HgPXc}YU~ z{%4(i98dQ3K$n9Ou=VqZfxXU#7QqN{)&)2wED4o)+1tzk<&-1}wx+YNJW@oPdJeYjaKktc>)aSf% zMESJ190&L_z;lr+z`2isT~Exsf}ydFaloiHQVmcxNa$Ciphh{^Is3`;q}j70jwP^Rh+mejs}vBX6&;yIdp40ms&M;VsxcAjqBPc?$&L+YvV5 z@)g;4l~vviS7S<7u6rA}ZDQrNzmSso9i5Fa4?9c$Fv?W&w@GblAJatxb~%%qrG#VU zK%&}`VEvF-Z885c*iA?F(OnrP6MIv}Dcyxv^#wY@70A*q8pL7U}>jt%&7Y}IR*kA2!Q(FA@ zKbx*zgxM1=AaydF?osDugcrJ8H|4;qYFy-U-7Kg>>TsMYcRH33tOy(^X5y#eZqEJ3 zPxjur(Y};&z-<}%t8fx-@yQ|pb59BOR93G2zC95K$Au@#cWc^V_rM+#LtTx-BA5G* zvB}vyPn8=4c2*k~d=d^DXrF$(Vga?fz~o7&g##D7_>iVsRkFR^hjxe-bHMCS3*MDa zl-L7)Fz@4HpD5kHo`%UFy@P>W&W_DWQEkb?@kluxICe8UPr1@hTy$hkJ*-^v3{W|r zg|kS&#s7)gGql=C)5T>|RT4b_86fE?*Xi3cO zND@YdE9@*Q=kx=8KK_tgVCGc<8N#hB{z(uJr}YkjO+nb~@=X)wHr5ShRer9w0ok#v6_bdzbWG)(BoGLziKX6Ck4@SJjAbolG^7WQ{y6n}!^Dx7c> zmSeR0IJ9KsvkT5NJXEbcFRct`vv;b&io|LwY64#+$*_hiXQbS4Tn)!s(F5?&y=zT!-5xwrQXO;YY(;Z%7x?J6szqdZ%62F-pe%4GYFL* zFhtgNivVAC@uWCYbK{hqj5)269U4Z$aTy1eegd@X5T%gtJmyqbaIzfVMR$cXtoXt< zjHXy^1Cj4#rX^3Nd7c_8%_L?A(mkf;U=M_q{!N5ivu$GK#M`8hPI}bdM^Wf1DtwEH zx@Cn!g4wQt!X*KNrlfKRFdPgftTykC3lON4vtp%lsP+KG^VPAb4{OQiDuP&V*IX~g z7m^{?yI@YMtq0Wg7?IQ=Dc9rN=v3}yN8WM}2_qyx6H4*VBoKxQ?}oCC&NKzXR{JdnTvcd&J;%9dm=W%2n_2xCgpUS} zF=z8w0mlgah|)-)fHyKQhZV);`C#&48soDoNP++{DhN8r7GFa&oVJWNzm|S%i+|QQcbB3z0ju?1soI12{+|`;!^dzun3ahHoIvMldK;E;we7n=oMy(%eW@1!gre-Rb)wM)FFD;`gHSvVhP4GlsjlMikW%62h&(-QQ!v#n4I|jqY0S2plvc?gpA-ty9*48 zkZV6jDjHb0$|JO*+~_P|>HQF+Q)cxS)8v@58MWG*L|!AjnF8Y_8RY<)L`Mb~k_K8h zr5t0WMZx_lym_sm9Zb&3sfH6sKW>|r6oPj^=*J+B?d@_rn95O1kaCU!#v!2(d4{KSv>^0R+SS=F#Bf2D)5Mx$gskU2iHBbNX6vi>pAX%*aTgYjp zPRo7n7#>i!NiHXIqwAjBS2`qAG8xg`KE)&_-zVsyRt_5DttgI05Jl0$B799#5Filc zNT5C0O)`y@4pySjeapd+De%Sg@7e@L_+Kbw6~<8`c>jn@+^-mT>^OG}`m47N}? z*WJ29vQZ&%fdWPVP^=u0oFvGpoe**i-E(XF8u^9Z-6F6~ooL6Bp6=gIQOw~{4l5lx zcH;n(^HZt=!U+2~m%=z|<=!9@_kFBjfusq$f!VY?eJ-M^BJ8Dqc$^Q33(KqVlwbJE z^#g!9NL(ZhvHX!8IRM}${7S}1CKly1zfh#JOUhks?w(z_x~RYBqi{ZR zrKhmcU&TK^a&^xHg-`kZgJLi_C*s}RMLG?o%EdcB`5}U2nI`O*i$YxHMi~-uGw?iN z+~!iy+z)KYgqc4~YNK&MeU?zLHam=vbeke_hm4h$Js?;=@L(|c*a0SI@?(cFj!D$p zLMCoB0;UO@$_-_|$#Z=^mdo3qMrQmx|9KhpOr~;aNEG+>l7W>4ax^d}1_X0j84;|_ z3L})tF;|+g(t(uQ4JLo6dQ<5K8-wSnp|zGU92o@fNh@q^{%1ousg#DaYt*;|WM)HD&vjJb?mY z9G@GFdMzN7H+Aaj>JMluR{!Cft>{<3QPk(b`+T6ZS1>fztbWTS40TgDVn51gU5@VV z&s1)Am6g+2>4oLZfElH%+`&zGV$0mwpds)m9CFiRi*g-*LVX6D3jh>?7kj5MgJcc7 z{egOSmR7KUT2w+GAL*>?zMEk)OgUPMj^hKY*-wG$(z~nVS@M8Unq;mX_7;g{l zCMm~6YJ5{IoBI%2r{{)pg#}E9giI#kMrqVZUGbclHf7<|@4*4o$v|VJ>3v(z$UPvM z=_yLz%0e!8_{aDszxwqQ-`_^rq|xuEXoxx?c*mmVA%pjBAx*fxMrV)3-TvYP``kmW zGA=K|5y%JYYM!wgKhhyVXFR-S<<2F@cq`i ziFx&FldT#v9=4m0RwMj_##ZG@XISU-B=3)Q<1NH-BKo(oa?9lf= zMZ&E;o8Sr=Ip4cQs}qQ@W_Yoo9KCX+GNv1u-WK-TvdxN{cql5Z9DUe>V7ys9$pmr9 zSZVTuF4p713mae!jbNJoP0a;FIFuhaIXlb_{R7o6$%@|FWdrlR5RIHCc5x4CR8;~Q z5{7cz0+N83O%Abdjt1w7X+;3232wjpcEcmOxJ z8kZUXP5J`Zsx4SMKD!)arM+l#q~Nj^H&AzrNPvEi@Y)zb(b;}csTNS*nbK=wO&P%)-al}cYf5z%BN)O_O=%%?R*|n~-jG3O0TA-V0!^_py30ws zEKDhC#Y8XW(r7=SjmUP6^QT8!CF!~XbJmokbT+78L|@g*%A^U8z)?1TKhGkK8{Yum(9X( zNn9Zi4;i?bloLbjr=U0Z6bzq&)GG{7b2d-xuyY%*^YRxWzTaerL*_%)?Yu zC|J83tQ7!dPKp*N^QjSf{+h)=`Q}kn*leZ!mXQJwe zI}>B=C@NrJ$(J#RID)R1V+sI^>~gLIscsGQjYx^qvJL6og33;ad?wi%JTEM&fv za6uBox2v4HlYvSZL~@g=FOXYx$aYyJFJ@^RE6}LsSJ(d%%2g7MI4$5r*SRw>pF6

@r)_VP8Gb^t(^NRh4Ld{CMB>|*REW7%+wvj#fs5SsR!I~Dp&q0 z1vh_9XsVuYi$Iy7x^m?)Q{F*-(@@w*2QoEIz{quHYII+v;0_FQ*aq6NaGd5WnZco4 zb>W!8d^0kHvmh)fH6rpS7LKA){wjr<6DUl{7@2=i1~J{B1#**r4a#LH9p_)?m$los z6Zi-wW5fHpuTn6F3kWu3=ASFg1>H0%wy#OK-W0zGmCJs*SO=owIZ~qq?eD%yq5Nnt zhL3_H%P!pO7iujR$hdH*)@oUJnY^lPlPB1Brbe@ zyx9G=eJ;pwQ!^w+O&b#~0^iLe7K)W~U!`Ch=L#- zF7S*wat18ib(KPS<+LrAvGWOT!pEqvmOaLkMtxB&SlyVZFZ>Sc2A3f4@yo6!%&>G^ zrQlZ1v{lf|Na)EhEM~7zD$T7Hheh>ZolK;x?htjRBP>grt$j+w929NK5kzrU0 z*HsEHQMA1RuDue@ZX2Y^=_0oGmOUs6K`x#7l4?e_Qkns4%k_$K8r<}cCN zR+VJ%_EUh{&Z`t~^;+jXI!&tElihwFtXWmXMORUum2OY=pwtQ(7f#89!=n6fQaS)Y z@l68ao3wU7o6wbn!YY4Nh#j>b~IRey&<*rib1GK_SZLPC`VapJ)bnkB&q;czy zeP5=y@V&Ry#Fcd8ATnS{Dc{77{!X$4K3dC#E-Hi@b6=%E-bUPnMDO17W{8m5D&?L? zPC8DhZReOqXwvYBOg?co0H_1N!U`jMt8^sHFe-p0MK%l%r$#B<1ez5`QJJe00O;Nv z_f-mHyPk!+25+HgIN^`NxJsdW?z&2Wb<5+ax-ZDK9bAMDmXTp?v0c}ob;gBju&c*WQDqQo!k}~* zup|q@k_mjnBZg){t;$sjCetdJ#(-r=%$i}n6M-m7-kchUSiGGaUaZTYh@p zX`?6L&fVvb0lQXkIx~#;8Ew)Wv4SN915pNHnJk?d(5#AADX{G^{xb=@Q=&sAcNag} z=+>0f6;!ifrWlq)e3P%3Z{pyX9~jWAYF8<+a@zJdXPaSIy9i6H+?a9U)s!8DKH*pa79+}Xr3Rfxc5Yo0SnGQ4$D<_{6nZ~4?aA7Hr80;#g zt~4kVG-e7nmMq?Hr^p{khB>(rGvCBWjmP=a$k41{uz)YWDqN*t+5#yzJX~uZD*~@B z5N8u~@f}CMkO8|^SMK{Dk;>={?;&PNqeiJGQ6xqHMa2t?IOYd8RrF|R*1c(HmbZ)> zsc@A-ZqO>FEf9fam`K%oT>p__9ff)2G9@KR!LDZ`33jcZ9COl|Yc&Xh_xv{E#uO~6 zhe04ojLQ*&Ycd2rzyNQqrK$1!Sf$1{8E96Os}#)9L?D{vh_p#MQk@yr+mc~zLN+Cv zYFar4yKXRFyMlVOC&2yqDR3Tnf{MiWjiQZZluJ40O-_wNl^Xvfp;=s1DqN*tj{Bk` zQF45lK!gq zZ!_|bbN5=xrn;Z#-0-7MN$O9f)C6|@7L}uQ{ZevMF9=*Sckj)zg)-F?wI(SCiz!QZ z;|z<6gk~+Bs^+QkRSG7Upo6BVZPc4MInAh*TzD(dDG4&z^ zOH@2zCnWZsFxa*FVALq#O(Zf4m21RfBp3b*uPHB{uTmq0-fz)M z&k$jW93GGTw8~Wqrq5}faH^cVN?;6|VWddR|7JW|(e#0`>blM+5lwXhpnSBNawez^ zG~R@KE<*YW2_t5tM(sd=UfO#th{MB0rTSG0%wg_4eyn-I%|!8p&!}^H9o<7qO+z)S z9_GeLR>htqLb_thL+>`Gs;nGiJW#mhO-Y8?wM_9Yr$!tE*gUCuaWv>L4Xwge3MSWH zkwdTpN>b|J6F9*!6aeriTqUpb1@c6i{|sS&g0IcU+6Un!iNTr43u0Y;c}?a zIz%A?_!OqinHoh3Vw~IZMyFg9OWUCI3wI3kM)TVrS7{ z(?H2p6fTEM0Eht?GG!0FbUSl*0O7uy_kPSprTSG0Y;1tte}FX!Fjz5Ky9`UT1O=J) zZjo~L#)E*n`^w|(&rG)22DCoFX~AApvH_0q?cun$%0;EZRSNF0COfC)kM9jm$+BR^ zzsdxKLgFIxdep6ilCz^m8JPuQmA7I^T6==y8xgfTp;1&SUZr3k)Hxv;&Kor?mh;(u zL7>*yFhm#o6cwy=MW@3gQb4ez2(be0^4L^>8w7RbqEhWD1^4h4JR0CzEaw#xSMX#| z^EPp!DkwQKjfhKPYou=3`~BDAuqEdCDOb8m!9Bhs$#BtvShcuZ=P^Iq350KDlP?#z zp5YKqw+YkpH!w4Xwdn}1a+QL6+_^yjUa(Ht@h5C5hVUUuj-#R?A+SPf%sOg7nGu!a zKBnqb3T~Qk46T|4{_PuVDu4*$Z6@NDnW6$S$vOZaPeKzEBSx%NxJtn_0P8<0R~W2C zl^ky1JmqKN6gD%7D6_p~2sK;xC~bR3P^`W~@kq7%GTQSv*XTq@b=> z6&%lvguA*&5Vt7}tU&I&9_4yje$B$)3gqax z&k)FiU`CY#apr>b+L3U|>RH-&}ZaBv>tCfuN|KQl&yJhe)U+LfEc z+nuX^EgV^a?0A-4RSQ-|(R}^C_uX?aZfZ!%ZQq`|l5o6up2CPXkc7!AQIN+HnCdfy3VB-L~UtJ7>1(YR(dFquhqpeHlO7&}(1oWtqR;~drd zJVThgOh*=E$bG+CsNJrAyCgoucbg!d&_X}5FlAyH<411Xl<9IaMQC)ndP{7vLpcYz z@2x6WG&jU2N#ZOxs+fMndaH&m*)EK6;dVK@Tk|Bp)7aumC>Q*8dQ+&J(J)k0u0fb3 zBU&TzF5YKV^9f2M*>HV38HH&)F6Cys44vz> z+uOASQXt>jH@oso#iO%t79o=e_o0L)Va<{*j#F66!?8;_625;`R1n5o4u1qUCH_d# zk5-UKv{PsptTTlrcp_uF570iMrPV==K7bu1Hhc#8L&2&UtT`gw-+h9}Lw0ZeLS6}S z-`^qguEGF^O*nQ=0q zAMHrtOhj3>tiD1&z4^N-<g8MiLbJ>&Ggj`kT;RC1vpkk6aS^qXsL0SWYeq@DI$Yigq z5S>Mo(hzk6amgDwd=@TGgnOl{HwEc|$_GT>i%CJ-Jx#})O*GmIZh+(^-a+F#-U?Je z7&d0$k0$h^maz2n2B=Fa*Hf%57Ow1#9E33kORCa+<`YSTL*+KTIms;+7TqXz3dns_ z_QKD-%>^>H@Dd%viIXwtM`f&%u-zM<_Ux2WK8PAOa?ESt%<9N}CIBETvKO>9w$RF- zW8{rN?h7=zFD6FSH7NHgLq7tuE}Da(V-m$DE_WjbHMV_Gcz9x#o`OY6-ZRyF7S6%0 zo1*?nIwfY4i0a;TD0h&dAAuXqr1@?H9UET|0E(n@v{`&80RM?axWvNJqs>F@%H%#Y zt|S~|9ggz_B11nCC6x<;9+8%awG}Nv`FkavDR92oYny;l-aHFu!Xm9tmW&yfSW&ql zq^zLHpmuheesq#gBbEW^4H83hfmpN?QC7Jx=m?~Jz?*i=VG(ANv4z6s(e|8samBKg!ULMBe8BfD~r0ATxr{*jbx44ALi3IQde>i{sEr zgd;~HsOd;~89g=KG$lKZMT9V3iLxkE-6g~>GiD94TZ{tF?MJ^-K;$uOSq zV4@r&svJ$EFNH(fTBbqkj!R$*BTFDzmAlYoFJN+Cg;8Itx0?aIGC6>RI&TT_Ihdv& zJ=lpvo}!`oBTNgD$_;dK9K;_DgdIDtKk&eFsH_bNo*ok&*-{=kA&hwQ1DIX*5~FDv z84W|F0i**dA#oE!sX;r;(vR}ZdcC;@S~>MXU0MB>ni67XeZ|B`3t>CxYV7w_(##5UYR^O?hZ$_4C6%V^x&v$31Wqi7^RS73&a+AzuMlS` z-wlxexP{5F1q*kJSZaJ9kOQ91M7ZF+-98fGp0<-?nW{D^A1G|$QV^r;u5D$?-m)}C z)psZ+hTocU=|_)DKl;uNgLsNLORF7Uv3Q^j0EEWf8J~E|9$Pu@GFcj1;OPxfTMRm= z+@hai3y&fKK5J}YKvTGsNk7l=Bcm6O0{g)JO(9m>t;llQ|v##_IkvbW8& z#7cv~Km9EIXb!9Y-E%unuA|X-AheY{P(weQ1HFa|Kdlopr6;7UhEx0DN?M z?o#d-2$P%UC1OZy?VxekV#s1;pX)HMBeEjHa{08$ui{P9EX~dLWu0A2s zj!+>%$z;UIyLwOJGfaf(N8YB!O$j$=iN@<*fbc8~*5^dqOb*=F`sCp08v~JD*94Wh ztD+SXfdn2ROjjjf;baRk-KNo##sT9gE06jsW24&2 z$75n`?K8;8dWI)>`Xh#?=WgWiJ2-_#WdbTk@z#^T=ec*(?%m31Mhk}o5V=p;ejCcY zErrW}`zVsynmEhX^~SHX{d5XHuK~$`?RwJprK$ z7b@{S?VjvsSH0|qkv$@N3MBU~8<52+(t*gsRH886ju^yK!ciN4=rvy>1xiu6OyxAy z9fkpsByQX30U{YDL`P2H=?}7pf;yuzH5I0wV*6I!ETeLc0^#S92@w8KG_V1}WP*xt7rY2#GgkDXe+c9Aiqua6TKX%)?Kq?sVgWJc(}1 zf~VI3-p!8n}>{>XM9Yccnlq#8AqjJf?`4z6Oh1|UP+ zR6xjg+(1-!BG1b+QLias$8*>{Uj`G6esjmE91Sy>5TEk9*Xwc(xO#}s+p3Dd@+hFQ zOX-`!6?zhOEHTlgm7@#6BW{;2F`yO2oJ`6MV~%SJad3dqK(Wd7`%u{^5LbFo7O*|% z5y25?`~55Q5WvZ#%y{5!|D}|J(l74!P`N{e?8RU$jfqBo3uBPm7gu_+oJ`y!VAj-i z4-ih>YV+#d4;@7Ts8OI`Esco=zz!z*p#1htK&4+&^G09+>$t|9>yQ?8>pcF<*KBeP zPmjGzVWMFPs9m~3A`S*3pG+Lz$yHA0UFz}ttwZgqFYbSNAau`$ToTY=v($-h!?sAz_ z7GqW}vA|{eR!9AvksPZF=db33Yar|x%3-2|tCf4^ry^}ZT$*8cPRP-1g3Gvx z6W!wsGO_|K))?P4*yMq1PFKqacYIauZlL(7&8{P1SwSBJ)+wP}BZrLiL zG(VIOPSInp=5ovtD_dCe${jhC(~inew1r_<0TJkAlfxxZnT=rm&SjHak`_rLgrEih zmR>H4Bsy{_YMP8SS$ z_b%n^X`7UTuRkCOItt;lD@VT&SHWgq{BNI-&}byTq4_RoqLDQ>lG?)}*d`RV`;8P7 zG*?}z8Rh=irkopj2s(tcxAj4dydMOI8Fqp%nJ_#EXe5O*^9d^#D|{adz>Zp6!4#rO zeCt_mY%TY0t_Y`X9YP(&pa3z+ScQPIS3y9C6dR@s%&;&CP>a4EsG1cg7szO`G))yp z*Fa@*YyB?J5bj_lTM9j23MZ`O*~U5p&is@K*WXi^u0H)k&jB$Twi!#!R{bXg=0Wk% z%_Zv%tS4kg(^Q?U&E=k!_E_@nh&Sef@#s|l1z*lts2t<-&lzw=bhB2ddMfqLoG1(1 zr1E3Hj4bFZl-$xZRqs~11}ZZ|XM2+R!|s#Jn(PIS91d;zd71x8m>o%yB8iBq(~e}e zcf&Sc5p45ihh|CfQ5@fW5bol~MFRPzl!Ku!Bwz~Jp&nLqmO!@zkgt@>a; z68(M9%>d5G+kPiuQxeN_8+lW=XW=lq-Sfa-& z5lC+Qr>{qJHBAfvr$p3A5vP5qKxC{na*)wfH&KEw{?{z}OR{?kz_?=*b27{zi5PH3 zRGyK>bQS8ho}rEb06LInXL&f70Ocxv)HJDp>Qf~Wl_;RRd)og?U&d)4+)R6J6<%T5 zR&r+?A)B!RLI>oeJ2o&~1-fNmn+!n;f;O_V?tDz>tk8L}1gCI+k3Zk4LZ0QmRQgRv z=Xg#aTpz6kFX+nTGaW)i65Fx=UV{-SnrEajT~O$6xIhEt!}usWPmW*8FfB+oO`_UW zGfeK&m^yYi!AC_< zviPMboQi2><+$9-qQwy>O4%MyAp>qwl|1aN9eR;R5H%1+EwRCz&LmKdFkNPDG#Q4+ zd3F{Xlxmv#rc+cvL?@}=^l#{hD=+$S+FwZ6!f8Oj+8y>d7pChl2nf>^5L;#m9MrL4 zo;o&W;oMCVm%i#FAmP|=0BiS@a^8w}+iiQ!Rg#obxjqzSl?z5aiA~60x?EV5qhP|$ zY6-h=LBg_Gnx-rEBSFTS1KF2Sca?ZFR_wq>It^fkHP7EG6m*LG{Ua+~yC0lVjN%DIrmj2x3aLXQd2 zE?lGu54}LAiVY&1AaFA%!P;?_I!1m<5zg!^30V04yZDl9B8SOZj!0B2cDS3JRVeNY73qztJ;oUB6Wr|5TsV&wvL+_g7N z;@ej)x}}x7pmHxRK`2E}Sdy0GwHeCQg#w)UPgyy}bbS^7{79I*Hqg|ub~02UuIlmD zKq4cVoy8dr$F%P-iTa_~jr7~qn$tS#8+v4V> zaw*^pm19ho1s%{_Yx;12Rv7}+8}w6VXSqxNEi8MZv}tNxRXOVD4an$FF%KE|DD1Ky zkaAq{q;d~s2&r5@dJso8<+6aYRy6+84}U!x%pmK4sQdn+BtWrpZ=|0RJ4-6(F8v1- z4|W2$d+_gwRY#u%?=Dfm$)dHz<=#;4h3plY!F^OtSyT4e)XEXKZ;ZKq2H=d9gVv75 z^0e+UIKhI9)C|LD;SsU3B1tTJpK)@I(tm5ZX}WTS0O}8D^W4!7b*j>Y=-8^9{`EE~ zhr|F$i##TO^)z+$O9Y8Mk7p^jyUNNbCeg{l@@62Fvm+x3yrmsACa%L6BOC%|XYp$S zSJPBMIoZ*#-8|48J(K%-s<|S+`57uFEJ$d{i`Ic2;m|!Y2JSLCXRk1 z@pH-(4lK&$m_!>R6pk=mb}G;OV_#9n6g>*C6h)ZnTExz>Dwhq~M7Nugil$yIR2oeH z|Gvg0s5qe1yYsV+0s76^3Lk}vx3jBqz0TXx5h#RU>7mM4cI6mE@Pi(nluzcy-)x?; z2sRSmdLmhyO@)(tXFOm6l=%uZ!M~ZNNuuh}?W%$gvt~S z;GvR1+8)Y;MIfP)tkYe>vU3@6LWb`1uxnhNuHZ1LE>uwI_g+_4>`1-6sKbx$j9B(Fj7I>ge=2pW$@}Z3$7s?BTsLzOYi% ze2H^<3R%EeZ(-T<6qCr}r#WQgYXWcK`STPRNXA40wN=QQ|21uzWUETbMY?HPi7P5c zoXyYVss}8eEQp&XYB$F}L7FZ#O+T-|?B#U5O1K1ao1{rF zBH}%M<1u&F4$zmv0n{1^Ng-qiNkH6PD}fCr!twCp7Gb&;rOVk#d>~jDq1joAR%t=r zKn}6J6=M$nlpz1jE`ydTC`Xe^(1bvyB6SD?Yu4bjJ6pMZJ^FGZI)sAPG{M>E^nCwc zEVh85nr9NxWqz#>=55M-m#Jf{Ont$_Av?og*Z?K-m>wB-Ozq}BQ4VLwe|6<{HJl14 z;3V&H-~c`pCD3b%j=q@{6XqBIK3q{F!NE(@c9BH<(f{KM-2Y%@z|byr+9b(h7XSP*JX zFsF)eLq7Mbg_=CFwHA#t^))DXg;5umVpTl56y+mOCKTZ|6Zfly)v_*ky8?vo+IXuB zZ6UJE_U$_&i<5?#V9vzmr%zo@)7@(=rCW)pNOX%Cpkn>gfsAP z+q>h$u9=736Hy)vM=~@5rg^$%3KUB%=ni9HGpT08-otd5B=i*y;_W_wqB8ZZD1#wK zxMiN|uNKyo4EUe2GBna8On+P^{D8Dk$$1({hVntb*j=Tci0=W^wFPoSER;l!@UqIy zxx;go3`NQnkTkmXB+MdIG2%&>tK<93TwohJ${=p52+vQ$`^nvMC9Z}cNo30ebHb^d zHsK_E$0>qoblYL1Ct>BjP|O8`RUs_&432O^xWa%~PZU5+l*jjX6MjSzQe_~=`i0)Z zq*`|>F^v{n*vCeYQO?)oFvCd9;`rp?a~R~3XH}T7h6_ zHj^Qz5@$eg&10iH6i(QnUZfid*Afng&~BieTf*nUnm_NWaUY~`7J^!W0JU5SCMpe8 zaj@bE*cZ;f7KU(E>MW-ccR&Qz%*_)OK)qfuRp%{8BH=u)8F)!dkDX}{Sl=eX@EK%_ z*L-Kv{S?jH%i_H<*De7l;q2uL3OJTz1QvV`8y!tY5l@tddUb>D%RN~c+UP$n<$`=} z#IZj;EFiG1nd*shrVM}`!CuABw-tiKmxD}6ID7fxB&_j$Bm%>q${6{QQTjChT!Vxu zA54cymAh?gOj$YRB&KwwJ(R!>0%K|)rFtEw0GcfH3o8Rl+a(g0G&N(@`p2AL5LvxlGXg`h;=v>Iv$0GiFxBTrsPHb0Y(w7~@Gp)M0jvbE;Rm zG01ZEj!*(pj&(x~z=bcA9Lo<;f+rKB!hk3+A``}CiXy0&4A|ZNO`@hBMv#1tXet5{ z?bxt=(u_Dhv<@?upvbYzWD-%hsToH7{6vim z)N2ieL*;rw`@!<&9Z9AF8_IzBPr4WzE7o_1Q9fqKQi& zT&~T@WKWsA1yX^!8&JwdGVwqGeUDHbCgo#-rm{i_)-@J|BAm!s&)SCdv}oJlQ3seG;wze6C=fYoYO|kB1#Gyc_u!ml7}57+i3{h(7xp2A@ICr63R@A_GfB>f=ZVVU(1u_~ zQxVD_$w3yFsX{aw4A)RNQ#}>--nk>HeMAV9h?59P;tK<*+$<&-GUy!h*p*}Y z+~{n?tcr3p*rRD0&FobFiVke5d8V@pr+W8}hRlT<2k1c%eP9-T17E0cj0(bM3D=;T z3{xYXXEaKUB4P4T6ks$@`8Xpq6_{wMU}%f*r85_ehI<8K&%t?`>PPlePY%R8(xpG; z!Vysqz-VTN$@FHl$r(fVSZp51oiMsunuk20XBZJ5*=T;-Q3k z9RzCz<%293P31-zke`k;Ld~vRws;MLAke2gTdGI33JVw$^$dKW8^ULY)Z6C~c|Hmd zTgjk&{FW?Yg{BG!O=T*V2O!BbH=0eOsZI9^s^i|!DYzJ+hC3QscSHq@W#BCAhVYr8 z%2w`qn2!P)hXzdfU^LbCt>+TkXQB)+zF9a@j{Vf8T#zeX6hmpMZxxh?hGj=77tVyk z1eV_Z2u4<(49jiKV;b>T6Lpy8_D!H(TU!C6sj|881)x}xX*xybl#_g_{IpoPAd^ct zk#MRnhjAnxBO^}AF^rIka>gdkX|&OpjZEe066*CHQ9f2R;^b)a9s!niPTyB(syr&P zDQU1l&`xtUIqK&O&e~}P63l5bd())I;b5eCw=WE3=O_^;U*=?JShFxg_zILOo+de< zv|Th0&!@S4t10Cp+QDCl6GDy9R6p0;0H(p#IXA8$nNtBKKiBvtDk`G~E0M4hHkIJ^ z6wJz5b|gb6CF;2uMng?SIb#!d(IX>s9@Fg>GxWJ$glMX0gvyz$in=7v0kNa*50k|S znREFOsvRpDO#yPOLG{N(HxFznm~}8^koD`2BZW9Ap#zuuN28(J1`HSh$bye!DqHq&%R*Fa8FkL4T(4j z2HqV*1Sa@pA$(-AwS7A9yh7#j;G@mVJTvHX6R6iiY!bGj@kta$3|Pve3<7x1hsBAX z9;)BtOBxMDcqB>`$ropw>MyArAwaQ!-8y}+6I$?vjGfIw_(l&t4n-j?@>u@O%=0Fl zhk7$}ysM#JTDc9Rd^{SzCN!0uxUg1R>^#N@S2jrx_p%d>kz@b^j&QDCWmCOnM~VEa ziqYp0)vx$eR{n2R^2#aHu>$s@je@5#gpYYLS-Is=3ec39hY_i5%ws^kIt2BSa2SxM zH6jNvV96XJjc{3z4+rR{pN@$}Gms33Blo-KVRERm52s)gJIXtv4w8_1KZ-vcwkl&t#s8nzBP(Yon257%2$fNb_Xagylvf&<6ry)shj`$tW|A73#GoDIawtF5o)? zKs42$$E*r#gv)|_xG|;yM5AFpW#wk2`VCI?hH@`}8lbd{t73#%_$R-K#p&L;G<)sC-G28XZFO~>S>BW9{NQ~l?YRKJBO*fUaa_l3|nd@AE9>=?6fw1sc0 zThJ=T&O)tDz+TzgPau5J){blzmZV8&z%`nn+l92~Q7R!LoCgNV$f}$YPCFfOE9KvQ#dvPN>|HmcQBXI*(>!*HNfFOMo=VG3r1Scd_azip0sL^$!z#`elj-k>{F7D14S zJ#*9GdFTnrI@z;!7=-;cey{7@@n}e=0t>G#1LmyPP`SBi6B(NY42Z5Qk~bOKC*gC4 z601kq#{ndKmy}DnItNX~=xTgAKGVuMJ5)?1l!Y5T7Q1j{=eeLdS&Ji`e@vq~BY7B* z5=YoBTG3SGr-~glv6@@B`;CWS#St+e^0RamC7P7OA_=;95mt{?Yrvv2}HOt6takX#hZYP0-W2km5chE}&UN#(h{!vF*7Rlh+9 zHTaNm4kmog&ob*);_b-$7-=-C1%BGVBH1M1A!GYg!cy61Ssn81%5@a%n94Yap5$~; z=~tAhnb=wEP)S)?zsQ6$Rw0W}^4<1j(Ib*dPsm_B=XsnItU5ppEoRTzXl-l(Ek&bQ z+%Mv0394K*2-dK8rO;aPoil`4d1v3;&2&H3c2iX&Avqnmr3>Wgox8EKX%?0yzh{o6 zjo(9#3KJg4%Ex1*+g^r-1t6(?yTU?1GT2dd*g~vw0cb1gFrr7RY*do-QJd$mGj-Sp$V<}- zL$u+tVGK~%KApG;S$skm%aKZ04&|oSA~Y3_)39lh2g>|`O#X&VEXrkAI+EasHr!#9 zlt;1M6F9fYk{3~%l zmtY<{27r94{*C}a?zHg|+ABM5;$a11Se=1~0%GIW`Yy&U!JwmyDzxkGC_$!`zl2(o zkkWm!AErzieU1^9m{_)NhH! zSo&1M?Z(tz`;Pz#m1ZYll} zUJ>FOE}f25gvOneHkLt5TXgeMC$Iy^fJNL=#3gajlU!rKXD)rcn480eq9^xa^X7$1 zaH^hk==M3vz&Sx~ZnzFvT}UypY~QBM>n)_}X*ZmBn_*f25*0msNzv=Z&(6$gOW~HZHDRi z$P7-gNod1((_un92PuSDD$sKX9Go;*ot$~%$jLH^XDtkAwLq|1EPgC6t7k2~!tR~} zt-8gzk{H&)v3-^$z{%PFX97y%B$X_i{kk!Oo4m)#8AzqUGmtvBQ;SpGzeCS#S93QH z1B8OS(;+pm7WYHT&+V^3LD%@oN{pmpajFp_Y90y#)sU3kd43MRc_`>i(IiUoIGx}& zvqpudR3x6O!^v$wdMLVRlarETC(0~clv9Kj=Aem+ zu18yFQes3It&dn21)-qq!4VbnhRI1@lyNSK268e>R8(*ei4|qG4HTq)&JUk+-6UhGmzgy3NZI)wU52;n-NDWP*kC(xW4Y}RE zF@W!|6aFdoEAE%rzq|@~m{Ol%v0^^qiu!Su)fMu#tLo?3Y1$&*bhpFm+3@kOVQ&;VS4|qL$tpr|9T7zy9-`uTD-VsGKTkiM%4~55{+DGu54&WW zKTU=r!d!(#J~NMr)~vt)Ak`*voy#yzl_71p#pD4gfMeDTHmnjjnRYSeLKj!-sw~kQ z_;5n(Pu%&-0Yl9xryvOo83*c;4Xd++h{igzi|h7L+F+7&+i>I#j{$cOlU7QDl z>k7ezhPYd>L_MRjt8=WXh23$t3$Qcb`VvT5=kk_IDGg^;F2l06%tmn^U`oSjHs~GP zU?(GQxEENS7{0PGld2_dW_IOXV4GVos%!+U-Ef7Cl`S7+Yz8-DZt=Lxic1C4MsqJA z9jTgmj>xJRcU`-=LOZPeK`t8q((#V_y_~=~k|hY7HRnAyms*zs;l=xloC7H zl>pIE*OHbGCZdXFZt;?^WeG-OsouT=tKR#PzOfIkv}5J~1U-Scu%(@57Btur1l+vm z1Ml0mGXyN26zvl=o_7ntyk)S!0NMJWH-N52JsYt9a#eVYQyFz9LZM4sIQc=DuCCkD z@34J*VFm78VduD7h4?(~;<0oxST{H{7vd&#Uxjp<9Y=OcRAUQIrb?}-mcb8{Uo#1->7Zou;$3?Y5+g2MFr}vN=b8^5@&Wv2!1P z9zf*oB5WM5u;T8pMuXLkJ+n!bi*~^B6obUJGMo+Dw);CVWbpxT8!v>d=JXlcKcfHOdt*|^M7X4#FJ`1tt$W`F;`%2}32S^xk50d!JM zQvg8b*k%9#2dha$K~#9!-J5}u+B^(|QGB@o0p9;{o5Xe^%hFo*U1$FOnQ7s=U3n8Y zF#6E#_Fp}w?HCdpT7QnO@2_veheT|&B{Rro`QHCbog&n>kXB6`qMiT}fp&)MxhR)OIRPYM&8}%2A%yLJhY)Xt3yIK}LTZv3WLcK*z5l)6 z#=)te)oKOArWdpD6A%amK4W)J*Y?oS{-tBJW&FFEU$x_BGBrPuBU8B z^&UlGYKyieLe70j9uICKhX}MXq^Jp_gwwRtuWY7hYa-<0erXHrfj#b%PXwAs8C*f` zpU+h=te+6bCqg4nDK(Jfsu;E(KI9V{8cQOIf*_~s@Gut=n?_3mN#5`1n!|SYEee`q zL(56(qIQz^>$z2&=Mav&?;?pUV(m;>7X?Y4_vdy7`$gREiX^7k&~nPUs2wF1JdS80 zp9nN1rRR5NeeaQD!R_vQC7%d2o>CS?QLcjTwe%nnXk|)S)Q)mrlj*Zr$S(qorBsUA zpLU4W;~=8?6OAcCV@|1QAj$U^9mkjU*~%0fT1=@GHQ)ax_Hk{Rrt*WADF&#WDV3r| zj^l-Jno_}O-%C*WA>$JFpUTZ%Y2+G9DT?Ap^t87F(0+K{4m1$|OrVhgYFR--A?*6$Me~cp3UU-|zSPncmAE$3O2m ziHpa6FqW&dLyXn37GGXPQ9B9c?L;=Md!bY^locn8U3{jZg;hW3+)tFIv>b6U zR?FqWt273nm1=9_#!ccaB#A_uK;=nXM&c_`HWCr-H&sy-C7YM#7+p#SZ5{Fj%UmVi_lSs~AbwOOwa*lBo-32)ZT<&m=aTU!4IR{+sf*Au` zrFKEi0hi;>F|I;>&Hk8y~qCokjpbs6afqr^=M6c>X{=AXFb+`_X@Z>NG%AZ-#v!UwnOwLc z`&45GRk;>ZOfFoZEp{3^s0#J~&T#|Ai*vZCN`RjI&7?pX^g$KjNgri2 zl%W|(Zb&CaRq%VUfGUaLh>EjGKwU^xM}+ZBZH8%Q3l-J{Q;2C;1#H^tw$Ld%5d2y__|@KF${EZn&7r@XSIqd4;RRF85?|D#JB_FxKnGQwCvVD&zNN zC}uRwF_ZV<>Fo6jdQf-t#r2wATloXq1LaL^S9CF72b9~Yi*yfuF?S9!04@>xINpG{iHDwUw_4-g(Nq@7Swfps! z{*Oxbj8L$yz24IApUPmYNk7cyxGMZbxqcuO(-|e3|$1)mo8Eqqp@Al_y zTj(6iXv}3ef?NXw#h5|bmc+4))l>7L4t$ir5hV>g6axd->_SK|CXQvSt7}3eQ3o-& zfJZ29eBj~ynm*-bdPX3|^=c!8r+b7VJ`?mLdBo-T>i#uM(5_ii2hRvabjtR19y2&D zv~j(B2!RbQc>4V$+t;~=l^!`>^5!1PC{E5lLeaR;EM-s4%SJ!%&nqP19~n{j1N^D? U6<`(rIRF3v07*qoM6N<$f?TKLMgRZ+ literal 476 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 literal 789 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 literal 982 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 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 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 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 zcmV)tK$pLXP)}z{G(R6NBM^<_2OxyO~f{v>%T!u@J{= z!2dBoP|O#QIpi)VD(3IO^9f)<1?PeUkbeOD8SrBf-Z6K9Bqe_uk4V@%=N!}&Tx1Iv z@BH;e3T6BTqbGA<2wsF>3UD~8VF3bzGsEk}&4Hx_T!d+G0TaPMnc?+<=3rP4tGXrQ z0z7lMQ$S`Erd(X0Q1-QDCR)-@ZV_-%j)x{UbDs?7NpLGqAZ+ zQucup-_T|#_<9C;Oeeo|?aIpAt#ek6A$YjZA-$_tQqDKdy^PW`JyK|?au;@7?ppGX z@NY6tb2`Sr*2;aw$&>lV%>7R%4CwX&C%3p_8kvtY$7rWqxe=VY6h5PG(>N!WTC7xFO`y!fL?H2jkBM<$4}TBj z=6FGsrVTx>#IAA7j|EPD){lPCU@2wvsHNm@(wYvAzx!-%vxu+=eLk@?jIIrxV!@lbh zcZXA~%4Nf6X2Tbw@JXRZ=McTk_y9&K%euiW&!+Gy$~(6=1wX*-8BRHZdN*;}=ne0^ z{Q4Hhbup?iE)GTgmy@q9bcOi0VNg#oj}wbK*T#8Cff98(`o+p98jalzkLr5#_xKqS z6eOp+(X!CToeb&#VLXGdyx9U7JPL0W@62%Ctbp@jpNvaA zR>&R#M^LviM#ZV?8$?{mZ0xx>O!$=50}>JR;%PUKmJqa8yySwCyx}s}t!TNeGlxA% zdh5;iqkwU=dvTh^tf&nhO!oIG`pbgk9@|HLVM*DJ?<7e=CaiS?4XfY$-;jf@d}H?I;%UN7M^dGzSl>>PgCX&8&Ex-~H2$xrN>C2b zqAG(CJ=w9?KO1_^SNU|(K0G*6Yedio;u6j+AW;^jNy3M=Z~)y3MQ2xS3y$Hpm~a_E?2igimyx3^PX zP`tbdrls5h@>X>mjZF-pi!0x9PUg6@@s~D)eB+sJS-JcSji55STAnB-qfTy|uM1Iq z>xp%Vxwmo%FA+h(Ap+?GxVfx9Whq)_&ks6sWJC7wJmgbH)hrI8ghyP|6cl)GkBeVH z+4~~AVbyYES?Bupk)%}t^O#-fe8To`#Qwk33!3)KA@hbG$%bnLmHGMrGI6TzlsVqa zo^!h8O+Vn(=b;relZq}|MhsOK6m!L#spH~{=@A<*&ftzy4`p1l8BD~A-kxTn%mZX_mGd^g&N`jj>uHufg8i^dHs^W6106yc4mo@P zCMI-=sP!q0%_++|x|K2g%_!-XZ26iM9on2fuNKrXK9KOf!H&b(B0(z3OL`%L8#zxO zDCe_t*snf>OS|9f5ft?VMHWaWROgf4Gam4OuIQ>W`^`l%N|J6sP~Nev|HA?~U*Qdm z55#%CEk{+^GN757l}#TP$lyly@3C*!x3fQfnc)_4mzS8vFR2IzehqfLr;grmQW|iqyCl8|(_d#5J&m;w z=ZS~d7uQQRoFr!htB@*M9?!U==biDJ#Tv6!8PEINJ7X)5q#ny_Me_VwP%I`WGcESDqV3^ zLD{o{!npDt8+MoO9(WaEKwKfzbYIix%(pLp!9L0nT-uu-0tDsZED1ego&-6cG9Pj` zyyXEQM0qj(ekfJ3lwa(+w9CQB>+l_IX(m zrQI^`KfK`Mdb;$^k(5;kWUyx+&f~xk4gO(AyU9KK6gMSD7kb0)oj^t(Cxgu)k3tO{ zCFTJn$!Hx@!}@gADk~`5Lnuu@Pf9|RjjJ_ey|;oMJiRdSKl0NnF3;d(*?Bti>^srm z_4vDH%^=p(t)R)le8Z!qEzI>Fx`&KAz+I4#l?gsMqg7f^q{7KHjH3#B5940=F9@pB z3(g~h6I2M#d9woc-Dntu4%w`MpgiExaA^zk5FPsWUJ}~#37Jz43OYDIgc9Vja|fia z;W9ygMtTK|yWS7n^g{4Fa57i~@;_$V6?HuO7$HGr!@K4w5Ht`$(8tPy={RJsGmCi7 zSL&|U5Ab|y?X@shpB6besT*}`*f*Y7@67^#!$Ogl<{a;wU@w3TQIFw(T2ccv#- z+&~2$KzoDgf`ST-=y#3Zok@nlcyPnW;82Bto)8rFrziIgV81LHu%amL&axTFlFJ8v zN)DnHq?b|jvRR^{$jusCg+}ga6+AkpGkF2Zi_5<2)1VbC3wnZ__xegVNKVHga>9QpA=_zL2BRb* z)L_35`^B<-6Af4~nY__!#(HsFjM@Lc7lp8-WyG0GUfcP1*{OR(ONYGN>TdH1OeSJo zTv0;_in>lnFgW$|S-7CM@6Ov|d!ntTFfNOVz=jcWH5t6uf;iUsblG`S2Q%A#hoH}Y zSj=>6mgKVBb!m(2e4;jy2&0yyeUT?{Y2(FbGI@10X&025M97JHqO1sI972Ih%_xEe zjtsZR^>EVN;iFT+ct{?es{@7v@eX+StTL$6J}3F{#>c&OY_x+$$)4=e;dD89#~`rzNB1Tz5yT z2`y!?dqM7@LM+=?S4&>dqVxAkzKp(YR>+buamYc?p~@?FsGES)h`oR|Zn>vmKX)D>RIgIxC5Wl$_J*26xN*o7fEQxdBZ!pnd0aV?R$9q9I#y z9w$eWB3A+0PGf3A(2u76m-Ztf6KyJ>JwYi#<7W%$`;wCPSx-u3Sf7R;&G_p!UO`FS zf>PZmM%uVUwiu_B4QoM%-EcbU@I{bSB97Q^FGj=llO^X-T!`pnwM0hWJVQ2| zJwa5XS$RXYK;T-%W(WR?oSuJtU)4{suY8j8n(??jUM?u|0F#pF;X)M}#-II4)OSvc ztp~zEj7!Mb3?3uklC7N+Omyu(m-AY%uf>^N-;|_$zOR?WrfoU1F3oPRU!=V3U|aM| zdmPm6wJKG}&l<7cFSw?~%KoJa=^@K0PGww*FjqD#1D9%Pg@*BG68+?y)=)qRnddzl zk0o-v3?90{hKtep^^VH169o80s^)aeX3+o{Kz%4T*&+G;Hmh{4(H^ zvOmeYMzMG|kv;6Pb>q|zn5vNR1@7v=d+3;Z3Y&Y{V*yI=K zf38MAn`FsceIjLllE;U7eTyg-`|uskW5n#ztMo&&VWM3XKxWDH?X4Tsk&=f->cmh~ zI4BSi?vMj})xJM;B8w+jNv{?&Sf!Z6Cvht}Z?W)}(ekYyy^25mPT&AGB>1$HW#kv^ zOF&Ec(HV?-ZZ{jYKR$d2*JBALnw1l3;^OEveLwCx_>zcyGK1Xd>`*Vhyl`{OB-u^K ze)O-!r1#}_e;cH{oX*%iM6)d@WG__+N_g>c!(r0TpMUprS#P6AKnym&7Cj=dFB!Zw z_kLI)9dWo$08KtA#@~+vzS9iOyMm_i{+Hi)eVYlO>C&40XOkDj;a{5^lja*GR|)-Sz^v_gEiQ5*vtv1TH@PW|B@Ozi%iK3pDa`H1TU{p1BZZ`u^vm4agXXzprug4Xw69>X2urTqpT_ z^W`M}eWMM(I6Ov)Ce)MLA6sGfDazZuXHE7Ss~dRy&C#25^15D8oESgg%kEaw5fc@3 z#5vip=5pGwM@!B2*jD^dgrJvvI@?#jVp2EQc&SODPNx=bN!`W;j$SmW5MC>Q18G0oQ0WilIo|V4tRwW!#CyfPtSOe@gD>~}9 zgkz5dVHk14L3DZrg02Fx0{D7?{rZB|3*-+?8@*Q)m9)`FLw)D^8tim}B3&jZh{4;h z>l8Ih<+v1K8w=JG6r&Z9iUB&^E=S5LR8zr1^2ZUh`rfNZ>aliQLeB=w{o7dKRhOqqr$nr4Vd38l+r<7`N zqVP}3`JvIVJV#v~f3p0aDuH(7j$w56ElX;~^d`Hkp^ZiaWHSiEXyr--eNXtC5U6}e z8P&%HeDN@tix5<*N&OF{!2darRTQn@lTJlYb)Q)rD=Qij2;}(bj0e#b<1m<4rZ7^~ zv{A&UOBfFLbL>WFN`);D5Wn$g(SHXrpRbn&_M<=U3icyd=p%FpsJ)rmHshV~HTn zEl0g9_&ZvBX4sFCXi~2zfUJfE%KSL+LqmejIEjf2juk}BA|U7$OLKZfM7&#v%ype* zHMCKo7+<=CVel)_D_TLbEIW}$R3n&ST~B1#Zu$I(X#sSb@YFBPbTQpCq5QmT03E$@d6HRz@+_5aXLNekBCWB%YJxJ_N17 z^XiNoN?TJppOm7}^^NGG>hn{tKGy?TlOh*BX(lT9f(npWwFM^-NFz#1ajX#3hIFoi zRIwZ@X_vYRC7R=%ph$ay?qo9^&%+fE%sT$fX^HV}xYkCqw)W>^+(eTwygC zDIsd+qn@~ke`c=#5EWKX{{pLrp9-J!EdzQD4AfVYW}-OvmABI;Zw0A$WBT?W$?haX z8$BCnB;UlIyGErQu_=5M6uzMR;x(#WgLr(m+zyMVdhJ`u}?D2AY#d(>@9ZAZzgJ7NFwg)FG$H{M>cQP5t8c~)aIAH-QNav% zKpPELA>)vg(FY+QuG%jvs^S?Hy#~PyfP2ct+I89+P_AmCL@flWr;SPz1=?t(pgCu~;1+S~VZXDEl=NRwx_NyRuH8e2)kMZAKeKS=aVC17-?{n}iCT z>B1g~?a+Hh^`dtU9Db;e(}Z`;1zMLj3S{%a5)c=!0{$g=tHYFs zw8dV*^^GU?wB(mJ9+v@z!5_bo9|fobx?{h9pSrlqL~xpCNVXLOTAMbCGak4=Tpo|Y zDv^~`ztw^>UqxV^6M(NPh~?mq-(K-^-#G7ioyjBEpen$t!xL{GN}<;1P) z>^I4s(5?>?(zWzjqgXS%I{RZ6uBdudNh}9{{H+8(F0jf7-MvQ$(FcGDChQhqMjHs! zoHmL*W7F2YqPlaohC`0@;M!n5d?~{_d-aNRfv({1i|TWrdsPPkeE`UWJ|YYd6RQfe z32k(5fDC}3!?Ob}(mot8vFhW)m$w28?v}(4>G`N9sz8Sk@bTER=oaW+c7b{PP`v@{ z*F!C?D$pjh(P&84ymRZFv!EUkH#%?;$>wwH+pJ{Ul+faQTcE=?-g}7<*JY*#x`U8k zHAsN32X?<97$`6n%>`PYHj0|U=7Vj-s9O=v11;(7JRG7C*q95%avt|Ytcr1AZW34>s^?>40EFavc=X1Vm-OwVp5O?4ZtuT0ubuTiHm8mHn~s+--XSjcF6QF17oq@y8K>pls0STP z_b)I2-PI3e)e4%XV>-<`ykEoT9s2agRRvmyHVQ#)5sE#2rNJ%Ao-mmfLk{5n1Q(cx zZ`HP4z_6VTLCNU|2I|Jko@Aw;T}w#9Ds^u6T^%zSk4pMEv*aI%#4OJJbu;8@qBjlwI%lsyYDWi6L` z9+inf;K`r;4@p z|A=s30+mQbTpxn|640aO0&PGWl_)y0o0ema3t+ZAK}`;`)$!faKlsdP(-M3Ei6ZvF zTmZ9OM87*7=^VPiP;aaL(U$djrE!iF7Y+<`4IJwxw9$yD$99FTs+h9CczaxKCx<(; z6EEcW24iBdMKD9tG}Spth<;3$*`vA(OzJIai8r)7u_>WN8~P;Eb#Sbk&_)4$VMP}) z-i62IMh=^hYoF2bYew*=I%qs6S|j=~UF%#_?B^>!32q{Kwl zTmxU*cE6UEH^qJ%3$y`k6l`uD1~J@&pkdH_yC}jThcSXLdLa7!>C%!#L`VJw7Ob}+ zecsT%!VgkmVU&P@-mHpa-GnxZlp({EEhu*d-Sd8Dfz>>E6IRIYvB(*i?(5IByePZC zl7v6_)iD|nl=XQo`s7kx%zi;qgP=_XT9Y=4At@tLie&<38?Rx3a5gzyqR;@-?OZXA z=nqft1urnv+wku@r&=Ek5T(3e^NOcwfvnl40yU?NB4s2*?<>S`ACO)dE$|i*&WO06 zLW2WZ(6b;JY2imd7Svy0sJDK={XWuo-jU6TUDt|nLyQYjw`A&o z;3Ger4S^h8wAT`VMNA3@DteA7kHh-6%K>@X*1e3z-1K(G>++mo|!$ zqHDAR>E$t;`bcgLXM|j+CE!b}1zd1pY|CNAMGo6~5cIFUz))}f5wSkR*so)c0|1iL zY65LU8>Nnzl=i2-lbQ!SkjB@zq(Lu%jZsyR=L1n z-Q_tJx$r~7JBH9r1zL|biusz+d(l;jIz-%MBB&6^5ppRJ1XY0WUoNBjqkV;g{vX|F zY+F7|cT05oe$xxg6KLF5@Hn4365X9$VZTiUTAMZsK{@Zo2VD(zwEGwaDBiTCYN86c zMTGzekCvk+o#Zs;+83vYe)BtGLrj;HcdAKVUT=LtEj$jySD!=GT%fgSquBJ(go^b3 ztx3EDL|pD7LV#NZr7s|;4W2;!v?o30u6=yojT{{AnTRRVp{L-oD=#qA+hD{Akag1D z0LQvHZ4^nTLsP@@~Mo)h|b#Bm{d0=k||x3X41&>s6<9DaPGxR}n* z;B2+rsBteaS}xCc1r9_UFD-t`K-ME{d3Av{r;XygIA^|;97wf;Iq5zQjV|VLD82Yt z3U1sl775JP*-hBCkT=IuF^h~(W~@JE`4?EvsU~QNO9nlEkw4Gd6A*6K7ie?ZsLzy@ zziAfYqDRkqpGd^1f-4Fo=67v)W|^Rd-@2XBZc^C$4*EB^z=%+u%V>Q0K3HcP3A8zF z6inHduiAD66uosOtBCt_d~2#hviLg)SuhsZxV7hUEI%mSi7pBq0HVz9;hM+AjX9z0~Z+!*}{H(C*aFYF5{?`#Fv=cNlQ zVYAc-Dn)=TZXnR+w9$y7eJMgDAB8zy`h9M^L=2`_e%J%=!DSTtZzkg-ai6F~xbK1& z*bnXnHpJ(?^&9DKCeY@zQB?J!_acwep4XPO%80?H07ax|75LeN<@vcqcu#U;ixAMI z7g($_Ui4h9w}f?@4G8q^X`|6U78Fyue^_5|&5sB;%zLsg!mU!IG8I606YjeuK}|W? zP9riG*hgySYCx{d1=<`|N4b2evHyJoqY`nF!t*u`ko@po`9h@v2yZBQ+bX@l9&Rm` z=d}cV_cXulHJGy4Vr7r=ylAIOB^|$O<2NZF06QUlRds=JdFBfY^|pd=_OL1Vdc*NP zLg-!cUL!>ej$gi6(l4UwXGP>-j&R?FFEDkygx_5%C!9r-X5G*1cvC?q9-?%^%mFc2 znD?6@c!^r&7uajEZld0XsFi7|041)X&39b83=cX??sORg1WwqyGC2r%zANw4|~ z4D}YQ3x`@cQW(&q?izwd4SB3l|D}Kv1iS{S)#kj{dItICG*Db%UcGJkmg8PAkuSj{ z969yS%DEVh`op>5p{+oC z-R@6bf0!f+$eJ{W?Qsw6!LKex?}qmZ`Tl%3TwIp4RB!K=QY*njYc6P9sEB)-C{9wX zqVKuv!HZ-g-YXKOZoKnmu{pI8!ZZ_9*71(l0 zjex8`zT*4J8}ME`$NxVFx+AzF3$6T2ebE_!k}s0x5sDb%h0v$;E7f=qs3|M*UN;vM z&7!6RZmuVQTswx!m{<&`2>Nxmv7k=%El>LFcqiM+K08q8LF59CU_IWef6IUXT*T*Xo6@{MI*+Yc6hHuLVU42 zG2kCYRiTX?UpmDi1Y|uGcrNDw@n{o|D;=zS6&3}Kt}*Ym8Q>PYKmRKBue>3;+%*QU zgC~k+9WNs9)ZcZ2ic=y~OqT2h_>RvHC7PWoIqieUVBT(oHUWuN=DqrY0-#vJ`}->h zx&zoK$HImo3do{BG?s~6#U%nKEGW&6rTE4vxj@#J0YOQCtVFE^l$XT_UNaYjOV|dy zS6@(%_g6-5J+ZLSdNyWrk~K5zRYBwN=+}<`kSfFTfG;`CW<(Y?hlQ8tUc{*~+EUwf z_@Nrf`WEcLwRo>v83gs3xKVj;lg%`!08KG0uQl+mf|kqkL;));SGB@?hj%ML*5hai z$Qp(WD?!m!&U0bF7(opmOuFmwUQu!_G59kBxGjyjj!ge|DbQDWQJ}RE{qZ`p(I5s7 zV(4fUgl?6fv#A2IW?A}kCn+D40$E*@mnAchCaruvTATNZB+jxcN)KGXt-ptk?QLc> z)`x}e8?Q5)jg}Aq(Ir~k**P*X^kW?zMemzFVdpYC&VD8VeqIS=b@`!+cF8oy?w$2` zuMkv9dSMj8YXfK(fK)5k=oN9Z2sUQ$qneHW9Yz3B#L5~7>s!{eoaCz@mr79#*?Y!& z=RKFb(CaVX+yg%pl#kJe0Ax1hz52vp5}ROrg2(E?MrRoi-VdDDnN0_%j6{N9mCM4E zfGkLp!A(OQ8`rL|98Bdv*2L#&o^}3sF#^r8G4B;gY_3Q}z(!9H=CMX5yE5=?^>one zHXj;VX|I)m!JUO^GVYc;yj7M}v%J(QfPI1|XGw5##?9p-%`xe&&U=*vmKT(k?Xr-> zUx`USy(GI7aS+o%vwJssT9^#*Jj6bV<9BM9xJ-BBVGy)L>f&ZJ9dNj1cube437X@| zyw^zIVb`WjKWoBcjXKxnBL(C<@Xni#zX(Dr2h8mM0Zl!g zriaG_&2e?!D|K`dPcz$PC8e(!P}J5Z)-=KE%!Y!3$Yn#+!Sh@gnn|~U^ArNI?kO~# ztWLr_P4ak}4xn^Z-fN_i7~D{_t>rI#5nV6#iDDaU%#9UIKqd0KDmb~*lF7SR*<~((%gNrmn554)IBmv{hr^%G}yHSAP zs*l31bWc1Qmhd!(2E!!MuE~3is54hb-uYy5IOb5G$-G$T&%OX(+h_nF1wsjM1@OD3 zSjZy(D3Ebr%Ydf|Fv7tCHfSy0E3z0d_v`F2Vy>iI4M-2YWSRl*yvYCt)TMx)iQiA* zcc2iNh(l}xba2iZEuY1%Jvsuq!vmDA&3lb=(lPhr2UgWbh`E5CC@0i03-A`a$(Tbc z3y1$OOwI#-R{>ceD02>EC4jL&*;V2(hlBNbuW`aqO5(9cMDrV`B<9!)k7mc?=JVv; z+oLvm^;(yFA@doKkBo+ zA9Eu0HnXvq1&`k`@?}pu?qWlIS-gmoz#tq&a3%PdG&4NS%fzQSZoqp*%;CjWpxz}C zMTu6FocolRW{0=DmB%(1i;V1>r9C1Q3C#tK4%5!;%CP=IN3nah_%s8T`Hz%>Jk4mZ z3Ga1}+$0v;q=A1)Qo*+^@GA(Gm%Vb@1ANl9iW*2s3=XU3cNjTJr&C6z4oZ$98UR{T z=#d*GQHjYX+%eET$TJ1??G5iQ6`s97<)wCQ5dSD znQNdOeULr_on-_~d zjzVFN5uU&tkb(>L$G~H1x(q7>Kad_ivA^dOf^66L!qt`+~vJ)i}_V}uXsN(f-Xzcb%?=5 zFPkME-g(HpY`oU4F^(*(PY6=E=l3xDHIzvHY!~Sv6I}I%EiJ~bq+!cDIwfbU@tFKD z2pVc^#QaLU*GQVIGNibbNB~bZw{pHu^>j2S!{qF#yyUI_*=R&;-#{zJBpK}RVFndT z-y6%0Cnke)N6^5^Bgq3H)+#Dx-^F8Y%zI5`croWoBs5>ED8J5JeLNrt>f*Ay>!tjW zDAL|a)%DVLkWj6ilPdH@dZacStJv1Gm<13G`A7G@O869bOb1Z94(}COIxz=9ArSy| z(%Qt5k-y`0wn6b<57*53lr_=Jm)t-rk%;`sV%1S-H3jll$hT$kI>s>5)X3m5#|}>u zfYN5X*RH4h-({z{ zMdJQ_RZY}K*S9>)IRW@1fUSJq>tBa>uT#e^yYO;idJPqGc>{^wE1X`j`RidlgF^H? zD#-i{695p2qMraVS3+8id%8tY}4o|F`E5Q{^m-So(SBT*>Sex@kVLuCvtSJ_7W`tmIYxkSW~3hrFd6UXk3 zuS4ZG5=V`Vmj*9`nR$11V_v%-O#h4>1LK4xy0ePyarh~xjIgmKoK+s7q{`CI5 zFiIXu+}KejDDjR(AsyU+{qc?gQka*AvJ<%mpNJ=&b^LQ583p=G#;&RL^z86Fjuhx!^Wt(P=#Gc@Y8F5%;8MW+(d$^72N{*|up#qNPvyIgxfm%Q1l0ZI zt2u2nCus}Xx>^B`zZGpHs3E@a<+schyi2XBmH+zBuMu%b;W@N90P`XtuYsrOfId9) zX$xIkt1 zSyaeIm`V(urjr)F{xI(=`r{&k8H8I}W&jTY5|PyBf>>v_`92#0BD3}oUxfI=&C|mb z1=Xy-?;fTuo{>t*Z=^1={L3ToG}kd7k-aSupwYf1+~S1~gwQZIV6n}EKC7I%{ow<1b=&*1e+tUnN38w`>QcmJO@Ht)w=kCBw=jUn8c zFE@es=iN##q=jJpk6N0?I!HbOeQnbbtn}#ct&CRM+&qxMf~5RL16hec6vs=3 zi^-EKZ+xF`ymtC9qWH|f*P#FAgSu-hYN?3(deswr=jOTGa+jr<$~sCt;-BA>$&JTN zTubrqBCBYYVZln2GqLh+Mzp)y{C4_o&4Zu_3P1V8KffpY{^$)~#TK>}>Y(c>XMY}q zX!HM@>aZ&`!Sr35kAS44`Ie&&h=1PY_*^5=(Q$-2=rHB%&&=EbG^Kvm48I#CT_%X6 z@6<^)83c=wP@z<73gaib(FKsL7<>lilCF%hmGWkg%BV#!2}SCI{RI1 zzk&5Rl9HA`cnNPbib=qEMAaz0ddk`6U_DT1KE6m26>mu+K^-bZcNP1?2IeWw1xfjA z$uJRZR{85GXPXNOdL>hyl1W2oM+_z$5~qQEY@sgg!Bl>iqn>gGL2>=+BwOhr>d>BQ zc`5^LCj-O+Ot?`4`D^2 zOI`cH*%7XgKj*lUG^3nBo0u6=BlI&X*Of5UQGh|yESqUsjC^&-@#^dD3iiV%)~Q4` zZ$2_R9<4+q;1Mgy{E4eci%E@NKuI^#g$^-!cw_ov)&t9eWHZDOXZ)lZK4gJDOezdHjIeIiaXC)nu{REh(7B+s77S zQ4(||_EEROf}+bp)3K4BOh6Ri%Pnvq)0@nroI#gmLBaKGM7xYqhW!m=hgh400LhV% z#q3bNW#teHq}g%y8SD>1jjUt|etbUC4DzQNC<<(!PA;M=MXwOwrD}n4R*pRKpj`EW z8mOa1(^X(lSWwngLoBFcy$Y|$j@3@4JjalR9y@ibN>Ixn2N8O+03{MNWwg^?EOZ5p zn9I1B1_hlXkJ`d5TkL1*LGam0Q2>)!O?5nNp&}Yw(~W#Z9fG=PCS_~3K*x0KS6!?< zR9secQ$d-hPAa+Pl(T`(u;!%GoRvZG`PvaP~UbN_VPH zlM+x;JO(DLhUy3qR?m8+Ql~hxf+8xY!*oniqo-=FF1ixXm4f`pYi&2%J0!o@$@{w%S;!4VL-bJ;ESEAE2^B{XWt*uC>S!C=FsAK$x z{W{pWh1o&TcOWRjhdMg(-&$B0m}m-lv}I#$Xp~X3<8D>Xi=;B7GgI)C%SWI(RtO6E zls;$RE?t;iO5GKtR+iz-2PPR6#&0sWz_+KQ+0_+@{co!pfuzlL4 zx8B$5BNF71L9#ATwq90In0JJz%nJjYwi`vhtMZDG0w(9xm8o(WgaA)a5Lrq5zrFVK z-#=2#@RYX{O^~xz{*YY9*A_yE zEC{38O!uk~B6J0QD8>$j=$NJny#74#7{H1MJ&PT{Fc{<;51(>o{u*>ZIm6I?3JJX- zg}Fmy_)|UghYfQAXiddZ`Ar~tx?bhf0Y9{&X*u1+~aklGsf*iLTXOUw*@kq4zhG@W^Mr2=9hd7~DT**~xq!ZP_fYI?HFz!t(P zDz1ZU-h4EtoZ-iKB}y#{9Su;8puo@oLa4AEK_o&1h{fe1WKZ~^j2V8?Zby9?H02tw#f6wL`{MQ}k9v_B}fpJ)cK z(BoB0#n`)Prr38XDx{0s48FD|J5X*|9t%rU6*pU=Uf)K(R5mZQpPeOgs9f1w61^&7b1mOnB%uemHpDX zC0{*IeZP-v-i#HtF6C@*V5hnbP*xqHluZ`q+Cgji5uJDy4!_&Cn!@V6GNX>-b1Ew=1{DO=%l z1xsoM@F?`b7yx2n!6_O#X7hn_OmXOJ6Y^D0gLhLkfOTZXf(P_&))rZXul zrG>f$hz02o9V_?pD&|6S`v;3r(VRhEKQ^SCZE+}w--9J=84HTy6J+1zo$1Lv=E{co zs)L0M6U*v=Q+`z^sLajpYWs26{$9%?LVL(&12BFn@zJ=9ZbCUr)#%N3fspbzaOG)m z_f+VWF{f}q&=$3pz*cD`I0c0rX;x`Js$`Jc=?CZMxru|U%c5g$Ul($Q zcf7^Hi;k3{ET&Ci2wK8dJ+h2F@hJqc0G8sYvHgY&^7G9=H_a($kuU-Kb8Okcz~jJi zKjV|^)hG4s9;JmXi9{l(%VtC$0dPtj0H;8p)$FtS9ub=MDv{0Wk_GB1XBd&XEcyx| z=P|REC#4UA^SF>hb8ub)9f&x5yy4t{XKa4R}z|MoJEVOj(9lJhPBJN*B_Gsf7a{Rp{Cu!~Pi< z4a*Gj(`=XKIX_&w^O}=`Hlduc-?*AeIdEP78AQa3M3|ySTrwair(@*Jf5jfLPwJ*z zW-eq;j{S&!1^cOM|7V!B%pji%?K}=4o1>L(qzx!%5n-U6spr5&I)YN22EFzog)mfB zT0apehz6&`k~NtB(RF}HMDMG6^}exB>B9VM3-etDIcZ^IZySW9X*SlOoZ+&V!<5T7 zaIFwZ(4z0gsf{?x?ZAdHBF%M^Sf@ChJEd7+H<`bSH~GFQ5gG*qK`o;J(P>jGEyktD z=5Y@zwB{u$k5iF^n8*8+#rvF|Y&q>3nJ^H}0kVV+|TV7%FAPB}ZGI2X_R8e3-D znafh{IySMdP=ee57*x-&KpKPum7?;~@Bg}MTvQMX!(0I63HBp7=1G3x*|$i6<1n*1 z)qFtUVet~M{%B4)i?&>B*}V9J16Ovs`+~lU4~Hh=b{7S@4ir(%*c<#&fIvF$hx z)Lc&Hv#w{~)QBJbHcNz8aPHUv7;iS3Q_cX05wi72*D46AuEu*f-4IMF9)Hb{52FtR zQipaNhEilMo=rf4pcc9ZcJwMv@851Y_Ib8>g0moX802x@hM>v6H`8o$${FedN7~01 z-Dr$<#-Nn{0y6`GzUmkI3pmggkwC@DxE+)$P?+CE6443y584;|pMLi@IGBhGP{1z{ z+vN=MkI;KpjLj)$aPyxh#Dt!+5#KH-{<@!xD(gyLk$Spr8bn6X04P&4_O==V;bH+` zKZl@8jE3V-8~2QtxD4_$Fvy#Y%_(P5+E&=Ie>heklw#QIWKmZn4g3wCgoz8Ee#6<> zT93mCNl%G_4Dz(dTdH*RWgjAFg5JB~*qn0qoQKJ+h!oTsbosivV(FC+Jt#$(u_w^N z*Er%DLGyhH>Ga4ufvAKCJuwXOJ^;om;MX>%oFNlUZlznaTa?q~{h}x|FQHeye%J&` zLB*IME0|pe&w&7o;XuSDBRX}dXja9?3=j$Y>t>`U8Pe7e}@5-l>w|C=CcsQ%+`jwBXbBv+lH zr0JE1%^kuSHwx)76_lr~CT5ukoqze=&zC&}?)<+Eq81x$8A*HWl8ym6E3r;Oe5aMT zj?wqc=f;A$>D8MDgZvOAn$q4IqZC}T?rdPo3VM;pX>a*xkt#K^zIzHJIGp?cwL+Vf zdUS5$uA>6=@|VrPXsM-sHM>$-P`Sds_JIA(>fOVp=erWk2-njp@VmZG=O(HIqczef zW^CU@(tZCWFlRMA0lQ63Hb$qQ%hwF8QzNhR9@33-%&)f!ey3=H%_uH?c7`STp9;9x ztwjJC%*}&_L=(c_4m-L&5$^CrP&I43>NCxVkD2E;iROo0pah$=5SAwR^7pl~fz%i! z0$faLIfy-O#Lh1?{-lAT2E@H0^Ju%6y#COkYF2w?j#)S>hfM-Vp)rwT^|p2QG`I&TP;DV-%e04Mq)!yG+ALqRDEC##$ieJ(V4DroSzmdB=;J zR2LV42)Yp%&F4j6c7;O-ov+Rr;L3`w&{SHVaL7LVNaLgwDLTe{$(yEVOypQoSsMcv z!B&EzAwjnj9+(ZdLFH)~fU9e``L07Qol5h?dR{Ah13Pt}=i9sq0S=GX$uTTniG?W6 zz?&}sM)L%vzHl5cJIIa8{CWaXYI8w}*OlWIg=VhVcN)*bUg0^T+8jgl!*pp&knp0~ zmH^Sd4{m(4O&+_J4>*ZcbX!d>$~1GE652}OeD26bi{G6MJx zL<$Ki(cC=8V$*I^-vI!Z-A=`q>@yc!7KT)1vzQDR!1x2^g-do*#f>SHY}oaFRLv}u zL*~WekbB5snhw}^I`M%b8r*hjHJb-6)6b|x^rTPdM=x>=2E?sJD{?C zIGytWI}O2Q5_YqzBJITsA)16ZH^hGo*wf@9D0X385ZR}vdYL&3bI3@9Fii?D!R&Hg zh&(|x5ce@@UxGP?ao4{C62E;2gUeDPvizc7vr=J3328{xFH#}0{`%3-5=~0{nJwia zLZ|$YNfTCy=xTn**(2FC5}}MH6$|A;9tDy796PShv2fdsT8_Z?fIC5O*%Kl0A?Q$X zcNoN^!9nuh6J4)>W$}w!L_7-QB0{J1kOihThd>fppp~U+1``v48kS&YMe6zyF+J5e z27-u~#&#=O0+g(B0FC}+6i5w23DdyEWXV3Ok8k5!*v%uur5jaoC`~RtwxLs2hoY9b zWuz#oT@N%0u7s+I0V1DL^pVjY6Y#-yb~j^}G7%IxRw?M6#%=eG7L)*7%r(mHCi562 zk@^`LzFDP=+l2SeAE7pNuDNm^r6m&*TvX`Eq8DB@N==2F&(?HhB979V` z-*!V#*Bh~|gLHc8f#ax!Z{u^s{YV`Xr#CDVGzxPlwJtZ0Z0gnv3WdZY;1=uYjOs~` zy{fgtTM~rGb$yQE21DD8{>^*q@iq-_WZi&-vL&b7EoI-OM0>0eU76m1xpYaBT)g4b z^#rXrhyqkig&I}8p-WV4 z_n6}Wyw0QvnK3GS;Nn#WU^LJ7MMjmNg8@Pe2#V0jg@2NH(NIUH6Q2eH^OU3l^aQ7< zqats4UE_*FO<=Az>XaL8JJ_Mn} zMYYkwRweO;&UmLR8QFVfS`?MEucn+~oqNc+hx_wsMsP|!X;f-DkYkRb*)iW>rtMa3 z!Rfpu_?P;e4};78*O>vMb$y1E%m#ns(%>%30vaqwow?cP^*NuIL%wwAcO`T{(2Q`( zqG-56+;MX(Na~U3Bn-gXCr&Ugao%jm)Y7k%HsxdBB) zi662(h*3^*xv>8)99r#=x&8u`fUN=ePKai7 z?gcYwXTco9S)nC3Ovq^oge^R(rP+nRW#<}Ph7fmV$C&J@pEyJ-Oosf-lEv#=nNNsq zKWo6&0EelJW(0wdW1;v#jwNnOaG=eqxkl2P&ypH28oUpK(MFE%S9@B1PyKTg2nb^> zWA;7V))j<39CCTqU<*If=sS0IFpFW@3kfiKOOeym=}3%TtOrIr4}i(C1G$~xGdRGx7sJF%$keDz;|kCMrh|?`XCTLi6CWFmUXLJ0#esqH5hGXH7W%z z0>vckJ9eJR=#0Z9QmS~hgr4O+qQk8|WT}S1tdVmgYS+<>{F`zYU_FF{lVgeB5}$lzLu^_3dCN!cFaG5Y5j);yXhKHtC`}a2D-}i6d}+DH;;S@STG!<}!eI%n!L=mI%Mxb2xi1 zYiLFnU2IpzFL+Hwj`?kh*Am!>NScAs3fPW*=_aFgig@^f(%t|_6E@BAYv*|~1V!xN za|Qr1xU#f0QPU)Xf5-#y6C2Wu6dl5DSNM`OIp%k`5ELnfi15H@6GJFj0+$UO2!y$r zURl;$&&S5?kz<@*E;>qOxfET}~9l z2@V?5j36jDVLI_)+Gky&o`+k41C(dKXsMWsl|~xH2XGm<3t&jeCQ}ukNO_;Ih59fl ziG~XD=C)qwB*J{*9fS|RYNVCu+0?CcJaBjM+Ku`9_(u{hb8HHhg+hW=B zB_Y3`V=TMZ5`^3CVHjN24uH#M9=J@L*S^!3C#MStqn~9rkx%@1U-zvAqM?DH+iIaX z++iR&q*#i23fKyu*% zaBozs)Yz22_vv@TzX~Edo{3M%Ry?1Kn6m{JN2Rx0Kz{G6F#1(30V2W$m+b>w*7v|= zKJ$WE0=wpaGAm4W8K4OeQb4sC=i6yqJ5izO;u zIq@88Hm2~+gj?Bnk>Z2p9s;|LG{90P0uH$ZCm0>QW}4B*=Up7Kmgr}QIdIzcVH!E6 z0w{ap0fuByc}u`4Rt`q%niBt87hHCeop|WG`(3?}NK?+l88ck_k(lOWRDX;^t(BFM)6E`=Xy>(gcl!ho16DIMKqXt1z*YlmhA&M zIMw9nL9Fk+ceeQ<5C49*4^$KDh|6g$3T=7(|+4s7>b~U7dv?ERtXsG6Gr-o zO53UONs;3^p{R=#x9>|A&e$SLnWJUrxn?~dbE_7`PH{_)!@gjl!lvBU+UZ0%8zcbx zc$Hn4Aexn@v&M#VKv2P*nfQqaIR?{i+fC1Y6=(_0C@Kfr?tk)J$Yl)L0v8G>xRVg( zCPbN|6HlY|t4|o=a`?ADu%d_tMZn(Ksur~Of-~W7V7@pbfPFmlnjEu`!W4Q(f4+`z z_6r2Z&o`1~cJ|;SYx+2IQ{J`&Z5LjAb`SSmkhoI_XltA@nk#k4Xs0t;rn2OmU+Mj3 zG=%6A#j_eu#n@u~zs|7JaMlR$N#O*IL%<0Nkn-4Lf|w1wdMJLQ4BZ?D3WSZH^i|6w zB+Wo?by@-dJKdJR>#;)qd^35?ZJO&UEzjj=0CH9fus0h0KkSHlUQf;|QAZU3w zLF^jnHHQ>N6cK1fb@2nsLMn8=OsetYa+YWbg7;m>pZyoCXRS;c7QwD_EHvRD7;K;7 z$&l(FK&q`63j{3(&`3d25~J7j22w->XhtP;uJ4$KIGMPXVH)VxS9IR>+HSAM^8FFe zR*_O8kpwf>2xk(T*byoq3q!F~Le&3imvqu_94+Gnr>znu2)%qwUO4|4PRRUu4=^bi zL}J<}PRGLQl#+#(K=)Yxubul>ZRCpLIDRj3lkOfXMuW12GqAyICnk{9rdh)njJq+6 zA3%@?NVbquP8P##7hwoi>BW`UV%gU1R{K=Z{UiM{b4Qvfq>B#Z`vB(Nqcf7Q;3JyC z*WHpz8cn}+qxec1x2kbi{_@vkz8vY_7Cxo5b-X1~c0`5tdh4){YBoXi1rpWfR6*wg zCbjWT561Tc<8_*W7x7tVmyvD@MXH;17AaZu-zTKH43y0B|K1 zm>{IqQW%Wb^9?%JC@PZH>ki%xmh15R#xAa+2rgrr-bY0Z18UO~|L7>+%jGf*wDGSz zSxmL+bP-`hok%PCvRyNR*r`bM=(*FU>a+b+)hCbcG8%Ss8F9N#NnErQ=+T}`WiT{^ zHoZAn0DMVA4*&kW1yw2WOtXcHKn3JvQNwQo46fKN0$%J}yF_Y(R*>Hq#%{uG zqP}Bs^IHy&Z&yjuU$OdItleR=y7o^jc!kaIEu&o~OC_lXYqy&S1qF^lZM4;nSA$^f zZas%g;G4lzVo)n>74F>&rjQ48R~^ANt`634^BrQ;AVhOH9VGh(KFG$_rHb z)_Oas28>F08sND2MEV|ZEIb%wzrnQ9T7gw|Qg|9L%NPXh%sLkKBG;>D4M;$kS9L{h zx}lnLz*J%ow6h`jxHMhCAc3DXBKz~eC(uQfLihjlf`P%JJz7$jTDO=IG`J-lA6I$c!VVPb+K86Da3{IMIrs!V&J5L( zL7`Uz0M?I|-6V4msEk|!A7^PRJ5+m+)>gw4oG&^v{`2%x+$ z!BoOI2+Sp)PUs}B+gurGC@<`4P?Hgs;T&v|G2tShcQlk2hr0?mE~=PH`W$gAxC9)^ zw~REqFbQy#c2j8rorFd3_!?l4fZG96>CQKmn2Z#w;lm&|4hD$>ejmOvSb=9M0eoQ) z)U2#7wZXyKZ(x8HAM+MdiODnna~%e;{01DXeU|7-6Z8kqR04p1pkXg89~b*l+fM*c z_t|(3$!C!|Q|Sx?jRC$K`Z&jH`tIt9%!*c_JR=Y8|0YDES${?FE&4h6rV;?e1Fkop zt?9e(wceLSO|V#yf1xQcB8?67lcYhhgTs2*N!24ttY7A&HV+mv?fE9~i;~w{O{Iz8 z5cT0$Kx*?GtN?H4nnv2nX)qY5-HiA5r7dc4u=bUuOuLv$JU-|lwFMq1qDoN<0d$xF zSb`7L>|g~LXri%#?WR)pl6d^)=>)P3Qrn4fumU{t57tyNz+ABjt~}rX2Wi=Aqtuqk zoW%YwGM*W%K%;AAABtV>!IcLc=(~Zj91|E*SRLCQRK9v288HUpiHre&hlEE$!alNYRk z_00^&MbUBWjsXIQ&p>}Mven|P5gh)qn_<1kumio-9@HE2R7m^U<}t(?24OYqO^nV( z&K(4_5+qntrxx#$1YPb^DmWEQfkP?By1iNiUk$mkrg{$V`mb1)rhJwZGTMp?BN8+O zW)v!CR8{aUIRtXaCP;1f6<7?IQJ9E~Z}v_f;~u&SkV^)EA%mLbJ9)v91LK?F7*HrP_uj|FI>%dm!zx3<6FTix-GSuHT^7*AS>5|3BFm?r~+QVD=GweYSs}2ya`Ap miDNKMIo9qF@{hs4|N9rlqnP8EN6Je80000N&i^l3IBZJ!{-wB|83&G@8=Ysuwmjj`eGx6ohuG6 zr)~bh9#bGX$1)xElqKseds!Bjbd>9KRegt7Ht8cmCq86+*Mnrwv*2uxZs^4|aTrUR z^yrvg+%ND0}I+eTw)YvO-GlZ_$MX8S~=Rph>{bPA)<@L$pSm08-{HMZ#NstA)? zswgGN$GYYu{k9Ep3*p$#bc~?5>h1>Z+|dqtNMp0qZ_V5goC_gVB?)>&cR`BF*yRo6(f~~Tb|G#R*{V+Xl;}IQD{V`=&L3sonkJ&d z<%+WnO?yX2fJhxkvu(I)!vy=1wCEUTp?NNEE`#^szUS&7bI5=w0gcuW<|1 z$cwbfZqsp|Ri-6Yox0>%jiN^(NSSkMQ2yMV%okYw)#FVb$%F3y#G(u~Cg!2A5Y zAZOZiaITigcBj)S+Jp^QycX)`Srp`gy){VvOn;Y)DsmD${#SaxBI5FQ6as|s8kMucS)44BD<#jDwz_K86K2ILg~xYU{?@V~KI zO||F<0AfObH&eC1G;ApJ4(^@=Uoxrw)Au5DF;$*_`bn>pniV6ZGj{KXv~5SZGK zXx^mAn>m$C@MO!sdn@fW`g^5e|(7mZLj+4gxAi}|Z{$rCI8e9`zHe!?$r4YHaCZ+oZF zw!?19KTQd>p5SZ$?%F^do_OMkC!ToXiSzgeJq$yP)!4-o00000NkvXXu0mjf_<{cj 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 zcmV+v3hVWWP)*$hx9Oqoww5il7w+*^*C`(BgI1u|M3Z$ z=!X9=0Se(4E&m*vZZcWxIJzNv=II=o>1n+!h~w$acqy0FgeFkaJ~{l*h>sTPWHw#v z``RY}n7&<6TUF^q-^bBcp2ITX+Vu$MNNcTA^|S6llkj*xN@m`kPG36|(I>adWQ{t? zW*K#F__CySwdYWc5KXj>s@Xdf#(M7U{N&35X{jxTn%;!!b2!&~RE{bvqhA($nf2Nb zGkOxf|Dlr-75GO%&+ne*sJqwoLq%UhbqGC5QdV*-9DTvdTvTd1G6+QP!gDOV{;9C$ zAo^g0b!4T@p~5K%3oSh}I<3}rPL&J-QBLmV$fC<9KHz26Ya8M7rv(cWElKYA>ZjVE zPGg^0DQpXa5@CJie|gVmVqr|d$N}q6D2y=D+*Y;e0EM3xr7$>we;O%k5a&`@(f_OB z$Py0xBA-#|E7x}dY+GR(VG_PL2n|GoD%o#=OKtry*@-`az_)tN&TVw!JA57M0?q?J z^Dv+3?RuRDZU6zqS6tiNCec~Z)w5zbI}t9QB1 zGwqQuej)%)o7?m#i)~?c;v*gVhRsnpvueA(?^gx^+Mv|4?-$qMAn4^;#xN%JKd-fm zl{S-!4>E{vNFz#Zxmi%qsu0eJO|9ClpZ-UQu!U030Txy)oPz^U3g`QmBU7Q$a=lzo8M zP2IG-tueC7aje>zn-VI6fUQAYzd$8I?!ryhdUlz?*=Zbk`}K~5chvrPf`i!Z@jkAz zv&Yle&0R`5^v7(;hp*R`LBKvK&lye(ZIrr`l7f4 zK_^<7?@Lfj?76nd+Jm4uFe=G1E>tP3|I5?ap(M=$QMye4tV00`3*IYl#~n#H&$Ug~ z9)w$>P(vMtw+QbTL19N#R|uw|n4NNVoR)a5JvCW-5MB$)VRT7Y)wV67fd@iasDM&i zvN8x~--hy>SdgcqDhZR^8I4^XmD=^J2YTIzG6QCE4#Ra?89E)c)UId2;kts>KcE~2 z96ETN1|x#mmfF8K6V?^9b?1hLT|-JY)^>hfTF~L)sQ(W-9#U8Ag8m_fL0d=TcDrEN z7nL>jMY|y|Q~m7%LHn-!a-^_1%WN-HU_hY#NGsK7CUCYlDt1ESk>0f%Go0;@ir4UA zfCIvraM6E1tB(skH!m*R0X+XcN*fD%qx=w$*8d^k6DK_66n3_SEw|C%0? zO@YZ&HCR!`E`ZLctj}C~+CZ~SF*O^1J)Z4?San5ZeZIx(TAVl1Y*Wa_UmX)~?Xm!O zLuGwF;Z;*;$NU92Bx6%ZS5=qeyk-|1N5#juBVpT4Fn`5SGG?2?bX6ad*aaed6cr!i zE)-$16Rvn6So0igH=#bJ3#wg9x1zE>|28KZL+k{IBToOQxe4_#r8VKBsI1Swfkg*^ zo2)XfpSTG^gR;kzet(+h*_Q1licPVBsx>YO;Bt^*keKzv)Oj1H@?0G0zzL&jqleLb@oi1GU z78bXmU)&w&2ju8x_7Wv8S1|OzeLFrO-Fw_bR!lDk=!W9G^cRk9n0~1SxOFo%K=)>? zzw-|BFT^jGJ#^(+!-|A^k@BT1j{ZHLCgI1lJ1@@~mgMSz8YFxlhbsAf=IIE!lJcx! zrcT0-I#mO7vGH)4pr3#pbmZk(!)T#!>DSov0O9*rp?e6I+(Jjxe%6r8yk0$z9Bty; ztNDQ!+4X&AVR_c@`RSd1*h#_p-T* z6LDOZPt2<|_uN^SOq=5OV_u-E4;xxTo;8pKQhWB$P5$#Hm>!-&FXz47HxC=S2?u`2 zLo&kV*+a*;2m<(inCDyC%W+FJ4;xxTo;9%dVtSTm4_#t0=O2i@E$!tjjLNE;aE9pj zC+XQdd*~G71z^x#zUTFrg#C85`mCYaGfIy-3a`uxv;D-vv|qRDR-ZMbR?itfd*~_* zMmYI|dwDv63?7fN_Ok}NXLba-hBCsuK=W=5?LhTe1C%{yz6%>bwnvzs`L8os%a4RS zYk2Niyo5f&UvYE4ex1s0-6cY>dKN>Vm$1fo14?%5E;0LH^$gNB??Bpy$3#ixshx-FiUJeVZ050$7;jhx9z8X@+n#ieWXh qXKs2x7(p1^GdKOmhBz*N`uHD_t?dpKsbp&a0000gP)0000gP)t-s0000G z5D+FNCUaOKB1>~XKtNw#U(B36|HMrH$XPaYvm>I&MU~}Y+VZ7$Ul9NR00DGTPE!Ct z=GbNc0AzGYL_t(|UhI}JZrm^sMMYZ&;0FTGaJMSmx`^w5)k3*L)TlO%095NrI*E#f z&XHoFLuE%Km#RpP0H+EoH4pRo=g&~pzdHX9z(xccI8p?Vd;|DMD8uKh<+4!VAwp3R zrm!1h_z)KnpfU%%6Lvc+8^A>ffPE)`#aLwxAF^QfG+u@s240)kh@h@kWq^o`1q3A1 zI0L{Oz6=XAlAluZMMVJkp%#weE0b&lEFi2Y95N0}B2z>+odXazNBNkF3OMez;*B zcIFP)zlj*ejB)Ly4>>h}he~G^$}NSm+9xRkKekvYk7Ujv`4q(wlfZ);J}FiKwL?3>V<{^VsG5rU`i)xefJU5TG%epNCU0&QV1%s8=@>uC-BM8rov&ObBLAg>RAH zin++Gi+ApMS^wOfn=%dc475IB7!wm?kf`#BzXD zPkPo!RWPaP)V;oQ8_>)uVQmk%XoH&N0yJ|$;;;Y)yx@1M8L5FhG8{FU;Xti`rh9x% zp#}FGwZW9@f4R>S5m`@VMn*+SIWjlgXbkWW5#M}%MOM`(8ofVj<$lM?q1I1bn_;zM z!A6eMNNym|4ep4E0Bm3n3O!l-5(}JUAdVyFgIym|e8cYl0+aBbVbLYwv~mf~a{IQl z=!-I&LDkUrv~u$<_i1#~Ld5A51#r8Z`Do`|3mhIRi)hX6#mRMq@11x9O+8C0S7pX?OGu#=iMQ@eRnd^F~MRx);Hx;F`96#EZtL~VXHW`+SBd&Rr?e92pa3D3{ zS(0blU+i=8b<2&DNaZ^F`%t1OW948NvKy2zW95dOCn!Ssn4tAh9D!>d_R=(pgnfoX z5}Id$B=I}@Aj)aL%C&uJ=-sB>0l)Va5qmsC=)-tvLtziiN|?_QbmPJ9Z&T_|@$-baR8yzC-jd(hf(gylG^TE zVt6Uc5>D0OE{gZk{|qY@3KzH4!W@pu^Y~9txE9;EcQf3^O5{H&AzW=8vm6J-OMh2B z+VD~_A^pMWrhlH+S}xB%L9nhQkn;V*J`G&emQ>EYnIOPJ=u6xTdBJuPi89J@qDMDq zm2kQBLh(27am{fD7cw zaDnzmOEs_S@6(`7Ih3R2@$m5>ZKF{^1|4%cR14F}g~{Pj__?>a;CWsg?--NeV?^Ot zxjq?fPbqiX^DO09d1`<$F4GmXt;+FSnNswMAMNL!cgOQqR^meGmHQmaCyP$1+%!=Q z1MaK%!A{Nek}?VApR~o8vS|DV3#U}j$|Yga3z|_Bg*Q;QolxXM{5%<&j=G%$KWgJ< z=1}gB<6~ zU6s43=J~k5r&FP~vU7V%x$~@Yw8Uen+~N4NHy)vMaTGybxFMxRV>8DjcRPwUQEj;y zdm5qc=O3^-?olPue(HHeu7keKbMa)uqju7}2!1qr6NNibD2hBaVQ)BJQ!#NEwJDH3 zM%{|nx6TiiIx{YmbEq{shsV4blsg!IiE5MF#c3|} z15Q@~1>J3w%~YEv8=vPV8>Y&QdgC!p*D4UM5wPH#f;f<(5Q;n0Ny4HB3paRqs5KN9 zU>+m_DR+wNdJ}OoV}v+MH=HP^_97Q%KdKya4M&^ca5?hOPm5efC1M`h*|l<~Bwc}7 zgEJ#5Hyub(B&_S>2dkHtEMpic;oQna?O;4Q8{>$;+)U1Z!bvID8xPc8!r7haF{dl( zr;pH2Tf7^ip*M0dCE_DJ+n0uNl!lMlO<6e(B$(BqN{j#ZW@dRRh}_CO3^vAtvvJTH zM=h|vvdE>MfQ*!*isBl{j*y9PBj(&I#O!l;HXe*GdgC|YiP35u=Odg(!hvKHF3COE z>E-1Cot6C6mQxFb1sFONT{faCLFetieHeHkF za<}C3#HHcNTEb{9a_x`qo7hjuq`Y#sF2-uM(NeTD5E{oxvAO6=+=O}K-;i#wxBy>KZPQn(~}+C98P=05h+CQE3tBN&VZINin4SMk!|xhEXT z4bf&gkOrbeQ8@}{FRvbu6bblk4DVxFR~wa+1_M-XW3X^%T52*-Ax@h~cr$1-BDG1m zfpB*+T#DFF3!bZ7n@q=3leLeQaJm8h8+;iz2VTU=>6R>e`Wof~X&_341cwn>7-Oy0 z^xKQRe?LivL#dq9dNiVC-8y}+oG(PpHAv7=@1vu((-0^3(R=x-ta8bb#ZS%2$jjH- zlp)l!jh3W0;1aiXmL9~EzFE1OfF6nwj{2Q*@`mX^$|`5+V=~L**yABkIU4(k8d3Wp zsj#&%7)0@{Z&r3f!xicf1n=D+CIDz~oKUnjRsN;DC_l9;$9}M6^HUx$nQReot|9qc zn5fYE#{tcD_Dvj#soV%a*#{$Bzn@~|IFO!ucZ$DJ!-G;cFOQYWN}-fnm%<%|tw+@S z#SdwY!Ai`^@n}fp4t&3j5iS?jRBDr-Zl6BzLXmGSaxFI*g=#aVpJvlTGic&upe9pk zE~KLT$9QA#70R#@A93M(A*f-viGIovPDbIubRc=lq5HvxXBq&HeSDGkU$t`4 zJrZH-;l@_H9mHBWqbB>iu;{NoO|;QHsdj*~#7pCq)C>5SCrc!>sl{OB*iSit%+V0_ zML#oH)b6Pz4&u1^JU$MKVjgWs?o_#DQf_Bwl!PDRkeiJxw5pAJ0F z{tKOsnv9i`4|nGjU2briUt)btP{ZI;*@GnY)89@7k{4%`7sH6IjQTxTGPLOfPUK6HjoV@)|$`n2Y`RM zf+zQQc_72c@Hij;_jr|+Yi`BSZ+`t~0NYFQ#TFDO_qg-8vr9&8W%O_>e)OwIO6!Nx=9_qH=g|m4xGR+t#qs?a z`DrS54{d()>oF<^>;%~eYBwqOB#YGkB(kb3tIcdkKji>2ACv#s-+i1;c7)2cc6PRY zgG+=~beEQRP#EF~(uNS;c zTvf4hf2GtWxmB>DjZ_<8sn`hsBZzX(fj^0$hg*-vzxvmm(J8vzY5eoAt;*43@>eI5 zMId@_c5u3rRun~DR?diUGD?&U2a>Ts5ER{T5Rh^Qi%<3P4!5>2jCRs6IzJK?<@l$C z8<<1Jub0N7cX~8Ok#h4|?cG#4^d5Xf;4Meqzo*K%BIw~8wHeB%OX zZZ0|-pZ>X6xyKz9;d@#+9Z0RsXj4x1Z^lnp7uP!IJ^pGM;Px8AvNUT-uSpNJkdKg#IetlpC@jXp_ugN}2uupB)+=SpOC@Li@A zG&V*koTzzYn{pje+h3&|L<2wtQY*Um{I0ezOy2EiH_a?>88gEFRixZJHA*A`e;f7U zV%&qdv(d6;4)h$19dd$+o4)P^7b7tjM}q-x#h!cCrEKhvh{>ExF(CelEf^UlUSn{xiH-$ASF@)n}VTkaMpH!qzh^Hs(*l1^Z- z4!XbJKTisj+gIZ$&)yvOf{}P<{QRSVj&PfD7(v?SdOea(cxP!=5EkL+(PqC)-NPmJ zaQ3-Ru_^iec``#eI1n62_}}rU$1<2bhOep~FK;f|96#?Cne3;+@#r;4x%l4b$2j+Y zEtmsXICi?;>ly~@bFaq{UX**%2m%=QE=FVYhBqT}Q@t{CyzTRB*@s)JeQ!Me_ur#F z!lqmwGJ#a9eP?IcsvJGk)k)QRO`k%b1$yZPdud(;$V~nE7Am)lTJP)pXW|$3;c3R^ z2k3N|8b2PB5Bv+yV%A7s)<}R_9b|-KK3z8Qsr@nW!yQqj_~X5ThHbu+S7lR!ej`bnNKf;FM;!D<>mJ zPe@KD=FY}ncJ0ARPRGLW!|kbPjW&NQl`|uJm6JCIQf&@jBa=lzG4?0%-AoQd8b&xr zyvbhb8g&o6m7Pset}FmzZUGiN9IqGI$fDdXOd`Dby4Ltq?nSzs9W7xvVng(Bg8#JX zDS>h$P2M6GNVVGg-i7oBQ@F>t>vNAd-r0<|Lll8=8;-FO z$I(h0dP4RO79;9^IMvq$DK{6X!&FVBlxh04__ z!oi^TU}$(=v2yi&Go6Zts8LOM$X;4PyBn=YpmMaI(k3W&O)3YrgL|%wdupuO0^9{D zh*ox5J}%N7;VgCZAn`JE6r* zUBa!z(G3W{%P!}3(VeYW<{(k5wJEmYrOvT20Ng7(Pbm`=8Ke4dc}py~$Md%7=n_)5uX+Mz zOpO*NaO*BEX+Tof;gV2AATO;pj9Dv>4PbY@f^sLd{))!f~Mf|5>^IWwVd4!&IJ0tPYECDdhkNfNw_~S69vxGpv7codFIu=za>R zU`AKHUwRsmN9NZrN5L1YoRia9LH8l5CsN=Pw&UATrkwYURe{Eaa&$EV5+;D<499@-kRB=YI^C1=~k}697mi_nwC>; zuBvjJn(Nnr>zyjNq-lDD+hm*jvKo z?i6XoTG-aegxiG!Y3f#Por($y=-G;j`z|Ous=v|A(IQRdfLabG9a+b!J9l_1!i-gN zKqqFBIjtnKTe(2;vYSCy-^kH7lykBA8P)H`7bZF7=HG?=Jr!1V+-Q=5ugkFGae{*I ztnZ0(oYr$9V1lFea{)^j4(uo@#(4`E)jtDY_$n3Q?~-Ttzwmij{BJy)o&-x2HgPXc}YU~ z{%4(i98dQ3K$n9Ou=VqZfxXU#7QqN{)&)2wED4o)+1tzk<&-1}wx+YNJW@oPdJeYjaKktc>)aSf% zMESJ190&L_z;lr+z`2isT~Exsf}ydFaloiHQVmcxNa$Ciphh{^Is3`;q}j70jwP^Rh+mejs}vBX6&;yIdp40ms&M;VsxcAjqBPc?$&L+YvV5 z@)g;4l~vviS7S<7u6rA}ZDQrNzmSso9i5Fa4?9c$Fv?W&w@GblAJatxb~%%qrG#VU zK%&}`VEvF-Z885c*iA?F(OnrP6MIv}Dcyxv^#wY@70A*q8pL7U}>jt%&7Y}IR*kA2!Q(FA@ zKbx*zgxM1=AaydF?osDugcrJ8H|4;qYFy-U-7Kg>>TsMYcRH33tOy(^X5y#eZqEJ3 zPxjur(Y};&z-<}%t8fx-@yQ|pb59BOR93G2zC95K$Au@#cWc^V_rM+#LtTx-BA5G* zvB}vyPn8=4c2*k~d=d^DXrF$(Vga?fz~o7&g##D7_>iVsRkFR^hjxe-bHMCS3*MDa zl-L7)Fz@4HpD5kHo`%UFy@P>W&W_DWQEkb?@kluxICe8UPr1@hTy$hkJ*-^v3{W|r zg|kS&#s7)gGql=C)5T>|RT4b_86fE?*Xi3cO zND@YdE9@*Q=kx=8KK_tgVCGc<8N#hB{z(uJr}YkjO+nb~@=X)wHr5ShRer9w0ok#v6_bdzbWG)(BoGLziKX6Ck4@SJjAbolG^7WQ{y6n}!^Dx7c> zmSeR0IJ9KsvkT5NJXEbcFRct`vv;b&io|LwY64#+$*_hiXQbS4Tn)!s(F5?&y=zT!-5xwrQXO;YY(;Z%7x?J6szqdZ%62F-pe%4GYFL* zFhtgNivVAC@uWCYbK{hqj5)269U4Z$aTy1eegd@X5T%gtJmyqbaIzfVMR$cXtoXt< zjHXy^1Cj4#rX^3Nd7c_8%_L?A(mkf;U=M_q{!N5ivu$GK#M`8hPI}bdM^Wf1DtwEH zx@Cn!g4wQt!X*KNrlfKRFdPgftTykC3lON4vtp%lsP+KG^VPAb4{OQiDuP&V*IX~g z7m^{?yI@YMtq0Wg7?IQ=Dc9rN=v3}yN8WM}2_qyx6H4*VBoKxQ?}oCC&NKzXR{JdnTvcd&J;%9dm=W%2n_2xCgpUS} zF=z8w0mlgah|)-)fHyKQhZV);`C#&48soDoNP++{DhN8r7GFa&oVJWNzm|S%i+|QQcbB3z0ju?1soI12{+|`;!^dzun3ahHoIvMldK;E;we7n=oMy(%eW@1!gre-Rb)wM)FFD;`gHSvVhP4GlsjlMikW%62h&(-QQ!v#n4I|jqY0S2plvc?gpA-ty9*48 zkZV6jDjHb0$|JO*+~_P|>HQF+Q)cxS)8v@58MWG*L|!AjnF8Y_8RY<)L`Mb~k_K8h zr5t0WMZx_lym_sm9Zb&3sfH6sKW>|r6oPj^=*J+B?d@_rn95O1kaCU!#v!2(d4{KSv>^0R+SS=F#Bf2D)5Mx$gskU2iHBbNX6vi>pAX%*aTgYjp zPRo7n7#>i!NiHXIqwAjBS2`qAG8xg`KE)&_-zVsyRt_5DttgI05Jl0$B799#5Filc zNT5C0O)`y@4pySjeapd+De%Sg@7e@L_+Kbw6~<8`c>jn@+^-mT>^OG}`m47N}? z*WJ29vQZ&%fdWPVP^=u0oFvGpoe**i-E(XF8u^9Z-6F6~ooL6Bp6=gIQOw~{4l5lx zcH;n(^HZt=!U+2~m%=z|<=!9@_kFBjfusq$f!VY?eJ-M^BJ8Dqc$^Q33(KqVlwbJE z^#g!9NL(ZhvHX!8IRM}${7S}1CKly1zfh#JOUhks?w(z_x~RYBqi{ZR zrKhmcU&TK^a&^xHg-`kZgJLi_C*s}RMLG?o%EdcB`5}U2nI`O*i$YxHMi~-uGw?iN z+~!iy+z)KYgqc4~YNK&MeU?zLHam=vbeke_hm4h$Js?;=@L(|c*a0SI@?(cFj!D$p zLMCoB0;UO@$_-_|$#Z=^mdo3qMrQmx|9KhpOr~;aNEG+>l7W>4ax^d}1_X0j84;|_ z3L})tF;|+g(t(uQ4JLo6dQ<5K8-wSnp|zGU92o@fNh@q^{%1ousg#DaYt*;|WM)HD&vjJb?mY z9G@GFdMzN7H+Aaj>JMluR{!Cft>{<3QPk(b`+T6ZS1>fztbWTS40TgDVn51gU5@VV z&s1)Am6g+2>4oLZfElH%+`&zGV$0mwpds)m9CFiRi*g-*LVX6D3jh>?7kj5MgJcc7 z{egOSmR7KUT2w+GAL*>?zMEk)OgUPMj^hKY*-wG$(z~nVS@M8Unq;mX_7;g{l zCMm~6YJ5{IoBI%2r{{)pg#}E9giI#kMrqVZUGbclHf7<|@4*4o$v|VJ>3v(z$UPvM z=_yLz%0e!8_{aDszxwqQ-`_^rq|xuEXoxx?c*mmVA%pjBAx*fxMrV)3-TvYP``kmW zGA=K|5y%JYYM!wgKhhyVXFR-S<<2F@cq`i ziFx&FldT#v9=4m0RwMj_##ZG@XISU-B=3)Q<1NH-BKo(oa?9lf= zMZ&E;o8Sr=Ip4cQs}qQ@W_Yoo9KCX+GNv1u-WK-TvdxN{cql5Z9DUe>V7ys9$pmr9 zSZVTuF4p713mae!jbNJoP0a;FIFuhaIXlb_{R7o6$%@|FWdrlR5RIHCc5x4CR8;~Q z5{7cz0+N83O%Abdjt1w7X+;3232wjpcEcmOxJ z8kZUXP5J`Zsx4SMKD!)arM+l#q~Nj^H&AzrNPvEi@Y)zb(b;}csTNS*nbK=wO&P%)-al}cYf5z%BN)O_O=%%?R*|n~-jG3O0TA-V0!^_py30ws zEKDhC#Y8XW(r7=SjmUP6^QT8!CF!~XbJmokbT+78L|@g*%A^U8z)?1TKhGkK8{Yum(9X( zNn9Zi4;i?bloLbjr=U0Z6bzq&)GG{7b2d-xuyY%*^YRxWzTaerL*_%)?Yu zC|J83tQ7!dPKp*N^QjSf{+h)=`Q}kn*leZ!mXQJwe zI}>B=C@NrJ$(J#RID)R1V+sI^>~gLIscsGQjYx^qvJL6og33;ad?wi%JTEM&fv za6uBox2v4HlYvSZL~@g=FOXYx$aYyJFJ@^RE6}LsSJ(d%%2g7MI4$5r*SRw>pF6

@r)_VP8Gb^t(^NRh4Ld{CMB>|*REW7%+wvj#fs5SsR!I~Dp&q0 z1vh_9XsVuYi$Iy7x^m?)Q{F*-(@@w*2QoEIz{quHYII+v;0_FQ*aq6NaGd5WnZco4 zb>W!8d^0kHvmh)fH6rpS7LKA){wjr<6DUl{7@2=i1~J{B1#**r4a#LH9p_)?m$los z6Zi-wW5fHpuTn6F3kWu3=ASFg1>H0%wy#OK-W0zGmCJs*SO=owIZ~qq?eD%yq5Nnt zhL3_H%P!pO7iujR$hdH*)@oUJnY^lPlPB1Brbe@ zyx9G=eJ;pwQ!^w+O&b#~0^iLe7K)W~U!`Ch=L#- zF7S*wat18ib(KPS<+LrAvGWOT!pEqvmOaLkMtxB&SlyVZFZ>Sc2A3f4@yo6!%&>G^ zrQlZ1v{lf|Na)EhEM~7zD$T7Hheh>ZolK;x?htjRBP>grt$j+w929NK5kzrU0 z*HsEHQMA1RuDue@ZX2Y^=_0oGmOUs6K`x#7l4?e_Qkns4%k_$K8r<}cCN zR+VJ%_EUh{&Z`t~^;+jXI!&tElihwFtXWmXMORUum2OY=pwtQ(7f#89!=n6fQaS)Y z@l68ao3wU7o6wbn!YY4Nh#j>b~IRey&<*rib1GK_SZLPC`VapJ)bnkB&q;czy zeP5=y@V&Ry#Fcd8ATnS{Dc{77{!X$4K3dC#E-Hi@b6=%E-bUPnMDO17W{8m5D&?L? zPC8DhZReOqXwvYBOg?co0H_1N!U`jMt8^sHFe-p0MK%l%r$#B<1ez5`QJJe00O;Nv z_f-mHyPk!+25+HgIN^`NxJsdW?z&2Wb<5+ax-ZDK9bAMDmXTp?v0c}ob;gBju&c*WQDqQo!k}~* zup|q@k_mjnBZg){t;$sjCetdJ#(-r=%$i}n6M-m7-kchUSiGGaUaZTYh@p zX`?6L&fVvb0lQXkIx~#;8Ew)Wv4SN915pNHnJk?d(5#AADX{G^{xb=@Q=&sAcNag} z=+>0f6;!ifrWlq)e3P%3Z{pyX9~jWAYF8<+a@zJdXPaSIy9i6H+?a9U)s!8DKH*pa79+}Xr3Rfxc5Yo0SnGQ4$D<_{6nZ~4?aA7Hr80;#g zt~4kVG-e7nmMq?Hr^p{khB>(rGvCBWjmP=a$k41{uz)YWDqN*t+5#yzJX~uZD*~@B z5N8u~@f}CMkO8|^SMK{Dk;>={?;&PNqeiJGQ6xqHMa2t?IOYd8RrF|R*1c(HmbZ)> zsc@A-ZqO>FEf9fam`K%oT>p__9ff)2G9@KR!LDZ`33jcZ9COl|Yc&Xh_xv{E#uO~6 zhe04ojLQ*&Ycd2rzyNQqrK$1!Sf$1{8E96Os}#)9L?D{vh_p#MQk@yr+mc~zLN+Cv zYFar4yKXRFyMlVOC&2yqDR3Tnf{MiWjiQZZluJ40O-_wNl^Xvfp;=s1DqN*tj{Bk` zQF45lK!gq zZ!_|bbN5=xrn;Z#-0-7MN$O9f)C6|@7L}uQ{ZevMF9=*Sckj)zg)-F?wI(SCiz!QZ z;|z<6gk~+Bs^+QkRSG7Upo6BVZPc4MInAh*TzD(dDG4&z^ zOH@2zCnWZsFxa*FVALq#O(Zf4m21RfBp3b*uPHB{uTmq0-fz)M z&k$jW93GGTw8~Wqrq5}faH^cVN?;6|VWddR|7JW|(e#0`>blM+5lwXhpnSBNawez^ zG~R@KE<*YW2_t5tM(sd=UfO#th{MB0rTSG0%wg_4eyn-I%|!8p&!}^H9o<7qO+z)S z9_GeLR>htqLb_thL+>`Gs;nGiJW#mhO-Y8?wM_9Yr$!tE*gUCuaWv>L4Xwge3MSWH zkwdTpN>b|J6F9*!6aeriTqUpb1@c6i{|sS&g0IcU+6Un!iNTr43u0Y;c}?a zIz%A?_!OqinHoh3Vw~IZMyFg9OWUCI3wI3kM)TVrS7{ z(?H2p6fTEM0Eht?GG!0FbUSl*0O7uy_kPSprTSG0Y;1tte}FX!Fjz5Ky9`UT1O=J) zZjo~L#)E*n`^w|(&rG)22DCoFX~AApvH_0q?cun$%0;EZRSNF0COfC)kM9jm$+BR^ zzsdxKLgFIxdep6ilCz^m8JPuQmA7I^T6==y8xgfTp;1&SUZr3k)Hxv;&Kor?mh;(u zL7>*yFhm#o6cwy=MW@3gQb4ez2(be0^4L^>8w7RbqEhWD1^4h4JR0CzEaw#xSMX#| z^EPp!DkwQKjfhKPYou=3`~BDAuqEdCDOb8m!9Bhs$#BtvShcuZ=P^Iq350KDlP?#z zp5YKqw+YkpH!w4Xwdn}1a+QL6+_^yjUa(Ht@h5C5hVUUuj-#R?A+SPf%sOg7nGu!a zKBnqb3T~Qk46T|4{_PuVDu4*$Z6@NDnW6$S$vOZaPeKzEBSx%NxJtn_0P8<0R~W2C zl^ky1JmqKN6gD%7D6_p~2sK;xC~bR3P^`W~@kq7%GTQSv*XTq@b=> z6&%lvguA*&5Vt7}tU&I&9_4yje$B$)3gqax z&k)FiU`CY#apr>b+L3U|>RH-&}ZaBv>tCfuN|KQl&yJhe)U+LfEc z+nuX^EgV^a?0A-4RSQ-|(R}^C_uX?aZfZ!%ZQq`|l5o6up2CPXkc7!AQIN+HnCdfy3VB-L~UtJ7>1(YR(dFquhqpeHlO7&}(1oWtqR;~drd zJVThgOh*=E$bG+CsNJrAyCgoucbg!d&_X}5FlAyH<411Xl<9IaMQC)ndP{7vLpcYz z@2x6WG&jU2N#ZOxs+fMndaH&m*)EK6;dVK@Tk|Bp)7aumC>Q*8dQ+&J(J)k0u0fb3 zBU&TzF5YKV^9f2M*>HV38HH&)F6Cys44vz> z+uOASQXt>jH@oso#iO%t79o=e_o0L)Va<{*j#F66!?8;_625;`R1n5o4u1qUCH_d# zk5-UKv{PsptTTlrcp_uF570iMrPV==K7bu1Hhc#8L&2&UtT`gw-+h9}Lw0ZeLS6}S z-`^qguEGF^O*nQ=0q zAMHrtOhj3>tiD1&z4^N-<g8MiLbJ>&Ggj`kT;RC1vpkk6aS^qXsL0SWYeq@DI$Yigq z5S>Mo(hzk6amgDwd=@TGgnOl{HwEc|$_GT>i%CJ-Jx#})O*GmIZh+(^-a+F#-U?Je z7&d0$k0$h^maz2n2B=Fa*Hf%57Ow1#9E33kORCa+<`YSTL*+KTIms;+7TqXz3dns_ z_QKD-%>^>H@Dd%viIXwtM`f&%u-zM<_Ux2WK8PAOa?ESt%<9N}CIBETvKO>9w$RF- zW8{rN?h7=zFD6FSH7NHgLq7tuE}Da(V-m$DE_WjbHMV_Gcz9x#o`OY6-ZRyF7S6%0 zo1*?nIwfY4i0a;TD0h&dAAuXqr1@?H9UET|0E(n@v{`&80RM?axWvNJqs>F@%H%#Y zt|S~|9ggz_B11nCC6x<;9+8%awG}Nv`FkavDR92oYny;l-aHFu!Xm9tmW&yfSW&ql zq^zLHpmuheesq#gBbEW^4H83hfmpN?QC7Jx=m?~Jz?*i=VG(ANv4z6s(e|8samBKg!ULMBe8BfD~r0ATxr{*jbx44ALi3IQde>i{sEr zgd;~HsOd;~89g=KG$lKZMT9V3iLxkE-6g~>GiD94TZ{tF?MJ^-K;$uOSq zV4@r&svJ$EFNH(fTBbqkj!R$*BTFDzmAlYoFJN+Cg;8Itx0?aIGC6>RI&TT_Ihdv& zJ=lpvo}!`oBTNgD$_;dK9K;_DgdIDtKk&eFsH_bNo*ok&*-{=kA&hwQ1DIX*5~FDv z84W|F0i**dA#oE!sX;r;(vR}ZdcC;@S~>MXU0MB>ni67XeZ|B`3t>CxYV7w_(##5UYR^O?hZ$_4C6%V^x&v$31Wqi7^RS73&a+AzuMlS` z-wlxexP{5F1q*kJSZaJ9kOQ91M7ZF+-98fGp0<-?nW{D^A1G|$QV^r;u5D$?-m)}C z)psZ+hTocU=|_)DKl;uNgLsNLORF7Uv3Q^j0EEWf8J~E|9$Pu@GFcj1;OPxfTMRm= z+@hai3y&fKK5J}YKvTGsNk7l=Bcm6O0{g)JO(9m>t;llQ|v##_IkvbW8& z#7cv~Km9EIXb!9Y-E%unuA|X-AheY{P(weQ1HFa|Kdlopr6;7UhEx0DN?M z?o#d-2$P%UC1OZy?VxekV#s1;pX)HMBeEjHa{08$ui{P9EX~dLWu0A2s zj!+>%$z;UIyLwOJGfaf(N8YB!O$j$=iN@<*fbc8~*5^dqOb*=F`sCp08v~JD*94Wh ztD+SXfdn2ROjjjf;baRk-KNo##sT9gE06jsW24&2 z$75n`?K8;8dWI)>`Xh#?=WgWiJ2-_#WdbTk@z#^T=ec*(?%m31Mhk}o5V=p;ejCcY zErrW}`zVsynmEhX^~SHX{d5XHuK~$`?RwJprK$ z7b@{S?VjvsSH0|qkv$@N3MBU~8<52+(t*gsRH886ju^yK!ciN4=rvy>1xiu6OyxAy z9fkpsByQX30U{YDL`P2H=?}7pf;yuzH5I0wV*6I!ETeLc0^#S92@w8KG_V1}WP*xt7rY2#GgkDXe+c9Aiqua6TKX%)?Kq?sVgWJc(}1 zf~VI3-p!8n}>{>XM9Yccnlq#8AqjJf?`4z6Oh1|UP+ zR6xjg+(1-!BG1b+QLias$8*>{Uj`G6esjmE91Sy>5TEk9*Xwc(xO#}s+p3Dd@+hFQ zOX-`!6?zhOEHTlgm7@#6BW{;2F`yO2oJ`6MV~%SJad3dqK(Wd7`%u{^5LbFo7O*|% z5y25?`~55Q5WvZ#%y{5!|D}|J(l74!P`N{e?8RU$jfqBo3uBPm7gu_+oJ`y!VAj-i z4-ih>YV+#d4;@7Ts8OI`Esco=zz!z*p#1htK&4+&^G09+>$t|9>yQ?8>pcF<*KBeP zPmjGzVWMFPs9m~3A`S*3pG+Lz$yHA0UFz}ttwZgqFYbSNAau`$ToTY=v($-h!?sAz_ z7GqW}vA|{eR!9AvksPZF=db33Yar|x%3-2|tCf4^ry^}ZT$*8cPRP-1g3Gvx z6W!wsGO_|K))?P4*yMq1PFKqacYIauZlL(7&8{P1SwSBJ)+wP}BZrLiL zG(VIOPSInp=5ovtD_dCe${jhC(~inew1r_<0TJkAlfxxZnT=rm&SjHak`_rLgrEih zmR>H4Bsy{_YMP8SS$ z_b%n^X`7UTuRkCOItt;lD@VT&SHWgq{BNI-&}byTq4_RoqLDQ>lG?)}*d`RV`;8P7 zG*?}z8Rh=irkopj2s(tcxAj4dydMOI8Fqp%nJ_#EXe5O*^9d^#D|{adz>Zp6!4#rO zeCt_mY%TY0t_Y`X9YP(&pa3z+ScQPIS3y9C6dR@s%&;&CP>a4EsG1cg7szO`G))yp z*Fa@*YyB?J5bj_lTM9j23MZ`O*~U5p&is@K*WXi^u0H)k&jB$Twi!#!R{bXg=0Wk% z%_Zv%tS4kg(^Q?U&E=k!_E_@nh&Sef@#s|l1z*lts2t<-&lzw=bhB2ddMfqLoG1(1 zr1E3Hj4bFZl-$xZRqs~11}ZZ|XM2+R!|s#Jn(PIS91d;zd71x8m>o%yB8iBq(~e}e zcf&Sc5p45ihh|CfQ5@fW5bol~MFRPzl!Ku!Bwz~Jp&nLqmO!@zkgt@>a; z68(M9%>d5G+kPiuQxeN_8+lW=XW=lq-Sfa-& z5lC+Qr>{qJHBAfvr$p3A5vP5qKxC{na*)wfH&KEw{?{z}OR{?kz_?=*b27{zi5PH3 zRGyK>bQS8ho}rEb06LInXL&f70Ocxv)HJDp>Qf~Wl_;RRd)og?U&d)4+)R6J6<%T5 zR&r+?A)B!RLI>oeJ2o&~1-fNmn+!n;f;O_V?tDz>tk8L}1gCI+k3Zk4LZ0QmRQgRv z=Xg#aTpz6kFX+nTGaW)i65Fx=UV{-SnrEajT~O$6xIhEt!}usWPmW*8FfB+oO`_UW zGfeK&m^yYi!AC_< zviPMboQi2><+$9-qQwy>O4%MyAp>qwl|1aN9eR;R5H%1+EwRCz&LmKdFkNPDG#Q4+ zd3F{Xlxmv#rc+cvL?@}=^l#{hD=+$S+FwZ6!f8Oj+8y>d7pChl2nf>^5L;#m9MrL4 zo;o&W;oMCVm%i#FAmP|=0BiS@a^8w}+iiQ!Rg#obxjqzSl?z5aiA~60x?EV5qhP|$ zY6-h=LBg_Gnx-rEBSFTS1KF2Sca?ZFR_wq>It^fkHP7EG6m*LG{Ua+~yC0lVjN%DIrmj2x3aLXQd2 zE?lGu54}LAiVY&1AaFA%!P;?_I!1m<5zg!^30V04yZDl9B8SOZj!0B2cDS3JRVeNY73qztJ;oUB6Wr|5TsV&wvL+_g7N z;@ej)x}}x7pmHxRK`2E}Sdy0GwHeCQg#w)UPgyy}bbS^7{79I*Hqg|ub~02UuIlmD zKq4cVoy8dr$F%P-iTa_~jr7~qn$tS#8+v4V> zaw*^pm19ho1s%{_Yx;12Rv7}+8}w6VXSqxNEi8MZv}tNxRXOVD4an$FF%KE|DD1Ky zkaAq{q;d~s2&r5@dJso8<+6aYRy6+84}U!x%pmK4sQdn+BtWrpZ=|0RJ4-6(F8v1- z4|W2$d+_gwRY#u%?=Dfm$)dHz<=#;4h3plY!F^OtSyT4e)XEXKZ;ZKq2H=d9gVv75 z^0e+UIKhI9)C|LD;SsU3B1tTJpK)@I(tm5ZX}WTS0O}8D^W4!7b*j>Y=-8^9{`EE~ zhr|F$i##TO^)z+$O9Y8Mk7p^jyUNNbCeg{l@@62Fvm+x3yrmsACa%L6BOC%|XYp$S zSJPBMIoZ*#-8|48J(K%-s<|S+`57uFEJ$d{i`Ic2;m|!Y2JSLCXRk1 z@pH-(4lK&$m_!>R6pk=mb}G;OV_#9n6g>*C6h)ZnTExz>Dwhq~M7Nugil$yIR2oeH z|Gvg0s5qe1yYsV+0s76^3Lk}vx3jBqz0TXx5h#RU>7mM4cI6mE@Pi(nluzcy-)x?; z2sRSmdLmhyO@)(tXFOm6l=%uZ!M~ZNNuuh}?W%$gvt~S z;GvR1+8)Y;MIfP)tkYe>vU3@6LWb`1uxnhNuHZ1LE>uwI_g+_4>`1-6sKbx$j9B(Fj7I>ge=2pW$@}Z3$7s?BTsLzOYi% ze2H^<3R%EeZ(-T<6qCr}r#WQgYXWcK`STPRNXA40wN=QQ|21uzWUETbMY?HPi7P5c zoXyYVss}8eEQp&XYB$F}L7FZ#O+T-|?B#U5O1K1ao1{rF zBH}%M<1u&F4$zmv0n{1^Ng-qiNkH6PD}fCr!twCp7Gb&;rOVk#d>~jDq1joAR%t=r zKn}6J6=M$nlpz1jE`ydTC`Xe^(1bvyB6SD?Yu4bjJ6pMZJ^FGZI)sAPG{M>E^nCwc zEVh85nr9NxWqz#>=55M-m#Jf{Ont$_Av?og*Z?K-m>wB-Ozq}BQ4VLwe|6<{HJl14 z;3V&H-~c`pCD3b%j=q@{6XqBIK3q{F!NE(@c9BH<(f{KM-2Y%@z|byr+9b(h7XSP*JX zFsF)eLq7Mbg_=CFwHA#t^))DXg;5umVpTl56y+mOCKTZ|6Zfly)v_*ky8?vo+IXuB zZ6UJE_U$_&i<5?#V9vzmr%zo@)7@(=rCW)pNOX%Cpkn>gfsAP z+q>h$u9=736Hy)vM=~@5rg^$%3KUB%=ni9HGpT08-otd5B=i*y;_W_wqB8ZZD1#wK zxMiN|uNKyo4EUe2GBna8On+P^{D8Dk$$1({hVntb*j=Tci0=W^wFPoSER;l!@UqIy zxx;go3`NQnkTkmXB+MdIG2%&>tK<93TwohJ${=p52+vQ$`^nvMC9Z}cNo30ebHb^d zHsK_E$0>qoblYL1Ct>BjP|O8`RUs_&432O^xWa%~PZU5+l*jjX6MjSzQe_~=`i0)Z zq*`|>F^v{n*vCeYQO?)oFvCd9;`rp?a~R~3XH}T7h6_ zHj^Qz5@$eg&10iH6i(QnUZfid*Afng&~BieTf*nUnm_NWaUY~`7J^!W0JU5SCMpe8 zaj@bE*cZ;f7KU(E>MW-ccR&Qz%*_)OK)qfuRp%{8BH=u)8F)!dkDX}{Sl=eX@EK%_ z*L-Kv{S?jH%i_H<*De7l;q2uL3OJTz1QvV`8y!tY5l@tddUb>D%RN~c+UP$n<$`=} z#IZj;EFiG1nd*shrVM}`!CuABw-tiKmxD}6ID7fxB&_j$Bm%>q${6{QQTjChT!Vxu zA54cymAh?gOj$YRB&KwwJ(R!>0%K|)rFtEw0GcfH3o8Rl+a(g0G&N(@`p2AL5LvxlGXg`h;=v>Iv$0GiFxBTrsPHb0Y(w7~@Gp)M0jvbE;Rm zG01ZEj!*(pj&(x~z=bcA9Lo<;f+rKB!hk3+A``}CiXy0&4A|ZNO`@hBMv#1tXet5{ z?bxt=(u_Dhv<@?upvbYzWD-%hsToH7{6vim z)N2ieL*;rw`@!<&9Z9AF8_IzBPr4WzE7o_1Q9fqKQi& zT&~T@WKWsA1yX^!8&JwdGVwqGeUDHbCgo#-rm{i_)-@J|BAm!s&)SCdv}oJlQ3seG;wze6C=fYoYO|kB1#Gyc_u!ml7}57+i3{h(7xp2A@ICr63R@A_GfB>f=ZVVU(1u_~ zQxVD_$w3yFsX{aw4A)RNQ#}>--nk>HeMAV9h?59P;tK<*+$<&-GUy!h*p*}Y z+~{n?tcr3p*rRD0&FobFiVke5d8V@pr+W8}hRlT<2k1c%eP9-T17E0cj0(bM3D=;T z3{xYXXEaKUB4P4T6ks$@`8Xpq6_{wMU}%f*r85_ehI<8K&%t?`>PPlePY%R8(xpG; z!Vysqz-VTN$@FHl$r(fVSZp51oiMsunuk20XBZJ5*=T;-Q3k z9RzCz<%293P31-zke`k;Ld~vRws;MLAke2gTdGI33JVw$^$dKW8^ULY)Z6C~c|Hmd zTgjk&{FW?Yg{BG!O=T*V2O!BbH=0eOsZI9^s^i|!DYzJ+hC3QscSHq@W#BCAhVYr8 z%2w`qn2!P)hXzdfU^LbCt>+TkXQB)+zF9a@j{Vf8T#zeX6hmpMZxxh?hGj=77tVyk z1eV_Z2u4<(49jiKV;b>T6Lpy8_D!H(TU!C6sj|881)x}xX*xybl#_g_{IpoPAd^ct zk#MRnhjAnxBO^}AF^rIka>gdkX|&OpjZEe066*CHQ9f2R;^b)a9s!niPTyB(syr&P zDQU1l&`xtUIqK&O&e~}P63l5bd())I;b5eCw=WE3=O_^;U*=?JShFxg_zILOo+de< zv|Th0&!@S4t10Cp+QDCl6GDy9R6p0;0H(p#IXA8$nNtBKKiBvtDk`G~E0M4hHkIJ^ z6wJz5b|gb6CF;2uMng?SIb#!d(IX>s9@Fg>GxWJ$glMX0gvyz$in=7v0kNa*50k|S znREFOsvRpDO#yPOLG{N(HxFznm~}8^koD`2BZW9Ap#zuuN28(J1`HSh$bye!DqHq&%R*Fa8FkL4T(4j z2HqV*1Sa@pA$(-AwS7A9yh7#j;G@mVJTvHX6R6iiY!bGj@kta$3|Pve3<7x1hsBAX z9;)BtOBxMDcqB>`$ropw>MyArAwaQ!-8y}+6I$?vjGfIw_(l&t4n-j?@>u@O%=0Fl zhk7$}ysM#JTDc9Rd^{SzCN!0uxUg1R>^#N@S2jrx_p%d>kz@b^j&QDCWmCOnM~VEa ziqYp0)vx$eR{n2R^2#aHu>$s@je@5#gpYYLS-Is=3ec39hY_i5%ws^kIt2BSa2SxM zH6jNvV96XJjc{3z4+rR{pN@$}Gms33Blo-KVRERm52s)gJIXtv4w8_1KZ-vcwkl&t#s8nzBP(Yon257%2$fNb_Xagylvf&<6ry)shj`$tW|A73#GoDIawtF5o)? zKs42$$E*r#gv)|_xG|;yM5AFpW#wk2`VCI?hH@`}8lbd{t73#%_$R-K#p&L;G<)sC-G28XZFO~>S>BW9{NQ~l?YRKJBO*fUaa_l3|nd@AE9>=?6fw1sc0 zThJ=T&O)tDz+TzgPau5J){blzmZV8&z%`nn+l92~Q7R!LoCgNV$f}$YPCFfOE9KvQ#dvPN>|HmcQBXI*(>!*HNfFOMo=VG3r1Scd_azip0sL^$!z#`elj-k>{F7D14S zJ#*9GdFTnrI@z;!7=-;cey{7@@n}e=0t>G#1LmyPP`SBi6B(NY42Z5Qk~bOKC*gC4 z601kq#{ndKmy}DnItNX~=xTgAKGVuMJ5)?1l!Y5T7Q1j{=eeLdS&Ji`e@vq~BY7B* z5=YoBTG3SGr-~glv6@@B`;CWS#St+e^0RamC7P7OA_=;95mt{?Yrvv2}HOt6takX#hZYP0-W2km5chE}&UN#(h{!vF*7Rlh+9 zHTaNm4kmog&ob*);_b-$7-=-C1%BGVBH1M1A!GYg!cy61Ssn81%5@a%n94Yap5$~; z=~tAhnb=wEP)S)?zsQ6$Rw0W}^4<1j(Ib*dPsm_B=XsnItU5ppEoRTzXl-l(Ek&bQ z+%Mv0394K*2-dK8rO;aPoil`4d1v3;&2&H3c2iX&Avqnmr3>Wgox8EKX%?0yzh{o6 zjo(9#3KJg4%Ex1*+g^r-1t6(?yTU?1GT2dd*g~vw0cb1gFrr7RY*do-QJd$mGj-Sp$V<}- zL$u+tVGK~%KApG;S$skm%aKZ04&|oSA~Y3_)39lh2g>|`O#X&VEXrkAI+EasHr!#9 zlt;1M6F9fYk{3~%l zmtY<{27r94{*C}a?zHg|+ABM5;$a11Se=1~0%GIW`Yy&U!JwmyDzxkGC_$!`zl2(o zkkWm!AErzieU1^9m{_)NhH! zSo&1M?Z(tz`;Pz#m1ZYll} zUJ>FOE}f25gvOneHkLt5TXgeMC$Iy^fJNL=#3gajlU!rKXD)rcn480eq9^xa^X7$1 zaH^hk==M3vz&Sx~ZnzFvT}UypY~QBM>n)_}X*ZmBn_*f25*0msNzv=Z&(6$gOW~HZHDRi z$P7-gNod1((_un92PuSDD$sKX9Go;*ot$~%$jLH^XDtkAwLq|1EPgC6t7k2~!tR~} zt-8gzk{H&)v3-^$z{%PFX97y%B$X_i{kk!Oo4m)#8AzqUGmtvBQ;SpGzeCS#S93QH z1B8OS(;+pm7WYHT&+V^3LD%@oN{pmpajFp_Y90y#)sU3kd43MRc_`>i(IiUoIGx}& zvqpudR3x6O!^v$wdMLVRlarETC(0~clv9Kj=Aem+ zu18yFQes3It&dn21)-qq!4VbnhRI1@lyNSK268e>R8(*ei4|qG4HTq)&JUJXlcKcfHOdt*|^M7X4#FJ`1tt$W`F;`%2}32S^xk50d!JM zQvg8b*k%9#2dha$K~#9!-J5}u+B^(|QGB@o0p9;{o5Xe^%hFo*U1$FOnQ7s=U3n8Y zF#6E#_Fp}w?HCdpT7QnO@2_veheT|&B{Rro`QHCbog&n>kXB6`qMiT}fp&)MxhR)OIRPYM&8}%2A%yLJhY)Xt3yIK}LTZv3WLcK*z5l)6 z#=)te)oKOArWdpD6A%amK4W)J*Y?oS{-tBJW&FFEU$x_BGBrPuBU8B z^&UlGYKyieLe70j9uICKhX}MXq^Jp_gwwRtuWY7hYa-<0erXHrfj#b%PXwAs8C*f` zpU+h=te+6bCqg4nDK(Jfsu;E(KI9V{8cQOIf*_~s@Gut=n?_3mN#5`1n!|SYEee`q zL(56(qIQz^>$z2&=Mav&?;?pUV(m;>7X?Y4_vdy7`$gREiX^7k&~nPUs2wF1JdS80 zp9nN1rRR5NeeaQD!R_vQC7%d2o>CS?QLcjTwe%nnXk|)S)Q)mrlj*Zr$S(qorBsUA zpLU4W;~=8?6OAcCV@|1QAj$U^9mkjU*~%0fT1=@GHQ)ax_Hk{Rrt*WADF&#WDV3r| zj^l-Jno_}O-%C*WA>$JFpUTZ%Y2+G9DT?Ap^t87F(0+K{4m1$|OrVhgYFR--A?*6$Me~cp3UU-|zSPncmAE$3O2m ziHpa6FqW&dLyXn37GGXPQ9B9c?L;=Md!bY^locn8U3{jZg;hW3+)tFIv>b6U zR?FqWt273nm1=9_#!ccaB#A_uK;=nXM&c_`HWCr-H&sy-C7YM#7+p#SZ5{Fj%UmVi_lSs~AbwOOwa*lBo-32)ZT<&m=aTU!4IR{+sf*Au` zrFKEi0hi;>F|I;>&Hk8y~qCokjpbs6afqr^=M6c>X{=AXFb+`_X@Z>NG%AZ-#v!UwnOwLc z`&45GRk;>ZOfFoZEp{3^s0#J~&T#|Ai*vZCN`RjI&7?pX^g$KjNgri2 zl%W|(Zb&CaRq%VUfGUaLh>EjGKwU^xM}+ZBZH8%Q3l-J{Q;2C;1#H^tw$Ld%5d2y__|@KF${EZn&7r@XSIqd4;RRF85?|D#JB_FxKnGQwCvVD&zNN zC}uRwF_ZV<>Fo6jdQf-t#r2wATloXq1LaL^S9CF72b9~Yi*yfuF?S9!04@>xINpG{iHDwUw_4-g(Nq@7Swfps! z{*Oxbj8L$yz24IApUPmYNk7cyxGMZbxqcuO(-|e3|$1)mo8Eqqp@Al_y zTj(6iXv}3ef?NXw#h5|bmc+4))l>7L4t$ir5hV>g6axd->_SK|CXQvSt7}3eQ3o-& zfJZ29eBj~ynm*-bdPX3|^=c!8r+b7VJ`?mLdBo-T>i#uM(5_ii2hRvabjtR19y2&D zv~j(B2!RbQc>4V$+t;~=l^!`>^5!1PC{E5lLeaR;EM-s4%SJ!%&nqP19~n{j1N^D? 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 68/79] [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 69/79] [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 70/79] [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 71/79] [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 72/79] [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 73/79] [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 74/79] [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 75/79] [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 76/79] [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 77/79] [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 78/79] [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 79/79] [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()!;