From e570c2eba592a3fdae5d60a3a8f2bf9e3ff46fa2 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Wed, 10 Sep 2025 15:17:01 -0400 Subject: [PATCH 01/29] [Dev] Stop creating dummy RELEASE file in release workflow (#6442) * [Dev] Stop creating dummy RELEASE file in release workflow * Delete RELEASE file * Update .github/workflows/create-release.yml Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update `create-release.yml` step desc * Update `create-release.yml` to use `pnpm version` --- .github/workflows/create-release.yml | 12 ++++++------ RELEASE | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) delete mode 100644 RELEASE diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index f2e17898334..fea857355a0 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -55,15 +55,15 @@ jobs: - name: Create release branch run: git checkout -b release - # In order to be able to open a PR into beta, we need the branch to have at least one change. - - name: Overwrite RELEASE file + # In order to be able to open a PR into beta, we need the branch to have at least one commit. + # The first commit is _usually_ just bumping the version number, so we can kill 2 birds with 1 stone here + - name: Bump release version run: | git config --local user.name "github-actions[bot]" git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" - echo "Release v${{ github.event.inputs.versionName }}" > RELEASE - git add RELEASE - git commit -m "Stage release v${{ github.event.inputs.versionName }}" - + pnpm --no-git-tag-version version ${{ github.events.inputs.versionName }} + git commit -am "Stage release for v${{ github.events.inputs.versionName }}" + - name: Push new branch run: git push origin release diff --git a/RELEASE b/RELEASE deleted file mode 100644 index a1a9f30b0e8..00000000000 --- a/RELEASE +++ /dev/null @@ -1 +0,0 @@ -Release v1.10.0 From 65c72c65b994ae43723e130074cb007757764696 Mon Sep 17 00:00:00 2001 From: Domagoj Date: Wed, 10 Sep 2025 21:23:13 +0200 Subject: [PATCH 02/29] [Dev] Add Podman support (#6150) * Add Dockerfile * Refactor for improved podman support * Podman support + docs * Update documentation for podman usage * Update docs/podman.md with working podman run command * Add package manager constraint to package.json and Dockerfile Update podman.md docs * Remove package manager constraints from github workflows per DayKev Update podman.md docs with extra steps for locales and testing command Remove missleading comment from Dockerfile * Remove Dockerfile comment * Re-add `pnpm` version to Github Pages workflow * Mention podman in CONTRIBUTING.md Fix typo in docs/podman.md test command * Fix path to docs/podman.md --------- Co-authored-by: Lugiad Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> --- .dockerignore | 7 ++++ .github/workflows/deploy-beta.yml | 2 - .github/workflows/deploy.yml | 2 - .github/workflows/linting.yml | 2 - .github/workflows/test-shard-template.yml | 2 - CONTRIBUTING.md | 3 +- Dockerfile | 47 +++++++++++++++++++++++ docs/podman.md | 27 +++++++++++++ package.json | 4 +- 9 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docs/podman.md diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000000..219c096336b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +# .dockerignore +node_modules +*.log +*.md +.gitignore +Dockerfile +.env \ No newline at end of file diff --git a/.github/workflows/deploy-beta.yml b/.github/workflows/deploy-beta.yml index 341999dcd45..5abba4488be 100644 --- a/.github/workflows/deploy-beta.yml +++ b/.github/workflows/deploy-beta.yml @@ -22,8 +22,6 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v4 - with: - version: 10 - uses: actions/setup-node@v4 with: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 528906196e5..1f2c1259dd1 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -20,8 +20,6 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v4 - with: - version: 10 - uses: actions/setup-node@v4 with: diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index edecae64f95..e1314c2cbd3 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -30,8 +30,6 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v4 - with: - version: 10 - name: Set up Node uses: actions/setup-node@v4 diff --git a/.github/workflows/test-shard-template.yml b/.github/workflows/test-shard-template.yml index 79aea56bbd0..6f4728863b4 100644 --- a/.github/workflows/test-shard-template.yml +++ b/.github/workflows/test-shard-template.yml @@ -32,8 +32,6 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v4 - with: - version: 10 - name: Set up Node.js uses: actions/setup-node@v4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 04ab7ff4faa..c24b648c490 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -80,7 +80,8 @@ Notable topics include: - [Commenting your code](./docs/comments.md) - [Linting & Formatting](./docs/linting.md) - [Localization](./docs/localization.md) -- [Enemy AI move selection](./docs/enemy-ai.md) +- [Enemy AI move selection](./docs/enemy-ai.md) +- [Running with Podman](./docs/podman.md) Again, if you have unanswered questions please feel free to ask! diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000000..ddb865b4831 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,47 @@ +# syntax=docker/dockerfile:1 +ARG NODE_VERSION=22.14 +ARG OS=alpine + +FROM node:${NODE_VERSION}-${OS} + +# Create non-root user +RUN addgroup -S appgroup && adduser -S appuser -G appgroup + +# Install git (for potential runtime needs) +RUN apk add --no-cache git + +# Set working directory +WORKDIR /app + +# Enable and prepare pnpm +RUN corepack enable && corepack prepare pnpm@10.14.0 --activate + +COPY . . + +# Copy package files +COPY package.json pnpm-lock.yaml ./ + +# Install all dependencies +RUN --mount=type=cache,target=/home/appuser/.pnpm-store \ + pnpm install --frozen-lockfile && \ + rm -rf /home/appuser/.pnpm-store/* + +# Change ownership +RUN chown -R appuser:appgroup /app + +# Switch to non-root user +USER appuser + +# Set environment variables +ENV VITE_BYPASS_LOGIN=1 \ + VITE_BYPASS_TUTORIAL=0 \ + NEXT_TELEMETRY_DISABLED=1 \ + PNP_HOME=/home/appuser/.shrc \ + NODE_ENV=development \ + PORT=8000 + +# Expose port +EXPOSE $PORT + +# Start the app in development mode +CMD ["pnpm", "run", "start:podman"] diff --git a/docs/podman.md b/docs/podman.md new file mode 100644 index 00000000000..dea52131e92 --- /dev/null +++ b/docs/podman.md @@ -0,0 +1,27 @@ +# Using Podman + +## Requirements + +* `podman >=5.x` + +## Steps + +1. `podman build -t pokerogue -f Dockerfile .` +2. `podman create --name temp-pokerogue localhost/pokerogue` +3. `podman cp temp-pokerogue:/app/node_modules ./` +4. `podman cp temp-pokerogue:/app/public/locales ./public/` +5. `podman rm temp-pokerogue` +6. `podman run --rm -p 8000:8000 -v $(pwd):/app:Z --userns=keep-id -u $(id -u):$(id -g) localhost/pokerogue` +7. Visit `http://localhost:8000/` + +Note: + +1. Steps 2,3,4 are required because mounting working directory without installed `node_modules/` and assets locally will be empty, +this way we prevent it by copying them from the container itself to local directory + +2. `podman run` may take a couple of minutes to mount the working directory + +### Running tests inside container + +`podman run --rm -p 8000:8000 -v $(pwd):/app:Z --userns=keep-id -u $(id -u):$(id -g) localhost/pokerogue pnpm test:silent +` \ No newline at end of file diff --git a/package.json b/package.json index e5da00019cb..8b5635d3115 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "start:prod": "vite --mode production", "start:beta": "vite --mode beta", "start:dev": "vite --mode development", + "start:podman": "vite --mode development --host 0.0.0.0 --port $PORT", "build": "vite build", "build:beta": "vite build --mode beta", "preview": "vite preview", @@ -71,5 +72,6 @@ }, "engines": { "node": ">=22.0.0" - } + }, + "packageManager": "pnpm@10.14.0" } From 328cc0221e6d1f936851f6c74c7c21857972c7fa Mon Sep 17 00:00:00 2001 From: Fabi <192151969+fabske0@users.noreply.github.com> Date: Thu, 11 Sep 2025 01:45:01 +0200 Subject: [PATCH 03/29] [i18n] Camel case remaining keys (#6508) * fix egg gacha keys * fix battle keys * fix game stats * fix splash texts --- src/data/splash-messages.ts | 4 ++-- src/phases/command-phase.ts | 2 +- src/phases/move-effect-phase.ts | 2 +- src/ui/handlers/egg-gacha-ui-handler.ts | 6 +++--- src/ui/handlers/game-stats-ui-handler.ts | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/data/splash-messages.ts b/src/data/splash-messages.ts index 21e7e5d05e6..a7791af78ac 100644 --- a/src/data/splash-messages.ts +++ b/src/data/splash-messages.ts @@ -234,7 +234,7 @@ const seasonalSplashMessages: Season[] = [ "valentines.happyValentines", "valentines.fullOfLove", "valentines.applinForYou", - "valentines.thePowerOfLoveIsThreeThirtyBST", + "valentines.thePowerOfLoveIsThreeThirtyBst", "valentines.haveAHeartScale", "valentines.i<3You", ], @@ -265,7 +265,7 @@ const seasonalSplashMessages: Season[] = [ "aprilFools.whoIsFinn", "aprilFools.watchOutForShadowPokemon", "aprilFools.nowWithDarkTypeLuxray", - "aprilFools.onlyOnPokerogueNetAGAIN", + "aprilFools.onlyOnPokerogueNetAgain", "aprilFools.noFreeVouchers", "aprilFools.altffourAchievementPoints", "aprilFools.rokePogue", diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index b9867e22522..2bf845776ca 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -220,7 +220,7 @@ export class CommandPhase extends FieldPhase { if (!moveStatus.value) { cannotSelectKey = "battle:moveCannotUseChallenge"; } else if (move.getPpRatio() === 0) { - cannotSelectKey = "battle:moveNoPP"; + cannotSelectKey = "battle:moveNoPp"; } else if (move.getName().endsWith(" (N)")) { cannotSelectKey = "battle:moveNotImplemented"; } else if (user.isMoveRestricted(move.moveId, user)) { diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index 0600f7d5ecf..6c143f1f8a1 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -932,7 +932,7 @@ export class MoveEffectPhase extends PokemonPhase { msg = i18next.t("battle:hitResultNotVeryEffective"); break; case HitResult.ONE_HIT_KO: - msg = i18next.t("battle:hitResultOneHitKO"); + msg = i18next.t("battle:hitResultOneHitKo"); break; } if (msg) { diff --git a/src/ui/handlers/egg-gacha-ui-handler.ts b/src/ui/handlers/egg-gacha-ui-handler.ts index bd96b4d9392..30afd2bf3db 100644 --- a/src/ui/handlers/egg-gacha-ui-handler.ts +++ b/src/ui/handlers/egg-gacha-ui-handler.ts @@ -96,7 +96,7 @@ export class EggGachaUiHandler extends MessageUiHandler { legendaryLabelY = 0; } - const gachaUpLabel = addTextObject(gachaX, gachaY, i18next.t("egg:legendaryUPGacha"), gachaTextStyle).setOrigin(0); + const gachaUpLabel = addTextObject(gachaX, gachaY, i18next.t("egg:legendaryUpGacha"), gachaTextStyle).setOrigin(0); gachaInfoContainer.add(gachaUpLabel); switch (gachaType as GachaType) { @@ -124,14 +124,14 @@ export class EggGachaUiHandler extends MessageUiHandler { gachaUpLabel.setAlign("center").setY(0); } - gachaUpLabel.setText(i18next.t("egg:moveUPGacha")).setX(0).setOrigin(0.5, 0); + gachaUpLabel.setText(i18next.t("egg:moveUpGacha")).setX(0).setOrigin(0.5, 0); break; case GachaType.SHINY: if (["de", "fr", "ko", "ru"].includes(currentLanguage)) { gachaUpLabel.setAlign("center").setY(0); } - gachaUpLabel.setText(i18next.t("egg:shinyUPGacha")).setX(0).setOrigin(0.5, 0); + gachaUpLabel.setText(i18next.t("egg:shinyUpGacha")).setX(0).setOrigin(0.5, 0); break; } diff --git a/src/ui/handlers/game-stats-ui-handler.ts b/src/ui/handlers/game-stats-ui-handler.ts index 9ffb7346b4d..e34c0af59e6 100644 --- a/src/ui/handlers/game-stats-ui-handler.ts +++ b/src/ui/handlers/game-stats-ui-handler.ts @@ -108,7 +108,7 @@ const displayStats: DisplayStats = { sourceFunc: gameData => gameData.gameStats.highestDamage.toString(), }, highestHeal: { - label_key: "highestHPHealed", + label_key: "highestHpHealed", sourceFunc: gameData => gameData.gameStats.highestHeal.toString(), }, pokemonSeen: { From 14c7d615b8fcf8ecb717aaf71f51888535da16a9 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Wed, 10 Sep 2025 18:57:48 -0500 Subject: [PATCH 04/29] [i18n] sync locales --- public/locales | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales b/public/locales index 090bfefaf7e..74de730a642 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit 090bfefaf7e9d4efcbca61fa78a9cdf5d701830b +Subproject commit 74de730a64272c8e9ca0a4cdcf3426cbf1b0aeda From e4a6a3de8232ce09b433db7ae21702a8524cd8ef Mon Sep 17 00:00:00 2001 From: Fabi <192151969+fabske0@users.noreply.github.com> Date: Thu, 11 Sep 2025 08:07:49 +0200 Subject: [PATCH 05/29] [Bug] Allow catch in limted catch during teleporter ME (#6531) Allow catch in teleporter ME --- src/data/challenge.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/data/challenge.ts b/src/data/challenge.ts index 64a88bc8be2..65faa900af7 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -1,5 +1,6 @@ import type { FixedBattleConfig } from "#app/battle"; import { getRandomTrainerFunc } from "#app/battle"; +import { globalScene } from "#app/global-scene"; import { defaultStarterSpeciesAndEvolutions } from "#balance/pokemon-evolutions"; import { speciesStarterCosts } from "#balance/starters"; import type { PokemonSpecies } from "#data/pokemon-species"; @@ -12,6 +13,7 @@ import { ClassicFixedBossWaves } from "#enums/fixed-boss-waves"; import { ModifierTier } from "#enums/modifier-tier"; import { MoveId } from "#enums/move-id"; import type { MoveSourceType } from "#enums/move-source-type"; +import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { Nature } from "#enums/nature"; import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; @@ -1076,7 +1078,12 @@ export class LimitedCatchChallenge extends Challenge { override applyPokemonAddToParty(pokemon: EnemyPokemon, status: BooleanHolder): boolean { if (status.value) { - status.value = pokemon.metWave % 10 === 1; + const isTeleporter = + globalScene.currentBattle.mysteryEncounter?.encounterType === MysteryEncounterType.TELEPORTING_HIJINKS + && globalScene.currentBattle.mysteryEncounter.selectedOption + !== globalScene.currentBattle.mysteryEncounter.options[2]; // don't allow catch when not choosing biome change option + const isFirstWave = pokemon.metWave % 10 === 1; + status.value = isTeleporter || isFirstWave; return true; } return false; From 559ca8610a0ba88fd9949f8abd01a1683215e0ec Mon Sep 17 00:00:00 2001 From: Wlowscha <54003515+Wlowscha@users.noreply.github.com> Date: Thu, 11 Sep 2025 09:30:17 +0200 Subject: [PATCH 06/29] [Misc] Simplifying imports of UI files (#6542) --- src/@types/api/pokerogue-daily-api.ts | 2 +- src/battle-scene.ts | 14 ++-- src/data/daily-run.ts | 2 +- .../encounters/bug-type-superfan-encounter.ts | 4 +- .../encounters/clowning-around-encounter.ts | 2 +- .../encounters/dancing-lessons-encounter.ts | 2 +- .../encounters/delibirdy-encounter.ts | 2 +- .../encounters/field-trip-encounter.ts | 2 +- .../global-trade-system-encounter.ts | 2 +- .../encounters/training-session-encounter.ts | 2 +- .../utils/encounter-phase-utils.ts | 6 +- .../utils/encounter-pokemon-utils.ts | 6 +- src/field/pokemon.ts | 4 +- src/init/init.ts | 2 +- src/modifier/modifier-type.ts | 4 +- src/phases/attempt-capture-phase.ts | 6 +- src/phases/egg-hatch-phase.ts | 6 +- src/phases/evolution-phase.ts | 2 +- src/phases/form-change-phase.ts | 2 +- src/phases/learn-move-phase.ts | 4 +- src/phases/revival-blessing-phase.ts | 4 +- src/phases/select-biome-phase.ts | 2 +- src/phases/select-modifier-phase.ts | 6 +- src/phases/select-starter-phase.ts | 4 +- src/phases/switch-phase.ts | 2 +- src/phases/title-phase.ts | 4 +- src/plugins/api/pokerogue-daily-api.ts | 2 +- src/system/game-data.ts | 2 +- src/tutorial.ts | 4 +- src/ui-inputs.ts | 10 +-- src/ui/battle-info/enemy-battle-info.ts | 2 +- src/ui/containers/arena-flyout.ts | 2 +- src/ui/containers/dropdown.ts | 2 +- src/ui/containers/egg-counter-container.ts | 2 +- src/ui/containers/filter-bar.ts | 6 +- src/ui/containers/filter-text.ts | 4 +- .../containers/hatched-pokemon-container.ts | 4 +- src/ui/containers/pokemon-info-container.ts | 2 +- .../handlers/abstract-binding-ui-handler.ts | 2 +- .../abstract-option-select-ui-handler.ts | 2 +- src/ui/handlers/achvs-ui-handler.ts | 4 +- src/ui/handlers/admin-ui-handler.ts | 6 +- src/ui/handlers/autocomplete-ui-handler.ts | 2 +- src/ui/handlers/awaitable-ui-handler.ts | 2 +- src/ui/handlers/ball-ui-handler.ts | 2 +- src/ui/handlers/battle-message-ui-handler.ts | 2 +- .../handlers/challenges-select-ui-handler.ts | 2 +- .../change-password-form-ui-handler.ts | 6 +- src/ui/handlers/command-ui-handler.ts | 4 +- src/ui/handlers/confirm-ui-handler.ts | 4 +- src/ui/handlers/egg-gacha-ui-handler.ts | 2 +- src/ui/handlers/egg-hatch-scene-ui-handler.ts | 2 +- src/ui/handlers/egg-list-ui-handler.ts | 8 +- src/ui/handlers/egg-summary-ui-handler.ts | 12 +-- src/ui/handlers/evolution-scene-ui-handler.ts | 2 +- src/ui/handlers/fight-ui-handler.ts | 4 +- src/ui/handlers/form-modal-ui-handler.ts | 4 +- src/ui/handlers/game-stats-ui-handler.ts | 2 +- src/ui/handlers/loading-modal-ui-handler.ts | 2 +- src/ui/handlers/login-form-ui-handler.ts | 8 +- src/ui/handlers/menu-ui-handler.ts | 8 +- src/ui/handlers/message-ui-handler.ts | 2 +- src/ui/handlers/modal-ui-handler.ts | 2 +- src/ui/handlers/modifier-select-ui-handler.ts | 4 +- .../handlers/mystery-encounter-ui-handler.ts | 4 +- src/ui/handlers/party-ui-handler.ts | 6 +- src/ui/handlers/pokedex-page-ui-handler.ts | 12 +-- src/ui/handlers/pokedex-scan-ui-handler.ts | 10 +-- src/ui/handlers/pokedex-ui-handler.ts | 23 ++--- .../handlers/registration-form-ui-handler.ts | 6 +- src/ui/handlers/rename-form-ui-handler.ts | 6 +- src/ui/handlers/run-history-ui-handler.ts | 4 +- src/ui/handlers/run-info-ui-handler.ts | 2 +- .../handlers/save-slot-select-ui-handler.ts | 6 +- .../session-reload-modal-ui-handler.ts | 4 +- src/ui/handlers/starter-select-ui-handler.ts | 25 ++---- src/ui/handlers/summary-ui-handler.ts | 2 +- src/ui/handlers/target-select-ui-handler.ts | 2 +- src/ui/handlers/test-dialogue-ui-handler.ts | 8 +- .../handlers/unavailable-modal-ui-handler.ts | 4 +- .../abstract-control-settings-ui-handler.ts | 4 +- .../settings/abstract-settings-ui-handler.ts | 4 +- src/ui/settings/gamepad-binding-ui-handler.ts | 2 +- .../settings/keyboard-binding-ui-handler.ts | 2 +- src/ui/settings/option-select-ui-handler.ts | 2 +- src/ui/ui.ts | 84 +++++++++---------- src/ui/utils/scrollable-grid-helper.ts | 4 +- test/abilities/arena-trap.test.ts | 2 +- test/challenges/hardcore.test.ts | 2 +- test/challenges/limited-support.test.ts | 2 +- test/daily-mode.test.ts | 2 +- test/imports.test.ts | 2 +- test/items/dire-hit.test.ts | 2 +- .../double-battle-chance-booster.test.ts | 2 +- test/items/temp-stat-stage-booster.test.ts | 2 +- .../mystery-encounter/encounter-test-utils.ts | 6 +- .../berries-abound-encounter.test.ts | 2 +- .../bug-type-superfan-encounter.test.ts | 2 +- .../clowning-around-encounter.test.ts | 2 +- .../dancing-lessons-encounter.test.ts | 2 +- .../department-store-sale-encounter.test.ts | 2 +- .../encounters/field-trip-encounter.test.ts | 2 +- .../fight-or-flight-encounter.test.ts | 2 +- .../fun-and-games-encounter.test.ts | 2 +- .../global-trade-system-encounter.test.ts | 2 +- .../mysterious-challengers-encounter.test.ts | 2 +- .../teleporting-hijinks-encounter.test.ts | 2 +- .../the-strong-stuff-encounter.test.ts | 2 +- .../the-winstrate-challenge-encounter.test.ts | 2 +- .../trash-to-treasure-encounter.test.ts | 2 +- .../encounters/weird-dream-encounter.test.ts | 2 +- test/phases/mystery-encounter-phase.test.ts | 4 +- test/phases/select-modifier-phase.test.ts | 2 +- test/plugins/api/pokerogue-daily-api.test.ts | 2 +- test/test-utils/game-manager-utils.ts | 2 +- test/test-utils/game-manager.ts | 14 ++-- test/test-utils/game-wrapper.ts | 2 +- test/test-utils/helpers/daily-mode-helper.ts | 2 +- test/test-utils/phase-interceptor.ts | 2 +- test/ui/item-manage-button.test.ts | 4 +- test/ui/pokedex.test.ts | 6 +- test/ui/starter-select.test.ts | 6 +- test/ui/transfer-item-options.test.ts | 4 +- test/ui/transfer-item.test.ts | 4 +- test/ui/type-hints.test.ts | 2 +- tsconfig.json | 9 +- 126 files changed, 288 insertions(+), 295 deletions(-) diff --git a/src/@types/api/pokerogue-daily-api.ts b/src/@types/api/pokerogue-daily-api.ts index 862ff2f51a3..838af2a2a34 100644 --- a/src/@types/api/pokerogue-daily-api.ts +++ b/src/@types/api/pokerogue-daily-api.ts @@ -1,4 +1,4 @@ -import type { ScoreboardCategory } from "#ui/containers/daily-run-scoreboard"; +import type { ScoreboardCategory } from "#ui/daily-run-scoreboard"; export interface GetDailyRankingsRequest { category: ScoreboardCategory; diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 50868e94c47..a8e8aa85121 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -121,13 +121,13 @@ import { vouchers } from "#system/voucher"; import { trainerConfigs } from "#trainers/trainer-config"; import type { HeldModifierConfig } from "#types/held-modifier-config"; import type { Localizable } from "#types/locales"; -import { AbilityBar } from "#ui/containers/ability-bar"; -import { ArenaFlyout } from "#ui/containers/arena-flyout"; -import { CandyBar } from "#ui/containers/candy-bar"; -import { CharSprite } from "#ui/containers/char-sprite"; -import { PartyExpBar } from "#ui/containers/party-exp-bar"; -import { PokeballTray } from "#ui/containers/pokeball-tray"; -import { PokemonInfoContainer } from "#ui/containers/pokemon-info-container"; +import { AbilityBar } from "#ui/ability-bar"; +import { ArenaFlyout } from "#ui/arena-flyout"; +import { CandyBar } from "#ui/candy-bar"; +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 } from "#ui/text"; import { UI } from "#ui/ui"; import { addUiThemeOverrides } from "#ui/ui-theme"; diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index a0d3358ecb0..addaebdd238 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -6,7 +6,7 @@ import { PokemonSpecies } from "#data/pokemon-species"; import { BiomeId } from "#enums/biome-id"; import { PartyMemberStrength } from "#enums/party-member-strength"; import { SpeciesId } from "#enums/species-id"; -import type { Starter } from "#ui/handlers/starter-select-ui-handler"; +import type { Starter } from "#ui/starter-select-ui-handler"; import { isNullOrUndefined, randSeedGauss, randSeedInt, randSeedItem } from "#utils/common"; import { getEnumValues } from "#utils/enums"; import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; diff --git a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts index 5462c0eb336..cb34190a584 100644 --- a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts +++ b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts @@ -46,8 +46,8 @@ import { } from "#mystery-encounters/mystery-encounter-requirements"; import { getRandomPartyMemberFunc, trainerConfigs } from "#trainers/trainer-config"; import { TrainerPartyCompoundTemplate, TrainerPartyTemplate } from "#trainers/trainer-party-template"; -import { MoveInfoOverlay } from "#ui/containers/move-info-overlay"; -import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; +import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; +import { MoveInfoOverlay } from "#ui/move-info-overlay"; import { isNullOrUndefined, randSeedInt, randSeedShuffle } from "#utils/common"; import i18next from "i18next"; diff --git a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts index 42907455e22..24ea7167864 100644 --- a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts +++ b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts @@ -45,7 +45,7 @@ import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter"; import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option"; import { trainerConfigs } from "#trainers/trainer-config"; import { TrainerPartyCompoundTemplate, TrainerPartyTemplate } from "#trainers/trainer-party-template"; -import type { OptionSelectConfig } from "#ui/handlers/abstract-option-select-ui-handler"; +import type { OptionSelectConfig } from "#ui/abstract-option-select-ui-handler"; import { randSeedInt, randSeedShuffle } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import i18next from "i18next"; diff --git a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts index 598f9d496a2..33512ff0760 100644 --- a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts +++ b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts @@ -37,7 +37,7 @@ import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encou import { MoveRequirement } from "#mystery-encounters/mystery-encounter-requirements"; import { DANCING_MOVES } from "#mystery-encounters/requirement-groups"; import { PokemonData } from "#system/pokemon-data"; -import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; +import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import i18next from "i18next"; diff --git a/src/data/mystery-encounters/encounters/delibirdy-encounter.ts b/src/data/mystery-encounters/encounters/delibirdy-encounter.ts index 79cccd91b26..8cd4c8bee66 100644 --- a/src/data/mystery-encounters/encounters/delibirdy-encounter.ts +++ b/src/data/mystery-encounters/encounters/delibirdy-encounter.ts @@ -33,7 +33,7 @@ import { MoneyRequirement, } from "#mystery-encounters/mystery-encounter-requirements"; import i18next from "#plugins/i18n"; -import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; +import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; import { randSeedItem } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; diff --git a/src/data/mystery-encounters/encounters/field-trip-encounter.ts b/src/data/mystery-encounters/encounters/field-trip-encounter.ts index 30c4026fcad..81d9bce3a76 100644 --- a/src/data/mystery-encounters/encounters/field-trip-encounter.ts +++ b/src/data/mystery-encounters/encounters/field-trip-encounter.ts @@ -18,7 +18,7 @@ import { import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter"; import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter"; import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option"; -import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; +import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; import i18next from "i18next"; /** i18n namespace for the encounter */ 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 7dbbe24fb69..823f016029e 100644 --- a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts +++ b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts @@ -42,7 +42,7 @@ import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encou import { PartySizeRequirement } from "#mystery-encounters/mystery-encounter-requirements"; import { PokemonData } from "#system/pokemon-data"; import { MusicPreference } from "#system/settings"; -import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; +import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; import { isNullOrUndefined, NumberHolder, randInt, randSeedInt, randSeedItem, randSeedShuffle } from "#utils/common"; import { getEnumKeys } from "#utils/enums"; import { getRandomLocaleEntry } from "#utils/i18n"; diff --git a/src/data/mystery-encounters/encounters/training-session-encounter.ts b/src/data/mystery-encounters/encounters/training-session-encounter.ts index 796840c431f..033a54cc5f5 100644 --- a/src/data/mystery-encounters/encounters/training-session-encounter.ts +++ b/src/data/mystery-encounters/encounters/training-session-encounter.ts @@ -27,7 +27,7 @@ import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter"; import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option"; import { PokemonData } from "#system/pokemon-data"; import type { HeldModifierConfig } from "#types/held-modifier-config"; -import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; +import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; import { isNullOrUndefined, randSeedShuffle } from "#utils/common"; import { getEnumValues } from "#utils/enums"; import i18next from "i18next"; diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index 0903624d903..aa569f11aca 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -46,9 +46,9 @@ import type { PokemonData } from "#system/pokemon-data"; import type { TrainerConfig } from "#trainers/trainer-config"; import { trainerConfigs } from "#trainers/trainer-config"; import type { HeldModifierConfig } from "#types/held-modifier-config"; -import type { OptionSelectConfig, OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; -import type { PartyOption, PokemonSelectFilter } from "#ui/handlers/party-ui-handler"; -import { PartyUiMode } from "#ui/handlers/party-ui-handler"; +import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; +import type { PartyOption, PokemonSelectFilter } from "#ui/party-ui-handler"; +import { PartyUiMode } from "#ui/party-ui-handler"; import { coerceArray, isNullOrUndefined, randomString, randSeedInt, randSeedItem } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import i18next from "i18next"; diff --git a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts index 0d07300d00d..8f6c78fab9c 100644 --- a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts @@ -31,9 +31,9 @@ import { showEncounterText, } from "#mystery-encounters/encounter-dialogue-utils"; import { achvs } from "#system/achv"; -import type { PartyOption } from "#ui/handlers/party-ui-handler"; -import { PartyUiMode } from "#ui/handlers/party-ui-handler"; -import { SummaryUiMode } from "#ui/handlers/summary-ui-handler"; +import type { PartyOption } from "#ui/party-ui-handler"; +import { PartyUiMode } from "#ui/party-ui-handler"; +import { SummaryUiMode } from "#ui/summary-ui-handler"; import { applyChallenges } from "#utils/challenge-utils"; import { BooleanHolder, isNullOrUndefined, randSeedInt } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 84ed3de6166..d3ff7312977 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -147,8 +147,8 @@ import type { StarterDataEntry, StarterMoveset } from "#types/save-data"; import type { TurnMove } from "#types/turn-move"; import { BattleInfo } from "#ui/battle-info"; import { EnemyBattleInfo } from "#ui/enemy-battle-info"; -import type { PartyOption } from "#ui/handlers/party-ui-handler"; -import { PartyUiHandler, PartyUiMode } from "#ui/handlers/party-ui-handler"; +import type { PartyOption } from "#ui/party-ui-handler"; +import { PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler"; import { PlayerBattleInfo } from "#ui/player-battle-info"; import { applyChallenges } from "#utils/challenge-utils"; import { diff --git a/src/init/init.ts b/src/init/init.ts index b717664b654..8452278b3f1 100644 --- a/src/init/init.ts +++ b/src/init/init.ts @@ -11,7 +11,7 @@ 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/handlers/game-stats-ui-handler"; +import { initStatsKeys } from "#ui/game-stats-ui-handler"; /** Initialize the game. */ export function initializeGame() { diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 155ada1c18d..579fb75ce3b 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -115,8 +115,8 @@ import { import type { PokemonMove } from "#moves/pokemon-move"; import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "#system/voucher"; import type { ModifierTypeFunc, WeightedModifierTypeWeightFunc } from "#types/modifier-types"; -import type { PokemonMoveSelectFilter, PokemonSelectFilter } from "#ui/handlers/party-ui-handler"; -import { PartyUiHandler } from "#ui/handlers/party-ui-handler"; +import type { PokemonMoveSelectFilter, PokemonSelectFilter } from "#ui/party-ui-handler"; +import { PartyUiHandler } from "#ui/party-ui-handler"; import { getModifierTierTextTint } from "#ui/text"; import { applyChallenges } from "#utils/challenge-utils"; import { diff --git a/src/phases/attempt-capture-phase.ts b/src/phases/attempt-capture-phase.ts index 81f85850e88..2eadae244d5 100644 --- a/src/phases/attempt-capture-phase.ts +++ b/src/phases/attempt-capture-phase.ts @@ -21,9 +21,9 @@ import type { EnemyPokemon } from "#field/pokemon"; import { PokemonHeldItemModifier } from "#modifiers/modifier"; import { PokemonPhase } from "#phases/pokemon-phase"; import { achvs } from "#system/achv"; -import type { PartyOption } from "#ui/handlers/party-ui-handler"; -import { PartyUiMode } from "#ui/handlers/party-ui-handler"; -import { SummaryUiMode } from "#ui/handlers/summary-ui-handler"; +import type { PartyOption } from "#ui/party-ui-handler"; +import { PartyUiMode } from "#ui/party-ui-handler"; +import { SummaryUiMode } from "#ui/summary-ui-handler"; import { applyChallenges } from "#utils/challenge-utils"; import { BooleanHolder } from "#utils/common"; import i18next from "i18next"; diff --git a/src/phases/egg-hatch-phase.ts b/src/phases/egg-hatch-phase.ts index bfd66bd02e4..946288c4fd8 100644 --- a/src/phases/egg-hatch-phase.ts +++ b/src/phases/egg-hatch-phase.ts @@ -9,9 +9,9 @@ import { doShinySparkleAnim } from "#field/anims"; import type { PlayerPokemon } from "#field/pokemon"; import type { EggLapsePhase } from "#phases/egg-lapse-phase"; import { achvs } from "#system/achv"; -import { EggCounterContainer } from "#ui/containers/egg-counter-container"; -import { PokemonInfoContainer } from "#ui/containers/pokemon-info-container"; -import type { EggHatchSceneUiHandler } from "#ui/handlers/egg-hatch-scene-ui-handler"; +import { EggCounterContainer } from "#ui/egg-counter-container"; +import type { EggHatchSceneUiHandler } from "#ui/egg-hatch-scene-ui-handler"; +import { PokemonInfoContainer } from "#ui/pokemon-info-container"; import { fixedInt, getFrameMs, randInt } from "#utils/common"; import i18next from "i18next"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; diff --git a/src/phases/evolution-phase.ts b/src/phases/evolution-phase.ts index 5943ed730ff..80750beeb68 100644 --- a/src/phases/evolution-phase.ts +++ b/src/phases/evolution-phase.ts @@ -10,7 +10,7 @@ import { LearnMoveSituation } from "#enums/learn-move-situation"; import { UiMode } from "#enums/ui-mode"; import { cos, sin } from "#field/anims"; import type { PlayerPokemon, Pokemon } from "#field/pokemon"; -import type { EvolutionSceneUiHandler } from "#ui/handlers/evolution-scene-ui-handler"; +import type { EvolutionSceneUiHandler } from "#ui/evolution-scene-ui-handler"; import { fixedInt, getFrameMs, randInt } from "#utils/common"; import i18next from "i18next"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; diff --git a/src/phases/form-change-phase.ts b/src/phases/form-change-phase.ts index 7521adee6c9..4fb34079367 100644 --- a/src/phases/form-change-phase.ts +++ b/src/phases/form-change-phase.ts @@ -8,7 +8,7 @@ import { UiMode } from "#enums/ui-mode"; import type { PlayerPokemon, Pokemon } from "#field/pokemon"; import { EvolutionPhase } from "#phases/evolution-phase"; import { achvs } from "#system/achv"; -import type { PartyUiHandler } from "#ui/handlers/party-ui-handler"; +import type { PartyUiHandler } from "#ui/party-ui-handler"; import { fixedInt } from "#utils/common"; export class FormChangePhase extends EvolutionPhase { diff --git a/src/phases/learn-move-phase.ts b/src/phases/learn-move-phase.ts index e75d7c8f6f3..4fc38b08d16 100644 --- a/src/phases/learn-move-phase.ts +++ b/src/phases/learn-move-phase.ts @@ -10,8 +10,8 @@ import { UiMode } from "#enums/ui-mode"; import type { Pokemon } from "#field/pokemon"; import type { Move } from "#moves/move"; import { PlayerPartyMemberPokemonPhase } from "#phases/player-party-member-pokemon-phase"; -import { EvolutionSceneUiHandler } from "#ui/handlers/evolution-scene-ui-handler"; -import { SummaryUiMode } from "#ui/handlers/summary-ui-handler"; +import { EvolutionSceneUiHandler } from "#ui/evolution-scene-ui-handler"; +import { SummaryUiMode } from "#ui/summary-ui-handler"; import i18next from "i18next"; export class LearnMovePhase extends PlayerPartyMemberPokemonPhase { diff --git a/src/phases/revival-blessing-phase.ts b/src/phases/revival-blessing-phase.ts index a9dedf4c325..fdb108d62ac 100644 --- a/src/phases/revival-blessing-phase.ts +++ b/src/phases/revival-blessing-phase.ts @@ -3,8 +3,8 @@ import { SwitchType } from "#enums/switch-type"; import { UiMode } from "#enums/ui-mode"; import type { PlayerPokemon } from "#field/pokemon"; import { BattlePhase } from "#phases/battle-phase"; -import type { PartyOption } from "#ui/handlers/party-ui-handler"; -import { PartyUiHandler, PartyUiMode } from "#ui/handlers/party-ui-handler"; +import type { PartyOption } from "#ui/party-ui-handler"; +import { PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler"; import { isNullOrUndefined, toDmgValue } from "#utils/common"; import i18next from "i18next"; diff --git a/src/phases/select-biome-phase.ts b/src/phases/select-biome-phase.ts index 3276c34306c..21c0cfade94 100644 --- a/src/phases/select-biome-phase.ts +++ b/src/phases/select-biome-phase.ts @@ -5,7 +5,7 @@ import { ChallengeType } from "#enums/challenge-type"; import { UiMode } from "#enums/ui-mode"; import { MapModifier, MoneyInterestModifier } from "#modifiers/modifier"; import { BattlePhase } from "#phases/battle-phase"; -import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; +import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; import { applyChallenges } from "#utils/challenge-utils"; import { BooleanHolder, randSeedInt } from "#utils/common"; diff --git a/src/phases/select-modifier-phase.ts b/src/phases/select-modifier-phase.ts index 51adeb21af0..3c378a95b2a 100644 --- a/src/phases/select-modifier-phase.ts +++ b/src/phases/select-modifier-phase.ts @@ -24,9 +24,9 @@ import { TmModifierType, } from "#modifiers/modifier-type"; import { BattlePhase } from "#phases/battle-phase"; -import type { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; -import { SHOP_OPTIONS_ROW_LIMIT } from "#ui/handlers/modifier-select-ui-handler"; -import { PartyOption, PartyUiHandler, PartyUiMode } from "#ui/handlers/party-ui-handler"; +import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; +import { SHOP_OPTIONS_ROW_LIMIT } from "#ui/modifier-select-ui-handler"; +import { PartyOption, PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler"; import { isNullOrUndefined, NumberHolder } from "#utils/common"; import i18next from "i18next"; diff --git a/src/phases/select-starter-phase.ts b/src/phases/select-starter-phase.ts index 50c06f96a77..a08394e3acb 100644 --- a/src/phases/select-starter-phase.ts +++ b/src/phases/select-starter-phase.ts @@ -7,8 +7,8 @@ import { ChallengeType } from "#enums/challenge-type"; import type { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { overrideHeldItems, overrideModifiers } from "#modifiers/modifier"; -import { SaveSlotUiMode } from "#ui/handlers/save-slot-select-ui-handler"; -import type { Starter } from "#ui/handlers/starter-select-ui-handler"; +import { SaveSlotUiMode } from "#ui/save-slot-select-ui-handler"; +import type { Starter } from "#ui/starter-select-ui-handler"; import { applyChallenges } from "#utils/challenge-utils"; import { isNullOrUndefined } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; diff --git a/src/phases/switch-phase.ts b/src/phases/switch-phase.ts index 8b03f5ec5ce..83a699b6b08 100644 --- a/src/phases/switch-phase.ts +++ b/src/phases/switch-phase.ts @@ -3,7 +3,7 @@ import { DynamicPhaseType } from "#enums/dynamic-phase-type"; import { SwitchType } from "#enums/switch-type"; import { UiMode } from "#enums/ui-mode"; import { BattlePhase } from "#phases/battle-phase"; -import { PartyOption, PartyUiHandler, PartyUiMode } from "#ui/handlers/party-ui-handler"; +import { PartyOption, PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler"; /** * Opens the party selector UI and transitions into a {@linkcode SwitchSummonPhase} diff --git a/src/phases/title-phase.ts b/src/phases/title-phase.ts index 97f6bf0d837..d422766bf09 100644 --- a/src/phases/title-phase.ts +++ b/src/phases/title-phase.ts @@ -16,8 +16,8 @@ import type { Modifier } from "#modifiers/modifier"; import { getDailyRunStarterModifiers, regenerateModifierPoolThresholds } from "#modifiers/modifier-type"; import { vouchers } from "#system/voucher"; import type { SessionSaveData } from "#types/save-data"; -import type { OptionSelectConfig, OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; -import { SaveSlotUiMode } from "#ui/handlers/save-slot-select-ui-handler"; +import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; +import { SaveSlotUiMode } from "#ui/save-slot-select-ui-handler"; import { isLocal, isLocalServerConnected, isNullOrUndefined } from "#utils/common"; import i18next from "i18next"; diff --git a/src/plugins/api/pokerogue-daily-api.ts b/src/plugins/api/pokerogue-daily-api.ts index dfde4720730..5ea3846e60e 100644 --- a/src/plugins/api/pokerogue-daily-api.ts +++ b/src/plugins/api/pokerogue-daily-api.ts @@ -1,6 +1,6 @@ import { ApiBase } from "#api/api-base"; import type { GetDailyRankingsPageCountRequest, GetDailyRankingsRequest } from "#types/api/pokerogue-daily-api"; -import type { RankingEntry } from "#ui/containers/daily-run-scoreboard"; +import type { RankingEntry } from "#ui/daily-run-scoreboard"; /** * A wrapper for daily-run PokéRogue API requests. diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 247f8c3660a..8c2a1219245 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -72,7 +72,7 @@ import type { VoucherCounts, VoucherUnlocks, } from "#types/save-data"; -import { RUN_HISTORY_LIMIT } from "#ui/handlers/run-history-ui-handler"; +import { RUN_HISTORY_LIMIT } from "#ui/run-history-ui-handler"; import { applyChallenges } from "#utils/challenge-utils"; import { executeIf, fixedInt, isLocal, NumberHolder, randInt, randSeedItem } from "#utils/common"; import { decrypt, encrypt } from "#utils/data"; diff --git a/src/tutorial.ts b/src/tutorial.ts index 5ab0be116f8..018d0927da0 100644 --- a/src/tutorial.ts +++ b/src/tutorial.ts @@ -1,8 +1,8 @@ import { globalScene } from "#app/global-scene"; import Overrides from "#app/overrides"; import { UiMode } from "#enums/ui-mode"; -import { AwaitableUiHandler } from "#ui/handlers/awaitable-ui-handler"; -import type { UiHandler } from "#ui/handlers/ui-handler"; +import { AwaitableUiHandler } from "#ui/awaitable-ui-handler"; +import type { UiHandler } from "#ui/ui-handler"; import i18next from "i18next"; export enum Tutorial { diff --git a/src/ui-inputs.ts b/src/ui-inputs.ts index 5c4a530b39a..fd7883d3136 100644 --- a/src/ui-inputs.ts +++ b/src/ui-inputs.ts @@ -3,16 +3,16 @@ import type { InputsController } from "#app/inputs-controller"; import { Button } from "#enums/buttons"; import { UiMode } from "#enums/ui-mode"; import { Setting, SettingKeys, settingIndex } from "#system/settings"; -import type { MessageUiHandler } from "#ui/handlers/message-ui-handler"; -import { PokedexPageUiHandler } from "#ui/handlers/pokedex-page-ui-handler"; -import { PokedexUiHandler } from "#ui/handlers/pokedex-ui-handler"; -import { RunInfoUiHandler } from "#ui/handlers/run-info-ui-handler"; -import { StarterSelectUiHandler } from "#ui/handlers/starter-select-ui-handler"; +import type { MessageUiHandler } from "#ui/message-ui-handler"; +import { PokedexPageUiHandler } from "#ui/pokedex-page-ui-handler"; +import { PokedexUiHandler } from "#ui/pokedex-ui-handler"; +import { RunInfoUiHandler } from "#ui/run-info-ui-handler"; import { SettingsAudioUiHandler } from "#ui/settings-audio-ui-handler"; import { SettingsDisplayUiHandler } from "#ui/settings-display-ui-handler"; import { SettingsGamepadUiHandler } from "#ui/settings-gamepad-ui-handler"; import { SettingsKeyboardUiHandler } from "#ui/settings-keyboard-ui-handler"; import { SettingsUiHandler } from "#ui/settings-ui-handler"; +import { StarterSelectUiHandler } from "#ui/starter-select-ui-handler"; import Phaser from "phaser"; type ActionKeys = Record void>; diff --git a/src/ui/battle-info/enemy-battle-info.ts b/src/ui/battle-info/enemy-battle-info.ts index ad72afedc38..1a16a1dd934 100644 --- a/src/ui/battle-info/enemy-battle-info.ts +++ b/src/ui/battle-info/enemy-battle-info.ts @@ -3,9 +3,9 @@ import { Stat } from "#enums/stat"; import { TextStyle } from "#enums/text-style"; import { UiTheme } from "#enums/ui-theme"; 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 { BattleFlyout } from "#ui/containers/battle-flyout"; import { addTextObject } from "#ui/text"; import { addWindow, WindowVariant } from "#ui/ui-theme"; import { getLocalizedSpriteKey } from "#utils/common"; diff --git a/src/ui/containers/arena-flyout.ts b/src/ui/containers/arena-flyout.ts index 3555694760d..a73846de1ac 100644 --- a/src/ui/containers/arena-flyout.ts +++ b/src/ui/containers/arena-flyout.ts @@ -15,8 +15,8 @@ import { } from "#events/arena"; import type { TurnEndEvent } from "#events/battle-scene"; import { BattleSceneEventType } from "#events/battle-scene"; -import { TimeOfDayWidget } from "#ui/containers/time-of-day-widget"; import { addTextObject } from "#ui/text"; +import { TimeOfDayWidget } from "#ui/time-of-day-widget"; import { addWindow, WindowVariant } from "#ui/ui-theme"; import { fixedInt } from "#utils/common"; import { toCamelCase, toTitleCase } from "#utils/strings"; diff --git a/src/ui/containers/dropdown.ts b/src/ui/containers/dropdown.ts index bf589085d2e..2244aa0e5ce 100644 --- a/src/ui/containers/dropdown.ts +++ b/src/ui/containers/dropdown.ts @@ -1,6 +1,6 @@ import { globalScene } from "#app/global-scene"; import { TextStyle } from "#enums/text-style"; -import { ScrollBar } from "#ui/containers/scroll-bar"; +import { ScrollBar } from "#ui/scroll-bar"; import { addTextObject } from "#ui/text"; import { addWindow, WindowVariant } from "#ui/ui-theme"; import i18next from "i18next"; diff --git a/src/ui/containers/egg-counter-container.ts b/src/ui/containers/egg-counter-container.ts index d080dd66a68..385480fc91d 100644 --- a/src/ui/containers/egg-counter-container.ts +++ b/src/ui/containers/egg-counter-container.ts @@ -2,7 +2,7 @@ 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 { EggHatchSceneUiHandler } from "#ui/handlers/egg-hatch-scene-ui-handler"; +import type { EggHatchSceneUiHandler } from "#ui/egg-hatch-scene-ui-handler"; import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; diff --git a/src/ui/containers/filter-bar.ts b/src/ui/containers/filter-bar.ts index bbca38c3f53..3f164c4fcbb 100644 --- a/src/ui/containers/filter-bar.ts +++ b/src/ui/containers/filter-bar.ts @@ -2,9 +2,9 @@ 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/containers/dropdown"; -import { DropDownType } from "#ui/containers/dropdown"; -import type { StarterContainer } from "#ui/containers/starter-container"; +import type { DropDown } from "#ui/dropdown"; +import { DropDownType } from "#ui/dropdown"; +import type { StarterContainer } from "#ui/starter-container"; import { addTextObject, getTextColor } from "#ui/text"; import { addWindow, WindowVariant } from "#ui/ui-theme"; diff --git a/src/ui/containers/filter-text.ts b/src/ui/containers/filter-text.ts index 0d15aca8530..8601a86defa 100644 --- a/src/ui/containers/filter-text.ts +++ b/src/ui/containers/filter-text.ts @@ -2,8 +2,8 @@ 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 { StarterContainer } from "#ui/containers/starter-container"; -import type { AwaitableUiHandler } from "#ui/handlers/awaitable-ui-handler"; +import type { AwaitableUiHandler } from "#ui/awaitable-ui-handler"; +import type { StarterContainer } from "#ui/starter-container"; import { addTextObject, getTextColor } from "#ui/text"; import type { UI } from "#ui/ui"; import { addWindow, WindowVariant } from "#ui/ui-theme"; diff --git a/src/ui/containers/hatched-pokemon-container.ts b/src/ui/containers/hatched-pokemon-container.ts index 456ffd923a1..b1bc66c21ec 100644 --- a/src/ui/containers/hatched-pokemon-container.ts +++ b/src/ui/containers/hatched-pokemon-container.ts @@ -4,8 +4,8 @@ import { Gender } from "#data/gender"; import type { PokemonSpecies } from "#data/pokemon-species"; import { DexAttr } from "#enums/dex-attr"; import { getVariantTint } from "#sprites/variant"; -import type { PokemonIconAnimHelper } from "#ui/utils/pokemon-icon-anim-helper"; -import { PokemonIconAnimMode } from "#ui/utils/pokemon-icon-anim-helper"; +import type { PokemonIconAnimHelper } from "#ui/pokemon-icon-anim-helper"; +import { PokemonIconAnimMode } from "#ui/pokemon-icon-anim-helper"; /** * A container for a Pokemon's sprite and icons to get displayed in the egg summary screen diff --git a/src/ui/containers/pokemon-info-container.ts b/src/ui/containers/pokemon-info-container.ts index 6072b610430..3b6e5bc2fc1 100644 --- a/src/ui/containers/pokemon-info-container.ts +++ b/src/ui/containers/pokemon-info-container.ts @@ -8,7 +8,7 @@ import type { Pokemon } from "#field/pokemon"; import { getVariantTint } from "#sprites/variant"; import type { DexEntry } from "#types/dex-data"; import type { StarterDataEntry } from "#types/save-data"; -import { ConfirmUiHandler } from "#ui/handlers/confirm-ui-handler"; +import { ConfirmUiHandler } from "#ui/confirm-ui-handler"; import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { fixedInt, getShinyDescriptor } from "#utils/common"; diff --git a/src/ui/handlers/abstract-binding-ui-handler.ts b/src/ui/handlers/abstract-binding-ui-handler.ts index d106ff6f914..6b747a10d2b 100644 --- a/src/ui/handlers/abstract-binding-ui-handler.ts +++ b/src/ui/handlers/abstract-binding-ui-handler.ts @@ -2,9 +2,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 { UiHandler } from "#ui/handlers/ui-handler"; import { NavigationManager } from "#ui/navigation-menu"; import { addTextObject, getTextColor } from "#ui/text"; +import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; import i18next from "i18next"; diff --git a/src/ui/handlers/abstract-option-select-ui-handler.ts b/src/ui/handlers/abstract-option-select-ui-handler.ts index 1e102010e4a..b86d5c33a0d 100644 --- a/src/ui/handlers/abstract-option-select-ui-handler.ts +++ b/src/ui/handlers/abstract-option-select-ui-handler.ts @@ -2,8 +2,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 { UiHandler } from "#ui/handlers/ui-handler"; 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"; import { argbFromRgba } from "@material/material-color-utilities"; diff --git a/src/ui/handlers/achvs-ui-handler.ts b/src/ui/handlers/achvs-ui-handler.ts index d7cf82e78ad..dea1829499e 100644 --- a/src/ui/handlers/achvs-ui-handler.ts +++ b/src/ui/handlers/achvs-ui-handler.ts @@ -8,8 +8,8 @@ import { achvs, getAchievementDescription } from "#system/achv"; import type { Voucher } from "#system/voucher"; import { getVoucherTypeIcon, getVoucherTypeName, vouchers } from "#system/voucher"; import type { AchvUnlocks, VoucherUnlocks } from "#types/save-data"; -import { ScrollBar } from "#ui/containers/scroll-bar"; -import { MessageUiHandler } from "#ui/handlers/message-ui-handler"; +import { MessageUiHandler } from "#ui/message-ui-handler"; +import { ScrollBar } from "#ui/scroll-bar"; import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import i18next from "i18next"; diff --git a/src/ui/handlers/admin-ui-handler.ts b/src/ui/handlers/admin-ui-handler.ts index 9ca30e35313..38420c61010 100644 --- a/src/ui/handlers/admin-ui-handler.ts +++ b/src/ui/handlers/admin-ui-handler.ts @@ -3,9 +3,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 { InputFieldConfig } from "#ui/handlers/form-modal-ui-handler"; -import { FormModalUiHandler } from "#ui/handlers/form-modal-ui-handler"; -import type { ModalConfig } from "#ui/handlers/modal-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 { getTextColor } from "#ui/text"; import { toTitleCase } from "#utils/strings"; diff --git a/src/ui/handlers/autocomplete-ui-handler.ts b/src/ui/handlers/autocomplete-ui-handler.ts index 914fe23a123..337b17048dc 100644 --- a/src/ui/handlers/autocomplete-ui-handler.ts +++ b/src/ui/handlers/autocomplete-ui-handler.ts @@ -1,6 +1,6 @@ import { Button } from "#enums/buttons"; import { UiMode } from "#enums/ui-mode"; -import { AbstractOptionSelectUiHandler } from "#ui/handlers/abstract-option-select-ui-handler"; +import { AbstractOptionSelectUiHandler } from "#ui/abstract-option-select-ui-handler"; export class AutoCompleteUiHandler extends AbstractOptionSelectUiHandler { modalContainer: Phaser.GameObjects.Container; diff --git a/src/ui/handlers/awaitable-ui-handler.ts b/src/ui/handlers/awaitable-ui-handler.ts index 9dcd3377da2..e8513b4acc1 100644 --- a/src/ui/handlers/awaitable-ui-handler.ts +++ b/src/ui/handlers/awaitable-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 { UiHandler } from "#ui/handlers/ui-handler"; +import { UiHandler } from "#ui/ui-handler"; export abstract class AwaitableUiHandler extends UiHandler { protected awaitingActionInput: boolean; diff --git a/src/ui/handlers/ball-ui-handler.ts b/src/ui/handlers/ball-ui-handler.ts index 3d1868c207e..3d8efca96b8 100644 --- a/src/ui/handlers/ball-ui-handler.ts +++ b/src/ui/handlers/ball-ui-handler.ts @@ -5,8 +5,8 @@ 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 { UiHandler } from "#ui/handlers/ui-handler"; 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/handlers/battle-message-ui-handler.ts b/src/ui/handlers/battle-message-ui-handler.ts index 6912109c7e7..f845f22a730 100644 --- a/src/ui/handlers/battle-message-ui-handler.ts +++ b/src/ui/handlers/battle-message-ui-handler.ts @@ -3,7 +3,7 @@ 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/handlers/message-ui-handler"; +import { MessageUiHandler } from "#ui/message-ui-handler"; import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import i18next from "i18next"; diff --git a/src/ui/handlers/challenges-select-ui-handler.ts b/src/ui/handlers/challenges-select-ui-handler.ts index 5cc91285a74..62f9d578667 100644 --- a/src/ui/handlers/challenges-select-ui-handler.ts +++ b/src/ui/handlers/challenges-select-ui-handler.ts @@ -5,8 +5,8 @@ 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 { UiHandler } from "#ui/handlers/ui-handler"; import { addTextObject } from "#ui/text"; +import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; import { getLocalizedSpriteKey } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/handlers/change-password-form-ui-handler.ts b/src/ui/handlers/change-password-form-ui-handler.ts index f4fdf349978..eccc67ffb04 100644 --- a/src/ui/handlers/change-password-form-ui-handler.ts +++ b/src/ui/handlers/change-password-form-ui-handler.ts @@ -1,9 +1,9 @@ import { globalScene } from "#app/global-scene"; import { pokerogueApi } from "#app/plugins/api/pokerogue-api"; import { UiMode } from "#enums/ui-mode"; -import type { InputFieldConfig } from "#ui/handlers/form-modal-ui-handler"; -import { FormModalUiHandler } from "#ui/handlers/form-modal-ui-handler"; -import type { ModalConfig } from "#ui/handlers/modal-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 i18next from "i18next"; export class ChangePasswordFormUiHandler extends FormModalUiHandler { diff --git a/src/ui/handlers/command-ui-handler.ts b/src/ui/handlers/command-ui-handler.ts index de5e51a4210..693fe0eefef 100644 --- a/src/ui/handlers/command-ui-handler.ts +++ b/src/ui/handlers/command-ui-handler.ts @@ -9,9 +9,9 @@ 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/handlers/party-ui-handler"; -import { UiHandler } from "#ui/handlers/ui-handler"; +import { PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler"; import { addTextObject } from "#ui/text"; +import { UiHandler } from "#ui/ui-handler"; import i18next from "i18next"; export class CommandUiHandler extends UiHandler { diff --git a/src/ui/handlers/confirm-ui-handler.ts b/src/ui/handlers/confirm-ui-handler.ts index 77f1f182514..64a0bb7028a 100644 --- a/src/ui/handlers/confirm-ui-handler.ts +++ b/src/ui/handlers/confirm-ui-handler.ts @@ -1,8 +1,8 @@ import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; import { UiMode } from "#enums/ui-mode"; -import type { OptionSelectConfig } from "#ui/handlers/abstract-option-select-ui-handler"; -import { AbstractOptionSelectUiHandler } from "#ui/handlers/abstract-option-select-ui-handler"; +import type { OptionSelectConfig } from "#ui/abstract-option-select-ui-handler"; +import { AbstractOptionSelectUiHandler } from "#ui/abstract-option-select-ui-handler"; import i18next from "i18next"; export class ConfirmUiHandler extends AbstractOptionSelectUiHandler { diff --git a/src/ui/handlers/egg-gacha-ui-handler.ts b/src/ui/handlers/egg-gacha-ui-handler.ts index 30afd2bf3db..f24c8c04fdb 100644 --- a/src/ui/handlers/egg-gacha-ui-handler.ts +++ b/src/ui/handlers/egg-gacha-ui-handler.ts @@ -9,7 +9,7 @@ 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/handlers/message-ui-handler"; +import { MessageUiHandler } from "#ui/message-ui-handler"; import { addTextObject, getEggTierTextTint, getTextStyleOptions } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { fixedInt, randSeedShuffle } from "#utils/common"; diff --git a/src/ui/handlers/egg-hatch-scene-ui-handler.ts b/src/ui/handlers/egg-hatch-scene-ui-handler.ts index 2fff9980de3..d0827532e14 100644 --- a/src/ui/handlers/egg-hatch-scene-ui-handler.ts +++ b/src/ui/handlers/egg-hatch-scene-ui-handler.ts @@ -1,7 +1,7 @@ import { globalScene } from "#app/global-scene"; import { Button } from "#enums/buttons"; import { UiMode } from "#enums/ui-mode"; -import { UiHandler } from "#ui/handlers/ui-handler"; +import { UiHandler } from "#ui/ui-handler"; export class EggHatchSceneUiHandler extends UiHandler { public eggHatchContainer: Phaser.GameObjects.Container; diff --git a/src/ui/handlers/egg-list-ui-handler.ts b/src/ui/handlers/egg-list-ui-handler.ts index e4d1d5b10e9..3ec509261bb 100644 --- a/src/ui/handlers/egg-list-ui-handler.ts +++ b/src/ui/handlers/egg-list-ui-handler.ts @@ -2,12 +2,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 { ScrollBar } from "#ui/containers/scroll-bar"; -import { MessageUiHandler } from "#ui/handlers/message-ui-handler"; +import { MessageUiHandler } from "#ui/message-ui-handler"; +import { PokemonIconAnimHelper, PokemonIconAnimMode } from "#ui/pokemon-icon-anim-helper"; +import { ScrollBar } from "#ui/scroll-bar"; +import { ScrollableGridHelper } from "#ui/scrollable-grid-helper"; import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; -import { PokemonIconAnimHelper, PokemonIconAnimMode } from "#ui/utils/pokemon-icon-anim-helper"; -import { ScrollableGridHelper } from "#ui/utils/scrollable-grid-helper"; import i18next from "i18next"; export class EggListUiHandler extends MessageUiHandler { diff --git a/src/ui/handlers/egg-summary-ui-handler.ts b/src/ui/handlers/egg-summary-ui-handler.ts index 1097615d83d..35dc9c5176f 100644 --- a/src/ui/handlers/egg-summary-ui-handler.ts +++ b/src/ui/handlers/egg-summary-ui-handler.ts @@ -3,12 +3,12 @@ import { getEggTierForSpecies } from "#data/egg"; import type { EggHatchData } from "#data/egg-hatch-data"; import { Button } from "#enums/buttons"; import { UiMode } from "#enums/ui-mode"; -import { HatchedPokemonContainer } from "#ui/containers/hatched-pokemon-container"; -import { PokemonHatchInfoContainer } from "#ui/containers/pokemon-hatch-info-container"; -import { ScrollBar } from "#ui/containers/scroll-bar"; -import { MessageUiHandler } from "#ui/handlers/message-ui-handler"; -import { PokemonIconAnimHelper, PokemonIconAnimMode } from "#ui/utils/pokemon-icon-anim-helper"; -import { ScrollableGridHelper } from "#ui/utils/scrollable-grid-helper"; +import { HatchedPokemonContainer } from "#ui/hatched-pokemon-container"; +import { MessageUiHandler } from "#ui/message-ui-handler"; +import { PokemonHatchInfoContainer } from "#ui/pokemon-hatch-info-container"; +import { PokemonIconAnimHelper, PokemonIconAnimMode } from "#ui/pokemon-icon-anim-helper"; +import { ScrollBar } from "#ui/scroll-bar"; +import { ScrollableGridHelper } from "#ui/scrollable-grid-helper"; const iconContainerX = 112; const iconContainerY = 9; diff --git a/src/ui/handlers/evolution-scene-ui-handler.ts b/src/ui/handlers/evolution-scene-ui-handler.ts index a1783544a07..ba3d8f8f57f 100644 --- a/src/ui/handlers/evolution-scene-ui-handler.ts +++ b/src/ui/handlers/evolution-scene-ui-handler.ts @@ -2,7 +2,7 @@ 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/handlers/message-ui-handler"; +import { MessageUiHandler } from "#ui/message-ui-handler"; import { addTextObject } from "#ui/text"; export class EvolutionSceneUiHandler extends MessageUiHandler { diff --git a/src/ui/handlers/fight-ui-handler.ts b/src/ui/handlers/fight-ui-handler.ts index 9dd00a90b66..72b6949eb9c 100644 --- a/src/ui/handlers/fight-ui-handler.ts +++ b/src/ui/handlers/fight-ui-handler.ts @@ -12,9 +12,9 @@ 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/containers/move-info-overlay"; -import { UiHandler } from "#ui/handlers/ui-handler"; +import { MoveInfoOverlay } from "#ui/move-info-overlay"; import { addTextObject, getTextColor } from "#ui/text"; +import { UiHandler } from "#ui/ui-handler"; import { fixedInt, getLocalizedSpriteKey, padInt } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/handlers/form-modal-ui-handler.ts b/src/ui/handlers/form-modal-ui-handler.ts index af1d8653df7..2efd39ca359 100644 --- a/src/ui/handlers/form-modal-ui-handler.ts +++ b/src/ui/handlers/form-modal-ui-handler.ts @@ -2,8 +2,8 @@ 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/handlers/modal-ui-handler"; -import { ModalUiHandler } from "#ui/handlers/modal-ui-handler"; +import type { ModalConfig } from "#ui/modal-ui-handler"; +import { ModalUiHandler } from "#ui/modal-ui-handler"; import { addTextInputObject, addTextObject, getTextColor } from "#ui/text"; import { addWindow, WindowVariant } from "#ui/ui-theme"; import { fixedInt } from "#utils/common"; diff --git a/src/ui/handlers/game-stats-ui-handler.ts b/src/ui/handlers/game-stats-ui-handler.ts index e34c0af59e6..24ff842a902 100644 --- a/src/ui/handlers/game-stats-ui-handler.ts +++ b/src/ui/handlers/game-stats-ui-handler.ts @@ -7,8 +7,8 @@ import { PlayerGender } from "#enums/player-gender"; import { TextStyle } from "#enums/text-style"; import { UiTheme } from "#enums/ui-theme"; import type { GameData } from "#system/game-data"; -import { UiHandler } from "#ui/handlers/ui-handler"; import { addTextObject } from "#ui/text"; +import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; import { formatFancyLargeNumber, getPlayTimeString } from "#utils/common"; import { toTitleCase } from "#utils/strings"; diff --git a/src/ui/handlers/loading-modal-ui-handler.ts b/src/ui/handlers/loading-modal-ui-handler.ts index 9b401e17f91..de00d911c47 100644 --- a/src/ui/handlers/loading-modal-ui-handler.ts +++ b/src/ui/handlers/loading-modal-ui-handler.ts @@ -1,6 +1,6 @@ import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; -import { ModalUiHandler } from "#ui/handlers/modal-ui-handler"; +import { ModalUiHandler } from "#ui/modal-ui-handler"; import { addTextObject } from "#ui/text"; import i18next from "i18next"; diff --git a/src/ui/handlers/login-form-ui-handler.ts b/src/ui/handlers/login-form-ui-handler.ts index 0634ae36ba8..44c5b93131f 100644 --- a/src/ui/handlers/login-form-ui-handler.ts +++ b/src/ui/handlers/login-form-ui-handler.ts @@ -3,10 +3,10 @@ import { globalScene } from "#app/global-scene"; import { TextStyle } from "#enums/text-style"; import { UiMode } from "#enums/ui-mode"; import { languageOptions } from "#system/settings-language"; -import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; -import type { InputFieldConfig } from "#ui/handlers/form-modal-ui-handler"; -import { FormModalUiHandler } from "#ui/handlers/form-modal-ui-handler"; -import type { ModalConfig } from "#ui/handlers/modal-ui-handler"; +import type { OptionSelectItem } from "#ui/abstract-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 } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { fixedInt } from "#utils/common"; diff --git a/src/ui/handlers/menu-ui-handler.ts b/src/ui/handlers/menu-ui-handler.ts index df1908bae39..419f2489818 100644 --- a/src/ui/handlers/menu-ui-handler.ts +++ b/src/ui/handlers/menu-ui-handler.ts @@ -7,10 +7,10 @@ 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 { BgmBar } from "#ui/containers/bgm-bar"; -import type { OptionSelectConfig, OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; -import type { AwaitableUiHandler } from "#ui/handlers/awaitable-ui-handler"; -import { MessageUiHandler } from "#ui/handlers/message-ui-handler"; +import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstract-option-select-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 } from "#ui/text"; import { addWindow, WindowVariant } from "#ui/ui-theme"; import { fixedInt, isLocal, sessionIdKey } from "#utils/common"; diff --git a/src/ui/handlers/message-ui-handler.ts b/src/ui/handlers/message-ui-handler.ts index b8e3f983cca..1deaca78493 100644 --- a/src/ui/handlers/message-ui-handler.ts +++ b/src/ui/handlers/message-ui-handler.ts @@ -1,6 +1,6 @@ import { globalScene } from "#app/global-scene"; import type { UiMode } from "#enums/ui-mode"; -import { AwaitableUiHandler } from "#ui/handlers/awaitable-ui-handler"; +import { AwaitableUiHandler } from "#ui/awaitable-ui-handler"; import { getFrameMs } from "#utils/common"; export abstract class MessageUiHandler extends AwaitableUiHandler { diff --git a/src/ui/handlers/modal-ui-handler.ts b/src/ui/handlers/modal-ui-handler.ts index e6eecece9a2..c145363b244 100644 --- a/src/ui/handlers/modal-ui-handler.ts +++ b/src/ui/handlers/modal-ui-handler.ts @@ -2,8 +2,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 { UiHandler } from "#ui/handlers/ui-handler"; import { addTextObject } from "#ui/text"; +import { UiHandler } from "#ui/ui-handler"; import { addWindow, WindowVariant } from "#ui/ui-theme"; export interface ModalConfig { diff --git a/src/ui/handlers/modifier-select-ui-handler.ts b/src/ui/handlers/modifier-select-ui-handler.ts index a721bf9e7db..95bc30fb97c 100644 --- a/src/ui/handlers/modifier-select-ui-handler.ts +++ b/src/ui/handlers/modifier-select-ui-handler.ts @@ -11,8 +11,8 @@ 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 { MoveInfoOverlay } from "#ui/containers/move-info-overlay"; -import { AwaitableUiHandler } from "#ui/handlers/awaitable-ui-handler"; +import { AwaitableUiHandler } from "#ui/awaitable-ui-handler"; +import { MoveInfoOverlay } from "#ui/move-info-overlay"; import { addTextObject, getModifierTierTextTint, getTextColor, getTextStyleOptions } from "#ui/text"; import { formatMoney, NumberHolder } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/handlers/mystery-encounter-ui-handler.ts b/src/ui/handlers/mystery-encounter-ui-handler.ts index 9bc6f0681ee..bbbd3cb4af8 100644 --- a/src/ui/handlers/mystery-encounter-ui-handler.ts +++ b/src/ui/handlers/mystery-encounter-ui-handler.ts @@ -9,9 +9,9 @@ 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/handlers/party-ui-handler"; -import { UiHandler } from "#ui/handlers/ui-handler"; +import { PartyUiMode } from "#ui/party-ui-handler"; 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"; import i18next from "i18next"; diff --git a/src/ui/handlers/party-ui-handler.ts b/src/ui/handlers/party-ui-handler.ts index cc2bb093b07..d4014cc0288 100644 --- a/src/ui/handlers/party-ui-handler.ts +++ b/src/ui/handlers/party-ui-handler.ts @@ -21,11 +21,11 @@ import type { PokemonMove } from "#moves/pokemon-move"; import type { CommandPhase } from "#phases/command-phase"; import { getVariantTint } from "#sprites/variant"; import type { TurnMove } from "#types/turn-move"; -import { MoveInfoOverlay } from "#ui/containers/move-info-overlay"; -import { MessageUiHandler } from "#ui/handlers/message-ui-handler"; +import { MessageUiHandler } from "#ui/message-ui-handler"; +import { MoveInfoOverlay } from "#ui/move-info-overlay"; +import { PokemonIconAnimHelper, PokemonIconAnimMode } from "#ui/pokemon-icon-anim-helper"; import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; -import { PokemonIconAnimHelper, PokemonIconAnimMode } from "#ui/utils/pokemon-icon-anim-helper"; import { applyChallenges } from "#utils/challenge-utils"; import { BooleanHolder, getLocalizedSpriteKey, randInt } from "#utils/common"; import { toCamelCase, toTitleCase } from "#utils/strings"; diff --git a/src/ui/handlers/pokedex-page-ui-handler.ts b/src/ui/handlers/pokedex-page-ui-handler.ts index 659c3488bc1..253309bf94a 100644 --- a/src/ui/handlers/pokedex-page-ui-handler.ts +++ b/src/ui/handlers/pokedex-page-ui-handler.ts @@ -46,12 +46,12 @@ import { getVariantIcon, getVariantTint } from "#sprites/variant"; import { SettingKeyboard } from "#system/settings-keyboard"; import type { DexEntry } from "#types/dex-data"; import type { StarterAttributes } from "#types/save-data"; -import { BaseStatsOverlay } from "#ui/containers/base-stats-overlay"; -import { MoveInfoOverlay } from "#ui/containers/move-info-overlay"; -import { PokedexInfoOverlay } from "#ui/containers/pokedex-info-overlay"; -import { StatsContainer } from "#ui/containers/stats-container"; -import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; -import { MessageUiHandler } from "#ui/handlers/message-ui-handler"; +import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; +import { BaseStatsOverlay } from "#ui/base-stats-overlay"; +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 } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { BooleanHolder, getLocalizedSpriteKey, isNullOrUndefined, padInt, rgbHexToRgba } from "#utils/common"; diff --git a/src/ui/handlers/pokedex-scan-ui-handler.ts b/src/ui/handlers/pokedex-scan-ui-handler.ts index bb3cec5bb56..1f5195588f3 100644 --- a/src/ui/handlers/pokedex-scan-ui-handler.ts +++ b/src/ui/handlers/pokedex-scan-ui-handler.ts @@ -1,11 +1,11 @@ import { allAbilities, allMoves, allSpecies } from "#data/data-lists"; import { UiMode } from "#enums/ui-mode"; import type { PlayerPokemon } from "#field/pokemon"; -import { FilterTextRow } from "#ui/containers/filter-text"; -import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; -import type { InputFieldConfig } from "#ui/handlers/form-modal-ui-handler"; -import { FormModalUiHandler } from "#ui/handlers/form-modal-ui-handler"; -import type { ModalConfig } from "#ui/handlers/modal-ui-handler"; +import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; +import { FilterTextRow } from "#ui/filter-text"; +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 { isNullOrUndefined } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/handlers/pokedex-ui-handler.ts b/src/ui/handlers/pokedex-ui-handler.ts index 3e37ccba563..c6f9dbee448 100644 --- a/src/ui/handlers/pokedex-ui-handler.ts +++ b/src/ui/handlers/pokedex-ui-handler.ts @@ -34,23 +34,16 @@ import { getVariantIcon, getVariantTint } from "#sprites/variant"; import { SettingKeyboard } from "#system/settings-keyboard"; import type { DexEntry } from "#types/dex-data"; import type { DexAttrProps, StarterAttributes } from "#types/save-data"; -import { - DropDown, - DropDownLabel, - DropDownOption, - DropDownState, - DropDownType, - SortCriteria, -} from "#ui/containers/dropdown"; -import { FilterBar } from "#ui/containers/filter-bar"; -import { FilterText, FilterTextRow } from "#ui/containers/filter-text"; -import { PokedexMonContainer } from "#ui/containers/pokedex-mon-container"; -import { ScrollBar } from "#ui/containers/scroll-bar"; -import type { OptionSelectConfig } from "#ui/handlers/abstract-option-select-ui-handler"; -import { MessageUiHandler } from "#ui/handlers/message-ui-handler"; +import type { OptionSelectConfig } from "#ui/abstract-option-select-ui-handler"; +import { DropDown, DropDownLabel, DropDownOption, DropDownState, DropDownType, SortCriteria } from "#ui/dropdown"; +import { FilterBar } from "#ui/filter-bar"; +import { FilterText, FilterTextRow } from "#ui/filter-text"; +import { MessageUiHandler } from "#ui/message-ui-handler"; +import { PokedexMonContainer } from "#ui/pokedex-mon-container"; +import { PokemonIconAnimHelper, PokemonIconAnimMode } from "#ui/pokemon-icon-anim-helper"; +import { ScrollBar } from "#ui/scroll-bar"; import { addTextObject, getTextColor } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; -import { PokemonIconAnimHelper, PokemonIconAnimMode } from "#ui/utils/pokemon-icon-anim-helper"; import { BooleanHolder, fixedInt, getLocalizedSpriteKey, padInt, randIntRange, rgbHexToRgba } from "#utils/common"; import type { StarterPreferences } from "#utils/data"; import { loadStarterPreferences } from "#utils/data"; diff --git a/src/ui/handlers/registration-form-ui-handler.ts b/src/ui/handlers/registration-form-ui-handler.ts index d424e44b455..2c8080d534d 100644 --- a/src/ui/handlers/registration-form-ui-handler.ts +++ b/src/ui/handlers/registration-form-ui-handler.ts @@ -2,9 +2,9 @@ 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/handlers/form-modal-ui-handler"; -import { FormModalUiHandler } from "#ui/handlers/form-modal-ui-handler"; -import type { ModalConfig } from "#ui/handlers/modal-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 } from "#ui/text"; import i18next from "i18next"; diff --git a/src/ui/handlers/rename-form-ui-handler.ts b/src/ui/handlers/rename-form-ui-handler.ts index f1d9ae3c981..9da5b0e8554 100644 --- a/src/ui/handlers/rename-form-ui-handler.ts +++ b/src/ui/handlers/rename-form-ui-handler.ts @@ -1,7 +1,7 @@ import type { PlayerPokemon } from "#field/pokemon"; -import type { InputFieldConfig } from "#ui/handlers/form-modal-ui-handler"; -import { FormModalUiHandler } from "#ui/handlers/form-modal-ui-handler"; -import type { ModalConfig } from "#ui/handlers/modal-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 i18next from "i18next"; export class RenameFormUiHandler extends FormModalUiHandler { diff --git a/src/ui/handlers/run-history-ui-handler.ts b/src/ui/handlers/run-history-ui-handler.ts index baf1577a2b4..4dd73d4826b 100644 --- a/src/ui/handlers/run-history-ui-handler.ts +++ b/src/ui/handlers/run-history-ui-handler.ts @@ -8,8 +8,8 @@ import { TrainerVariant } from "#enums/trainer-variant"; import { UiMode } from "#enums/ui-mode"; import type { PokemonData } from "#system/pokemon-data"; import type { RunEntry } from "#types/save-data"; -import { MessageUiHandler } from "#ui/handlers/message-ui-handler"; -import { RunDisplayMode } from "#ui/handlers/run-info-ui-handler"; +import { MessageUiHandler } from "#ui/message-ui-handler"; +import { RunDisplayMode } from "#ui/run-info-ui-handler"; import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { fixedInt, formatLargeNumber } from "#utils/common"; diff --git a/src/ui/handlers/run-info-ui-handler.ts b/src/ui/handlers/run-info-ui-handler.ts index 93ace112148..556884194b1 100644 --- a/src/ui/handlers/run-info-ui-handler.ts +++ b/src/ui/handlers/run-info-ui-handler.ts @@ -22,8 +22,8 @@ import { getVariantTint } from "#sprites/variant"; import type { PokemonData } from "#system/pokemon-data"; import { SettingKeyboard } from "#system/settings-keyboard"; import type { SessionSaveData } from "#types/save-data"; -import { UiHandler } from "#ui/handlers/ui-handler"; 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"; import { toCamelCase } from "#utils/strings"; diff --git a/src/ui/handlers/save-slot-select-ui-handler.ts b/src/ui/handlers/save-slot-select-ui-handler.ts index 5115ab23578..a71be5dd070 100644 --- a/src/ui/handlers/save-slot-select-ui-handler.ts +++ b/src/ui/handlers/save-slot-select-ui-handler.ts @@ -8,9 +8,9 @@ import { UiMode } from "#enums/ui-mode"; import * as Modifier from "#modifiers/modifier"; import type { PokemonData } from "#system/pokemon-data"; import type { SessionSaveData } from "#types/save-data"; -import type { OptionSelectConfig } from "#ui/handlers/abstract-option-select-ui-handler"; -import { MessageUiHandler } from "#ui/handlers/message-ui-handler"; -import { RunDisplayMode } from "#ui/handlers/run-info-ui-handler"; +import type { OptionSelectConfig } from "#ui/abstract-option-select-ui-handler"; +import { MessageUiHandler } from "#ui/message-ui-handler"; +import { RunDisplayMode } from "#ui/run-info-ui-handler"; import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; import { fixedInt, formatLargeNumber, getPlayTimeString, isNullOrUndefined } from "#utils/common"; diff --git a/src/ui/handlers/session-reload-modal-ui-handler.ts b/src/ui/handlers/session-reload-modal-ui-handler.ts index 33c18b1974a..1f5a205f990 100644 --- a/src/ui/handlers/session-reload-modal-ui-handler.ts +++ b/src/ui/handlers/session-reload-modal-ui-handler.ts @@ -1,7 +1,7 @@ import { TextStyle } from "#enums/text-style"; import type { UiMode } from "#enums/ui-mode"; -import type { ModalConfig } from "#ui/handlers/modal-ui-handler"; -import { ModalUiHandler } from "#ui/handlers/modal-ui-handler"; +import type { ModalConfig } from "#ui/modal-ui-handler"; +import { ModalUiHandler } from "#ui/modal-ui-handler"; import { addTextObject } from "#ui/text"; export class SessionReloadModalUiHandler extends ModalUiHandler { diff --git a/src/ui/handlers/starter-select-ui-handler.ts b/src/ui/handlers/starter-select-ui-handler.ts index 7c67ed13d4b..18be7e130e3 100644 --- a/src/ui/handlers/starter-select-ui-handler.ts +++ b/src/ui/handlers/starter-select-ui-handler.ts @@ -50,24 +50,17 @@ import { RibbonData } from "#system/ribbons/ribbon-data"; import { SettingKeyboard } from "#system/settings-keyboard"; import type { DexEntry } from "#types/dex-data"; import type { DexAttrProps, StarterAttributes, StarterDataEntry, StarterMoveset } from "#types/save-data"; -import { - DropDown, - DropDownLabel, - DropDownOption, - DropDownState, - DropDownType, - SortCriteria, -} from "#ui/containers/dropdown"; -import { FilterBar } from "#ui/containers/filter-bar"; -import { MoveInfoOverlay } from "#ui/containers/move-info-overlay"; -import { ScrollBar } from "#ui/containers/scroll-bar"; -import { StarterContainer } from "#ui/containers/starter-container"; -import { StatsContainer } from "#ui/containers/stats-container"; -import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; -import { MessageUiHandler } from "#ui/handlers/message-ui-handler"; +import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; +import { DropDown, DropDownLabel, DropDownOption, DropDownState, DropDownType, SortCriteria } from "#ui/dropdown"; +import { FilterBar } from "#ui/filter-bar"; +import { MessageUiHandler } from "#ui/message-ui-handler"; +import { MoveInfoOverlay } from "#ui/move-info-overlay"; +import { PokemonIconAnimHelper, PokemonIconAnimMode } from "#ui/pokemon-icon-anim-helper"; +import { ScrollBar } from "#ui/scroll-bar"; +import { StarterContainer } from "#ui/starter-container"; +import { StatsContainer } from "#ui/stats-container"; import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; -import { PokemonIconAnimHelper, PokemonIconAnimMode } from "#ui/utils/pokemon-icon-anim-helper"; import { applyChallenges, checkStarterValidForChallenge } from "#utils/challenge-utils"; import { BooleanHolder, diff --git a/src/ui/handlers/summary-ui-handler.ts b/src/ui/handlers/summary-ui-handler.ts index e73c5bae431..1c647573cbf 100644 --- a/src/ui/handlers/summary-ui-handler.ts +++ b/src/ui/handlers/summary-ui-handler.ts @@ -25,8 +25,8 @@ import type { PokemonMove } from "#moves/pokemon-move"; import type { Variant } from "#sprites/variant"; import { getVariantTint } from "#sprites/variant"; import { achvs } from "#system/achv"; -import { UiHandler } from "#ui/handlers/ui-handler"; import { addBBCodeTextObject, addTextObject, getBBCodeFrag, getTextColor } from "#ui/text"; +import { UiHandler } from "#ui/ui-handler"; import { fixedInt, formatStat, diff --git a/src/ui/handlers/target-select-ui-handler.ts b/src/ui/handlers/target-select-ui-handler.ts index 777a6734383..4e3096b96f4 100644 --- a/src/ui/handlers/target-select-ui-handler.ts +++ b/src/ui/handlers/target-select-ui-handler.ts @@ -7,7 +7,7 @@ import { UiMode } from "#enums/ui-mode"; import type { Pokemon } from "#field/pokemon"; import type { ModifierBar } from "#modifiers/modifier"; import { getMoveTargets } from "#moves/move-utils"; -import { UiHandler } from "#ui/handlers/ui-handler"; +import { UiHandler } from "#ui/ui-handler"; import { fixedInt, isNullOrUndefined } from "#utils/common"; export type TargetSelectCallback = (targets: BattlerIndex[]) => void; diff --git a/src/ui/handlers/test-dialogue-ui-handler.ts b/src/ui/handlers/test-dialogue-ui-handler.ts index d72de64ef70..bd5c1a1dc37 100644 --- a/src/ui/handlers/test-dialogue-ui-handler.ts +++ b/src/ui/handlers/test-dialogue-ui-handler.ts @@ -1,9 +1,9 @@ import { UiMode } from "#enums/ui-mode"; import type { PlayerPokemon } from "#field/pokemon"; -import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; -import type { InputFieldConfig } from "#ui/handlers/form-modal-ui-handler"; -import { FormModalUiHandler } from "#ui/handlers/form-modal-ui-handler"; -import type { ModalConfig } from "#ui/handlers/modal-ui-handler"; +import type { OptionSelectItem } from "#ui/abstract-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 { isNullOrUndefined } from "#utils/common"; import i18next from "i18next"; diff --git a/src/ui/handlers/unavailable-modal-ui-handler.ts b/src/ui/handlers/unavailable-modal-ui-handler.ts index 5b885bfff77..7ba77dcac23 100644 --- a/src/ui/handlers/unavailable-modal-ui-handler.ts +++ b/src/ui/handlers/unavailable-modal-ui-handler.ts @@ -2,8 +2,8 @@ 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/handlers/modal-ui-handler"; -import { ModalUiHandler } from "#ui/handlers/modal-ui-handler"; +import type { ModalConfig } from "#ui/modal-ui-handler"; +import { ModalUiHandler } from "#ui/modal-ui-handler"; import { addTextObject } from "#ui/text"; import { sessionIdKey } from "#utils/common"; import { removeCookie } from "#utils/cookies"; diff --git a/src/ui/settings/abstract-control-settings-ui-handler.ts b/src/ui/settings/abstract-control-settings-ui-handler.ts index 2d9f3e6a6bd..17812785d1e 100644 --- a/src/ui/settings/abstract-control-settings-ui-handler.ts +++ b/src/ui/settings/abstract-control-settings-ui-handler.ts @@ -5,10 +5,10 @@ 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 { ScrollBar } from "#ui/containers/scroll-bar"; -import { UiHandler } from "#ui/handlers/ui-handler"; import { NavigationManager, NavigationMenu } from "#ui/navigation-menu"; +import { ScrollBar } from "#ui/scroll-bar"; import { addTextObject, getTextColor } from "#ui/text"; +import { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; import { toCamelCase } from "#utils/strings"; 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 876c18eb697..e22c28116f5 100644 --- a/src/ui/settings/abstract-settings-ui-handler.ts +++ b/src/ui/settings/abstract-settings-ui-handler.ts @@ -6,9 +6,9 @@ import type { SettingType } from "#system/settings"; import { Setting, SettingKeys } from "#system/settings"; import type { AnyFn } from "#types/type-helpers"; import type { InputsIcons } from "#ui/abstract-control-settings-ui-handler"; -import { ScrollBar } from "#ui/containers/scroll-bar"; -import { MessageUiHandler } from "#ui/handlers/message-ui-handler"; +import { MessageUiHandler } from "#ui/message-ui-handler"; import { NavigationManager, NavigationMenu } from "#ui/navigation-menu"; +import { ScrollBar } from "#ui/scroll-bar"; import { addTextObject, getTextColor } 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 4fdc4abdbfe..93923aeb57d 100644 --- a/src/ui/settings/gamepad-binding-ui-handler.ts +++ b/src/ui/settings/gamepad-binding-ui-handler.ts @@ -3,7 +3,7 @@ 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/handlers/abstract-binding-ui-handler"; +import { AbstractBindingUiHandler } from "#ui/abstract-binding-ui-handler"; import { addTextObject } 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 b1fd153461f..b339ac16188 100644 --- a/src/ui/settings/keyboard-binding-ui-handler.ts +++ b/src/ui/settings/keyboard-binding-ui-handler.ts @@ -3,7 +3,7 @@ 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/handlers/abstract-binding-ui-handler"; +import { AbstractBindingUiHandler } from "#ui/abstract-binding-ui-handler"; import { addTextObject } from "#ui/text"; import i18next from "i18next"; diff --git a/src/ui/settings/option-select-ui-handler.ts b/src/ui/settings/option-select-ui-handler.ts index 235f16e7f09..c989c768244 100644 --- a/src/ui/settings/option-select-ui-handler.ts +++ b/src/ui/settings/option-select-ui-handler.ts @@ -1,5 +1,5 @@ import { UiMode } from "#enums/ui-mode"; -import { AbstractOptionSelectUiHandler } from "#ui/handlers/abstract-option-select-ui-handler"; +import { AbstractOptionSelectUiHandler } from "#ui/abstract-option-select-ui-handler"; export class OptionSelectUiHandler extends AbstractOptionSelectUiHandler { constructor(mode: UiMode = UiMode.OPTION_SELECT) { diff --git a/src/ui/ui.ts b/src/ui/ui.ts index c7d33f66605..76b07d7bfa5 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -4,59 +4,59 @@ 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/containers/achv-bar"; -import type { BgmBar } from "#ui/containers/bgm-bar"; -import { SavingIconContainer } from "#ui/containers/saving-icon-handler"; +import { AchvBar } from "#ui/achv-bar"; +import { AchvsUiHandler } from "#ui/achvs-ui-handler"; +import { AutoCompleteUiHandler } from "#ui/autocomplete-ui-handler"; +import { AwaitableUiHandler } from "#ui/awaitable-ui-handler"; +import { BallUiHandler } from "#ui/ball-ui-handler"; +import { BattleMessageUiHandler } from "#ui/battle-message-ui-handler"; +import type { BgmBar } from "#ui/bgm-bar"; +import { GameChallengesUiHandler } from "#ui/challenges-select-ui-handler"; +import { ChangePasswordFormUiHandler } from "#ui/change-password-form-ui-handler"; +import { CommandUiHandler } from "#ui/command-ui-handler"; +import { ConfirmUiHandler } from "#ui/confirm-ui-handler"; +import { EggGachaUiHandler } from "#ui/egg-gacha-ui-handler"; +import { EggHatchSceneUiHandler } from "#ui/egg-hatch-scene-ui-handler"; +import { EggListUiHandler } from "#ui/egg-list-ui-handler"; +import { EggSummaryUiHandler } from "#ui/egg-summary-ui-handler"; +import { EvolutionSceneUiHandler } from "#ui/evolution-scene-ui-handler"; +import { FightUiHandler } from "#ui/fight-ui-handler"; +import { GameStatsUiHandler } from "#ui/game-stats-ui-handler"; import { GamepadBindingUiHandler } from "#ui/gamepad-binding-ui-handler"; -import { AchvsUiHandler } from "#ui/handlers/achvs-ui-handler"; -import { AutoCompleteUiHandler } from "#ui/handlers/autocomplete-ui-handler"; -import { AwaitableUiHandler } from "#ui/handlers/awaitable-ui-handler"; -import { BallUiHandler } from "#ui/handlers/ball-ui-handler"; -import { BattleMessageUiHandler } from "#ui/handlers/battle-message-ui-handler"; -import { GameChallengesUiHandler } from "#ui/handlers/challenges-select-ui-handler"; -import { ChangePasswordFormUiHandler } from "#ui/handlers/change-password-form-ui-handler"; -import { CommandUiHandler } from "#ui/handlers/command-ui-handler"; -import { ConfirmUiHandler } from "#ui/handlers/confirm-ui-handler"; -import { EggGachaUiHandler } from "#ui/handlers/egg-gacha-ui-handler"; -import { EggHatchSceneUiHandler } from "#ui/handlers/egg-hatch-scene-ui-handler"; -import { EggListUiHandler } from "#ui/handlers/egg-list-ui-handler"; -import { EggSummaryUiHandler } from "#ui/handlers/egg-summary-ui-handler"; -import { EvolutionSceneUiHandler } from "#ui/handlers/evolution-scene-ui-handler"; -import { FightUiHandler } from "#ui/handlers/fight-ui-handler"; -import { GameStatsUiHandler } from "#ui/handlers/game-stats-ui-handler"; -import { LoadingModalUiHandler } from "#ui/handlers/loading-modal-ui-handler"; -import { LoginFormUiHandler } from "#ui/handlers/login-form-ui-handler"; -import { MenuUiHandler } from "#ui/handlers/menu-ui-handler"; -import { MessageUiHandler } from "#ui/handlers/message-ui-handler"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; -import { MysteryEncounterUiHandler } from "#ui/handlers/mystery-encounter-ui-handler"; -import { PartyUiHandler } from "#ui/handlers/party-ui-handler"; -import { PokedexPageUiHandler } from "#ui/handlers/pokedex-page-ui-handler"; -import { PokedexScanUiHandler } from "#ui/handlers/pokedex-scan-ui-handler"; -import { PokedexUiHandler } from "#ui/handlers/pokedex-ui-handler"; -import { RegistrationFormUiHandler } from "#ui/handlers/registration-form-ui-handler"; -import { RenameFormUiHandler } from "#ui/handlers/rename-form-ui-handler"; -import { RunHistoryUiHandler } from "#ui/handlers/run-history-ui-handler"; -import { RunInfoUiHandler } from "#ui/handlers/run-info-ui-handler"; -import { SaveSlotSelectUiHandler } from "#ui/handlers/save-slot-select-ui-handler"; -import { SessionReloadModalUiHandler } from "#ui/handlers/session-reload-modal-ui-handler"; -import { StarterSelectUiHandler } from "#ui/handlers/starter-select-ui-handler"; -import { SummaryUiHandler } from "#ui/handlers/summary-ui-handler"; -import { TargetSelectUiHandler } from "#ui/handlers/target-select-ui-handler"; -import { TestDialogueUiHandler } from "#ui/handlers/test-dialogue-ui-handler"; -import { TitleUiHandler } from "#ui/handlers/title-ui-handler"; -import type { UiHandler } from "#ui/handlers/ui-handler"; -import { UnavailableModalUiHandler } from "#ui/handlers/unavailable-modal-ui-handler"; import { KeyboardBindingUiHandler } from "#ui/keyboard-binding-ui-handler"; +import { LoadingModalUiHandler } from "#ui/loading-modal-ui-handler"; +import { LoginFormUiHandler } from "#ui/login-form-ui-handler"; +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/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"; +import { PokedexScanUiHandler } from "#ui/pokedex-scan-ui-handler"; +import { PokedexUiHandler } from "#ui/pokedex-ui-handler"; +import { RegistrationFormUiHandler } from "#ui/registration-form-ui-handler"; +import { RenameFormUiHandler } from "#ui/rename-form-ui-handler"; +import { RunHistoryUiHandler } from "#ui/run-history-ui-handler"; +import { RunInfoUiHandler } from "#ui/run-info-ui-handler"; +import { SaveSlotSelectUiHandler } from "#ui/save-slot-select-ui-handler"; +import { SavingIconContainer } from "#ui/saving-icon-handler"; +import { SessionReloadModalUiHandler } from "#ui/session-reload-modal-ui-handler"; import { SettingsAudioUiHandler } from "#ui/settings-audio-ui-handler"; import { SettingsDisplayUiHandler } from "#ui/settings-display-ui-handler"; import { SettingsGamepadUiHandler } from "#ui/settings-gamepad-ui-handler"; import { SettingsKeyboardUiHandler } from "#ui/settings-keyboard-ui-handler"; import { SettingsUiHandler } from "#ui/settings-ui-handler"; +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 } from "#ui/text"; +import { TitleUiHandler } from "#ui/title-ui-handler"; +import type { UiHandler } from "#ui/ui-handler"; import { addWindow } from "#ui/ui-theme"; +import { UnavailableModalUiHandler } from "#ui/unavailable-modal-ui-handler"; import { executeIf } from "#utils/common"; import i18next from "i18next"; import { AdminUiHandler } from "./handlers/admin-ui-handler"; diff --git a/src/ui/utils/scrollable-grid-helper.ts b/src/ui/utils/scrollable-grid-helper.ts index 675352ff6fb..74ddfdfa412 100644 --- a/src/ui/utils/scrollable-grid-helper.ts +++ b/src/ui/utils/scrollable-grid-helper.ts @@ -1,6 +1,6 @@ import { Button } from "#enums/buttons"; -import type { ScrollBar } from "#ui/containers/scroll-bar"; -import type { UiHandler } from "#ui/handlers/ui-handler"; +import type { ScrollBar } from "#ui/scroll-bar"; +import type { UiHandler } from "#ui/ui-handler"; type UpdateGridCallbackFunction = () => void; type UpdateDetailsCallbackFunction = (index: number) => void; diff --git a/test/abilities/arena-trap.test.ts b/test/abilities/arena-trap.test.ts index 5b426fd4f47..8f5d820a145 100644 --- a/test/abilities/arena-trap.test.ts +++ b/test/abilities/arena-trap.test.ts @@ -6,7 +6,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { GameManager } from "#test/test-utils/game-manager"; -import type { PartyUiHandler } from "#ui/handlers/party-ui-handler"; +import type { PartyUiHandler } from "#ui/party-ui-handler"; import i18next from "i18next"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/challenges/hardcore.test.ts b/test/challenges/hardcore.test.ts index a52d7102868..0f4ab1b9f02 100644 --- a/test/challenges/hardcore.test.ts +++ b/test/challenges/hardcore.test.ts @@ -8,7 +8,7 @@ import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { UiMode } from "#enums/ui-mode"; import { GameManager } from "#test/test-utils/game-manager"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/challenges/limited-support.test.ts b/test/challenges/limited-support.test.ts index ba8930943dd..35413220550 100644 --- a/test/challenges/limited-support.test.ts +++ b/test/challenges/limited-support.test.ts @@ -5,7 +5,7 @@ import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { ExpBoosterModifier } from "#modifiers/modifier"; import { GameManager } from "#test/test-utils/game-manager"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/daily-mode.test.ts b/test/daily-mode.test.ts index fae12a0b5d7..34a8da80478 100644 --- a/test/daily-mode.test.ts +++ b/test/daily-mode.test.ts @@ -5,7 +5,7 @@ import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { MapModifier } from "#modifiers/modifier"; import { GameManager } from "#test/test-utils/game-manager"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Daily Mode", () => { diff --git a/test/imports.test.ts b/test/imports.test.ts index aeaa763c05e..04e9462d8d0 100644 --- a/test/imports.test.ts +++ b/test/imports.test.ts @@ -1,4 +1,4 @@ -import { initStatsKeys } from "#ui/handlers/game-stats-ui-handler"; +import { initStatsKeys } from "#ui/game-stats-ui-handler"; import { describe, expect, it } from "vitest"; async function importModule() { diff --git a/test/items/dire-hit.test.ts b/test/items/dire-hit.test.ts index d704a94f3a8..6d4bc7524eb 100644 --- a/test/items/dire-hit.test.ts +++ b/test/items/dire-hit.test.ts @@ -10,7 +10,7 @@ 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/test-utils/game-manager"; -import type { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +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 index 9985d4b3a55..2c12b34eba3 100644 --- a/test/items/double-battle-chance-booster.test.ts +++ b/test/items/double-battle-chance-booster.test.ts @@ -5,7 +5,7 @@ import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { DoubleBattleChanceBoosterModifier } from "#modifiers/modifier"; import { GameManager } from "#test/test-utils/game-manager"; -import type { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +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/temp-stat-stage-booster.test.ts b/test/items/temp-stat-stage-booster.test.ts index 499f1d630b0..05ea5a03eae 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 { GameManager } from "#test/test-utils/game-manager"; -import type { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +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/mystery-encounter/encounter-test-utils.ts b/test/mystery-encounter/encounter-test-utils.ts index fcf27b2c6fb..7b2dbfc9aeb 100644 --- a/test/mystery-encounter/encounter-test-utils.ts +++ b/test/mystery-encounter/encounter-test-utils.ts @@ -13,10 +13,10 @@ import { } from "#phases/mystery-encounter-phases"; import { VictoryPhase } from "#phases/victory-phase"; import type { GameManager } from "#test/test-utils/game-manager"; -import type { MessageUiHandler } from "#ui/handlers/message-ui-handler"; -import type { MysteryEncounterUiHandler } from "#ui/handlers/mystery-encounter-ui-handler"; -import type { PartyUiHandler } from "#ui/handlers/party-ui-handler"; +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"; +import type { PartyUiHandler } from "#ui/party-ui-handler"; import { isNullOrUndefined } from "#utils/common"; import { expect, 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 44585d4d795..5e9dffa1332 100644 --- a/test/mystery-encounter/encounters/berries-abound-encounter.test.ts +++ b/test/mystery-encounter/encounters/berries-abound-encounter.test.ts @@ -17,7 +17,7 @@ import { } from "#test/mystery-encounter/encounter-test-utils"; import { GameManager } from "#test/test-utils/game-manager"; import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/berriesAbound"; 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 a3357b00b89..723516174fb 100644 --- a/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts +++ b/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts @@ -20,7 +20,7 @@ import { } from "#test/mystery-encounter/encounter-test-utils"; import { GameManager } from "#test/test-utils/game-manager"; import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/bugTypeSuperfan"; diff --git a/test/mystery-encounter/encounters/clowning-around-encounter.test.ts b/test/mystery-encounter/encounters/clowning-around-encounter.test.ts index d199a331943..e7ec6e43392 100644 --- a/test/mystery-encounter/encounters/clowning-around-encounter.test.ts +++ b/test/mystery-encounter/encounters/clowning-around-encounter.test.ts @@ -29,8 +29,8 @@ import { } from "#test/mystery-encounter/encounter-test-utils"; import { GameManager } from "#test/test-utils/game-manager"; import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; -import type { PartyUiHandler } from "#ui/handlers/party-ui-handler"; import type { OptionSelectUiHandler } from "#ui/option-select-ui-handler"; +import type { PartyUiHandler } from "#ui/party-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/dancing-lessons-encounter.test.ts b/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts index bf42e6d4df3..81a2fc7463c 100644 --- a/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts +++ b/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts @@ -18,7 +18,7 @@ import { skipBattleRunMysteryEncounterRewardsPhase, } from "#test/mystery-encounter/encounter-test-utils"; import { GameManager } from "#test/test-utils/game-manager"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/dancingLessons"; 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 d6c566c4de6..c270429b394 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 { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils"; import { GameManager } from "#test/test-utils/game-manager"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/departmentStoreSale"; diff --git a/test/mystery-encounter/encounters/field-trip-encounter.test.ts b/test/mystery-encounter/encounters/field-trip-encounter.test.ts index b8e6e36cf17..fd3e20012b1 100644 --- a/test/mystery-encounter/encounters/field-trip-encounter.test.ts +++ b/test/mystery-encounter/encounters/field-trip-encounter.test.ts @@ -12,7 +12,7 @@ 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/test-utils/game-manager"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +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/fight-or-flight-encounter.test.ts b/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts index 34c0f635000..81dbad16e01 100644 --- a/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts +++ b/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts @@ -17,7 +17,7 @@ import { } from "#test/mystery-encounter/encounter-test-utils"; import { GameManager } from "#test/test-utils/game-manager"; import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/fightOrFlight"; 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 8a058bad5fe..bc1a2893627 100644 --- a/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts +++ b/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts @@ -22,7 +22,7 @@ import { } from "#test/mystery-encounter/encounter-test-utils"; import { GameManager } from "#test/test-utils/game-manager"; import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/funAndGames"; 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 90bc41fde2b..c8e934168bc 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 { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils"; import { GameManager } from "#test/test-utils/game-manager"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +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/mysterious-challengers-encounter.test.ts b/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts index ed8b6bffbe9..a8d91f8f101 100644 --- a/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts +++ b/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts @@ -20,7 +20,7 @@ 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/handlers/modifier-select-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/mysteriousChallengers"; diff --git a/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts b/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts index a096ea5ff6e..c88d77a8cf5 100644 --- a/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts +++ b/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts @@ -16,7 +16,7 @@ import { } from "#test/mystery-encounter/encounter-test-utils"; import { GameManager } from "#test/test-utils/game-manager"; import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +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-strong-stuff-encounter.test.ts b/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts index 5df2d2ab358..06c4c3c1cee 100644 --- a/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts +++ b/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts @@ -24,7 +24,7 @@ import { } from "#test/mystery-encounter/encounter-test-utils"; import { GameManager } from "#test/test-utils/game-manager"; import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +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 9b009879522..814e2ee07fb 100644 --- a/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts +++ b/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts @@ -20,7 +20,7 @@ import { VictoryPhase } from "#phases/victory-phase"; import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils"; import { GameManager } from "#test/test-utils/game-manager"; import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +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 6f6c01c7322..91a88712e9b 100644 --- a/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts +++ b/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts @@ -27,7 +27,7 @@ import { } from "#test/mystery-encounter/encounter-test-utils"; import { GameManager } from "#test/test-utils/game-manager"; import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import * as Utils from "#utils/common"; 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 3640ed3809f..f00ef834624 100644 --- a/test/mystery-encounter/encounters/weird-dream-encounter.test.ts +++ b/test/mystery-encounter/encounters/weird-dream-encounter.test.ts @@ -16,7 +16,7 @@ import { } from "#test/mystery-encounter/encounter-test-utils"; import { GameManager } from "#test/test-utils/game-manager"; import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/weirdDream"; diff --git a/test/phases/mystery-encounter-phase.test.ts b/test/phases/mystery-encounter-phase.test.ts index 8dfbd509a05..30ab977dbc6 100644 --- a/test/phases/mystery-encounter-phase.test.ts +++ b/test/phases/mystery-encounter-phase.test.ts @@ -5,8 +5,8 @@ import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { MysteryEncounterOptionSelectedPhase } from "#phases/mystery-encounter-phases"; import { GameManager } from "#test/test-utils/game-manager"; -import type { MessageUiHandler } from "#ui/handlers/message-ui-handler"; -import type { MysteryEncounterUiHandler } from "#ui/handlers/mystery-encounter-ui-handler"; +import type { MessageUiHandler } from "#ui/message-ui-handler"; +import type { MysteryEncounterUiHandler } from "#ui/mystery-encounter-ui-handler"; import i18next from "i18next"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/phases/select-modifier-phase.test.ts b/test/phases/select-modifier-phase.test.ts index f6446c6e7be..c6f07088819 100644 --- a/test/phases/select-modifier-phase.test.ts +++ b/test/phases/select-modifier-phase.test.ts @@ -12,7 +12,7 @@ import { ModifierTypeOption } from "#modifiers/modifier-type"; import { SelectModifierPhase } from "#phases/select-modifier-phase"; import { GameManager } from "#test/test-utils/game-manager"; import { initSceneWithoutEncounterPhase } from "#test/test-utils/game-manager-utils"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { shiftCharCodes } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import Phaser from "phaser"; diff --git a/test/plugins/api/pokerogue-daily-api.test.ts b/test/plugins/api/pokerogue-daily-api.test.ts index b45896e6a2c..ef5dfddada5 100644 --- a/test/plugins/api/pokerogue-daily-api.test.ts +++ b/test/plugins/api/pokerogue-daily-api.test.ts @@ -2,7 +2,7 @@ import { PokerogueDailyApi } from "#api/pokerogue-daily-api"; 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/containers/daily-run-scoreboard"; +import { type RankingEntry, ScoreboardCategory } from "#ui/daily-run-scoreboard"; 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/test-utils/game-manager-utils.ts b/test/test-utils/game-manager-utils.ts index 7b12251819f..26b7ccf1020 100644 --- a/test/test-utils/game-manager-utils.ts +++ b/test/test-utils/game-manager-utils.ts @@ -9,7 +9,7 @@ import type { MoveId } from "#enums/move-id"; import type { SpeciesId } from "#enums/species-id"; import { PlayerPokemon } from "#field/pokemon"; import type { StarterMoveset } from "#types/save-data"; -import type { Starter } from "#ui/handlers/starter-select-ui-handler"; +import type { Starter } from "#ui/starter-select-ui-handler"; import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; /** Function to convert Blob to string */ diff --git a/test/test-utils/game-manager.ts b/test/test-utils/game-manager.ts index 6b7c805df74..1b379daae88 100644 --- a/test/test-utils/game-manager.ts +++ b/test/test-utils/game-manager.ts @@ -45,13 +45,13 @@ 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 { PhaseClass, PhaseString } from "#types/phase-types"; -import type { BallUiHandler } from "#ui/handlers/ball-ui-handler"; -import type { BattleMessageUiHandler } from "#ui/handlers/battle-message-ui-handler"; -import type { CommandUiHandler } from "#ui/handlers/command-ui-handler"; -import type { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; -import type { PartyUiHandler } from "#ui/handlers/party-ui-handler"; -import type { StarterSelectUiHandler } from "#ui/handlers/starter-select-ui-handler"; -import type { TargetSelectUiHandler } from "#ui/handlers/target-select-ui-handler"; +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"; +import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; +import type { PartyUiHandler } from "#ui/party-ui-handler"; +import type { StarterSelectUiHandler } from "#ui/starter-select-ui-handler"; +import type { TargetSelectUiHandler } from "#ui/target-select-ui-handler"; import { isNullOrUndefined } from "#utils/common"; import fs from "node:fs"; import { AES, enc } from "crypto-js"; diff --git a/test/test-utils/game-wrapper.ts b/test/test-utils/game-wrapper.ts index 166f4b8de7a..d18ea9301ea 100644 --- a/test/test-utils/game-wrapper.ts +++ b/test/test-utils/game-wrapper.ts @@ -12,7 +12,7 @@ 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/containers/pokedex-mon-container"; +import { PokedexMonContainer } from "#ui/pokedex-mon-container"; import fs from "node:fs"; import Phaser from "phaser"; import { vi } from "vitest"; diff --git a/test/test-utils/helpers/daily-mode-helper.ts b/test/test-utils/helpers/daily-mode-helper.ts index 365c5df3627..ca882eaf548 100644 --- a/test/test-utils/helpers/daily-mode-helper.ts +++ b/test/test-utils/helpers/daily-mode-helper.ts @@ -7,7 +7,7 @@ import { EncounterPhase } from "#phases/encounter-phase"; import { TitlePhase } from "#phases/title-phase"; import { TurnInitPhase } from "#phases/turn-init-phase"; import { GameManagerHelper } from "#test/test-utils/helpers/game-manager-helper"; -import type { SaveSlotSelectUiHandler } from "#ui/handlers/save-slot-select-ui-handler"; +import type { SaveSlotSelectUiHandler } from "#ui/save-slot-select-ui-handler"; /** * Helper to handle daily mode specifics diff --git a/test/test-utils/phase-interceptor.ts b/test/test-utils/phase-interceptor.ts index 4ac5e1150e5..5968e8e3617 100644 --- a/test/test-utils/phase-interceptor.ts +++ b/test/test-utils/phase-interceptor.ts @@ -67,7 +67,7 @@ import { UnlockPhase } from "#phases/unlock-phase"; import { VictoryPhase } from "#phases/victory-phase"; import { ErrorInterceptor } from "#test/test-utils/error-interceptor"; import type { PhaseClass, PhaseString } from "#types/phase-types"; -import type { AwaitableUiHandler } from "#ui/handlers/awaitable-ui-handler"; +import type { AwaitableUiHandler } from "#ui/awaitable-ui-handler"; import { UI } from "#ui/ui"; export interface PromptHandler { diff --git a/test/ui/item-manage-button.test.ts b/test/ui/item-manage-button.test.ts index b5c24776e7b..c28cd9e802e 100644 --- a/test/ui/item-manage-button.test.ts +++ b/test/ui/item-manage-button.test.ts @@ -5,8 +5,8 @@ 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/handlers/modifier-select-ui-handler"; -import { type PartyUiHandler, PartyUiMode } from "#ui/handlers/party-ui-handler"; +import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; +import { type PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/ui/pokedex.test.ts b/test/ui/pokedex.test.ts index 34539094232..6b84b253260 100644 --- a/test/ui/pokedex.test.ts +++ b/test/ui/pokedex.test.ts @@ -8,9 +8,9 @@ import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { GameManager } from "#test/test-utils/game-manager"; import type { StarterAttributes } from "#types/save-data"; -import { FilterTextRow } from "#ui/containers/filter-text"; -import { PokedexPageUiHandler } from "#ui/handlers/pokedex-page-ui-handler"; -import { PokedexUiHandler } from "#ui/handlers/pokedex-ui-handler"; +import { FilterTextRow } from "#ui/filter-text"; +import { PokedexPageUiHandler } from "#ui/pokedex-page-ui-handler"; +import { PokedexUiHandler } from "#ui/pokedex-ui-handler"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; diff --git a/test/ui/starter-select.test.ts b/test/ui/starter-select.test.ts index 2f575b72a5c..397f3d6086f 100644 --- a/test/ui/starter-select.test.ts +++ b/test/ui/starter-select.test.ts @@ -8,10 +8,10 @@ import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import type { TitlePhase } from "#phases/title-phase"; import { GameManager } from "#test/test-utils/game-manager"; -import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; -import type { SaveSlotSelectUiHandler } from "#ui/handlers/save-slot-select-ui-handler"; -import type { StarterSelectUiHandler } from "#ui/handlers/starter-select-ui-handler"; +import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; import type { OptionSelectUiHandler } from "#ui/option-select-ui-handler"; +import type { SaveSlotSelectUiHandler } from "#ui/save-slot-select-ui-handler"; +import type { StarterSelectUiHandler } from "#ui/starter-select-ui-handler"; import i18next from "i18next"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/ui/transfer-item-options.test.ts b/test/ui/transfer-item-options.test.ts index 7e9c1b5e36b..901aa261f50 100644 --- a/test/ui/transfer-item-options.test.ts +++ b/test/ui/transfer-item-options.test.ts @@ -4,8 +4,8 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { GameManager } from "#test/test-utils/game-manager"; -import { type PartyUiHandler, PartyUiMode } from "#ui/handlers/party-ui-handler"; -import type { RenameFormUiHandler } from "#ui/handlers/rename-form-ui-handler"; +import { type PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler"; +import type { RenameFormUiHandler } from "#ui/rename-form-ui-handler"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/ui/transfer-item.test.ts b/test/ui/transfer-item.test.ts index 67a21b0656d..c04c16623e3 100644 --- a/test/ui/transfer-item.test.ts +++ b/test/ui/transfer-item.test.ts @@ -4,8 +4,8 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { GameManager } from "#test/test-utils/game-manager"; -import { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; -import { PartyUiHandler, PartyUiMode } from "#ui/handlers/party-ui-handler"; +import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; +import { PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler"; import Phaser from "phaser"; import type BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/test/ui/type-hints.test.ts b/test/ui/type-hints.test.ts index 56891e22c2a..b5fe0d9585a 100644 --- a/test/ui/type-hints.test.ts +++ b/test/ui/type-hints.test.ts @@ -4,7 +4,7 @@ import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; import { GameManager } from "#test/test-utils/game-manager"; import type { MockText } from "#test/test-utils/mocks/mocks-container/mock-text"; -import { FightUiHandler } from "#ui/handlers/fight-ui-handler"; +import { FightUiHandler } from "#ui/fight-ui-handler"; import i18next from "i18next"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; diff --git a/tsconfig.json b/tsconfig.json index 7bf82eaaca0..131a0503ee3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -50,7 +50,14 @@ ], "#trainers/*": ["./src/data/trainers/*.ts"], "#types/*": ["./src/@types/helpers/*.ts", "./src/@types/*.ts", "./src/typings/phaser/*.ts"], - "#ui/*": ["./src/ui/battle-info/*.ts", "./src/ui/settings/*.ts", "./src/ui/*.ts"], + "#ui/*": [ + "./src/ui/battle-info/*.ts", + "./src/ui/containers/*.ts", + "./src/ui/handlers/*.ts", + "./src/ui/settings/*.ts", + "./src/ui/utils/*.ts", + "./src/ui/*.ts" + ], "#utils/*": ["./src/utils/*.ts"], "#data/*": ["./src/data/pokemon-forms/*.ts", "./src/data/pokemon/*.ts", "./src/data/*.ts"], "#test/*": ["./test/*.ts"], From a5f80ab4908c4f802b3d69b1a66096a6f09b9ff9 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Thu, 11 Sep 2025 00:32:11 -0700 Subject: [PATCH 07/29] [Misc] Delete useless test file --- test/imports.test.ts | 34 ---------------------------------- 1 file changed, 34 deletions(-) delete mode 100644 test/imports.test.ts diff --git a/test/imports.test.ts b/test/imports.test.ts deleted file mode 100644 index 04e9462d8d0..00000000000 --- a/test/imports.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { initStatsKeys } from "#ui/game-stats-ui-handler"; -import { describe, expect, it } from "vitest"; - -async function importModule() { - try { - initStatsKeys(); - const { PokemonMove } = await import("#app/data/moves/pokemon-move"); - const { SpeciesId: Species } = await import("#enums/species-id"); - return { - PokemonMove, - Species, - }; - // Dynamically import the module - } catch (error) { - // Log the error stack trace - console.error("Error during import:", error.stack); - // Rethrow the error to ensure the test fails - throw error; - } -} - -describe("tests to debug the import, with trace", () => { - it("import PokemonMove module", async () => { - const module = await importModule(); - // Example assertion - expect(module.PokemonMove).toBeDefined(); - }); - - it("import Species module", async () => { - const module = await importModule(); - // Example assertion - expect(module.Species).toBeDefined(); - }); -}); From 90d58c4457554db6ee95f42e0ab26e2e1780d512 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Thu, 11 Sep 2025 08:33:45 -0500 Subject: [PATCH 08/29] [Docs] [Bug] Fix types for PhaseInterceptor --- test/test-utils/phase-interceptor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test-utils/phase-interceptor.ts b/test/test-utils/phase-interceptor.ts index 5968e8e3617..6c7b5bf3033 100644 --- a/test/test-utils/phase-interceptor.ts +++ b/test/test-utils/phase-interceptor.ts @@ -111,8 +111,8 @@ export class PhaseInterceptor { private intervalRun: NodeJS.Timeout; private prompts: PromptHandler[]; private inProgress?: InProgressStub; - private originalSetMode: UI["setMode"]; - private originalSuperEnd: Phase["end"]; + private originalSetMode: typeof UI.prototype.setMode; + private originalSuperEnd: typeof Phase.prototype.end; /** * List of phases with their corresponding start methods. From 0cc59974cccfdfec9c42ffdb6191afa61a1116aa Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Thu, 11 Sep 2025 08:53:26 -0500 Subject: [PATCH 09/29] [Docs] [Bug] Downgrade typedoc temporarily --- package.json | 2 +- pnpm-lock.yaml | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 8b5635d3115..ee5b001a589 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "lefthook": "^1.12.2", "msw": "^2.10.4", "phaser3spectorjs": "^0.0.8", - "typedoc": "^0.28.12", + "typedoc": "0.28.7", "typedoc-github-theme": "^0.3.1", "typedoc-plugin-coverage": "^4.0.1", "typedoc-plugin-mdn-links": "^5.0.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5bbe08bf0c6..e750095a4c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -88,17 +88,17 @@ importers: specifier: ^0.0.8 version: 0.0.8 typedoc: - specifier: ^0.28.12 - version: 0.28.12(typescript@5.8.3) + specifier: 0.28.7 + version: 0.28.7(typescript@5.8.3) typedoc-github-theme: specifier: ^0.3.1 - version: 0.3.1(typedoc@0.28.12(typescript@5.8.3)) + version: 0.3.1(typedoc@0.28.7(typescript@5.8.3)) typedoc-plugin-coverage: specifier: ^4.0.1 - version: 4.0.1(typedoc@0.28.12(typescript@5.8.3)) + version: 4.0.1(typedoc@0.28.7(typescript@5.8.3)) typedoc-plugin-mdn-links: specifier: ^5.0.9 - version: 5.0.9(typedoc@0.28.12(typescript@5.8.3)) + version: 5.0.9(typedoc@0.28.7(typescript@5.8.3)) typescript: specifier: ^5.8.3 version: 5.8.3 @@ -1818,12 +1818,12 @@ packages: peerDependencies: typedoc: 0.27.x || 0.28.x - typedoc@0.28.12: - resolution: {integrity: sha512-H5ODu4f7N+myG4MfuSp2Vh6wV+WLoZaEYxKPt2y8hmmqNEMVrH69DAjjdmYivF4tP/C2jrIZCZhPalZlTU/ipA==} + typedoc@0.28.7: + resolution: {integrity: sha512-lpz0Oxl6aidFkmS90VQDQjk/Qf2iw0IUvFqirdONBdj7jPSN9mGXhy66BcGNDxx5ZMyKKiBVAREvPEzT6Uxipw==} engines: {node: '>= 18', pnpm: '>= 10'} hasBin: true peerDependencies: - typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x + typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x typescript@5.8.3: resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} @@ -3663,19 +3663,19 @@ snapshots: type-fest@4.41.0: {} - typedoc-github-theme@0.3.1(typedoc@0.28.12(typescript@5.8.3)): + typedoc-github-theme@0.3.1(typedoc@0.28.7(typescript@5.8.3)): dependencies: - typedoc: 0.28.12(typescript@5.8.3) + typedoc: 0.28.7(typescript@5.8.3) - typedoc-plugin-coverage@4.0.1(typedoc@0.28.12(typescript@5.8.3)): + typedoc-plugin-coverage@4.0.1(typedoc@0.28.7(typescript@5.8.3)): dependencies: - typedoc: 0.28.12(typescript@5.8.3) + typedoc: 0.28.7(typescript@5.8.3) - typedoc-plugin-mdn-links@5.0.9(typedoc@0.28.12(typescript@5.8.3)): + typedoc-plugin-mdn-links@5.0.9(typedoc@0.28.7(typescript@5.8.3)): dependencies: - typedoc: 0.28.12(typescript@5.8.3) + typedoc: 0.28.7(typescript@5.8.3) - typedoc@0.28.12(typescript@5.8.3): + typedoc@0.28.7(typescript@5.8.3): dependencies: '@gerrit0/mini-shiki': 3.12.2 lunr: 2.3.9 From 86027b82bea03216a6aad4fc6f716afbc9408943 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Thu, 11 Sep 2025 13:47:58 -0500 Subject: [PATCH 10/29] [Docs] Adjust favicon icon for docs site --- typedoc.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typedoc.config.js b/typedoc.config.js index fabe9f1c8c5..d9e880743ca 100644 --- a/typedoc.config.js +++ b/typedoc.config.js @@ -43,7 +43,7 @@ const config = { readme: "./README.md", coverageLabel: "Documented", coverageSvgWidth: 120, // Increased from 104 baseline due to adding 2 extra letters - favicon: "./public/images/logo.png", + favicon: "./favicon.ico", theme: "typedoc-github-theme", customFooterHtml: "

Copyright Pagefault Games 2025

", customFooterHtmlDisableWrapper: true, From 6c39ec721e8b66774df5886b2eeb04eb4633098e Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Thu, 11 Sep 2025 19:47:06 -0700 Subject: [PATCH 11/29] [Dev] Add `build:dev` command to `package.json` --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index ee5b001a589..770e3ce30a9 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "start:podman": "vite --mode development --host 0.0.0.0 --port $PORT", "build": "vite build", "build:beta": "vite build --mode beta", + "build:dev": "vite build --mode development", "preview": "vite preview", "test": "vitest run --no-isolate", "test:cov": "vitest run --coverage --no-isolate", From c458cbb2be477b53c6de72b47f134e9dcde7d258 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Sep 2025 19:54:31 -0700 Subject: [PATCH 12/29] [Deps] Bump vite from 7.0.6 to 7.0.7 (#6546) Bump vite from 7.0.6 to 7.0.7 Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.0.6 to 7.0.7. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v7.0.7/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v7.0.7/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 7.0.7 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 441 ++++++++++++++++++++++++++----------------------- 2 files changed, 231 insertions(+), 212 deletions(-) diff --git a/package.json b/package.json index 770e3ce30a9..5a47b31ff14 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "typedoc-plugin-coverage": "^4.0.1", "typedoc-plugin-mdn-links": "^5.0.9", "typescript": "^5.8.3", - "vite": "^7.0.6", + "vite": "^7.0.7", "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 e750095a4c5..0638e3ba49a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -103,11 +103,11 @@ importers: specifier: ^5.8.3 version: 5.8.3 vite: - specifier: ^7.0.6 - version: 7.0.6(@types/node@22.16.5)(yaml@2.8.1) + specifier: ^7.0.7 + version: 7.0.7(@types/node@22.16.5)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@7.0.6(@types/node@22.16.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.8.3)(vite@7.0.7(@types/node@22.16.5)(yaml@2.8.1)) vitest: specifier: ^3.2.4 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.1) @@ -285,158 +285,158 @@ packages: resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} engines: {node: '>=18'} - '@esbuild/aix-ppc64@0.25.8': - resolution: {integrity: sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==} + '@esbuild/aix-ppc64@0.25.9': + resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.8': - resolution: {integrity: sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==} + '@esbuild/android-arm64@0.25.9': + resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.8': - resolution: {integrity: sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==} + '@esbuild/android-arm@0.25.9': + resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.8': - resolution: {integrity: sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==} + '@esbuild/android-x64@0.25.9': + resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.8': - resolution: {integrity: sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==} + '@esbuild/darwin-arm64@0.25.9': + resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.8': - resolution: {integrity: sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==} + '@esbuild/darwin-x64@0.25.9': + resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.8': - resolution: {integrity: sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==} + '@esbuild/freebsd-arm64@0.25.9': + resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.8': - resolution: {integrity: sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==} + '@esbuild/freebsd-x64@0.25.9': + resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.8': - resolution: {integrity: sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==} + '@esbuild/linux-arm64@0.25.9': + resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.8': - resolution: {integrity: sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==} + '@esbuild/linux-arm@0.25.9': + resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.8': - resolution: {integrity: sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==} + '@esbuild/linux-ia32@0.25.9': + resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.8': - resolution: {integrity: sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==} + '@esbuild/linux-loong64@0.25.9': + resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.8': - resolution: {integrity: sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==} + '@esbuild/linux-mips64el@0.25.9': + resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.8': - resolution: {integrity: sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==} + '@esbuild/linux-ppc64@0.25.9': + resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.8': - resolution: {integrity: sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==} + '@esbuild/linux-riscv64@0.25.9': + resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.8': - resolution: {integrity: sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==} + '@esbuild/linux-s390x@0.25.9': + resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.8': - resolution: {integrity: sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==} + '@esbuild/linux-x64@0.25.9': + resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.8': - resolution: {integrity: sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==} + '@esbuild/netbsd-arm64@0.25.9': + resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.8': - resolution: {integrity: sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==} + '@esbuild/netbsd-x64@0.25.9': + resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.8': - resolution: {integrity: sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==} + '@esbuild/openbsd-arm64@0.25.9': + resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.8': - resolution: {integrity: sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==} + '@esbuild/openbsd-x64@0.25.9': + resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.8': - resolution: {integrity: sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==} + '@esbuild/openharmony-arm64@0.25.9': + resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.25.8': - resolution: {integrity: sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==} + '@esbuild/sunos-x64@0.25.9': + resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.8': - resolution: {integrity: sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==} + '@esbuild/win32-arm64@0.25.9': + resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.8': - resolution: {integrity: sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==} + '@esbuild/win32-ia32@0.25.9': + resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.8': - resolution: {integrity: sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==} + '@esbuild/win32-x64@0.25.9': + resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -612,103 +612,108 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@rollup/rollup-android-arm-eabi@4.46.1': - resolution: {integrity: sha512-oENme6QxtLCqjChRUUo3S6X8hjCXnWmJWnedD7VbGML5GUtaOtAyx+fEEXnBXVf0CBZApMQU0Idwi0FmyxzQhw==} + '@rollup/rollup-android-arm-eabi@4.50.1': + resolution: {integrity: sha512-HJXwzoZN4eYTdD8bVV22DN8gsPCAj3V20NHKOs8ezfXanGpmVPR7kalUHd+Y31IJp9stdB87VKPFbsGY3H/2ag==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.46.1': - resolution: {integrity: sha512-OikvNT3qYTl9+4qQ9Bpn6+XHM+ogtFadRLuT2EXiFQMiNkXFLQfNVppi5o28wvYdHL2s3fM0D/MZJ8UkNFZWsw==} + '@rollup/rollup-android-arm64@4.50.1': + resolution: {integrity: sha512-PZlsJVcjHfcH53mOImyt3bc97Ep3FJDXRpk9sMdGX0qgLmY0EIWxCag6EigerGhLVuL8lDVYNnSo8qnTElO4xw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.46.1': - resolution: {integrity: sha512-EFYNNGij2WllnzljQDQnlFTXzSJw87cpAs4TVBAWLdkvic5Uh5tISrIL6NRcxoh/b2EFBG/TK8hgRrGx94zD4A==} + '@rollup/rollup-darwin-arm64@4.50.1': + resolution: {integrity: sha512-xc6i2AuWh++oGi4ylOFPmzJOEeAa2lJeGUGb4MudOtgfyyjr4UPNK+eEWTPLvmPJIY/pgw6ssFIox23SyrkkJw==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.46.1': - resolution: {integrity: sha512-ZaNH06O1KeTug9WI2+GRBE5Ujt9kZw4a1+OIwnBHal92I8PxSsl5KpsrPvthRynkhMck4XPdvY0z26Cym/b7oA==} + '@rollup/rollup-darwin-x64@4.50.1': + resolution: {integrity: sha512-2ofU89lEpDYhdLAbRdeyz/kX3Y2lpYc6ShRnDjY35bZhd2ipuDMDi6ZTQ9NIag94K28nFMofdnKeHR7BT0CATw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.46.1': - resolution: {integrity: sha512-n4SLVebZP8uUlJ2r04+g2U/xFeiQlw09Me5UFqny8HGbARl503LNH5CqFTb5U5jNxTouhRjai6qPT0CR5c/Iig==} + '@rollup/rollup-freebsd-arm64@4.50.1': + resolution: {integrity: sha512-wOsE6H2u6PxsHY/BeFHA4VGQN3KUJFZp7QJBmDYI983fgxq5Th8FDkVuERb2l9vDMs1D5XhOrhBrnqcEY6l8ZA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.46.1': - resolution: {integrity: sha512-8vu9c02F16heTqpvo3yeiu7Vi1REDEC/yES/dIfq3tSXe6mLndiwvYr3AAvd1tMNUqE9yeGYa5w7PRbI5QUV+w==} + '@rollup/rollup-freebsd-x64@4.50.1': + resolution: {integrity: sha512-A/xeqaHTlKbQggxCqispFAcNjycpUEHP52mwMQZUNqDUJFFYtPHCXS1VAG29uMlDzIVr+i00tSFWFLivMcoIBQ==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.46.1': - resolution: {integrity: sha512-K4ncpWl7sQuyp6rWiGUvb6Q18ba8mzM0rjWJ5JgYKlIXAau1db7hZnR0ldJvqKWWJDxqzSLwGUhA4jp+KqgDtQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.50.1': + resolution: {integrity: sha512-54v4okehwl5TaSIkpp97rAHGp7t3ghinRd/vyC1iXqXMfjYUTm7TfYmCzXDoHUPTTf36L8pr0E7YsD3CfB3ZDg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.46.1': - resolution: {integrity: sha512-YykPnXsjUjmXE6j6k2QBBGAn1YsJUix7pYaPLK3RVE0bQL2jfdbfykPxfF8AgBlqtYbfEnYHmLXNa6QETjdOjQ==} + '@rollup/rollup-linux-arm-musleabihf@4.50.1': + resolution: {integrity: sha512-p/LaFyajPN/0PUHjv8TNyxLiA7RwmDoVY3flXHPSzqrGcIp/c2FjwPPP5++u87DGHtw+5kSH5bCJz0mvXngYxw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.46.1': - resolution: {integrity: sha512-kKvqBGbZ8i9pCGW3a1FH3HNIVg49dXXTsChGFsHGXQaVJPLA4f/O+XmTxfklhccxdF5FefUn2hvkoGJH0ScWOA==} + '@rollup/rollup-linux-arm64-gnu@4.50.1': + resolution: {integrity: sha512-2AbMhFFkTo6Ptna1zO7kAXXDLi7H9fGTbVaIq2AAYO7yzcAsuTNWPHhb2aTA6GPiP+JXh85Y8CiS54iZoj4opw==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.46.1': - resolution: {integrity: sha512-zzX5nTw1N1plmqC9RGC9vZHFuiM7ZP7oSWQGqpbmfjK7p947D518cVK1/MQudsBdcD84t6k70WNczJOct6+hdg==} + '@rollup/rollup-linux-arm64-musl@4.50.1': + resolution: {integrity: sha512-Cgef+5aZwuvesQNw9eX7g19FfKX5/pQRIyhoXLCiBOrWopjo7ycfB292TX9MDcDijiuIJlx1IzJz3IoCPfqs9w==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.46.1': - resolution: {integrity: sha512-O8CwgSBo6ewPpktFfSDgB6SJN9XDcPSvuwxfejiddbIC/hn9Tg6Ai0f0eYDf3XvB/+PIWzOQL+7+TZoB8p9Yuw==} + '@rollup/rollup-linux-loongarch64-gnu@4.50.1': + resolution: {integrity: sha512-RPhTwWMzpYYrHrJAS7CmpdtHNKtt2Ueo+BlLBjfZEhYBhK00OsEqM08/7f+eohiF6poe0YRDDd8nAvwtE/Y62Q==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.46.1': - resolution: {integrity: sha512-JnCfFVEKeq6G3h3z8e60kAp8Rd7QVnWCtPm7cxx+5OtP80g/3nmPtfdCXbVl063e3KsRnGSKDHUQMydmzc/wBA==} + '@rollup/rollup-linux-ppc64-gnu@4.50.1': + resolution: {integrity: sha512-eSGMVQw9iekut62O7eBdbiccRguuDgiPMsw++BVUg+1K7WjZXHOg/YOT9SWMzPZA+w98G+Fa1VqJgHZOHHnY0Q==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.46.1': - resolution: {integrity: sha512-dVxuDqS237eQXkbYzQQfdf/njgeNw6LZuVyEdUaWwRpKHhsLI+y4H/NJV8xJGU19vnOJCVwaBFgr936FHOnJsQ==} + '@rollup/rollup-linux-riscv64-gnu@4.50.1': + resolution: {integrity: sha512-S208ojx8a4ciIPrLgazF6AgdcNJzQE4+S9rsmOmDJkusvctii+ZvEuIC4v/xFqzbuP8yDjn73oBlNDgF6YGSXQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.46.1': - resolution: {integrity: sha512-CvvgNl2hrZrTR9jXK1ye0Go0HQRT6ohQdDfWR47/KFKiLd5oN5T14jRdUVGF4tnsN8y9oSfMOqH6RuHh+ck8+w==} + '@rollup/rollup-linux-riscv64-musl@4.50.1': + resolution: {integrity: sha512-3Ag8Ls1ggqkGUvSZWYcdgFwriy2lWo+0QlYgEFra/5JGtAd6C5Hw59oojx1DeqcA2Wds2ayRgvJ4qxVTzCHgzg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.46.1': - resolution: {integrity: sha512-x7ANt2VOg2565oGHJ6rIuuAon+A8sfe1IeUx25IKqi49OjSr/K3awoNqr9gCwGEJo9OuXlOn+H2p1VJKx1psxA==} + '@rollup/rollup-linux-s390x-gnu@4.50.1': + resolution: {integrity: sha512-t9YrKfaxCYe7l7ldFERE1BRg/4TATxIg+YieHQ966jwvo7ddHJxPj9cNFWLAzhkVsbBvNA4qTbPVNsZKBO4NSg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.46.1': - resolution: {integrity: sha512-9OADZYryz/7E8/qt0vnaHQgmia2Y0wrjSSn1V/uL+zw/i7NUhxbX4cHXdEQ7dnJgzYDS81d8+tf6nbIdRFZQoQ==} + '@rollup/rollup-linux-x64-gnu@4.50.1': + resolution: {integrity: sha512-MCgtFB2+SVNuQmmjHf+wfI4CMxy3Tk8XjA5Z//A0AKD7QXUYFMQcns91K6dEHBvZPCnhJSyDWLApk40Iq/H3tA==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.46.1': - resolution: {integrity: sha512-NuvSCbXEKY+NGWHyivzbjSVJi68Xfq1VnIvGmsuXs6TCtveeoDRKutI5vf2ntmNnVq64Q4zInet0UDQ+yMB6tA==} + '@rollup/rollup-linux-x64-musl@4.50.1': + resolution: {integrity: sha512-nEvqG+0jeRmqaUMuwzlfMKwcIVffy/9KGbAGyoa26iu6eSngAYQ512bMXuqqPrlTyfqdlB9FVINs93j534UJrg==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.46.1': - resolution: {integrity: sha512-mWz+6FSRb82xuUMMV1X3NGiaPFqbLN9aIueHleTZCc46cJvwTlvIh7reQLk4p97dv0nddyewBhwzryBHH7wtPw==} + '@rollup/rollup-openharmony-arm64@4.50.1': + resolution: {integrity: sha512-RDsLm+phmT3MJd9SNxA9MNuEAO/J2fhW8GXk62G/B4G7sLVumNFbRwDL6v5NrESb48k+QMqdGbHgEtfU0LCpbA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.50.1': + resolution: {integrity: sha512-hpZB/TImk2FlAFAIsoElM3tLzq57uxnGYwplg6WDyAxbYczSi8O2eQ+H2Lx74504rwKtZ3N2g4bCUkiamzS6TQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.46.1': - resolution: {integrity: sha512-7Thzy9TMXDw9AU4f4vsLNBxh7/VOKuXi73VH3d/kHGr0tZ3x/ewgL9uC7ojUKmH1/zvmZe2tLapYcZllk3SO8Q==} + '@rollup/rollup-win32-ia32-msvc@4.50.1': + resolution: {integrity: sha512-SXjv8JlbzKM0fTJidX4eVsH+Wmnp0/WcD8gJxIZyR6Gay5Qcsmdbi9zVtnbkGPG8v2vMR1AD06lGWy5FLMcG7A==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.46.1': - resolution: {integrity: sha512-7GVB4luhFmGUNXXJhH2jJwZCFB3pIOixv2E3s17GQHBFUOQaISlt7aGcQgqvCaDSxTZJUzlK/QJ1FN8S94MrzQ==} + '@rollup/rollup-win32-x64-msvc@4.50.1': + resolution: {integrity: sha512-StxAO/8ts62KZVRAm4JZYq9+NqNsV7RvimNK+YM7ry//zebEH6meuugqW/P5OFUCjyQgui+9fUxT6d5NShvMvA==} cpu: [x64] os: [win32] @@ -1022,8 +1027,8 @@ packages: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} - esbuild@0.25.8: - resolution: {integrity: sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==} + esbuild@0.25.9: + resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} engines: {node: '>=18'} hasBin: true @@ -1058,8 +1063,9 @@ packages: fast-uri@3.0.6: resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} - fdir@6.4.6: - resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -1597,8 +1603,8 @@ packages: engines: {node: '>= 0.4'} hasBin: true - rollup@4.46.1: - resolution: {integrity: sha512-33xGNBsDJAkzt0PvninskHlWnTIPgDtTwhg0U38CUoNP/7H6wI2Cz6dUeoNPbjdTdsYTGuiFFASuUOWovH0SyQ==} + rollup@4.50.1: + resolution: {integrity: sha512-78E9voJHwnXQMiQdiqswVLZwJIzdBKJ1GdI5Zx6XwoFKUIk09/sSrr+05QFzvYb8q6Y9pPV45zzDuYa3907TZA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1734,6 +1740,10 @@ packages: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + tinypool@1.1.1: resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} engines: {node: ^18.0.0 || >=20.0.0} @@ -1865,8 +1875,8 @@ packages: vite: optional: true - vite@7.0.6: - resolution: {integrity: sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg==} + vite@7.0.7: + resolution: {integrity: sha512-hc6LujN/EkJHmxeiDJMs0qBontZ1cdBvvoCbWhVjzUFTU329VRyOC46gHNSA8NcOC5yzCeXpwI40tieI3DEZqg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -2222,82 +2232,82 @@ snapshots: '@csstools/css-tokenizer@3.0.4': {} - '@esbuild/aix-ppc64@0.25.8': + '@esbuild/aix-ppc64@0.25.9': optional: true - '@esbuild/android-arm64@0.25.8': + '@esbuild/android-arm64@0.25.9': optional: true - '@esbuild/android-arm@0.25.8': + '@esbuild/android-arm@0.25.9': optional: true - '@esbuild/android-x64@0.25.8': + '@esbuild/android-x64@0.25.9': optional: true - '@esbuild/darwin-arm64@0.25.8': + '@esbuild/darwin-arm64@0.25.9': optional: true - '@esbuild/darwin-x64@0.25.8': + '@esbuild/darwin-x64@0.25.9': optional: true - '@esbuild/freebsd-arm64@0.25.8': + '@esbuild/freebsd-arm64@0.25.9': optional: true - '@esbuild/freebsd-x64@0.25.8': + '@esbuild/freebsd-x64@0.25.9': optional: true - '@esbuild/linux-arm64@0.25.8': + '@esbuild/linux-arm64@0.25.9': optional: true - '@esbuild/linux-arm@0.25.8': + '@esbuild/linux-arm@0.25.9': optional: true - '@esbuild/linux-ia32@0.25.8': + '@esbuild/linux-ia32@0.25.9': optional: true - '@esbuild/linux-loong64@0.25.8': + '@esbuild/linux-loong64@0.25.9': optional: true - '@esbuild/linux-mips64el@0.25.8': + '@esbuild/linux-mips64el@0.25.9': optional: true - '@esbuild/linux-ppc64@0.25.8': + '@esbuild/linux-ppc64@0.25.9': optional: true - '@esbuild/linux-riscv64@0.25.8': + '@esbuild/linux-riscv64@0.25.9': optional: true - '@esbuild/linux-s390x@0.25.8': + '@esbuild/linux-s390x@0.25.9': optional: true - '@esbuild/linux-x64@0.25.8': + '@esbuild/linux-x64@0.25.9': optional: true - '@esbuild/netbsd-arm64@0.25.8': + '@esbuild/netbsd-arm64@0.25.9': optional: true - '@esbuild/netbsd-x64@0.25.8': + '@esbuild/netbsd-x64@0.25.9': optional: true - '@esbuild/openbsd-arm64@0.25.8': + '@esbuild/openbsd-arm64@0.25.9': optional: true - '@esbuild/openbsd-x64@0.25.8': + '@esbuild/openbsd-x64@0.25.9': optional: true - '@esbuild/openharmony-arm64@0.25.8': + '@esbuild/openharmony-arm64@0.25.9': optional: true - '@esbuild/sunos-x64@0.25.8': + '@esbuild/sunos-x64@0.25.9': optional: true - '@esbuild/win32-arm64@0.25.8': + '@esbuild/win32-arm64@0.25.9': optional: true - '@esbuild/win32-ia32@0.25.8': + '@esbuild/win32-ia32@0.25.9': optional: true - '@esbuild/win32-x64@0.25.8': + '@esbuild/win32-x64@0.25.9': optional: true '@gerrit0/mini-shiki@3.12.2': @@ -2474,64 +2484,67 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@rollup/rollup-android-arm-eabi@4.46.1': + '@rollup/rollup-android-arm-eabi@4.50.1': optional: true - '@rollup/rollup-android-arm64@4.46.1': + '@rollup/rollup-android-arm64@4.50.1': optional: true - '@rollup/rollup-darwin-arm64@4.46.1': + '@rollup/rollup-darwin-arm64@4.50.1': optional: true - '@rollup/rollup-darwin-x64@4.46.1': + '@rollup/rollup-darwin-x64@4.50.1': optional: true - '@rollup/rollup-freebsd-arm64@4.46.1': + '@rollup/rollup-freebsd-arm64@4.50.1': optional: true - '@rollup/rollup-freebsd-x64@4.46.1': + '@rollup/rollup-freebsd-x64@4.50.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.46.1': + '@rollup/rollup-linux-arm-gnueabihf@4.50.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.46.1': + '@rollup/rollup-linux-arm-musleabihf@4.50.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.46.1': + '@rollup/rollup-linux-arm64-gnu@4.50.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.46.1': + '@rollup/rollup-linux-arm64-musl@4.50.1': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.46.1': + '@rollup/rollup-linux-loongarch64-gnu@4.50.1': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.46.1': + '@rollup/rollup-linux-ppc64-gnu@4.50.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.46.1': + '@rollup/rollup-linux-riscv64-gnu@4.50.1': optional: true - '@rollup/rollup-linux-riscv64-musl@4.46.1': + '@rollup/rollup-linux-riscv64-musl@4.50.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.46.1': + '@rollup/rollup-linux-s390x-gnu@4.50.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.46.1': + '@rollup/rollup-linux-x64-gnu@4.50.1': optional: true - '@rollup/rollup-linux-x64-musl@4.46.1': + '@rollup/rollup-linux-x64-musl@4.50.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.46.1': + '@rollup/rollup-openharmony-arm64@4.50.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.46.1': + '@rollup/rollup-win32-arm64-msvc@4.50.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.46.1': + '@rollup/rollup-win32-ia32-msvc@4.50.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.50.1': optional: true '@shikijs/engine-oniguruma@3.12.2': @@ -2610,14 +2623,14 @@ snapshots: chai: 5.2.1 tinyrainbow: 2.0.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.1))': + '@vitest/mocker@3.2.4(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(vite@7.0.7(@types/node@22.16.5)(yaml@2.8.1))': 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.5)(typescript@5.8.3) - vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.1) + vite: 7.0.7(@types/node@22.16.5)(yaml@2.8.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -2868,34 +2881,34 @@ snapshots: dependencies: es-errors: 1.3.0 - esbuild@0.25.8: + esbuild@0.25.9: optionalDependencies: - '@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 + '@esbuild/aix-ppc64': 0.25.9 + '@esbuild/android-arm': 0.25.9 + '@esbuild/android-arm64': 0.25.9 + '@esbuild/android-x64': 0.25.9 + '@esbuild/darwin-arm64': 0.25.9 + '@esbuild/darwin-x64': 0.25.9 + '@esbuild/freebsd-arm64': 0.25.9 + '@esbuild/freebsd-x64': 0.25.9 + '@esbuild/linux-arm': 0.25.9 + '@esbuild/linux-arm64': 0.25.9 + '@esbuild/linux-ia32': 0.25.9 + '@esbuild/linux-loong64': 0.25.9 + '@esbuild/linux-mips64el': 0.25.9 + '@esbuild/linux-ppc64': 0.25.9 + '@esbuild/linux-riscv64': 0.25.9 + '@esbuild/linux-s390x': 0.25.9 + '@esbuild/linux-x64': 0.25.9 + '@esbuild/netbsd-arm64': 0.25.9 + '@esbuild/netbsd-x64': 0.25.9 + '@esbuild/openbsd-arm64': 0.25.9 + '@esbuild/openbsd-x64': 0.25.9 + '@esbuild/openharmony-arm64': 0.25.9 + '@esbuild/sunos-x64': 0.25.9 + '@esbuild/win32-arm64': 0.25.9 + '@esbuild/win32-ia32': 0.25.9 + '@esbuild/win32-x64': 0.25.9 escalade@3.2.0: {} @@ -2921,7 +2934,7 @@ snapshots: fast-uri@3.0.6: {} - fdir@6.4.6(picomatch@4.0.3): + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 @@ -3467,30 +3480,31 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - rollup@4.46.1: + rollup@4.50.1: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@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 + '@rollup/rollup-android-arm-eabi': 4.50.1 + '@rollup/rollup-android-arm64': 4.50.1 + '@rollup/rollup-darwin-arm64': 4.50.1 + '@rollup/rollup-darwin-x64': 4.50.1 + '@rollup/rollup-freebsd-arm64': 4.50.1 + '@rollup/rollup-freebsd-x64': 4.50.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.50.1 + '@rollup/rollup-linux-arm-musleabihf': 4.50.1 + '@rollup/rollup-linux-arm64-gnu': 4.50.1 + '@rollup/rollup-linux-arm64-musl': 4.50.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.50.1 + '@rollup/rollup-linux-ppc64-gnu': 4.50.1 + '@rollup/rollup-linux-riscv64-gnu': 4.50.1 + '@rollup/rollup-linux-riscv64-musl': 4.50.1 + '@rollup/rollup-linux-s390x-gnu': 4.50.1 + '@rollup/rollup-linux-x64-gnu': 4.50.1 + '@rollup/rollup-linux-x64-musl': 4.50.1 + '@rollup/rollup-openharmony-arm64': 4.50.1 + '@rollup/rollup-win32-arm64-msvc': 4.50.1 + '@rollup/rollup-win32-ia32-msvc': 4.50.1 + '@rollup/rollup-win32-x64-msvc': 4.50.1 fsevents: 2.3.3 rrweb-cssom@0.8.0: {} @@ -3604,7 +3618,12 @@ snapshots: tinyglobby@0.2.14: dependencies: - fdir: 6.4.6(picomatch@4.0.3) + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 tinypool@1.1.1: {} @@ -3711,7 +3730,7 @@ snapshots: debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.1) + vite: 7.0.7(@types/node@22.16.5)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - jiti @@ -3726,25 +3745,25 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@7.0.6(@types/node@22.16.5)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@7.0.7(@types/node@22.16.5)(yaml@2.8.1)): dependencies: debug: 4.4.1 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.8.3) optionalDependencies: - vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.1) + vite: 7.0.7(@types/node@22.16.5)(yaml@2.8.1) transitivePeerDependencies: - supports-color - typescript - vite@7.0.6(@types/node@22.16.5)(yaml@2.8.1): + vite@7.0.7(@types/node@22.16.5)(yaml@2.8.1): dependencies: - esbuild: 0.25.8 - fdir: 6.4.6(picomatch@4.0.3) + esbuild: 0.25.9 + fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.46.1 - tinyglobby: 0.2.14 + rollup: 4.50.1 + tinyglobby: 0.2.15 optionalDependencies: '@types/node': 22.16.5 fsevents: 2.3.3 @@ -3759,7 +3778,7 @@ snapshots: dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@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.1)) + '@vitest/mocker': 3.2.4(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(vite@7.0.7(@types/node@22.16.5)(yaml@2.8.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -3777,7 +3796,7 @@ snapshots: tinyglobby: 0.2.14 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.1) + vite: 7.0.7(@types/node@22.16.5)(yaml@2.8.1) vite-node: 3.2.4(@types/node@22.16.5)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: From a6fb32b32be639f3e4a3e780847ded7def1e4e5b Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Thu, 11 Sep 2025 21:28:26 -0700 Subject: [PATCH 13/29] [Deps] Update TypeScript from `5.8.3` to `5.9.2` (#6548) --- package.json | 2 +- pnpm-lock.yaml | 84 +++++++++++++++++++++++++------------------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index 5a47b31ff14..3086ee85747 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "typedoc-github-theme": "^0.3.1", "typedoc-plugin-coverage": "^4.0.1", "typedoc-plugin-mdn-links": "^5.0.9", - "typescript": "^5.8.3", + "typescript": "^5.9.2", "vite": "^7.0.7", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0638e3ba49a..09747b23be3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,7 +19,7 @@ importers: version: 4.2.0 i18next: specifier: ^24.2.3 - version: 24.2.3(typescript@5.8.3) + version: 24.2.3(typescript@5.9.2) i18next-browser-languagedetector: specifier: ^8.2.0 version: 8.2.0 @@ -28,7 +28,7 @@ importers: version: 3.0.2 i18next-korean-postposition-processor: specifier: ^1.0.0 - version: 1.0.0(i18next@24.2.3(typescript@5.8.3)) + version: 1.0.0(i18next@24.2.3(typescript@5.9.2)) json-stable-stringify: specifier: ^1.3.0 version: 1.3.0 @@ -59,7 +59,7 @@ importers: version: 22.16.5 '@vitest/coverage-istanbul': specifier: ^3.2.4 - 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.1)) + 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.9.2))(yaml@2.8.1)) '@vitest/expect': specifier: ^3.2.4 version: 3.2.4 @@ -83,37 +83,37 @@ importers: version: 1.12.2 msw: specifier: ^2.10.4 - version: 2.10.4(@types/node@22.16.5)(typescript@5.8.3) + version: 2.10.4(@types/node@22.16.5)(typescript@5.9.2) phaser3spectorjs: specifier: ^0.0.8 version: 0.0.8 typedoc: specifier: 0.28.7 - version: 0.28.7(typescript@5.8.3) + version: 0.28.7(typescript@5.9.2) typedoc-github-theme: specifier: ^0.3.1 - version: 0.3.1(typedoc@0.28.7(typescript@5.8.3)) + version: 0.3.1(typedoc@0.28.7(typescript@5.9.2)) typedoc-plugin-coverage: specifier: ^4.0.1 - version: 4.0.1(typedoc@0.28.7(typescript@5.8.3)) + version: 4.0.1(typedoc@0.28.7(typescript@5.9.2)) typedoc-plugin-mdn-links: specifier: ^5.0.9 - version: 5.0.9(typedoc@0.28.7(typescript@5.8.3)) + version: 5.0.9(typedoc@0.28.7(typescript@5.9.2)) typescript: - specifier: ^5.8.3 - version: 5.8.3 + specifier: ^5.9.2 + version: 5.9.2 vite: specifier: ^7.0.7 version: 7.0.7(@types/node@22.16.5)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@7.0.7(@types/node@22.16.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@7.0.7(@types/node@22.16.5)(yaml@2.8.1)) vitest: specifier: ^3.2.4 - 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.1) + version: 3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.9.2))(yaml@2.8.1) vitest-canvas-mock: specifier: ^0.3.3 - 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.1)) + 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.9.2))(yaml@2.8.1)) packages: @@ -1835,8 +1835,8 @@ packages: peerDependencies: typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + typescript@5.9.2: + resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} engines: {node: '>=14.17'} hasBin: true @@ -2599,7 +2599,7 @@ snapshots: '@types/unist@3.0.3': {} - '@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.1))': + '@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.9.2))(yaml@2.8.1))': dependencies: '@istanbuljs/schema': 0.1.3 debug: 4.4.1 @@ -2611,7 +2611,7 @@ snapshots: magicast: 0.3.5 test-exclude: 7.0.1 tinyrainbow: 2.0.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.1) + vitest: 3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.9.2))(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -2623,13 +2623,13 @@ snapshots: chai: 5.2.1 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(vite@7.0.7(@types/node@22.16.5)(yaml@2.8.1))': + '@vitest/mocker@3.2.4(msw@2.10.4(@types/node@22.16.5)(typescript@5.9.2))(vite@7.0.7(@types/node@22.16.5)(yaml@2.8.1))': 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.5)(typescript@5.8.3) + msw: 2.10.4(@types/node@22.16.5)(typescript@5.9.2) vite: 7.0.7(@types/node@22.16.5)(yaml@2.8.1) '@vitest/pretty-format@3.2.4': @@ -3053,19 +3053,19 @@ snapshots: transitivePeerDependencies: - encoding - i18next-korean-postposition-processor@1.0.0(i18next@24.2.3(typescript@5.8.3)): + i18next-korean-postposition-processor@1.0.0(i18next@24.2.3(typescript@5.9.2)): dependencies: - i18next: 24.2.3(typescript@5.8.3) + i18next: 24.2.3(typescript@5.9.2) i18next@22.5.1: dependencies: '@babel/runtime': 7.28.2 - i18next@24.2.3(typescript@5.8.3): + i18next@24.2.3(typescript@5.9.2): dependencies: '@babel/runtime': 7.28.2 optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.2 iconv-lite@0.4.24: dependencies: @@ -3332,7 +3332,7 @@ snapshots: ms@2.1.3: {} - msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3): + msw@2.10.4(@types/node@22.16.5)(typescript@5.9.2): dependencies: '@bundled-es-modules/cookie': 2.0.1 '@bundled-es-modules/statuses': 1.0.1 @@ -3353,7 +3353,7 @@ snapshots: type-fest: 4.41.0 yargs: 17.7.2 optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - '@types/node' @@ -3659,9 +3659,9 @@ snapshots: dependencies: punycode: 2.3.1 - tsconfck@3.1.6(typescript@5.8.3): + tsconfck@3.1.6(typescript@5.9.2): optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.2 tsconfig-paths-webpack-plugin@4.2.0: dependencies: @@ -3682,28 +3682,28 @@ snapshots: type-fest@4.41.0: {} - typedoc-github-theme@0.3.1(typedoc@0.28.7(typescript@5.8.3)): + typedoc-github-theme@0.3.1(typedoc@0.28.7(typescript@5.9.2)): dependencies: - typedoc: 0.28.7(typescript@5.8.3) + typedoc: 0.28.7(typescript@5.9.2) - typedoc-plugin-coverage@4.0.1(typedoc@0.28.7(typescript@5.8.3)): + typedoc-plugin-coverage@4.0.1(typedoc@0.28.7(typescript@5.9.2)): dependencies: - typedoc: 0.28.7(typescript@5.8.3) + typedoc: 0.28.7(typescript@5.9.2) - typedoc-plugin-mdn-links@5.0.9(typedoc@0.28.7(typescript@5.8.3)): + typedoc-plugin-mdn-links@5.0.9(typedoc@0.28.7(typescript@5.9.2)): dependencies: - typedoc: 0.28.7(typescript@5.8.3) + typedoc: 0.28.7(typescript@5.9.2) - typedoc@0.28.7(typescript@5.8.3): + typedoc@0.28.7(typescript@5.9.2): dependencies: '@gerrit0/mini-shiki': 3.12.2 lunr: 2.3.9 markdown-it: 14.1.0 minimatch: 9.0.5 - typescript: 5.8.3 + typescript: 5.9.2 yaml: 2.8.1 - typescript@5.8.3: {} + typescript@5.9.2: {} uc.micro@2.1.0: {} @@ -3745,11 +3745,11 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@7.0.7(@types/node@22.16.5)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@7.0.7(@types/node@22.16.5)(yaml@2.8.1)): dependencies: debug: 4.4.1 globrex: 0.1.2 - tsconfck: 3.1.6(typescript@5.8.3) + tsconfck: 3.1.6(typescript@5.9.2) optionalDependencies: vite: 7.0.7(@types/node@22.16.5)(yaml@2.8.1) transitivePeerDependencies: @@ -3769,16 +3769,16 @@ snapshots: fsevents: 2.3.3 yaml: 2.8.1 - 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.1)): + 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.9.2))(yaml@2.8.1)): dependencies: jest-canvas-mock: 2.5.2 - 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.1) + vitest: 3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.9.2))(yaml@2.8.1) - 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.1): + vitest@3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.9.2))(yaml@2.8.1): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(vite@7.0.7(@types/node@22.16.5)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(msw@2.10.4(@types/node@22.16.5)(typescript@5.9.2))(vite@7.0.7(@types/node@22.16.5)(yaml@2.8.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 From c7a2c666af0009bb347616cefd9a767fb66b4b46 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Fri, 12 Sep 2025 14:53:27 -0500 Subject: [PATCH 14/29] [Refactor] Remove `isNullOrUndefined` in favor of loose check against null (#6549) * Remove `isNullOrUndefined` in favor of loose check against null * Fix missing method call * Remove isNullOrUndefined import --- src/battle-scene.ts | 19 +++-- src/data/abilities/ability.ts | 37 ++++------ src/data/balance/pokemon-evolutions.ts | 18 ++--- src/data/battle-anims.ts | 8 +- src/data/battler-tags.ts | 8 +- src/data/daily-run.ts | 6 +- src/data/moves/move-utils.ts | 12 +-- src/data/moves/move.ts | 30 ++++---- .../encounters/bug-type-superfan-encounter.ts | 14 ++-- .../encounters/dark-deal-encounter.ts | 4 +- .../encounters/fiery-fallout-encounter.ts | 4 +- .../global-trade-system-encounter.ts | 6 +- .../the-pokemon-salesman-encounter.ts | 8 +- .../encounters/training-session-encounter.ts | 4 +- .../encounters/uncommon-breed-encounter.ts | 4 +- .../encounters/weird-dream-encounter.ts | 16 ++-- .../mystery-encounter-option.ts | 4 +- .../mystery-encounter-requirements.ts | 73 +++++++----------- .../mystery-encounter-save-data.ts | 3 +- .../mystery-encounters/mystery-encounter.ts | 4 +- .../can-learn-move-requirement.ts | 4 +- .../utils/encounter-dialogue-utils.ts | 3 +- .../utils/encounter-phase-utils.ts | 28 +++---- .../utils/encounter-pokemon-utils.ts | 4 +- src/data/pokemon-species.ts | 10 +-- src/data/pokemon/pokemon-data.ts | 37 +++++----- src/data/trainers/trainer-config.ts | 74 +++++++++---------- src/field/arena.ts | 6 +- src/field/mystery-encounter-intro.ts | 9 +-- src/field/pokemon.ts | 31 ++++---- src/game-mode.ts | 6 +- src/modifier/init-modifier-pools.ts | 5 +- src/modifier/modifier-type.ts | 14 +--- src/modifier/modifier.ts | 11 +-- src/phases/faint-phase.ts | 3 +- src/phases/move-effect-phase.ts | 6 +- src/phases/mystery-encounter-phases.ts | 6 +- src/phases/pokemon-anim-phase.ts | 5 +- src/phases/revival-blessing-phase.ts | 8 +- src/phases/select-modifier-phase.ts | 4 +- src/phases/select-starter-phase.ts | 5 +- src/phases/stat-stage-change-phase.ts | 4 +- src/phases/title-phase.ts | 4 +- src/sprites/variant.ts | 3 +- src/system/ribbons/ribbon-methods.ts | 3 +- .../version-migration/versions/v1_0_4.ts | 5 +- .../version-migration/versions/v1_7_0.ts | 5 +- src/timed-event-manager.ts | 27 ++++--- src/ui/containers/pokedex-mon-container.ts | 9 +-- .../handlers/mystery-encounter-ui-handler.ts | 14 ++-- src/ui/handlers/pokedex-page-ui-handler.ts | 8 +- src/ui/handlers/pokedex-scan-ui-handler.ts | 3 +- .../handlers/save-slot-select-ui-handler.ts | 4 +- src/ui/handlers/starter-select-ui-handler.ts | 18 ++--- src/ui/handlers/summary-ui-handler.ts | 15 +--- src/ui/handlers/target-select-ui-handler.ts | 11 +-- src/ui/handlers/test-dialogue-ui-handler.ts | 7 +- src/utils/common.ts | 9 --- test/abilities/healer.test.ts | 3 +- test/eggs/egg.test.ts | 2 +- .../mystery-encounter/encounter-test-utils.ts | 5 +- test/test-utils/game-manager.ts | 5 +- 62 files changed, 315 insertions(+), 410 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index a8e8aa85121..74b44d324d7 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -138,7 +138,6 @@ import { formatMoney, getIvsFromId, isBetween, - isNullOrUndefined, NumberHolder, randomString, randSeedInt, @@ -867,7 +866,7 @@ export class BattleScene extends SceneBase { * this is weird and causes a lot of random jank */ getPokemonById(pokemonId: number | undefined): Pokemon | null { - if (isNullOrUndefined(pokemonId)) { + if (pokemonId == null) { return null; } @@ -1319,7 +1318,7 @@ export class BattleScene extends SceneBase { if ( !this.gameMode.hasTrainers || Overrides.BATTLE_TYPE_OVERRIDE === BattleType.WILD - || (Overrides.DISABLE_STANDARD_TRAINERS_OVERRIDE && isNullOrUndefined(trainerData)) + || (Overrides.DISABLE_STANDARD_TRAINERS_OVERRIDE && trainerData == null) ) { newBattleType = BattleType.WILD; } else { @@ -1383,7 +1382,7 @@ export class BattleScene extends SceneBase { newDouble = false; } - if (!isNullOrUndefined(Overrides.BATTLE_STYLE_OVERRIDE)) { + if (Overrides.BATTLE_STYLE_OVERRIDE != null) { let doubleOverrideForWave: "single" | "double" | null = null; switch (Overrides.BATTLE_STYLE_OVERRIDE) { @@ -1572,7 +1571,7 @@ export class BattleScene extends SceneBase { // Give trainers with specialty types an appropriately-typed form for Wormadam, Rotom, Arceus, Oricorio, Silvally, or Paldean Tauros. !isEggPhase && this.currentBattle?.battleType === BattleType.TRAINER - && !isNullOrUndefined(this.currentBattle.trainer) + && this.currentBattle.trainer != null && this.currentBattle.trainer.config.hasSpecialtyType() ) { if (species.speciesId === SpeciesId.WORMADAM) { @@ -2692,7 +2691,7 @@ export class BattleScene extends SceneBase { } } else if (modifier instanceof FusePokemonModifier) { args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon); - } else if (modifier instanceof RememberMoveModifier && !isNullOrUndefined(cost)) { + } else if (modifier instanceof RememberMoveModifier && cost != null) { args.push(cost); } @@ -3007,7 +3006,7 @@ export class BattleScene extends SceneBase { } if ( modifier instanceof PokemonHeldItemModifier - && !isNullOrUndefined(modifier.getSpecies()) + && modifier.getSpecies() != null && !this.getPokemonById(modifier.pokemonId)?.hasSpecies(modifier.getSpecies()!) ) { modifiers.splice(m--, 1); @@ -3573,7 +3572,7 @@ export class BattleScene extends SceneBase { // Loading override or session encounter let encounter: MysteryEncounter | null; if ( - !isNullOrUndefined(Overrides.MYSTERY_ENCOUNTER_OVERRIDE) + Overrides.MYSTERY_ENCOUNTER_OVERRIDE != null && allMysteryEncounters.hasOwnProperty(Overrides.MYSTERY_ENCOUNTER_OVERRIDE) ) { encounter = allMysteryEncounters[Overrides.MYSTERY_ENCOUNTER_OVERRIDE]; @@ -3584,7 +3583,7 @@ export class BattleScene extends SceneBase { encounter = allMysteryEncounters[encounterType ?? -1]; return encounter; } else { - encounter = !isNullOrUndefined(encounterType) ? allMysteryEncounters[encounterType] : null; + encounter = encounterType != null ? allMysteryEncounters[encounterType] : null; } // Check for queued encounters first @@ -3643,7 +3642,7 @@ export class BattleScene extends SceneBase { ? MysteryEncounterTier.ULTRA : MysteryEncounterTier.ROGUE; - if (!isNullOrUndefined(Overrides.MYSTERY_ENCOUNTER_TIER_OVERRIDE)) { + if (Overrides.MYSTERY_ENCOUNTER_TIER_OVERRIDE != null) { tier = Overrides.MYSTERY_ENCOUNTER_TIER_OVERRIDE; } diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index 8bb2f30b243..9e5bd8030d6 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -67,7 +67,6 @@ import type { Constructor } from "#utils/common"; import { BooleanHolder, coerceArray, - isNullOrUndefined, NumberHolder, randSeedFloat, randSeedInt, @@ -1040,7 +1039,7 @@ export class PostDefendStatStageChangeAbAttr extends PostDefendAbAttr { if (this.allOthers) { const ally = pokemon.getAlly(); - const otherPokemon = !isNullOrUndefined(ally) ? pokemon.getOpponents().concat([ally]) : pokemon.getOpponents(); + const otherPokemon = ally != null ? pokemon.getOpponents().concat([ally]) : pokemon.getOpponents(); for (const other of otherPokemon) { globalScene.phaseManager.unshiftNew( "StatStageChangePhase", @@ -1473,7 +1472,7 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr { override canApply({ move, opponent: attacker, pokemon }: PostMoveInteractionAbAttrParams): boolean { return ( - isNullOrUndefined(attacker.getTag(BattlerTagType.DISABLED)) + attacker.getTag(BattlerTagType.DISABLED) == null && move.doesFlagEffectApply({ flag: MoveFlags.MAKES_CONTACT, user: attacker, target: pokemon }) && (this.chance === -1 || pokemon.randBattleSeedInt(100) < this.chance) ); @@ -2810,7 +2809,7 @@ export class PostSummonAllyHealAbAttr extends PostSummonAbAttr { override apply({ pokemon, simulated }: AbAttrBaseParams): void { const target = pokemon.getAlly(); - if (!simulated && !isNullOrUndefined(target)) { + if (!simulated && target != null) { globalScene.phaseManager.unshiftNew( "PokemonHealPhase", target.getBattlerIndex(), @@ -2841,7 +2840,7 @@ export class PostSummonClearAllyStatStagesAbAttr extends PostSummonAbAttr { override apply({ pokemon, simulated }: AbAttrBaseParams): void { const target = pokemon.getAlly(); - if (!simulated && !isNullOrUndefined(target)) { + if (!simulated && target != null) { for (const s of BATTLE_STATS) { target.setStatStage(s, 0); } @@ -2960,13 +2959,13 @@ export class PostSummonHealStatusAbAttr extends PostSummonRemoveEffectAbAttr { public override canApply({ pokemon }: AbAttrBaseParams): boolean { const status = pokemon.status?.effect; - return !isNullOrUndefined(status) && (this.immuneEffects.length === 0 || this.immuneEffects.includes(status)); + return status != null && (this.immuneEffects.length === 0 || this.immuneEffects.includes(status)); } public override apply({ pokemon }: AbAttrBaseParams): void { // TODO: should probably check against simulated... const status = pokemon.status?.effect; - if (!isNullOrUndefined(status)) { + if (status != null) { this.statusHealed = status; pokemon.resetStatus(false); pokemon.updateInfo(); @@ -3102,7 +3101,7 @@ export class PostSummonCopyAllyStatsAbAttr extends PostSummonAbAttr { } const ally = pokemon.getAlly(); - return !(isNullOrUndefined(ally) || ally.getStatStages().every(s => s === 0)); + return !(ally == null || ally.getStatStages().every(s => s === 0)); } override apply({ pokemon, simulated }: AbAttrBaseParams): void { @@ -3110,7 +3109,7 @@ export class PostSummonCopyAllyStatsAbAttr extends PostSummonAbAttr { return; } const ally = pokemon.getAlly(); - if (!isNullOrUndefined(ally)) { + if (ally != null) { for (const s of BATTLE_STATS) { pokemon.setStatStage(s, ally.getStatStage(s)); } @@ -3240,7 +3239,7 @@ export class CommanderAbAttr extends AbAttr { const ally = pokemon.getAlly(); return ( globalScene.currentBattle?.double - && !isNullOrUndefined(ally) + && ally != null && ally.species.speciesId === SpeciesId.DONDOZO && !(ally.isFainted() || ally.getTag(BattlerTagType.COMMANDED)) ); @@ -3284,7 +3283,7 @@ export class PreSwitchOutResetStatusAbAttr extends PreSwitchOutAbAttr { } override canApply({ pokemon }: AbAttrBaseParams): boolean { - return !isNullOrUndefined(pokemon.status); + return pokemon.status != null; } override apply({ pokemon, simulated }: AbAttrBaseParams): void { @@ -3564,7 +3563,7 @@ export class ProtectStatAbAttr extends PreStatStageChangeAbAttr { } override canApply({ stat, cancelled }: PreStatStageChangeAbAttrParams): boolean { - return !cancelled.value && (isNullOrUndefined(this.protectedStat) || stat === this.protectedStat); + return !cancelled.value && (this.protectedStat == null || stat === this.protectedStat); } /** @@ -3800,11 +3799,7 @@ export class ConditionalUserFieldProtectStatAbAttr extends PreStatStageChangeAbA if (!target) { return false; } - return ( - !cancelled.value - && (isNullOrUndefined(this.protectedStat) || stat === this.protectedStat) - && this.condition(target) - ); + return !cancelled.value && (this.protectedStat == null || stat === this.protectedStat) && this.condition(target); } /** @@ -4561,7 +4556,7 @@ export class PostTurnStatusHealAbAttr extends PostTurnAbAttr { } override canApply({ pokemon }: AbAttrBaseParams): boolean { - return !isNullOrUndefined(pokemon.status) && this.effects.includes(pokemon.status.effect) && !pokemon.isFullHp(); + return pokemon.status != null && this.effects.includes(pokemon.status.effect) && !pokemon.isFullHp(); } override apply({ simulated, passive, pokemon }: AbAttrBaseParams): void { @@ -4896,7 +4891,7 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr { */ export class FetchBallAbAttr extends PostTurnAbAttr { override canApply({ simulated, pokemon }: AbAttrBaseParams): boolean { - return !simulated && !isNullOrUndefined(globalScene.currentBattle.lastUsedPokeball) && !!pokemon.isPlayer; + return !simulated && globalScene.currentBattle.lastUsedPokeball != null && !!pokemon.isPlayer; } /** @@ -6261,7 +6256,7 @@ class ForceSwitchOutHelper { true, 500, ); - if (globalScene.currentBattle.double && !isNullOrUndefined(allyPokemon)) { + if (globalScene.currentBattle.double && allyPokemon != null) { globalScene.redirectPokemonMoves(switchOutTarget, allyPokemon); } } @@ -7113,7 +7108,7 @@ export function initAbilities() { .attr(PostDefendMoveDisableAbAttr, 30) .bypassFaint(), new Ability(AbilityId.HEALER, 5) - .conditionalAttr(pokemon => !isNullOrUndefined(pokemon.getAlly()) && randSeedInt(10) < 3, PostTurnResetStatusAbAttr, true), + .conditionalAttr(pokemon => pokemon.getAlly() != null && randSeedInt(10) < 3, PostTurnResetStatusAbAttr, true), new Ability(AbilityId.FRIEND_GUARD, 5) .attr(AlliedFieldDamageReductionAbAttr, 0.75) .ignorable(), diff --git a/src/data/balance/pokemon-evolutions.ts b/src/data/balance/pokemon-evolutions.ts index d364dc036b1..fd88fc5da37 100644 --- a/src/data/balance/pokemon-evolutions.ts +++ b/src/data/balance/pokemon-evolutions.ts @@ -14,7 +14,7 @@ import { TimeOfDay } from "#enums/time-of-day"; import { WeatherType } from "#enums/weather-type"; import type { Pokemon } from "#field/pokemon"; import type { SpeciesStatBoosterItem, SpeciesStatBoosterModifierType } from "#modifiers/modifier-type"; -import { coerceArray, isNullOrUndefined, randSeedInt } from "#utils/common"; +import { coerceArray, randSeedInt } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import { toCamelCase } from "#utils/strings"; import i18next from "i18next"; @@ -128,7 +128,7 @@ export class SpeciesEvolutionCondition { } public get description(): string[] { - if (!isNullOrUndefined(this.desc)) { + if (this.desc != null) { return this.desc; } this.desc = this.data.map(cond => { @@ -161,7 +161,7 @@ export class SpeciesEvolutionCondition { case EvoCondKey.HELD_ITEM: return i18next.t(`pokemonEvolutions:heldItem.${toCamelCase(cond.itemKey)}`); } - }).filter(s => !isNullOrUndefined(s)); // Filter out stringless conditions + }).filter(s => s != null); // Filter out stringless conditions return this.desc; } @@ -233,7 +233,7 @@ export class SpeciesFormEvolution { this.evoFormKey = evoFormKey; this.level = level; this.item = item || EvolutionItem.NONE; - if (!isNullOrUndefined(condition)) { + if (condition != null) { this.condition = new SpeciesEvolutionCondition(...coerceArray(condition)); } this.wildDelay = wildDelay ?? SpeciesWildEvolutionDelay.NONE; @@ -291,8 +291,8 @@ export class SpeciesFormEvolution { return ( pokemon.level >= this.level && // Check form key, using the fusion's form key if we're checking the fusion - (isNullOrUndefined(this.preFormKey) || (forFusion ? pokemon.getFusionFormKey() : pokemon.getFormKey()) === this.preFormKey) && - (isNullOrUndefined(this.condition) || this.condition.conditionsFulfilled(pokemon)) && + (this.preFormKey == null || (forFusion ? pokemon.getFusionFormKey() : pokemon.getFormKey()) === this.preFormKey) && + (this.condition == null || this.condition.conditionsFulfilled(pokemon)) && ((item ?? EvolutionItem.NONE) === (this.item ?? EvolutionItem.NONE)) ); } @@ -305,11 +305,11 @@ export class SpeciesFormEvolution { */ public isValidItemEvolution(pokemon: Pokemon, forFusion = false): boolean { return ( - !isNullOrUndefined(this.item) && + this.item != null && pokemon.level >= this.level && // Check form key, using the fusion's form key if we're checking the fusion - (isNullOrUndefined(this.preFormKey) || (forFusion ? pokemon.getFusionFormKey() : pokemon.getFormKey()) === this.preFormKey) && - (isNullOrUndefined(this.condition) || this.condition.conditionsFulfilled(pokemon)) + (this.preFormKey == null || (forFusion ? pokemon.getFusionFormKey() : pokemon.getFormKey()) === this.preFormKey) && + (this.condition == null || this.condition.conditionsFulfilled(pokemon)) ); } diff --git a/src/data/battle-anims.ts b/src/data/battle-anims.ts index 1dcb7d7eebf..573a1730796 100644 --- a/src/data/battle-anims.ts +++ b/src/data/battle-anims.ts @@ -7,7 +7,7 @@ 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 { coerceArray, getFrameMs, isNullOrUndefined, type nil } from "#utils/common"; +import { coerceArray, getFrameMs, type nil } from "#utils/common"; import { getEnumKeys, getEnumValues } from "#utils/enums"; import { toKebabCase } from "#utils/strings"; import Phaser from "phaser"; @@ -388,7 +388,7 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent { moveAnim.bgSprite.setAlpha(this.opacity / 255); globalScene.field.add(moveAnim.bgSprite); const fieldPokemon = globalScene.getEnemyPokemon(false) ?? globalScene.getPlayerPokemon(false); - if (!isNullOrUndefined(priority)) { + if (priority != null) { globalScene.field.moveTo(moveAnim.bgSprite as Phaser.GameObjects.GameObject, priority); } else if (fieldPokemon?.isOnField()) { globalScene.field.moveBelow(moveAnim.bgSprite as Phaser.GameObjects.GameObject, fieldPokemon); @@ -524,7 +524,7 @@ export async function initEncounterAnims(encounterAnim: EncounterAnim | Encounte const encounterAnimNames = getEnumKeys(EncounterAnim); const encounterAnimFetches: Promise>[] = []; for (const anim of anims) { - if (encounterAnims.has(anim) && !isNullOrUndefined(encounterAnims.get(anim))) { + if (encounterAnims.has(anim) && encounterAnims.get(anim) != null) { continue; } encounterAnimFetches.push( @@ -1240,7 +1240,7 @@ export abstract class BattleAnim { const graphicIndex = graphicFrameCount++; const moveSprite = sprites[graphicIndex]; - if (!isNullOrUndefined(frame.priority)) { + if (frame.priority != null) { const setSpritePriority = (priority: number) => { if (existingFieldSprites.length > priority) { // Move to specified priority index diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index c495cdaa604..711a2bd0b44 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -49,7 +49,7 @@ import type { TypeBoostTagType, } from "#types/battler-tags"; import type { Mutable } from "#types/type-helpers"; -import { BooleanHolder, coerceArray, getFrameMs, isNullOrUndefined, NumberHolder, toDmgValue } from "#utils/common"; +import { BooleanHolder, coerceArray, getFrameMs, NumberHolder, toDmgValue } from "#utils/common"; import { toCamelCase } from "#utils/strings"; /** @@ -378,7 +378,7 @@ export class DisabledTag extends MoveRestrictionBattlerTag { // Disable fails against struggle or an empty move history // TODO: Confirm if this is redundant given Disable/Cursed Body's disable conditions const move = pokemon.getLastNonVirtualMove(); - if (isNullOrUndefined(move) || move.move === MoveId.STRUGGLE) { + if (move == null || move.move === MoveId.STRUGGLE) { return; } @@ -451,7 +451,7 @@ export class GorillaTacticsTag extends MoveRestrictionBattlerTag { override canAdd(pokemon: Pokemon): boolean { // Choice items ignore struggle, so Gorilla Tactics should too const lastSelectedMove = pokemon.getLastNonVirtualMove(); - return !isNullOrUndefined(lastSelectedMove) && lastSelectedMove.move !== MoveId.STRUGGLE; + return lastSelectedMove != null && lastSelectedMove.move !== MoveId.STRUGGLE; } /** @@ -1305,7 +1305,7 @@ export class EncoreTag extends MoveRestrictionBattlerTag { override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { if (lapseType === BattlerTagLapseType.CUSTOM) { const encoredMove = pokemon.getMoveset().find(m => m.moveId === this.moveId); - return !isNullOrUndefined(encoredMove) && encoredMove.getPpRatio() > 0; + return encoredMove != null && encoredMove.getPpRatio() > 0; } return super.lapse(pokemon, lapseType); } diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index addaebdd238..5f49b9adbb0 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -7,7 +7,7 @@ import { BiomeId } from "#enums/biome-id"; import { PartyMemberStrength } from "#enums/party-member-strength"; import { SpeciesId } from "#enums/species-id"; import type { Starter } from "#ui/starter-select-ui-handler"; -import { isNullOrUndefined, randSeedGauss, randSeedInt, randSeedItem } from "#utils/common"; +import { randSeedGauss, randSeedInt, randSeedItem } from "#utils/common"; import { getEnumValues } from "#utils/enums"; import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; @@ -32,7 +32,7 @@ export function getDailyRunStarters(seed: string): Starter[] { const startingLevel = globalScene.gameMode.getStartingLevel(); const eventStarters = getDailyEventSeedStarters(seed); - if (!isNullOrUndefined(eventStarters)) { + if (eventStarters != null) { starters.push(...eventStarters); return; } @@ -127,7 +127,7 @@ const dailyBiomeWeights: BiomeWeights = { export function getDailyStartingBiome(): BiomeId { const eventBiome = getDailyEventSeedBiome(globalScene.seed); - if (!isNullOrUndefined(eventBiome)) { + if (eventBiome != null) { return eventBiome; } diff --git a/src/data/moves/move-utils.ts b/src/data/moves/move-utils.ts index eedeea53087..1fe0880317b 100644 --- a/src/data/moves/move-utils.ts +++ b/src/data/moves/move-utils.ts @@ -7,7 +7,7 @@ import { PokemonType } from "#enums/pokemon-type"; import type { Pokemon } from "#field/pokemon"; import { applyMoveAttrs } from "#moves/apply-attrs"; import type { Move, MoveTargetSet, UserMoveConditionFunc } from "#moves/move"; -import { isNullOrUndefined, NumberHolder } from "#utils/common"; +import { NumberHolder } from "#utils/common"; /** * Return whether the move targets the field @@ -78,7 +78,7 @@ export function getMoveTargets(user: Pokemon, move: MoveId, replaceTarget?: Move case MoveTarget.OTHER: case MoveTarget.ALL_NEAR_OTHERS: case MoveTarget.ALL_OTHERS: - set = !isNullOrUndefined(ally) ? opponents.concat([ally]) : opponents; + set = ally != null ? opponents.concat([ally]) : opponents; multiple = moveTarget === MoveTarget.ALL_NEAR_OTHERS || moveTarget === MoveTarget.ALL_OTHERS; break; case MoveTarget.NEAR_ENEMY: @@ -95,22 +95,22 @@ export function getMoveTargets(user: Pokemon, move: MoveId, replaceTarget?: Move return { targets: [-1 as BattlerIndex], multiple: false }; case MoveTarget.NEAR_ALLY: case MoveTarget.ALLY: - set = !isNullOrUndefined(ally) ? [ally] : []; + set = ally != null ? [ally] : []; break; case MoveTarget.USER_OR_NEAR_ALLY: case MoveTarget.USER_AND_ALLIES: case MoveTarget.USER_SIDE: - set = !isNullOrUndefined(ally) ? [user, ally] : [user]; + set = ally != null ? [user, ally] : [user]; multiple = moveTarget !== MoveTarget.USER_OR_NEAR_ALLY; break; case MoveTarget.ALL: case MoveTarget.BOTH_SIDES: - set = (!isNullOrUndefined(ally) ? [user, ally] : [user]).concat(opponents); + set = (ally != null ? [user, ally] : [user]).concat(opponents); multiple = true; break; case MoveTarget.CURSE: { - const extraTargets = !isNullOrUndefined(ally) ? [ally] : []; + const extraTargets = ally != null ? [ally] : []; set = user.getTypes(true).includes(PokemonType.GHOST) ? opponents.concat(extraTargets) : [user]; } break; diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index 19d145a36d5..91d61c15b8b 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -88,7 +88,7 @@ import type { AttackMoveResult } from "#types/attack-move-result"; import type { Localizable } from "#types/locales"; import type { ChargingMove, MoveAttrMap, MoveAttrString, MoveClassMap, MoveKindString, MoveMessageFunc } from "#types/move-types"; import type { TurnMove } from "#types/turn-move"; -import { BooleanHolder, coerceArray, type Constructor, isNullOrUndefined, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common"; +import { BooleanHolder, coerceArray, type Constructor, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common"; import { getEnumValues } from "#utils/enums"; import { toCamelCase, toTitleCase } from "#utils/strings"; import i18next from "i18next"; @@ -835,7 +835,7 @@ export abstract class Move implements Localizable { applyAbAttrs("VariableMovePowerAbAttr", abAttrParams); const ally = source.getAlly(); - if (!isNullOrUndefined(ally)) { + if (ally != null) { applyAbAttrs("AllyMoveCategoryPowerBoostAbAttr", {...abAttrParams, pokemon: ally}); } @@ -965,7 +965,7 @@ export abstract class Move implements Localizable { // ...and cannot enhance Pollen Puff when targeting an ally. const ally = user.getAlly(); - const exceptPollenPuffAlly: boolean = this.id === MoveId.POLLEN_PUFF && !isNullOrUndefined(ally) && targets.includes(ally.getBattlerIndex()) + const exceptPollenPuffAlly: boolean = this.id === MoveId.POLLEN_PUFF && ally != null && targets.includes(ally.getBattlerIndex()) return (!restrictSpread || !isMultiTarget) && !this.isChargingMove() @@ -2114,7 +2114,7 @@ export class FlameBurstAttr extends MoveEffectAttr { const targetAlly = target.getAlly(); const cancelled = new BooleanHolder(false); - if (!isNullOrUndefined(targetAlly)) { + if (targetAlly != null) { applyAbAttrs("BlockNonDirectDamageAbAttr", {pokemon: targetAlly, cancelled}); } @@ -2127,7 +2127,7 @@ export class FlameBurstAttr extends MoveEffectAttr { } getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number { - return !isNullOrUndefined(target.getAlly()) ? -5 : 0; + return target.getAlly() != null ? -5 : 0; } } @@ -3156,7 +3156,7 @@ export class WeatherInstantChargeAttr extends InstantChargeAttr { super((user, move) => { const currentWeather = globalScene.arena.weather; - if (isNullOrUndefined(currentWeather?.weatherType)) { + if (currentWeather?.weatherType == null) { return false; } else { return !currentWeather?.isEffectSuppressed() @@ -6293,7 +6293,7 @@ export class RevivalBlessingAttr extends MoveEffectAttr { pokemon.heal(Math.min(toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp())); globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:revivalBlessing", { pokemonName: getPokemonNameWithAffix(pokemon) }), 0, true); const allyPokemon = user.getAlly(); - if (globalScene.currentBattle.double && globalScene.getEnemyParty().length > 1 && !isNullOrUndefined(allyPokemon)) { + if (globalScene.currentBattle.double && globalScene.getEnemyParty().length > 1 && allyPokemon != null) { // Handle cases where revived pokemon needs to get switched in on same turn if (allyPokemon.isFainted() || allyPokemon === pokemon) { // Enemy switch phase should be removed and replaced with the revived pkmn switching in @@ -6462,7 +6462,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500); // in double battles redirect potential moves off fled pokemon - if (globalScene.currentBattle.double && !isNullOrUndefined(allyPokemon)) { + if (globalScene.currentBattle.double && allyPokemon != null) { globalScene.redirectPokemonMoves(switchOutTarget, allyPokemon); } } @@ -7122,7 +7122,7 @@ export class CopyMoveAttr extends CallMoveAttr { getCondition(): MoveConditionFunc { return (_user, target, _move) => { const lastMove = this.mirrorMove ? target.getLastNonVirtualMove(false, false)?.move : globalScene.currentBattle.lastMove; - return !isNullOrUndefined(lastMove) && !this.invalidMoves.has(lastMove); + return lastMove != null && !this.invalidMoves.has(lastMove); }; } } @@ -7169,7 +7169,7 @@ export class RepeatMoveAttr extends MoveEffectAttr { && firstTarget !== target.getAlly() ) { const ally = firstTarget.getAlly(); - if (!isNullOrUndefined(ally) && ally.isActive()) { + if (ally != null && ally.isActive()) { moveTargets = [ ally.getBattlerIndex() ]; } } @@ -7476,7 +7476,7 @@ export class SketchAttr extends MoveEffectAttr { } const targetMove = target.getLastNonVirtualMove(); - return !isNullOrUndefined(targetMove) + return targetMove != null && !invalidSketchMoves.has(targetMove.move) && user.getMoveset().every(m => m.moveId !== targetMove.move) }; @@ -7533,7 +7533,7 @@ export class AbilityCopyAttr extends MoveEffectAttr { user.setTempAbility(target.getAbility()); const ally = user.getAlly(); - if (this.copyToPartner && globalScene.currentBattle?.double && !isNullOrUndefined(ally) && ally.hp) { // TODO is this the best way to check that the ally is active? + if (this.copyToPartner && globalScene.currentBattle?.double && ally != null && ally.hp) { // TODO is this the best way to check that the ally is active? globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", { pokemonName: getPokemonNameWithAffix(ally), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name })); ally.setTempAbility(target.getAbility()); } @@ -8054,7 +8054,7 @@ const failIfGhostTypeCondition: MoveConditionFunc = (user: Pokemon, target: Poke const failIfNoTargetHeldItemsCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => target.getHeldItems().filter(i => i.isTransferable)?.length > 0; const attackedByItemMessageFunc = (user: Pokemon, target: Pokemon, move: Move) => { - if (isNullOrUndefined(target)) { // Fix bug when used against targets that have both fainted + if (target == null) { // Fix bug when used against targets that have both fainted return ""; } const heldItems = target.getHeldItems().filter(i => i.isTransferable); @@ -8611,7 +8611,7 @@ export function initMoves() { .attr(AddBattlerTagAttr, BattlerTagType.DISABLED, false, true) .condition((_user, target, _move) => { const lastNonVirtualMove = target.getLastNonVirtualMove(); - return !isNullOrUndefined(lastNonVirtualMove) && lastNonVirtualMove.move !== MoveId.STRUGGLE; + return lastNonVirtualMove != null && lastNonVirtualMove.move !== MoveId.STRUGGLE; }) .ignoresSubstitute() .reflectable(), @@ -9955,7 +9955,7 @@ export function initMoves() { .condition(failOnGravityCondition) .condition((_user, target, _move) => ![ SpeciesId.DIGLETT, SpeciesId.DUGTRIO, SpeciesId.ALOLA_DIGLETT, SpeciesId.ALOLA_DUGTRIO, SpeciesId.SANDYGAST, SpeciesId.PALOSSAND, SpeciesId.WIGLETT, SpeciesId.WUGTRIO ].includes(target.species.speciesId)) .condition((_user, target, _move) => !(target.species.speciesId === SpeciesId.GENGAR && target.getFormKey() === "mega")) - .condition((_user, target, _move) => isNullOrUndefined(target.getTag(BattlerTagType.INGRAIN)) && isNullOrUndefined(target.getTag(BattlerTagType.IGNORE_FLYING))) + .condition((_user, target, _move) => target.getTag(BattlerTagType.INGRAIN) == null && target.getTag(BattlerTagType.IGNORE_FLYING) == null) .attr(AddBattlerTagAttr, BattlerTagType.TELEKINESIS, false, true, 3) .attr(AddBattlerTagAttr, BattlerTagType.FLOATING, false, true, 3) .reflectable(), diff --git a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts index cb34190a584..00e98048ada 100644 --- a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts +++ b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts @@ -48,7 +48,7 @@ import { getRandomPartyMemberFunc, trainerConfigs } from "#trainers/trainer-conf import { TrainerPartyCompoundTemplate, TrainerPartyTemplate } from "#trainers/trainer-party-template"; import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; import { MoveInfoOverlay } from "#ui/move-info-overlay"; -import { isNullOrUndefined, randSeedInt, randSeedShuffle } from "#utils/common"; +import { randSeedInt, randSeedShuffle } from "#utils/common"; import i18next from "i18next"; /** the i18n namespace for the encounter */ @@ -571,7 +571,7 @@ function getTrainerConfigForWave(waveIndex: number) { .setPartyMemberFunc( 4, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => { - if (!isNullOrUndefined(pool3Mon.formIndex)) { + if (pool3Mon.formIndex != null) { p.formIndex = pool3Mon.formIndex; p.generateAndPopulateMoveset(); p.generateName(); @@ -603,7 +603,7 @@ function getTrainerConfigForWave(waveIndex: number) { .setPartyMemberFunc( 3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => { - if (!isNullOrUndefined(pool3Mon.formIndex)) { + if (pool3Mon.formIndex != null) { p.formIndex = pool3Mon.formIndex; p.generateAndPopulateMoveset(); p.generateName(); @@ -613,7 +613,7 @@ function getTrainerConfigForWave(waveIndex: number) { .setPartyMemberFunc( 4, getRandomPartyMemberFunc([pool3Mon2.species], TrainerSlot.TRAINER, true, p => { - if (!isNullOrUndefined(pool3Mon2.formIndex)) { + if (pool3Mon2.formIndex != null) { p.formIndex = pool3Mon2.formIndex; p.generateAndPopulateMoveset(); p.generateName(); @@ -648,7 +648,7 @@ function getTrainerConfigForWave(waveIndex: number) { .setPartyMemberFunc( 3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => { - if (!isNullOrUndefined(pool3Mon.formIndex)) { + if (pool3Mon.formIndex != null) { p.formIndex = pool3Mon.formIndex; p.generateAndPopulateMoveset(); p.generateName(); @@ -687,7 +687,7 @@ function getTrainerConfigForWave(waveIndex: number) { .setPartyMemberFunc( 2, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => { - if (!isNullOrUndefined(pool3Mon.formIndex)) { + if (pool3Mon.formIndex != null) { p.formIndex = pool3Mon.formIndex; p.generateAndPopulateMoveset(); p.generateName(); @@ -697,7 +697,7 @@ function getTrainerConfigForWave(waveIndex: number) { .setPartyMemberFunc( 3, getRandomPartyMemberFunc([pool3Mon2.species], TrainerSlot.TRAINER, true, p => { - if (!isNullOrUndefined(pool3Mon2.formIndex)) { + if (pool3Mon2.formIndex != null) { p.formIndex = pool3Mon2.formIndex; p.generateAndPopulateMoveset(); p.generateName(); diff --git a/src/data/mystery-encounters/encounters/dark-deal-encounter.ts b/src/data/mystery-encounters/encounters/dark-deal-encounter.ts index 65d22bfc6de..426eafb5e67 100644 --- a/src/data/mystery-encounters/encounters/dark-deal-encounter.ts +++ b/src/data/mystery-encounters/encounters/dark-deal-encounter.ts @@ -15,7 +15,7 @@ import { getRandomPlayerPokemon, getRandomSpeciesByStarterCost } from "#mystery- import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter"; import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter"; import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option"; -import { isNullOrUndefined, randSeedInt } from "#utils/common"; +import { randSeedInt } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; /** i18n namespace for encounter */ @@ -192,7 +192,7 @@ export const DarkDealEncounter: MysteryEncounter = MysteryEncounterBuilder.withE }; }), }; - if (!isNullOrUndefined(bossSpecies.forms) && bossSpecies.forms.length > 0) { + if (bossSpecies.forms != null && bossSpecies.forms.length > 0) { pokemonConfig.formIndex = 0; } const config: EnemyPartyConfig = { diff --git a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts index 1cc31eaa21f..0f37a1fae94 100644 --- a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts +++ b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts @@ -45,7 +45,7 @@ import { TypeRequirement, } from "#mystery-encounters/mystery-encounter-requirements"; import { FIRE_RESISTANT_ABILITIES } from "#mystery-encounters/requirement-groups"; -import { isNullOrUndefined, randSeedInt } from "#utils/common"; +import { randSeedInt } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; /** the i18n namespace for the encounter */ @@ -238,7 +238,7 @@ export const FieryFalloutEncounter: MysteryEncounter = MysteryEncounterBuilder.w // Burn random member const burnable = nonFireTypes.filter( - p => isNullOrUndefined(p.status) || isNullOrUndefined(p.status.effect) || p.status.effect === StatusEffect.NONE, + p => p.status == null || p.status.effect == null || p.status.effect === StatusEffect.NONE, ); if (burnable?.length > 0) { const roll = randSeedInt(burnable.length); 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 823f016029e..e2166e99f6a 100644 --- a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts +++ b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts @@ -43,7 +43,7 @@ import { PartySizeRequirement } from "#mystery-encounters/mystery-encounter-requ import { PokemonData } from "#system/pokemon-data"; import { MusicPreference } from "#system/settings"; import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; -import { isNullOrUndefined, NumberHolder, randInt, randSeedInt, randSeedItem, randSeedShuffle } from "#utils/common"; +import { NumberHolder, randInt, randSeedInt, randSeedItem, randSeedShuffle } from "#utils/common"; import { getEnumKeys } from "#utils/enums"; import { getRandomLocaleEntry } from "#utils/i18n"; import { getPokemonSpecies } from "#utils/pokemon-utils"; @@ -537,7 +537,7 @@ function generateTradeOption(alreadyUsedSpecies: PokemonSpecies[], originalBst?: bstCap = originalBst + 100; bstMin = originalBst - 100; } - while (isNullOrUndefined(newSpecies)) { + while (newSpecies == null) { // Get all non-legendary species that fall within the Bst range requirements let validSpecies = allSpecies.filter(s => { const isLegendaryOrMythical = s.legendary || s.subLegendary || s.mythical; @@ -550,7 +550,7 @@ function generateTradeOption(alreadyUsedSpecies: PokemonSpecies[], originalBst?: if (validSpecies?.length > 20) { validSpecies = randSeedShuffle(validSpecies); newSpecies = validSpecies.pop(); - while (isNullOrUndefined(newSpecies) || alreadyUsedSpecies.includes(newSpecies)) { + while (newSpecies == null || alreadyUsedSpecies.includes(newSpecies)) { newSpecies = validSpecies.pop(); } } else { diff --git a/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts b/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts index 292c866c0ee..51efa0c7586 100644 --- a/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts @@ -28,7 +28,7 @@ import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter"; import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option"; import { MoneyRequirement } from "#mystery-encounters/mystery-encounter-requirements"; import { PokemonData } from "#system/pokemon-data"; -import { isNullOrUndefined, randSeedInt, randSeedItem } from "#utils/common"; +import { randSeedInt, randSeedItem } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; /** the i18n namespace for this encounter */ @@ -81,7 +81,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui let tries = 0; // Reroll any species that don't have HAs - while ((isNullOrUndefined(species.abilityHidden) || species.abilityHidden === AbilityId.NONE) && tries < 5) { + while ((species.abilityHidden == null || species.abilityHidden === AbilityId.NONE) && tries < 5) { species = getSalesmanSpeciesOffer(); tries++; } @@ -110,7 +110,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui */ if ( r === 0 - || ((isNullOrUndefined(species.abilityHidden) || species.abilityHidden === AbilityId.NONE) + || ((species.abilityHidden == null || species.abilityHidden === AbilityId.NONE) && validEventEncounters.length === 0) ) { // If you roll 1%, give shiny Magikarp with random variant @@ -118,7 +118,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui pokemon = new PlayerPokemon(species, 5, 2, undefined, undefined, true); } else if ( validEventEncounters.length > 0 - && (r <= EVENT_THRESHOLD || isNullOrUndefined(species.abilityHidden) || species.abilityHidden === AbilityId.NONE) + && (r <= EVENT_THRESHOLD || species.abilityHidden == null || species.abilityHidden === AbilityId.NONE) ) { tries = 0; do { diff --git a/src/data/mystery-encounters/encounters/training-session-encounter.ts b/src/data/mystery-encounters/encounters/training-session-encounter.ts index 033a54cc5f5..1f3778a5d2c 100644 --- a/src/data/mystery-encounters/encounters/training-session-encounter.ts +++ b/src/data/mystery-encounters/encounters/training-session-encounter.ts @@ -28,7 +28,7 @@ import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encou import { PokemonData } from "#system/pokemon-data"; import type { HeldModifierConfig } from "#types/held-modifier-config"; import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; -import { isNullOrUndefined, randSeedShuffle } from "#utils/common"; +import { randSeedShuffle } from "#utils/common"; import { getEnumValues } from "#utils/enums"; import i18next from "i18next"; @@ -324,7 +324,7 @@ export const TrainingSessionEncounter: MysteryEncounter = MysteryEncounterBuilde // Only update the fusion's dex data if the Pokemon is already caught in dex (ignore rentals) const rootFusionSpecies = playerPokemon.fusionSpecies?.getRootSpeciesId(); if ( - !isNullOrUndefined(rootFusionSpecies) + rootFusionSpecies != null && speciesStarterCosts.hasOwnProperty(rootFusionSpecies) && !!globalScene.gameData.dexData[rootFusionSpecies].caughtAttr ) { diff --git a/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts b/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts index 7bbc4a57757..cd61a6852f7 100644 --- a/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts +++ b/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts @@ -32,7 +32,7 @@ import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encou import { MoveRequirement, PersistentModifierRequirement } from "#mystery-encounters/mystery-encounter-requirements"; import { CHARMING_MOVES } from "#mystery-encounters/requirement-groups"; import { PokemonData } from "#system/pokemon-data"; -import { isNullOrUndefined, randSeedInt } from "#utils/common"; +import { randSeedInt } from "#utils/common"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounters/uncommonBreed"; @@ -167,7 +167,7 @@ export const UncommonBreedEncounter: MysteryEncounter = MysteryEncounterBuilder. const encounter = globalScene.currentBattle.mysteryEncounter!; const eggMove = encounter.misc.eggMove; - if (!isNullOrUndefined(eggMove)) { + if (eggMove != null) { // Check what type of move the egg move is to determine target const pokemonMove = new PokemonMove(eggMove); const move = pokemonMove.getMove(); diff --git a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts index 1fcbd2961d1..abd81fb92ea 100644 --- a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts +++ b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts @@ -41,7 +41,7 @@ import { PokemonData } from "#system/pokemon-data"; import { trainerConfigs } from "#trainers/trainer-config"; import { TrainerPartyTemplate } from "#trainers/trainer-party-template"; import type { HeldModifierConfig } from "#types/held-modifier-config"; -import { isNullOrUndefined, NumberHolder, randSeedInt, randSeedShuffle } from "#utils/common"; +import { NumberHolder, randSeedInt, randSeedShuffle } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; /** i18n namespace for encounter */ @@ -634,7 +634,7 @@ function getTransformedSpecies( alreadyUsedSpecies: PokemonSpecies[], ): PokemonSpecies { let newSpecies: PokemonSpecies | undefined; - while (isNullOrUndefined(newSpecies)) { + while (newSpecies == null) { const bstCap = originalBst + bstSearchRange[1]; const bstMin = Math.max(originalBst + bstSearchRange[0], 0); @@ -655,7 +655,7 @@ function getTransformedSpecies( if (validSpecies?.length > 20) { validSpecies = randSeedShuffle(validSpecies); newSpecies = validSpecies.pop(); - while (isNullOrUndefined(newSpecies) || alreadyUsedSpecies.includes(newSpecies)) { + while (newSpecies == null || alreadyUsedSpecies.includes(newSpecies)) { newSpecies = validSpecies.pop(); } } else { @@ -771,12 +771,12 @@ async function addEggMoveToNewPokemonMoveset( if (eggMoves) { const eggMoveIndices = randSeedShuffle([0, 1, 2, 3]); let randomEggMoveIndex = eggMoveIndices.pop(); - let randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null; + let randomEggMove = randomEggMoveIndex != null ? eggMoves[randomEggMoveIndex] : null; let retries = 0; while (retries < 3 && (!randomEggMove || newPokemon.moveset.some(m => m.moveId === randomEggMove))) { // If Pokemon already knows this move, roll for another egg move randomEggMoveIndex = eggMoveIndices.pop(); - randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null; + randomEggMove = randomEggMoveIndex != null ? eggMoves[randomEggMoveIndex] : null; retries++; } @@ -791,11 +791,7 @@ async function addEggMoveToNewPokemonMoveset( } // For pokemon that the player owns (including ones just caught), unlock the egg move - if ( - !forBattle - && !isNullOrUndefined(randomEggMoveIndex) - && !!globalScene.gameData.dexData[speciesRootForm].caughtAttr - ) { + if (!forBattle && randomEggMoveIndex != null && !!globalScene.gameData.dexData[speciesRootForm].caughtAttr) { await globalScene.gameData.setEggMoveUnlocked(getPokemonSpecies(speciesRootForm), randomEggMoveIndex, true); } } diff --git a/src/data/mystery-encounters/mystery-encounter-option.ts b/src/data/mystery-encounters/mystery-encounter-option.ts index fc7bb15d343..1b3b260414d 100644 --- a/src/data/mystery-encounters/mystery-encounter-option.ts +++ b/src/data/mystery-encounters/mystery-encounter-option.ts @@ -12,7 +12,7 @@ import { MoneyRequirement, TypeRequirement, } from "#mystery-encounters/mystery-encounter-requirements"; -import { isNullOrUndefined, randSeedInt } from "#utils/common"; +import { randSeedInt } from "#utils/common"; // biome-ignore lint/suspicious/noConfusingVoidType: void unions in callbacks are OK export type OptionPhaseCallback = () => Promise; @@ -62,7 +62,7 @@ export class MysteryEncounterOption implements IMysteryEncounterOption { onPostOptionPhase?: OptionPhaseCallback; constructor(option: IMysteryEncounterOption | null) { - if (!isNullOrUndefined(option)) { + if (option != null) { Object.assign(this, option); } this.hasDexProgress = this.hasDexProgress ?? false; diff --git a/src/data/mystery-encounters/mystery-encounter-requirements.ts b/src/data/mystery-encounters/mystery-encounter-requirements.ts index f20d513419e..85906044b77 100644 --- a/src/data/mystery-encounters/mystery-encounter-requirements.ts +++ b/src/data/mystery-encounters/mystery-encounter-requirements.ts @@ -15,7 +15,7 @@ import { WeatherType } from "#enums/weather-type"; import type { PlayerPokemon } from "#field/pokemon"; import { AttackTypeBoosterModifier } from "#modifiers/modifier"; import type { AttackTypeBoosterModifierType } from "#modifiers/modifier-type"; -import { coerceArray, isNullOrUndefined } from "#utils/common"; +import { coerceArray } from "#utils/common"; export interface EncounterRequirement { meetsRequirement(): boolean; // Boolean to see if a requirement is met @@ -219,7 +219,7 @@ export class WaveRangeRequirement extends EncounterSceneRequirement { } override meetsRequirement(): boolean { - if (!isNullOrUndefined(this.waveRange) && this.waveRange[0] <= this.waveRange[1]) { + if (this.waveRange != null && this.waveRange[0] <= this.waveRange[1]) { const waveIndex = globalScene.currentBattle.waveIndex; if ( (waveIndex >= 0 && this.waveRange[0] >= 0 && this.waveRange[0] > waveIndex) @@ -275,11 +275,7 @@ export class TimeOfDayRequirement extends EncounterSceneRequirement { override meetsRequirement(): boolean { const timeOfDay = globalScene.arena?.getTimeOfDay(); - return !( - !isNullOrUndefined(timeOfDay) - && this.requiredTimeOfDay?.length > 0 - && !this.requiredTimeOfDay.includes(timeOfDay) - ); + return !(timeOfDay != null && this.requiredTimeOfDay?.length > 0 && !this.requiredTimeOfDay.includes(timeOfDay)); } override getDialogueToken(_pokemon?: PlayerPokemon): [string, string] { @@ -298,7 +294,7 @@ export class WeatherRequirement extends EncounterSceneRequirement { override meetsRequirement(): boolean { const currentWeather = globalScene.arena.weather?.weatherType; return !( - !isNullOrUndefined(currentWeather) + currentWeather != null && this.requiredWeather?.length > 0 && !this.requiredWeather.includes(currentWeather!) ); @@ -307,7 +303,7 @@ export class WeatherRequirement extends EncounterSceneRequirement { override getDialogueToken(_pokemon?: PlayerPokemon): [string, string] { const currentWeather = globalScene.arena.weather?.weatherType; let token = ""; - if (!isNullOrUndefined(currentWeather)) { + if (currentWeather != null) { token = WeatherType[currentWeather].replace("_", " ").toLocaleLowerCase(); } return ["weather", token]; @@ -331,7 +327,7 @@ export class PartySizeRequirement extends EncounterSceneRequirement { } override meetsRequirement(): boolean { - if (!isNullOrUndefined(this.partySizeRange) && this.partySizeRange[0] <= this.partySizeRange[1]) { + if (this.partySizeRange != null && this.partySizeRange[0] <= this.partySizeRange[1]) { const partySize = this.excludeDisallowedPokemon ? globalScene.getPokemonAllowedInBattle().length : globalScene.getPlayerParty().length; @@ -363,7 +359,7 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement { override meetsRequirement(): boolean { const partyPokemon = globalScene.getPlayerParty(); - if (isNullOrUndefined(partyPokemon) || this.requiredHeldItemModifiers?.length < 0) { + if (partyPokemon == null || this.requiredHeldItemModifiers?.length < 0) { return false; } let modifierCount = 0; @@ -396,7 +392,7 @@ export class MoneyRequirement extends EncounterSceneRequirement { override meetsRequirement(): boolean { const money = globalScene.money; - if (isNullOrUndefined(money)) { + if (money == null) { return false; } @@ -429,7 +425,7 @@ export class SpeciesRequirement extends EncounterPokemonRequirement { override meetsRequirement(): boolean { const partyPokemon = globalScene.getPlayerParty(); - if (isNullOrUndefined(partyPokemon) || this.requiredSpecies?.length < 0) { + if (partyPokemon == null || this.requiredSpecies?.length < 0) { return false; } return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon; @@ -469,7 +465,7 @@ export class NatureRequirement extends EncounterPokemonRequirement { override meetsRequirement(): boolean { const partyPokemon = globalScene.getPlayerParty(); - if (isNullOrUndefined(partyPokemon) || this.requiredNature?.length < 0) { + if (partyPokemon == null || this.requiredNature?.length < 0) { return false; } return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon; @@ -484,7 +480,7 @@ export class NatureRequirement extends EncounterPokemonRequirement { } override getDialogueToken(pokemon?: PlayerPokemon): [string, string] { - if (!isNullOrUndefined(pokemon?.nature) && this.requiredNature.includes(pokemon.nature)) { + if (pokemon?.nature != null && this.requiredNature.includes(pokemon.nature)) { return ["nature", Nature[pokemon.nature]]; } return ["nature", ""]; @@ -508,7 +504,7 @@ export class TypeRequirement extends EncounterPokemonRequirement { override meetsRequirement(): boolean { let partyPokemon = globalScene.getPlayerParty(); - if (isNullOrUndefined(partyPokemon)) { + if (partyPokemon == null) { return false; } @@ -561,7 +557,7 @@ export class MoveRequirement extends EncounterPokemonRequirement { override meetsRequirement(): boolean { const partyPokemon = globalScene.getPlayerParty(); - if (isNullOrUndefined(partyPokemon) || this.requiredMoves?.length < 0) { + if (partyPokemon == null || this.requiredMoves?.length < 0) { return false; } return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon; @@ -612,7 +608,7 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement { override meetsRequirement(): boolean { const partyPokemon = globalScene.getPlayerParty(); - if (isNullOrUndefined(partyPokemon) || this.requiredMoves?.length < 0) { + if (partyPokemon == null || this.requiredMoves?.length < 0) { return false; } return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon; @@ -668,7 +664,7 @@ export class AbilityRequirement extends EncounterPokemonRequirement { override meetsRequirement(): boolean { const partyPokemon = globalScene.getPlayerParty(); - if (isNullOrUndefined(partyPokemon) || this.requiredAbilities?.length < 0) { + if (partyPokemon == null || this.requiredAbilities?.length < 0) { return false; } return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon; @@ -692,7 +688,7 @@ export class AbilityRequirement extends EncounterPokemonRequirement { override getDialogueToken(pokemon?: PlayerPokemon): [string, string] { const matchingAbility = this.requiredAbilities.find(a => pokemon?.hasAbility(a, false)); - if (!isNullOrUndefined(matchingAbility)) { + if (matchingAbility != null) { return ["ability", allAbilities[matchingAbility].name]; } return ["ability", ""]; @@ -713,7 +709,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement { override meetsRequirement(): boolean { const partyPokemon = globalScene.getPlayerParty(); - if (isNullOrUndefined(partyPokemon) || this.requiredStatusEffect?.length < 0) { + if (partyPokemon == null || this.requiredStatusEffect?.length < 0) { return false; } const x = this.queryParty(partyPokemon).length >= this.minNumberOfPokemon; @@ -727,11 +723,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement { return this.requiredStatusEffect.some(statusEffect => { if (statusEffect === StatusEffect.NONE) { // StatusEffect.NONE also checks for null or undefined status - return ( - isNullOrUndefined(pokemon.status) - || isNullOrUndefined(pokemon.status.effect) - || pokemon.status.effect === statusEffect - ); + return pokemon.status == null || pokemon.status.effect == null || pokemon.status.effect === statusEffect; } return pokemon.status?.effect === statusEffect; }); @@ -742,11 +734,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement { return !this.requiredStatusEffect.some(statusEffect => { if (statusEffect === StatusEffect.NONE) { // StatusEffect.NONE also checks for null or undefined status - return ( - isNullOrUndefined(pokemon.status) - || isNullOrUndefined(pokemon.status.effect) - || pokemon.status.effect === statusEffect - ); + return pokemon.status == null || pokemon.status.effect == null || pokemon.status.effect === statusEffect; } return pokemon.status?.effect === statusEffect; }); @@ -756,9 +744,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement { override getDialogueToken(pokemon?: PlayerPokemon): [string, string] { const reqStatus = this.requiredStatusEffect.filter(a => { if (a === StatusEffect.NONE) { - return ( - isNullOrUndefined(pokemon?.status) || isNullOrUndefined(pokemon.status.effect) || pokemon.status.effect === a - ); + return pokemon?.status == null || pokemon.status.effect == null || pokemon.status.effect === a; } return pokemon!.status?.effect === a; }); @@ -788,7 +774,7 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen override meetsRequirement(): boolean { const partyPokemon = globalScene.getPlayerParty(); - if (isNullOrUndefined(partyPokemon) || this.requiredFormChangeItem?.length < 0) { + if (partyPokemon == null || this.requiredFormChangeItem?.length < 0) { return false; } return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon; @@ -847,7 +833,7 @@ export class HeldItemRequirement extends EncounterPokemonRequirement { override meetsRequirement(): boolean { const partyPokemon = globalScene.getPlayerParty(); - if (isNullOrUndefined(partyPokemon)) { + if (partyPokemon == null) { return false; } return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon; @@ -911,7 +897,7 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe override meetsRequirement(): boolean { const partyPokemon = globalScene.getPlayerParty(); - if (isNullOrUndefined(partyPokemon)) { + if (partyPokemon == null) { return false; } return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon; @@ -978,7 +964,7 @@ export class LevelRequirement extends EncounterPokemonRequirement { override meetsRequirement(): boolean { // Party Pokemon inside required level range - if (!isNullOrUndefined(this.requiredLevelRange) && this.requiredLevelRange[0] <= this.requiredLevelRange[1]) { + if (this.requiredLevelRange != null && this.requiredLevelRange[0] <= this.requiredLevelRange[1]) { const partyPokemon = globalScene.getPlayerParty(); const pokemonInRange = this.queryParty(partyPokemon); if (pokemonInRange.length < this.minNumberOfPokemon) { @@ -1019,10 +1005,7 @@ export class FriendshipRequirement extends EncounterPokemonRequirement { override meetsRequirement(): boolean { // Party Pokemon inside required friendship range - if ( - !isNullOrUndefined(this.requiredFriendshipRange) - && this.requiredFriendshipRange[0] <= this.requiredFriendshipRange[1] - ) { + if (this.requiredFriendshipRange != null && this.requiredFriendshipRange[0] <= this.requiredFriendshipRange[1]) { const partyPokemon = globalScene.getPlayerParty(); const pokemonInRange = this.queryParty(partyPokemon); if (pokemonInRange.length < this.minNumberOfPokemon) { @@ -1071,7 +1054,7 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement { override meetsRequirement(): boolean { // Party Pokemon's health inside required health range - if (!isNullOrUndefined(this.requiredHealthRange) && this.requiredHealthRange[0] <= this.requiredHealthRange[1]) { + if (this.requiredHealthRange != null && this.requiredHealthRange[0] <= this.requiredHealthRange[1]) { const partyPokemon = globalScene.getPlayerParty(); const pokemonInRange = this.queryParty(partyPokemon); if (pokemonInRange.length < this.minNumberOfPokemon) { @@ -1098,7 +1081,7 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement { override getDialogueToken(pokemon?: PlayerPokemon): [string, string] { const hpRatio = pokemon?.getHpRatio(); - if (!isNullOrUndefined(hpRatio)) { + if (hpRatio != null) { return ["healthRatio", Math.floor(hpRatio * 100).toString() + "%"]; } return ["healthRatio", ""]; @@ -1119,7 +1102,7 @@ export class WeightRequirement extends EncounterPokemonRequirement { override meetsRequirement(): boolean { // Party Pokemon's weight inside required weight range - if (!isNullOrUndefined(this.requiredWeightRange) && this.requiredWeightRange[0] <= this.requiredWeightRange[1]) { + if (this.requiredWeightRange != null && this.requiredWeightRange[0] <= this.requiredWeightRange[1]) { const partyPokemon = globalScene.getPlayerParty(); const pokemonInRange = this.queryParty(partyPokemon); if (pokemonInRange.length < this.minNumberOfPokemon) { diff --git a/src/data/mystery-encounters/mystery-encounter-save-data.ts b/src/data/mystery-encounters/mystery-encounter-save-data.ts index f04abccba5f..71cd2517a95 100644 --- a/src/data/mystery-encounters/mystery-encounter-save-data.ts +++ b/src/data/mystery-encounters/mystery-encounter-save-data.ts @@ -1,7 +1,6 @@ import { BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT } from "#app/constants"; import type { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import type { MysteryEncounterType } from "#enums/mystery-encounter-type"; -import { isNullOrUndefined } from "#utils/common"; export class SeenEncounterData { type: MysteryEncounterType; @@ -28,7 +27,7 @@ export class MysteryEncounterSaveData { queuedEncounters: QueuedEncounter[] = []; constructor(data?: MysteryEncounterSaveData) { - if (!isNullOrUndefined(data)) { + if (data != null) { Object.assign(this, data); } diff --git a/src/data/mystery-encounters/mystery-encounter.ts b/src/data/mystery-encounters/mystery-encounter.ts index 273e14248e6..f18660b5d71 100644 --- a/src/data/mystery-encounters/mystery-encounter.ts +++ b/src/data/mystery-encounters/mystery-encounter.ts @@ -25,7 +25,7 @@ import { StatusEffectRequirement, WaveRangeRequirement, } from "#mystery-encounters/mystery-encounter-requirements"; -import { coerceArray, isNullOrUndefined, randSeedInt } from "#utils/common"; +import { coerceArray, randSeedInt } from "#utils/common"; import { capitalizeFirstLetter } from "#utils/strings"; export interface EncounterStartOfBattleEffect { @@ -275,7 +275,7 @@ export class MysteryEncounter implements IMysteryEncounter { private seedOffset?: any; constructor(encounter: IMysteryEncounter | null) { - if (!isNullOrUndefined(encounter)) { + if (encounter != null) { Object.assign(this, encounter); } this.encounterTier = this.encounterTier ?? MysteryEncounterTier.COMMON; diff --git a/src/data/mystery-encounters/requirements/can-learn-move-requirement.ts b/src/data/mystery-encounters/requirements/can-learn-move-requirement.ts index 26602b8ae31..a5810406ef9 100644 --- a/src/data/mystery-encounters/requirements/can-learn-move-requirement.ts +++ b/src/data/mystery-encounters/requirements/can-learn-move-requirement.ts @@ -3,7 +3,7 @@ import type { MoveId } from "#enums/move-id"; import type { PlayerPokemon } from "#field/pokemon"; import { PokemonMove } from "#moves/pokemon-move"; import { EncounterPokemonRequirement } from "#mystery-encounters/mystery-encounter-requirements"; -import { coerceArray, isNullOrUndefined } from "#utils/common"; +import { coerceArray } from "#utils/common"; /** * {@linkcode CanLearnMoveRequirement} options @@ -44,7 +44,7 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement { .getPlayerParty() .filter(pkm => (this.includeFainted ? pkm.isAllowedInChallenge() : pkm.isAllowedInBattle())); - if (isNullOrUndefined(partyPokemon) || this.requiredMoves?.length < 0) { + if (partyPokemon == null || this.requiredMoves?.length < 0) { return false; } diff --git a/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts b/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts index 1a9b008f9e9..be681f731e8 100644 --- a/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts @@ -1,7 +1,6 @@ import { globalScene } from "#app/global-scene"; import type { TextStyle } from "#enums/text-style"; import { getTextWithColors } from "#ui/text"; -import { isNullOrUndefined } from "#utils/common"; import i18next from "i18next"; /** @@ -11,7 +10,7 @@ import i18next from "i18next"; * @param primaryStyle Can define a text style to be applied to the entire string. Must be defined for BBCodeText styles to be applied correctly */ export function getEncounterText(keyOrString?: string, primaryStyle?: TextStyle): string | null { - if (isNullOrUndefined(keyOrString)) { + if (keyOrString == null) { return null; } diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index aa569f11aca..86cd3fa3a32 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -49,7 +49,7 @@ import type { HeldModifierConfig } from "#types/held-modifier-config"; import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; import type { PartyOption, PokemonSelectFilter } from "#ui/party-ui-handler"; import { PartyUiMode } from "#ui/party-ui-handler"; -import { coerceArray, isNullOrUndefined, randomString, randSeedInt, randSeedItem } from "#utils/common"; +import { coerceArray, randomString, randSeedInt, randSeedItem } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import i18next from "i18next"; @@ -143,7 +143,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig): const trainerType = partyConfig?.trainerType; const partyTrainerConfig = partyConfig?.trainerConfig; let trainerConfig: TrainerConfig; - if (!isNullOrUndefined(trainerType) || partyTrainerConfig) { + if (trainerType != null || partyTrainerConfig) { globalScene.currentBattle.mysteryEncounter!.encounterMode = MysteryEncounterMode.TRAINER_BATTLE; if (globalScene.currentBattle.trainer) { globalScene.currentBattle.trainer.setVisible(false); @@ -154,7 +154,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig): const doubleTrainer = trainerConfig.doubleOnly || (trainerConfig.hasDouble && !!partyConfig.doubleBattle); doubleBattle = doubleTrainer; - const trainerFemale = isNullOrUndefined(partyConfig.female) ? !!randSeedInt(2) : partyConfig.female; + const trainerFemale = partyConfig.female == null ? !!randSeedInt(2) : partyConfig.female; const newTrainer = new Trainer( trainerConfig.trainerType, doubleTrainer ? TrainerVariant.DOUBLE : trainerFemale ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT, @@ -202,7 +202,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig): let dataSource: PokemonData | undefined; let isBoss = false; if (!loaded) { - if ((!isNullOrUndefined(trainerType) || trainerConfig) && battle.trainer) { + if ((trainerType != null || trainerConfig) && battle.trainer) { // Allows overriding a trainer's pokemon to use specific species/data if (partyConfig?.pokemonConfigs && e < partyConfig.pokemonConfigs.length) { const config = partyConfig.pokemonConfigs[e]; @@ -258,7 +258,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig): enemyPokemon.resetSummonData(); } - if ((!loaded && isNullOrUndefined(partyConfig.countAsSeen)) || partyConfig.countAsSeen) { + if ((!loaded && partyConfig.countAsSeen == null) || partyConfig.countAsSeen) { globalScene.gameData.setPokemonSeen(enemyPokemon, true, !!(trainerType || trainerConfig)); } @@ -266,7 +266,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig): const config = partyConfig.pokemonConfigs[e]; // Set form - if (!isNullOrUndefined(config.nickname)) { + if (config.nickname != null) { enemyPokemon.nickname = btoa(unescape(encodeURIComponent(config.nickname))); } @@ -276,22 +276,22 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig): } // Set form - if (!isNullOrUndefined(config.formIndex)) { + if (config.formIndex != null) { enemyPokemon.formIndex = config.formIndex; } // Set shiny - if (!isNullOrUndefined(config.shiny)) { + if (config.shiny != null) { enemyPokemon.shiny = config.shiny; } // Set Variant - if (enemyPokemon.shiny && !isNullOrUndefined(config.variant)) { + if (enemyPokemon.shiny && config.variant != null) { enemyPokemon.variant = config.variant; } // Set custom mystery encounter data fields (such as sprite scale, custom abilities, types, etc.) - if (!isNullOrUndefined(config.customPokemonData)) { + if (config.customPokemonData != null) { enemyPokemon.customPokemonData = config.customPokemonData; } @@ -300,7 +300,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig): let segments = config.bossSegments ?? globalScene.getEncounterBossSegments(globalScene.currentBattle.waveIndex, level, enemySpecies, true); - if (!isNullOrUndefined(config.bossSegmentModifier)) { + if (config.bossSegmentModifier != null) { segments += config.bossSegmentModifier; } enemyPokemon.setBoss(true, segments); @@ -335,18 +335,18 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig): } // Set ability - if (!isNullOrUndefined(config.abilityIndex)) { + if (config.abilityIndex != null) { enemyPokemon.abilityIndex = config.abilityIndex; } // Set gender - if (!isNullOrUndefined(config.gender)) { + if (config.gender != null) { enemyPokemon.gender = config.gender!; enemyPokemon.summonData.gender = config.gender; } // Set AI type - if (!isNullOrUndefined(config.aiType)) { + if (config.aiType != null) { enemyPokemon.aiType = config.aiType; } diff --git a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts index 8f6c78fab9c..01d4659d379 100644 --- a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts @@ -35,7 +35,7 @@ import type { PartyOption } from "#ui/party-ui-handler"; import { PartyUiMode } from "#ui/party-ui-handler"; import { SummaryUiMode } from "#ui/summary-ui-handler"; import { applyChallenges } from "#utils/challenge-utils"; -import { BooleanHolder, isNullOrUndefined, randSeedInt } from "#utils/common"; +import { BooleanHolder, randSeedInt } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import i18next from "i18next"; @@ -276,7 +276,7 @@ export function getRandomSpeciesByStarterCost( if (types && types.length > 0) { filteredSpecies = filteredSpecies.filter( - s => types.includes(s[0].type1) || (!isNullOrUndefined(s[0].type2) && types.includes(s[0].type2)), + s => types.includes(s[0].type1) || (s[0].type2 != null && types.includes(s[0].type2)), ); } diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 2d76c2c0400..7c00bf5dff7 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -28,7 +28,7 @@ import type { Variant, VariantSet } from "#sprites/variant"; import { populateVariantColorCache, variantColorCache, variantData } from "#sprites/variant"; import type { Localizable } from "#types/locales"; import type { StarterMoveset } from "#types/save-data"; -import { isNullOrUndefined, randSeedFloat, randSeedGauss, randSeedInt } from "#utils/common"; +import { 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"; @@ -197,7 +197,7 @@ export abstract class PokemonSpeciesForm { * @returns The id of the ability */ getPassiveAbility(formIndex?: number): AbilityId { - if (isNullOrUndefined(formIndex)) { + if (formIndex == null) { formIndex = this.formIndex; } let starterSpeciesId = this.speciesId; @@ -551,7 +551,7 @@ export abstract class PokemonSpeciesForm { const spriteKey = this.getSpriteKey(female, formIndex, shiny, variant, back); globalScene.loadPokemonAtlas(spriteKey, this.getSpriteAtlasPath(female, formIndex, shiny, variant, back)); globalScene.load.audio(this.getCryKey(formIndex), `audio/${this.getCryKey(formIndex)}.m4a`); - if (!isNullOrUndefined(variant)) { + if (variant != null) { await this.loadVariantColors(spriteKey, female, variant, back, formIndex); } return new Promise(resolve => { @@ -579,7 +579,7 @@ export abstract class PokemonSpeciesForm { const spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant, back) .replace("variant/", "") .replace(/_[1-3]$/, ""); - if (!isNullOrUndefined(variant)) { + if (variant != null) { loadPokemonVariantAssets(spriteKey, spritePath, variant).then(() => resolve()); } }); @@ -791,7 +791,7 @@ export class PokemonSpecies extends PokemonSpeciesForm implements Localizable { * @returns A randomly rolled gender based on this Species' {@linkcode malePercent}. */ generateGender(): Gender { - if (isNullOrUndefined(this.malePercent)) { + if (this.malePercent == null) { return Gender.GENDERLESS; } diff --git a/src/data/pokemon/pokemon-data.ts b/src/data/pokemon/pokemon-data.ts index 87ffbbab4cd..4fbb70bccb2 100644 --- a/src/data/pokemon/pokemon-data.ts +++ b/src/data/pokemon/pokemon-data.ts @@ -16,7 +16,6 @@ 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"; import { getPokemonSpeciesForm } from "#utils/pokemon-utils"; /** @@ -64,14 +63,14 @@ function deserializePokemonSpeciesForm(value: SerializedSpeciesForm | PokemonSpe // @ts-expect-error: We may be deserializing a PokemonSpeciesForm, but we catch later on let { id, formIdx } = value; - if (isNullOrUndefined(id) || isNullOrUndefined(formIdx)) { + if (id == null || formIdx == null) { // @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)) { + if (id == null || formIdx == null) { return null; } return getPokemonSpeciesForm(id, formIdx); @@ -151,13 +150,13 @@ export class PokemonSummonData { public moveHistory: TurnMove[] = []; constructor(source?: PokemonSummonData | SerializedPokemonSummonData) { - if (isNullOrUndefined(source)) { + if (source == null) { return; } // TODO: Rework this into an actual generic function for use elsewhere for (const [key, value] of Object.entries(source)) { - if (isNullOrUndefined(value) && this.hasOwnProperty(key)) { + if (value == null && this.hasOwnProperty(key)) { continue; } @@ -171,7 +170,7 @@ export class PokemonSummonData { const illusionData = { ...value, }; - if (!isNullOrUndefined(illusionData.fusionSpecies)) { + if (illusionData.fusionSpecies != null) { switch (typeof illusionData.fusionSpecies) { case "object": illusionData.fusionSpecies = allSpecies[illusionData.fusionSpecies.speciesId]; @@ -224,18 +223,18 @@ export class PokemonSummonData { 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, - }, + speciesForm: speciesForm == null ? undefined : { id: speciesForm.speciesId, formIdx: speciesForm.formIndex }, + fusionSpeciesForm: + fusionSpeciesForm == null + ? undefined + : { id: fusionSpeciesForm.speciesId, formIdx: fusionSpeciesForm.formIndex }, + illusion: + illusion == null + ? 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)) { @@ -278,7 +277,7 @@ export class PokemonBattleData { public berriesEaten: BerryType[] = []; constructor(source?: PokemonBattleData | Partial) { - if (!isNullOrUndefined(source)) { + if (source != null) { this.hitCount = source.hitCount ?? 0; this.hasEatenBerry = source.hasEatenBerry ?? false; this.berriesEaten = source.berriesEaten ?? []; diff --git a/src/data/trainers/trainer-config.ts b/src/data/trainers/trainer-config.ts index 9d891444829..55362017cee 100644 --- a/src/data/trainers/trainer-config.ts +++ b/src/data/trainers/trainer-config.ts @@ -41,7 +41,7 @@ import type { TrainerConfigs, TrainerTierPools, } from "#types/trainer-funcs"; -import { coerceArray, isNullOrUndefined, randSeedInt, randSeedIntRange, randSeedItem } from "#utils/common"; +import { coerceArray, randSeedInt, randSeedIntRange, randSeedItem } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import { toCamelCase, toTitleCase } from "#utils/strings"; import i18next from "i18next"; @@ -474,7 +474,7 @@ export class TrainerConfig { .fill(null) .map((_, i) => i) .filter(i => shedinjaCanTera || party[i].species.speciesId !== SpeciesId.SHEDINJA); // Shedinja can only Tera on Bug specialty type (or no specialty type) - const setPartySlot = !isNullOrUndefined(slot) ? Phaser.Math.Wrap(slot, 0, party.length) : -1; // If we have a tera slot defined, wrap it to party size. + const setPartySlot = slot != null ? Phaser.Math.Wrap(slot, 0, party.length) : -1; // If we have a tera slot defined, wrap it to party size. for (let t = 0; t < Math.min(count(), party.length); t++) { const randomIndex = partyMemberIndexes.indexOf(setPartySlot) > -1 ? setPartySlot : randSeedItem(partyMemberIndexes); @@ -537,7 +537,7 @@ export class TrainerConfig { initI18n(); } - if (!isNullOrUndefined(specialtyType)) { + if (specialtyType != null) { this.setSpecialtyType(specialtyType); } @@ -612,7 +612,7 @@ export class TrainerConfig { signatureSpecies.forEach((speciesPool, s) => { this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(coerceArray(speciesPool))); }); - if (!isNullOrUndefined(specialtyType)) { + if (specialtyType != null) { this.setSpeciesFilter(p => p.isOfType(specialtyType)); this.setSpecialtyType(specialtyType); } @@ -717,7 +717,7 @@ export class TrainerConfig { }); // Set species filter and specialty type if provided, otherwise filter by base total. - if (!isNullOrUndefined(specialtyType)) { + if (specialtyType != null) { this.setSpeciesFilter(p => p.isOfType(specialtyType) && p.baseTotal >= ELITE_FOUR_MINIMUM_BST); this.setSpecialtyType(specialtyType); } else { @@ -895,7 +895,7 @@ export class TrainerConfig { * @returns `true` if `specialtyType` is defined and not {@link PokemonType.UNKNOWN} */ hasSpecialtyType(): boolean { - return !isNullOrUndefined(this.specialtyType) && this.specialtyType !== PokemonType.UNKNOWN; + return this.specialtyType != null && this.specialtyType !== PokemonType.UNKNOWN; } /** @@ -2942,7 +2942,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.SLOWBRO, SpeciesId.GALAR_SLOWBRO], TrainerSlot.TRAINER, true, p => { // Tera Ice Slowbro/G-Slowbro p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.ICE_BEAM)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.ICE_BEAM)) { // Check if Ice Beam is in the moveset, if not, replace the third move with Ice Beam. p.moveset[2] = new PokemonMove(MoveId.ICE_BEAM); } @@ -2967,7 +2967,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.STEELIX], TrainerSlot.TRAINER, true, p => { // Tera Fighting Steelix p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.BODY_PRESS)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.BODY_PRESS)) { // Check if Body Press is in the moveset, if not, replace the third move with Body Press. p.moveset[2] = new PokemonMove(MoveId.BODY_PRESS); } @@ -2992,7 +2992,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.ARBOK, SpeciesId.WEEZING], TrainerSlot.TRAINER, true, p => { // Tera Ghost Arbok/Weezing p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST); } @@ -3018,7 +3018,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.GYARADOS, SpeciesId.AERODACTYL], TrainerSlot.TRAINER, true, p => { // Tera Dragon Gyarados/Aerodactyl p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST); } @@ -3079,7 +3079,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.GENGAR], TrainerSlot.TRAINER, true, p => { // Tera Dark Gengar p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.DARK_PULSE)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.DARK_PULSE)) { // Check if Dark Pulse is in the moveset, if not, replace the third move with Dark Pulse. p.moveset[2] = new PokemonMove(MoveId.DARK_PULSE); } @@ -3163,7 +3163,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.DHELMISE], TrainerSlot.TRAINER, true, p => { // Tera Dragon Dhelmise p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST); } @@ -3193,7 +3193,7 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(true, 2); p.abilityIndex = 1; // Sniper p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.X_SCISSOR)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.X_SCISSOR)) { // Check if X-Scissor is in the moveset, if not, replace the third move with X-Scissor. p.moveset[2] = new PokemonMove(MoveId.X_SCISSOR); } @@ -3232,7 +3232,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.STEELIX, SpeciesId.LOPUNNY], TrainerSlot.TRAINER, true, p => { // Tera Fire Steelix/Lopunny p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST); } @@ -3375,7 +3375,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.CERULEDGE], TrainerSlot.TRAINER, true, p => { // Tera Steel Ceruledge p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.IRON_HEAD)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.IRON_HEAD)) { // Check if Iron Head is in the moveset, if not, replace the third move with Iron Head. p.moveset[2] = new PokemonMove(MoveId.IRON_HEAD); } @@ -3413,7 +3413,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.INCINEROAR], TrainerSlot.TRAINER, true, p => { // Tera Fighting Incineroar p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.CROSS_CHOP)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.CROSS_CHOP)) { // Check if Cross Chop is in the moveset, if not, replace the third move with Cross Chop. p.moveset[2] = new PokemonMove(MoveId.CROSS_CHOP); } @@ -3486,7 +3486,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.DECIDUEYE], TrainerSlot.TRAINER, true, p => { // Tera Flying Decidueye p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.BRAVE_BIRD)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.BRAVE_BIRD)) { // Check if Brave Bird is in the moveset, if not, replace the third move with Brave Bird. p.moveset[2] = new PokemonMove(MoveId.BRAVE_BIRD); } @@ -3511,7 +3511,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.TOXICROAK], TrainerSlot.TRAINER, true, p => { // Tera Dark Toxicroak p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.SUCKER_PUNCH)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.SUCKER_PUNCH)) { // Check if Sucker Punch is in the moveset, if not, replace the third move with Sucker Punch. p.moveset[2] = new PokemonMove(MoveId.SUCKER_PUNCH); } @@ -3536,7 +3536,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.EISCUE], TrainerSlot.TRAINER, true, p => { // Tera Water Eiscue p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.LIQUIDATION)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.LIQUIDATION)) { // Check if Liquidation is in the moveset, if not, replace the third move with Liquidation. p.moveset[2] = new PokemonMove(MoveId.LIQUIDATION); } @@ -3598,7 +3598,7 @@ export const trainerConfigs: TrainerConfigs = { // Tera Dragon Torkoal p.abilityIndex = 1; // Drought p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST); } @@ -3695,7 +3695,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.EXEGGUTOR], TrainerSlot.TRAINER, true, p => { // Tera Fire Exeggutor p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST); } @@ -3705,7 +3705,7 @@ export const trainerConfigs: TrainerConfigs = { 3, getRandomPartyMemberFunc([SpeciesId.TALONFLAME], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.SUNNY_DAY)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.SUNNY_DAY)) { // Check if Sunny Day is in the moveset, if not, replace the third move with Sunny Day. p.moveset[2] = new PokemonMove(MoveId.SUNNY_DAY); } @@ -3728,7 +3728,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.REUNICLUS], TrainerSlot.TRAINER, true, p => { // Tera Steel Reuniclus p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.FLASH_CANNON)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.FLASH_CANNON)) { // Check if Flash Cannon is in the moveset, if not, replace the third move with Flash Cannon. p.moveset[2] = new PokemonMove(MoveId.FLASH_CANNON); } @@ -3756,7 +3756,7 @@ export const trainerConfigs: TrainerConfigs = { // Tera Fairy Excadrill p.setBoss(true, 2); p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST); } @@ -3771,7 +3771,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.SCEPTILE], TrainerSlot.TRAINER, true, p => { // Tera Dragon Sceptile p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.DUAL_CHOP)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.DUAL_CHOP)) { // Check if Dual Chop is in the moveset, if not, replace the third move with Dual Chop. p.moveset[2] = new PokemonMove(MoveId.DUAL_CHOP); } @@ -3841,7 +3841,7 @@ export const trainerConfigs: TrainerConfigs = { p.formIndex = 1; // Partner Pikachu p.gender = Gender.MALE; p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.VOLT_TACKLE)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.VOLT_TACKLE)) { // Check if Volt Tackle is in the moveset, if not, replace the first move with Volt Tackle. p.moveset[0] = new PokemonMove(MoveId.VOLT_TACKLE); } @@ -4072,7 +4072,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.KELDEO], TrainerSlot.TRAINER, true, p => { p.pokeball = PokeballType.ROGUE_BALL; p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.SECRET_SWORD)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.SECRET_SWORD)) { // Check if Secret Sword is in the moveset, if not, replace the third move with Secret Sword. p.moveset[2] = new PokemonMove(MoveId.SECRET_SWORD); } @@ -4401,7 +4401,7 @@ export const trainerConfigs: TrainerConfigs = { 5, getRandomPartyMemberFunc([SpeciesId.KINGAMBIT], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST); } @@ -4480,7 +4480,7 @@ export const trainerConfigs: TrainerConfigs = { 4, getRandomPartyMemberFunc([SpeciesId.TERAPAGOS], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_STARSTORM)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.TERA_STARSTORM)) { // Check if Tera Starstorm is in the moveset, if not, replace the first move with Tera Starstorm. p.moveset[0] = new PokemonMove(MoveId.TERA_STARSTORM); } @@ -4494,7 +4494,7 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(true, 2); p.teraType = PokemonType.FIGHTING; p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST); } @@ -5054,7 +5054,7 @@ export const trainerConfigs: TrainerConfigs = { 2, getRandomPartyMemberFunc([SpeciesId.HONCHKROW], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.SUCKER_PUNCH)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.SUCKER_PUNCH)) { // Check if Sucker Punch is in the moveset, if not, replace the third move with Sucker Punch. p.moveset[2] = new PokemonMove(MoveId.SUCKER_PUNCH); } @@ -5517,7 +5517,7 @@ export const trainerConfigs: TrainerConfigs = { p.formIndex = randSeedInt(18); // Random Silvally Form p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ROGUE_BALL; - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.MULTI_ATTACK)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.MULTI_ATTACK)) { // Check if Multi Attack is in the moveset, if not, replace the first move with Multi Attack. p.moveset[0] = new PokemonMove(MoveId.MULTI_ATTACK); } @@ -5590,7 +5590,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.GOLISOPOD], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.FIRST_IMPRESSION)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.FIRST_IMPRESSION)) { // Check if First Impression is in the moveset, if not, replace the third move with First Impression. p.moveset[2] = new PokemonMove(MoveId.FIRST_IMPRESSION); p.gender = Gender.MALE; @@ -5607,7 +5607,7 @@ export const trainerConfigs: TrainerConfigs = { getRandomPartyMemberFunc([SpeciesId.GOLISOPOD], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.FIRST_IMPRESSION)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.FIRST_IMPRESSION)) { // Check if First Impression is in the moveset, if not, replace the third move with First Impression. p.moveset[2] = new PokemonMove(MoveId.FIRST_IMPRESSION); p.abilityIndex = 2; // Anticipation @@ -5643,7 +5643,7 @@ export const trainerConfigs: TrainerConfigs = { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ROGUE_BALL; p.formIndex = randSeedInt(4, 1); // Shock, Burn, Chill, or Douse Drive - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TECHNO_BLAST)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.TECHNO_BLAST)) { // Check if Techno Blast is in the moveset, if not, replace the third move with Techno Blast. p.moveset[2] = new PokemonMove(MoveId.TECHNO_BLAST); } @@ -5778,7 +5778,7 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(true, 2); p.abilityIndex = 2; // Pixilate p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.HYPER_VOICE)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.HYPER_VOICE)) { // Check if Hyper Voice is in the moveset, if not, replace the second move with Hyper Voice. p.moveset[1] = new PokemonMove(MoveId.HYPER_VOICE); p.gender = Gender.FEMALE; @@ -5807,7 +5807,7 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(true, 2); p.abilityIndex = 2; // Pixilate p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.HYPER_VOICE)) { + if (!p.moveset.some(move => move != null && move.moveId === MoveId.HYPER_VOICE)) { // Check if Hyper Voice is in the moveset, if not, replace the second move with Hyper Voice. p.moveset[1] = new PokemonMove(MoveId.HYPER_VOICE); p.gender = Gender.FEMALE; diff --git a/src/field/arena.ts b/src/field/arena.ts index ff7379b2a4a..c4708be1336 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -36,7 +36,7 @@ import type { Pokemon } from "#field/pokemon"; import { FieldEffectModifier } from "#modifiers/modifier"; import type { Move } from "#moves/move"; import type { AbstractConstructor } from "#types/type-helpers"; -import { type Constructor, isNullOrUndefined, NumberHolder, randSeedInt } from "#utils/common"; +import { type Constructor, NumberHolder, randSeedInt } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; export class Arena { @@ -339,7 +339,7 @@ export class Arena { const weatherDuration = new NumberHolder(0); - if (!isNullOrUndefined(user)) { + if (user != null) { weatherDuration.value = 5; globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, weatherDuration); } @@ -420,7 +420,7 @@ export class Arena { const terrainDuration = new NumberHolder(0); - if (!isNullOrUndefined(user)) { + if (user != null) { terrainDuration.value = 5; globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, terrainDuration); } diff --git a/src/field/mystery-encounter-intro.ts b/src/field/mystery-encounter-intro.ts index cf0a0f30529..4b4a234251a 100644 --- a/src/field/mystery-encounter-intro.ts +++ b/src/field/mystery-encounter-intro.ts @@ -5,7 +5,6 @@ import { getSpriteKeysFromSpecies } from "#mystery-encounters/encounter-pokemon- import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter"; import { loadPokemonVariantAssets } from "#sprites/pokemon-sprite"; import type { Variant } from "#sprites/variant"; -import { isNullOrUndefined } from "#utils/common"; import type { GameObjects } from "phaser"; type PlayAnimationConfig = Phaser.Types.Animations.PlayAnimationConfig; @@ -98,7 +97,7 @@ export class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Container { ...config, }; - if (!isNullOrUndefined(result.species)) { + if (result.species != null) { const keys = getSpriteKeysFromSpecies(result.species, undefined, undefined, result.isShiny, result.variant); result.spriteKey = keys.spriteKey; result.fileRoot = keys.fileRoot; @@ -205,12 +204,12 @@ export class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Container { n++; } - if (!isNullOrUndefined(pokemonShinySparkle)) { + if (pokemonShinySparkle != null) { // Offset the sparkle to match the Pokemon's position pokemonShinySparkle.setPosition(sprite.x, sprite.y); } - if (!isNullOrUndefined(alpha)) { + if (alpha != null) { sprite.setAlpha(alpha); tintSprite.setAlpha(alpha); } @@ -234,7 +233,7 @@ export class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Container { this.spriteConfigs.forEach(config => { if (config.isPokemon) { globalScene.loadPokemonAtlas(config.spriteKey, config.fileRoot); - if (config.isShiny && !isNullOrUndefined(config.variant)) { + if (config.isShiny && config.variant != null) { shinyPromises.push(loadPokemonVariantAssets(config.spriteKey, config.fileRoot, config.variant)); } } else if (config.isItem) { diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index d3ff7312977..e6a46ac926f 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -159,7 +159,6 @@ import { fixedInt, getIvsFromId, isBetween, - isNullOrUndefined, NumberHolder, randSeedFloat, randSeedInt, @@ -886,7 +885,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { return this.fallbackVariantColor(cacheKey, spritePath, useExpSprite, battleSpritePath, error); }) .then(c => { - if (!isNullOrUndefined(c)) { + if (c != null) { variantColorCache[cacheKey] = c; } }); @@ -1475,7 +1474,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { } const ally = this.getAlly(); - if (!isNullOrUndefined(ally)) { + if (ally != null) { applyAbAttrs("AllyStatMultiplierAbAttr", { pokemon: ally, stat, @@ -1658,7 +1657,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { if (useIllusion && this.summonData.illusion) { return this.summonData.illusion.gender; } - if (!ignoreOverride && !isNullOrUndefined(this.summonData.gender)) { + if (!ignoreOverride && this.summonData.gender != null) { return this.summonData.gender; } return this.gender; @@ -1674,7 +1673,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { if (useIllusion && this.summonData.illusion?.fusionGender) { return this.summonData.illusion.fusionGender; } - if (!ignoreOverride && !isNullOrUndefined(this.summonData.fusionGender)) { + if (!ignoreOverride && this.summonData.fusionGender != null) { return this.summonData.fusionGender; } return this.fusionGender; @@ -1793,7 +1792,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { * @returns Whether this Pokemon has this species as either its base or fusion counterpart. */ hasSpecies(species: SpeciesId, formKey?: string): boolean { - if (isNullOrUndefined(formKey)) { + if (formKey == null) { return this.species.speciesId === species || this.fusionSpecies?.speciesId === species; } @@ -1941,7 +1940,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { secondType = fusionType1; } - if (secondType === PokemonType.UNKNOWN && isNullOrUndefined(fusionType2)) { + if (secondType === PokemonType.UNKNOWN && fusionType2 == null) { // If second pokemon was monotype and shared its primary type secondType = customTypes @@ -2024,12 +2023,12 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { return allAbilities[Overrides.ENEMY_ABILITY_OVERRIDE]; } if (this.isFusion()) { - if (!isNullOrUndefined(this.fusionCustomPokemonData?.ability) && this.fusionCustomPokemonData.ability !== -1) { + if (this.fusionCustomPokemonData?.ability != null && this.fusionCustomPokemonData.ability !== -1) { return allAbilities[this.fusionCustomPokemonData.ability]; } return allAbilities[this.getFusionSpeciesForm(ignoreOverride).getAbility(this.fusionAbilityIndex)]; } - if (!isNullOrUndefined(this.customPokemonData.ability) && this.customPokemonData.ability !== -1) { + if (this.customPokemonData.ability != null && this.customPokemonData.ability !== -1) { return allAbilities[this.customPokemonData.ability]; } let abilityId = this.getSpeciesForm(ignoreOverride).getAbility(this.abilityIndex); @@ -2053,7 +2052,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { if (Overrides.ENEMY_PASSIVE_ABILITY_OVERRIDE && this.isEnemy()) { return allAbilities[Overrides.ENEMY_PASSIVE_ABILITY_OVERRIDE]; } - if (!isNullOrUndefined(this.customPokemonData.passive) && this.customPokemonData.passive !== -1) { + if (this.customPokemonData.passive != null && this.customPokemonData.passive !== -1) { return allAbilities[this.customPokemonData.passive]; } @@ -2237,7 +2236,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { public getWeight(): number { const autotomizedTag = this.getTag(AutotomizedTag); let weightRemoved = 0; - if (!isNullOrUndefined(autotomizedTag)) { + if (autotomizedTag != null) { weightRemoved = 100 * autotomizedTag.autotomizeCount; } const minWeight = 0.1; @@ -2384,7 +2383,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { cancelled?: BooleanHolder, useIllusion = false, ): TypeDamageMultiplier { - if (!isNullOrUndefined(this.turnData?.moveEffectiveness)) { + if (this.turnData?.moveEffectiveness != null) { return this.turnData?.moveEffectiveness; } @@ -3606,7 +3605,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { }); const ally = this.getAlly(); - if (!isNullOrUndefined(ally)) { + if (ally != null) { const ignore = this.hasAbilityWithAttr("MoveAbilityBypassAbAttr") || sourceMove.hasFlag(MoveFlags.IGNORE_ABILITIES); applyAbAttrs("AllyStatMultiplierAbAttr", { @@ -4022,7 +4021,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { const ally = this.getAlly(); /** Additionally apply friend guard damage reduction if ally has it. */ - if (globalScene.currentBattle.double && !isNullOrUndefined(ally) && ally.isActive(true)) { + if (globalScene.currentBattle.double && ally != null && ally.isActive(true)) { applyAbAttrs("AlliedFieldDamageReductionAbAttr", { ...abAttrParams, // Same parameters as before, except we are applying the ally's ability @@ -6397,13 +6396,13 @@ export class EnemyPokemon extends Pokemon { if ( speciesId in Overrides.ENEMY_FORM_OVERRIDES - && !isNullOrUndefined(Overrides.ENEMY_FORM_OVERRIDES[speciesId]) + && Overrides.ENEMY_FORM_OVERRIDES[speciesId] != null && this.species.forms[Overrides.ENEMY_FORM_OVERRIDES[speciesId]] ) { this.formIndex = Overrides.ENEMY_FORM_OVERRIDES[speciesId]; } else if (globalScene.gameMode.isDaily && globalScene.gameMode.isWaveFinal(globalScene.currentBattle.waveIndex)) { const eventBoss = getDailyEventSeedBoss(globalScene.seed); - if (!isNullOrUndefined(eventBoss)) { + if (eventBoss != null) { this.formIndex = eventBoss.formIndex; } } diff --git a/src/game-mode.ts b/src/game-mode.ts index 9ea3adf59d3..e543e3c42ca 100644 --- a/src/game-mode.ts +++ b/src/game-mode.ts @@ -14,7 +14,7 @@ import { SpeciesId } from "#enums/species-id"; import type { Arena } from "#field/arena"; import { classicFixedBattles, type FixedBattleConfigs } from "#trainers/fixed-battle-configs"; import { applyChallenges } from "#utils/challenge-utils"; -import { BooleanHolder, isNullOrUndefined, randSeedInt, randSeedItem } from "#utils/common"; +import { BooleanHolder, randSeedInt, randSeedItem } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import i18next from "i18next"; @@ -146,7 +146,7 @@ export class GameMode implements GameModeConfig { * - Town */ getStartingBiome(): BiomeId { - if (!isNullOrUndefined(Overrides.STARTING_BIOME_OVERRIDE)) { + if (Overrides.STARTING_BIOME_OVERRIDE != null) { return Overrides.STARTING_BIOME_OVERRIDE; } @@ -234,7 +234,7 @@ export class GameMode implements GameModeConfig { getOverrideSpecies(waveIndex: number): PokemonSpecies | null { if (this.isDaily && this.isWaveFinal(waveIndex)) { const eventBoss = getDailyEventSeedBoss(globalScene.seed); - if (!isNullOrUndefined(eventBoss)) { + if (eventBoss != null) { // Cannot set form index here, it will be overriden when adding it as enemy pokemon. return getPokemonSpecies(eventBoss.speciesId); } diff --git a/src/modifier/init-modifier-pools.ts b/src/modifier/init-modifier-pools.ts index ba12920407d..e6ec69eac7f 100644 --- a/src/modifier/init-modifier-pools.ts +++ b/src/modifier/init-modifier-pools.ts @@ -31,7 +31,6 @@ import { } from "#modifiers/modifier-pools"; import { WeightedModifierType } from "#modifiers/modifier-type"; import type { WeightedModifierTypeWeightFunc } from "#types/modifier-types"; -import { isNullOrUndefined } from "#utils/common"; /** * Initialize the wild modifier pool @@ -409,7 +408,7 @@ function initUltraModifierPool() { if (!isHoldingOrb) { const moveset = p .getMoveset(true) - .filter(m => !isNullOrUndefined(m)) + .filter(m => m != null) .map(m => m.moveId); const canSetStatus = p.canSetStatus(StatusEffect.TOXIC, true, true, null, true); @@ -455,7 +454,7 @@ function initUltraModifierPool() { if (!isHoldingOrb) { const moveset = p .getMoveset(true) - .filter(m => !isNullOrUndefined(m)) + .filter(m => m != null) .map(m => m.moveId); const canSetStatus = p.canSetStatus(StatusEffect.BURN, true, true, null, true); diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 579fb75ce3b..d67011bc145 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -119,15 +119,7 @@ import type { PokemonMoveSelectFilter, PokemonSelectFilter } from "#ui/party-ui- import { PartyUiHandler } from "#ui/party-ui-handler"; import { getModifierTierTextTint } from "#ui/text"; import { applyChallenges } from "#utils/challenge-utils"; -import { - BooleanHolder, - formatMoney, - isNullOrUndefined, - NumberHolder, - padInt, - randSeedInt, - randSeedItem, -} from "#utils/common"; +import { BooleanHolder, formatMoney, NumberHolder, padInt, randSeedInt, randSeedItem } from "#utils/common"; import { getEnumKeys, getEnumValues } from "#utils/enums"; import { getModifierPoolForType, getModifierType } from "#utils/modifier-utils"; import { toCamelCase } from "#utils/strings"; @@ -263,7 +255,7 @@ export class ModifierType { this.tier = modifier.modifierType.tier; return this; } - if (isNullOrUndefined(defaultTier)) { + if (defaultTier == null) { // If weight is 0, keep track of the first tier where the item was found defaultTier = modifier.modifierType.tier; } @@ -2920,7 +2912,7 @@ export function getPartyLuckValue(party: Pokemon[]): number { globalScene.executeWithSeedOffset( () => { const eventLuck = getDailyEventSeedLuck(globalScene.seed); - if (!isNullOrUndefined(eventLuck)) { + if (eventLuck != null) { DailyLuck.value = eventLuck; return; } diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 1f470e592c2..82e64316edd 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -42,7 +42,7 @@ import type { import type { VoucherType } from "#system/voucher"; import type { ModifierInstanceMap, ModifierString } from "#types/modifier-types"; import { addTextObject } from "#ui/text"; -import { BooleanHolder, hslToHex, isNullOrUndefined, NumberHolder, randSeedFloat, toDmgValue } from "#utils/common"; +import { BooleanHolder, hslToHex, NumberHolder, randSeedFloat, toDmgValue } from "#utils/common"; import { getModifierType } from "#utils/modifier-utils"; import i18next from "i18next"; @@ -2113,10 +2113,7 @@ export class PokemonHpRestoreModifier extends ConsumablePokemonModifier { * @returns `true` if the {@linkcode PokemonHpRestoreModifier} should be applied */ override shouldApply(playerPokemon?: PlayerPokemon, multiplier?: number): boolean { - return ( - super.shouldApply(playerPokemon) - && (this.fainted || (!isNullOrUndefined(multiplier) && typeof multiplier === "number")) - ); + return super.shouldApply(playerPokemon) && (this.fainted || (multiplier != null && typeof multiplier === "number")); } /** @@ -2753,10 +2750,10 @@ export class PokemonMultiHitModifier extends PokemonHeldItemModifier { return false; } - if (!isNullOrUndefined(count)) { + if (count != null) { return this.applyHitCountBoost(count); } - if (!isNullOrUndefined(damageMultiplier)) { + if (damageMultiplier != null) { return this.applyDamageModifier(pokemon, damageMultiplier); } diff --git a/src/phases/faint-phase.ts b/src/phases/faint-phase.ts index 349dfcfa8e5..821d16c6546 100644 --- a/src/phases/faint-phase.ts +++ b/src/phases/faint-phase.ts @@ -17,7 +17,6 @@ import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon"; import { PokemonInstantReviveModifier } from "#modifiers/modifier"; import { PokemonMove } from "#moves/pokemon-move"; import { PokemonPhase } from "#phases/pokemon-phase"; -import { isNullOrUndefined } from "#utils/common"; import i18next from "i18next"; export class FaintPhase extends PokemonPhase { @@ -187,7 +186,7 @@ export class FaintPhase extends PokemonPhase { // in double battles redirect potential moves off fainted pokemon const allyPokemon = pokemon.getAlly(); - if (globalScene.currentBattle.double && !isNullOrUndefined(allyPokemon)) { + if (globalScene.currentBattle.double && allyPokemon != null) { globalScene.redirectPokemonMoves(pokemon, allyPokemon); } diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index 6c143f1f8a1..717bc670558 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -40,7 +40,7 @@ import { DamageAchv } from "#system/achv"; import type { DamageResult } from "#types/damage-result"; import type { TurnMove } from "#types/turn-move"; import type { nil } from "#utils/common"; -import { BooleanHolder, isNullOrUndefined, NumberHolder } from "#utils/common"; +import { BooleanHolder, NumberHolder } from "#utils/common"; import i18next from "i18next"; export type HitCheckEntry = [HitCheckResult, TypeDamageMultiplier]; @@ -740,7 +740,7 @@ export class MoveEffectPhase extends PokemonPhase { (attr: MoveAttr) => attr.is("MoveEffectAttr") && attr.trigger === triggerType - && (isNullOrUndefined(selfTarget) || attr.selfTarget === selfTarget) + && (selfTarget == null || attr.selfTarget === selfTarget) && (!attr.firstHitOnly || this.firstHit) && (!attr.lastHitOnly || this.lastHit) && (!attr.firstTargetOnly || (firstTarget ?? true)), @@ -765,7 +765,7 @@ export class MoveEffectPhase extends PokemonPhase { */ protected applyMoveEffects(target: Pokemon, effectiveness: TypeDamageMultiplier, firstTarget: boolean): void { const user = this.getUserPokemon(); - if (isNullOrUndefined(user)) { + if (user == null) { return; } diff --git a/src/phases/mystery-encounter-phases.ts b/src/phases/mystery-encounter-phases.ts index df670deaf26..4f50b40c965 100644 --- a/src/phases/mystery-encounter-phases.ts +++ b/src/phases/mystery-encounter-phases.ts @@ -14,7 +14,7 @@ import type { OptionSelectSettings } from "#mystery-encounters/encounter-phase-u import { transitionMysteryEncounterIntroVisuals } from "#mystery-encounters/encounter-phase-utils"; import type { MysteryEncounterOption, OptionPhaseCallback } from "#mystery-encounters/mystery-encounter-option"; import { SeenEncounterData } from "#mystery-encounters/mystery-encounter-save-data"; -import { isNullOrUndefined, randSeedItem } from "#utils/common"; +import { randSeedItem } from "#utils/common"; import i18next from "i18next"; /** @@ -93,7 +93,7 @@ export class MysteryEncounterPhase extends Phase { if (option.onPreOptionPhase) { globalScene.executeWithSeedOffset(async () => { return await option.onPreOptionPhase!().then(result => { - if (isNullOrUndefined(result) || result) { + if (result == null || result) { this.continueEncounter(); } }); @@ -578,7 +578,7 @@ export class PostMysteryEncounterPhase extends Phase { if (this.onPostOptionSelect) { globalScene.executeWithSeedOffset(async () => { return await this.onPostOptionSelect!().then(result => { - if (isNullOrUndefined(result) || result) { + if (result == null || result) { this.continueEncounter(); } }); diff --git a/src/phases/pokemon-anim-phase.ts b/src/phases/pokemon-anim-phase.ts index 39e9c609aec..c45f201641c 100644 --- a/src/phases/pokemon-anim-phase.ts +++ b/src/phases/pokemon-anim-phase.ts @@ -4,7 +4,6 @@ import { PokemonAnimType } from "#enums/pokemon-anim-type"; import { SpeciesId } from "#enums/species-id"; import type { Pokemon } from "#field/pokemon"; import { BattlePhase } from "#phases/battle-phase"; -import { isNullOrUndefined } from "#utils/common"; export class PokemonAnimPhase extends BattlePhase { public readonly phaseName = "PokemonAnimPhase"; @@ -52,7 +51,7 @@ export class PokemonAnimPhase extends BattlePhase { private doSubstituteAddAnim(): void { const substitute = this.pokemon.getTag(SubstituteTag); - if (isNullOrUndefined(substitute)) { + if (substitute == null) { this.end(); return; } @@ -336,7 +335,7 @@ export class PokemonAnimPhase extends BattlePhase { // Note: unlike the other Commander animation, this is played through the // Dondozo instead of the Tatsugiri. const tatsugiri = this.pokemon.getAlly(); - if (isNullOrUndefined(tatsugiri)) { + if (tatsugiri == null) { console.warn("Aborting COMMANDER_REMOVE anim: Tatsugiri is undefined"); this.end(); return; diff --git a/src/phases/revival-blessing-phase.ts b/src/phases/revival-blessing-phase.ts index fdb108d62ac..5d75f2c9b47 100644 --- a/src/phases/revival-blessing-phase.ts +++ b/src/phases/revival-blessing-phase.ts @@ -5,7 +5,7 @@ import type { PlayerPokemon } from "#field/pokemon"; import { BattlePhase } from "#phases/battle-phase"; import type { PartyOption } from "#ui/party-ui-handler"; import { PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler"; -import { isNullOrUndefined, toDmgValue } from "#utils/common"; +import { toDmgValue } from "#utils/common"; import i18next from "i18next"; /** @@ -42,11 +42,7 @@ export class RevivalBlessingPhase extends BattlePhase { ); const allyPokemon = this.user.getAlly(); - if ( - globalScene.currentBattle.double - && globalScene.getPlayerParty().length > 1 - && !isNullOrUndefined(allyPokemon) - ) { + if (globalScene.currentBattle.double && globalScene.getPlayerParty().length > 1 && allyPokemon != null) { if (slotIndex <= 1) { // Revived ally pokemon globalScene.phaseManager.unshiftNew( diff --git a/src/phases/select-modifier-phase.ts b/src/phases/select-modifier-phase.ts index 3c378a95b2a..2031fc5c5f1 100644 --- a/src/phases/select-modifier-phase.ts +++ b/src/phases/select-modifier-phase.ts @@ -27,7 +27,7 @@ import { BattlePhase } from "#phases/battle-phase"; import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import { SHOP_OPTIONS_ROW_LIMIT } from "#ui/modifier-select-ui-handler"; import { PartyOption, PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler"; -import { isNullOrUndefined, NumberHolder } from "#utils/common"; +import { NumberHolder } from "#utils/common"; import i18next from "i18next"; export type ModifierSelectCallback = (rowCursor: number, cursor: number) => boolean; @@ -429,7 +429,7 @@ export class SelectModifierPhase extends BattlePhase { } let multiplier = 1; - if (!isNullOrUndefined(this.customModifierSettings?.rerollMultiplier)) { + if (this.customModifierSettings?.rerollMultiplier != null) { if (this.customModifierSettings.rerollMultiplier < 0) { // Completely overrides reroll cost to -1 and early exits return -1; diff --git a/src/phases/select-starter-phase.ts b/src/phases/select-starter-phase.ts index a08394e3acb..27e2150fd06 100644 --- a/src/phases/select-starter-phase.ts +++ b/src/phases/select-starter-phase.ts @@ -10,7 +10,6 @@ import { overrideHeldItems, overrideModifiers } from "#modifiers/modifier"; import { SaveSlotUiMode } from "#ui/save-slot-select-ui-handler"; import type { Starter } from "#ui/starter-select-ui-handler"; import { applyChallenges } from "#utils/challenge-utils"; -import { isNullOrUndefined } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; @@ -51,7 +50,7 @@ export class SelectStarterPhase extends Phase { let starterFormIndex = Math.min(starterProps.formIndex, Math.max(starter.species.forms.length - 1, 0)); if ( starter.species.speciesId in Overrides.STARTER_FORM_OVERRIDES - && !isNullOrUndefined(Overrides.STARTER_FORM_OVERRIDES[starter.species.speciesId]) + && Overrides.STARTER_FORM_OVERRIDES[starter.species.speciesId] != null && starter.species.forms[Overrides.STARTER_FORM_OVERRIDES[starter.species.speciesId]!] ) { starterFormIndex = Overrides.STARTER_FORM_OVERRIDES[starter.species.speciesId]!; @@ -89,7 +88,7 @@ export class SelectStarterPhase extends Phase { starterPokemon.nickname = starter.nickname; } - if (!isNullOrUndefined(starter.teraType)) { + if (starter.teraType != null) { starterPokemon.teraType = starter.teraType; } else { starterPokemon.teraType = starterPokemon.species.type1; diff --git a/src/phases/stat-stage-change-phase.ts b/src/phases/stat-stage-change-phase.ts index 6c15342ddeb..2731c037d5f 100644 --- a/src/phases/stat-stage-change-phase.ts +++ b/src/phases/stat-stage-change-phase.ts @@ -13,7 +13,7 @@ import type { Pokemon } from "#field/pokemon"; import { ResetNegativeStatStageModifier } from "#modifiers/modifier"; import { PokemonPhase } from "#phases/pokemon-phase"; import type { ConditionalUserFieldProtectStatAbAttrParams, PreStatStageChangeAbAttrParams } from "#types/ability-types"; -import { BooleanHolder, isNullOrUndefined, NumberHolder } from "#utils/common"; +import { BooleanHolder, NumberHolder } from "#utils/common"; import i18next from "i18next"; export type StatStageChangeCallback = ( @@ -153,7 +153,7 @@ export class StatStageChangePhase extends PokemonPhase { applyAbAttrs("ConditionalUserFieldProtectStatAbAttr", abAttrParams); // TODO: Consider skipping this call if `cancelled` is false. const ally = pokemon.getAlly(); - if (!isNullOrUndefined(ally)) { + if (ally != null) { applyAbAttrs("ConditionalUserFieldProtectStatAbAttr", { ...abAttrParams, pokemon: ally }); } diff --git a/src/phases/title-phase.ts b/src/phases/title-phase.ts index d422766bf09..414be4c820c 100644 --- a/src/phases/title-phase.ts +++ b/src/phases/title-phase.ts @@ -18,7 +18,7 @@ import { vouchers } from "#system/voucher"; import type { SessionSaveData } from "#types/save-data"; import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; import { SaveSlotUiMode } from "#ui/save-slot-select-ui-handler"; -import { isLocal, isLocalServerConnected, isNullOrUndefined } from "#utils/common"; +import { isLocal, isLocalServerConnected } from "#utils/common"; import i18next from "i18next"; export class TitlePhase extends Phase { @@ -289,7 +289,7 @@ export class TitlePhase extends Phase { } else { // Grab first 10 chars of ISO date format (YYYY-MM-DD) and convert to base64 let seed: string = btoa(new Date().toISOString().substring(0, 10)); - if (!isNullOrUndefined(Overrides.DAILY_RUN_SEED_OVERRIDE)) { + if (Overrides.DAILY_RUN_SEED_OVERRIDE != null) { seed = Overrides.DAILY_RUN_SEED_OVERRIDE; } generateDaily(seed); diff --git a/src/sprites/variant.ts b/src/sprites/variant.ts index 28d7ed13839..9d7a20bc058 100644 --- a/src/sprites/variant.ts +++ b/src/sprites/variant.ts @@ -2,7 +2,6 @@ import { globalScene } from "#app/global-scene"; import { VariantTier } from "#enums/variant-tier"; import type { Pokemon } from "#field/pokemon"; import { hasExpSprite } from "#sprites/sprite-utils"; -import { isNullOrUndefined } from "#utils/common"; export type Variant = 0 | 1 | 2; @@ -138,7 +137,7 @@ export async function populateVariantColorCache( return fallbackVariantColor(cacheKey, spritePath, useExpSprite, battleSpritePath, error); }) .then(c => { - if (!isNullOrUndefined(c)) { + if (c != null) { variantColorCache[cacheKey] = c; } }); diff --git a/src/system/ribbons/ribbon-methods.ts b/src/system/ribbons/ribbon-methods.ts index 138c0be7b51..f1aeb9fefc2 100644 --- a/src/system/ribbons/ribbon-methods.ts +++ b/src/system/ribbons/ribbon-methods.ts @@ -2,7 +2,6 @@ import { globalScene } from "#app/global-scene"; import { pokemonPrevolutions } from "#balance/pokemon-evolutions"; import type { SpeciesId } from "#enums/species-id"; import type { RibbonFlag } from "#system/ribbons/ribbon-data"; -import { isNullOrUndefined } from "#utils/common"; /** * Award one or more ribbons to a species and its pre-evolutions @@ -14,7 +13,7 @@ export function awardRibbonsToSpeciesLine(id: SpeciesId, ribbons: RibbonFlag): v const dexData = globalScene.gameData.dexData; dexData[id].ribbons.award(ribbons); // Mark all pre-evolutions of the Pokémon with the same ribbon flags. - for (let prevoId = pokemonPrevolutions[id]; !isNullOrUndefined(prevoId); prevoId = pokemonPrevolutions[prevoId]) { + for (let prevoId = pokemonPrevolutions[id]; prevoId != null; prevoId = pokemonPrevolutions[prevoId]) { dexData[prevoId].ribbons.award(ribbons); } } diff --git a/src/system/version-migration/versions/v1_0_4.ts b/src/system/version-migration/versions/v1_0_4.ts index 8229b9320d5..5342396d576 100644 --- a/src/system/version-migration/versions/v1_0_4.ts +++ b/src/system/version-migration/versions/v1_0_4.ts @@ -8,7 +8,6 @@ import type { SessionSaveData, SystemSaveData } from "#types/save-data"; 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"; /** * Migrate ability starter data if empty for caught species. @@ -82,7 +81,7 @@ const fixLegendaryStats: SystemSaveMigrator = { const fixStarterData: SystemSaveMigrator = { version: "1.0.4", migrate: (data: SystemSaveData): void => { - if (!isNullOrUndefined(data.starterData)) { + if (data.starterData != null) { for (const starterId of defaultStarterSpecies) { if (data.starterData[starterId]?.abilityAttr) { data.starterData[starterId].abilityAttr |= AbilityAttr.ABILITY_1; @@ -198,7 +197,7 @@ const migrateCustomPokemonData: SessionSaveMigrator = { pokemon["fusionMysteryEncounterPokemonData"] = null; } pokemon.customPokemonData = pokemon.customPokemonData ?? new CustomPokemonData(); - if (!isNullOrUndefined(pokemon["natureOverride"]) && pokemon["natureOverride"] >= 0) { + if (pokemon["natureOverride"] != null && pokemon["natureOverride"] >= 0) { pokemon.customPokemonData.nature = pokemon["natureOverride"]; pokemon["natureOverride"] = -1; } diff --git a/src/system/version-migration/versions/v1_7_0.ts b/src/system/version-migration/versions/v1_7_0.ts index 6d365cf31ac..e526ccd2c2b 100644 --- a/src/system/version-migration/versions/v1_7_0.ts +++ b/src/system/version-migration/versions/v1_7_0.ts @@ -3,7 +3,6 @@ import { DexAttr } from "#enums/dex-attr"; import type { SessionSaveData, SystemSaveData } from "#types/save-data"; import type { SessionSaveMigrator } from "#types/session-save-migrator"; import type { SystemSaveMigrator } from "#types/system-save-migrator"; -import { isNullOrUndefined } from "#utils/common"; import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; /** @@ -68,13 +67,13 @@ const migrateTera: SessionSaveMigrator = { } data.party.forEach(p => { - if (isNullOrUndefined(p.teraType)) { + if (p.teraType == null) { p.teraType = getPokemonSpeciesForm(p.species, p.formIndex).type1; } }); data.enemyParty.forEach(p => { - if (isNullOrUndefined(p.teraType)) { + if (p.teraType == null) { p.teraType = getPokemonSpeciesForm(p.species, p.formIndex).type1; } }); diff --git a/src/timed-event-manager.ts b/src/timed-event-manager.ts index ed92a1c9ca5..7db89b2a0ef 100644 --- a/src/timed-event-manager.ts +++ b/src/timed-event-manager.ts @@ -9,7 +9,6 @@ import { TextStyle } from "#enums/text-style"; import { WeatherType } from "#enums/weather-type"; import { addTextObject } from "#ui/text"; import type { nil } from "#utils/common"; -import { isNullOrUndefined } from "#utils/common"; import i18next from "i18next"; export enum EventType { @@ -428,7 +427,7 @@ export class TimedEventManager { getEventBannerLangs(): string[] { const ret: string[] = []; - ret.push(...timedEvents.find(te => this.isActive(te) && !isNullOrUndefined(te.availableLangs))?.availableLangs!); + ret.push(...timedEvents.find(te => this.isActive(te) && te.availableLangs != null)?.availableLangs!); return ret; } @@ -437,7 +436,7 @@ export class TimedEventManager { timedEvents .filter(te => this.isActive(te)) .map(te => { - if (!isNullOrUndefined(te.eventEncounters)) { + if (te.eventEncounters != null) { ret.push(...te.eventEncounters); } }); @@ -452,7 +451,7 @@ export class TimedEventManager { let multiplier = CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER; const classicFriendshipEvents = timedEvents.filter(te => this.isActive(te)); for (const fe of classicFriendshipEvents) { - if (!isNullOrUndefined(fe.classicFriendshipMultiplier) && fe.classicFriendshipMultiplier > multiplier) { + if (fe.classicFriendshipMultiplier != null && fe.classicFriendshipMultiplier > multiplier) { multiplier = fe.classicFriendshipMultiplier; } } @@ -476,7 +475,7 @@ export class TimedEventManager { timedEvents .filter(te => this.isActive(te)) .map(te => { - if (!isNullOrUndefined(te.delibirdyBuff)) { + if (te.delibirdyBuff != null) { ret.push(...te.delibirdyBuff); } }); @@ -492,7 +491,7 @@ export class TimedEventManager { timedEvents .filter(te => this.isActive(te)) .map(te => { - if (!isNullOrUndefined(te.weather)) { + if (te.weather != null) { ret.push(...te.weather); } }); @@ -504,7 +503,7 @@ export class TimedEventManager { timedEvents .filter(te => this.isActive(te)) .map(te => { - if (!isNullOrUndefined(te.mysteryEncounterTierChanges)) { + if (te.mysteryEncounterTierChanges != null) { ret.push(...te.mysteryEncounterTierChanges); } }); @@ -514,7 +513,7 @@ export class TimedEventManager { getEventMysteryEncountersDisabled(): MysteryEncounterType[] { const ret: MysteryEncounterType[] = []; timedEvents - .filter(te => this.isActive(te) && !isNullOrUndefined(te.mysteryEncounterTierChanges)) + .filter(te => this.isActive(te) && te.mysteryEncounterTierChanges != null) .map(te => { te.mysteryEncounterTierChanges?.map(metc => { if (metc.disable) { @@ -531,7 +530,7 @@ export class TimedEventManager { ): MysteryEncounterTier { let ret = normal; timedEvents - .filter(te => this.isActive(te) && !isNullOrUndefined(te.mysteryEncounterTierChanges)) + .filter(te => this.isActive(te) && te.mysteryEncounterTierChanges != null) .map(te => { te.mysteryEncounterTierChanges?.map(metc => { if (metc.mysteryEncounter === encounterType) { @@ -544,7 +543,7 @@ export class TimedEventManager { getEventLuckBoost(): number { let ret = 0; - const luckEvents = timedEvents.filter(te => this.isActive(te) && !isNullOrUndefined(te.luckBoost)); + const luckEvents = timedEvents.filter(te => this.isActive(te) && te.luckBoost != null); for (const le of luckEvents) { ret += le.luckBoost!; } @@ -556,7 +555,7 @@ export class TimedEventManager { timedEvents .filter(te => this.isActive(te)) .map(te => { - if (!isNullOrUndefined(te.luckBoostedSpecies)) { + if (te.luckBoostedSpecies != null) { ret.push(...te.luckBoostedSpecies.filter(s => !ret.includes(s))); } }); @@ -576,7 +575,7 @@ export class TimedEventManager { getFixedBattleEventRewards(wave: number): string[] { const ret: string[] = []; timedEvents - .filter(te => this.isActive(te) && !isNullOrUndefined(te.classicWaveRewards)) + .filter(te => this.isActive(te) && te.classicWaveRewards != null) .map(te => { ret.push(...te.classicWaveRewards!.filter(cwr => cwr.wave === wave).map(cwr => cwr.type)); }); @@ -586,7 +585,7 @@ export class TimedEventManager { // Gets the extra shiny chance for trainers due to event (odds/65536) getClassicTrainerShinyChance(): number { let ret = 0; - const tsEvents = timedEvents.filter(te => this.isActive(te) && !isNullOrUndefined(te.trainerShinyChance)); + const tsEvents = timedEvents.filter(te => this.isActive(te) && te.trainerShinyChance != null); tsEvents.map(t => (ret += t.trainerShinyChance!)); return ret; } @@ -594,7 +593,7 @@ export class TimedEventManager { getEventBgmReplacement(bgm: string): string { let ret = bgm; timedEvents.map(te => { - if (this.isActive(te) && !isNullOrUndefined(te.music)) { + if (this.isActive(te) && te.music != null) { te.music.map(mr => { if (mr[0] === bgm) { console.log(`it is ${te.name} so instead of ${mr[0]} we play ${mr[1]}`); diff --git a/src/ui/containers/pokedex-mon-container.ts b/src/ui/containers/pokedex-mon-container.ts index 15ef6c9b5c8..158f42dd42a 100644 --- a/src/ui/containers/pokedex-mon-container.ts +++ b/src/ui/containers/pokedex-mon-container.ts @@ -3,7 +3,6 @@ import type { PokemonSpecies } from "#data/pokemon-species"; import { TextStyle } from "#enums/text-style"; import type { Variant } from "#sprites/variant"; import { addTextObject } from "#ui/text"; -import { isNullOrUndefined } from "#utils/common"; interface SpeciesDetails { shiny?: boolean; @@ -177,16 +176,16 @@ export class PokedexMonContainer extends Phaser.GameObjects.Container { const defaultDexAttr = globalScene.gameData.getSpeciesDefaultDexAttr(species, false, true); const defaultProps = globalScene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr); - if (!isNullOrUndefined(formIndex)) { + if (formIndex != null) { defaultProps.formIndex = formIndex; } - if (!isNullOrUndefined(shiny)) { + if (shiny != null) { defaultProps.shiny = shiny; } - if (!isNullOrUndefined(variant)) { + if (variant != null) { defaultProps.variant = variant; } - if (!isNullOrUndefined(female)) { + if (female != null) { defaultProps.female = female; } diff --git a/src/ui/handlers/mystery-encounter-ui-handler.ts b/src/ui/handlers/mystery-encounter-ui-handler.ts index bbbd3cb4af8..e4c9dfbfee3 100644 --- a/src/ui/handlers/mystery-encounter-ui-handler.ts +++ b/src/ui/handlers/mystery-encounter-ui-handler.ts @@ -13,7 +13,7 @@ import { PartyUiMode } from "#ui/party-ui-handler"; 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"; +import { fixedInt } from "#utils/common"; import i18next from "i18next"; import type BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; @@ -95,12 +95,10 @@ export class MysteryEncounterUiHandler extends UiHandler { super.show(args); this.overrideSettings = (args[0] as OptionSelectSettings) ?? {}; - const showDescriptionContainer = isNullOrUndefined(this.overrideSettings?.hideDescription) - ? true - : !this.overrideSettings.hideDescription; - const slideInDescription = isNullOrUndefined(this.overrideSettings?.slideInDescription) - ? true - : this.overrideSettings.slideInDescription; + const showDescriptionContainer = + this.overrideSettings?.hideDescription == null ? true : !this.overrideSettings.hideDescription; + const slideInDescription = + this.overrideSettings?.slideInDescription == null ? true : this.overrideSettings.slideInDescription; const startingCursorIndex = this.overrideSettings?.startingCursorIndex ?? 0; this.cursorContainer.setVisible(true); @@ -567,7 +565,7 @@ export class MysteryEncounterUiHandler extends UiHandler { } this.tooltipContainer.setVisible(true); - if (isNullOrUndefined(cursor) || cursor > this.optionsContainer.length - 2) { + if (cursor == null || cursor > this.optionsContainer.length - 2) { // Ignore hovers on view party button // Hide dex progress if visible this.showHideDexProgress(false); diff --git a/src/ui/handlers/pokedex-page-ui-handler.ts b/src/ui/handlers/pokedex-page-ui-handler.ts index 253309bf94a..31e2998b850 100644 --- a/src/ui/handlers/pokedex-page-ui-handler.ts +++ b/src/ui/handlers/pokedex-page-ui-handler.ts @@ -54,7 +54,7 @@ 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 } from "#utils/common"; +import { BooleanHolder, getLocalizedSpriteKey, padInt, rgbHexToRgba } from "#utils/common"; import { getEnumValues } from "#utils/enums"; import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; import { toCamelCase, toTitleCase } from "#utils/strings"; @@ -2424,11 +2424,7 @@ export class PokedexPageUiHandler extends MessageUiHandler { // We will only update the sprite if there is a change to form, shiny/variant // or gender for species with gender sprite differences const shouldUpdateSprite = - (species?.genderDiffs && !isNullOrUndefined(female)) - || !isNullOrUndefined(formIndex) - || !isNullOrUndefined(shiny) - || !isNullOrUndefined(variant) - || forceUpdate; + (species?.genderDiffs && female != null) || formIndex != null || shiny != null || variant != null || forceUpdate; if (this.activeTooltip === "CANDY") { if (this.species && this.pokemonCandyContainer.visible) { diff --git a/src/ui/handlers/pokedex-scan-ui-handler.ts b/src/ui/handlers/pokedex-scan-ui-handler.ts index 1f5195588f3..18afd0598c2 100644 --- a/src/ui/handlers/pokedex-scan-ui-handler.ts +++ b/src/ui/handlers/pokedex-scan-ui-handler.ts @@ -6,7 +6,6 @@ import { FilterTextRow } from "#ui/filter-text"; 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 { isNullOrUndefined } from "#utils/common"; import i18next from "i18next"; export class PokedexScanUiHandler extends FormModalUiHandler { @@ -132,7 +131,7 @@ export class PokedexScanUiHandler extends FormModalUiHandler { return { label: value, handler: () => { - if (!isNullOrUndefined(evt.data) || evt.inputType?.toLowerCase() === "deletecontentbackward") { + if (evt.data != null || evt.inputType?.toLowerCase() === "deletecontentbackward") { inputObject.setText(value); } ui.revertMode(); diff --git a/src/ui/handlers/save-slot-select-ui-handler.ts b/src/ui/handlers/save-slot-select-ui-handler.ts index a71be5dd070..194971a005f 100644 --- a/src/ui/handlers/save-slot-select-ui-handler.ts +++ b/src/ui/handlers/save-slot-select-ui-handler.ts @@ -13,7 +13,7 @@ import { MessageUiHandler } from "#ui/message-ui-handler"; import { RunDisplayMode } from "#ui/run-info-ui-handler"; import { addTextObject } from "#ui/text"; import { addWindow } from "#ui/ui-theme"; -import { fixedInt, formatLargeNumber, getPlayTimeString, isNullOrUndefined } from "#utils/common"; +import { fixedInt, formatLargeNumber, getPlayTimeString } from "#utils/common"; import i18next from "i18next"; const SESSION_SLOTS_COUNT = 5; @@ -405,7 +405,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler { } this.setArrowVisibility(hasData); } - if (!isNullOrUndefined(prevSlotIndex)) { + if (prevSlotIndex != null) { this.revertSessionSlot(prevSlotIndex); } diff --git a/src/ui/handlers/starter-select-ui-handler.ts b/src/ui/handlers/starter-select-ui-handler.ts index 18be7e130e3..53e566864b1 100644 --- a/src/ui/handlers/starter-select-ui-handler.ts +++ b/src/ui/handlers/starter-select-ui-handler.ts @@ -66,7 +66,6 @@ import { BooleanHolder, fixedInt, getLocalizedSpriteKey, - isNullOrUndefined, NumberHolder, padInt, randIntRange, @@ -2548,7 +2547,7 @@ export class StarterSelectUiHandler extends MessageUiHandler { case Button.CYCLE_TERA: if (this.canCycleTera) { const speciesForm = getPokemonSpeciesForm(this.lastSpecies.speciesId, starterAttributes.form ?? 0); - if (speciesForm.type1 === this.teraCursor && !isNullOrUndefined(speciesForm.type2)) { + if (speciesForm.type1 === this.teraCursor && speciesForm.type2 != null) { starterAttributes.tera = speciesForm.type2; originalStarterAttributes.tera = starterAttributes.tera; this.setSpeciesDetails(this.lastSpecies, { @@ -2790,7 +2789,7 @@ export class StarterSelectUiHandler extends MessageUiHandler { */ switchMoveHandler(targetIndex: number, newMove: MoveId, previousMove: MoveId) { const starterMoveset = this.starterMoveset; - if (isNullOrUndefined(starterMoveset)) { + if (starterMoveset == null) { console.warn("Trying to update a non-existing moveset"); return; } @@ -3687,7 +3686,7 @@ export class StarterSelectUiHandler extends MessageUiHandler { ); } - if (!isNullOrUndefined(props.formIndex)) { + if (props.formIndex != null) { // If switching forms while the pokemon is in the team, update its moveset this.updateSelectedStarterMoveset(species.speciesId); } @@ -3809,10 +3808,7 @@ export class StarterSelectUiHandler extends MessageUiHandler { // We will only update the sprite if there is a change to form, shiny/variant // or gender for species with gender sprite differences const shouldUpdateSprite = - (species?.genderDiffs && !isNullOrUndefined(female)) - || !isNullOrUndefined(formIndex) - || !isNullOrUndefined(shiny) - || !isNullOrUndefined(variant); + (species?.genderDiffs && female != null) || formIndex != null || shiny != null || variant != null; const isFreshStartChallenge = globalScene.gameMode.hasChallenge(Challenges.FRESH_START); @@ -3850,7 +3846,7 @@ export class StarterSelectUiHandler extends MessageUiHandler { ); // TODO: is this bang correct? this.abilityCursor = abilityIndex !== undefined ? abilityIndex : (abilityIndex = oldAbilityIndex); this.natureCursor = natureIndex !== undefined ? natureIndex : (natureIndex = oldNatureIndex); - this.teraCursor = !isNullOrUndefined(teraType) ? teraType : (teraType = oldTeraType); + this.teraCursor = teraType != null ? teraType : (teraType = oldTeraType); const [isInParty, partyIndex]: [boolean, number] = this.isInParty(species); // we use this to firstly check if the pokemon is in the party, and if so, to get the party index in order to update the icon image if (isInParty) { this.updatePartyIcon(species, partyIndex); @@ -3991,7 +3987,7 @@ export class StarterSelectUiHandler extends MessageUiHandler { this.canCycleTera = !this.statsMode && this.allowTera - && !isNullOrUndefined(getPokemonSpeciesForm(species.speciesId, formIndex ?? 0).type2) + && getPokemonSpeciesForm(species.speciesId, formIndex ?? 0).type2 != null && !globalScene.gameMode.hasChallenge(Challenges.FRESH_START); } @@ -4592,7 +4588,7 @@ export class StarterSelectUiHandler extends MessageUiHandler { this.canCycleTera = !this.statsMode && this.allowTera - && !isNullOrUndefined(getPokemonSpeciesForm(this.lastSpecies.speciesId, formIndex ?? 0).type2) + && getPokemonSpeciesForm(this.lastSpecies.speciesId, formIndex ?? 0).type2 != null && !globalScene.gameMode.hasChallenge(Challenges.FRESH_START); this.updateInstructions(); } diff --git a/src/ui/handlers/summary-ui-handler.ts b/src/ui/handlers/summary-ui-handler.ts index 1c647573cbf..c9c8229ebfd 100644 --- a/src/ui/handlers/summary-ui-handler.ts +++ b/src/ui/handlers/summary-ui-handler.ts @@ -27,15 +27,7 @@ import { getVariantTint } from "#sprites/variant"; import { achvs } from "#system/achv"; import { addBBCodeTextObject, addTextObject, getBBCodeFrag, getTextColor } from "#ui/text"; import { UiHandler } from "#ui/ui-handler"; -import { - fixedInt, - formatStat, - getLocalizedSpriteKey, - getShinyDescriptor, - isNullOrUndefined, - padInt, - rgbHexToRgba, -} from "#utils/common"; +import { fixedInt, formatStat, getLocalizedSpriteKey, getShinyDescriptor, padInt, rgbHexToRgba } from "#utils/common"; import { getEnumValues } from "#utils/enums"; import { toCamelCase, toTitleCase } from "#utils/strings"; import { argbFromRgba } from "@material/material-color-utilities"; @@ -895,10 +887,7 @@ export class SummaryUiHandler extends UiHandler { profileContainer.add(luckText); } - if ( - globalScene.gameData.achvUnlocks.hasOwnProperty(achvs.TERASTALLIZE.id) - && !isNullOrUndefined(this.pokemon) - ) { + if (globalScene.gameData.achvUnlocks.hasOwnProperty(achvs.TERASTALLIZE.id) && this.pokemon != null) { const teraIcon = globalScene.add.sprite(123, 26, "button_tera"); teraIcon.setName("terastallize-icon"); teraIcon.setFrame(PokemonType[this.pokemon.getTeraType()].toLowerCase()); diff --git a/src/ui/handlers/target-select-ui-handler.ts b/src/ui/handlers/target-select-ui-handler.ts index 4e3096b96f4..bd81278c661 100644 --- a/src/ui/handlers/target-select-ui-handler.ts +++ b/src/ui/handlers/target-select-ui-handler.ts @@ -8,7 +8,7 @@ import type { Pokemon } from "#field/pokemon"; import type { ModifierBar } from "#modifiers/modifier"; import { getMoveTargets } from "#moves/move-utils"; import { UiHandler } from "#ui/ui-handler"; -import { fixedInt, isNullOrUndefined } from "#utils/common"; +import { fixedInt } from "#utils/common"; export type TargetSelectCallback = (targets: BattlerIndex[]) => void; @@ -71,7 +71,7 @@ export class TargetSelectUiHandler extends UiHandler { */ resetCursor(cursorN: number, user: Pokemon): void { if ( - !isNullOrUndefined(cursorN) + cursorN != null && ([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2].includes(cursorN) || user.tempSummonData.waveTurnCount === 1) ) { // Reset cursor on the first turn of a fight or if an ally was targeted last turn @@ -90,13 +90,10 @@ export class TargetSelectUiHandler extends UiHandler { this.targetSelectCallback(button === Button.ACTION ? targetIndexes : []); success = true; if (this.fieldIndex === BattlerIndex.PLAYER) { - if (isNullOrUndefined(this.cursor0) || this.cursor0 !== this.cursor) { + if (this.cursor0 == null || this.cursor0 !== this.cursor) { this.cursor0 = this.cursor; } - } else if ( - this.fieldIndex === BattlerIndex.PLAYER_2 - && (isNullOrUndefined(this.cursor1) || this.cursor1 !== this.cursor) - ) { + } else if (this.fieldIndex === BattlerIndex.PLAYER_2 && (this.cursor1 == null || this.cursor1 !== this.cursor)) { this.cursor1 = this.cursor; } } else if (this.isMultipleTargets) { diff --git a/src/ui/handlers/test-dialogue-ui-handler.ts b/src/ui/handlers/test-dialogue-ui-handler.ts index bd5c1a1dc37..b33e6726547 100644 --- a/src/ui/handlers/test-dialogue-ui-handler.ts +++ b/src/ui/handlers/test-dialogue-ui-handler.ts @@ -4,7 +4,6 @@ import type { OptionSelectItem } from "#ui/abstract-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 { isNullOrUndefined } from "#utils/common"; import i18next from "i18next"; export class TestDialogueUiHandler extends FormModalUiHandler { @@ -18,7 +17,7 @@ export class TestDialogueUiHandler extends FormModalUiHandler { .map((t, i) => { const value = Object.values(object)[i]; - if (typeof value === "object" && !isNullOrUndefined(value)) { + if (typeof value === "object" && value != null) { // we check for not null or undefined here because if the language json file has a null key, the typeof will still be an object, but that object will be null, causing issues // If the value is an object, execute the same process // si el valor es un objeto ejecuta el mismo proceso @@ -27,7 +26,7 @@ export class TestDialogueUiHandler extends FormModalUiHandler { t => t.length > 0, ); } - if (typeof value === "string" || isNullOrUndefined(value)) { + if (typeof value === "string" || value == null) { // we check for null or undefined here as per above - the typeof is still an object but the value is null so we need to exit out of this and pass the null key // Return in the format expected by i18next @@ -109,7 +108,7 @@ export class TestDialogueUiHandler extends FormModalUiHandler { handler: () => { // this is here to make sure that if you try to backspace then enter, the last known evt.data (backspace) is picked up // this is because evt.data is null for backspace, so without this, the autocomplete windows just closes - if (!isNullOrUndefined(evt.data) || evt.inputType?.toLowerCase() === "deletecontentbackward") { + if (evt.data != null || evt.inputType?.toLowerCase() === "deletecontentbackward") { const separatedArray = inputObject.text.split(" "); separatedArray[separatedArray.length - 1] = value; inputObject.setText(separatedArray.join(" ")); diff --git a/src/utils/common.ts b/src/utils/common.ts index 2734b075a53..f0166b1e74c 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -458,15 +458,6 @@ export function truncateString(str: string, maxLength = 10) { return str; } -/** - * Report whether a given value is nullish (`null`/`undefined`). - * @param val - The value whose nullishness is being checked - * @returns `true` if `val` is either `null` or `undefined` - */ -export function isNullOrUndefined(val: any): val is null | undefined { - return val === null || val === undefined; -} - /** * 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. diff --git a/test/abilities/healer.test.ts b/test/abilities/healer.test.ts index 43280ff8271..fb28cd891ac 100644 --- a/test/abilities/healer.test.ts +++ b/test/abilities/healer.test.ts @@ -6,7 +6,6 @@ import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import type { Pokemon } from "#field/pokemon"; 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"; @@ -37,7 +36,7 @@ describe("Abilities - Healer", () => { // Mock healer to have a 100% chance of healing its ally vi.spyOn(allAbilities[AbilityId.HEALER].getAttrs("PostTurnResetStatusAbAttr")[0], "getCondition").mockReturnValue( - (pokemon: Pokemon) => !isNullOrUndefined(pokemon.getAlly()), + (pokemon: Pokemon) => pokemon.getAlly() != null, ); }); diff --git a/test/eggs/egg.test.ts b/test/eggs/egg.test.ts index 8b47e68f402..001adf83b37 100644 --- a/test/eggs/egg.test.ts +++ b/test/eggs/egg.test.ts @@ -202,7 +202,7 @@ describe("Egg Generation Tests", () => { const scene = game.scene; const eggMoveIndex = new Egg({ scene }).eggMoveIndex; - const result = !Utils.isNullOrUndefined(eggMoveIndex) && eggMoveIndex >= 0 && eggMoveIndex <= 3; + const result = eggMoveIndex != null && eggMoveIndex >= 0 && eggMoveIndex <= 3; expect(result).toBe(true); }); diff --git a/test/mystery-encounter/encounter-test-utils.ts b/test/mystery-encounter/encounter-test-utils.ts index 7b2dbfc9aeb..4aad0e000d9 100644 --- a/test/mystery-encounter/encounter-test-utils.ts +++ b/test/mystery-encounter/encounter-test-utils.ts @@ -17,7 +17,6 @@ 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"; import type { PartyUiHandler } from "#ui/party-ui-handler"; -import { isNullOrUndefined } from "#utils/common"; import { expect, vi } from "vitest"; /** @@ -147,7 +146,7 @@ export async function runSelectMysteryEncounterOption( break; } - if (!isNullOrUndefined(secondaryOptionSelect?.pokemonNo)) { + if (secondaryOptionSelect?.pokemonNo != null) { await handleSecondaryOptionSelect(game, secondaryOptionSelect.pokemonNo, secondaryOptionSelect.optionNo); } else { uiHandler.processInput(Button.ACTION); @@ -174,7 +173,7 @@ async function handleSecondaryOptionSelect(game: GameManager, pokemonNo: number, partyUiHandler.processInput(Button.ACTION); // If there is a second choice to make after selecting a Pokemon - if (!isNullOrUndefined(optionNo)) { + if (optionNo != null) { // Wait for Summary menu to close and second options to spawn const secondOptionUiHandler = game.scene.ui.handlers[UiMode.OPTION_SELECT] as OptionSelectUiHandler; vi.spyOn(secondOptionUiHandler, "show"); diff --git a/test/test-utils/game-manager.ts b/test/test-utils/game-manager.ts index 1b379daae88..f9db964ad26 100644 --- a/test/test-utils/game-manager.ts +++ b/test/test-utils/game-manager.ts @@ -52,7 +52,6 @@ import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import type { PartyUiHandler } from "#ui/party-ui-handler"; import type { StarterSelectUiHandler } from "#ui/starter-select-ui-handler"; import type { TargetSelectUiHandler } from "#ui/target-select-ui-handler"; -import { isNullOrUndefined } from "#utils/common"; import fs from "node:fs"; import { AES, enc } from "crypto-js"; import { expect, vi } from "vitest"; @@ -240,7 +239,7 @@ export class GameManager { * @returns A Promise that resolves when the EncounterPhase ends. */ async runToMysteryEncounter(encounterType?: MysteryEncounterType, species?: SpeciesId[]) { - if (!isNullOrUndefined(encounterType)) { + if (encounterType != null) { this.override.disableTrainerWaves(); this.override.mysteryEncounter(encounterType); } @@ -272,7 +271,7 @@ export class GameManager { ); await this.phaseInterceptor.to("EncounterPhase"); - if (!isNullOrUndefined(encounterType)) { + if (encounterType != null) { expect(this.scene.currentBattle?.mysteryEncounter?.encounterType).toBe(encounterType); } } From 465f0c2ced921429cf06ace4c26ebb22bd52db06 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Sat, 13 Sep 2025 01:19:48 -0400 Subject: [PATCH 15/29] [Refactor] `getPokemonById` returns `undefined` instead of `null` https://github.com/pagefaultgames/pokerogue/pull/6544 * [Refactor] Make `BattleScene.getPokemonById` return `undefined` instead of `null` * fixed substitute unit test :( * Update src/phases/obtain-status-effect-phase.ts Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> * Update src/phases/pokemon-phase.ts Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> * Update battle-scene.ts comment for dean * Add todo comment --------- Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/battle-scene.ts | 19 ++++++++++--------- src/data/arena-tag.ts | 11 +++++------ src/data/battler-tags.ts | 4 ++-- src/modifier/modifier.ts | 2 +- src/phases/move-effect-phase.ts | 11 ++++++++--- src/phases/obtain-status-effect-phase.ts | 1 + src/phases/pokemon-phase.ts | 7 +++++-- test/battler-tags/substitute.test.ts | 2 +- 8 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 74b44d324d7..374cf3f270f 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -858,20 +858,21 @@ export class BattleScene extends SceneBase { } /** - * Return the {@linkcode Pokemon} associated with a given ID. - * @param pokemonId - The ID whose Pokemon will be retrieved. - * @returns The {@linkcode Pokemon} associated with the given id. - * Returns `null` if the ID is `undefined` or not present in either party. - * @todo Change the `null` to `undefined` and update callers' signatures - - * this is weird and causes a lot of random jank + * Return the {@linkcode Pokemon} associated with the given ID. + * @param pokemonId - The PID whose Pokemon will be retrieved + * @returns The `Pokemon` associated with the given ID, + * or `undefined` if none is found in either team's party. + * @see {@linkcode Pokemon.id} + * @todo `pokemonId` should not allow `undefined` */ - getPokemonById(pokemonId: number | undefined): Pokemon | null { + public getPokemonById(pokemonId: number | undefined): Pokemon | undefined { if (pokemonId == null) { - return null; + // biome-ignore lint/nursery/noUselessUndefined: More explicit + return undefined; } const party = (this.getPlayerParty() as Pokemon[]).concat(this.getEnemyParty()); - return party.find(p => p.id === pokemonId) ?? null; + return party.find(p => p.id === pokemonId); } addPlayerPokemon( diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index 22955e0a9ac..d3098314beb 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -138,7 +138,7 @@ export abstract class ArenaTag implements BaseArenaTag { } } - onOverlap(_arena: Arena, _source: Pokemon | null): void {} + onOverlap(_arena: Arena, _source: Pokemon | undefined): void {} /** * Trigger this {@linkcode ArenaTag}'s effect, reducing its duration as applicable. @@ -172,9 +172,8 @@ export abstract class ArenaTag implements BaseArenaTag { /** * Helper function that retrieves the source Pokemon * @returns - The source {@linkcode Pokemon} for this tag. - * Returns `null` if `this.sourceId` is `undefined` */ - public getSourcePokemon(): Pokemon | null { + public getSourcePokemon(): Pokemon | undefined { return globalScene.getPokemonById(this.sourceId); } @@ -617,7 +616,7 @@ export class NoCritTag extends SerializableArenaTag { globalScene.phaseManager.queueMessage( i18next.t("arenaTag:noCritOnRemove", { - pokemonNameWithAffix: getPokemonNameWithAffix(source ?? undefined), + pokemonNameWithAffix: getPokemonNameWithAffix(source), moveName: this.getMoveName(), }), ); @@ -1537,7 +1536,7 @@ export class SuppressAbilitiesTag extends SerializableArenaTag { } } - public override onOverlap(_arena: Arena, source: Pokemon | null): void { + public override onOverlap(_arena: Arena, source: Pokemon | undefined): void { (this as Mutable).sourceCount++; this.playActivationMessage(source); } @@ -1580,7 +1579,7 @@ export class SuppressAbilitiesTag extends SerializableArenaTag { return this.sourceCount > 1; } - private playActivationMessage(pokemon: Pokemon | null) { + private playActivationMessage(pokemon: Pokemon | undefined) { if (pokemon) { globalScene.phaseManager.queueMessage( i18next.t("arenaTag:neutralizingGasOnAdd", { diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 711a2bd0b44..6490a6086c4 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -198,7 +198,7 @@ export class BattlerTag implements BaseBattlerTag { * Helper function that retrieves the source Pokemon object * @returns The source {@linkcode Pokemon}, or `null` if none is found */ - public getSourcePokemon(): Pokemon | null { + public getSourcePokemon(): Pokemon | undefined { return globalScene.getPokemonById(this.sourceId); } } @@ -968,7 +968,7 @@ export class InfatuatedTag extends SerializableBattlerTag { phaseManager.queueMessage( i18next.t("battlerTags:infatuatedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - sourcePokemonName: getPokemonNameWithAffix(globalScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct? + sourcePokemonName: getPokemonNameWithAffix(this.getSourcePokemon()), }), ); phaseManager.unshiftNew("CommonAnimPhase", pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT); diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 82e64316edd..b94c479e96e 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -728,7 +728,7 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier { } getPokemon(): Pokemon | undefined { - return globalScene.getPokemonById(this.pokemonId) ?? undefined; + return globalScene.getPokemonById(this.pokemonId); } getScoreMultiplier(): number { diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index 717bc670558..18e25b328f8 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -645,13 +645,18 @@ export class MoveEffectPhase extends PokemonPhase { return move.getAttrs("HitsTagAttr").some(hta => hta.tagType === semiInvulnerableTag.tagType); } - /** @returns The {@linkcode Pokemon} using this phase's invoked move */ - public getUserPokemon(): Pokemon | null { + /** + * @todo Investigate why this doesn't use `BattlerIndex` + * @returns The {@linkcode Pokemon} using this phase's invoked move + */ + public getUserPokemon(): Pokemon | undefined { // TODO: Make this purely a battler index if (this.battlerIndex > BattlerIndex.ENEMY_2) { return globalScene.getPokemonById(this.battlerIndex); } - return (this.player ? globalScene.getPlayerField() : globalScene.getEnemyField())[this.fieldIndex]; + // TODO: Figure out why this uses `fieldIndex` instead of `BattlerIndex` + // TODO: Remove `?? undefined` once field pokemon getters are made sane + return (this.player ? globalScene.getPlayerField() : globalScene.getEnemyField())[this.fieldIndex] ?? undefined; } /** diff --git a/src/phases/obtain-status-effect-phase.ts b/src/phases/obtain-status-effect-phase.ts index 4846130cf4d..b9f3e266d87 100644 --- a/src/phases/obtain-status-effect-phase.ts +++ b/src/phases/obtain-status-effect-phase.ts @@ -23,6 +23,7 @@ export class ObtainStatusEffectPhase extends PokemonPhase { * @param sourceText - The text to show for the source of the status effect, if any; default `null`. * @param statusMessage - A string containing text to be displayed upon status setting; * defaults to normal key for status if empty or omitted. + * @todo stop passing `null` to the phase */ constructor( battlerIndex: BattlerIndex, diff --git a/src/phases/pokemon-phase.ts b/src/phases/pokemon-phase.ts index 1a1a7e2efa3..92b29889079 100644 --- a/src/phases/pokemon-phase.ts +++ b/src/phases/pokemon-phase.ts @@ -9,7 +9,9 @@ export abstract class PokemonPhase extends FieldPhase { * TODO: Make this either use IDs or `BattlerIndex`es, not a weird mix of both */ protected battlerIndex: BattlerIndex | number; + // TODO: Why is this needed? public player: boolean; + /** @todo Remove in favor of `battlerIndex` pleas for fuck's sake */ public fieldIndex: number; constructor(battlerIndex?: BattlerIndex | number) { @@ -32,10 +34,11 @@ export abstract class PokemonPhase extends FieldPhase { this.fieldIndex = battlerIndex % 2; } + // TODO: This should have `undefined` in its signature getPokemon(): Pokemon { if (this.battlerIndex > BattlerIndex.ENEMY_2) { - return globalScene.getPokemonById(this.battlerIndex)!; //TODO: is this bang correct? + return globalScene.getPokemonById(this.battlerIndex)!; } - return globalScene.getField()[this.battlerIndex]!; //TODO: is this bang correct? + return globalScene.getField()[this.battlerIndex]!; } } diff --git a/test/battler-tags/substitute.test.ts b/test/battler-tags/substitute.test.ts index 7ae60ad1408..a2ff539d2a8 100644 --- a/test/battler-tags/substitute.test.ts +++ b/test/battler-tags/substitute.test.ts @@ -49,7 +49,7 @@ describe("BattlerTag - SubstituteTag", () => { vi.spyOn(messages, "getPokemonNameWithAffix").mockReturnValue(""); vi.spyOn(mockPokemon.scene as BattleScene, "getPokemonById").mockImplementation(pokemonId => - mockPokemon.id === pokemonId ? mockPokemon : null, + mockPokemon.id === pokemonId ? mockPokemon : undefined, ); }); From c217f47942f06c149882378a853231c903e2d509 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Sat, 13 Sep 2025 14:36:38 -0400 Subject: [PATCH 16/29] [Refactor] Added `playTween` utility function (#6545) * Added `playTween` utility function Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com> * Update comment wording for benjie --------- Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com> --- src/utils/anim-utils.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/utils/anim-utils.ts diff --git a/src/utils/anim-utils.ts b/src/utils/anim-utils.ts new file mode 100644 index 00000000000..f1a06552d38 --- /dev/null +++ b/src/utils/anim-utils.ts @@ -0,0 +1,26 @@ +import { globalScene } from "#app/global-scene"; +import type { SceneBase } from "#app/scene-base"; + +/** + * Plays a Tween animation, resolving once the animation completes. + * @param config - The config for a single Tween + * @param scene - The {@linkcode SceneBase} on which the Tween plays; default {@linkcode globalScene} + * @returns A Promise that resolves once the Tween has been played. + * + * @privateRemarks + * The `config` input should not include an `onComplete` field as that callback is + * used to resolve the Promise containing the Tween animation. + * However, `config`'s type cannot be changed to something like `Omit` + * due to how the type for `TweenBuilderConfig` is defined. + */ +export async function playTween( + config: Phaser.Types.Tweens.TweenBuilderConfig, + scene: SceneBase = globalScene, +): Promise { + await new Promise(resolve => + scene.tweens.add({ + ...config, + onComplete: resolve, + }), + ); +} From e233f24526c7084d281c98928d266e227f477740 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sat, 13 Sep 2025 15:13:21 -0500 Subject: [PATCH 17/29] [Deps] Update biome to 2.2.4 (#6550) * Update biome and adjust rules * Add noMisusedPromises * Downgrade `noMisusedPromises` to info, enable noImportCycles --- biome.jsonc | 16 +++++++---- package.json | 2 +- pnpm-lock.yaml | 74 ++++++++++++++++++++++++------------------------ src/overrides.ts | 4 +-- 4 files changed, 51 insertions(+), 45 deletions(-) diff --git a/biome.jsonc b/biome.jsonc index e1aac032597..9e87518e636 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.2.3/schema.json", + "$schema": "https://biomejs.dev/schemas/2.2.4/schema.json", "vcs": { "enabled": true, "clientKind": "git", @@ -98,7 +98,9 @@ "useTrimStartEnd": "error", "useReadonlyClassProperties": { "level": "info", // TODO: Graduate to error eventually - "options": { "checkAllProperties": true } + // NOTE: "checkAllProperties" has an immature implementation that + // causes many false positives across files. Enable if/when maturity improves + "options": { "checkAllProperties": false } }, "useConsistentObjectDefinitions": { "level": "error", @@ -209,11 +211,15 @@ "nursery": { "noUselessUndefined": "error", "useMaxParams": { - "level": "warn", // TODO: Change to "error"... eventually... - "options": { "max": 4 } // A lot of stuff has a few params, but + "level": "info", // TODO: Change to "error"... eventually... + "options": { "max": 7 } }, "noShadow": "warn", // TODO: refactor and make "error" - "noNonNullAssertedOptionalChain": "warn" // TODO: refactor and make "error" + "noNonNullAssertedOptionalChain": "warn", // TODO: refactor and make "error" + "noDuplicateDependencies": "error", + "noImportCycles": "error", + // TODO: Change to error once promises are used properly + "noMisusedPromises": "info" } } }, diff --git a/package.json b/package.json index 3086ee85747..f07b9b0e1b3 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "update-locales:remote": "git submodule update --progress --init --recursive --force --remote" }, "devDependencies": { - "@biomejs/biome": "2.2.3", + "@biomejs/biome": "2.2.4", "@ls-lint/ls-lint": "2.3.1", "@types/crypto-js": "^4.2.0", "@types/jsdom": "^21.1.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 09747b23be3..46608772338 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,8 +43,8 @@ importers: version: 1.80.16(graphology-types@0.24.8) devDependencies: '@biomejs/biome': - specifier: 2.2.3 - version: 2.2.3 + specifier: 2.2.4 + version: 2.2.4 '@ls-lint/ls-lint': specifier: 2.3.1 version: 2.3.1 @@ -195,55 +195,55 @@ packages: resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} engines: {node: '>=6.9.0'} - '@biomejs/biome@2.2.3': - resolution: {integrity: sha512-9w0uMTvPrIdvUrxazZ42Ib7t8Y2yoGLKLdNne93RLICmaHw7mcLv4PPb5LvZLJF3141gQHiCColOh/v6VWlWmg==} + '@biomejs/biome@2.2.4': + resolution: {integrity: sha512-TBHU5bUy/Ok6m8c0y3pZiuO/BZoY/OcGxoLlrfQof5s8ISVwbVBdFINPQZyFfKwil8XibYWb7JMwnT8wT4WVPg==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@2.2.3': - resolution: {integrity: sha512-OrqQVBpadB5eqzinXN4+Q6honBz+tTlKVCsbEuEpljK8ASSItzIRZUA02mTikl3H/1nO2BMPFiJ0nkEZNy3B1w==} + '@biomejs/cli-darwin-arm64@2.2.4': + resolution: {integrity: sha512-RJe2uiyaloN4hne4d2+qVj3d3gFJFbmrr5PYtkkjei1O9c+BjGXgpUPVbi8Pl8syumhzJjFsSIYkcLt2VlVLMA==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@2.2.3': - resolution: {integrity: sha512-OCdBpb1TmyfsTgBAM1kPMXyYKTohQ48WpiN9tkt9xvU6gKVKHY4oVwteBebiOqyfyzCNaSiuKIPjmHjUZ2ZNMg==} + '@biomejs/cli-darwin-x64@2.2.4': + resolution: {integrity: sha512-cFsdB4ePanVWfTnPVaUX+yr8qV8ifxjBKMkZwN7gKb20qXPxd/PmwqUH8mY5wnM9+U0QwM76CxFyBRJhC9tQwg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@2.2.3': - resolution: {integrity: sha512-q3w9jJ6JFPZPeqyvwwPeaiS/6NEszZ+pXKF+IczNo8Xj6fsii45a4gEEicKyKIytalV+s829ACZujQlXAiVLBQ==} + '@biomejs/cli-linux-arm64-musl@2.2.4': + resolution: {integrity: sha512-7TNPkMQEWfjvJDaZRSkDCPT/2r5ESFPKx+TEev+I2BXDGIjfCZk2+b88FOhnJNHtksbOZv8ZWnxrA5gyTYhSsQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-arm64@2.2.3': - resolution: {integrity: sha512-g/Uta2DqYpECxG+vUmTAmUKlVhnGEcY7DXWgKP8ruLRa8Si1QHsWknPY3B/wCo0KgYiFIOAZ9hjsHfNb9L85+g==} + '@biomejs/cli-linux-arm64@2.2.4': + resolution: {integrity: sha512-M/Iz48p4NAzMXOuH+tsn5BvG/Jb07KOMTdSVwJpicmhN309BeEyRyQX+n1XDF0JVSlu28+hiTQ2L4rZPvu7nMw==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-x64-musl@2.2.3': - resolution: {integrity: sha512-y76Dn4vkP1sMRGPFlNc+OTETBhGPJ90jY3il6jAfur8XWrYBQV3swZ1Jo0R2g+JpOeeoA0cOwM7mJG6svDz79w==} + '@biomejs/cli-linux-x64-musl@2.2.4': + resolution: {integrity: sha512-m41nFDS0ksXK2gwXL6W6yZTYPMH0LughqbsxInSKetoH6morVj43szqKx79Iudkp8WRT5SxSh7qVb8KCUiewGg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-linux-x64@2.2.3': - resolution: {integrity: sha512-LEtyYL1fJsvw35CxrbQ0gZoxOG3oZsAjzfRdvRBRHxOpQ91Q5doRVjvWW/wepgSdgk5hlaNzfeqpyGmfSD0Eyw==} + '@biomejs/cli-linux-x64@2.2.4': + resolution: {integrity: sha512-orr3nnf2Dpb2ssl6aihQtvcKtLySLta4E2UcXdp7+RTa7mfJjBgIsbS0B9GC8gVu0hjOu021aU8b3/I1tn+pVQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-win32-arm64@2.2.3': - resolution: {integrity: sha512-Ms9zFYzjcJK7LV+AOMYnjN3pV3xL8Prxf9aWdDVL74onLn5kcvZ1ZMQswE5XHtnd/r/0bnUd928Rpbs14BzVmA==} + '@biomejs/cli-win32-arm64@2.2.4': + resolution: {integrity: sha512-NXnfTeKHDFUWfxAefa57DiGmu9VyKi0cDqFpdI+1hJWQjGJhJutHPX0b5m+eXvTKOaf+brU+P0JrQAZMb5yYaQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@2.2.3': - resolution: {integrity: sha512-gvCpewE7mBwBIpqk1YrUqNR4mCiyJm6UI3YWQQXkedSSEwzRdodRpaKhbdbHw1/hmTWOVXQ+Eih5Qctf4TCVOQ==} + '@biomejs/cli-win32-x64@2.2.4': + resolution: {integrity: sha512-3Y4V4zVRarVh/B/eSHczR4LYoSVyv3Dfuvm3cWs5w/HScccS0+Wt/lHOcDTRYeHjQmMYVC3rIRWqyN2EI52+zg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -2164,39 +2164,39 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@biomejs/biome@2.2.3': + '@biomejs/biome@2.2.4': optionalDependencies: - '@biomejs/cli-darwin-arm64': 2.2.3 - '@biomejs/cli-darwin-x64': 2.2.3 - '@biomejs/cli-linux-arm64': 2.2.3 - '@biomejs/cli-linux-arm64-musl': 2.2.3 - '@biomejs/cli-linux-x64': 2.2.3 - '@biomejs/cli-linux-x64-musl': 2.2.3 - '@biomejs/cli-win32-arm64': 2.2.3 - '@biomejs/cli-win32-x64': 2.2.3 + '@biomejs/cli-darwin-arm64': 2.2.4 + '@biomejs/cli-darwin-x64': 2.2.4 + '@biomejs/cli-linux-arm64': 2.2.4 + '@biomejs/cli-linux-arm64-musl': 2.2.4 + '@biomejs/cli-linux-x64': 2.2.4 + '@biomejs/cli-linux-x64-musl': 2.2.4 + '@biomejs/cli-win32-arm64': 2.2.4 + '@biomejs/cli-win32-x64': 2.2.4 - '@biomejs/cli-darwin-arm64@2.2.3': + '@biomejs/cli-darwin-arm64@2.2.4': optional: true - '@biomejs/cli-darwin-x64@2.2.3': + '@biomejs/cli-darwin-x64@2.2.4': optional: true - '@biomejs/cli-linux-arm64-musl@2.2.3': + '@biomejs/cli-linux-arm64-musl@2.2.4': optional: true - '@biomejs/cli-linux-arm64@2.2.3': + '@biomejs/cli-linux-arm64@2.2.4': optional: true - '@biomejs/cli-linux-x64-musl@2.2.3': + '@biomejs/cli-linux-x64-musl@2.2.4': optional: true - '@biomejs/cli-linux-x64@2.2.3': + '@biomejs/cli-linux-x64@2.2.4': optional: true - '@biomejs/cli-win32-arm64@2.2.3': + '@biomejs/cli-win32-arm64@2.2.4': optional: true - '@biomejs/cli-win32-x64@2.2.3': + '@biomejs/cli-win32-x64@2.2.4': optional: true '@bundled-es-modules/cookie@2.0.1': diff --git a/src/overrides.ts b/src/overrides.ts index b8212ea8fd6..9f6b4ced3a2 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -1,4 +1,4 @@ -import { type PokeballCounts } from "#app/battle-scene"; +import type { PokeballCounts } from "#app/battle-scene"; import { EvolutionItem } from "#balance/pokemon-evolutions"; import { Gender } from "#data/gender"; import { AbilityId } from "#enums/ability-id"; @@ -21,7 +21,7 @@ import { TrainerType } from "#enums/trainer-type"; import { Unlockables } from "#enums/unlockables"; import { VariantTier } from "#enums/variant-tier"; import { WeatherType } from "#enums/weather-type"; -import { type ModifierOverride } from "#modifiers/modifier-type"; +import type { ModifierOverride } from "#modifiers/modifier-type"; import { Variant } from "#sprites/variant"; /** From 3ed6a9a960ff4d643cc438d9fd79727e310fb202 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sat, 13 Sep 2025 15:21:24 -0500 Subject: [PATCH 18/29] =?UTF-8?q?[Balance]=20Trainer=20boss=20Pok=C3=A9mon?= =?UTF-8?q?=20no=20longer=20gain=20a=20stat=20boost=20when=20a=20boss=20se?= =?UTF-8?q?gment=20is=20broken=20#6552?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trainer boss Pokémon no longer gain a stat boost when a boss segment is broken --- src/field/pokemon.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index e6a46ac926f..9b2a5725f58 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -6909,7 +6909,7 @@ export class EnemyPokemon extends Pokemon { const segmentSize = this.getMaxHp() / this.bossSegments; clearedBossSegmentIndex = Math.ceil(this.hp / segmentSize); } - if (clearedBossSegmentIndex <= this.bossSegmentIndex) { + if (clearedBossSegmentIndex <= this.bossSegmentIndex && !this.hasTrainer()) { this.handleBossSegmentCleared(clearedBossSegmentIndex); } this.battleInfo.updateBossSegments(this); From b170145fb8983a778222020cd8604a08a1cda2cc Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Sat, 13 Sep 2025 14:55:13 -0700 Subject: [PATCH 19/29] [Dev] Update `pnpm` from `10.14.0` to `10.16.1` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f07b9b0e1b3..27b1fc4e290 100644 --- a/package.json +++ b/package.json @@ -74,5 +74,5 @@ "engines": { "node": ">=22.0.0" }, - "packageManager": "pnpm@10.14.0" + "packageManager": "pnpm@10.16.1" } From 521b88eabe5cd474baefb9f465b7cc1594b2ac85 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sat, 13 Sep 2025 18:36:21 -0500 Subject: [PATCH 20/29] [Bug] [Beta] Fix bug where boss segments are not actually broken (#6553) Fix bug where boss segments are not actually broken --- src/field/pokemon.ts | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 9b2a5725f58..9f217cc4d64 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -6909,7 +6909,7 @@ export class EnemyPokemon extends Pokemon { const segmentSize = this.getMaxHp() / this.bossSegments; clearedBossSegmentIndex = Math.ceil(this.hp / segmentSize); } - if (clearedBossSegmentIndex <= this.bossSegmentIndex && !this.hasTrainer()) { + if (clearedBossSegmentIndex <= this.bossSegmentIndex) { this.handleBossSegmentCleared(clearedBossSegmentIndex); } this.battleInfo.updateBossSegments(this); @@ -6938,12 +6938,20 @@ export class EnemyPokemon extends Pokemon { * @param segmentIndex index of the segment to get down to (0 = no shield left, 1 = 1 shield left, etc.) */ handleBossSegmentCleared(segmentIndex: number): void { + let doStatBoost = !this.hasTrainer(); + // TODO: Rewrite this bespoke logic to improve clarity while (this.bossSegmentIndex > 0 && segmentIndex - 1 < this.bossSegmentIndex) { + this.bossSegmentIndex--; + + // Continue, _not_ break here, to ensure that each segment is still broken + if (!doStatBoost) { + continue; + } + let boostedStat: EffectiveStat | undefined; // Filter out already maxed out stat stages and weigh the rest based on existing stats const leftoverStats = EFFECTIVE_STATS.filter((s: EffectiveStat) => this.getStatStage(s) < 6); const statWeights = leftoverStats.map((s: EffectiveStat) => this.getStat(s, false)); - let boostedStat: EffectiveStat | undefined; const statThresholds: number[] = []; let totalWeight = 0; @@ -6962,18 +6970,18 @@ export class EnemyPokemon extends Pokemon { } if (boostedStat === undefined) { - this.bossSegmentIndex--; - return; + doStatBoost = false; + continue; } let stages = 1; // increase the boost if the boss has at least 3 segments and we passed last shield - if (this.bossSegments >= 3 && this.bossSegmentIndex === 1) { + if (this.bossSegments >= 3 && this.bossSegmentIndex === 0) { stages++; } // increase the boost if the boss has at least 5 segments and we passed the second to last shield - if (this.bossSegments >= 5 && this.bossSegmentIndex === 2) { + if (this.bossSegments >= 5 && this.bossSegmentIndex === 1) { stages++; } @@ -6986,7 +6994,6 @@ export class EnemyPokemon extends Pokemon { true, true, ); - this.bossSegmentIndex--; } } From 24a0ca95f40cb9a7c9ce6947e0255ad5d169230c Mon Sep 17 00:00:00 2001 From: Madmadness65 <59298170+Madmadness65@users.noreply.github.com> Date: Sun, 14 Sep 2025 09:58:56 -0500 Subject: [PATCH 21/29] [Balance] Change Happiny evolution method, update Chansey happiness req https://github.com/pagefaultgames/pokerogue/pull/6551 * [Balance] Change Happiny evolution method Happiny now evolves into Chansey by using an Oval Stone during the Dawn or Day, instead of 160 friendship (Blissey's friendship requirement of 200 remains unchanged). Also removed unnecessary comments from Gligar's and Sneasel's evolutions. * Update Chansey -> Blissey 200 -> 180 Friendship Required (Base 140) --------- Co-authored-by: damocleas Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/balance/pokemon-evolutions.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/data/balance/pokemon-evolutions.ts b/src/data/balance/pokemon-evolutions.ts index fd88fc5da37..c868a49dbfa 100644 --- a/src/data/balance/pokemon-evolutions.ts +++ b/src/data/balance/pokemon-evolutions.ts @@ -53,6 +53,7 @@ export enum EvolutionItem { PRISM_SCALE, RAZOR_CLAW, RAZOR_FANG, + OVAL_STONE, REAPER_CLOTH, ELECTIRIZER, MAGMARIZER, @@ -1496,10 +1497,13 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesFormEvolution(SpeciesId.DUDUNSPARCE, "", "two-segment", 32, null, {key: EvoCondKey.MOVE, move: MoveId.HYPER_DRILL}, SpeciesWildEvolutionDelay.LONG) ], [SpeciesId.GLIGAR]: [ - new SpeciesEvolution(SpeciesId.GLISCOR, 1, EvolutionItem.RAZOR_FANG, {key: EvoCondKey.TIME, time: [TimeOfDay.DUSK, TimeOfDay.NIGHT]} /* Razor fang at night*/, SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(SpeciesId.GLISCOR, 1, EvolutionItem.RAZOR_FANG, {key: EvoCondKey.TIME, time: [TimeOfDay.DUSK, TimeOfDay.NIGHT]}, SpeciesWildEvolutionDelay.VERY_LONG) ], [SpeciesId.SNEASEL]: [ - new SpeciesEvolution(SpeciesId.WEAVILE, 1, EvolutionItem.RAZOR_CLAW, {key: EvoCondKey.TIME, time: [TimeOfDay.DUSK, TimeOfDay.NIGHT]} /* Razor claw at night*/, SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(SpeciesId.WEAVILE, 1, EvolutionItem.RAZOR_CLAW, {key: EvoCondKey.TIME, time: [TimeOfDay.DUSK, TimeOfDay.NIGHT]}, SpeciesWildEvolutionDelay.VERY_LONG) + ], + [SpeciesId.HAPPINY]: [ + new SpeciesEvolution(SpeciesId.CHANSEY, 1, EvolutionItem.OVAL_STONE, {key: EvoCondKey.TIME, time: [TimeOfDay.DAWN, TimeOfDay.DAY]}, SpeciesWildEvolutionDelay.SHORT) ], [SpeciesId.URSARING]: [ new SpeciesEvolution(SpeciesId.URSALUNA, 1, EvolutionItem.PEAT_BLOCK, null, SpeciesWildEvolutionDelay.VERY_LONG) //Ursaring does not evolve into Bloodmoon Ursaluna @@ -1760,7 +1764,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(SpeciesId.CROBAT, 1, null, {key: EvoCondKey.FRIENDSHIP, value: 120}, SpeciesWildEvolutionDelay.VERY_LONG) ], [SpeciesId.CHANSEY]: [ - new SpeciesEvolution(SpeciesId.BLISSEY, 1, null, {key: EvoCondKey.FRIENDSHIP, value: 200}, SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(SpeciesId.BLISSEY, 1, null, {key: EvoCondKey.FRIENDSHIP, value: 180}, SpeciesWildEvolutionDelay.LONG) ], [SpeciesId.PICHU]: [ new SpeciesFormEvolution(SpeciesId.PIKACHU, "spiky", "partner", 1, null, {key: EvoCondKey.FRIENDSHIP, value: 90}, SpeciesWildEvolutionDelay.SHORT), @@ -1787,9 +1791,6 @@ export const pokemonEvolutions: PokemonEvolutions = { [SpeciesId.CHINGLING]: [ new SpeciesEvolution(SpeciesId.CHIMECHO, 1, null, [{key: EvoCondKey.FRIENDSHIP, value: 90}, {key: EvoCondKey.TIME, time: [TimeOfDay.DUSK, TimeOfDay.NIGHT]}], SpeciesWildEvolutionDelay.MEDIUM) ], - [SpeciesId.HAPPINY]: [ - new SpeciesEvolution(SpeciesId.CHANSEY, 1, null, {key: EvoCondKey.FRIENDSHIP, value: 160}, SpeciesWildEvolutionDelay.SHORT) - ], [SpeciesId.MUNCHLAX]: [ new SpeciesEvolution(SpeciesId.SNORLAX, 1, null, {key: EvoCondKey.FRIENDSHIP, value: 120}, SpeciesWildEvolutionDelay.LONG) ], From 25a2fb4266ebf84470ae8549c9b6d76a31eb2194 Mon Sep 17 00:00:00 2001 From: Xavion3 Date: Mon, 15 Sep 2025 12:44:58 +1000 Subject: [PATCH 22/29] [Balance] Tweak trainer moveset TM generation. (#6533) * Lower TM weight in moveset generation. * Implement a cap on amount of TMs based on wave. * Extract ai moveset generation to its own file * Minor doc cleanup * Move magic numbers to balance file and export them * Tweak stab move weight generation --------- Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> --- src/ai/ai-moveset-gen.ts | 715 +++++++++++++++++++++++++ src/data/balance/moveset-generation.ts | 209 ++++++++ src/data/trainers/trainer-config.ts | 33 +- src/field/pokemon.ts | 299 +---------- 4 files changed, 963 insertions(+), 293 deletions(-) create mode 100644 src/ai/ai-moveset-gen.ts create mode 100644 src/data/balance/moveset-generation.ts diff --git a/src/ai/ai-moveset-gen.ts b/src/ai/ai-moveset-gen.ts new file mode 100644 index 00000000000..f46df09b33e --- /dev/null +++ b/src/ai/ai-moveset-gen.ts @@ -0,0 +1,715 @@ +import { globalScene } from "#app/global-scene"; +import { speciesEggMoves } from "#balance/egg-moves"; +import { + BASE_WEIGHT_MULTIPLIER, + BOSS_EXTRA_WEIGHT_MULTIPLIER, + COMMON_TIER_TM_LEVEL_REQUIREMENT, + COMMON_TM_MOVESET_WEIGHT, + EGG_MOVE_LEVEL_REQUIREMENT, + EGG_MOVE_TO_LEVEL_WEIGHT, + EGG_MOVE_WEIGHT_MAX, + EVOLUTION_MOVE_WEIGHT, + GREAT_TIER_TM_LEVEL_REQUIREMENT, + GREAT_TM_MOVESET_WEIGHT, + getMaxEggMoveCount, + getMaxTmCount, + RARE_EGG_MOVE_LEVEL_REQUIREMENT, + STAB_BLACKLIST, + ULTRA_TIER_TM_LEVEL_REQUIREMENT, + ULTRA_TM_MOVESET_WEIGHT, +} from "#balance/moveset-generation"; +import { EVOLVE_MOVE, RELEARN_MOVE } from "#balance/pokemon-level-moves"; +import { speciesTmMoves, tmPoolTiers } from "#balance/tms"; +import { allMoves } from "#data/data-lists"; +import { ModifierTier } from "#enums/modifier-tier"; +import { MoveCategory } from "#enums/move-category"; +import type { MoveId } from "#enums/move-id"; +import { PokemonType } from "#enums/pokemon-type"; +import type { SpeciesId } from "#enums/species-id"; +import { Stat } from "#enums/stat"; +import type { EnemyPokemon, Pokemon } from "#field/pokemon"; +import { PokemonMove } from "#moves/pokemon-move"; +import { NumberHolder, randSeedInt } from "#utils/common"; +import { isBeta } from "#utils/utility-vars"; + +/** + * Compute and assign a weight to the level-up moves currently available to the Pokémon + * + * @param pokemon - The Pokémon to generate a level-based move pool for + * @returns A map of move IDs to their computed weights + * + * @remarks + * A move's weight is determined by its level, as follows: + * 1. If the level is an {@linkcode EVOLVE_MOVE} move, weight is 60 + * 2. If it is level 1 with 80+ BP, it is considered a "move reminder" move and + * weight is 60 + * 3. If the Pokémon has a trainer and the move is a {@linkcode RELEARN_MOVE}, + * weight is 60 + * 4. Otherwise, weight is the earliest level the move can be learned + 20 + */ +function getAndWeightLevelMoves(pokemon: Pokemon): Map { + const movePool = new Map(); + let allLevelMoves: [number, MoveId][]; + // TODO: Investigate why there needs to be error handling here + try { + allLevelMoves = pokemon.getLevelMoves(1, true, true, pokemon.hasTrainer()); + } catch (e) { + console.warn("Error encountered trying to generate moveset for %s: %s", pokemon.species.name, e); + return movePool; + } + + const level = pokemon.level; + const hasTrainer = pokemon.hasTrainer(); + + for (const levelMove of allLevelMoves) { + const [learnLevel, id] = levelMove; + if (level < learnLevel) { + break; + } + const move = allMoves[id]; + // Skip unimplemented moves or moves that are already in the pool + if (move.name.endsWith(" (N)") || movePool.has(id)) { + continue; + } + + let weight = learnLevel + 20; + switch (learnLevel) { + case EVOLVE_MOVE: + weight = EVOLUTION_MOVE_WEIGHT; + break; + // Assume level 1 moves with 80+ BP are "move reminder" moves and bump their weight. Trainers use actual relearn moves. + case 1: + if (move.power >= 80) { + weight = 60; + } + break; + case RELEARN_MOVE: + if (hasTrainer) { + weight = 60; + } + } + + movePool.set(id, weight); + } + + return movePool; +} + +/** + * Determine which TM tiers a Pokémon can learn based on its level + * @param level - The level of the Pokémon + * @returns A tuple indicating whether the Pokémon can learn common, great, and ultra tier TMs + */ +function getAllowedTmTiers(level: number): [common: boolean, great: boolean, ultra: boolean] { + return [ + level >= COMMON_TIER_TM_LEVEL_REQUIREMENT, + level >= GREAT_TIER_TM_LEVEL_REQUIREMENT, + level >= ULTRA_TIER_TM_LEVEL_REQUIREMENT, + ]; +} + +/** + * Get the TMs that a species can learn based on its ID and formKey + * @param speciesId - The species ID of the Pokémon + * @param level - The level of the Pokémon + * @param formKey - The form key of the Pokémon + * @param levelPool - The current level-based move pool, to avoid duplicates + * @param tmPool - The TM move pool to add to, which will be modified in place + * @param allowedTiers - The tiers of TMs the Pokémon is allowed to learn + * + * @privateRemarks + * Split out from `getAndWeightTmMoves` to allow fusion species to add their TMs + * without duplicating code. + */ +function getTmPoolForSpecies( + speciesId: number, + level: number, + formKey: string, + levelPool: ReadonlyMap, + eggPool: ReadonlyMap, + tmPool: Map, + allowedTiers = getAllowedTmTiers(level), +): void { + const [allowCommon, allowGreat, allowUltra] = allowedTiers; + const tms = speciesTmMoves[speciesId]; + + let moveId: MoveId; + for (const tm of tms) { + if (Array.isArray(tm)) { + if (tm[0] !== formKey) { + continue; + } + moveId = tm[1]; + } else { + moveId = tm; + } + + if (levelPool.has(moveId) || eggPool.has(moveId) || tmPool.has(moveId)) { + continue; + } + switch (tmPoolTiers[moveId]) { + case ModifierTier.COMMON: + allowCommon && tmPool.set(moveId, COMMON_TM_MOVESET_WEIGHT); + break; + case ModifierTier.GREAT: + allowGreat && tmPool.set(moveId, GREAT_TM_MOVESET_WEIGHT); + break; + case ModifierTier.ULTRA: + allowUltra && tmPool.set(moveId, ULTRA_TM_MOVESET_WEIGHT); + break; + } + } +} + +/** + * Compute and assign a weight to the TM moves currently available to the Pokémon + * @param pokemon - The Pokémon to generate a TM-based move pool for + * @param currentSet - The current movepool, to avoid duplicates + * @param tmPool - The TM move pool to add to, which will be modified in place + * @returns A map of move IDs to their computed weights + * + * @remarks + * Only trainer pokemon can learn TM moves, and there are restrictions + * as to how many and which TMs are available based on the level of the Pokémon. + * 1. Before level 25, no TM moves are available + * 2. Between levels 25 and 40, only COMMON tier TMs are available, + */ +function getAndWeightTmMoves( + pokemon: Pokemon, + currentPool: ReadonlyMap, + eggPool: ReadonlyMap, + tmPool: Map, +): void { + const level = pokemon.level; + const allowedTiers = getAllowedTmTiers(level); + if (!allowedTiers.includes(true)) { + return; + } + + const form = pokemon.species.forms[pokemon.formIndex]?.formKey ?? ""; + getTmPoolForSpecies(pokemon.species.speciesId, level, form, currentPool, eggPool, tmPool, allowedTiers); + const fusionFormKey = pokemon.getFusionFormKey(); + const fusionSpecies = pokemon.fusionSpecies?.speciesId; + if (fusionSpecies != null && fusionFormKey != null && fusionFormKey !== "") { + getTmPoolForSpecies(fusionSpecies, level, fusionFormKey, currentPool, eggPool, tmPool, allowedTiers); + } +} + +/** + * Get the weight multiplier for an egg move + * @param levelPool - Map of level up moves to their weights + * @param level - The level of the Pokémon + * @param forRare - Whether this is for a rare egg move + * @param isBoss - Whether the Pokémon having the egg move generated is a boss Pokémon + */ +export function getEggMoveWeight( + // biome-ignore-start lint/correctness/noUnusedFunctionParameters: Saved to allow this algorithm to be tweaked easily without adjusting signatures + levelPool: ReadonlyMap, + level: number, + forRare: boolean, + isBoss: boolean, + // biome-ignore-end lint/correctness/noUnusedFunctionParameters: Endrange +): number { + const levelUpWeightedEggMoveWeight = Math.round(Math.max(...levelPool.values()) * EGG_MOVE_TO_LEVEL_WEIGHT); + // Rare egg moves are always weighted at 5/6 the weight of normal egg moves + return Math.min(levelUpWeightedEggMoveWeight, EGG_MOVE_WEIGHT_MAX) * (forRare ? 5 / 6 : 1); +} + +/** + * Submethod of {@linkcode getAndWeightEggMoves} that adds egg moves for a specific species to the egg move pool + * + * @param rootSpeciesId - The ID of the root species for which to generate the egg move pool. + * @param levelPool - A readonly map of move IDs to their levels, representing moves already learned by leveling up. + * @param eggPool - A map to be populated with egg move IDs and their corresponding weights. + * @param eggMoveWeight - The default weight to assign to regular egg moves. + * @param excludeRare - If true, excludes rare egg moves + * @param rareEggMoveWeight - The weight to assign to rare egg moves; default 0 + * + * @privateRemarks + * Split from `getAndWeightEggMoves` to allow fusion species to add their egg moves without duplicating code. + * + * @remarks + * - Moves present in `levelPool` are excluded from the egg pool. + * - If `excludeRare` is true, rare egg moves (at index 3) are skipped. + * - Rare egg moves are assigned `rareEggMoveWeight`, while others receive `eggMoveWeight`. + */ +function getEggPoolForSpecies( + rootSpeciesId: SpeciesId, + levelPool: ReadonlyMap, + eggPool: Map, + eggMoveWeight: number, + excludeRare: boolean, + rareEggMoveWeight = 0, +): void { + for (const [idx, moveId] of speciesEggMoves[rootSpeciesId].entries()) { + if (levelPool.has(moveId) || (idx === 3 && excludeRare)) { + continue; + } + eggPool.set(Math.max(moveId, eggPool.get(moveId) ?? 0), idx === 3 ? rareEggMoveWeight : eggMoveWeight); + } +} + +/** + * Compute and assign a weight to the egg moves currently available to the Pokémon + * @param pokemon - The Pokémon to generate egg moves for + * @param levelPool - The map of level-based moves to their weights + * @param eggPool - A map of move IDs to their weights for egg moves that will be modified in place + * + * @remarks + * This function checks if the Pokémon meets the requirements to learn egg moves, + * and if allowed, calculates the weights for regular and rare egg moves using the provided pools. + */ +function getAndWeightEggMoves( + pokemon: Pokemon, + levelPool: ReadonlyMap, + eggPool: Map, +): void { + const level = pokemon.level; + if (level < EGG_MOVE_LEVEL_REQUIREMENT || !globalScene.currentBattle?.trainer?.config.allowEggMoves) { + return; + } + const isBoss = pokemon.isBoss(); + const excludeRare = isBoss || level < RARE_EGG_MOVE_LEVEL_REQUIREMENT; + const eggMoveWeight = getEggMoveWeight(levelPool, level, false, isBoss); + let rareEggMoveWeight: number | undefined; + if (!excludeRare) { + rareEggMoveWeight = getEggMoveWeight(levelPool, level, true, isBoss); + } + getEggPoolForSpecies( + pokemon.species.getRootSpeciesId(), + levelPool, + eggPool, + eggMoveWeight, + excludeRare, + rareEggMoveWeight, + ); + + const fusionSpecies = pokemon.fusionSpecies?.getRootSpeciesId(); + if (fusionSpecies != null) { + getEggPoolForSpecies(fusionSpecies, levelPool, eggPool, eggMoveWeight, excludeRare, rareEggMoveWeight); + } +} + +/** + * Filter a move pool, removing moves that are not allowed based on conditions + * @param pool - The move pool to filter + * @param isBoss - Whether the Pokémon is a boss + * @param hasTrainer - Whether the Pokémon has a trainer + */ +function filterMovePool(pool: Map, isBoss: boolean, hasTrainer: boolean): void { + for (const [moveId, weight] of pool) { + if (weight <= 0) { + pool.delete(moveId); + continue; + } + const move = allMoves[moveId]; + // Forbid unimplemented moves + if (move.name.endsWith(" (N)")) { + pool.delete(moveId); + continue; + } + // Bosses never get self ko moves or Pain Split + if (isBoss && (move.hasAttr("SacrificialAttr") || move.hasAttr("HpSplitAttr"))) { + pool.delete(moveId); + } + + // No one gets Memento or Final Gambit + if (move.hasAttr("SacrificialAttrOnHit")) { + pool.delete(moveId); + continue; + } + + // Trainers never get OHKO moves + if (hasTrainer && move.hasAttr("OneHitKOAttr")) { + pool.delete(moveId); + } + } +} + +/** + * Perform Trainer-specific adjustments to move weights in a move pool + * @param pool - The move pool to adjust + */ +function adjustWeightsForTrainer(pool: Map): void { + for (const [moveId, weight] of pool.entries()) { + const move = allMoves[moveId]; + let adjustedWeight = weight; + // Half the weight of self KO moves on trainers + adjustedWeight *= move.hasAttr("SacrificialAttr") ? 0.5 : 1; + + // Trainers get a weight bump to stat buffing moves + adjustedWeight *= move.getAttrs("StatStageChangeAttr").some(a => a.stages > 1 && a.selfTarget) ? 1.25 : 1; + + // Trainers get a weight decrease to multiturn moves + adjustedWeight *= !!move.isChargingMove() || !!move.hasAttr("RechargeAttr") ? 0.7 : 1; + if (adjustedWeight !== weight) { + pool.set(moveId, adjustedWeight); + } + } +} + +/** + * Adjust weights of damaging moves in a move pool based on their power and category + * + * @param pool - The move pool to adjust + * @param pokemon - The Pokémon for which the moveset is being generated + * @param willTera - Whether the Pokémon is expected to Tera (i.e., has instant Tera on a Trainer Pokémon); default `false` + * @remarks + * Caps max power at 90 to avoid something like hyper beam ruining the stats. + * pokemon is a pretty soft weighting factor, although it is scaled with the weight multiplier. + */ +function adjustDamageMoveWeights(pool: Map, pokemon: Pokemon, willTera = false): void { + // begin max power at 40 to avoid inflating weights too much when there are only low power moves + let maxPower = 40; + for (const moveId of pool.keys()) { + const move = allMoves[moveId]; + maxPower = Math.max(maxPower, move.calculateEffectivePower()); + if (maxPower >= 90) { + maxPower = 90; + break; + } + } + + const atk = pokemon.getStat(Stat.ATK); + const spAtk = pokemon.getStat(Stat.SPATK); + const lowerStat = Math.min(atk, spAtk); + const higherStat = Math.max(atk, spAtk); + const worseCategory = atk > spAtk ? MoveCategory.SPECIAL : MoveCategory.PHYSICAL; + const statRatio = lowerStat / higherStat; + const adjustmentRatio = Math.min(Math.pow(statRatio, 3) * 1.3, 1); + + for (const [moveId, weight] of pool) { + const move = allMoves[moveId]; + let adjustedWeight = weight; + if (move.category === MoveCategory.STATUS) { + continue; + } + // Scale weight based on their ratio to the highest power move, capping at 50% reduction + adjustedWeight *= Math.max(Math.min(move.calculateEffectivePower() / maxPower, 1), 0.5); + + // Scale weight based the stat it uses to deal damage, based on the ratio between said stat + // and the higher stat + if (move.hasAttr("DefAtkAttr")) { + const def = pokemon.getStat(Stat.DEF); + const defRatio = def / higherStat; + const defAdjustRatio = Math.min(Math.pow(defRatio, 3) * 1.3, 1.1); + adjustedWeight *= defAdjustRatio; + } else if ( + move.category === worseCategory + && !move.hasAttr("PhotonGeyserCategoryAttr") + && !move.hasAttr("ShellSideArmCategoryAttr") + && !(move.hasAttr("TeraMoveCategoryAttr") && willTera) + ) { + // Raw multiply each move's category by the stat it uses to deal damage + // moves that always use the higher offensive stat are left unadjusted + adjustedWeight *= adjustmentRatio; + } + + if (adjustedWeight !== weight) { + pool.set(moveId, adjustedWeight); + } + } +} + +/** + * Calculate the total weight of all moves in a move pool + * @param pool - The move pool to calculate the total weight for + * @returns The total weight of all moves in the pool + */ +// biome-ignore lint/correctness/noUnusedVariables: May be useful +function calculateTotalPoolWeight(pool: Map): number { + let totalWeight = 0; + for (const weight of pool.values()) { + totalWeight += weight; + } + return totalWeight; +} + +/** + * Filter a pool and return a new array of moves that pass the predicate + * @param pool - The move pool to filter + * @param predicate - The predicate function to determine if a move should be included + * @param totalWeight - An output parameter to hold the total weight of the filtered pool. Its value is reset to 0 if provided. + * @returns An array of move ID and weight tuples that pass the predicate + */ +function filterPool( + pool: ReadonlyMap, + predicate: (moveId: MoveId) => boolean, + totalWeight?: NumberHolder, +): [id: MoveId, weight: number][] { + let hasTotalWeight = false; + if (totalWeight != null) { + totalWeight.value = 0; + hasTotalWeight = true; + } + const newPool: [id: MoveId, weight: number][] = []; + for (const [moveId, weight] of pool) { + if (predicate(moveId)) { + newPool.push([moveId, weight]); + if (hasTotalWeight) { + // Bang is safe here because we set `hasTotalWeight` in the if check above + totalWeight!.value += weight; + } + } + } + + return newPool; +} + +/** + * Forcibly add a STAB move to the Pokémon's moveset from the provided pools + * + * @remarks + * If no STAB move is available, add any damaging move. + * If no damaging move is available, no move is added + * @param pool - The master move pool + * @param tmPool - The TM move pool + * @param eggPool - The egg move pool + * @param pokemon - The Pokémon for which the moveset is being generated + * @param tmCount - A holder for the count of TM moves selected + * @param eggMoveCount - A holder for the count of egg moves selected + * @param willTera - Whether the Pokémon is expected to Tera (i.e., has instant Tera on a Trainer Pokémon); default `false` + * @param forceAnyDamageIfNoStab - If true, will force any damaging move if no STAB move is available + */ +// biome-ignore lint/nursery/useMaxParams: This is a complex function that needs all these parameters +function forceStabMove( + pool: Map, + tmPool: Map, + eggPool: Map, + pokemon: Pokemon, + tmCount: NumberHolder, + eggMoveCount: NumberHolder, + willTera = false, + forceAnyDamageIfNoStab = false, +): void { + // All Pokemon force a STAB move first + const totalWeight = new NumberHolder(0); + const stabMovePool = filterPool( + pool, + moveId => { + const move = allMoves[moveId]; + return ( + move.category !== MoveCategory.STATUS + && (pokemon.isOfType(move.type) + || (willTera && move.hasAttr("TeraBlastTypeAttr") && pokemon.getTeraType() !== PokemonType.STELLAR)) + && !STAB_BLACKLIST.has(moveId) + ); + }, + totalWeight, + ); + + const chosenPool = + stabMovePool.length > 0 || !forceAnyDamageIfNoStab + ? stabMovePool + : filterPool( + pool, + m => allMoves[m[0]].category !== MoveCategory.STATUS && !STAB_BLACKLIST.has(m[0]), + totalWeight, + ); + + if (chosenPool.length > 0) { + let rand = randSeedInt(totalWeight.value); + let index = 0; + while (rand > chosenPool[index][1]) { + rand -= chosenPool[index++][1]; + } + const selectedId = chosenPool[index][0]; + pool.delete(selectedId); + if (tmPool.has(selectedId)) { + tmPool.delete(selectedId); + tmCount.value++; + } else if (eggPool.has(selectedId)) { + eggPool.delete(selectedId); + eggMoveCount.value++; + } + pokemon.moveset.push(new PokemonMove(selectedId)); + } +} + +/** + * Adjust weights in the remaining move pool based on existing moves in the Pokémon's moveset + * + * @remarks + * Submethod for step 5 of moveset generation + * @param pool - The move pool to filter + * @param pokemon - The Pokémon for which the moveset is being generated + */ +function filterRemainingTrainerMovePool(pool: [id: MoveId, weight: number][], pokemon: Pokemon) { + // Sqrt the weight of any damaging moves with overlapping types. pokemon is about a 0.05 - 0.1 multiplier. + // Other damaging moves 2x weight if 0-1 damaging moves, 0.5x if 2, 0.125x if 3. These weights get 20x if STAB. + // Status moves remain unchanged on weight, pokemon encourages 1-2 + for (const [idx, [moveId, weight]] of pool.entries()) { + let ret: number; + if ( + pokemon.moveset.some( + mo => mo.getMove().category !== MoveCategory.STATUS && mo.getMove().type === allMoves[moveId].type, + ) + ) { + ret = Math.ceil(Math.sqrt(weight)); + } else if (allMoves[moveId].category !== MoveCategory.STATUS) { + ret = Math.ceil( + (weight / Math.max(Math.pow(4, pokemon.moveset.filter(mo => (mo.getMove().power ?? 0) > 1).length) / 8, 0.5)) + * (pokemon.isOfType(allMoves[moveId].type) && !STAB_BLACKLIST.has(moveId) ? 20 : 1), + ); + } else { + ret = weight; + } + pool[idx] = [moveId, ret]; + } +} + +/** + * Fill in the remaining slots in the Pokémon's moveset from the provided pools + * @param pokemon - The Pokémon for which the moveset is being generated + * @param tmPool - The TM move pool + * @param eggMovePool - The egg move pool + * @param tmCount - A holder for the count of moves that have been added to the moveset from TMs + * @param eggMoveCount - A holder for the count of moves that have been added to the moveset from egg moves + * @param baseWeights - The base weights of all moves in the master pool + * @param remainingPool - The remaining move pool to select from + */ +function fillInRemainingMovesetSlots( + pokemon: Pokemon, + tmPool: Map, + eggMovePool: Map, + tmCount: NumberHolder, + eggMoveCount: NumberHolder, + baseWeights: Map, + remainingPool: [id: MoveId, weight: number][], +): void { + const tmCap = getMaxTmCount(pokemon.level); + const eggCap = getMaxEggMoveCount(pokemon.level); + const remainingPoolWeight = new NumberHolder(0); + while (remainingPool.length > pokemon.moveset.length && pokemon.moveset.length < 4) { + const nonLevelMoveCount = tmCount.value + eggMoveCount.value; + remainingPool = filterPool( + baseWeights, + (m: MoveId) => + !pokemon.moveset.some( + mo => + m === mo.moveId || (allMoves[m]?.hasAttr("SacrificialAttr") && mo.getMove()?.hasAttr("SacrificialAttr")), // Only one self-KO move allowed + ) + && (nonLevelMoveCount < tmCap || !tmPool.has(m)) + && (nonLevelMoveCount < eggCap || !eggMovePool.has(m)), + remainingPoolWeight, + ); + if (pokemon.hasTrainer()) { + filterRemainingTrainerMovePool(remainingPool, pokemon); + } + const totalWeight = remainingPool.reduce((v, m) => v + m[1], 0); + let rand = randSeedInt(totalWeight); + let index = 0; + while (rand > remainingPool[index][1]) { + rand -= remainingPool[index++][1]; + } + const selectedMoveId = remainingPool[index][0]; + baseWeights.delete(selectedMoveId); + if (tmPool.has(selectedMoveId)) { + tmCount.value++; + tmPool.delete(selectedMoveId); + } else if (eggMovePool.has(selectedMoveId)) { + eggMoveCount.value++; + eggMovePool.delete(selectedMoveId); + } + pokemon.moveset.push(new PokemonMove(selectedMoveId)); + } +} + +/** + * Debugging function to log computed move weights for a Pokémon + * @param pokemon - The Pokémon for which the move weights were computed + * @param pool - The move pool containing move IDs and their weights + * @param note - Short note to include in the log for context + */ +function debugMoveWeights(pokemon: Pokemon, pool: Map, note: string): void { + if (isBeta || import.meta.env.DEV) { + const moveNameToWeightMap = new Map(); + const sortedByValue = Array.from(pool.entries()).sort((a, b) => b[1] - a[1]); + for (const [moveId, weight] of sortedByValue) { + moveNameToWeightMap.set(allMoves[moveId].name, weight); + } + console.log("%cComputed move weights [%s] for %s", "color: blue", note, pokemon.name, moveNameToWeightMap); + } +} + +/** + * Generate a moveset for a given Pokémon based on its level, types, stats, and whether it is wild or a trainer's Pokémon. + * @param pokemon - The Pokémon to generate a moveset for + * @returns A reference to the Pokémon's moveset array + */ +export function generateMoveset(pokemon: Pokemon): void { + pokemon.moveset = []; + // Step 1: Generate the pools from various sources: level up, egg moves, and TMs + const learnPool = getAndWeightLevelMoves(pokemon); + debugMoveWeights(pokemon, learnPool, "Initial Level Moves"); + const hasTrainer = pokemon.hasTrainer(); + const tmPool = new Map(); + const eggMovePool = new Map(); + + if (hasTrainer) { + getAndWeightEggMoves(pokemon, learnPool, eggMovePool); + eggMovePool.size > 0 && debugMoveWeights(pokemon, eggMovePool, "Initial Egg Moves"); + getAndWeightTmMoves(pokemon, learnPool, eggMovePool, tmPool); + tmPool.size > 0 && debugMoveWeights(pokemon, tmPool, "Initial Tm Moves"); + } + + // Now, combine pools into one master pool. + // The pools are kept around so we know where the move was sourced from + const movePool = new Map([...tmPool.entries(), ...eggMovePool.entries(), ...learnPool.entries()]); + + // Step 2: Filter out forbidden moves + const isBoss = pokemon.isBoss(); + filterMovePool(movePool, isBoss, hasTrainer); + + // Step 3: Adjust weights for trainers + if (hasTrainer) { + adjustWeightsForTrainer(movePool); + } + + /** Determine whether this pokemon will instantly tera */ + const willTera = + hasTrainer + && globalScene.currentBattle?.trainer?.config.trainerAI.instantTeras.includes( + // The cast to EnemyPokemon is safe; includes will just return false if the property doesn't exist + (pokemon as EnemyPokemon).initialTeamIndex, + ); + + adjustDamageMoveWeights(movePool, pokemon, willTera); + + /** The higher this is, the greater the impact of weight. At `0` all moves are equal weight. */ + let weightMultiplier = BASE_WEIGHT_MULTIPLIER; + if (isBoss) { + weightMultiplier += BOSS_EXTRA_WEIGHT_MULTIPLIER; + } + + const baseWeights = new Map(movePool); + for (const [moveId, weight] of baseWeights) { + if (weight <= 0) { + baseWeights.delete(moveId); + continue; + } + baseWeights.set(moveId, Math.ceil(Math.pow(weight, weightMultiplier) * 100)); + } + + const tmCount = new NumberHolder(0); + const eggMoveCount = new NumberHolder(0); + + debugMoveWeights(pokemon, baseWeights, "Pre STAB Move"); + + // Step 4: Force a STAB move if possible + forceStabMove(movePool, tmPool, eggMovePool, pokemon, tmCount, eggMoveCount, willTera); + // Note: To force a secondary stab, call this a second time, and pass `false` for the last parameter + // Would also tweak the function to not consider moves already in the moveset + // e.g. forceStabMove(..., false); + + // Step 5: Fill in remaining slots + fillInRemainingMovesetSlots( + pokemon, + tmPool, + eggMovePool, + tmCount, + eggMoveCount, + baseWeights, + filterPool(baseWeights, (m: MoveId) => !pokemon.moveset.some(mo => m[0] === mo.moveId)), + ); +} diff --git a/src/data/balance/moveset-generation.ts b/src/data/balance/moveset-generation.ts new file mode 100644 index 00000000000..d6579eb45e7 --- /dev/null +++ b/src/data/balance/moveset-generation.ts @@ -0,0 +1,209 @@ +/* + * SPDX-Copyright-Text: 2025 Pagefault Games + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { MoveId } from "#enums/move-id"; + + +/** + * # Balance: Moveset Generation Configuration + * + * This module contains configuration constants and functions that control + * the limitations and rules around moveset generation for generated Pokémon. + * + * + * ### Move Weights + * + * The various move weight constants in this module control how likely + * certain categories of moves are to appear in a generated Pokémon's + * moveset. Higher weights make a move more likely to be chosen. + * The constants here specify the *base* weight for a move when first computed. + * These weights are post-processed (and then scaled up such that weights have a larger impact, + * for instance, on boss Pokémon) before being used in the actual moveset generation. + * + * Post Processing of weights includes, but is not limited to: + * - Adjusting weights of status moves + * - Adjusting weights based on the move's power relative to the highest power available + * - Adjusting weights based on the stat the move uses to calculate damage relative to the higher stat + * + * + * All weights go through additional post-processing based on + * their expected power (accuracy * damage * expected number of hits) + * + * @module + */ + + +//#region Constants +/** + * The minimum level for a Pokémon to generate with a move it can only learn + * from a common tier TM + */ +export const COMMON_TIER_TM_LEVEL_REQUIREMENT = 25; +/** + * The minimum level for a Pokémon to generate with a move it can only learn + * from a great tier TM + */ +export const GREAT_TIER_TM_LEVEL_REQUIREMENT = 40; +/** + * The minimum level for a Pokémon to generate with a move it can only learn + * from an ultra tier TM + */ +export const ULTRA_TIER_TM_LEVEL_REQUIREMENT = 55; + +/** Below this level, Pokémon will be unable to generate with any egg moves */ +export const EGG_MOVE_LEVEL_REQUIREMENT = 60; +/** Below this level, Pokémon will be unable to generate with rare egg moves */ +export const RARE_EGG_MOVE_LEVEL_REQUIREMENT = 170; + +// Note: Not exported, only for use with `getMaxTmCount +/** Below this level, Pokémon will be unable to generate with any TMs */ +const ONE_TM_THRESHOLD = 25; +/** Below this level, Pokémon will generate with at most 1 TM */ +const TWO_TM_THRESHOLD = 41; +/** Below this level, Pokémon will generate with at most two TMs */ +const THREE_TM_THRESHOLD = 71; +/** Below this level, Pokémon will generate with at most three TMs */ +const FOUR_TM_THRESHOLD = 101; + +/** Below this level, Pokémon will be unable to generate any egg moves */ +const ONE_EGG_MOVE_THRESHOLD = 80; +/** Below this level, Pokémon will generate with at most 1 egg moves */ +const TWO_EGG_MOVE_THRESHOLD = 121; +/** Below this level, Pokémon will generate with at most 2 egg moves */ +const THREE_EGG_MOVE_THRESHOLD = 161; +/** Above this level, Pokémon will generate with at most 3 egg moves */ +const FOUR_EGG_MOVE_THRESHOLD = 201; + + +/** The weight given to TMs in the common tier during moveset generation */ +export const COMMON_TM_MOVESET_WEIGHT = 12; +/** The weight given to TMs in the great tier during moveset generation */ +export const GREAT_TM_MOVESET_WEIGHT = 14; +/** The weight given to TMs in the ultra tier during moveset generation */ +export const ULTRA_TM_MOVESET_WEIGHT = 18; + +/** + * The maximum weight an egg move can ever have + * @remarks + * Egg moves have their weights adjusted based on the maximum weight of the Pokémon's + * level-up moves. Rare Egg moves are always 5/6th of the computed egg move weight. + * Boss pokemon are not allowed to spawn with rare egg moves. + * @see {@linkcode EGG_MOVE_TO_LEVEL_WEIGHT} + */ +export const EGG_MOVE_WEIGHT_MAX = 60; +/** + * The percentage of the Pokémon's highest weighted level move to the weight an + * egg move can generate with + */ +export const EGG_MOVE_TO_LEVEL_WEIGHT = 0.85; +/** The weight given to evolution moves */ +export const EVOLUTION_MOVE_WEIGHT = 70; +/** The weight given to relearn moves */ +export const RELEARN_MOVE_WEIGHT = 60; + +/** The base weight multiplier to use + * + * The higher the number, the more impact weights have on the final move selection. + * i.e. if set to 0, all moves have equal chance of being selected regardless of their weight. + */ +export const BASE_WEIGHT_MULTIPLIER = 1.6; + +/** The additional weight added onto {@linkcode BASE_WEIGHT_MULTIPLIER} for boss Pokémon */ +export const BOSS_EXTRA_WEIGHT_MULTIPLIER = 0.4; + + + +/** + * Set of moves that should be blacklisted from the forced STAB during moveset generation + * + * @remarks + * During moveset generation, trainer pokemon attempt to force their pokemon to generate with STAB + * moves in their movesets. Moves in this list not be considered to be "STAB" moves for this purpose. + * This does *not* prevent them from appearing in the moveset, but they will never + * be selected as a forced STAB move. + */ +export const STAB_BLACKLIST: ReadonlySet = new Set([ + MoveId.BEAT_UP, + MoveId.BELCH, + MoveId.BIDE, + MoveId.COMEUPPANCE, + MoveId.COUNTER, + MoveId.DOOM_DESIRE, + MoveId.DRAGON_RAGE, + MoveId.DREAM_EATER, + MoveId.ENDEAVOR, + MoveId.EXPLOSION, + MoveId.FAKE_OUT, + MoveId.FIRST_IMPRESSION, + MoveId.FISSURE, + MoveId.FLING, + MoveId.FOCUS_PUNCH, + MoveId.FUTURE_SIGHT, + MoveId.GUILLOTINE, + MoveId.HOLD_BACK, + MoveId.HORN_DRILL, + MoveId.LAST_RESORT, + MoveId.METAL_BURST, + MoveId.MIRROR_COAT, + MoveId.MISTY_EXPLOSION, + MoveId.NATURAL_GIFT, + MoveId.NATURES_MADNESS, + MoveId.NIGHT_SHADE, + MoveId.PSYWAVE, + MoveId.RUINATION, + MoveId.SELF_DESTRUCT, + MoveId.SHEER_COLD, + MoveId.SHELL_TRAP, + MoveId.SKY_DROP, + MoveId.SNORE, + MoveId.SONIC_BOOM, + MoveId.SPIT_UP, + MoveId.STEEL_BEAM, + MoveId.STEEL_ROLLER, + MoveId.SUPER_FANG, + MoveId.SYNCHRONOISE, + MoveId.UPPER_HAND, +]); + +//#endregion Constants + +/** + * Get the maximum number of TMs a Pokémon is allowed to learn based on + * its level + * @param level - The level of the Pokémon + * @returns The number of TMs the Pokémon can learn at this level + */ +export function getMaxTmCount(level: number) { + if (level < ONE_TM_THRESHOLD) { + return 0; + } + if (level < TWO_TM_THRESHOLD) { + return 1; + } + if (level < THREE_TM_THRESHOLD) { + return 2; + } + if (level < FOUR_TM_THRESHOLD) { + return 3; + } + return 4; +} + + +export function getMaxEggMoveCount(level: number): number { + if (level < ONE_EGG_MOVE_THRESHOLD) { + return 0; + } + if (level < TWO_EGG_MOVE_THRESHOLD) { + return 1; + } + if (level < THREE_EGG_MOVE_THRESHOLD) { + return 2; + } + if (level < FOUR_EGG_MOVE_THRESHOLD) { + return 3; + } + return 4; +} diff --git a/src/data/trainers/trainer-config.ts b/src/data/trainers/trainer-config.ts index 55362017cee..b5786d1f0a2 100644 --- a/src/data/trainers/trainer-config.ts +++ b/src/data/trainers/trainer-config.ts @@ -3,6 +3,8 @@ import { globalScene } from "#app/global-scene"; import { pokemonEvolutions, pokemonPrevolutions } from "#balance/pokemon-evolutions"; import { signatureSpecies } from "#balance/signature-species"; import { tmSpecies } from "#balance/tms"; +// biome-ignore lint/correctness/noUnusedImports: Used in a tsdoc comment +import type { RARE_EGG_MOVE_LEVEL_REQUIREMENT } from "#data/balance/moveset-generation"; import { modifierTypes } from "#data/data-lists"; import { doubleBattleDialogue } from "#data/double-battle-dialogue"; import { Gender } from "#data/gender"; @@ -41,6 +43,7 @@ import type { TrainerConfigs, TrainerTierPools, } from "#types/trainer-funcs"; +import type { Mutable } from "#types/type-helpers"; import { coerceArray, randSeedInt, randSeedIntRange, randSeedItem } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import { toCamelCase, toTitleCase } from "#utils/strings"; @@ -119,6 +122,15 @@ export class TrainerConfig { public hasVoucher = false; public trainerAI: TrainerAI; + /** + * Whether this trainer's Pokémon are allowed to generate with egg moves + * @defaultValue `false` + * + * @see {@linkcode setEggMovesAllowed} + * @see {@linkcode RARE_EGG_MOVE_LEVEL_THRESHOLD} + */ + public readonly allowEggMoves: boolean = false; + public encounterMessages: string[] = []; public victoryMessages: string[] = []; public defeatMessages: string[] = []; @@ -387,8 +399,27 @@ export class TrainerConfig { return this; } - setBoss(): TrainerConfig { + /** + * Allow this trainer's Pokémon to have egg moves when generating their movesets. + * + * @remarks + * It is redundant to call this if {@linkcode setBoss} is also called on the configuration. + * @returns `this` for method chaining + * @see {@linkcode allowEggMoves} + */ + public setEggMovesAllowed(): this { + (this as Mutable).allowEggMoves = true; + return this; + } + + /** + * Set this trainer as a boss trainer + * @returns `this` for method chaining + * @see {@linkcode isBoss} + */ + public setBoss(): TrainerConfig { this.isBoss = true; + (this as Mutable).allowEggMoves = true; return this; } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 9f217cc4d64..46f88abc61c 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1,5 +1,6 @@ import type { Ability, PreAttackModifyDamageAbAttrParams } from "#abilities/ability"; import { applyAbAttrs, applyOnGainAbAttrs, applyOnLoseAbAttrs } from "#abilities/apply-ab-attrs"; +import { generateMoveset } from "#app/ai/ai-moveset-gen"; import type { AnySound, BattleScene } from "#app/battle-scene"; import { PLAYER_PARTY_MAX_SIZE, RARE_CANDY_FRIENDSHIP_CAP } from "#app/constants"; import { timedEventManager } from "#app/global-event-manager"; @@ -18,7 +19,7 @@ import type { LevelMoves } from "#balance/pokemon-level-moves"; import { EVOLVE_MOVE, RELEARN_MOVE } from "#balance/pokemon-level-moves"; import { BASE_HIDDEN_ABILITY_CHANCE, BASE_SHINY_CHANCE, SHINY_EPIC_CHANCE, SHINY_VARIANT_CHANCE } from "#balance/rates"; import { getStarterValueFriendshipCap, speciesStarterCosts } from "#balance/starters"; -import { reverseCompatibleTms, tmPoolTiers, tmSpecies } from "#balance/tms"; +import { reverseCompatibleTms, tmSpecies } from "#balance/tms"; import type { SuppressAbilitiesTag } from "#data/arena-tag"; import { NoCritTag, WeakenMoveScreenTag } from "#data/arena-tag"; import { @@ -81,7 +82,6 @@ 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 { ModifierTier } from "#enums/modifier-tier"; import { MoveCategory } from "#enums/move-category"; import { MoveFlags } from "#enums/move-flags"; import { MoveId } from "#enums/move-id"; @@ -1440,6 +1440,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { simulated = true, ignoreHeldItems = false, ): number { + // biome-ignore-start lint/nursery/useMaxParams: test const statVal = new NumberHolder(this.getStat(stat, false)); if (!ignoreHeldItems) { globalScene.applyModifiers(StatBoosterModifier, this.isPlayer(), this, stat, statVal); @@ -1538,6 +1539,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { } return Math.floor(ret); + // biome-ignore-end lint/nursery/useMaxParams: test } calculateStats(): void { @@ -2774,7 +2776,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { * This causes problems when there are intentional duplicates (i.e. Smeargle with Sketch) */ if (levelMoves) { - this.getUniqueMoves(levelMoves, ret); + Pokemon.getUniqueMoves(levelMoves, ret); } return ret; @@ -2788,7 +2790,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { * @param levelMoves the input array to search for non-duplicates from * @param ret the output array to be pushed into. */ - private getUniqueMoves(levelMoves: LevelMoves, ret: LevelMoves): void { + private static getUniqueMoves(levelMoves: LevelMoves, ret: LevelMoves): void { const uniqueMoves: MoveId[] = []; for (const lm of levelMoves) { if (!uniqueMoves.find(m => m === lm[1])) { @@ -3046,294 +3048,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { /** Generates a semi-random moveset for a Pokemon */ public generateAndPopulateMoveset(): void { - this.moveset = []; - let movePool: [MoveId, number][] = []; - const allLevelMoves = this.getLevelMoves(1, true, true, this.hasTrainer()); - if (!allLevelMoves) { - console.warn("Error encountered trying to generate moveset for:", this.species.name); - return; - } - - for (const levelMove of allLevelMoves) { - if (this.level < levelMove[0]) { - break; - } - let weight = levelMove[0] + 20; - // Evolution Moves - if (levelMove[0] === EVOLVE_MOVE) { - weight = 70; - } - // Assume level 1 moves with 80+ BP are "move reminder" moves and bump their weight. Trainers use actual relearn moves. - if ( - (levelMove[0] === 1 && allMoves[levelMove[1]].power >= 80) - || (levelMove[0] === RELEARN_MOVE && this.hasTrainer()) - ) { - weight = 60; - } - if (!movePool.some(m => m[0] === levelMove[1]) && !allMoves[levelMove[1]].name.endsWith(" (N)")) { - movePool.push([levelMove[1], weight]); - } - } - - if (this.hasTrainer()) { - const tms = Object.keys(tmSpecies); - for (const tm of tms) { - const moveId = Number.parseInt(tm) as MoveId; - let compatible = false; - for (const p of tmSpecies[tm]) { - if (Array.isArray(p)) { - if ( - p[0] === this.species.speciesId - || (this.fusionSpecies - && p[0] === this.fusionSpecies.speciesId - && p.slice(1).indexOf(this.species.forms[this.formIndex]) > -1) - ) { - compatible = true; - break; - } - } else if (p === this.species.speciesId || (this.fusionSpecies && p === this.fusionSpecies.speciesId)) { - compatible = true; - break; - } - } - if (compatible && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) { - if (tmPoolTiers[moveId] === ModifierTier.COMMON && this.level >= 15) { - movePool.push([moveId, 24]); - } else if (tmPoolTiers[moveId] === ModifierTier.GREAT && this.level >= 30) { - movePool.push([moveId, 28]); - } else if (tmPoolTiers[moveId] === ModifierTier.ULTRA && this.level >= 50) { - movePool.push([moveId, 34]); - } - } - } - - // No egg moves below level 60 - if (this.level >= 60) { - for (let i = 0; i < 3; i++) { - const moveId = speciesEggMoves[this.species.getRootSpeciesId()][i]; - if (!movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) { - movePool.push([moveId, 60]); - } - } - const moveId = speciesEggMoves[this.species.getRootSpeciesId()][3]; - // No rare egg moves before e4 - if ( - this.level >= 170 - && !movePool.some(m => m[0] === moveId) - && !allMoves[moveId].name.endsWith(" (N)") - && !this.isBoss() - ) { - movePool.push([moveId, 50]); - } - if (this.fusionSpecies) { - for (let i = 0; i < 3; i++) { - const moveId = speciesEggMoves[this.fusionSpecies.getRootSpeciesId()][i]; - if (!movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) { - movePool.push([moveId, 60]); - } - } - const moveId = speciesEggMoves[this.fusionSpecies.getRootSpeciesId()][3]; - // No rare egg moves before e4 - if ( - this.level >= 170 - && !movePool.some(m => m[0] === moveId) - && !allMoves[moveId].name.endsWith(" (N)") - && !this.isBoss() - ) { - movePool.push([moveId, 50]); - } - } - } - } - - // Bosses never get self ko moves or Pain Split - if (this.isBoss()) { - movePool = movePool.filter( - m => !allMoves[m[0]].hasAttr("SacrificialAttr") && !allMoves[m[0]].hasAttr("HpSplitAttr"), - ); - } - // No one gets Memento or Final Gambit - movePool = movePool.filter(m => !allMoves[m[0]].hasAttr("SacrificialAttrOnHit")); - if (this.hasTrainer()) { - // Trainers never get OHKO moves - movePool = movePool.filter(m => !allMoves[m[0]].hasAttr("OneHitKOAttr")); - // Half the weight of self KO moves - movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].hasAttr("SacrificialAttr") ? 0.5 : 1)]); - // Trainers get a weight bump to stat buffing moves - movePool = movePool.map(m => [ - m[0], - m[1] * (allMoves[m[0]].getAttrs("StatStageChangeAttr").some(a => a.stages > 1 && a.selfTarget) ? 1.25 : 1), - ]); - // Trainers get a weight decrease to multiturn moves - movePool = movePool.map(m => [ - m[0], - m[1] * (!!allMoves[m[0]].isChargingMove() || !!allMoves[m[0]].hasAttr("RechargeAttr") ? 0.7 : 1), - ]); - } - - // Weight towards higher power moves, by reducing the power of moves below the highest power. - // Caps max power at 90 to avoid something like hyper beam ruining the stats. - // This is a pretty soft weighting factor, although it is scaled with the weight multiplier. - const maxPower = Math.min( - movePool.reduce((v, m) => Math.max(allMoves[m[0]].calculateEffectivePower(), v), 40), - 90, - ); - movePool = movePool.map(m => [ - m[0], - m[1] - * (allMoves[m[0]].category === MoveCategory.STATUS - ? 1 - : Math.max(Math.min(allMoves[m[0]].calculateEffectivePower() / maxPower, 1), 0.5)), - ]); - - // Weight damaging moves against the lower stat. This uses a non-linear relationship. - // If the higher stat is 1 - 1.09x higher, no change. At higher stat ~1.38x lower stat, off-stat moves have half weight. - // One third weight at ~1.58x higher, one quarter weight at ~1.73x higher, one fifth at ~1.87x, and one tenth at ~2.35x higher. - const atk = this.getStat(Stat.ATK); - const spAtk = this.getStat(Stat.SPATK); - const worseCategory: MoveCategory = atk > spAtk ? MoveCategory.SPECIAL : MoveCategory.PHYSICAL; - const statRatio = worseCategory === MoveCategory.PHYSICAL ? atk / spAtk : spAtk / atk; - movePool = movePool.map(m => [ - m[0], - m[1] * (allMoves[m[0]].category === worseCategory ? Math.min(Math.pow(statRatio, 3) * 1.3, 1) : 1), - ]); - - /** The higher this is the more the game weights towards higher level moves. At `0` all moves are equal weight. */ - let weightMultiplier = 1.6; - if (this.isBoss()) { - weightMultiplier += 0.4; - } - const baseWeights: [MoveId, number][] = movePool.map(m => [ - m[0], - Math.ceil(Math.pow(m[1], weightMultiplier) * 100), - ]); - - const STAB_BLACKLIST: ReadonlySet = new Set([ - MoveId.BEAT_UP, - MoveId.BELCH, - MoveId.BIDE, - MoveId.COMEUPPANCE, - MoveId.COUNTER, - MoveId.DOOM_DESIRE, - MoveId.DRAGON_RAGE, - MoveId.DREAM_EATER, - MoveId.ENDEAVOR, - MoveId.EXPLOSION, - MoveId.FAKE_OUT, - MoveId.FIRST_IMPRESSION, - MoveId.FISSURE, - MoveId.FLING, - MoveId.FOCUS_PUNCH, - MoveId.FUTURE_SIGHT, - MoveId.GUILLOTINE, - MoveId.HOLD_BACK, - MoveId.HORN_DRILL, - MoveId.LAST_RESORT, - MoveId.METAL_BURST, - MoveId.MIRROR_COAT, - MoveId.MISTY_EXPLOSION, - MoveId.NATURAL_GIFT, - MoveId.NATURES_MADNESS, - MoveId.NIGHT_SHADE, - MoveId.PSYWAVE, - MoveId.RUINATION, - MoveId.SELF_DESTRUCT, - MoveId.SHEER_COLD, - MoveId.SHELL_TRAP, - MoveId.SKY_DROP, - MoveId.SNORE, - MoveId.SONIC_BOOM, - MoveId.SPIT_UP, - MoveId.STEEL_BEAM, - MoveId.STEEL_ROLLER, - MoveId.SUPER_FANG, - MoveId.SYNCHRONOISE, - MoveId.UPPER_HAND, - ]); - - // All Pokemon force a STAB move first - const stabMovePool = baseWeights.filter( - m => - allMoves[m[0]].category !== MoveCategory.STATUS - && this.isOfType(allMoves[m[0]].type) - && !STAB_BLACKLIST.has(m[0]), - ); - - if (stabMovePool.length > 0) { - const totalWeight = stabMovePool.reduce((v, m) => v + m[1], 0); - let rand = randSeedInt(totalWeight); - let index = 0; - while (rand > stabMovePool[index][1]) { - rand -= stabMovePool[index++][1]; - } - this.moveset.push(new PokemonMove(stabMovePool[index][0])); - } else { - // If there are no damaging STAB moves, just force a random damaging move - const attackMovePool = baseWeights.filter( - m => allMoves[m[0]].category !== MoveCategory.STATUS && !STAB_BLACKLIST.has(m[0]), - ); - if (attackMovePool.length > 0) { - const totalWeight = attackMovePool.reduce((v, m) => v + m[1], 0); - let rand = randSeedInt(totalWeight); - let index = 0; - while (rand > attackMovePool[index][1]) { - rand -= attackMovePool[index++][1]; - } - this.moveset.push(new PokemonMove(attackMovePool[index][0], 0, 0)); - } - } - - while (baseWeights.length > this.moveset.length && this.moveset.length < 4) { - if (this.hasTrainer()) { - // Sqrt the weight of any damaging moves with overlapping types. This is about a 0.05 - 0.1 multiplier. - // Other damaging moves 2x weight if 0-1 damaging moves, 0.5x if 2, 0.125x if 3. These weights get 20x if STAB. - // Status moves remain unchanged on weight, this encourages 1-2 - movePool = baseWeights - .filter( - m => - !this.moveset.some( - mo => - m[0] === mo.moveId - || (allMoves[m[0]].hasAttr("SacrificialAttr") && mo.getMove().hasAttr("SacrificialAttr")), // Only one self-KO move allowed - ), - ) - .map(m => { - let ret: number; - if ( - this.moveset.some( - mo => mo.getMove().category !== MoveCategory.STATUS && mo.getMove().type === allMoves[m[0]].type, - ) - ) { - ret = Math.ceil(Math.sqrt(m[1])); - } else if (allMoves[m[0]].category !== MoveCategory.STATUS) { - ret = Math.ceil( - (m[1] / Math.max(Math.pow(4, this.moveset.filter(mo => (mo.getMove().power ?? 0) > 1).length) / 8, 0.5)) - * (this.isOfType(allMoves[m[0]].type) && !STAB_BLACKLIST.has(m[0]) ? 20 : 1), - ); - } else { - ret = m[1]; - } - return [m[0], ret]; - }); - } else { - // Non-trainer pokemon just use normal weights - movePool = baseWeights.filter( - m => - !this.moveset.some( - mo => - m[0] === mo.moveId - || (allMoves[m[0]].hasAttr("SacrificialAttr") && mo.getMove().hasAttr("SacrificialAttr")), // Only one self-KO move allowed - ), - ); - } - const totalWeight = movePool.reduce((v, m) => v + m[1], 0); - let rand = randSeedInt(totalWeight); - let index = 0; - while (rand > movePool[index][1]) { - rand -= movePool[index++][1]; - } - this.moveset.push(new PokemonMove(movePool[index][0])); - } + generateMoveset(this); // Trigger FormChange, except for enemy Pokemon during Mystery Encounters, to avoid crashes if ( From 793dea002401887678f8c767d97efc1365f10c4f Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sun, 14 Sep 2025 22:35:12 -0500 Subject: [PATCH 23/29] [Bug] [Docs] Fix `@module` tags (#6557) Fix `@module` tags --- src/constants/colors.ts | 3 +- src/data/arena-tag.ts | 71 ++++++++++++------------ src/data/balance/moveset-generation.ts | 4 +- src/data/battler-tags.ts | 77 +++++++++++++------------- src/phase-manager.ts | 17 +++--- test/test-utils/setup/test-end-log.ts | 2 +- 6 files changed, 85 insertions(+), 89 deletions(-) diff --git a/src/constants/colors.ts b/src/constants/colors.ts index 717c5fa5f0d..a2400ef5f90 100644 --- a/src/constants/colors.ts +++ b/src/constants/colors.ts @@ -1,7 +1,8 @@ /** - * @module + * * A big file storing colors used in logging. * Minified by Terser during production builds, so has no overhead. + * @module */ // Colors used in prod diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index d3098314beb..e59d7173538 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -1,39 +1,4 @@ -/** 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"; -import { CommonBattleAnim } from "#data/battle-anims"; -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 { 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 { 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 { - ArenaScreenTagType, - ArenaTagData, - EntryHazardTagType, - RoomArenaTagType, - SerializableArenaTagType, -} from "#types/arena-tags"; -import type { Mutable } from "#types/type-helpers"; -import { BooleanHolder, type 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 Happy Hour @@ -75,8 +40,42 @@ import i18next from "i18next"; * } * ``` * Notes - * - If the class has any subclasses, then the second form of `loadTag` *must* be used. + * - If the class has any subclasses, then the second form of `loadTag` *must* be used.\ + * @module */ +// 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"; +import { CommonBattleAnim } from "#data/battle-anims"; +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 { 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 { 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 { + ArenaScreenTagType, + ArenaTagData, + EntryHazardTagType, + RoomArenaTagType, + SerializableArenaTagType, +} from "#types/arena-tags"; +import type { Mutable } from "#types/type-helpers"; +import { BooleanHolder, type NumberHolder, toDmgValue } from "#utils/common"; +import i18next from "i18next"; /** Interface containing the serializable fields of ArenaTagData. */ interface BaseArenaTag { diff --git a/src/data/balance/moveset-generation.ts b/src/data/balance/moveset-generation.ts index d6579eb45e7..91423f80f9a 100644 --- a/src/data/balance/moveset-generation.ts +++ b/src/data/balance/moveset-generation.ts @@ -3,9 +3,6 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { MoveId } from "#enums/move-id"; - - /** * # Balance: Moveset Generation Configuration * @@ -33,6 +30,7 @@ import { MoveId } from "#enums/move-id"; * * @module */ +import { MoveId } from "#enums/move-id"; //#region Constants diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 6490a6086c4..dc4a5383e24 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -1,3 +1,41 @@ +/** + * 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. + * + * 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; + * } + * ``` + * Notes + * - If the class has any subclasses, then the second form of `loadTag` *must* be used. + * @module + */ import { applyAbAttrs } from "#abilities/apply-ab-attrs"; import { globalScene } from "#app/global-scene"; import { getPokemonNameWithAffix } from "#app/messages"; @@ -52,45 +90,6 @@ import type { Mutable } from "#types/type-helpers"; import { BooleanHolder, coerceArray, getFrameMs, NumberHolder, toDmgValue } from "#utils/common"; import { toCamelCase } from "#utils/strings"; -/** - * @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. - * - * 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; - * } - * ``` - * Notes - * - If the class has any subclasses, then the second form of `loadTag` *must* be used. - */ - /** Interface containing the serializable fields of BattlerTag */ interface BaseBattlerTag { /** The tag's remaining duration */ diff --git a/src/phase-manager.ts b/src/phase-manager.ts index 4bb7e0a4b37..253c6d8314d 100644 --- a/src/phase-manager.ts +++ b/src/phase-manager.ts @@ -1,3 +1,11 @@ +/** + * Manager for phases used by battle scene. + * + * @remarks + * **This file must not be imported or used directly.** + * The manager is exclusively used by the Battle Scene and is NOT intended for external use. + * @module + */ import { PHASE_START_COLOR } from "#app/constants/colors"; import { globalScene } from "#app/global-scene"; import type { Phase } from "#app/phase"; @@ -103,15 +111,6 @@ import { WeatherEffectPhase } from "#phases/weather-effect-phase"; import type { PhaseMap, PhaseString } from "#types/phase-types"; import { type Constructor, coerceArray } from "#utils/common"; -/** - * @module - * Manager for phases used by battle scene. - * - * @remarks - * **This file must not be imported or used directly.** - * The manager is exclusively used by the Battle Scene and is NOT intended for external use. - */ - /** * Object that holds all of the phase constructors. * This is used to create new phases dynamically using the `newPhase` method in the `PhaseManager`. diff --git a/test/test-utils/setup/test-end-log.ts b/test/test-utils/setup/test-end-log.ts index 9814ba8a45c..fbcb9480330 100644 --- a/test/test-utils/setup/test-end-log.ts +++ b/test/test-utils/setup/test-end-log.ts @@ -5,10 +5,10 @@ import chalk from "chalk"; import type { RunnerTask, RunnerTaskResult, RunnerTestCase } from "vitest"; /** - * @module * Code to add markers to the beginning and end of tests. * Intended for use with {@linkcode CustomDefaultReporter}, and placed inside test hooks * (rather than as part of the reporter) to ensure Vitest waits for the log messages to be printed. + * @module */ /** A long string of "="s to partition off each test from one another. */ From de94e738fbc5eed77b104152632eaf51e9b8ee86 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Sun, 14 Sep 2025 20:45:01 -0700 Subject: [PATCH 24/29] [Docs] Add blank space to prevent incorrect comment attachment Biome will "attach" comments to imports if there is no space between them when it sorts imports (this allows suppression comments to work) --- src/data/arena-tag.ts | 3 ++- src/data/balance/moveset-generation.ts | 1 + src/data/battler-tags.ts | 1 + src/phase-manager.ts | 1 + test/test-utils/setup/test-end-log.ts | 12 ++++++------ 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index e59d7173538..ff939194bcd 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -40,9 +40,10 @@ * } * ``` * Notes - * - If the class has any subclasses, then the second form of `loadTag` *must* be used.\ + * - If the class has any subclasses, then the second form of `loadTag` *must* be used. * @module */ + // biome-ignore-start lint/correctness/noUnusedImports: TSDoc imports import type { BattlerTag } from "#app/data/battler-tags"; // biome-ignore-end lint/correctness/noUnusedImports: TSDoc imports diff --git a/src/data/balance/moveset-generation.ts b/src/data/balance/moveset-generation.ts index 91423f80f9a..f9c2a03f4a9 100644 --- a/src/data/balance/moveset-generation.ts +++ b/src/data/balance/moveset-generation.ts @@ -30,6 +30,7 @@ * * @module */ + import { MoveId } from "#enums/move-id"; diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index dc4a5383e24..80a30516903 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -36,6 +36,7 @@ * - If the class has any subclasses, then the second form of `loadTag` *must* be used. * @module */ + import { applyAbAttrs } from "#abilities/apply-ab-attrs"; import { globalScene } from "#app/global-scene"; import { getPokemonNameWithAffix } from "#app/messages"; diff --git a/src/phase-manager.ts b/src/phase-manager.ts index 253c6d8314d..3fbf68de60d 100644 --- a/src/phase-manager.ts +++ b/src/phase-manager.ts @@ -6,6 +6,7 @@ * The manager is exclusively used by the Battle Scene and is NOT intended for external use. * @module */ + import { PHASE_START_COLOR } from "#app/constants/colors"; import { globalScene } from "#app/global-scene"; import type { Phase } from "#app/phase"; diff --git a/test/test-utils/setup/test-end-log.ts b/test/test-utils/setup/test-end-log.ts index fbcb9480330..5be8299b124 100644 --- a/test/test-utils/setup/test-end-log.ts +++ b/test/test-utils/setup/test-end-log.ts @@ -1,9 +1,3 @@ -// biome-ignore lint/correctness/noUnusedImports: TSDoc -import type CustomDefaultReporter from "#test/test-utils/reporters/custom-default-reporter"; -import { basename, join, relative } from "path"; -import chalk from "chalk"; -import type { RunnerTask, RunnerTaskResult, RunnerTestCase } from "vitest"; - /** * Code to add markers to the beginning and end of tests. * Intended for use with {@linkcode CustomDefaultReporter}, and placed inside test hooks @@ -11,6 +5,12 @@ import type { RunnerTask, RunnerTaskResult, RunnerTestCase } from "vitest"; * @module */ +// biome-ignore lint/correctness/noUnusedImports: TSDoc +import type CustomDefaultReporter from "#test/test-utils/reporters/custom-default-reporter"; +import { basename, join, relative } from "path"; +import chalk from "chalk"; +import type { RunnerTask, RunnerTaskResult, RunnerTestCase } from "vitest"; + /** A long string of "="s to partition off each test from one another. */ const TEST_END_BARRIER = chalk.bold.hex("#ff7c7cff")("=================="); From b7cee4b3131211587ec8b67f085b456c5fbc0892 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Mon, 15 Sep 2025 00:25:25 -0700 Subject: [PATCH 25/29] [Misc] Remove leftover temporary comments in `pokemon.ts` --- src/field/pokemon.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 46f88abc61c..4b8a39ee759 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1440,7 +1440,6 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { simulated = true, ignoreHeldItems = false, ): number { - // biome-ignore-start lint/nursery/useMaxParams: test const statVal = new NumberHolder(this.getStat(stat, false)); if (!ignoreHeldItems) { globalScene.applyModifiers(StatBoosterModifier, this.isPlayer(), this, stat, statVal); @@ -1539,7 +1538,6 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { } return Math.floor(ret); - // biome-ignore-end lint/nursery/useMaxParams: test } calculateStats(): void { From 8013093513fd272b6f8aa5d76329c682a098813d Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 15 Sep 2025 14:04:13 -0500 Subject: [PATCH 26/29] [Bug] Secondary fusions with gender evo condition can now evolve (#6510) --- src/data/balance/pokemon-evolutions.ts | 6 +++--- src/field/pokemon.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/data/balance/pokemon-evolutions.ts b/src/data/balance/pokemon-evolutions.ts index c868a49dbfa..0c2fa4e78fa 100644 --- a/src/data/balance/pokemon-evolutions.ts +++ b/src/data/balance/pokemon-evolutions.ts @@ -166,7 +166,7 @@ export class SpeciesEvolutionCondition { return this.desc; } - public conditionsFulfilled(pokemon: Pokemon): boolean { + public conditionsFulfilled(pokemon: Pokemon, forFusion = false): boolean { console.log(this.data); return this.data.every(cond => { switch (cond.key) { @@ -186,7 +186,7 @@ export class SpeciesEvolutionCondition { m.getStackCount() + pokemon.getPersistentTreasureCount() >= cond.value ); case EvoCondKey.GENDER: - return pokemon.gender === cond.gender; + return cond.gender === (forFusion ? pokemon.fusionGender : pokemon.gender); case EvoCondKey.SHEDINJA: // Shedinja cannot be evolved into directly return false; case EvoCondKey.BIOME: @@ -293,7 +293,7 @@ export class SpeciesFormEvolution { pokemon.level >= this.level && // Check form key, using the fusion's form key if we're checking the fusion (this.preFormKey == null || (forFusion ? pokemon.getFusionFormKey() : pokemon.getFormKey()) === this.preFormKey) && - (this.condition == null || this.condition.conditionsFulfilled(pokemon)) && + (this.condition == null || this.condition.conditionsFulfilled(pokemon, forFusion)) && ((item ?? EvolutionItem.NONE) === (this.item ?? EvolutionItem.NONE)) ); } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 4b8a39ee759..d48f4ae8ad2 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -2635,7 +2635,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container { e => new FusionSpeciesFormEvolution(this.species.speciesId, e), ); for (const fe of fusionEvolutions) { - if (fe.validate(this)) { + if (fe.validate(this, true)) { return fe; } } From 65bb58a635c5e32eb852f5ab2db438e97b0ef907 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Mon, 15 Sep 2025 16:51:28 -0400 Subject: [PATCH 27/29] [Dev] Fix + rename `test:create` boilerplate file (#6560) * Rename `default.ts` to `default.boilerplate.ts` * Update `test:create` script to look in the correct location * Update `biome.jsonc` to remove explicit boilerplate folder check * Apply Biome --- biome.jsonc | 11 ++--------- .../{default.ts => default.boilerplate.ts} | 2 +- scripts/create-test/create-test.js | 4 ++-- 3 files changed, 5 insertions(+), 12 deletions(-) rename scripts/create-test/boilerplates/{default.ts => default.boilerplate.ts} (94%) diff --git a/biome.jsonc b/biome.jsonc index 9e87518e636..2433ba52010 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -254,16 +254,9 @@ }, // Overrides to prevent unused import removal inside `overrides.ts`, enums & `.d.ts` files (for TSDoc linkcodes), - // as well as inside script boilerplate files. + // as well as inside script boilerplate files (whose imports will _presumably_ be used in the generated file). { - // TODO: Rename existing boilerplates in the folder and remove this last alias - "includes": [ - "**/src/overrides.ts", - "**/src/enums/**/*", - "**/*.d.ts", - "scripts/**/*.boilerplate.ts", - "**/boilerplates/*.ts" - ], + "includes": ["**/src/overrides.ts", "**/src/enums/**/*", "**/*.d.ts", "scripts/**/*.boilerplate.ts"], "linter": { "rules": { "correctness": { diff --git a/scripts/create-test/boilerplates/default.ts b/scripts/create-test/boilerplates/default.boilerplate.ts similarity index 94% rename from scripts/create-test/boilerplates/default.ts rename to scripts/create-test/boilerplates/default.boilerplate.ts index e644e740594..7b633cf8276 100644 --- a/scripts/create-test/boilerplates/default.ts +++ b/scripts/create-test/boilerplates/default.boilerplate.ts @@ -47,6 +47,6 @@ describe("{{description}}", () => { await game.toEndOfTurn(); expect(feebas).toHaveUsedMove({ move: MoveId.SPLASH, result: MoveResult.SUCCESS }); - expect(game.textInterceptor.logs).toContain(i18next.t("moveTriggers:splash")); + expect(game).toHaveShownMessage(i18next.t("moveTriggers:splash")); }); }); diff --git a/scripts/create-test/create-test.js b/scripts/create-test/create-test.js index 5e395783da7..df065657346 100644 --- a/scripts/create-test/create-test.js +++ b/scripts/create-test/create-test.js @@ -102,9 +102,9 @@ async function promptFileName(selectedType) { function getBoilerplatePath(choiceType) { switch (choiceType) { // case "Reward": - // return path.join(__dirname, "boilerplates/reward.ts"); + // return path.join(__dirname, "boilerplates/reward.boilerplate.ts"); default: - return path.join(__dirname, "boilerplates/default.ts"); + return path.join(__dirname, "boilerplates/default.boilerplate.ts"); } } From 6ce59ecbd983bccbf24ca3c7f4c2cbf42d78a41d Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 15 Sep 2025 19:49:18 -0500 Subject: [PATCH 28/29] [Bug] Cookies being fetched improperly --- src/utils/cookies.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/cookies.ts b/src/utils/cookies.ts index e82895d1fac..49c47437241 100644 --- a/src/utils/cookies.ts +++ b/src/utils/cookies.ts @@ -25,9 +25,9 @@ export function getCookie(cName: string): string { const ca = document.cookie.split(";"); // Check all cookies in the document and see if any of them match, grabbing the first one whose value lines up for (const c of ca) { - const cTrimmed = c.trim(); + const cTrimmed = c.trimStart(); if (cTrimmed.startsWith(name)) { - return c.slice(name.length, c.length); + return c.substring(name.length, c.length); } } return ""; From 85c38dfdbe1a6cf6aa26862ec7952ab76f2d7ab0 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 15 Sep 2025 19:55:45 -0500 Subject: [PATCH 29/29] [Bug] Cookies being fetched improperly v2 --- src/utils/cookies.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/utils/cookies.ts b/src/utils/cookies.ts index 49c47437241..e16d9d78556 100644 --- a/src/utils/cookies.ts +++ b/src/utils/cookies.ts @@ -23,10 +23,12 @@ export function getCookie(cName: string): string { } const name = `${cName}=`; const ca = document.cookie.split(";"); - // Check all cookies in the document and see if any of them match, grabbing the first one whose value lines up - for (const c of ca) { - const cTrimmed = c.trimStart(); - if (cTrimmed.startsWith(name)) { + for (let c of ca) { + // ⚠️ DO NOT REPLACE THIS WITH C = C.TRIM() - IT BREAKS IN NON-CHROMIUM BROWSERS ⚠️ + while (c.charAt(0) === " ") { + c = c.substring(1); + } + if (c.indexOf(name) === 0) { return c.substring(name.length, c.length); } }