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": {
"browser": true,
"es2021": true
},
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"parser": "@typescript-eslint/parser", // Specifies the ESLint parser for TypeScript
"plugins": ["@typescript-eslint", "import"], // Includes TypeScript and import plugins
"overrides": [
{
"files": ["src/**/*.ts"],
"extends": "eslint:recommended"
"files": ["src/**/*.{ts,tsx,js,jsx}"], // Applies these rules to all TypeScript and JavaScript files in the src directory
"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",
"test": "vitest run",
"test:cov": "vitest run --coverage",
"test:watch": "vitest watch --coverage"
"test:watch": "vitest watch --coverage",
"eslint": "eslint --fix ."
},
"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",
"axios": "^1.6.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",
"json-beautify": "^1.1.1",
"lefthook": "^1.6.12",
"phaser3spectorjs": "^0.0.8",
"pokenode-ts": "^1.20.0",
"typescript": "^5.0.3",
"typescript": "^5.4.5",
"typescript-eslint": "^7.10.0",
"vite": "^4.5.0",
"vite-plugin-fs": "^0.4.4",
"vitest": "^1.4.0",

View File

@ -12,27 +12,28 @@ export const clientSessionId = Utils.randomString(32);
export function updateUserInfo(): Promise<[boolean, integer]> {
return new Promise<[boolean, integer]>(resolve => {
if (bypassLogin) {
loggedInUser = { username: 'Guest', lastSessionSlot: -1 };
loggedInUser = { username: "Guest", lastSessionSlot: -1 };
let lastSessionSlot = -1;
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;
break;
}
}
loggedInUser.lastSessionSlot = lastSessionSlot;
// 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}_${loggedInUser.username}`))
if (localStorage.hasOwnProperty(`${d}_${loggedInUser.username}`)) {
localStorage.setItem(`${d}_${loggedInUser.username}_bak`, localStorage.getItem(`${d}_${loggedInUser.username}`));
}
localStorage.setItem(`${d}_${loggedInUser.username}`, localStorage.getItem(d));
localStorage.removeItem(d);
}
});
return resolve([ true, 200 ]);
}
Utils.apiFetch('account/info', true).then(response => {
Utils.apiFetch("account/info", true).then(response => {
if (!response.ok) {
resolve([ false, response.status ]);
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 { PlayerGender } from "./system/game-data";
import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
import { MoneyAchv } from "./system/achv";
import { PokeballType } from "./data/pokeball";
export enum BattleType {
@ -34,7 +33,7 @@ export interface TurnCommand {
targets?: BattlerIndex[];
skip?: boolean;
args?: any[];
};
}
interface TurnCommands {
[key: integer]: TurnCommand
@ -93,25 +92,26 @@ export default class Battle {
private initBattleSpec(): void {
let spec = BattleSpec.DEFAULT;
if (this.gameMode.isClassic) {
if (this.waveIndex === 200)
if (this.gameMode.isWaveFinal(this.waveIndex) && this.gameMode.isClassic) {
spec = BattleSpec.FINAL_BOSS;
}
this.battleSpec = spec;
}
private getLevelForWave(): integer {
let levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex);
let baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2);
const levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex);
const baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2);
const bossMultiplier = 1.2;
if (!(this.waveIndex % 10)) {
if (this.gameMode.isBoss(this.waveIndex)) {
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;
}
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));
}
return ret + levelOffset;
}
@ -125,8 +125,9 @@ export default class Battle {
randSeedGaussForLevel(value: number): number {
let rand = 0;
for (let i = value; i > 0; i--)
for (let i = value; i > 0; i--) {
rand += Phaser.Math.RND.realInRange(0, 1);
}
return rand / value;
}
@ -162,20 +163,22 @@ export default class Battle {
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;
}
addBattleScore(scene: BattleScene): void {
let partyMemberTurnMultiplier = scene.getEnemyParty().length / 2 + 0.5;
if (this.double)
if (this.double) {
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;
}
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);
scene.score += finalBattleScore;
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 {
const battlers = this.enemyParty.slice(0, this.getBattlerCount());
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 this.trainer.getBattleBgm();
} else if (this.gameMode.isClassic && this.waveIndex > 195 && this.battleSpec !== BattleSpec.FINAL_BOSS)
return 'end_summit';
for (let pokemon of battlers) {
} else if (this.gameMode.isClassic && this.waveIndex > 195 && this.battleSpec !== BattleSpec.FINAL_BOSS) {
return "end_summit";
}
for (const pokemon of battlers) {
if (this.battleSpec === BattleSpec.FINAL_BOSS) {
if (pokemon.formIndex)
return 'battle_final';
return 'battle_final_encounter';
if (pokemon.formIndex) {
return "battle_final";
}
return "battle_final_encounter";
}
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)
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.RESHIRAM || pokemon.species.speciesId === Species.ZEKROM)
return 'battle_legendary_res_zek';
if (pokemon.species.speciesId === Species.KYUREM)
return 'battle_legendary_kyurem';
if (pokemon.species.legendary)
return 'battle_legendary_res_zek';
return 'battle_legendary_unova';
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";
}
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.RESHIRAM || pokemon.species.speciesId === Species.ZEKROM) {
return "battle_legendary_res_zek";
}
if (pokemon.species.speciesId === Species.KYUREM) {
return "battle_legendary_kyurem";
}
if (pokemon.species.legendary) {
return "battle_legendary_res_zek";
}
return "battle_legendary_unova";
}
}
if (scene.gameMode.isClassic && this.waveIndex <= 4)
return 'battle_wild';
if (scene.gameMode.isClassic && this.waveIndex <= 4) {
return "battle_wild";
}
return null;
}
randSeedInt(scene: BattleScene, range: integer, min: integer = 0): integer {
if (range <= 1)
if (range <= 1) {
return min;
let ret: integer;
}
const tempRngCounter = scene.rngCounter;
const tempSeedOverride = scene.rngSeedOverride;
const state = Phaser.Math.RND.state();
if (this.battleSeedState)
if (this.battleSeedState) {
Phaser.Math.RND.state(this.battleSeedState);
else {
} else {
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.rngSeedOverride = this.battleSeed;
ret = Utils.randSeedInt(range, min);
const ret = Utils.randSeedInt(range, min);
this.battleSeedState = Phaser.Math.RND.state();
Phaser.Math.RND.state(state);
scene.rngCounter = tempRngCounter;
@ -245,9 +257,10 @@ export default class Battle {
export class FixedBattle extends Battle {
constructor(scene: BattleScene, waveIndex: integer, config: FixedBattleConfig) {
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);
}
}
}
type GetTrainerFunc = (scene: BattleScene) => Trainer;
@ -290,7 +303,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[]): Get
return (scene: BattleScene) => {
const rand = Utils.randSeedInt(trainerPool.length);
const trainerTypes: TrainerType[] = [];
for (let trainerPoolEntry of trainerPool) {
for (const trainerPoolEntry of trainerPool) {
const trainerType = Array.isArray(trainerPoolEntry)
? Utils.randSeedItem(trainerPoolEntry)
: trainerPoolEntry;

View File

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

View File

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

View File

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

View File

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

View File

@ -9,20 +9,19 @@ import { BattlerTag } from "./battler-tags";
import { BattlerTagType } from "./enums/battler-tag-type";
import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect";
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 { ArenaTagType } from "./enums/arena-tag-type";
import { Stat } from "./pokemon-stat";
import { PokemonHeldItemModifier } from "../modifier/modifier";
import { BerryModifier, PokemonHeldItemModifier } from "../modifier/modifier";
import { Moves } from "./enums/moves";
import { TerrainType } from "./terrain";
import { SpeciesFormChangeManualTrigger } from "./pokemon-forms";
import { Abilities } from "./enums/abilities";
import i18next, { Localizable } from "#app/plugins/i18n.js";
import { Command } from "../ui/command-ui-handler";
import Battle from "#app/battle.js";
import { ability } from "#app/locales/en/ability.js";
import { PokeballType, getPokeballName } from "./pokeball";
import { getPokeballName } from "./pokeball";
import { BerryModifierType } from "#app/modifier/modifier-type";
export class Ability implements Localizable {
public id: Abilities;
@ -39,7 +38,7 @@ export class Ability implements Localizable {
constructor(id: Abilities, generation: integer) {
this.id = id;
this.nameAppend = '';
this.nameAppend = "";
this.generation = generation;
this.attrs = [];
this.conditions = [];
@ -48,10 +47,10 @@ export class Ability implements Localizable {
}
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.description = this.id ? i18next.t(`ability:${i18nKey}.description`) as string : '';
this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`) as string}${this.nameAppend}` : "";
this.description = this.id ? i18next.t(`ability:${i18nKey}.description`) as string : "";
}
getAttrs(attrType: { new(...args: any[]): AbAttr }): AbAttr[] {
@ -94,12 +93,12 @@ export class Ability implements Localizable {
}
partial(): this {
this.nameAppend += ' (P)';
this.nameAppend += " (P)";
return this;
}
unimplemented(): this {
this.nameAppend += ' (N)';
this.nameAppend += " (N)";
return this;
}
}
@ -127,7 +126,7 @@ export abstract class AbAttr {
return null;
}
getCondition(): AbAttrCondition {
getCondition(): AbAttrCondition | null {
return this.extraCondition || null;
}
@ -145,7 +144,7 @@ export class BlockRecoilDamageAttr extends AbAttr {
}
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 {
const formIndex = this.formFunc(pokemon);
if (formIndex !== pokemon.formIndex)
if (formIndex !== pokemon.formIndex) {
return pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
}
return false;
}
@ -193,7 +193,7 @@ export class PostBattleInitStatChangeAbAttr extends PostBattleInitAbAttr {
constructor(stats: BattleStat | BattleStat[], levels: integer, selfTarget?: boolean) {
super();
this.stats = typeof(stats) === 'number'
this.stats = typeof(stats) === "number"
? [ stats as BattleStat ]
: stats as BattleStat[];
this.levels = levels;
@ -203,19 +203,21 @@ export class PostBattleInitStatChangeAbAttr extends PostBattleInitAbAttr {
applyPostBattleInit(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const statChangePhases: StatChangePhase[] = [];
if (this.selfTarget)
if (this.selfTarget) {
statChangePhases.push(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.levels));
else {
for (let opponent of pokemon.getOpponents())
} else {
for (const opponent of pokemon.getOpponents()) {
statChangePhases.push(new StatChangePhase(pokemon.scene, opponent.getBattlerIndex(), false, this.stats, this.levels));
}
}
for (let statChangePhase of statChangePhases) {
if (!this.selfTarget && !statChangePhase.getPokemon().summonData)
pokemon.scene.pushPhase(statChangePhase); // TODO: This causes the ability bar to be shown at the wrong time
else
for (const statChangePhase of statChangePhases) {
if (!this.selfTarget && !statChangePhase.getPokemon().summonData) {
pokemon.scene.pushPhase(statChangePhase);
} else { // TODO: This causes the ability bar to be shown at the wrong time
pokemon.scene.unshiftPhase(statChangePhase);
}
}
return true;
}
@ -256,7 +258,7 @@ export class PreDefendFullHpEndureAbAttr extends PreDefendAbAttr {
return pokemon.addTag(BattlerTagType.STURDY, 1);
}
return false
return false;
}
}
@ -391,9 +393,10 @@ class TypeImmunityStatChangeAbAttr extends TypeImmunityAbAttr {
if (ret) {
cancelled.value = true;
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));
}
}
return ret;
}
@ -416,9 +419,10 @@ class TypeImmunityAddBattlerTagAbAttr extends TypeImmunityAbAttr {
if (ret) {
cancelled.value = true;
const simulated = args.length > 1 && args[1];
if (!simulated)
if (!simulated) {
pokemon.addTag(this.tagType, this.turnCount, undefined, pokemon.id);
}
}
return ret;
}
@ -453,14 +457,15 @@ export class PostDefendAbAttr extends AbAttr {
export class PostDefendDisguiseAbAttr extends PostDefendAbAttr {
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);
if (!recoilDamage)
if (!recoilDamage) {
return false;
}
pokemon.damageAndUpdate(recoilDamage, HitResult.OTHER);
pokemon.turnData.damageTaken += recoilDamage;
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\'s disguise was busted!'));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, "'s disguise was busted!"));
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 {
const ret = super.applyPreDefend(pokemon, passive, attacker, move, cancelled, args)
const ret = super.applyPreDefend(pokemon, passive, attacker, move, cancelled, args);
if (ret) {
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 {
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 ) {
pokemon.scene.queueMessage(getPokemonMessage(attacker, ` sucked up the liquid ooze!`));
pokemon.scene.queueMessage(getPokemonMessage(attacker, " sucked up the liquid ooze!"));
return true;
}
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 {
if (this.condition(pokemon, attacker, move.getMove())) {
if (this.allOthers) {
let otherPokemon = pokemon.getAlly() ? pokemon.getOpponents().concat([ pokemon.getAlly() ]) : pokemon.getOpponents();
for (let other of otherPokemon) {
const otherPokemon = pokemon.getAlly() ? pokemon.getOpponents().concat([ pokemon.getAlly() ]) : pokemon.getOpponents();
for (const other of otherPokemon) {
other.scene.unshiftPhase(new StatChangePhase(other.scene, (other).getBattlerIndex(), false, [ this.stat ], this.levels));
}
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 {
const hpGateFlat: integer = Math.ceil(pokemon.getMaxHp() * this.hpGate)
const lastAttackReceived = pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1]
const hpGateFlat: integer = Math.ceil(pokemon.getMaxHp() * this.hpGate);
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)) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.levels));
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 {
if (hitResult < HitResult.NO_EFFECT)
if (hitResult < HitResult.NO_EFFECT) {
return pokemon.scene.arena.trySetTerrain(this.terrainType, true);
}
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 {
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 false;
}
@ -818,8 +825,9 @@ export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr {
}
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 false;
}
@ -842,7 +850,7 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr {
}
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 {
const type = (args[0] as Utils.IntegerHolder);
if (type.value == this.matchType) {
if (type.value === this.matchType) {
type.value = this.newType;
(args[1] as Utils.NumberHolder).value *= this.powerMultiplier;
return true;
@ -1150,8 +1158,9 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
if (heldItems.length) {
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
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}!`));
}
resolve(success);
});
return;
@ -1181,7 +1190,7 @@ export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr {
}
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)];
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 {
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)];
@ -1238,8 +1247,9 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
if (heldItems.length) {
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
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}!`));
}
resolve(success);
});
return;
@ -1273,7 +1283,7 @@ class PostVictoryStatChangeAbAttr extends PostVictoryAbAttr {
}
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.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> {
const stat = typeof this.stat === 'function'
const stat = typeof this.stat === "function"
? this.stat(pokemon)
: this.stat;
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels));
@ -1356,6 +1366,28 @@ export class IgnoreOpponentStatChangesAbAttr extends AbAttr {
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 {
constructor() {
@ -1378,10 +1410,10 @@ export class PostIntimidateStatChangeAbAttr extends AbAttr {
private overwrites: boolean;
constructor(stats: BattleStat[], levels: integer, overwrites?: boolean) {
super(true)
this.stats = stats
this.levels = levels
this.overwrites = !!overwrites
super(true);
this.stats = stats;
this.levels = levels;
this.overwrites = !!overwrites;
}
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) {
super(false);
this.stats = typeof(stats) === 'number'
this.stats = typeof(stats) === "number"
? [ stats as BattleStat ]
: stats as BattleStat[];
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));
return true;
}
for (let opponent of pokemon.getOpponents()) {
const cancelled = new Utils.BooleanHolder(false)
for (const opponent of pokemon.getOpponents()) {
const cancelled = new Utils.BooleanHolder(false);
if (this.intimidate) {
applyAbAttrs(IntimidateImmunityAbAttr, opponent, cancelled);
applyAbAttrs(PostIntimidateStatChangeAbAttr, opponent, cancelled);
@ -1523,10 +1555,11 @@ export class PostSummonClearAllyStatsAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const target = pokemon.getAlly();
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.scene.queueMessage(getPokemonMessage(target, `'s stat changes\nwere removed!`));
target.scene.queueMessage(getPokemonMessage(target, "'s stat changes\nwere removed!"));
return true;
}
@ -1544,15 +1577,16 @@ export class DownloadAbAttr extends PostSummonAbAttr {
this.enemyDef = 0;
this.enemySpDef = 0;
for (let opponent of pokemon.getOpponents()) {
for (const opponent of pokemon.getOpponents()) {
this.enemyDef += opponent.stats[BattleStat.DEF];
this.enemySpDef += opponent.stats[BattleStat.SPDEF];
}
if (this.enemyDef < this.enemySpDef)
if (this.enemyDef < this.enemySpDef) {
this.stats = [BattleStat.ATK];
else
} else {
this.stats = [BattleStat.SPATK];
}
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));
@ -1573,8 +1607,9 @@ export class PostSummonWeatherChangeAbAttr extends PostSummonAbAttr {
}
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 false;
}
@ -1605,8 +1640,9 @@ export class PostSummonFormChangeAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const formIndex = this.formFunc(pokemon);
if (formIndex !== pokemon.formIndex)
if (formIndex !== pokemon.formIndex) {
return pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
}
return false;
}
@ -1615,18 +1651,21 @@ export class PostSummonFormChangeAbAttr extends PostSummonAbAttr {
export class TraceAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const targets = pokemon.getOpponents();
if (!targets.length)
if (!targets.length) {
return false;
}
let target: Pokemon;
if (targets.length > 1)
if (targets.length > 1) {
pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex);
else
} else {
target = targets[0];
}
// 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;
}
pokemon.summonData.ability = target.getAbility().id;
@ -1643,14 +1682,16 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const targets = pokemon.getOpponents();
if (!targets.length)
if (!targets.length) {
return false;
}
let target: Pokemon;
if (targets.length > 1)
if (targets.length > 1) {
pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex);
else
} else {
target = targets[0];
}
pokemon.summonData.speciesForm = target.getSpeciesForm();
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.types = target.getTypes();
pokemon.scene.playSound('PRSFX- Transform');
pokemon.scene.playSound("PRSFX- Transform");
pokemon.loadAssets(false).then(() => pokemon.playAnim());
@ -1732,7 +1773,7 @@ export class ProtectStatAbAttr extends PreStatChangeAbAttr {
}
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 {
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 {
const target = (args[1] as Pokemon);
const move = (args[2] as Move);
if(!this.condition(pokemon,target,move))
if(!this.condition(pokemon,target,move)) {
return false;
}
(args[0] as Utils.BooleanHolder).value = true;
return true;
@ -1885,8 +1927,9 @@ export class IncrementMovePriorityAbAttr extends AbAttr {
}
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;
}
(args[1] as Utils.IntegerHolder).value += this.increaseAmount;
return true;
@ -1913,8 +1956,9 @@ export class BlockWeatherDamageAttr extends PreWeatherDamageAbAttr {
}
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;
}
return true;
}
@ -1941,8 +1985,9 @@ export class SuppressWeatherEffectAbAttr extends PreWeatherEffectAbAttr {
function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition {
return (pokemon: Pokemon) => {
if (pokemon.scene.arena.weather?.isEffectSuppressed(pokemon.scene))
if (pokemon.scene.arena.weather?.isEffectSuppressed(pokemon.scene)) {
return false;
}
const weatherType = pokemon.scene.arena.weather?.weatherType;
return weatherType && weatherTypes.indexOf(weatherType) > -1;
};
@ -1950,8 +1995,8 @@ function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition {
function getAnticipationCondition(): AbAttrCondition {
return (pokemon: Pokemon) => {
for (let opponent of pokemon.getOpponents()) {
for (let move of opponent.moveset) {
for (const opponent of pokemon.getOpponents()) {
for (const move of opponent.moveset) {
// move is super effective
if (move.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.getMove().type, opponent) >= 2) {
return true;
@ -1995,7 +2040,7 @@ function getAnticipationCondition(): AbAttrCondition {
function getOncePerBattleCondition(ability: Abilities): AbAttrCondition {
return (pokemon: Pokemon) => {
return !pokemon.battleData?.abilitiesApplied.includes(ability);
}
};
}
export class ForewarnAbAttr extends PostSummonAbAttr {
@ -2007,8 +2052,8 @@ export class ForewarnAbAttr extends PostSummonAbAttr {
let maxPowerSeen = 0;
let maxMove = "";
let movePower = 0;
for (let opponent of pokemon.getOpponents()) {
for (let move of opponent.moveset) {
for (const opponent of pokemon.getOpponents()) {
for (const move of opponent.moveset) {
if (move.getMove() instanceof StatusMove) {
movePower = 1;
} 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 {
for (let opponent of pokemon.getOpponents()) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " frisked " + opponent.name + "\'s " + opponent.getAbility().name + "!"));
for (const opponent of pokemon.getOpponents()) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " frisked " + opponent.name + "'s " + opponent.getAbility().name + "!"));
}
return true;
}
@ -2066,8 +2111,9 @@ export class PostWeatherChangeAddBattlerTagAttr extends PostWeatherChangeAbAttr
applyPostWeatherChange(pokemon: Pokemon, passive: boolean, weather: WeatherType, args: any[]): boolean {
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 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 {
if (!this.terrainTypes.find(t => t === terrain))
if (!this.terrainTypes.find(t => t === terrain)) {
return false;
}
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 {
constructor() {
super(true);
}
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
let selectableStats = [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD];
let increaseStatArray = selectableStats.filter(s => pokemon.summonData.battleStats[s] < 6);
const selectableStats = [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD];
const increaseStatArray = selectableStats.filter(s => pokemon.summonData.battleStats[s] < 6);
let decreaseStatArray = selectableStats.filter(s => pokemon.summonData.battleStats[s] > -6);
if (increaseStatArray.length > 0) {
let increaseStat = increaseStatArray[Utils.randInt(increaseStatArray.length)];
const increaseStat = increaseStatArray[Utils.randInt(increaseStatArray.length)];
decreaseStatArray = decreaseStatArray.filter(s => s !== increaseStat);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [increaseStat], 2));
}
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));
}
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
* @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
*/
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
let lastUsed = pokemon.scene.currentBattle.lastUsedPokeball;
if(lastUsed != null && pokemon.isPlayer) {
const lastUsed = pokemon.scene.currentBattle.lastUsedPokeball;
if(lastUsed !== null && pokemon.isPlayer) {
pokemon.scene.pokeballCounts[lastUsed]++;
pokemon.scene.currentBattle.lastUsedPokeball = null;
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 {
if (!pokemon.scene.arena.weather?.isImmutable())
if (!pokemon.scene.arena.weather?.isImmutable()) {
return pokemon.scene.arena.trySetWeather(this.weatherType, true);
}
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 {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) {
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) {
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> {
return new Promise(resolve => {
if (!pokemon.canApplyAbility(passive)) {
if (!passive)
if (!passive) {
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
else
} else {
return resolve();
}
}
const ability = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility());
const attrs = ability.getAttrs(attrType) as TAttr[];
const clearSpliceQueueAndResolve = () => {
pokemon.scene.clearPhaseQueueSplice();
if (!passive)
if (!passive) {
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
else
} else {
return resolve();
}
};
const applyNextAbAttr = () => {
if (attrs.length)
if (attrs.length) {
applyAbAttr(attrs.shift());
else
} else {
clearSpliceQueueAndResolve();
}
};
const applyAbAttr = (attr: TAttr) => {
if (!canApplyAttr(pokemon, attr))
if (!canApplyAttr(pokemon, attr)) {
return applyNextAbAttr();
}
pokemon.scene.setPhaseQueueSplice();
const onApplySuccess = () => {
if (pokemon.battleData && !pokemon.battleData.abilitiesApplied.includes(ability.id)) {
pokemon.battleData.abilitiesApplied.push(ability.id);
}
if (attr.showAbility && !quiet) {
if (showAbilityInstant)
if (showAbilityInstant) {
pokemon.scene.abilityBar.showAbility(pokemon, passive);
else
} else {
queueShowAbility(pokemon, passive);
}
}
if (!quiet) {
const message = attr.getTriggerMessage(pokemon, (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name, args);
if (message) {
if (isAsync)
if (isAsync) {
pokemon.scene.ui.showText(message, null, () => pokemon.scene.ui.showText(null, 0), null, true);
else
} else {
pokemon.scene.queueMessage(message);
}
}
}
};
const result = applyFunc(attr, passive);
if (result instanceof Promise) {
result.then(success => {
if (success)
if (success) {
onApplySuccess();
}
applyNextAbAttr();
});
} else {
if (result)
if (result) {
onApplySuccess();
}
applyNextAbAttr();
}
};
@ -3110,7 +3260,7 @@ export function initAbilities() {
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.SANDSTORM),
new Ability(Abilities.PRESSURE, 3)
.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)
.attr(ReceivedTypeDamageMultiplierAbAttr, Type.FIRE, 0.5)
.attr(ReceivedTypeDamageMultiplierAbAttr, Type.ICE, 0.5)
@ -3133,8 +3283,8 @@ export function initAbilities() {
new Ability(Abilities.TRUANT, 3)
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.TRUANT, 1, false),
new Ability(Abilities.HUSTLE, 3)
.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.ATK, 1.5, (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)
.attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED),
new Ability(Abilities.PLUS, 3)
@ -3260,7 +3410,7 @@ export function initAbilities() {
.attr(MovePowerBoostAbAttr, (user, target, move) => {
const power = new Utils.NumberHolder(move.power);
applyMoveAttrs(VariablePowerAttr, user, target, move, power);
return power.value <= 60
return power.value <= 60;
}, 1.5),
new Ability(Abilities.LEAF_GUARD, 4)
.attr(StatusEffectImmunityAbAttr)
@ -3269,7 +3419,7 @@ export function initAbilities() {
new Ability(Abilities.KLUTZ, 4)
.unimplemented(),
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),
new Ability(Abilities.SUPER_LUCK, 4)
.attr(BonusCritAbAttr)
@ -3278,7 +3428,7 @@ export function initAbilities() {
.attr(PostFaintContactDamageAbAttr,4)
.bypassFaint(),
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)
.attr(ForewarnAbAttr),
new Ability(Abilities.UNAWARE, 4)
@ -3326,7 +3476,7 @@ export function initAbilities() {
.ignorable()
.partial(),
new Ability(Abilities.BAD_DREAMS, 4)
.unimplemented(),
.attr(PostTurnHurtIfSleepingAbAttr),
new Ability(Abilities.PICKPOCKET, 5)
.attr(PostDefendStealHeldItemAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT)),
new Ability(Abilities.SHEER_FORCE, 5)
@ -3367,7 +3517,13 @@ export function initAbilities() {
new Ability(Abilities.FLARE_BOOST, 5)
.attr(MovePowerBoostAbAttr, (user, target, move) => move.category === MoveCategory.SPECIAL && user.status?.effect === StatusEffect.BURN, 1.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)
.attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon.getAlly() === attacker && move.getMove() instanceof AttackMove)
.ignorable(),
@ -3442,10 +3598,10 @@ export function initAbilities() {
.attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 1.1)
.partial(),
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),
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),
new Ability(Abilities.AROMA_VEIL, 6)
.ignorable()
@ -3501,10 +3657,10 @@ export function initAbilities() {
new Ability(Abilities.PARENTAL_BOND, 6)
.unimplemented(),
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),
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),
new Ability(Abilities.AURA_BREAK, 6)
.ignorable()
@ -3570,7 +3726,7 @@ export function initAbilities() {
.attr(UnsuppressableAbilityAbAttr)
.attr(NoFusionAbilityAbAttr),
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(PostBattleInitFormChangeAbAttr, 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(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
.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(PostTurnFormChangeAbAttr, 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(PostTurnFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === "complete" ? 4 : 2)
.attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr)
.attr(UnsuppressableAbilityAbAttr)
@ -3740,7 +3896,7 @@ export function initAbilities() {
.attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr)
.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(),
new Ability(Abilities.PASTEL_VEIL, 8)
.attr(StatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC)
@ -3886,8 +4042,9 @@ export function initAbilities() {
.partial(),
new Ability(Abilities.MINDS_EYE, 9)
.attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [Type.NORMAL, Type.FIGHTING])
.ignorable() // TODO: evasiveness bypass should not be ignored, but accuracy immunity should
.partial(),
.attr(ProtectStatAbAttr, BattleStat.ACC)
.attr(IgnoreOpponentEvasionAbAttr)
.ignorable(),
new Ability(Abilities.SUPERSWEET_SYRUP, 9)
.attr(PostSummonStatChangeAbAttr, BattleStat.EVA, -1)
.condition(getOncePerBattleCondition(Abilities.SUPERSWEET_SYRUP)),

View File

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

View File

@ -40,7 +40,7 @@ export abstract class ArenaTag {
onAdd(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 { }
@ -65,13 +65,13 @@ export class MistTag extends ArenaTag {
super.onAdd(arena);
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 {
(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;
}
@ -110,7 +110,7 @@ class ReflectTag extends WeakenMoveScreenTag {
}
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 {
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 {
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 {
const user = arena.scene.getPokemonById(this.sourceId);
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);
}
@ -196,11 +196,11 @@ class MudSportTag extends WeakenMoveTypeTag {
}
onAdd(arena: Arena): void {
arena.scene.queueMessage('Electricity\'s power was weakened!');
arena.scene.queueMessage("Electricity's power was weakened!");
}
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 {
arena.scene.queueMessage('Fire\'s power was weakened!');
arena.scene.queueMessage("Fire's power was weakened!");
}
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 {
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 this.activateTrap(pokemon);
}
@ -275,9 +276,11 @@ class SpikesTag extends ArenaTrapTag {
const damageHpRatio = 1 / (10 - 2 * this.layers);
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);
if (pokemon.turnData) pokemon.turnData.damageTaken += damage;
if (pokemon.turnData) {
pokemon.turnData.damageTaken += damage;
}
return true;
}
}
@ -302,9 +305,10 @@ class ToxicSpikesTag extends ArenaTrapTag {
}
onRemove(arena: Arena): void {
if (!this.neutralized)
if (!this.neutralized) {
super.onRemove(arena);
}
}
activateTrap(pokemon: Pokemon): boolean {
if (pokemon.isGrounded()) {
@ -316,19 +320,22 @@ class ToxicSpikesTag extends ArenaTrapTag {
}
} else if (!pokemon.status) {
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 false;
}
getMatchupScoreMultiplier(pokemon: Pokemon): number {
if (pokemon.isGrounded() || !pokemon.canSetStatus(StatusEffect.POISON, true))
if (pokemon.isGrounded() || !pokemon.canSetStatus(StatusEffect.POISON, true)) {
return 1;
if (pokemon.isOfType(Type.POISON))
}
if (pokemon.isOfType(Type.POISON)) {
return 1.25;
}
return super.getMatchupScoreMultiplier(pokemon);
}
}
@ -345,8 +352,9 @@ class DelayedAttackTag extends ArenaTag {
lapse(arena: Arena): boolean {
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)));
}
return ret;
}
@ -399,8 +407,9 @@ class StealthRockTag extends ArenaTrapTag {
const cancelled = new Utils.BooleanHolder(false);
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
if (cancelled.value)
if (cancelled.value) {
return false;
}
const damageHpRatio = this.getDamageHpRatio(pokemon);
@ -408,7 +417,9 @@ class StealthRockTag extends ArenaTrapTag {
const damage = Math.ceil(pokemon.getMaxHp() * damageHpRatio);
pokemon.scene.queueMessage(`Pointed stones dug into\n${pokemon.name}!`);
pokemon.damageAndUpdate(damage, HitResult.OTHER);
if (pokemon.turnData) pokemon.turnData.damageTaken += damage;
if (pokemon.turnData) {
pokemon.turnData.damageTaken += damage;
}
}
return false;
@ -428,6 +439,8 @@ class StickyWebTag extends ArenaTrapTag {
onAdd(arena: Arena): void {
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);
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 {
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 {
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 {
arena.scene.queueMessage('Gravity intensified!');
arena.scene.queueMessage("Gravity intensified!");
}
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 {
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 {
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 * as Utils from "../utils";
import { BattlerIndex } from "../battle";
import stringify, { Element } from "json-stable-stringify";
import { Element } from "json-stable-stringify";
import { Moves } from "./enums/moves";
import { getTypeRgb } from "./type";
//import fs from 'vite-plugin-fs/browser';
export enum AnimFrameTarget {
@ -119,24 +118,25 @@ export class AnimConfig {
this.graphic = source.graphic;
const frames: any[][] = source.frames;
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]);
}
});
this.frames = frames;
const frameTimedEvents = source.frameTimedEvents;
for (let fte of Object.keys(frameTimedEvents)) {
for (const fte of Object.keys(frameTimedEvents)) {
const timedEvents: AnimTimedEvent[] = [];
for (let te of frameTimedEvents[fte]) {
for (const te of frameTimedEvents[fte]) {
let timedEvent: AnimTimedEvent;
switch (te.eventType) {
case 'AnimTimedSoundEvent':
case "AnimTimedSoundEvent":
timedEvent = new AnimTimedSoundEvent(te.frameIndex, te.resourceName, te);
break;
case 'AnimTimedAddBgEvent':
case "AnimTimedAddBgEvent":
timedEvent = new AnimTimedAddBgEvent(te.frameIndex, te.resourceName, te);
break;
case 'AnimTimedUpdateBgEvent':
case "AnimTimedUpdateBgEvent":
timedEvent = new AnimTimedUpdateBgEvent(te.frameIndex, te.resourceName, te);
break;
}
@ -147,19 +147,21 @@ export class AnimConfig {
this.position = source.position;
this.hue = source.hue;
} else
} else {
this.frames = [];
}
}
getSoundResourceNames(): string[] {
const sounds = new Set<string>();
for (let ftes of this.frameTimedEvents.values()) {
for (let fte of ftes) {
if (fte instanceof AnimTimedSoundEvent && fte.resourceName)
for (const ftes of this.frameTimedEvents.values()) {
for (const fte of ftes) {
if (fte instanceof AnimTimedSoundEvent && fte.resourceName) {
sounds.add(fte.resourceName);
}
}
}
return Array.from(sounds.values());
}
@ -167,12 +169,13 @@ export class AnimConfig {
getBackgroundResourceNames(): string[] {
const backgrounds = new Set<string>();
for (let ftes of this.frameTimedEvents.values()) {
for (let fte of ftes) {
if (fte instanceof AnimTimedAddBgEvent && fte.resourceName)
for (const ftes of this.frameTimedEvents.values()) {
for (const fte of ftes) {
if (fte instanceof AnimTimedAddBgEvent && fte.resourceName) {
backgrounds.add(fte.resourceName);
}
}
}
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) {
this.x = !init ? ((x || 0) - 128) * 0.5 : x;
this.y = !init ? ((y || 0) - 224) * 0.5 : y;
if (zoomX)
if (zoomX) {
this.zoomX = zoomX;
else if (init)
} else if (init) {
this.zoomX = 0;
if (zoomY)
}
if (zoomY) {
this.zoomY = zoomY;
else if (init)
} else if (init) {
this.zoomY = 0;
if (angle)
}
if (angle) {
this.angle = angle;
else if (init)
} else if (init) {
this.angle = 0;
if (mirror)
}
if (mirror) {
this.mirror = mirror;
else if (init)
} else if (init) {
this.mirror = false;
if (visible)
}
if (visible) {
this.visible = visible;
else if (init)
} else if (init) {
this.visible = false;
if (blendType)
}
if (blendType) {
this.blendType = blendType;
else if (init)
} else if (init) {
this.blendType = AnimBlendType.NORMAL;
}
if (!init) {
let target = AnimFrameTarget.GRAPHIC;
switch (pattern) {
@ -239,30 +248,36 @@ class AnimFrame {
this.target = target;
this.graphicFrame = pattern >= 0 ? pattern : 0;
}
if (opacity)
if (opacity) {
this.opacity = opacity;
else if (init)
} else if (init) {
this.opacity = 0;
if (colorR || colorG || colorB || colorA)
}
if (colorR || colorG || colorB || colorA) {
this.color = [ colorR || 0, colorG || 0, colorB || 0, colorA || 0 ];
else if (init)
} else if (init) {
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 ];
else if (init)
} else if (init) {
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 ];
else if (init)
} else if (init) {
this.flash = [ 0, 0, 0, 0 ];
if (locked)
}
if (locked) {
this.locked = locked;
else if (init)
} else if (init) {
this.locked = false;
if (priority)
}
if (priority) {
this.priority = priority;
else if (init)
} else if (init) {
this.priority = 0;
}
this.focus = focus || AnimFocus.TARGET;
}
}
@ -314,12 +329,13 @@ class AnimTimedSoundEvent extends AnimTimedEvent {
console.error(err);
}
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);
}
}
getEventType(): string {
return 'AnimTimedSoundEvent';
return "AnimTimedSoundEvent";
}
}
@ -368,12 +384,15 @@ class AnimTimedUpdateBgEvent extends AnimTimedBgEvent {
execute(scene: BattleScene, moveAnim: MoveAnim): integer {
const tweenProps = {};
if (this.bgX !== undefined)
tweenProps['x'] = (this.bgX * 0.5) - 320;
if (this.bgY !== undefined)
tweenProps['y'] = (this.bgY * 0.5) - 284;
if (this.opacity !== undefined)
tweenProps['alpha'] = (this.opacity || 0) / 255;
if (this.bgX !== undefined) {
tweenProps["x"] = (this.bgX * 0.5) - 320;
}
if (this.bgY !== undefined) {
tweenProps["y"] = (this.bgY * 0.5) - 284;
}
if (this.opacity !== undefined) {
tweenProps["alpha"] = (this.opacity || 0) / 255;
}
if (Object.keys(tweenProps).length) {
scene.tweens.add(Object.assign({
targets: moveAnim.bgSprite,
@ -384,7 +403,7 @@ class AnimTimedUpdateBgEvent extends AnimTimedBgEvent {
}
getEventType(): string {
return 'AnimTimedUpdateBgEvent';
return "AnimTimedUpdateBgEvent";
}
}
@ -394,8 +413,9 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
}
execute(scene: BattleScene, moveAnim: MoveAnim): integer {
if (moveAnim.bgSprite)
if (moveAnim.bgSprite) {
moveAnim.bgSprite.destroy();
}
moveAnim.bgSprite = 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);
@ -404,8 +424,9 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
moveAnim.bgSprite.setAlpha(this.opacity / 255);
scene.field.add(moveAnim.bgSprite);
const fieldPokemon = scene.getEnemyPokemon() || scene.getPlayerPokemon();
if (fieldPokemon?.isOnField())
if (fieldPokemon?.isOnField()) {
scene.field.moveBelow(moveAnim.bgSprite as Phaser.GameObjects.GameObject, fieldPokemon);
}
scene.tweens.add({
targets: moveAnim.bgSprite,
@ -416,7 +437,7 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
}
getEventType(): string {
return 'AnimTimedAddBgEvent';
return "AnimTimedAddBgEvent";
}
}
@ -431,7 +452,7 @@ export function initCommonAnims(scene: BattleScene): Promise<void> {
const commonAnimFetches = [];
for (let ca = 0; ca < commonAnimIds.length; 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(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> {
return new Promise(resolve => {
if (moveAnims.has(move)) {
if (moveAnims.get(move) !== null)
if (moveAnims.get(move) !== null) {
resolve();
else {
let loadedCheckTimer = setInterval(() => {
} else {
const loadedCheckTimer = setInterval(() => {
if (moveAnims.get(move) !== null) {
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;
}
clearInterval(loadedCheckTimer);
resolve();
}
@ -458,7 +480,7 @@ export function initMoveAnim(scene: BattleScene, move: Moves): Promise<void> {
} else {
moveAnims.set(move, null);
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) => {
scene.cachedFetch(`./battle-anims/${moveName}.json`)
.then(response => {
@ -473,13 +495,15 @@ export function initMoveAnim(scene: BattleScene, move: Moves): Promise<void> {
if (Array.isArray(ba)) {
populateMoveAnim(move, ba[0]);
populateMoveAnim(move, ba[1]);
} else
} else {
populateMoveAnim(move, ba);
}
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());
else
} else {
resolve();
}
});
};
fetchAnimAndResolve(move);
@ -490,10 +514,10 @@ export function initMoveAnim(scene: BattleScene, move: Moves): Promise<void> {
export function initMoveChargeAnim(scene: BattleScene, chargeAnim: ChargeAnim): Promise<void> {
return new Promise(resolve => {
if (chargeAnims.has(chargeAnim)) {
if (chargeAnims.get(chargeAnim) !== null)
if (chargeAnims.get(chargeAnim) !== null) {
resolve();
else {
let loadedCheckTimer = setInterval(() => {
} else {
const loadedCheckTimer = setInterval(() => {
if (chargeAnims.get(chargeAnim) !== null) {
clearInterval(loadedCheckTimer);
resolve();
@ -502,14 +526,15 @@ export function initMoveChargeAnim(scene: BattleScene, chargeAnim: ChargeAnim):
}
} else {
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(ca => {
if (Array.isArray(ca)) {
populateMoveChargeAnim(chargeAnim, ca[0]);
populateMoveChargeAnim(chargeAnim, ca[1]);
} else
} else {
populateMoveChargeAnim(chargeAnim, ca);
}
resolve();
});
}
@ -543,15 +568,16 @@ export function loadCommonAnimAssets(scene: BattleScene, startLoad?: boolean): P
export function loadMoveAnimAssets(scene: BattleScene, moveIds: Moves[], startLoad?: boolean): Promise<void> {
return new Promise(resolve => {
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;
if (chargeAttr) {
const moveChargeAnims = chargeAnims.get(chargeAttr.chargeAnim);
moveAnimations.push(moveChargeAnims instanceof AnimConfig ? moveChargeAnims : moveChargeAnims[0]);
if (Array.isArray(moveChargeAnims))
if (Array.isArray(moveChargeAnims)) {
moveAnimations.push(moveChargeAnims[1]);
}
}
}
loadAnimAssets(scene, moveAnimations, startLoad).then(() => resolve());
});
}
@ -560,28 +586,36 @@ function loadAnimAssets(scene: BattleScene, anims: AnimConfig[], startLoad?: boo
return new Promise(resolve => {
const backgrounds = new Set<string>();
const sounds = new Set<string>();
for (let a of anims) {
if (!a.frames?.length)
for (const a of anims) {
if (!a.frames?.length) {
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)
scene.loadImage(bg, 'battle_anims');
for (let s of sounds)
scene.loadSe(s, 'battle_anims', s);
const animSounds = a.getSoundResourceNames();
for (const ms of animSounds) {
sounds.add(ms);
}
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) {
scene.load.once(Phaser.Loader.Events.COMPLETE, () => resolve());
if (!scene.load.isLoading())
if (!scene.load.isLoading()) {
scene.load.start();
} else
}
} else {
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) {
if (src1 === src2)
if (src1 === src2) {
return false;
if (src1 < src2)
}
if (src1 < src2) {
return dst1 > dst2;
}
return dst1 < dst2;
}
@ -680,11 +716,11 @@ export abstract class BattleAnim {
let u = 0;
let t = 0;
for (let frame of frames) {
for (const frame of frames) {
let x = frame.x + 106;
let y = frame.y + 116;
let scaleX = (frame.zoomX / 100) * (!frame.mirror ? 1 : -1);
let scaleY = (frame.zoomY / 100);
const scaleY = (frame.zoomY / 100);
switch (frame.focus) {
case AnimFocus.TARGET:
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);
x = point[0];
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;
}
break;
}
const angle = -frame.angle;
@ -717,8 +754,9 @@ export abstract class BattleAnim {
const target = !isOppAnim ? this.target : this.user;
if (!target.isOnField()) {
if (callback)
if (callback) {
callback();
}
return;
}
@ -736,29 +774,35 @@ export abstract class BattleAnim {
userSprite.setPosition(0, 0);
userSprite.setScale(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);
targetSprite.setPosition(0, 0);
targetSprite.setScale(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);
if (!this.isHideUser())
if (!this.isHideUser()) {
userSprite.setVisible(true);
if (!this.isHideTarget() && (targetSprite !== userSprite || !this.isHideUser()))
}
if (!this.isHideTarget() && (targetSprite !== userSprite || !this.isHideUser())) {
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();
}
if (this.bgSprite)
}
if (this.bgSprite) {
this.bgSprite.destroy();
if (callback)
}
if (callback) {
callback();
}
};
if (!scene.moveAnimations)
if (!scene.moveAnimations) {
return cleanUpAndComplete();
}
const anim = this.getAnim();
@ -787,22 +831,22 @@ export abstract class BattleAnim {
let u = 0;
let t = 0;
let g = 0;
for (let frame of spriteFrames) {
for (const frame of spriteFrames) {
if (frame.target !== AnimFrameTarget.GRAPHIC) {
const isUser = frame.target === AnimFrameTarget.USER;
if (isUser && target === user)
if (isUser && target === user) {
continue;
}
const sprites = spriteCache[isUser ? AnimFrameTarget.USER : AnimFrameTarget.TARGET];
const spriteSource = isUser ? userSprite : targetSprite;
if ((isUser ? u : t) === sprites.length) {
let sprite: Phaser.GameObjects.Sprite;
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]);
sprite.setPipelineData('spriteKey', (isUser ? user : target).getBattleSpriteKey());
sprite.setPipelineData('shiny', (isUser ? user : target).shiny);
sprite.setPipelineData('variant', (isUser ? user : target).variant);
sprite.setPipelineData('ignoreFieldPos', true);
spriteSource.on('animationupdate', (_anim, frame) => sprite.setFrame(frame.textureFrame));
const 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]);
sprite.setPipelineData("spriteKey", (isUser ? user : target).getBattleSpriteKey());
sprite.setPipelineData("shiny", (isUser ? user : target).shiny);
sprite.setPipelineData("variant", (isUser ? user : target).variant);
sprite.setPipelineData("ignoreFieldPos", true);
spriteSource.on("animationupdate", (_anim, frame) => sprite.setFrame(frame.textureFrame));
scene.field.add(sprite);
sprites.push(sprite);
}
@ -815,16 +859,16 @@ export abstract class BattleAnim {
pokemonSprite.setAngle(graphicFrameData.angle);
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.pipelineData['tone'] = frame.tone;
pokemonSprite.pipelineData["tone"] = frame.tone;
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);
} else {
const sprites = spriteCache[AnimFrameTarget.GRAPHIC];
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);
scene.field.add(newSprite);
spritePriorities.push(1);
@ -845,10 +889,11 @@ export abstract class BattleAnim {
case 2:
switch (frame.focus) {
case AnimFocus.USER:
if (this.bgSprite)
if (this.bgSprite) {
scene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.bgSprite);
else
} else {
scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.user);
}
break;
case AnimFocus.TARGET:
scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.target);
@ -891,20 +936,22 @@ export abstract class BattleAnim {
}
}
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);
}
}
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;
if (count < spriteCache[i].length) {
const spritesToRemove = spriteCache[i].slice(count, spriteCache[i].length);
for (let rs of spritesToRemove) {
if (!rs.getData('locked') as boolean) {
for (const rs of spritesToRemove) {
if (!rs.getData("locked") as boolean) {
const spriteCacheIndex = spriteCache[i].indexOf(rs);
spriteCache[i].splice(spriteCacheIndex, 1);
if (i === AnimFrameTarget.GRAPHIC)
if (i === AnimFrameTarget.GRAPHIC) {
spritePriorities.splice(spriteCacheIndex, 1);
}
rs.destroy();
}
}
@ -914,18 +961,20 @@ export abstract class BattleAnim {
r--;
},
onComplete: () => {
for (let ms of Object.values(spriteCache).flat()) {
if (ms && !ms.getData('locked'))
for (const ms of Object.values(spriteCache).flat()) {
if (ms && !ms.getData("locked")) {
ms.destroy();
}
}
if (r) {
scene.tweens.addCounter({
duration: Utils.getFrameMs(r),
onComplete: () => cleanUpAndComplete()
});
} else
} else {
cleanUpAndComplete();
}
}
});
}
}
@ -998,15 +1047,15 @@ export class MoveChargeAnim extends MoveAnim {
export async function populateAnims() {
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 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 commonNamePattern = /name: (?:Common:)?(Opp )?(.*)/;
const moveNameToId = {};
for (let move of Utils.getEnumValues(Moves).slice(1)) {
const moveName = Moves[move].toUpperCase().replace(/\_/g, '');
for (const move of Utils.getEnumValues(Moves).slice(1)) {
const moveName = Moves[move].toUpperCase().replace(/\_/g, "");
moveNameToId[moveName] = move;
}
@ -1014,49 +1063,52 @@ export async function populateAnims() {
const animsData = [];//battleAnimRawData.split('!ruby/array:PBAnimation').slice(1);
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 commonAnimId: CommonAnim;
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 name = nameMatch[2].toLowerCase();
if (commonAnimMatchNames.indexOf(name) > -1)
if (commonAnimMatchNames.indexOf(name) > -1) {
commonAnimId = commonAnimIds[commonAnimMatchNames.indexOf(name)];
else if (chargeAnimMatchNames.indexOf(name) > -1) {
isOppMove = nameField.startsWith('name: Opp ');
} else if (chargeAnimMatchNames.indexOf(name) > -1) {
isOppMove = nameField.startsWith("name: Opp ");
chargeAnimId = chargeAnimIds[chargeAnimMatchNames.indexOf(name)];
}
}
const nameIndex = nameField.indexOf(':', 5) + 1;
const animName = nameField.slice(nameIndex, nameField.indexOf('\n', nameIndex));
if (!moveNameToId.hasOwnProperty(animName) && !commonAnimId && !chargeAnimId)
const nameIndex = nameField.indexOf(":", 5) + 1;
const animName = nameField.slice(nameIndex, nameField.indexOf("\n", nameIndex));
if (!moveNameToId.hasOwnProperty(animName) && !commonAnimId && !chargeAnimId) {
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];
if (commonAnimId)
}
if (commonAnimId) {
commonAnims.set(commonAnimId, anim);
else if (chargeAnimId)
} else if (chargeAnimId) {
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 ]);
}
for (let f = 0; f < fields.length; f++) {
const field = fields[f];
const fieldName = field.slice(0, field.indexOf(':'));
const fieldData = field.slice(fieldName.length + 1, field.lastIndexOf('\n')).trim();
const fieldName = field.slice(0, field.indexOf(":"));
const fieldData = field.slice(fieldName.length + 1, field.lastIndexOf("\n")).trim();
switch (fieldName) {
case 'array':
const framesData = fieldData.split(' - - - ').slice(1);
case "array":
const framesData = fieldData.split(" - - - ").slice(1);
for (let fd = 0; fd < framesData.length; fd++) {
anim.frames.push([]);
const frameData = framesData[fd];
const focusFramesData = frameData.split(' - - ');
const focusFramesData = frameData.split(" - - ");
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]),
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]),
@ -1065,115 +1117,126 @@ export async function populateAnims() {
}
}
break;
case 'graphic':
const graphic = fieldData !== "''" ? fieldData : '';
anim.graphic = graphic.indexOf('.') > -1
? graphic.slice(0, fieldData.indexOf('.'))
case "graphic":
const graphic = fieldData !== "''" ? fieldData : "";
anim.graphic = graphic.indexOf(".") > -1
? graphic.slice(0, fieldData.indexOf("."))
: graphic;
break;
case 'timing':
const timingEntries = fieldData.split('- !ruby/object:PBAnimTiming ').slice(1);
case "timing":
const timingEntries = fieldData.split("- !ruby/object:PBAnimTiming ").slice(1);
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",')
.replace(/flashColor: !ruby\/object:Color { alpha: ([\d\.]+), blue: ([\d\.]+), green: ([\d\.]+), red: ([\d\.]+)}/, 'flashRed: $4, flashGreen: $3, flashBlue: $2, flashAlpha: $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");
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]);
let timedEvent: AnimTimedEvent;
switch (timingType) {
case 0:
if (resourceName && resourceName.indexOf('.') === -1) {
if (resourceName && resourceName.indexOf(".") === -1) {
let ext: string;
[ 'wav', 'mp3', 'm4a' ].every(e => {
[ "wav", "mp3", "m4a" ].every(e => {
if (seNames.indexOf(`${resourceName}.${e}`) > -1) {
ext = e;
return false;
}
return true;
});
if (!ext)
ext = '.wav';
if (!ext) {
ext = ".wav";
}
resourceName += `.${ext}`;
}
timedEvent = new AnimTimedSoundEvent(frameIndex, resourceName);
break;
case 1:
timedEvent = new AnimTimedAddBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf('.')));
timedEvent = new AnimTimedAddBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf(".")));
break;
case 2:
timedEvent = new AnimTimedUpdateBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf('.')));
timedEvent = new AnimTimedUpdateBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf(".")));
break;
}
if (!timedEvent)
if (!timedEvent) {
continue;
}
const propPattern = /([a-z]+): (.*?)(?:,|\})/ig;
let propMatch: RegExpExecArray;
while ((propMatch = propPattern.exec(timingData))) {
const prop = propMatch[1];
let value: any = propMatch[2];
switch (prop) {
case 'bgX':
case 'bgY':
case "bgX":
case "bgY":
value = parseFloat(value);
break;
case 'volume':
case 'pitch':
case 'opacity':
case 'colorRed':
case 'colorGreen':
case 'colorBlue':
case 'colorAlpha':
case 'duration':
case 'flashScope':
case 'flashRed':
case 'flashGreen':
case 'flashBlue':
case 'flashAlpha':
case 'flashDuration':
case "volume":
case "pitch":
case "opacity":
case "colorRed":
case "colorGreen":
case "colorBlue":
case "colorAlpha":
case "duration":
case "flashScope":
case "flashRed":
case "flashGreen":
case "flashBlue":
case "flashAlpha":
case "flashDuration":
value = parseInt(value);
break;
}
if (timedEvent.hasOwnProperty(prop))
if (timedEvent.hasOwnProperty(prop)) {
timedEvent[prop] = value;
}
if (!anim.frameTimedEvents.has(frameIndex))
}
if (!anim.frameTimedEvents.has(frameIndex)) {
anim.frameTimedEvents.set(frameIndex, []);
}
anim.frameTimedEvents.get(frameIndex).push(timedEvent);
}
break;
case 'position':
case "position":
anim.position = parseInt(fieldData);
break;
case 'hue':
case "hue":
anim.hue = parseInt(fieldData);
break;
}
}
}
// used in commented code
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const animReplacer = (k, v) => {
if (k === 'id' && !v)
if (k === "id" && !v) {
return undefined;
if (v instanceof Map)
}
if (v instanceof Map) {
return Object.fromEntries(v);
if (v instanceof AnimTimedEvent)
v['eventType'] = v.getEventType();
}
if (v instanceof AnimTimedEvent) {
v["eventType"] = v.getEventType();
}
return v;
};
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 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 propSets = [ animConfigProps, animFrameProps ];
// used in commented code
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const animComparator = (a: Element, b: Element) => {
let props: string[];
let p = 0;
for (let p = 0; p < propSets.length; p++) {
props = propSets[p];
let ai = props.indexOf(a.key);
if (ai === -1)
const ai = props.indexOf(a.key);
if (ai === -1) {
continue;
let bi = props.indexOf(b.key);
}
const bi = props.indexOf(b.key);
return ai < bi ? -1 : ai > bi ? 1 : 0;
}

View File

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

View File

@ -56,7 +56,7 @@ export class BattlerTag {
}
getDescriptor(): string {
return '';
return "";
}
isSourceLinked(): boolean {
@ -97,13 +97,13 @@ export class RechargingTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
pokemon.getMoveQueue().push({ move: Moves.NONE, targets: [] })
pokemon.getMoveQueue().push({ move: Moves.NONE, targets: [] });
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
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.getMoveQueue().shift();
@ -136,7 +136,7 @@ export class TrappedTag extends BattlerTag {
}
getDescriptor(): string {
return 'trapping';
return "trapping";
}
isSourceLinked(): boolean {
@ -144,7 +144,7 @@ export class TrappedTag extends BattlerTag {
}
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);
(pokemon.scene.getCurrentPhase() as MovePhase).cancel();
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' flinched!'));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " flinched!"));
return true;
}
getDescriptor(): string {
return 'flinching';
return "flinching";
}
}
export class InterruptedTag extends BattlerTag {
constructor(sourceMove: Moves){
super(BattlerTagType.INTERRUPTED, BattlerTagLapseType.PRE_MOVE, 0, sourceMove)
super(BattlerTagType.INTERRUPTED, BattlerTagLapseType.PRE_MOVE, 0, sourceMove);
}
canAdd(pokemon: Pokemon): boolean {
return !!pokemon.getTag(BattlerTagType.FLYING)
return !!pokemon.getTag(BattlerTagType.FLYING);
}
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
pokemon.getMoveQueue().shift()
pokemon.pushMoveHistory({move: Moves.NONE, result: MoveResult.OTHER})
pokemon.getMoveQueue().shift();
pokemon.pushMoveHistory({move: Moves.NONE, result: MoveResult.OTHER});
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
super.lapse(pokemon, lapseType);
(pokemon.scene.getCurrentPhase() as MovePhase).cancel();
return true
return true;
}
}
@ -213,33 +213,33 @@ export class ConfusedTag extends BattlerTag {
super.onAdd(pokemon);
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 {
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 {
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 {
const ret = lapseType !== BattlerTagLapseType.CUSTOM && super.lapse(pokemon, lapseType);
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));
if (pokemon.randSeedInt(3)) {
const atk = pokemon.getBattleStat(Stat.ATK);
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));
pokemon.scene.queueMessage('It hurt itself in its\nconfusion!');
pokemon.scene.queueMessage("It hurt itself in its\nconfusion!");
pokemon.damageAndUpdate(damage);
pokemon.battleData.hitCount++;
(pokemon.scene.getCurrentPhase() as MovePhase).cancel();
@ -250,7 +250,7 @@ export class ConfusedTag extends BattlerTag {
}
getDescriptor(): string {
return 'confusion';
return "confusion";
}
}
@ -272,7 +272,7 @@ export class InfatuatedTag extends BattlerTag {
onOverlap(pokemon: Pokemon): void {
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 {
@ -283,7 +283,7 @@ export class InfatuatedTag extends BattlerTag {
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT));
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();
}
}
@ -294,7 +294,7 @@ export class InfatuatedTag extends BattlerTag {
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' got over\nits infatuation.'));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " got over\nits infatuation."));
}
isSourceLinked(): boolean {
@ -302,7 +302,7 @@ export class InfatuatedTag extends BattlerTag {
}
getDescriptor(): string {
return 'infatuation';
return "infatuation";
}
}
@ -329,7 +329,7 @@ export class SeedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
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();
}
@ -349,7 +349,7 @@ export class SeedTag extends BattlerTag {
const reverseDrain = pokemon.hasAbilityWithAttr(ReverseDrainAbAttr);
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, source.getBattlerIndex(),
!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));
}
}
@ -359,7 +359,7 @@ export class SeedTag extends BattlerTag {
}
getDescriptor(): string {
return 'seeding';
return "seeding";
}
}
@ -371,34 +371,35 @@ export class NightmareTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
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 {
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 {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
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
const cancelled = new Utils.BooleanHolder(false);
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
if (!cancelled.value)
if (!cancelled.value) {
pokemon.damageAndUpdate(Math.ceil(pokemon.getMaxHp() / 4));
}
}
return ret;
}
getDescriptor(): string {
return 'nightmares';
return "nightmares";
}
}
@ -437,17 +438,20 @@ export class EncoreTag extends BattlerTag {
}
canAdd(pokemon: Pokemon): boolean {
if (pokemon.isMax())
if (pokemon.isMax()) {
return false;
}
const lastMoves = pokemon.getLastXMoves(1);
if (!lastMoves.length)
if (!lastMoves.length) {
return false;
}
const repeatableMove = lastMoves[0];
if (!repeatableMove.move || repeatableMove.virtual)
if (!repeatableMove.move || repeatableMove.virtual) {
return false;
}
switch (repeatableMove.move) {
case Moves.MIMIC:
@ -460,8 +464,9 @@ export class EncoreTag extends BattlerTag {
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;
}
this.moveId = repeatableMove.move;
@ -471,7 +476,7 @@ export class EncoreTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
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);
if (movePhase) {
@ -487,7 +492,7 @@ export class EncoreTag extends BattlerTag {
onRemove(pokemon: Pokemon): void {
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 {
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),
getPokemonMessage(pokemon, ` absorbed\nnutrients with its roots!`), true));
getPokemonMessage(pokemon, " absorbed\nnutrients with its roots!"), true));
}
return ret;
}
getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon, ' planted its roots!');
return getPokemonMessage(pokemon, " planted its roots!");
}
getDescriptor(): string {
return 'roots';
return "roots";
}
}
@ -548,15 +554,16 @@ export class AquaRingTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
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 {
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), `${this.getMoveName()} restored\n${pokemon.name}\'s HP!`, true));
}
return ret;
}
@ -579,7 +586,7 @@ export class MinimizeTag extends BattlerTag {
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
//If a pokemon dynamaxes they lose minimized status
if(pokemon.isMax()){
return false
return false;
}
return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
}
@ -601,7 +608,7 @@ export class DrowsyTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' grew drowsy!'));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " grew drowsy!"));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -614,7 +621,7 @@ export class DrowsyTag extends BattlerTag {
}
getDescriptor(): string {
return 'drowsiness';
return "drowsiness";
}
}
@ -650,8 +657,9 @@ export abstract class DamagingTrapTag extends TrappedTag {
const cancelled = new Utils.BooleanHolder(false);
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
if (!cancelled.value)
pokemon.damageAndUpdate(Math.ceil(pokemon.getMaxHp() / 8))
if (!cancelled.value) {
pokemon.damageAndUpdate(Math.ceil(pokemon.getMaxHp() / 8));
}
}
return ret;
@ -684,7 +692,7 @@ export abstract class VortexTrapTag extends DamagingTrapTag {
}
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 {
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 {
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 {
super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\nprotected itself!'));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, "\nprotected itself!"));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.CUSTOM) {
new CommonBattleAnim(CommonAnim.PROTECT, pokemon).play(pokemon.scene);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\nprotected itself!'));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, "\nprotected itself!"));
return true;
}
@ -900,12 +908,12 @@ export class EnduringTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' braced\nitself!'));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " braced\nitself!"));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.CUSTOM) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' endured\nthe hit!'));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " endured\nthe hit!"));
return true;
}
@ -920,7 +928,7 @@ export class SturdyTag extends BattlerTag {
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.CUSTOM) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' endured\nthe hit!'));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " endured\nthe hit!"));
return true;
}
@ -940,10 +948,11 @@ export class PerishSongTag extends BattlerTag {
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = super.lapse(pokemon, lapseType);
if (ret)
if (ret) {
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);
}
return ret;
}
@ -974,8 +983,9 @@ export class TruantTag extends AbilityBattlerTag {
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (!pokemon.hasAbility(Abilities.TRUANT))
if (!pokemon.hasAbility(Abilities.TRUANT)) {
return super.lapse(pokemon, lapseType);
}
const passive = pokemon.getAbility().id !== Abilities.TRUANT;
const lastMove = pokemon.getLastXMoves().find(() => true);
@ -983,7 +993,7 @@ export class TruantTag extends AbilityBattlerTag {
if (lastMove && lastMove.move !== Moves.NONE) {
(pokemon.scene.getCurrentPhase() as MovePhase).cancel();
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;
@ -998,12 +1008,13 @@ export class SlowStartTag extends AbilityBattlerTag {
onAdd(pokemon: Pokemon): void {
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 {
if (!pokemon.hasAbility(this.ability))
if (!pokemon.hasAbility(this.ability)) {
this.turnCount = 1;
}
return super.lapse(pokemon, lapseType);
}
@ -1011,7 +1022,7 @@ export class SlowStartTag extends AbilityBattlerTag {
onRemove(pokemon: Pokemon): void {
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 {
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 {
@ -1192,7 +1203,7 @@ export class CritBoostTag extends BattlerTag {
onRemove(pokemon: Pokemon): void {
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 {
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();
}
@ -1271,7 +1282,7 @@ export class CursedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
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();
}

View File

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

View File

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

View File

@ -14,7 +14,7 @@ export interface DailyRunConfig {
export function fetchDailyRunSeed(): Promise<string> {
return new Promise<string>((resolve, reject) => {
Utils.apiFetch('daily/seed').then(response => {
Utils.apiFetch("daily/seed").then(response => {
if (!response.ok) {
resolve(null);
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.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.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.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.VULPIX]: [ Moves.MOONBLAST, Moves.PSYCHIC, Moves.MORNING_SUN, Moves.TAIL_GLOW ],
[Species.ZUBAT]: [ Moves.FLOATY_FALL, Moves.DIRE_CLAW, Moves.SWORDS_DANCE, Moves.BRAVE_BIRD ],
[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.WICKED_BLOW ],
[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.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.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 ],
@ -34,18 +34,18 @@ export const speciesEggMoves = {
[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.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.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.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.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.DROWZEE]: [ Moves.DREAM_EATER, Moves.RECOVER, Moves.NIGHTMARE, Moves.SPORE ],
[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.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 ],
@ -57,7 +57,7 @@ export const speciesEggMoves = {
[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.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.MAGIKARP]: [ Moves.FLIP_TURN, Moves.ICE_SPINNER, Moves.LIQUIDATION, Moves.DRAGON_ASCENT ],
[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.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.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.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 ],
@ -100,16 +100,16 @@ export const speciesEggMoves = {
[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.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.HERACROSS]: [ Moves.ROCK_BLAST, Moves.LUNGE, Moves.ICICLE_SPEAR, Moves.TIDY_UP ],
[Species.SNEASEL]: [ Moves.DIRE_CLAW, Moves.KOWTOW_CLEAVE, Moves.TRIPLE_AXEL, Moves.GLACIAL_LANCE ],
[Species.HERACROSS]: [ Moves.ROCK_BLAST, Moves.FIRST_IMPRESSION, Moves.ICICLE_SPEAR, Moves.TIDY_UP ],
[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.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.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.DELIBIRD]: [ Moves.GLACIATE, Moves.FREEZE_DRY, Moves.CHILLY_RECEPTION, Moves.BLEAKWIND_STORM ],
[Species.REMORAID]: [ Moves.WATER_SHURIKEN, Moves.SNIPE_SHOT, Moves.SEARING_SHOT, Moves.ELECTRO_SHOT ],
[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.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 ],
@ -122,10 +122,10 @@ export const speciesEggMoves = {
[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.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.LARVITAR]: [ Moves.DRAGON_DANCE, Moves.MOUNTAIN_GALE, Moves.MIGHTY_CLEAVE, Moves.SHORE_UP ],
[Species.SUICUNE]: [ Moves.RECOVER, Moves.NASTY_PLOT, Moves.FREEZE_DRY, Moves.STEAM_ERUPTION ],
[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.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.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 ],
@ -138,7 +138,7 @@ export const speciesEggMoves = {
[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.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.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 ],
@ -146,8 +146,8 @@ export const speciesEggMoves = {
[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.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.SABLEYE]: [ Moves.RECOVER, Moves.TOPSY_TURVY, Moves.PARTING_SHOT, Moves.SALT_CURE ],
[Species.SKITTY]: [ Moves.THUNDEROUS_KICK, Moves.ENTRAINMENT, Moves.TIDY_UP, Moves.V_CREATE ],
[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.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 ],
@ -159,8 +159,8 @@ export const speciesEggMoves = {
[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.WAILMER]: [ Moves.CURSE, Moves.LIQUIDATION, Moves.FLOATY_FALL, Moves.RECOVER ],
[Species.NUMEL]: [ Moves.SANDSEAR_STORM, Moves.SPIKES, Moves.SHORE_UP, Moves.SEARING_SHOT ],
[Species.TORKOAL]: [ Moves.SLACK_OFF, Moves.SPIKES, Moves.BODY_PRESS, Moves.BURNING_BULWARK ],
[Species.NUMEL]: [ Moves.TRICK_ROOM, Moves.ENERGY_BALL, Moves.MORNING_SUN, Moves.BLUE_FLARE ],
[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.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 ],
@ -176,20 +176,20 @@ export const speciesEggMoves = {
[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.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.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.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.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.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.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.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.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 ],
@ -208,9 +208,9 @@ export const speciesEggMoves = {
[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.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.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.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 ],
@ -235,16 +235,16 @@ export const speciesEggMoves = {
[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.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.ROTOM]: [ Moves.STRENGTH_SAP, Moves.FIERY_DANCE, Moves.SPLISHY_SPLASH, Moves.RISING_VOLTAGE ],
[Species.UXIE]: [ Moves.COSMIC_POWER, Moves.BODY_PRESS, Moves.RECOVER, Moves.LUMINA_CRASH ],
[Species.MESPRIT]: [ Moves.QUIVER_DANCE, Moves.AURA_SPHERE, Moves.RECOVER, Moves.LUMINA_CRASH ],
[Species.AZELF]: [ Moves.PHOTON_GEYSER, Moves.ICE_BEAM, Moves.MOONBLAST, Moves.LUMINA_CRASH ],
[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.SPARKLY_SWIRL ],
[Species.MESPRIT]: [ Moves.TAIL_GLOW, Moves.AURA_SPHERE, Moves.RECOVER, 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.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.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.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 ],
@ -260,37 +260,37 @@ export const speciesEggMoves = {
[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.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.PANPOUR]: [ Moves.NASTY_PLOT, Moves.ENERGY_BALL, Moves.AURA_SPHERE, Moves.STEAM_ERUPTION ],
[Species.MUNNA]: [ Moves.COSMIC_POWER, Moves.AURA_SPHERE, Moves.EARTH_POWER, Moves.LUMINA_CRASH ],
[Species.PANSEAR]: [ Moves.NASTY_PLOT, Moves.SCALD, Moves.SCORCHING_SANDS, Moves.TORCH_SONG ],
[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.MYSTICAL_POWER ],
[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.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.DRILBUR]: [ Moves.IRON_HEAD, Moves.ICE_SPINNER, Moves.SHIFT_GEAR, Moves.HEADLONG_RUSH ],
[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.THOUSAND_ARROWS ],
[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.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.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.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.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.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.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.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.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.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.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.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 ],
@ -304,7 +304,7 @@ export const speciesEggMoves = {
[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.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.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 ],
@ -312,7 +312,7 @@ export const speciesEggMoves = {
[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.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.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 ],
@ -330,7 +330,7 @@ export const speciesEggMoves = {
[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.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.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 ],
@ -352,7 +352,7 @@ export const speciesEggMoves = {
[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.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.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 ],
@ -369,7 +369,7 @@ export const speciesEggMoves = {
[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.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.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 ],
@ -386,7 +386,7 @@ export const speciesEggMoves = {
[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.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.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 ],
@ -394,12 +394,12 @@ export const speciesEggMoves = {
[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.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.PYUKUMUKU]: [ Moves.MIRROR_COAT, Moves.BANEFUL_BUNKER, Moves.TOXIC_SPIKES, Moves.SALT_CURE ],
[Species.SANDYGAST]: [ Moves.SCORCHING_SANDS, Moves.SPLISHY_SPLASH, Moves.CURSE, 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.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.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.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 ],
@ -410,12 +410,12 @@ export const speciesEggMoves = {
[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_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.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.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.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 ],
@ -426,9 +426,9 @@ export const speciesEggMoves = {
[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.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.SCORBUNNY]: [ Moves.EXTREME_SPEED, Moves.TROP_KICK, Moves.TRIPLE_AXEL, Moves.THUNDEROUS_KICK ],
[Species.SOBBLE]: [ Moves.AEROBLAST, Moves.FROST_BREATH, Moves.SEARING_SHOT, Moves.SURGING_STRIKES ],
[Species.GROOKEY]: [ Moves.HIGH_HORSEPOWER, Moves.CLANGOROUS_SOUL, Moves.GRASSY_GLIDE, Moves.SAPPY_SEED ],
[Species.SCORBUNNY]: [ Moves.EXTREME_SPEED, Moves.HIGH_JUMP_KICK, Moves.TRIPLE_AXEL, Moves.BOLT_STRIKE ],
[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.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 ],
@ -438,7 +438,7 @@ export const speciesEggMoves = {
[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.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.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 ],
@ -452,11 +452,11 @@ export const speciesEggMoves = {
[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.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.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.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.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 ],
@ -467,8 +467,8 @@ export const speciesEggMoves = {
[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.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.REGIDRAGO]: [ Moves.METEOR_MASH, Moves.FLAMETHROWER, Moves.CALM_MIND, Moves.DRAGON_DARTS ],
[Species.REGIELEKI]: [ Moves.NASTY_PLOT, Moves.ICE_BEAM, Moves.EARTH_POWER, Moves.ELECTRO_DRIFT ],
[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.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 ],
@ -478,40 +478,40 @@ export const speciesEggMoves = {
[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.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.PAWMI]: [ Moves.DRAIN_PUNCH, Moves.WISH, Moves.PARTING_SHOT, Moves.PLASMA_FISTS ],
[Species.TANDEMAUS]: [ Moves.BATON_PASS, Moves.BITE, Moves.SIZZLY_SLIDE, Moves.REVIVAL_BLESSING ],
[Species.FIDOUGH]: [ Moves.WISH, Moves.BODY_PRESS, Moves.PARTING_SHOT, Moves.SIZZLY_SLIDE ],
[Species.NYMBLE]: [ Moves.CEASELESS_EDGE, Moves.FELL_STINGER, Moves.ATTACK_ORDER, Moves.WICKED_BLOW ],
[Species.PAWMI]: [ Moves.DRAIN_PUNCH, Moves.ICE_PUNCH, Moves.MACH_PUNCH, Moves.PLASMA_FISTS ],
[Species.TANDEMAUS]: [ Moves.BATON_PASS, Moves.THIEF, Moves.SIZZLY_SLIDE, Moves.REVIVAL_BLESSING ],
[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.SQUAWKABILLY]: [ Moves.PARTING_SHOT, Moves.BULK_UP, Moves.FLARE_BLITZ, Moves.HEAD_CHARGE ],
[Species.NACLI]: [ Moves.BODY_PRESS, Moves.SPIKES, Moves.CURSE, Moves.DIAMOND_STORM ],
[Species.SQUAWKABILLY]: [ Moves.PARTING_SHOT, Moves.EARTHQUAKE, Moves.FLARE_BLITZ, Moves.EXTREME_SPEED ],
[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.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.MASCHIFF]: [ Moves.PARTING_SHOT, Moves.KNOCK_OFF, Moves.NUZZLE, Moves.COLLISION_COURSE ],
[Species.SHROODLE]: [ Moves.FIRE_LASH, Moves.PARTING_SHOT, Moves.TOXIC, Moves.TOPSY_TURVY ],
[Species.MASCHIFF]: [ Moves.PARTING_SHOT, Moves.KNOCK_OFF, Moves.PLAY_ROUGH, Moves.COLLISION_COURSE ],
[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.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.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.FLITTLE]: [ Moves.COSMIC_POWER, Moves.AURA_SPHERE, Moves.ROOST, Moves.SEARING_SHOT ],
[Species.TINKATINK]: [ Moves.NUZZLE, Moves.SHIFT_GEAR, Moves.ICE_HAMMER, Moves.PYRO_BALL ],
[Species.FLITTLE]: [ Moves.COSMIC_POWER, Moves.AURA_SPHERE, Moves.ROOST, Moves.FIERY_DANCE ],
[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.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.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.ORTHWORM]: [ Moves.GLARE, Moves.COIL, Moves.BODY_PRESS, Moves.SHORE_UP ],
[Species.GLIMMET]: [ Moves.CALM_MIND, Moves.SHORE_UP, Moves.PARTING_SHOT, Moves.FIERY_DANCE ],
[Species.GREAVARD]: [ Moves.TIDY_UP, Moves.YAWN, Moves.SHORE_UP, Moves.COLLISION_COURSE ],
[Species.ORTHWORM]: [ Moves.SIZZLY_SLIDE, Moves.COIL, Moves.BODY_PRESS, Moves.SHORE_UP ],
[Species.GLIMMET]: [ Moves.CALM_MIND, Moves.EARTH_POWER, Moves.FIERY_DANCE, Moves.MALIGNANT_CHAIN ],
[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.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.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.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.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 ],
@ -521,12 +521,12 @@ export const speciesEggMoves = {
[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_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.FRIGIBAX]: [ Moves.DRAGON_DARTS, Moves.BULK_UP, Moves.SHORE_UP, Moves.GLACIAL_LANCE ],
[Species.GIMMIGHOUL]: [ Moves.COSMIC_POWER, Moves.STORED_POWER, Moves.BATON_PASS, Moves.ASTRAL_BARRAGE ],
[Species.WO_CHIEN]: [ Moves.SPORE, Moves.RAGE_POWDER, Moves.SAPPY_SEED, Moves.STRENGTH_SAP ],
[Species.IRON_THORNS]: [ Moves.DIAMOND_STORM, Moves.SHORE_UP, Moves.SHIFT_GEAR, Moves.PLASMA_FISTS ],
[Species.FRIGIBAX]: [ Moves.DRAGON_DARTS, Moves.DRAGON_DANCE, Moves.EARTHQUAKE, Moves.GLACIAL_LANCE ],
[Species.GIMMIGHOUL]: [ Moves.COSMIC_POWER, Moves.STORED_POWER, Moves.EARTH_POWER, Moves.ASTRAL_BARRAGE ],
[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.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.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 ],
@ -534,28 +534,28 @@ export const speciesEggMoves = {
[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.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.OKIDOGI]: [ Moves.SLACK_OFF, Moves.OBSTRUCT, Moves.DIRE_CLAW, Moves.COLLISION_COURSE ],
[Species.POLTCHAGEIST]: [ Moves.SHELL_SMASH, Moves.INFERNAL_PARADE, Moves.LEECH_SEED, Moves.SPARKLY_SWIRL ],
[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.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.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.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.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.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_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_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_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_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_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 ],
@ -566,47 +566,49 @@ export const speciesEggMoves = {
[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.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_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.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.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 {
let output = '';
let output = "";
const speciesNames = Utils.getEnumKeys(Species);
const speciesValues = Utils.getEnumValues(Species);
const lines = content.split(/\n/g);
lines.forEach((line, l) => {
const cols = line.split(',').slice(0, 5);
const moveNames = allMoves.map(m => m.name.replace(/ \([A-Z]\)$/, '').toLowerCase());
const enumSpeciesName = cols[0].toUpperCase().replace(/[ -]/g, '_');
const cols = line.split(",").slice(0, 5);
const moveNames = allMoves.map(m => m.name.replace(/ \([A-Z]\)$/, "").toLowerCase());
const enumSpeciesName = cols[0].toUpperCase().replace(/[ -]/g, "_");
const species = speciesValues[speciesNames.findIndex(s => s === enumSpeciesName)];
let eggMoves: Moves[] = [];
const eggMoves: Moves[] = [];
for (let m = 0; m < 4; m++) {
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);
if (moveIndex === -1)
console.warn(moveName, 'could not be parsed');
if (moveIndex === -1) {
console.warn(moveName, "could not be parsed");
}
}
if (eggMoves.find(m => m !== Moves.NONE))
output += `[Species.${Species[species]}]: [ ${eggMoves.map(m => `Moves.${Moves[m]}`).join(', ')} ],\n`;
if (eggMoves.find(m => m !== Moves.NONE)) {
output += `[Species.${Species[species]}]: [ ${eggMoves.map(m => `Moves.${Moves[m]}`).join(", ")} ],\n`;
}
});
console.log(output);
}
const eggMovesStr = ``;
const eggMovesStr = "";
if (eggMovesStr) {
setTimeout(() => {
parseEggMoves(eggMovesStr);

View File

@ -1,10 +1,8 @@
import { Type } from "./type";
import * as Utils from "../utils";
import BattleScene from "../battle-scene";
import { Species } from "./enums/species";
import { getPokemonSpecies, speciesStarters } from "./pokemon-species";
import { EggTier } from "./enums/egg-type";
import i18next from '../plugins/i18n';
import i18next from "../plugins/i18n";
export const EGG_SEED = 1073741824;
@ -34,8 +32,9 @@ export class Egg {
}
getKey(): string {
if (this.isManaphyEgg())
return 'manaphy';
if (this.isManaphyEgg()) {
return "manaphy";
}
return this.tier.toString();
}
}
@ -53,38 +52,42 @@ export function getEggTierDefaultHatchWaves(tier: EggTier): integer {
}
export function getEggDescriptor(egg: Egg): string {
if (egg.isManaphyEgg())
return 'Manaphy';
if (egg.isManaphyEgg()) {
return "Manaphy";
}
switch (egg.tier) {
case EggTier.GREAT:
return i18next.t('egg:greatTier');
return i18next.t("egg:greatTier");
case EggTier.ULTRA:
return i18next.t('egg:ultraTier');
return i18next.t("egg:ultraTier");
case EggTier.MASTER:
return i18next.t('egg:masterTier');
return i18next.t("egg:masterTier");
default:
return i18next.t('egg:defaultTier');
return i18next.t("egg:defaultTier");
}
}
export function getEggHatchWavesMessage(hatchWaves: integer): string {
if (hatchWaves <= 5)
return i18next.t('egg:hatchWavesMessageSoon');
if (hatchWaves <= 15)
return i18next.t('egg:hatchWavesMessageClose');
if (hatchWaves <= 50)
return i18next.t('egg:hatchWavesMessageNotClose');
return i18next.t('egg:hatchWavesMessageLongTime');
if (hatchWaves <= 5) {
return i18next.t("egg:hatchWavesMessageSoon");
}
if (hatchWaves <= 15) {
return i18next.t("egg:hatchWavesMessageClose");
}
if (hatchWaves <= 50) {
return i18next.t("egg:hatchWavesMessageNotClose");
}
return i18next.t("egg:hatchWavesMessageLongTime");
}
export function getEggGachaTypeDescriptor(scene: BattleScene, egg: Egg): string {
switch (egg.gachaType) {
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:
return i18next.t('egg:gachaTypeMove');
return i18next.t("egg:gachaTypeMove");
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
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 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(() => {
ret = Phaser.Math.RND.shuffle(legendarySpecies)[index];

View File

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

View File

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

View File

@ -5,7 +5,7 @@ export enum GrowthRate {
MEDIUM_SLOW,
SLOW,
FLUCTUATING
};
}
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 ],
@ -19,8 +19,9 @@ const expLevels = [
export function getLevelTotalExp(level: integer, growthRate: GrowthRate): integer {
if (level < 100) {
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 levelExp;
}
@ -47,8 +48,9 @@ export function getLevelTotalExp(level: integer, growthRate: GrowthRate): intege
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);
}
@ -60,16 +62,16 @@ export function getLevelRelExp(level: integer, growthRate: GrowthRate): number {
export function getGrowthRateColor(growthRate: GrowthRate, shadow?: boolean) {
switch (growthRate) {
case GrowthRate.ERRATIC:
return !shadow ? '#f85888' : '#906060';
return !shadow ? "#f85888" : "#906060";
case GrowthRate.FAST:
return !shadow ? '#f8d030' : '#b8a038';
return !shadow ? "#f8d030" : "#b8a038";
case GrowthRate.MEDIUM_FAST:
return !shadow ? '#78c850' : '#588040';
return !shadow ? "#78c850" : "#588040";
case GrowthRate.MEDIUM_SLOW:
return !shadow ? '#6890f0' : '#807870';
return !shadow ? "#6890f0" : "#807870";
case GrowthRate.SLOW:
return !shadow ? '#f08030' : '#c03028';
return !shadow ? "#f08030" : "#c03028";
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) {
switch (gender) {
case Gender.MALE:
return '♂';
return "♂";
case Gender.FEMALE:
return '♀';
return "♀";
}
return '';
return "";
}
export function getGenderColor(gender: Gender, shadow?: boolean) {
switch (gender) {
case Gender.MALE:
return shadow ? '#006090' : '#40c8f8';
return shadow ? "#006090" : "#40c8f8";
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 { TextStyle, getBBCodeFrag } from "../ui/text";
import { UiTheme } from "#app/enums/ui-theme";
import i18next from 'i18next';
import i18next from "i18next";
export enum Nature {
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 {
let ret = Utils.toReadableString(Nature[nature]);
//Translating nature
if(i18next.exists('nature:' + ret)){
ret = i18next.t('nature:' + ret as any)
if(i18next.exists("nature:" + ret)){
ret = i18next.t("nature:" + ret as any);
}
if (includeStatEffects) {
const stats = Utils.getEnumValues(Stat).slice(1);
let increasedStat: Stat = null;
let decreasedStat: Stat = null;
for (let stat of stats) {
for (const stat of stats) {
const multiplier = getNatureStatMultiplier(nature, stat);
if (multiplier > 1)
if (multiplier > 1) {
increasedStat = stat;
else if (multiplier < 1)
} else if (multiplier < 1) {
decreasedStat = stat;
}
}
const textStyle = forStarterSelect ? TextStyle.SUMMARY_ALT : TextStyle.WINDOW;
const getTextFrag = !ignoreBBCode ? (text: string, style: TextStyle) => getBBCodeFrag(text, style, uiTheme) : (text: string, style: TextStyle) => text;
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)}`;
else
ret = getTextFrag(`${ret}${!forStarterSelect ? '\n' : ' '}(-)`, textStyle);
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)}`;
} else {
ret = getTextFrag(`${ret}${!forStarterSelect ? "\n" : " "}(-)`, textStyle);
}
}
return ret;
}

View File

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

View File

@ -1,5 +1,5 @@
import { Gender } from "./gender";
import { AttackTypeBoosterModifier, FlinchChanceModifier } from "../modifier/modifier";
import { FlinchChanceModifier } from "../modifier/modifier";
import { Moves } from "./enums/moves";
import { PokeballType } from "./pokeball";
import Pokemon from "../field/pokemon";
@ -185,7 +185,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.DUGTRIO, 26, null, null)
],
[Species.MEOWTH]: [
new SpeciesFormEvolution(Species.PERSIAN, '', '', 28, null, null)
new SpeciesFormEvolution(Species.PERSIAN, "", "", 28, null, null)
],
[Species.PSYDUCK]: [
new SpeciesEvolution(Species.GOLDUCK, 33, null, null)
@ -298,7 +298,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.QUILAVA, 14, null, null)
],
[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))
],
[Species.TOTODILE]: [
@ -646,7 +646,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.DEWOTT, 17, null, null)
],
[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))
],
[Species.PATRAT]: [
@ -797,7 +797,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.KINGAMBIT, 64, null, null)
],
[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))
],
[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)
],
[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, '', '', 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE))
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))
],
[Species.HONEDGE]: [
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)
],
[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))
],
[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)
],
[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))
],
[Species.NOIBAT]: [
@ -900,7 +900,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.DARTRIX, 17, null, null)
],
[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))
],
[Species.LITTEN]: [
@ -1049,9 +1049,9 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.BARRASKEWDA, 26, null, null)
],
[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 SpeciesFormEvolution(Species.TOXTRICITY, '', 'amped', 30, null, null)
new SpeciesFormEvolution(Species.TOXTRICITY, "", "amped", 30, null, null)
],
[Species.SIZZLIPEDE]: [
new SpeciesEvolution(Species.CENTISKORCH, 28, null, null)
@ -1109,7 +1109,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.HISUI_ZOROARK, 30, null, null)
],
[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]: [
new SpeciesEvolution(Species.FLORAGATO, 16, null, null)
@ -1130,8 +1130,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.QUAQUAVAL, 36, null, null)
],
[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, '', '', 18, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE))
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))
],
[Species.TAROUNTULA]: [
new SpeciesEvolution(Species.SPIDOPS, 15, null, null)
@ -1215,8 +1215,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.CLODSIRE, 20, null, null)
],
[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.RAICHU, '', '', 1, EvolutionItem.THUNDER_STONE, null, 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)
],
[Species.NIDORINA]: [
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)
],
[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)
],
[Species.TANGELA]: [
@ -1267,14 +1267,14 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
],
[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.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.VAPOREON, '', '', 1, EvolutionItem.WATER_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.LEAFEON, '', '', 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.GLACEON, '', '', 1, EvolutionItem.ICE_STONE, null, 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.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.JOLTEON, "", "", 1, EvolutionItem.THUNDER_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.GLACEON, "", "", 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG),
],
[Species.TOGETIC]: [
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)
],
[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]: [
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;
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);
}
return ret;
}), SpeciesWildEvolutionDelay.VERY_LONG),
new SpeciesEvolution(Species.DUDUNSPARCE, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0), 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.LONG)
],
[Species.GLIGAR]: [
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)
],
[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', 'male', 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE), 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)
],
[Species.MINCCINO]: [
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)
],
[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, '', '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, "", "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, "", "midnight", 25, null, new SpeciesEvolutionCondition(p => (p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT) && (p.formIndex === 0)), null)
],
[Species.STEENEE]: [
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)
],
[Species.SINISTEA]: [
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, "phony", "phony", 1, EvolutionItem.CRACKED_POT, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.POLTEAGEIST, "antique", "antique", 1, EvolutionItem.CHIPPED_POT, null, SpeciesWildEvolutionDelay.LONG)
],
[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, '', '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, '', '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, '', '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, '', '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, "", "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, "", "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, "", "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, "", "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, "", "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]: [
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]: [
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, "", "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)
],
[Species.GALAR_DARUMAKA]: [
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)
],
[Species.POLTCHAGEIST]: [
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, "counterfeit", "unremarkable", 1, EvolutionItem.UNREMARKABLE_TEACUP, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.SINISTCHA, "artisan", "masterpiece", 1, EvolutionItem.MASTERPIECE_TEACUP, null, SpeciesWildEvolutionDelay.LONG)
],
[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)
@ -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)
],
[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 {
@ -1618,13 +1620,14 @@ interface 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);
prevolutionKeys.forEach(pk => {
const evolutions = pokemonEvolutions[pk];
for (let ev of evolutions) {
if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1)
for (const ev of evolutions) {
if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) {
continue;
}
pokemonPrevolutions[ev.speciesId] = parseInt(pk) as Species;
}
});

View File

@ -147,38 +147,46 @@ export class SpeciesFormChange {
}
canChange(pokemon: Pokemon): boolean {
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))
if (pokemon.species.speciesId !== this.speciesId) {
return false;
}
if (!this.trigger.canChange(pokemon))
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 (const condition of this.conditions) {
if (!condition.predicate(pokemon)) {
return false;
}
}
if (!this.trigger.canChange(pokemon)) {
return false;
}
return true;
}
findTrigger(triggerType: { new(...args: any[]): SpeciesFormChangeTrigger }): SpeciesFormChangeTrigger {
if (!this.trigger.hasTriggerType(triggerType))
if (!this.trigger.hasTriggerType(triggerType)) {
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;
}
@ -218,10 +226,11 @@ export class SpeciesFormChangeCompoundTrigger {
}
canChange(pokemon: Pokemon): boolean {
for (let trigger of this.triggers) {
if (!trigger.canChange(pokemon))
for (const trigger of this.triggers) {
if (!trigger.canChange(pokemon)) {
return false;
}
}
return true;
}
@ -278,8 +287,9 @@ export class SpeciesFormChangeStatusEffectTrigger extends SpeciesFormChangeTrigg
constructor(statusEffects: StatusEffect | StatusEffect[], invert: boolean = false) {
super();
if (!Array.isArray(statusEffects))
if (!Array.isArray(statusEffects)) {
statusEffects = [ statusEffects ];
}
this.statusEffects = statusEffects;
this.invert = invert;
}
@ -310,7 +320,7 @@ export abstract class SpeciesFormChangeMoveTrigger extends SpeciesFormChangeTrig
constructor(move: Moves | ((m: Moves) => boolean), used: boolean = true) {
super();
this.movePredicate = typeof move === 'function' ? move : (m: Moves) => m === move;
this.movePredicate = typeof move === "function" ? move : (m: Moves) => m === move;
this.used = used;
}
}
@ -344,17 +354,21 @@ export class SpeciesDefaultFormMatchTrigger extends SpeciesFormChangeTrigger {
export function getSpeciesFormChangeMessage(pokemon: Pokemon, formChange: SpeciesFormChange, preName: string): string {
const isMega = formChange.formKey.indexOf(SpeciesFormKey.MEGA) > -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 prefix = !pokemon.isPlayer() ? pokemon.hasTrainer() ? 'Foe ' : 'Wild ' : 'Your ';
if (isMega)
const prefix = !pokemon.isPlayer() ? pokemon.hasTrainer() ? "Foe " : "Wild " : "Your ";
if (isMega) {
return `${prefix}${preName} mega-evolved\ninto ${pokemon.name}!`;
if (isGmax)
}
if (isGmax) {
return `${prefix}${preName} Gigantamaxed\ninto ${pokemon.name}!`;
if (isEmax)
}
if (isEmax) {
return `${prefix}${preName} Eternamaxed\ninto ${pokemon.name}!`;
if (isRevert)
}
if (isRevert) {
return `${prefix}${pokemon.name} reverted\nto its original form!`;
}
return `${prefix}${preName} changed form!`;
}
@ -364,221 +378,221 @@ interface PokemonFormChanges {
export const pokemonFormChanges: PokemonFormChanges = {
[Species.VENUSAUR]: [
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.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.VENUSAURITE)),
new SpeciesFormChange(Species.VENUSAUR, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[Species.BLASTOISE]: [
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.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BLASTOISINITE)),
new SpeciesFormChange(Species.BLASTOISE, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[Species.CHARIZARD]: [
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.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
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.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[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]: [
new SpeciesFormChange(Species.BEEDRILL, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BEEDRILLITE))
new SpeciesFormChange(Species.BEEDRILL, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BEEDRILLITE))
],
[Species.PIDGEOT]: [
new SpeciesFormChange(Species.PIDGEOT, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.PIDGEOTITE))
new SpeciesFormChange(Species.PIDGEOT, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.PIDGEOTITE))
],
[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]: [
new SpeciesFormChange(Species.MEOWTH, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
new SpeciesFormChange(Species.MEOWTH, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[Species.ALAKAZAM]: [
new SpeciesFormChange(Species.ALAKAZAM, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALAKAZITE))
new SpeciesFormChange(Species.ALAKAZAM, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALAKAZITE))
],
[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]: [
new SpeciesFormChange(Species.SLOWBRO, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SLOWBRONITE))
new SpeciesFormChange(Species.SLOWBRO, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SLOWBRONITE))
],
[Species.GENGAR]: [
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.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GENGARITE)),
new SpeciesFormChange(Species.GENGAR, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[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]: [
new SpeciesFormChange(Species.KANGASKHAN, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.KANGASKHANITE))
new SpeciesFormChange(Species.KANGASKHAN, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.KANGASKHANITE))
],
[Species.PINSIR]: [
new SpeciesFormChange(Species.PINSIR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.PINSIRITE))
new SpeciesFormChange(Species.PINSIR, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.PINSIRITE))
],
[Species.GYARADOS]: [
new SpeciesFormChange(Species.GYARADOS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GYARADOSITE))
new SpeciesFormChange(Species.GYARADOS, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GYARADOSITE))
],
[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]: [
new SpeciesFormChange(Species.EEVEE, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
new SpeciesFormChange(Species.EEVEE, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[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]: [
new SpeciesFormChange(Species.AERODACTYL, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AERODACTYLITE))
new SpeciesFormChange(Species.AERODACTYL, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AERODACTYLITE))
],
[Species.MEWTWO]: [
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_X, new SpeciesFormChangeItemTrigger(FormChangeItem.MEWTWONITE_X)),
new SpeciesFormChange(Species.MEWTWO, "", SpeciesFormKey.MEGA_Y, new SpeciesFormChangeItemTrigger(FormChangeItem.MEWTWONITE_Y))
],
[Species.AMPHAROS]: [
new SpeciesFormChange(Species.AMPHAROS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AMPHAROSITE))
new SpeciesFormChange(Species.AMPHAROS, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AMPHAROSITE))
],
[Species.STEELIX]: [
new SpeciesFormChange(Species.STEELIX, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.STEELIXITE))
new SpeciesFormChange(Species.STEELIX, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.STEELIXITE))
],
[Species.SCIZOR]: [
new SpeciesFormChange(Species.SCIZOR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SCIZORITE))
new SpeciesFormChange(Species.SCIZOR, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SCIZORITE))
],
[Species.HERACROSS]: [
new SpeciesFormChange(Species.HERACROSS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.HERACRONITE))
new SpeciesFormChange(Species.HERACROSS, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.HERACRONITE))
],
[Species.HOUNDOOM]: [
new SpeciesFormChange(Species.HOUNDOOM, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.HOUNDOOMINITE))
new SpeciesFormChange(Species.HOUNDOOM, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.HOUNDOOMINITE))
],
[Species.TYRANITAR]: [
new SpeciesFormChange(Species.TYRANITAR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.TYRANITARITE))
new SpeciesFormChange(Species.TYRANITAR, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.TYRANITARITE))
],
[Species.SCEPTILE]: [
new SpeciesFormChange(Species.SCEPTILE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SCEPTILITE))
new SpeciesFormChange(Species.SCEPTILE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SCEPTILITE))
],
[Species.BLAZIKEN]: [
new SpeciesFormChange(Species.BLAZIKEN, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BLAZIKENITE))
new SpeciesFormChange(Species.BLAZIKEN, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BLAZIKENITE))
],
[Species.SWAMPERT]: [
new SpeciesFormChange(Species.SWAMPERT, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SWAMPERTITE))
new SpeciesFormChange(Species.SWAMPERT, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SWAMPERTITE))
],
[Species.GARDEVOIR]: [
new SpeciesFormChange(Species.GARDEVOIR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GARDEVOIRITE))
new SpeciesFormChange(Species.GARDEVOIR, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GARDEVOIRITE))
],
[Species.SABLEYE]: [
new SpeciesFormChange(Species.SABLEYE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SABLENITE))
new SpeciesFormChange(Species.SABLEYE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SABLENITE))
],
[Species.MAWILE]: [
new SpeciesFormChange(Species.MAWILE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MAWILITE))
new SpeciesFormChange(Species.MAWILE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MAWILITE))
],
[Species.AGGRON]: [
new SpeciesFormChange(Species.AGGRON, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AGGRONITE))
new SpeciesFormChange(Species.AGGRON, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AGGRONITE))
],
[Species.MEDICHAM]: [
new SpeciesFormChange(Species.MEDICHAM, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MEDICHAMITE))
new SpeciesFormChange(Species.MEDICHAM, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MEDICHAMITE))
],
[Species.MANECTRIC]: [
new SpeciesFormChange(Species.MANECTRIC, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MANECTITE))
new SpeciesFormChange(Species.MANECTRIC, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MANECTITE))
],
[Species.SHARPEDO]: [
new SpeciesFormChange(Species.SHARPEDO, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SHARPEDONITE))
new SpeciesFormChange(Species.SHARPEDO, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SHARPEDONITE))
],
[Species.CAMERUPT]: [
new SpeciesFormChange(Species.CAMERUPT, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.CAMERUPTITE))
new SpeciesFormChange(Species.CAMERUPT, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.CAMERUPTITE))
],
[Species.ALTARIA]: [
new SpeciesFormChange(Species.ALTARIA, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALTARIANITE))
new SpeciesFormChange(Species.ALTARIA, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALTARIANITE))
],
[Species.BANETTE]: [
new SpeciesFormChange(Species.BANETTE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BANETTITE))
new SpeciesFormChange(Species.BANETTE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BANETTITE))
],
[Species.ABSOL]: [
new SpeciesFormChange(Species.ABSOL, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ABSOLITE))
new SpeciesFormChange(Species.ABSOL, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ABSOLITE))
],
[Species.GLALIE]: [
new SpeciesFormChange(Species.GLALIE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GLALITITE))
new SpeciesFormChange(Species.GLALIE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GLALITITE))
],
[Species.SALAMENCE]: [
new SpeciesFormChange(Species.SALAMENCE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SALAMENCITE))
new SpeciesFormChange(Species.SALAMENCE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SALAMENCITE))
],
[Species.METAGROSS]: [
new SpeciesFormChange(Species.METAGROSS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.METAGROSSITE))
new SpeciesFormChange(Species.METAGROSS, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.METAGROSSITE))
],
[Species.LATIAS]: [
new SpeciesFormChange(Species.LATIAS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LATIASITE))
new SpeciesFormChange(Species.LATIAS, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LATIASITE))
],
[Species.LATIOS]: [
new SpeciesFormChange(Species.LATIOS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LATIOSITE))
new SpeciesFormChange(Species.LATIOS, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LATIOSITE))
],
[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]: [
new SpeciesFormChange(Species.GROUDON, '', SpeciesFormKey.PRIMAL, new SpeciesFormChangeItemTrigger(FormChangeItem.RED_ORB))
new SpeciesFormChange(Species.GROUDON, "", SpeciesFormKey.PRIMAL, new SpeciesFormChangeItemTrigger(FormChangeItem.RED_ORB))
],
[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]: [
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', 'speed', new SpeciesFormChangeItemTrigger(FormChangeItem.SMOOTH_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", "speed", new SpeciesFormChangeItemTrigger(FormChangeItem.SMOOTH_METEORITE))
],
[Species.LOPUNNY]: [
new SpeciesFormChange(Species.LOPUNNY, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LOPUNNITE))
new SpeciesFormChange(Species.LOPUNNY, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LOPUNNITE))
],
[Species.GARCHOMP]: [
new SpeciesFormChange(Species.GARCHOMP, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GARCHOMPITE))
new SpeciesFormChange(Species.GARCHOMP, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GARCHOMPITE))
],
[Species.LUCARIO]: [
new SpeciesFormChange(Species.LUCARIO, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LUCARIONITE))
new SpeciesFormChange(Species.LUCARIO, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LUCARIONITE))
],
[Species.ABOMASNOW]: [
new SpeciesFormChange(Species.ABOMASNOW, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ABOMASITE))
new SpeciesFormChange(Species.ABOMASNOW, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ABOMASITE))
],
[Species.GALLADE]: [
new SpeciesFormChange(Species.GALLADE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GALLADITE))
new SpeciesFormChange(Species.GALLADE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GALLADITE))
],
[Species.AUDINO]: [
new SpeciesFormChange(Species.AUDINO, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AUDINITE))
new SpeciesFormChange(Species.AUDINO, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AUDINITE))
],
[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]: [
new SpeciesFormChange(Species.PALKIA, '', SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.LUSTROUS_ORB))
new SpeciesFormChange(Species.PALKIA, "", SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.LUSTROUS_ORB))
],
[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]: [
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 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 SpeciesFormChangeTimeOfDayTrigger(TimeOfDay.DAWN, TimeOfDay.NIGHT)),
new SpeciesFormChange(Species.SHAYMIN, "sky", "land", new SpeciesFormChangeStatusEffectTrigger(StatusEffect.FREEZE))
],
[Species.ARCEUS]: [
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', 'poison', new SpeciesFormChangeItemTrigger(FormChangeItem.TOXIC_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', 'bug', new SpeciesFormChangeItemTrigger(FormChangeItem.INSECT_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', 'fire', new SpeciesFormChangeItemTrigger(FormChangeItem.FLAME_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', 'electric', new SpeciesFormChangeItemTrigger(FormChangeItem.ZAP_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', 'dragon', new SpeciesFormChangeItemTrigger(FormChangeItem.DRACO_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", "fighting", new SpeciesFormChangeItemTrigger(FormChangeItem.FIST_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", "ground", new SpeciesFormChangeItemTrigger(FormChangeItem.EARTH_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", "ghost", new SpeciesFormChangeItemTrigger(FormChangeItem.SPOOKY_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", "water", new SpeciesFormChangeItemTrigger(FormChangeItem.SPLASH_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", "psychic", new SpeciesFormChangeItemTrigger(FormChangeItem.MIND_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", "dark", new SpeciesFormChangeItemTrigger(FormChangeItem.DREAD_PLATE)),
new SpeciesFormChange(Species.ARCEUS, "normal", "fairy", new SpeciesFormChangeItemTrigger(FormChangeItem.PIXIE_PLATE))
],
[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]: [
new SpeciesFormChange(Species.GARBODOR, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
new SpeciesFormChange(Species.GARBODOR, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[Species.TORNADUS]: [
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))
],
[Species.KYUREM]: [
new SpeciesFormChange(Species.KYUREM, '', 'black', new SpeciesFormChangeItemTrigger(FormChangeItem.DARK_STONE)),
new SpeciesFormChange(Species.KYUREM, '', 'white', new SpeciesFormChangeItemTrigger(FormChangeItem.LIGHT_STONE))
new SpeciesFormChange(Species.KYUREM, "", "black", new SpeciesFormChangeItemTrigger(FormChangeItem.DARK_STONE)),
new SpeciesFormChange(Species.KYUREM, "", "white", new SpeciesFormChangeItemTrigger(FormChangeItem.LIGHT_STONE))
],
[Species.KELDEO]: [
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, "ordinary", "resolute", new SpeciesFormChangeMoveLearnedTrigger(Moves.SECRET_SWORD)),
new SpeciesFormChange(Species.KELDEO, "resolute", "ordinary", new SpeciesFormChangeMoveLearnedTrigger(Moves.SECRET_SWORD, false))
],
[Species.MELOETTA]: [
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 SpeciesFormChangeActiveTrigger(false), 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 SpeciesFormChangeActiveTrigger(false), true)
],
[Species.GENESECT]: [
new SpeciesFormChange(Species.GENESECT, '', 'shock', new SpeciesFormChangeItemTrigger(FormChangeItem.SHOCK_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, '', 'douse', new SpeciesFormChangeItemTrigger(FormChangeItem.DOUSE_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, "", "chill", new SpeciesFormChangeItemTrigger(FormChangeItem.CHILL_DRIVE)),
new SpeciesFormChange(Species.GENESECT, "", "douse", new SpeciesFormChangeItemTrigger(FormChangeItem.DOUSE_DRIVE))
],
[Species.GRENINJA]: [
new SpeciesFormChange(Species.GRENINJA, 'battle-bond', 'ash', new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.GRENINJA, 'ash', 'battle-bond', new SpeciesFormChangeManualTrigger(), true)
new SpeciesFormChange(Species.GRENINJA, "battle-bond", "ash", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.GRENINJA, "ash", "battle-bond", new SpeciesFormChangeManualTrigger(), true)
],
[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, '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 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, "blade", "shield", new SpeciesFormChangeActiveTrigger(false), true)
],
[Species.ZYGARDE]: [
new SpeciesFormChange(Species.ZYGARDE, '50-pc', 'complete', 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, 'complete', '10-pc', 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, "10-pc", "complete", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.ZYGARDE, "complete", "10-pc", new SpeciesFormChangeManualTrigger(), true)
],
[Species.DIANCIE]: [
new SpeciesFormChange(Species.DIANCIE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.DIANCITE))
new SpeciesFormChange(Species.DIANCIE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.DIANCITE))
],
[Species.HOOPA]: [
new SpeciesFormChange(Species.HOOPA, '', 'unbound', new SpeciesFormChangeItemTrigger(FormChangeItem.PRISON_BOTTLE))
new SpeciesFormChange(Species.HOOPA, "", "unbound", new SpeciesFormChangeItemTrigger(FormChangeItem.PRISON_BOTTLE))
],
[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]: [
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', 'poison', new SpeciesFormChangeItemTrigger(FormChangeItem.POISON_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', 'bug', new SpeciesFormChangeItemTrigger(FormChangeItem.BUG_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', 'fire', new SpeciesFormChangeItemTrigger(FormChangeItem.FIRE_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', 'electric', new SpeciesFormChangeItemTrigger(FormChangeItem.ELECTRIC_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', 'dragon', new SpeciesFormChangeItemTrigger(FormChangeItem.DRAGON_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", "fighting", new SpeciesFormChangeItemTrigger(FormChangeItem.FIGHTING_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", "ground", new SpeciesFormChangeItemTrigger(FormChangeItem.GROUND_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", "ghost", new SpeciesFormChangeItemTrigger(FormChangeItem.GHOST_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", "water", new SpeciesFormChangeItemTrigger(FormChangeItem.WATER_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", "psychic", new SpeciesFormChangeItemTrigger(FormChangeItem.PSYCHIC_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", "dark", new SpeciesFormChangeItemTrigger(FormChangeItem.DARK_MEMORY)),
new SpeciesFormChange(Species.SILVALLY, "normal", "fairy", new SpeciesFormChangeItemTrigger(FormChangeItem.FAIRY_MEMORY))
],
[Species.MINIOR]: [
new SpeciesFormChange(Species.MINIOR, 'red-meteor', 'red', 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', 'orange-meteor', 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, 'green-meteor', 'green', 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', 'blue-meteor', 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, 'violet-meteor', 'violet', new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'violet', 'violet-meteor', 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, "orange-meteor", "orange", 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", "yellow-meteor", 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, "blue-meteor", "blue", 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", "indigo-meteor", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, "violet-meteor", "violet", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, "violet", "violet-meteor", new SpeciesFormChangeManualTrigger(), true)
],
[Species.MIMIKYU]: [
new SpeciesFormChange(Species.MIMIKYU, 'disguised', 'busted', new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MIMIKYU, 'busted', 'disguised', new SpeciesFormChangeManualTrigger(), true)
new SpeciesFormChange(Species.MIMIKYU, "disguised", "busted", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MIMIKYU, "busted", "disguised", new SpeciesFormChangeManualTrigger(), true)
],
[Species.NECROZMA]: [
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, "", "dawn-wings", new SpeciesFormChangeItemTrigger(FormChangeItem.N_LUNARIZER)),
new SpeciesFormChange(Species.NECROZMA, "", "dusk-mane", new SpeciesFormChangeItemTrigger(FormChangeItem.N_SOLARIZER))
],
[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]: [
new SpeciesFormChange(Species.RILLABOOM, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
new SpeciesFormChange(Species.RILLABOOM, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[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]: [
new SpeciesFormChange(Species.INTELEON, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
new SpeciesFormChange(Species.INTELEON, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[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]: [
new SpeciesFormChange(Species.ORBEETLE, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
new SpeciesFormChange(Species.ORBEETLE, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[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]: [
new SpeciesFormChange(Species.COALOSSAL, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
new SpeciesFormChange(Species.COALOSSAL, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[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]: [
new SpeciesFormChange(Species.APPLETUN, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
new SpeciesFormChange(Species.APPLETUN, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[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]: [
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, 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, "amped", 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, "lowkey", new SpeciesFormChangeCompoundTrigger(new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS, false), new SpeciesDefaultFormMatchTrigger("lowkey")))
],
[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]: [
new SpeciesFormChange(Species.HATTERENE, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
new SpeciesFormChange(Species.HATTERENE, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[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]: [
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, '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, '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, '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, 'rainbow-swirl', 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, "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, "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, "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, "rainbow-swirl", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[Species.MORPEKO]: [
new SpeciesFormChange(Species.MORPEKO, 'full-belly', 'hangry', new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MORPEKO, 'hangry', 'full-belly', new SpeciesFormChangeManualTrigger(), true)
new SpeciesFormChange(Species.MORPEKO, "full-belly", "hangry", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MORPEKO, "hangry", "full-belly", new SpeciesFormChangeManualTrigger(), true)
],
[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]: [
new SpeciesFormChange(Species.DURALUDON, '', SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
new SpeciesFormChange(Species.DURALUDON, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[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]: [
new SpeciesFormChange(Species.ZAMAZENTA, 'hero', 'crowned', new SpeciesFormChangeItemTrigger(FormChangeItem.RUSTED_SHIELD))
new SpeciesFormChange(Species.ZAMAZENTA, "hero", "crowned", new SpeciesFormChangeItemTrigger(FormChangeItem.RUSTED_SHIELD))
],
[Species.ETERNATUS]: [
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 SpeciesFormChangeManualTrigger()),
new SpeciesFormChange(Species.ETERNATUS, "", SpeciesFormKey.ETERNAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[Species.URSHIFU]: [
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, "single-strike", SpeciesFormKey.GIGANTAMAX_SINGLE, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)),
new SpeciesFormChange(Species.URSHIFU, "rapid-strike", SpeciesFormKey.GIGANTAMAX_RAPID, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
],
[Species.CALYREX]: [
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, "", "ice", new SpeciesFormChangeItemTrigger(FormChangeItem.ICY_REINS_OF_UNITY)),
new SpeciesFormChange(Species.CALYREX, "", "shadow", new SpeciesFormChangeItemTrigger(FormChangeItem.SHADOW_REINS_OF_UNITY))
],
[Species.ENAMORUS]: [
new SpeciesFormChange(Species.ENAMORUS, SpeciesFormKey.INCARNATE, SpeciesFormKey.THERIAN, new SpeciesFormChangeItemTrigger(FormChangeItem.REVEAL_GLASS))
],
[Species.OGERPON]: [
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', '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-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-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-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-tera', 'cornerstone-mask', new SpeciesFormChangeManualTrigger(), true) //When no longer holding a Rock Tera Shard
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", "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-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-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-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-tera", "cornerstone-mask", new SpeciesFormChangeManualTrigger(), true) //When no longer holding a Rock Tera Shard
],
[Species.TERAPAGOS]: [
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, 'stellar', 'terastal', new SpeciesFormChangeManualTrigger(), true) //When no longer holding a Stellar Tera Shard
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, "stellar", "terastal", new SpeciesFormChangeManualTrigger(), true) //When no longer holding a Stellar Tera Shard
],
[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);
formChangeKeys.forEach(pk => {
const formChanges = pokemonFormChanges[pk];
let newFormChanges: SpeciesFormChange[] = [];
for (let fc of formChanges) {
const newFormChanges: SpeciesFormChange[] = [];
for (const fc of formChanges) {
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)));
}
}
formChanges.push(...newFormChanges);
});
}

View File

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

View File

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

View File

@ -1,4 +1,4 @@
import i18next from '../plugins/i18n';
import i18next from "../plugins/i18n";
export enum Stat {
HP = 0,
@ -7,28 +7,28 @@ export enum Stat {
SPATK,
SPDEF,
SPD
};
}
export function getStatName(stat: Stat, shorten: boolean = false) {
let ret: string;
switch (stat) {
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;
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;
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;
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;
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;
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;
}
return ret;

View File

@ -1,45 +1,45 @@
import i18next from "../plugins/i18n";
export function getBattleCountSplashMessage(): string {
return `{COUNT} ${i18next.t('splashMessages:battlesWon')}`;
return `{COUNT} ${i18next.t("splashMessages:battlesWon")}`;
}
export function getSplashMessages(): string[] {
const splashMessages = Array(10).fill(getBattleCountSplashMessage());
splashMessages.push(...[
i18next.t('splashMessages:joinTheDiscord'),
i18next.t('splashMessages:infiniteLevels'),
i18next.t('splashMessages:everythingStacks'),
i18next.t('splashMessages:optionalSaveScumming'),
i18next.t('splashMessages:biomes'),
i18next.t('splashMessages:openSource'),
i18next.t('splashMessages:playWithSpeed'),
i18next.t('splashMessages:liveBugTesting'),
i18next.t('splashMessages:heavyInfluence'),
i18next.t('splashMessages:pokemonRiskAndPokemonRain'),
i18next.t('splashMessages:nowWithMoreSalt'),
i18next.t('splashMessages:infiniteFusionAtHome'),
i18next.t('splashMessages:brokenEggMoves'),
i18next.t('splashMessages:magnificent'),
i18next.t('splashMessages:mubstitute'),
i18next.t('splashMessages:thatsCrazy'),
i18next.t('splashMessages:oranceJuice'),
i18next.t('splashMessages:questionableBalancing'),
i18next.t('splashMessages:coolShaders'),
i18next.t('splashMessages:aiFree'),
i18next.t('splashMessages:suddenDifficultySpikes'),
i18next.t('splashMessages:basedOnAnUnfinishedFlashGame'),
i18next.t('splashMessages:moreAddictiveThanIntended'),
i18next.t('splashMessages:mostlyConsistentSeeds'),
i18next.t('splashMessages:achievementPointsDontDoAnything'),
i18next.t('splashMessages:youDoNotStartAtLevel'),
i18next.t('splashMessages:dontTalkAboutTheManaphyEggIncident'),
i18next.t('splashMessages:alsoTryPokengine'),
i18next.t('splashMessages:alsoTryEmeraldRogue'),
i18next.t('splashMessages:alsoTryRadicalRed'),
i18next.t('splashMessages:eeveeExpo'),
i18next.t('splashMessages:ynoproject'),
i18next.t("splashMessages:joinTheDiscord"),
i18next.t("splashMessages:infiniteLevels"),
i18next.t("splashMessages:everythingStacks"),
i18next.t("splashMessages:optionalSaveScumming"),
i18next.t("splashMessages:biomes"),
i18next.t("splashMessages:openSource"),
i18next.t("splashMessages:playWithSpeed"),
i18next.t("splashMessages:liveBugTesting"),
i18next.t("splashMessages:heavyInfluence"),
i18next.t("splashMessages:pokemonRiskAndPokemonRain"),
i18next.t("splashMessages:nowWithMoreSalt"),
i18next.t("splashMessages:infiniteFusionAtHome"),
i18next.t("splashMessages:brokenEggMoves"),
i18next.t("splashMessages:magnificent"),
i18next.t("splashMessages:mubstitute"),
i18next.t("splashMessages:thatsCrazy"),
i18next.t("splashMessages:oranceJuice"),
i18next.t("splashMessages:questionableBalancing"),
i18next.t("splashMessages:coolShaders"),
i18next.t("splashMessages:aiFree"),
i18next.t("splashMessages:suddenDifficultySpikes"),
i18next.t("splashMessages:basedOnAnUnfinishedFlashGame"),
i18next.t("splashMessages:moreAddictiveThanIntended"),
i18next.t("splashMessages:mostlyConsistentSeeds"),
i18next.t("splashMessages:achievementPointsDontDoAnything"),
i18next.t("splashMessages:youDoNotStartAtLevel"),
i18next.t("splashMessages:dontTalkAboutTheManaphyEggIncident"),
i18next.t("splashMessages:alsoTryPokengine"),
i18next.t("splashMessages:alsoTryEmeraldRogue"),
i18next.t("splashMessages:alsoTryRadicalRed"),
i18next.t("splashMessages:eeveeExpo"),
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 {
const sourceClause = sourceText ? ` ${statusEffect !== StatusEffect.SLEEP ? 'by' : 'from'} ${sourceText}` : '';
const sourceClause = sourceText ? ` ${statusEffect !== StatusEffect.SLEEP ? "by" : "from"} ${sourceText}` : "";
switch (statusEffect) {
case StatusEffect.POISON:
return `\nwas poisoned${sourceClause}!`;
@ -48,76 +48,76 @@ export function getStatusEffectObtainText(statusEffect: StatusEffect, sourceText
return `\nwas burned${sourceClause}!`;
}
return '';
return "";
}
export function getStatusEffectActivationText(statusEffect: StatusEffect): string {
switch (statusEffect) {
case StatusEffect.POISON:
case StatusEffect.TOXIC:
return ' is hurt\nby poison!';
return " is hurt\nby poison!";
case StatusEffect.PARALYSIS:
return ' is paralyzed!\nIt can\'t move!';
return " is paralyzed!\nIt can't move!";
case StatusEffect.SLEEP:
return ' is fast asleep.';
return " is fast asleep.";
case StatusEffect.FREEZE:
return ' is\nfrozen solid!';
return " is\nfrozen solid!";
case StatusEffect.BURN:
return ' is hurt\nby its burn!';
return " is hurt\nby its burn!";
}
return '';
return "";
}
export function getStatusEffectOverlapText(statusEffect: StatusEffect): string {
switch (statusEffect) {
case StatusEffect.POISON:
case StatusEffect.TOXIC:
return ' is\nalready poisoned!';
return " is\nalready poisoned!";
case StatusEffect.PARALYSIS:
return ' is\nalready paralyzed!';
return " is\nalready paralyzed!";
case StatusEffect.SLEEP:
return ' is\nalready asleep!';
return " is\nalready asleep!";
case StatusEffect.FREEZE:
return ' is\nalready frozen!';
return " is\nalready frozen!";
case StatusEffect.BURN:
return ' is\nalready burned!';
return " is\nalready burned!";
}
return '';
return "";
}
export function getStatusEffectHealText(statusEffect: StatusEffect): string {
switch (statusEffect) {
case StatusEffect.POISON:
case StatusEffect.TOXIC:
return ' was\ncured of its poison!';
return " was\ncured of its poison!";
case StatusEffect.PARALYSIS:
return ' was\nhealed of paralysis!';
return " was\nhealed of paralysis!";
case StatusEffect.SLEEP:
return ' woke up!';
return " woke up!";
case StatusEffect.FREEZE:
return ' was\ndefrosted!';
return " was\ndefrosted!";
case StatusEffect.BURN:
return ' was\nhealed of its burn!';
return " was\nhealed of its burn!";
}
return '';
return "";
}
export function getStatusEffectDescriptor(statusEffect: StatusEffect): string {
switch (statusEffect) {
case StatusEffect.POISON:
case StatusEffect.TOXIC:
return 'poisoning';
return "poisoning";
case StatusEffect.PARALYSIS:
return 'paralysis';
return "paralysis";
case StatusEffect.SLEEP:
return 'sleep';
return "sleep";
case StatusEffect.FREEZE:
return 'freezing';
return "freezing";
case StatusEffect.BURN:
return 'burn';
return "burn";
}
}

View File

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

View File

@ -24,8 +24,9 @@ export class Terrain {
}
lapse(): boolean {
if (this.turnsLeft)
if (this.turnsLeft) {
return !!--this.turnsLeft;
}
return true;
}
@ -33,16 +34,19 @@ export class Terrain {
getAttackTypeMultiplier(attackType: Type): number {
switch (this.terrainType) {
case TerrainType.ELECTRIC:
if (attackType === Type.ELECTRIC)
if (attackType === Type.ELECTRIC) {
return 1.3;
}
break;
case TerrainType.GRASSY:
if (attackType === Type.GRASS)
if (attackType === Type.GRASS) {
return 1.3;
}
break;
case TerrainType.PSYCHIC:
if (attackType === Type.PSYCHIC)
if (attackType === Type.PSYCHIC) {
return 1.3;
}
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 {
let t = 0;
for (let template of this.templates) {
if (t + template.size > index)
for (const template of this.templates) {
if (t + template.size > index) {
return template.getStrength(index - t);
}
t += template.size;
}
@ -85,9 +86,10 @@ export class TrainerPartyCompoundTemplate extends TrainerPartyTemplate {
isSameSpecies(index: integer): boolean {
let t = 0;
for (let template of this.templates) {
if (t + template.size > index)
for (const template of this.templates) {
if (t + template.size > index) {
return template.isSameSpecies(index - t);
}
t += template.size;
}
@ -96,9 +98,10 @@ export class TrainerPartyCompoundTemplate extends TrainerPartyTemplate {
isBalanced(index: integer): boolean {
let t = 0;
for (let template of this.templates) {
if (t + template.size > index)
for (const template of this.templates) {
if (t + template.size > index) {
return template.isBalanced(index - t);
}
t += template.size;
}
@ -211,8 +214,8 @@ export class TrainerConfig {
constructor(trainerType: TrainerType, allowLegendaries?: boolean) {
this.trainerType = trainerType;
this.name = Utils.toReadableString(TrainerType[this.getDerivedType()]);
this.battleBgm = 'battle_trainer';
this.victoryBgm = 'victory_trainer';
this.battleBgm = "battle_trainer";
this.victoryBgm = "victory_trainer";
this.partyTemplates = [trainerPartyTemplates.TWO_AVG];
this.speciesFilter = species => (allowLegendaries || (!species.legendary && !species.subLegendary && !species.mythical)) && !species.isTrainerForbidden();
}
@ -223,21 +226,22 @@ export class TrainerConfig {
getSpriteKey(female?: boolean): string {
let ret = this.getKey();
if (this.hasGenders)
ret += `_${female ? 'f' : 'm'}`;
if (this.hasGenders) {
ret += `_${female ? "f" : "m"}`;
}
return ret;
}
setName(name: string): TrainerConfig {
if (name === 'Finn') {
if (name === "Finn") {
// Give the rival a localized name
// First check if i18n is initialized
if (!getIsInitialized()) {
initI18n();
}
// This is only the male name, because the female name is handled in a different function (setHasGenders)
if (name === 'Finn') {
name = i18next.t('trainerNames:rival');
if (name === "Finn") {
name = i18next.t("trainerNames:rival");
}
}
this.name = name;
@ -251,7 +255,7 @@ export class TrainerConfig {
}
// 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
this.title = i18next.t(`titles:${title}`);
@ -289,14 +293,14 @@ export class TrainerConfig {
**/
setHasGenders(nameFemale?: string, femaleEncounterBgm?: TrainerType | string): TrainerConfig {
// 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.
if (!getIsInitialized()) {
// Initialize the i18n system if it is not already initialized.
initI18n();
}
// Set the localized name for the female rival.
this.nameFemale = i18next.t('trainerNames:rival_female');
this.nameFemale = i18next.t("trainerNames:rival_female");
} else {
// Otherwise, assign the provided female name.
this.nameFemale = nameFemale;
@ -309,8 +313,8 @@ export class TrainerConfig {
if (femaleEncounterBgm) {
// 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.
this.femaleEncounterBgm = typeof femaleEncounterBgm === 'number'
? TrainerType[femaleEncounterBgm].toString().replace(/_/g, ' ').toLowerCase()
this.femaleEncounterBgm = typeof femaleEncounterBgm === "number"
? TrainerType[femaleEncounterBgm].toString().replace(/_/g, " ").toLowerCase()
: femaleEncounterBgm;
}
@ -321,8 +325,9 @@ export class TrainerConfig {
setHasDouble(nameDouble: string, doubleEncounterBgm?: TrainerType | string): TrainerConfig {
this.hasDouble = true;
this.nameDouble = nameDouble;
if (doubleEncounterBgm)
this.doubleEncounterBgm = typeof doubleEncounterBgm === 'number' ? TrainerType[doubleEncounterBgm].toString().replace(/\_/g, ' ').toLowerCase() : doubleEncounterBgm;
if (doubleEncounterBgm) {
this.doubleEncounterBgm = typeof doubleEncounterBgm === "number" ? TrainerType[doubleEncounterBgm].toString().replace(/\_/g, " ").toLowerCase() : doubleEncounterBgm;
}
return this;
}
@ -362,7 +367,7 @@ export class 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;
}
@ -435,8 +440,9 @@ export class TrainerConfig {
// Set up party members with their corresponding species.
signatureSpecies.forEach((speciesPool, s) => {
// Ensure speciesPool is an array.
if (!Array.isArray(speciesPool))
if (!Array.isArray(speciesPool)) {
speciesPool = [speciesPool];
}
// Set a function to get a random party member from the species pool.
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.
const nameForCall = this.name.toLowerCase().replace(/\s/g, '_');
const nameForCall = this.name.toLowerCase().replace(/\s/g, "_");
this.name = i18next.t(`trainerNames:${nameForCall}`);
// 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.
this.setMoneyMultiplier(2.5);
this.setBoss();
this.setStaticParty();
this.setBattleBgm('battle_unova_gym');
this.setVictoryBgm('victory_gym');
this.setBattleBgm("battle_unova_gym");
this.setVictoryBgm("victory_gym");
this.setGenModifiersFunc(party => {
const waveIndex = party[0].scene.currentBattle.waveIndex;
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.
signatureSpecies.forEach((speciesPool, s) => {
// Ensure speciesPool is an array.
if (!Array.isArray(speciesPool))
if (!Array.isArray(speciesPool)) {
speciesPool = [speciesPool];
}
// Set a function to get a random party member from the species pool.
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.
const nameForCall = this.name.toLowerCase().replace(/\s/g, '_');
const nameForCall = this.name.toLowerCase().replace(/\s/g, "_");
this.name = i18next.t(`trainerNames:${nameForCall}`);
// 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.
this.setMoneyMultiplier(3.25);
this.setBoss();
this.setStaticParty();
this.setBattleBgm('battle_elite');
this.setVictoryBgm('victory_gym');
this.setBattleBgm("battle_elite");
this.setVictoryBgm("victory_gym");
this.setGenModifiersFunc(party => getRandomTeraModifiers(party, 2, specialtyTypes.length ? specialtyTypes : null));
return this;
@ -535,8 +542,9 @@ export class TrainerConfig {
// Set up party members with their corresponding species.
signatureSpecies.forEach((speciesPool, s) => {
// Ensure speciesPool is an array.
if (!Array.isArray(speciesPool))
if (!Array.isArray(speciesPool)) {
speciesPool = [speciesPool];
}
// Set a function to get a random party member from the species pool.
this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool));
});
@ -545,18 +553,18 @@ export class TrainerConfig {
this.setSpeciesFilter(p => p.baseTotal >= 470);
// 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}`);
// 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.
this.setMoneyMultiplier(10);
this.setBoss();
this.setStaticParty();
this.setBattleBgm('battle_champion_alder');
this.setVictoryBgm('victory_champion');
this.setBattleBgm("battle_champion_alder");
this.setVictoryBgm("victory_champion");
this.setGenModifiersFunc(party => getRandomTeraModifiers(party, 3));
return this;
@ -569,19 +577,21 @@ export class TrainerConfig {
* @returns {string} - The title of the trainer.
**/
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
if (!trainerSlot && variant === TrainerVariant.DOUBLE && this.nameDouble)
if (!trainerSlot && variant === TrainerVariant.DOUBLE && this.nameDouble) {
return this.nameDouble;
}
// Female variant
if (this.hasGenders) {
// If the name is already set
if (this.nameFemale) {
// 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;
}
} else
// Check if !variant is true, if so return the name, else return the name with _female appended
if (variant) {
@ -607,9 +617,10 @@ export class TrainerConfig {
const isDouble = variant === TrainerVariant.DOUBLE;
const trainerKey = this.getSpriteKey(variant === TrainerVariant.FEMALE);
const partnerTrainerKey = this.getSpriteKey(true);
scene.loadAtlas(trainerKey, 'trainer');
if (isDouble)
scene.loadAtlas(partnerTrainerKey, 'trainer');
scene.loadAtlas(trainerKey, "trainer");
if (isDouble) {
scene.loadAtlas(partnerTrainerKey, "trainer");
}
scene.load.once(Phaser.Loader.Events.COMPLETE, () => {
const originalWarn = console.warn;
// Ignore warnings for missing frames, because there will be a lot
@ -636,8 +647,9 @@ export class TrainerConfig {
}
resolve();
});
if (!scene.load.isLoading())
if (!scene.load.isLoading()) {
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 {
return (scene: BattleScene, level: integer, strength: PartyMemberStrength) => {
let species = Utils.randSeedItem(speciesPool);
if (!ignoreEvolution)
if (!ignoreEvolution) {
species = getPokemonSpecies(species).getTrainerSpeciesForLevel(level, true, strength);
}
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 = {
[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)),
[TrainerType.ARTIST]: new TrainerConfig(++t).setEncounterBgm(TrainerType.RICH).setPartyTemplates(trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.THREE_AVG)
.setSpeciesPools([ Species.SMEARGLE ]),
[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)
.setSpeciesPools({
[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.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.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)
.setSpeciesPools({
[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.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))
.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)
.setSpeciesPools({
[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.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)
.setSpeciesPools({
[TrainerPoolTier.COMMON]: [ Species.PICHU, Species.STARLY, Species.TAILLOW, Species.BOLTUND ],
@ -739,7 +752,7 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerPoolTier.SUPER_RARE]: [ Species.POPPLIO ]
}),
[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)),
[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)
@ -769,7 +782,7 @@ export const trainerConfigs: TrainerConfigs = {
[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)
.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)
.setPartyTemplates(trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG)
.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.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),
[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)
.setSpeciesPools({
[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.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)
.setSpeciesPools({
[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.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({
[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.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 ],
}),
[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]: 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.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({
[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 ],
@ -818,66 +831,66 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerPoolTier.ULTRA_RARE]: [ Species.ROTOM, Species.MELTAN ]
}),
[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.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({
[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.RARE]: [ Species.TANGELA, Species.EEVEE, Species.YANMA ],
[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()
.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(1, getRandomPartyMemberFunc([ Species.MINUN, Species.ILLUMISE, Species.EMOLGA, Species.CASCOON, Species.KAKUNA, Species.CLEFFA, Species.COTTONEE, Species.EEVEE ], TrainerSlot.TRAINER_PARTNER))
.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.WAITER]: new TrainerConfig(++t).setHasGenders('Waitress').setHasDouble('Restaurant Staff').setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.CLERK)
[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)
.setSpeciesPools({
[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.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.YOUNGSTER]: new TrainerConfig(++t).setMoneyMultiplier(0.5).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders('Lass', 'lass').setHasDouble('Beginners').setPartyTemplates(trainerPartyTemplates.TWO_WEAKER)
[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)
.setSpeciesPools(
[ 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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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),
@ -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.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.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.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.CYNTHIA]: new TrainerConfig(++t).initForChampion([ Species.SPIRITOMB, Species.GIRATINA, Species.GARCHOMP, Species.MILOTIC, Species.LUCARIO, Species.TOGEKISS ]).setBattleBgm('battle_sinnoh_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.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.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.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.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 ]),
@ -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.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)
.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)),
[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)
.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(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(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))
.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(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))
@ -995,7 +1008,7 @@ export const trainerConfigs: TrainerConfigs = {
const starter = party[0];
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,
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))
@ -1011,7 +1024,7 @@ export const trainerConfigs: TrainerConfigs = {
const starter = party[0];
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,
p => {
p.setBoss(true, 3);

View File

@ -6,7 +6,7 @@ class TrainerNameConfig {
public femaleUrls: 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 {
@ -19,6 +19,8 @@ interface TrainerNameConfigs {
[key: integer]: TrainerNameConfig
}
// used in a commented code
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const trainerNameConfigs: TrainerNameConfigs = {
[TrainerType.ACE_TRAINER]: new TrainerNameConfig(TrainerType.ACE_TRAINER),
[TrainerType.ARTIST]: new TrainerNameConfig(TrainerType.ARTIST),
@ -27,13 +29,13 @@ const trainerNameConfigs: TrainerNameConfigs = {
[TrainerType.BAKER]: new TrainerNameConfig(TrainerType.BAKER),
[TrainerType.BEAUTY]: new TrainerNameConfig(TrainerType.BEAUTY),
[TrainerType.BIKER]: new TrainerNameConfig(TrainerType.BIKER),
[TrainerType.BLACK_BELT]: new TrainerNameConfig(TrainerType.BLACK_BELT).hasGenderVariant('Battle_Girl'),
[TrainerType.BREEDER]: new TrainerNameConfig(TrainerType.BREEDER, 'Pokémon_Breeder'),
[TrainerType.BLACK_BELT]: new TrainerNameConfig(TrainerType.BLACK_BELT).hasGenderVariant("Battle_Girl"),
[TrainerType.BREEDER]: new TrainerNameConfig(TrainerType.BREEDER, "Pokémon_Breeder"),
[TrainerType.CLERK]: new TrainerNameConfig(TrainerType.CLERK),
[TrainerType.CYCLIST]: new TrainerNameConfig(TrainerType.CYCLIST),
[TrainerType.DANCER]: new TrainerNameConfig(TrainerType.DANCER),
[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.GUITARIST]: new TrainerNameConfig(TrainerType.GUITARIST),
[TrainerType.HARLEQUIN]: new TrainerNameConfig(TrainerType.HARLEQUIN),
@ -50,24 +52,24 @@ const trainerNameConfigs: TrainerNameConfigs = {
[TrainerType.OFFICER]: new TrainerNameConfig(TrainerType.OFFICER),
[TrainerType.PARASOL_LADY]: new TrainerNameConfig(TrainerType.PARASOL_LADY),
[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.PSYCHIC]: new TrainerNameConfig(TrainerType.PSYCHIC),
[TrainerType.RANGER]: new TrainerNameConfig(TrainerType.RANGER),
[TrainerType.RICH]: new TrainerNameConfig(TrainerType.RICH, 'Gentleman').hasGenderVariant('Madame'),
[TrainerType.RICH_KID]: new TrainerNameConfig(TrainerType.RICH_KID, 'Rich_Boy').hasGenderVariant('Lady'),
[TrainerType.RICH]: new TrainerNameConfig(TrainerType.RICH, "Gentleman").hasGenderVariant("Madame"),
[TrainerType.RICH_KID]: new TrainerNameConfig(TrainerType.RICH_KID, "Rich_Boy").hasGenderVariant("Lady"),
[TrainerType.ROUGHNECK]: new TrainerNameConfig(TrainerType.ROUGHNECK),
[TrainerType.SCIENTIST]: new TrainerNameConfig(TrainerType.SCIENTIST),
[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.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.TWINS]: new TrainerNameConfig(TrainerType.TWINS),
[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.YOUNGSTER]: new TrainerNameConfig(TrainerType.YOUNGSTER).hasGenderVariant('Lass')
[TrainerType.YOUNGSTER]: new TrainerNameConfig(TrainerType.YOUNGSTER).hasGenderVariant("Lass")
};
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"],
};
// 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) {
return new Promise<void>(resolve => {
fetch(`https://bulbapedia.bulbagarden.net/wiki/${url}_(Trainer_class)`)
.then(response => response.text())
.then(html => {
console.log(url);
const htmlDoc = parser.parseFromString(html, 'text/html');
const trainerListHeader = htmlDoc.querySelector('#Trainer_list').parentElement;
const htmlDoc = parser.parseFromString(html, "text/html");
const trainerListHeader = htmlDoc.querySelector("#Trainer_list").parentElement;
const elements = [...trainerListHeader.parentElement.childNodes];
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 => {
if (t.nodeName !== 'TABLE' || t['className'] !== 'expandable')
if (t.nodeName !== "TABLE" || t["className"] !== "expandable") {
return false;
}
const childIndex = elements.indexOf(t);
return childIndex > startChildIndex && childIndex < endChildIndex;
}).map(t => t as Element);
console.log(url, tables)
for (let table of tables) {
const trainerRows = [...table.querySelectorAll('tr:not(:first-child)')].filter(r => r.children.length === 9);
for (let row of trainerRows) {
console.log(url, tables);
for (const table of tables) {
const trainerRows = [...table.querySelectorAll("tr:not(:first-child)")].filter(r => r.children.length === 9);
for (const row of trainerRows) {
const nameCell = row.firstElementChild;
const content = nameCell.innerHTML;
if (content.indexOf(' <a ') > -1) {
if (content.indexOf(" <a ") > -1) {
const female = /♀/.test(content);
if (url === 'Twins')
console.log(content)
if (url === "Twins") {
console.log(content);
}
const nameMatch = />([a-z]+(?: &amp; [a-z]+)?)<\/a>/i.exec(content);
if (nameMatch)
(female || forceFemale ? femaleTrainerNames : trainerNames).add(nameMatch[1].replace('&amp;', '&'));
if (nameMatch) {
(female || forceFemale ? femaleTrainerNames : trainerNames).add(nameMatch[1].replace("&amp;", "&"));
}
}
}
}

View File

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

View File

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

View File

@ -1,13 +1,15 @@
export function getData() {
const dataStr = localStorage.getItem('data');
if (!dataStr)
const dataStr = localStorage.getItem("data");
if (!dataStr) {
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() {
const sessionStr = localStorage.getItem('sessionData');
if (!sessionStr)
const sessionStr = localStorage.getItem("sessionData");
if (!sessionStr) {
return null;
}
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(() => {
if (!this.egg)
if (!this.egg) {
return this.end();
}
const eggIndex = this.scene.gameData.eggs.findIndex(e => e.id === this.egg.id);
if (eggIndex === -1)
if (eggIndex === -1) {
return this.end();
}
this.scene.gameData.eggs.splice(eggIndex, 1);
@ -63,17 +65,17 @@ export class EggHatchPhase extends Phase {
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.eggHatchContainer.add(this.eggHatchBg);
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.eggCrackSprite = this.scene.add.sprite(0, 0, 'egg_crack', '0');
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.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.setVisible(false);
@ -83,14 +85,14 @@ export class EggHatchPhase extends Phase {
this.eggHatchContainer.add(this.eggContainer);
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 });
return ret;
};
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.eggHatchContainer.add(this.pokemonShinySparkle);
@ -106,8 +108,9 @@ export class EggHatchPhase extends Phase {
this.eggHatchContainer.add(this.infoContainer);
const pokemon = this.generatePokemon();
if (pokemon.fusionSpecies)
if (pokemon.fusionSpecies) {
pokemon.clearFusionSpecies();
}
this.pokemonSprite.setVisible(false);
@ -117,41 +120,48 @@ export class EggHatchPhase extends Phase {
this.canSkip = true;
this.scene.time.delayedCall(1000, () => {
if (!this.hatched)
this.evolutionBgm = this.scene.playSoundWithoutBgm('evolution');
if (!this.hatched) {
this.evolutionBgm = this.scene.playSoundWithoutBgm("evolution");
}
});
this.scene.time.delayedCall(2000, () => {
if (this.hatched)
if (this.hatched) {
return;
}
this.eggCrackSprite.setVisible(true);
this.doSpray(1, this.eggSprite.displayHeight / -2);
this.doEggShake(2).then(() => {
if (this.hatched)
if (this.hatched) {
return;
}
this.scene.time.delayedCall(1000, () => {
if (this.hatched)
if (this.hatched) {
return;
}
this.doSpray(2, this.eggSprite.displayHeight / -4);
this.eggCrackSprite.setFrame('1');
this.scene.time.delayedCall(125, () => this.eggCrackSprite.setFrame('2'));
this.eggCrackSprite.setFrame("1");
this.scene.time.delayedCall(125, () => this.eggCrackSprite.setFrame("2"));
this.doEggShake(4).then(() => {
if (this.hatched)
if (this.hatched) {
return;
}
this.scene.time.delayedCall(1000, () => {
if (this.hatched)
if (this.hatched) {
return;
this.scene.playSound('egg_crack');
}
this.scene.playSound("egg_crack");
this.doSpray(4);
this.eggCrackSprite.setFrame('3');
this.scene.time.delayedCall(125, () => this.eggCrackSprite.setFrame('4'));
this.eggCrackSprite.setFrame("3");
this.scene.time.delayedCall(125, () => this.eggCrackSprite.setFrame("4"));
this.doEggShake(8, 2).then(() => {
if (!this.hatched)
if (!this.hatched) {
this.doHatch();
}
});
});
});
});
})
});
});
});
@ -159,74 +169,82 @@ export class EggHatchPhase extends Phase {
}
end() {
if (this.scene.findPhase((p) => p instanceof EggHatchPhase))
if (this.scene.findPhase((p) => p instanceof EggHatchPhase)) {
this.eggHatchHandler.clear();
else
} else {
this.scene.time.delayedCall(250, () => this.scene.setModifiersVisible(true));
}
super.end();
}
doEggShake(intensity: number, repeatCount?: integer, count?: integer): Promise<void> {
return new Promise(resolve => {
if (repeatCount === undefined)
if (repeatCount === undefined) {
repeatCount = 0;
if (count === undefined)
}
if (count === undefined) {
count = 0;
this.scene.playSound('pb_move');
}
this.scene.playSound("pb_move");
this.scene.tweens.add({
targets: this.eggContainer,
x: `-=${intensity / (count ? 1 : 2)}`,
ease: 'Sine.easeInOut',
ease: "Sine.easeInOut",
duration: 125,
onComplete: () => {
this.scene.tweens.add({
targets: this.eggContainer,
x: `+=${intensity}`,
ease: 'Sine.easeInOut',
ease: "Sine.easeInOut",
duration: 250,
onComplete: () => {
count++;
if (count < repeatCount)
if (count < repeatCount) {
return this.doEggShake(intensity, repeatCount, count).then(() => resolve());
}
this.scene.tweens.add({
targets: this.eggContainer,
x: `-=${intensity / 2}`,
ease: 'Sine.easeInOut',
ease: "Sine.easeInOut",
duration: 125,
onComplete: () => resolve()
});
}
})
});
}
});
});
}
trySkip(): boolean {
if (!this.canSkip || this.skipped)
if (!this.canSkip || this.skipped) {
return false;
}
this.skipped = true;
if (!this.hatched)
if (!this.hatched) {
this.doHatch();
else
} else {
this.doReveal();
}
return true;
}
doHatch(): void {
this.canSkip = false;
this.hatched = true;
if (this.evolutionBgm)
if (this.evolutionBgm) {
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.play('egg_lightrays');
this.eggLightraysOverlay.play("egg_lightrays");
this.scene.tweens.add({
duration: Utils.fixedInt(125),
targets: this.eggHatchOverlay,
alpha: 1,
ease: 'Cubic.easeIn',
ease: "Cubic.easeIn",
onComplete: () => {
this.skipped = false;
this.canSkip = true;
@ -234,40 +252,45 @@ export class EggHatchPhase extends Phase {
});
this.scene.time.delayedCall(Utils.fixedInt(1500), () => {
this.canSkip = false;
if (!this.skipped)
if (!this.skipped) {
this.doReveal();
}
});
}
doReveal(): void {
const isShiny = this.pokemon.isShiny();
if (this.pokemon.species.subLegendary)
if (this.pokemon.species.subLegendary) {
this.scene.validateAchv(achvs.HATCH_SUB_LEGENDARY);
if (this.pokemon.species.legendary)
}
if (this.pokemon.species.legendary) {
this.scene.validateAchv(achvs.HATCH_LEGENDARY);
if (this.pokemon.species.mythical)
}
if (this.pokemon.species.mythical) {
this.scene.validateAchv(achvs.HATCH_MYTHICAL);
if (isShiny)
}
if (isShiny) {
this.scene.validateAchv(achvs.HATCH_SHINY);
}
this.eggContainer.setVisible(false);
this.pokemonSprite.play(this.pokemon.getSpriteKey(true));
this.pokemonSprite.setPipelineData('ignoreTimeTint', true);
this.pokemonSprite.setPipelineData('spriteKey', this.pokemon.getSpriteKey());
this.pokemonSprite.setPipelineData('shiny', this.pokemon.shiny);
this.pokemonSprite.setPipelineData('variant', this.pokemon.variant);
this.pokemonSprite.setPipelineData("ignoreTimeTint", true);
this.pokemonSprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey());
this.pokemonSprite.setPipelineData("shiny", this.pokemon.shiny);
this.pokemonSprite.setPipelineData("variant", this.pokemon.variant);
this.pokemonSprite.setVisible(true);
this.scene.time.delayedCall(Utils.fixedInt(250), () => {
this.pokemon.cry();
if (isShiny) {
this.scene.time.delayedCall(Utils.fixedInt(500), () => {
this.pokemonShinySparkle.play(`sparkle${this.pokemon.variant ? `_${this.pokemon.variant + 1}` : ''}`);
this.scene.playSound('sparkle');
this.pokemonShinySparkle.play(`sparkle${this.pokemon.variant ? `_${this.pokemon.variant + 1}` : ""}`);
this.scene.playSound("sparkle");
});
}
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.scene.playSoundWithoutBgm('evolution_fanfare');
this.scene.playSoundWithoutBgm("evolution_fanfare");
this.scene.ui.showText(`${this.pokemon.name} hatched from the egg!`, null, () => {
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),
targets: this.eggHatchOverlay,
alpha: 0,
ease: 'Cubic.easeOut'
ease: "Cubic.easeOut"
});
}
@ -306,14 +329,14 @@ export class EggHatchPhase extends Phase {
doSprayParticle(trigIndex: integer, offsetY: number) {
const initialX = this.eggHatchBg.displayWidth / 2;
const initialY = this.eggHatchBg.displayHeight / 2 + offsetY;
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 shardKey = !this.egg.isManaphyEgg() ? this.egg.tier.toString() : "1";
const particle = this.scene.add.image(initialX, initialY, "egg_shard", `${shardKey}_${Math.floor(trigIndex / 2)}`);
this.eggHatchContainer.add(particle);
let f = 0;
let yOffset = 0;
let speed = 3 - Utils.randInt(8);
let amp = 24 + Utils.randInt(32);
const speed = 3 - Utils.randInt(8);
const amp = 24 + Utils.randInt(32);
const particleTimer = this.scene.tweens.addCounter({
repeat: -1,
@ -329,8 +352,9 @@ export class EggHatchPhase extends Phase {
if (trigIndex < 160) {
particle.setPosition(initialX + (speed * f) / 3, initialY + yOffset);
particle.y += -this.sin(trigIndex, amp);
if (f > 108)
if (f > 108) {
particle.setScale((1 - (f - 108) / 20));
}
trigIndex += 2 * speedMultiplier;
f += speedMultiplier;
} else {
@ -354,9 +378,10 @@ export class EggHatchPhase extends Phase {
speciesOverride = rand ? Species.PHIONE : Species.MANAPHY;
} else if (this.egg.tier === EggTier.MASTER
&& this.egg.gachaType === GachaType.LEGENDARY) {
if (!Utils.randSeedInt(2))
if (!Utils.randSeedInt(2)) {
speciesOverride = getLegendaryGachaSpeciesForTimestamp(this.scene, this.egg.timestamp);
}
}
if (speciesOverride) {
const pokemonSpecies = getPokemonSpecies(speciesOverride);
@ -386,18 +411,19 @@ export class EggHatchPhase extends Phase {
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)
.map(s => parseInt(s) as Species)
.filter(s => !pokemonPrevolutions.hasOwnProperty(s) && getPokemonSpecies(s).isObtainable() && ignoredSpecies.indexOf(s) === -1);
let totalWeight = 0;
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);
const species = getPokemonSpecies(speciesId);
if (species.isRegional())
if (species.isRegional()) {
weight = Math.floor(weight / (species.isRareRegional() ? 8 : 2));
}
speciesWeights.push(totalWeight + weight);
totalWeight += weight;
}
@ -422,8 +448,9 @@ export class EggHatchPhase extends Phase {
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]);
}
const baseChance = this.egg.gachaType === GachaType.MOVE ? 3 : 6;
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(() => {
if (!this.validate())
if (!this.validate()) {
return this.end();
}
this.scene.fadeOutBgm(null, false);
@ -57,11 +58,11 @@ export class EvolutionPhase extends Phase {
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.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.setScale(0.4359673025);
this.evolutionBg.setVisible(false);
@ -73,7 +74,7 @@ export class EvolutionPhase extends Phase {
this.evolutionContainer.add(this.evolutionBgOverlay);
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 });
return ret;
};
@ -97,13 +98,14 @@ export class EvolutionPhase extends Phase {
[ this.pokemonSprite, this.pokemonTintSprite, this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => {
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.setPipelineData('ignoreTimeTint', true);
sprite.setPipelineData('spriteKey', this.pokemon.getSpriteKey());
sprite.setPipelineData('shiny', this.pokemon.shiny);
sprite.setPipelineData('variant', this.pokemon.variant);
[ 'spriteColors', 'fusionSpriteColors' ].map(k => {
if (this.pokemon.summonData?.speciesForm)
k += 'Base';
sprite.setPipelineData("ignoreTimeTint", true);
sprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey());
sprite.setPipelineData("shiny", this.pokemon.shiny);
sprite.setPipelineData("variant", this.pokemon.variant);
[ "spriteColors", "fusionSpriteColors" ].map(k => {
if (this.pokemon.summonData?.speciesForm) {
k += "Base";
}
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 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.getPossibleEvolution(this.evolution).then(evolvedPokemon => {
[ this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => {
sprite.play(evolvedPokemon.getSpriteKey(true));
sprite.setPipelineData('ignoreTimeTint', true);
sprite.setPipelineData('spriteKey', evolvedPokemon.getSpriteKey());
sprite.setPipelineData('shiny', evolvedPokemon.shiny);
sprite.setPipelineData('variant', evolvedPokemon.variant);
[ 'spriteColors', 'fusionSpriteColors' ].map(k => {
if (evolvedPokemon.summonData?.speciesForm)
k += 'Base';
sprite.setPipelineData("ignoreTimeTint", true);
sprite.setPipelineData("spriteKey", evolvedPokemon.getSpriteKey());
sprite.setPipelineData("shiny", evolvedPokemon.shiny);
sprite.setPipelineData("variant", evolvedPokemon.variant);
[ "spriteColors", "fusionSpriteColors" ].map(k => {
if (evolvedPokemon.summonData?.speciesForm) {
k += "Base";
}
sprite.pipelineData[k] = evolvedPokemon.getSprite().pipelineData[k];
});
});
this.scene.time.delayedCall(1000, () => {
const evolutionBgm = this.scene.playSoundWithoutBgm('evolution');
const evolutionBgm = this.scene.playSoundWithoutBgm("evolution");
this.scene.tweens.add({
targets: this.evolutionBgOverlay,
alpha: 1,
delay: 500,
duration: 1500,
ease: 'Sine.easeOut',
ease: "Sine.easeOut",
onComplete: () => {
this.scene.time.delayedCall(1000, () => {
this.scene.tweens.add({
@ -152,7 +155,7 @@ export class EvolutionPhase extends Phase {
this.evolutionBg.setVisible(true);
this.evolutionBg.play();
});
this.scene.playSound('charge');
this.scene.playSound("charge");
this.doSpiralUpward();
this.scene.tweens.addCounter({
from: 0,
@ -164,7 +167,7 @@ export class EvolutionPhase extends Phase {
onComplete: () => {
this.pokemonSprite.setVisible(false);
this.scene.time.delayedCall(1100, () => {
this.scene.playSound('beam');
this.scene.playSound("beam");
this.doArcDownward();
this.scene.time.delayedCall(1500, () => {
this.pokemonEvoTintSprite.setScale(0.25);
@ -188,8 +191,8 @@ export class EvolutionPhase extends Phase {
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:pauseEvolutionsQuestion', { 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, () => {
const end = () => {
this.scene.ui.showText(null, 0);
this.scene.playBgm();
@ -199,7 +202,7 @@ export class EvolutionPhase extends Phase {
this.scene.ui.setOverlayMode(Mode.CONFIRM, () => {
this.scene.ui.revertMode();
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.time.delayedCall(3000, end);
@ -209,7 +212,7 @@ export class EvolutionPhase extends Phase {
return;
}
this.scene.playSound('sparkle');
this.scene.playSound("sparkle");
this.pokemonEvoSprite.setVisible(true);
this.doCircleInward();
this.scene.time.delayedCall(900, () => {
@ -217,17 +220,18 @@ export class EvolutionPhase extends Phase {
this.pokemon.evolve(this.evolution).then(() => {
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 EndEvolutionPhase(this.scene));
this.scene.playSound('shine');
this.scene.playSound("shine");
this.doSpray();
this.scene.tweens.add({
targets: this.evolutionOverlay,
alpha: 1,
duration: 250,
easing: 'Sine.easeIn',
easing: "Sine.easeIn",
onComplete: () => {
this.evolutionBgOverlay.setAlpha(1);
this.evolutionBg.setVisible(false);
@ -236,7 +240,7 @@ export class EvolutionPhase extends Phase {
alpha: 0,
duration: 2000,
delay: 150,
easing: 'Sine.easeIn',
easing: "Sine.easeIn",
onComplete: () => {
this.scene.tweens.add({
targets: this.evolutionBgOverlay,
@ -247,10 +251,10 @@ export class EvolutionPhase extends Phase {
this.scene.time.delayedCall(250, () => {
this.pokemon.cry();
this.scene.time.delayedCall(1250, () => {
this.scene.playSoundWithoutBgm('evolution_fanfare');
this.scene.playSoundWithoutBgm("evolution_fanfare");
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());
});
});
@ -266,7 +270,7 @@ export class EvolutionPhase extends Phase {
});
});
}
})
});
}
});
});
@ -283,9 +287,10 @@ export class EvolutionPhase extends Phase {
onRepeat: () => {
if (f < 64) {
if (!(f & 7)) {
for (let i = 0; i < 4; i++)
for (let i = 0; i < 4; i++) {
this.doSpiralUpwardParticle((f & 120) * 2 + i * 64);
}
}
f++;
}
}
@ -301,9 +306,10 @@ export class EvolutionPhase extends Phase {
onRepeat: () => {
if (f < 96) {
if (f < 6) {
for (let i = 0; i < 9; i++)
for (let i = 0; i < 9; i++) {
this.doArcDownParticle(i * 16);
}
}
f++;
}
}
@ -317,22 +323,23 @@ export class EvolutionPhase extends Phase {
this.scene.tweens.add({
targets: this.pokemonTintSprite,
scale: 0.25,
ease: 'Cubic.easeInOut',
ease: "Cubic.easeInOut",
duration: 500 / l,
yoyo: !isLastCycle
});
this.scene.tweens.add({
targets: this.pokemonEvoTintSprite,
scale: 1,
ease: 'Cubic.easeInOut',
ease: "Cubic.easeInOut",
duration: 500 / l,
yoyo: !isLastCycle,
onComplete: () => {
if (evolutionHandler.cancelled)
if (evolutionHandler.cancelled) {
return resolve(false);
if (l < lastCycle)
}
if (l < lastCycle) {
this.doCycle(l + 0.5, lastCycle).then(success => resolve(success));
else {
} else {
this.pokemonTintSprite.setVisible(false);
resolve(true);
}
@ -349,12 +356,14 @@ export class EvolutionPhase extends Phase {
duration: Utils.getFrameMs(1),
onRepeat: () => {
if (!f) {
for (let i = 0; i < 16; i++)
for (let i = 0; i < 16; i++) {
this.doCircleInwardParticle(i * 16, 4);
}
} else if (f === 32) {
for (let i = 0; i < 16; i++)
for (let i = 0; i < 16; i++) {
this.doCircleInwardParticle(i * 16, 8);
}
}
f++;
}
});
@ -368,10 +377,12 @@ export class EvolutionPhase extends Phase {
duration: Utils.getFrameMs(1),
onRepeat: () => {
if (!f) {
for (let i = 0; i < 8; i++)
for (let i = 0; i < 8; i++) {
this.doSprayParticle(i);
} else if (f < 50)
}
} else if (f < 50) {
this.doSprayParticle(Utils.randInt(8));
}
f++;
}
});
@ -379,7 +390,7 @@ export class EvolutionPhase extends Phase {
doSpiralUpwardParticle(trigIndex: integer) {
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);
let f = 0;
@ -400,8 +411,9 @@ export class EvolutionPhase extends Phase {
particle.x += cos(trigIndex, amp);
particle.setScale(1 - (f / 80));
trigIndex += 4;
if (f & 1)
if (f & 1) {
amp--;
}
f++;
} else {
particle.destroy();
@ -414,7 +426,7 @@ export class EvolutionPhase extends Phase {
doArcDownParticle(trigIndex: integer) {
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);
this.evolutionContainer.add(particle);
@ -448,7 +460,7 @@ export class EvolutionPhase extends Phase {
doCircleInwardParticle(trigIndex: integer, speed: integer) {
const initialX = this.evolutionBaseBg.displayWidth / 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);
let amp = 120;
@ -480,13 +492,13 @@ export class EvolutionPhase extends Phase {
doSprayParticle(trigIndex: integer) {
const initialX = this.evolutionBaseBg.displayWidth / 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);
let f = 0;
let yOffset = 0;
let speed = 3 - Utils.randInt(8);
let amp = 48 + Utils.randInt(64);
const speed = 3 - Utils.randInt(8);
const amp = 48 + Utils.randInt(64);
const particleTimer = this.scene.tweens.addCounter({
repeat: -1,
@ -497,13 +509,15 @@ export class EvolutionPhase extends Phase {
});
const updateParticle = () => {
if (!(f & 3))
if (!(f & 3)) {
yOffset++;
}
if (trigIndex < 128) {
particle.setPosition(initialX + (speed * f) / 3, initialY + yOffset);
particle.y += -sin(trigIndex, amp);
if (f > 108)
if (f > 108) {
particle.setScale((1 - (f - 108) / 20));
}
trigIndex++;
f++;
} 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) {
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({
key: 'pb_open_particle',
key: "pb_open_particle",
frames: pbOpenParticlesFrameNames,
frameRate: 16,
repeat: -1
});
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);
const angle = index * 45;
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
});
particle.play({
key: 'pb_open_particle',
key: "pb_open_particle",
startFrame: (index + 3) % 4,
frameRate: Math.floor(16 * scene.gameSpeed)
});
@ -52,7 +52,7 @@ function doDefaultPbOpenParticles(scene: BattleScene, x: number, y: number, radi
delay: 500,
duration: 75,
alpha: 0,
ease: 'Sine.easeIn',
ease: "Sine.easeIn",
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) {
let particles: Phaser.GameObjects.Image[] = [];
for (let i = 0; i < 10; i++)
const particles: Phaser.GameObjects.Image[] = [];
for (let i = 0; i < 10; i++) {
particles.push(doFanOutParticle(scene, i * 25, x, y, 1, 1, 5, frameIndex));
}
scene.tweens.add({
targets: particles,
delay: 750,
duration: 250,
alpha: 0,
ease: 'Sine.easeIn',
ease: "Sine.easeIn",
onComplete: () => {
for (let particle of particles)
for (const particle of particles) {
particle.destroy();
}
}
});
}
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 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));
}
scene.tweens.add({
targets: particles,
delay: 750,
duration: 250,
alpha: 0,
ease: 'Sine.easeIn',
ease: "Sine.easeIn",
onComplete: () => {
for (let particle of particles)
for (const particle of particles) {
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 {
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);
const updateParticle = () => {
if (!particle.scene)
if (!particle.scene) {
return particleTimer.remove();
}
particle.x = x + sin(trigIndex, f * xSpeed);
particle.y = y + cos(trigIndex, f * ySpeed);
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 {
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.setAlpha(0.5);
scene.field.add(particle);
@ -139,14 +144,14 @@ export function addPokeballCaptureStars(scene: BattleScene, pokeball: Phaser.Gam
scene.tweens.add({
targets: particle,
y: pokeball.y - 10,
ease: 'Sine.easeOut',
ease: "Sine.easeOut",
duration: 250,
onComplete: () => {
scene.tweens.add({
targets: particle,
y: pokeball.y,
alpha: 0,
ease: 'Sine.easeIn',
ease: "Sine.easeIn",
duration: 250
});
}

View File

@ -18,7 +18,7 @@ import { TimeOfDay } from "../data/enums/time-of-day";
import { Terrain, TerrainType } from "../data/terrain";
import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability";
import Pokemon from "./pokemon";
import * as Overrides from '../overrides';
import * as Overrides from "../overrides";
export class Arena {
public scene: BattleScene;
@ -58,16 +58,18 @@ export class Arena {
const timeOfDay = this.getTimeOfDay();
if (timeOfDay !== this.lastTimeOfDay) {
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.lastTimeOfDay = timeOfDay;
}
}
randomSpecies(waveIndex: integer, level: integer, attempt?: integer): PokemonSpecies {
const overrideSpecies = this.scene.gameMode.getOverrideSpecies(waveIndex);
if (overrideSpecies)
if (overrideSpecies) {
return overrideSpecies;
}
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));
const tierValue = Utils.randSeedInt(!isBoss ? 512 : 64);
@ -82,23 +84,24 @@ export class Arena {
const tierPool = this.pokemonPool[tier];
let ret: PokemonSpecies;
let regen = false;
if (!tierPool.length)
if (!tierPool.length) {
ret = this.scene.randomSpecies(waveIndex, level);
else {
} else {
const entry = tierPool[Utils.randSeedInt(tierPool.length)];
let species: Species;
if (typeof entry === 'number')
if (typeof entry === "number") {
species = entry as Species;
else {
} else {
const levelThresholds = Object.keys(entry);
for (let l = levelThresholds.length - 1; l >= 0; l--) {
const levelThreshold = parseInt(levelThresholds[l]);
if (level >= levelThreshold) {
const speciesIds = entry[levelThreshold];
if (speciesIds.length > 1)
if (speciesIds.length > 1) {
species = speciesIds[Utils.randSeedInt(speciesIds.length)];
else
} else {
species = speciesIds[0];
}
break;
}
}
@ -125,13 +128,13 @@ export class Arena {
}
if (regen && (attempt || 0) < 10) {
console.log('Incompatible level: regenerating...');
console.log("Incompatible level: regenerating...");
return this.randomSpecies(waveIndex, level, (attempt || 0) + 1);
}
const newSpeciesId = ret.getWildSpeciesForLevel(level, true, isBoss, this.scene.gameMode);
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);
}
return ret;
@ -140,7 +143,7 @@ export class Arena {
randomTrainerType(waveIndex: integer): TrainerType {
const isBoss = !!this.trainerPool[BiomePoolTier.BOSS].length
&& 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);
let tier = !isBoss
? 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.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.SUNNY + (weather - 1)));
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
*/
trySetWeather(weather: WeatherType, hasPokemonSource: boolean): boolean {
if (Overrides.WEATHER_OVERRIDE)
if (Overrides.WEATHER_OVERRIDE) {
return this.trySetWeatherOverride(Overrides.WEATHER_OVERRIDE);
}
if (this.weather?.weatherType === (weather || undefined))
if (this.weather?.weatherType === (weather || undefined)) {
return false;
}
const oldWeatherType = this.weather?.weatherType || WeatherType.NONE;
@ -306,7 +311,7 @@ export class Arena {
}
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);
});
@ -314,22 +319,25 @@ export class Arena {
}
trySetTerrain(terrain: TerrainType, hasPokemonSource: boolean, ignoreAnim: boolean = false): boolean {
if (this.terrain?.terrainType === (terrain || undefined))
if (this.terrain?.terrainType === (terrain || undefined)) {
return false;
}
const oldTerrainType = this.terrain?.terrainType || TerrainType.NONE;
this.terrain = terrain ? new Terrain(terrain, hasPokemonSource ? 5 : 0) : null;
if (this.terrain) {
if (!ignoreAnim)
if (!ignoreAnim) {
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.MISTY_TERRAIN + (terrain - 1)));
}
this.scene.queueMessage(getTerrainStartMessage(terrain));
} else
} else {
this.scene.queueMessage(getTerrainClearMessage(oldTerrainType));
}
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);
});
@ -350,12 +358,14 @@ export class Arena {
getAttackTypeMultiplier(attackType: Type, grounded: boolean): number {
let weatherMultiplier = 1;
if (this.weather && !this.weather.isEffectSuppressed(this.scene))
if (this.weather && !this.weather.isEffectSuppressed(this.scene)) {
weatherMultiplier = this.weather.getAttackTypeMultiplier(attackType);
}
let terrainMultiplier = 1;
if (this.terrain && grounded)
if (this.terrain && grounded) {
terrainMultiplier = this.terrain.getAttackTypeMultiplier(attackType);
}
return weatherMultiplier * terrainMultiplier;
}
@ -412,14 +422,17 @@ export class Arena {
const waveCycle = ((this.scene.currentBattle?.waveIndex || 0) + this.scene.waveCycleOffset) % 40;
if (waveCycle < 15)
if (waveCycle < 15) {
return TimeOfDay.DAY;
}
if (waveCycle < 20)
if (waveCycle < 20) {
return TimeOfDay.DUSK;
}
if (waveCycle < 35)
if (waveCycle < 35) {
return TimeOfDay.NIGHT;
}
return TimeOfDay.DAWN;
}
@ -452,8 +465,9 @@ export class Arena {
}
getDuskTint(): [integer, integer, integer] {
if (!this.isOutside())
if (!this.isOutside()) {
return [ 0, 0, 0 ];
}
switch (this.biomeType) {
default:
@ -469,8 +483,9 @@ export class Arena {
return this.getDayTint();
}
if (!this.isOutside())
if (!this.isOutside()) {
return [ 64, 64, 64 ];
}
switch (this.biomeType) {
default:
@ -483,11 +498,12 @@ export class Arena {
}
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 instanceof tagType);
if (side !== ArenaTagSide.BOTH)
if (side !== ArenaTagSide.BOTH) {
tags = tags.filter(t => t.side === side);
}
tags.forEach(t => t.apply(this, args));
}
@ -514,7 +530,7 @@ export class Arena {
}
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 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.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.props = !player ?
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.setVisible(false);
return ret;
@ -703,7 +719,7 @@ export class ArenaBase extends Phaser.GameObjects.Container {
setBiome(biome: Biome, propValue?: integer): void {
const hasProps = getBiomeHasProps(biome);
const biomeKey = getBiomeKey(biome);
const baseKey = `${biomeKey}_${this.player ? 'a' : 'b'}`;
const baseKey = `${biomeKey}_${this.player ? "a" : "b"}`;
if (biome !== this.biome) {
this.base.setTexture(baseKey);
@ -717,8 +733,9 @@ export class ArenaBase extends Phaser.GameObjects.Container {
repeat: -1
});
this.base.play(baseKey);
} else
} else {
this.base.stop();
}
this.add(this.base);
}
@ -729,7 +746,7 @@ export class ArenaBase extends Phaser.GameObjects.Container {
? hasProps ? Utils.randSeedInt(8) : 0
: propValue;
this.props.forEach((prop, p) => {
const propKey = `${biomeKey}_b${hasProps ? `_${p + 1}` : ''}`;
const propKey = `${biomeKey}_b${hasProps ? `_${p + 1}` : ""}`;
prop.setTexture(propKey);
if (hasProps && prop.texture.frameTotal > 1) {
@ -741,8 +758,9 @@ export class ArenaBase extends Phaser.GameObjects.Container {
repeat: -1
});
prop.play(propKey);
} else
} else {
prop.stop();
}
prop.setVisible(hasProps && !!(this.propValue & (1 << p)));
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 {
const scene = target.scene;
if (!scene?.damageNumbersMode)
if (!scene?.damageNumbersMode) {
return;
}
const battlerIndex = target.getBattlerIndex();
const baseScale = target.getSpriteScale() / 6;
@ -26,40 +27,44 @@ export default class DamageNumberHandler {
switch (result) {
case HitResult.SUPER_EFFECTIVE:
[ textColor, shadowColor ] = [ '#f8d030', '#b8a038' ];
[ textColor, shadowColor ] = [ "#f8d030", "#b8a038" ];
break;
case HitResult.NOT_VERY_EFFECTIVE:
[ textColor, shadowColor ] = [ '#f08030', '#c03028' ];
[ textColor, shadowColor ] = [ "#f08030", "#c03028" ];
break;
case HitResult.ONE_HIT_KO:
[ textColor, shadowColor ] = [ '#a040a0', '#483850' ];
[ textColor, shadowColor ] = [ "#a040a0", "#483850" ];
break;
case HitResult.HEAL:
[ textColor, shadowColor ] = [ '#78c850', '#588040' ];
[ textColor, shadowColor ] = [ "#78c850", "#588040" ];
break;
default:
[ textColor, shadowColor ] = [ '#ffffff', '#636363' ];
[ textColor, shadowColor ] = [ "#ffffff", "#636363" ];
break;
}
if (textColor)
if (textColor) {
damageNumber.setColor(textColor);
}
if (shadowColor) {
if (critical) {
damageNumber.setShadowOffset(0, 0);
damageNumber.setStroke(shadowColor, 12);
} else
} else {
damageNumber.setShadowColor(shadowColor);
}
}
scene.fieldUI.add(damageNumber);
if (!this.damageNumbers.has(battlerIndex))
if (!this.damageNumbers.has(battlerIndex)) {
this.damageNumbers.set(battlerIndex, []);
}
const yOffset = this.damageNumbers.get(battlerIndex).length * -10;
if (yOffset)
if (yOffset) {
damageNumber.y += yOffset;
}
this.damageNumbers.get(battlerIndex).push(damageNumber);
@ -68,14 +73,14 @@ export default class DamageNumberHandler {
targets: damageNumber,
duration: Utils.fixedInt(750),
alpha: 1,
y: '-=32'
y: "-=32"
});
scene.tweens.add({
delay: 375,
targets: damageNumber,
duration: Utils.fixedInt(625),
alpha: 0,
ease: 'Sine.easeIn',
ease: "Sine.easeIn",
onComplete: () => {
this.damageNumbers.get(battlerIndex).splice(this.damageNumbers.get(battlerIndex).indexOf(damageNumber), 1);
damageNumber.destroy(true);
@ -94,68 +99,68 @@ export default class DamageNumberHandler {
alpha: 1,
scaleX: 0.75 * baseScale,
scaleY: 1.25 * baseScale,
y: '-=16',
ease: 'Cubic.easeOut'
y: "-=16",
ease: "Cubic.easeOut"
},
{
duration: Utils.fixedInt(175),
alpha: 1,
scaleX: 0.875 * baseScale,
scaleY: 1.125 * baseScale,
y: '+=16',
ease: 'Cubic.easeIn'
y: "+=16",
ease: "Cubic.easeIn"
},
{
duration: Utils.fixedInt(100),
scaleX: 1.25 * baseScale,
scaleY: 0.75 * baseScale,
ease: 'Cubic.easeOut'
ease: "Cubic.easeOut"
},
{
duration: Utils.fixedInt(175),
scaleX: 0.875 * baseScale,
scaleY: 1.125 * baseScale,
y: '-=8',
ease: 'Cubic.easeOut'
y: "-=8",
ease: "Cubic.easeOut"
},
{
duration: Utils.fixedInt(50),
scaleX: 0.925 * baseScale,
scaleY: 1.075 * baseScale,
y: '+=8',
ease: 'Cubic.easeIn'
y: "+=8",
ease: "Cubic.easeIn"
},
{
duration: Utils.fixedInt(100),
scaleX: 1.125 * baseScale,
scaleY: 0.875 * baseScale,
ease: 'Cubic.easeOut'
ease: "Cubic.easeOut"
},
{
duration: Utils.fixedInt(175),
scaleX: 0.925 * baseScale,
scaleY: 1.075 * baseScale,
y: '-=4',
ease: 'Cubic.easeOut'
y: "-=4",
ease: "Cubic.easeOut"
},
{
duration: Utils.fixedInt(50),
scaleX: 0.975 * baseScale,
scaleY: 1.025 * baseScale,
y: '+=4',
ease: 'Cubic.easeIn'
y: "+=4",
ease: "Cubic.easeIn"
},
{
duration: Utils.fixedInt(100),
scaleX: 1.075 * baseScale,
scaleY: 0.925 * baseScale,
ease: 'Cubic.easeOut'
ease: "Cubic.easeOut"
},
{
duration: Utils.fixedInt(25),
scaleX: baseScale,
scaleY: baseScale,
ease: 'Cubic.easeOut'
ease: "Cubic.easeOut"
},
{
delay: Utils.fixedInt(500),

View File

@ -20,11 +20,13 @@ export default class PokemonSpriteSparkleHandler {
onLapse(): void {
Array.from(this.sprites.values()).filter(s => !s.scene).map(s => this.sprites.delete(s));
for (let s of this.sprites.values()) {
if (!s.pipelineData['teraColor'] || !(s.pipelineData['teraColor'] as number[]).find(c => c))
for (const s of this.sprites.values()) {
if (!s.pipelineData["teraColor"] || !(s.pipelineData["teraColor"] as number[]).find(c => c)) {
continue;
if (!s.visible || (s.parentContainer instanceof Pokemon && !s.parentContainer.parentContainer))
}
if (!s.visible || (s.parentContainer instanceof Pokemon && !s.parentContainer.parentContainer)) {
continue;
}
const pokemon = s.parentContainer instanceof Pokemon ? s.parentContainer as Pokemon : null;
const parent = (pokemon || s).parentContainer;
const texture = s.texture;
@ -32,12 +34,12 @@ export default class PokemonSpriteSparkleHandler {
const [ pixelX, pixelY ] = [ Utils.randInt(width), Utils.randInt(height) ];
const ratioX = s.width / width;
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) {
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');
sparkle.pipelineData['ignoreTimeTint'] = s.pipelineData['ignoreTimeTint'];
sparkle.play('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.play("tera_sparkle");
parent.add(sparkle);
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 {
if (!Array.isArray(sprites))
if (!Array.isArray(sprites)) {
sprites = [ sprites ];
for (let s of sprites) {
if (this.sprites.has(s))
}
for (const s of sprites) {
if (this.sprites.has(s)) {
continue;
}
this.sprites.add(s);
}
}
remove(sprites: Phaser.GameObjects.Sprite | Phaser.GameObjects.Sprite[]): void {
if (!Array.isArray(sprites))
if (!Array.isArray(sprites)) {
sprites = [ sprites ];
for (let s of sprites) {
}
for (const s of sprites) {
this.sprites.delete(s);
}
}
removeAll(): void {
for (let s of this.sprites.values())
for (const s of this.sprites.values()) {
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 { PersistentModifier } from "../modifier/modifier";
import { trainerNamePools } from "../data/trainer-names";
import { ArenaTagType } from "#app/data/enums/arena-tag-type";
import { ArenaTag, ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag";
import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag";
import {getIsInitialized, initI18n} from "#app/plugins/i18n";
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);
if (variant === TrainerVariant.DOUBLE) {
if (this.config.doubleOnly) {
if (partnerName)
if (partnerName) {
this.partnerName = partnerName;
else
[ this.name, this.partnerName ] = this.name.split(' & ');
} else
} else {
[ this.name, this.partnerName ] = this.name.split(" & ");
}
} else {
this.partnerName = partnerName || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[1] : namePool);
}
}
}
switch (this.variant) {
case TrainerVariant.FEMALE:
if (!this.config.hasGenders)
if (!this.config.hasGenders) {
variant = TrainerVariant.DEFAULT;
}
break;
case TrainerVariant.DOUBLE:
if (!this.config.hasDouble)
if (!this.config.hasDouble) {
variant = TrainerVariant.DEFAULT;
}
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.
// 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.
@ -169,8 +172,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
}
getPartyTemplate(): TrainerPartyTemplate {
if (this.config.partyTemplateFunc)
if (this.config.partyTemplateFunc) {
return this.config.partyTemplateFunc(this.scene);
}
return this.config.partyTemplates[this.partyTemplateIndex];
}
@ -179,10 +183,11 @@ export default class Trainer extends Phaser.GameObjects.Container {
const partyTemplate = this.getPartyTemplate();
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;
}
for (let i = 0; i < partyTemplate.size; i++) {
let multiplier = 1;
@ -243,9 +248,10 @@ export default class Trainer extends Phaser.GameObjects.Container {
let offset = 0;
if (template instanceof TrainerPartyCompoundTemplate) {
for (let innerTemplate of template.templates) {
if (offset + innerTemplate.size > index)
for (const innerTemplate of template.templates) {
if (offset + innerTemplate.size > index) {
break;
}
offset += innerTemplate.size;
}
}
@ -267,7 +273,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
let species: PokemonSpecies;
if (this.config.speciesPools) {
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]);
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]}`);
@ -275,36 +281,39 @@ export default class Trainer extends Phaser.GameObjects.Container {
}
const tierPool = this.config.speciesPools[tier];
species = getPokemonSpecies(Utils.randSeedItem(tierPool));
} else
} else {
species = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter);
}
let ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength));
let retry = false;
console.log(ret.getName());
if (pokemonPrevolutions.hasOwnProperty(species.speciesId) && ret.speciesId !== species.speciesId)
if (pokemonPrevolutions.hasOwnProperty(species.speciesId) && ret.speciesId !== species.speciesId) {
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();
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;
}
}
if (!retry && this.config.specialtyTypes.length && !this.config.specialtyTypes.find(t => ret.isOfType(t))) {
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;
while (retry && evoAttempt++ < 10) {
ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength));
console.log(ret.name);
if (this.config.specialtyTypes.find(t => ret.isOfType(t)))
if (this.config.specialtyTypes.find(t => ret.isOfType(t))) {
retry = false;
}
}
}
if (retry && (attempt || 0) < 10) {
console.log('Rerolling party member...')
console.log("Rerolling party member...");
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][] {
if (trainerSlot && !this.isDouble())
if (trainerSlot && !this.isDouble()) {
trainerSlot = TrainerSlot.NONE;
}
const party = this.scene.getEnemyParty();
const nonFaintedPartyMembers = party.slice(this.scene.currentBattle.getBattlerCount()).filter(p => !p.isFainted()).filter(p => !trainerSlot || p.trainerSlot === trainerSlot);
const partyMemberScores = nonFaintedPartyMembers.map(p => {
const playerField = this.scene.getPlayerField();
let score = 0;
let ret: [integer, integer];
for (let playerPokemon of playerField) {
for (const playerPokemon of playerField) {
score += p.getMatchupScore(playerPokemon);
if (playerPokemon.species.legendary)
if (playerPokemon.species.legendary) {
score /= 2;
}
}
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));
ret = [ party.indexOf(p), score ];
return ret;
}
return [ party.indexOf(p), score ];
});
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 {
if (trainerSlot && !this.isDouble())
if (trainerSlot && !this.isDouble()) {
trainerSlot = TrainerSlot.NONE;
}
const sortedPartyMemberScores = this.getSortedPartyMemberMatchupScores(partyMemberScores);
@ -380,8 +391,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
}
genModifiers(party: EnemyPokemon[]): PersistentModifier[] {
if (this.config.genModifiersFunc)
if (this.config.genModifiersFunc) {
return this.config.genModifiersFunc(party);
}
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 {
// 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}'!`);
return false;
@ -449,8 +461,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
const ret: Phaser.GameObjects.Sprite[] = [
this.getAt(0)
];
if (this.variant === TrainerVariant.DOUBLE && !this.config.doubleOnly)
if (this.variant === TrainerVariant.DOUBLE && !this.config.doubleOnly) {
ret.push(this.getAt(2));
}
return ret;
}
@ -458,8 +471,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
const ret: Phaser.GameObjects.Sprite[] = [
this.getAt(1)
];
if (this.variant === TrainerVariant.DOUBLE && !this.config.doubleOnly)
if (this.variant === TrainerVariant.DOUBLE && !this.config.doubleOnly) {
ret.push(this.getAt(3));
}
return ret;
}
@ -476,10 +490,11 @@ export default class Trainer extends Phaser.GameObjects.Container {
targets: tintSprite,
alpha: alpha || 1,
duration: duration,
ease: ease || 'Linear'
ease: ease || "Linear"
});
} else
} else {
tintSprite.setAlpha(alpha);
}
});
}
@ -491,7 +506,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
targets: tintSprite,
alpha: 0,
duration: duration,
ease: ease || 'Linear',
ease: ease || "Linear",
onComplete: () => {
tintSprite.setVisible(false);
tintSprite.setAlpha(1);

View File

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

View File

@ -5,7 +5,7 @@ import { Species } from "./data/enums/species";
import PokemonSpecies, { allSpecies } from "./data/pokemon-species";
import { Arena } from "./field/arena";
import * as Utils from "./utils";
import * as Overrides from './overrides';
import * as Overrides from "./overrides";
export enum GameModes {
CLASSIC,
@ -52,8 +52,9 @@ export class GameMode implements GameModeConfig {
* - 5 for all other modes
*/
getStartingLevel(): integer {
if (Overrides.STARTING_LEVEL_OVERRIDE)
if (Overrides.STARTING_LEVEL_OVERRIDE) {
return Overrides.STARTING_LEVEL_OVERRIDE;
}
switch (this.modeId) {
case GameModes.DAILY:
return 20;
@ -97,32 +98,36 @@ export class GameMode implements GameModeConfig {
}
isWaveTrainer(waveIndex: integer, arena: Arena): boolean {
if (this.isDaily)
if (this.isDaily) {
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;
else if (waveIndex % 10 !== 1 && waveIndex % 10) {
} else if (waveIndex % 10 !== 1 && waveIndex % 10) {
const trainerChance = arena.getTrainerChance();
let allowTrainerBattle = true;
if (trainerChance) {
const waveBase = Math.floor(waveIndex / 10) * 10;
for (let w = Math.max(waveIndex - 3, waveBase + 2); w <= Math.min(waveIndex + 3, waveBase + 9); w++) {
if (w === waveIndex)
if (w === waveIndex) {
continue;
}
if ((w % 30) === (arena.scene.offsetGym ? 0 : 20) || fixedBattles.hasOwnProperty(w)) {
allowTrainerBattle = false;
break;
} else if (w < waveIndex) {
arena.scene.executeWithSeedOffset(() => {
const waveTrainerChance = arena.getTrainerChance();
if (!Utils.randSeedInt(waveTrainerChance))
if (!Utils.randSeedInt(waveTrainerChance)) {
allowTrainerBattle = false;
}
}, w);
if (!allowTrainerBattle)
if (!allowTrainerBattle) {
break;
}
}
}
}
return allowTrainerBattle && trainerChance && !Utils.randSeedInt(trainerChance);
}
return false;
@ -147,8 +152,14 @@ export class GameMode implements GameModeConfig {
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:
return waveIndex === 200;
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 {
switch (this.modeId) {
case GameModes.CLASSIC:
@ -182,13 +232,13 @@ export class GameMode implements GameModeConfig {
getName(): string {
switch (this.modeId) {
case GameModes.CLASSIC:
return 'Classic';
return "Classic";
case GameModes.ENDLESS:
return 'Endless';
return "Endless";
case GameModes.SPLICED_ENDLESS:
return 'Endless (Spliced)';
return "Endless (Spliced)";
case GameModes.DAILY:
return 'Daily Run';
return "Daily Run";
}
}
}

View File

@ -1,6 +1,6 @@
import Phaser, {Time} from "phaser";
import * as Utils from "./utils";
import {initTouchControls} from './touch-controls';
import {initTouchControls} from "./touch-controls";
import pad_generic from "./configs/pad_generic";
import pad_unlicensedSNES from "./configs/pad_unlicensedSNES";
import pad_xbox360 from "./configs/pad_xbox360";
@ -79,7 +79,7 @@ export class InputsController {
pressTime: false,
isPressed: false,
source: null,
}
};
}
// We don't want the menu key to be repeated
delete this.interactions[Button.MENU];
@ -98,11 +98,11 @@ export class InputsController {
init(): void {
this.events = new Phaser.Events.EventEmitter();
this.scene.game.events.on(Phaser.Core.Events.BLUR, () => {
this.loseFocus()
})
this.loseFocus();
});
if (typeof this.scene.input.gamepad !== 'undefined') {
this.scene.input.gamepad.on('connected', function (thisGamepad) {
if (typeof this.scene.input.gamepad !== "undefined") {
this.scene.input.gamepad.on("connected", function (thisGamepad) {
this.refreshGamepads();
this.setupGamepad(thisGamepad);
}, this);
@ -112,12 +112,12 @@ export class InputsController {
if (this.scene.input.gamepad.total) {
this.refreshGamepads();
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('up', this.gamepadButtonUp, this);
this.scene.input.gamepad.on("down", this.gamepadButtonDown, this);
this.scene.input.gamepad.on("up", this.gamepadButtonUp, this);
}
// Keyboard
@ -173,13 +173,13 @@ export class InputsController {
this.interactions[b].isPressed
) {
// 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.
this.delLastProcessedMovementTime(b);
return;
}
// Emits an event for the button press.
this.events.emit('input_down', {
this.events.emit("input_down", {
controller_type: this.interactions[b].source,
button: b,
});
@ -199,9 +199,9 @@ export class InputsController {
* that the gamepad controls are correctly mapped to in-game actions.
*/
setupGamepad(thisGamepad: Phaser.Input.Gamepad.Gamepad): void {
let gamepadID = thisGamepad.id.toLowerCase();
const gamepadID = thisGamepad.id.toLowerCase();
const mappedPad = this.mapGamepad(gamepadID);
this.player['mapping'] = mappedPad.gamepadMapping;
this.player["mapping"] = mappedPad.gamepadMapping;
}
/**
@ -215,7 +215,7 @@ export class InputsController {
refreshGamepads(): void {
// Sometimes, gamepads are undefined. For some reason.
this.gamepads = this.scene.input.gamepad.gamepads.filter(function (el) {
return el != null;
return el !== null;
});
for (const [index, thisGamepad] of this.gamepads.entries()) {
@ -236,7 +236,9 @@ export class InputsController {
*/
getActionGamepadMapping(): ActionGamepadMapping {
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_S] = Button.DOWN;
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.
*/
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 buttonDown = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
if (buttonDown !== undefined) {
this.events.emit('input_down', {
controller_type: 'gamepad',
this.events.emit("input_down", {
controller_type: "gamepad",
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.
*/
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 buttonUp = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
if (buttonUp !== undefined) {
this.events.emit('input_up', {
controller_type: 'gamepad',
this.events.emit("input_up", {
controller_type: "gamepad",
button: buttonUp,
});
this.delLastProcessedMovementTime(buttonUp);
@ -353,8 +359,9 @@ export class InputsController {
for (const b of Utils.getEnumValues(Button)) {
const keys: Phaser.Input.Keyboard.Key[] = [];
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));
}
mobileKeyConfig[Button[b]] = keys[0];
}
this.buttonKeys[b] = keys;
@ -385,16 +392,16 @@ export class InputsController {
listenInputKeyboard(): void {
this.buttonKeys.forEach((row, index) => {
for (const key of row) {
key.on('down', () => {
this.events.emit('input_down', {
controller_type: 'keyboard',
key.on("down", () => {
this.events.emit("input_down", {
controller_type: "keyboard",
button: index,
});
this.setLastProcessedMovementTime(index, 'keyboard');
this.setLastProcessedMovementTime(index, "keyboard");
});
key.on('up', () => {
this.events.emit('input_up', {
controller_type: 'keyboard',
key.on("up", () => {
this.events.emit("input_up", {
controller_type: "keyboard",
button: index,
});
this.delLastProcessedMovementTime(index);
@ -419,11 +426,11 @@ export class InputsController {
mapGamepad(id: string): GamepadConfig {
id = id.toLowerCase();
if (id.includes('081f') && id.includes('e401')) {
if (id.includes("081f") && id.includes("e401")) {
return pad_unlicensedSNES;
} else if (id.includes('xbox') && id.includes('360')) {
} else if (id.includes("xbox") && id.includes("360")) {
return pad_xbox360;
} else if (id.includes('054c')) {
} else if (id.includes("054c")) {
return pad_dualshock;
}
@ -436,7 +443,9 @@ export class InputsController {
* firing a repeated input - this is to prevent multiple buttons from firing repeatedly.
*/
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) {
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.
*/
setLastProcessedMovementTime(button: Button, source: String = 'keyboard'): void {
if (!this.interactions.hasOwnProperty(button)) return;
setLastProcessedMovementTime(button: Button, source: String = "keyboard"): void {
if (!this.interactions.hasOwnProperty(button)) {
return;
}
this.setButtonLock(button);
this.interactions[button].pressTime = this.time.now;
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.
*/
delLastProcessedMovementTime(button: Button): void {
if (!this.interactions.hasOwnProperty(button)) return;
if (!this.interactions.hasOwnProperty(button)) {
return;
}
this.releaseButtonLock(button);
this.interactions[button].pressTime = null;
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.
*/
setButtonLock(button: Button): void {
if (this.buttonLock === button || this.buttonLock2 === button) return;
if (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;
if (this.buttonLock === button || this.buttonLock2 === button) {
return;
}
if (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.
*/
releaseButtonLock(button: Button): void {
if (this.buttonLock === button) this.buttonLock = null;
else if (this.buttonLock2 === button) this.buttonLock2 = null;
if (this.buttonLock === button) {
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 {
constructor() {
super('loading');
super("loading");
Phaser.Plugins.PluginCache.register('Loader', CacheBustedLoaderPlugin, 'load');
Phaser.Plugins.PluginCache.register("Loader", CacheBustedLoaderPlugin, "load");
initI18n();
}
preload() {
this.load['manifest'] = this.game['manifest'];
this.load["manifest"] = this.game["manifest"];
if (!isMobile())
this.load.video('intro_dark', 'images/intro_dark.mp4', true);
if (!isMobile()) {
this.load.video("intro_dark", "images/intro_dark.mp4", true);
}
this.loadImage('loading_bg', 'arenas');
this.loadImage('logo', '');
this.loadImage("loading_bg", "arenas");
this.loadImage("logo", "");
// Load menu images
this.loadAtlas('bg', 'ui');
this.loadImage('command_fight_labels', 'ui');
this.loadAtlas('prompt', 'ui');
this.loadImage('candy', 'ui');
this.loadImage('candy_overlay', 'ui');
this.loadImage('cursor', 'ui');
this.loadImage('cursor_reverse', 'ui');
for (let wv of Utils.getEnumValues(WindowVariant)) {
for (let w = 1; w <= 5; w++)
this.loadImage(`window_${w}${getWindowVariantSuffix(wv)}`, 'ui/windows');
this.loadAtlas("bg", "ui");
this.loadImage("command_fight_labels", "ui");
this.loadAtlas("prompt", "ui");
this.loadImage("candy", "ui");
this.loadImage("candy_overlay", "ui");
this.loadImage("cursor", "ui");
this.loadImage("cursor_reverse", "ui");
for (const wv of Utils.getEnumValues(WindowVariant)) {
for (let w = 1; w <= 5; w++) {
this.loadImage(`window_${w}${getWindowVariantSuffix(wv)}`, "ui/windows");
}
this.loadAtlas('namebox', 'ui');
this.loadImage('pbinfo_player', 'ui');
this.loadImage('pbinfo_player_stats', 'ui');
this.loadImage('pbinfo_player_mini', 'ui');
this.loadImage('pbinfo_player_mini_stats', 'ui');
this.loadAtlas('pbinfo_player_type', 'ui');
this.loadAtlas('pbinfo_player_type1', 'ui');
this.loadAtlas('pbinfo_player_type2', 'ui');
this.loadImage('pbinfo_enemy_mini', 'ui');
this.loadImage('pbinfo_enemy_mini_stats', 'ui');
this.loadImage('pbinfo_enemy_boss', 'ui');
this.loadImage('pbinfo_enemy_boss_stats', 'ui');
this.loadAtlas('pbinfo_enemy_type', 'ui');
this.loadAtlas('pbinfo_enemy_type1', 'ui');
this.loadAtlas('pbinfo_enemy_type2', 'ui');
this.loadAtlas('pbinfo_stat', 'ui');
this.loadAtlas('pbinfo_stat_numbers', 'ui');
this.loadImage('overlay_lv', 'ui');
this.loadAtlas('numbers', 'ui');
this.loadAtlas('numbers_red', 'ui');
this.loadAtlas('overlay_hp', 'ui');
this.loadAtlas('overlay_hp_boss', 'ui');
this.loadImage('overlay_exp', 'ui');
this.loadImage('icon_owned', 'ui');
this.loadImage('ability_bar_left', 'ui');
this.loadImage('party_exp_bar', 'ui');
this.loadImage('achv_bar', 'ui');
this.loadImage('achv_bar_2', 'ui');
this.loadImage('achv_bar_3', 'ui');
this.loadImage('achv_bar_4', 'ui');
this.loadImage('achv_bar_5', 'ui');
this.loadImage('shiny_star', 'ui', 'shiny.png');
this.loadImage('shiny_star_1', 'ui', 'shiny_1.png');
this.loadImage('shiny_star_2', 'ui', 'shiny_2.png');
this.loadImage('shiny_star_small', 'ui', 'shiny_small.png');
this.loadImage('shiny_star_small_1', 'ui', 'shiny_small_1.png');
this.loadImage('shiny_star_small_2', 'ui', 'shiny_small_2.png');
this.loadImage('ha_capsule', 'ui', 'ha_capsule.png');
this.loadImage('champion_ribbon', 'ui', 'champion_ribbon.png');
this.loadImage('icon_spliced', 'ui');
this.loadImage('icon_tera', 'ui');
this.loadImage('type_tera', 'ui');
this.loadAtlas('type_bgs', 'ui');
}
this.loadAtlas("namebox", "ui");
this.loadImage("pbinfo_player", "ui");
this.loadImage("pbinfo_player_stats", "ui");
this.loadImage("pbinfo_player_mini", "ui");
this.loadImage("pbinfo_player_mini_stats", "ui");
this.loadAtlas("pbinfo_player_type", "ui");
this.loadAtlas("pbinfo_player_type1", "ui");
this.loadAtlas("pbinfo_player_type2", "ui");
this.loadImage("pbinfo_enemy_mini", "ui");
this.loadImage("pbinfo_enemy_mini_stats", "ui");
this.loadImage("pbinfo_enemy_boss", "ui");
this.loadImage("pbinfo_enemy_boss_stats", "ui");
this.loadAtlas("pbinfo_enemy_type", "ui");
this.loadAtlas("pbinfo_enemy_type1", "ui");
this.loadAtlas("pbinfo_enemy_type2", "ui");
this.loadAtlas("pbinfo_stat", "ui");
this.loadAtlas("pbinfo_stat_numbers", "ui");
this.loadImage("overlay_lv", "ui");
this.loadAtlas("numbers", "ui");
this.loadAtlas("numbers_red", "ui");
this.loadAtlas("overlay_hp", "ui");
this.loadAtlas("overlay_hp_boss", "ui");
this.loadImage("overlay_exp", "ui");
this.loadImage("icon_owned", "ui");
this.loadImage("ability_bar_left", "ui");
this.loadImage("party_exp_bar", "ui");
this.loadImage("achv_bar", "ui");
this.loadImage("achv_bar_2", "ui");
this.loadImage("achv_bar_3", "ui");
this.loadImage("achv_bar_4", "ui");
this.loadImage("achv_bar_5", "ui");
this.loadImage("shiny_star", "ui", "shiny.png");
this.loadImage("shiny_star_1", "ui", "shiny_1.png");
this.loadImage("shiny_star_2", "ui", "shiny_2.png");
this.loadImage("shiny_star_small", "ui", "shiny_small.png");
this.loadImage("shiny_star_small_1", "ui", "shiny_small_1.png");
this.loadImage("shiny_star_small_2", "ui", "shiny_small_2.png");
this.loadImage("ha_capsule", "ui", "ha_capsule.png");
this.loadImage("champion_ribbon", "ui", "champion_ribbon.png");
this.loadImage("icon_spliced", "ui");
this.loadImage("icon_tera", "ui");
this.loadImage("type_tera", "ui");
this.loadAtlas("type_bgs", "ui");
this.loadImage('pb_tray_overlay_player', 'ui');
this.loadImage('pb_tray_overlay_enemy', 'ui');
this.loadAtlas('pb_tray_ball', 'ui');
this.loadImage("pb_tray_overlay_player", "ui");
this.loadImage("pb_tray_overlay_enemy", "ui");
this.loadAtlas("pb_tray_ball", "ui");
this.loadImage('party_bg', 'ui');
this.loadImage('party_bg_double', 'ui');
this.loadAtlas('party_slot_main', 'ui');
this.loadAtlas('party_slot', 'ui');
this.loadImage('party_slot_overlay_lv', 'ui');
this.loadImage('party_slot_hp_bar', 'ui');
this.loadAtlas('party_slot_hp_overlay', 'ui');
this.loadAtlas('party_pb', 'ui');
this.loadAtlas('party_cancel', 'ui');
this.loadImage("party_bg", "ui");
this.loadImage("party_bg_double", "ui");
this.loadAtlas("party_slot_main", "ui");
this.loadAtlas("party_slot", "ui");
this.loadImage("party_slot_overlay_lv", "ui");
this.loadImage("party_slot_hp_bar", "ui");
this.loadAtlas("party_slot_hp_overlay", "ui");
this.loadAtlas("party_pb", "ui");
this.loadAtlas("party_cancel", "ui");
this.loadImage('summary_bg', 'ui');
this.loadImage('summary_overlay_shiny', 'ui');
this.loadImage('summary_profile', 'ui');
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_ability', 'ui'); // Pixel text 'ABILITY'
this.loadImage('summary_profile_passive', 'ui'); // Pixel text 'PASSIVE'
this.loadImage('summary_status', 'ui');
this.loadImage('summary_stats', 'ui');
this.loadImage('summary_stats_overlay_exp', 'ui');
this.loadImage('summary_moves', 'ui');
this.loadImage('summary_moves_effect', 'ui');
this.loadImage('summary_moves_overlay_row', 'ui');
this.loadImage('summary_moves_overlay_pp', 'ui');
this.loadAtlas('summary_moves_cursor', 'ui');
for (let t = 1; t <= 3; t++)
this.loadImage(`summary_tabs_${t}`, 'ui');
this.loadImage("summary_bg", "ui");
this.loadImage("summary_overlay_shiny", "ui");
this.loadImage("summary_profile", "ui");
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_ability", "ui"); // Pixel text 'ABILITY'
this.loadImage("summary_profile_passive", "ui"); // Pixel text 'PASSIVE'
this.loadImage("summary_status", "ui");
this.loadImage("summary_stats", "ui");
this.loadImage("summary_stats_overlay_exp", "ui");
this.loadImage("summary_moves", "ui");
this.loadImage("summary_moves_effect", "ui");
this.loadImage("summary_moves_overlay_row", "ui");
this.loadImage("summary_moves_overlay_pp", "ui");
this.loadAtlas("summary_moves_cursor", "ui");
for (let t = 1; t <= 3; t++) {
this.loadImage(`summary_tabs_${t}`, "ui");
}
this.loadImage('starter_select_bg', 'ui');
this.loadImage('select_cursor', 'ui');
this.loadImage('select_cursor_highlight', 'ui');
this.loadImage('select_cursor_highlight_thick', 'ui');
this.loadImage('select_cursor_pokerus', 'ui');
this.loadImage('select_gen_cursor', 'ui');
this.loadImage('select_gen_cursor_highlight', 'ui');
this.loadImage("starter_select_bg", "ui");
this.loadImage("select_cursor", "ui");
this.loadImage("select_cursor_highlight", "ui");
this.loadImage("select_cursor_highlight_thick", "ui");
this.loadImage("select_cursor_pokerus", "ui");
this.loadImage("select_gen_cursor", "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
Utils.getEnumValues(Biome).map(bt => {
const btKey = Biome[bt].toLowerCase();
const isBaseAnimated = btKey === 'end';
const isBaseAnimated = btKey === "end";
const baseAKey = `${btKey}_a`;
const baseBKey = `${btKey}_b`;
this.loadImage(`${btKey}_bg`, 'arenas');
if (!isBaseAnimated)
this.loadImage(baseAKey, 'arenas');
else
this.loadAtlas(baseAKey, 'arenas');
if (!isBaseAnimated)
this.loadImage(baseBKey, 'arenas');
else
this.loadAtlas(baseBKey, 'arenas');
this.loadImage(`${btKey}_bg`, "arenas");
if (!isBaseAnimated) {
this.loadImage(baseAKey, "arenas");
} else {
this.loadAtlas(baseAKey, "arenas");
}
if (!isBaseAnimated) {
this.loadImage(baseBKey, "arenas");
} else {
this.loadAtlas(baseBKey, "arenas");
}
if (getBiomeHasProps(bt)) {
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}`;
if (!isPropAnimated)
this.loadImage(propKey, 'arenas');
else
this.loadAtlas(propKey, 'arenas');
if (!isPropAnimated) {
this.loadImage(propKey, "arenas");
} else {
this.loadAtlas(propKey, "arenas");
}
}
}
});
// 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
this.loadAtlas('trainer_m_back', 'trainer');
this.loadAtlas('trainer_m_back_pb', 'trainer');
this.loadAtlas('trainer_f_back', 'trainer');
this.loadAtlas('trainer_f_back_pb', 'trainer');
this.loadAtlas("trainer_m_back", "trainer");
this.loadAtlas("trainer_m_back_pb", "trainer");
this.loadAtlas("trainer_f_back", "trainer");
this.loadAtlas("trainer_f_back_pb", "trainer");
Utils.getEnumValues(TrainerType).map(tt => {
const config = trainerConfigs[tt];
this.loadAtlas(config.getSpriteKey(), 'trainer');
if (config.doubleOnly || config.hasDouble)
this.loadAtlas(config.getSpriteKey(true), 'trainer');
this.loadAtlas(config.getSpriteKey(), "trainer");
if (config.doubleOnly || config.hasDouble) {
this.loadAtlas(config.getSpriteKey(true), "trainer");
}
});
// Load character sprites
this.loadAtlas('c_rival_m', 'character', 'rival_m');
this.loadAtlas('c_rival_f', 'character', 'rival_f');
this.loadAtlas("c_rival_m", "character", "rival_m");
this.loadAtlas("c_rival_f", "character", "rival_f");
// Load pokemon-related images
this.loadImage(`pkmn__back__sub`, 'pokemon/back', 'sub.png');
this.loadImage(`pkmn__sub`, 'pokemon', 'sub.png');
this.loadAtlas('battle_stats', 'effects');
this.loadAtlas('shiny', 'effects');
this.loadAtlas('shiny_2', 'effects');
this.loadAtlas('shiny_3', 'effects');
this.loadImage('tera', 'effects');
this.loadAtlas('pb_particles', 'effects');
this.loadImage('evo_sparkle', 'effects');
this.loadAtlas('tera_sparkle', 'effects');
this.load.video('evo_bg', 'images/effects/evo_bg.mp4', true);
this.loadImage("pkmn__back__sub", "pokemon/back", "sub.png");
this.loadImage("pkmn__sub", "pokemon", "sub.png");
this.loadAtlas("battle_stats", "effects");
this.loadAtlas("shiny", "effects");
this.loadAtlas("shiny_2", "effects");
this.loadAtlas("shiny_3", "effects");
this.loadImage("tera", "effects");
this.loadAtlas("pb_particles", "effects");
this.loadImage("evo_sparkle", "effects");
this.loadAtlas("tera_sparkle", "effects");
this.load.video("evo_bg", "images/effects/evo_bg.mp4", true);
this.loadAtlas('pb', '');
this.loadAtlas('items', '');
this.loadAtlas('types', '');
this.loadAtlas('statuses', '');
this.loadAtlas('categories', '');
this.loadAtlas("pb", "");
this.loadAtlas("items", "");
this.loadAtlas("types", "");
this.loadAtlas("statuses", "");
this.loadAtlas("categories", "");
this.loadAtlas('egg', 'egg');
this.loadAtlas('egg_crack', 'egg');
this.loadAtlas('egg_icons', 'egg');
this.loadAtlas('egg_shard', 'egg');
this.loadAtlas('egg_lightrays', 'egg');
this.loadAtlas("egg", "egg");
this.loadAtlas("egg_crack", "egg");
this.loadAtlas("egg_icons", "egg");
this.loadAtlas("egg_shard", "egg");
this.loadAtlas("egg_lightrays", "egg");
Utils.getEnumKeys(GachaType).forEach(gt => {
const key = gt.toLowerCase();
this.loadImage(`gacha_${key}`, 'egg');
this.loadAtlas(`gacha_underlay_${key}`, 'egg');
this.loadImage(`gacha_${key}`, "egg");
this.loadAtlas(`gacha_underlay_${key}`, "egg");
});
this.loadImage('gacha_glass', 'egg');
this.loadImage('gacha_eggs', 'egg');
this.loadAtlas('gacha_hatch', 'egg');
this.loadImage('gacha_knob', 'egg');
this.loadImage("gacha_glass", "egg");
this.loadImage("gacha_eggs", "egg");
this.loadAtlas("gacha_hatch", "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_f', 'cg');
this.loadImage("end_m", "cg");
this.loadImage("end_f", "cg");
for (let i = 0; i < 10; i++) {
this.loadAtlas(`pokemon_icons_${i}`, '');
if (i)
this.loadAtlas(`pokemon_icons_${i}v`, '');
this.loadAtlas(`pokemon_icons_${i}`, "");
if (i) {
this.loadAtlas(`pokemon_icons_${i}v`, "");
}
}
this.loadSe('select');
this.loadSe('menu_open');
this.loadSe('hit');
this.loadSe('hit_strong');
this.loadSe('hit_weak');
this.loadSe('stat_up');
this.loadSe('stat_down');
this.loadSe('faint');
this.loadSe('flee');
this.loadSe('low_hp');
this.loadSe('exp');
this.loadSe('level_up');
this.loadSe('sparkle');
this.loadSe('restore');
this.loadSe('shine');
this.loadSe('shing');
this.loadSe('charge');
this.loadSe('beam');
this.loadSe('upgrade');
this.loadSe('buy');
this.loadSe('achv');
this.loadSe('error');
this.loadSe("select");
this.loadSe("menu_open");
this.loadSe("hit");
this.loadSe("hit_strong");
this.loadSe("hit_weak");
this.loadSe("stat_up");
this.loadSe("stat_down");
this.loadSe("faint");
this.loadSe("flee");
this.loadSe("low_hp");
this.loadSe("exp");
this.loadSe("level_up");
this.loadSe("sparkle");
this.loadSe("restore");
this.loadSe("shine");
this.loadSe("shing");
this.loadSe("charge");
this.loadSe("beam");
this.loadSe("upgrade");
this.loadSe("buy");
this.loadSe("achv");
this.loadSe("error");
this.loadSe('pb_rel');
this.loadSe('pb_throw');
this.loadSe('pb_bounce_1');
this.loadSe('pb_bounce_2');
this.loadSe('pb_move');
this.loadSe('pb_catch');
this.loadSe('pb_lock');
this.loadSe("pb_rel");
this.loadSe("pb_throw");
this.loadSe("pb_bounce_1");
this.loadSe("pb_bounce_2");
this.loadSe("pb_move");
this.loadSe("pb_catch");
this.loadSe("pb_lock");
this.loadSe('pb_tray_enter');
this.loadSe('pb_tray_ball');
this.loadSe('pb_tray_empty');
this.loadSe("pb_tray_enter");
this.loadSe("pb_tray_ball");
this.loadSe("pb_tray_empty");
this.loadSe('egg_crack');
this.loadSe('egg_hatch');
this.loadSe('gacha_dial');
this.loadSe('gacha_running');
this.loadSe('gacha_dispense');
this.loadSe("egg_crack");
this.loadSe("egg_hatch");
this.loadSe("gacha_dial");
this.loadSe("gacha_running");
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('item_fanfare', 'bw/item_fanfare.mp3');
this.loadBgm('minor_fanfare', 'bw/minor_fanfare.mp3');
this.loadBgm('heal', 'bw/heal.mp3');
this.loadBgm('victory_trainer', 'bw/victory_trainer.mp3');
this.loadBgm('victory_gym', 'bw/victory_gym.mp3');
this.loadBgm('victory_champion', 'bw/victory_champion.mp3');
this.loadBgm('evolution', 'bw/evolution.mp3');
this.loadBgm('evolution_fanfare', 'bw/evolution_fanfare.mp3');
this.loadBgm("level_up_fanfare", "bw/level_up_fanfare.mp3");
this.loadBgm("item_fanfare", "bw/item_fanfare.mp3");
this.loadBgm("minor_fanfare", "bw/minor_fanfare.mp3");
this.loadBgm("heal", "bw/heal.mp3");
this.loadBgm("victory_trainer", "bw/victory_trainer.mp3");
this.loadBgm("victory_gym", "bw/victory_gym.mp3");
this.loadBgm("victory_champion", "bw/victory_champion.mp3");
this.loadBgm("evolution", "bw/evolution.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();
}
@ -283,7 +291,7 @@ export class LoadingScene extends SceneBase {
const loadingGraphics: any[] = [];
const bg = this.add.image(0, 0, '');
const bg = this.add.image(0, 0, "");
bg.setOrigin(0, 0);
bg.setScale(6);
bg.setVisible(false);
@ -300,7 +308,7 @@ export class LoadingScene extends SceneBase {
const width = this.cameras.main.width;
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.setOrigin(0.5, 0.5);
logo.setScale(4);
@ -308,7 +316,7 @@ export class LoadingScene extends SceneBase {
const percentText = this.make.text({
x: width / 2,
y: height / 2 - 24,
text: '0%',
text: "0%",
style: {
font: "72px emerald",
color: "#ffffff",
@ -345,8 +353,9 @@ export class LoadingScene extends SceneBase {
loadingGraphics.push(bg, graphics, progressBar, progressBox, logo, percentText, assetText);
if (!mobile)
if (!mobile) {
loadingGraphics.map(g => g.setVisible(false));
}
const destroyLoadingAssets = () => {
intro.destroy();
@ -358,30 +367,32 @@ export class LoadingScene extends SceneBase {
assetText.destroy();
};
this.load.on('filecomplete', key => {
this.load.on("filecomplete", key => {
switch (key) {
case 'intro_dark':
intro.load('intro_dark');
intro.on('complete', () => {
case "intro_dark":
intro.load("intro_dark");
intro.on("complete", () => {
this.tweens.add({
targets: intro,
duration: 500,
alpha: 0,
ease: 'Sine.easeIn'
ease: "Sine.easeIn"
});
loadingGraphics.map(g => g.setVisible(true));
});
intro.play();
break;
case 'loading_bg':
bg.setTexture('loading_bg');
if (mobile)
case "loading_bg":
bg.setTexture("loading_bg");
if (mobile) {
bg.setVisible(true);
}
break;
case 'logo':
logo.setTexture('logo');
if (mobile)
case "logo":
logo.setTexture("logo");
if (mobile) {
logo.setVisible(true);
}
break;
}
});

View File

@ -1,5 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
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;

View File

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

View File

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

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const menuUiHandler: SimpleTranslationEntries = {
"GAME_SETTINGS": 'Spieleinstellungen',
"GAME_SETTINGS": "Spieleinstellungen",
"ACHIEVEMENTS": "Erfolge",
"STATS": "Statistiken",
"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)" },
"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" },

View File

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

View File

@ -8,7 +8,7 @@ export const tutorial: SimpleTranslationEntries = {
$Für Fehlerberichte nutze bitte den PokéRogue Discord-Server.
$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.
$Dort kannst du u. A. die Spielgeschwin-\ndigkeit und das Fensterdesign ändern.

View File

@ -1,11 +1,11 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const voucher: SimpleTranslationEntries = {
"vouchers": "Vouchers",
"eggVoucher": "Egg Voucher",
"eggVoucherPlus": "Egg Voucher Plus",
"eggVoucherPremium": "Egg Voucher Premium",
"eggVoucherGold": "Egg Voucher Gold",
"locked": "Locked",
"defeatTrainer": "Defeat {{trainerName}}"
"vouchers": "Gutschein",
"eggVoucher": "Ei-Gutschein",
"eggVoucherPlus": "Ei-Gutschein Plus",
"eggVoucherPremium": "Ei-Gutschein Premium",
"eggVoucherGold": "Ei-Gutschein Gold",
"locked": "Gesperrt",
"defeatTrainer": "Besiege {{trainerName}}"
} 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!",
"strongWindsLapseMessage": "Die rätselhafte Luftströmung hält an.",
"strongWindsClearMessage": "Die rätselhafte Luftströmung hat sich wieder geleget.",
}
};

View File

@ -1,5 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
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;

View File

@ -439,7 +439,7 @@ export const ability: AbilityTranslationEntries = {
},
tintedLens: {
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: {
name: "Filter",
@ -751,7 +751,7 @@ export const ability: AbilityTranslationEntries = {
},
auraBreak: {
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: {
name: "Primordial Sea",

View File

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

View File

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

View File

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

View File

@ -185,7 +185,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"RELIC_GOLD": { name: "Relic Gold" },
"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" },
"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)" },
"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" },

View File

@ -17,7 +17,7 @@ export const splashMessages: SimpleTranslationEntries = {
"brokenEggMoves": "Broken Egg Moves!",
"magnificent": "Magnificent!",
"mubstitute": "Mubstitute!",
"thatsCrazy": "That\'s Crazy!",
"thatsCrazy": "That's Crazy!",
"oranceJuice": "Orance Juice!",
"questionableBalancing": "Questionable Balancing!",
"coolShaders": "Cool Shaders!",
@ -26,9 +26,9 @@ export const splashMessages: SimpleTranslationEntries = {
"basedOnAnUnfinishedFlashGame": "Based on an Unfinished Flash Game!",
"moreAddictiveThanIntended": "More Addictive than Intended!",
"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!",
"dontTalkAboutTheManaphyEggIncident": "Don\'t Talk About the Manaphy Egg Incident!",
"dontTalkAboutTheManaphyEggIncident": "Don't Talk About the Manaphy Egg Incident!",
"alsoTryPokengine": "Also Try Pokéngine!",
"alsoTryEmeraldRogue": "Also Try Emerald Rogue!",
"alsoTryRadicalRed": "Also Try Radical Red!",

View File

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

View File

@ -1,5 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@ export const splashMessages: SimpleTranslationEntries = {
"brokenEggMoves": "Broken Egg Moves!",
"magnificent": "Magnificent!",
"mubstitute": "Mubstitute!",
"thatsCrazy": "That\'s Crazy!",
"thatsCrazy": "That's Crazy!",
"oranceJuice": "Orance Juice!",
"questionableBalancing": "Questionable Balancing!",
"coolShaders": "Cool Shaders!",
@ -26,9 +26,9 @@ export const splashMessages: SimpleTranslationEntries = {
"basedOnAnUnfinishedFlashGame": "Based on an Unfinished Flash Game!",
"moreAddictiveThanIntended": "More Addictive than Intended!",
"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!",
"dontTalkAboutTheManaphyEggIncident": "Don\'t Talk About the Manaphy Egg Incident!",
"dontTalkAboutTheManaphyEggIncident": "Don't Talk About the Manaphy Egg Incident!",
"alsoTryPokengine": "Also Try Pokéngine!",
"alsoTryEmeraldRogue": "Also Try Emerald Rogue!",
"alsoTryRadicalRed": "Also Try Radical Red!",

View File

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

View File

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

View File

@ -1,5 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
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;

View File

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

View File

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

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const menuUiHandler: SimpleTranslationEntries = {
"GAME_SETTINGS": 'Paramètres',
"GAME_SETTINGS": "Paramètres",
"ACHIEVEMENTS": "Succès",
"STATS": "Statistiques",
"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)" },
"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." },

View File

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

View File

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

View File

@ -1,5 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
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;

View File

@ -711,7 +711,7 @@ export const ability: AbilityTranslationEntries = {
},
megaLauncher: {
name: "Megalancio",
description: 'Potenzia le mosse "pulsar", Forzasfera e Ondasana.',
description: "Potenzia le mosse \"pulsar\", Forzasfera e Ondasana.",
},
grassPelt: {
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.",
},
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",
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: {
name: "Albergamemorie",
description: "Il Pokémon riporta alla mente vecchi ricordi, facendo risplendere la Maschera Turchese e aumentando la propria Velocità.",
name: "Ospitalità",
description: "Quando un Pokémon con questa abilità entra in campo ricopre di attenzioni l'alleato, restituendogli un po' dei suoi PS.",
},
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",
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: {
name: "Sciroppo Sublime",
description: "La prima volta che il Pokémon entra in campo, spande un odore dolciastro che diminuisce l'elusione degli avversari.",
name: "Albergamemorie",
description: "Il Pokémon riporta alla mente vecchi ricordi, facendo risplendere la Maschera Fondamenta e aumentando la propria Difesa.",
},
teraShift: {
name: "Teramorfosi",

View File

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

View File

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

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