Compare commits

...

35 Commits

Author SHA1 Message Date
Madmadness65
ef71667bf5 Run linter on changes, add items to zh_TW localization 2024-05-23 11:58:15 -05:00
Madmadness65
a4430a2cc5 Merge branch 'main' into plates_memories 2024-05-23 11:25:08 -05:00
Greenlamp2
bac6c22973
ESLint - The Essential Linter and Formatter for JavaScript and TypeScript (#1224)
* eslint config + packages

* updated eslint config

* fix the issue eslint adding ;;;; at interfaces

* first round with eslint --fix .

* removed config for unused export

* Revert "first round with eslint --fix ."

This reverts commit 77a88e0895.

* removed config for camelCase

* for real this time, first round of eslint --fix .

* halfway to manual eslint fix

* eslint done

* added "how to setup" the hook to eslint --fix each new file before commit (if wanted)

* removed eslintrc config file duplicat

* fix human error + ignore build folder + merge overrides

* added curly brace style + eslint

* applied double quote linter rule

* added lefthook

* test precommit

* test precommit

* test precommit

* test precommit

* test precommit

* test precommit

* test precommit

* github action to run eslint

* added node_modules to ignore eslint

* different action for typescript

* no need for different glob (default src)

* node 20

* node 20

* removed no longer needed install file

* remove hooks part from README

* eslint fixes

---------

Co-authored-by: Frederico Santos <frederico.f.santos@tecnico.ulisboa.pt>
2024-05-23 11:03:10 -04:00
iv
2240e09406
zh_tw localization (#1279)
* zh_tw translation

* update translation to newer version

* follow file naming convention
2024-05-23 07:01:22 -05:00
Vance Ehrlich
45415a87bb
Disable tera-blast to prevent its use while there is not an animation (#1270)
* Disable tera-blast to prevent its use while there is not an animation

* Update TERA_BLAST to be unimplemented rather than partial
2024-05-22 23:37:23 -05:00
damocleas
8cd166536a
Egg-move changes for 8 pokemon (#1262)
Ekans
Nidoran F
Zubat
Spinarak
Pyukumuku
Cosmog
Nacli
Flittle
2024-05-22 19:08:26 -05:00
Tempoanon
8b4aa872d9
Update wrong Italian ability localizations and berry pouch (#1259) 2024-05-22 18:38:00 -05:00
Dmitriy K
a601d4d39e
hotfix creating berry with undefined type (#1260) 2024-05-22 18:34:49 -05:00
Blitzy
6c824d8894
Give Certain Starters a Reliable Level 1 Damaging Move (#1250)
* Give certain Pokemon who start without a damage dealing move a Level 1 option.

A simple QOL change to certain Pokemon who otherwise didn't start with any sort of damage dealing move, or started out with unreliable moves that made the first biome a chore to get through such as Wrap/Bind or Astonish/Flail. The move choices were simply to help early game for these Pokemon and majority of these moves were moves the Pokemon had access to at some point save for some special cases. The following Pokemon were affected: Abra, Gastly, Lickitung, Dunsparce, Slugma, Wailmer, Spoink, Shuppet, Duskull, Burmy, Chingling, Bonsly, Carnivine, Giratina, Darkrai, Throh, Vanillite, Pumpkaboo, Bounsweet, Pyukumuku, Cosmog, Magearna, Applin, Sinistea, Poltchageist.

* Give certain Pokemon a level 1 damage dealing move

* Added Formatting to indicate what is custom, changed Spoink to pull from Confusion 2 levels earlier
2024-05-22 16:36:57 -05:00
Jannik Tappert
e66d7026d5
Added German Localization to Voucher.ts (#1249) 2024-05-22 14:40:53 -05:00
nedpfeiffer
b72b432ce3
Spanish translations (#1084)
* spanish translations

* shortened translation
2024-05-22 13:01:29 -05:00
Matthew Olker
99557b318f Merge branch 'main' of https://github.com/pagefaultgames/pokerogue 2024-05-22 11:06:49 -04:00
Matthew Olker
aed9b56a7b Add helper functions to game mode 2024-05-22 11:06:24 -04:00
Ethan
ecc17c5342
Fixes Issue #805, the TODO was for a bug and was fixed in Platinum (#1238) 2024-05-22 09:59:29 -05:00
Dmitriy K
cd7e818a01
Mostly implement the Harvest ability (#1081)
* add harvest ability, move berry phase before turn end phase

* readd removing berry from memory after harvest
2024-05-22 08:52:45 -04:00
Xavion3
7ae09a31a5
Hotfix Sucker Punch and Upper Hand AI (#1237) 2024-05-22 07:13:39 -05:00
Benjamin Odom
460e94725b
Fix Money Typo (#1234) 2024-05-22 01:50:14 -05:00
zaccie
b66a68a37b
Drop Shadow Fixes On Team Builder Screen (#1220)
* Drop Shadow Adjustments

Adding support for x,y axis on dropshadow and adjusting the values to be less bad

* Further Refined New Shadow Positons

- Reverted MOVE_INFO_CONTENT to the old default
- Slight adjustments to other values

* Fixed Broken Drop Shadows

Fixed a case where the dropshadow became worse

---------

Co-authored-by: Benjamin Odom <bennybroseph@gmail.com>
2024-05-22 01:23:40 -05:00
Franck TROUILLEZ
7ac4900a3e
Allow to explicitly ignore faint phase when damaging. (#1182)
This allows to skip the faint phase in the `#damage` method for physical and special moves, to ensure we first queue the messages for the effectiveness of the attack and the potential critical hit.
We then explicitly unshift the faint phase in this case.
2024-05-22 01:01:16 -05:00
Frederico Santos
ae03b9cb20
Money with abbreviated form (#1222) 2024-05-22 00:54:44 -05:00
Ethan
c1c464b07a
Fixes Issue #1225: Scrafty line does not have Trailblaze in their TM learnset (#1228) 2024-05-22 00:33:49 -05:00
Madmadness65
25a792f080 Reduce wild evolution delay on some Pokémon
It was causing some Pokémon to be unevolved in later Classic mode trainer battles (notably the fifth and sixth rival fights). Lowering their evolution delay *should* mean they are fully evolved by these fights now.
2024-05-21 22:36:12 -05:00
td76099
fbd863a25c
Feature: Finish implementing Mind's Eye (#1060)
* Adds in the accuracy and evasion bypass for Mind's Eye

* Added comment to new IgnoreOpponentEvasionAbAttr class

* Added docs to apply so that it is actually complete
2024-05-21 23:11:42 -04:00
damocleas
879f009156
Quick-fix Egg Moves for Applin, Sableye, Pawmi, Nacli (#1226) 2024-05-21 19:50:06 -05:00
Madmadness65
3c8b4550b6 End shiny event
I hope everyone enjoyed the extended shiny event this weekend.
2024-05-21 18:58:48 -05:00
Madmadness65
bbfb4bb795 Fix Rayquaza's egg moves being reverted
It was an error from the document used.
2024-05-21 14:55:10 -05:00
Madmadness65
f1e622e4b9 Update egg moves
The newest batch of egg move changes.
2024-05-21 14:26:33 -05:00
zaccie
33f8365192
Drop Shadow Adjustments (#1197)
* Drop Shadow Adjustments

Adding support for x,y axis on dropshadow and adjusting the values to be less bad

* Further Refined New Shadow Positons

- Reverted MOVE_INFO_CONTENT to the old default
- Slight adjustments to other values
2024-05-21 10:00:33 -05:00
LaukkaE
8c01403630
tie event to UTC (#1203)
correct time
2024-05-21 09:38:07 -05:00
Jannik Tappert
5eb4077f13
Fixed german localization of bad dreams (#1206) 2024-05-21 09:33:54 -05:00
Lugiad
6405bcab87
Correction to French ability-trigger.ts (#1200) 2024-05-21 08:53:06 -05:00
Xavion3
3fd1ecf6a7
Update moveset logic to account for new sacrifice attr (#1192) 2024-05-21 02:40:53 -05:00
Sbug98
42e2be22bc
Implements bad dreams (#633)
* test commit

* de modified readme

* first implementation, needs testing with healer

* fixed beahviour if 2+ opponents are on field, also added message

* further fixed

* reset of overrides.ts before merge to main

* fixed grammar

Co-authored-by: Jonas Pinson <jonas.pinson@gmail.com>

* Implemented changes suggested by @bennybroseph and @TempsRay

* Added more docs to the class

* removed old comments

* fixed ability name in comments

* added translation and made message localized

* fixed ability name

* added missing bracket

---------

Co-authored-by: Jonas Pinson <jonas.pinson@gmail.com>
2024-05-21 02:26:01 -05:00
Jacob Knispel
6016ecfb46
Prevent Pokemon Info screen from being covered up (#1156)
* Move Pokemon info screen when confirming

Prevents the yes/no confirm menu from getting in the way when the Pokemon Info screen is open when catching a new Pokemon

* Greatly sped up makeRoomForConfirmUi()
2024-05-21 02:24:03 -05:00
0zuzu
67d5532d15
Check available Pkmn before asking to switch (#1194)
* Create Start Server.bat

idk anymore

* Update .gitignore

* Delete Start Server.bat

* Update .gitignore

* Update phases.ts

Check available party before asking to switch
2024-05-21 02:16:17 -05:00
322 changed files with 42370 additions and 33696 deletions

7
.eslintignore Normal file
View File

@ -0,0 +1,7 @@
dist/*
build/*
coverage/*
public/*
.github/*
node_modules/*
.vscode/*

View File

@ -1,17 +1,29 @@
{ {
"env": { "parser": "@typescript-eslint/parser", // Specifies the ESLint parser for TypeScript
"browser": true, "plugins": ["@typescript-eslint", "import"], // Includes TypeScript and import plugins
"es2021": true
},
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"overrides": [ "overrides": [
{ {
"files": ["src/**/*.ts"], "files": ["src/**/*.{ts,tsx,js,jsx}"], // Applies these rules to all TypeScript and JavaScript files in the src directory
"extends": "eslint:recommended" "rules": {
// General rules that apply to all files
"eqeqeq": ["error", "always"], // Enforces the use of === and !== instead of == and !=
"indent": ["error", 2], // Enforces a 2-space indentation
"quotes": ["error", "double"], // Enforces the use of double quotes for strings
"no-var": "error", // Disallows the use of var, enforcing let or const instead
"prefer-const": "error", // Prefers the use of const for variables that are never reassigned
"no-undef": "off", // Disables the rule that disallows the use of undeclared variables (TypeScript handles this)
"@typescript-eslint/no-unused-vars": [ "error", {
"args": "none", // Allows unused function parameters. Useful for functions with specific signatures where not all parameters are always used.
"ignoreRestSiblings": true // Allows unused variables that are part of a rest property in object destructuring. Useful for excluding certain properties from an object while using the rest.
}],
"eol-last": ["error", "always"], // Enforces at least one newline at the end of files
"@typescript-eslint/semi": ["error", "always"], // Requires semicolons for TypeScript-specific syntax
"semi": "off", // Disables the general semi rule for TypeScript files
"@typescript-eslint/no-extra-semi": ["error"], // Disallows unnecessary semicolons for TypeScript-specific syntax
"brace-style": "off", // Note: you must disable the base rule as it can report incorrect errors
"curly": ["error", "all"], // Enforces the use of curly braces for all control statements
"@typescript-eslint/brace-style": ["error", "1tbs"]
} }
], }
"rules": {} ]
} }

31
.github/workflows/eslint.yml vendored Normal file
View File

@ -0,0 +1,31 @@
name: ESLint
on:
# Trigger the workflow on push or pull request,
# but only for the main branch
push:
branches:
- main # Trigger on push events to the main branch
pull_request:
branches:
- main # Trigger on pull request events targeting the main branch
jobs:
run-linters: # Define a job named "run-linters"
name: Run linters # Human-readable name for the job
runs-on: ubuntu-latest # Specify the latest Ubuntu runner for the job
steps:
- name: Check out Git repository # Step to check out the repository
uses: actions/checkout@v2 # Use the checkout action version 2
- name: Set up Node.js # Step to set up Node.js environment
uses: actions/setup-node@v1 # Use the setup-node action version 1
with:
node-version: 20 # Specify Node.js version 20
- name: Install Node.js dependencies # Step to install Node.js dependencies
run: npm ci # Use 'npm ci' to install dependencies
- name: eslint # Step to run linters
uses: icrawl/action-eslint@v1

7
lefthook.yml Normal file
View File

@ -0,0 +1,7 @@
pre-commit:
parallel: true
commands:
eslint:
glob: '*.{js,jsx,ts,tsx}'
run: npx eslint --fix {staged_files}
stage_fixed: true

6103
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -10,18 +10,25 @@
"preview": "vite preview", "preview": "vite preview",
"test": "vitest run", "test": "vitest run",
"test:cov": "vitest run --coverage", "test:cov": "vitest run --coverage",
"test:watch": "vitest watch --coverage" "test:watch": "vitest watch --coverage",
"eslint": "eslint --fix ."
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.3.0",
"@typescript-eslint/eslint-plugin": "^7.10.0",
"@typescript-eslint/parser": "^7.10.0",
"@vitest/coverage-istanbul": "^1.4.0", "@vitest/coverage-istanbul": "^1.4.0",
"axios": "^1.6.2", "axios": "^1.6.2",
"axios-cache-interceptor": "^1.3.2", "axios-cache-interceptor": "^1.3.2",
"eslint": "^8.25.0", "eslint": "^8.57.0",
"eslint-plugin-import": "^2.29.1",
"jsdom": "^24.0.0", "jsdom": "^24.0.0",
"json-beautify": "^1.1.1", "json-beautify": "^1.1.1",
"lefthook": "^1.6.12",
"phaser3spectorjs": "^0.0.8", "phaser3spectorjs": "^0.0.8",
"pokenode-ts": "^1.20.0", "pokenode-ts": "^1.20.0",
"typescript": "^5.0.3", "typescript": "^5.4.5",
"typescript-eslint": "^7.10.0",
"vite": "^4.5.0", "vite": "^4.5.0",
"vite-plugin-fs": "^0.4.4", "vite-plugin-fs": "^0.4.4",
"vitest": "^1.4.0", "vitest": "^1.4.0",

View File

@ -12,27 +12,28 @@ export const clientSessionId = Utils.randomString(32);
export function updateUserInfo(): Promise<[boolean, integer]> { export function updateUserInfo(): Promise<[boolean, integer]> {
return new Promise<[boolean, integer]>(resolve => { return new Promise<[boolean, integer]>(resolve => {
if (bypassLogin) { if (bypassLogin) {
loggedInUser = { username: 'Guest', lastSessionSlot: -1 }; loggedInUser = { username: "Guest", lastSessionSlot: -1 };
let lastSessionSlot = -1; let lastSessionSlot = -1;
for (let s = 0; s < 5; s++) { for (let s = 0; s < 5; s++) {
if (localStorage.getItem(`sessionData${s ? s : ''}_${loggedInUser.username}`)) { if (localStorage.getItem(`sessionData${s ? s : ""}_${loggedInUser.username}`)) {
lastSessionSlot = s; lastSessionSlot = s;
break; break;
} }
} }
loggedInUser.lastSessionSlot = lastSessionSlot; loggedInUser.lastSessionSlot = lastSessionSlot;
// Migrate old data from before the username was appended // Migrate old data from before the username was appended
[ 'data', 'sessionData', 'sessionData1', 'sessionData2', 'sessionData3', 'sessionData4' ].map(d => { [ "data", "sessionData", "sessionData1", "sessionData2", "sessionData3", "sessionData4" ].map(d => {
if (localStorage.hasOwnProperty(d)) { if (localStorage.hasOwnProperty(d)) {
if (localStorage.hasOwnProperty(`${d}_${loggedInUser.username}`)) if (localStorage.hasOwnProperty(`${d}_${loggedInUser.username}`)) {
localStorage.setItem(`${d}_${loggedInUser.username}_bak`, localStorage.getItem(`${d}_${loggedInUser.username}`)); localStorage.setItem(`${d}_${loggedInUser.username}_bak`, localStorage.getItem(`${d}_${loggedInUser.username}`));
}
localStorage.setItem(`${d}_${loggedInUser.username}`, localStorage.getItem(d)); localStorage.setItem(`${d}_${loggedInUser.username}`, localStorage.getItem(d));
localStorage.removeItem(d); localStorage.removeItem(d);
} }
}); });
return resolve([ true, 200 ]); return resolve([ true, 200 ]);
} }
Utils.apiFetch('account/info', true).then(response => { Utils.apiFetch("account/info", true).then(response => {
if (!response.ok) { if (!response.ok) {
resolve([ false, response.status ]); resolve([ false, response.status ]);
return; return;

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,6 @@ import { GameMode } from "./game-mode";
import { BattleSpec } from "./enums/battle-spec"; import { BattleSpec } from "./enums/battle-spec";
import { PlayerGender } from "./system/game-data"; import { PlayerGender } from "./system/game-data";
import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier"; import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
import { MoneyAchv } from "./system/achv";
import { PokeballType } from "./data/pokeball"; import { PokeballType } from "./data/pokeball";
export enum BattleType { export enum BattleType {
@ -34,7 +33,7 @@ export interface TurnCommand {
targets?: BattlerIndex[]; targets?: BattlerIndex[];
skip?: boolean; skip?: boolean;
args?: any[]; args?: any[];
}; }
interface TurnCommands { interface TurnCommands {
[key: integer]: TurnCommand [key: integer]: TurnCommand
@ -93,25 +92,26 @@ export default class Battle {
private initBattleSpec(): void { private initBattleSpec(): void {
let spec = BattleSpec.DEFAULT; let spec = BattleSpec.DEFAULT;
if (this.gameMode.isClassic) { if (this.gameMode.isWaveFinal(this.waveIndex) && this.gameMode.isClassic) {
if (this.waveIndex === 200)
spec = BattleSpec.FINAL_BOSS; spec = BattleSpec.FINAL_BOSS;
} }
this.battleSpec = spec; this.battleSpec = spec;
} }
private getLevelForWave(): integer { private getLevelForWave(): integer {
let levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex); const levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex);
let baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2); const baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2);
const bossMultiplier = 1.2; const bossMultiplier = 1.2;
if (!(this.waveIndex % 10)) { if (this.gameMode.isBoss(this.waveIndex)) {
const ret = Math.floor(baseLevel * bossMultiplier); const ret = Math.floor(baseLevel * bossMultiplier);
if (this.battleSpec === BattleSpec.FINAL_BOSS || !(this.waveIndex % 250)) if (this.battleSpec === BattleSpec.FINAL_BOSS || !(this.waveIndex % 250)) {
return Math.ceil(ret / 25) * 25; return Math.ceil(ret / 25) * 25;
}
let levelOffset = 0; let levelOffset = 0;
if (!this.gameMode.isWaveFinal(this.waveIndex)) if (!this.gameMode.isWaveFinal(this.waveIndex)) {
levelOffset = Math.round(Phaser.Math.RND.realInRange(-1, 1) * Math.floor(levelWaveIndex / 10)); levelOffset = Math.round(Phaser.Math.RND.realInRange(-1, 1) * Math.floor(levelWaveIndex / 10));
}
return ret + levelOffset; return ret + levelOffset;
} }
@ -125,8 +125,9 @@ export default class Battle {
randSeedGaussForLevel(value: number): number { randSeedGaussForLevel(value: number): number {
let rand = 0; let rand = 0;
for (let i = value; i > 0; i--) for (let i = value; i > 0; i--) {
rand += Phaser.Math.RND.realInRange(0, 1); rand += Phaser.Math.RND.realInRange(0, 1);
}
return rand / value; return rand / value;
} }
@ -162,20 +163,22 @@ export default class Battle {
scene.addMoney(moneyAmount.value); scene.addMoney(moneyAmount.value);
scene.queueMessage(`You picked up ₽${moneyAmount.value.toLocaleString('en-US')}!`, null, true); scene.queueMessage(`You picked up ₽${moneyAmount.value.toLocaleString("en-US")}!`, null, true);
scene.currentBattle.moneyScattered = 0; scene.currentBattle.moneyScattered = 0;
} }
addBattleScore(scene: BattleScene): void { addBattleScore(scene: BattleScene): void {
let partyMemberTurnMultiplier = scene.getEnemyParty().length / 2 + 0.5; let partyMemberTurnMultiplier = scene.getEnemyParty().length / 2 + 0.5;
if (this.double) if (this.double) {
partyMemberTurnMultiplier /= 1.5; partyMemberTurnMultiplier /= 1.5;
for (let p of scene.getEnemyParty()) { }
if (p.isBoss()) for (const p of scene.getEnemyParty()) {
if (p.isBoss()) {
partyMemberTurnMultiplier *= (p.bossSegments / 1.5) / scene.getEnemyParty().length; partyMemberTurnMultiplier *= (p.bossSegments / 1.5) / scene.getEnemyParty().length;
} }
const turnMultiplier = Phaser.Tweens.Builders.GetEaseFunction('Sine.easeIn')(1 - Math.min(this.turn - 2, 10 * partyMemberTurnMultiplier) / (10 * partyMemberTurnMultiplier)); }
const turnMultiplier = Phaser.Tweens.Builders.GetEaseFunction("Sine.easeIn")(1 - Math.min(this.turn - 2, 10 * partyMemberTurnMultiplier) / (10 * partyMemberTurnMultiplier));
const finalBattleScore = Math.ceil(this.battleScore * turnMultiplier); const finalBattleScore = Math.ceil(this.battleScore * turnMultiplier);
scene.score += finalBattleScore; scene.score += finalBattleScore;
console.log(`Battle Score: ${finalBattleScore} (${this.turn - 1} Turns x${Math.floor(turnMultiplier * 100) / 100})`); console.log(`Battle Score: ${finalBattleScore} (${this.turn - 1} Turns x${Math.floor(turnMultiplier * 100) / 100})`);
@ -186,54 +189,63 @@ export default class Battle {
getBgmOverride(scene: BattleScene): string { getBgmOverride(scene: BattleScene): string {
const battlers = this.enemyParty.slice(0, this.getBattlerCount()); const battlers = this.enemyParty.slice(0, this.getBattlerCount());
if (this.battleType === BattleType.TRAINER) { if (this.battleType === BattleType.TRAINER) {
if (!this.started && this.trainer.config.encounterBgm && this.trainer.getEncounterMessages()?.length) if (!this.started && this.trainer.config.encounterBgm && this.trainer.getEncounterMessages()?.length) {
return `encounter_${this.trainer.getEncounterBgm()}`; return `encounter_${this.trainer.getEncounterBgm()}`;
}
return this.trainer.getBattleBgm(); return this.trainer.getBattleBgm();
} else if (this.gameMode.isClassic && this.waveIndex > 195 && this.battleSpec !== BattleSpec.FINAL_BOSS) } else if (this.gameMode.isClassic && this.waveIndex > 195 && this.battleSpec !== BattleSpec.FINAL_BOSS) {
return 'end_summit'; return "end_summit";
for (let pokemon of battlers) { }
for (const pokemon of battlers) {
if (this.battleSpec === BattleSpec.FINAL_BOSS) { if (this.battleSpec === BattleSpec.FINAL_BOSS) {
if (pokemon.formIndex) if (pokemon.formIndex) {
return 'battle_final'; return "battle_final";
return 'battle_final_encounter'; }
return "battle_final_encounter";
} }
if (pokemon.species.legendary || pokemon.species.subLegendary || pokemon.species.mythical) { if (pokemon.species.legendary || pokemon.species.subLegendary || pokemon.species.mythical) {
if (pokemon.species.speciesId === Species.REGIROCK || pokemon.species.speciesId === Species.REGICE || pokemon.species.speciesId === Species.REGISTEEL || pokemon.species.speciesId === Species.REGIGIGAS || pokemon.species.speciesId === Species.REGIELEKI || pokemon.species.speciesId === Species.REGIDRAGO) if (pokemon.species.speciesId === Species.REGIROCK || pokemon.species.speciesId === Species.REGICE || pokemon.species.speciesId === Species.REGISTEEL || pokemon.species.speciesId === Species.REGIGIGAS || pokemon.species.speciesId === Species.REGIELEKI || pokemon.species.speciesId === Species.REGIDRAGO) {
return 'battle_legendary_regis'; return "battle_legendary_regis";
if (pokemon.species.speciesId === Species.COBALION || pokemon.species.speciesId === Species.TERRAKION || pokemon.species.speciesId === Species.VIRIZION || pokemon.species.speciesId === Species.TORNADUS || pokemon.species.speciesId === Species.THUNDURUS || pokemon.species.speciesId === Species.LANDORUS || pokemon.species.speciesId === Species.KELDEO || pokemon.species.speciesId === Species.MELOETTA || pokemon.species.speciesId === Species.GENESECT) }
return 'battle_legendary_unova'; if (pokemon.species.speciesId === Species.COBALION || pokemon.species.speciesId === Species.TERRAKION || pokemon.species.speciesId === Species.VIRIZION || pokemon.species.speciesId === Species.TORNADUS || pokemon.species.speciesId === Species.THUNDURUS || pokemon.species.speciesId === Species.LANDORUS || pokemon.species.speciesId === Species.KELDEO || pokemon.species.speciesId === Species.MELOETTA || pokemon.species.speciesId === Species.GENESECT) {
if (pokemon.species.speciesId === Species.RESHIRAM || pokemon.species.speciesId === Species.ZEKROM) return "battle_legendary_unova";
return 'battle_legendary_res_zek'; }
if (pokemon.species.speciesId === Species.KYUREM) if (pokemon.species.speciesId === Species.RESHIRAM || pokemon.species.speciesId === Species.ZEKROM) {
return 'battle_legendary_kyurem'; return "battle_legendary_res_zek";
if (pokemon.species.legendary) }
return 'battle_legendary_res_zek'; if (pokemon.species.speciesId === Species.KYUREM) {
return 'battle_legendary_unova'; return "battle_legendary_kyurem";
}
if (pokemon.species.legendary) {
return "battle_legendary_res_zek";
}
return "battle_legendary_unova";
} }
} }
if (scene.gameMode.isClassic && this.waveIndex <= 4) if (scene.gameMode.isClassic && this.waveIndex <= 4) {
return 'battle_wild'; return "battle_wild";
}
return null; return null;
} }
randSeedInt(scene: BattleScene, range: integer, min: integer = 0): integer { randSeedInt(scene: BattleScene, range: integer, min: integer = 0): integer {
if (range <= 1) if (range <= 1) {
return min; return min;
let ret: integer; }
const tempRngCounter = scene.rngCounter; const tempRngCounter = scene.rngCounter;
const tempSeedOverride = scene.rngSeedOverride; const tempSeedOverride = scene.rngSeedOverride;
const state = Phaser.Math.RND.state(); const state = Phaser.Math.RND.state();
if (this.battleSeedState) if (this.battleSeedState) {
Phaser.Math.RND.state(this.battleSeedState); Phaser.Math.RND.state(this.battleSeedState);
else { } else {
Phaser.Math.RND.sow([ Utils.shiftCharCodes(this.battleSeed, this.turn << 6) ]); Phaser.Math.RND.sow([ Utils.shiftCharCodes(this.battleSeed, this.turn << 6) ]);
console.log('Battle Seed:', this.battleSeed); console.log("Battle Seed:", this.battleSeed);
} }
scene.rngCounter = this.rngCounter++; scene.rngCounter = this.rngCounter++;
scene.rngSeedOverride = this.battleSeed; scene.rngSeedOverride = this.battleSeed;
ret = Utils.randSeedInt(range, min); const ret = Utils.randSeedInt(range, min);
this.battleSeedState = Phaser.Math.RND.state(); this.battleSeedState = Phaser.Math.RND.state();
Phaser.Math.RND.state(state); Phaser.Math.RND.state(state);
scene.rngCounter = tempRngCounter; scene.rngCounter = tempRngCounter;
@ -245,9 +257,10 @@ export default class Battle {
export class FixedBattle extends Battle { export class FixedBattle extends Battle {
constructor(scene: BattleScene, waveIndex: integer, config: FixedBattleConfig) { constructor(scene: BattleScene, waveIndex: integer, config: FixedBattleConfig) {
super(scene.gameMode, waveIndex, config.battleType, config.battleType === BattleType.TRAINER ? config.getTrainer(scene) : null, config.double); super(scene.gameMode, waveIndex, config.battleType, config.battleType === BattleType.TRAINER ? config.getTrainer(scene) : null, config.double);
if (config.getEnemyParty) if (config.getEnemyParty) {
this.enemyParty = config.getEnemyParty(scene); this.enemyParty = config.getEnemyParty(scene);
} }
}
} }
type GetTrainerFunc = (scene: BattleScene) => Trainer; type GetTrainerFunc = (scene: BattleScene) => Trainer;
@ -290,7 +303,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[]): Get
return (scene: BattleScene) => { return (scene: BattleScene) => {
const rand = Utils.randSeedInt(trainerPool.length); const rand = Utils.randSeedInt(trainerPool.length);
const trainerTypes: TrainerType[] = []; const trainerTypes: TrainerType[] = [];
for (let trainerPoolEntry of trainerPool) { for (const trainerPoolEntry of trainerPool) {
const trainerType = Array.isArray(trainerPoolEntry) const trainerType = Array.isArray(trainerPoolEntry)
? Utils.randSeedItem(trainerPoolEntry) ? Utils.randSeedItem(trainerPoolEntry)
: trainerPoolEntry; : trainerPoolEntry;

View File

@ -2,8 +2,8 @@
* Dualshock mapping * Dualshock mapping
*/ */
const pad_dualshock = { const pad_dualshock = {
padID: 'Dualshock', padID: "Dualshock",
padType: 'Sony', padType: "Sony",
gamepadMapping: { gamepadMapping: {
RC_S: 0, RC_S: 0,
RC_E: 1, RC_E: 1,

View File

@ -2,8 +2,8 @@
* Generic pad mapping * Generic pad mapping
*/ */
const pad_generic = { const pad_generic = {
padID: 'Generic', padID: "Generic",
padType: 'generic', padType: "generic",
gamepadMapping: { gamepadMapping: {
RC_S: 0, RC_S: 0,
RC_E: 1, RC_E: 1,

View File

@ -2,8 +2,8 @@
* 081f-e401 - UnlicensedSNES * 081f-e401 - UnlicensedSNES
*/ */
const pad_unlicensedSNES = { const pad_unlicensedSNES = {
padID: '081f-e401', padID: "081f-e401",
padType: 'snes', padType: "snes",
gamepadMapping : { gamepadMapping : {
RC_S: 2, RC_S: 2,
RC_E: 1, RC_E: 1,

View File

@ -2,8 +2,8 @@
* Generic pad mapping * Generic pad mapping
*/ */
const pad_xbox360 = { const pad_xbox360 = {
padID: 'Xbox 360 controller (XInput STANDARD GAMEPAD)', padID: "Xbox 360 controller (XInput STANDARD GAMEPAD)",
padType: 'xbox', padType: "xbox",
gamepadMapping: { gamepadMapping: {
RC_S: 0, RC_S: 0,
RC_E: 1, RC_E: 1,

View File

@ -9,20 +9,19 @@ import { BattlerTag } from "./battler-tags";
import { BattlerTagType } from "./enums/battler-tag-type"; import { BattlerTagType } from "./enums/battler-tag-type";
import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect"; import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect";
import { Gender } from "./gender"; import { Gender } from "./gender";
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, RecoilAttr, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves, StatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr } from "./move"; import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves, StatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr } from "./move";
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
import { ArenaTagType } from "./enums/arena-tag-type"; import { ArenaTagType } from "./enums/arena-tag-type";
import { Stat } from "./pokemon-stat"; import { Stat } from "./pokemon-stat";
import { PokemonHeldItemModifier } from "../modifier/modifier"; import { BerryModifier, PokemonHeldItemModifier } from "../modifier/modifier";
import { Moves } from "./enums/moves"; import { Moves } from "./enums/moves";
import { TerrainType } from "./terrain"; import { TerrainType } from "./terrain";
import { SpeciesFormChangeManualTrigger } from "./pokemon-forms"; import { SpeciesFormChangeManualTrigger } from "./pokemon-forms";
import { Abilities } from "./enums/abilities"; import { Abilities } from "./enums/abilities";
import i18next, { Localizable } from "#app/plugins/i18n.js"; import i18next, { Localizable } from "#app/plugins/i18n.js";
import { Command } from "../ui/command-ui-handler"; import { Command } from "../ui/command-ui-handler";
import Battle from "#app/battle.js"; import { getPokeballName } from "./pokeball";
import { ability } from "#app/locales/en/ability.js"; import { BerryModifierType } from "#app/modifier/modifier-type";
import { PokeballType, getPokeballName } from "./pokeball";
export class Ability implements Localizable { export class Ability implements Localizable {
public id: Abilities; public id: Abilities;
@ -39,7 +38,7 @@ export class Ability implements Localizable {
constructor(id: Abilities, generation: integer) { constructor(id: Abilities, generation: integer) {
this.id = id; this.id = id;
this.nameAppend = ''; this.nameAppend = "";
this.generation = generation; this.generation = generation;
this.attrs = []; this.attrs = [];
this.conditions = []; this.conditions = [];
@ -48,10 +47,10 @@ export class Ability implements Localizable {
} }
localize(): void { localize(): void {
const i18nKey = Abilities[this.id].split('_').filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join('') as string; const i18nKey = Abilities[this.id].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("") as string;
this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`) as string}${this.nameAppend}` : ''; this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`) as string}${this.nameAppend}` : "";
this.description = this.id ? i18next.t(`ability:${i18nKey}.description`) as string : ''; this.description = this.id ? i18next.t(`ability:${i18nKey}.description`) as string : "";
} }
getAttrs(attrType: { new(...args: any[]): AbAttr }): AbAttr[] { getAttrs(attrType: { new(...args: any[]): AbAttr }): AbAttr[] {
@ -94,12 +93,12 @@ export class Ability implements Localizable {
} }
partial(): this { partial(): this {
this.nameAppend += ' (P)'; this.nameAppend += " (P)";
return this; return this;
} }
unimplemented(): this { unimplemented(): this {
this.nameAppend += ' (N)'; this.nameAppend += " (N)";
return this; return this;
} }
} }
@ -127,7 +126,7 @@ export abstract class AbAttr {
return null; return null;
} }
getCondition(): AbAttrCondition { getCondition(): AbAttrCondition | null {
return this.extraCondition || null; return this.extraCondition || null;
} }
@ -145,7 +144,7 @@ export class BlockRecoilDamageAttr extends AbAttr {
} }
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]) { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]) {
return i18next.t('abilityTriggers:blockRecoilDamage', {pokemonName: `${getPokemonPrefix(pokemon)}${pokemon.name}`, abilityName: abilityName}); return i18next.t("abilityTriggers:blockRecoilDamage", {pokemonName: `${getPokemonPrefix(pokemon)}${pokemon.name}`, abilityName: abilityName});
} }
} }
@ -178,8 +177,9 @@ export class PostBattleInitFormChangeAbAttr extends PostBattleInitAbAttr {
applyPostBattleInit(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostBattleInit(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const formIndex = this.formFunc(pokemon); const formIndex = this.formFunc(pokemon);
if (formIndex !== pokemon.formIndex) if (formIndex !== pokemon.formIndex) {
return pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false); return pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
}
return false; return false;
} }
@ -193,7 +193,7 @@ export class PostBattleInitStatChangeAbAttr extends PostBattleInitAbAttr {
constructor(stats: BattleStat | BattleStat[], levels: integer, selfTarget?: boolean) { constructor(stats: BattleStat | BattleStat[], levels: integer, selfTarget?: boolean) {
super(); super();
this.stats = typeof(stats) === 'number' this.stats = typeof(stats) === "number"
? [ stats as BattleStat ] ? [ stats as BattleStat ]
: stats as BattleStat[]; : stats as BattleStat[];
this.levels = levels; this.levels = levels;
@ -203,19 +203,21 @@ export class PostBattleInitStatChangeAbAttr extends PostBattleInitAbAttr {
applyPostBattleInit(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostBattleInit(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const statChangePhases: StatChangePhase[] = []; const statChangePhases: StatChangePhase[] = [];
if (this.selfTarget) if (this.selfTarget) {
statChangePhases.push(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.levels)); statChangePhases.push(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.levels));
else { } else {
for (let opponent of pokemon.getOpponents()) for (const opponent of pokemon.getOpponents()) {
statChangePhases.push(new StatChangePhase(pokemon.scene, opponent.getBattlerIndex(), false, this.stats, this.levels)); statChangePhases.push(new StatChangePhase(pokemon.scene, opponent.getBattlerIndex(), false, this.stats, this.levels));
} }
}
for (let statChangePhase of statChangePhases) { for (const statChangePhase of statChangePhases) {
if (!this.selfTarget && !statChangePhase.getPokemon().summonData) if (!this.selfTarget && !statChangePhase.getPokemon().summonData) {
pokemon.scene.pushPhase(statChangePhase); // TODO: This causes the ability bar to be shown at the wrong time pokemon.scene.pushPhase(statChangePhase);
else } else { // TODO: This causes the ability bar to be shown at the wrong time
pokemon.scene.unshiftPhase(statChangePhase); pokemon.scene.unshiftPhase(statChangePhase);
} }
}
return true; return true;
} }
@ -256,7 +258,7 @@ export class PreDefendFullHpEndureAbAttr extends PreDefendAbAttr {
return pokemon.addTag(BattlerTagType.STURDY, 1); return pokemon.addTag(BattlerTagType.STURDY, 1);
} }
return false return false;
} }
} }
@ -391,9 +393,10 @@ class TypeImmunityStatChangeAbAttr extends TypeImmunityAbAttr {
if (ret) { if (ret) {
cancelled.value = true; cancelled.value = true;
const simulated = args.length > 1 && args[1]; const simulated = args.length > 1 && args[1];
if (!simulated) if (!simulated) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels));
} }
}
return ret; return ret;
} }
@ -416,9 +419,10 @@ class TypeImmunityAddBattlerTagAbAttr extends TypeImmunityAbAttr {
if (ret) { if (ret) {
cancelled.value = true; cancelled.value = true;
const simulated = args.length > 1 && args[1]; const simulated = args.length > 1 && args[1];
if (!simulated) if (!simulated) {
pokemon.addTag(this.tagType, this.turnCount, undefined, pokemon.id); pokemon.addTag(this.tagType, this.turnCount, undefined, pokemon.id);
} }
}
return ret; return ret;
} }
@ -453,14 +457,15 @@ export class PostDefendAbAttr extends AbAttr {
export class PostDefendDisguiseAbAttr extends PostDefendAbAttr { export class PostDefendDisguiseAbAttr extends PostDefendAbAttr {
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (pokemon.formIndex == 0 && pokemon.battleData.hitCount != 0 && (move.getMove().category == MoveCategory.SPECIAL || move.getMove().category == MoveCategory.PHYSICAL)) { if (pokemon.formIndex === 0 && pokemon.battleData.hitCount !== 0 && (move.getMove().category === MoveCategory.SPECIAL || move.getMove().category === MoveCategory.PHYSICAL)) {
const recoilDamage = Math.ceil((pokemon.getMaxHp() / 8) - attacker.turnData.damageDealt); const recoilDamage = Math.ceil((pokemon.getMaxHp() / 8) - attacker.turnData.damageDealt);
if (!recoilDamage) if (!recoilDamage) {
return false; return false;
}
pokemon.damageAndUpdate(recoilDamage, HitResult.OTHER); pokemon.damageAndUpdate(recoilDamage, HitResult.OTHER);
pokemon.turnData.damageTaken += recoilDamage; pokemon.turnData.damageTaken += recoilDamage;
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\'s disguise was busted!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, "'s disguise was busted!"));
return true; return true;
} }
@ -547,7 +552,7 @@ export class MoveImmunityStatChangeAbAttr extends MoveImmunityAbAttr {
} }
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean { applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const ret = super.applyPreDefend(pokemon, passive, attacker, move, cancelled, args) const ret = super.applyPreDefend(pokemon, passive, attacker, move, cancelled, args);
if (ret) { if (ret) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels));
} }
@ -559,7 +564,7 @@ export class MoveImmunityStatChangeAbAttr extends MoveImmunityAbAttr {
export class ReverseDrainAbAttr extends PostDefendAbAttr { export class ReverseDrainAbAttr extends PostDefendAbAttr {
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (!!move.getMove().getAttrs(HitHealAttr).length || !!move.getMove().getAttrs(StrengthSapHealAttr).length ) { if (!!move.getMove().getAttrs(HitHealAttr).length || !!move.getMove().getAttrs(StrengthSapHealAttr).length ) {
pokemon.scene.queueMessage(getPokemonMessage(attacker, ` sucked up the liquid ooze!`)); pokemon.scene.queueMessage(getPokemonMessage(attacker, " sucked up the liquid ooze!"));
return true; return true;
} }
return false; return false;
@ -586,8 +591,8 @@ export class PostDefendStatChangeAbAttr extends PostDefendAbAttr {
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (this.condition(pokemon, attacker, move.getMove())) { if (this.condition(pokemon, attacker, move.getMove())) {
if (this.allOthers) { if (this.allOthers) {
let otherPokemon = pokemon.getAlly() ? pokemon.getOpponents().concat([ pokemon.getAlly() ]) : pokemon.getOpponents(); const otherPokemon = pokemon.getAlly() ? pokemon.getOpponents().concat([ pokemon.getAlly() ]) : pokemon.getOpponents();
for (let other of otherPokemon) { for (const other of otherPokemon) {
other.scene.unshiftPhase(new StatChangePhase(other.scene, (other).getBattlerIndex(), false, [ this.stat ], this.levels)); other.scene.unshiftPhase(new StatChangePhase(other.scene, (other).getBattlerIndex(), false, [ this.stat ], this.levels));
} }
return true; return true;
@ -618,8 +623,8 @@ export class PostDefendHpGatedStatChangeAbAttr extends PostDefendAbAttr {
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
const hpGateFlat: integer = Math.ceil(pokemon.getMaxHp() * this.hpGate) const hpGateFlat: integer = Math.ceil(pokemon.getMaxHp() * this.hpGate);
const lastAttackReceived = pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1] const lastAttackReceived = pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1];
if (this.condition(pokemon, attacker, move.getMove()) && (pokemon.hp <= hpGateFlat && (pokemon.hp + lastAttackReceived.damage) > hpGateFlat)) { if (this.condition(pokemon, attacker, move.getMove()) && (pokemon.hp <= hpGateFlat && (pokemon.hp + lastAttackReceived.damage) > hpGateFlat)) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.levels));
return true; return true;
@ -700,8 +705,9 @@ export class PostDefendTerrainChangeAbAttr extends PostDefendAbAttr {
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (hitResult < HitResult.NO_EFFECT) if (hitResult < HitResult.NO_EFFECT) {
return pokemon.scene.arena.trySetTerrain(this.terrainType, true); return pokemon.scene.arena.trySetTerrain(this.terrainType, true);
}
return false; return false;
} }
@ -755,8 +761,9 @@ export class PostDefendContactApplyTagChanceAbAttr extends PostDefendAbAttr {
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance) if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance) {
return attacker.addTag(this.tagType, this.turnCount, move.moveId, attacker.id); return attacker.addTag(this.tagType, this.turnCount, move.moveId, attacker.id);
}
return false; return false;
} }
@ -818,8 +825,9 @@ export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr {
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (!pokemon.scene.arena.weather?.isImmutable()) if (!pokemon.scene.arena.weather?.isImmutable()) {
return pokemon.scene.arena.trySetWeather(this.weatherType, true); return pokemon.scene.arena.trySetWeather(this.weatherType, true);
}
return false; return false;
} }
@ -842,7 +850,7 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr {
} }
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return getPokemonMessage(pokemon, ` swapped\nabilities with its target!`); return getPokemonMessage(pokemon, " swapped\nabilities with its target!");
} }
} }
@ -956,7 +964,7 @@ export class MoveTypeChangePowerMultiplierAbAttr extends VariableMoveTypeAbAttr
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const type = (args[0] as Utils.IntegerHolder); const type = (args[0] as Utils.IntegerHolder);
if (type.value == this.matchType) { if (type.value === this.matchType) {
type.value = this.newType; type.value = this.newType;
(args[1] as Utils.NumberHolder).value *= this.powerMultiplier; (args[1] as Utils.NumberHolder).value *= this.powerMultiplier;
return true; return true;
@ -1150,8 +1158,9 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
if (heldItems.length) { if (heldItems.length) {
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false, false).then(success => { pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false, false).then(success => {
if (success) if (success) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${defender.name}'s ${stolenItem.type.name}!`)); pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${defender.name}'s ${stolenItem.type.name}!`));
}
resolve(success); resolve(success);
}); });
return; return;
@ -1181,7 +1190,7 @@ export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr {
} }
applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (pokemon != attacker && (!this.contactRequired || move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance && !pokemon.status) { if (pokemon !== attacker && (!this.contactRequired || move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance && !pokemon.status) {
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)];
return attacker.trySetStatus(effect, true, pokemon); return attacker.trySetStatus(effect, true, pokemon);
} }
@ -1211,7 +1220,7 @@ export class PostAttackApplyBattlerTagAbAttr extends PostAttackAbAttr {
} }
applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (pokemon != attacker && (!this.contactRequired || move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance(attacker, pokemon, move) && !pokemon.status) { if (pokemon !== attacker && (!this.contactRequired || move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance(attacker, pokemon, move) && !pokemon.status) {
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)];
@ -1238,8 +1247,9 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
if (heldItems.length) { if (heldItems.length) {
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false, false).then(success => { pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false, false).then(success => {
if (success) if (success) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${attacker.name}'s ${stolenItem.type.name}!`)); pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${attacker.name}'s ${stolenItem.type.name}!`));
}
resolve(success); resolve(success);
}); });
return; return;
@ -1273,7 +1283,7 @@ class PostVictoryStatChangeAbAttr extends PostVictoryAbAttr {
} }
applyPostVictory(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> { applyPostVictory(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> {
const stat = typeof this.stat === 'function' const stat = typeof this.stat === "function"
? this.stat(pokemon) ? this.stat(pokemon)
: this.stat; : this.stat;
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels));
@ -1320,7 +1330,7 @@ export class PostKnockOutStatChangeAbAttr extends PostKnockOutAbAttr {
} }
applyPostKnockOut(pokemon: Pokemon, passive: boolean, knockedOut: Pokemon, args: any[]): boolean | Promise<boolean> { applyPostKnockOut(pokemon: Pokemon, passive: boolean, knockedOut: Pokemon, args: any[]): boolean | Promise<boolean> {
const stat = typeof this.stat === 'function' const stat = typeof this.stat === "function"
? this.stat(pokemon) ? this.stat(pokemon)
: this.stat; : this.stat;
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels));
@ -1356,6 +1366,28 @@ export class IgnoreOpponentStatChangesAbAttr extends AbAttr {
return true; return true;
} }
} }
/**
* Ignores opponent's evasion stat changes when determining if a move hits or not
* @extends AbAttr
* @see {@linkcode apply}
*/
export class IgnoreOpponentEvasionAbAttr extends AbAttr {
constructor() {
super(false);
}
/**
* Checks if enemy Pokemon is trapped by an Arena Trap-esque ability
* @param pokemon N/A
* @param passive N/A
* @param cancelled N/A
* @param args [0] {@linkcode Utils.IntegerHolder} of BattleStat.EVA
* @returns if evasion level was successfully considered as 0
*/
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]) {
(args[0] as Utils.IntegerHolder).value = 0;
return true;
}
}
export class IntimidateImmunityAbAttr extends AbAttr { export class IntimidateImmunityAbAttr extends AbAttr {
constructor() { constructor() {
@ -1378,10 +1410,10 @@ export class PostIntimidateStatChangeAbAttr extends AbAttr {
private overwrites: boolean; private overwrites: boolean;
constructor(stats: BattleStat[], levels: integer, overwrites?: boolean) { constructor(stats: BattleStat[], levels: integer, overwrites?: boolean) {
super(true) super(true);
this.stats = stats this.stats = stats;
this.levels = levels this.levels = levels;
this.overwrites = !!overwrites this.overwrites = !!overwrites;
} }
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
@ -1455,7 +1487,7 @@ export class PostSummonStatChangeAbAttr extends PostSummonAbAttr {
constructor(stats: BattleStat | BattleStat[], levels: integer, selfTarget?: boolean, intimidate?: boolean) { constructor(stats: BattleStat | BattleStat[], levels: integer, selfTarget?: boolean, intimidate?: boolean) {
super(false); super(false);
this.stats = typeof(stats) === 'number' this.stats = typeof(stats) === "number"
? [ stats as BattleStat ] ? [ stats as BattleStat ]
: stats as BattleStat[]; : stats as BattleStat[];
this.levels = levels; this.levels = levels;
@ -1469,8 +1501,8 @@ export class PostSummonStatChangeAbAttr extends PostSummonAbAttr {
pokemon.scene.pushPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.levels)); pokemon.scene.pushPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.levels));
return true; return true;
} }
for (let opponent of pokemon.getOpponents()) { for (const opponent of pokemon.getOpponents()) {
const cancelled = new Utils.BooleanHolder(false) const cancelled = new Utils.BooleanHolder(false);
if (this.intimidate) { if (this.intimidate) {
applyAbAttrs(IntimidateImmunityAbAttr, opponent, cancelled); applyAbAttrs(IntimidateImmunityAbAttr, opponent, cancelled);
applyAbAttrs(PostIntimidateStatChangeAbAttr, opponent, cancelled); applyAbAttrs(PostIntimidateStatChangeAbAttr, opponent, cancelled);
@ -1523,10 +1555,11 @@ export class PostSummonClearAllyStatsAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const target = pokemon.getAlly(); const target = pokemon.getAlly();
if (target?.isActive(true)) { if (target?.isActive(true)) {
for (let s = 0; s < target.summonData.battleStats.length; s++) for (let s = 0; s < target.summonData.battleStats.length; s++) {
target.summonData.battleStats[s] = 0; target.summonData.battleStats[s] = 0;
}
target.scene.queueMessage(getPokemonMessage(target, `'s stat changes\nwere removed!`)); target.scene.queueMessage(getPokemonMessage(target, "'s stat changes\nwere removed!"));
return true; return true;
} }
@ -1544,15 +1577,16 @@ export class DownloadAbAttr extends PostSummonAbAttr {
this.enemyDef = 0; this.enemyDef = 0;
this.enemySpDef = 0; this.enemySpDef = 0;
for (let opponent of pokemon.getOpponents()) { for (const opponent of pokemon.getOpponents()) {
this.enemyDef += opponent.stats[BattleStat.DEF]; this.enemyDef += opponent.stats[BattleStat.DEF];
this.enemySpDef += opponent.stats[BattleStat.SPDEF]; this.enemySpDef += opponent.stats[BattleStat.SPDEF];
} }
if (this.enemyDef < this.enemySpDef) if (this.enemyDef < this.enemySpDef) {
this.stats = [BattleStat.ATK]; this.stats = [BattleStat.ATK];
else } else {
this.stats = [BattleStat.SPATK]; this.stats = [BattleStat.SPATK];
}
if (this.enemyDef > 0 && this.enemySpDef > 0) { // only activate if there's actually an enemy to download from if (this.enemyDef > 0 && this.enemySpDef > 0) { // only activate if there's actually an enemy to download from
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, this.stats, 1)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, this.stats, 1));
@ -1573,8 +1607,9 @@ export class PostSummonWeatherChangeAbAttr extends PostSummonAbAttr {
} }
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
if (!pokemon.scene.arena.weather?.isImmutable()) if (!pokemon.scene.arena.weather?.isImmutable()) {
return pokemon.scene.arena.trySetWeather(this.weatherType, true); return pokemon.scene.arena.trySetWeather(this.weatherType, true);
}
return false; return false;
} }
@ -1605,8 +1640,9 @@ export class PostSummonFormChangeAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const formIndex = this.formFunc(pokemon); const formIndex = this.formFunc(pokemon);
if (formIndex !== pokemon.formIndex) if (formIndex !== pokemon.formIndex) {
return pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false); return pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
}
return false; return false;
} }
@ -1615,18 +1651,21 @@ export class PostSummonFormChangeAbAttr extends PostSummonAbAttr {
export class TraceAbAttr extends PostSummonAbAttr { export class TraceAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const targets = pokemon.getOpponents(); const targets = pokemon.getOpponents();
if (!targets.length) if (!targets.length) {
return false; return false;
}
let target: Pokemon; let target: Pokemon;
if (targets.length > 1) if (targets.length > 1) {
pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex); pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex);
else } else {
target = targets[0]; target = targets[0];
}
// Wonder Guard is normally uncopiable so has the attribute, but trace specifically can copy it // Wonder Guard is normally uncopiable so has the attribute, but trace specifically can copy it
if (target.getAbility().hasAttr(UncopiableAbilityAbAttr) && target.getAbility().id !== Abilities.WONDER_GUARD) if (target.getAbility().hasAttr(UncopiableAbilityAbAttr) && target.getAbility().id !== Abilities.WONDER_GUARD) {
return false; return false;
}
pokemon.summonData.ability = target.getAbility().id; pokemon.summonData.ability = target.getAbility().id;
@ -1643,14 +1682,16 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const targets = pokemon.getOpponents(); const targets = pokemon.getOpponents();
if (!targets.length) if (!targets.length) {
return false; return false;
}
let target: Pokemon; let target: Pokemon;
if (targets.length > 1) if (targets.length > 1) {
pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex); pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex);
else } else {
target = targets[0]; target = targets[0];
}
pokemon.summonData.speciesForm = target.getSpeciesForm(); pokemon.summonData.speciesForm = target.getSpeciesForm();
pokemon.summonData.fusionSpeciesForm = target.getFusionSpeciesForm(); pokemon.summonData.fusionSpeciesForm = target.getFusionSpeciesForm();
@ -1662,7 +1703,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
pokemon.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m.moveId, m.ppUsed, m.ppUp)); pokemon.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m.moveId, m.ppUsed, m.ppUp));
pokemon.summonData.types = target.getTypes(); pokemon.summonData.types = target.getTypes();
pokemon.scene.playSound('PRSFX- Transform'); pokemon.scene.playSound("PRSFX- Transform");
pokemon.loadAssets(false).then(() => pokemon.playAnim()); pokemon.loadAssets(false).then(() => pokemon.playAnim());
@ -1732,7 +1773,7 @@ export class ProtectStatAbAttr extends PreStatChangeAbAttr {
} }
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return getPokemonMessage(pokemon, `'s ${abilityName}\nprevents lowering its ${this.protectedStat !== undefined ? getBattleStatName(this.protectedStat) : 'stats'}!`); return getPokemonMessage(pokemon, `'s ${abilityName}\nprevents lowering its ${this.protectedStat !== undefined ? getBattleStatName(this.protectedStat) : "stats"}!`);
} }
} }
@ -1761,7 +1802,7 @@ export class StatusEffectImmunityAbAttr extends PreSetStatusAbAttr {
} }
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return getPokemonMessage(pokemon, `'s ${abilityName}\nprevents ${this.immuneEffects.length ? getStatusEffectDescriptor(args[0] as StatusEffect) : 'status problems'}!`); return getPokemonMessage(pokemon, `'s ${abilityName}\nprevents ${this.immuneEffects.length ? getStatusEffectDescriptor(args[0] as StatusEffect) : "status problems"}!`);
} }
} }
@ -1851,8 +1892,9 @@ export class ConditionalCritAbAttr extends AbAttr {
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const target = (args[1] as Pokemon); const target = (args[1] as Pokemon);
const move = (args[2] as Move); const move = (args[2] as Move);
if(!this.condition(pokemon,target,move)) if(!this.condition(pokemon,target,move)) {
return false; return false;
}
(args[0] as Utils.BooleanHolder).value = true; (args[0] as Utils.BooleanHolder).value = true;
return true; return true;
@ -1885,8 +1927,9 @@ export class IncrementMovePriorityAbAttr extends AbAttr {
} }
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (!this.moveIncrementFunc(pokemon, args[0] as Move)) if (!this.moveIncrementFunc(pokemon, args[0] as Move)) {
return false; return false;
}
(args[1] as Utils.IntegerHolder).value += this.increaseAmount; (args[1] as Utils.IntegerHolder).value += this.increaseAmount;
return true; return true;
@ -1913,8 +1956,9 @@ export class BlockWeatherDamageAttr extends PreWeatherDamageAbAttr {
} }
applyPreWeatherEffect(pokemon: Pokemon, passive: boolean, weather: Weather, cancelled: Utils.BooleanHolder, args: any[]): boolean { applyPreWeatherEffect(pokemon: Pokemon, passive: boolean, weather: Weather, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (!this.weatherTypes.length || this.weatherTypes.indexOf(weather?.weatherType) > -1) if (!this.weatherTypes.length || this.weatherTypes.indexOf(weather?.weatherType) > -1) {
cancelled.value = true; cancelled.value = true;
}
return true; return true;
} }
@ -1941,8 +1985,9 @@ export class SuppressWeatherEffectAbAttr extends PreWeatherEffectAbAttr {
function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition { function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition {
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
if (pokemon.scene.arena.weather?.isEffectSuppressed(pokemon.scene)) if (pokemon.scene.arena.weather?.isEffectSuppressed(pokemon.scene)) {
return false; return false;
}
const weatherType = pokemon.scene.arena.weather?.weatherType; const weatherType = pokemon.scene.arena.weather?.weatherType;
return weatherType && weatherTypes.indexOf(weatherType) > -1; return weatherType && weatherTypes.indexOf(weatherType) > -1;
}; };
@ -1950,8 +1995,8 @@ function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition {
function getAnticipationCondition(): AbAttrCondition { function getAnticipationCondition(): AbAttrCondition {
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
for (let opponent of pokemon.getOpponents()) { for (const opponent of pokemon.getOpponents()) {
for (let move of opponent.moveset) { for (const move of opponent.moveset) {
// move is super effective // move is super effective
if (move.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.getMove().type, opponent) >= 2) { if (move.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.getMove().type, opponent) >= 2) {
return true; return true;
@ -1995,7 +2040,7 @@ function getAnticipationCondition(): AbAttrCondition {
function getOncePerBattleCondition(ability: Abilities): AbAttrCondition { function getOncePerBattleCondition(ability: Abilities): AbAttrCondition {
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
return !pokemon.battleData?.abilitiesApplied.includes(ability); return !pokemon.battleData?.abilitiesApplied.includes(ability);
} };
} }
export class ForewarnAbAttr extends PostSummonAbAttr { export class ForewarnAbAttr extends PostSummonAbAttr {
@ -2007,8 +2052,8 @@ export class ForewarnAbAttr extends PostSummonAbAttr {
let maxPowerSeen = 0; let maxPowerSeen = 0;
let maxMove = ""; let maxMove = "";
let movePower = 0; let movePower = 0;
for (let opponent of pokemon.getOpponents()) { for (const opponent of pokemon.getOpponents()) {
for (let move of opponent.moveset) { for (const move of opponent.moveset) {
if (move.getMove() instanceof StatusMove) { if (move.getMove() instanceof StatusMove) {
movePower = 1; movePower = 1;
} else if (move.getMove().findAttr(attr => attr instanceof OneHitKOAttr)) { } else if (move.getMove().findAttr(attr => attr instanceof OneHitKOAttr)) {
@ -2038,8 +2083,8 @@ export class FriskAbAttr extends PostSummonAbAttr {
} }
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
for (let opponent of pokemon.getOpponents()) { for (const opponent of pokemon.getOpponents()) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " frisked " + opponent.name + "\'s " + opponent.getAbility().name + "!")); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " frisked " + opponent.name + "'s " + opponent.getAbility().name + "!"));
} }
return true; return true;
} }
@ -2066,8 +2111,9 @@ export class PostWeatherChangeAddBattlerTagAttr extends PostWeatherChangeAbAttr
applyPostWeatherChange(pokemon: Pokemon, passive: boolean, weather: WeatherType, args: any[]): boolean { applyPostWeatherChange(pokemon: Pokemon, passive: boolean, weather: WeatherType, args: any[]): boolean {
console.log(this.weatherTypes.find(w => weather === w), WeatherType[weather]); console.log(this.weatherTypes.find(w => weather === w), WeatherType[weather]);
if (!this.weatherTypes.find(w => weather === w)) if (!this.weatherTypes.find(w => weather === w)) {
return false; return false;
}
return pokemon.addTag(this.tagType, this.turnCount); return pokemon.addTag(this.tagType, this.turnCount);
} }
@ -2155,8 +2201,9 @@ export class PostTerrainChangeAddBattlerTagAttr extends PostTerrainChangeAbAttr
} }
applyPostTerrainChange(pokemon: Pokemon, passive: boolean, terrain: TerrainType, args: any[]): boolean { applyPostTerrainChange(pokemon: Pokemon, passive: boolean, terrain: TerrainType, args: any[]): boolean {
if (!this.terrainTypes.find(t => t === terrain)) if (!this.terrainTypes.find(t => t === terrain)) {
return false; return false;
}
return pokemon.addTag(this.tagType, this.turnCount); return pokemon.addTag(this.tagType, this.turnCount);
} }
@ -2206,23 +2253,89 @@ export class PostTurnResetStatusAbAttr extends PostTurnAbAttr {
} }
} }
/**
* After the turn ends, try to create an extra item
*/
export class PostTurnLootAbAttr extends PostTurnAbAttr {
/**
* @param itemType - The type of item to create
* @param procChance - Chance to create an item
* @see {@linkcode applyPostTurn()}
*/
constructor(
/** Extend itemType to add more options */
private itemType: "EATEN_BERRIES" | "HELD_BERRIES",
private procChance: (pokemon: Pokemon) => number
) {
super();
}
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const pass = Phaser.Math.RND.realInRange(0, 1);
// Clamp procChance to [0, 1]. Skip if didn't proc (less than pass)
if (Math.max(Math.min(this.procChance(pokemon), 1), 0) < pass) {
return false;
}
if (this.itemType === "EATEN_BERRIES") {
return this.createEatenBerry(pokemon);
} else {
return false;
}
}
/**
* Create a new berry chosen randomly from the berries the pokemon ate this battle
* @param pokemon The pokemon with this ability
* @returns whether a new berry was created
*/
createEatenBerry(pokemon: Pokemon): boolean {
const berriesEaten = pokemon.battleData.berriesEaten;
if (!berriesEaten.length) {
return false;
}
const randomIdx = Utils.randSeedInt(berriesEaten.length);
const chosenBerryType = berriesEaten[randomIdx];
const chosenBerry = new BerryModifierType(chosenBerryType);
berriesEaten.splice(randomIdx); // Remove berry from memory
const berryModifier = pokemon.scene.findModifier(
(m) => m instanceof BerryModifier && m.berryType === chosenBerryType,
pokemon.isPlayer()
) as BerryModifier | undefined;
if (!berryModifier) {
pokemon.scene.addModifier(new BerryModifier(chosenBerry, pokemon.id, chosenBerryType, 1));
} else {
berryModifier.stackCount++;
}
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` harvested one ${chosenBerry.name}!`));
pokemon.scene.updateModifiers(pokemon.isPlayer());
return true;
}
}
export class MoodyAbAttr extends PostTurnAbAttr { export class MoodyAbAttr extends PostTurnAbAttr {
constructor() { constructor() {
super(true); super(true);
} }
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
let selectableStats = [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD]; const selectableStats = [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD];
let increaseStatArray = selectableStats.filter(s => pokemon.summonData.battleStats[s] < 6); const increaseStatArray = selectableStats.filter(s => pokemon.summonData.battleStats[s] < 6);
let decreaseStatArray = selectableStats.filter(s => pokemon.summonData.battleStats[s] > -6); let decreaseStatArray = selectableStats.filter(s => pokemon.summonData.battleStats[s] > -6);
if (increaseStatArray.length > 0) { if (increaseStatArray.length > 0) {
let increaseStat = increaseStatArray[Utils.randInt(increaseStatArray.length)]; const increaseStat = increaseStatArray[Utils.randInt(increaseStatArray.length)];
decreaseStatArray = decreaseStatArray.filter(s => s !== increaseStat); decreaseStatArray = decreaseStatArray.filter(s => s !== increaseStat);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [increaseStat], 2)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [increaseStat], 2));
} }
if (decreaseStatArray.length > 0) { if (decreaseStatArray.length > 0) {
let decreaseStat = selectableStats[Utils.randInt(selectableStats.length)]; const decreaseStat = selectableStats[Utils.randInt(selectableStats.length)];
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [decreaseStat], -1)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [decreaseStat], -1));
} }
return true; return true;
@ -2282,6 +2395,34 @@ export class PostTurnFormChangeAbAttr extends PostTurnAbAttr {
} }
} }
/**
* Attribute used for abilities (Bad Dreams) that damages the opponents for being asleep
*/
export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr {
/**
* Deals damage to all sleeping opponents equal to 1/8 of their max hp (min 1)
* @param {Pokemon} pokemon Pokemon that has this ability
* @param {boolean} passive N/A
* @param {any[]} args N/A
* @returns {boolean} true if any opponents are sleeping
*/
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> {
let hadEffect: boolean = false;
for(const opp of pokemon.getOpponents()) {
if(opp.status !== undefined && opp.status.effect === StatusEffect.SLEEP) {
opp.damageAndUpdate(Math.floor(Math.max(1, opp.getMaxHp() / 8)), HitResult.OTHER);
pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", {pokemonName: `${getPokemonPrefix(opp)}${opp.name}`}));
hadEffect = true;
}
}
return hadEffect;
}
}
/** /**
* Grabs the last failed Pokeball used * Grabs the last failed Pokeball used
* @extends PostTurnAbAttr * @extends PostTurnAbAttr
@ -2298,8 +2439,8 @@ export class FetchBallAbAttr extends PostTurnAbAttr {
* @returns true if player has used a pokeball and this pokemon is owned by the player * @returns true if player has used a pokeball and this pokemon is owned by the player
*/ */
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
let lastUsed = pokemon.scene.currentBattle.lastUsedPokeball; const lastUsed = pokemon.scene.currentBattle.lastUsedPokeball;
if(lastUsed != null && pokemon.isPlayer) { if(lastUsed !== null && pokemon.isPlayer) {
pokemon.scene.pokeballCounts[lastUsed]++; pokemon.scene.pokeballCounts[lastUsed]++;
pokemon.scene.currentBattle.lastUsedPokeball = null; pokemon.scene.currentBattle.lastUsedPokeball = null;
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` found a\n${getPokeballName(lastUsed)}!`)); pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` found a\n${getPokeballName(lastUsed)}!`));
@ -2321,8 +2462,9 @@ export class PostBiomeChangeWeatherChangeAbAttr extends PostBiomeChangeAbAttr {
} }
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (!pokemon.scene.arena.weather?.isImmutable()) if (!pokemon.scene.arena.weather?.isImmutable()) {
return pokemon.scene.arena.trySetWeather(this.weatherType, true); return pokemon.scene.arena.trySetWeather(this.weatherType, true);
}
return false; return false;
} }
@ -2498,7 +2640,7 @@ export class PostFaintContactDamageAbAttr extends PostFaintAbAttr {
applyPostFaint(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostFaint(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) { if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) {
const cancelled = new Utils.BooleanHolder(false); const cancelled = new Utils.BooleanHolder(false);
pokemon.scene.getField(true).map(p=>applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled)) pokemon.scene.getField(true).map(p=>applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled));
if (cancelled) { if (cancelled) {
return false; return false;
} }
@ -2780,62 +2922,70 @@ function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: { new(...args: any
pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> { pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> {
return new Promise(resolve => { return new Promise(resolve => {
if (!pokemon.canApplyAbility(passive)) { if (!pokemon.canApplyAbility(passive)) {
if (!passive) if (!passive) {
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve()); return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
else } else {
return resolve(); return resolve();
} }
}
const ability = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()); const ability = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility());
const attrs = ability.getAttrs(attrType) as TAttr[]; const attrs = ability.getAttrs(attrType) as TAttr[];
const clearSpliceQueueAndResolve = () => { const clearSpliceQueueAndResolve = () => {
pokemon.scene.clearPhaseQueueSplice(); pokemon.scene.clearPhaseQueueSplice();
if (!passive) if (!passive) {
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve()); return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
else } else {
return resolve(); return resolve();
}
}; };
const applyNextAbAttr = () => { const applyNextAbAttr = () => {
if (attrs.length) if (attrs.length) {
applyAbAttr(attrs.shift()); applyAbAttr(attrs.shift());
else } else {
clearSpliceQueueAndResolve(); clearSpliceQueueAndResolve();
}
}; };
const applyAbAttr = (attr: TAttr) => { const applyAbAttr = (attr: TAttr) => {
if (!canApplyAttr(pokemon, attr)) if (!canApplyAttr(pokemon, attr)) {
return applyNextAbAttr(); return applyNextAbAttr();
}
pokemon.scene.setPhaseQueueSplice(); pokemon.scene.setPhaseQueueSplice();
const onApplySuccess = () => { const onApplySuccess = () => {
if (pokemon.battleData && !pokemon.battleData.abilitiesApplied.includes(ability.id)) { if (pokemon.battleData && !pokemon.battleData.abilitiesApplied.includes(ability.id)) {
pokemon.battleData.abilitiesApplied.push(ability.id); pokemon.battleData.abilitiesApplied.push(ability.id);
} }
if (attr.showAbility && !quiet) { if (attr.showAbility && !quiet) {
if (showAbilityInstant) if (showAbilityInstant) {
pokemon.scene.abilityBar.showAbility(pokemon, passive); pokemon.scene.abilityBar.showAbility(pokemon, passive);
else } else {
queueShowAbility(pokemon, passive); queueShowAbility(pokemon, passive);
} }
}
if (!quiet) { if (!quiet) {
const message = attr.getTriggerMessage(pokemon, (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name, args); const message = attr.getTriggerMessage(pokemon, (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name, args);
if (message) { if (message) {
if (isAsync) if (isAsync) {
pokemon.scene.ui.showText(message, null, () => pokemon.scene.ui.showText(null, 0), null, true); pokemon.scene.ui.showText(message, null, () => pokemon.scene.ui.showText(null, 0), null, true);
else } else {
pokemon.scene.queueMessage(message); pokemon.scene.queueMessage(message);
} }
} }
}
}; };
const result = applyFunc(attr, passive); const result = applyFunc(attr, passive);
if (result instanceof Promise) { if (result instanceof Promise) {
result.then(success => { result.then(success => {
if (success) if (success) {
onApplySuccess(); onApplySuccess();
}
applyNextAbAttr(); applyNextAbAttr();
}); });
} else { } else {
if (result) if (result) {
onApplySuccess(); onApplySuccess();
}
applyNextAbAttr(); applyNextAbAttr();
} }
}; };
@ -3110,7 +3260,7 @@ export function initAbilities() {
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.SANDSTORM), .attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.SANDSTORM),
new Ability(Abilities.PRESSURE, 3) new Ability(Abilities.PRESSURE, 3)
.attr(IncreasePpAbAttr) .attr(IncreasePpAbAttr)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is exerting its Pressure!')), .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " is exerting its Pressure!")),
new Ability(Abilities.THICK_FAT, 3) new Ability(Abilities.THICK_FAT, 3)
.attr(ReceivedTypeDamageMultiplierAbAttr, Type.FIRE, 0.5) .attr(ReceivedTypeDamageMultiplierAbAttr, Type.FIRE, 0.5)
.attr(ReceivedTypeDamageMultiplierAbAttr, Type.ICE, 0.5) .attr(ReceivedTypeDamageMultiplierAbAttr, Type.ICE, 0.5)
@ -3133,8 +3283,8 @@ export function initAbilities() {
new Ability(Abilities.TRUANT, 3) new Ability(Abilities.TRUANT, 3)
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.TRUANT, 1, false), .attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.TRUANT, 1, false),
new Ability(Abilities.HUSTLE, 3) new Ability(Abilities.HUSTLE, 3)
.attr(BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5, (user, target, move) => move.category == MoveCategory.PHYSICAL) .attr(BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5, (user, target, move) => move.category === MoveCategory.PHYSICAL)
.attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 0.8, (user, target, move) => move.category == MoveCategory.PHYSICAL), .attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 0.8, (user, target, move) => move.category === MoveCategory.PHYSICAL),
new Ability(Abilities.CUTE_CHARM, 3) new Ability(Abilities.CUTE_CHARM, 3)
.attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED), .attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED),
new Ability(Abilities.PLUS, 3) new Ability(Abilities.PLUS, 3)
@ -3260,7 +3410,7 @@ export function initAbilities() {
.attr(MovePowerBoostAbAttr, (user, target, move) => { .attr(MovePowerBoostAbAttr, (user, target, move) => {
const power = new Utils.NumberHolder(move.power); const power = new Utils.NumberHolder(move.power);
applyMoveAttrs(VariablePowerAttr, user, target, move, power); applyMoveAttrs(VariablePowerAttr, user, target, move, power);
return power.value <= 60 return power.value <= 60;
}, 1.5), }, 1.5),
new Ability(Abilities.LEAF_GUARD, 4) new Ability(Abilities.LEAF_GUARD, 4)
.attr(StatusEffectImmunityAbAttr) .attr(StatusEffectImmunityAbAttr)
@ -3269,7 +3419,7 @@ export function initAbilities() {
new Ability(Abilities.KLUTZ, 4) new Ability(Abilities.KLUTZ, 4)
.unimplemented(), .unimplemented(),
new Ability(Abilities.MOLD_BREAKER, 4) new Ability(Abilities.MOLD_BREAKER, 4)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' breaks the mold!')) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " breaks the mold!"))
.attr(MoveAbilityBypassAbAttr), .attr(MoveAbilityBypassAbAttr),
new Ability(Abilities.SUPER_LUCK, 4) new Ability(Abilities.SUPER_LUCK, 4)
.attr(BonusCritAbAttr) .attr(BonusCritAbAttr)
@ -3278,7 +3428,7 @@ export function initAbilities() {
.attr(PostFaintContactDamageAbAttr,4) .attr(PostFaintContactDamageAbAttr,4)
.bypassFaint(), .bypassFaint(),
new Ability(Abilities.ANTICIPATION, 4) new Ability(Abilities.ANTICIPATION, 4)
.conditionalAttr(getAnticipationCondition(), PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' shuddered!')), .conditionalAttr(getAnticipationCondition(), PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " shuddered!")),
new Ability(Abilities.FOREWARN, 4) new Ability(Abilities.FOREWARN, 4)
.attr(ForewarnAbAttr), .attr(ForewarnAbAttr),
new Ability(Abilities.UNAWARE, 4) new Ability(Abilities.UNAWARE, 4)
@ -3326,7 +3476,7 @@ export function initAbilities() {
.ignorable() .ignorable()
.partial(), .partial(),
new Ability(Abilities.BAD_DREAMS, 4) new Ability(Abilities.BAD_DREAMS, 4)
.unimplemented(), .attr(PostTurnHurtIfSleepingAbAttr),
new Ability(Abilities.PICKPOCKET, 5) new Ability(Abilities.PICKPOCKET, 5)
.attr(PostDefendStealHeldItemAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT)), .attr(PostDefendStealHeldItemAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT)),
new Ability(Abilities.SHEER_FORCE, 5) new Ability(Abilities.SHEER_FORCE, 5)
@ -3367,7 +3517,13 @@ export function initAbilities() {
new Ability(Abilities.FLARE_BOOST, 5) new Ability(Abilities.FLARE_BOOST, 5)
.attr(MovePowerBoostAbAttr, (user, target, move) => move.category === MoveCategory.SPECIAL && user.status?.effect === StatusEffect.BURN, 1.5), .attr(MovePowerBoostAbAttr, (user, target, move) => move.category === MoveCategory.SPECIAL && user.status?.effect === StatusEffect.BURN, 1.5),
new Ability(Abilities.HARVEST, 5) new Ability(Abilities.HARVEST, 5)
.unimplemented(), .attr(
PostTurnLootAbAttr,
"EATEN_BERRIES",
/** Rate is doubled when under sun {@link https://dex.pokemonshowdown.com/abilities/harvest} */
(pokemon) => 0.5 * (getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN)(pokemon) ? 2 : 1)
)
.partial(),
new Ability(Abilities.TELEPATHY, 5) new Ability(Abilities.TELEPATHY, 5)
.attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon.getAlly() === attacker && move.getMove() instanceof AttackMove) .attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon.getAlly() === attacker && move.getMove() instanceof AttackMove)
.ignorable(), .ignorable(),
@ -3442,10 +3598,10 @@ export function initAbilities() {
.attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 1.1) .attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 1.1)
.partial(), .partial(),
new Ability(Abilities.TURBOBLAZE, 5) new Ability(Abilities.TURBOBLAZE, 5)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is radiating a blazing aura!')) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " is radiating a blazing aura!"))
.attr(MoveAbilityBypassAbAttr), .attr(MoveAbilityBypassAbAttr),
new Ability(Abilities.TERAVOLT, 5) new Ability(Abilities.TERAVOLT, 5)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is radiating a bursting aura!')) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " is radiating a bursting aura!"))
.attr(MoveAbilityBypassAbAttr), .attr(MoveAbilityBypassAbAttr),
new Ability(Abilities.AROMA_VEIL, 6) new Ability(Abilities.AROMA_VEIL, 6)
.ignorable() .ignorable()
@ -3501,10 +3657,10 @@ export function initAbilities() {
new Ability(Abilities.PARENTAL_BOND, 6) new Ability(Abilities.PARENTAL_BOND, 6)
.unimplemented(), .unimplemented(),
new Ability(Abilities.DARK_AURA, 6) new Ability(Abilities.DARK_AURA, 6)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is radiating a Dark Aura!')) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " is radiating a Dark Aura!"))
.attr(FieldMoveTypePowerBoostAbAttr, Type.DARK, 4 / 3), .attr(FieldMoveTypePowerBoostAbAttr, Type.DARK, 4 / 3),
new Ability(Abilities.FAIRY_AURA, 6) new Ability(Abilities.FAIRY_AURA, 6)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is radiating a Fairy Aura!')) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " is radiating a Fairy Aura!"))
.attr(FieldMoveTypePowerBoostAbAttr, Type.FAIRY, 4 / 3), .attr(FieldMoveTypePowerBoostAbAttr, Type.FAIRY, 4 / 3),
new Ability(Abilities.AURA_BREAK, 6) new Ability(Abilities.AURA_BREAK, 6)
.ignorable() .ignorable()
@ -3570,7 +3726,7 @@ export function initAbilities() {
.attr(UnsuppressableAbilityAbAttr) .attr(UnsuppressableAbilityAbAttr)
.attr(NoFusionAbilityAbAttr), .attr(NoFusionAbilityAbAttr),
new Ability(Abilities.DISGUISE, 7) new Ability(Abilities.DISGUISE, 7)
.attr(PreDefendMovePowerToOneAbAttr, (target, user, move) => target.formIndex == 0 && target.getAttackTypeEffectiveness(move.type, user) > 0) .attr(PreDefendMovePowerToOneAbAttr, (target, user, move) => target.formIndex === 0 && target.getAttackTypeEffectiveness(move.type, user) > 0)
.attr(PostSummonFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1) .attr(PostSummonFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
.attr(PostBattleInitFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1) .attr(PostBattleInitFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
.attr(PostDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1) .attr(PostDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
@ -3590,9 +3746,9 @@ export function initAbilities() {
.attr(UnsuppressableAbilityAbAttr) .attr(UnsuppressableAbilityAbAttr)
.attr(NoFusionAbilityAbAttr), .attr(NoFusionAbilityAbAttr),
new Ability(Abilities.POWER_CONSTRUCT, 7) // TODO: 10% Power Construct Zygarde isn't accounted for yet. If changed, update Zygarde's getSpeciesFormIndex entry accordingly new Ability(Abilities.POWER_CONSTRUCT, 7) // TODO: 10% Power Construct Zygarde isn't accounted for yet. If changed, update Zygarde's getSpeciesFormIndex entry accordingly
.attr(PostBattleInitFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === 'complete' ? 4 : 2) .attr(PostBattleInitFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === "complete" ? 4 : 2)
.attr(PostSummonFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === 'complete' ? 4 : 2) .attr(PostSummonFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === "complete" ? 4 : 2)
.attr(PostTurnFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === 'complete' ? 4 : 2) .attr(PostTurnFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === "complete" ? 4 : 2)
.attr(UncopiableAbilityAbAttr) .attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr) .attr(UnswappableAbilityAbAttr)
.attr(UnsuppressableAbilityAbAttr) .attr(UnsuppressableAbilityAbAttr)
@ -3740,7 +3896,7 @@ export function initAbilities() {
.attr(UncopiableAbilityAbAttr) .attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr) .attr(UnswappableAbilityAbAttr)
.attr(NoTransformAbilityAbAttr) .attr(NoTransformAbilityAbAttr)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, '\'s Neutralizing Gas filled the area!')) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, "'s Neutralizing Gas filled the area!"))
.partial(), .partial(),
new Ability(Abilities.PASTEL_VEIL, 8) new Ability(Abilities.PASTEL_VEIL, 8)
.attr(StatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC) .attr(StatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC)
@ -3886,8 +4042,9 @@ export function initAbilities() {
.partial(), .partial(),
new Ability(Abilities.MINDS_EYE, 9) new Ability(Abilities.MINDS_EYE, 9)
.attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [Type.NORMAL, Type.FIGHTING]) .attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [Type.NORMAL, Type.FIGHTING])
.ignorable() // TODO: evasiveness bypass should not be ignored, but accuracy immunity should .attr(ProtectStatAbAttr, BattleStat.ACC)
.partial(), .attr(IgnoreOpponentEvasionAbAttr)
.ignorable(),
new Ability(Abilities.SUPERSWEET_SYRUP, 9) new Ability(Abilities.SUPERSWEET_SYRUP, 9)
.attr(PostSummonStatChangeAbAttr, BattleStat.EVA, -1) .attr(PostSummonStatChangeAbAttr, BattleStat.EVA, -1)
.condition(getOncePerBattleCondition(Abilities.SUPERSWEET_SYRUP)), .condition(getOncePerBattleCondition(Abilities.SUPERSWEET_SYRUP)),

View File

@ -1,60 +1,60 @@
import { MainClient, NamedAPIResource } from 'pokenode-ts'; import { MainClient, NamedAPIResource } from "pokenode-ts";
import { MoveTarget, allMoves } from './move'; import { MoveTarget, allMoves } from "./move";
import * as Utils from '../utils'; import * as Utils from "../utils";
import fs from 'vite-plugin-fs/browser'; import fs from "vite-plugin-fs/browser";
import PokemonSpecies, { PokemonForm, SpeciesFormKey, allSpecies } from './pokemon-species'; import PokemonSpecies, { PokemonForm, SpeciesFormKey, allSpecies } from "./pokemon-species";
import { GrowthRate } from './exp'; import { GrowthRate } from "./exp";
import { Type } from './type'; import { Type } from "./type";
import { allAbilities } from './ability'; import { allAbilities } from "./ability";
import { Abilities } from "./enums/abilities"; import { Abilities } from "./enums/abilities";
import { Species } from './enums/species'; import { Species } from "./enums/species";
import { pokemonFormLevelMoves } from './pokemon-level-moves'; import { pokemonFormLevelMoves } from "./pokemon-level-moves";
import { tmSpecies } from './tms'; import { tmSpecies } from "./tms";
import { Moves } from './enums/moves'; import { Moves } from "./enums/moves";
const targetMap = { const targetMap = {
'specific-move': MoveTarget.ATTACKER, "specific-move": MoveTarget.ATTACKER,
'selected-pokemon-me-first': MoveTarget.NEAR_ENEMY, "selected-pokemon-me-first": MoveTarget.NEAR_ENEMY,
'ally': MoveTarget.NEAR_ALLY, "ally": MoveTarget.NEAR_ALLY,
'users-field': MoveTarget.USER_SIDE, "users-field": MoveTarget.USER_SIDE,
'user-or-ally': MoveTarget.USER_OR_NEAR_ALLY, "user-or-ally": MoveTarget.USER_OR_NEAR_ALLY,
'opponents-field': MoveTarget.ENEMY_SIDE, "opponents-field": MoveTarget.ENEMY_SIDE,
'user': MoveTarget.USER, "user": MoveTarget.USER,
'random-opponent': MoveTarget.RANDOM_NEAR_ENEMY, "random-opponent": MoveTarget.RANDOM_NEAR_ENEMY,
'all-other-pokemon': MoveTarget.ALL_NEAR_OTHERS, "all-other-pokemon": MoveTarget.ALL_NEAR_OTHERS,
'selected-pokemon': MoveTarget.NEAR_OTHER, "selected-pokemon": MoveTarget.NEAR_OTHER,
'all-opponents': MoveTarget.ALL_NEAR_ENEMIES, "all-opponents": MoveTarget.ALL_NEAR_ENEMIES,
'entire-field': MoveTarget.BOTH_SIDES, "entire-field": MoveTarget.BOTH_SIDES,
'user-and-allies': MoveTarget.USER_AND_ALLIES, "user-and-allies": MoveTarget.USER_AND_ALLIES,
'all-pokemon': MoveTarget.ALL, "all-pokemon": MoveTarget.ALL,
'all-allies': MoveTarget.NEAR_ALLY, "all-allies": MoveTarget.NEAR_ALLY,
'fainting-pokemon': MoveTarget.NEAR_OTHER "fainting-pokemon": MoveTarget.NEAR_OTHER
}; };
const generationMap = { const generationMap = {
'generation-i': 1, "generation-i": 1,
'generation-ii': 2, "generation-ii": 2,
'generation-iii': 3, "generation-iii": 3,
'generation-iv': 4, "generation-iv": 4,
'generation-v': 5, "generation-v": 5,
'generation-vi': 6, "generation-vi": 6,
'generation-vii': 7, "generation-vii": 7,
'generation-viii': 8, "generation-viii": 8,
'generation-ix': 9 "generation-ix": 9
}; };
const growthRateMap = { const growthRateMap = {
'slow-then-very-fast': GrowthRate.ERRATIC, "slow-then-very-fast": GrowthRate.ERRATIC,
'fast': GrowthRate.FAST, "fast": GrowthRate.FAST,
'medium': GrowthRate.MEDIUM_FAST, "medium": GrowthRate.MEDIUM_FAST,
'medium-slow': GrowthRate.MEDIUM_SLOW, "medium-slow": GrowthRate.MEDIUM_SLOW,
'slow': GrowthRate.SLOW, "slow": GrowthRate.SLOW,
'fast-then-very-slow': GrowthRate.FLUCTUATING "fast-then-very-slow": GrowthRate.FLUCTUATING
}; };
const regionalForms = [ 'alola', 'galar', 'hisui', 'paldea' ]; const regionalForms = [ "alola", "galar", "hisui", "paldea" ];
const ignoredForms = [ 'gmax', 'totem', 'cap', 'starter' ]; const ignoredForms = [ "gmax", "totem", "cap", "starter" ];
const generationDexNumbers = { const generationDexNumbers = {
1: 151, 1: 151,
@ -68,7 +68,7 @@ const generationDexNumbers = {
9: 1010 9: 1010
}; };
const versions = [ 'scarlet-violet', 'sword-shield', 'sun-moon' ]; const versions = [ "scarlet-violet", "sword-shield", "sun-moon" ];
type LevelMove = [level: integer, moveId: integer]; type LevelMove = [level: integer, moveId: integer];
@ -93,57 +93,60 @@ export async function printPokemon() {
const useExistingTmList = true; const useExistingTmList = true;
let enumStr = `export enum Species {\n`; let enumStr = "export enum Species {\n";
let pokemonSpeciesStr = `\tallSpecies.push(\n`; let pokemonSpeciesStr = "\tallSpecies.push(\n";
const speciesLevelMoves: SpeciesLevelMoves = {}; const speciesLevelMoves: SpeciesLevelMoves = {};
const speciesFormLevelMoves: SpeciesFormLevelMoves = {}; const speciesFormLevelMoves: SpeciesFormLevelMoves = {};
const moveTmSpecies: TmSpecies = {}; const moveTmSpecies: TmSpecies = {};
let pokemonArr: NamedAPIResource[] = []; let pokemonArr: NamedAPIResource[] = [];
let offset = 0; const offset = 0;
let pokemonResponse = await api.pokemon.listPokemons(offset, 2000) const pokemonResponse = await api.pokemon.listPokemons(offset, 2000);
pokemonArr = pokemonResponse.results; pokemonArr = pokemonResponse.results;
const types = Utils.getEnumKeys(Type).map(t => t.toLowerCase()); const types = Utils.getEnumKeys(Type).map(t => t.toLowerCase());
const abilities = Utils.getEnumKeys(Abilities).map(a => a.toLowerCase().replace(/\_/g, '-')); const abilities = Utils.getEnumKeys(Abilities).map(a => a.toLowerCase().replace(/\_/g, "-"));
const pokemonSpeciesList: PokemonSpecies[] = []; const pokemonSpeciesList: PokemonSpecies[] = [];
for (let p of pokemonArr) { for (const p of pokemonArr) {
const pokemon = await api.pokemon.getPokemonByName(p.name); const pokemon = await api.pokemon.getPokemonByName(p.name);
let region: string = ''; let region: string = "";
if (pokemon.id > 10000) { if (pokemon.id > 10000) {
const dexIdMatch = /\/(\d+)\//.exec(pokemon.species.url); const dexIdMatch = /\/(\d+)\//.exec(pokemon.species.url);
if (!dexIdMatch) if (!dexIdMatch) {
continue; continue;
}
const matchingSpecies = pokemonSpeciesList[parseInt(dexIdMatch[1]) - 1]; const matchingSpecies = pokemonSpeciesList[parseInt(dexIdMatch[1]) - 1];
if (!matchingSpecies) if (!matchingSpecies) {
continue; continue;
}
const speciesKey = (matchingSpecies as any).key as string; const speciesKey = (matchingSpecies as any).key as string;
const formName = pokemon.name.slice(speciesKey.length + 1); const formName = pokemon.name.slice(speciesKey.length + 1);
if (ignoredForms.filter(f => formName.indexOf(f) > -1).length) if (ignoredForms.filter(f => formName.indexOf(f) > -1).length) {
continue; continue;
}
let shortFormName = formName.indexOf('-') > -1 const shortFormName = formName.indexOf("-") > -1
? formName.slice(0, formName.indexOf('-')) ? formName.slice(0, formName.indexOf("-"))
: formName; : formName;
if (regionalForms.indexOf(shortFormName) > -1) if (regionalForms.indexOf(shortFormName) > -1) {
region = shortFormName.toUpperCase(); region = shortFormName.toUpperCase();
else { } else {
const formBaseStats: integer[] = []; const formBaseStats: integer[] = [];
let formBaseTotal = 0; let formBaseTotal = 0;
// Assume correct stat order in API result // Assume correct stat order in API result
for (let stat of pokemon.stats) { for (const stat of pokemon.stats) {
formBaseStats.push(stat.base_stat); formBaseStats.push(stat.base_stat);
formBaseTotal += stat.base_stat; formBaseTotal += stat.base_stat;
} }
@ -164,12 +167,13 @@ export async function printPokemon() {
let moveVer: string; let moveVer: string;
if (!speciesFormLevelMoves.hasOwnProperty(speciesKey)) if (!speciesFormLevelMoves.hasOwnProperty(speciesKey)) {
speciesFormLevelMoves[speciesKey] = []; speciesFormLevelMoves[speciesKey] = [];
}
speciesFormLevelMoves[speciesKey][pokemonForm.formIndex] = []; speciesFormLevelMoves[speciesKey][pokemonForm.formIndex] = [];
for (let version of versions) { for (const version of versions) {
if (pokemon.moves.find(m => m.version_group_details.find(v => v.version_group.name === version && v.move_learn_method.name === 'level-up'))) { if (pokemon.moves.find(m => m.version_group_details.find(v => v.version_group.name === version && v.move_learn_method.name === "level-up"))) {
moveVer = version; moveVer = version;
break; break;
} }
@ -180,32 +184,36 @@ export async function printPokemon() {
moveData.version_group_details.filter(v => versions.indexOf(v.version_group.name) > -1).forEach(verData => { moveData.version_group_details.filter(v => versions.indexOf(v.version_group.name) > -1).forEach(verData => {
const isMoveVer = verData.version_group.name === moveVer; const isMoveVer = verData.version_group.name === moveVer;
const moveName = moveData.move.name.toUpperCase().replace(/\_/g, '').replace(/\-/g, '_'); const moveName = moveData.move.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_");
const moveId = Math.max(Utils.getEnumKeys(Moves).indexOf(moveName), 0); const moveId = Math.max(Utils.getEnumKeys(Moves).indexOf(moveName), 0);
const learnMethod = verData.move_learn_method.name; const learnMethod = verData.move_learn_method.name;
if (isMoveVer && learnMethod === 'level-up') if (isMoveVer && learnMethod === "level-up") {
speciesFormLevelMoves[speciesKey][pokemonForm.formIndex].push([ verData.level_learned_at, moveId ]); speciesFormLevelMoves[speciesKey][pokemonForm.formIndex].push([ verData.level_learned_at, moveId ]);
}
if ([ 'machine', 'tutor' ].indexOf(learnMethod) > -1 || (useExistingTmList && tmSpecies.hasOwnProperty(moveId as Moves) && learnMethod === 'level-up')) { if ([ "machine", "tutor" ].indexOf(learnMethod) > -1 || (useExistingTmList && tmSpecies.hasOwnProperty(moveId as Moves) && learnMethod === "level-up")) {
if (!moveTmSpecies.hasOwnProperty(moveId)) if (!moveTmSpecies.hasOwnProperty(moveId)) {
moveTmSpecies[moveId] = []; moveTmSpecies[moveId] = [];
}
const speciesIndex = moveTmSpecies[moveId].findIndex(s => s[0] === speciesKey); const speciesIndex = moveTmSpecies[moveId].findIndex(s => s[0] === speciesKey);
if (speciesIndex === -1) if (speciesIndex === -1) {
moveTmSpecies[moveId].push([ speciesKey, formName ]); moveTmSpecies[moveId].push([ speciesKey, formName ]);
else } else {
(moveTmSpecies[moveId][speciesIndex] as string[]).push(formName); (moveTmSpecies[moveId][speciesIndex] as string[]).push(formName);
} }
}
}); });
}); });
if (JSON.stringify(speciesLevelMoves[speciesKey]) === JSON.stringify(speciesFormLevelMoves[speciesKey][pokemonForm.formIndex])) { if (JSON.stringify(speciesLevelMoves[speciesKey]) === JSON.stringify(speciesFormLevelMoves[speciesKey][pokemonForm.formIndex])) {
delete speciesFormLevelMoves[speciesKey][pokemonForm.formIndex]; delete speciesFormLevelMoves[speciesKey][pokemonForm.formIndex];
if (!Object.keys(speciesFormLevelMoves[speciesKey]).length) if (!Object.keys(speciesFormLevelMoves[speciesKey]).length) {
delete speciesFormLevelMoves[speciesKey]; delete speciesFormLevelMoves[speciesKey];
} }
} }
}
matchingSpecies.forms.push(pokemonForm); matchingSpecies.forms.push(pokemonForm);
continue; continue;
@ -214,7 +222,7 @@ export async function printPokemon() {
const species = await api.pokemon.getPokemonSpeciesByName(pokemon.species.name); const species = await api.pokemon.getPokemonSpeciesByName(pokemon.species.name);
let speciesKey = species.name.toUpperCase().replace(/\-/g, '_'); let speciesKey = species.name.toUpperCase().replace(/\-/g, "_");
const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === speciesKey); const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === speciesKey);
@ -227,15 +235,16 @@ export async function printPokemon() {
let generationIndex = 0; let generationIndex = 0;
if (!region) if (!region) {
while (++generationIndex < 9 && dexId > generationDexNumbers[generationIndex]); while (++generationIndex < 9 && dexId > generationDexNumbers[generationIndex]){}
else } else {
generationIndex = regionalForms.indexOf(region.toLowerCase()) + 6; generationIndex = regionalForms.indexOf(region.toLowerCase()) + 6;
}
const baseStats: integer[] = []; const baseStats: integer[] = [];
let baseTotal = 0; let baseTotal = 0;
// Assume correct stat order in API result // Assume correct stat order in API result
for (let stat of pokemon.stats) { for (const stat of pokemon.stats) {
baseStats.push(stat.base_stat); baseStats.push(stat.base_stat);
baseTotal += stat.base_stat; baseTotal += stat.base_stat;
} }
@ -250,7 +259,7 @@ export async function printPokemon() {
]; ];
const pokemonSpecies = new PokemonSpecies(dexId, generationIndex, species.is_legendary && baseTotal < 660, species.is_legendary && baseTotal >= 660, species.is_mythical, const pokemonSpecies = new PokemonSpecies(dexId, generationIndex, species.is_legendary && baseTotal < 660, species.is_legendary && baseTotal >= 660, species.is_mythical,
species.genera.find(g => g.language.name === 'en')?.genus, type1 as Type, type2 > -1 ? type2 as Type : null, pokemon.height / 10, pokemon.weight / 10, ability1 as Abilities, ability2 as Abilities, abilityHidden as Abilities, species.genera.find(g => g.language.name === "en")?.genus, type1 as Type, type2 > -1 ? type2 as Type : null, pokemon.height / 10, pokemon.weight / 10, ability1 as Abilities, ability2 as Abilities, abilityHidden as Abilities,
baseTotal, baseStats[0], baseStats[1], baseStats[2], baseStats[3], baseStats[4], baseStats[5], species.capture_rate, species.base_happiness, pokemon.base_experience, growthRateMap[species.growth_rate.name], baseTotal, baseStats[0], baseStats[1], baseStats[2], baseStats[3], baseStats[4], baseStats[5], species.capture_rate, species.base_happiness, pokemon.base_experience, growthRateMap[species.growth_rate.name],
species.gender_rate < 9 ? 100 - (species.gender_rate * 12.5) : null, species.has_gender_differences, species.forms_switchable); species.gender_rate < 9 ? 100 - (species.gender_rate * 12.5) : null, species.has_gender_differences, species.forms_switchable);
@ -262,8 +271,8 @@ export async function printPokemon() {
speciesLevelMoves[speciesKey] = []; speciesLevelMoves[speciesKey] = [];
for (let version of versions) { for (const version of versions) {
if (pokemon.moves.find(m => m.version_group_details.find(v => v.version_group.name === version && v.move_learn_method.name === 'level-up'))) { if (pokemon.moves.find(m => m.version_group_details.find(v => v.version_group.name === version && v.move_learn_method.name === "level-up"))) {
moveVer = version; moveVer = version;
break; break;
} }
@ -274,23 +283,26 @@ export async function printPokemon() {
if (moveVer) { if (moveVer) {
pokemon.moves.forEach(moveData => { pokemon.moves.forEach(moveData => {
const verData = moveData.version_group_details.find(v => v.version_group.name === moveVer); const verData = moveData.version_group_details.find(v => v.version_group.name === moveVer);
if (!verData) if (!verData) {
return; return;
}
const moveName = moveData.move.name.toUpperCase().replace(/\_/g, '').replace(/\-/g, '_'); const moveName = moveData.move.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_");
const moveId = Math.max(Utils.getEnumKeys(Moves).indexOf(moveName), 0); const moveId = Math.max(Utils.getEnumKeys(Moves).indexOf(moveName), 0);
switch (verData.move_learn_method.name) { switch (verData.move_learn_method.name) {
case 'level-up': case "level-up":
speciesLevelMoves[speciesKey].push([ verData.level_learned_at, moveId ]); speciesLevelMoves[speciesKey].push([ verData.level_learned_at, moveId ]);
break; break;
case 'machine': case "machine":
case 'tutor': case "tutor":
if (moveId > 0) { if (moveId > 0) {
if (!moveTmSpecies.hasOwnProperty(moveId)) if (!moveTmSpecies.hasOwnProperty(moveId)) {
moveTmSpecies[moveId] = []; moveTmSpecies[moveId] = [];
if (moveTmSpecies[moveId].indexOf(speciesKey) === -1) }
if (moveTmSpecies[moveId].indexOf(speciesKey) === -1) {
moveTmSpecies[moveId].push(speciesKey); moveTmSpecies[moveId].push(speciesKey);
}
speciesTmMoves.push(moveId); speciesTmMoves.push(moveId);
} }
break; break;
@ -298,7 +310,7 @@ export async function printPokemon() {
}); });
} }
for (let f of pokemon.forms) { for (const f of pokemon.forms) {
const form = await api.pokemon.getPokemonFormByName(f.name); const form = await api.pokemon.getPokemonFormByName(f.name);
const formIndex = pokemonSpecies.forms.length; const formIndex = pokemonSpecies.forms.length;
@ -307,7 +319,7 @@ export async function printPokemon() {
: null; : null;
const formName = matchingForm const formName = matchingForm
? matchingForm.formName ? matchingForm.formName
: form.form_names.find(fn => fn.language.name === 'en')?.name || form.form_name; : form.form_names.find(fn => fn.language.name === "en")?.name || form.form_name;
const formKey = matchingForm const formKey = matchingForm
? matchingForm.formKey ? matchingForm.formKey
: form.form_name; : form.form_name;
@ -321,7 +333,7 @@ export async function printPokemon() {
pokemonForm.generation = pokemonSpecies.generation; pokemonForm.generation = pokemonSpecies.generation;
if (!pokemonForm.formIndex && speciesTmMoves.length) { if (!pokemonForm.formIndex && speciesTmMoves.length) {
for (let moveId of speciesTmMoves) { for (const moveId of speciesTmMoves) {
const speciesIndex = moveTmSpecies[moveId].findIndex(s => s === speciesKey); const speciesIndex = moveTmSpecies[moveId].findIndex(s => s === speciesKey);
moveTmSpecies[moveId][speciesIndex] = [ moveTmSpecies[moveId][speciesIndex] = [
speciesKey, speciesKey,
@ -336,86 +348,92 @@ export async function printPokemon() {
console.log(pokemonSpecies.name, pokemonSpecies); console.log(pokemonSpecies.name, pokemonSpecies);
} }
for (let pokemonSpecies of pokemonSpeciesList) { for (const pokemonSpecies of pokemonSpeciesList) {
const speciesKey = (pokemonSpecies as any).key as string; const speciesKey = (pokemonSpecies as any).key as string;
enumStr += ` ${speciesKey}${pokemonSpecies.speciesId >= 2000 ? ` = ${pokemonSpecies.speciesId}` : ''},\n`; enumStr += ` ${speciesKey}${pokemonSpecies.speciesId >= 2000 ? ` = ${pokemonSpecies.speciesId}` : ""},\n`;
pokemonSpeciesStr += ` new PokemonSpecies(Species.${speciesKey}, "${pokemonSpecies.name}", ${pokemonSpecies.generation}, ${pokemonSpecies.subLegendary}, ${pokemonSpecies.legendary}, ${pokemonSpecies.mythical}, "${pokemonSpecies.species}", Type.${Type[pokemonSpecies.type1]}, ${pokemonSpecies.type2 ? `Type.${Type[pokemonSpecies.type2]}` : 'null'}, ${pokemonSpecies.height}, ${pokemonSpecies.weight}, Abilities.${Abilities[pokemonSpecies.ability1]}, Abilities.${Abilities[pokemonSpecies.ability2]}, Abilities.${Abilities[pokemonSpecies.abilityHidden]}, ${pokemonSpecies.baseTotal}, ${pokemonSpecies.baseStats[0]}, ${pokemonSpecies.baseStats[1]}, ${pokemonSpecies.baseStats[2]}, ${pokemonSpecies.baseStats[3]}, ${pokemonSpecies.baseStats[4]}, ${pokemonSpecies.baseStats[5]}, ${pokemonSpecies.catchRate}, ${pokemonSpecies.baseFriendship}, ${pokemonSpecies.baseExp}, GrowthRate.${GrowthRate[pokemonSpecies.growthRate]}, ${pokemonSpecies.malePercent}, ${pokemonSpecies.genderDiffs}`; pokemonSpeciesStr += ` new PokemonSpecies(Species.${speciesKey}, "${pokemonSpecies.name}", ${pokemonSpecies.generation}, ${pokemonSpecies.subLegendary}, ${pokemonSpecies.legendary}, ${pokemonSpecies.mythical}, "${pokemonSpecies.species}", Type.${Type[pokemonSpecies.type1]}, ${pokemonSpecies.type2 ? `Type.${Type[pokemonSpecies.type2]}` : "null"}, ${pokemonSpecies.height}, ${pokemonSpecies.weight}, Abilities.${Abilities[pokemonSpecies.ability1]}, Abilities.${Abilities[pokemonSpecies.ability2]}, Abilities.${Abilities[pokemonSpecies.abilityHidden]}, ${pokemonSpecies.baseTotal}, ${pokemonSpecies.baseStats[0]}, ${pokemonSpecies.baseStats[1]}, ${pokemonSpecies.baseStats[2]}, ${pokemonSpecies.baseStats[3]}, ${pokemonSpecies.baseStats[4]}, ${pokemonSpecies.baseStats[5]}, ${pokemonSpecies.catchRate}, ${pokemonSpecies.baseFriendship}, ${pokemonSpecies.baseExp}, GrowthRate.${GrowthRate[pokemonSpecies.growthRate]}, ${pokemonSpecies.malePercent}, ${pokemonSpecies.genderDiffs}`;
if (pokemonSpecies.forms.length > 1) { if (pokemonSpecies.forms.length > 1) {
pokemonSpeciesStr += `, ${pokemonSpecies.canChangeForm},`; pokemonSpeciesStr += `, ${pokemonSpecies.canChangeForm},`;
for (let form of pokemonSpecies.forms) for (const form of pokemonSpecies.forms) {
pokemonSpeciesStr += `\n new PokemonForm("${form.formName}", "${form.formName}", Type.${Type[form.type1]}, ${form.type2 ? `Type.${Type[form.type2]}` : 'null'}, ${form.height}, ${form.weight}, Abilities.${Abilities[form.ability1]}, Abilities.${Abilities[form.ability2]}, Abilities.${Abilities[form.abilityHidden]}, ${form.baseTotal}, ${form.baseStats[0]}, ${form.baseStats[1]}, ${form.baseStats[2]}, ${form.baseStats[3]}, ${form.baseStats[4]}, ${form.baseStats[5]}, ${form.catchRate}, ${form.baseFriendship}, ${form.baseExp}${form.genderDiffs ? ', true' : ''}),`; pokemonSpeciesStr += `\n new PokemonForm("${form.formName}", "${form.formName}", Type.${Type[form.type1]}, ${form.type2 ? `Type.${Type[form.type2]}` : "null"}, ${form.height}, ${form.weight}, Abilities.${Abilities[form.ability1]}, Abilities.${Abilities[form.ability2]}, Abilities.${Abilities[form.abilityHidden]}, ${form.baseTotal}, ${form.baseStats[0]}, ${form.baseStats[1]}, ${form.baseStats[2]}, ${form.baseStats[3]}, ${form.baseStats[4]}, ${form.baseStats[5]}, ${form.catchRate}, ${form.baseFriendship}, ${form.baseExp}${form.genderDiffs ? ", true" : ""}),`;
pokemonSpeciesStr += '\n ';
} }
pokemonSpeciesStr += `),\n`; pokemonSpeciesStr += "\n ";
}
pokemonSpeciesStr += "),\n";
} }
let speciesLevelMovesStr = `export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {\n`; let speciesLevelMovesStr = "export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {\n";
let speciesFormLevelMovesStr = `export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {\n`; let speciesFormLevelMovesStr = "export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {\n";
let tmSpeciesStr = `export const tmSpecies: TmSpecies = {\n`; let tmSpeciesStr = "export const tmSpecies: TmSpecies = {\n";
for (let species of Object.keys(speciesLevelMoves)) { for (const species of Object.keys(speciesLevelMoves)) {
speciesLevelMovesStr += ` [Species.${species}]: [\n`; speciesLevelMovesStr += ` [Species.${species}]: [\n`;
const orderedLevelMoves = speciesLevelMoves[species].sort((a: LevelMove, b: LevelMove) => { const orderedLevelMoves = speciesLevelMoves[species].sort((a: LevelMove, b: LevelMove) => {
if (a[0] !== b[0]) if (a[0] !== b[0]) {
return a[0] < b[0] ? -1 : 1; return a[0] < b[0] ? -1 : 1;
}
return a[1] < b[1] ? -1 : 1; return a[1] < b[1] ? -1 : 1;
}); });
for (let lm of orderedLevelMoves) for (const lm of orderedLevelMoves) {
speciesLevelMovesStr += ` [ ${lm[0]}, Moves.${Moves[lm[1]]} ],\n`; speciesLevelMovesStr += ` [ ${lm[0]}, Moves.${Moves[lm[1]]} ],\n`;
speciesLevelMovesStr += ` ],\n`;
} }
for (let species of Object.keys(speciesFormLevelMoves)) { speciesLevelMovesStr += " ],\n";
}
for (const species of Object.keys(speciesFormLevelMoves)) {
speciesFormLevelMovesStr += ` [Species.${species}]: {\n`; speciesFormLevelMovesStr += ` [Species.${species}]: {\n`;
for (let f of Object.keys(speciesFormLevelMoves[species])) { for (const f of Object.keys(speciesFormLevelMoves[species])) {
speciesFormLevelMovesStr += ` ${f}: [\n`; speciesFormLevelMovesStr += ` ${f}: [\n`;
const orderedLevelMoves = speciesFormLevelMoves[species][f].sort((a: LevelMove, b: LevelMove) => { const orderedLevelMoves = speciesFormLevelMoves[species][f].sort((a: LevelMove, b: LevelMove) => {
if (a[0] !== b[0]) if (a[0] !== b[0]) {
return a[0] < b[0] ? -1 : 1; return a[0] < b[0] ? -1 : 1;
}
return a[1] < b[1] ? -1 : 1; return a[1] < b[1] ? -1 : 1;
}); });
for (let lm of orderedLevelMoves) for (const lm of orderedLevelMoves) {
speciesFormLevelMovesStr += ` [ ${lm[0]}, Moves.${Moves[lm[1]]} ],\n`; speciesFormLevelMovesStr += ` [ ${lm[0]}, Moves.${Moves[lm[1]]} ],\n`;
speciesFormLevelMovesStr += ` ],\n`;
} }
speciesFormLevelMovesStr += ` },\n`; speciesFormLevelMovesStr += " ],\n";
} }
for (let moveId of Object.keys(moveTmSpecies)) { speciesFormLevelMovesStr += " },\n";
}
for (const moveId of Object.keys(moveTmSpecies)) {
tmSpeciesStr += ` [Moves.${Moves[parseInt(moveId)]}]: [\n`; tmSpeciesStr += ` [Moves.${Moves[parseInt(moveId)]}]: [\n`;
for (let species of moveTmSpecies[moveId]) { for (const species of moveTmSpecies[moveId]) {
if (typeof species === 'string') if (typeof species === "string") {
tmSpeciesStr += ` Species.${species},\n`; tmSpeciesStr += ` Species.${species},\n`;
else { } else {
const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === species[0]); const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === species[0]);
const forms = (species as string[]).slice(1); const forms = (species as string[]).slice(1);
if (matchingExistingSpecies && (!pokemonFormLevelMoves.hasOwnProperty(matchingExistingSpecies.speciesId) || matchingExistingSpecies.forms.length <= 1 || (matchingExistingSpecies.forms.length === 2 && matchingExistingSpecies.forms[1].formKey.indexOf(SpeciesFormKey.MEGA) > -1) || matchingExistingSpecies.forms.length === forms.length)) if (matchingExistingSpecies && (!pokemonFormLevelMoves.hasOwnProperty(matchingExistingSpecies.speciesId) || matchingExistingSpecies.forms.length <= 1 || (matchingExistingSpecies.forms.length === 2 && matchingExistingSpecies.forms[1].formKey.indexOf(SpeciesFormKey.MEGA) > -1) || matchingExistingSpecies.forms.length === forms.length)) {
tmSpeciesStr += ` Species.${species[0]},\n`; tmSpeciesStr += ` Species.${species[0]},\n`;
else { } else {
tmSpeciesStr += ` [\n Species.${species[0]},\n`; tmSpeciesStr += ` [\n Species.${species[0]},\n`;
for (let form of forms) for (const form of forms) {
tmSpeciesStr += ` '${form}',\n`; tmSpeciesStr += ` '${form}',\n`;
tmSpeciesStr += ` ],\n`; }
tmSpeciesStr += " ],\n";
} }
} }
} }
tmSpeciesStr += ` ],\n`; tmSpeciesStr += " ],\n";
} }
enumStr += `\n};`; enumStr += "\n};";
pokemonSpeciesStr += ` );`; pokemonSpeciesStr += " );";
speciesLevelMovesStr += `\n};`; speciesLevelMovesStr += "\n};";
speciesFormLevelMovesStr += `\n};`; speciesFormLevelMovesStr += "\n};";
tmSpeciesStr += `\n};`; tmSpeciesStr += "\n};";
console.log(enumStr); console.log(enumStr);
console.log(pokemonSpeciesStr); console.log(pokemonSpeciesStr);
@ -423,39 +441,40 @@ export async function printPokemon() {
console.log(speciesFormLevelMovesStr); console.log(speciesFormLevelMovesStr);
console.log(tmSpeciesStr); console.log(tmSpeciesStr);
console.log(moveTmSpecies) console.log(moveTmSpecies);
} }
export async function printAbilities() { export async function printAbilities() {
const replaceText = true; const replaceText = true;
let abilityContent: string = await fs.readFile('./src/data/ability.ts'); let abilityContent: string = await fs.readFile("./src/data/ability.ts");
const api = new MainClient(); const api = new MainClient();
let enumStr = `export enum Abilities {\n NONE,`; let enumStr = "export enum Abilities {\n NONE,";
let abilityStr = ' allAbilities.push('; let abilityStr = " allAbilities.push(";
abilityContent = abilityContent.slice(abilityContent.indexOf(abilityStr)); abilityContent = abilityContent.slice(abilityContent.indexOf(abilityStr));
let abilities: NamedAPIResource[] = []; let abilities: NamedAPIResource[] = [];
let offset = 0; const offset = 0;
let abilitiesResponse = await api.pokemon.listAbilities(offset, 2000); const abilitiesResponse = await api.pokemon.listAbilities(offset, 2000);
abilities = abilitiesResponse.results; abilities = abilitiesResponse.results;
for (let a of abilities) { for (const a of abilities) {
const ability = await api.pokemon.getAbilityByName(a.name); const ability = await api.pokemon.getAbilityByName(a.name);
const abilityEnumName = ability.name.toUpperCase().replace(/\_/g, '').replace(/\-/g, '_'); const abilityEnumName = ability.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_");
enumStr += `\n ${abilityEnumName},`; enumStr += `\n ${abilityEnumName},`;
console.log(ability.name, ability); console.log(ability.name, ability);
const matchingLineIndex = abilityContent.search(new RegExp(`new Ability\\\(Abilities.${abilityEnumName},`)); const matchingLineIndex = abilityContent.search(new RegExp(`new Ability\\\(Abilities.${abilityEnumName},`));
let matchingLine = matchingLineIndex > -1 ? abilityContent.slice(matchingLineIndex) : null; let matchingLine = matchingLineIndex > -1 ? abilityContent.slice(matchingLineIndex) : null;
if (matchingLine) if (matchingLine) {
matchingLine = matchingLine.slice(0, matchingLine.search(/,(?: \/\/.*?)?(?:\r)?\n[ \t]+(?:new|\);)/)); matchingLine = matchingLine.slice(0, matchingLine.search(/,(?: \/\/.*?)?(?:\r)?\n[ \t]+(?:new|\);)/));
}
let abilityName = ability.names.find(ln => ln.language.name === 'en').name; let abilityName = ability.names.find(ln => ln.language.name === "en").name;
[ 'N', 'P' ].every(s => { [ "N", "P" ].every(s => {
if (!matchingLine || matchingLine.indexOf(` (${s})`) > -1) { if (!matchingLine || matchingLine.indexOf(` (${s})`) > -1) {
abilityName += ` (${s})`; abilityName += ` (${s})`;
return false; return false;
@ -465,26 +484,29 @@ export async function printAbilities() {
let flavorText: string; let flavorText: string;
if (!matchingLine || replaceText) { if (!matchingLine || replaceText) {
for (let version of versions) { for (const version of versions) {
if ((flavorText = ability.flavor_text_entries.find(fte => fte.language.name === 'en' && fte.version_group.name === version)?.flavor_text) || '') { if ((flavorText = ability.flavor_text_entries.find(fte => fte.language.name === "en" && fte.version_group.name === version)?.flavor_text) || "") {
if (flavorText.indexOf('forgotten') > -1) if (flavorText.indexOf("forgotten") > -1) {
continue; continue;
}
break; break;
} }
} }
} else if (matchingLine) } else if (matchingLine) {
flavorText = allAbilities[ability.id].description; flavorText = allAbilities[ability.id].description;
abilityStr += `\n new Ability(Abilities.${abilityEnumName}, "${abilityName}", "${flavorText?.replace(/\n/g, '\\n').replace(/ /g, ' ').replace(//g, '\'') || ''}", ${generationMap[ability.generation.name]})`; }
abilityStr += `\n new Ability(Abilities.${abilityEnumName}, "${abilityName}", "${flavorText?.replace(/\n/g, "\\n").replace(/ /g, " ").replace(//g, "'") || ""}", ${generationMap[ability.generation.name]})`;
if (matchingLine && matchingLine.length > 1) { if (matchingLine && matchingLine.length > 1) {
const newLineIndex = matchingLine.indexOf('\n'); const newLineIndex = matchingLine.indexOf("\n");
if (newLineIndex > -1) if (newLineIndex > -1) {
abilityStr += matchingLine.slice(newLineIndex); abilityStr += matchingLine.slice(newLineIndex);
} }
abilityStr += ','; }
abilityStr += ",";
} }
enumStr += `\n};`; enumStr += "\n};";
abilityStr += `\n);`; abilityStr += "\n);";
console.log(enumStr); console.log(enumStr);
console.log(abilityStr); console.log(abilityStr);
@ -493,35 +515,36 @@ export async function printAbilities() {
export async function printMoves() { export async function printMoves() {
const replaceText = true; const replaceText = true;
let moveContent: string = await fs.readFile('./src/data/move.ts'); let moveContent: string = await fs.readFile("./src/data/move.ts");
const api = new MainClient(); const api = new MainClient();
let enumStr = `export enum Moves {\n NONE,`; let enumStr = "export enum Moves {\n NONE,";
let moveStr = ' allMoves.push('; let moveStr = " allMoves.push(";
moveContent = moveContent.slice(moveContent.indexOf(moveStr)); moveContent = moveContent.slice(moveContent.indexOf(moveStr));
let moves: NamedAPIResource[] = []; let moves: NamedAPIResource[] = [];
let offset = 0; const offset = 0;
let movesResponse = await api.move.listMoves(offset, 2000); const movesResponse = await api.move.listMoves(offset, 2000);
moves = movesResponse.results; moves = movesResponse.results;
console.log(moves); console.log(moves);
for (let m of moves) { for (const m of moves) {
const move = await api.move.getMoveByName(m.name); const move = await api.move.getMoveByName(m.name);
const moveEnumName = move.name.toUpperCase().replace(/\_/g, '').replace(/\-/g, '_'); const moveEnumName = move.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_");
enumStr += `\n ${moveEnumName},`; enumStr += `\n ${moveEnumName},`;
console.log(move.name, move); console.log(move.name, move);
const matchingLineIndex = moveContent.search(new RegExp(`new (?:Attack|(?:Self)?Status)Move\\\(Moves.${Moves[move.id]},`)); const matchingLineIndex = moveContent.search(new RegExp(`new (?:Attack|(?:Self)?Status)Move\\\(Moves.${Moves[move.id]},`));
let matchingLine = matchingLineIndex > -1 ? moveContent.slice(matchingLineIndex) : null; let matchingLine = matchingLineIndex > -1 ? moveContent.slice(matchingLineIndex) : null;
if (matchingLine) if (matchingLine) {
matchingLine = matchingLine.slice(0, matchingLine.search(/,(?: \/\/.*?)?(?:\r)?\n[ \t]+(?:new|\);)/)); matchingLine = matchingLine.slice(0, matchingLine.search(/,(?: \/\/.*?)?(?:\r)?\n[ \t]+(?:new|\);)/));
}
let moveName = move.names.find(ln => ln.language.name === 'en').name; let moveName = move.names.find(ln => ln.language.name === "en").name;
[ 'N', 'P' ].every(s => { [ "N", "P" ].every(s => {
if (!matchingLine || matchingLine.indexOf(` (${s})`) > -1) { if (!matchingLine || matchingLine.indexOf(` (${s})`) > -1) {
moveName += ` (${s})`; moveName += ` (${s})`;
return false; return false;
@ -531,32 +554,35 @@ export async function printMoves() {
let flavorText: string; let flavorText: string;
if (!matchingLine || replaceText) { if (!matchingLine || replaceText) {
for (let version of versions) { for (const version of versions) {
if ((flavorText = move.flavor_text_entries.find(fte => fte.language.name === 'en' && fte.version_group.name === version)?.flavor_text) || '') { if ((flavorText = move.flavor_text_entries.find(fte => fte.language.name === "en" && fte.version_group.name === version)?.flavor_text) || "") {
if (flavorText.indexOf('forgotten') > -1) if (flavorText.indexOf("forgotten") > -1) {
continue; continue;
}
break; break;
} }
} }
} else if (matchingLine) } else if (matchingLine) {
flavorText = allMoves[move.id].effect; flavorText = allMoves[move.id].effect;
}
const moveTarget = targetMap[move.target.name]; const moveTarget = targetMap[move.target.name];
moveStr += `\n new ${move.damage_class.name !== 'status' ? 'Attack' : (moveTarget === MoveTarget.USER ? 'Self' : '') + 'Status'}Move(Moves.${moveEnumName}, "${moveName}", Type.${move.type.name.toUpperCase()}${move.damage_class.name !== 'status' ? `, MoveCategory.${move.damage_class.name.toUpperCase()}` : ''}${move.damage_class.name !== 'status' ? `, ${move.power || -1}` : ''}, ${move.accuracy || -1}, ${move.pp}, "${flavorText?.replace(/\n/g, '\\n').replace(/ /g, ' ').replace(//g, '\'') || ''}", ${move.effect_chance || -1}, ${move.priority}, ${generationMap[move.generation.name]})`; moveStr += `\n new ${move.damage_class.name !== "status" ? "Attack" : (moveTarget === MoveTarget.USER ? "Self" : "") + "Status"}Move(Moves.${moveEnumName}, "${moveName}", Type.${move.type.name.toUpperCase()}${move.damage_class.name !== "status" ? `, MoveCategory.${move.damage_class.name.toUpperCase()}` : ""}${move.damage_class.name !== "status" ? `, ${move.power || -1}` : ""}, ${move.accuracy || -1}, ${move.pp}, "${flavorText?.replace(/\n/g, "\\n").replace(/ /g, " ").replace(//g, "'") || ""}", ${move.effect_chance || -1}, ${move.priority}, ${generationMap[move.generation.name]})`;
const expectedTarget = move.damage_class.name !== 'status' || moveTarget !== MoveTarget.USER ? MoveTarget.NEAR_OTHER : MoveTarget.USER; const expectedTarget = move.damage_class.name !== "status" || moveTarget !== MoveTarget.USER ? MoveTarget.NEAR_OTHER : MoveTarget.USER;
if (matchingLine && matchingLine.length > 1) { if (matchingLine && matchingLine.length > 1) {
const newLineIndex = matchingLine.indexOf('\n'); const newLineIndex = matchingLine.indexOf("\n");
if (newLineIndex > -1) { if (newLineIndex > -1) {
console.log(matchingLine.slice(newLineIndex).replace(/(?:\r)?\n[ \t]+.target\(.*?\)/g, ''), newLineIndex) console.log(matchingLine.slice(newLineIndex).replace(/(?:\r)?\n[ \t]+.target\(.*?\)/g, ""), newLineIndex);
moveStr += matchingLine.slice(newLineIndex).replace(/(?:\r)?\n[ \t]+.target\(.*?\)/g, ''); moveStr += matchingLine.slice(newLineIndex).replace(/(?:\r)?\n[ \t]+.target\(.*?\)/g, "");
} }
} }
if (moveTarget !== expectedTarget) if (moveTarget !== expectedTarget) {
moveStr += `\n .target(MoveTarget.${MoveTarget[moveTarget]})`; moveStr += `\n .target(MoveTarget.${MoveTarget[moveTarget]})`;
moveStr += ','; }
moveStr += ",";
} }
enumStr += `\n};`; enumStr += "\n};";
moveStr += `\n);`; moveStr += "\n);";
console.log(enumStr); console.log(enumStr);
console.log(moveStr); console.log(moveStr);
@ -569,31 +595,33 @@ export async function printTmSpecies() {
const moveIds = Object.keys(tmSpecies).map(k => parseInt(k) as Moves); const moveIds = Object.keys(tmSpecies).map(k => parseInt(k) as Moves);
for (let moveId of moveIds) { for (const moveId of moveIds) {
const move = await api.move.getMoveById(moveId); const move = await api.move.getMoveById(moveId);
moveTmSpecies[moveId] = []; moveTmSpecies[moveId] = [];
for (let species of move.learned_by_pokemon) { for (const species of move.learned_by_pokemon) {
const dexIdMatch = /\/(\d+)\//.exec(species.url); const dexIdMatch = /\/(\d+)\//.exec(species.url);
if (!dexIdMatch) if (!dexIdMatch) {
continue; continue;
}
let dexId = parseInt(dexIdMatch[1]); const dexId = parseInt(dexIdMatch[1]);
let matchingSpecies: PokemonSpecies; let matchingSpecies: PokemonSpecies;
let formKey = ''; let formKey = "";
console.log(species.name); console.log(species.name);
if (dexId < 10000) if (dexId < 10000) {
matchingSpecies = allSpecies[dexId - 1]; matchingSpecies = allSpecies[dexId - 1];
else { } else {
const pokemon = await api.pokemon.getPokemonById(dexId); const pokemon = await api.pokemon.getPokemonById(dexId);
const speciesDexIdMatch = /\/(\d+)\//.exec(pokemon.species.url); const speciesDexIdMatch = /\/(\d+)\//.exec(pokemon.species.url);
if (!speciesDexIdMatch) if (!speciesDexIdMatch) {
continue; continue;
}
const speciesDexId = parseInt(speciesDexIdMatch[1]); const speciesDexId = parseInt(speciesDexIdMatch[1]);
@ -606,12 +634,13 @@ export async function printTmSpecies() {
if (regionKey) { if (regionKey) {
formKey = formKey.slice(regionKey.length + 1); formKey = formKey.slice(regionKey.length + 1);
matchingSpecies = allSpecies.find(s => Species[s.speciesId] === `${regionKey.toUpperCase()}_${speciesKey}`); matchingSpecies = allSpecies.find(s => Species[s.speciesId] === `${regionKey.toUpperCase()}_${speciesKey}`);
} else } else {
matchingSpecies = allSpecies[speciesDexId - 1]; matchingSpecies = allSpecies[speciesDexId - 1];
} }
}
if (!matchingSpecies) { if (!matchingSpecies) {
console.log('NO MATCH', species.name); console.log("NO MATCH", species.name);
continue; continue;
} }
@ -619,40 +648,42 @@ export async function printTmSpecies() {
const matchingIndex = moveTmSpecies[moveId].findIndex(s => Array.isArray(s) ? s[0] === speciesKey : s === speciesKey); const matchingIndex = moveTmSpecies[moveId].findIndex(s => Array.isArray(s) ? s[0] === speciesKey : s === speciesKey);
if (matchingIndex === -1) if (matchingIndex === -1) {
moveTmSpecies[moveId].push(!formKey ? speciesKey : [ speciesKey, formKey ]); moveTmSpecies[moveId].push(!formKey ? speciesKey : [ speciesKey, formKey ]);
else { } else {
if (!Array.isArray(moveTmSpecies[moveId][matchingIndex])) if (!Array.isArray(moveTmSpecies[moveId][matchingIndex])) {
moveTmSpecies[moveId][matchingIndex] = [ moveTmSpecies[moveId][matchingIndex] as string, '' ]; moveTmSpecies[moveId][matchingIndex] = [ moveTmSpecies[moveId][matchingIndex] as string, "" ];
}
(moveTmSpecies[moveId][matchingIndex] as string[]).push(formKey); (moveTmSpecies[moveId][matchingIndex] as string[]).push(formKey);
} }
} }
} }
let tmSpeciesStr = `export const tmSpecies: TmSpecies = {\n`; let tmSpeciesStr = "export const tmSpecies: TmSpecies = {\n";
for (let moveId of Object.keys(moveTmSpecies)) { for (const moveId of Object.keys(moveTmSpecies)) {
tmSpeciesStr += ` [Moves.${Moves[parseInt(moveId)]}]: [\n`; tmSpeciesStr += ` [Moves.${Moves[parseInt(moveId)]}]: [\n`;
for (let species of moveTmSpecies[moveId]) { for (const species of moveTmSpecies[moveId]) {
if (typeof species === 'string') if (typeof species === "string") {
tmSpeciesStr += ` Species.${species},\n`; tmSpeciesStr += ` Species.${species},\n`;
else { } else {
const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === species[0]); const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === species[0]);
const forms = (species as string[]).slice(1); const forms = (species as string[]).slice(1);
if (matchingExistingSpecies && (!pokemonFormLevelMoves.hasOwnProperty(matchingExistingSpecies.speciesId) || matchingExistingSpecies.forms.length <= 1 || (matchingExistingSpecies.forms.length === 2 && matchingExistingSpecies.forms[1].formKey.indexOf(SpeciesFormKey.MEGA) > -1) || matchingExistingSpecies.forms.length === forms.length)) if (matchingExistingSpecies && (!pokemonFormLevelMoves.hasOwnProperty(matchingExistingSpecies.speciesId) || matchingExistingSpecies.forms.length <= 1 || (matchingExistingSpecies.forms.length === 2 && matchingExistingSpecies.forms[1].formKey.indexOf(SpeciesFormKey.MEGA) > -1) || matchingExistingSpecies.forms.length === forms.length)) {
tmSpeciesStr += ` Species.${species[0]},\n`; tmSpeciesStr += ` Species.${species[0]},\n`;
else { } else {
tmSpeciesStr += ` [\n Species.${species[0]},\n`; tmSpeciesStr += ` [\n Species.${species[0]},\n`;
for (let form of forms) for (const form of forms) {
tmSpeciesStr += ` '${form}',\n`; tmSpeciesStr += ` '${form}',\n`;
tmSpeciesStr += ` ],\n`; }
tmSpeciesStr += " ],\n";
} }
} }
} }
tmSpeciesStr += ` ],\n`; tmSpeciesStr += " ],\n";
} }
tmSpeciesStr += `\n};`; tmSpeciesStr += "\n};";
console.log(tmSpeciesStr); console.log(tmSpeciesStr);
} }

View File

@ -40,7 +40,7 @@ export abstract class ArenaTag {
onAdd(arena: Arena): void { } onAdd(arena: Arena): void { }
onRemove(arena: Arena): void { onRemove(arena: Arena): void {
arena.scene.queueMessage(`${this.getMoveName()}\'s effect wore off${this.side === ArenaTagSide.PLAYER ? '\non your side' : this.side === ArenaTagSide.ENEMY ? '\non the foe\'s side' : ''}.`); arena.scene.queueMessage(`${this.getMoveName()}\'s effect wore off${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`);
} }
onOverlap(arena: Arena): void { } onOverlap(arena: Arena): void { }
@ -65,13 +65,13 @@ export class MistTag extends ArenaTag {
super.onAdd(arena); super.onAdd(arena);
const source = arena.scene.getPokemonById(this.sourceId); const source = arena.scene.getPokemonById(this.sourceId);
arena.scene.queueMessage(getPokemonMessage(source, `'s team became\nshrouded in mist!`)); arena.scene.queueMessage(getPokemonMessage(source, "'s team became\nshrouded in mist!"));
} }
apply(arena: Arena, args: any[]): boolean { apply(arena: Arena, args: any[]): boolean {
(args[0] as Utils.BooleanHolder).value = true; (args[0] as Utils.BooleanHolder).value = true;
arena.scene.queueMessage('The mist prevented\nthe lowering of stats!'); arena.scene.queueMessage("The mist prevented\nthe lowering of stats!");
return true; return true;
} }
@ -110,7 +110,7 @@ class ReflectTag extends WeakenMoveScreenTag {
} }
onAdd(arena: Arena): void { onAdd(arena: Arena): void {
arena.scene.queueMessage(`Reflect reduced the damage of physical moves${this.side === ArenaTagSide.PLAYER ? '\non your side' : this.side === ArenaTagSide.ENEMY ? '\non the foe\'s side' : ''}.`); arena.scene.queueMessage(`Reflect reduced the damage of physical moves${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`);
} }
} }
@ -132,7 +132,7 @@ class LightScreenTag extends WeakenMoveScreenTag {
} }
onAdd(arena: Arena): void { onAdd(arena: Arena): void {
arena.scene.queueMessage(`Light Screen reduced the damage of special moves${this.side === ArenaTagSide.PLAYER ? '\non your side' : this.side === ArenaTagSide.ENEMY ? '\non the foe\'s side' : ''}.`); arena.scene.queueMessage(`Light Screen reduced the damage of special moves${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`);
} }
} }
@ -142,7 +142,7 @@ class AuroraVeilTag extends WeakenMoveScreenTag {
} }
onAdd(arena: Arena): void { onAdd(arena: Arena): void {
arena.scene.queueMessage(`Aurora Veil reduced the damage of moves${this.side === ArenaTagSide.PLAYER ? '\non your side' : this.side === ArenaTagSide.ENEMY ? '\non the foe\'s side' : ''}.`); arena.scene.queueMessage(`Aurora Veil reduced the damage of moves${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`);
} }
} }
@ -158,7 +158,7 @@ class WishTag extends ArenaTag {
onAdd(arena: Arena): void { onAdd(arena: Arena): void {
const user = arena.scene.getPokemonById(this.sourceId); const user = arena.scene.getPokemonById(this.sourceId);
this.battlerIndex = user.getBattlerIndex(); this.battlerIndex = user.getBattlerIndex();
this.triggerMessage = getPokemonMessage(user, '\'s wish\ncame true!'); this.triggerMessage = getPokemonMessage(user, "'s wish\ncame true!");
this.healHp = Math.max(Math.floor(user.getMaxHp() / 2), 1); this.healHp = Math.max(Math.floor(user.getMaxHp() / 2), 1);
} }
@ -196,11 +196,11 @@ class MudSportTag extends WeakenMoveTypeTag {
} }
onAdd(arena: Arena): void { onAdd(arena: Arena): void {
arena.scene.queueMessage('Electricity\'s power was weakened!'); arena.scene.queueMessage("Electricity's power was weakened!");
} }
onRemove(arena: Arena): void { onRemove(arena: Arena): void {
arena.scene.queueMessage('The effects of Mud Sport\nhave faded.'); arena.scene.queueMessage("The effects of Mud Sport\nhave faded.");
} }
} }
@ -210,11 +210,11 @@ class WaterSportTag extends WeakenMoveTypeTag {
} }
onAdd(arena: Arena): void { onAdd(arena: Arena): void {
arena.scene.queueMessage('Fire\'s power was weakened!'); arena.scene.queueMessage("Fire's power was weakened!");
} }
onRemove(arena: Arena): void { onRemove(arena: Arena): void {
arena.scene.queueMessage('The effects of Water Sport\nhave faded.'); arena.scene.queueMessage("The effects of Water Sport\nhave faded.");
} }
} }
@ -239,8 +239,9 @@ export class ArenaTrapTag extends ArenaTag {
apply(arena: Arena, args: any[]): boolean { apply(arena: Arena, args: any[]): boolean {
const pokemon = args[0] as Pokemon; const pokemon = args[0] as Pokemon;
if (this.sourceId === pokemon.id || (this.side === ArenaTagSide.PLAYER) !== pokemon.isPlayer()) if (this.sourceId === pokemon.id || (this.side === ArenaTagSide.PLAYER) !== pokemon.isPlayer()) {
return false; return false;
}
return this.activateTrap(pokemon); return this.activateTrap(pokemon);
} }
@ -275,9 +276,11 @@ class SpikesTag extends ArenaTrapTag {
const damageHpRatio = 1 / (10 - 2 * this.layers); const damageHpRatio = 1 / (10 - 2 * this.layers);
const damage = Math.ceil(pokemon.getMaxHp() * damageHpRatio); const damage = Math.ceil(pokemon.getMaxHp() * damageHpRatio);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is hurt\nby the spikes!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is hurt\nby the spikes!"));
pokemon.damageAndUpdate(damage, HitResult.OTHER); pokemon.damageAndUpdate(damage, HitResult.OTHER);
if (pokemon.turnData) pokemon.turnData.damageTaken += damage; if (pokemon.turnData) {
pokemon.turnData.damageTaken += damage;
}
return true; return true;
} }
} }
@ -302,9 +305,10 @@ class ToxicSpikesTag extends ArenaTrapTag {
} }
onRemove(arena: Arena): void { onRemove(arena: Arena): void {
if (!this.neutralized) if (!this.neutralized) {
super.onRemove(arena); super.onRemove(arena);
} }
}
activateTrap(pokemon: Pokemon): boolean { activateTrap(pokemon: Pokemon): boolean {
if (pokemon.isGrounded()) { if (pokemon.isGrounded()) {
@ -316,19 +320,22 @@ class ToxicSpikesTag extends ArenaTrapTag {
} }
} else if (!pokemon.status) { } else if (!pokemon.status) {
const toxic = this.layers > 1; const toxic = this.layers > 1;
if (pokemon.trySetStatus(!toxic ? StatusEffect.POISON : StatusEffect.TOXIC, true, null, 0, `the ${this.getMoveName()}`)) if (pokemon.trySetStatus(!toxic ? StatusEffect.POISON : StatusEffect.TOXIC, true, null, 0, `the ${this.getMoveName()}`)) {
return true; return true;
} }
} }
}
return false; return false;
} }
getMatchupScoreMultiplier(pokemon: Pokemon): number { getMatchupScoreMultiplier(pokemon: Pokemon): number {
if (pokemon.isGrounded() || !pokemon.canSetStatus(StatusEffect.POISON, true)) if (pokemon.isGrounded() || !pokemon.canSetStatus(StatusEffect.POISON, true)) {
return 1; return 1;
if (pokemon.isOfType(Type.POISON)) }
if (pokemon.isOfType(Type.POISON)) {
return 1.25; return 1.25;
}
return super.getMatchupScoreMultiplier(pokemon); return super.getMatchupScoreMultiplier(pokemon);
} }
} }
@ -345,8 +352,9 @@ class DelayedAttackTag extends ArenaTag {
lapse(arena: Arena): boolean { lapse(arena: Arena): boolean {
const ret = super.lapse(arena); const ret = super.lapse(arena);
if (!ret) if (!ret) {
arena.scene.unshiftPhase(new MoveEffectPhase(arena.scene, this.sourceId, [ this.targetIndex ], new PokemonMove(this.sourceMove, 0, 0, true))); arena.scene.unshiftPhase(new MoveEffectPhase(arena.scene, this.sourceId, [ this.targetIndex ], new PokemonMove(this.sourceMove, 0, 0, true)));
}
return ret; return ret;
} }
@ -399,8 +407,9 @@ class StealthRockTag extends ArenaTrapTag {
const cancelled = new Utils.BooleanHolder(false); const cancelled = new Utils.BooleanHolder(false);
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
if (cancelled.value) if (cancelled.value) {
return false; return false;
}
const damageHpRatio = this.getDamageHpRatio(pokemon); const damageHpRatio = this.getDamageHpRatio(pokemon);
@ -408,7 +417,9 @@ class StealthRockTag extends ArenaTrapTag {
const damage = Math.ceil(pokemon.getMaxHp() * damageHpRatio); const damage = Math.ceil(pokemon.getMaxHp() * damageHpRatio);
pokemon.scene.queueMessage(`Pointed stones dug into\n${pokemon.name}!`); pokemon.scene.queueMessage(`Pointed stones dug into\n${pokemon.name}!`);
pokemon.damageAndUpdate(damage, HitResult.OTHER); pokemon.damageAndUpdate(damage, HitResult.OTHER);
if (pokemon.turnData) pokemon.turnData.damageTaken += damage; if (pokemon.turnData) {
pokemon.turnData.damageTaken += damage;
}
} }
return false; return false;
@ -428,6 +439,8 @@ class StickyWebTag extends ArenaTrapTag {
onAdd(arena: Arena): void { onAdd(arena: Arena): void {
super.onAdd(arena); super.onAdd(arena);
// does not seem to be used anywhere
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const source = arena.scene.getPokemonById(this.sourceId); const source = arena.scene.getPokemonById(this.sourceId);
arena.scene.queueMessage(`A ${this.getMoveName()} has been laid out on the ground around the opposing team!`); arena.scene.queueMessage(`A ${this.getMoveName()} has been laid out on the ground around the opposing team!`);
} }
@ -460,11 +473,11 @@ export class TrickRoomTag extends ArenaTag {
} }
onAdd(arena: Arena): void { onAdd(arena: Arena): void {
arena.scene.queueMessage(getPokemonMessage(arena.scene.getPokemonById(this.sourceId), ' twisted\nthe dimensions!')); arena.scene.queueMessage(getPokemonMessage(arena.scene.getPokemonById(this.sourceId), " twisted\nthe dimensions!"));
} }
onRemove(arena: Arena): void { onRemove(arena: Arena): void {
arena.scene.queueMessage('The twisted dimensions\nreturned to normal!'); arena.scene.queueMessage("The twisted dimensions\nreturned to normal!");
} }
} }
@ -474,11 +487,11 @@ export class GravityTag extends ArenaTag {
} }
onAdd(arena: Arena): void { onAdd(arena: Arena): void {
arena.scene.queueMessage('Gravity intensified!'); arena.scene.queueMessage("Gravity intensified!");
} }
onRemove(arena: Arena): void { onRemove(arena: Arena): void {
arena.scene.queueMessage('Gravity returned to normal!'); arena.scene.queueMessage("Gravity returned to normal!");
} }
} }
@ -488,11 +501,11 @@ class TailwindTag extends ArenaTag {
} }
onAdd(arena: Arena): void { onAdd(arena: Arena): void {
arena.scene.queueMessage(`The Tailwind blew from behind${this.side === ArenaTagSide.PLAYER ? '\nyour' : this.side === ArenaTagSide.ENEMY ? '\nthe opposing' : ''} team!`); arena.scene.queueMessage(`The Tailwind blew from behind${this.side === ArenaTagSide.PLAYER ? "\nyour" : this.side === ArenaTagSide.ENEMY ? "\nthe opposing" : ""} team!`);
} }
onRemove(arena: Arena): void { onRemove(arena: Arena): void {
arena.scene.queueMessage(`${this.side === ArenaTagSide.PLAYER ? 'Your' : this.side === ArenaTagSide.ENEMY ? 'The opposing' : ''} team's Tailwind petered out!`); arena.scene.queueMessage(`${this.side === ArenaTagSide.PLAYER ? "Your" : this.side === ArenaTagSide.ENEMY ? "The opposing" : ""} team's Tailwind petered out!`);
} }
} }

View File

@ -4,9 +4,8 @@ import { AttackMove, ChargeAttr, DelayedAttackAttr, MoveFlags, SelfStatusMove, a
import Pokemon from "../field/pokemon"; import Pokemon from "../field/pokemon";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { BattlerIndex } from "../battle"; import { BattlerIndex } from "../battle";
import stringify, { Element } from "json-stable-stringify"; import { Element } from "json-stable-stringify";
import { Moves } from "./enums/moves"; import { Moves } from "./enums/moves";
import { getTypeRgb } from "./type";
//import fs from 'vite-plugin-fs/browser'; //import fs from 'vite-plugin-fs/browser';
export enum AnimFrameTarget { export enum AnimFrameTarget {
@ -119,24 +118,25 @@ export class AnimConfig {
this.graphic = source.graphic; this.graphic = source.graphic;
const frames: any[][] = source.frames; const frames: any[][] = source.frames;
frames.map(animFrames => { frames.map(animFrames => {
for (let f = 0; f < animFrames.length; f++) for (let f = 0; f < animFrames.length; f++) {
animFrames[f] = new ImportedAnimFrame(animFrames[f]); animFrames[f] = new ImportedAnimFrame(animFrames[f]);
}
}); });
this.frames = frames; this.frames = frames;
const frameTimedEvents = source.frameTimedEvents; const frameTimedEvents = source.frameTimedEvents;
for (let fte of Object.keys(frameTimedEvents)) { for (const fte of Object.keys(frameTimedEvents)) {
const timedEvents: AnimTimedEvent[] = []; const timedEvents: AnimTimedEvent[] = [];
for (let te of frameTimedEvents[fte]) { for (const te of frameTimedEvents[fte]) {
let timedEvent: AnimTimedEvent; let timedEvent: AnimTimedEvent;
switch (te.eventType) { switch (te.eventType) {
case 'AnimTimedSoundEvent': case "AnimTimedSoundEvent":
timedEvent = new AnimTimedSoundEvent(te.frameIndex, te.resourceName, te); timedEvent = new AnimTimedSoundEvent(te.frameIndex, te.resourceName, te);
break; break;
case 'AnimTimedAddBgEvent': case "AnimTimedAddBgEvent":
timedEvent = new AnimTimedAddBgEvent(te.frameIndex, te.resourceName, te); timedEvent = new AnimTimedAddBgEvent(te.frameIndex, te.resourceName, te);
break; break;
case 'AnimTimedUpdateBgEvent': case "AnimTimedUpdateBgEvent":
timedEvent = new AnimTimedUpdateBgEvent(te.frameIndex, te.resourceName, te); timedEvent = new AnimTimedUpdateBgEvent(te.frameIndex, te.resourceName, te);
break; break;
} }
@ -147,19 +147,21 @@ export class AnimConfig {
this.position = source.position; this.position = source.position;
this.hue = source.hue; this.hue = source.hue;
} else } else {
this.frames = []; this.frames = [];
} }
}
getSoundResourceNames(): string[] { getSoundResourceNames(): string[] {
const sounds = new Set<string>(); const sounds = new Set<string>();
for (let ftes of this.frameTimedEvents.values()) { for (const ftes of this.frameTimedEvents.values()) {
for (let fte of ftes) { for (const fte of ftes) {
if (fte instanceof AnimTimedSoundEvent && fte.resourceName) if (fte instanceof AnimTimedSoundEvent && fte.resourceName) {
sounds.add(fte.resourceName); sounds.add(fte.resourceName);
} }
} }
}
return Array.from(sounds.values()); return Array.from(sounds.values());
} }
@ -167,12 +169,13 @@ export class AnimConfig {
getBackgroundResourceNames(): string[] { getBackgroundResourceNames(): string[] {
const backgrounds = new Set<string>(); const backgrounds = new Set<string>();
for (let ftes of this.frameTimedEvents.values()) { for (const ftes of this.frameTimedEvents.values()) {
for (let fte of ftes) { for (const fte of ftes) {
if (fte instanceof AnimTimedAddBgEvent && fte.resourceName) if (fte instanceof AnimTimedAddBgEvent && fte.resourceName) {
backgrounds.add(fte.resourceName); backgrounds.add(fte.resourceName);
} }
} }
}
return Array.from(backgrounds.values()); return Array.from(backgrounds.values());
} }
@ -202,30 +205,36 @@ class AnimFrame {
flashR: integer, flashG: integer, flashB: integer, flashA: integer, locked: boolean, priority: integer, focus: AnimFocus, init?: boolean) { flashR: integer, flashG: integer, flashB: integer, flashA: integer, locked: boolean, priority: integer, focus: AnimFocus, init?: boolean) {
this.x = !init ? ((x || 0) - 128) * 0.5 : x; this.x = !init ? ((x || 0) - 128) * 0.5 : x;
this.y = !init ? ((y || 0) - 224) * 0.5 : y; this.y = !init ? ((y || 0) - 224) * 0.5 : y;
if (zoomX) if (zoomX) {
this.zoomX = zoomX; this.zoomX = zoomX;
else if (init) } else if (init) {
this.zoomX = 0; this.zoomX = 0;
if (zoomY) }
if (zoomY) {
this.zoomY = zoomY; this.zoomY = zoomY;
else if (init) } else if (init) {
this.zoomY = 0; this.zoomY = 0;
if (angle) }
if (angle) {
this.angle = angle; this.angle = angle;
else if (init) } else if (init) {
this.angle = 0; this.angle = 0;
if (mirror) }
if (mirror) {
this.mirror = mirror; this.mirror = mirror;
else if (init) } else if (init) {
this.mirror = false; this.mirror = false;
if (visible) }
if (visible) {
this.visible = visible; this.visible = visible;
else if (init) } else if (init) {
this.visible = false; this.visible = false;
if (blendType) }
if (blendType) {
this.blendType = blendType; this.blendType = blendType;
else if (init) } else if (init) {
this.blendType = AnimBlendType.NORMAL; this.blendType = AnimBlendType.NORMAL;
}
if (!init) { if (!init) {
let target = AnimFrameTarget.GRAPHIC; let target = AnimFrameTarget.GRAPHIC;
switch (pattern) { switch (pattern) {
@ -239,30 +248,36 @@ class AnimFrame {
this.target = target; this.target = target;
this.graphicFrame = pattern >= 0 ? pattern : 0; this.graphicFrame = pattern >= 0 ? pattern : 0;
} }
if (opacity) if (opacity) {
this.opacity = opacity; this.opacity = opacity;
else if (init) } else if (init) {
this.opacity = 0; this.opacity = 0;
if (colorR || colorG || colorB || colorA) }
if (colorR || colorG || colorB || colorA) {
this.color = [ colorR || 0, colorG || 0, colorB || 0, colorA || 0 ]; this.color = [ colorR || 0, colorG || 0, colorB || 0, colorA || 0 ];
else if (init) } else if (init) {
this.color = [ 0, 0, 0, 0 ]; this.color = [ 0, 0, 0, 0 ];
if (toneR || toneG || toneB || toneA) }
if (toneR || toneG || toneB || toneA) {
this.tone = [ toneR || 0, toneG || 0, toneB || 0, toneA || 0 ]; this.tone = [ toneR || 0, toneG || 0, toneB || 0, toneA || 0 ];
else if (init) } else if (init) {
this.tone = [ 0, 0, 0, 0 ]; this.tone = [ 0, 0, 0, 0 ];
if (flashR || flashG || flashB || flashA) }
if (flashR || flashG || flashB || flashA) {
this.flash = [ flashR || 0, flashG || 0, flashB || 0, flashA || 0 ]; this.flash = [ flashR || 0, flashG || 0, flashB || 0, flashA || 0 ];
else if (init) } else if (init) {
this.flash = [ 0, 0, 0, 0 ]; this.flash = [ 0, 0, 0, 0 ];
if (locked) }
if (locked) {
this.locked = locked; this.locked = locked;
else if (init) } else if (init) {
this.locked = false; this.locked = false;
if (priority) }
if (priority) {
this.priority = priority; this.priority = priority;
else if (init) } else if (init) {
this.priority = 0; this.priority = 0;
}
this.focus = focus || AnimFocus.TARGET; this.focus = focus || AnimFocus.TARGET;
} }
} }
@ -314,12 +329,13 @@ class AnimTimedSoundEvent extends AnimTimedEvent {
console.error(err); console.error(err);
} }
return Math.ceil((scene.sound.get(this.resourceName).totalDuration * 1000) / 33.33); return Math.ceil((scene.sound.get(this.resourceName).totalDuration * 1000) / 33.33);
} else } else {
return Math.ceil((battleAnim.user.cry(soundConfig).totalDuration * 1000) / 33.33); return Math.ceil((battleAnim.user.cry(soundConfig).totalDuration * 1000) / 33.33);
} }
}
getEventType(): string { getEventType(): string {
return 'AnimTimedSoundEvent'; return "AnimTimedSoundEvent";
} }
} }
@ -368,12 +384,15 @@ class AnimTimedUpdateBgEvent extends AnimTimedBgEvent {
execute(scene: BattleScene, moveAnim: MoveAnim): integer { execute(scene: BattleScene, moveAnim: MoveAnim): integer {
const tweenProps = {}; const tweenProps = {};
if (this.bgX !== undefined) if (this.bgX !== undefined) {
tweenProps['x'] = (this.bgX * 0.5) - 320; tweenProps["x"] = (this.bgX * 0.5) - 320;
if (this.bgY !== undefined) }
tweenProps['y'] = (this.bgY * 0.5) - 284; if (this.bgY !== undefined) {
if (this.opacity !== undefined) tweenProps["y"] = (this.bgY * 0.5) - 284;
tweenProps['alpha'] = (this.opacity || 0) / 255; }
if (this.opacity !== undefined) {
tweenProps["alpha"] = (this.opacity || 0) / 255;
}
if (Object.keys(tweenProps).length) { if (Object.keys(tweenProps).length) {
scene.tweens.add(Object.assign({ scene.tweens.add(Object.assign({
targets: moveAnim.bgSprite, targets: moveAnim.bgSprite,
@ -384,7 +403,7 @@ class AnimTimedUpdateBgEvent extends AnimTimedBgEvent {
} }
getEventType(): string { getEventType(): string {
return 'AnimTimedUpdateBgEvent'; return "AnimTimedUpdateBgEvent";
} }
} }
@ -394,8 +413,9 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
} }
execute(scene: BattleScene, moveAnim: MoveAnim): integer { execute(scene: BattleScene, moveAnim: MoveAnim): integer {
if (moveAnim.bgSprite) if (moveAnim.bgSprite) {
moveAnim.bgSprite.destroy(); moveAnim.bgSprite.destroy();
}
moveAnim.bgSprite = this.resourceName moveAnim.bgSprite = this.resourceName
? scene.add.tileSprite(this.bgX - 320, this.bgY - 284, 896, 576, this.resourceName) ? scene.add.tileSprite(this.bgX - 320, this.bgY - 284, 896, 576, this.resourceName)
: scene.add.rectangle(this.bgX - 320, this.bgY - 284, 896, 576, 0); : scene.add.rectangle(this.bgX - 320, this.bgY - 284, 896, 576, 0);
@ -404,8 +424,9 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
moveAnim.bgSprite.setAlpha(this.opacity / 255); moveAnim.bgSprite.setAlpha(this.opacity / 255);
scene.field.add(moveAnim.bgSprite); scene.field.add(moveAnim.bgSprite);
const fieldPokemon = scene.getEnemyPokemon() || scene.getPlayerPokemon(); const fieldPokemon = scene.getEnemyPokemon() || scene.getPlayerPokemon();
if (fieldPokemon?.isOnField()) if (fieldPokemon?.isOnField()) {
scene.field.moveBelow(moveAnim.bgSprite as Phaser.GameObjects.GameObject, fieldPokemon); scene.field.moveBelow(moveAnim.bgSprite as Phaser.GameObjects.GameObject, fieldPokemon);
}
scene.tweens.add({ scene.tweens.add({
targets: moveAnim.bgSprite, targets: moveAnim.bgSprite,
@ -416,7 +437,7 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
} }
getEventType(): string { getEventType(): string {
return 'AnimTimedAddBgEvent'; return "AnimTimedAddBgEvent";
} }
} }
@ -431,7 +452,7 @@ export function initCommonAnims(scene: BattleScene): Promise<void> {
const commonAnimFetches = []; const commonAnimFetches = [];
for (let ca = 0; ca < commonAnimIds.length; ca++) { for (let ca = 0; ca < commonAnimIds.length; ca++) {
const commonAnimId = commonAnimIds[ca]; const commonAnimId = commonAnimIds[ca];
commonAnimFetches.push(scene.cachedFetch(`./battle-anims/common-${commonAnimNames[ca].toLowerCase().replace(/\_/g, '-')}.json`) commonAnimFetches.push(scene.cachedFetch(`./battle-anims/common-${commonAnimNames[ca].toLowerCase().replace(/\_/g, "-")}.json`)
.then(response => response.json()) .then(response => response.json())
.then(cas => commonAnims.set(commonAnimId, new AnimConfig(cas)))); .then(cas => commonAnims.set(commonAnimId, new AnimConfig(cas))));
} }
@ -442,14 +463,15 @@ export function initCommonAnims(scene: BattleScene): Promise<void> {
export function initMoveAnim(scene: BattleScene, move: Moves): Promise<void> { export function initMoveAnim(scene: BattleScene, move: Moves): Promise<void> {
return new Promise(resolve => { return new Promise(resolve => {
if (moveAnims.has(move)) { if (moveAnims.has(move)) {
if (moveAnims.get(move) !== null) if (moveAnims.get(move) !== null) {
resolve(); resolve();
else { } else {
let loadedCheckTimer = setInterval(() => { const loadedCheckTimer = setInterval(() => {
if (moveAnims.get(move) !== null) { if (moveAnims.get(move) !== null) {
const chargeAttr = allMoves[move].getAttrs(ChargeAttr).find(() => true) as ChargeAttr || allMoves[move].getAttrs(DelayedAttackAttr).find(() => true) as DelayedAttackAttr; const chargeAttr = allMoves[move].getAttrs(ChargeAttr).find(() => true) as ChargeAttr || allMoves[move].getAttrs(DelayedAttackAttr).find(() => true) as DelayedAttackAttr;
if (chargeAttr && chargeAnims.get(chargeAttr.chargeAnim) === null) if (chargeAttr && chargeAnims.get(chargeAttr.chargeAnim) === null) {
return; return;
}
clearInterval(loadedCheckTimer); clearInterval(loadedCheckTimer);
resolve(); resolve();
} }
@ -458,7 +480,7 @@ export function initMoveAnim(scene: BattleScene, move: Moves): Promise<void> {
} else { } else {
moveAnims.set(move, null); moveAnims.set(move, null);
const defaultMoveAnim = allMoves[move] instanceof AttackMove ? Moves.TACKLE : allMoves[move] instanceof SelfStatusMove ? Moves.FOCUS_ENERGY : Moves.TAIL_WHIP; const defaultMoveAnim = allMoves[move] instanceof AttackMove ? Moves.TACKLE : allMoves[move] instanceof SelfStatusMove ? Moves.FOCUS_ENERGY : Moves.TAIL_WHIP;
const moveName = Moves[move].toLowerCase().replace(/\_/g, '-'); const moveName = Moves[move].toLowerCase().replace(/\_/g, "-");
const fetchAnimAndResolve = (move: Moves) => { const fetchAnimAndResolve = (move: Moves) => {
scene.cachedFetch(`./battle-anims/${moveName}.json`) scene.cachedFetch(`./battle-anims/${moveName}.json`)
.then(response => { .then(response => {
@ -473,13 +495,15 @@ export function initMoveAnim(scene: BattleScene, move: Moves): Promise<void> {
if (Array.isArray(ba)) { if (Array.isArray(ba)) {
populateMoveAnim(move, ba[0]); populateMoveAnim(move, ba[0]);
populateMoveAnim(move, ba[1]); populateMoveAnim(move, ba[1]);
} else } else {
populateMoveAnim(move, ba); populateMoveAnim(move, ba);
}
const chargeAttr = allMoves[move].getAttrs(ChargeAttr).find(() => true) as ChargeAttr || allMoves[move].getAttrs(DelayedAttackAttr).find(() => true) as DelayedAttackAttr; const chargeAttr = allMoves[move].getAttrs(ChargeAttr).find(() => true) as ChargeAttr || allMoves[move].getAttrs(DelayedAttackAttr).find(() => true) as DelayedAttackAttr;
if (chargeAttr) if (chargeAttr) {
initMoveChargeAnim(scene, chargeAttr.chargeAnim).then(() => resolve()); initMoveChargeAnim(scene, chargeAttr.chargeAnim).then(() => resolve());
else } else {
resolve(); resolve();
}
}); });
}; };
fetchAnimAndResolve(move); fetchAnimAndResolve(move);
@ -490,10 +514,10 @@ export function initMoveAnim(scene: BattleScene, move: Moves): Promise<void> {
export function initMoveChargeAnim(scene: BattleScene, chargeAnim: ChargeAnim): Promise<void> { export function initMoveChargeAnim(scene: BattleScene, chargeAnim: ChargeAnim): Promise<void> {
return new Promise(resolve => { return new Promise(resolve => {
if (chargeAnims.has(chargeAnim)) { if (chargeAnims.has(chargeAnim)) {
if (chargeAnims.get(chargeAnim) !== null) if (chargeAnims.get(chargeAnim) !== null) {
resolve(); resolve();
else { } else {
let loadedCheckTimer = setInterval(() => { const loadedCheckTimer = setInterval(() => {
if (chargeAnims.get(chargeAnim) !== null) { if (chargeAnims.get(chargeAnim) !== null) {
clearInterval(loadedCheckTimer); clearInterval(loadedCheckTimer);
resolve(); resolve();
@ -502,14 +526,15 @@ export function initMoveChargeAnim(scene: BattleScene, chargeAnim: ChargeAnim):
} }
} else { } else {
chargeAnims.set(chargeAnim, null); chargeAnims.set(chargeAnim, null);
scene.cachedFetch(`./battle-anims/${ChargeAnim[chargeAnim].toLowerCase().replace(/\_/g, '-')}.json`) scene.cachedFetch(`./battle-anims/${ChargeAnim[chargeAnim].toLowerCase().replace(/\_/g, "-")}.json`)
.then(response => response.json()) .then(response => response.json())
.then(ca => { .then(ca => {
if (Array.isArray(ca)) { if (Array.isArray(ca)) {
populateMoveChargeAnim(chargeAnim, ca[0]); populateMoveChargeAnim(chargeAnim, ca[0]);
populateMoveChargeAnim(chargeAnim, ca[1]); populateMoveChargeAnim(chargeAnim, ca[1]);
} else } else {
populateMoveChargeAnim(chargeAnim, ca); populateMoveChargeAnim(chargeAnim, ca);
}
resolve(); resolve();
}); });
} }
@ -543,15 +568,16 @@ export function loadCommonAnimAssets(scene: BattleScene, startLoad?: boolean): P
export function loadMoveAnimAssets(scene: BattleScene, moveIds: Moves[], startLoad?: boolean): Promise<void> { export function loadMoveAnimAssets(scene: BattleScene, moveIds: Moves[], startLoad?: boolean): Promise<void> {
return new Promise(resolve => { return new Promise(resolve => {
const moveAnimations = moveIds.map(m => moveAnims.get(m) as AnimConfig).flat(); const moveAnimations = moveIds.map(m => moveAnims.get(m) as AnimConfig).flat();
for (let moveId of moveIds) { for (const moveId of moveIds) {
const chargeAttr = allMoves[moveId].getAttrs(ChargeAttr).find(() => true) as ChargeAttr || allMoves[moveId].getAttrs(DelayedAttackAttr).find(() => true) as DelayedAttackAttr; const chargeAttr = allMoves[moveId].getAttrs(ChargeAttr).find(() => true) as ChargeAttr || allMoves[moveId].getAttrs(DelayedAttackAttr).find(() => true) as DelayedAttackAttr;
if (chargeAttr) { if (chargeAttr) {
const moveChargeAnims = chargeAnims.get(chargeAttr.chargeAnim); const moveChargeAnims = chargeAnims.get(chargeAttr.chargeAnim);
moveAnimations.push(moveChargeAnims instanceof AnimConfig ? moveChargeAnims : moveChargeAnims[0]); moveAnimations.push(moveChargeAnims instanceof AnimConfig ? moveChargeAnims : moveChargeAnims[0]);
if (Array.isArray(moveChargeAnims)) if (Array.isArray(moveChargeAnims)) {
moveAnimations.push(moveChargeAnims[1]); moveAnimations.push(moveChargeAnims[1]);
} }
} }
}
loadAnimAssets(scene, moveAnimations, startLoad).then(() => resolve()); loadAnimAssets(scene, moveAnimations, startLoad).then(() => resolve());
}); });
} }
@ -560,28 +586,36 @@ function loadAnimAssets(scene: BattleScene, anims: AnimConfig[], startLoad?: boo
return new Promise(resolve => { return new Promise(resolve => {
const backgrounds = new Set<string>(); const backgrounds = new Set<string>();
const sounds = new Set<string>(); const sounds = new Set<string>();
for (let a of anims) { for (const a of anims) {
if (!a.frames?.length) if (!a.frames?.length) {
continue; continue;
const animSounds = a.getSoundResourceNames();
for (let ms of animSounds)
sounds.add(ms);
const animBackgrounds = a.getBackgroundResourceNames();
for (let abg of animBackgrounds)
backgrounds.add(abg);
if (a.graphic)
scene.loadSpritesheet(a.graphic, 'battle_anims', 96);
} }
for (let bg of backgrounds) const animSounds = a.getSoundResourceNames();
scene.loadImage(bg, 'battle_anims'); for (const ms of animSounds) {
for (let s of sounds) sounds.add(ms);
scene.loadSe(s, 'battle_anims', s); }
const animBackgrounds = a.getBackgroundResourceNames();
for (const abg of animBackgrounds) {
backgrounds.add(abg);
}
if (a.graphic) {
scene.loadSpritesheet(a.graphic, "battle_anims", 96);
}
}
for (const bg of backgrounds) {
scene.loadImage(bg, "battle_anims");
}
for (const s of sounds) {
scene.loadSe(s, "battle_anims", s);
}
if (startLoad) { if (startLoad) {
scene.load.once(Phaser.Loader.Events.COMPLETE, () => resolve()); scene.load.once(Phaser.Loader.Events.COMPLETE, () => resolve());
if (!scene.load.isLoading()) if (!scene.load.isLoading()) {
scene.load.start(); scene.load.start();
} else }
} else {
resolve(); resolve();
}
}); });
} }
@ -620,10 +654,12 @@ function repositionY(x1: number, y1: number, x2: number, y2: number, tx: number,
} }
function isReversed(src1: number, src2: number, dst1: number, dst2: number) { function isReversed(src1: number, src2: number, dst1: number, dst2: number) {
if (src1 === src2) if (src1 === src2) {
return false; return false;
if (src1 < src2) }
if (src1 < src2) {
return dst1 > dst2; return dst1 > dst2;
}
return dst1 < dst2; return dst1 < dst2;
} }
@ -680,11 +716,11 @@ export abstract class BattleAnim {
let u = 0; let u = 0;
let t = 0; let t = 0;
for (let frame of frames) { for (const frame of frames) {
let x = frame.x + 106; let x = frame.x + 106;
let y = frame.y + 116; let y = frame.y + 116;
let scaleX = (frame.zoomX / 100) * (!frame.mirror ? 1 : -1); let scaleX = (frame.zoomX / 100) * (!frame.mirror ? 1 : -1);
let scaleY = (frame.zoomY / 100); const scaleY = (frame.zoomY / 100);
switch (frame.focus) { switch (frame.focus) {
case AnimFocus.TARGET: case AnimFocus.TARGET:
x += targetInitialX - targetFocusX; x += targetInitialX - targetFocusX;
@ -699,8 +735,9 @@ export abstract class BattleAnim {
this.dstLine[0], this.dstLine[1] - userHalfHeight, this.dstLine[2], this.dstLine[3] - targetHalfHeight, x, y); this.dstLine[0], this.dstLine[1] - userHalfHeight, this.dstLine[2], this.dstLine[3] - targetHalfHeight, x, y);
x = point[0]; x = point[0];
y = point[1]; y = point[1];
if (frame.target === AnimFrameTarget.GRAPHIC && isReversed(this.srcLine[0], this.srcLine[2], this.dstLine[0], this.dstLine[2])) if (frame.target === AnimFrameTarget.GRAPHIC && isReversed(this.srcLine[0], this.srcLine[2], this.dstLine[0], this.dstLine[2])) {
scaleX = scaleX * -1; scaleX = scaleX * -1;
}
break; break;
} }
const angle = -frame.angle; const angle = -frame.angle;
@ -717,8 +754,9 @@ export abstract class BattleAnim {
const target = !isOppAnim ? this.target : this.user; const target = !isOppAnim ? this.target : this.user;
if (!target.isOnField()) { if (!target.isOnField()) {
if (callback) if (callback) {
callback(); callback();
}
return; return;
} }
@ -736,29 +774,35 @@ export abstract class BattleAnim {
userSprite.setPosition(0, 0); userSprite.setPosition(0, 0);
userSprite.setScale(1); userSprite.setScale(1);
userSprite.setAlpha(1); userSprite.setAlpha(1);
userSprite.pipelineData['tone'] = [ 0.0, 0.0, 0.0, 0.0 ]; userSprite.pipelineData["tone"] = [ 0.0, 0.0, 0.0, 0.0 ];
userSprite.setAngle(0); userSprite.setAngle(0);
targetSprite.setPosition(0, 0); targetSprite.setPosition(0, 0);
targetSprite.setScale(1); targetSprite.setScale(1);
targetSprite.setAlpha(1); targetSprite.setAlpha(1);
targetSprite.pipelineData['tone'] = [ 0.0, 0.0, 0.0, 0.0 ]; targetSprite.pipelineData["tone"] = [ 0.0, 0.0, 0.0, 0.0 ];
targetSprite.setAngle(0); targetSprite.setAngle(0);
if (!this.isHideUser()) if (!this.isHideUser()) {
userSprite.setVisible(true); userSprite.setVisible(true);
if (!this.isHideTarget() && (targetSprite !== userSprite || !this.isHideUser())) }
if (!this.isHideTarget() && (targetSprite !== userSprite || !this.isHideUser())) {
targetSprite.setVisible(true); targetSprite.setVisible(true);
for (let ms of Object.values(spriteCache).flat()) { }
if (ms) for (const ms of Object.values(spriteCache).flat()) {
if (ms) {
ms.destroy(); ms.destroy();
} }
if (this.bgSprite) }
if (this.bgSprite) {
this.bgSprite.destroy(); this.bgSprite.destroy();
if (callback) }
if (callback) {
callback(); callback();
}
}; };
if (!scene.moveAnimations) if (!scene.moveAnimations) {
return cleanUpAndComplete(); return cleanUpAndComplete();
}
const anim = this.getAnim(); const anim = this.getAnim();
@ -787,22 +831,22 @@ export abstract class BattleAnim {
let u = 0; let u = 0;
let t = 0; let t = 0;
let g = 0; let g = 0;
for (let frame of spriteFrames) { for (const frame of spriteFrames) {
if (frame.target !== AnimFrameTarget.GRAPHIC) { if (frame.target !== AnimFrameTarget.GRAPHIC) {
const isUser = frame.target === AnimFrameTarget.USER; const isUser = frame.target === AnimFrameTarget.USER;
if (isUser && target === user) if (isUser && target === user) {
continue; continue;
}
const sprites = spriteCache[isUser ? AnimFrameTarget.USER : AnimFrameTarget.TARGET]; const sprites = spriteCache[isUser ? AnimFrameTarget.USER : AnimFrameTarget.TARGET];
const spriteSource = isUser ? userSprite : targetSprite; const spriteSource = isUser ? userSprite : targetSprite;
if ((isUser ? u : t) === sprites.length) { if ((isUser ? u : t) === sprites.length) {
let sprite: Phaser.GameObjects.Sprite; const sprite = scene.addPokemonSprite(isUser ? user : target, 0, 0, spriteSource.texture, spriteSource.frame.name, true);
sprite = scene.addPokemonSprite(isUser ? user : target, 0, 0, spriteSource.texture, spriteSource.frame.name, true); [ "spriteColors", "fusionSpriteColors" ].map(k => sprite.pipelineData[k] = (isUser ? user : target).getSprite().pipelineData[k]);
[ 'spriteColors', 'fusionSpriteColors' ].map(k => sprite.pipelineData[k] = (isUser ? user : target).getSprite().pipelineData[k]); sprite.setPipelineData("spriteKey", (isUser ? user : target).getBattleSpriteKey());
sprite.setPipelineData('spriteKey', (isUser ? user : target).getBattleSpriteKey()); sprite.setPipelineData("shiny", (isUser ? user : target).shiny);
sprite.setPipelineData('shiny', (isUser ? user : target).shiny); sprite.setPipelineData("variant", (isUser ? user : target).variant);
sprite.setPipelineData('variant', (isUser ? user : target).variant); sprite.setPipelineData("ignoreFieldPos", true);
sprite.setPipelineData('ignoreFieldPos', true); spriteSource.on("animationupdate", (_anim, frame) => sprite.setFrame(frame.textureFrame));
spriteSource.on('animationupdate', (_anim, frame) => sprite.setFrame(frame.textureFrame));
scene.field.add(sprite); scene.field.add(sprite);
sprites.push(sprite); sprites.push(sprite);
} }
@ -815,16 +859,16 @@ export abstract class BattleAnim {
pokemonSprite.setAngle(graphicFrameData.angle); pokemonSprite.setAngle(graphicFrameData.angle);
pokemonSprite.setScale(graphicFrameData.scaleX * spriteSource.parentContainer.scale, graphicFrameData.scaleY * spriteSource.parentContainer.scale); pokemonSprite.setScale(graphicFrameData.scaleX * spriteSource.parentContainer.scale, graphicFrameData.scaleY * spriteSource.parentContainer.scale);
pokemonSprite.setData('locked', frame.locked); pokemonSprite.setData("locked", frame.locked);
pokemonSprite.setAlpha(frame.opacity / 255); pokemonSprite.setAlpha(frame.opacity / 255);
pokemonSprite.pipelineData['tone'] = frame.tone; pokemonSprite.pipelineData["tone"] = frame.tone;
pokemonSprite.setVisible(frame.visible && (isUser ? user.visible : target.visible)); pokemonSprite.setVisible(frame.visible && (isUser ? user.visible : target.visible));
pokemonSprite.setBlendMode(frame.blendType === AnimBlendType.NORMAL ? Phaser.BlendModes.NORMAL : frame.blendType === AnimBlendType.ADD ? Phaser.BlendModes.ADD : Phaser.BlendModes.DIFFERENCE); pokemonSprite.setBlendMode(frame.blendType === AnimBlendType.NORMAL ? Phaser.BlendModes.NORMAL : frame.blendType === AnimBlendType.ADD ? Phaser.BlendModes.ADD : Phaser.BlendModes.DIFFERENCE);
} else { } else {
const sprites = spriteCache[AnimFrameTarget.GRAPHIC]; const sprites = spriteCache[AnimFrameTarget.GRAPHIC];
if (g === sprites.length) { if (g === sprites.length) {
let newSprite: Phaser.GameObjects.Sprite = scene.addFieldSprite(0, 0, anim.graphic, 1); const newSprite: Phaser.GameObjects.Sprite = scene.addFieldSprite(0, 0, anim.graphic, 1);
sprites.push(newSprite); sprites.push(newSprite);
scene.field.add(newSprite); scene.field.add(newSprite);
spritePriorities.push(1); spritePriorities.push(1);
@ -845,10 +889,11 @@ export abstract class BattleAnim {
case 2: case 2:
switch (frame.focus) { switch (frame.focus) {
case AnimFocus.USER: case AnimFocus.USER:
if (this.bgSprite) if (this.bgSprite) {
scene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.bgSprite); scene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.bgSprite);
else } else {
scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.user); scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.user);
}
break; break;
case AnimFocus.TARGET: case AnimFocus.TARGET:
scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.target); scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.target);
@ -891,20 +936,22 @@ export abstract class BattleAnim {
} }
} }
if (anim.frameTimedEvents.has(f)) { if (anim.frameTimedEvents.has(f)) {
for (let event of anim.frameTimedEvents.get(f)) for (const event of anim.frameTimedEvents.get(f)) {
r = Math.max((anim.frames.length - f) + event.execute(scene, this), r); r = Math.max((anim.frames.length - f) + event.execute(scene, this), r);
} }
}
const targets = Utils.getEnumValues(AnimFrameTarget); const targets = Utils.getEnumValues(AnimFrameTarget);
for (let i of targets) { for (const i of targets) {
const count = i === AnimFrameTarget.GRAPHIC ? g : i === AnimFrameTarget.USER ? u : t; const count = i === AnimFrameTarget.GRAPHIC ? g : i === AnimFrameTarget.USER ? u : t;
if (count < spriteCache[i].length) { if (count < spriteCache[i].length) {
const spritesToRemove = spriteCache[i].slice(count, spriteCache[i].length); const spritesToRemove = spriteCache[i].slice(count, spriteCache[i].length);
for (let rs of spritesToRemove) { for (const rs of spritesToRemove) {
if (!rs.getData('locked') as boolean) { if (!rs.getData("locked") as boolean) {
const spriteCacheIndex = spriteCache[i].indexOf(rs); const spriteCacheIndex = spriteCache[i].indexOf(rs);
spriteCache[i].splice(spriteCacheIndex, 1); spriteCache[i].splice(spriteCacheIndex, 1);
if (i === AnimFrameTarget.GRAPHIC) if (i === AnimFrameTarget.GRAPHIC) {
spritePriorities.splice(spriteCacheIndex, 1); spritePriorities.splice(spriteCacheIndex, 1);
}
rs.destroy(); rs.destroy();
} }
} }
@ -914,18 +961,20 @@ export abstract class BattleAnim {
r--; r--;
}, },
onComplete: () => { onComplete: () => {
for (let ms of Object.values(spriteCache).flat()) { for (const ms of Object.values(spriteCache).flat()) {
if (ms && !ms.getData('locked')) if (ms && !ms.getData("locked")) {
ms.destroy(); ms.destroy();
} }
}
if (r) { if (r) {
scene.tweens.addCounter({ scene.tweens.addCounter({
duration: Utils.getFrameMs(r), duration: Utils.getFrameMs(r),
onComplete: () => cleanUpAndComplete() onComplete: () => cleanUpAndComplete()
}); });
} else } else {
cleanUpAndComplete(); cleanUpAndComplete();
} }
}
}); });
} }
} }
@ -998,15 +1047,15 @@ export class MoveChargeAnim extends MoveAnim {
export async function populateAnims() { export async function populateAnims() {
const commonAnimNames = Utils.getEnumKeys(CommonAnim).map(k => k.toLowerCase()); const commonAnimNames = Utils.getEnumKeys(CommonAnim).map(k => k.toLowerCase());
const commonAnimMatchNames = commonAnimNames.map(k => k.replace(/\_/g, '')); const commonAnimMatchNames = commonAnimNames.map(k => k.replace(/\_/g, ""));
const commonAnimIds = Utils.getEnumValues(CommonAnim) as CommonAnim[]; const commonAnimIds = Utils.getEnumValues(CommonAnim) as CommonAnim[];
const chargeAnimNames = Utils.getEnumKeys(ChargeAnim).map(k => k.toLowerCase()); const chargeAnimNames = Utils.getEnumKeys(ChargeAnim).map(k => k.toLowerCase());
const chargeAnimMatchNames = chargeAnimNames.map(k => k.replace(/\_/g, ' ')); const chargeAnimMatchNames = chargeAnimNames.map(k => k.replace(/\_/g, " "));
const chargeAnimIds = Utils.getEnumValues(ChargeAnim) as ChargeAnim[]; const chargeAnimIds = Utils.getEnumValues(ChargeAnim) as ChargeAnim[];
const commonNamePattern = /name: (?:Common:)?(Opp )?(.*)/; const commonNamePattern = /name: (?:Common:)?(Opp )?(.*)/;
const moveNameToId = {}; const moveNameToId = {};
for (let move of Utils.getEnumValues(Moves).slice(1)) { for (const move of Utils.getEnumValues(Moves).slice(1)) {
const moveName = Moves[move].toUpperCase().replace(/\_/g, ''); const moveName = Moves[move].toUpperCase().replace(/\_/g, "");
moveNameToId[moveName] = move; moveNameToId[moveName] = move;
} }
@ -1014,49 +1063,52 @@ export async function populateAnims() {
const animsData = [];//battleAnimRawData.split('!ruby/array:PBAnimation').slice(1); const animsData = [];//battleAnimRawData.split('!ruby/array:PBAnimation').slice(1);
for (let a = 0; a < animsData.length; a++) { for (let a = 0; a < animsData.length; a++) {
const fields = animsData[a].split('@').slice(1); const fields = animsData[a].split("@").slice(1);
const nameField = fields.find(f => f.startsWith('name: ')); const nameField = fields.find(f => f.startsWith("name: "));
let isOppMove: boolean; let isOppMove: boolean;
let commonAnimId: CommonAnim; let commonAnimId: CommonAnim;
let chargeAnimId: ChargeAnim; let chargeAnimId: ChargeAnim;
if (!nameField.startsWith('name: Move:') && !(isOppMove = nameField.startsWith('name: OppMove:'))) { if (!nameField.startsWith("name: Move:") && !(isOppMove = nameField.startsWith("name: OppMove:"))) {
const nameMatch = commonNamePattern.exec(nameField); const nameMatch = commonNamePattern.exec(nameField);
const name = nameMatch[2].toLowerCase(); const name = nameMatch[2].toLowerCase();
if (commonAnimMatchNames.indexOf(name) > -1) if (commonAnimMatchNames.indexOf(name) > -1) {
commonAnimId = commonAnimIds[commonAnimMatchNames.indexOf(name)]; commonAnimId = commonAnimIds[commonAnimMatchNames.indexOf(name)];
else if (chargeAnimMatchNames.indexOf(name) > -1) { } else if (chargeAnimMatchNames.indexOf(name) > -1) {
isOppMove = nameField.startsWith('name: Opp '); isOppMove = nameField.startsWith("name: Opp ");
chargeAnimId = chargeAnimIds[chargeAnimMatchNames.indexOf(name)]; chargeAnimId = chargeAnimIds[chargeAnimMatchNames.indexOf(name)];
} }
} }
const nameIndex = nameField.indexOf(':', 5) + 1; const nameIndex = nameField.indexOf(":", 5) + 1;
const animName = nameField.slice(nameIndex, nameField.indexOf('\n', nameIndex)); const animName = nameField.slice(nameIndex, nameField.indexOf("\n", nameIndex));
if (!moveNameToId.hasOwnProperty(animName) && !commonAnimId && !chargeAnimId) if (!moveNameToId.hasOwnProperty(animName) && !commonAnimId && !chargeAnimId) {
continue; continue;
let anim = commonAnimId || chargeAnimId ? new AnimConfig() : new AnimConfig(); }
if (anim instanceof AnimConfig) const anim = commonAnimId || chargeAnimId ? new AnimConfig() : new AnimConfig();
if (anim instanceof AnimConfig) {
(anim as AnimConfig).id = moveNameToId[animName]; (anim as AnimConfig).id = moveNameToId[animName];
if (commonAnimId) }
if (commonAnimId) {
commonAnims.set(commonAnimId, anim); commonAnims.set(commonAnimId, anim);
else if (chargeAnimId) } else if (chargeAnimId) {
chargeAnims.set(chargeAnimId, !isOppMove ? anim : [ chargeAnims.get(chargeAnimId) as AnimConfig, anim ]); chargeAnims.set(chargeAnimId, !isOppMove ? anim : [ chargeAnims.get(chargeAnimId) as AnimConfig, anim ]);
else } else {
moveAnims.set(moveNameToId[animName], !isOppMove ? anim as AnimConfig : [ moveAnims.get(moveNameToId[animName]) as AnimConfig, anim as AnimConfig ]); moveAnims.set(moveNameToId[animName], !isOppMove ? anim as AnimConfig : [ moveAnims.get(moveNameToId[animName]) as AnimConfig, anim as AnimConfig ]);
}
for (let f = 0; f < fields.length; f++) { for (let f = 0; f < fields.length; f++) {
const field = fields[f]; const field = fields[f];
const fieldName = field.slice(0, field.indexOf(':')); const fieldName = field.slice(0, field.indexOf(":"));
const fieldData = field.slice(fieldName.length + 1, field.lastIndexOf('\n')).trim(); const fieldData = field.slice(fieldName.length + 1, field.lastIndexOf("\n")).trim();
switch (fieldName) { switch (fieldName) {
case 'array': case "array":
const framesData = fieldData.split(' - - - ').slice(1); const framesData = fieldData.split(" - - - ").slice(1);
for (let fd = 0; fd < framesData.length; fd++) { for (let fd = 0; fd < framesData.length; fd++) {
anim.frames.push([]); anim.frames.push([]);
const frameData = framesData[fd]; const frameData = framesData[fd];
const focusFramesData = frameData.split(' - - '); const focusFramesData = frameData.split(" - - ");
for (let tf = 0; tf < focusFramesData.length; tf++) { for (let tf = 0; tf < focusFramesData.length; tf++) {
const values = focusFramesData[tf].replace(/ \- /g, '').split('\n'); const values = focusFramesData[tf].replace(/ \- /g, "").split("\n");
const targetFrame = new AnimFrame(parseFloat(values[0]), parseFloat(values[1]), parseFloat(values[2]), parseFloat(values[11]), parseFloat(values[3]), const targetFrame = new AnimFrame(parseFloat(values[0]), parseFloat(values[1]), parseFloat(values[2]), parseFloat(values[11]), parseFloat(values[3]),
parseInt(values[4]) === 1, parseInt(values[6]) === 1, parseInt(values[5]), parseInt(values[7]), parseInt(values[8]), parseInt(values[12]), parseInt(values[13]), parseInt(values[4]) === 1, parseInt(values[6]) === 1, parseInt(values[5]), parseInt(values[7]), parseInt(values[8]), parseInt(values[12]), parseInt(values[13]),
parseInt(values[14]), parseInt(values[15]), parseInt(values[16]), parseInt(values[17]), parseInt(values[18]), parseInt(values[19]), parseInt(values[14]), parseInt(values[15]), parseInt(values[16]), parseInt(values[17]), parseInt(values[18]), parseInt(values[19]),
@ -1065,115 +1117,126 @@ export async function populateAnims() {
} }
} }
break; break;
case 'graphic': case "graphic":
const graphic = fieldData !== "''" ? fieldData : ''; const graphic = fieldData !== "''" ? fieldData : "";
anim.graphic = graphic.indexOf('.') > -1 anim.graphic = graphic.indexOf(".") > -1
? graphic.slice(0, fieldData.indexOf('.')) ? graphic.slice(0, fieldData.indexOf("."))
: graphic; : graphic;
break; break;
case 'timing': case "timing":
const timingEntries = fieldData.split('- !ruby/object:PBAnimTiming ').slice(1); const timingEntries = fieldData.split("- !ruby/object:PBAnimTiming ").slice(1);
for (let t = 0; t < timingEntries.length; t++) { for (let t = 0; t < timingEntries.length; t++) {
const timingData = timingEntries[t].replace(/\n/g, ' ').replace(/[ ]{2,}/g, ' ').replace(/[a-z]+: ! '', /ig, '').replace(/name: (.*?),/, 'name: "$1",') const timingData = timingEntries[t].replace(/\n/g, " ").replace(/[ ]{2,}/g, " ").replace(/[a-z]+: ! '', /ig, "").replace(/name: (.*?),/, "name: \"$1\",")
.replace(/flashColor: !ruby\/object:Color { alpha: ([\d\.]+), blue: ([\d\.]+), green: ([\d\.]+), red: ([\d\.]+)}/, 'flashRed: $4, flashGreen: $3, flashBlue: $2, flashAlpha: $1'); .replace(/flashColor: !ruby\/object:Color { alpha: ([\d\.]+), blue: ([\d\.]+), green: ([\d\.]+), red: ([\d\.]+)}/, "flashRed: $4, flashGreen: $3, flashBlue: $2, flashAlpha: $1");
const frameIndex = parseInt(/frame: (\d+)/.exec(timingData)[1]); const frameIndex = parseInt(/frame: (\d+)/.exec(timingData)[1]);
let resourceName = /name: "(.*?)"/.exec(timingData)[1].replace("''", ''); let resourceName = /name: "(.*?)"/.exec(timingData)[1].replace("''", "");
const timingType = parseInt(/timingType: (\d)/.exec(timingData)[1]); const timingType = parseInt(/timingType: (\d)/.exec(timingData)[1]);
let timedEvent: AnimTimedEvent; let timedEvent: AnimTimedEvent;
switch (timingType) { switch (timingType) {
case 0: case 0:
if (resourceName && resourceName.indexOf('.') === -1) { if (resourceName && resourceName.indexOf(".") === -1) {
let ext: string; let ext: string;
[ 'wav', 'mp3', 'm4a' ].every(e => { [ "wav", "mp3", "m4a" ].every(e => {
if (seNames.indexOf(`${resourceName}.${e}`) > -1) { if (seNames.indexOf(`${resourceName}.${e}`) > -1) {
ext = e; ext = e;
return false; return false;
} }
return true; return true;
}); });
if (!ext) if (!ext) {
ext = '.wav'; ext = ".wav";
}
resourceName += `.${ext}`; resourceName += `.${ext}`;
} }
timedEvent = new AnimTimedSoundEvent(frameIndex, resourceName); timedEvent = new AnimTimedSoundEvent(frameIndex, resourceName);
break; break;
case 1: case 1:
timedEvent = new AnimTimedAddBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf('.'))); timedEvent = new AnimTimedAddBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf(".")));
break; break;
case 2: case 2:
timedEvent = new AnimTimedUpdateBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf('.'))); timedEvent = new AnimTimedUpdateBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf(".")));
break; break;
} }
if (!timedEvent) if (!timedEvent) {
continue; continue;
}
const propPattern = /([a-z]+): (.*?)(?:,|\})/ig; const propPattern = /([a-z]+): (.*?)(?:,|\})/ig;
let propMatch: RegExpExecArray; let propMatch: RegExpExecArray;
while ((propMatch = propPattern.exec(timingData))) { while ((propMatch = propPattern.exec(timingData))) {
const prop = propMatch[1]; const prop = propMatch[1];
let value: any = propMatch[2]; let value: any = propMatch[2];
switch (prop) { switch (prop) {
case 'bgX': case "bgX":
case 'bgY': case "bgY":
value = parseFloat(value); value = parseFloat(value);
break; break;
case 'volume': case "volume":
case 'pitch': case "pitch":
case 'opacity': case "opacity":
case 'colorRed': case "colorRed":
case 'colorGreen': case "colorGreen":
case 'colorBlue': case "colorBlue":
case 'colorAlpha': case "colorAlpha":
case 'duration': case "duration":
case 'flashScope': case "flashScope":
case 'flashRed': case "flashRed":
case 'flashGreen': case "flashGreen":
case 'flashBlue': case "flashBlue":
case 'flashAlpha': case "flashAlpha":
case 'flashDuration': case "flashDuration":
value = parseInt(value); value = parseInt(value);
break; break;
} }
if (timedEvent.hasOwnProperty(prop)) if (timedEvent.hasOwnProperty(prop)) {
timedEvent[prop] = value; timedEvent[prop] = value;
} }
if (!anim.frameTimedEvents.has(frameIndex)) }
if (!anim.frameTimedEvents.has(frameIndex)) {
anim.frameTimedEvents.set(frameIndex, []); anim.frameTimedEvents.set(frameIndex, []);
}
anim.frameTimedEvents.get(frameIndex).push(timedEvent); anim.frameTimedEvents.get(frameIndex).push(timedEvent);
} }
break; break;
case 'position': case "position":
anim.position = parseInt(fieldData); anim.position = parseInt(fieldData);
break; break;
case 'hue': case "hue":
anim.hue = parseInt(fieldData); anim.hue = parseInt(fieldData);
break; break;
} }
} }
} }
// used in commented code
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const animReplacer = (k, v) => { const animReplacer = (k, v) => {
if (k === 'id' && !v) if (k === "id" && !v) {
return undefined; return undefined;
if (v instanceof Map) }
if (v instanceof Map) {
return Object.fromEntries(v); return Object.fromEntries(v);
if (v instanceof AnimTimedEvent) }
v['eventType'] = v.getEventType(); if (v instanceof AnimTimedEvent) {
v["eventType"] = v.getEventType();
}
return v; return v;
}; };
const animConfigProps = [ 'id', 'graphic', 'frames', 'frameTimedEvents', 'position', 'hue' ]; const animConfigProps = [ "id", "graphic", "frames", "frameTimedEvents", "position", "hue" ];
const animFrameProps = [ 'x', 'y', 'zoomX', 'zoomY', 'angle', 'mirror', 'visible', 'blendType', 'target', 'graphicFrame', 'opacity', 'color', 'tone', 'flash', 'locked', 'priority', 'focus' ]; const animFrameProps = [ "x", "y", "zoomX", "zoomY", "angle", "mirror", "visible", "blendType", "target", "graphicFrame", "opacity", "color", "tone", "flash", "locked", "priority", "focus" ];
const propSets = [ animConfigProps, animFrameProps ]; const propSets = [ animConfigProps, animFrameProps ];
// used in commented code
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const animComparator = (a: Element, b: Element) => { const animComparator = (a: Element, b: Element) => {
let props: string[]; let props: string[];
let p = 0;
for (let p = 0; p < propSets.length; p++) { for (let p = 0; p < propSets.length; p++) {
props = propSets[p]; props = propSets[p];
let ai = props.indexOf(a.key); const ai = props.indexOf(a.key);
if (ai === -1) if (ai === -1) {
continue; continue;
let bi = props.indexOf(b.key); }
const bi = props.indexOf(b.key);
return ai < bi ? -1 : ai > bi ? 1 : 0; return ai < bi ? -1 : ai > bi ? 1 : 0;
} }

View File

@ -12,21 +12,21 @@ export enum BattleStat {
export function getBattleStatName(stat: BattleStat) { export function getBattleStatName(stat: BattleStat) {
switch (stat) { switch (stat) {
case BattleStat.ATK: case BattleStat.ATK:
return 'Attack'; return "Attack";
case BattleStat.DEF: case BattleStat.DEF:
return 'Defense'; return "Defense";
case BattleStat.SPATK: case BattleStat.SPATK:
return 'Sp. Atk'; return "Sp. Atk";
case BattleStat.SPDEF: case BattleStat.SPDEF:
return 'Sp. Def'; return "Sp. Def";
case BattleStat.SPD: case BattleStat.SPD:
return 'Speed'; return "Speed";
case BattleStat.ACC: case BattleStat.ACC:
return 'Accuracy'; return "Accuracy";
case BattleStat.EVA: case BattleStat.EVA:
return 'Evasiveness'; return "Evasiveness";
default: default:
return '???'; return "???";
} }
} }
@ -34,30 +34,30 @@ export function getBattleStatLevelChangeDescription(levels: integer, up: boolean
if (up) { if (up) {
switch (levels) { switch (levels) {
case 1: case 1:
return 'rose'; return "rose";
case 2: case 2:
return 'sharply rose'; return "sharply rose";
case 3: case 3:
case 4: case 4:
case 5: case 5:
case 6: case 6:
return 'rose drastically'; return "rose drastically";
default: default:
return 'won\'t go any higher'; return "won't go any higher";
} }
} else { } else {
switch (levels) { switch (levels) {
case 1: case 1:
return 'fell'; return "fell";
case 2: case 2:
return 'harshly fell'; return "harshly fell";
case 3: case 3:
case 4: case 4:
case 5: case 5:
case 6: case 6:
return 'severely fell'; return "severely fell";
default: default:
return 'won\'t go any lower'; return "won't go any lower";
} }
} }
} }

View File

@ -56,7 +56,7 @@ export class BattlerTag {
} }
getDescriptor(): string { getDescriptor(): string {
return ''; return "";
} }
isSourceLinked(): boolean { isSourceLinked(): boolean {
@ -97,13 +97,13 @@ export class RechargingTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.getMoveQueue().push({ move: Moves.NONE, targets: [] }) pokemon.getMoveQueue().push({ move: Moves.NONE, targets: [] });
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
super.lapse(pokemon, lapseType); super.lapse(pokemon, lapseType);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' must\nrecharge!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " must\nrecharge!"));
(pokemon.scene.getCurrentPhase() as MovePhase).cancel(); (pokemon.scene.getCurrentPhase() as MovePhase).cancel();
pokemon.getMoveQueue().shift(); pokemon.getMoveQueue().shift();
@ -136,7 +136,7 @@ export class TrappedTag extends BattlerTag {
} }
getDescriptor(): string { getDescriptor(): string {
return 'trapping'; return "trapping";
} }
isSourceLinked(): boolean { isSourceLinked(): boolean {
@ -144,7 +144,7 @@ export class TrappedTag extends BattlerTag {
} }
getTrapMessage(pokemon: Pokemon): string { getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon, ' can no\nlonger escape!'); return getPokemonMessage(pokemon, " can no\nlonger escape!");
} }
} }
@ -167,36 +167,36 @@ export class FlinchedTag extends BattlerTag {
super.lapse(pokemon, lapseType); super.lapse(pokemon, lapseType);
(pokemon.scene.getCurrentPhase() as MovePhase).cancel(); (pokemon.scene.getCurrentPhase() as MovePhase).cancel();
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' flinched!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " flinched!"));
return true; return true;
} }
getDescriptor(): string { getDescriptor(): string {
return 'flinching'; return "flinching";
} }
} }
export class InterruptedTag extends BattlerTag { export class InterruptedTag extends BattlerTag {
constructor(sourceMove: Moves){ constructor(sourceMove: Moves){
super(BattlerTagType.INTERRUPTED, BattlerTagLapseType.PRE_MOVE, 0, sourceMove) super(BattlerTagType.INTERRUPTED, BattlerTagLapseType.PRE_MOVE, 0, sourceMove);
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
return !!pokemon.getTag(BattlerTagType.FLYING) return !!pokemon.getTag(BattlerTagType.FLYING);
} }
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.getMoveQueue().shift() pokemon.getMoveQueue().shift();
pokemon.pushMoveHistory({move: Moves.NONE, result: MoveResult.OTHER}) pokemon.pushMoveHistory({move: Moves.NONE, result: MoveResult.OTHER});
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
super.lapse(pokemon, lapseType); super.lapse(pokemon, lapseType);
(pokemon.scene.getCurrentPhase() as MovePhase).cancel(); (pokemon.scene.getCurrentPhase() as MovePhase).cancel();
return true return true;
} }
} }
@ -213,33 +213,33 @@ export class ConfusedTag extends BattlerTag {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION)); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' became\nconfused!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " became\nconfused!"));
} }
onRemove(pokemon: Pokemon): void { onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon); super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' snapped\nout of confusion!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " snapped\nout of confusion!"));
} }
onOverlap(pokemon: Pokemon): void { onOverlap(pokemon: Pokemon): void {
super.onOverlap(pokemon); super.onOverlap(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nalready confused!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nalready confused!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM && super.lapse(pokemon, lapseType); const ret = lapseType !== BattlerTagLapseType.CUSTOM && super.lapse(pokemon, lapseType);
if (ret) { if (ret) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nconfused!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nconfused!"));
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION)); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION));
if (pokemon.randSeedInt(3)) { if (pokemon.randSeedInt(3)) {
const atk = pokemon.getBattleStat(Stat.ATK); const atk = pokemon.getBattleStat(Stat.ATK);
const def = pokemon.getBattleStat(Stat.DEF); const def = pokemon.getBattleStat(Stat.DEF);
const damage = Math.ceil(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedInt(15, 85) / 100)); const damage = Math.ceil(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedInt(15, 85) / 100));
pokemon.scene.queueMessage('It hurt itself in its\nconfusion!'); pokemon.scene.queueMessage("It hurt itself in its\nconfusion!");
pokemon.damageAndUpdate(damage); pokemon.damageAndUpdate(damage);
pokemon.battleData.hitCount++; pokemon.battleData.hitCount++;
(pokemon.scene.getCurrentPhase() as MovePhase).cancel(); (pokemon.scene.getCurrentPhase() as MovePhase).cancel();
@ -250,7 +250,7 @@ export class ConfusedTag extends BattlerTag {
} }
getDescriptor(): string { getDescriptor(): string {
return 'confusion'; return "confusion";
} }
} }
@ -272,7 +272,7 @@ export class InfatuatedTag extends BattlerTag {
onOverlap(pokemon: Pokemon): void { onOverlap(pokemon: Pokemon): void {
super.onOverlap(pokemon); super.onOverlap(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nalready in love!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nalready in love!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -283,7 +283,7 @@ export class InfatuatedTag extends BattlerTag {
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT)); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT));
if (pokemon.randSeedInt(2)) { if (pokemon.randSeedInt(2)) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nimmobilized by love!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nimmobilized by love!"));
(pokemon.scene.getCurrentPhase() as MovePhase).cancel(); (pokemon.scene.getCurrentPhase() as MovePhase).cancel();
} }
} }
@ -294,7 +294,7 @@ export class InfatuatedTag extends BattlerTag {
onRemove(pokemon: Pokemon): void { onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon); super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' got over\nits infatuation.')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " got over\nits infatuation."));
} }
isSourceLinked(): boolean { isSourceLinked(): boolean {
@ -302,7 +302,7 @@ export class InfatuatedTag extends BattlerTag {
} }
getDescriptor(): string { getDescriptor(): string {
return 'infatuation'; return "infatuation";
} }
} }
@ -329,7 +329,7 @@ export class SeedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' was seeded!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " was seeded!"));
this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex(); this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex();
} }
@ -349,7 +349,7 @@ export class SeedTag extends BattlerTag {
const reverseDrain = pokemon.hasAbilityWithAttr(ReverseDrainAbAttr); const reverseDrain = pokemon.hasAbilityWithAttr(ReverseDrainAbAttr);
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, source.getBattlerIndex(), pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, source.getBattlerIndex(),
!reverseDrain ? damage : damage * -1, !reverseDrain ? damage : damage * -1,
!reverseDrain ? getPokemonMessage(pokemon, '\'s health is\nsapped by Leech Seed!') : getPokemonMessage(source, '\'s Leech Seed\nsucked up the liquid ooze!'), !reverseDrain ? getPokemonMessage(pokemon, "'s health is\nsapped by Leech Seed!") : getPokemonMessage(source, "'s Leech Seed\nsucked up the liquid ooze!"),
false, true)); false, true));
} }
} }
@ -359,7 +359,7 @@ export class SeedTag extends BattlerTag {
} }
getDescriptor(): string { getDescriptor(): string {
return 'seeding'; return "seeding";
} }
} }
@ -371,34 +371,35 @@ export class NightmareTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' began\nhaving a Nightmare!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " began\nhaving a Nightmare!"));
} }
onOverlap(pokemon: Pokemon): void { onOverlap(pokemon: Pokemon): void {
super.onOverlap(pokemon); super.onOverlap(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nalready locked in a Nightmare!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nalready locked in a Nightmare!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) { if (ret) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is locked\nin a Nightmare!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is locked\nin a Nightmare!"));
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CURSE)); // TODO: Update animation type pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CURSE)); // TODO: Update animation type
const cancelled = new Utils.BooleanHolder(false); const cancelled = new Utils.BooleanHolder(false);
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
if (!cancelled.value) if (!cancelled.value) {
pokemon.damageAndUpdate(Math.ceil(pokemon.getMaxHp() / 4)); pokemon.damageAndUpdate(Math.ceil(pokemon.getMaxHp() / 4));
} }
}
return ret; return ret;
} }
getDescriptor(): string { getDescriptor(): string {
return 'nightmares'; return "nightmares";
} }
} }
@ -437,17 +438,20 @@ export class EncoreTag extends BattlerTag {
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
if (pokemon.isMax()) if (pokemon.isMax()) {
return false; return false;
}
const lastMoves = pokemon.getLastXMoves(1); const lastMoves = pokemon.getLastXMoves(1);
if (!lastMoves.length) if (!lastMoves.length) {
return false; return false;
}
const repeatableMove = lastMoves[0]; const repeatableMove = lastMoves[0];
if (!repeatableMove.move || repeatableMove.virtual) if (!repeatableMove.move || repeatableMove.virtual) {
return false; return false;
}
switch (repeatableMove.move) { switch (repeatableMove.move) {
case Moves.MIMIC: case Moves.MIMIC:
@ -460,8 +464,9 @@ export class EncoreTag extends BattlerTag {
return false; return false;
} }
if (allMoves[repeatableMove.move].getAttrs(ChargeAttr).length && repeatableMove.result === MoveResult.OTHER) if (allMoves[repeatableMove.move].getAttrs(ChargeAttr).length && repeatableMove.result === MoveResult.OTHER) {
return false; return false;
}
this.moveId = repeatableMove.move; this.moveId = repeatableMove.move;
@ -471,7 +476,7 @@ export class EncoreTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onRemove(pokemon); super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' got\nan Encore!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " got\nan Encore!"));
const movePhase = pokemon.scene.findPhase(m => m instanceof MovePhase && m.pokemon === pokemon); const movePhase = pokemon.scene.findPhase(m => m instanceof MovePhase && m.pokemon === pokemon);
if (movePhase) { if (movePhase) {
@ -487,7 +492,7 @@ export class EncoreTag extends BattlerTag {
onRemove(pokemon: Pokemon): void { onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon); super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\'s Encore\nended!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, "'s Encore\nended!"));
} }
} }
@ -524,19 +529,20 @@ export class IngrainTag extends TrappedTag {
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) if (ret) {
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), Math.floor(pokemon.getMaxHp() / 16), pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), Math.floor(pokemon.getMaxHp() / 16),
getPokemonMessage(pokemon, ` absorbed\nnutrients with its roots!`), true)); getPokemonMessage(pokemon, " absorbed\nnutrients with its roots!"), true));
}
return ret; return ret;
} }
getTrapMessage(pokemon: Pokemon): string { getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon, ' planted its roots!'); return getPokemonMessage(pokemon, " planted its roots!");
} }
getDescriptor(): string { getDescriptor(): string {
return 'roots'; return "roots";
} }
} }
@ -548,15 +554,16 @@ export class AquaRingTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' surrounded\nitself with a veil of water!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " surrounded\nitself with a veil of water!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) if (ret) {
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(),
Math.floor(pokemon.getMaxHp() / 16), `${this.getMoveName()} restored\n${pokemon.name}\'s HP!`, true)); Math.floor(pokemon.getMaxHp() / 16), `${this.getMoveName()} restored\n${pokemon.name}\'s HP!`, true));
}
return ret; return ret;
} }
@ -579,7 +586,7 @@ export class MinimizeTag extends BattlerTag {
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
//If a pokemon dynamaxes they lose minimized status //If a pokemon dynamaxes they lose minimized status
if(pokemon.isMax()){ if(pokemon.isMax()){
return false return false;
} }
return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
} }
@ -601,7 +608,7 @@ export class DrowsyTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' grew drowsy!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " grew drowsy!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -614,7 +621,7 @@ export class DrowsyTag extends BattlerTag {
} }
getDescriptor(): string { getDescriptor(): string {
return 'drowsiness'; return "drowsiness";
} }
} }
@ -650,8 +657,9 @@ export abstract class DamagingTrapTag extends TrappedTag {
const cancelled = new Utils.BooleanHolder(false); const cancelled = new Utils.BooleanHolder(false);
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
if (!cancelled.value) if (!cancelled.value) {
pokemon.damageAndUpdate(Math.ceil(pokemon.getMaxHp() / 8)) pokemon.damageAndUpdate(Math.ceil(pokemon.getMaxHp() / 8));
}
} }
return ret; return ret;
@ -684,7 +692,7 @@ export abstract class VortexTrapTag extends DamagingTrapTag {
} }
getTrapMessage(pokemon: Pokemon): string { getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon, ' was trapped\nin the vortex!'); return getPokemonMessage(pokemon, " was trapped\nin the vortex!");
} }
} }
@ -726,7 +734,7 @@ export class MagmaStormTag extends DamagingTrapTag {
} }
getTrapMessage(pokemon: Pokemon): string { getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon, ` became trapped\nby swirling magma!`); return getPokemonMessage(pokemon, " became trapped\nby swirling magma!");
} }
} }
@ -736,7 +744,7 @@ export class SnapTrapTag extends DamagingTrapTag {
} }
getTrapMessage(pokemon: Pokemon): string { getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon, ` got trapped\nby a snap trap!`); return getPokemonMessage(pokemon, " got trapped\nby a snap trap!");
} }
} }
@ -769,13 +777,13 @@ export class ProtectedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\nprotected itself!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, "\nprotected itself!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.CUSTOM) { if (lapseType === BattlerTagLapseType.CUSTOM) {
new CommonBattleAnim(CommonAnim.PROTECT, pokemon).play(pokemon.scene); new CommonBattleAnim(CommonAnim.PROTECT, pokemon).play(pokemon.scene);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\nprotected itself!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, "\nprotected itself!"));
return true; return true;
} }
@ -900,12 +908,12 @@ export class EnduringTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' braced\nitself!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " braced\nitself!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.CUSTOM) { if (lapseType === BattlerTagLapseType.CUSTOM) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' endured\nthe hit!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " endured\nthe hit!"));
return true; return true;
} }
@ -920,7 +928,7 @@ export class SturdyTag extends BattlerTag {
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.CUSTOM) { if (lapseType === BattlerTagLapseType.CUSTOM) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' endured\nthe hit!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " endured\nthe hit!"));
return true; return true;
} }
@ -940,10 +948,11 @@ export class PerishSongTag extends BattlerTag {
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = super.lapse(pokemon, lapseType); const ret = super.lapse(pokemon, lapseType);
if (ret) if (ret) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, `\'s perish count fell to ${this.turnCount}.`)); pokemon.scene.queueMessage(getPokemonMessage(pokemon, `\'s perish count fell to ${this.turnCount}.`));
else } else {
pokemon.damageAndUpdate(pokemon.hp, HitResult.ONE_HIT_KO, false, true, true); pokemon.damageAndUpdate(pokemon.hp, HitResult.ONE_HIT_KO, false, true, true);
}
return ret; return ret;
} }
@ -974,8 +983,9 @@ export class TruantTag extends AbilityBattlerTag {
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (!pokemon.hasAbility(Abilities.TRUANT)) if (!pokemon.hasAbility(Abilities.TRUANT)) {
return super.lapse(pokemon, lapseType); return super.lapse(pokemon, lapseType);
}
const passive = pokemon.getAbility().id !== Abilities.TRUANT; const passive = pokemon.getAbility().id !== Abilities.TRUANT;
const lastMove = pokemon.getLastXMoves().find(() => true); const lastMove = pokemon.getLastXMoves().find(() => true);
@ -983,7 +993,7 @@ export class TruantTag extends AbilityBattlerTag {
if (lastMove && lastMove.move !== Moves.NONE) { if (lastMove && lastMove.move !== Moves.NONE) {
(pokemon.scene.getCurrentPhase() as MovePhase).cancel(); (pokemon.scene.getCurrentPhase() as MovePhase).cancel();
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.id, passive)); pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.id, passive));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nloafing around!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nloafing around!"));
} }
return true; return true;
@ -998,12 +1008,13 @@ export class SlowStartTag extends AbilityBattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' can\'t\nget it going!'), null, false, null, true); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " can't\nget it going!"), null, false, null, true);
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (!pokemon.hasAbility(this.ability)) if (!pokemon.hasAbility(this.ability)) {
this.turnCount = 1; this.turnCount = 1;
}
return super.lapse(pokemon, lapseType); return super.lapse(pokemon, lapseType);
} }
@ -1011,7 +1022,7 @@ export class SlowStartTag extends AbilityBattlerTag {
onRemove(pokemon: Pokemon): void { onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon); super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' finally\ngot its act together!'), null, false, null); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " finally\ngot its act together!"), null, false, null);
} }
} }
@ -1182,7 +1193,7 @@ export class CritBoostTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is getting\npumped!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is getting\npumped!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -1192,7 +1203,7 @@ export class CritBoostTag extends BattlerTag {
onRemove(pokemon: Pokemon): void { onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon); super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' relaxed.')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " relaxed."));
} }
} }
@ -1227,7 +1238,7 @@ export class SaltCuredTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is being salt cured!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is being salt cured!"));
this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex(); this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex();
} }
@ -1271,7 +1282,7 @@ export class CursedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' has been cursed!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " has been cursed!"));
this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex(); this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex();
} }

View File

@ -1,13 +1,12 @@
import { PokemonHealPhase, StatChangePhase } from "../phases"; import { PokemonHealPhase, StatChangePhase } from "../phases";
import { getPokemonMessage } from "../messages"; import { getPokemonMessage } from "../messages";
import Pokemon, { HitResult } from "../field/pokemon"; import Pokemon, { HitResult } from "../field/pokemon";
import { getBattleStatName } from "./battle-stat";
import { BattleStat } from "./battle-stat"; import { BattleStat } from "./battle-stat";
import { BattlerTagType } from "./enums/battler-tag-type"; import { BattlerTagType } from "./enums/battler-tag-type";
import { getStatusEffectHealText } from "./status-effect"; import { getStatusEffectHealText } from "./status-effect";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { DoubleBerryEffectAbAttr, ReduceBerryUseThresholdAbAttr, applyAbAttrs } from "./ability"; import { DoubleBerryEffectAbAttr, ReduceBerryUseThresholdAbAttr, applyAbAttrs } from "./ability";
import i18next from '../plugins/i18n'; import i18next from "../plugins/i18n";
export enum BerryType { export enum BerryType {
SITRUS, SITRUS,
@ -80,8 +79,9 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
case BerryType.SITRUS: case BerryType.SITRUS:
case BerryType.ENIGMA: case BerryType.ENIGMA:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
if (pokemon.battleData) if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType); pokemon.battleData.berriesEaten.push(berryType);
}
const hpHealed = new Utils.NumberHolder(Math.floor(pokemon.getMaxHp() / 4)); const hpHealed = new Utils.NumberHolder(Math.floor(pokemon.getMaxHp() / 4));
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, hpHealed); applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, hpHealed);
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(),
@ -89,15 +89,17 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
}; };
case BerryType.LUM: case BerryType.LUM:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
if (pokemon.battleData) if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType); pokemon.battleData.berriesEaten.push(berryType);
}
if (pokemon.status) { if (pokemon.status) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(pokemon.status.effect))); pokemon.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(pokemon.status.effect)));
pokemon.resetStatus(); pokemon.resetStatus();
pokemon.updateInfo(); pokemon.updateInfo();
} }
if (pokemon.getTag(BattlerTagType.CONFUSED)) if (pokemon.getTag(BattlerTagType.CONFUSED)) {
pokemon.lapseTag(BattlerTagType.CONFUSED); pokemon.lapseTag(BattlerTagType.CONFUSED);
}
}; };
case BerryType.LIECHI: case BerryType.LIECHI:
case BerryType.GANLON: case BerryType.GANLON:
@ -105,8 +107,9 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
case BerryType.APICOT: case BerryType.APICOT:
case BerryType.SALAC: case BerryType.SALAC:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
if (pokemon.battleData) if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType); pokemon.battleData.berriesEaten.push(berryType);
}
const battleStat = (berryType - BerryType.LIECHI) as BattleStat; const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
const statLevels = new Utils.NumberHolder(1); const statLevels = new Utils.NumberHolder(1);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels); applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels);
@ -114,22 +117,25 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
}; };
case BerryType.LANSAT: case BerryType.LANSAT:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
if (pokemon.battleData) if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType); pokemon.battleData.berriesEaten.push(berryType);
}
pokemon.addTag(BattlerTagType.CRIT_BOOST); pokemon.addTag(BattlerTagType.CRIT_BOOST);
}; };
case BerryType.STARF: case BerryType.STARF:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
if (pokemon.battleData) if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType); pokemon.battleData.berriesEaten.push(berryType);
}
const statLevels = new Utils.NumberHolder(2); const statLevels = new Utils.NumberHolder(2);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels); applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ BattleStat.RAND ], statLevels.value)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ BattleStat.RAND ], statLevels.value));
}; };
case BerryType.LEPPA: case BerryType.LEPPA:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
if (pokemon.battleData) if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType); pokemon.battleData.berriesEaten.push(berryType);
}
const ppRestoreMove = pokemon.getMoveset().find(m => !m.getPpRatio()) ? pokemon.getMoveset().find(m => !m.getPpRatio()) : pokemon.getMoveset().find(m => m.getPpRatio() < 1); const ppRestoreMove = pokemon.getMoveset().find(m => !m.getPpRatio()) ? pokemon.getMoveset().find(m => !m.getPpRatio()) : pokemon.getMoveset().find(m => m.getPpRatio() < 1);
if(ppRestoreMove !== undefined){ if(ppRestoreMove !== undefined){
ppRestoreMove.ppUsed = Math.max(ppRestoreMove.ppUsed - 10, 0); ppRestoreMove.ppUsed = Math.max(ppRestoreMove.ppUsed - 10, 0);

View File

@ -1,26 +1,27 @@
import { Species } from "./enums/species"; import { Species } from "./enums/species";
import { Type } from './type'; import { Type } from "./type";
import * as Utils from '../utils'; import * as Utils from "../utils";
import beautify from 'json-beautify'; import beautify from "json-beautify";
import { TrainerType } from "./enums/trainer-type"; import { TrainerType } from "./enums/trainer-type";
import { TimeOfDay } from "./enums/time-of-day"; import { TimeOfDay } from "./enums/time-of-day";
import { Biome } from "./enums/biome"; import { Biome } from "./enums/biome";
import { SpeciesFormEvolution } from "./pokemon-evolutions"; import { SpeciesFormEvolution } from "./pokemon-evolutions";
export function getBiomeName(biome: Biome | -1) { export function getBiomeName(biome: Biome | -1) {
if (biome === -1) if (biome === -1) {
return 'Somewhere you can\'t remember'; return "Somewhere you can't remember";
}
switch (biome) { switch (biome) {
case Biome.GRASS: case Biome.GRASS:
return 'Grassy Field'; return "Grassy Field";
case Biome.RUINS: case Biome.RUINS:
return 'Ancient Ruins'; return "Ancient Ruins";
case Biome.ABYSS: case Biome.ABYSS:
return 'The Abyss'; return "The Abyss";
case Biome.SPACE: case Biome.SPACE:
return 'Stratosphere'; return "Stratosphere";
case Biome.END: case Biome.END:
return 'Final Destination'; return "Final Destination";
default: default:
return Utils.toReadableString(Biome[biome]); return Utils.toReadableString(Biome[biome]);
} }
@ -83,7 +84,7 @@ export enum BiomePoolTier {
BOSS_RARE, BOSS_RARE,
BOSS_SUPER_RARE, BOSS_SUPER_RARE,
BOSS_ULTRA_RARE BOSS_ULTRA_RARE
}; }
export const uncatchableSpecies: Species[] = []; export const uncatchableSpecies: Species[] = [];
@ -7659,7 +7660,7 @@ export const biomeTrainerPools: BiomeTrainerPools = {
const linkedBiomes: (Biome | [ Biome, integer ])[] = Array.isArray(biomeLinks[biome]) const linkedBiomes: (Biome | [ Biome, integer ])[] = Array.isArray(biomeLinks[biome])
? biomeLinks[biome] as (Biome | [ Biome, integer ])[] ? biomeLinks[biome] as (Biome | [ Biome, integer ])[]
: [ biomeLinks[biome] as Biome ]; : [ biomeLinks[biome] as Biome ];
for (let linkedBiomeEntry of linkedBiomes) { for (const linkedBiomeEntry of linkedBiomes) {
const linkedBiome = !Array.isArray(linkedBiomeEntry) const linkedBiome = !Array.isArray(linkedBiomeEntry)
? linkedBiomeEntry as Biome ? linkedBiomeEntry as Biome
: linkedBiomeEntry[0]; : linkedBiomeEntry[0];
@ -7676,22 +7677,23 @@ export const biomeTrainerPools: BiomeTrainerPools = {
traverseBiome(Biome.TOWN, 0); traverseBiome(Biome.TOWN, 0);
biomeDepths[Biome.END] = [ Object.values(biomeDepths).map(d => d[0]).reduce((max: integer, value: integer) => Math.max(max, value), 0) + 1, 1 ]; biomeDepths[Biome.END] = [ Object.values(biomeDepths).map(d => d[0]).reduce((max: integer, value: integer) => Math.max(max, value), 0) + 1, 1 ];
import('./pokemon-evolutions').then(pe => { import("./pokemon-evolutions").then(pe => {
const pokemonEvolutions = pe.pokemonEvolutions; const pokemonEvolutions = pe.pokemonEvolutions;
for (let biome of Utils.getEnumValues(Biome)) { for (const biome of Utils.getEnumValues(Biome)) {
biomePokemonPools[biome] = {}; biomePokemonPools[biome] = {};
biomeTrainerPools[biome] = {}; biomeTrainerPools[biome] = {};
for (let tier of Utils.getEnumValues(BiomePoolTier)) { for (const tier of Utils.getEnumValues(BiomePoolTier)) {
biomePokemonPools[biome][tier] = {}; biomePokemonPools[biome][tier] = {};
biomeTrainerPools[biome][tier] = []; biomeTrainerPools[biome][tier] = [];
for (let tod of Utils.getEnumValues(TimeOfDay)) for (const tod of Utils.getEnumValues(TimeOfDay)) {
biomePokemonPools[biome][tier][tod] = []; biomePokemonPools[biome][tier][tod] = [];
} }
} }
}
for (let pb of pokemonBiomes) { for (const pb of pokemonBiomes) {
const speciesId = pb[0] as Species; const speciesId = pb[0] as Species;
const biomeEntries = pb[3] as (Biome | BiomePoolTier)[][]; const biomeEntries = pb[3] as (Biome | BiomePoolTier)[][];
@ -7699,10 +7701,11 @@ export const biomeTrainerPools: BiomeTrainerPools = {
? pokemonEvolutions[speciesId] ? pokemonEvolutions[speciesId]
: []; : [];
if (!biomeEntries.filter(b => b[0] !== Biome.END).length && !speciesEvolutions.filter(es => !!((pokemonBiomes.find(p => p[0] === es.speciesId))[3] as any[]).filter(b => b[0] !== Biome.END).length).length) if (!biomeEntries.filter(b => b[0] !== Biome.END).length && !speciesEvolutions.filter(es => !!((pokemonBiomes.find(p => p[0] === es.speciesId))[3] as any[]).filter(b => b[0] !== Biome.END).length).length) {
uncatchableSpecies.push(speciesId); uncatchableSpecies.push(speciesId);
}
for (let b of biomeEntries) { for (const b of biomeEntries) {
const biome = b[0]; const biome = b[0];
const tier = b[1]; const tier = b[1];
const timesOfDay = b.length > 2 const timesOfDay = b.length > 2
@ -7711,9 +7714,10 @@ export const biomeTrainerPools: BiomeTrainerPools = {
: [ b[2] ] : [ b[2] ]
: [ TimeOfDay.ALL ]; : [ TimeOfDay.ALL ];
for (let tod of timesOfDay) { for (const tod of timesOfDay) {
if (!biomePokemonPools.hasOwnProperty(biome) || !biomePokemonPools[biome].hasOwnProperty(tier) || !biomePokemonPools[biome][tier].hasOwnProperty(tod)) if (!biomePokemonPools.hasOwnProperty(biome) || !biomePokemonPools[biome].hasOwnProperty(tier) || !biomePokemonPools[biome][tier].hasOwnProperty(tod)) {
continue; continue;
}
const biomeTierPool = biomePokemonPools[biome][tier][tod]; const biomeTierPool = biomePokemonPools[biome][tier][tod];
@ -7734,28 +7738,30 @@ export const biomeTrainerPools: BiomeTrainerPools = {
break; break;
} }
} }
if (treeIndex > -1) if (treeIndex > -1) {
break; break;
} }
}
if (treeIndex > -1) if (treeIndex > -1) {
(biomeTierPool[treeIndex] as unknown as Species[]).splice(arrayIndex, 0, speciesId); (biomeTierPool[treeIndex] as unknown as Species[]).splice(arrayIndex, 0, speciesId);
else } else {
(biomeTierPool as unknown as Species[][]).push([ speciesId ]); (biomeTierPool as unknown as Species[][]).push([ speciesId ]);
} }
} }
} }
}
for (let b of Object.keys(biomePokemonPools)) { for (const b of Object.keys(biomePokemonPools)) {
for (let t of Object.keys(biomePokemonPools[b])) { for (const t of Object.keys(biomePokemonPools[b])) {
const tier = parseInt(t) as BiomePoolTier; const tier = parseInt(t) as BiomePoolTier;
for (let tod of Object.keys(biomePokemonPools[b][t])) { for (const tod of Object.keys(biomePokemonPools[b][t])) {
const biomeTierTimePool = biomePokemonPools[b][t][tod]; const biomeTierTimePool = biomePokemonPools[b][t][tod];
for (let e = 0; e < biomeTierTimePool.length; e++) { for (let e = 0; e < biomeTierTimePool.length; e++) {
const entry = biomeTierTimePool[e]; const entry = biomeTierTimePool[e];
if (entry.length === 1) if (entry.length === 1) {
biomeTierTimePool[e] = entry[0]; biomeTierTimePool[e] = entry[0];
else { } else {
const newEntry = { const newEntry = {
1: [ entry[0] ] 1: [ entry[0] ]
}; };
@ -7763,11 +7769,12 @@ export const biomeTrainerPools: BiomeTrainerPools = {
const speciesId = entry[s]; const speciesId = entry[s];
const prevolution = entry.map(s => pokemonEvolutions[s]).flat().find(e => e && e.speciesId === speciesId); const prevolution = entry.map(s => pokemonEvolutions[s]).flat().find(e => e && e.speciesId === speciesId);
const level = prevolution.level - (prevolution.level === 1 ? 1 : 0) + (prevolution.wildDelay * 10) - (tier >= BiomePoolTier.BOSS ? 10 : 0); const level = prevolution.level - (prevolution.level === 1 ? 1 : 0) + (prevolution.wildDelay * 10) - (tier >= BiomePoolTier.BOSS ? 10 : 0);
if (!newEntry.hasOwnProperty(level)) if (!newEntry.hasOwnProperty(level)) {
newEntry[level] = [ speciesId ]; newEntry[level] = [ speciesId ];
else } else {
newEntry[level].push(speciesId); newEntry[level].push(speciesId);
} }
}
biomeTierTimePool[e] = newEntry; biomeTierTimePool[e] = newEntry;
} }
} }
@ -7775,16 +7782,17 @@ export const biomeTrainerPools: BiomeTrainerPools = {
} }
} }
for (let tb of trainerBiomes) { for (const tb of trainerBiomes) {
const trainerType = tb[0] as TrainerType; const trainerType = tb[0] as TrainerType;
const biomeEntries = tb[1] as BiomePoolTier[][]; const biomeEntries = tb[1] as BiomePoolTier[][];
for (let b of biomeEntries) { for (const b of biomeEntries) {
const biome = b[0]; const biome = b[0];
const tier = b[1]; const tier = b[1];
if (!biomeTrainerPools.hasOwnProperty(biome) || !biomeTrainerPools[biome].hasOwnProperty(tier)) if (!biomeTrainerPools.hasOwnProperty(biome) || !biomeTrainerPools[biome].hasOwnProperty(tier)) {
continue; continue;
}
const biomeTierPool = biomeTrainerPools[biome][tier]; const biomeTierPool = biomeTrainerPools[biome][tier];
biomeTierPool.push(trainerType); biomeTierPool.push(trainerType);
@ -7794,32 +7802,34 @@ export const biomeTrainerPools: BiomeTrainerPools = {
//outputPools(); //outputPools();
}); });
// used in a commented code
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function outputPools() { function outputPools() {
const pokemonOutput = {}; const pokemonOutput = {};
const trainerOutput = {}; const trainerOutput = {};
for (let b of Object.keys(biomePokemonPools)) { for (const b of Object.keys(biomePokemonPools)) {
const biome = Biome[b]; const biome = Biome[b];
pokemonOutput[biome] = {}; pokemonOutput[biome] = {};
trainerOutput[biome] = {}; trainerOutput[biome] = {};
for (let t of Object.keys(biomePokemonPools[b])) { for (const t of Object.keys(biomePokemonPools[b])) {
const tier = BiomePoolTier[t]; const tier = BiomePoolTier[t];
pokemonOutput[biome][tier] = {}; pokemonOutput[biome][tier] = {};
for (let tod of Object.keys(biomePokemonPools[b][t])) { for (const tod of Object.keys(biomePokemonPools[b][t])) {
const timeOfDay = TimeOfDay[tod]; const timeOfDay = TimeOfDay[tod];
pokemonOutput[biome][tier][timeOfDay] = []; pokemonOutput[biome][tier][timeOfDay] = [];
for (let f of biomePokemonPools[b][t][tod]) { for (const f of biomePokemonPools[b][t][tod]) {
if (typeof f === 'number') if (typeof f === "number") {
pokemonOutput[biome][tier][timeOfDay].push(Species[f]); pokemonOutput[biome][tier][timeOfDay].push(Species[f]);
else { } else {
const tree = {}; const tree = {};
for (let l of Object.keys(f)) { for (const l of Object.keys(f)) {
tree[l] = f[l].map(s => Species[s]); tree[l] = f[l].map(s => Species[s]);
} }
@ -7830,18 +7840,19 @@ export const biomeTrainerPools: BiomeTrainerPools = {
} }
} }
for (let t of Object.keys(biomeTrainerPools[b])) { for (const t of Object.keys(biomeTrainerPools[b])) {
const tier = BiomePoolTier[t]; const tier = BiomePoolTier[t];
trainerOutput[biome][tier] = []; trainerOutput[biome][tier] = [];
for (let f of biomeTrainerPools[b][t]) for (const f of biomeTrainerPools[b][t]) {
trainerOutput[biome][tier].push(TrainerType[f]); trainerOutput[biome][tier].push(TrainerType[f]);
} }
} }
}
console.log(beautify(pokemonOutput, null, 2, 180).replace(/( | (?:\{ "\d+": \[ )?| "(?:.*?)": \[ |(?:,|\[) (?:"\w+": \[ |(?:\{ )?"\d+": \[ )?)"(\w+)"(?= |,|\n)/g, '$1Species.$2').replace(/"(\d+)": /g, '$1: ').replace(/((?: )|(?:(?!\n) "(?:.*?)": \{) |\[(?: .*? )?\], )"(\w+)"/g, '$1[TimeOfDay.$2]').replace(/( )"(.*?)"/g, '$1[BiomePoolTier.$2]').replace(/( )"(.*?)"/g, '$1[Biome.$2]')); console.log(beautify(pokemonOutput, null, 2, 180).replace(/( | (?:\{ "\d+": \[ )?| "(?:.*?)": \[ |(?:,|\[) (?:"\w+": \[ |(?:\{ )?"\d+": \[ )?)"(\w+)"(?= |,|\n)/g, "$1Species.$2").replace(/"(\d+)": /g, "$1: ").replace(/((?: )|(?:(?!\n) "(?:.*?)": \{) |\[(?: .*? )?\], )"(\w+)"/g, "$1[TimeOfDay.$2]").replace(/( )"(.*?)"/g, "$1[BiomePoolTier.$2]").replace(/( )"(.*?)"/g, "$1[Biome.$2]"));
console.log(beautify(trainerOutput, null, 2, 120).replace(/( | (?:\{ "\d+": \[ )?| "(?:.*?)": \[ |, (?:(?:\{ )?"\d+": \[ )?)"(.*?)"/g, '$1TrainerType.$2').replace(/"(\d+)": /g, '$1: ').replace(/( )"(.*?)"/g, '$1[BiomePoolTier.$2]').replace(/( )"(.*?)"/g, '$1[Biome.$2]')); console.log(beautify(trainerOutput, null, 2, 120).replace(/( | (?:\{ "\d+": \[ )?| "(?:.*?)": \[ |, (?:(?:\{ )?"\d+": \[ )?)"(.*?)"/g, "$1TrainerType.$2").replace(/"(\d+)": /g, "$1: ").replace(/( )"(.*?)"/g, "$1[BiomePoolTier.$2]").replace(/( )"(.*?)"/g, "$1[Biome.$2]"));
} }
/*for (let pokemon of allSpecies) { /*for (let pokemon of allSpecies) {

View File

@ -14,7 +14,7 @@ export interface DailyRunConfig {
export function fetchDailyRunSeed(): Promise<string> { export function fetchDailyRunSeed(): Promise<string> {
return new Promise<string>((resolve, reject) => { return new Promise<string>((resolve, reject) => {
Utils.apiFetch('daily/seed').then(response => { Utils.apiFetch("daily/seed").then(response => {
if (!response.ok) { if (!response.ok) {
resolve(null); resolve(null);
return; return;

File diff suppressed because it is too large Load Diff

View File

@ -13,16 +13,16 @@ export const speciesEggMoves = {
[Species.PIDGEY]: [ Moves.HEAT_WAVE, Moves.FOCUS_BLAST, Moves.U_TURN, Moves.WILDBOLT_STORM ], [Species.PIDGEY]: [ Moves.HEAT_WAVE, Moves.FOCUS_BLAST, Moves.U_TURN, Moves.WILDBOLT_STORM ],
[Species.RATTATA]: [ Moves.HYPER_FANG, Moves.PSYCHIC_FANGS, Moves.FIRE_FANG, Moves.EXTREME_SPEED ], [Species.RATTATA]: [ Moves.HYPER_FANG, Moves.PSYCHIC_FANGS, Moves.FIRE_FANG, Moves.EXTREME_SPEED ],
[Species.SPEAROW]: [ Moves.FLOATY_FALL, Moves.EXTREME_SPEED, Moves.TIDY_UP, Moves.TRIPLE_ARROWS ], [Species.SPEAROW]: [ Moves.FLOATY_FALL, Moves.EXTREME_SPEED, Moves.TIDY_UP, Moves.TRIPLE_ARROWS ],
[Species.EKANS]: [ Moves.SHED_TAIL, Moves.DRAGON_DANCE, Moves.SLACK_OFF, Moves.NOXIOUS_TORQUE ], [Species.EKANS]: [ Moves.NOXIOUS_TORQUE, Moves.DRAGON_DANCE, Moves.SLACK_OFF, Moves.SHED_TAIL ],
[Species.SANDSHREW]: [ Moves.DIRE_CLAW, Moves.CEASELESS_EDGE, Moves.SHORE_UP, Moves.PRECIPICE_BLADES ], [Species.SANDSHREW]: [ Moves.DIRE_CLAW, Moves.CEASELESS_EDGE, Moves.SHORE_UP, Moves.PRECIPICE_BLADES ],
[Species.NIDORAN_F]: [ Moves.DIRE_CLAW, Moves.SHORE_UP, Moves.THOUSAND_WAVES, Moves.SALT_CURE ], [Species.NIDORAN_F]: [ Moves.NO_RETREAT, Moves.BANEFUL_BUNKER, Moves.SANDSEAR_STORM, Moves.MALIGNANT_CHAIN ],
[Species.NIDORAN_M]: [ Moves.NOXIOUS_TORQUE, Moves.KINGS_SHIELD, Moves.NO_RETREAT, Moves.PRECIPICE_BLADES ], [Species.NIDORAN_M]: [ Moves.NOXIOUS_TORQUE, Moves.KINGS_SHIELD, Moves.NO_RETREAT, Moves.PRECIPICE_BLADES ],
[Species.VULPIX]: [ Moves.MOONBLAST, Moves.PSYCHIC, Moves.MORNING_SUN, Moves.TAIL_GLOW ], [Species.VULPIX]: [ Moves.MOONBLAST, Moves.ICE_BEAM, Moves.MORNING_SUN, Moves.TAIL_GLOW ],
[Species.ZUBAT]: [ Moves.FLOATY_FALL, Moves.DIRE_CLAW, Moves.SWORDS_DANCE, Moves.BRAVE_BIRD ], [Species.ZUBAT]: [ Moves.FLOATY_FALL, Moves.DIRE_CLAW, Moves.SWORDS_DANCE, Moves.WICKED_BLOW ],
[Species.ODDISH]: [ Moves.SLUDGE_BOMB, Moves.FIERY_DANCE, Moves.STRENGTH_SAP, Moves.SPORE ], [Species.ODDISH]: [ Moves.SLUDGE_BOMB, Moves.FIERY_DANCE, Moves.STRENGTH_SAP, Moves.SPORE ],
[Species.PARAS]: [ Moves.FIRST_IMPRESSION, Moves.SAPPY_SEED, Moves.CRABHAMMER, Moves.DIRE_CLAW ], [Species.PARAS]: [ Moves.FIRST_IMPRESSION, Moves.SAPPY_SEED, Moves.CRABHAMMER, Moves.DIRE_CLAW ],
[Species.VENONAT]: [ Moves.SLUDGE_BOMB, Moves.MOONLIGHT, Moves.EARTH_POWER, Moves.MYSTICAL_POWER ], [Species.VENONAT]: [ Moves.SLUDGE_BOMB, Moves.MOONLIGHT, Moves.EARTH_POWER, Moves.MYSTICAL_POWER ],
[Species.DIGLETT]: [ Moves.STRENGTH_SAP, Moves.SWORDS_DANCE, Moves.ICE_SPINNER, Moves.HEADLONG_RUSH ], [Species.DIGLETT]: [ Moves.REVERSAL, Moves.SWORDS_DANCE, Moves.ICE_SPINNER, Moves.HEADLONG_RUSH ],
[Species.MEOWTH]: [ Moves.COVET, Moves.HAPPY_HOUR, Moves.PARTING_SHOT, Moves.MAKE_IT_RAIN ], [Species.MEOWTH]: [ Moves.COVET, Moves.HAPPY_HOUR, Moves.PARTING_SHOT, Moves.MAKE_IT_RAIN ],
[Species.PSYDUCK]: [ Moves.MYSTICAL_POWER, Moves.AQUA_STEP, Moves.AURA_SPHERE, Moves.MIND_BLOWN ], [Species.PSYDUCK]: [ Moves.MYSTICAL_POWER, Moves.AQUA_STEP, Moves.AURA_SPHERE, Moves.MIND_BLOWN ],
[Species.MANKEY]: [ Moves.DRAIN_PUNCH, Moves.RAGING_FURY, Moves.METEOR_MASH, Moves.NO_RETREAT ], [Species.MANKEY]: [ Moves.DRAIN_PUNCH, Moves.RAGING_FURY, Moves.METEOR_MASH, Moves.NO_RETREAT ],
@ -34,18 +34,18 @@ export const speciesEggMoves = {
[Species.TENTACOOL]: [ Moves.BANEFUL_BUNKER, Moves.STRENGTH_SAP, Moves.HAZE, Moves.MALIGNANT_CHAIN ], [Species.TENTACOOL]: [ Moves.BANEFUL_BUNKER, Moves.STRENGTH_SAP, Moves.HAZE, Moves.MALIGNANT_CHAIN ],
[Species.GEODUDE]: [ Moves.BODY_PRESS, Moves.BULK_UP, Moves.SHORE_UP, Moves.HEAD_SMASH ], [Species.GEODUDE]: [ Moves.BODY_PRESS, Moves.BULK_UP, Moves.SHORE_UP, Moves.HEAD_SMASH ],
[Species.PONYTA]: [ Moves.HIGH_HORSEPOWER, Moves.FIRE_LASH, Moves.SWORDS_DANCE, Moves.VOLT_TACKLE ], [Species.PONYTA]: [ Moves.HIGH_HORSEPOWER, Moves.FIRE_LASH, Moves.SWORDS_DANCE, Moves.VOLT_TACKLE ],
[Species.SLOWPOKE]: [ Moves.BOUNCY_BUBBLE, Moves.PARTING_SHOT, Moves.COSMIC_POWER, Moves.LUMINA_CRASH ], [Species.SLOWPOKE]: [ Moves.BOUNCY_BUBBLE, Moves.FLAMETHROWER, Moves.MYSTICAL_POWER, Moves.SHED_TAIL ],
[Species.MAGNEMITE]: [ Moves.PARABOLIC_CHARGE, Moves.BODY_PRESS, Moves.ICE_BEAM, Moves.THUNDERCLAP ], [Species.MAGNEMITE]: [ Moves.PARABOLIC_CHARGE, Moves.BODY_PRESS, Moves.ICE_BEAM, Moves.THUNDERCLAP ],
[Species.FARFETCHD]: [ Moves.BATON_PASS, Moves.SACRED_SWORD, Moves.ROOST, Moves.VICTORY_DANCE ], [Species.FARFETCHD]: [ Moves.BATON_PASS, Moves.SACRED_SWORD, Moves.ROOST, Moves.VICTORY_DANCE ],
[Species.DODUO]: [ Moves.TRIPLE_AXEL, Moves.MULTI_ATTACK, Moves.FLOATY_FALL, Moves.TRIPLE_ARROWS ], [Species.DODUO]: [ Moves.TRIPLE_AXEL, Moves.MULTI_ATTACK, Moves.FLOATY_FALL, Moves.TRIPLE_ARROWS ],
[Species.SEEL]: [ Moves.FREEZE_DRY, Moves.CHILLY_RECEPTION, Moves.SLACK_OFF, Moves.BOUNCY_BUBBLE ], [Species.SEEL]: [ Moves.FREEZE_DRY, Moves.CHILLY_RECEPTION, Moves.SLACK_OFF, Moves.BOUNCY_BUBBLE ],
[Species.GRIMER]: [ Moves.SHADOW_SNEAK, Moves.CURSE, Moves.STRENGTH_SAP, Moves.NOXIOUS_TORQUE ], [Species.GRIMER]: [ Moves.SHADOW_SNEAK, Moves.CURSE, Moves.STRENGTH_SAP, Moves.NOXIOUS_TORQUE ],
[Species.SHELLDER]: [ Moves.ROCK_BLAST, Moves.WATER_SHURIKEN, Moves.BANEFUL_BUNKER, Moves.BONE_RUSH ], [Species.SHELLDER]: [ Moves.ROCK_BLAST, Moves.WATER_SHURIKEN, Moves.BANEFUL_BUNKER, Moves.BONE_RUSH ],
[Species.GASTLY]: [ Moves.FROST_BREATH, Moves.AURA_SPHERE, Moves.NASTY_PLOT, Moves.MALIGNANT_CHAIN ], [Species.GASTLY]: [ Moves.ICE_BEAM, Moves.AURA_SPHERE, Moves.NASTY_PLOT, Moves.MALIGNANT_CHAIN ],
[Species.ONIX]: [ Moves.SHORE_UP, Moves.BODY_PRESS, Moves.HEAD_SMASH, Moves.SPIN_OUT ], [Species.ONIX]: [ Moves.SHORE_UP, Moves.BODY_PRESS, Moves.HEAD_SMASH, Moves.SPIN_OUT ],
[Species.DROWZEE]: [ Moves.DREAM_EATER, Moves.RECOVER, Moves.NIGHTMARE, Moves.SPORE ], [Species.DROWZEE]: [ Moves.DREAM_EATER, Moves.RECOVER, Moves.NIGHTMARE, Moves.SPORE ],
[Species.KRABBY]: [ Moves.ICICLE_CRASH, Moves.LIQUIDATION, Moves.IVY_CUDGEL, Moves.SHELL_SMASH ], [Species.KRABBY]: [ Moves.ICICLE_CRASH, Moves.LIQUIDATION, Moves.IVY_CUDGEL, Moves.SHELL_SMASH ],
[Species.VOLTORB]: [ Moves.BUZZY_BUZZ, Moves.OVERHEAT, Moves.FROST_BREATH, Moves.TAIL_GLOW ], [Species.VOLTORB]: [ Moves.BUZZY_BUZZ, Moves.OVERHEAT, Moves.ICE_BEAM, Moves.TAIL_GLOW ],
[Species.EXEGGCUTE]: [ Moves.MYSTICAL_POWER, Moves.APPLE_ACID, Moves.TRICK_ROOM, Moves.FICKLE_BEAM ], [Species.EXEGGCUTE]: [ Moves.MYSTICAL_POWER, Moves.APPLE_ACID, Moves.TRICK_ROOM, Moves.FICKLE_BEAM ],
[Species.CUBONE]: [ Moves.HEAD_SMASH, Moves.WOOD_HAMMER, Moves.PAIN_SPLIT, Moves.VOLT_TACKLE ], [Species.CUBONE]: [ Moves.HEAD_SMASH, Moves.WOOD_HAMMER, Moves.PAIN_SPLIT, Moves.VOLT_TACKLE ],
[Species.LICKITUNG]: [ Moves.BODY_SLAM, Moves.FIRE_LASH, Moves.GRAV_APPLE, Moves.MILK_DRINK ], [Species.LICKITUNG]: [ Moves.BODY_SLAM, Moves.FIRE_LASH, Moves.GRAV_APPLE, Moves.MILK_DRINK ],
@ -57,7 +57,7 @@ export const speciesEggMoves = {
[Species.GOLDEEN]: [ Moves.DRILL_RUN, Moves.FLIP_TURN, Moves.DRAGON_DANCE, Moves.FISHIOUS_REND ], [Species.GOLDEEN]: [ Moves.DRILL_RUN, Moves.FLIP_TURN, Moves.DRAGON_DANCE, Moves.FISHIOUS_REND ],
[Species.STARYU]: [ Moves.CALM_MIND, Moves.BOUNCY_BUBBLE, Moves.MOONBLAST, Moves.MYSTICAL_POWER ], [Species.STARYU]: [ Moves.CALM_MIND, Moves.BOUNCY_BUBBLE, Moves.MOONBLAST, Moves.MYSTICAL_POWER ],
[Species.SCYTHER]: [ Moves.GEAR_GRIND, Moves.BUG_BITE, Moves.STORM_THROW, Moves.MIGHTY_CLEAVE ], [Species.SCYTHER]: [ Moves.GEAR_GRIND, Moves.BUG_BITE, Moves.STORM_THROW, Moves.MIGHTY_CLEAVE ],
[Species.PINSIR]: [ Moves.CRUSH_GRIP, Moves.U_TURN, Moves.CLOSE_COMBAT, Moves.EXTREME_SPEED ], [Species.PINSIR]: [ Moves.EARTHQUAKE, Moves.LEECH_LIFE, Moves.CLOSE_COMBAT, Moves.EXTREME_SPEED ],
[Species.TAUROS]: [ Moves.HIGH_HORSEPOWER, Moves.FLARE_BLITZ, Moves.WAVE_CRASH, Moves.HEAD_CHARGE ], [Species.TAUROS]: [ Moves.HIGH_HORSEPOWER, Moves.FLARE_BLITZ, Moves.WAVE_CRASH, Moves.HEAD_CHARGE ],
[Species.MAGIKARP]: [ Moves.FLIP_TURN, Moves.ICE_SPINNER, Moves.LIQUIDATION, Moves.DRAGON_ASCENT ], [Species.MAGIKARP]: [ Moves.FLIP_TURN, Moves.ICE_SPINNER, Moves.LIQUIDATION, Moves.DRAGON_ASCENT ],
[Species.LAPRAS]: [ Moves.RECOVER, Moves.FREEZE_DRY, Moves.CHILLY_RECEPTION, Moves.BOOMBURST ], [Species.LAPRAS]: [ Moves.RECOVER, Moves.FREEZE_DRY, Moves.CHILLY_RECEPTION, Moves.BOOMBURST ],
@ -79,7 +79,7 @@ export const speciesEggMoves = {
[Species.SENTRET]: [ Moves.TIDY_UP, Moves.THIEF, Moves.NUZZLE, Moves.EXTREME_SPEED ], [Species.SENTRET]: [ Moves.TIDY_UP, Moves.THIEF, Moves.NUZZLE, Moves.EXTREME_SPEED ],
[Species.HOOTHOOT]: [ Moves.CALM_MIND, Moves.ESPER_WING, Moves.BOOMBURST, Moves.OBLIVION_WING ], [Species.HOOTHOOT]: [ Moves.CALM_MIND, Moves.ESPER_WING, Moves.BOOMBURST, Moves.OBLIVION_WING ],
[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.MEGAHORN, Moves.SILK_TRAP, 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.VOLT_SWITCH, Moves.TAIL_GLOW ], [Species.CHINCHOU]: [ Moves.THUNDERCLAP, Moves.BOUNCY_BUBBLE, Moves.VOLT_SWITCH, Moves.TAIL_GLOW ],
[Species.PICHU]: [ Moves.THUNDERCLAP, Moves.SPLISHY_SPLASH, Moves.FLOATY_FALL, Moves.THUNDER_CAGE ], [Species.PICHU]: [ Moves.THUNDERCLAP, Moves.SPLISHY_SPLASH, Moves.FLOATY_FALL, Moves.THUNDER_CAGE ],
[Species.CLEFFA]: [ Moves.TAKE_HEART, Moves.POWER_GEM, Moves.WISH, Moves.LIGHT_OF_RUIN ], [Species.CLEFFA]: [ Moves.TAKE_HEART, Moves.POWER_GEM, Moves.WISH, Moves.LIGHT_OF_RUIN ],
@ -100,16 +100,16 @@ export const speciesEggMoves = {
[Species.DUNSPARCE]: [ Moves.BODY_SLAM, Moves.WICKED_TORQUE, Moves.BLAZING_TORQUE, Moves.EXTREME_SPEED ], [Species.DUNSPARCE]: [ Moves.BODY_SLAM, Moves.WICKED_TORQUE, Moves.BLAZING_TORQUE, Moves.EXTREME_SPEED ],
[Species.GLIGAR]: [ Moves.STONE_AXE, Moves.EARTHQUAKE, Moves.ROOST, Moves.FLOATY_FALL ], [Species.GLIGAR]: [ Moves.STONE_AXE, Moves.EARTHQUAKE, Moves.ROOST, Moves.FLOATY_FALL ],
[Species.SNUBBULL]: [ Moves.PARTING_SHOT, Moves.EARTHQUAKE, Moves.STUFF_CHEEKS, Moves.MAGICAL_TORQUE ], [Species.SNUBBULL]: [ Moves.PARTING_SHOT, Moves.EARTHQUAKE, Moves.STUFF_CHEEKS, Moves.MAGICAL_TORQUE ],
[Species.QWILFISH]: [ Moves.BARB_BARRAGE, Moves.BANEFUL_BUNKER, Moves.NUZZLE, Moves.FISHIOUS_REND ], [Species.QWILFISH]: [ Moves.BARB_BARRAGE, Moves.BANEFUL_BUNKER, Moves.KNOCK_OFF, Moves.FISHIOUS_REND ],
[Species.SHUCKLE]: [ Moves.COSMIC_POWER, Moves.SHORE_UP, Moves.BODY_PRESS, Moves.SALT_CURE ], [Species.SHUCKLE]: [ Moves.COSMIC_POWER, Moves.SHORE_UP, Moves.BODY_PRESS, Moves.SALT_CURE ],
[Species.HERACROSS]: [ Moves.ROCK_BLAST, Moves.LUNGE, Moves.ICICLE_SPEAR, Moves.TIDY_UP ], [Species.HERACROSS]: [ Moves.ROCK_BLAST, Moves.FIRST_IMPRESSION, Moves.ICICLE_SPEAR, Moves.TIDY_UP ],
[Species.SNEASEL]: [ Moves.DIRE_CLAW, Moves.KOWTOW_CLEAVE, Moves.TRIPLE_AXEL, Moves.GLACIAL_LANCE ], [Species.SNEASEL]: [ Moves.DIRE_CLAW, Moves.SUCKER_PUNCH, Moves.TRIPLE_AXEL, Moves.WICKED_BLOW ],
[Species.TEDDIURSA]: [ Moves.DIRE_CLAW, Moves.FACADE, Moves.BULK_UP, Moves.SLACK_OFF ], [Species.TEDDIURSA]: [ Moves.DIRE_CLAW, Moves.FACADE, Moves.BULK_UP, Moves.SLACK_OFF ],
[Species.SLUGMA]: [ Moves.BURNING_BULWARK, Moves.POWER_GEM, Moves.MAGMA_STORM, Moves.HYDRO_STEAM ], [Species.SLUGMA]: [ Moves.BURNING_BULWARK, Moves.POWER_GEM, Moves.MAGMA_STORM, Moves.HYDRO_STEAM ],
[Species.SWINUB]: [ Moves.ICE_SPINNER, Moves.HEADLONG_RUSH, Moves.MIGHTY_CLEAVE, Moves.GLACIAL_LANCE ], [Species.SWINUB]: [ Moves.ICE_SPINNER, Moves.HEADLONG_RUSH, Moves.MIGHTY_CLEAVE, Moves.GLACIAL_LANCE ],
[Species.CORSOLA]: [ Moves.SCALD, Moves.FREEZE_DRY, Moves.STRENGTH_SAP, Moves.SALT_CURE ], [Species.CORSOLA]: [ Moves.SCALD, Moves.FREEZE_DRY, Moves.STRENGTH_SAP, Moves.SALT_CURE ],
[Species.REMORAID]: [ Moves.TWIN_BEAM, Moves.SNIPE_SHOT, Moves.SEARING_SHOT, Moves.ELECTRO_SHOT ], [Species.REMORAID]: [ Moves.WATER_SHURIKEN, Moves.SNIPE_SHOT, Moves.SEARING_SHOT, Moves.ELECTRO_SHOT ],
[Species.DELIBIRD]: [ Moves.GLACIATE, Moves.FREEZE_DRY, Moves.CHILLY_RECEPTION, Moves.BLEAKWIND_STORM ], [Species.DELIBIRD]: [ Moves.DRILL_RUN, Moves.FLOATY_FALL, Moves.NO_RETREAT, Moves.GLACIAL_LANCE ],
[Species.SKARMORY]: [ Moves.ROOST, Moves.BODY_PRESS, Moves.SPIKY_SHIELD, Moves.BEAK_BLAST ], [Species.SKARMORY]: [ Moves.ROOST, Moves.BODY_PRESS, Moves.SPIKY_SHIELD, Moves.BEAK_BLAST ],
[Species.HOUNDOUR]: [ Moves.SEARING_SHOT, Moves.FIERY_WRATH, Moves.PARTING_SHOT, Moves.HYDRO_STEAM ], [Species.HOUNDOUR]: [ Moves.SEARING_SHOT, Moves.FIERY_WRATH, Moves.PARTING_SHOT, Moves.HYDRO_STEAM ],
[Species.PHANPY]: [ Moves.SHORE_UP, Moves.HEAD_SMASH, Moves.MOUNTAIN_GALE, Moves.VOLT_TACKLE ], [Species.PHANPY]: [ Moves.SHORE_UP, Moves.HEAD_SMASH, Moves.MOUNTAIN_GALE, Moves.VOLT_TACKLE ],
@ -122,10 +122,10 @@ export const speciesEggMoves = {
[Species.MILTANK]: [ Moves.BODY_PRESS, Moves.BULK_UP, Moves.YAWN, Moves.SIZZLY_SLIDE ], [Species.MILTANK]: [ Moves.BODY_PRESS, Moves.BULK_UP, Moves.YAWN, Moves.SIZZLY_SLIDE ],
[Species.RAIKOU]: [ Moves.THUNDERCLAP, Moves.NASTY_PLOT, Moves.ICE_BEAM, Moves.PARABOLIC_CHARGE ], [Species.RAIKOU]: [ Moves.THUNDERCLAP, Moves.NASTY_PLOT, Moves.ICE_BEAM, Moves.PARABOLIC_CHARGE ],
[Species.ENTEI]: [ Moves.BURNING_BULWARK, Moves.DRAGON_DANCE, Moves.EARTHQUAKE, Moves.MIGHTY_CLEAVE ], [Species.ENTEI]: [ Moves.BURNING_BULWARK, Moves.DRAGON_DANCE, Moves.EARTHQUAKE, Moves.MIGHTY_CLEAVE ],
[Species.SUICUNE]: [ Moves.HYDRO_STEAM, Moves.CALM_MIND, Moves.FREEZE_DRY, Moves.BOUNCY_BUBBLE ], [Species.SUICUNE]: [ Moves.RECOVER, Moves.NASTY_PLOT, Moves.FREEZE_DRY, Moves.STEAM_ERUPTION ],
[Species.LARVITAR]: [ Moves.DRAGON_DANCE, Moves.MOUNTAIN_GALE, Moves.MIGHTY_CLEAVE, Moves.SHORE_UP ], [Species.LARVITAR]: [ Moves.DRAGON_DANCE, Moves.MOUNTAIN_GALE, Moves.SHORE_UP, Moves.DIAMOND_STORM ],
[Species.LUGIA]: [ Moves.TAKE_HEART, Moves.STORED_POWER, Moves.SCALD, Moves.OBLIVION_WING ], [Species.LUGIA]: [ Moves.TAKE_HEART, Moves.STORED_POWER, Moves.SCALD, Moves.OBLIVION_WING ],
[Species.HO_OH]: [ Moves.BURNING_BULWARK, Moves.U_TURN, Moves.BRAVE_BIRD, Moves.REVIVAL_BLESSING ], [Species.HO_OH]: [ Moves.SWORDS_DANCE, Moves.EARTHQUAKE, Moves.BRAVE_BIRD, Moves.REVIVAL_BLESSING ],
[Species.CELEBI]: [ Moves.MYSTICAL_POWER, Moves.STORED_POWER, Moves.COSMIC_POWER, Moves.SEED_FLARE ], [Species.CELEBI]: [ Moves.MYSTICAL_POWER, Moves.STORED_POWER, Moves.COSMIC_POWER, Moves.SEED_FLARE ],
[Species.TREECKO]: [ Moves.DRAGON_PULSE, Moves.DRAGON_ENERGY, Moves.SECRET_SWORD, Moves.SEED_FLARE ], [Species.TREECKO]: [ Moves.DRAGON_PULSE, Moves.DRAGON_ENERGY, Moves.SECRET_SWORD, Moves.SEED_FLARE ],
[Species.TORCHIC]: [ Moves.HIGH_JUMP_KICK, Moves.SUPERCELL_SLAM, Moves.KNOCK_OFF, Moves.V_CREATE ], [Species.TORCHIC]: [ Moves.HIGH_JUMP_KICK, Moves.SUPERCELL_SLAM, Moves.KNOCK_OFF, Moves.V_CREATE ],
@ -138,7 +138,7 @@ export const speciesEggMoves = {
[Species.TAILLOW]: [ Moves.SWORDS_DANCE, Moves.FACADE, Moves.DRILL_RUN, Moves.EXTREME_SPEED ], [Species.TAILLOW]: [ Moves.SWORDS_DANCE, Moves.FACADE, Moves.DRILL_RUN, Moves.EXTREME_SPEED ],
[Species.WINGULL]: [ Moves.THUNDER, Moves.FLIP_TURN, Moves.DEFOG, Moves.STEAM_ERUPTION ], [Species.WINGULL]: [ Moves.THUNDER, Moves.FLIP_TURN, Moves.DEFOG, Moves.STEAM_ERUPTION ],
[Species.RALTS]: [ Moves.BOOMBURST, Moves.BITTER_BLADE, Moves.QUIVER_DANCE, Moves.VICTORY_DANCE ], [Species.RALTS]: [ Moves.BOOMBURST, Moves.BITTER_BLADE, Moves.QUIVER_DANCE, Moves.VICTORY_DANCE ],
[Species.SURSKIT]: [ Moves.ROOST, Moves.FIERY_DANCE, Moves.STICKY_WEB, Moves.BLEAKWIND_STORM ], [Species.SURSKIT]: [ Moves.POLLEN_PUFF, Moves.FIERY_DANCE, Moves.BOUNCY_BUBBLE, Moves.AEROBLAST ],
[Species.SHROOMISH]: [ Moves.ACCELEROCK, Moves.TRAILBLAZE, Moves.STORM_THROW, Moves.SAPPY_SEED ], [Species.SHROOMISH]: [ Moves.ACCELEROCK, Moves.TRAILBLAZE, Moves.STORM_THROW, Moves.SAPPY_SEED ],
[Species.SLAKOTH]: [ Moves.FACADE, Moves.JUMP_KICK, Moves.KNOCK_OFF, Moves.SKILL_SWAP ], [Species.SLAKOTH]: [ Moves.FACADE, Moves.JUMP_KICK, Moves.KNOCK_OFF, Moves.SKILL_SWAP ],
[Species.NINCADA]: [ Moves.ATTACK_ORDER, Moves.STICKY_WEB, Moves.SPIRIT_SHACKLE, Moves.SHELL_SMASH ], [Species.NINCADA]: [ Moves.ATTACK_ORDER, Moves.STICKY_WEB, Moves.SPIRIT_SHACKLE, Moves.SHELL_SMASH ],
@ -146,8 +146,8 @@ export const speciesEggMoves = {
[Species.MAKUHITA]: [ Moves.STORM_THROW, Moves.SLACK_OFF, Moves.HEAT_CRASH, Moves.DOUBLE_IRON_BASH ], [Species.MAKUHITA]: [ Moves.STORM_THROW, Moves.SLACK_OFF, Moves.HEAT_CRASH, Moves.DOUBLE_IRON_BASH ],
[Species.AZURILL]: [ Moves.JET_PUNCH, Moves.SPIRIT_BREAK, Moves.SWORDS_DANCE, Moves.SURGING_STRIKES ], [Species.AZURILL]: [ Moves.JET_PUNCH, Moves.SPIRIT_BREAK, Moves.SWORDS_DANCE, Moves.SURGING_STRIKES ],
[Species.NOSEPASS]: [ Moves.SHORE_UP, Moves.BODY_PRESS, Moves.CALM_MIND, Moves.TACHYON_CUTTER ], [Species.NOSEPASS]: [ Moves.SHORE_UP, Moves.BODY_PRESS, Moves.CALM_MIND, Moves.TACHYON_CUTTER ],
[Species.SKITTY]: [ Moves.THUNDEROUS_KICK, Moves.SKETCH, Moves.TIDY_UP, Moves.V_CREATE ], [Species.SKITTY]: [ Moves.THUNDEROUS_KICK, Moves.ENTRAINMENT, Moves.TIDY_UP, Moves.V_CREATE ],
[Species.SABLEYE]: [ Moves.RECOVER, Moves.TOPSY_TURVY, Moves.PARTING_SHOT, Moves.SALT_CURE ], [Species.SABLEYE]: [ Moves.RECOVER, Moves.TOPSY_TURVY, Moves.CURSE, Moves.SALT_CURE ],
[Species.MAWILE]: [ Moves.BULLET_PUNCH, Moves.MAGICAL_TORQUE, Moves.EARTHQUAKE, Moves.DOUBLE_IRON_BASH ], [Species.MAWILE]: [ Moves.BULLET_PUNCH, Moves.MAGICAL_TORQUE, Moves.EARTHQUAKE, Moves.DOUBLE_IRON_BASH ],
[Species.ARON]: [ Moves.HEAD_SMASH, Moves.BODY_PRESS, Moves.SHORE_UP, Moves.SALT_CURE ], [Species.ARON]: [ Moves.HEAD_SMASH, Moves.BODY_PRESS, Moves.SHORE_UP, Moves.SALT_CURE ],
[Species.MEDITITE]: [ Moves.THUNDEROUS_KICK, Moves.SUCKER_PUNCH, Moves.BULLET_PUNCH, Moves.PHOTON_GEYSER ], [Species.MEDITITE]: [ Moves.THUNDEROUS_KICK, Moves.SUCKER_PUNCH, Moves.BULLET_PUNCH, Moves.PHOTON_GEYSER ],
@ -159,8 +159,8 @@ export const speciesEggMoves = {
[Species.GULPIN]: [ Moves.STRENGTH_SAP, Moves.EARTH_POWER, Moves.GROWTH, Moves.MALIGNANT_CHAIN ], [Species.GULPIN]: [ Moves.STRENGTH_SAP, Moves.EARTH_POWER, Moves.GROWTH, Moves.MALIGNANT_CHAIN ],
[Species.CARVANHA]: [ Moves.DRILL_RUN, Moves.ICE_SPINNER, Moves.WAVE_CRASH, Moves.SWORDS_DANCE ], [Species.CARVANHA]: [ Moves.DRILL_RUN, Moves.ICE_SPINNER, Moves.WAVE_CRASH, Moves.SWORDS_DANCE ],
[Species.WAILMER]: [ Moves.CURSE, Moves.LIQUIDATION, Moves.FLOATY_FALL, Moves.RECOVER ], [Species.WAILMER]: [ Moves.CURSE, Moves.LIQUIDATION, Moves.FLOATY_FALL, Moves.RECOVER ],
[Species.NUMEL]: [ Moves.SANDSEAR_STORM, Moves.SPIKES, Moves.SHORE_UP, Moves.SEARING_SHOT ], [Species.NUMEL]: [ Moves.TRICK_ROOM, Moves.ENERGY_BALL, Moves.MORNING_SUN, Moves.BLUE_FLARE ],
[Species.TORKOAL]: [ Moves.SLACK_OFF, Moves.SPIKES, Moves.BODY_PRESS, Moves.BURNING_BULWARK ], [Species.TORKOAL]: [ Moves.MORNING_SUN, Moves.BURNING_BULWARK, Moves.BODY_PRESS, Moves.HYDRO_STEAM ],
[Species.SPOINK]: [ Moves.AURA_SPHERE, Moves.MILK_DRINK, Moves.COSMIC_POWER, Moves.EXPANDING_FORCE ], [Species.SPOINK]: [ Moves.AURA_SPHERE, Moves.MILK_DRINK, Moves.COSMIC_POWER, Moves.EXPANDING_FORCE ],
[Species.SPINDA]: [ Moves.SUPERPOWER, Moves.SLACK_OFF, Moves.FLEUR_CANNON, Moves.V_CREATE ], [Species.SPINDA]: [ Moves.SUPERPOWER, Moves.SLACK_OFF, Moves.FLEUR_CANNON, Moves.V_CREATE ],
[Species.TRAPINCH]: [ Moves.FIRE_LASH, Moves.DRAGON_DARTS, Moves.THOUSAND_ARROWS, Moves.DRAGON_ENERGY ], [Species.TRAPINCH]: [ Moves.FIRE_LASH, Moves.DRAGON_DARTS, Moves.THOUSAND_ARROWS, Moves.DRAGON_ENERGY ],
@ -176,20 +176,20 @@ export const speciesEggMoves = {
[Species.LILEEP]: [ Moves.POWER_GEM, Moves.SCALD, Moves.STONE_AXE, Moves.SAPPY_SEED ], [Species.LILEEP]: [ Moves.POWER_GEM, Moves.SCALD, Moves.STONE_AXE, Moves.SAPPY_SEED ],
[Species.ANORITH]: [ Moves.LIQUIDATION, Moves.LEECH_LIFE, Moves.DRAGON_DANCE, Moves.MIGHTY_CLEAVE ], [Species.ANORITH]: [ Moves.LIQUIDATION, Moves.LEECH_LIFE, Moves.DRAGON_DANCE, Moves.MIGHTY_CLEAVE ],
[Species.FEEBAS]: [ Moves.CALM_MIND, Moves.FREEZE_DRY, Moves.MOONBLAST, Moves.STEAM_ERUPTION ], [Species.FEEBAS]: [ Moves.CALM_MIND, Moves.FREEZE_DRY, Moves.MOONBLAST, Moves.STEAM_ERUPTION ],
[Species.CASTFORM]: [ Moves.BOOMBURST, Moves.HYDRO_STEAM, Moves.CLEAR_SMOG, Moves.QUIVER_DANCE ], [Species.CASTFORM]: [ Moves.BOOMBURST, Moves.HYDRO_STEAM, Moves.ERUPTION, Moves.QUIVER_DANCE ],
[Species.KECLEON]: [ Moves.DRAIN_PUNCH, Moves.DRAGON_DANCE, Moves.EXTREME_SPEED, Moves.MULTI_ATTACK ], [Species.KECLEON]: [ Moves.DRAIN_PUNCH, Moves.DRAGON_DANCE, Moves.EXTREME_SPEED, Moves.MULTI_ATTACK ],
[Species.SHUPPET]: [ Moves.DRAIN_PUNCH, Moves.TOPSY_TURVY, Moves.PARTING_SHOT, Moves.SPECTRAL_THIEF ], [Species.SHUPPET]: [ Moves.STORM_THROW, Moves.TIDY_UP, Moves.PARTING_SHOT, Moves.SPECTRAL_THIEF ],
[Species.DUSKULL]: [ Moves.BULK_UP, Moves.DRAIN_PUNCH, Moves.STRENGTH_SAP, Moves.RAGE_FIST ], [Species.DUSKULL]: [ Moves.BULK_UP, Moves.DRAIN_PUNCH, Moves.STRENGTH_SAP, Moves.RAGE_FIST ],
[Species.TROPIUS]: [ Moves.STUFF_CHEEKS, Moves.EARTH_POWER, Moves.APPLE_ACID, Moves.SAPPY_SEED ], [Species.TROPIUS]: [ Moves.STUFF_CHEEKS, Moves.EARTH_POWER, Moves.APPLE_ACID, Moves.SAPPY_SEED ],
[Species.ABSOL]: [ Moves.KOWTOW_CLEAVE, Moves.SACRED_SWORD, Moves.DIRE_CLAW, Moves.BITTER_BLADE ], [Species.ABSOL]: [ Moves.KOWTOW_CLEAVE, Moves.SACRED_SWORD, Moves.DIRE_CLAW, Moves.BITTER_BLADE ],
[Species.WYNAUT]: [ Moves.RECOVER, Moves.PERISH_SONG, Moves.TAUNT, Moves.SHED_TAIL ], [Species.WYNAUT]: [ Moves.RECOVER, Moves.SHED_TAIL, Moves.TAUNT, Moves.COMEUPPANCE ],
[Species.SNORUNT]: [ Moves.AURORA_VEIL, Moves.HYPER_VOICE, Moves.EARTH_POWER, Moves.NO_RETREAT ], [Species.SNORUNT]: [ Moves.AURORA_VEIL, Moves.HYPER_VOICE, Moves.EARTH_POWER, Moves.NO_RETREAT ],
[Species.SPHEAL]: [ Moves.FLIP_TURN, Moves.FREEZE_DRY, Moves.SLACK_OFF, Moves.STEAM_ERUPTION ], [Species.SPHEAL]: [ Moves.FLIP_TURN, Moves.FREEZE_DRY, Moves.SLACK_OFF, Moves.STEAM_ERUPTION ],
[Species.CLAMPERL]: [ Moves.ICE_SPINNER, Moves.LIQUIDATION, Moves.EARTH_POWER, Moves.ORIGIN_PULSE ], [Species.CLAMPERL]: [ Moves.ICE_SPINNER, Moves.LIQUIDATION, Moves.EARTH_POWER, Moves.STEAM_ERUPTION ],
[Species.RELICANTH]: [ Moves.BODY_PRESS, Moves.SHORE_UP, Moves.WAVE_CRASH, Moves.FISHIOUS_REND ], [Species.RELICANTH]: [ Moves.BODY_PRESS, Moves.SHORE_UP, Moves.WAVE_CRASH, Moves.FISHIOUS_REND ],
[Species.LUVDISC]: [ Moves.BATON_PASS, Moves.THIEF, Moves.BOUNCY_BUBBLE, Moves.TAKE_HEART ], [Species.LUVDISC]: [ Moves.BATON_PASS, Moves.THIEF, Moves.BOUNCY_BUBBLE, Moves.TAKE_HEART ],
[Species.BAGON]: [ Moves.FLOATY_FALL, Moves.FIRE_LASH, Moves.DRAGON_DANCE, Moves.GLAIVE_RUSH ], [Species.BAGON]: [ Moves.FLOATY_FALL, Moves.FIRE_LASH, Moves.DRAGON_DANCE, Moves.GLAIVE_RUSH ],
[Species.BELDUM]: [ Moves.PSYCHIC_FANGS, Moves.RECOVER, Moves.MOUNTAIN_GALE, Moves.SHIFT_GEAR ], [Species.BELDUM]: [ Moves.PSYCHIC_FANGS, Moves.RECOVER, Moves.TRIPLE_AXEL, Moves.SHIFT_GEAR ],
[Species.REGIROCK]: [ Moves.STONE_AXE, Moves.BODY_PRESS, Moves.RECOVER, Moves.SALT_CURE ], [Species.REGIROCK]: [ Moves.STONE_AXE, Moves.BODY_PRESS, Moves.RECOVER, Moves.SALT_CURE ],
[Species.REGICE]: [ Moves.EARTH_POWER, Moves.COSMIC_POWER, Moves.RECOVER, Moves.FREEZE_DRY ], [Species.REGICE]: [ Moves.EARTH_POWER, Moves.COSMIC_POWER, Moves.RECOVER, Moves.FREEZE_DRY ],
[Species.REGISTEEL]: [ Moves.BODY_PRESS, Moves.HEAT_CRASH, Moves.RECOVER, Moves.GIGATON_HAMMER ], [Species.REGISTEEL]: [ Moves.BODY_PRESS, Moves.HEAT_CRASH, Moves.RECOVER, Moves.GIGATON_HAMMER ],
@ -208,9 +208,9 @@ export const speciesEggMoves = {
[Species.KRICKETOT]: [ Moves.BONEMERANG, Moves.ROOST, Moves.ROCK_BLAST, Moves.VICTORY_DANCE ], [Species.KRICKETOT]: [ Moves.BONEMERANG, Moves.ROOST, Moves.ROCK_BLAST, Moves.VICTORY_DANCE ],
[Species.SHINX]: [ Moves.FIRE_LASH, Moves.TRIPLE_AXEL, Moves.FACADE, Moves.BOLT_STRIKE ], [Species.SHINX]: [ Moves.FIRE_LASH, Moves.TRIPLE_AXEL, Moves.FACADE, Moves.BOLT_STRIKE ],
[Species.BUDEW]: [ Moves.FIERY_DANCE, Moves.SLUDGE_WAVE, Moves.SPORE, Moves.QUIVER_DANCE ], [Species.BUDEW]: [ Moves.FIERY_DANCE, Moves.SLUDGE_WAVE, Moves.SPORE, Moves.QUIVER_DANCE ],
[Species.CRANIDOS]: [ Moves.STONE_AXE, Moves.ACCELEROCK, Moves.HEADLONG_RUSH, Moves.DRAGON_DANCE ], [Species.CRANIDOS]: [ Moves.DRAGON_DANCE, Moves.ACCELEROCK, Moves.HEADLONG_RUSH, Moves.VOLT_TACKLE ],
[Species.SHIELDON]: [ Moves.PAIN_SPLIT, Moves.BODY_PRESS, Moves.KINGS_SHIELD, Moves.DIAMOND_STORM ], [Species.SHIELDON]: [ Moves.PAIN_SPLIT, Moves.BODY_PRESS, Moves.KINGS_SHIELD, Moves.DIAMOND_STORM ],
[Species.BURMY]: [ Moves.BODY_PRESS, Moves.TOXIC, Moves.HEAL_ORDER, Moves.DEFEND_ORDER ], [Species.BURMY]: [ Moves.BODY_PRESS, Moves.DEFEND_ORDER, Moves.HEAL_ORDER, Moves.SAPPY_SEED ],
[Species.COMBEE]: [ Moves.SPORE, Moves.HEAT_WAVE, Moves.KINGS_SHIELD, Moves.QUIVER_DANCE ], [Species.COMBEE]: [ Moves.SPORE, Moves.HEAT_WAVE, Moves.KINGS_SHIELD, Moves.QUIVER_DANCE ],
[Species.PACHIRISU]: [ Moves.BADDY_BAD, Moves.SIZZLY_SLIDE, Moves.U_TURN, Moves.ZIPPY_ZAP ], [Species.PACHIRISU]: [ Moves.BADDY_BAD, Moves.SIZZLY_SLIDE, Moves.U_TURN, Moves.ZIPPY_ZAP ],
[Species.BUIZEL]: [ Moves.JET_PUNCH, Moves.TRIPLE_AXEL, Moves.SUPERCELL_SLAM, Moves.SURGING_STRIKES ], [Species.BUIZEL]: [ Moves.JET_PUNCH, Moves.TRIPLE_AXEL, Moves.SUPERCELL_SLAM, Moves.SURGING_STRIKES ],
@ -235,16 +235,16 @@ export const speciesEggMoves = {
[Species.CROAGUNK]: [ Moves.DIRE_CLAW, Moves.ICE_PUNCH, Moves.THUNDEROUS_KICK, Moves.VICTORY_DANCE ], [Species.CROAGUNK]: [ Moves.DIRE_CLAW, Moves.ICE_PUNCH, Moves.THUNDEROUS_KICK, Moves.VICTORY_DANCE ],
[Species.CARNIVINE]: [ Moves.STRENGTH_SAP, Moves.FIRE_LASH, Moves.MIGHTY_CLEAVE, Moves.FLOWER_TRICK ], [Species.CARNIVINE]: [ Moves.STRENGTH_SAP, Moves.FIRE_LASH, Moves.MIGHTY_CLEAVE, Moves.FLOWER_TRICK ],
[Species.FINNEON]: [ Moves.QUIVER_DANCE, Moves.BOUNCY_BUBBLE, Moves.FREEZE_DRY, Moves.ORIGIN_PULSE ], [Species.FINNEON]: [ Moves.QUIVER_DANCE, Moves.BOUNCY_BUBBLE, Moves.FREEZE_DRY, Moves.ORIGIN_PULSE ],
[Species.MANTYKE]: [ Moves.BOUNCY_BUBBLE, Moves.SPIKES, Moves.ROOST, Moves.STEAM_ERUPTION ], [Species.MANTYKE]: [ Moves.BOUNCY_BUBBLE, Moves.STEALTH_ROCK, Moves.NASTY_PLOT, Moves.STEAM_ERUPTION ],
[Species.SNOVER]: [ Moves.HIGH_HORSEPOWER, Moves.STRENGTH_SAP, Moves.AURORA_VEIL, Moves.IVY_CUDGEL ], [Species.SNOVER]: [ Moves.HIGH_HORSEPOWER, Moves.STRENGTH_SAP, Moves.AURORA_VEIL, Moves.IVY_CUDGEL ],
[Species.ROTOM]: [ Moves.STRENGTH_SAP, Moves.FIERY_DANCE, Moves.SPLISHY_SPLASH, Moves.RISING_VOLTAGE ], [Species.ROTOM]: [ Moves.STRENGTH_SAP, Moves.FIERY_DANCE, Moves.SPLISHY_SPLASH, Moves.ELECTRO_DRIFT ],
[Species.UXIE]: [ Moves.COSMIC_POWER, Moves.BODY_PRESS, Moves.RECOVER, Moves.LUMINA_CRASH ], [Species.UXIE]: [ Moves.COSMIC_POWER, Moves.BODY_PRESS, Moves.RECOVER, Moves.SPARKLY_SWIRL ],
[Species.MESPRIT]: [ Moves.QUIVER_DANCE, Moves.AURA_SPHERE, Moves.RECOVER, Moves.LUMINA_CRASH ], [Species.MESPRIT]: [ Moves.TAIL_GLOW, Moves.AURA_SPHERE, Moves.RECOVER, Moves.LUMINA_CRASH ],
[Species.AZELF]: [ Moves.PHOTON_GEYSER, Moves.ICE_BEAM, Moves.MOONBLAST, Moves.LUMINA_CRASH ], [Species.AZELF]: [ Moves.PSYSTRIKE, Moves.ICE_BEAM, Moves.MOONBLAST, Moves.TAIL_GLOW ],
[Species.DIALGA]: [ Moves.CORE_ENFORCER, Moves.TAKE_HEART, Moves.RECOVER, Moves.MAKE_IT_RAIN ], [Species.DIALGA]: [ Moves.CORE_ENFORCER, Moves.TAKE_HEART, Moves.RECOVER, Moves.MAKE_IT_RAIN ],
[Species.PALKIA]: [ Moves.RECOVER, Moves.TAKE_HEART, Moves.WATER_SPOUT, Moves.DRAGON_ENERGY ], [Species.PALKIA]: [ Moves.RECOVER, Moves.TAKE_HEART, Moves.WATER_SPOUT, Moves.DRAGON_ENERGY ],
[Species.HEATRAN]: [ Moves.TORCH_SONG, Moves.RECOVER, Moves.FLASH_CANNON, Moves.MATCHA_GOTCHA ], [Species.HEATRAN]: [ Moves.TORCH_SONG, Moves.RECOVER, Moves.FLASH_CANNON, Moves.MATCHA_GOTCHA ],
[Species.REGIGIGAS]: [ Moves.SKILL_SWAP, Moves.SHORE_UP, Moves.EXTREME_SPEED, Moves.GIGATON_HAMMER ], [Species.REGIGIGAS]: [ Moves.SKILL_SWAP, Moves.RECOVER, Moves.EXTREME_SPEED, Moves.GIGATON_HAMMER ],
[Species.GIRATINA]: [ Moves.DRAGON_DANCE, Moves.GLAIVE_RUSH, Moves.RECOVER, Moves.SPECTRAL_THIEF ], [Species.GIRATINA]: [ Moves.DRAGON_DANCE, Moves.GLAIVE_RUSH, Moves.RECOVER, Moves.SPECTRAL_THIEF ],
[Species.CRESSELIA]: [ Moves.COSMIC_POWER, Moves.SECRET_SWORD, Moves.SIZZLY_SLIDE, Moves.LUMINA_CRASH ], [Species.CRESSELIA]: [ Moves.COSMIC_POWER, Moves.SECRET_SWORD, Moves.SIZZLY_SLIDE, Moves.LUMINA_CRASH ],
[Species.PHIONE]: [ Moves.BOUNCY_BUBBLE, Moves.FREEZE_DRY, Moves.SPLISHY_SPLASH, Moves.QUIVER_DANCE ], [Species.PHIONE]: [ Moves.BOUNCY_BUBBLE, Moves.FREEZE_DRY, Moves.SPLISHY_SPLASH, Moves.QUIVER_DANCE ],
@ -260,37 +260,37 @@ export const speciesEggMoves = {
[Species.LILLIPUP]: [ Moves.CLOSE_COMBAT, Moves.THIEF, Moves.HIGH_HORSEPOWER, Moves.LAST_RESPECTS ], [Species.LILLIPUP]: [ Moves.CLOSE_COMBAT, Moves.THIEF, Moves.HIGH_HORSEPOWER, Moves.LAST_RESPECTS ],
[Species.PURRLOIN]: [ Moves.ENCORE, Moves.ASSIST, Moves.PARTING_SHOT, Moves.WICKED_BLOW ], [Species.PURRLOIN]: [ Moves.ENCORE, Moves.ASSIST, Moves.PARTING_SHOT, Moves.WICKED_BLOW ],
[Species.PANSAGE]: [ Moves.SWORDS_DANCE, Moves.TEMPER_FLARE, Moves.EARTHQUAKE, Moves.IVY_CUDGEL ], [Species.PANSAGE]: [ Moves.SWORDS_DANCE, Moves.TEMPER_FLARE, Moves.EARTHQUAKE, Moves.IVY_CUDGEL ],
[Species.PANSEAR]: [ Moves.NASTY_PLOT, Moves.SCALD, Moves.SCORCHING_SANDS, Moves.SEARING_SHOT ], [Species.PANSEAR]: [ Moves.NASTY_PLOT, Moves.SCALD, Moves.SCORCHING_SANDS, Moves.TORCH_SONG ],
[Species.PANPOUR]: [ Moves.NASTY_PLOT, Moves.ENERGY_BALL, Moves.AURA_SPHERE, Moves.STEAM_ERUPTION ], [Species.PANPOUR]: [ Moves.NASTY_PLOT, Moves.ENERGY_BALL, Moves.EARTH_POWER, Moves.STEAM_ERUPTION ],
[Species.MUNNA]: [ Moves.COSMIC_POWER, Moves.AURA_SPHERE, Moves.EARTH_POWER, Moves.LUMINA_CRASH ], [Species.MUNNA]: [ Moves.COSMIC_POWER, Moves.AURA_SPHERE, Moves.EARTH_POWER, Moves.MYSTICAL_POWER ],
[Species.PIDOVE]: [ Moves.GUNK_SHOT, Moves.TIDY_UP, Moves.FLOATY_FALL, Moves.TRIPLE_ARROWS ], [Species.PIDOVE]: [ Moves.GUNK_SHOT, Moves.TIDY_UP, Moves.FLOATY_FALL, Moves.TRIPLE_ARROWS ],
[Species.BLITZLE]: [ Moves.HIGH_HORSEPOWER, Moves.THUNDEROUS_KICK, Moves.FLARE_BLITZ, Moves.VOLT_TACKLE ], [Species.BLITZLE]: [ Moves.HIGH_HORSEPOWER, Moves.THUNDEROUS_KICK, Moves.FLARE_BLITZ, Moves.VOLT_TACKLE ],
[Species.ROGGENROLA]: [ Moves.BODY_PRESS, Moves.CURSE, Moves.SHORE_UP, Moves.DIAMOND_STORM ], [Species.ROGGENROLA]: [ Moves.BODY_PRESS, Moves.CURSE, Moves.SHORE_UP, Moves.DIAMOND_STORM ],
[Species.WOOBAT]: [ Moves.TAKE_HEART, Moves.STORED_POWER, Moves.MYSTICAL_FIRE, Moves.OBLIVION_WING ], [Species.WOOBAT]: [ Moves.ESPER_WING, Moves.STORED_POWER, Moves.MYSTICAL_FIRE, Moves.OBLIVION_WING ],
[Species.DRILBUR]: [ Moves.IRON_HEAD, Moves.ICE_SPINNER, Moves.SHIFT_GEAR, Moves.HEADLONG_RUSH ], [Species.DRILBUR]: [ Moves.IRON_HEAD, Moves.ICE_SPINNER, Moves.SHIFT_GEAR, Moves.THOUSAND_ARROWS ],
[Species.AUDINO]: [ Moves.FOLLOW_ME, Moves.MOONBLAST, Moves.WISH, Moves.LUNAR_BLESSING ], [Species.AUDINO]: [ Moves.FOLLOW_ME, Moves.MOONBLAST, Moves.WISH, Moves.LUNAR_BLESSING ],
[Species.TIMBURR]: [ Moves.MACH_PUNCH, Moves.DRAIN_PUNCH, Moves.ICE_HAMMER, Moves.DOUBLE_IRON_BASH ], [Species.TIMBURR]: [ Moves.MACH_PUNCH, Moves.DRAIN_PUNCH, Moves.ICE_HAMMER, Moves.DOUBLE_IRON_BASH ],
[Species.TYMPOLE]: [ Moves.LIQUIDATION, Moves.HIGH_HORSEPOWER, Moves.TOXIC, Moves.SHORE_UP ], [Species.TYMPOLE]: [ Moves.JET_PUNCH, Moves.HIGH_HORSEPOWER, Moves.BULK_UP, Moves.SURGING_STRIKES ],
[Species.THROH]: [ Moves.DRAIN_PUNCH, Moves.SLACK_OFF, Moves.METEOR_MASH, Moves.NO_RETREAT ], [Species.THROH]: [ Moves.DRAIN_PUNCH, Moves.SLACK_OFF, Moves.METEOR_MASH, Moves.NO_RETREAT ],
[Species.SAWK]: [ Moves.DRAIN_PUNCH, Moves.MACH_PUNCH, Moves.ENDEAVOR, Moves.VICTORY_DANCE ], [Species.SAWK]: [ Moves.DRAIN_PUNCH, Moves.MACH_PUNCH, Moves.ENDEAVOR, Moves.VICTORY_DANCE ],
[Species.SEWADDLE]: [ Moves.STONE_AXE, Moves.PSYCHO_CUT, Moves.TIDY_UP, Moves.BITTER_BLADE ], [Species.SEWADDLE]: [ Moves.STONE_AXE, Moves.PSYCHO_CUT, Moves.TIDY_UP, Moves.BITTER_BLADE ],
[Species.VENIPEDE]: [ Moves.SWORDS_DANCE, Moves.BATON_PASS, Moves.NOXIOUS_TORQUE, Moves.BLAZING_TORQUE ], [Species.VENIPEDE]: [ Moves.SWORDS_DANCE, Moves.BATON_PASS, Moves.NOXIOUS_TORQUE, Moves.BLAZING_TORQUE ],
[Species.COTTONEE]: [ Moves.POLLEN_PUFF, Moves.PARTING_SHOT, Moves.SLEEP_POWDER, Moves.SEED_FLARE ], [Species.COTTONEE]: [ Moves.POLLEN_PUFF, Moves.PARTING_SHOT, Moves.SLEEP_POWDER, Moves.SEED_FLARE ],
[Species.PETILIL]: [ Moves.THUNDEROUS_KICK, Moves.BATON_PASS, Moves.AQUA_STEP, Moves.FIERY_DANCE ], [Species.PETILIL]: [ Moves.THUNDEROUS_KICK, Moves.SPARKLING_ARIA, Moves.AQUA_STEP, Moves.FIERY_DANCE ],
[Species.BASCULIN]: [ Moves.LAST_RESPECTS, Moves.CLOSE_COMBAT, Moves.TRIPLE_DIVE, Moves.DRAGON_DANCE ], [Species.BASCULIN]: [ Moves.LAST_RESPECTS, Moves.CLOSE_COMBAT, Moves.TRIPLE_DIVE, Moves.DRAGON_DANCE ],
[Species.SANDILE]: [ Moves.DIRE_CLAW, Moves.PARTING_SHOT, Moves.FIRE_LASH, Moves.PRECIPICE_BLADES ], [Species.SANDILE]: [ Moves.DIRE_CLAW, Moves.PARTING_SHOT, Moves.FIRE_LASH, Moves.PRECIPICE_BLADES ],
[Species.DARUMAKA]: [ Moves.DRAIN_PUNCH, Moves.THUNDER_PUNCH, Moves.BLAZING_TORQUE, Moves.V_CREATE ], [Species.DARUMAKA]: [ Moves.DRAIN_PUNCH, Moves.THUNDER_PUNCH, Moves.BLAZING_TORQUE, Moves.V_CREATE ],
[Species.MARACTUS]: [ Moves.SCORCHING_SANDS, Moves.QUIVER_DANCE, Moves.FIERY_DANCE, Moves.SEED_FLARE ], [Species.MARACTUS]: [ Moves.SCORCHING_SANDS, Moves.QUIVER_DANCE, Moves.FIERY_DANCE, Moves.SEED_FLARE ],
[Species.DWEBBLE]: [ Moves.CRABHAMMER, Moves.STONE_AXE, Moves.LEECH_LIFE, Moves.SHORE_UP ], [Species.DWEBBLE]: [ Moves.CRABHAMMER, Moves.STONE_AXE, Moves.LEECH_LIFE, Moves.MIGHTY_CLEAVE ],
[Species.SCRAGGY]: [ Moves.SUCKER_PUNCH, Moves.TRIPLE_AXEL, Moves.DRAGON_DANCE, Moves.COLLISION_COURSE ], [Species.SCRAGGY]: [ Moves.SUCKER_PUNCH, Moves.TRIPLE_AXEL, Moves.DRAGON_DANCE, Moves.COLLISION_COURSE ],
[Species.SIGILYPH]: [ Moves.STORED_POWER, Moves.TAKE_HEART, Moves.FREEZING_GLARE, Moves.OBLIVION_WING ], [Species.SIGILYPH]: [ Moves.STORED_POWER, Moves.TAKE_HEART, Moves.FREEZING_GLARE, Moves.OBLIVION_WING ],
[Species.YAMASK]: [ Moves.RECOVER, Moves.INFERNAL_PARADE, Moves.AURA_SPHERE, Moves.TOPSY_TURVY ], [Species.YAMASK]: [ Moves.RECOVER, Moves.INFERNAL_PARADE, Moves.AURA_SPHERE, Moves.TOPSY_TURVY ],
[Species.TIRTOUGA]: [ Moves.ICE_SPINNER, Moves.WAVE_CRASH, Moves.SHORE_UP, Moves.MIGHTY_CLEAVE ], [Species.TIRTOUGA]: [ Moves.ICE_SPINNER, Moves.LIQUIDATION, Moves.SHORE_UP, Moves.MIGHTY_CLEAVE ],
[Species.ARCHEN]: [ Moves.ROOST, Moves.MIGHTY_CLEAVE, Moves.FLOATY_FALL, Moves.SKILL_SWAP ], [Species.ARCHEN]: [ Moves.ROOST, Moves.MIGHTY_CLEAVE, Moves.FLOATY_FALL, Moves.SKILL_SWAP ],
[Species.TRUBBISH]: [ Moves.TIDY_UP, Moves.RECOVER, Moves.DIRE_CLAW, Moves.GIGATON_HAMMER ], [Species.TRUBBISH]: [ Moves.TIDY_UP, Moves.RECOVER, Moves.DIRE_CLAW, Moves.GIGATON_HAMMER ],
[Species.ZORUA]: [ Moves.FLAMETHROWER, Moves.PSYCHIC, Moves.AURA_SPHERE, Moves.BADDY_BAD ], [Species.ZORUA]: [ Moves.FLAMETHROWER, Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.FIERY_WRATH ],
[Species.MINCCINO]: [ Moves.ICICLE_SPEAR, Moves.TIDY_UP, Moves.KNOCK_OFF, Moves.POPULATION_BOMB ], [Species.MINCCINO]: [ Moves.ICICLE_SPEAR, Moves.TIDY_UP, Moves.KNOCK_OFF, Moves.POPULATION_BOMB ],
[Species.GOTHITA]: [ Moves.MILK_DRINK, Moves.COSMIC_POWER, Moves.AURA_SPHERE, Moves.PSYSTRIKE ], [Species.GOTHITA]: [ Moves.MILK_DRINK, Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.PSYSTRIKE ],
[Species.SOLOSIS]: [ Moves.COSMIC_POWER, Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.PSYSTRIKE ], [Species.SOLOSIS]: [ Moves.COSMIC_POWER, Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.PSYSTRIKE ],
[Species.DUCKLETT]: [ Moves.QUIVER_DANCE, Moves.EARTH_POWER, Moves.FREEZE_DRY, Moves.OBLIVION_WING ], [Species.DUCKLETT]: [ Moves.QUIVER_DANCE, Moves.EARTH_POWER, Moves.FREEZE_DRY, Moves.OBLIVION_WING ],
[Species.VANILLITE]: [ Moves.EARTH_POWER, Moves.AURORA_VEIL, Moves.DECORATE, Moves.MILK_DRINK ], [Species.VANILLITE]: [ Moves.EARTH_POWER, Moves.AURORA_VEIL, Moves.DECORATE, Moves.MILK_DRINK ],
@ -304,7 +304,7 @@ export const speciesEggMoves = {
[Species.FERROSEED]: [ Moves.STRENGTH_SAP, Moves.BODY_PRESS, Moves.SPIKY_SHIELD, Moves.SAPPY_SEED ], [Species.FERROSEED]: [ Moves.STRENGTH_SAP, Moves.BODY_PRESS, Moves.SPIKY_SHIELD, Moves.SAPPY_SEED ],
[Species.KLINK]: [ Moves.FLARE_BLITZ, Moves.HIGH_HORSEPOWER, Moves.FUSION_BOLT, Moves.DOUBLE_IRON_BASH ], [Species.KLINK]: [ Moves.FLARE_BLITZ, Moves.HIGH_HORSEPOWER, Moves.FUSION_BOLT, Moves.DOUBLE_IRON_BASH ],
[Species.TYNAMO]: [ Moves.SCALD, Moves.STRENGTH_SAP, Moves.FIRE_LASH, Moves.PLASMA_FISTS ], [Species.TYNAMO]: [ Moves.SCALD, Moves.STRENGTH_SAP, Moves.FIRE_LASH, Moves.PLASMA_FISTS ],
[Species.ELGYEM]: [ Moves.MYSTICAL_POWER, Moves.TRICK_ROOM, Moves.STORED_POWER, Moves.LUMINA_CRASH ], [Species.ELGYEM]: [ Moves.MYSTICAL_POWER, Moves.TRICK_ROOM, Moves.STORED_POWER, Moves.ASTRAL_BARRAGE ],
[Species.LITWICK]: [ Moves.FIERY_DANCE, Moves.EARTH_POWER, Moves.MOONBLAST, Moves.ASTRAL_BARRAGE ], [Species.LITWICK]: [ Moves.FIERY_DANCE, Moves.EARTH_POWER, Moves.MOONBLAST, Moves.ASTRAL_BARRAGE ],
[Species.AXEW]: [ Moves.STONE_AXE, Moves.DIRE_CLAW, Moves.FIRE_LASH, Moves.GLAIVE_RUSH ], [Species.AXEW]: [ Moves.STONE_AXE, Moves.DIRE_CLAW, Moves.FIRE_LASH, Moves.GLAIVE_RUSH ],
[Species.CUBCHOO]: [ Moves.TRIPLE_AXEL, Moves.LIQUIDATION, Moves.SWORDS_DANCE, Moves.COLLISION_COURSE ], [Species.CUBCHOO]: [ Moves.TRIPLE_AXEL, Moves.LIQUIDATION, Moves.SWORDS_DANCE, Moves.COLLISION_COURSE ],
@ -312,7 +312,7 @@ export const speciesEggMoves = {
[Species.SHELMET]: [ Moves.SHED_TAIL, Moves.NASTY_PLOT, Moves.BATON_PASS, Moves.HEAT_WAVE ], [Species.SHELMET]: [ Moves.SHED_TAIL, Moves.NASTY_PLOT, Moves.BATON_PASS, Moves.HEAT_WAVE ],
[Species.STUNFISK]: [ Moves.SHORE_UP, Moves.BANEFUL_BUNKER, Moves.THUNDER_CAGE, Moves.THUNDERCLAP ], [Species.STUNFISK]: [ Moves.SHORE_UP, Moves.BANEFUL_BUNKER, Moves.THUNDER_CAGE, Moves.THUNDERCLAP ],
[Species.MIENFOO]: [ Moves.GUNK_SHOT, Moves.SUPERCELL_SLAM, Moves.KNOCK_OFF, Moves.MOUNTAIN_GALE ], [Species.MIENFOO]: [ Moves.GUNK_SHOT, Moves.SUPERCELL_SLAM, Moves.KNOCK_OFF, Moves.MOUNTAIN_GALE ],
[Species.DRUDDIGON]: [ Moves.GLARE, Moves.ROOST, Moves.DRAGON_HAMMER, Moves.FIRE_LASH ], [Species.DRUDDIGON]: [ Moves.FIRE_LASH, Moves.ROOST, Moves.DRAGON_DARTS, Moves.CLANGOROUS_SOUL ],
[Species.GOLETT]: [ Moves.SHIFT_GEAR, Moves.DRAIN_PUNCH, Moves.HEADLONG_RUSH, Moves.RAGE_FIST ], [Species.GOLETT]: [ Moves.SHIFT_GEAR, Moves.DRAIN_PUNCH, Moves.HEADLONG_RUSH, Moves.RAGE_FIST ],
[Species.PAWNIARD]: [ Moves.SUCKER_PUNCH, Moves.CEASELESS_EDGE, Moves.BITTER_BLADE, Moves.LAST_RESPECTS ], [Species.PAWNIARD]: [ Moves.SUCKER_PUNCH, Moves.CEASELESS_EDGE, Moves.BITTER_BLADE, Moves.LAST_RESPECTS ],
[Species.BOUFFALANT]: [ Moves.SLACK_OFF, Moves.JUMP_KICK, Moves.HEAD_SMASH, Moves.FLARE_BLITZ ], [Species.BOUFFALANT]: [ Moves.SLACK_OFF, Moves.JUMP_KICK, Moves.HEAD_SMASH, Moves.FLARE_BLITZ ],
@ -330,7 +330,7 @@ export const speciesEggMoves = {
[Species.RESHIRAM]: [ Moves.ROOST, Moves.TAKE_HEART, Moves.ERUPTION, Moves.DRAGON_ENERGY ], [Species.RESHIRAM]: [ Moves.ROOST, Moves.TAKE_HEART, Moves.ERUPTION, Moves.DRAGON_ENERGY ],
[Species.ZEKROM]: [ Moves.DRAGON_DANCE, Moves.THUNDEROUS_KICK, Moves.DRAGON_HAMMER, Moves.BOLT_BEAK ], [Species.ZEKROM]: [ Moves.DRAGON_DANCE, Moves.THUNDEROUS_KICK, Moves.DRAGON_HAMMER, Moves.BOLT_BEAK ],
[Species.LANDORUS]: [ Moves.STONE_AXE, Moves.THOUSAND_ARROWS, Moves.ROOST, Moves.FLOATY_FALL ], [Species.LANDORUS]: [ Moves.STONE_AXE, Moves.THOUSAND_ARROWS, Moves.ROOST, Moves.FLOATY_FALL ],
[Species.KYUREM]: [ Moves.ICICLE_CRASH, Moves.DRAGON_ENERGY, Moves.NASTY_PLOT, Moves.GLACIAL_LANCE ], [Species.KYUREM]: [ Moves.DRAGON_DARTS, Moves.DRAGON_ENERGY, Moves.NO_RETREAT, Moves.GLACIAL_LANCE ],
[Species.KELDEO]: [ Moves.BOUNCY_BUBBLE, Moves.THUNDERBOLT, Moves.FREEZE_DRY, Moves.STEAM_ERUPTION ], [Species.KELDEO]: [ Moves.BOUNCY_BUBBLE, Moves.THUNDERBOLT, Moves.FREEZE_DRY, Moves.STEAM_ERUPTION ],
[Species.MELOETTA]: [ Moves.TORCH_SONG, Moves.QUIVER_DANCE, Moves.THUNDEROUS_KICK, Moves.BOOMBURST ], [Species.MELOETTA]: [ Moves.TORCH_SONG, Moves.QUIVER_DANCE, Moves.THUNDEROUS_KICK, Moves.BOOMBURST ],
[Species.GENESECT]: [ Moves.EXTREME_SPEED, Moves.U_TURN, Moves.SHIFT_GEAR, Moves.TAIL_GLOW ], [Species.GENESECT]: [ Moves.EXTREME_SPEED, Moves.U_TURN, Moves.SHIFT_GEAR, Moves.TAIL_GLOW ],
@ -352,7 +352,7 @@ export const speciesEggMoves = {
[Species.INKAY]: [ Moves.POWER_TRIP, Moves.STORED_POWER, Moves.RECOVER, Moves.PSYCHO_BOOST ], [Species.INKAY]: [ Moves.POWER_TRIP, Moves.STORED_POWER, Moves.RECOVER, Moves.PSYCHO_BOOST ],
[Species.BINACLE]: [ Moves.TRIPLE_AXEL, Moves.ACCELEROCK, Moves.DIRE_CLAW, Moves.MIGHTY_CLEAVE ], [Species.BINACLE]: [ Moves.TRIPLE_AXEL, Moves.ACCELEROCK, Moves.DIRE_CLAW, Moves.MIGHTY_CLEAVE ],
[Species.SKRELP]: [ Moves.RECOVER, Moves.CORE_ENFORCER, Moves.CALM_MIND, Moves.MALIGNANT_CHAIN ], [Species.SKRELP]: [ Moves.RECOVER, Moves.CORE_ENFORCER, Moves.CALM_MIND, Moves.MALIGNANT_CHAIN ],
[Species.CLAUNCHER]: [ Moves.SHELL_SMASH, Moves.ARMOR_CANNON, Moves.TERRAIN_PULSE, Moves.ORIGIN_PULSE ], [Species.CLAUNCHER]: [ Moves.SHELL_SMASH, Moves.ARMOR_CANNON, Moves.WATER_SHURIKEN, Moves.ORIGIN_PULSE ],
[Species.HELIOPTILE]: [ Moves.WEATHER_BALL, Moves.BOOMBURST, Moves.EARTH_POWER, Moves.TAIL_GLOW ], [Species.HELIOPTILE]: [ Moves.WEATHER_BALL, Moves.BOOMBURST, Moves.EARTH_POWER, Moves.TAIL_GLOW ],
[Species.TYRUNT]: [ Moves.DRAGON_HAMMER, Moves.FLARE_BLITZ, Moves.VOLT_TACKLE, Moves.AXE_KICK ], [Species.TYRUNT]: [ Moves.DRAGON_HAMMER, Moves.FLARE_BLITZ, Moves.VOLT_TACKLE, Moves.AXE_KICK ],
[Species.AMAURA]: [ Moves.RECOVER, Moves.AURORA_VEIL, Moves.POWER_GEM, Moves.GEOMANCY ], [Species.AMAURA]: [ Moves.RECOVER, Moves.AURORA_VEIL, Moves.POWER_GEM, Moves.GEOMANCY ],
@ -369,7 +369,7 @@ export const speciesEggMoves = {
[Species.YVELTAL]: [ Moves.SLUDGE_WAVE, Moves.POWER_TRIP, Moves.FIERY_WRATH, Moves.CLANGOROUS_SOUL ], [Species.YVELTAL]: [ Moves.SLUDGE_WAVE, Moves.POWER_TRIP, Moves.FIERY_WRATH, Moves.CLANGOROUS_SOUL ],
[Species.ZYGARDE]: [ Moves.DRAGON_DARTS, Moves.HEAL_ORDER, Moves.VICTORY_DANCE, Moves.DOUBLE_IRON_BASH ], [Species.ZYGARDE]: [ Moves.DRAGON_DARTS, Moves.HEAL_ORDER, Moves.VICTORY_DANCE, Moves.DOUBLE_IRON_BASH ],
[Species.DIANCIE]: [ Moves.MAGICAL_TORQUE, Moves.BODY_PRESS, Moves.SHORE_UP, Moves.GEOMANCY ], [Species.DIANCIE]: [ Moves.MAGICAL_TORQUE, Moves.BODY_PRESS, Moves.SHORE_UP, Moves.GEOMANCY ],
[Species.HOOPA]: [ Moves.PHOTON_GEYSER, Moves.EARTH_POWER, Moves.BATON_PASS, Moves.TIDY_UP ], [Species.HOOPA]: [ Moves.PHOTON_GEYSER, Moves.SECRET_SWORD, Moves.TIDY_UP, Moves.WICKED_BLOW ],
[Species.VOLCANION]: [ Moves.HYDRO_STEAM, Moves.CALM_MIND, Moves.ENERGY_BALL, Moves.SEARING_SHOT ], [Species.VOLCANION]: [ Moves.HYDRO_STEAM, Moves.CALM_MIND, Moves.ENERGY_BALL, Moves.SEARING_SHOT ],
[Species.ROWLET]: [ Moves.SNIPE_SHOT, Moves.POLTERGEIST, Moves.FIRST_IMPRESSION, Moves.VICTORY_DANCE ], [Species.ROWLET]: [ Moves.SNIPE_SHOT, Moves.POLTERGEIST, Moves.FIRST_IMPRESSION, Moves.VICTORY_DANCE ],
[Species.LITTEN]: [ Moves.FAKE_OUT, Moves.PARTING_SHOT, Moves.MORNING_SUN, Moves.SACRED_FIRE ], [Species.LITTEN]: [ Moves.FAKE_OUT, Moves.PARTING_SHOT, Moves.MORNING_SUN, Moves.SACRED_FIRE ],
@ -386,7 +386,7 @@ export const speciesEggMoves = {
[Species.MUDBRAY]: [ Moves.BODY_PRESS, Moves.YAWN, Moves.SHORE_UP, Moves.THOUSAND_WAVES ], [Species.MUDBRAY]: [ Moves.BODY_PRESS, Moves.YAWN, Moves.SHORE_UP, Moves.THOUSAND_WAVES ],
[Species.DEWPIDER]: [ Moves.AQUA_JET, Moves.SILK_TRAP, Moves.SWORDS_DANCE, Moves.AQUA_STEP ], [Species.DEWPIDER]: [ Moves.AQUA_JET, Moves.SILK_TRAP, Moves.SWORDS_DANCE, Moves.AQUA_STEP ],
[Species.FOMANTIS]: [ Moves.SUPERPOWER, Moves.HEADLONG_RUSH, Moves.ICE_HAMMER, Moves.BITTER_BLADE ], [Species.FOMANTIS]: [ Moves.SUPERPOWER, Moves.HEADLONG_RUSH, Moves.ICE_HAMMER, Moves.BITTER_BLADE ],
[Species.MORELULL]: [ Moves.CALM_MIND, Moves.LEECH_SEED, Moves.STRENGTH_SAP, Moves.SPARKLY_SWIRL ], [Species.MORELULL]: [ Moves.CALM_MIND, Moves.SAPPY_SEED, Moves.SPARKLY_SWIRL, Moves.MATCHA_GOTCHA ],
[Species.SALANDIT]: [ Moves.FAKE_OUT, Moves.FIERY_DANCE, Moves.SCALD, Moves.MALIGNANT_CHAIN ], [Species.SALANDIT]: [ Moves.FAKE_OUT, Moves.FIERY_DANCE, Moves.SCALD, Moves.MALIGNANT_CHAIN ],
[Species.STUFFUL]: [ Moves.DRAIN_PUNCH, Moves.METEOR_MASH, Moves.ICE_HAMMER, Moves.RAGE_FIST ], [Species.STUFFUL]: [ Moves.DRAIN_PUNCH, Moves.METEOR_MASH, Moves.ICE_HAMMER, Moves.RAGE_FIST ],
[Species.BOUNSWEET]: [ Moves.TRIPLE_AXEL, Moves.AQUA_STEP, Moves.THUNDEROUS_KICK, Moves.SAPPY_SEED ], [Species.BOUNSWEET]: [ Moves.TRIPLE_AXEL, Moves.AQUA_STEP, Moves.THUNDEROUS_KICK, Moves.SAPPY_SEED ],
@ -394,12 +394,12 @@ export const speciesEggMoves = {
[Species.ORANGURU]: [ Moves.FOUL_PLAY, Moves.YAWN, Moves.FOLLOW_ME, Moves.LUNAR_BLESSING ], [Species.ORANGURU]: [ Moves.FOUL_PLAY, Moves.YAWN, Moves.FOLLOW_ME, Moves.LUNAR_BLESSING ],
[Species.PASSIMIAN]: [ Moves.FAKE_OUT, Moves.SUCKER_PUNCH, Moves.SWORDS_DANCE, Moves.PYRO_BALL ], [Species.PASSIMIAN]: [ Moves.FAKE_OUT, Moves.SUCKER_PUNCH, Moves.SWORDS_DANCE, Moves.PYRO_BALL ],
[Species.WIMPOD]: [ Moves.ICE_SPINNER, Moves.OBSTRUCT, Moves.KNOCK_OFF, Moves.SURGING_STRIKES ], [Species.WIMPOD]: [ Moves.ICE_SPINNER, Moves.OBSTRUCT, Moves.KNOCK_OFF, Moves.SURGING_STRIKES ],
[Species.SANDYGAST]: [ Moves.SCORCHING_SANDS, Moves.PARTING_SHOT, Moves.CURSE, Moves.SALT_CURE ], [Species.SANDYGAST]: [ Moves.SCORCHING_SANDS, Moves.SPLISHY_SPLASH, Moves.CURSE, Moves.SALT_CURE ],
[Species.PYUKUMUKU]: [ Moves.MIRROR_COAT, Moves.BANEFUL_BUNKER, Moves.TOXIC_SPIKES, Moves.SALT_CURE ], [Species.PYUKUMUKU]: [ Moves.COMEUPPANCE, Moves.BANEFUL_BUNKER, Moves.TOXIC_SPIKES, Moves.SALT_CURE ],
[Species.TYPE_NULL]: [ Moves.DIRE_CLAW, Moves.RECOVER, Moves.EXTREME_SPEED, Moves.NO_RETREAT ], [Species.TYPE_NULL]: [ Moves.DIRE_CLAW, Moves.RECOVER, Moves.EXTREME_SPEED, Moves.NO_RETREAT ],
[Species.MINIOR]: [ Moves.EARTH_POWER, Moves.FLOATY_FALL, Moves.ZING_ZAP, Moves.DIAMOND_STORM ], [Species.MINIOR]: [ Moves.EARTH_POWER, Moves.FLOATY_FALL, Moves.ZING_ZAP, Moves.DIAMOND_STORM ],
[Species.KOMALA]: [ Moves.SLACK_OFF, Moves.EXTREME_SPEED, Moves.KNOCK_OFF, Moves.CLOSE_COMBAT ], [Species.KOMALA]: [ Moves.SLACK_OFF, Moves.EXTREME_SPEED, Moves.KNOCK_OFF, Moves.CLOSE_COMBAT ],
[Species.TURTONATOR]: [ Moves.SHELL_SMASH, Moves.ARMOR_CANNON, Moves.EARTH_POWER, Moves.CLANGING_SCALES ], [Species.TURTONATOR]: [ Moves.BURNING_BULWARK, Moves.ARMOR_CANNON, Moves.EARTH_POWER, Moves.CLANGING_SCALES ],
[Species.TOGEDEMARU]: [ Moves.FAKE_OUT, Moves.METAL_BURST, Moves.METEOR_MASH, Moves.BOLT_STRIKE ], [Species.TOGEDEMARU]: [ Moves.FAKE_OUT, Moves.METAL_BURST, Moves.METEOR_MASH, Moves.BOLT_STRIKE ],
[Species.MIMIKYU]: [ Moves.SPIRIT_BREAK, Moves.TIDY_UP, Moves.SIZZLY_SLIDE, Moves.SPECTRAL_THIEF ], [Species.MIMIKYU]: [ Moves.SPIRIT_BREAK, Moves.TIDY_UP, Moves.SIZZLY_SLIDE, Moves.SPECTRAL_THIEF ],
[Species.BRUXISH]: [ Moves.ICE_FANG, Moves.FIRE_FANG, Moves.FLIP_TURN, Moves.FILLET_AWAY ], [Species.BRUXISH]: [ Moves.ICE_FANG, Moves.FIRE_FANG, Moves.FLIP_TURN, Moves.FILLET_AWAY ],
@ -410,12 +410,12 @@ export const speciesEggMoves = {
[Species.TAPU_LELE]: [ Moves.MOONLIGHT, Moves.NASTY_PLOT, Moves.HEAT_WAVE, Moves.EXPANDING_FORCE ], [Species.TAPU_LELE]: [ Moves.MOONLIGHT, Moves.NASTY_PLOT, Moves.HEAT_WAVE, Moves.EXPANDING_FORCE ],
[Species.TAPU_BULU]: [ Moves.GRASSY_GLIDE, Moves.CLOSE_COMBAT, Moves.PLAY_ROUGH, Moves.VICTORY_DANCE ], [Species.TAPU_BULU]: [ Moves.GRASSY_GLIDE, Moves.CLOSE_COMBAT, Moves.PLAY_ROUGH, Moves.VICTORY_DANCE ],
[Species.TAPU_FINI]: [ Moves.AURA_SPHERE, Moves.EARTH_POWER, Moves.RECOVER, Moves.QUIVER_DANCE ], [Species.TAPU_FINI]: [ Moves.AURA_SPHERE, Moves.EARTH_POWER, Moves.RECOVER, Moves.QUIVER_DANCE ],
[Species.COSMOG]: [ Moves.VICTORY_DANCE, Moves.QUIVER_DANCE, Moves.STORED_POWER, Moves.PHOTON_GEYSER ], [Species.COSMOG]: [ Moves.VICTORY_DANCE, Moves.QUIVER_DANCE, Moves.SACRED_FIRE, Moves.PHOTON_GEYSER ],
[Species.NIHILEGO]: [ Moves.RECOVER, Moves.QUIVER_DANCE, Moves.ENERGY_BALL, Moves.MALIGNANT_CHAIN ], [Species.NIHILEGO]: [ Moves.RECOVER, Moves.QUIVER_DANCE, Moves.ENERGY_BALL, Moves.MALIGNANT_CHAIN ],
[Species.BUZZWOLE]: [ Moves.LEECH_LIFE, Moves.BULLET_PUNCH, Moves.DARKEST_LARIAT, Moves.COLLISION_COURSE ], [Species.BUZZWOLE]: [ Moves.LEECH_LIFE, Moves.BULLET_PUNCH, Moves.DARKEST_LARIAT, Moves.COLLISION_COURSE ],
[Species.PHEROMOSA]: [ Moves.AURA_SPHERE, Moves.MAKE_IT_RAIN, Moves.ATTACK_ORDER, Moves.COLLISION_COURSE ], [Species.PHEROMOSA]: [ Moves.AURA_SPHERE, Moves.MAKE_IT_RAIN, Moves.ATTACK_ORDER, Moves.COLLISION_COURSE ],
[Species.XURKITREE]: [ Moves.OVERHEAT, Moves.GIGA_DRAIN, Moves.TAIL_GLOW, Moves.THUNDERCLAP ], [Species.XURKITREE]: [ Moves.OVERHEAT, Moves.GIGA_DRAIN, Moves.TAIL_GLOW, Moves.THUNDERCLAP ],
[Species.CELESTEELA]: [ Moves.ROOST, Moves.BUZZY_BUZZ, Moves.SPIKES, Moves.OBLIVION_WING ], [Species.CELESTEELA]: [ Moves.RECOVER, Moves.BUZZY_BUZZ, Moves.EARTH_POWER, Moves.OBLIVION_WING ],
[Species.KARTANA]: [ Moves.MIGHTY_CLEAVE, Moves.CEASELESS_EDGE, Moves.BITTER_BLADE, Moves.BEHEMOTH_BLADE ], [Species.KARTANA]: [ Moves.MIGHTY_CLEAVE, Moves.CEASELESS_EDGE, Moves.BITTER_BLADE, Moves.BEHEMOTH_BLADE ],
[Species.GUZZLORD]: [ Moves.SUCKER_PUNCH, Moves.COMEUPPANCE, Moves.SLACK_OFF, Moves.RUINATION ], [Species.GUZZLORD]: [ Moves.SUCKER_PUNCH, Moves.COMEUPPANCE, Moves.SLACK_OFF, Moves.RUINATION ],
[Species.NECROZMA]: [ Moves.COSMIC_POWER, Moves.SACRED_FIRE, Moves.ASTRAL_BARRAGE, Moves.CLANGOROUS_SOUL ], [Species.NECROZMA]: [ Moves.COSMIC_POWER, Moves.SACRED_FIRE, Moves.ASTRAL_BARRAGE, Moves.CLANGOROUS_SOUL ],
@ -426,9 +426,9 @@ export const speciesEggMoves = {
[Species.BLACEPHALON]: [ Moves.NASTY_PLOT, Moves.SEARING_SHOT, Moves.GIGA_DRAIN, Moves.ASTRAL_BARRAGE ], [Species.BLACEPHALON]: [ Moves.NASTY_PLOT, Moves.SEARING_SHOT, Moves.GIGA_DRAIN, Moves.ASTRAL_BARRAGE ],
[Species.ZERAORA]: [ Moves.SWORDS_DANCE, Moves.TRIPLE_AXEL, Moves.BOLT_STRIKE, Moves.PYRO_BALL ], [Species.ZERAORA]: [ Moves.SWORDS_DANCE, Moves.TRIPLE_AXEL, Moves.BOLT_STRIKE, Moves.PYRO_BALL ],
[Species.MELTAN]: [ Moves.BULLET_PUNCH, Moves.DRAIN_PUNCH, Moves.BULK_UP, Moves.PLASMA_FISTS ], [Species.MELTAN]: [ Moves.BULLET_PUNCH, Moves.DRAIN_PUNCH, Moves.BULK_UP, Moves.PLASMA_FISTS ],
[Species.GROOKEY]: [ Moves.HEADLONG_RUSH, Moves.CLOSE_COMBAT, Moves.GRASSY_GLIDE, Moves.CLANGOROUS_SOUL ], [Species.GROOKEY]: [ Moves.HIGH_HORSEPOWER, Moves.CLANGOROUS_SOUL, Moves.GRASSY_GLIDE, Moves.SAPPY_SEED ],
[Species.SCORBUNNY]: [ Moves.EXTREME_SPEED, Moves.TROP_KICK, Moves.TRIPLE_AXEL, Moves.THUNDEROUS_KICK ], [Species.SCORBUNNY]: [ Moves.EXTREME_SPEED, Moves.HIGH_JUMP_KICK, Moves.TRIPLE_AXEL, Moves.BOLT_STRIKE ],
[Species.SOBBLE]: [ Moves.AEROBLAST, Moves.FROST_BREATH, Moves.SEARING_SHOT, Moves.SURGING_STRIKES ], [Species.SOBBLE]: [ Moves.ESPER_WING, Moves.FROST_BREATH, Moves.SEARING_SHOT, Moves.STEAM_ERUPTION ],
[Species.SKWOVET]: [ Moves.KNOCK_OFF, Moves.GRAV_APPLE, Moves.BODY_PRESS, Moves.SLACK_OFF ], [Species.SKWOVET]: [ Moves.KNOCK_OFF, Moves.GRAV_APPLE, Moves.BODY_PRESS, Moves.SLACK_OFF ],
[Species.ROOKIDEE]: [ Moves.ROOST, Moves.BODY_PRESS, Moves.IRON_HEAD, Moves.KINGS_SHIELD ], [Species.ROOKIDEE]: [ Moves.ROOST, Moves.BODY_PRESS, Moves.IRON_HEAD, Moves.KINGS_SHIELD ],
[Species.BLIPBUG]: [ Moves.HEAL_ORDER, Moves.EXPANDING_FORCE, Moves.SPORE, Moves.TAIL_GLOW ], [Species.BLIPBUG]: [ Moves.HEAL_ORDER, Moves.EXPANDING_FORCE, Moves.SPORE, Moves.TAIL_GLOW ],
@ -438,7 +438,7 @@ export const speciesEggMoves = {
[Species.CHEWTLE]: [ Moves.FIRE_FANG, Moves.ACCELEROCK, Moves.SHELL_SMASH, Moves.WAVE_CRASH ], [Species.CHEWTLE]: [ Moves.FIRE_FANG, Moves.ACCELEROCK, Moves.SHELL_SMASH, Moves.WAVE_CRASH ],
[Species.YAMPER]: [ Moves.ICE_FANG, Moves.TIDY_UP, Moves.THUNDERCLAP, Moves.ZING_ZAP ], [Species.YAMPER]: [ Moves.ICE_FANG, Moves.TIDY_UP, Moves.THUNDERCLAP, Moves.ZING_ZAP ],
[Species.ROLYCOLY]: [ Moves.BURNING_BULWARK, Moves.ZING_ZAP, Moves.WORK_UP, Moves.DIAMOND_STORM ], [Species.ROLYCOLY]: [ Moves.BURNING_BULWARK, Moves.ZING_ZAP, Moves.WORK_UP, Moves.DIAMOND_STORM ],
[Species.APPLIN]: [ Moves.DRAGON_CHEER, Moves.PARTING_SHOT, Moves.FLOWER_TRICK, Moves.STRENGTH_SAP ], [Species.APPLIN]: [ Moves.DRAGON_CHEER, Moves.DRAGON_HAMMER, Moves.FLOWER_TRICK, Moves.STRENGTH_SAP ],
[Species.SILICOBRA]: [ Moves.SHORE_UP, Moves.SHED_TAIL, Moves.STONE_EDGE, Moves.PRECIPICE_BLADES ], [Species.SILICOBRA]: [ Moves.SHORE_UP, Moves.SHED_TAIL, Moves.STONE_EDGE, Moves.PRECIPICE_BLADES ],
[Species.CRAMORANT]: [ Moves.APPLE_ACID, Moves.SURF, Moves.SCORCHING_SANDS, Moves.OBLIVION_WING ], [Species.CRAMORANT]: [ Moves.APPLE_ACID, Moves.SURF, Moves.SCORCHING_SANDS, Moves.OBLIVION_WING ],
[Species.ARROKUDA]: [ Moves.THUNDER_FANG, Moves.KNOCK_OFF, Moves.ICE_FANG, Moves.FILLET_AWAY ], [Species.ARROKUDA]: [ Moves.THUNDER_FANG, Moves.KNOCK_OFF, Moves.ICE_FANG, Moves.FILLET_AWAY ],
@ -452,11 +452,11 @@ export const speciesEggMoves = {
[Species.FALINKS]: [ Moves.COMBAT_TORQUE, Moves.PSYSHIELD_BASH, Moves.HEAL_ORDER, Moves.POPULATION_BOMB ], [Species.FALINKS]: [ Moves.COMBAT_TORQUE, Moves.PSYSHIELD_BASH, Moves.HEAL_ORDER, Moves.POPULATION_BOMB ],
[Species.PINCURCHIN]: [ Moves.TRICK_ROOM, Moves.RISING_VOLTAGE, Moves.STRENGTH_SAP, Moves.THUNDERCLAP ], [Species.PINCURCHIN]: [ Moves.TRICK_ROOM, Moves.RISING_VOLTAGE, Moves.STRENGTH_SAP, Moves.THUNDERCLAP ],
[Species.SNOM]: [ Moves.MOONBLAST, Moves.SURF, Moves.EARTH_POWER, Moves.FIERY_DANCE ], [Species.SNOM]: [ Moves.MOONBLAST, Moves.SURF, Moves.EARTH_POWER, Moves.FIERY_DANCE ],
[Species.STONJOURNER]: [ Moves.BODY_PRESS, Moves.BULK_UP, Moves.SHORE_UP, Moves.ACCELEROCK ], [Species.STONJOURNER]: [ Moves.BODY_PRESS, Moves.HELPING_HAND, Moves.ACCELEROCK, Moves.DIAMOND_STORM ],
[Species.EISCUE]: [ Moves.TRIPLE_AXEL, Moves.AQUA_STEP, Moves.SHELL_SMASH, Moves.GLACIAL_LANCE ], [Species.EISCUE]: [ Moves.TRIPLE_AXEL, Moves.AQUA_STEP, Moves.SHELL_SMASH, Moves.GLACIAL_LANCE ],
[Species.INDEEDEE]: [ Moves.MATCHA_GOTCHA, Moves.EXPANDING_FORCE, Moves.MOONBLAST, Moves.REVIVAL_BLESSING ], [Species.INDEEDEE]: [ Moves.MATCHA_GOTCHA, Moves.EXPANDING_FORCE, Moves.MOONBLAST, Moves.REVIVAL_BLESSING ],
[Species.MORPEKO]: [ Moves.TRIPLE_AXEL, Moves.OBSTRUCT, Moves.PARTING_SHOT, Moves.SWORDS_DANCE ], [Species.MORPEKO]: [ Moves.TRIPLE_AXEL, Moves.OBSTRUCT, Moves.PARTING_SHOT, Moves.SWORDS_DANCE ],
[Species.CUFANT]: [ Moves.LIQUIDATION, Moves.HEAVY_SLAM, Moves.CLOSE_COMBAT, Moves.GIGATON_HAMMER ], [Species.CUFANT]: [ Moves.LIQUIDATION, Moves.CURSE, Moves.COMBAT_TORQUE, Moves.GIGATON_HAMMER ],
[Species.DRACOZOLT]: [ Moves.TRIPLE_AXEL, Moves.DRAGON_HAMMER, Moves.FIRE_LASH, Moves.DRAGON_DANCE ], [Species.DRACOZOLT]: [ Moves.TRIPLE_AXEL, Moves.DRAGON_HAMMER, Moves.FIRE_LASH, Moves.DRAGON_DANCE ],
[Species.ARCTOZOLT]: [ Moves.TRIPLE_AXEL, Moves.LIQUIDATION, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ], [Species.ARCTOZOLT]: [ Moves.TRIPLE_AXEL, Moves.LIQUIDATION, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ],
[Species.DRACOVISH]: [ Moves.TRIPLE_AXEL, Moves.DRAGON_HAMMER, Moves.THUNDER_FANG, Moves.DRAGON_DANCE ], [Species.DRACOVISH]: [ Moves.TRIPLE_AXEL, Moves.DRAGON_HAMMER, Moves.THUNDER_FANG, Moves.DRAGON_DANCE ],
@ -467,8 +467,8 @@ export const speciesEggMoves = {
[Species.ZAMAZENTA]: [ Moves.PSYSHIELD_BASH, Moves.BODY_PRESS, Moves.SLACK_OFF, Moves.VICTORY_DANCE ], [Species.ZAMAZENTA]: [ Moves.PSYSHIELD_BASH, Moves.BODY_PRESS, Moves.SLACK_OFF, Moves.VICTORY_DANCE ],
[Species.KUBFU]: [ Moves.METEOR_MASH, Moves.DRAIN_PUNCH, Moves.JET_PUNCH, Moves.DRAGON_DANCE ], [Species.KUBFU]: [ Moves.METEOR_MASH, Moves.DRAIN_PUNCH, Moves.JET_PUNCH, Moves.DRAGON_DANCE ],
[Species.ZARUDE]: [ Moves.SAPPY_SEED, Moves.PARTING_SHOT, Moves.WICKED_BLOW, Moves.VICTORY_DANCE ], [Species.ZARUDE]: [ Moves.SAPPY_SEED, Moves.PARTING_SHOT, Moves.WICKED_BLOW, Moves.VICTORY_DANCE ],
[Species.REGIELEKI]: [ Moves.NASTY_PLOT, Moves.FROST_BREATH, Moves.PARTING_SHOT, Moves.ELECTRO_DRIFT ], [Species.REGIELEKI]: [ Moves.NASTY_PLOT, Moves.ICE_BEAM, Moves.EARTH_POWER, Moves.ELECTRO_DRIFT ],
[Species.REGIDRAGO]: [ Moves.METEOR_MASH, Moves.FLAMETHROWER, Moves.CALM_MIND, Moves.DRAGON_DARTS ], [Species.REGIDRAGO]: [ Moves.METEOR_MASH, Moves.FLAMETHROWER, Moves.TAKE_HEART, Moves.DRAGON_DARTS ],
[Species.GLASTRIER]: [ Moves.TRICK_ROOM, Moves.SLACK_OFF, Moves.HIGH_HORSEPOWER, Moves.GLACIAL_LANCE ], [Species.GLASTRIER]: [ Moves.TRICK_ROOM, Moves.SLACK_OFF, Moves.HIGH_HORSEPOWER, Moves.GLACIAL_LANCE ],
[Species.SPECTRIER]: [ Moves.EARTH_POWER, Moves.PARTING_SHOT, Moves.AURA_SPHERE, Moves.ASTRAL_BARRAGE ], [Species.SPECTRIER]: [ Moves.EARTH_POWER, Moves.PARTING_SHOT, Moves.AURA_SPHERE, Moves.ASTRAL_BARRAGE ],
[Species.CALYREX]: [ Moves.SAPPY_SEED, Moves.RECOVER, Moves.SECRET_SWORD, Moves.PHOTON_GEYSER ], [Species.CALYREX]: [ Moves.SAPPY_SEED, Moves.RECOVER, Moves.SECRET_SWORD, Moves.PHOTON_GEYSER ],
@ -478,40 +478,40 @@ export const speciesEggMoves = {
[Species.QUAXLY]: [ Moves.DRAGON_DANCE, Moves.TRIPLE_AXEL, Moves.TROP_KICK, Moves.THUNDEROUS_KICK ], [Species.QUAXLY]: [ Moves.DRAGON_DANCE, Moves.TRIPLE_AXEL, Moves.TROP_KICK, Moves.THUNDEROUS_KICK ],
[Species.LECHONK]: [ Moves.MILK_DRINK, Moves.BLAZING_TORQUE, Moves.FILLET_AWAY, Moves.MULTI_ATTACK ], [Species.LECHONK]: [ Moves.MILK_DRINK, Moves.BLAZING_TORQUE, Moves.FILLET_AWAY, Moves.MULTI_ATTACK ],
[Species.TAROUNTULA]: [ Moves.STONE_AXE, Moves.LEECH_LIFE, Moves.THIEF, Moves.SPORE ], [Species.TAROUNTULA]: [ Moves.STONE_AXE, Moves.LEECH_LIFE, Moves.THIEF, Moves.SPORE ],
[Species.NYMBLE]: [ Moves.CEASELESS_EDGE, Moves.FELL_STINGER, Moves.LEECH_LIFE, Moves.WICKED_BLOW ], [Species.NYMBLE]: [ Moves.CEASELESS_EDGE, Moves.FELL_STINGER, Moves.ATTACK_ORDER, Moves.WICKED_BLOW ],
[Species.PAWMI]: [ Moves.DRAIN_PUNCH, Moves.WISH, Moves.PARTING_SHOT, Moves.PLASMA_FISTS ], [Species.PAWMI]: [ Moves.DRAIN_PUNCH, Moves.ICE_PUNCH, Moves.MACH_PUNCH, Moves.PLASMA_FISTS ],
[Species.TANDEMAUS]: [ Moves.BATON_PASS, Moves.BITE, Moves.SIZZLY_SLIDE, Moves.REVIVAL_BLESSING ], [Species.TANDEMAUS]: [ Moves.BATON_PASS, Moves.THIEF, Moves.SIZZLY_SLIDE, Moves.REVIVAL_BLESSING ],
[Species.FIDOUGH]: [ Moves.WISH, Moves.BODY_PRESS, Moves.PARTING_SHOT, Moves.SIZZLY_SLIDE ], [Species.FIDOUGH]: [ Moves.WISH, Moves.BODY_PRESS, Moves.SIZZLY_SLIDE, Moves.TIDY_UP ],
[Species.SMOLIV]: [ Moves.STRENGTH_SAP, Moves.EARTH_POWER, Moves.CALM_MIND, Moves.BOOMBURST ], [Species.SMOLIV]: [ Moves.STRENGTH_SAP, Moves.EARTH_POWER, Moves.CALM_MIND, Moves.BOOMBURST ],
[Species.SQUAWKABILLY]: [ Moves.PARTING_SHOT, Moves.BULK_UP, Moves.FLARE_BLITZ, Moves.HEAD_CHARGE ], [Species.SQUAWKABILLY]: [ Moves.PARTING_SHOT, Moves.EARTHQUAKE, Moves.FLARE_BLITZ, Moves.EXTREME_SPEED ],
[Species.NACLI]: [ Moves.BODY_PRESS, Moves.SPIKES, Moves.CURSE, Moves.DIAMOND_STORM ], [Species.NACLI]: [ Moves.BODY_PRESS, Moves.TOXIC, Moves.CURSE, Moves.DIAMOND_STORM ],
[Species.CHARCADET]: [ Moves.SACRED_SWORD, Moves.PHOTON_GEYSER, Moves.MOONBLAST, Moves.SPECTRAL_THIEF ], [Species.CHARCADET]: [ Moves.SACRED_SWORD, Moves.PHOTON_GEYSER, Moves.MOONBLAST, Moves.SPECTRAL_THIEF ],
[Species.TADBULB]: [ Moves.PARABOLIC_CHARGE, Moves.SCALD, Moves.EARTH_POWER, Moves.ELECTRO_SHOT ], [Species.TADBULB]: [ Moves.PARABOLIC_CHARGE, Moves.SCALD, Moves.EARTH_POWER, Moves.ELECTRO_SHOT ],
[Species.WATTREL]: [ Moves.NASTY_PLOT, Moves.TAILWIND, Moves.HEAT_WAVE, Moves.AEROBLAST ], [Species.WATTREL]: [ Moves.NASTY_PLOT, Moves.TAILWIND, Moves.HEAT_WAVE, Moves.AEROBLAST ],
[Species.MASCHIFF]: [ Moves.PARTING_SHOT, Moves.KNOCK_OFF, Moves.NUZZLE, Moves.COLLISION_COURSE ], [Species.MASCHIFF]: [ Moves.PARTING_SHOT, Moves.KNOCK_OFF, Moves.PLAY_ROUGH, Moves.COLLISION_COURSE ],
[Species.SHROODLE]: [ Moves.FIRE_LASH, Moves.PARTING_SHOT, Moves.TOXIC, Moves.TOPSY_TURVY ], [Species.SHROODLE]: [ Moves.GASTRO_ACID, Moves.PARTING_SHOT, Moves.TOXIC, Moves.SKETCH ],
[Species.BRAMBLIN]: [ Moves.TAILWIND, Moves.STRENGTH_SAP, Moves.CEASELESS_EDGE, Moves.LAST_RESPECTS ], [Species.BRAMBLIN]: [ Moves.TAILWIND, Moves.STRENGTH_SAP, Moves.CEASELESS_EDGE, Moves.LAST_RESPECTS ],
[Species.TOEDSCOOL]: [ Moves.STRENGTH_SAP, Moves.TOPSY_TURVY, Moves.PARTING_SHOT, Moves.SAPPY_SEED ], [Species.TOEDSCOOL]: [ Moves.STRENGTH_SAP, Moves.TOPSY_TURVY, Moves.PARTING_SHOT, Moves.SAPPY_SEED ],
[Species.KLAWF]: [ Moves.CRABHAMMER, Moves.SHORE_UP, Moves.MIGHTY_CLEAVE, Moves.SHELL_SMASH ], [Species.KLAWF]: [ Moves.CRABHAMMER, Moves.SHORE_UP, Moves.MIGHTY_CLEAVE, Moves.SHELL_SMASH ],
[Species.CAPSAKID]: [ Moves.STRENGTH_SAP, Moves.APPLE_ACID, Moves.FROST_BREATH, Moves.TORCH_SONG ], [Species.CAPSAKID]: [ Moves.STRENGTH_SAP, Moves.APPLE_ACID, Moves.FROST_BREATH, Moves.TORCH_SONG ],
[Species.RELLOR]: [ Moves.TOXIC_SPIKES, Moves.RECOVER, Moves.HEAT_WAVE, Moves.LUMINA_CRASH ], [Species.RELLOR]: [ Moves.TOXIC_SPIKES, Moves.RECOVER, Moves.HEAT_WAVE, Moves.LUMINA_CRASH ],
[Species.FLITTLE]: [ Moves.COSMIC_POWER, Moves.AURA_SPHERE, Moves.ROOST, Moves.SEARING_SHOT ], [Species.FLITTLE]: [ Moves.COSMIC_POWER, Moves.AURA_SPHERE, Moves.ROOST, Moves.FIERY_DANCE ],
[Species.TINKATINK]: [ Moves.NUZZLE, Moves.SHIFT_GEAR, Moves.ICE_HAMMER, Moves.PYRO_BALL ], [Species.TINKATINK]: [ Moves.MAGICAL_TORQUE, Moves.SHIFT_GEAR, Moves.ICE_HAMMER, Moves.PYRO_BALL ],
[Species.WIGLETT]: [ Moves.SHELL_SMASH, Moves.ICICLE_CRASH, Moves.SEED_BOMB, Moves.SURGING_STRIKES ], [Species.WIGLETT]: [ Moves.SHELL_SMASH, Moves.ICICLE_CRASH, Moves.SEED_BOMB, Moves.SURGING_STRIKES ],
[Species.BOMBIRDIER]: [ Moves.U_TURN, Moves.TIDY_UP, Moves.SUCKER_PUNCH, Moves.MIGHTY_CLEAVE ], [Species.BOMBIRDIER]: [ Moves.U_TURN, Moves.TIDY_UP, Moves.SUCKER_PUNCH, Moves.MIGHTY_CLEAVE ],
[Species.FINIZEN]: [ Moves.TRIPLE_AXEL, Moves.DRAIN_PUNCH, Moves.HEADLONG_RUSH, Moves.SURGING_STRIKES ], [Species.FINIZEN]: [ Moves.TRIPLE_AXEL, Moves.DRAIN_PUNCH, Moves.HEADLONG_RUSH, Moves.SURGING_STRIKES ],
[Species.VAROOM]: [ Moves.COMBAT_TORQUE, Moves.U_TURN, Moves.BLAZING_TORQUE, Moves.NOXIOUS_TORQUE ], [Species.VAROOM]: [ Moves.COMBAT_TORQUE, Moves.U_TURN, Moves.BLAZING_TORQUE, Moves.NOXIOUS_TORQUE ],
[Species.CYCLIZAR]: [ Moves.BATON_PASS, Moves.BLAZING_TORQUE, Moves.HEAD_CHARGE, Moves.CLANGOROUS_SOUL ], [Species.CYCLIZAR]: [ Moves.BATON_PASS, Moves.BLAZING_TORQUE, Moves.HEAD_CHARGE, Moves.CLANGOROUS_SOUL ],
[Species.ORTHWORM]: [ Moves.GLARE, Moves.COIL, Moves.BODY_PRESS, Moves.SHORE_UP ], [Species.ORTHWORM]: [ Moves.SIZZLY_SLIDE, Moves.COIL, Moves.BODY_PRESS, Moves.SHORE_UP ],
[Species.GLIMMET]: [ Moves.CALM_MIND, Moves.SHORE_UP, Moves.PARTING_SHOT, Moves.FIERY_DANCE ], [Species.GLIMMET]: [ Moves.CALM_MIND, Moves.EARTH_POWER, Moves.FIERY_DANCE, Moves.MALIGNANT_CHAIN ],
[Species.GREAVARD]: [ Moves.TIDY_UP, Moves.YAWN, Moves.SHORE_UP, Moves.COLLISION_COURSE ], [Species.GREAVARD]: [ Moves.SHADOW_BONE, Moves.YAWN, Moves.SHORE_UP, Moves.COLLISION_COURSE ],
[Species.FLAMIGO]: [ Moves.THUNDEROUS_KICK, Moves.TRIPLE_AXEL, Moves.U_TURN, Moves.VICTORY_DANCE ], [Species.FLAMIGO]: [ Moves.THUNDEROUS_KICK, Moves.TRIPLE_AXEL, Moves.U_TURN, Moves.VICTORY_DANCE ],
[Species.CETODDLE]: [ Moves.ICICLE_CRASH, Moves.HIGH_HORSEPOWER, Moves.RECOVER, Moves.DRAGON_DANCE ], [Species.CETODDLE]: [ Moves.TRIPLE_AXEL, Moves.HIGH_HORSEPOWER, Moves.RECOVER, Moves.DRAGON_DANCE ],
[Species.VELUZA]: [ Moves.CEASELESS_EDGE, Moves.FLIP_TURN, Moves.ICE_SPINNER, Moves.PSYBLADE ], [Species.VELUZA]: [ Moves.CEASELESS_EDGE, Moves.FLIP_TURN, Moves.ICE_SPINNER, Moves.PSYBLADE ],
[Species.DONDOZO]: [ Moves.SOFT_BOILED, Moves.ICE_SPINNER, Moves.TOXIC, Moves.SALT_CURE ], [Species.DONDOZO]: [ Moves.SOFT_BOILED, Moves.ICE_SPINNER, Moves.TOXIC, Moves.SALT_CURE ],
[Species.TATSUGIRI]: [ Moves.ICE_BEAM, Moves.BATON_PASS, Moves.SCALD, Moves.FILLET_AWAY ], [Species.TATSUGIRI]: [ Moves.ICE_BEAM, Moves.FILLET_AWAY, Moves.CORE_ENFORCER, Moves.STEAM_ERUPTION ],
[Species.GREAT_TUSK]: [ Moves.STONE_AXE, Moves.MORNING_SUN, Moves.DRAGON_DANCE, Moves.COLLISION_COURSE ], [Species.GREAT_TUSK]: [ Moves.STONE_AXE, Moves.MORNING_SUN, Moves.DRAGON_DANCE, Moves.COLLISION_COURSE ],
[Species.SCREAM_TAIL]: [ Moves.COSMIC_POWER, Moves.LUMINA_CRASH, Moves.MOONLIGHT, Moves.SHED_TAIL ], [Species.SCREAM_TAIL]: [ Moves.TORCH_SONG, Moves.GLITZY_GLOW, Moves.MOONLIGHT, Moves.SPARKLY_SWIRL ],
[Species.BRUTE_BONNET]: [ Moves.DARKEST_LARIAT, Moves.STRENGTH_SAP, Moves.EARTHQUAKE, Moves.SAPPY_SEED ], [Species.BRUTE_BONNET]: [ Moves.DARKEST_LARIAT, Moves.STRENGTH_SAP, Moves.EARTHQUAKE, Moves.SAPPY_SEED ],
[Species.FLUTTER_MANE]: [ Moves.MOONLIGHT, Moves.FLAMETHROWER, Moves.EARTH_POWER, Moves.ASTRAL_BARRAGE ], [Species.FLUTTER_MANE]: [ Moves.MOONLIGHT, Moves.FLAMETHROWER, Moves.EARTH_POWER, Moves.ASTRAL_BARRAGE ],
[Species.SLITHER_WING]: [ Moves.KNOCK_OFF, Moves.VICTORY_DANCE, Moves.FIRE_LASH, Moves.THUNDEROUS_KICK ], [Species.SLITHER_WING]: [ Moves.KNOCK_OFF, Moves.VICTORY_DANCE, Moves.FIRE_LASH, Moves.THUNDEROUS_KICK ],
@ -521,12 +521,12 @@ export const speciesEggMoves = {
[Species.IRON_HANDS]: [ Moves.DRAIN_PUNCH, Moves.BULK_UP, Moves.PLASMA_FISTS, Moves.ICE_HAMMER ], [Species.IRON_HANDS]: [ Moves.DRAIN_PUNCH, Moves.BULK_UP, Moves.PLASMA_FISTS, Moves.ICE_HAMMER ],
[Species.IRON_JUGULIS]: [ Moves.FIERY_WRATH, Moves.ROOST, Moves.NASTY_PLOT, Moves.OBLIVION_WING ], [Species.IRON_JUGULIS]: [ Moves.FIERY_WRATH, Moves.ROOST, Moves.NASTY_PLOT, Moves.OBLIVION_WING ],
[Species.IRON_MOTH]: [ Moves.EARTH_POWER, Moves.SEARING_SHOT, Moves.QUIVER_DANCE, Moves.MALIGNANT_CHAIN ], [Species.IRON_MOTH]: [ Moves.EARTH_POWER, Moves.SEARING_SHOT, Moves.QUIVER_DANCE, Moves.MALIGNANT_CHAIN ],
[Species.IRON_THORNS]: [ Moves.MIGHTY_CLEAVE, Moves.SHORE_UP, Moves.SHIFT_GEAR, Moves.FUSION_BOLT ], [Species.IRON_THORNS]: [ Moves.DIAMOND_STORM, Moves.SHORE_UP, Moves.SHIFT_GEAR, Moves.PLASMA_FISTS ],
[Species.FRIGIBAX]: [ Moves.DRAGON_DARTS, Moves.BULK_UP, Moves.SHORE_UP, Moves.GLACIAL_LANCE ], [Species.FRIGIBAX]: [ Moves.DRAGON_DARTS, Moves.DRAGON_DANCE, Moves.EARTHQUAKE, Moves.GLACIAL_LANCE ],
[Species.GIMMIGHOUL]: [ Moves.COSMIC_POWER, Moves.STORED_POWER, Moves.BATON_PASS, Moves.ASTRAL_BARRAGE ], [Species.GIMMIGHOUL]: [ Moves.COSMIC_POWER, Moves.STORED_POWER, Moves.EARTH_POWER, Moves.ASTRAL_BARRAGE ],
[Species.WO_CHIEN]: [ Moves.SPORE, Moves.RAGE_POWDER, Moves.SAPPY_SEED, Moves.STRENGTH_SAP ], [Species.WO_CHIEN]: [ Moves.SPORE, Moves.FIERY_WRATH, Moves.SAPPY_SEED, Moves.STRENGTH_SAP ],
[Species.CHIEN_PAO]: [ Moves.KNOCK_OFF, Moves.PARTING_SHOT, Moves.BITTER_BLADE, Moves.GLACIAL_LANCE ], [Species.CHIEN_PAO]: [ Moves.KNOCK_OFF, Moves.PARTING_SHOT, Moves.BITTER_BLADE, Moves.GLACIAL_LANCE ],
[Species.TING_LU]: [ Moves.SHORE_UP, Moves.CURSE, Moves.SAPPY_SEED, Moves.THOUSAND_ARROWS ], [Species.TING_LU]: [ Moves.SHORE_UP, Moves.WICKED_BLOW, Moves.SAPPY_SEED, Moves.THOUSAND_ARROWS ],
[Species.CHI_YU]: [ Moves.FIERY_WRATH, Moves.HYDRO_STEAM, Moves.TORCH_SONG, Moves.ERUPTION ], [Species.CHI_YU]: [ Moves.FIERY_WRATH, Moves.HYDRO_STEAM, Moves.TORCH_SONG, Moves.ERUPTION ],
[Species.ROARING_MOON]: [ Moves.FIRE_LASH, Moves.DRAGON_HAMMER, Moves.SUCKER_PUNCH, Moves.WICKED_BLOW ], [Species.ROARING_MOON]: [ Moves.FIRE_LASH, Moves.DRAGON_HAMMER, Moves.SUCKER_PUNCH, Moves.WICKED_BLOW ],
[Species.IRON_VALIANT]: [ Moves.PLASMA_FISTS, Moves.VICTORY_DANCE, Moves.QUIVER_DANCE, Moves.MAGICAL_TORQUE ], [Species.IRON_VALIANT]: [ Moves.PLASMA_FISTS, Moves.VICTORY_DANCE, Moves.QUIVER_DANCE, Moves.MAGICAL_TORQUE ],
@ -534,28 +534,28 @@ export const speciesEggMoves = {
[Species.MIRAIDON]: [ Moves.ICE_BEAM, Moves.CLANGOROUS_SOUL, Moves.RISING_VOLTAGE, Moves.DRAGON_ENERGY ], [Species.MIRAIDON]: [ Moves.ICE_BEAM, Moves.CLANGOROUS_SOUL, Moves.RISING_VOLTAGE, Moves.DRAGON_ENERGY ],
[Species.WALKING_WAKE]: [ Moves.BOUNCY_BUBBLE, Moves.NASTY_PLOT, Moves.EARTH_POWER, Moves.DRAGON_ENERGY ], [Species.WALKING_WAKE]: [ Moves.BOUNCY_BUBBLE, Moves.NASTY_PLOT, Moves.EARTH_POWER, Moves.DRAGON_ENERGY ],
[Species.IRON_LEAVES]: [ Moves.SPORE, Moves.U_TURN, Moves.MIGHTY_CLEAVE, Moves.BITTER_BLADE ], [Species.IRON_LEAVES]: [ Moves.SPORE, Moves.U_TURN, Moves.MIGHTY_CLEAVE, Moves.BITTER_BLADE ],
[Species.POLTCHAGEIST]: [ Moves.COSMIC_POWER, Moves.INFERNAL_PARADE, Moves.LEECH_SEED, Moves.SPARKLY_SWIRL ], [Species.POLTCHAGEIST]: [ Moves.SHELL_SMASH, Moves.INFERNAL_PARADE, Moves.LEECH_SEED, Moves.SPARKLY_SWIRL ],
[Species.OKIDOGI]: [ Moves.SLACK_OFF, Moves.OBSTRUCT, Moves.DIRE_CLAW, Moves.COLLISION_COURSE ], [Species.OKIDOGI]: [ Moves.DRAIN_PUNCH, Moves.KNOCK_OFF, Moves.DIRE_CLAW, Moves.VICTORY_DANCE ],
[Species.MUNKIDORI]: [ Moves.PSYSTRIKE, Moves.HEAT_WAVE, Moves.EARTH_POWER, Moves.MALIGNANT_CHAIN ], [Species.MUNKIDORI]: [ Moves.PSYSTRIKE, Moves.HEAT_WAVE, Moves.EARTH_POWER, Moves.MALIGNANT_CHAIN ],
[Species.FEZANDIPITI]: [ Moves.BATON_PASS, Moves.COSMIC_POWER, Moves.SIZZLY_SLIDE, Moves.MALIGNANT_CHAIN ], [Species.FEZANDIPITI]: [ Moves.BARB_BARRAGE, Moves.VICTORY_DANCE, Moves.TRIPLE_AXEL, Moves.MAGICAL_TORQUE ],
[Species.OGERPON]: [ Moves.FLOWER_TRICK, Moves.BONEMERANG, Moves.TRIPLE_AXEL, Moves.GIGATON_HAMMER ], [Species.OGERPON]: [ Moves.FLOWER_TRICK, Moves.BONEMERANG, Moves.TRIPLE_AXEL, Moves.GIGATON_HAMMER ],
[Species.GOUGING_FIRE]: [ Moves.SUPERCELL_SLAM, Moves.BULK_UP, Moves.SACRED_FIRE, Moves.GLAIVE_RUSH ], [Species.GOUGING_FIRE]: [ Moves.SUPERCELL_SLAM, Moves.BULK_UP, Moves.SACRED_FIRE, Moves.GLAIVE_RUSH ],
[Species.RAGING_BOLT]: [ Moves.NASTY_PLOT, Moves.FLAMETHROWER, Moves.RECOVER, Moves.ELECTRO_DRIFT ], [Species.RAGING_BOLT]: [ Moves.NASTY_PLOT, Moves.FLAMETHROWER, Moves.RECOVER, Moves.ELECTRO_DRIFT ],
[Species.IRON_BOULDER]: [ Moves.PSYBLADE, Moves.KOWTOW_CLEAVE, Moves.STONE_AXE, Moves.BITTER_BLADE ], [Species.IRON_BOULDER]: [ Moves.PSYBLADE, Moves.KOWTOW_CLEAVE, Moves.STONE_AXE, Moves.BITTER_BLADE ],
[Species.IRON_CROWN]: [ Moves.NASTY_PLOT, Moves.SECRET_SWORD, Moves.PHOTON_GEYSER, Moves.ELECTRO_DRIFT ], [Species.IRON_CROWN]: [ Moves.NASTY_PLOT, Moves.SECRET_SWORD, Moves.PHOTON_GEYSER, Moves.ELECTRO_DRIFT ],
[Species.TERAPAGOS]: [ Moves.EARTH_POWER, Moves.SHORE_UP, Moves.ICE_BEAM, Moves.SHELL_SMASH ], [Species.TERAPAGOS]: [ Moves.MOONBLAST, Moves.RECOVER, Moves.ICE_BEAM, Moves.SHELL_SMASH ],
[Species.PECHARUNT]: [ Moves.TOXIC_SPIKES, Moves.BODY_PRESS, Moves.HEX, Moves.BANEFUL_BUNKER ], [Species.PECHARUNT]: [ Moves.TOXIC_SPIKES, Moves.BODY_PRESS, Moves.HEX, Moves.BANEFUL_BUNKER ],
[Species.ALOLA_RATTATA]: [ Moves.STORM_THROW, Moves.PLAY_ROUGH, Moves.TIDY_UP, Moves.POPULATION_BOMB ], [Species.ALOLA_RATTATA]: [ Moves.STORM_THROW, Moves.PLAY_ROUGH, Moves.TIDY_UP, Moves.POPULATION_BOMB ],
[Species.ALOLA_SANDSHREW]: [ Moves.SPIKY_SHIELD, Moves.AQUA_CUTTER, Moves.SHIFT_GEAR, Moves.GLACIAL_LANCE ], [Species.ALOLA_SANDSHREW]: [ Moves.SPIKY_SHIELD, Moves.AQUA_CUTTER, Moves.SHIFT_GEAR, Moves.GLACIAL_LANCE ],
[Species.ALOLA_VULPIX]: [ Moves.MOONBLAST, Moves.AURORA_VEIL, Moves.PARTING_SHOT, Moves.FREEZY_FROST ], [Species.ALOLA_VULPIX]: [ Moves.MOONBLAST, Moves.AURORA_VEIL, Moves.FLAMETHROWER, Moves.FREEZY_FROST ],
[Species.ALOLA_DIGLETT]: [ Moves.THOUSAND_WAVES, Moves.SWORDS_DANCE, Moves.TRIPLE_DIVE, Moves.MOUNTAIN_GALE ], [Species.ALOLA_DIGLETT]: [ Moves.THOUSAND_WAVES, Moves.SWORDS_DANCE, Moves.TRIPLE_DIVE, Moves.MOUNTAIN_GALE ],
[Species.ALOLA_MEOWTH]: [ Moves.MAKE_IT_RAIN, Moves.BUZZY_BUZZ, Moves.PARTING_SHOT, Moves.BADDY_BAD ], [Species.ALOLA_MEOWTH]: [ Moves.BADDY_BAD, Moves.BUZZY_BUZZ, Moves.PARTING_SHOT, Moves.MAKE_IT_RAIN ],
[Species.ALOLA_GEODUDE]: [ Moves.HIGH_HORSEPOWER, Moves.BULK_UP, Moves.STONE_AXE, Moves.EXTREME_SPEED ], [Species.ALOLA_GEODUDE]: [ Moves.HIGH_HORSEPOWER, Moves.BULK_UP, Moves.STONE_AXE, Moves.EXTREME_SPEED ],
[Species.ALOLA_GRIMER]: [ Moves.SUCKER_PUNCH, Moves.DIRE_CLAW, Moves.STRENGTH_SAP, Moves.SURGING_STRIKES ], [Species.ALOLA_GRIMER]: [ Moves.SUCKER_PUNCH, Moves.DIRE_CLAW, Moves.STRENGTH_SAP, Moves.SURGING_STRIKES ],
[Species.ETERNAL_FLOETTE]: [ Moves.FIERY_DANCE, Moves.GIGA_DRAIN, Moves.POLLEN_PUFF, Moves.QUIVER_DANCE ], [Species.ETERNAL_FLOETTE]: [ Moves.FIERY_DANCE, Moves.CHLOROBLAST, Moves.POLLEN_PUFF, Moves.QUIVER_DANCE ],
[Species.GALAR_MEOWTH]: [ Moves.AQUA_CUTTER, Moves.KNOCK_OFF, Moves.BULLET_PUNCH, Moves.BEHEMOTH_BASH ], [Species.GALAR_MEOWTH]: [ Moves.AQUA_CUTTER, Moves.KNOCK_OFF, Moves.BULLET_PUNCH, Moves.BEHEMOTH_BASH ],
[Species.GALAR_PONYTA]: [ Moves.SPIRIT_BREAK, Moves.EXTREME_SPEED, Moves.FLARE_BLITZ, Moves.PHOTON_GEYSER ], [Species.GALAR_PONYTA]: [ Moves.SPIRIT_BREAK, Moves.EXTREME_SPEED, Moves.FLARE_BLITZ, Moves.PHOTON_GEYSER ],
[Species.GALAR_SLOWPOKE]: [ Moves.TRICK_ROOM, Moves.BADDY_BAD, Moves.MOONBLAST, Moves.LUMINA_CRASH ], [Species.GALAR_SLOWPOKE]: [ Moves.TRICK_ROOM, Moves.BADDY_BAD, Moves.MOONBLAST, Moves.TORCH_SONG ],
[Species.GALAR_FARFETCHD]: [ Moves.ROOST, Moves.SACRED_SWORD, Moves.KINGS_SHIELD, Moves.BEHEMOTH_BLADE ], [Species.GALAR_FARFETCHD]: [ Moves.ROOST, Moves.SACRED_SWORD, Moves.KINGS_SHIELD, Moves.BEHEMOTH_BLADE ],
[Species.GALAR_ARTICUNO]: [ Moves.AURA_SPHERE, Moves.OBLIVION_WING, Moves.ICE_BEAM, Moves.PSYSTRIKE ], [Species.GALAR_ARTICUNO]: [ Moves.AURA_SPHERE, Moves.OBLIVION_WING, Moves.ICE_BEAM, Moves.PSYSTRIKE ],
[Species.GALAR_ZAPDOS]: [ Moves.TIDY_UP, Moves.FLOATY_FALL, Moves.ROOST, Moves.BOLT_BEAK ], [Species.GALAR_ZAPDOS]: [ Moves.TIDY_UP, Moves.FLOATY_FALL, Moves.ROOST, Moves.BOLT_BEAK ],
@ -566,47 +566,49 @@ export const speciesEggMoves = {
[Species.GALAR_YAMASK]: [ Moves.STRENGTH_SAP, Moves.DIRE_CLAW, Moves.THOUSAND_WAVES, Moves.SPECTRAL_THIEF ], [Species.GALAR_YAMASK]: [ Moves.STRENGTH_SAP, Moves.DIRE_CLAW, Moves.THOUSAND_WAVES, Moves.SPECTRAL_THIEF ],
[Species.GALAR_STUNFISK]: [ Moves.SPIKY_SHIELD, Moves.TRICK_ROOM, Moves.SHORE_UP, Moves.SALT_CURE ], [Species.GALAR_STUNFISK]: [ Moves.SPIKY_SHIELD, Moves.TRICK_ROOM, Moves.SHORE_UP, Moves.SALT_CURE ],
[Species.HISUI_GROWLITHE]: [ Moves.WOOD_HAMMER, Moves.HEAD_SMASH, Moves.VOLT_TACKLE, Moves.MORNING_SUN ], [Species.HISUI_GROWLITHE]: [ Moves.WOOD_HAMMER, Moves.HEAD_SMASH, Moves.VOLT_TACKLE, Moves.MORNING_SUN ],
[Species.HISUI_VOLTORB]: [ Moves.FROST_BREATH, Moves.NASTY_PLOT, Moves.PARABOLIC_CHARGE, Moves.SEED_FLARE ], [Species.HISUI_VOLTORB]: [ Moves.ICE_BEAM, Moves.NASTY_PLOT, Moves.PARABOLIC_CHARGE, Moves.SEED_FLARE ],
[Species.HISUI_QWILFISH]: [ Moves.CEASELESS_EDGE, Moves.KNOCK_OFF, Moves.STRENGTH_SAP, Moves.FISHIOUS_REND ], [Species.HISUI_QWILFISH]: [ Moves.CEASELESS_EDGE, Moves.KNOCK_OFF, Moves.STRENGTH_SAP, Moves.FISHIOUS_REND ],
[Species.HISUI_SNEASEL]: [ Moves.THUNDEROUS_KICK, Moves.KNOCK_OFF, Moves.ICE_SPINNER, Moves.VICTORY_DANCE ], [Species.HISUI_SNEASEL]: [ Moves.THUNDEROUS_KICK, Moves.KNOCK_OFF, Moves.ICE_SPINNER, Moves.VICTORY_DANCE ],
[Species.HISUI_ZORUA]: [ Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.PARTING_SHOT, Moves.BLOOD_MOON ], [Species.HISUI_ZORUA]: [ Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.PARTING_SHOT, Moves.BLOOD_MOON ],
[Species.PALDEA_TAUROS]: [ Moves.NO_RETREAT, Moves.BLAZING_TORQUE, Moves.AQUA_STEP, Moves.THUNDEROUS_KICK ], [Species.PALDEA_TAUROS]: [ Moves.NO_RETREAT, Moves.BLAZING_TORQUE, Moves.AQUA_STEP, Moves.THUNDEROUS_KICK ],
[Species.PALDEA_WOOPER]: [ Moves.RECOVER, Moves.STONE_AXE, Moves.BANEFUL_BUNKER, Moves.SAPPY_SEED ], [Species.PALDEA_WOOPER]: [ Moves.RECOVER, Moves.STONE_AXE, Moves.BANEFUL_BUNKER, Moves.SAPPY_SEED ],
[Species.BLOODMOON_URSALUNA]: [ Moves.GLARE, Moves.TRICK_ROOM, Moves.PARTING_SHOT, Moves.MIND_BLOWN ] [Species.BLOODMOON_URSALUNA]: [ Moves.NASTY_PLOT, Moves.TRICK_ROOM, Moves.THUNDERBOLT, Moves.BOOMBURST ]
}; };
function parseEggMoves(content: string): void { function parseEggMoves(content: string): void {
let output = ''; let output = "";
const speciesNames = Utils.getEnumKeys(Species); const speciesNames = Utils.getEnumKeys(Species);
const speciesValues = Utils.getEnumValues(Species); const speciesValues = Utils.getEnumValues(Species);
const lines = content.split(/\n/g); const lines = content.split(/\n/g);
lines.forEach((line, l) => { lines.forEach((line, l) => {
const cols = line.split(',').slice(0, 5); const cols = line.split(",").slice(0, 5);
const moveNames = allMoves.map(m => m.name.replace(/ \([A-Z]\)$/, '').toLowerCase()); const moveNames = allMoves.map(m => m.name.replace(/ \([A-Z]\)$/, "").toLowerCase());
const enumSpeciesName = cols[0].toUpperCase().replace(/[ -]/g, '_'); const enumSpeciesName = cols[0].toUpperCase().replace(/[ -]/g, "_");
const species = speciesValues[speciesNames.findIndex(s => s === enumSpeciesName)]; const species = speciesValues[speciesNames.findIndex(s => s === enumSpeciesName)];
let eggMoves: Moves[] = []; const eggMoves: Moves[] = [];
for (let m = 0; m < 4; m++) { for (let m = 0; m < 4; m++) {
const moveName = cols[m + 1].trim(); const moveName = cols[m + 1].trim();
const moveIndex = moveName !== 'N/A' ? moveNames.findIndex(mn => mn === moveName.toLowerCase()) : -1; const moveIndex = moveName !== "N/A" ? moveNames.findIndex(mn => mn === moveName.toLowerCase()) : -1;
eggMoves.push(moveIndex > -1 ? moveIndex as Moves : Moves.NONE); eggMoves.push(moveIndex > -1 ? moveIndex as Moves : Moves.NONE);
if (moveIndex === -1) if (moveIndex === -1) {
console.warn(moveName, 'could not be parsed'); console.warn(moveName, "could not be parsed");
}
} }
if (eggMoves.find(m => m !== Moves.NONE)) if (eggMoves.find(m => m !== Moves.NONE)) {
output += `[Species.${Species[species]}]: [ ${eggMoves.map(m => `Moves.${Moves[m]}`).join(', ')} ],\n`; output += `[Species.${Species[species]}]: [ ${eggMoves.map(m => `Moves.${Moves[m]}`).join(", ")} ],\n`;
}
}); });
console.log(output); console.log(output);
} }
const eggMovesStr = ``; const eggMovesStr = "";
if (eggMovesStr) { if (eggMovesStr) {
setTimeout(() => { setTimeout(() => {
parseEggMoves(eggMovesStr); parseEggMoves(eggMovesStr);

View File

@ -1,10 +1,8 @@
import { Type } from "./type";
import * as Utils from "../utils";
import BattleScene from "../battle-scene"; import BattleScene from "../battle-scene";
import { Species } from "./enums/species"; import { Species } from "./enums/species";
import { getPokemonSpecies, speciesStarters } from "./pokemon-species"; import { getPokemonSpecies, speciesStarters } from "./pokemon-species";
import { EggTier } from "./enums/egg-type"; import { EggTier } from "./enums/egg-type";
import i18next from '../plugins/i18n'; import i18next from "../plugins/i18n";
export const EGG_SEED = 1073741824; export const EGG_SEED = 1073741824;
@ -34,8 +32,9 @@ export class Egg {
} }
getKey(): string { getKey(): string {
if (this.isManaphyEgg()) if (this.isManaphyEgg()) {
return 'manaphy'; return "manaphy";
}
return this.tier.toString(); return this.tier.toString();
} }
} }
@ -53,38 +52,42 @@ export function getEggTierDefaultHatchWaves(tier: EggTier): integer {
} }
export function getEggDescriptor(egg: Egg): string { export function getEggDescriptor(egg: Egg): string {
if (egg.isManaphyEgg()) if (egg.isManaphyEgg()) {
return 'Manaphy'; return "Manaphy";
}
switch (egg.tier) { switch (egg.tier) {
case EggTier.GREAT: case EggTier.GREAT:
return i18next.t('egg:greatTier'); return i18next.t("egg:greatTier");
case EggTier.ULTRA: case EggTier.ULTRA:
return i18next.t('egg:ultraTier'); return i18next.t("egg:ultraTier");
case EggTier.MASTER: case EggTier.MASTER:
return i18next.t('egg:masterTier'); return i18next.t("egg:masterTier");
default: default:
return i18next.t('egg:defaultTier'); return i18next.t("egg:defaultTier");
} }
} }
export function getEggHatchWavesMessage(hatchWaves: integer): string { export function getEggHatchWavesMessage(hatchWaves: integer): string {
if (hatchWaves <= 5) if (hatchWaves <= 5) {
return i18next.t('egg:hatchWavesMessageSoon'); return i18next.t("egg:hatchWavesMessageSoon");
if (hatchWaves <= 15) }
return i18next.t('egg:hatchWavesMessageClose'); if (hatchWaves <= 15) {
if (hatchWaves <= 50) return i18next.t("egg:hatchWavesMessageClose");
return i18next.t('egg:hatchWavesMessageNotClose'); }
return i18next.t('egg:hatchWavesMessageLongTime'); if (hatchWaves <= 50) {
return i18next.t("egg:hatchWavesMessageNotClose");
}
return i18next.t("egg:hatchWavesMessageLongTime");
} }
export function getEggGachaTypeDescriptor(scene: BattleScene, egg: Egg): string { export function getEggGachaTypeDescriptor(scene: BattleScene, egg: Egg): string {
switch (egg.gachaType) { switch (egg.gachaType) {
case GachaType.LEGENDARY: case GachaType.LEGENDARY:
return `${i18next.t('egg:gachaTypeLegendary')} (${getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(scene, egg.timestamp)).getName()})`; return `${i18next.t("egg:gachaTypeLegendary")} (${getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(scene, egg.timestamp)).getName()})`;
case GachaType.MOVE: case GachaType.MOVE:
return i18next.t('egg:gachaTypeMove'); return i18next.t("egg:gachaTypeMove");
case GachaType.SHINY: case GachaType.SHINY:
return i18next.t('egg:gachaTypeShiny'); return i18next.t("egg:gachaTypeShiny");
} }
} }
@ -98,10 +101,9 @@ export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timesta
// 86400000 is the number of miliseconds in one day // 86400000 is the number of miliseconds in one day
const timeDate = new Date(timestamp); const timeDate = new Date(timestamp);
const dayDate = new Date(Date.UTC(timeDate.getUTCFullYear(), timeDate.getUTCMonth(), timeDate.getUTCDate()));
const dayTimestamp = timeDate.getTime(); // Timestamp of current week const dayTimestamp = timeDate.getTime(); // Timestamp of current week
const offset = Math.floor(Math.floor(dayTimestamp / 86400000) / legendarySpecies.length); // Cycle number const offset = Math.floor(Math.floor(dayTimestamp / 86400000) / legendarySpecies.length); // Cycle number
const index = Math.floor(dayTimestamp / 86400000) % legendarySpecies.length // Index within cycle const index = Math.floor(dayTimestamp / 86400000) % legendarySpecies.length; // Index within cycle
scene.executeWithSeedOffset(() => { scene.executeWithSeedOffset(() => {
ret = Phaser.Math.RND.shuffle(legendarySpecies)[index]; ret = Phaser.Math.RND.shuffle(legendarySpecies)[index];

View File

@ -1872,4 +1872,4 @@ export enum Moves {
UPPER_HAND, UPPER_HAND,
/**{@link https://bulbapedia.bulbagarden.net/wiki/Malignant_Chain_(move) | Source} */ /**{@link https://bulbapedia.bulbagarden.net/wiki/Malignant_Chain_(move) | Source} */
MALIGNANT_CHAIN, MALIGNANT_CHAIN,
}; }

View File

@ -2163,7 +2163,7 @@ export enum Species {
PALDEA_WOOPER = 8194, PALDEA_WOOPER = 8194,
/**{@link https://bulbapedia.bulbagarden.net/wiki/Ursaluna_(Pokémon) | Source} */ /**{@link https://bulbapedia.bulbagarden.net/wiki/Ursaluna_(Pokémon) | Source} */
BLOODMOON_URSALUNA = 8901, BLOODMOON_URSALUNA = 8901,
}; }
export const defaultStarterSpecies: Species[] = [ export const defaultStarterSpecies: Species[] = [
Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE,

View File

@ -5,7 +5,7 @@ export enum GrowthRate {
MEDIUM_SLOW, MEDIUM_SLOW,
SLOW, SLOW,
FLUCTUATING FLUCTUATING
}; }
const expLevels = [ const expLevels = [
[ 0, 15, 52, 122, 237, 406, 637, 942, 1326, 1800, 2369, 3041, 3822, 4719, 5737, 6881, 8155, 9564, 11111, 12800, 14632, 16610, 18737, 21012, 23437, 26012, 28737, 31610, 34632, 37800, 41111, 44564, 48155, 51881, 55737, 59719, 63822, 68041, 72369, 76800, 81326, 85942, 90637, 95406, 100237, 105122, 110052, 115015, 120001, 125000, 131324, 137795, 144410, 151165, 158056, 165079, 172229, 179503, 186894, 194400, 202013, 209728, 217540, 225443, 233431, 241496, 249633, 257834, 267406, 276458, 286328, 296358, 305767, 316074, 326531, 336255, 346965, 357812, 367807, 378880, 390077, 400293, 411686, 423190, 433572, 445239, 457001, 467489, 479378, 491346, 501878, 513934, 526049, 536557, 548720, 560922, 571333, 583539, 591882, 600000 ], [ 0, 15, 52, 122, 237, 406, 637, 942, 1326, 1800, 2369, 3041, 3822, 4719, 5737, 6881, 8155, 9564, 11111, 12800, 14632, 16610, 18737, 21012, 23437, 26012, 28737, 31610, 34632, 37800, 41111, 44564, 48155, 51881, 55737, 59719, 63822, 68041, 72369, 76800, 81326, 85942, 90637, 95406, 100237, 105122, 110052, 115015, 120001, 125000, 131324, 137795, 144410, 151165, 158056, 165079, 172229, 179503, 186894, 194400, 202013, 209728, 217540, 225443, 233431, 241496, 249633, 257834, 267406, 276458, 286328, 296358, 305767, 316074, 326531, 336255, 346965, 357812, 367807, 378880, 390077, 400293, 411686, 423190, 433572, 445239, 457001, 467489, 479378, 491346, 501878, 513934, 526049, 536557, 548720, 560922, 571333, 583539, 591882, 600000 ],
@ -19,8 +19,9 @@ const expLevels = [
export function getLevelTotalExp(level: integer, growthRate: GrowthRate): integer { export function getLevelTotalExp(level: integer, growthRate: GrowthRate): integer {
if (level < 100) { if (level < 100) {
const levelExp = expLevels[growthRate][level - 1]; const levelExp = expLevels[growthRate][level - 1];
if (growthRate !== GrowthRate.MEDIUM_FAST) if (growthRate !== GrowthRate.MEDIUM_FAST) {
return Math.floor(levelExp * 0.325 + getLevelTotalExp(level, GrowthRate.MEDIUM_FAST) * 0.675); return Math.floor(levelExp * 0.325 + getLevelTotalExp(level, GrowthRate.MEDIUM_FAST) * 0.675);
}
return levelExp; return levelExp;
} }
@ -47,8 +48,9 @@ export function getLevelTotalExp(level: integer, growthRate: GrowthRate): intege
break; break;
} }
if (growthRate !== GrowthRate.MEDIUM_FAST) if (growthRate !== GrowthRate.MEDIUM_FAST) {
return Math.floor(ret * 0.325 + getLevelTotalExp(level, GrowthRate.MEDIUM_FAST) * 0.675); return Math.floor(ret * 0.325 + getLevelTotalExp(level, GrowthRate.MEDIUM_FAST) * 0.675);
}
return Math.floor(ret); return Math.floor(ret);
} }
@ -60,16 +62,16 @@ export function getLevelRelExp(level: integer, growthRate: GrowthRate): number {
export function getGrowthRateColor(growthRate: GrowthRate, shadow?: boolean) { export function getGrowthRateColor(growthRate: GrowthRate, shadow?: boolean) {
switch (growthRate) { switch (growthRate) {
case GrowthRate.ERRATIC: case GrowthRate.ERRATIC:
return !shadow ? '#f85888' : '#906060'; return !shadow ? "#f85888" : "#906060";
case GrowthRate.FAST: case GrowthRate.FAST:
return !shadow ? '#f8d030' : '#b8a038'; return !shadow ? "#f8d030" : "#b8a038";
case GrowthRate.MEDIUM_FAST: case GrowthRate.MEDIUM_FAST:
return !shadow ? '#78c850' : '#588040'; return !shadow ? "#78c850" : "#588040";
case GrowthRate.MEDIUM_SLOW: case GrowthRate.MEDIUM_SLOW:
return !shadow ? '#6890f0' : '#807870'; return !shadow ? "#6890f0" : "#807870";
case GrowthRate.SLOW: case GrowthRate.SLOW:
return !shadow ? '#f08030' : '#c03028'; return !shadow ? "#f08030" : "#c03028";
case GrowthRate.FLUCTUATING: case GrowthRate.FLUCTUATING:
return !shadow ? '#a040a0' : '#483850'; return !shadow ? "#a040a0" : "#483850";
} }
} }

View File

@ -7,19 +7,19 @@ export enum Gender {
export function getGenderSymbol(gender: Gender) { export function getGenderSymbol(gender: Gender) {
switch (gender) { switch (gender) {
case Gender.MALE: case Gender.MALE:
return '♂'; return "♂";
case Gender.FEMALE: case Gender.FEMALE:
return '♀'; return "♀";
} }
return ''; return "";
} }
export function getGenderColor(gender: Gender, shadow?: boolean) { export function getGenderColor(gender: Gender, shadow?: boolean) {
switch (gender) { switch (gender) {
case Gender.MALE: case Gender.MALE:
return shadow ? '#006090' : '#40c8f8'; return shadow ? "#006090" : "#40c8f8";
case Gender.FEMALE: case Gender.FEMALE:
return shadow ? '#984038' : '#f89890'; return shadow ? "#984038" : "#f89890";
} }
return '#ffffff'; return "#ffffff";
} }

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@ import { Stat, getStatName } from "./pokemon-stat";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { TextStyle, getBBCodeFrag } from "../ui/text"; import { TextStyle, getBBCodeFrag } from "../ui/text";
import { UiTheme } from "#app/enums/ui-theme"; import { UiTheme } from "#app/enums/ui-theme";
import i18next from 'i18next'; import i18next from "i18next";
export enum Nature { export enum Nature {
HARDY, HARDY,
@ -35,26 +35,28 @@ export enum Nature {
export function getNatureName(nature: Nature, includeStatEffects: boolean = false, forStarterSelect: boolean = false, ignoreBBCode: boolean = false, uiTheme: UiTheme = UiTheme.DEFAULT): string { export function getNatureName(nature: Nature, includeStatEffects: boolean = false, forStarterSelect: boolean = false, ignoreBBCode: boolean = false, uiTheme: UiTheme = UiTheme.DEFAULT): string {
let ret = Utils.toReadableString(Nature[nature]); let ret = Utils.toReadableString(Nature[nature]);
//Translating nature //Translating nature
if(i18next.exists('nature:' + ret)){ if(i18next.exists("nature:" + ret)){
ret = i18next.t('nature:' + ret as any) ret = i18next.t("nature:" + ret as any);
} }
if (includeStatEffects) { if (includeStatEffects) {
const stats = Utils.getEnumValues(Stat).slice(1); const stats = Utils.getEnumValues(Stat).slice(1);
let increasedStat: Stat = null; let increasedStat: Stat = null;
let decreasedStat: Stat = null; let decreasedStat: Stat = null;
for (let stat of stats) { for (const stat of stats) {
const multiplier = getNatureStatMultiplier(nature, stat); const multiplier = getNatureStatMultiplier(nature, stat);
if (multiplier > 1) if (multiplier > 1) {
increasedStat = stat; increasedStat = stat;
else if (multiplier < 1) } else if (multiplier < 1) {
decreasedStat = stat; decreasedStat = stat;
} }
}
const textStyle = forStarterSelect ? TextStyle.SUMMARY_ALT : TextStyle.WINDOW; const textStyle = forStarterSelect ? TextStyle.SUMMARY_ALT : TextStyle.WINDOW;
const getTextFrag = !ignoreBBCode ? (text: string, style: TextStyle) => getBBCodeFrag(text, style, uiTheme) : (text: string, style: TextStyle) => text; const getTextFrag = !ignoreBBCode ? (text: string, style: TextStyle) => getBBCodeFrag(text, style, uiTheme) : (text: string, style: TextStyle) => text;
if (increasedStat && decreasedStat) if (increasedStat && decreasedStat) {
ret = `${getTextFrag(`${ret}${!forStarterSelect ? '\n' : ' '}(`, textStyle)}${getTextFrag(`+${getStatName(increasedStat, true)}`, TextStyle.SUMMARY_PINK)}${getTextFrag('/', textStyle)}${getTextFrag(`-${getStatName(decreasedStat, true)}`, TextStyle.SUMMARY_BLUE)}${getTextFrag(')', textStyle)}`; ret = `${getTextFrag(`${ret}${!forStarterSelect ? "\n" : " "}(`, textStyle)}${getTextFrag(`+${getStatName(increasedStat, true)}`, TextStyle.SUMMARY_PINK)}${getTextFrag("/", textStyle)}${getTextFrag(`-${getStatName(decreasedStat, true)}`, TextStyle.SUMMARY_BLUE)}${getTextFrag(")", textStyle)}`;
else } else {
ret = getTextFrag(`${ret}${!forStarterSelect ? '\n' : ' '}(-)`, textStyle); ret = getTextFrag(`${ret}${!forStarterSelect ? "\n" : " "}(-)`, textStyle);
}
} }
return ret; return ret;
} }

View File

@ -1,5 +1,5 @@
import BattleScene from "../battle-scene"; import BattleScene from "../battle-scene";
import i18next from '../plugins/i18n'; import i18next from "../plugins/i18n";
export enum PokeballType { export enum PokeballType {
POKEBALL, POKEBALL,
@ -8,22 +8,22 @@ export enum PokeballType {
ROGUE_BALL, ROGUE_BALL,
MASTER_BALL, MASTER_BALL,
LUXURY_BALL LUXURY_BALL
}; }
export function getPokeballAtlasKey(type: PokeballType): string { export function getPokeballAtlasKey(type: PokeballType): string {
switch (type) { switch (type) {
case PokeballType.POKEBALL: case PokeballType.POKEBALL:
return 'pb'; return "pb";
case PokeballType.GREAT_BALL: case PokeballType.GREAT_BALL:
return 'gb'; return "gb";
case PokeballType.ULTRA_BALL: case PokeballType.ULTRA_BALL:
return 'ub'; return "ub";
case PokeballType.ROGUE_BALL: case PokeballType.ROGUE_BALL:
return 'rb'; return "rb";
case PokeballType.MASTER_BALL: case PokeballType.MASTER_BALL:
return 'mb'; return "mb";
case PokeballType.LUXURY_BALL: case PokeballType.LUXURY_BALL:
return 'lb'; return "lb";
} }
} }
@ -31,22 +31,22 @@ export function getPokeballName(type: PokeballType): string {
let ret: string; let ret: string;
switch (type) { switch (type) {
case PokeballType.POKEBALL: case PokeballType.POKEBALL:
ret = i18next.t('pokeball:pokeBall'); ret = i18next.t("pokeball:pokeBall");
break; break;
case PokeballType.GREAT_BALL: case PokeballType.GREAT_BALL:
ret = i18next.t('pokeball:greatBall'); ret = i18next.t("pokeball:greatBall");
break; break;
case PokeballType.ULTRA_BALL: case PokeballType.ULTRA_BALL:
ret = i18next.t('pokeball:ultraBall'); ret = i18next.t("pokeball:ultraBall");
break; break;
case PokeballType.ROGUE_BALL: case PokeballType.ROGUE_BALL:
ret = i18next.t('pokeball:rogueBall'); ret = i18next.t("pokeball:rogueBall");
break; break;
case PokeballType.MASTER_BALL: case PokeballType.MASTER_BALL:
ret = i18next.t('pokeball:masterBall'); ret = i18next.t("pokeball:masterBall");
break; break;
case PokeballType.LUXURY_BALL: case PokeballType.LUXURY_BALL:
ret = i18next.t('pokeball:luxuryBall'); ret = i18next.t("pokeball:luxuryBall");
break; break;
} }
return ret; return ret;
@ -90,16 +90,16 @@ export function doPokeballBounceAnim(scene: BattleScene, pokeball: Phaser.GameOb
let bouncePower = 1; let bouncePower = 1;
let bounceYOffset = y1; let bounceYOffset = y1;
let bounceY = y2; let bounceY = y2;
let yd = y2 - y1; const yd = y2 - y1;
const doBounce = () => { const doBounce = () => {
scene.tweens.add({ scene.tweens.add({
targets: pokeball, targets: pokeball,
y: y2, y: y2,
duration: bouncePower * baseBounceDuration, duration: bouncePower * baseBounceDuration,
ease: 'Cubic.easeIn', ease: "Cubic.easeIn",
onComplete: () => { onComplete: () => {
scene.playSound('pb_bounce_1', { volume: bouncePower }); scene.playSound("pb_bounce_1", { volume: bouncePower });
bouncePower = bouncePower > 0.01 ? bouncePower * 0.5 : 0; bouncePower = bouncePower > 0.01 ? bouncePower * 0.5 : 0;
@ -111,12 +111,13 @@ export function doPokeballBounceAnim(scene: BattleScene, pokeball: Phaser.GameOb
targets: pokeball, targets: pokeball,
y: bounceY, y: bounceY,
duration: bouncePower * baseBounceDuration, duration: bouncePower * baseBounceDuration,
ease: 'Cubic.easeOut', ease: "Cubic.easeOut",
onComplete: () => doBounce() onComplete: () => doBounce()
}); });
} else if (callback) } else if (callback) {
callback(); callback();
} }
}
}); });
}; };

View File

@ -1,5 +1,5 @@
import { Gender } from "./gender"; import { Gender } from "./gender";
import { AttackTypeBoosterModifier, FlinchChanceModifier } from "../modifier/modifier"; import { FlinchChanceModifier } from "../modifier/modifier";
import { Moves } from "./enums/moves"; import { Moves } from "./enums/moves";
import { PokeballType } from "./pokeball"; import { PokeballType } from "./pokeball";
import Pokemon from "../field/pokemon"; import Pokemon from "../field/pokemon";
@ -185,7 +185,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.DUGTRIO, 26, null, null) new SpeciesEvolution(Species.DUGTRIO, 26, null, null)
], ],
[Species.MEOWTH]: [ [Species.MEOWTH]: [
new SpeciesFormEvolution(Species.PERSIAN, '', '', 28, null, null) new SpeciesFormEvolution(Species.PERSIAN, "", "", 28, null, null)
], ],
[Species.PSYDUCK]: [ [Species.PSYDUCK]: [
new SpeciesEvolution(Species.GOLDUCK, 33, null, null) new SpeciesEvolution(Species.GOLDUCK, 33, null, null)
@ -298,7 +298,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.QUILAVA, 14, null, null) new SpeciesEvolution(Species.QUILAVA, 14, null, null)
], ],
[Species.QUILAVA]: [ [Species.QUILAVA]: [
new SpeciesEvolution(Species.HISUI_TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.HISUI_TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
new SpeciesEvolution(Species.TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) new SpeciesEvolution(Species.TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY))
], ],
[Species.TOTODILE]: [ [Species.TOTODILE]: [
@ -646,7 +646,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.DEWOTT, 17, null, null) new SpeciesEvolution(Species.DEWOTT, 17, null, null)
], ],
[Species.DEWOTT]: [ [Species.DEWOTT]: [
new SpeciesEvolution(Species.HISUI_SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.HISUI_SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
new SpeciesEvolution(Species.SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) new SpeciesEvolution(Species.SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY))
], ],
[Species.PATRAT]: [ [Species.PATRAT]: [
@ -797,7 +797,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.KINGAMBIT, 64, null, null) new SpeciesEvolution(Species.KINGAMBIT, 64, null, null)
], ],
[Species.RUFFLET]: [ [Species.RUFFLET]: [
new SpeciesEvolution(Species.HISUI_BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.HISUI_BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
new SpeciesEvolution(Species.BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) new SpeciesEvolution(Species.BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY))
], ],
[Species.VULLABY]: [ [Species.VULLABY]: [
@ -858,8 +858,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.PANGORO, 32, null, new SpeciesEvolutionCondition(p => !!p.scene.getParty().find(p => p.getTypes(false, false, true).indexOf(Type.DARK) > -1)), SpeciesWildEvolutionDelay.MEDIUM) new SpeciesEvolution(Species.PANGORO, 32, null, new SpeciesEvolutionCondition(p => !!p.scene.getParty().find(p => p.getTypes(false, false, true).indexOf(Type.DARK) > -1)), SpeciesWildEvolutionDelay.MEDIUM)
], ],
[Species.ESPURR]: [ [Species.ESPURR]: [
new SpeciesFormEvolution(Species.MEOWSTIC, '', 'female', 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)), new SpeciesFormEvolution(Species.MEOWSTIC, "", "female", 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)),
new SpeciesFormEvolution(Species.MEOWSTIC, '', '', 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE)) new SpeciesFormEvolution(Species.MEOWSTIC, "", "", 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE))
], ],
[Species.HONEDGE]: [ [Species.HONEDGE]: [
new SpeciesEvolution(Species.DOUBLADE, 35, null, null) new SpeciesEvolution(Species.DOUBLADE, 35, null, null)
@ -883,14 +883,14 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.AURORUS, 39, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM) new SpeciesEvolution(Species.AURORUS, 39, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM)
], ],
[Species.GOOMY]: [ [Species.GOOMY]: [
new SpeciesEvolution(Species.HISUI_SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.HISUI_SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
new SpeciesEvolution(Species.SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) new SpeciesEvolution(Species.SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY))
], ],
[Species.SLIGGOO]: [ [Species.SLIGGOO]: [
new SpeciesEvolution(Species.GOODRA, 50, null, new SpeciesEvolutionCondition(p => [ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ].indexOf(p.scene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.GOODRA, 50, null, new SpeciesEvolutionCondition(p => [ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ].indexOf(p.scene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.BERGMITE]: [ [Species.BERGMITE]: [
new SpeciesEvolution(Species.HISUI_AVALUGG, 37, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.HISUI_AVALUGG, 37, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
new SpeciesEvolution(Species.AVALUGG, 37, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) new SpeciesEvolution(Species.AVALUGG, 37, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY))
], ],
[Species.NOIBAT]: [ [Species.NOIBAT]: [
@ -900,7 +900,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.DARTRIX, 17, null, null) new SpeciesEvolution(Species.DARTRIX, 17, null, null)
], ],
[Species.DARTRIX]: [ [Species.DARTRIX]: [
new SpeciesEvolution(Species.HISUI_DECIDUEYE, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.HISUI_DECIDUEYE, 36, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
new SpeciesEvolution(Species.DECIDUEYE, 34, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) new SpeciesEvolution(Species.DECIDUEYE, 34, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY))
], ],
[Species.LITTEN]: [ [Species.LITTEN]: [
@ -1049,9 +1049,9 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.BARRASKEWDA, 26, null, null) new SpeciesEvolution(Species.BARRASKEWDA, 26, null, null)
], ],
[Species.TOXEL]: [ [Species.TOXEL]: [
new SpeciesFormEvolution(Species.TOXTRICITY, '', 'lowkey', 30, null, new SpeciesFormEvolution(Species.TOXTRICITY, "", "lowkey", 30, null,
new SpeciesEvolutionCondition(p => [ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ].indexOf(p.getNature()) > -1)), new SpeciesEvolutionCondition(p => [ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ].indexOf(p.getNature()) > -1)),
new SpeciesFormEvolution(Species.TOXTRICITY, '', 'amped', 30, null, null) new SpeciesFormEvolution(Species.TOXTRICITY, "", "amped", 30, null, null)
], ],
[Species.SIZZLIPEDE]: [ [Species.SIZZLIPEDE]: [
new SpeciesEvolution(Species.CENTISKORCH, 28, null, null) new SpeciesEvolution(Species.CENTISKORCH, 28, null, null)
@ -1109,7 +1109,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.HISUI_ZOROARK, 30, null, null) new SpeciesEvolution(Species.HISUI_ZOROARK, 30, null, null)
], ],
[Species.HISUI_SLIGGOO]: [ [Species.HISUI_SLIGGOO]: [
new SpeciesEvolution(Species.HISUI_GOODRA, 50, null, new SpeciesEvolutionCondition(p => [ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ].indexOf(p.scene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.HISUI_GOODRA, 50, null, new SpeciesEvolutionCondition(p => [ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ].indexOf(p.scene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.SPRIGATITO]: [ [Species.SPRIGATITO]: [
new SpeciesEvolution(Species.FLORAGATO, 16, null, null) new SpeciesEvolution(Species.FLORAGATO, 16, null, null)
@ -1130,8 +1130,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.QUAQUAVAL, 36, null, null) new SpeciesEvolution(Species.QUAQUAVAL, 36, null, null)
], ],
[Species.LECHONK]: [ [Species.LECHONK]: [
new SpeciesFormEvolution(Species.OINKOLOGNE, '', 'female', 18, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)), new SpeciesFormEvolution(Species.OINKOLOGNE, "", "female", 18, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)),
new SpeciesFormEvolution(Species.OINKOLOGNE, '', '', 18, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE)) new SpeciesFormEvolution(Species.OINKOLOGNE, "", "", 18, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE))
], ],
[Species.TAROUNTULA]: [ [Species.TAROUNTULA]: [
new SpeciesEvolution(Species.SPIDOPS, 15, null, null) new SpeciesEvolution(Species.SPIDOPS, 15, null, null)
@ -1215,8 +1215,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.CLODSIRE, 20, null, null) new SpeciesEvolution(Species.CLODSIRE, 20, null, null)
], ],
[Species.PIKACHU]: [ [Species.PIKACHU]: [
new SpeciesFormEvolution(Species.ALOLA_RAICHU, '', '', 1, EvolutionItem.THUNDER_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ISLAND || p.scene.arena.biomeType === Biome.BEACH), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALOLA_RAICHU, "", "", 1, EvolutionItem.THUNDER_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ISLAND || p.scene.arena.biomeType === Biome.BEACH), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.RAICHU, '', '', 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesFormEvolution(Species.RAICHU, "", "", 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.NIDORINA]: [ [Species.NIDORINA]: [
new SpeciesEvolution(Species.NIDOQUEEN, 1, EvolutionItem.MOON_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.NIDOQUEEN, 1, EvolutionItem.MOON_STONE, null, SpeciesWildEvolutionDelay.LONG)
@ -1254,7 +1254,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.CLOYSTER, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.CLOYSTER, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.EXEGGCUTE]: [ [Species.EXEGGCUTE]: [
new SpeciesEvolution(Species.ALOLA_EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ISLAND || p.scene.arena.biomeType == Biome.BEACH), SpeciesWildEvolutionDelay.LONG), new SpeciesEvolution(Species.ALOLA_EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ISLAND || p.scene.arena.biomeType === Biome.BEACH), SpeciesWildEvolutionDelay.LONG),
new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.TANGELA]: [ [Species.TANGELA]: [
@ -1267,14 +1267,14 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.EEVEE]: [ [Species.EEVEE]: [
new SpeciesFormEvolution(Species.SYLVEON, '', '', 1, null, new SpeciesFriendshipEvolutionCondition(70, p => !!p.getMoveset().find(m => m.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.SYLVEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(70, p => !!p.getMoveset().find(m => m.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ESPEON, '', '', 1, null, new SpeciesFriendshipEvolutionCondition(70, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ESPEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(70, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.UMBREON, '', '', 1, null, new SpeciesFriendshipEvolutionCondition(70, p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.UMBREON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(70, p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.VAPOREON, '', '', 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.VAPOREON, "", "", 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.JOLTEON, '', '', 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.JOLTEON, "", "", 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.FLAREON, '', '', 1, EvolutionItem.FIRE_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.FLAREON, "", "", 1, EvolutionItem.FIRE_STONE, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.LEAFEON, '', '', 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.LEAFEON, "", "", 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.GLACEON, '', '', 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.GLACEON, "", "", 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG),
], ],
[Species.TOGETIC]: [ [Species.TOGETIC]: [
new SpeciesEvolution(Species.TOGEKISS, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.TOGEKISS, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
@ -1295,16 +1295,17 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.MISMAGIUS, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.MISMAGIUS, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.GIRAFARIG]: [ [Species.GIRAFARIG]: [
new SpeciesEvolution(Species.FARIGIRAF, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.TWIN_BEAM).length > 0), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.FARIGIRAF, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.TWIN_BEAM).length > 0), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.DUNSPARCE]: [ [Species.DUNSPARCE]: [
new SpeciesFormEvolution(Species.DUDUNSPARCE, '', 'three-segment', 32, null, new SpeciesEvolutionCondition(p => { new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "three-segment", 32, null, new SpeciesEvolutionCondition(p => {
let ret = false; let ret = false;
if (p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0) if (p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0) {
p.scene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id); p.scene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
}
return ret; return ret;
}), SpeciesWildEvolutionDelay.VERY_LONG), }), SpeciesWildEvolutionDelay.LONG),
new SpeciesEvolution(Species.DUDUNSPARCE, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.DUDUNSPARCE, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.GLIGAR]: [ [Species.GLIGAR]: [
new SpeciesEvolution(Species.GLISCOR, 1, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor fang at night*/), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.GLISCOR, 1, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor fang at night*/), SpeciesWildEvolutionDelay.LONG)
@ -1363,8 +1364,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.LILLIGANT, 1, EvolutionItem.SUN_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.LILLIGANT, 1, EvolutionItem.SUN_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.BASCULIN]: [ [Species.BASCULIN]: [
new SpeciesFormEvolution(Species.BASCULEGION, 'white-striped', 'female', 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesFormEvolution(Species.BASCULEGION, "white-striped", "female", 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE), SpeciesWildEvolutionDelay.VERY_LONG),
new SpeciesFormEvolution(Species.BASCULEGION, 'white-striped', 'male', 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesFormEvolution(Species.BASCULEGION, "white-striped", "male", 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE), SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.MINCCINO]: [ [Species.MINCCINO]: [
new SpeciesEvolution(Species.CINCCINO, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.CINCCINO, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.LONG)
@ -1391,9 +1392,9 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.CRABOMINABLE, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.CRABOMINABLE, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.ROCKRUFF]: [ [Species.ROCKRUFF]: [
new SpeciesFormEvolution(Species.LYCANROC, '', 'midday', 25, null, new SpeciesEvolutionCondition(p => (p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY) && (p.formIndex === 0)), null), new SpeciesFormEvolution(Species.LYCANROC, "", "midday", 25, null, new SpeciesEvolutionCondition(p => (p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY) && (p.formIndex === 0)), null),
new SpeciesFormEvolution(Species.LYCANROC, '', 'dusk', 25, null, new SpeciesEvolutionCondition(p => p.formIndex === 1), null), new SpeciesFormEvolution(Species.LYCANROC, "", "dusk", 25, null, new SpeciesEvolutionCondition(p => p.formIndex === 1), null),
new SpeciesFormEvolution(Species.LYCANROC, '', 'midnight', 25, null, new SpeciesEvolutionCondition(p => (p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT) && (p.formIndex === 0)), null) new SpeciesFormEvolution(Species.LYCANROC, "", "midnight", 25, null, new SpeciesEvolutionCondition(p => (p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT) && (p.formIndex === 0)), null)
], ],
[Species.STEENEE]: [ [Species.STEENEE]: [
new SpeciesEvolution(Species.TSAREENA, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.STOMP).length > 0), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.TSAREENA, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.STOMP).length > 0), SpeciesWildEvolutionDelay.LONG)
@ -1416,26 +1417,26 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.TAUNT).length > 0), SpeciesWildEvolutionDelay.MEDIUM) new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.TAUNT).length > 0), SpeciesWildEvolutionDelay.MEDIUM)
], ],
[Species.SINISTEA]: [ [Species.SINISTEA]: [
new SpeciesFormEvolution(Species.POLTEAGEIST, 'phony', 'phony', 1, EvolutionItem.CRACKED_POT, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.POLTEAGEIST, "phony", "phony", 1, EvolutionItem.CRACKED_POT, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.POLTEAGEIST, 'antique', 'antique', 1, EvolutionItem.CHIPPED_POT, null, SpeciesWildEvolutionDelay.LONG) new SpeciesFormEvolution(Species.POLTEAGEIST, "antique", "antique", 1, EvolutionItem.CHIPPED_POT, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.MILCERY]: [ [Species.MILCERY]: [
new SpeciesFormEvolution(Species.ALCREMIE, '', 'vanilla-cream', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.TOWN || p.scene.arena.biomeType === Biome.PLAINS || p.scene.arena.biomeType === Biome.GRASS || p.scene.arena.biomeType === Biome.TALL_GRASS || p.scene.arena.biomeType === Biome.METROPOLIS), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "vanilla-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.TOWN || p.scene.arena.biomeType === Biome.PLAINS || p.scene.arena.biomeType === Biome.GRASS || p.scene.arena.biomeType === Biome.TALL_GRASS || p.scene.arena.biomeType === Biome.METROPOLIS), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'ruby-cream', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.BADLANDS || p.scene.arena.biomeType === Biome.VOLCANO || p.scene.arena.biomeType === Biome.GRAVEYARD || p.scene.arena.biomeType === Biome.FACTORY || p.scene.arena.biomeType === Biome.SLUM), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.BADLANDS || p.scene.arena.biomeType === Biome.VOLCANO || p.scene.arena.biomeType === Biome.GRAVEYARD || p.scene.arena.biomeType === Biome.FACTORY || p.scene.arena.biomeType === Biome.SLUM), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'matcha-cream', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.FOREST || p.scene.arena.biomeType === Biome.SWAMP || p.scene.arena.biomeType === Biome.MEADOW || p.scene.arena.biomeType === Biome.JUNGLE), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "matcha-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.FOREST || p.scene.arena.biomeType === Biome.SWAMP || p.scene.arena.biomeType === Biome.MEADOW || p.scene.arena.biomeType === Biome.JUNGLE), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'mint-cream', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.SEA || p.scene.arena.biomeType === Biome.BEACH || p.scene.arena.biomeType === Biome.LAKE || p.scene.arena.biomeType === Biome.SEABED), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "mint-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.SEA || p.scene.arena.biomeType === Biome.BEACH || p.scene.arena.biomeType === Biome.LAKE || p.scene.arena.biomeType === Biome.SEABED), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'lemon-cream', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.DESERT || p.scene.arena.biomeType === Biome.POWER_PLANT || p.scene.arena.biomeType === Biome.DOJO || p.scene.arena.biomeType === Biome.RUINS || p.scene.arena.biomeType === Biome.CONSTRUCTION_SITE), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "lemon-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.DESERT || p.scene.arena.biomeType === Biome.POWER_PLANT || p.scene.arena.biomeType === Biome.DOJO || p.scene.arena.biomeType === Biome.RUINS || p.scene.arena.biomeType === Biome.CONSTRUCTION_SITE), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'salted-cream', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.MOUNTAIN || p.scene.arena.biomeType === Biome.CAVE || p.scene.arena.biomeType === Biome.ICE_CAVE || p.scene.arena.biomeType === Biome.FAIRY_CAVE || p.scene.arena.biomeType === Biome.SNOWY_FOREST), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "salted-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.MOUNTAIN || p.scene.arena.biomeType === Biome.CAVE || p.scene.arena.biomeType === Biome.ICE_CAVE || p.scene.arena.biomeType === Biome.FAIRY_CAVE || p.scene.arena.biomeType === Biome.SNOWY_FOREST), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'ruby-swirl', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.WASTELAND || p.scene.arena.biomeType === Biome.LABORATORY), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.WASTELAND || p.scene.arena.biomeType === Biome.LABORATORY), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'caramel-swirl', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.TEMPLE || p.scene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "caramel-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.TEMPLE || p.scene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'rainbow-swirl', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ABYSS || p.scene.arena.biomeType === Biome.SPACE || p.scene.arena.biomeType === Biome.END), SpeciesWildEvolutionDelay.LONG) new SpeciesFormEvolution(Species.ALCREMIE, "", "rainbow-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ABYSS || p.scene.arena.biomeType === Biome.SPACE || p.scene.arena.biomeType === Biome.END), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.DURALUDON]: [ [Species.DURALUDON]: [
new SpeciesFormEvolution(Species.ARCHALUDON, '', '', 1, EvolutionItem.METAL_ALLOY, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesFormEvolution(Species.ARCHALUDON, "", "", 1, EvolutionItem.METAL_ALLOY, null, SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.KUBFU]: [ [Species.KUBFU]: [
new SpeciesFormEvolution(Species.URSHIFU, '', 'single-strike', 1, EvolutionItem.SCROLL_OF_DARKNESS, null, SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesFormEvolution(Species.URSHIFU, "", "single-strike", 1, EvolutionItem.SCROLL_OF_DARKNESS, null, SpeciesWildEvolutionDelay.VERY_LONG),
new SpeciesFormEvolution(Species.URSHIFU, '', 'rapid-strike', 1, EvolutionItem.SCROLL_OF_WATERS, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesFormEvolution(Species.URSHIFU, "", "rapid-strike", 1, EvolutionItem.SCROLL_OF_WATERS, null, SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.GALAR_DARUMAKA]: [ [Species.GALAR_DARUMAKA]: [
new SpeciesEvolution(Species.GALAR_DARMANITAN, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.GALAR_DARMANITAN, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
@ -1466,8 +1467,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.CETITAN, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.CETITAN, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.POLTCHAGEIST]: [ [Species.POLTCHAGEIST]: [
new SpeciesFormEvolution(Species.SINISTCHA, 'counterfeit', 'unremarkable', 1, EvolutionItem.UNREMARKABLE_TEACUP, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.SINISTCHA, "counterfeit", "unremarkable", 1, EvolutionItem.UNREMARKABLE_TEACUP, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.SINISTCHA, 'artisan', 'masterpiece', 1, EvolutionItem.MASTERPIECE_TEACUP, null, SpeciesWildEvolutionDelay.LONG) new SpeciesFormEvolution(Species.SINISTCHA, "artisan", "masterpiece", 1, EvolutionItem.MASTERPIECE_TEACUP, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.DIPPLIN]: [ [Species.DIPPLIN]: [
new SpeciesEvolution(Species.HYDRAPPLE, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.DRAGON_CHEER).length > 0), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.HYDRAPPLE, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.DRAGON_CHEER).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
@ -1608,7 +1609,8 @@ 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 SpeciesEvolution(Species.GHOLDENGO, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.VERY_LONG) ] new SpeciesEvolution(Species.GHOLDENGO, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.VERY_LONG)
]
}; };
interface PokemonPrevolutions { interface PokemonPrevolutions {
@ -1618,13 +1620,14 @@ interface PokemonPrevolutions {
export const pokemonPrevolutions: PokemonPrevolutions = {}; export const pokemonPrevolutions: PokemonPrevolutions = {};
{ {
const megaFormKeys = [ SpeciesFormKey.MEGA, '', SpeciesFormKey.MEGA_X, '', SpeciesFormKey.MEGA_Y ].map(sfk => sfk as string); const megaFormKeys = [ SpeciesFormKey.MEGA, "", SpeciesFormKey.MEGA_X, "", SpeciesFormKey.MEGA_Y ].map(sfk => sfk as string);
const prevolutionKeys = Object.keys(pokemonEvolutions); const prevolutionKeys = Object.keys(pokemonEvolutions);
prevolutionKeys.forEach(pk => { prevolutionKeys.forEach(pk => {
const evolutions = pokemonEvolutions[pk]; const evolutions = pokemonEvolutions[pk];
for (let ev of evolutions) { for (const ev of evolutions) {
if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) {
continue; continue;
}
pokemonPrevolutions[ev.speciesId] = parseInt(pk) as Species; pokemonPrevolutions[ev.speciesId] = parseInt(pk) as Species;
} }
}); });

View File

@ -147,38 +147,46 @@ export class SpeciesFormChange {
} }
canChange(pokemon: Pokemon): boolean { canChange(pokemon: Pokemon): boolean {
if (pokemon.species.speciesId !== this.speciesId) if (pokemon.species.speciesId !== this.speciesId) {
return false;
if (!pokemon.species.forms.length)
return false;
const formKeys = pokemon.species.forms.map(f => f.formKey);
if (formKeys[pokemon.formIndex] !== this.preFormKey)
return false;
if (formKeys[pokemon.formIndex] === this.formKey)
return false;
for (let condition of this.conditions) {
if (!condition.predicate(pokemon))
return false; return false;
} }
if (!this.trigger.canChange(pokemon)) if (!pokemon.species.forms.length) {
return false; return false;
}
const formKeys = pokemon.species.forms.map(f => f.formKey);
if (formKeys[pokemon.formIndex] !== this.preFormKey) {
return false;
}
if (formKeys[pokemon.formIndex] === this.formKey) {
return false;
}
for (const condition of this.conditions) {
if (!condition.predicate(pokemon)) {
return false;
}
}
if (!this.trigger.canChange(pokemon)) {
return false;
}
return true; return true;
} }
findTrigger(triggerType: { new(...args: any[]): SpeciesFormChangeTrigger }): SpeciesFormChangeTrigger { findTrigger(triggerType: { new(...args: any[]): SpeciesFormChangeTrigger }): SpeciesFormChangeTrigger {
if (!this.trigger.hasTriggerType(triggerType)) if (!this.trigger.hasTriggerType(triggerType)) {
return null; return null;
}
let trigger = this.trigger; const trigger = this.trigger;
if (trigger instanceof SpeciesFormChangeCompoundTrigger) if (trigger instanceof SpeciesFormChangeCompoundTrigger) {
return trigger.triggers.find(t => t.hasTriggerType(triggerType)); return trigger.triggers.find(t => t.hasTriggerType(triggerType));
}
return trigger; return trigger;
} }
@ -218,10 +226,11 @@ export class SpeciesFormChangeCompoundTrigger {
} }
canChange(pokemon: Pokemon): boolean { canChange(pokemon: Pokemon): boolean {
for (let trigger of this.triggers) { for (const trigger of this.triggers) {
if (!trigger.canChange(pokemon)) if (!trigger.canChange(pokemon)) {
return false; return false;
} }
}
return true; return true;
} }
@ -278,8 +287,9 @@ export class SpeciesFormChangeStatusEffectTrigger extends SpeciesFormChangeTrigg
constructor(statusEffects: StatusEffect | StatusEffect[], invert: boolean = false) { constructor(statusEffects: StatusEffect | StatusEffect[], invert: boolean = false) {
super(); super();
if (!Array.isArray(statusEffects)) if (!Array.isArray(statusEffects)) {
statusEffects = [ statusEffects ]; statusEffects = [ statusEffects ];
}
this.statusEffects = statusEffects; this.statusEffects = statusEffects;
this.invert = invert; this.invert = invert;
} }
@ -310,7 +320,7 @@ export abstract class SpeciesFormChangeMoveTrigger extends SpeciesFormChangeTrig
constructor(move: Moves | ((m: Moves) => boolean), used: boolean = true) { constructor(move: Moves | ((m: Moves) => boolean), used: boolean = true) {
super(); super();
this.movePredicate = typeof move === 'function' ? move : (m: Moves) => m === move; this.movePredicate = typeof move === "function" ? move : (m: Moves) => m === move;
this.used = used; this.used = used;
} }
} }
@ -344,17 +354,21 @@ export class SpeciesDefaultFormMatchTrigger extends SpeciesFormChangeTrigger {
export function getSpeciesFormChangeMessage(pokemon: Pokemon, formChange: SpeciesFormChange, preName: string): string { export function getSpeciesFormChangeMessage(pokemon: Pokemon, formChange: SpeciesFormChange, preName: string): string {
const isMega = formChange.formKey.indexOf(SpeciesFormKey.MEGA) > -1; const isMega = formChange.formKey.indexOf(SpeciesFormKey.MEGA) > -1;
const isGmax = formChange.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1; const isGmax = formChange.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1;
const isEmax = formChange.formKey.indexOf('eternamax') > -1; const isEmax = formChange.formKey.indexOf("eternamax") > -1;
const isRevert = !isMega && formChange.formKey === pokemon.species.forms[0].formKey; const isRevert = !isMega && formChange.formKey === pokemon.species.forms[0].formKey;
const prefix = !pokemon.isPlayer() ? pokemon.hasTrainer() ? 'Foe ' : 'Wild ' : 'Your '; const prefix = !pokemon.isPlayer() ? pokemon.hasTrainer() ? "Foe " : "Wild " : "Your ";
if (isMega) if (isMega) {
return `${prefix}${preName} mega-evolved\ninto ${pokemon.name}!`; return `${prefix}${preName} mega-evolved\ninto ${pokemon.name}!`;
if (isGmax) }
if (isGmax) {
return `${prefix}${preName} Gigantamaxed\ninto ${pokemon.name}!`; return `${prefix}${preName} Gigantamaxed\ninto ${pokemon.name}!`;
if (isEmax) }
if (isEmax) {
return `${prefix}${preName} Eternamaxed\ninto ${pokemon.name}!`; return `${prefix}${preName} Eternamaxed\ninto ${pokemon.name}!`;
if (isRevert) }
if (isRevert) {
return `${prefix}${pokemon.name} reverted\nto its original form!`; return `${prefix}${pokemon.name} reverted\nto its original form!`;
}
return `${prefix}${preName} changed form!`; return `${prefix}${preName} changed form!`;
} }
@ -364,221 +378,221 @@ interface PokemonFormChanges {
export const pokemonFormChanges: PokemonFormChanges = { export const pokemonFormChanges: PokemonFormChanges = {
[Species.VENUSAUR]: [ [Species.VENUSAUR]: [
new SpeciesFormChange(Species.VENUSAUR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.VENUSAURITE)), new SpeciesFormChange(Species.VENUSAUR, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.VENUSAURITE)),
new SpeciesFormChange(Species.VENUSAUR, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.VENUSAUR, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.BLASTOISE]: [ [Species.BLASTOISE]: [
new SpeciesFormChange(Species.BLASTOISE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BLASTOISINITE)), new SpeciesFormChange(Species.BLASTOISE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BLASTOISINITE)),
new SpeciesFormChange(Species.BLASTOISE, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.BLASTOISE, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.CHARIZARD]: [ [Species.CHARIZARD]: [
new SpeciesFormChange(Species.CHARIZARD, '', SpeciesFormKey.MEGA_X, new SpeciesFormChangeItemTrigger(FormChangeItem.CHARIZARDITE_X)), new SpeciesFormChange(Species.CHARIZARD, "", SpeciesFormKey.MEGA_X, new SpeciesFormChangeItemTrigger(FormChangeItem.CHARIZARDITE_X)),
new SpeciesFormChange(Species.CHARIZARD, '', SpeciesFormKey.MEGA_Y, new SpeciesFormChangeItemTrigger(FormChangeItem.CHARIZARDITE_Y)), new SpeciesFormChange(Species.CHARIZARD, "", SpeciesFormKey.MEGA_Y, new SpeciesFormChangeItemTrigger(FormChangeItem.CHARIZARDITE_Y)),
new SpeciesFormChange(Species.CHARIZARD, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.CHARIZARD, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.BUTTERFREE]: [ [Species.BUTTERFREE]: [
new SpeciesFormChange(Species.BUTTERFREE, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.BUTTERFREE, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.BEEDRILL]: [ [Species.BEEDRILL]: [
new SpeciesFormChange(Species.BEEDRILL, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BEEDRILLITE)) new SpeciesFormChange(Species.BEEDRILL, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BEEDRILLITE))
], ],
[Species.PIDGEOT]: [ [Species.PIDGEOT]: [
new SpeciesFormChange(Species.PIDGEOT, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.PIDGEOTITE)) new SpeciesFormChange(Species.PIDGEOT, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.PIDGEOTITE))
], ],
[Species.PIKACHU]: [ [Species.PIKACHU]: [
new SpeciesFormChange(Species.PIKACHU, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.PIKACHU, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.MEOWTH]: [ [Species.MEOWTH]: [
new SpeciesFormChange(Species.MEOWTH, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.MEOWTH, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.ALAKAZAM]: [ [Species.ALAKAZAM]: [
new SpeciesFormChange(Species.ALAKAZAM, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALAKAZITE)) new SpeciesFormChange(Species.ALAKAZAM, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALAKAZITE))
], ],
[Species.MACHAMP]: [ [Species.MACHAMP]: [
new SpeciesFormChange(Species.MACHAMP, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.MACHAMP, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.SLOWBRO]: [ [Species.SLOWBRO]: [
new SpeciesFormChange(Species.SLOWBRO, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SLOWBRONITE)) new SpeciesFormChange(Species.SLOWBRO, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SLOWBRONITE))
], ],
[Species.GENGAR]: [ [Species.GENGAR]: [
new SpeciesFormChange(Species.GENGAR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GENGARITE)), new SpeciesFormChange(Species.GENGAR, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GENGARITE)),
new SpeciesFormChange(Species.GENGAR, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.GENGAR, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.KINGLER]: [ [Species.KINGLER]: [
new SpeciesFormChange(Species.KINGLER, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.KINGLER, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.KANGASKHAN]: [ [Species.KANGASKHAN]: [
new SpeciesFormChange(Species.KANGASKHAN, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.KANGASKHANITE)) new SpeciesFormChange(Species.KANGASKHAN, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.KANGASKHANITE))
], ],
[Species.PINSIR]: [ [Species.PINSIR]: [
new SpeciesFormChange(Species.PINSIR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.PINSIRITE)) new SpeciesFormChange(Species.PINSIR, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.PINSIRITE))
], ],
[Species.GYARADOS]: [ [Species.GYARADOS]: [
new SpeciesFormChange(Species.GYARADOS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GYARADOSITE)) new SpeciesFormChange(Species.GYARADOS, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GYARADOSITE))
], ],
[Species.LAPRAS]: [ [Species.LAPRAS]: [
new SpeciesFormChange(Species.LAPRAS, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.LAPRAS, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.EEVEE]: [ [Species.EEVEE]: [
new SpeciesFormChange(Species.EEVEE, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.EEVEE, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.SNORLAX]: [ [Species.SNORLAX]: [
new SpeciesFormChange(Species.SNORLAX, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.SNORLAX, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.AERODACTYL]: [ [Species.AERODACTYL]: [
new SpeciesFormChange(Species.AERODACTYL, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AERODACTYLITE)) new SpeciesFormChange(Species.AERODACTYL, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AERODACTYLITE))
], ],
[Species.MEWTWO]: [ [Species.MEWTWO]: [
new SpeciesFormChange(Species.MEWTWO, '', SpeciesFormKey.MEGA_X, new SpeciesFormChangeItemTrigger(FormChangeItem.MEWTWONITE_X)), new SpeciesFormChange(Species.MEWTWO, "", SpeciesFormKey.MEGA_X, new SpeciesFormChangeItemTrigger(FormChangeItem.MEWTWONITE_X)),
new SpeciesFormChange(Species.MEWTWO, '', SpeciesFormKey.MEGA_Y, new SpeciesFormChangeItemTrigger(FormChangeItem.MEWTWONITE_Y)) new SpeciesFormChange(Species.MEWTWO, "", SpeciesFormKey.MEGA_Y, new SpeciesFormChangeItemTrigger(FormChangeItem.MEWTWONITE_Y))
], ],
[Species.AMPHAROS]: [ [Species.AMPHAROS]: [
new SpeciesFormChange(Species.AMPHAROS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AMPHAROSITE)) new SpeciesFormChange(Species.AMPHAROS, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AMPHAROSITE))
], ],
[Species.STEELIX]: [ [Species.STEELIX]: [
new SpeciesFormChange(Species.STEELIX, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.STEELIXITE)) new SpeciesFormChange(Species.STEELIX, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.STEELIXITE))
], ],
[Species.SCIZOR]: [ [Species.SCIZOR]: [
new SpeciesFormChange(Species.SCIZOR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SCIZORITE)) new SpeciesFormChange(Species.SCIZOR, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SCIZORITE))
], ],
[Species.HERACROSS]: [ [Species.HERACROSS]: [
new SpeciesFormChange(Species.HERACROSS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.HERACRONITE)) new SpeciesFormChange(Species.HERACROSS, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.HERACRONITE))
], ],
[Species.HOUNDOOM]: [ [Species.HOUNDOOM]: [
new SpeciesFormChange(Species.HOUNDOOM, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.HOUNDOOMINITE)) new SpeciesFormChange(Species.HOUNDOOM, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.HOUNDOOMINITE))
], ],
[Species.TYRANITAR]: [ [Species.TYRANITAR]: [
new SpeciesFormChange(Species.TYRANITAR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.TYRANITARITE)) new SpeciesFormChange(Species.TYRANITAR, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.TYRANITARITE))
], ],
[Species.SCEPTILE]: [ [Species.SCEPTILE]: [
new SpeciesFormChange(Species.SCEPTILE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SCEPTILITE)) new SpeciesFormChange(Species.SCEPTILE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SCEPTILITE))
], ],
[Species.BLAZIKEN]: [ [Species.BLAZIKEN]: [
new SpeciesFormChange(Species.BLAZIKEN, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BLAZIKENITE)) new SpeciesFormChange(Species.BLAZIKEN, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BLAZIKENITE))
], ],
[Species.SWAMPERT]: [ [Species.SWAMPERT]: [
new SpeciesFormChange(Species.SWAMPERT, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SWAMPERTITE)) new SpeciesFormChange(Species.SWAMPERT, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SWAMPERTITE))
], ],
[Species.GARDEVOIR]: [ [Species.GARDEVOIR]: [
new SpeciesFormChange(Species.GARDEVOIR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GARDEVOIRITE)) new SpeciesFormChange(Species.GARDEVOIR, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GARDEVOIRITE))
], ],
[Species.SABLEYE]: [ [Species.SABLEYE]: [
new SpeciesFormChange(Species.SABLEYE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SABLENITE)) new SpeciesFormChange(Species.SABLEYE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SABLENITE))
], ],
[Species.MAWILE]: [ [Species.MAWILE]: [
new SpeciesFormChange(Species.MAWILE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MAWILITE)) new SpeciesFormChange(Species.MAWILE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MAWILITE))
], ],
[Species.AGGRON]: [ [Species.AGGRON]: [
new SpeciesFormChange(Species.AGGRON, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AGGRONITE)) new SpeciesFormChange(Species.AGGRON, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AGGRONITE))
], ],
[Species.MEDICHAM]: [ [Species.MEDICHAM]: [
new SpeciesFormChange(Species.MEDICHAM, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MEDICHAMITE)) new SpeciesFormChange(Species.MEDICHAM, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MEDICHAMITE))
], ],
[Species.MANECTRIC]: [ [Species.MANECTRIC]: [
new SpeciesFormChange(Species.MANECTRIC, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MANECTITE)) new SpeciesFormChange(Species.MANECTRIC, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MANECTITE))
], ],
[Species.SHARPEDO]: [ [Species.SHARPEDO]: [
new SpeciesFormChange(Species.SHARPEDO, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SHARPEDONITE)) new SpeciesFormChange(Species.SHARPEDO, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SHARPEDONITE))
], ],
[Species.CAMERUPT]: [ [Species.CAMERUPT]: [
new SpeciesFormChange(Species.CAMERUPT, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.CAMERUPTITE)) new SpeciesFormChange(Species.CAMERUPT, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.CAMERUPTITE))
], ],
[Species.ALTARIA]: [ [Species.ALTARIA]: [
new SpeciesFormChange(Species.ALTARIA, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALTARIANITE)) new SpeciesFormChange(Species.ALTARIA, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALTARIANITE))
], ],
[Species.BANETTE]: [ [Species.BANETTE]: [
new SpeciesFormChange(Species.BANETTE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BANETTITE)) new SpeciesFormChange(Species.BANETTE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BANETTITE))
], ],
[Species.ABSOL]: [ [Species.ABSOL]: [
new SpeciesFormChange(Species.ABSOL, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ABSOLITE)) new SpeciesFormChange(Species.ABSOL, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ABSOLITE))
], ],
[Species.GLALIE]: [ [Species.GLALIE]: [
new SpeciesFormChange(Species.GLALIE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GLALITITE)) new SpeciesFormChange(Species.GLALIE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GLALITITE))
], ],
[Species.SALAMENCE]: [ [Species.SALAMENCE]: [
new SpeciesFormChange(Species.SALAMENCE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SALAMENCITE)) new SpeciesFormChange(Species.SALAMENCE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SALAMENCITE))
], ],
[Species.METAGROSS]: [ [Species.METAGROSS]: [
new SpeciesFormChange(Species.METAGROSS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.METAGROSSITE)) new SpeciesFormChange(Species.METAGROSS, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.METAGROSSITE))
], ],
[Species.LATIAS]: [ [Species.LATIAS]: [
new SpeciesFormChange(Species.LATIAS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LATIASITE)) new SpeciesFormChange(Species.LATIAS, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LATIASITE))
], ],
[Species.LATIOS]: [ [Species.LATIOS]: [
new SpeciesFormChange(Species.LATIOS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LATIOSITE)) new SpeciesFormChange(Species.LATIOS, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LATIOSITE))
], ],
[Species.KYOGRE]: [ [Species.KYOGRE]: [
new SpeciesFormChange(Species.KYOGRE, '', SpeciesFormKey.PRIMAL, new SpeciesFormChangeItemTrigger(FormChangeItem.BLUE_ORB)) new SpeciesFormChange(Species.KYOGRE, "", SpeciesFormKey.PRIMAL, new SpeciesFormChangeItemTrigger(FormChangeItem.BLUE_ORB))
], ],
[Species.GROUDON]: [ [Species.GROUDON]: [
new SpeciesFormChange(Species.GROUDON, '', SpeciesFormKey.PRIMAL, new SpeciesFormChangeItemTrigger(FormChangeItem.RED_ORB)) new SpeciesFormChange(Species.GROUDON, "", SpeciesFormKey.PRIMAL, new SpeciesFormChangeItemTrigger(FormChangeItem.RED_ORB))
], ],
[Species.RAYQUAZA]: [ [Species.RAYQUAZA]: [
new SpeciesFormChange(Species.RAYQUAZA, '', SpeciesFormKey.MEGA, new SpeciesFormChangeCompoundTrigger(new SpeciesFormChangeItemTrigger(FormChangeItem.RAYQUAZITE), new SpeciesFormChangeMoveLearnedTrigger(Moves.DRAGON_ASCENT))) new SpeciesFormChange(Species.RAYQUAZA, "", SpeciesFormKey.MEGA, new SpeciesFormChangeCompoundTrigger(new SpeciesFormChangeItemTrigger(FormChangeItem.RAYQUAZITE), new SpeciesFormChangeMoveLearnedTrigger(Moves.DRAGON_ASCENT)))
], ],
[Species.DEOXYS]: [ [Species.DEOXYS]: [
new SpeciesFormChange(Species.DEOXYS, 'normal', 'attack', new SpeciesFormChangeItemTrigger(FormChangeItem.SHARP_METEORITE)), new SpeciesFormChange(Species.DEOXYS, "normal", "attack", new SpeciesFormChangeItemTrigger(FormChangeItem.SHARP_METEORITE)),
new SpeciesFormChange(Species.DEOXYS, 'normal', 'defense', new SpeciesFormChangeItemTrigger(FormChangeItem.HARD_METEORITE)), new SpeciesFormChange(Species.DEOXYS, "normal", "defense", new SpeciesFormChangeItemTrigger(FormChangeItem.HARD_METEORITE)),
new SpeciesFormChange(Species.DEOXYS, 'normal', 'speed', new SpeciesFormChangeItemTrigger(FormChangeItem.SMOOTH_METEORITE)) new SpeciesFormChange(Species.DEOXYS, "normal", "speed", new SpeciesFormChangeItemTrigger(FormChangeItem.SMOOTH_METEORITE))
], ],
[Species.LOPUNNY]: [ [Species.LOPUNNY]: [
new SpeciesFormChange(Species.LOPUNNY, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LOPUNNITE)) new SpeciesFormChange(Species.LOPUNNY, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LOPUNNITE))
], ],
[Species.GARCHOMP]: [ [Species.GARCHOMP]: [
new SpeciesFormChange(Species.GARCHOMP, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GARCHOMPITE)) new SpeciesFormChange(Species.GARCHOMP, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GARCHOMPITE))
], ],
[Species.LUCARIO]: [ [Species.LUCARIO]: [
new SpeciesFormChange(Species.LUCARIO, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LUCARIONITE)) new SpeciesFormChange(Species.LUCARIO, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LUCARIONITE))
], ],
[Species.ABOMASNOW]: [ [Species.ABOMASNOW]: [
new SpeciesFormChange(Species.ABOMASNOW, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ABOMASITE)) new SpeciesFormChange(Species.ABOMASNOW, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ABOMASITE))
], ],
[Species.GALLADE]: [ [Species.GALLADE]: [
new SpeciesFormChange(Species.GALLADE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GALLADITE)) new SpeciesFormChange(Species.GALLADE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GALLADITE))
], ],
[Species.AUDINO]: [ [Species.AUDINO]: [
new SpeciesFormChange(Species.AUDINO, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AUDINITE)) new SpeciesFormChange(Species.AUDINO, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AUDINITE))
], ],
[Species.DIALGA]: [ [Species.DIALGA]: [
new SpeciesFormChange(Species.DIALGA, '', SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.ADAMANT_CRYSTAL)) new SpeciesFormChange(Species.DIALGA, "", SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.ADAMANT_CRYSTAL))
], ],
[Species.PALKIA]: [ [Species.PALKIA]: [
new SpeciesFormChange(Species.PALKIA, '', SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.LUSTROUS_ORB)) new SpeciesFormChange(Species.PALKIA, "", SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.LUSTROUS_ORB))
], ],
[Species.GIRATINA]: [ [Species.GIRATINA]: [
new SpeciesFormChange(Species.GIRATINA, 'altered', SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.GRISEOUS_CORE)) new SpeciesFormChange(Species.GIRATINA, "altered", SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.GRISEOUS_CORE))
], ],
[Species.SHAYMIN]: [ [Species.SHAYMIN]: [
new SpeciesFormChange(Species.SHAYMIN, 'land', 'sky', new SpeciesFormChangeCompoundTrigger(new SpeciesFormChangeTimeOfDayTrigger(TimeOfDay.DAY, TimeOfDay.DUSK), new SpeciesFormChange(Species.SHAYMIN, "land", "sky", new SpeciesFormChangeCompoundTrigger(new SpeciesFormChangeTimeOfDayTrigger(TimeOfDay.DAY, TimeOfDay.DUSK),
new SpeciesFormChangeItemTrigger(FormChangeItem.GRACIDEA), new SpeciesFormChangeStatusEffectTrigger(StatusEffect.FREEZE, true))), new SpeciesFormChangeItemTrigger(FormChangeItem.GRACIDEA), new SpeciesFormChangeStatusEffectTrigger(StatusEffect.FREEZE, true))),
new SpeciesFormChange(Species.SHAYMIN, 'sky', 'land', new SpeciesFormChangeTimeOfDayTrigger(TimeOfDay.DAWN, TimeOfDay.NIGHT)), new SpeciesFormChange(Species.SHAYMIN, "sky", "land", new SpeciesFormChangeTimeOfDayTrigger(TimeOfDay.DAWN, TimeOfDay.NIGHT)),
new SpeciesFormChange(Species.SHAYMIN, 'sky', 'land', new SpeciesFormChangeStatusEffectTrigger(StatusEffect.FREEZE)) new SpeciesFormChange(Species.SHAYMIN, "sky", "land", new SpeciesFormChangeStatusEffectTrigger(StatusEffect.FREEZE))
], ],
[Species.ARCEUS]: [ [Species.ARCEUS]: [
new SpeciesFormChange(Species.ARCEUS, 'normal', 'fighting', new SpeciesFormChangeItemTrigger(FormChangeItem.FIST_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "fighting", new SpeciesFormChangeItemTrigger(FormChangeItem.FIST_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'flying', new SpeciesFormChangeItemTrigger(FormChangeItem.SKY_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "flying", new SpeciesFormChangeItemTrigger(FormChangeItem.SKY_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'poison', new SpeciesFormChangeItemTrigger(FormChangeItem.TOXIC_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "poison", new SpeciesFormChangeItemTrigger(FormChangeItem.TOXIC_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'ground', new SpeciesFormChangeItemTrigger(FormChangeItem.EARTH_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "ground", new SpeciesFormChangeItemTrigger(FormChangeItem.EARTH_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'rock', new SpeciesFormChangeItemTrigger(FormChangeItem.STONE_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "rock", new SpeciesFormChangeItemTrigger(FormChangeItem.STONE_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'bug', new SpeciesFormChangeItemTrigger(FormChangeItem.INSECT_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "bug", new SpeciesFormChangeItemTrigger(FormChangeItem.INSECT_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'ghost', new SpeciesFormChangeItemTrigger(FormChangeItem.SPOOKY_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "ghost", new SpeciesFormChangeItemTrigger(FormChangeItem.SPOOKY_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'steel', new SpeciesFormChangeItemTrigger(FormChangeItem.IRON_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "steel", new SpeciesFormChangeItemTrigger(FormChangeItem.IRON_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'fire', new SpeciesFormChangeItemTrigger(FormChangeItem.FLAME_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "fire", new SpeciesFormChangeItemTrigger(FormChangeItem.FLAME_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'water', new SpeciesFormChangeItemTrigger(FormChangeItem.SPLASH_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "water", new SpeciesFormChangeItemTrigger(FormChangeItem.SPLASH_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'grass', new SpeciesFormChangeItemTrigger(FormChangeItem.MEADOW_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "grass", new SpeciesFormChangeItemTrigger(FormChangeItem.MEADOW_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'electric', new SpeciesFormChangeItemTrigger(FormChangeItem.ZAP_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "electric", new SpeciesFormChangeItemTrigger(FormChangeItem.ZAP_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'psychic', new SpeciesFormChangeItemTrigger(FormChangeItem.MIND_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "psychic", new SpeciesFormChangeItemTrigger(FormChangeItem.MIND_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'ice', new SpeciesFormChangeItemTrigger(FormChangeItem.ICICLE_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "ice", new SpeciesFormChangeItemTrigger(FormChangeItem.ICICLE_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'dragon', new SpeciesFormChangeItemTrigger(FormChangeItem.DRACO_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "dragon", new SpeciesFormChangeItemTrigger(FormChangeItem.DRACO_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'dark', new SpeciesFormChangeItemTrigger(FormChangeItem.DREAD_PLATE)), new SpeciesFormChange(Species.ARCEUS, "normal", "dark", new SpeciesFormChangeItemTrigger(FormChangeItem.DREAD_PLATE)),
new SpeciesFormChange(Species.ARCEUS, 'normal', 'fairy', new SpeciesFormChangeItemTrigger(FormChangeItem.PIXIE_PLATE)) new SpeciesFormChange(Species.ARCEUS, "normal", "fairy", new SpeciesFormChangeItemTrigger(FormChangeItem.PIXIE_PLATE))
], ],
[Species.DARMANITAN]: [ [Species.DARMANITAN]: [
new SpeciesFormChange(Species.DARMANITAN, '', 'zen', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.DARMANITAN, "", "zen", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.DARMANITAN, 'zen', '', new SpeciesFormChangeManualTrigger(), true) new SpeciesFormChange(Species.DARMANITAN, "zen", "", new SpeciesFormChangeManualTrigger(), true)
], ],
[Species.GARBODOR]: [ [Species.GARBODOR]: [
new SpeciesFormChange(Species.GARBODOR, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.GARBODOR, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.TORNADUS]: [ [Species.TORNADUS]: [
new SpeciesFormChange(Species.TORNADUS, SpeciesFormKey.INCARNATE, SpeciesFormKey.THERIAN, new SpeciesFormChangeItemTrigger(FormChangeItem.REVEAL_GLASS)) new SpeciesFormChange(Species.TORNADUS, SpeciesFormKey.INCARNATE, SpeciesFormKey.THERIAN, new SpeciesFormChangeItemTrigger(FormChangeItem.REVEAL_GLASS))
@ -590,203 +604,203 @@ export const pokemonFormChanges: PokemonFormChanges = {
new SpeciesFormChange(Species.LANDORUS, SpeciesFormKey.INCARNATE, SpeciesFormKey.THERIAN, new SpeciesFormChangeItemTrigger(FormChangeItem.REVEAL_GLASS)) new SpeciesFormChange(Species.LANDORUS, SpeciesFormKey.INCARNATE, SpeciesFormKey.THERIAN, new SpeciesFormChangeItemTrigger(FormChangeItem.REVEAL_GLASS))
], ],
[Species.KYUREM]: [ [Species.KYUREM]: [
new SpeciesFormChange(Species.KYUREM, '', 'black', new SpeciesFormChangeItemTrigger(FormChangeItem.DARK_STONE)), new SpeciesFormChange(Species.KYUREM, "", "black", new SpeciesFormChangeItemTrigger(FormChangeItem.DARK_STONE)),
new SpeciesFormChange(Species.KYUREM, '', 'white', new SpeciesFormChangeItemTrigger(FormChangeItem.LIGHT_STONE)) new SpeciesFormChange(Species.KYUREM, "", "white", new SpeciesFormChangeItemTrigger(FormChangeItem.LIGHT_STONE))
], ],
[Species.KELDEO]: [ [Species.KELDEO]: [
new SpeciesFormChange(Species.KELDEO, 'ordinary', 'resolute', new SpeciesFormChangeMoveLearnedTrigger(Moves.SECRET_SWORD)), new SpeciesFormChange(Species.KELDEO, "ordinary", "resolute", new SpeciesFormChangeMoveLearnedTrigger(Moves.SECRET_SWORD)),
new SpeciesFormChange(Species.KELDEO, 'resolute', 'ordinary', new SpeciesFormChangeMoveLearnedTrigger(Moves.SECRET_SWORD, false)) new SpeciesFormChange(Species.KELDEO, "resolute", "ordinary", new SpeciesFormChangeMoveLearnedTrigger(Moves.SECRET_SWORD, false))
], ],
[Species.MELOETTA]: [ [Species.MELOETTA]: [
new SpeciesFormChange(Species.MELOETTA, 'aria', 'pirouette', new SpeciesFormChangePostMoveTrigger(Moves.RELIC_SONG), true), new SpeciesFormChange(Species.MELOETTA, "aria", "pirouette", new SpeciesFormChangePostMoveTrigger(Moves.RELIC_SONG), true),
new SpeciesFormChange(Species.MELOETTA, 'pirouette', 'aria', new SpeciesFormChangePostMoveTrigger(Moves.RELIC_SONG), true), new SpeciesFormChange(Species.MELOETTA, "pirouette", "aria", new SpeciesFormChangePostMoveTrigger(Moves.RELIC_SONG), true),
new SpeciesFormChange(Species.MELOETTA, 'pirouette', 'aria', new SpeciesFormChangeActiveTrigger(false), true) new SpeciesFormChange(Species.MELOETTA, "pirouette", "aria", new SpeciesFormChangeActiveTrigger(false), true)
], ],
[Species.GENESECT]: [ [Species.GENESECT]: [
new SpeciesFormChange(Species.GENESECT, '', 'shock', new SpeciesFormChangeItemTrigger(FormChangeItem.SHOCK_DRIVE)), new SpeciesFormChange(Species.GENESECT, "", "shock", new SpeciesFormChangeItemTrigger(FormChangeItem.SHOCK_DRIVE)),
new SpeciesFormChange(Species.GENESECT, '', 'burn', new SpeciesFormChangeItemTrigger(FormChangeItem.BURN_DRIVE)), new SpeciesFormChange(Species.GENESECT, "", "burn", new SpeciesFormChangeItemTrigger(FormChangeItem.BURN_DRIVE)),
new SpeciesFormChange(Species.GENESECT, '', 'chill', new SpeciesFormChangeItemTrigger(FormChangeItem.CHILL_DRIVE)), new SpeciesFormChange(Species.GENESECT, "", "chill", new SpeciesFormChangeItemTrigger(FormChangeItem.CHILL_DRIVE)),
new SpeciesFormChange(Species.GENESECT, '', 'douse', new SpeciesFormChangeItemTrigger(FormChangeItem.DOUSE_DRIVE)) new SpeciesFormChange(Species.GENESECT, "", "douse", new SpeciesFormChangeItemTrigger(FormChangeItem.DOUSE_DRIVE))
], ],
[Species.GRENINJA]: [ [Species.GRENINJA]: [
new SpeciesFormChange(Species.GRENINJA, 'battle-bond', 'ash', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.GRENINJA, "battle-bond", "ash", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.GRENINJA, 'ash', 'battle-bond', new SpeciesFormChangeManualTrigger(), true) new SpeciesFormChange(Species.GRENINJA, "ash", "battle-bond", new SpeciesFormChangeManualTrigger(), true)
], ],
[Species.AEGISLASH]: [ [Species.AEGISLASH]: [
new SpeciesFormChange(Species.AEGISLASH, 'blade', 'shield', new SpeciesFormChangePreMoveTrigger(Moves.KINGS_SHIELD), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.STANCE_CHANGE))), new SpeciesFormChange(Species.AEGISLASH, "blade", "shield", new SpeciesFormChangePreMoveTrigger(Moves.KINGS_SHIELD), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.STANCE_CHANGE))),
new SpeciesFormChange(Species.AEGISLASH, 'shield', 'blade', new SpeciesFormChangePreMoveTrigger(m => allMoves[m].category !== MoveCategory.STATUS), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.STANCE_CHANGE))), new SpeciesFormChange(Species.AEGISLASH, "shield", "blade", new SpeciesFormChangePreMoveTrigger(m => allMoves[m].category !== MoveCategory.STATUS), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.STANCE_CHANGE))),
new SpeciesFormChange(Species.AEGISLASH, 'blade', 'shield', new SpeciesFormChangeActiveTrigger(false), true) new SpeciesFormChange(Species.AEGISLASH, "blade", "shield", new SpeciesFormChangeActiveTrigger(false), true)
], ],
[Species.ZYGARDE]: [ [Species.ZYGARDE]: [
new SpeciesFormChange(Species.ZYGARDE, '50-pc', 'complete', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.ZYGARDE, "50-pc", "complete", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.ZYGARDE, 'complete', '50-pc', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.ZYGARDE, "complete", "50-pc", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.ZYGARDE, '10-pc', 'complete', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.ZYGARDE, "10-pc", "complete", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.ZYGARDE, 'complete', '10-pc', new SpeciesFormChangeManualTrigger(), true) new SpeciesFormChange(Species.ZYGARDE, "complete", "10-pc", new SpeciesFormChangeManualTrigger(), true)
], ],
[Species.DIANCIE]: [ [Species.DIANCIE]: [
new SpeciesFormChange(Species.DIANCIE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.DIANCITE)) new SpeciesFormChange(Species.DIANCIE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.DIANCITE))
], ],
[Species.HOOPA]: [ [Species.HOOPA]: [
new SpeciesFormChange(Species.HOOPA, '', 'unbound', new SpeciesFormChangeItemTrigger(FormChangeItem.PRISON_BOTTLE)) new SpeciesFormChange(Species.HOOPA, "", "unbound", new SpeciesFormChangeItemTrigger(FormChangeItem.PRISON_BOTTLE))
], ],
[Species.WISHIWASHI]: [ [Species.WISHIWASHI]: [
new SpeciesFormChange(Species.WISHIWASHI, '', 'school', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.WISHIWASHI, "", "school", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.WISHIWASHI, 'school', '', new SpeciesFormChangeManualTrigger(), true) new SpeciesFormChange(Species.WISHIWASHI, "school", "", new SpeciesFormChangeManualTrigger(), true)
], ],
[Species.SILVALLY]: [ [Species.SILVALLY]: [
new SpeciesFormChange(Species.SILVALLY, 'normal', 'fighting', new SpeciesFormChangeItemTrigger(FormChangeItem.FIGHTING_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "fighting", new SpeciesFormChangeItemTrigger(FormChangeItem.FIGHTING_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'flying', new SpeciesFormChangeItemTrigger(FormChangeItem.FLYING_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "flying", new SpeciesFormChangeItemTrigger(FormChangeItem.FLYING_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'poison', new SpeciesFormChangeItemTrigger(FormChangeItem.POISON_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "poison", new SpeciesFormChangeItemTrigger(FormChangeItem.POISON_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'ground', new SpeciesFormChangeItemTrigger(FormChangeItem.GROUND_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "ground", new SpeciesFormChangeItemTrigger(FormChangeItem.GROUND_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'rock', new SpeciesFormChangeItemTrigger(FormChangeItem.ROCK_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "rock", new SpeciesFormChangeItemTrigger(FormChangeItem.ROCK_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'bug', new SpeciesFormChangeItemTrigger(FormChangeItem.BUG_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "bug", new SpeciesFormChangeItemTrigger(FormChangeItem.BUG_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'ghost', new SpeciesFormChangeItemTrigger(FormChangeItem.GHOST_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "ghost", new SpeciesFormChangeItemTrigger(FormChangeItem.GHOST_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'steel', new SpeciesFormChangeItemTrigger(FormChangeItem.STEEL_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "steel", new SpeciesFormChangeItemTrigger(FormChangeItem.STEEL_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'fire', new SpeciesFormChangeItemTrigger(FormChangeItem.FIRE_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "fire", new SpeciesFormChangeItemTrigger(FormChangeItem.FIRE_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'water', new SpeciesFormChangeItemTrigger(FormChangeItem.WATER_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "water", new SpeciesFormChangeItemTrigger(FormChangeItem.WATER_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'grass', new SpeciesFormChangeItemTrigger(FormChangeItem.GRASS_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "grass", new SpeciesFormChangeItemTrigger(FormChangeItem.GRASS_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'electric', new SpeciesFormChangeItemTrigger(FormChangeItem.ELECTRIC_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "electric", new SpeciesFormChangeItemTrigger(FormChangeItem.ELECTRIC_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'psychic', new SpeciesFormChangeItemTrigger(FormChangeItem.PSYCHIC_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "psychic", new SpeciesFormChangeItemTrigger(FormChangeItem.PSYCHIC_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'ice', new SpeciesFormChangeItemTrigger(FormChangeItem.ICE_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "ice", new SpeciesFormChangeItemTrigger(FormChangeItem.ICE_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'dragon', new SpeciesFormChangeItemTrigger(FormChangeItem.DRAGON_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "dragon", new SpeciesFormChangeItemTrigger(FormChangeItem.DRAGON_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'dark', new SpeciesFormChangeItemTrigger(FormChangeItem.DARK_MEMORY)), new SpeciesFormChange(Species.SILVALLY, "normal", "dark", new SpeciesFormChangeItemTrigger(FormChangeItem.DARK_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, 'normal', 'fairy', new SpeciesFormChangeItemTrigger(FormChangeItem.FAIRY_MEMORY)) new SpeciesFormChange(Species.SILVALLY, "normal", "fairy", new SpeciesFormChangeItemTrigger(FormChangeItem.FAIRY_MEMORY))
], ],
[Species.MINIOR]: [ [Species.MINIOR]: [
new SpeciesFormChange(Species.MINIOR, 'red-meteor', 'red', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MINIOR, "red-meteor", "red", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'red', 'red-meteor', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MINIOR, "red", "red-meteor", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'orange-meteor', 'orange', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MINIOR, "orange-meteor", "orange", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'orange', 'orange-meteor', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MINIOR, "orange", "orange-meteor", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'yellow-meteor', 'yellow', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MINIOR, "yellow-meteor", "yellow", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'yellow', 'yellow-meteor', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MINIOR, "yellow", "yellow-meteor", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'green-meteor', 'green', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MINIOR, "green-meteor", "green", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'green', 'green-meteor', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MINIOR, "green", "green-meteor", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'blue-meteor', 'blue', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MINIOR, "blue-meteor", "blue", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'blue', 'blue-meteor', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MINIOR, "blue", "blue-meteor", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'indigo-meteor', 'indigo', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MINIOR, "indigo-meteor", "indigo", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'indigo', 'indigo-meteor', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MINIOR, "indigo", "indigo-meteor", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'violet-meteor', 'violet', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MINIOR, "violet-meteor", "violet", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'violet', 'violet-meteor', new SpeciesFormChangeManualTrigger(), true) new SpeciesFormChange(Species.MINIOR, "violet", "violet-meteor", new SpeciesFormChangeManualTrigger(), true)
], ],
[Species.MIMIKYU]: [ [Species.MIMIKYU]: [
new SpeciesFormChange(Species.MIMIKYU, 'disguised', 'busted', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MIMIKYU, "disguised", "busted", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MIMIKYU, 'busted', 'disguised', new SpeciesFormChangeManualTrigger(), true) new SpeciesFormChange(Species.MIMIKYU, "busted", "disguised", new SpeciesFormChangeManualTrigger(), true)
], ],
[Species.NECROZMA]: [ [Species.NECROZMA]: [
new SpeciesFormChange(Species.NECROZMA, '', 'dawn-wings', new SpeciesFormChangeItemTrigger(FormChangeItem.N_LUNARIZER)), new SpeciesFormChange(Species.NECROZMA, "", "dawn-wings", new SpeciesFormChangeItemTrigger(FormChangeItem.N_LUNARIZER)),
new SpeciesFormChange(Species.NECROZMA, '', 'dusk-mane', new SpeciesFormChangeItemTrigger(FormChangeItem.N_SOLARIZER)) new SpeciesFormChange(Species.NECROZMA, "", "dusk-mane", new SpeciesFormChangeItemTrigger(FormChangeItem.N_SOLARIZER))
], ],
[Species.MELMETAL]: [ [Species.MELMETAL]: [
new SpeciesFormChange(Species.MELMETAL, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.MELMETAL, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.RILLABOOM]: [ [Species.RILLABOOM]: [
new SpeciesFormChange(Species.RILLABOOM, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.RILLABOOM, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.CINDERACE]: [ [Species.CINDERACE]: [
new SpeciesFormChange(Species.CINDERACE, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.CINDERACE, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.INTELEON]: [ [Species.INTELEON]: [
new SpeciesFormChange(Species.INTELEON, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.INTELEON, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.CORVIKNIGHT]: [ [Species.CORVIKNIGHT]: [
new SpeciesFormChange(Species.CORVIKNIGHT, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.CORVIKNIGHT, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.ORBEETLE]: [ [Species.ORBEETLE]: [
new SpeciesFormChange(Species.ORBEETLE, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.ORBEETLE, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.DREDNAW]: [ [Species.DREDNAW]: [
new SpeciesFormChange(Species.DREDNAW, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.DREDNAW, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.COALOSSAL]: [ [Species.COALOSSAL]: [
new SpeciesFormChange(Species.COALOSSAL, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.COALOSSAL, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.FLAPPLE]: [ [Species.FLAPPLE]: [
new SpeciesFormChange(Species.FLAPPLE, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.FLAPPLE, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.APPLETUN]: [ [Species.APPLETUN]: [
new SpeciesFormChange(Species.APPLETUN, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.APPLETUN, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.SANDACONDA]: [ [Species.SANDACONDA]: [
new SpeciesFormChange(Species.SANDACONDA, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.SANDACONDA, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.TOXTRICITY]: [ [Species.TOXTRICITY]: [
new SpeciesFormChange(Species.TOXTRICITY, 'amped', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)), new SpeciesFormChange(Species.TOXTRICITY, "amped", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)),
new SpeciesFormChange(Species.TOXTRICITY, 'lowkey', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)), new SpeciesFormChange(Species.TOXTRICITY, "lowkey", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)),
new SpeciesFormChange(Species.TOXTRICITY, SpeciesFormKey.GIGANTAMAX, 'amped', new SpeciesFormChangeCompoundTrigger(new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS, false), new SpeciesDefaultFormMatchTrigger('amped'))), new SpeciesFormChange(Species.TOXTRICITY, SpeciesFormKey.GIGANTAMAX, "amped", new SpeciesFormChangeCompoundTrigger(new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS, false), new SpeciesDefaultFormMatchTrigger("amped"))),
new SpeciesFormChange(Species.TOXTRICITY, SpeciesFormKey.GIGANTAMAX, 'lowkey', new SpeciesFormChangeCompoundTrigger(new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS, false), new SpeciesDefaultFormMatchTrigger('lowkey'))) new SpeciesFormChange(Species.TOXTRICITY, SpeciesFormKey.GIGANTAMAX, "lowkey", new SpeciesFormChangeCompoundTrigger(new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS, false), new SpeciesDefaultFormMatchTrigger("lowkey")))
], ],
[Species.CENTISKORCH]: [ [Species.CENTISKORCH]: [
new SpeciesFormChange(Species.CENTISKORCH, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.CENTISKORCH, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.HATTERENE]: [ [Species.HATTERENE]: [
new SpeciesFormChange(Species.HATTERENE, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.HATTERENE, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.GRIMMSNARL]: [ [Species.GRIMMSNARL]: [
new SpeciesFormChange(Species.GRIMMSNARL, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.GRIMMSNARL, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.ALCREMIE]: [ [Species.ALCREMIE]: [
new SpeciesFormChange(Species.ALCREMIE, 'vanilla-cream', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)), new SpeciesFormChange(Species.ALCREMIE, "vanilla-cream", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)),
new SpeciesFormChange(Species.ALCREMIE, 'ruby-cream', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)), new SpeciesFormChange(Species.ALCREMIE, "ruby-cream", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)),
new SpeciesFormChange(Species.ALCREMIE, 'matcha-cream', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)), new SpeciesFormChange(Species.ALCREMIE, "matcha-cream", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)),
new SpeciesFormChange(Species.ALCREMIE, 'mint-cream', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)), new SpeciesFormChange(Species.ALCREMIE, "mint-cream", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)),
new SpeciesFormChange(Species.ALCREMIE, 'lemon-cream', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)), new SpeciesFormChange(Species.ALCREMIE, "lemon-cream", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)),
new SpeciesFormChange(Species.ALCREMIE, 'salted-cream', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)), new SpeciesFormChange(Species.ALCREMIE, "salted-cream", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)),
new SpeciesFormChange(Species.ALCREMIE, 'ruby-swirl', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)), new SpeciesFormChange(Species.ALCREMIE, "ruby-swirl", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)),
new SpeciesFormChange(Species.ALCREMIE, 'caramel-swirl', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)), new SpeciesFormChange(Species.ALCREMIE, "caramel-swirl", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)),
new SpeciesFormChange(Species.ALCREMIE, 'rainbow-swirl', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.ALCREMIE, "rainbow-swirl", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.MORPEKO]: [ [Species.MORPEKO]: [
new SpeciesFormChange(Species.MORPEKO, 'full-belly', 'hangry', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.MORPEKO, "full-belly", "hangry", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MORPEKO, 'hangry', 'full-belly', new SpeciesFormChangeManualTrigger(), true) new SpeciesFormChange(Species.MORPEKO, "hangry", "full-belly", new SpeciesFormChangeManualTrigger(), true)
], ],
[Species.COPPERAJAH]: [ [Species.COPPERAJAH]: [
new SpeciesFormChange(Species.COPPERAJAH, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.COPPERAJAH, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.DURALUDON]: [ [Species.DURALUDON]: [
new SpeciesFormChange(Species.DURALUDON, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.DURALUDON, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.ZACIAN]: [ [Species.ZACIAN]: [
new SpeciesFormChange(Species.ZACIAN, 'hero', 'crowned', new SpeciesFormChangeItemTrigger(FormChangeItem.RUSTED_SWORD)) new SpeciesFormChange(Species.ZACIAN, "hero", "crowned", new SpeciesFormChangeItemTrigger(FormChangeItem.RUSTED_SWORD))
], ],
[Species.ZAMAZENTA]: [ [Species.ZAMAZENTA]: [
new SpeciesFormChange(Species.ZAMAZENTA, 'hero', 'crowned', new SpeciesFormChangeItemTrigger(FormChangeItem.RUSTED_SHIELD)) new SpeciesFormChange(Species.ZAMAZENTA, "hero", "crowned", new SpeciesFormChangeItemTrigger(FormChangeItem.RUSTED_SHIELD))
], ],
[Species.ETERNATUS]: [ [Species.ETERNATUS]: [
new SpeciesFormChange(Species.ETERNATUS, '', SpeciesFormKey.ETERNAMAX, new SpeciesFormChangeManualTrigger()), new SpeciesFormChange(Species.ETERNATUS, "", SpeciesFormKey.ETERNAMAX, new SpeciesFormChangeManualTrigger()),
new SpeciesFormChange(Species.ETERNATUS, '', SpeciesFormKey.ETERNAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.ETERNATUS, "", SpeciesFormKey.ETERNAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.URSHIFU]: [ [Species.URSHIFU]: [
new SpeciesFormChange(Species.URSHIFU, 'single-strike', SpeciesFormKey.GIGANTAMAX_SINGLE, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)), new SpeciesFormChange(Species.URSHIFU, "single-strike", SpeciesFormKey.GIGANTAMAX_SINGLE, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)),
new SpeciesFormChange(Species.URSHIFU, 'rapid-strike', SpeciesFormKey.GIGANTAMAX_RAPID, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) new SpeciesFormChange(Species.URSHIFU, "rapid-strike", SpeciesFormKey.GIGANTAMAX_RAPID, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
], ],
[Species.CALYREX]: [ [Species.CALYREX]: [
new SpeciesFormChange(Species.CALYREX, '', 'ice', new SpeciesFormChangeItemTrigger(FormChangeItem.ICY_REINS_OF_UNITY)), new SpeciesFormChange(Species.CALYREX, "", "ice", new SpeciesFormChangeItemTrigger(FormChangeItem.ICY_REINS_OF_UNITY)),
new SpeciesFormChange(Species.CALYREX, '', 'shadow', new SpeciesFormChangeItemTrigger(FormChangeItem.SHADOW_REINS_OF_UNITY)) new SpeciesFormChange(Species.CALYREX, "", "shadow", new SpeciesFormChangeItemTrigger(FormChangeItem.SHADOW_REINS_OF_UNITY))
], ],
[Species.ENAMORUS]: [ [Species.ENAMORUS]: [
new SpeciesFormChange(Species.ENAMORUS, SpeciesFormKey.INCARNATE, SpeciesFormKey.THERIAN, new SpeciesFormChangeItemTrigger(FormChangeItem.REVEAL_GLASS)) new SpeciesFormChange(Species.ENAMORUS, SpeciesFormKey.INCARNATE, SpeciesFormKey.THERIAN, new SpeciesFormChangeItemTrigger(FormChangeItem.REVEAL_GLASS))
], ],
[Species.OGERPON]: [ [Species.OGERPON]: [
new SpeciesFormChange(Species.OGERPON, 'teal-mask', 'wellspring-mask', new SpeciesFormChangeItemTrigger(FormChangeItem.WELLSPRING_MASK)), new SpeciesFormChange(Species.OGERPON, "teal-mask", "wellspring-mask", new SpeciesFormChangeItemTrigger(FormChangeItem.WELLSPRING_MASK)),
new SpeciesFormChange(Species.OGERPON, 'teal-mask', 'hearthflame-mask', new SpeciesFormChangeItemTrigger(FormChangeItem.HEARTHFLAME_MASK)), new SpeciesFormChange(Species.OGERPON, "teal-mask", "hearthflame-mask", new SpeciesFormChangeItemTrigger(FormChangeItem.HEARTHFLAME_MASK)),
new SpeciesFormChange(Species.OGERPON, 'teal-mask', 'cornerstone-mask', new SpeciesFormChangeItemTrigger(FormChangeItem.CORNERSTONE_MASK)), new SpeciesFormChange(Species.OGERPON, "teal-mask", "cornerstone-mask", new SpeciesFormChangeItemTrigger(FormChangeItem.CORNERSTONE_MASK)),
new SpeciesFormChange(Species.OGERPON, 'teal-mask', 'teal-mask-tera', new SpeciesFormChangeManualTrigger(), true), //When holding a Grass Tera Shard new SpeciesFormChange(Species.OGERPON, "teal-mask", "teal-mask-tera", new SpeciesFormChangeManualTrigger(), true), //When holding a Grass Tera Shard
new SpeciesFormChange(Species.OGERPON, 'teal-mask-tera', 'teal-mask', new SpeciesFormChangeManualTrigger(), true), //When no longer holding a Grass Tera Shard new SpeciesFormChange(Species.OGERPON, "teal-mask-tera", "teal-mask", new SpeciesFormChangeManualTrigger(), true), //When no longer holding a Grass Tera Shard
new SpeciesFormChange(Species.OGERPON, 'wellspring-mask', 'wellspring-mask-tera', new SpeciesFormChangeManualTrigger(), true), //When holding a Water Tera Shard new SpeciesFormChange(Species.OGERPON, "wellspring-mask", "wellspring-mask-tera", new SpeciesFormChangeManualTrigger(), true), //When holding a Water Tera Shard
new SpeciesFormChange(Species.OGERPON, 'wellspring-mask-tera', 'wellspring-mask', new SpeciesFormChangeManualTrigger(), true), //When no longer holding a Water Tera Shard new SpeciesFormChange(Species.OGERPON, "wellspring-mask-tera", "wellspring-mask", new SpeciesFormChangeManualTrigger(), true), //When no longer holding a Water Tera Shard
new SpeciesFormChange(Species.OGERPON, 'hearthflame-mask', 'hearthflame-mask-tera', new SpeciesFormChangeManualTrigger(), true), //When holding a Fire Tera Shard new SpeciesFormChange(Species.OGERPON, "hearthflame-mask", "hearthflame-mask-tera", new SpeciesFormChangeManualTrigger(), true), //When holding a Fire Tera Shard
new SpeciesFormChange(Species.OGERPON, 'hearthflame-mask-tera', 'hearthflame-mask', new SpeciesFormChangeManualTrigger(), true), //When no longer holding a Fire Tera Shard new SpeciesFormChange(Species.OGERPON, "hearthflame-mask-tera", "hearthflame-mask", new SpeciesFormChangeManualTrigger(), true), //When no longer holding a Fire Tera Shard
new SpeciesFormChange(Species.OGERPON, 'cornerstone-mask', 'cornerstone-mask-tera', new SpeciesFormChangeManualTrigger(), true), //When holding a Rock Tera Shard new SpeciesFormChange(Species.OGERPON, "cornerstone-mask", "cornerstone-mask-tera", new SpeciesFormChangeManualTrigger(), true), //When holding a Rock Tera Shard
new SpeciesFormChange(Species.OGERPON, 'cornerstone-mask-tera', 'cornerstone-mask', new SpeciesFormChangeManualTrigger(), true) //When no longer holding a Rock Tera Shard new SpeciesFormChange(Species.OGERPON, "cornerstone-mask-tera", "cornerstone-mask", new SpeciesFormChangeManualTrigger(), true) //When no longer holding a Rock Tera Shard
], ],
[Species.TERAPAGOS]: [ [Species.TERAPAGOS]: [
new SpeciesFormChange(Species.TERAPAGOS, '', 'terastal', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.TERAPAGOS, "", "terastal", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.TERAPAGOS, 'terastal', 'stellar', new SpeciesFormChangeManualTrigger(), true), //When holding a Stellar Tera Shard new SpeciesFormChange(Species.TERAPAGOS, "terastal", "stellar", new SpeciesFormChangeManualTrigger(), true), //When holding a Stellar Tera Shard
new SpeciesFormChange(Species.TERAPAGOS, 'stellar', 'terastal', new SpeciesFormChangeManualTrigger(), true) //When no longer holding a Stellar Tera Shard new SpeciesFormChange(Species.TERAPAGOS, "stellar", "terastal", new SpeciesFormChangeManualTrigger(), true) //When no longer holding a Stellar Tera Shard
], ],
[Species.GALAR_DARMANITAN]: [ [Species.GALAR_DARMANITAN]: [
new SpeciesFormChange(Species.GALAR_DARMANITAN, '', 'zen', new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.GALAR_DARMANITAN, "", "zen", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.GALAR_DARMANITAN, 'zen', '', new SpeciesFormChangeManualTrigger(), true) new SpeciesFormChange(Species.GALAR_DARMANITAN, "zen", "", new SpeciesFormChangeManualTrigger(), true)
] ]
}; };
@ -794,12 +808,13 @@ export const pokemonFormChanges: PokemonFormChanges = {
const formChangeKeys = Object.keys(pokemonFormChanges); const formChangeKeys = Object.keys(pokemonFormChanges);
formChangeKeys.forEach(pk => { formChangeKeys.forEach(pk => {
const formChanges = pokemonFormChanges[pk]; const formChanges = pokemonFormChanges[pk];
let newFormChanges: SpeciesFormChange[] = []; const newFormChanges: SpeciesFormChange[] = [];
for (let fc of formChanges) { for (const fc of formChanges) {
const itemTrigger = fc.findTrigger(SpeciesFormChangeItemTrigger) as SpeciesFormChangeItemTrigger; const itemTrigger = fc.findTrigger(SpeciesFormChangeItemTrigger) as SpeciesFormChangeItemTrigger;
if (itemTrigger && !formChanges.find(c => fc.formKey === c.preFormKey && fc.preFormKey === c.formKey)) if (itemTrigger && !formChanges.find(c => fc.formKey === c.preFormKey && fc.preFormKey === c.formKey)) {
newFormChanges.push(new SpeciesFormChange(fc.speciesId, fc.formKey, fc.preFormKey, new SpeciesFormChangeItemTrigger(itemTrigger.item, false))); newFormChanges.push(new SpeciesFormChange(fc.speciesId, fc.formKey, fc.preFormKey, new SpeciesFormChangeItemTrigger(itemTrigger.item, false)));
} }
}
formChanges.push(...newFormChanges); formChanges.push(...newFormChanges);
}); });
} }

View File

@ -1055,13 +1055,13 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
], ],
[Species.ABRA]: [ [Species.ABRA]: [
[ 1, Moves.TELEPORT ], [ 1, Moves.TELEPORT ],
[ 1, Moves.CONFUSION ], //Custom
], ],
[Species.KADABRA]: [ [Species.KADABRA]: [
[ 0, Moves.CONFUSION ], [ 0, Moves.PSYBEAM ], //Custom
[ 1, Moves.DISABLE ], [ 1, Moves.DISABLE ],
[ 1, Moves.TELEPORT ], [ 1, Moves.TELEPORT ],
[ 1, Moves.KINESIS ], [ 1, Moves.KINESIS ],
[ 5, Moves.PSYBEAM ],
[ 10, Moves.REFLECT ], [ 10, Moves.REFLECT ],
[ 15, Moves.ALLY_SWITCH ], [ 15, Moves.ALLY_SWITCH ],
[ 20, Moves.PSYCHO_CUT ], [ 20, Moves.PSYCHO_CUT ],
@ -1542,6 +1542,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.GASTLY]: [ [Species.GASTLY]: [
[ 1, Moves.CONFUSE_RAY ], [ 1, Moves.CONFUSE_RAY ],
[ 1, Moves.LICK ], [ 1, Moves.LICK ],
[ 1, Moves.ACID ], //Custom
[ 4, Moves.HYPNOSIS ], [ 4, Moves.HYPNOSIS ],
[ 8, Moves.MEAN_LOOK ], [ 8, Moves.MEAN_LOOK ],
[ 12, Moves.PAYBACK ], [ 12, Moves.PAYBACK ],
@ -1841,6 +1842,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.LICKITUNG]: [ [Species.LICKITUNG]: [
[ 1, Moves.DEFENSE_CURL ], [ 1, Moves.DEFENSE_CURL ],
[ 1, Moves.LICK ], [ 1, Moves.LICK ],
[ 1, Moves.TACKLE ], //Custom
[ 6, Moves.REST ], [ 6, Moves.REST ],
[ 12, Moves.SUPERSONIC ], [ 12, Moves.SUPERSONIC ],
[ 18, Moves.WRAP ], [ 18, Moves.WRAP ],
@ -3549,6 +3551,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.DUNSPARCE]: [ [Species.DUNSPARCE]: [
[ 1, Moves.DEFENSE_CURL ], [ 1, Moves.DEFENSE_CURL ],
[ 1, Moves.FLAIL ], [ 1, Moves.FLAIL ],
[ 1, Moves.TACKLE ], //Custom
[ 4, Moves.MUD_SLAP ], [ 4, Moves.MUD_SLAP ],
[ 8, Moves.ROLLOUT ], [ 8, Moves.ROLLOUT ],
[ 12, Moves.GLARE ], [ 12, Moves.GLARE ],
@ -3769,7 +3772,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.SLUGMA]: [ [Species.SLUGMA]: [
[ 1, Moves.SMOG ], [ 1, Moves.SMOG ],
[ 1, Moves.YAWN ], [ 1, Moves.YAWN ],
[ 6, Moves.EMBER ], [ 5, Moves.EMBER ], //Custom, Moved from Level 6 to 5
[ 8, Moves.ROCK_THROW ], [ 8, Moves.ROCK_THROW ],
[ 13, Moves.HARDEN ], [ 13, Moves.HARDEN ],
[ 20, Moves.CLEAR_SMOG ], [ 20, Moves.CLEAR_SMOG ],
@ -5543,6 +5546,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
], ],
[Species.WAILMER]: [ [Species.WAILMER]: [
[ 1, Moves.SPLASH ], [ 1, Moves.SPLASH ],
[ 1, Moves.TACKLE ], //Custom
[ 3, Moves.GROWL ], [ 3, Moves.GROWL ],
[ 6, Moves.ASTONISH ], [ 6, Moves.ASTONISH ],
[ 12, Moves.WATER_GUN ], [ 12, Moves.WATER_GUN ],
@ -5635,7 +5639,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
], ],
[Species.SPOINK]: [ [Species.SPOINK]: [
[ 1, Moves.SPLASH ], [ 1, Moves.SPLASH ],
[ 7, Moves.CONFUSION ], [ 5, Moves.CONFUSION ], //Custom, Moved from Level 7 to 5
[ 10, Moves.GROWL ], [ 10, Moves.GROWL ],
[ 14, Moves.PSYBEAM ], [ 14, Moves.PSYBEAM ],
[ 18, Moves.PSYCH_UP ], [ 18, Moves.PSYCH_UP ],
@ -6144,6 +6148,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
], ],
[Species.SHUPPET]: [ [Species.SHUPPET]: [
[ 1, Moves.ASTONISH ], [ 1, Moves.ASTONISH ],
[ 1, Moves.PURSUIT ], //Custom
[ 4, Moves.SCREECH ], [ 4, Moves.SCREECH ],
[ 7, Moves.NIGHT_SHADE ], [ 7, Moves.NIGHT_SHADE ],
[ 10, Moves.SPITE ], [ 10, Moves.SPITE ],
@ -6175,6 +6180,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.DUSKULL]: [ [Species.DUSKULL]: [
[ 1, Moves.ASTONISH ], [ 1, Moves.ASTONISH ],
[ 1, Moves.LEER ], [ 1, Moves.LEER ],
[ 1, Moves.PURSUIT ], //Custom
[ 4, Moves.DISABLE ], [ 4, Moves.DISABLE ],
[ 8, Moves.SHADOW_SNEAK ], [ 8, Moves.SHADOW_SNEAK ],
[ 12, Moves.CONFUSE_RAY ], [ 12, Moves.CONFUSE_RAY ],
@ -7082,6 +7088,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
], ],
[Species.BURMY]: [ [Species.BURMY]: [
[ 1, Moves.PROTECT ], [ 1, Moves.PROTECT ],
[ 1, Moves.STRUGGLE_BUG ], //Custom
[ 10, Moves.TACKLE ], [ 10, Moves.TACKLE ],
[ 15, Moves.BUG_BITE ], [ 15, Moves.BUG_BITE ],
[ 20, Moves.STRING_SHOT ], [ 20, Moves.STRING_SHOT ],
@ -7417,6 +7424,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
], ],
[Species.CHINGLING]: [ [Species.CHINGLING]: [
[ 1, Moves.WRAP ], [ 1, Moves.WRAP ],
[ 1, Moves.PSYWAVE ], //Custom
[ 4, Moves.GROWL ], [ 4, Moves.GROWL ],
[ 7, Moves.ASTONISH ], [ 7, Moves.ASTONISH ],
[ 10, Moves.CONFUSION ], [ 10, Moves.CONFUSION ],
@ -7500,6 +7508,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.BONSLY]: [ [Species.BONSLY]: [
[ 1, Moves.FAKE_TEARS ], [ 1, Moves.FAKE_TEARS ],
[ 1, Moves.COPYCAT ], [ 1, Moves.COPYCAT ],
[ 1, Moves.TACKLE ], //Custom
[ 4, Moves.FLAIL ], [ 4, Moves.FLAIL ],
[ 8, Moves.ROCK_THROW ], [ 8, Moves.ROCK_THROW ],
[ 12, Moves.BLOCK ], [ 12, Moves.BLOCK ],
@ -7801,6 +7810,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.CARNIVINE]: [ [Species.CARNIVINE]: [
[ 1, Moves.BIND ], [ 1, Moves.BIND ],
[ 1, Moves.GROWTH ], [ 1, Moves.GROWTH ],
[ 1, Moves.LEAFAGE ], //Custom
[ 7, Moves.BITE ], [ 7, Moves.BITE ],
[ 11, Moves.VINE_WHIP ], [ 11, Moves.VINE_WHIP ],
[ 17, Moves.SWEET_SCENT ], [ 17, Moves.SWEET_SCENT ],
@ -8406,6 +8416,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.GIRATINA]: [ [Species.GIRATINA]: [
[ 1, Moves.SHADOW_SNEAK ], [ 1, Moves.SHADOW_SNEAK ],
[ 1, Moves.DEFOG ], [ 1, Moves.DEFOG ],
[ 1, Moves.TWISTER ], //Custom
[ 7, Moves.DRAGON_BREATH ], [ 7, Moves.DRAGON_BREATH ],
[ 14, Moves.ANCIENT_POWER ], [ 14, Moves.ANCIENT_POWER ],
[ 21, Moves.HEX ], [ 21, Moves.HEX ],
@ -8467,6 +8478,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.DARKRAI]: [ [Species.DARKRAI]: [
[ 1, Moves.DISABLE ], [ 1, Moves.DISABLE ],
[ 1, Moves.OMINOUS_WIND ], [ 1, Moves.OMINOUS_WIND ],
[ 1, Moves.PURSUIT ], //Custom
[ 11, Moves.QUICK_ATTACK ], [ 11, Moves.QUICK_ATTACK ],
[ 20, Moves.HYPNOSIS ], [ 20, Moves.HYPNOSIS ],
[ 29, Moves.SUCKER_PUNCH ], [ 29, Moves.SUCKER_PUNCH ],
@ -9220,10 +9232,11 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 70, Moves.HYDRO_PUMP ], [ 70, Moves.HYDRO_PUMP ],
], ],
[Species.THROH]: [ [Species.THROH]: [
[ 1, Moves.BIND ], [ 1, Moves.KARATE_CHOP ], //Custom
[ 1, Moves.LEER ], [ 1, Moves.LEER ],
[ 1, Moves.BIDE ], [ 1, Moves.BIDE ],
[ 1, Moves.MAT_BLOCK ], [ 1, Moves.MAT_BLOCK ],
[ 1, Moves.BIND ],
[ 5, Moves.FOCUS_ENERGY ], [ 5, Moves.FOCUS_ENERGY ],
[ 10, Moves.CIRCLE_THROW ], [ 10, Moves.CIRCLE_THROW ],
[ 15, Moves.WIDE_GUARD ], [ 15, Moves.WIDE_GUARD ],
@ -10004,6 +10017,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.VANILLITE]: [ [Species.VANILLITE]: [
[ 1, Moves.HARDEN ], [ 1, Moves.HARDEN ],
[ 1, Moves.ASTONISH ], [ 1, Moves.ASTONISH ],
[ 1, Moves.POWDER_SNOW ], //Custom
[ 4, Moves.TAUNT ], [ 4, Moves.TAUNT ],
[ 8, Moves.MIST ], [ 8, Moves.MIST ],
[ 12, Moves.ICY_WIND ], [ 12, Moves.ICY_WIND ],
@ -12206,6 +12220,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.PUMPKABOO]: [ [Species.PUMPKABOO]: [
[ 1, Moves.ASTONISH ], [ 1, Moves.ASTONISH ],
[ 1, Moves.TRICK_OR_TREAT ], [ 1, Moves.TRICK_OR_TREAT ],
[ 1, Moves.LEAFAGE ], //Custom
[ 4, Moves.SHADOW_SNEAK ], [ 4, Moves.SHADOW_SNEAK ],
[ 8, Moves.CONFUSE_RAY ], [ 8, Moves.CONFUSE_RAY ],
[ 12, Moves.RAZOR_LEAF ], [ 12, Moves.RAZOR_LEAF ],
@ -13074,6 +13089,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
], ],
[Species.BOUNSWEET]: [ [Species.BOUNSWEET]: [
[ 1, Moves.SPLASH ], [ 1, Moves.SPLASH ],
[ 1, Moves.LEAFAGE ], //Custom
[ 4, Moves.PLAY_NICE ], [ 4, Moves.PLAY_NICE ],
[ 8, Moves.RAPID_SPIN ], [ 8, Moves.RAPID_SPIN ],
[ 12, Moves.RAZOR_LEAF ], [ 12, Moves.RAZOR_LEAF ],
@ -13222,6 +13238,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 68, Moves.SANDSTORM ], [ 68, Moves.SANDSTORM ],
], ],
[Species.PYUKUMUKU]: [ [Species.PYUKUMUKU]: [
[ 1, Moves.COUNTER ], //Custom, Moved from Level 20 to 1
[ 1, Moves.HARDEN ], [ 1, Moves.HARDEN ],
[ 1, Moves.BATON_PASS ], [ 1, Moves.BATON_PASS ],
[ 1, Moves.BIDE ], [ 1, Moves.BIDE ],
@ -13230,7 +13247,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 5, Moves.HELPING_HAND ], [ 5, Moves.HELPING_HAND ],
[ 10, Moves.TAUNT ], [ 10, Moves.TAUNT ],
[ 15, Moves.SAFEGUARD ], [ 15, Moves.SAFEGUARD ],
[ 20, Moves.COUNTER ], [ 20, Moves.MIRROR_COAT ], //Custom
[ 25, Moves.PURIFY ], [ 25, Moves.PURIFY ],
[ 30, Moves.CURSE ], [ 30, Moves.CURSE ],
[ 35, Moves.GASTRO_ACID ], [ 35, Moves.GASTRO_ACID ],
@ -13546,6 +13563,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.COSMOG]: [ [Species.COSMOG]: [
[ 1, Moves.TELEPORT ], [ 1, Moves.TELEPORT ],
[ 1, Moves.SPLASH ], [ 1, Moves.SPLASH ],
[ 1, Moves.STORED_POWER ], //Custom
], ],
[Species.COSMOEM]: [ [Species.COSMOEM]: [
[ 0, Moves.COSMIC_POWER ], [ 0, Moves.COSMIC_POWER ],
@ -13742,6 +13760,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.MAGEARNA]: [ [Species.MAGEARNA]: [
[ 1, Moves.HELPING_HAND ], [ 1, Moves.HELPING_HAND ],
[ 1, Moves.GYRO_BALL ], [ 1, Moves.GYRO_BALL ],
[ 1, Moves.FAIRY_WIND ], //Custom
[ 6, Moves.DEFENSE_CURL ], [ 6, Moves.DEFENSE_CURL ],
[ 12, Moves.ROLLOUT ], [ 12, Moves.ROLLOUT ],
[ 18, Moves.IRON_DEFENSE ], [ 18, Moves.IRON_DEFENSE ],
@ -14310,6 +14329,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.APPLIN]: [ [Species.APPLIN]: [
[ 1, Moves.WITHDRAW ], [ 1, Moves.WITHDRAW ],
[ 1, Moves.ASTONISH ], [ 1, Moves.ASTONISH ],
[ 1, Moves.LEAFAGE ], //Custom
], ],
[Species.FLAPPLE]: [ [Species.FLAPPLE]: [
[ 0, Moves.WING_ATTACK ], [ 0, Moves.WING_ATTACK ],
@ -14352,6 +14372,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.SILICOBRA]: [ [Species.SILICOBRA]: [
[ 1, Moves.SAND_ATTACK ], [ 1, Moves.SAND_ATTACK ],
[ 1, Moves.WRAP ], [ 1, Moves.WRAP ],
[ 1, Moves.MUD_SLAP ], //Custom
[ 5, Moves.MINIMIZE ], [ 5, Moves.MINIMIZE ],
[ 10, Moves.BRUTAL_SWING ], [ 10, Moves.BRUTAL_SWING ],
[ 15, Moves.BULLDOZE ], [ 15, Moves.BULLDOZE ],
@ -14512,6 +14533,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.SINISTEA]: [ [Species.SINISTEA]: [
[ 1, Moves.WITHDRAW ], [ 1, Moves.WITHDRAW ],
[ 1, Moves.ASTONISH ], [ 1, Moves.ASTONISH ],
[ 1, Moves.ABSORB ], //Custom
[ 6, Moves.AROMATIC_MIST ], [ 6, Moves.AROMATIC_MIST ],
[ 12, Moves.MEGA_DRAIN ], [ 12, Moves.MEGA_DRAIN ],
[ 24, Moves.SUCKER_PUNCH ], [ 24, Moves.SUCKER_PUNCH ],
@ -16832,6 +16854,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
], ],
[Species.IRON_BUNDLE]: [ [Species.IRON_BUNDLE]: [
[ 1, Moves.PRESENT ], [ 1, Moves.PRESENT ],
[ 1, Moves.WATER_GUN ], //Custom
[ 7, Moves.POWDER_SNOW ], [ 7, Moves.POWDER_SNOW ],
[ 14, Moves.WHIRLPOOL ], [ 14, Moves.WHIRLPOOL ],
[ 21, Moves.TAKE_DOWN ], [ 21, Moves.TAKE_DOWN ],
@ -17203,7 +17226,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 1, Moves.STUN_SPORE ], [ 1, Moves.STUN_SPORE ],
[ 1, Moves.WITHDRAW ], [ 1, Moves.WITHDRAW ],
[ 1, Moves.ASTONISH ], [ 1, Moves.ASTONISH ],
[ 6, Moves.ABSORB ], [ 5, Moves.ABSORB ], //Custom, Moved from Level 6 to 5
[ 12, Moves.LIFE_DEW ], [ 12, Moves.LIFE_DEW ],
[ 18, Moves.FOUL_PLAY ], [ 18, Moves.FOUL_PLAY ],
[ 24, Moves.MEGA_DRAIN ], [ 24, Moves.MEGA_DRAIN ],

View File

@ -1,21 +1,21 @@
import { Abilities } from "./enums/abilities"; import { Abilities } from "./enums/abilities";
import BattleScene, { AnySound } from '../battle-scene'; import BattleScene, { AnySound } from "../battle-scene";
import { Variant, variantColorCache } from './variant'; import { Variant, variantColorCache } from "./variant";
import { variantData } from './variant'; import { variantData } from "./variant";
import { GrowthRate } from './exp'; import { GrowthRate } from "./exp";
import { SpeciesWildEvolutionDelay, pokemonEvolutions, pokemonPrevolutions } from './pokemon-evolutions'; import { SpeciesWildEvolutionDelay, pokemonEvolutions, pokemonPrevolutions } from "./pokemon-evolutions";
import { Species } from './enums/species'; import { Species } from "./enums/species";
import { Type } from './type'; import { Type } from "./type";
import { LevelMoves, pokemonFormLevelMoves, pokemonFormLevelMoves as pokemonSpeciesFormLevelMoves, pokemonSpeciesLevelMoves } from './pokemon-level-moves'; import { LevelMoves, pokemonFormLevelMoves, pokemonFormLevelMoves as pokemonSpeciesFormLevelMoves, pokemonSpeciesLevelMoves } from "./pokemon-level-moves";
import { uncatchableSpecies } from './biomes'; import { uncatchableSpecies } from "./biomes";
import * as Utils from '../utils'; import * as Utils from "../utils";
import { StarterMoveset } from '../system/game-data'; import { StarterMoveset } from "../system/game-data";
import { speciesEggMoves } from './egg-moves'; import { speciesEggMoves } from "./egg-moves";
import { PartyMemberStrength } from "./enums/party-member-strength"; import { PartyMemberStrength } from "./enums/party-member-strength";
import { GameMode } from '../game-mode'; import { GameMode } from "../game-mode";
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities"; import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities";
import { VariantSet } from './variant'; import { VariantSet } from "./variant";
import i18next, { Localizable } from '../plugins/i18n'; import i18next, { Localizable } from "../plugins/i18n";
import { Stat } from "./pokemon-stat"; import { Stat } from "./pokemon-stat";
export enum Region { export enum Region {
@ -27,17 +27,19 @@ export enum Region {
} }
export function getPokemonSpecies(species: Species): PokemonSpecies { export function getPokemonSpecies(species: Species): PokemonSpecies {
if (species >= 2000) if (species >= 2000) {
return allSpecies.find(s => s.speciesId === species); return allSpecies.find(s => s.speciesId === species);
}
return allSpecies[species - 1]; return allSpecies[species - 1];
} }
export function getPokemonSpeciesForm(species: Species, formIndex: integer): PokemonSpeciesForm { export function getPokemonSpeciesForm(species: Species, formIndex: integer): PokemonSpeciesForm {
let retSpecies: PokemonSpecies = species >= 2000 const retSpecies: PokemonSpecies = species >= 2000
? allSpecies.find(s => s.speciesId === species) ? allSpecies.find(s => s.speciesId === species)
: allSpecies[species - 1]; : allSpecies[species - 1];
if (formIndex < retSpecies.forms?.length) if (formIndex < retSpecies.forms?.length) {
return retSpecies.forms[formIndex]; return retSpecies.forms[formIndex];
}
return retSpecies; return retSpecies;
} }
@ -46,26 +48,30 @@ export function getFusedSpeciesName(speciesAName: string, speciesBName: string):
const fragBPattern = /([a-z]{2}.*?[aeiou(?:y$)\-\'])(.*?)$/i; const fragBPattern = /([a-z]{2}.*?[aeiou(?:y$)\-\'])(.*?)$/i;
const [ speciesAPrefixMatch, speciesBPrefixMatch ] = [ speciesAName, speciesBName ].map(n => /^(?:[^ ]+) /.exec(n)); const [ speciesAPrefixMatch, speciesBPrefixMatch ] = [ speciesAName, speciesBName ].map(n => /^(?:[^ ]+) /.exec(n));
const [ speciesAPrefix, speciesBPrefix ] = [ speciesAPrefixMatch, speciesBPrefixMatch ].map(m => m ? m[0] : ''); const [ speciesAPrefix, speciesBPrefix ] = [ speciesAPrefixMatch, speciesBPrefixMatch ].map(m => m ? m[0] : "");
if (speciesAPrefix) if (speciesAPrefix) {
speciesAName = speciesAName.slice(speciesAPrefix.length); speciesAName = speciesAName.slice(speciesAPrefix.length);
if (speciesBPrefix) }
if (speciesBPrefix) {
speciesBName = speciesBName.slice(speciesBPrefix.length); speciesBName = speciesBName.slice(speciesBPrefix.length);
}
const [ speciesASuffixMatch, speciesBSuffixMatch ] = [ speciesAName, speciesBName ].map(n => / (?:[^ ]+)$/.exec(n)); const [ speciesASuffixMatch, speciesBSuffixMatch ] = [ speciesAName, speciesBName ].map(n => / (?:[^ ]+)$/.exec(n));
const [ speciesASuffix, speciesBSuffix ] = [ speciesASuffixMatch, speciesBSuffixMatch ].map(m => m ? m[0] : ''); const [ speciesASuffix, speciesBSuffix ] = [ speciesASuffixMatch, speciesBSuffixMatch ].map(m => m ? m[0] : "");
if (speciesASuffix) if (speciesASuffix) {
speciesAName = speciesAName.slice(0, -speciesASuffix.length); speciesAName = speciesAName.slice(0, -speciesASuffix.length);
if (speciesBSuffix) }
if (speciesBSuffix) {
speciesBName = speciesBName.slice(0, -speciesBSuffix.length); speciesBName = speciesBName.slice(0, -speciesBSuffix.length);
}
const splitNameA = speciesAName.split(/ /g); const splitNameA = speciesAName.split(/ /g);
const splitNameB = speciesBName.split(/ /g); const splitNameB = speciesBName.split(/ /g);
let fragAMatch = fragAPattern.exec(speciesAName); const fragAMatch = fragAPattern.exec(speciesAName);
let fragBMatch = fragBPattern.exec(speciesBName); const fragBMatch = fragBPattern.exec(speciesBName);
let fragA: string; let fragA: string;
let fragB: string; let fragB: string;
@ -78,23 +84,27 @@ export function getFusedSpeciesName(speciesAName: string, speciesBName: string):
if (fragBMatch) { if (fragBMatch) {
const lastCharA = fragA.slice(fragA.length - 1); const lastCharA = fragA.slice(fragA.length - 1);
const prevCharB = fragBMatch[1].slice(fragBMatch.length - 1); const prevCharB = fragBMatch[1].slice(fragBMatch.length - 1);
fragB = (/[\-']/.test(prevCharB) ? prevCharB : '') + fragBMatch[2] || prevCharB; fragB = (/[\-']/.test(prevCharB) ? prevCharB : "") + fragBMatch[2] || prevCharB;
if (lastCharA === fragB[0]) { if (lastCharA === fragB[0]) {
if (/[aiu]/.test(lastCharA)) if (/[aiu]/.test(lastCharA)) {
fragB = fragB.slice(1); fragB = fragB.slice(1);
else { } else {
const newCharMatch = new RegExp(`[^${lastCharA}]`).exec(fragB); const newCharMatch = new RegExp(`[^${lastCharA}]`).exec(fragB);
if (newCharMatch?.index > 0) if (newCharMatch?.index > 0) {
fragB = fragB.slice(newCharMatch.index); fragB = fragB.slice(newCharMatch.index);
} }
} }
} else }
} else {
fragB = speciesBName; fragB = speciesBName;
} else }
} else {
fragB = splitNameB[splitNameB.length - 1]; fragB = splitNameB[splitNameB.length - 1];
}
if (splitNameA.length > 1) if (splitNameA.length > 1) {
fragA = `${splitNameA.slice(0, splitNameA.length - 1).join(' ')} ${fragA}`; fragA = `${splitNameA.slice(0, splitNameA.length - 1).join(" ")} ${fragA}`;
}
fragB = `${fragB.slice(0, 1).toLowerCase()}${fragB.slice(1)}`; fragB = `${fragB.slice(0, 1).toLowerCase()}${fragB.slice(1)}`;
@ -141,8 +151,9 @@ export abstract class PokemonSpeciesForm {
getRootSpeciesId(forStarter: boolean = false): Species { getRootSpeciesId(forStarter: boolean = false): Species {
let ret = this.speciesId; let ret = this.speciesId;
while (pokemonPrevolutions.hasOwnProperty(ret) && (!forStarter || !speciesStarters.hasOwnProperty(ret))) while (pokemonPrevolutions.hasOwnProperty(ret) && (!forStarter || !speciesStarters.hasOwnProperty(ret))) {
ret = pokemonPrevolutions[ret]; ret = pokemonPrevolutions[ret];
}
return ret; return ret;
} }
@ -159,8 +170,9 @@ export abstract class PokemonSpeciesForm {
} }
getLevelMoves(): LevelMoves { getLevelMoves(): LevelMoves {
if (pokemonSpeciesFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonSpeciesFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex)) if (pokemonSpeciesFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonSpeciesFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex)) {
return pokemonSpeciesFormLevelMoves[this.speciesId][this.formIndex].slice(0); return pokemonSpeciesFormLevelMoves[this.speciesId][this.formIndex].slice(0);
}
return pokemonSpeciesLevelMoves[this.speciesId].slice(0); return pokemonSpeciesLevelMoves[this.speciesId].slice(0);
} }
@ -199,7 +211,7 @@ export abstract class PokemonSpeciesForm {
* @returns The species' base stat amount. * @returns The species' base stat amount.
*/ */
getBaseStat(stat: Stat): integer { getBaseStat(stat: Stat): integer {
return this.baseStats[stat] return this.baseStats[stat];
} }
getBaseExp(): integer { getBaseExp(): integer {
@ -218,25 +230,25 @@ export abstract class PokemonSpeciesForm {
} }
getSpriteAtlasPath(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string { getSpriteAtlasPath(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string {
const spriteId = this.getSpriteId(female, formIndex, shiny, variant).replace(/\_{2}/g, '/'); const spriteId = this.getSpriteId(female, formIndex, shiny, variant).replace(/\_{2}/g, "/");
return `${/_[1-3]$/.test(spriteId) ? 'variant/' : ''}${spriteId}`; return `${/_[1-3]$/.test(spriteId) ? "variant/" : ""}${spriteId}`;
} }
getSpriteId(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer, back?: boolean): string { getSpriteId(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer, back?: boolean): string {
if (formIndex === undefined || this instanceof PokemonForm) if (formIndex === undefined || this instanceof PokemonForm) {
formIndex = this.formIndex; formIndex = this.formIndex;
}
const formSpriteKey = this.getFormSpriteKey(formIndex); const formSpriteKey = this.getFormSpriteKey(formIndex);
const showGenderDiffs = this.genderDiffs && female && ![ SpeciesFormKey.MEGA, SpeciesFormKey.GIGANTAMAX ].find(k => formSpriteKey === k); const showGenderDiffs = this.genderDiffs && female && ![ SpeciesFormKey.MEGA, SpeciesFormKey.GIGANTAMAX ].find(k => formSpriteKey === k);
const baseSpriteKey = `${showGenderDiffs ? 'female__' : ''}${this.speciesId}${formSpriteKey ? `-${formSpriteKey}` : ''}`; const baseSpriteKey = `${showGenderDiffs ? "female__" : ""}${this.speciesId}${formSpriteKey ? `-${formSpriteKey}` : ""}`;
let variantSet: VariantSet;
let config = variantData; let config = variantData;
`${back ? 'back__' : ''}${baseSpriteKey}`.split('__').map(p => config ? config = config[p] : null); `${back ? "back__" : ""}${baseSpriteKey}`.split("__").map(p => config ? config = config[p] : null);
variantSet = config as VariantSet; const variantSet = config as VariantSet;
return `${back ? 'back__' : ''}${shiny && (!variantSet || (!variant && !variantSet[variant || 0])) ? 'shiny__' : ''}${baseSpriteKey}${shiny && variantSet && variantSet[variant || 0] === 2 ? `_${variant + 1}` : ''}`; return `${back ? "back__" : ""}${shiny && (!variantSet || (!variant && !variantSet[variant || 0])) ? "shiny__" : ""}${baseSpriteKey}${shiny && variantSet && variantSet[variant || 0] === 2 ? `_${variant + 1}` : ""}`;
} }
getSpriteKey(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string { getSpriteKey(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string {
@ -247,19 +259,21 @@ export abstract class PokemonSpeciesForm {
getIconAtlasKey(formIndex?: integer, shiny?: boolean, variant?: integer): string { getIconAtlasKey(formIndex?: integer, shiny?: boolean, variant?: integer): string {
const isVariant = shiny && variantData[this.speciesId] && variantData[this.speciesId][variant]; const isVariant = shiny && variantData[this.speciesId] && variantData[this.speciesId][variant];
return `pokemon_icons_${this.generation}${isVariant ? 'v' : ''}`; return `pokemon_icons_${this.generation}${isVariant ? "v" : ""}`;
} }
getIconId(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string { getIconId(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string {
if (formIndex === undefined) if (formIndex === undefined) {
formIndex = this.formIndex; formIndex = this.formIndex;
}
let ret = this.speciesId.toString(); let ret = this.speciesId.toString();
const isVariant = shiny && variantData[this.speciesId] && variantData[this.speciesId][variant]; const isVariant = shiny && variantData[this.speciesId] && variantData[this.speciesId][variant];
if (shiny && !isVariant) if (shiny && !isVariant) {
ret += 's'; ret += "s";
}
switch (this.speciesId) { switch (this.speciesId) {
case Species.HIPPOPOTAS: case Species.HIPPOPOTAS:
@ -267,7 +281,7 @@ export abstract class PokemonSpeciesForm {
case Species.UNFEZANT: case Species.UNFEZANT:
case Species.FRILLISH: case Species.FRILLISH:
case Species.JELLICENT: case Species.JELLICENT:
ret += female ? '-f' : ''; ret += female ? "-f" : "";
break; break;
} }
@ -278,16 +292,18 @@ export abstract class PokemonSpeciesForm {
break; break;
case Species.ZACIAN: case Species.ZACIAN:
case Species.ZAMAZENTA: case Species.ZAMAZENTA:
if (formSpriteKey.startsWith('behemoth')) if (formSpriteKey.startsWith("behemoth")) {
formSpriteKey = 'crowned'; formSpriteKey = "crowned";
}
default: default:
ret += `-${formSpriteKey}`; ret += `-${formSpriteKey}`;
break; break;
} }
} }
if (isVariant) if (isVariant) {
ret += `_${variant + 1}`; ret += `_${variant + 1}`;
}
return ret; return ret;
} }
@ -322,33 +338,33 @@ export abstract class PokemonSpeciesForm {
case SpeciesFormKey.GIGANTAMAX: case SpeciesFormKey.GIGANTAMAX:
case SpeciesFormKey.GIGANTAMAX_SINGLE: case SpeciesFormKey.GIGANTAMAX_SINGLE:
case SpeciesFormKey.GIGANTAMAX_RAPID: case SpeciesFormKey.GIGANTAMAX_RAPID:
case 'white': case "white":
case 'black': case "black":
case 'therian': case "therian":
case 'sky': case "sky":
case 'gorging': case "gorging":
case 'gulping': case "gulping":
case 'no-ice': case "no-ice":
case 'hangry': case "hangry":
case 'crowned': case "crowned":
case 'eternamax': case "eternamax":
case 'four': case "four":
case 'droopy': case "droopy":
case 'stretchy': case "stretchy":
case 'roaming': case "roaming":
case 'complete': case "complete":
case '10': case "10":
case 'super': case "super":
case 'unbound': case "unbound":
case 'pau': case "pau":
case 'pompom': case "pompom":
case 'sensu': case "sensu":
case 'dusk': case "dusk":
case 'midnight': case "midnight":
case 'school': case "school":
case 'dawn-wings': case "dawn-wings":
case 'dusk-mane': case "dusk-mane":
case 'ultra': case "ultra":
ret += `-${formKey}`; ret += `-${formKey}`;
break; break;
} }
@ -358,18 +374,21 @@ export abstract class PokemonSpeciesForm {
validateStarterMoveset(moveset: StarterMoveset, eggMoves: integer): boolean { validateStarterMoveset(moveset: StarterMoveset, eggMoves: integer): boolean {
const rootSpeciesId = this.getRootSpeciesId(); const rootSpeciesId = this.getRootSpeciesId();
for (let moveId of moveset) { for (const moveId of moveset) {
if (speciesEggMoves.hasOwnProperty(rootSpeciesId)) { if (speciesEggMoves.hasOwnProperty(rootSpeciesId)) {
const eggMoveIndex = speciesEggMoves[rootSpeciesId].findIndex(m => m === moveId); const eggMoveIndex = speciesEggMoves[rootSpeciesId].findIndex(m => m === moveId);
if (eggMoveIndex > -1 && eggMoves & Math.pow(2, eggMoveIndex)) if (eggMoveIndex > -1 && eggMoves & Math.pow(2, eggMoveIndex)) {
continue; continue;
} }
}
if (pokemonFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex)) { if (pokemonFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex)) {
if (!pokemonFormLevelMoves[this.speciesId][this.formIndex].find(lm => lm[0] <= 5 && lm[1] === moveId)) if (!pokemonFormLevelMoves[this.speciesId][this.formIndex].find(lm => lm[0] <= 5 && lm[1] === moveId)) {
return false; return false;
} else if (!pokemonSpeciesLevelMoves[this.speciesId].find(lm => lm[0] <= 5 && lm[1] === moveId)) }
} else if (!pokemonSpeciesLevelMoves[this.speciesId].find(lm => lm[0] <= 5 && lm[1] === moveId)) {
return false; return false;
} }
}
return true; return true;
} }
@ -391,19 +410,20 @@ export abstract class PokemonSpeciesForm {
frameRate: 12, frameRate: 12,
repeat: -1 repeat: -1
}); });
let spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant).replace('variant/', '').replace(/_[1-3]$/, ''); let spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant).replace("variant/", "").replace(/_[1-3]$/, "");
const useExpSprite = scene.experimentalSprites && scene.hasExpSprite(spriteKey); const useExpSprite = scene.experimentalSprites && scene.hasExpSprite(spriteKey);
if (useExpSprite) if (useExpSprite) {
spritePath = `exp/${spritePath}`; spritePath = `exp/${spritePath}`;
let variantSet: VariantSet; }
let config = variantData; let config = variantData;
spritePath.split('/').map(p => config ? config = config[p] : null); spritePath.split("/").map(p => config ? config = config[p] : null);
variantSet = config as VariantSet; const variantSet = config as VariantSet;
if (variantSet && variantSet[variant] === 1) { if (variantSet && variantSet[variant] === 1) {
const populateVariantColors = (key: string): Promise<void> => { const populateVariantColors = (key: string): Promise<void> => {
return new Promise(resolve => { return new Promise(resolve => {
if (variantColorCache.hasOwnProperty(key)) if (variantColorCache.hasOwnProperty(key)) {
return resolve(); return resolve();
}
scene.cachedFetch(`./images/pokemon/variant/${spritePath}.json`).then(res => res.json()).then(c => { scene.cachedFetch(`./images/pokemon/variant/${spritePath}.json`).then(res => res.json()).then(c => {
variantColorCache[key] = c; variantColorCache[key] = c;
resolve(); resolve();
@ -416,21 +436,25 @@ export abstract class PokemonSpeciesForm {
resolve(); resolve();
}); });
if (startLoad) { if (startLoad) {
if (!scene.load.isLoading()) if (!scene.load.isLoading()) {
scene.load.start(); scene.load.start();
} else }
} else {
resolve(); resolve();
}
}); });
} }
cry(scene: BattleScene, soundConfig?: Phaser.Types.Sound.SoundConfig, ignorePlay?: boolean): AnySound { cry(scene: BattleScene, soundConfig?: Phaser.Types.Sound.SoundConfig, ignorePlay?: boolean): AnySound {
const cryKey = this.getCryKey(this.formIndex); const cryKey = this.getCryKey(this.formIndex);
let cry = scene.sound.get(cryKey) as AnySound; let cry = scene.sound.get(cryKey) as AnySound;
if (cry?.pendingRemove) if (cry?.pendingRemove) {
cry = null; cry = null;
}
cry = scene.playSound(cry || cryKey, soundConfig); cry = scene.playSound(cry || cryKey, soundConfig);
if (ignorePlay) if (ignorePlay) {
cry.stop(); cry.stop();
}
return cry; return cry;
} }
@ -440,11 +464,11 @@ export abstract class PokemonSpeciesForm {
const sourceFrame = sourceTexture.frames[sourceTexture.firstFrame]; const sourceFrame = sourceTexture.frames[sourceTexture.firstFrame];
const sourceImage = sourceTexture.getSourceImage() as HTMLImageElement; const sourceImage = sourceTexture.getSourceImage() as HTMLImageElement;
const canvas = document.createElement('canvas'); const canvas = document.createElement("canvas");
const spriteColors: integer[][] = []; const spriteColors: integer[][] = [];
const context = canvas.getContext('2d'); const context = canvas.getContext("2d");
const frame = sourceFrame; const frame = sourceFrame;
canvas.width = frame.width; canvas.width = frame.width;
canvas.height = frame.height; canvas.height = frame.height;
@ -456,16 +480,18 @@ export abstract class PokemonSpeciesForm {
if (pixelData[i + 3]) { if (pixelData[i + 3]) {
const pixel = pixelData.slice(i, i + 4); const pixel = pixelData.slice(i, i + 4);
const [ r, g, b, a ] = pixel; const [ r, g, b, a ] = pixel;
if (!spriteColors.find(c => c[0] === r && c[1] === g && c[2] === b)) if (!spriteColors.find(c => c[0] === r && c[1] === g && c[2] === b)) {
spriteColors.push([ r, g, b, a ]); spriteColors.push([ r, g, b, a ]);
} }
} }
}
const pixelColors = []; const pixelColors = [];
for (let i = 0; i < pixelData.length; i += 4) { for (let i = 0; i < pixelData.length; i += 4) {
const total = pixelData.slice(i, i + 3).reduce((total: integer, value: integer) => total + value, 0); const total = pixelData.slice(i, i + 3).reduce((total: integer, value: integer) => total + value, 0);
if (!total) if (!total) {
continue; continue;
}
pixelColors.push(argbFromRgba({ r: pixelData[i], g: pixelData[i + 1], b: pixelData[i + 2], a: pixelData[i + 3] })); pixelColors.push(argbFromRgba({ r: pixelData[i], g: pixelData[i + 1], b: pixelData[i + 2], a: pixelData[i + 3] }));
} }
@ -476,7 +502,7 @@ export abstract class PokemonSpeciesForm {
scene.executeWithSeedOffset(() => { scene.executeWithSeedOffset(() => {
paletteColors = QuantizerCelebi.quantize(pixelColors, 2); paletteColors = QuantizerCelebi.quantize(pixelColors, 2);
}, 0, 'This result should not vary'); }, 0, "This result should not vary");
Math.random = originalRandom; Math.random = originalRandom;
@ -538,10 +564,11 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
case SpeciesFormKey.MEGA_Y: case SpeciesFormKey.MEGA_Y:
return `Mega ${this.name} Y`; return `Mega ${this.name} Y`;
default: default:
if (form.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1) if (form.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1) {
return `G-Max ${this.name}`; return `G-Max ${this.name}`;
} }
} }
}
return this.name; return this.name;
} }
@ -580,80 +607,88 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
if (prevolutionLevels.length) { if (prevolutionLevels.length) {
for (let pl = prevolutionLevels.length - 1; pl >= 0; pl--) { for (let pl = prevolutionLevels.length - 1; pl >= 0; pl--) {
const prevolutionLevel = prevolutionLevels[pl]; const prevolutionLevel = prevolutionLevels[pl];
if (level < prevolutionLevel[1]) if (level < prevolutionLevel[1]) {
return prevolutionLevel[0]; return prevolutionLevel[0];
} }
} }
}
if (!allowEvolving || !pokemonEvolutions.hasOwnProperty(this.speciesId)) if (!allowEvolving || !pokemonEvolutions.hasOwnProperty(this.speciesId)) {
return this.speciesId; return this.speciesId;
}
const evolutions = pokemonEvolutions[this.speciesId]; const evolutions = pokemonEvolutions[this.speciesId];
const easeInFunc = Phaser.Tweens.Builders.GetEaseFunction('Sine.easeIn'); const easeInFunc = Phaser.Tweens.Builders.GetEaseFunction("Sine.easeIn");
const easeOutFunc = Phaser.Tweens.Builders.GetEaseFunction('Sine.easeOut'); const easeOutFunc = Phaser.Tweens.Builders.GetEaseFunction("Sine.easeOut");
const evolutionPool: Map<number, Species> = new Map(); const evolutionPool: Map<number, Species> = new Map();
let totalWeight = 0; let totalWeight = 0;
let noEvolutionChance = 1; let noEvolutionChance = 1;
for (let ev of evolutions) { for (const ev of evolutions) {
if (ev.level > level) if (ev.level > level) {
continue; continue;
}
let evolutionChance: number; let evolutionChance: number;
const evolutionSpecies = getPokemonSpecies(ev.speciesId); const evolutionSpecies = getPokemonSpecies(ev.speciesId);
const isRegionalEvolution = !this.isRegional() && evolutionSpecies.isRegional(); const isRegionalEvolution = !this.isRegional() && evolutionSpecies.isRegional();
if (!forTrainer && isRegionalEvolution) if (!forTrainer && isRegionalEvolution) {
evolutionChance = 0; evolutionChance = 0;
else { } else {
if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE) { if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE) {
if (strength === PartyMemberStrength.STRONGER) if (strength === PartyMemberStrength.STRONGER) {
evolutionChance = 1; evolutionChance = 1;
else { } else {
const maxLevelDiff = this.getStrengthLevelDiff(strength); const maxLevelDiff = this.getStrengthLevelDiff(strength);
const minChance: number = 0.875 - 0.125 * strength; const minChance: number = 0.875 - 0.125 * strength;
evolutionChance = Math.min(minChance + easeInFunc(Math.min(level - ev.level, maxLevelDiff) / maxLevelDiff) * (1 - minChance), 1); evolutionChance = Math.min(minChance + easeInFunc(Math.min(level - ev.level, maxLevelDiff) / maxLevelDiff) * (1 - minChance), 1);
} }
} else { } else {
let preferredMinLevel = Math.max((ev.level - 1) + ev.wildDelay * this.getStrengthLevelDiff(strength), 1); const preferredMinLevel = Math.max((ev.level - 1) + ev.wildDelay * this.getStrengthLevelDiff(strength), 1);
let evolutionLevel = Math.max(ev.level > 1 ? ev.level : Math.floor(preferredMinLevel / 2), 1); let evolutionLevel = Math.max(ev.level > 1 ? ev.level : Math.floor(preferredMinLevel / 2), 1);
if (ev.level <= 1 && pokemonPrevolutions.hasOwnProperty(this.speciesId)) { if (ev.level <= 1 && pokemonPrevolutions.hasOwnProperty(this.speciesId)) {
const prevolutionLevel = pokemonEvolutions[pokemonPrevolutions[this.speciesId]].find(ev => ev.speciesId === this.speciesId).level; const prevolutionLevel = pokemonEvolutions[pokemonPrevolutions[this.speciesId]].find(ev => ev.speciesId === this.speciesId).level;
if (prevolutionLevel > 1) if (prevolutionLevel > 1) {
evolutionLevel = prevolutionLevel; evolutionLevel = prevolutionLevel;
} }
}
evolutionChance = Math.min(0.65 * easeInFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel) / preferredMinLevel) + 0.35 * easeOutFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel * 2.5) / (preferredMinLevel * 2.5)), 1); evolutionChance = Math.min(0.65 * easeInFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel) / preferredMinLevel) + 0.35 * easeOutFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel * 2.5) / (preferredMinLevel * 2.5)), 1);
} }
} }
if (evolutionChance > 0) { if (evolutionChance > 0) {
if (isRegionalEvolution) if (isRegionalEvolution) {
evolutionChance /= (evolutionSpecies.isRareRegional() ? 16 : 4); evolutionChance /= (evolutionSpecies.isRareRegional() ? 16 : 4);
}
totalWeight += evolutionChance; totalWeight += evolutionChance;
evolutionPool.set(totalWeight, ev.speciesId); evolutionPool.set(totalWeight, ev.speciesId);
if ((1 - evolutionChance) < noEvolutionChance) if ((1 - evolutionChance) < noEvolutionChance) {
noEvolutionChance = 1 - evolutionChance; noEvolutionChance = 1 - evolutionChance;
} }
} }
}
if (noEvolutionChance === 1 || Phaser.Math.RND.realInRange(0, 1) < noEvolutionChance) if (noEvolutionChance === 1 || Phaser.Math.RND.realInRange(0, 1) < noEvolutionChance) {
return this.speciesId; return this.speciesId;
}
const randValue = evolutionPool.size === 1 ? 0 : Utils.randSeedInt(totalWeight); const randValue = evolutionPool.size === 1 ? 0 : Utils.randSeedInt(totalWeight);
for (let weight of evolutionPool.keys()) { for (const weight of evolutionPool.keys()) {
if (randValue < weight) if (randValue < weight) {
return getPokemonSpecies(evolutionPool.get(weight)).getSpeciesForLevel(level, true, forTrainer, strength); return getPokemonSpecies(evolutionPool.get(weight)).getSpeciesForLevel(level, true, forTrainer, strength);
} }
}
return this.speciesId; return this.speciesId;
} }
@ -664,16 +699,17 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
//console.log(Species[this.speciesId], pokemonEvolutions[this.speciesId]) //console.log(Species[this.speciesId], pokemonEvolutions[this.speciesId])
if (pokemonEvolutions.hasOwnProperty(this.speciesId)) { if (pokemonEvolutions.hasOwnProperty(this.speciesId)) {
for (let e of pokemonEvolutions[this.speciesId]) { for (const e of pokemonEvolutions[this.speciesId]) {
const speciesId = e.speciesId; const speciesId = e.speciesId;
const level = e.level; const level = e.level;
evolutionLevels.push([ speciesId, level ]); evolutionLevels.push([ speciesId, level ]);
//console.log(Species[speciesId], getPokemonSpecies(speciesId), getPokemonSpecies(speciesId).getEvolutionLevels()); //console.log(Species[speciesId], getPokemonSpecies(speciesId), getPokemonSpecies(speciesId).getEvolutionLevels());
const nextEvolutionLevels = getPokemonSpecies(speciesId).getEvolutionLevels(); const nextEvolutionLevels = getPokemonSpecies(speciesId).getEvolutionLevels();
for (let npl of nextEvolutionLevels) for (const npl of nextEvolutionLevels) {
evolutionLevels.push(npl); evolutionLevels.push(npl);
} }
} }
}
return evolutionLevels; return evolutionLevels;
} }
@ -682,18 +718,19 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
const prevolutionLevels = []; const prevolutionLevels = [];
const allEvolvingPokemon = Object.keys(pokemonEvolutions); const allEvolvingPokemon = Object.keys(pokemonEvolutions);
for (let p of allEvolvingPokemon) { for (const p of allEvolvingPokemon) {
for (let e of pokemonEvolutions[p]) { for (const e of pokemonEvolutions[p]) {
if (e.speciesId === this.speciesId && (!this.forms.length || !e.evoFormKey || e.evoFormKey === this.forms[this.formIndex].formKey)) { if (e.speciesId === this.speciesId && (!this.forms.length || !e.evoFormKey || e.evoFormKey === this.forms[this.formIndex].formKey)) {
const speciesId = parseInt(p) as Species; const speciesId = parseInt(p) as Species;
let level = e.level; const level = e.level;
prevolutionLevels.push([ speciesId, level ]); prevolutionLevels.push([ speciesId, level ]);
const subPrevolutionLevels = getPokemonSpecies(speciesId).getPrevolutionLevels(); const subPrevolutionLevels = getPokemonSpecies(speciesId).getPrevolutionLevels();
for (let spl of subPrevolutionLevels) for (const spl of subPrevolutionLevels) {
prevolutionLevels.push(spl); prevolutionLevels.push(spl);
} }
} }
} }
}
return prevolutionLevels; return prevolutionLevels;
} }
@ -747,7 +784,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
} }
return this.forms?.length return this.forms?.length
? this.forms[formIndex || 0].getFormSpriteKey() ? this.forms[formIndex || 0].getFormSpriteKey()
: ''; : "";
} }
} }

View File

@ -1,4 +1,4 @@
import i18next from '../plugins/i18n'; import i18next from "../plugins/i18n";
export enum Stat { export enum Stat {
HP = 0, HP = 0,
@ -7,28 +7,28 @@ export enum Stat {
SPATK, SPATK,
SPDEF, SPDEF,
SPD SPD
}; }
export function getStatName(stat: Stat, shorten: boolean = false) { export function getStatName(stat: Stat, shorten: boolean = false) {
let ret: string; let ret: string;
switch (stat) { switch (stat) {
case Stat.HP: case Stat.HP:
ret = !shorten ? i18next.t('pokemonInfo:Stat.HP') : i18next.t('pokemonInfo:Stat.HPshortened'); ret = !shorten ? i18next.t("pokemonInfo:Stat.HP") : i18next.t("pokemonInfo:Stat.HPshortened");
break; break;
case Stat.ATK: case Stat.ATK:
ret = !shorten ? i18next.t('pokemonInfo:Stat.ATK') : i18next.t('pokemonInfo:Stat.ATKshortened'); ret = !shorten ? i18next.t("pokemonInfo:Stat.ATK") : i18next.t("pokemonInfo:Stat.ATKshortened");
break; break;
case Stat.DEF: case Stat.DEF:
ret = !shorten ? i18next.t('pokemonInfo:Stat.DEF') : i18next.t('pokemonInfo:Stat.DEFshortened'); ret = !shorten ? i18next.t("pokemonInfo:Stat.DEF") : i18next.t("pokemonInfo:Stat.DEFshortened");
break; break;
case Stat.SPATK: case Stat.SPATK:
ret = !shorten ? i18next.t('pokemonInfo:Stat.SPATK') : i18next.t('pokemonInfo:Stat.SPATKshortened'); ret = !shorten ? i18next.t("pokemonInfo:Stat.SPATK") : i18next.t("pokemonInfo:Stat.SPATKshortened");
break; break;
case Stat.SPDEF: case Stat.SPDEF:
ret = !shorten ? i18next.t('pokemonInfo:Stat.SPDEF') : i18next.t('pokemonInfo:Stat.SPDEFshortened'); ret = !shorten ? i18next.t("pokemonInfo:Stat.SPDEF") : i18next.t("pokemonInfo:Stat.SPDEFshortened");
break; break;
case Stat.SPD: case Stat.SPD:
ret = !shorten ? i18next.t('pokemonInfo:Stat.SPD') : i18next.t('pokemonInfo:Stat.SPDshortened'); ret = !shorten ? i18next.t("pokemonInfo:Stat.SPD") : i18next.t("pokemonInfo:Stat.SPDshortened");
break; break;
} }
return ret; return ret;

View File

@ -1,45 +1,45 @@
import i18next from "../plugins/i18n"; import i18next from "../plugins/i18n";
export function getBattleCountSplashMessage(): string { export function getBattleCountSplashMessage(): string {
return `{COUNT} ${i18next.t('splashMessages:battlesWon')}`; return `{COUNT} ${i18next.t("splashMessages:battlesWon")}`;
} }
export function getSplashMessages(): string[] { export function getSplashMessages(): string[] {
const splashMessages = Array(10).fill(getBattleCountSplashMessage()); const splashMessages = Array(10).fill(getBattleCountSplashMessage());
splashMessages.push(...[ splashMessages.push(...[
i18next.t('splashMessages:joinTheDiscord'), i18next.t("splashMessages:joinTheDiscord"),
i18next.t('splashMessages:infiniteLevels'), i18next.t("splashMessages:infiniteLevels"),
i18next.t('splashMessages:everythingStacks'), i18next.t("splashMessages:everythingStacks"),
i18next.t('splashMessages:optionalSaveScumming'), i18next.t("splashMessages:optionalSaveScumming"),
i18next.t('splashMessages:biomes'), i18next.t("splashMessages:biomes"),
i18next.t('splashMessages:openSource'), i18next.t("splashMessages:openSource"),
i18next.t('splashMessages:playWithSpeed'), i18next.t("splashMessages:playWithSpeed"),
i18next.t('splashMessages:liveBugTesting'), i18next.t("splashMessages:liveBugTesting"),
i18next.t('splashMessages:heavyInfluence'), i18next.t("splashMessages:heavyInfluence"),
i18next.t('splashMessages:pokemonRiskAndPokemonRain'), i18next.t("splashMessages:pokemonRiskAndPokemonRain"),
i18next.t('splashMessages:nowWithMoreSalt'), i18next.t("splashMessages:nowWithMoreSalt"),
i18next.t('splashMessages:infiniteFusionAtHome'), i18next.t("splashMessages:infiniteFusionAtHome"),
i18next.t('splashMessages:brokenEggMoves'), i18next.t("splashMessages:brokenEggMoves"),
i18next.t('splashMessages:magnificent'), i18next.t("splashMessages:magnificent"),
i18next.t('splashMessages:mubstitute'), i18next.t("splashMessages:mubstitute"),
i18next.t('splashMessages:thatsCrazy'), i18next.t("splashMessages:thatsCrazy"),
i18next.t('splashMessages:oranceJuice'), i18next.t("splashMessages:oranceJuice"),
i18next.t('splashMessages:questionableBalancing'), i18next.t("splashMessages:questionableBalancing"),
i18next.t('splashMessages:coolShaders'), i18next.t("splashMessages:coolShaders"),
i18next.t('splashMessages:aiFree'), i18next.t("splashMessages:aiFree"),
i18next.t('splashMessages:suddenDifficultySpikes'), i18next.t("splashMessages:suddenDifficultySpikes"),
i18next.t('splashMessages:basedOnAnUnfinishedFlashGame'), i18next.t("splashMessages:basedOnAnUnfinishedFlashGame"),
i18next.t('splashMessages:moreAddictiveThanIntended'), i18next.t("splashMessages:moreAddictiveThanIntended"),
i18next.t('splashMessages:mostlyConsistentSeeds'), i18next.t("splashMessages:mostlyConsistentSeeds"),
i18next.t('splashMessages:achievementPointsDontDoAnything'), i18next.t("splashMessages:achievementPointsDontDoAnything"),
i18next.t('splashMessages:youDoNotStartAtLevel'), i18next.t("splashMessages:youDoNotStartAtLevel"),
i18next.t('splashMessages:dontTalkAboutTheManaphyEggIncident'), i18next.t("splashMessages:dontTalkAboutTheManaphyEggIncident"),
i18next.t('splashMessages:alsoTryPokengine'), i18next.t("splashMessages:alsoTryPokengine"),
i18next.t('splashMessages:alsoTryEmeraldRogue'), i18next.t("splashMessages:alsoTryEmeraldRogue"),
i18next.t('splashMessages:alsoTryRadicalRed'), i18next.t("splashMessages:alsoTryRadicalRed"),
i18next.t('splashMessages:eeveeExpo'), i18next.t("splashMessages:eeveeExpo"),
i18next.t('splashMessages:ynoproject'), i18next.t("splashMessages:ynoproject"),
]); ]);
return splashMessages return splashMessages;
} }

View File

@ -32,7 +32,7 @@ export class Status {
} }
export function getStatusEffectObtainText(statusEffect: StatusEffect, sourceText?: string): string { export function getStatusEffectObtainText(statusEffect: StatusEffect, sourceText?: string): string {
const sourceClause = sourceText ? ` ${statusEffect !== StatusEffect.SLEEP ? 'by' : 'from'} ${sourceText}` : ''; const sourceClause = sourceText ? ` ${statusEffect !== StatusEffect.SLEEP ? "by" : "from"} ${sourceText}` : "";
switch (statusEffect) { switch (statusEffect) {
case StatusEffect.POISON: case StatusEffect.POISON:
return `\nwas poisoned${sourceClause}!`; return `\nwas poisoned${sourceClause}!`;
@ -48,76 +48,76 @@ export function getStatusEffectObtainText(statusEffect: StatusEffect, sourceText
return `\nwas burned${sourceClause}!`; return `\nwas burned${sourceClause}!`;
} }
return ''; return "";
} }
export function getStatusEffectActivationText(statusEffect: StatusEffect): string { export function getStatusEffectActivationText(statusEffect: StatusEffect): string {
switch (statusEffect) { switch (statusEffect) {
case StatusEffect.POISON: case StatusEffect.POISON:
case StatusEffect.TOXIC: case StatusEffect.TOXIC:
return ' is hurt\nby poison!'; return " is hurt\nby poison!";
case StatusEffect.PARALYSIS: case StatusEffect.PARALYSIS:
return ' is paralyzed!\nIt can\'t move!'; return " is paralyzed!\nIt can't move!";
case StatusEffect.SLEEP: case StatusEffect.SLEEP:
return ' is fast asleep.'; return " is fast asleep.";
case StatusEffect.FREEZE: case StatusEffect.FREEZE:
return ' is\nfrozen solid!'; return " is\nfrozen solid!";
case StatusEffect.BURN: case StatusEffect.BURN:
return ' is hurt\nby its burn!'; return " is hurt\nby its burn!";
} }
return ''; return "";
} }
export function getStatusEffectOverlapText(statusEffect: StatusEffect): string { export function getStatusEffectOverlapText(statusEffect: StatusEffect): string {
switch (statusEffect) { switch (statusEffect) {
case StatusEffect.POISON: case StatusEffect.POISON:
case StatusEffect.TOXIC: case StatusEffect.TOXIC:
return ' is\nalready poisoned!'; return " is\nalready poisoned!";
case StatusEffect.PARALYSIS: case StatusEffect.PARALYSIS:
return ' is\nalready paralyzed!'; return " is\nalready paralyzed!";
case StatusEffect.SLEEP: case StatusEffect.SLEEP:
return ' is\nalready asleep!'; return " is\nalready asleep!";
case StatusEffect.FREEZE: case StatusEffect.FREEZE:
return ' is\nalready frozen!'; return " is\nalready frozen!";
case StatusEffect.BURN: case StatusEffect.BURN:
return ' is\nalready burned!'; return " is\nalready burned!";
} }
return ''; return "";
} }
export function getStatusEffectHealText(statusEffect: StatusEffect): string { export function getStatusEffectHealText(statusEffect: StatusEffect): string {
switch (statusEffect) { switch (statusEffect) {
case StatusEffect.POISON: case StatusEffect.POISON:
case StatusEffect.TOXIC: case StatusEffect.TOXIC:
return ' was\ncured of its poison!'; return " was\ncured of its poison!";
case StatusEffect.PARALYSIS: case StatusEffect.PARALYSIS:
return ' was\nhealed of paralysis!'; return " was\nhealed of paralysis!";
case StatusEffect.SLEEP: case StatusEffect.SLEEP:
return ' woke up!'; return " woke up!";
case StatusEffect.FREEZE: case StatusEffect.FREEZE:
return ' was\ndefrosted!'; return " was\ndefrosted!";
case StatusEffect.BURN: case StatusEffect.BURN:
return ' was\nhealed of its burn!'; return " was\nhealed of its burn!";
} }
return ''; return "";
} }
export function getStatusEffectDescriptor(statusEffect: StatusEffect): string { export function getStatusEffectDescriptor(statusEffect: StatusEffect): string {
switch (statusEffect) { switch (statusEffect) {
case StatusEffect.POISON: case StatusEffect.POISON:
case StatusEffect.TOXIC: case StatusEffect.TOXIC:
return 'poisoning'; return "poisoning";
case StatusEffect.PARALYSIS: case StatusEffect.PARALYSIS:
return 'paralysis'; return "paralysis";
case StatusEffect.SLEEP: case StatusEffect.SLEEP:
return 'sleep'; return "sleep";
case StatusEffect.FREEZE: case StatusEffect.FREEZE:
return 'freezing'; return "freezing";
case StatusEffect.BURN: case StatusEffect.BURN:
return 'burn'; return "burn";
} }
} }

View File

@ -11,26 +11,27 @@ export enum TempBattleStat {
} }
export function getTempBattleStatName(tempBattleStat: TempBattleStat) { export function getTempBattleStatName(tempBattleStat: TempBattleStat) {
if (tempBattleStat === TempBattleStat.CRIT) if (tempBattleStat === TempBattleStat.CRIT) {
return 'critical-hit ratio'; return "critical-hit ratio";
}
return getBattleStatName(tempBattleStat as integer as BattleStat); return getBattleStatName(tempBattleStat as integer as BattleStat);
} }
export function getTempBattleStatBoosterItemName(tempBattleStat: TempBattleStat) { export function getTempBattleStatBoosterItemName(tempBattleStat: TempBattleStat) {
switch (tempBattleStat) { switch (tempBattleStat) {
case TempBattleStat.ATK: case TempBattleStat.ATK:
return 'X Attack'; return "X Attack";
case TempBattleStat.DEF: case TempBattleStat.DEF:
return 'X Defense'; return "X Defense";
case TempBattleStat.SPATK: case TempBattleStat.SPATK:
return 'X Sp. Atk'; return "X Sp. Atk";
case TempBattleStat.SPDEF: case TempBattleStat.SPDEF:
return 'X Sp. Def'; return "X Sp. Def";
case TempBattleStat.SPD: case TempBattleStat.SPD:
return 'X Speed'; return "X Speed";
case TempBattleStat.ACC: case TempBattleStat.ACC:
return 'X Accuracy'; return "X Accuracy";
case TempBattleStat.CRIT: case TempBattleStat.CRIT:
return 'Dire Hit'; return "Dire Hit";
} }
} }

View File

@ -24,8 +24,9 @@ export class Terrain {
} }
lapse(): boolean { lapse(): boolean {
if (this.turnsLeft) if (this.turnsLeft) {
return !!--this.turnsLeft; return !!--this.turnsLeft;
}
return true; return true;
} }
@ -33,16 +34,19 @@ export class Terrain {
getAttackTypeMultiplier(attackType: Type): number { getAttackTypeMultiplier(attackType: Type): number {
switch (this.terrainType) { switch (this.terrainType) {
case TerrainType.ELECTRIC: case TerrainType.ELECTRIC:
if (attackType === Type.ELECTRIC) if (attackType === Type.ELECTRIC) {
return 1.3; return 1.3;
}
break; break;
case TerrainType.GRASSY: case TerrainType.GRASSY:
if (attackType === Type.GRASS) if (attackType === Type.GRASS) {
return 1.3; return 1.3;
}
break; break;
case TerrainType.PSYCHIC: case TerrainType.PSYCHIC:
if (attackType === Type.PSYCHIC) if (attackType === Type.PSYCHIC) {
return 1.3; return 1.3;
}
break; break;
} }

File diff suppressed because it is too large Load Diff

View File

@ -74,9 +74,10 @@ export class TrainerPartyCompoundTemplate extends TrainerPartyTemplate {
getStrength(index: integer): PartyMemberStrength { getStrength(index: integer): PartyMemberStrength {
let t = 0; let t = 0;
for (let template of this.templates) { for (const template of this.templates) {
if (t + template.size > index) if (t + template.size > index) {
return template.getStrength(index - t); return template.getStrength(index - t);
}
t += template.size; t += template.size;
} }
@ -85,9 +86,10 @@ export class TrainerPartyCompoundTemplate extends TrainerPartyTemplate {
isSameSpecies(index: integer): boolean { isSameSpecies(index: integer): boolean {
let t = 0; let t = 0;
for (let template of this.templates) { for (const template of this.templates) {
if (t + template.size > index) if (t + template.size > index) {
return template.isSameSpecies(index - t); return template.isSameSpecies(index - t);
}
t += template.size; t += template.size;
} }
@ -96,9 +98,10 @@ export class TrainerPartyCompoundTemplate extends TrainerPartyTemplate {
isBalanced(index: integer): boolean { isBalanced(index: integer): boolean {
let t = 0; let t = 0;
for (let template of this.templates) { for (const template of this.templates) {
if (t + template.size > index) if (t + template.size > index) {
return template.isBalanced(index - t); return template.isBalanced(index - t);
}
t += template.size; t += template.size;
} }
@ -211,8 +214,8 @@ export class TrainerConfig {
constructor(trainerType: TrainerType, allowLegendaries?: boolean) { constructor(trainerType: TrainerType, allowLegendaries?: boolean) {
this.trainerType = trainerType; this.trainerType = trainerType;
this.name = Utils.toReadableString(TrainerType[this.getDerivedType()]); this.name = Utils.toReadableString(TrainerType[this.getDerivedType()]);
this.battleBgm = 'battle_trainer'; this.battleBgm = "battle_trainer";
this.victoryBgm = 'victory_trainer'; this.victoryBgm = "victory_trainer";
this.partyTemplates = [trainerPartyTemplates.TWO_AVG]; this.partyTemplates = [trainerPartyTemplates.TWO_AVG];
this.speciesFilter = species => (allowLegendaries || (!species.legendary && !species.subLegendary && !species.mythical)) && !species.isTrainerForbidden(); this.speciesFilter = species => (allowLegendaries || (!species.legendary && !species.subLegendary && !species.mythical)) && !species.isTrainerForbidden();
} }
@ -223,21 +226,22 @@ export class TrainerConfig {
getSpriteKey(female?: boolean): string { getSpriteKey(female?: boolean): string {
let ret = this.getKey(); let ret = this.getKey();
if (this.hasGenders) if (this.hasGenders) {
ret += `_${female ? 'f' : 'm'}`; ret += `_${female ? "f" : "m"}`;
}
return ret; return ret;
} }
setName(name: string): TrainerConfig { setName(name: string): TrainerConfig {
if (name === 'Finn') { if (name === "Finn") {
// Give the rival a localized name // Give the rival a localized name
// First check if i18n is initialized // First check if i18n is initialized
if (!getIsInitialized()) { if (!getIsInitialized()) {
initI18n(); initI18n();
} }
// This is only the male name, because the female name is handled in a different function (setHasGenders) // This is only the male name, because the female name is handled in a different function (setHasGenders)
if (name === 'Finn') { if (name === "Finn") {
name = i18next.t('trainerNames:rival'); name = i18next.t("trainerNames:rival");
} }
} }
this.name = name; this.name = name;
@ -251,7 +255,7 @@ export class TrainerConfig {
} }
// Make the title lowercase and replace spaces with underscores // Make the title lowercase and replace spaces with underscores
title = title.toLowerCase().replace(/\s/g, '_'); title = title.toLowerCase().replace(/\s/g, "_");
// Get the title from the i18n file // Get the title from the i18n file
this.title = i18next.t(`titles:${title}`); this.title = i18next.t(`titles:${title}`);
@ -289,14 +293,14 @@ export class TrainerConfig {
**/ **/
setHasGenders(nameFemale?: string, femaleEncounterBgm?: TrainerType | string): TrainerConfig { setHasGenders(nameFemale?: string, femaleEncounterBgm?: TrainerType | string): TrainerConfig {
// If the female name is 'Ivy' (the rival), assign a localized name. // If the female name is 'Ivy' (the rival), assign a localized name.
if (nameFemale === 'Ivy') { if (nameFemale === "Ivy") {
// Check if the internationalization (i18n) system is initialized. // Check if the internationalization (i18n) system is initialized.
if (!getIsInitialized()) { if (!getIsInitialized()) {
// Initialize the i18n system if it is not already initialized. // Initialize the i18n system if it is not already initialized.
initI18n(); initI18n();
} }
// Set the localized name for the female rival. // Set the localized name for the female rival.
this.nameFemale = i18next.t('trainerNames:rival_female'); this.nameFemale = i18next.t("trainerNames:rival_female");
} else { } else {
// Otherwise, assign the provided female name. // Otherwise, assign the provided female name.
this.nameFemale = nameFemale; this.nameFemale = nameFemale;
@ -309,8 +313,8 @@ export class TrainerConfig {
if (femaleEncounterBgm) { if (femaleEncounterBgm) {
// If the BGM is a TrainerType (number), convert it to a string, replace underscores with spaces, and convert to lowercase. // If the BGM is a TrainerType (number), convert it to a string, replace underscores with spaces, and convert to lowercase.
// Otherwise, assign the provided string as the BGM. // Otherwise, assign the provided string as the BGM.
this.femaleEncounterBgm = typeof femaleEncounterBgm === 'number' this.femaleEncounterBgm = typeof femaleEncounterBgm === "number"
? TrainerType[femaleEncounterBgm].toString().replace(/_/g, ' ').toLowerCase() ? TrainerType[femaleEncounterBgm].toString().replace(/_/g, " ").toLowerCase()
: femaleEncounterBgm; : femaleEncounterBgm;
} }
@ -321,8 +325,9 @@ export class TrainerConfig {
setHasDouble(nameDouble: string, doubleEncounterBgm?: TrainerType | string): TrainerConfig { setHasDouble(nameDouble: string, doubleEncounterBgm?: TrainerType | string): TrainerConfig {
this.hasDouble = true; this.hasDouble = true;
this.nameDouble = nameDouble; this.nameDouble = nameDouble;
if (doubleEncounterBgm) if (doubleEncounterBgm) {
this.doubleEncounterBgm = typeof doubleEncounterBgm === 'number' ? TrainerType[doubleEncounterBgm].toString().replace(/\_/g, ' ').toLowerCase() : doubleEncounterBgm; this.doubleEncounterBgm = typeof doubleEncounterBgm === "number" ? TrainerType[doubleEncounterBgm].toString().replace(/\_/g, " ").toLowerCase() : doubleEncounterBgm;
}
return this; return this;
} }
@ -362,7 +367,7 @@ export class TrainerConfig {
} }
setEncounterBgm(encounterBgm: TrainerType | string): TrainerConfig { setEncounterBgm(encounterBgm: TrainerType | string): TrainerConfig {
this.encounterBgm = typeof encounterBgm === 'number' ? TrainerType[encounterBgm].toString().toLowerCase() : encounterBgm; this.encounterBgm = typeof encounterBgm === "number" ? TrainerType[encounterBgm].toString().toLowerCase() : encounterBgm;
return this; return this;
} }
@ -435,8 +440,9 @@ export class TrainerConfig {
// Set up party members with their corresponding species. // Set up party members with their corresponding species.
signatureSpecies.forEach((speciesPool, s) => { signatureSpecies.forEach((speciesPool, s) => {
// Ensure speciesPool is an array. // Ensure speciesPool is an array.
if (!Array.isArray(speciesPool)) if (!Array.isArray(speciesPool)) {
speciesPool = [speciesPool]; speciesPool = [speciesPool];
}
// Set a function to get a random party member from the species pool. // Set a function to get a random party member from the species pool.
this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool)); this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool));
}); });
@ -448,18 +454,18 @@ export class TrainerConfig {
} }
// 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, "_");
this.name = i18next.t(`trainerNames:${nameForCall}`); this.name = i18next.t(`trainerNames:${nameForCall}`);
// Set the title to "gym_leader". (this is the key in the i18n file) // Set the title to "gym_leader". (this is the key in the i18n file)
this.setTitle('gym_leader'); this.setTitle("gym_leader");
// Configure various properties for the Gym Leader. // Configure various properties for the Gym Leader.
this.setMoneyMultiplier(2.5); this.setMoneyMultiplier(2.5);
this.setBoss(); this.setBoss();
this.setStaticParty(); this.setStaticParty();
this.setBattleBgm('battle_unova_gym'); this.setBattleBgm("battle_unova_gym");
this.setVictoryBgm('victory_gym'); this.setVictoryBgm("victory_gym");
this.setGenModifiersFunc(party => { this.setGenModifiersFunc(party => {
const waveIndex = party[0].scene.currentBattle.waveIndex; const waveIndex = party[0].scene.currentBattle.waveIndex;
return getRandomTeraModifiers(party, waveIndex >= 100 ? 1 : 0, specialtyTypes.length ? specialtyTypes : null); return getRandomTeraModifiers(party, waveIndex >= 100 ? 1 : 0, specialtyTypes.length ? specialtyTypes : null);
@ -486,8 +492,9 @@ export class TrainerConfig {
// Set up party members with their corresponding species. // Set up party members with their corresponding species.
signatureSpecies.forEach((speciesPool, s) => { signatureSpecies.forEach((speciesPool, s) => {
// Ensure speciesPool is an array. // Ensure speciesPool is an array.
if (!Array.isArray(speciesPool)) if (!Array.isArray(speciesPool)) {
speciesPool = [speciesPool]; speciesPool = [speciesPool];
}
// Set a function to get a random party member from the species pool. // Set a function to get a random party member from the species pool.
this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool)); this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool));
}); });
@ -501,18 +508,18 @@ export class TrainerConfig {
} }
// 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, "_");
this.name = i18next.t(`trainerNames:${nameForCall}`); this.name = i18next.t(`trainerNames:${nameForCall}`);
// Set the title to "elite_four". (this is the key in the i18n file) // Set the title to "elite_four". (this is the key in the i18n file)
this.setTitle('elite_four'); this.setTitle("elite_four");
// Configure various properties for the Elite Four member. // Configure various properties for the Elite Four member.
this.setMoneyMultiplier(3.25); this.setMoneyMultiplier(3.25);
this.setBoss(); this.setBoss();
this.setStaticParty(); this.setStaticParty();
this.setBattleBgm('battle_elite'); this.setBattleBgm("battle_elite");
this.setVictoryBgm('victory_gym'); this.setVictoryBgm("victory_gym");
this.setGenModifiersFunc(party => getRandomTeraModifiers(party, 2, specialtyTypes.length ? specialtyTypes : null)); this.setGenModifiersFunc(party => getRandomTeraModifiers(party, 2, specialtyTypes.length ? specialtyTypes : null));
return this; return this;
@ -535,8 +542,9 @@ export class TrainerConfig {
// Set up party members with their corresponding species. // Set up party members with their corresponding species.
signatureSpecies.forEach((speciesPool, s) => { signatureSpecies.forEach((speciesPool, s) => {
// Ensure speciesPool is an array. // Ensure speciesPool is an array.
if (!Array.isArray(speciesPool)) if (!Array.isArray(speciesPool)) {
speciesPool = [speciesPool]; speciesPool = [speciesPool];
}
// Set a function to get a random party member from the species pool. // Set a function to get a random party member from the species pool.
this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool)); this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool));
}); });
@ -545,18 +553,18 @@ export class TrainerConfig {
this.setSpeciesFilter(p => p.baseTotal >= 470); 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, "_");
this.name = i18next.t(`trainerNames:${nameForCall}`); this.name = i18next.t(`trainerNames:${nameForCall}`);
// Set the title to "champion". (this is the key in the i18n file) // Set the title to "champion". (this is the key in the i18n file)
this.setTitle('champion'); this.setTitle("champion");
// Configure various properties for the Champion. // Configure various properties for the Champion.
this.setMoneyMultiplier(10); this.setMoneyMultiplier(10);
this.setBoss(); this.setBoss();
this.setStaticParty(); this.setStaticParty();
this.setBattleBgm('battle_champion_alder'); this.setBattleBgm("battle_champion_alder");
this.setVictoryBgm('victory_champion'); this.setVictoryBgm("victory_champion");
this.setGenModifiersFunc(party => getRandomTeraModifiers(party, 3)); this.setGenModifiersFunc(party => getRandomTeraModifiers(party, 3));
return this; return this;
@ -569,19 +577,21 @@ export class TrainerConfig {
* @returns {string} - The title of the trainer. * @returns {string} - The title of the trainer.
**/ **/
getTitle(trainerSlot: TrainerSlot = TrainerSlot.NONE, variant: TrainerVariant): string { getTitle(trainerSlot: TrainerSlot = TrainerSlot.NONE, variant: TrainerVariant): string {
let ret = this.name; const ret = this.name;
// Check if the variant is double and the name for double exists // Check if the variant is double and the name for double exists
if (!trainerSlot && variant === TrainerVariant.DOUBLE && this.nameDouble) if (!trainerSlot && variant === TrainerVariant.DOUBLE && this.nameDouble) {
return this.nameDouble; return this.nameDouble;
}
// Female variant // Female variant
if (this.hasGenders) { if (this.hasGenders) {
// If the name is already set // If the name is already set
if (this.nameFemale) { if (this.nameFemale) {
// Check if the variant is either female or this is for the partner in a double battle // Check if the variant is either female or this is for the partner in a double battle
if (variant === TrainerVariant.FEMALE || (variant === TrainerVariant.DOUBLE && trainerSlot === TrainerSlot.TRAINER_PARTNER)) if (variant === TrainerVariant.FEMALE || (variant === TrainerVariant.DOUBLE && trainerSlot === TrainerSlot.TRAINER_PARTNER)) {
return this.nameFemale; return this.nameFemale;
}
} else } else
// Check if !variant is true, if so return the name, else return the name with _female appended // Check if !variant is true, if so return the name, else return the name with _female appended
if (variant) { if (variant) {
@ -607,9 +617,10 @@ export class TrainerConfig {
const isDouble = variant === TrainerVariant.DOUBLE; const isDouble = variant === TrainerVariant.DOUBLE;
const trainerKey = this.getSpriteKey(variant === TrainerVariant.FEMALE); const trainerKey = this.getSpriteKey(variant === TrainerVariant.FEMALE);
const partnerTrainerKey = this.getSpriteKey(true); const partnerTrainerKey = this.getSpriteKey(true);
scene.loadAtlas(trainerKey, 'trainer'); scene.loadAtlas(trainerKey, "trainer");
if (isDouble) if (isDouble) {
scene.loadAtlas(partnerTrainerKey, 'trainer'); scene.loadAtlas(partnerTrainerKey, "trainer");
}
scene.load.once(Phaser.Loader.Events.COMPLETE, () => { scene.load.once(Phaser.Loader.Events.COMPLETE, () => {
const originalWarn = console.warn; const originalWarn = console.warn;
// Ignore warnings for missing frames, because there will be a lot // Ignore warnings for missing frames, because there will be a lot
@ -636,8 +647,9 @@ export class TrainerConfig {
} }
resolve(); resolve();
}); });
if (!scene.load.isLoading()) if (!scene.load.isLoading()) {
scene.load.start(); scene.load.start();
}
}); });
} }
} }
@ -659,8 +671,9 @@ function getGymLeaderPartyTemplate(scene: BattleScene) {
function getRandomPartyMemberFunc(speciesPool: Species[], trainerSlot: TrainerSlot = TrainerSlot.TRAINER, ignoreEvolution: boolean = false, postProcess?: (enemyPokemon: EnemyPokemon) => void): PartyMemberFunc { function getRandomPartyMemberFunc(speciesPool: Species[], trainerSlot: TrainerSlot = TrainerSlot.TRAINER, ignoreEvolution: boolean = false, postProcess?: (enemyPokemon: EnemyPokemon) => void): PartyMemberFunc {
return (scene: BattleScene, level: integer, strength: PartyMemberStrength) => { return (scene: BattleScene, level: integer, strength: PartyMemberStrength) => {
let species = Utils.randSeedItem(speciesPool); let species = Utils.randSeedItem(speciesPool);
if (!ignoreEvolution) if (!ignoreEvolution) {
species = getPokemonSpecies(species).getTrainerSpeciesForLevel(level, true, strength); species = getPokemonSpecies(species).getTrainerSpeciesForLevel(level, true, strength);
}
return scene.addEnemyPokemon(getPokemonSpecies(species), level, trainerSlot, undefined, undefined, postProcess); return scene.addEnemyPokemon(getPokemonSpecies(species), level, trainerSlot, undefined, undefined, postProcess);
}; };
} }
@ -687,12 +700,12 @@ function getRandomTeraModifiers(party: EnemyPokemon[], count: integer, types?: T
export const trainerConfigs: TrainerConfigs = { export const trainerConfigs: TrainerConfigs = {
[TrainerType.UNKNOWN]: new TrainerConfig(0).setHasGenders(), [TrainerType.UNKNOWN]: new TrainerConfig(0).setHasGenders(),
[TrainerType.ACE_TRAINER]: new TrainerConfig(++t).setHasGenders('Ace Trainer Female').setHasDouble('Ace Duo').setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.ACE_TRAINER) [TrainerType.ACE_TRAINER]: new TrainerConfig(++t).setHasGenders("Ace Trainer Female").setHasDouble("Ace Duo").setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.ACE_TRAINER)
.setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.THREE_WEAK_BALANCED, trainerPartyTemplates.FOUR_WEAK_BALANCED, trainerPartyTemplates.FIVE_WEAK_BALANCED, trainerPartyTemplates.SIX_WEAK_BALANCED)), .setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.THREE_WEAK_BALANCED, trainerPartyTemplates.FOUR_WEAK_BALANCED, trainerPartyTemplates.FIVE_WEAK_BALANCED, trainerPartyTemplates.SIX_WEAK_BALANCED)),
[TrainerType.ARTIST]: new TrainerConfig(++t).setEncounterBgm(TrainerType.RICH).setPartyTemplates(trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.THREE_AVG) [TrainerType.ARTIST]: new TrainerConfig(++t).setEncounterBgm(TrainerType.RICH).setPartyTemplates(trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.THREE_AVG)
.setSpeciesPools([ Species.SMEARGLE ]), .setSpeciesPools([ Species.SMEARGLE ]),
[TrainerType.BACKERS]: new TrainerConfig(++t).setHasGenders("Backers").setDoubleOnly().setEncounterBgm(TrainerType.CYCLIST), [TrainerType.BACKERS]: new TrainerConfig(++t).setHasGenders("Backers").setDoubleOnly().setEncounterBgm(TrainerType.CYCLIST),
[TrainerType.BACKPACKER]: new TrainerConfig(++t).setHasGenders("Backpacker Female").setHasDouble('Backpackers').setSpeciesFilter(s => s.isOfType(Type.FLYING) || s.isOfType(Type.ROCK)).setEncounterBgm(TrainerType.BACKPACKER) [TrainerType.BACKPACKER]: new TrainerConfig(++t).setHasGenders("Backpacker Female").setHasDouble("Backpackers").setSpeciesFilter(s => s.isOfType(Type.FLYING) || s.isOfType(Type.ROCK)).setEncounterBgm(TrainerType.BACKPACKER)
.setPartyTemplates(trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.ONE_WEAK_ONE_STRONG, trainerPartyTemplates.ONE_AVG_ONE_STRONG) .setPartyTemplates(trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.ONE_WEAK_ONE_STRONG, trainerPartyTemplates.ONE_AVG_ONE_STRONG)
.setSpeciesPools({ .setSpeciesPools({
[TrainerPoolTier.COMMON]: [ Species.RHYHORN, Species.AIPOM, Species.MAKUHITA, Species.MAWILE, Species.NUMEL, Species.LILLIPUP, Species.SANDILE, Species.WOOLOO ], [TrainerPoolTier.COMMON]: [ Species.RHYHORN, Species.AIPOM, Species.MAKUHITA, Species.MAWILE, Species.NUMEL, Species.LILLIPUP, Species.SANDILE, Species.WOOLOO ],
@ -703,7 +716,7 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerType.BAKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setMoneyMultiplier(1.35).setSpeciesFilter(s => s.isOfType(Type.GRASS) || s.isOfType(Type.FIRE)), [TrainerType.BAKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setMoneyMultiplier(1.35).setSpeciesFilter(s => s.isOfType(Type.GRASS) || s.isOfType(Type.FIRE)),
[TrainerType.BEAUTY]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.PARASOL_LADY), [TrainerType.BEAUTY]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.PARASOL_LADY),
[TrainerType.BIKER]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.POISON)), [TrainerType.BIKER]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.POISON)),
[TrainerType.BLACK_BELT]: new TrainerConfig(++t).setHasGenders('Battle Girl', TrainerType.PSYCHIC).setHasDouble('Crush Kin').setEncounterBgm(TrainerType.ROUGHNECK).setSpecialtyTypes(Type.FIGHTING) [TrainerType.BLACK_BELT]: new TrainerConfig(++t).setHasGenders("Battle Girl", TrainerType.PSYCHIC).setHasDouble("Crush Kin").setEncounterBgm(TrainerType.ROUGHNECK).setSpecialtyTypes(Type.FIGHTING)
.setPartyTemplates(trainerPartyTemplates.TWO_WEAK_ONE_AVG, trainerPartyTemplates.TWO_WEAK_ONE_AVG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_ONE_STRONG, trainerPartyTemplates.THREE_AVG, trainerPartyTemplates.TWO_AVG_ONE_STRONG) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK_ONE_AVG, trainerPartyTemplates.TWO_WEAK_ONE_AVG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_ONE_STRONG, trainerPartyTemplates.THREE_AVG, trainerPartyTemplates.TWO_AVG_ONE_STRONG)
.setSpeciesPools({ .setSpeciesPools({
[TrainerPoolTier.COMMON]: [ Species.NIDORAN_F, Species.NIDORAN_M, Species.MACHOP, Species.MAKUHITA, Species.MEDITITE, Species.CROAGUNK, Species.TIMBURR ], [TrainerPoolTier.COMMON]: [ Species.NIDORAN_F, Species.NIDORAN_M, Species.MACHOP, Species.MAKUHITA, Species.MEDITITE, Species.CROAGUNK, Species.TIMBURR ],
@ -712,17 +725,17 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerPoolTier.SUPER_RARE]: [ Species.HITMONTOP, Species.INFERNAPE, Species.GALLADE, Species.HAWLUCHA, Species.HAKAMO_O ], [TrainerPoolTier.SUPER_RARE]: [ Species.HITMONTOP, Species.INFERNAPE, Species.GALLADE, Species.HAWLUCHA, Species.HAKAMO_O ],
[TrainerPoolTier.ULTRA_RARE]: [ Species.KUBFU ] [TrainerPoolTier.ULTRA_RARE]: [ Species.KUBFU ]
}), }),
[TrainerType.BREEDER]: new TrainerConfig(++t).setMoneyMultiplier(1.325).setEncounterBgm(TrainerType.POKEFAN).setHasGenders("Breeder Female").setHasDouble('Breeders') [TrainerType.BREEDER]: new TrainerConfig(++t).setMoneyMultiplier(1.325).setEncounterBgm(TrainerType.POKEFAN).setHasGenders("Breeder Female").setHasDouble("Breeders")
.setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.FOUR_WEAKER, trainerPartyTemplates.FIVE_WEAKER, trainerPartyTemplates.SIX_WEAKER)) .setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.FOUR_WEAKER, trainerPartyTemplates.FIVE_WEAKER, trainerPartyTemplates.SIX_WEAKER))
.setSpeciesFilter(s => s.baseTotal < 450), .setSpeciesFilter(s => s.baseTotal < 450),
[TrainerType.CLERK]: new TrainerConfig(++t).setHasGenders("Clerk Female").setHasDouble('Colleagues').setEncounterBgm(TrainerType.CLERK) [TrainerType.CLERK]: new TrainerConfig(++t).setHasGenders("Clerk Female").setHasDouble("Colleagues").setEncounterBgm(TrainerType.CLERK)
.setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.THREE_WEAK, trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_ONE_AVG) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.THREE_WEAK, trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_ONE_AVG)
.setSpeciesPools({ .setSpeciesPools({
[TrainerPoolTier.COMMON]: [ Species.MEOWTH, Species.PSYDUCK, Species.BUDEW, Species.PIDOVE, Species.CINCCINO, Species.LITLEO ], [TrainerPoolTier.COMMON]: [ Species.MEOWTH, Species.PSYDUCK, Species.BUDEW, Species.PIDOVE, Species.CINCCINO, Species.LITLEO ],
[TrainerPoolTier.UNCOMMON]: [ Species.JIGGLYPUFF, Species.MAGNEMITE, Species.MARILL, Species.COTTONEE, Species.SKIDDO ], [TrainerPoolTier.UNCOMMON]: [ Species.JIGGLYPUFF, Species.MAGNEMITE, Species.MARILL, Species.COTTONEE, Species.SKIDDO ],
[TrainerPoolTier.RARE]: [ Species.BUIZEL, Species.SNEASEL, Species.KLEFKI, Species.INDEEDEE ] [TrainerPoolTier.RARE]: [ Species.BUIZEL, Species.SNEASEL, Species.KLEFKI, Species.INDEEDEE ]
}), }),
[TrainerType.CYCLIST]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setHasGenders("Cyclist Female").setHasDouble('Cyclists').setEncounterBgm(TrainerType.CYCLIST) [TrainerType.CYCLIST]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setHasGenders("Cyclist Female").setHasDouble("Cyclists").setEncounterBgm(TrainerType.CYCLIST)
.setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.ONE_AVG) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.ONE_AVG)
.setSpeciesPools({ .setSpeciesPools({
[TrainerPoolTier.COMMON]: [ Species.PICHU, Species.STARLY, Species.TAILLOW, Species.BOLTUND ], [TrainerPoolTier.COMMON]: [ Species.PICHU, Species.STARLY, Species.TAILLOW, Species.BOLTUND ],
@ -739,7 +752,7 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerPoolTier.SUPER_RARE]: [ Species.POPPLIO ] [TrainerPoolTier.SUPER_RARE]: [ Species.POPPLIO ]
}), }),
[TrainerType.DEPOT_AGENT]: new TrainerConfig(++t).setMoneyMultiplier(1.45).setEncounterBgm(TrainerType.CLERK), [TrainerType.DEPOT_AGENT]: new TrainerConfig(++t).setMoneyMultiplier(1.45).setEncounterBgm(TrainerType.CLERK),
[TrainerType.DOCTOR]: new TrainerConfig(++t).setHasGenders('Nurse', 'lass').setHasDouble('Medical Team').setMoneyMultiplier(3).setEncounterBgm(TrainerType.CLERK) [TrainerType.DOCTOR]: new TrainerConfig(++t).setHasGenders("Nurse", "lass").setHasDouble("Medical Team").setMoneyMultiplier(3).setEncounterBgm(TrainerType.CLERK)
.setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.HEAL_PULSE)), .setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.HEAL_PULSE)),
[TrainerType.FISHERMAN]: new TrainerConfig(++t).setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.BACKPACKER).setSpecialtyTypes(Type.WATER) [TrainerType.FISHERMAN]: new TrainerConfig(++t).setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.BACKPACKER).setSpecialtyTypes(Type.WATER)
.setPartyTemplates(trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.THREE_WEAK_SAME, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.SIX_WEAKER) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.THREE_WEAK_SAME, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.SIX_WEAKER)
@ -769,7 +782,7 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerType.HEX_MANIAC]: new TrainerConfig(++t).setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.PSYCHIC) [TrainerType.HEX_MANIAC]: new TrainerConfig(++t).setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.PSYCHIC)
.setPartyTemplates(trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.ONE_AVG_ONE_STRONG, trainerPartyTemplates.TWO_AVG_SAME_ONE_AVG, trainerPartyTemplates.THREE_AVG, trainerPartyTemplates.TWO_STRONG) .setPartyTemplates(trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.ONE_AVG_ONE_STRONG, trainerPartyTemplates.TWO_AVG_SAME_ONE_AVG, trainerPartyTemplates.THREE_AVG, trainerPartyTemplates.TWO_STRONG)
.setSpeciesFilter(s => s.isOfType(Type.GHOST)), .setSpeciesFilter(s => s.isOfType(Type.GHOST)),
[TrainerType.NURSERY_AIDE]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setEncounterBgm('lass'), [TrainerType.NURSERY_AIDE]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setEncounterBgm("lass"),
[TrainerType.OFFICER]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.CLERK) [TrainerType.OFFICER]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.CLERK)
.setPartyTemplates(trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG) .setPartyTemplates(trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG)
.setSpeciesPools({ .setSpeciesPools({
@ -781,9 +794,9 @@ export const trainerConfigs: TrainerConfigs = {
}), }),
[TrainerType.PARASOL_LADY]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.PARASOL_LADY).setSpeciesFilter(s => s.isOfType(Type.WATER)), [TrainerType.PARASOL_LADY]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.PARASOL_LADY).setSpeciesFilter(s => s.isOfType(Type.WATER)),
[TrainerType.PILOT]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => tmSpecies[Moves.FLY].indexOf(s.speciesId) > -1), [TrainerType.PILOT]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => tmSpecies[Moves.FLY].indexOf(s.speciesId) > -1),
[TrainerType.POKEFAN]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setName('PokéFan').setHasGenders("PokéFan Female").setHasDouble('PokéFan Family').setEncounterBgm(TrainerType.POKEFAN) [TrainerType.POKEFAN]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setName("PokéFan").setHasGenders("PokéFan Female").setHasDouble("PokéFan Family").setEncounterBgm(TrainerType.POKEFAN)
.setPartyTemplates(trainerPartyTemplates.SIX_WEAKER, trainerPartyTemplates.FOUR_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.FOUR_WEAK_SAME, trainerPartyTemplates.FIVE_WEAK, trainerPartyTemplates.SIX_WEAKER_SAME), .setPartyTemplates(trainerPartyTemplates.SIX_WEAKER, trainerPartyTemplates.FOUR_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.FOUR_WEAK_SAME, trainerPartyTemplates.FIVE_WEAK, trainerPartyTemplates.SIX_WEAKER_SAME),
[TrainerType.PRESCHOOLER]: new TrainerConfig(++t).setMoneyMultiplier(0.2).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders("Preschooler Female", 'lass').setHasDouble('Preschoolers') [TrainerType.PRESCHOOLER]: new TrainerConfig(++t).setMoneyMultiplier(0.2).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders("Preschooler Female", "lass").setHasDouble("Preschoolers")
.setPartyTemplates(trainerPartyTemplates.THREE_WEAK, trainerPartyTemplates.FOUR_WEAKER, trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.FIVE_WEAKER) .setPartyTemplates(trainerPartyTemplates.THREE_WEAK, trainerPartyTemplates.FOUR_WEAKER, trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.FIVE_WEAKER)
.setSpeciesPools({ .setSpeciesPools({
[TrainerPoolTier.COMMON]: [ Species.CATERPIE, Species.PICHU, Species.SANDSHREW, Species.LEDYBA, Species.BUDEW, Species.BURMY, Species.WOOLOO, Species.PAWMI, Species.SMOLIV ], [TrainerPoolTier.COMMON]: [ Species.CATERPIE, Species.PICHU, Species.SANDSHREW, Species.LEDYBA, Species.BUDEW, Species.BURMY, Species.WOOLOO, Species.PAWMI, Species.SMOLIV ],
@ -791,7 +804,7 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerPoolTier.RARE]: [ Species.RALTS, Species.RIOLU, Species.JOLTIK, Species.TANDEMAUS ], [TrainerPoolTier.RARE]: [ Species.RALTS, Species.RIOLU, Species.JOLTIK, Species.TANDEMAUS ],
[TrainerPoolTier.SUPER_RARE]: [ Species.DARUMAKA, Species.TINKATINK ], [TrainerPoolTier.SUPER_RARE]: [ Species.DARUMAKA, Species.TINKATINK ],
}), }),
[TrainerType.PSYCHIC]: new TrainerConfig(++t).setHasGenders("Psychic Female").setHasDouble('Psychics').setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.PSYCHIC) [TrainerType.PSYCHIC]: new TrainerConfig(++t).setHasGenders("Psychic Female").setHasDouble("Psychics").setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.PSYCHIC)
.setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.TWO_WEAK_SAME_TWO_WEAK_SAME, trainerPartyTemplates.ONE_STRONGER) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.TWO_WEAK_SAME_TWO_WEAK_SAME, trainerPartyTemplates.ONE_STRONGER)
.setSpeciesPools({ .setSpeciesPools({
[TrainerPoolTier.COMMON]: [ Species.ABRA, Species.DROWZEE, Species.RALTS, Species.SPOINK, Species.GOTHITA, Species.SOLOSIS, Species.BLIPBUG, Species.ESPURR, Species.HATENNA ], [TrainerPoolTier.COMMON]: [ Species.ABRA, Species.DROWZEE, Species.RALTS, Species.SPOINK, Species.GOTHITA, Species.SOLOSIS, Species.BLIPBUG, Species.ESPURR, Species.HATENNA ],
@ -799,17 +812,17 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerPoolTier.RARE]: [ Species.ELGYEM, Species.SIGILYPH, Species.BALTOY, Species.GIRAFARIG, Species.MEOWSTIC ], [TrainerPoolTier.RARE]: [ Species.ELGYEM, Species.SIGILYPH, Species.BALTOY, Species.GIRAFARIG, Species.MEOWSTIC ],
[TrainerPoolTier.SUPER_RARE]: [ Species.BELDUM, Species.ESPEON, Species.STANTLER ], [TrainerPoolTier.SUPER_RARE]: [ Species.BELDUM, Species.ESPEON, Species.STANTLER ],
}), }),
[TrainerType.RANGER]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setName('Pokémon Ranger').setEncounterBgm(TrainerType.BACKPACKER).setHasGenders("Pokémon Ranger Female").setHasDouble('Pokémon Rangers') [TrainerType.RANGER]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setName("Pokémon Ranger").setEncounterBgm(TrainerType.BACKPACKER).setHasGenders("Pokémon Ranger Female").setHasDouble("Pokémon Rangers")
.setSpeciesPools({ .setSpeciesPools({
[TrainerPoolTier.COMMON]: [ Species.PICHU, Species.GROWLITHE, Species.PONYTA, Species.ZIGZAGOON, Species.SEEDOT, Species.BIDOOF, Species.RIOLU, Species.SEWADDLE, Species.SKIDDO, Species.SALANDIT, Species.YAMPER ], [TrainerPoolTier.COMMON]: [ Species.PICHU, Species.GROWLITHE, Species.PONYTA, Species.ZIGZAGOON, Species.SEEDOT, Species.BIDOOF, Species.RIOLU, Species.SEWADDLE, Species.SKIDDO, Species.SALANDIT, Species.YAMPER ],
[TrainerPoolTier.UNCOMMON]: [ Species.AZURILL, Species.TAUROS, Species.MAREEP, Species.FARFETCHD, Species.TEDDIURSA, Species.SHROOMISH, Species.ELECTRIKE, Species.BUDEW, Species.BUIZEL, Species.MUDBRAY, Species.STUFFUL ], [TrainerPoolTier.UNCOMMON]: [ Species.AZURILL, Species.TAUROS, Species.MAREEP, Species.FARFETCHD, Species.TEDDIURSA, Species.SHROOMISH, Species.ELECTRIKE, Species.BUDEW, Species.BUIZEL, Species.MUDBRAY, Species.STUFFUL ],
[TrainerPoolTier.RARE]: [ Species.EEVEE, Species.SCYTHER, Species.KANGASKHAN, Species.RALTS, Species.MUNCHLAX, Species.ZORUA, Species.PALDEA_TAUROS, Species.TINKATINK, Species.CYCLIZAR, Species.FLAMIGO ], [TrainerPoolTier.RARE]: [ Species.EEVEE, Species.SCYTHER, Species.KANGASKHAN, Species.RALTS, Species.MUNCHLAX, Species.ZORUA, Species.PALDEA_TAUROS, Species.TINKATINK, Species.CYCLIZAR, Species.FLAMIGO ],
[TrainerPoolTier.SUPER_RARE]: [ Species.LARVESTA ], [TrainerPoolTier.SUPER_RARE]: [ Species.LARVESTA ],
}), }),
[TrainerType.RICH]: new TrainerConfig(++t).setMoneyMultiplier(5).setName('Gentleman').setHasGenders('Madame').setHasDouble('Rich Couple'), [TrainerType.RICH]: new TrainerConfig(++t).setMoneyMultiplier(5).setName("Gentleman").setHasGenders("Madame").setHasDouble("Rich Couple"),
[TrainerType.RICH_KID]: new TrainerConfig(++t).setMoneyMultiplier(3.75).setName('Rich Boy').setHasGenders('Lady').setHasDouble('Rich Kids').setEncounterBgm(TrainerType.RICH), [TrainerType.RICH_KID]: new TrainerConfig(++t).setMoneyMultiplier(3.75).setName("Rich Boy").setHasGenders("Lady").setHasDouble("Rich Kids").setEncounterBgm(TrainerType.RICH),
[TrainerType.ROUGHNECK]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.DARK)), [TrainerType.ROUGHNECK]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.DARK)),
[TrainerType.SCIENTIST]: new TrainerConfig(++t).setHasGenders("Scientist Female").setHasDouble('Scientists').setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.SCIENTIST) [TrainerType.SCIENTIST]: new TrainerConfig(++t).setHasGenders("Scientist Female").setHasDouble("Scientists").setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.SCIENTIST)
.setSpeciesPools({ .setSpeciesPools({
[TrainerPoolTier.COMMON]: [ Species.MAGNEMITE, Species.GRIMER, Species.DROWZEE, Species.VOLTORB, Species.KOFFING ], [TrainerPoolTier.COMMON]: [ Species.MAGNEMITE, Species.GRIMER, Species.DROWZEE, Species.VOLTORB, Species.KOFFING ],
[TrainerPoolTier.UNCOMMON]: [ Species.BALTOY, Species.BRONZOR, Species.FERROSEED, Species.KLINK, Species.CHARJABUG, Species.BLIPBUG, Species.HELIOPTILE ], [TrainerPoolTier.UNCOMMON]: [ Species.BALTOY, Species.BRONZOR, Species.FERROSEED, Species.KLINK, Species.CHARJABUG, Species.BLIPBUG, Species.HELIOPTILE ],
@ -818,66 +831,66 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerPoolTier.ULTRA_RARE]: [ Species.ROTOM, Species.MELTAN ] [TrainerPoolTier.ULTRA_RARE]: [ Species.ROTOM, Species.MELTAN ]
}), }),
[TrainerType.SMASHER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST), [TrainerType.SMASHER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST),
[TrainerType.SNOW_WORKER]: new TrainerConfig(++t).setName('Worker').setHasGenders("Worker Female").setHasDouble('Workers').setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => s.isOfType(Type.ICE) || s.isOfType(Type.STEEL)), [TrainerType.SNOW_WORKER]: new TrainerConfig(++t).setName("Worker").setHasGenders("Worker Female").setHasDouble("Workers").setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => s.isOfType(Type.ICE) || s.isOfType(Type.STEEL)),
[TrainerType.STRIKER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST), [TrainerType.STRIKER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST),
[TrainerType.SCHOOL_KID]: new TrainerConfig(++t).setMoneyMultiplier(0.75).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders("School Kid Female", 'lass').setHasDouble('School Kids') [TrainerType.SCHOOL_KID]: new TrainerConfig(++t).setMoneyMultiplier(0.75).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders("School Kid Female", "lass").setHasDouble("School Kids")
.setSpeciesPools({ .setSpeciesPools({
[TrainerPoolTier.COMMON]: [ Species.ODDISH, Species.EXEGGCUTE, Species.TEDDIURSA, Species.WURMPLE, Species.RALTS, Species.SHROOMISH, Species.FLETCHLING ], [TrainerPoolTier.COMMON]: [ Species.ODDISH, Species.EXEGGCUTE, Species.TEDDIURSA, Species.WURMPLE, Species.RALTS, Species.SHROOMISH, Species.FLETCHLING ],
[TrainerPoolTier.UNCOMMON]: [ Species.VOLTORB, Species.WHISMUR, Species.MEDITITE, Species.MIME_JR, Species.NYMBLE ], [TrainerPoolTier.UNCOMMON]: [ Species.VOLTORB, Species.WHISMUR, Species.MEDITITE, Species.MIME_JR, Species.NYMBLE ],
[TrainerPoolTier.RARE]: [ Species.TANGELA, Species.EEVEE, Species.YANMA ], [TrainerPoolTier.RARE]: [ Species.TANGELA, Species.EEVEE, Species.YANMA ],
[TrainerPoolTier.SUPER_RARE]: [ Species.TADBULB ] [TrainerPoolTier.SUPER_RARE]: [ Species.TADBULB ]
}), }),
[TrainerType.SWIMMER]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setEncounterBgm(TrainerType.PARASOL_LADY).setHasGenders("Swimmer Female").setHasDouble('Swimmers').setSpecialtyTypes(Type.WATER).setSpeciesFilter(s => s.isOfType(Type.WATER)), [TrainerType.SWIMMER]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setEncounterBgm(TrainerType.PARASOL_LADY).setHasGenders("Swimmer Female").setHasDouble("Swimmers").setSpecialtyTypes(Type.WATER).setSpeciesFilter(s => s.isOfType(Type.WATER)),
[TrainerType.TWINS]: new TrainerConfig(++t).setDoubleOnly().setMoneyMultiplier(0.65).setUseSameSeedForAllMembers() [TrainerType.TWINS]: new TrainerConfig(++t).setDoubleOnly().setMoneyMultiplier(0.65).setUseSameSeedForAllMembers()
.setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_STRONG)) .setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_STRONG))
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PLUSLE, Species.VOLBEAT, Species.PACHIRISU, Species.SILCOON, Species.METAPOD, Species.IGGLYBUFF, Species.PETILIL, Species.EEVEE ])) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PLUSLE, Species.VOLBEAT, Species.PACHIRISU, Species.SILCOON, Species.METAPOD, Species.IGGLYBUFF, Species.PETILIL, Species.EEVEE ]))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.MINUN, Species.ILLUMISE, Species.EMOLGA, Species.CASCOON, Species.KAKUNA, Species.CLEFFA, Species.COTTONEE, Species.EEVEE ], TrainerSlot.TRAINER_PARTNER)) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.MINUN, Species.ILLUMISE, Species.EMOLGA, Species.CASCOON, Species.KAKUNA, Species.CLEFFA, Species.COTTONEE, Species.EEVEE ], TrainerSlot.TRAINER_PARTNER))
.setEncounterBgm(TrainerType.TWINS), .setEncounterBgm(TrainerType.TWINS),
[TrainerType.VETERAN]: new TrainerConfig(++t).setHasGenders("Veteran Female").setHasDouble('Veteran Duo').setMoneyMultiplier(2.5).setEncounterBgm(TrainerType.ACE_TRAINER).setSpeciesFilter(s => s.isOfType(Type.DRAGON)), [TrainerType.VETERAN]: new TrainerConfig(++t).setHasGenders("Veteran Female").setHasDouble("Veteran Duo").setMoneyMultiplier(2.5).setEncounterBgm(TrainerType.ACE_TRAINER).setSpeciesFilter(s => s.isOfType(Type.DRAGON)),
[TrainerType.WAITER]: new TrainerConfig(++t).setHasGenders('Waitress').setHasDouble('Restaurant Staff').setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.CLERK) [TrainerType.WAITER]: new TrainerConfig(++t).setHasGenders("Waitress").setHasDouble("Restaurant Staff").setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.CLERK)
.setSpeciesPools({ .setSpeciesPools({
[TrainerPoolTier.COMMON]: [ Species.CLEFFA, Species.CHATOT, Species.PANSAGE, Species.PANSEAR, Species.PANPOUR, Species.MINCCINO ], [TrainerPoolTier.COMMON]: [ Species.CLEFFA, Species.CHATOT, Species.PANSAGE, Species.PANSEAR, Species.PANPOUR, Species.MINCCINO ],
[TrainerPoolTier.UNCOMMON]: [ Species.TROPIUS, Species.PETILIL, Species.BOUNSWEET, Species.INDEEDEE ], [TrainerPoolTier.UNCOMMON]: [ Species.TROPIUS, Species.PETILIL, Species.BOUNSWEET, Species.INDEEDEE ],
[TrainerPoolTier.RARE]: [ Species.APPLIN, Species.SINISTEA, Species.POLTCHAGEIST ] [TrainerPoolTier.RARE]: [ Species.APPLIN, Species.SINISTEA, Species.POLTCHAGEIST ]
}), }),
[TrainerType.WORKER]: new TrainerConfig(++t).setHasGenders("Worker Female").setHasDouble('Workers').setEncounterBgm(TrainerType.CLERK).setMoneyMultiplier(1.7).setSpeciesFilter(s => s.isOfType(Type.ROCK) || s.isOfType(Type.STEEL)), [TrainerType.WORKER]: new TrainerConfig(++t).setHasGenders("Worker Female").setHasDouble("Workers").setEncounterBgm(TrainerType.CLERK).setMoneyMultiplier(1.7).setSpeciesFilter(s => s.isOfType(Type.ROCK) || s.isOfType(Type.STEEL)),
[TrainerType.YOUNGSTER]: new TrainerConfig(++t).setMoneyMultiplier(0.5).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders('Lass', 'lass').setHasDouble('Beginners').setPartyTemplates(trainerPartyTemplates.TWO_WEAKER) [TrainerType.YOUNGSTER]: new TrainerConfig(++t).setMoneyMultiplier(0.5).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders("Lass", "lass").setHasDouble("Beginners").setPartyTemplates(trainerPartyTemplates.TWO_WEAKER)
.setSpeciesPools( .setSpeciesPools(
[ Species.CATERPIE, Species.WEEDLE, Species.RATTATA, Species.SENTRET, Species.POOCHYENA, Species.ZIGZAGOON, Species.WURMPLE, Species.BIDOOF, Species.PATRAT, Species.LILLIPUP ] [ Species.CATERPIE, Species.WEEDLE, Species.RATTATA, Species.SENTRET, Species.POOCHYENA, Species.ZIGZAGOON, Species.WURMPLE, Species.BIDOOF, Species.PATRAT, Species.LILLIPUP ]
), ),
[TrainerType.BROCK]: new TrainerConfig((t = TrainerType.BROCK)).initForGymLeader([ Species.GEODUDE, Species.ONIX ], Type.ROCK).setBattleBgm('battle_kanto_gym'), [TrainerType.BROCK]: new TrainerConfig((t = TrainerType.BROCK)).initForGymLeader([ Species.GEODUDE, Species.ONIX ], Type.ROCK).setBattleBgm("battle_kanto_gym"),
[TrainerType.MISTY]: new TrainerConfig(++t).initForGymLeader([ Species.STARYU, Species.PSYDUCK ], Type.WATER).setBattleBgm('battle_kanto_gym'), [TrainerType.MISTY]: new TrainerConfig(++t).initForGymLeader([ Species.STARYU, Species.PSYDUCK ], Type.WATER).setBattleBgm("battle_kanto_gym"),
[TrainerType.LT_SURGE]: new TrainerConfig(++t).initForGymLeader([ Species.VOLTORB, Species.PIKACHU, Species.ELECTABUZZ ], Type.ELECTRIC).setBattleBgm('battle_kanto_gym'), [TrainerType.LT_SURGE]: new TrainerConfig(++t).initForGymLeader([ Species.VOLTORB, Species.PIKACHU, Species.ELECTABUZZ ], Type.ELECTRIC).setBattleBgm("battle_kanto_gym"),
[TrainerType.ERIKA]: new TrainerConfig(++t).initForGymLeader([ Species.ODDISH, Species.BELLSPROUT, Species.TANGELA, Species.HOPPIP ], Type.GRASS).setBattleBgm('battle_kanto_gym'), [TrainerType.ERIKA]: new TrainerConfig(++t).initForGymLeader([ Species.ODDISH, Species.BELLSPROUT, Species.TANGELA, Species.HOPPIP ], Type.GRASS).setBattleBgm("battle_kanto_gym"),
[TrainerType.JANINE]: new TrainerConfig(++t).initForGymLeader([ Species.VENONAT, Species.SPINARAK, Species.ZUBAT ], Type.POISON).setBattleBgm('battle_kanto_gym'), [TrainerType.JANINE]: new TrainerConfig(++t).initForGymLeader([ Species.VENONAT, Species.SPINARAK, Species.ZUBAT ], Type.POISON).setBattleBgm("battle_kanto_gym"),
[TrainerType.SABRINA]: new TrainerConfig(++t).initForGymLeader([ Species.ABRA, Species.MR_MIME, Species.ESPEON ], Type.PSYCHIC).setBattleBgm('battle_kanto_gym'), [TrainerType.SABRINA]: new TrainerConfig(++t).initForGymLeader([ Species.ABRA, Species.MR_MIME, Species.ESPEON ], Type.PSYCHIC).setBattleBgm("battle_kanto_gym"),
[TrainerType.BLAINE]: new TrainerConfig(++t).initForGymLeader([ Species.GROWLITHE, Species.PONYTA, Species.MAGMAR ], Type.FIRE).setBattleBgm('battle_kanto_gym'), [TrainerType.BLAINE]: new TrainerConfig(++t).initForGymLeader([ Species.GROWLITHE, Species.PONYTA, Species.MAGMAR ], Type.FIRE).setBattleBgm("battle_kanto_gym"),
[TrainerType.GIOVANNI]: new TrainerConfig(++t).initForGymLeader([ Species.SANDILE, Species.MURKROW, Species.NIDORAN_M, Species.NIDORAN_F ], Type.DARK).setBattleBgm('battle_kanto_gym'), [TrainerType.GIOVANNI]: new TrainerConfig(++t).initForGymLeader([ Species.SANDILE, Species.MURKROW, Species.NIDORAN_M, Species.NIDORAN_F ], Type.DARK).setBattleBgm("battle_kanto_gym"),
[TrainerType.FALKNER]: new TrainerConfig(++t).initForGymLeader([ Species.PIDGEY, Species.HOOTHOOT, Species.DODUO ], Type.FLYING).setBattleBgm('battle_johto_gym'), [TrainerType.FALKNER]: new TrainerConfig(++t).initForGymLeader([ Species.PIDGEY, Species.HOOTHOOT, Species.DODUO ], Type.FLYING).setBattleBgm("battle_johto_gym"),
[TrainerType.BUGSY]: new TrainerConfig(++t).initForGymLeader([ Species.SCYTHER, Species.HERACROSS, Species.SHUCKLE, Species.PINSIR ], Type.BUG).setBattleBgm('battle_johto_gym'), [TrainerType.BUGSY]: new TrainerConfig(++t).initForGymLeader([ Species.SCYTHER, Species.HERACROSS, Species.SHUCKLE, Species.PINSIR ], Type.BUG).setBattleBgm("battle_johto_gym"),
[TrainerType.WHITNEY]: new TrainerConfig(++t).initForGymLeader([ Species.GIRAFARIG, Species.MILTANK ], Type.NORMAL).setBattleBgm('battle_johto_gym'), [TrainerType.WHITNEY]: new TrainerConfig(++t).initForGymLeader([ Species.GIRAFARIG, Species.MILTANK ], Type.NORMAL).setBattleBgm("battle_johto_gym"),
[TrainerType.MORTY]: new TrainerConfig(++t).initForGymLeader([ Species.GASTLY, Species.MISDREAVUS, Species.SABLEYE ], Type.GHOST).setBattleBgm('battle_johto_gym'), [TrainerType.MORTY]: new TrainerConfig(++t).initForGymLeader([ Species.GASTLY, Species.MISDREAVUS, Species.SABLEYE ], Type.GHOST).setBattleBgm("battle_johto_gym"),
[TrainerType.CHUCK]: new TrainerConfig(++t).initForGymLeader([ Species.POLIWRATH, Species.MANKEY ], Type.FIGHTING).setBattleBgm('battle_johto_gym'), [TrainerType.CHUCK]: new TrainerConfig(++t).initForGymLeader([ Species.POLIWRATH, Species.MANKEY ], Type.FIGHTING).setBattleBgm("battle_johto_gym"),
[TrainerType.JASMINE]: new TrainerConfig(++t).initForGymLeader([ Species.MAGNEMITE, Species.STEELIX ], Type.STEEL).setBattleBgm('battle_johto_gym'), [TrainerType.JASMINE]: new TrainerConfig(++t).initForGymLeader([ Species.MAGNEMITE, Species.STEELIX ], Type.STEEL).setBattleBgm("battle_johto_gym"),
[TrainerType.PRYCE]: new TrainerConfig(++t).initForGymLeader([ Species.SEEL, Species.SWINUB ], Type.ICE).setBattleBgm('battle_johto_gym'), [TrainerType.PRYCE]: new TrainerConfig(++t).initForGymLeader([ Species.SEEL, Species.SWINUB ], Type.ICE).setBattleBgm("battle_johto_gym"),
[TrainerType.CLAIR]: new TrainerConfig(++t).initForGymLeader([ Species.DRATINI, Species.HORSEA, Species.GYARADOS ], Type.DRAGON).setBattleBgm('battle_johto_gym'), [TrainerType.CLAIR]: new TrainerConfig(++t).initForGymLeader([ Species.DRATINI, Species.HORSEA, Species.GYARADOS ], Type.DRAGON).setBattleBgm("battle_johto_gym"),
[TrainerType.ROXANNE]: new TrainerConfig(++t).initForGymLeader([ Species.GEODUDE, Species.NOSEPASS ], Type.ROCK).setBattleBgm('battle_hoenn_gym'), [TrainerType.ROXANNE]: new TrainerConfig(++t).initForGymLeader([ Species.GEODUDE, Species.NOSEPASS ], Type.ROCK).setBattleBgm("battle_hoenn_gym"),
[TrainerType.BRAWLY]: new TrainerConfig(++t).initForGymLeader([ Species.MACHOP, Species.MAKUHITA ], Type.FIGHTING).setBattleBgm('battle_hoenn_gym'), [TrainerType.BRAWLY]: new TrainerConfig(++t).initForGymLeader([ Species.MACHOP, Species.MAKUHITA ], Type.FIGHTING).setBattleBgm("battle_hoenn_gym"),
[TrainerType.WATTSON]: new TrainerConfig(++t).initForGymLeader([ Species.MAGNEMITE, Species.VOLTORB, Species.ELECTRIKE ], Type.ELECTRIC).setBattleBgm('battle_hoenn_gym'), [TrainerType.WATTSON]: new TrainerConfig(++t).initForGymLeader([ Species.MAGNEMITE, Species.VOLTORB, Species.ELECTRIKE ], Type.ELECTRIC).setBattleBgm("battle_hoenn_gym"),
[TrainerType.FLANNERY]: new TrainerConfig(++t).initForGymLeader([ Species.SLUGMA, Species.TORKOAL, Species.NUMEL ], Type.FIRE).setBattleBgm('battle_hoenn_gym'), [TrainerType.FLANNERY]: new TrainerConfig(++t).initForGymLeader([ Species.SLUGMA, Species.TORKOAL, Species.NUMEL ], Type.FIRE).setBattleBgm("battle_hoenn_gym"),
[TrainerType.NORMAN]: new TrainerConfig(++t).initForGymLeader([ Species.SLAKOTH, Species.SPINDA, Species.CHANSEY, Species.KANGASKHAN ], Type.NORMAL).setBattleBgm('battle_hoenn_gym'), [TrainerType.NORMAN]: new TrainerConfig(++t).initForGymLeader([ Species.SLAKOTH, Species.SPINDA, Species.CHANSEY, Species.KANGASKHAN ], Type.NORMAL).setBattleBgm("battle_hoenn_gym"),
[TrainerType.WINONA]: new TrainerConfig(++t).initForGymLeader([ Species.SWABLU, Species.WINGULL, Species.TROPIUS, Species.SKARMORY ], Type.FLYING).setBattleBgm('battle_hoenn_gym'), [TrainerType.WINONA]: new TrainerConfig(++t).initForGymLeader([ Species.SWABLU, Species.WINGULL, Species.TROPIUS, Species.SKARMORY ], Type.FLYING).setBattleBgm("battle_hoenn_gym"),
[TrainerType.TATE]: new TrainerConfig(++t).initForGymLeader([ Species.SOLROCK, Species.NATU, Species.CHIMECHO, Species.GALLADE ], Type.PSYCHIC).setBattleBgm('battle_hoenn_gym'), [TrainerType.TATE]: new TrainerConfig(++t).initForGymLeader([ Species.SOLROCK, Species.NATU, Species.CHIMECHO, Species.GALLADE ], Type.PSYCHIC).setBattleBgm("battle_hoenn_gym"),
[TrainerType.LIZA]: new TrainerConfig(++t).initForGymLeader([ Species.LUNATONE, Species.SPOINK, Species.BALTOY, Species.GARDEVOIR ], Type.PSYCHIC).setBattleBgm('battle_hoenn_gym'), [TrainerType.LIZA]: new TrainerConfig(++t).initForGymLeader([ Species.LUNATONE, Species.SPOINK, Species.BALTOY, Species.GARDEVOIR ], Type.PSYCHIC).setBattleBgm("battle_hoenn_gym"),
[TrainerType.JUAN]: new TrainerConfig(++t).initForGymLeader([ Species.HORSEA, Species.BARBOACH, Species.SPHEAL, Species.RELICANTH ], Type.WATER).setBattleBgm('battle_hoenn_gym'), [TrainerType.JUAN]: new TrainerConfig(++t).initForGymLeader([ Species.HORSEA, Species.BARBOACH, Species.SPHEAL, Species.RELICANTH ], Type.WATER).setBattleBgm("battle_hoenn_gym"),
[TrainerType.ROARK]: new TrainerConfig(++t).initForGymLeader([ Species.CRANIDOS, Species.LARVITAR, Species.GEODUDE ], Type.ROCK).setBattleBgm('battle_sinnoh_gym'), [TrainerType.ROARK]: new TrainerConfig(++t).initForGymLeader([ Species.CRANIDOS, Species.LARVITAR, Species.GEODUDE ], Type.ROCK).setBattleBgm("battle_sinnoh_gym"),
[TrainerType.GARDENIA]: new TrainerConfig(++t).initForGymLeader([ Species.ROSELIA, Species.TANGELA, Species.TURTWIG ], Type.GRASS).setBattleBgm('battle_sinnoh_gym'), [TrainerType.GARDENIA]: new TrainerConfig(++t).initForGymLeader([ Species.ROSELIA, Species.TANGELA, Species.TURTWIG ], Type.GRASS).setBattleBgm("battle_sinnoh_gym"),
[TrainerType.MAYLENE]: new TrainerConfig(++t).initForGymLeader([ Species.LUCARIO, Species.MEDITITE, Species.CHIMCHAR ], Type.FIGHTING).setBattleBgm('battle_sinnoh_gym'), [TrainerType.MAYLENE]: new TrainerConfig(++t).initForGymLeader([ Species.LUCARIO, Species.MEDITITE, Species.CHIMCHAR ], Type.FIGHTING).setBattleBgm("battle_sinnoh_gym"),
[TrainerType.CRASHER_WAKE]: new TrainerConfig(++t).initForGymLeader([ Species.BUIZEL, Species.MAGIKARP, Species.PIPLUP ], Type.WATER).setBattleBgm('battle_sinnoh_gym'), [TrainerType.CRASHER_WAKE]: new TrainerConfig(++t).initForGymLeader([ Species.BUIZEL, Species.MAGIKARP, Species.PIPLUP ], Type.WATER).setBattleBgm("battle_sinnoh_gym"),
[TrainerType.FANTINA]: new TrainerConfig(++t).initForGymLeader([ Species.MISDREAVUS, Species.DRIFLOON, Species.SPIRITOMB ], Type.GHOST).setBattleBgm('battle_sinnoh_gym'), [TrainerType.FANTINA]: new TrainerConfig(++t).initForGymLeader([ Species.MISDREAVUS, Species.DRIFLOON, Species.SPIRITOMB ], Type.GHOST).setBattleBgm("battle_sinnoh_gym"),
[TrainerType.BYRON]: new TrainerConfig(++t).initForGymLeader([ Species.SHIELDON, Species.BRONZOR, Species.AGGRON ], Type.STEEL).setBattleBgm('battle_sinnoh_gym'), [TrainerType.BYRON]: new TrainerConfig(++t).initForGymLeader([ Species.SHIELDON, Species.BRONZOR, Species.AGGRON ], Type.STEEL).setBattleBgm("battle_sinnoh_gym"),
[TrainerType.CANDICE]: new TrainerConfig(++t).initForGymLeader([ Species.SNEASEL, Species.SNOVER, Species.SNORUNT ], Type.ICE).setBattleBgm('battle_sinnoh_gym'), [TrainerType.CANDICE]: new TrainerConfig(++t).initForGymLeader([ Species.SNEASEL, Species.SNOVER, Species.SNORUNT ], Type.ICE).setBattleBgm("battle_sinnoh_gym"),
[TrainerType.VOLKNER]: new TrainerConfig(++t).initForGymLeader([ Species.SHINX, Species.CHINCHOU, Species.ROTOM ], Type.ELECTRIC).setBattleBgm('battle_sinnoh_gym'), [TrainerType.VOLKNER]: new TrainerConfig(++t).initForGymLeader([ Species.SHINX, Species.CHINCHOU, Species.ROTOM ], Type.ELECTRIC).setBattleBgm("battle_sinnoh_gym"),
[TrainerType.CILAN]: new TrainerConfig(++t).initForGymLeader([ Species.PANSAGE, Species.COTTONEE, Species.PETILIL ], Type.GRASS), [TrainerType.CILAN]: new TrainerConfig(++t).initForGymLeader([ Species.PANSAGE, Species.COTTONEE, Species.PETILIL ], Type.GRASS),
[TrainerType.CHILI]: new TrainerConfig(++t).initForGymLeader([ Species.PANSEAR, Species.DARUMAKA, Species.HEATMOR ], Type.FIRE), [TrainerType.CHILI]: new TrainerConfig(++t).initForGymLeader([ Species.PANSEAR, Species.DARUMAKA, Species.HEATMOR ], Type.FIRE),
[TrainerType.CRESS]: new TrainerConfig(++t).initForGymLeader([ Species.PANPOUR, Species.BASCULIN, Species.TYMPOLE ], Type.WATER), [TrainerType.CRESS]: new TrainerConfig(++t).initForGymLeader([ Species.PANPOUR, Species.BASCULIN, Species.TYMPOLE ], Type.WATER),
@ -957,14 +970,14 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerType.LACEY]: new TrainerConfig(++t).initForEliteFour([ Species.EXCADRILL, Species.PRIMARINA, Species.ALCREMIE, Species.GALAR_SLOWBRO ], Type.FAIRY), [TrainerType.LACEY]: new TrainerConfig(++t).initForEliteFour([ Species.EXCADRILL, Species.PRIMARINA, Species.ALCREMIE, Species.GALAR_SLOWBRO ], Type.FAIRY),
[TrainerType.DRAYTON]: new TrainerConfig(++t).initForEliteFour([ Species.DRAGONITE, Species.ARCHALUDON, Species.FLYGON, Species.SCEPTILE ], Type.DRAGON), [TrainerType.DRAYTON]: new TrainerConfig(++t).initForEliteFour([ Species.DRAGONITE, Species.ARCHALUDON, Species.FLYGON, Species.SCEPTILE ], Type.DRAGON),
[TrainerType.BLUE]: new TrainerConfig((t = TrainerType.BLUE)).initForChampion([ Species.GYARADOS, Species.MEWTWO, Species.ARCANINE, Species.ALAKAZAM, Species.PIDGEOT ]).setBattleBgm('battle_kanto_champion'), [TrainerType.BLUE]: new TrainerConfig((t = TrainerType.BLUE)).initForChampion([ Species.GYARADOS, Species.MEWTWO, Species.ARCANINE, Species.ALAKAZAM, Species.PIDGEOT ]).setBattleBgm("battle_kanto_champion"),
[TrainerType.RED]: new TrainerConfig(++t).initForChampion([ Species.CHARIZARD, [ Species.LUGIA, Species.HO_OH ], Species.SNORLAX, Species.RAICHU, Species.ESPEON ]).setBattleBgm('battle_johto_champion'), [TrainerType.RED]: new TrainerConfig(++t).initForChampion([ Species.CHARIZARD, [ Species.LUGIA, Species.HO_OH ], Species.SNORLAX, Species.RAICHU, Species.ESPEON ]).setBattleBgm("battle_johto_champion"),
[TrainerType.LANCE_CHAMPION]: new TrainerConfig(++t).setName("Lance").initForChampion([ Species.DRAGONITE, Species.ZYGARDE, Species.AERODACTYL, Species.KINGDRA, Species.ALOLA_EXEGGUTOR ]).setBattleBgm('battle_johto_champion'), [TrainerType.LANCE_CHAMPION]: new TrainerConfig(++t).setName("Lance").initForChampion([ Species.DRAGONITE, Species.ZYGARDE, Species.AERODACTYL, Species.KINGDRA, Species.ALOLA_EXEGGUTOR ]).setBattleBgm("battle_johto_champion"),
[TrainerType.STEVEN]: new TrainerConfig(++t).initForChampion([ Species.METAGROSS, [ Species.DIALGA, Species.PALKIA ], Species.SKARMORY, Species.AGGRON, Species.CARBINK ]).setBattleBgm('battle_hoenn_champion'), [TrainerType.STEVEN]: new TrainerConfig(++t).initForChampion([ Species.METAGROSS, [ Species.DIALGA, Species.PALKIA ], Species.SKARMORY, Species.AGGRON, Species.CARBINK ]).setBattleBgm("battle_hoenn_champion"),
[TrainerType.WALLACE]: new TrainerConfig(++t).initForChampion([ Species.MILOTIC, Species.KYOGRE, Species.WHISCASH, Species.WALREIN, Species.LUDICOLO ]).setBattleBgm('battle_hoenn_champion'), [TrainerType.WALLACE]: new TrainerConfig(++t).initForChampion([ Species.MILOTIC, Species.KYOGRE, Species.WHISCASH, Species.WALREIN, Species.LUDICOLO ]).setBattleBgm("battle_hoenn_champion"),
[TrainerType.CYNTHIA]: new TrainerConfig(++t).initForChampion([ Species.SPIRITOMB, Species.GIRATINA, Species.GARCHOMP, Species.MILOTIC, Species.LUCARIO, Species.TOGEKISS ]).setBattleBgm('battle_sinnoh_champion'), [TrainerType.CYNTHIA]: new TrainerConfig(++t).initForChampion([ Species.SPIRITOMB, Species.GIRATINA, Species.GARCHOMP, Species.MILOTIC, Species.LUCARIO, Species.TOGEKISS ]).setBattleBgm("battle_sinnoh_champion"),
[TrainerType.ALDER]: new TrainerConfig(++t).initForChampion([ Species.VOLCARONA, Species.GROUDON, Species.BOUFFALANT, Species.ACCELGOR, Species.CONKELDURR ]), [TrainerType.ALDER]: new TrainerConfig(++t).initForChampion([ Species.VOLCARONA, Species.GROUDON, Species.BOUFFALANT, Species.ACCELGOR, Species.CONKELDURR ]),
[TrainerType.IRIS]: new TrainerConfig(++t).initForChampion([ Species.HAXORUS, Species.YVELTAL, Species.DRUDDIGON, Species.ARON, Species.LAPRAS ]).setBattleBgm('battle_champion_iris'), [TrainerType.IRIS]: new TrainerConfig(++t).initForChampion([ Species.HAXORUS, Species.YVELTAL, Species.DRUDDIGON, Species.ARON, Species.LAPRAS ]).setBattleBgm("battle_champion_iris"),
[TrainerType.DIANTHA]: new TrainerConfig(++t).initForChampion([ Species.HAWLUCHA, Species.XERNEAS, Species.GOURGEIST, Species.GOODRA, Species.GARDEVOIR ]), [TrainerType.DIANTHA]: new TrainerConfig(++t).initForChampion([ Species.HAWLUCHA, Species.XERNEAS, Species.GOURGEIST, Species.GOODRA, Species.GARDEVOIR ]),
[TrainerType.HAU]: new TrainerConfig(++t).initForChampion([ Species.ALOLA_RAICHU, [ Species.SOLGALEO, Species.LUNALA ], Species.NOIVERN, [ Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA ], Species.CRABOMINABLE ]), [TrainerType.HAU]: new TrainerConfig(++t).initForChampion([ Species.ALOLA_RAICHU, [ Species.SOLGALEO, Species.LUNALA ], Species.NOIVERN, [ Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA ], Species.CRABOMINABLE ]),
[TrainerType.GEETA]: new TrainerConfig(++t).initForChampion([ Species.GLIMMORA, Species.MIRAIDON, Species.ESPATHRA, Species.VELUZA, Species.KINGAMBIT ]), [TrainerType.GEETA]: new TrainerConfig(++t).initForChampion([ Species.GLIMMORA, Species.MIRAIDON, Species.ESPATHRA, Species.VELUZA, Species.KINGAMBIT ]),
@ -972,21 +985,21 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerType.KIERAN]: new TrainerConfig(++t).initForChampion([ Species.POLITOED, [ Species.OGERPON, Species.TERAPAGOS ], Species.HYDRAPPLE, Species.PORYGON_Z, Species.GRIMMSNARL ]), [TrainerType.KIERAN]: new TrainerConfig(++t).initForChampion([ Species.POLITOED, [ Species.OGERPON, Species.TERAPAGOS ], Species.HYDRAPPLE, Species.PORYGON_Z, Species.GRIMMSNARL ]),
[TrainerType.LEON]: new TrainerConfig(++t).initForChampion([ Species.DRAGAPULT, [ Species.ZACIAN, Species.ZAMAZENTA ], Species.SEISMITOAD, Species.AEGISLASH, Species.CHARIZARD ]), [TrainerType.LEON]: new TrainerConfig(++t).initForChampion([ Species.DRAGAPULT, [ Species.ZACIAN, Species.ZAMAZENTA ], Species.SEISMITOAD, Species.AEGISLASH, Species.CHARIZARD ]),
[TrainerType.RIVAL]: new TrainerConfig((t = TrainerType.RIVAL)).setName('Finn').setHasGenders('Ivy').setHasCharSprite().setTitle('Rival').setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival').setPartyTemplates(trainerPartyTemplates.RIVAL) [TrainerType.RIVAL]: new TrainerConfig((t = TrainerType.RIVAL)).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL)
.setModifierRewardFuncs(() => modifierTypes.SUPER_EXP_CHARM, () => modifierTypes.EXP_SHARE) .setModifierRewardFuncs(() => modifierTypes.SUPER_EXP_CHARM, () => modifierTypes.EXP_SHARE)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT, Species.CHESPIN, Species.FENNEKIN, Species.FROAKIE, Species.ROWLET, Species.LITTEN, Species.POPPLIO, Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE, Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT, Species.CHESPIN, Species.FENNEKIN, Species.FROAKIE, Species.ROWLET, Species.LITTEN, Species.POPPLIO, Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE, Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEY, Species.HOOTHOOT, Species.TAILLOW, Species.STARLY, Species.PIDOVE, Species.FLETCHLING, Species.PIKIPEK, Species.ROOKIDEE, Species.WATTREL ], TrainerSlot.TRAINER, true)), .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEY, Species.HOOTHOOT, Species.TAILLOW, Species.STARLY, Species.PIDOVE, Species.FLETCHLING, Species.PIKIPEK, Species.ROOKIDEE, Species.WATTREL ], TrainerSlot.TRAINER, true)),
[TrainerType.RIVAL_2]: new TrainerConfig(++t).setName('Finn').setHasGenders('Ivy').setHasCharSprite().setTitle('Rival').setStaticParty().setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival').setPartyTemplates(trainerPartyTemplates.RIVAL_2) [TrainerType.RIVAL_2]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_2)
.setModifierRewardFuncs(() => modifierTypes.EXP_SHARE) .setModifierRewardFuncs(() => modifierTypes.EXP_SHARE)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT, Species.QUILLADIN, Species.BRAIXEN, Species.FROGADIER, Species.DARTRIX, Species.TORRACAT, Species.BRIONNE, Species.THWACKEY, Species.RABOOT, Species.DRIZZILE, Species.FLORAGATO, Species.CROCALOR, Species.QUAXWELL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT, Species.QUILLADIN, Species.BRAIXEN, Species.FROGADIER, Species.DARTRIX, Species.TORRACAT, Species.BRIONNE, Species.THWACKEY, Species.RABOOT, Species.DRIZZILE, Species.FLORAGATO, Species.CROCALOR, Species.QUAXWELL ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOTTO, Species.HOOTHOOT, Species.TAILLOW, Species.STARAVIA, Species.TRANQUILL, Species.FLETCHINDER, Species.TRUMBEAK, Species.CORVISQUIRE, Species.WATTREL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOTTO, Species.HOOTHOOT, Species.TAILLOW, Species.STARAVIA, Species.TRANQUILL, Species.FLETCHINDER, Species.TRUMBEAK, Species.CORVISQUIRE, Species.WATTREL ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)), .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)),
[TrainerType.RIVAL_3]: new TrainerConfig(++t).setName('Finn').setHasGenders('Ivy').setHasCharSprite().setTitle('Rival').setStaticParty().setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival').setPartyTemplates(trainerPartyTemplates.RIVAL_3) [TrainerType.RIVAL_3]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_3)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
.setSpeciesFilter(species => species.baseTotal >= 540), .setSpeciesFilter(species => species.baseTotal >= 540),
[TrainerType.RIVAL_4]: new TrainerConfig(++t).setName('Finn').setHasGenders('Ivy').setHasCharSprite().setTitle('Rival').setBoss().setStaticParty().setMoneyMultiplier(1.75).setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival_2').setPartyTemplates(trainerPartyTemplates.RIVAL_4) [TrainerType.RIVAL_4]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(1.75).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_2").setPartyTemplates(trainerPartyTemplates.RIVAL_4)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
@ -995,7 +1008,7 @@ export const trainerConfigs: TrainerConfigs = {
const starter = party[0]; const starter = party[0];
return [ modifierTypes.TERA_SHARD().generateType(null, [ starter.species.type1 ]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; return [ modifierTypes.TERA_SHARD().generateType(null, [ starter.species.type1 ]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ];
}), }),
[TrainerType.RIVAL_5]: new TrainerConfig(++t).setName('Finn').setHasGenders('Ivy').setHasCharSprite().setTitle('Rival').setBoss().setStaticParty().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival_3').setPartyTemplates(trainerPartyTemplates.RIVAL_5) [TrainerType.RIVAL_5]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_5)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true, .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true,
p => p.setBoss(true, 2))) p => p.setBoss(true, 2)))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true))
@ -1011,7 +1024,7 @@ export const trainerConfigs: TrainerConfigs = {
const starter = party[0]; const starter = party[0];
return [ modifierTypes.TERA_SHARD().generateType(null, [ starter.species.type1 ]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; return [ modifierTypes.TERA_SHARD().generateType(null, [ starter.species.type1 ]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ];
}), }),
[TrainerType.RIVAL_6]: new TrainerConfig(++t).setName('Finn').setHasGenders('Ivy').setHasCharSprite().setTitle('Rival').setBoss().setStaticParty().setMoneyMultiplier(3).setEncounterBgm('final').setBattleBgm('battle_rival_3').setPartyTemplates(trainerPartyTemplates.RIVAL_6) [TrainerType.RIVAL_6]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(3).setEncounterBgm("final").setBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_6)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true, .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true,
p => { p => {
p.setBoss(true, 3); p.setBoss(true, 3);

View File

@ -6,7 +6,7 @@ class TrainerNameConfig {
public femaleUrls: string[]; public femaleUrls: string[];
constructor(type: TrainerType, ...urls: string[]) { constructor(type: TrainerType, ...urls: string[]) {
this.urls = urls.length ? urls : [ Utils.toReadableString(TrainerType[type]).replace(/ /g, '_') ]; this.urls = urls.length ? urls : [ Utils.toReadableString(TrainerType[type]).replace(/ /g, "_") ];
} }
hasGenderVariant(...femaleUrls: string[]): TrainerNameConfig { hasGenderVariant(...femaleUrls: string[]): TrainerNameConfig {
@ -19,6 +19,8 @@ interface TrainerNameConfigs {
[key: integer]: TrainerNameConfig [key: integer]: TrainerNameConfig
} }
// used in a commented code
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const trainerNameConfigs: TrainerNameConfigs = { const trainerNameConfigs: TrainerNameConfigs = {
[TrainerType.ACE_TRAINER]: new TrainerNameConfig(TrainerType.ACE_TRAINER), [TrainerType.ACE_TRAINER]: new TrainerNameConfig(TrainerType.ACE_TRAINER),
[TrainerType.ARTIST]: new TrainerNameConfig(TrainerType.ARTIST), [TrainerType.ARTIST]: new TrainerNameConfig(TrainerType.ARTIST),
@ -27,13 +29,13 @@ const trainerNameConfigs: TrainerNameConfigs = {
[TrainerType.BAKER]: new TrainerNameConfig(TrainerType.BAKER), [TrainerType.BAKER]: new TrainerNameConfig(TrainerType.BAKER),
[TrainerType.BEAUTY]: new TrainerNameConfig(TrainerType.BEAUTY), [TrainerType.BEAUTY]: new TrainerNameConfig(TrainerType.BEAUTY),
[TrainerType.BIKER]: new TrainerNameConfig(TrainerType.BIKER), [TrainerType.BIKER]: new TrainerNameConfig(TrainerType.BIKER),
[TrainerType.BLACK_BELT]: new TrainerNameConfig(TrainerType.BLACK_BELT).hasGenderVariant('Battle_Girl'), [TrainerType.BLACK_BELT]: new TrainerNameConfig(TrainerType.BLACK_BELT).hasGenderVariant("Battle_Girl"),
[TrainerType.BREEDER]: new TrainerNameConfig(TrainerType.BREEDER, 'Pokémon_Breeder'), [TrainerType.BREEDER]: new TrainerNameConfig(TrainerType.BREEDER, "Pokémon_Breeder"),
[TrainerType.CLERK]: new TrainerNameConfig(TrainerType.CLERK), [TrainerType.CLERK]: new TrainerNameConfig(TrainerType.CLERK),
[TrainerType.CYCLIST]: new TrainerNameConfig(TrainerType.CYCLIST), [TrainerType.CYCLIST]: new TrainerNameConfig(TrainerType.CYCLIST),
[TrainerType.DANCER]: new TrainerNameConfig(TrainerType.DANCER), [TrainerType.DANCER]: new TrainerNameConfig(TrainerType.DANCER),
[TrainerType.DEPOT_AGENT]: new TrainerNameConfig(TrainerType.DEPOT_AGENT), [TrainerType.DEPOT_AGENT]: new TrainerNameConfig(TrainerType.DEPOT_AGENT),
[TrainerType.DOCTOR]: new TrainerNameConfig(TrainerType.DOCTOR).hasGenderVariant('Nurse'), [TrainerType.DOCTOR]: new TrainerNameConfig(TrainerType.DOCTOR).hasGenderVariant("Nurse"),
[TrainerType.FISHERMAN]: new TrainerNameConfig(TrainerType.FISHERMAN), [TrainerType.FISHERMAN]: new TrainerNameConfig(TrainerType.FISHERMAN),
[TrainerType.GUITARIST]: new TrainerNameConfig(TrainerType.GUITARIST), [TrainerType.GUITARIST]: new TrainerNameConfig(TrainerType.GUITARIST),
[TrainerType.HARLEQUIN]: new TrainerNameConfig(TrainerType.HARLEQUIN), [TrainerType.HARLEQUIN]: new TrainerNameConfig(TrainerType.HARLEQUIN),
@ -50,24 +52,24 @@ const trainerNameConfigs: TrainerNameConfigs = {
[TrainerType.OFFICER]: new TrainerNameConfig(TrainerType.OFFICER), [TrainerType.OFFICER]: new TrainerNameConfig(TrainerType.OFFICER),
[TrainerType.PARASOL_LADY]: new TrainerNameConfig(TrainerType.PARASOL_LADY), [TrainerType.PARASOL_LADY]: new TrainerNameConfig(TrainerType.PARASOL_LADY),
[TrainerType.PILOT]: new TrainerNameConfig(TrainerType.PILOT), [TrainerType.PILOT]: new TrainerNameConfig(TrainerType.PILOT),
[TrainerType.POKEFAN]: new TrainerNameConfig(TrainerType.POKEFAN, 'Poké_Fan'), [TrainerType.POKEFAN]: new TrainerNameConfig(TrainerType.POKEFAN, "Poké_Fan"),
[TrainerType.PRESCHOOLER]: new TrainerNameConfig(TrainerType.PRESCHOOLER), [TrainerType.PRESCHOOLER]: new TrainerNameConfig(TrainerType.PRESCHOOLER),
[TrainerType.PSYCHIC]: new TrainerNameConfig(TrainerType.PSYCHIC), [TrainerType.PSYCHIC]: new TrainerNameConfig(TrainerType.PSYCHIC),
[TrainerType.RANGER]: new TrainerNameConfig(TrainerType.RANGER), [TrainerType.RANGER]: new TrainerNameConfig(TrainerType.RANGER),
[TrainerType.RICH]: new TrainerNameConfig(TrainerType.RICH, 'Gentleman').hasGenderVariant('Madame'), [TrainerType.RICH]: new TrainerNameConfig(TrainerType.RICH, "Gentleman").hasGenderVariant("Madame"),
[TrainerType.RICH_KID]: new TrainerNameConfig(TrainerType.RICH_KID, 'Rich_Boy').hasGenderVariant('Lady'), [TrainerType.RICH_KID]: new TrainerNameConfig(TrainerType.RICH_KID, "Rich_Boy").hasGenderVariant("Lady"),
[TrainerType.ROUGHNECK]: new TrainerNameConfig(TrainerType.ROUGHNECK), [TrainerType.ROUGHNECK]: new TrainerNameConfig(TrainerType.ROUGHNECK),
[TrainerType.SCIENTIST]: new TrainerNameConfig(TrainerType.SCIENTIST), [TrainerType.SCIENTIST]: new TrainerNameConfig(TrainerType.SCIENTIST),
[TrainerType.SMASHER]: new TrainerNameConfig(TrainerType.SMASHER), [TrainerType.SMASHER]: new TrainerNameConfig(TrainerType.SMASHER),
[TrainerType.SNOW_WORKER]: new TrainerNameConfig(TrainerType.SNOW_WORKER, 'Worker'), [TrainerType.SNOW_WORKER]: new TrainerNameConfig(TrainerType.SNOW_WORKER, "Worker"),
[TrainerType.STRIKER]: new TrainerNameConfig(TrainerType.STRIKER), [TrainerType.STRIKER]: new TrainerNameConfig(TrainerType.STRIKER),
[TrainerType.SCHOOL_KID]: new TrainerNameConfig(TrainerType.SCHOOL_KID, 'School_Kid'), [TrainerType.SCHOOL_KID]: new TrainerNameConfig(TrainerType.SCHOOL_KID, "School_Kid"),
[TrainerType.SWIMMER]: new TrainerNameConfig(TrainerType.SWIMMER), [TrainerType.SWIMMER]: new TrainerNameConfig(TrainerType.SWIMMER),
[TrainerType.TWINS]: new TrainerNameConfig(TrainerType.TWINS), [TrainerType.TWINS]: new TrainerNameConfig(TrainerType.TWINS),
[TrainerType.VETERAN]: new TrainerNameConfig(TrainerType.VETERAN), [TrainerType.VETERAN]: new TrainerNameConfig(TrainerType.VETERAN),
[TrainerType.WAITER]: new TrainerNameConfig(TrainerType.WAITER).hasGenderVariant('Waitress'), [TrainerType.WAITER]: new TrainerNameConfig(TrainerType.WAITER).hasGenderVariant("Waitress"),
[TrainerType.WORKER]: new TrainerNameConfig(TrainerType.WORKER), [TrainerType.WORKER]: new TrainerNameConfig(TrainerType.WORKER),
[TrainerType.YOUNGSTER]: new TrainerNameConfig(TrainerType.YOUNGSTER).hasGenderVariant('Lass') [TrainerType.YOUNGSTER]: new TrainerNameConfig(TrainerType.YOUNGSTER).hasGenderVariant("Lass")
}; };
export const trainerNamePools = { export const trainerNamePools = {
@ -121,36 +123,41 @@ export const trainerNamePools = {
[TrainerType.HEX_MANIAC]: ["Kindra","Patricia","Tammy","Tasha","Valerie","Alaina","Kathleen","Leah","Makie","Sylvia","Anina","Arachna","Carrie","Desdemona","Josette","Luna","Melanie","Osanna","Raziah"], [TrainerType.HEX_MANIAC]: ["Kindra","Patricia","Tammy","Tasha","Valerie","Alaina","Kathleen","Leah","Makie","Sylvia","Anina","Arachna","Carrie","Desdemona","Josette","Luna","Melanie","Osanna","Raziah"],
}; };
// function used in a commented code
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function fetchAndPopulateTrainerNames(url: string, parser: DOMParser, trainerNames: Set<string>, femaleTrainerNames: Set<string>, forceFemale: boolean = false) { function fetchAndPopulateTrainerNames(url: string, parser: DOMParser, trainerNames: Set<string>, femaleTrainerNames: Set<string>, forceFemale: boolean = false) {
return new Promise<void>(resolve => { return new Promise<void>(resolve => {
fetch(`https://bulbapedia.bulbagarden.net/wiki/${url}_(Trainer_class)`) fetch(`https://bulbapedia.bulbagarden.net/wiki/${url}_(Trainer_class)`)
.then(response => response.text()) .then(response => response.text())
.then(html => { .then(html => {
console.log(url); console.log(url);
const htmlDoc = parser.parseFromString(html, 'text/html'); const htmlDoc = parser.parseFromString(html, "text/html");
const trainerListHeader = htmlDoc.querySelector('#Trainer_list').parentElement; const trainerListHeader = htmlDoc.querySelector("#Trainer_list").parentElement;
const elements = [...trainerListHeader.parentElement.childNodes]; const elements = [...trainerListHeader.parentElement.childNodes];
const startChildIndex = elements.indexOf(trainerListHeader); const startChildIndex = elements.indexOf(trainerListHeader);
const endChildIndex = elements.findIndex(h => h.nodeName === 'H2' && elements.indexOf(h) > startChildIndex); const endChildIndex = elements.findIndex(h => h.nodeName === "H2" && elements.indexOf(h) > startChildIndex);
const tables = elements.filter(t => { const tables = elements.filter(t => {
if (t.nodeName !== 'TABLE' || t['className'] !== 'expandable') if (t.nodeName !== "TABLE" || t["className"] !== "expandable") {
return false; return false;
}
const childIndex = elements.indexOf(t); const childIndex = elements.indexOf(t);
return childIndex > startChildIndex && childIndex < endChildIndex; return childIndex > startChildIndex && childIndex < endChildIndex;
}).map(t => t as Element); }).map(t => t as Element);
console.log(url, tables) console.log(url, tables);
for (let table of tables) { for (const table of tables) {
const trainerRows = [...table.querySelectorAll('tr:not(:first-child)')].filter(r => r.children.length === 9); const trainerRows = [...table.querySelectorAll("tr:not(:first-child)")].filter(r => r.children.length === 9);
for (let row of trainerRows) { for (const row of trainerRows) {
const nameCell = row.firstElementChild; const nameCell = row.firstElementChild;
const content = nameCell.innerHTML; const content = nameCell.innerHTML;
if (content.indexOf(' <a ') > -1) { if (content.indexOf(" <a ") > -1) {
const female = /♀/.test(content); const female = /♀/.test(content);
if (url === 'Twins') if (url === "Twins") {
console.log(content) console.log(content);
}
const nameMatch = />([a-z]+(?: &amp; [a-z]+)?)<\/a>/i.exec(content); const nameMatch = />([a-z]+(?: &amp; [a-z]+)?)<\/a>/i.exec(content);
if (nameMatch) if (nameMatch) {
(female || forceFemale ? femaleTrainerNames : trainerNames).add(nameMatch[1].replace('&amp;', '&')); (female || forceFemale ? femaleTrainerNames : trainerNames).add(nameMatch[1].replace("&amp;", "&"));
}
} }
} }
} }

View File

@ -19,13 +19,14 @@ export enum Type {
DARK, DARK,
FAIRY, FAIRY,
STELLAR STELLAR
}; }
export type TypeDamageMultiplier = 0 | 0.125 | 0.25 | 0.5 | 1 | 2 | 4 | 8; export type TypeDamageMultiplier = 0 | 0.125 | 0.25 | 0.5 | 1 | 2 | 4 | 8;
export function getTypeDamageMultiplier(attackType: integer, defType: integer): TypeDamageMultiplier { export function getTypeDamageMultiplier(attackType: integer, defType: integer): TypeDamageMultiplier {
if (attackType === Type.UNKNOWN || defType === Type.UNKNOWN) if (attackType === Type.UNKNOWN || defType === Type.UNKNOWN) {
return 1; return 1;
}
switch (defType) { switch (defType) {
case Type.NORMAL: case Type.NORMAL:

View File

@ -32,10 +32,12 @@ export class Weather {
} }
lapse(): boolean { lapse(): boolean {
if (this.isImmutable()) if (this.isImmutable()) {
return true; return true;
if (this.turnsLeft) }
if (this.turnsLeft) {
return !!--this.turnsLeft; return !!--this.turnsLeft;
}
return true; return true;
} }
@ -76,17 +78,21 @@ export class Weather {
switch (this.weatherType) { switch (this.weatherType) {
case WeatherType.SUNNY: case WeatherType.SUNNY:
case WeatherType.HARSH_SUN: case WeatherType.HARSH_SUN:
if (attackType === Type.FIRE) if (attackType === Type.FIRE) {
return 1.5; return 1.5;
if (attackType === Type.WATER) }
if (attackType === Type.WATER) {
return 0.5; return 0.5;
}
break; break;
case WeatherType.RAIN: case WeatherType.RAIN:
case WeatherType.HEAVY_RAIN: case WeatherType.HEAVY_RAIN:
if (attackType === Type.FIRE) if (attackType === Type.FIRE) {
return 0.5; return 0.5;
if (attackType === Type.WATER) }
if (attackType === Type.WATER) {
return 1.5; return 1.5;
}
break; break;
} }
@ -107,13 +113,15 @@ export class Weather {
isEffectSuppressed(scene: BattleScene): boolean { isEffectSuppressed(scene: BattleScene): boolean {
const field = scene.getField(true); const field = scene.getField(true);
for (let pokemon of field) { for (const pokemon of field) {
let suppressWeatherEffectAbAttr = pokemon.getAbility().getAttrs(SuppressWeatherEffectAbAttr).find(() => true) as SuppressWeatherEffectAbAttr; let suppressWeatherEffectAbAttr = pokemon.getAbility().getAttrs(SuppressWeatherEffectAbAttr).find(() => true) as SuppressWeatherEffectAbAttr;
if (!suppressWeatherEffectAbAttr) if (!suppressWeatherEffectAbAttr) {
suppressWeatherEffectAbAttr = pokemon.hasPassive() ? pokemon.getPassiveAbility().getAttrs(SuppressWeatherEffectAbAttr).find(() => true) as SuppressWeatherEffectAbAttr : null; suppressWeatherEffectAbAttr = pokemon.hasPassive() ? pokemon.getPassiveAbility().getAttrs(SuppressWeatherEffectAbAttr).find(() => true) as SuppressWeatherEffectAbAttr : null;
if (suppressWeatherEffectAbAttr && (!this.isImmutable() || suppressWeatherEffectAbAttr.affectsImmutable)) }
if (suppressWeatherEffectAbAttr && (!this.isImmutable() || suppressWeatherEffectAbAttr.affectsImmutable)) {
return true; return true;
} }
}
return false; return false;
} }
@ -122,23 +130,23 @@ export class Weather {
export function getWeatherStartMessage(weatherType: WeatherType): string { export function getWeatherStartMessage(weatherType: WeatherType): string {
switch (weatherType) { switch (weatherType) {
case WeatherType.SUNNY: case WeatherType.SUNNY:
return i18next.t('weather:sunnyStartMessage'); return i18next.t("weather:sunnyStartMessage");
case WeatherType.RAIN: case WeatherType.RAIN:
return i18next.t('weather:rainStartMessage'); return i18next.t("weather:rainStartMessage");
case WeatherType.SANDSTORM: case WeatherType.SANDSTORM:
return i18next.t('weather:sandstormStartMessage'); return i18next.t("weather:sandstormStartMessage");
case WeatherType.HAIL: case WeatherType.HAIL:
return i18next.t('weather:hailStartMessage'); return i18next.t("weather:hailStartMessage");
case WeatherType.SNOW: case WeatherType.SNOW:
return i18next.t('weather:snowStartMessage'); return i18next.t("weather:snowStartMessage");
case WeatherType.FOG: case WeatherType.FOG:
return i18next.t('weather:fogStartMessage'); return i18next.t("weather:fogStartMessage");
case WeatherType.HEAVY_RAIN: case WeatherType.HEAVY_RAIN:
return i18next.t('weather:heavyRainStartMessage'); return i18next.t("weather:heavyRainStartMessage");
case WeatherType.HARSH_SUN: case WeatherType.HARSH_SUN:
return i18next.t('weather:harshSunStartMessage'); return i18next.t("weather:harshSunStartMessage");
case WeatherType.STRONG_WINDS: case WeatherType.STRONG_WINDS:
return i18next.t('weather:strongWindsStartMessage'); return i18next.t("weather:strongWindsStartMessage");
} }
return null; return null;
@ -147,23 +155,23 @@ export function getWeatherStartMessage(weatherType: WeatherType): string {
export function getWeatherLapseMessage(weatherType: WeatherType): string { export function getWeatherLapseMessage(weatherType: WeatherType): string {
switch (weatherType) { switch (weatherType) {
case WeatherType.SUNNY: case WeatherType.SUNNY:
return i18next.t('weather:sunnyLapseMessage'); return i18next.t("weather:sunnyLapseMessage");
case WeatherType.RAIN: case WeatherType.RAIN:
return i18next.t('weather:rainLapseMessage'); return i18next.t("weather:rainLapseMessage");
case WeatherType.SANDSTORM: case WeatherType.SANDSTORM:
return i18next.t('weather:sandstormLapseMessage'); return i18next.t("weather:sandstormLapseMessage");
case WeatherType.HAIL: case WeatherType.HAIL:
return i18next.t('weather:hailLapseMessage'); return i18next.t("weather:hailLapseMessage");
case WeatherType.SNOW: case WeatherType.SNOW:
return i18next.t('weather:snowLapseMessage'); return i18next.t("weather:snowLapseMessage");
case WeatherType.FOG: case WeatherType.FOG:
return i18next.t('weather:fogLapseMessage'); return i18next.t("weather:fogLapseMessage");
case WeatherType.HEAVY_RAIN: case WeatherType.HEAVY_RAIN:
return i18next.t('weather:heavyRainLapseMessage'); return i18next.t("weather:heavyRainLapseMessage");
case WeatherType.HARSH_SUN: case WeatherType.HARSH_SUN:
return i18next.t('weather:harshSunLapseMessage'); return i18next.t("weather:harshSunLapseMessage");
case WeatherType.STRONG_WINDS: case WeatherType.STRONG_WINDS:
return i18next.t('weather:strongWindsLapseMessage'); return i18next.t("weather:strongWindsLapseMessage");
} }
return null; return null;
@ -172,9 +180,9 @@ export function getWeatherLapseMessage(weatherType: WeatherType): string {
export function getWeatherDamageMessage(weatherType: WeatherType, pokemon: Pokemon): string { export function getWeatherDamageMessage(weatherType: WeatherType, pokemon: Pokemon): string {
switch (weatherType) { switch (weatherType) {
case WeatherType.SANDSTORM: case WeatherType.SANDSTORM:
return i18next.t('weather:sandstormDamageMessage', {pokemonPrefix: getPokemonPrefix(pokemon), pokemonName: pokemon.name}); return i18next.t("weather:sandstormDamageMessage", {pokemonPrefix: getPokemonPrefix(pokemon), pokemonName: pokemon.name});
case WeatherType.HAIL: case WeatherType.HAIL:
return i18next.t('weather:hailDamageMessage', {pokemonPrefix: getPokemonPrefix(pokemon), pokemonName: pokemon.name}); return i18next.t("weather:hailDamageMessage", {pokemonPrefix: getPokemonPrefix(pokemon), pokemonName: pokemon.name});
} }
return null; return null;
@ -183,23 +191,23 @@ export function getWeatherDamageMessage(weatherType: WeatherType, pokemon: Pokem
export function getWeatherClearMessage(weatherType: WeatherType): string { export function getWeatherClearMessage(weatherType: WeatherType): string {
switch (weatherType) { switch (weatherType) {
case WeatherType.SUNNY: case WeatherType.SUNNY:
return i18next.t('weather:sunnyClearMessage'); return i18next.t("weather:sunnyClearMessage");
case WeatherType.RAIN: case WeatherType.RAIN:
return i18next.t('weather:rainClearMessage'); return i18next.t("weather:rainClearMessage");
case WeatherType.SANDSTORM: case WeatherType.SANDSTORM:
return i18next.t('weather:sandstormClearMessage'); return i18next.t("weather:sandstormClearMessage");
case WeatherType.HAIL: case WeatherType.HAIL:
return i18next.t('weather:hailClearMessage'); return i18next.t("weather:hailClearMessage");
case WeatherType.SNOW: case WeatherType.SNOW:
return i18next.t('weather:snowClearMessage'); return i18next.t("weather:snowClearMessage");
case WeatherType.FOG: case WeatherType.FOG:
return i18next.t('weather:fogClearMessage'); return i18next.t("weather:fogClearMessage");
case WeatherType.HEAVY_RAIN: case WeatherType.HEAVY_RAIN:
return i18next.t('weather:heavyRainClearMessage'); return i18next.t("weather:heavyRainClearMessage");
case WeatherType.HARSH_SUN: case WeatherType.HARSH_SUN:
return i18next.t('weather:harshSunClearMessage'); return i18next.t("weather:harshSunClearMessage");
case WeatherType.STRONG_WINDS: case WeatherType.STRONG_WINDS:
return i18next.t('weather:strongWindsClearMessage'); return i18next.t("weather:strongWindsClearMessage");
} }
return null; return null;
@ -208,32 +216,33 @@ export function getWeatherClearMessage(weatherType: WeatherType): string {
export function getTerrainStartMessage(terrainType: TerrainType): string { export function getTerrainStartMessage(terrainType: TerrainType): string {
switch (terrainType) { switch (terrainType) {
case TerrainType.MISTY: case TerrainType.MISTY:
return 'Mist swirled around the battlefield!'; return "Mist swirled around the battlefield!";
case TerrainType.ELECTRIC: case TerrainType.ELECTRIC:
return 'An electric current ran across the battlefield!'; return "An electric current ran across the battlefield!";
case TerrainType.GRASSY: case TerrainType.GRASSY:
return 'Grass grew to cover the battlefield!'; return "Grass grew to cover the battlefield!";
case TerrainType.PSYCHIC: case TerrainType.PSYCHIC:
return 'The battlefield got weird!'; return "The battlefield got weird!";
} }
} }
export function getTerrainClearMessage(terrainType: TerrainType): string { export function getTerrainClearMessage(terrainType: TerrainType): string {
switch (terrainType) { switch (terrainType) {
case TerrainType.MISTY: case TerrainType.MISTY:
return 'The mist disappeared from the battlefield.'; return "The mist disappeared from the battlefield.";
case TerrainType.ELECTRIC: case TerrainType.ELECTRIC:
return 'The electricity disappeared from the battlefield.'; return "The electricity disappeared from the battlefield.";
case TerrainType.GRASSY: case TerrainType.GRASSY:
return 'The grass disappeared from the battlefield.'; return "The grass disappeared from the battlefield.";
case TerrainType.PSYCHIC: case TerrainType.PSYCHIC:
return 'The weirdness disappeared from the battlefield!'; return "The weirdness disappeared from the battlefield!";
} }
} }
export function getTerrainBlockMessage(pokemon: Pokemon, terrainType: TerrainType): string { export function getTerrainBlockMessage(pokemon: Pokemon, terrainType: TerrainType): string {
if (terrainType === TerrainType.MISTY) if (terrainType === TerrainType.MISTY) {
return getPokemonMessage(pokemon, ` surrounds itself with a protective mist!`); return getPokemonMessage(pokemon, " surrounds itself with a protective mist!");
}
return getPokemonMessage(pokemon, ` is protected by the ${Utils.toReadableString(TerrainType[terrainType])} Terrain!`); return getPokemonMessage(pokemon, ` is protected by the ${Utils.toReadableString(TerrainType[terrainType])} Terrain!`);
} }
@ -250,16 +259,18 @@ export function getRandomWeatherType(arena: any /* Importing from arena causes a
weatherPool = [ weatherPool = [
{ weatherType: WeatherType.NONE, weight: 7 } { weatherType: WeatherType.NONE, weight: 7 }
]; ];
if (hasSun) if (hasSun) {
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 3 }); weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 3 });
}
break; break;
case Biome.TALL_GRASS: case Biome.TALL_GRASS:
weatherPool = [ weatherPool = [
{ weatherType: WeatherType.NONE, weight: 8 }, { weatherType: WeatherType.NONE, weight: 8 },
{ weatherType: WeatherType.RAIN, weight: 5 }, { weatherType: WeatherType.RAIN, weight: 5 },
]; ];
if (hasSun) if (hasSun) {
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 8 }); weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 8 });
}
break; break;
case Biome.FOREST: case Biome.FOREST:
weatherPool = [ weatherPool = [
@ -285,8 +296,9 @@ export function getRandomWeatherType(arena: any /* Importing from arena causes a
{ weatherType: WeatherType.NONE, weight: 8 }, { weatherType: WeatherType.NONE, weight: 8 },
{ weatherType: WeatherType.RAIN, weight: 3 } { weatherType: WeatherType.RAIN, weight: 3 }
]; ];
if (hasSun) if (hasSun) {
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 }); weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 });
}
break; break;
case Biome.LAKE: case Biome.LAKE:
weatherPool = [ weatherPool = [
@ -305,15 +317,17 @@ export function getRandomWeatherType(arena: any /* Importing from arena causes a
{ weatherType: WeatherType.NONE, weight: 8 }, { weatherType: WeatherType.NONE, weight: 8 },
{ weatherType: WeatherType.SANDSTORM, weight: 2 } { weatherType: WeatherType.SANDSTORM, weight: 2 }
]; ];
if (hasSun) if (hasSun) {
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 }); weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 });
}
break; break;
case Biome.DESERT: case Biome.DESERT:
weatherPool = [ weatherPool = [
{ weatherType: WeatherType.SANDSTORM, weight: 2 } { weatherType: WeatherType.SANDSTORM, weight: 2 }
]; ];
if (hasSun) if (hasSun) {
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 }); weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 });
}
break; break;
case Biome.ICE_CAVE: case Biome.ICE_CAVE:
weatherPool = [ weatherPool = [
@ -326,8 +340,9 @@ export function getRandomWeatherType(arena: any /* Importing from arena causes a
weatherPool = [ weatherPool = [
{ weatherType: WeatherType.NONE, weight: 2 } { weatherType: WeatherType.NONE, weight: 2 }
]; ];
if (hasSun) if (hasSun) {
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 }); weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 });
}
case Biome.VOLCANO: case Biome.VOLCANO:
weatherPool = [ weatherPool = [
{ weatherType: hasSun ? WeatherType.SUNNY : WeatherType.NONE, weight: 1 } { weatherType: hasSun ? WeatherType.SUNNY : WeatherType.NONE, weight: 1 }
@ -356,8 +371,9 @@ export function getRandomWeatherType(arena: any /* Importing from arena causes a
{ weatherType: WeatherType.NONE, weight: 5 }, { weatherType: WeatherType.NONE, weight: 5 },
{ weatherType: WeatherType.RAIN, weight: 1 }, { weatherType: WeatherType.RAIN, weight: 1 },
]; ];
if (hasSun) if (hasSun) {
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 }); weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 });
}
break; break;
} }
@ -367,12 +383,13 @@ export function getRandomWeatherType(arena: any /* Importing from arena causes a
const rand = Utils.randSeedInt(totalWeight); const rand = Utils.randSeedInt(totalWeight);
let w = 0; let w = 0;
for (let weather of weatherPool) { for (const weather of weatherPool) {
w += weather.weight; w += weather.weight;
if (rand < w) if (rand < w) {
return weather.weatherType; return weather.weatherType;
} }
} }
}
return weatherPool.length return weatherPool.length
? weatherPool[0].weatherType ? weatherPool[0].weatherType

View File

@ -1,13 +1,15 @@
export function getData() { export function getData() {
const dataStr = localStorage.getItem('data'); const dataStr = localStorage.getItem("data");
if (!dataStr) if (!dataStr) {
return null; return null;
return JSON.parse(atob(dataStr), (k, v) => k.endsWith('Attr') && ![ 'natureAttr', 'abilityAttr', 'passiveAttr' ].includes(k) ? BigInt(v) : v); }
return JSON.parse(atob(dataStr), (k, v) => k.endsWith("Attr") && ![ "natureAttr", "abilityAttr", "passiveAttr" ].includes(k) ? BigInt(v) : v);
} }
export function getSession() { export function getSession() {
const sessionStr = localStorage.getItem('sessionData'); const sessionStr = localStorage.getItem("sessionData");
if (!sessionStr) if (!sessionStr) {
return null; return null;
}
return JSON.parse(atob(sessionStr)); return JSON.parse(atob(sessionStr));
} }

View File

@ -47,13 +47,15 @@ export class EggHatchPhase extends Phase {
this.scene.ui.setModeForceTransition(Mode.EGG_HATCH_SCENE).then(() => { this.scene.ui.setModeForceTransition(Mode.EGG_HATCH_SCENE).then(() => {
if (!this.egg) if (!this.egg) {
return this.end(); return this.end();
}
const eggIndex = this.scene.gameData.eggs.findIndex(e => e.id === this.egg.id); const eggIndex = this.scene.gameData.eggs.findIndex(e => e.id === this.egg.id);
if (eggIndex === -1) if (eggIndex === -1) {
return this.end(); return this.end();
}
this.scene.gameData.eggs.splice(eggIndex, 1); this.scene.gameData.eggs.splice(eggIndex, 1);
@ -63,17 +65,17 @@ export class EggHatchPhase extends Phase {
this.eggHatchContainer = this.eggHatchHandler.eggHatchContainer; this.eggHatchContainer = this.eggHatchHandler.eggHatchContainer;
this.eggHatchBg = this.scene.add.image(0, 0, 'default_bg'); this.eggHatchBg = this.scene.add.image(0, 0, "default_bg");
this.eggHatchBg.setOrigin(0, 0); this.eggHatchBg.setOrigin(0, 0);
this.eggHatchContainer.add(this.eggHatchBg); this.eggHatchContainer.add(this.eggHatchBg);
this.eggContainer = this.scene.add.container(this.eggHatchBg.displayWidth / 2, this.eggHatchBg.displayHeight / 2); this.eggContainer = this.scene.add.container(this.eggHatchBg.displayWidth / 2, this.eggHatchBg.displayHeight / 2);
this.eggSprite = this.scene.add.sprite(0, 0, 'egg', `egg_${this.egg.getKey()}`); this.eggSprite = this.scene.add.sprite(0, 0, "egg", `egg_${this.egg.getKey()}`);
this.eggCrackSprite = this.scene.add.sprite(0, 0, 'egg_crack', '0'); this.eggCrackSprite = this.scene.add.sprite(0, 0, "egg_crack", "0");
this.eggCrackSprite.setVisible(false); this.eggCrackSprite.setVisible(false);
this.eggLightraysOverlay = this.scene.add.sprite((-this.eggHatchBg.displayWidth / 2) + 4, -this.eggHatchBg.displayHeight / 2, 'egg_lightrays', '3'); this.eggLightraysOverlay = this.scene.add.sprite((-this.eggHatchBg.displayWidth / 2) + 4, -this.eggHatchBg.displayHeight / 2, "egg_lightrays", "3");
this.eggLightraysOverlay.setOrigin(0, 0); this.eggLightraysOverlay.setOrigin(0, 0);
this.eggLightraysOverlay.setVisible(false); this.eggLightraysOverlay.setVisible(false);
@ -83,14 +85,14 @@ export class EggHatchPhase extends Phase {
this.eggHatchContainer.add(this.eggContainer); this.eggHatchContainer.add(this.eggContainer);
const getPokemonSprite = () => { const getPokemonSprite = () => {
const ret = this.scene.add.sprite(this.eggHatchBg.displayWidth / 2, this.eggHatchBg.displayHeight / 2, `pkmn__sub`); const ret = this.scene.add.sprite(this.eggHatchBg.displayWidth / 2, this.eggHatchBg.displayHeight / 2, "pkmn__sub");
ret.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true }); ret.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
return ret; return ret;
}; };
this.eggHatchContainer.add((this.pokemonSprite = getPokemonSprite())); this.eggHatchContainer.add((this.pokemonSprite = getPokemonSprite()));
this.pokemonShinySparkle = this.scene.add.sprite(this.pokemonSprite.x, this.pokemonSprite.y, 'shiny'); this.pokemonShinySparkle = this.scene.add.sprite(this.pokemonSprite.x, this.pokemonSprite.y, "shiny");
this.pokemonShinySparkle.setVisible(false); this.pokemonShinySparkle.setVisible(false);
this.eggHatchContainer.add(this.pokemonShinySparkle); this.eggHatchContainer.add(this.pokemonShinySparkle);
@ -106,8 +108,9 @@ export class EggHatchPhase extends Phase {
this.eggHatchContainer.add(this.infoContainer); this.eggHatchContainer.add(this.infoContainer);
const pokemon = this.generatePokemon(); const pokemon = this.generatePokemon();
if (pokemon.fusionSpecies) if (pokemon.fusionSpecies) {
pokemon.clearFusionSpecies(); pokemon.clearFusionSpecies();
}
this.pokemonSprite.setVisible(false); this.pokemonSprite.setVisible(false);
@ -117,41 +120,48 @@ export class EggHatchPhase extends Phase {
this.canSkip = true; this.canSkip = true;
this.scene.time.delayedCall(1000, () => { this.scene.time.delayedCall(1000, () => {
if (!this.hatched) if (!this.hatched) {
this.evolutionBgm = this.scene.playSoundWithoutBgm('evolution'); this.evolutionBgm = this.scene.playSoundWithoutBgm("evolution");
}
}); });
this.scene.time.delayedCall(2000, () => { this.scene.time.delayedCall(2000, () => {
if (this.hatched) if (this.hatched) {
return; return;
}
this.eggCrackSprite.setVisible(true); this.eggCrackSprite.setVisible(true);
this.doSpray(1, this.eggSprite.displayHeight / -2); this.doSpray(1, this.eggSprite.displayHeight / -2);
this.doEggShake(2).then(() => { this.doEggShake(2).then(() => {
if (this.hatched) if (this.hatched) {
return; return;
}
this.scene.time.delayedCall(1000, () => { this.scene.time.delayedCall(1000, () => {
if (this.hatched) if (this.hatched) {
return; return;
}
this.doSpray(2, this.eggSprite.displayHeight / -4); this.doSpray(2, this.eggSprite.displayHeight / -4);
this.eggCrackSprite.setFrame('1'); this.eggCrackSprite.setFrame("1");
this.scene.time.delayedCall(125, () => this.eggCrackSprite.setFrame('2')); this.scene.time.delayedCall(125, () => this.eggCrackSprite.setFrame("2"));
this.doEggShake(4).then(() => { this.doEggShake(4).then(() => {
if (this.hatched) if (this.hatched) {
return; return;
}
this.scene.time.delayedCall(1000, () => { this.scene.time.delayedCall(1000, () => {
if (this.hatched) if (this.hatched) {
return; return;
this.scene.playSound('egg_crack'); }
this.scene.playSound("egg_crack");
this.doSpray(4); this.doSpray(4);
this.eggCrackSprite.setFrame('3'); this.eggCrackSprite.setFrame("3");
this.scene.time.delayedCall(125, () => this.eggCrackSprite.setFrame('4')); this.scene.time.delayedCall(125, () => this.eggCrackSprite.setFrame("4"));
this.doEggShake(8, 2).then(() => { this.doEggShake(8, 2).then(() => {
if (!this.hatched) if (!this.hatched) {
this.doHatch(); this.doHatch();
}
});
}); });
}); });
}); });
})
}); });
}); });
}); });
@ -159,74 +169,82 @@ export class EggHatchPhase extends Phase {
} }
end() { end() {
if (this.scene.findPhase((p) => p instanceof EggHatchPhase)) if (this.scene.findPhase((p) => p instanceof EggHatchPhase)) {
this.eggHatchHandler.clear(); this.eggHatchHandler.clear();
else } else {
this.scene.time.delayedCall(250, () => this.scene.setModifiersVisible(true)); this.scene.time.delayedCall(250, () => this.scene.setModifiersVisible(true));
}
super.end(); super.end();
} }
doEggShake(intensity: number, repeatCount?: integer, count?: integer): Promise<void> { doEggShake(intensity: number, repeatCount?: integer, count?: integer): Promise<void> {
return new Promise(resolve => { return new Promise(resolve => {
if (repeatCount === undefined) if (repeatCount === undefined) {
repeatCount = 0; repeatCount = 0;
if (count === undefined) }
if (count === undefined) {
count = 0; count = 0;
this.scene.playSound('pb_move'); }
this.scene.playSound("pb_move");
this.scene.tweens.add({ this.scene.tweens.add({
targets: this.eggContainer, targets: this.eggContainer,
x: `-=${intensity / (count ? 1 : 2)}`, x: `-=${intensity / (count ? 1 : 2)}`,
ease: 'Sine.easeInOut', ease: "Sine.easeInOut",
duration: 125, duration: 125,
onComplete: () => { onComplete: () => {
this.scene.tweens.add({ this.scene.tweens.add({
targets: this.eggContainer, targets: this.eggContainer,
x: `+=${intensity}`, x: `+=${intensity}`,
ease: 'Sine.easeInOut', ease: "Sine.easeInOut",
duration: 250, duration: 250,
onComplete: () => { onComplete: () => {
count++; count++;
if (count < repeatCount) if (count < repeatCount) {
return this.doEggShake(intensity, repeatCount, count).then(() => resolve()); return this.doEggShake(intensity, repeatCount, count).then(() => resolve());
}
this.scene.tweens.add({ this.scene.tweens.add({
targets: this.eggContainer, targets: this.eggContainer,
x: `-=${intensity / 2}`, x: `-=${intensity / 2}`,
ease: 'Sine.easeInOut', ease: "Sine.easeInOut",
duration: 125, duration: 125,
onComplete: () => resolve() onComplete: () => resolve()
}); });
} }
}) });
} }
}); });
}); });
} }
trySkip(): boolean { trySkip(): boolean {
if (!this.canSkip || this.skipped) if (!this.canSkip || this.skipped) {
return false; return false;
}
this.skipped = true; this.skipped = true;
if (!this.hatched) if (!this.hatched) {
this.doHatch(); this.doHatch();
else } else {
this.doReveal(); this.doReveal();
}
return true; return true;
} }
doHatch(): void { doHatch(): void {
this.canSkip = false; this.canSkip = false;
this.hatched = true; this.hatched = true;
if (this.evolutionBgm) if (this.evolutionBgm) {
SoundFade.fadeOut(this.scene, this.evolutionBgm, Utils.fixedInt(100)); SoundFade.fadeOut(this.scene, this.evolutionBgm, Utils.fixedInt(100));
for (let e = 0; e < 5; e++) }
this.scene.time.delayedCall(Utils.fixedInt(375 * e), () => this.scene.playSound('egg_hatch', { volume: 1 - (e * 0.2) })); for (let e = 0; e < 5; e++) {
this.scene.time.delayedCall(Utils.fixedInt(375 * e), () => this.scene.playSound("egg_hatch", { volume: 1 - (e * 0.2) }));
}
this.eggLightraysOverlay.setVisible(true); this.eggLightraysOverlay.setVisible(true);
this.eggLightraysOverlay.play('egg_lightrays'); this.eggLightraysOverlay.play("egg_lightrays");
this.scene.tweens.add({ this.scene.tweens.add({
duration: Utils.fixedInt(125), duration: Utils.fixedInt(125),
targets: this.eggHatchOverlay, targets: this.eggHatchOverlay,
alpha: 1, alpha: 1,
ease: 'Cubic.easeIn', ease: "Cubic.easeIn",
onComplete: () => { onComplete: () => {
this.skipped = false; this.skipped = false;
this.canSkip = true; this.canSkip = true;
@ -234,40 +252,45 @@ export class EggHatchPhase extends Phase {
}); });
this.scene.time.delayedCall(Utils.fixedInt(1500), () => { this.scene.time.delayedCall(Utils.fixedInt(1500), () => {
this.canSkip = false; this.canSkip = false;
if (!this.skipped) if (!this.skipped) {
this.doReveal(); this.doReveal();
}
}); });
} }
doReveal(): void { doReveal(): void {
const isShiny = this.pokemon.isShiny(); const isShiny = this.pokemon.isShiny();
if (this.pokemon.species.subLegendary) if (this.pokemon.species.subLegendary) {
this.scene.validateAchv(achvs.HATCH_SUB_LEGENDARY); this.scene.validateAchv(achvs.HATCH_SUB_LEGENDARY);
if (this.pokemon.species.legendary) }
if (this.pokemon.species.legendary) {
this.scene.validateAchv(achvs.HATCH_LEGENDARY); this.scene.validateAchv(achvs.HATCH_LEGENDARY);
if (this.pokemon.species.mythical) }
if (this.pokemon.species.mythical) {
this.scene.validateAchv(achvs.HATCH_MYTHICAL); this.scene.validateAchv(achvs.HATCH_MYTHICAL);
if (isShiny) }
if (isShiny) {
this.scene.validateAchv(achvs.HATCH_SHINY); this.scene.validateAchv(achvs.HATCH_SHINY);
}
this.eggContainer.setVisible(false); this.eggContainer.setVisible(false);
this.pokemonSprite.play(this.pokemon.getSpriteKey(true)); this.pokemonSprite.play(this.pokemon.getSpriteKey(true));
this.pokemonSprite.setPipelineData('ignoreTimeTint', true); this.pokemonSprite.setPipelineData("ignoreTimeTint", true);
this.pokemonSprite.setPipelineData('spriteKey', this.pokemon.getSpriteKey()); this.pokemonSprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey());
this.pokemonSprite.setPipelineData('shiny', this.pokemon.shiny); this.pokemonSprite.setPipelineData("shiny", this.pokemon.shiny);
this.pokemonSprite.setPipelineData('variant', this.pokemon.variant); this.pokemonSprite.setPipelineData("variant", this.pokemon.variant);
this.pokemonSprite.setVisible(true); this.pokemonSprite.setVisible(true);
this.scene.time.delayedCall(Utils.fixedInt(250), () => { this.scene.time.delayedCall(Utils.fixedInt(250), () => {
this.pokemon.cry(); this.pokemon.cry();
if (isShiny) { if (isShiny) {
this.scene.time.delayedCall(Utils.fixedInt(500), () => { this.scene.time.delayedCall(Utils.fixedInt(500), () => {
this.pokemonShinySparkle.play(`sparkle${this.pokemon.variant ? `_${this.pokemon.variant + 1}` : ''}`); this.pokemonShinySparkle.play(`sparkle${this.pokemon.variant ? `_${this.pokemon.variant + 1}` : ""}`);
this.scene.playSound('sparkle'); this.scene.playSound("sparkle");
}); });
} }
this.scene.time.delayedCall(Utils.fixedInt(!this.skipped ? !isShiny ? 1250 : 1750 : !isShiny ? 250 : 750), () => { this.scene.time.delayedCall(Utils.fixedInt(!this.skipped ? !isShiny ? 1250 : 1750 : !isShiny ? 250 : 750), () => {
this.infoContainer.show(this.pokemon, false, this.skipped ? 2 : 1); this.infoContainer.show(this.pokemon, false, this.skipped ? 2 : 1);
this.scene.playSoundWithoutBgm('evolution_fanfare'); this.scene.playSoundWithoutBgm("evolution_fanfare");
this.scene.ui.showText(`${this.pokemon.name} hatched from the egg!`, null, () => { this.scene.ui.showText(`${this.pokemon.name} hatched from the egg!`, null, () => {
this.scene.gameData.updateSpeciesDexIvs(this.pokemon.species.speciesId, this.pokemon.ivs); this.scene.gameData.updateSpeciesDexIvs(this.pokemon.species.speciesId, this.pokemon.ivs);
@ -285,7 +308,7 @@ export class EggHatchPhase extends Phase {
duration: Utils.fixedInt(this.skipped ? 500 : 3000), duration: Utils.fixedInt(this.skipped ? 500 : 3000),
targets: this.eggHatchOverlay, targets: this.eggHatchOverlay,
alpha: 0, alpha: 0,
ease: 'Cubic.easeOut' ease: "Cubic.easeOut"
}); });
} }
@ -306,14 +329,14 @@ export class EggHatchPhase extends Phase {
doSprayParticle(trigIndex: integer, offsetY: number) { doSprayParticle(trigIndex: integer, offsetY: number) {
const initialX = this.eggHatchBg.displayWidth / 2; const initialX = this.eggHatchBg.displayWidth / 2;
const initialY = this.eggHatchBg.displayHeight / 2 + offsetY; const initialY = this.eggHatchBg.displayHeight / 2 + offsetY;
const shardKey = !this.egg.isManaphyEgg() ? this.egg.tier.toString() : '1'; const shardKey = !this.egg.isManaphyEgg() ? this.egg.tier.toString() : "1";
const particle = this.scene.add.image(initialX, initialY, 'egg_shard', `${shardKey}_${Math.floor(trigIndex / 2)}`); const particle = this.scene.add.image(initialX, initialY, "egg_shard", `${shardKey}_${Math.floor(trigIndex / 2)}`);
this.eggHatchContainer.add(particle); this.eggHatchContainer.add(particle);
let f = 0; let f = 0;
let yOffset = 0; let yOffset = 0;
let speed = 3 - Utils.randInt(8); const speed = 3 - Utils.randInt(8);
let amp = 24 + Utils.randInt(32); const amp = 24 + Utils.randInt(32);
const particleTimer = this.scene.tweens.addCounter({ const particleTimer = this.scene.tweens.addCounter({
repeat: -1, repeat: -1,
@ -329,8 +352,9 @@ export class EggHatchPhase extends Phase {
if (trigIndex < 160) { if (trigIndex < 160) {
particle.setPosition(initialX + (speed * f) / 3, initialY + yOffset); particle.setPosition(initialX + (speed * f) / 3, initialY + yOffset);
particle.y += -this.sin(trigIndex, amp); particle.y += -this.sin(trigIndex, amp);
if (f > 108) if (f > 108) {
particle.setScale((1 - (f - 108) / 20)); particle.setScale((1 - (f - 108) / 20));
}
trigIndex += 2 * speedMultiplier; trigIndex += 2 * speedMultiplier;
f += speedMultiplier; f += speedMultiplier;
} else { } else {
@ -354,9 +378,10 @@ export class EggHatchPhase extends Phase {
speciesOverride = rand ? Species.PHIONE : Species.MANAPHY; speciesOverride = rand ? Species.PHIONE : Species.MANAPHY;
} else if (this.egg.tier === EggTier.MASTER } else if (this.egg.tier === EggTier.MASTER
&& this.egg.gachaType === GachaType.LEGENDARY) { && this.egg.gachaType === GachaType.LEGENDARY) {
if (!Utils.randSeedInt(2)) if (!Utils.randSeedInt(2)) {
speciesOverride = getLegendaryGachaSpeciesForTimestamp(this.scene, this.egg.timestamp); speciesOverride = getLegendaryGachaSpeciesForTimestamp(this.scene, this.egg.timestamp);
} }
}
if (speciesOverride) { if (speciesOverride) {
const pokemonSpecies = getPokemonSpecies(speciesOverride); const pokemonSpecies = getPokemonSpecies(speciesOverride);
@ -386,18 +411,19 @@ export class EggHatchPhase extends Phase {
const ignoredSpecies = [ Species.PHIONE, Species.MANAPHY, Species.ETERNATUS ]; const ignoredSpecies = [ Species.PHIONE, Species.MANAPHY, Species.ETERNATUS ];
let speciesPool = Object.keys(speciesStarters) const speciesPool = Object.keys(speciesStarters)
.filter(s => speciesStarters[s] >= minStarterValue && speciesStarters[s] <= maxStarterValue) .filter(s => speciesStarters[s] >= minStarterValue && speciesStarters[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);
let totalWeight = 0; let totalWeight = 0;
const speciesWeights = []; const speciesWeights = [];
for (let 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 - speciesStarters[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 / (species.isRareRegional() ? 8 : 2)); weight = Math.floor(weight / (species.isRareRegional() ? 8 : 2));
}
speciesWeights.push(totalWeight + weight); speciesWeights.push(totalWeight + weight);
totalWeight += weight; totalWeight += weight;
} }
@ -422,8 +448,9 @@ export class EggHatchPhase extends Phase {
const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967295)); const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967295));
for (let s = 0; s < ret.ivs.length; s++) for (let s = 0; s < ret.ivs.length; s++) {
ret.ivs[s] = Math.max(ret.ivs[s], secondaryIvs[s]); ret.ivs[s] = Math.max(ret.ivs[s], secondaryIvs[s]);
}
const baseChance = this.egg.gachaType === GachaType.MOVE ? 3 : 6; const baseChance = this.egg.gachaType === GachaType.MOVE ? 3 : 6;
this.eggMoveIndex = Utils.randSeedInt(baseChance * Math.pow(2, 3 - this.egg.tier)) this.eggMoveIndex = Utils.randSeedInt(baseChance * Math.pow(2, 3 - this.egg.tier))

View File

@ -48,8 +48,9 @@ export class EvolutionPhase extends Phase {
this.setMode().then(() => { this.setMode().then(() => {
if (!this.validate()) if (!this.validate()) {
return this.end(); return this.end();
}
this.scene.fadeOutBgm(null, false); this.scene.fadeOutBgm(null, false);
@ -57,11 +58,11 @@ export class EvolutionPhase extends Phase {
this.evolutionContainer = evolutionHandler.evolutionContainer; this.evolutionContainer = evolutionHandler.evolutionContainer;
this.evolutionBaseBg = this.scene.add.image(0, 0, 'default_bg'); this.evolutionBaseBg = this.scene.add.image(0, 0, "default_bg");
this.evolutionBaseBg.setOrigin(0, 0); this.evolutionBaseBg.setOrigin(0, 0);
this.evolutionContainer.add(this.evolutionBaseBg); this.evolutionContainer.add(this.evolutionBaseBg);
this.evolutionBg = this.scene.add.video(0, 0, 'evo_bg').stop(); this.evolutionBg = this.scene.add.video(0, 0, "evo_bg").stop();
this.evolutionBg.setOrigin(0, 0); this.evolutionBg.setOrigin(0, 0);
this.evolutionBg.setScale(0.4359673025); this.evolutionBg.setScale(0.4359673025);
this.evolutionBg.setVisible(false); this.evolutionBg.setVisible(false);
@ -73,7 +74,7 @@ export class EvolutionPhase extends Phase {
this.evolutionContainer.add(this.evolutionBgOverlay); this.evolutionContainer.add(this.evolutionBgOverlay);
const getPokemonSprite = () => { const getPokemonSprite = () => {
const ret = this.scene.addPokemonSprite(this.pokemon, this.evolutionBaseBg.displayWidth / 2, this.evolutionBaseBg.displayHeight / 2, `pkmn__sub`); const ret = this.scene.addPokemonSprite(this.pokemon, this.evolutionBaseBg.displayWidth / 2, this.evolutionBaseBg.displayHeight / 2, "pkmn__sub");
ret.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true }); ret.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
return ret; return ret;
}; };
@ -97,13 +98,14 @@ export class EvolutionPhase extends Phase {
[ this.pokemonSprite, this.pokemonTintSprite, this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => { [ this.pokemonSprite, this.pokemonTintSprite, this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => {
sprite.play(this.pokemon.getSpriteKey(true)); sprite.play(this.pokemon.getSpriteKey(true));
sprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()) }); sprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()) });
sprite.setPipelineData('ignoreTimeTint', true); sprite.setPipelineData("ignoreTimeTint", true);
sprite.setPipelineData('spriteKey', this.pokemon.getSpriteKey()); sprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey());
sprite.setPipelineData('shiny', this.pokemon.shiny); sprite.setPipelineData("shiny", this.pokemon.shiny);
sprite.setPipelineData('variant', this.pokemon.variant); sprite.setPipelineData("variant", this.pokemon.variant);
[ 'spriteColors', 'fusionSpriteColors' ].map(k => { [ "spriteColors", "fusionSpriteColors" ].map(k => {
if (this.pokemon.summonData?.speciesForm) if (this.pokemon.summonData?.speciesForm) {
k += 'Base'; k += "Base";
}
sprite.pipelineData[k] = this.pokemon.getSprite().pipelineData[k]; sprite.pipelineData[k] = this.pokemon.getSprite().pipelineData[k];
}); });
}); });
@ -116,32 +118,33 @@ export class EvolutionPhase extends Phase {
const evolutionHandler = this.scene.ui.getHandler() as EvolutionSceneHandler; const evolutionHandler = this.scene.ui.getHandler() as EvolutionSceneHandler;
const preName = this.pokemon.name; const preName = this.pokemon.name;
this.scene.ui.showText(i18next.t('menu:evolving', { pokemonName: preName }), null, () => { this.scene.ui.showText(i18next.t("menu:evolving", { pokemonName: preName }), null, () => {
this.pokemon.cry(); this.pokemon.cry();
this.pokemon.getPossibleEvolution(this.evolution).then(evolvedPokemon => { this.pokemon.getPossibleEvolution(this.evolution).then(evolvedPokemon => {
[ this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => { [ this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => {
sprite.play(evolvedPokemon.getSpriteKey(true)); sprite.play(evolvedPokemon.getSpriteKey(true));
sprite.setPipelineData('ignoreTimeTint', true); sprite.setPipelineData("ignoreTimeTint", true);
sprite.setPipelineData('spriteKey', evolvedPokemon.getSpriteKey()); sprite.setPipelineData("spriteKey", evolvedPokemon.getSpriteKey());
sprite.setPipelineData('shiny', evolvedPokemon.shiny); sprite.setPipelineData("shiny", evolvedPokemon.shiny);
sprite.setPipelineData('variant', evolvedPokemon.variant); sprite.setPipelineData("variant", evolvedPokemon.variant);
[ 'spriteColors', 'fusionSpriteColors' ].map(k => { [ "spriteColors", "fusionSpriteColors" ].map(k => {
if (evolvedPokemon.summonData?.speciesForm) if (evolvedPokemon.summonData?.speciesForm) {
k += 'Base'; k += "Base";
}
sprite.pipelineData[k] = evolvedPokemon.getSprite().pipelineData[k]; sprite.pipelineData[k] = evolvedPokemon.getSprite().pipelineData[k];
}); });
}); });
this.scene.time.delayedCall(1000, () => { this.scene.time.delayedCall(1000, () => {
const evolutionBgm = this.scene.playSoundWithoutBgm('evolution'); const evolutionBgm = this.scene.playSoundWithoutBgm("evolution");
this.scene.tweens.add({ this.scene.tweens.add({
targets: this.evolutionBgOverlay, targets: this.evolutionBgOverlay,
alpha: 1, alpha: 1,
delay: 500, delay: 500,
duration: 1500, duration: 1500,
ease: 'Sine.easeOut', ease: "Sine.easeOut",
onComplete: () => { onComplete: () => {
this.scene.time.delayedCall(1000, () => { this.scene.time.delayedCall(1000, () => {
this.scene.tweens.add({ this.scene.tweens.add({
@ -152,7 +155,7 @@ export class EvolutionPhase extends Phase {
this.evolutionBg.setVisible(true); this.evolutionBg.setVisible(true);
this.evolutionBg.play(); this.evolutionBg.play();
}); });
this.scene.playSound('charge'); this.scene.playSound("charge");
this.doSpiralUpward(); this.doSpiralUpward();
this.scene.tweens.addCounter({ this.scene.tweens.addCounter({
from: 0, from: 0,
@ -164,7 +167,7 @@ export class EvolutionPhase extends Phase {
onComplete: () => { onComplete: () => {
this.pokemonSprite.setVisible(false); this.pokemonSprite.setVisible(false);
this.scene.time.delayedCall(1100, () => { this.scene.time.delayedCall(1100, () => {
this.scene.playSound('beam'); this.scene.playSound("beam");
this.doArcDownward(); this.doArcDownward();
this.scene.time.delayedCall(1500, () => { this.scene.time.delayedCall(1500, () => {
this.pokemonEvoTintSprite.setScale(0.25); this.pokemonEvoTintSprite.setScale(0.25);
@ -188,8 +191,8 @@ export class EvolutionPhase extends Phase {
this.scene.unshiftPhase(new EndEvolutionPhase(this.scene)); this.scene.unshiftPhase(new EndEvolutionPhase(this.scene));
this.scene.ui.showText(i18next.t('menu:stoppedEvolving', { pokemonName: preName }), null, () => { this.scene.ui.showText(i18next.t("menu:stoppedEvolving", { pokemonName: preName }), null, () => {
this.scene.ui.showText(i18next.t('menu:pauseEvolutionsQuestion', { pokemonName: preName }), null, () => { this.scene.ui.showText(i18next.t("menu:pauseEvolutionsQuestion", { pokemonName: preName }), null, () => {
const end = () => { const end = () => {
this.scene.ui.showText(null, 0); this.scene.ui.showText(null, 0);
this.scene.playBgm(); this.scene.playBgm();
@ -199,7 +202,7 @@ export class EvolutionPhase extends Phase {
this.scene.ui.setOverlayMode(Mode.CONFIRM, () => { this.scene.ui.setOverlayMode(Mode.CONFIRM, () => {
this.scene.ui.revertMode(); this.scene.ui.revertMode();
this.pokemon.pauseEvolutions = true; this.pokemon.pauseEvolutions = true;
this.scene.ui.showText(i18next.t('menu:evolutionsPaused', { pokemonName: preName }), null, end, 3000); this.scene.ui.showText(i18next.t("menu:evolutionsPaused", { pokemonName: preName }), null, end, 3000);
}, () => { }, () => {
this.scene.ui.revertMode(); this.scene.ui.revertMode();
this.scene.time.delayedCall(3000, end); this.scene.time.delayedCall(3000, end);
@ -209,7 +212,7 @@ export class EvolutionPhase extends Phase {
return; return;
} }
this.scene.playSound('sparkle'); this.scene.playSound("sparkle");
this.pokemonEvoSprite.setVisible(true); this.pokemonEvoSprite.setVisible(true);
this.doCircleInward(); this.doCircleInward();
this.scene.time.delayedCall(900, () => { this.scene.time.delayedCall(900, () => {
@ -217,17 +220,18 @@ export class EvolutionPhase extends Phase {
this.pokemon.evolve(this.evolution).then(() => { this.pokemon.evolve(this.evolution).then(() => {
const levelMoves = this.pokemon.getLevelMoves(this.lastLevel + 1, true); const levelMoves = this.pokemon.getLevelMoves(this.lastLevel + 1, true);
for (let lm of levelMoves) for (const lm of levelMoves) {
this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.scene.getParty().indexOf(this.pokemon), lm[1])); this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.scene.getParty().indexOf(this.pokemon), lm[1]));
}
this.scene.unshiftPhase(new EndEvolutionPhase(this.scene)); this.scene.unshiftPhase(new EndEvolutionPhase(this.scene));
this.scene.playSound('shine'); this.scene.playSound("shine");
this.doSpray(); this.doSpray();
this.scene.tweens.add({ this.scene.tweens.add({
targets: this.evolutionOverlay, targets: this.evolutionOverlay,
alpha: 1, alpha: 1,
duration: 250, duration: 250,
easing: 'Sine.easeIn', easing: "Sine.easeIn",
onComplete: () => { onComplete: () => {
this.evolutionBgOverlay.setAlpha(1); this.evolutionBgOverlay.setAlpha(1);
this.evolutionBg.setVisible(false); this.evolutionBg.setVisible(false);
@ -236,7 +240,7 @@ export class EvolutionPhase extends Phase {
alpha: 0, alpha: 0,
duration: 2000, duration: 2000,
delay: 150, delay: 150,
easing: 'Sine.easeIn', easing: "Sine.easeIn",
onComplete: () => { onComplete: () => {
this.scene.tweens.add({ this.scene.tweens.add({
targets: this.evolutionBgOverlay, targets: this.evolutionBgOverlay,
@ -247,10 +251,10 @@ export class EvolutionPhase extends Phase {
this.scene.time.delayedCall(250, () => { this.scene.time.delayedCall(250, () => {
this.pokemon.cry(); this.pokemon.cry();
this.scene.time.delayedCall(1250, () => { this.scene.time.delayedCall(1250, () => {
this.scene.playSoundWithoutBgm('evolution_fanfare'); this.scene.playSoundWithoutBgm("evolution_fanfare");
evolvedPokemon.destroy(); evolvedPokemon.destroy();
this.scene.ui.showText(i18next.t('menu:evolutionDone', { pokemonName: preName, evolvedPokemonName: this.pokemon.name }), null, () => this.end(), null, true, Utils.fixedInt(4000)); this.scene.ui.showText(i18next.t("menu:evolutionDone", { pokemonName: preName, evolvedPokemonName: this.pokemon.name }), null, () => this.end(), null, true, Utils.fixedInt(4000));
this.scene.time.delayedCall(Utils.fixedInt(4250), () => this.scene.playBgm()); this.scene.time.delayedCall(Utils.fixedInt(4250), () => this.scene.playBgm());
}); });
}); });
@ -266,7 +270,7 @@ export class EvolutionPhase extends Phase {
}); });
}); });
} }
}) });
} }
}); });
}); });
@ -283,9 +287,10 @@ export class EvolutionPhase extends Phase {
onRepeat: () => { onRepeat: () => {
if (f < 64) { if (f < 64) {
if (!(f & 7)) { if (!(f & 7)) {
for (let i = 0; i < 4; i++) for (let i = 0; i < 4; i++) {
this.doSpiralUpwardParticle((f & 120) * 2 + i * 64); this.doSpiralUpwardParticle((f & 120) * 2 + i * 64);
} }
}
f++; f++;
} }
} }
@ -301,9 +306,10 @@ export class EvolutionPhase extends Phase {
onRepeat: () => { onRepeat: () => {
if (f < 96) { if (f < 96) {
if (f < 6) { if (f < 6) {
for (let i = 0; i < 9; i++) for (let i = 0; i < 9; i++) {
this.doArcDownParticle(i * 16); this.doArcDownParticle(i * 16);
} }
}
f++; f++;
} }
} }
@ -317,22 +323,23 @@ export class EvolutionPhase extends Phase {
this.scene.tweens.add({ this.scene.tweens.add({
targets: this.pokemonTintSprite, targets: this.pokemonTintSprite,
scale: 0.25, scale: 0.25,
ease: 'Cubic.easeInOut', ease: "Cubic.easeInOut",
duration: 500 / l, duration: 500 / l,
yoyo: !isLastCycle yoyo: !isLastCycle
}); });
this.scene.tweens.add({ this.scene.tweens.add({
targets: this.pokemonEvoTintSprite, targets: this.pokemonEvoTintSprite,
scale: 1, scale: 1,
ease: 'Cubic.easeInOut', ease: "Cubic.easeInOut",
duration: 500 / l, duration: 500 / l,
yoyo: !isLastCycle, yoyo: !isLastCycle,
onComplete: () => { onComplete: () => {
if (evolutionHandler.cancelled) if (evolutionHandler.cancelled) {
return resolve(false); return resolve(false);
if (l < lastCycle) }
if (l < lastCycle) {
this.doCycle(l + 0.5, lastCycle).then(success => resolve(success)); this.doCycle(l + 0.5, lastCycle).then(success => resolve(success));
else { } else {
this.pokemonTintSprite.setVisible(false); this.pokemonTintSprite.setVisible(false);
resolve(true); resolve(true);
} }
@ -349,12 +356,14 @@ export class EvolutionPhase extends Phase {
duration: Utils.getFrameMs(1), duration: Utils.getFrameMs(1),
onRepeat: () => { onRepeat: () => {
if (!f) { if (!f) {
for (let i = 0; i < 16; i++) for (let i = 0; i < 16; i++) {
this.doCircleInwardParticle(i * 16, 4); this.doCircleInwardParticle(i * 16, 4);
}
} else if (f === 32) { } else if (f === 32) {
for (let i = 0; i < 16; i++) for (let i = 0; i < 16; i++) {
this.doCircleInwardParticle(i * 16, 8); this.doCircleInwardParticle(i * 16, 8);
} }
}
f++; f++;
} }
}); });
@ -368,10 +377,12 @@ export class EvolutionPhase extends Phase {
duration: Utils.getFrameMs(1), duration: Utils.getFrameMs(1),
onRepeat: () => { onRepeat: () => {
if (!f) { if (!f) {
for (let i = 0; i < 8; i++) for (let i = 0; i < 8; i++) {
this.doSprayParticle(i); this.doSprayParticle(i);
} else if (f < 50) }
} else if (f < 50) {
this.doSprayParticle(Utils.randInt(8)); this.doSprayParticle(Utils.randInt(8));
}
f++; f++;
} }
}); });
@ -379,7 +390,7 @@ export class EvolutionPhase extends Phase {
doSpiralUpwardParticle(trigIndex: integer) { doSpiralUpwardParticle(trigIndex: integer) {
const initialX = this.evolutionBaseBg.displayWidth / 2; const initialX = this.evolutionBaseBg.displayWidth / 2;
const particle = this.scene.add.image(initialX, 0, 'evo_sparkle'); const particle = this.scene.add.image(initialX, 0, "evo_sparkle");
this.evolutionContainer.add(particle); this.evolutionContainer.add(particle);
let f = 0; let f = 0;
@ -400,8 +411,9 @@ export class EvolutionPhase extends Phase {
particle.x += cos(trigIndex, amp); particle.x += cos(trigIndex, amp);
particle.setScale(1 - (f / 80)); particle.setScale(1 - (f / 80));
trigIndex += 4; trigIndex += 4;
if (f & 1) if (f & 1) {
amp--; amp--;
}
f++; f++;
} else { } else {
particle.destroy(); particle.destroy();
@ -414,7 +426,7 @@ export class EvolutionPhase extends Phase {
doArcDownParticle(trigIndex: integer) { doArcDownParticle(trigIndex: integer) {
const initialX = this.evolutionBaseBg.displayWidth / 2; const initialX = this.evolutionBaseBg.displayWidth / 2;
const particle = this.scene.add.image(initialX, 0, 'evo_sparkle'); const particle = this.scene.add.image(initialX, 0, "evo_sparkle");
particle.setScale(0.5); particle.setScale(0.5);
this.evolutionContainer.add(particle); this.evolutionContainer.add(particle);
@ -448,7 +460,7 @@ export class EvolutionPhase extends Phase {
doCircleInwardParticle(trigIndex: integer, speed: integer) { doCircleInwardParticle(trigIndex: integer, speed: integer) {
const initialX = this.evolutionBaseBg.displayWidth / 2; const initialX = this.evolutionBaseBg.displayWidth / 2;
const initialY = this.evolutionBaseBg.displayHeight / 2; const initialY = this.evolutionBaseBg.displayHeight / 2;
const particle = this.scene.add.image(initialX, initialY, 'evo_sparkle'); const particle = this.scene.add.image(initialX, initialY, "evo_sparkle");
this.evolutionContainer.add(particle); this.evolutionContainer.add(particle);
let amp = 120; let amp = 120;
@ -480,13 +492,13 @@ export class EvolutionPhase extends Phase {
doSprayParticle(trigIndex: integer) { doSprayParticle(trigIndex: integer) {
const initialX = this.evolutionBaseBg.displayWidth / 2; const initialX = this.evolutionBaseBg.displayWidth / 2;
const initialY = this.evolutionBaseBg.displayHeight / 2; const initialY = this.evolutionBaseBg.displayHeight / 2;
const particle = this.scene.add.image(initialX, initialY, 'evo_sparkle'); const particle = this.scene.add.image(initialX, initialY, "evo_sparkle");
this.evolutionContainer.add(particle); this.evolutionContainer.add(particle);
let f = 0; let f = 0;
let yOffset = 0; let yOffset = 0;
let speed = 3 - Utils.randInt(8); const speed = 3 - Utils.randInt(8);
let amp = 48 + Utils.randInt(64); const amp = 48 + Utils.randInt(64);
const particleTimer = this.scene.tweens.addCounter({ const particleTimer = this.scene.tweens.addCounter({
repeat: -1, repeat: -1,
@ -497,13 +509,15 @@ export class EvolutionPhase extends Phase {
}); });
const updateParticle = () => { const updateParticle = () => {
if (!(f & 3)) if (!(f & 3)) {
yOffset++; yOffset++;
}
if (trigIndex < 128) { if (trigIndex < 128) {
particle.setPosition(initialX + (speed * f) / 3, initialY + yOffset); particle.setPosition(initialX + (speed * f) / 3, initialY + yOffset);
particle.y += -sin(trigIndex, amp); particle.y += -sin(trigIndex, amp);
if (f > 108) if (f > 108) {
particle.setScale((1 - (f - 108) / 20)); particle.setScale((1 - (f - 108) / 20));
}
trigIndex++; trigIndex++;
f++; f++;
} else { } else {

View File

@ -23,16 +23,16 @@ export function addPokeballOpenParticles(scene: BattleScene, x: number, y: numbe
} }
function doDefaultPbOpenParticles(scene: BattleScene, x: number, y: number, radius: number) { function doDefaultPbOpenParticles(scene: BattleScene, x: number, y: number, radius: number) {
const pbOpenParticlesFrameNames = scene.anims.generateFrameNames('pb_particles', { start: 0, end: 3, suffix: '.png' }); const pbOpenParticlesFrameNames = scene.anims.generateFrameNames("pb_particles", { start: 0, end: 3, suffix: ".png" });
scene.anims.create({ scene.anims.create({
key: 'pb_open_particle', key: "pb_open_particle",
frames: pbOpenParticlesFrameNames, frames: pbOpenParticlesFrameNames,
frameRate: 16, frameRate: 16,
repeat: -1 repeat: -1
}); });
const addParticle = (index: integer) => { const addParticle = (index: integer) => {
const particle = scene.add.sprite(x, y, 'pb_open_particle'); const particle = scene.add.sprite(x, y, "pb_open_particle");
scene.field.add(particle); scene.field.add(particle);
const angle = index * 45; const angle = index * 45;
const [ xCoord, yCoord ] = [ radius * Math.cos(angle * Math.PI / 180), radius * Math.sin(angle * Math.PI / 180) ]; const [ xCoord, yCoord ] = [ radius * Math.cos(angle * Math.PI / 180), radius * Math.sin(angle * Math.PI / 180) ];
@ -43,7 +43,7 @@ function doDefaultPbOpenParticles(scene: BattleScene, x: number, y: number, radi
duration: 575 duration: 575
}); });
particle.play({ particle.play({
key: 'pb_open_particle', key: "pb_open_particle",
startFrame: (index + 3) % 4, startFrame: (index + 3) % 4,
frameRate: Math.floor(16 * scene.gameSpeed) frameRate: Math.floor(16 * scene.gameSpeed)
}); });
@ -52,7 +52,7 @@ function doDefaultPbOpenParticles(scene: BattleScene, x: number, y: number, radi
delay: 500, delay: 500,
duration: 75, duration: 75,
alpha: 0, alpha: 0,
ease: 'Sine.easeIn', ease: "Sine.easeIn",
onComplete: () => particle.destroy() onComplete: () => particle.destroy()
}); });
}; };
@ -66,39 +66,43 @@ function doDefaultPbOpenParticles(scene: BattleScene, x: number, y: number, radi
} }
function doUbOpenParticles(scene: BattleScene, x: number, y: number, frameIndex: integer) { function doUbOpenParticles(scene: BattleScene, x: number, y: number, frameIndex: integer) {
let particles: Phaser.GameObjects.Image[] = []; const particles: Phaser.GameObjects.Image[] = [];
for (let i = 0; i < 10; i++) for (let i = 0; i < 10; i++) {
particles.push(doFanOutParticle(scene, i * 25, x, y, 1, 1, 5, frameIndex)); particles.push(doFanOutParticle(scene, i * 25, x, y, 1, 1, 5, frameIndex));
}
scene.tweens.add({ scene.tweens.add({
targets: particles, targets: particles,
delay: 750, delay: 750,
duration: 250, duration: 250,
alpha: 0, alpha: 0,
ease: 'Sine.easeIn', ease: "Sine.easeIn",
onComplete: () => { onComplete: () => {
for (let particle of particles) for (const particle of particles) {
particle.destroy(); particle.destroy();
} }
}
}); });
} }
function doMbOpenParticles(scene: BattleScene, x: number, y: number) { function doMbOpenParticles(scene: BattleScene, x: number, y: number) {
let particles: Phaser.GameObjects.Image[] = []; const particles: Phaser.GameObjects.Image[] = [];
for (let j = 0; j < 2; j++) { for (let j = 0; j < 2; j++) {
for (let i = 0; i < 8; i++) for (let i = 0; i < 8; i++) {
particles.push(doFanOutParticle(scene, i * 32, x, y, j ? 1 : 2, j ? 2 : 1, 8, 4)); particles.push(doFanOutParticle(scene, i * 32, x, y, j ? 1 : 2, j ? 2 : 1, 8, 4));
}
scene.tweens.add({ scene.tweens.add({
targets: particles, targets: particles,
delay: 750, delay: 750,
duration: 250, duration: 250,
alpha: 0, alpha: 0,
ease: 'Sine.easeIn', ease: "Sine.easeIn",
onComplete: () => { onComplete: () => {
for (let particle of particles) for (const particle of particles) {
particle.destroy(); particle.destroy();
} }
}
}); });
} }
} }
@ -106,12 +110,13 @@ function doMbOpenParticles(scene: BattleScene, x: number, y: number) {
function doFanOutParticle(scene: BattleScene, trigIndex: integer, x: integer, y: integer, xSpeed: integer, ySpeed: integer, angle: integer, frameIndex: integer): Phaser.GameObjects.Image { function doFanOutParticle(scene: BattleScene, trigIndex: integer, x: integer, y: integer, xSpeed: integer, ySpeed: integer, angle: integer, frameIndex: integer): Phaser.GameObjects.Image {
let f = 0; let f = 0;
const particle = scene.add.image(x, y, 'pb_particles', `${frameIndex}.png`); const particle = scene.add.image(x, y, "pb_particles", `${frameIndex}.png`);
scene.field.add(particle); scene.field.add(particle);
const updateParticle = () => { const updateParticle = () => {
if (!particle.scene) if (!particle.scene) {
return particleTimer.remove(); return particleTimer.remove();
}
particle.x = x + sin(trigIndex, f * xSpeed); particle.x = x + sin(trigIndex, f * xSpeed);
particle.y = y + cos(trigIndex, f * ySpeed); particle.y = y + cos(trigIndex, f * ySpeed);
trigIndex = (trigIndex + angle); trigIndex = (trigIndex + angle);
@ -131,7 +136,7 @@ function doFanOutParticle(scene: BattleScene, trigIndex: integer, x: integer, y:
export function addPokeballCaptureStars(scene: BattleScene, pokeball: Phaser.GameObjects.Sprite): void { export function addPokeballCaptureStars(scene: BattleScene, pokeball: Phaser.GameObjects.Sprite): void {
const addParticle = () => { const addParticle = () => {
const particle = scene.add.sprite(pokeball.x, pokeball.y, 'pb_particles', '4.png'); const particle = scene.add.sprite(pokeball.x, pokeball.y, "pb_particles", "4.png");
particle.setOrigin(pokeball.originX, pokeball.originY); particle.setOrigin(pokeball.originX, pokeball.originY);
particle.setAlpha(0.5); particle.setAlpha(0.5);
scene.field.add(particle); scene.field.add(particle);
@ -139,14 +144,14 @@ export function addPokeballCaptureStars(scene: BattleScene, pokeball: Phaser.Gam
scene.tweens.add({ scene.tweens.add({
targets: particle, targets: particle,
y: pokeball.y - 10, y: pokeball.y - 10,
ease: 'Sine.easeOut', ease: "Sine.easeOut",
duration: 250, duration: 250,
onComplete: () => { onComplete: () => {
scene.tweens.add({ scene.tweens.add({
targets: particle, targets: particle,
y: pokeball.y, y: pokeball.y,
alpha: 0, alpha: 0,
ease: 'Sine.easeIn', ease: "Sine.easeIn",
duration: 250 duration: 250
}); });
} }

View File

@ -18,7 +18,7 @@ import { TimeOfDay } from "../data/enums/time-of-day";
import { Terrain, TerrainType } from "../data/terrain"; import { Terrain, TerrainType } from "../data/terrain";
import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability"; import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability";
import Pokemon from "./pokemon"; import Pokemon from "./pokemon";
import * as Overrides from '../overrides'; import * as Overrides from "../overrides";
export class Arena { export class Arena {
public scene: BattleScene; public scene: BattleScene;
@ -58,16 +58,18 @@ export class Arena {
const timeOfDay = this.getTimeOfDay(); const timeOfDay = this.getTimeOfDay();
if (timeOfDay !== this.lastTimeOfDay) { if (timeOfDay !== this.lastTimeOfDay) {
this.pokemonPool = {}; this.pokemonPool = {};
for (let tier of Object.keys(biomePokemonPools[this.biomeType])) for (const tier of Object.keys(biomePokemonPools[this.biomeType])) {
this.pokemonPool[tier] = Object.assign([], biomePokemonPools[this.biomeType][tier][TimeOfDay.ALL]).concat(biomePokemonPools[this.biomeType][tier][timeOfDay]); this.pokemonPool[tier] = Object.assign([], biomePokemonPools[this.biomeType][tier][TimeOfDay.ALL]).concat(biomePokemonPools[this.biomeType][tier][timeOfDay]);
}
this.lastTimeOfDay = timeOfDay; this.lastTimeOfDay = timeOfDay;
} }
} }
randomSpecies(waveIndex: integer, level: integer, attempt?: integer): PokemonSpecies { randomSpecies(waveIndex: integer, level: integer, attempt?: integer): PokemonSpecies {
const overrideSpecies = this.scene.gameMode.getOverrideSpecies(waveIndex); const overrideSpecies = this.scene.gameMode.getOverrideSpecies(waveIndex);
if (overrideSpecies) if (overrideSpecies) {
return overrideSpecies; return overrideSpecies;
}
const isBoss = !!this.scene.getEncounterBossSegments(waveIndex, level) && !!this.pokemonPool[BiomePoolTier.BOSS].length const isBoss = !!this.scene.getEncounterBossSegments(waveIndex, level) && !!this.pokemonPool[BiomePoolTier.BOSS].length
&& (this.biomeType !== Biome.END || this.scene.gameMode.isClassic || this.scene.gameMode.isWaveFinal(waveIndex)); && (this.biomeType !== Biome.END || this.scene.gameMode.isClassic || this.scene.gameMode.isWaveFinal(waveIndex));
const tierValue = Utils.randSeedInt(!isBoss ? 512 : 64); const tierValue = Utils.randSeedInt(!isBoss ? 512 : 64);
@ -82,23 +84,24 @@ export class Arena {
const tierPool = this.pokemonPool[tier]; const tierPool = this.pokemonPool[tier];
let ret: PokemonSpecies; let ret: PokemonSpecies;
let regen = false; let regen = false;
if (!tierPool.length) if (!tierPool.length) {
ret = this.scene.randomSpecies(waveIndex, level); ret = this.scene.randomSpecies(waveIndex, level);
else { } else {
const entry = tierPool[Utils.randSeedInt(tierPool.length)]; const entry = tierPool[Utils.randSeedInt(tierPool.length)];
let species: Species; let species: Species;
if (typeof entry === 'number') if (typeof entry === "number") {
species = entry as Species; species = entry as Species;
else { } else {
const levelThresholds = Object.keys(entry); const levelThresholds = Object.keys(entry);
for (let l = levelThresholds.length - 1; l >= 0; l--) { for (let l = levelThresholds.length - 1; l >= 0; l--) {
const levelThreshold = parseInt(levelThresholds[l]); const levelThreshold = parseInt(levelThresholds[l]);
if (level >= levelThreshold) { if (level >= levelThreshold) {
const speciesIds = entry[levelThreshold]; const speciesIds = entry[levelThreshold];
if (speciesIds.length > 1) if (speciesIds.length > 1) {
species = speciesIds[Utils.randSeedInt(speciesIds.length)]; species = speciesIds[Utils.randSeedInt(speciesIds.length)];
else } else {
species = speciesIds[0]; species = speciesIds[0];
}
break; break;
} }
} }
@ -125,13 +128,13 @@ export class Arena {
} }
if (regen && (attempt || 0) < 10) { if (regen && (attempt || 0) < 10) {
console.log('Incompatible level: regenerating...'); console.log("Incompatible level: regenerating...");
return this.randomSpecies(waveIndex, level, (attempt || 0) + 1); return this.randomSpecies(waveIndex, level, (attempt || 0) + 1);
} }
const newSpeciesId = ret.getWildSpeciesForLevel(level, true, isBoss, this.scene.gameMode); const newSpeciesId = ret.getWildSpeciesForLevel(level, true, isBoss, this.scene.gameMode);
if (newSpeciesId !== ret.speciesId) { if (newSpeciesId !== ret.speciesId) {
console.log('Replaced', Species[ret.speciesId], 'with', Species[newSpeciesId]); console.log("Replaced", Species[ret.speciesId], "with", Species[newSpeciesId]);
ret = getPokemonSpecies(newSpeciesId); ret = getPokemonSpecies(newSpeciesId);
} }
return ret; return ret;
@ -140,7 +143,7 @@ export class Arena {
randomTrainerType(waveIndex: integer): TrainerType { randomTrainerType(waveIndex: integer): TrainerType {
const isBoss = !!this.trainerPool[BiomePoolTier.BOSS].length const isBoss = !!this.trainerPool[BiomePoolTier.BOSS].length
&& this.scene.gameMode.isTrainerBoss(waveIndex, this.biomeType, this.scene.offsetGym); && this.scene.gameMode.isTrainerBoss(waveIndex, this.biomeType, this.scene.offsetGym);
console.log(isBoss, this.trainerPool) console.log(isBoss, this.trainerPool);
const tierValue = Utils.randSeedInt(!isBoss ? 512 : 64); const tierValue = Utils.randSeedInt(!isBoss ? 512 : 64);
let tier = !isBoss let tier = !isBoss
? tierValue >= 156 ? BiomePoolTier.COMMON : tierValue >= 32 ? BiomePoolTier.UNCOMMON : tierValue >= 6 ? BiomePoolTier.RARE : tierValue >= 1 ? BiomePoolTier.SUPER_RARE : BiomePoolTier.ULTRA_RARE ? tierValue >= 156 ? BiomePoolTier.COMMON : tierValue >= 32 ? BiomePoolTier.UNCOMMON : tierValue >= 6 ? BiomePoolTier.RARE : tierValue >= 1 ? BiomePoolTier.SUPER_RARE : BiomePoolTier.ULTRA_RARE
@ -276,7 +279,7 @@ export class Arena {
this.weather = new Weather(weather, 0); this.weather = new Weather(weather, 0);
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.SUNNY + (weather - 1))); this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.SUNNY + (weather - 1)));
this.scene.queueMessage(getWeatherStartMessage(weather)); this.scene.queueMessage(getWeatherStartMessage(weather));
return true return true;
} }
/** /**
@ -286,11 +289,13 @@ export class Arena {
* @returns true if new weather set, false if no weather provided or attempting to set the same weather as currently in use * @returns true if new weather set, false if no weather provided or attempting to set the same weather as currently in use
*/ */
trySetWeather(weather: WeatherType, hasPokemonSource: boolean): boolean { trySetWeather(weather: WeatherType, hasPokemonSource: boolean): boolean {
if (Overrides.WEATHER_OVERRIDE) if (Overrides.WEATHER_OVERRIDE) {
return this.trySetWeatherOverride(Overrides.WEATHER_OVERRIDE); return this.trySetWeatherOverride(Overrides.WEATHER_OVERRIDE);
}
if (this.weather?.weatherType === (weather || undefined)) if (this.weather?.weatherType === (weather || undefined)) {
return false; return false;
}
const oldWeatherType = this.weather?.weatherType || WeatherType.NONE; const oldWeatherType = this.weather?.weatherType || WeatherType.NONE;
@ -306,7 +311,7 @@ export class Arena {
} }
this.scene.getField(true).filter(p => p.isOnField()).map(pokemon => { this.scene.getField(true).filter(p => p.isOnField()).map(pokemon => {
pokemon.findAndRemoveTags(t => 'weatherTypes' in t && !(t.weatherTypes as WeatherType[]).find(t => t === weather)); pokemon.findAndRemoveTags(t => "weatherTypes" in t && !(t.weatherTypes as WeatherType[]).find(t => t === weather));
applyPostWeatherChangeAbAttrs(PostWeatherChangeAbAttr, pokemon, weather); applyPostWeatherChangeAbAttrs(PostWeatherChangeAbAttr, pokemon, weather);
}); });
@ -314,22 +319,25 @@ export class Arena {
} }
trySetTerrain(terrain: TerrainType, hasPokemonSource: boolean, ignoreAnim: boolean = false): boolean { trySetTerrain(terrain: TerrainType, hasPokemonSource: boolean, ignoreAnim: boolean = false): boolean {
if (this.terrain?.terrainType === (terrain || undefined)) if (this.terrain?.terrainType === (terrain || undefined)) {
return false; return false;
}
const oldTerrainType = this.terrain?.terrainType || TerrainType.NONE; const oldTerrainType = this.terrain?.terrainType || TerrainType.NONE;
this.terrain = terrain ? new Terrain(terrain, hasPokemonSource ? 5 : 0) : null; this.terrain = terrain ? new Terrain(terrain, hasPokemonSource ? 5 : 0) : null;
if (this.terrain) { if (this.terrain) {
if (!ignoreAnim) if (!ignoreAnim) {
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.MISTY_TERRAIN + (terrain - 1))); this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.MISTY_TERRAIN + (terrain - 1)));
}
this.scene.queueMessage(getTerrainStartMessage(terrain)); this.scene.queueMessage(getTerrainStartMessage(terrain));
} else } else {
this.scene.queueMessage(getTerrainClearMessage(oldTerrainType)); this.scene.queueMessage(getTerrainClearMessage(oldTerrainType));
}
this.scene.getField(true).filter(p => p.isOnField()).map(pokemon => { this.scene.getField(true).filter(p => p.isOnField()).map(pokemon => {
pokemon.findAndRemoveTags(t => 'terrainTypes' in t && !(t.terrainTypes as TerrainType[]).find(t => t === terrain)); pokemon.findAndRemoveTags(t => "terrainTypes" in t && !(t.terrainTypes as TerrainType[]).find(t => t === terrain));
applyPostTerrainChangeAbAttrs(PostTerrainChangeAbAttr, pokemon, terrain); applyPostTerrainChangeAbAttrs(PostTerrainChangeAbAttr, pokemon, terrain);
}); });
@ -350,12 +358,14 @@ export class Arena {
getAttackTypeMultiplier(attackType: Type, grounded: boolean): number { getAttackTypeMultiplier(attackType: Type, grounded: boolean): number {
let weatherMultiplier = 1; let weatherMultiplier = 1;
if (this.weather && !this.weather.isEffectSuppressed(this.scene)) if (this.weather && !this.weather.isEffectSuppressed(this.scene)) {
weatherMultiplier = this.weather.getAttackTypeMultiplier(attackType); weatherMultiplier = this.weather.getAttackTypeMultiplier(attackType);
}
let terrainMultiplier = 1; let terrainMultiplier = 1;
if (this.terrain && grounded) if (this.terrain && grounded) {
terrainMultiplier = this.terrain.getAttackTypeMultiplier(attackType); terrainMultiplier = this.terrain.getAttackTypeMultiplier(attackType);
}
return weatherMultiplier * terrainMultiplier; return weatherMultiplier * terrainMultiplier;
} }
@ -412,14 +422,17 @@ export class Arena {
const waveCycle = ((this.scene.currentBattle?.waveIndex || 0) + this.scene.waveCycleOffset) % 40; const waveCycle = ((this.scene.currentBattle?.waveIndex || 0) + this.scene.waveCycleOffset) % 40;
if (waveCycle < 15) if (waveCycle < 15) {
return TimeOfDay.DAY; return TimeOfDay.DAY;
}
if (waveCycle < 20) if (waveCycle < 20) {
return TimeOfDay.DUSK; return TimeOfDay.DUSK;
}
if (waveCycle < 35) if (waveCycle < 35) {
return TimeOfDay.NIGHT; return TimeOfDay.NIGHT;
}
return TimeOfDay.DAWN; return TimeOfDay.DAWN;
} }
@ -452,8 +465,9 @@ export class Arena {
} }
getDuskTint(): [integer, integer, integer] { getDuskTint(): [integer, integer, integer] {
if (!this.isOutside()) if (!this.isOutside()) {
return [ 0, 0, 0 ]; return [ 0, 0, 0 ];
}
switch (this.biomeType) { switch (this.biomeType) {
default: default:
@ -469,8 +483,9 @@ export class Arena {
return this.getDayTint(); return this.getDayTint();
} }
if (!this.isOutside()) if (!this.isOutside()) {
return [ 64, 64, 64 ]; return [ 64, 64, 64 ];
}
switch (this.biomeType) { switch (this.biomeType) {
default: default:
@ -483,11 +498,12 @@ export class Arena {
} }
applyTagsForSide(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }, side: ArenaTagSide, ...args: any[]): void { applyTagsForSide(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }, side: ArenaTagSide, ...args: any[]): void {
let tags = typeof tagType === 'string' let tags = typeof tagType === "string"
? this.tags.filter(t => t.tagType === tagType) ? this.tags.filter(t => t.tagType === tagType)
: this.tags.filter(t => t instanceof tagType); : this.tags.filter(t => t instanceof tagType);
if (side !== ArenaTagSide.BOTH) if (side !== ArenaTagSide.BOTH) {
tags = tags.filter(t => t.side === side); tags = tags.filter(t => t.side === side);
}
tags.forEach(t => t.apply(this, args)); tags.forEach(t => t.apply(this, args));
} }
@ -514,7 +530,7 @@ export class Arena {
} }
getTagOnSide(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }, side: ArenaTagSide): ArenaTag { getTagOnSide(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }, side: ArenaTagSide): ArenaTag {
return typeof(tagType) === 'string' return typeof(tagType) === "string"
? this.tags.find(t => t.tagType === tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side)) ? this.tags.find(t => t.tagType === tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side))
: this.tags.find(t => t instanceof tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side)); : this.tags.find(t => t instanceof tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side));
} }
@ -688,12 +704,12 @@ export class ArenaBase extends Phaser.GameObjects.Container {
this.player = player; this.player = player;
this.base = scene.addFieldSprite(0, 0, 'plains_a', null, 1); this.base = scene.addFieldSprite(0, 0, "plains_a", null, 1);
this.base.setOrigin(0, 0); this.base.setOrigin(0, 0);
this.props = !player ? this.props = !player ?
new Array(3).fill(null).map(() => { new Array(3).fill(null).map(() => {
const ret = scene.addFieldSprite(0, 0, 'plains_b', null, 1); const ret = scene.addFieldSprite(0, 0, "plains_b", null, 1);
ret.setOrigin(0, 0); ret.setOrigin(0, 0);
ret.setVisible(false); ret.setVisible(false);
return ret; return ret;
@ -703,7 +719,7 @@ export class ArenaBase extends Phaser.GameObjects.Container {
setBiome(biome: Biome, propValue?: integer): void { setBiome(biome: Biome, propValue?: integer): void {
const hasProps = getBiomeHasProps(biome); const hasProps = getBiomeHasProps(biome);
const biomeKey = getBiomeKey(biome); const biomeKey = getBiomeKey(biome);
const baseKey = `${biomeKey}_${this.player ? 'a' : 'b'}`; const baseKey = `${biomeKey}_${this.player ? "a" : "b"}`;
if (biome !== this.biome) { if (biome !== this.biome) {
this.base.setTexture(baseKey); this.base.setTexture(baseKey);
@ -717,8 +733,9 @@ export class ArenaBase extends Phaser.GameObjects.Container {
repeat: -1 repeat: -1
}); });
this.base.play(baseKey); this.base.play(baseKey);
} else } else {
this.base.stop(); this.base.stop();
}
this.add(this.base); this.add(this.base);
} }
@ -729,7 +746,7 @@ export class ArenaBase extends Phaser.GameObjects.Container {
? hasProps ? Utils.randSeedInt(8) : 0 ? hasProps ? Utils.randSeedInt(8) : 0
: propValue; : propValue;
this.props.forEach((prop, p) => { this.props.forEach((prop, p) => {
const propKey = `${biomeKey}_b${hasProps ? `_${p + 1}` : ''}`; const propKey = `${biomeKey}_b${hasProps ? `_${p + 1}` : ""}`;
prop.setTexture(propKey); prop.setTexture(propKey);
if (hasProps && prop.texture.frameTotal > 1) { if (hasProps && prop.texture.frameTotal > 1) {
@ -741,8 +758,9 @@ export class ArenaBase extends Phaser.GameObjects.Container {
repeat: -1 repeat: -1
}); });
prop.play(propKey); prop.play(propKey);
} else } else {
prop.stop(); prop.stop();
}
prop.setVisible(hasProps && !!(this.propValue & (1 << p))); prop.setVisible(hasProps && !!(this.propValue & (1 << p)));
this.add(prop); this.add(prop);

View File

@ -13,8 +13,9 @@ export default class DamageNumberHandler {
add(target: Pokemon, amount: integer, result: DamageResult | HitResult.HEAL = HitResult.EFFECTIVE, critical: boolean = false): void { add(target: Pokemon, amount: integer, result: DamageResult | HitResult.HEAL = HitResult.EFFECTIVE, critical: boolean = false): void {
const scene = target.scene; const scene = target.scene;
if (!scene?.damageNumbersMode) if (!scene?.damageNumbersMode) {
return; return;
}
const battlerIndex = target.getBattlerIndex(); const battlerIndex = target.getBattlerIndex();
const baseScale = target.getSpriteScale() / 6; const baseScale = target.getSpriteScale() / 6;
@ -26,40 +27,44 @@ export default class DamageNumberHandler {
switch (result) { switch (result) {
case HitResult.SUPER_EFFECTIVE: case HitResult.SUPER_EFFECTIVE:
[ textColor, shadowColor ] = [ '#f8d030', '#b8a038' ]; [ textColor, shadowColor ] = [ "#f8d030", "#b8a038" ];
break; break;
case HitResult.NOT_VERY_EFFECTIVE: case HitResult.NOT_VERY_EFFECTIVE:
[ textColor, shadowColor ] = [ '#f08030', '#c03028' ]; [ textColor, shadowColor ] = [ "#f08030", "#c03028" ];
break; break;
case HitResult.ONE_HIT_KO: case HitResult.ONE_HIT_KO:
[ textColor, shadowColor ] = [ '#a040a0', '#483850' ]; [ textColor, shadowColor ] = [ "#a040a0", "#483850" ];
break; break;
case HitResult.HEAL: case HitResult.HEAL:
[ textColor, shadowColor ] = [ '#78c850', '#588040' ]; [ textColor, shadowColor ] = [ "#78c850", "#588040" ];
break; break;
default: default:
[ textColor, shadowColor ] = [ '#ffffff', '#636363' ]; [ textColor, shadowColor ] = [ "#ffffff", "#636363" ];
break; break;
} }
if (textColor) if (textColor) {
damageNumber.setColor(textColor); damageNumber.setColor(textColor);
}
if (shadowColor) { if (shadowColor) {
if (critical) { if (critical) {
damageNumber.setShadowOffset(0, 0); damageNumber.setShadowOffset(0, 0);
damageNumber.setStroke(shadowColor, 12); damageNumber.setStroke(shadowColor, 12);
} else } else {
damageNumber.setShadowColor(shadowColor); damageNumber.setShadowColor(shadowColor);
} }
}
scene.fieldUI.add(damageNumber); scene.fieldUI.add(damageNumber);
if (!this.damageNumbers.has(battlerIndex)) if (!this.damageNumbers.has(battlerIndex)) {
this.damageNumbers.set(battlerIndex, []); this.damageNumbers.set(battlerIndex, []);
}
const yOffset = this.damageNumbers.get(battlerIndex).length * -10; const yOffset = this.damageNumbers.get(battlerIndex).length * -10;
if (yOffset) if (yOffset) {
damageNumber.y += yOffset; damageNumber.y += yOffset;
}
this.damageNumbers.get(battlerIndex).push(damageNumber); this.damageNumbers.get(battlerIndex).push(damageNumber);
@ -68,14 +73,14 @@ export default class DamageNumberHandler {
targets: damageNumber, targets: damageNumber,
duration: Utils.fixedInt(750), duration: Utils.fixedInt(750),
alpha: 1, alpha: 1,
y: '-=32' y: "-=32"
}); });
scene.tweens.add({ scene.tweens.add({
delay: 375, delay: 375,
targets: damageNumber, targets: damageNumber,
duration: Utils.fixedInt(625), duration: Utils.fixedInt(625),
alpha: 0, alpha: 0,
ease: 'Sine.easeIn', ease: "Sine.easeIn",
onComplete: () => { onComplete: () => {
this.damageNumbers.get(battlerIndex).splice(this.damageNumbers.get(battlerIndex).indexOf(damageNumber), 1); this.damageNumbers.get(battlerIndex).splice(this.damageNumbers.get(battlerIndex).indexOf(damageNumber), 1);
damageNumber.destroy(true); damageNumber.destroy(true);
@ -94,68 +99,68 @@ export default class DamageNumberHandler {
alpha: 1, alpha: 1,
scaleX: 0.75 * baseScale, scaleX: 0.75 * baseScale,
scaleY: 1.25 * baseScale, scaleY: 1.25 * baseScale,
y: '-=16', y: "-=16",
ease: 'Cubic.easeOut' ease: "Cubic.easeOut"
}, },
{ {
duration: Utils.fixedInt(175), duration: Utils.fixedInt(175),
alpha: 1, alpha: 1,
scaleX: 0.875 * baseScale, scaleX: 0.875 * baseScale,
scaleY: 1.125 * baseScale, scaleY: 1.125 * baseScale,
y: '+=16', y: "+=16",
ease: 'Cubic.easeIn' ease: "Cubic.easeIn"
}, },
{ {
duration: Utils.fixedInt(100), duration: Utils.fixedInt(100),
scaleX: 1.25 * baseScale, scaleX: 1.25 * baseScale,
scaleY: 0.75 * baseScale, scaleY: 0.75 * baseScale,
ease: 'Cubic.easeOut' ease: "Cubic.easeOut"
}, },
{ {
duration: Utils.fixedInt(175), duration: Utils.fixedInt(175),
scaleX: 0.875 * baseScale, scaleX: 0.875 * baseScale,
scaleY: 1.125 * baseScale, scaleY: 1.125 * baseScale,
y: '-=8', y: "-=8",
ease: 'Cubic.easeOut' ease: "Cubic.easeOut"
}, },
{ {
duration: Utils.fixedInt(50), duration: Utils.fixedInt(50),
scaleX: 0.925 * baseScale, scaleX: 0.925 * baseScale,
scaleY: 1.075 * baseScale, scaleY: 1.075 * baseScale,
y: '+=8', y: "+=8",
ease: 'Cubic.easeIn' ease: "Cubic.easeIn"
}, },
{ {
duration: Utils.fixedInt(100), duration: Utils.fixedInt(100),
scaleX: 1.125 * baseScale, scaleX: 1.125 * baseScale,
scaleY: 0.875 * baseScale, scaleY: 0.875 * baseScale,
ease: 'Cubic.easeOut' ease: "Cubic.easeOut"
}, },
{ {
duration: Utils.fixedInt(175), duration: Utils.fixedInt(175),
scaleX: 0.925 * baseScale, scaleX: 0.925 * baseScale,
scaleY: 1.075 * baseScale, scaleY: 1.075 * baseScale,
y: '-=4', y: "-=4",
ease: 'Cubic.easeOut' ease: "Cubic.easeOut"
}, },
{ {
duration: Utils.fixedInt(50), duration: Utils.fixedInt(50),
scaleX: 0.975 * baseScale, scaleX: 0.975 * baseScale,
scaleY: 1.025 * baseScale, scaleY: 1.025 * baseScale,
y: '+=4', y: "+=4",
ease: 'Cubic.easeIn' ease: "Cubic.easeIn"
}, },
{ {
duration: Utils.fixedInt(100), duration: Utils.fixedInt(100),
scaleX: 1.075 * baseScale, scaleX: 1.075 * baseScale,
scaleY: 0.925 * baseScale, scaleY: 0.925 * baseScale,
ease: 'Cubic.easeOut' ease: "Cubic.easeOut"
}, },
{ {
duration: Utils.fixedInt(25), duration: Utils.fixedInt(25),
scaleX: baseScale, scaleX: baseScale,
scaleY: baseScale, scaleY: baseScale,
ease: 'Cubic.easeOut' ease: "Cubic.easeOut"
}, },
{ {
delay: Utils.fixedInt(500), delay: Utils.fixedInt(500),

View File

@ -20,11 +20,13 @@ export default class PokemonSpriteSparkleHandler {
onLapse(): void { onLapse(): void {
Array.from(this.sprites.values()).filter(s => !s.scene).map(s => this.sprites.delete(s)); Array.from(this.sprites.values()).filter(s => !s.scene).map(s => this.sprites.delete(s));
for (let s of this.sprites.values()) { for (const s of this.sprites.values()) {
if (!s.pipelineData['teraColor'] || !(s.pipelineData['teraColor'] as number[]).find(c => c)) if (!s.pipelineData["teraColor"] || !(s.pipelineData["teraColor"] as number[]).find(c => c)) {
continue; continue;
if (!s.visible || (s.parentContainer instanceof Pokemon && !s.parentContainer.parentContainer)) }
if (!s.visible || (s.parentContainer instanceof Pokemon && !s.parentContainer.parentContainer)) {
continue; continue;
}
const pokemon = s.parentContainer instanceof Pokemon ? s.parentContainer as Pokemon : null; const pokemon = s.parentContainer instanceof Pokemon ? s.parentContainer as Pokemon : null;
const parent = (pokemon || s).parentContainer; const parent = (pokemon || s).parentContainer;
const texture = s.texture; const texture = s.texture;
@ -32,12 +34,12 @@ export default class PokemonSpriteSparkleHandler {
const [ pixelX, pixelY ] = [ Utils.randInt(width), Utils.randInt(height) ]; const [ pixelX, pixelY ] = [ Utils.randInt(width), Utils.randInt(height) ];
const ratioX = s.width / width; const ratioX = s.width / width;
const ratioY = s.height / height; const ratioY = s.height / height;
const pixel = texture.manager.getPixel(pixelX, pixelY, texture.key, '__BASE'); const pixel = texture.manager.getPixel(pixelX, pixelY, texture.key, "__BASE");
if (pixel.alpha) { if (pixel.alpha) {
const [ xOffset, yOffset ] = [ -s.originX * s.width, -s.originY * s.height]; const [ xOffset, yOffset ] = [ -s.originX * s.width, -s.originY * s.height];
const sparkle = (s.scene as BattleScene).addFieldSprite(((pokemon?.x || 0) + s.x + pixelX * ratioX + xOffset), ((pokemon?.y || 0) + s.y + pixelY * ratioY + yOffset), 'tera_sparkle'); const sparkle = (s.scene as BattleScene).addFieldSprite(((pokemon?.x || 0) + s.x + pixelX * ratioX + xOffset), ((pokemon?.y || 0) + s.y + pixelY * ratioY + yOffset), "tera_sparkle");
sparkle.pipelineData['ignoreTimeTint'] = s.pipelineData['ignoreTimeTint']; sparkle.pipelineData["ignoreTimeTint"] = s.pipelineData["ignoreTimeTint"];
sparkle.play('tera_sparkle'); sparkle.play("tera_sparkle");
parent.add(sparkle); parent.add(sparkle);
s.scene.time.delayedCall(Utils.fixedInt(Math.floor((1000 / 12) * 13)), () => sparkle.destroy()); s.scene.time.delayedCall(Utils.fixedInt(Math.floor((1000 / 12) * 13)), () => sparkle.destroy());
} }
@ -45,25 +47,29 @@ export default class PokemonSpriteSparkleHandler {
} }
add(sprites: Phaser.GameObjects.Sprite | Phaser.GameObjects.Sprite[]): void { add(sprites: Phaser.GameObjects.Sprite | Phaser.GameObjects.Sprite[]): void {
if (!Array.isArray(sprites)) if (!Array.isArray(sprites)) {
sprites = [ sprites ]; sprites = [ sprites ];
for (let s of sprites) { }
if (this.sprites.has(s)) for (const s of sprites) {
if (this.sprites.has(s)) {
continue; continue;
}
this.sprites.add(s); this.sprites.add(s);
} }
} }
remove(sprites: Phaser.GameObjects.Sprite | Phaser.GameObjects.Sprite[]): void { remove(sprites: Phaser.GameObjects.Sprite | Phaser.GameObjects.Sprite[]): void {
if (!Array.isArray(sprites)) if (!Array.isArray(sprites)) {
sprites = [ sprites ]; sprites = [ sprites ];
for (let s of sprites) { }
for (const s of sprites) {
this.sprites.delete(s); this.sprites.delete(s);
} }
} }
removeAll(): void { removeAll(): void {
for (let s of this.sprites.values()) for (const s of this.sprites.values()) {
this.sprites.delete(s); this.sprites.delete(s);
} }
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -8,8 +8,7 @@ import { EnemyPokemon } from "./pokemon";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { PersistentModifier } from "../modifier/modifier"; import { PersistentModifier } from "../modifier/modifier";
import { trainerNamePools } from "../data/trainer-names"; import { trainerNamePools } from "../data/trainer-names";
import { ArenaTagType } from "#app/data/enums/arena-tag-type"; import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag";
import { ArenaTag, 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";
@ -39,23 +38,27 @@ export default class Trainer extends Phaser.GameObjects.Container {
this.name = name || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[variant === TrainerVariant.FEMALE ? 1 : 0] : namePool); this.name = name || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[variant === TrainerVariant.FEMALE ? 1 : 0] : namePool);
if (variant === TrainerVariant.DOUBLE) { if (variant === TrainerVariant.DOUBLE) {
if (this.config.doubleOnly) { if (this.config.doubleOnly) {
if (partnerName) if (partnerName) {
this.partnerName = partnerName; this.partnerName = partnerName;
else } else {
[ this.name, this.partnerName ] = this.name.split(' & '); [ this.name, this.partnerName ] = this.name.split(" & ");
} else }
} else {
this.partnerName = partnerName || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[1] : namePool); this.partnerName = partnerName || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[1] : namePool);
} }
} }
}
switch (this.variant) { switch (this.variant) {
case TrainerVariant.FEMALE: case TrainerVariant.FEMALE:
if (!this.config.hasGenders) if (!this.config.hasGenders) {
variant = TrainerVariant.DEFAULT; variant = TrainerVariant.DEFAULT;
}
break; break;
case TrainerVariant.DOUBLE: case TrainerVariant.DOUBLE:
if (!this.config.hasDouble) if (!this.config.hasDouble) {
variant = TrainerVariant.DEFAULT; variant = TrainerVariant.DEFAULT;
}
break; break;
} }
@ -120,7 +123,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
} }
// Get the localized trainer class name from the i18n file and set it as the title. // Get the localized trainer class name from the i18n file and set it as the title.
// This is used for trainer class names, not titles like "Elite Four, Champion, etc." // This is used for trainer class names, not titles like "Elite Four, Champion, etc."
title = i18next.t(`trainerClasses:${name.toLowerCase().replace(/\s/g, '_')}`); title = i18next.t(`trainerClasses:${name.toLowerCase().replace(/\s/g, "_")}`);
} }
// If no specific trainer slot is set. // If no specific trainer slot is set.
@ -169,8 +172,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
} }
getPartyTemplate(): TrainerPartyTemplate { getPartyTemplate(): TrainerPartyTemplate {
if (this.config.partyTemplateFunc) if (this.config.partyTemplateFunc) {
return this.config.partyTemplateFunc(this.scene); return this.config.partyTemplateFunc(this.scene);
}
return this.config.partyTemplates[this.partyTemplateIndex]; return this.config.partyTemplates[this.partyTemplateIndex];
} }
@ -179,10 +183,11 @@ export default class Trainer extends Phaser.GameObjects.Container {
const partyTemplate = this.getPartyTemplate(); const partyTemplate = this.getPartyTemplate();
const difficultyWaveIndex = this.scene.gameMode.getWaveForDifficulty(waveIndex); const difficultyWaveIndex = this.scene.gameMode.getWaveForDifficulty(waveIndex);
let baseLevel = 1 + difficultyWaveIndex / 2 + Math.pow(difficultyWaveIndex / 25, 2); const baseLevel = 1 + difficultyWaveIndex / 2 + Math.pow(difficultyWaveIndex / 25, 2);
if (this.isDouble() && partyTemplate.size < 2) if (this.isDouble() && partyTemplate.size < 2) {
partyTemplate.size = 2; partyTemplate.size = 2;
}
for (let i = 0; i < partyTemplate.size; i++) { for (let i = 0; i < partyTemplate.size; i++) {
let multiplier = 1; let multiplier = 1;
@ -243,9 +248,10 @@ export default class Trainer extends Phaser.GameObjects.Container {
let offset = 0; let offset = 0;
if (template instanceof TrainerPartyCompoundTemplate) { if (template instanceof TrainerPartyCompoundTemplate) {
for (let innerTemplate of template.templates) { for (const innerTemplate of template.templates) {
if (offset + innerTemplate.size > index) if (offset + innerTemplate.size > index) {
break; break;
}
offset += innerTemplate.size; offset += innerTemplate.size;
} }
} }
@ -267,7 +273,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
let species: PokemonSpecies; let species: PokemonSpecies;
if (this.config.speciesPools) { if (this.config.speciesPools) {
const tierValue = Utils.randSeedInt(512); const tierValue = Utils.randSeedInt(512);
let tier = tierValue >= 156 ? TrainerPoolTier.COMMON : tierValue >= 32 ? TrainerPoolTier.UNCOMMON : tierValue >= 6 ? TrainerPoolTier.RARE : tierValue >= 1 ? TrainerPoolTier.SUPER_RARE : TrainerPoolTier.ULTRA_RARE let tier = tierValue >= 156 ? TrainerPoolTier.COMMON : tierValue >= 32 ? TrainerPoolTier.UNCOMMON : tierValue >= 6 ? TrainerPoolTier.RARE : tierValue >= 1 ? TrainerPoolTier.SUPER_RARE : TrainerPoolTier.ULTRA_RARE;
console.log(TrainerPoolTier[tier]); console.log(TrainerPoolTier[tier]);
while (!this.config.speciesPools.hasOwnProperty(tier) || !this.config.speciesPools[tier].length) { while (!this.config.speciesPools.hasOwnProperty(tier) || !this.config.speciesPools[tier].length) {
console.log(`Downgraded trainer Pokemon rarity tier from ${TrainerPoolTier[tier]} to ${TrainerPoolTier[tier - 1]}`); console.log(`Downgraded trainer Pokemon rarity tier from ${TrainerPoolTier[tier]} to ${TrainerPoolTier[tier - 1]}`);
@ -275,36 +281,39 @@ export default class Trainer extends Phaser.GameObjects.Container {
} }
const tierPool = this.config.speciesPools[tier]; const tierPool = this.config.speciesPools[tier];
species = getPokemonSpecies(Utils.randSeedItem(tierPool)); species = getPokemonSpecies(Utils.randSeedItem(tierPool));
} else } else {
species = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter); species = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter);
}
let ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength)); let ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength));
let retry = false; let retry = false;
console.log(ret.getName()); console.log(ret.getName());
if (pokemonPrevolutions.hasOwnProperty(species.speciesId) && ret.speciesId !== species.speciesId) if (pokemonPrevolutions.hasOwnProperty(species.speciesId) && ret.speciesId !== species.speciesId) {
retry = true; retry = true;
else if (template.isBalanced(battle.enemyParty.length)) { } else if (template.isBalanced(battle.enemyParty.length)) {
const partyMemberTypes = battle.enemyParty.map(p => p.getTypes(true)).flat(); const partyMemberTypes = battle.enemyParty.map(p => p.getTypes(true)).flat();
if (partyMemberTypes.indexOf(ret.type1) > -1 || (ret.type2 !== null && partyMemberTypes.indexOf(ret.type2) > -1)) if (partyMemberTypes.indexOf(ret.type1) > -1 || (ret.type2 !== null && partyMemberTypes.indexOf(ret.type2) > -1)) {
retry = true; retry = true;
} }
}
if (!retry && this.config.specialtyTypes.length && !this.config.specialtyTypes.find(t => ret.isOfType(t))) { if (!retry && this.config.specialtyTypes.length && !this.config.specialtyTypes.find(t => ret.isOfType(t))) {
retry = true; retry = true;
console.log('Attempting reroll of species evolution to fit specialty type...'); console.log("Attempting reroll of species evolution to fit specialty type...");
let evoAttempt = 0; let evoAttempt = 0;
while (retry && evoAttempt++ < 10) { while (retry && evoAttempt++ < 10) {
ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength)); ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength));
console.log(ret.name); console.log(ret.name);
if (this.config.specialtyTypes.find(t => ret.isOfType(t))) if (this.config.specialtyTypes.find(t => ret.isOfType(t))) {
retry = false; retry = false;
} }
} }
}
if (retry && (attempt || 0) < 10) { if (retry && (attempt || 0) < 10) {
console.log('Rerolling party member...') console.log("Rerolling party member...");
ret = this.genNewPartyMemberSpecies(level, strength, (attempt || 0) + 1); ret = this.genNewPartyMemberSpecies(level, strength, (attempt || 0) + 1);
} }
@ -312,25 +321,26 @@ export default class Trainer extends Phaser.GameObjects.Container {
} }
getPartyMemberMatchupScores(trainerSlot: TrainerSlot = TrainerSlot.NONE, forSwitch: boolean = false): [integer, integer][] { getPartyMemberMatchupScores(trainerSlot: TrainerSlot = TrainerSlot.NONE, forSwitch: boolean = false): [integer, integer][] {
if (trainerSlot && !this.isDouble()) if (trainerSlot && !this.isDouble()) {
trainerSlot = TrainerSlot.NONE; trainerSlot = TrainerSlot.NONE;
}
const party = this.scene.getEnemyParty(); const party = this.scene.getEnemyParty();
const nonFaintedPartyMembers = party.slice(this.scene.currentBattle.getBattlerCount()).filter(p => !p.isFainted()).filter(p => !trainerSlot || p.trainerSlot === trainerSlot); const nonFaintedPartyMembers = party.slice(this.scene.currentBattle.getBattlerCount()).filter(p => !p.isFainted()).filter(p => !trainerSlot || p.trainerSlot === trainerSlot);
const partyMemberScores = nonFaintedPartyMembers.map(p => { const partyMemberScores = nonFaintedPartyMembers.map(p => {
const playerField = this.scene.getPlayerField(); const playerField = this.scene.getPlayerField();
let score = 0; let score = 0;
let ret: [integer, integer]; for (const playerPokemon of playerField) {
for (let playerPokemon of playerField) {
score += p.getMatchupScore(playerPokemon); score += p.getMatchupScore(playerPokemon);
if (playerPokemon.species.legendary) if (playerPokemon.species.legendary) {
score /= 2; score /= 2;
} }
}
score /= playerField.length; score /= playerField.length;
if (forSwitch && !p.isOnField()) if (forSwitch && !p.isOnField()) {
this.scene.arena.findTagsOnSide(t => t instanceof ArenaTrapTag, ArenaTagSide.ENEMY).map(t => score *= (t as ArenaTrapTag).getMatchupScoreMultiplier(p)); this.scene.arena.findTagsOnSide(t => t instanceof ArenaTrapTag, ArenaTagSide.ENEMY).map(t => score *= (t as ArenaTrapTag).getMatchupScoreMultiplier(p));
ret = [ party.indexOf(p), score ]; }
return ret; return [ party.indexOf(p), score ];
}); });
return partyMemberScores; return partyMemberScores;
@ -348,8 +358,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
} }
getNextSummonIndex(trainerSlot: TrainerSlot = TrainerSlot.NONE, partyMemberScores: [integer, integer][] = this.getPartyMemberMatchupScores(trainerSlot)): integer { getNextSummonIndex(trainerSlot: TrainerSlot = TrainerSlot.NONE, partyMemberScores: [integer, integer][] = this.getPartyMemberMatchupScores(trainerSlot)): integer {
if (trainerSlot && !this.isDouble()) if (trainerSlot && !this.isDouble()) {
trainerSlot = TrainerSlot.NONE; trainerSlot = TrainerSlot.NONE;
}
const sortedPartyMemberScores = this.getSortedPartyMemberMatchupScores(partyMemberScores); const sortedPartyMemberScores = this.getSortedPartyMemberMatchupScores(partyMemberScores);
@ -380,8 +391,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
} }
genModifiers(party: EnemyPokemon[]): PersistentModifier[] { genModifiers(party: EnemyPokemon[]): PersistentModifier[] {
if (this.config.genModifiersFunc) if (this.config.genModifiersFunc) {
return this.config.genModifiersFunc(party); return this.config.genModifiersFunc(party);
}
return []; return [];
} }
@ -404,7 +416,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
*/ */
tryPlaySprite(sprite: Phaser.GameObjects.Sprite, tintSprite: Phaser.GameObjects.Sprite, animConfig: Phaser.Types.Animations.PlayAnimationConfig): boolean { tryPlaySprite(sprite: Phaser.GameObjects.Sprite, tintSprite: Phaser.GameObjects.Sprite, animConfig: Phaser.Types.Animations.PlayAnimationConfig): boolean {
// Show an error in the console if there isn't a texture loaded // Show an error in the console if there isn't a texture loaded
if (sprite.texture.key === '__MISSING') { if (sprite.texture.key === "__MISSING") {
console.error(`No texture found for '${animConfig.key}'!`); console.error(`No texture found for '${animConfig.key}'!`);
return false; return false;
@ -449,8 +461,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
const ret: Phaser.GameObjects.Sprite[] = [ const ret: Phaser.GameObjects.Sprite[] = [
this.getAt(0) this.getAt(0)
]; ];
if (this.variant === TrainerVariant.DOUBLE && !this.config.doubleOnly) if (this.variant === TrainerVariant.DOUBLE && !this.config.doubleOnly) {
ret.push(this.getAt(2)); ret.push(this.getAt(2));
}
return ret; return ret;
} }
@ -458,8 +471,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
const ret: Phaser.GameObjects.Sprite[] = [ const ret: Phaser.GameObjects.Sprite[] = [
this.getAt(1) this.getAt(1)
]; ];
if (this.variant === TrainerVariant.DOUBLE && !this.config.doubleOnly) if (this.variant === TrainerVariant.DOUBLE && !this.config.doubleOnly) {
ret.push(this.getAt(3)); ret.push(this.getAt(3));
}
return ret; return ret;
} }
@ -476,10 +490,11 @@ export default class Trainer extends Phaser.GameObjects.Container {
targets: tintSprite, targets: tintSprite,
alpha: alpha || 1, alpha: alpha || 1,
duration: duration, duration: duration,
ease: ease || 'Linear' ease: ease || "Linear"
}); });
} else } else {
tintSprite.setAlpha(alpha); tintSprite.setAlpha(alpha);
}
}); });
} }
@ -491,7 +506,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
targets: tintSprite, targets: tintSprite,
alpha: 0, alpha: 0,
duration: duration, duration: duration,
ease: ease || 'Linear', ease: ease || "Linear",
onComplete: () => { onComplete: () => {
tintSprite.setVisible(false); tintSprite.setVisible(false);
tintSprite.setAlpha(1); tintSprite.setAlpha(1);

View File

@ -27,8 +27,9 @@ export class FormChangePhase extends EvolutionPhase {
} }
setMode(): Promise<void> { setMode(): Promise<void> {
if (!this.modal) if (!this.modal) {
return super.setMode(); return super.setMode();
}
return this.scene.ui.setOverlayMode(Mode.EVOLUTION_SCENE); return this.scene.ui.setOverlayMode(Mode.EVOLUTION_SCENE);
} }
@ -39,13 +40,14 @@ export class FormChangePhase extends EvolutionPhase {
[ this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => { [ this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => {
sprite.play(transformedPokemon.getSpriteKey(true)); sprite.play(transformedPokemon.getSpriteKey(true));
sprite.setPipelineData('ignoreTimeTint', true); sprite.setPipelineData("ignoreTimeTint", true);
sprite.setPipelineData('spriteKey', transformedPokemon.getSpriteKey()); sprite.setPipelineData("spriteKey", transformedPokemon.getSpriteKey());
sprite.setPipelineData('shiny', transformedPokemon.shiny); sprite.setPipelineData("shiny", transformedPokemon.shiny);
sprite.setPipelineData('variant', transformedPokemon.variant); sprite.setPipelineData("variant", transformedPokemon.variant);
[ 'spriteColors', 'fusionSpriteColors' ].map(k => { [ "spriteColors", "fusionSpriteColors" ].map(k => {
if (transformedPokemon.summonData?.speciesForm) if (transformedPokemon.summonData?.speciesForm) {
k += 'Base'; k += "Base";
}
sprite.pipelineData[k] = transformedPokemon.getSprite().pipelineData[k]; sprite.pipelineData[k] = transformedPokemon.getSprite().pipelineData[k];
}); });
}); });
@ -56,7 +58,7 @@ export class FormChangePhase extends EvolutionPhase {
alpha: 1, alpha: 1,
delay: 500, delay: 500,
duration: 1500, duration: 1500,
ease: 'Sine.easeOut', ease: "Sine.easeOut",
onComplete: () => { onComplete: () => {
this.scene.time.delayedCall(1000, () => { this.scene.time.delayedCall(1000, () => {
this.scene.tweens.add({ this.scene.tweens.add({
@ -67,7 +69,7 @@ export class FormChangePhase extends EvolutionPhase {
this.evolutionBg.setVisible(true); this.evolutionBg.setVisible(true);
this.evolutionBg.play(); this.evolutionBg.play();
}); });
this.scene.playSound('charge'); this.scene.playSound("charge");
this.doSpiralUpward(); this.doSpiralUpward();
this.scene.tweens.addCounter({ this.scene.tweens.addCounter({
from: 0, from: 0,
@ -79,27 +81,28 @@ export class FormChangePhase extends EvolutionPhase {
onComplete: () => { onComplete: () => {
this.pokemonSprite.setVisible(false); this.pokemonSprite.setVisible(false);
this.scene.time.delayedCall(1100, () => { this.scene.time.delayedCall(1100, () => {
this.scene.playSound('beam'); this.scene.playSound("beam");
this.doArcDownward(); this.doArcDownward();
this.scene.time.delayedCall(1000, () => { this.scene.time.delayedCall(1000, () => {
this.pokemonEvoTintSprite.setScale(0.25); this.pokemonEvoTintSprite.setScale(0.25);
this.pokemonEvoTintSprite.setVisible(true); this.pokemonEvoTintSprite.setVisible(true);
this.doCycle(1, 1).then(_success => { this.doCycle(1, 1).then(_success => {
this.scene.playSound('sparkle'); this.scene.playSound("sparkle");
this.pokemonEvoSprite.setVisible(true); this.pokemonEvoSprite.setVisible(true);
this.doCircleInward(); this.doCircleInward();
this.scene.time.delayedCall(900, () => { this.scene.time.delayedCall(900, () => {
this.pokemon.changeForm(this.formChange).then(() => { this.pokemon.changeForm(this.formChange).then(() => {
if (!this.modal) if (!this.modal) {
this.scene.unshiftPhase(new EndEvolutionPhase(this.scene)); this.scene.unshiftPhase(new EndEvolutionPhase(this.scene));
}
this.scene.playSound('shine'); this.scene.playSound("shine");
this.doSpray(); this.doSpray();
this.scene.tweens.add({ this.scene.tweens.add({
targets: this.evolutionOverlay, targets: this.evolutionOverlay,
alpha: 1, alpha: 1,
duration: 250, duration: 250,
easing: 'Sine.easeIn', easing: "Sine.easeIn",
onComplete: () => { onComplete: () => {
this.evolutionBgOverlay.setAlpha(1); this.evolutionBgOverlay.setAlpha(1);
this.evolutionBg.setVisible(false); this.evolutionBg.setVisible(false);
@ -108,7 +111,7 @@ export class FormChangePhase extends EvolutionPhase {
alpha: 0, alpha: 0,
duration: 2000, duration: 2000,
delay: 150, delay: 150,
easing: 'Sine.easeIn', easing: "Sine.easeIn",
onComplete: () => { onComplete: () => {
this.scene.tweens.add({ this.scene.tweens.add({
targets: this.evolutionBgOverlay, targets: this.evolutionBgOverlay,
@ -128,7 +131,7 @@ export class FormChangePhase extends EvolutionPhase {
} }
const delay = playEvolutionFanfare ? 4000 : 1750; const delay = playEvolutionFanfare ? 4000 : 1750;
this.scene.playSoundWithoutBgm(playEvolutionFanfare ? 'evolution_fanfare' : 'minor_fanfare'); this.scene.playSoundWithoutBgm(playEvolutionFanfare ? "evolution_fanfare" : "minor_fanfare");
transformedPokemon.destroy(); transformedPokemon.destroy();
this.scene.ui.showText(getSpeciesFormChangeMessage(this.pokemon, this.formChange, preName), null, () => this.end(), null, true, Utils.fixedInt(delay)); this.scene.ui.showText(getSpeciesFormChangeMessage(this.pokemon, this.formChange, preName), null, () => this.end(), null, true, Utils.fixedInt(delay));
@ -147,7 +150,7 @@ export class FormChangePhase extends EvolutionPhase {
}); });
}); });
} }
}) });
} }
}); });
}); });
@ -165,9 +168,10 @@ export class FormChangePhase extends EvolutionPhase {
super.end(); super.end();
}); });
} else } else {
super.end(); super.end();
} }
}
} }
export class QuietFormChangePhase extends BattlePhase { export class QuietFormChangePhase extends BattlePhase {
@ -183,8 +187,9 @@ export class QuietFormChangePhase extends BattlePhase {
start(): void { start(): void {
super.start(); super.start();
if (this.pokemon.formIndex === this.pokemon.species.forms.findIndex(f => f.formKey === this.formChange.formKey)) if (this.pokemon.formIndex === this.pokemon.species.forms.findIndex(f => f.formKey === this.formChange.formKey)) {
return this.end(); return this.end();
}
const preName = this.pokemon.name; const preName = this.pokemon.name;
@ -196,26 +201,28 @@ export class QuietFormChangePhase extends BattlePhase {
} }
const getPokemonSprite = () => { const getPokemonSprite = () => {
const sprite = this.scene.addPokemonSprite(this.pokemon, this.pokemon.x + this.pokemon.getSprite().x, this.pokemon.y + this.pokemon.getSprite().y, `pkmn__sub`); const sprite = this.scene.addPokemonSprite(this.pokemon, this.pokemon.x + this.pokemon.getSprite().x, this.pokemon.y + this.pokemon.getSprite().y, "pkmn__sub");
sprite.setOrigin(0.5, 1); sprite.setOrigin(0.5, 1);
sprite.play(this.pokemon.getBattleSpriteKey()).stop(); sprite.play(this.pokemon.getBattleSpriteKey()).stop();
sprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()) }); sprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()) });
[ 'spriteColors', 'fusionSpriteColors' ].map(k => { [ "spriteColors", "fusionSpriteColors" ].map(k => {
if (this.pokemon.summonData?.speciesForm) if (this.pokemon.summonData?.speciesForm) {
k += 'Base'; k += "Base";
}
sprite.pipelineData[k] = this.pokemon.getSprite().pipelineData[k]; sprite.pipelineData[k] = this.pokemon.getSprite().pipelineData[k];
}); });
this.scene.field.add(sprite); this.scene.field.add(sprite);
return sprite; return sprite;
} };
const [ pokemonTintSprite, pokemonFormTintSprite ] = [ getPokemonSprite(), getPokemonSprite() ]; const [ pokemonTintSprite, pokemonFormTintSprite ] = [ getPokemonSprite(), getPokemonSprite() ];
this.pokemon.getSprite().on('animationupdate', (_anim, frame) => { this.pokemon.getSprite().on("animationupdate", (_anim, frame) => {
if (frame.textureKey === pokemonTintSprite.texture.key) if (frame.textureKey === pokemonTintSprite.texture.key) {
pokemonTintSprite.setFrame(frame.textureFrame); pokemonTintSprite.setFrame(frame.textureFrame);
else } else {
pokemonFormTintSprite.setFrame(frame.textureFrame); pokemonFormTintSprite.setFrame(frame.textureFrame);
}
}); });
pokemonTintSprite.setAlpha(0); pokemonTintSprite.setAlpha(0);
@ -223,13 +230,13 @@ export class QuietFormChangePhase extends BattlePhase {
pokemonFormTintSprite.setVisible(false); pokemonFormTintSprite.setVisible(false);
pokemonFormTintSprite.setTintFill(0xFFFFFF); pokemonFormTintSprite.setTintFill(0xFFFFFF);
this.scene.playSound('PRSFX- Transform'); this.scene.playSound("PRSFX- Transform");
this.scene.tweens.add({ this.scene.tweens.add({
targets: pokemonTintSprite, targets: pokemonTintSprite,
alpha: 1, alpha: 1,
duration: 1000, duration: 1000,
ease: 'Cubic.easeIn', ease: "Cubic.easeIn",
onComplete: () => { onComplete: () => {
this.pokemon.setVisible(false); this.pokemon.setVisible(false);
this.pokemon.changeForm(this.formChange).then(() => { this.pokemon.changeForm(this.formChange).then(() => {
@ -240,7 +247,7 @@ export class QuietFormChangePhase extends BattlePhase {
targets: pokemonTintSprite, targets: pokemonTintSprite,
delay: 250, delay: 250,
scale: 0.01, scale: 0.01,
ease: 'Cubic.easeInOut', ease: "Cubic.easeInOut",
duration: 500, duration: 500,
onComplete: () => pokemonTintSprite.destroy() onComplete: () => pokemonTintSprite.destroy()
}); });
@ -248,7 +255,7 @@ export class QuietFormChangePhase extends BattlePhase {
targets: pokemonFormTintSprite, targets: pokemonFormTintSprite,
delay: 250, delay: 250,
scale: this.pokemon.getSpriteScale(), scale: this.pokemon.getSpriteScale(),
ease: 'Cubic.easeInOut', ease: "Cubic.easeInOut",
duration: 500, duration: 500,
onComplete: () => { onComplete: () => {
this.pokemon.setVisible(true); this.pokemon.setVisible(true);
@ -256,7 +263,7 @@ export class QuietFormChangePhase extends BattlePhase {
targets: pokemonFormTintSprite, targets: pokemonFormTintSprite,
delay: 250, delay: 250,
alpha: 0, alpha: 0,
ease: 'Cubic.easeOut', ease: "Cubic.easeOut",
duration: 1000, duration: 1000,
onComplete: () => { onComplete: () => {
pokemonTintSprite.setVisible(false); pokemonTintSprite.setVisible(false);
@ -282,9 +289,10 @@ export class QuietFormChangePhase extends BattlePhase {
this.pokemon.cry(); this.pokemon.cry();
const movePhase = this.scene.findPhase(p => p instanceof MovePhase && p.pokemon === this.pokemon) as MovePhase; const movePhase = this.scene.findPhase(p => p instanceof MovePhase && p.pokemon === this.pokemon) as MovePhase;
if (movePhase) if (movePhase) {
movePhase.cancel(); movePhase.cancel();
} }
}
super.end(); super.end();
} }

View File

@ -5,7 +5,7 @@ import { Species } from "./data/enums/species";
import PokemonSpecies, { allSpecies } from "./data/pokemon-species"; import PokemonSpecies, { allSpecies } from "./data/pokemon-species";
import { Arena } from "./field/arena"; import { Arena } from "./field/arena";
import * as Utils from "./utils"; import * as Utils from "./utils";
import * as Overrides from './overrides'; import * as Overrides from "./overrides";
export enum GameModes { export enum GameModes {
CLASSIC, CLASSIC,
@ -52,8 +52,9 @@ export class GameMode implements GameModeConfig {
* - 5 for all other modes * - 5 for all other modes
*/ */
getStartingLevel(): integer { getStartingLevel(): integer {
if (Overrides.STARTING_LEVEL_OVERRIDE) if (Overrides.STARTING_LEVEL_OVERRIDE) {
return Overrides.STARTING_LEVEL_OVERRIDE; return Overrides.STARTING_LEVEL_OVERRIDE;
}
switch (this.modeId) { switch (this.modeId) {
case GameModes.DAILY: case GameModes.DAILY:
return 20; return 20;
@ -97,32 +98,36 @@ export class GameMode implements GameModeConfig {
} }
isWaveTrainer(waveIndex: integer, arena: Arena): boolean { isWaveTrainer(waveIndex: integer, arena: Arena): boolean {
if (this.isDaily) if (this.isDaily) {
return waveIndex % 10 === 5 || (!(waveIndex % 10) && waveIndex > 10 && !this.isWaveFinal(waveIndex)); return waveIndex % 10 === 5 || (!(waveIndex % 10) && waveIndex > 10 && !this.isWaveFinal(waveIndex));
if ((waveIndex % 30) === (arena.scene.offsetGym ? 0 : 20) && !this.isWaveFinal(waveIndex)) }
if ((waveIndex % 30) === (arena.scene.offsetGym ? 0 : 20) && !this.isWaveFinal(waveIndex)) {
return true; return true;
else if (waveIndex % 10 !== 1 && waveIndex % 10) { } else if (waveIndex % 10 !== 1 && waveIndex % 10) {
const trainerChance = arena.getTrainerChance(); const trainerChance = arena.getTrainerChance();
let allowTrainerBattle = true; let allowTrainerBattle = true;
if (trainerChance) { if (trainerChance) {
const waveBase = Math.floor(waveIndex / 10) * 10; const waveBase = Math.floor(waveIndex / 10) * 10;
for (let w = Math.max(waveIndex - 3, waveBase + 2); w <= Math.min(waveIndex + 3, waveBase + 9); w++) { for (let w = Math.max(waveIndex - 3, waveBase + 2); w <= Math.min(waveIndex + 3, waveBase + 9); w++) {
if (w === waveIndex) if (w === waveIndex) {
continue; continue;
}
if ((w % 30) === (arena.scene.offsetGym ? 0 : 20) || fixedBattles.hasOwnProperty(w)) { if ((w % 30) === (arena.scene.offsetGym ? 0 : 20) || fixedBattles.hasOwnProperty(w)) {
allowTrainerBattle = false; allowTrainerBattle = false;
break; break;
} else if (w < waveIndex) { } else if (w < waveIndex) {
arena.scene.executeWithSeedOffset(() => { arena.scene.executeWithSeedOffset(() => {
const waveTrainerChance = arena.getTrainerChance(); const waveTrainerChance = arena.getTrainerChance();
if (!Utils.randSeedInt(waveTrainerChance)) if (!Utils.randSeedInt(waveTrainerChance)) {
allowTrainerBattle = false; allowTrainerBattle = false;
}
}, w); }, w);
if (!allowTrainerBattle) if (!allowTrainerBattle) {
break; break;
} }
} }
} }
}
return allowTrainerBattle && trainerChance && !Utils.randSeedInt(trainerChance); return allowTrainerBattle && trainerChance && !Utils.randSeedInt(trainerChance);
} }
return false; return false;
@ -147,8 +152,14 @@ export class GameMode implements GameModeConfig {
return null; return null;
} }
isWaveFinal(waveIndex: integer): boolean { /**
switch (this.modeId) { * Checks if wave provided is the final for current or specified game mode
* @param waveIndex
* @param modeId game mode
* @returns if the current wave is final for classic or daily OR a minor boss in endless
*/
isWaveFinal(waveIndex: integer, modeId: GameModes = this.modeId): boolean {
switch (modeId) {
case GameModes.CLASSIC: case GameModes.CLASSIC:
return waveIndex === 200; return waveIndex === 200;
case GameModes.ENDLESS: case GameModes.ENDLESS:
@ -159,6 +170,45 @@ export class GameMode implements GameModeConfig {
} }
} }
/**
* Every 10 waves is a boss battle
* @returns true if waveIndex is a multiple of 10
*/
isBoss(waveIndex: integer): boolean {
return waveIndex % 10 === 0;
}
/**
* Every 50 waves of an Endless mode is a boss
* At this time it is paradox pokemon
* @returns true if waveIndex is a multiple of 50 in Endless
*/
isEndlessBoss(waveIndex: integer): boolean {
return waveIndex % 50 &&
(this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS);
}
/**
* Every 250 waves of an Endless mode is a minor boss
* At this time it is Eternatus
* @returns true if waveIndex is a multiple of 250 in Endless
*/
isEndlessMinorBoss(waveIndex: integer): boolean {
return waveIndex % 250 === 0 &&
(this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS);
}
/**
* Every 1000 waves of an Endless mode is a major boss
* At this time it is Eternamax Eternatus
* @returns true if waveIndex is a multiple of 1000 in Endless
*/
isEndlessMajorBoss(waveIndex: integer): boolean {
return waveIndex % 1000 === 0 &&
(this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS);
}
getClearScoreBonus(): integer { getClearScoreBonus(): integer {
switch (this.modeId) { switch (this.modeId) {
case GameModes.CLASSIC: case GameModes.CLASSIC:
@ -182,13 +232,13 @@ export class GameMode implements GameModeConfig {
getName(): string { getName(): string {
switch (this.modeId) { switch (this.modeId) {
case GameModes.CLASSIC: case GameModes.CLASSIC:
return 'Classic'; return "Classic";
case GameModes.ENDLESS: case GameModes.ENDLESS:
return 'Endless'; return "Endless";
case GameModes.SPLICED_ENDLESS: case GameModes.SPLICED_ENDLESS:
return 'Endless (Spliced)'; return "Endless (Spliced)";
case GameModes.DAILY: case GameModes.DAILY:
return 'Daily Run'; return "Daily Run";
} }
} }
} }

View File

@ -1,6 +1,6 @@
import Phaser, {Time} from "phaser"; import Phaser, {Time} from "phaser";
import * as Utils from "./utils"; import * as Utils from "./utils";
import {initTouchControls} from './touch-controls'; import {initTouchControls} from "./touch-controls";
import pad_generic from "./configs/pad_generic"; import pad_generic from "./configs/pad_generic";
import pad_unlicensedSNES from "./configs/pad_unlicensedSNES"; import pad_unlicensedSNES from "./configs/pad_unlicensedSNES";
import pad_xbox360 from "./configs/pad_xbox360"; import pad_xbox360 from "./configs/pad_xbox360";
@ -79,7 +79,7 @@ export class InputsController {
pressTime: false, pressTime: false,
isPressed: false, isPressed: false,
source: null, source: null,
} };
} }
// We don't want the menu key to be repeated // We don't want the menu key to be repeated
delete this.interactions[Button.MENU]; delete this.interactions[Button.MENU];
@ -98,11 +98,11 @@ export class InputsController {
init(): void { init(): void {
this.events = new Phaser.Events.EventEmitter(); this.events = new Phaser.Events.EventEmitter();
this.scene.game.events.on(Phaser.Core.Events.BLUR, () => { this.scene.game.events.on(Phaser.Core.Events.BLUR, () => {
this.loseFocus() this.loseFocus();
}) });
if (typeof this.scene.input.gamepad !== 'undefined') { if (typeof this.scene.input.gamepad !== "undefined") {
this.scene.input.gamepad.on('connected', function (thisGamepad) { this.scene.input.gamepad.on("connected", function (thisGamepad) {
this.refreshGamepads(); this.refreshGamepads();
this.setupGamepad(thisGamepad); this.setupGamepad(thisGamepad);
}, this); }, this);
@ -112,12 +112,12 @@ export class InputsController {
if (this.scene.input.gamepad.total) { if (this.scene.input.gamepad.total) {
this.refreshGamepads(); this.refreshGamepads();
for (const thisGamepad of this.gamepads) { for (const thisGamepad of this.gamepads) {
this.scene.input.gamepad.emit('connected', thisGamepad); this.scene.input.gamepad.emit("connected", thisGamepad);
} }
} }
this.scene.input.gamepad.on('down', this.gamepadButtonDown, this); this.scene.input.gamepad.on("down", this.gamepadButtonDown, this);
this.scene.input.gamepad.on('up', this.gamepadButtonUp, this); this.scene.input.gamepad.on("up", this.gamepadButtonUp, this);
} }
// Keyboard // Keyboard
@ -173,13 +173,13 @@ export class InputsController {
this.interactions[b].isPressed this.interactions[b].isPressed
) { ) {
// Prevents repeating button interactions when gamepad support is disabled. // Prevents repeating button interactions when gamepad support is disabled.
if (!this.gamepadSupport && this.interactions[b].source === 'gamepad') { if (!this.gamepadSupport && this.interactions[b].source === "gamepad") {
// Deletes the last interaction for a button if gamepad is disabled. // Deletes the last interaction for a button if gamepad is disabled.
this.delLastProcessedMovementTime(b); this.delLastProcessedMovementTime(b);
return; return;
} }
// Emits an event for the button press. // Emits an event for the button press.
this.events.emit('input_down', { this.events.emit("input_down", {
controller_type: this.interactions[b].source, controller_type: this.interactions[b].source,
button: b, button: b,
}); });
@ -199,9 +199,9 @@ export class InputsController {
* that the gamepad controls are correctly mapped to in-game actions. * that the gamepad controls are correctly mapped to in-game actions.
*/ */
setupGamepad(thisGamepad: Phaser.Input.Gamepad.Gamepad): void { setupGamepad(thisGamepad: Phaser.Input.Gamepad.Gamepad): void {
let gamepadID = thisGamepad.id.toLowerCase(); const gamepadID = thisGamepad.id.toLowerCase();
const mappedPad = this.mapGamepad(gamepadID); const mappedPad = this.mapGamepad(gamepadID);
this.player['mapping'] = mappedPad.gamepadMapping; this.player["mapping"] = mappedPad.gamepadMapping;
} }
/** /**
@ -215,7 +215,7 @@ export class InputsController {
refreshGamepads(): void { refreshGamepads(): void {
// Sometimes, gamepads are undefined. For some reason. // Sometimes, gamepads are undefined. For some reason.
this.gamepads = this.scene.input.gamepad.gamepads.filter(function (el) { this.gamepads = this.scene.input.gamepad.gamepads.filter(function (el) {
return el != null; return el !== null;
}); });
for (const [index, thisGamepad] of this.gamepads.entries()) { for (const [index, thisGamepad] of this.gamepads.entries()) {
@ -236,7 +236,9 @@ export class InputsController {
*/ */
getActionGamepadMapping(): ActionGamepadMapping { getActionGamepadMapping(): ActionGamepadMapping {
const gamepadMapping = {}; const gamepadMapping = {};
if (!this.player?.mapping) return gamepadMapping; if (!this.player?.mapping) {
return gamepadMapping;
}
gamepadMapping[this.player.mapping.LC_N] = Button.UP; gamepadMapping[this.player.mapping.LC_N] = Button.UP;
gamepadMapping[this.player.mapping.LC_S] = Button.DOWN; gamepadMapping[this.player.mapping.LC_S] = Button.DOWN;
gamepadMapping[this.player.mapping.LC_W] = Button.LEFT; gamepadMapping[this.player.mapping.LC_W] = Button.LEFT;
@ -272,15 +274,17 @@ export class InputsController {
* - If mapped, emits an 'input_down' event with the controller type and button action, and updates the interaction of this button. * - If mapped, emits an 'input_down' event with the controller type and button action, and updates the interaction of this button.
*/ */
gamepadButtonDown(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void { gamepadButtonDown(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
if (!this.gamepadSupport) return; if (!this.gamepadSupport) {
return;
}
const actionMapping = this.getActionGamepadMapping(); const actionMapping = this.getActionGamepadMapping();
const buttonDown = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index]; const buttonDown = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
if (buttonDown !== undefined) { if (buttonDown !== undefined) {
this.events.emit('input_down', { this.events.emit("input_down", {
controller_type: 'gamepad', controller_type: "gamepad",
button: buttonDown, button: buttonDown,
}); });
this.setLastProcessedMovementTime(buttonDown, 'gamepad'); this.setLastProcessedMovementTime(buttonDown, "gamepad");
} }
} }
@ -298,12 +302,14 @@ export class InputsController {
* - If mapped, emits an 'input_up' event with the controller type and button action, and clears the interaction for this button. * - If mapped, emits an 'input_up' event with the controller type and button action, and clears the interaction for this button.
*/ */
gamepadButtonUp(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void { gamepadButtonUp(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
if (!this.gamepadSupport) return; if (!this.gamepadSupport) {
return;
}
const actionMapping = this.getActionGamepadMapping(); const actionMapping = this.getActionGamepadMapping();
const buttonUp = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index]; const buttonUp = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
if (buttonUp !== undefined) { if (buttonUp !== undefined) {
this.events.emit('input_up', { this.events.emit("input_up", {
controller_type: 'gamepad', controller_type: "gamepad",
button: buttonUp, button: buttonUp,
}); });
this.delLastProcessedMovementTime(buttonUp); this.delLastProcessedMovementTime(buttonUp);
@ -353,8 +359,9 @@ export class InputsController {
for (const b of Utils.getEnumValues(Button)) { for (const b of Utils.getEnumValues(Button)) {
const keys: Phaser.Input.Keyboard.Key[] = []; const keys: Phaser.Input.Keyboard.Key[] = [];
if (keyConfig.hasOwnProperty(b)) { if (keyConfig.hasOwnProperty(b)) {
for (let k of keyConfig[b]) for (const k of keyConfig[b]) {
keys.push(this.scene.input.keyboard.addKey(k, false)); keys.push(this.scene.input.keyboard.addKey(k, false));
}
mobileKeyConfig[Button[b]] = keys[0]; mobileKeyConfig[Button[b]] = keys[0];
} }
this.buttonKeys[b] = keys; this.buttonKeys[b] = keys;
@ -385,16 +392,16 @@ export class InputsController {
listenInputKeyboard(): void { listenInputKeyboard(): void {
this.buttonKeys.forEach((row, index) => { this.buttonKeys.forEach((row, index) => {
for (const key of row) { for (const key of row) {
key.on('down', () => { key.on("down", () => {
this.events.emit('input_down', { this.events.emit("input_down", {
controller_type: 'keyboard', controller_type: "keyboard",
button: index, button: index,
}); });
this.setLastProcessedMovementTime(index, 'keyboard'); this.setLastProcessedMovementTime(index, "keyboard");
}); });
key.on('up', () => { key.on("up", () => {
this.events.emit('input_up', { this.events.emit("input_up", {
controller_type: 'keyboard', controller_type: "keyboard",
button: index, button: index,
}); });
this.delLastProcessedMovementTime(index); this.delLastProcessedMovementTime(index);
@ -419,11 +426,11 @@ export class InputsController {
mapGamepad(id: string): GamepadConfig { mapGamepad(id: string): GamepadConfig {
id = id.toLowerCase(); id = id.toLowerCase();
if (id.includes('081f') && id.includes('e401')) { if (id.includes("081f") && id.includes("e401")) {
return pad_unlicensedSNES; return pad_unlicensedSNES;
} else if (id.includes('xbox') && id.includes('360')) { } else if (id.includes("xbox") && id.includes("360")) {
return pad_xbox360; return pad_xbox360;
} else if (id.includes('054c')) { } else if (id.includes("054c")) {
return pad_dualshock; return pad_dualshock;
} }
@ -436,7 +443,9 @@ export class InputsController {
* firing a repeated input - this is to prevent multiple buttons from firing repeatedly. * firing a repeated input - this is to prevent multiple buttons from firing repeatedly.
*/ */
repeatInputDurationJustPassed(button: Button): boolean { repeatInputDurationJustPassed(button: Button): boolean {
if (!this.isButtonLocked(button)) return false; if (!this.isButtonLocked(button)) {
return false;
}
if (this.time.now - this.interactions[button].pressTime >= repeatInputDelayMillis) { if (this.time.now - this.interactions[button].pressTime >= repeatInputDelayMillis) {
return true; return true;
} }
@ -457,8 +466,10 @@ export class InputsController {
* *
* Additionally, this method locks the button (by calling `setButtonLock`) to prevent it from being re-processed until it is released, ensuring that each press is handled distinctly. * Additionally, this method locks the button (by calling `setButtonLock`) to prevent it from being re-processed until it is released, ensuring that each press is handled distinctly.
*/ */
setLastProcessedMovementTime(button: Button, source: String = 'keyboard'): void { setLastProcessedMovementTime(button: Button, source: String = "keyboard"): void {
if (!this.interactions.hasOwnProperty(button)) return; if (!this.interactions.hasOwnProperty(button)) {
return;
}
this.setButtonLock(button); this.setButtonLock(button);
this.interactions[button].pressTime = this.time.now; this.interactions[button].pressTime = this.time.now;
this.interactions[button].isPressed = true; this.interactions[button].isPressed = true;
@ -480,7 +491,9 @@ export class InputsController {
* It releases the button lock, which prevents the button from being processed repeatedly until it's explicitly released. * It releases the button lock, which prevents the button from being processed repeatedly until it's explicitly released.
*/ */
delLastProcessedMovementTime(button: Button): void { delLastProcessedMovementTime(button: Button): void {
if (!this.interactions.hasOwnProperty(button)) return; if (!this.interactions.hasOwnProperty(button)) {
return;
}
this.releaseButtonLock(button); this.releaseButtonLock(button);
this.interactions[button].pressTime = null; this.interactions[button].pressTime = null;
this.interactions[button].isPressed = false; this.interactions[button].isPressed = false;
@ -543,11 +556,18 @@ export class InputsController {
* This mechanism allows for up to two buttons to be locked at the same time. * This mechanism allows for up to two buttons to be locked at the same time.
*/ */
setButtonLock(button: Button): void { setButtonLock(button: Button): void {
if (this.buttonLock === button || this.buttonLock2 === button) return; if (this.buttonLock === button || this.buttonLock2 === button) {
if (this.buttonLock === button) this.buttonLock2 = button; return;
else if (this.buttonLock2 === button) this.buttonLock = button; }
else if (!!this.buttonLock) this.buttonLock2 = button; if (this.buttonLock === button) {
else this.buttonLock = button; this.buttonLock2 = button;
} else if (this.buttonLock2 === button) {
this.buttonLock = button;
} else if (!!this.buttonLock) {
this.buttonLock2 = button;
} else {
this.buttonLock = button;
}
} }
/** /**
@ -561,7 +581,10 @@ export class InputsController {
* This action frees the button to be processed again, ensuring it can respond to new inputs. * This action frees the button to be processed again, ensuring it can respond to new inputs.
*/ */
releaseButtonLock(button: Button): void { releaseButtonLock(button: Button): void {
if (this.buttonLock === button) this.buttonLock = null; if (this.buttonLock === button) {
else if (this.buttonLock2 === button) this.buttonLock2 = null; this.buttonLock = null;
} else if (this.buttonLock2 === button) {
this.buttonLock2 = null;
}
} }
} }

View File

@ -12,268 +12,276 @@ import { initI18n } from "./plugins/i18n";
export class LoadingScene extends SceneBase { export class LoadingScene extends SceneBase {
constructor() { constructor() {
super('loading'); super("loading");
Phaser.Plugins.PluginCache.register('Loader', CacheBustedLoaderPlugin, 'load'); Phaser.Plugins.PluginCache.register("Loader", CacheBustedLoaderPlugin, "load");
initI18n(); initI18n();
} }
preload() { preload() {
this.load['manifest'] = this.game['manifest']; this.load["manifest"] = this.game["manifest"];
if (!isMobile()) if (!isMobile()) {
this.load.video('intro_dark', 'images/intro_dark.mp4', true); this.load.video("intro_dark", "images/intro_dark.mp4", true);
}
this.loadImage('loading_bg', 'arenas'); this.loadImage("loading_bg", "arenas");
this.loadImage('logo', ''); this.loadImage("logo", "");
// Load menu images // Load menu images
this.loadAtlas('bg', 'ui'); this.loadAtlas("bg", "ui");
this.loadImage('command_fight_labels', 'ui'); this.loadImage("command_fight_labels", "ui");
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('cursor', 'ui'); this.loadImage("cursor", "ui");
this.loadImage('cursor_reverse', 'ui'); this.loadImage("cursor_reverse", "ui");
for (let wv of Utils.getEnumValues(WindowVariant)) { for (const wv of Utils.getEnumValues(WindowVariant)) {
for (let w = 1; w <= 5; w++) for (let w = 1; w <= 5; w++) {
this.loadImage(`window_${w}${getWindowVariantSuffix(wv)}`, 'ui/windows'); this.loadImage(`window_${w}${getWindowVariantSuffix(wv)}`, "ui/windows");
} }
this.loadAtlas('namebox', 'ui'); }
this.loadImage('pbinfo_player', 'ui'); this.loadAtlas("namebox", "ui");
this.loadImage('pbinfo_player_stats', 'ui'); this.loadImage("pbinfo_player", "ui");
this.loadImage('pbinfo_player_mini', 'ui'); this.loadImage("pbinfo_player_stats", "ui");
this.loadImage('pbinfo_player_mini_stats', 'ui'); this.loadImage("pbinfo_player_mini", "ui");
this.loadAtlas('pbinfo_player_type', 'ui'); this.loadImage("pbinfo_player_mini_stats", "ui");
this.loadAtlas('pbinfo_player_type1', 'ui'); this.loadAtlas("pbinfo_player_type", "ui");
this.loadAtlas('pbinfo_player_type2', 'ui'); this.loadAtlas("pbinfo_player_type1", "ui");
this.loadImage('pbinfo_enemy_mini', 'ui'); this.loadAtlas("pbinfo_player_type2", "ui");
this.loadImage('pbinfo_enemy_mini_stats', 'ui'); this.loadImage("pbinfo_enemy_mini", "ui");
this.loadImage('pbinfo_enemy_boss', 'ui'); this.loadImage("pbinfo_enemy_mini_stats", "ui");
this.loadImage('pbinfo_enemy_boss_stats', 'ui'); this.loadImage("pbinfo_enemy_boss", "ui");
this.loadAtlas('pbinfo_enemy_type', 'ui'); this.loadImage("pbinfo_enemy_boss_stats", "ui");
this.loadAtlas('pbinfo_enemy_type1', 'ui'); this.loadAtlas("pbinfo_enemy_type", "ui");
this.loadAtlas('pbinfo_enemy_type2', 'ui'); this.loadAtlas("pbinfo_enemy_type1", "ui");
this.loadAtlas('pbinfo_stat', 'ui'); this.loadAtlas("pbinfo_enemy_type2", "ui");
this.loadAtlas('pbinfo_stat_numbers', 'ui'); this.loadAtlas("pbinfo_stat", "ui");
this.loadImage('overlay_lv', 'ui'); this.loadAtlas("pbinfo_stat_numbers", "ui");
this.loadAtlas('numbers', 'ui'); this.loadImage("overlay_lv", "ui");
this.loadAtlas('numbers_red', 'ui'); this.loadAtlas("numbers", "ui");
this.loadAtlas('overlay_hp', 'ui'); this.loadAtlas("numbers_red", "ui");
this.loadAtlas('overlay_hp_boss', 'ui'); this.loadAtlas("overlay_hp", "ui");
this.loadImage('overlay_exp', 'ui'); this.loadAtlas("overlay_hp_boss", "ui");
this.loadImage('icon_owned', 'ui'); this.loadImage("overlay_exp", "ui");
this.loadImage('ability_bar_left', 'ui'); this.loadImage("icon_owned", "ui");
this.loadImage('party_exp_bar', 'ui'); this.loadImage("ability_bar_left", "ui");
this.loadImage('achv_bar', 'ui'); this.loadImage("party_exp_bar", "ui");
this.loadImage('achv_bar_2', 'ui'); this.loadImage("achv_bar", "ui");
this.loadImage('achv_bar_3', 'ui'); this.loadImage("achv_bar_2", "ui");
this.loadImage('achv_bar_4', 'ui'); this.loadImage("achv_bar_3", "ui");
this.loadImage('achv_bar_5', 'ui'); this.loadImage("achv_bar_4", "ui");
this.loadImage('shiny_star', 'ui', 'shiny.png'); this.loadImage("achv_bar_5", "ui");
this.loadImage('shiny_star_1', 'ui', 'shiny_1.png'); this.loadImage("shiny_star", "ui", "shiny.png");
this.loadImage('shiny_star_2', 'ui', 'shiny_2.png'); this.loadImage("shiny_star_1", "ui", "shiny_1.png");
this.loadImage('shiny_star_small', 'ui', 'shiny_small.png'); this.loadImage("shiny_star_2", "ui", "shiny_2.png");
this.loadImage('shiny_star_small_1', 'ui', 'shiny_small_1.png'); this.loadImage("shiny_star_small", "ui", "shiny_small.png");
this.loadImage('shiny_star_small_2', 'ui', 'shiny_small_2.png'); this.loadImage("shiny_star_small_1", "ui", "shiny_small_1.png");
this.loadImage('ha_capsule', 'ui', 'ha_capsule.png'); this.loadImage("shiny_star_small_2", "ui", "shiny_small_2.png");
this.loadImage('champion_ribbon', 'ui', 'champion_ribbon.png'); this.loadImage("ha_capsule", "ui", "ha_capsule.png");
this.loadImage('icon_spliced', 'ui'); this.loadImage("champion_ribbon", "ui", "champion_ribbon.png");
this.loadImage('icon_tera', 'ui'); this.loadImage("icon_spliced", "ui");
this.loadImage('type_tera', 'ui'); this.loadImage("icon_tera", "ui");
this.loadAtlas('type_bgs', 'ui'); this.loadImage("type_tera", "ui");
this.loadAtlas("type_bgs", "ui");
this.loadImage('pb_tray_overlay_player', 'ui'); this.loadImage("pb_tray_overlay_player", "ui");
this.loadImage('pb_tray_overlay_enemy', 'ui'); this.loadImage("pb_tray_overlay_enemy", "ui");
this.loadAtlas('pb_tray_ball', 'ui'); this.loadAtlas("pb_tray_ball", "ui");
this.loadImage('party_bg', 'ui'); this.loadImage("party_bg", "ui");
this.loadImage('party_bg_double', 'ui'); this.loadImage("party_bg_double", "ui");
this.loadAtlas('party_slot_main', 'ui'); this.loadAtlas("party_slot_main", "ui");
this.loadAtlas('party_slot', 'ui'); this.loadAtlas("party_slot", "ui");
this.loadImage('party_slot_overlay_lv', 'ui'); this.loadImage("party_slot_overlay_lv", "ui");
this.loadImage('party_slot_hp_bar', 'ui'); this.loadImage("party_slot_hp_bar", "ui");
this.loadAtlas('party_slot_hp_overlay', 'ui'); this.loadAtlas("party_slot_hp_overlay", "ui");
this.loadAtlas('party_pb', 'ui'); this.loadAtlas("party_pb", "ui");
this.loadAtlas('party_cancel', 'ui'); this.loadAtlas("party_cancel", "ui");
this.loadImage('summary_bg', 'ui'); this.loadImage("summary_bg", "ui");
this.loadImage('summary_overlay_shiny', 'ui'); this.loadImage("summary_overlay_shiny", "ui");
this.loadImage('summary_profile', 'ui'); this.loadImage("summary_profile", "ui");
this.loadImage('summary_profile_prompt_z', 'ui') // The pixel Z button prompt this.loadImage("summary_profile_prompt_z", "ui"); // The pixel Z button prompt
this.loadImage('summary_profile_prompt_a', 'ui'); // The pixel A button prompt this.loadImage("summary_profile_prompt_a", "ui"); // The pixel A button prompt
this.loadImage('summary_profile_ability', 'ui'); // Pixel text 'ABILITY' this.loadImage("summary_profile_ability", "ui"); // Pixel text 'ABILITY'
this.loadImage('summary_profile_passive', 'ui'); // Pixel text 'PASSIVE' this.loadImage("summary_profile_passive", "ui"); // Pixel text 'PASSIVE'
this.loadImage('summary_status', 'ui'); this.loadImage("summary_status", "ui");
this.loadImage('summary_stats', 'ui'); this.loadImage("summary_stats", "ui");
this.loadImage('summary_stats_overlay_exp', 'ui'); this.loadImage("summary_stats_overlay_exp", "ui");
this.loadImage('summary_moves', 'ui'); this.loadImage("summary_moves", "ui");
this.loadImage('summary_moves_effect', 'ui'); this.loadImage("summary_moves_effect", "ui");
this.loadImage('summary_moves_overlay_row', 'ui'); this.loadImage("summary_moves_overlay_row", "ui");
this.loadImage('summary_moves_overlay_pp', 'ui'); this.loadImage("summary_moves_overlay_pp", "ui");
this.loadAtlas('summary_moves_cursor', 'ui'); this.loadAtlas("summary_moves_cursor", "ui");
for (let t = 1; t <= 3; t++) for (let t = 1; t <= 3; t++) {
this.loadImage(`summary_tabs_${t}`, 'ui'); this.loadImage(`summary_tabs_${t}`, "ui");
}
this.loadImage('starter_select_bg', 'ui'); this.loadImage("starter_select_bg", "ui");
this.loadImage('select_cursor', 'ui'); this.loadImage("select_cursor", "ui");
this.loadImage('select_cursor_highlight', 'ui'); this.loadImage("select_cursor_highlight", "ui");
this.loadImage('select_cursor_highlight_thick', 'ui'); this.loadImage("select_cursor_highlight_thick", "ui");
this.loadImage('select_cursor_pokerus', 'ui'); this.loadImage("select_cursor_pokerus", "ui");
this.loadImage('select_gen_cursor', 'ui'); this.loadImage("select_gen_cursor", "ui");
this.loadImage('select_gen_cursor_highlight', 'ui'); this.loadImage("select_gen_cursor_highlight", "ui");
this.loadImage('saving_icon', 'ui'); this.loadImage("saving_icon", "ui");
this.loadImage('default_bg', 'arenas'); this.loadImage("default_bg", "arenas");
// Load arena images // Load arena images
Utils.getEnumValues(Biome).map(bt => { Utils.getEnumValues(Biome).map(bt => {
const btKey = Biome[bt].toLowerCase(); const btKey = Biome[bt].toLowerCase();
const isBaseAnimated = btKey === 'end'; const isBaseAnimated = btKey === "end";
const baseAKey = `${btKey}_a`; const baseAKey = `${btKey}_a`;
const baseBKey = `${btKey}_b`; const baseBKey = `${btKey}_b`;
this.loadImage(`${btKey}_bg`, 'arenas'); this.loadImage(`${btKey}_bg`, "arenas");
if (!isBaseAnimated) if (!isBaseAnimated) {
this.loadImage(baseAKey, 'arenas'); this.loadImage(baseAKey, "arenas");
else } else {
this.loadAtlas(baseAKey, 'arenas'); this.loadAtlas(baseAKey, "arenas");
if (!isBaseAnimated) }
this.loadImage(baseBKey, 'arenas'); if (!isBaseAnimated) {
else this.loadImage(baseBKey, "arenas");
this.loadAtlas(baseBKey, 'arenas'); } else {
this.loadAtlas(baseBKey, "arenas");
}
if (getBiomeHasProps(bt)) { if (getBiomeHasProps(bt)) {
for (let p = 1; p <= 3; p++) { for (let p = 1; p <= 3; p++) {
const isPropAnimated = p === 3 && [ 'power_plant', 'end' ].find(b => b === btKey); const isPropAnimated = p === 3 && [ "power_plant", "end" ].find(b => b === btKey);
const propKey = `${btKey}_b_${p}`; const propKey = `${btKey}_b_${p}`;
if (!isPropAnimated) if (!isPropAnimated) {
this.loadImage(propKey, 'arenas'); this.loadImage(propKey, "arenas");
else } else {
this.loadAtlas(propKey, 'arenas'); this.loadAtlas(propKey, "arenas");
}
} }
} }
}); });
// Load bitmap fonts // Load bitmap fonts
this.load.bitmapFont('item-count', 'fonts/item-count.png', 'fonts/item-count.xml'); this.load.bitmapFont("item-count", "fonts/item-count.png", "fonts/item-count.xml");
// Load trainer images // Load trainer images
this.loadAtlas('trainer_m_back', 'trainer'); this.loadAtlas("trainer_m_back", "trainer");
this.loadAtlas('trainer_m_back_pb', 'trainer'); this.loadAtlas("trainer_m_back_pb", "trainer");
this.loadAtlas('trainer_f_back', 'trainer'); this.loadAtlas("trainer_f_back", "trainer");
this.loadAtlas('trainer_f_back_pb', 'trainer'); this.loadAtlas("trainer_f_back_pb", "trainer");
Utils.getEnumValues(TrainerType).map(tt => { Utils.getEnumValues(TrainerType).map(tt => {
const config = trainerConfigs[tt]; const config = trainerConfigs[tt];
this.loadAtlas(config.getSpriteKey(), 'trainer'); this.loadAtlas(config.getSpriteKey(), "trainer");
if (config.doubleOnly || config.hasDouble) if (config.doubleOnly || config.hasDouble) {
this.loadAtlas(config.getSpriteKey(true), 'trainer'); this.loadAtlas(config.getSpriteKey(true), "trainer");
}
}); });
// Load character sprites // Load character sprites
this.loadAtlas('c_rival_m', 'character', 'rival_m'); this.loadAtlas("c_rival_m", "character", "rival_m");
this.loadAtlas('c_rival_f', 'character', 'rival_f'); this.loadAtlas("c_rival_f", "character", "rival_f");
// Load pokemon-related images // Load pokemon-related images
this.loadImage(`pkmn__back__sub`, 'pokemon/back', 'sub.png'); this.loadImage("pkmn__back__sub", "pokemon/back", "sub.png");
this.loadImage(`pkmn__sub`, 'pokemon', 'sub.png'); this.loadImage("pkmn__sub", "pokemon", "sub.png");
this.loadAtlas('battle_stats', 'effects'); this.loadAtlas("battle_stats", "effects");
this.loadAtlas('shiny', 'effects'); this.loadAtlas("shiny", "effects");
this.loadAtlas('shiny_2', 'effects'); this.loadAtlas("shiny_2", "effects");
this.loadAtlas('shiny_3', 'effects'); this.loadAtlas("shiny_3", "effects");
this.loadImage('tera', 'effects'); this.loadImage("tera", "effects");
this.loadAtlas('pb_particles', 'effects'); this.loadAtlas("pb_particles", "effects");
this.loadImage('evo_sparkle', 'effects'); this.loadImage("evo_sparkle", "effects");
this.loadAtlas('tera_sparkle', 'effects'); this.loadAtlas("tera_sparkle", "effects");
this.load.video('evo_bg', 'images/effects/evo_bg.mp4', true); this.load.video("evo_bg", "images/effects/evo_bg.mp4", true);
this.loadAtlas('pb', ''); this.loadAtlas("pb", "");
this.loadAtlas('items', ''); this.loadAtlas("items", "");
this.loadAtlas('types', ''); this.loadAtlas("types", "");
this.loadAtlas('statuses', ''); this.loadAtlas("statuses", "");
this.loadAtlas('categories', ''); this.loadAtlas("categories", "");
this.loadAtlas('egg', 'egg'); this.loadAtlas("egg", "egg");
this.loadAtlas('egg_crack', 'egg'); this.loadAtlas("egg_crack", "egg");
this.loadAtlas('egg_icons', 'egg'); this.loadAtlas("egg_icons", "egg");
this.loadAtlas('egg_shard', 'egg'); this.loadAtlas("egg_shard", "egg");
this.loadAtlas('egg_lightrays', 'egg'); this.loadAtlas("egg_lightrays", "egg");
Utils.getEnumKeys(GachaType).forEach(gt => { Utils.getEnumKeys(GachaType).forEach(gt => {
const key = gt.toLowerCase(); const key = gt.toLowerCase();
this.loadImage(`gacha_${key}`, 'egg'); this.loadImage(`gacha_${key}`, "egg");
this.loadAtlas(`gacha_underlay_${key}`, 'egg'); this.loadAtlas(`gacha_underlay_${key}`, "egg");
}); });
this.loadImage('gacha_glass', 'egg'); this.loadImage("gacha_glass", "egg");
this.loadImage('gacha_eggs', 'egg'); this.loadImage("gacha_eggs", "egg");
this.loadAtlas('gacha_hatch', 'egg'); this.loadAtlas("gacha_hatch", "egg");
this.loadImage('gacha_knob', 'egg'); this.loadImage("gacha_knob", "egg");
this.loadImage('egg_list_bg', 'ui'); this.loadImage("egg_list_bg", "ui");
this.loadImage('end_m', 'cg'); this.loadImage("end_m", "cg");
this.loadImage('end_f', 'cg'); this.loadImage("end_f", "cg");
for (let i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
this.loadAtlas(`pokemon_icons_${i}`, ''); this.loadAtlas(`pokemon_icons_${i}`, "");
if (i) if (i) {
this.loadAtlas(`pokemon_icons_${i}v`, ''); this.loadAtlas(`pokemon_icons_${i}v`, "");
}
} }
this.loadSe('select'); this.loadSe("select");
this.loadSe('menu_open'); this.loadSe("menu_open");
this.loadSe('hit'); this.loadSe("hit");
this.loadSe('hit_strong'); this.loadSe("hit_strong");
this.loadSe('hit_weak'); this.loadSe("hit_weak");
this.loadSe('stat_up'); this.loadSe("stat_up");
this.loadSe('stat_down'); this.loadSe("stat_down");
this.loadSe('faint'); this.loadSe("faint");
this.loadSe('flee'); this.loadSe("flee");
this.loadSe('low_hp'); this.loadSe("low_hp");
this.loadSe('exp'); this.loadSe("exp");
this.loadSe('level_up'); this.loadSe("level_up");
this.loadSe('sparkle'); this.loadSe("sparkle");
this.loadSe('restore'); this.loadSe("restore");
this.loadSe('shine'); this.loadSe("shine");
this.loadSe('shing'); this.loadSe("shing");
this.loadSe('charge'); this.loadSe("charge");
this.loadSe('beam'); this.loadSe("beam");
this.loadSe('upgrade'); this.loadSe("upgrade");
this.loadSe('buy'); this.loadSe("buy");
this.loadSe('achv'); this.loadSe("achv");
this.loadSe('error'); this.loadSe("error");
this.loadSe('pb_rel'); this.loadSe("pb_rel");
this.loadSe('pb_throw'); this.loadSe("pb_throw");
this.loadSe('pb_bounce_1'); this.loadSe("pb_bounce_1");
this.loadSe('pb_bounce_2'); this.loadSe("pb_bounce_2");
this.loadSe('pb_move'); this.loadSe("pb_move");
this.loadSe('pb_catch'); this.loadSe("pb_catch");
this.loadSe('pb_lock'); this.loadSe("pb_lock");
this.loadSe('pb_tray_enter'); this.loadSe("pb_tray_enter");
this.loadSe('pb_tray_ball'); this.loadSe("pb_tray_ball");
this.loadSe('pb_tray_empty'); this.loadSe("pb_tray_empty");
this.loadSe('egg_crack'); this.loadSe("egg_crack");
this.loadSe('egg_hatch'); this.loadSe("egg_hatch");
this.loadSe('gacha_dial'); this.loadSe("gacha_dial");
this.loadSe('gacha_running'); this.loadSe("gacha_running");
this.loadSe('gacha_dispense'); this.loadSe("gacha_dispense");
this.loadSe('PRSFX- Transform', 'battle_anims'); this.loadSe("PRSFX- Transform", "battle_anims");
this.loadBgm('menu'); this.loadBgm("menu");
this.loadBgm('level_up_fanfare', 'bw/level_up_fanfare.mp3'); this.loadBgm("level_up_fanfare", "bw/level_up_fanfare.mp3");
this.loadBgm('item_fanfare', 'bw/item_fanfare.mp3'); this.loadBgm("item_fanfare", "bw/item_fanfare.mp3");
this.loadBgm('minor_fanfare', 'bw/minor_fanfare.mp3'); this.loadBgm("minor_fanfare", "bw/minor_fanfare.mp3");
this.loadBgm('heal', 'bw/heal.mp3'); this.loadBgm("heal", "bw/heal.mp3");
this.loadBgm('victory_trainer', 'bw/victory_trainer.mp3'); this.loadBgm("victory_trainer", "bw/victory_trainer.mp3");
this.loadBgm('victory_gym', 'bw/victory_gym.mp3'); this.loadBgm("victory_gym", "bw/victory_gym.mp3");
this.loadBgm('victory_champion', 'bw/victory_champion.mp3'); this.loadBgm("victory_champion", "bw/victory_champion.mp3");
this.loadBgm('evolution', 'bw/evolution.mp3'); this.loadBgm("evolution", "bw/evolution.mp3");
this.loadBgm('evolution_fanfare', 'bw/evolution_fanfare.mp3'); this.loadBgm("evolution_fanfare", "bw/evolution_fanfare.mp3");
this.load.plugin('rextexteditplugin', 'https://raw.githubusercontent.com/rexrainbow/phaser3-rex-notes/master/dist/rextexteditplugin.min.js', true); this.load.plugin("rextexteditplugin", "https://raw.githubusercontent.com/rexrainbow/phaser3-rex-notes/master/dist/rextexteditplugin.min.js", true);
this.loadLoadingScreen(); this.loadLoadingScreen();
} }
@ -283,7 +291,7 @@ export class LoadingScene extends SceneBase {
const loadingGraphics: any[] = []; const loadingGraphics: any[] = [];
const bg = this.add.image(0, 0, ''); const bg = this.add.image(0, 0, "");
bg.setOrigin(0, 0); bg.setOrigin(0, 0);
bg.setScale(6); bg.setScale(6);
bg.setVisible(false); bg.setVisible(false);
@ -300,7 +308,7 @@ export class LoadingScene extends SceneBase {
const width = this.cameras.main.width; const width = this.cameras.main.width;
const height = this.cameras.main.height; const height = this.cameras.main.height;
const logo = this.add.image(width / 2, 240, ''); const logo = this.add.image(width / 2, 240, "");
logo.setVisible(false); logo.setVisible(false);
logo.setOrigin(0.5, 0.5); logo.setOrigin(0.5, 0.5);
logo.setScale(4); logo.setScale(4);
@ -308,7 +316,7 @@ export class LoadingScene extends SceneBase {
const percentText = this.make.text({ const percentText = this.make.text({
x: width / 2, x: width / 2,
y: height / 2 - 24, y: height / 2 - 24,
text: '0%', text: "0%",
style: { style: {
font: "72px emerald", font: "72px emerald",
color: "#ffffff", color: "#ffffff",
@ -345,8 +353,9 @@ export class LoadingScene extends SceneBase {
loadingGraphics.push(bg, graphics, progressBar, progressBox, logo, percentText, assetText); loadingGraphics.push(bg, graphics, progressBar, progressBox, logo, percentText, assetText);
if (!mobile) if (!mobile) {
loadingGraphics.map(g => g.setVisible(false)); loadingGraphics.map(g => g.setVisible(false));
}
const destroyLoadingAssets = () => { const destroyLoadingAssets = () => {
intro.destroy(); intro.destroy();
@ -358,30 +367,32 @@ export class LoadingScene extends SceneBase {
assetText.destroy(); assetText.destroy();
}; };
this.load.on('filecomplete', key => { this.load.on("filecomplete", key => {
switch (key) { switch (key) {
case 'intro_dark': case "intro_dark":
intro.load('intro_dark'); intro.load("intro_dark");
intro.on('complete', () => { intro.on("complete", () => {
this.tweens.add({ this.tweens.add({
targets: intro, targets: intro,
duration: 500, duration: 500,
alpha: 0, alpha: 0,
ease: 'Sine.easeIn' ease: "Sine.easeIn"
}); });
loadingGraphics.map(g => g.setVisible(true)); loadingGraphics.map(g => g.setVisible(true));
}); });
intro.play(); intro.play();
break; break;
case 'loading_bg': case "loading_bg":
bg.setTexture('loading_bg'); bg.setTexture("loading_bg");
if (mobile) if (mobile) {
bg.setVisible(true); bg.setVisible(true);
}
break; break;
case 'logo': case "logo":
logo.setTexture('logo'); logo.setTexture("logo");
if (mobile) if (mobile) {
logo.setVisible(true); logo.setVisible(true);
}
break; break;
} }
}); });

View File

@ -1,5 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const abilityTriggers: SimpleTranslationEntries = { export const abilityTriggers: SimpleTranslationEntries = {
'blockRecoilDamage' : `{{pokemonName}} wurde durch {{abilityName}}\nvor Rückstoß geschützt!`, "blockRecoilDamage" : "{{pokemonName}} wurde durch {{abilityName}}\nvor Rückstoß geschützt!",
"badDreams": "{{pokemonName}} ist in einem Alptraum gefangen!",
} as const; } as const;

View File

@ -11,7 +11,7 @@ export const battle: SimpleTranslationEntries = {
"playerGo": "Los! {{pokemonName}}!", "playerGo": "Los! {{pokemonName}}!",
"trainerGo": "{{trainerName}} sendet {{pokemonName}} raus!", "trainerGo": "{{trainerName}} sendet {{pokemonName}} raus!",
"switchQuestion": "Möchtest du\n{{pokemonName}} auswechseln?", "switchQuestion": "Möchtest du\n{{pokemonName}} auswechseln?",
"trainerDefeated": `{{trainerName}}\nwurde besiegt!`, "trainerDefeated": "{{trainerName}}\nwurde besiegt!",
"pokemonCaught": "{{pokemonName}} wurde gefangen!", "pokemonCaught": "{{pokemonName}} wurde gefangen!",
"pokemon": "Pokémon", "pokemon": "Pokémon",
"sendOutPokemon": "Los, {{pokemonName}}!", "sendOutPokemon": "Los, {{pokemonName}}!",
@ -21,7 +21,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "Es hat keine Wirkung auf {{pokemonName}}…", "hitResultNoEffect": "Es hat keine Wirkung auf {{pokemonName}}…",
"hitResultOneHitKO": "Ein K.O.-Treffer!", "hitResultOneHitKO": "Ein K.O.-Treffer!",
"attackFailed": "Es ist fehlgeschlagen!", "attackFailed": "Es ist fehlgeschlagen!",
"attackHitsCount": `{{count}}-mal getroffen!`, "attackHitsCount": "{{count}}-mal getroffen!",
"expGain": "{{pokemonName}} erhält\n{{exp}} Erfahrungspunkte!", "expGain": "{{pokemonName}} erhält\n{{exp}} Erfahrungspunkte!",
"levelUp": "{{pokemonName}} erreicht\nLv. {{level}}!", "levelUp": "{{pokemonName}} erreicht\nLv. {{level}}!",
"learnMove": "{{pokemonName}} erlernt\n{{moveName}}!", "learnMove": "{{pokemonName}} erlernt\n{{moveName}}!",
@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = {
"noEscapeTrainer": "Du kannst nicht\naus einem Trainerkampf fliehen!", "noEscapeTrainer": "Du kannst nicht\naus einem Trainerkampf fliehen!",
"noEscapePokemon": "{{pokemonName}}'s {{moveName}}\nverhindert {{escapeVerb}}!", "noEscapePokemon": "{{pokemonName}}'s {{moveName}}\nverhindert {{escapeVerb}}!",
"runAwaySuccess": "Du bist entkommen!", "runAwaySuccess": "Du bist entkommen!",
"runAwayCannotEscape": 'Flucht gescheitert!', "runAwayCannotEscape": "Flucht gescheitert!",
"escapeVerbSwitch": "auswechseln", "escapeVerbSwitch": "auswechseln",
"escapeVerbFlee": "flucht", "escapeVerbFlee": "flucht",
"skipItemQuestion": "Bist du sicher, dass du kein Item nehmen willst?", "skipItemQuestion": "Bist du sicher, dass du kein Item nehmen willst?",

View File

@ -48,4 +48,4 @@ export const deConfig = {
battleMessageUiHandler: battleMessageUiHandler, battleMessageUiHandler: battleMessageUiHandler,
berry: berry, berry: berry,
voucher: voucher, voucher: voucher,
} };

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const menuUiHandler: SimpleTranslationEntries = { export const menuUiHandler: SimpleTranslationEntries = {
"GAME_SETTINGS": 'Spieleinstellungen', "GAME_SETTINGS": "Spieleinstellungen",
"ACHIEVEMENTS": "Erfolge", "ACHIEVEMENTS": "Erfolge",
"STATS": "Statistiken", "STATS": "Statistiken",
"VOUCHERS": "Gutscheine", "VOUCHERS": "Gutscheine",

View File

@ -198,7 +198,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"HEALING_CHARM": { name: "Heilungspin", description: "Erhöht die Effektivität von Heilungsattacken sowie Heilitems um 10% (Beleber ausgenommen)" }, "HEALING_CHARM": { name: "Heilungspin", description: "Erhöht die Effektivität von Heilungsattacken sowie Heilitems um 10% (Beleber ausgenommen)" },
"CANDY_JAR": { name: "Bonbonglas", description: "Erhöht die Anzahl der Level die ein Sonderbonbon erhöht um 1" }, "CANDY_JAR": { name: "Bonbonglas", description: "Erhöht die Anzahl der Level die ein Sonderbonbon erhöht um 1" },
"BERRY_POUCH": { name: "Beerentüte", description: "Fügt eine 25% Chance hinzu, dass Beeren nicht verbraucht werden" }, "BERRY_POUCH": { name: "Beerentüte", description: "Fügt eine 33% Chance hinzu, dass Beeren nicht verbraucht werden" },
"FOCUS_BAND": { name: "Fokusband", description: "Fügt eine 10% Chance hinzu, dass Angriffe die zur Kampfunfähigkeit führen mit 1 KP überlebt werden" }, "FOCUS_BAND": { name: "Fokusband", description: "Fügt eine 10% Chance hinzu, dass Angriffe die zur Kampfunfähigkeit führen mit 1 KP überlebt werden" },

View File

@ -41,4 +41,4 @@ export const starterSelectUiHandler: SimpleTranslationEntries = {
"locked": "Gesperrt", "locked": "Gesperrt",
"disabled": "Deaktiviert", "disabled": "Deaktiviert",
"uncaught": "Ungefangen" "uncaught": "Ungefangen"
} };

View File

@ -8,7 +8,7 @@ export const tutorial: SimpleTranslationEntries = {
$Für Fehlerberichte nutze bitte den PokéRogue Discord-Server. $Für Fehlerberichte nutze bitte den PokéRogue Discord-Server.
$Sollte das Spiel langsam laufen, überprüfe, ob in deinem Browser "Hardwarebeschleunigung" aktiviert ist.`, $Sollte das Spiel langsam laufen, überprüfe, ob in deinem Browser "Hardwarebeschleunigung" aktiviert ist.`,
"accessMenu": `Nutze M oder Esc, um das Menü zu öffnen. Dort hast du Zugriff auf die Einstellungen und andere Funktionen.`, "accessMenu": "Nutze M oder Esc, um das Menü zu öffnen. Dort hast du Zugriff auf die Einstellungen und andere Funktionen.",
"menu": `In diesem Menü hast du Zugriff auf die Einstellungen. "menu": `In diesem Menü hast du Zugriff auf die Einstellungen.
$Dort kannst du u. A. die Spielgeschwin-\ndigkeit und das Fensterdesign ändern. $Dort kannst du u. A. die Spielgeschwin-\ndigkeit und das Fensterdesign ändern.

View File

@ -1,11 +1,11 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const voucher: SimpleTranslationEntries = { export const voucher: SimpleTranslationEntries = {
"vouchers": "Vouchers", "vouchers": "Gutschein",
"eggVoucher": "Egg Voucher", "eggVoucher": "Ei-Gutschein",
"eggVoucherPlus": "Egg Voucher Plus", "eggVoucherPlus": "Ei-Gutschein Plus",
"eggVoucherPremium": "Egg Voucher Premium", "eggVoucherPremium": "Ei-Gutschein Premium",
"eggVoucherGold": "Egg Voucher Gold", "eggVoucherGold": "Ei-Gutschein Gold",
"locked": "Locked", "locked": "Gesperrt",
"defeatTrainer": "Defeat {{trainerName}}" "defeatTrainer": "Besiege {{trainerName}}"
} as const; } as const;

View File

@ -41,4 +41,4 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "Alle Flug-Pokémon werden von rätselhaften Luftströmungen geschützt!", "strongWindsStartMessage": "Alle Flug-Pokémon werden von rätselhaften Luftströmungen geschützt!",
"strongWindsLapseMessage": "Die rätselhafte Luftströmung hält an.", "strongWindsLapseMessage": "Die rätselhafte Luftströmung hält an.",
"strongWindsClearMessage": "Die rätselhafte Luftströmung hat sich wieder geleget.", "strongWindsClearMessage": "Die rätselhafte Luftströmung hat sich wieder geleget.",
} };

View File

@ -1,5 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const abilityTriggers: SimpleTranslationEntries = { export const abilityTriggers: SimpleTranslationEntries = {
'blockRecoilDamage' : `{{pokemonName}}'s {{abilityName}}\nprotected it from recoil!`, "blockRecoilDamage" : "{{pokemonName}}'s {{abilityName}}\nprotected it from recoil!",
"badDreams": "{{pokemonName}} is tormented!",
} as const; } as const;

View File

@ -439,7 +439,7 @@ export const ability: AbilityTranslationEntries = {
}, },
tintedLens: { tintedLens: {
name: "Tinted Lens", name: "Tinted Lens",
description: 'The Pokémon can use "not very effective" moves to deal regular damage.', description: "The Pokémon can use \"not very effective\" moves to deal regular damage.",
}, },
filter: { filter: {
name: "Filter", name: "Filter",
@ -751,7 +751,7 @@ export const ability: AbilityTranslationEntries = {
}, },
auraBreak: { auraBreak: {
name: "Aura Break", name: "Aura Break",
description: 'The effects of "Aura" Abilities are reversed to lower the power of affected moves.', description: "The effects of \"Aura\" Abilities are reversed to lower the power of affected moves.",
}, },
primordialSea: { primordialSea: {
name: "Primordial Sea", name: "Primordial Sea",

View File

@ -11,7 +11,7 @@ export const battle: SimpleTranslationEntries = {
"playerGo": "Go! {{pokemonName}}!", "playerGo": "Go! {{pokemonName}}!",
"trainerGo": "{{trainerName}} sent out {{pokemonName}}!", "trainerGo": "{{trainerName}} sent out {{pokemonName}}!",
"switchQuestion": "Will you switch\n{{pokemonName}}?", "switchQuestion": "Will you switch\n{{pokemonName}}?",
"trainerDefeated": `You defeated\n{{trainerName}}!`, "trainerDefeated": "You defeated\n{{trainerName}}!",
"pokemonCaught": "{{pokemonName}} was caught!", "pokemonCaught": "{{pokemonName}} was caught!",
"pokemon": "Pokémon", "pokemon": "Pokémon",
"sendOutPokemon": "Go! {{pokemonName}}!", "sendOutPokemon": "Go! {{pokemonName}}!",
@ -21,7 +21,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "It doesn't affect {{pokemonName}}!", "hitResultNoEffect": "It doesn't affect {{pokemonName}}!",
"hitResultOneHitKO": "It's a one-hit KO!", "hitResultOneHitKO": "It's a one-hit KO!",
"attackFailed": "But it failed!", "attackFailed": "But it failed!",
"attackHitsCount": `Hit {{count}} time(s)!`, "attackHitsCount": "Hit {{count}} time(s)!",
"expGain": "{{pokemonName}} gained\n{{exp}} EXP. Points!", "expGain": "{{pokemonName}} gained\n{{exp}} EXP. Points!",
"levelUp": "{{pokemonName}} grew to\nLv. {{level}}!", "levelUp": "{{pokemonName}} grew to\nLv. {{level}}!",
"learnMove": "{{pokemonName}} learned\n{{moveName}}!", "learnMove": "{{pokemonName}} learned\n{{moveName}}!",
@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = {
"noEscapeTrainer": "You can't run\nfrom a trainer battle!", "noEscapeTrainer": "You can't run\nfrom a trainer battle!",
"noEscapePokemon": "{{pokemonName}}'s {{moveName}}\nprevents {{escapeVerb}}!", "noEscapePokemon": "{{pokemonName}}'s {{moveName}}\nprevents {{escapeVerb}}!",
"runAwaySuccess": "You got away safely!", "runAwaySuccess": "You got away safely!",
"runAwayCannotEscape": 'You can\'t escape!', "runAwayCannotEscape": "You can't escape!",
"escapeVerbSwitch": "switching", "escapeVerbSwitch": "switching",
"escapeVerbFlee": "fleeing", "escapeVerbFlee": "fleeing",
"notDisabled": "{{pokemonName}}'s {{moveName}} is disabled\nno more!", "notDisabled": "{{pokemonName}}'s {{moveName}} is disabled\nno more!",

View File

@ -48,4 +48,4 @@ export const enConfig = {
battleMessageUiHandler: battleMessageUiHandler, battleMessageUiHandler: battleMessageUiHandler,
berry: berry, berry: berry,
voucher: voucher, voucher: voucher,
} };

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const menuUiHandler: SimpleTranslationEntries = { export const menuUiHandler: SimpleTranslationEntries = {
"GAME_SETTINGS": 'Game Settings', "GAME_SETTINGS": "Game Settings",
"ACHIEVEMENTS": "Achievements", "ACHIEVEMENTS": "Achievements",
"STATS": "Stats", "STATS": "Stats",
"VOUCHERS": "Vouchers", "VOUCHERS": "Vouchers",

View File

@ -185,7 +185,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"RELIC_GOLD": { name: "Relic Gold" }, "RELIC_GOLD": { name: "Relic Gold" },
"AMULET_COIN": { name: "Amulet Coin", description: "Increases money rewards by 20%" }, "AMULET_COIN": { name: "Amulet Coin", description: "Increases money rewards by 20%" },
"GOLDEN_PUNCH": { name: "Golden Punch", description: "Grants 50% of damage inflicted as money" }, "GOLDEN_PUNCH": { name: "Golden Punch", description: "Grants 50% of direct damage inflicted as money" },
"COIN_CASE": { name: "Coin Case", description: "After every 10th battle, receive 10% of your money in interest" }, "COIN_CASE": { name: "Coin Case", description: "After every 10th battle, receive 10% of your money in interest" },
"LOCK_CAPSULE": { name: "Lock Capsule", description: "Allows you to lock item rarities when rerolling items" }, "LOCK_CAPSULE": { name: "Lock Capsule", description: "Allows you to lock item rarities when rerolling items" },
@ -198,7 +198,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"HEALING_CHARM": { name: "Healing Charm", description: "Increases the effectiveness of HP restoring moves and items by 10% (excludes Revives)" }, "HEALING_CHARM": { name: "Healing Charm", description: "Increases the effectiveness of HP restoring moves and items by 10% (excludes Revives)" },
"CANDY_JAR": { name: "Candy Jar", description: "Increases the number of levels added by Rare Candy items by 1" }, "CANDY_JAR": { name: "Candy Jar", description: "Increases the number of levels added by Rare Candy items by 1" },
"BERRY_POUCH": { name: "Berry Pouch", description: "Adds a 25% chance that a used berry will not be consumed" }, "BERRY_POUCH": { name: "Berry Pouch", description: "Adds a 33% chance that a used berry will not be consumed" },
"FOCUS_BAND": { name: "Focus Band", description: "Adds a 10% chance to survive with 1 HP after being damaged enough to faint" }, "FOCUS_BAND": { name: "Focus Band", description: "Adds a 10% chance to survive with 1 HP after being damaged enough to faint" },

View File

@ -17,7 +17,7 @@ export const splashMessages: SimpleTranslationEntries = {
"brokenEggMoves": "Broken Egg Moves!", "brokenEggMoves": "Broken Egg Moves!",
"magnificent": "Magnificent!", "magnificent": "Magnificent!",
"mubstitute": "Mubstitute!", "mubstitute": "Mubstitute!",
"thatsCrazy": "That\'s Crazy!", "thatsCrazy": "That's Crazy!",
"oranceJuice": "Orance Juice!", "oranceJuice": "Orance Juice!",
"questionableBalancing": "Questionable Balancing!", "questionableBalancing": "Questionable Balancing!",
"coolShaders": "Cool Shaders!", "coolShaders": "Cool Shaders!",
@ -26,9 +26,9 @@ export const splashMessages: SimpleTranslationEntries = {
"basedOnAnUnfinishedFlashGame": "Based on an Unfinished Flash Game!", "basedOnAnUnfinishedFlashGame": "Based on an Unfinished Flash Game!",
"moreAddictiveThanIntended": "More Addictive than Intended!", "moreAddictiveThanIntended": "More Addictive than Intended!",
"mostlyConsistentSeeds": "Mostly Consistent Seeds!", "mostlyConsistentSeeds": "Mostly Consistent Seeds!",
"achievementPointsDontDoAnything": "Achievement Points Don\'t Do Anything!", "achievementPointsDontDoAnything": "Achievement Points Don't Do Anything!",
"youDoNotStartAtLevel": "You Do Not Start at Level 2000!", "youDoNotStartAtLevel": "You Do Not Start at Level 2000!",
"dontTalkAboutTheManaphyEggIncident": "Don\'t Talk About the Manaphy Egg Incident!", "dontTalkAboutTheManaphyEggIncident": "Don't Talk About the Manaphy Egg Incident!",
"alsoTryPokengine": "Also Try Pokéngine!", "alsoTryPokengine": "Also Try Pokéngine!",
"alsoTryEmeraldRogue": "Also Try Emerald Rogue!", "alsoTryEmeraldRogue": "Also Try Emerald Rogue!",
"alsoTryRadicalRed": "Also Try Radical Red!", "alsoTryRadicalRed": "Also Try Radical Red!",

View File

@ -6,7 +6,7 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
* account interactions, descriptive text, etc. * account interactions, descriptive text, etc.
*/ */
export const starterSelectUiHandler: SimpleTranslationEntries = { export const starterSelectUiHandler: SimpleTranslationEntries = {
"confirmStartTeam":'Begin with these Pokémon?', "confirmStartTeam":"Begin with these Pokémon?",
"gen1": "I", "gen1": "I",
"gen2": "II", "gen2": "II",
"gen3": "III", "gen3": "III",
@ -20,25 +20,25 @@ export const starterSelectUiHandler: SimpleTranslationEntries = {
"ability": "Ability:", "ability": "Ability:",
"passive": "Passive:", "passive": "Passive:",
"nature": "Nature:", "nature": "Nature:",
"eggMoves": 'Egg Moves', "eggMoves": "Egg Moves",
"start": "Start", "start": "Start",
"addToParty": "Add to Party", "addToParty": "Add to Party",
"toggleIVs": 'Toggle IVs', "toggleIVs": "Toggle IVs",
"manageMoves": 'Manage Moves', "manageMoves": "Manage Moves",
"useCandies": 'Use Candies', "useCandies": "Use Candies",
"selectMoveSwapOut": "Select a move to swap out.", "selectMoveSwapOut": "Select a move to swap out.",
"selectMoveSwapWith": "Select a move to swap with", "selectMoveSwapWith": "Select a move to swap with",
"unlockPassive": "Unlock Passive", "unlockPassive": "Unlock Passive",
"reduceCost": "Reduce Cost", "reduceCost": "Reduce Cost",
"cycleShiny": "R: Cycle Shiny", "cycleShiny": "R: Cycle Shiny",
"cycleForm": 'F: Cycle Form', "cycleForm": "F: Cycle Form",
"cycleGender": 'G: Cycle Gender', "cycleGender": "G: Cycle Gender",
"cycleAbility": 'E: Cycle Ability', "cycleAbility": "E: Cycle Ability",
"cycleNature": 'N: Cycle Nature', "cycleNature": "N: Cycle Nature",
"cycleVariant": 'V: Cycle Variant', "cycleVariant": "V: Cycle Variant",
"enablePassive": "Enable Passive", "enablePassive": "Enable Passive",
"disablePassive": "Disable Passive", "disablePassive": "Disable Passive",
"locked": "Locked", "locked": "Locked",
"disabled": "Disabled", "disabled": "Disabled",
"uncaught": "Uncaught" "uncaught": "Uncaught"
} };

View File

@ -6,7 +6,7 @@ export const tutorial: SimpleTranslationEntries = {
$The game is a work in progress, but fully playable.\nFor bug reports, please use the Discord community. $The game is a work in progress, but fully playable.\nFor bug reports, please use the Discord community.
$If the game runs slowly, please ensure 'Hardware Acceleration' is turned on in your browser settings.`, $If the game runs slowly, please ensure 'Hardware Acceleration' is turned on in your browser settings.`,
"accessMenu": `To access the menu, press M or Escape while awaiting input.\nThe menu contains settings and various features.`, "accessMenu": "To access the menu, press M or Escape while awaiting input.\nThe menu contains settings and various features.",
"menu": `From this menu you can access the settings. "menu": `From this menu you can access the settings.
$From the settings you can change game speed, window style, and other options. $From the settings you can change game speed, window style, and other options.

View File

@ -41,4 +41,4 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "A heavy wind began!", "strongWindsStartMessage": "A heavy wind began!",
"strongWindsLapseMessage": "The wind blows intensely.", "strongWindsLapseMessage": "The wind blows intensely.",
"strongWindsClearMessage": "The heavy wind stopped." "strongWindsClearMessage": "The heavy wind stopped."
} };

View File

@ -1,5 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const abilityTriggers: SimpleTranslationEntries = { export const abilityTriggers: SimpleTranslationEntries = {
'blockRecoilDamage' : `{{pokemonName}}'s {{abilityName}}\nprotected it from recoil!`, "blockRecoilDamage" : "{{pokemonName}}'s {{abilityName}}\nprotected it from recoil!",
"badDreams": "{{pokemonName}} Está atormentado!"
} as const; } as const;

View File

@ -1,10 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const battleMessageUiHandler: SimpleTranslationEntries = { export const battleMessageUiHandler: SimpleTranslationEntries = {
"ivBest": "Best", "ivBest": "Inmejorable",
"ivFantastic": "Fantastic", "ivFantastic": "Fantástico",
"ivVeryGood": "Very Good", "ivVeryGood": "Notable",
"ivPrettyGood": "Pretty Good", "ivPrettyGood": "Genial",
"ivDecent": "Decent", "ivDecent": "No está mal",
"ivNoGood": "No Good", "ivNoGood": "Cojea un poco",
} as const; } as const;

View File

@ -21,7 +21,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "No afecta a {{pokemonName}}!", "hitResultNoEffect": "No afecta a {{pokemonName}}!",
"hitResultOneHitKO": "!KO en 1 golpe!", "hitResultOneHitKO": "!KO en 1 golpe!",
"attackFailed": "¡Pero ha fallado!", "attackFailed": "¡Pero ha fallado!",
"attackHitsCount": `N.º de golpes: {{count}}.`, "attackHitsCount": "N.º de golpes: {{count}}.",
"expGain": "{{pokemonName}} ha ganado\n{{exp}} puntos de experiencia.", "expGain": "{{pokemonName}} ha ganado\n{{exp}} puntos de experiencia.",
"levelUp": "¡{{pokemonName}} ha subido al \nNv. {{level}}!", "levelUp": "¡{{pokemonName}} ha subido al \nNv. {{level}}!",
"learnMove": "¡{{pokemonName}} ha aprendido {{moveName}}!", "learnMove": "¡{{pokemonName}} ha aprendido {{moveName}}!",

View File

@ -2,47 +2,47 @@ import { BerryTranslationEntries } from "#app/plugins/i18n";
export const berry: BerryTranslationEntries = { export const berry: BerryTranslationEntries = {
"SITRUS": { "SITRUS": {
name: "Sitrus Berry", name: "Baya Zidra",
effect: "Restores 25% HP if HP is below 50%", effect: "Restaura 25% PS si estos caen por debajo del 50%",
}, },
"LUM": { "LUM": {
name: "Lum Berry", name: "Baya Ziuela",
effect: "Cures any non-volatile status condition and confusion", effect: "Cura cualquier problema de estado",
}, },
"ENIGMA": { "ENIGMA": {
name: "Enigma Berry", name: "Baya Enigma",
effect: "Restores 25% HP if hit by a super effective move", effect: "Restaura 25% PS si le alcanza un ataque supereficaz",
}, },
"LIECHI": { "LIECHI": {
name: "Liechi Berry", name: "Baya Lichi",
effect: "Raises Attack if HP is below 25%", effect: "Aumenta el ataque si los PS están por debajo de 25%",
}, },
"GANLON": { "GANLON": {
name: "Ganlon Berry", name: "Baya Gonlan",
effect: "Raises Defense if HP is below 25%", effect: "Aumenta la defensa si los PS están por debajo de 25%",
}, },
"PETAYA": { "PETAYA": {
name: "Petaya Berry", name: "Baya Yapati",
effect: "Raises Sp. Atk if HP is below 25%", effect: "Aumenta el ataque especial si los PS están por debajo de 25%",
}, },
"APICOT": { "APICOT": {
name: "Apicot Berry", name: "Baya Aricoc",
effect: "Raises Sp. Def if HP is below 25%", effect: "Aumenta la defensa especial si los PS están por debajo de 25%",
}, },
"SALAC": { "SALAC": {
name: "Salac Berry", name: "Baya Aslac",
effect: "Raises Speed if HP is below 25%", effect: "Aumenta la velocidad si los PS están por debajo de 25%",
}, },
"LANSAT": { "LANSAT": {
name: "Lansat Berry", name: "Baya Zonlan",
effect: "Raises critical hit ratio if HP is below 25%", effect: "Aumenta el índice de golpe crítico si los PS están por debajo de 25%",
}, },
"STARF": { "STARF": {
name: "Starf Berry", name: "Baya Arabol",
effect: "Sharply raises a random stat if HP is below 25%", effect: "Aumenta mucho una estadística al azar si los PS están por debajo de 25%",
}, },
"LEPPA": { "LEPPA": {
name: "Leppa Berry", name: "Baya Zanama",
effect: "Restores 10 PP to a move if its PP reaches 0", effect: "Restaura 10 PP del primer movimiento cuyos PP bajen a 0",
}, },
} as const; } as const;

View File

@ -48,4 +48,4 @@ export const esConfig = {
battleMessageUiHandler: battleMessageUiHandler, battleMessageUiHandler: battleMessageUiHandler,
berry: berry, berry: berry,
voucher: voucher, voucher: voucher,
} };

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const menuUiHandler: SimpleTranslationEntries = { export const menuUiHandler: SimpleTranslationEntries = {
"GAME_SETTINGS": 'Ajustes', "GAME_SETTINGS": "Ajustes",
"ACHIEVEMENTS": "Logros", "ACHIEVEMENTS": "Logros",
"STATS": "Estadísticas", "STATS": "Estadísticas",
"VOUCHERS": "Vales", "VOUCHERS": "Vales",
@ -9,7 +9,7 @@ export const menuUiHandler: SimpleTranslationEntries = {
"EGG_GACHA": "Gacha de Huevos", "EGG_GACHA": "Gacha de Huevos",
"MANAGE_DATA": "Gestionar Datos", "MANAGE_DATA": "Gestionar Datos",
"COMMUNITY": "Comunidad", "COMMUNITY": "Comunidad",
"SAVE_AND_QUIT": "Save and Quit", "SAVE_AND_QUIT": "Guardar y Salir",
"LOG_OUT": "Cerrar Sesión", "LOG_OUT": "Cerrar Sesión",
"slot": "Ranura {{slotNumber}}", "slot": "Ranura {{slotNumber}}",
"importSession": "Importar Sesión", "importSession": "Importar Sesión",

View File

@ -198,7 +198,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"HEALING_CHARM": { name: "Healing Charm", description: "Increases the effectiveness of HP restoring moves and items by 10% (excludes Revives)" }, "HEALING_CHARM": { name: "Healing Charm", description: "Increases the effectiveness of HP restoring moves and items by 10% (excludes Revives)" },
"CANDY_JAR": { name: "Candy Jar", description: "Increases the number of levels added by Rare Candy items by 1" }, "CANDY_JAR": { name: "Candy Jar", description: "Increases the number of levels added by Rare Candy items by 1" },
"BERRY_POUCH": { name: "Berry Pouch", description: "Adds a 25% chance that a used berry will not be consumed" }, "BERRY_POUCH": { name: "Berry Pouch", description: "Adds a 33% chance that a used berry will not be consumed" },
"FOCUS_BAND": { name: "Focus Band", description: "Adds a 10% chance to survive with 1 HP after being damaged enough to faint" }, "FOCUS_BAND": { name: "Focus Band", description: "Adds a 10% chance to survive with 1 HP after being damaged enough to faint" },

View File

@ -2,8 +2,8 @@ import { PokemonInfoTranslationEntries } from "#app/plugins/i18n";
export const pokemonInfo: PokemonInfoTranslationEntries = { export const pokemonInfo: PokemonInfoTranslationEntries = {
Stat: { Stat: {
"HP": "PV", "HP": "PS",
"HPshortened": "PV", "HPshortened": "PS",
"ATK": "Ataque", "ATK": "Ataque",
"ATKshortened": "Ata", "ATKshortened": "Ata",
"DEF": "Defensa", "DEF": "Defensa",
@ -17,25 +17,25 @@ export const pokemonInfo: PokemonInfoTranslationEntries = {
}, },
Type: { Type: {
"UNKNOWN": "Unknown", "UNKNOWN": "Desconocido",
"NORMAL": "Normal", "NORMAL": "Normal",
"FIGHTING": "Fighting", "FIGHTING": "Lucha",
"FLYING": "Flying", "FLYING": "Volador",
"POISON": "Poison", "POISON": "Veneno",
"GROUND": "Ground", "GROUND": "Tierra",
"ROCK": "Rock", "ROCK": "Roca",
"BUG": "Bug", "BUG": "Bicho",
"GHOST": "Ghost", "GHOST": "Fantasma",
"STEEL": "Steel", "STEEL": "Acero",
"FIRE": "Fire", "FIRE": "Fuego",
"WATER": "Water", "WATER": "Agua",
"GRASS": "Grass", "GRASS": "Planta",
"ELECTRIC": "Electric", "ELECTRIC": "Eléctrico",
"PSYCHIC": "Psychic", "PSYCHIC": "Psíquico",
"ICE": "Ice", "ICE": "Hielo",
"DRAGON": "Dragon", "DRAGON": "Dragón",
"DARK": "Dark", "DARK": "Siniestro",
"FAIRY": "Fairy", "FAIRY": "Hada",
"STELLAR": "Stellar", "STELLAR": "Astral",
}, },
} as const; } as const;

View File

@ -17,7 +17,7 @@ export const splashMessages: SimpleTranslationEntries = {
"brokenEggMoves": "Broken Egg Moves!", "brokenEggMoves": "Broken Egg Moves!",
"magnificent": "Magnificent!", "magnificent": "Magnificent!",
"mubstitute": "Mubstitute!", "mubstitute": "Mubstitute!",
"thatsCrazy": "That\'s Crazy!", "thatsCrazy": "That's Crazy!",
"oranceJuice": "Orance Juice!", "oranceJuice": "Orance Juice!",
"questionableBalancing": "Questionable Balancing!", "questionableBalancing": "Questionable Balancing!",
"coolShaders": "Cool Shaders!", "coolShaders": "Cool Shaders!",
@ -26,9 +26,9 @@ export const splashMessages: SimpleTranslationEntries = {
"basedOnAnUnfinishedFlashGame": "Based on an Unfinished Flash Game!", "basedOnAnUnfinishedFlashGame": "Based on an Unfinished Flash Game!",
"moreAddictiveThanIntended": "More Addictive than Intended!", "moreAddictiveThanIntended": "More Addictive than Intended!",
"mostlyConsistentSeeds": "Mostly Consistent Seeds!", "mostlyConsistentSeeds": "Mostly Consistent Seeds!",
"achievementPointsDontDoAnything": "Achievement Points Don\'t Do Anything!", "achievementPointsDontDoAnything": "Achievement Points Don't Do Anything!",
"youDoNotStartAtLevel": "You Do Not Start at Level 2000!", "youDoNotStartAtLevel": "You Do Not Start at Level 2000!",
"dontTalkAboutTheManaphyEggIncident": "Don\'t Talk About the Manaphy Egg Incident!", "dontTalkAboutTheManaphyEggIncident": "Don't Talk About the Manaphy Egg Incident!",
"alsoTryPokengine": "Also Try Pokéngine!", "alsoTryPokengine": "Also Try Pokéngine!",
"alsoTryEmeraldRogue": "Also Try Emerald Rogue!", "alsoTryEmeraldRogue": "Also Try Emerald Rogue!",
"alsoTryRadicalRed": "Also Try Radical Red!", "alsoTryRadicalRed": "Also Try Radical Red!",

View File

@ -6,7 +6,7 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
* account interactions, descriptive text, etc. * account interactions, descriptive text, etc.
*/ */
export const starterSelectUiHandler: SimpleTranslationEntries = { export const starterSelectUiHandler: SimpleTranslationEntries = {
"confirmStartTeam":'¿Comenzar con estos Pokémon?', "confirmStartTeam":"¿Comenzar con estos Pokémon?",
"gen1": "I", "gen1": "I",
"gen2": "II", "gen2": "II",
"gen3": "III", "gen3": "III",
@ -31,14 +31,14 @@ export const starterSelectUiHandler: SimpleTranslationEntries = {
"unlockPassive": "Añadir Pasiva", "unlockPassive": "Añadir Pasiva",
"reduceCost": "Reducir Coste", "reduceCost": "Reducir Coste",
"cycleShiny": "R: Cambiar Shiny", "cycleShiny": "R: Cambiar Shiny",
"cycleForm": 'F: Cambiar Forma', "cycleForm": "F: Cambiar Forma",
"cycleGender": 'G: Cambiar Género', "cycleGender": "G: Cambiar Género",
"cycleAbility": 'E: Cambiar Habilidad', "cycleAbility": "E: Cambiar Habilidad",
"cycleNature": 'N: Cambiar Naturaleza', "cycleNature": "N: Cambiar Naturaleza",
"cycleVariant": 'V: Cambiar Variante', "cycleVariant": "V: Cambiar Variante",
"enablePassive": "Activar Pasiva", "enablePassive": "Activar Pasiva",
"disablePassive": "Desactivar Pasiva", "disablePassive": "Desactivar Pasiva",
"locked": "Locked", "locked": "Locked",
"disabled": "Disabled", "disabled": "Disabled",
"uncaught": "Uncaught" "uncaught": "Uncaught"
} };

View File

@ -41,4 +41,4 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "A heavy wind began!", "strongWindsStartMessage": "A heavy wind began!",
"strongWindsLapseMessage": "The wind blows intensely.", "strongWindsLapseMessage": "The wind blows intensely.",
"strongWindsClearMessage": "The heavy wind stopped." "strongWindsClearMessage": "The heavy wind stopped."
} };

View File

@ -1,5 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const abilityTriggers: SimpleTranslationEntries = { export const abilityTriggers: SimpleTranslationEntries = {
'blockRecoilDamage' : `{{abilityName}}\nde {{pokemonName}} le protège du contrecoup !`, "blockRecoilDamage" : "{{abilityName}}\nde {{pokemonName}} le protège du contrecoup !",
"badDreams": "{{pokemonName}} a le sommeil agité !"
} as const; } as const;

View File

@ -11,7 +11,7 @@ export const battle: SimpleTranslationEntries = {
"playerGo": "{{pokemonName}} ! Go !", "playerGo": "{{pokemonName}} ! Go !",
"trainerGo": "{{pokemonName}} est envoyé par\n{{trainerName}} !", "trainerGo": "{{pokemonName}} est envoyé par\n{{trainerName}} !",
"switchQuestion": "Voulez-vous changer\nvotre {{pokemonName}} ?", "switchQuestion": "Voulez-vous changer\nvotre {{pokemonName}} ?",
"trainerDefeated": `Vous avez battu\n{{trainerName}} !`, "trainerDefeated": "Vous avez battu\n{{trainerName}} !",
"pokemonCaught": "Vous avez attrapé {{pokemonName}} !", "pokemonCaught": "Vous avez attrapé {{pokemonName}} !",
"pokemon": "Pokémon", "pokemon": "Pokémon",
"sendOutPokemon": "{{pokemonName}} ! Go !", "sendOutPokemon": "{{pokemonName}} ! Go !",
@ -21,7 +21,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "Ça naffecte pas {{pokemonName}}…", "hitResultNoEffect": "Ça naffecte pas {{pokemonName}}…",
"hitResultOneHitKO": "K.O. en un coup !", "hitResultOneHitKO": "K.O. en un coup !",
"attackFailed": "Mais cela échoue !", "attackFailed": "Mais cela échoue !",
"attackHitsCount": `Touché {{count}} fois !`, "attackHitsCount": "Touché {{count}} fois !",
"expGain": "{{pokemonName}} gagne\n{{exp}} Points dExp !", "expGain": "{{pokemonName}} gagne\n{{exp}} Points dExp !",
"levelUp": "{{pokemonName}} monte au\nN. {{level}} !", "levelUp": "{{pokemonName}} monte au\nN. {{level}} !",
"learnMove": "{{pokemonName}} apprend\n{{moveName}} !", "learnMove": "{{pokemonName}} apprend\n{{moveName}} !",

View File

@ -48,4 +48,4 @@ export const frConfig = {
battleMessageUiHandler: battleMessageUiHandler, battleMessageUiHandler: battleMessageUiHandler,
berry: berry, berry: berry,
voucher: voucher, voucher: voucher,
} };

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const menuUiHandler: SimpleTranslationEntries = { export const menuUiHandler: SimpleTranslationEntries = {
"GAME_SETTINGS": 'Paramètres', "GAME_SETTINGS": "Paramètres",
"ACHIEVEMENTS": "Succès", "ACHIEVEMENTS": "Succès",
"STATS": "Statistiques", "STATS": "Statistiques",
"VOUCHERS": "Coupons", "VOUCHERS": "Coupons",

View File

@ -198,7 +198,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"HEALING_CHARM": { name: "Charme Soin", description: "Augmente de 10% lefficacité des capacités et objets de soin de PV (hors Rappels)" }, "HEALING_CHARM": { name: "Charme Soin", description: "Augmente de 10% lefficacité des capacités et objets de soin de PV (hors Rappels)" },
"CANDY_JAR": { name: "Jarre de Bonbons", description: "Augmente de 1 le nombre de niveaux gagnés à lutilisation dun Super Bonbon" }, "CANDY_JAR": { name: "Jarre de Bonbons", description: "Augmente de 1 le nombre de niveaux gagnés à lutilisation dun Super Bonbon" },
"BERRY_POUCH": { name: "Sac à Baies", description: "Ajoute 25% de chances quune Baie utilisée ne soit pas consommée" }, "BERRY_POUCH": { name: "Sac à Baies", description: "Ajoute 33% de chances quune Baie utilisée ne soit pas consommée" },
"FOCUS_BAND": { name: "Bandeau", description: "Ajoute 10% de chances de survivre avec 1 PV si les dégâts reçus pouvaient mettre K.O." }, "FOCUS_BAND": { name: "Bandeau", description: "Ajoute 10% de chances de survivre avec 1 PV si les dégâts reçus pouvaient mettre K.O." },

View File

@ -6,7 +6,7 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
* account interactions, descriptive text, etc. * account interactions, descriptive text, etc.
*/ */
export const starterSelectUiHandler: SimpleTranslationEntries = { export const starterSelectUiHandler: SimpleTranslationEntries = {
"confirmStartTeam":'Commencer avec ces Pokémon ?', "confirmStartTeam":"Commencer avec ces Pokémon ?",
"gen1": "1G", "gen1": "1G",
"gen2": "2G", "gen2": "2G",
"gen3": "3G", "gen3": "3G",
@ -41,4 +41,4 @@ export const starterSelectUiHandler: SimpleTranslationEntries = {
"locked": "Verrouillé", "locked": "Verrouillé",
"disabled": "Désactivé", "disabled": "Désactivé",
"uncaught": "Non-capturé" "uncaught": "Non-capturé"
} };

View File

@ -41,4 +41,4 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "Un vent mystérieux se lève !", "strongWindsStartMessage": "Un vent mystérieux se lève !",
"strongWindsLapseMessage": "Le vent mystérieux souffle violemment !", "strongWindsLapseMessage": "Le vent mystérieux souffle violemment !",
"strongWindsClearMessage": "Le vent mystérieux sest dissipé…" "strongWindsClearMessage": "Le vent mystérieux sest dissipé…"
} };

View File

@ -1,5 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const abilityTriggers: SimpleTranslationEntries = { export const abilityTriggers: SimpleTranslationEntries = {
'blockRecoilDamage' : `{{abilityName}} di {{pokemonName}}\nl'ha protetto dal contraccolpo!`, "blockRecoilDamage" : "{{abilityName}} di {{pokemonName}}\nl'ha protetto dal contraccolpo!",
"badDreams": "{{pokemonName}} è tormentato!",
} as const; } as const;

View File

@ -711,7 +711,7 @@ export const ability: AbilityTranslationEntries = {
}, },
megaLauncher: { megaLauncher: {
name: "Megalancio", name: "Megalancio",
description: 'Potenzia le mosse "pulsar", Forzasfera e Ondasana.', description: "Potenzia le mosse \"pulsar\", Forzasfera e Ondasana.",
}, },
grassPelt: { grassPelt: {
name: "Peloderba", name: "Peloderba",
@ -1194,36 +1194,36 @@ export const ability: AbilityTranslationEntries = {
description: "Quando usa mosse di stato, il Pokémon agisce più lentamente, ma ignora l'abilità del bersaglio se questa ha effetto su tali mosse.", description: "Quando usa mosse di stato, il Pokémon agisce più lentamente, ma ignora l'abilità del bersaglio se questa ha effetto su tali mosse.",
}, },
mindsEye: { mindsEye: {
name: "Ospitalità",
description: "Quando un Pokémon con questa abilità entra in campo ricopre di attenzioni l'alleato, restituendogli un po' dei suoi PS.",
},
supersweetSyrup: {
name: "Occhio Interiore", name: "Occhio Interiore",
description: "Permette di colpire bersagli di tipo Spettro con mosse di tipo Normale e Lotta, di ignorare modifiche alla loro elusione e di non veder ridotta la propria precisione.", description: "Permette di colpire bersagli di tipo Spettro con mosse di tipo Normale e Lotta, di ignorare modifiche alla loro elusione e di non veder ridotta la propria precisione.",
}, },
supersweetSyrup: {
name: "Sciroppo Sublime",
description: "La prima volta che il Pokémon entra in campo, spande un odore dolciastro che diminuisce l'elusione degli avversari.",
},
hospitality: { hospitality: {
name: "Albergamemorie", name: "Ospitalità",
description: "Il Pokémon riporta alla mente vecchi ricordi, facendo risplendere la Maschera Turchese e aumentando la propria Velocità.", description: "Quando un Pokémon con questa abilità entra in campo ricopre di attenzioni l'alleato, restituendogli un po' dei suoi PS.",
}, },
toxicChain: { toxicChain: {
name: "Albergamemorie",
description: "Il Pokémon riporta alla mente vecchi ricordi, facendo risplendere la Maschera Pozzo e aumentando la propria Difesa Speciale.",
},
embodyAspectTeal: {
name: "Albergamemorie",
description: "Il Pokémon riporta alla mente vecchi ricordi, facendo risplendere la Maschera Focolare e aumentando il proprio Attacco.",
},
embodyAspectWellspring: {
name: "Albergamemorie",
description: "Il Pokémon riporta alla mente vecchi ricordi, facendo risplendere la Maschera Fondamenta e aumentando la propria Difesa.",
},
embodyAspectHearthflame: {
name: "Catena Tossica", name: "Catena Tossica",
description: "Quando il Pokémon colpisce il bersaglio con una mossa, può iperavvelenarlo grazie al potere della catena intrisa di tossine.", description: "Quando il Pokémon colpisce il bersaglio con una mossa, può iperavvelenarlo grazie al potere della catena intrisa di tossine.",
}, },
embodyAspectTeal: {
name: "Albergamemorie",
description: "Il Pokémon riporta alla mente vecchi ricordi, facendo risplendere la Maschera Focolare e aumentando il proprio Velocità.",
},
embodyAspectWellspring: {
name: "Albergamemorie",
description: "Il Pokémon riporta alla mente vecchi ricordi, facendo risplendere la Maschera Fondamenta e aumentando la propria Difesa Speciale.",
},
embodyAspectHearthflame: {
name: "Albergamemorie",
description: "Il Pokémon riporta alla mente vecchi ricordi, facendo risplendere la Maschera Fondamenta e aumentando la propria Attacco.",
},
embodyAspectCornerstone: { embodyAspectCornerstone: {
name: "Sciroppo Sublime", name: "Albergamemorie",
description: "La prima volta che il Pokémon entra in campo, spande un odore dolciastro che diminuisce l'elusione degli avversari.", description: "Il Pokémon riporta alla mente vecchi ricordi, facendo risplendere la Maschera Fondamenta e aumentando la propria Difesa.",
}, },
teraShift: { teraShift: {
name: "Teramorfosi", name: "Teramorfosi",

View File

@ -11,7 +11,7 @@ export const battle: SimpleTranslationEntries = {
"playerGo": "Vai! {{pokemonName}}!", "playerGo": "Vai! {{pokemonName}}!",
"trainerGo": "{{trainerName}} manda in campo {{pokemonName}}!", "trainerGo": "{{trainerName}} manda in campo {{pokemonName}}!",
"switchQuestion": "Vuoi cambiare\n{{pokemonName}}?", "switchQuestion": "Vuoi cambiare\n{{pokemonName}}?",
"trainerDefeated": `Hai sconfitto\n{{trainerName}}!`, "trainerDefeated": "Hai sconfitto\n{{trainerName}}!",
"pokemonCaught": "Preso! {{pokemonName}} è stato catturato!", "pokemonCaught": "Preso! {{pokemonName}} è stato catturato!",
"pokemon": "Pokémon", "pokemon": "Pokémon",
"sendOutPokemon": "Vai! {{pokemonName}}!", "sendOutPokemon": "Vai! {{pokemonName}}!",
@ -21,7 +21,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "Non ha effetto su {{pokemonName}}!", "hitResultNoEffect": "Non ha effetto su {{pokemonName}}!",
"hitResultOneHitKO": "KO con un colpo!", "hitResultOneHitKO": "KO con un colpo!",
"attackFailed": "Ma ha fallito!", "attackFailed": "Ma ha fallito!",
"attackHitsCount": `Colpito {{count}} volta/e!`, "attackHitsCount": "Colpito {{count}} volta/e!",
"expGain": "{{pokemonName}} ha guadagnato\n{{exp}} Punti Esperienza!", "expGain": "{{pokemonName}} ha guadagnato\n{{exp}} Punti Esperienza!",
"levelUp": "{{pokemonName}} è salito al\nlivello {{level}}!", "levelUp": "{{pokemonName}} è salito al\nlivello {{level}}!",
"learnMove": "{{pokemonName}} impara\n{{moveName}}!", "learnMove": "{{pokemonName}} impara\n{{moveName}}!",
@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = {
"noEscapeTrainer": "Non puoi sottrarti\nalla lotta con un'allenatore!", "noEscapeTrainer": "Non puoi sottrarti\nalla lotta con un'allenatore!",
"noEscapePokemon": "{{moveName}} di {{pokemonName}}\npreviene la {{escapeVerb}}!", "noEscapePokemon": "{{moveName}} di {{pokemonName}}\npreviene la {{escapeVerb}}!",
"runAwaySuccess": "Scampato pericolo!", "runAwaySuccess": "Scampato pericolo!",
"runAwayCannotEscape": 'Non puoi fuggire!', "runAwayCannotEscape": "Non puoi fuggire!",
"escapeVerbSwitch": "cambiando", "escapeVerbSwitch": "cambiando",
"escapeVerbFlee": "fuggendo", "escapeVerbFlee": "fuggendo",
"notDisabled": "{{pokemonName}}'s {{moveName}} non è più\ndisabilitata!", "notDisabled": "{{pokemonName}}'s {{moveName}} non è più\ndisabilitata!",

View File

@ -48,4 +48,4 @@ export const itConfig = {
battleMessageUiHandler: battleMessageUiHandler, battleMessageUiHandler: battleMessageUiHandler,
berry: berry, berry: berry,
voucher: voucher, voucher: voucher,
} };

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