Merge remote-tracking branch 'upstream/beta' into todo-test-enable

This commit is contained in:
Bertie690 2025-09-11 18:32:49 -04:00
commit b53cb2e13d
221 changed files with 1521 additions and 1327 deletions

7
.dockerignore Normal file
View File

@ -0,0 +1,7 @@
# .dockerignore
node_modules
*.log
*.md
.gitignore
Dockerfile
.env

View File

@ -55,15 +55,15 @@ jobs:
- name: Create release branch - name: Create release branch
run: git checkout -b release 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. # In order to be able to open a PR into beta, we need the branch to have at least one commit.
- name: Overwrite RELEASE file # 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: | run: |
git config --local user.name "github-actions[bot]" git config --local user.name "github-actions[bot]"
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
echo "Release v${{ github.event.inputs.versionName }}" > RELEASE pnpm --no-git-tag-version version ${{ github.events.inputs.versionName }}
git add RELEASE git commit -am "Stage release for v${{ github.events.inputs.versionName }}"
git commit -m "Stage release v${{ github.event.inputs.versionName }}"
- name: Push new branch - name: Push new branch
run: git push origin release run: git push origin release

View File

@ -22,8 +22,6 @@ jobs:
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with:
version: 10
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:

View File

@ -20,8 +20,6 @@ jobs:
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with:
version: 10
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:

View File

@ -27,20 +27,18 @@ jobs:
# Only push docs when running on pushes to main/beta # Only push docs when running on pushes to main/beta
DRY_RUN: ${{github.event_name != 'push' || (github.ref_name != 'beta' && github.ref_name != 'main')}} DRY_RUN: ${{github.event_name != 'push' || (github.ref_name != 'beta' && github.ref_name != 'main')}}
strategy:
fail-fast: false
steps: steps:
- name: Checkout repository for Typedoc - name: Checkout repository for Typedoc
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
submodules: 'recursive'
path: pokerogue_docs path: pokerogue_docs
sparse-checkout: |
- name: Install OS package /*
run: | !/public/
sudo apt update /public/images/pokemon/variant/_exp_masterlist.json
sudo apt install -y git openssh-client /public/images/pokemon/variant/_masterlist.json
/public/images/logo.png
sparse-checkout-cone-mode: false
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4

View File

@ -30,8 +30,6 @@ jobs:
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with:
version: 10
- name: Set up Node - name: Set up Node
uses: actions/setup-node@v4 uses: actions/setup-node@v4

View File

@ -32,8 +32,6 @@ jobs:
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with:
version: 10
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4

View File

@ -28,6 +28,10 @@ jobs:
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
sparse-checkout: |
.github/test-filters.yml
sparse-checkout-cone-mode: false
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36
id: filter id: filter

View File

@ -80,7 +80,8 @@ Notable topics include:
- [Commenting your code](./docs/comments.md) - [Commenting your code](./docs/comments.md)
- [Linting & Formatting](./docs/linting.md) - [Linting & Formatting](./docs/linting.md)
- [Localization](./docs/localization.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! Again, if you have unanswered questions please feel free to ask!

47
Dockerfile Normal file
View File

@ -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"]

View File

@ -1 +0,0 @@
Release v1.10.0

27
docs/podman.md Normal file
View File

@ -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
`

View File

@ -7,6 +7,7 @@
"start:prod": "vite --mode production", "start:prod": "vite --mode production",
"start:beta": "vite --mode beta", "start:beta": "vite --mode beta",
"start:dev": "vite --mode development", "start:dev": "vite --mode development",
"start:podman": "vite --mode development --host 0.0.0.0 --port $PORT",
"build": "vite build", "build": "vite build",
"build:beta": "vite build --mode beta", "build:beta": "vite build --mode beta",
"preview": "vite preview", "preview": "vite preview",
@ -46,7 +47,7 @@
"lefthook": "^1.12.2", "lefthook": "^1.12.2",
"msw": "^2.10.4", "msw": "^2.10.4",
"phaser3spectorjs": "^0.0.8", "phaser3spectorjs": "^0.0.8",
"typedoc": "^0.28.8", "typedoc": "0.28.7",
"typedoc-github-theme": "^0.3.1", "typedoc-github-theme": "^0.3.1",
"typedoc-plugin-coverage": "^4.0.1", "typedoc-plugin-coverage": "^4.0.1",
"typedoc-plugin-mdn-links": "^5.0.9", "typedoc-plugin-mdn-links": "^5.0.9",
@ -71,5 +72,6 @@
}, },
"engines": { "engines": {
"node": ">=22.0.0" "node": ">=22.0.0"
} },
"packageManager": "pnpm@10.14.0"
} }

View File

@ -59,7 +59,7 @@ importers:
version: 22.16.5 version: 22.16.5
'@vitest/coverage-istanbul': '@vitest/coverage-istanbul':
specifier: ^3.2.4 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.0)) version: 3.2.4(vitest@3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.1))
'@vitest/expect': '@vitest/expect':
specifier: ^3.2.4 specifier: ^3.2.4
version: 3.2.4 version: 3.2.4
@ -88,32 +88,32 @@ importers:
specifier: ^0.0.8 specifier: ^0.0.8
version: 0.0.8 version: 0.0.8
typedoc: typedoc:
specifier: ^0.28.8 specifier: 0.28.7
version: 0.28.8(typescript@5.8.3) version: 0.28.7(typescript@5.8.3)
typedoc-github-theme: typedoc-github-theme:
specifier: ^0.3.1 specifier: ^0.3.1
version: 0.3.1(typedoc@0.28.8(typescript@5.8.3)) version: 0.3.1(typedoc@0.28.7(typescript@5.8.3))
typedoc-plugin-coverage: typedoc-plugin-coverage:
specifier: ^4.0.1 specifier: ^4.0.1
version: 4.0.1(typedoc@0.28.8(typescript@5.8.3)) version: 4.0.1(typedoc@0.28.7(typescript@5.8.3))
typedoc-plugin-mdn-links: typedoc-plugin-mdn-links:
specifier: ^5.0.9 specifier: ^5.0.9
version: 5.0.9(typedoc@0.28.8(typescript@5.8.3)) version: 5.0.9(typedoc@0.28.7(typescript@5.8.3))
typescript: typescript:
specifier: ^5.8.3 specifier: ^5.8.3
version: 5.8.3 version: 5.8.3
vite: vite:
specifier: ^7.0.6 specifier: ^7.0.6
version: 7.0.6(@types/node@22.16.5)(yaml@2.8.0) version: 7.0.6(@types/node@22.16.5)(yaml@2.8.1)
vite-tsconfig-paths: vite-tsconfig-paths:
specifier: ^5.1.4 specifier: ^5.1.4
version: 5.1.4(typescript@5.8.3)(vite@7.0.6(@types/node@22.16.5)(yaml@2.8.0)) version: 5.1.4(typescript@5.8.3)(vite@7.0.6(@types/node@22.16.5)(yaml@2.8.1))
vitest: vitest:
specifier: ^3.2.4 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.0) version: 3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.1)
vitest-canvas-mock: vitest-canvas-mock:
specifier: ^0.3.3 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.0)) version: 0.3.3(vitest@3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.1))
packages: packages:
@ -441,8 +441,8 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@gerrit0/mini-shiki@3.8.1': '@gerrit0/mini-shiki@3.12.2':
resolution: {integrity: sha512-HVZW+8pxoOExr5ZMPK15U79jQAZTO/S6i5byQyyZGjtNj+qaYd82cizTncwFzTQgiLo8uUBym6vh+/1tfJklTw==} resolution: {integrity: sha512-HKZPmO8OSSAAo20H2B3xgJdxZaLTwtlMwxg0967scnrDlPwe6j5+ULGHyIqwgTbFCn9yv/ff8CmfWZLE9YKBzA==}
'@inquirer/checkbox@4.2.0': '@inquirer/checkbox@4.2.0':
resolution: {integrity: sha512-fdSw07FLJEU5vbpOPzXo5c6xmMGDzbZE2+niuDHX5N6mc6V0Ebso/q3xiHra4D73+PMsC8MJmcaZKuAAoaQsSA==} resolution: {integrity: sha512-fdSw07FLJEU5vbpOPzXo5c6xmMGDzbZE2+niuDHX5N6mc6V0Ebso/q3xiHra4D73+PMsC8MJmcaZKuAAoaQsSA==}
@ -712,17 +712,17 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@shikijs/engine-oniguruma@3.8.1': '@shikijs/engine-oniguruma@3.12.2':
resolution: {integrity: sha512-KGQJZHlNY7c656qPFEQpIoqOuC4LrxjyNndRdzk5WKB/Ie87+NJCF1xo9KkOUxwxylk7rT6nhlZyTGTC4fCe1g==} resolution: {integrity: sha512-hozwnFHsLvujK4/CPVHNo3Bcg2EsnG8krI/ZQ2FlBlCRpPZW4XAEQmEwqegJsypsTAN9ehu2tEYe30lYKSZW/w==}
'@shikijs/langs@3.8.1': '@shikijs/langs@3.12.2':
resolution: {integrity: sha512-TjOFg2Wp1w07oKnXjs0AUMb4kJvujML+fJ1C5cmEj45lhjbUXtziT1x2bPQb9Db6kmPhkG5NI2tgYW1/DzhUuQ==} resolution: {integrity: sha512-bVx5PfuZHDSHoBal+KzJZGheFuyH4qwwcwG/n+MsWno5cTlKmaNtTsGzJpHYQ8YPbB5BdEdKU1rga5/6JGY8ww==}
'@shikijs/themes@3.8.1': '@shikijs/themes@3.12.2':
resolution: {integrity: sha512-Vu3t3BBLifc0GB0UPg2Pox1naTemrrvyZv2lkiSw3QayVV60me1ujFQwPZGgUTmwXl1yhCPW8Lieesm0CYruLQ==} resolution: {integrity: sha512-fTR3QAgnwYpfGczpIbzPjlRnxyONJOerguQv1iwpyQZ9QXX4qy/XFQqXlf17XTsorxnHoJGbH/LXBvwtqDsF5A==}
'@shikijs/types@3.8.1': '@shikijs/types@3.12.2':
resolution: {integrity: sha512-5C39Q8/8r1I26suLh+5TPk1DTrbY/kn3IdWA5HdizR0FhlhD05zx5nKCqhzSfDHH3p4S0ZefxWd77DLV+8FhGg==} resolution: {integrity: sha512-K5UIBzxCyv0YoxN3LMrKB9zuhp1bV+LgewxuVwHdl4Gz5oePoUFrr9EfgJlGlDeXCU1b/yhdnXeuRvAnz8HN8Q==}
'@shikijs/vscode-textmate@10.0.2': '@shikijs/vscode-textmate@10.0.2':
resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
@ -1818,8 +1818,8 @@ packages:
peerDependencies: peerDependencies:
typedoc: 0.27.x || 0.28.x typedoc: 0.27.x || 0.28.x
typedoc@0.28.8: typedoc@0.28.7:
resolution: {integrity: sha512-16GfLopc8icHfdvqZDqdGBoS2AieIRP2rpf9mU+MgN+gGLyEQvAO0QgOa6NJ5QNmQi0LFrDY9in4F2fUNKgJKA==} resolution: {integrity: sha512-lpz0Oxl6aidFkmS90VQDQjk/Qf2iw0IUvFqirdONBdj7jPSN9mGXhy66BcGNDxx5ZMyKKiBVAREvPEzT6Uxipw==}
engines: {node: '>= 18', pnpm: '>= 10'} engines: {node: '>= 18', pnpm: '>= 10'}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -2020,8 +2020,8 @@ packages:
yallist@3.1.1: yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
yaml@2.8.0: yaml@2.8.1:
resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==}
engines: {node: '>= 14.6'} engines: {node: '>= 14.6'}
hasBin: true hasBin: true
@ -2300,12 +2300,12 @@ snapshots:
'@esbuild/win32-x64@0.25.8': '@esbuild/win32-x64@0.25.8':
optional: true optional: true
'@gerrit0/mini-shiki@3.8.1': '@gerrit0/mini-shiki@3.12.2':
dependencies: dependencies:
'@shikijs/engine-oniguruma': 3.8.1 '@shikijs/engine-oniguruma': 3.12.2
'@shikijs/langs': 3.8.1 '@shikijs/langs': 3.12.2
'@shikijs/themes': 3.8.1 '@shikijs/themes': 3.12.2
'@shikijs/types': 3.8.1 '@shikijs/types': 3.12.2
'@shikijs/vscode-textmate': 10.0.2 '@shikijs/vscode-textmate': 10.0.2
'@inquirer/checkbox@4.2.0(@types/node@22.16.5)': '@inquirer/checkbox@4.2.0(@types/node@22.16.5)':
@ -2534,20 +2534,20 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.46.1': '@rollup/rollup-win32-x64-msvc@4.46.1':
optional: true optional: true
'@shikijs/engine-oniguruma@3.8.1': '@shikijs/engine-oniguruma@3.12.2':
dependencies: dependencies:
'@shikijs/types': 3.8.1 '@shikijs/types': 3.12.2
'@shikijs/vscode-textmate': 10.0.2 '@shikijs/vscode-textmate': 10.0.2
'@shikijs/langs@3.8.1': '@shikijs/langs@3.12.2':
dependencies: dependencies:
'@shikijs/types': 3.8.1 '@shikijs/types': 3.12.2
'@shikijs/themes@3.8.1': '@shikijs/themes@3.12.2':
dependencies: dependencies:
'@shikijs/types': 3.8.1 '@shikijs/types': 3.12.2
'@shikijs/types@3.8.1': '@shikijs/types@3.12.2':
dependencies: dependencies:
'@shikijs/vscode-textmate': 10.0.2 '@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.4 '@types/hast': 3.0.4
@ -2586,7 +2586,7 @@ snapshots:
'@types/unist@3.0.3': {} '@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.0))': '@vitest/coverage-istanbul@3.2.4(vitest@3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.1))':
dependencies: dependencies:
'@istanbuljs/schema': 0.1.3 '@istanbuljs/schema': 0.1.3
debug: 4.4.1 debug: 4.4.1
@ -2598,7 +2598,7 @@ snapshots:
magicast: 0.3.5 magicast: 0.3.5
test-exclude: 7.0.1 test-exclude: 7.0.1
tinyrainbow: 2.0.0 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.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)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -2610,14 +2610,14 @@ snapshots:
chai: 5.2.1 chai: 5.2.1
tinyrainbow: 2.0.0 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.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))':
dependencies: dependencies:
'@vitest/spy': 3.2.4 '@vitest/spy': 3.2.4
estree-walker: 3.0.3 estree-walker: 3.0.3
magic-string: 0.30.17 magic-string: 0.30.17
optionalDependencies: 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.8.3)
vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.0) vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.1)
'@vitest/pretty-format@3.2.4': '@vitest/pretty-format@3.2.4':
dependencies: dependencies:
@ -3663,26 +3663,26 @@ snapshots:
type-fest@4.41.0: {} type-fest@4.41.0: {}
typedoc-github-theme@0.3.1(typedoc@0.28.8(typescript@5.8.3)): typedoc-github-theme@0.3.1(typedoc@0.28.7(typescript@5.8.3)):
dependencies: dependencies:
typedoc: 0.28.8(typescript@5.8.3) typedoc: 0.28.7(typescript@5.8.3)
typedoc-plugin-coverage@4.0.1(typedoc@0.28.8(typescript@5.8.3)): typedoc-plugin-coverage@4.0.1(typedoc@0.28.7(typescript@5.8.3)):
dependencies: dependencies:
typedoc: 0.28.8(typescript@5.8.3) typedoc: 0.28.7(typescript@5.8.3)
typedoc-plugin-mdn-links@5.0.9(typedoc@0.28.8(typescript@5.8.3)): typedoc-plugin-mdn-links@5.0.9(typedoc@0.28.7(typescript@5.8.3)):
dependencies: dependencies:
typedoc: 0.28.8(typescript@5.8.3) typedoc: 0.28.7(typescript@5.8.3)
typedoc@0.28.8(typescript@5.8.3): typedoc@0.28.7(typescript@5.8.3):
dependencies: dependencies:
'@gerrit0/mini-shiki': 3.8.1 '@gerrit0/mini-shiki': 3.12.2
lunr: 2.3.9 lunr: 2.3.9
markdown-it: 14.1.0 markdown-it: 14.1.0
minimatch: 9.0.5 minimatch: 9.0.5
typescript: 5.8.3 typescript: 5.8.3
yaml: 2.8.0 yaml: 2.8.1
typescript@5.8.3: {} typescript@5.8.3: {}
@ -3705,13 +3705,13 @@ snapshots:
util-deprecate@1.0.2: {} util-deprecate@1.0.2: {}
vite-node@3.2.4(@types/node@22.16.5)(yaml@2.8.0): vite-node@3.2.4(@types/node@22.16.5)(yaml@2.8.1):
dependencies: dependencies:
cac: 6.7.14 cac: 6.7.14
debug: 4.4.1 debug: 4.4.1
es-module-lexer: 1.7.0 es-module-lexer: 1.7.0
pathe: 2.0.3 pathe: 2.0.3
vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.0) vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.1)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/node' - '@types/node'
- jiti - jiti
@ -3726,18 +3726,18 @@ snapshots:
- tsx - tsx
- yaml - yaml
vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@7.0.6(@types/node@22.16.5)(yaml@2.8.0)): vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@7.0.6(@types/node@22.16.5)(yaml@2.8.1)):
dependencies: dependencies:
debug: 4.4.1 debug: 4.4.1
globrex: 0.1.2 globrex: 0.1.2
tsconfck: 3.1.6(typescript@5.8.3) tsconfck: 3.1.6(typescript@5.8.3)
optionalDependencies: optionalDependencies:
vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.0) vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
- typescript - typescript
vite@7.0.6(@types/node@22.16.5)(yaml@2.8.0): vite@7.0.6(@types/node@22.16.5)(yaml@2.8.1):
dependencies: dependencies:
esbuild: 0.25.8 esbuild: 0.25.8
fdir: 6.4.6(picomatch@4.0.3) fdir: 6.4.6(picomatch@4.0.3)
@ -3748,18 +3748,18 @@ snapshots:
optionalDependencies: optionalDependencies:
'@types/node': 22.16.5 '@types/node': 22.16.5
fsevents: 2.3.3 fsevents: 2.3.3
yaml: 2.8.0 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.0)): vitest-canvas-mock@0.3.3(vitest@3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.1)):
dependencies: dependencies:
jest-canvas-mock: 2.5.2 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.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.8.3))(yaml@2.8.0): vitest@3.2.4(@types/node@22.16.5)(jsdom@26.1.0)(msw@2.10.4(@types/node@22.16.5)(typescript@5.8.3))(yaml@2.8.1):
dependencies: dependencies:
'@types/chai': 5.2.2 '@types/chai': 5.2.2
'@vitest/expect': 3.2.4 '@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.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/pretty-format': 3.2.4 '@vitest/pretty-format': 3.2.4
'@vitest/runner': 3.2.4 '@vitest/runner': 3.2.4
'@vitest/snapshot': 3.2.4 '@vitest/snapshot': 3.2.4
@ -3777,8 +3777,8 @@ snapshots:
tinyglobby: 0.2.14 tinyglobby: 0.2.14
tinypool: 1.1.1 tinypool: 1.1.1
tinyrainbow: 2.0.0 tinyrainbow: 2.0.0
vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.0) vite: 7.0.6(@types/node@22.16.5)(yaml@2.8.1)
vite-node: 3.2.4(@types/node@22.16.5)(yaml@2.8.0) vite-node: 3.2.4(@types/node@22.16.5)(yaml@2.8.1)
why-is-node-running: 2.3.0 why-is-node-running: 2.3.0
optionalDependencies: optionalDependencies:
'@types/node': 22.16.5 '@types/node': 22.16.5
@ -3862,7 +3862,7 @@ snapshots:
yallist@3.1.1: {} yallist@3.1.1: {}
yaml@2.8.0: {} yaml@2.8.1: {}
yargs-parser@21.1.1: {} yargs-parser@21.1.1: {}

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

@ -1 +1 @@
Subproject commit 090bfefaf7e9d4efcbca61fa78a9cdf5d701830b Subproject commit 74de730a64272c8e9ca0a4cdcf3426cbf1b0aeda

View File

@ -1,7 +1,10 @@
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { BattlerIndex } from "#enums/battler-index";
import { MoveId } from "#enums/move-id"; import { MoveId } from "#enums/move-id";
import { MoveResult } from "#enums/move-result";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { GameManager } from "#test/test-utils/game-manager"; import { GameManager } from "#test/test-utils/game-manager";
import i18next from "i18next";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
@ -32,12 +35,18 @@ describe("{{description}}", () => {
.enemyLevel(100); .enemyLevel(100);
}); });
// Find more awesome utility functions inside `#test/test-utils`!
it("should do XYZ", async () => { it("should do XYZ", async () => {
await game.classicMode.startBattle([SpeciesId.FEEBAS]); await game.classicMode.startBattle([SpeciesId.FEEBAS]);
const feebas = game.field.getPlayerPokemon();
game.move.use(MoveId.SPLASH); game.move.use(MoveId.SPLASH);
await game.move.forceEnemyMove(MoveId.CELEBRATE);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
await game.toEndOfTurn(); await game.toEndOfTurn();
expect(true).toBe(true); expect(feebas).toHaveUsedMove({ move: MoveId.SPLASH, result: MoveResult.SUCCESS });
expect(game.textInterceptor.logs).toContain(i18next.t("moveTriggers:splash"));
}); });
}); });

View File

@ -1,4 +1,4 @@
import type { ScoreboardCategory } from "#ui/containers/daily-run-scoreboard"; import type { ScoreboardCategory } from "#ui/daily-run-scoreboard";
export interface GetDailyRankingsRequest { export interface GetDailyRankingsRequest {
category: ScoreboardCategory; category: ScoreboardCategory;

View File

@ -1,4 +1,4 @@
import type { SessionSaveData, SystemSaveData } from "#system/game-data"; import type { SessionSaveData, SystemSaveData } from "#types/save-data";
export interface UpdateAllSavedataRequest { export interface UpdateAllSavedataRequest {
system: SystemSaveData; system: SystemSaveData;

View File

@ -1,4 +1,4 @@
import type { SystemSaveData } from "#system/game-data"; import type { SystemSaveData } from "#types/save-data";
export interface GetSystemSavedataRequest { export interface GetSystemSavedataRequest {
clientSessionId: string; clientSessionId: string;

View File

@ -1,7 +1,7 @@
import type { ArenaTagTypeMap } from "#data/arena-tag"; import type { ArenaTagTypeMap } from "#data/arena-tag";
import type { ArenaTagType } from "#enums/arena-tag-type"; import type { ArenaTagType } from "#enums/arena-tag-type";
// biome-ignore lint/correctness/noUnusedImports: TSDocs // biome-ignore lint/correctness/noUnusedImports: TSDocs
import type { SessionSaveData } from "#system/game-data"; import type { SessionSaveData } from "#types/save-data";
import type { ObjectValues } from "#types/type-helpers"; import type { ObjectValues } from "#types/type-helpers";
/** Subset of {@linkcode ArenaTagType}s that apply some negative effect to pokemon that switch in ({@link https://bulbapedia.bulbagarden.net/wiki/List_of_moves_that_cause_entry_hazards#List_of_traps | entry hazards} and Imprison. */ /** Subset of {@linkcode ArenaTagType}s that apply some negative effect to pokemon that switch in ({@link https://bulbapedia.bulbagarden.net/wiki/List_of_moves_that_cause_entry_hazards#List_of_traps | entry hazards} and Imprison. */
@ -38,6 +38,7 @@ type SerializableArenaTagTypeMap = Pick<ArenaTagTypeMap, SerializableArenaTagTyp
/** /**
* Type mapping all `ArenaTag`s to type-safe representations of their serialized forms. * Type mapping all `ArenaTag`s to type-safe representations of their serialized forms.
*
* @interface * @interface
*/ */
export type ArenaTagDataMap = { export type ArenaTagDataMap = {

View File

@ -1,7 +1,7 @@
// biome-ignore-start lint/correctness/noUnusedImports: Used in a TSDoc comment // biome-ignore-start lint/correctness/noUnusedImports: Used in a TSDoc comment
import type { AbilityBattlerTag, BattlerTagTypeMap, SerializableBattlerTag, TypeBoostTag } from "#data/battler-tags"; import type { AbilityBattlerTag, BattlerTagTypeMap, SerializableBattlerTag, TypeBoostTag } from "#data/battler-tags";
import type { AbilityId } from "#enums/ability-id"; import type { AbilityId } from "#enums/ability-id";
import type { SessionSaveData } from "#system/game-data"; import type { SessionSaveData } from "#types/save-data";
// biome-ignore-end lint/correctness/noUnusedImports: Used in a TSDoc comment // biome-ignore-end lint/correctness/noUnusedImports: Used in a TSDoc comment
import type { BattlerTagType } from "#enums/battler-tag-type"; import type { BattlerTagType } from "#enums/battler-tag-type";

143
src/@types/save-data.ts Normal file
View File

@ -0,0 +1,143 @@
import type { PokeballCounts } from "#app/battle-scene";
import type { Tutorial } from "#app/tutorial";
import type { BattleType } from "#enums/battle-type";
import type { GameModes } from "#enums/game-modes";
import type { MoveId } from "#enums/move-id";
import type { MysteryEncounterType } from "#enums/mystery-encounter-type";
import type { PlayerGender } from "#enums/player-gender";
import type { PokemonType } from "#enums/pokemon-type";
import type { MysteryEncounterSaveData } from "#mystery-encounters/mystery-encounter-save-data";
import type { Variant } from "#sprites/variant";
import type { ArenaData } from "#system/arena-data";
import type { ChallengeData } from "#system/challenge-data";
import type { EggData } from "#system/egg-data";
import type { GameStats } from "#system/game-stats";
import type { ModifierData } from "#system/modifier-data";
import type { PokemonData } from "#system/pokemon-data";
import type { TrainerData } from "#system/trainer-data";
import type { DexData } from "./dex-data";
export interface SystemSaveData {
trainerId: number;
secretId: number;
gender: PlayerGender;
dexData: DexData;
starterData: StarterData;
gameStats: GameStats;
unlocks: Unlocks;
achvUnlocks: AchvUnlocks;
voucherUnlocks: VoucherUnlocks;
voucherCounts: VoucherCounts;
eggs: EggData[];
gameVersion: string;
timestamp: number;
eggPity: number[];
unlockPity: number[];
}
export interface SessionSaveData {
seed: string;
playTime: number;
gameMode: GameModes;
party: PokemonData[];
enemyParty: PokemonData[];
modifiers: ModifierData[];
enemyModifiers: ModifierData[];
arena: ArenaData;
pokeballCounts: PokeballCounts;
money: number;
score: number;
waveIndex: number;
battleType: BattleType;
trainer: TrainerData;
gameVersion: string;
/** The player-chosen name of the run */
name: string;
timestamp: number;
challenges: ChallengeData[];
mysteryEncounterType: MysteryEncounterType | -1; // Only defined when current wave is ME,
mysteryEncounterSaveData: MysteryEncounterSaveData;
/**
* Counts the amount of pokemon fainted in your party during the current arena encounter.
*/
playerFaints: number;
}
export interface Unlocks {
[key: number]: boolean;
}
export interface AchvUnlocks {
[key: string]: number;
}
export interface VoucherUnlocks {
[key: string]: number;
}
export interface VoucherCounts {
[type: string]: number;
}
export type StarterMoveset = [MoveId] | [MoveId, MoveId] | [MoveId, MoveId, MoveId] | [MoveId, MoveId, MoveId, MoveId];
export interface StarterFormMoveData {
[key: number]: StarterMoveset;
}
export interface StarterMoveData {
[key: number]: StarterMoveset | StarterFormMoveData;
}
export interface StarterAttributes {
nature?: number;
ability?: number;
variant?: number;
form?: number;
female?: boolean;
shiny?: boolean;
favorite?: boolean;
nickname?: string;
tera?: PokemonType;
}
export interface DexAttrProps {
shiny: boolean;
female: boolean;
variant: Variant;
formIndex: number;
}
export type RunHistoryData = Record<number, RunEntry>;
export interface RunEntry {
entry: SessionSaveData;
isVictory: boolean;
/*Automatically set to false at the moment - implementation TBD*/
isFavorite: boolean;
}
export interface StarterDataEntry {
moveset: StarterMoveset | StarterFormMoveData | null;
eggMoves: number;
candyCount: number;
friendship: number;
abilityAttr: number;
passiveAttr: number;
valueReduction: number;
classicWinCount: number;
}
export interface StarterData {
[key: number]: StarterDataEntry;
}
// TODO: Rework into a bitmask
export type TutorialFlags = {
[key in Tutorial]: boolean;
};
// TODO: Rework into a bitmask
export interface SeenDialogues {
[key: string]: boolean;
}

View File

@ -1,4 +1,4 @@
import type { SessionSaveData } from "#system/game-data"; import type { SessionSaveData } from "./save-data";
export interface SessionSaveMigrator { export interface SessionSaveMigrator {
version: string; version: string;

View File

@ -1,4 +1,4 @@
import type { SystemSaveData } from "#system/game-data"; import type { SystemSaveData } from "./save-data";
export interface SystemSaveMigrator { export interface SystemSaveMigrator {
version: string; version: string;

View File

@ -121,13 +121,13 @@ import { vouchers } from "#system/voucher";
import { trainerConfigs } from "#trainers/trainer-config"; import { trainerConfigs } from "#trainers/trainer-config";
import type { HeldModifierConfig } from "#types/held-modifier-config"; import type { HeldModifierConfig } from "#types/held-modifier-config";
import type { Localizable } from "#types/locales"; import type { Localizable } from "#types/locales";
import { AbilityBar } from "#ui/containers/ability-bar"; import { AbilityBar } from "#ui/ability-bar";
import { ArenaFlyout } from "#ui/containers/arena-flyout"; import { ArenaFlyout } from "#ui/arena-flyout";
import { CandyBar } from "#ui/containers/candy-bar"; import { CandyBar } from "#ui/candy-bar";
import { CharSprite } from "#ui/containers/char-sprite"; import { CharSprite } from "#ui/char-sprite";
import { PartyExpBar } from "#ui/containers/party-exp-bar"; import { PartyExpBar } from "#ui/party-exp-bar";
import { PokeballTray } from "#ui/containers/pokeball-tray"; import { PokeballTray } from "#ui/pokeball-tray";
import { PokemonInfoContainer } from "#ui/containers/pokemon-info-container"; import { PokemonInfoContainer } from "#ui/pokemon-info-container";
import { addTextObject, getTextColor } from "#ui/text"; import { addTextObject, getTextColor } from "#ui/text";
import { UI } from "#ui/ui"; import { UI } from "#ui/ui";
import { addUiThemeOverrides } from "#ui/ui-theme"; import { addUiThemeOverrides } from "#ui/ui-theme";
@ -3108,7 +3108,7 @@ export class BattleScene extends SceneBase {
* Apply all modifiers that match `modifierType` in a random order * Apply all modifiers that match `modifierType` in a random order
* @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier} * @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier}
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true` * @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
* @param ...args The list of arguments needed to invoke `modifierType.apply` * @param args The list of arguments needed to invoke `modifierType.apply`
* @returns the list of all modifiers that matched `modifierType` and were applied. * @returns the list of all modifiers that matched `modifierType` and were applied.
*/ */
applyShuffledModifiers<T extends PersistentModifier>( applyShuffledModifiers<T extends PersistentModifier>(
@ -3140,7 +3140,7 @@ export class BattleScene extends SceneBase {
* Apply all modifiers that match `modifierType` * Apply all modifiers that match `modifierType`
* @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier} * @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier}
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true` * @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
* @param ...args The list of arguments needed to invoke `modifierType.apply` * @param args The list of arguments needed to invoke `modifierType.apply`
* @returns the list of all modifiers that matched `modifierType` and were applied. * @returns the list of all modifiers that matched `modifierType` and were applied.
*/ */
applyModifiers<T extends PersistentModifier>( applyModifiers<T extends PersistentModifier>(
@ -3175,7 +3175,7 @@ export class BattleScene extends SceneBase {
* Apply the first modifier that matches `modifierType` * Apply the first modifier that matches `modifierType`
* @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier} * @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier}
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true` * @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
* @param ...args The list of arguments needed to invoke `modifierType.apply` * @param args The list of arguments needed to invoke `modifierType.apply`
* @returns the first modifier that matches `modifierType` and was applied; return `null` if none matched * @returns the first modifier that matches `modifierType` and was applied; return `null` if none matched
*/ */
applyModifier<T extends PersistentModifier>( applyModifier<T extends PersistentModifier>(
@ -3323,7 +3323,7 @@ export class BattleScene extends SceneBase {
/** /**
* This function retrieves the sprite and audio keys for active Pokemon. * This function retrieves the sprite and audio keys for active Pokemon.
* Active Pokemon include both enemy and player Pokemon of the current wave. * Active Pokemon include both enemy and player Pokemon of the current wave.
* Note: Questions on garbage collection go to @frutescens * Note: Questions on garbage collection go to `@frutescens`
* @returns a string array of active sprite and audio keys that should not be deleted * @returns a string array of active sprite and audio keys that should not be deleted
*/ */
getActiveKeys(): string[] { getActiveKeys(): string[] {

View File

@ -510,7 +510,7 @@ export class ClearWeatherAbAttr extends AbAttr {
private weather: WeatherType[]; private weather: WeatherType[];
/** /**
* @param weather {@linkcode WeatherType[]} - the weather to be removed * @param weather - The weather to be removed
*/ */
constructor(weather: WeatherType[]) { constructor(weather: WeatherType[]) {
super(true); super(true);
@ -540,7 +540,7 @@ export class ClearTerrainAbAttr extends AbAttr {
private terrain: TerrainType[]; private terrain: TerrainType[];
/** /**
* @param terrain {@linkcode TerrainType[]} - the terrain to be removed * @param terrain - the terrain to be removed
*/ */
constructor(terrain: TerrainType[]) { constructor(terrain: TerrainType[]) {
super(true); super(true);
@ -658,7 +658,6 @@ export class ReceivedMoveDamageMultiplierAbAttr extends PreDefendAbAttr {
/** /**
* Reduces the damage dealt to an allied Pokemon. Used by Friend Guard. * Reduces the damage dealt to an allied Pokemon. Used by Friend Guard.
* @see {@linkcode applyPreDefend}
*/ */
export class AlliedFieldDamageReductionAbAttr extends PreDefendAbAttr { export class AlliedFieldDamageReductionAbAttr extends PreDefendAbAttr {
private damageMultiplier: number; private damageMultiplier: number;
@ -694,8 +693,6 @@ export interface TypeMultiplierAbAttrParams extends AugmentMoveInteractionAbAttr
/** /**
* Determines whether a Pokemon is immune to a move because of an ability. * Determines whether a Pokemon is immune to a move because of an ability.
* @see {@linkcode applyPreDefend}
* @see {@linkcode getCondition}
*/ */
export class TypeImmunityAbAttr extends PreDefendAbAttr { export class TypeImmunityAbAttr extends PreDefendAbAttr {
private immuneType: PokemonType | null; private immuneType: PokemonType | null;
@ -845,7 +842,6 @@ export class NonSuperEffectiveImmunityAbAttr extends TypeImmunityAbAttr {
/** /**
* Attribute implementing the effects of {@link https://bulbapedia.bulbagarden.net/wiki/Tera_Shell_(Ability) | Tera Shell} * Attribute implementing the effects of {@link https://bulbapedia.bulbagarden.net/wiki/Tera_Shell_(Ability) | Tera Shell}
* When the source is at full HP, incoming attacks will have a maximum 0.5x type effectiveness multiplier. * When the source is at full HP, incoming attacks will have a maximum 0.5x type effectiveness multiplier.
* @extends PreDefendAbAttr
*/ */
export class FullHpResistTypeAbAttr extends PreDefendAbAttr { export class FullHpResistTypeAbAttr extends PreDefendAbAttr {
/** /**
@ -1354,11 +1350,9 @@ export class PostDefendContactDamageAbAttr extends PostDefendAbAttr {
} }
} }
/** /**
* @description: This ability applies the Perish Song tag to the attacking pokemon * This ability applies the Perish Song tag to the attacking pokemon
* and the defending pokemon if the move makes physical contact and neither pokemon * and the defending pokemon if the move makes physical contact and neither pokemon
* already has the Perish Song tag. * already has the Perish Song tag.
* @class PostDefendPerishSongAbAttr
* @extends {PostDefendAbAttr}
*/ */
export class PostDefendPerishSongAbAttr extends PostDefendAbAttr { export class PostDefendPerishSongAbAttr extends PostDefendAbAttr {
private turns: number; private turns: number;
@ -1964,19 +1958,16 @@ export class PreAttackFieldMoveTypePowerBoostAbAttr extends FieldMovePowerBoostA
/** /**
* Boosts the power of a specific type of move for all Pokemon in the field. * Boosts the power of a specific type of move for all Pokemon in the field.
* @extends PreAttackFieldMoveTypePowerBoostAbAttr
*/ */
export class FieldMoveTypePowerBoostAbAttr extends PreAttackFieldMoveTypePowerBoostAbAttr {} export class FieldMoveTypePowerBoostAbAttr extends PreAttackFieldMoveTypePowerBoostAbAttr {}
/** /**
* Boosts the power of a specific type of move for the user and its allies. * Boosts the power of a specific type of move for the user and its allies.
* @extends PreAttackFieldMoveTypePowerBoostAbAttr
*/ */
export class UserFieldMoveTypePowerBoostAbAttr extends PreAttackFieldMoveTypePowerBoostAbAttr {} export class UserFieldMoveTypePowerBoostAbAttr extends PreAttackFieldMoveTypePowerBoostAbAttr {}
/** /**
* Boosts the power of moves in specified categories. * Boosts the power of moves in specified categories.
* @extends FieldMovePowerBoostAbAttr
*/ */
export class AllyMoveCategoryPowerBoostAbAttr extends FieldMovePowerBoostAbAttr { export class AllyMoveCategoryPowerBoostAbAttr extends FieldMovePowerBoostAbAttr {
/** /**
@ -2582,7 +2573,6 @@ export class PostIntimidateStatStageChangeAbAttr extends AbAttr {
/** /**
* Base class for defining all {@linkcode Ability} Attributes post summon * Base class for defining all {@linkcode Ability} Attributes post summon
* @see {@linkcode applyPostSummon()}
*/ */
export abstract class PostSummonAbAttr extends AbAttr { export abstract class PostSummonAbAttr extends AbAttr {
/** Should the ability activate when gained in battle? This will almost always be true */ /** Should the ability activate when gained in battle? This will almost always be true */
@ -2622,7 +2612,7 @@ export class PostSummonRemoveArenaTagAbAttr extends PostSummonAbAttr {
private arenaTags: ArenaTagType[]; private arenaTags: ArenaTagType[];
/** /**
* @param arenaTags {@linkcode ArenaTagType[]} - the arena tags to be removed * @param arenaTags - The arena tags to be removed
*/ */
constructor(arenaTags: ArenaTagType[]) { constructor(arenaTags: ArenaTagType[]) {
super(true); super(true);
@ -3183,7 +3173,6 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
/** /**
* Reverts weather-based forms to their normal forms when the user is summoned. * Reverts weather-based forms to their normal forms when the user is summoned.
* Used by Cloud Nine and Air Lock. * Used by Cloud Nine and Air Lock.
* @extends PostSummonAbAttr
*/ */
export class PostSummonWeatherSuppressedFormChangeAbAttr extends PostSummonAbAttr { export class PostSummonWeatherSuppressedFormChangeAbAttr extends PostSummonAbAttr {
override canApply(_params: AbAttrBaseParams): boolean { override canApply(_params: AbAttrBaseParams): boolean {
@ -3203,7 +3192,6 @@ export class PostSummonWeatherSuppressedFormChangeAbAttr extends PostSummonAbAtt
/** /**
* Triggers weather-based form change when summoned into an active weather. * Triggers weather-based form change when summoned into an active weather.
* Used by Forecast and Flower Gift. * Used by Forecast and Flower Gift.
* @extends PostSummonAbAttr
*/ */
export class PostSummonFormChangeByWeatherAbAttr extends PostSummonAbAttr { export class PostSummonFormChangeByWeatherAbAttr extends PostSummonAbAttr {
private ability: AbilityId; private ability: AbilityId;
@ -3385,7 +3373,6 @@ export class PreSwitchOutHealAbAttr extends PreSwitchOutAbAttr {
/** /**
* Attribute for form changes that occur on switching out * Attribute for form changes that occur on switching out
* @see {@linkcode applyPreSwitchOut}
*/ */
export class PreSwitchOutFormChangeAbAttr extends PreSwitchOutAbAttr { export class PreSwitchOutFormChangeAbAttr extends PreSwitchOutAbAttr {
private formFunc: (p: Pokemon) => number; private formFunc: (p: Pokemon) => number;
@ -4252,8 +4239,8 @@ function getAnticipationCondition(): AbAttrCondition {
* Creates an ability condition that causes the ability to fail if that ability * Creates an ability condition that causes the ability to fail if that ability
* has already been used by that pokemon that battle. It requires an ability to * has already been used by that pokemon that battle. It requires an ability to
* be specified due to current limitations in how conditions on abilities work. * be specified due to current limitations in how conditions on abilities work.
* @param {AbilityId} ability The ability to check if it's already been applied * @param ability The ability to check if it's already been applied
* @returns {AbAttrCondition} The condition * @returns The condition
*/ */
function getOncePerBattleCondition(ability: AbilityId): AbAttrCondition { function getOncePerBattleCondition(ability: AbilityId): AbAttrCondition {
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
@ -4644,7 +4631,7 @@ export class PostTurnRestoreBerryAbAttr extends PostTurnAbAttr {
/** /**
* @param procChance - function providing chance to restore an item * @param procChance - function providing chance to restore an item
* @see {@linkcode createEatenBerry()} * @see {@linkcode createEatenBerry}
*/ */
constructor(private procChance: (pokemon: Pokemon) => number) { constructor(private procChance: (pokemon: Pokemon) => number) {
super(); super();
@ -4909,7 +4896,6 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr {
/** /**
* Grabs the last failed Pokeball used * Grabs the last failed Pokeball used
* @sealed * @sealed
* @see {@linkcode applyPostTurn}
*/ */
export class FetchBallAbAttr extends PostTurnAbAttr { export class FetchBallAbAttr extends PostTurnAbAttr {
override canApply({ simulated, pokemon }: AbAttrBaseParams): boolean { override canApply({ simulated, pokemon }: AbAttrBaseParams): boolean {
@ -4999,7 +4985,6 @@ export class PostMoveUsedAbAttr extends AbAttr {
/** /**
* Triggers after a dance move is used either by the opponent or the player * Triggers after a dance move is used either by the opponent or the player
* @extends PostMoveUsedAbAttr
*/ */
export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr { export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
override canApply({ source, pokemon }: PostMoveUsedAbAttrParams): boolean { override canApply({ source, pokemon }: PostMoveUsedAbAttrParams): boolean {
@ -5058,7 +5043,6 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
/** /**
* Triggers after the Pokemon loses or consumes an item * Triggers after the Pokemon loses or consumes an item
* @extends AbAttr
*/ */
export class PostItemLostAbAttr extends AbAttr { export class PostItemLostAbAttr extends AbAttr {
canApply(_params: Closed<AbAttrBaseParams>): boolean { canApply(_params: Closed<AbAttrBaseParams>): boolean {
@ -5229,7 +5213,6 @@ type ArenaTrapCondition = (user: Pokemon, target: Pokemon) => boolean;
/** /**
* Base class for checking if a Pokemon is trapped by arena trap * Base class for checking if a Pokemon is trapped by arena trap
* @extends AbAttr
* @field {@linkcode arenaTrapCondition} Conditional for trapping abilities. * @field {@linkcode arenaTrapCondition} Conditional for trapping abilities.
* For example, Magnet Pull will only activate if opponent is Steel type. * For example, Magnet Pull will only activate if opponent is Steel type.
* @see {@linkcode applyCheckTrapped} * @see {@linkcode applyCheckTrapped}
@ -5565,7 +5548,6 @@ export interface ReduceStatusEffectDurationAbAttrParams extends AbAttrBaseParams
/** /**
* Used by Early Bird, makes the pokemon wake up faster * Used by Early Bird, makes the pokemon wake up faster
* @param statusEffect - The {@linkcode StatusEffect} to check for * @param statusEffect - The {@linkcode StatusEffect} to check for
* @see {@linkcode apply}
* @sealed * @sealed
*/ */
export class ReduceStatusEffectDurationAbAttr extends AbAttr { export class ReduceStatusEffectDurationAbAttr extends AbAttr {
@ -5861,8 +5843,6 @@ export class IgnoreTypeStatusEffectImmunityAbAttr extends AbAttr {
/** /**
* Gives money to the user after the battle. * Gives money to the user after the battle.
*
* @extends PostBattleAbAttr
*/ */
export class MoneyAbAttr extends PostBattleAbAttr { export class MoneyAbAttr extends PostBattleAbAttr {
override canApply({ simulated, victory }: PostBattleAbAttrParams): boolean { override canApply({ simulated, victory }: PostBattleAbAttrParams): boolean {
@ -5966,7 +5946,6 @@ export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
/** /**
* Base class for defining {@linkcode Ability} attributes before summon * Base class for defining {@linkcode Ability} attributes before summon
* (should use {@linkcode PostSummonAbAttr} for most ability) * (should use {@linkcode PostSummonAbAttr} for most ability)
* @see {@linkcode applyPreSummon()}
*/ */
export class PreSummonAbAttr extends AbAttr { export class PreSummonAbAttr extends AbAttr {
private declare readonly _: never; private declare readonly _: never;
@ -6418,8 +6397,6 @@ export class PostDamageAbAttr extends AbAttr {
* and its opponents, and determines whether a forced switch-out should occur. * and its opponents, and determines whether a forced switch-out should occur.
* *
* Used by Wimp Out and Emergency Exit * Used by Wimp Out and Emergency Exit
*
* @see {@linkcode applyPostDamage}
* @sealed * @sealed
*/ */
export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr { export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr {
@ -7038,6 +7015,7 @@ export function initAbilities() {
.attr(StatMultiplierAbAttr, Stat.SPATK, 1.5) .attr(StatMultiplierAbAttr, Stat.SPATK, 1.5)
.condition(getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN)), .condition(getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN)),
new Ability(AbilityId.QUICK_FEET, 4) new Ability(AbilityId.QUICK_FEET, 4)
// TODO: This should ignore the speed drop, not manually undo it
.conditionalAttr(pokemon => pokemon.status ? pokemon.status.effect === StatusEffect.PARALYSIS : false, StatMultiplierAbAttr, Stat.SPD, 2) .conditionalAttr(pokemon => pokemon.status ? pokemon.status.effect === StatusEffect.PARALYSIS : false, StatMultiplierAbAttr, Stat.SPD, 2)
.conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(AbilityId.COMATOSE), StatMultiplierAbAttr, Stat.SPD, 1.5), .conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(AbilityId.COMATOSE), StatMultiplierAbAttr, Stat.SPD, 1.5),
new Ability(AbilityId.NORMALIZE, 4) new Ability(AbilityId.NORMALIZE, 4)

View File

@ -1132,7 +1132,7 @@ class ImprisonTag extends EntryHazardTag {
/** /**
* This applies the effects of Imprison to any opposing Pokemon that switch into the field while the source Pokemon is still active * This applies the effects of Imprison to any opposing Pokemon that switch into the field while the source Pokemon is still active
* @param {Pokemon} pokemon the Pokemon Imprison is applied to * @param pokemon the Pokemon Imprison is applied to
* @returns `true` * @returns `true`
*/ */
override activateTrap(pokemon: Pokemon): boolean { override activateTrap(pokemon: Pokemon): boolean {

View File

@ -2192,7 +2192,7 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
null, null,
false, false,
null, null,
true, false,
); );
} }
@ -2507,10 +2507,7 @@ export class RemovedTypeTag extends SerializableBattlerTag {
} }
} }
/** /** Battler tag for effects that ground the source, allowing Ground-type moves to hit them. */
* Battler tag for effects that ground the source, allowing Ground-type moves to hit them.
* @description `IGNORE_FLYING`: Persistent grounding effects (i.e. from Smack Down and Thousand Waves)
*/
export class GroundedTag extends SerializableBattlerTag { export class GroundedTag extends SerializableBattlerTag {
public override readonly tagType = BattlerTagType.IGNORE_FLYING; public override readonly tagType = BattlerTagType.IGNORE_FLYING;
constructor(tagType: BattlerTagType.IGNORE_FLYING, lapseType: BattlerTagLapseType, sourceMove: MoveId) { constructor(tagType: BattlerTagType.IGNORE_FLYING, lapseType: BattlerTagLapseType, sourceMove: MoveId) {
@ -2518,11 +2515,7 @@ export class GroundedTag extends SerializableBattlerTag {
} }
} }
/** /** Removes flying type from a pokemon for a single turn */
* @description `ROOSTED`: Tag for temporary grounding if only source of ungrounding is flying and pokemon uses Roost.
* Roost removes flying type from a pokemon for a single turn.
*/
export class RoostedTag extends BattlerTag { export class RoostedTag extends BattlerTag {
private isBaseFlying: boolean; private isBaseFlying: boolean;
private isBasePureFlying: boolean; private isBasePureFlying: boolean;
@ -2601,7 +2594,7 @@ export class FormBlockDamageTag extends SerializableBattlerTag {
/** /**
* Applies the tag to the Pokémon. * Applies the tag to the Pokémon.
* Triggers a form change if the Pokémon is not in its defense form. * Triggers a form change if the Pokémon is not in its defense form.
* @param {Pokemon} pokemon The Pokémon to which the tag is added. * @param pokemon The Pokémon to which the tag is added.
*/ */
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);

View File

@ -1,5 +1,6 @@
import type { FixedBattleConfig } from "#app/battle"; import type { FixedBattleConfig } from "#app/battle";
import { getRandomTrainerFunc } from "#app/battle"; import { getRandomTrainerFunc } from "#app/battle";
import { globalScene } from "#app/global-scene";
import { defaultStarterSpeciesAndEvolutions } from "#balance/pokemon-evolutions"; import { defaultStarterSpeciesAndEvolutions } from "#balance/pokemon-evolutions";
import { speciesStarterCosts } from "#balance/starters"; import { speciesStarterCosts } from "#balance/starters";
import type { PokemonSpecies } from "#data/pokemon-species"; 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 { ModifierTier } from "#enums/modifier-tier";
import { MoveId } from "#enums/move-id"; import { MoveId } from "#enums/move-id";
import type { MoveSourceType } from "#enums/move-source-type"; import type { MoveSourceType } from "#enums/move-source-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { Nature } from "#enums/nature"; import { Nature } from "#enums/nature";
import { PokemonType } from "#enums/pokemon-type"; import { PokemonType } from "#enums/pokemon-type";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
@ -21,9 +23,10 @@ import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
import { Trainer } from "#field/trainer"; import { Trainer } from "#field/trainer";
import type { ModifierTypeOption } from "#modifiers/modifier-type"; import type { ModifierTypeOption } from "#modifiers/modifier-type";
import { PokemonMove } from "#moves/pokemon-move"; import { PokemonMove } from "#moves/pokemon-move";
import type { DexAttrProps, GameData, StarterDataEntry } from "#system/game-data"; import type { GameData } from "#system/game-data";
import { RibbonData, type RibbonFlag } from "#system/ribbons/ribbon-data"; import { RibbonData, type RibbonFlag } from "#system/ribbons/ribbon-data";
import type { DexEntry } from "#types/dex-data"; import type { DexEntry } from "#types/dex-data";
import type { DexAttrProps, StarterDataEntry } from "#types/save-data";
import { type BooleanHolder, isBetween, type NumberHolder, randSeedItem } from "#utils/common"; import { type BooleanHolder, isBetween, type NumberHolder, randSeedItem } from "#utils/common";
import { deepCopy } from "#utils/data"; import { deepCopy } from "#utils/data";
import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils";
@ -56,7 +59,7 @@ export abstract class Challenge {
} }
/** /**
* @param id {@link Challenges} The enum value for the challenge * @param id - The enum value for the challenge
*/ */
constructor(id: Challenges, maxValue: number = Number.MAX_SAFE_INTEGER) { constructor(id: Challenges, maxValue: number = Number.MAX_SAFE_INTEGER) {
this.id = id; this.id = id;
@ -85,9 +88,9 @@ export abstract class Challenge {
} }
/** /**
* Used for unlockable challenges to check if they're unlocked. * Check if an unlockable challenge is unlocked
* @param data {@link GameData} The save data. * @param data - The save data
* @returns {@link boolean} Whether this challenge is unlocked. * @returns Whether this challenge is unlocked
*/ */
isUnlocked(data: GameData): boolean { isUnlocked(data: GameData): boolean {
return this.conditions.every(f => f(data)); return this.conditions.every(f => f(data));
@ -95,8 +98,8 @@ export abstract class Challenge {
/** /**
* Adds an unlock condition to this challenge. * Adds an unlock condition to this challenge.
* @param condition {@link ChallengeCondition} The condition to add. * @param condition - The condition to add
* @returns {@link Challenge} This challenge * @returns This challenge
*/ */
condition(condition: ChallengeCondition): Challenge { condition(condition: ChallengeCondition): Challenge {
this.conditions.push(condition); this.conditions.push(condition);
@ -105,7 +108,7 @@ export abstract class Challenge {
} }
/** /**
* @returns {@link string} The localised name of this challenge. * @returns The localised name of this challenge.
*/ */
getName(): string { getName(): string {
return i18next.t(`challenges:${this.geti18nKey()}.name`); return i18next.t(`challenges:${this.geti18nKey()}.name`);
@ -132,7 +135,7 @@ export abstract class Challenge {
/** /**
* Increase the value of the challenge * Increase the value of the challenge
* @returns {@link boolean} Returns true if the value changed * @returns Returns true if the value changed
*/ */
increaseValue(): boolean { increaseValue(): boolean {
if (this.value < this.maxValue) { if (this.value < this.maxValue) {
@ -144,7 +147,7 @@ export abstract class Challenge {
/** /**
* Decrease the value of the challenge * Decrease the value of the challenge
* @returns {@link boolean} Returns true if the value changed * @returns Returns true if the value changed
*/ */
decreaseValue(): boolean { decreaseValue(): boolean {
if (this.value > 0) { if (this.value > 0) {
@ -163,7 +166,7 @@ export abstract class Challenge {
/** /**
* Decrease the severity of the challenge * Decrease the severity of the challenge
* @returns {@link boolean} Returns true if the value changed * @returns Returns true if the value changed
*/ */
decreaseSeverity(): boolean { decreaseSeverity(): boolean {
if (this.severity > 0) { if (this.severity > 0) {
@ -175,7 +178,7 @@ export abstract class Challenge {
/** /**
* Increase the severity of the challenge * Increase the severity of the challenge
* @returns {@link boolean} Returns true if the value changed * @returns Returns true if the value changed
*/ */
increaseSeverity(): boolean { increaseSeverity(): boolean {
if (this.severity < this.maxSeverity) { if (this.severity < this.maxSeverity) {
@ -187,7 +190,7 @@ export abstract class Challenge {
/** /**
* Gets the "difficulty" value of this challenge. * Gets the "difficulty" value of this challenge.
* @returns {@link integer} The difficulty value. * @returns The difficulty value.
*/ */
getDifficulty(): number { getDifficulty(): number {
return this.value; return this.value;
@ -195,7 +198,7 @@ export abstract class Challenge {
/** /**
* Gets the minimum difficulty added by this challenge. * Gets the minimum difficulty added by this challenge.
* @returns {@link integer} The difficulty value. * @returns The difficulty value.
*/ */
getMinDifficulty(): number { getMinDifficulty(): number {
return 0; return 0;
@ -203,7 +206,7 @@ export abstract class Challenge {
/** /**
* Clones a challenge, either from another challenge or json. Chainable. * Clones a challenge, either from another challenge or json. Chainable.
* @param source The source challenge or json. * @param _source - The source challenge or json.
* @returns This challenge. * @returns This challenge.
*/ */
static loadChallenge(_source: Challenge | any): Challenge { static loadChallenge(_source: Challenge | any): Challenge {
@ -212,10 +215,10 @@ export abstract class Challenge {
/** /**
* An apply function for STARTER_CHOICE challenges. Derived classes should alter this. * An apply function for STARTER_CHOICE challenges. Derived classes should alter this.
* @param _pokemon {@link PokemonSpecies} The pokemon to check the validity of. * @param _pokemon - The Pokémon to check the validity of
* @param _valid {@link BooleanHolder} A BooleanHolder, the value gets set to false if the pokemon isn't allowed. * @param _valid - Holder for whether the Pokémon is valid or not
* @param _dexAttr {@link DexAttrProps} The dex attributes of the pokemon. * @param _dexAttr - The dex attributes of the Pokémon
* @returns {@link boolean} Whether this function did anything. * @returns Whether this function did anything.
*/ */
applyStarterChoice(_pokemon: PokemonSpecies, _valid: BooleanHolder, _dexAttr: DexAttrProps): boolean { applyStarterChoice(_pokemon: PokemonSpecies, _valid: BooleanHolder, _dexAttr: DexAttrProps): boolean {
return false; return false;
@ -223,8 +226,8 @@ export abstract class Challenge {
/** /**
* An apply function for STARTER_POINTS challenges. Derived classes should alter this. * An apply function for STARTER_POINTS challenges. Derived classes should alter this.
* @param _points {@link NumberHolder} The amount of points you have available. * @param _points - Holder for amount of starter points the user has to spend
* @returns {@link boolean} Whether this function did anything. * @returns Whether this function did anything
*/ */
applyStarterPoints(_points: NumberHolder): boolean { applyStarterPoints(_points: NumberHolder): boolean {
return false; return false;
@ -232,9 +235,9 @@ export abstract class Challenge {
/** /**
* An apply function for STARTER_COST challenges. Derived classes should alter this. * An apply function for STARTER_COST challenges. Derived classes should alter this.
* @param _species {@link SpeciesId} The pokemon to change the cost of. * @param _species - The pokémon to change the cost of
* @param _cost {@link NumberHolder} The cost of the starter. * @param _cost - Holder for the cost of the starter Pokémon
* @returns {@link boolean} Whether this function did anything. * @returns Whether this function did anything.
*/ */
applyStarterCost(_species: SpeciesId, _cost: NumberHolder): boolean { applyStarterCost(_species: SpeciesId, _cost: NumberHolder): boolean {
return false; return false;
@ -242,8 +245,8 @@ export abstract class Challenge {
/** /**
* An apply function for STARTER_SELECT_MODIFY challenges. Derived classes should alter this. * An apply function for STARTER_SELECT_MODIFY challenges. Derived classes should alter this.
* @param _pokemon {@link Pokemon} The starter pokemon to modify. * @param _pokemon - The starter Pokémon to modify.
* @returns {@link boolean} Whether this function did anything. * @returns Whether this function did anything.
*/ */
applyStarterSelectModify(_speciesId: SpeciesId, _dexEntry: DexEntry, _starterDataEntry: StarterDataEntry): boolean { applyStarterSelectModify(_speciesId: SpeciesId, _dexEntry: DexEntry, _starterDataEntry: StarterDataEntry): boolean {
return false; return false;
@ -251,8 +254,8 @@ export abstract class Challenge {
/** /**
* An apply function for STARTER_MODIFY challenges. Derived classes should alter this. * An apply function for STARTER_MODIFY challenges. Derived classes should alter this.
* @param _pokemon {@link Pokemon} The starter pokemon to modify. * @param _pokemon - The starter Pokémon to modify.
* @returns {@link boolean} Whether this function did anything. * @returns Whether this function did anything.
*/ */
applyStarterModify(_pokemon: Pokemon): boolean { applyStarterModify(_pokemon: Pokemon): boolean {
return false; return false;
@ -260,9 +263,9 @@ export abstract class Challenge {
/** /**
* An apply function for POKEMON_IN_BATTLE challenges. Derived classes should alter this. * An apply function for POKEMON_IN_BATTLE challenges. Derived classes should alter this.
* @param _pokemon {@link Pokemon} The pokemon to check the validity of. * @param _pokemon - The Pokémon to check the validity of
* @param _valid {@link BooleanHolder} A BooleanHolder, the value gets set to false if the pokemon isn't allowed. * @param _valid - Holds a boolean that will be set to false if the Pokémon isn't allowed
* @returns {@link boolean} Whether this function did anything. * @returns Whether this function did anything
*/ */
applyPokemonInBattle(_pokemon: Pokemon, _valid: BooleanHolder): boolean { applyPokemonInBattle(_pokemon: Pokemon, _valid: BooleanHolder): boolean {
return false; return false;
@ -270,9 +273,9 @@ export abstract class Challenge {
/** /**
* An apply function for FIXED_BATTLE challenges. Derived classes should alter this. * An apply function for FIXED_BATTLE challenges. Derived classes should alter this.
* @param _waveIndex {@link Number} The current wave index. * @param _waveIndex The current wave index
* @param _battleConfig {@link FixedBattleConfig} The battle config to modify. * @param _battleConfig - The battle config to modify
* @returns {@link boolean} Whether this function did anything. * @returns Whether this function did anything
*/ */
applyFixedBattle(_waveIndex: number, _battleConfig: FixedBattleConfig): boolean { applyFixedBattle(_waveIndex: number, _battleConfig: FixedBattleConfig): boolean {
return false; return false;
@ -280,8 +283,8 @@ export abstract class Challenge {
/** /**
* An apply function for TYPE_EFFECTIVENESS challenges. Derived classes should alter this. * An apply function for TYPE_EFFECTIVENESS challenges. Derived classes should alter this.
* @param _effectiveness {@linkcode NumberHolder} The current effectiveness of the move. * @param _effectiveness - The current effectiveness of the move
* @returns Whether this function did anything. * @returns Whether this function did anything
*/ */
applyTypeEffectiveness(_effectiveness: NumberHolder): boolean { applyTypeEffectiveness(_effectiveness: NumberHolder): boolean {
return false; return false;
@ -289,11 +292,11 @@ export abstract class Challenge {
/** /**
* An apply function for AI_LEVEL challenges. Derived classes should alter this. * An apply function for AI_LEVEL challenges. Derived classes should alter this.
* @param _level {@link NumberHolder} The generated level. * @param _level - The generated level.
* @param _levelCap {@link Number} The current level cap. * @param _levelCap - The current level cap.
* @param _isTrainer {@link Boolean} Whether this is a trainer pokemon. * @param _isTrainer - Whether this is a trainer Pokémon
* @param _isBoss {@link Boolean} Whether this is a non-trainer boss pokemon. * @param _isBoss - Whether this is a non-trainer boss Pokémon
* @returns {@link boolean} Whether this function did anything. * @returns - Whether this function did anything
*/ */
applyLevelChange(_level: NumberHolder, _levelCap: number, _isTrainer: boolean, _isBoss: boolean): boolean { applyLevelChange(_level: NumberHolder, _levelCap: number, _isTrainer: boolean, _isBoss: boolean): boolean {
return false; return false;
@ -301,9 +304,9 @@ export abstract class Challenge {
/** /**
* An apply function for AI_MOVE_SLOTS challenges. Derived classes should alter this. * An apply function for AI_MOVE_SLOTS challenges. Derived classes should alter this.
* @param pokemon {@link Pokemon} The pokemon that is being considered. * @param _pokemon - The Pokémon that is being considered
* @param moveSlots {@link NumberHolder} The amount of move slots. * @param _moveSlots - The amount of move slots
* @returns {@link boolean} Whether this function did anything. * @returns Whether this function did anything
*/ */
applyMoveSlot(_pokemon: Pokemon, _moveSlots: NumberHolder): boolean { applyMoveSlot(_pokemon: Pokemon, _moveSlots: NumberHolder): boolean {
return false; return false;
@ -311,9 +314,9 @@ export abstract class Challenge {
/** /**
* An apply function for PASSIVE_ACCESS challenges. Derived classes should alter this. * An apply function for PASSIVE_ACCESS challenges. Derived classes should alter this.
* @param pokemon {@link Pokemon} The pokemon to change. * @param _pokemon - The Pokémon to change
* @param hasPassive {@link BooleanHolder} Whether it should have its passive. * @param _hasPassive - Whether it should have its passive
* @returns {@link boolean} Whether this function did anything. * @returns Whether this function did anything
*/ */
applyPassiveAccess(_pokemon: Pokemon, _hasPassive: BooleanHolder): boolean { applyPassiveAccess(_pokemon: Pokemon, _hasPassive: BooleanHolder): boolean {
return false; return false;
@ -321,7 +324,7 @@ export abstract class Challenge {
/** /**
* An apply function for GAME_MODE_MODIFY challenges. Derived classes should alter this. * An apply function for GAME_MODE_MODIFY challenges. Derived classes should alter this.
* @returns {@link boolean} Whether this function did anything. * @returns Whether this function did anything
*/ */
applyGameModeModify(): boolean { applyGameModeModify(): boolean {
return false; return false;
@ -329,11 +332,11 @@ export abstract class Challenge {
/** /**
* An apply function for MOVE_ACCESS. Derived classes should alter this. * An apply function for MOVE_ACCESS. Derived classes should alter this.
* @param _pokemon {@link Pokemon} What pokemon would learn the move. * @param _pokemon - What Pokémon would learn the move
* @param _moveSource {@link MoveSourceType} What source the pokemon would get the move from. * @param _moveSource - What source the Pokémon would get the move from
* @param _move {@link MoveId} The move in question. * @param _move - The move in question
* @param _level {@link NumberHolder} The level threshold for access. * @param _level - The level threshold for access
* @returns {@link boolean} Whether this function did anything. * @returns Whether this function did anything
*/ */
applyMoveAccessLevel(_pokemon: Pokemon, _moveSource: MoveSourceType, _move: MoveId, _level: NumberHolder): boolean { applyMoveAccessLevel(_pokemon: Pokemon, _moveSource: MoveSourceType, _move: MoveId, _level: NumberHolder): boolean {
return false; return false;
@ -341,21 +344,21 @@ export abstract class Challenge {
/** /**
* An apply function for MOVE_WEIGHT. Derived classes should alter this. * An apply function for MOVE_WEIGHT. Derived classes should alter this.
* @param _pokemon {@link Pokemon} What pokemon would learn the move. * @param _pokemon - What Pokémon would learn the move
* @param _moveSource {@link MoveSourceType} What source the pokemon would get the move from. * @param _moveSource - What source the Pokémon would get the move from
* @param _move {@link MoveId} The move in question. * @param _move - The move in question.
* @param _weight {@link NumberHolder} The base weight of the move * @param _weight - The base weight of the move
* @returns {@link boolean} Whether this function did anything. * @returns Whether this function did anything
*/ */
applyMoveWeight(_pokemon: Pokemon, _moveSource: MoveSourceType, _move: MoveId, _level: NumberHolder): boolean { applyMoveWeight(_pokemon: Pokemon, _moveSource: MoveSourceType, _move: MoveId, _weight: NumberHolder): boolean {
return false; return false;
} }
/** /**
* An apply function for FlipStats. Derived classes should alter this. * An apply function for FlipStats. Derived classes should alter this.
* @param _pokemon {@link Pokemon} What pokemon would learn the move. * @param _pokemon - What Pokémon would learn the move
* @param _baseStats What are the stats to flip. * @param _baseStats What are the stats to flip
* @returns {@link boolean} Whether this function did anything. * @returns Whether this function did anything
*/ */
applyFlipStat(_pokemon: Pokemon, _baseStats: number[]) { applyFlipStat(_pokemon: Pokemon, _baseStats: number[]) {
return false; return false;
@ -381,9 +384,9 @@ export abstract class Challenge {
/** /**
* An apply function for POKEMON_ADD_TO_PARTY. Derived classes should alter this. * An apply function for POKEMON_ADD_TO_PARTY. Derived classes should alter this.
* @param _pokemon - The pokemon being caught * @param _pokemon - The Pokémon being caught
* @param _status - Whether the pokemon can be added to the party or not * @param _status - Whether the Pokémon can be added to the party or not
* @return Whether this function did anything * @returns Whether this function did anything
*/ */
applyPokemonAddToParty(_pokemon: EnemyPokemon, _status: BooleanHolder): boolean { applyPokemonAddToParty(_pokemon: EnemyPokemon, _status: BooleanHolder): boolean {
return false; return false;
@ -391,8 +394,8 @@ export abstract class Challenge {
/** /**
* An apply function for POKEMON_FUSION. Derived classes should alter this. * An apply function for POKEMON_FUSION. Derived classes should alter this.
* @param _pokemon - The pokemon being checked * @param _pokemon - The Pokémon being checked
* @param _status - Whether the selected pokemon is allowed to fuse or not * @param _status - Whether the selected Pokémon is allowed to fuse or not
* @returns Whether this function did anything * @returns Whether this function did anything
*/ */
applyPokemonFusion(_pokemon: PlayerPokemon, _status: BooleanHolder): boolean { applyPokemonFusion(_pokemon: PlayerPokemon, _status: BooleanHolder): boolean {
@ -670,10 +673,7 @@ export class SingleGenerationChallenge extends Challenge {
return false; return false;
} }
/** override getDifficulty(): number {
* @overrides
*/
getDifficulty(): number {
return this.value > 0 ? 1 : 0; return this.value > 0 ? 1 : 0;
} }
@ -756,10 +756,7 @@ export class SingleTypeChallenge extends Challenge {
return false; return false;
} }
/** override getDifficulty(): number {
* @overrides
*/
getDifficulty(): number {
return this.value > 0 ? 1 : 0; return this.value > 0 ? 1 : 0;
} }
@ -1081,7 +1078,12 @@ export class LimitedCatchChallenge extends Challenge {
override applyPokemonAddToParty(pokemon: EnemyPokemon, status: BooleanHolder): boolean { override applyPokemonAddToParty(pokemon: EnemyPokemon, status: BooleanHolder): boolean {
if (status.value) { 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 true;
} }
return false; return false;

View File

@ -6,7 +6,7 @@ import { PokemonSpecies } from "#data/pokemon-species";
import { BiomeId } from "#enums/biome-id"; import { BiomeId } from "#enums/biome-id";
import { PartyMemberStrength } from "#enums/party-member-strength"; import { PartyMemberStrength } from "#enums/party-member-strength";
import { SpeciesId } from "#enums/species-id"; 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 { isNullOrUndefined, randSeedGauss, randSeedInt, randSeedItem } from "#utils/common";
import { getEnumValues } from "#utils/enums"; import { getEnumValues } from "#utils/enums";
import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils";

View File

@ -1,7 +1,7 @@
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import type { PlayerPokemon } from "#field/pokemon"; import type { PlayerPokemon } from "#field/pokemon";
import type { StarterDataEntry } from "#system/game-data";
import type { DexEntry } from "#types/dex-data"; import type { DexEntry } from "#types/dex-data";
import type { StarterDataEntry } from "#types/save-data";
/** /**
* Stores data associated with a specific egg and the hatched pokemon * Stores data associated with a specific egg and the hatched pokemon

View File

@ -644,9 +644,9 @@ export abstract class Move implements Localizable {
* will not consider {@linkcode AbilityId.WIND_RIDER | Wind Rider }. * will not consider {@linkcode AbilityId.WIND_RIDER | Wind Rider }.
* *
* To simply check whether the move has a flag, use {@linkcode hasFlag}. * To simply check whether the move has a flag, use {@linkcode hasFlag}.
* @param flag {@linkcode MoveFlags} MoveFlag to check on user and/or target * @param flag - MoveFlag to check on user and/or target
* @param user {@linkcode Pokemon} the Pokemon using the move * @param user - the Pokemon using the move
* @param target {@linkcode Pokemon} the Pokemon receiving the move * @param target - the Pokemon receiving the move
* @param isFollowUp (defaults to `false`) `true` if the move was used as a follow up * @param isFollowUp (defaults to `false`) `true` if the move was used as a follow up
* @returns boolean * @returns boolean
* @see {@linkcode hasFlag} * @see {@linkcode hasFlag}
@ -1133,11 +1133,7 @@ function ChargeMove<TBase extends SubMove>(Base: TBase, nameAppend: string) {
export class ChargingAttackMove extends ChargeMove(AttackMove, "ChargingAttackMove") {} export class ChargingAttackMove extends ChargeMove(AttackMove, "ChargingAttackMove") {}
export class ChargingSelfStatusMove extends ChargeMove(SelfStatusMove, "ChargingSelfStatusMove") {} export class ChargingSelfStatusMove extends ChargeMove(SelfStatusMove, "ChargingSelfStatusMove") {}
/** /** Base class defining all {@linkcode Move} Attributes */
* Base class defining all {@linkcode Move} Attributes
* @abstract
* @see {@linkcode apply}
*/
export abstract class MoveAttr { export abstract class MoveAttr {
/** Should this {@linkcode Move} target the user? */ /** Should this {@linkcode Move} target the user? */
public selfTarget: boolean; public selfTarget: boolean;
@ -1233,8 +1229,6 @@ interface MoveEffectAttrOptions {
/** /**
* Base class defining all Move Effect Attributes * Base class defining all Move Effect Attributes
* @extends MoveAttr
* @see {@linkcode apply}
*/ */
export class MoveEffectAttr extends MoveAttr { export class MoveEffectAttr extends MoveAttr {
/** /**
@ -1450,7 +1444,6 @@ export class PreMoveMessageAttr extends MoveAttr {
* Attribute for moves that can be conditionally interrupted to be considered to * Attribute for moves that can be conditionally interrupted to be considered to
* have failed before their "useMove" message is displayed. Currently used by * have failed before their "useMove" message is displayed. Currently used by
* Focus Punch. * Focus Punch.
* @extends MoveAttr
*/ */
export class PreUseInterruptAttr extends MoveAttr { export class PreUseInterruptAttr extends MoveAttr {
protected message: string | MoveMessageFunc; protected message: string | MoveMessageFunc;
@ -1494,7 +1487,6 @@ export class PreUseInterruptAttr extends MoveAttr {
/** /**
* Attribute for Status moves that take attack type effectiveness * Attribute for Status moves that take attack type effectiveness
* into consideration (i.e. {@linkcode https://bulbapedia.bulbagarden.net/wiki/Thunder_Wave_(move) | Thunder Wave}) * into consideration (i.e. {@linkcode https://bulbapedia.bulbagarden.net/wiki/Thunder_Wave_(move) | Thunder Wave})
* @extends MoveAttr
*/ */
export class RespectAttackTypeImmunityAttr extends MoveAttr { } export class RespectAttackTypeImmunityAttr extends MoveAttr { }
@ -1778,9 +1770,7 @@ export class RecoilAttr extends MoveEffectAttr {
/** /**
* Attribute used for moves which self KO the user regardless if the move hits a target * Attribute used for moves which self KO the user regardless if the move hits a target
* @extends MoveEffectAttr */
* @see {@linkcode apply}
**/
export class SacrificialAttr extends MoveEffectAttr { export class SacrificialAttr extends MoveEffectAttr {
constructor() { constructor() {
super(true, { trigger: MoveEffectTrigger.POST_TARGET }); super(true, { trigger: MoveEffectTrigger.POST_TARGET });
@ -1811,9 +1801,7 @@ export class SacrificialAttr extends MoveEffectAttr {
/** /**
* Attribute used for moves which self KO the user but only if the move hits a target * Attribute used for moves which self KO the user but only if the move hits a target
* @extends MoveEffectAttr */
* @see {@linkcode apply}
**/
export class SacrificialAttrOnHit extends MoveEffectAttr { export class SacrificialAttrOnHit extends MoveEffectAttr {
constructor() { constructor() {
super(true); super(true);
@ -1850,8 +1838,6 @@ export class SacrificialAttrOnHit extends MoveEffectAttr {
/** /**
* Attribute used for moves which cut the user's Max HP in half. * Attribute used for moves which cut the user's Max HP in half.
* Triggers using {@linkcode MoveEffectTrigger.POST_TARGET}. * Triggers using {@linkcode MoveEffectTrigger.POST_TARGET}.
* @extends MoveEffectAttr
* @see {@linkcode apply}
*/ */
export class HalfSacrificialAttr extends MoveEffectAttr { export class HalfSacrificialAttr extends MoveEffectAttr {
constructor() { constructor() {
@ -1951,8 +1937,6 @@ export class AddSubstituteAttr extends MoveEffectAttr {
/** /**
* Heals the user or target by {@linkcode healRatio} depending on the value of {@linkcode selfTarget} * Heals the user or target by {@linkcode healRatio} depending on the value of {@linkcode selfTarget}
* @extends MoveEffectAttr
* @see {@linkcode apply}
*/ */
export class HealAttr extends MoveEffectAttr { export class HealAttr extends MoveEffectAttr {
constructor( constructor(
@ -2041,8 +2025,6 @@ export class RestAttr extends HealAttr {
/** /**
* Cures the user's party of non-volatile status conditions, ie. Heal Bell, Aromatherapy * Cures the user's party of non-volatile status conditions, ie. Heal Bell, Aromatherapy
* @extends MoveEffectAttr
* @see {@linkcode apply}
*/ */
export class PartyStatusCureAttr extends MoveEffectAttr { export class PartyStatusCureAttr extends MoveEffectAttr {
/** Message to display after using move */ /** Message to display after using move */
@ -2101,7 +2083,6 @@ export class PartyStatusCureAttr extends MoveEffectAttr {
/** /**
* Applies damage to the target's ally equal to 1/16 of that ally's max HP. * Applies damage to the target's ally equal to 1/16 of that ally's max HP.
* @extends MoveEffectAttr
*/ */
export class FlameBurstAttr extends MoveEffectAttr { export class FlameBurstAttr extends MoveEffectAttr {
constructor() { constructor() {
@ -2190,8 +2171,6 @@ export class SacrificialFullRestoreAttr extends SacrificialAttr {
/** /**
* Attribute used for moves which ignore type-based debuffs from weather, namely Hydro Steam. * Attribute used for moves which ignore type-based debuffs from weather, namely Hydro Steam.
* Called during damage calculation after getting said debuff from getAttackTypeMultiplier in the Pokemon class. * Called during damage calculation after getting said debuff from getAttackTypeMultiplier in the Pokemon class.
* @extends MoveAttr
* @see {@linkcode apply}
*/ */
export class IgnoreWeatherTypeDebuffAttr extends MoveAttr { export class IgnoreWeatherTypeDebuffAttr extends MoveAttr {
/** The {@linkcode WeatherType} this move ignores */ /** The {@linkcode WeatherType} this move ignores */
@ -2270,8 +2249,6 @@ export class SandHealAttr extends WeatherHealAttr {
/** /**
* Heals the target or the user by either {@linkcode normalHealRatio} or {@linkcode boostedHealRatio} * Heals the target or the user by either {@linkcode normalHealRatio} or {@linkcode boostedHealRatio}
* depending on the evaluation of {@linkcode condition} * depending on the evaluation of {@linkcode condition}
* @extends HealAttr
* @see {@linkcode apply}
*/ */
export class BoostHealAttr extends HealAttr { export class BoostHealAttr extends HealAttr {
/** Healing received when {@linkcode condition} is false */ /** Healing received when {@linkcode condition} is false */
@ -2304,8 +2281,6 @@ export class BoostHealAttr extends HealAttr {
/** /**
* Heals the target only if it is the ally * Heals the target only if it is the ally
* @extends HealAttr
* @see {@linkcode apply}
*/ */
export class HealOnAllyAttr extends HealAttr { export class HealOnAllyAttr extends HealAttr {
override canApply(user: Pokemon, target: Pokemon, _move: Move, _args?: any[]): boolean { override canApply(user: Pokemon, target: Pokemon, _move: Move, _args?: any[]): boolean {
@ -2324,9 +2299,6 @@ export class HealOnAllyAttr extends HealAttr {
/** /**
* Heals user as a side effect of a move that hits a target. * Heals user as a side effect of a move that hits a target.
* Healing is based on {@linkcode healRatio} * the amount of damage dealt or a stat of the target. * Healing is based on {@linkcode healRatio} * the amount of damage dealt or a stat of the target.
* @extends MoveEffectAttr
* @see {@linkcode apply}
* @see {@linkcode getUserBenefitScore}
*/ */
// TODO: Make Strength Sap its own attribute that extends off of this one // TODO: Make Strength Sap its own attribute that extends off of this one
export class HitHealAttr extends MoveEffectAttr { export class HitHealAttr extends MoveEffectAttr {
@ -2396,8 +2368,6 @@ export class HitHealAttr extends MoveEffectAttr {
* Attribute used for moves that change priority in a turn given a condition, * Attribute used for moves that change priority in a turn given a condition,
* e.g. Grassy Glide * e.g. Grassy Glide
* Called when move order is calculated in {@linkcode TurnStartPhase}. * Called when move order is calculated in {@linkcode TurnStartPhase}.
* @extends MoveAttr
* @see {@linkcode apply}
*/ */
export class IncrementMovePriorityAttr extends MoveAttr { export class IncrementMovePriorityAttr extends MoveAttr {
/** The condition for a move's priority being incremented */ /** The condition for a move's priority being incremented */
@ -2433,10 +2403,8 @@ export class IncrementMovePriorityAttr extends MoveAttr {
/** /**
* Attribute used for attack moves that hit multiple times per use, e.g. Bullet Seed. * Attribute used for attack moves that hit multiple times per use, e.g. Bullet Seed.
* *
* @remarks
* Applied at the beginning of {@linkcode MoveEffectPhase}. * Applied at the beginning of {@linkcode MoveEffectPhase}.
*
* @extends MoveAttr
* @see {@linkcode apply}
*/ */
export class MultiHitAttr extends MoveAttr { export class MultiHitAttr extends MoveAttr {
/** This move's intrinsic multi-hit type. It should never be modified. */ /** This move's intrinsic multi-hit type. It should never be modified. */
@ -2946,8 +2914,6 @@ export class StealEatBerryAttr extends EatBerryAttr {
/** /**
* Move attribute that signals that the move should cure a status effect * Move attribute that signals that the move should cure a status effect
* @extends MoveEffectAttr
* @see {@linkcode apply()}
*/ */
export class HealStatusEffectAttr extends MoveEffectAttr { export class HealStatusEffectAttr extends MoveEffectAttr {
/** List of Status Effects to cure */ /** List of Status Effects to cure */
@ -3030,8 +2996,6 @@ export class BypassSleepAttr extends MoveAttr {
/** /**
* Attribute used for moves that bypass the burn damage reduction of physical moves, currently only facade * Attribute used for moves that bypass the burn damage reduction of physical moves, currently only facade
* Called during damage calculation * Called during damage calculation
* @extends MoveAttr
* @see {@linkcode apply}
*/ */
export class BypassBurnDamageReductionAttr extends MoveAttr { export class BypassBurnDamageReductionAttr extends MoveAttr {
/** Prevents the move's damage from being reduced by burn /** Prevents the move's damage from being reduced by burn
@ -3140,7 +3104,6 @@ export class OneHitKOAttr extends MoveAttr {
/** /**
* Attribute that allows charge moves to resolve in 1 turn under a given condition. * Attribute that allows charge moves to resolve in 1 turn under a given condition.
* Should only be used for {@linkcode ChargingMove | ChargingMoves} as a `chargeAttr`. * Should only be used for {@linkcode ChargingMove | ChargingMoves} as a `chargeAttr`.
* @extends MoveAttr
*/ */
export class InstantChargeAttr extends MoveAttr { export class InstantChargeAttr extends MoveAttr {
/** The condition in which the move with this attribute instantly charges */ /** The condition in which the move with this attribute instantly charges */
@ -3177,7 +3140,6 @@ export class InstantChargeAttr extends MoveAttr {
/** /**
* Attribute that allows charge moves to resolve in 1 turn while specific {@linkcode WeatherType | Weather} * Attribute that allows charge moves to resolve in 1 turn while specific {@linkcode WeatherType | Weather}
* is active. Should only be used for {@linkcode ChargingMove | ChargingMoves} as a `chargeAttr`. * is active. Should only be used for {@linkcode ChargingMove | ChargingMoves} as a `chargeAttr`.
* @extends InstantChargeAttr
*/ */
export class WeatherInstantChargeAttr extends InstantChargeAttr { export class WeatherInstantChargeAttr extends InstantChargeAttr {
constructor(weatherTypes: WeatherType[]) { constructor(weatherTypes: WeatherType[]) {
@ -3307,7 +3269,6 @@ export class WishAttr extends MoveEffectAttr {
/** /**
* Attribute that cancels the associated move's effects when set to be combined with the user's ally's * Attribute that cancels the associated move's effects when set to be combined with the user's ally's
* subsequent move this turn. Used for Grass Pledge, Water Pledge, and Fire Pledge. * subsequent move this turn. Used for Grass Pledge, Water Pledge, and Fire Pledge.
* @extends OverrideMoveEffectAttr
*/ */
export class AwaitCombinedPledgeAttr extends OverrideMoveEffectAttr { export class AwaitCombinedPledgeAttr extends OverrideMoveEffectAttr {
constructor() { constructor() {
@ -3362,7 +3323,6 @@ export class AwaitCombinedPledgeAttr extends OverrideMoveEffectAttr {
/** /**
* Set of optional parameters that may be applied to stat stage changing effects * Set of optional parameters that may be applied to stat stage changing effects
* @extends MoveEffectAttrOptions
* @see {@linkcode StatStageChangeAttr} * @see {@linkcode StatStageChangeAttr}
*/ */
interface StatStageChangeAttrOptions extends MoveEffectAttrOptions { interface StatStageChangeAttrOptions extends MoveEffectAttrOptions {
@ -3379,9 +3339,6 @@ interface StatStageChangeAttrOptions extends MoveEffectAttrOptions {
* @param stages How many stages to change the stat(s) by, [-6, 6] * @param stages How many stages to change the stat(s) by, [-6, 6]
* @param selfTarget `true` if the move is self-targetting * @param selfTarget `true` if the move is self-targetting
* @param options {@linkcode StatStageChangeAttrOptions} Container for any optional parameters for this attribute. * @param options {@linkcode StatStageChangeAttrOptions} Container for any optional parameters for this attribute.
*
* @extends MoveEffectAttr
* @see {@linkcode apply}
*/ */
export class StatStageChangeAttr extends MoveEffectAttr { export class StatStageChangeAttr extends MoveEffectAttr {
public stats: BattleStat[]; public stats: BattleStat[];
@ -3812,8 +3769,6 @@ export class ResetStatsAttr extends MoveEffectAttr {
/** /**
* Attribute used for status moves, specifically Heart, Guard, and Power Swap, * Attribute used for status moves, specifically Heart, Guard, and Power Swap,
* that swaps the user's and target's corresponding stat stages. * that swaps the user's and target's corresponding stat stages.
* @extends MoveEffectAttr
* @see {@linkcode apply}
*/ */
export class SwapStatStagesAttr extends MoveEffectAttr { export class SwapStatStagesAttr extends MoveEffectAttr {
/** The stat stages to be swapped between the user and the target */ /** The stat stages to be swapped between the user and the target */
@ -4101,8 +4056,6 @@ export class WeightPowerAttr extends VariablePowerAttr {
/** /**
* Attribute used for Electro Ball move. * Attribute used for Electro Ball move.
* @extends VariablePowerAttr
* @see {@linkcode apply}
**/ **/
export class ElectroBallPowerAttr extends VariablePowerAttr { export class ElectroBallPowerAttr extends VariablePowerAttr {
/** /**
@ -4136,8 +4089,6 @@ export class ElectroBallPowerAttr extends VariablePowerAttr {
/** /**
* Attribute used for Gyro Ball move. * Attribute used for Gyro Ball move.
* @extends VariablePowerAttr
* @see {@linkcode apply}
**/ **/
export class GyroBallPowerAttr extends VariablePowerAttr { export class GyroBallPowerAttr extends VariablePowerAttr {
/** /**
@ -4393,11 +4344,11 @@ const countPositiveStatStages = (pokemon: Pokemon): number => {
export class PositiveStatStagePowerAttr extends VariablePowerAttr { export class PositiveStatStagePowerAttr extends VariablePowerAttr {
/** /**
* @param {Pokemon} user The pokemon that is being used to calculate the amount of positive stats * @param user The pokemon that is being used to calculate the amount of positive stats
* @param {Pokemon} target N/A * @param target N/A
* @param {Move} move N/A * @param move N/A
* @param {any[]} args The argument for VariablePowerAttr, accumulates and sets the amount of power multiplied by stats * @param args The argument for VariablePowerAttr, accumulates and sets the amount of power multiplied by stats
* @returns {boolean} Returns true if attribute is applied * @returns Returns true if attribute is applied
*/ */
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const positiveStatStages: number = countPositiveStatStages(user); const positiveStatStages: number = countPositiveStatStages(user);
@ -4417,10 +4368,10 @@ export class PunishmentPowerAttr extends VariablePowerAttr {
private PUNISHMENT_MAX_BASE_POWER = 200; private PUNISHMENT_MAX_BASE_POWER = 200;
/** /**
* @param {Pokemon} user N/A * @param user N/A
* @param {Pokemon} target The pokemon that the move is being used against, as well as calculating the stats for the min/max base power * @param target The pokemon that the move is being used against, as well as calculating the stats for the min/max base power
* @param {Move} move N/A * @param move N/A
* @param {any[]} args The value that is being changed due to VariablePowerAttr * @param args The value that is being changed due to VariablePowerAttr
* @returns Returns true if attribute is applied * @returns Returns true if attribute is applied
*/ */
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
@ -4536,8 +4487,6 @@ const hasStockpileStacksCondition: MoveConditionFunc = (user) => {
/** /**
* Attribute used for multi-hit moves that increase power in increments of the * Attribute used for multi-hit moves that increase power in increments of the
* move's base power for each hit, namely Triple Kick and Triple Axel. * move's base power for each hit, namely Triple Kick and Triple Axel.
* @extends VariablePowerAttr
* @see {@linkcode apply}
*/ */
export class MultiHitPowerIncrementAttr extends VariablePowerAttr { export class MultiHitPowerIncrementAttr extends VariablePowerAttr {
/** The max number of base power increments allowed for this move */ /** The max number of base power increments allowed for this move */
@ -4574,8 +4523,6 @@ export class MultiHitPowerIncrementAttr extends VariablePowerAttr {
* Attribute used for moves that double in power if the given move immediately * Attribute used for moves that double in power if the given move immediately
* preceded the move applying the attribute, namely Fusion Flare and * preceded the move applying the attribute, namely Fusion Flare and
* Fusion Bolt. * Fusion Bolt.
* @extends VariablePowerAttr
* @see {@linkcode apply}
*/ */
export class LastMoveDoublePowerAttr extends VariablePowerAttr { export class LastMoveDoublePowerAttr extends VariablePowerAttr {
/** The move that must precede the current move */ /** The move that must precede the current move */
@ -4678,7 +4625,6 @@ export class CombinedPledgeStabBoostAttr extends MoveAttr {
/** /**
* Variable Power attribute for {@link https://bulbapedia.bulbagarden.net/wiki/Round_(move) | Round}. * Variable Power attribute for {@link https://bulbapedia.bulbagarden.net/wiki/Round_(move) | Round}.
* Doubles power if another Pokemon has previously selected Round this turn. * Doubles power if another Pokemon has previously selected Round this turn.
* @extends VariablePowerAttr
*/ */
export class RoundPowerAttr extends VariablePowerAttr { export class RoundPowerAttr extends VariablePowerAttr {
override apply(user: Pokemon, target: Pokemon, move: Move, args: [NumberHolder]): boolean { override apply(user: Pokemon, target: Pokemon, move: Move, args: [NumberHolder]): boolean {
@ -4696,8 +4642,6 @@ export class RoundPowerAttr extends VariablePowerAttr {
* Attribute for the "combo" effect of {@link https://bulbapedia.bulbagarden.net/wiki/Round_(move) | Round}. * Attribute for the "combo" effect of {@link https://bulbapedia.bulbagarden.net/wiki/Round_(move) | Round}.
* Preempts the next move in the turn order with the first instance of any Pokemon * Preempts the next move in the turn order with the first instance of any Pokemon
* using Round. Also marks the Pokemon using the cued Round to double the move's power. * using Round. Also marks the Pokemon using the cued Round to double the move's power.
* @extends MoveEffectAttr
* @see {@linkcode RoundPowerAttr}
*/ */
export class CueNextRoundAttr extends MoveEffectAttr { export class CueNextRoundAttr extends MoveEffectAttr {
constructor() { constructor() {
@ -4899,8 +4843,6 @@ export class StormAccuracyAttr extends VariableAccuracyAttr {
/** /**
* Attribute used for moves which never miss * Attribute used for moves which never miss
* against Pokemon with the {@linkcode BattlerTagType.MINIMIZED} * against Pokemon with the {@linkcode BattlerTagType.MINIMIZED}
* @extends VariableAccuracyAttr
* @see {@linkcode apply}
*/ */
export class AlwaysHitMinimizeAttr extends VariableAccuracyAttr { export class AlwaysHitMinimizeAttr extends VariableAccuracyAttr {
/** /**
@ -4973,9 +4915,8 @@ export class PhotonGeyserCategoryAttr extends VariableMoveCategoryAttr {
* Attribute used for tera moves that change category based on the user's Atk and SpAtk stats * Attribute used for tera moves that change category based on the user's Atk and SpAtk stats
* Note: Currently, `getEffectiveStat` does not ignore all abilities that affect stats except those * Note: Currently, `getEffectiveStat` does not ignore all abilities that affect stats except those
* with the attribute of `StatMultiplierAbAttr` * with the attribute of `StatMultiplierAbAttr`
* TODO: Remove the `.partial()` tag from Tera Blast and Tera Starstorm when the above issue is resolved
* @extends VariableMoveCategoryAttr
*/ */
// TODO: Remove the `.partial()` tag from Tera Blast and Tera Starstorm when the above issue is resolved
export class TeraMoveCategoryAttr extends VariableMoveCategoryAttr { export class TeraMoveCategoryAttr extends VariableMoveCategoryAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const category = (args[0] as NumberHolder); const category = (args[0] as NumberHolder);
@ -4992,7 +4933,6 @@ export class TeraMoveCategoryAttr extends VariableMoveCategoryAttr {
/** /**
* Increases the power of Tera Blast if the user is Terastallized into Stellar type * Increases the power of Tera Blast if the user is Terastallized into Stellar type
* @extends VariablePowerAttr
*/ */
export class TeraBlastPowerAttr extends VariablePowerAttr { export class TeraBlastPowerAttr extends VariablePowerAttr {
/** /**
@ -5019,8 +4959,6 @@ export class TeraBlastPowerAttr extends VariablePowerAttr {
/** /**
* Change the move category to status when used on the ally * Change the move category to status when used on the ally
* @extends VariableMoveCategoryAttr
* @see {@linkcode apply}
*/ */
export class StatusCategoryOnAllyAttr extends VariableMoveCategoryAttr { export class StatusCategoryOnAllyAttr extends VariableMoveCategoryAttr {
/** /**
@ -5252,8 +5190,6 @@ export class WeatherBallTypeAttr extends VariableMoveTypeAttr {
/** /**
* Changes the move's type to match the current terrain. * Changes the move's type to match the current terrain.
* Has no effect if the user is not grounded. * Has no effect if the user is not grounded.
* @extends VariableMoveTypeAttr
* @see {@linkcode apply}
*/ */
export class TerrainPulseTypeAttr extends VariableMoveTypeAttr { export class TerrainPulseTypeAttr extends VariableMoveTypeAttr {
/** /**
@ -5301,7 +5237,6 @@ export class TerrainPulseTypeAttr extends VariableMoveTypeAttr {
/** /**
* Changes type based on the user's IVs * Changes type based on the user's IVs
* @extends VariableMoveTypeAttr
*/ */
export class HiddenPowerTypeAttr extends VariableMoveTypeAttr { export class HiddenPowerTypeAttr extends VariableMoveTypeAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
@ -5329,7 +5264,6 @@ export class HiddenPowerTypeAttr extends VariableMoveTypeAttr {
/** /**
* Changes the type of Tera Blast to match the user's tera type * Changes the type of Tera Blast to match the user's tera type
* @extends VariableMoveTypeAttr
*/ */
export class TeraBlastTypeAttr extends VariableMoveTypeAttr { export class TeraBlastTypeAttr extends VariableMoveTypeAttr {
/** /**
@ -5356,7 +5290,6 @@ export class TeraBlastTypeAttr extends VariableMoveTypeAttr {
/** /**
* Attribute used for Tera Starstorm that changes the move type to Stellar * Attribute used for Tera Starstorm that changes the move type to Stellar
* @extends VariableMoveTypeAttr
*/ */
export class TeraStarstormTypeAttr extends VariableMoveTypeAttr { export class TeraStarstormTypeAttr extends VariableMoveTypeAttr {
/** /**
@ -5402,7 +5335,6 @@ export class MatchUserTypeAttr extends VariableMoveTypeAttr {
/** /**
* Changes the type of a Pledge move based on the Pledge move combined with it. * Changes the type of a Pledge move based on the Pledge move combined with it.
* @extends VariableMoveTypeAttr
*/ */
export class CombinedPledgeTypeAttr extends VariableMoveTypeAttr { export class CombinedPledgeTypeAttr extends VariableMoveTypeAttr {
override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
@ -5540,10 +5472,10 @@ export class SheerColdAccuracyAttr extends OneHitKOAccuracyAttr {
/** /**
* Changes the normal One Hit KO Accuracy Attr to implement the Gen VII changes, * Changes the normal One Hit KO Accuracy Attr to implement the Gen VII changes,
* where if the user is Ice-Type, it has more accuracy. * where if the user is Ice-Type, it has more accuracy.
* @param {Pokemon} user Pokemon that is using the move; checks the Pokemon's level. * @param user Pokemon that is using the move; checks the Pokemon's level.
* @param {Pokemon} target Pokemon that is receiving the move; checks the Pokemon's level. * @param target Pokemon that is receiving the move; checks the Pokemon's level.
* @param {Move} move N/A * @param move N/A
* @param {any[]} args Uses the accuracy argument, allowing to change it from either 0 if it doesn't pass * @param args Uses the accuracy argument, allowing to change it from either 0 if it doesn't pass
* the first if/else, or 30/20 depending on the type of the user Pokemon. * the first if/else, or 30/20 depending on the type of the user Pokemon.
* @returns Returns true if move is successful, false if misses. * @returns Returns true if move is successful, false if misses.
*/ */
@ -5658,7 +5590,6 @@ export class FrenzyAttr extends MoveEffectAttr {
/** /**
* Attribute that grants {@link https://bulbapedia.bulbagarden.net/wiki/Semi-invulnerable_turn | semi-invulnerability} to the user during * Attribute that grants {@link https://bulbapedia.bulbagarden.net/wiki/Semi-invulnerable_turn | semi-invulnerability} to the user during
* the associated move's charging phase. Should only be used for {@linkcode ChargingMove | ChargingMoves} as a `chargeAttr`. * the associated move's charging phase. Should only be used for {@linkcode ChargingMove | ChargingMoves} as a `chargeAttr`.
* @extends MoveEffectAttr
*/ */
export class SemiInvulnerableAttr extends MoveEffectAttr { export class SemiInvulnerableAttr extends MoveEffectAttr {
/** The type of {@linkcode SemiInvulnerableTag} to grant to the user */ /** The type of {@linkcode SemiInvulnerableTag} to grant to the user */
@ -5812,7 +5743,6 @@ export class YawnAttr extends AddBattlerTagAttr {
/** /**
* Adds a {@link https://bulbapedia.bulbagarden.net/wiki/Seeding | Seeding} effect to the target * Adds a {@link https://bulbapedia.bulbagarden.net/wiki/Seeding | Seeding} effect to the target
* as seen with Leech Seed and Sappy Seed. * as seen with Leech Seed and Sappy Seed.
* @extends AddBattlerTagAttr
*/ */
export class LeechSeedAttr extends AddBattlerTagAttr { export class LeechSeedAttr extends AddBattlerTagAttr {
constructor() { constructor() {
@ -5822,7 +5752,6 @@ export class LeechSeedAttr extends AddBattlerTagAttr {
/** /**
* Adds the appropriate battler tag for Smack Down and Thousand arrows * Adds the appropriate battler tag for Smack Down and Thousand arrows
* @extends AddBattlerTagAttr
*/ */
export class FallDownAttr extends AddBattlerTagAttr { export class FallDownAttr extends AddBattlerTagAttr {
constructor() { constructor() {
@ -5847,7 +5776,6 @@ export class FallDownAttr extends AddBattlerTagAttr {
/** /**
* Adds the appropriate battler tag for Gulp Missile when Surf or Dive is used. * Adds the appropriate battler tag for Gulp Missile when Surf or Dive is used.
* @extends MoveEffectAttr
*/ */
export class GulpMissileTagAttr extends MoveEffectAttr { export class GulpMissileTagAttr extends MoveEffectAttr {
constructor() { constructor() {
@ -5887,7 +5815,6 @@ export class GulpMissileTagAttr extends MoveEffectAttr {
/** /**
* Attribute to implement Jaw Lock's linked trapping effect between the user and target * Attribute to implement Jaw Lock's linked trapping effect between the user and target
* @extends AddBattlerTagAttr
*/ */
export class JawLockAttr extends AddBattlerTagAttr { export class JawLockAttr extends AddBattlerTagAttr {
constructor() { constructor() {
@ -6053,7 +5980,6 @@ export class ProtectAttr extends AddBattlerTagAttr {
/** /**
* Attribute to remove all Substitutes from the field. * Attribute to remove all Substitutes from the field.
* @extends MoveEffectAttr
* @see {@link https://bulbapedia.bulbagarden.net/wiki/Tidy_Up_(move) | Tidy Up} * @see {@link https://bulbapedia.bulbagarden.net/wiki/Tidy_Up_(move) | Tidy Up}
* @see {@linkcode SubstituteTag} * @see {@linkcode SubstituteTag}
*/ */
@ -6085,7 +6011,6 @@ export class RemoveAllSubstitutesAttr extends MoveEffectAttr {
* Attribute used when a move can deal damage to {@linkcode BattlerTagType} * Attribute used when a move can deal damage to {@linkcode BattlerTagType}
* Moves that always hit but do not deal double damage: Thunder, Fissure, Sky Uppercut, * Moves that always hit but do not deal double damage: Thunder, Fissure, Sky Uppercut,
* Smack Down, Hurricane, Thousand Arrows * Smack Down, Hurricane, Thousand Arrows
* @extends MoveAttr
*/ */
export class HitsTagAttr extends MoveAttr { export class HitsTagAttr extends MoveAttr {
/** The {@linkcode BattlerTagType} this move hits */ /** The {@linkcode BattlerTagType} this move hits */
@ -6199,8 +6124,6 @@ export class AddArenaTrapTagAttr extends AddArenaTagAttr {
/** /**
* Attribute used for Stone Axe and Ceaseless Edge. * Attribute used for Stone Axe and Ceaseless Edge.
* Applies the given ArenaTrapTag when move is used. * Applies the given ArenaTrapTag when move is used.
* @extends AddArenaTagAttr
* @see {@linkcode apply}
*/ */
export class AddArenaTrapTagHitAttr extends AddArenaTagAttr { export class AddArenaTrapTagHitAttr extends AddArenaTagAttr {
/** /**
@ -6293,10 +6216,7 @@ export class RemoveScreensAttr extends MoveEffectAttr {
} }
} }
/*Swaps arena effects between the player and enemy side /** Swaps arena effects between the player and enemy side */
* @extends MoveEffectAttr
* @see {@linkcode apply}
*/
export class SwapArenaTagsAttr extends MoveEffectAttr { export class SwapArenaTagsAttr extends MoveEffectAttr {
public SwapTags: ArenaTagType[]; public SwapTags: ArenaTagType[];
@ -6362,8 +6282,6 @@ export class AddPledgeEffectAttr extends AddArenaTagAttr {
/** /**
* Attribute used for Revival Blessing. * Attribute used for Revival Blessing.
* @extends MoveEffectAttr
* @see {@linkcode apply}
*/ */
export class RevivalBlessingAttr extends MoveEffectAttr { export class RevivalBlessingAttr extends MoveEffectAttr {
constructor() { constructor() {
@ -6428,7 +6346,6 @@ export class RevivalBlessingAttr extends MoveEffectAttr {
} }
} }
export class ForceSwitchOutAttr extends MoveEffectAttr { export class ForceSwitchOutAttr extends MoveEffectAttr {
constructor( constructor(
private selfSwitch: boolean = false, private selfSwitch: boolean = false,
@ -6787,7 +6704,7 @@ export class CopyBiomeTypeAttr extends MoveEffectAttr {
/** /**
* Retrieves a type from the current terrain * Retrieves a type from the current terrain
* @param terrainType {@linkcode TerrainType} * @param terrainType {@linkcode TerrainType}
* @returns {@linkcode Type} * @returns
*/ */
private getTypeForTerrain(terrainType: TerrainType): PokemonType { private getTypeForTerrain(terrainType: TerrainType): PokemonType {
switch (terrainType) { switch (terrainType) {
@ -6808,7 +6725,7 @@ export class CopyBiomeTypeAttr extends MoveEffectAttr {
/** /**
* Retrieves a type from the current biome * Retrieves a type from the current biome
* @param biomeType {@linkcode BiomeId} * @param biomeType {@linkcode BiomeId}
* @returns {@linkcode Type} * @returns
*/ */
private getTypeForBiome(biomeType: BiomeId): PokemonType { private getTypeForBiome(biomeType: BiomeId): PokemonType {
switch (biomeType) { switch (biomeType) {
@ -6871,7 +6788,7 @@ export class CopyBiomeTypeAttr extends MoveEffectAttr {
} }
} }
/** /**
* Attribute to override the target's current types to the given type. * Attribute to override the target's current types to the given type.
* Used by {@linkcode MoveId.SOAK} and {@linkcode MoveId.MAGIC_POWDER}. * Used by {@linkcode MoveId.SOAK} and {@linkcode MoveId.MAGIC_POWDER}.
*/ */
@ -6941,8 +6858,6 @@ export class FirstMoveTypeAttr extends MoveEffectAttr {
/** /**
* Attribute used to call a move. * Attribute used to call a move.
* Used by other move attributes: {@linkcode RandomMoveAttr}, {@linkcode RandomMovesetMoveAttr}, {@linkcode CopyMoveAttr} * Used by other move attributes: {@linkcode RandomMoveAttr}, {@linkcode RandomMovesetMoveAttr}, {@linkcode CopyMoveAttr}
* @see {@linkcode apply} for move call
* @extends OverrideMoveEffectAttr
*/ */
class CallMoveAttr extends OverrideMoveEffectAttr { class CallMoveAttr extends OverrideMoveEffectAttr {
protected invalidMoves: ReadonlySet<MoveId>; protected invalidMoves: ReadonlySet<MoveId>;
@ -6974,8 +6889,6 @@ class CallMoveAttr extends OverrideMoveEffectAttr {
/** /**
* Attribute used to call a random move. * Attribute used to call a random move.
* Used for {@linkcode MoveId.METRONOME} * Used for {@linkcode MoveId.METRONOME}
* @see {@linkcode apply} for move selection and move call
* @extends CallMoveAttr to call a selected move
*/ */
export class RandomMoveAttr extends CallMoveAttr { export class RandomMoveAttr extends CallMoveAttr {
constructor(invalidMoves: ReadonlySet<MoveId>) { constructor(invalidMoves: ReadonlySet<MoveId>) {
@ -7023,8 +6936,6 @@ export class RandomMoveAttr extends CallMoveAttr {
* Fails if the user has no callable moves. * Fails if the user has no callable moves.
* *
* Invalid moves are indicated by what is passed in to invalidMoves: {@linkcode invalidAssistMoves} or {@linkcode invalidSleepTalkMoves} * Invalid moves are indicated by what is passed in to invalidMoves: {@linkcode invalidAssistMoves} or {@linkcode invalidSleepTalkMoves}
* @extends RandomMoveAttr to use the callMove function on a moveId
* @see {@linkcode getCondition} for move selection
*/ */
export class RandomMovesetMoveAttr extends CallMoveAttr { export class RandomMovesetMoveAttr extends CallMoveAttr {
private includeParty: boolean; private includeParty: boolean;
@ -7210,8 +7121,6 @@ export class NaturePowerAttr extends OverrideMoveEffectAttr {
/** /**
* Attribute used to copy a previously-used move. * Attribute used to copy a previously-used move.
* Used for {@linkcode MoveId.COPYCAT} and {@linkcode MoveId.MIRROR_MOVE} * Used for {@linkcode MoveId.COPYCAT} and {@linkcode MoveId.MIRROR_MOVE}
* @see {@linkcode apply} for move selection and move call
* @extends CallMoveAttr to call a selected move
*/ */
export class CopyMoveAttr extends CallMoveAttr { export class CopyMoveAttr extends CallMoveAttr {
private mirrorMove: boolean; private mirrorMove: boolean;
@ -7488,11 +7397,11 @@ export class SketchAttr extends MoveEffectAttr {
} }
/** /**
* User copies the opponent's last used move, if possible * User copies the opponent's last used move, if possible
* @param {Pokemon} user Pokemon that used the move and will replace Sketch with the copied move * @param user Pokemon that used the move and will replace Sketch with the copied move
* @param {Pokemon} target Pokemon that the user wants to copy a move from * @param target Pokemon that the user wants to copy a move from
* @param {Move} move Move being used * @param move Move being used
* @param {any[]} args Unused * @param args Unused
* @returns {boolean} true if the function succeeds, otherwise false * @returns true if the function succeeds, otherwise false
*/ */
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
@ -7655,10 +7564,6 @@ export class SwitchAbilitiesAttr extends MoveEffectAttr {
/** /**
* Attribute used for moves that suppress abilities like {@linkcode MoveId.GASTRO_ACID}. * Attribute used for moves that suppress abilities like {@linkcode MoveId.GASTRO_ACID}.
* A suppressed ability cannot be activated. * A suppressed ability cannot be activated.
*
* @extends MoveEffectAttr
* @see {@linkcode apply}
* @see {@linkcode getCondition}
*/ */
export class SuppressAbilitiesAttr extends MoveEffectAttr { export class SuppressAbilitiesAttr extends MoveEffectAttr {
/** Sets ability suppression for the target pokemon and displays a message. */ /** Sets ability suppression for the target pokemon and displays a message. */
@ -7684,8 +7589,7 @@ export class SuppressAbilitiesAttr extends MoveEffectAttr {
/** /**
* Applies the effects of {@linkcode SuppressAbilitiesAttr} if the target has already moved this turn. * Applies the effects of {@linkcode SuppressAbilitiesAttr} if the target has already moved this turn.
* @extends MoveEffectAttr * @see {@linkcode MoveId.CORE_ENFORCER}
* @see {@linkcode MoveId.CORE_ENFORCER} (the move which uses this effect)
*/ */
export class SuppressAbilitiesIfActedAttr extends MoveEffectAttr { export class SuppressAbilitiesIfActedAttr extends MoveEffectAttr {
/** /**
@ -7734,8 +7638,6 @@ export class TransformAttr extends MoveEffectAttr {
/** /**
* Attribute used for status moves, namely Speed Swap, * Attribute used for status moves, namely Speed Swap,
* that swaps the user's and target's corresponding stats. * that swaps the user's and target's corresponding stats.
* @extends MoveEffectAttr
* @see {@linkcode apply}
*/ */
export class SwapStatAttr extends MoveEffectAttr { export class SwapStatAttr extends MoveEffectAttr {
/** The stat to be swapped between the user and the target */ /** The stat to be swapped between the user and the target */
@ -7776,7 +7678,6 @@ export class SwapStatAttr extends MoveEffectAttr {
/** /**
* Attribute used to switch the user's own stats. * Attribute used to switch the user's own stats.
* Used by Power Shift. * Used by Power Shift.
* @extends MoveEffectAttr
*/ */
export class ShiftStatAttr extends MoveEffectAttr { export class ShiftStatAttr extends MoveEffectAttr {
private statToSwitch: EffectiveStat; private statToSwitch: EffectiveStat;
@ -7791,7 +7692,7 @@ export class ShiftStatAttr extends MoveEffectAttr {
/** /**
* Switches the user's stats based on the {@linkcode statToSwitch} and {@linkcode statToSwitchWith} attributes. * Switches the user's stats based on the {@linkcode statToSwitch} and {@linkcode statToSwitchWith} attributes.
* @param {Pokemon} user the {@linkcode Pokemon} that used the move * @param user the {@linkcode Pokemon} that used the move
* @param target n/a * @param target n/a
* @param move n/a * @param move n/a
* @param args n/a * @param args n/a
@ -7819,7 +7720,7 @@ export class ShiftStatAttr extends MoveEffectAttr {
/** /**
* Encourages the user to use the move if the stat to switch with is greater than the stat to switch. * Encourages the user to use the move if the stat to switch with is greater than the stat to switch.
* @param {Pokemon} user the {@linkcode Pokemon} that used the move * @param user the {@linkcode Pokemon} that used the move
* @param target n/a * @param target n/a
* @param move n/a * @param move n/a
* @returns number of points to add to the user's benefit score * @returns number of points to add to the user's benefit score
@ -7833,8 +7734,6 @@ export class ShiftStatAttr extends MoveEffectAttr {
* Attribute used for status moves, namely Power Split and Guard Split, * Attribute used for status moves, namely Power Split and Guard Split,
* that take the average of a user's and target's corresponding * that take the average of a user's and target's corresponding
* stats and assign that average back to each corresponding stat. * stats and assign that average back to each corresponding stat.
* @extends MoveEffectAttr
* @see {@linkcode apply}
*/ */
export class AverageStatsAttr extends MoveEffectAttr { export class AverageStatsAttr extends MoveEffectAttr {
/** The stats to be averaged individually between the user and the target */ /** The stats to be averaged individually between the user and the target */
@ -7887,11 +7786,7 @@ export class MoneyAttr extends MoveEffectAttr {
} }
} }
/** /** Applies {@linkcode BattlerTagType.DESTINY_BOND} to the user */
* Applies {@linkcode BattlerTagType.DESTINY_BOND} to the user.
*
* @extends MoveEffectAttr
*/
export class DestinyBondAttr extends MoveEffectAttr { export class DestinyBondAttr extends MoveEffectAttr {
constructor() { constructor() {
super(true, { trigger: MoveEffectTrigger.PRE_APPLY }); super(true, { trigger: MoveEffectTrigger.PRE_APPLY });
@ -7902,7 +7797,7 @@ export class DestinyBondAttr extends MoveEffectAttr {
* @param user {@linkcode Pokemon} that is having the tag applied to. * @param user {@linkcode Pokemon} that is having the tag applied to.
* @param target {@linkcode Pokemon} N/A * @param target {@linkcode Pokemon} N/A
* @param move {@linkcode Move} {@linkcode Move.DESTINY_BOND} * @param move {@linkcode Move} {@linkcode Move.DESTINY_BOND}
* @param {any[]} args N/A * @param args N/A
* @returns true * @returns true
*/ */
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
@ -7912,10 +7807,7 @@ export class DestinyBondAttr extends MoveEffectAttr {
} }
} }
/** /** Attribute to apply a battler tag to the target if they have had their stats boosted this turn */
* Attribute to apply a battler tag to the target if they have had their stats boosted this turn.
* @extends AddBattlerTagAttr
*/
export class AddBattlerTagIfBoostedAttr extends AddBattlerTagAttr { export class AddBattlerTagIfBoostedAttr extends AddBattlerTagAttr {
constructor(tag: BattlerTagType) { constructor(tag: BattlerTagType) {
super(tag, false, false, 2, 5); super(tag, false, false, 2, 5);
@ -7925,7 +7817,7 @@ export class AddBattlerTagIfBoostedAttr extends AddBattlerTagAttr {
* @param user {@linkcode Pokemon} using this move * @param user {@linkcode Pokemon} using this move
* @param target {@linkcode Pokemon} target of this move * @param target {@linkcode Pokemon} target of this move
* @param move {@linkcode Move} being used * @param move {@linkcode Move} being used
* @param {any[]} args N/A * @param args N/A
* @returns true * @returns true
*/ */
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
@ -7938,7 +7830,6 @@ export class AddBattlerTagIfBoostedAttr extends AddBattlerTagAttr {
/** /**
* Attribute to apply a status effect to the target if they have had their stats boosted this turn. * Attribute to apply a status effect to the target if they have had their stats boosted this turn.
* @extends MoveEffectAttr
*/ */
export class StatusIfBoostedAttr extends MoveEffectAttr { export class StatusIfBoostedAttr extends MoveEffectAttr {
public effect: StatusEffect; public effect: StatusEffect;
@ -7952,7 +7843,7 @@ export class StatusIfBoostedAttr extends MoveEffectAttr {
* @param user {@linkcode Pokemon} using this move * @param user {@linkcode Pokemon} using this move
* @param target {@linkcode Pokemon} target of this move * @param target {@linkcode Pokemon} target of this move
* @param move {@linkcode Move} N/A * @param move {@linkcode Move} N/A
* @param {any[]} args N/A * @param args N/A
* @returns true * @returns true
*/ */
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
@ -8034,7 +7925,6 @@ export class AfterYouAttr extends MoveEffectAttr {
/** /**
* Move effect to force the target to move last, ignoring priority. * Move effect to force the target to move last, ignoring priority.
* If applied to multiple targets, they move in speed order after all other moves. * If applied to multiple targets, they move in speed order after all other moves.
* @extends MoveEffectAttr
*/ */
export class ForceLastAttr extends MoveEffectAttr { export class ForceLastAttr extends MoveEffectAttr {
/** /**
@ -8213,11 +8103,11 @@ export class ResistLastMoveTypeAttr extends MoveEffectAttr {
/** /**
* User changes its type to a random type that resists the target's last used move * User changes its type to a random type that resists the target's last used move
* @param {Pokemon} user Pokemon that used the move and will change types * @param user Pokemon that used the move and will change types
* @param {Pokemon} target Opposing pokemon that recently used a move * @param target Opposing pokemon that recently used a move
* @param {Move} move Move being used * @param move Move being used
* @param {any[]} args Unused * @param args Unused
* @returns {boolean} true if the function succeeds * @returns true if the function succeeds
*/ */
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
if (!super.apply(user, target, move, args)) { if (!super.apply(user, target, move, args)) {
@ -8278,9 +8168,6 @@ export class ResistLastMoveTypeAttr extends MoveEffectAttr {
* Drops the target's immunity to types it is immune to * Drops the target's immunity to types it is immune to
* and makes its evasiveness be ignored during accuracy * and makes its evasiveness be ignored during accuracy
* checks. Used by: {@linkcode MoveId.ODOR_SLEUTH | Odor Sleuth}, {@linkcode MoveId.MIRACLE_EYE | Miracle Eye} and {@linkcode MoveId.FORESIGHT | Foresight} * checks. Used by: {@linkcode MoveId.ODOR_SLEUTH | Odor Sleuth}, {@linkcode MoveId.MIRACLE_EYE | Miracle Eye} and {@linkcode MoveId.FORESIGHT | Foresight}
*
* @extends AddBattlerTagAttr
* @see {@linkcode apply}
*/ */
export class ExposedMoveAttr extends AddBattlerTagAttr { export class ExposedMoveAttr extends AddBattlerTagAttr {
constructor(tagType: BattlerTagType) { constructor(tagType: BattlerTagType) {

View File

@ -46,8 +46,8 @@ import {
} from "#mystery-encounters/mystery-encounter-requirements"; } from "#mystery-encounters/mystery-encounter-requirements";
import { getRandomPartyMemberFunc, trainerConfigs } from "#trainers/trainer-config"; import { getRandomPartyMemberFunc, trainerConfigs } from "#trainers/trainer-config";
import { TrainerPartyCompoundTemplate, TrainerPartyTemplate } from "#trainers/trainer-party-template"; import { TrainerPartyCompoundTemplate, TrainerPartyTemplate } from "#trainers/trainer-party-template";
import { MoveInfoOverlay } from "#ui/containers/move-info-overlay"; import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
import type { OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; import { MoveInfoOverlay } from "#ui/move-info-overlay";
import { isNullOrUndefined, randSeedInt, randSeedShuffle } from "#utils/common"; import { isNullOrUndefined, randSeedInt, randSeedShuffle } from "#utils/common";
import i18next from "i18next"; import i18next from "i18next";

View File

@ -45,7 +45,7 @@ import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option"; import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option";
import { trainerConfigs } from "#trainers/trainer-config"; import { trainerConfigs } from "#trainers/trainer-config";
import { TrainerPartyCompoundTemplate, TrainerPartyTemplate } from "#trainers/trainer-party-template"; 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 { randSeedInt, randSeedShuffle } from "#utils/common";
import { getPokemonSpecies } from "#utils/pokemon-utils"; import { getPokemonSpecies } from "#utils/pokemon-utils";
import i18next from "i18next"; import i18next from "i18next";

View File

@ -37,7 +37,7 @@ import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encou
import { MoveRequirement } from "#mystery-encounters/mystery-encounter-requirements"; import { MoveRequirement } from "#mystery-encounters/mystery-encounter-requirements";
import { DANCING_MOVES } from "#mystery-encounters/requirement-groups"; import { DANCING_MOVES } from "#mystery-encounters/requirement-groups";
import { PokemonData } from "#system/pokemon-data"; 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 { getPokemonSpecies } from "#utils/pokemon-utils";
import i18next from "i18next"; import i18next from "i18next";

View File

@ -33,7 +33,7 @@ import {
MoneyRequirement, MoneyRequirement,
} from "#mystery-encounters/mystery-encounter-requirements"; } from "#mystery-encounters/mystery-encounter-requirements";
import i18next from "#plugins/i18n"; 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 { randSeedItem } from "#utils/common";
import { getPokemonSpecies } from "#utils/pokemon-utils"; import { getPokemonSpecies } from "#utils/pokemon-utils";

View File

@ -18,7 +18,7 @@ import {
import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter"; import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter"; import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option"; 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"; import i18next from "i18next";
/** i18n namespace for the encounter */ /** i18n namespace for the encounter */

View File

@ -42,7 +42,7 @@ import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encou
import { PartySizeRequirement } from "#mystery-encounters/mystery-encounter-requirements"; import { PartySizeRequirement } from "#mystery-encounters/mystery-encounter-requirements";
import { PokemonData } from "#system/pokemon-data"; import { PokemonData } from "#system/pokemon-data";
import { MusicPreference } from "#system/settings"; 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 { isNullOrUndefined, NumberHolder, randInt, randSeedInt, randSeedItem, randSeedShuffle } from "#utils/common";
import { getEnumKeys } from "#utils/enums"; import { getEnumKeys } from "#utils/enums";
import { getRandomLocaleEntry } from "#utils/i18n"; import { getRandomLocaleEntry } from "#utils/i18n";

View File

@ -27,7 +27,7 @@ import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option"; import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option";
import { PokemonData } from "#system/pokemon-data"; import { PokemonData } from "#system/pokemon-data";
import type { HeldModifierConfig } from "#types/held-modifier-config"; 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 { isNullOrUndefined, randSeedShuffle } from "#utils/common";
import { getEnumValues } from "#utils/enums"; import { getEnumValues } from "#utils/enums";
import i18next from "i18next"; import i18next from "i18next";

View File

@ -576,10 +576,9 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
*/ */
/** /**
* @static Defines the type of encounter which is used as an identifier, should be tied to a unique MysteryEncounterType * Defines the type of encounter which is used as an identifier, should be tied to a unique MysteryEncounterType
* NOTE: if new functions are added to {@linkcode MysteryEncounter} class
* @param encounterType * @param encounterType
* @returns this * @returns a new instance of MysteryEncounterBuilder with encounterType set
*/ */
static withEncounterType( static withEncounterType(
encounterType: MysteryEncounterType, encounterType: MysteryEncounterType,

View File

@ -46,9 +46,9 @@ import type { PokemonData } from "#system/pokemon-data";
import type { TrainerConfig } from "#trainers/trainer-config"; import type { TrainerConfig } from "#trainers/trainer-config";
import { trainerConfigs } from "#trainers/trainer-config"; import { trainerConfigs } from "#trainers/trainer-config";
import type { HeldModifierConfig } from "#types/held-modifier-config"; import type { HeldModifierConfig } from "#types/held-modifier-config";
import type { OptionSelectConfig, OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
import type { PartyOption, PokemonSelectFilter } from "#ui/handlers/party-ui-handler"; import type { PartyOption, PokemonSelectFilter } from "#ui/party-ui-handler";
import { PartyUiMode } from "#ui/handlers/party-ui-handler"; import { PartyUiMode } from "#ui/party-ui-handler";
import { coerceArray, isNullOrUndefined, randomString, randSeedInt, randSeedItem } from "#utils/common"; import { coerceArray, isNullOrUndefined, randomString, randSeedInt, randSeedItem } from "#utils/common";
import { getPokemonSpecies } from "#utils/pokemon-utils"; import { getPokemonSpecies } from "#utils/pokemon-utils";
import i18next from "i18next"; import i18next from "i18next";
@ -969,7 +969,7 @@ export function handleMysteryEncounterBattleStartEffects() {
/** /**
* Can queue extra phases or logic during {@linkcode TurnInitPhase} * Can queue extra phases or logic during {@linkcode TurnInitPhase}
* Should mostly just be used for injecting custom phases into the battle system on turn start * Should mostly just be used for injecting custom phases into the battle system on turn start
* @return boolean - if true, will skip the remainder of the {@linkcode TurnInitPhase} * @returns boolean - if true, will skip the remainder of the {@linkcode TurnInitPhase}
*/ */
export function handleMysteryEncounterTurnStartEffects(): boolean { export function handleMysteryEncounterTurnStartEffects(): boolean {
const encounter = globalScene.currentBattle.mysteryEncounter; const encounter = globalScene.currentBattle.mysteryEncounter;
@ -986,7 +986,7 @@ export function handleMysteryEncounterTurnStartEffects(): boolean {
* @param level the level of the mon, which differs between MEs * @param level the level of the mon, which differs between MEs
* @param isBoss whether the mon should be a Boss * @param isBoss whether the mon should be a Boss
* @param rerollHidden whether the mon should get an extra roll for Hidden Ability * @param rerollHidden whether the mon should get an extra roll for Hidden Ability
* @returns {@linkcode EnemyPokemon} for the requested encounter * @returns for the requested encounter
*/ */
export function getRandomEncounterSpecies(level: number, isBoss = false, rerollHidden = false): EnemyPokemon { export function getRandomEncounterSpecies(level: number, isBoss = false, rerollHidden = false): EnemyPokemon {
let bossSpecies: PokemonSpecies; let bossSpecies: PokemonSpecies;

View File

@ -31,9 +31,9 @@ import {
showEncounterText, showEncounterText,
} from "#mystery-encounters/encounter-dialogue-utils"; } from "#mystery-encounters/encounter-dialogue-utils";
import { achvs } from "#system/achv"; import { achvs } from "#system/achv";
import type { PartyOption } from "#ui/handlers/party-ui-handler"; import type { PartyOption } from "#ui/party-ui-handler";
import { PartyUiMode } from "#ui/handlers/party-ui-handler"; import { PartyUiMode } from "#ui/party-ui-handler";
import { SummaryUiMode } from "#ui/handlers/summary-ui-handler"; import { SummaryUiMode } from "#ui/summary-ui-handler";
import { applyChallenges } from "#utils/challenge-utils"; import { applyChallenges } from "#utils/challenge-utils";
import { BooleanHolder, isNullOrUndefined, randSeedInt } from "#utils/common"; import { BooleanHolder, isNullOrUndefined, randSeedInt } from "#utils/common";
import { getPokemonSpecies } from "#utils/pokemon-utils"; import { getPokemonSpecies } from "#utils/pokemon-utils";

View File

@ -289,7 +289,7 @@ export class SpeciesFormChangeRevertWeatherFormTrigger extends SpeciesFormChange
/** /**
* Checks if the Pokemon has the required ability and the weather is one that will revert * Checks if the Pokemon has the required ability and the weather is one that will revert
* the Pokemon to its original form or the weather or ability is suppressed * the Pokemon to its original form or the weather or ability is suppressed
* @param {Pokemon} pokemon the pokemon that is trying to do the form change * @param pokemon the pokemon that is trying to do the form change
* @returns `true` if the Pokemon will revert to its original form, `false` otherwise * @returns `true` if the Pokemon will revert to its original form, `false` otherwise
*/ */
canChange(pokemon: Pokemon): boolean { canChange(pokemon: Pokemon): boolean {

View File

@ -26,8 +26,8 @@ import { loadPokemonVariantAssets } from "#sprites/pokemon-sprite";
import { hasExpSprite } from "#sprites/sprite-utils"; import { hasExpSprite } from "#sprites/sprite-utils";
import type { Variant, VariantSet } from "#sprites/variant"; import type { Variant, VariantSet } from "#sprites/variant";
import { populateVariantColorCache, variantColorCache, variantData } from "#sprites/variant"; import { populateVariantColorCache, variantColorCache, variantData } from "#sprites/variant";
import type { StarterMoveset } from "#system/game-data";
import type { Localizable } from "#types/locales"; import type { Localizable } from "#types/locales";
import type { StarterMoveset } from "#types/save-data";
import { isNullOrUndefined, randSeedFloat, randSeedGauss, randSeedInt } from "#utils/common"; import { isNullOrUndefined, randSeedFloat, randSeedGauss, randSeedInt } from "#utils/common";
import { getPokemonSpecies } from "#utils/pokemon-utils"; import { getPokemonSpecies } from "#utils/pokemon-utils";
import { toCamelCase, toPascalCase } from "#utils/strings"; import { toCamelCase, toPascalCase } from "#utils/strings";
@ -919,7 +919,7 @@ export class PokemonSpecies extends PokemonSpeciesForm implements Localizable {
* The calculation with evolution delay is a weighted average of the easeIn and easeOut functions where preferredMinLevel is the denominator. * The calculation with evolution delay is a weighted average of the easeIn and easeOut functions where preferredMinLevel is the denominator.
* This also means a lower value of x will lead to a higher evolution chance. * This also means a lower value of x will lead to a higher evolution chance.
* @param strength {@linkcode PartyMemberStrength} The strength of the party member in question * @param strength {@linkcode PartyMemberStrength} The strength of the party member in question
* @returns {@linkcode number} The level difference from expected evolution level tolerated for a mon to be unevolved. Lower value = higher evolution chance. * @returns The level difference from expected evolution level tolerated for a mon to be unevolved. Lower value = higher evolution chance.
*/ */
private getStrengthLevelDiff(strength: PartyMemberStrength): number { private getStrengthLevelDiff(strength: PartyMemberStrength): number {
switch (Math.min(strength, PartyMemberStrength.STRONGER)) { switch (Math.min(strength, PartyMemberStrength.STRONGER)) {

View File

@ -234,7 +234,7 @@ const seasonalSplashMessages: Season[] = [
"valentines.happyValentines", "valentines.happyValentines",
"valentines.fullOfLove", "valentines.fullOfLove",
"valentines.applinForYou", "valentines.applinForYou",
"valentines.thePowerOfLoveIsThreeThirtyBST", "valentines.thePowerOfLoveIsThreeThirtyBst",
"valentines.haveAHeartScale", "valentines.haveAHeartScale",
"valentines.i<3You", "valentines.i<3You",
], ],
@ -265,7 +265,7 @@ const seasonalSplashMessages: Season[] = [
"aprilFools.whoIsFinn", "aprilFools.whoIsFinn",
"aprilFools.watchOutForShadowPokemon", "aprilFools.watchOutForShadowPokemon",
"aprilFools.nowWithDarkTypeLuxray", "aprilFools.nowWithDarkTypeLuxray",
"aprilFools.onlyOnPokerogueNetAGAIN", "aprilFools.onlyOnPokerogueNetAgain",
"aprilFools.noFreeVouchers", "aprilFools.noFreeVouchers",
"aprilFools.altffourAchievementPoints", "aprilFools.altffourAchievementPoints",
"aprilFools.rokePogue", "aprilFools.rokePogue",

View File

@ -204,7 +204,7 @@ export class TrainerConfig {
/** /**
* Returns the derived trainer type for a given trainer type. * Returns the derived trainer type for a given trainer type.
* @param trainerTypeToDeriveFrom - The trainer type to derive from. (If null, the this.trainerType property will be used.) * @param trainerTypeToDeriveFrom - The trainer type to derive from. (If null, the this.trainerType property will be used.)
* @returns {TrainerType} - The derived trainer type. * @returns - The derived trainer type.
*/ */
getDerivedType(trainerTypeToDeriveFrom: TrainerType | null = null): TrainerType { getDerivedType(trainerTypeToDeriveFrom: TrainerType | null = null): TrainerType {
let trainerType = trainerTypeToDeriveFrom ? trainerTypeToDeriveFrom : this.trainerType; let trainerType = trainerTypeToDeriveFrom ? trainerTypeToDeriveFrom : this.trainerType;
@ -274,9 +274,9 @@ export class TrainerConfig {
/** /**
* Sets the configuration for trainers with genders, including the female name and encounter background music (BGM). * Sets the configuration for trainers with genders, including the female name and encounter background music (BGM).
* @param {string} [nameFemale] The name of the female trainer. If 'Ivy', a localized name will be assigned. * @param [nameFemale] The name of the female trainer. If 'Ivy', a localized name will be assigned.
* @param {TrainerType | string} [femaleEncounterBgm] The encounter BGM for the female trainer, which can be a TrainerType or a string. * @param [femaleEncounterBgm] The encounter BGM for the female trainer, which can be a TrainerType or a string.
* @returns {TrainerConfig} The updated TrainerConfig instance. * @returns The updated TrainerConfig instance.
*/ */
setHasGenders(nameFemale?: string, femaleEncounterBgm?: TrainerType | string): TrainerConfig { setHasGenders(nameFemale?: string, femaleEncounterBgm?: TrainerType | string): TrainerConfig {
// If the female name is 'Ivy' (the rival), assign a localized name. // If the female name is 'Ivy' (the rival), assign a localized name.
@ -314,7 +314,7 @@ export class TrainerConfig {
* Sets the configuration for trainers with double battles, including the name of the double trainer and the encounter BGM. * Sets the configuration for trainers with double battles, including the name of the double trainer and the encounter BGM.
* @param nameDouble The name of the double trainer (e.g., "Ace Duo" for Trainer Class Doubles or "red_blue_double" for NAMED trainer doubles). * @param nameDouble The name of the double trainer (e.g., "Ace Duo" for Trainer Class Doubles or "red_blue_double" for NAMED trainer doubles).
* @param doubleEncounterBgm The encounter BGM for the double trainer, which can be a TrainerType or a string. * @param doubleEncounterBgm The encounter BGM for the double trainer, which can be a TrainerType or a string.
* @returns {TrainerConfig} The updated TrainerConfig instance. * @returns The updated TrainerConfig instance.
*/ */
setHasDouble(nameDouble: string, doubleEncounterBgm?: TrainerType | string): TrainerConfig { setHasDouble(nameDouble: string, doubleEncounterBgm?: TrainerType | string): TrainerConfig {
this.hasDouble = true; this.hasDouble = true;
@ -331,7 +331,7 @@ export class TrainerConfig {
/** /**
* Sets the trainer type for double battles. * Sets the trainer type for double battles.
* @param trainerTypeDouble The TrainerType of the partner in a double battle. * @param trainerTypeDouble The TrainerType of the partner in a double battle.
* @returns {TrainerConfig} The updated TrainerConfig instance. * @returns The updated TrainerConfig instance.
*/ */
setDoubleTrainerType(trainerTypeDouble: TrainerType): TrainerConfig { setDoubleTrainerType(trainerTypeDouble: TrainerType): TrainerConfig {
this.trainerTypeDouble = trainerTypeDouble; this.trainerTypeDouble = trainerTypeDouble;
@ -356,7 +356,7 @@ export class TrainerConfig {
/** /**
* Sets the title for double trainers * Sets the title for double trainers
* @param titleDouble The key for the title in the i18n file. (e.g., "champion_double"). * @param titleDouble The key for the title in the i18n file. (e.g., "champion_double").
* @returns {TrainerConfig} The updated TrainerConfig instance. * @returns The updated TrainerConfig instance.
*/ */
setDoubleTitle(titleDouble: string): TrainerConfig { setDoubleTitle(titleDouble: string): TrainerConfig {
// First check if i18n is initialized // First check if i18n is initialized
@ -523,9 +523,9 @@ export class TrainerConfig {
* Initializes the trainer configuration for an evil team admin. * Initializes the trainer configuration for an evil team admin.
* @param title The title of the evil team admin. * @param title The title of the evil team admin.
* @param poolName The evil team the admin belongs to. * @param poolName The evil team the admin belongs to.
* @param {SpeciesId | SpeciesId[]} signatureSpecies The signature species for the evil team leader. * @param signatureSpecies The signature species for the evil team leader.
* @param specialtyType The specialty Type of the admin, if they have one * @param specialtyType The specialty Type of the admin, if they have one
* @returns {TrainerConfig} The updated TrainerConfig instance. * @returns The updated TrainerConfig instance.
*/ */
initForEvilTeamAdmin( initForEvilTeamAdmin(
title: string, title: string,
@ -566,7 +566,7 @@ export class TrainerConfig {
/** /**
* Initializes the trainer configuration for a Stat Trainer, as part of the Trainer's Test Mystery Encounter. * Initializes the trainer configuration for a Stat Trainer, as part of the Trainer's Test Mystery Encounter.
* @param _isMale Whether the stat trainer is Male or Female (for localization of the title). * @param _isMale Whether the stat trainer is Male or Female (for localization of the title).
* @returns {TrainerConfig} The updated TrainerConfig instance. * @returns The updated TrainerConfig instance.
*/ */
initForStatTrainer(_isMale = false): TrainerConfig { initForStatTrainer(_isMale = false): TrainerConfig {
if (!getIsInitialized()) { if (!getIsInitialized()) {
@ -590,10 +590,10 @@ export class TrainerConfig {
/** /**
* Initializes the trainer configuration for an evil team leader. Temporarily hardcoding evil leader teams though. * Initializes the trainer configuration for an evil team leader. Temporarily hardcoding evil leader teams though.
* @param {SpeciesId | SpeciesId[]} signatureSpecies The signature species for the evil team leader. * @param signatureSpecies The signature species for the evil team leader.
* @param {PokemonType} specialtyType The specialty type for the evil team Leader. * @param specialtyType The specialty type for the evil team Leader.
* @param boolean Whether or not this is the rematch fight * @param boolean Whether or not this is the rematch fight
* @returns {TrainerConfig} The updated TrainerConfig instance. * @returns The updated TrainerConfig instance.
*/ */
initForEvilTeamLeader( initForEvilTeamLeader(
title: string, title: string,
@ -631,12 +631,12 @@ export class TrainerConfig {
/** /**
* Initializes the trainer configuration for a Gym Leader. * Initializes the trainer configuration for a Gym Leader.
* @param {SpeciesId | SpeciesId[]} signatureSpecies The signature species for the Gym Leader. Added to party in reverse order. * @param signatureSpecies The signature species for the Gym Leader. Added to party in reverse order.
* @param isMale Whether the Gym Leader is Male or Not (for localization of the title). * @param isMale Whether the Gym Leader is Male or Not (for localization of the title).
* @param {PokemonType} specialtyType The specialty type for the Gym Leader. * @param specialtyType The specialty type for the Gym Leader.
* @param ignoreMinTeraWave Whether the Gym Leader always uses Tera (true), or only Teras after {@linkcode GYM_LEADER_TERA_WAVE} (false). Defaults to false. * @param ignoreMinTeraWave Whether the Gym Leader always uses Tera (true), or only Teras after {@linkcode GYM_LEADER_TERA_WAVE} (false). Defaults to false.
* @param teraSlot Optional, sets the party member in this slot to Terastallize. Wraps based on party size. * @param teraSlot Optional, sets the party member in this slot to Terastallize. Wraps based on party size.
* @returns {TrainerConfig} The updated TrainerConfig instance. * @returns The updated TrainerConfig instance.
*/ */
initForGymLeader( initForGymLeader(
signatureSpecies: (SpeciesId | SpeciesId[])[], signatureSpecies: (SpeciesId | SpeciesId[])[],
@ -748,9 +748,9 @@ export class TrainerConfig {
/** /**
* Initializes the trainer configuration for a Champion. * Initializes the trainer configuration for a Champion.
* @param {SpeciesId | SpeciesId[]} signatureSpecies The signature species for the Champion. * @param signatureSpecies The signature species for the Champion.
* @param isMale Whether the Champion is Male or Female (for localization of the title). * @param isMale Whether the Champion is Male or Female (for localization of the title).
* @returns {TrainerConfig} The updated TrainerConfig instance. * @returns The updated TrainerConfig instance.
*/ */
initForChampion(isMale: boolean): TrainerConfig { initForChampion(isMale: boolean): TrainerConfig {
// Check if the internationalization (i18n) system is initialized. // Check if the internationalization (i18n) system is initialized.
@ -785,7 +785,7 @@ export class TrainerConfig {
/** /**
* Sets a localized name for the trainer. This should only be used for trainers that dont use a "initFor" function and are considered "named" trainers * Sets a localized name for the trainer. This should only be used for trainers that dont use a "initFor" function and are considered "named" trainers
* @param name - The name of the trainer. * @param name - The name of the trainer.
* @returns {TrainerConfig} The updated TrainerConfig instance. * @returns The updated TrainerConfig instance.
*/ */
setLocalizedName(name: string): TrainerConfig { setLocalizedName(name: string): TrainerConfig {
// Check if the internationalization (i18n) system is initialized. // Check if the internationalization (i18n) system is initialized.
@ -798,9 +798,9 @@ export class TrainerConfig {
/** /**
* Retrieves the title for the trainer based on the provided trainer slot and variant. * Retrieves the title for the trainer based on the provided trainer slot and variant.
* @param {TrainerSlot} trainerSlot - The slot to determine which title to use. Defaults to TrainerSlot.NONE. * @param trainerSlot - The slot to determine which title to use. Defaults to TrainerSlot.NONE.
* @param {TrainerVariant} variant - The variant of the trainer to determine the specific title. * @param variant - The variant of the trainer to determine the specific title.
* @returns {string} - The title of the trainer. * @returns - The title of the trainer.
*/ */
getTitle(trainerSlot: TrainerSlot = TrainerSlot.NONE, variant: TrainerVariant): string { getTitle(trainerSlot: TrainerSlot = TrainerSlot.NONE, variant: TrainerVariant): string {
const ret = this.name; const ret = this.name;

View File

@ -29,7 +29,7 @@ export enum MoveFlags {
SLICING_MOVE = 1 << 8, SLICING_MOVE = 1 << 8,
/** /**
* Indicates a move should be affected by {@linkcode AbilityId.RECKLESS} * Indicates a move should be affected by {@linkcode AbilityId.RECKLESS}
* @see {@linkcode Move.recklessMove()} * @see {@linkcode Move.recklessMove}
*/ */
RECKLESS_MOVE = 1 << 9, RECKLESS_MOVE = 1 << 9,
/** Indicates a move should be affected by {@linkcode AbilityId.BULLETPROOF} */ /** Indicates a move should be affected by {@linkcode AbilityId.BULLETPROOF} */

View File

@ -16,10 +16,7 @@ export enum ArenaEventType {
TAG_REMOVED = "onTagRemoved", TAG_REMOVED = "onTagRemoved",
} }
/** /** Base container class for all {@linkcode ArenaEventType} events */
* Base container class for all {@linkcode ArenaEventType} events
* @extends Event
*/
export class ArenaEvent extends Event { export class ArenaEvent extends Event {
/** The total duration of the {@linkcode ArenaEventType} */ /** The total duration of the {@linkcode ArenaEventType} */
public duration: number; public duration: number;
@ -29,10 +26,7 @@ export class ArenaEvent extends Event {
this.duration = duration; this.duration = duration;
} }
} }
/** /** Container class for {@linkcode ArenaEventType.WEATHER_CHANGED} events */
* Container class for {@linkcode ArenaEventType.WEATHER_CHANGED} events
* @extends ArenaEvent
*/
export class WeatherChangedEvent extends ArenaEvent { export class WeatherChangedEvent extends ArenaEvent {
/** The {@linkcode WeatherType} being overridden */ /** The {@linkcode WeatherType} being overridden */
public oldWeatherType: WeatherType; public oldWeatherType: WeatherType;
@ -45,10 +39,7 @@ export class WeatherChangedEvent extends ArenaEvent {
this.newWeatherType = newWeatherType; this.newWeatherType = newWeatherType;
} }
} }
/** /** Container class for {@linkcode ArenaEventType.TERRAIN_CHANGED} events */
* Container class for {@linkcode ArenaEventType.TERRAIN_CHANGED} events
* @extends ArenaEvent
*/
export class TerrainChangedEvent extends ArenaEvent { export class TerrainChangedEvent extends ArenaEvent {
/** The {@linkcode TerrainType} being overridden */ /** The {@linkcode TerrainType} being overridden */
public oldTerrainType: TerrainType; public oldTerrainType: TerrainType;
@ -62,10 +53,7 @@ export class TerrainChangedEvent extends ArenaEvent {
} }
} }
/** /** Container class for {@linkcode ArenaEventType.TAG_ADDED} events */
* Container class for {@linkcode ArenaEventType.TAG_ADDED} events
* @extends ArenaEvent
*/
export class TagAddedEvent extends ArenaEvent { export class TagAddedEvent extends ArenaEvent {
/** The {@linkcode ArenaTagType} being added */ /** The {@linkcode ArenaTagType} being added */
public arenaTagType: ArenaTagType; public arenaTagType: ArenaTagType;
@ -91,10 +79,7 @@ export class TagAddedEvent extends ArenaEvent {
this.arenaTagMaxLayers = arenaTagMaxLayers!; // TODO: is this bang correct? this.arenaTagMaxLayers = arenaTagMaxLayers!; // TODO: is this bang correct?
} }
} }
/** /** Container class for {@linkcode ArenaEventType.TAG_REMOVED} events */
* Container class for {@linkcode ArenaEventType.TAG_REMOVED} events
* @extends ArenaEvent
*/
export class TagRemovedEvent extends ArenaEvent { export class TagRemovedEvent extends ArenaEvent {
/** The {@linkcode ArenaTagType} being removed */ /** The {@linkcode ArenaTagType} being removed */
public arenaTagType: ArenaTagType; public arenaTagType: ArenaTagType;

View File

@ -43,10 +43,7 @@ export enum BattleSceneEventType {
NEW_ARENA = "onNewArena", NEW_ARENA = "onNewArena",
} }
/** /** Container class for {@linkcode BattleSceneEventType.CANDY_UPGRADE_NOTIFICATION_CHANGED} events */
* Container class for {@linkcode BattleSceneEventType.CANDY_UPGRADE_NOTIFICATION_CHANGED} events
* @extends Event
*/
export class CandyUpgradeNotificationChangedEvent extends Event { export class CandyUpgradeNotificationChangedEvent extends Event {
/** The new value the setting was changed to */ /** The new value the setting was changed to */
public newValue: number; public newValue: number;
@ -57,10 +54,7 @@ export class CandyUpgradeNotificationChangedEvent extends Event {
} }
} }
/** /** Container class for {@linkcode BattleSceneEventType.MOVE_USED} events */
* Container class for {@linkcode BattleSceneEventType.MOVE_USED} events
* @extends Event
*/
export class MoveUsedEvent extends Event { export class MoveUsedEvent extends Event {
/** The ID of the {@linkcode Pokemon} that used the {@linkcode Move} */ /** The ID of the {@linkcode Pokemon} that used the {@linkcode Move} */
public pokemonId: number; public pokemonId: number;
@ -76,10 +70,7 @@ export class MoveUsedEvent extends Event {
this.ppUsed = ppUsed; this.ppUsed = ppUsed;
} }
} }
/** /** Container class for {@linkcode BattleSceneEventType.BERRY_USED} events */
* Container class for {@linkcode BattleSceneEventType.BERRY_USED} events
* @extends Event
*/
export class BerryUsedEvent extends Event { export class BerryUsedEvent extends Event {
/** The {@linkcode BerryModifier} being used */ /** The {@linkcode BerryModifier} being used */
public berryModifier: BerryModifier; public berryModifier: BerryModifier;
@ -90,28 +81,19 @@ export class BerryUsedEvent extends Event {
} }
} }
/** /** Container class for {@linkcode BattleSceneEventType.ENCOUNTER_PHASE} events */
* Container class for {@linkcode BattleSceneEventType.ENCOUNTER_PHASE} events
* @extends Event
*/
export class EncounterPhaseEvent extends Event { export class EncounterPhaseEvent extends Event {
constructor() { constructor() {
super(BattleSceneEventType.ENCOUNTER_PHASE); super(BattleSceneEventType.ENCOUNTER_PHASE);
} }
} }
/** /** Container class for {@linkcode BattleSceneEventType.TURN_INIT} events */
* Container class for {@linkcode BattleSceneEventType.TURN_INIT} events
* @extends Event
*/
export class TurnInitEvent extends Event { export class TurnInitEvent extends Event {
constructor() { constructor() {
super(BattleSceneEventType.TURN_INIT); super(BattleSceneEventType.TURN_INIT);
} }
} }
/** /** Container class for {@linkcode BattleSceneEventType.TURN_END} events */
* Container class for {@linkcode BattleSceneEventType.TURN_END} events
* @extends Event
*/
export class TurnEndEvent extends Event { export class TurnEndEvent extends Event {
/** The amount of turns in the current battle */ /** The amount of turns in the current battle */
public turnCount: number; public turnCount: number;
@ -121,10 +103,7 @@ export class TurnEndEvent extends Event {
this.turnCount = turnCount; this.turnCount = turnCount;
} }
} }
/** /** Container class for {@linkcode BattleSceneEventType.NEW_ARENA} events */
* Container class for {@linkcode BattleSceneEventType.NEW_ARENA} events
* @extends Event
*/
export class NewArenaEvent extends Event { export class NewArenaEvent extends Event {
constructor() { constructor() {
super(BattleSceneEventType.NEW_ARENA); super(BattleSceneEventType.NEW_ARENA);

View File

@ -8,7 +8,6 @@ export enum EggEventType {
/** /**
* Container class for {@linkcode EggEventType.EGG_COUNT_CHANGED} events * Container class for {@linkcode EggEventType.EGG_COUNT_CHANGED} events
* @extends Event
*/ */
export class EggCountChangedEvent extends Event { export class EggCountChangedEvent extends Event {
/** The updated egg count. */ /** The updated egg count. */

View File

@ -732,14 +732,12 @@ export class Arena {
* Attempt to get a tag from the Arena via {@linkcode getTagOnSide} that applies to both sides * Attempt to get a tag from the Arena via {@linkcode getTagOnSide} that applies to both sides
* @param tagType - The {@linkcode ArenaTagType} to retrieve * @param tagType - The {@linkcode ArenaTagType} to retrieve
* @returns The existing {@linkcode ArenaTag}, or `undefined` if not present. * @returns The existing {@linkcode ArenaTag}, or `undefined` if not present.
* @overload
*/ */
getTag(tagType: ArenaTagType): ArenaTag | undefined; getTag(tagType: ArenaTagType): ArenaTag | undefined;
/** /**
* Attempt to get a tag from the Arena via {@linkcode getTagOnSide} that applies to both sides * Attempt to get a tag from the Arena via {@linkcode getTagOnSide} that applies to both sides
* @param tagType - The constructor of the {@linkcode ArenaTag} to retrieve * @param tagType - The constructor of the {@linkcode ArenaTag} to retrieve
* @returns The existing {@linkcode ArenaTag}, or `undefined` if not present. * @returns The existing {@linkcode ArenaTag}, or `undefined` if not present.
* @overload
*/ */
getTag<T extends ArenaTag>(tagType: Constructor<T> | AbstractConstructor<T>): T | undefined; getTag<T extends ArenaTag>(tagType: Constructor<T> | AbstractConstructor<T>): T | undefined;
getTag(tagType: ArenaTagType | Constructor<ArenaTag> | AbstractConstructor<ArenaTag>): ArenaTag | undefined { getTag(tagType: ArenaTagType | Constructor<ArenaTag> | AbstractConstructor<ArenaTag>): ArenaTag | undefined {

View File

@ -137,18 +137,18 @@ import { loadMoveAnimations } from "#sprites/pokemon-asset-loader";
import type { Variant } from "#sprites/variant"; import type { Variant } from "#sprites/variant";
import { populateVariantColors, variantColorCache, variantData } from "#sprites/variant"; import { populateVariantColors, variantColorCache, variantData } from "#sprites/variant";
import { achvs } from "#system/achv"; import { achvs } from "#system/achv";
import type { StarterDataEntry, StarterMoveset } from "#system/game-data";
import type { PokemonData } from "#system/pokemon-data"; import type { PokemonData } from "#system/pokemon-data";
import { RibbonData } from "#system/ribbons/ribbon-data"; import { RibbonData } from "#system/ribbons/ribbon-data";
import { awardRibbonsToSpeciesLine } from "#system/ribbons/ribbon-methods"; import { awardRibbonsToSpeciesLine } from "#system/ribbons/ribbon-methods";
import type { AbAttrMap, AbAttrString, TypeMultiplierAbAttrParams } from "#types/ability-types"; import type { AbAttrMap, AbAttrString, TypeMultiplierAbAttrParams } from "#types/ability-types";
import type { DamageCalculationResult, DamageResult } from "#types/damage-result"; import type { DamageCalculationResult, DamageResult } from "#types/damage-result";
import type { IllusionData } from "#types/illusion-data"; import type { IllusionData } from "#types/illusion-data";
import type { StarterDataEntry, StarterMoveset } from "#types/save-data";
import type { TurnMove } from "#types/turn-move"; import type { TurnMove } from "#types/turn-move";
import { BattleInfo } from "#ui/battle-info"; import { BattleInfo } from "#ui/battle-info";
import { EnemyBattleInfo } from "#ui/enemy-battle-info"; import { EnemyBattleInfo } from "#ui/enemy-battle-info";
import type { PartyOption } from "#ui/handlers/party-ui-handler"; import type { PartyOption } from "#ui/party-ui-handler";
import { PartyUiHandler, PartyUiMode } from "#ui/handlers/party-ui-handler"; import { PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler";
import { PlayerBattleInfo } from "#ui/player-battle-info"; import { PlayerBattleInfo } from "#ui/player-battle-info";
import { applyChallenges } from "#utils/challenge-utils"; import { applyChallenges } from "#utils/challenge-utils";
import { import {
@ -2647,11 +2647,11 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
/** /**
* Gets all level up moves in a given range for a particular pokemon. * Gets all level up moves in a given range for a particular pokemon.
* @param {number} startingLevel Don't include moves below this level * @param startingLevel Don't include moves below this level
* @param {boolean} includeEvolutionMoves Whether to include evolution moves * @param includeEvolutionMoves Whether to include evolution moves
* @param {boolean} simulateEvolutionChain Whether to include moves from prior evolutions * @param simulateEvolutionChain Whether to include moves from prior evolutions
* @param {boolean} includeRelearnerMoves Whether to include moves that would require a relearner. Note the move relearner inherently allows evolution moves * @param includeRelearnerMoves Whether to include moves that would require a relearner. Note the move relearner inherently allows evolution moves
* @returns {LevelMoves} A list of moves and the levels they can be learned at * @returns A list of moves and the levels they can be learned at
*/ */
getLevelMoves( getLevelMoves(
startingLevel?: number, startingLevel?: number,
@ -3209,9 +3209,55 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
Math.ceil(Math.pow(m[1], weightMultiplier) * 100), Math.ceil(Math.pow(m[1], weightMultiplier) * 100),
]); ]);
const STAB_BLACKLIST: ReadonlySet<MoveId> = 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 // All Pokemon force a STAB move first
const stabMovePool = baseWeights.filter( const stabMovePool = baseWeights.filter(
m => allMoves[m[0]].category !== MoveCategory.STATUS && this.isOfType(allMoves[m[0]].type), m =>
allMoves[m[0]].category !== MoveCategory.STATUS
&& this.isOfType(allMoves[m[0]].type)
&& !STAB_BLACKLIST.has(m[0]),
); );
if (stabMovePool.length > 0) { if (stabMovePool.length > 0) {
@ -3224,7 +3270,9 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
this.moveset.push(new PokemonMove(stabMovePool[index][0])); this.moveset.push(new PokemonMove(stabMovePool[index][0]));
} else { } else {
// If there are no damaging STAB moves, just force a random damaging move // If there are no damaging STAB moves, just force a random damaging move
const attackMovePool = baseWeights.filter(m => allMoves[m[0]].category !== MoveCategory.STATUS); const attackMovePool = baseWeights.filter(
m => allMoves[m[0]].category !== MoveCategory.STATUS && !STAB_BLACKLIST.has(m[0]),
);
if (attackMovePool.length > 0) { if (attackMovePool.length > 0) {
const totalWeight = attackMovePool.reduce((v, m) => v + m[1], 0); const totalWeight = attackMovePool.reduce((v, m) => v + m[1], 0);
let rand = randSeedInt(totalWeight); let rand = randSeedInt(totalWeight);
@ -3261,7 +3309,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
} else if (allMoves[m[0]].category !== MoveCategory.STATUS) { } else if (allMoves[m[0]].category !== MoveCategory.STATUS) {
ret = Math.ceil( ret = Math.ceil(
(m[1] / Math.max(Math.pow(4, this.moveset.filter(mo => (mo.getMove().power ?? 0) > 1).length) / 8, 0.5)) (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) ? 20 : 1), * (this.isOfType(allMoves[m[0]].type) && !STAB_BLACKLIST.has(m[0]) ? 20 : 1),
); );
} else { } else {
ret = m[1]; ret = m[1];
@ -3448,7 +3496,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
* @param isCritical determines whether a critical hit has occurred or not (`false` by default) * @param isCritical determines whether a critical hit has occurred or not (`false` by default)
* @param simulated determines whether effects are applied without altering game state (`true` by default) * @param simulated determines whether effects are applied without altering game state (`true` by default)
* @param ignoreHeldItems determines whether this Pokemon's held items should be ignored during the stat calculation, default `false` * @param ignoreHeldItems determines whether this Pokemon's held items should be ignored during the stat calculation, default `false`
* @return the stat stage multiplier to be used for effective stat calculation * @returns the stat stage multiplier to be used for effective stat calculation
*/ */
getStatStageMultiplier( getStatStageMultiplier(
stat: EffectiveStat, stat: EffectiveStat,
@ -3504,8 +3552,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
* This method considers various factors such as the user's accuracy level, the target's evasion level, * This method considers various factors such as the user's accuracy level, the target's evasion level,
* abilities, and modifiers to compute the final accuracy multiplier. * abilities, and modifiers to compute the final accuracy multiplier.
* *
* @param target {@linkcode Pokemon} - The target Pokémon against which the move is used. * @param target - The target Pokémon against which the move is used.
* @param sourceMove {@linkcode Move} - The move being used by the user. * @param sourceMove - The move being used by the user.
* @returns The calculated accuracy multiplier. * @returns The calculated accuracy multiplier.
*/ */
getAccuracyMultiplier(target: Pokemon, sourceMove: Move): number { getAccuracyMultiplier(target: Pokemon, sourceMove: Move): number {
@ -4020,7 +4068,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
*/ */
getCriticalHitResult(source: Pokemon, move: Move): boolean { getCriticalHitResult(source: Pokemon, move: Move): boolean {
if (move.hasAttr("FixedDamageAttr")) { if (move.hasAttr("FixedDamageAttr")) {
// fixed damage moves (Dragon Rage, etc.) will nevet crit // fixed damage moves (Dragon Rage, etc.) will never crit
return false; return false;
} }
@ -4244,18 +4292,10 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
return false; return false;
} }
/**@overload */
getTag(tagType: BattlerTagType.GRUDGE): GrudgeTag | undefined; getTag(tagType: BattlerTagType.GRUDGE): GrudgeTag | undefined;
/** @overload */
getTag(tagType: BattlerTagType.SUBSTITUTE): SubstituteTag | undefined; getTag(tagType: BattlerTagType.SUBSTITUTE): SubstituteTag | undefined;
/** @overload */
getTag(tagType: BattlerTagType): BattlerTag | undefined; getTag(tagType: BattlerTagType): BattlerTag | undefined;
/** @overload */
getTag<T extends BattlerTag>(tagType: Constructor<T>): T | undefined; getTag<T extends BattlerTag>(tagType: Constructor<T>): T | undefined;
getTag(tagType: BattlerTagType | Constructor<BattlerTag>): BattlerTag | undefined { getTag(tagType: BattlerTagType | Constructor<BattlerTag>): BattlerTag | undefined {
return typeof tagType === "function" return typeof tagType === "function"
? this.summonData.tags.find(t => t instanceof tagType) ? this.summonData.tags.find(t => t instanceof tagType)
@ -4403,7 +4443,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
* @param user - The move user * @param user - The move user
* @param target - The target of the move * @param target - The target of the move
* *
* @returns {boolean} `true` if the move is disabled for this Pokemon due to the player's target selection * @returns `true` if the move is disabled for this Pokemon due to the player's target selection
* *
* @see {@linkcode MoveRestrictionBattlerTag} * @see {@linkcode MoveRestrictionBattlerTag}
*/ */
@ -5195,7 +5235,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
/** /**
* Reset a {@linkcode Pokemon}'s {@linkcode PokemonWaveData | waveData}. * Reset a {@linkcode Pokemon}'s {@linkcode PokemonWaveData | waveData}.
* Should be called upon starting a new wave in addition to whenever an arena transition occurs. * Should be called upon starting a new wave in addition to whenever an arena transition occurs.
* @see {@linkcode resetBattleAndWaveData()} * @see {@linkcode resetBattleAndWaveData}
*/ */
resetWaveData(): void { resetWaveData(): void {
this.waveData = new PokemonWaveData(); this.waveData = new PokemonWaveData();
@ -5630,7 +5670,6 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
/** /**
* Generates a random number using the current battle's seed, or the global seed if `globalScene.currentBattle` is falsy * Generates a random number using the current battle's seed, or the global seed if `globalScene.currentBattle` is falsy
* <!-- @import "../battle".Battle -->
* This calls either {@linkcode BattleScene.randBattleSeedInt}({@linkcode range}, {@linkcode min}) in `src/battle-scene.ts` * This calls either {@linkcode BattleScene.randBattleSeedInt}({@linkcode range}, {@linkcode min}) in `src/battle-scene.ts`
* which calls {@linkcode Battle.randSeedInt}({@linkcode range}, {@linkcode min}) in `src/battle.ts` * which calls {@linkcode Battle.randSeedInt}({@linkcode range}, {@linkcode min}) in `src/battle.ts`
* which calls {@linkcode randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts`, * which calls {@linkcode randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts`,

View File

@ -315,8 +315,8 @@ export class GameMode implements GameModeConfig {
/** /**
* Checks whether there is a fixed battle on this gamemode on a given wave. * Checks whether there is a fixed battle on this gamemode on a given wave.
* @param {number} waveIndex The wave to check. * @param waveIndex The wave to check.
* @returns {boolean} If this game mode has a fixed battle on this wave * @returns If this game mode has a fixed battle on this wave
*/ */
isFixedBattle(waveIndex: number): boolean { isFixedBattle(waveIndex: number): boolean {
const dummyConfig = new FixedBattleConfig(); const dummyConfig = new FixedBattleConfig();
@ -328,8 +328,8 @@ export class GameMode implements GameModeConfig {
/** /**
* Returns the config for the fixed battle for a particular wave. * Returns the config for the fixed battle for a particular wave.
* @param {number} waveIndex The wave to check. * @param waveIndex The wave to check.
* @returns {boolean} The fixed battle for this wave. * @returns The fixed battle for this wave.
*/ */
getFixedBattle(waveIndex: number): FixedBattleConfig { getFixedBattle(waveIndex: number): FixedBattleConfig {
const challengeConfig = new FixedBattleConfig(); const challengeConfig = new FixedBattleConfig();

View File

@ -11,7 +11,7 @@ import { initMoves } from "#moves/move";
import { initMysteryEncounters } from "#mystery-encounters/mystery-encounters"; import { initMysteryEncounters } from "#mystery-encounters/mystery-encounters";
import { initAchievements } from "#system/achv"; import { initAchievements } from "#system/achv";
import { initVouchers } from "#system/voucher"; 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. */ /** Initialize the game. */
export function initializeGame() { export function initializeGame() {

View File

@ -154,6 +154,7 @@ export class LoadingScene extends SceneBase {
this.loadImage("select_gen_cursor", "ui"); this.loadImage("select_gen_cursor", "ui");
this.loadImage("select_gen_cursor_highlight", "ui"); this.loadImage("select_gen_cursor_highlight", "ui");
this.loadImage("language_icon", "ui");
this.loadImage("saving_icon", "ui"); this.loadImage("saving_icon", "ui");
this.loadImage("discord", "ui"); this.loadImage("discord", "ui");
this.loadImage("google", "ui"); this.loadImage("google", "ui");

View File

@ -6,8 +6,8 @@ import i18next from "i18next";
/** /**
* Retrieves the Pokemon's name, potentially with an affix indicating its role (wild or foe) in the current battle context, translated * Retrieves the Pokemon's name, potentially with an affix indicating its role (wild or foe) in the current battle context, translated
* @param pokemon {@linkcode Pokemon} name and battle context will be retrieved from this instance * @param pokemon {@linkcode Pokemon} name and battle context will be retrieved from this instance
* @param {boolean} useIllusion - Whether we want the name of the illusion or not. Default value : true * @param useIllusion - Whether we want the name of the illusion or not. Default value : true
* @returns {string} ex: "Wild Gengar", "Ectoplasma sauvage" * @returns ex: "Wild Gengar", "Ectoplasma sauvage"
*/ */
export function getPokemonNameWithAffix(pokemon: Pokemon | undefined, useIllusion = true): string { export function getPokemonNameWithAffix(pokemon: Pokemon | undefined, useIllusion = true): string {
if (!pokemon) { if (!pokemon) {

View File

@ -115,8 +115,8 @@ import {
import type { PokemonMove } from "#moves/pokemon-move"; import type { PokemonMove } from "#moves/pokemon-move";
import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "#system/voucher"; import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "#system/voucher";
import type { ModifierTypeFunc, WeightedModifierTypeWeightFunc } from "#types/modifier-types"; import type { ModifierTypeFunc, WeightedModifierTypeWeightFunc } from "#types/modifier-types";
import type { PokemonMoveSelectFilter, PokemonSelectFilter } from "#ui/handlers/party-ui-handler"; import type { PokemonMoveSelectFilter, PokemonSelectFilter } from "#ui/party-ui-handler";
import { PartyUiHandler } from "#ui/handlers/party-ui-handler"; import { PartyUiHandler } from "#ui/party-ui-handler";
import { getModifierTierTextTint } from "#ui/text"; import { getModifierTierTextTint } from "#ui/text";
import { applyChallenges } from "#utils/challenge-utils"; import { applyChallenges } from "#utils/challenge-utils";
import { import {
@ -150,7 +150,7 @@ export class ModifierType {
/** /**
* Checks if the modifier type is of a specific type * Checks if the modifier type is of a specific type
* @param modifierType - The type to check against * @param modifierType - The type to check against
* @return Whether the modifier type is of the specified type * @returns Whether the modifier type is of the specified type
*/ */
public is<K extends ModifierTypeString>(modifierType: K): this is ModifierTypeInstanceMap[K] { public is<K extends ModifierTypeString>(modifierType: K): this is ModifierTypeInstanceMap[K] {
const targetType = ModifierTypeConstructorMap[modifierType]; const targetType = ModifierTypeConstructorMap[modifierType];
@ -874,11 +874,7 @@ export class AttackTypeBoosterModifierType
export type SpeciesStatBoosterItem = keyof typeof SpeciesStatBoosterModifierTypeGenerator.items; export type SpeciesStatBoosterItem = keyof typeof SpeciesStatBoosterModifierTypeGenerator.items;
/** /** Modifier type for {@linkcode SpeciesStatBoosterModifier} */
* Modifier type for {@linkcode SpeciesStatBoosterModifier}
* @extends PokemonHeldItemModifierType
* @implements GeneratedPersistentModifierType
*/
export class SpeciesStatBoosterModifierType export class SpeciesStatBoosterModifierType
extends PokemonHeldItemModifierType extends PokemonHeldItemModifierType
implements GeneratedPersistentModifierType implements GeneratedPersistentModifierType
@ -1396,7 +1392,6 @@ class TempStatStageBoosterModifierTypeGenerator extends ModifierTypeGenerator {
* Modifier type generator for {@linkcode SpeciesStatBoosterModifierType}, which * Modifier type generator for {@linkcode SpeciesStatBoosterModifierType}, which
* encapsulates the logic for weighting the most useful held item from * encapsulates the logic for weighting the most useful held item from
* the current list of {@linkcode items}. * the current list of {@linkcode items}.
* @extends ModifierTypeGenerator
*/ */
class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator { class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator {
/** Object comprised of the currently available species-based stat boosting held items */ /** Object comprised of the currently available species-based stat boosting held items */

View File

@ -73,8 +73,8 @@ export class ModifierBar extends Phaser.GameObjects.Container {
/** /**
* Method to update content displayed in {@linkcode ModifierBar} * Method to update content displayed in {@linkcode ModifierBar}
* @param {PersistentModifier[]} modifiers - The list of modifiers to be displayed in the {@linkcode ModifierBar} * @param modifiers - The list of modifiers to be displayed in the {@linkcode ModifierBar}
* @param {boolean} hideHeldItems - If set to "true", only modifiers not assigned to a Pokémon are displayed * @param hideHeldItems - If set to "true", only modifiers not assigned to a Pokémon are displayed
*/ */
updateModifiers(modifiers: PersistentModifier[], hideHeldItems = false) { updateModifiers(modifiers: PersistentModifier[], hideHeldItems = false) {
this.removeAll(true); this.removeAll(true);
@ -345,9 +345,6 @@ export class AddVoucherModifier extends ConsumableModifier {
* modifier will be removed. If a modifier of the same type is to be added, it * modifier will be removed. If a modifier of the same type is to be added, it
* will reset {@linkcode battleCount} back to {@linkcode maxBattles} of the * will reset {@linkcode battleCount} back to {@linkcode maxBattles} of the
* existing modifier instead of adding that modifier directly. * existing modifier instead of adding that modifier directly.
* @extends PersistentModifier
* @abstract
* @see {@linkcode add}
*/ */
export abstract class LapsingPersistentModifier extends PersistentModifier { export abstract class LapsingPersistentModifier extends PersistentModifier {
/** The maximum amount of battles the modifier will exist for */ /** The maximum amount of battles the modifier will exist for */
@ -458,8 +455,6 @@ export abstract class LapsingPersistentModifier extends PersistentModifier {
/** /**
* Modifier used for passive items, specifically lures, that * Modifier used for passive items, specifically lures, that
* temporarily increases the chance of a double battle. * temporarily increases the chance of a double battle.
* @extends LapsingPersistentModifier
* @see {@linkcode apply}
*/ */
export class DoubleBattleChanceBoosterModifier extends LapsingPersistentModifier { export class DoubleBattleChanceBoosterModifier extends LapsingPersistentModifier {
public declare type: DoubleBattleChanceBoosterModifierType; public declare type: DoubleBattleChanceBoosterModifierType;
@ -495,8 +490,6 @@ export class DoubleBattleChanceBoosterModifier extends LapsingPersistentModifier
* Modifier used for party-wide items, specifically the X items, that * Modifier used for party-wide items, specifically the X items, that
* temporarily increases the stat stage multiplier of the corresponding * temporarily increases the stat stage multiplier of the corresponding
* {@linkcode TempBattleStat}. * {@linkcode TempBattleStat}.
* @extends LapsingPersistentModifier
* @see {@linkcode apply}
*/ */
export class TempStatStageBoosterModifier extends LapsingPersistentModifier { export class TempStatStageBoosterModifier extends LapsingPersistentModifier {
/** The stat whose stat stage multiplier will be temporarily increased */ /** The stat whose stat stage multiplier will be temporarily increased */
@ -562,8 +555,6 @@ export class TempStatStageBoosterModifier extends LapsingPersistentModifier {
/** /**
* Modifier used for party-wide items, namely Dire Hit, that * Modifier used for party-wide items, namely Dire Hit, that
* temporarily increments the critical-hit stage * temporarily increments the critical-hit stage
* @extends LapsingPersistentModifier
* @see {@linkcode apply}
*/ */
export class TempCritBoosterModifier extends LapsingPersistentModifier { export class TempCritBoosterModifier extends LapsingPersistentModifier {
clone() { clone() {
@ -818,8 +809,6 @@ export abstract class LapsingPokemonHeldItemModifier extends PokemonHeldItemModi
/** /**
* Modifier used for held items, specifically vitamins like Carbos, Hp Up, etc., that * Modifier used for held items, specifically vitamins like Carbos, Hp Up, etc., that
* increase the value of a given {@linkcode PermanentStat}. * increase the value of a given {@linkcode PermanentStat}.
* @extends PokemonHeldItemModifier
* @see {@linkcode apply}
*/ */
export class BaseStatModifier extends PokemonHeldItemModifier { export class BaseStatModifier extends PokemonHeldItemModifier {
protected stat: PermanentStat; protected stat: PermanentStat;
@ -1126,8 +1115,6 @@ export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier {
/** /**
* Modifier used for held items that Applies {@linkcode Stat} boost(s) * Modifier used for held items that Applies {@linkcode Stat} boost(s)
* using a multiplier. * using a multiplier.
* @extends PokemonHeldItemModifier
* @see {@linkcode apply}
*/ */
export class StatBoosterModifier extends PokemonHeldItemModifier { export class StatBoosterModifier extends PokemonHeldItemModifier {
/** The stats that the held item boosts */ /** The stats that the held item boosts */
@ -1194,8 +1181,6 @@ export class StatBoosterModifier extends PokemonHeldItemModifier {
/** /**
* Modifier used for held items, specifically Eviolite, that apply * Modifier used for held items, specifically Eviolite, that apply
* {@linkcode Stat} boost(s) using a multiplier if the holder can evolve. * {@linkcode Stat} boost(s) using a multiplier if the holder can evolve.
* @extends StatBoosterModifier
* @see {@linkcode apply}
*/ */
export class EvolutionStatBoosterModifier extends StatBoosterModifier { export class EvolutionStatBoosterModifier extends StatBoosterModifier {
matchType(modifier: Modifier): boolean { matchType(modifier: Modifier): boolean {
@ -1216,13 +1201,16 @@ export class EvolutionStatBoosterModifier extends StatBoosterModifier {
/** /**
* Boosts the incoming stat value by a {@linkcode EvolutionStatBoosterModifier.multiplier} if the holder * Boosts the incoming stat value by a {@linkcode EvolutionStatBoosterModifier.multiplier} if the holder
* can evolve. Note that, if the holder is a fusion, they will receive * can evolve
*
* @remarks
* Note that, if the holder is a fusion, they will receive
* only half of the boost if either of the fused members are fully * only half of the boost if either of the fused members are fully
* evolved. However, if they are both unevolved, the full boost * evolved. However, if they are both unevolved, the full boost
* will apply. * will apply.
* @param pokemon {@linkcode Pokemon} that holds the item * @param pokemon - The `Pokemon` holding the item
* @param _stat {@linkcode Stat} The {@linkcode Stat} to be boosted * @param _stat - The `Stat` to be boosted
* @param statValue{@linkcode NumberHolder} that holds the resulting value of the stat * @param statValue - Holds the resulting value of the stat
* @returns `true` if the stat boost applies successfully, false otherwise * @returns `true` if the stat boost applies successfully, false otherwise
* @see shouldApply * @see shouldApply
*/ */
@ -1246,8 +1234,6 @@ export class EvolutionStatBoosterModifier extends StatBoosterModifier {
/** /**
* Modifier used for held items that Applies {@linkcode Stat} boost(s) using a * Modifier used for held items that Applies {@linkcode Stat} boost(s) using a
* multiplier if the holder is of a specific {@linkcode SpeciesId}. * multiplier if the holder is of a specific {@linkcode SpeciesId}.
* @extends StatBoosterModifier
* @see {@linkcode apply}
*/ */
export class SpeciesStatBoosterModifier extends StatBoosterModifier { export class SpeciesStatBoosterModifier extends StatBoosterModifier {
/** The species that the held item's stat boost(s) apply to */ /** The species that the held item's stat boost(s) apply to */
@ -1321,8 +1307,6 @@ export class SpeciesStatBoosterModifier extends StatBoosterModifier {
/** /**
* Modifier used for held items that apply critical-hit stage boost(s). * Modifier used for held items that apply critical-hit stage boost(s).
* @extends PokemonHeldItemModifier
* @see {@linkcode apply}
*/ */
export class CritBoosterModifier extends PokemonHeldItemModifier { export class CritBoosterModifier extends PokemonHeldItemModifier {
/** The amount of stages by which the held item increases the current critical-hit stage value */ /** The amount of stages by which the held item increases the current critical-hit stage value */
@ -1369,8 +1353,6 @@ export class CritBoosterModifier extends PokemonHeldItemModifier {
/** /**
* Modifier used for held items that apply critical-hit stage boost(s) * Modifier used for held items that apply critical-hit stage boost(s)
* if the holder is of a specific {@linkcode SpeciesId}. * if the holder is of a specific {@linkcode SpeciesId}.
* @extends CritBoosterModifier
* @see {@linkcode shouldApply}
*/ */
export class SpeciesCritBoosterModifier extends CritBoosterModifier { export class SpeciesCritBoosterModifier extends CritBoosterModifier {
/** The species that the held item's critical-hit stage boost applies to */ /** The species that the held item's critical-hit stage boost applies to */
@ -1694,8 +1676,6 @@ export class TurnHealModifier extends PokemonHeldItemModifier {
/** /**
* Modifier used for held items, namely Toxic Orb and Flame Orb, that apply a * Modifier used for held items, namely Toxic Orb and Flame Orb, that apply a
* set {@linkcode StatusEffect} at the end of a turn. * set {@linkcode StatusEffect} at the end of a turn.
* @extends PokemonHeldItemModifier
* @see {@linkcode apply}
*/ */
export class TurnStatusEffectModifier extends PokemonHeldItemModifier { export class TurnStatusEffectModifier extends PokemonHeldItemModifier {
/** The status effect to be applied by the held item */ /** The status effect to be applied by the held item */
@ -1721,7 +1701,7 @@ export class TurnStatusEffectModifier extends PokemonHeldItemModifier {
* would be the only item able to {@linkcode apply} successfully. * would be the only item able to {@linkcode apply} successfully.
* @override * @override
* @param modifier {@linkcode Modifier} being type tested * @param modifier {@linkcode Modifier} being type tested
* @return `true` if {@linkcode modifier} is an instance of * @returns `true` if {@linkcode modifier} is an instance of
* TurnStatusEffectModifier, false otherwise * TurnStatusEffectModifier, false otherwise
*/ */
matchType(modifier: Modifier): boolean { matchType(modifier: Modifier): boolean {
@ -1966,8 +1946,6 @@ export class PokemonInstantReviveModifier extends PokemonHeldItemModifier {
/** /**
* Modifier used for held items, namely White Herb, that restore adverse stat * Modifier used for held items, namely White Herb, that restore adverse stat
* stages in battle. * stages in battle.
* @extends PokemonHeldItemModifier
* @see {@linkcode apply}
*/ */
export class ResetNegativeStatStageModifier extends PokemonHeldItemModifier { export class ResetNegativeStatStageModifier extends PokemonHeldItemModifier {
matchType(modifier: Modifier) { matchType(modifier: Modifier) {
@ -2013,8 +1991,6 @@ export class ResetNegativeStatStageModifier extends PokemonHeldItemModifier {
/** /**
* Modifier used for held items, namely Mystical Rock, that extend the * Modifier used for held items, namely Mystical Rock, that extend the
* duration of weather and terrain effects. * duration of weather and terrain effects.
* @extends PokemonHeldItemModifier
* @see {@linkcode apply}
*/ */
export class FieldEffectModifier extends PokemonHeldItemModifier { export class FieldEffectModifier extends PokemonHeldItemModifier {
/** /**
@ -3400,8 +3376,6 @@ export class ExtraModifierModifier extends PersistentModifier {
/** /**
* Modifier used for timed boosts to the player's shop item rewards. * Modifier used for timed boosts to the player's shop item rewards.
* @extends LapsingPersistentModifier
* @see {@linkcode apply}
*/ */
export class TempExtraModifierModifier extends LapsingPersistentModifier { export class TempExtraModifierModifier extends LapsingPersistentModifier {
/** /**

View File

@ -21,9 +21,9 @@ import type { EnemyPokemon } from "#field/pokemon";
import { PokemonHeldItemModifier } from "#modifiers/modifier"; import { PokemonHeldItemModifier } from "#modifiers/modifier";
import { PokemonPhase } from "#phases/pokemon-phase"; import { PokemonPhase } from "#phases/pokemon-phase";
import { achvs } from "#system/achv"; import { achvs } from "#system/achv";
import type { PartyOption } from "#ui/handlers/party-ui-handler"; import type { PartyOption } from "#ui/party-ui-handler";
import { PartyUiMode } from "#ui/handlers/party-ui-handler"; import { PartyUiMode } from "#ui/party-ui-handler";
import { SummaryUiMode } from "#ui/handlers/summary-ui-handler"; import { SummaryUiMode } from "#ui/summary-ui-handler";
import { applyChallenges } from "#utils/challenge-utils"; import { applyChallenges } from "#utils/challenge-utils";
import { BooleanHolder } from "#utils/common"; import { BooleanHolder } from "#utils/common";
import i18next from "i18next"; import i18next from "i18next";

View File

@ -215,7 +215,7 @@ export class CommandPhase extends FieldPhase {
if (!moveStatus.value) { if (!moveStatus.value) {
cannotSelectKey = "battle:moveCannotUseChallenge"; cannotSelectKey = "battle:moveCannotUseChallenge";
} else if (move.getPpRatio() === 0) { } else if (move.getPpRatio() === 0) {
cannotSelectKey = "battle:moveNoPP"; cannotSelectKey = "battle:moveNoPp";
} else if (move.getName().endsWith(" (N)")) { } else if (move.getName().endsWith(" (N)")) {
cannotSelectKey = "battle:moveNotImplemented"; cannotSelectKey = "battle:moveNotImplemented";
} else if (user.isMoveRestricted(move.moveId, user)) { } else if (user.isMoveRestricted(move.moveId, user)) {

View File

@ -9,9 +9,9 @@ import { doShinySparkleAnim } from "#field/anims";
import type { PlayerPokemon } from "#field/pokemon"; import type { PlayerPokemon } from "#field/pokemon";
import type { EggLapsePhase } from "#phases/egg-lapse-phase"; import type { EggLapsePhase } from "#phases/egg-lapse-phase";
import { achvs } from "#system/achv"; import { achvs } from "#system/achv";
import { EggCounterContainer } from "#ui/containers/egg-counter-container"; import { EggCounterContainer } from "#ui/egg-counter-container";
import { PokemonInfoContainer } from "#ui/containers/pokemon-info-container"; import type { EggHatchSceneUiHandler } from "#ui/egg-hatch-scene-ui-handler";
import type { EggHatchSceneHandler } from "#ui/handlers/egg-hatch-scene-handler"; import { PokemonInfoContainer } from "#ui/pokemon-info-container";
import { fixedInt, getFrameMs, randInt } from "#utils/common"; import { fixedInt, getFrameMs, randInt } from "#utils/common";
import i18next from "i18next"; import i18next from "i18next";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
@ -32,7 +32,7 @@ export class EggHatchPhase extends Phase {
private eggCounterContainer: EggCounterContainer; private eggCounterContainer: EggCounterContainer;
/** The scene handler for egg hatching */ /** The scene handler for egg hatching */
private eggHatchHandler: EggHatchSceneHandler; private eggHatchHandler: EggHatchSceneUiHandler;
/** The phaser gameobject container that holds everything */ /** The phaser gameobject container that holds everything */
private eggHatchContainer: Phaser.GameObjects.Container; private eggHatchContainer: Phaser.GameObjects.Container;
/** The phaser image that is the background */ /** The phaser image that is the background */
@ -92,7 +92,7 @@ export class EggHatchPhase extends Phase {
globalScene.fadeOutBgm(undefined, false); globalScene.fadeOutBgm(undefined, false);
this.eggHatchHandler = globalScene.ui.getHandler() as EggHatchSceneHandler; this.eggHatchHandler = globalScene.ui.getHandler() as EggHatchSceneUiHandler;
this.eggHatchContainer = this.eggHatchHandler.eggHatchContainer; this.eggHatchContainer = this.eggHatchHandler.eggHatchContainer;

View File

@ -10,7 +10,7 @@ import { LearnMoveSituation } from "#enums/learn-move-situation";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { cos, sin } from "#field/anims"; import { cos, sin } from "#field/anims";
import type { PlayerPokemon, Pokemon } from "#field/pokemon"; import type { PlayerPokemon, Pokemon } from "#field/pokemon";
import type { EvolutionSceneHandler } from "#ui/handlers/evolution-scene-handler"; import type { EvolutionSceneUiHandler } from "#ui/evolution-scene-ui-handler";
import { fixedInt, getFrameMs, randInt } from "#utils/common"; import { fixedInt, getFrameMs, randInt } from "#utils/common";
import i18next from "i18next"; import i18next from "i18next";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
@ -29,7 +29,7 @@ export class EvolutionPhase extends Phase {
private evolution: SpeciesFormEvolution | null; private evolution: SpeciesFormEvolution | null;
private fusionSpeciesEvolved: boolean; // Whether the evolution is of the fused species private fusionSpeciesEvolved: boolean; // Whether the evolution is of the fused species
private evolutionBgm: AnySound | null; private evolutionBgm: AnySound | null;
private evolutionHandler: EvolutionSceneHandler; private evolutionHandler: EvolutionSceneUiHandler;
/** Container for all assets used by the scene. When the scene is cleared, the children within this are destroyed. */ /** Container for all assets used by the scene. When the scene is cleared, the children within this are destroyed. */
protected evolutionContainer: Phaser.GameObjects.Container; protected evolutionContainer: Phaser.GameObjects.Container;
@ -79,7 +79,7 @@ export class EvolutionPhase extends Phase {
* *
*/ */
private setupEvolutionAssets(): void { private setupEvolutionAssets(): void {
this.evolutionHandler = globalScene.ui.getHandler() as EvolutionSceneHandler; this.evolutionHandler = globalScene.ui.getHandler() as EvolutionSceneUiHandler;
this.evolutionContainer = this.evolutionHandler.evolutionContainer; this.evolutionContainer = this.evolutionHandler.evolutionContainer;
this.evolutionBaseBg = globalScene.add.image(0, 0, "default_bg").setOrigin(0); this.evolutionBaseBg = globalScene.add.image(0, 0, "default_bg").setOrigin(0);

View File

@ -8,7 +8,7 @@ import { UiMode } from "#enums/ui-mode";
import type { PlayerPokemon, Pokemon } from "#field/pokemon"; import type { PlayerPokemon, Pokemon } from "#field/pokemon";
import { EvolutionPhase } from "#phases/evolution-phase"; import { EvolutionPhase } from "#phases/evolution-phase";
import { achvs } from "#system/achv"; 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"; import { fixedInt } from "#utils/common";
export class FormChangePhase extends EvolutionPhase { export class FormChangePhase extends EvolutionPhase {

View File

@ -16,13 +16,13 @@ import type { EndCardPhase } from "#phases/end-card-phase";
import { achvs, ChallengeAchv } from "#system/achv"; import { achvs, ChallengeAchv } from "#system/achv";
import { ArenaData } from "#system/arena-data"; import { ArenaData } from "#system/arena-data";
import { ChallengeData } from "#system/challenge-data"; import { ChallengeData } from "#system/challenge-data";
import type { SessionSaveData } from "#system/game-data";
import { ModifierData as PersistentModifierData } from "#system/modifier-data"; import { ModifierData as PersistentModifierData } from "#system/modifier-data";
import { PokemonData } from "#system/pokemon-data"; import { PokemonData } from "#system/pokemon-data";
import { RibbonData, type RibbonFlag } from "#system/ribbons/ribbon-data"; import { RibbonData, type RibbonFlag } from "#system/ribbons/ribbon-data";
import { awardRibbonsToSpeciesLine } from "#system/ribbons/ribbon-methods"; import { awardRibbonsToSpeciesLine } from "#system/ribbons/ribbon-methods";
import { TrainerData } from "#system/trainer-data"; import { TrainerData } from "#system/trainer-data";
import { trainerConfigs } from "#trainers/trainer-config"; import { trainerConfigs } from "#trainers/trainer-config";
import type { SessionSaveData } from "#types/save-data";
import { checkSpeciesValidForChallenge, isNuzlockeChallenge } from "#utils/challenge-utils"; import { checkSpeciesValidForChallenge, isNuzlockeChallenge } from "#utils/challenge-utils";
import { isLocal, isLocalServerConnected } from "#utils/common"; import { isLocal, isLocalServerConnected } from "#utils/common";
import { getPokemonSpecies } from "#utils/pokemon-utils"; import { getPokemonSpecies } from "#utils/pokemon-utils";

View File

@ -10,8 +10,8 @@ import { UiMode } from "#enums/ui-mode";
import type { Pokemon } from "#field/pokemon"; import type { Pokemon } from "#field/pokemon";
import type { Move } from "#moves/move"; import type { Move } from "#moves/move";
import { PlayerPartyMemberPokemonPhase } from "#phases/player-party-member-pokemon-phase"; import { PlayerPartyMemberPokemonPhase } from "#phases/player-party-member-pokemon-phase";
import { EvolutionSceneHandler } from "#ui/handlers/evolution-scene-handler"; import { EvolutionSceneUiHandler } from "#ui/evolution-scene-ui-handler";
import { SummaryUiMode } from "#ui/handlers/summary-ui-handler"; import { SummaryUiMode } from "#ui/summary-ui-handler";
import i18next from "i18next"; import i18next from "i18next";
export class LearnMovePhase extends PlayerPartyMemberPokemonPhase { export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
@ -47,7 +47,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
} }
this.messageMode = this.messageMode =
globalScene.ui.getHandler() instanceof EvolutionSceneHandler ? UiMode.EVOLUTION_SCENE : UiMode.MESSAGE; globalScene.ui.getHandler() instanceof EvolutionSceneUiHandler ? UiMode.EVOLUTION_SCENE : UiMode.MESSAGE;
globalScene.ui.setMode(this.messageMode); globalScene.ui.setMode(this.messageMode);
// If the Pokemon has less than 4 moves, the new move is added to the largest empty moveset index // If the Pokemon has less than 4 moves, the new move is added to the largest empty moveset index
// If it has 4 moves, the phase then checks if the player wants to replace the move itself. // If it has 4 moves, the phase then checks if the player wants to replace the move itself.

View File

@ -289,10 +289,7 @@ export class MysteryEncounterBattlePhase extends Phase {
this.doMysteryEncounterBattle(); this.doMysteryEncounterBattle();
} }
/** /** Get intro battle message for new battle */
* Gets intro battle message for new battle
* @private
*/
private getBattleMessage(): string { private getBattleMessage(): string {
const enemyField = globalScene.getEnemyField(); const enemyField = globalScene.getEnemyField();
const encounterMode = globalScene.currentBattle.mysteryEncounter!.encounterMode; const encounterMode = globalScene.currentBattle.mysteryEncounter!.encounterMode;
@ -323,8 +320,7 @@ export class MysteryEncounterBattlePhase extends Phase {
} }
/** /**
* Queues {@linkcode SummonPhase}s for the new battle, and handles trainer animations/dialogue if it's a Trainer battle * Queue {@linkcode SummonPhase}s for the new battle and handle trainer animations/dialogue for Trainer battles
* @private
*/ */
private doMysteryEncounterBattle() { private doMysteryEncounterBattle() {
const encounterMode = globalScene.currentBattle.mysteryEncounter!.encounterMode; const encounterMode = globalScene.currentBattle.mysteryEncounter!.encounterMode;
@ -401,7 +397,6 @@ export class MysteryEncounterBattlePhase extends Phase {
/** /**
* Initiate {@linkcode SummonPhase}s, {@linkcode ScanIvsPhase}, {@linkcode PostSummonPhase}s, etc. * Initiate {@linkcode SummonPhase}s, {@linkcode ScanIvsPhase}, {@linkcode PostSummonPhase}s, etc.
* @private
*/ */
private endBattleSetup() { private endBattleSetup() {
const enemyField = globalScene.getEnemyField(); const enemyField = globalScene.getEnemyField();
@ -450,10 +445,7 @@ export class MysteryEncounterBattlePhase extends Phase {
this.end(); this.end();
} }
/** /** Ease in enemy trainer */
* Ease in enemy trainer
* @private
*/
private showEnemyTrainer(): void { private showEnemyTrainer(): void {
// Show enemy trainer // Show enemy trainer
const trainer = globalScene.currentBattle.trainer; const trainer = globalScene.currentBattle.trainer;

View File

@ -3,8 +3,8 @@ import { SwitchType } from "#enums/switch-type";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import type { PlayerPokemon } from "#field/pokemon"; import type { PlayerPokemon } from "#field/pokemon";
import { BattlePhase } from "#phases/battle-phase"; import { BattlePhase } from "#phases/battle-phase";
import type { PartyOption } from "#ui/handlers/party-ui-handler"; import type { PartyOption } from "#ui/party-ui-handler";
import { PartyUiHandler, PartyUiMode } from "#ui/handlers/party-ui-handler"; import { PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler";
import { isNullOrUndefined, toDmgValue } from "#utils/common"; import { isNullOrUndefined, toDmgValue } from "#utils/common";
import i18next from "i18next"; import i18next from "i18next";

View File

@ -5,7 +5,7 @@ import { ChallengeType } from "#enums/challenge-type";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { MapModifier, MoneyInterestModifier } from "#modifiers/modifier"; import { MapModifier, MoneyInterestModifier } from "#modifiers/modifier";
import { BattlePhase } from "#phases/battle-phase"; 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 { applyChallenges } from "#utils/challenge-utils";
import { BooleanHolder, randSeedInt } from "#utils/common"; import { BooleanHolder, randSeedInt } from "#utils/common";

View File

@ -24,9 +24,9 @@ import {
TmModifierType, TmModifierType,
} from "#modifiers/modifier-type"; } from "#modifiers/modifier-type";
import { BattlePhase } from "#phases/battle-phase"; import { BattlePhase } from "#phases/battle-phase";
import type { ModifierSelectUiHandler } from "#ui/handlers/modifier-select-ui-handler"; import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler";
import { SHOP_OPTIONS_ROW_LIMIT } from "#ui/handlers/modifier-select-ui-handler"; import { SHOP_OPTIONS_ROW_LIMIT } from "#ui/modifier-select-ui-handler";
import { PartyOption, PartyUiHandler, PartyUiMode } from "#ui/handlers/party-ui-handler"; import { PartyOption, PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler";
import { isNullOrUndefined, NumberHolder } from "#utils/common"; import { isNullOrUndefined, NumberHolder } from "#utils/common";
import i18next from "i18next"; import i18next from "i18next";

View File

@ -7,8 +7,8 @@ import { ChallengeType } from "#enums/challenge-type";
import type { SpeciesId } from "#enums/species-id"; import type { SpeciesId } from "#enums/species-id";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { overrideHeldItems, overrideModifiers } from "#modifiers/modifier"; import { overrideHeldItems, overrideModifiers } from "#modifiers/modifier";
import { SaveSlotUiMode } from "#ui/handlers/save-slot-select-ui-handler"; import { SaveSlotUiMode } from "#ui/save-slot-select-ui-handler";
import type { Starter } from "#ui/handlers/starter-select-ui-handler"; import type { Starter } from "#ui/starter-select-ui-handler";
import { applyChallenges } from "#utils/challenge-utils"; import { applyChallenges } from "#utils/challenge-utils";
import { isNullOrUndefined } from "#utils/common"; import { isNullOrUndefined } from "#utils/common";
import { getPokemonSpecies } from "#utils/pokemon-utils"; import { getPokemonSpecies } from "#utils/pokemon-utils";

View File

@ -3,7 +3,7 @@ import { DynamicPhaseType } from "#enums/dynamic-phase-type";
import { SwitchType } from "#enums/switch-type"; import { SwitchType } from "#enums/switch-type";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { BattlePhase } from "#phases/battle-phase"; 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} * Opens the party selector UI and transitions into a {@linkcode SwitchSummonPhase}

View File

@ -14,10 +14,10 @@ import { Unlockables } from "#enums/unlockables";
import { getBiomeKey } from "#field/arena"; import { getBiomeKey } from "#field/arena";
import type { Modifier } from "#modifiers/modifier"; import type { Modifier } from "#modifiers/modifier";
import { getDailyRunStarterModifiers, regenerateModifierPoolThresholds } from "#modifiers/modifier-type"; import { getDailyRunStarterModifiers, regenerateModifierPoolThresholds } from "#modifiers/modifier-type";
import type { SessionSaveData } from "#system/game-data";
import { vouchers } from "#system/voucher"; import { vouchers } from "#system/voucher";
import type { OptionSelectConfig, OptionSelectItem } from "#ui/handlers/abstract-option-select-ui-handler"; import type { SessionSaveData } from "#types/save-data";
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 { isLocal, isLocalServerConnected, isNullOrUndefined } from "#utils/common";
import i18next from "i18next"; import i18next from "i18next";

View File

@ -1,6 +1,6 @@
import { ApiBase } from "#api/api-base"; import { ApiBase } from "#api/api-base";
import type { GetDailyRankingsPageCountRequest, GetDailyRankingsRequest } from "#types/api/pokerogue-daily-api"; 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. * A wrapper for daily-run PokéRogue API requests.

View File

@ -1,5 +1,4 @@
import { ApiBase } from "#api/api-base"; import { ApiBase } from "#api/api-base";
import type { SessionSaveData } from "#system/game-data";
import type { import type {
ClearSessionSavedataRequest, ClearSessionSavedataRequest,
ClearSessionSavedataResponse, ClearSessionSavedataResponse,
@ -8,6 +7,7 @@ import type {
NewClearSessionSavedataRequest, NewClearSessionSavedataRequest,
UpdateSessionSavedataRequest, UpdateSessionSavedataRequest,
} from "#types/api/pokerogue-session-save-data-api"; } from "#types/api/pokerogue-session-save-data-api";
import type { SessionSaveData } from "#types/save-data";
/** /**
* A wrapper for PokéRogue session savedata API requests. * A wrapper for PokéRogue session savedata API requests.

View File

@ -1,6 +1,5 @@
import { pokerogueApi } from "#api/pokerogue-api"; import { pokerogueApi } from "#api/pokerogue-api";
import { clientSessionId, loggedInUser, updateUserInfo } from "#app/account"; import { clientSessionId, loggedInUser, updateUserInfo } from "#app/account";
import type { PokeballCounts } from "#app/battle-scene";
import { defaultStarterSpecies, saveKey } from "#app/constants"; import { defaultStarterSpecies, saveKey } from "#app/constants";
import { getGameMode } from "#app/game-mode"; import { getGameMode } from "#app/game-mode";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
@ -24,11 +23,9 @@ import { Device } from "#enums/devices";
import { DexAttr } from "#enums/dex-attr"; import { DexAttr } from "#enums/dex-attr";
import { GameDataType } from "#enums/game-data-type"; import { GameDataType } from "#enums/game-data-type";
import { GameModes } from "#enums/game-modes"; import { GameModes } from "#enums/game-modes";
import type { MoveId } from "#enums/move-id";
import type { MysteryEncounterType } from "#enums/mystery-encounter-type"; import type { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { Nature } from "#enums/nature"; import { Nature } from "#enums/nature";
import { PlayerGender } from "#enums/player-gender"; import { PlayerGender } from "#enums/player-gender";
import type { PokemonType } from "#enums/pokemon-type";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import { TrainerVariant } from "#enums/trainer-variant"; import { TrainerVariant } from "#enums/trainer-variant";
@ -62,7 +59,20 @@ import {
import { VoucherType, vouchers } from "#system/voucher"; import { VoucherType, vouchers } from "#system/voucher";
import { trainerConfigs } from "#trainers/trainer-config"; import { trainerConfigs } from "#trainers/trainer-config";
import type { DexData, DexEntry } from "#types/dex-data"; import type { DexData, DexEntry } from "#types/dex-data";
import { RUN_HISTORY_LIMIT } from "#ui/handlers/run-history-ui-handler"; import type {
AchvUnlocks,
DexAttrProps,
RunHistoryData,
SeenDialogues,
SessionSaveData,
StarterData,
SystemSaveData,
TutorialFlags,
Unlocks,
VoucherCounts,
VoucherUnlocks,
} from "#types/save-data";
import { RUN_HISTORY_LIMIT } from "#ui/run-history-ui-handler";
import { applyChallenges } from "#utils/challenge-utils"; import { applyChallenges } from "#utils/challenge-utils";
import { executeIf, fixedInt, isLocal, NumberHolder, randInt, randSeedItem } from "#utils/common"; import { executeIf, fixedInt, isLocal, NumberHolder, randInt, randSeedItem } from "#utils/common";
import { decrypt, encrypt } from "#utils/data"; import { decrypt, encrypt } from "#utils/data";
@ -94,132 +104,6 @@ function getDataTypeKey(dataType: GameDataType, slotId = 0): string {
} }
} }
// TODO: Move all these exported interfaces to @types
export interface SystemSaveData {
trainerId: number;
secretId: number;
gender: PlayerGender;
dexData: DexData;
starterData: StarterData;
gameStats: GameStats;
unlocks: Unlocks;
achvUnlocks: AchvUnlocks;
voucherUnlocks: VoucherUnlocks;
voucherCounts: VoucherCounts;
eggs: EggData[];
gameVersion: string;
timestamp: number;
eggPity: number[];
unlockPity: number[];
}
export interface SessionSaveData {
seed: string;
playTime: number;
gameMode: GameModes;
party: PokemonData[];
enemyParty: PokemonData[];
modifiers: PersistentModifierData[];
enemyModifiers: PersistentModifierData[];
arena: ArenaData;
pokeballCounts: PokeballCounts;
money: number;
score: number;
waveIndex: number;
battleType: BattleType;
trainer: TrainerData;
gameVersion: string;
/** The player-chosen name of the run */
name: string;
timestamp: number;
challenges: ChallengeData[];
mysteryEncounterType: MysteryEncounterType | -1; // Only defined when current wave is ME,
mysteryEncounterSaveData: MysteryEncounterSaveData;
/**
* Counts the amount of pokemon fainted in your party during the current arena encounter.
*/
playerFaints: number;
}
interface Unlocks {
[key: number]: boolean;
}
export interface AchvUnlocks {
[key: string]: number;
}
export interface VoucherUnlocks {
[key: string]: number;
}
export interface VoucherCounts {
[type: string]: number;
}
export type StarterMoveset = [MoveId] | [MoveId, MoveId] | [MoveId, MoveId, MoveId] | [MoveId, MoveId, MoveId, MoveId];
export interface StarterFormMoveData {
[key: number]: StarterMoveset;
}
export interface StarterMoveData {
[key: number]: StarterMoveset | StarterFormMoveData;
}
export interface StarterAttributes {
nature?: number;
ability?: number;
variant?: number;
form?: number;
female?: boolean;
shiny?: boolean;
favorite?: boolean;
nickname?: string;
tera?: PokemonType;
}
export interface DexAttrProps {
shiny: boolean;
female: boolean;
variant: Variant;
formIndex: number;
}
export type RunHistoryData = Record<number, RunEntry>;
export interface RunEntry {
entry: SessionSaveData;
isVictory: boolean;
/*Automatically set to false at the moment - implementation TBD*/
isFavorite: boolean;
}
export interface StarterDataEntry {
moveset: StarterMoveset | StarterFormMoveData | null;
eggMoves: number;
candyCount: number;
friendship: number;
abilityAttr: number;
passiveAttr: number;
valueReduction: number;
classicWinCount: number;
}
export interface StarterData {
[key: number]: StarterDataEntry;
}
// TODO: Rework into a bitmask
export type TutorialFlags = {
[key in Tutorial]: boolean;
};
// TODO: Rework into a bitmask
export interface SeenDialogues {
[key: string]: boolean;
}
const systemShortKeys = { const systemShortKeys = {
seenAttr: "$sa", seenAttr: "$sa",
caughtAttr: "$ca", caughtAttr: "$ca",
@ -2002,9 +1886,7 @@ export class GameData {
}); });
} }
/** /** Return whether the root species of a given `PokemonSpecies` has been unlocked in the dex */
* Checks whether the root species of a given {@PokemonSpecies} has been unlocked in the dex
*/
isRootSpeciesUnlocked(species: PokemonSpecies): boolean { isRootSpeciesUnlocked(species: PokemonSpecies): boolean {
return !!this.dexData[species.getRootSpeciesId()]?.caughtAttr; return !!this.dexData[species.getRootSpeciesId()]?.caughtAttr;
} }

View File

@ -0,0 +1,101 @@
import { globalScene } from "#app/global-scene";
import type { SettingsDisplayUiHandler } from "#ui/settings-display-ui-handler";
import i18next from "i18next";
const cancelHandler = () => {
globalScene.ui.revertMode();
const handler = globalScene.ui.getHandler();
// Reset the cursor to the current language, if in the settings menu
if (handler && typeof (handler as SettingsDisplayUiHandler).setOptionCursor === "function") {
(handler as SettingsDisplayUiHandler).setOptionCursor(-1, 0, true);
}
};
const changeLocaleHandler = (locale: string): boolean => {
try {
i18next.changeLanguage(locale);
localStorage.setItem("prLang", locale);
cancelHandler();
// Reload the whole game to apply the new locale since also some constants are translated
window.location.reload();
return true;
} catch (error) {
console.error("Error changing locale:", error);
return false;
}
};
export const languageOptions = [
{
label: "English",
handler: () => changeLocaleHandler("en"),
},
{
label: "Español (ES)",
handler: () => changeLocaleHandler("es-ES"),
},
{
label: "Español (LATAM)",
handler: () => changeLocaleHandler("es-MX"),
},
{
label: "Français",
handler: () => changeLocaleHandler("fr"),
},
{
label: "Deutsch",
handler: () => changeLocaleHandler("de"),
},
{
label: "Italiano",
handler: () => changeLocaleHandler("it"),
},
{
label: "Português (BR)",
handler: () => changeLocaleHandler("pt-BR"),
},
{
label: "한국어",
handler: () => changeLocaleHandler("ko"),
},
{
label: "日本語",
handler: () => changeLocaleHandler("ja"),
},
{
label: "简体中文",
handler: () => changeLocaleHandler("zh-CN"),
},
{
label: "繁體中文",
handler: () => changeLocaleHandler("zh-TW"),
},
{
label: "Català (Needs Help)",
handler: () => changeLocaleHandler("ca"),
},
{
label: "Türkçe (Needs Help)",
handler: () => changeLocaleHandler("tr"),
},
{
label: "Русский (Needs Help)",
handler: () => changeLocaleHandler("ru"),
},
{
label: "Dansk (Needs Help)",
handler: () => changeLocaleHandler("da"),
},
{
label: "Română (Needs Help)",
handler: () => changeLocaleHandler("ro"),
},
{
label: "Tagalog (Needs Help)",
handler: () => changeLocaleHandler("tl"),
},
{
label: i18next.t("settings:back"),
handler: () => cancelHandler(),
},
];

View File

@ -6,10 +6,10 @@ import { PlayerGender } from "#enums/player-gender";
import { ShopCursorTarget } from "#enums/shop-cursor-target"; import { ShopCursorTarget } from "#enums/shop-cursor-target";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { CandyUpgradeNotificationChangedEvent } from "#events/battle-scene"; import { CandyUpgradeNotificationChangedEvent } from "#events/battle-scene";
import type { SettingsUiHandler } from "#ui/settings-ui-handler";
import { updateWindowType } from "#ui/ui-theme"; import { updateWindowType } from "#ui/ui-theme";
import { isLocal } from "#utils/common"; import { isLocal } from "#utils/common";
import i18next from "i18next"; import i18next from "i18next";
import { languageOptions } from "./settings-language";
const VOLUME_OPTIONS: SettingOption[] = [ const VOLUME_OPTIONS: SettingOption[] = [
{ {
@ -120,6 +120,14 @@ export interface Setting {
default: number; default: number;
type: SettingType; type: SettingType;
requireReload?: boolean; requireReload?: boolean;
/**
* Specifies the behavior when navigating left/right at the boundaries of the option
*
* - `true`: the cursor will stay on the boundary instead of moving
* - `false`: the cursor will wrap to the other end of the options list
* @defaultValue `false`
*/
clamp?: boolean;
/** Whether the setting can be activated or not */ /** Whether the setting can be activated or not */
activatable?: boolean; activatable?: boolean;
/** Determines whether the setting should be hidden from the UI */ /** Determines whether the setting should be hidden from the UI */
@ -230,6 +238,7 @@ export const Setting: Array<Setting> = [
], ],
default: 3, default: 3,
type: SettingType.GENERAL, type: SettingType.GENERAL,
clamp: false,
}, },
{ {
key: SettingKeys.HP_Bar_Speed, key: SettingKeys.HP_Bar_Speed,
@ -639,6 +648,7 @@ export const Setting: Array<Setting> = [
options: VOLUME_OPTIONS, options: VOLUME_OPTIONS,
default: 5, default: 5,
type: SettingType.AUDIO, type: SettingType.AUDIO,
clamp: true,
}, },
{ {
key: SettingKeys.BGM_Volume, key: SettingKeys.BGM_Volume,
@ -646,6 +656,7 @@ export const Setting: Array<Setting> = [
options: VOLUME_OPTIONS, options: VOLUME_OPTIONS,
default: 10, default: 10,
type: SettingType.AUDIO, type: SettingType.AUDIO,
clamp: true,
}, },
{ {
key: SettingKeys.Field_Volume, key: SettingKeys.Field_Volume,
@ -653,6 +664,7 @@ export const Setting: Array<Setting> = [
options: VOLUME_OPTIONS, options: VOLUME_OPTIONS,
default: 10, default: 10,
type: SettingType.AUDIO, type: SettingType.AUDIO,
clamp: true,
}, },
{ {
key: SettingKeys.SE_Volume, key: SettingKeys.SE_Volume,
@ -660,6 +672,7 @@ export const Setting: Array<Setting> = [
options: VOLUME_OPTIONS, options: VOLUME_OPTIONS,
default: 10, default: 10,
type: SettingType.AUDIO, type: SettingType.AUDIO,
clamp: true,
}, },
{ {
key: SettingKeys.UI_Volume, key: SettingKeys.UI_Volume,
@ -667,6 +680,7 @@ export const Setting: Array<Setting> = [
options: VOLUME_OPTIONS, options: VOLUME_OPTIONS,
default: 10, default: 10,
type: SettingType.AUDIO, type: SettingType.AUDIO,
clamp: true,
}, },
{ {
key: SettingKeys.Battle_Music, key: SettingKeys.Battle_Music,
@ -897,98 +911,8 @@ export function setSetting(setting: string, value: number): boolean {
break; break;
case SettingKeys.Language: case SettingKeys.Language:
if (value && globalScene.ui) { if (value && globalScene.ui) {
const cancelHandler = () => {
globalScene.ui.revertMode();
(globalScene.ui.getHandler() as SettingsUiHandler).setOptionCursor(-1, 0, true);
};
const changeLocaleHandler = (locale: string): boolean => {
try {
i18next.changeLanguage(locale);
localStorage.setItem("prLang", locale);
cancelHandler();
// Reload the whole game to apply the new locale since also some constants are translated
window.location.reload();
return true;
} catch (error) {
console.error("Error changing locale:", error);
return false;
}
};
globalScene.ui.setOverlayMode(UiMode.OPTION_SELECT, { globalScene.ui.setOverlayMode(UiMode.OPTION_SELECT, {
options: [ options: languageOptions,
{
label: "English",
handler: () => changeLocaleHandler("en"),
},
{
label: "Español (ES)",
handler: () => changeLocaleHandler("es-ES"),
},
{
label: "Español (LATAM)",
handler: () => changeLocaleHandler("es-MX"),
},
{
label: "Français",
handler: () => changeLocaleHandler("fr"),
},
{
label: "Deutsch",
handler: () => changeLocaleHandler("de"),
},
{
label: "Italiano",
handler: () => changeLocaleHandler("it"),
},
{
label: "Português (BR)",
handler: () => changeLocaleHandler("pt-BR"),
},
{
label: "한국어",
handler: () => changeLocaleHandler("ko"),
},
{
label: "日本語",
handler: () => changeLocaleHandler("ja"),
},
{
label: "简体中文",
handler: () => changeLocaleHandler("zh-CN"),
},
{
label: "繁體中文",
handler: () => changeLocaleHandler("zh-TW"),
},
{
label: "Català (Needs Help)",
handler: () => changeLocaleHandler("ca"),
},
{
label: "Türkçe (Needs Help)",
handler: () => changeLocaleHandler("tr"),
},
{
label: "Русский (Needs Help)",
handler: () => changeLocaleHandler("ru"),
},
{
label: "Dansk (Needs Help)",
handler: () => changeLocaleHandler("da"),
},
{
label: "Română (Needs Help)",
handler: () => changeLocaleHandler("ro"),
},
{
label: "Tagalog (Needs Help)",
handler: () => changeLocaleHandler("tl"),
},
{
label: i18next.t("settings:back"),
handler: () => cancelHandler(),
},
],
maxOptions: 7, maxOptions: 7,
}); });
return false; return false;

View File

@ -1,7 +1,7 @@
/** biome-ignore-all lint/performance/noNamespaceImport: Convenience */ /** biome-ignore-all lint/performance/noNamespaceImport: Convenience */
import { version } from "#package.json"; import { version } from "#package.json";
import type { SessionSaveData, SystemSaveData } from "#system/game-data"; import type { SessionSaveData, SystemSaveData } from "#types/save-data";
import type { SessionSaveMigrator } from "#types/session-save-migrator"; import type { SessionSaveMigrator } from "#types/session-save-migrator";
import type { SettingsSaveMigrator } from "#types/settings-save-migrator"; import type { SettingsSaveMigrator } from "#types/settings-save-migrator";
import type { SystemSaveMigrator } from "#types/system-save-migrator"; import type { SystemSaveMigrator } from "#types/system-save-migrator";

View File

@ -3,8 +3,8 @@ import { allSpecies } from "#data/data-lists";
import { CustomPokemonData } from "#data/pokemon-data"; import { CustomPokemonData } from "#data/pokemon-data";
import { AbilityAttr } from "#enums/ability-attr"; import { AbilityAttr } from "#enums/ability-attr";
import { DexAttr } from "#enums/dex-attr"; import { DexAttr } from "#enums/dex-attr";
import type { SessionSaveData, SystemSaveData } from "#system/game-data";
import { SettingKeys } from "#system/settings"; import { SettingKeys } from "#system/settings";
import type { SessionSaveData, SystemSaveData } from "#types/save-data";
import type { SessionSaveMigrator } from "#types/session-save-migrator"; import type { SessionSaveMigrator } from "#types/session-save-migrator";
import type { SettingsSaveMigrator } from "#types/settings-save-migrator"; import type { SettingsSaveMigrator } from "#types/settings-save-migrator";
import type { SystemSaveMigrator } from "#types/system-save-migrator"; import type { SystemSaveMigrator } from "#types/system-save-migrator";

View File

@ -2,7 +2,7 @@ import type { BattlerIndex } from "#enums/battler-index";
import type { MoveId } from "#enums/move-id"; import type { MoveId } from "#enums/move-id";
import type { MoveResult } from "#enums/move-result"; import type { MoveResult } from "#enums/move-result";
import { MoveUseMode } from "#enums/move-use-mode"; import { MoveUseMode } from "#enums/move-use-mode";
import type { SessionSaveData } from "#system/game-data"; import type { SessionSaveData } from "#types/save-data";
import type { SessionSaveMigrator } from "#types/session-save-migrator"; import type { SessionSaveMigrator } from "#types/session-save-migrator";
import type { TurnMove } from "#types/turn-move"; import type { TurnMove } from "#types/turn-move";

View File

@ -1,6 +1,6 @@
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { DexAttr } from "#enums/dex-attr"; import { DexAttr } from "#enums/dex-attr";
import type { SessionSaveData, SystemSaveData } from "#system/game-data"; import type { SessionSaveData, SystemSaveData } from "#types/save-data";
import type { SessionSaveMigrator } from "#types/session-save-migrator"; import type { SessionSaveMigrator } from "#types/session-save-migrator";
import type { SystemSaveMigrator } from "#types/system-save-migrator"; import type { SystemSaveMigrator } from "#types/system-save-migrator";
import { isNullOrUndefined } from "#utils/common"; import { isNullOrUndefined } from "#utils/common";

View File

@ -1,6 +1,6 @@
import { DexAttr } from "#enums/dex-attr"; import { DexAttr } from "#enums/dex-attr";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import type { SystemSaveData } from "#system/game-data"; import type { SystemSaveData } from "#types/save-data";
import type { SystemSaveMigrator } from "#types/system-save-migrator"; import type { SystemSaveMigrator } from "#types/system-save-migrator";
import { getPokemonSpecies } from "#utils/pokemon-utils"; import { getPokemonSpecies } from "#utils/pokemon-utils";

View File

@ -1,7 +1,7 @@
import { MoveId } from "#enums/move-id"; import { MoveId } from "#enums/move-id";
import { PokemonMove } from "#moves/pokemon-move"; import { PokemonMove } from "#moves/pokemon-move";
import type { SessionSaveData } from "#system/game-data";
import type { PokemonData } from "#system/pokemon-data"; import type { PokemonData } from "#system/pokemon-data";
import type { SessionSaveData } from "#types/save-data";
import type { SessionSaveMigrator } from "#types/session-save-migrator"; import type { SessionSaveMigrator } from "#types/session-save-migrator";
/** /**

View File

@ -5,9 +5,9 @@ import type Phaser from "phaser";
const repeatInputDelayMillis = 250; const repeatInputDelayMillis = 250;
export class TouchControl { export class TouchControl {
events: Phaser.Events.EventEmitter; readonly events: Phaser.Events.EventEmitter;
private buttonLock: string[] = []; private buttonLock: string[] = [];
private inputInterval: NodeJS.Timeout[] = []; private readonly inputInterval: NodeJS.Timeout[] = [];
/** Whether touch controls are disabled */ /** Whether touch controls are disabled */
private disabled = false; private disabled = false;
/** Whether the last touch event has finished before disabling */ /** Whether the last touch event has finished before disabling */
@ -61,12 +61,46 @@ export class TouchControl {
* event, removes the keydown state, and removes the 'active' class from the node and the last touched element. * event, removes the keydown state, and removes the 'active' class from the node and the last touched element.
*/ */
bindKey(node: HTMLElement, key: string) { bindKey(node: HTMLElement, key: string) {
node.addEventListener("touchstart", (event: TouchEvent) => {
// Handle touch events for touch devices
this.touchButtonDown(node, key);
event.preventDefault();
// prevent pointer event from also firing (undefined just sets presence of custom attribute)
if (event.currentTarget instanceof HTMLElement) {
event.currentTarget.dataset.skipPointerEvent = undefined;
}
});
node.addEventListener("pointerdown", event => { node.addEventListener("pointerdown", event => {
const currentTarget = event.currentTarget;
if (currentTarget instanceof HTMLElement && "skipPointerDown" in currentTarget.dataset) {
return;
}
event.preventDefault(); event.preventDefault();
this.touchButtonDown(node, key); this.touchButtonDown(node, key);
}); });
node.addEventListener("touchcancel", (event: TouchEvent) => {
if (event.currentTarget instanceof HTMLElement && "skipPointerDown" in event.currentTarget.dataset) {
delete event.currentTarget.dataset.skipPointerEvent;
}
});
node.addEventListener("touchend", (event: TouchEvent) => {
event.preventDefault();
this.touchButtonUp(node, key, event.target?.["id"]);
if (event.currentTarget instanceof HTMLElement && "skipPointerDown" in event.currentTarget.dataset) {
// allow pointer event to once again fire
delete event.currentTarget.dataset.skipPointerEvent;
event.currentTarget.dataset.skipPointerUp = undefined;
}
});
node.addEventListener("pointerup", event => { node.addEventListener("pointerup", event => {
if (event.currentTarget instanceof HTMLElement && "skipPointerUp" in event.currentTarget.dataset) {
delete event.currentTarget.dataset.skipPointerUp;
return;
}
event.preventDefault(); event.preventDefault();
this.touchButtonUp(node, key, event.target?.["id"]); this.touchButtonUp(node, key, event.target?.["id"]);
}); });
@ -143,7 +177,7 @@ export class TouchControl {
* {@link https://stackoverflow.com/a/39778831/4622620|Source} * {@link https://stackoverflow.com/a/39778831/4622620|Source}
* *
* Prevent zoom on specified element * Prevent zoom on specified element
* @param {HTMLElement} element * @param element
*/ */
preventElementZoom(element: HTMLElement | null): void { preventElementZoom(element: HTMLElement | null): void {
if (!element) { if (!element) {

View File

@ -1,8 +1,8 @@
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import Overrides from "#app/overrides"; import Overrides from "#app/overrides";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { AwaitableUiHandler } from "#ui/handlers/awaitable-ui-handler"; import { AwaitableUiHandler } from "#ui/awaitable-ui-handler";
import type { UiHandler } from "#ui/handlers/ui-handler"; import type { UiHandler } from "#ui/ui-handler";
import i18next from "i18next"; import i18next from "i18next";
export enum Tutorial { export enum Tutorial {

View File

@ -3,16 +3,16 @@ import type { InputsController } from "#app/inputs-controller";
import { Button } from "#enums/buttons"; import { Button } from "#enums/buttons";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { Setting, SettingKeys, settingIndex } from "#system/settings"; import { Setting, SettingKeys, settingIndex } from "#system/settings";
import { PokedexPageUiHandler } from "#ui/containers/pokedex-page-ui-handler"; import type { MessageUiHandler } from "#ui/message-ui-handler";
import type { MessageUiHandler } from "#ui/handlers/message-ui-handler"; import { PokedexPageUiHandler } from "#ui/pokedex-page-ui-handler";
import { PokedexUiHandler } from "#ui/handlers/pokedex-ui-handler"; import { PokedexUiHandler } from "#ui/pokedex-ui-handler";
import { RunInfoUiHandler } from "#ui/handlers/run-info-ui-handler"; import { RunInfoUiHandler } from "#ui/run-info-ui-handler";
import { StarterSelectUiHandler } from "#ui/handlers/starter-select-ui-handler";
import { SettingsAudioUiHandler } from "#ui/settings-audio-ui-handler"; import { SettingsAudioUiHandler } from "#ui/settings-audio-ui-handler";
import { SettingsDisplayUiHandler } from "#ui/settings-display-ui-handler"; import { SettingsDisplayUiHandler } from "#ui/settings-display-ui-handler";
import { SettingsGamepadUiHandler } from "#ui/settings-gamepad-ui-handler"; import { SettingsGamepadUiHandler } from "#ui/settings-gamepad-ui-handler";
import { SettingsKeyboardUiHandler } from "#ui/settings-keyboard-ui-handler"; import { SettingsKeyboardUiHandler } from "#ui/settings-keyboard-ui-handler";
import { SettingsUiHandler } from "#ui/settings-ui-handler"; import { SettingsUiHandler } from "#ui/settings-ui-handler";
import { StarterSelectUiHandler } from "#ui/starter-select-ui-handler";
import Phaser from "phaser"; import Phaser from "phaser";
type ActionKeys = Record<Button, () => void>; type ActionKeys = Record<Button, () => void>;

View File

@ -3,9 +3,9 @@ import { Stat } from "#enums/stat";
import { TextStyle } from "#enums/text-style"; import { TextStyle } from "#enums/text-style";
import { UiTheme } from "#enums/ui-theme"; import { UiTheme } from "#enums/ui-theme";
import type { EnemyPokemon } from "#field/pokemon"; import type { EnemyPokemon } from "#field/pokemon";
import { BattleFlyout } from "#ui/battle-flyout";
import type { BattleInfoParamList } from "#ui/battle-info"; import type { BattleInfoParamList } from "#ui/battle-info";
import { BattleInfo } from "#ui/battle-info"; import { BattleInfo } from "#ui/battle-info";
import { BattleFlyout } from "#ui/containers/battle-flyout";
import { addTextObject } from "#ui/text"; import { addTextObject } from "#ui/text";
import { addWindow, WindowVariant } from "#ui/ui-theme"; import { addWindow, WindowVariant } from "#ui/ui-theme";
import { getLocalizedSpriteKey } from "#utils/common"; import { getLocalizedSpriteKey } from "#utils/common";

View File

@ -15,8 +15,8 @@ import {
} from "#events/arena"; } from "#events/arena";
import type { TurnEndEvent } from "#events/battle-scene"; import type { TurnEndEvent } from "#events/battle-scene";
import { BattleSceneEventType } 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 { addTextObject } from "#ui/text";
import { TimeOfDayWidget } from "#ui/time-of-day-widget";
import { addWindow, WindowVariant } from "#ui/ui-theme"; import { addWindow, WindowVariant } from "#ui/ui-theme";
import { fixedInt } from "#utils/common"; import { fixedInt } from "#utils/common";
import { toCamelCase, toTitleCase } from "#utils/strings"; import { toCamelCase, toTitleCase } from "#utils/strings";

View File

@ -53,7 +53,7 @@ export class BgmBar extends Phaser.GameObjects.Container {
/* /*
* Set the BGM Name to the BGM bar. * Set the BGM Name to the BGM bar.
* @param {string} bgmName The name of the BGM to set. * @param bgmName The name of the BGM to set.
*/ */
setBgmToBgmBar(bgmName: string): void { setBgmToBgmBar(bgmName: string): void {
this.musicText.setText(`${i18next.t("bgmName:music")}${this.getRealBgmName(bgmName)}`); this.musicText.setText(`${i18next.t("bgmName:music")}${this.getRealBgmName(bgmName)}`);
@ -71,7 +71,7 @@ export class BgmBar extends Phaser.GameObjects.Container {
/* /*
Show or hide the BGM bar. Show or hide the BGM bar.
@param {boolean} visible Whether to show or hide the BGM bar. @param visible Whether to show or hide the BGM bar.
*/ */
public toggleBgmBar(visible: boolean): void { public toggleBgmBar(visible: boolean): void {
/* /*

View File

@ -202,8 +202,8 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container {
* The method fetches the total page count if necessary, followed by fetching the rankings for the specified category * The method fetches the total page count if necessary, followed by fetching the rankings for the specified category
* and page. It updates the UI with the fetched rankings or shows an appropriate message if no rankings are found. * and page. It updates the UI with the fetched rankings or shows an appropriate message if no rankings are found.
* *
* @param {ScoreboardCategory} [category=this.category] - The category to fetch rankings for. Defaults to the current category. * @param [category=this.category] - The category to fetch rankings for. Defaults to the current category.
* @param {number} [page=this.page] - The page number to fetch. Defaults to the current page. * @param [page=this.page] - The page number to fetch. Defaults to the current page.
*/ */
update(category: ScoreboardCategory = this.category, page: number = this.page) { update(category: ScoreboardCategory = this.category, page: number = this.page) {
if (this.isUpdating) { if (this.isUpdating) {
@ -249,7 +249,7 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container {
/** /**
* Sets the state of the navigation buttons. * Sets the state of the navigation buttons.
* @param {boolean} [enabled=true] - Whether the buttons should be enabled or disabled. * @param [enabled=true] - Whether the buttons should be enabled or disabled.
*/ */
setButtonsState(enabled = true) { setButtonsState(enabled = true) {
const buttons = [ const buttons = [

View File

@ -1,6 +1,6 @@
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { TextStyle } from "#enums/text-style"; 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 { addTextObject } from "#ui/text";
import { addWindow, WindowVariant } from "#ui/ui-theme"; import { addWindow, WindowVariant } from "#ui/ui-theme";
import i18next from "i18next"; import i18next from "i18next";

View File

@ -2,14 +2,11 @@ import { globalScene } from "#app/global-scene";
import { TextStyle } from "#enums/text-style"; import { TextStyle } from "#enums/text-style";
import type { EggCountChangedEvent } from "#events/egg"; import type { EggCountChangedEvent } from "#events/egg";
import { EggEventType } from "#events/egg"; import { EggEventType } from "#events/egg";
import type { EggHatchSceneHandler } from "#ui/handlers/egg-hatch-scene-handler"; import type { EggHatchSceneUiHandler } from "#ui/egg-hatch-scene-ui-handler";
import { addTextObject } from "#ui/text"; import { addTextObject } from "#ui/text";
import { addWindow } from "#ui/ui-theme"; import { addWindow } from "#ui/ui-theme";
/** /** A container that displays the count of hatching eggs */
* A container that displays the count of hatching eggs.
* @extends Phaser.GameObjects.Container
*/
export class EggCounterContainer extends Phaser.GameObjects.Container { export class EggCounterContainer extends Phaser.GameObjects.Container {
private readonly WINDOW_DEFAULT_WIDTH = 37; private readonly WINDOW_DEFAULT_WIDTH = 37;
private readonly WINDOW_MEDIUM_WIDTH = 42; private readonly WINDOW_MEDIUM_WIDTH = 42;
@ -27,7 +24,7 @@ export class EggCounterContainer extends Phaser.GameObjects.Container {
super(globalScene, 0, 0); super(globalScene, 0, 0);
this.eggCount = eggCount; this.eggCount = eggCount;
const uiHandler = globalScene.ui.getHandler() as EggHatchSceneHandler; const uiHandler = globalScene.ui.getHandler() as EggHatchSceneUiHandler;
uiHandler.eventTarget.addEventListener(EggEventType.EGG_COUNT_CHANGED, this.onEggCountChangedEvent); uiHandler.eventTarget.addEventListener(EggEventType.EGG_COUNT_CHANGED, this.onEggCountChangedEvent);
this.setup(); this.setup();

View File

@ -2,9 +2,9 @@ import { globalScene } from "#app/global-scene";
import type { DropDownColumn } from "#enums/drop-down-column"; import type { DropDownColumn } from "#enums/drop-down-column";
import { TextStyle } from "#enums/text-style"; import { TextStyle } from "#enums/text-style";
import type { UiTheme } from "#enums/ui-theme"; import type { UiTheme } from "#enums/ui-theme";
import type { DropDown } from "#ui/containers/dropdown"; import type { DropDown } from "#ui/dropdown";
import { DropDownType } from "#ui/containers/dropdown"; import { DropDownType } from "#ui/dropdown";
import type { StarterContainer } from "#ui/containers/starter-container"; import type { StarterContainer } from "#ui/starter-container";
import { addTextObject, getTextColor } from "#ui/text"; import { addTextObject, getTextColor } from "#ui/text";
import { addWindow, WindowVariant } from "#ui/ui-theme"; import { addWindow, WindowVariant } from "#ui/ui-theme";

View File

@ -2,8 +2,8 @@ import { globalScene } from "#app/global-scene";
import { TextStyle } from "#enums/text-style"; import { TextStyle } from "#enums/text-style";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import type { UiTheme } from "#enums/ui-theme"; import type { UiTheme } from "#enums/ui-theme";
import type { StarterContainer } from "#ui/containers/starter-container"; import type { AwaitableUiHandler } from "#ui/awaitable-ui-handler";
import type { AwaitableUiHandler } from "#ui/handlers/awaitable-ui-handler"; import type { StarterContainer } from "#ui/starter-container";
import { addTextObject, getTextColor } from "#ui/text"; import { addTextObject, getTextColor } from "#ui/text";
import type { UI } from "#ui/ui"; import type { UI } from "#ui/ui";
import { addWindow, WindowVariant } from "#ui/ui-theme"; import { addWindow, WindowVariant } from "#ui/ui-theme";

View File

@ -4,8 +4,8 @@ import { Gender } from "#data/gender";
import type { PokemonSpecies } from "#data/pokemon-species"; import type { PokemonSpecies } from "#data/pokemon-species";
import { DexAttr } from "#enums/dex-attr"; import { DexAttr } from "#enums/dex-attr";
import { getVariantTint } from "#sprites/variant"; import { getVariantTint } from "#sprites/variant";
import type { PokemonIconAnimHandler } from "#ui/handlers/pokemon-icon-anim-handler"; import type { PokemonIconAnimHelper } from "#ui/pokemon-icon-anim-helper";
import { PokemonIconAnimMode } from "#ui/handlers/pokemon-icon-anim-handler"; 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 * A container for a Pokemon's sprite and icons to get displayed in the egg summary screen
@ -81,9 +81,9 @@ export class HatchedPokemonContainer extends Phaser.GameObjects.Container {
* Animates the pokemon icon if it has a new form or shiny variant * Animates the pokemon icon if it has a new form or shiny variant
* *
* @param hatchData the {@linkcode EggHatchData} to base the icons on * @param hatchData the {@linkcode EggHatchData} to base the icons on
* @param iconAnimHandler the {@linkcode PokemonIconAnimHandler} to use to animate the sprites * @param iconAnimHandler the {@linkcode PokemonIconAnimHelper} to use to animate the sprites
*/ */
updateAndAnimate(hatchData: EggHatchData, iconAnimHandler: PokemonIconAnimHandler) { updateAndAnimate(hatchData: EggHatchData, iconAnimHandler: PokemonIconAnimHelper) {
const displayPokemon = hatchData.pokemon; const displayPokemon = hatchData.pokemon;
this.species = displayPokemon.species; this.species = displayPokemon.species;

View File

@ -9,11 +9,11 @@ import { PokemonType } from "#enums/pokemon-type";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { TextStyle } from "#enums/text-style"; import { TextStyle } from "#enums/text-style";
import type { PlayerPokemon } from "#field/pokemon"; import type { PlayerPokemon } from "#field/pokemon";
import { PokemonInfoContainer } from "#ui/containers/pokemon-info-container";
import { addTextObject } from "#ui/text"; import { addTextObject } from "#ui/text";
import { padInt, rgbHexToRgba } from "#utils/common"; import { padInt, rgbHexToRgba } from "#utils/common";
import { getPokemonSpeciesForm } from "#utils/pokemon-utils"; import { getPokemonSpeciesForm } from "#utils/pokemon-utils";
import { argbFromRgba } from "@material/material-color-utilities"; import { argbFromRgba } from "@material/material-color-utilities";
import { PokemonInfoContainer } from "./pokemon-info-container";
/** /**
* Class for the hatch info summary of each pokemon * Class for the hatch info summary of each pokemon

View File

@ -6,15 +6,15 @@ import { PokemonType } from "#enums/pokemon-type";
import { TextStyle } from "#enums/text-style"; import { TextStyle } from "#enums/text-style";
import type { Pokemon } from "#field/pokemon"; import type { Pokemon } from "#field/pokemon";
import { getVariantTint } from "#sprites/variant"; import { getVariantTint } from "#sprites/variant";
import type { StarterDataEntry } from "#system/game-data";
import type { DexEntry } from "#types/dex-data"; import type { DexEntry } from "#types/dex-data";
import { StatsContainer } from "#ui/containers/stats-container"; 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 { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text";
import { addWindow } from "#ui/ui-theme"; import { addWindow } from "#ui/ui-theme";
import { fixedInt, getShinyDescriptor } from "#utils/common"; import { fixedInt, getShinyDescriptor } from "#utils/common";
import i18next from "i18next"; import i18next from "i18next";
import type BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; import type BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
import { StatsContainer } from "./stats-container";
interface LanguageSetting { interface LanguageSetting {
infoContainerTextSize: string; infoContainerTextSize: string;

View File

@ -1,7 +1,7 @@
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { fixedInt } from "#utils/common"; import { fixedInt } from "#utils/common";
export class SavingIconHandler extends Phaser.GameObjects.Container { export class SavingIconContainer extends Phaser.GameObjects.Container {
private icon: Phaser.GameObjects.Sprite; private icon: Phaser.GameObjects.Sprite;
private animActive: boolean; private animActive: boolean;

Some files were not shown because too many files have changed in this diff Show More