Merge branch 'main' into plates_memories
64
.github/workflows/github-pages.yml
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
name: "Github Pages"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pages:
|
||||||
|
name: Github Pages
|
||||||
|
if: github.repository == 'pagefaultgames/pokerogue'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
api-dir: ./
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository for Typedoc
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
path: pokerogue_docs
|
||||||
|
|
||||||
|
- name: Install OS package
|
||||||
|
run: |
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y git openssh-client
|
||||||
|
|
||||||
|
- name: Setup Node 20.13.1
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
|
||||||
|
- name: Checkout repository for Github Pages
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
path: pokerogue_gh
|
||||||
|
ref: gh-pages
|
||||||
|
|
||||||
|
- name: Install Node.js dependencies
|
||||||
|
working-directory: ${{env.api-dir}}
|
||||||
|
run: |
|
||||||
|
cd pokerogue_docs
|
||||||
|
npm ci
|
||||||
|
npm install typedoc --save-dev
|
||||||
|
|
||||||
|
- name: Generate Typedoc docs
|
||||||
|
working-directory: ${{env.api-dir}}
|
||||||
|
run: |
|
||||||
|
cd pokerogue_docs
|
||||||
|
npx typedoc --out /tmp/docs --githubPages false --entryPoints ./src/
|
||||||
|
|
||||||
|
- name: Commit & Push docs
|
||||||
|
run: |
|
||||||
|
cd pokerogue_gh
|
||||||
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
mkdir -p $GITHUB_REF_NAME
|
||||||
|
rm -rf $GITHUB_REF_NAME/*
|
||||||
|
cp -r /tmp/docs/. $GITHUB_REF_NAME
|
||||||
|
git add $GITHUB_REF_NAME
|
||||||
|
git commit --allow-empty -m "[skip ci] Deploy docs"
|
||||||
|
git push
|
3
.gitignore
vendored
@ -35,4 +35,5 @@ src/data/battle-anim-raw-data*.ts
|
|||||||
src/data/battle-anim-data.ts
|
src/data/battle-anim-data.ts
|
||||||
src/overrides.ts
|
src/overrides.ts
|
||||||
|
|
||||||
coverage
|
coverage
|
||||||
|
/typedoc
|
||||||
|
100
package-lock.json
generated
@ -31,6 +31,7 @@
|
|||||||
"lefthook": "^1.6.12",
|
"lefthook": "^1.6.12",
|
||||||
"phaser3spectorjs": "^0.0.8",
|
"phaser3spectorjs": "^0.0.8",
|
||||||
"pokenode-ts": "^1.20.0",
|
"pokenode-ts": "^1.20.0",
|
||||||
|
"typedoc": "^0.25.13",
|
||||||
"typescript": "^5.4.5",
|
"typescript": "^5.4.5",
|
||||||
"typescript-eslint": "^7.10.0",
|
"typescript-eslint": "^7.10.0",
|
||||||
"vite": "^4.5.0",
|
"vite": "^4.5.0",
|
||||||
@ -1663,6 +1664,12 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ansi-sequence-parser": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/ansi-styles": {
|
"node_modules/ansi-styles": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
@ -4246,6 +4253,12 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jsonc-parser": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/jsonify": {
|
"node_modules/jsonify": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz",
|
||||||
@ -4557,6 +4570,12 @@
|
|||||||
"yallist": "^3.0.2"
|
"yallist": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lunr": {
|
||||||
|
"version": "2.3.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
|
||||||
|
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
"version": "0.30.10",
|
"version": "0.30.10",
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
|
||||||
@ -4592,6 +4611,18 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/marked": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"marked": "bin/marked.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/media-typer": {
|
"node_modules/media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
@ -5676,6 +5707,18 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/shiki": {
|
||||||
|
"version": "0.14.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz",
|
||||||
|
"integrity": "sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-sequence-parser": "^1.1.0",
|
||||||
|
"jsonc-parser": "^3.2.0",
|
||||||
|
"vscode-oniguruma": "^1.7.0",
|
||||||
|
"vscode-textmate": "^8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/side-channel": {
|
"node_modules/side-channel": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
|
||||||
@ -6151,6 +6194,51 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/typedoc": {
|
||||||
|
"version": "0.25.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.13.tgz",
|
||||||
|
"integrity": "sha512-pQqiwiJ+Z4pigfOnnysObszLiU3mVLWAExSPf+Mu06G/qsc3wzbuM56SZQvONhHLncLUhYzOVkjFFpFfL5AzhQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"lunr": "^2.3.9",
|
||||||
|
"marked": "^4.3.0",
|
||||||
|
"minimatch": "^9.0.3",
|
||||||
|
"shiki": "^0.14.7"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"typedoc": "bin/typedoc"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typedoc/node_modules/brace-expansion": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typedoc/node_modules/minimatch": {
|
||||||
|
"version": "9.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
|
||||||
|
"integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16 || 14 >=14.17"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.4.5",
|
"version": "5.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||||
@ -7482,6 +7570,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vscode-oniguruma": {
|
||||||
|
"version": "1.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
|
||||||
|
"integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/vscode-textmate": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/w3c-xmlserializer": {
|
"node_modules/w3c-xmlserializer": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
"test:cov": "vitest run --coverage",
|
"test:cov": "vitest run --coverage",
|
||||||
"test:watch": "vitest watch --coverage",
|
"test:watch": "vitest watch --coverage",
|
||||||
"eslint": "eslint --fix .",
|
"eslint": "eslint --fix .",
|
||||||
"eslint-ci": "eslint ."
|
"eslint-ci": "eslint .",
|
||||||
|
"docs": "typedoc"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.3.0",
|
"@eslint/js": "^9.3.0",
|
||||||
@ -29,6 +30,7 @@
|
|||||||
"lefthook": "^1.6.12",
|
"lefthook": "^1.6.12",
|
||||||
"phaser3spectorjs": "^0.0.8",
|
"phaser3spectorjs": "^0.0.8",
|
||||||
"pokenode-ts": "^1.20.0",
|
"pokenode-ts": "^1.20.0",
|
||||||
|
"typedoc": "^0.25.13",
|
||||||
"typescript": "^5.4.5",
|
"typescript": "^5.4.5",
|
||||||
"typescript-eslint": "^7.10.0",
|
"typescript-eslint": "^7.10.0",
|
||||||
"vite": "^4.5.0",
|
"vite": "^4.5.0",
|
||||||
|
BIN
public/audio/cry/718-10-pc.m4a
Normal file
BIN
public/images/battle_anims/PRAS- Giga Impact Opp BG.png
Normal file
After Width: | Height: | Size: 44 KiB |
14939
public/images/items.json
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 125 KiB |
BIN
public/images/items/flame_orb.png
Normal file
After Width: | Height: | Size: 367 B |
BIN
public/images/items/toxic_orb.png
Normal file
After Width: | Height: | Size: 408 B |
@ -1332,6 +1332,27 @@
|
|||||||
"h": 24
|
"h": 24
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"filename": "173_2",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 40,
|
||||||
|
"h": 30
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 11,
|
||||||
|
"w": 18,
|
||||||
|
"h": 18
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 174,
|
||||||
|
"y": 253,
|
||||||
|
"w": 18,
|
||||||
|
"h": 18
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"filename": "173_3",
|
"filename": "173_3",
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 60 KiB |
41
public/images/trainer/firebreather.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "firebreather.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 80,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 80,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:f692676a166fc1915532cd94d5799af4:fb833f76fb6797474657726bb59a7eee:aeb55e30992938f494b6cd2420158dda$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/trainer/firebreather.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
440
public/images/types_ko.json
Normal file
@ -0,0 +1,440 @@
|
|||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "types_ko.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 280
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "unknown",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "bug",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 14,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "dark",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 28,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "dragon",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 42,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "electric",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 56,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "fairy",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 70,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "fighting",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 84,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "fire",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 98,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "flying",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 112,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "ghost",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 126,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "grass",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 140,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "ground",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 154,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "ice",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 168,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "normal",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 182,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "poison",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 196,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "psychic",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 210,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "rock",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 224,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "steel",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 238,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "water",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 252,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "stellar",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 266,
|
||||||
|
"w": 32,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:f14cf47d9a8f1d40c8e03aa6ba00fff3:6fc4227b57a95d429a1faad4280f7ec8:5961efbfbf4c56b8745347e7a663a32f$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/types_ko.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
@ -1876,7 +1876,20 @@ export default class BattleScene extends SceneBase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
tryTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, transferStack: boolean, playSound: boolean, instant?: boolean, ignoreUpdate?: boolean): Promise<boolean> {
|
/**
|
||||||
|
* Try to transfer a held item to another pokemon.
|
||||||
|
* If the recepient already has the maximum amount allowed for this item, the transfer is cancelled.
|
||||||
|
* The quantity to transfer is automatically capped at how much the recepient can take before reaching the maximum stack size for the item.
|
||||||
|
* A transfer that moves a quantity smaller than what is specified in the transferQuantity parameter is still considered successful.
|
||||||
|
* @param itemModifier {@linkcode PokemonHeldItemModifier} item to transfer (represents the whole stack)
|
||||||
|
* @param target {@linkcode Pokemon} pokemon recepient in this transfer
|
||||||
|
* @param playSound {boolean}
|
||||||
|
* @param transferQuantity {@linkcode integer} how many items of the stack to transfer. Optional, defaults to 1
|
||||||
|
* @param instant {boolean}
|
||||||
|
* @param ignoreUpdate {boolean}
|
||||||
|
* @returns true if the transfer was successful
|
||||||
|
*/
|
||||||
|
tryTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, playSound: boolean, transferQuantity: integer = 1, instant?: boolean, ignoreUpdate?: boolean): Promise<boolean> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const source = itemModifier.pokemonId ? itemModifier.getPokemon(target.scene) : null;
|
const source = itemModifier.pokemonId ? itemModifier.getPokemon(target.scene) : null;
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
@ -1894,14 +1907,16 @@ export default class BattleScene extends SceneBase {
|
|||||||
if (matchingModifier.stackCount >= maxStackCount) {
|
if (matchingModifier.stackCount >= maxStackCount) {
|
||||||
return resolve(false);
|
return resolve(false);
|
||||||
}
|
}
|
||||||
const countTaken = transferStack ? Math.min(itemModifier.stackCount, maxStackCount - matchingModifier.stackCount) : 1;
|
const countTaken = Math.min(transferQuantity, itemModifier.stackCount, maxStackCount - matchingModifier.stackCount);
|
||||||
itemModifier.stackCount -= countTaken;
|
itemModifier.stackCount -= countTaken;
|
||||||
newItemModifier.stackCount = matchingModifier.stackCount + countTaken;
|
newItemModifier.stackCount = matchingModifier.stackCount + countTaken;
|
||||||
removeOld = !itemModifier.stackCount;
|
removeOld = !itemModifier.stackCount;
|
||||||
} else if (!transferStack) {
|
} else {
|
||||||
newItemModifier.stackCount = 1;
|
const countTaken = Math.min(transferQuantity, itemModifier.stackCount);
|
||||||
removeOld = !(--itemModifier.stackCount);
|
itemModifier.stackCount -= countTaken;
|
||||||
|
newItemModifier.stackCount = countTaken;
|
||||||
}
|
}
|
||||||
|
removeOld = !itemModifier.stackCount;
|
||||||
if (!removeOld || !source || this.removeModifier(itemModifier, !source.isPlayer())) {
|
if (!removeOld || !source || this.removeModifier(itemModifier, !source.isPlayer())) {
|
||||||
const addModifier = () => {
|
const addModifier = () => {
|
||||||
if (!matchingModifier || this.removeModifier(matchingModifier, !target.isPlayer())) {
|
if (!matchingModifier || this.removeModifier(matchingModifier, !target.isPlayer())) {
|
||||||
|
@ -501,7 +501,7 @@ export class FieldPriorityMoveImmunityAbAttr extends PreDefendAbAttr {
|
|||||||
applyMoveAttrs(IncrementMovePriorityAttr,attacker,null,move.getMove(),attackPriority);
|
applyMoveAttrs(IncrementMovePriorityAttr,attacker,null,move.getMove(),attackPriority);
|
||||||
applyAbAttrs(IncrementMovePriorityAbAttr, attacker, null, move.getMove(), attackPriority);
|
applyAbAttrs(IncrementMovePriorityAbAttr, attacker, null, move.getMove(), attackPriority);
|
||||||
|
|
||||||
if (move.getMove().moveTarget===MoveTarget.USER) {
|
if (move.getMove().moveTarget===MoveTarget.USER || move.getMove().moveTarget===MoveTarget.NEAR_ALLY) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -674,7 +674,10 @@ export class PostDefendApplyBattlerTagAbAttr extends PostDefendAbAttr {
|
|||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
||||||
if (this.condition(pokemon, attacker, move.getMove())) {
|
if (this.condition(pokemon, attacker, move.getMove())) {
|
||||||
pokemon.addTag(this.tagType, undefined, undefined, pokemon.id);
|
if (!pokemon.getTag(this.tagType)) {
|
||||||
|
pokemon.addTag(this.tagType, undefined, undefined, pokemon.id);
|
||||||
|
pokemon.scene.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: pokemon.name, moveName: move.getName() }));
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -1226,7 +1229,7 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
|
|||||||
const heldItems = this.getTargetHeldItems(defender).filter(i => i.getTransferrable(false));
|
const heldItems = this.getTargetHeldItems(defender).filter(i => i.getTransferrable(false));
|
||||||
if (heldItems.length) {
|
if (heldItems.length) {
|
||||||
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
|
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
|
||||||
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false, false).then(success => {
|
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => {
|
||||||
if (success) {
|
if (success) {
|
||||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${defender.name}'s ${stolenItem.type.name}!`));
|
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${defender.name}'s ${stolenItem.type.name}!`));
|
||||||
}
|
}
|
||||||
@ -1315,7 +1318,7 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
|
|||||||
const heldItems = this.getTargetHeldItems(attacker).filter(i => i.getTransferrable(false));
|
const heldItems = this.getTargetHeldItems(attacker).filter(i => i.getTransferrable(false));
|
||||||
if (heldItems.length) {
|
if (heldItems.length) {
|
||||||
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
|
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
|
||||||
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false, false).then(success => {
|
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => {
|
||||||
if (success) {
|
if (success) {
|
||||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${attacker.name}'s ${stolenItem.type.name}!`));
|
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${attacker.name}'s ${stolenItem.type.name}!`));
|
||||||
}
|
}
|
||||||
@ -2066,6 +2069,37 @@ export class BlockNonDirectDamageAbAttr extends AbAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This attribute will block any status damage that you put in the parameter.
|
||||||
|
*/
|
||||||
|
export class BlockStatusDamageAbAttr extends BlockNonDirectDamageAbAttr {
|
||||||
|
private effects: StatusEffect[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {StatusEffect[]} effects The status effect(s) that will be blocked from damaging the ability pokemon
|
||||||
|
*/
|
||||||
|
constructor(...effects: StatusEffect[]) {
|
||||||
|
super(false);
|
||||||
|
|
||||||
|
this.effects = effects;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Pokemon} pokemon The pokemon with the ability
|
||||||
|
* @param {boolean} passive N/A
|
||||||
|
* @param {Utils.BooleanHolder} cancelled Whether to cancel the status damage
|
||||||
|
* @param {any[]} args N/A
|
||||||
|
* @returns Returns true if status damage is blocked
|
||||||
|
*/
|
||||||
|
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
|
if (this.effects.includes(pokemon.status.effect)) {
|
||||||
|
cancelled.value = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class BlockOneHitKOAbAttr extends AbAttr {
|
export class BlockOneHitKOAbAttr extends AbAttr {
|
||||||
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
cancelled.value = true;
|
cancelled.value = true;
|
||||||
@ -2380,6 +2414,41 @@ export class PostTurnAbAttr extends AbAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This attribute will heal 1/8th HP if the ability pokemon has the correct status.
|
||||||
|
*/
|
||||||
|
export class PostTurnStatusHealAbAttr extends PostTurnAbAttr {
|
||||||
|
private effects: StatusEffect[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {StatusEffect[]} effects The status effect(s) that will qualify healing the ability pokemon
|
||||||
|
*/
|
||||||
|
constructor(...effects: StatusEffect[]) {
|
||||||
|
super(false);
|
||||||
|
|
||||||
|
this.effects = effects;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Pokemon} pokemon The pokemon with the ability that will receive the healing
|
||||||
|
* @param {Boolean} passive N/A
|
||||||
|
* @param {any[]} args N/A
|
||||||
|
* @returns Returns true if healed from status, false if not
|
||||||
|
*/
|
||||||
|
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> {
|
||||||
|
if (this.effects.includes(pokemon.status.effect)) {
|
||||||
|
if (pokemon.getMaxHp() !== pokemon.hp) {
|
||||||
|
const scene = pokemon.scene;
|
||||||
|
const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name;
|
||||||
|
scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.getBattlerIndex(),
|
||||||
|
Math.max(Math.floor(pokemon.getMaxHp() / 8), 1), i18next.t("abilityTriggers:poisonHeal", { pokemonName: pokemon.name, abilityName: abilityName}), true));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After the turn ends, resets the status of either the ability holder or their ally
|
* After the turn ends, resets the status of either the ability holder or their ally
|
||||||
* @param {boolean} allyTarget Whether to target ally, defaults to false (self-target)
|
* @param {boolean} allyTarget Whether to target ally, defaults to false (self-target)
|
||||||
@ -2870,7 +2939,7 @@ export class PostBattleLootAbAttr extends PostBattleAbAttr {
|
|||||||
const postBattleLoot = pokemon.scene.currentBattle.postBattleLoot;
|
const postBattleLoot = pokemon.scene.currentBattle.postBattleLoot;
|
||||||
if (postBattleLoot.length) {
|
if (postBattleLoot.length) {
|
||||||
const randItem = Utils.randSeedItem(postBattleLoot);
|
const randItem = Utils.randSeedItem(postBattleLoot);
|
||||||
if (pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false, true, true)) {
|
if (pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, true, 1, true)) {
|
||||||
postBattleLoot.splice(postBattleLoot.indexOf(randItem), 1);
|
postBattleLoot.splice(postBattleLoot.indexOf(randItem), 1);
|
||||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` picked up\n${randItem.type.name}!`));
|
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` picked up\n${randItem.type.name}!`));
|
||||||
return true;
|
return true;
|
||||||
@ -3200,6 +3269,50 @@ export class MoneyAbAttr extends PostBattleAbAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a stat change after a Pokémon is summoned,
|
||||||
|
* conditioned on the presence of a specific arena tag.
|
||||||
|
*
|
||||||
|
* @extends {PostSummonStatChangeAbAttr}
|
||||||
|
*/
|
||||||
|
export class PostSummonStatChangeOnArenaAbAttr extends PostSummonStatChangeAbAttr {
|
||||||
|
/**
|
||||||
|
* The type of arena tag that conditions the stat change.
|
||||||
|
* @private
|
||||||
|
* @type {ArenaTagType}
|
||||||
|
*/
|
||||||
|
private tagType: ArenaTagType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance of PostSummonStatChangeOnArenaAbAttr.
|
||||||
|
* Initializes the stat change to increase Attack by 1 stage if the specified arena tag is present.
|
||||||
|
*
|
||||||
|
* @param {ArenaTagType} tagType - The type of arena tag to check for.
|
||||||
|
*/
|
||||||
|
constructor(tagType: ArenaTagType) {
|
||||||
|
super([BattleStat.ATK], 1, true, false);
|
||||||
|
this.tagType = tagType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the post-summon stat change if the specified arena tag is present on pokemon's side.
|
||||||
|
* This is used in Wind Rider ability.
|
||||||
|
*
|
||||||
|
* @param {Pokemon} pokemon - The Pokémon being summoned.
|
||||||
|
* @param {boolean} passive - Whether the effect is passive.
|
||||||
|
* @param {any[]} args - Additional arguments.
|
||||||
|
* @returns {boolean} - Returns true if the stat change was applied, otherwise false.
|
||||||
|
*/
|
||||||
|
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
|
||||||
|
const side = pokemon.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||||
|
|
||||||
|
if (pokemon.scene.arena.getTagOnSide(this.tagType, side)) {
|
||||||
|
return super.applyPostSummon(pokemon, passive, args);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: { new(...args: any[]): TAttr },
|
function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: { new(...args: any[]): TAttr },
|
||||||
pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> {
|
pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
@ -3603,9 +3716,9 @@ export function initAbilities() {
|
|||||||
.conditionalAttr(pokemon => !Utils.randSeedInt(3), PostTurnResetStatusAbAttr),
|
.conditionalAttr(pokemon => !Utils.randSeedInt(3), PostTurnResetStatusAbAttr),
|
||||||
new Ability(Abilities.GUTS, 3)
|
new Ability(Abilities.GUTS, 3)
|
||||||
.attr(BypassBurnDamageReductionAbAttr)
|
.attr(BypassBurnDamageReductionAbAttr)
|
||||||
.conditionalAttr(pokemon => !!pokemon.status, BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5),
|
.conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(Abilities.COMATOSE), BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5),
|
||||||
new Ability(Abilities.MARVEL_SCALE, 3)
|
new Ability(Abilities.MARVEL_SCALE, 3)
|
||||||
.conditionalAttr(pokemon => !!pokemon.status, BattleStatMultiplierAbAttr, BattleStat.DEF, 1.5)
|
.conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(Abilities.COMATOSE), BattleStatMultiplierAbAttr, BattleStat.DEF, 1.5)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.LIQUID_OOZE, 3)
|
new Ability(Abilities.LIQUID_OOZE, 3)
|
||||||
.attr(ReverseDrainAbAttr),
|
.attr(ReverseDrainAbAttr),
|
||||||
@ -3685,7 +3798,8 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.IRON_FIST, 4)
|
new Ability(Abilities.IRON_FIST, 4)
|
||||||
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.PUNCHING_MOVE), 1.2),
|
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.PUNCHING_MOVE), 1.2),
|
||||||
new Ability(Abilities.POISON_HEAL, 4)
|
new Ability(Abilities.POISON_HEAL, 4)
|
||||||
.unimplemented(),
|
.attr(PostTurnStatusHealAbAttr, StatusEffect.TOXIC, StatusEffect.POISON)
|
||||||
|
.attr(BlockStatusDamageAbAttr, StatusEffect.TOXIC, StatusEffect.POISON),
|
||||||
new Ability(Abilities.ADAPTABILITY, 4)
|
new Ability(Abilities.ADAPTABILITY, 4)
|
||||||
.attr(StabBoostAbAttr),
|
.attr(StabBoostAbAttr),
|
||||||
new Ability(Abilities.SKILL_LINK, 4)
|
new Ability(Abilities.SKILL_LINK, 4)
|
||||||
@ -3699,7 +3813,7 @@ export function initAbilities() {
|
|||||||
.condition(getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN)),
|
.condition(getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN)),
|
||||||
new Ability(Abilities.QUICK_FEET, 4)
|
new Ability(Abilities.QUICK_FEET, 4)
|
||||||
.conditionalAttr(pokemon => pokemon.status ? pokemon.status.effect === StatusEffect.PARALYSIS : false, BattleStatMultiplierAbAttr, BattleStat.SPD, 2)
|
.conditionalAttr(pokemon => pokemon.status ? pokemon.status.effect === StatusEffect.PARALYSIS : false, BattleStatMultiplierAbAttr, BattleStat.SPD, 2)
|
||||||
.conditionalAttr(pokemon => !!pokemon.status, BattleStatMultiplierAbAttr, BattleStat.SPD, 1.5),
|
.conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(Abilities.COMATOSE), BattleStatMultiplierAbAttr, BattleStat.SPD, 1.5),
|
||||||
new Ability(Abilities.NORMALIZE, 4)
|
new Ability(Abilities.NORMALIZE, 4)
|
||||||
.attr(MoveTypeChangeAttr, Type.NORMAL, 1.2, (user, target, move) => move.id !== Moves.HIDDEN_POWER && move.id !== Moves.WEATHER_BALL &&
|
.attr(MoveTypeChangeAttr, Type.NORMAL, 1.2, (user, target, move) => move.id !== Moves.HIDDEN_POWER && move.id !== Moves.WEATHER_BALL &&
|
||||||
move.id !== Moves.NATURAL_GIFT && move.id !== Moves.JUDGMENT && move.id !== Moves.TECHNO_BLAST),
|
move.id !== Moves.NATURAL_GIFT && move.id !== Moves.JUDGMENT && move.id !== Moves.TECHNO_BLAST),
|
||||||
@ -4268,9 +4382,9 @@ export function initAbilities() {
|
|||||||
.attr(TypeImmunityStatChangeAbAttr, Type.FIRE, BattleStat.DEF, 2)
|
.attr(TypeImmunityStatChangeAbAttr, Type.FIRE, BattleStat.DEF, 2)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.WIND_RIDER, 9)
|
new Ability(Abilities.WIND_RIDER, 9)
|
||||||
.attr(MoveImmunityStatChangeAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.getMove().hasFlag(MoveFlags.WIND_MOVE), BattleStat.ATK, 1)
|
.attr(MoveImmunityStatChangeAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.getMove().hasFlag(MoveFlags.WIND_MOVE) && move.getMove().category !== MoveCategory.STATUS, BattleStat.ATK, 1)
|
||||||
.ignorable()
|
.attr(PostSummonStatChangeOnArenaAbAttr, ArenaTagType.TAILWIND)
|
||||||
.partial(),
|
.ignorable(),
|
||||||
new Ability(Abilities.GUARD_DOG, 9)
|
new Ability(Abilities.GUARD_DOG, 9)
|
||||||
.attr(PostIntimidateStatChangeAbAttr, [BattleStat.ATK], 1, true)
|
.attr(PostIntimidateStatChangeAbAttr, [BattleStat.ATK], 1, true)
|
||||||
.attr(ForceSwitchOutImmunityAbAttr)
|
.attr(ForceSwitchOutImmunityAbAttr)
|
||||||
@ -4278,8 +4392,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.ROCKY_PAYLOAD, 9)
|
new Ability(Abilities.ROCKY_PAYLOAD, 9)
|
||||||
.attr(MoveTypePowerBoostAbAttr, Type.ROCK),
|
.attr(MoveTypePowerBoostAbAttr, Type.ROCK),
|
||||||
new Ability(Abilities.WIND_POWER, 9)
|
new Ability(Abilities.WIND_POWER, 9)
|
||||||
.attr(PostDefendApplyBattlerTagAbAttr, (target, user, move) => move.hasFlag(MoveFlags.WIND_MOVE), BattlerTagType.CHARGED)
|
.attr(PostDefendApplyBattlerTagAbAttr, (target, user, move) => move.hasFlag(MoveFlags.WIND_MOVE), BattlerTagType.CHARGED),
|
||||||
.partial(),
|
|
||||||
new Ability(Abilities.ZERO_TO_HERO, 9)
|
new Ability(Abilities.ZERO_TO_HERO, 9)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
|
@ -4,7 +4,7 @@ import * as Utils from "../utils";
|
|||||||
import { MoveCategory, allMoves, MoveTarget } from "./move";
|
import { MoveCategory, allMoves, MoveTarget } from "./move";
|
||||||
import { getPokemonMessage } from "../messages";
|
import { getPokemonMessage } from "../messages";
|
||||||
import Pokemon, { HitResult, PokemonMove } from "../field/pokemon";
|
import Pokemon, { HitResult, PokemonMove } from "../field/pokemon";
|
||||||
import { MoveEffectPhase, PokemonHealPhase, StatChangePhase} from "../phases";
|
import { MoveEffectPhase, PokemonHealPhase, ShowAbilityPhase, StatChangePhase} from "../phases";
|
||||||
import { StatusEffect } from "./status-effect";
|
import { StatusEffect } from "./status-effect";
|
||||||
import { BattlerIndex } from "../battle";
|
import { BattlerIndex } from "../battle";
|
||||||
import { Moves } from "./enums/moves";
|
import { Moves } from "./enums/moves";
|
||||||
@ -12,6 +12,9 @@ import { ArenaTagType } from "./enums/arena-tag-type";
|
|||||||
import { BlockNonDirectDamageAbAttr, ProtectStatAbAttr, applyAbAttrs } from "./ability";
|
import { BlockNonDirectDamageAbAttr, ProtectStatAbAttr, applyAbAttrs } from "./ability";
|
||||||
import { BattleStat } from "./battle-stat";
|
import { BattleStat } from "./battle-stat";
|
||||||
import { CommonAnim, CommonBattleAnim } from "./battle-anims";
|
import { CommonAnim, CommonBattleAnim } from "./battle-anims";
|
||||||
|
import { Abilities } from "./enums/abilities";
|
||||||
|
import { BattlerTagType } from "./enums/battler-tag-type";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
export enum ArenaTagSide {
|
export enum ArenaTagSide {
|
||||||
BOTH,
|
BOTH,
|
||||||
@ -625,6 +628,22 @@ class TailwindTag extends ArenaTag {
|
|||||||
|
|
||||||
onAdd(arena: Arena): void {
|
onAdd(arena: Arena): void {
|
||||||
arena.scene.queueMessage(`The Tailwind blew from behind${this.side === ArenaTagSide.PLAYER ? "\nyour" : this.side === ArenaTagSide.ENEMY ? "\nthe opposing" : ""} team!`);
|
arena.scene.queueMessage(`The Tailwind blew from behind${this.side === ArenaTagSide.PLAYER ? "\nyour" : this.side === ArenaTagSide.ENEMY ? "\nthe opposing" : ""} team!`);
|
||||||
|
|
||||||
|
const source = arena.scene.getPokemonById(this.sourceId);
|
||||||
|
const party = source.isPlayer() ? source.scene.getPlayerField() : source.scene.getEnemyField();
|
||||||
|
|
||||||
|
for (const pokemon of party) {
|
||||||
|
// Apply the CHARGED tag to party members with the WIND_POWER ability
|
||||||
|
if (pokemon.hasAbility(Abilities.WIND_POWER) && !pokemon.getTag(BattlerTagType.CHARGED)) {
|
||||||
|
pokemon.addTag(BattlerTagType.CHARGED);
|
||||||
|
pokemon.scene.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: pokemon.name, moveName: this.getMoveName() }));
|
||||||
|
}
|
||||||
|
// Raise attack by one stage if party member has WIND_RIDER ability
|
||||||
|
if (pokemon.hasAbility(Abilities.WIND_RIDER)) {
|
||||||
|
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.getBattlerIndex()));
|
||||||
|
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.ATK], 1, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onRemove(arena: Arena): void {
|
onRemove(arena: Arena): void {
|
||||||
|
@ -1823,7 +1823,7 @@ export const biomeTrainerPools: BiomeTrainerPools = {
|
|||||||
[BiomePoolTier.BOSS_ULTRA_RARE]: []
|
[BiomePoolTier.BOSS_ULTRA_RARE]: []
|
||||||
},
|
},
|
||||||
[Biome.VOLCANO]: {
|
[Biome.VOLCANO]: {
|
||||||
[BiomePoolTier.COMMON]: [],
|
[BiomePoolTier.COMMON]: [ TrainerType.FIREBREATHER ],
|
||||||
[BiomePoolTier.UNCOMMON]: [],
|
[BiomePoolTier.UNCOMMON]: [],
|
||||||
[BiomePoolTier.RARE]: [],
|
[BiomePoolTier.RARE]: [],
|
||||||
[BiomePoolTier.SUPER_RARE]: [],
|
[BiomePoolTier.SUPER_RARE]: [],
|
||||||
@ -7304,6 +7304,10 @@ export function initBiomes() {
|
|||||||
[ Biome.GRAVEYARD, BiomePoolTier.UNCOMMON ]
|
[ Biome.GRAVEYARD, BiomePoolTier.UNCOMMON ]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
[ TrainerType.FIREBREATHER, [
|
||||||
|
[ Biome.VOLCANO, BiomePoolTier.COMMON ]
|
||||||
|
]
|
||||||
|
],
|
||||||
[ TrainerType.BROCK, [
|
[ TrainerType.BROCK, [
|
||||||
[ Biome.CAVE, BiomePoolTier.BOSS ]
|
[ Biome.CAVE, BiomePoolTier.BOSS ]
|
||||||
]
|
]
|
||||||
|
@ -421,6 +421,20 @@ export const trainerTypeDialogue: TrainerTypeDialogue = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
[TrainerType.FIREBREATHER]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:firebreather.encounter.1",
|
||||||
|
"dialogue:firebreather.encounter.2",
|
||||||
|
"dialogue:firebreather.encounter.3",
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:firebreather.victory.1",
|
||||||
|
"dialogue:firebreather.victory.2",
|
||||||
|
"dialogue:firebreather.victory.3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
[TrainerType.BROCK]: {
|
[TrainerType.BROCK]: {
|
||||||
encounter: [
|
encounter: [
|
||||||
"dialogue:brock.encounter.1",
|
"dialogue:brock.encounter.1",
|
||||||
|
@ -16,6 +16,7 @@ export enum TrainerType {
|
|||||||
DANCER,
|
DANCER,
|
||||||
DEPOT_AGENT,
|
DEPOT_AGENT,
|
||||||
DOCTOR,
|
DOCTOR,
|
||||||
|
FIREBREATHER,
|
||||||
FISHERMAN,
|
FISHERMAN,
|
||||||
GUITARIST,
|
GUITARIST,
|
||||||
HARLEQUIN,
|
HARLEQUIN,
|
||||||
|
@ -423,6 +423,14 @@ export default class Move implements Localizable {
|
|||||||
export class AttackMove extends Move {
|
export class AttackMove extends Move {
|
||||||
constructor(id: Moves, type: Type, category: MoveCategory, power: integer, accuracy: integer, pp: integer, chance: integer, priority: integer, generation: integer) {
|
constructor(id: Moves, type: Type, category: MoveCategory, power: integer, accuracy: integer, pp: integer, chance: integer, priority: integer, generation: integer) {
|
||||||
super(id, type, category, MoveTarget.NEAR_OTHER, power, accuracy, pp, chance, priority, generation);
|
super(id, type, category, MoveTarget.NEAR_OTHER, power, accuracy, pp, chance, priority, generation);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link https://bulbapedia.bulbagarden.net/wiki/Freeze_(status_condition)}
|
||||||
|
* > All damaging Fire-type moves can now thaw a frozen target, regardless of whether or not they have a chance to burn;
|
||||||
|
*/
|
||||||
|
if (this.type === Type.FIRE) {
|
||||||
|
this.addAttr(new HealStatusEffectAttr(false, StatusEffect.FREEZE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
|
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
|
||||||
@ -1437,7 +1445,7 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr {
|
|||||||
const highestItemTier = heldItems.map(m => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier, highestTier), 0);
|
const highestItemTier = heldItems.map(m => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier, highestTier), 0);
|
||||||
const tierHeldItems = heldItems.filter(m => m.type.getOrInferTier(poolType) === highestItemTier);
|
const tierHeldItems = heldItems.filter(m => m.type.getOrInferTier(poolType) === highestItemTier);
|
||||||
const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)];
|
const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)];
|
||||||
user.scene.tryTransferHeldItemModifier(stolenItem, user, false, false).then(success => {
|
user.scene.tryTransferHeldItemModifier(stolenItem, user, false).then(success => {
|
||||||
if (success) {
|
if (success) {
|
||||||
user.scene.queueMessage(getPokemonMessage(user, ` stole\n${target.name}'s ${stolenItem.type.name}!`));
|
user.scene.queueMessage(getPokemonMessage(user, ` stole\n${target.name}'s ${stolenItem.type.name}!`));
|
||||||
}
|
}
|
||||||
@ -1486,7 +1494,7 @@ export class RemoveHeldItemAttr extends MoveEffectAttr {
|
|||||||
const highestItemTier = heldItems.map(m => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier, highestTier), 0);
|
const highestItemTier = heldItems.map(m => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier, highestTier), 0);
|
||||||
const tierHeldItems = heldItems.filter(m => m.type.getOrInferTier(poolType) === highestItemTier);
|
const tierHeldItems = heldItems.filter(m => m.type.getOrInferTier(poolType) === highestItemTier);
|
||||||
const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)];
|
const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)];
|
||||||
user.scene.tryTransferHeldItemModifier(stolenItem, user, false, false).then(success => {
|
user.scene.tryTransferHeldItemModifier(stolenItem, user, false).then(success => {
|
||||||
if (success) {
|
if (success) {
|
||||||
user.scene.queueMessage(getPokemonMessage(user, ` knocked off\n${target.name}'s ${stolenItem.type.name}!`));
|
user.scene.queueMessage(getPokemonMessage(user, ` knocked off\n${target.name}'s ${stolenItem.type.name}!`));
|
||||||
}
|
}
|
||||||
@ -1612,15 +1620,31 @@ export class StealEatBerryAttr extends EatBerryAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 */
|
||||||
private effects: StatusEffect[];
|
private effects: StatusEffect[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param selfTarget - Whether this move targets the user
|
||||||
|
* @param ...effects - List of status effects to cure
|
||||||
|
*/
|
||||||
constructor(selfTarget: boolean, ...effects: StatusEffect[]) {
|
constructor(selfTarget: boolean, ...effects: StatusEffect[]) {
|
||||||
super(selfTarget);
|
super(selfTarget);
|
||||||
|
|
||||||
this.effects = effects;
|
this.effects = effects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param user {@linkcode Pokemon} source of the move
|
||||||
|
* @param target {@linkcode Pokemon} target of the move
|
||||||
|
* @param move the {@linkcode Move} being used
|
||||||
|
* @returns true if the status is cured
|
||||||
|
*/
|
||||||
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)) {
|
||||||
return false;
|
return false;
|
||||||
@ -2680,12 +2704,57 @@ export class HitCountPowerAttr extends VariablePowerAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turning a once was (StatChangeCountPowerAttr) statement and making it available to call for any attribute.
|
||||||
|
* @param {Pokemon} pokemon The pokemon that is being used to calculate the count of positive stats
|
||||||
|
* @returns {number} Returns the amount of positive stats
|
||||||
|
*/
|
||||||
|
const countPositiveStats = (pokemon: Pokemon): number => {
|
||||||
|
return pokemon.summonData.battleStats.reduce((total, stat) => (stat && stat > 0) ? total + stat : total, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute that increases power based on the amount of positive stat increases.
|
||||||
|
*/
|
||||||
export class StatChangeCountPowerAttr extends VariablePowerAttr {
|
export class StatChangeCountPowerAttr extends VariablePowerAttr {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Pokemon} user The pokemon that is being used to calculate the amount of positive stats
|
||||||
|
* @param {Pokemon} target N/A
|
||||||
|
* @param {Move} move N/A
|
||||||
|
* @param {any[]} args The argument for VariablePowerAttr, accumulates and sets the amount of power multiplied by stats
|
||||||
|
* @returns {boolean} 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 positiveStats: number = user.summonData.battleStats.reduce((total, stat) => stat > 0 && stat ? total + stat : total, 0);
|
const positiveStats: number = countPositiveStats(user);
|
||||||
|
|
||||||
(args[0] as Utils.NumberHolder).value += positiveStats * 20;
|
(args[0] as Utils.NumberHolder).value += positiveStats * 20;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Punishment normally has a base power of 60,
|
||||||
|
* but gains 20 power for every increased stat stage the target has,
|
||||||
|
* up to a maximum of 200 base power in total.
|
||||||
|
*/
|
||||||
|
export class PunishmentPowerAttr extends VariablePowerAttr {
|
||||||
|
private PUNISHMENT_MIN_BASE_POWER = 60;
|
||||||
|
private PUNISHMENT_MAX_BASE_POWER = 200;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Pokemon} 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 {Move} move N/A
|
||||||
|
* @param {any[]} args The value that is being changed due to VariablePowerAttr
|
||||||
|
* @returns Returns true if attribute is applied
|
||||||
|
*/
|
||||||
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
|
const positiveStats: number = countPositiveStats(target);
|
||||||
|
(args[0] as Utils.NumberHolder).value = Math.min(
|
||||||
|
this.PUNISHMENT_MAX_BASE_POWER,
|
||||||
|
this.PUNISHMENT_MIN_BASE_POWER + positiveStats * 20
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6110,7 +6179,8 @@ export function initMoves() {
|
|||||||
new StatusMove(Moves.GUARD_SWAP, Type.PSYCHIC, -1, 10, -1, 0, 4)
|
new StatusMove(Moves.GUARD_SWAP, Type.PSYCHIC, -1, 10, -1, 0, 4)
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
new AttackMove(Moves.PUNISHMENT, Type.DARK, MoveCategory.PHYSICAL, -1, 100, 5, -1, 0, 4)
|
new AttackMove(Moves.PUNISHMENT, Type.DARK, MoveCategory.PHYSICAL, -1, 100, 5, -1, 0, 4)
|
||||||
.unimplemented(),
|
.makesContact(true)
|
||||||
|
.attr(PunishmentPowerAttr),
|
||||||
new AttackMove(Moves.LAST_RESORT, Type.NORMAL, MoveCategory.PHYSICAL, 140, 100, 5, -1, 0, 4)
|
new AttackMove(Moves.LAST_RESORT, Type.NORMAL, MoveCategory.PHYSICAL, 140, 100, 5, -1, 0, 4)
|
||||||
.attr(LastResortAttr),
|
.attr(LastResortAttr),
|
||||||
new StatusMove(Moves.WORRY_SEED, Type.GRASS, 100, 10, -1, 0, 4)
|
new StatusMove(Moves.WORRY_SEED, Type.GRASS, 100, 10, -1, 0, 4)
|
||||||
@ -6681,6 +6751,7 @@ export function initMoves() {
|
|||||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||||
new AttackMove(Moves.STEAM_ERUPTION, Type.WATER, MoveCategory.SPECIAL, 110, 95, 5, 30, 0, 6)
|
new AttackMove(Moves.STEAM_ERUPTION, Type.WATER, MoveCategory.SPECIAL, 110, 95, 5, 30, 0, 6)
|
||||||
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
||||||
|
.attr(HealStatusEffectAttr, false, StatusEffect.FREEZE)
|
||||||
.attr(StatusEffectAttr, StatusEffect.BURN),
|
.attr(StatusEffectAttr, StatusEffect.BURN),
|
||||||
new AttackMove(Moves.HYPERSPACE_HOLE, Type.PSYCHIC, MoveCategory.SPECIAL, 80, -1, 5, -1, 0, 6)
|
new AttackMove(Moves.HYPERSPACE_HOLE, Type.PSYCHIC, MoveCategory.SPECIAL, 80, -1, 5, -1, 0, 6)
|
||||||
.ignoresProtect(),
|
.ignoresProtect(),
|
||||||
@ -7357,6 +7428,7 @@ export function initMoves() {
|
|||||||
.attr(MultiHitAttr, MultiHitType._2),
|
.attr(MultiHitAttr, MultiHitType._2),
|
||||||
new AttackMove(Moves.SCORCHING_SANDS, Type.GROUND, MoveCategory.SPECIAL, 70, 100, 10, 30, 0, 8)
|
new AttackMove(Moves.SCORCHING_SANDS, Type.GROUND, MoveCategory.SPECIAL, 70, 100, 10, 30, 0, 8)
|
||||||
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
||||||
|
.attr(HealStatusEffectAttr, false, StatusEffect.FREEZE)
|
||||||
.attr(StatusEffectAttr, StatusEffect.BURN),
|
.attr(StatusEffectAttr, StatusEffect.BURN),
|
||||||
new StatusMove(Moves.JUNGLE_HEALING, Type.GRASS, -1, 10, -1, 0, 8)
|
new StatusMove(Moves.JUNGLE_HEALING, Type.GRASS, -1, 10, -1, 0, 8)
|
||||||
.attr(HealAttr, 0.25, true, false)
|
.attr(HealAttr, 0.25, true, false)
|
||||||
@ -7736,6 +7808,7 @@ export function initMoves() {
|
|||||||
new AttackMove(Moves.MATCHA_GOTCHA, Type.GRASS, MoveCategory.SPECIAL, 80, 90, 15, 20, 0, 9)
|
new AttackMove(Moves.MATCHA_GOTCHA, Type.GRASS, MoveCategory.SPECIAL, 80, 90, 15, 20, 0, 9)
|
||||||
.attr(HitHealAttr)
|
.attr(HitHealAttr)
|
||||||
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
||||||
|
.attr(HealStatusEffectAttr, false, StatusEffect.FREEZE)
|
||||||
.attr(StatusEffectAttr, StatusEffect.BURN)
|
.attr(StatusEffectAttr, StatusEffect.BURN)
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
||||||
.triageMove()
|
.triageMove()
|
||||||
|
@ -765,10 +765,10 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
|||||||
new SpeciesFormChange(Species.DURALUDON, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
|
new SpeciesFormChange(Species.DURALUDON, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
|
||||||
],
|
],
|
||||||
[Species.ZACIAN]: [
|
[Species.ZACIAN]: [
|
||||||
new SpeciesFormChange(Species.ZACIAN, "hero", "crowned", new SpeciesFormChangeItemTrigger(FormChangeItem.RUSTED_SWORD))
|
new SpeciesFormChange(Species.ZACIAN, "hero-of-many-battles", "crowned", new SpeciesFormChangeItemTrigger(FormChangeItem.RUSTED_SWORD))
|
||||||
],
|
],
|
||||||
[Species.ZAMAZENTA]: [
|
[Species.ZAMAZENTA]: [
|
||||||
new SpeciesFormChange(Species.ZAMAZENTA, "hero", "crowned", new SpeciesFormChangeItemTrigger(FormChangeItem.RUSTED_SHIELD))
|
new SpeciesFormChange(Species.ZAMAZENTA, "hero-of-many-battles", "crowned", new SpeciesFormChangeItemTrigger(FormChangeItem.RUSTED_SHIELD))
|
||||||
],
|
],
|
||||||
[Species.ETERNATUS]: [
|
[Species.ETERNATUS]: [
|
||||||
new SpeciesFormChange(Species.ETERNATUS, "", SpeciesFormKey.ETERNAMAX, new SpeciesFormChangeManualTrigger()),
|
new SpeciesFormChange(Species.ETERNATUS, "", SpeciesFormKey.ETERNAMAX, new SpeciesFormChangeManualTrigger()),
|
||||||
|
@ -387,9 +387,11 @@ export abstract class PokemonSpeciesForm {
|
|||||||
case "four":
|
case "four":
|
||||||
case "droopy":
|
case "droopy":
|
||||||
case "stretchy":
|
case "stretchy":
|
||||||
|
case "hero":
|
||||||
case "roaming":
|
case "roaming":
|
||||||
case "complete":
|
case "complete":
|
||||||
case "10":
|
case "10":
|
||||||
|
case "10-pc":
|
||||||
case "super":
|
case "super":
|
||||||
case "unbound":
|
case "unbound":
|
||||||
case "pau":
|
case "pau":
|
||||||
@ -2137,13 +2139,13 @@ export function initSpecies() {
|
|||||||
new PokemonForm("Blue Meteor Form", "blue-meteor", Type.ROCK, Type.FLYING, 0.3, 40, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, "", true),
|
new PokemonForm("Blue Meteor Form", "blue-meteor", Type.ROCK, Type.FLYING, 0.3, 40, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, "", true),
|
||||||
new PokemonForm("Indigo Meteor Form", "indigo-meteor", Type.ROCK, Type.FLYING, 0.3, 40, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, "", true),
|
new PokemonForm("Indigo Meteor Form", "indigo-meteor", Type.ROCK, Type.FLYING, 0.3, 40, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, "", true),
|
||||||
new PokemonForm("Violet Meteor Form", "violet-meteor", Type.ROCK, Type.FLYING, 0.3, 40, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, "", true),
|
new PokemonForm("Violet Meteor Form", "violet-meteor", Type.ROCK, Type.FLYING, 0.3, 40, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 440, 60, 60, 100, 60, 100, 60, 30, 70, 154, false, "", true),
|
||||||
new PokemonForm("Red Core Form", "red", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154),
|
new PokemonForm("Red Core Form", "red", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154, false, null, true),
|
||||||
new PokemonForm("Orange Core Form", "orange", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154),
|
new PokemonForm("Orange Core Form", "orange", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154, false, null, true),
|
||||||
new PokemonForm("Yellow Core Form", "yellow", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154),
|
new PokemonForm("Yellow Core Form", "yellow", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154, false, null, true),
|
||||||
new PokemonForm("Green Core Form", "green", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154),
|
new PokemonForm("Green Core Form", "green", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154, false, null, true),
|
||||||
new PokemonForm("Blue Core Form", "blue", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154),
|
new PokemonForm("Blue Core Form", "blue", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154, false, null, true),
|
||||||
new PokemonForm("Indigo Core Form", "indigo", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154),
|
new PokemonForm("Indigo Core Form", "indigo", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154, false, null, true),
|
||||||
new PokemonForm("Violet Core Form", "violet", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154),
|
new PokemonForm("Violet Core Form", "violet", Type.ROCK, Type.FLYING, 0.3, 0.3, Abilities.SHIELDS_DOWN, Abilities.NONE, Abilities.NONE, 500, 60, 100, 60, 100, 60, 120, 30, 70, 154, false, null, true),
|
||||||
),
|
),
|
||||||
new PokemonSpecies(Species.KOMALA, 7, false, false, false, "Drowsing Pokémon", Type.NORMAL, null, 0.4, 19.9, Abilities.COMATOSE, Abilities.NONE, Abilities.NONE, 480, 65, 115, 65, 75, 95, 65, 45, 70, 168, GrowthRate.SLOW, 50, false),
|
new PokemonSpecies(Species.KOMALA, 7, false, false, false, "Drowsing Pokémon", Type.NORMAL, null, 0.4, 19.9, Abilities.COMATOSE, Abilities.NONE, Abilities.NONE, 480, 65, 115, 65, 75, 95, 65, 45, 70, 168, GrowthRate.SLOW, 50, false),
|
||||||
new PokemonSpecies(Species.TURTONATOR, 7, false, false, false, "Blast Turtle Pokémon", Type.FIRE, Type.DRAGON, 2, 212, Abilities.SHELL_ARMOR, Abilities.NONE, Abilities.NONE, 485, 60, 78, 135, 91, 85, 36, 70, 50, 170, GrowthRate.MEDIUM_FAST, 50, false),
|
new PokemonSpecies(Species.TURTONATOR, 7, false, false, false, "Blast Turtle Pokémon", Type.FIRE, Type.DRAGON, 2, 212, Abilities.SHELL_ARMOR, Abilities.NONE, Abilities.NONE, 485, 60, 78, 135, 91, 85, 36, 70, 50, 170, GrowthRate.MEDIUM_FAST, 50, false),
|
||||||
@ -2272,7 +2274,7 @@ export function initSpecies() {
|
|||||||
new PokemonSpecies(Species.TOXEL, 8, false, false, false, "Baby Pokémon", Type.ELECTRIC, Type.POISON, 0.4, 11, Abilities.RATTLED, Abilities.STATIC, Abilities.KLUTZ, 242, 40, 38, 35, 54, 35, 40, 75, 50, 48, GrowthRate.MEDIUM_SLOW, 50, false),
|
new PokemonSpecies(Species.TOXEL, 8, false, false, false, "Baby Pokémon", Type.ELECTRIC, Type.POISON, 0.4, 11, Abilities.RATTLED, Abilities.STATIC, Abilities.KLUTZ, 242, 40, 38, 35, 54, 35, 40, 75, 50, 48, GrowthRate.MEDIUM_SLOW, 50, false),
|
||||||
new PokemonSpecies(Species.TOXTRICITY, 8, false, false, false, "Punk Pokémon", Type.ELECTRIC, Type.POISON, 1.6, 40, Abilities.PUNK_ROCK, Abilities.PLUS, Abilities.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, GrowthRate.MEDIUM_SLOW, 50, false, true,
|
new PokemonSpecies(Species.TOXTRICITY, 8, false, false, false, "Punk Pokémon", Type.ELECTRIC, Type.POISON, 1.6, 40, Abilities.PUNK_ROCK, Abilities.PLUS, Abilities.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, GrowthRate.MEDIUM_SLOW, 50, false, true,
|
||||||
new PokemonForm("Amped Form", "amped", Type.ELECTRIC, Type.POISON, 1.6, 40, Abilities.PUNK_ROCK, Abilities.PLUS, Abilities.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, false, "", true),
|
new PokemonForm("Amped Form", "amped", Type.ELECTRIC, Type.POISON, 1.6, 40, Abilities.PUNK_ROCK, Abilities.PLUS, Abilities.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, false, "", true),
|
||||||
new PokemonForm("Low-Key Form", "lowkey", Type.ELECTRIC, Type.POISON, 1.6, 40, Abilities.PUNK_ROCK, Abilities.MINUS, Abilities.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, true),
|
new PokemonForm("Low-Key Form", "lowkey", Type.ELECTRIC, Type.POISON, 1.6, 40, Abilities.PUNK_ROCK, Abilities.MINUS, Abilities.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, false, "lowkey", true),
|
||||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ELECTRIC, Type.POISON, 24, 40, Abilities.PUNK_ROCK, Abilities.MINUS, Abilities.TECHNICIAN, 602, 95, 118, 80, 144, 80, 85, 45, 50, 176),
|
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ELECTRIC, Type.POISON, 24, 40, Abilities.PUNK_ROCK, Abilities.MINUS, Abilities.TECHNICIAN, 602, 95, 118, 80, 144, 80, 85, 45, 50, 176),
|
||||||
),
|
),
|
||||||
new PokemonSpecies(Species.SIZZLIPEDE, 8, false, false, false, "Radiator Pokémon", Type.FIRE, Type.BUG, 0.7, 1, Abilities.FLASH_FIRE, Abilities.WHITE_SMOKE, Abilities.FLAME_BODY, 305, 50, 65, 45, 50, 50, 45, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false),
|
new PokemonSpecies(Species.SIZZLIPEDE, 8, false, false, false, "Radiator Pokémon", Type.FIRE, Type.BUG, 0.7, 1, Abilities.FLASH_FIRE, Abilities.WHITE_SMOKE, Abilities.FLAME_BODY, 305, 50, 65, 45, 50, 50, 45, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false),
|
||||||
@ -2355,11 +2357,11 @@ export function initSpecies() {
|
|||||||
new PokemonSpecies(Species.DRAKLOAK, 8, false, false, false, "Caretaker Pokémon", Type.DRAGON, Type.GHOST, 1.4, 11, Abilities.CLEAR_BODY, Abilities.INFILTRATOR, Abilities.CURSED_BODY, 410, 68, 80, 50, 60, 50, 102, 45, 50, 144, GrowthRate.SLOW, 50, false),
|
new PokemonSpecies(Species.DRAKLOAK, 8, false, false, false, "Caretaker Pokémon", Type.DRAGON, Type.GHOST, 1.4, 11, Abilities.CLEAR_BODY, Abilities.INFILTRATOR, Abilities.CURSED_BODY, 410, 68, 80, 50, 60, 50, 102, 45, 50, 144, GrowthRate.SLOW, 50, false),
|
||||||
new PokemonSpecies(Species.DRAGAPULT, 8, false, false, false, "Stealth Pokémon", Type.DRAGON, Type.GHOST, 3, 50, Abilities.CLEAR_BODY, Abilities.INFILTRATOR, Abilities.CURSED_BODY, 600, 88, 120, 75, 100, 75, 142, 45, 50, 300, GrowthRate.SLOW, 50, false),
|
new PokemonSpecies(Species.DRAGAPULT, 8, false, false, false, "Stealth Pokémon", Type.DRAGON, Type.GHOST, 3, 50, Abilities.CLEAR_BODY, Abilities.INFILTRATOR, Abilities.CURSED_BODY, 600, 88, 120, 75, 100, 75, 142, 45, 50, 300, GrowthRate.SLOW, 50, false),
|
||||||
new PokemonSpecies(Species.ZACIAN, 8, false, true, false, "Warrior Pokémon", Type.FAIRY, null, 2.8, 110, Abilities.INTREPID_SWORD, Abilities.NONE, Abilities.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, GrowthRate.SLOW, null, false, false,
|
new PokemonSpecies(Species.ZACIAN, 8, false, true, false, "Warrior Pokémon", Type.FAIRY, null, 2.8, 110, Abilities.INTREPID_SWORD, Abilities.NONE, Abilities.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, GrowthRate.SLOW, null, false, false,
|
||||||
new PokemonForm("Hero of Many Battles", "hero", Type.FAIRY, null, 2.8, 110, Abilities.INTREPID_SWORD, Abilities.NONE, Abilities.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, false, "", true),
|
new PokemonForm("Hero of Many Battles", "hero-of-many-battles", Type.FAIRY, null, 2.8, 110, Abilities.INTREPID_SWORD, Abilities.NONE, Abilities.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, false, "", true),
|
||||||
new PokemonForm("Crowned", "crowned", Type.FAIRY, Type.STEEL, 2.8, 355, Abilities.INTREPID_SWORD, Abilities.NONE, Abilities.NONE, 700, 92, 150, 115, 80, 115, 148, 10, 0, 335),
|
new PokemonForm("Crowned", "crowned", Type.FAIRY, Type.STEEL, 2.8, 355, Abilities.INTREPID_SWORD, Abilities.NONE, Abilities.NONE, 700, 92, 150, 115, 80, 115, 148, 10, 0, 335),
|
||||||
),
|
),
|
||||||
new PokemonSpecies(Species.ZAMAZENTA, 8, false, true, false, "Warrior Pokémon", Type.FIGHTING, null, 2.9, 210, Abilities.DAUNTLESS_SHIELD, Abilities.NONE, Abilities.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, GrowthRate.SLOW, null, false, false,
|
new PokemonSpecies(Species.ZAMAZENTA, 8, false, true, false, "Warrior Pokémon", Type.FIGHTING, null, 2.9, 210, Abilities.DAUNTLESS_SHIELD, Abilities.NONE, Abilities.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, GrowthRate.SLOW, null, false, false,
|
||||||
new PokemonForm("Hero of Many Battles", "hero", Type.FIGHTING, null, 2.9, 210, Abilities.DAUNTLESS_SHIELD, Abilities.NONE, Abilities.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, false, "", true),
|
new PokemonForm("Hero of Many Battles", "hero-of-many-battles", Type.FIGHTING, null, 2.9, 210, Abilities.DAUNTLESS_SHIELD, Abilities.NONE, Abilities.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, false, "", true),
|
||||||
new PokemonForm("Crowned", "crowned", Type.FIGHTING, Type.STEEL, 2.9, 785, Abilities.DAUNTLESS_SHIELD, Abilities.NONE, Abilities.NONE, 700, 92, 120, 140, 80, 140, 128, 10, 0, 335),
|
new PokemonForm("Crowned", "crowned", Type.FIGHTING, Type.STEEL, 2.9, 785, Abilities.DAUNTLESS_SHIELD, Abilities.NONE, Abilities.NONE, 700, 92, 120, 140, 80, 140, 128, 10, 0, 335),
|
||||||
),
|
),
|
||||||
new PokemonSpecies(Species.ETERNATUS, 8, false, true, false, "Gigantic Pokémon", Type.POISON, Type.DRAGON, 20, 950, Abilities.PRESSURE, Abilities.NONE, Abilities.NONE, 690, 140, 85, 95, 145, 95, 130, 255, 0, 345, GrowthRate.SLOW, null, false, true,
|
new PokemonSpecies(Species.ETERNATUS, 8, false, true, false, "Gigantic Pokémon", Type.POISON, Type.DRAGON, 20, 950, Abilities.PRESSURE, Abilities.NONE, Abilities.NONE, 690, 140, 85, 95, 145, 95, 130, 255, 0, 345, GrowthRate.SLOW, null, false, true,
|
||||||
@ -2468,9 +2470,9 @@ export function initSpecies() {
|
|||||||
new PokemonSpecies(Species.WUGTRIO, 9, false, false, false, "Garden Eel Pokémon", Type.WATER, null, 1.2, 5.4, Abilities.GOOEY, Abilities.RATTLED, Abilities.SAND_VEIL, 425, 35, 100, 50, 50, 70, 120, 50, 50, 149, GrowthRate.MEDIUM_FAST, 50, false),
|
new PokemonSpecies(Species.WUGTRIO, 9, false, false, false, "Garden Eel Pokémon", Type.WATER, null, 1.2, 5.4, Abilities.GOOEY, Abilities.RATTLED, Abilities.SAND_VEIL, 425, 35, 100, 50, 50, 70, 120, 50, 50, 149, GrowthRate.MEDIUM_FAST, 50, false),
|
||||||
new PokemonSpecies(Species.BOMBIRDIER, 9, false, false, false, "Item Drop Pokémon", Type.FLYING, Type.DARK, 1.5, 42.9, Abilities.BIG_PECKS, Abilities.KEEN_EYE, Abilities.ROCKY_PAYLOAD, 485, 70, 103, 85, 60, 85, 82, 25, 50, 243, GrowthRate.SLOW, 50, false),
|
new PokemonSpecies(Species.BOMBIRDIER, 9, false, false, false, "Item Drop Pokémon", Type.FLYING, Type.DARK, 1.5, 42.9, Abilities.BIG_PECKS, Abilities.KEEN_EYE, Abilities.ROCKY_PAYLOAD, 485, 70, 103, 85, 60, 85, 82, 25, 50, 243, GrowthRate.SLOW, 50, false),
|
||||||
new PokemonSpecies(Species.FINIZEN, 9, false, false, false, "Dolphin Pokémon", Type.WATER, null, 1.3, 60.2, Abilities.WATER_VEIL, Abilities.NONE, Abilities.NONE, 315, 70, 45, 40, 45, 40, 75, 200, 50, 63, GrowthRate.SLOW, 50, false),
|
new PokemonSpecies(Species.FINIZEN, 9, false, false, false, "Dolphin Pokémon", Type.WATER, null, 1.3, 60.2, Abilities.WATER_VEIL, Abilities.NONE, Abilities.NONE, 315, 70, 45, 40, 45, 40, 75, 200, 50, 63, GrowthRate.SLOW, 50, false),
|
||||||
new PokemonSpecies(Species.PALAFIN, 9, false, false, false, "Dolphin Pokémon", Type.WATER, null, 1.3, 60.2, Abilities.ZERO_TO_HERO, Abilities.NONE, Abilities.NONE, 457, 100, 70, 72, 53, 62, 100, 45, 50, 160, GrowthRate.SLOW, 50, false, false,
|
new PokemonSpecies(Species.PALAFIN, 9, false, false, false, "Dolphin Pokémon", Type.WATER, null, 1.3, 60.2, Abilities.ZERO_TO_HERO, Abilities.NONE, Abilities.NONE, 457, 100, 70, 72, 53, 62, 100, 45, 50, 160, GrowthRate.SLOW, 50, false, true,
|
||||||
new PokemonForm("Zero Form", "zero", Type.WATER, null, 1.3, 60.2, Abilities.ZERO_TO_HERO, Abilities.NONE, Abilities.ZERO_TO_HERO, 457, 100, 70, 72, 53, 62, 100, 45, 50, 160, false, null, true),
|
new PokemonForm("Zero Form", "zero", Type.WATER, null, 1.3, 60.2, Abilities.ZERO_TO_HERO, Abilities.NONE, Abilities.ZERO_TO_HERO, 457, 100, 70, 72, 53, 62, 100, 45, 50, 160, false, null, true),
|
||||||
new PokemonForm("Hero Form", "hero", Type.WATER, null, 1.8, 97.4, Abilities.ZERO_TO_HERO, Abilities.NONE, Abilities.ZERO_TO_HERO, 650, 100, 160, 97, 106, 87, 100, 45, 50, 160, false, null),
|
new PokemonForm("Hero Form", "hero", Type.WATER, null, 1.8, 97.4, Abilities.ZERO_TO_HERO, Abilities.NONE, Abilities.ZERO_TO_HERO, 650, 100, 160, 97, 106, 87, 100, 45, 50, 160),
|
||||||
),
|
),
|
||||||
new PokemonSpecies(Species.VAROOM, 9, false, false, false, "Single-Cyl Pokémon", Type.STEEL, Type.POISON, 1, 35, Abilities.OVERCOAT, Abilities.NONE, Abilities.SLOW_START, 300, 45, 70, 63, 30, 45, 47, 190, 50, 60, GrowthRate.MEDIUM_FAST, 50, false),
|
new PokemonSpecies(Species.VAROOM, 9, false, false, false, "Single-Cyl Pokémon", Type.STEEL, Type.POISON, 1, 35, Abilities.OVERCOAT, Abilities.NONE, Abilities.SLOW_START, 300, 45, 70, 63, 30, 45, 47, 190, 50, 60, GrowthRate.MEDIUM_FAST, 50, false),
|
||||||
new PokemonSpecies(Species.REVAVROOM, 9, false, false, false, "Multi-Cyl Pokémon", Type.STEEL, Type.POISON, 1.8, 120, Abilities.OVERCOAT, Abilities.NONE, Abilities.FILTER, 500, 80, 119, 90, 54, 67, 90, 75, 50, 175, GrowthRate.MEDIUM_FAST, 50, false),
|
new PokemonSpecies(Species.REVAVROOM, 9, false, false, false, "Multi-Cyl Pokémon", Type.STEEL, Type.POISON, 1.8, 120, Abilities.OVERCOAT, Abilities.NONE, Abilities.FILTER, 500, 80, 119, 90, 54, 67, 90, 75, 50, 175, GrowthRate.MEDIUM_FAST, 50, false),
|
||||||
|
@ -989,6 +989,8 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
[TrainerType.DEPOT_AGENT]: new TrainerConfig(++t).setMoneyMultiplier(1.45).setEncounterBgm(TrainerType.CLERK),
|
[TrainerType.DEPOT_AGENT]: new TrainerConfig(++t).setMoneyMultiplier(1.45).setEncounterBgm(TrainerType.CLERK),
|
||||||
[TrainerType.DOCTOR]: new TrainerConfig(++t).setHasGenders("Nurse", "lass").setHasDouble("Medical Team").setMoneyMultiplier(3).setEncounterBgm(TrainerType.CLERK)
|
[TrainerType.DOCTOR]: new TrainerConfig(++t).setHasGenders("Nurse", "lass").setHasDouble("Medical Team").setMoneyMultiplier(3).setEncounterBgm(TrainerType.CLERK)
|
||||||
.setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.HEAL_PULSE)),
|
.setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.HEAL_PULSE)),
|
||||||
|
[TrainerType.FIREBREATHER]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.ROUGHNECK)
|
||||||
|
.setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.SMOG) || s.isOfType(Type.FIRE)),
|
||||||
[TrainerType.FISHERMAN]: new TrainerConfig(++t).setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.BACKPACKER).setSpecialtyTypes(Type.WATER)
|
[TrainerType.FISHERMAN]: new TrainerConfig(++t).setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.BACKPACKER).setSpecialtyTypes(Type.WATER)
|
||||||
.setPartyTemplates(trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.THREE_WEAK_SAME, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.SIX_WEAKER)
|
.setPartyTemplates(trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.THREE_WEAK_SAME, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.SIX_WEAKER)
|
||||||
.setSpeciesPools({
|
.setSpeciesPools({
|
||||||
|
@ -36,6 +36,7 @@ const trainerNameConfigs: TrainerNameConfigs = {
|
|||||||
[TrainerType.DANCER]: new TrainerNameConfig(TrainerType.DANCER),
|
[TrainerType.DANCER]: new TrainerNameConfig(TrainerType.DANCER),
|
||||||
[TrainerType.DEPOT_AGENT]: new TrainerNameConfig(TrainerType.DEPOT_AGENT),
|
[TrainerType.DEPOT_AGENT]: new TrainerNameConfig(TrainerType.DEPOT_AGENT),
|
||||||
[TrainerType.DOCTOR]: new TrainerNameConfig(TrainerType.DOCTOR).hasGenderVariant("Nurse"),
|
[TrainerType.DOCTOR]: new TrainerNameConfig(TrainerType.DOCTOR).hasGenderVariant("Nurse"),
|
||||||
|
[TrainerType.FIREBREATHER]: new TrainerNameConfig(TrainerType.FIREBREATHER),
|
||||||
[TrainerType.FISHERMAN]: new TrainerNameConfig(TrainerType.FISHERMAN),
|
[TrainerType.FISHERMAN]: new TrainerNameConfig(TrainerType.FISHERMAN),
|
||||||
[TrainerType.GUITARIST]: new TrainerNameConfig(TrainerType.GUITARIST),
|
[TrainerType.GUITARIST]: new TrainerNameConfig(TrainerType.GUITARIST),
|
||||||
[TrainerType.HARLEQUIN]: new TrainerNameConfig(TrainerType.HARLEQUIN),
|
[TrainerType.HARLEQUIN]: new TrainerNameConfig(TrainerType.HARLEQUIN),
|
||||||
@ -87,6 +88,7 @@ export const trainerNamePools = {
|
|||||||
[TrainerType.DANCER]: ["Brian","Davey","Dirk","Edmond","Mickey","Raymond","Cara","Julia","Maika","Mireille","Ronda","Zoe"],
|
[TrainerType.DANCER]: ["Brian","Davey","Dirk","Edmond","Mickey","Raymond","Cara","Julia","Maika","Mireille","Ronda","Zoe"],
|
||||||
[TrainerType.DEPOT_AGENT]: ["Josh","Hank","Vincent"],
|
[TrainerType.DEPOT_AGENT]: ["Josh","Hank","Vincent"],
|
||||||
[TrainerType.DOCTOR]: [["Hank","Jerry","Jules","Logan","Wayne","Braid","Derek","Heath","Julius","Kit","Graham"],["Kirsten","Sachiko","Shery","Carol","Dixie","Mariah"]],
|
[TrainerType.DOCTOR]: [["Hank","Jerry","Jules","Logan","Wayne","Braid","Derek","Heath","Julius","Kit","Graham"],["Kirsten","Sachiko","Shery","Carol","Dixie","Mariah"]],
|
||||||
|
[TrainerType.FIREBREATHER]: ["Bill","Burt","Cliff","Dick","Lyle","Ned","Otis","Ray","Richard","Walt"],
|
||||||
[TrainerType.FISHERMAN]: ["Andre","Arnold","Barney","Chris","Edgar","Henry","Jonah","Justin","Kyle","Martin","Marvin","Ralph","Raymond","Scott","Stephen","Wilton","Tully","Andrew","Barny","Carter","Claude","Dale","Elliot","Eugene","Ivan","Ned","Nolan","Roger","Ronald","Wade","Wayne","Darian","Kai","Chip","Hank","Kaden","Tommy","Tylor","Alec","Brett","Cameron","Cody","Cole","Cory","Erick","George","Joseph","Juan","Kenneth","Luc","Miguel","Travis","Walter","Zachary","Josh","Gideon","Kyler","Liam","Murphy","Bruce","Damon","Devon","Hubert","Jones","Lydon","Mick","Pete","Sean","Sid","Vince","Bucky","Dean","Eustace","Kenzo","Leroy","Mack","Ryder","Ewan","Finn","Murray","Seward","Shad","Wharton","Finley","Fisher","Fisk","River","Sheaffer","Timin","Carl","Ernest","Hal","Herbert","Hisato","Mike","Vernon","Harriet","Marina","Chase"],
|
[TrainerType.FISHERMAN]: ["Andre","Arnold","Barney","Chris","Edgar","Henry","Jonah","Justin","Kyle","Martin","Marvin","Ralph","Raymond","Scott","Stephen","Wilton","Tully","Andrew","Barny","Carter","Claude","Dale","Elliot","Eugene","Ivan","Ned","Nolan","Roger","Ronald","Wade","Wayne","Darian","Kai","Chip","Hank","Kaden","Tommy","Tylor","Alec","Brett","Cameron","Cody","Cole","Cory","Erick","George","Joseph","Juan","Kenneth","Luc","Miguel","Travis","Walter","Zachary","Josh","Gideon","Kyler","Liam","Murphy","Bruce","Damon","Devon","Hubert","Jones","Lydon","Mick","Pete","Sean","Sid","Vince","Bucky","Dean","Eustace","Kenzo","Leroy","Mack","Ryder","Ewan","Finn","Murray","Seward","Shad","Wharton","Finley","Fisher","Fisk","River","Sheaffer","Timin","Carl","Ernest","Hal","Herbert","Hisato","Mike","Vernon","Harriet","Marina","Chase"],
|
||||||
[TrainerType.GUITARIST]: ["Anna","Beverly","January","Tina","Alicia","Claudia","Julia","Lidia","Mireia","Noelia","Sara","Sheila","Tatiana"],
|
[TrainerType.GUITARIST]: ["Anna","Beverly","January","Tina","Alicia","Claudia","Julia","Lidia","Mireia","Noelia","Sara","Sheila","Tatiana"],
|
||||||
[TrainerType.HARLEQUIN]: ["Charley","Ian","Jack","Kerry","Louis","Pat","Paul","Rick","Anders","Clarence","Gary"],
|
[TrainerType.HARLEQUIN]: ["Charley","Ian","Jack","Kerry","Louis","Pat","Paul","Rick","Anders","Clarence","Gary"],
|
||||||
|
@ -14,30 +14,51 @@ import { EggTier } from "./data/enums/egg-type";
|
|||||||
import PokemonInfoContainer from "./ui/pokemon-info-container";
|
import PokemonInfoContainer from "./ui/pokemon-info-container";
|
||||||
import EggsToHatchCountContainer from "./ui/eggs-to-hatch-count-container";
|
import EggsToHatchCountContainer from "./ui/eggs-to-hatch-count-container";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that represents egg hatching
|
||||||
|
*/
|
||||||
export class EggHatchPhase extends Phase {
|
export class EggHatchPhase extends Phase {
|
||||||
|
/** The egg that is hatching */
|
||||||
private egg: Egg;
|
private egg: Egg;
|
||||||
|
|
||||||
|
/** The number of eggs that are hatching */
|
||||||
private eggsToHatchCount: integer;
|
private eggsToHatchCount: integer;
|
||||||
|
/** The container that lists how many eggs are hatching */
|
||||||
private eggsToHatchCountContainer: EggsToHatchCountContainer;
|
private eggsToHatchCountContainer: EggsToHatchCountContainer;
|
||||||
|
|
||||||
|
/** The scene handler for egg hatching */
|
||||||
private eggHatchHandler: EggHatchSceneHandler;
|
private eggHatchHandler: EggHatchSceneHandler;
|
||||||
|
/** The phaser gameobject container that holds everything */
|
||||||
private eggHatchContainer: Phaser.GameObjects.Container;
|
private eggHatchContainer: Phaser.GameObjects.Container;
|
||||||
|
/** The phaser image that is the background */
|
||||||
private eggHatchBg: Phaser.GameObjects.Image;
|
private eggHatchBg: Phaser.GameObjects.Image;
|
||||||
|
/** The phaser rectangle that overlays during the scene */
|
||||||
private eggHatchOverlay: Phaser.GameObjects.Rectangle;
|
private eggHatchOverlay: Phaser.GameObjects.Rectangle;
|
||||||
|
/** The phaser container that holds the egg */
|
||||||
private eggContainer: Phaser.GameObjects.Container;
|
private eggContainer: Phaser.GameObjects.Container;
|
||||||
|
/** The phaser sprite of the egg */
|
||||||
private eggSprite: Phaser.GameObjects.Sprite;
|
private eggSprite: Phaser.GameObjects.Sprite;
|
||||||
|
/** The phaser sprite of the cracks in an egg */
|
||||||
private eggCrackSprite: Phaser.GameObjects.Sprite;
|
private eggCrackSprite: Phaser.GameObjects.Sprite;
|
||||||
|
/** The phaser sprite that represents the overlaid light rays */
|
||||||
private eggLightraysOverlay: Phaser.GameObjects.Sprite;
|
private eggLightraysOverlay: Phaser.GameObjects.Sprite;
|
||||||
|
/** The phaser sprite of the hatched Pokemon */
|
||||||
private pokemonSprite: Phaser.GameObjects.Sprite;
|
private pokemonSprite: Phaser.GameObjects.Sprite;
|
||||||
|
/** The phaser sprite for shiny sparkles */
|
||||||
private pokemonShinySparkle: Phaser.GameObjects.Sprite;
|
private pokemonShinySparkle: Phaser.GameObjects.Sprite;
|
||||||
|
|
||||||
|
/** The {@link PokemonInfoContainer} of the newly hatched Pokemon */
|
||||||
private infoContainer: PokemonInfoContainer;
|
private infoContainer: PokemonInfoContainer;
|
||||||
|
|
||||||
|
/** The newly hatched {@link PlayerPokemon} */
|
||||||
private pokemon: PlayerPokemon;
|
private pokemon: PlayerPokemon;
|
||||||
|
/** The index of which egg move is unlocked. 0-2 is common, 3 is rare */
|
||||||
private eggMoveIndex: integer;
|
private eggMoveIndex: integer;
|
||||||
|
/** Internal booleans representing if the egg is hatched, able to be skipped, or skipped */
|
||||||
private hatched: boolean;
|
private hatched: boolean;
|
||||||
private canSkip: boolean;
|
private canSkip: boolean;
|
||||||
private skipped: boolean;
|
private skipped: boolean;
|
||||||
|
/** The sound effect being played when the egg is hatched */
|
||||||
private evolutionBgm: AnySound;
|
private evolutionBgm: AnySound;
|
||||||
|
|
||||||
constructor(scene: BattleScene, egg: Egg, eggsToHatchCount: integer) {
|
constructor(scene: BattleScene, egg: Egg, eggsToHatchCount: integer) {
|
||||||
@ -117,6 +138,7 @@ export class EggHatchPhase extends Phase {
|
|||||||
|
|
||||||
this.eggHatchContainer.add(this.infoContainer);
|
this.eggHatchContainer.add(this.infoContainer);
|
||||||
|
|
||||||
|
// The game will try to unfuse any Pokemon even though eggs should not generate fused Pokemon in the first place
|
||||||
const pokemon = this.generatePokemon();
|
const pokemon = this.generatePokemon();
|
||||||
if (pokemon.fusionSpecies) {
|
if (pokemon.fusionSpecies) {
|
||||||
pokemon.clearFusionSpecies();
|
pokemon.clearFusionSpecies();
|
||||||
@ -187,6 +209,13 @@ export class EggHatchPhase extends Phase {
|
|||||||
super.end();
|
super.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that animates egg shaking
|
||||||
|
* @param intensity of horizontal shaking. Doubled on the first call (where count is 0)
|
||||||
|
* @param repeatCount the number of times this function should be called (asynchronous recursion?!?)
|
||||||
|
* @param count the current number of times this function has been called.
|
||||||
|
* @returns nothing since it's a Promise<void>
|
||||||
|
*/
|
||||||
doEggShake(intensity: number, repeatCount?: integer, count?: integer): Promise<void> {
|
doEggShake(intensity: number, repeatCount?: integer, count?: integer): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
if (repeatCount === undefined) {
|
if (repeatCount === undefined) {
|
||||||
@ -226,6 +255,10 @@ export class EggHatchPhase extends Phase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to skip the hatching animation
|
||||||
|
* @returns false if cannot be skipped or already skipped. True otherwise
|
||||||
|
*/
|
||||||
trySkip(): boolean {
|
trySkip(): boolean {
|
||||||
if (!this.canSkip || this.skipped) {
|
if (!this.canSkip || this.skipped) {
|
||||||
return false;
|
return false;
|
||||||
@ -239,6 +272,9 @@ export class EggHatchPhase extends Phase {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays the animation of an egg hatch
|
||||||
|
*/
|
||||||
doHatch(): void {
|
doHatch(): void {
|
||||||
this.canSkip = false;
|
this.canSkip = false;
|
||||||
this.hatched = true;
|
this.hatched = true;
|
||||||
@ -268,6 +304,9 @@ export class EggHatchPhase extends Phase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to do the logic and animation of completing a hatch and revealing the Pokemon
|
||||||
|
*/
|
||||||
doReveal(): void {
|
doReveal(): void {
|
||||||
// Update/reduce count of hatching eggs when revealed if count is at least 1
|
// Update/reduce count of hatching eggs when revealed if count is at least 1
|
||||||
// If count is 0, hide eggsToHatchCountContainer instead
|
// If count is 0, hide eggsToHatchCountContainer instead
|
||||||
@ -333,10 +372,21 @@ export class EggHatchPhase extends Phase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to generate sine. (Why is this not a Utils?!?)
|
||||||
|
* @param index random number from 0-7 being passed in to scale pi/128
|
||||||
|
* @param amplitude Scaling
|
||||||
|
* @returns a number
|
||||||
|
*/
|
||||||
sin(index: integer, amplitude: integer): number {
|
sin(index: integer, amplitude: integer): number {
|
||||||
return amplitude * Math.sin(index * (Math.PI / 128));
|
return amplitude * Math.sin(index * (Math.PI / 128));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animates spraying
|
||||||
|
* @param intensity number of times this is repeated (this is a badly named variable)
|
||||||
|
* @param offsetY how much to offset the Y coordinates
|
||||||
|
*/
|
||||||
doSpray(intensity: integer, offsetY?: number) {
|
doSpray(intensity: integer, offsetY?: number) {
|
||||||
this.scene.tweens.addCounter({
|
this.scene.tweens.addCounter({
|
||||||
repeat: intensity,
|
repeat: intensity,
|
||||||
@ -347,6 +397,11 @@ export class EggHatchPhase extends Phase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animates a particle used in the spray animation
|
||||||
|
* @param trigIndex Used to modify the particle's vertical speed, is a random number from 0-7
|
||||||
|
* @param offsetY how much to offset the Y coordinate
|
||||||
|
*/
|
||||||
doSprayParticle(trigIndex: integer, offsetY: number) {
|
doSprayParticle(trigIndex: integer, offsetY: number) {
|
||||||
const initialX = this.eggHatchBg.displayWidth / 2;
|
const initialX = this.eggHatchBg.displayWidth / 2;
|
||||||
const initialY = this.eggHatchBg.displayHeight / 2 + offsetY;
|
const initialY = this.eggHatchBg.displayHeight / 2 + offsetY;
|
||||||
@ -387,12 +442,22 @@ export class EggHatchPhase extends Phase {
|
|||||||
updateParticle();
|
updateParticle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a Pokemon to be hatched by the egg
|
||||||
|
* @returns the hatched PlayerPokemon
|
||||||
|
*/
|
||||||
generatePokemon(): PlayerPokemon {
|
generatePokemon(): PlayerPokemon {
|
||||||
let ret: PlayerPokemon;
|
let ret: PlayerPokemon;
|
||||||
let speciesOverride: Species;
|
let speciesOverride: Species; // SpeciesOverride should probably be a passed in parameter for future species-eggs
|
||||||
|
|
||||||
this.scene.executeWithSeedOffset(() => {
|
this.scene.executeWithSeedOffset(() => {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manaphy eggs have a 1/8 chance of being Manaphy and 7/8 chance of being Phione
|
||||||
|
* Legendary eggs pulled from the legendary gacha have a 50% of being converted into
|
||||||
|
* the species that was the legendary focus at the time
|
||||||
|
*/
|
||||||
if (this.egg.isManaphyEgg()) {
|
if (this.egg.isManaphyEgg()) {
|
||||||
const rand = Utils.randSeedInt(8);
|
const rand = Utils.randSeedInt(8);
|
||||||
|
|
||||||
@ -437,6 +502,18 @@ export class EggHatchPhase extends Phase {
|
|||||||
.map(s => parseInt(s) as Species)
|
.map(s => parseInt(s) as Species)
|
||||||
.filter(s => !pokemonPrevolutions.hasOwnProperty(s) && getPokemonSpecies(s).isObtainable() && ignoredSpecies.indexOf(s) === -1);
|
.filter(s => !pokemonPrevolutions.hasOwnProperty(s) && getPokemonSpecies(s).isObtainable() && ignoredSpecies.indexOf(s) === -1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokemon that are cheaper in their tier get a weight boost. Regionals get a weight penalty
|
||||||
|
* 1 cost mons get 2x
|
||||||
|
* 2 cost mons get 1.5x
|
||||||
|
* 4, 6, 8 cost mons get 1.75x
|
||||||
|
* 3, 5, 7, 9 cost mons get 1x
|
||||||
|
* Alolan, Galarian, and Paldean mons get 0.5x
|
||||||
|
* Hisui mons get 0.125x
|
||||||
|
*
|
||||||
|
* The total weight is also being calculated EACH time there is an egg hatch instead of being generated once
|
||||||
|
* and being the same each time
|
||||||
|
*/
|
||||||
let totalWeight = 0;
|
let totalWeight = 0;
|
||||||
const speciesWeights = [];
|
const speciesWeights = [];
|
||||||
for (const speciesId of speciesPool) {
|
for (const speciesId of speciesPool) {
|
||||||
@ -464,6 +541,16 @@ export class EggHatchPhase extends Phase {
|
|||||||
ret = this.scene.addPlayerPokemon(pokemonSpecies, 1, undefined, undefined, undefined, false);
|
ret = this.scene.addPlayerPokemon(pokemonSpecies, 1, undefined, undefined, undefined, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non Shiny gacha Pokemon have a 1/128 chance of being shiny
|
||||||
|
* Shiny gacha Pokemon have a 1/64 chance of being shiny
|
||||||
|
* IVs are rolled twice and the higher of each stat's IV is taken
|
||||||
|
* The egg move gacha doubles the rate of rare egg moves but the base rates are
|
||||||
|
* Common: 1/48
|
||||||
|
* Rare: 1/24
|
||||||
|
* Epic: 1/12
|
||||||
|
* Legendary: 1/6
|
||||||
|
*/
|
||||||
ret.trySetShiny(this.egg.gachaType === GachaType.SHINY ? 1024 : 512);
|
ret.trySetShiny(this.egg.gachaType === GachaType.SHINY ? 1024 : 512);
|
||||||
ret.variant = ret.shiny ? ret.generateVariant() : 0;
|
ret.variant = ret.shiny ? ret.generateVariant() : 0;
|
||||||
|
|
||||||
|
77
src/field/arena-events.ts
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import { ArenaTagSide } from "#app/data/arena-tag.js";
|
||||||
|
import { ArenaTagType } from "#app/data/enums/arena-tag-type.js";
|
||||||
|
import { TerrainType } from "#app/data/terrain.js";
|
||||||
|
import { WeatherType } from "#app/data/weather.js";
|
||||||
|
|
||||||
|
/** Alias for all {@linkcode ArenaEvent} type strings */
|
||||||
|
export enum ArenaEventType {
|
||||||
|
/** Triggers when a {@linkcode WeatherType} is added, overlapped, or removed */
|
||||||
|
WEATHER_CHANGED = "onWeatherChanged",
|
||||||
|
/** Triggers when a {@linkcode TerrainType} is added, overlapped, or removed */
|
||||||
|
TERRAIN_CHANGED = "onTerrainChanged",
|
||||||
|
|
||||||
|
/** Triggers when a {@linkcode ArenaTagType} is added or removed */
|
||||||
|
TAG_CHANGED = "onTagChanged",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base container class for all {@linkcode ArenaEventType} events
|
||||||
|
* @extends Event
|
||||||
|
*/
|
||||||
|
export class ArenaEvent extends Event {
|
||||||
|
/** The total duration of the {@linkcode ArenaEventType} */
|
||||||
|
public duration: number;
|
||||||
|
constructor(eventType: ArenaEventType, duration: number) {
|
||||||
|
super(eventType);
|
||||||
|
|
||||||
|
this.duration = duration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Container class for {@linkcode ArenaEventType.WEATHER_CHANGED} events
|
||||||
|
* @extends ArenaEvent
|
||||||
|
*/
|
||||||
|
export class WeatherChangedEvent extends ArenaEvent {
|
||||||
|
/** The {@linkcode WeatherType} being overridden */
|
||||||
|
public oldWeatherType: WeatherType;
|
||||||
|
/** The {@linkcode WeatherType} being set */
|
||||||
|
public newWeatherType: WeatherType;
|
||||||
|
constructor(oldWeatherType: WeatherType, newWeatherType: WeatherType, duration: number) {
|
||||||
|
super(ArenaEventType.WEATHER_CHANGED, duration);
|
||||||
|
|
||||||
|
this.oldWeatherType = oldWeatherType;
|
||||||
|
this.newWeatherType = newWeatherType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Container class for {@linkcode ArenaEventType.TERRAIN_CHANGED} events
|
||||||
|
* @extends ArenaEvent
|
||||||
|
*/
|
||||||
|
export class TerrainChangedEvent extends ArenaEvent {
|
||||||
|
/** The {@linkcode TerrainType} being overridden */
|
||||||
|
public oldTerrainType: TerrainType;
|
||||||
|
/** The {@linkcode TerrainType} being set */
|
||||||
|
public newTerrainType: TerrainType;
|
||||||
|
constructor(oldTerrainType: TerrainType, newTerrainType: TerrainType, duration: number) {
|
||||||
|
super(ArenaEventType.TERRAIN_CHANGED, duration);
|
||||||
|
|
||||||
|
this.oldTerrainType = oldTerrainType;
|
||||||
|
this.newTerrainType = newTerrainType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Container class for {@linkcode ArenaEventType.TAG_CHANGED} events
|
||||||
|
* @extends ArenaEvent
|
||||||
|
*/
|
||||||
|
export class TagChangedEvent extends ArenaEvent {
|
||||||
|
/** The {@linkcode ArenaTagType} being set */
|
||||||
|
public arenaTagType: ArenaTagType;
|
||||||
|
/** The {@linkcode ArenaTagSide} the tag is being placed on */
|
||||||
|
public arenaTagSide: ArenaTagSide;
|
||||||
|
constructor(arenaTagType: ArenaTagType, arenaTagSide: ArenaTagSide, duration: number) {
|
||||||
|
super(ArenaEventType.TAG_CHANGED, duration);
|
||||||
|
|
||||||
|
this.arenaTagType = arenaTagType;
|
||||||
|
this.arenaTagSide = arenaTagSide;
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@ import { Terrain, TerrainType } from "../data/terrain";
|
|||||||
import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability";
|
import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability";
|
||||||
import Pokemon from "./pokemon";
|
import Pokemon from "./pokemon";
|
||||||
import * as Overrides from "../overrides";
|
import * as Overrides from "../overrides";
|
||||||
|
import { WeatherChangedEvent, TerrainChangedEvent, TagChangedEvent } from "./arena-events";
|
||||||
|
|
||||||
export class Arena {
|
export class Arena {
|
||||||
public scene: BattleScene;
|
public scene: BattleScene;
|
||||||
@ -34,6 +35,8 @@ export class Arena {
|
|||||||
private pokemonPool: PokemonPools;
|
private pokemonPool: PokemonPools;
|
||||||
private trainerPool: BiomeTierTrainerPools;
|
private trainerPool: BiomeTierTrainerPools;
|
||||||
|
|
||||||
|
public readonly eventTarget: EventTarget = new EventTarget();
|
||||||
|
|
||||||
constructor(scene: BattleScene, biome: Biome, bgm: string) {
|
constructor(scene: BattleScene, biome: Biome, bgm: string) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.biomeType = biome;
|
this.biomeType = biome;
|
||||||
@ -300,6 +303,7 @@ export class Arena {
|
|||||||
const oldWeatherType = this.weather?.weatherType || WeatherType.NONE;
|
const oldWeatherType = this.weather?.weatherType || WeatherType.NONE;
|
||||||
|
|
||||||
this.weather = weather ? new Weather(weather, hasPokemonSource ? 5 : 0) : null;
|
this.weather = weather ? new Weather(weather, hasPokemonSource ? 5 : 0) : null;
|
||||||
|
this.eventTarget.dispatchEvent(new WeatherChangedEvent(oldWeatherType, this.weather?.weatherType, this.weather?.turnsLeft));
|
||||||
|
|
||||||
if (this.weather) {
|
if (this.weather) {
|
||||||
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.SUNNY + (weather - 1)));
|
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.SUNNY + (weather - 1)));
|
||||||
@ -324,6 +328,7 @@ export class Arena {
|
|||||||
const oldTerrainType = this.terrain?.terrainType || TerrainType.NONE;
|
const oldTerrainType = this.terrain?.terrainType || TerrainType.NONE;
|
||||||
|
|
||||||
this.terrain = terrain ? new Terrain(terrain, hasPokemonSource ? 5 : 0) : null;
|
this.terrain = terrain ? new Terrain(terrain, hasPokemonSource ? 5 : 0) : null;
|
||||||
|
this.eventTarget.dispatchEvent(new TerrainChangedEvent(oldTerrainType,this.terrain?.terrainType, this.terrain?.turnsLeft));
|
||||||
|
|
||||||
if (this.terrain) {
|
if (this.terrain) {
|
||||||
if (!ignoreAnim) {
|
if (!ignoreAnim) {
|
||||||
@ -545,6 +550,8 @@ export class Arena {
|
|||||||
this.tags.push(newTag);
|
this.tags.push(newTag);
|
||||||
newTag.onAdd(this);
|
newTag.onAdd(this);
|
||||||
|
|
||||||
|
this.eventTarget.dispatchEvent(new TagChangedEvent(newTag.tagType, newTag.side, newTag.turnCount));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -978,7 +978,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
if (this.isOnField() && !ability.hasAttr(SuppressFieldAbilitiesAbAttr)) {
|
if (this.isOnField() && !ability.hasAttr(SuppressFieldAbilitiesAbAttr)) {
|
||||||
const suppressed = new Utils.BooleanHolder(false);
|
const suppressed = new Utils.BooleanHolder(false);
|
||||||
this.scene.getField(true).map(p => {
|
this.scene.getField(true).filter(p => p !== this).map(p => {
|
||||||
if (p.getAbility().hasAttr(SuppressFieldAbilitiesAbAttr) && p.canApplyAbility()) {
|
if (p.getAbility().hasAttr(SuppressFieldAbilitiesAbAttr) && p.canApplyAbility()) {
|
||||||
p.getAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, false, suppressed, [ability]));
|
p.getAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, false, suppressed, [ability]));
|
||||||
}
|
}
|
||||||
@ -1222,7 +1222,22 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that tries to set a Pokemon shiny based on the trainer's trainer ID and secret ID
|
||||||
|
* Endless Pokemon in the end biome are unable to be set to shiny
|
||||||
|
*
|
||||||
|
* The exact mechanic is that it calculates E as the XOR of the player's trainer ID and secret ID
|
||||||
|
* F is calculated as the XOR of the first 16 bits of the Pokemon's ID with the last 16 bits
|
||||||
|
* The XOR of E and F are then compared to the thresholdOverride (default case 32) to see whether or not to generate a shiny
|
||||||
|
* @param thresholdOverride number that is divided by 2^16 (65536) to get the shiny chance
|
||||||
|
* @returns true if the Pokemon has been set as a shiny, false otherwise
|
||||||
|
*/
|
||||||
trySetShiny(thresholdOverride?: integer): boolean {
|
trySetShiny(thresholdOverride?: integer): boolean {
|
||||||
|
// Shiny Pokemon should not spawn in the end biome in endless
|
||||||
|
if (this.scene.gameMode.isEndless && this.scene.arena.biomeType === Biome.END) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const rand1 = Utils.binToDec(Utils.decToBin(this.id).substring(0, 16));
|
const rand1 = Utils.binToDec(Utils.decToBin(this.id).substring(0, 16));
|
||||||
const rand2 = Utils.binToDec(Utils.decToBin(this.id).substring(16, 32));
|
const rand2 = Utils.binToDec(Utils.decToBin(this.id).substring(16, 32));
|
||||||
|
|
||||||
@ -1250,18 +1265,25 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return this.shiny;
|
return this.shiny;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a variant
|
||||||
|
* Has a 10% of returning 2 (epic variant)
|
||||||
|
* And a 30% of returning 1 (rare variant)
|
||||||
|
* Returns 0 (basic shiny) if there is no variant or 60% of the time otherwise
|
||||||
|
* @returns the shiny variant
|
||||||
|
*/
|
||||||
generateVariant(): Variant {
|
generateVariant(): Variant {
|
||||||
if (!this.shiny || !variantData.hasOwnProperty(this.species.speciesId)) {
|
if (!this.shiny || !variantData.hasOwnProperty(this.species.speciesId)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const rand = Utils.randSeedInt(10);
|
const rand = Utils.randSeedInt(10);
|
||||||
if (rand > 3) {
|
if (rand >= 4) {
|
||||||
return 0;
|
return 0; // 6/10
|
||||||
|
} else if (rand >= 1) {
|
||||||
|
return 1; // 3/10
|
||||||
|
} else {
|
||||||
|
return 2; // 1/10
|
||||||
}
|
}
|
||||||
if (rand) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
generateFusionSpecies(forStarter?: boolean): void {
|
generateFusionSpecies(forStarter?: boolean): void {
|
||||||
@ -3167,7 +3189,7 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
&& (m as PokemonHeldItemModifier).pokemonId === pokemon.id, true) as PokemonHeldItemModifier[];
|
&& (m as PokemonHeldItemModifier).pokemonId === pokemon.id, true) as PokemonHeldItemModifier[];
|
||||||
const transferModifiers: Promise<boolean>[] = [];
|
const transferModifiers: Promise<boolean>[] = [];
|
||||||
for (const modifier of fusedPartyMemberHeldModifiers) {
|
for (const modifier of fusedPartyMemberHeldModifiers) {
|
||||||
transferModifiers.push(this.scene.tryTransferHeldItemModifier(modifier, this, true, false, true, true));
|
transferModifiers.push(this.scene.tryTransferHeldItemModifier(modifier, this, false, modifier.getStackCount(), true, true));
|
||||||
}
|
}
|
||||||
Promise.allSettled(transferModifiers).then(() => {
|
Promise.allSettled(transferModifiers).then(() => {
|
||||||
this.scene.updateModifiers(true, true).then(() => {
|
this.scene.updateModifiers(true, true).then(() => {
|
||||||
|
@ -3,4 +3,5 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
|||||||
export const abilityTriggers: SimpleTranslationEntries = {
|
export const abilityTriggers: SimpleTranslationEntries = {
|
||||||
"blockRecoilDamage" : "{{pokemonName}} wurde durch {{abilityName}}\nvor Rückstoß geschützt!",
|
"blockRecoilDamage" : "{{pokemonName}} wurde durch {{abilityName}}\nvor Rückstoß geschützt!",
|
||||||
"badDreams": "{{pokemonName}} ist in einem Alptraum gefangen!",
|
"badDreams": "{{pokemonName}} ist in einem Alptraum gefangen!",
|
||||||
|
"windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!",
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -367,6 +367,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "Ich werde für das nächste Rennen tunen."
|
1: "Ich werde für das nächste Rennen tunen."
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"firebreather": {
|
||||||
|
"encounter": {
|
||||||
|
1: "My flames shall devour you!",
|
||||||
|
2: "My soul is on fire. I'll show you how hot it burns!",
|
||||||
|
3: "Step right up and take a look!"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: "I burned down to ashes...",
|
||||||
|
2: "Yow! That's hot!",
|
||||||
|
3: "Ow! I scorched the tip of my nose!"
|
||||||
|
},
|
||||||
|
},
|
||||||
"brock": {
|
"brock": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "Meine Expertise in Bezug auf Gesteins-Pokémon wird dich besiegen! Komm schon!",
|
1: "Meine Expertise in Bezug auf Gesteins-Pokémon wird dich besiegen! Komm schon!",
|
||||||
@ -516,7 +528,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "Oh, es scheint, als hätte ich verloren.",
|
1: "Oh, es scheint, als hätte ich verloren.",
|
||||||
2: "Es scheint, als hätte ich noch so viel mehr zu lernen, wenn es um den Kämpfe geht.",
|
2: "Es scheint, als hätte ich noch so viel mehr zu lernen, wenn es um Kämpfe geht.",
|
||||||
3: "Ich werde mir zu Herzen nehmen, was ich heute gelernt habe."
|
3: "Ich werde mir zu Herzen nehmen, was ich heute gelernt habe."
|
||||||
},
|
},
|
||||||
"defeat": {
|
"defeat": {
|
||||||
@ -775,7 +787,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"marshal": {
|
"marshal": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `Mein Mentor, Lauro, sieht sieht Potential in dir. Ich werde dich testen,
|
1: `Mein Mentor, Lauro, sieht Potential in dir. Ich werde dich testen,
|
||||||
$dich an die Grenzen deiner Stärke bringen. Kiai!`,
|
$dich an die Grenzen deiner Stärke bringen. Kiai!`,
|
||||||
2: "Ein Sieg, ein entscheidender Sieg, das ist mein Ziel! Herausforderer, hier komme ich!",
|
2: "Ein Sieg, ein entscheidender Sieg, das ist mein Ziel! Herausforderer, hier komme ich!",
|
||||||
3: "Ich selber suche die Stärke eines Kämpfers zu entwickeln und jede Schwäche in mir zu brechen!"
|
3: "Ich selber suche die Stärke eines Kämpfers zu entwickeln und jede Schwäche in mir zu brechen!"
|
||||||
@ -930,7 +942,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"lacey": {
|
"lacey": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "Ich werde dir mit meiner gewohnten Team, als Mitglied der Top Vier gegenüberstehen."
|
1: "Ich werde dir mit meinem gewohnten Team, als Mitglied der Top Vier gegenüberstehen."
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "Das war ein großartiger Kampf!"
|
1: "Das war ein großartiger Kampf!"
|
||||||
@ -1025,7 +1037,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"cress": {
|
"cress": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "Das ist korrekt! Ich und meine geschätzten Wasser-Typen werden deine Gegner im Kampf sein!"
|
1: "Das ist korrekt! Ich und meine geschätzten Wasser-Pokémon werden deine Gegner im Kampf sein!"
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "Verlieren? Ich? Das glaube ich nicht."
|
1: "Verlieren? Ich? Das glaube ich nicht."
|
||||||
@ -1234,8 +1246,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"bugsy": {
|
"bugsy": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `Wow, erstaunlich! Du bist ein Experte für Pokémon!
|
1: "Ich bin Kai, der Arenaleiter von Azalea City. Ich bin ein großer Fan von Käfer-Pokémon.",
|
||||||
$Meine Forschung ist noch nicht abgeschlossen. OK, du gewinnst.`,
|
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: `Wow, erstaunlich! Du bist ein Experte für Pokémon!
|
1: `Wow, erstaunlich! Du bist ein Experte für Pokémon!
|
||||||
|
@ -48,6 +48,7 @@ export const trainerClasses: SimpleTranslationEntries = {
|
|||||||
"depot_agent": "Bahnangestellter",
|
"depot_agent": "Bahnangestellter",
|
||||||
"doctor": "Arzt",
|
"doctor": "Arzt",
|
||||||
"doctor_female": "Ärztin",
|
"doctor_female": "Ärztin",
|
||||||
|
"firebreather": "Feuerspucker",
|
||||||
"fisherman": "Angler",
|
"fisherman": "Angler",
|
||||||
"fisherman_female": "Angler", // Seems to be the same in german but exists in other languages like italian
|
"fisherman_female": "Angler", // Seems to be the same in german but exists in other languages like italian
|
||||||
"gentleman": "Gentleman",
|
"gentleman": "Gentleman",
|
||||||
|
@ -3,5 +3,7 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
|||||||
export const abilityTriggers: SimpleTranslationEntries = {
|
export const abilityTriggers: SimpleTranslationEntries = {
|
||||||
"blockRecoilDamage" : "{{pokemonName}}'s {{abilityName}}\nprotected it from recoil!",
|
"blockRecoilDamage" : "{{pokemonName}}'s {{abilityName}}\nprotected it from recoil!",
|
||||||
"badDreams": "{{pokemonName}} is tormented!",
|
"badDreams": "{{pokemonName}} is tormented!",
|
||||||
"perishBody": "{{pokemonName}}'s {{abilityName}}\n will faint both pokemon in 3 turns!",
|
"windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!",
|
||||||
|
"perishBody": "{{pokemonName}}'s {{abilityName}}\nwill faint both pokemon in 3 turns!",
|
||||||
|
"poisonHeal": "{{pokemonName}}'s {{abilityName}}\nrestored its HP a little!"
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -359,6 +359,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "I'll tune up for the next race."
|
1: "I'll tune up for the next race."
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"firebreather": {
|
||||||
|
"encounter": {
|
||||||
|
1: "My flames shall devour you!",
|
||||||
|
2: "My soul is on fire. I'll show you how hot it burns!",
|
||||||
|
3: "Step right up and take a look!"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: "I burned down to ashes...",
|
||||||
|
2: "Yow! That's hot!",
|
||||||
|
3: "Ow! I scorched the tip of my nose!"
|
||||||
|
},
|
||||||
|
},
|
||||||
"brock": {
|
"brock": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
||||||
@ -1203,8 +1215,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"bugsy": {
|
"bugsy": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `Whoa, amazing! You're an expert on Pokémon!
|
1: "I'm Bugsy! I never lose when it comes to bug Pokémon!"
|
||||||
$My research isn't complete yet. OK, you win.`,
|
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
||||||
|
@ -209,6 +209,9 @@ export const modifierType: ModifierTypeTranslationEntries = {
|
|||||||
"LEFTOVERS": { name: "Leftovers", description: "Heals 1/16 of a Pokémon's maximum HP every turn" },
|
"LEFTOVERS": { name: "Leftovers", description: "Heals 1/16 of a Pokémon's maximum HP every turn" },
|
||||||
"SHELL_BELL": { name: "Shell Bell", description: "Heals 1/8 of a Pokémon's dealt damage" },
|
"SHELL_BELL": { name: "Shell Bell", description: "Heals 1/8 of a Pokémon's dealt damage" },
|
||||||
|
|
||||||
|
"TOXIC_ORB": { name: "Toxic Orb", description: "Badly poisons its holder at the end of the turn if they do not have a status condition already" },
|
||||||
|
"FLAME_ORB": { name: "Flame Orb", description: "Burns its holder at the end of the turn if they do not have a status condition already" },
|
||||||
|
|
||||||
"BATON": { name: "Baton", description: "Allows passing along effects when switching Pokémon, which also bypasses traps" },
|
"BATON": { name: "Baton", description: "Allows passing along effects when switching Pokémon, which also bypasses traps" },
|
||||||
|
|
||||||
"SHINY_CHARM": { name: "Shiny Charm", description: "Dramatically increases the chance of a wild Pokémon being Shiny" },
|
"SHINY_CHARM": { name: "Shiny Charm", description: "Dramatically increases the chance of a wild Pokémon being Shiny" },
|
||||||
|
@ -48,6 +48,7 @@ export const trainerClasses: SimpleTranslationEntries = {
|
|||||||
"depot_agent": "Depot Agent",
|
"depot_agent": "Depot Agent",
|
||||||
"doctor": "Doctor",
|
"doctor": "Doctor",
|
||||||
"doctor_female": "Doctor",
|
"doctor_female": "Doctor",
|
||||||
|
"firebreather": "Firebreather",
|
||||||
"fisherman": "Fisherman",
|
"fisherman": "Fisherman",
|
||||||
"fisherman_female": "Fisherman",
|
"fisherman_female": "Fisherman",
|
||||||
"gentleman": "Gentleman",
|
"gentleman": "Gentleman",
|
||||||
|
@ -2,5 +2,6 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
|||||||
|
|
||||||
export const abilityTriggers: SimpleTranslationEntries = {
|
export const abilityTriggers: SimpleTranslationEntries = {
|
||||||
"blockRecoilDamage" : "¡{{abilityName}} de {{pokemonName}}\nlo protegió del daño de retroceso!",
|
"blockRecoilDamage" : "¡{{abilityName}} de {{pokemonName}}\nlo protegió del daño de retroceso!",
|
||||||
"badDreams": "¡{{pokemonName}} está atormentado!"
|
"badDreams": "¡{{pokemonName}} está atormentado!",
|
||||||
|
"windPowerCharged": "¡{{pokemonName}} se ha cargado de electricidad gracias a {{moveName}}!",
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -359,6 +359,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "I'll tune up for the next race."
|
1: "I'll tune up for the next race."
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"firebreather": {
|
||||||
|
"encounter": {
|
||||||
|
1: "My flames shall devour you!",
|
||||||
|
2: "My soul is on fire. I'll show you how hot it burns!",
|
||||||
|
3: "Step right up and take a look!"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: "I burned down to ashes...",
|
||||||
|
2: "Yow! That's hot!",
|
||||||
|
3: "Ow! I scorched the tip of my nose!"
|
||||||
|
},
|
||||||
|
},
|
||||||
"brock": {
|
"brock": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
||||||
@ -1203,8 +1215,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"bugsy": {
|
"bugsy": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `Whoa, amazing! You're an expert on Pokémon!
|
1: "I'm Bugsy! I never lose when it comes to bug Pokémon!"
|
||||||
$My research isn't complete yet. OK, you win.`,
|
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
||||||
|
@ -48,6 +48,7 @@ export const trainerClasses: SimpleTranslationEntries = {
|
|||||||
"depot_agent": "Ferroviario",
|
"depot_agent": "Ferroviario",
|
||||||
"doctor": "Enfermero",
|
"doctor": "Enfermero",
|
||||||
"doctor_female": "Enfermera",
|
"doctor_female": "Enfermera",
|
||||||
|
"firebreather": "Comefuegos",
|
||||||
"fisherman": "Pescador",
|
"fisherman": "Pescador",
|
||||||
"fisherman_female": "Pescadora",
|
"fisherman_female": "Pescadora",
|
||||||
"gentleman": "Aristócrata",
|
"gentleman": "Aristócrata",
|
||||||
|
@ -2,5 +2,6 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
|||||||
|
|
||||||
export const abilityTriggers: SimpleTranslationEntries = {
|
export const abilityTriggers: SimpleTranslationEntries = {
|
||||||
"blockRecoilDamage" : "{{abilityName}}\nde {{pokemonName}} le protège du contrecoup !",
|
"blockRecoilDamage" : "{{abilityName}}\nde {{pokemonName}} le protège du contrecoup !",
|
||||||
"badDreams": "{{pokemonName}} a le sommeil agité !"
|
"badDreams": "{{pokemonName}} a le sommeil agité !",
|
||||||
|
"windPowerCharged": "{{pokemonName}} a été touché par la capacité {{moveName}} et se charge en électricité !"
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -359,6 +359,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "I'll tune up for the next race."
|
1: "I'll tune up for the next race."
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"firebreather": {
|
||||||
|
"encounter": {
|
||||||
|
1: "My flames shall devour you!",
|
||||||
|
2: "My soul is on fire. I'll show you how hot it burns!",
|
||||||
|
3: "Step right up and take a look!"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: "I burned down to ashes...",
|
||||||
|
2: "Yow! That's hot!",
|
||||||
|
3: "Ow! I scorched the tip of my nose!"
|
||||||
|
},
|
||||||
|
},
|
||||||
"brock": {
|
"brock": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
||||||
@ -1203,8 +1215,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"bugsy": {
|
"bugsy": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `Whoa, amazing! You're an expert on Pokémon!
|
1: "I'm Bugsy! I never lose when it comes to bug Pokémon!"
|
||||||
$My research isn't complete yet. OK, you win.`,
|
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
||||||
|
@ -48,6 +48,7 @@ export const trainerClasses: SimpleTranslationEntries = {
|
|||||||
"depot_agent": "Cheminot",
|
"depot_agent": "Cheminot",
|
||||||
"doctor": "Docteur",
|
"doctor": "Docteur",
|
||||||
"doctor_female": "Docteure",
|
"doctor_female": "Docteure",
|
||||||
|
"firebreather": "Firebreather",
|
||||||
"fisherman": "Pêcheur",
|
"fisherman": "Pêcheur",
|
||||||
"fisherman_female": "Pêcheuse",
|
"fisherman_female": "Pêcheuse",
|
||||||
"gentleman": "Gentleman",
|
"gentleman": "Gentleman",
|
||||||
|
@ -3,4 +3,5 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
|||||||
export const abilityTriggers: SimpleTranslationEntries = {
|
export const abilityTriggers: SimpleTranslationEntries = {
|
||||||
"blockRecoilDamage" : "{{abilityName}} di {{pokemonName}}\nl'ha protetto dal contraccolpo!",
|
"blockRecoilDamage" : "{{abilityName}} di {{pokemonName}}\nl'ha protetto dal contraccolpo!",
|
||||||
"badDreams": "{{pokemonName}} è tormentato!",
|
"badDreams": "{{pokemonName}} è tormentato!",
|
||||||
|
"windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!",
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -359,6 +359,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "I'll tune up for the next race."
|
1: "I'll tune up for the next race."
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"firebreather": {
|
||||||
|
"encounter": {
|
||||||
|
1: "My flames shall devour you!",
|
||||||
|
2: "My soul is on fire. I'll show you how hot it burns!",
|
||||||
|
3: "Step right up and take a look!"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: "I burned down to ashes...",
|
||||||
|
2: "Yow! That's hot!",
|
||||||
|
3: "Ow! I scorched the tip of my nose!"
|
||||||
|
},
|
||||||
|
},
|
||||||
"brock": {
|
"brock": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
||||||
@ -1203,8 +1215,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"bugsy": {
|
"bugsy": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `Whoa, amazing! You're an expert on Pokémon!
|
1: "I'm Bugsy! I never lose when it comes to bug Pokémon!"
|
||||||
$My research isn't complete yet. OK, you win.`,
|
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
||||||
|
@ -48,6 +48,7 @@ export const trainerClasses: SimpleTranslationEntries = {
|
|||||||
"depot_agent": "Depot Agent",
|
"depot_agent": "Depot Agent",
|
||||||
"doctor": "Doctor",
|
"doctor": "Doctor",
|
||||||
"doctor_female": "Doctor",
|
"doctor_female": "Doctor",
|
||||||
|
"firebreather": "Firebreather",
|
||||||
"fisherman": "Fisherman",
|
"fisherman": "Fisherman",
|
||||||
"fisherman_female": "Fisherman",
|
"fisherman_female": "Fisherman",
|
||||||
"gentleman": "Gentleman",
|
"gentleman": "Gentleman",
|
||||||
|
@ -2,5 +2,5 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
|||||||
|
|
||||||
export const abilityTriggers: SimpleTranslationEntries = {
|
export const abilityTriggers: SimpleTranslationEntries = {
|
||||||
"blockRecoilDamage" : "{{pokemonName}}(는)은 {{abilityName}} 때문에\n반동 데미지를 받지 않는다!",
|
"blockRecoilDamage" : "{{pokemonName}}(는)은 {{abilityName}} 때문에\n반동 데미지를 받지 않는다!",
|
||||||
"badDreams": "{{pokemonName}} is tormented!",
|
"badDreams": "{{pokemonName}}(는)은\n나이트메어 때문에 시달리고 있다!",
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -15,7 +15,7 @@ export const battle: SimpleTranslationEntries = {
|
|||||||
"trainerDefeated": "{{trainerName}}과(와)의\n승부에서 이겼다!",
|
"trainerDefeated": "{{trainerName}}과(와)의\n승부에서 이겼다!",
|
||||||
"moneyWon": "상금으로\n₽{{moneyAmount}}을 손에 넣었다!",
|
"moneyWon": "상금으로\n₽{{moneyAmount}}을 손에 넣었다!",
|
||||||
"pokemonCaught": "신난다-!\n{{pokemonName}}(를)을 잡았다!",
|
"pokemonCaught": "신난다-!\n{{pokemonName}}(를)을 잡았다!",
|
||||||
"partyFull": "지닌 포켓몬이 가득 찼습니다. {{pokemonName}}(를)\n대신해 포켓몬을 놓아주시겠습니까?",
|
"partyFull": "지닌 포켓몬이 가득 찼습니다. {{pokemonName}}를(을)\n대신해 포켓몬을 놓아주시겠습니까?",
|
||||||
"pokemon": "포켓몬",
|
"pokemon": "포켓몬",
|
||||||
"sendOutPokemon": "가랏! {{pokemonName}}!",
|
"sendOutPokemon": "가랏! {{pokemonName}}!",
|
||||||
"hitResultCriticalHit": "급소에 맞았다!",
|
"hitResultCriticalHit": "급소에 맞았다!",
|
||||||
|
@ -359,6 +359,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "I'll tune up for the next race."
|
1: "I'll tune up for the next race."
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"firebreather": {
|
||||||
|
"encounter": {
|
||||||
|
1: "My flames shall devour you!",
|
||||||
|
2: "My soul is on fire. I'll show you how hot it burns!",
|
||||||
|
3: "Step right up and take a look!"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: "I burned down to ashes...",
|
||||||
|
2: "Yow! That's hot!",
|
||||||
|
3: "Ow! I scorched the tip of my nose!"
|
||||||
|
},
|
||||||
|
},
|
||||||
"brock": {
|
"brock": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
||||||
@ -1203,8 +1215,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"bugsy": {
|
"bugsy": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `Whoa, amazing! You're an expert on Pokémon!
|
1: "I'm Bugsy! I never lose when it comes to bug Pokémon!"
|
||||||
$My research isn't complete yet. OK, you win.`,
|
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
||||||
@ -2086,127 +2097,125 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"rival": {
|
"rival": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `@c{smile}Hey, I was looking for you! I knew you were eager to get going but I expected at least a goodbye…
|
1: `@c{smile}오, 찾았다! 떠나려는 건 알고 있었지만\n인사정도는 해줄 줄 알았는데…
|
||||||
$@c{smile_eclosed}So you're really pursuing your dream after all?\n I almost can't believe it.
|
$@c{smile_eclosed}그러니까 정말로 꿈을 좇겠다는 거지?\n듣고도 못 믿었다니까.
|
||||||
$@c{serious_smile_fists}Since we're here, how about a battle?\nAfter all, I want to make sure you're ready.
|
$@c{serious_smile_fists}여기까지 온 김에, 배틀은 어때?\n준비가 됐나 보자구.
|
||||||
$@c{serious_mopen_fists}Don't hold back, I want you to give me everything you've got!`
|
$@c{serious_mopen_fists}망설이지 말고,\n너의 진면목을 보여봐!`
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: `@c{shock}Wow… You cleaned me out.\nAre you actually a beginner?
|
1: `@c{shock}와… 정말 깔끔하게 당했네.\n초보자 맞아?
|
||||||
$@c{smile}Maybe it was a bit of luck but…\nWho knows you might just be able to go all the way.
|
$@c{smile}운이 따른 건지도 모르겠지만…\n그래도 정말 꿈을 이룰 지도.
|
||||||
$By the way, the professor asked me to give you these items. They look pretty cool.
|
$그나저나, 박사님께서 이걸 전해달라고 하시더라.\n좋아 보이던데.
|
||||||
$@c{serious_smile_fists}Good luck out there!`
|
$@c{serious_smile_fists}아무튼, 힘 내는거야!`
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"rival_female": {
|
"rival_female": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `@c{smile_wave}There you are! I've been looking everywhere for you!\n@c{angry_mopen}Did you forget to say goodbye to your best friend?
|
1: `@c{smile_wave}여깄구나! 찾고 있었어!\n@c{angry_mopen}절친한테 작별인사도 안 하는거야?
|
||||||
$@c{smile_ehalf}You're going after your dream, huh?\nThat day is really today isn't it…
|
$@c{smile_ehalf}꿈을 향해 떠나는거구나. 그렇지?\n이런 날이 오긴 하네…
|
||||||
$@c{smile}Anyway, I'll forgive you for forgetting me, but on one condition. @c{smile_wave_wink}You have to battle me!
|
$@c{smile}아무튼, 날 까먹고 가버린 건 용서해주겠어.\n@c{smile_wave_wink}배틀을 해준다면 말야!
|
||||||
$@c{angry_mopen}Give it your all! Wouldn't want your adventure to be over before it started, right?`
|
$@c{angry_mopen}최선을 다 해 봐.\n모험을 시작과 동시에 끝내고 싶지 않다면!`
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: `@c{shock}You just started and you're already this strong?!@d{96}\n@c{angry}You totally cheated, didn't you?
|
1: `@c{shock}왜 벌써 이렇게 센 건데?!@d{96}\n@c{angry}아니면 뭔가 속임수, 그런 거?
|
||||||
$@c{smile_wave_wink}Just kidding!@d{64} @c{smile_eclosed}I lost fair and square… I have a feeling you're going to do really well out there.
|
$@c{smile_wave_wink}농담, 농담!@d{64} @c{smile_eclosed}내가 진 거 맞아…\n너 정말 앞으로도 잘 하겠는데.
|
||||||
$@c{smile}By the way, the professor wanted me to give you some items. Hopefully they're helpful!
|
$@c{smile}아 그래, 박사님께서 전해달라던 물건.\n도움이 되면 좋겠어!
|
||||||
$@c{smile_wave}Do your best like always! I believe in you!`
|
$@c{smile_wave}항상 최선을 다 하라구! 믿고 있을게!`
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"rival_2": {
|
"rival_2": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `@c{smile}Hey, you're here too?\n@c{smile_eclosed}Still a perfect record, huh…?
|
1: `@c{smile}어라, 너 여깄었구나?\n@c{smile_eclosed}아직도 전승 중이라, 이거지…?
|
||||||
$@c{serious_mopen_fists}I know it kind of looks like I followed you here, but that's mostly not true.
|
$@c{serious_mopen_fists}널 쫓아서 온 것 같아 보이겠지만, 오해야.
|
||||||
$@c{serious_smile_fists}Honestly though, I've been itching for a rematch since you beat me back at home.
|
$@c{serious_smile_fists}그래도 솔직히 그 때부터 쭉 재대결이 간절했어.
|
||||||
$I've been doing a lot of my own training so I'll definitely put up a fight this time.
|
$그 동안의 훈련도 있겠다 마침 좋은 기회같지?
|
||||||
$@c{serious_mopen_fists}Don't hold back, just like before!\nLet's go!`
|
$@c{serious_mopen_fists}자, 전처럼!\n배틀이야!`
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: `@c{neutral_eclosed}Oh. I guess I was overconfident.
|
1: `@c{neutral_eclosed}이런. 자신감이 과했나봐.
|
||||||
$@c{smile}That's alright, though. I figured this might happen.\n@c{serious_mopen_fists}It just means I need to try harder for next time!\n
|
$@c{smile}그래, 또 지고 말았네.\n@c{serious_mopen_fists}좀 더 열심히 훈련을 해야겠어!\n
|
||||||
$@c{smile}Oh, not that you really need the help, but I had an extra one of these lying around and figured you might want it.\n
|
$@c{smile}너한테 도움이 필요할 것 같지는 않지만, 이거.\n남는 게 있어서 말이야.
|
||||||
$@c{serious_smile_fists}Don't expect another one after this, though!\nI can't keep giving my opponent an advantage after all.
|
$@c{serious_smile_fists}물론 이번이 마지막이야, 알겠지?\n공평하게 하지 않으면 그게 내 핑계거리가 되고 말거야.
|
||||||
$@c{smile}Anyway, take care!`
|
$@c{smile}이제 갈게. 앞으로도 조심하고!`
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"rival_2_female": {
|
"rival_2_female": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `@c{smile_wave}Oh, fancy meeting you here. Looks like you're still undefeated. @c{angry_mopen}Huh… Not bad!
|
1: `@c{smile_wave}우연이네, 이런 곳에서 만나고.\n아직 연전연승이구나? @c{angry_mopen}나쁘지 않아!
|
||||||
$@c{angry_mopen}I know what you're thinking, and no, I wasn't creeping on you. @c{smile_eclosed}I just happened to be in the area.
|
$@c{angry_mopen}무슨 생각하고있는지 알겠어, 하지만 아냐.\n@c{smile_eclosed}우연히 근처에 있었을 뿐이라구.
|
||||||
$@c{smile_ehalf}I'm happy for you but I just want to let you know that it's OK to lose sometimes.
|
$@c{smile_ehalf}그래도 마침, 가끔은 지는것도 괜찮다고 알려주고 싶었는데.
|
||||||
$@c{smile}We learn from our mistakes, often more than we would if we kept succeeding.
|
$@c{smile}우린 실수를 통해서도 성장할 수 있잖아.\n때로는 성공을 반복할 때보다도 더 많이 말야.
|
||||||
$@c{angry_mopen}In any case, I've been training hard for our rematch, so you'd better give it your all!`
|
$@c{angry_mopen}어쨌든간에, 나도 이런 때를 위해 훈련해왔으니까,\n너도 최선을 다 하는게 좋을 거야!`
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: `@c{neutral}I… wasn't supposed to lose that time…
|
1: `@c{neutral}이… 번에도 져버릴 줄이야…
|
||||||
$@c{smile}Aw well. That just means I'll have to train even harder for next time!
|
$@c{smile}으, 그래. 더 열심히 훈련하면 되겠지!
|
||||||
$@c{smile_wave}I also got you another one of these!\n@c{smile_wave_wink}No need to thank me~.
|
$@c{smile_wave}이것도 하나 더 챙겨왔으니 받아!\n@c{smile_wave_wink}감사 인사는 됐다구~.
|
||||||
$@c{angry_mopen}This is the last one, though! You won't be getting anymore freebies from me after this!
|
$@c{angry_mopen}하지만, 마지막이야!\n또 이렇게 공짜로 나눠주진 않을 테니까!
|
||||||
$@c{smile_wave}Keep at it!`
|
$@c{smile_wave}그럼!`
|
||||||
},
|
},
|
||||||
"defeat": {
|
"defeat": {
|
||||||
1: "It's OK to lose sometimes…"
|
1: "가끔은 지는 것도 괜찮아…"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rival_3": {
|
"rival_3": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `@c{smile}Hey, look who it is! It's been a while.\n@c{neutral}You're… still undefeated? Huh.
|
1: `@c{smile}이게 누구야! 오랜만이야.\n@c{neutral}역시나… 쭉 이기고 있었구나?
|
||||||
$@c{neutral_eclosed}Things have been kind of… strange.\nIt's not the same back home without you.
|
$@c{neutral_eclosed}상황이 좀… 그렇더라. \n혼자 마을로 돌아가봤자 너 없인 예전같아질 수 없겠지.
|
||||||
$@c{serious}I know it's selfish, but I need to get this off my chest.\n@c{neutral_eclosed}I think you're in over your head here.
|
$@c{serious}이기적인 이야기란건 알지만 말해야겠어.\n@c{neutral_eclosed}너 지금 좀 아닌 것 같아.
|
||||||
$@c{serious}Never losing once is just unrealistic.\nWe need to lose sometimes in order to grow.
|
$@c{serious}계속 이기기만 하겠다는 건 너무 비현실적이야.\n사람은 원래 꺾여가며 성장하는 거라고.
|
||||||
$@c{neutral_eclosed}You've had a great run but there's still so much ahead, and it only gets harder. @c{neutral}Are you prepared for that?
|
$@c{neutral_eclosed}물론 지금까지는 잘 해왔다고 생각하겠지만,\n갈 길이 멀지. @c{neutral}대비는 되어 있어?
|
||||||
$@c{serious_mopen_fists}If so, prove it to me.`
|
$@c{serious_mopen_fists}그렇다면, 내게 증명해 줘.`
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "@c{angry_mhalf}This is ridiculous… I've hardly stopped training…\nHow are we still so far apart?"
|
1: "@c{angry_mhalf}말도 안 돼… 한시도 쉬지 않고 훈련했는데…\n어째서 전혀 닿을 수 없는거야?"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"rival_3_female": {
|
"rival_3_female": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `@c{smile_wave}Long time no see! Still haven't lost, huh.\n@c{angry}You're starting to get on my nerves. @c{smile_wave_wink}Just kidding!
|
1: `@c{smile_wave}오랜만이야! 아직도 안 졌구나.\n@c{angry}거슬리게 말야. @c{smile_wave_wink}농담이야!
|
||||||
$@c{smile_ehalf}But really, don't you miss home by now? Or… me?\nI… I mean, we've really missed you.
|
$@c{smile_ehalf}하지만 진짜, 고향이 그립진 않아? 집이나… 나는?\n나… 나는, 네가 정말 그리웠어.
|
||||||
$@c{smile_eclosed}I support you in your dream and everything, but the reality is you're going to lose sooner or later.
|
$@c{smile_eclosed}난 너의 꿈과 모든 것을 응원하지만,\n넌 언젠가 패배를 겪게 될 거야.
|
||||||
$@c{smile}And when you do, I'll be there for you like always.\n@c{angry_mopen}Now, let me show you how strong I've become!`
|
$@c{smile}그 땐 언제나처럼 내가 곁에 있어줄게.\n@c{angry_mopen}내가 얼마나 강해졌는지도, 지금 보여 줄 테니까!`
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "@c{shock}After all that… it wasn't enough…?\nYou'll never come back at this rate…"
|
1: "@c{shock}이렇게까지 했는데도… 모자랐던 거야…?\n이러면 정말로 너는 이제 영영…"
|
||||||
|
|
||||||
},
|
},
|
||||||
"defeat": {
|
"defeat": {
|
||||||
1: "You gave it your best, now let's go home."
|
1: "최선을 다 했지.\n집에 갈 시간이야."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rival_4": {
|
"rival_4": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `@c{neutral}Hey.
|
1: `@c{neutral}안녕.
|
||||||
$I won't mince words or pleasantries with you.\n@c{neutral_eclosed}I'm here to win, plain and simple.
|
$잡담은 넘어가자.\n@c{neutral_eclosed}너에게 이기기 위해 찾아왔어. 간단하지.
|
||||||
$@c{serious_mhalf_fists}I've learned to maximize my potential by putting all my time into training.
|
$@c{serious_mhalf_fists}이제 잠재력을 끌어내는 법은 확실히 알겠어.
|
||||||
$@c{smile}You get a lot of extra time when you cut out the unnecessary sleep and social interaction.
|
$@c{smile}잠이나 사회적인 활동들.\n줄일 수 있는 불필요한 시간이 아주 많더라.
|
||||||
$@c{serious_mopen_fists}None of that matters anymore, not until I win.
|
$@c{serious_mopen_fists}오직 승리 뿐이야.\n이제 아무것도 중요하지 않아.
|
||||||
$@c{neutral_eclosed}I've even reached the point where I don't lose anymore.\n@c{smile_eclosed}I suppose your philosophy wasn't so wrong after all.
|
$@c{neutral_eclosed}나도 이제 더 이상은 지지 않게 됐어.\n@c{smile_eclosed}네 그 철학이 완전히 틀린 건 아니었나봐.
|
||||||
$@c{angry_mhalf}Losing is for the weak, and I'm not weak anymore.
|
$@c{angry_mhalf}패배는 약자에게 주어지는 것이고, 난 더 이상 약하지 않아.
|
||||||
$@c{serious_mopen_fists}Prepare yourself.`
|
$@c{serious_mopen_fists}준비해.`
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "@c{neutral}What…@d{64} What are you?"
|
1: "@c{neutral}너…@d{64} 너 대체 뭐야?"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"rival_4_female": {
|
"rival_4_female": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `@c{neutral}It's me! You didn't forget about me again… did you?
|
1: `@c{neutral}나야! 날 잊어버리고 있던 건… 아니지?
|
||||||
$@c{smile}You should be proud of how far you made it. Congrats!\nBut it looks like it's the end of your journey.
|
$@c{smile}네 업적에 자랑스러워 할 때가 됐어. 축하해!\n하지만 네 여행도 여기까지야.
|
||||||
$@c{smile_eclosed}You've awoken something in me I never knew was there.\nIt seems like all I do now is train.
|
$@c{smile_eclosed}너는 나도 모르던 내 안의 무언가를 일깨웠어.\n이제 훈련 말고는 아무것도 하지 않아.
|
||||||
$@c{smile_ehalf}I hardly even eat or sleep now, I just train my Pokémon all day, getting stronger every time.
|
$@c{smile_ehalf}먹지도 자지도 않고, 그저 하루종일.\n더 강해지고 있어.
|
||||||
$@c{neutral}In fact, I… hardly recognize myself.
|
$@c{neutral}사실, 나… 이제 내가 뭔지도 잘 모르겠어.
|
||||||
$And now, I've finally reached peak performance.\nI don't think anyone could beat me now.
|
$그렇지만 기량만은, 정점에 다다랐지.\n아무도 내게 이길 수 없을거야.
|
||||||
$And you know what? It's all because of you.\n@c{smile_ehalf}I don't know whether to thank you or hate you.
|
$그거 알아? 이게 전부 네 덕이야.\n@c{smile_ehalf}감사해야할지 증오해야할지 모르겠네.
|
||||||
$@c{angry_mopen}Prepare yourself.`
|
$@c{angry_mopen}준비해.`
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "@c{neutral}What…@d{64} What are you?"
|
1: "@c{neutral}너…@d{64} 너 대체 뭐야?"
|
||||||
|
|
||||||
},
|
},
|
||||||
"defeat": {
|
"defeat": {
|
||||||
1: "$@c{smile}You should be proud of how far you made it."
|
1: "$@c{smile}네가 키운 상대야. 자랑스럽지?"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rival_5": {
|
"rival_5": {
|
||||||
@ -2231,47 +2240,46 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"rival_6": {
|
"rival_6": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `@c{smile_eclosed}We meet again.
|
1: `@c{smile_eclosed}다시 만났구나.
|
||||||
$@c{neutral}I've had some time to reflect on all this.\nThere's a reason this all seems so strange.
|
$@c{neutral}모든 걸 되짚어 봤어.\n이 기이함에도 이유가 있더라.
|
||||||
$@c{neutral_eclosed}Your dream, my drive to beat you…\nIt's all a part of something greater.
|
$@c{neutral_eclosed}널 이기고자 하는 욕구, 아니면 네 꿈…\n이건 그저 더 큰 무언가의 일부일 뿐이었어.
|
||||||
$@c{serious}This isn't about me, or about you… This is about the world, @c{serious_mhalf_fists}and it's my purpose to push you to your limits.
|
$@c{serious}개인의 문제가 아니라 세계 전체가 엮인 일이었고…\n@c{serious_mhalf_fists}난 널 한계까지 밀어붙이기 위한 도구였던 거지.
|
||||||
$@c{neutral_eclosed}Whether I've fulfilled that purpose I can't say, but I've done everything in my power.
|
$@c{neutral_eclosed}내가 잘 쓰였는진 모르겠지만 어쨌든 최선을 다 했고.
|
||||||
$@c{neutral}This place we ended up in is terrifying… Yet somehow I feel unphased, like I've been here before.
|
$@c{neutral}끝끝내 도착한 이곳은 끔찍하지만…\n언젠가 와 본 것 같아.
|
||||||
$@c{serious_mhalf_fists}You feel the same, don't you?
|
$@c{serious_mhalf_fists}너도 그렇게 느끼지?
|
||||||
$@c{serious}…and it's like something here is speaking to me.\nThis is all the world's known for a long time now.
|
$@c{serious}…그리고 무언가가 이야기하고 있어.\n오랫동안 세상에 알려져온 무언가가.
|
||||||
$Those times we cherished together that seem so recent are nothing but a distant memory.
|
$우리가 함께했던 소중한 시간들은 이제 그저 아득해.
|
||||||
$@c{neutral_eclosed}Who can say whether they were ever even real in the first place.
|
$@c{neutral_eclosed}실제로 일어난 일이긴 할까?
|
||||||
$@c{serious_mopen_fists}You need to keep pushing, because if you don't, it will never end. You're the only one who can do this.
|
$@c{serious_mopen_fists}너는 계속 나아가야 해. 그렇지 않으면 끝나지 않아.\n오직 너만이 할 수 있어.
|
||||||
$@c{serious_smile_fists}I hardly know what any of this means, I just know that it's true.
|
$@c{serious_smile_fists}잘 모르겠지만, 하나만은 확실해.
|
||||||
$@c{serious_mopen_fists}If you can't defeat me here and now, you won't stand a chance.`
|
$@c{serious_mopen_fists}여기서 날 쓰러뜨리지 못한다면, 너에게 기회는 없을거란걸.`
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: `@c{smile_eclosed}It looks like my work is done here.
|
1: `@c{smile_eclosed}내 역할은 여기까진 것 같아.
|
||||||
$I want you to promise me one thing.\n@c{smile}After you heal the world, please come home.`
|
$하나만 약속해 줘.\n@c{smile}세상을 원래대로 되돌리고 나면, 집으로 돌아오는거야.`
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"rival_6_female": {
|
"rival_6_female": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `@c{smile_ehalf}So it's just us again.
|
1: `@c{smile_ehalf}또 이렇게 만났네.
|
||||||
$@c{smile_eclosed}You know, I keep going around and around in my head…
|
$@c{smile_eclosed}나 머릿속이 빙글빙글 도는 것 같아…
|
||||||
$@c{smile_ehalf}There's something to all this, why everything seems so strange now…
|
$@c{smile_ehalf}모든 것이 이상하게 보이는 이유.\n분명 뭔가가 있어…
|
||||||
$@c{smile}You have your dream, and I have this ambition in me…
|
$@c{smile}너는 너의 꿈이 있고,\n나는 나의 야망이 있지…
|
||||||
$I just can't help but feel there's a greater purpose to all this, to what we're doing, you and I.
|
$이 모든것, 우리가 하고 있는 모든 일들이\n더 큰 무언가를 위한 것임을 느낄 수밖에 없어.
|
||||||
$@c{smile_eclosed}I think I'm supposed to push you… to your limits.
|
$@c{smile_eclosed}나는 아마 너를…\n한계까지 몰아붙여야 하는 거야.
|
||||||
$@c{smile_ehalf}I'm not sure if I've been doing a good job at that, but I've tried my best up to now.
|
$@c{smile_ehalf}잘 해왔는지는 모르겠는데, 최선은 다 했어.
|
||||||
$It's something about this strange and dreadful place… Everything seems so clear…
|
$이 이상하고 무서운 곳…\n모든게 선명하게 보이고…
|
||||||
$This… is all the world's known for a long time now.
|
$이건… 오래전부터 세상에 알려져온 전부.
|
||||||
$@c{smile_eclosed}It's like I can barely remember the memories we cherished together.
|
$@c{smile_eclosed}우리가 함께해온 추억들이, 이제는 거의 떠오르지 않아.
|
||||||
$@c{smile_ehalf}Were they even real? They seem so far away now…
|
$@c{smile_ehalf}실제로 일어났던 일일까? 너무 멀게만 느껴지는데…
|
||||||
$@c{angry_mopen}You need to keep pushing, because if you don't, it will never end. You're the only one who can do this.
|
$@c{angry_mopen}계속 나아가야 해. 안 그러면, 영원히 끝나지 않을 거야. \n오직 너만이 할 수 있어.
|
||||||
$@c{smile_ehalf}I… don't know what all this means… but I feel it's true.
|
$@c{smile_ehalf}난… 이 모든게 무슨 의미가 있는지는 잘 모르겠지만…\n이거 하나는 느끼고 있어.
|
||||||
$@c{neutral}If you can't defeat me here and now, you won't stand a chance.`
|
$@c{neutral}여기서 날 쓰러뜨리지 못한다면, 너에게 기회는 없을거란걸.`
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: `@c{smile_ehalf}I… I think I fulfilled my purpose…
|
1: `@c{smile_ehalf}나… 내 소임을 다 한 기분이야…
|
||||||
$@c{smile_eclosed}Promise me… After you heal the world… Please… come home safe.
|
$@c{smile_eclosed}약속해 줘… 세상을 원래대로 되돌리고서… \n집으로… 무사히 돌아오는 거야.
|
||||||
$@c{smile_ehalf}…Thank you.`
|
$@c{smile_ehalf}…고마워.`
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -2282,17 +2290,17 @@ export const PGFdialogue: DialogueTranslationEntries = PGMdialogue;
|
|||||||
|
|
||||||
// Dialogue of the endboss of the game when the player character is male (Or unset)
|
// Dialogue of the endboss of the game when the player character is male (Or unset)
|
||||||
export const PGMbattleSpecDialogue: SimpleTranslationEntries = {
|
export const PGMbattleSpecDialogue: SimpleTranslationEntries = {
|
||||||
"encounter": `It appears the time has finally come once again.\nYou know why you have come here, do you not?
|
"encounter": `드디어 때가 다시 도래했다.\n당도한 연유를 아는가?
|
||||||
$You were drawn here, because you have been here before.\nCountless times.
|
$이미 도달한 적이 있기에 이 자리에 있다.\n셀 수도 없이 많이.
|
||||||
$Though, perhaps it can be counted.\nTo be precise, this is in fact your 5,643,853rd cycle.
|
$아니, 사실 셀 수는 있지.\n정확히 너의 5,643,853번째다.
|
||||||
$Each cycle your mind reverts to its former state.\nEven so, somehow, remnants of your former selves remain.
|
$매 번 태초의 정신으로 되돌아갔을 뿐.\n하지만 어떻게든, 흔적은 남는다.
|
||||||
$Until now you have yet to succeed, but I sense a different presence in you this time.\n
|
$실패만을 반복했을 뿐이지만,\n지금은 네 안에 무언가가 있구나.\n
|
||||||
$You are the only one here, though it is as if there is… another.
|
$홀로 선 것처럼 보이나, 무언가 이질적인…
|
||||||
$Will you finally prove a formidable challenge to me?\nThe challenge I have longed for for millennia?
|
$마침내 그간의 갈망을 해소해주는가?\n수천 년 간 기다려온 도전을?
|
||||||
$We begin.`,
|
$시작하지.`,
|
||||||
"firstStageWin": `I see. The presence I felt was indeed real.\nIt appears I no longer need to hold back.
|
"firstStageWin": `그렇군. 정말로 있었어.\n이제 주저할 필요는 없다.
|
||||||
$Do not disappoint me.`,
|
$실망시키지 않도록.`,
|
||||||
"secondStageWin": "…Magnificent."
|
"secondStageWin": "…고무적이군."
|
||||||
};
|
};
|
||||||
|
|
||||||
// Dialogue of the endboss of the game when the player character is female. For languages that do not have gendered pronouns, this can be set to PGMbattleSpecDialogue.
|
// Dialogue of the endboss of the game when the player character is female. For languages that do not have gendered pronouns, this can be set to PGMbattleSpecDialogue.
|
||||||
@ -2301,22 +2309,22 @@ export const PGFbattleSpecDialogue: SimpleTranslationEntries = PGMbattleSpecDial
|
|||||||
// Dialogue that does not fit into any other category (e.g. tutorial messages, or the end of the game). For when the player character is male
|
// Dialogue that does not fit into any other category (e.g. tutorial messages, or the end of the game). For when the player character is male
|
||||||
export const PGMmiscDialogue: SimpleTranslationEntries = {
|
export const PGMmiscDialogue: SimpleTranslationEntries = {
|
||||||
"ending":
|
"ending":
|
||||||
`@c{smile}Oh? You won?@d{96} @c{smile_eclosed}I guess I should've known.\nBut, you're back now.
|
`@c{smile}오? 이긴거야?@d{96} @c{smile_eclosed}진즉 알았어야 했는데.\n아무튼, 돌아왔구나.
|
||||||
$@c{smile}It's over.@d{64} You ended the loop.
|
$@c{smile}다 끝난거야.@d{64} 네가 굴레를 끝장냈어.
|
||||||
$@c{serious_smile_fists}You fulfilled your dream too, didn't you?\nYou didn't lose even once.
|
$@c{serious_smile_fists}네 꿈도 이뤄졌고말야.\n진짜로 한 번도 안 졌잖아.
|
||||||
$@c{neutral}I'm the only one who'll remember what you did.@d{96}\nI guess that's okay, isn't it?
|
$@c{neutral}기억하는 건 우리들 뿐일 모양이지만.@d{96}\n그래도, 괜찮지?
|
||||||
$@c{serious_smile_fists}Your legend will always live on in our hearts.
|
$@c{serious_smile_fists}오늘의 일은\n너와 나의 마음 속에 항상 함께할 거야.
|
||||||
$@c{smile_eclosed}Anyway, I've had about enough of this place, haven't you? Let's head home.
|
$@c{smile_eclosed}여기 구경도 충분히 했으니\n이제 집에 가자.
|
||||||
$@c{serious_smile_fists}Maybe when we get back, we can have another battle?\nIf you're up to it.`,
|
$@c{serious_smile_fists}되돌아가서, 다시 배틀을 할 수도 있지 않을까?\n네가 원한다면 말야.`,
|
||||||
"ending_female":
|
"ending_female":
|
||||||
`@c{shock}You're back?@d{32} Does that mean…@d{96} you won?!\n@c{smile_ehalf}I should have known you had it in you.
|
`@c{shock}돌아왔구나?@d{32} 그 말은…@d{96} 이겼어?!\n@c{smile_ehalf}그럴 줄 알았다니까.
|
||||||
$@c{smile_eclosed}Of course… I always had that feeling.\n@c{smile}It's over now, right? You ended the loop.
|
$@c{smile_eclosed}물론… 언제나 느껴왔지.\n@c{smile}끝난 거, 맞지? 이 굴레를 말이야.
|
||||||
$@c{smile_ehalf}You fulfilled your dream too, didn't you?\nYou didn't lose even once.
|
$@c{smile_ehalf}네 꿈도 이뤘고 말이야.\n어떻게 한번도 안 졌대?
|
||||||
$I'll be the only one to remember what you did.\n@c{angry_mopen}I'll try not to forget!
|
$네가 한 일은 나만 기억하게 될 모양이지만.\n@c{angry_mopen}나, 안 까먹어볼 테니까!
|
||||||
$@c{smile_wave_wink}Just kidding!@d{64} @c{smile}I'd never forget.@d{32}\nYour legend will live on in our hearts.
|
$@c{smile_wave_wink}농담이야!@d{64} @c{smile}절대로 안 잊어버릴 거야.@d{32}\n오늘 일은 우리의 마음 속에서 살아갈 야.
|
||||||
$@c{smile_wave}Anyway,@d{64} it's getting late…@d{96} I think?\nIt's hard to tell in this place.
|
$@c{smile_wave}어쨌든,@d{64} 시간이 좀 늦었어…@d{96}\n이런 곳에서 할 말은 아닌가?
|
||||||
$Let's go home. @c{smile_wave_wink}Maybe tomorrow, we can have another battle, for old time's sake?`,
|
$집에 가자. @c{smile_wave_wink}아마 내일은,\n추억을 되짚어보기 위한 배틀을 해볼 수 있을 거야.`,
|
||||||
"ending_endless": "Congratulations on reaching the current end!\nMore content is coming soon.",
|
"ending_endless": "끝에 도달하신 것을 축하드립니다!\n더 많은 컨텐츠를 기다려주세요.",
|
||||||
"ending_name": "Devs"
|
"ending_name": "Devs"
|
||||||
};
|
};
|
||||||
// Dialogue that does not fit into any other category (e.g. tutorial messages, or the end of the game). For when the player character is female. For languages that do not have gendered pronouns, this can be set to PGMmiscDialogue.
|
// Dialogue that does not fit into any other category (e.g. tutorial messages, or the end of the game). For when the player character is female. For languages that do not have gendered pronouns, this can be set to PGMmiscDialogue.
|
||||||
|
@ -11,6 +11,7 @@ export const menu: SimpleTranslationEntries = {
|
|||||||
"dailyRun": "데일리 런 (베타)",
|
"dailyRun": "데일리 런 (베타)",
|
||||||
"loadGame": "불러오기",
|
"loadGame": "불러오기",
|
||||||
"newGame": "새 게임",
|
"newGame": "새 게임",
|
||||||
|
"settings": "설정",
|
||||||
"selectGameMode": "게임 모드를 선택해주세요.",
|
"selectGameMode": "게임 모드를 선택해주세요.",
|
||||||
"logInOrCreateAccount": "로그인 또는 등록을 해 주세요. 개인정보를 요구하지 않습니다!",
|
"logInOrCreateAccount": "로그인 또는 등록을 해 주세요. 개인정보를 요구하지 않습니다!",
|
||||||
"username": "이름",
|
"username": "이름",
|
||||||
|
@ -48,6 +48,7 @@ export const trainerClasses: SimpleTranslationEntries = {
|
|||||||
"depot_agent": "역무원",
|
"depot_agent": "역무원",
|
||||||
"doctor": "의사",
|
"doctor": "의사",
|
||||||
"doctor_female": "간호사", // doctor_f.png 파일이 간호사
|
"doctor_female": "간호사", // doctor_f.png 파일이 간호사
|
||||||
|
"firebreather": "Firebreather",
|
||||||
"fisherman": "낚시꾼",
|
"fisherman": "낚시꾼",
|
||||||
"fisherman_female": "낚시꾼",
|
"fisherman_female": "낚시꾼",
|
||||||
"gentleman": "신사",
|
"gentleman": "신사",
|
||||||
|
@ -12,7 +12,7 @@ export const tutorial: SimpleTranslationEntries = {
|
|||||||
$설정에서 게임 속도, 윈도우 스타일 및 기타 옵션을 변경할 수 있습니다.
|
$설정에서 게임 속도, 윈도우 스타일 및 기타 옵션을 변경할 수 있습니다.
|
||||||
$여기에는 다양한 다른 기능도 있으니 꼭 확인해보세요!`,
|
$여기에는 다양한 다른 기능도 있으니 꼭 확인해보세요!`,
|
||||||
|
|
||||||
starterSelect: `이 화면에서 스타팅을 선택할 수 있습니다.\n이들은 당신의 첫 번째 파티 멤버들입니다.
|
starterSelect: `이 화면에서 Z나 스페이스바로 스타팅을 선택할 수 있습니다.\n이들은 당신의 첫 번째 파티 멤버들입니다.
|
||||||
$최대 6마리의 파티로 시작할 수 있지만\n포켓몬에 따라 코스트가 있어 총합 10을 넘겨선 안 됩니다.
|
$최대 6마리의 파티로 시작할 수 있지만\n포켓몬에 따라 코스트가 있어 총합 10을 넘겨선 안 됩니다.
|
||||||
$계속 잡거나 부화시켜서\n선택할 수 있는 성별, 특성, 폼 등의 폭을 넓힐 수 있습니다.
|
$계속 잡거나 부화시켜서\n선택할 수 있는 성별, 특성, 폼 등의 폭을 넓힐 수 있습니다.
|
||||||
$개체값도 점점 누적되어 높아지므로,\n같은 포켓몬을 많이 잡아보세요!`,
|
$개체값도 점점 누적되어 높아지므로,\n같은 포켓몬을 많이 잡아보세요!`,
|
||||||
@ -22,7 +22,8 @@ export const tutorial: SimpleTranslationEntries = {
|
|||||||
|
|
||||||
statChange: `포켓몬은 교체하지 않으면 다음 전투에서도 능력치 변화가 유지됩니다.
|
statChange: `포켓몬은 교체하지 않으면 다음 전투에서도 능력치 변화가 유지됩니다.
|
||||||
$대신 트레이너 배틀이나 새로운 바이옴 입장 직전에 자동으로 들여보내지게 됩니다.
|
$대신 트레이너 배틀이나 새로운 바이옴 입장 직전에 자동으로 들여보내지게 됩니다.
|
||||||
$C 또는 Shift를 꾹 눌러 현재 포켓몬의 능력치 변화를 볼 수도 있습니다.`,
|
$C 또는 Shift를 꾹 눌러 현재 포켓몬의 능력치 변화를 볼 수도 있습니다.
|
||||||
|
$V를 눌러 상대방이 사용했던 기술도 확인하여 전투를 유리하게 이끌어봅시다.`,
|
||||||
|
|
||||||
selectItem: `전투가 끝날때마다 무작위 아이템 3개 중 하나를 선택하여 얻습니다.
|
selectItem: `전투가 끝날때마다 무작위 아이템 3개 중 하나를 선택하여 얻습니다.
|
||||||
$종류는 소모품, 포켓몬의 지닌 도구, 영구적 패시브 아이템에 이르기까지 다양합니다.
|
$종류는 소모품, 포켓몬의 지닌 도구, 영구적 패시브 아이템에 이르기까지 다양합니다.
|
||||||
|
@ -3,4 +3,5 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
|||||||
export const abilityTriggers: SimpleTranslationEntries = {
|
export const abilityTriggers: SimpleTranslationEntries = {
|
||||||
"blockRecoilDamage" : "{{abilityName}} de {{pokemonName}}\nprotegeu-o do dano de recuo!",
|
"blockRecoilDamage" : "{{abilityName}} de {{pokemonName}}\nprotegeu-o do dano de recuo!",
|
||||||
"badDreams": "{{pokemonName}} está tendo pesadelos!",
|
"badDreams": "{{pokemonName}} está tendo pesadelos!",
|
||||||
|
"windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!"
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -359,6 +359,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "I'll tune up for the next race."
|
1: "I'll tune up for the next race."
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"firebreather": {
|
||||||
|
"encounter": {
|
||||||
|
1: "My flames shall devour you!",
|
||||||
|
2: "My soul is on fire. I'll show you how hot it burns!",
|
||||||
|
3: "Step right up and take a look!"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: "I burned down to ashes...",
|
||||||
|
2: "Yow! That's hot!",
|
||||||
|
3: "Ow! I scorched the tip of my nose!"
|
||||||
|
},
|
||||||
|
},
|
||||||
"brock": {
|
"brock": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
||||||
@ -1203,8 +1215,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"bugsy": {
|
"bugsy": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `Whoa, amazing! You're an expert on Pokémon!
|
1: "I'm Bugsy! I never lose when it comes to bug Pokémon!"
|
||||||
$My research isn't complete yet. OK, you win.`,
|
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
||||||
|
@ -48,6 +48,7 @@ export const trainerClasses: SimpleTranslationEntries = {
|
|||||||
"depot_agent": "Ferroviário",
|
"depot_agent": "Ferroviário",
|
||||||
"doctor": "Doutor",
|
"doctor": "Doutor",
|
||||||
"doctor_female": "Doutora",
|
"doctor_female": "Doutora",
|
||||||
|
"firebreather": "Firebreather",
|
||||||
"fishermen": "Pescador",
|
"fishermen": "Pescador",
|
||||||
"fishermen_female": "Pescadora",
|
"fishermen_female": "Pescadora",
|
||||||
"gentleman": "Cavalheiro",
|
"gentleman": "Cavalheiro",
|
||||||
|
@ -2,5 +2,6 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
|||||||
|
|
||||||
export const abilityTriggers: SimpleTranslationEntries = {
|
export const abilityTriggers: SimpleTranslationEntries = {
|
||||||
"blockRecoilDamage" : "{{pokemonName}} 的 {{abilityName}}\n抵消了反作用力!",
|
"blockRecoilDamage" : "{{pokemonName}} 的 {{abilityName}}\n抵消了反作用力!",
|
||||||
"badDreams": "{{pokemonName}} 被折磨着!"
|
"badDreams": "{{pokemonName}} 被折磨着!",
|
||||||
|
"windPowerCharged": "受 {{moveName}} 的影响, {{pokemonName}} 提升了能力!"
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -359,6 +359,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "I'll tune up for the next race."
|
1: "I'll tune up for the next race."
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"firebreather": {
|
||||||
|
"encounter": {
|
||||||
|
1: "My flames shall devour you!",
|
||||||
|
2: "My soul is on fire. I'll show you how hot it burns!",
|
||||||
|
3: "Step right up and take a look!"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: "I burned down to ashes...",
|
||||||
|
2: "Yow! That's hot!",
|
||||||
|
3: "Ow! I scorched the tip of my nose!"
|
||||||
|
},
|
||||||
|
},
|
||||||
"brock": {
|
"brock": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
||||||
@ -1203,8 +1215,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"bugsy": {
|
"bugsy": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `Whoa, amazing! You're an expert on Pokémon!
|
1: "I'm Bugsy! I never lose when it comes to bug Pokémon!"
|
||||||
$My research isn't complete yet. OK, you win.`,
|
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
||||||
|
@ -48,6 +48,7 @@ export const trainerClasses: SimpleTranslationEntries = {
|
|||||||
"depot_agent": "铁路员工",
|
"depot_agent": "铁路员工",
|
||||||
"doctor": "医生",
|
"doctor": "医生",
|
||||||
"doctor_female": "医生",
|
"doctor_female": "医生",
|
||||||
|
"firebreather": "Firebreather",
|
||||||
"fisherman": "垂钓者",
|
"fisherman": "垂钓者",
|
||||||
"fisherman_female": "垂钓者",
|
"fisherman_female": "垂钓者",
|
||||||
"gentleman": "绅士",
|
"gentleman": "绅士",
|
||||||
|
@ -3,4 +3,5 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
|||||||
export const abilityTriggers: SimpleTranslationEntries = {
|
export const abilityTriggers: SimpleTranslationEntries = {
|
||||||
"blockRecoilDamage" : "{{pokemonName}} 的 {{abilityName}}\n抵消了反作用力!",
|
"blockRecoilDamage" : "{{pokemonName}} 的 {{abilityName}}\n抵消了反作用力!",
|
||||||
"badDreams": "{{pokemonName}} 被折磨着!",
|
"badDreams": "{{pokemonName}} 被折磨着!",
|
||||||
|
"windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!"
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -359,6 +359,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "I'll tune up for the next race."
|
1: "I'll tune up for the next race."
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"firebreather": {
|
||||||
|
"encounter": {
|
||||||
|
1: "My flames shall devour you!",
|
||||||
|
2: "My soul is on fire. I'll show you how hot it burns!",
|
||||||
|
3: "Step right up and take a look!"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: "I burned down to ashes...",
|
||||||
|
2: "Yow! That's hot!",
|
||||||
|
3: "Ow! I scorched the tip of my nose!"
|
||||||
|
},
|
||||||
|
},
|
||||||
"brock": {
|
"brock": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
||||||
@ -1203,8 +1215,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"bugsy": {
|
"bugsy": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `Whoa, amazing! You're an expert on Pokémon!
|
1: "I'm Bugsy! I never lose when it comes to bug Pokémon!"
|
||||||
$My research isn't complete yet. OK, you win.`,
|
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
1: "Whoa, amazing! You're an expert on Pokémon!\nMy research isn't complete yet. OK, you win."
|
||||||
|
@ -48,6 +48,7 @@ export const trainerClasses: SimpleTranslationEntries = {
|
|||||||
"depot_agent": "鐵路員工",
|
"depot_agent": "鐵路員工",
|
||||||
"doctor": "醫生",
|
"doctor": "醫生",
|
||||||
"doctor_female": "醫生",
|
"doctor_female": "醫生",
|
||||||
|
"firebreather": "Firebreather",
|
||||||
"fisherman": "垂釣者",
|
"fisherman": "垂釣者",
|
||||||
"fisherman_female": "垂釣者",
|
"fisherman_female": "垂釣者",
|
||||||
"gentleman": "紳士",
|
"gentleman": "紳士",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import * as Modifiers from "./modifier";
|
import * as Modifiers from "./modifier";
|
||||||
import { AttackMove, allMoves } from "../data/move";
|
import { AttackMove, allMoves } from "../data/move";
|
||||||
import { Moves } from "../data/enums/moves";
|
import { Moves } from "../data/enums/moves";
|
||||||
|
import { Abilities } from "../data/enums/abilities";
|
||||||
import { PokeballType, getPokeballCatchMultiplier, getPokeballName } from "../data/pokeball";
|
import { PokeballType, getPokeballCatchMultiplier, getPokeballName } from "../data/pokeball";
|
||||||
import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "../field/pokemon";
|
import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "../field/pokemon";
|
||||||
import { EvolutionItem, pokemonEvolutions } from "../data/pokemon-evolutions";
|
import { EvolutionItem, pokemonEvolutions } from "../data/pokemon-evolutions";
|
||||||
@ -756,14 +757,23 @@ export class EvolutionItemModifierType extends PokemonModifierType implements Ge
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that represents form changing items
|
||||||
|
*/
|
||||||
export class FormChangeItemModifierType extends PokemonModifierType implements GeneratedPersistentModifierType {
|
export class FormChangeItemModifierType extends PokemonModifierType implements GeneratedPersistentModifierType {
|
||||||
public formChangeItem: FormChangeItem;
|
public formChangeItem: FormChangeItem;
|
||||||
|
|
||||||
constructor(formChangeItem: FormChangeItem) {
|
constructor(formChangeItem: FormChangeItem) {
|
||||||
super("", FormChangeItem[formChangeItem].toLowerCase(), (_type, args) => new Modifiers.PokemonFormChangeItemModifier(this, (args[0] as PlayerPokemon).id, formChangeItem, true),
|
super("", FormChangeItem[formChangeItem].toLowerCase(), (_type, args) => new Modifiers.PokemonFormChangeItemModifier(this, (args[0] as PlayerPokemon).id, formChangeItem, true),
|
||||||
(pokemon: PlayerPokemon) => {
|
(pokemon: PlayerPokemon) => {
|
||||||
if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId) && !!pokemonFormChanges[pokemon.species.speciesId].find(fc => fc.trigger.hasTriggerType(SpeciesFormChangeItemTrigger)
|
// Make sure the Pokemon has alternate forms
|
||||||
&& (fc.trigger as SpeciesFormChangeItemTrigger).item === this.formChangeItem)) {
|
if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId)
|
||||||
|
// Get all form changes for this species with an item trigger, including any compound triggers
|
||||||
|
&& pokemonFormChanges[pokemon.species.speciesId].filter(fc => fc.trigger.hasTriggerType(SpeciesFormChangeItemTrigger))
|
||||||
|
// Returns true if any form changes match this item
|
||||||
|
.map(fc => fc.findTrigger(SpeciesFormChangeItemTrigger) as SpeciesFormChangeItemTrigger)
|
||||||
|
.flat().flatMap(fc => fc.item).includes(this.formChangeItem)
|
||||||
|
) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1182,6 +1192,9 @@ export const modifierTypes = {
|
|||||||
LEFTOVERS: () => new PokemonHeldItemModifierType("modifierType:ModifierType.LEFTOVERS", "leftovers", (type, args) => new Modifiers.TurnHealModifier(type, (args[0] as Pokemon).id)),
|
LEFTOVERS: () => new PokemonHeldItemModifierType("modifierType:ModifierType.LEFTOVERS", "leftovers", (type, args) => new Modifiers.TurnHealModifier(type, (args[0] as Pokemon).id)),
|
||||||
SHELL_BELL: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SHELL_BELL", "shell_bell", (type, args) => new Modifiers.HitHealModifier(type, (args[0] as Pokemon).id)),
|
SHELL_BELL: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SHELL_BELL", "shell_bell", (type, args) => new Modifiers.HitHealModifier(type, (args[0] as Pokemon).id)),
|
||||||
|
|
||||||
|
TOXIC_ORB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.TOXIC_ORB", "toxic_orb", (type, args) => new Modifiers.TurnStatusEffectModifier(type, (args[0] as Pokemon).id)),
|
||||||
|
FLAME_ORB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.FLAME_ORB", "flame_orb", (type, args) => new Modifiers.TurnStatusEffectModifier(type, (args[0] as Pokemon).id)),
|
||||||
|
|
||||||
BATON: () => new PokemonHeldItemModifierType("modifierType:ModifierType.BATON", "stick", (type, args) => new Modifiers.SwitchEffectTransferModifier(type, (args[0] as Pokemon).id)),
|
BATON: () => new PokemonHeldItemModifierType("modifierType:ModifierType.BATON", "stick", (type, args) => new Modifiers.SwitchEffectTransferModifier(type, (args[0] as Pokemon).id)),
|
||||||
|
|
||||||
SHINY_CHARM: () => new ModifierType("modifierType:ModifierType.SHINY_CHARM", "shiny_charm", (type, _args) => new Modifiers.ShinyRateBoosterModifier(type)),
|
SHINY_CHARM: () => new ModifierType("modifierType:ModifierType.SHINY_CHARM", "shiny_charm", (type, _args) => new Modifiers.ShinyRateBoosterModifier(type)),
|
||||||
@ -1247,7 +1260,12 @@ const modifierPool: ModifierPool = {
|
|||||||
[ModifierTier.GREAT]: [
|
[ModifierTier.GREAT]: [
|
||||||
new WeightedModifierType(modifierTypes.GREAT_BALL, 6),
|
new WeightedModifierType(modifierTypes.GREAT_BALL, 6),
|
||||||
new WeightedModifierType(modifierTypes.FULL_HEAL, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.FULL_HEAL, (party: Pokemon[]) => {
|
||||||
const statusEffectPartyMemberCount = Math.min(party.filter(p => p.hp && !!p.status).length, 3);
|
const statusEffectPartyMemberCount = Math.min(party.filter(p => p.hp && !!p.status && !p.getHeldItems().some(i => {
|
||||||
|
if (i instanceof Modifiers.TurnStatusEffectModifier) {
|
||||||
|
return (i as Modifiers.TurnStatusEffectModifier).getStatusEffect() === p.status.effect;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})).length, 3);
|
||||||
return statusEffectPartyMemberCount * 6;
|
return statusEffectPartyMemberCount * 6;
|
||||||
}, 18),
|
}, 18),
|
||||||
new WeightedModifierType(modifierTypes.REVIVE, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.REVIVE, (party: Pokemon[]) => {
|
||||||
@ -1270,7 +1288,12 @@ const modifierPool: ModifierPool = {
|
|||||||
return thresholdPartyMemberCount;
|
return thresholdPartyMemberCount;
|
||||||
}, 3),
|
}, 3),
|
||||||
new WeightedModifierType(modifierTypes.FULL_RESTORE, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.FULL_RESTORE, (party: Pokemon[]) => {
|
||||||
const statusEffectPartyMemberCount = Math.min(party.filter(p => p.hp && !!p.status).length, 3);
|
const statusEffectPartyMemberCount = Math.min(party.filter(p => p.hp && !!p.status && !p.getHeldItems().some(i => {
|
||||||
|
if (i instanceof Modifiers.TurnStatusEffectModifier) {
|
||||||
|
return (i as Modifiers.TurnStatusEffectModifier).getStatusEffect() === p.status.effect;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})).length, 3);
|
||||||
const thresholdPartyMemberCount = Math.floor((Math.min(party.filter(p => (p.getInverseHp() >= 150 || p.getHpRatio() <= 0.5) && !p.isFainted()).length, 3) + statusEffectPartyMemberCount) / 2);
|
const thresholdPartyMemberCount = Math.floor((Math.min(party.filter(p => (p.getInverseHp() >= 150 || p.getHpRatio() <= 0.5) && !p.isFainted()).length, 3) + statusEffectPartyMemberCount) / 2);
|
||||||
return thresholdPartyMemberCount;
|
return thresholdPartyMemberCount;
|
||||||
}, 3),
|
}, 3),
|
||||||
@ -1312,6 +1335,40 @@ const modifierPool: ModifierPool = {
|
|||||||
new WeightedModifierType(modifierTypes.MINT, 4),
|
new WeightedModifierType(modifierTypes.MINT, 4),
|
||||||
new WeightedModifierType(modifierTypes.RARE_EVOLUTION_ITEM, (party: Pokemon[]) => Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 15) * 4, 32), 32),
|
new WeightedModifierType(modifierTypes.RARE_EVOLUTION_ITEM, (party: Pokemon[]) => Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 15) * 4, 32), 32),
|
||||||
new WeightedModifierType(modifierTypes.AMULET_COIN, 3),
|
new WeightedModifierType(modifierTypes.AMULET_COIN, 3),
|
||||||
|
new WeightedModifierType(modifierTypes.TOXIC_ORB, (party: Pokemon[]) => {
|
||||||
|
let weight = 0;
|
||||||
|
const filteredParty = party.filter(p => (p.status?.effect === StatusEffect.TOXIC || p.canSetStatus(StatusEffect.TOXIC, true, true))
|
||||||
|
&& !p.hasAbility(Abilities.FLARE_BOOST)
|
||||||
|
&& !p.getHeldItems().some(i => i instanceof Modifiers.TurnStatusEffectModifier));
|
||||||
|
if (filteredParty.some(p => p.hasAbility(Abilities.TOXIC_BOOST) || p.hasAbility(Abilities.POISON_HEAL))) {
|
||||||
|
weight = 4;
|
||||||
|
} else if (filteredParty.some(p => p.hasAbility(Abilities.GUTS) || p.hasAbility(Abilities.QUICK_FEET) || p.hasAbility(Abilities.MARVEL_SCALE))) {
|
||||||
|
weight = 2;
|
||||||
|
} else {
|
||||||
|
const moveList = [Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT];
|
||||||
|
if (filteredParty.some(p => p.getMoveset().some(m => moveList.includes(m.moveId)))) {
|
||||||
|
weight = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 15) * weight, 8 * weight);
|
||||||
|
}, 32),
|
||||||
|
new WeightedModifierType(modifierTypes.FLAME_ORB, (party: Pokemon[]) => {
|
||||||
|
let weight = 0;
|
||||||
|
const filteredParty = party.filter(p => (p.status?.effect === StatusEffect.BURN || p.canSetStatus(StatusEffect.BURN, true, true))
|
||||||
|
&& !p.hasAbility(Abilities.TOXIC_BOOST) && !p.hasAbility(Abilities.POISON_HEAL)
|
||||||
|
&& !p.getHeldItems().some(i => i instanceof Modifiers.TurnStatusEffectModifier));
|
||||||
|
if (filteredParty.some(p => p.hasAbility(Abilities.FLARE_BOOST))) {
|
||||||
|
weight = 4;
|
||||||
|
} else if (filteredParty.some(p => p.hasAbility(Abilities.GUTS) || p.hasAbility(Abilities.QUICK_FEET) || p.hasAbility(Abilities.MARVEL_SCALE))) {
|
||||||
|
weight = 2;
|
||||||
|
} else {
|
||||||
|
const moveList = [Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT];
|
||||||
|
if (filteredParty.some(p => p.getMoveset().some(m => moveList.includes(m.moveId)))) {
|
||||||
|
weight = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 15) * weight, 8 * weight);
|
||||||
|
}, 32),
|
||||||
new WeightedModifierType(modifierTypes.REVIVER_SEED, 4),
|
new WeightedModifierType(modifierTypes.REVIVER_SEED, 4),
|
||||||
new WeightedModifierType(modifierTypes.CANDY_JAR, 5),
|
new WeightedModifierType(modifierTypes.CANDY_JAR, 5),
|
||||||
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 10),
|
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 10),
|
||||||
|
@ -851,6 +851,66 @@ export class TurnHealModifier extends PokemonHeldItemModifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifier used for held items, namely Toxic Orb and Flame Orb, that apply a
|
||||||
|
* set {@linkcode StatusEffect} at the end of a turn.
|
||||||
|
* @extends PokemonHeldItemModifier
|
||||||
|
* @see {@linkcode apply}
|
||||||
|
*/
|
||||||
|
export class TurnStatusEffectModifier extends PokemonHeldItemModifier {
|
||||||
|
/** The status effect to be applied by the held item */
|
||||||
|
private effect: StatusEffect;
|
||||||
|
|
||||||
|
constructor (type: ModifierType, pokemonId: integer, stackCount?: integer) {
|
||||||
|
super(type, pokemonId, stackCount);
|
||||||
|
|
||||||
|
switch (type.id) {
|
||||||
|
case "TOXIC_ORB":
|
||||||
|
this.effect = StatusEffect.TOXIC;
|
||||||
|
break;
|
||||||
|
case "FLAME_ORB":
|
||||||
|
this.effect = StatusEffect.BURN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if {@linkcode modifier} is an instance of this class,
|
||||||
|
* intentionally ignoring potentially different {@linkcode effect}s
|
||||||
|
* to prevent held item stockpiling since the item obtained first
|
||||||
|
* would be the only item able to {@linkcode apply} successfully.
|
||||||
|
* @override
|
||||||
|
* @param modifier {@linkcode Modifier} being type tested
|
||||||
|
* @return true if {@linkcode modifier} is an instance of
|
||||||
|
* TurnStatusEffectModifier, false otherwise
|
||||||
|
*/
|
||||||
|
matchType(modifier: Modifier): boolean {
|
||||||
|
return modifier instanceof TurnStatusEffectModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
clone() {
|
||||||
|
return new TurnStatusEffectModifier(this.type, this.pokemonId, this.stackCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to inflicts the holder with the associated {@linkcode StatusEffect}.
|
||||||
|
* @param args [0] {@linkcode Pokemon} that holds the held item
|
||||||
|
* @returns true if the status effect was applied successfully, false if
|
||||||
|
* otherwise
|
||||||
|
*/
|
||||||
|
apply(args: any[]): boolean {
|
||||||
|
return (args[0] as Pokemon).trySetStatus(this.effect, true, undefined, undefined, this.type.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMaxHeldItemCount(pokemon: Pokemon): integer {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStatusEffect(): StatusEffect {
|
||||||
|
return this.effect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class HitHealModifier extends PokemonHeldItemModifier {
|
export class HitHealModifier extends PokemonHeldItemModifier {
|
||||||
constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) {
|
constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) {
|
||||||
super(type, pokemonId, stackCount);
|
super(type, pokemonId, stackCount);
|
||||||
@ -1868,7 +1928,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
|
|||||||
}
|
}
|
||||||
const randItemIndex = pokemon.randSeedInt(itemModifiers.length);
|
const randItemIndex = pokemon.randSeedInt(itemModifiers.length);
|
||||||
const randItem = itemModifiers[randItemIndex];
|
const randItem = itemModifiers[randItemIndex];
|
||||||
heldItemTransferPromises.push(pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false, false).then(success => {
|
heldItemTransferPromises.push(pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false).then(success => {
|
||||||
if (success) {
|
if (success) {
|
||||||
transferredModifierTypes.push(randItem.type);
|
transferredModifierTypes.push(randItem.type);
|
||||||
itemModifiers.splice(randItemIndex, 1);
|
itemModifiers.splice(randItemIndex, 1);
|
||||||
|
@ -14,6 +14,7 @@ import { PokeballType } from "./data/pokeball";
|
|||||||
import {TimeOfDay} from "#app/data/enums/time-of-day";
|
import {TimeOfDay} from "#app/data/enums/time-of-day";
|
||||||
import { Gender } from "./data/gender";
|
import { Gender } from "./data/gender";
|
||||||
import { StatusEffect } from "./data/status-effect";
|
import { StatusEffect } from "./data/status-effect";
|
||||||
|
import { modifierTypes } from "./modifier/modifier-type";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides for testing different in game situations
|
* Overrides for testing different in game situations
|
||||||
@ -100,7 +101,7 @@ export const OPP_VARIANT_OVERRIDE: Variant = 0;
|
|||||||
* - BerryType is for BERRY
|
* - BerryType is for BERRY
|
||||||
*/
|
*/
|
||||||
interface ModifierOverride {
|
interface ModifierOverride {
|
||||||
name: string,
|
name: keyof typeof modifierTypes & string,
|
||||||
count?: integer
|
count?: integer
|
||||||
type?: TempBattleStat|Stat|Nature|Type|BerryType
|
type?: TempBattleStat|Stat|Nature|Type|BerryType
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMov
|
|||||||
import { Mode } from "./ui/ui";
|
import { Mode } from "./ui/ui";
|
||||||
import { Command } from "./ui/command-ui-handler";
|
import { Command } from "./ui/command-ui-handler";
|
||||||
import { Stat } from "./data/pokemon-stat";
|
import { Stat } from "./data/pokemon-stat";
|
||||||
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, PokemonMoveAccuracyBoosterModifier, overrideModifiers, overrideHeldItems, BypassSpeedChanceModifier } from "./modifier/modifier";
|
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, PokemonMoveAccuracyBoosterModifier, overrideModifiers, overrideHeldItems, BypassSpeedChanceModifier, TurnStatusEffectModifier } from "./modifier/modifier";
|
||||||
import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
|
import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
|
||||||
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
|
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
|
||||||
import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims";
|
import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims";
|
||||||
@ -1513,7 +1513,7 @@ export class SwitchSummonPhase extends SummonPhase {
|
|||||||
const batonPassModifier = this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier
|
const batonPassModifier = this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier
|
||||||
&& (m as SwitchEffectTransferModifier).pokemonId === this.lastPokemon.id) as SwitchEffectTransferModifier;
|
&& (m as SwitchEffectTransferModifier).pokemonId === this.lastPokemon.id) as SwitchEffectTransferModifier;
|
||||||
if (batonPassModifier && !this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedPokemon.id)) {
|
if (batonPassModifier && !this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedPokemon.id)) {
|
||||||
this.scene.tryTransferHeldItemModifier(batonPassModifier, switchedPokemon, false, false);
|
this.scene.tryTransferHeldItemModifier(batonPassModifier, switchedPokemon, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1548,11 +1548,16 @@ export class SwitchSummonPhase extends SummonPhase {
|
|||||||
super.onEnd();
|
super.onEnd();
|
||||||
|
|
||||||
const pokemon = this.getPokemon();
|
const pokemon = this.getPokemon();
|
||||||
const moveId = pokemon.scene.currentBattle.turnCommands[this.fieldIndex]?.move?.move;
|
|
||||||
|
const moveId = this.lastPokemon?.scene.currentBattle.lastMove;
|
||||||
const lastUsedMove = moveId ? allMoves[moveId] : undefined;
|
const lastUsedMove = moveId ? allMoves[moveId] : undefined;
|
||||||
|
|
||||||
|
const currentCommand = pokemon.scene.currentBattle.turnCommands[this.fieldIndex]?.command;
|
||||||
|
const lastPokemonIsForceSwitchedAndNotFainted = !!lastUsedMove?.findAttr(attr => attr instanceof ForceSwitchOutAttr) && !this.lastPokemon.isFainted();
|
||||||
|
|
||||||
// Compensate for turn spent summoning
|
// Compensate for turn spent summoning
|
||||||
if (pokemon.scene.currentBattle.turnCommands[this.fieldIndex]?.command === Command.POKEMON || !!lastUsedMove?.findAttr(attr => attr instanceof ForceSwitchOutAttr)) { //check if hard switch OR pivot move was used
|
// Or compensate for force switch move if switched out pokemon is not fainted
|
||||||
|
if (currentCommand === Command.POKEMON || lastPokemonIsForceSwitchedAndNotFainted) {
|
||||||
pokemon.battleSummonData.turnCount--;
|
pokemon.battleSummonData.turnCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2284,6 +2289,8 @@ export class TurnEndPhase extends FieldPhase {
|
|||||||
|
|
||||||
applyPostTurnAbAttrs(PostTurnAbAttr, pokemon);
|
applyPostTurnAbAttrs(PostTurnAbAttr, pokemon);
|
||||||
|
|
||||||
|
this.scene.applyModifiers(TurnStatusEffectModifier, pokemon.isPlayer(), pokemon);
|
||||||
|
|
||||||
this.scene.applyModifiers(TurnHeldItemTransferModifier, pokemon.isPlayer(), pokemon);
|
this.scene.applyModifiers(TurnHeldItemTransferModifier, pokemon.isPlayer(), pokemon);
|
||||||
|
|
||||||
pokemon.battleSummonData.turnCount++;
|
pokemon.battleSummonData.turnCount++;
|
||||||
@ -4895,14 +4902,12 @@ export class SelectModifierPhase extends BattlePhase {
|
|||||||
this.scene.playSound("buy");
|
this.scene.playSound("buy");
|
||||||
}
|
}
|
||||||
} else if (cursor === 1) {
|
} else if (cursor === 1) {
|
||||||
this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER, -1, (fromSlotIndex: integer, itemIndex: integer, toSlotIndex: integer) => {
|
this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER, -1, (fromSlotIndex: integer, itemIndex: integer, itemQuantity: integer, toSlotIndex: integer) => {
|
||||||
if (toSlotIndex !== undefined && fromSlotIndex < 6 && toSlotIndex < 6 && fromSlotIndex !== toSlotIndex && itemIndex > -1) {
|
if (toSlotIndex !== undefined && fromSlotIndex < 6 && toSlotIndex < 6 && fromSlotIndex !== toSlotIndex && itemIndex > -1) {
|
||||||
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers)).then(() => {
|
const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||||
const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
|
||||||
&& (m as PokemonHeldItemModifier).getTransferrable(true) && (m as PokemonHeldItemModifier).pokemonId === party[fromSlotIndex].id) as PokemonHeldItemModifier[];
|
&& (m as PokemonHeldItemModifier).getTransferrable(true) && (m as PokemonHeldItemModifier).pokemonId === party[fromSlotIndex].id) as PokemonHeldItemModifier[];
|
||||||
const itemModifier = itemModifiers[itemIndex];
|
const itemModifier = itemModifiers[itemIndex];
|
||||||
this.scene.tryTransferHeldItemModifier(itemModifier, party[toSlotIndex], true, true);
|
this.scene.tryTransferHeldItemModifier(itemModifier, party[toSlotIndex], true, itemQuantity);
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers));
|
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers));
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import { allMoves } from "../data/move";
|
|||||||
import { TrainerVariant } from "../field/trainer";
|
import { TrainerVariant } from "../field/trainer";
|
||||||
import { OutdatedPhase, ReloadSessionPhase } from "#app/phases";
|
import { OutdatedPhase, ReloadSessionPhase } from "#app/phases";
|
||||||
import { Variant, variantData } from "#app/data/variant";
|
import { Variant, variantData } from "#app/data/variant";
|
||||||
|
import { TerrainChangedEvent, WeatherChangedEvent } from "#app/field/arena-events.js";
|
||||||
|
|
||||||
const saveKey = "x0i2O7WRiANTqPmZ"; // Temporary; secure encryption is not yet necessary
|
const saveKey = "x0i2O7WRiANTqPmZ"; // Temporary; secure encryption is not yet necessary
|
||||||
|
|
||||||
@ -740,6 +741,10 @@ export class GameData {
|
|||||||
});
|
});
|
||||||
|
|
||||||
scene.arena.weather = sessionData.arena.weather;
|
scene.arena.weather = sessionData.arena.weather;
|
||||||
|
scene.arena.eventTarget.dispatchEvent(new WeatherChangedEvent(null, scene.arena.weather?.weatherType, scene.arena.weather?.turnsLeft));
|
||||||
|
|
||||||
|
scene.arena.terrain = sessionData.arena.terrain;
|
||||||
|
scene.arena.eventTarget.dispatchEvent(new TerrainChangedEvent(null, scene.arena.terrain?.terrainType, scene.arena.terrain?.turnsLeft));
|
||||||
// TODO
|
// TODO
|
||||||
//scene.arena.tags = sessionData.arena.tags;
|
//scene.arena.tags = sessionData.arena.tags;
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ export enum PartyOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PartySelectCallback = (cursor: integer, option: PartyOption) => void;
|
export type PartySelectCallback = (cursor: integer, option: PartyOption) => void;
|
||||||
export type PartyModifierTransferSelectCallback = (fromCursor: integer, index: integer, toCursor?: integer) => void;
|
export type PartyModifierTransferSelectCallback = (fromCursor: integer, index: integer, itemQuantity?: integer, toCursor?: integer) => void;
|
||||||
export type PartyModifierSpliceSelectCallback = (fromCursor: integer, toCursor?: integer) => void;
|
export type PartyModifierSpliceSelectCallback = (fromCursor: integer, toCursor?: integer) => void;
|
||||||
export type PokemonSelectFilter = (pokemon: PlayerPokemon) => string;
|
export type PokemonSelectFilter = (pokemon: PlayerPokemon) => string;
|
||||||
export type PokemonModifierTransferSelectFilter = (pokemon: PlayerPokemon, modifier: PokemonHeldItemModifier) => string;
|
export type PokemonModifierTransferSelectFilter = (pokemon: PlayerPokemon, modifier: PokemonHeldItemModifier) => string;
|
||||||
@ -87,6 +87,10 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||||||
private transferMode: boolean;
|
private transferMode: boolean;
|
||||||
private transferOptionCursor: integer;
|
private transferOptionCursor: integer;
|
||||||
private transferCursor: integer;
|
private transferCursor: integer;
|
||||||
|
/** Current quantity selection for every item held by the pokemon selected for the transfer */
|
||||||
|
private transferQuantities: integer[];
|
||||||
|
/** Stack size of every item that the selected pokemon is holding */
|
||||||
|
private transferQuantitiesMax: integer[];
|
||||||
|
|
||||||
private lastCursor: integer = 0;
|
private lastCursor: integer = 0;
|
||||||
private selectCallback: PartySelectCallback | PartyModifierTransferSelectCallback;
|
private selectCallback: PartySelectCallback | PartyModifierTransferSelectCallback;
|
||||||
@ -231,8 +235,8 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||||||
let success = false;
|
let success = false;
|
||||||
|
|
||||||
if (this.optionsMode) {
|
if (this.optionsMode) {
|
||||||
|
const option = this.options[this.optionsCursor];
|
||||||
if (button === Button.ACTION) {
|
if (button === Button.ACTION) {
|
||||||
const option = this.options[this.optionsCursor];
|
|
||||||
const pokemon = this.scene.getParty()[this.cursor];
|
const pokemon = this.scene.getParty()[this.cursor];
|
||||||
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && !this.transferMode && option !== PartyOption.CANCEL) {
|
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && !this.transferMode && option !== PartyOption.CANCEL) {
|
||||||
this.startTransfer();
|
this.startTransfer();
|
||||||
@ -270,7 +274,9 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
if (this.selectCallback) {
|
if (this.selectCallback) {
|
||||||
if (option === PartyOption.TRANSFER) {
|
if (option === PartyOption.TRANSFER) {
|
||||||
(this.selectCallback as PartyModifierTransferSelectCallback)(this.transferCursor, this.transferOptionCursor, this.cursor);
|
if (this.transferCursor !== this.cursor) {
|
||||||
|
(this.selectCallback as PartyModifierTransferSelectCallback)(this.transferCursor, this.transferOptionCursor, this.transferQuantities[this.transferOptionCursor], this.cursor);
|
||||||
|
}
|
||||||
this.clearTransfer();
|
this.clearTransfer();
|
||||||
} else if (this.partyUiMode === PartyUiMode.SPLICE) {
|
} else if (this.partyUiMode === PartyUiMode.SPLICE) {
|
||||||
if (option === PartyOption.SPLICE) {
|
if (option === PartyOption.SPLICE) {
|
||||||
@ -369,17 +375,50 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
switch (button) {
|
switch (button) {
|
||||||
|
case Button.LEFT:
|
||||||
|
/** Decrease quantity for the current item and update UI */
|
||||||
|
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) {
|
||||||
|
this.transferQuantities[option] = this.transferQuantities[option] === 1 ? this.transferQuantitiesMax[option] : this.transferQuantities[option] - 1;
|
||||||
|
this.updateOptions();
|
||||||
|
success = this.setCursor(this.optionsCursor); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Button.RIGHT:
|
||||||
|
/** Increase quantity for the current item and update UI */
|
||||||
|
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) {
|
||||||
|
this.transferQuantities[option] = this.transferQuantities[option] === this.transferQuantitiesMax[option] ? 1 : this.transferQuantities[option] + 1;
|
||||||
|
this.updateOptions();
|
||||||
|
success = this.setCursor(this.optionsCursor); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Button.UP:
|
case Button.UP:
|
||||||
success = this.setCursor(this.optionsCursor ? this.optionsCursor - 1 : this.options.length - 1);
|
/** If currently selecting items to transfer, reset quantity selection */
|
||||||
|
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) {
|
||||||
|
this.transferQuantities[option] = this.transferQuantitiesMax[option];
|
||||||
|
this.updateOptions();
|
||||||
|
}
|
||||||
|
success = this.setCursor(this.optionsCursor ? this.optionsCursor - 1 : this.options.length - 1); /** Move cursor */
|
||||||
break;
|
break;
|
||||||
case Button.DOWN:
|
case Button.DOWN:
|
||||||
success = this.setCursor(this.optionsCursor < this.options.length - 1 ? this.optionsCursor + 1 : 0);
|
/** If currently selecting items to transfer, reset quantity selection */
|
||||||
|
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) {
|
||||||
|
this.transferQuantities[option] = this.transferQuantitiesMax[option];
|
||||||
|
this.updateOptions();
|
||||||
|
}
|
||||||
|
success = this.setCursor(this.optionsCursor < this.options.length - 1 ? this.optionsCursor + 1 : 0); /** Move cursor */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (button === Button.ACTION) {
|
if (button === Button.ACTION) {
|
||||||
if (this.cursor < 6) {
|
if (this.cursor < 6) {
|
||||||
|
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && !this.transferMode) {
|
||||||
|
/** Initialize item quantities for the selected Pokemon */
|
||||||
|
const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||||
|
&& (m as PokemonHeldItemModifier).getTransferrable(true) && (m as PokemonHeldItemModifier).pokemonId === this.scene.getParty()[this.cursor].id) as PokemonHeldItemModifier[];
|
||||||
|
this.transferQuantities = itemModifiers.map(item => item.getStackCount());
|
||||||
|
this.transferQuantitiesMax = itemModifiers.map(item => item.getStackCount());
|
||||||
|
}
|
||||||
this.showOptions();
|
this.showOptions();
|
||||||
ui.playSelect();
|
ui.playSelect();
|
||||||
} else if (this.partyUiMode === PartyUiMode.FAINT_SWITCH || this.partyUiMode === PartyUiMode.REVIVAL_BLESSING) {
|
} else if (this.partyUiMode === PartyUiMode.FAINT_SWITCH || this.partyUiMode === PartyUiMode.REVIVAL_BLESSING) {
|
||||||
@ -555,7 +594,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||||||
break;
|
break;
|
||||||
case PartyUiMode.MODIFIER_TRANSFER:
|
case PartyUiMode.MODIFIER_TRANSFER:
|
||||||
if (!this.transferMode) {
|
if (!this.transferMode) {
|
||||||
optionsMessage = "Select a held item to transfer.";
|
optionsMessage = "Select a held item to transfer.\nUse < and > to change the quantity.";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PartyUiMode.SPLICE:
|
case PartyUiMode.SPLICE:
|
||||||
@ -569,7 +608,12 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||||||
|
|
||||||
this.updateOptions();
|
this.updateOptions();
|
||||||
|
|
||||||
this.partyMessageBox.setSize(262 - Math.max(this.optionsBg.displayWidth - 56, 0), 30);
|
/** When an item is being selected for transfer, the message box is taller as the message occupies two lines */
|
||||||
|
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) {
|
||||||
|
this.partyMessageBox.setSize(262 - Math.max(this.optionsBg.displayWidth - 56, 0), 42);
|
||||||
|
} else {
|
||||||
|
this.partyMessageBox.setSize(262 - Math.max(this.optionsBg.displayWidth - 56, 0), 30);
|
||||||
|
}
|
||||||
|
|
||||||
this.setCursor(0);
|
this.setCursor(0);
|
||||||
}
|
}
|
||||||
@ -741,8 +785,9 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||||||
} else {
|
} else {
|
||||||
const itemModifier = itemModifiers[option];
|
const itemModifier = itemModifiers[option];
|
||||||
optionName = itemModifier.type.name;
|
optionName = itemModifier.type.name;
|
||||||
if (itemModifier.stackCount > 1) {
|
/** For every item that has stack bigger than 1, display the current quantity selection */
|
||||||
optionName += ` (${itemModifier.stackCount})`;
|
if (this.transferQuantitiesMax[option] > 1) {
|
||||||
|
optionName += ` (${this.transferQuantities[option]})`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1339,11 +1339,27 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
case Button.UP:
|
case Button.UP:
|
||||||
if (row) {
|
if (row) {
|
||||||
success = this.setCursor(this.cursor - 9);
|
success = this.setCursor(this.cursor - 9);
|
||||||
|
} else {
|
||||||
|
// when strictly opposite starter based on rows length
|
||||||
|
// does not exits, set cursor on the second to last row
|
||||||
|
if (this.cursor + (rows - 1) * 9 > genStarters - 1) {
|
||||||
|
success = this.setCursor(this.cursor + (rows - 2) * 9);
|
||||||
|
} else {
|
||||||
|
success = this.setCursor(this.cursor + (rows - 1) * 9);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Button.DOWN:
|
case Button.DOWN:
|
||||||
if (row < rows - 2 || (row < rows - 1 && this.cursor % 9 <= (genStarters - 1) % 9)) {
|
if (row < rows - 2 || (row < rows - 1 && this.cursor % 9 <= (genStarters - 1) % 9)) {
|
||||||
success = this.setCursor(this.cursor + 9);
|
success = this.setCursor(this.cursor + 9);
|
||||||
|
} else {
|
||||||
|
// if there is no starter below while being on the second to
|
||||||
|
// last row, adjust cursor position with one line less
|
||||||
|
if (row === rows - 2 && this.cursor + 9 > genStarters - 1) {
|
||||||
|
success = this.setCursor(this.cursor - (rows - 2) * 9);
|
||||||
|
} else {
|
||||||
|
success = this.setCursor(this.cursor - (rows - 1) * 9);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Button.LEFT:
|
case Button.LEFT:
|
||||||
|
@ -68,7 +68,14 @@ export class StatsContainer extends Phaser.GameObjects.Container {
|
|||||||
this.statsIvsCache = ivChartData.slice(0);
|
this.statsIvsCache = ivChartData.slice(0);
|
||||||
|
|
||||||
this.ivStatValueTexts.map((t: BBCodeText, i: integer) => {
|
this.ivStatValueTexts.map((t: BBCodeText, i: integer) => {
|
||||||
let label = ivs[i].toString();
|
let label = "";
|
||||||
|
|
||||||
|
// Check to see if IVs are 31, if so change the text style to gold, otherwise leave them be.
|
||||||
|
if (ivs[i] === 31) {
|
||||||
|
label += `[color=${getTextColor(TextStyle.SUMMARY_GOLD, false, (this.scene as BattleScene).uiTheme)}][shadow]${ivs[i].toString()}[/shadow][/color]`;
|
||||||
|
} else {
|
||||||
|
label = ivs[i].toString();
|
||||||
|
}
|
||||||
if (this.showDiff && originalIvs) {
|
if (this.showDiff && originalIvs) {
|
||||||
if (originalIvs[i] < ivs[i]) {
|
if (originalIvs[i] < ivs[i]) {
|
||||||
label += ` ([color=${getTextColor(TextStyle.SUMMARY_BLUE, false, (this.scene as BattleScene).uiTheme)}][shadow=${getTextColor(TextStyle.SUMMARY_BLUE, true, (this.scene as BattleScene).uiTheme)}]+${ivs[i] - originalIvs[i]}[/shadow][/color])`;
|
label += ` ([color=${getTextColor(TextStyle.SUMMARY_BLUE, false, (this.scene as BattleScene).uiTheme)}][shadow=${getTextColor(TextStyle.SUMMARY_BLUE, true, (this.scene as BattleScene).uiTheme)}]+${ivs[i] - originalIvs[i]}[/shadow][/color])`;
|
||||||
|
@ -407,6 +407,7 @@ export function verifyLang(lang?: string): boolean {
|
|||||||
case "zh_CN":
|
case "zh_CN":
|
||||||
case "zh_TW":
|
case "zh_TW":
|
||||||
case "pt_BR":
|
case "pt_BR":
|
||||||
|
case "ko":
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
11
src/vite.env.d.ts
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
|
|
||||||
|
interface ImportMetaEnv {
|
||||||
|
readonly VITE_BYPASS_LOGIN?: string;
|
||||||
|
readonly VITE_BYPASS_TUTORIAL?: string;
|
||||||
|
readonly VITE_API_BASE_URL?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImportMeta {
|
||||||
|
readonly env: ImportMetaEnv
|
||||||
|
}
|
@ -16,5 +16,10 @@
|
|||||||
},
|
},
|
||||||
"outDir": "./build",
|
"outDir": "./build",
|
||||||
"noEmit": true
|
"noEmit": true
|
||||||
}
|
},
|
||||||
|
"typedocOptions": {
|
||||||
|
"entryPoints": ["src/"],
|
||||||
|
"entryPointStrategy": "expand",
|
||||||
|
"out": "typedoc",
|
||||||
|
}
|
||||||
}
|
}
|
11
vite.env.d.ts
vendored
@ -1,11 +0,0 @@
|
|||||||
/// <reference types="vite/client" />
|
|
||||||
|
|
||||||
interface ImportMetaEnv {
|
|
||||||
readonly VITE_BYPASS_LOGIN: string;
|
|
||||||
readonly VITE_BYPASS_TUTORIAL: string;
|
|
||||||
readonly VITE_API_BASE_URL: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ImportMeta {
|
|
||||||
readonly env: ImportMetaEnv;
|
|
||||||
}
|
|