mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2024-12-01 19:26:16 +00:00
Merge branch 'beta' into evil-team-monogen
This commit is contained in:
commit
62042bf826
@ -1,6 +1,6 @@
|
|||||||
VITE_BYPASS_LOGIN=0
|
VITE_BYPASS_LOGIN=0
|
||||||
VITE_BYPASS_TUTORIAL=0
|
VITE_BYPASS_TUTORIAL=0
|
||||||
VITE_SERVER_URL=https://api.beta.pokerogue.net
|
VITE_SERVER_URL=https://apibeta.pokerogue.net
|
||||||
VITE_DISCORD_CLIENT_ID=1248062921129459756
|
VITE_DISCORD_CLIENT_ID=1248062921129459756
|
||||||
VITE_GOOGLE_CLIENT_ID=955345393540-2k6lfftf0fdnb0krqmpthjnqavfvvf73.apps.googleusercontent.com
|
VITE_GOOGLE_CLIENT_ID=955345393540-2k6lfftf0fdnb0krqmpthjnqavfvvf73.apps.googleusercontent.com
|
||||||
VITE_I18N_DEBUG=1
|
VITE_I18N_DEBUG=0
|
||||||
|
@ -3,5 +3,5 @@ VITE_BYPASS_TUTORIAL=0
|
|||||||
VITE_SERVER_URL=http://localhost:8001
|
VITE_SERVER_URL=http://localhost:8001
|
||||||
VITE_DISCORD_CLIENT_ID=1234567890
|
VITE_DISCORD_CLIENT_ID=1234567890
|
||||||
VITE_GOOGLE_CLIENT_ID=1234567890
|
VITE_GOOGLE_CLIENT_ID=1234567890
|
||||||
VITE_I18N_DEBUG=1
|
VITE_I18N_DEBUG=0
|
||||||
VITE_PORT=8000
|
VITE_PORT=8000
|
||||||
|
38
.github/CODEOWNERS
vendored
38
.github/CODEOWNERS
vendored
@ -5,41 +5,3 @@
|
|||||||
|
|
||||||
# github actions/templates etc. - Dev Leads
|
# github actions/templates etc. - Dev Leads
|
||||||
/.github @pagefaultgames/dev-leads
|
/.github @pagefaultgames/dev-leads
|
||||||
|
|
||||||
# --- Translations ---
|
|
||||||
|
|
||||||
# all translations - Translation Leads
|
|
||||||
/src/locales @pagefaultgames/translation-leads
|
|
||||||
|
|
||||||
# Catalan (Spain/Spanish)
|
|
||||||
/src/locales/ca_ES @pagefaultgames/catalan-translation-team
|
|
||||||
|
|
||||||
# German
|
|
||||||
/src/locales/de @pagefaultgames/german-translation-team
|
|
||||||
|
|
||||||
# English
|
|
||||||
/src/locales/en @pagefaultgames/english-translation-team
|
|
||||||
|
|
||||||
# Spanish
|
|
||||||
/src/locales/es @pagefaultgames/spanish-translation-team
|
|
||||||
|
|
||||||
# French
|
|
||||||
/src/locales/fr @pagefaultgames/french-translation-team
|
|
||||||
|
|
||||||
# Italian
|
|
||||||
/src/locales/it @pagefaultgames/italian-translation-team
|
|
||||||
|
|
||||||
# Japenese
|
|
||||||
/src/locales/ja @pagefaultgames/japanese-translation-team
|
|
||||||
|
|
||||||
# Korean
|
|
||||||
/src/locales/ko @pagefaultgames/korean-translation-team
|
|
||||||
|
|
||||||
# Brasilian (Brasil/Portuguese)
|
|
||||||
/src/locales/pt_BR @pagefaultgames/portuguese_br-translation-team
|
|
||||||
|
|
||||||
# Chinese (simplified)
|
|
||||||
/src/locales/zh_CN @pagefaultgames/chinese_simplified-translation-team
|
|
||||||
|
|
||||||
# Chinese (traditional)
|
|
||||||
/src/locales/zh_TW @pagefaultgames/chinese_traditional-translation-team
|
|
||||||
|
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -1 +1 @@
|
|||||||
github: patapancakes
|
github: pagefaultgames
|
||||||
|
2
.github/workflows/deploy-beta.yml
vendored
2
.github/workflows/deploy-beta.yml
vendored
@ -11,6 +11,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: 'recursive'
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: "20"
|
node-version: "20"
|
||||||
|
2
.github/workflows/deploy.yml
vendored
2
.github/workflows/deploy.yml
vendored
@ -10,6 +10,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: 'recursive'
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: "20"
|
node-version: "20"
|
||||||
|
2
.github/workflows/eslint.yml
vendored
2
.github/workflows/eslint.yml
vendored
@ -22,6 +22,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Check out Git repository # Step to check out the repository
|
- name: Check out Git repository # Step to check out the repository
|
||||||
uses: actions/checkout@v4 # Use the checkout action version 4
|
uses: actions/checkout@v4 # Use the checkout action version 4
|
||||||
|
with:
|
||||||
|
submodules: 'recursive'
|
||||||
|
|
||||||
- name: Set up Node.js # Step to set up Node.js environment
|
- name: Set up Node.js # Step to set up Node.js environment
|
||||||
uses: actions/setup-node@v4 # Use the setup-node action version 4
|
uses: actions/setup-node@v4 # Use the setup-node action version 4
|
||||||
|
1
.github/workflows/github-pages.yml
vendored
1
.github/workflows/github-pages.yml
vendored
@ -26,6 +26,7 @@ jobs:
|
|||||||
- name: Checkout repository for Typedoc
|
- name: Checkout repository for Typedoc
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
|
submodules: 'recursive'
|
||||||
path: pokerogue_docs
|
path: pokerogue_docs
|
||||||
|
|
||||||
- name: Install OS package
|
- name: Install OS package
|
||||||
|
2
.github/workflows/test-shard-template.yml
vendored
2
.github/workflows/test-shard-template.yml
vendored
@ -20,6 +20,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Check out Git repository
|
- name: Check out Git repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: 'recursive'
|
||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
|
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
@ -22,6 +22,7 @@ jobs:
|
|||||||
- name: Check out Git repository
|
- name: Check out Git repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
submodules: 'recursive'
|
||||||
path: tests-action
|
path: tests-action
|
||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "public/locales"]
|
||||||
|
path = public/locales
|
||||||
|
url = https://github.com/pagefaultgames/pokerogue-locales
|
@ -24,6 +24,9 @@ We're using ESLint as our common linter and formatter. It will run automatically
|
|||||||
**How do I test a new _______?**
|
**How do I test a new _______?**
|
||||||
- In the `src/overrides.ts` file there are overrides for most values you'll need to change for testing
|
- In the `src/overrides.ts` file there are overrides for most values you'll need to change for testing
|
||||||
|
|
||||||
|
**How do I retrieve the translations?**
|
||||||
|
- The translations were moved to the [dedicated translation repository](https://github.com/pagefaultgames/pokerogue-locales) and are now applied as a submodule in this project.
|
||||||
|
- The command to retrieve the translations is `git submodule update --init --recursive`. If you still struggle to get it working, please reach out to #dev-corner channel in Discord.
|
||||||
|
|
||||||
## 🪧 To Do
|
## 🪧 To Do
|
||||||
Check out [Github Issues](https://github.com/pagefaultgames/pokerogue/issues) to see how can you help us!
|
Check out [Github Issues](https://github.com/pagefaultgames/pokerogue/issues) to see how can you help us!
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* This script creates a test boilerplate file for a move or ability.
|
* This script creates a test boilerplate file in the appropriate
|
||||||
* @param {string} type - The type of test to create. Either "move", "ability",
|
* directory based on the type selected.
|
||||||
* or "item".
|
* @example npm run create-test
|
||||||
* @param {string} fileName - The name of the file to create.
|
|
||||||
* @example npm run create-test move tackle
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
@ -34,7 +32,7 @@ async function promptTestType() {
|
|||||||
console.log("Exiting...");
|
console.log("Exiting...");
|
||||||
return process.exit();
|
return process.exit();
|
||||||
} else if (!typeChoices.includes(typeAnswer.selectedOption)) {
|
} else if (!typeChoices.includes(typeAnswer.selectedOption)) {
|
||||||
console.error('Please provide a valid type ("move", "ability", or "item")!');
|
console.error(`Please provide a valid type (${typeChoices.join(", ")})!`);
|
||||||
return await promptTestType();
|
return await promptTestType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +100,7 @@ async function runInteractive() {
|
|||||||
description = `Mystery Encounter - ${formattedName}`;
|
description = `Mystery Encounter - ${formattedName}`;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.error('Invalid type. Please use "move", "ability", or "item".');
|
console.error(`Invalid type. Please use one of the following: ${typeChoices.join(", ")}.`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,11 @@ export default [
|
|||||||
"keyword-spacing": ["error", { "before": true, "after": true }], // Enforces spacing before and after keywords
|
"keyword-spacing": ["error", { "before": true, "after": true }], // Enforces spacing before and after keywords
|
||||||
"comma-spacing": ["error", { "before": false, "after": true }], // Enforces spacing after comma
|
"comma-spacing": ["error", { "before": false, "after": true }], // Enforces spacing after comma
|
||||||
"import-x/extensions": ["error", "never", { "json": "always" }], // Enforces no extension for imports unless json
|
"import-x/extensions": ["error", "never", { "json": "always" }], // Enforces no extension for imports unless json
|
||||||
|
"array-bracket-spacing": ["error", "always", { "objectsInArrays": false, "arraysInArrays": false }], // Enforces consistent spacing inside array brackets
|
||||||
|
"object-curly-spacing": ["error", "always", { "arraysInObjects": false, "objectsInObjects": false }], // Enforces consistent spacing inside braces of object literals, destructuring assignments, and import/export specifiers
|
||||||
|
"computed-property-spacing": ["error", "never" ], // Enforces consistent spacing inside computed property brackets
|
||||||
|
"space-infix-ops": ["error", { "int32Hint": false }], // Enforces spacing around infix operators
|
||||||
|
"no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }], // Disallows multiple empty lines
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -14,3 +14,8 @@ pre-push:
|
|||||||
eslint:
|
eslint:
|
||||||
glob: "*.{js,ts,jsx,tsx}"
|
glob: "*.{js,ts,jsx,tsx}"
|
||||||
run: npx eslint --fix {push_files}
|
run: npx eslint --fix {push_files}
|
||||||
|
|
||||||
|
post-merge:
|
||||||
|
commands:
|
||||||
|
update-submodules:
|
||||||
|
run: git submodule update --init --recursive
|
51
package-lock.json
generated
51
package-lock.json
generated
@ -12,6 +12,7 @@
|
|||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"i18next": "^23.11.1",
|
"i18next": "^23.11.1",
|
||||||
"i18next-browser-languagedetector": "^7.2.1",
|
"i18next-browser-languagedetector": "^7.2.1",
|
||||||
|
"i18next-http-backend": "^2.6.1",
|
||||||
"i18next-korean-postposition-processor": "^1.0.0",
|
"i18next-korean-postposition-processor": "^1.0.0",
|
||||||
"json-stable-stringify": "^1.1.0",
|
"json-stable-stringify": "^1.1.0",
|
||||||
"phaser": "^3.70.0",
|
"phaser": "^3.70.0",
|
||||||
@ -37,7 +38,7 @@
|
|||||||
"typedoc": "^0.26.4",
|
"typedoc": "^0.26.4",
|
||||||
"typescript": "^5.5.3",
|
"typescript": "^5.5.3",
|
||||||
"typescript-eslint": "^8.0.0-alpha.54",
|
"typescript-eslint": "^8.0.0-alpha.54",
|
||||||
"vite": "^5.3.5",
|
"vite": "^5.4.8",
|
||||||
"vite-tsconfig-paths": "^4.3.2",
|
"vite-tsconfig-paths": "^4.3.2",
|
||||||
"vitest": "^2.0.4",
|
"vitest": "^2.0.4",
|
||||||
"vitest-canvas-mock": "^0.3.3"
|
"vitest-canvas-mock": "^0.3.3"
|
||||||
@ -3650,7 +3651,6 @@
|
|||||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
@ -4004,9 +4004,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/i18next-http-backend": {
|
"node_modules/i18next-http-backend": {
|
||||||
"version": "2.5.2",
|
"version": "2.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.6.1.tgz",
|
||||||
"integrity": "sha512-+K8HbDfrvc1/2X8jpb7RLhI9ZxBDpx3xogYkQwGKlWAUXLSEGXzgdt3EcUjLlBCdMwdQY+K+EUF6oh8oB6rwHw==",
|
"integrity": "sha512-rCilMAnlEQNeKOZY1+x8wLM5IpYOj10guGvEpeC59tNjj6MMreLIjIW8D1RclhD3ifLwn6d/Y9HEM1RUE6DSog==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cross-fetch": "4.0.0"
|
"cross-fetch": "4.0.0"
|
||||||
}
|
}
|
||||||
@ -5042,7 +5043,6 @@
|
|||||||
"url": "https://github.com/sponsors/ai"
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"nanoid": "bin/nanoid.cjs"
|
"nanoid": "bin/nanoid.cjs"
|
||||||
},
|
},
|
||||||
@ -5441,9 +5441,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.4.39",
|
"version": "8.4.47",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
|
||||||
"integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==",
|
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -5459,16 +5459,21 @@
|
|||||||
"url": "https://github.com/sponsors/ai"
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.7",
|
"nanoid": "^3.3.7",
|
||||||
"picocolors": "^1.0.1",
|
"picocolors": "^1.1.0",
|
||||||
"source-map-js": "^1.2.0"
|
"source-map-js": "^1.2.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^10 || ^12 || >=14"
|
"node": "^10 || ^12 || >=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/postcss/node_modules/picocolors": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/prelude-ls": {
|
"node_modules/prelude-ls": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||||
@ -5865,11 +5870,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@ -6469,15 +6473,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "5.3.5",
|
"version": "5.4.8",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",
|
||||||
"integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==",
|
"integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.21.3",
|
"esbuild": "^0.21.3",
|
||||||
"postcss": "^8.4.39",
|
"postcss": "^8.4.43",
|
||||||
"rollup": "^4.13.0"
|
"rollup": "^4.20.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"vite": "bin/vite.js"
|
"vite": "bin/vite.js"
|
||||||
@ -6496,6 +6499,7 @@
|
|||||||
"less": "*",
|
"less": "*",
|
||||||
"lightningcss": "^1.21.0",
|
"lightningcss": "^1.21.0",
|
||||||
"sass": "*",
|
"sass": "*",
|
||||||
|
"sass-embedded": "*",
|
||||||
"stylus": "*",
|
"stylus": "*",
|
||||||
"sugarss": "*",
|
"sugarss": "*",
|
||||||
"terser": "^5.4.0"
|
"terser": "^5.4.0"
|
||||||
@ -6513,6 +6517,9 @@
|
|||||||
"sass": {
|
"sass": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"sass-embedded": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"stylus": {
|
"stylus": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
"docs": "typedoc",
|
"docs": "typedoc",
|
||||||
"depcruise": "depcruise src",
|
"depcruise": "depcruise src",
|
||||||
"depcruise:graph": "depcruise src --output-type dot | node dependency-graph.js > dependency-graph.svg",
|
"depcruise:graph": "depcruise src --output-type dot | node dependency-graph.js > dependency-graph.svg",
|
||||||
"create-test": "node ./create-test-boilerplate.js"
|
"create-test": "node ./create-test-boilerplate.js",
|
||||||
|
"postinstall": "npx lefthook install && npx lefthook run post-merge"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.3.0",
|
"@eslint/js": "^9.3.0",
|
||||||
@ -41,7 +42,7 @@
|
|||||||
"typedoc": "^0.26.4",
|
"typedoc": "^0.26.4",
|
||||||
"typescript": "^5.5.3",
|
"typescript": "^5.5.3",
|
||||||
"typescript-eslint": "^8.0.0-alpha.54",
|
"typescript-eslint": "^8.0.0-alpha.54",
|
||||||
"vite": "^5.3.5",
|
"vite": "^5.4.8",
|
||||||
"vite-tsconfig-paths": "^4.3.2",
|
"vite-tsconfig-paths": "^4.3.2",
|
||||||
"vitest": "^2.0.4",
|
"vitest": "^2.0.4",
|
||||||
"vitest-canvas-mock": "^0.3.3"
|
"vitest-canvas-mock": "^0.3.3"
|
||||||
@ -51,6 +52,7 @@
|
|||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"i18next": "^23.11.1",
|
"i18next": "^23.11.1",
|
||||||
"i18next-browser-languagedetector": "^7.2.1",
|
"i18next-browser-languagedetector": "^7.2.1",
|
||||||
|
"i18next-http-backend": "^2.6.1",
|
||||||
"i18next-korean-postposition-processor": "^1.0.0",
|
"i18next-korean-postposition-processor": "^1.0.0",
|
||||||
"json-stable-stringify": "^1.1.0",
|
"json-stable-stringify": "^1.1.0",
|
||||||
"phaser": "^3.70.0",
|
"phaser": "^3.70.0",
|
||||||
|
BIN
public/images/ui/friendship.png
Normal file
BIN
public/images/ui/friendship.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 174 B |
BIN
public/images/ui/friendship_overlay.png
Normal file
BIN
public/images/ui/friendship_overlay.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 182 B |
BIN
public/images/ui/legacy/friendship.png
Normal file
BIN
public/images/ui/legacy/friendship.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 174 B |
BIN
public/images/ui/legacy/friendship_overlay.png
Normal file
BIN
public/images/ui/legacy/friendship_overlay.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 182 B |
1
public/locales
Submodule
1
public/locales
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 3ccef8472dd7cc7c362538489954cb8fdad27e5f
|
12
src/@types/i18next.d.ts
vendored
12
src/@types/i18next.d.ts
vendored
@ -1,18 +1,8 @@
|
|||||||
import { type enConfig } from "#app/locales/en/config";
|
|
||||||
import { TOptions } from "i18next";
|
import { TOptions } from "i18next";
|
||||||
|
|
||||||
//TODO: this needs to be type properly in the future
|
|
||||||
// Module declared to make referencing keys in the localization files type-safe.
|
// Module declared to make referencing keys in the localization files type-safe.
|
||||||
declare module "i18next" {
|
declare module "i18next" {
|
||||||
interface CustomTypeOptions {
|
|
||||||
defaultNS: "menu", // needed here as well for typedoc
|
|
||||||
resources: typeof enConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TFunction {
|
interface TFunction {
|
||||||
(
|
(key: string | string[], options?: TOptions & Record<string, unknown>): string;
|
||||||
key: string | string[],
|
|
||||||
options?: TOptions & Record<string, unknown>
|
|
||||||
): string;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import { trainerConfigs, TrainerSlot } from "./data/trainer-config";
|
|||||||
import Trainer, { TrainerVariant } from "./field/trainer";
|
import Trainer, { TrainerVariant } from "./field/trainer";
|
||||||
import TrainerData from "./system/trainer-data";
|
import TrainerData from "./system/trainer-data";
|
||||||
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
||||||
import { pokemonPrevolutions } from "./data/pokemon-evolutions";
|
import { pokemonPrevolutions } from "./data/balance/pokemon-evolutions";
|
||||||
import PokeballTray from "./ui/pokeball-tray";
|
import PokeballTray from "./ui/pokeball-tray";
|
||||||
import InvertPostFX from "./pipelines/invert";
|
import InvertPostFX from "./pipelines/invert";
|
||||||
import { Achv, achvs, ModifierAchv, MoneyAchv } from "./system/achv";
|
import { Achv, achvs, ModifierAchv, MoneyAchv } from "./system/achv";
|
||||||
@ -42,7 +42,7 @@ import PokemonSpriteSparkleHandler from "./field/pokemon-sprite-sparkle-handler"
|
|||||||
import CharSprite from "./ui/char-sprite";
|
import CharSprite from "./ui/char-sprite";
|
||||||
import DamageNumberHandler from "./field/damage-number-handler";
|
import DamageNumberHandler from "./field/damage-number-handler";
|
||||||
import PokemonInfoContainer from "./ui/pokemon-info-container";
|
import PokemonInfoContainer from "./ui/pokemon-info-container";
|
||||||
import { biomeDepths, getBiomeName } from "./data/biomes";
|
import { biomeDepths, getBiomeName } from "./data/balance/biomes";
|
||||||
import { SceneBase } from "./scene-base";
|
import { SceneBase } from "./scene-base";
|
||||||
import CandyBar from "./ui/candy-bar";
|
import CandyBar from "./ui/candy-bar";
|
||||||
import { Variant, variantData } from "./data/variant";
|
import { Variant, variantData } from "./data/variant";
|
||||||
@ -1040,10 +1040,6 @@ export default class BattleScene extends SceneBase {
|
|||||||
|
|
||||||
this.gameMode = getGameMode(GameModes.CLASSIC);
|
this.gameMode = getGameMode(GameModes.CLASSIC);
|
||||||
|
|
||||||
this.setSeed(Overrides.SEED_OVERRIDE || Utils.randomString(24));
|
|
||||||
console.log("Seed:", this.seed);
|
|
||||||
this.resetSeed(); // Properly resets RNG after saving and quitting a session
|
|
||||||
|
|
||||||
this.disableMenu = false;
|
this.disableMenu = false;
|
||||||
|
|
||||||
this.score = 0;
|
this.score = 0;
|
||||||
@ -1078,6 +1074,12 @@ export default class BattleScene extends SceneBase {
|
|||||||
//@ts-ignore - allowing `null` for currentBattle causes a lot of trouble
|
//@ts-ignore - allowing `null` for currentBattle causes a lot of trouble
|
||||||
this.currentBattle = null; // TODO: resolve ts-ignore
|
this.currentBattle = null; // TODO: resolve ts-ignore
|
||||||
|
|
||||||
|
// Reset RNG after end of game or save & quit.
|
||||||
|
// This needs to happen after clearing this.currentBattle or the seed will be affected by the last wave played
|
||||||
|
this.setSeed(Overrides.SEED_OVERRIDE || Utils.randomString(24));
|
||||||
|
console.log("Seed:", this.seed);
|
||||||
|
this.resetSeed();
|
||||||
|
|
||||||
this.biomeWaveText.setText(startingWave.toString());
|
this.biomeWaveText.setText(startingWave.toString());
|
||||||
this.biomeWaveText.setVisible(false);
|
this.biomeWaveText.setVisible(false);
|
||||||
|
|
||||||
@ -2443,7 +2445,10 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
if ((modifier as PersistentModifier).add(this.modifiers, !!virtual, this)) {
|
if ((modifier as PersistentModifier).add(this.modifiers, !!virtual, this)) {
|
||||||
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
||||||
success = modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]);
|
const pokemon = this.getPokemonById(modifier.pokemonId);
|
||||||
|
if (pokemon) {
|
||||||
|
success = modifier.apply(pokemon, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (playSound && !this.sound.get(soundName)) {
|
if (playSound && !this.sound.get(soundName)) {
|
||||||
this.playSound(soundName);
|
this.playSound(soundName);
|
||||||
@ -2470,7 +2475,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
for (const p in this.party) {
|
for (const p in this.party) {
|
||||||
const pokemon = this.party[p];
|
const pokemon = this.party[p];
|
||||||
|
|
||||||
const args: any[] = [ pokemon ];
|
const args: unknown[] = [];
|
||||||
if (modifier instanceof PokemonHpRestoreModifier) {
|
if (modifier instanceof PokemonHpRestoreModifier) {
|
||||||
if (!(modifier as PokemonHpRestoreModifier).fainted) {
|
if (!(modifier as PokemonHpRestoreModifier).fainted) {
|
||||||
const hpRestoreMultiplier = new Utils.IntegerHolder(1);
|
const hpRestoreMultiplier = new Utils.IntegerHolder(1);
|
||||||
@ -2483,8 +2488,8 @@ export default class BattleScene extends SceneBase {
|
|||||||
args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon);
|
args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modifier.shouldApply(args)) {
|
if (modifier.shouldApply(pokemon, ...args)) {
|
||||||
const result = modifier.apply(args);
|
const result = modifier.apply(pokemon, ...args);
|
||||||
if (result instanceof Promise) {
|
if (result instanceof Promise) {
|
||||||
modifierPromises.push(result.then(s => success ||= s));
|
modifierPromises.push(result.then(s => success ||= s));
|
||||||
} else {
|
} else {
|
||||||
@ -2496,8 +2501,8 @@ export default class BattleScene extends SceneBase {
|
|||||||
return Promise.allSettled([ this.party.map(p => p.updateInfo(instant)), ...modifierPromises ]).then(() => resolve(success));
|
return Promise.allSettled([ this.party.map(p => p.updateInfo(instant)), ...modifierPromises ]).then(() => resolve(success));
|
||||||
} else {
|
} else {
|
||||||
const args = [ this ];
|
const args = [ this ];
|
||||||
if (modifier.shouldApply(args)) {
|
if (modifier.shouldApply(...args)) {
|
||||||
const result = modifier.apply(args);
|
const result = modifier.apply(...args);
|
||||||
if (result instanceof Promise) {
|
if (result instanceof Promise) {
|
||||||
return result.then(success => resolve(success));
|
return result.then(success => resolve(success));
|
||||||
} else {
|
} else {
|
||||||
@ -2519,7 +2524,10 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
if ((modifier as PersistentModifier).add(this.enemyModifiers, false, this)) {
|
if ((modifier as PersistentModifier).add(this.enemyModifiers, false, this)) {
|
||||||
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
||||||
modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]);
|
const pokemon = this.getPokemonById(modifier.pokemonId);
|
||||||
|
if (pokemon) {
|
||||||
|
modifier.apply(pokemon, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (const rm of modifiersToRemove) {
|
for (const rm of modifiersToRemove) {
|
||||||
this.removeModifier(rm, true);
|
this.removeModifier(rm, true);
|
||||||
@ -2753,7 +2761,10 @@ export default class BattleScene extends SceneBase {
|
|||||||
if (modifierIndex > -1) {
|
if (modifierIndex > -1) {
|
||||||
modifiers.splice(modifierIndex, 1);
|
modifiers.splice(modifierIndex, 1);
|
||||||
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
||||||
modifier.apply([ this.getPokemonById(modifier.pokemonId), false ]);
|
const pokemon = this.getPokemonById(modifier.pokemonId);
|
||||||
|
if (pokemon) {
|
||||||
|
modifier.apply(pokemon, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2771,16 +2782,36 @@ export default class BattleScene extends SceneBase {
|
|||||||
return (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType);
|
return (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType);
|
||||||
}
|
}
|
||||||
|
|
||||||
findModifiers(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier[] {
|
/**
|
||||||
return (player ? this.modifiers : this.enemyModifiers).filter(m => (modifierFilter as ModifierPredicate)(m));
|
* Get all of the modifiers that pass the `modifierFilter` function
|
||||||
|
* @param modifierFilter The function used to filter a target's modifiers
|
||||||
|
* @param isPlayer Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
|
||||||
|
* @returns the list of all modifiers that passed the `modifierFilter` function
|
||||||
|
*/
|
||||||
|
findModifiers(modifierFilter: ModifierPredicate, isPlayer: boolean = true): PersistentModifier[] {
|
||||||
|
return (isPlayer ? this.modifiers : this.enemyModifiers).filter(modifierFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the first modifier that pass the `modifierFilter` function
|
||||||
|
* @param modifierFilter The function used to filter a target's modifiers
|
||||||
|
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
|
||||||
|
* @returns the first modifier that passed the `modifierFilter` function; `undefined` if none passed
|
||||||
|
*/
|
||||||
findModifier(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier | undefined {
|
findModifier(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier | undefined {
|
||||||
return (player ? this.modifiers : this.enemyModifiers).find(m => (modifierFilter as ModifierPredicate)(m));
|
return (player ? this.modifiers : this.enemyModifiers).find(modifierFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyShuffledModifiers(scene: BattleScene, modifierType: Constructor<Modifier>, player: boolean = true, ...args: any[]): PersistentModifier[] {
|
/**
|
||||||
let modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args));
|
* Apply all modifiers that match `modifierType` in a random order
|
||||||
|
* @param scene {@linkcode BattleScene} used to randomize the order of modifiers
|
||||||
|
* @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier}
|
||||||
|
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
|
||||||
|
* @param ...args The list of arguments needed to invoke `modifierType.apply`
|
||||||
|
* @returns the list of all modifiers that matched `modifierType` and were applied.
|
||||||
|
*/
|
||||||
|
applyShuffledModifiers<T extends PersistentModifier>(scene: BattleScene, modifierType: Constructor<T>, player: boolean = true, ...args: Parameters<T["apply"]>): T[] {
|
||||||
|
let modifiers = (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType && m.shouldApply(...args));
|
||||||
scene.executeWithSeedOffset(() => {
|
scene.executeWithSeedOffset(() => {
|
||||||
const shuffleModifiers = mods => {
|
const shuffleModifiers = mods => {
|
||||||
if (mods.length < 1) {
|
if (mods.length < 1) {
|
||||||
@ -2794,15 +2825,23 @@ export default class BattleScene extends SceneBase {
|
|||||||
return this.applyModifiersInternal(modifiers, player, args);
|
return this.applyModifiersInternal(modifiers, player, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyModifiers(modifierType: Constructor<Modifier>, player: boolean = true, ...args: any[]): PersistentModifier[] {
|
/**
|
||||||
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args));
|
* Apply all modifiers that match `modifierType`
|
||||||
|
* @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier}
|
||||||
|
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
|
||||||
|
* @param ...args The list of arguments needed to invoke `modifierType.apply`
|
||||||
|
* @returns the list of all modifiers that matched `modifierType` and were applied.
|
||||||
|
*/
|
||||||
|
applyModifiers<T extends PersistentModifier>(modifierType: Constructor<T>, player: boolean = true, ...args: Parameters<T["apply"]>): T[] {
|
||||||
|
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType && m.shouldApply(...args));
|
||||||
return this.applyModifiersInternal(modifiers, player, args);
|
return this.applyModifiersInternal(modifiers, player, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyModifiersInternal(modifiers: PersistentModifier[], player: boolean, args: any[]): PersistentModifier[] {
|
/** Helper function to apply all passed modifiers */
|
||||||
const appliedModifiers: PersistentModifier[] = [];
|
applyModifiersInternal<T extends PersistentModifier>(modifiers: T[], player: boolean, args: Parameters<T["apply"]>): T[] {
|
||||||
|
const appliedModifiers: T[] = [];
|
||||||
for (const modifier of modifiers) {
|
for (const modifier of modifiers) {
|
||||||
if (modifier.apply(args)) {
|
if (modifier.apply(...args)) {
|
||||||
console.log("Applied", modifier.type.name, !player ? "(enemy)" : "");
|
console.log("Applied", modifier.type.name, !player ? "(enemy)" : "");
|
||||||
appliedModifiers.push(modifier);
|
appliedModifiers.push(modifier);
|
||||||
}
|
}
|
||||||
@ -2811,10 +2850,17 @@ export default class BattleScene extends SceneBase {
|
|||||||
return appliedModifiers;
|
return appliedModifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyModifier(modifierType: Constructor<Modifier>, player: boolean = true, ...args: any[]): PersistentModifier | null {
|
/**
|
||||||
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args));
|
* Apply the first modifier that matches `modifierType`
|
||||||
|
* @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier}
|
||||||
|
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
|
||||||
|
* @param ...args The list of arguments needed to invoke `modifierType.apply`
|
||||||
|
* @returns the first modifier that matches `modifierType` and was applied; return `null` if none matched
|
||||||
|
*/
|
||||||
|
applyModifier<T extends PersistentModifier>(modifierType: Constructor<T>, player: boolean = true, ...args: Parameters<T["apply"]>): T | null {
|
||||||
|
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType && m.shouldApply(...args));
|
||||||
for (const modifier of modifiers) {
|
for (const modifier of modifiers) {
|
||||||
if (modifier.apply(args)) {
|
if (modifier.apply(...args)) {
|
||||||
console.log("Applied", modifier.type.name, !player ? "(enemy)" : "");
|
console.log("Applied", modifier.type.name, !player ? "(enemy)" : "");
|
||||||
return modifier;
|
return modifier;
|
||||||
}
|
}
|
||||||
@ -2880,7 +2926,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
validateAchv(achv: Achv, args?: any[]): boolean {
|
validateAchv(achv: Achv, args?: unknown[]): boolean {
|
||||||
if (!this.gameData.achvUnlocks.hasOwnProperty(achv.id) && achv.validate(this, args)) {
|
if (!this.gameData.achvUnlocks.hasOwnProperty(achv.id) && achv.validate(this, args)) {
|
||||||
this.gameData.achvUnlocks[achv.id] = new Date().getTime();
|
this.gameData.achvUnlocks[achv.id] = new Date().getTime();
|
||||||
this.ui.achvBar.showAchv(achv);
|
this.ui.achvBar.showAchv(achv);
|
||||||
@ -2893,7 +2939,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
validateVoucher(voucher: Voucher, args?: any[]): boolean {
|
validateVoucher(voucher: Voucher, args?: unknown[]): boolean {
|
||||||
if (!this.gameData.voucherUnlocks.hasOwnProperty(voucher.id) && voucher.validate(this, args)) {
|
if (!this.gameData.voucherUnlocks.hasOwnProperty(voucher.id) && voucher.validate(this, args)) {
|
||||||
this.gameData.voucherUnlocks[voucher.id] = new Date().getTime();
|
this.gameData.voucherUnlocks[voucher.id] = new Date().getTime();
|
||||||
this.ui.achvBar.showAchv(voucher);
|
this.ui.achvBar.showAchv(voucher);
|
||||||
@ -3091,11 +3137,6 @@ export default class BattleScene extends SceneBase {
|
|||||||
private isWaveMysteryEncounter(newBattleType: BattleType, waveIndex: number, sessionDataEncounterType?: MysteryEncounterType): boolean {
|
private isWaveMysteryEncounter(newBattleType: BattleType, waveIndex: number, sessionDataEncounterType?: MysteryEncounterType): boolean {
|
||||||
const [ lowestMysteryEncounterWave, highestMysteryEncounterWave ] = this.gameMode.getMysteryEncounterLegalWaves();
|
const [ lowestMysteryEncounterWave, highestMysteryEncounterWave ] = this.gameMode.getMysteryEncounterLegalWaves();
|
||||||
if (this.gameMode.hasMysteryEncounters && newBattleType === BattleType.WILD && !this.gameMode.isBoss(waveIndex) && waveIndex < highestMysteryEncounterWave && waveIndex > lowestMysteryEncounterWave) {
|
if (this.gameMode.hasMysteryEncounters && newBattleType === BattleType.WILD && !this.gameMode.isBoss(waveIndex) && waveIndex < highestMysteryEncounterWave && waveIndex > lowestMysteryEncounterWave) {
|
||||||
// If ME type is already defined in session data, no need to roll RNG check
|
|
||||||
if (!isNullOrUndefined(sessionDataEncounterType)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Base spawn weight is BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT/256, and increases by WEIGHT_INCREMENT_ON_SPAWN_MISS/256 for each missed attempt at spawning an encounter on a valid floor
|
// Base spawn weight is BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT/256, and increases by WEIGHT_INCREMENT_ON_SPAWN_MISS/256 for each missed attempt at spawning an encounter on a valid floor
|
||||||
const sessionEncounterRate = this.mysteryEncounterSaveData.encounterSpawnChance;
|
const sessionEncounterRate = this.mysteryEncounterSaveData.encounterSpawnChance;
|
||||||
const encounteredEvents = this.mysteryEncounterSaveData.encounteredEvents;
|
const encounteredEvents = this.mysteryEncounterSaveData.encounteredEvents;
|
||||||
|
@ -497,7 +497,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], rand
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 1/3 chance for evil team grunts to be double battles */
|
/* 1/3 chance for evil team grunts to be double battles */
|
||||||
const evilTeamGrunts = [TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT];
|
const evilTeamGrunts = [ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ];
|
||||||
const isEvilTeamGrunt = evilTeamGrunts.includes(trainerTypes[rand]);
|
const isEvilTeamGrunt = evilTeamGrunts.includes(trainerTypes[rand]);
|
||||||
|
|
||||||
if (trainerConfigs[trainerTypes[rand]].hasDouble && isEvilTeamGrunt) {
|
if (trainerConfigs[trainerTypes[rand]].hasDouble && isEvilTeamGrunt) {
|
||||||
|
@ -4,7 +4,7 @@ import { Constructor } from "#app/utils";
|
|||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
import { getPokemonNameWithAffix } from "../messages";
|
import { getPokemonNameWithAffix } from "../messages";
|
||||||
import { Weather, WeatherType } from "./weather";
|
import { Weather, WeatherType } from "./weather";
|
||||||
import { BattlerTag, GroundedTag, GulpMissileTag, SemiInvulnerableTag } from "./battler-tags";
|
import { BattlerTag, GroundedTag } from "./battler-tags";
|
||||||
import { StatusEffect, getNonVolatileStatusEffects, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect";
|
import { StatusEffect, getNonVolatileStatusEffects, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect";
|
||||||
import { Gender } from "./gender";
|
import { Gender } from "./gender";
|
||||||
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, FlinchAttr, OneHitKOAttr, HitHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr, VariableMoveTypeAttr, RandomMovesetMoveAttr, RandomMoveAttr, NaturePowerAttr, CopyMoveAttr, MoveAttr, MultiHitAttr, ChargeAttr, SacrificialAttr, SacrificialAttrOnHit, NeutralDamageAgainstFlyingTypeMultiplierAttr, FixedDamageAttr } from "./move";
|
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, FlinchAttr, OneHitKOAttr, HitHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr, VariableMoveTypeAttr, RandomMovesetMoveAttr, RandomMoveAttr, NaturePowerAttr, CopyMoveAttr, MoveAttr, MultiHitAttr, ChargeAttr, SacrificialAttr, SacrificialAttrOnHit, NeutralDamageAgainstFlyingTypeMultiplierAttr, FixedDamageAttr } from "./move";
|
||||||
@ -123,6 +123,7 @@ export class Ability implements Localizable {
|
|||||||
type AbAttrApplyFunc<TAttr extends AbAttr> = (attr: TAttr, passive: boolean) => boolean | Promise<boolean>;
|
type AbAttrApplyFunc<TAttr extends AbAttr> = (attr: TAttr, passive: boolean) => boolean | Promise<boolean>;
|
||||||
type AbAttrCondition = (pokemon: Pokemon) => boolean;
|
type AbAttrCondition = (pokemon: Pokemon) => boolean;
|
||||||
|
|
||||||
|
// TODO: Can this be improved?
|
||||||
type PokemonAttackCondition = (user: Pokemon | null, target: Pokemon | null, move: Move) => boolean;
|
type PokemonAttackCondition = (user: Pokemon | null, target: Pokemon | null, move: Move) => boolean;
|
||||||
type PokemonDefendCondition = (target: Pokemon, user: Pokemon, move: Move) => boolean;
|
type PokemonDefendCondition = (target: Pokemon, user: Pokemon, move: Move) => boolean;
|
||||||
type PokemonStatStageChangeCondition = (target: Pokemon, statsChanged: BattleStat[], stages: number) => boolean;
|
type PokemonStatStageChangeCondition = (target: Pokemon, statsChanged: BattleStat[], stages: number) => boolean;
|
||||||
@ -518,6 +519,7 @@ export class FullHpResistTypeAbAttr extends PreDefendAbAttr {
|
|||||||
|
|
||||||
if (pokemon.isFullHp() && typeMultiplier.value > 0.5) {
|
if (pokemon.isFullHp() && typeMultiplier.value > 0.5) {
|
||||||
typeMultiplier.value = 0.5;
|
typeMultiplier.value = 0.5;
|
||||||
|
pokemon.turnData.moveEffectiveness = 0.5;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -536,53 +538,6 @@ export class PostDefendAbAttr extends AbAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies the effects of Gulp Missile when the user is hit by an attack.
|
|
||||||
* @extends PostDefendAbAttr
|
|
||||||
*/
|
|
||||||
export class PostDefendGulpMissileAbAttr extends PostDefendAbAttr {
|
|
||||||
constructor() {
|
|
||||||
super(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Damages the attacker and triggers the secondary effect based on the form or the BattlerTagType.
|
|
||||||
* @param {Pokemon} pokemon - The defending Pokemon.
|
|
||||||
* @param passive - n/a
|
|
||||||
* @param {Pokemon} attacker - The attacking Pokemon.
|
|
||||||
* @param {Move} move - The move being used.
|
|
||||||
* @param {HitResult} hitResult - n/a
|
|
||||||
* @param {any[]} args - n/a
|
|
||||||
* @returns Whether the effects of the ability are applied.
|
|
||||||
*/
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean | Promise<boolean> {
|
|
||||||
const battlerTag = pokemon.getTag(GulpMissileTag);
|
|
||||||
if (!battlerTag || move.category === MoveCategory.STATUS || pokemon.getTag(SemiInvulnerableTag)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (simulated) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
|
||||||
applyAbAttrs(BlockNonDirectDamageAbAttr, attacker, cancelled);
|
|
||||||
|
|
||||||
if (!cancelled.value) {
|
|
||||||
attacker.damageAndUpdate(Math.max(1, Math.floor(attacker.getMaxHp() / 4)), HitResult.OTHER);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (battlerTag.tagType === BattlerTagType.GULP_MISSILE_ARROKUDA) {
|
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, attacker.getBattlerIndex(), false, [ Stat.DEF ], -1));
|
|
||||||
} else {
|
|
||||||
attacker.trySetStatus(StatusEffect.PARALYSIS, true, pokemon);
|
|
||||||
}
|
|
||||||
|
|
||||||
pokemon.removeTag(battlerTag.tagType);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class FieldPriorityMoveImmunityAbAttr extends PreDefendAbAttr {
|
export class FieldPriorityMoveImmunityAbAttr extends PreDefendAbAttr {
|
||||||
applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
const attackPriority = new Utils.IntegerHolder(move.priority);
|
const attackPriority = new Utils.IntegerHolder(move.priority);
|
||||||
@ -2479,7 +2434,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
|
|||||||
pokemon.setStatStage(s, target.getStatStage(s));
|
pokemon.setStatStage(s, target.getStatStage(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
pokemon.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m!.moveId, m!.ppUsed, m!.ppUp)); // TODO: are those bangs correct?
|
pokemon.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m?.moveId ?? Moves.NONE, m?.ppUsed, m?.ppUp));
|
||||||
pokemon.summonData.types = target.getTypes();
|
pokemon.summonData.types = target.getTypes();
|
||||||
|
|
||||||
|
|
||||||
@ -3199,12 +3154,12 @@ export class ForewarnAbAttr extends PostSummonAbAttr {
|
|||||||
} else if (move?.getMove().power === -1) {
|
} else if (move?.getMove().power === -1) {
|
||||||
movePower = 80;
|
movePower = 80;
|
||||||
} else {
|
} else {
|
||||||
movePower = move!.getMove().power; // TODO: is this bang correct?
|
movePower = move?.getMove().power ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (movePower > maxPowerSeen) {
|
if (movePower > maxPowerSeen) {
|
||||||
maxPowerSeen = movePower;
|
maxPowerSeen = movePower;
|
||||||
maxMove = move!.getName(); // TODO: is this bang correct?
|
maxMove = move?.getName() ?? "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5210,8 +5165,7 @@ export function initAbilities() {
|
|||||||
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonMoldBreaker", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }))
|
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonMoldBreaker", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }))
|
||||||
.attr(MoveAbilityBypassAbAttr),
|
.attr(MoveAbilityBypassAbAttr),
|
||||||
new Ability(Abilities.SUPER_LUCK, 4)
|
new Ability(Abilities.SUPER_LUCK, 4)
|
||||||
.attr(BonusCritAbAttr)
|
.attr(BonusCritAbAttr),
|
||||||
.partial(),
|
|
||||||
new Ability(Abilities.AFTERMATH, 4)
|
new Ability(Abilities.AFTERMATH, 4)
|
||||||
.attr(PostFaintContactDamageAbAttr, 4)
|
.attr(PostFaintContactDamageAbAttr, 4)
|
||||||
.bypassFaint(),
|
.bypassFaint(),
|
||||||
@ -5223,8 +5177,7 @@ export function initAbilities() {
|
|||||||
.attr(IgnoreOpponentStatStagesAbAttr)
|
.attr(IgnoreOpponentStatStagesAbAttr)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.TINTED_LENS, 4)
|
new Ability(Abilities.TINTED_LENS, 4)
|
||||||
//@ts-ignore
|
.attr(DamageBoostAbAttr, 2, (user, target, move) => (target?.getMoveEffectiveness(user!, move) ?? 1) <= 0.5),
|
||||||
.attr(DamageBoostAbAttr, 2, (user, target, move) => target?.getMoveEffectiveness(user, move) <= 0.5), // TODO: fix TS issues
|
|
||||||
new Ability(Abilities.FILTER, 4)
|
new Ability(Abilities.FILTER, 4)
|
||||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getMoveEffectiveness(user, move) >= 2, 0.75)
|
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getMoveEffectiveness(user, move) >= 2, 0.75)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
@ -5342,8 +5295,9 @@ export function initAbilities() {
|
|||||||
.attr(WonderSkinAbAttr)
|
.attr(WonderSkinAbAttr)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.ANALYTIC, 5)
|
new Ability(Abilities.ANALYTIC, 5)
|
||||||
//@ts-ignore
|
.attr(MovePowerBoostAbAttr, (user, target, move) =>
|
||||||
.attr(MovePowerBoostAbAttr, (user, target, move) => !!target?.getLastXMoves(1).find(m => m.turn === target?.scene.currentBattle.turn) || user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command !== Command.FIGHT, 1.3), // TODO fix TS issues
|
!!target?.getLastXMoves(1).find(m => m.turn === target?.scene.currentBattle.turn)
|
||||||
|
|| user?.scene.currentBattle.turnCommands[target?.getBattlerIndex() ?? BattlerIndex.ATTACKER]?.command !== Command.FIGHT, 1.3),
|
||||||
new Ability(Abilities.ILLUSION, 5)
|
new Ability(Abilities.ILLUSION, 5)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
@ -5508,8 +5462,7 @@ export function initAbilities() {
|
|||||||
.bypassFaint()
|
.bypassFaint()
|
||||||
.partial(),
|
.partial(),
|
||||||
new Ability(Abilities.STAKEOUT, 7)
|
new Ability(Abilities.STAKEOUT, 7)
|
||||||
//@ts-ignore
|
.attr(MovePowerBoostAbAttr, (user, target, move) => user?.scene.currentBattle.turnCommands[target?.getBattlerIndex() ?? BattlerIndex.ATTACKER]?.command === Command.POKEMON, 2),
|
||||||
.attr(MovePowerBoostAbAttr, (user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command === Command.POKEMON, 2), // TODO: fix TS issues
|
|
||||||
new Ability(Abilities.WATER_BUBBLE, 7)
|
new Ability(Abilities.WATER_BUBBLE, 7)
|
||||||
.attr(ReceivedTypeDamageMultiplierAbAttr, Type.FIRE, 0.5)
|
.attr(ReceivedTypeDamageMultiplierAbAttr, Type.FIRE, 0.5)
|
||||||
.attr(MoveTypePowerBoostAbAttr, Type.WATER, 2)
|
.attr(MoveTypePowerBoostAbAttr, Type.WATER, 2)
|
||||||
@ -5647,8 +5600,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.PRISM_ARMOR, 7)
|
new Ability(Abilities.PRISM_ARMOR, 7)
|
||||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getMoveEffectiveness(user, move) >= 2, 0.75),
|
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getMoveEffectiveness(user, move) >= 2, 0.75),
|
||||||
new Ability(Abilities.NEUROFORCE, 7)
|
new Ability(Abilities.NEUROFORCE, 7)
|
||||||
//@ts-ignore
|
.attr(MovePowerBoostAbAttr, (user, target, move) => (target?.getMoveEffectiveness(user!, move) ?? 1) >= 2, 1.25),
|
||||||
.attr(MovePowerBoostAbAttr, (user, target, move) => target?.getMoveEffectiveness(user, move) >= 2, 1.25), // TODO: fix TS issues
|
|
||||||
new Ability(Abilities.INTREPID_SWORD, 8)
|
new Ability(Abilities.INTREPID_SWORD, 8)
|
||||||
.attr(PostSummonStatStageChangeAbAttr, [ Stat.ATK ], 1, true)
|
.attr(PostSummonStatStageChangeAbAttr, [ Stat.ATK ], 1, true)
|
||||||
.condition(getOncePerBattleCondition(Abilities.INTREPID_SWORD)),
|
.condition(getOncePerBattleCondition(Abilities.INTREPID_SWORD)),
|
||||||
@ -5669,13 +5621,19 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.MIRROR_ARMOR, 8)
|
new Ability(Abilities.MIRROR_ARMOR, 8)
|
||||||
.ignorable()
|
.ignorable()
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
|
/**
|
||||||
|
* Right now, the logic is attached to Surf and Dive moves. Ideally, the post-defend/hit should be an
|
||||||
|
* ability attribute but the current implementation of move effects for BattlerTag does not support this- in the case
|
||||||
|
* where Cramorant is fainted.
|
||||||
|
* @see {@linkcode GulpMissileTagAttr} and {@linkcode GulpMissileTag} for Gulp Missile implementation
|
||||||
|
*/
|
||||||
new Ability(Abilities.GULP_MISSILE, 8)
|
new Ability(Abilities.GULP_MISSILE, 8)
|
||||||
.attr(UnsuppressableAbilityAbAttr)
|
.attr(UnsuppressableAbilityAbAttr)
|
||||||
.attr(NoTransformAbilityAbAttr)
|
.attr(NoTransformAbilityAbAttr)
|
||||||
.attr(NoFusionAbilityAbAttr)
|
.attr(NoFusionAbilityAbAttr)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(PostDefendGulpMissileAbAttr),
|
.bypassFaint(),
|
||||||
new Ability(Abilities.STALWART, 8)
|
new Ability(Abilities.STALWART, 8)
|
||||||
.attr(BlockRedirectAbAttr),
|
.attr(BlockRedirectAbAttr),
|
||||||
new Ability(Abilities.STEAM_ENGINE, 8)
|
new Ability(Abilities.STEAM_ENGINE, 8)
|
||||||
@ -5740,10 +5698,8 @@ export function initAbilities() {
|
|||||||
.attr(UserFieldStatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC)
|
.attr(UserFieldStatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.HUNGER_SWITCH, 8)
|
new Ability(Abilities.HUNGER_SWITCH, 8)
|
||||||
//@ts-ignore
|
.attr(PostTurnFormChangeAbAttr, p => p.getFormKey() ? 0 : 1)
|
||||||
.attr(PostTurnFormChangeAbAttr, p => p.getFormKey ? 0 : 1) // TODO: fix ts-ignore
|
.attr(PostTurnFormChangeAbAttr, p => p.getFormKey() ? 1 : 0)
|
||||||
//@ts-ignore
|
|
||||||
.attr(PostTurnFormChangeAbAttr, p => p.getFormKey ? 1 : 0) // TODO: fix ts-ignore
|
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(NoTransformAbilityAbAttr)
|
.attr(NoTransformAbilityAbAttr)
|
||||||
|
@ -511,6 +511,39 @@ class WaterSportTag extends WeakenMoveTypeTag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arena Tag class for the secondary effect of {@link https://bulbapedia.bulbagarden.net/wiki/Plasma_Fists_(move) | Plasma Fists}.
|
||||||
|
* Converts Normal-type moves to Electric type for the rest of the turn.
|
||||||
|
*/
|
||||||
|
export class PlasmaFistsTag extends ArenaTag {
|
||||||
|
constructor() {
|
||||||
|
super(ArenaTagType.PLASMA_FISTS, 1, Moves.PLASMA_FISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Queues Plasma Fists' on-add message */
|
||||||
|
onAdd(arena: Arena): void {
|
||||||
|
arena.scene.queueMessage(i18next.t("arenaTag:plasmaFistsOnAdd"));
|
||||||
|
}
|
||||||
|
|
||||||
|
onRemove(arena: Arena): void { } // Removes default on-remove message
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts Normal-type moves to Electric type
|
||||||
|
* @param arena n/a
|
||||||
|
* @param args
|
||||||
|
* - `[0]` {@linkcode Utils.NumberHolder} A container with a move's {@linkcode Type}
|
||||||
|
* @returns `true` if the given move type changed; `false` otherwise.
|
||||||
|
*/
|
||||||
|
apply(arena: Arena, args: any[]): boolean {
|
||||||
|
const moveType = args[0];
|
||||||
|
if (moveType instanceof Utils.NumberHolder && moveType.value === Type.NORMAL) {
|
||||||
|
moveType.value = Type.ELECTRIC;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class to implement arena traps.
|
* Abstract class to implement arena traps.
|
||||||
*/
|
*/
|
||||||
@ -1010,6 +1043,8 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov
|
|||||||
return new MudSportTag(turnCount, sourceId);
|
return new MudSportTag(turnCount, sourceId);
|
||||||
case ArenaTagType.WATER_SPORT:
|
case ArenaTagType.WATER_SPORT:
|
||||||
return new WaterSportTag(turnCount, sourceId);
|
return new WaterSportTag(turnCount, sourceId);
|
||||||
|
case ArenaTagType.PLASMA_FISTS:
|
||||||
|
return new PlasmaFistsTag();
|
||||||
case ArenaTagType.SPIKES:
|
case ArenaTagType.SPIKES:
|
||||||
return new SpikesTag(sourceId, side);
|
return new SpikesTag(sourceId, side);
|
||||||
case ArenaTagType.TOXIC_SPIKES:
|
case ArenaTagType.TOXIC_SPIKES:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Type } from "./type";
|
import { Type } from "#app/data/type";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "#app/utils";
|
||||||
import { pokemonEvolutions, SpeciesFormEvolution } from "./pokemon-evolutions";
|
import { pokemonEvolutions, SpeciesFormEvolution } from "#app/data/balance/pokemon-evolutions";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { Biome } from "#enums/biome";
|
import { Biome } from "#enums/biome";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
@ -1,5 +1,5 @@
|
|||||||
import { allMoves } from "./move";
|
import { allMoves } from "#app/data/move";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "#app/utils";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ export const speciesEggMoves = {
|
|||||||
[Species.LEDYBA]: [ Moves.POLLEN_PUFF, Moves.THIEF, Moves.PARTING_SHOT, Moves.SPORE ],
|
[Species.LEDYBA]: [ Moves.POLLEN_PUFF, Moves.THIEF, Moves.PARTING_SHOT, Moves.SPORE ],
|
||||||
[Species.SPINARAK]: [ Moves.PARTING_SHOT, Moves.ATTACK_ORDER, Moves.GASTRO_ACID, Moves.STRENGTH_SAP ],
|
[Species.SPINARAK]: [ Moves.PARTING_SHOT, Moves.ATTACK_ORDER, Moves.GASTRO_ACID, Moves.STRENGTH_SAP ],
|
||||||
[Species.CHINCHOU]: [ Moves.THUNDERCLAP, Moves.BOUNCY_BUBBLE, Moves.THUNDER_CAGE, Moves.TAIL_GLOW ],
|
[Species.CHINCHOU]: [ Moves.THUNDERCLAP, Moves.BOUNCY_BUBBLE, Moves.THUNDER_CAGE, Moves.TAIL_GLOW ],
|
||||||
[Species.PICHU]: [ Moves.MOONBLAST, Moves.WAVE_CRASH, Moves.AIR_SLASH, Moves.AURA_WHEEL ],
|
[Species.PICHU]: [ Moves.MOONBLAST, Moves.TRIPLE_AXEL, Moves.FIERY_DANCE, Moves.AURA_WHEEL ],
|
||||||
[Species.CLEFFA]: [ Moves.CALM_MIND, Moves.EARTH_POWER, Moves.WISH, Moves.LIGHT_OF_RUIN ],
|
[Species.CLEFFA]: [ Moves.CALM_MIND, Moves.EARTH_POWER, Moves.WISH, Moves.LIGHT_OF_RUIN ],
|
||||||
[Species.IGGLYBUFF]: [ Moves.DRAIN_PUNCH, Moves.GRAV_APPLE, Moves.SOFT_BOILED, Moves.EXTREME_SPEED ],
|
[Species.IGGLYBUFF]: [ Moves.DRAIN_PUNCH, Moves.GRAV_APPLE, Moves.SOFT_BOILED, Moves.EXTREME_SPEED ],
|
||||||
[Species.TOGEPI]: [ Moves.SCORCHING_SANDS, Moves.ROOST, Moves.RELIC_SONG, Moves.FIERY_DANCE ],
|
[Species.TOGEPI]: [ Moves.SCORCHING_SANDS, Moves.ROOST, Moves.RELIC_SONG, Moves.FIERY_DANCE ],
|
||||||
@ -195,7 +195,7 @@ export const speciesEggMoves = {
|
|||||||
[Species.REGISTEEL]: [ Moves.BODY_PRESS, Moves.SIZZLY_SLIDE, Moves.RECOVER, Moves.GIGATON_HAMMER ],
|
[Species.REGISTEEL]: [ Moves.BODY_PRESS, Moves.SIZZLY_SLIDE, Moves.RECOVER, Moves.GIGATON_HAMMER ],
|
||||||
[Species.LATIAS]: [ Moves.CORE_ENFORCER, Moves.FUSION_FLARE, Moves.SPARKLY_SWIRL, Moves.MYSTICAL_POWER ],
|
[Species.LATIAS]: [ Moves.CORE_ENFORCER, Moves.FUSION_FLARE, Moves.SPARKLY_SWIRL, Moves.MYSTICAL_POWER ],
|
||||||
[Species.LATIOS]: [ Moves.CORE_ENFORCER, Moves.BLUE_FLARE, Moves.NASTY_PLOT, Moves.TACHYON_CUTTER ],
|
[Species.LATIOS]: [ Moves.CORE_ENFORCER, Moves.BLUE_FLARE, Moves.NASTY_PLOT, Moves.TACHYON_CUTTER ],
|
||||||
[Species.KYOGRE]: [ Moves.RECOVER, Moves.HURRICANE, Moves.FLIP_TURN, Moves.WILDBOLT_STORM ],
|
[Species.KYOGRE]: [ Moves.RECOVER, Moves.HURRICANE, Moves.FREEZY_FROST, Moves.WILDBOLT_STORM ],
|
||||||
[Species.GROUDON]: [ Moves.STONE_AXE, Moves.SOLAR_BLADE, Moves.MORNING_SUN, Moves.SACRED_FIRE ],
|
[Species.GROUDON]: [ Moves.STONE_AXE, Moves.SOLAR_BLADE, Moves.MORNING_SUN, Moves.SACRED_FIRE ],
|
||||||
[Species.RAYQUAZA]: [ Moves.V_CREATE, Moves.DRAGON_DARTS, Moves.CORE_ENFORCER, Moves.OBLIVION_WING ],
|
[Species.RAYQUAZA]: [ Moves.V_CREATE, Moves.DRAGON_DARTS, Moves.CORE_ENFORCER, Moves.OBLIVION_WING ],
|
||||||
[Species.JIRACHI]: [ Moves.TACHYON_CUTTER, Moves.TRIPLE_ARROWS, Moves.ROCK_SLIDE, Moves.SHELL_SMASH ],
|
[Species.JIRACHI]: [ Moves.TACHYON_CUTTER, Moves.TRIPLE_ARROWS, Moves.ROCK_SLIDE, Moves.SHELL_SMASH ],
|
574
src/data/balance/passives.ts
Normal file
574
src/data/balance/passives.ts
Normal file
@ -0,0 +1,574 @@
|
|||||||
|
import { Abilities } from "#app/enums/abilities";
|
||||||
|
import { Species } from "#app/enums/species";
|
||||||
|
|
||||||
|
export const starterPassiveAbilities = {
|
||||||
|
[Species.BULBASAUR]: Abilities.GRASSY_SURGE,
|
||||||
|
[Species.CHARMANDER]: Abilities.BEAST_BOOST,
|
||||||
|
[Species.SQUIRTLE]: Abilities.STURDY,
|
||||||
|
[Species.CATERPIE]: Abilities.MAGICIAN,
|
||||||
|
[Species.WEEDLE]: Abilities.TINTED_LENS,
|
||||||
|
[Species.PIDGEY]: Abilities.SHEER_FORCE,
|
||||||
|
[Species.RATTATA]: Abilities.STRONG_JAW,
|
||||||
|
[Species.SPEAROW]: Abilities.MOXIE,
|
||||||
|
[Species.EKANS]: Abilities.REGENERATOR,
|
||||||
|
[Species.SANDSHREW]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.NIDORAN_F]: Abilities.FLARE_BOOST,
|
||||||
|
[Species.NIDORAN_M]: Abilities.GUTS,
|
||||||
|
[Species.VULPIX]: Abilities.FUR_COAT,
|
||||||
|
[Species.ZUBAT]: Abilities.INTIMIDATE,
|
||||||
|
[Species.ODDISH]: Abilities.TRIAGE,
|
||||||
|
[Species.PARAS]: Abilities.TRIAGE,
|
||||||
|
[Species.VENONAT]: Abilities.SIMPLE,
|
||||||
|
[Species.DIGLETT]: Abilities.STURDY,
|
||||||
|
[Species.MEOWTH]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.PSYDUCK]: Abilities.SIMPLE,
|
||||||
|
[Species.MANKEY]: Abilities.IRON_FIST,
|
||||||
|
[Species.GROWLITHE]: Abilities.SPEED_BOOST,
|
||||||
|
[Species.POLIWAG]: Abilities.NO_GUARD,
|
||||||
|
[Species.ABRA]: Abilities.PSYCHIC_SURGE,
|
||||||
|
[Species.MACHOP]: Abilities.QUICK_FEET,
|
||||||
|
[Species.BELLSPROUT]: Abilities.FLOWER_GIFT,
|
||||||
|
[Species.TENTACOOL]: Abilities.TOXIC_CHAIN,
|
||||||
|
[Species.GEODUDE]: Abilities.DRY_SKIN,
|
||||||
|
[Species.PONYTA]: Abilities.MAGIC_GUARD,
|
||||||
|
[Species.SLOWPOKE]: Abilities.UNAWARE,
|
||||||
|
[Species.MAGNEMITE]: Abilities.LEVITATE,
|
||||||
|
[Species.FARFETCHD]: Abilities.SNIPER,
|
||||||
|
[Species.DODUO]: Abilities.PARENTAL_BOND,
|
||||||
|
[Species.SEEL]: Abilities.WATER_BUBBLE,
|
||||||
|
[Species.GRIMER]: Abilities.WATER_ABSORB,
|
||||||
|
[Species.SHELLDER]: Abilities.ICE_SCALES,
|
||||||
|
[Species.GASTLY]: Abilities.SHADOW_SHIELD,
|
||||||
|
[Species.ONIX]: Abilities.ROCKY_PAYLOAD,
|
||||||
|
[Species.DROWZEE]: Abilities.MAGICIAN,
|
||||||
|
[Species.KRABBY]: Abilities.THERMAL_EXCHANGE,
|
||||||
|
[Species.VOLTORB]: Abilities.TRANSISTOR,
|
||||||
|
[Species.EXEGGCUTE]: Abilities.RIPEN,
|
||||||
|
[Species.CUBONE]: Abilities.PARENTAL_BOND,
|
||||||
|
[Species.LICKITUNG]: Abilities.CHEEK_POUCH,
|
||||||
|
[Species.KOFFING]: Abilities.PARENTAL_BOND,
|
||||||
|
[Species.RHYHORN]: Abilities.FILTER,
|
||||||
|
[Species.TANGELA]: Abilities.SEED_SOWER,
|
||||||
|
[Species.KANGASKHAN]: Abilities.GUTS,
|
||||||
|
[Species.HORSEA]: Abilities.DRAGONS_MAW,
|
||||||
|
[Species.GOLDEEN]: Abilities.MULTISCALE,
|
||||||
|
[Species.STARYU]: Abilities.REGENERATOR,
|
||||||
|
[Species.SCYTHER]: Abilities.TINTED_LENS,
|
||||||
|
[Species.PINSIR]: Abilities.TINTED_LENS,
|
||||||
|
[Species.TAUROS]: Abilities.STAMINA,
|
||||||
|
[Species.MAGIKARP]: Abilities.MULTISCALE,
|
||||||
|
[Species.LAPRAS]: Abilities.LIGHTNING_ROD,
|
||||||
|
[Species.DITTO]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.EEVEE]: Abilities.PICKUP,
|
||||||
|
[Species.PORYGON]: Abilities.PROTEAN,
|
||||||
|
[Species.OMANYTE]: Abilities.STURDY,
|
||||||
|
[Species.KABUTO]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.AERODACTYL]: Abilities.ORICHALCUM_PULSE,
|
||||||
|
[Species.ARTICUNO]: Abilities.SNOW_WARNING,
|
||||||
|
[Species.ZAPDOS]: Abilities.DRIZZLE,
|
||||||
|
[Species.MOLTRES]: Abilities.DROUGHT,
|
||||||
|
[Species.DRATINI]: Abilities.AERILATE,
|
||||||
|
[Species.MEWTWO]: Abilities.NEUROFORCE,
|
||||||
|
[Species.MEW]: Abilities.PROTEAN,
|
||||||
|
[Species.CHIKORITA]: Abilities.THICK_FAT,
|
||||||
|
[Species.CYNDAQUIL]: Abilities.DROUGHT,
|
||||||
|
[Species.TOTODILE]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.SENTRET]: Abilities.PICKUP,
|
||||||
|
[Species.HOOTHOOT]: Abilities.AERILATE,
|
||||||
|
[Species.LEDYBA]: Abilities.PRANKSTER,
|
||||||
|
[Species.SPINARAK]: Abilities.PRANKSTER,
|
||||||
|
[Species.CHINCHOU]: Abilities.WATER_BUBBLE,
|
||||||
|
[Species.PICHU]: Abilities.ELECTRIC_SURGE,
|
||||||
|
[Species.CLEFFA]: Abilities.ANALYTIC,
|
||||||
|
[Species.IGGLYBUFF]: Abilities.HUGE_POWER,
|
||||||
|
[Species.TOGEPI]: Abilities.PIXILATE,
|
||||||
|
[Species.NATU]: Abilities.TINTED_LENS,
|
||||||
|
[Species.MAREEP]: Abilities.ELECTROMORPHOSIS,
|
||||||
|
[Species.HOPPIP]: Abilities.FLUFFY,
|
||||||
|
[Species.AIPOM]: Abilities.SCRAPPY,
|
||||||
|
[Species.SUNKERN]: Abilities.DROUGHT,
|
||||||
|
[Species.YANMA]: Abilities.SHEER_FORCE,
|
||||||
|
[Species.WOOPER]: Abilities.COMATOSE,
|
||||||
|
[Species.MURKROW]: Abilities.DARK_AURA,
|
||||||
|
[Species.MISDREAVUS]: Abilities.BEADS_OF_RUIN,
|
||||||
|
[Species.UNOWN]: Abilities.PICKUP,
|
||||||
|
[Species.GIRAFARIG]: Abilities.PARENTAL_BOND,
|
||||||
|
[Species.PINECO]: Abilities.IRON_BARBS,
|
||||||
|
[Species.DUNSPARCE]: Abilities.UNAWARE,
|
||||||
|
[Species.GLIGAR]: Abilities.TOXIC_BOOST,
|
||||||
|
[Species.SNUBBULL]: Abilities.PIXILATE,
|
||||||
|
[Species.QWILFISH]: Abilities.TOXIC_DEBRIS,
|
||||||
|
[Species.SHUCKLE]: Abilities.HARVEST,
|
||||||
|
[Species.HERACROSS]: Abilities.TECHNICIAN,
|
||||||
|
[Species.SNEASEL]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.TEDDIURSA]: Abilities.THICK_FAT,
|
||||||
|
[Species.SLUGMA]: Abilities.DESOLATE_LAND,
|
||||||
|
[Species.SWINUB]: Abilities.SLUSH_RUSH,
|
||||||
|
[Species.CORSOLA]: Abilities.STORM_DRAIN,
|
||||||
|
[Species.REMORAID]: Abilities.SIMPLE,
|
||||||
|
[Species.DELIBIRD]: Abilities.HUGE_POWER,
|
||||||
|
[Species.SKARMORY]: Abilities.LIGHTNING_ROD,
|
||||||
|
[Species.HOUNDOUR]: Abilities.DROUGHT,
|
||||||
|
[Species.PHANPY]: Abilities.SPEED_BOOST,
|
||||||
|
[Species.STANTLER]: Abilities.SPEED_BOOST,
|
||||||
|
[Species.SMEARGLE]: Abilities.PRANKSTER,
|
||||||
|
[Species.TYROGUE]: Abilities.MOXIE,
|
||||||
|
[Species.SMOOCHUM]: Abilities.PSYCHIC_SURGE,
|
||||||
|
[Species.ELEKID]: Abilities.SHEER_FORCE,
|
||||||
|
[Species.MAGBY]: Abilities.CONTRARY,
|
||||||
|
[Species.MILTANK]: Abilities.STAMINA,
|
||||||
|
[Species.RAIKOU]: Abilities.TRANSISTOR,
|
||||||
|
[Species.ENTEI]: Abilities.MOXIE,
|
||||||
|
[Species.SUICUNE]: Abilities.UNAWARE,
|
||||||
|
[Species.LARVITAR]: Abilities.SAND_RUSH,
|
||||||
|
[Species.LUGIA]: Abilities.DELTA_STREAM,
|
||||||
|
[Species.HO_OH]: Abilities.MAGIC_GUARD,
|
||||||
|
[Species.CELEBI]: Abilities.PSYCHIC_SURGE,
|
||||||
|
[Species.TREECKO]: Abilities.TINTED_LENS,
|
||||||
|
[Species.TORCHIC]: Abilities.RECKLESS,
|
||||||
|
[Species.MUDKIP]: Abilities.DRIZZLE,
|
||||||
|
[Species.POOCHYENA]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.ZIGZAGOON]: Abilities.RUN_AWAY,
|
||||||
|
[Species.WURMPLE]: Abilities.SIMPLE,
|
||||||
|
[Species.LOTAD]: Abilities.DRIZZLE,
|
||||||
|
[Species.SEEDOT]: Abilities.SHARPNESS,
|
||||||
|
[Species.TAILLOW]: Abilities.AERILATE,
|
||||||
|
[Species.WINGULL]: Abilities.SWIFT_SWIM,
|
||||||
|
[Species.RALTS]: Abilities.PSYCHIC_SURGE,
|
||||||
|
[Species.SURSKIT]: Abilities.WATER_BUBBLE,
|
||||||
|
[Species.SHROOMISH]: Abilities.GUTS,
|
||||||
|
[Species.SLAKOTH]: Abilities.GUTS,
|
||||||
|
[Species.NINCADA]: Abilities.MAGIC_GUARD,
|
||||||
|
[Species.WHISMUR]: Abilities.PUNK_ROCK,
|
||||||
|
[Species.MAKUHITA]: Abilities.STAMINA,
|
||||||
|
[Species.AZURILL]: Abilities.MISTY_SURGE,
|
||||||
|
[Species.NOSEPASS]: Abilities.LEVITATE,
|
||||||
|
[Species.SKITTY]: Abilities.SCRAPPY,
|
||||||
|
[Species.SABLEYE]: Abilities.UNNERVE,
|
||||||
|
[Species.MAWILE]: Abilities.UNNERVE,
|
||||||
|
[Species.ARON]: Abilities.EARTH_EATER,
|
||||||
|
[Species.MEDITITE]: Abilities.MINDS_EYE,
|
||||||
|
[Species.ELECTRIKE]: Abilities.ELECTRIC_SURGE,
|
||||||
|
[Species.PLUSLE]: Abilities.POWER_SPOT,
|
||||||
|
[Species.MINUN]: Abilities.POWER_SPOT,
|
||||||
|
[Species.VOLBEAT]: Abilities.HONEY_GATHER,
|
||||||
|
[Species.ILLUMISE]: Abilities.HONEY_GATHER,
|
||||||
|
[Species.GULPIN]: Abilities.EARTH_EATER,
|
||||||
|
[Species.CARVANHA]: Abilities.SHEER_FORCE,
|
||||||
|
[Species.WAILMER]: Abilities.LEVITATE,
|
||||||
|
[Species.NUMEL]: Abilities.FUR_COAT,
|
||||||
|
[Species.TORKOAL]: Abilities.ANALYTIC,
|
||||||
|
[Species.SPOINK]: Abilities.PSYCHIC_SURGE,
|
||||||
|
[Species.SPINDA]: Abilities.SIMPLE,
|
||||||
|
[Species.TRAPINCH]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.CACNEA]: Abilities.SAND_RUSH,
|
||||||
|
[Species.SWABLU]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.ZANGOOSE]: Abilities.POISON_HEAL,
|
||||||
|
[Species.SEVIPER]: Abilities.MULTISCALE,
|
||||||
|
[Species.LUNATONE]: Abilities.SHADOW_SHIELD,
|
||||||
|
[Species.SOLROCK]: Abilities.DROUGHT,
|
||||||
|
[Species.BARBOACH]: Abilities.SIMPLE,
|
||||||
|
[Species.CORPHISH]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.BALTOY]: Abilities.WELL_BAKED_BODY,
|
||||||
|
[Species.LILEEP]: Abilities.SEED_SOWER,
|
||||||
|
[Species.ANORITH]: Abilities.WATER_ABSORB,
|
||||||
|
[Species.FEEBAS]: Abilities.MAGIC_GUARD,
|
||||||
|
[Species.CASTFORM]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.KECLEON]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.SHUPPET]: Abilities.SHADOW_SHIELD,
|
||||||
|
[Species.DUSKULL]: Abilities.UNNERVE,
|
||||||
|
[Species.TROPIUS]: Abilities.RIPEN,
|
||||||
|
[Species.ABSOL]: Abilities.SHARPNESS,
|
||||||
|
[Species.WYNAUT]: Abilities.STURDY,
|
||||||
|
[Species.SNORUNT]: Abilities.SNOW_WARNING,
|
||||||
|
[Species.SPHEAL]: Abilities.UNAWARE,
|
||||||
|
[Species.CLAMPERL]: Abilities.DRIZZLE,
|
||||||
|
[Species.RELICANTH]: Abilities.PRIMORDIAL_SEA,
|
||||||
|
[Species.LUVDISC]: Abilities.MULTISCALE,
|
||||||
|
[Species.BAGON]: Abilities.DRAGONS_MAW,
|
||||||
|
[Species.BELDUM]: Abilities.LEVITATE,
|
||||||
|
[Species.REGIROCK]: Abilities.SAND_STREAM,
|
||||||
|
[Species.REGICE]: Abilities.SNOW_WARNING,
|
||||||
|
[Species.REGISTEEL]: Abilities.FILTER,
|
||||||
|
[Species.LATIAS]: Abilities.PRISM_ARMOR,
|
||||||
|
[Species.LATIOS]: Abilities.TINTED_LENS,
|
||||||
|
[Species.KYOGRE]: Abilities.MOLD_BREAKER,
|
||||||
|
[Species.GROUDON]: Abilities.TURBOBLAZE,
|
||||||
|
[Species.RAYQUAZA]: Abilities.UNNERVE,
|
||||||
|
[Species.JIRACHI]: Abilities.COMATOSE,
|
||||||
|
[Species.DEOXYS]: Abilities.PROTEAN,
|
||||||
|
[Species.TURTWIG]: Abilities.THICK_FAT,
|
||||||
|
[Species.CHIMCHAR]: Abilities.BEAST_BOOST,
|
||||||
|
[Species.PIPLUP]: Abilities.DRIZZLE,
|
||||||
|
[Species.STARLY]: Abilities.ROCK_HEAD,
|
||||||
|
[Species.BIDOOF]: Abilities.SAP_SIPPER,
|
||||||
|
[Species.KRICKETOT]: Abilities.SHARPNESS,
|
||||||
|
[Species.SHINX]: Abilities.SPEED_BOOST,
|
||||||
|
[Species.BUDEW]: Abilities.GRASSY_SURGE,
|
||||||
|
[Species.CRANIDOS]: Abilities.ROCK_HEAD,
|
||||||
|
[Species.SHIELDON]: Abilities.EARTH_EATER,
|
||||||
|
[Species.BURMY]: Abilities.STURDY,
|
||||||
|
[Species.COMBEE]: Abilities.INTIMIDATE,
|
||||||
|
[Species.PACHIRISU]: Abilities.HONEY_GATHER,
|
||||||
|
[Species.BUIZEL]: Abilities.MOXIE,
|
||||||
|
[Species.CHERUBI]: Abilities.ORICHALCUM_PULSE,
|
||||||
|
[Species.SHELLOS]: Abilities.REGENERATOR,
|
||||||
|
[Species.DRIFLOON]: Abilities.MAGIC_GUARD,
|
||||||
|
[Species.BUNEARY]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.GLAMEOW]: Abilities.INTIMIDATE,
|
||||||
|
[Species.CHINGLING]: Abilities.PUNK_ROCK,
|
||||||
|
[Species.STUNKY]: Abilities.NEUTRALIZING_GAS,
|
||||||
|
[Species.BRONZOR]: Abilities.BULLETPROOF,
|
||||||
|
[Species.BONSLY]: Abilities.SAP_SIPPER,
|
||||||
|
[Species.MIME_JR]: Abilities.OPPORTUNIST,
|
||||||
|
[Species.HAPPINY]: Abilities.FUR_COAT,
|
||||||
|
[Species.CHATOT]: Abilities.PUNK_ROCK,
|
||||||
|
[Species.SPIRITOMB]: Abilities.VESSEL_OF_RUIN,
|
||||||
|
[Species.GIBLE]: Abilities.SAND_STREAM,
|
||||||
|
[Species.MUNCHLAX]: Abilities.RIPEN,
|
||||||
|
[Species.RIOLU]: Abilities.MINDS_EYE,
|
||||||
|
[Species.HIPPOPOTAS]: Abilities.UNAWARE,
|
||||||
|
[Species.SKORUPI]: Abilities.SUPER_LUCK,
|
||||||
|
[Species.CROAGUNK]: Abilities.MOXIE,
|
||||||
|
[Species.CARNIVINE]: Abilities.ARENA_TRAP,
|
||||||
|
[Species.FINNEON]: Abilities.WATER_BUBBLE,
|
||||||
|
[Species.MANTYKE]: Abilities.UNAWARE,
|
||||||
|
[Species.SNOVER]: Abilities.THICK_FAT,
|
||||||
|
[Species.ROTOM]: Abilities.HADRON_ENGINE,
|
||||||
|
[Species.UXIE]: Abilities.UNAWARE,
|
||||||
|
[Species.MESPRIT]: Abilities.MOODY,
|
||||||
|
[Species.AZELF]: Abilities.NEUROFORCE,
|
||||||
|
[Species.DIALGA]: Abilities.LEVITATE,
|
||||||
|
[Species.PALKIA]: Abilities.SPEED_BOOST,
|
||||||
|
[Species.HEATRAN]: Abilities.EARTH_EATER,
|
||||||
|
[Species.REGIGIGAS]: Abilities.SCRAPPY,
|
||||||
|
[Species.GIRATINA]: Abilities.SHADOW_SHIELD,
|
||||||
|
[Species.CRESSELIA]: Abilities.SHADOW_SHIELD,
|
||||||
|
[Species.PHIONE]: Abilities.SIMPLE,
|
||||||
|
[Species.MANAPHY]: Abilities.PRIMORDIAL_SEA,
|
||||||
|
[Species.DARKRAI]: Abilities.UNNERVE,
|
||||||
|
[Species.SHAYMIN]: Abilities.WIND_RIDER,
|
||||||
|
[Species.ARCEUS]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.VICTINI]: Abilities.SHEER_FORCE,
|
||||||
|
[Species.SNIVY]: Abilities.MULTISCALE,
|
||||||
|
[Species.TEPIG]: Abilities.ROCK_HEAD,
|
||||||
|
[Species.OSHAWOTT]: Abilities.INTREPID_SWORD,
|
||||||
|
[Species.PATRAT]: Abilities.NO_GUARD,
|
||||||
|
[Species.LILLIPUP]: Abilities.FUR_COAT,
|
||||||
|
[Species.PURRLOIN]: Abilities.PICKUP,
|
||||||
|
[Species.PANSAGE]: Abilities.WELL_BAKED_BODY,
|
||||||
|
[Species.PANSEAR]: Abilities.WATER_ABSORB,
|
||||||
|
[Species.PANPOUR]: Abilities.SAP_SIPPER,
|
||||||
|
[Species.MUNNA]: Abilities.NEUTRALIZING_GAS,
|
||||||
|
[Species.PIDOVE]: Abilities.SNIPER,
|
||||||
|
[Species.BLITZLE]: Abilities.ELECTRIC_SURGE,
|
||||||
|
[Species.ROGGENROLA]: Abilities.SOLID_ROCK,
|
||||||
|
[Species.WOOBAT]: Abilities.OPPORTUNIST,
|
||||||
|
[Species.DRILBUR]: Abilities.SAND_STREAM,
|
||||||
|
[Species.AUDINO]: Abilities.FRIEND_GUARD,
|
||||||
|
[Species.TIMBURR]: Abilities.ROCKY_PAYLOAD,
|
||||||
|
[Species.TYMPOLE]: Abilities.POISON_HEAL,
|
||||||
|
[Species.THROH]: Abilities.STAMINA,
|
||||||
|
[Species.SAWK]: Abilities.SCRAPPY,
|
||||||
|
[Species.SEWADDLE]: Abilities.SHARPNESS,
|
||||||
|
[Species.VENIPEDE]: Abilities.STAMINA,
|
||||||
|
[Species.COTTONEE]: Abilities.FLUFFY,
|
||||||
|
[Species.PETILIL]: Abilities.SIMPLE,
|
||||||
|
[Species.BASCULIN]: Abilities.SUPREME_OVERLORD,
|
||||||
|
[Species.SANDILE]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.DARUMAKA]: Abilities.GORILLA_TACTICS,
|
||||||
|
[Species.MARACTUS]: Abilities.WELL_BAKED_BODY,
|
||||||
|
[Species.DWEBBLE]: Abilities.ROCKY_PAYLOAD,
|
||||||
|
[Species.SCRAGGY]: Abilities.PROTEAN,
|
||||||
|
[Species.SIGILYPH]: Abilities.FLARE_BOOST,
|
||||||
|
[Species.YAMASK]: Abilities.PURIFYING_SALT,
|
||||||
|
[Species.TIRTOUGA]: Abilities.WATER_ABSORB,
|
||||||
|
[Species.ARCHEN]: Abilities.MULTISCALE,
|
||||||
|
[Species.TRUBBISH]: Abilities.NEUTRALIZING_GAS,
|
||||||
|
[Species.ZORUA]: Abilities.DARK_AURA,
|
||||||
|
[Species.MINCCINO]: Abilities.FUR_COAT,
|
||||||
|
[Species.GOTHITA]: Abilities.UNNERVE,
|
||||||
|
[Species.SOLOSIS]: Abilities.PSYCHIC_SURGE,
|
||||||
|
[Species.DUCKLETT]: Abilities.DRIZZLE,
|
||||||
|
[Species.VANILLITE]: Abilities.SLUSH_RUSH,
|
||||||
|
[Species.DEERLING]: Abilities.FUR_COAT,
|
||||||
|
[Species.EMOLGA]: Abilities.TRANSISTOR,
|
||||||
|
[Species.KARRABLAST]: Abilities.QUICK_DRAW,
|
||||||
|
[Species.FOONGUS]: Abilities.THICK_FAT,
|
||||||
|
[Species.FRILLISH]: Abilities.POISON_HEAL,
|
||||||
|
[Species.ALOMOMOLA]: Abilities.MULTISCALE,
|
||||||
|
[Species.JOLTIK]: Abilities.TRANSISTOR,
|
||||||
|
[Species.FERROSEED]: Abilities.ROUGH_SKIN,
|
||||||
|
[Species.KLINK]: Abilities.STEELY_SPIRIT,
|
||||||
|
[Species.TYNAMO]: Abilities.POISON_HEAL,
|
||||||
|
[Species.ELGYEM]: Abilities.PRISM_ARMOR,
|
||||||
|
[Species.LITWICK]: Abilities.SOUL_HEART,
|
||||||
|
[Species.AXEW]: Abilities.DRAGONS_MAW,
|
||||||
|
[Species.CUBCHOO]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.CRYOGONAL]: Abilities.SNOW_WARNING,
|
||||||
|
[Species.SHELMET]: Abilities.PROTEAN,
|
||||||
|
[Species.STUNFISK]: Abilities.STORM_DRAIN,
|
||||||
|
[Species.MIENFOO]: Abilities.NO_GUARD,
|
||||||
|
[Species.DRUDDIGON]: Abilities.INTIMIDATE,
|
||||||
|
[Species.GOLETT]: Abilities.SHADOW_SHIELD,
|
||||||
|
[Species.PAWNIARD]: Abilities.SWORD_OF_RUIN,
|
||||||
|
[Species.BOUFFALANT]: Abilities.ROCK_HEAD,
|
||||||
|
[Species.RUFFLET]: Abilities.SPEED_BOOST,
|
||||||
|
[Species.VULLABY]: Abilities.THICK_FAT,
|
||||||
|
[Species.HEATMOR]: Abilities.CONTRARY,
|
||||||
|
[Species.DURANT]: Abilities.COMPOUND_EYES,
|
||||||
|
[Species.DEINO]: Abilities.PARENTAL_BOND,
|
||||||
|
[Species.LARVESTA]: Abilities.DROUGHT,
|
||||||
|
[Species.COBALION]: Abilities.INTREPID_SWORD,
|
||||||
|
[Species.TERRAKION]: Abilities.ROCKY_PAYLOAD,
|
||||||
|
[Species.VIRIZION]: Abilities.SHARPNESS,
|
||||||
|
[Species.TORNADUS]: Abilities.DRIZZLE,
|
||||||
|
[Species.THUNDURUS]: Abilities.DRIZZLE,
|
||||||
|
[Species.RESHIRAM]: Abilities.ORICHALCUM_PULSE,
|
||||||
|
[Species.ZEKROM]: Abilities.HADRON_ENGINE,
|
||||||
|
[Species.LANDORUS]: Abilities.STORM_DRAIN,
|
||||||
|
[Species.KYUREM]: Abilities.SNOW_WARNING,
|
||||||
|
[Species.KELDEO]: Abilities.GRIM_NEIGH,
|
||||||
|
[Species.MELOETTA]: Abilities.MINDS_EYE,
|
||||||
|
[Species.GENESECT]: Abilities.PROTEAN,
|
||||||
|
[Species.CHESPIN]: Abilities.DAUNTLESS_SHIELD,
|
||||||
|
[Species.FENNEKIN]: Abilities.PSYCHIC_SURGE,
|
||||||
|
[Species.FROAKIE]: Abilities.STAKEOUT,
|
||||||
|
[Species.BUNNELBY]: Abilities.GUTS,
|
||||||
|
[Species.FLETCHLING]: Abilities.MAGIC_GUARD,
|
||||||
|
[Species.SCATTERBUG]: Abilities.PRANKSTER,
|
||||||
|
[Species.LITLEO]: Abilities.BEAST_BOOST,
|
||||||
|
[Species.FLABEBE]: Abilities.GRASSY_SURGE,
|
||||||
|
[Species.SKIDDO]: Abilities.SEED_SOWER,
|
||||||
|
[Species.PANCHAM]: Abilities.FUR_COAT,
|
||||||
|
[Species.FURFROU]: Abilities.FLUFFY,
|
||||||
|
[Species.ESPURR]: Abilities.FUR_COAT,
|
||||||
|
[Species.HONEDGE]: Abilities.SHARPNESS,
|
||||||
|
[Species.SPRITZEE]: Abilities.FUR_COAT,
|
||||||
|
[Species.SWIRLIX]: Abilities.WELL_BAKED_BODY,
|
||||||
|
[Species.INKAY]: Abilities.UNNERVE,
|
||||||
|
[Species.BINACLE]: Abilities.SAP_SIPPER,
|
||||||
|
[Species.SKRELP]: Abilities.DRAGONS_MAW,
|
||||||
|
[Species.CLAUNCHER]: Abilities.SWIFT_SWIM,
|
||||||
|
[Species.HELIOPTILE]: Abilities.PROTEAN,
|
||||||
|
[Species.TYRUNT]: Abilities.RECKLESS,
|
||||||
|
[Species.AMAURA]: Abilities.ICE_SCALES,
|
||||||
|
[Species.HAWLUCHA]: Abilities.MOXIE,
|
||||||
|
[Species.DEDENNE]: Abilities.PIXILATE,
|
||||||
|
[Species.CARBINK]: Abilities.SOLID_ROCK,
|
||||||
|
[Species.GOOMY]: Abilities.REGENERATOR,
|
||||||
|
[Species.KLEFKI]: Abilities.LEVITATE,
|
||||||
|
[Species.PHANTUMP]: Abilities.SHADOW_TAG,
|
||||||
|
[Species.PUMPKABOO]: Abilities.WELL_BAKED_BODY,
|
||||||
|
[Species.BERGMITE]: Abilities.ICE_SCALES,
|
||||||
|
[Species.NOIBAT]: Abilities.PUNK_ROCK,
|
||||||
|
[Species.XERNEAS]: Abilities.HARVEST,
|
||||||
|
[Species.YVELTAL]: Abilities.SOUL_HEART,
|
||||||
|
[Species.ZYGARDE]: Abilities.HUGE_POWER,
|
||||||
|
[Species.DIANCIE]: Abilities.LEVITATE,
|
||||||
|
[Species.HOOPA]: Abilities.OPPORTUNIST,
|
||||||
|
[Species.VOLCANION]: Abilities.FILTER,
|
||||||
|
[Species.ROWLET]: Abilities.SNIPER,
|
||||||
|
[Species.LITTEN]: Abilities.OPPORTUNIST,
|
||||||
|
[Species.POPPLIO]: Abilities.PUNK_ROCK,
|
||||||
|
[Species.PIKIPEK]: Abilities.TECHNICIAN,
|
||||||
|
[Species.YUNGOOS]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.GRUBBIN]: Abilities.SPEED_BOOST,
|
||||||
|
[Species.CRABRAWLER]: Abilities.WATER_BUBBLE,
|
||||||
|
[Species.ORICORIO]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.CUTIEFLY]: Abilities.TINTED_LENS,
|
||||||
|
[Species.ROCKRUFF]: Abilities.ROCKY_PAYLOAD,
|
||||||
|
[Species.WISHIWASHI]: Abilities.REGENERATOR,
|
||||||
|
[Species.MAREANIE]: Abilities.TOXIC_DEBRIS,
|
||||||
|
[Species.MUDBRAY]: Abilities.CUD_CHEW,
|
||||||
|
[Species.DEWPIDER]: Abilities.TINTED_LENS,
|
||||||
|
[Species.FOMANTIS]: Abilities.SHARPNESS,
|
||||||
|
[Species.MORELULL]: Abilities.TRIAGE,
|
||||||
|
[Species.SALANDIT]: Abilities.DRAGONS_MAW,
|
||||||
|
[Species.STUFFUL]: Abilities.SCRAPPY,
|
||||||
|
[Species.BOUNSWEET]: Abilities.MOXIE,
|
||||||
|
[Species.COMFEY]: Abilities.FRIEND_GUARD,
|
||||||
|
[Species.ORANGURU]: Abilities.POWER_SPOT,
|
||||||
|
[Species.PASSIMIAN]: Abilities.LIBERO,
|
||||||
|
[Species.WIMPOD]: Abilities.REGENERATOR,
|
||||||
|
[Species.SANDYGAST]: Abilities.SAND_SPIT,
|
||||||
|
[Species.PYUKUMUKU]: Abilities.PURIFYING_SALT,
|
||||||
|
[Species.TYPE_NULL]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.MINIOR]: Abilities.STURDY,
|
||||||
|
[Species.KOMALA]: Abilities.GUTS,
|
||||||
|
[Species.TURTONATOR]: Abilities.DAUNTLESS_SHIELD,
|
||||||
|
[Species.TOGEDEMARU]: Abilities.ROUGH_SKIN,
|
||||||
|
[Species.MIMIKYU]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.BRUXISH]: Abilities.MULTISCALE,
|
||||||
|
[Species.DRAMPA]: Abilities.THICK_FAT,
|
||||||
|
[Species.DHELMISE]: Abilities.WATER_BUBBLE,
|
||||||
|
[Species.JANGMO_O]: Abilities.DAUNTLESS_SHIELD,
|
||||||
|
[Species.TAPU_KOKO]: Abilities.TRANSISTOR,
|
||||||
|
[Species.TAPU_LELE]: Abilities.SHEER_FORCE,
|
||||||
|
[Species.TAPU_BULU]: Abilities.TRIAGE,
|
||||||
|
[Species.TAPU_FINI]: Abilities.FAIRY_AURA,
|
||||||
|
[Species.COSMOG]: Abilities.BEAST_BOOST,
|
||||||
|
[Species.NIHILEGO]: Abilities.LEVITATE,
|
||||||
|
[Species.BUZZWOLE]: Abilities.MOXIE,
|
||||||
|
[Species.PHEROMOSA]: Abilities.TINTED_LENS,
|
||||||
|
[Species.XURKITREE]: Abilities.TRANSISTOR,
|
||||||
|
[Species.CELESTEELA]: Abilities.HEATPROOF,
|
||||||
|
[Species.KARTANA]: Abilities.SHARPNESS,
|
||||||
|
[Species.GUZZLORD]: Abilities.POISON_HEAL,
|
||||||
|
[Species.NECROZMA]: Abilities.BEAST_BOOST,
|
||||||
|
[Species.MAGEARNA]: Abilities.STEELY_SPIRIT,
|
||||||
|
[Species.MARSHADOW]: Abilities.IRON_FIST,
|
||||||
|
[Species.POIPOLE]: Abilities.SHEER_FORCE,
|
||||||
|
[Species.STAKATAKA]: Abilities.SOLID_ROCK,
|
||||||
|
[Species.BLACEPHALON]: Abilities.MAGIC_GUARD,
|
||||||
|
[Species.ZERAORA]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.MELTAN]: Abilities.STEELY_SPIRIT,
|
||||||
|
[Species.GROOKEY]: Abilities.GRASS_PELT,
|
||||||
|
[Species.SCORBUNNY]: Abilities.NO_GUARD,
|
||||||
|
[Species.SOBBLE]: Abilities.SUPER_LUCK,
|
||||||
|
[Species.SKWOVET]: Abilities.HARVEST,
|
||||||
|
[Species.ROOKIDEE]: Abilities.IRON_BARBS,
|
||||||
|
[Species.BLIPBUG]: Abilities.PSYCHIC_SURGE,
|
||||||
|
[Species.NICKIT]: Abilities.MAGICIAN,
|
||||||
|
[Species.GOSSIFLEUR]: Abilities.GRASSY_SURGE,
|
||||||
|
[Species.WOOLOO]: Abilities.SIMPLE,
|
||||||
|
[Species.CHEWTLE]: Abilities.ROCKY_PAYLOAD,
|
||||||
|
[Species.YAMPER]: Abilities.SHEER_FORCE,
|
||||||
|
[Species.ROLYCOLY]: Abilities.SOLID_ROCK,
|
||||||
|
[Species.APPLIN]: Abilities.DRAGONS_MAW,
|
||||||
|
[Species.SILICOBRA]: Abilities.SAND_RUSH,
|
||||||
|
[Species.CRAMORANT]: Abilities.LIGHTNING_ROD,
|
||||||
|
[Species.ARROKUDA]: Abilities.INTIMIDATE,
|
||||||
|
[Species.TOXEL]: Abilities.ELECTRIC_SURGE,
|
||||||
|
[Species.SIZZLIPEDE]: Abilities.SPEED_BOOST,
|
||||||
|
[Species.CLOBBOPUS]: Abilities.WATER_BUBBLE,
|
||||||
|
[Species.SINISTEA]: Abilities.SHADOW_SHIELD,
|
||||||
|
[Species.HATENNA]: Abilities.FAIRY_AURA,
|
||||||
|
[Species.IMPIDIMP]: Abilities.FUR_COAT,
|
||||||
|
[Species.MILCERY]: Abilities.REGENERATOR,
|
||||||
|
[Species.FALINKS]: Abilities.PARENTAL_BOND,
|
||||||
|
[Species.PINCURCHIN]: Abilities.ELECTROMORPHOSIS,
|
||||||
|
[Species.SNOM]: Abilities.SNOW_WARNING,
|
||||||
|
[Species.STONJOURNER]: Abilities.STURDY,
|
||||||
|
[Species.EISCUE]: Abilities.ICE_SCALES,
|
||||||
|
[Species.INDEEDEE]: Abilities.FRIEND_GUARD,
|
||||||
|
[Species.MORPEKO]: Abilities.MOODY,
|
||||||
|
[Species.CUFANT]: Abilities.EARTH_EATER,
|
||||||
|
[Species.DRACOZOLT]: Abilities.NO_GUARD,
|
||||||
|
[Species.ARCTOZOLT]: Abilities.TRANSISTOR,
|
||||||
|
[Species.DRACOVISH]: Abilities.SWIFT_SWIM,
|
||||||
|
[Species.ARCTOVISH]: Abilities.STRONG_JAW,
|
||||||
|
[Species.DURALUDON]: Abilities.STEELWORKER,
|
||||||
|
[Species.DREEPY]: Abilities.PARENTAL_BOND,
|
||||||
|
[Species.ZACIAN]: Abilities.UNNERVE,
|
||||||
|
[Species.ZAMAZENTA]: Abilities.UNNERVE,
|
||||||
|
[Species.ETERNATUS]: Abilities.NEUTRALIZING_GAS,
|
||||||
|
[Species.KUBFU]: Abilities.IRON_FIST,
|
||||||
|
[Species.ZARUDE]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.REGIELEKI]: Abilities.ELECTRIC_SURGE,
|
||||||
|
[Species.REGIDRAGO]: Abilities.MULTISCALE,
|
||||||
|
[Species.GLASTRIER]: Abilities.FILTER,
|
||||||
|
[Species.SPECTRIER]: Abilities.SHADOW_SHIELD,
|
||||||
|
[Species.CALYREX]: Abilities.HARVEST,
|
||||||
|
[Species.ENAMORUS]: Abilities.FAIRY_AURA,
|
||||||
|
[Species.SPRIGATITO]: Abilities.MAGICIAN,
|
||||||
|
[Species.FUECOCO]: Abilities.PUNK_ROCK,
|
||||||
|
[Species.QUAXLY]: Abilities.OPPORTUNIST,
|
||||||
|
[Species.LECHONK]: Abilities.SIMPLE,
|
||||||
|
[Species.TAROUNTULA]: Abilities.HONEY_GATHER,
|
||||||
|
[Species.NYMBLE]: Abilities.GUTS,
|
||||||
|
[Species.PAWMI]: Abilities.TRANSISTOR,
|
||||||
|
[Species.TANDEMAUS]: Abilities.SCRAPPY,
|
||||||
|
[Species.FIDOUGH]: Abilities.WATER_ABSORB,
|
||||||
|
[Species.SMOLIV]: Abilities.RIPEN,
|
||||||
|
[Species.SQUAWKABILLY]: Abilities.MOXIE,
|
||||||
|
[Species.NACLI]: Abilities.SOLID_ROCK,
|
||||||
|
[Species.CHARCADET]: Abilities.PRISM_ARMOR,
|
||||||
|
[Species.TADBULB]: Abilities.STAMINA,
|
||||||
|
[Species.WATTREL]: Abilities.SHEER_FORCE,
|
||||||
|
[Species.MASCHIFF]: Abilities.STRONG_JAW,
|
||||||
|
[Species.SHROODLE]: Abilities.CORROSION,
|
||||||
|
[Species.BRAMBLIN]: Abilities.SHADOW_SHIELD,
|
||||||
|
[Species.TOEDSCOOL]: Abilities.PRANKSTER,
|
||||||
|
[Species.KLAWF]: Abilities.WATER_ABSORB,
|
||||||
|
[Species.CAPSAKID]: Abilities.PARENTAL_BOND,
|
||||||
|
[Species.RELLOR]: Abilities.PRANKSTER,
|
||||||
|
[Species.FLITTLE]: Abilities.DAZZLING,
|
||||||
|
[Species.TINKATINK]: Abilities.STEELWORKER,
|
||||||
|
[Species.WIGLETT]: Abilities.STURDY,
|
||||||
|
[Species.BOMBIRDIER]: Abilities.UNBURDEN,
|
||||||
|
[Species.FINIZEN]: Abilities.IRON_FIST,
|
||||||
|
[Species.VAROOM]: Abilities.LEVITATE,
|
||||||
|
[Species.CYCLIZAR]: Abilities.PROTEAN,
|
||||||
|
[Species.ORTHWORM]: Abilities.REGENERATOR,
|
||||||
|
[Species.GLIMMET]: Abilities.LEVITATE,
|
||||||
|
[Species.GREAVARD]: Abilities.FUR_COAT,
|
||||||
|
[Species.FLAMIGO]: Abilities.MOXIE,
|
||||||
|
[Species.CETODDLE]: Abilities.ICE_SCALES,
|
||||||
|
[Species.VELUZA]: Abilities.SUPER_LUCK,
|
||||||
|
[Species.DONDOZO]: Abilities.PARENTAL_BOND,
|
||||||
|
[Species.TATSUGIRI]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.GREAT_TUSK]: Abilities.INTIMIDATE,
|
||||||
|
[Species.SCREAM_TAIL]: Abilities.UNAWARE,
|
||||||
|
[Species.BRUTE_BONNET]: Abilities.CHLOROPHYLL,
|
||||||
|
[Species.FLUTTER_MANE]: Abilities.DAZZLING,
|
||||||
|
[Species.SLITHER_WING]: Abilities.SCRAPPY,
|
||||||
|
[Species.SANDY_SHOCKS]: Abilities.EARTH_EATER,
|
||||||
|
[Species.IRON_TREADS]: Abilities.STEELY_SPIRIT,
|
||||||
|
[Species.IRON_BUNDLE]: Abilities.SNOW_WARNING,
|
||||||
|
[Species.IRON_HANDS]: Abilities.IRON_FIST,
|
||||||
|
[Species.IRON_JUGULIS]: Abilities.LIGHTNING_ROD,
|
||||||
|
[Species.IRON_MOTH]: Abilities.LEVITATE,
|
||||||
|
[Species.IRON_THORNS]: Abilities.SAND_STREAM,
|
||||||
|
[Species.FRIGIBAX]: Abilities.SNOW_WARNING,
|
||||||
|
[Species.GIMMIGHOUL]: Abilities.HONEY_GATHER,
|
||||||
|
[Species.WO_CHIEN]: Abilities.VESSEL_OF_RUIN,
|
||||||
|
[Species.CHIEN_PAO]: Abilities.INTIMIDATE,
|
||||||
|
[Species.TING_LU]: Abilities.STAMINA,
|
||||||
|
[Species.CHI_YU]: Abilities.BERSERK,
|
||||||
|
[Species.ROARING_MOON]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.IRON_VALIANT]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.KORAIDON]: Abilities.OPPORTUNIST,
|
||||||
|
[Species.MIRAIDON]: Abilities.OPPORTUNIST,
|
||||||
|
[Species.WALKING_WAKE]: Abilities.BEAST_BOOST,
|
||||||
|
[Species.IRON_LEAVES]: Abilities.SHARPNESS,
|
||||||
|
[Species.POLTCHAGEIST]: Abilities.TRIAGE,
|
||||||
|
[Species.OKIDOGI]: Abilities.FUR_COAT,
|
||||||
|
[Species.MUNKIDORI]: Abilities.NEUROFORCE,
|
||||||
|
[Species.FEZANDIPITI]: Abilities.LEVITATE,
|
||||||
|
[Species.OGERPON]: Abilities.OPPORTUNIST,
|
||||||
|
[Species.GOUGING_FIRE]: Abilities.BEAST_BOOST,
|
||||||
|
[Species.RAGING_BOLT]: Abilities.BEAST_BOOST,
|
||||||
|
[Species.IRON_BOULDER]: Abilities.SHARPNESS,
|
||||||
|
[Species.IRON_CROWN]: Abilities.SHARPNESS,
|
||||||
|
[Species.TERAPAGOS]: Abilities.SOUL_HEART,
|
||||||
|
[Species.PECHARUNT]: Abilities.TOXIC_CHAIN,
|
||||||
|
[Species.ALOLA_RATTATA]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.ALOLA_SANDSHREW]: Abilities.ICE_SCALES,
|
||||||
|
[Species.ALOLA_VULPIX]: Abilities.SHEER_FORCE,
|
||||||
|
[Species.ALOLA_DIGLETT]: Abilities.STURDY,
|
||||||
|
[Species.ALOLA_MEOWTH]: Abilities.DARK_AURA,
|
||||||
|
[Species.ALOLA_GEODUDE]: Abilities.DRY_SKIN,
|
||||||
|
[Species.ALOLA_GRIMER]: Abilities.TOXIC_DEBRIS,
|
||||||
|
[Species.ETERNAL_FLOETTE]: Abilities.MAGIC_GUARD,
|
||||||
|
[Species.GALAR_MEOWTH]: Abilities.STEELWORKER,
|
||||||
|
[Species.GALAR_PONYTA]: Abilities.MOXIE,
|
||||||
|
[Species.GALAR_SLOWPOKE]: Abilities.UNAWARE,
|
||||||
|
[Species.GALAR_FARFETCHD]: Abilities.INTREPID_SWORD,
|
||||||
|
[Species.GALAR_ARTICUNO]: Abilities.SERENE_GRACE,
|
||||||
|
[Species.GALAR_ZAPDOS]: Abilities.TOUGH_CLAWS,
|
||||||
|
[Species.GALAR_MOLTRES]: Abilities.DARK_AURA,
|
||||||
|
[Species.GALAR_CORSOLA]: Abilities.SHADOW_SHIELD,
|
||||||
|
[Species.GALAR_ZIGZAGOON]: Abilities.POISON_HEAL,
|
||||||
|
[Species.GALAR_DARUMAKA]: Abilities.FLASH_FIRE,
|
||||||
|
[Species.GALAR_YAMASK]: Abilities.TABLETS_OF_RUIN,
|
||||||
|
[Species.GALAR_STUNFISK]: Abilities.ARENA_TRAP,
|
||||||
|
[Species.HISUI_GROWLITHE]: Abilities.RECKLESS,
|
||||||
|
[Species.HISUI_VOLTORB]: Abilities.TRANSISTOR,
|
||||||
|
[Species.HISUI_QWILFISH]: Abilities.MERCILESS,
|
||||||
|
[Species.HISUI_SNEASEL]: Abilities.SCRAPPY,
|
||||||
|
[Species.HISUI_ZORUA]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.PALDEA_TAUROS]: Abilities.ADAPTABILITY,
|
||||||
|
[Species.PALDEA_WOOPER]: Abilities.THICK_FAT,
|
||||||
|
[Species.BLOODMOON_URSALUNA]: Abilities.BERSERK
|
||||||
|
};
|
@ -1,16 +1,18 @@
|
|||||||
import { Gender } from "./gender";
|
import { Gender } from "#app/data/gender";
|
||||||
import { PokeballType } from "./pokeball";
|
import { PokeballType } from "#app/data/pokeball";
|
||||||
import Pokemon from "../field/pokemon";
|
import Pokemon from "#app/field/pokemon";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import { Type } from "./type";
|
import { Type } from "#app/data/type";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "#app/utils";
|
||||||
import { SpeciesFormKey } from "./pokemon-species";
|
import { WeatherType } from "#app/data/weather";
|
||||||
import { WeatherType } from "./weather";
|
import { Nature } from "#app/data/nature";
|
||||||
import { Nature } from "./nature";
|
|
||||||
import { Biome } from "#enums/biome";
|
import { Biome } from "#enums/biome";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { TimeOfDay } from "#enums/time-of-day";
|
import { TimeOfDay } from "#enums/time-of-day";
|
||||||
|
import { DamageMoneyRewardModifier, ExtraModifierModifier, MoneyMultiplierModifier } from "#app/modifier/modifier";
|
||||||
|
import { SpeciesFormKey } from "#enums/species-form-key";
|
||||||
|
|
||||||
|
|
||||||
export enum SpeciesWildEvolutionDelay {
|
export enum SpeciesWildEvolutionDelay {
|
||||||
NONE,
|
NONE,
|
||||||
@ -1647,8 +1649,14 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.FROSMOTH, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM)
|
new SpeciesEvolution(Species.FROSMOTH, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM)
|
||||||
],
|
],
|
||||||
[Species.GIMMIGHOUL]: [
|
[Species.GIMMIGHOUL]: [
|
||||||
new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 ), SpeciesWildEvolutionDelay.VERY_LONG),
|
new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesEvolutionCondition(p => p.evoCounter
|
||||||
new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 ), SpeciesWildEvolutionDelay.VERY_LONG)
|
+ p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length
|
||||||
|
+ p.scene.findModifiers(m => m instanceof MoneyMultiplierModifier
|
||||||
|
|| m instanceof ExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG),
|
||||||
|
new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesEvolutionCondition(p => p.evoCounter
|
||||||
|
+ p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length
|
||||||
|
+ p.scene.findModifiers(m => m instanceof MoneyMultiplierModifier
|
||||||
|
|| m instanceof ExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
53
src/data/balance/rates.ts
Normal file
53
src/data/balance/rates.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Rates for shinies and other random properties are defined in this file.
|
||||||
|
* CHANCE is defined as x/65536
|
||||||
|
* RATE is defined as 1/x
|
||||||
|
*/
|
||||||
|
|
||||||
|
// #region Encounterable properties
|
||||||
|
/** `64/65536 -> 1/1024` */
|
||||||
|
export const BASE_SHINY_CHANCE = 64;
|
||||||
|
|
||||||
|
/** `256/65536 -> 1/256` */
|
||||||
|
export const BASE_HIDDEN_ABILITY_CHANCE = 256;
|
||||||
|
|
||||||
|
// #region Egg properties
|
||||||
|
|
||||||
|
// Threshold x at which a gacha egg is determined to be a certain tier
|
||||||
|
// Specifically, the tier is determined by the highest threshold a random value between 0-255 meets or exceeds
|
||||||
|
// Legendary Up Gacha raises these thresholds by 1, thereby giving Legendary eggs 2/256 chance
|
||||||
|
export const GACHA_DEFAULT_COMMON_EGG_THRESHOLD = 52; // Default 204/256 chance, 203/256 chance in Legendary Up Gacha
|
||||||
|
export const GACHA_DEFAULT_RARE_EGG_THRESHOLD = 8; // Default 44/256 chance
|
||||||
|
export const GACHA_DEFAULT_EPIC_EGG_THRESHOLD = 1; // Default 7/256 chance, leaving Legendary as 1/256 chance
|
||||||
|
export const GACHA_LEGENDARY_UP_THRESHOLD_OFFSET = 1; // The offset to threshold for Legendary Up gacha eggs. +x/256 Legendary Egg chance, -x/256 Common Egg chance
|
||||||
|
|
||||||
|
// The number of eggs without finding a certain tier egg it takes for egg pity to kick in and that tier to be forced
|
||||||
|
// These numbers are roughly the 80% mark. That is, 80% of the time you'll get an egg before this gets triggered.
|
||||||
|
export const EGG_PITY_LEGENDARY_THRESHOLD = 412;
|
||||||
|
export const EGG_PITY_EPIC_THRESHOLD = 59;
|
||||||
|
export const EGG_PITY_RARE_THRESHOLD = 9;
|
||||||
|
|
||||||
|
// Waves to hatch an egg of a given tier
|
||||||
|
export const HATCH_WAVES_COMMON_EGG = 10;
|
||||||
|
export const HATCH_WAVES_RARE_EGG = 25;
|
||||||
|
export const HATCH_WAVES_EPIC_EGG = 50;
|
||||||
|
export const HATCH_WAVES_LEGENDARY_EGG = 100;
|
||||||
|
export const HATCH_WAVES_MANAPHY_EGG = 50;
|
||||||
|
|
||||||
|
// Rates for specific random properties in 1/x
|
||||||
|
export const GACHA_DEFAULT_SHINY_RATE = 128;
|
||||||
|
export const GACHA_SHINY_UP_SHINY_RATE = 64;
|
||||||
|
export const SAME_SPECIES_EGG_SHINY_RATE = 12;
|
||||||
|
export const SAME_SPECIES_EGG_HA_RATE = 8;
|
||||||
|
export const MANAPHY_EGG_MANAPHY_RATE = 8;
|
||||||
|
export const GACHA_EGG_HA_RATE = 192;
|
||||||
|
|
||||||
|
// 1/x for legendary eggs, 1/x*2 for epic eggs, 1/x*4 for rare eggs, and 1/x*8 for common eggs
|
||||||
|
export const GACHA_DEFAULT_RARE_EGGMOVE_RATE = 6;
|
||||||
|
export const SAME_SPECIES_EGG_RARE_EGGMOVE_RATE = 3;
|
||||||
|
export const GACHA_MOVE_UP_RARE_EGGMOVE_RATE = 3;
|
||||||
|
|
||||||
|
// #region Variant properties
|
||||||
|
// The chance x/10 of a shiny being a variant, then of being specifically an epic variant
|
||||||
|
export const SHINY_VARIANT_CHANCE = 4;
|
||||||
|
export const SHINY_EPIC_CHANCE = 1;
|
671
src/data/balance/starters.ts
Normal file
671
src/data/balance/starters.ts
Normal file
@ -0,0 +1,671 @@
|
|||||||
|
import { Species } from "#enums/species";
|
||||||
|
|
||||||
|
export const POKERUS_STARTER_COUNT = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to get the cumulative friendship threshold at which a candy is earned
|
||||||
|
* @param starterCost The cost of the starter, found in {@linkcode speciesStarterCosts}
|
||||||
|
* @returns aforementioned threshold
|
||||||
|
*/
|
||||||
|
export function getStarterValueFriendshipCap(starterCost: number): number {
|
||||||
|
switch (starterCost) {
|
||||||
|
case 1:
|
||||||
|
return 20;
|
||||||
|
case 2:
|
||||||
|
return 40;
|
||||||
|
case 3:
|
||||||
|
return 60;
|
||||||
|
case 4:
|
||||||
|
return 100;
|
||||||
|
case 5:
|
||||||
|
return 140;
|
||||||
|
case 6:
|
||||||
|
return 200;
|
||||||
|
case 7:
|
||||||
|
return 280;
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
return 450;
|
||||||
|
default:
|
||||||
|
return 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const speciesStarterCosts = {
|
||||||
|
[Species.BULBASAUR]: 3,
|
||||||
|
[Species.CHARMANDER]: 3,
|
||||||
|
[Species.SQUIRTLE]: 3,
|
||||||
|
[Species.CATERPIE]: 2,
|
||||||
|
[Species.WEEDLE]: 1,
|
||||||
|
[Species.PIDGEY]: 1,
|
||||||
|
[Species.RATTATA]: 1,
|
||||||
|
[Species.SPEAROW]: 1,
|
||||||
|
[Species.EKANS]: 2,
|
||||||
|
[Species.PIKACHU]: 3,
|
||||||
|
[Species.SANDSHREW]: 2,
|
||||||
|
[Species.NIDORAN_F]: 3,
|
||||||
|
[Species.NIDORAN_M]: 3,
|
||||||
|
[Species.CLEFAIRY]: 3,
|
||||||
|
[Species.VULPIX]: 3,
|
||||||
|
[Species.JIGGLYPUFF]: 2,
|
||||||
|
[Species.ZUBAT]: 3,
|
||||||
|
[Species.ODDISH]: 3,
|
||||||
|
[Species.PARAS]: 2,
|
||||||
|
[Species.VENONAT]: 2,
|
||||||
|
[Species.DIGLETT]: 2,
|
||||||
|
[Species.MEOWTH]: 3,
|
||||||
|
[Species.PSYDUCK]: 2,
|
||||||
|
[Species.MANKEY]: 4,
|
||||||
|
[Species.GROWLITHE]: 4,
|
||||||
|
[Species.POLIWAG]: 2,
|
||||||
|
[Species.ABRA]: 4,
|
||||||
|
[Species.MACHOP]: 3,
|
||||||
|
[Species.BELLSPROUT]: 2,
|
||||||
|
[Species.TENTACOOL]: 3,
|
||||||
|
[Species.GEODUDE]: 3,
|
||||||
|
[Species.PONYTA]: 2,
|
||||||
|
[Species.SLOWPOKE]: 3,
|
||||||
|
[Species.MAGNEMITE]: 4,
|
||||||
|
[Species.FARFETCHD]: 2,
|
||||||
|
[Species.DODUO]: 3,
|
||||||
|
[Species.SEEL]: 1,
|
||||||
|
[Species.GRIMER]: 2,
|
||||||
|
[Species.SHELLDER]: 5,
|
||||||
|
[Species.GASTLY]: 4,
|
||||||
|
[Species.ONIX]: 3,
|
||||||
|
[Species.DROWZEE]: 2,
|
||||||
|
[Species.KRABBY]: 3,
|
||||||
|
[Species.VOLTORB]: 2,
|
||||||
|
[Species.EXEGGCUTE]: 3,
|
||||||
|
[Species.CUBONE]: 3,
|
||||||
|
[Species.HITMONLEE]: 4,
|
||||||
|
[Species.HITMONCHAN]: 4,
|
||||||
|
[Species.LICKITUNG]: 3,
|
||||||
|
[Species.KOFFING]: 2,
|
||||||
|
[Species.RHYHORN]: 3,
|
||||||
|
[Species.CHANSEY]: 3,
|
||||||
|
[Species.TANGELA]: 3,
|
||||||
|
[Species.KANGASKHAN]: 4,
|
||||||
|
[Species.HORSEA]: 3,
|
||||||
|
[Species.GOLDEEN]: 2,
|
||||||
|
[Species.STARYU]: 3,
|
||||||
|
[Species.MR_MIME]: 3,
|
||||||
|
[Species.SCYTHER]: 5,
|
||||||
|
[Species.JYNX]: 4,
|
||||||
|
[Species.ELECTABUZZ]: 4,
|
||||||
|
[Species.MAGMAR]: 4,
|
||||||
|
[Species.PINSIR]: 4,
|
||||||
|
[Species.TAUROS]: 4,
|
||||||
|
[Species.MAGIKARP]: 4,
|
||||||
|
[Species.LAPRAS]: 4,
|
||||||
|
[Species.DITTO]: 2,
|
||||||
|
[Species.EEVEE]: 3,
|
||||||
|
[Species.PORYGON]: 4,
|
||||||
|
[Species.OMANYTE]: 3,
|
||||||
|
[Species.KABUTO]: 3,
|
||||||
|
[Species.AERODACTYL]: 5,
|
||||||
|
[Species.SNORLAX]: 5,
|
||||||
|
[Species.ARTICUNO]: 6,
|
||||||
|
[Species.ZAPDOS]: 6,
|
||||||
|
[Species.MOLTRES]: 6,
|
||||||
|
[Species.DRATINI]: 4,
|
||||||
|
[Species.MEWTWO]: 8,
|
||||||
|
[Species.MEW]: 6,
|
||||||
|
|
||||||
|
[Species.CHIKORITA]: 2,
|
||||||
|
[Species.CYNDAQUIL]: 3,
|
||||||
|
[Species.TOTODILE]: 3,
|
||||||
|
[Species.SENTRET]: 1,
|
||||||
|
[Species.HOOTHOOT]: 2,
|
||||||
|
[Species.LEDYBA]: 1,
|
||||||
|
[Species.SPINARAK]: 1,
|
||||||
|
[Species.CHINCHOU]: 2,
|
||||||
|
[Species.PICHU]: 2,
|
||||||
|
[Species.CLEFFA]: 2,
|
||||||
|
[Species.IGGLYBUFF]: 1,
|
||||||
|
[Species.TOGEPI]: 3,
|
||||||
|
[Species.NATU]: 2,
|
||||||
|
[Species.MAREEP]: 2,
|
||||||
|
[Species.MARILL]: 4,
|
||||||
|
[Species.SUDOWOODO]: 3,
|
||||||
|
[Species.HOPPIP]: 2,
|
||||||
|
[Species.AIPOM]: 2,
|
||||||
|
[Species.SUNKERN]: 1,
|
||||||
|
[Species.YANMA]: 3,
|
||||||
|
[Species.WOOPER]: 2,
|
||||||
|
[Species.MURKROW]: 3,
|
||||||
|
[Species.MISDREAVUS]: 2,
|
||||||
|
[Species.UNOWN]: 1,
|
||||||
|
[Species.WOBBUFFET]: 2,
|
||||||
|
[Species.GIRAFARIG]: 3,
|
||||||
|
[Species.PINECO]: 2,
|
||||||
|
[Species.DUNSPARCE]: 3,
|
||||||
|
[Species.GLIGAR]: 3,
|
||||||
|
[Species.SNUBBULL]: 2,
|
||||||
|
[Species.QWILFISH]: 3,
|
||||||
|
[Species.SHUCKLE]: 3,
|
||||||
|
[Species.HERACROSS]: 5,
|
||||||
|
[Species.SNEASEL]: 4,
|
||||||
|
[Species.TEDDIURSA]: 4,
|
||||||
|
[Species.SLUGMA]: 2,
|
||||||
|
[Species.SWINUB]: 3,
|
||||||
|
[Species.CORSOLA]: 2,
|
||||||
|
[Species.REMORAID]: 2,
|
||||||
|
[Species.DELIBIRD]: 2,
|
||||||
|
[Species.MANTINE]: 3,
|
||||||
|
[Species.SKARMORY]: 4,
|
||||||
|
[Species.HOUNDOUR]: 3,
|
||||||
|
[Species.PHANPY]: 3,
|
||||||
|
[Species.STANTLER]: 3,
|
||||||
|
[Species.SMEARGLE]: 1,
|
||||||
|
[Species.TYROGUE]: 3,
|
||||||
|
[Species.SMOOCHUM]: 3,
|
||||||
|
[Species.ELEKID]: 3,
|
||||||
|
[Species.MAGBY]: 3,
|
||||||
|
[Species.MILTANK]: 4,
|
||||||
|
[Species.RAIKOU]: 6,
|
||||||
|
[Species.ENTEI]: 6,
|
||||||
|
[Species.SUICUNE]: 6,
|
||||||
|
[Species.LARVITAR]: 4,
|
||||||
|
[Species.LUGIA]: 8,
|
||||||
|
[Species.HO_OH]: 8,
|
||||||
|
[Species.CELEBI]: 6,
|
||||||
|
|
||||||
|
[Species.TREECKO]: 3,
|
||||||
|
[Species.TORCHIC]: 4,
|
||||||
|
[Species.MUDKIP]: 3,
|
||||||
|
[Species.POOCHYENA]: 2,
|
||||||
|
[Species.ZIGZAGOON]: 2,
|
||||||
|
[Species.WURMPLE]: 1,
|
||||||
|
[Species.LOTAD]: 3,
|
||||||
|
[Species.SEEDOT]: 2,
|
||||||
|
[Species.TAILLOW]: 3,
|
||||||
|
[Species.WINGULL]: 2,
|
||||||
|
[Species.RALTS]: 3,
|
||||||
|
[Species.SURSKIT]: 2,
|
||||||
|
[Species.SHROOMISH]: 3,
|
||||||
|
[Species.SLAKOTH]: 4,
|
||||||
|
[Species.NINCADA]: 4,
|
||||||
|
[Species.WHISMUR]: 2,
|
||||||
|
[Species.MAKUHITA]: 3,
|
||||||
|
[Species.AZURILL]: 4,
|
||||||
|
[Species.NOSEPASS]: 2,
|
||||||
|
[Species.SKITTY]: 1,
|
||||||
|
[Species.SABLEYE]: 2,
|
||||||
|
[Species.MAWILE]: 3,
|
||||||
|
[Species.ARON]: 3,
|
||||||
|
[Species.MEDITITE]: 3,
|
||||||
|
[Species.ELECTRIKE]: 2,
|
||||||
|
[Species.PLUSLE]: 2,
|
||||||
|
[Species.MINUN]: 2,
|
||||||
|
[Species.VOLBEAT]: 2,
|
||||||
|
[Species.ILLUMISE]: 2,
|
||||||
|
[Species.ROSELIA]: 3,
|
||||||
|
[Species.GULPIN]: 1,
|
||||||
|
[Species.CARVANHA]: 3,
|
||||||
|
[Species.WAILMER]: 2,
|
||||||
|
[Species.NUMEL]: 2,
|
||||||
|
[Species.TORKOAL]: 3,
|
||||||
|
[Species.SPOINK]: 2,
|
||||||
|
[Species.SPINDA]: 1,
|
||||||
|
[Species.TRAPINCH]: 3,
|
||||||
|
[Species.CACNEA]: 2,
|
||||||
|
[Species.SWABLU]: 2,
|
||||||
|
[Species.ZANGOOSE]: 4,
|
||||||
|
[Species.SEVIPER]: 3,
|
||||||
|
[Species.LUNATONE]: 3,
|
||||||
|
[Species.SOLROCK]: 3,
|
||||||
|
[Species.BARBOACH]: 2,
|
||||||
|
[Species.CORPHISH]: 3,
|
||||||
|
[Species.BALTOY]: 2,
|
||||||
|
[Species.LILEEP]: 3,
|
||||||
|
[Species.ANORITH]: 3,
|
||||||
|
[Species.FEEBAS]: 4,
|
||||||
|
[Species.CASTFORM]: 1,
|
||||||
|
[Species.KECLEON]: 2,
|
||||||
|
[Species.SHUPPET]: 2,
|
||||||
|
[Species.DUSKULL]: 3,
|
||||||
|
[Species.TROPIUS]: 3,
|
||||||
|
[Species.CHIMECHO]: 3,
|
||||||
|
[Species.ABSOL]: 4,
|
||||||
|
[Species.WYNAUT]: 2,
|
||||||
|
[Species.SNORUNT]: 2,
|
||||||
|
[Species.SPHEAL]: 2,
|
||||||
|
[Species.CLAMPERL]: 3,
|
||||||
|
[Species.RELICANTH]: 3,
|
||||||
|
[Species.LUVDISC]: 1,
|
||||||
|
[Species.BAGON]: 4,
|
||||||
|
[Species.BELDUM]: 4,
|
||||||
|
[Species.REGIROCK]: 6,
|
||||||
|
[Species.REGICE]: 6,
|
||||||
|
[Species.REGISTEEL]: 6,
|
||||||
|
[Species.LATIAS]: 7,
|
||||||
|
[Species.LATIOS]: 7,
|
||||||
|
[Species.KYOGRE]: 9,
|
||||||
|
[Species.GROUDON]: 9,
|
||||||
|
[Species.RAYQUAZA]: 9,
|
||||||
|
[Species.JIRACHI]: 7,
|
||||||
|
[Species.DEOXYS]: 7,
|
||||||
|
|
||||||
|
[Species.TURTWIG]: 3,
|
||||||
|
[Species.CHIMCHAR]: 3,
|
||||||
|
[Species.PIPLUP]: 3,
|
||||||
|
[Species.STARLY]: 3,
|
||||||
|
[Species.BIDOOF]: 2,
|
||||||
|
[Species.KRICKETOT]: 1,
|
||||||
|
[Species.SHINX]: 2,
|
||||||
|
[Species.BUDEW]: 3,
|
||||||
|
[Species.CRANIDOS]: 3,
|
||||||
|
[Species.SHIELDON]: 3,
|
||||||
|
[Species.BURMY]: 2,
|
||||||
|
[Species.COMBEE]: 2,
|
||||||
|
[Species.PACHIRISU]: 2,
|
||||||
|
[Species.BUIZEL]: 2,
|
||||||
|
[Species.CHERUBI]: 1,
|
||||||
|
[Species.SHELLOS]: 3,
|
||||||
|
[Species.DRIFLOON]: 2,
|
||||||
|
[Species.BUNEARY]: 2,
|
||||||
|
[Species.GLAMEOW]: 2,
|
||||||
|
[Species.CHINGLING]: 2,
|
||||||
|
[Species.STUNKY]: 2,
|
||||||
|
[Species.BRONZOR]: 3,
|
||||||
|
[Species.BONSLY]: 2,
|
||||||
|
[Species.MIME_JR]: 2,
|
||||||
|
[Species.HAPPINY]: 2,
|
||||||
|
[Species.CHATOT]: 2,
|
||||||
|
[Species.SPIRITOMB]: 4,
|
||||||
|
[Species.GIBLE]: 4,
|
||||||
|
[Species.MUNCHLAX]: 4,
|
||||||
|
[Species.RIOLU]: 3,
|
||||||
|
[Species.HIPPOPOTAS]: 3,
|
||||||
|
[Species.SKORUPI]: 3,
|
||||||
|
[Species.CROAGUNK]: 2,
|
||||||
|
[Species.CARNIVINE]: 2,
|
||||||
|
[Species.FINNEON]: 1,
|
||||||
|
[Species.MANTYKE]: 2,
|
||||||
|
[Species.SNOVER]: 2,
|
||||||
|
[Species.ROTOM]: 5,
|
||||||
|
[Species.UXIE]: 6,
|
||||||
|
[Species.MESPRIT]: 6,
|
||||||
|
[Species.AZELF]: 6,
|
||||||
|
[Species.DIALGA]: 8,
|
||||||
|
[Species.PALKIA]: 8,
|
||||||
|
[Species.HEATRAN]: 6,
|
||||||
|
[Species.REGIGIGAS]: 7,
|
||||||
|
[Species.GIRATINA]: 8,
|
||||||
|
[Species.CRESSELIA]: 6,
|
||||||
|
[Species.PHIONE]: 4,
|
||||||
|
[Species.MANAPHY]: 7,
|
||||||
|
[Species.DARKRAI]: 7,
|
||||||
|
[Species.SHAYMIN]: 6,
|
||||||
|
[Species.ARCEUS]: 9,
|
||||||
|
|
||||||
|
[Species.VICTINI]: 7,
|
||||||
|
[Species.SNIVY]: 3,
|
||||||
|
[Species.TEPIG]: 3,
|
||||||
|
[Species.OSHAWOTT]: 3,
|
||||||
|
[Species.PATRAT]: 1,
|
||||||
|
[Species.LILLIPUP]: 3,
|
||||||
|
[Species.PURRLOIN]: 2,
|
||||||
|
[Species.PANSAGE]: 2,
|
||||||
|
[Species.PANSEAR]: 2,
|
||||||
|
[Species.PANPOUR]: 2,
|
||||||
|
[Species.MUNNA]: 2,
|
||||||
|
[Species.PIDOVE]: 1,
|
||||||
|
[Species.BLITZLE]: 2,
|
||||||
|
[Species.ROGGENROLA]: 3,
|
||||||
|
[Species.WOOBAT]: 3,
|
||||||
|
[Species.DRILBUR]: 4,
|
||||||
|
[Species.AUDINO]: 3,
|
||||||
|
[Species.TIMBURR]: 4,
|
||||||
|
[Species.TYMPOLE]: 3,
|
||||||
|
[Species.THROH]: 4,
|
||||||
|
[Species.SAWK]: 4,
|
||||||
|
[Species.SEWADDLE]: 2,
|
||||||
|
[Species.VENIPEDE]: 3,
|
||||||
|
[Species.COTTONEE]: 3,
|
||||||
|
[Species.PETILIL]: 3,
|
||||||
|
[Species.BASCULIN]: 4,
|
||||||
|
[Species.SANDILE]: 4,
|
||||||
|
[Species.DARUMAKA]: 4,
|
||||||
|
[Species.MARACTUS]: 2,
|
||||||
|
[Species.DWEBBLE]: 2,
|
||||||
|
[Species.SCRAGGY]: 3,
|
||||||
|
[Species.SIGILYPH]: 4,
|
||||||
|
[Species.YAMASK]: 3,
|
||||||
|
[Species.TIRTOUGA]: 3,
|
||||||
|
[Species.ARCHEN]: 3,
|
||||||
|
[Species.TRUBBISH]: 2,
|
||||||
|
[Species.ZORUA]: 3,
|
||||||
|
[Species.MINCCINO]: 3,
|
||||||
|
[Species.GOTHITA]: 3,
|
||||||
|
[Species.SOLOSIS]: 3,
|
||||||
|
[Species.DUCKLETT]: 2,
|
||||||
|
[Species.VANILLITE]: 3,
|
||||||
|
[Species.DEERLING]: 2,
|
||||||
|
[Species.EMOLGA]: 2,
|
||||||
|
[Species.KARRABLAST]: 3,
|
||||||
|
[Species.FOONGUS]: 2,
|
||||||
|
[Species.FRILLISH]: 3,
|
||||||
|
[Species.ALOMOMOLA]: 4,
|
||||||
|
[Species.JOLTIK]: 3,
|
||||||
|
[Species.FERROSEED]: 3,
|
||||||
|
[Species.KLINK]: 3,
|
||||||
|
[Species.TYNAMO]: 2,
|
||||||
|
[Species.ELGYEM]: 2,
|
||||||
|
[Species.LITWICK]: 3,
|
||||||
|
[Species.AXEW]: 4,
|
||||||
|
[Species.CUBCHOO]: 2,
|
||||||
|
[Species.CRYOGONAL]: 4,
|
||||||
|
[Species.SHELMET]: 2,
|
||||||
|
[Species.STUNFISK]: 3,
|
||||||
|
[Species.MIENFOO]: 3,
|
||||||
|
[Species.DRUDDIGON]: 4,
|
||||||
|
[Species.GOLETT]: 3,
|
||||||
|
[Species.PAWNIARD]: 4,
|
||||||
|
[Species.BOUFFALANT]: 4,
|
||||||
|
[Species.RUFFLET]: 3,
|
||||||
|
[Species.VULLABY]: 3,
|
||||||
|
[Species.HEATMOR]: 3,
|
||||||
|
[Species.DURANT]: 4,
|
||||||
|
[Species.DEINO]: 4,
|
||||||
|
[Species.LARVESTA]: 4,
|
||||||
|
[Species.COBALION]: 6,
|
||||||
|
[Species.TERRAKION]: 6,
|
||||||
|
[Species.VIRIZION]: 6,
|
||||||
|
[Species.TORNADUS]: 7,
|
||||||
|
[Species.THUNDURUS]: 7,
|
||||||
|
[Species.RESHIRAM]: 8,
|
||||||
|
[Species.ZEKROM]: 8,
|
||||||
|
[Species.LANDORUS]: 7,
|
||||||
|
[Species.KYUREM]: 8,
|
||||||
|
[Species.KELDEO]: 6,
|
||||||
|
[Species.MELOETTA]: 7,
|
||||||
|
[Species.GENESECT]: 6,
|
||||||
|
|
||||||
|
[Species.CHESPIN]: 3,
|
||||||
|
[Species.FENNEKIN]: 3,
|
||||||
|
[Species.FROAKIE]: 4,
|
||||||
|
[Species.BUNNELBY]: 3,
|
||||||
|
[Species.FLETCHLING]: 3,
|
||||||
|
[Species.SCATTERBUG]: 2,
|
||||||
|
[Species.LITLEO]: 2,
|
||||||
|
[Species.FLABEBE]: 3,
|
||||||
|
[Species.SKIDDO]: 2,
|
||||||
|
[Species.PANCHAM]: 3,
|
||||||
|
[Species.FURFROU]: 3,
|
||||||
|
[Species.ESPURR]: 2,
|
||||||
|
[Species.HONEDGE]: 4,
|
||||||
|
[Species.SPRITZEE]: 2,
|
||||||
|
[Species.SWIRLIX]: 3,
|
||||||
|
[Species.INKAY]: 3,
|
||||||
|
[Species.BINACLE]: 3,
|
||||||
|
[Species.SKRELP]: 2,
|
||||||
|
[Species.CLAUNCHER]: 3,
|
||||||
|
[Species.HELIOPTILE]: 3,
|
||||||
|
[Species.TYRUNT]: 3,
|
||||||
|
[Species.AMAURA]: 3,
|
||||||
|
[Species.HAWLUCHA]: 4,
|
||||||
|
[Species.DEDENNE]: 2,
|
||||||
|
[Species.CARBINK]: 2,
|
||||||
|
[Species.GOOMY]: 4,
|
||||||
|
[Species.KLEFKI]: 3,
|
||||||
|
[Species.PHANTUMP]: 2,
|
||||||
|
[Species.PUMPKABOO]: 2,
|
||||||
|
[Species.BERGMITE]: 3,
|
||||||
|
[Species.NOIBAT]: 3,
|
||||||
|
[Species.XERNEAS]: 8,
|
||||||
|
[Species.YVELTAL]: 8,
|
||||||
|
[Species.ZYGARDE]: 8,
|
||||||
|
[Species.DIANCIE]: 7,
|
||||||
|
[Species.HOOPA]: 7,
|
||||||
|
[Species.VOLCANION]: 6,
|
||||||
|
[Species.ETERNAL_FLOETTE]: 4,
|
||||||
|
|
||||||
|
[Species.ROWLET]: 3,
|
||||||
|
[Species.LITTEN]: 3,
|
||||||
|
[Species.POPPLIO]: 4,
|
||||||
|
[Species.PIKIPEK]: 2,
|
||||||
|
[Species.YUNGOOS]: 2,
|
||||||
|
[Species.GRUBBIN]: 3,
|
||||||
|
[Species.CRABRAWLER]: 3,
|
||||||
|
[Species.ORICORIO]: 3,
|
||||||
|
[Species.CUTIEFLY]: 3,
|
||||||
|
[Species.ROCKRUFF]: 3,
|
||||||
|
[Species.WISHIWASHI]: 2,
|
||||||
|
[Species.MAREANIE]: 2,
|
||||||
|
[Species.MUDBRAY]: 3,
|
||||||
|
[Species.DEWPIDER]: 3,
|
||||||
|
[Species.FOMANTIS]: 2,
|
||||||
|
[Species.MORELULL]: 2,
|
||||||
|
[Species.SALANDIT]: 3,
|
||||||
|
[Species.STUFFUL]: 3,
|
||||||
|
[Species.BOUNSWEET]: 3,
|
||||||
|
[Species.COMFEY]: 4,
|
||||||
|
[Species.ORANGURU]: 4,
|
||||||
|
[Species.PASSIMIAN]: 4,
|
||||||
|
[Species.WIMPOD]: 3,
|
||||||
|
[Species.SANDYGAST]: 3,
|
||||||
|
[Species.PYUKUMUKU]: 2,
|
||||||
|
[Species.TYPE_NULL]: 5,
|
||||||
|
[Species.MINIOR]: 4,
|
||||||
|
[Species.KOMALA]: 3,
|
||||||
|
[Species.TURTONATOR]: 4,
|
||||||
|
[Species.TOGEDEMARU]: 3,
|
||||||
|
[Species.MIMIKYU]: 4,
|
||||||
|
[Species.BRUXISH]: 4,
|
||||||
|
[Species.DRAMPA]: 4,
|
||||||
|
[Species.DHELMISE]: 4,
|
||||||
|
[Species.JANGMO_O]: 4,
|
||||||
|
[Species.TAPU_KOKO]: 6,
|
||||||
|
[Species.TAPU_LELE]: 6,
|
||||||
|
[Species.TAPU_BULU]: 6,
|
||||||
|
[Species.TAPU_FINI]: 6,
|
||||||
|
[Species.COSMOG]: 7,
|
||||||
|
[Species.NIHILEGO]: 6,
|
||||||
|
[Species.BUZZWOLE]: 6,
|
||||||
|
[Species.PHEROMOSA]: 7,
|
||||||
|
[Species.XURKITREE]: 6,
|
||||||
|
[Species.CELESTEELA]: 6,
|
||||||
|
[Species.KARTANA]: 7,
|
||||||
|
[Species.GUZZLORD]: 6,
|
||||||
|
[Species.NECROZMA]: 8,
|
||||||
|
[Species.MAGEARNA]: 7,
|
||||||
|
[Species.MARSHADOW]: 7,
|
||||||
|
[Species.POIPOLE]: 7,
|
||||||
|
[Species.STAKATAKA]: 6,
|
||||||
|
[Species.BLACEPHALON]: 7,
|
||||||
|
[Species.ZERAORA]: 6,
|
||||||
|
[Species.MELTAN]: 6,
|
||||||
|
[Species.ALOLA_RATTATA]: 1,
|
||||||
|
[Species.ALOLA_SANDSHREW]: 2,
|
||||||
|
[Species.ALOLA_VULPIX]: 3,
|
||||||
|
[Species.ALOLA_DIGLETT]: 2,
|
||||||
|
[Species.ALOLA_MEOWTH]: 3,
|
||||||
|
[Species.ALOLA_GEODUDE]: 3,
|
||||||
|
[Species.ALOLA_GRIMER]: 3,
|
||||||
|
|
||||||
|
[Species.GROOKEY]: 3,
|
||||||
|
[Species.SCORBUNNY]: 4,
|
||||||
|
[Species.SOBBLE]: 3,
|
||||||
|
[Species.SKWOVET]: 2,
|
||||||
|
[Species.ROOKIDEE]: 3,
|
||||||
|
[Species.BLIPBUG]: 2,
|
||||||
|
[Species.NICKIT]: 1,
|
||||||
|
[Species.GOSSIFLEUR]: 2,
|
||||||
|
[Species.WOOLOO]: 2,
|
||||||
|
[Species.CHEWTLE]: 3,
|
||||||
|
[Species.YAMPER]: 2,
|
||||||
|
[Species.ROLYCOLY]: 3,
|
||||||
|
[Species.APPLIN]: 3,
|
||||||
|
[Species.SILICOBRA]: 3,
|
||||||
|
[Species.CRAMORANT]: 3,
|
||||||
|
[Species.ARROKUDA]: 3,
|
||||||
|
[Species.TOXEL]: 3,
|
||||||
|
[Species.SIZZLIPEDE]: 3,
|
||||||
|
[Species.CLOBBOPUS]: 2,
|
||||||
|
[Species.SINISTEA]: 3,
|
||||||
|
[Species.HATENNA]: 3,
|
||||||
|
[Species.IMPIDIMP]: 3,
|
||||||
|
[Species.MILCERY]: 3,
|
||||||
|
[Species.FALINKS]: 4,
|
||||||
|
[Species.PINCURCHIN]: 3,
|
||||||
|
[Species.SNOM]: 3,
|
||||||
|
[Species.STONJOURNER]: 3,
|
||||||
|
[Species.EISCUE]: 3,
|
||||||
|
[Species.INDEEDEE]: 4,
|
||||||
|
[Species.MORPEKO]: 3,
|
||||||
|
[Species.CUFANT]: 3,
|
||||||
|
[Species.DRACOZOLT]: 5,
|
||||||
|
[Species.ARCTOZOLT]: 4,
|
||||||
|
[Species.DRACOVISH]: 5,
|
||||||
|
[Species.ARCTOVISH]: 4,
|
||||||
|
[Species.DURALUDON]: 5,
|
||||||
|
[Species.DREEPY]: 4,
|
||||||
|
[Species.ZACIAN]: 9,
|
||||||
|
[Species.ZAMAZENTA]: 8,
|
||||||
|
[Species.ETERNATUS]: 10,
|
||||||
|
[Species.KUBFU]: 6,
|
||||||
|
[Species.ZARUDE]: 6,
|
||||||
|
[Species.REGIELEKI]: 6,
|
||||||
|
[Species.REGIDRAGO]: 6,
|
||||||
|
[Species.GLASTRIER]: 6,
|
||||||
|
[Species.SPECTRIER]: 7,
|
||||||
|
[Species.CALYREX]: 8,
|
||||||
|
[Species.GALAR_MEOWTH]: 3,
|
||||||
|
[Species.GALAR_PONYTA]: 2,
|
||||||
|
[Species.GALAR_SLOWPOKE]: 3,
|
||||||
|
[Species.GALAR_FARFETCHD]: 3,
|
||||||
|
[Species.GALAR_CORSOLA]: 3,
|
||||||
|
[Species.GALAR_ZIGZAGOON]: 3,
|
||||||
|
[Species.GALAR_DARUMAKA]: 4,
|
||||||
|
[Species.GALAR_YAMASK]: 3,
|
||||||
|
[Species.GALAR_STUNFISK]: 2,
|
||||||
|
[Species.GALAR_MR_MIME]: 3,
|
||||||
|
[Species.GALAR_ARTICUNO]: 6,
|
||||||
|
[Species.GALAR_ZAPDOS]: 6,
|
||||||
|
[Species.GALAR_MOLTRES]: 6,
|
||||||
|
[Species.HISUI_GROWLITHE]: 4,
|
||||||
|
[Species.HISUI_VOLTORB]: 3,
|
||||||
|
[Species.HISUI_QWILFISH]: 4,
|
||||||
|
[Species.HISUI_SNEASEL]: 5,
|
||||||
|
[Species.HISUI_ZORUA]: 3,
|
||||||
|
[Species.ENAMORUS]: 7,
|
||||||
|
|
||||||
|
[Species.SPRIGATITO]: 4,
|
||||||
|
[Species.FUECOCO]: 4,
|
||||||
|
[Species.QUAXLY]: 4,
|
||||||
|
[Species.LECHONK]: 2,
|
||||||
|
[Species.TAROUNTULA]: 1,
|
||||||
|
[Species.NYMBLE]: 3,
|
||||||
|
[Species.PAWMI]: 3,
|
||||||
|
[Species.TANDEMAUS]: 4,
|
||||||
|
[Species.FIDOUGH]: 2,
|
||||||
|
[Species.SMOLIV]: 3,
|
||||||
|
[Species.SQUAWKABILLY]: 2,
|
||||||
|
[Species.NACLI]: 4,
|
||||||
|
[Species.CHARCADET]: 4,
|
||||||
|
[Species.TADBULB]: 3,
|
||||||
|
[Species.WATTREL]: 3,
|
||||||
|
[Species.MASCHIFF]: 3,
|
||||||
|
[Species.SHROODLE]: 2,
|
||||||
|
[Species.BRAMBLIN]: 3,
|
||||||
|
[Species.TOEDSCOOL]: 3,
|
||||||
|
[Species.KLAWF]: 3,
|
||||||
|
[Species.CAPSAKID]: 3,
|
||||||
|
[Species.RELLOR]: 2,
|
||||||
|
[Species.FLITTLE]: 3,
|
||||||
|
[Species.TINKATINK]: 4,
|
||||||
|
[Species.WIGLETT]: 2,
|
||||||
|
[Species.BOMBIRDIER]: 3,
|
||||||
|
[Species.FINIZEN]: 3,
|
||||||
|
[Species.VAROOM]: 4,
|
||||||
|
[Species.CYCLIZAR]: 4,
|
||||||
|
[Species.ORTHWORM]: 4,
|
||||||
|
[Species.GLIMMET]: 4,
|
||||||
|
[Species.GREAVARD]: 3,
|
||||||
|
[Species.FLAMIGO]: 4,
|
||||||
|
[Species.CETODDLE]: 3,
|
||||||
|
[Species.VELUZA]: 4,
|
||||||
|
[Species.DONDOZO]: 4,
|
||||||
|
[Species.TATSUGIRI]: 4,
|
||||||
|
[Species.GREAT_TUSK]: 6,
|
||||||
|
[Species.SCREAM_TAIL]: 6,
|
||||||
|
[Species.BRUTE_BONNET]: 6,
|
||||||
|
[Species.FLUTTER_MANE]: 7,
|
||||||
|
[Species.SLITHER_WING]: 6,
|
||||||
|
[Species.SANDY_SHOCKS]: 6,
|
||||||
|
[Species.IRON_TREADS]: 6,
|
||||||
|
[Species.IRON_BUNDLE]: 6,
|
||||||
|
[Species.IRON_HANDS]: 6,
|
||||||
|
[Species.IRON_JUGULIS]: 6,
|
||||||
|
[Species.IRON_MOTH]: 6,
|
||||||
|
[Species.IRON_THORNS]: 6,
|
||||||
|
[Species.FRIGIBAX]: 4,
|
||||||
|
[Species.GIMMIGHOUL]: 4,
|
||||||
|
[Species.WO_CHIEN]: 6,
|
||||||
|
[Species.CHIEN_PAO]: 7,
|
||||||
|
[Species.TING_LU]: 6,
|
||||||
|
[Species.CHI_YU]: 7,
|
||||||
|
[Species.ROARING_MOON]: 6,
|
||||||
|
[Species.IRON_VALIANT]: 6,
|
||||||
|
[Species.KORAIDON]: 9,
|
||||||
|
[Species.MIRAIDON]: 9,
|
||||||
|
[Species.WALKING_WAKE]: 6,
|
||||||
|
[Species.IRON_LEAVES]: 6,
|
||||||
|
[Species.POLTCHAGEIST]: 4,
|
||||||
|
[Species.OKIDOGI]: 6,
|
||||||
|
[Species.MUNKIDORI]: 6,
|
||||||
|
[Species.FEZANDIPITI]: 6,
|
||||||
|
[Species.OGERPON]: 7,
|
||||||
|
[Species.GOUGING_FIRE]: 7,
|
||||||
|
[Species.RAGING_BOLT]: 6,
|
||||||
|
[Species.IRON_BOULDER]: 7,
|
||||||
|
[Species.IRON_CROWN]: 6,
|
||||||
|
[Species.TERAPAGOS]: 8,
|
||||||
|
[Species.PECHARUNT]: 6,
|
||||||
|
[Species.PALDEA_TAUROS]: 5,
|
||||||
|
[Species.PALDEA_WOOPER]: 3,
|
||||||
|
[Species.BLOODMOON_URSALUNA]: 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
const starterCandyCosts: { passive: number; costReduction: [number, number]; egg: number; }[] = [
|
||||||
|
{ passive: 40, costReduction: [ 25, 60 ], egg: 30 }, // 1 Cost
|
||||||
|
{ passive: 40, costReduction: [ 25, 60 ], egg: 30 }, // 2 Cost
|
||||||
|
{ passive: 35, costReduction: [ 20, 50 ], egg: 25 }, // 3 Cost
|
||||||
|
{ passive: 30, costReduction: [ 15, 40 ], egg: 20 }, // 4 Cost
|
||||||
|
{ passive: 25, costReduction: [ 12, 35 ], egg: 18 }, // 5 Cost
|
||||||
|
{ passive: 20, costReduction: [ 10, 30 ], egg: 15 }, // 6 Cost
|
||||||
|
{ passive: 15, costReduction: [ 8, 20 ], egg: 12 }, // 7 Cost
|
||||||
|
{ passive: 10, costReduction: [ 5, 15 ], egg: 10 }, // 8 Cost
|
||||||
|
{ passive: 10, costReduction: [ 5, 15 ], egg: 10 }, // 9 Cost
|
||||||
|
{ passive: 10, costReduction: [ 5, 15 ], egg: 10 }, // 10 Cost
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for {@linkcode starterCandyCosts} for passive unlock candy cost based on initial point cost
|
||||||
|
* @param starterCost the default point cost of the starter found in {@linkcode speciesStarterCosts}
|
||||||
|
* @returns the candy cost for passive unlock
|
||||||
|
*/
|
||||||
|
export function getPassiveCandyCount(starterCost: number): number {
|
||||||
|
return starterCandyCosts[starterCost - 1].passive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for {@linkcode starterCandyCosts} for value reduction unlock candy cost based on initial point cost
|
||||||
|
* @param starterCost the default point cost of the starter found in {@linkcode speciesStarterCosts}
|
||||||
|
* @returns respective candy cost for the two cost reductions as an array 2 numbers
|
||||||
|
*/
|
||||||
|
export function getValueReductionCandyCounts(starterCost: number): [number, number] {
|
||||||
|
return starterCandyCosts[starterCost - 1].costReduction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for {@linkcode starterCandyCosts} for egg purchase candy cost based on initial point cost
|
||||||
|
* @param starterCost the default point cost of the starter found in {@linkcode speciesStarterCosts}
|
||||||
|
* @returns the candy cost for the purchasable egg
|
||||||
|
*/
|
||||||
|
export function getSameSpeciesEggCandyCounts(starterCost: number): number {
|
||||||
|
return starterCandyCosts[starterCost - 1].egg;
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
import { ModifierTier } from "../modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
|
|
@ -2123,7 +2123,36 @@ export class StockpilingTag extends BattlerTag {
|
|||||||
*/
|
*/
|
||||||
export class GulpMissileTag extends BattlerTag {
|
export class GulpMissileTag extends BattlerTag {
|
||||||
constructor(tagType: BattlerTagType, sourceMove: Moves) {
|
constructor(tagType: BattlerTagType, sourceMove: Moves) {
|
||||||
super(tagType, BattlerTagLapseType.CUSTOM, 0, sourceMove);
|
super(tagType, BattlerTagLapseType.HIT, 0, sourceMove);
|
||||||
|
}
|
||||||
|
|
||||||
|
override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
|
if (pokemon.getTag(BattlerTagType.UNDERWATER)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const moveEffectPhase = pokemon.scene.getCurrentPhase();
|
||||||
|
if (moveEffectPhase instanceof MoveEffectPhase) {
|
||||||
|
const attacker = moveEffectPhase.getUserPokemon();
|
||||||
|
|
||||||
|
if (!attacker) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
|
applyAbAttrs(BlockNonDirectDamageAbAttr, attacker, cancelled);
|
||||||
|
|
||||||
|
if (!cancelled.value) {
|
||||||
|
attacker.damageAndUpdate(Math.max(1, Math.floor(attacker.getMaxHp() / 4)), HitResult.OTHER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.tagType === BattlerTagType.GULP_MISSILE_ARROKUDA) {
|
||||||
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, attacker.getBattlerIndex(), false, [ Stat.DEF ], -1));
|
||||||
|
} else {
|
||||||
|
attacker.trySetStatus(StatusEffect.PARALYSIS, true, pokemon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2238,7 +2267,7 @@ export class HealBlockTag extends MoveRestrictionBattlerTag {
|
|||||||
* Uses DisabledTag's selectionDeniedText() message
|
* Uses DisabledTag's selectionDeniedText() message
|
||||||
*/
|
*/
|
||||||
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
|
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
|
||||||
return i18next.t("battle:moveDisabled", { moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledHealBlock", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name, healBlockName: allMoves[Moves.HEAL_BLOCK].name });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2248,7 +2277,7 @@ export class HealBlockTag extends MoveRestrictionBattlerTag {
|
|||||||
* @returns {string} text to display when the move is interrupted
|
* @returns {string} text to display when the move is interrupted
|
||||||
*/
|
*/
|
||||||
override interruptedText(pokemon: Pokemon, move: Moves): string {
|
override interruptedText(pokemon: Pokemon, move: Moves): string {
|
||||||
return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledHealBlock", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name, healBlockName: allMoves[Moves.HEAL_BLOCK].name });
|
||||||
}
|
}
|
||||||
|
|
||||||
override onRemove(pokemon: Pokemon): void {
|
override onRemove(pokemon: Pokemon): void {
|
||||||
@ -2501,8 +2530,8 @@ export class TormentTag extends MoveRestrictionBattlerTag {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
override selectionDeniedText(_pokemon: Pokemon, move: Moves): string {
|
override selectionDeniedText(pokemon: Pokemon, _move: Moves): string {
|
||||||
return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledTorment", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2530,12 +2559,12 @@ export class TauntTag extends MoveRestrictionBattlerTag {
|
|||||||
return allMoves[move].category === MoveCategory.STATUS;
|
return allMoves[move].category === MoveCategory.STATUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
override selectionDeniedText(_pokemon: Pokemon, move: Moves): string {
|
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
|
||||||
return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledTaunt", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
||||||
}
|
}
|
||||||
|
|
||||||
override interruptedText(pokemon: Pokemon, move: Moves): string {
|
override interruptedText(pokemon: Pokemon, move: Moves): string {
|
||||||
return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledTaunt", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2580,15 +2609,52 @@ export class ImprisonTag extends MoveRestrictionBattlerTag {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
override selectionDeniedText(_pokemon: Pokemon, move: Moves): string {
|
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
|
||||||
return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledImprison", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
||||||
}
|
}
|
||||||
|
|
||||||
override interruptedText(pokemon: Pokemon, move: Moves): string {
|
override interruptedText(pokemon: Pokemon, move: Moves): string {
|
||||||
return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledImprison", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Battler Tag that applies the effects of Syrup Bomb to the target Pokemon.
|
||||||
|
* For three turns, starting from the turn of hit, at the end of each turn, the target Pokemon's speed will decrease by 1.
|
||||||
|
* The tag can also expire by taking the target Pokemon off the field.
|
||||||
|
*/
|
||||||
|
export class SyrupBombTag extends BattlerTag {
|
||||||
|
constructor() {
|
||||||
|
super(BattlerTagType.SYRUP_BOMB, BattlerTagLapseType.TURN_END, 3, Moves.SYRUP_BOMB);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the Syrup Bomb battler tag to the target Pokemon.
|
||||||
|
* @param {Pokemon} pokemon the target Pokemon
|
||||||
|
*/
|
||||||
|
override onAdd(pokemon: Pokemon) {
|
||||||
|
super.onAdd(pokemon);
|
||||||
|
pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the single-stage speed down to the target Pokemon and decrements the tag's turn count
|
||||||
|
* @param {Pokemon} pokemon the target Pokemon
|
||||||
|
* @param {BattlerTagLapseType} _lapseType
|
||||||
|
* @returns `true` if the turnCount is still greater than 0 | `false` if the turnCount is 0 or the target Pokemon has been removed from the field
|
||||||
|
*/
|
||||||
|
override lapse(pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean {
|
||||||
|
if (!pokemon.isActive(true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); // Custom message in lieu of an animation in mainline
|
||||||
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(
|
||||||
|
pokemon.scene, pokemon.getBattlerIndex(), true,
|
||||||
|
[ Stat.SPD ], -1, true, false, true
|
||||||
|
));
|
||||||
|
return --this.turnCount > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a {@linkcode BattlerTag} based on the provided tag type, turn count, source move, and source ID.
|
* Retrieves a {@linkcode BattlerTag} based on the provided tag type, turn count, source move, and source ID.
|
||||||
@ -2763,6 +2829,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
|
|||||||
return new TauntTag();
|
return new TauntTag();
|
||||||
case BattlerTagType.IMPRISON:
|
case BattlerTagType.IMPRISON:
|
||||||
return new ImprisonTag(sourceId);
|
return new ImprisonTag(sourceId);
|
||||||
|
case BattlerTagType.SYRUP_BOMB:
|
||||||
|
return new SyrupBombTag();
|
||||||
case BattlerTagType.NONE:
|
case BattlerTagType.NONE:
|
||||||
default:
|
default:
|
||||||
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
|
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
import * as Utils from "../utils";
|
import * as Utils from "#app/utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { defaultStarterSpecies, DexAttrProps, GameData } from "#app/system/game-data";
|
import { defaultStarterSpecies, DexAttrProps, GameData } from "#app/system/game-data";
|
||||||
import PokemonSpecies, { getPokemonSpecies, getPokemonSpeciesForm, speciesStarters } from "./pokemon-species";
|
import PokemonSpecies, { getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
|
||||||
|
import { speciesStarterCosts } from "#app/data/balance/starters";
|
||||||
import Pokemon, { PokemonMove } from "#app/field/pokemon";
|
import Pokemon, { PokemonMove } from "#app/field/pokemon";
|
||||||
import { BattleType, FixedBattleConfig } from "#app/battle";
|
import { BattleType, FixedBattleConfig } from "#app/battle";
|
||||||
import Trainer, { TrainerVariant } from "#app/field/trainer";
|
import Trainer, { TrainerVariant } from "#app/field/trainer";
|
||||||
import { GameMode } from "#app/game-mode";
|
import { GameMode } from "#app/game-mode";
|
||||||
import { Type } from "./type";
|
import { Type } from "#app/data/type";
|
||||||
import { Challenges } from "#enums/challenges";
|
import { Challenges } from "#enums/challenges";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import { Nature } from "./nature";
|
import { Nature } from "#app/data/nature";
|
||||||
import { Moves } from "#app/enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { TypeColor, TypeShadow } from "#app/enums/color";
|
import { TypeColor, TypeShadow } from "#enums/color";
|
||||||
import { pokemonEvolutions } from "./pokemon-evolutions";
|
import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
import { pokemonFormChanges } from "./pokemon-forms";
|
import { pokemonFormChanges } from "#app/data/pokemon-forms";
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
|
|
||||||
/** A constant for the default max cost of the starting party before a run */
|
/** A constant for the default max cost of the starting party before a run */
|
||||||
@ -814,7 +815,7 @@ export class FreshStartChallenge extends Challenge {
|
|||||||
|
|
||||||
applyStarterCost(species: Species, cost: Utils.NumberHolder): boolean {
|
applyStarterCost(species: Species, cost: Utils.NumberHolder): boolean {
|
||||||
if (defaultStarterSpecies.includes(species)) {
|
if (defaultStarterSpecies.includes(species)) {
|
||||||
cost.value = speciesStarters[species];
|
cost.value = speciesStarterCosts[species];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -896,7 +897,7 @@ export class LowerStarterMaxCostChallenge extends Challenge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder): boolean {
|
applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder): boolean {
|
||||||
if (speciesStarters[pokemon.speciesId] > DEFAULT_PARTY_MAX_COST - this.value) {
|
if (speciesStarterCosts[pokemon.speciesId] > DEFAULT_PARTY_MAX_COST - this.value) {
|
||||||
valid.value = false;
|
valid.value = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import BattleScene from "../battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import { PlayerPokemon } from "../field/pokemon";
|
import { PlayerPokemon } from "#app/field/pokemon";
|
||||||
import { Starter } from "../ui/starter-select-ui-handler";
|
import { Starter } from "#app/ui/starter-select-ui-handler";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "#app/utils";
|
||||||
import PokemonSpecies, { PokemonSpeciesForm, getPokemonSpecies, getPokemonSpeciesForm, speciesStarters } from "./pokemon-species";
|
import PokemonSpecies, { PokemonSpeciesForm, getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
|
||||||
|
import { speciesStarterCosts } from "#app/data/balance/starters";
|
||||||
|
|
||||||
export interface DailyRunConfig {
|
export interface DailyRunConfig {
|
||||||
seed: integer;
|
seed: integer;
|
||||||
@ -46,9 +47,9 @@ export function getDailyRunStarters(scene: BattleScene, seed: string): Starter[]
|
|||||||
|
|
||||||
for (let c = 0; c < starterCosts.length; c++) {
|
for (let c = 0; c < starterCosts.length; c++) {
|
||||||
const cost = starterCosts[c];
|
const cost = starterCosts[c];
|
||||||
const costSpecies = Object.keys(speciesStarters)
|
const costSpecies = Object.keys(speciesStarterCosts)
|
||||||
.map(s => parseInt(s) as Species)
|
.map(s => parseInt(s) as Species)
|
||||||
.filter(s => speciesStarters[s] === cost);
|
.filter(s => speciesStarterCosts[s] === cost);
|
||||||
const randPkmSpecies = getPokemonSpecies(Utils.randSeedItem(costSpecies));
|
const randPkmSpecies = getPokemonSpecies(Utils.randSeedItem(costSpecies));
|
||||||
const starterSpecies = getPokemonSpecies(randPkmSpecies.getTrainerSpeciesForLevel(startingLevel, true, PartyMemberStrength.STRONGER));
|
const starterSpecies = getPokemonSpecies(randPkmSpecies.getTrainerSpeciesForLevel(startingLevel, true, PartyMemberStrength.STRONGER));
|
||||||
starters.push(getDailyRunStarter(scene, starterSpecies, startingLevel));
|
starters.push(getDailyRunStarter(scene, starterSpecies, startingLevel));
|
||||||
|
@ -1,30 +1,19 @@
|
|||||||
import BattleScene from "../battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import PokemonSpecies, { getPokemonSpecies, speciesStarters } from "./pokemon-species";
|
import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
import { VariantTier } from "../enums/variant-tier";
|
import { speciesStarterCosts } from "#app/data/balance/starters";
|
||||||
import * as Utils from "../utils";
|
import { VariantTier } from "#enums/variant-tier";
|
||||||
|
import * as Utils from "#app/utils";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
import { pokemonPrevolutions } from "./pokemon-evolutions";
|
import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
import { PlayerPokemon } from "#app/field/pokemon";
|
import { PlayerPokemon } from "#app/field/pokemon";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { EggTier } from "#enums/egg-type";
|
import { EggTier } from "#enums/egg-type";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { EggSourceType } from "#app/enums/egg-source-types";
|
import { EggSourceType } from "#enums/egg-source-types";
|
||||||
|
import { MANAPHY_EGG_MANAPHY_RATE, SAME_SPECIES_EGG_HA_RATE, GACHA_EGG_HA_RATE, GACHA_DEFAULT_RARE_EGGMOVE_RATE, SAME_SPECIES_EGG_RARE_EGGMOVE_RATE, GACHA_MOVE_UP_RARE_EGGMOVE_RATE, GACHA_DEFAULT_SHINY_RATE, GACHA_SHINY_UP_SHINY_RATE, SAME_SPECIES_EGG_SHINY_RATE, EGG_PITY_LEGENDARY_THRESHOLD, EGG_PITY_EPIC_THRESHOLD, EGG_PITY_RARE_THRESHOLD, SHINY_VARIANT_CHANCE, SHINY_EPIC_CHANCE, GACHA_DEFAULT_COMMON_EGG_THRESHOLD, GACHA_DEFAULT_RARE_EGG_THRESHOLD, GACHA_DEFAULT_EPIC_EGG_THRESHOLD, GACHA_LEGENDARY_UP_THRESHOLD_OFFSET, HATCH_WAVES_MANAPHY_EGG, HATCH_WAVES_COMMON_EGG, HATCH_WAVES_RARE_EGG, HATCH_WAVES_EPIC_EGG, HATCH_WAVES_LEGENDARY_EGG } from "#app/data/balance/rates";
|
||||||
|
|
||||||
export const EGG_SEED = 1073741824;
|
export const EGG_SEED = 1073741824;
|
||||||
|
|
||||||
// Rates for specific random properties in 1/x
|
|
||||||
const DEFAULT_SHINY_RATE = 128;
|
|
||||||
const GACHA_SHINY_UP_SHINY_RATE = 64;
|
|
||||||
const SAME_SPECIES_EGG_SHINY_RATE = 12;
|
|
||||||
const SAME_SPECIES_EGG_HA_RATE = 8;
|
|
||||||
const MANAPHY_EGG_MANAPHY_RATE = 8;
|
|
||||||
const GACHA_EGG_HA_RATE = 192;
|
|
||||||
|
|
||||||
// 1/x for legendary eggs, 1/x*2 for epic eggs, 1/x*4 for rare eggs, and 1/x*8 for common eggs
|
|
||||||
const DEFAULT_RARE_EGGMOVE_RATE = 6;
|
|
||||||
const SAME_SPECIES_EGG_RARE_EGGMOVE_RATE = 3;
|
|
||||||
const GACHA_MOVE_UP_RARE_EGGMOVE_RATE = 3;
|
|
||||||
|
|
||||||
/** Egg options to override egg properties */
|
/** Egg options to override egg properties */
|
||||||
export interface IEggOptions {
|
export interface IEggOptions {
|
||||||
/** Id. Used to check if egg type will be manaphy (id % 204 === 0) */
|
/** Id. Used to check if egg type will be manaphy (id % 204 === 0) */
|
||||||
@ -323,7 +312,7 @@ export class Egg {
|
|||||||
////
|
////
|
||||||
|
|
||||||
private rollEggMoveIndex() {
|
private rollEggMoveIndex() {
|
||||||
let baseChance = DEFAULT_RARE_EGGMOVE_RATE;
|
let baseChance = GACHA_DEFAULT_RARE_EGGMOVE_RATE;
|
||||||
switch (this._sourceType) {
|
switch (this._sourceType) {
|
||||||
case EggSourceType.SAME_SPECIES_EGG:
|
case EggSourceType.SAME_SPECIES_EGG:
|
||||||
baseChance = SAME_SPECIES_EGG_RARE_EGGMOVE_RATE;
|
baseChance = SAME_SPECIES_EGG_RARE_EGGMOVE_RATE;
|
||||||
@ -341,24 +330,24 @@ export class Egg {
|
|||||||
|
|
||||||
private getEggTierDefaultHatchWaves(eggTier?: EggTier): number {
|
private getEggTierDefaultHatchWaves(eggTier?: EggTier): number {
|
||||||
if (this._species === Species.PHIONE || this._species === Species.MANAPHY) {
|
if (this._species === Species.PHIONE || this._species === Species.MANAPHY) {
|
||||||
return 50;
|
return HATCH_WAVES_MANAPHY_EGG;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (eggTier ?? this._tier) {
|
switch (eggTier ?? this._tier) {
|
||||||
case EggTier.COMMON:
|
case EggTier.COMMON:
|
||||||
return 10;
|
return HATCH_WAVES_COMMON_EGG;
|
||||||
case EggTier.GREAT:
|
case EggTier.GREAT:
|
||||||
return 25;
|
return HATCH_WAVES_RARE_EGG;
|
||||||
case EggTier.ULTRA:
|
case EggTier.ULTRA:
|
||||||
return 50;
|
return HATCH_WAVES_EPIC_EGG;
|
||||||
}
|
}
|
||||||
return 100;
|
return HATCH_WAVES_LEGENDARY_EGG;
|
||||||
}
|
}
|
||||||
|
|
||||||
private rollEggTier(): EggTier {
|
private rollEggTier(): EggTier {
|
||||||
const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? 1 : 0;
|
const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0;
|
||||||
const tierValue = Utils.randInt(256);
|
const tierValue = Utils.randInt(256);
|
||||||
return tierValue >= 52 + tierValueOffset ? EggTier.COMMON : tierValue >= 8 + tierValueOffset ? EggTier.GREAT : tierValue >= 1 + tierValueOffset ? EggTier.ULTRA : EggTier.MASTER;
|
return tierValue >= GACHA_DEFAULT_COMMON_EGG_THRESHOLD + tierValueOffset ? EggTier.COMMON : tierValue >= GACHA_DEFAULT_RARE_EGG_THRESHOLD + tierValueOffset ? EggTier.GREAT : tierValue >= GACHA_DEFAULT_EPIC_EGG_THRESHOLD + tierValueOffset ? EggTier.ULTRA : EggTier.MASTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
private rollSpecies(scene: BattleScene): Species | null {
|
private rollSpecies(scene: BattleScene): Species | null {
|
||||||
@ -409,8 +398,8 @@ export class Egg {
|
|||||||
|
|
||||||
const ignoredSpecies = [ Species.PHIONE, Species.MANAPHY, Species.ETERNATUS ];
|
const ignoredSpecies = [ Species.PHIONE, Species.MANAPHY, Species.ETERNATUS ];
|
||||||
|
|
||||||
let speciesPool = Object.keys(speciesStarters)
|
let speciesPool = Object.keys(speciesStarterCosts)
|
||||||
.filter(s => speciesStarters[s] >= minStarterValue && speciesStarters[s] <= maxStarterValue)
|
.filter(s => speciesStarterCosts[s] >= minStarterValue && speciesStarterCosts[s] <= maxStarterValue)
|
||||||
.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);
|
||||||
|
|
||||||
@ -441,7 +430,7 @@ export class Egg {
|
|||||||
let totalWeight = 0;
|
let totalWeight = 0;
|
||||||
const speciesWeights : number[] = [];
|
const speciesWeights : number[] = [];
|
||||||
for (const speciesId of speciesPool) {
|
for (const speciesId of speciesPool) {
|
||||||
let weight = Math.floor((((maxStarterValue - speciesStarters[speciesId]) / ((maxStarterValue - minStarterValue) + 1)) * 1.5 + 1) * 100);
|
let weight = Math.floor((((maxStarterValue - speciesStarterCosts[speciesId]) / ((maxStarterValue - minStarterValue) + 1)) * 1.5 + 1) * 100);
|
||||||
const species = getPokemonSpecies(speciesId);
|
const species = getPokemonSpecies(speciesId);
|
||||||
if (species.isRegional()) {
|
if (species.isRegional()) {
|
||||||
weight = Math.floor(weight / 2);
|
weight = Math.floor(weight / 2);
|
||||||
@ -475,7 +464,7 @@ export class Egg {
|
|||||||
* @returns True if the egg is shiny
|
* @returns True if the egg is shiny
|
||||||
**/
|
**/
|
||||||
private rollShiny(): boolean {
|
private rollShiny(): boolean {
|
||||||
let shinyChance = DEFAULT_SHINY_RATE;
|
let shinyChance = GACHA_DEFAULT_SHINY_RATE;
|
||||||
switch (this._sourceType) {
|
switch (this._sourceType) {
|
||||||
case EggSourceType.GACHA_SHINY:
|
case EggSourceType.GACHA_SHINY:
|
||||||
shinyChance = GACHA_SHINY_UP_SHINY_RATE;
|
shinyChance = GACHA_SHINY_UP_SHINY_RATE;
|
||||||
@ -498,9 +487,9 @@ export class Egg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const rand = Utils.randSeedInt(10);
|
const rand = Utils.randSeedInt(10);
|
||||||
if (rand >= 4) {
|
if (rand >= SHINY_VARIANT_CHANCE) {
|
||||||
return VariantTier.STANDARD; // 6/10
|
return VariantTier.STANDARD; // 6/10
|
||||||
} else if (rand >= 1) {
|
} else if (rand >= SHINY_EPIC_CHANCE) {
|
||||||
return VariantTier.RARE; // 3/10
|
return VariantTier.RARE; // 3/10
|
||||||
} else {
|
} else {
|
||||||
return VariantTier.EPIC; // 1/10
|
return VariantTier.EPIC; // 1/10
|
||||||
@ -508,16 +497,16 @@ export class Egg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private checkForPityTierOverrides(scene: BattleScene): void {
|
private checkForPityTierOverrides(scene: BattleScene): void {
|
||||||
const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? 1 : 0;
|
const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0;
|
||||||
scene.gameData.eggPity[EggTier.GREAT] += 1;
|
scene.gameData.eggPity[EggTier.GREAT] += 1;
|
||||||
scene.gameData.eggPity[EggTier.ULTRA] += 1;
|
scene.gameData.eggPity[EggTier.ULTRA] += 1;
|
||||||
scene.gameData.eggPity[EggTier.MASTER] += 1 + tierValueOffset;
|
scene.gameData.eggPity[EggTier.MASTER] += 1 + tierValueOffset;
|
||||||
// These numbers are roughly the 80% mark. That is, 80% of the time you'll get an egg before this gets triggered.
|
// These numbers are roughly the 80% mark. That is, 80% of the time you'll get an egg before this gets triggered.
|
||||||
if (scene.gameData.eggPity[EggTier.MASTER] >= 412 && this._tier === EggTier.COMMON) {
|
if (scene.gameData.eggPity[EggTier.MASTER] >= EGG_PITY_LEGENDARY_THRESHOLD && this._tier === EggTier.COMMON) {
|
||||||
this._tier = EggTier.MASTER;
|
this._tier = EggTier.MASTER;
|
||||||
} else if (scene.gameData.eggPity[EggTier.ULTRA] >= 59 && this._tier === EggTier.COMMON) {
|
} else if (scene.gameData.eggPity[EggTier.ULTRA] >= EGG_PITY_EPIC_THRESHOLD && this._tier === EggTier.COMMON) {
|
||||||
this._tier = EggTier.ULTRA;
|
this._tier = EggTier.ULTRA;
|
||||||
} else if (scene.gameData.eggPity[EggTier.GREAT] >= 9 && this._tier === EggTier.COMMON) {
|
} else if (scene.gameData.eggPity[EggTier.GREAT] >= EGG_PITY_RARE_THRESHOLD && this._tier === EggTier.COMMON) {
|
||||||
this._tier = EggTier.GREAT;
|
this._tier = EggTier.GREAT;
|
||||||
}
|
}
|
||||||
scene.gameData.eggPity[this._tier] = 0;
|
scene.gameData.eggPity[this._tier] = 0;
|
||||||
@ -544,7 +533,7 @@ export class Egg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getEggTierFromSpeciesStarterValue(): EggTier {
|
private getEggTierFromSpeciesStarterValue(): EggTier {
|
||||||
const speciesStartValue = speciesStarters[this.species];
|
const speciesStartValue = speciesStarterCosts[this.species];
|
||||||
if (speciesStartValue >= 1 && speciesStartValue <= 3) {
|
if (speciesStartValue >= 1 && speciesStartValue <= 3) {
|
||||||
return EggTier.COMMON;
|
return EggTier.COMMON;
|
||||||
}
|
}
|
||||||
@ -567,7 +556,7 @@ export class Egg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timestamp: number): Species {
|
export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timestamp: number): Species {
|
||||||
const legendarySpecies = Object.entries(speciesStarters)
|
const legendarySpecies = Object.entries(speciesStarterCosts)
|
||||||
.filter(s => s[1] >= 8 && s[1] <= 9)
|
.filter(s => s[1] >= 8 && s[1] <= 9)
|
||||||
.map(s => parseInt(s[0]))
|
.map(s => parseInt(s[0]))
|
||||||
.filter(s => getPokemonSpecies(s).isObtainable());
|
.filter(s => getPokemonSpecies(s).isObtainable());
|
||||||
@ -594,7 +583,7 @@ export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timesta
|
|||||||
* @returns The egg tier of a given pokemon species
|
* @returns The egg tier of a given pokemon species
|
||||||
*/
|
*/
|
||||||
export function getEggTierForSpecies(pokemonSpecies :PokemonSpecies): EggTier {
|
export function getEggTierForSpecies(pokemonSpecies :PokemonSpecies): EggTier {
|
||||||
const speciesBaseValue = speciesStarters[pokemonSpecies.getRootSpeciesId()];
|
const speciesBaseValue = speciesStarterCosts[pokemonSpecies.getRootSpeciesId()];
|
||||||
if (speciesBaseValue <= 3) {
|
if (speciesBaseValue <= 3) {
|
||||||
return EggTier.COMMON;
|
return EggTier.COMMON;
|
||||||
} else if (speciesBaseValue <= 5) {
|
} else if (speciesBaseValue <= 5) {
|
||||||
|
275
src/data/move.ts
275
src/data/move.ts
@ -25,7 +25,6 @@ import { Moves } from "#enums/moves";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { MoveUsedEvent } from "#app/events/battle-scene";
|
import { MoveUsedEvent } from "#app/events/battle-scene";
|
||||||
import { BATTLE_STATS, type BattleStat, EFFECTIVE_STATS, type EffectiveStat, getStatKey, Stat } from "#app/enums/stat";
|
import { BATTLE_STATS, type BattleStat, EFFECTIVE_STATS, type EffectiveStat, getStatKey, Stat } from "#app/enums/stat";
|
||||||
import { PartyStatusCurePhase } from "#app/phases/party-status-cure-phase";
|
|
||||||
import { BattleEndPhase } from "#app/phases/battle-end-phase";
|
import { BattleEndPhase } from "#app/phases/battle-end-phase";
|
||||||
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
||||||
import { MovePhase } from "#app/phases/move-phase";
|
import { MovePhase } from "#app/phases/move-phase";
|
||||||
@ -34,6 +33,7 @@ import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
|
|||||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
import { SwitchPhase } from "#app/phases/switch-phase";
|
import { SwitchPhase } from "#app/phases/switch-phase";
|
||||||
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase";
|
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase";
|
||||||
|
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
||||||
import { SpeciesFormChangeRevertWeatherFormTrigger } from "./pokemon-forms";
|
import { SpeciesFormChangeRevertWeatherFormTrigger } from "./pokemon-forms";
|
||||||
import { GameMode } from "#app/game-mode";
|
import { GameMode } from "#app/game-mode";
|
||||||
import { applyChallenges, ChallengeType } from "./challenge";
|
import { applyChallenges, ChallengeType } from "./challenge";
|
||||||
@ -341,7 +341,8 @@ export default class Move implements Localizable {
|
|||||||
* @returns `true` if the move can bypass the target's Substitute; `false` otherwise.
|
* @returns `true` if the move can bypass the target's Substitute; `false` otherwise.
|
||||||
*/
|
*/
|
||||||
hitsSubstitute(user: Pokemon, target: Pokemon | null): boolean {
|
hitsSubstitute(user: Pokemon, target: Pokemon | null): boolean {
|
||||||
if (this.moveTarget === MoveTarget.USER || !target?.getTag(BattlerTagType.SUBSTITUTE)) {
|
if ([ MoveTarget.USER, MoveTarget.USER_SIDE, MoveTarget.ENEMY_SIDE, MoveTarget.BOTH_SIDES ].includes(this.moveTarget)
|
||||||
|
|| !target?.getTag(BattlerTagType.SUBSTITUTE)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,220 +399,202 @@ export default class Move implements Localizable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.MAKES_CONTACT} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.MAKES_CONTACT} flag for the calling Move
|
||||||
* @param makesContact The value (boolean) to set the flag to
|
* @param setFlag Default `true`, set to `false` if the move doesn't make contact
|
||||||
|
* @see {@linkcode Abilities.STATIC}
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
makesContact(makesContact: boolean = true): this {
|
makesContact(setFlag: boolean = true): this {
|
||||||
this.setFlag(MoveFlags.MAKES_CONTACT, makesContact);
|
this.setFlag(MoveFlags.MAKES_CONTACT, setFlag);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.IGNORE_PROTECT} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.IGNORE_PROTECT} flag for the calling Move
|
||||||
* @param ignoresProtect The value (boolean) to set the flag to
|
* @see {@linkcode Moves.CURSE}
|
||||||
* example: @see {@linkcode Moves.CURSE}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
ignoresProtect(ignoresProtect: boolean = true): this {
|
ignoresProtect(): this {
|
||||||
this.setFlag(MoveFlags.IGNORE_PROTECT, ignoresProtect);
|
this.setFlag(MoveFlags.IGNORE_PROTECT, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.IGNORE_VIRTUAL} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.IGNORE_VIRTUAL} flag for the calling Move
|
||||||
* @param ignoresVirtual The value (boolean) to set the flag to
|
* @see {@linkcode Moves.NATURE_POWER}
|
||||||
* example: @see {@linkcode Moves.NATURE_POWER}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
ignoresVirtual(ignoresVirtual: boolean = true): this {
|
ignoresVirtual(): this {
|
||||||
this.setFlag(MoveFlags.IGNORE_VIRTUAL, ignoresVirtual);
|
this.setFlag(MoveFlags.IGNORE_VIRTUAL, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.SOUND_BASED} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.SOUND_BASED} flag for the calling Move
|
||||||
* @param soundBased The value (boolean) to set the flag to
|
* @see {@linkcode Moves.UPROAR}
|
||||||
* example: @see {@linkcode Moves.UPROAR}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
soundBased(soundBased: boolean = true): this {
|
soundBased(): this {
|
||||||
this.setFlag(MoveFlags.SOUND_BASED, soundBased);
|
this.setFlag(MoveFlags.SOUND_BASED, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.HIDE_USER} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.HIDE_USER} flag for the calling Move
|
||||||
* @param hidesUser The value (boolean) to set the flag to
|
* @see {@linkcode Moves.TELEPORT}
|
||||||
* example: @see {@linkcode Moves.TELEPORT}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
hidesUser(hidesUser: boolean = true): this {
|
hidesUser(): this {
|
||||||
this.setFlag(MoveFlags.HIDE_USER, hidesUser);
|
this.setFlag(MoveFlags.HIDE_USER, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.HIDE_TARGET} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.HIDE_TARGET} flag for the calling Move
|
||||||
* @param hidesTarget The value (boolean) to set the flag to
|
* @see {@linkcode Moves.WHIRLWIND}
|
||||||
* example: @see {@linkcode Moves.WHIRLWIND}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
hidesTarget(hidesTarget: boolean = true): this {
|
hidesTarget(): this {
|
||||||
this.setFlag(MoveFlags.HIDE_TARGET, hidesTarget);
|
this.setFlag(MoveFlags.HIDE_TARGET, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.BITING_MOVE} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.BITING_MOVE} flag for the calling Move
|
||||||
* @param bitingMove The value (boolean) to set the flag to
|
* @see {@linkcode Moves.BITE}
|
||||||
* example: @see {@linkcode Moves.BITE}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
bitingMove(bitingMove: boolean = true): this {
|
bitingMove(): this {
|
||||||
this.setFlag(MoveFlags.BITING_MOVE, bitingMove);
|
this.setFlag(MoveFlags.BITING_MOVE, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.PULSE_MOVE} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.PULSE_MOVE} flag for the calling Move
|
||||||
* @param pulseMove The value (boolean) to set the flag to
|
* @see {@linkcode Moves.WATER_PULSE}
|
||||||
* example: @see {@linkcode Moves.WATER_PULSE}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
pulseMove(pulseMove: boolean = true): this {
|
pulseMove(): this {
|
||||||
this.setFlag(MoveFlags.PULSE_MOVE, pulseMove);
|
this.setFlag(MoveFlags.PULSE_MOVE, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.PUNCHING_MOVE} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.PUNCHING_MOVE} flag for the calling Move
|
||||||
* @param punchingMove The value (boolean) to set the flag to
|
* @see {@linkcode Moves.DRAIN_PUNCH}
|
||||||
* example: @see {@linkcode Moves.DRAIN_PUNCH}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
punchingMove(punchingMove: boolean = true): this {
|
punchingMove(): this {
|
||||||
this.setFlag(MoveFlags.PUNCHING_MOVE, punchingMove);
|
this.setFlag(MoveFlags.PUNCHING_MOVE, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.SLICING_MOVE} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.SLICING_MOVE} flag for the calling Move
|
||||||
* @param slicingMove The value (boolean) to set the flag to
|
* @see {@linkcode Moves.X_SCISSOR}
|
||||||
* example: @see {@linkcode Moves.X_SCISSOR}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
slicingMove(slicingMove: boolean = true): this {
|
slicingMove(): this {
|
||||||
this.setFlag(MoveFlags.SLICING_MOVE, slicingMove);
|
this.setFlag(MoveFlags.SLICING_MOVE, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.RECKLESS_MOVE} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.RECKLESS_MOVE} flag for the calling Move
|
||||||
* @see {@linkcode Abilities.RECKLESS}
|
* @see {@linkcode Abilities.RECKLESS}
|
||||||
* @param recklessMove The value to set the flag to
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
recklessMove(recklessMove: boolean = true): this {
|
recklessMove(): this {
|
||||||
this.setFlag(MoveFlags.RECKLESS_MOVE, recklessMove);
|
this.setFlag(MoveFlags.RECKLESS_MOVE, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.BALLBOMB_MOVE} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.BALLBOMB_MOVE} flag for the calling Move
|
||||||
* @param ballBombMove The value (boolean) to set the flag to
|
* @see {@linkcode Moves.ELECTRO_BALL}
|
||||||
* example: @see {@linkcode Moves.ELECTRO_BALL}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
ballBombMove(ballBombMove: boolean = true): this {
|
ballBombMove(): this {
|
||||||
this.setFlag(MoveFlags.BALLBOMB_MOVE, ballBombMove);
|
this.setFlag(MoveFlags.BALLBOMB_MOVE, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.POWDER_MOVE} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.POWDER_MOVE} flag for the calling Move
|
||||||
* @param powderMove The value (boolean) to set the flag to
|
* @see {@linkcode Moves.STUN_SPORE}
|
||||||
* example: @see {@linkcode Moves.STUN_SPORE}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
powderMove(powderMove: boolean = true): this {
|
powderMove(): this {
|
||||||
this.setFlag(MoveFlags.POWDER_MOVE, powderMove);
|
this.setFlag(MoveFlags.POWDER_MOVE, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.DANCE_MOVE} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.DANCE_MOVE} flag for the calling Move
|
||||||
* @param danceMove The value (boolean) to set the flag to
|
* @see {@linkcode Moves.PETAL_DANCE}
|
||||||
* example: @see {@linkcode Moves.PETAL_DANCE}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
danceMove(danceMove: boolean = true): this {
|
danceMove(): this {
|
||||||
this.setFlag(MoveFlags.DANCE_MOVE, danceMove);
|
this.setFlag(MoveFlags.DANCE_MOVE, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.WIND_MOVE} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.WIND_MOVE} flag for the calling Move
|
||||||
* @param windMove The value (boolean) to set the flag to
|
* @see {@linkcode Moves.HURRICANE}
|
||||||
* example: @see {@linkcode Moves.HURRICANE}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
windMove(windMove: boolean = true): this {
|
windMove(): this {
|
||||||
this.setFlag(MoveFlags.WIND_MOVE, windMove);
|
this.setFlag(MoveFlags.WIND_MOVE, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.TRIAGE_MOVE} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.TRIAGE_MOVE} flag for the calling Move
|
||||||
* @param triageMove The value (boolean) to set the flag to
|
* @see {@linkcode Moves.ABSORB}
|
||||||
* example: @see {@linkcode Moves.ABSORB}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
triageMove(triageMove: boolean = true): this {
|
triageMove(): this {
|
||||||
this.setFlag(MoveFlags.TRIAGE_MOVE, triageMove);
|
this.setFlag(MoveFlags.TRIAGE_MOVE, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.IGNORE_ABILITIES} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.IGNORE_ABILITIES} flag for the calling Move
|
||||||
* @param ignoresAbilities sThe value (boolean) to set the flag to
|
* @see {@linkcode Moves.SUNSTEEL_STRIKE}
|
||||||
* example: @see {@linkcode Moves.SUNSTEEL_STRIKE}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
ignoresAbilities(ignoresAbilities: boolean = true): this {
|
ignoresAbilities(): this {
|
||||||
this.setFlag(MoveFlags.IGNORE_ABILITIES, ignoresAbilities);
|
this.setFlag(MoveFlags.IGNORE_ABILITIES, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.CHECK_ALL_HITS} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.CHECK_ALL_HITS} flag for the calling Move
|
||||||
* @param checkAllHits The value (boolean) to set the flag to
|
* @see {@linkcode Moves.TRIPLE_AXEL}
|
||||||
* example: @see {@linkcode Moves.TRIPLE_AXEL}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
checkAllHits(checkAllHits: boolean = true): this {
|
checkAllHits(): this {
|
||||||
this.setFlag(MoveFlags.CHECK_ALL_HITS, checkAllHits);
|
this.setFlag(MoveFlags.CHECK_ALL_HITS, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.IGNORE_SUBSTITUTE} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.IGNORE_SUBSTITUTE} flag for the calling Move
|
||||||
* @param ignoresSubstitute The value (boolean) to set the flag to
|
* @see {@linkcode Moves.WHIRLWIND}
|
||||||
* example: @see {@linkcode Moves.WHIRLWIND}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
ignoresSubstitute(ignoresSubstitute: boolean = true): this {
|
ignoresSubstitute(): this {
|
||||||
this.setFlag(MoveFlags.IGNORE_SUBSTITUTE, ignoresSubstitute);
|
this.setFlag(MoveFlags.IGNORE_SUBSTITUTE, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@linkcode MoveFlags.REDIRECT_COUNTER} flag for the calling Move
|
* Sets the {@linkcode MoveFlags.REDIRECT_COUNTER} flag for the calling Move
|
||||||
* @param redirectCounter The value (boolean) to set the flag to
|
* @see {@linkcode Moves.METAL_BURST}
|
||||||
* example: @see {@linkcode Moves.METAL_BURST}
|
|
||||||
* @returns The {@linkcode Move} that called this function
|
* @returns The {@linkcode Move} that called this function
|
||||||
*/
|
*/
|
||||||
redirectCounter(redirectCounter: boolean = true): this {
|
redirectCounter(): this {
|
||||||
this.setFlag(MoveFlags.REDIRECT_COUNTER, redirectCounter);
|
this.setFlag(MoveFlags.REDIRECT_COUNTER, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1602,12 +1585,31 @@ export class PartyStatusCureAttr extends MoveEffectAttr {
|
|||||||
if (!this.canApply(user, target, move, args)) {
|
if (!this.canApply(user, target, move, args)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.addPartyCurePhase(user);
|
const partyPokemon = user.isPlayer() ? user.scene.getParty() : user.scene.getEnemyParty();
|
||||||
|
partyPokemon.forEach(p => this.cureStatus(p, user.id));
|
||||||
|
|
||||||
|
if (this.message) {
|
||||||
|
user.scene.queueMessage(this.message);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
addPartyCurePhase(user: Pokemon) {
|
/**
|
||||||
user.scene.unshiftPhase(new PartyStatusCurePhase(user.scene, user, this.message, this.abilityCondition));
|
* Tries to cure the status of the given {@linkcode Pokemon}
|
||||||
|
* @param pokemon The {@linkcode Pokemon} to cure.
|
||||||
|
* @param userId The ID of the (move) {@linkcode Pokemon | user}.
|
||||||
|
*/
|
||||||
|
public cureStatus(pokemon: Pokemon, userId: number) {
|
||||||
|
if (!pokemon.isOnField() || pokemon.id === userId) { // user always cures its own status, regardless of ability
|
||||||
|
pokemon.resetStatus(false);
|
||||||
|
pokemon.updateInfo();
|
||||||
|
} else if (!pokemon.hasAbility(this.abilityCondition)) {
|
||||||
|
pokemon.resetStatus();
|
||||||
|
pokemon.updateInfo();
|
||||||
|
} else {
|
||||||
|
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.id, pokemon.getPassiveAbility()?.id === this.abilityCondition));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2685,20 +2687,42 @@ export class DelayedAttackAttr extends OverrideMoveEffectAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute used for moves that change stat stages
|
||||||
|
* @param stats {@linkcode BattleStat} array of stats to be changed
|
||||||
|
* @param stages stages by which to change the stats, from -6 to 6
|
||||||
|
* @param selfTarget whether the changes are applied to the user (true) or the target (false)
|
||||||
|
* @param condition {@linkcode MoveConditionFunc} optional condition to trigger the stat change
|
||||||
|
* @param firstHitOnly whether the stat change only applies on the first hit of a multi hit move
|
||||||
|
* @param moveEffectTrigger {@linkcode MoveEffectTrigger} the trigger for the effect to take place
|
||||||
|
* @param firstTargetOnly whether, if this is a multi target move, to only apply the effect after the first target is hit, rather than once for each target
|
||||||
|
* @param lastHitOnly whether the effect should only apply after the last hit of a multi hit move
|
||||||
|
*
|
||||||
|
* @extends MoveEffectAttr
|
||||||
|
* @see {@linkcode apply}
|
||||||
|
*/
|
||||||
export class StatStageChangeAttr extends MoveEffectAttr {
|
export class StatStageChangeAttr extends MoveEffectAttr {
|
||||||
public stats: BattleStat[];
|
public stats: BattleStat[];
|
||||||
public stages: integer;
|
public stages: integer;
|
||||||
private condition: MoveConditionFunc | null;
|
private condition: MoveConditionFunc | null;
|
||||||
private showMessage: boolean;
|
private showMessage: boolean;
|
||||||
|
|
||||||
constructor(stats: BattleStat[], stages: integer, selfTarget?: boolean, condition?: MoveConditionFunc | null, showMessage: boolean = true, firstHitOnly: boolean = false, moveEffectTrigger: MoveEffectTrigger = MoveEffectTrigger.HIT, firstTargetOnly: boolean = false) {
|
constructor(stats: BattleStat[], stages: integer, selfTarget?: boolean, condition?: MoveConditionFunc | null, showMessage: boolean = true, firstHitOnly: boolean = false, moveEffectTrigger: MoveEffectTrigger = MoveEffectTrigger.HIT, firstTargetOnly: boolean = false, lastHitOnly: boolean = false) {
|
||||||
super(selfTarget, moveEffectTrigger, firstHitOnly, false, firstTargetOnly);
|
super(selfTarget, moveEffectTrigger, firstHitOnly, lastHitOnly, firstTargetOnly);
|
||||||
this.stats = stats;
|
this.stats = stats;
|
||||||
this.stages = stages;
|
this.stages = stages;
|
||||||
this.condition = condition!; // TODO: is this bang correct?
|
this.condition = condition!; // TODO: is this bang correct?
|
||||||
this.showMessage = showMessage;
|
this.showMessage = showMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to change stats of the user or target (depending on value of selfTarget) if conditions are met
|
||||||
|
* @param user {@linkcode Pokemon} the user of the move
|
||||||
|
* @param target {@linkcode Pokemon} the target of the move
|
||||||
|
* @param move {@linkcode Move} the move
|
||||||
|
* @param args unused
|
||||||
|
* @returns whether stat stages were changed
|
||||||
|
*/
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args?: any[]): boolean | Promise<boolean> {
|
apply(user: Pokemon, target: Pokemon, move: Move, args?: any[]): boolean | Promise<boolean> {
|
||||||
if (!super.apply(user, target, move, args) || (this.condition && !this.condition(user, target, move))) {
|
if (!super.apply(user, target, move, args) || (this.condition && !this.condition(user, target, move))) {
|
||||||
return false;
|
return false;
|
||||||
@ -3918,7 +3942,14 @@ export class PhotonGeyserCategoryAttr extends VariableMoveCategoryAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TeraBlastCategoryAttr extends VariableMoveCategoryAttr {
|
/**
|
||||||
|
* Attribute used for tera moves that change category based on the user's Atk and SpAtk stats
|
||||||
|
* Note: Currently, `getEffectiveStat` does not ignore all abilities that affect stats except those
|
||||||
|
* with the attribute of `StatMultiplierAbAttr`
|
||||||
|
* TODO: Remove the `.partial()` tag from Tera Blast and Tera Starstorm when the above issue is resolved
|
||||||
|
* @extends VariableMoveCategoryAttr
|
||||||
|
*/
|
||||||
|
export class TeraMoveCategoryAttr extends VariableMoveCategoryAttr {
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
const category = (args[0] as Utils.NumberHolder);
|
const category = (args[0] as Utils.NumberHolder);
|
||||||
|
|
||||||
@ -4007,6 +4038,30 @@ export class VariableMoveTypeAttr extends MoveAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute used for Tera Starstorm that changes the move type to Stellar
|
||||||
|
* @extends VariableMoveTypeAttr
|
||||||
|
*/
|
||||||
|
export class TeraStarstormTypeAttr extends VariableMoveTypeAttr {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param user the {@linkcode Pokemon} using the move
|
||||||
|
* @param target n/a
|
||||||
|
* @param move n/a
|
||||||
|
* @param args[0] {@linkcode Utils.NumberHolder} the move type
|
||||||
|
* @returns `true` if the move type is changed to {@linkcode Type.STELLAR}, `false` otherwise
|
||||||
|
*/
|
||||||
|
override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
|
if (user.isTerastallized() && (user.hasFusionSpecies(Species.TERAPAGOS) || user.species.speciesId === Species.TERAPAGOS)) {
|
||||||
|
const moveType = args[0] as Utils.NumberHolder;
|
||||||
|
|
||||||
|
moveType.value = Type.STELLAR;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class FormChangeItemTypeAttr extends VariableMoveTypeAttr {
|
export class FormChangeItemTypeAttr extends VariableMoveTypeAttr {
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
const moveType = args[0];
|
const moveType = args[0];
|
||||||
@ -4544,6 +4599,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
|
|||||||
case BattlerTagType.DROWSY:
|
case BattlerTagType.DROWSY:
|
||||||
case BattlerTagType.DISABLED:
|
case BattlerTagType.DISABLED:
|
||||||
case BattlerTagType.HEAL_BLOCK:
|
case BattlerTagType.HEAL_BLOCK:
|
||||||
|
case BattlerTagType.RECEIVE_DOUBLE_DAMAGE:
|
||||||
return -5;
|
return -5;
|
||||||
case BattlerTagType.SEEDED:
|
case BattlerTagType.SEEDED:
|
||||||
case BattlerTagType.SALT_CURED:
|
case BattlerTagType.SALT_CURED:
|
||||||
@ -4564,6 +4620,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
|
|||||||
case BattlerTagType.ENCORE:
|
case BattlerTagType.ENCORE:
|
||||||
return -2;
|
return -2;
|
||||||
case BattlerTagType.MINIMIZED:
|
case BattlerTagType.MINIMIZED:
|
||||||
|
case BattlerTagType.ALWAYS_GET_HIT:
|
||||||
return 0;
|
return 0;
|
||||||
case BattlerTagType.INGRAIN:
|
case BattlerTagType.INGRAIN:
|
||||||
case BattlerTagType.IGNORE_ACCURACY:
|
case BattlerTagType.IGNORE_ACCURACY:
|
||||||
@ -5226,6 +5283,9 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
|||||||
*/
|
*/
|
||||||
const switchOutTarget = this.selfSwitch ? user : target;
|
const switchOutTarget = this.selfSwitch ? user : target;
|
||||||
if (switchOutTarget instanceof PlayerPokemon) {
|
if (switchOutTarget instanceof PlayerPokemon) {
|
||||||
|
if (switchOutTarget.scene.getParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
||||||
|
|
||||||
if (switchOutTarget.hp > 0) {
|
if (switchOutTarget.hp > 0) {
|
||||||
@ -5234,6 +5294,9 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else if (user.scene.currentBattle.battleType !== BattleType.WILD) {
|
} else if (user.scene.currentBattle.battleType !== BattleType.WILD) {
|
||||||
|
if (switchOutTarget.scene.getEnemyParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Switch out logic for trainer battles
|
// Switch out logic for trainer battles
|
||||||
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
||||||
|
|
||||||
@ -5244,6 +5307,9 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
|||||||
false, false), MoveEndPhase);
|
false, false), MoveEndPhase);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (user.scene.currentBattle.waveIndex % 10 === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Switch out logic for everything else (eg: WILD battles)
|
// Switch out logic for everything else (eg: WILD battles)
|
||||||
switchOutTarget.leaveField(false);
|
switchOutTarget.leaveField(false);
|
||||||
|
|
||||||
@ -5339,7 +5405,7 @@ export class ChillyReceptionAttr extends ForceSwitchOutAttr {
|
|||||||
|
|
||||||
getCondition(): MoveConditionFunc {
|
getCondition(): MoveConditionFunc {
|
||||||
// chilly reception move will go through if the weather is change-able to snow, or the user can switch out, else move will fail
|
// chilly reception move will go through if the weather is change-able to snow, or the user can switch out, else move will fail
|
||||||
return (user, target, move) => user.scene.arena.trySetWeather(WeatherType.SNOW, true) || super.getSwitchOutCondition()(user, target, move);
|
return (user, target, move) => user.scene.arena.weather?.weatherType !== WeatherType.SNOW || super.getSwitchOutCondition()(user, target, move);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export class RemoveTypeAttr extends MoveEffectAttr {
|
export class RemoveTypeAttr extends MoveEffectAttr {
|
||||||
@ -6580,7 +6646,7 @@ export class MoveCondition {
|
|||||||
|
|
||||||
export class FirstMoveCondition extends MoveCondition {
|
export class FirstMoveCondition extends MoveCondition {
|
||||||
constructor() {
|
constructor() {
|
||||||
super((user, target, move) => user.battleSummonData?.turnCount === 1);
|
super((user, target, move) => user.battleSummonData?.waveTurnCount === 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
|
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
|
||||||
@ -7257,7 +7323,7 @@ export function initMoves() {
|
|||||||
new StatusMove(Moves.CURSE, Type.GHOST, -1, 10, -1, 0, 2)
|
new StatusMove(Moves.CURSE, Type.GHOST, -1, 10, -1, 0, 2)
|
||||||
.attr(CurseAttr)
|
.attr(CurseAttr)
|
||||||
.ignoresSubstitute()
|
.ignoresSubstitute()
|
||||||
.ignoresProtect(true)
|
.ignoresProtect()
|
||||||
.target(MoveTarget.CURSE),
|
.target(MoveTarget.CURSE),
|
||||||
new AttackMove(Moves.FLAIL, Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 15, -1, 0, 2)
|
new AttackMove(Moves.FLAIL, Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 15, -1, 0, 2)
|
||||||
.attr(LowHpPowerAttr),
|
.attr(LowHpPowerAttr),
|
||||||
@ -8897,8 +8963,8 @@ export function initMoves() {
|
|||||||
.attr(HalfSacrificialAttr)
|
.attr(HalfSacrificialAttr)
|
||||||
.target(MoveTarget.ALL_NEAR_OTHERS),
|
.target(MoveTarget.ALL_NEAR_OTHERS),
|
||||||
new AttackMove(Moves.PLASMA_FISTS, Type.ELECTRIC, MoveCategory.PHYSICAL, 100, 100, 15, -1, 0, 7)
|
new AttackMove(Moves.PLASMA_FISTS, Type.ELECTRIC, MoveCategory.PHYSICAL, 100, 100, 15, -1, 0, 7)
|
||||||
.punchingMove()
|
.attr(AddArenaTagAttr, ArenaTagType.PLASMA_FISTS, 1)
|
||||||
.partial(),
|
.punchingMove(),
|
||||||
new AttackMove(Moves.PHOTON_GEYSER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7)
|
new AttackMove(Moves.PHOTON_GEYSER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7)
|
||||||
.attr(PhotonGeyserCategoryAttr)
|
.attr(PhotonGeyserCategoryAttr)
|
||||||
.ignoresAbilities()
|
.ignoresAbilities()
|
||||||
@ -8928,7 +8994,7 @@ export function initMoves() {
|
|||||||
.partial()
|
.partial()
|
||||||
.ignoresVirtual(),
|
.ignoresVirtual(),
|
||||||
/* End Unused */
|
/* End Unused */
|
||||||
new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 50, 100, 15, 100, 2, 7) //LGPE Implementation
|
new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 50, 100, 15, -1, 2, 7) //LGPE Implementation
|
||||||
.attr(CritOnlyAttr),
|
.attr(CritOnlyAttr),
|
||||||
new AttackMove(Moves.SPLISHY_SPLASH, Type.WATER, MoveCategory.SPECIAL, 90, 100, 15, 30, 0, 7)
|
new AttackMove(Moves.SPLISHY_SPLASH, Type.WATER, MoveCategory.SPECIAL, 90, 100, 15, 30, 0, 7)
|
||||||
.attr(StatusEffectAttr, StatusEffect.PARALYSIS)
|
.attr(StatusEffectAttr, StatusEffect.PARALYSIS)
|
||||||
@ -9155,16 +9221,15 @@ export function initMoves() {
|
|||||||
.attr(HalfSacrificialAttr),
|
.attr(HalfSacrificialAttr),
|
||||||
new AttackMove(Moves.EXPANDING_FORCE, Type.PSYCHIC, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 8)
|
new AttackMove(Moves.EXPANDING_FORCE, Type.PSYCHIC, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 8)
|
||||||
.attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.PSYCHIC && user.isGrounded() ? 1.5 : 1)
|
.attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.PSYCHIC && user.isGrounded() ? 1.5 : 1)
|
||||||
.attr(VariableTargetAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.PSYCHIC && user.isGrounded() ? 6 : 3),
|
.attr(VariableTargetAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.PSYCHIC && user.isGrounded() ? MoveTarget.ALL_NEAR_ENEMIES : MoveTarget.NEAR_OTHER),
|
||||||
new AttackMove(Moves.STEEL_ROLLER, Type.STEEL, MoveCategory.PHYSICAL, 130, 100, 5, -1, 0, 8)
|
new AttackMove(Moves.STEEL_ROLLER, Type.STEEL, MoveCategory.PHYSICAL, 130, 100, 5, -1, 0, 8)
|
||||||
.attr(ClearTerrainAttr)
|
.attr(ClearTerrainAttr)
|
||||||
.condition((user, target, move) => !!user.scene.arena.terrain),
|
.condition((user, target, move) => !!user.scene.arena.terrain),
|
||||||
new AttackMove(Moves.SCALE_SHOT, Type.DRAGON, MoveCategory.PHYSICAL, 25, 90, 20, -1, 0, 8)
|
new AttackMove(Moves.SCALE_SHOT, Type.DRAGON, MoveCategory.PHYSICAL, 25, 90, 20, -1, 0, 8)
|
||||||
//.attr(StatStageChangeAttr, Stat.SPD, 1, true) // TODO: Have boosts only apply at end of move, not after every hit
|
.attr(StatStageChangeAttr, [ Stat.SPD ], 1, true, null, true, false, MoveEffectTrigger.HIT, false, true)
|
||||||
//.attr(StatStageChangeAttr, Stat.DEF, -1, true)
|
.attr(StatStageChangeAttr, [ Stat.DEF ], -1, true, null, true, false, MoveEffectTrigger.HIT, false, true)
|
||||||
.attr(MultiHitAttr)
|
.attr(MultiHitAttr)
|
||||||
.makesContact(false)
|
.makesContact(false),
|
||||||
.partial(),
|
|
||||||
new AttackMove(Moves.METEOR_BEAM, Type.ROCK, MoveCategory.SPECIAL, 120, 90, 10, 100, 0, 8)
|
new AttackMove(Moves.METEOR_BEAM, Type.ROCK, MoveCategory.SPECIAL, 120, 90, 10, 100, 0, 8)
|
||||||
.attr(ChargeAttr, ChargeAnim.METEOR_BEAM_CHARGING, i18next.t("moveTriggers:isOverflowingWithSpacePower", { pokemonName: "{USER}" }), null, true)
|
.attr(ChargeAttr, ChargeAnim.METEOR_BEAM_CHARGING, i18next.t("moveTriggers:isOverflowingWithSpacePower", { pokemonName: "{USER}" }), null, true)
|
||||||
.attr(StatStageChangeAttr, [ Stat.SPATK ], 1, true)
|
.attr(StatStageChangeAttr, [ Stat.SPATK ], 1, true)
|
||||||
@ -9430,10 +9495,11 @@ export function initMoves() {
|
|||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
End Unused */
|
End Unused */
|
||||||
new AttackMove(Moves.TERA_BLAST, Type.NORMAL, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 9)
|
new AttackMove(Moves.TERA_BLAST, Type.NORMAL, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 9)
|
||||||
.attr(TeraBlastCategoryAttr)
|
.attr(TeraMoveCategoryAttr)
|
||||||
.attr(TeraBlastTypeAttr)
|
.attr(TeraBlastTypeAttr)
|
||||||
.attr(TeraBlastPowerAttr)
|
.attr(TeraBlastPowerAttr)
|
||||||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1, true, (user, target, move) => user.isTerastallized() && user.isOfType(Type.STELLAR)),
|
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1, true, (user, target, move) => user.isTerastallized() && user.isOfType(Type.STELLAR))
|
||||||
|
.partial(), /** Does not ignore abilities that affect stats, relevant in determining the move's category {@see TeraMoveCategoryAttr} */
|
||||||
new SelfStatusMove(Moves.SILK_TRAP, Type.BUG, -1, 10, -1, 4, 9)
|
new SelfStatusMove(Moves.SILK_TRAP, Type.BUG, -1, 10, -1, 4, 9)
|
||||||
.attr(ProtectAttr, BattlerTagType.SILK_TRAP)
|
.attr(ProtectAttr, BattlerTagType.SILK_TRAP)
|
||||||
.condition(failIfLastCondition),
|
.condition(failIfLastCondition),
|
||||||
@ -9613,9 +9679,8 @@ export function initMoves() {
|
|||||||
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
||||||
.triageMove(),
|
.triageMove(),
|
||||||
new AttackMove(Moves.SYRUP_BOMB, Type.GRASS, MoveCategory.SPECIAL, 60, 85, 10, -1, 0, 9)
|
new AttackMove(Moves.SYRUP_BOMB, Type.GRASS, MoveCategory.SPECIAL, 60, 85, 10, -1, 0, 9)
|
||||||
.attr(StatStageChangeAttr, [ Stat.SPD ], -1) //Temporary
|
.attr(AddBattlerTagAttr, BattlerTagType.SYRUP_BOMB, false, false, 3)
|
||||||
.ballBombMove()
|
.ballBombMove(),
|
||||||
.partial(),
|
|
||||||
new AttackMove(Moves.IVY_CUDGEL, Type.GRASS, MoveCategory.PHYSICAL, 100, 100, 10, -1, 0, 9)
|
new AttackMove(Moves.IVY_CUDGEL, Type.GRASS, MoveCategory.PHYSICAL, 100, 100, 10, -1, 0, 9)
|
||||||
.attr(IvyCudgelTypeAttr)
|
.attr(IvyCudgelTypeAttr)
|
||||||
.attr(HighCritAttr)
|
.attr(HighCritAttr)
|
||||||
@ -9624,8 +9689,10 @@ export function initMoves() {
|
|||||||
.attr(ElectroShotChargeAttr)
|
.attr(ElectroShotChargeAttr)
|
||||||
.ignoresVirtual(),
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.TERA_STARSTORM, Type.NORMAL, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 9)
|
new AttackMove(Moves.TERA_STARSTORM, Type.NORMAL, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 9)
|
||||||
.attr(TeraBlastCategoryAttr)
|
.attr(TeraMoveCategoryAttr)
|
||||||
.partial(),
|
.attr(TeraStarstormTypeAttr)
|
||||||
|
.attr(VariableTargetAttr, (user, target, move) => (user.hasFusionSpecies(Species.TERAPAGOS) || user.species.speciesId === Species.TERAPAGOS) && user.isTerastallized() ? MoveTarget.ALL_NEAR_ENEMIES : MoveTarget.NEAR_OTHER)
|
||||||
|
.partial(), /** Does not ignore abilities that affect stats, relevant in determining the move's category {@see TeraMoveCategoryAttr} */
|
||||||
new AttackMove(Moves.FICKLE_BEAM, Type.DRAGON, MoveCategory.SPECIAL, 80, 100, 5, 30, 0, 9)
|
new AttackMove(Moves.FICKLE_BEAM, Type.DRAGON, MoveCategory.SPECIAL, 80, 100, 5, 30, 0, 9)
|
||||||
.attr(PreMoveMessageAttr, doublePowerChanceMessageFunc)
|
.attr(PreMoveMessageAttr, doublePowerChanceMessageFunc)
|
||||||
.attr(DoublePowerChanceAttr),
|
.attr(DoublePowerChanceAttr),
|
||||||
|
@ -18,7 +18,7 @@ import { modifierTypes } from "#app/modifier/modifier-type";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:aTrainersTest";
|
const namespace = "mysteryEncounters/aTrainersTest";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Trainer's Test encounter.
|
* A Trainer's Test encounter.
|
||||||
@ -32,7 +32,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
.withIntroSpriteConfigs([]) // These are set in onInit()
|
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
@ -76,24 +76,24 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
encounter.dialogue.intro = [
|
encounter.dialogue.intro = [
|
||||||
{
|
{
|
||||||
speaker: `trainerNames:${trainerNameKey}`,
|
speaker: `trainerNames:${trainerNameKey}`,
|
||||||
text: `${namespace}.${trainerNameKey}.intro_dialogue`
|
text: `${namespace}:${trainerNameKey}.intro_dialogue`
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
encounter.options[0].dialogue!.selected = [
|
encounter.options[0].dialogue!.selected = [
|
||||||
{
|
{
|
||||||
speaker: `trainerNames:${trainerNameKey}`,
|
speaker: `trainerNames:${trainerNameKey}`,
|
||||||
text: `${namespace}.${trainerNameKey}.accept`
|
text: `${namespace}:${trainerNameKey}.accept`
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
encounter.options[1].dialogue!.selected = [
|
encounter.options[1].dialogue!.selected = [
|
||||||
{
|
{
|
||||||
speaker: `trainerNames:${trainerNameKey}`,
|
speaker: `trainerNames:${trainerNameKey}`,
|
||||||
text: `${namespace}.${trainerNameKey}.decline`
|
text: `${namespace}:${trainerNameKey}.decline`
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
encounter.setDialogueToken("statTrainerName", i18next.t(`trainerNames:${trainerNameKey}`));
|
encounter.setDialogueToken("statTrainerName", i18next.t(`trainerNames:${trainerNameKey}`));
|
||||||
const eggDescription = i18next.t(`${namespace}.title`) + ":\n" + i18next.t(`trainerNames:${trainerNameKey}`);
|
const eggDescription = i18next.t(`${namespace}:title`) + ":\n" + i18next.t(`trainerNames:${trainerNameKey}`);
|
||||||
encounter.misc = { trainerType, trainerNameKey, trainerEggDescription: eggDescription };
|
encounter.misc = { trainerType, trainerNameKey, trainerEggDescription: eggDescription };
|
||||||
|
|
||||||
// Trainer config
|
// Trainer config
|
||||||
@ -128,14 +128,14 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withIntroDialogue()
|
.withIntroDialogue()
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`
|
buttonTooltip: `${namespace}:option.1.tooltip`
|
||||||
},
|
},
|
||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
@ -151,15 +151,15 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
eggDescriptor: encounter.misc.trainerEggDescription,
|
eggDescriptor: encounter.misc.trainerEggDescription,
|
||||||
tier: EggTier.ULTRA
|
tier: EggTier.ULTRA
|
||||||
};
|
};
|
||||||
encounter.setDialogueToken("eggType", i18next.t(`${namespace}.eggTypes.epic`));
|
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.epic`));
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SACRED_ASH ], guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ULTRA ], fillRemaining: true }, [ eggOptions ]);
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SACRED_ASH ], guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ULTRA ], fillRemaining: true }, [ eggOptions ]);
|
||||||
return initBattleWithEnemyConfig(scene, config);
|
return initBattleWithEnemyConfig(scene, config);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`
|
buttonTooltip: `${namespace}:option.2.tooltip`
|
||||||
},
|
},
|
||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
@ -173,14 +173,14 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
eggDescriptor: encounter.misc.trainerEggDescription,
|
eggDescriptor: encounter.misc.trainerEggDescription,
|
||||||
tier: EggTier.GREAT
|
tier: EggTier.GREAT
|
||||||
};
|
};
|
||||||
encounter.setDialogueToken("eggType", i18next.t(`${namespace}.eggTypes.rare`));
|
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.rare`));
|
||||||
setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: -1 }, [ eggOptions ]);
|
setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: -1 }, [ eggOptions ]);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.withOutroDialogue([
|
.withOutroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.outro`
|
text: `${namespace}:outro`
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
.build();
|
.build();
|
||||||
|
@ -27,7 +27,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:absoluteAvarice";
|
const namespace = "mysteryEncounters/absoluteAvarice";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Absolute Avarice encounter.
|
* Absolute Avarice encounter.
|
||||||
@ -163,12 +163,12 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
modifierConfigs: bossModifierConfigs,
|
modifierConfigs: bossModifierConfigs,
|
||||||
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}.option.1.boss_enraged`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.boss_enraged`);
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,11 +250,11 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -274,7 +274,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
scene.addModifier(seedModifier, false, false, false, true);
|
scene.addModifier(seedModifier, false, false, false, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
queueEncounterMessage(scene, `${namespace}.option.1.food_stash`);
|
queueEncounterMessage(scene, `${namespace}:option.1.food_stash`);
|
||||||
};
|
};
|
||||||
|
|
||||||
setEncounterRewards(scene, { fillRemaining: true }, undefined, givePartyPokemonReviverSeeds);
|
setEncounterRewards(scene, { fillRemaining: true }, undefined, givePartyPokemonReviverSeeds);
|
||||||
@ -294,11 +294,11 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -336,11 +336,11 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`,
|
text: `${namespace}:option.3.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
@ -8,14 +8,15 @@ import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/myst
|
|||||||
import { AbilityRequirement, CombinationPokemonRequirement, MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
import { AbilityRequirement, CombinationPokemonRequirement, MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||||
import { getHighestStatTotalPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { getHighestStatTotalPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
import { EXTORTION_ABILITIES, EXTORTION_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
import { EXTORTION_ABILITIES, EXTORTION_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
||||||
import { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species";
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
import { speciesStarterCosts } from "#app/data/balance/starters";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:offerYouCantRefuse";
|
const namespace = "mysteryEncounters/anOfferYouCantRefuse";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Money offered starts at base value of Relic Gold, increasing linearly up to 3x Relic Gold based on the starter tier of the Pokemon being purchased
|
* Money offered starts at base value of Relic Gold, increasing linearly up to 3x Relic Gold based on the starter tier of the Pokemon being purchased
|
||||||
@ -56,22 +57,22 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
const pokemon = getHighestStatTotalPlayerPokemon(scene, true, true);
|
const pokemon = getHighestStatTotalPlayerPokemon(scene, true, true);
|
||||||
|
|
||||||
const baseSpecies = pokemon.getSpeciesForm().getRootSpeciesId();
|
const baseSpecies = pokemon.getSpeciesForm().getRootSpeciesId();
|
||||||
const starterValue: number = speciesStarters[baseSpecies] ?? 1;
|
const starterValue: number = speciesStarterCosts[baseSpecies] ?? 1;
|
||||||
const multiplier = Math.max(MONEY_MAXIMUM_MULTIPLIER / 10 * starterValue, MONEY_MINIMUM_MULTIPLIER);
|
const multiplier = Math.max(MONEY_MAXIMUM_MULTIPLIER / 10 * starterValue, MONEY_MINIMUM_MULTIPLIER);
|
||||||
const price = scene.getWaveMoneyAmount(multiplier);
|
const price = scene.getWaveMoneyAmount(multiplier);
|
||||||
|
|
||||||
@ -104,12 +105,12 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -135,13 +136,13 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
|
|||||||
new AbilityRequirement(EXTORTION_ABILITIES))
|
new AbilityRequirement(EXTORTION_ABILITIES))
|
||||||
)
|
)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
disabledButtonTooltip: `${namespace}.option.2.tooltip_disabled`,
|
disabledButtonTooltip: `${namespace}:option.2.tooltip_disabled`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -159,12 +160,12 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.option.3.selected`,
|
text: `${namespace}:option.3.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -33,7 +33,7 @@ import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:berriesAbound";
|
const namespace = "mysteryEncounters/berriesAbound";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Berries Abound encounter.
|
* Berries Abound encounter.
|
||||||
@ -50,7 +50,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
.withIntroSpriteConfigs([]) // Set in onInit()
|
.withIntroSpriteConfigs([]) // Set in onInit()
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
@ -110,16 +110,16 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -129,7 +129,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
const numBerries = encounter.misc.numBerries;
|
const numBerries = encounter.misc.numBerries;
|
||||||
|
|
||||||
const doBerryRewards = () => {
|
const doBerryRewards = () => {
|
||||||
const berryText = i18next.t(`${namespace}.berries`);
|
const berryText = i18next.t(`${namespace}:berries`);
|
||||||
|
|
||||||
scene.playSound("item_fanfare");
|
scene.playSound("item_fanfare");
|
||||||
queueEncounterMessage(scene, i18next.t("battle:rewardGainCount", { modifierName: berryText, count: numBerries }));
|
queueEncounterMessage(scene, i18next.t("battle:rewardGainCount", { modifierName: berryText, count: numBerries }));
|
||||||
@ -157,8 +157,8 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`
|
buttonTooltip: `${namespace}:option.2.tooltip`
|
||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
// Pick race for berries
|
// Pick race for berries
|
||||||
@ -180,7 +180,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
if (speedDiff < 1) {
|
if (speedDiff < 1) {
|
||||||
// Caught and attacked by boss, gets +1 to all stats at start of fight
|
// Caught and attacked by boss, gets +1 to all stats at start of fight
|
||||||
const doBerryRewards = () => {
|
const doBerryRewards = () => {
|
||||||
const berryText = i18next.t(`${namespace}.berries`);
|
const berryText = i18next.t(`${namespace}:berries`);
|
||||||
|
|
||||||
scene.playSound("item_fanfare");
|
scene.playSound("item_fanfare");
|
||||||
queueEncounterMessage(scene, i18next.t("battle:rewardGainCount", { modifierName: berryText, count: numBerries }));
|
queueEncounterMessage(scene, i18next.t("battle:rewardGainCount", { modifierName: berryText, count: numBerries }));
|
||||||
@ -199,11 +199,11 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
const config = scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0];
|
const config = scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0];
|
||||||
config.pokemonConfigs![0].tags = [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ];
|
config.pokemonConfigs![0].tags = [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ];
|
||||||
config.pokemonConfigs![0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => {
|
config.pokemonConfigs![0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}.option.2.boss_enraged`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:option.2.boss_enraged`);
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
||||||
};
|
};
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, undefined, doBerryRewards);
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, undefined, doBerryRewards);
|
||||||
await showEncounterText(scene, `${namespace}.option.2.selected_bad`);
|
await showEncounterText(scene, `${namespace}:option.2.selected_bad`);
|
||||||
await initBattleWithEnemyConfig(scene, config);
|
await initBattleWithEnemyConfig(scene, config);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@ -211,7 +211,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
const numBerriesGrabbed = Math.max(Math.min(Math.round((speedDiff - 1) / 0.08), numBerries), 2);
|
const numBerriesGrabbed = Math.max(Math.min(Math.round((speedDiff - 1) / 0.08), numBerries), 2);
|
||||||
encounter.setDialogueToken("numBerries", String(numBerriesGrabbed));
|
encounter.setDialogueToken("numBerries", String(numBerriesGrabbed));
|
||||||
const doFasterBerryRewards = () => {
|
const doFasterBerryRewards = () => {
|
||||||
const berryText = i18next.t(`${namespace}.berries`);
|
const berryText = i18next.t(`${namespace}:berries`);
|
||||||
|
|
||||||
scene.playSound("item_fanfare");
|
scene.playSound("item_fanfare");
|
||||||
queueEncounterMessage(scene, i18next.t("battle:rewardGainCount", { modifierName: berryText, count: numBerriesGrabbed }));
|
queueEncounterMessage(scene, i18next.t("battle:rewardGainCount", { modifierName: berryText, count: numBerriesGrabbed }));
|
||||||
@ -224,7 +224,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
setEncounterExp(scene, fastestPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs![0].species.baseExp);
|
setEncounterExp(scene, fastestPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs![0].species.baseExp);
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, undefined, doFasterBerryRewards);
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, undefined, doFasterBerryRewards);
|
||||||
await showEncounterText(scene, `${namespace}.option.2.selected`);
|
await showEncounterText(scene, `${namespace}:option.2.selected`);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -232,11 +232,11 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`,
|
text: `${namespace}:option.3.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -52,7 +52,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:bugTypeSuperfan";
|
const namespace = "mysteryEncounters/bugTypeSuperfan";
|
||||||
|
|
||||||
const POOL_1_POKEMON = [
|
const POOL_1_POKEMON = [
|
||||||
Species.PARASECT,
|
Species.PARASECT,
|
||||||
@ -203,11 +203,11 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
@ -276,17 +276,17 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -317,9 +317,9 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withPrimaryPokemonRequirement(new TypeRequirement(Type.BUG, false, 1)) // Must have 1 Bug type on team
|
.withPrimaryPokemonRequirement(new TypeRequirement(Type.BUG, false, 1)) // Must have 1 Bug type on team
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
disabledButtonTooltip: `${namespace}.option.2.disabled_tooltip`
|
disabledButtonTooltip: `${namespace}:option.2.disabled_tooltip`
|
||||||
})
|
})
|
||||||
.withPreOptionPhase(async (scene: BattleScene) => {
|
.withPreOptionPhase(async (scene: BattleScene) => {
|
||||||
// Player shows off their bug types
|
// Player shows off their bug types
|
||||||
@ -327,31 +327,31 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Player gets different rewards depending on the number of bug types they have
|
// Player gets different rewards depending on the number of bug types they have
|
||||||
const numBugTypes = scene.getParty().filter(p => p.isOfType(Type.BUG, true)).length;
|
const numBugTypes = scene.getParty().filter(p => p.isOfType(Type.BUG, true)).length;
|
||||||
const numBugTypesText = i18next.t(`${namespace}.numBugTypes`, { count: numBugTypes });
|
const numBugTypesText = i18next.t(`${namespace}:numBugTypes`, { count: numBugTypes });
|
||||||
encounter.setDialogueToken("numBugTypes", numBugTypesText);
|
encounter.setDialogueToken("numBugTypes", numBugTypesText);
|
||||||
|
|
||||||
if (numBugTypes < 2) {
|
if (numBugTypes < 2) {
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SUPER_LURE, modifierTypes.GREAT_BALL ], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SUPER_LURE, modifierTypes.GREAT_BALL ], fillRemaining: false });
|
||||||
encounter.selectedOption!.dialogue!.selected = [
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.option.2.selected_0_to_1`,
|
text: `${namespace}:option.2.selected_0_to_1`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
} else if (numBugTypes < 4) {
|
} else if (numBugTypes < 4) {
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.QUICK_CLAW, modifierTypes.MAX_LURE, modifierTypes.ULTRA_BALL ], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.QUICK_CLAW, modifierTypes.MAX_LURE, modifierTypes.ULTRA_BALL ], fillRemaining: false });
|
||||||
encounter.selectedOption!.dialogue!.selected = [
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.option.2.selected_2_to_3`,
|
text: `${namespace}:option.2.selected_2_to_3`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
} else if (numBugTypes < 6) {
|
} else if (numBugTypes < 6) {
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.GRIP_CLAW, modifierTypes.MAX_LURE, modifierTypes.ROGUE_BALL ], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.GRIP_CLAW, modifierTypes.MAX_LURE, modifierTypes.ROGUE_BALL ], fillRemaining: false });
|
||||||
encounter.selectedOption!.dialogue!.selected = [
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.option.2.selected_4_to_5`,
|
text: `${namespace}:option.2.selected_4_to_5`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
@ -382,8 +382,8 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifierOptions, fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifierOptions, fillRemaining: false });
|
||||||
encounter.selectedOption!.dialogue!.selected = [
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.option.2.selected_6`,
|
text: `${namespace}:option.2.selected_6`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -401,19 +401,19 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1)
|
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1)
|
||||||
))
|
))
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`,
|
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`,
|
text: `${namespace}:option.3.selected`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.option.3.selected_dialogue`,
|
text: `${namespace}:option.3.selected_dialogue`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
secondOptionPrompt: `${namespace}.option.3.select_prompt`,
|
secondOptionPrompt: `${namespace}:option.3.select_prompt`,
|
||||||
})
|
})
|
||||||
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
@ -452,7 +452,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
(item instanceof AttackTypeBoosterModifier && (item.type as AttackTypeBoosterModifierType).moveType === Type.BUG);
|
(item instanceof AttackTypeBoosterModifier && (item.type as AttackTypeBoosterModifierType).moveType === Type.BUG);
|
||||||
});
|
});
|
||||||
if (!hasValidItem) {
|
if (!hasValidItem) {
|
||||||
return getEncounterText(scene, `${namespace}.option.3.invalid_selection`) ?? null;
|
return getEncounterText(scene, `${namespace}:option.3.invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -480,7 +480,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
.build())
|
.build())
|
||||||
.withOutroDialogue([
|
.withOutroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.outro`,
|
text: `${namespace}:outro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.build();
|
.build();
|
||||||
@ -634,7 +634,7 @@ function getTrainerConfigForWave(waveIndex: number) {
|
|||||||
function doBugTypeMoveTutor(scene: BattleScene): Promise<void> {
|
function doBugTypeMoveTutor(scene: BattleScene): Promise<void> {
|
||||||
return new Promise<void>(async resolve => {
|
return new Promise<void>(async resolve => {
|
||||||
const moveOptions = scene.currentBattle.mysteryEncounter!.misc.moveTutorOptions;
|
const moveOptions = scene.currentBattle.mysteryEncounter!.misc.moveTutorOptions;
|
||||||
await showEncounterDialogue(scene, `${namespace}.battle_won`, `${namespace}.speaker`);
|
await showEncounterDialogue(scene, `${namespace}:battle_won`, `${namespace}:speaker`);
|
||||||
|
|
||||||
const overlayScale = 1;
|
const overlayScale = 1;
|
||||||
const moveInfoOverlay = new MoveInfoOverlay(scene, {
|
const moveInfoOverlay = new MoveInfoOverlay(scene, {
|
||||||
@ -669,7 +669,7 @@ function doBugTypeMoveTutor(scene: BattleScene): Promise<void> {
|
|||||||
moveInfoOverlay.setVisible(false);
|
moveInfoOverlay.setVisible(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = await selectOptionThenPokemon(scene, optionSelectItems, `${namespace}.teach_move_prompt`, undefined, onHoverOverCancel);
|
const result = await selectOptionThenPokemon(scene, optionSelectItems, `${namespace}:teach_move_prompt`, undefined, onHoverOverCancel);
|
||||||
// let forceExit = !!result;
|
// let forceExit = !!result;
|
||||||
if (!result) {
|
if (!result) {
|
||||||
moveInfoOverlay.active = false;
|
moveInfoOverlay.active = false;
|
||||||
|
@ -34,7 +34,7 @@ import { EncounterAnim } from "#enums/encounter-anims";
|
|||||||
import { Challenges } from "#enums/challenges";
|
import { Challenges } from "#enums/challenges";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:clowningAround";
|
const namespace = "mysteryEncounters/clowningAround";
|
||||||
|
|
||||||
const RANDOM_ABILITY_POOL = [
|
const RANDOM_ABILITY_POOL = [
|
||||||
Abilities.STURDY,
|
Abilities.STURDY,
|
||||||
@ -98,11 +98,11 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
speaker: `${namespace}.speaker`
|
speaker: `${namespace}:speaker`
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
@ -148,19 +148,19 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOption(
|
.withOption(
|
||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
speaker: `${namespace}.speaker`
|
speaker: `${namespace}:speaker`
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -199,7 +199,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
// After the battle, offer the player the opportunity to permanently swap ability
|
// After the battle, offer the player the opportunity to permanently swap ability
|
||||||
const abilityWasSwapped = await handleSwapAbility(scene);
|
const abilityWasSwapped = await handleSwapAbility(scene);
|
||||||
if (abilityWasSwapped) {
|
if (abilityWasSwapped) {
|
||||||
await showEncounterText(scene, `${namespace}.option.1.ability_gained`);
|
await showEncounterText(scene, `${namespace}:option.1.ability_gained`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Play animations once ability swap is complete
|
// Play animations once ability swap is complete
|
||||||
@ -222,19 +222,19 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
speaker: `${namespace}.speaker`
|
speaker: `${namespace}:speaker`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected_2`,
|
text: `${namespace}:option.2.selected_2`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected_3`,
|
text: `${namespace}:option.2.selected_3`,
|
||||||
speaker: `${namespace}.speaker`
|
speaker: `${namespace}:speaker`
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -308,19 +308,19 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`,
|
text: `${namespace}:option.3.selected`,
|
||||||
speaker: `${namespace}.speaker`
|
speaker: `${namespace}:speaker`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected_2`,
|
text: `${namespace}:option.3.selected_2`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected_3`,
|
text: `${namespace}:option.3.selected_3`,
|
||||||
speaker: `${namespace}.speaker`
|
speaker: `${namespace}:speaker`
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -377,15 +377,15 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withOutroDialogue([
|
.withOutroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.outro`,
|
text: `${namespace}:outro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
async function handleSwapAbility(scene: BattleScene) {
|
async function handleSwapAbility(scene: BattleScene) {
|
||||||
return new Promise<boolean>(async resolve => {
|
return new Promise<boolean>(async resolve => {
|
||||||
await showEncounterDialogue(scene, `${namespace}.option.1.apply_ability_dialogue`, `${namespace}.speaker`);
|
await showEncounterDialogue(scene, `${namespace}:option.1.apply_ability_dialogue`, `${namespace}:speaker`);
|
||||||
await showEncounterText(scene, `${namespace}.option.1.apply_ability_message`);
|
await showEncounterText(scene, `${namespace}:option.1.apply_ability_message`);
|
||||||
|
|
||||||
scene.ui.setMode(Mode.MESSAGE).then(() => {
|
scene.ui.setMode(Mode.MESSAGE).then(() => {
|
||||||
displayYesNoOptions(scene, resolve);
|
displayYesNoOptions(scene, resolve);
|
||||||
@ -394,7 +394,7 @@ async function handleSwapAbility(scene: BattleScene) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function displayYesNoOptions(scene: BattleScene, resolve) {
|
function displayYesNoOptions(scene: BattleScene, resolve) {
|
||||||
showEncounterText(scene, `${namespace}.option.1.ability_prompt`, null, 500, false);
|
showEncounterText(scene, `${namespace}:option.1.ability_prompt`, null, 500, false);
|
||||||
const fullOptions = [
|
const fullOptions = [
|
||||||
{
|
{
|
||||||
label: i18next.t("menu:yes"),
|
label: i18next.t("menu:yes"),
|
||||||
|
@ -30,7 +30,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:dancingLessons";
|
const namespace = "mysteryEncounters/dancingLessons";
|
||||||
|
|
||||||
// Fire form
|
// Fire form
|
||||||
const BAILE_STYLE_BIOMES = [
|
const BAILE_STYLE_BIOMES = [
|
||||||
@ -99,12 +99,12 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
})
|
})
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
// Gets +1 to all stats except SPD on battle start
|
// Gets +1 to all stats except SPD on battle start
|
||||||
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}.option.1.boss_enraged`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.boss_enraged`);
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF ], 1));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF ], 1));
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
@ -173,11 +173,11 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -202,11 +202,11 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -237,13 +237,13 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||||
.withPrimaryPokemonRequirement(new MoveRequirement(DANCING_MOVES)) // Will set option3PrimaryName and option3PrimaryMove dialogue tokens automatically
|
.withPrimaryPokemonRequirement(new MoveRequirement(DANCING_MOVES)) // Will set option3PrimaryName and option3PrimaryMove dialogue tokens automatically
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`,
|
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||||
secondOptionPrompt: `${namespace}.option.3.select_prompt`,
|
secondOptionPrompt: `${namespace}:option.3.select_prompt`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`,
|
text: `${namespace}:option.3.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -278,7 +278,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
}
|
}
|
||||||
const meetsReqs = encounter.options[2].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
const meetsReqs = encounter.options[2].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
||||||
if (!meetsReqs) {
|
if (!meetsReqs) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
return getEncounterText(scene, `${namespace}:invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -16,7 +16,7 @@ import { PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#app/mod
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** i18n namespace for encounter */
|
/** i18n namespace for encounter */
|
||||||
const namespace = "mysteryEncounter:darkDeal";
|
const namespace = "mysteryEncounters/darkDeal";
|
||||||
|
|
||||||
/** Exclude Ultra Beasts (inludes Cosmog/Solgaleo/Lunala/Necrozma), Paradox (includes Miraidon/Koraidon), Eternatus, and Mythicals */
|
/** Exclude Ultra Beasts (inludes Cosmog/Solgaleo/Lunala/Necrozma), Paradox (includes Miraidon/Koraidon), Eternatus, and Mythicals */
|
||||||
const excludedBosses = [
|
const excludedBosses = [
|
||||||
@ -107,32 +107,32 @@ export const DarkDealEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withSceneWaveRangeRequirement(30, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
.withSceneWaveRangeRequirement(30, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||||
.withScenePartySizeRequirement(2, 6, true) // Must have at least 2 pokemon in party
|
.withScenePartySizeRequirement(2, 6, true) // Must have at least 2 pokemon in party
|
||||||
.withCatchAllowed(true)
|
.withCatchAllowed(true)
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOption(
|
.withOption(
|
||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.option.1.selected_dialogue`,
|
text: `${namespace}:option.1.selected_dialogue`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected_message`,
|
text: `${namespace}:option.1.selected_message`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -187,12 +187,12 @@ export const DarkDealEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -204,7 +204,7 @@ export const DarkDealEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withOutroDialogue([
|
.withOutroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.outro`
|
text: `${namespace}:outro`
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
.build();
|
.build();
|
||||||
|
@ -19,7 +19,7 @@ import { getPokemonSpecies } from "#app/data/pokemon-species";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:delibirdy";
|
const namespace = "mysteryEncounters/delibirdy";
|
||||||
|
|
||||||
/** Berries only */
|
/** Berries only */
|
||||||
const OPTION_2_ALLOWED_MODIFIERS = [ "BerryModifier", "PokemonInstantReviveModifier" ];
|
const OPTION_2_ALLOWED_MODIFIERS = [ "BerryModifier", "PokemonInstantReviveModifier" ];
|
||||||
@ -81,15 +81,15 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOutroDialogue([
|
.withOutroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.outro`,
|
text: `${namespace}:outro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
@ -108,11 +108,11 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withSceneMoneyRequirement(0, DELIBIRDY_MONEY_PRICE_MULTIPLIER) // Must have money to spawn
|
.withSceneMoneyRequirement(0, DELIBIRDY_MONEY_PRICE_MULTIPLIER) // Must have money to spawn
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -145,12 +145,12 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withPrimaryPokemonRequirement(new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS))
|
.withPrimaryPokemonRequirement(new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS))
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
secondOptionPrompt: `${namespace}.option.2.select_prompt`,
|
secondOptionPrompt: `${namespace}:option.2.select_prompt`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -183,7 +183,7 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
// If pokemon has valid item, it can be selected
|
// If pokemon has valid item, it can be selected
|
||||||
const meetsReqs = encounter.options[1].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
const meetsReqs = encounter.options[1].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
||||||
if (!meetsReqs) {
|
if (!meetsReqs) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
return getEncounterText(scene, `${namespace}:invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -193,7 +193,7 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
const modifier = encounter.misc.chosenModifier;
|
const modifier: BerryModifier | HealingBoosterModifier = encounter.misc.chosenModifier;
|
||||||
|
|
||||||
// Give the player a Candy Jar if they gave a Berry, and a Healing Charm for Reviver Seed
|
// Give the player a Candy Jar if they gave a Berry, and a Healing Charm for Reviver Seed
|
||||||
if (modifier instanceof BerryModifier) {
|
if (modifier instanceof BerryModifier) {
|
||||||
@ -239,12 +239,12 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withPrimaryPokemonRequirement(new HeldItemRequirement(OPTION_3_DISALLOWED_MODIFIERS, 1, true))
|
.withPrimaryPokemonRequirement(new HeldItemRequirement(OPTION_3_DISALLOWED_MODIFIERS, 1, true))
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
secondOptionPrompt: `${namespace}.option.3.select_prompt`,
|
secondOptionPrompt: `${namespace}:option.3.select_prompt`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`,
|
text: `${namespace}:option.3.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -277,7 +277,7 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
// If pokemon has valid item, it can be selected
|
// If pokemon has valid item, it can be selected
|
||||||
const meetsReqs = encounter.options[2].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
const meetsReqs = encounter.options[2].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
||||||
if (!meetsReqs) {
|
if (!meetsReqs) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
return getEncounterText(scene, `${namespace}:invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -14,7 +14,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** i18n namespace for encounter */
|
/** i18n namespace for encounter */
|
||||||
const namespace = "mysteryEncounter:departmentStoreSale";
|
const namespace = "mysteryEncounters/departmentStoreSale";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Department Store Sale encounter.
|
* Department Store Sale encounter.
|
||||||
@ -43,21 +43,21 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
},
|
},
|
||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
// Choose TMs
|
// Choose TMs
|
||||||
@ -82,8 +82,8 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
},
|
},
|
||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
// Choose Vitamins
|
// Choose Vitamins
|
||||||
@ -106,8 +106,8 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
},
|
},
|
||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
// Choose X Items
|
// Choose X Items
|
||||||
@ -130,8 +130,8 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.4.label`,
|
buttonLabel: `${namespace}:option.4.label`,
|
||||||
buttonTooltip: `${namespace}.option.4.tooltip`,
|
buttonTooltip: `${namespace}:option.4.tooltip`,
|
||||||
},
|
},
|
||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
// Choose Pokeballs
|
// Choose Pokeballs
|
||||||
@ -158,7 +158,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withOutroDialogue([
|
.withOutroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.outro`,
|
text: `${namespace}:outro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
.build();
|
.build();
|
||||||
|
@ -14,7 +14,7 @@ import i18next from "i18next";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** i18n namespace for the encounter */
|
/** i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:fieldTrip";
|
const namespace = "mysteryEncounters/fieldTrip";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Field Trip encounter.
|
* Field Trip encounter.
|
||||||
@ -44,24 +44,24 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOption(
|
.withOption(
|
||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
secondOptionPrompt: `${namespace}.second_option_prompt`,
|
secondOptionPrompt: `${namespace}:second_option_prompt`,
|
||||||
})
|
})
|
||||||
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
@ -72,7 +72,7 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
label: move.getName(),
|
label: move.getName(),
|
||||||
handler: () => {
|
handler: () => {
|
||||||
// Pokemon and move selected
|
// Pokemon and move selected
|
||||||
encounter.setDialogueToken("moveCategory", i18next.t(`${namespace}.physical`));
|
encounter.setDialogueToken("moveCategory", i18next.t(`${namespace}:physical`));
|
||||||
pokemonAndMoveChosen(scene, pokemon, move, MoveCategory.PHYSICAL);
|
pokemonAndMoveChosen(scene, pokemon, move, MoveCategory.PHYSICAL);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
@ -105,9 +105,9 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
secondOptionPrompt: `${namespace}.second_option_prompt`,
|
secondOptionPrompt: `${namespace}:second_option_prompt`,
|
||||||
})
|
})
|
||||||
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
@ -118,7 +118,7 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
label: move.getName(),
|
label: move.getName(),
|
||||||
handler: () => {
|
handler: () => {
|
||||||
// Pokemon and move selected
|
// Pokemon and move selected
|
||||||
encounter.setDialogueToken("moveCategory", i18next.t(`${namespace}.special`));
|
encounter.setDialogueToken("moveCategory", i18next.t(`${namespace}:special`));
|
||||||
pokemonAndMoveChosen(scene, pokemon, move, MoveCategory.SPECIAL);
|
pokemonAndMoveChosen(scene, pokemon, move, MoveCategory.SPECIAL);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
@ -151,9 +151,9 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
secondOptionPrompt: `${namespace}.second_option_prompt`,
|
secondOptionPrompt: `${namespace}:second_option_prompt`,
|
||||||
})
|
})
|
||||||
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
@ -164,7 +164,7 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
label: move.getName(),
|
label: move.getName(),
|
||||||
handler: () => {
|
handler: () => {
|
||||||
// Pokemon and move selected
|
// Pokemon and move selected
|
||||||
encounter.setDialogueToken("moveCategory", i18next.t(`${namespace}.status`));
|
encounter.setDialogueToken("moveCategory", i18next.t(`${namespace}:status`));
|
||||||
pokemonAndMoveChosen(scene, pokemon, move, MoveCategory.STATUS);
|
pokemonAndMoveChosen(scene, pokemon, move, MoveCategory.STATUS);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
@ -203,28 +203,28 @@ function pokemonAndMoveChosen(scene: BattleScene, pokemon: PlayerPokemon, move:
|
|||||||
if (!correctMove) {
|
if (!correctMove) {
|
||||||
encounter.selectedOption!.dialogue!.selected = [
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}:option.selected`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.incorrect`,
|
text: `${namespace}:incorrect`,
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.incorrect_exp`,
|
text: `${namespace}:incorrect_exp`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
setEncounterExp(scene, scene.getParty().map((p) => p.id), 50);
|
setEncounterExp(scene, scene.getParty().map((p) => p.id), 50);
|
||||||
} else {
|
} else {
|
||||||
encounter.selectedOption!.dialogue!.selected = [
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}:option.selected`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.correct`,
|
text: `${namespace}:correct`,
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.correct_exp`,
|
text: `${namespace}:correct_exp`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
setEncounterExp(scene, [ pokemon.id ], 100);
|
setEncounterExp(scene, [ pokemon.id ], 100);
|
||||||
|
@ -24,7 +24,7 @@ import { EncounterAnim } from "#enums/encounter-anims";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:fieryFallout";
|
const namespace = "mysteryEncounters/fieryFallout";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Damage percentage taken when suffering the heat.
|
* Damage percentage taken when suffering the heat.
|
||||||
@ -49,7 +49,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
.withFleeAllowed(false)
|
.withFleeAllowed(false)
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
@ -122,16 +122,16 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -170,11 +170,11 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -197,7 +197,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
if (chosenPokemon.trySetStatus(StatusEffect.BURN)) {
|
if (chosenPokemon.trySetStatus(StatusEffect.BURN)) {
|
||||||
// Burn applied
|
// Burn applied
|
||||||
encounter.setDialogueToken("burnedPokemon", chosenPokemon.getNameToRender());
|
encounter.setDialogueToken("burnedPokemon", chosenPokemon.getNameToRender());
|
||||||
queueEncounterMessage(scene, `${namespace}.option.2.target_burned`);
|
queueEncounterMessage(scene, `${namespace}:option.2.target_burned`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,12 +211,12 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
.withPrimaryPokemonRequirement(new TypeRequirement(Type.FIRE, true, 1)) // Will set option3PrimaryName dialogue token automatically
|
.withPrimaryPokemonRequirement(new TypeRequirement(Type.FIRE, true, 1)) // Will set option3PrimaryName dialogue token automatically
|
||||||
.withSecondaryPokemonRequirement(new TypeRequirement(Type.FIRE, true, 1)) // Will set option3SecondaryName dialogue token automatically
|
.withSecondaryPokemonRequirement(new TypeRequirement(Type.FIRE, true, 1)) // Will set option3SecondaryName dialogue token automatically
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`,
|
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`,
|
text: `${namespace}:option.3.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -251,6 +251,6 @@ function giveLeadPokemonCharcoal(scene: BattleScene) {
|
|||||||
const charcoal = generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.FIRE ]) as AttackTypeBoosterModifierType;
|
const charcoal = generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.FIRE ]) as AttackTypeBoosterModifierType;
|
||||||
applyModifierTypeToPlayerPokemon(scene, leadPokemon, charcoal);
|
applyModifierTypeToPlayerPokemon(scene, leadPokemon, charcoal);
|
||||||
scene.currentBattle.mysteryEncounter!.setDialogueToken("leadPokemon", leadPokemon.getNameToRender());
|
scene.currentBattle.mysteryEncounter!.setDialogueToken("leadPokemon", leadPokemon.getNameToRender());
|
||||||
queueEncounterMessage(scene, `${namespace}.found_charcoal`);
|
queueEncounterMessage(scene, `${namespace}:found_charcoal`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:fightOrFlight";
|
const namespace = "mysteryEncounters/fightOrFlight";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fight or Flight encounter.
|
* Fight or Flight encounter.
|
||||||
@ -48,7 +48,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
.withIntroSpriteConfigs([]) // Set in onInit()
|
.withIntroSpriteConfigs([]) // Set in onInit()
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
@ -67,7 +67,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
isBoss: true,
|
isBoss: true,
|
||||||
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}.option.1.stat_boost`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.stat_boost`);
|
||||||
// Randomly boost 1 stat 2 stages
|
// Randomly boost 1 stat 2 stages
|
||||||
// Cannot boost Spd, Acc, or Evasion
|
// Cannot boost Spd, Acc, or Evasion
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ randSeedInt(4, 1) ], 2));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ randSeedInt(4, 1) ], 2));
|
||||||
@ -120,16 +120,16 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -146,12 +146,12 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||||
.withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically
|
.withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
disabledButtonTooltip: `${namespace}.option.2.disabled_tooltip`,
|
disabledButtonTooltip: `${namespace}:option.2.disabled_tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`
|
text: `${namespace}:option.2.selected`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@ -170,11 +170,11 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`,
|
text: `${namespace}:option.3.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -25,7 +25,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
import { isPokemonValidForEncounterOptionSelection } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { isPokemonValidForEncounterOptionSelection } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:funAndGames";
|
const namespace = "mysteryEncounters/funAndGames";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fun and Games! encounter.
|
* Fun and Games! encounter.
|
||||||
@ -72,13 +72,13 @@ export const FunAndGamesEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
scene.loadBgm("mystery_encounter_fun_and_games", "mystery_encounter_fun_and_games.mp3");
|
scene.loadBgm("mystery_encounter_fun_and_games", "mystery_encounter_fun_and_games.mp3");
|
||||||
@ -93,11 +93,11 @@ export const FunAndGamesEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withSceneRequirement(new MoneyRequirement(0, 1.5)) // Cost equal to 1 Max Potion
|
.withSceneRequirement(new MoneyRequirement(0, 1.5)) // Cost equal to 1 Max Potion
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -112,7 +112,7 @@ export const FunAndGamesEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Only Pokemon that are not KOed/legal can be selected
|
// Only Pokemon that are not KOed/legal can be selected
|
||||||
const selectableFilter = (pokemon: Pokemon) => {
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}.invalid_selection`);
|
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}:invalid_selection`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
@ -141,11 +141,11 @@ export const FunAndGamesEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -231,7 +231,7 @@ function handleLoseMinigame(scene: BattleScene) {
|
|||||||
scene.currentBattle.enemyParty = [];
|
scene.currentBattle.enemyParty = [];
|
||||||
scene.currentBattle.mysteryEncounter!.doContinueEncounter = undefined;
|
scene.currentBattle.mysteryEncounter!.doContinueEncounter = undefined;
|
||||||
leaveEncounterWithoutBattle(scene, true);
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
await showEncounterText(scene, `${namespace}.ko`);
|
await showEncounterText(scene, `${namespace}:ko`);
|
||||||
const reviveCost = scene.getWaveMoneyAmount(1.5);
|
const reviveCost = scene.getWaveMoneyAmount(1.5);
|
||||||
updatePlayerMoney(scene, -reviveCost, true, false);
|
updatePlayerMoney(scene, -reviveCost, true, false);
|
||||||
}
|
}
|
||||||
@ -257,19 +257,19 @@ function handleNextTurn(scene: BattleScene) {
|
|||||||
if (healthRatio < 0.03) {
|
if (healthRatio < 0.03) {
|
||||||
// Grand prize
|
// Grand prize
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.MULTI_LENS ], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.MULTI_LENS ], fillRemaining: false });
|
||||||
resultMessageKey = `${namespace}.best_result`;
|
resultMessageKey = `${namespace}:best_result`;
|
||||||
} else if (healthRatio < 0.15) {
|
} else if (healthRatio < 0.15) {
|
||||||
// 2nd prize
|
// 2nd prize
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SCOPE_LENS ], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SCOPE_LENS ], fillRemaining: false });
|
||||||
resultMessageKey = `${namespace}.great_result`;
|
resultMessageKey = `${namespace}:great_result`;
|
||||||
} else if (healthRatio < 0.33) {
|
} else if (healthRatio < 0.33) {
|
||||||
// 3rd prize
|
// 3rd prize
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.WIDE_LENS ], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.WIDE_LENS ], fillRemaining: false });
|
||||||
resultMessageKey = `${namespace}.good_result`;
|
resultMessageKey = `${namespace}:good_result`;
|
||||||
} else {
|
} else {
|
||||||
// No prize
|
// No prize
|
||||||
isHealPhase = true;
|
isHealPhase = true;
|
||||||
resultMessageKey = `${namespace}.bad_result`;
|
resultMessageKey = `${namespace}:bad_result`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// End the battle
|
// End the battle
|
||||||
@ -279,7 +279,7 @@ function handleNextTurn(scene: BattleScene) {
|
|||||||
scene.currentBattle.mysteryEncounter!.doContinueEncounter = undefined;
|
scene.currentBattle.mysteryEncounter!.doContinueEncounter = undefined;
|
||||||
leaveEncounterWithoutBattle(scene, isHealPhase);
|
leaveEncounterWithoutBattle(scene, isHealPhase);
|
||||||
// Must end the TurnInit phase prematurely so battle phases aren't added to queue
|
// Must end the TurnInit phase prematurely so battle phases aren't added to queue
|
||||||
queueEncounterMessage(scene, `${namespace}.end_game`);
|
queueEncounterMessage(scene, `${namespace}:end_game`);
|
||||||
queueEncounterMessage(scene, resultMessageKey);
|
queueEncounterMessage(scene, resultMessageKey);
|
||||||
|
|
||||||
// Skip remainder of TurnInitPhase
|
// Skip remainder of TurnInitPhase
|
||||||
@ -287,9 +287,9 @@ function handleNextTurn(scene: BattleScene) {
|
|||||||
} else {
|
} else {
|
||||||
if (encounter.misc.turnsRemaining < 3) {
|
if (encounter.misc.turnsRemaining < 3) {
|
||||||
// Display charging messages on turns that aren't the initial turn
|
// Display charging messages on turns that aren't the initial turn
|
||||||
queueEncounterMessage(scene, `${namespace}.charging_continue`);
|
queueEncounterMessage(scene, `${namespace}:charging_continue`);
|
||||||
}
|
}
|
||||||
queueEncounterMessage(scene, `${namespace}.turn_remaining_${encounter.misc.turnsRemaining}`);
|
queueEncounterMessage(scene, `${namespace}:turn_remaining_${encounter.misc.turnsRemaining}`);
|
||||||
encounter.misc.turnsRemaining--;
|
encounter.misc.turnsRemaining--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
import { addPokemonDataToDexAndValidateAchievements } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { addPokemonDataToDexAndValidateAchievements } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:globalTradeSystem";
|
const namespace = "mysteryEncounters/globalTradeSystem";
|
||||||
|
|
||||||
/** Base shiny chance of 512/65536 -> 1/128 odds, affected by events and Shiny Charms. Cannot exceed 1/16 odds. */
|
/** Base shiny chance of 512/65536 -> 1/128 odds, affected by events and Shiny Charms. Cannot exceed 1/16 odds. */
|
||||||
const WONDER_TRADE_SHINY_CHANCE = 512;
|
const WONDER_TRADE_SHINY_CHANCE = 512;
|
||||||
@ -93,12 +93,12 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
@ -133,9 +133,9 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withHasDexProgress(true)
|
.withHasDexProgress(true)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
secondOptionPrompt: `${namespace}.option.1.trade_options_prompt`,
|
secondOptionPrompt: `${namespace}:option.1.trade_options_prompt`,
|
||||||
})
|
})
|
||||||
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
@ -159,7 +159,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
onHover: () => {
|
onHover: () => {
|
||||||
const formName = tradePokemon.species.forms && tradePokemon.species.forms.length > tradePokemon.formIndex ? tradePokemon.species.forms[pokemon.formIndex].formName : null;
|
const formName = tradePokemon.species.forms && tradePokemon.species.forms.length > tradePokemon.formIndex ? tradePokemon.species.forms[tradePokemon.formIndex].formName : null;
|
||||||
const line1 = i18next.t("pokemonInfoContainer:ability") + " " + tradePokemon.getAbility().name + (tradePokemon.getGender() !== Gender.GENDERLESS ? " | " + i18next.t("pokemonInfoContainer:gender") + " " + getGenderSymbol(tradePokemon.getGender()) : "");
|
const line1 = i18next.t("pokemonInfoContainer:ability") + " " + tradePokemon.getAbility().name + (tradePokemon.getGender() !== Gender.GENDERLESS ? " | " + i18next.t("pokemonInfoContainer:gender") + " " + getGenderSymbol(tradePokemon.getGender()) : "");
|
||||||
const line2 = i18next.t("pokemonInfoContainer:nature") + " " + getNatureName(tradePokemon.getNature()) + (formName ? " | " + i18next.t("pokemonInfoContainer:form") + " " + formName : "");
|
const line2 = i18next.t("pokemonInfoContainer:nature") + " " + getNatureName(tradePokemon.getNature()) + (formName ? " | " + i18next.t("pokemonInfoContainer:form") + " " + formName : "");
|
||||||
showEncounterText(scene, `${line1}\n${line2}`, 0, 0, false);
|
showEncounterText(scene, `${line1}\n${line2}`, 0, 0, false);
|
||||||
@ -201,7 +201,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||||||
// Show the trade animation
|
// Show the trade animation
|
||||||
await showTradeBackground(scene);
|
await showTradeBackground(scene);
|
||||||
await doPokemonTradeSequence(scene, tradedPokemon, newPlayerPokemon);
|
await doPokemonTradeSequence(scene, tradedPokemon, newPlayerPokemon);
|
||||||
await showEncounterText(scene, `${namespace}.trade_received`, null, 0, true, 4000);
|
await showEncounterText(scene, `${namespace}:trade_received`, null, 0, true, 4000);
|
||||||
scene.playBgm(encounter.misc.bgmKey);
|
scene.playBgm(encounter.misc.bgmKey);
|
||||||
await addPokemonDataToDexAndValidateAchievements(scene, newPlayerPokemon);
|
await addPokemonDataToDexAndValidateAchievements(scene, newPlayerPokemon);
|
||||||
await hideTradeBackground(scene);
|
await hideTradeBackground(scene);
|
||||||
@ -216,8 +216,8 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withHasDexProgress(true)
|
.withHasDexProgress(true)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
})
|
})
|
||||||
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
@ -309,7 +309,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||||||
// Show the trade animation
|
// Show the trade animation
|
||||||
await showTradeBackground(scene);
|
await showTradeBackground(scene);
|
||||||
await doPokemonTradeSequence(scene, tradedPokemon, newPlayerPokemon);
|
await doPokemonTradeSequence(scene, tradedPokemon, newPlayerPokemon);
|
||||||
await showEncounterText(scene, `${namespace}.trade_received`, null, 0, true, 4000);
|
await showEncounterText(scene, `${namespace}:trade_received`, null, 0, true, 4000);
|
||||||
scene.playBgm(encounter.misc.bgmKey);
|
scene.playBgm(encounter.misc.bgmKey);
|
||||||
await addPokemonDataToDexAndValidateAchievements(scene, newPlayerPokemon);
|
await addPokemonDataToDexAndValidateAchievements(scene, newPlayerPokemon);
|
||||||
await hideTradeBackground(scene);
|
await hideTradeBackground(scene);
|
||||||
@ -323,9 +323,9 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
secondOptionPrompt: `${namespace}.option.3.trade_options_prompt`,
|
secondOptionPrompt: `${namespace}:option.3.trade_options_prompt`,
|
||||||
})
|
})
|
||||||
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
@ -355,7 +355,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||||||
return it.isTransferable;
|
return it.isTransferable;
|
||||||
}).length > 0;
|
}).length > 0;
|
||||||
if (!meetsReqs) {
|
if (!meetsReqs) {
|
||||||
return getEncounterText(scene, `${namespace}.option.3.invalid_selection`) ?? null;
|
return getEncounterText(scene, `${namespace}:option.3.invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -403,18 +403,18 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||||||
// Generate a trainer name
|
// Generate a trainer name
|
||||||
const traderName = generateRandomTraderName();
|
const traderName = generateRandomTraderName();
|
||||||
encounter.setDialogueToken("tradeTrainerName", traderName.trim());
|
encounter.setDialogueToken("tradeTrainerName", traderName.trim());
|
||||||
await showEncounterText(scene, `${namespace}.item_trade_selected`);
|
await showEncounterText(scene, `${namespace}:item_trade_selected`);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.4.label`,
|
buttonLabel: `${namespace}:option.4.label`,
|
||||||
buttonTooltip: `${namespace}.option.4.tooltip`,
|
buttonTooltip: `${namespace}:option.4.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.4.selected`,
|
text: `${namespace}:option.4.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -628,10 +628,10 @@ function doPokemonTradeSequence(scene: BattleScene, tradedPokemon: PlayerPokemon
|
|||||||
duration: 500,
|
duration: 500,
|
||||||
onComplete: async () => {
|
onComplete: async () => {
|
||||||
scene.fadeOutBgm(1000, false);
|
scene.fadeOutBgm(1000, false);
|
||||||
await showEncounterText(scene, `${namespace}.pokemon_trade_selected`);
|
await showEncounterText(scene, `${namespace}:pokemon_trade_selected`);
|
||||||
tradedPokemon.cry();
|
tradedPokemon.cry();
|
||||||
scene.playBgm("evolution");
|
scene.playBgm("evolution");
|
||||||
await showEncounterText(scene, `${namespace}.pokemon_trade_goodbye`);
|
await showEncounterText(scene, `${namespace}:pokemon_trade_goodbye`);
|
||||||
|
|
||||||
tradedPokeball.setAlpha(0);
|
tradedPokeball.setAlpha(0);
|
||||||
tradedPokeball.setVisible(true);
|
tradedPokeball.setVisible(true);
|
||||||
|
@ -21,7 +21,7 @@ const OPTION_2_REQUIRED_MOVE = Moves.FLY;
|
|||||||
*/
|
*/
|
||||||
const DAMAGE_PERCENTAGE: number = 25;
|
const DAMAGE_PERCENTAGE: number = 25;
|
||||||
/** The i18n namespace for the encounter */
|
/** The i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:lostAtSea";
|
const namespace = "mysteryEncounters/lostAtSea";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lost at sea encounter.
|
* Lost at sea encounter.
|
||||||
@ -40,7 +40,7 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
y: 3,
|
y: 3,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withIntroDialogue([{ text: `${namespace}.intro` }])
|
.withIntroDialogue([{ text: `${namespace}:intro` }])
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
@ -50,22 +50,22 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOption(
|
.withOption(
|
||||||
// Option 1: Use a (non fainted) pokemon that can learn Surf to guide you back/
|
// Option 1: Use a (non fainted) pokemon that can learn Surf to guide you back/
|
||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withPokemonCanLearnMoveRequirement(OPTION_1_REQUIRED_MOVE)
|
.withPokemonCanLearnMoveRequirement(OPTION_1_REQUIRED_MOVE)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
disabledButtonLabel: `${namespace}.option.1.label_disabled`,
|
disabledButtonLabel: `${namespace}:option.1.label_disabled`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
disabledButtonTooltip: `${namespace}.option.1.tooltip_disabled`,
|
disabledButtonTooltip: `${namespace}:option.1.tooltip_disabled`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -78,13 +78,13 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withPokemonCanLearnMoveRequirement(OPTION_2_REQUIRED_MOVE)
|
.withPokemonCanLearnMoveRequirement(OPTION_2_REQUIRED_MOVE)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
disabledButtonLabel: `${namespace}.option.2.label_disabled`,
|
disabledButtonLabel: `${namespace}:option.2.label_disabled`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
disabledButtonTooltip: `${namespace}.option.2.tooltip_disabled`,
|
disabledButtonTooltip: `${namespace}:option.2.tooltip_disabled`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -94,11 +94,11 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
// Option 3: Wander aimlessly
|
// Option 3: Wander aimlessly
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`,
|
text: `${namespace}:option.3.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -118,7 +118,7 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
)
|
)
|
||||||
.withOutroDialogue([
|
.withOutroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.outro`,
|
text: `${namespace}:outro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.build();
|
.build();
|
||||||
|
@ -20,7 +20,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:mysteriousChallengers";
|
const namespace = "mysteryEncounters/mysteriousChallengers";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mysterious Challengers encounter.
|
* Mysterious Challengers encounter.
|
||||||
@ -34,7 +34,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||||||
.withIntroSpriteConfigs([]) // These are set in onInit()
|
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
@ -125,16 +125,16 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}:option.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -155,11 +155,11 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}:option.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -180,11 +180,11 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}:option.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -208,7 +208,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withOutroDialogue([
|
.withOutroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.outro`,
|
text: `${namespace}:outro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.build();
|
.build();
|
||||||
|
@ -16,7 +16,7 @@ import { GameOverPhase } from "#app/phases/game-over-phase";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** i18n namespace for encounter */
|
/** i18n namespace for encounter */
|
||||||
const namespace = "mysteryEncounter:mysteriousChest";
|
const namespace = "mysteryEncounters/mysteriousChest";
|
||||||
|
|
||||||
const RAND_LENGTH = 100;
|
const RAND_LENGTH = 100;
|
||||||
const TRAP_PERCENT = 35;
|
const TRAP_PERCENT = 35;
|
||||||
@ -58,12 +58,12 @@ export const MysteriousChestEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
@ -96,11 +96,11 @@ export const MysteriousChestEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -141,7 +141,7 @@ export const MysteriousChestEncounter: MysteryEncounter =
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
// Display result message then proceed to rewards
|
// Display result message then proceed to rewards
|
||||||
queueEncounterMessage(scene, `${namespace}.option.1.normal`);
|
queueEncounterMessage(scene, `${namespace}:option.1.normal`);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT) {
|
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT) {
|
||||||
// Choose between 3 ULTRA tier items (30%)
|
// Choose between 3 ULTRA tier items (30%)
|
||||||
@ -153,19 +153,19 @@ export const MysteriousChestEncounter: MysteryEncounter =
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
// Display result message then proceed to rewards
|
// Display result message then proceed to rewards
|
||||||
queueEncounterMessage(scene, `${namespace}.option.1.good`);
|
queueEncounterMessage(scene, `${namespace}:option.1.good`);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT) {
|
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT) {
|
||||||
// Choose between 2 ROGUE tier items (10%)
|
// Choose between 2 ROGUE tier items (10%)
|
||||||
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE ]});
|
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE ]});
|
||||||
// Display result message then proceed to rewards
|
// Display result message then proceed to rewards
|
||||||
queueEncounterMessage(scene, `${namespace}.option.1.great`);
|
queueEncounterMessage(scene, `${namespace}:option.1.great`);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT - MASTER_REWARDS_PERCENT) {
|
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT - MASTER_REWARDS_PERCENT) {
|
||||||
// Choose 1 MASTER tier item (5%)
|
// Choose 1 MASTER tier item (5%)
|
||||||
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.MASTER ]});
|
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.MASTER ]});
|
||||||
// Display result message then proceed to rewards
|
// Display result message then proceed to rewards
|
||||||
queueEncounterMessage(scene, `${namespace}.option.1.amazing`);
|
queueEncounterMessage(scene, `${namespace}:option.1.amazing`);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
} else {
|
} else {
|
||||||
// Your highest level unfainted Pokemon gets OHKO. Start battle against a Gimmighoul (35%)
|
// Your highest level unfainted Pokemon gets OHKO. Start battle against a Gimmighoul (35%)
|
||||||
@ -173,7 +173,7 @@ export const MysteriousChestEncounter: MysteryEncounter =
|
|||||||
koPlayerPokemon(scene, highestLevelPokemon);
|
koPlayerPokemon(scene, highestLevelPokemon);
|
||||||
|
|
||||||
encounter.setDialogueToken("pokeName", highestLevelPokemon.getNameToRender());
|
encounter.setDialogueToken("pokeName", highestLevelPokemon.getNameToRender());
|
||||||
await showEncounterText(scene, `${namespace}.option.1.bad`);
|
await showEncounterText(scene, `${namespace}:option.1.bad`);
|
||||||
|
|
||||||
// Handle game over edge case
|
// Handle game over edge case
|
||||||
const allowedPokemon = scene.getParty().filter(p => p.isAllowedInBattle());
|
const allowedPokemon = scene.getParty().filter(p => p.isAllowedInBattle());
|
||||||
@ -193,11 +193,11 @@ export const MysteriousChestEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -15,7 +15,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
import { isPokemonValidForEncounterOptionSelection } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { isPokemonValidForEncounterOptionSelection } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:partTimer";
|
const namespace = "mysteryEncounters/partTimer";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Part Timer encounter.
|
* Part Timer encounter.
|
||||||
@ -45,11 +45,11 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
@ -69,17 +69,17 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOption(MysteryEncounterOptionBuilder
|
.withOption(MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`
|
text: `${namespace}:option.1.selected`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@ -118,7 +118,7 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Only Pokemon non-KOd pokemon can be selected
|
// Only Pokemon non-KOd pokemon can be selected
|
||||||
const selectableFilter = (pokemon: Pokemon) => {
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}.invalid_selection`);
|
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}:invalid_selection`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
@ -132,14 +132,14 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Give money and do dialogue
|
// Give money and do dialogue
|
||||||
if (moneyMultiplier > 2.5) {
|
if (moneyMultiplier > 2.5) {
|
||||||
await showEncounterDialogue(scene, `${namespace}.job_complete_good`, `${namespace}.speaker`);
|
await showEncounterDialogue(scene, `${namespace}:job_complete_good`, `${namespace}:speaker`);
|
||||||
} else {
|
} else {
|
||||||
await showEncounterDialogue(scene, `${namespace}.job_complete_bad`, `${namespace}.speaker`);
|
await showEncounterDialogue(scene, `${namespace}:job_complete_bad`, `${namespace}:speaker`);
|
||||||
}
|
}
|
||||||
const moneyChange = scene.getWaveMoneyAmount(moneyMultiplier);
|
const moneyChange = scene.getWaveMoneyAmount(moneyMultiplier);
|
||||||
updatePlayerMoney(scene, moneyChange, true, false);
|
updatePlayerMoney(scene, moneyChange, true, false);
|
||||||
await showEncounterText(scene, i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange }));
|
await showEncounterText(scene, i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange }));
|
||||||
await showEncounterText(scene, `${namespace}.pokemon_tired`);
|
await showEncounterText(scene, `${namespace}:pokemon_tired`);
|
||||||
|
|
||||||
setEncounterRewards(scene, { fillRemaining: true });
|
setEncounterRewards(scene, { fillRemaining: true });
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
@ -149,11 +149,11 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
.withOption(MysteryEncounterOptionBuilder
|
.withOption(MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`
|
text: `${namespace}:option.2.selected`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@ -195,7 +195,7 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Only Pokemon non-KOd pokemon can be selected
|
// Only Pokemon non-KOd pokemon can be selected
|
||||||
const selectableFilter = (pokemon: Pokemon) => {
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}.invalid_selection`);
|
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}:invalid_selection`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
@ -209,14 +209,14 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Give money and do dialogue
|
// Give money and do dialogue
|
||||||
if (moneyMultiplier > 2.5) {
|
if (moneyMultiplier > 2.5) {
|
||||||
await showEncounterDialogue(scene, `${namespace}.job_complete_good`, `${namespace}.speaker`);
|
await showEncounterDialogue(scene, `${namespace}:job_complete_good`, `${namespace}:speaker`);
|
||||||
} else {
|
} else {
|
||||||
await showEncounterDialogue(scene, `${namespace}.job_complete_bad`, `${namespace}.speaker`);
|
await showEncounterDialogue(scene, `${namespace}:job_complete_bad`, `${namespace}:speaker`);
|
||||||
}
|
}
|
||||||
const moneyChange = scene.getWaveMoneyAmount(moneyMultiplier);
|
const moneyChange = scene.getWaveMoneyAmount(moneyMultiplier);
|
||||||
updatePlayerMoney(scene, moneyChange, true, false);
|
updatePlayerMoney(scene, moneyChange, true, false);
|
||||||
await showEncounterText(scene, i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange }));
|
await showEncounterText(scene, i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange }));
|
||||||
await showEncounterText(scene, `${namespace}.pokemon_tired`);
|
await showEncounterText(scene, `${namespace}:pokemon_tired`);
|
||||||
|
|
||||||
setEncounterRewards(scene, { fillRemaining: true });
|
setEncounterRewards(scene, { fillRemaining: true });
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
@ -228,12 +228,12 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||||
.withPrimaryPokemonRequirement(new MoveRequirement(CHARMING_MOVES)) // Will set option3PrimaryName and option3PrimaryMove dialogue tokens automatically
|
.withPrimaryPokemonRequirement(new MoveRequirement(CHARMING_MOVES)) // Will set option3PrimaryName and option3PrimaryMove dialogue tokens automatically
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`,
|
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`,
|
text: `${namespace}:option.3.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -264,11 +264,11 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
await transitionMysteryEncounterIntroVisuals(scene, false, false);
|
await transitionMysteryEncounterIntroVisuals(scene, false, false);
|
||||||
|
|
||||||
// Give money and do dialogue
|
// Give money and do dialogue
|
||||||
await showEncounterDialogue(scene, `${namespace}.job_complete_good`, `${namespace}.speaker`);
|
await showEncounterDialogue(scene, `${namespace}:job_complete_good`, `${namespace}:speaker`);
|
||||||
const moneyChange = scene.getWaveMoneyAmount(2.5);
|
const moneyChange = scene.getWaveMoneyAmount(2.5);
|
||||||
updatePlayerMoney(scene, moneyChange, true, false);
|
updatePlayerMoney(scene, moneyChange, true, false);
|
||||||
await showEncounterText(scene, i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange }));
|
await showEncounterText(scene, i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange }));
|
||||||
await showEncounterText(scene, `${namespace}.pokemon_tired`);
|
await showEncounterText(scene, `${namespace}:pokemon_tired`);
|
||||||
|
|
||||||
setEncounterRewards(scene, { fillRemaining: true });
|
setEncounterRewards(scene, { fillRemaining: true });
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
@ -277,8 +277,8 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withOutroDialogue([
|
.withOutroDialogue([
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.outro`,
|
text: `${namespace}:outro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
.build();
|
.build();
|
||||||
|
@ -21,7 +21,7 @@ import { SummonPhase } from "#app/phases/summon-phase";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:safariZone";
|
const namespace = "mysteryEncounters/safariZone";
|
||||||
|
|
||||||
const TRAINER_THROW_ANIMATION_TIMES = [ 512, 184, 768 ];
|
const TRAINER_THROW_ANIMATION_TIMES = [ 512, 184, 768 ];
|
||||||
|
|
||||||
@ -51,12 +51,12 @@ export const SafariZoneEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
scene.currentBattle.mysteryEncounter?.setDialogueToken("numEncounters", NUM_SAFARI_ENCOUNTERS.toString());
|
scene.currentBattle.mysteryEncounter?.setDialogueToken("numEncounters", NUM_SAFARI_ENCOUNTERS.toString());
|
||||||
return true;
|
return true;
|
||||||
@ -65,11 +65,11 @@ export const SafariZoneEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withSceneRequirement(new MoneyRequirement(0, SAFARI_MONEY_MULTIPLIER)) // Cost equal to 1 Max Revive
|
.withSceneRequirement(new MoneyRequirement(0, SAFARI_MONEY_MULTIPLIER)) // Cost equal to 1 Max Revive
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -98,11 +98,11 @@ export const SafariZoneEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -133,11 +133,11 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.safari.1.label`,
|
buttonLabel: `${namespace}:safari.1.label`,
|
||||||
buttonTooltip: `${namespace}.safari.1.tooltip`,
|
buttonTooltip: `${namespace}:safari.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.safari.1.selected`,
|
text: `${namespace}:safari.1.selected`,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -168,11 +168,11 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.safari.2.label`,
|
buttonLabel: `${namespace}:safari.2.label`,
|
||||||
buttonTooltip: `${namespace}.safari.2.tooltip`,
|
buttonTooltip: `${namespace}:safari.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.safari.2.selected`,
|
text: `${namespace}:safari.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -186,9 +186,9 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
|
|||||||
// 80% chance to increase flee stage +1
|
// 80% chance to increase flee stage +1
|
||||||
const fleeChangeResult = tryChangeFleeStage(scene, 1, 8);
|
const fleeChangeResult = tryChangeFleeStage(scene, 1, 8);
|
||||||
if (!fleeChangeResult) {
|
if (!fleeChangeResult) {
|
||||||
await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.busy_eating`) ?? "", null, 1000, false );
|
await showEncounterText(scene, getEncounterText(scene, `${namespace}:safari.busy_eating`) ?? "", null, 1000, false );
|
||||||
} else {
|
} else {
|
||||||
await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.eating`) ?? "", null, 1000, false);
|
await showEncounterText(scene, getEncounterText(scene, `${namespace}:safari.eating`) ?? "", null, 1000, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
await doEndTurn(scene, 1);
|
await doEndTurn(scene, 1);
|
||||||
@ -198,11 +198,11 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.safari.3.label`,
|
buttonLabel: `${namespace}:safari.3.label`,
|
||||||
buttonTooltip: `${namespace}.safari.3.tooltip`,
|
buttonTooltip: `${namespace}:safari.3.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.safari.3.selected`,
|
text: `${namespace}:safari.3.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -215,9 +215,9 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
|
|||||||
// 80% chance to decrease catch stage -1
|
// 80% chance to decrease catch stage -1
|
||||||
const catchChangeResult = tryChangeCatchStage(scene, -1, 8);
|
const catchChangeResult = tryChangeCatchStage(scene, -1, 8);
|
||||||
if (!catchChangeResult) {
|
if (!catchChangeResult) {
|
||||||
await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.beside_itself_angry`) ?? "", null, 1000, false );
|
await showEncounterText(scene, getEncounterText(scene, `${namespace}:safari.beside_itself_angry`) ?? "", null, 1000, false );
|
||||||
} else {
|
} else {
|
||||||
await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.angry`) ?? "", null, 1000, false );
|
await showEncounterText(scene, getEncounterText(scene, `${namespace}:safari.angry`) ?? "", null, 1000, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
await doEndTurn(scene, 2);
|
await doEndTurn(scene, 2);
|
||||||
@ -227,8 +227,8 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.safari.4.label`,
|
buttonLabel: `${namespace}:safari.4.label`,
|
||||||
buttonTooltip: `${namespace}.safari.4.tooltip`,
|
buttonTooltip: `${namespace}:safari.4.tooltip`,
|
||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
// Flee option
|
// Flee option
|
||||||
@ -253,7 +253,7 @@ async function summonSafariPokemon(scene: BattleScene) {
|
|||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
// Message pokemon remaining
|
// Message pokemon remaining
|
||||||
encounter.setDialogueToken("remainingCount", encounter.misc.safariPokemonRemaining);
|
encounter.setDialogueToken("remainingCount", encounter.misc.safariPokemonRemaining);
|
||||||
scene.queueMessage(getEncounterText(scene, `${namespace}.safari.remaining_count`) ?? "", null, true);
|
scene.queueMessage(getEncounterText(scene, `${namespace}:safari.remaining_count`) ?? "", null, true);
|
||||||
|
|
||||||
// Generate pokemon using safariPokemonRemaining so they are always the same pokemon no matter how many turns are taken
|
// Generate pokemon using safariPokemonRemaining so they are always the same pokemon no matter how many turns are taken
|
||||||
// Safari pokemon roll twice on shiny and HA chances, but are otherwise normal
|
// Safari pokemon roll twice on shiny and HA chances, but are otherwise normal
|
||||||
@ -518,7 +518,7 @@ async function doEndTurn(scene: BattleScene, cursorIndex: number) {
|
|||||||
leaveEncounterWithoutBattle(scene, true);
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
scene.queueMessage(getEncounterText(scene, `${namespace}.safari.watching`) ?? "", 0, null, 1000);
|
scene.queueMessage(getEncounterText(scene, `${namespace}:safari.watching`) ?? "", 0, null, 1000);
|
||||||
initSubsequentOptionSelect(scene, { overrideOptions: safariZoneGameOptions, startingCursorIndex: cursorIndex, hideDescription: true });
|
initSubsequentOptionSelect(scene, { overrideOptions: safariZoneGameOptions, startingCursorIndex: cursorIndex, hideDescription: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:shadyVitaminDealer";
|
const namespace = "mysteryEncounters/shadyVitaminDealer";
|
||||||
|
|
||||||
const VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER = 1.5;
|
const VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER = 1.5;
|
||||||
const VITAMIN_DEALER_EXPENSIVE_PRICE_MULTIPLIER = 3.5;
|
const VITAMIN_DEALER_EXPENSIVE_PRICE_MULTIPLIER = 3.5;
|
||||||
@ -55,26 +55,26 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOption(
|
.withOption(
|
||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withSceneMoneyRequirement(0, VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER)
|
.withSceneMoneyRequirement(0, VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}:option.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -103,7 +103,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||||||
return i18next.t("partyUiHandler:cantBeUsed", { pokemonName: pokemon.getNameToRender() }) ?? null;
|
return i18next.t("partyUiHandler:cantBeUsed", { pokemonName: pokemon.getNameToRender() }) ?? null;
|
||||||
}
|
}
|
||||||
if (!encounter.pokemonMeetsPrimaryRequirements(scene, pokemon)) {
|
if (!encounter.pokemonMeetsPrimaryRequirements(scene, pokemon)) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
return getEncounterText(scene, `${namespace}:invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -139,7 +139,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
chosenPokemon.nature = newNature;
|
chosenPokemon.nature = newNature;
|
||||||
encounter.setDialogueToken("newNature", getNatureName(newNature));
|
encounter.setDialogueToken("newNature", getNatureName(newNature));
|
||||||
queueEncounterMessage(scene, `${namespace}.cheap_side_effects`);
|
queueEncounterMessage(scene, `${namespace}:cheap_side_effects`);
|
||||||
setEncounterExp(scene, [ chosenPokemon.id ], 100);
|
setEncounterExp(scene, [ chosenPokemon.id ], 100);
|
||||||
chosenPokemon.updateInfo();
|
chosenPokemon.updateInfo();
|
||||||
})
|
})
|
||||||
@ -150,11 +150,11 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withSceneMoneyRequirement(0, VITAMIN_DEALER_EXPENSIVE_PRICE_MULTIPLIER)
|
.withSceneMoneyRequirement(0, VITAMIN_DEALER_EXPENSIVE_PRICE_MULTIPLIER)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}:option.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -178,7 +178,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Only Pokemon that can gain benefits are unfainted
|
// Only Pokemon that can gain benefits are unfainted
|
||||||
const selectableFilter = (pokemon: Pokemon) => {
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}.invalid_selection`);
|
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}:invalid_selection`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
@ -200,7 +200,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
const chosenPokemon = encounter.misc.chosenPokemon;
|
const chosenPokemon = encounter.misc.chosenPokemon;
|
||||||
|
|
||||||
queueEncounterMessage(scene, `${namespace}.no_bad_effects`);
|
queueEncounterMessage(scene, `${namespace}:no_bad_effects`);
|
||||||
setEncounterExp(scene, [ chosenPokemon.id ], 100);
|
setEncounterExp(scene, [ chosenPokemon.id ], 100);
|
||||||
|
|
||||||
chosenPokemon.updateInfo();
|
chosenPokemon.updateInfo();
|
||||||
@ -209,12 +209,12 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`,
|
text: `${namespace}:option.3.selected`,
|
||||||
speaker: `${namespace}.speaker`
|
speaker: `${namespace}:speaker`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -21,7 +21,7 @@ import { BerryType } from "#enums/berry-type";
|
|||||||
import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data";
|
import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data";
|
||||||
|
|
||||||
/** i18n namespace for the encounter */
|
/** i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:slumberingSnorlax";
|
const namespace = "mysteryEncounters/slumberingSnorlax";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sleeping Snorlax encounter.
|
* Sleeping Snorlax encounter.
|
||||||
@ -48,7 +48,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
@ -88,16 +88,16 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -123,11 +123,11 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -135,7 +135,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
|||||||
// Fall asleep waiting for Snorlax
|
// Fall asleep waiting for Snorlax
|
||||||
// Full heal party
|
// Full heal party
|
||||||
scene.unshiftPhase(new PartyHealPhase(scene, true));
|
scene.unshiftPhase(new PartyHealPhase(scene, true));
|
||||||
queueEncounterMessage(scene, `${namespace}.option.2.rest_result`);
|
queueEncounterMessage(scene, `${namespace}:option.2.rest_result`);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -144,12 +144,12 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||||
.withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES))
|
.withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES))
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`,
|
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`
|
text: `${namespace}:option.3.selected`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@ -23,7 +23,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
import { getEncounterPokemonLevelForWave, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { getEncounterPokemonLevelForWave, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:teleportingHijinks";
|
const namespace = "mysteryEncounters/teleportingHijinks";
|
||||||
|
|
||||||
const MONEY_COST_MULTIPLIER = 1.75;
|
const MONEY_COST_MULTIPLIER = 1.75;
|
||||||
const BIOME_CANDIDATES = [ Biome.SPACE, Biome.FAIRY_CAVE, Biome.LABORATORY, Biome.ISLAND, Biome.WASTELAND, Biome.DOJO ];
|
const BIOME_CANDIDATES = [ Biome.SPACE, Biome.FAIRY_CAVE, Biome.LABORATORY, Biome.ISLAND, Biome.WASTELAND, Biome.DOJO ];
|
||||||
@ -55,12 +55,12 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
const price = scene.getWaveMoneyAmount(MONEY_COST_MULTIPLIER);
|
const price = scene.getWaveMoneyAmount(MONEY_COST_MULTIPLIER);
|
||||||
@ -76,11 +76,11 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withSceneMoneyRequirement(0, MONEY_COST_MULTIPLIER) // Must be able to pay teleport cost
|
.withSceneMoneyRequirement(0, MONEY_COST_MULTIPLIER) // Must be able to pay teleport cost
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -100,12 +100,12 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||||
.withPokemonTypeRequirement(MACHINE_INTERFACING_TYPES, true, 1) // Must have Steel or Electric type
|
.withPokemonTypeRequirement(MACHINE_INTERFACING_TYPES, true, 1) // Must have Steel or Electric type
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
disabledButtonTooltip: `${namespace}.option.2.disabled_tooltip`,
|
disabledButtonTooltip: `${namespace}:option.2.disabled_tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -119,11 +119,11 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`,
|
text: `${namespace}:option.3.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -162,10 +162,10 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) {
|
|||||||
const newBiome = filteredBiomes[randSeedInt(filteredBiomes.length)];
|
const newBiome = filteredBiomes[randSeedInt(filteredBiomes.length)];
|
||||||
|
|
||||||
// Show dialogue and transition biome
|
// Show dialogue and transition biome
|
||||||
await showEncounterText(scene, `${namespace}.transport`);
|
await showEncounterText(scene, `${namespace}:transport`);
|
||||||
await Promise.all([ animateBiomeChange(scene, newBiome), transitionMysteryEncounterIntroVisuals(scene) ]);
|
await Promise.all([ animateBiomeChange(scene, newBiome), transitionMysteryEncounterIntroVisuals(scene) ]);
|
||||||
scene.playBgm();
|
scene.playBgm();
|
||||||
await showEncounterText(scene, `${namespace}.attacked`);
|
await showEncounterText(scene, `${namespace}:attacked`);
|
||||||
|
|
||||||
// Init enemy
|
// Init enemy
|
||||||
const level = getEncounterPokemonLevelForWave(scene, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
|
const level = getEncounterPokemonLevelForWave(scene, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
|
||||||
@ -186,7 +186,7 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) {
|
|||||||
isBoss: true,
|
isBoss: true,
|
||||||
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}.boss_enraged`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:boss_enraged`);
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
@ -10,7 +10,8 @@ import { Biome } from "#enums/biome";
|
|||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species";
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
import { speciesStarterCosts } from "#app/data/balance/starters";
|
||||||
import { Nature } from "#enums/nature";
|
import { Nature } from "#enums/nature";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { PlayerPokemon } from "#app/field/pokemon";
|
import { PlayerPokemon } from "#app/field/pokemon";
|
||||||
@ -26,7 +27,7 @@ import { Type } from "#app/data/type";
|
|||||||
import { getPokeballTintColor } from "#app/data/pokeball";
|
import { getPokeballTintColor } from "#app/data/pokeball";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:expertPokemonBreeder";
|
const namespace = "mysteryEncounters/theExpertPokemonBreeder";
|
||||||
|
|
||||||
const trainerNameKey = "trainerNames:expert_pokemon_breeder";
|
const trainerNameKey = "trainerNames:expert_pokemon_breeder";
|
||||||
|
|
||||||
@ -85,11 +86,11 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
|
|||||||
.withIntroSpriteConfigs([]) // These are set in onInit()
|
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
speaker: trainerNameKey,
|
speaker: trainerNameKey,
|
||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
@ -138,45 +139,45 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Dialogue and egg calcs for Pokemon 1
|
// Dialogue and egg calcs for Pokemon 1
|
||||||
const [ pokemon1CommonEggs, pokemon1RareEggs ] = calculateEggRewardsForPokemon(pokemon1);
|
const [ pokemon1CommonEggs, pokemon1RareEggs ] = calculateEggRewardsForPokemon(pokemon1);
|
||||||
let pokemon1Tooltip = getEncounterText(scene, `${namespace}.option.1.tooltip_base`)!;
|
let pokemon1Tooltip = getEncounterText(scene, `${namespace}:option.1.tooltip_base`)!;
|
||||||
if (pokemon1RareEggs > 0) {
|
if (pokemon1RareEggs > 0) {
|
||||||
const eggsText = i18next.t(`${namespace}.numEggs`, { count: pokemon1RareEggs, rarity: i18next.t("egg:greatTier") });
|
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon1RareEggs, rarity: i18next.t("egg:greatTier") });
|
||||||
pokemon1Tooltip += i18next.t(`${namespace}.eggs_tooltip`, { eggs: eggsText });
|
pokemon1Tooltip += i18next.t(`${namespace}:eggs_tooltip`, { eggs: eggsText });
|
||||||
encounter.setDialogueToken("pokemon1RareEggs", eggsText);
|
encounter.setDialogueToken("pokemon1RareEggs", eggsText);
|
||||||
}
|
}
|
||||||
if (pokemon1CommonEggs > 0) {
|
if (pokemon1CommonEggs > 0) {
|
||||||
const eggsText = i18next.t(`${namespace}.numEggs`, { count: pokemon1CommonEggs, rarity: i18next.t("egg:defaultTier") });
|
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon1CommonEggs, rarity: i18next.t("egg:defaultTier") });
|
||||||
pokemon1Tooltip += i18next.t(`${namespace}.eggs_tooltip`, { eggs: eggsText });
|
pokemon1Tooltip += i18next.t(`${namespace}:eggs_tooltip`, { eggs: eggsText });
|
||||||
encounter.setDialogueToken("pokemon1CommonEggs", eggsText);
|
encounter.setDialogueToken("pokemon1CommonEggs", eggsText);
|
||||||
}
|
}
|
||||||
encounter.options[0].dialogue!.buttonTooltip = pokemon1Tooltip;
|
encounter.options[0].dialogue!.buttonTooltip = pokemon1Tooltip;
|
||||||
|
|
||||||
// Dialogue and egg calcs for Pokemon 2
|
// Dialogue and egg calcs for Pokemon 2
|
||||||
const [ pokemon2CommonEggs, pokemon2RareEggs ] = calculateEggRewardsForPokemon(pokemon2);
|
const [ pokemon2CommonEggs, pokemon2RareEggs ] = calculateEggRewardsForPokemon(pokemon2);
|
||||||
let pokemon2Tooltip = getEncounterText(scene, `${namespace}.option.2.tooltip_base`)!;
|
let pokemon2Tooltip = getEncounterText(scene, `${namespace}:option.2.tooltip_base`)!;
|
||||||
if (pokemon2RareEggs > 0) {
|
if (pokemon2RareEggs > 0) {
|
||||||
const eggsText = i18next.t(`${namespace}.numEggs`, { count: pokemon2RareEggs, rarity: i18next.t("egg:greatTier") });
|
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon2RareEggs, rarity: i18next.t("egg:greatTier") });
|
||||||
pokemon2Tooltip += i18next.t(`${namespace}.eggs_tooltip`, { eggs: eggsText });
|
pokemon2Tooltip += i18next.t(`${namespace}:eggs_tooltip`, { eggs: eggsText });
|
||||||
encounter.setDialogueToken("pokemon2RareEggs", eggsText);
|
encounter.setDialogueToken("pokemon2RareEggs", eggsText);
|
||||||
}
|
}
|
||||||
if (pokemon2CommonEggs > 0) {
|
if (pokemon2CommonEggs > 0) {
|
||||||
const eggsText = i18next.t(`${namespace}.numEggs`, { count: pokemon2CommonEggs, rarity: i18next.t("egg:defaultTier") });
|
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon2CommonEggs, rarity: i18next.t("egg:defaultTier") });
|
||||||
pokemon2Tooltip += i18next.t(`${namespace}.eggs_tooltip`, { eggs: eggsText });
|
pokemon2Tooltip += i18next.t(`${namespace}:eggs_tooltip`, { eggs: eggsText });
|
||||||
encounter.setDialogueToken("pokemon1CommonEggs", eggsText);
|
encounter.setDialogueToken("pokemon1CommonEggs", eggsText);
|
||||||
}
|
}
|
||||||
encounter.options[1].dialogue!.buttonTooltip = pokemon2Tooltip;
|
encounter.options[1].dialogue!.buttonTooltip = pokemon2Tooltip;
|
||||||
|
|
||||||
// Dialogue and egg calcs for Pokemon 3
|
// Dialogue and egg calcs for Pokemon 3
|
||||||
const [ pokemon3CommonEggs, pokemon3RareEggs ] = calculateEggRewardsForPokemon(pokemon3);
|
const [ pokemon3CommonEggs, pokemon3RareEggs ] = calculateEggRewardsForPokemon(pokemon3);
|
||||||
let pokemon3Tooltip = getEncounterText(scene, `${namespace}.option.3.tooltip_base`)!;
|
let pokemon3Tooltip = getEncounterText(scene, `${namespace}:option.3.tooltip_base`)!;
|
||||||
if (pokemon3RareEggs > 0) {
|
if (pokemon3RareEggs > 0) {
|
||||||
const eggsText = i18next.t(`${namespace}.numEggs`, { count: pokemon3RareEggs, rarity: i18next.t("egg:greatTier") });
|
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon3RareEggs, rarity: i18next.t("egg:greatTier") });
|
||||||
pokemon3Tooltip += i18next.t(`${namespace}.eggs_tooltip`, { eggs: eggsText });
|
pokemon3Tooltip += i18next.t(`${namespace}:eggs_tooltip`, { eggs: eggsText });
|
||||||
encounter.setDialogueToken("pokemon3RareEggs", eggsText);
|
encounter.setDialogueToken("pokemon3RareEggs", eggsText);
|
||||||
}
|
}
|
||||||
if (pokemon3CommonEggs > 0) {
|
if (pokemon3CommonEggs > 0) {
|
||||||
const eggsText = i18next.t(`${namespace}.numEggs`, { count: pokemon3CommonEggs, rarity: i18next.t("egg:defaultTier") });
|
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon3CommonEggs, rarity: i18next.t("egg:defaultTier") });
|
||||||
pokemon3Tooltip += i18next.t(`${namespace}.eggs_tooltip`, { eggs: eggsText });
|
pokemon3Tooltip += i18next.t(`${namespace}:eggs_tooltip`, { eggs: eggsText });
|
||||||
encounter.setDialogueToken("pokemon3CommonEggs", eggsText);
|
encounter.setDialogueToken("pokemon3CommonEggs", eggsText);
|
||||||
}
|
}
|
||||||
encounter.options[2].dialogue!.buttonTooltip = pokemon3Tooltip;
|
encounter.options[2].dialogue!.buttonTooltip = pokemon3Tooltip;
|
||||||
@ -195,18 +196,18 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOption(
|
.withOption(
|
||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
speaker: trainerNameKey,
|
speaker: trainerNameKey,
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}:option.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -228,17 +229,17 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
|
|||||||
encounter.dialogue.outro = [
|
encounter.dialogue.outro = [
|
||||||
{
|
{
|
||||||
speaker: trainerNameKey,
|
speaker: trainerNameKey,
|
||||||
text: `${namespace}.outro`,
|
text: `${namespace}:outro`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
if (encounter.dialogueTokens.hasOwnProperty("pokemon1CommonEggs")) {
|
if (encounter.dialogueTokens.hasOwnProperty("pokemon1CommonEggs")) {
|
||||||
encounter.dialogue.outro.push({
|
encounter.dialogue.outro.push({
|
||||||
text: i18next.t(`${namespace}.gained_eggs`, { numEggs: encounter.dialogueTokens["pokemon1CommonEggs"] }),
|
text: i18next.t(`${namespace}:gained_eggs`, { numEggs: encounter.dialogueTokens["pokemon1CommonEggs"] }),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (encounter.dialogueTokens.hasOwnProperty("pokemon1RareEggs")) {
|
if (encounter.dialogueTokens.hasOwnProperty("pokemon1RareEggs")) {
|
||||||
encounter.dialogue.outro.push({
|
encounter.dialogue.outro.push({
|
||||||
text: i18next.t(`${namespace}.gained_eggs`, { numEggs: encounter.dialogueTokens["pokemon1RareEggs"] }),
|
text: i18next.t(`${namespace}:gained_eggs`, { numEggs: encounter.dialogueTokens["pokemon1RareEggs"] }),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,11 +255,11 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
speaker: trainerNameKey,
|
speaker: trainerNameKey,
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}:option.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -280,17 +281,17 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
|
|||||||
encounter.dialogue.outro = [
|
encounter.dialogue.outro = [
|
||||||
{
|
{
|
||||||
speaker: trainerNameKey,
|
speaker: trainerNameKey,
|
||||||
text: `${namespace}.outro`,
|
text: `${namespace}:outro`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
if (encounter.dialogueTokens.hasOwnProperty("pokemon2CommonEggs")) {
|
if (encounter.dialogueTokens.hasOwnProperty("pokemon2CommonEggs")) {
|
||||||
encounter.dialogue.outro.push({
|
encounter.dialogue.outro.push({
|
||||||
text: i18next.t(`${namespace}.gained_eggs`, { numEggs: encounter.dialogueTokens["pokemon2CommonEggs"] }),
|
text: i18next.t(`${namespace}:gained_eggs`, { numEggs: encounter.dialogueTokens["pokemon2CommonEggs"] }),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (encounter.dialogueTokens.hasOwnProperty("pokemon2RareEggs")) {
|
if (encounter.dialogueTokens.hasOwnProperty("pokemon2RareEggs")) {
|
||||||
encounter.dialogue.outro.push({
|
encounter.dialogue.outro.push({
|
||||||
text: i18next.t(`${namespace}.gained_eggs`, { numEggs: encounter.dialogueTokens["pokemon2RareEggs"] }),
|
text: i18next.t(`${namespace}:gained_eggs`, { numEggs: encounter.dialogueTokens["pokemon2RareEggs"] }),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,11 +307,11 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
speaker: trainerNameKey,
|
speaker: trainerNameKey,
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}:option.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -332,17 +333,17 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
|
|||||||
encounter.dialogue.outro = [
|
encounter.dialogue.outro = [
|
||||||
{
|
{
|
||||||
speaker: trainerNameKey,
|
speaker: trainerNameKey,
|
||||||
text: `${namespace}.outro`,
|
text: `${namespace}:outro`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
if (encounter.dialogueTokens.hasOwnProperty("pokemon3CommonEggs")) {
|
if (encounter.dialogueTokens.hasOwnProperty("pokemon3CommonEggs")) {
|
||||||
encounter.dialogue.outro.push({
|
encounter.dialogue.outro.push({
|
||||||
text: i18next.t(`${namespace}.gained_eggs`, { numEggs: encounter.dialogueTokens["pokemon3CommonEggs"] }),
|
text: i18next.t(`${namespace}:gained_eggs`, { numEggs: encounter.dialogueTokens["pokemon3CommonEggs"] }),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (encounter.dialogueTokens.hasOwnProperty("pokemon3RareEggs")) {
|
if (encounter.dialogueTokens.hasOwnProperty("pokemon3RareEggs")) {
|
||||||
encounter.dialogue.outro.push({
|
encounter.dialogue.outro.push({
|
||||||
text: i18next.t(`${namespace}.gained_eggs`, { numEggs: encounter.dialogueTokens["pokemon3RareEggs"] }),
|
text: i18next.t(`${namespace}:gained_eggs`, { numEggs: encounter.dialogueTokens["pokemon3RareEggs"] }),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +358,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
|
|||||||
.withOutroDialogue([
|
.withOutroDialogue([
|
||||||
{
|
{
|
||||||
speaker: trainerNameKey,
|
speaker: trainerNameKey,
|
||||||
text: `${namespace}.outro`,
|
text: `${namespace}:outro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.build();
|
.build();
|
||||||
@ -374,7 +375,7 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
trainerType: TrainerType.EXPERT_POKEMON_BREEDER,
|
trainerType: TrainerType.EXPERT_POKEMON_BREEDER,
|
||||||
pokemonConfigs: [
|
pokemonConfigs: [
|
||||||
{
|
{
|
||||||
nickname: i18next.t(`${namespace}.cleffa_1_nickname`, { speciesName: getPokemonSpecies(cleffaSpecies).getName() }),
|
nickname: i18next.t(`${namespace}:cleffa_1_nickname`, { speciesName: getPokemonSpecies(cleffaSpecies).getName() }),
|
||||||
species: getPokemonSpecies(cleffaSpecies),
|
species: getPokemonSpecies(cleffaSpecies),
|
||||||
isBoss: false,
|
isBoss: false,
|
||||||
abilityIndex: 1, // Magic Guard
|
abilityIndex: 1, // Magic Guard
|
||||||
@ -394,7 +395,7 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
if (scene.arena.biomeType === Biome.SPACE) {
|
if (scene.arena.biomeType === Biome.SPACE) {
|
||||||
// All 3 members always Cleffa line, but different configs
|
// All 3 members always Cleffa line, but different configs
|
||||||
baseConfig.pokemonConfigs!.push({
|
baseConfig.pokemonConfigs!.push({
|
||||||
nickname: i18next.t(`${namespace}.cleffa_2_nickname`, { speciesName: getPokemonSpecies(cleffaSpecies).getName() }),
|
nickname: i18next.t(`${namespace}:cleffa_2_nickname`, { speciesName: getPokemonSpecies(cleffaSpecies).getName() }),
|
||||||
species: getPokemonSpecies(cleffaSpecies),
|
species: getPokemonSpecies(cleffaSpecies),
|
||||||
isBoss: false,
|
isBoss: false,
|
||||||
abilityIndex: 1, // Magic Guard
|
abilityIndex: 1, // Magic Guard
|
||||||
@ -405,7 +406,7 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
ivs: [ 31, 31, 31, 31, 31, 31 ]
|
ivs: [ 31, 31, 31, 31, 31, 31 ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
nickname: i18next.t(`${namespace}.cleffa_3_nickname`, { speciesName: getPokemonSpecies(cleffaSpecies).getName() }),
|
nickname: i18next.t(`${namespace}:cleffa_3_nickname`, { speciesName: getPokemonSpecies(cleffaSpecies).getName() }),
|
||||||
species: getPokemonSpecies(cleffaSpecies),
|
species: getPokemonSpecies(cleffaSpecies),
|
||||||
isBoss: false,
|
isBoss: false,
|
||||||
abilityIndex: 2, // Friend Guard / Unaware
|
abilityIndex: 2, // Friend Guard / Unaware
|
||||||
@ -454,8 +455,8 @@ function calculateEggRewardsForPokemon(pokemon: PlayerPokemon): [number, number]
|
|||||||
const rootSpecies = pokemon.species.getRootSpeciesId();
|
const rootSpecies = pokemon.species.getRootSpeciesId();
|
||||||
let pointsFromStarterTier = 0;
|
let pointsFromStarterTier = 0;
|
||||||
// 2 points for every 1 below 7 that the pokemon's starter tier is (max 12, min 0)
|
// 2 points for every 1 below 7 that the pokemon's starter tier is (max 12, min 0)
|
||||||
if (speciesStarters.hasOwnProperty(rootSpecies)) {
|
if (speciesStarterCosts.hasOwnProperty(rootSpecies)) {
|
||||||
const starterTier = speciesStarters[rootSpecies];
|
const starterTier = speciesStarterCosts[rootSpecies];
|
||||||
pointsFromStarterTier = Math.min(Math.max(Math.floor(7 - starterTier) * 2, 0), 12);
|
pointsFromStarterTier = Math.min(Math.max(Math.floor(7 - starterTier) * 2, 0), 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,7 +472,7 @@ function calculateEggRewardsForPokemon(pokemon: PlayerPokemon): [number, number]
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getEggOptions(scene: BattleScene, commonEggs: number, rareEggs: number) {
|
function getEggOptions(scene: BattleScene, commonEggs: number, rareEggs: number) {
|
||||||
const eggDescription = i18next.t(`${namespace}.title`) + ":\n" + i18next.t(trainerNameKey);
|
const eggDescription = i18next.t(`${namespace}:title`) + ":\n" + i18next.t(trainerNameKey);
|
||||||
const eggOptions: IEggOptions[] = [];
|
const eggOptions: IEggOptions[] = [];
|
||||||
|
|
||||||
if (commonEggs > 0) {
|
if (commonEggs > 0) {
|
||||||
@ -540,7 +541,7 @@ function onGameOver(scene: BattleScene) {
|
|||||||
encounter.dialogue.outro = [
|
encounter.dialogue.outro = [
|
||||||
{
|
{
|
||||||
speaker: trainerNameKey,
|
speaker: trainerNameKey,
|
||||||
text: `${namespace}.outro_failed`,
|
text: `${namespace}:outro_failed`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -558,6 +559,10 @@ function onGameOver(scene: BattleScene) {
|
|||||||
// Revert BGM
|
// Revert BGM
|
||||||
scene.playBgm(scene.arena.bgm);
|
scene.playBgm(scene.arena.bgm);
|
||||||
|
|
||||||
|
// Clear any leftover battle phases
|
||||||
|
scene.clearPhaseQueue();
|
||||||
|
scene.clearPhaseQueueSplice();
|
||||||
|
|
||||||
// Return enemy Pokemon
|
// Return enemy Pokemon
|
||||||
const pokemon = scene.getEnemyPokemon();
|
const pokemon = scene.getEnemyPokemon();
|
||||||
if (pokemon) {
|
if (pokemon) {
|
||||||
|
@ -5,7 +5,8 @@ import BattleScene from "#app/battle-scene";
|
|||||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||||
import { MoneyRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
import { MoneyRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||||
import { catchPokemon, getRandomSpeciesByStarterTier, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { catchPokemon, getRandomSpeciesByStarterTier, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
import { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species";
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
import { speciesStarterCosts } from "#app/data/balance/starters";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { PokeballType } from "#app/data/pokeball";
|
import { PokeballType } from "#app/data/pokeball";
|
||||||
import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon";
|
import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon";
|
||||||
@ -18,7 +19,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:pokemonSalesman";
|
const namespace = "mysteryEncounters/thePokemonSalesman";
|
||||||
|
|
||||||
const MAX_POKEMON_PRICE_MULTIPLIER = 4;
|
const MAX_POKEMON_PRICE_MULTIPLIER = 4;
|
||||||
|
|
||||||
@ -45,16 +46,16 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
@ -88,15 +89,15 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
|||||||
isPokemon: true
|
isPokemon: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const starterTier = speciesStarters[species.speciesId];
|
const starterTier = speciesStarterCosts[species.speciesId];
|
||||||
// Prices decrease by starter tier less than 5, but only reduces cost by half at max
|
// Prices decrease by starter tier less than 5, but only reduces cost by half at max
|
||||||
let priceMultiplier = MAX_POKEMON_PRICE_MULTIPLIER * (Math.max(starterTier, 2.5) / 5);
|
let priceMultiplier = MAX_POKEMON_PRICE_MULTIPLIER * (Math.max(starterTier, 2.5) / 5);
|
||||||
if (pokemon.shiny) {
|
if (pokemon.shiny) {
|
||||||
// Always max price for shiny (flip HA back to normal), and add special messaging
|
// Always max price for shiny (flip HA back to normal), and add special messaging
|
||||||
priceMultiplier = MAX_POKEMON_PRICE_MULTIPLIER;
|
priceMultiplier = MAX_POKEMON_PRICE_MULTIPLIER;
|
||||||
pokemon.abilityIndex = 0;
|
pokemon.abilityIndex = 0;
|
||||||
encounter.dialogue.encounterOptionsDialogue!.description = `${namespace}.description_shiny`;
|
encounter.dialogue.encounterOptionsDialogue!.description = `${namespace}:description_shiny`;
|
||||||
encounter.options[0].dialogue!.buttonTooltip = `${namespace}.option.1.tooltip_shiny`;
|
encounter.options[0].dialogue!.buttonTooltip = `${namespace}:option.1.tooltip_shiny`;
|
||||||
}
|
}
|
||||||
const price = scene.getWaveMoneyAmount(priceMultiplier);
|
const price = scene.getWaveMoneyAmount(priceMultiplier);
|
||||||
encounter.setDialogueToken("purchasePokemon", pokemon.getNameToRender());
|
encounter.setDialogueToken("purchasePokemon", pokemon.getNameToRender());
|
||||||
@ -116,11 +117,11 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
|||||||
.withHasDexProgress(true)
|
.withHasDexProgress(true)
|
||||||
.withSceneMoneyRequirement(0, MAX_POKEMON_PRICE_MULTIPLIER) // Wave scaling money multiplier of 2
|
.withSceneMoneyRequirement(0, MAX_POKEMON_PRICE_MULTIPLIER) // Wave scaling money multiplier of 2
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected_message`,
|
text: `${namespace}:option.1.selected_message`,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -133,7 +134,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
|||||||
updatePlayerMoney(scene, -price, true, false);
|
updatePlayerMoney(scene, -price, true, false);
|
||||||
|
|
||||||
// Show dialogue
|
// Show dialogue
|
||||||
await showEncounterDialogue(scene, `${namespace}.option.1.selected_dialogue`, `${namespace}.speaker`);
|
await showEncounterDialogue(scene, `${namespace}:option.1.selected_dialogue`, `${namespace}:speaker`);
|
||||||
await transitionMysteryEncounterIntroVisuals(scene);
|
await transitionMysteryEncounterIntroVisuals(scene);
|
||||||
|
|
||||||
// "Catch" purchased pokemon
|
// "Catch" purchased pokemon
|
||||||
@ -147,11 +148,11 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -20,7 +20,7 @@ import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:theStrongStuff";
|
const namespace = "mysteryEncounters/theStrongStuff";
|
||||||
|
|
||||||
// Halved for HP stat
|
// Halved for HP stat
|
||||||
const HIGH_BST_REDUCTION_VALUE = 15;
|
const HIGH_BST_REDUCTION_VALUE = 15;
|
||||||
@ -64,7 +64,7 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||||||
]) // Set in onInit()
|
]) // Set in onInit()
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
@ -102,7 +102,7 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||||||
],
|
],
|
||||||
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}.option.2.stat_boost`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:option.2.stat_boost`);
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.DEF, Stat.SPDEF ], 2));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.DEF, Stat.SPDEF ], 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,16 +117,16 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`
|
text: `${namespace}:option.1.selected`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -159,11 +159,11 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
encounter.setDialogueToken("reductionValue", HIGH_BST_REDUCTION_VALUE.toString());
|
encounter.setDialogueToken("reductionValue", HIGH_BST_REDUCTION_VALUE.toString());
|
||||||
encounter.setDialogueToken("increaseValue", BST_INCREASE_VALUE.toString());
|
encounter.setDialogueToken("increaseValue", BST_INCREASE_VALUE.toString());
|
||||||
await showEncounterText(scene, `${namespace}.option.1.selected_2`, null, undefined, true);
|
await showEncounterText(scene, `${namespace}:option.1.selected_2`, null, undefined, true);
|
||||||
|
|
||||||
encounter.dialogue.outro = [
|
encounter.dialogue.outro = [
|
||||||
{
|
{
|
||||||
text: `${namespace}.outro`,
|
text: `${namespace}:outro`,
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
setEncounterRewards(scene, { fillRemaining: true });
|
setEncounterRewards(scene, { fillRemaining: true });
|
||||||
@ -173,11 +173,11 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -25,7 +25,7 @@ import { ModifierTier } from "#app/modifier/modifier-tier";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:theWinstrateChallenge";
|
const namespace = "mysteryEncounters/theWinstrateChallenge";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Winstrate Challenge encounter.
|
* The Winstrate Challenge encounter.
|
||||||
@ -74,11 +74,11 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
@ -94,17 +94,17 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -119,12 +119,12 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -142,7 +142,7 @@ async function spawnNextTrainerOrEndEncounter(scene: BattleScene) {
|
|||||||
const nextConfig = encounter.enemyPartyConfigs.pop();
|
const nextConfig = encounter.enemyPartyConfigs.pop();
|
||||||
if (!nextConfig) {
|
if (!nextConfig) {
|
||||||
await transitionMysteryEncounterIntroVisuals(scene, false, false);
|
await transitionMysteryEncounterIntroVisuals(scene, false, false);
|
||||||
await showEncounterDialogue(scene, `${namespace}.victory`, `${namespace}.speaker`);
|
await showEncounterDialogue(scene, `${namespace}:victory`, `${namespace}:speaker`);
|
||||||
|
|
||||||
// Give 10x Voucher
|
// Give 10x Voucher
|
||||||
const newModifier = modifierTypes.VOUCHER_PREMIUM().newModifier();
|
const newModifier = modifierTypes.VOUCHER_PREMIUM().newModifier();
|
||||||
@ -150,7 +150,7 @@ async function spawnNextTrainerOrEndEncounter(scene: BattleScene) {
|
|||||||
scene.playSound("item_fanfare");
|
scene.playSound("item_fanfare");
|
||||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: newModifier?.type.name }));
|
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: newModifier?.type.name }));
|
||||||
|
|
||||||
await showEncounterDialogue(scene, `${namespace}.victory_2`, `${namespace}.speaker`);
|
await showEncounterDialogue(scene, `${namespace}:victory_2`, `${namespace}:speaker`);
|
||||||
scene.ui.clearText(); // Clears "Winstrate" title from screen as rewards get animated in
|
scene.ui.clearText(); // Clears "Winstrate" title from screen as rewards get animated in
|
||||||
const machoBrace = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE)!;
|
const machoBrace = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE)!;
|
||||||
machoBrace.type.tier = ModifierTier.MASTER;
|
machoBrace.type.tier = ModifierTier.MASTER;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Ability, allAbilities } from "#app/data/ability";
|
import { Ability, allAbilities } from "#app/data/ability";
|
||||||
import { EnemyPartyConfig, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, selectPokemonForOption, setEncounterRewards, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
import { EnemyPartyConfig, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, selectPokemonForOption, setEncounterRewards, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { getNatureName, Nature } from "#app/data/nature";
|
import { getNatureName, Nature } from "#app/data/nature";
|
||||||
import { speciesStarters } from "#app/data/pokemon-species";
|
import { speciesStarterCosts } from "#app/data/balance/starters";
|
||||||
import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
|
import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
|
||||||
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
|
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||||
import { AbilityAttr } from "#app/system/game-data";
|
import { AbilityAttr } from "#app/system/game-data";
|
||||||
@ -23,7 +23,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
import { isPokemonValidForEncounterOptionSelection } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { isPokemonValidForEncounterOptionSelection } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
|
||||||
/** The i18n namespace for the encounter */
|
/** The i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:trainingSession";
|
const namespace = "mysteryEncounters/trainingSession";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Training Session encounter.
|
* Training Session encounter.
|
||||||
@ -49,22 +49,22 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOption(
|
.withOption(
|
||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withHasDexProgress(true)
|
.withHasDexProgress(true)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}:option.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -78,7 +78,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Only Pokemon that are not KOed/legal can be trained
|
// Only Pokemon that are not KOed/legal can be trained
|
||||||
const selectableFilter = (pokemon: Pokemon) => {
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}.invalid_selection`);
|
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}:invalid_selection`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
@ -156,7 +156,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
scene.addModifier(mod, true, false, false, true);
|
scene.addModifier(mod, true, false, false, true);
|
||||||
}
|
}
|
||||||
scene.updateModifiers(true);
|
scene.updateModifiers(true);
|
||||||
queueEncounterMessage(scene, `${namespace}.option.1.finished`);
|
queueEncounterMessage(scene, `${namespace}:option.1.finished`);
|
||||||
};
|
};
|
||||||
|
|
||||||
setEncounterRewards(scene, { fillRemaining: true }, undefined, onBeforeRewardsPhase);
|
setEncounterRewards(scene, { fillRemaining: true }, undefined, onBeforeRewardsPhase);
|
||||||
@ -170,12 +170,12 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withHasDexProgress(true)
|
.withHasDexProgress(true)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
secondOptionPrompt: `${namespace}.option.2.select_prompt`,
|
secondOptionPrompt: `${namespace}:option.2.select_prompt`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}:option.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -204,7 +204,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Only Pokemon that are not KOed/legal can be trained
|
// Only Pokemon that are not KOed/legal can be trained
|
||||||
const selectableFilter = (pokemon: Pokemon) => {
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}.invalid_selection`);
|
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}:invalid_selection`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
@ -221,7 +221,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
scene.removePokemonFromPlayerParty(playerPokemon, false);
|
scene.removePokemonFromPlayerParty(playerPokemon, false);
|
||||||
|
|
||||||
const onBeforeRewardsPhase = () => {
|
const onBeforeRewardsPhase = () => {
|
||||||
queueEncounterMessage(scene, `${namespace}.option.2.finished`);
|
queueEncounterMessage(scene, `${namespace}:option.2.finished`);
|
||||||
// Add the pokemon back to party with Nature change
|
// Add the pokemon back to party with Nature change
|
||||||
playerPokemon.setNature(encounter.misc.chosenNature);
|
playerPokemon.setNature(encounter.misc.chosenNature);
|
||||||
scene.gameData.setPokemonCaught(playerPokemon, false);
|
scene.gameData.setPokemonCaught(playerPokemon, false);
|
||||||
@ -246,12 +246,12 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withHasDexProgress(true)
|
.withHasDexProgress(true)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
secondOptionPrompt: `${namespace}.option.3.select_prompt`,
|
secondOptionPrompt: `${namespace}:option.3.select_prompt`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}:option.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -295,7 +295,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Only Pokemon that are not KOed/legal can be trained
|
// Only Pokemon that are not KOed/legal can be trained
|
||||||
const selectableFilter = (pokemon: Pokemon) => {
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}.invalid_selection`);
|
return isPokemonValidForEncounterOptionSelection(pokemon, scene, `${namespace}:invalid_selection`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
@ -316,7 +316,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
scene.removePokemonFromPlayerParty(playerPokemon, false);
|
scene.removePokemonFromPlayerParty(playerPokemon, false);
|
||||||
|
|
||||||
const onBeforeRewardsPhase = () => {
|
const onBeforeRewardsPhase = () => {
|
||||||
queueEncounterMessage(scene, `${namespace}.option.3.finished`);
|
queueEncounterMessage(scene, `${namespace}:option.3.finished`);
|
||||||
// Add the pokemon back to party with ability change
|
// Add the pokemon back to party with ability change
|
||||||
const abilityIndex = encounter.misc.abilityIndex;
|
const abilityIndex = encounter.misc.abilityIndex;
|
||||||
|
|
||||||
@ -326,7 +326,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
// Only update the fusion's dex data if the Pokemon is already caught in dex (ignore rentals)
|
// Only update the fusion's dex data if the Pokemon is already caught in dex (ignore rentals)
|
||||||
const rootFusionSpecies = playerPokemon.fusionSpecies?.getRootSpeciesId();
|
const rootFusionSpecies = playerPokemon.fusionSpecies?.getRootSpeciesId();
|
||||||
if (!isNullOrUndefined(rootFusionSpecies)
|
if (!isNullOrUndefined(rootFusionSpecies)
|
||||||
&& speciesStarters.hasOwnProperty(rootFusionSpecies)
|
&& speciesStarterCosts.hasOwnProperty(rootFusionSpecies)
|
||||||
&& !!scene.gameData.dexData[rootFusionSpecies].caughtAttr) {
|
&& !!scene.gameData.dexData[rootFusionSpecies].caughtAttr) {
|
||||||
scene.gameData.starterData[rootFusionSpecies].abilityAttr |= playerPokemon.fusionAbilityIndex !== 1 || playerPokemon.fusionSpecies?.ability2
|
scene.gameData.starterData[rootFusionSpecies].abilityAttr |= playerPokemon.fusionAbilityIndex !== 1 || playerPokemon.fusionSpecies?.ability2
|
||||||
? 1 << playerPokemon.fusionAbilityIndex
|
? 1 << playerPokemon.fusionAbilityIndex
|
||||||
@ -356,11 +356,11 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.4.label`,
|
buttonLabel: `${namespace}:option.4.label`,
|
||||||
buttonTooltip: `${namespace}.option.4.tooltip`,
|
buttonTooltip: `${namespace}:option.4.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.4.selected`,
|
text: `${namespace}:option.4.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -19,7 +19,7 @@ import { PokemonMove } from "#app/field/pokemon";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:trashToTreasure";
|
const namespace = "mysteryEncounters/trashToTreasure";
|
||||||
|
|
||||||
const SOUND_EFFECT_WAIT_TIME = 700;
|
const SOUND_EFFECT_WAIT_TIME = 700;
|
||||||
|
|
||||||
@ -51,12 +51,12 @@ export const TrashToTreasureEncounter: MysteryEncounter =
|
|||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
@ -90,11 +90,11 @@ export const TrashToTreasureEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -123,18 +123,18 @@ export const TrashToTreasureEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
// Investigate garbage, battle Gmax Garbodor
|
// Investigate garbage, battle Gmax Garbodor
|
||||||
scene.setFieldScale(0.75);
|
scene.setFieldScale(0.75);
|
||||||
await showEncounterText(scene, `${namespace}.option.2.selected_2`);
|
await showEncounterText(scene, `${namespace}:option.2.selected_2`);
|
||||||
transitionMysteryEncounterIntroVisuals(scene);
|
transitionMysteryEncounterIntroVisuals(scene);
|
||||||
|
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
@ -25,7 +25,7 @@ import { Stat } from "#enums/stat";
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:uncommonBreed";
|
const namespace = "mysteryEncounters/uncommonBreed";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uncommon Breed encounter.
|
* Uncommon Breed encounter.
|
||||||
@ -42,7 +42,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
|
|||||||
.withIntroSpriteConfigs([]) // Set in onInit()
|
.withIntroSpriteConfigs([]) // Set in onInit()
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
@ -85,7 +85,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}.option.1.stat_boost`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.stat_boost`);
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
@ -125,16 +125,16 @@ export const UncommonBreedEncounter: MysteryEncounter =
|
|||||||
scene.time.delayedCall(500, () => scene.playSound("battle_anims/PRSFX- Spotlight2"));
|
scene.time.delayedCall(500, () => scene.playSound("battle_anims/PRSFX- Spotlight2"));
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -167,12 +167,12 @@ export const UncommonBreedEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||||
.withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 4)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically
|
.withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 4)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
disabledButtonTooltip: `${namespace}.option.2.disabled_tooltip`,
|
disabledButtonTooltip: `${namespace}:option.2.disabled_tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`
|
text: `${namespace}:option.2.selected`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@ -211,12 +211,12 @@ export const UncommonBreedEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||||
.withPrimaryPokemonRequirement(new MoveRequirement(CHARMING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically
|
.withPrimaryPokemonRequirement(new MoveRequirement(CHARMING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.3.label`,
|
buttonLabel: `${namespace}:option.3.label`,
|
||||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||||
disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`,
|
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.3.selected`
|
text: `${namespace}:option.3.selected`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@ -23,7 +23,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
import { Challenges } from "#enums/challenges";
|
import { Challenges } from "#enums/challenges";
|
||||||
|
|
||||||
/** i18n namespace for encounter */
|
/** i18n namespace for encounter */
|
||||||
const namespace = "mysteryEncounter:weirdDream";
|
const namespace = "mysteryEncounters/weirdDream";
|
||||||
|
|
||||||
/** Exclude Ultra Beasts, Paradox, Eternatus, and all legendary/mythical/trio pokemon that are below 570 BST */
|
/** Exclude Ultra Beasts, Paradox, Eternatus, and all legendary/mythical/trio pokemon that are below 570 BST */
|
||||||
const EXCLUDED_TRANSFORMATION_SPECIES = [
|
const EXCLUDED_TRANSFORMATION_SPECIES = [
|
||||||
@ -118,16 +118,16 @@ export const WeirdDreamEncounter: MysteryEncounter =
|
|||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
text: `${namespace}.intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}.description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}.query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
scene.loadBgm("mystery_encounter_weird_dream", "mystery_encounter_weird_dream.mp3");
|
scene.loadBgm("mystery_encounter_weird_dream", "mystery_encounter_weird_dream.mp3");
|
||||||
return true;
|
return true;
|
||||||
@ -141,11 +141,11 @@ export const WeirdDreamEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withHasDexProgress(true)
|
.withHasDexProgress(true)
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.1.selected`,
|
text: `${namespace}:option.1.selected`,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -165,7 +165,7 @@ export const WeirdDreamEncounter: MysteryEncounter =
|
|||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
// Starts cutscene dialogue, but does not await so that cutscene plays as player goes through dialogue
|
// Starts cutscene dialogue, but does not await so that cutscene plays as player goes through dialogue
|
||||||
const cutsceneDialoguePromise = showEncounterText(scene, `${namespace}.option.1.cutscene`);
|
const cutsceneDialoguePromise = showEncounterText(scene, `${namespace}:option.1.cutscene`);
|
||||||
|
|
||||||
// Change the entire player's party
|
// Change the entire player's party
|
||||||
// Wait for all new Pokemon assets to be loaded before showing transformation animations
|
// Wait for all new Pokemon assets to be loaded before showing transformation animations
|
||||||
@ -189,7 +189,7 @@ export const WeirdDreamEncounter: MysteryEncounter =
|
|||||||
await cutsceneDialoguePromise;
|
await cutsceneDialoguePromise;
|
||||||
|
|
||||||
doHideDreamBackground(scene);
|
doHideDreamBackground(scene);
|
||||||
await showEncounterText(scene, `${namespace}.option.1.dream_complete`);
|
await showEncounterText(scene, `${namespace}:option.1.dream_complete`);
|
||||||
|
|
||||||
await doNewTeamPostProcess(scene, transformations);
|
await doNewTeamPostProcess(scene, transformations);
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.MEMORY_MUSHROOM, modifierTypes.ROGUE_BALL, modifierTypes.MINT, modifierTypes.MINT ]});
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.MEMORY_MUSHROOM, modifierTypes.ROGUE_BALL, modifierTypes.MINT, modifierTypes.MINT ]});
|
||||||
@ -199,11 +199,11 @@ export const WeirdDreamEncounter: MysteryEncounter =
|
|||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
buttonLabel: `${namespace}.option.2.label`,
|
buttonLabel: `${namespace}:option.2.label`,
|
||||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||||
selected: [
|
selected: [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.2.selected`,
|
text: `${namespace}:option.2.selected`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -5,16 +5,16 @@ import { Abilities } from "#enums/abilities";
|
|||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { TimeOfDay } from "#enums/time-of-day";
|
import { TimeOfDay } from "#enums/time-of-day";
|
||||||
import { Nature } from "../nature";
|
import { Nature } from "#app/data/nature";
|
||||||
import { EvolutionItem, pokemonEvolutions } from "../pokemon-evolutions";
|
import { EvolutionItem, pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
import { FormChangeItem, pokemonFormChanges, SpeciesFormChangeItemTrigger } from "../pokemon-forms";
|
import { FormChangeItem, pokemonFormChanges, SpeciesFormChangeItemTrigger } from "#app/data/pokemon-forms";
|
||||||
import { SpeciesFormKey } from "../pokemon-species";
|
import { StatusEffect } from "#app/data/status-effect";
|
||||||
import { StatusEffect } from "../status-effect";
|
import { Type } from "#app/data/type";
|
||||||
import { Type } from "../type";
|
import { WeatherType } from "#app/data/weather";
|
||||||
import { WeatherType } from "../weather";
|
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { AttackTypeBoosterModifier } from "#app/modifier/modifier";
|
import { AttackTypeBoosterModifier } from "#app/modifier/modifier";
|
||||||
import { AttackTypeBoosterModifierType } from "#app/modifier/modifier-type";
|
import { AttackTypeBoosterModifierType } from "#app/modifier/modifier-type";
|
||||||
|
import { SpeciesFormKey } from "#enums/species-form-key";
|
||||||
|
|
||||||
export interface EncounterRequirement {
|
export interface EncounterRequirement {
|
||||||
meetsRequirement(scene: BattleScene): boolean; // Boolean to see if a requirement is met
|
meetsRequirement(scene: BattleScene): boolean; // Boolean to see if a requirement is met
|
||||||
@ -1033,4 +1033,3 @@ export class WeightRequirement extends EncounterPokemonRequirement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ import { FunAndGamesEncounter } from "#app/data/mystery-encounters/encounters/fu
|
|||||||
import { UncommonBreedEncounter } from "#app/data/mystery-encounters/encounters/uncommon-breed-encounter";
|
import { UncommonBreedEncounter } from "#app/data/mystery-encounters/encounters/uncommon-breed-encounter";
|
||||||
import { GlobalTradeSystemEncounter } from "#app/data/mystery-encounters/encounters/global-trade-system-encounter";
|
import { GlobalTradeSystemEncounter } from "#app/data/mystery-encounters/encounters/global-trade-system-encounter";
|
||||||
import { TheExpertPokemonBreederEncounter } from "#app/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter";
|
import { TheExpertPokemonBreederEncounter } from "#app/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter";
|
||||||
import { getBiomeName } from "#app/data/biomes";
|
import { getBiomeName } from "#app/data/balance/biomes";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spawn chance: (BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT + WIGHT_INCREMENT_ON_SPAWN_MISS * <number of missed spawns>) / MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT
|
* Spawn chance: (BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT + WIGHT_INCREMENT_ON_SPAWN_MISS * <number of missed spawns>) / MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT
|
||||||
@ -363,6 +363,7 @@ export function initMysteryEncounters() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Add ANY biome encounters to biome map
|
// Add ANY biome encounters to biome map
|
||||||
|
// eslint-disable-next-line
|
||||||
let encounterBiomeTableLog = "";
|
let encounterBiomeTableLog = "";
|
||||||
mysteryEncountersByBiome.forEach((biomeEncounters, biome) => {
|
mysteryEncountersByBiome.forEach((biomeEncounters, biome) => {
|
||||||
anyBiomeEncounters.forEach(encounter => {
|
anyBiomeEncounters.forEach(encounter => {
|
||||||
@ -374,5 +375,5 @@ export function initMysteryEncounters() {
|
|||||||
encounterBiomeTableLog += `${getBiomeName(biome).toUpperCase()}: [${biomeEncounters.map(type => MysteryEncounterType[type].toString().toLowerCase()).sort().join(", ")}]\n`;
|
encounterBiomeTableLog += `${getBiomeName(biome).toUpperCase()}: [${biomeEncounters.map(type => MysteryEncounterType[type].toString().toLowerCase()).sort().join(", ")}]\n`;
|
||||||
});
|
});
|
||||||
|
|
||||||
console.debug("All Mystery Encounters by Biome:\n" + encounterBiomeTableLog);
|
//console.debug("All Mystery Encounters by Biome:\n" + encounterBiomeTableLog);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Battle, { BattlerIndex, BattleType } from "#app/battle";
|
import Battle, { BattlerIndex, BattleType } from "#app/battle";
|
||||||
import { biomeLinks, BiomePoolTier } from "#app/data/biomes";
|
import { biomeLinks, BiomePoolTier } from "#app/data/balance/biomes";
|
||||||
import MysteryEncounterOption from "#app/data/mystery-encounters/mystery-encounter-option";
|
import MysteryEncounterOption from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||||
import { AVERAGE_ENCOUNTERS_PER_RUN_TARGET, WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters";
|
import { AVERAGE_ENCOUNTERS_PER_RUN_TARGET, WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters";
|
||||||
import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
|
@ -12,7 +12,8 @@ import { Mode } from "#app/ui/ui";
|
|||||||
import { PartyOption, PartyUiMode } from "#app/ui/party-ui-handler";
|
import { PartyOption, PartyUiMode } from "#app/ui/party-ui-handler";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { Type } from "#app/data/type";
|
import { Type } from "#app/data/type";
|
||||||
import PokemonSpecies, { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species";
|
import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
import { speciesStarterCosts } from "#app/data/balance/starters";
|
||||||
import { getEncounterText, queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
import { getEncounterText, queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||||
@ -206,8 +207,8 @@ export function getRandomSpeciesByStarterTier(starterTiers: number | [number, nu
|
|||||||
let min = Array.isArray(starterTiers) ? starterTiers[0] : starterTiers;
|
let min = Array.isArray(starterTiers) ? starterTiers[0] : starterTiers;
|
||||||
let max = Array.isArray(starterTiers) ? starterTiers[1] : starterTiers;
|
let max = Array.isArray(starterTiers) ? starterTiers[1] : starterTiers;
|
||||||
|
|
||||||
let filteredSpecies: [PokemonSpecies, number][] = Object.keys(speciesStarters)
|
let filteredSpecies: [PokemonSpecies, number][] = Object.keys(speciesStarterCosts)
|
||||||
.map(s => [parseInt(s) as Species, speciesStarters[s] as number])
|
.map(s => [ parseInt(s) as Species, speciesStarterCosts[s] as number ])
|
||||||
.filter(s => {
|
.filter(s => {
|
||||||
const pokemonSpecies = getPokemonSpecies(s[0]);
|
const pokemonSpecies = getPokemonSpecies(s[0]);
|
||||||
return pokemonSpecies && (!excludedSpecies || !excludedSpecies.includes(s[0]))
|
return pokemonSpecies && (!excludedSpecies || !excludedSpecies.includes(s[0]))
|
||||||
@ -224,7 +225,7 @@ export function getRandomSpeciesByStarterTier(starterTiers: number | [number, nu
|
|||||||
// If no filtered mons exist at specified starter tiers, will expand starter search range until there are
|
// If no filtered mons exist at specified starter tiers, will expand starter search range until there are
|
||||||
// Starts by decrementing starter tier min until it is 0, then increments tier max up to 10
|
// Starts by decrementing starter tier min until it is 0, then increments tier max up to 10
|
||||||
let tryFilterStarterTiers: [PokemonSpecies, number][] = filteredSpecies.filter(s => (s[1] >= min && s[1] <= max));
|
let tryFilterStarterTiers: [PokemonSpecies, number][] = filteredSpecies.filter(s => (s[1] >= min && s[1] <= max));
|
||||||
while (tryFilterStarterTiers.length === 0 && (min !== 0 && max !== 10)) {
|
while (tryFilterStarterTiers.length === 0 && !(min === 0 && max === 10)) {
|
||||||
if (min > 0) {
|
if (min > 0) {
|
||||||
min--;
|
min--;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { PokemonFormChangeItemModifier, TerastallizeModifier } from "../modifier/modifier";
|
import { PokemonFormChangeItemModifier, TerastallizeModifier } from "../modifier/modifier";
|
||||||
import Pokemon from "../field/pokemon";
|
import Pokemon from "../field/pokemon";
|
||||||
import { SpeciesFormKey } from "./pokemon-species";
|
|
||||||
import { StatusEffect } from "./status-effect";
|
import { StatusEffect } from "./status-effect";
|
||||||
import { MoveCategory, allMoves } from "./move";
|
import { MoveCategory, allMoves } from "./move";
|
||||||
import { Type } from "./type";
|
import { Type } from "./type";
|
||||||
import { Constructor } from "#app/utils";
|
import { Constructor, nil } from "#app/utils";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
@ -13,6 +12,7 @@ import { getPokemonNameWithAffix } from "#app/messages";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { WeatherType } from "./weather";
|
import { WeatherType } from "./weather";
|
||||||
import { Challenges } from "#app/enums/challenges";
|
import { Challenges } from "#app/enums/challenges";
|
||||||
|
import { SpeciesFormKey } from "#enums/species-form-key";
|
||||||
|
|
||||||
export enum FormChangeItem {
|
export enum FormChangeItem {
|
||||||
NONE,
|
NONE,
|
||||||
@ -185,7 +185,7 @@ export class SpeciesFormChange {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
findTrigger(triggerType: Constructor<SpeciesFormChangeTrigger>): SpeciesFormChangeTrigger | null {
|
findTrigger(triggerType: Constructor<SpeciesFormChangeTrigger>): SpeciesFormChangeTrigger | nil {
|
||||||
if (!this.trigger.hasTriggerType(triggerType)) {
|
if (!this.trigger.hasTriggerType(triggerType)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -193,7 +193,7 @@ export class SpeciesFormChange {
|
|||||||
const trigger = this.trigger;
|
const trigger = this.trigger;
|
||||||
|
|
||||||
if (trigger instanceof SpeciesFormChangeCompoundTrigger) {
|
if (trigger instanceof SpeciesFormChangeCompoundTrigger) {
|
||||||
return trigger.triggers.find(t => t.hasTriggerType(triggerType))!; // TODO: is this bang correct?
|
return trigger.triggers.find(t => t.hasTriggerType(triggerType));
|
||||||
}
|
}
|
||||||
|
|
||||||
return trigger;
|
return trigger;
|
||||||
@ -202,11 +202,11 @@ export class SpeciesFormChange {
|
|||||||
|
|
||||||
export class SpeciesFormChangeCondition {
|
export class SpeciesFormChangeCondition {
|
||||||
public predicate: SpeciesFormChangeConditionPredicate;
|
public predicate: SpeciesFormChangeConditionPredicate;
|
||||||
public enforceFunc: SpeciesFormChangeConditionEnforceFunc | null;
|
public enforceFunc: SpeciesFormChangeConditionEnforceFunc | nil;
|
||||||
|
|
||||||
constructor(predicate: SpeciesFormChangeConditionPredicate, enforceFunc?: SpeciesFormChangeConditionEnforceFunc) {
|
constructor(predicate: SpeciesFormChangeConditionPredicate, enforceFunc?: SpeciesFormChangeConditionEnforceFunc) {
|
||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
this.enforceFunc = enforceFunc!; // TODO: is this bang correct?
|
this.enforceFunc = enforceFunc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,22 +1,27 @@
|
|||||||
import BattleScene, { startingWave } from "../battle-scene";
|
import BattleScene, { startingWave } from "#app/battle-scene";
|
||||||
import { ModifierTypeFunc, modifierTypes } from "../modifier/modifier-type";
|
import { ModifierTypeFunc, modifierTypes } from "#app/modifier/modifier-type";
|
||||||
import { EnemyPokemon, PokemonMove } from "../field/pokemon";
|
import { EnemyPokemon, PokemonMove } from "#app/field/pokemon";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "#app/utils";
|
||||||
import { PokeballType } from "./pokeball";
|
import { PokeballType } from "#app/data/pokeball";
|
||||||
import { pokemonEvolutions, pokemonPrevolutions } from "./pokemon-evolutions";
|
import { pokemonEvolutions, pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
import PokemonSpecies, { getPokemonSpecies, PokemonSpeciesFilter } from "./pokemon-species";
|
import PokemonSpecies, { getPokemonSpecies, PokemonSpeciesFilter } from "#app/data/pokemon-species";
|
||||||
import { tmSpecies } from "./tms";
|
import { tmSpecies } from "#app/data/balance/tms";
|
||||||
import { Type } from "./type";
|
import { Type } from "#app/data/type";
|
||||||
import { doubleBattleDialogue } from "./dialogue";
|
import { doubleBattleDialogue } from "#app/data/dialogue";
|
||||||
import { PersistentModifier } from "../modifier/modifier";
|
import { PersistentModifier } from "#app/modifier/modifier";
|
||||||
import { TrainerVariant } from "../field/trainer";
|
import { TrainerVariant } from "#app/field/trainer";
|
||||||
import { getIsInitialized, initI18n } from "#app/plugins/i18n";
|
import { getIsInitialized, initI18n } from "#app/plugins/i18n";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import {Gender} from "./gender";
|
import { Gender } from "#app/data/gender";
|
||||||
|
|
||||||
|
/** Minimum BST for Pokemon generated onto the Elite Four's teams */
|
||||||
|
const ELITE_FOUR_MINIMUM_BST = 460;
|
||||||
|
/** Minimum BST for Pokemon generated onto the E4 Champion's team */
|
||||||
|
const CHAMPION_MINIMUM_BST = 508;
|
||||||
|
|
||||||
export enum TrainerPoolTier {
|
export enum TrainerPoolTier {
|
||||||
COMMON,
|
COMMON,
|
||||||
@ -860,10 +865,10 @@ export class TrainerConfig {
|
|||||||
|
|
||||||
// Set species filter and specialty types if provided, otherwise filter by base total.
|
// Set species filter and specialty types if provided, otherwise filter by base total.
|
||||||
if (specialtyTypes.length) {
|
if (specialtyTypes.length) {
|
||||||
this.setSpeciesFilter(p => specialtyTypes.some(t => p.isOfType(t)) && p.baseTotal >= 450);
|
this.setSpeciesFilter(p => specialtyTypes.some(t => p.isOfType(t)) && p.baseTotal >= ELITE_FOUR_MINIMUM_BST);
|
||||||
this.setSpecialtyTypes(...specialtyTypes);
|
this.setSpecialtyTypes(...specialtyTypes);
|
||||||
} else {
|
} else {
|
||||||
this.setSpeciesFilter(p => p.baseTotal >= 450);
|
this.setSpeciesFilter(p => p.baseTotal >= ELITE_FOUR_MINIMUM_BST);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Localize the trainer's name by converting it to lowercase and replacing spaces with underscores.
|
// Localize the trainer's name by converting it to lowercase and replacing spaces with underscores.
|
||||||
@ -913,8 +918,7 @@ export class TrainerConfig {
|
|||||||
this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool));
|
this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set species filter to only include species with a base total of 470 or higher.
|
this.setSpeciesFilter(p => p.baseTotal >= CHAMPION_MINIMUM_BST);
|
||||||
this.setSpeciesFilter(p => p.baseTotal >= 470);
|
|
||||||
|
|
||||||
// Localize the trainer's name by converting it to lowercase and replacing spaces with underscores.
|
// Localize the trainer's name by converting it to lowercase and replacing spaces with underscores.
|
||||||
const nameForCall = this.name.toLowerCase().replace(/\s/g, "_");
|
const nameForCall = this.name.toLowerCase().replace(/\s/g, "_");
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
export enum ArenaTagType {
|
export enum ArenaTagType {
|
||||||
NONE = "NONE",
|
NONE = "NONE",
|
||||||
MUD_SPORT = "MUD_SPORT",
|
MUD_SPORT = "MUD_SPORT",
|
||||||
@ -25,4 +24,5 @@ export enum ArenaTagType {
|
|||||||
SAFEGUARD = "SAFEGUARD",
|
SAFEGUARD = "SAFEGUARD",
|
||||||
NO_CRIT = "NO_CRIT",
|
NO_CRIT = "NO_CRIT",
|
||||||
IMPRISON = "IMPRISON",
|
IMPRISON = "IMPRISON",
|
||||||
|
PLASMA_FISTS = "PLASMA_FISTS",
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
export enum BattlerTagType {
|
export enum BattlerTagType {
|
||||||
NONE = "NONE",
|
NONE = "NONE",
|
||||||
RECHARGING = "RECHARGING",
|
RECHARGING = "RECHARGING",
|
||||||
@ -85,4 +84,5 @@ export enum BattlerTagType {
|
|||||||
TORMENT = "TORMENT",
|
TORMENT = "TORMENT",
|
||||||
TAUNT = "TAUNT",
|
TAUNT = "TAUNT",
|
||||||
IMPRISON = "IMPRISON",
|
IMPRISON = "IMPRISON",
|
||||||
|
SYRUP_BOMB = "SYRUP_BOMB",
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
export enum BerryType {
|
export enum BerryType {
|
||||||
SITRUS,
|
SITRUS,
|
||||||
LUM,
|
LUM,
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
export enum Biome {
|
export enum Biome {
|
||||||
TOWN,
|
TOWN,
|
||||||
PLAINS,
|
PLAINS,
|
||||||
|
13
src/enums/species-form-key.ts
Normal file
13
src/enums/species-form-key.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export enum SpeciesFormKey {
|
||||||
|
MEGA = "mega",
|
||||||
|
MEGA_X = "mega-x",
|
||||||
|
MEGA_Y = "mega-y",
|
||||||
|
PRIMAL = "primal",
|
||||||
|
ORIGIN = "origin",
|
||||||
|
INCARNATE = "incarnate",
|
||||||
|
THERIAN = "therian",
|
||||||
|
GIGANTAMAX = "gigantamax",
|
||||||
|
GIGANTAMAX_SINGLE = "gigantamax-single",
|
||||||
|
GIGANTAMAX_RAPID = "gigantamax-rapid",
|
||||||
|
ETERNAMAX = "eternamax",
|
||||||
|
}
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
export enum TimeOfDay {
|
export enum TimeOfDay {
|
||||||
ALL = -1,
|
ALL = -1,
|
||||||
DAWN,
|
DAWN,
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
import BattleScene from "../battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import { biomePokemonPools, BiomePoolTier, BiomeTierTrainerPools, biomeTrainerPools, PokemonPools } from "../data/biomes";
|
import { biomePokemonPools, BiomePoolTier, BiomeTierTrainerPools, biomeTrainerPools, PokemonPools } from "#app/data/balance/biomes";
|
||||||
import { Constructor } from "#app/utils";
|
import { Constructor } from "#app/utils";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "#app/utils";
|
||||||
import PokemonSpecies, { getPokemonSpecies } from "../data/pokemon-species";
|
import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
import { getTerrainClearMessage, getTerrainStartMessage, getWeatherClearMessage, getWeatherStartMessage, Weather, WeatherType } from "../data/weather";
|
import { getTerrainClearMessage, getTerrainStartMessage, getWeatherClearMessage, getWeatherStartMessage, Weather, WeatherType } from "#app/data/weather";
|
||||||
import { CommonAnim } from "../data/battle-anims";
|
import { CommonAnim } from "#app/data/battle-anims";
|
||||||
import { Type } from "../data/type";
|
import { Type } from "#app/data/type";
|
||||||
import Move from "../data/move";
|
import Move from "#app/data/move";
|
||||||
import { ArenaTag, ArenaTagSide, ArenaTrapTag, getArenaTag } from "../data/arena-tag";
|
import { ArenaTag, ArenaTagSide, ArenaTrapTag, getArenaTag } from "#app/data/arena-tag";
|
||||||
import { BattlerIndex } from "../battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { Terrain, TerrainType } from "../data/terrain";
|
import { Terrain, TerrainType } from "#app/data/terrain";
|
||||||
import { applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs, PostTerrainChangeAbAttr, PostWeatherChangeAbAttr } from "../data/ability";
|
import { applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs, PostTerrainChangeAbAttr, PostWeatherChangeAbAttr } from "#app/data/ability";
|
||||||
import Pokemon from "./pokemon";
|
import Pokemon from "#app/field/pokemon";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
import { TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEvent } from "../events/arena";
|
import { TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena";
|
||||||
import { ArenaTagType } from "#enums/arena-tag-type";
|
import { ArenaTagType } from "#enums/arena-tag-type";
|
||||||
import { Biome } from "#enums/biome";
|
import { Biome } from "#enums/biome";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { TimeOfDay } from "#enums/time-of-day";
|
import { TimeOfDay } from "#enums/time-of-day";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import { Abilities } from "#app/enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "#app/data/pokemon-forms";
|
import { SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "#app/data/pokemon-forms";
|
||||||
import { CommonAnimPhase } from "#app/phases/common-anim-phase";
|
import { CommonAnimPhase } from "#app/phases/common-anim-phase";
|
||||||
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
||||||
|
@ -1,43 +1,45 @@
|
|||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import BattleScene, { AnySound } from "../battle-scene";
|
import BattleScene, { AnySound } from "#app/battle-scene";
|
||||||
import { Variant, VariantSet, variantColorCache } from "#app/data/variant";
|
import { Variant, VariantSet, variantColorCache } from "#app/data/variant";
|
||||||
import { variantData } from "#app/data/variant";
|
import { variantData } from "#app/data/variant";
|
||||||
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "../ui/battle-info";
|
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "#app/ui/battle-info";
|
||||||
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget } from "../data/move";
|
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget } from "#app/data/move";
|
||||||
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species";
|
import { default as PokemonSpecies, PokemonSpeciesForm, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
|
||||||
|
import { getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters";
|
||||||
|
import { starterPassiveAbilities } from "#app/data/balance/passives";
|
||||||
import { Constructor, isNullOrUndefined, randSeedInt } from "#app/utils";
|
import { Constructor, isNullOrUndefined, randSeedInt } from "#app/utils";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "#app/utils";
|
||||||
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from "../data/type";
|
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from "#app/data/type";
|
||||||
import { getLevelTotalExp } from "../data/exp";
|
import { getLevelTotalExp } from "#app/data/exp";
|
||||||
import { Stat, type PermanentStat, type BattleStat, type EffectiveStat, PERMANENT_STATS, BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat";
|
import { Stat, type PermanentStat, type BattleStat, type EffectiveStat, PERMANENT_STATS, BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat";
|
||||||
import { DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, BaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempStatStageBoosterModifier, TempCritBoosterModifier, StatBoosterModifier, CritBoosterModifier, TerastallizeModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonIncrementingStatModifier, EvoTrackerModifier } from "../modifier/modifier";
|
import { DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, BaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempStatStageBoosterModifier, TempCritBoosterModifier, StatBoosterModifier, CritBoosterModifier, TerastallizeModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonIncrementingStatModifier, EvoTrackerModifier } from "#app/modifier/modifier";
|
||||||
import { PokeballType } from "../data/pokeball";
|
import { PokeballType } from "#app/data/pokeball";
|
||||||
import { Gender } from "../data/gender";
|
import { Gender } from "#app/data/gender";
|
||||||
import { initMoveAnim, loadMoveAnimAssets } from "../data/battle-anims";
|
import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims";
|
||||||
import { Status, StatusEffect, getRandomStatus } from "../data/status-effect";
|
import { Status, StatusEffect, getRandomStatus } from "#app/data/status-effect";
|
||||||
import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from "../data/pokemon-evolutions";
|
import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from "#app/data/balance/pokemon-evolutions";
|
||||||
import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from "../data/tms";
|
import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from "#app/data/balance/tms";
|
||||||
import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoostTag, SubstituteTag, TypeImmuneTag, getBattlerTag, SemiInvulnerableTag, TypeBoostTag, MoveRestrictionBattlerTag, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag, TarShotTag, AutotomizedTag } from "../data/battler-tags";
|
import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoostTag, SubstituteTag, TypeImmuneTag, getBattlerTag, SemiInvulnerableTag, TypeBoostTag, MoveRestrictionBattlerTag, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag, TarShotTag, AutotomizedTag } from "../data/battler-tags";
|
||||||
import { WeatherType } from "../data/weather";
|
import { WeatherType } from "#app/data/weather";
|
||||||
import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "../data/arena-tag";
|
import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "#app/data/arena-tag";
|
||||||
import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs } from "../data/ability";
|
import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs } from "#app/data/ability";
|
||||||
import PokemonData from "../system/pokemon-data";
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
import { BattlerIndex } from "../battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { Mode } from "../ui/ui";
|
import { Mode } from "#app/ui/ui";
|
||||||
import PartyUiHandler, { PartyOption, PartyUiMode } from "../ui/party-ui-handler";
|
import PartyUiHandler, { PartyOption, PartyUiMode } from "#app/ui/party-ui-handler";
|
||||||
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
||||||
import { LevelMoves } from "../data/pokemon-level-moves";
|
import { LevelMoves } from "#app/data/balance/pokemon-level-moves";
|
||||||
import { DamageAchv, achvs } from "../system/achv";
|
import { DamageAchv, achvs } from "#app/system/achv";
|
||||||
import { DexAttr, StarterDataEntry, StarterMoveset } from "../system/game-data";
|
import { DexAttr, StarterDataEntry, StarterMoveset } from "#app/system/game-data";
|
||||||
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities";
|
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities";
|
||||||
import { Nature, getNatureStatMultiplier } from "../data/nature";
|
import { Nature, getNatureStatMultiplier } from "#app/data/nature";
|
||||||
import { SpeciesFormChange, SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from "../data/pokemon-forms";
|
import { SpeciesFormChange, SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from "#app/data/pokemon-forms";
|
||||||
import { TerrainType } from "../data/terrain";
|
import { TerrainType } from "#app/data/terrain";
|
||||||
import { TrainerSlot } from "../data/trainer-config";
|
import { TrainerSlot } from "#app/data/trainer-config";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { speciesEggMoves } from "../data/egg-moves";
|
import { speciesEggMoves } from "#app/data/balance/egg-moves";
|
||||||
import { ModifierTier } from "../modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { ArenaTagType } from "#enums/arena-tag-type";
|
import { ArenaTagType } from "#enums/arena-tag-type";
|
||||||
@ -58,10 +60,12 @@ import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
|||||||
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase";
|
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase";
|
||||||
import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase";
|
import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase";
|
||||||
import { Challenges } from "#enums/challenges";
|
import { Challenges } from "#enums/challenges";
|
||||||
import { PokemonAnimType } from "#app/enums/pokemon-anim-type";
|
import { PokemonAnimType } from "#enums/pokemon-anim-type";
|
||||||
import { PLAYER_PARTY_MAX_SIZE } from "#app/constants";
|
import { PLAYER_PARTY_MAX_SIZE } from "#app/constants";
|
||||||
import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data";
|
import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data";
|
||||||
import { SwitchType } from "#enums/switch-type";
|
import { SwitchType } from "#enums/switch-type";
|
||||||
|
import { SpeciesFormKey } from "#enums/species-form-key";
|
||||||
|
import { BASE_HIDDEN_ABILITY_CHANCE, BASE_SHINY_CHANCE, SHINY_EPIC_CHANCE, SHINY_VARIANT_CHANCE } from "#app/data/balance/rates";
|
||||||
|
|
||||||
export enum FieldPosition {
|
export enum FieldPosition {
|
||||||
CENTER,
|
CENTER,
|
||||||
@ -139,7 +143,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
throw `Cannot create a player Pokemon for species '${species.getName(formIndex)}'`;
|
throw `Cannot create a player Pokemon for species '${species.getName(formIndex)}'`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hiddenAbilityChance = new Utils.IntegerHolder(256);
|
const hiddenAbilityChance = new Utils.IntegerHolder(BASE_HIDDEN_ABILITY_CHANCE);
|
||||||
if (!this.hasTrainer()) {
|
if (!this.hasTrainer()) {
|
||||||
this.scene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
|
this.scene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
|
||||||
}
|
}
|
||||||
@ -1083,6 +1087,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return !!this.fusionSpecies;
|
return !!this.fusionSpecies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the {@linkcode Pokemon} has a fusion with the specified {@linkcode Species}.
|
||||||
|
* @param species the pokemon {@linkcode Species} to check
|
||||||
|
* @returns `true` if the {@linkcode Pokemon} has a fusion with the specified {@linkcode Species}, `false` otherwise
|
||||||
|
*/
|
||||||
|
hasFusionSpecies(species: Species): boolean {
|
||||||
|
return this.fusionSpecies?.speciesId === species;
|
||||||
|
}
|
||||||
|
|
||||||
abstract isBoss(): boolean;
|
abstract isBoss(): boolean;
|
||||||
|
|
||||||
getMoveset(ignoreOverride?: boolean): (PokemonMove | null)[] {
|
getMoveset(ignoreOverride?: boolean): (PokemonMove | null)[] {
|
||||||
@ -1512,11 +1525,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
applyMoveAttrs(VariableMoveTypeAttr, this, null, move, moveTypeHolder);
|
applyMoveAttrs(VariableMoveTypeAttr, this, null, move, moveTypeHolder);
|
||||||
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, this, null, move, simulated, moveTypeHolder);
|
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, this, null, move, simulated, moveTypeHolder);
|
||||||
|
|
||||||
|
this.scene.arena.applyTags(ArenaTagType.PLASMA_FISTS, moveTypeHolder);
|
||||||
|
|
||||||
return moveTypeHolder.value as Type;
|
return moveTypeHolder.value as Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the effectiveness of a move against the Pokémon.
|
* Calculates the effectiveness of a move against the Pokémon.
|
||||||
* This includes modifiers from move and ability attributes.
|
* This includes modifiers from move and ability attributes.
|
||||||
@ -1529,6 +1543,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* @returns The type damage multiplier, indicating the effectiveness of the move
|
* @returns The type damage multiplier, indicating the effectiveness of the move
|
||||||
*/
|
*/
|
||||||
getMoveEffectiveness(source: Pokemon, move: Move, ignoreAbility: boolean = false, simulated: boolean = true, cancelled?: Utils.BooleanHolder): TypeDamageMultiplier {
|
getMoveEffectiveness(source: Pokemon, move: Move, ignoreAbility: boolean = false, simulated: boolean = true, cancelled?: Utils.BooleanHolder): TypeDamageMultiplier {
|
||||||
|
if (!Utils.isNullOrUndefined(this.turnData?.moveEffectiveness)) {
|
||||||
|
return this.turnData?.moveEffectiveness;
|
||||||
|
}
|
||||||
|
|
||||||
if (move.hasAttr(TypelessAttr)) {
|
if (move.hasAttr(TypelessAttr)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1822,7 +1840,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* The exact mechanic is that it calculates E as the XOR of the player's trainer ID and secret ID.
|
* 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.
|
* 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 {@linkcode shinyThreshold} (or {@linkcode thresholdOverride} if set) to see whether or not to generate a shiny.
|
* The XOR of E and F are then compared to the {@linkcode shinyThreshold} (or {@linkcode thresholdOverride} if set) to see whether or not to generate a shiny.
|
||||||
* The base shiny odds are {@linkcode baseShinyChance} / 65536
|
* The base shiny odds are {@linkcode BASE_SHINY_CHANCE} / 65536
|
||||||
* @param thresholdOverride number that is divided by 2^16 (65536) to get the shiny chance, overrides {@linkcode shinyThreshold} if set (bypassing shiny rate modifiers such as Shiny Charm)
|
* @param thresholdOverride number that is divided by 2^16 (65536) to get the shiny chance, overrides {@linkcode shinyThreshold} if set (bypassing shiny rate modifiers such as Shiny Charm)
|
||||||
* @returns true if the Pokemon has been set as a shiny, false otherwise
|
* @returns true if the Pokemon has been set as a shiny, false otherwise
|
||||||
*/
|
*/
|
||||||
@ -1838,9 +1856,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
const E = this.scene.gameData.trainerId ^ this.scene.gameData.secretId;
|
const E = this.scene.gameData.trainerId ^ this.scene.gameData.secretId;
|
||||||
const F = rand1 ^ rand2;
|
const F = rand1 ^ rand2;
|
||||||
|
|
||||||
/** `64/65536 -> 1/1024` */
|
const shinyThreshold = new Utils.IntegerHolder(BASE_SHINY_CHANCE);
|
||||||
const baseShinyChance = 64;
|
|
||||||
const shinyThreshold = new Utils.IntegerHolder(baseShinyChance);
|
|
||||||
if (thresholdOverride === undefined) {
|
if (thresholdOverride === undefined) {
|
||||||
if (this.scene.eventManager.isEventActive()) {
|
if (this.scene.eventManager.isEventActive()) {
|
||||||
shinyThreshold.value *= this.scene.eventManager.getShinyMultiplier();
|
shinyThreshold.value *= this.scene.eventManager.getShinyMultiplier();
|
||||||
@ -1865,15 +1881,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* Function that tries to set a Pokemon shiny based on seed.
|
* Function that tries to set a Pokemon shiny based on seed.
|
||||||
* For manual use only, usually to roll a Pokemon's shiny chance a second time.
|
* For manual use only, usually to roll a Pokemon's shiny chance a second time.
|
||||||
*
|
*
|
||||||
* The base shiny odds are {@linkcode baseShinyChance} / 65536
|
* The base shiny odds are {@linkcode BASE_SHINY_CHANCE} / 65536
|
||||||
* @param thresholdOverride number that is divided by 2^16 (65536) to get the shiny chance, overrides {@linkcode shinyThreshold} if set (bypassing shiny rate modifiers such as Shiny Charm)
|
* @param thresholdOverride number that is divided by 2^16 (65536) to get the shiny chance, overrides {@linkcode shinyThreshold} if set (bypassing shiny rate modifiers such as Shiny Charm)
|
||||||
* @param applyModifiersToOverride If {@linkcode thresholdOverride} is set and this is true, will apply Shiny Charm and event modifiers to {@linkcode thresholdOverride}
|
* @param applyModifiersToOverride If {@linkcode thresholdOverride} is set and this is true, will apply Shiny Charm and event modifiers to {@linkcode thresholdOverride}
|
||||||
* @returns true if the Pokemon has been set as a shiny, false otherwise
|
* @returns true if the Pokemon has been set as a shiny, false otherwise
|
||||||
*/
|
*/
|
||||||
trySetShinySeed(thresholdOverride?: integer, applyModifiersToOverride?: boolean): boolean {
|
trySetShinySeed(thresholdOverride?: integer, applyModifiersToOverride?: boolean): boolean {
|
||||||
/** `64/65536 -> 1/1024` */
|
const shinyThreshold = new Utils.IntegerHolder(BASE_SHINY_CHANCE);
|
||||||
const baseShinyChance = 64;
|
|
||||||
const shinyThreshold = new Utils.IntegerHolder(baseShinyChance);
|
|
||||||
if (thresholdOverride === undefined || applyModifiersToOverride) {
|
if (thresholdOverride === undefined || applyModifiersToOverride) {
|
||||||
if (thresholdOverride !== undefined && applyModifiersToOverride) {
|
if (thresholdOverride !== undefined && applyModifiersToOverride) {
|
||||||
shinyThreshold.value = thresholdOverride;
|
shinyThreshold.value = thresholdOverride;
|
||||||
@ -1921,9 +1935,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
this.scene.executeWithSeedOffset(() => {
|
this.scene.executeWithSeedOffset(() => {
|
||||||
rand.value = Utils.randSeedInt(10);
|
rand.value = Utils.randSeedInt(10);
|
||||||
}, this.id, this.scene.waveSeed);
|
}, this.id, this.scene.waveSeed);
|
||||||
if (rand.value >= 4) {
|
if (rand.value >= SHINY_VARIANT_CHANCE) {
|
||||||
return 0; // 6/10
|
return 0; // 6/10
|
||||||
} else if (rand.value >= 1) {
|
} else if (rand.value >= SHINY_EPIC_CHANCE) {
|
||||||
return 1; // 3/10
|
return 1; // 3/10
|
||||||
} else {
|
} else {
|
||||||
return 2; // 1/10
|
return 2; // 1/10
|
||||||
@ -1931,7 +1945,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
generateFusionSpecies(forStarter?: boolean): void {
|
generateFusionSpecies(forStarter?: boolean): void {
|
||||||
const hiddenAbilityChance = new Utils.IntegerHolder(256);
|
const hiddenAbilityChance = new Utils.IntegerHolder(BASE_HIDDEN_ABILITY_CHANCE);
|
||||||
if (!this.hasTrainer()) {
|
if (!this.hasTrainer()) {
|
||||||
this.scene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
|
this.scene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
|
||||||
}
|
}
|
||||||
@ -3979,7 +3993,8 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
let compatible = false;
|
let compatible = false;
|
||||||
for (const p of tmSpecies[tm]) {
|
for (const p of tmSpecies[tm]) {
|
||||||
if (Array.isArray(p)) {
|
if (Array.isArray(p)) {
|
||||||
if (p[0] === this.species.speciesId || (this.fusionSpecies && p[0] === this.fusionSpecies.speciesId) && p.slice(1).indexOf(this.species.forms[this.formIndex]) > -1) {
|
const [ pkm, form ] = p;
|
||||||
|
if ((pkm === this.species.speciesId || this.fusionSpecies && pkm === this.fusionSpecies.speciesId) && form === this.getFormKey()) {
|
||||||
compatible = true;
|
compatible = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4047,7 +4062,7 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
starterData.forEach((sd: StarterDataEntry, i: integer) => {
|
starterData.forEach((sd: StarterDataEntry, i: integer) => {
|
||||||
const speciesId = !i ? starterSpeciesId : fusionStarterSpeciesId as Species;
|
const speciesId = !i ? starterSpeciesId : fusionStarterSpeciesId as Species;
|
||||||
sd.friendship = (sd.friendship || 0) + starterAmount.value;
|
sd.friendship = (sd.friendship || 0) + starterAmount.value;
|
||||||
if (sd.friendship >= getStarterValueFriendshipCap(speciesStarters[speciesId])) {
|
if (sd.friendship >= getStarterValueFriendshipCap(speciesStarterCosts[speciesId])) {
|
||||||
this.scene.gameData.addStarterCandy(getPokemonSpecies(speciesId), 1);
|
this.scene.gameData.addStarterCandy(getPokemonSpecies(speciesId), 1);
|
||||||
sd.friendship = 0;
|
sd.friendship = 0;
|
||||||
}
|
}
|
||||||
@ -4995,6 +5010,8 @@ export class PokemonBattleData {
|
|||||||
export class PokemonBattleSummonData {
|
export class PokemonBattleSummonData {
|
||||||
/** The number of turns the pokemon has passed since entering the battle */
|
/** The number of turns the pokemon has passed since entering the battle */
|
||||||
public turnCount: number = 1;
|
public turnCount: number = 1;
|
||||||
|
/** The number of turns the pokemon has passed since the start of the wave */
|
||||||
|
public waveTurnCount: number = 1;
|
||||||
/** The list of moves the pokemon has used since entering the battle */
|
/** The list of moves the pokemon has used since entering the battle */
|
||||||
public moveHistory: TurnMove[] = [];
|
public moveHistory: TurnMove[] = [];
|
||||||
}
|
}
|
||||||
@ -5011,6 +5028,7 @@ export class PokemonTurnData {
|
|||||||
public order: number;
|
public order: number;
|
||||||
public statStagesIncreased: boolean = false;
|
public statStagesIncreased: boolean = false;
|
||||||
public statStagesDecreased: boolean = false;
|
public statStagesDecreased: boolean = false;
|
||||||
|
public moveEffectiveness: TypeDamageMultiplier | null = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum AiType {
|
export enum AiType {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import BattleScene from "../battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import {pokemonPrevolutions} from "../data/pokemon-evolutions";
|
import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
import PokemonSpecies, {getPokemonSpecies} from "../data/pokemon-species";
|
import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
import {
|
import {
|
||||||
TrainerConfig,
|
TrainerConfig,
|
||||||
TrainerPartyCompoundTemplate,
|
TrainerPartyCompoundTemplate,
|
||||||
@ -10,11 +10,11 @@ import {
|
|||||||
trainerConfigs,
|
trainerConfigs,
|
||||||
trainerPartyTemplates,
|
trainerPartyTemplates,
|
||||||
signatureSpecies
|
signatureSpecies
|
||||||
} from "../data/trainer-config";
|
} from "#app/data/trainer-config";
|
||||||
import {EnemyPokemon} from "./pokemon";
|
import { EnemyPokemon } from "#app/field/pokemon";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "#app/utils";
|
||||||
import {PersistentModifier} from "../modifier/modifier";
|
import { PersistentModifier } from "#app/modifier/modifier";
|
||||||
import {trainerNamePools} from "../data/trainer-names";
|
import { trainerNamePools } from "#app/data/trainer-names";
|
||||||
import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag";
|
import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag";
|
||||||
import { getIsInitialized, initI18n } from "#app/plugins/i18n";
|
import { getIsInitialized, initI18n } from "#app/plugins/i18n";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
@ -1,24 +1,23 @@
|
|||||||
import { GachaType } from "./enums/gacha-types";
|
import { GachaType } from "#enums/gacha-types";
|
||||||
import { getBiomeHasProps } from "./field/arena";
|
import { getBiomeHasProps } from "#app/field/arena";
|
||||||
import CacheBustedLoaderPlugin from "./plugins/cache-busted-loader-plugin";
|
import CacheBustedLoaderPlugin from "#app/plugins/cache-busted-loader-plugin";
|
||||||
import { SceneBase } from "./scene-base";
|
import { SceneBase } from "#app/scene-base";
|
||||||
import { WindowVariant, getWindowVariantSuffix } from "./ui/ui-theme";
|
import { WindowVariant, getWindowVariantSuffix } from "#app/ui/ui-theme";
|
||||||
import { isMobile } from "./touch-controls";
|
import { isMobile } from "#app/touch-controls";
|
||||||
import * as Utils from "./utils";
|
import * as Utils from "#app/utils";
|
||||||
import { initI18n } from "./plugins/i18n";
|
import { initPokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
import { initPokemonPrevolutions } from "#app/data/pokemon-evolutions";
|
import { initBiomes } from "#app/data/balance/biomes";
|
||||||
import { initBiomes } from "#app/data/biomes";
|
import { initEggMoves } from "#app/data/balance/egg-moves";
|
||||||
import { initEggMoves } from "#app/data/egg-moves";
|
|
||||||
import { initPokemonForms } from "#app/data/pokemon-forms";
|
import { initPokemonForms } from "#app/data/pokemon-forms";
|
||||||
import { initSpecies } from "#app/data/pokemon-species";
|
import { initSpecies } from "#app/data/pokemon-species";
|
||||||
import { initMoves } from "#app/data/move";
|
import { initMoves } from "#app/data/move";
|
||||||
import { initAbilities } from "#app/data/ability";
|
import { initAbilities } from "#app/data/ability";
|
||||||
import { initAchievements } from "#app/system/achv";
|
import { initAchievements } from "#app/system/achv";
|
||||||
import { initTrainerTypeDialogue } from "#app/data/dialogue";
|
import { initTrainerTypeDialogue } from "#app/data/dialogue";
|
||||||
import { initChallenges } from "./data/challenge";
|
import { initChallenges } from "#app/data/challenge";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { initStatsKeys } from "./ui/game-stats-ui-handler";
|
import { initStatsKeys } from "#app/ui/game-stats-ui-handler";
|
||||||
import { initVouchers } from "./system/voucher";
|
import { initVouchers } from "#app/system/voucher";
|
||||||
import { Biome } from "#enums/biome";
|
import { Biome } from "#enums/biome";
|
||||||
import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters";
|
import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters";
|
||||||
|
|
||||||
@ -31,7 +30,6 @@ export class LoadingScene extends SceneBase {
|
|||||||
super(LoadingScene.KEY);
|
super(LoadingScene.KEY);
|
||||||
|
|
||||||
Phaser.Plugins.PluginCache.register("Loader", CacheBustedLoaderPlugin, "load");
|
Phaser.Plugins.PluginCache.register("Loader", CacheBustedLoaderPlugin, "load");
|
||||||
initI18n();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
preload() {
|
preload() {
|
||||||
@ -46,6 +44,8 @@ export class LoadingScene extends SceneBase {
|
|||||||
this.loadAtlas("prompt", "ui");
|
this.loadAtlas("prompt", "ui");
|
||||||
this.loadImage("candy", "ui");
|
this.loadImage("candy", "ui");
|
||||||
this.loadImage("candy_overlay", "ui");
|
this.loadImage("candy_overlay", "ui");
|
||||||
|
this.loadImage("friendship", "ui");
|
||||||
|
this.loadImage("friendship_overlay", "ui");
|
||||||
this.loadImage("cursor", "ui");
|
this.loadImage("cursor", "ui");
|
||||||
this.loadImage("cursor_reverse", "ui");
|
this.loadImage("cursor_reverse", "ui");
|
||||||
for (const wv of Utils.getEnumValues(WindowVariant)) {
|
for (const wv of Utils.getEnumValues(WindowVariant)) {
|
||||||
|
@ -1 +0,0 @@
|
|||||||
{}
|
|
@ -1 +0,0 @@
|
|||||||
{}
|
|
@ -1 +0,0 @@
|
|||||||
{}
|
|
@ -1,40 +0,0 @@
|
|||||||
{
|
|
||||||
"activeBattleEffects": "Efectes d'Arena Activa",
|
|
||||||
"player": "Jugador",
|
|
||||||
"neutral": "Neutre",
|
|
||||||
"enemy": "Enemic",
|
|
||||||
"sunny": "Assolellat",
|
|
||||||
"rain": "Plujós",
|
|
||||||
"sandstorm": "Tempesta Sorra",
|
|
||||||
"hail": "Calamarsa",
|
|
||||||
"snow": "Neu",
|
|
||||||
"fog": "Boira",
|
|
||||||
"heavyRain": "Diluvi",
|
|
||||||
"harshSun": "Sol Abrasador",
|
|
||||||
"strongWinds": "Vents Forts",
|
|
||||||
"misty": "Camp de Boira",
|
|
||||||
"electric": "Camp Elèctric",
|
|
||||||
"grassy": "Camp d'Herba",
|
|
||||||
"psychic": "Camp Psíquic",
|
|
||||||
"mudSport": "Xipollejo Fang",
|
|
||||||
"waterSport": "Hidrorraig",
|
|
||||||
"spikes": "Pues",
|
|
||||||
"toxicSpikes": "Pues Tòxiques",
|
|
||||||
"mist": "Boirina",
|
|
||||||
"futureSight": "Premonició",
|
|
||||||
"doomDesire": "Desig Ocult",
|
|
||||||
"wish": "Desig",
|
|
||||||
"stealthRock": "Trampa Roques",
|
|
||||||
"stickyWeb": "Xarxa Viscosa",
|
|
||||||
"trickRoom": "Espai Rar",
|
|
||||||
"gravity": "Gravetat",
|
|
||||||
"reflect": "Reflex",
|
|
||||||
"lightScreen": "Pantalla de Llum",
|
|
||||||
"auroraVeil": "Vel Aurora",
|
|
||||||
"quickGuard": "Anticipi",
|
|
||||||
"wideGuard": "Vasta Guàrdia",
|
|
||||||
"matBlock": "Escut Tatami",
|
|
||||||
"craftyShield": "Truc Defensa",
|
|
||||||
"tailwind": "Vent Afí",
|
|
||||||
"happyHour": "Paga Extra"
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
{}
|
|
@ -1 +0,0 @@
|
|||||||
{}
|
|
@ -1 +0,0 @@
|
|||||||
{}
|
|
@ -1 +0,0 @@
|
|||||||
{}
|
|
@ -1 +0,0 @@
|
|||||||
{}
|
|
@ -1 +0,0 @@
|
|||||||
{}
|
|
@ -1 +0,0 @@
|
|||||||
{}
|
|
@ -1 +0,0 @@
|
|||||||
{}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user